51 lines
3.8 KiB
Markdown
51 lines
3.8 KiB
Markdown
# Tasks — add-api-plugin
|
|
|
|
## 1. Scaffold
|
|
|
|
- [ ] 1.1 Create `packages/api/api-plugin/` with `src/{define,registry,context,service-registry,hook-executor,topo-sort,error-codes,types}/` + `tests/setup/`
|
|
- [ ] 1.2 `package.json` v0.1.0, type module, sideEffects false. Deps: `@suaveplan/error` `@suaveplan/events` `@suaveplan/types` `tslib` (`workspace:^` / `catalog:build`), `zod` (`catalog:forms`), `@opentelemetry/api` (`catalog:observability`). Dev: `@suaveplan/testing` `@vitest/coverage-istanbul` `vitest` `fast-check` (`catalog:testing`), `@types/node` `typescript` (`catalog:`), `vite` `vite-plugin-dts` (`catalog:build`). 8 subpath exports.
|
|
- [ ] 1.3 `tsconfig.json` + `tsconfig.lib.json` extending `../../../tsconfig.base.json`
|
|
- [ ] 1.4 `vite.config.ts` (dts, ES, externals)
|
|
- [ ] 1.5 `vitest.config.ts` (`pool: forks`, `provider: istanbul`, thresholds 100/100/100/100, `testTimeout: 30000`, `setupFiles: ['./tests/setup/polyfills.ts']`)
|
|
- [ ] 1.6 `tests/setup/polyfills.ts`
|
|
|
|
## 2. Implementation
|
|
|
|
- [ ] 2.1 `src/error-codes.ts` + `.md` + test — 10 PLUGIN.* codes + `PluginError`
|
|
- [ ] 2.2 `src/types/api-plugin.ts` + `.md` — `PluginDescriptor`, `PluginInstance`, `PluginState` (`pending`/`registered`/`initializing`/`initialized`/`ready`/`disabled`/`error`), `PluginNode`
|
|
- [ ] 2.3 `src/topo-sort/topo-sort.{ts,test.ts,md,index.ts}` — Kahn's + DFS cycle detect + alpha tie-break; export `validateDependencies`
|
|
- [ ] 2.4 `src/service-registry/service-registry.{ts,md,index.ts}` — empty `ServiceRegistry` interface for module augmentation, `ServiceKey = keyof ServiceRegistry` helper
|
|
- [ ] 2.5 `src/context/context.{ts,test.ts,md,index.ts}` — `createPluginContext(opts)`; typed `getService`/`registerService`/`hasService`; `getOwnConfig<T>()`; `signal: AbortSignal`
|
|
- [ ] 2.6 `src/hook-executor/hook-executor.{ts,test.ts,md,index.ts}` — priority-sorted handlers, `execute` (sequential abort-on-throw) + `executeAll` (parallel allSettled); does NOT include lifecycle hook slots
|
|
- [ ] 2.7 `src/define/define.{ts,test.ts,md,index.ts}` — `definePlugin` factory with TConfig inference
|
|
- [ ] 2.8 `src/registry/registry.{ts,test.ts,md,index.ts}` — `PluginRegistry` class; topo-sort delegation; 4-phase lifecycle; `initTimeout`/`shutdownTimeout` enforcement via AbortSignal; `defineCodes`-typed errors; OTel span per hook
|
|
- [ ] 2.9 `src/index.ts` — named re-exports only
|
|
|
|
## 3. Tests
|
|
|
|
- [ ] 3.1 Co-located `*.test.ts` per spec scenario
|
|
- [ ] 3.2 `src/api-plugin.spec-conformance.test.ts` — every PLUGIN.* thrown from production; `expectTypeOf` on `definePlugin<TConfig>` + `getService<K>` + `getOwnConfig<T>`
|
|
- [ ] 3.3 `tests/property.test.ts` — fast-check topo-sort dep invariant + determinism (200 runs each)
|
|
- [ ] 3.4 `tests/dep-graph.test.ts` — deps allowlist + subpath coverage + sibling .md presence
|
|
- [ ] 3.5 All tests import runner from `@suaveplan/testing/runner`
|
|
- [ ] 3.6 Every `it(...)` has `{ timeout: 5000 }` (30000 for AbortSignal-timeout tests)
|
|
|
|
## 4. Documentation
|
|
|
|
- [ ] 4.1 Sibling `.md` per impl file (≥200 words)
|
|
- [ ] 4.2 `README.md` — Quick-start, Modules list, ServiceRegistry augmentation example, sample plugin
|
|
|
|
## 5. Gates
|
|
|
|
- [ ] 5.1 `bunx turbo lint typecheck test --filter=@suaveplan/api-plugin --force` — green
|
|
- [ ] 5.2 `bunx turbo test:coverage --filter=@suaveplan/api-plugin --force` — 100/100/100/100
|
|
- [ ] 5.3 `bun scripts/openspec-conformance.ts @suaveplan/api-plugin` — exit 0
|
|
- [ ] 5.4 `bunx turbo build --filter=@suaveplan/api-plugin --force` — green
|
|
- [ ] 5.5 Banned-pattern grep clean; no `export *` in feature barrels; no direct vitest/bun:test imports
|
|
|
|
## 6. Archive
|
|
|
|
- [ ] 6.1 Fold `specs/api-plugin/spec.md` → `openspec/specs/api-plugin/spec.md`
|
|
- [ ] 6.2 Move change folder → `openspec/archive/<yyyy-mm-dd>-add-api-plugin/`
|
|
- [ ] 6.3 Refresh MANIFEST + STATUS (`@suaveplan/api-plugin` → ✅)
|