Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@suaveplan/api-host - Host orchestration core for the Suaveplan API plugin system. Provides the stable error-code registry (HOST/PLUGIN/RELOAD/CAPABILITY/ADMIN/LEDGER), the author-facing definePlugin DX, the runtime CapabilityRegistry, the LifecycleDriver + ReloadDriver + PluginLedger + admin Hono sub-router, the ErrorBoundary, the §6 11-step RequestPipeline, the top-level createHost(config) entry point composing every internal driver, and the HostInstruments registry covering the §12.3 metric surface. The ./testing subpath is reserved.
host orchestration core for the Suaveplan API plugin system.
This package is the keystone of the API plugin system. Every downstream package either consumes api-host directly (worker proxies talk to it) or extends it (adapters register with its CapabilityRegistry).
Documentation tree
- admin-api —
createAdminApibuilds the host-side Hono sub-router that exposes the design §8.4 admin surface — every operational en…- admin-api —
createAdminApibuilds the host-side Hono sub-router that exposes the design §8.4 admin surface — every operational en… - audit-sink —
MemoryAdminAuditSinkis the in-memory default audit sink for the host's admin API. Every admin endpoint emits a struc… - idempotency-store —
InMemoryIdempotencyStoreis the process-local default for the admin API'sIdempotency-Keyenforcement. Mutating adm… - rate-limiter —
AdminRateLimiterenforces the design §8.4 per-principal rate limits on every admin endpoint. Read endpoints share a 6…
- admin-api —
- capability-registry — The
CapabilityRegistryis the live, single-instance store of every capability adapter wired into a host process. Stag…- capability-registry — The
CapabilityRegistryis the live, single-instance store of every capability adapter wired into a host process. Stag…
- capability-registry — The
- define-plugin —
definePluginis the canonical entry point plugin authors call to declare theirname/version/requires/ `iso…- define-plugin —
definePluginis the canonical entry point plugin authors call to declare theirname/version/requires/ `iso…
- define-plugin —
- empty-secrets —
EmptySecretsis the no-op defaultSecretsLikeimplementation the host injects into everyPluginContext/ `Request…- empty-secrets —
EmptySecretsis the no-op defaultSecretsLikeimplementation the host injects into everyPluginContext/ `Request…
- empty-secrets —
- error-boundary — The
ErrorBoundarywraps every step of the per-request pipeline (design doc §6 steps 1–11) and projects every captured…- error-boundary — The
ErrorBoundarywraps every step of the per-request pipeline (design doc §6 steps 1–11) and projects every captured…
- error-boundary — The
- error-codes — This module owns every stable error code raised by
@suaveplan/api-hostand its sub-drivers (lifecycle, hot reload, ca…- error-codes — This module owns every stable error code raised by
@suaveplan/api-hostand its sub-drivers (lifecycle, hot reload, ca…
- error-codes — This module owns every stable error code raised by
- host —
createHost(config)composes every internal driver (LifecycleDriver,ReloadDriver,PluginLedger, `CapabilityRegi…- host —
createHost(config)composes every internal driver (LifecycleDriver,ReloadDriver,PluginLedger, `CapabilityRegi…
- host —
- hot-reload —
ReloadDriverimplements the §8.1 blue-green hot-reload primitive plus the §8.1aRollbackJournalintegration. Each `…- file-watcher —
FileWatcheris the dev-mode file-system watch primitive consumed byReloadDriver's §8.3 trigger path. Each `registe… - hot-reload —
ReloadDriverimplements the §8.1 blue-green hot-reload primitive plus the §8.1aRollbackJournalintegration. Each `…
- file-watcher —
- lifecycle —
LifecycleDriveris the runtime executor for the per-plugin lifecycle FSM defined in@suaveplan/api-lifecycle. It ow…- lifecycle —
LifecycleDriveris the runtime executor for the per-plugin lifecycle FSM defined in@suaveplan/api-lifecycle. It ow…
- lifecycle —
- otel —
createHostInstrumentsbuilds the frozen bundle of every OpenTelemetry counter and histogram the host emits on a produ…- otel —
createHostInstrumentsbuilds the frozen bundle of every OpenTelemetry counter and histogram the host emits on a produ…
- otel —
- in-memory-bus —
InMemoryPipelineEventsBusis the canonical fixture wired bycreateTestHost(test keystone) and consumed by every… - noop-bus —
NoopPipelineEventsBusis the default value the host installs onHostAdapters.pipelineEventswhen no operator-suppli… - pipeline-events-constants —
@suaveplan/api-typesis types-only — adding a runtime export there breaks the byte-size invariant CI enforces. The `P… - plugin-ledger —
PluginLedgeris the host-owned metadata store backing every plugin record the API host orchestrates. It persists the…- migrations —
HostMigrationRunneris the forward-only idempotent migration engine the API host runs against its plugin ledger DB. I… - plugin-ledger —
PluginLedgeris the host-owned metadata store backing every plugin record the API host orchestrates. It persists the…
- migrations —
- request-pipeline —
RequestPipelineimplements the design-doc §6 per-request data flow exactly: tenant resolve, CSRF check, session resol…- request-pipeline-driver — This module exports the
runPipelinefunction: the orchestrator that chains the §6 step gates (`request-pipeline-steps… - request-pipeline-emitters — This module owns the three side-effecting closers the §6 pipeline calls once a request has reached its outcome: `emitAu…
- request-pipeline-helpers — This module concentrates the pure (no-
this, no side-effecting) helpers the §6 request pipeline relies on: request-id… - request-pipeline-outcomes — This module ties the bare emitters and validators together for the orchestrator. It exposes
DriverConfig(the frozen… - request-pipeline-stage-emit — This module wraps the
PipelineEventsBus.emitcalls the §6 11-step driver makes around every stage. The helper central… - request-pipeline-stage-skip — The §6 11-step request pipeline has four stages (
csrf,capability,idempotency,audit) that may be conditionall… - request-pipeline-steps — This module hosts the six per-request gate functions the §6 pipeline runs after route match and before plugin handler i…
- request-pipeline-validation — This module owns the two Zod-validation functions the §6 pipeline runs:
validateRequest(step 6) parses body / query… - request-pipeline —
RequestPipelineimplements the design-doc §6 per-request data flow exactly: tenant resolve, CSRF check, session resol…
- request-pipeline-driver — This module exports the
- reserved-prefix — The reserved-prefix contract publishes the canonical list of URL path prefixes that
@suaveplan/api-host(and every fi…- reserved-prefix — The reserved-prefix contract publishes the canonical list of URL path prefixes that
@suaveplan/api-host(and every fi…
- reserved-prefix — The reserved-prefix contract publishes the canonical list of URL path prefixes that
- testing —
@suaveplan/api-host/testingis a reserved subpath in API plugin system. The intent is to popul…- create-test-host —
createTestHostis The keystone of the@suaveplan/api-host/testingsubpath. It composes every in-memory adap…- create-test-host —
createTestHostis The keystone of the@suaveplan/api-host/testingsubpath. It composes every in-memory adap…
- create-test-host —
- pipeline-events-conformance — This harness drives a host factory's
RequestPipelinethrough a known-shape happy-path request and a known-shape 404 r…- pipeline-events-conformance — This harness drives a host factory's
RequestPipelinethrough a known-shape happy-path request and a known-shape 404 r…
- pipeline-events-conformance — This harness drives a host factory's
- testing —
@suaveplan/api-host/testingis a reserved subpath in API plugin system. The intent is to popul…
- create-test-host —
Chunk status
@suaveplan/api-host ships in chunks per the precedent set by the @suaveplan/pdf migration. Chunk A — this release — ships the pieces every later chunk depends on:
| Subpath | Status | Description |
|---|---|---|
./error-codes |
✅ Chunk A | Full union of HOST_* / PLUGIN_* / RELOAD_* / CAPABILITY_* / ADMIN_* codes + default status map + HostError class. Every later chunk's codes are pre-declared so the union is stable. |
./define-plugin |
✅ Chunk A | definePlugin<const Caps>(spec) author DX + PluginModule<Caps> + derived context types. |
./capability-registry |
✅ Chunk A | Runtime CapabilityRegistry with semver-shape validation, duplicate detection, assertSatisfies compat check, reverse-order disposers. defineCapability(...) helper. |
./otel |
✅ Chunk A | createHostInstruments + HOST_COUNTER_NAMES (12) + HOST_HISTOGRAM_NAMES (4) covering the §12.3 surface; per-plugin meter cache. |
./testing |
✅ Test tier | Populated with createTestHost(config?) — composes every test in-memory adapter into a running Host in one line. The legacy STAGE_2_RESERVED sentinel flips to false. The runPipelineRouterConformance harness still ships from this subpath. |
./lifecycle |
⏳ Chunk B | LifecycleDriver — per-plugin FSM mutex, every §4 transition, auto-rollback hand-off, worker-tier crashed auto-restart. |
./hot-reload |
⏳ Chunk B | ReloadDriver — blue-green primitive, RollbackJournal ring buffer, drain timer, native-binding guard. |
./plugin-ledger |
⏳ Chunk C | Host-owned metadata DB + forward-only idempotent migrations. |
./admin-api |
⏳ Chunk C | Hono sub-router for §8.4 endpoints + RBAC + rate-limit + audit envelope. |
./error-boundary |
⏳ Chunk D | Per-step boundary mapping SuaveplanError → manifest statusMap, AbortError → 499. |
./request-pipeline |
⏳ Chunk D | Steps 1–11 from §6 in documented order + CSRF gating + streaming bypass. |
./host |
⏳ Chunk D | Top-level createHost(config) composing every driver. |
Until the follow-up chunks ship, this package is not a runnable host — it is the contract surface every downstream package can compile and link against.
Modules
src/error-codes/error-codes.md— error-code registry.src/define-plugin/define-plugin.md— author-facing plugin entry point.src/capability-registry/capability-registry.md— runtime capability registry.src/lifecycle/lifecycle.md—LifecycleDriverdriving every §4 transition.src/hot-reload/hot-reload.md—ReloadDriverblue-green primitive (§8.1).src/hot-reload/file-watcher.md— debounced filesystem watcher.src/plugin-ledger/plugin-ledger.md— SQLite-backed host metadata store.src/plugin-ledger/migrations.md— forward-only migration runner.src/admin-api/admin-api.md— Hono admin sub-router (§8.4).src/admin-api/audit-sink.md— pluggable audit sink.src/admin-api/idempotency-store.md— Idempotency-Key store.src/admin-api/rate-limiter.md— admin token-bucket limiter.src/error-boundary/error-boundary.md— §12.7 pipeline-step throw containment.src/request-pipeline/request-pipeline.md— §6 11-step per-request driver.src/host/host.md— top-levelcreateHost(config)composing every internal driver.src/otel/otel.md— host instrument registry.src/testing/testing.md— RESERVED subpath for test utilities.
Conformance posture
api-host carries suaveplan.conformanceSkip for api-lifecycle, api-loader, api-manifest, and api-secrets. These four packages each export a run*Conformance(factory) harness expecting the consumer to PROVIDE a concrete implementation of the contract (LifecycleDriverFactory, ManifestSchemaSet, etc.). api-host is the orchestrator that DRIVES those contracts — it consumes the abstract types, composes them via LifecycleDriver / ReloadDriver / RequestPipeline, and threads SecretsLike through ctx.secrets. It does not implement the abstract types itself.
The ./testing createTestHost(...) factory is the canonical proof that api-host composes the four contracts correctly. The e2e/foundation-stack-test-host Playwright suite drives every contract through createTestHost end-to-end and asserts on the observable behaviour (lifecycle install → start → handler invocation → secret resolution → ledger persistence). When the §16 check-conformance-tests.ts lint reports api-host as a consumer without conformance tests, the skip plus the e2e smoke is the documented answer.
If a future change extracts the conformance harnesses into adapter-agnostic forms (i.e., the harness signature shifts from factory: () => Impl to factory: () => Driver), the skip can be removed and the harness invoked through createTestHost's adapter bag.
Install
bun add @suaveplan/api-host
License
MIT