/**
 * CLI Routes Module
 * Handles all CLI-related API endpoints
 */
import { getCliToolsStatus, getCliToolsFullStatus, installCliTool, uninstallCliTool, enableCliTool, disableCliTool, getExecutionHistoryAsync, getConversationDetailWithNativeInfo, deleteExecutionAsync, batchDeleteExecutionsAsync, executeCliTool, getNativeSessionContent, getFormattedNativeConversation, getEnrichedConversation, getHistoryWithNativeInfo } from '../../tools/cli-executor.js';
import { SmartContentFormatter } from '../../tools/cli-output-converter.js';
import { generateSmartContext, formatSmartContext } from '../../tools/smart-context.js';
import { getToolConfig, updateToolConfig, getFullConfigResponse } from '../../tools/cli-config-manager.js';
import { loadClaudeCliTools, ensureClaudeCliTools, saveClaudeCliTools, loadClaudeCliSettings, saveClaudeCliSettings, updateClaudeToolEnabled, updateClaudeCacheSettings, getClaudeCliToolsInfo, addClaudeApiEndpoint, removeClaudeApiEndpoint, // @deprecated - kept for backward compatibility
updateCodeIndexMcp, getCodeIndexMcp } from '../../tools/claude-cli-tools.js';
const activeExecutions = new Map();
const EXECUTION_RETENTION_MS = 5 * 60 * 1000; // 5 minutes
/**
 * Cleanup stale completed executions older than retention period
 * Runs periodically to prevent memory buildup
 */
export function cleanupStaleExecutions() {
    const now = Date.now();
    const staleIds = [];
    for (const [id, exec] of activeExecutions.entries()) {
        if (exec.completedTimestamp && (now - exec.completedTimestamp) > EXECUTION_RETENTION_MS) {
            staleIds.push(id);
        }
    }
    staleIds.forEach(id => {
        activeExecutions.delete(id);
        console.log(`[ActiveExec] Cleaned up stale execution: ${id}`);
    });
    if (staleIds.length > 0) {
        console.log(`[ActiveExec] Cleaned up ${staleIds.length} stale execution(s), remaining: ${activeExecutions.size}`);
    }
}
/**
 * Get all active CLI executions
 * Used by frontend to restore state when view is opened during execution
 */
export function getActiveExecutions() {
    return Array.from(activeExecutions.values());
}
/**
 * Update active execution state from hook events
 * Called by hooks-routes when CLI events are received from terminal execution
 */
export function updateActiveExecution(event) {
    const { type, executionId, tool, mode, prompt, output, success } = event;
    // Debug log for troubleshooting
    console.log(`[ActiveExec] ${type}: ${executionId} (current count: ${activeExecutions.size})`);
    if (!executionId) {
        console.warn('[ActiveExec] Missing executionId, skipping');
        return;
    }
    if (type === 'started') {
        // Create new active execution
        activeExecutions.set(executionId, {
            id: executionId,
            tool: tool || 'unknown',
            mode: mode || 'analysis',
            prompt: (prompt || '').substring(0, 500),
            startTime: Date.now(),
            output: '',
            status: 'running'
        });
    }
    else if (type === 'output') {
        // Append output to existing execution
        const activeExec = activeExecutions.get(executionId);
        if (activeExec && output) {
            activeExec.output += output;
        }
    }
    else if (type === 'completed') {
        // Mark as completed with timestamp for retention-based cleanup
        const activeExec = activeExecutions.get(executionId);
        if (activeExec) {
            activeExec.status = success ? 'completed' : 'error';
            activeExec.completedTimestamp = Date.now();
            console.log(`[ActiveExec] Marked as ${activeExec.status}, retained for ${EXECUTION_RETENTION_MS / 1000}s`);
        }
    }
}
/**
 * Handle CLI routes
 * @returns true if route was handled, false otherwise
 */
export async function handleCliRoutes(ctx) {
    const { pathname, url, req, res, initialPath, handlePostRequest, broadcastToClients } = ctx;
    // API: Get Active CLI Executions (for state recovery)
    if (pathname === '/api/cli/active' && req.method === 'GET') {
        const executions = getActiveExecutions().map(exec => ({
            ...exec,
            isComplete: exec.status !== 'running'
        }));
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ executions }));
        return true;
    }
    // API: CLI Tools Status
    if (pathname === '/api/cli/status') {
        const status = await getCliToolsStatus();
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(status));
        return true;
    }
    // API: CLI Tools Full Status (with enabled state)
    if (pathname === '/api/cli/full-status') {
        const status = await getCliToolsFullStatus();
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(status));
        return true;
    }
    // API: Install CLI Tool
    if (pathname === '/api/cli/install' && req.method === 'POST') {
        handlePostRequest(req, res, async (body) => {
            const { tool } = body;
            if (!tool) {
                return { error: 'Tool name is required', status: 400 };
            }
            const result = await installCliTool(tool);
            if (result.success) {
                // Broadcast tool installed event
                broadcastToClients({
                    type: 'CLI_TOOL_INSTALLED',
                    payload: { tool, timestamp: new Date().toISOString() }
                });
                return { success: true, message: `${tool} installed successfully` };
            }
            else {
                return { success: false, error: result.error, status: 500 };
            }
        });
        return true;
    }
    // API: Uninstall CLI Tool
    if (pathname === '/api/cli/uninstall' && req.method === 'POST') {
        handlePostRequest(req, res, async (body) => {
            const { tool } = body;
            if (!tool) {
                return { error: 'Tool name is required', status: 400 };
            }
            const result = await uninstallCliTool(tool);
            if (result.success) {
                // Broadcast tool uninstalled event
                broadcastToClients({
                    type: 'CLI_TOOL_UNINSTALLED',
                    payload: { tool, timestamp: new Date().toISOString() }
                });
                return { success: true, message: `${tool} uninstalled successfully` };
            }
            else {
                return { success: false, error: result.error, status: 500 };
            }
        });
        return true;
    }
    // API: Enable CLI Tool
    if (pathname === '/api/cli/enable' && req.method === 'POST') {
        handlePostRequest(req, res, async (body) => {
            const { tool } = body;
            if (!tool) {
                return { error: 'Tool name is required', status: 400 };
            }
            const result = enableCliTool(tool);
            // Broadcast tool enabled event
            broadcastToClients({
                type: 'CLI_TOOL_ENABLED',
                payload: { tool, timestamp: new Date().toISOString() }
            });
            return { success: true, message: `${tool} enabled` };
        });
        return true;
    }
    // API: Disable CLI Tool
    if (pathname === '/api/cli/disable' && req.method === 'POST') {
        handlePostRequest(req, res, async (body) => {
            const { tool } = body;
            if (!tool) {
                return { error: 'Tool name is required', status: 400 };
            }
            const result = disableCliTool(tool);
            // Broadcast tool disabled event
            broadcastToClients({
                type: 'CLI_TOOL_DISABLED',
                payload: { tool, timestamp: new Date().toISOString() }
            });
            return { success: true, message: `${tool} disabled` };
        });
        return true;
    }
    // API: Get Full CLI Config (with predefined models)
    if (pathname === '/api/cli/config' && req.method === 'GET') {
        try {
            const response = getFullConfigResponse(initialPath);
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify(response));
        }
        catch (err) {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: err.message }));
        }
        return true;
    }
    // API: Get/Update Tool Config
    const configMatch = pathname.match(/^\/api\/cli\/config\/(gemini|qwen|codex|claude|opencode)$/);
    if (configMatch) {
        const tool = configMatch[1];
        // GET: Get single tool config
        if (req.method === 'GET') {
            try {
                const toolConfig = getToolConfig(initialPath, tool);
                res.writeHead(200, { 'Content-Type': 'application/json' });
                res.end(JSON.stringify(toolConfig));
            }
            catch (err) {
                res.writeHead(500, { 'Content-Type': 'application/json' });
                res.end(JSON.stringify({ error: err.message }));
            }
            return true;
        }
        // PUT: Update tool config
        if (req.method === 'PUT') {
            handlePostRequest(req, res, async (body) => {
                try {
                    const updates = body;
                    const updated = updateToolConfig(initialPath, tool, updates);
                    // Broadcast config updated event
                    broadcastToClients({
                        type: 'CLI_CONFIG_UPDATED',
                        payload: { tool, config: updated, timestamp: new Date().toISOString() }
                    });
                    return { success: true, config: updated };
                }
                catch (err) {
                    return { error: err.message, status: 500 };
                }
            });
            return true;
        }
    }
    // Helper: Get API endpoints from tools (type: 'api-endpoint')
    const getApiEndpointsFromTools = (config) => {
        return Object.entries(config.tools)
            .filter(([_, t]) => t.type === 'api-endpoint')
            .map(([name, t]) => ({ id: t.id || name, name, enabled: t.enabled }));
    };
    // API: Get all API endpoints (for --tool custom --model <id>)
    if (pathname === '/api/cli/endpoints' && req.method === 'GET') {
        try {
            // Use ensureClaudeCliTools to auto-create config if missing
            const config = ensureClaudeCliTools(initialPath);
            const endpoints = getApiEndpointsFromTools(config);
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ endpoints }));
        }
        catch (err) {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: err.message }));
        }
        return true;
    }
    // API: Add/Update API endpoint
    if (pathname === '/api/cli/endpoints' && req.method === 'POST') {
        handlePostRequest(req, res, async (body) => {
            try {
                const { id, name, enabled } = body;
                if (!id || !name) {
                    return { error: 'id and name are required', status: 400 };
                }
                const config = addClaudeApiEndpoint(initialPath, { id, name, enabled: enabled !== false });
                broadcastToClients({
                    type: 'CLI_ENDPOINT_UPDATED',
                    payload: { endpoint: { id, name, enabled }, timestamp: new Date().toISOString() }
                });
                return { success: true, endpoints: getApiEndpointsFromTools(config) };
            }
            catch (err) {
                return { error: err.message, status: 500 };
            }
        });
        return true;
    }
    // API: Update API endpoint enabled status
    if (pathname.match(/^\/api\/cli\/endpoints\/[^/]+$/) && req.method === 'PUT') {
        const endpointId = pathname.split('/').pop() || '';
        handlePostRequest(req, res, async (body) => {
            try {
                const { enabled, name: newName } = body;
                const config = loadClaudeCliTools(initialPath);
                // Find the tool by id (api-endpoint type)
                const toolEntry = Object.entries(config.tools).find(([_, t]) => t.type === 'api-endpoint' && t.id === endpointId);
                if (!toolEntry) {
                    return { error: 'Endpoint not found', status: 404 };
                }
                const [toolName, tool] = toolEntry;
                if (typeof enabled === 'boolean')
                    tool.enabled = enabled;
                // If name changes, we need to rename the key
                if (newName && newName !== toolName) {
                    delete config.tools[toolName];
                    config.tools[newName] = tool;
                }
                saveClaudeCliTools(initialPath, config);
                const endpoint = { id: tool.id || toolName, name: newName || toolName, enabled: tool.enabled };
                broadcastToClients({
                    type: 'CLI_ENDPOINT_UPDATED',
                    payload: { endpoint, timestamp: new Date().toISOString() }
                });
                return { success: true, endpoint };
            }
            catch (err) {
                return { error: err.message, status: 500 };
            }
        });
        return true;
    }
    // API: Delete API endpoint
    if (pathname.match(/^\/api\/cli\/endpoints\/[^/]+$/) && req.method === 'DELETE') {
        const endpointId = pathname.split('/').pop() || '';
        try {
            const config = removeClaudeApiEndpoint(initialPath, endpointId);
            broadcastToClients({
                type: 'CLI_ENDPOINT_DELETED',
                payload: { endpointId, timestamp: new Date().toISOString() }
            });
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ success: true, endpoints: getApiEndpointsFromTools(config) }));
        }
        catch (err) {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: err.message }));
        }
        return true;
    }
    // API: CLI Execution History
    if (pathname === '/api/cli/history') {
        const projectPath = url.searchParams.get('path') || initialPath;
        const limit = parseInt(url.searchParams.get('limit') || '50', 10);
        const tool = url.searchParams.get('tool') || null;
        const status = url.searchParams.get('status') || null;
        const category = url.searchParams.get('category');
        const search = url.searchParams.get('search') || null;
        const recursive = url.searchParams.get('recursive') !== 'false';
        getExecutionHistoryAsync(projectPath, { limit, tool, status, category, search, recursive })
            .then(history => {
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify(history));
        })
            .catch(err => {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: err.message }));
        });
        return true;
    }
    // API: CLI Execution Detail (GET) or Delete (DELETE)
    if (pathname === '/api/cli/execution') {
        const projectPath = url.searchParams.get('path') || initialPath;
        const executionId = url.searchParams.get('id');
        if (!executionId) {
            res.writeHead(400, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: 'Execution ID is required' }));
            return true;
        }
        // Handle DELETE request
        if (req.method === 'DELETE') {
            deleteExecutionAsync(projectPath, executionId)
                .then(result => {
                if (result.success) {
                    res.writeHead(200, { 'Content-Type': 'application/json' });
                    res.end(JSON.stringify({ success: true, message: 'Execution deleted' }));
                }
                else {
                    res.writeHead(500, { 'Content-Type': 'application/json' });
                    res.end(JSON.stringify({ error: result.error || 'Delete failed' }));
                }
            })
                .catch(err => {
                res.writeHead(500, { 'Content-Type': 'application/json' });
                res.end(JSON.stringify({ error: err.message }));
            });
            return true;
        }
        // Handle GET request - return conversation with native session info
        const conversation = getConversationDetailWithNativeInfo(projectPath, executionId);
        if (!conversation) {
            res.writeHead(404, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: 'Conversation not found' }));
            return true;
        }
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(conversation));
        return true;
    }
    // API: Batch Delete CLI Executions
    if (pathname === '/api/cli/batch-delete' && req.method === 'POST') {
        handlePostRequest(req, res, async (body) => {
            const { path: projectPath, ids } = body;
            if (!ids || !Array.isArray(ids) || ids.length === 0) {
                return { error: 'ids array is required', status: 400 };
            }
            const basePath = projectPath || initialPath;
            return await batchDeleteExecutionsAsync(basePath, ids);
        });
        return true;
    }
    // API: Get Native Session Content
    if (pathname === '/api/cli/native-session') {
        const projectPath = url.searchParams.get('path') || initialPath;
        const executionId = url.searchParams.get('id');
        const format = url.searchParams.get('format') || 'json';
        if (!executionId) {
            res.writeHead(400, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: 'Execution ID is required' }));
            return true;
        }
        try {
            let result;
            if (format === 'text') {
                result = await getFormattedNativeConversation(projectPath, executionId, {
                    includeThoughts: url.searchParams.get('thoughts') === 'true',
                    includeToolCalls: url.searchParams.get('tools') === 'true',
                    includeTokens: url.searchParams.get('tokens') === 'true'
                });
            }
            else if (format === 'pairs') {
                const enriched = await getEnrichedConversation(projectPath, executionId);
                result = enriched?.merged || null;
            }
            else {
                result = await getNativeSessionContent(projectPath, executionId);
            }
            if (!result) {
                res.writeHead(404, { 'Content-Type': 'application/json' });
                res.end(JSON.stringify({ error: 'Native session not found' }));
                return true;
            }
            res.writeHead(200, { 'Content-Type': format === 'text' ? 'text/plain' : 'application/json' });
            res.end(format === 'text' ? result : JSON.stringify(result));
        }
        catch (err) {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: err.message }));
        }
        return true;
    }
    // API: Get Enriched Conversation
    if (pathname === '/api/cli/enriched') {
        const projectPath = url.searchParams.get('path') || initialPath;
        const executionId = url.searchParams.get('id');
        if (!executionId) {
            res.writeHead(400, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: 'Execution ID is required' }));
            return true;
        }
        getEnrichedConversation(projectPath, executionId)
            .then(result => {
            if (!result) {
                res.writeHead(404, { 'Content-Type': 'application/json' });
                res.end(JSON.stringify({ error: 'Conversation not found' }));
                return;
            }
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify(result));
        })
            .catch(err => {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: err.message }));
        });
        return true;
    }
    // API: Get History with Native Session Info
    if (pathname === '/api/cli/history-native') {
        const projectPath = url.searchParams.get('path') || initialPath;
        const limit = parseInt(url.searchParams.get('limit') || '50', 10);
        const tool = url.searchParams.get('tool') || null;
        const status = url.searchParams.get('status') || null;
        const category = url.searchParams.get('category');
        const search = url.searchParams.get('search') || null;
        const recursive = url.searchParams.get('recursive') !== 'false';
        getHistoryWithNativeInfo(projectPath, { limit, tool, status, category, search, recursive })
            .then(history => {
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify(history));
        })
            .catch(err => {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: err.message }));
        });
        return true;
    }
    // API: Execute CLI Tool
    if (pathname === '/api/cli/execute' && req.method === 'POST') {
        handlePostRequest(req, res, async (body) => {
            const { tool, prompt, mode, format, model, dir, includeDirs, timeout, smartContext, parentExecutionId, category } = body;
            if (!tool || !prompt) {
                return { error: 'tool and prompt are required', status: 400 };
            }
            // Generate smart context if enabled
            let finalPrompt = prompt;
            if (smartContext?.enabled) {
                try {
                    const contextResult = await generateSmartContext(prompt, {
                        enabled: true,
                        maxFiles: smartContext.maxFiles || 10,
                        searchMode: 'text'
                    }, dir || initialPath);
                    const contextAppendage = formatSmartContext(contextResult);
                    if (contextAppendage) {
                        finalPrompt = prompt + contextAppendage;
                    }
                }
                catch (err) {
                    console.warn('[Smart Context] Failed to generate:', err);
                }
            }
            const executionId = `${Date.now()}-${tool}`;
            // Store active execution for state recovery
            activeExecutions.set(executionId, {
                id: executionId,
                tool,
                mode: mode || 'analysis',
                prompt: prompt.substring(0, 500), // Truncate for display
                startTime: Date.now(),
                output: '',
                status: 'running'
            });
            // Broadcast execution started
            broadcastToClients({
                type: 'CLI_EXECUTION_STARTED',
                payload: {
                    executionId,
                    tool,
                    mode: mode || 'analysis',
                    parentExecutionId,
                    timestamp: new Date().toISOString()
                }
            });
            try {
                const result = await executeCliTool({
                    tool,
                    prompt: finalPrompt,
                    mode: mode || 'analysis',
                    format: format || 'plain',
                    model,
                    cd: dir || initialPath,
                    includeDirs,
                    timeout: timeout || 0, // 0 = no internal timeout, controlled by external caller
                    category: category || 'user',
                    parentExecutionId,
                    stream: true
                }, (unit) => {
                    // CliOutputUnit handler: use SmartContentFormatter for intelligent formatting (never returns null)
                    const content = SmartContentFormatter.format(unit.content, unit.type);
                    // Append to active execution buffer
                    const activeExec = activeExecutions.get(executionId);
                    if (activeExec) {
                        activeExec.output += content || '';
                    }
                    broadcastToClients({
                        type: 'CLI_OUTPUT',
                        payload: {
                            executionId,
                            chunkType: unit.type,
                            data: content
                        }
                    });
                });
                // Mark as completed with timestamp for retention-based cleanup (not immediate delete)
                const activeExec = activeExecutions.get(executionId);
                if (activeExec) {
                    activeExec.status = result.success ? 'completed' : 'error';
                    activeExec.completedTimestamp = Date.now();
                    console.log(`[ActiveExec] Direct execution ${executionId} marked as ${activeExec.status}, retained for ${EXECUTION_RETENTION_MS / 1000}s`);
                }
                // Broadcast completion
                broadcastToClients({
                    type: 'CLI_EXECUTION_COMPLETED',
                    payload: {
                        executionId,
                        success: result.success,
                        status: result.execution.status,
                        duration_ms: result.execution.duration_ms
                    }
                });
                return {
                    success: result.success,
                    execution: result.execution
                };
            }
            catch (error) {
                // Mark as completed with timestamp for retention-based cleanup (not immediate delete)
                const activeExec = activeExecutions.get(executionId);
                if (activeExec) {
                    activeExec.status = 'error';
                    activeExec.completedTimestamp = Date.now();
                    console.log(`[ActiveExec] Direct execution ${executionId} marked as error, retained for ${EXECUTION_RETENTION_MS / 1000}s`);
                }
                broadcastToClients({
                    type: 'CLI_EXECUTION_ERROR',
                    payload: {
                        executionId,
                        error: error.message
                    }
                });
                return { error: error.message, status: 500 };
            }
        });
        return true;
    }
    // API: CLI Review - Submit review for an execution
    if (pathname.startsWith('/api/cli/review/') && req.method === 'POST') {
        const executionId = pathname.replace('/api/cli/review/', '');
        handlePostRequest(req, res, async (body) => {
            const { status, rating, comments, reviewer } = body;
            if (!status) {
                return { error: 'status is required', status: 400 };
            }
            try {
                const historyStore = await import('../../tools/cli-history-store.js').then(m => m.getHistoryStore(initialPath));
                const execution = historyStore.getConversation(executionId);
                if (!execution) {
                    return { error: 'Execution not found', status: 404 };
                }
                const review = historyStore.saveReview({
                    execution_id: executionId,
                    status,
                    rating,
                    comments,
                    reviewer
                });
                broadcastToClients({
                    type: 'CLI_REVIEW_UPDATED',
                    payload: {
                        executionId,
                        review,
                        timestamp: new Date().toISOString()
                    }
                });
                return { success: true, review };
            }
            catch (error) {
                return { error: error.message, status: 500 };
            }
        });
        return true;
    }
    // API: CLI Review - Get review for an execution
    if (pathname.startsWith('/api/cli/review/') && req.method === 'GET') {
        const executionId = pathname.replace('/api/cli/review/', '');
        try {
            const historyStore = await import('../../tools/cli-history-store.js').then(m => m.getHistoryStore(initialPath));
            const review = historyStore.getReview(executionId);
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ review }));
        }
        catch (error) {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: error.message }));
        }
        return true;
    }
    // API: CLI Reviews - List all reviews
    if (pathname === '/api/cli/reviews' && req.method === 'GET') {
        try {
            const historyStore = await import('../../tools/cli-history-store.js').then(m => m.getHistoryStore(initialPath));
            const statusFilter = url.searchParams.get('status');
            const limit = parseInt(url.searchParams.get('limit') || '50', 10);
            const reviews = historyStore.getReviews({
                status: statusFilter || undefined,
                limit
            });
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ reviews, count: reviews.length }));
        }
        catch (error) {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: error.message }));
        }
        return true;
    }
    // API: Get CLI Tools Config from .claude/cli-tools.json (with fallback to global)
    if (pathname === '/api/cli/tools-config' && req.method === 'GET') {
        try {
            // Use ensureClaudeCliTools to auto-create config if missing
            const toolsConfig = ensureClaudeCliTools(initialPath);
            const settingsConfig = loadClaudeCliSettings(initialPath);
            const info = getClaudeCliToolsInfo(initialPath);
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({
                tools: toolsConfig,
                settings: settingsConfig,
                _configInfo: info
            }));
        }
        catch (err) {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: err.message }));
        }
        return true;
    }
    // API: Update CLI Tools Config
    if (pathname === '/api/cli/tools-config' && req.method === 'PUT') {
        handlePostRequest(req, res, async (body) => {
            try {
                const updates = body;
                // Update tools config if provided
                if (updates.tools) {
                    const currentTools = loadClaudeCliTools(initialPath);
                    const updatedTools = {
                        ...currentTools,
                        tools: { ...currentTools.tools, ...(updates.tools.tools || {}) }
                    };
                    saveClaudeCliTools(initialPath, updatedTools);
                }
                // Update settings config if provided
                if (updates.settings) {
                    const currentSettings = loadClaudeCliSettings(initialPath);
                    const s = updates.settings;
                    // Deep merge: only update fields that are explicitly provided
                    const updatedSettings = {
                        ...currentSettings,
                        // Scalar fields: only update if explicitly provided
                        ...(s.defaultTool !== undefined && { defaultTool: s.defaultTool }),
                        ...(s.promptFormat !== undefined && { promptFormat: s.promptFormat }),
                        ...(s.nativeResume !== undefined && { nativeResume: s.nativeResume }),
                        ...(s.recursiveQuery !== undefined && { recursiveQuery: s.recursiveQuery }),
                        ...(s.codeIndexMcp !== undefined && { codeIndexMcp: s.codeIndexMcp }),
                        // Nested objects: deep merge
                        smartContext: {
                            ...currentSettings.smartContext,
                            ...(s.smartContext || {})
                        },
                        cache: {
                            ...currentSettings.cache,
                            ...(s.cache || {})
                        }
                    };
                    saveClaudeCliSettings(initialPath, updatedSettings);
                }
                const toolsConfig = loadClaudeCliTools(initialPath);
                const settingsConfig = loadClaudeCliSettings(initialPath);
                broadcastToClients({
                    type: 'CLI_TOOLS_CONFIG_UPDATED',
                    payload: { tools: toolsConfig, settings: settingsConfig, timestamp: new Date().toISOString() }
                });
                return { success: true, tools: toolsConfig, settings: settingsConfig };
            }
            catch (err) {
                return { error: err.message, status: 500 };
            }
        });
        return true;
    }
    // API: Update specific tool enabled status
    const toolsConfigMatch = pathname.match(/^\/api\/cli\/tools-config\/([a-zA-Z0-9_-]+)$/);
    if (toolsConfigMatch && req.method === 'PUT') {
        const toolName = toolsConfigMatch[1];
        handlePostRequest(req, res, async (body) => {
            try {
                const { enabled } = body;
                const config = updateClaudeToolEnabled(initialPath, toolName, enabled);
                broadcastToClients({
                    type: 'CLI_TOOL_TOGGLED',
                    payload: { tool: toolName, enabled, timestamp: new Date().toISOString() }
                });
                return { success: true, config };
            }
            catch (err) {
                return { error: err.message, status: 500 };
            }
        });
        return true;
    }
    // API: Update cache settings
    if (pathname === '/api/cli/tools-config/cache' && req.method === 'PUT') {
        handlePostRequest(req, res, async (body) => {
            try {
                const cacheSettings = body;
                const settings = updateClaudeCacheSettings(initialPath, cacheSettings);
                broadcastToClients({
                    type: 'CLI_CACHE_SETTINGS_UPDATED',
                    payload: { cache: settings.cache, timestamp: new Date().toISOString() }
                });
                return { success: true, settings };
            }
            catch (err) {
                return { error: err.message, status: 500 };
            }
        });
        return true;
    }
    // API: Get Code Index MCP provider
    if (pathname === '/api/cli/code-index-mcp' && req.method === 'GET') {
        try {
            const provider = getCodeIndexMcp(initialPath);
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ provider }));
        }
        catch (err) {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: err.message }));
        }
        return true;
    }
    // API: Update Code Index MCP provider
    if (pathname === '/api/cli/code-index-mcp' && req.method === 'PUT') {
        handlePostRequest(req, res, async (body) => {
            try {
                const { provider } = body;
                if (!provider || !['codexlens', 'ace', 'none'].includes(provider)) {
                    return { error: 'Invalid provider. Must be "codexlens", "ace", or "none"', status: 400 };
                }
                const result = updateCodeIndexMcp(initialPath, provider);
                if (result.success) {
                    broadcastToClients({
                        type: 'CODE_INDEX_MCP_UPDATED',
                        payload: { provider, timestamp: new Date().toISOString() }
                    });
                    return { success: true, provider };
                }
                else {
                    return { error: result.error, status: 500 };
                }
            }
            catch (err) {
                return { error: err.message, status: 500 };
            }
        });
        return true;
    }
    return false;
}
//# sourceMappingURL=cli-routes.js.map