# `capability-id` — `secrets` and `secrets.bun` constants _(no submodules)_ ## Purpose This module pins the two literal capability ids the api-secrets family contributes to the plugin-host `CapabilityId` union: `"secrets"` (the abstract Secrets capability, always provided by Stage-4 adapters) and `"secrets.bun"` (reserved here so plugin manifests can declare `requiredCapabilities: ["secrets.bun"]` at type-check time before The `api-secrets-bun` adapter ships). The constants are typed via `satisfies CapabilityId`, so if the union in `@suaveplan/api-types` ever drops either id this package's typecheck fails — surfacing a contract regression at the boundary instead of letting it slip into production. ## Features - `SECRETS_CAPABILITY_ID` — typed as the literal `"secrets"`. - `SECRETS_BUN_CAPABILITY_ID` — typed as the literal `"secrets.bun"`. - Compile-time invariant: both literals must remain assignable to `CapabilityId`. - Re-export of `CapabilityId` for downstream packages importing solely from `api-secrets`. ## Usage: Basic ```ts import { SECRETS_CAPABILITY_ID } from "@suaveplan/api-secrets/capability-id"; const requirements: readonly CapabilityId[] = [SECRETS_CAPABILITY_ID]; ``` ## Usage: Advanced Encode a plugin manifest's required capabilities as a literal-tuple so consumers downstream get autocompletion: ```ts import { SECRETS_BUN_CAPABILITY_ID, SECRETS_CAPABILITY_ID, type CapabilityId, } from "@suaveplan/api-secrets/capability-id"; const manifest = { name: "@example/billing", requiredCapabilities: [SECRETS_CAPABILITY_ID] as const, optionalCapabilities: [SECRETS_BUN_CAPABILITY_ID] as const, } satisfies { name: string; requiredCapabilities: readonly CapabilityId[]; optionalCapabilities: readonly CapabilityId[]; }; ``` ## API Reference - `type CapabilityId` — re-exported from `@suaveplan/api-types/capabilities`. - `const SECRETS_CAPABILITY_ID: "secrets"`. - `const SECRETS_BUN_CAPABILITY_ID: "secrets.bun"`. ## Implementation Notes Both constants use `as const satisfies CapabilityId` so the value type narrows to the literal AND the assignment-to-union invariant is checked. If a future api-types revision removes either id, this module fails to compile — the spec-conformance test in this folder then surfaces a clear error rather than a vague "literal not assignable". The `secrets.bun` id is reserved before its adapter exists specifically so plugin authors writing for the Bun deployment can ship manifests today; the host's capability resolver simply refuses to inject `ctx.secrets.bun` until The adapter is registered.