/**
 * ToolRegistry — manages available tools, the currently selected runtime
 * tool names, and system prompt rebuilding.
 *
 * The key boundary is:
 * - available tools: everything the runtime/extensions provide right now
 * - selected tools: the subset currently exposed to the model
 *
 * Refresh/reload rebuilds availability but preserves the current selection
 * and mode prompt unless the caller explicitly replaces them.
 */
import { EDIT, EXECUTE_TOOL, FIND, GREP, LS, READ } from '../../tool-names.js';
import { wrapToolsWithExtensions } from '../extensions/wrapper.js';
import { createDefaultPermissionPolicy, deriveModePermissionPolicy } from '../permissions/policy.js';
import { buildVisibleSkillsSection } from '../prompts/skill-section.js';
import { assembleSystemPrompt } from '../system-prompt.js';
function normalizePromptGuidelines(guidelines) {
    if (!guidelines || guidelines.length === 0)
        return [];
    const unique = new Set();
    for (const guideline of guidelines) {
        const normalized = guideline.trim();
        if (normalized.length > 0)
            unique.add(normalized);
    }
    return Array.from(unique);
}
const EXECUTE_TOOL_PERMISSION_TOOL_NAMES = [READ, EDIT, GREP, FIND, LS];
function getPermissionToolNames(toolNames) {
    const permissionToolNames = new Set(toolNames);
    if (permissionToolNames.has(EXECUTE_TOOL)) {
        for (const toolName of EXECUTE_TOOL_PERMISSION_TOOL_NAMES) {
            permissionToolNames.add(toolName);
        }
    }
    return Array.from(permissionToolNames);
}
export class ToolRegistry {
    _agent;
    _resourceLoader;
    _settingsManager;
    _cwd;
    _publishedTools = new Map();
    _availableTools = new Map();
    _runtimeTools = new Map();
    _extensionTools = new Map();
    _toolPromptGuidelines = new Map();
    _selectedRuntimeToolNames = [];
    _modeSystemPrompt;
    _extensionRunner;
    _baseSystemPrompt = '';
    _modeName;
    _permissionPolicy = createDefaultPermissionPolicy();
    _fixedPermissionPolicy;
    _getWorkspaceRoots() {
        return [...new Set([...(this._settingsManager.getWorkspaceRoots() ?? []), this._cwd])].filter((root) => typeof root === 'string' && root.trim().length > 0);
    }
    get baseSystemPrompt() {
        return this._baseSystemPrompt;
    }
    constructor(_agent, _resourceLoader, _settingsManager, _cwd, fixedPermissionPolicy) {
        this._agent = _agent;
        this._resourceLoader = _resourceLoader;
        this._settingsManager = _settingsManager;
        this._cwd = _cwd;
        this._fixedPermissionPolicy = fixedPermissionPolicy;
        if (fixedPermissionPolicy) {
            this._permissionPolicy = fixedPermissionPolicy;
        }
    }
    _getDangerouslySkipRuntimePermissions() {
        return this._settingsManager.getDangerouslySkipRuntimePermissions?.() ?? false;
    }
    _getDangerouslySkipSpreadsheetPermissions() {
        return this._settingsManager.getDangerouslySkipSpreadsheetPermissions?.() ?? false;
    }
    getAllTools() {
        return Array.from(this._availableTools.values()).map((tool) => ({
            name: tool.name,
            description: tool.description,
            parameters: tool.parameters
        }));
    }
    getToolNames() {
        return this._agent.state.tools.map((tool) => tool.name);
    }
    getPermissionPolicy() {
        if (this._fixedPermissionPolicy) {
            return this._fixedPermissionPolicy;
        }
        return deriveModePermissionPolicy(getPermissionToolNames(this._selectedRuntimeToolNames), this._modeName, this._getWorkspaceRoots(), this._settingsManager.getFilesystemApprovals(), this._getDangerouslySkipRuntimePermissions(), this._getDangerouslySkipSpreadsheetPermissions());
    }
    applyMode(toolNames, prompt, modeName) {
        this._modeSystemPrompt = prompt;
        this._modeName = modeName;
        this.replaceToolsByName(toolNames);
    }
    replaceToolsByName(toolNames) {
        this._selectedRuntimeToolNames = [...new Set(toolNames)];
        this._publishCurrentRegistry();
    }
    overrideBaseSystemPrompt(prompt) {
        this._baseSystemPrompt = prompt;
        this._agent.setSystemPrompt(prompt);
    }
    rebuildSystemPrompt(toolNames = Array.from(this._publishedTools.keys())) {
        const validToolNames = toolNames.filter((name) => this._availableTools.has(name));
        // Collect tool-provided guidelines (e.g. MCP, extension tools)
        const toolGuidelines = [];
        for (const name of validToolNames) {
            const guidelines = this._toolPromptGuidelines.get(name);
            if (guidelines)
                toolGuidelines.push(...guidelines);
        }
        // AgentController prompt: mode-specific prompt (from AgentDefinition), or an
        // internally injected prompt for subagent/task runtimes.
        const agentPrompt = this._modeSystemPrompt ?? this._resourceLoader.getSystemPrompt() ?? '';
        const skillsSection = buildVisibleSkillsSection(this._resourceLoader.getSkills().skills, this._settingsManager.getDisabledSkills());
        return assembleSystemPrompt({
            agentPrompt,
            skillsSection,
            contextFiles: this._resourceLoader.getAgentsFiles().agentsFiles,
            toolGuidelines: toolGuidelines.length > 0 ? toolGuidelines : undefined
        });
    }
    refresh(options) {
        this._extensionRunner = options.extensionRunner;
        this._rebuildAvailableTools(options.tools);
        if (options.modeName !== undefined) {
            this._modeName = options.modeName;
        }
        if (options.toolNames) {
            this._selectedRuntimeToolNames = [...new Set(options.toolNames)];
        }
        this._publishCurrentRegistry();
    }
    _rebuildAvailableTools(tools) {
        const registeredTools = this._extensionRunner?.getAllRegisteredTools() ?? [];
        const allRegisteredTools = [
            ...registeredTools,
            ...tools.map((definition) => ({ definition, extensionPath: '<sdk>' }))
        ];
        this._toolPromptGuidelines = new Map(allRegisteredTools
            .map((registeredTool) => {
            const guidelines = normalizePromptGuidelines(registeredTool.definition.promptGuidelines);
            return guidelines.length > 0
                ? [registeredTool.definition.name, guidelines]
                : undefined;
        })
            .filter((entry) => entry !== undefined));
        this._extensionTools = new Map(registeredTools.map((rt) => [rt.definition.name, rt.definition]));
        this._runtimeTools = new Map(tools.map((definition) => [definition.name, definition]));
        this._availableTools = new Map([...this._extensionTools, ...this._runtimeTools]);
    }
    _publishCurrentRegistry() {
        const selectedTools = [];
        const selectedNames = new Set();
        for (const [name, def] of this._extensionTools) {
            selectedTools.push(def);
            selectedNames.add(name);
        }
        for (const name of this._selectedRuntimeToolNames) {
            const def = this._runtimeTools.get(name);
            if (def && !selectedNames.has(name)) {
                selectedTools.push(def);
                selectedNames.add(name);
            }
        }
        // Wrap with extension event hooks (tool_call / tool_result interception)
        const finalTools = this._extensionRunner
            ? wrapToolsWithExtensions(selectedTools, this._extensionRunner)
            : selectedTools;
        this._publishedTools = new Map(finalTools.map((tool) => [tool.name, tool]));
        this._agent.setTools(finalTools);
        this._permissionPolicy =
            this._fixedPermissionPolicy ??
                deriveModePermissionPolicy(getPermissionToolNames(this._selectedRuntimeToolNames), this._modeName, this._getWorkspaceRoots(), this._settingsManager.getFilesystemApprovals(), this._getDangerouslySkipRuntimePermissions(), this._getDangerouslySkipSpreadsheetPermissions());
        this._baseSystemPrompt = this.rebuildSystemPrompt(Array.from(this._publishedTools.keys()));
        this._agent.setSystemPrompt(this._baseSystemPrompt);
    }
}
//# sourceMappingURL=tool-registry.js.map