import { type ClientId } from '@zhixuan92/multi-model-agent-core'; /** How a client's skills are laid out on disk. 'none' means the client has * no Agent Skills mechanism at all -- registration alone is a complete, * successful install for it (FR-8). */ type SkillPathStrategy = 'standard' | 'bespoke' | 'none'; /** The shape and location of a client's MCP registration entry. */ export type McpConfigFormat = 'json' | 'toml' | 'plugin-json' | 'stdio-json'; /** * The primary-source evidence backing a client's writer. * * Present for exactly the clients `docs/verification/ * mcp-client-registration-profiles.md` covers and marks ready. The five writers * that predate that artifact (claude-code, claude-desktop, codex, antigravity, * cursor) carry no profile -- their absence records that they were not verified * through this gate, and pretending otherwise by back-filling a profile nobody * researched would make the gate a decoration. * * The rule is enforced from the artifact rather than from a list in code: see * `tests/contract/clients/gated-registration-writers.test.ts`, which reads that * document and requires the capability row and the writer registry to agree with * every client it covers. */ interface RegistrationProfile { /** The exact vendor-owned source URL this profile was verified against. * Must appear verbatim in the evidence artifact. */ verifiedBy: string; /** The verified user-level registration path, human-readable (writers resolve * their own actual path; this is the evidence record, not executable). */ path: string; /** How MMA recognises its own previously-written entry in this client's file. */ ownershipRecognizer: string; /** The client's own connect-time credential substitution mechanism. Never a * static token. */ dynamicCredentialMechanism: string; } export interface ClientCapability { id: ClientId; skillPathStrategy: SkillPathStrategy; /** EXACTLY ONE root, or null. Required to be null when -- and only when -- * skillPathStrategy is 'none'. */ skillRoot: string | null; /** Plural on purpose: a client may have OS-specific registration locations * (Claude Desktop's macOS vs Windows paths). Unrelated to skill roots. * * EMPTY means "no verified path, so no writer may target this client". * Emptiness is the uniform, checkable signal -- never leave a half-trusted * path here. * * TWO rows are empty, for opposite reasons, and each row states its own: * `vscode` never had a derivable home-level path to begin with, and * `antigravity` had one that the vendor retired. See * docs/verification/mcp-client-registration-profiles.md. */ mcpConfigPaths: readonly string[]; mcpConfigFormat: McpConfigFormat; /** The top-level key a client's registration file nests its MCP servers under. * Defaults to `mcpServers` when omitted -- every client but opencode uses that * default; opencode verified its own servers live under a top-level `mcp` key * instead. Read by `registration-writer.ts` so a differently-keyed client * never needs a second, forked install path. */ mcpTopLevelKey?: string; /** Present for exactly the clients the evidence artifact covers and marks * ready. `vscode` stays without one -- it remains BLOCKED. See the * {@link RegistrationProfile} doc for why the older writers carry none. */ registrationProfile?: RegistrationProfile; } /** The frozen capability registry -- exactly one row per ClientId, in * CLIENT_IDS order. See the spec's Data model table; values are used * verbatim. */ export declare const CLIENT_CAPABILITIES: readonly ClientCapability[]; export {}; //# sourceMappingURL=capability-registry.d.ts.map