11 KiB
@suaveplan/api-manifest - Zod manifest schema, parser, cross-field validators, dep-graph resolver, capability resolver, and canonical hasher for Suaveplan API plugin system
Stage-1 contract package of the Suaveplan API plugin system: Zod schemas, parser, cross-field validators, dependency-graph resolver, capability resolver, and canonical hasher for the plugin.json manifest documented in
docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md §3.
This package is the single source of truth for the declarative half of every plugin contract. Every consumer (host loader, admin API, CLI scaffolder, OpenAPI emitter, definePlugin typings) imports from here — the schema does not live in any single host implementation.
Documentation tree
- capability-resolver — Decide whether a plugin can boot against the host's registered capability set. Missing required capabilities block reso…
- capability-resolver — Decide whether a plugin can boot against the host's registered capability set. Missing required capabilities block reso…
- dep-graph — Topologically order a set of plugin manifests so each plugin's
dependsOnentries precede it. Deterministic — lexicogr… - error-codes — Frozen
MANIFEST.*error-code registry plus the concreteSuaveplanErrorsubclass thrown by every public path in this…- error-codes — Frozen
MANIFEST.*error-code registry plus the concreteSuaveplanErrorsubclass thrown by every public path in this…
- error-codes — Frozen
- hash — Compute
sha256:<hex>over the canonical-JSON encoding of a manifest. Used byRollbackJournalentries and the plugin…- canonical-json — Canonical JSON encoder used by
hashManifest. Object keys are sorted lexicographically at every depth; array order is… - hash — Compute
sha256:<hex>over the canonical-JSON encoding of a manifest. Used byRollbackJournalentries and the plugin…
- canonical-json — Canonical JSON encoder used by
- parse — Two top-level entry points for converting an unknown JSON value into a typed
PluginManifest.parseManifestis the t…- parse — Two top-level entry points for converting an unknown JSON value into a typed
PluginManifest.parseManifestis the t…
- parse — Two top-level entry points for converting an unknown JSON value into a typed
- compat — Validates the compatibility block of a plugin manifest: the
apiHostsemver range and the two capability arrays (`requ… - config — Plugin-level config block.
schemaPathpoints at a JSON Schema the host validates user-supplied config against at inst… - database — Database-wiring block. Pins whether the plugin needs a database connection, which engines it supports, its current sche…
- depends-on — Map of plugin-name → semver range used by the dep-graph resolver. Names follow the same npm-package convention as `iden…
- errors — Plugin-error status-map block. Maps
PLUGIN.<DOMAIN>.<REASON>codes to HTTP status numbers and optional redaction path… - events — Event-bus topology declaration. Lists the subjects this plugin publishes and the subjects it subscribes to. Subjects fo…
- graphql — Optional GraphQL contribution block. When
contributesistrue, the host loads the SDL attypes(path relative to… - identity — Zod schema for the identity fields of a plugin manifest — the keys that uniquely identify a plugin in the registry and…
- isolation — Two Zod enum schemas covering the orthogonal isolation and trust axes of the manifest. Isolation determines how the hos…
- jobs — Background-job block: cron schedules and queued workers. Handlers live in the code half of the manifest; this block is…
- openapi — OpenAPI contribution block. When
contributes: truethe host emits a per-plugin OpenAPI document by introspecting the… - permissions — Zod schemas for the sandbox permissions block.
permissions.fsandpermissions.fetchare host-proxied allowlists hon… - plugin-manifest — Composite Zod schema joining every per-key sub-schema into a single strict-mode object. The inferred
PluginManifestt… - routes — Validates the declarative HTTP-routes block. Carries the route
prefixplus an optionalpublicRoutesarray — routes… - sagas — Saga ownership + participation block.
ownslists the sagas this plugin orchestrates (each with a non-empty step list)… - scopes — AuthZ scope declarations. Each entry pins a
resource:actionname and an optional human-readable description. The host… - secrets — Declares the named secrets the plugin needs at boot. Names use SCREAMING_SNAKE_CASE so they map cleanly onto environmen…
- sse — Server-Sent-Events endpoint declarations. Mirrors the WebSocket block's shape minus the heartbeat/connection cap — SSE…
- telemetry — Telemetry-instrument declarations. The host pre-registers every named counter, histogram, and gauge so plugin code can…
- two-phase-commit — Two-phase-commit participation declaration. A plugin sets
participates: trueto opt into the host's 2PC coordinator;… - uninstall — Uninstall data-handling policy. Three modes:
archive(move rows to a prefixed shadow table so they survive removal),… - websockets — Validates the WebSocket endpoint declarations. Each entry pins a path, an optional auth scope, the set of subjects the…
- testing — Reusable conformance harness for downstream tooling (admin CLI, IDE plugin) that ships its own
parseManifestimplemen…- conformance — Reusable conformance harness for downstream tooling (admin CLI, IDE plugin) that ships its own
parseManifestimplemen…
- conformance — Reusable conformance harness for downstream tooling (admin CLI, IDE plugin) that ships its own
- validate-error-status-map-shape — Defence-in-depth re-check of the
errors.statusMapshape. The Zod schema already rejects malformed entries; this valid… - validate-openapi-requires-graphql-or-routes — Rejects manifests that declare an OpenAPI contribution but expose neither HTTP routes nor a GraphQL contribution. The O…
- validate-permissions-when-sandboxed — Enforces that a
sandboxed-tier plugin declarespermissions.budgets. Without budgets the host can't enforce CPU/memo… - validate-saga-ownership — Cross-field validator that rejects sagas whose step list references a plugin neither owned by this manifest nor declare…
Install
bun add @suaveplan/api-manifest
Subpath exports
Each concern is a separate subpath so consumers tree-shake to exactly what they use.
./schema—pluginManifestSchema, the composite Zod schema, plus every per-key sub-schema../parse—parseManifestandparseManifestSafe../validators— four cross-field validators that Zod alone can't express../dep-graph—resolveInstallOrderand the in-housesatisfiessemver matcher../capability-resolver—resolveCapabilities../hash—hashManifestand the underlyingcanonicalJsonencoder../error-codes—MANIFEST_CODESregistry andManifestError../testing—runManifestConformanceharness and fixtures.
Modules
Schema
identity,compat,isolation,permissionsdepends-on,routes,graphqlwebsockets,sse,sagas,two-phase-commitdatabase,jobs,eventssecrets,config,scopestelemetry,openapi,errors,uninstallplugin-manifest— the composite schema.
Parse, validators, graph, capability, hash, testing
parsevalidate-saga-ownershipvalidate-permissions-when-sandboxedvalidate-openapi-requires-graphql-or-routesvalidate-error-status-map-shapedep-graph,semvercapability-resolverhash,canonical-jsontestingerror-codes
Error codes
Every code is namespaced under MANIFEST.* and produced by defineCodes. The eleven codes — PARSE_FAILED, DEPENDENCY_CYCLE, MISSING_DEPENDENCY, DEPENDENCY_VERSION_MISMATCH, CAPABILITY_REQUIRED_MISSING, CAPABILITY_VERSION_MISMATCH, OPTIONAL_CAPABILITY_MISSING, INVALID_SAGA_OWNERSHIP, SANDBOX_REQUIRES_BUDGETS, INVALID_ERROR_STATUS_MAP, OPENAPI_REQUIRES_GRAPHQL_OR_ROUTES — are pinned by a spec-conformance test and each has at least one production-path reference.
Dependencies
@suaveplan/api-types— the type-level view of the manifest (zero runtime).@suaveplan/error—SuaveplanError,defineCodes.@suaveplan/types— shared logger/clock/id-generator contracts.zod— runtime schema engine.
License
MIT