# `capability-id` — `"auth.provider"` capability contribution _(no submodules)_ ## Purpose The `capability-id` module pins the runtime literal for the `"auth.provider"` capability this package contributes to the host's capability registry. The closed `CapabilityId` union in `@suaveplan/api-types` already includes `"auth.provider"` (alongside `"auth.session"`); this module simply exposes a typed constant and predicate so concrete providers, the host's capability resolver, and downstream plugin manifests can author against a single value rather than a free-form string. Centralising the literal gives us one place to grep if the id ever needs to evolve via an OpenSpec change. ## Features - `AUTH_PROVIDER_CAPABILITY_ID` constant pinned to `"auth.provider"` via a `satisfies` clause that fails the build if the literal drifts out of the `CapabilityId` union. - `isAuthProviderCapabilityId(value)` runtime type-guard for capability descriptors that flow through `unknown`. - `AuthProviderCapabilityId` type alias — `Extract` — so consumers can name the type without re-spelling the literal. ## Usage: Basic ```ts import { AUTH_PROVIDER_CAPABILITY_ID } from "@suaveplan/api-auth-provider/capability-id"; definePlugin({ requires: [AUTH_PROVIDER_CAPABILITY_ID] as const, start: async (ctx) => { // ctx.capabilities["auth.provider"] is now in scope. }, }); ``` ## Usage: Advanced The host's capability resolver inspects untyped descriptors and narrows them to the typed slot via the predicate: ```ts import { AUTH_PROVIDER_CAPABILITY_ID, isAuthProviderCapabilityId, } from "@suaveplan/api-auth-provider/capability-id"; function bindCapability(descriptor: { id: string }) { if (isAuthProviderCapabilityId(descriptor.id)) { // descriptor.id is now typed as "auth.provider". registerSlot(AUTH_PROVIDER_CAPABILITY_ID, descriptor); } } ``` ## API Reference - `const AUTH_PROVIDER_CAPABILITY_ID: AuthProviderCapabilityId` — frozen literal. - `function isAuthProviderCapabilityId(value: string): value is AuthProviderCapabilityId` - `type AuthProviderCapabilityId = Extract` ## Implementation Notes The `satisfies` clause is the load-bearing line of the module — if the `CapabilityId` union ever loses `"auth.provider"`, the build fails here rather than downstream. The predicate uses an equality test against the constant rather than the literal to keep the two in lockstep — if a future change renames the id, the constant and predicate move together. There is intentionally no companion type-augmentation block here; the union in `@suaveplan/api-types` is closed and pre-includes every capability the host knows about, so adding a capability is a co-located OpenSpec change to that package and not a downstream module-augmentation pattern.