/**
 * Claude CLI Tools Configuration Manager
 * Manages cli-tools.json (tools) and cli-settings.json (settings)
 *
 * Configuration Strategy (GLOBAL ONLY):
 * - READ: Global → Default (no project-level configs)
 * - CREATE/SAVE: Always in ~/.claude/ (global user-level config)
 *
 * Config location: ~/.claude/cli-tools.json
 * Settings location: ~/.claude/cli-settings.json
 *
 * Note: Project-level configs are NOT used - all config is user-level.
 */
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
// ========== Debug Logging ==========
// Only output logs when DEBUG is enabled (via --debug flag or DEBUG env var)
function isDebugEnabled() {
    return process.env.DEBUG === 'true' || process.env.DEBUG === '1' || process.env.CCW_DEBUG === 'true';
}
function debugLog(message) {
    if (isDebugEnabled()) {
        console.log(message);
    }
}
// ========== Default Config ==========
const DEFAULT_TOOLS_CONFIG = {
    version: '3.4.0',
    tools: {
        gemini: {
            enabled: true,
            primaryModel: 'gemini-2.5-pro',
            secondaryModel: 'gemini-2.5-flash',
            availableModels: ['gemini-2.5-pro', 'gemini-2.5-flash', 'gemini-2.0-flash', 'gemini-2.0-flash-thinking', 'gemini-1.5-pro'],
            tags: [],
            type: 'builtin'
        },
        qwen: {
            enabled: true,
            primaryModel: 'coder-model',
            secondaryModel: 'coder-model',
            availableModels: ['coder-model', 'vision-model', 'qwen-2.5-coder', 'qwen-2.5-72b'],
            tags: [],
            type: 'builtin'
        },
        codex: {
            enabled: true,
            primaryModel: 'gpt-5.2',
            secondaryModel: 'gpt-5.2',
            availableModels: ['gpt-5.2', 'gpt-5', 'gpt5-codex', 'o3', 'o1'],
            tags: [],
            type: 'builtin'
        },
        claude: {
            enabled: true,
            primaryModel: 'sonnet',
            secondaryModel: 'haiku',
            availableModels: ['opus', 'sonnet', 'haiku'],
            tags: [],
            type: 'builtin'
        },
        opencode: {
            enabled: true,
            primaryModel: 'opencode/glm-4.7-free',
            secondaryModel: 'opencode/glm-4.7-free',
            availableModels: ['opencode/glm-4.7-free', 'opencode/deepseek-v3-free'],
            tags: [],
            type: 'builtin'
        }
    }
    // Note: api-endpoint type tools are added dynamically via addClaudeApiEndpoint
};
const DEFAULT_SETTINGS_CONFIG = {
    version: '1.0.0',
    defaultTool: 'gemini',
    promptFormat: 'plain',
    smartContext: {
        enabled: false,
        maxFiles: 10
    },
    nativeResume: true,
    recursiveQuery: true,
    cache: {
        injectionMode: 'auto',
        defaultPrefix: '',
        defaultSuffix: ''
    },
    codeIndexMcp: 'ace'
};
// ========== Helper Functions ==========
function getProjectConfigPath(projectDir) {
    return path.join(projectDir, '.claude', 'cli-tools.json');
}
function getProjectSettingsPath(projectDir) {
    return path.join(projectDir, '.claude', 'cli-settings.json');
}
function getGlobalConfigPath() {
    // Support CCW_DATA_DIR for test isolation
    const claudeHome = process.env.CCW_DATA_DIR
        ? path.join(process.env.CCW_DATA_DIR, '.claude')
        : path.join(os.homedir(), '.claude');
    return path.join(claudeHome, 'cli-tools.json');
}
function getGlobalSettingsPath() {
    // Support CCW_DATA_DIR for test isolation
    const claudeHome = process.env.CCW_DATA_DIR
        ? path.join(process.env.CCW_DATA_DIR, '.claude')
        : path.join(os.homedir(), '.claude');
    return path.join(claudeHome, 'cli-settings.json');
}
/**
 * Resolve config path - GLOBAL ONLY
 * Config is user-level, stored only in ~/.claude/cli-tools.json
 * Returns { path, source } where source is 'global' | 'default'
 */
function resolveConfigPath(projectDir) {
    const globalPath = getGlobalConfigPath();
    if (fs.existsSync(globalPath)) {
        return { path: globalPath, source: 'global' };
    }
    // Return global path for default (will be created there)
    return { path: globalPath, source: 'default' };
}
/**
 * Resolve settings path - GLOBAL ONLY
 * Settings are user-level, stored only in ~/.claude/cli-settings.json
 */
function resolveSettingsPath(projectDir) {
    const globalPath = getGlobalSettingsPath();
    if (fs.existsSync(globalPath)) {
        return { path: globalPath, source: 'global' };
    }
    // Return global path for default (will be created there)
    return { path: globalPath, source: 'default' };
}
// NOTE: ensureClaudeDir removed - config should only be in ~/.claude/, not project directory
// ========== Main Functions ==========
/**
 * Create a timestamped backup of the config file
 * @param filePath - Path to the config file to backup
 * @returns Path to the backup file
 */
function backupConfigFile(filePath) {
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T')[0] + '-' +
        new Date().toISOString().replace(/[:.]/g, '-').split('T')[1].substring(0, 8);
    const backupPath = `${filePath}.${timestamp}.bak`;
    try {
        if (fs.existsSync(filePath)) {
            fs.copyFileSync(filePath, backupPath);
            debugLog(`[claude-cli-tools] Created backup: ${backupPath}`);
        }
        return backupPath;
    }
    catch (err) {
        console.warn('[claude-cli-tools] Failed to create backup:', err);
        return '';
    }
}
/**
 * Ensure tool has required fields (for backward compatibility)
 */
function ensureToolTags(tool) {
    return {
        enabled: tool.enabled ?? true,
        primaryModel: tool.primaryModel,
        secondaryModel: tool.secondaryModel,
        tags: tool.tags ?? [],
        envFile: tool.envFile,
        settingsFile: tool.settingsFile
    };
}
/**
 * Migrate config from older versions to v3.3.0
 * v3.2.0: All endpoints (cli-wrapper, api-endpoint) are in tools with type field
 * v3.3.0: Remove models field (moved to system reference)
 */
function migrateConfig(config, projectDir, configPath) {
    const version = parseFloat(config.version || '1.0');
    let needsMigration = false;
    // Check if models field exists (v3.3.0 migration)
    if (config.models) {
        needsMigration = true;
        debugLog('[claude-cli-tools] Detected models field, will remove (moved to system reference)');
    }
    // Already v3.3+, no migration needed
    if (version >= 3.3 && !needsMigration) {
        return config;
    }
    // Create backup before migration if config path is provided
    if (configPath && (version < 3.3 || needsMigration)) {
        backupConfigFile(configPath);
    }
    debugLog(`[claude-cli-tools] Migrating config from v${config.version || '1.0'} to v3.3.0`);
    // Try to load legacy cli-config.json for model data
    let legacyCliConfig = null;
    try {
        const { StoragePaths } = require('../config/storage-paths.js');
        const legacyPath = StoragePaths.project(projectDir).cliConfig;
        const fs = require('fs');
        if (fs.existsSync(legacyPath)) {
            legacyCliConfig = JSON.parse(fs.readFileSync(legacyPath, 'utf-8'));
            debugLog(`[claude-cli-tools] Found legacy cli-config.json, merging model data`);
        }
    }
    catch {
        // Ignore errors loading legacy config
    }
    const migratedTools = {};
    for (const [key, tool] of Object.entries(config.tools || {})) {
        const t = tool;
        const legacyTool = legacyCliConfig?.tools?.[key];
        migratedTools[key] = {
            enabled: t.enabled ?? legacyTool?.enabled ?? true,
            primaryModel: t.primaryModel ?? legacyTool?.primaryModel ?? DEFAULT_TOOLS_CONFIG.tools[key]?.primaryModel,
            secondaryModel: t.secondaryModel ?? legacyTool?.secondaryModel ?? DEFAULT_TOOLS_CONFIG.tools[key]?.secondaryModel,
            tags: t.tags ?? legacyTool?.tags ?? [],
            type: t.type ?? DEFAULT_TOOLS_CONFIG.tools[key]?.type ?? 'builtin',
            id: t.id // Preserve id for api-endpoint type
        };
    }
    // Add any missing default tools
    for (const [key, defaultTool] of Object.entries(DEFAULT_TOOLS_CONFIG.tools)) {
        if (!migratedTools[key]) {
            const legacyTool = legacyCliConfig?.tools?.[key];
            migratedTools[key] = {
                enabled: legacyTool?.enabled ?? defaultTool.enabled,
                primaryModel: legacyTool?.primaryModel ?? defaultTool.primaryModel,
                secondaryModel: legacyTool?.secondaryModel ?? defaultTool.secondaryModel,
                tags: legacyTool?.tags ?? defaultTool.tags,
                type: defaultTool.type ?? 'builtin'
            };
        }
    }
    // Migrate customEndpoints (v3.0 and below): cli-wrapper -> tools, others -> api-endpoint tools
    const customEndpoints = config.customEndpoints || [];
    for (const ep of customEndpoints) {
        if (ep.tags?.includes('cli-wrapper')) {
            // CLI wrapper becomes a tool with type: 'cli-wrapper'
            if (!migratedTools[ep.name]) {
                migratedTools[ep.name] = {
                    enabled: ep.enabled ?? true,
                    tags: ep.tags.filter((t) => t !== 'cli-wrapper'),
                    type: 'cli-wrapper'
                };
                debugLog(`[claude-cli-tools] Migrated cli-wrapper "${ep.name}" to tools`);
            }
        }
        else {
            // Pure API endpoint becomes a tool with type: 'api-endpoint'
            if (!migratedTools[ep.name]) {
                migratedTools[ep.name] = {
                    enabled: ep.enabled ?? true,
                    tags: [],
                    type: 'api-endpoint',
                    id: ep.id // Store endpoint ID for settings lookup
                };
                debugLog(`[claude-cli-tools] Migrated API endpoint "${ep.name}" to tools`);
            }
        }
    }
    // Migrate apiEndpoints (v3.1): convert to tools with type: 'api-endpoint'
    const apiEndpoints = config.apiEndpoints || [];
    for (const ep of apiEndpoints) {
        if (!migratedTools[ep.name]) {
            migratedTools[ep.name] = {
                enabled: ep.enabled ?? true,
                tags: [],
                type: 'api-endpoint',
                id: ep.id // Store endpoint ID for settings lookup
            };
            debugLog(`[claude-cli-tools] Migrated API endpoint "${ep.name}" to tools`);
        }
    }
    // Remove models field if it exists (v3.3.0 migration)
    if (config.models) {
        debugLog('[claude-cli-tools] Removed models field (moved to system reference)');
    }
    return {
        version: '3.3.0',
        tools: migratedTools,
        $schema: config.$schema
    };
}
/**
 * Ensure CLI tools configuration file exists
 * Creates default config in global ~/.claude directory (user-level config)
 * @param projectDir - Project directory path (used for reading existing project config)
 * @param createInProject - DEPRECATED: Always creates in global dir. Kept for backward compatibility.
 * @returns The config that was created/exists
 */
export function ensureClaudeCliTools(projectDir, createInProject = false) {
    const resolved = resolveConfigPath(projectDir);
    if (resolved.source !== 'default') {
        // Config exists, load and return it
        return loadClaudeCliTools(projectDir);
    }
    // Config doesn't exist - create in global directory only
    debugLog('[claude-cli-tools] Config not found, creating default cli-tools.json in ~/.claude');
    const defaultConfig = { ...DEFAULT_TOOLS_CONFIG };
    // Always create in global directory (user-level config), respecting CCW_DATA_DIR
    const claudeHome = process.env.CCW_DATA_DIR
        ? path.join(process.env.CCW_DATA_DIR, '.claude')
        : path.join(os.homedir(), '.claude');
    if (!fs.existsSync(claudeHome)) {
        fs.mkdirSync(claudeHome, { recursive: true });
    }
    const globalPath = getGlobalConfigPath();
    try {
        fs.writeFileSync(globalPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');
        debugLog(`[claude-cli-tools] Created default config at: ${globalPath}`);
        return { ...defaultConfig, _source: 'global' };
    }
    catch (err) {
        console.error('[claude-cli-tools] Failed to create global config:', err);
        return { ...defaultConfig, _source: 'default' };
    }
}
/**
 * Async version of ensureClaudeCliTools with automatic availability sync
 * Creates default config in global ~/.claude directory and syncs with actual tool availability
 * @param projectDir - Project directory path (used for reading existing project config)
 * @param createInProject - DEPRECATED: Always creates in global dir. Kept for backward compatibility.
 * @returns The config that was created/exists
 */
export async function ensureClaudeCliToolsAsync(projectDir, createInProject = false) {
    const resolved = resolveConfigPath(projectDir);
    if (resolved.source !== 'default') {
        // Config exists, load and return it
        return loadClaudeCliTools(projectDir);
    }
    // Config doesn't exist - create in global directory only
    debugLog('[claude-cli-tools] Config not found, creating default cli-tools.json in ~/.claude');
    const defaultConfig = { ...DEFAULT_TOOLS_CONFIG };
    // Always create in global directory (user-level config), respecting CCW_DATA_DIR
    const claudeHome = process.env.CCW_DATA_DIR
        ? path.join(process.env.CCW_DATA_DIR, '.claude')
        : path.join(os.homedir(), '.claude');
    if (!fs.existsSync(claudeHome)) {
        fs.mkdirSync(claudeHome, { recursive: true });
    }
    const globalPath = getGlobalConfigPath();
    try {
        fs.writeFileSync(globalPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');
        debugLog(`[claude-cli-tools] Created default config at: ${globalPath}`);
        // Auto-sync with actual tool availability on first creation
        try {
            debugLog('[claude-cli-tools] Auto-syncing tool availability on first creation...');
            const syncResult = await syncBuiltinToolsAvailability(projectDir);
            debugLog(`[claude-cli-tools] Auto-sync completed: enabled=[${syncResult.changes.enabled.join(', ')}], disabled=[${syncResult.changes.disabled.join(', ')}]`);
            return { ...syncResult.config, _source: 'global' };
        }
        catch (syncErr) {
            console.warn('[claude-cli-tools] Failed to auto-sync availability:', syncErr);
            // Return default config if sync fails
            return { ...defaultConfig, _source: 'global' };
        }
    }
    catch (err) {
        console.error('[claude-cli-tools] Failed to create global config:', err);
        return { ...defaultConfig, _source: 'default' };
    }
}
/**
 * Load CLI tools configuration from global ~/.claude/cli-tools.json
 * Falls back to default config if not found.
 *
 * Automatically migrates older config versions to v3.2.0
 */
export function loadClaudeCliTools(projectDir) {
    const resolved = resolveConfigPath(projectDir);
    try {
        if (resolved.source === 'default') {
            return { ...DEFAULT_TOOLS_CONFIG, _source: 'default' };
        }
        const content = fs.readFileSync(resolved.path, 'utf-8');
        const parsed = JSON.parse(content);
        // Migrate older versions to v3.3.0 (pass config path for backup)
        const migrated = migrateConfig(parsed, projectDir, resolved.path);
        // Load user-configured tools only (defaults NOT merged)
        const mergedTools = {};
        for (const [key, tool] of Object.entries(migrated.tools || {})) {
            mergedTools[key] = {
                ...ensureToolTags(tool),
                type: tool.type ?? 'builtin',
                id: tool.id // Preserve id for api-endpoint type
            };
        }
        const config = {
            version: migrated.version || DEFAULT_TOOLS_CONFIG.version,
            tools: mergedTools,
            $schema: migrated.$schema,
            _source: resolved.source
        };
        // Save migrated config if version changed or models field exists
        const needsVersionUpdate = migrated.version !== parsed.version;
        const hasModelsField = parsed.models !== undefined;
        if (needsVersionUpdate || hasModelsField) {
            try {
                saveClaudeCliTools(projectDir, config);
                debugLog(`[claude-cli-tools] Saved migrated config to: ${resolved.path}`);
            }
            catch (err) {
                console.warn('[claude-cli-tools] Failed to save migrated config:', err);
            }
        }
        debugLog(`[claude-cli-tools] Loaded tools config from ${resolved.source}: ${resolved.path}`);
        return config;
    }
    catch (err) {
        console.error('[claude-cli-tools] Error loading tools config:', err);
        return { ...DEFAULT_TOOLS_CONFIG, _source: 'default' };
    }
}
/**
 * Save CLI tools configuration to global ~/.claude/cli-tools.json
 * Always saves to global directory (user-level config)
 */
export function saveClaudeCliTools(projectDir, config) {
    const { _source, ...configToSave } = config;
    // Always save to global directory, respecting CCW_DATA_DIR
    const claudeHome = process.env.CCW_DATA_DIR
        ? path.join(process.env.CCW_DATA_DIR, '.claude')
        : path.join(os.homedir(), '.claude');
    if (!fs.existsSync(claudeHome)) {
        fs.mkdirSync(claudeHome, { recursive: true });
    }
    const configPath = getGlobalConfigPath();
    try {
        fs.writeFileSync(configPath, JSON.stringify(configToSave, null, 2), 'utf-8');
        debugLog(`[claude-cli-tools] Saved tools config to: ${configPath}`);
    }
    catch (err) {
        console.error('[claude-cli-tools] Error saving tools config:', err);
        throw new Error(`Failed to save CLI tools config: ${err}`);
    }
}
/**
 * Load CLI settings configuration from global ~/.claude/cli-settings.json
 * Falls back to default settings if not found.
 */
export function loadClaudeCliSettings(projectDir) {
    const resolved = resolveSettingsPath(projectDir);
    try {
        if (resolved.source === 'default') {
            return { ...DEFAULT_SETTINGS_CONFIG, _source: 'default' };
        }
        const content = fs.readFileSync(resolved.path, 'utf-8');
        const parsed = JSON.parse(content);
        const config = {
            ...DEFAULT_SETTINGS_CONFIG,
            ...parsed,
            smartContext: {
                ...DEFAULT_SETTINGS_CONFIG.smartContext,
                ...(parsed.smartContext || {})
            },
            cache: {
                ...DEFAULT_SETTINGS_CONFIG.cache,
                ...(parsed.cache || {})
            },
            _source: resolved.source
        };
        debugLog(`[claude-cli-tools] Loaded settings from ${resolved.source}: ${resolved.path}`);
        return config;
    }
    catch (err) {
        console.error('[claude-cli-tools] Error loading settings:', err);
        return { ...DEFAULT_SETTINGS_CONFIG, _source: 'default' };
    }
}
/**
 * Save CLI settings configuration to global ~/.claude/cli-settings.json
 * Always saves to global directory (user-level config)
 */
export function saveClaudeCliSettings(projectDir, config) {
    const { _source, ...configToSave } = config;
    // Always save to global directory, respecting CCW_DATA_DIR
    const claudeHome = process.env.CCW_DATA_DIR
        ? path.join(process.env.CCW_DATA_DIR, '.claude')
        : path.join(os.homedir(), '.claude');
    if (!fs.existsSync(claudeHome)) {
        fs.mkdirSync(claudeHome, { recursive: true });
    }
    const settingsPath = getGlobalSettingsPath();
    try {
        fs.writeFileSync(settingsPath, JSON.stringify(configToSave, null, 2), 'utf-8');
        debugLog(`[claude-cli-tools] Saved settings to: ${settingsPath}`);
    }
    catch (err) {
        console.error('[claude-cli-tools] Error saving settings:', err);
        throw new Error(`Failed to save CLI settings: ${err}`);
    }
}
/**
 * Update enabled status for a specific tool
 */
export function updateClaudeToolEnabled(projectDir, toolName, enabled) {
    const config = loadClaudeCliTools(projectDir);
    if (config.tools[toolName]) {
        config.tools[toolName].enabled = enabled;
        saveClaudeCliTools(projectDir, config);
    }
    return config;
}
/**
 * Update cache settings
 */
export function updateClaudeCacheSettings(projectDir, cacheSettings) {
    const settings = loadClaudeCliSettings(projectDir);
    settings.cache = {
        ...settings.cache,
        ...cacheSettings
    };
    saveClaudeCliSettings(projectDir, settings);
    return settings;
}
/**
 * Update default tool
 */
export function updateClaudeDefaultTool(projectDir, defaultTool) {
    const settings = loadClaudeCliSettings(projectDir);
    settings.defaultTool = defaultTool;
    saveClaudeCliSettings(projectDir, settings);
    return settings;
}
/**
 * Get the default tool from config
 * Returns the configured defaultTool or 'gemini' as fallback
 */
export function getDefaultTool(projectDir) {
    try {
        const settings = loadClaudeCliSettings(projectDir);
        return settings.defaultTool || 'gemini';
    }
    catch {
        return 'gemini';
    }
}
// ========== Settings Persistence Functions ==========
/**
 * Update prompt format setting
 * @param projectDir - Project directory path
 * @param format - Prompt format: 'plain' | 'yaml' | 'json'
 * @returns Updated settings config
 */
export function setPromptFormat(projectDir, format) {
    const settings = loadClaudeCliSettings(projectDir);
    settings.promptFormat = format;
    saveClaudeCliSettings(projectDir, settings);
    return settings;
}
/**
 * Get prompt format setting
 * @param projectDir - Project directory path
 * @returns Current prompt format or 'plain' as fallback
 */
export function getPromptFormat(projectDir) {
    try {
        const settings = loadClaudeCliSettings(projectDir);
        return settings.promptFormat || 'plain';
    }
    catch {
        return 'plain';
    }
}
/**
 * Update smart context enabled setting
 * @param projectDir - Project directory path
 * @param enabled - Whether smart context is enabled
 * @returns Updated settings config
 */
export function setSmartContextEnabled(projectDir, enabled) {
    const settings = loadClaudeCliSettings(projectDir);
    settings.smartContext = {
        ...settings.smartContext,
        enabled
    };
    saveClaudeCliSettings(projectDir, settings);
    return settings;
}
/**
 * Get smart context enabled setting
 * @param projectDir - Project directory path
 * @returns Current smart context status or false as fallback
 */
export function getSmartContextEnabled(projectDir) {
    try {
        const settings = loadClaudeCliSettings(projectDir);
        return settings.smartContext?.enabled ?? false;
    }
    catch {
        return false;
    }
}
/**
 * Update native resume setting
 * @param projectDir - Project directory path
 * @param enabled - Whether native resume is enabled
 * @returns Updated settings config
 */
export function setNativeResume(projectDir, enabled) {
    const settings = loadClaudeCliSettings(projectDir);
    settings.nativeResume = enabled;
    saveClaudeCliSettings(projectDir, settings);
    return settings;
}
/**
 * Get native resume setting
 * @param projectDir - Project directory path
 * @returns Current native resume status or true as fallback
 */
export function getNativeResume(projectDir) {
    try {
        const settings = loadClaudeCliSettings(projectDir);
        return settings.nativeResume ?? true;
    }
    catch {
        return true;
    }
}
/**
 * Add API endpoint as a tool with type: 'api-endpoint'
 * Usage: --tool <name> or --tool custom --model <id>
 */
export function addClaudeApiEndpoint(projectDir, endpoint) {
    const config = loadClaudeCliTools(projectDir);
    // Add as a tool with type: 'api-endpoint'
    config.tools[endpoint.name] = {
        enabled: endpoint.enabled,
        primaryModel: endpoint.model, // Use endpoint.model as primaryModel (can be overridden via --model)
        secondaryModel: endpoint.model, // Same as primary for fallback
        tags: [],
        type: 'api-endpoint',
        id: endpoint.id // Store endpoint ID for settings lookup
    };
    saveClaudeCliTools(projectDir, config);
    return config;
}
/**
 * Remove API endpoint tool by id or name
 */
export function removeClaudeApiEndpoint(projectDir, endpointId) {
    const config = loadClaudeCliTools(projectDir);
    // Find the tool by id or name
    const toolToRemove = Object.entries(config.tools).find(([name, t]) => t.type === 'api-endpoint' && (t.id === endpointId || name === endpointId || name.toLowerCase() === endpointId.toLowerCase()));
    if (toolToRemove) {
        delete config.tools[toolToRemove[0]];
    }
    saveClaudeCliTools(projectDir, config);
    return config;
}
/**
 * @deprecated Use addClaudeApiEndpoint instead
 * Adds tool to config based on tags:
 * - cli-wrapper tag -> type: 'cli-wrapper'
 * - others -> type: 'api-endpoint'
 */
export function addClaudeCustomEndpoint(projectDir, endpoint) {
    const config = loadClaudeCliTools(projectDir);
    if (endpoint.tags?.includes('cli-wrapper')) {
        // CLI wrapper tool
        config.tools[endpoint.name] = {
            enabled: endpoint.enabled,
            tags: endpoint.tags.filter(t => t !== 'cli-wrapper'),
            type: 'cli-wrapper'
        };
    }
    else {
        // API endpoint tool
        config.tools[endpoint.name] = {
            enabled: endpoint.enabled,
            tags: [],
            type: 'api-endpoint',
            id: endpoint.id
        };
    }
    saveClaudeCliTools(projectDir, config);
    return config;
}
/**
 * Remove endpoint tool (cli-wrapper or api-endpoint)
 */
export function removeClaudeCustomEndpoint(projectDir, endpointId) {
    const config = loadClaudeCliTools(projectDir);
    // Find the tool by id or name (cli-wrapper or api-endpoint type)
    const toolToRemove = Object.entries(config.tools).find(([name, t]) => (t.type === 'cli-wrapper' || t.type === 'api-endpoint') &&
        (name === endpointId || name.toLowerCase() === endpointId.toLowerCase() || t.id === endpointId));
    if (toolToRemove) {
        delete config.tools[toolToRemove[0]];
    }
    saveClaudeCliTools(projectDir, config);
    return config;
}
/**
 * Get config source info
 */
export function getClaudeCliToolsInfo(projectDir) {
    const resolved = resolveConfigPath(projectDir);
    return {
        projectPath: getProjectConfigPath(projectDir),
        globalPath: getGlobalConfigPath(),
        activePath: resolved.path,
        source: resolved.source
    };
}
/**
 * Update Code Index MCP provider and switch CLAUDE.md reference
 * Strategy: Only modify global user-level CLAUDE.md (~/.claude/CLAUDE.md)
 * This is consistent with Chinese response and Windows platform settings
 */
export function updateCodeIndexMcp(projectDir, provider) {
    try {
        // Update settings config
        const settings = loadClaudeCliSettings(projectDir);
        settings.codeIndexMcp = provider;
        saveClaudeCliSettings(projectDir, settings);
        // Only update global CLAUDE.md (consistent with Chinese response / Windows platform)
        const globalClaudeMdPath = path.join(os.homedir(), '.claude', 'CLAUDE.md');
        // Define patterns for all formats
        const codexlensPattern = /@~\/\.claude\/workflows\/context-tools\.md/g;
        const acePattern = /@~\/\.claude\/workflows\/context-tools-ace\.md/g;
        const nonePattern = /@~\/\.claude\/workflows\/context-tools-none\.md/g;
        // Determine target file based on provider
        const targetFile = provider === 'ace'
            ? '@~/.claude/workflows/context-tools-ace.md'
            : provider === 'none'
                ? '@~/.claude/workflows/context-tools-none.md'
                : '@~/.claude/workflows/context-tools.md';
        if (!fs.existsSync(globalClaudeMdPath)) {
            // If global CLAUDE.md doesn't exist, check project-level
            const projectClaudeMdPath = path.join(projectDir, '.claude', 'CLAUDE.md');
            if (fs.existsSync(projectClaudeMdPath)) {
                let content = fs.readFileSync(projectClaudeMdPath, 'utf-8');
                // Replace any existing pattern with the target
                content = content.replace(codexlensPattern, targetFile);
                content = content.replace(acePattern, targetFile);
                content = content.replace(nonePattern, targetFile);
                fs.writeFileSync(projectClaudeMdPath, content, 'utf-8');
                debugLog(`[claude-cli-tools] Updated project CLAUDE.md to use ${provider} (no global CLAUDE.md found)`);
            }
        }
        else {
            // Update global CLAUDE.md (primary target)
            let content = fs.readFileSync(globalClaudeMdPath, 'utf-8');
            // Replace any existing pattern with the target
            content = content.replace(codexlensPattern, targetFile);
            content = content.replace(acePattern, targetFile);
            content = content.replace(nonePattern, targetFile);
            fs.writeFileSync(globalClaudeMdPath, content, 'utf-8');
            debugLog(`[claude-cli-tools] Updated global CLAUDE.md to use ${provider}`);
        }
        return { success: true, settings };
    }
    catch (err) {
        console.error('[claude-cli-tools] Error updating Code Index MCP:', err);
        return { success: false, error: err.message };
    }
}
/**
 * Get current Code Index MCP provider
 */
export function getCodeIndexMcp(projectDir) {
    const settings = loadClaudeCliSettings(projectDir);
    return settings.codeIndexMcp || 'ace';
}
/**
 * Get the context-tools file path based on provider
 */
export function getContextToolsPath(provider) {
    switch (provider) {
        case 'ace':
            return 'context-tools-ace.md';
        case 'none':
            return 'context-tools-none.md';
        default:
            return 'context-tools.md';
    }
}
// ========== Model Configuration Functions ==========
// NOTE: Model reference data has been moved to system reference (src/config/provider-models.ts)
// User configuration only manages primaryModel/secondaryModel per tool via tools.{tool}
/**
 * Get tool configuration (compatible with cli-config-manager interface)
 */
export function getToolConfig(projectDir, tool) {
    const config = loadClaudeCliTools(projectDir);
    const toolConfig = config.tools[tool];
    if (!toolConfig) {
        const defaultTool = DEFAULT_TOOLS_CONFIG.tools[tool];
        return {
            enabled: defaultTool?.enabled ?? true,
            primaryModel: defaultTool?.primaryModel ?? '',
            secondaryModel: defaultTool?.secondaryModel ?? '',
            tags: defaultTool?.tags ?? []
        };
    }
    return {
        enabled: toolConfig.enabled,
        primaryModel: toolConfig.primaryModel ?? '',
        secondaryModel: toolConfig.secondaryModel ?? '',
        tags: toolConfig.tags,
        envFile: toolConfig.envFile,
        settingsFile: toolConfig.settingsFile
    };
}
/**
 * Update tool configuration
 */
export function updateToolConfig(projectDir, tool, updates) {
    const config = loadClaudeCliTools(projectDir);
    if (config.tools[tool]) {
        if (updates.enabled !== undefined) {
            config.tools[tool].enabled = updates.enabled;
        }
        if (updates.primaryModel !== undefined) {
            config.tools[tool].primaryModel = updates.primaryModel;
        }
        if (updates.secondaryModel !== undefined) {
            config.tools[tool].secondaryModel = updates.secondaryModel;
        }
        if (updates.availableModels !== undefined) {
            config.tools[tool].availableModels = updates.availableModels;
        }
        if (updates.tags !== undefined) {
            config.tools[tool].tags = updates.tags;
        }
        // Handle envFile: set to undefined if null/empty, otherwise set value
        if (updates.envFile !== undefined) {
            if (updates.envFile === null || updates.envFile === '') {
                delete config.tools[tool].envFile;
            }
            else {
                config.tools[tool].envFile = updates.envFile;
            }
        }
        // Handle settingsFile: set to undefined if null/empty, otherwise set value
        if (updates.settingsFile !== undefined) {
            if (updates.settingsFile === null || updates.settingsFile === '') {
                delete config.tools[tool].settingsFile;
            }
            else {
                config.tools[tool].settingsFile = updates.settingsFile;
            }
        }
        saveClaudeCliTools(projectDir, config);
    }
    return config;
}
/**
 * Get primary model for a tool
 */
export function getPrimaryModel(projectDir, tool) {
    const toolConfig = getToolConfig(projectDir, tool);
    return toolConfig.primaryModel;
}
/**
 * Get secondary model for a tool
 */
export function getSecondaryModel(projectDir, tool) {
    const toolConfig = getToolConfig(projectDir, tool);
    return toolConfig.secondaryModel;
}
/**
 * Check if a tool is enabled
 */
export function isToolEnabled(projectDir, tool) {
    const toolConfig = getToolConfig(projectDir, tool);
    return toolConfig.enabled;
}
/**
 * Get full config response for API
 * Note: Provider model reference has been moved to system reference (see provider-routes.ts)
 */
export function getFullConfigResponse(projectDir) {
    const config = loadClaudeCliTools(projectDir);
    return {
        config
    };
}
// ========== Tool Detection & Sync Functions ==========
/**
 * Sync builtin tools availability with cli-tools.json
 *
 * For builtin tools (gemini, qwen, codex, claude, opencode):
 * - Checks actual tool availability using system PATH
 * - Updates enabled status based on actual availability
 *
 * For non-builtin tools (cli-wrapper, api-endpoint):
 * - Leaves them unchanged as they have different availability mechanisms
 *
 * @returns Updated config and sync results
 */
export async function syncBuiltinToolsAvailability(projectDir) {
    // Import getCliToolsStatus dynamically to avoid circular dependency
    const { getCliToolsStatus } = await import('./cli-executor.js');
    // Get actual tool availability
    const actualStatus = await getCliToolsStatus();
    // Load current config
    const config = loadClaudeCliTools(projectDir);
    const changes = {
        enabled: [],
        disabled: [],
        unchanged: []
    };
    // Builtin tools that need sync
    const builtinTools = ['gemini', 'qwen', 'codex', 'claude', 'opencode'];
    for (const toolName of builtinTools) {
        const isAvailable = actualStatus[toolName]?.available ?? false;
        const currentConfig = config.tools[toolName];
        const wasEnabled = currentConfig?.enabled ?? true;
        // Update based on actual availability
        if (isAvailable && !wasEnabled) {
            // Tool exists but was disabled - enable it
            if (!currentConfig) {
                config.tools[toolName] = {
                    enabled: true,
                    primaryModel: DEFAULT_TOOLS_CONFIG.tools[toolName]?.primaryModel || '',
                    secondaryModel: DEFAULT_TOOLS_CONFIG.tools[toolName]?.secondaryModel || '',
                    tags: [],
                    type: 'builtin'
                };
            }
            else {
                currentConfig.enabled = true;
            }
            changes.enabled.push(toolName);
        }
        else if (!isAvailable && wasEnabled) {
            // Tool doesn't exist but was enabled - disable it
            if (currentConfig) {
                currentConfig.enabled = false;
            }
            changes.disabled.push(toolName);
        }
        else {
            // No change needed
            changes.unchanged.push(toolName);
        }
    }
    // Save updated config
    saveClaudeCliTools(projectDir, config);
    console.log('[claude-cli-tools] Synced builtin tools availability:', {
        enabled: changes.enabled,
        disabled: changes.disabled,
        unchanged: changes.unchanged
    });
    return { config, changes };
}
/**
 * Get sync status report without actually modifying config
 *
 * @returns Report showing what would change if sync were run
 */
export async function getBuiltinToolsSyncReport(projectDir) {
    // Import getCliToolsStatus dynamically to avoid circular dependency
    const { getCliToolsStatus } = await import('./cli-executor.js');
    // Get actual tool availability
    const actualStatus = await getCliToolsStatus();
    // Load current config
    const config = loadClaudeCliTools(projectDir);
    const builtinTools = ['gemini', 'qwen', 'codex', 'claude', 'opencode'];
    const current = {};
    const recommended = {};
    for (const toolName of builtinTools) {
        const isAvailable = actualStatus[toolName]?.available ?? false;
        const isEnabled = config.tools[toolName]?.enabled ?? true;
        current[toolName] = {
            available: isAvailable,
            enabled: isEnabled
        };
        if (isAvailable && !isEnabled) {
            recommended[toolName] = {
                shouldEnable: true,
                reason: 'Tool is installed but disabled in config'
            };
        }
        else if (!isAvailable && isEnabled) {
            recommended[toolName] = {
                shouldEnable: false,
                reason: 'Tool is not installed but enabled in config'
            };
        }
    }
    return { current, recommended };
}
//# sourceMappingURL=claude-cli-tools.js.map