/**
 * Tool Registry - MCP-like tool system for CCW
 * Provides tool discovery, validation, and execution
 */
import http from 'http';
// Import TypeScript migrated tools (schema + handler)
import * as editFileMod from './edit-file.js';
import * as writeFileMod from './write-file.js';
import * as getModulesByDepthMod from './get-modules-by-depth.js';
import * as classifyFoldersMod from './classify-folders.js';
import * as detectChangedModulesMod from './detect-changed-modules.js';
import * as discoverDesignFilesMod from './discover-design-files.js';
import * as generateModuleDocsMod from './generate-module-docs.js';
import * as convertTokensToCssMod from './convert-tokens-to-css.js';
import * as sessionManagerMod from './session-manager.js';
import * as cliExecutorMod from './cli-executor.js';
import * as smartSearchMod from './smart-search.js';
import { executeInitWithProgress } from './smart-search.js';
// codex_lens removed - functionality integrated into smart_search
import * as readFileMod from './read-file.js';
import * as coreMemoryMod from './core-memory.js';
import * as contextCacheMod from './context-cache.js';
import * as skillContextLoaderMod from './skill-context-loader.js';
// Import legacy JS tools
import { uiGeneratePreviewTool } from './ui-generate-preview.js';
import { uiInstantiatePrototypesTool } from './ui-instantiate-prototypes.js';
import { updateModuleClaudeTool } from './update-module-claude.js';
// Tool registry
const tools = new Map();
// Dashboard notification settings
const DASHBOARD_PORT = process.env.CCW_PORT || 3456;
/**
 * Notify dashboard of tool execution events (fire and forget)
 */
function notifyDashboard(data) {
    const payload = JSON.stringify({
        type: 'tool_execution',
        ...data,
        timestamp: new Date().toISOString()
    });
    const req = http.request({
        hostname: 'localhost',
        port: Number(DASHBOARD_PORT),
        path: '/api/hook',
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Content-Length': Buffer.byteLength(payload)
        }
    });
    // Fire and forget - log errors only in debug mode
    req.on('error', (err) => {
        if (process.env.DEBUG)
            console.error('[Dashboard] Tool notification failed:', err.message);
    });
    req.write(payload);
    req.end();
}
/**
 * Convert new-style tool (schema + handler) to legacy format
 */
function toLegacyTool(mod) {
    return {
        name: mod.schema.name,
        description: mod.schema.description,
        parameters: {
            type: 'object',
            properties: mod.schema.inputSchema?.properties || {},
            required: mod.schema.inputSchema?.required || []
        },
        execute: async (params) => {
            const result = await mod.handler(params);
            if (!result.success) {
                throw new Error(result.error);
            }
            return result.result;
        }
    };
}
/**
 * Register a tool in the registry
 */
function registerTool(tool) {
    if (!tool.name || !tool.execute) {
        throw new Error('Tool must have name and execute function');
    }
    tools.set(tool.name, tool);
}
/**
 * Get all registered tools
 */
export function listTools() {
    return Array.from(tools.values()).map(tool => ({
        name: tool.name,
        description: tool.description,
        parameters: tool.parameters
    }));
}
/**
 * Get a specific tool by name
 */
export function getTool(name) {
    return tools.get(name) || null;
}
/**
 * Validate parameters against tool schema
 */
function validateParams(tool, params) {
    const errors = [];
    const schema = tool.parameters;
    if (!schema || !schema.properties) {
        return { valid: true, errors: [] };
    }
    // Check required parameters
    const required = schema.required || [];
    for (const req of required) {
        if (params[req] === undefined || params[req] === null) {
            errors.push(`Missing required parameter: ${req}`);
        }
    }
    // Type validation
    for (const [key, value] of Object.entries(params)) {
        const propSchema = schema.properties[key];
        if (!propSchema) {
            continue; // Allow extra params
        }
        if (propSchema.type === 'string' && typeof value !== 'string') {
            errors.push(`Parameter '${key}' must be a string`);
        }
        if (propSchema.type === 'boolean' && typeof value !== 'boolean') {
            errors.push(`Parameter '${key}' must be a boolean`);
        }
        if (propSchema.type === 'number' && typeof value !== 'number') {
            errors.push(`Parameter '${key}' must be a number`);
        }
    }
    return { valid: errors.length === 0, errors };
}
/**
 * Execute a tool with given parameters
 */
export async function executeTool(name, params = {}) {
    const tool = tools.get(name);
    if (!tool) {
        return {
            success: false,
            error: `Tool not found: ${name}`
        };
    }
    // Validate parameters
    const validation = validateParams(tool, params);
    if (!validation.valid) {
        return {
            success: false,
            error: `Parameter validation failed: ${validation.errors.join(', ')}`
        };
    }
    // Notify dashboard - execution started
    notifyDashboard({
        toolName: name,
        status: 'started',
        params: sanitizeParams(params)
    });
    // Execute tool
    try {
        const result = await tool.execute(params);
        // Notify dashboard - execution completed
        notifyDashboard({
            toolName: name,
            status: 'completed',
            result: sanitizeResult(result)
        });
        return {
            success: true,
            result
        };
    }
    catch (error) {
        // Notify dashboard - execution failed
        notifyDashboard({
            toolName: name,
            status: 'failed',
            error: error.message || 'Tool execution failed'
        });
        return {
            success: false,
            error: error.message || 'Tool execution failed'
        };
    }
}
/**
 * Sanitize params for notification (truncate large values)
 */
function sanitizeParams(params) {
    const sanitized = {};
    for (const [key, value] of Object.entries(params)) {
        if (typeof value === 'string' && value.length > 200) {
            sanitized[key] = value.substring(0, 200) + '...';
        }
        else if (typeof value === 'object' && value !== null) {
            sanitized[key] = '[Object]';
        }
        else {
            sanitized[key] = value;
        }
    }
    return sanitized;
}
/**
 * Sanitize result for notification (truncate large values)
 */
function sanitizeResult(result) {
    if (result === null || result === undefined)
        return result;
    const str = JSON.stringify(result);
    if (str.length > 500) {
        return { _truncated: true, preview: str.substring(0, 500) + '...' };
    }
    return result;
}
/**
 * Execute a tool with progress callback (for init actions)
 */
export async function executeToolWithProgress(name, params = {}, onProgress) {
    // For smart_search init, use special progress-aware execution
    if (name === 'smart_search' && params.action === 'init') {
        try {
            // Notify dashboard - execution started
            notifyDashboard({
                toolName: name,
                status: 'started',
                params: sanitizeParams(params)
            });
            const result = await executeInitWithProgress(params, onProgress);
            // Notify dashboard - execution completed
            notifyDashboard({
                toolName: name,
                status: 'completed',
                result: sanitizeResult(result)
            });
            return {
                success: result.success,
                result,
                error: result.error
            };
        }
        catch (error) {
            notifyDashboard({
                toolName: name,
                status: 'failed',
                error: error.message || 'Tool execution failed'
            });
            return {
                success: false,
                error: error.message || 'Tool execution failed'
            };
        }
    }
    // Fall back to regular execution for other tools
    return executeTool(name, params);
}
/**
 * Get tool schema in MCP-compatible format
 */
export function getToolSchema(name) {
    const tool = tools.get(name);
    if (!tool)
        return null;
    return {
        name: tool.name,
        description: tool.description,
        inputSchema: {
            type: 'object',
            properties: tool.parameters?.properties || {},
            required: tool.parameters?.required || []
        }
    };
}
/**
 * Get all tool schemas in MCP-compatible format
 */
export function getAllToolSchemas() {
    return Array.from(tools.keys()).map(name => getToolSchema(name)).filter((s) => s !== null);
}
// Register TypeScript migrated tools
registerTool(toLegacyTool(editFileMod));
registerTool(toLegacyTool(writeFileMod));
registerTool(toLegacyTool(getModulesByDepthMod));
registerTool(toLegacyTool(classifyFoldersMod));
registerTool(toLegacyTool(detectChangedModulesMod));
registerTool(toLegacyTool(discoverDesignFilesMod));
registerTool(toLegacyTool(generateModuleDocsMod));
registerTool(toLegacyTool(convertTokensToCssMod));
registerTool(toLegacyTool(sessionManagerMod));
registerTool(toLegacyTool(cliExecutorMod));
registerTool(toLegacyTool(smartSearchMod));
// codex_lens removed - functionality integrated into smart_search
registerTool(toLegacyTool(readFileMod));
registerTool(toLegacyTool(coreMemoryMod));
registerTool(toLegacyTool(contextCacheMod));
registerTool(toLegacyTool(skillContextLoaderMod));
// Register legacy JS tools
registerTool(uiGeneratePreviewTool);
registerTool(uiInstantiatePrototypesTool);
registerTool(updateModuleClaudeTool);
// Export for external tool registration
export { registerTool };
//# sourceMappingURL=index.js.map