/** Consequence class, declared per tool in PLUGIN.md. `publicAllowlist` and * `adminAllowlist` answer who may call a tool; this answers what happens when * they do. The classification rule lives in .docs/tool-risk-classes.md. */ export type RiskClass = 'read' | 'write_local' | 'exec' | 'external'; export declare const RISK_CLASSES: readonly RiskClass[]; /** True for every class other than `read` — the single question a downstream * gate or audit store asks of the registry, so it never needs a name list. */ export declare function isConsequential(riskClass: RiskClass): boolean; export interface ToolSurface { admin: ReadonlySet; public: ReadonlySet; /** Every declared tool across every plugin (both `tools:` and `hidden:` * entries). Used by the manager-boot drift assertion to verify that a * specialist's `tools:` frontmatter names tools that actually exist. */ all: ReadonlySet; /** Per-plugin MCP server descriptors. Key is the plugin directory name * (matches the `mcp____*` namespace). Spawned by Claude Code at * session start via `--mcp-config`. Plugins with `tools: []` contribute * no servers. */ mcpServers: ReadonlyMap; /** Declared consequence class per tool, keyed by the canonical long name. * One entry per `tools:` entry. `hidden:` names are bare strings with no * field slots, so they carry no class and do not appear here. */ riskByTool: ReadonlyMap; } export interface McpServerDescriptor { command: string; args: readonly string[]; env?: Readonly>; } export declare class ToolSurfaceError extends Error { readonly reason: string; readonly detail: string; constructor(reason: string, detail: string); } interface ToolEntry { name: string; publicAllowlist: boolean; adminAllowlist: boolean; riskClass: RiskClass; } /** A `hidden:` entry. No allowlist booleans: hidden is exactly "served by the * MCP server, absent from both allowlists", so declaring them would be two * ways to say the same thing. The risk class is required (Task 1998). */ interface HiddenEntry { name: string; riskClass: RiskClass; } /** Parse the tools: block out of a PLUGIN.md frontmatter body. Returns an * empty array when the frontmatter has no tools: key or declares `tools: []`. * Throws ToolSurfaceError on any malformed entry (missing name, missing or * non-boolean publicAllowlist or adminAllowlist). */ export declare function parseToolsBlock(frontmatter: string, pluginDir: string): ToolEntry[]; /** Parse the `hidden:` block out of a PLUGIN.md frontmatter body. Returns * one entry per tool declared as hidden — these tools are served by the * plugin's MCP server but excluded from agent-visible enumerations. They * count for the `all` surface so specialists may still name them in their * `tools:` frontmatter without tripping the drift assertion. * * Task 1998 — a hidden entry carries a `riskClass` on the same terms as a * `tools:` entry, because hidden means excluded from enumeration, not * excluded from being called. The pre-1998 bare-name shape (`- wifi`) is * rejected rather than tolerated: a schema accepting both would silently * re-create the gap where `riskByTool.get()` answered * `undefined` for a tool that is served. */ export declare function parseHiddenBlock(frontmatter: string, pluginDir: string): HiddenEntry[]; /** Parse the optional `mcp:` block out of a PLUGIN.md frontmatter body. * Returns null when the frontmatter has no `mcp:` key. Throws on a malformed * shape (missing command, args not a list, env not key:value pairs). The * schema mirrors Claude Code's `.mcp.json`. Platform plugins anchor on * ${PLATFORM_ROOT}; premium plugins anchor on ${PREMIUM_PLUGINS_ROOT} * (the sibling `premium-plugins/` directory). * * mcp: * command: node * args: * - ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js * - ${PLATFORM_ROOT}/plugins/memory/mcp/dist/index.js * env: * MCP_SPAWN_TEE_NAME: memory * ACCOUNT_ID: ${ACCOUNT_ID} */ export declare function parseMcpBlock(frontmatter: string, pluginDir: string): McpServerDescriptor | null; /** Walk a plugins root directory, parse every /PLUGIN.md, and return * the {admin, public, all, mcpServers} sets. Throws on the first malformed * manifest — the caller (the manager boot) must exit non-zero so the * operator sees the gap. * * Invariant: a plugin that declares `tools:` with at least one entry MUST * also declare an `mcp:` block. Without it the spawn would push * `--allowed-tools mcp____*` for a server that was never registered * with Claude Code; the tools would be unreachable and the operator would * see "tool not found" rather than a boot-time gap. */ export declare function loadToolSurface(pluginsRoots: string | readonly string[]): ToolSurface; export {}; //# sourceMappingURL=tool-surface.d.ts.map