export interface ToolSurface {
    admin: ReadonlySet<string>;
    public: ReadonlySet<string>;
    /** 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<string>;
    /** Per-plugin MCP server descriptors. Key is the plugin directory name
     *  (matches the `mcp__<plugin>__*` namespace). Spawned by Claude Code at
     *  session start via `--mcp-config`. Plugins with `tools: []` contribute
     *  no servers. */
    mcpServers: ReadonlyMap<string, McpServerDescriptor>;
}
export interface McpServerDescriptor {
    command: string;
    args: readonly string[];
    env?: Readonly<Record<string, string>>;
}
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;
}
/** 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
 *  the list of tool names 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. */
export declare function parseHiddenBlock(frontmatter: string): string[];
/** 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 <name>/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__<plugin>__*` 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