@shi_zhen/code-helper 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../package.json","../../src/cli/utils/exec.ts","../../src/cli/utils/webui.ts","../../src/cli/utils/version.ts","../../src/cli/menus/main.ts","../../src/cli/ui.ts","../../src/cli/utils/claude.ts","../../src/cli/utils/config.ts","../../src/cli/menus/auth.ts","../../src/cli/utils/api.ts","../../src/cli/menus/manage.ts","../../src/cli/menus/install.ts","../../src/cli/utils/platform.ts","../../src/cli/menus/uninstall.ts","../../src/cli/menus/mcp.ts","../../src/cli/services/mcp.ts","../../src/cli/config/constants.ts","../../src/cli/utils/cache.ts","../../src/cli/menus/plugins.ts","../../src/cli/services/marketplace.ts","../../src/cli/menus/settings.ts","../../src/cli/index.ts"],"sourcesContent":["{\n \"name\": \"@shi_zhen/code-helper\",\n \"version\": \"0.1.0\",\n \"description\": \"Code Helper - A unified tool to manage your Claude Code\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/shirenchuang/code-helper.git\"\n },\n \"author\": \"shirenchuang\",\n \"module\": \"dist/index.js\",\n \"typings\": \"dist/index.d.ts\",\n \"bin\": {\n \"ch\": \"./bin/code-helper.js\",\n \"code-helper\": \"./bin/code-helper.js\"\n },\n \"files\": [\n \"bin\",\n \"dist\",\n \"LEGAL.md\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"build:watch\": \"tsup --watch\",\n \"dev\": \"tsup --watch\",\n \"lint\": \"eslint src --ext .ts\",\n \"test\": \"jest\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"dependencies\": {\n \"@babel/runtime\": \"^7.18.0\",\n \"boxen\": \"^5.1.2\",\n \"chalk\": \"^4.1.2\",\n \"execa\": \"^5.1.1\",\n \"figlet\": \"^1.7.0\",\n \"inquirer\": \"^8.2.6\",\n \"ora\": \"^5.4.1\"\n },\n \"devDependencies\": {\n \"@types/figlet\": \"^1.5.8\",\n \"@types/inquirer\": \"^8.2.10\",\n \"@types/node\": \"^20.0.0\",\n \"@typescript-eslint/eslint-plugin\": \"^6.0.0\",\n \"@typescript-eslint/parser\": \"^6.0.0\",\n \"eslint\": \"^8.0.0\",\n \"tsup\": \"^8.0.0\",\n \"typescript\": \"^5.0.0\"\n },\n \"engines\": {\n \"node\": \">=20\"\n },\n \"keywords\": [\n \"claude\",\n \"claude-code\",\n \"mcp\",\n \"ai\",\n \"cli\",\n \"tools\"\n ],\n \"license\": \"MIT\"\n}\n","/**\n * 命令执行工具\n */\nimport execa from 'execa';\n\n/**\n * 执行 shell 命令\n */\nexport async function executeCommand(\n command: string,\n envVars?: Record<string, string>,\n): Promise<string> {\n try {\n // 如果是管道命令,使用 pipefail 确保管道中任何命令失败都会被捕获\n let finalCommand = command;\n if (command.includes('|')) {\n finalCommand = `set -o pipefail && ${command}`;\n }\n\n const { stdout } = await execa.command(finalCommand, {\n shell: true,\n stdio: 'inherit',\n env: envVars ? { ...process.env, ...envVars } : undefined,\n });\n return stdout || '';\n } catch (error) {\n const execError = error as any;\n throw new Error(execError.stderr || execError.message || '命令执行失败');\n }\n}\n\n/**\n * 执行命令并返回输出(不显示在终端)\n */\nexport async function executeCommandQuiet(command: string): Promise<string> {\n try {\n const { stdout } = await execa.command(command, {\n shell: true,\n });\n return stdout || '';\n } catch (error) {\n const execError = error as any;\n throw new Error(execError.stderr || execError.message || '命令执行失败');\n }\n}\n\n/**\n * 检查命令是否存在\n */\nexport async function commandExists(command: string): Promise<boolean> {\n try {\n await execa.command(`which ${command}`, { shell: true });\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * Web UI 启动工具\n */\nimport chalk from 'chalk';\nimport inquirer from 'inquirer';\n\n/**\n * 显示 Web UI 启动提示\n */\nexport async function launchWebUI(): Promise<void> {\n console.log(chalk.cyan('\\n🚀 ClaudeCode UI 启动指南\\n'));\n console.log(chalk.yellow('请在终端中手动执行以下命令来启动 Web UI:\\n'));\n console.log(chalk.green.bold(' npx @siteboon/claude-code-ui\\n'));\n console.log(\n chalk.dim('说明: 使用开源版本的 Claude Code UI'),\n );\n console.log(chalk.dim(' 这样可以确保使用正确的 Node.js 版本和依赖'));\n console.log();\n\n // 等待用户按回车返回\n await inquirer.prompt([\n {\n type: 'input',\n name: 'confirm',\n message: '按 Enter 键返回主菜单',\n },\n ]);\n}\n","/**\n * 版本检查和自动更新工具\n */\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { executeCommand, executeCommandQuiet } from './exec';\n\n// 缓存文件路径(避免频繁检查)\nconst os = require('os');\nconst path = require('path');\nconst fs = require('fs');\n\nconst CACHE_DIR = path.join(os.homedir(), '.code-helper');\nconst CACHE_FILE = path.join(CACHE_DIR, 'version-check.json');\nconst CHECK_INTERVAL = 24 * 60 * 60 * 1000; // 24小时检查一次\n\ninterface VersionCache {\n lastCheck: number;\n latestVersion: string;\n}\n\n/**\n * 获取本地版本号\n */\nfunction getLocalVersion(): string {\n const pkg = require('../../../package.json');\n return pkg.version;\n}\n\n/**\n * 获取远程最新版本号\n */\nasync function getRemoteVersion(): Promise<string | null> {\n try {\n const result = await executeCommandQuiet(\n 'npm view code-helper version',\n );\n return result.trim();\n } catch (error) {\n console.error(chalk.yellow('⚠️ 无法检查版本更新'));\n return null;\n }\n}\n\n/**\n * 读取版本检查缓存\n */\nfunction readCache(): VersionCache | null {\n try {\n if (!fs.existsSync(CACHE_FILE)) {\n return null;\n }\n const content = fs.readFileSync(CACHE_FILE, 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\n/**\n * 写入版本检查缓存\n */\nfunction writeCache(data: VersionCache): void {\n try {\n if (!fs.existsSync(CACHE_DIR)) {\n fs.mkdirSync(CACHE_DIR, { recursive: true });\n }\n fs.writeFileSync(CACHE_FILE, JSON.stringify(data, null, 2));\n } catch (error) {\n // 缓存写入失败不影响主流程\n }\n}\n\n/**\n * 比较版本号\n */\nfunction compareVersions(v1: string, v2: string): number {\n const parts1 = v1.split('.').map(Number);\n const parts2 = v2.split('.').map(Number);\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const part1 = parts1[i] || 0;\n const part2 = parts2[i] || 0;\n\n if (part1 > part2) return 1;\n if (part1 < part2) return -1;\n }\n\n return 0;\n}\n\n/**\n * 自动更新到最新版本\n */\nasync function updateToLatest(): Promise<boolean> {\n const spinner = ora('正在更新到最新版本...').start();\n\n try {\n await executeCommand('npm install -g code-helper@latest');\n spinner.succeed(chalk.green('✅ 更新成功!'));\n return true;\n } catch (error) {\n spinner.fail(chalk.red('❌ 更新失败'));\n console.error(chalk.red(`错误: ${error}`));\n return false;\n }\n}\n\n/**\n * 检查版本更新并自动更新\n */\nexport async function checkAndUpdate(\n forceCheck: boolean = false,\n): Promise<void> {\n const localVersion = getLocalVersion();\n\n // 检查缓存,避免频繁检查\n const cache = readCache();\n const now = Date.now();\n\n if (!forceCheck && cache && now - cache.lastCheck < CHECK_INTERVAL) {\n // 距离上次检查不到24小时,使用缓存\n if (compareVersions(cache.latestVersion, localVersion) > 0) {\n console.log(\n chalk.yellow(\n `\\n💡 提示: 有新版本 ${cache.latestVersion} 可用 (当前版本: ${localVersion})`,\n ),\n );\n console.log(chalk.gray(' 下次启动时将自动更新...\\n'));\n }\n return;\n }\n\n // 检查远程版本\n const spinner = ora('正在检查版本更新...').start();\n const remoteVersion = await getRemoteVersion();\n\n if (!remoteVersion) {\n spinner.stop();\n return;\n }\n\n // 更新缓存\n writeCache({\n lastCheck: now,\n latestVersion: remoteVersion,\n });\n\n // 比较版本\n if (compareVersions(remoteVersion, localVersion) > 0) {\n spinner.succeed(\n chalk.cyan(`发现新版本: ${remoteVersion} (当前版本: ${localVersion})`),\n );\n console.log(chalk.gray('正在自动更新...\\n'));\n\n const success = await updateToLatest();\n\n if (success) {\n console.log(\n chalk.green('\\n✨ 更新完成!请重新运行命令以使用最新版本。\\n'),\n );\n process.exit(0);\n } else {\n console.log(\n chalk.yellow(\n '\\n⚠️ 自动更新失败,你可以手动运行: npm install -g code-helper@latest\\n',\n ),\n );\n }\n } else {\n spinner.succeed(chalk.green(`当前已是最新版本 v${localVersion}`));\n }\n}\n\n/**\n * 测试更新功能(模拟有新版本)\n */\nexport async function testUpdate(): Promise<void> {\n const localVersion = getLocalVersion();\n console.log(chalk.cyan('\\n🧪 测试模式: 模拟版本更新流程\\n'));\n console.log(chalk.gray(`当前版本: ${localVersion}`));\n console.log(chalk.gray('正在检查远程版本...\\n'));\n\n const remoteVersion = await getRemoteVersion();\n\n if (!remoteVersion) {\n console.log(chalk.red('❌ 无法获取远程版本'));\n return;\n }\n\n console.log(chalk.gray(`远程版本: ${remoteVersion}\\n`));\n\n if (compareVersions(remoteVersion, localVersion) > 0) {\n console.log(chalk.green('✅ 远程版本更新,会触发自动更新'));\n } else if (compareVersions(remoteVersion, localVersion) === 0) {\n console.log(chalk.yellow('⚠️ 远程版本与本地版本相同'));\n console.log(chalk.gray(' 真实使用时不会触发更新'));\n } else {\n console.log(chalk.yellow('⚠️ 本地版本高于远程版本'));\n console.log(chalk.gray(' 这通常发生在本地开发时'));\n }\n\n console.log(\n chalk.cyan('\\n💡 提示: 发布新版本后,用户首次启动时会自动更新\\n'),\n );\n}\n","/**\n * 主菜单\n */\nimport inquirer from 'inquirer';\nimport { createBoxTitle, showHeader, theme } from '../ui';\nimport { detectClaudeInstallation, formatClaudeStatus } from '../utils/claude';\nimport {\n getApiKeyStatus,\n getBaseUrlStatus,\n getCurrentProfileStatus,\n} from '../utils/config';\nimport { showAuthMenu } from './auth';\nimport { showManageMenu } from './manage';\nimport { showMcpMenu } from './mcp';\nimport { showPluginsMenu } from './plugins';\nimport { showSettingsMenu } from './settings';\n\n/**\n * 主菜单选项\n */\nenum MainMenuChoice {\n MANAGE = 'manage',\n AUTH = 'auth',\n SETTINGS = 'settings',\n MCP = 'mcp',\n PLUGINS = 'plugins',\n WEBUI = 'webui',\n EXIT = 'exit',\n}\n\n/**\n * 显示主菜单\n */\nexport async function showMainMenu(): Promise<void> {\n // 首次进入时检测一次\n let claudeInfo = detectClaudeInstallation();\n\n while (true) {\n showHeader();\n\n // 使用缓存的状态,避免每次都检测\n const claudeStatus = formatClaudeStatus(claudeInfo);\n\n // 显示当前配置状态\n console.log(\n `Claude Code: ${\n claudeInfo.installed\n ? theme.success(claudeStatus)\n : theme.dim(claudeStatus)\n }`,\n );\n\n const profileStatus = getCurrentProfileStatus();\n const apiKeyStatus = getApiKeyStatus();\n const baseUrlStatus = getBaseUrlStatus();\n console.log(`当前配置: ${profileStatus}`);\n console.log(`Base URL: ${baseUrlStatus}`);\n console.log(`API Key: ${apiKeyStatus}\\n`);\n\n console.log(createBoxTitle('主菜单'));\n console.log();\n\n const { choice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'choice',\n message: '请选择操作:',\n pageSize: 10,\n choices: [\n {\n name: `${theme.primary('1.')} Claude Code 管理 ${theme.dim(\n '(安装/卸载)',\n )}`,\n value: MainMenuChoice.MANAGE,\n },\n {\n name: `${theme.primary('2.')} 授权登录`,\n value: MainMenuChoice.AUTH,\n },\n {\n name: `${theme.primary('3.')} Claude Code 配置`,\n value: MainMenuChoice.SETTINGS,\n },\n {\n name: `${theme.primary('4.')} MCP 服务管理`,\n value: MainMenuChoice.MCP,\n },\n {\n name: `${theme.primary('5.')} 插件市场`,\n value: MainMenuChoice.PLUGINS,\n },\n {\n name: `${theme.primary('6.')} 启动 Web UI ${theme.dim(\n '(图形化界面)',\n )}`,\n value: MainMenuChoice.WEBUI,\n },\n new inquirer.Separator(),\n {\n name: `${theme.dim('0.')} 退出`,\n value: MainMenuChoice.EXIT,\n },\n ],\n },\n ]);\n\n switch (choice) {\n case MainMenuChoice.MANAGE:\n await showManageMenu();\n // 从管理菜单返回后刷新状态\n claudeInfo = detectClaudeInstallation();\n break;\n case MainMenuChoice.AUTH:\n await showAuthMenu();\n break;\n case MainMenuChoice.SETTINGS:\n await showSettingsMenu();\n break;\n case MainMenuChoice.MCP:\n await showMcpMenu();\n break;\n case MainMenuChoice.PLUGINS:\n await showPluginsMenu();\n break;\n case MainMenuChoice.WEBUI: {\n const { launchWebUI } = require('../utils/webui');\n await launchWebUI();\n break;\n }\n case MainMenuChoice.EXIT:\n console.log('\\n再见!');\n process.exit(0);\n }\n }\n}\n","/**\n * UI 模块 - ASCII 艺术字、颜色主题、边框装饰\n */\nimport boxen from 'boxen';\nimport chalk from 'chalk';\nimport figlet from 'figlet';\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst pkg = require('../../package.json');\nconst VERSION = pkg.version;\n\n// 橙色主题色\nexport const theme = {\n primary: chalk.hex('#FF8C00'), // 深橙色\n secondary: chalk.hex('#FFA500'), // 橙色\n success: chalk.green,\n error: chalk.red,\n warning: chalk.yellow,\n info: chalk.cyan,\n dim: chalk.gray,\n};\n\n/**\n * 生成 ASCII 艺术字标题\n */\nexport function generateTitle(): string {\n try {\n const title = figlet.textSync('CODE HELPER', {\n font: 'Standard',\n horizontalLayout: 'default',\n });\n return theme.primary(title);\n } catch {\n return theme.primary('CODE HELPER');\n }\n}\n\n/**\n * 显示头部信息\n */\nexport function showHeader(): void {\n console.clear();\n\n const title = generateTitle();\n const subtitle = `Code Helper v${VERSION}\\nA unified tool to manage your Claude Code`;\n\n const header = boxen(\n `${title}\\n\\n${theme.secondary(subtitle)}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'yellow',\n textAlignment: 'center',\n },\n );\n\n console.log(header);\n}\n\n/**\n * 显示分隔线\n */\nexport function showDivider(): void {\n console.log(theme.dim('─'.repeat(50)));\n}\n\n/**\n * 显示成功消息\n */\nexport function showSuccess(message: string): void {\n console.log(theme.success(`✓ ${message}`));\n}\n\n/**\n * 显示错误消息\n */\nexport function showError(message: string): void {\n console.log(theme.error(`✗ ${message}`));\n}\n\n/**\n * 显示警告消息\n */\nexport function showWarning(message: string): void {\n console.log(theme.warning(`⚠ ${message}`));\n}\n\n/**\n * 显示信息消息\n */\nexport function showInfo(message: string): void {\n console.log(theme.info(`ℹ ${message}`));\n}\n\n/**\n * 创建带边框的标题\n */\nexport function createBoxTitle(title: string): string {\n return boxen(theme.primary(title), {\n padding: { left: 2, right: 2, top: 0, bottom: 0 },\n borderStyle: 'round',\n borderColor: 'yellow',\n textAlignment: 'center',\n });\n}\n","/**\n * Claude Code 检测工具\n */\nimport { execSync } from 'child_process';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\n\n/**\n * Claude 安装信息\n */\nexport interface ClaudeInstallInfo {\n installed: boolean;\n version?: string;\n installMethod?: 'npm' | 'official' | 'homebrew' | 'unknown';\n binaryPath?: string;\n}\n\n/**\n * 缓存的安装信息\n */\nlet cachedInfo: ClaudeInstallInfo | null = null;\nlet lastCheckTime: number = 0;\nconst CACHE_DURATION = 5000; // 缓存 5 秒\n\n/**\n * 执行带超时的命令\n */\nfunction execSyncWithTimeout(\n command: string,\n timeoutMs: number = 2000,\n): string {\n try {\n return execSync(command, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'ignore'],\n timeout: timeoutMs,\n }).trim();\n } catch {\n return '';\n }\n}\n\n/**\n * 检测 Claude Code 安装状态(同步版本,用于快速获取)\n */\nfunction detectClaudeInstallationSync(): ClaudeInstallInfo {\n try {\n // 1. 快速检查命令是否存在(缩短超时时间)\n const whichResult = execSyncWithTimeout('which claude', 1000);\n\n if (!whichResult) {\n return { installed: false };\n }\n\n // 2. 先检测安装方式(通过文件路径快速判断,不需要执行命令)\n let installMethod: 'npm' | 'official' | 'homebrew' | 'unknown' = 'unknown';\n\n // 检查是否通过官方脚本安装(最快,只需要检查文件)\n const officialPaths = [\n path.join(os.homedir(), '.local/bin/claude'),\n path.join(os.homedir(), '.claude/bin/claude'),\n ];\n\n for (const officialPath of officialPaths) {\n if (whichResult === officialPath || fs.existsSync(officialPath)) {\n installMethod = 'official';\n break;\n }\n }\n\n // 检查是否通过 npm 安装(可能较慢,放在后面)\n if (installMethod === 'unknown' && whichResult.includes('node_modules')) {\n installMethod = 'npm';\n }\n\n // 检查是否通过 Homebrew 安装(macOS)\n if (\n installMethod === 'unknown' &&\n process.platform === 'darwin' &&\n whichResult.includes('homebrew')\n ) {\n installMethod = 'homebrew';\n }\n\n // 3. 获取版本(可能较慢,但需要显示,使用较短超时)\n let version: string | undefined;\n try {\n const versionOutput = execSyncWithTimeout('claude --version', 1500);\n if (versionOutput) {\n // 提取版本号,可能格式: \"claude version 1.2.3\" 或 \"1.2.3\"\n const versionMatch = versionOutput.match(/(\\d+\\.\\d+\\.\\d+)/);\n version = versionMatch ? versionMatch[1] : versionOutput;\n }\n } catch {\n version = undefined;\n }\n\n return {\n installed: true,\n version,\n installMethod,\n binaryPath: whichResult,\n };\n } catch {\n return { installed: false };\n }\n}\n\n/**\n * 格式化安装方式显示文本\n */\nexport function formatInstallMethod(\n method?: 'npm' | 'official' | 'homebrew' | 'unknown',\n): string {\n switch (method) {\n case 'npm':\n return 'npm 全局安装';\n case 'official':\n return '官方脚本安装';\n case 'homebrew':\n return 'Homebrew 安装';\n case 'unknown':\n default:\n return '未知方式';\n }\n}\n\n/**\n * 检测 Claude Code 安装状态(带缓存)\n */\nexport function detectClaudeInstallation(): ClaudeInstallInfo {\n const now = Date.now();\n\n // 如果缓存有效,直接返回缓存\n if (cachedInfo && now - lastCheckTime < CACHE_DURATION) {\n return cachedInfo;\n }\n\n // 执行检测\n cachedInfo = detectClaudeInstallationSync();\n lastCheckTime = now;\n\n return cachedInfo;\n}\n\n/**\n * 获取缓存的安装信息(如果有),不会触发新的检测\n */\nexport function getCachedClaudeInfo(): ClaudeInstallInfo | null {\n return cachedInfo;\n}\n\n/**\n * 强制刷新缓存\n */\nexport function refreshClaudeInstallation(): ClaudeInstallInfo {\n cachedInfo = detectClaudeInstallationSync();\n lastCheckTime = Date.now();\n return cachedInfo;\n}\n\n/**\n * 清除缓存(在安装/卸载后调用)\n */\nexport function clearClaudeCache(): void {\n cachedInfo = null;\n lastCheckTime = 0;\n}\n\n/**\n * 格式化安装信息显示文本\n */\nexport function formatClaudeStatus(info: ClaudeInstallInfo): string {\n if (!info.installed) {\n return '未安装';\n }\n\n const parts: string[] = ['已安装'];\n\n if (info.version) {\n parts.push(`v${info.version}`);\n }\n\n if (info.installMethod) {\n parts.push(`(${formatInstallMethod(info.installMethod)})`);\n }\n\n return parts.join(' ');\n}\n","/**\n * 配置读写工具\n */\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport { theme } from '../ui';\n\n// Claude 配置目录\nconst CLAUDE_DIR = path.join(os.homedir(), '.claude');\nconst SETTINGS_FILE = path.join(CLAUDE_DIR, 'settings.json');\nconst CODE_HELPER_CONFIG_FILE = path.join(CLAUDE_DIR, 'code-helper.json');\n\n// Code Helper 配置目录(用于存储 profiles)\nconst CODE_HELPER_DIR = path.join(os.homedir(), '.code-helper');\nconst PROFILES_FILE = path.join(CODE_HELPER_DIR, 'profiles.json');\n\n// 智谱 AI Base URL\nexport const GLM_BASE_URL = 'https://open.bigmodel.cn/api/anthropic';\n\n// Kimi Base URL\nexport const KIMI_BASE_URL = 'https://api.kimi.com/coding';\n\n// 默认 Anthropic Base URL\nexport const DEFAULT_BASE_URL = 'https://api.anthropic.com';\n\n/**\n * Claude Code settings.json 结构\n */\ninterface ClaudeSettings {\n env?: {\n ANTHROPIC_AUTH_TOKEN?: string;\n ANTHROPIC_BASE_URL?: string;\n [key: string]: string | undefined;\n };\n language?: string;\n cleanupPeriodDays?: number;\n plansDirectory?: string;\n showTurnDuration?: boolean;\n spinnerTipsEnabled?: boolean;\n [key: string]: any;\n}\n\n/**\n * Code Helper 配置结构\n */\ninterface CodeHelperConfig {\n version: string;\n installedMcps: string[];\n installedPlugins: string[];\n preferences: {\n defaultBaseUrl: string;\n };\n}\n\n/**\n * 确保 Claude 配置目录存在\n */\nfunction ensureClaudeDir(): void {\n if (!fs.existsSync(CLAUDE_DIR)) {\n fs.mkdirSync(CLAUDE_DIR, { recursive: true });\n }\n}\n\n/**\n * 读取 Claude settings.json\n */\nexport function readClaudeSettings(): ClaudeSettings {\n try {\n if (fs.existsSync(SETTINGS_FILE)) {\n const content = fs.readFileSync(SETTINGS_FILE, 'utf-8');\n return JSON.parse(content);\n }\n } catch {\n // 文件不存在或解析失败\n }\n return {};\n}\n\n/**\n * 写入 Claude settings.json\n */\nexport function writeClaudeSettings(settings: ClaudeSettings): void {\n ensureClaudeDir();\n fs.writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2), 'utf-8');\n}\n\n/**\n * 读取 Code Helper 配置\n */\nexport function readCodeHelperConfig(): CodeHelperConfig {\n try {\n if (fs.existsSync(CODE_HELPER_CONFIG_FILE)) {\n const content = fs.readFileSync(CODE_HELPER_CONFIG_FILE, 'utf-8');\n return JSON.parse(content);\n }\n } catch {\n // 文件不存在或解析失败\n }\n return {\n version: '0.1.0',\n installedMcps: [],\n installedPlugins: [],\n preferences: {\n defaultBaseUrl: DEFAULT_BASE_URL,\n },\n };\n}\n\n/**\n * 写入 Code Helper 配置\n */\nexport function writeCodeHelperConfig(config: CodeHelperConfig): void {\n ensureClaudeDir();\n fs.writeFileSync(CODE_HELPER_CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');\n}\n\n// 保持向后兼容的别名\nexport const readMacoConfig = readCodeHelperConfig;\nexport const writeMacoConfig = writeCodeHelperConfig;\n\n/**\n * 获取当前 API Key 状态\n */\nexport function getApiKeyStatus(): string {\n const settings = readClaudeSettings();\n const apiKey = settings.env?.ANTHROPIC_AUTH_TOKEN;\n\n if (apiKey && apiKey.length > 0) {\n // 显示脱敏的 API Key\n const masked = apiKey.substring(0, 4) + '****';\n return theme.success(`已设置 (${masked})`);\n }\n\n return theme.dim('未设置');\n}\n\n/**\n * 获取当前 Base URL 状态\n */\nexport function getBaseUrlStatus(): string {\n const settings = readClaudeSettings();\n const baseUrl = settings.env?.ANTHROPIC_BASE_URL;\n\n if (baseUrl && baseUrl.length > 0) {\n // 简化显示\n try {\n const url = new URL(baseUrl);\n return theme.success(url.host);\n } catch {\n return theme.success(baseUrl);\n }\n }\n\n return theme.dim('未设置');\n}\n\n/**\n * 扩展的配置选项\n */\nexport interface SaveApiConfigOptions {\n model?: string;\n smallFastModel?: string;\n haikuModel?: string;\n opusModel?: string;\n sonnetModel?: string;\n skipWebFetchPreflight?: boolean;\n timeout?: string; // API 超时时间(毫秒)\n}\n\n/**\n * 保存 API 配置\n */\nexport async function saveApiConfig(\n baseUrl: string,\n apiKey: string,\n options?: SaveApiConfigOptions,\n): Promise<void> {\n const settings = readClaudeSettings();\n\n // 确保 env 对象存在\n if (!settings.env) {\n settings.env = {};\n }\n\n // 先清理掉所有服务特有的配置\n delete settings.env.ANTHROPIC_MODEL;\n delete settings.env.ANTHROPIC_SMALL_FAST_MODEL;\n delete settings.env.ANTHROPIC_DEFAULT_HAIKU_MODEL;\n delete settings.env.ANTHROPIC_DEFAULT_OPUS_MODEL;\n delete settings.env.ANTHROPIC_DEFAULT_SONNET_MODEL;\n delete settings.env.API_TIMEOUT_MS;\n delete settings.skipWebFetchPreflight;\n\n // 设置核心配置(所有服务都需要)\n settings.env.ANTHROPIC_AUTH_TOKEN = apiKey;\n settings.env.ANTHROPIC_BASE_URL = baseUrl;\n settings.env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = '1';\n\n // 设置模型(如果提供)\n if (options?.model) {\n settings.env.ANTHROPIC_MODEL = options.model;\n }\n\n // 设置额外的模型配置(如果提供)\n if (options?.smallFastModel) {\n settings.env.ANTHROPIC_SMALL_FAST_MODEL = options.smallFastModel;\n }\n if (options?.haikuModel) {\n settings.env.ANTHROPIC_DEFAULT_HAIKU_MODEL = options.haikuModel;\n }\n if (options?.opusModel) {\n settings.env.ANTHROPIC_DEFAULT_OPUS_MODEL = options.opusModel;\n }\n if (options?.sonnetModel) {\n settings.env.ANTHROPIC_DEFAULT_SONNET_MODEL = options.sonnetModel;\n }\n\n // 设置 skipWebFetchPreflight(如果提供)\n if (options?.skipWebFetchPreflight) {\n settings.skipWebFetchPreflight = true;\n }\n\n // 设置超时时间(如果提供)\n if (options?.timeout) {\n settings.env.API_TIMEOUT_MS = options.timeout;\n }\n\n writeClaudeSettings(settings);\n\n // 同时更新 Code Helper 配置\n const helperConfig = readCodeHelperConfig();\n helperConfig.preferences.defaultBaseUrl = baseUrl;\n writeCodeHelperConfig(helperConfig);\n}\n\n// ============================================\n// API 配置管理(Profiles)\n// ============================================\n\n/**\n * API 配置 Profile 接口\n */\nexport interface ApiProfile {\n id: string; // 唯一标识\n name: string; // 显示名称,如 \"智谱-个人\"\n baseUrl: string; // API Base URL\n apiKey: string; // API Key\n model?: string; // 默认模型(可选,仅矽塔需要)\n timeout?: string; // API 超时时间(可选,智谱需要)\n description?: string; // 描述(可选)\n createdAt: string; // 创建时间\n updatedAt: string; // 更新时间\n}\n\n/**\n * Profiles 配置文件结构\n */\ninterface ProfilesConfig {\n version: string;\n currentProfileId: string | null; // 当前激活的配置 ID\n profiles: ApiProfile[];\n}\n\n/**\n * 确保 Code Helper 配置目录存在\n */\nfunction ensureCodeHelperDir(): void {\n if (!fs.existsSync(CODE_HELPER_DIR)) {\n fs.mkdirSync(CODE_HELPER_DIR, { recursive: true });\n }\n}\n\n/**\n * 读取 Profiles 配置\n */\nexport function readProfiles(): ProfilesConfig {\n try {\n if (fs.existsSync(PROFILES_FILE)) {\n const content = fs.readFileSync(PROFILES_FILE, 'utf-8');\n return JSON.parse(content);\n }\n } catch {\n // 文件不存在或解析失败\n }\n return {\n version: '1.0.0',\n currentProfileId: null,\n profiles: [],\n };\n}\n\n/**\n * 写入 Profiles 配置\n */\nexport function writeProfiles(config: ProfilesConfig): void {\n ensureCodeHelperDir();\n fs.writeFileSync(PROFILES_FILE, JSON.stringify(config, null, 2), 'utf-8');\n}\n\n/**\n * 获取所有配置列表\n */\nexport function getAllProfiles(): ApiProfile[] {\n return readProfiles().profiles;\n}\n\n/**\n * 获取当前激活的配置\n */\nexport function getCurrentProfile(): ApiProfile | null {\n const config = readProfiles();\n if (!config.currentProfileId) return null;\n return config.profiles.find((p) => p.id === config.currentProfileId) || null;\n}\n\n/**\n * 添加新配置\n */\nexport function addProfile(\n profile: Omit<ApiProfile, 'id' | 'createdAt' | 'updatedAt'>,\n): ApiProfile {\n const config = readProfiles();\n const now = new Date().toISOString();\n\n const newProfile: ApiProfile = {\n ...profile,\n id: `profile_${Date.now()}`,\n createdAt: now,\n updatedAt: now,\n };\n\n config.profiles.push(newProfile);\n writeProfiles(config);\n\n return newProfile;\n}\n\n/**\n * 更新配置\n */\nexport function updateProfile(\n id: string,\n updates: Partial<Omit<ApiProfile, 'id' | 'createdAt'>>,\n): boolean {\n const config = readProfiles();\n const index = config.profiles.findIndex((p) => p.id === id);\n\n if (index === -1) return false;\n\n config.profiles[index] = {\n ...config.profiles[index],\n ...updates,\n updatedAt: new Date().toISOString(),\n };\n\n writeProfiles(config);\n return true;\n}\n\n/**\n * 删除配置\n */\nexport function deleteProfile(id: string): boolean {\n const config = readProfiles();\n const index = config.profiles.findIndex((p) => p.id === id);\n\n if (index === -1) return false;\n\n config.profiles.splice(index, 1);\n\n // 如果删除的是当前配置,清空 currentProfileId\n if (config.currentProfileId === id) {\n config.currentProfileId = null;\n }\n\n writeProfiles(config);\n return true;\n}\n\n/**\n * 切换到指定配置\n */\nexport function switchProfile(id: string): boolean {\n const config = readProfiles();\n const profile = config.profiles.find((p) => p.id === id);\n\n if (!profile) return false;\n\n // 更新 Claude settings.json\n const settings = readClaudeSettings();\n if (!settings.env) {\n settings.env = {};\n }\n\n // 先清理掉所有服务特有的配置\n delete settings.env.ANTHROPIC_MODEL;\n delete settings.env.ANTHROPIC_SMALL_FAST_MODEL;\n delete settings.env.ANTHROPIC_DEFAULT_HAIKU_MODEL;\n delete settings.env.ANTHROPIC_DEFAULT_OPUS_MODEL;\n delete settings.env.ANTHROPIC_DEFAULT_SONNET_MODEL;\n delete settings.env.API_TIMEOUT_MS;\n delete settings.skipWebFetchPreflight;\n\n // 设置核心配置(所有服务都需要)\n settings.env.ANTHROPIC_AUTH_TOKEN = profile.apiKey;\n settings.env.ANTHROPIC_BASE_URL = profile.baseUrl;\n settings.env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = '1';\n\n // 如果配置了默认模型(仅矽塔需要)\n if (profile.model) {\n settings.env.ANTHROPIC_MODEL = profile.model;\n }\n\n // 如果配置了超时时间(智谱需要)\n if (profile.timeout) {\n settings.env.API_TIMEOUT_MS = profile.timeout;\n }\n\n writeClaudeSettings(settings);\n\n // 更新当前配置 ID\n config.currentProfileId = id;\n writeProfiles(config);\n\n return true;\n}\n\n/**\n * 获取当前配置的显示状态\n */\nexport function getCurrentProfileStatus(): string {\n const current = getCurrentProfile();\n if (current) {\n return theme.success(`${current.name}`);\n }\n return theme.dim('未选择配置');\n}\n","/**\n * 授权登录菜单\n */\nimport inquirer from 'inquirer';\nimport ora from 'ora';\nimport {\n createBoxTitle,\n showError,\n showHeader,\n showInfo,\n showSuccess,\n showWarning,\n theme,\n} from '../ui';\nimport { verifyApiKey } from '../utils/api';\nimport {\n addProfile,\n ApiProfile,\n DEFAULT_BASE_URL,\n deleteProfile,\n getAllProfiles,\n getCurrentProfile,\n GLM_BASE_URL,\n KIMI_BASE_URL,\n readClaudeSettings,\n saveApiConfig,\n switchProfile,\n} from '../utils/config';\n\n/**\n * 显示授权菜单\n */\nexport async function showAuthMenu(): Promise<void> {\n while (true) {\n showHeader();\n\n console.log(createBoxTitle('授权登录'));\n console.log();\n\n // 显示当前配置状态\n const currentProfile = getCurrentProfile();\n if (currentProfile) {\n console.log(\n `${theme.primary('当前配置:')} ${theme.success(currentProfile.name)}`,\n );\n console.log(`${theme.dim(' Base URL:')} ${currentProfile.baseUrl}`);\n console.log(\n `${theme.dim(' API Key:')} ${maskApiKey(currentProfile.apiKey)}`,\n );\n console.log();\n }\n\n // 获取已保存的配置\n const savedProfiles = getAllProfiles();\n\n // 构建菜单选项\n const choices: any[] = [\n {\n name: `Claude API ${theme.dim('(推荐 - 官方 API)')}`,\n value: { type: 'claude' },\n },\n {\n name: `智谱 GLM AI ${theme.dim('(开放平台)')}`,\n value: { type: 'glm' },\n },\n {\n name: `Kimi AI ${theme.dim('(月之暗面)')}`,\n value: { type: 'kimi' },\n },\n {\n name: `手动输入密钥 ${theme.dim('(自定义 Base URL)')}`,\n value: { type: 'manual' },\n },\n ];\n\n // 如果有已保存的配置,显示恢复选项\n if (savedProfiles.length > 0) {\n choices.push(new inquirer.Separator());\n choices.push(new inquirer.Separator(theme.dim('── 已保存的配置 ──')));\n\n for (const profile of savedProfiles) {\n const isCurrent = currentProfile?.id === profile.id;\n if (isCurrent) {\n // 当前配置也显示\"恢复\"按钮(因为可能卸载后需要重新配置)\n choices.push({\n name: `${theme.success('✓')} ${theme.info('恢复')} ${\n profile.name\n } ${theme.dim('(当前)')}`,\n value: { type: 'restore', profile },\n });\n } else {\n // 非当前配置显示\"恢复\"按钮\n choices.push({\n name: ` ${theme.info('恢复')} ${profile.name}`,\n value: { type: 'restore', profile },\n });\n }\n }\n\n choices.push({\n name: ` ${theme.error('✕')} 管理已保存的配置`,\n value: { type: 'manage' },\n });\n }\n\n choices.push(\n new inquirer.Separator(),\n {\n name: `${theme.dim('<-')} 返回`,\n value: { type: 'back' },\n },\n {\n name: `${theme.dim('X')} 退出`,\n value: { type: 'exit' },\n },\n );\n\n const { choice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'choice',\n message: '请选择授权方式:',\n pageSize: 15,\n choices,\n },\n ]);\n\n switch (choice.type) {\n case 'claude':\n await handleClaudeAuth();\n break;\n case 'glm':\n await handleGlmAuth();\n break;\n case 'kimi':\n await handleKimiAuth();\n break;\n case 'manual':\n await handleManualAuth();\n break;\n case 'restore':\n await handleRestoreProfile(choice.profile);\n break;\n case 'manage':\n await handleManageProfiles();\n break;\n case 'back':\n return;\n case 'exit':\n process.exit(0);\n }\n }\n}\n\n/**\n * 处理 Claude 官方 API 授权\n */\nasync function handleClaudeAuth(): Promise<void> {\n console.log();\n\n console.log(theme.primary('Claude API 授权'));\n console.log();\n console.log(theme.dim('Base URL: ') + DEFAULT_BASE_URL);\n console.log();\n showInfo('获取 API Key 方式:');\n console.log(\n theme.dim(' 1. 访问 https://console.anthropic.com/settings/keys'),\n );\n console.log(theme.dim(' 2. 创建或复制 API Key'));\n console.log(theme.dim(' 3. 粘贴到下方'));\n console.log();\n console.log(theme.dim(' (直接按回车可返回)'));\n console.log();\n\n const { apiKey } = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: '请输入 Claude API Key:',\n mask: '*',\n },\n ]);\n\n // 空输入则返回\n if (!apiKey || apiKey.trim().length === 0) {\n return;\n }\n\n // 验证 API Key\n console.log();\n const spinner = ora('正在验证 API Key...').start();\n const verification = await verifyApiKey(DEFAULT_BASE_URL, apiKey.trim());\n\n if (!verification.valid) {\n spinner.fail('API Key 验证失败');\n console.log();\n showError(verification.error || '未知错误');\n await waitForEnter();\n return;\n }\n\n spinner.succeed('API Key 验证通过');\n\n try {\n await saveApiConfig(DEFAULT_BASE_URL, apiKey.trim());\n\n console.log();\n showSuccess('Claude API 授权配置已生效');\n\n // 显示配置内容\n displaySavedConfig();\n\n // 询问是否保存配置\n await askToSaveProfile(\n 'Claude API',\n DEFAULT_BASE_URL,\n apiKey.trim(),\n );\n } catch (error) {\n console.log();\n showError(`保存配置失败: ${(error as Error).message}`);\n await waitForEnter();\n }\n}\n\n/**\n * 处理智谱 GLM AI 授权\n */\nasync function handleGlmAuth(): Promise<void> {\n console.log();\n\n console.log(theme.primary('智谱 GLM AI 授权'));\n console.log();\n console.log(theme.dim('Base URL: ') + GLM_BASE_URL);\n console.log();\n showInfo('获取 API Key 方式:');\n console.log(\n theme.dim(' 1. 访问 https://bigmodel.cn/usercenter/proj-mgmt/apikeys'),\n );\n console.log(theme.dim(' 2. 创建或复制 API Key'));\n console.log(theme.dim(' 3. 粘贴到下方'));\n console.log();\n console.log(theme.dim(' (直接按回车可返回)'));\n console.log();\n\n const { apiKey } = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: '请输入智谱 API Key:',\n mask: '*',\n },\n ]);\n\n // 空输入则返回\n if (!apiKey || apiKey.trim().length === 0) {\n return;\n }\n\n // 验证 API Key\n console.log();\n const spinner = ora('正在验证 API Key...').start();\n const verification = await verifyApiKey(GLM_BASE_URL, apiKey.trim());\n\n if (!verification.valid) {\n spinner.fail('API Key 验证失败');\n console.log();\n showError(verification.error || '未知错误');\n await waitForEnter();\n return;\n }\n\n spinner.succeed('API Key 验证通过');\n\n try {\n // 保存智谱 AI 配置(设置超时时间)\n await saveApiConfig(GLM_BASE_URL, apiKey.trim(), {\n timeout: '3000000',\n });\n\n console.log();\n showSuccess('智谱 GLM AI 授权配置已生效');\n\n // 显示配置内容\n displaySavedConfig();\n\n // 询问是否保存配置(包含超时时间)\n await askToSaveProfile(\n '智谱 GLM',\n GLM_BASE_URL,\n apiKey.trim(),\n undefined,\n '3000000',\n );\n } catch (error) {\n console.log();\n showError(`保存配置失败: ${(error as Error).message}`);\n await waitForEnter();\n }\n}\n\n/**\n * 处理 Kimi AI 授权\n */\nasync function handleKimiAuth(): Promise<void> {\n console.log();\n\n console.log(theme.primary('Kimi AI 授权'));\n console.log();\n console.log(theme.dim('Base URL: ') + KIMI_BASE_URL);\n console.log();\n showInfo('获取 API Key 方式:');\n console.log(theme.dim(' 1. 访问 Kimi AI 官网获取 API Key'));\n console.log(theme.dim(' 2. 创建或复制 API Key'));\n console.log(theme.dim(' 3. 粘贴到下方'));\n console.log();\n console.log(theme.dim(' (直接按回车可返回)'));\n console.log();\n\n const { apiKey } = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: '请输入 Kimi API Key:',\n mask: '*',\n },\n ]);\n\n // 空输入则返回\n if (!apiKey || apiKey.trim().length === 0) {\n return;\n }\n\n // 验证 API Key\n console.log();\n const spinner = ora('正在验证 API Key...').start();\n const verification = await verifyApiKey(KIMI_BASE_URL, apiKey.trim());\n\n if (!verification.valid) {\n spinner.fail('API Key 验证失败');\n console.log();\n showError(verification.error || '未知错误');\n await waitForEnter();\n return;\n }\n\n spinner.succeed('API Key 验证通过');\n\n try {\n // 保存 Kimi AI 配置(设置超时时间)\n await saveApiConfig(KIMI_BASE_URL, apiKey.trim(), {\n timeout: '3000000',\n });\n\n console.log();\n showSuccess('Kimi AI 授权配置已生效');\n\n // 显示配置内容\n displaySavedConfig();\n\n // 询问是否保存配置(包含超时时间)\n await askToSaveProfile(\n 'Kimi AI',\n KIMI_BASE_URL,\n apiKey.trim(),\n undefined,\n '3000000',\n );\n } catch (error) {\n console.log();\n showError(`保存配置失败: ${(error as Error).message}`);\n await waitForEnter();\n }\n}\n\n\n/**\n * 处理手动输入密钥\n */\nasync function handleManualAuth(): Promise<void> {\n console.log();\n console.log(theme.primary('手动输入配置'));\n console.log();\n console.log(theme.dim('只需配置以下必要字段:'));\n console.log(theme.dim(' - ANTHROPIC_AUTH_TOKEN'));\n console.log(theme.dim(' - ANTHROPIC_BASE_URL'));\n console.log(theme.dim(' - API_TIMEOUT_MS (可选)'));\n console.log(\n theme.dim(' - CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC (默认禁用)'),\n );\n console.log();\n console.log(theme.dim('(任意步骤直接按回车可返回)'));\n console.log();\n\n const { baseUrl } = await inquirer.prompt([\n {\n type: 'input',\n name: 'baseUrl',\n message: '请输入 ANTHROPIC_BASE_URL:',\n default: DEFAULT_BASE_URL,\n },\n ]);\n\n // 空输入则返回\n if (!baseUrl || baseUrl.trim().length === 0) {\n return;\n }\n\n const { apiKey } = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: '请输入 ANTHROPIC_AUTH_TOKEN:',\n mask: '*',\n },\n ]);\n\n // 空输入则返回\n if (!apiKey || apiKey.trim().length === 0) {\n return;\n }\n\n const { timeout } = await inquirer.prompt([\n {\n type: 'input',\n name: 'timeout',\n message: '请输入 API_TIMEOUT_MS(毫秒,直接回车跳过):',\n default: '',\n validate: (input) => {\n if (!input || input.trim() === '') return true;\n const num = parseInt(input.trim(), 10);\n return (!isNaN(num) && num > 0) || '请输入有效的数字';\n },\n },\n ]);\n\n // 验证 API Key\n console.log();\n const spinner = ora('正在验证 API Key...').start();\n const verification = await verifyApiKey(baseUrl.trim(), apiKey.trim());\n\n if (!verification.valid) {\n spinner.fail('API Key 验证失败');\n console.log();\n showError(verification.error || '未知错误');\n await waitForEnter();\n return;\n }\n\n spinner.succeed('API Key 验证通过');\n\n try {\n // 使用 saveApiConfig 统一处理配置\n const options: any = {};\n if (timeout && timeout.trim()) {\n options.timeout = timeout.trim();\n }\n\n await saveApiConfig(baseUrl.trim(), apiKey.trim(), options);\n\n console.log();\n showSuccess('配置已生效');\n\n // 显示配置内容\n displaySavedConfig();\n\n // 询问是否保存配置(包含 timeout)\n await askToSaveProfile(\n '自定义配置',\n baseUrl.trim(),\n apiKey.trim(),\n undefined,\n timeout && timeout.trim() ? timeout.trim() : undefined,\n );\n } catch (error) {\n console.log();\n showError(`保存配置失败: ${(error as Error).message}`);\n await waitForEnter();\n }\n}\n\n/**\n * 询问是否保存配置\n */\nasync function askToSaveProfile(\n defaultName: string,\n baseUrl: string,\n apiKey: string,\n model?: string,\n timeout?: string,\n): Promise<void> {\n console.log();\n const { save } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'save',\n message: '是否保存此配置以便下次快速恢复?',\n default: true,\n },\n ]);\n\n if (!save) {\n await waitForEnter();\n return;\n }\n\n const { name } = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: '请输入配置名称:',\n default: defaultName,\n validate: (input) => input.trim() !== '' || '名称不能为空',\n },\n ]);\n\n try {\n const newProfile = addProfile({\n name: name.trim(),\n baseUrl,\n apiKey,\n model,\n timeout,\n });\n\n // 设置为当前配置\n switchProfile(newProfile.id);\n\n showSuccess(`配置 \"${name.trim()}\" 已保存`);\n showInfo('下次可以直接选择\"恢复\"来快速切换');\n } catch (error) {\n showError(`保存失败: ${(error as Error).message}`);\n }\n\n await waitForEnter();\n}\n\n/**\n * 恢复已保存的配置\n */\nasync function handleRestoreProfile(profile: ApiProfile): Promise<void> {\n console.log();\n\n try {\n const success = switchProfile(profile.id);\n if (success) {\n showSuccess(`已切换到:${profile.name}`);\n showInfo('配置已生效');\n } else {\n showError('切换失败');\n }\n } catch (error) {\n showError(`切换失败: ${(error as Error).message}`);\n }\n\n await waitForEnter();\n}\n\n/**\n * 管理已保存的配置(删除)\n */\nasync function handleManageProfiles(): Promise<void> {\n while (true) {\n const profiles = getAllProfiles();\n const currentProfile = getCurrentProfile();\n\n if (profiles.length === 0) {\n console.log();\n showWarning('没有已保存的配置');\n await waitForEnter();\n return;\n }\n\n showHeader();\n console.log(createBoxTitle('管理已保存的配置'));\n console.log();\n\n const choices: any[] = profiles.map((p) => {\n const isCurrent = currentProfile?.id === p.id;\n const suffix = isCurrent ? theme.warning(' (当前使用中)') : '';\n return {\n name: `${theme.error('✕')} 删除 ${p.name}${suffix} ${theme.dim(\n `- ${p.baseUrl}`,\n )}`,\n value: p,\n };\n });\n\n choices.push(new inquirer.Separator(), {\n name: `${theme.dim('<-')} 返回`,\n value: null,\n });\n\n const { profile } = await inquirer.prompt([\n {\n type: 'list',\n name: 'profile',\n message: '请选择要删除的配置:',\n pageSize: 10,\n choices,\n },\n ]);\n\n if (!profile) return;\n\n // 确认删除\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `确定要删除配置 \"${profile.name}\" 吗?`,\n default: false,\n },\n ]);\n\n if (!confirm) {\n // 用户取消删除,继续显示管理菜单\n continue;\n }\n\n try {\n deleteProfile(profile.id);\n showSuccess(`配置 \"${profile.name}\" 已删除`);\n } catch (error) {\n showError(`删除失败: ${(error as Error).message}`);\n }\n\n await waitForEnter();\n // 删除后继续循环,显示更新后的配置列表\n }\n}\n\n/**\n * 脱敏显示 API Key\n */\nfunction maskApiKey(apiKey: string): string {\n if (apiKey.length <= 8) {\n return '*'.repeat(apiKey.length);\n }\n return apiKey.substring(0, 4) + '****' + apiKey.substring(apiKey.length - 4);\n}\n\n/**\n * 显示已保存的配置\n */\nfunction displaySavedConfig(): void {\n const settings = readClaudeSettings();\n console.log();\n console.log(theme.dim('配置已同步:'));\n console.log(JSON.stringify(settings, null, 2));\n}\n\n/**\n * 等待用户按回车\n */\nasync function waitForEnter(): Promise<void> {\n console.log();\n await inquirer.prompt([\n { type: 'input', name: 'continue', message: '按回车键继续...' },\n ]);\n}\n","/**\n * API 验证工具\n */\nimport http from 'http';\nimport https from 'https';\n\n/**\n * 验证 API Key 是否有效\n * @param baseUrl API Base URL\n * @param apiKey API Key\n * @returns 验证结果,包括是否有效和错误信息\n */\nexport async function verifyApiKey(\n baseUrl: string,\n apiKey: string,\n): Promise<{ valid: boolean; error?: string }> {\n return new Promise((resolve) => {\n try {\n const url = new URL(baseUrl);\n const isHttps = url.protocol === 'https:';\n const client = isHttps ? https : http;\n\n // 构建一个最小的测试请求\n const testPayload = JSON.stringify({\n model: 'claude-3-5-sonnet-20241022',\n max_tokens: 1,\n messages: [{ role: 'user', content: 'test' }],\n });\n\n // 构建请求选项 - 使用 /v1/messages 端点来验证\n const requestOptions = {\n hostname: url.hostname,\n port: url.port || (isHttps ? 443 : 80),\n path: `${url.pathname}/v1/messages`.replace(/\\/+/g, '/'),\n method: 'POST',\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(testPayload),\n },\n timeout: 15000, // 15秒超时\n };\n\n const req = client.request(requestOptions, (res) => {\n let responseData = '';\n\n res.on('data', (chunk) => {\n responseData += chunk;\n });\n\n res.on('end', () => {\n // 200-299 状态码认为是成功\n // 注意:即使返回错误响应(如 400 模型不存在),只要是 401/403 以外的状态码\n // 都说明 API Key 本身是有效的(服务器认可了这个 Key)\n if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {\n resolve({ valid: true });\n } else if (res.statusCode === 401 || res.statusCode === 403) {\n // 401/403 说明 API Key 无效或未授权\n resolve({ valid: false, error: 'API Key 无效或未授权' });\n } else if (res.statusCode === 400) {\n // 400 通常是请求参数问题,但说明 API Key 是有效的\n // 尝试解析错误信息\n try {\n const errorData = JSON.parse(responseData);\n if (errorData.error?.message) {\n // 如果错误信息提到模型问题,认为验证通过\n if (\n errorData.error.message.includes('model') ||\n errorData.error.message.includes('不支持')\n ) {\n resolve({ valid: true });\n return;\n }\n }\n } catch {\n // 忽略 JSON 解析错误\n }\n // 其他 400 错误也认为 Key 有效(只是请求格式问题)\n resolve({ valid: true });\n } else {\n resolve({\n valid: false,\n error: `服务器返回错误 (${res.statusCode})`,\n });\n }\n });\n });\n\n req.on('error', (error) => {\n // 网络错误\n if (error.message.includes('ENOTFOUND')) {\n resolve({\n valid: false,\n error: 'Base URL 无法访问,请检查网络或 URL 是否正确',\n });\n } else if (\n error.message.includes('ETIMEDOUT') ||\n error.message.includes('ECONNREFUSED')\n ) {\n resolve({ valid: false, error: '连接超时,请检查网络或代理设置' });\n } else {\n resolve({ valid: false, error: `网络错误: ${error.message}` });\n }\n });\n\n req.on('timeout', () => {\n req.destroy();\n resolve({ valid: false, error: '请求超时,请检查网络连接' });\n });\n\n // 发送请求体\n req.write(testPayload);\n req.end();\n } catch (error) {\n resolve({\n valid: false,\n error: `验证失败: ${(error as Error).message}`,\n });\n }\n });\n}\n","/**\n * Claude Code 管理菜单(安装/卸载)\n */\nimport inquirer from 'inquirer';\nimport ora from 'ora';\nimport { createBoxTitle, showHeader, showInfo, theme } from '../ui';\nimport {\n clearClaudeCache,\n detectClaudeInstallation,\n formatInstallMethod,\n getCachedClaudeInfo,\n} from '../utils/claude';\nimport { showInstallMenu } from './install';\nimport { showUninstallMenu } from './uninstall';\n\n/**\n * 管理菜单选项\n */\nenum ManageMenuChoice {\n INSTALL = 'install',\n UNINSTALL = 'uninstall',\n REFRESH = 'refresh',\n BACK = 'back',\n EXIT = 'exit',\n}\n\n/**\n * 显示 Claude Code 管理菜单\n */\nexport async function showManageMenu(): Promise<void> {\n // 第一次进入时快速检测一次\n let claudeInfo = getCachedClaudeInfo();\n if (!claudeInfo) {\n const spinner = ora('正在检测 Claude Code...').start();\n claudeInfo = detectClaudeInstallation();\n spinner.stop();\n }\n\n while (true) {\n showHeader();\n\n console.log(createBoxTitle('Claude Code 管理'));\n console.log();\n\n // 显示安装状态\n console.log(theme.primary('当前状态:'));\n console.log();\n if (claudeInfo.installed) {\n showInfo(`✓ 已安装`);\n if (claudeInfo.version) {\n console.log(` 版本:${theme.success(claudeInfo.version)}`);\n }\n if (claudeInfo.installMethod) {\n console.log(\n ` 安装方式:${theme.info(\n formatInstallMethod(claudeInfo.installMethod),\n )}`,\n );\n }\n if (claudeInfo.binaryPath) {\n console.log(` 路径:${theme.dim(claudeInfo.binaryPath)}`);\n }\n } else {\n showInfo(`✗ 未安装`);\n }\n console.log();\n\n const { choice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'choice',\n message: '请选择操作:',\n choices: [\n {\n name: `${theme.primary('>')} 安装 Claude Code`,\n value: ManageMenuChoice.INSTALL,\n },\n {\n name: `${theme.error('*')} 卸载 Claude Code`,\n value: ManageMenuChoice.UNINSTALL,\n disabled: !claudeInfo.installed ? '未安装' : false,\n },\n {\n name: `${theme.info('↻')} 刷新状态`,\n value: ManageMenuChoice.REFRESH,\n },\n new inquirer.Separator(),\n {\n name: `${theme.dim('<-')} 返回`,\n value: ManageMenuChoice.BACK,\n },\n {\n name: `${theme.dim('X')} 退出`,\n value: ManageMenuChoice.EXIT,\n },\n ],\n },\n ]);\n\n switch (choice) {\n case ManageMenuChoice.INSTALL:\n await showInstallMenu();\n // 安装后清除缓存并刷新\n clearClaudeCache();\n claudeInfo = detectClaudeInstallation();\n break;\n case ManageMenuChoice.UNINSTALL:\n await showUninstallMenu();\n // 卸载后清除缓存并刷新\n clearClaudeCache();\n claudeInfo = detectClaudeInstallation();\n break;\n case ManageMenuChoice.REFRESH: {\n // 手动刷新\n const spinner = ora('正在刷新状态...').start();\n clearClaudeCache();\n claudeInfo = detectClaudeInstallation();\n spinner.succeed('状态已刷新');\n await new Promise((resolve) => {\n setTimeout(resolve, 500);\n });\n break;\n }\n case ManageMenuChoice.BACK:\n return;\n case ManageMenuChoice.EXIT:\n process.exit(0);\n }\n }\n}\n","/**\n * 安装 Claude Code 菜单\n */\nimport { execSync } from 'child_process';\nimport inquirer from 'inquirer';\nimport net from 'net';\nimport ora from 'ora';\nimport {\n createBoxTitle,\n showError,\n showHeader,\n showInfo,\n showSuccess,\n showWarning,\n theme,\n} from '../ui';\nimport { commandExists, executeCommand } from '../utils/exec';\nimport { detectPlatform, PlatformInfo } from '../utils/platform';\n\n// 常见代理端口\nconst COMMON_PROXY_PORTS = [\n { port: 7890, name: 'Clash' },\n { port: 7891, name: 'Clash (SOCKS)' },\n { port: 1087, name: 'V2RayU' },\n { port: 1086, name: 'V2RayU (SOCKS)' },\n { port: 8118, name: 'Privoxy' },\n { port: 1080, name: 'SOCKS5' },\n { port: 8080, name: 'HTTP Proxy' },\n { port: 9090, name: 'Clash Dashboard' },\n];\n\n/**\n * 安装方式\n */\ninterface InstallMethod {\n name: string;\n command: string;\n description: string;\n platforms: string[];\n recommended?: boolean;\n}\n\n/**\n * 可用的安装方式\n */\nconst INSTALL_METHODS: InstallMethod[] = [\n {\n name: '官方脚本安装',\n command: 'curl -fsSL https://claude.ai/install.sh | bash',\n description: '需要代理或外网访问',\n platforms: ['darwin', 'linux'],\n recommended: true,\n },\n {\n name: 'npm 安装',\n command: 'npm install -g @anthropic-ai/claude-code',\n description: '无需翻墙',\n platforms: ['darwin', 'linux', 'win32'],\n },\n {\n name: '官方脚本安装 (Windows)',\n command: 'irm https://claude.ai/install.ps1 | iex',\n description: '需要代理或外网访问',\n platforms: ['win32'],\n recommended: true,\n },\n {\n name: 'WinGet 安装',\n command: 'winget install Anthropic.ClaudeCode',\n description: '适用于 Windows',\n platforms: ['win32'],\n },\n];\n\n/**\n * 获取当前平台可用的安装方式\n */\nfunction getAvailableMethods(platform: PlatformInfo): InstallMethod[] {\n return INSTALL_METHODS.filter((method) =>\n method.platforms.includes(platform.os),\n );\n}\n\n/**\n * 检测端口是否开放\n */\nfunction checkPort(port: number, host = '127.0.0.1'): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = new net.Socket();\n socket.setTimeout(500);\n\n socket.on('connect', () => {\n socket.destroy();\n resolve(true);\n });\n\n socket.on('timeout', () => {\n socket.destroy();\n resolve(false);\n });\n\n socket.on('error', () => {\n socket.destroy();\n resolve(false);\n });\n\n socket.connect(port, host);\n });\n}\n\n/**\n * 检测系统代理设置\n */\nfunction getSystemProxy(): { host: string; port: number } | null {\n // 先检查环境变量\n const httpProxy = process.env.http_proxy || process.env.HTTP_PROXY;\n const httpsProxy = process.env.https_proxy || process.env.HTTPS_PROXY;\n const proxy = httpsProxy || httpProxy;\n\n if (proxy) {\n try {\n const url = new URL(proxy);\n return { host: url.hostname, port: parseInt(url.port) || 80 };\n } catch {\n // 忽略解析错误\n }\n }\n\n // macOS: 尝试获取系统代理设置\n if (process.platform === 'darwin') {\n try {\n const output = execSync('networksetup -getwebproxy \"Wi-Fi\"', {\n encoding: 'utf-8',\n timeout: 3000,\n });\n const enabledMatch = output.match(/Enabled:\\s*(Yes|No)/i);\n const serverMatch = output.match(/Server:\\s*(\\S+)/);\n const portMatch = output.match(/Port:\\s*(\\d+)/);\n\n if (\n enabledMatch?.[1].toLowerCase() === 'yes' &&\n serverMatch &&\n portMatch\n ) {\n return { host: serverMatch[1], port: parseInt(portMatch[1]) };\n }\n } catch {\n // 忽略错误\n }\n }\n\n return null;\n}\n\n/**\n * 检测本机可用的代理端口\n */\nasync function detectProxyPorts(): Promise<{ port: number; name: string }[]> {\n const availablePorts: { port: number; name: string }[] = [];\n\n // 并行检测所有常见端口\n const results = await Promise.all(\n COMMON_PROXY_PORTS.map(async ({ port, name }) => {\n const isOpen = await checkPort(port);\n return { port, name, isOpen };\n }),\n );\n\n for (const result of results) {\n if (result.isOpen) {\n availablePorts.push({ port: result.port, name: result.name });\n }\n }\n\n return availablePorts;\n}\n\n/**\n * 判断是否为网络错误\n */\nfunction isNetworkError(errorMessage: string): boolean {\n const networkErrorPatterns = [\n 'syntax error',\n '<!DOCTYPE',\n '<html',\n 'Could not resolve host',\n 'Connection refused',\n 'Network is unreachable',\n 'Operation timed out',\n 'SSL',\n 'SSL_connect',\n 'SSL_ERROR',\n 'LibreSSL',\n 'certificate',\n 'ENOTFOUND',\n 'ECONNREFUSED',\n 'ETIMEDOUT',\n 'ECONNRESET',\n ];\n\n return networkErrorPatterns.some((pattern) =>\n errorMessage.toLowerCase().includes(pattern.toLowerCase()),\n );\n}\n\n/**\n * 格式化友好的错误信息\n */\nfunction formatErrorMessage(error: Error): string {\n const errorMsg = error.message;\n\n // 检测是网络错误\n if (isNetworkError(errorMsg)) {\n return '网络连接失败,该安装方式需要能够访问外网';\n }\n\n // 其他错误只显示前两行\n const lines = errorMsg.split('\\n').filter((line) => line.trim());\n if (lines.length > 2) {\n return (\n lines.slice(0, 2).join('\\n') +\n `\\n${theme.dim(`... 省略 ${lines.length - 2} 行`)}`\n );\n }\n\n return errorMsg;\n}\n\n/**\n * 需要外网访问的命令\n */\nfunction needsExternalNetwork(command: string): boolean {\n return command.includes('claude.ai');\n}\n\n/**\n * 显示安装菜单\n */\nexport async function showInstallMenu(): Promise<void> {\n showHeader();\n\n const platform = detectPlatform();\n\n console.log(createBoxTitle('安装 Claude Code'));\n console.log();\n\n showInfo(`检测到您的系统:${platform.osName} ${platform.arch}`);\n console.log();\n\n const availableMethods = getAvailableMethods(platform);\n\n const choices = availableMethods.map((method) => ({\n name: `${method.name}${\n method.recommended ? theme.success(' (推荐)') : ''\n } - ${theme.dim(method.description)}`,\n value: method,\n }));\n\n choices.push(new inquirer.Separator() as any);\n choices.push({\n name: `${theme.dim('<-')} 返回`,\n value: null,\n } as any);\n choices.push({\n name: `${theme.dim('X')} 退出`,\n value: 'exit',\n } as any);\n\n const { method } = await inquirer.prompt([\n {\n type: 'list',\n name: 'method',\n message: '请选择安装方式:',\n choices,\n },\n ]);\n\n if (!method) {\n return;\n }\n\n if (method === 'exit') {\n process.exit(0);\n }\n\n let proxyUrl: string | null = null;\n let finalMethod = method;\n\n // 如果是需要外网访问的命令,先检测代理再询问是否使用\n if (needsExternalNetwork(method.command)) {\n console.log();\n\n // 先检测代理\n const spinner = ora('检测本机代理...').start();\n\n // 先检测系统代理\n const systemProxy = getSystemProxy();\n // 再检测常见代理端口\n const detectedPorts = await detectProxyPorts();\n\n spinner.stop();\n\n const proxyChoices: any[] = [];\n\n // 系统代理\n if (systemProxy) {\n proxyChoices.push({\n name: `${theme.success('✓')} 系统代理 ${theme.dim(\n `(${systemProxy.host}:${systemProxy.port})`,\n )}`,\n value: `http://${systemProxy.host}:${systemProxy.port}`,\n });\n }\n\n // 检测到的代理端口\n for (const { port, name } of detectedPorts) {\n // 避免与系统代理重复\n if (systemProxy && systemProxy.port === port) continue;\n proxyChoices.push({\n name: `${theme.success('✓')} ${name} ${theme.dim(\n `(127.0.0.1:${port})`,\n )}`,\n value: `http://127.0.0.1:${port}`,\n });\n }\n\n // 检测到代理才询问是否使用\n const hasDetectedProxy = proxyChoices.length > 0;\n\n if (hasDetectedProxy) {\n showInfo('检测到本机代理:');\n for (const choice of proxyChoices) {\n console.log(` ${choice.name}`);\n }\n console.log();\n\n const { useProxy } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'useProxy',\n message: '是否使用代理?(建议开启)',\n default: true,\n },\n ]);\n\n if (useProxy) {\n // 如果只有一个代理,直接使用\n if (proxyChoices.length === 1) {\n proxyUrl = proxyChoices[0].value;\n } else {\n // 多个代理让用户选择\n proxyChoices.push(new inquirer.Separator());\n proxyChoices.push({\n name: `${theme.dim('✕')} 不使用代理`,\n value: null,\n });\n\n const { selectedProxy } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedProxy',\n message: '请选择代理:',\n choices: proxyChoices,\n },\n ]);\n\n if (selectedProxy) {\n proxyUrl = selectedProxy;\n }\n }\n }\n } else {\n // 未检测到代理,自动切换到 npm 安装\n showWarning('未检测到本机代理');\n showInfo('自动切换到 npm 安装方式(无需翻墙)');\n console.log();\n\n // 找到 npm 安装方式\n const npmMethod = availableMethods.find((m) =>\n m.command.includes('npm install'),\n );\n if (npmMethod) {\n finalMethod = npmMethod;\n }\n }\n }\n\n // 构建最终命令\n let finalCommand = finalMethod.command;\n let envVars: Record<string, string> = {};\n\n if (proxyUrl) {\n // 如果是 curl 命令,直接在命令中添加代理参数\n if (finalCommand.includes('curl')) {\n finalCommand = finalCommand.replace('curl ', `curl --proxy ${proxyUrl} `);\n } else {\n // 其他命令使用环境变量\n envVars = {\n http_proxy: proxyUrl,\n https_proxy: proxyUrl,\n HTTP_PROXY: proxyUrl,\n HTTPS_PROXY: proxyUrl,\n };\n }\n showInfo(`使用代理: ${proxyUrl}`);\n }\n\n // 确认安装\n console.log();\n showInfo(`将执行命令: ${theme.secondary(finalCommand)}`);\n console.log();\n\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: '确认执行安装?',\n default: true,\n },\n ]);\n\n if (!confirm) {\n return;\n }\n\n // 执行安装\n const spinner = ora('正在安装 Claude Code...').start();\n\n try {\n await executeCommand(finalCommand, envVars);\n\n // 验证安装是否成功\n spinner.text = '验证安装...';\n const installed = await commandExists('claude');\n\n if (installed) {\n spinner.succeed('Claude Code 安装成功!');\n showSuccess('您现在可以在终端中运行 claude 命令');\n console.log();\n showInfo('下一步:配置 API 密钥');\n console.log(\n theme.dim(' 返回主菜单 -> 选择 \"授权登录\" -> 配置您的 API Key'),\n );\n console.log(theme.dim(' 配置完成后即可开始使用 Claude Code'));\n } else {\n spinner.fail('安装失败');\n showError('安装命令执行完成,但未找到 claude 命令');\n console.log();\n showInfo('可能的原因:');\n console.log(theme.dim(' 1. 安装过程中出现网络错误'));\n console.log(theme.dim(' 2. 需要重新打开终端才能使用 claude 命令'));\n console.log(theme.dim(' 3. 环境变量 PATH 未正确设置'));\n console.log();\n showInfo('建议:');\n if (proxyUrl) {\n console.log(\n theme.dim(\n ' 1. 检查代理软件是否设置为【全局模式】(规则模式可能拦截 claude.ai)',\n ),\n );\n console.log(theme.dim(' 2. 换用 \"npm 安装\" 方式(无需翻墙)'));\n } else {\n console.log(\n theme.dim(' 1. 使用代理重试(选择\"官方脚本安装\"后开启代理选项)'),\n );\n console.log(theme.dim(' 2. 换用 \"npm 安装\" 方式(无需翻墙)'));\n }\n }\n } catch (error) {\n spinner.fail('安装失败');\n const friendlyError = formatErrorMessage(error as Error);\n showError(friendlyError);\n\n // 如果是网络错误,给出额外建议\n if (isNetworkError((error as Error).message)) {\n console.log();\n showInfo('建议:');\n if (proxyUrl) {\n console.log(\n theme.dim(\n ' 1. 检查代理软件是否设置为【全局模式】(规则模式可能拦截 claude.ai)',\n ),\n );\n console.log(theme.dim(' 2. 尝试更换代理端口或代理软件'));\n console.log(theme.dim(' 3. 换用 \"npm 安装\" 方式(无需翻墙)'));\n } else {\n console.log(\n theme.dim(' 1. 使用代理重试(选择\"官方脚本安装\"后开启代理选项)'),\n );\n console.log(theme.dim(' 2. 换用 \"npm 安装\" 方式(无需翻墙)'));\n }\n }\n }\n\n // 等待用户确认后返回\n await inquirer.prompt([\n {\n type: 'input',\n name: 'continue',\n message: '按回车键返回主菜单...',\n },\n ]);\n}\n","/**\n * 系统检测工具\n */\nimport os from 'os';\n\n/**\n * 平台信息\n */\nexport interface PlatformInfo {\n os: NodeJS.Platform;\n osName: string;\n arch: string;\n isWindows: boolean;\n isMac: boolean;\n isLinux: boolean;\n}\n\n/**\n * 获取操作系统友好名称\n */\nfunction getOsName(platform: NodeJS.Platform): string {\n switch (platform) {\n case 'darwin':\n return 'macOS';\n case 'win32':\n return 'Windows';\n case 'linux':\n return 'Linux';\n default:\n return platform;\n }\n}\n\n/**\n * 获取架构友好名称\n */\nfunction getArchName(arch: string): string {\n switch (arch) {\n case 'x64':\n return 'x64';\n case 'arm64':\n return 'arm64';\n case 'ia32':\n return 'x86';\n default:\n return arch;\n }\n}\n\n/**\n * 检测当前平台信息\n */\nexport function detectPlatform(): PlatformInfo {\n const platform = os.platform();\n const arch = os.arch();\n\n return {\n os: platform,\n osName: getOsName(platform),\n arch: getArchName(arch),\n isWindows: platform === 'win32',\n isMac: platform === 'darwin',\n isLinux: platform === 'linux',\n };\n}\n","/**\n * 卸载 Claude Code 菜单\n */\nimport fs from 'fs';\nimport inquirer from 'inquirer';\nimport ora from 'ora';\nimport os from 'os';\nimport path from 'path';\nimport {\n createBoxTitle,\n showError,\n showHeader,\n showInfo,\n showSuccess,\n showWarning,\n theme,\n} from '../ui';\nimport { executeCommand } from '../utils/exec';\nimport { detectPlatform } from '../utils/platform';\n\n/**\n * 卸载选项\n */\nenum UninstallChoice {\n PROGRAM_ONLY = 'program_only',\n COMPLETE = 'complete',\n BACK = 'back',\n EXIT = 'exit',\n}\n\n/**\n * 显示卸载菜单\n */\nexport async function showUninstallMenu(): Promise<void> {\n showHeader();\n\n console.log(createBoxTitle('卸载 Claude Code'));\n console.log();\n\n const { choice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'choice',\n message: '请选择卸载方式:',\n choices: [\n {\n name: `仅卸载程序 ${theme.dim('(保留配置、会话和插件)')}`,\n value: UninstallChoice.PROGRAM_ONLY,\n },\n {\n name: `${theme.error('完整卸载')} ${theme.dim(\n '(删除程序、配置、会话和插件)',\n )}`,\n value: UninstallChoice.COMPLETE,\n },\n new inquirer.Separator(),\n {\n name: `${theme.dim('<-')} 返回`,\n value: UninstallChoice.BACK,\n },\n {\n name: `${theme.dim('X')} 退出`,\n value: UninstallChoice.EXIT,\n },\n ],\n },\n ]);\n\n switch (choice) {\n case UninstallChoice.PROGRAM_ONLY:\n await handleProgramOnlyUninstall();\n break;\n case UninstallChoice.COMPLETE:\n await handleCompleteUninstall();\n break;\n case UninstallChoice.BACK:\n return;\n case UninstallChoice.EXIT:\n process.exit(0);\n }\n}\n\n/**\n * 仅卸载程序\n */\nasync function handleProgramOnlyUninstall(): Promise<void> {\n console.log();\n showInfo('将仅卸载 Claude Code 程序,保留以下内容:');\n console.log(theme.dim(' - ~/.claude/ 目录(配置和会话)'));\n console.log(theme.dim(' - ~/.claude.json(MCP 配置)'));\n console.log(theme.dim(' - 已安装的插件'));\n console.log();\n\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: '确认卸载 Claude Code 程序?',\n default: false,\n },\n ]);\n\n if (!confirm) {\n return;\n }\n\n const spinner = ora('正在卸载 Claude Code...').start();\n\n try {\n const platform = detectPlatform();\n\n // 尝试多种卸载方式\n let uninstalled = false;\n\n // 1. 尝试 npm 卸载\n try {\n await executeCommand('npm uninstall -g @anthropic-ai/claude-code');\n uninstalled = true;\n } catch {\n // npm 卸载失败,尝试其他方式\n }\n\n // 2. macOS 尝试 Homebrew 卸载\n if (platform.isMac && !uninstalled) {\n try {\n await executeCommand('brew uninstall --cask claude 2>/dev/null');\n uninstalled = true;\n } catch {\n // Homebrew 卸载失败\n }\n }\n\n // 3. 尝试删除二进制文件\n const binaryPaths = [\n '/usr/local/bin/claude',\n path.join(os.homedir(), '.local/bin/claude'),\n path.join(os.homedir(), '.claude/bin/claude'),\n ];\n\n for (const binPath of binaryPaths) {\n if (fs.existsSync(binPath)) {\n try {\n fs.unlinkSync(binPath);\n uninstalled = true;\n } catch {\n // 删除失败\n }\n }\n }\n\n if (uninstalled) {\n spinner.succeed('Claude Code 程序已卸载');\n showSuccess('配置和会话已保留,重新安装后可继续使用');\n } else {\n spinner.warn('未找到已安装的 Claude Code');\n showInfo('可能已经卸载或使用了其他安装方式');\n }\n } catch (error) {\n spinner.fail('卸载失败');\n showError((error as Error).message);\n }\n\n console.log();\n await inquirer.prompt([\n {\n type: 'input',\n name: 'continue',\n message: '按回车键返回...',\n },\n ]);\n}\n\n/**\n * 完整卸载\n */\nasync function handleCompleteUninstall(): Promise<void> {\n console.log();\n showWarning('⚠️ 完整卸载将删除以下所有内容:');\n console.log(theme.error(' - Claude Code 程序'));\n console.log(theme.error(' - ~/.claude/ 目录(配置和会话)'));\n console.log(theme.error(' - ~/.claude.json(MCP 配置)'));\n console.log(theme.error(' - 已安装的插件'));\n console.log();\n showWarning('此操作不可恢复!');\n console.log();\n\n const { confirmFirst } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmFirst',\n message: '确认要完整卸载 Claude Code?',\n default: false,\n },\n ]);\n\n if (!confirmFirst) {\n return;\n }\n\n const { confirmSecond } = await inquirer.prompt([\n {\n type: 'input',\n name: 'confirmSecond',\n message: '请输入 \"DELETE\" 确认删除:',\n },\n ]);\n\n if (confirmSecond !== 'DELETE') {\n showInfo('已取消卸载');\n return;\n }\n\n const spinner = ora('正在完整卸载 Claude Code...').start();\n\n try {\n const platform = detectPlatform();\n\n // 1. 卸载程序\n spinner.text = '卸载程序...';\n try {\n await executeCommand(\n 'npm uninstall -g @anthropic-ai/claude-code 2>/dev/null || true',\n );\n } catch {}\n\n if (platform.isMac) {\n try {\n await executeCommand(\n 'brew uninstall --cask claude 2>/dev/null || true',\n );\n } catch {}\n }\n\n // 删除二进制文件\n const binaryPaths = [\n '/usr/local/bin/claude',\n path.join(os.homedir(), '.local/bin/claude'),\n path.join(os.homedir(), '.claude/bin/claude'),\n ];\n\n for (const binPath of binaryPaths) {\n if (fs.existsSync(binPath)) {\n try {\n fs.unlinkSync(binPath);\n } catch {}\n }\n }\n\n // 2. 删除配置目录\n spinner.text = '删除配置和会话...';\n const claudeDir = path.join(os.homedir(), '.claude');\n if (fs.existsSync(claudeDir)) {\n fs.rmSync(claudeDir, { recursive: true, force: true });\n }\n\n // 3. 删除 MCP 配置\n spinner.text = '删除 MCP 配置...';\n const claudeJson = path.join(os.homedir(), '.claude.json');\n if (fs.existsSync(claudeJson)) {\n fs.unlinkSync(claudeJson);\n }\n\n spinner.succeed('Claude Code 已完整卸载');\n showSuccess('所有程序、配置和数据已删除');\n } catch (error) {\n spinner.fail('卸载过程中出现错误');\n showError((error as Error).message);\n }\n\n console.log();\n await inquirer.prompt([\n {\n type: 'input',\n name: 'continue',\n message: '按回车键返回...',\n },\n ]);\n}\n","/**\n * MCP 服务管理菜单\n */\nimport inquirer from 'inquirer';\nimport ora from 'ora';\nimport type { McpServer } from '../config/constants';\nimport { McpService } from '../services/mcp';\nimport {\n createBoxTitle,\n showHeader,\n showInfo,\n showWarning,\n theme,\n} from '../ui';\n\n// MCP 服务实例(暂时未使用,待功能启用后使用)\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst mcpService = new McpService();\n\n/**\n * 显示 MCP 管理主菜单\n */\nexport async function showMcpMenu(): Promise<void> {\n showHeader();\n console.log(createBoxTitle('MCP 服务管理'));\n console.log();\n console.log();\n console.log(theme.info(' 🚀 敬请期待 🚀'));\n console.log();\n console.log(theme.dim(' MCP 服务管理功能即将上线'));\n console.log(theme.dim(' 支持本地+云端 MCP 服务管理'));\n console.log(theme.dim(' 敬请期待...'));\n console.log();\n console.log();\n\n await inquirer.prompt([\n { type: 'input', name: 'continue', message: '按回车键返回...' },\n ]);\n return;\n\n // ==================== 以下代码暂时禁用 ====================\n /*\n // 加载 MCP 列表\n const spinner = ora('正在加载 MCP 服务列表...').start();\n let mcpServers = await mcpService.fetchMcpServers();\n spinner.stop();\n\n while (true) {\n showHeader();\n console.log(createBoxTitle('MCP 服务管理'));\n console.log();\n\n const installedServers = mcpService.getInstalledServers();\n const recommendedServers = mcpServers.filter((s) => s.recommended);\n const allInstalled =\n recommendedServers.length > 0 &&\n recommendedServers.every((s) => installedServers.includes(s.id));\n\n console.log(\n theme.dim(\n `已安装: ${installedServers.length}/${mcpServers.length} 个服务 | 推荐: ${recommendedServers.length} 个`,\n ),\n );\n console.log();\n\n const choices: any[] = [];\n\n if (allInstalled && recommendedServers.length > 0) {\n choices.push({\n name: `一键卸载所有推荐 MCP (${recommendedServers.length} 个)`,\n value: McpChoice.UNINSTALL_ALL,\n });\n } else if (recommendedServers.length > 0) {\n choices.push({\n name: `一键安装所有推荐 MCP (${recommendedServers.length} 个)`,\n value: McpChoice.INSTALL_ALL,\n });\n }\n\n choices.push(new inquirer.Separator());\n\n // 按来源和推荐程度排序\n const sortedServers = [...mcpServers].sort((a, b) => {\n // 推荐的排在前面\n if (a.recommended !== b.recommended) {\n return a.recommended ? -1 : 1;\n }\n // 本地的排在前面\n if (a.source !== b.source) {\n return a.source === 'local' ? -1 : 1;\n }\n // 按名称排序\n return a.name.localeCompare(b.name);\n });\n\n for (const server of sortedServers) {\n const isInstalled = installedServers.includes(server.id);\n const statusIcon = isInstalled ? theme.success('[+]') : theme.dim('[ ]');\n const sourceLabel =\n server.source === 'marketplace'\n ? theme.info('云端')\n : theme.dim('本地');\n const recommendedLabel = server.recommended ? theme.warning(' ⭐') : '';\n\n choices.push({\n name: `${statusIcon} ${server.name} [${sourceLabel}]${recommendedLabel} - ${theme.dim(server.description)}`,\n value: server.id,\n });\n }\n\n choices.push(new inquirer.Separator());\n choices.push({\n name: `${theme.info('🔄')} 刷新服务列表`,\n value: McpChoice.REFRESH,\n });\n choices.push(new inquirer.Separator());\n choices.push({ name: `${theme.dim('<-')} 返回`, value: McpChoice.BACK });\n choices.push({ name: `${theme.dim('x')} 退出`, value: McpChoice.EXIT });\n\n const { choice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'choice',\n message: '请选择MCP服务:',\n pageSize: 15,\n choices,\n },\n ]);\n\n if (choice === McpChoice.INSTALL_ALL) {\n await handleInstallAll(recommendedServers);\n } else if (choice === McpChoice.UNINSTALL_ALL) {\n await handleUninstallAll(recommendedServers);\n } else if (choice === McpChoice.REFRESH) {\n const refreshSpinner = ora('正在刷新 MCP 服务列表...').start();\n mcpServers = await mcpService.refreshMcpServers();\n refreshSpinner.succeed('MCP 服务列表已刷新');\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), 800);\n });\n continue;\n } else if (choice === McpChoice.BACK) {\n return;\n } else if (choice === McpChoice.EXIT) {\n process.exit(0);\n } else {\n const server = mcpServers.find((s) => s.id === choice);\n if (server) {\n await showMcpDetailMenu(server);\n }\n }\n }\n */\n}\n\n/**\n * 显示单个 MCP 服务的详情菜单\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nasync function showMcpDetailMenu(server: McpServer): Promise<void> {\n const isInstalled = mcpService.isServerInstalled(server.id);\n\n while (true) {\n showHeader();\n console.log(createBoxTitle(server.name));\n console.log();\n\n console.log(theme.primary('ID:'), theme.dim(server.id));\n console.log(\n theme.primary('来源:'),\n server.source === 'marketplace'\n ? theme.info('云端市场')\n : theme.dim('本地内置'),\n );\n console.log(\n theme.primary('传输:'),\n theme.dim(server.transport.toUpperCase()),\n );\n console.log(\n theme.primary('类型:'),\n theme.dim(server.category || 'builtin'),\n );\n\n // 根据传输协议显示不同信息\n if (server.transport === 'http' || server.transport === 'sse') {\n console.log(theme.primary('地址:'), theme.dim(server.url || 'N/A'));\n if (server.requiredEnv && server.requiredEnv.length > 0) {\n console.log(\n theme.primary('需要:'),\n theme.warning(`API Key (${server.requiredEnv.join(', ')})`),\n );\n if (server.apiKeyUrl) {\n console.log(theme.primary('获取:'), theme.info(server.apiKeyUrl));\n }\n }\n } else {\n if (server.package) {\n console.log(theme.primary('包名:'), theme.dim(server.package));\n }\n if (server.command && server.args) {\n console.log(\n theme.primary('命令:'),\n theme.dim(`${server.command} ${server.args.join(' ')}`),\n );\n }\n }\n\n console.log(theme.primary('描述:'), theme.dim(server.description));\n if (server.usage) {\n console.log();\n console.log(theme.primary('使用说明:'));\n console.log(theme.dim(` ${server.usage}`));\n }\n if (server.recommended) {\n console.log();\n console.log(theme.warning('⭐ 推荐安装'));\n }\n console.log();\n console.log(\n theme.primary('[+] 状态:'),\n isInstalled ? theme.success('已安装') : theme.warning('未安装'),\n );\n console.log();\n\n const choices: any[] = [];\n\n if (isInstalled) {\n choices.push({\n name: '* 卸载',\n value: 'uninstall',\n });\n } else {\n choices.push({\n name: '* 安装',\n value: 'install',\n });\n }\n\n choices.push(new inquirer.Separator());\n choices.push({ name: `${theme.dim('<-')} 返回`, value: 'back' });\n choices.push({ name: `${theme.dim('x')} 退出`, value: 'exit' });\n\n const { action } = await inquirer.prompt([\n { type: 'list', name: 'action', message: '请选择操作:', choices },\n ]);\n\n if (action === 'install') {\n await handleInstallOne(server);\n return;\n } else if (action === 'uninstall') {\n await handleUninstallOne(server);\n return;\n } else if (action === 'back') {\n return;\n } else if (action === 'exit') {\n process.exit(0);\n }\n }\n}\n\n/**\n * 一键安装所有推荐 MCP\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nasync function handleInstallAll(servers: McpServer[]): Promise<void> {\n console.log();\n\n // 检查是否有需要 API Key 的服务\n const serversNeedingKeys = servers.filter(\n (s) => s.requiredEnv && s.requiredEnv.length > 0,\n );\n const serversNoKeys = servers.filter(\n (s) => !s.requiredEnv || s.requiredEnv.length === 0,\n );\n\n if (serversNeedingKeys.length > 0) {\n console.log(theme.warning('⚠️ 以下服务需要 API Key,将跳过安装:'));\n for (const srv of serversNeedingKeys) {\n console.log(\n theme.dim(` • ${srv.name} (需要 ${srv.requiredEnv!.join(', ')})`),\n );\n }\n console.log();\n console.log(theme.info('💡 请单独安装这些服务以配置 API Key'));\n console.log();\n }\n\n const installCount = serversNoKeys.length;\n if (installCount === 0) {\n showInfo('所有推荐服务都需要 API Key,请单独安装');\n console.log();\n await inquirer.prompt([\n { type: 'input', name: 'continue', message: '按回车键继续...' },\n ]);\n return;\n }\n\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `确定要安装 ${installCount} 个可直接安装的 MCP 服务吗?`,\n default: false,\n },\n ]);\n\n if (!confirm) return;\n\n const spinner = ora('正在安装 MCP 服务...').start();\n try {\n for (const server of serversNoKeys) {\n spinner.text = `正在安装 ${server.name}...`;\n mcpService.installServer(server);\n }\n spinner.succeed(`成功安装 ${installCount} 个 MCP 服务`);\n } catch (error) {\n spinner.fail(`安装失败: ${(error as Error).message}`);\n }\n console.log();\n await inquirer.prompt([\n { type: 'input', name: 'continue', message: '按回车键继续...' },\n ]);\n}\n\n/**\n * 一键卸载所有推荐 MCP\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nasync function handleUninstallAll(servers: McpServer[]): Promise<void> {\n console.log();\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `确定要卸载全部 ${servers.length} 个推荐 MCP 服务吗?`,\n default: false,\n },\n ]);\n\n if (!confirm) return;\n\n const spinner = ora('正在卸载 MCP 服务...').start();\n try {\n for (const server of servers) {\n spinner.text = `正在卸载 ${server.name}...`;\n mcpService.uninstallServer(server.id);\n }\n spinner.succeed(`成功卸载 ${servers.length} 个 MCP 服务`);\n } catch (error) {\n spinner.fail(`卸载失败: ${(error as Error).message}`);\n }\n console.log();\n await inquirer.prompt([\n { type: 'input', name: 'continue', message: '按回车键继续...' },\n ]);\n}\n\n/**\n * 安装单个 MCP 服务\n */\nasync function handleInstallOne(server: McpServer): Promise<void> {\n console.log();\n\n let userEnv: Record<string, string> = {};\n\n // 检查是否需要 API Key\n if (server.requiredEnv && server.requiredEnv.length > 0) {\n console.log(theme.warning('⚠️ 此服务需要配置 API Key'));\n console.log();\n\n if (server.apiKeyUrl) {\n console.log(\n theme.info(`📌 获取 API Key: ${theme.dim(server.apiKeyUrl)}`),\n );\n console.log();\n }\n\n // 询问用户是否现在配置\n const { configureNow } = await inquirer.prompt([\n {\n type: 'list',\n name: 'configureNow',\n message: '请选择:',\n choices: [\n { name: '💡 现在输入 API Key', value: 'yes' },\n {\n name: '⏭️ 暂时跳过(稍后手动配置 ~/.claude.json)',\n value: 'skip',\n },\n { name: '❌ 取消安装', value: 'cancel' },\n ],\n },\n ]);\n\n if (configureNow === 'cancel') {\n showInfo('已取消安装');\n console.log();\n await inquirer.prompt([\n { type: 'input', name: 'continue', message: '按回车键继续...' },\n ]);\n return;\n }\n\n if (configureNow === 'yes') {\n console.log();\n // 逐个输入必需的环境变量\n for (const envKey of server.requiredEnv) {\n const { value } = await inquirer.prompt([\n {\n type: 'password',\n name: 'value',\n message: `请输入 ${envKey}:`,\n mask: '*',\n },\n ]);\n userEnv[envKey] = value;\n }\n }\n }\n\n console.log();\n const spinner = ora(`正在安装 ${server.name}...`).start();\n\n try {\n mcpService.installServer(server, userEnv);\n spinner.succeed(`${server.name} 安装成功`);\n\n // 提示信息\n if (server.requiredEnv && server.requiredEnv.length > 0) {\n if (Object.keys(userEnv).length === 0) {\n console.log();\n showWarning(\n `请在 ~/.claude.json 中手动配置 ${server.requiredEnv.join(', ')}`,\n );\n } else {\n console.log();\n showInfo('API Key 已配置,重启 Claude Code 后生效');\n }\n }\n } catch (error) {\n spinner.fail(`安装失败: ${(error as Error).message}`);\n }\n\n console.log();\n await inquirer.prompt([\n { type: 'input', name: 'continue', message: '按回车键继续...' },\n ]);\n}\n\n/**\n * 卸载单个 MCP 服务\n */\nasync function handleUninstallOne(server: McpServer): Promise<void> {\n console.log();\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `确定要卸载 ${server.name} 吗?`,\n default: false,\n },\n ]);\n\n if (!confirm) return;\n\n const spinner = ora(`正在卸载 ${server.name}...`).start();\n\n try {\n mcpService.uninstallServer(server.id);\n spinner.succeed(`${server.name} 卸载成功`);\n } catch (error) {\n spinner.fail(`卸载失败: ${(error as Error).message}`);\n }\n\n console.log();\n await inquirer.prompt([\n { type: 'input', name: 'continue', message: '按回车键继续...' },\n ]);\n}\n","/**\n * MCP 服务管理\n */\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport {\n BUILTIN_DEFAULT_MCPS,\n MCP_SERVERS_CONFIG_FILE,\n type McpRegistry,\n type McpServer,\n} from '../config/constants';\nimport { showWarning } from '../ui';\nimport { CacheManager } from '../utils/cache';\n\n// MCP 配置文件路径\nconst CLAUDE_JSON_FILE = path.join(os.homedir(), '.claude.json');\n\nexport class McpService {\n private cacheManager: CacheManager;\n\n constructor() {\n this.cacheManager = new CacheManager('mcp-servers');\n }\n\n /**\n * 获取所有 MCP 推荐列表(从本地配置文件读取)\n */\n async fetchMcpServers(): Promise<McpServer[]> {\n try {\n // 读取本地配置文件\n if (fs.existsSync(MCP_SERVERS_CONFIG_FILE)) {\n const content = fs.readFileSync(MCP_SERVERS_CONFIG_FILE, 'utf-8');\n const data: McpRegistry = JSON.parse(content);\n \n if (data.mcpServers && Array.isArray(data.mcpServers)) {\n const mcpServers = this.normalizeServers(data.mcpServers);\n // 合并本地内置和配置文件中的服务器\n return this.mergeServers(BUILTIN_DEFAULT_MCPS, mcpServers);\n }\n }\n \n // 配置文件不存在,使用内置默认配置\n showWarning('使用内置默认 MCP 配置');\n return BUILTIN_DEFAULT_MCPS;\n } catch (error) {\n // 读取失败,使用内置默认配置\n showWarning('读取 MCP 配置文件失败,使用内置默认配置');\n return BUILTIN_DEFAULT_MCPS;\n }\n }\n\n /**\n * 刷新 MCP 列表(清除缓存并重新获取)\n */\n async refreshMcpServers(): Promise<McpServer[]> {\n this.cacheManager.clear();\n return this.fetchMcpServers();\n }\n\n /**\n * 标准化 MCP 服务器数据\n */\n private normalizeServers(rawServers: any[]): McpServer[] {\n return rawServers.map((server) => ({\n id: server.id,\n name: server.name,\n description: server.description,\n usage: server.usage,\n transport: server.transport || 'stdio', // 默认 stdio 传输\n package: server.package,\n command: server.command,\n args: server.args || [],\n url: server.url,\n headers: server.headers,\n env: server.env,\n requiredEnv: server.requiredEnv,\n apiKeyUrl: server.apiKeyUrl,\n category: server.category || 'remote',\n recommended: server.recommended || false,\n source: server.source || 'marketplace',\n }));\n }\n\n /**\n * 合并本地和远程 MCP 列表(去重)\n */\n private mergeServers(\n localServers: McpServer[],\n remoteServers: McpServer[],\n ): McpServer[] {\n const serverMap = new Map<string, McpServer>();\n\n // 先添加本地服务器(优先级高)\n for (const server of localServers) {\n serverMap.set(server.id, server);\n }\n\n // 再添加远程服务器(不覆盖本地)\n for (const server of remoteServers) {\n if (!serverMap.has(server.id)) {\n serverMap.set(server.id, server);\n }\n }\n\n return Array.from(serverMap.values());\n }\n\n /**\n * 降级处理\n */\n private handleFallback(\n cached: { data: McpRegistry; timestamp: number } | null,\n ): McpServer[] {\n if (cached) {\n showWarning('使用缓存的 MCP 列表(API 暂时不可用)');\n return this.mergeServers(BUILTIN_DEFAULT_MCPS, cached.data.mcpServers);\n }\n\n showWarning('使用内置默认 MCP 配置');\n return BUILTIN_DEFAULT_MCPS;\n }\n\n /**\n * 读取 MCP 配置\n */\n readMcpConfig(): any {\n try {\n if (fs.existsSync(CLAUDE_JSON_FILE)) {\n const content = fs.readFileSync(CLAUDE_JSON_FILE, 'utf-8');\n return JSON.parse(content);\n }\n } catch {\n // 文件不存在或解析失败\n }\n return { mcpServers: {} };\n }\n\n /**\n * 写入 MCP 配置\n */\n writeMcpConfig(config: any): void {\n fs.writeFileSync(\n CLAUDE_JSON_FILE,\n JSON.stringify(config, null, 2),\n 'utf-8',\n );\n }\n\n /**\n * 获取已安装的 MCP 服务列表\n */\n getInstalledServers(): string[] {\n const config = this.readMcpConfig();\n return Object.keys(config.mcpServers || {});\n }\n\n /**\n * 检查 MCP 服务器是否已安装\n */\n isServerInstalled(serverId: string): boolean {\n return this.getInstalledServers().includes(serverId);\n }\n\n /**\n * 安装单个 MCP 服务器\n * @param server MCP 服务器配置\n * @param userEnv 用户提供的环境变量(如 API Key)\n */\n installServer(server: McpServer, userEnv?: Record<string, string>): void {\n const config = this.readMcpConfig();\n if (!config.mcpServers) {\n config.mcpServers = {};\n }\n\n // 根据传输协议构建配置\n if (server.transport === 'http' || server.transport === 'sse') {\n // HTTP/SSE 传输\n const headers: Record<string, string> = {};\n\n // 替换 headers 中的环境变量模板\n if (server.headers) {\n for (const [key, value] of Object.entries(server.headers)) {\n // 检查是否为模板变量 ${VAR_NAME}\n const match = value.match(/^\\$\\{(.+)\\}$/);\n if (match && userEnv) {\n const varName = match[1];\n headers[key] = userEnv[varName] || value;\n } else {\n headers[key] = value;\n }\n }\n }\n\n config.mcpServers[server.id] = {\n transport: server.transport,\n url: server.url!,\n ...(Object.keys(headers).length > 0 ? { headers } : {}),\n };\n } else {\n // stdio 传输(默认)\n config.mcpServers[server.id] = {\n command: server.command!,\n args: server.args!,\n ...(server.env || userEnv\n ? { env: { ...server.env, ...userEnv } }\n : {}),\n };\n }\n\n this.writeMcpConfig(config);\n }\n\n /**\n * 卸载单个 MCP 服务器\n */\n uninstallServer(serverId: string): void {\n const config = this.readMcpConfig();\n delete config.mcpServers[serverId];\n this.writeMcpConfig(config);\n }\n\n /**\n * 批量安装 MCP 服务器(不提示输入 API Key)\n */\n installServers(servers: McpServer[]): void {\n const config = this.readMcpConfig();\n if (!config.mcpServers) {\n config.mcpServers = {};\n }\n\n for (const server of servers) {\n // 根据传输协议构建配置\n if (server.transport === 'http' || server.transport === 'sse') {\n config.mcpServers[server.id] = {\n transport: server.transport,\n url: server.url!,\n ...(server.headers ? { headers: server.headers } : {}),\n };\n } else {\n config.mcpServers[server.id] = {\n command: server.command!,\n args: server.args!,\n ...(server.env ? { env: server.env } : {}),\n };\n }\n }\n\n this.writeMcpConfig(config);\n }\n\n /**\n * 批量卸载 MCP 服务器\n */\n uninstallServers(serverIds: string[]): void {\n const config = this.readMcpConfig();\n\n for (const serverId of serverIds) {\n delete config.mcpServers[serverId];\n }\n\n this.writeMcpConfig(config);\n }\n}\n","/**\n * 配置常量\n */\n\n/**\n * 市场相关配置\n */\nexport interface Market {\n name: string;\n source: string;\n description: string;\n category: 'official' | 'team' | 'experimental';\n recommended: boolean;\n default: boolean;\n}\n\nexport interface MarketRegistry {\n version: string;\n updated_at: string;\n markets: Market[];\n}\n\n/**\n * 本地配置文件路径\n */\nimport path from 'path';\nexport const CONFIG_DIR = path.resolve(__dirname, '../../../config');\nexport const MARKETS_CONFIG_FILE = path.join(CONFIG_DIR, 'markets.json');\nexport const MCP_SERVERS_CONFIG_FILE = path.join(CONFIG_DIR, 'mcpServers.json');\n\n/**\n * 缓存过期时间(6小时)\n */\nexport const CACHE_TTL = 6 * 60 * 60 * 1000;\n\n/**\n * 内置默认市场配置(降级使用)\n */\nexport const BUILTIN_DEFAULT_MARKETS: Market[] = [\n {\n name: 'macopowers',\n source: 'https://github.com/macopowers-dev/macopowers.git',\n description: 'MacoPowers Official Plugin Marketplace',\n category: 'official',\n recommended: true,\n default: true,\n },\n];\n\n/**\n * MCP 服务相关配置\n */\n\n/**\n * MCP 传输协议类型\n */\nexport type McpTransport = 'stdio' | 'http' | 'sse';\n\n/**\n * MCP 服务器配置接口\n */\nexport interface McpServer {\n id: string;\n name: string;\n description: string;\n usage?: string; // 使用说明\n transport: McpTransport; // 传输协议\n package?: string; // stdio: NPM包名\n command?: string; // stdio: 启动命令\n args?: string[]; // stdio: 命令参数\n url?: string; // http/sse: 服务地址\n headers?: Record<string, string>; // http/sse: 请求头(支持模板变量 ${VAR_NAME})\n env?: Record<string, string>; // stdio: 环境变量\n requiredEnv?: string[]; // 必需的环境变量列表(用于提示用户输入)\n apiKeyUrl?: string; // 获取 API Key 的网页地址\n category?: 'builtin' | 'remote' | 'custom';\n recommended?: boolean;\n source?: 'local' | 'marketplace';\n}\n\n/**\n * MCP 注册中心响应格式\n */\nexport interface McpRegistry {\n version: string;\n updated_at: string;\n mcpServers: McpServer[];\n}\n\n/**\n * 内置默认 MCP 服务配置(降级使用)\n */\nexport const BUILTIN_DEFAULT_MCPS: McpServer[] = [\n {\n id: 'context7',\n name: 'Context7',\n description:\n 'Get real-time documentation and code examples for popular libraries like React, Next.js, Node.js',\n usage:\n 'Query the latest API docs, usage examples and best practices for any library in Claude. Example: \"How to use Next.js 14 Server Actions?\", \"React useEffect latest usage\".',\n transport: 'http',\n url: 'https://mcp.context7.com/mcp',\n headers: {\n CONTEXT7_API_KEY: '${CONTEXT7_API_KEY}',\n },\n requiredEnv: ['CONTEXT7_API_KEY'],\n apiKeyUrl: 'https://context7.com/dashboard',\n category: 'builtin',\n recommended: true,\n source: 'local',\n },\n];\n","/**\n * 缓存管理器\n */\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\n\nexport class CacheManager {\n private cacheDir: string;\n private cacheFile: string;\n\n constructor(cacheName: string) {\n this.cacheDir = path.join(os.homedir(), '.code-helper', 'cache');\n this.cacheFile = path.join(this.cacheDir, `${cacheName}.json`);\n this.ensureCacheDir();\n }\n\n /**\n * 加载缓存\n */\n load<T>(): { data: T; timestamp: number } | null {\n try {\n if (!fs.existsSync(this.cacheFile)) {\n return null;\n }\n\n const content = fs.readFileSync(this.cacheFile, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n return null;\n }\n }\n\n /**\n * 保存缓存\n */\n save(data: any): void {\n const cacheData = {\n data,\n timestamp: Date.now(),\n };\n fs.writeFileSync(this.cacheFile, JSON.stringify(cacheData, null, 2));\n }\n\n /**\n * 检查缓存是否过期\n */\n isExpired(ttl: number): boolean {\n try {\n if (!fs.existsSync(this.cacheFile)) {\n return true;\n }\n\n const content = fs.readFileSync(this.cacheFile, 'utf-8');\n const { timestamp } = JSON.parse(content);\n return Date.now() - timestamp > ttl;\n } catch (error) {\n return true;\n }\n }\n\n /**\n * 清除缓存\n */\n clear(): void {\n if (fs.existsSync(this.cacheFile)) {\n fs.unlinkSync(this.cacheFile);\n }\n }\n\n /**\n * 确保缓存目录存在\n */\n private ensureCacheDir(): void {\n if (!fs.existsSync(this.cacheDir)) {\n fs.mkdirSync(this.cacheDir, { recursive: true });\n }\n }\n}\n","/**\n * 插件市场菜单\n */\nimport { execSync } from 'child_process';\nimport fs from 'fs';\nimport inquirer from 'inquirer';\nimport ora from 'ora';\nimport os from 'os';\nimport path from 'path';\nimport { MarketplaceService } from '../services/marketplace';\nimport type { Market } from '../types/marketplace';\nimport {\n createBoxTitle,\n showHeader,\n showInfo,\n showWarning,\n theme,\n} from '../ui';\n\n/**\n * 执行 Claude 命令\n */\nfunction execClaude(command: string): string {\n try {\n return execSync(`claude ${command}`, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n } catch (error: any) {\n throw new Error(`执行命令失败: ${error.message}\\n${error.stderr || ''}`);\n }\n}\n\n/**\n * 市场插件信息接口\n */\ninterface MarketplacePlugin {\n id: string;\n name: string;\n description: string;\n marketplace: string;\n category?: string;\n recommended?: boolean;\n version?: string;\n installedVersion?: string;\n hasUpdate?: boolean;\n}\n\n/**\n * 已安装插件信息\n */\ninterface InstalledPlugin {\n name: string; // 格式:pluginId@marketplace\n version: string;\n enabled: boolean;\n}\n\n/**\n * 插件状态\n */\ntype PluginStatus = 'not_installed' | 'enabled' | 'disabled';\n\n// 市场服务实例\nconst marketplaceService = new MarketplaceService();\n\n/**\n * 获取已安装的插件列表\n */\nfunction getInstalledPlugins(): InstalledPlugin[] {\n try {\n const output = execClaude('plugin list');\n const plugins: InstalledPlugin[] = [];\n const lines = output.split('\\n');\n let currentPlugin: Partial<InstalledPlugin> = {};\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.startsWith('❯ ')) {\n if (currentPlugin.name) {\n plugins.push(currentPlugin as InstalledPlugin);\n }\n currentPlugin = { name: trimmed.substring(2).trim() };\n } else if (trimmed.startsWith('Version:')) {\n currentPlugin.version = trimmed.substring(8).trim();\n } else if (trimmed.startsWith('Status:')) {\n currentPlugin.enabled = trimmed.includes('enabled');\n }\n }\n\n if (currentPlugin.name) {\n plugins.push(currentPlugin as InstalledPlugin);\n }\n\n return plugins;\n } catch (error) {\n return [];\n }\n}\n\n/**\n * 获取插件状态\n */\nfunction getPluginStatus(\n pluginFullName: string,\n installedPlugins: InstalledPlugin[],\n): PluginStatus {\n const installed = installedPlugins.find((p) => p.name === pluginFullName);\n if (!installed) return 'not_installed';\n return installed.enabled ? 'enabled' : 'disabled';\n}\n\n/**\n * 获取状态显示文本\n */\nfunction getStatusText(status: PluginStatus): string {\n switch (status) {\n case 'not_installed':\n return theme.dim('[未安装]');\n case 'enabled':\n return theme.success('[已启用]');\n case 'disabled':\n return theme.warning('[已禁用]');\n }\n}\n\n/**\n * 确保默认市场已添加\n */\nasync function ensureDefaultMarkets(markets: Market[]): Promise<void> {\n for (const market of markets) {\n if (market.default) {\n const isInstalled = await marketplaceService.isMarketInstalled(\n market.source,\n market.name,\n );\n if (!isInstalled) {\n try {\n await marketplaceService.addMarket(market);\n } catch (error) {\n // 静默忽略错误\n }\n }\n }\n }\n}\n\n/**\n * 显示插件市场主菜单 - 市场选择\n */\nexport async function showPluginsMenu(): Promise<void> {\n // 加载市场列表\n const spinner = ora('正在加载插件市场...').start();\n const markets = await marketplaceService.fetchMarkets();\n\n // 确保默认市场已添加\n await ensureDefaultMarkets(markets);\n\n // 获取已安装的市场\n const installedMarkets = await marketplaceService.getInstalledMarkets();\n\n spinner.stop();\n\n while (true) {\n showHeader();\n console.log(createBoxTitle('插件市场'));\n console.log();\n console.log(theme.primary('📦 可用市场:'));\n console.log();\n console.log(theme.dim('↑↓ 选择 | Enter 确认'));\n console.log();\n\n // 构建市场选项列表\n const marketChoices = markets.map((market) => {\n // 通过源地址或名称匹配已安装的市场\n const isInstalled = installedMarkets.some((m) => {\n // 源地址匹配\n if (m.source) {\n const normalizedSource = market.source.replace(/\\.git$/, '');\n const normalizedInstalled = m.source.replace(/\\.git$/, '');\n if (normalizedInstalled === normalizedSource) {\n return true;\n }\n if (normalizedInstalled.includes(market.name)) {\n return true;\n }\n }\n // 名称匹配(处理 -dev 后缀)\n const baseMarketName = market.name.replace(/-dev$/, '');\n const baseInstalledName = m.name.replace(/-dev$/, '');\n return baseMarketName === baseInstalledName;\n });\n const statusIcon = isInstalled ? theme.success('✓') : theme.dim('•');\n const categoryLabel = getCategoryLabel(market.category);\n\n return {\n name: ` ${statusIcon} [${categoryLabel}] ${market.name} - ${theme.dim(\n market.description,\n )}`,\n value: { type: 'market', market },\n };\n });\n\n const choices = [\n ...marketChoices,\n new inquirer.Separator(),\n {\n name: ` ${theme.info('🔄')} 刷新市场列表`,\n value: { type: 'refresh' },\n },\n {\n name: ` ${theme.info('⬆️')} 更新所有市场`,\n value: { type: 'update_all_markets' },\n },\n new inquirer.Separator(),\n {\n name: ` ${theme.dim('<-')} 返回`,\n value: { type: 'back' },\n },\n {\n name: ` ${theme.dim('X')} 退出`,\n value: { type: 'exit' },\n },\n ];\n\n const { selection } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selection',\n message: '请选择市场:',\n pageSize: 15,\n choices,\n },\n ]);\n\n if (selection.type === 'back') {\n return;\n }\n\n if (selection.type === 'exit') {\n process.exit(0);\n }\n\n if (selection.type === 'refresh') {\n const refreshSpinner = ora('正在刷新市场列表...').start();\n const newMarkets = await marketplaceService.refreshMarkets();\n markets.length = 0;\n markets.push(...newMarkets);\n refreshSpinner.succeed('市场列表已刷新');\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), 800);\n });\n continue;\n }\n\n if (selection.type === 'update_all_markets') {\n const updateSpinner = ora('正在更新所有市场...').start();\n try {\n await marketplaceService.updateAllMarkets();\n updateSpinner.succeed('所有市场已更新');\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), 1000);\n });\n } catch (error: any) {\n updateSpinner.fail(`更新失败: ${error.message}`);\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), 1500);\n });\n }\n continue;\n }\n\n if (selection.type === 'market') {\n await showMarketPlugins(selection.market);\n }\n }\n}\n\n/**\n * 获取分类标签\n */\nfunction getCategoryLabel(category: string): string {\n switch (category) {\n case 'official':\n return theme.success('官方');\n case 'team':\n return theme.info('团队');\n case 'experimental':\n return theme.warning('实验');\n default:\n return theme.dim('其他');\n }\n}\n\n/**\n * 显示市场的插件列表\n */\nasync function showMarketPlugins(market: Market): Promise<void> {\n // 确保市场已添加(通过源地址和名称双重匹配)\n const isInstalled = await marketplaceService.isMarketInstalled(\n market.source,\n market.name,\n );\n if (!isInstalled) {\n const addSpinner = ora('正在添加市场...').start();\n try {\n await marketplaceService.addMarket(market);\n addSpinner.succeed('市场添加成功');\n } catch (error: any) {\n addSpinner.fail(`市场添加失败: ${error.message}`);\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), 2000);\n });\n return;\n }\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), 800);\n });\n }\n\n // 获取市场在 Claude CLI 中的实际名称\n const installedMarketName = await marketplaceService.getInstalledMarketName(\n market.source,\n market.name,\n );\n if (!installedMarketName) {\n showWarning('无法找到已安装的市场');\n return;\n }\n\n // 加载插件列表(使用实际的市场名称)\n const loadingSpinner = ora('正在加载插件列表...').start();\n const marketplacePlugins = await marketplaceService.getMarketPlugins(\n installedMarketName,\n );\n let installedPlugins = getInstalledPlugins();\n loadingSpinner.stop();\n\n while (true) {\n showHeader();\n console.log(createBoxTitle(`${market.name} 插件市场`));\n console.log();\n console.log(`${theme.dim('描述:')} ${market.description}`);\n console.log(`${theme.dim('源地址:')} ${market.source}`);\n console.log();\n console.log(theme.primary('📦 可用插件:'));\n console.log();\n console.log(theme.dim('↑↓ 选择 | Enter 确认'));\n console.log();\n\n // 构建插件选项列表\n const pluginStatuses = new Map<string, PluginStatus>();\n for (const p of marketplacePlugins) {\n const pluginFullName = `${p.id}@${p.marketplace}`;\n pluginStatuses.set(\n pluginFullName,\n getPluginStatus(pluginFullName, installedPlugins),\n );\n }\n\n const pluginChoices = marketplacePlugins.map((p) => {\n const pluginFullName = `${p.id}@${p.marketplace}`;\n const status = pluginStatuses.get(pluginFullName)!;\n const statusText = getStatusText(status);\n const updateBadge = p.hasUpdate ? theme.warning(' (有更新)') : '';\n return {\n name: ` ${statusText} ${p.name}${updateBadge} - ${theme.dim(\n p.description,\n )}`,\n value: { type: 'plugin', plugin: p, status },\n };\n });\n\n // 检查是否有可更新的插件\n const hasUpdatablePlugins = marketplacePlugins.some(\n (p) =>\n p.hasUpdate &&\n pluginStatuses.get(`${p.id}@${p.marketplace}`) !== 'not_installed',\n );\n\n const choices = [\n ...pluginChoices,\n new inquirer.Separator(),\n {\n name: ` ${theme.success('⚡')} 一键安装全部`,\n value: { type: 'install_all' },\n },\n ...(hasUpdatablePlugins\n ? [\n {\n name: ` ${theme.info('⬆️')} 更新所有已安装插件`,\n value: { type: 'update_all_plugins' },\n },\n ]\n : []),\n {\n name: ` ${theme.info('🔄')} 更新此市场`,\n value: { type: 'update_market' },\n },\n new inquirer.Separator(),\n {\n name: ` ${theme.dim('<-')} 返回`,\n value: { type: 'back' },\n },\n {\n name: ` ${theme.dim('X')} 退出`,\n value: { type: 'exit' },\n },\n ];\n\n const { selection } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selection',\n message: '请选择插件:',\n pageSize: 15,\n choices,\n },\n ]);\n\n if (selection.type === 'back') {\n return;\n }\n\n if (selection.type === 'exit') {\n process.exit(0);\n }\n\n if (selection.type === 'install_all') {\n await handleInstallAll(marketplacePlugins);\n // 刷新插件状态\n installedPlugins = getInstalledPlugins();\n continue;\n }\n\n if (selection.type === 'update_all_plugins') {\n const updateSpinner = ora('正在更新所有已安装的插件...').start();\n try {\n const pluginsToUpdate = marketplacePlugins.filter(\n (p) =>\n p.hasUpdate &&\n pluginStatuses.get(`${p.id}@${p.marketplace}`) !== 'not_installed',\n );\n for (const plugin of pluginsToUpdate) {\n const pluginFullName = `${plugin.id}@${plugin.marketplace}`;\n updateSpinner.text = `正在更新 ${plugin.name}...`;\n await marketplaceService.updatePlugin(pluginFullName);\n }\n updateSpinner.succeed('所有插件已更新');\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), 1000);\n });\n // 刷新插件列表和状态\n installedPlugins = getInstalledPlugins();\n } catch (error: any) {\n updateSpinner.fail(`更新失败: ${error.message}`);\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), 1500);\n });\n }\n continue;\n }\n\n if (selection.type === 'update_market') {\n const updateSpinner = ora(`正在更新市场 ${market.name}...`).start();\n try {\n await marketplaceService.updateMarket(installedMarketName);\n updateSpinner.succeed('市场已更新');\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), 1000);\n });\n // 刷新插件列表\n const updatedPlugins = await marketplaceService.getMarketPlugins(\n installedMarketName,\n );\n marketplacePlugins.length = 0;\n marketplacePlugins.push(...updatedPlugins);\n installedPlugins = getInstalledPlugins();\n } catch (error: any) {\n updateSpinner.fail(`更新失败: ${error.message}`);\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), 1500);\n });\n }\n continue;\n }\n\n if (selection.type === 'plugin') {\n await showPluginDetail(selection.plugin, selection.status);\n // 操作后刷新插件状态\n installedPlugins = getInstalledPlugins();\n }\n }\n}\n\n/**\n * 显示插件详情页\n */\nasync function showPluginDetail(\n plugin: MarketplacePlugin,\n initialStatus: PluginStatus,\n): Promise<void> {\n const pluginFullName = `${plugin.id}@${plugin.marketplace}`;\n let needRefresh = true; // 首次进入需要刷新状态\n let currentStatus = initialStatus;\n\n while (true) {\n showHeader();\n console.log(createBoxTitle(`插件详情:${plugin.id}`));\n console.log();\n\n // 显示插件信息\n console.log(` ${theme.primary('名称:')} ${plugin.name}`);\n console.log(\n ` ${theme.primary('分类:')} ${theme.info(\n plugin.category || 'development',\n )}`,\n );\n console.log(` ${theme.primary('描述:')} ${plugin.description}`);\n console.log();\n\n // 获取最新状态(只在需要时刷新)\n if (needRefresh) {\n const spinner = ora('正在获取插件状态...').start();\n const installedPlugins = getInstalledPlugins();\n currentStatus = getPluginStatus(pluginFullName, installedPlugins);\n spinner.stop();\n needRefresh = false;\n }\n const status = currentStatus;\n\n // 显示状态\n if (status === 'not_installed') {\n console.log(` ${theme.primary('状态:')} ${theme.dim('[未安装]')}`);\n } else {\n console.log(` ${theme.primary('状态:')} ${theme.success('[已安装]')}`);\n if (plugin.installedVersion) {\n console.log(\n ` ${theme.primary('当前版本:')} ${plugin.installedVersion}`,\n );\n }\n if (plugin.version) {\n console.log(` ${theme.primary('市场版本:')} ${plugin.version}`);\n }\n if (plugin.hasUpdate) {\n console.log(` ${theme.warning('⬆️ 有新版本可用')}`);\n }\n console.log(\n ` ${theme.primary('启用状态:')} ${\n status === 'enabled'\n ? theme.success('[已启用]')\n : theme.warning('[已禁用]')\n }`,\n );\n }\n\n console.log();\n console.log(theme.dim('↑↓ 选择 | Enter 确认'));\n console.log();\n\n // 根据状态构建操作选项\n let actionChoices: any[] = [];\n\n if (status === 'not_installed') {\n actionChoices = [\n {\n name: ` ${theme.success('>')} 安装插件`,\n value: 'install',\n },\n ];\n } else if (status === 'enabled') {\n actionChoices = [\n ...(plugin.hasUpdate\n ? [\n {\n name: ` ${theme.info('⬆️')} 更新插件`,\n value: 'update',\n },\n ]\n : []),\n {\n name: ` ${theme.warning('>')} 禁用插件`,\n value: 'disable',\n },\n {\n name: ` ${theme.error('*')} 卸载插件`,\n value: 'uninstall',\n },\n ];\n } else if (status === 'disabled') {\n actionChoices = [\n ...(plugin.hasUpdate\n ? [\n {\n name: ` ${theme.info('⬆️')} 更新插件`,\n value: 'update',\n },\n ]\n : []),\n {\n name: ` ${theme.success('>')} 启用插件`,\n value: 'enable',\n },\n {\n name: ` ${theme.error('*')} 卸载插件`,\n value: 'uninstall',\n },\n ];\n }\n\n const choices = [\n ...actionChoices,\n new inquirer.Separator(),\n {\n name: ` ${theme.dim('<-')} 返回`,\n value: 'back',\n },\n {\n name: ` ${theme.dim('X')} 退出`,\n value: 'exit',\n },\n ];\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: '请选择操作:',\n pageSize: 10,\n choices,\n },\n ]);\n\n if (action === 'back') {\n return;\n }\n\n if (action === 'exit') {\n process.exit(0);\n }\n\n // 执行操作\n await executePluginAction(action, plugin, pluginFullName);\n // 操作后需要刷新状态\n needRefresh = true;\n }\n}\n\n/**\n * 执行插件操作\n */\nasync function executePluginAction(\n action: string,\n plugin: MarketplacePlugin,\n pluginFullName: string,\n): Promise<void> {\n const spinner = ora();\n\n try {\n switch (action) {\n case 'install':\n console.log();\n console.log(`$ claude plugin install ${pluginFullName}`);\n spinner.start(`${theme.success('+')} 正在安装插件...`);\n execClaude(`plugin install ${pluginFullName}`);\n spinner.succeed(`${theme.success('+')} 插件安装成功`);\n break;\n\n case 'enable':\n console.log();\n console.log(`$ claude plugin enable ${pluginFullName}`);\n spinner.start(`${theme.success('+')} 正在启用插件...`);\n execClaude(`plugin enable ${pluginFullName}`);\n spinner.succeed(`${theme.success('+')} 插件已启用`);\n break;\n\n case 'disable':\n console.log();\n console.log(`$ claude plugin disable ${pluginFullName}`);\n spinner.start(`${theme.warning('*')} 正在禁用插件...`);\n execClaude(`plugin disable ${pluginFullName}`);\n spinner.succeed(`${theme.warning('*')} 插件已禁用`);\n break;\n\n case 'update':\n console.log();\n console.log(`$ claude plugin update ${pluginFullName}`);\n spinner.start(`${theme.info('⬆️')} 正在更新插件...`);\n await marketplaceService.updatePlugin(pluginFullName);\n spinner.succeed(`${theme.success('⬆️')} 插件已更新`);\n break;\n\n case 'uninstall': {\n console.log();\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `确定要卸载插件 \"${plugin.name}\" 吗?`,\n default: false,\n },\n ]);\n if (confirm) {\n console.log(`$ claude plugin uninstall ${pluginFullName}`);\n spinner.start(`${theme.error('-')} 正在卸载插件...`);\n\n // 尝试不同的 scope\n let uninstalled = false;\n const scopes = ['user', 'project', 'local'];\n\n for (const scope of scopes) {\n try {\n execClaude(`plugin uninstall ${pluginFullName} --scope ${scope}`);\n uninstalled = true;\n break;\n } catch (e: any) {\n // 如果是 scope 不匹配的错误,继续尝试下一个\n if (!e.message.includes('scope')) {\n throw e;\n }\n }\n }\n\n if (uninstalled) {\n spinner.succeed(`${theme.error('-')} 插件已卸载`);\n } else {\n spinner.fail('CLI 卸载失败');\n console.log();\n showWarning('Claude CLI 无法卸载此插件(已知 bug)');\n\n // 提供手动清理选项\n const { manualClean } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'manualClean',\n message: '是否手动清理配置文件来完成卸载?',\n default: true,\n },\n ]);\n\n if (manualClean) {\n try {\n const settingsPath = path.join(\n os.homedir(),\n '.claude',\n 'settings.json',\n );\n const settings = JSON.parse(\n fs.readFileSync(settingsPath, 'utf-8'),\n );\n\n // 移除 enabledPlugins 中的相关条目\n if (settings.enabledPlugins) {\n const keysToRemove = Object.keys(\n settings.enabledPlugins,\n ).filter((key) => key.startsWith(`${plugin.id}@`));\n for (const key of keysToRemove) {\n delete settings.enabledPlugins[key];\n }\n }\n\n fs.writeFileSync(\n settingsPath,\n JSON.stringify(settings, null, 2),\n );\n console.log(theme.success('✓ 已从配置中移除插件'));\n showInfo('重启 Claude Code 后生效');\n } catch (e) {\n showWarning('手动清理失败,请手动编辑 ~/.claude/settings.json');\n }\n } else {\n showInfo('建议:使用\"禁用插件\"来停用此插件');\n }\n }\n }\n break;\n }\n }\n } catch (error: any) {\n spinner.fail(`操作失败: ${error.message}`);\n }\n\n // 短暂停留让用户看到结果\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), 800);\n });\n}\n\n/**\n * 一键安装全部推荐插件\n */\nasync function handleInstallAll(\n marketplacePlugins: MarketplacePlugin[],\n): Promise<void> {\n console.log();\n\n const recommendedPlugins = marketplacePlugins.filter((p) => p.recommended);\n\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `确定要安装全部 ${recommendedPlugins.length} 个推荐插件吗?`,\n default: true,\n },\n ]);\n\n if (!confirm) return;\n\n const spinner = ora('正在安装插件...').start();\n\n try {\n for (const plugin of recommendedPlugins) {\n const pluginFullName = `${plugin.id}@${plugin.marketplace}`;\n spinner.text = `正在安装 ${plugin.name}...`;\n\n const installedPlugins = getInstalledPlugins();\n const installed = installedPlugins.find((p) => p.name === pluginFullName);\n\n if (installed) {\n if (!installed.enabled) {\n execClaude(`plugin enable ${pluginFullName}`);\n }\n } else {\n execClaude(`plugin install ${pluginFullName}`);\n }\n }\n\n spinner.succeed(`成功安装 ${recommendedPlugins.length} 个推荐插件`);\n console.log();\n showInfo('插件已生效,无需重启 Claude Code');\n } catch (error) {\n spinner.fail(`安装失败: ${(error as Error).message}`);\n }\n\n console.log();\n await inquirer.prompt([\n { type: 'input', name: 'continue', message: '按回车键继续...' },\n ]);\n}\n","/**\n * 市场服务\n */\nimport { execSync } from 'child_process';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport {\n BUILTIN_DEFAULT_MARKETS,\n CACHE_TTL,\n MARKETS_CONFIG_FILE,\n} from '../config/constants';\nimport type {\n InstalledMarket,\n Market,\n MarketRegistry,\n MarketplacePlugin,\n} from '../types/marketplace';\nimport { showWarning } from '../ui';\nimport { CacheManager } from '../utils/cache';\n\nexport class MarketplaceService {\n private cacheManager: CacheManager;\n\n constructor() {\n this.cacheManager = new CacheManager('markets');\n }\n\n /**\n * 获取市场列表(从本地配置文件读取)\n */\n async fetchMarkets(): Promise<Market[]> {\n try {\n // 读取本地配置文件\n if (fs.existsSync(MARKETS_CONFIG_FILE)) {\n const content = fs.readFileSync(MARKETS_CONFIG_FILE, 'utf-8');\n const data: MarketRegistry = JSON.parse(content);\n \n if (data.markets && Array.isArray(data.markets)) {\n return this.normalizeMarkets(data.markets);\n }\n }\n \n // 配置文件不存在,使用内置默认配置\n showWarning('使用内置默认市场配置');\n return BUILTIN_DEFAULT_MARKETS;\n } catch (error) {\n // 读取失败,使用内置默认配置\n showWarning('读取配置文件失败,使用内置默认市场配置');\n return BUILTIN_DEFAULT_MARKETS;\n }\n }\n\n /**\n * 标准化市场数据(移除内部字段)\n */\n private normalizeMarkets(rawMarkets: any[]): Market[] {\n return rawMarkets.map((market) => ({\n name: market.name,\n source: market.source,\n description: market.description,\n category: market.category,\n recommended: market.recommended || false,\n default: market.default || false,\n }));\n }\n\n /**\n * 获取已安装的市场列表\n */\n async getInstalledMarkets(): Promise<InstalledMarket[]> {\n try {\n const output = this.execClaude('plugin marketplace list');\n return this.parseMarketplaceList(output);\n } catch (error) {\n return [];\n }\n }\n\n /**\n * 检查市场是否已安装(通过源地址或名称匹配)\n */\n async isMarketInstalled(\n marketSource: string,\n marketName?: string,\n ): Promise<boolean> {\n const installed = await this.getInstalledMarkets();\n const normalizedSource = marketSource.replace(/\\.git$/, '');\n\n return installed.some((m) => {\n // 1. 尝试源地址匹配\n if (m.source) {\n const normalizedInstalled = m.source.replace(/\\.git$/, '');\n if (normalizedInstalled === normalizedSource) {\n return true;\n }\n // 如果源地址包含市场名称,也认为匹配\n if (marketName && normalizedInstalled.includes(marketName)) {\n return true;\n }\n }\n\n // 2. 尝试名称匹配(处理 macopowers vs macopowers-dev)\n if (marketName) {\n const baseMarketName = marketName.replace(/-dev$/, '');\n const baseInstalledName = m.name.replace(/-dev$/, '');\n if (baseMarketName === baseInstalledName) {\n return true;\n }\n }\n\n return false;\n });\n }\n\n /**\n * 根据源地址或名称获取已安装市场的名称\n */\n async getInstalledMarketName(\n marketSource: string,\n marketName?: string,\n ): Promise<string | null> {\n const installed = await this.getInstalledMarkets();\n const normalizedSource = marketSource.replace(/\\.git$/, '');\n\n const found = installed.find((m) => {\n // 1. 尝试源地址匹配\n if (m.source) {\n const normalizedInstalled = m.source.replace(/\\.git$/, '');\n if (normalizedInstalled === normalizedSource) {\n return true;\n }\n if (marketName && normalizedInstalled.includes(marketName)) {\n return true;\n }\n }\n\n // 2. 尝试名称匹配\n if (marketName) {\n const baseMarketName = marketName.replace(/-dev$/, '');\n const baseInstalledName = m.name.replace(/-dev$/, '');\n if (baseMarketName === baseInstalledName) {\n return true;\n }\n }\n\n return false;\n });\n return found ? found.name : null;\n }\n\n /**\n * 添加市场\n */\n async addMarket(market: Market): Promise<boolean> {\n try {\n this.execClaude(`plugin marketplace add \"${market.source}\"`);\n return true;\n } catch (error: any) {\n if (\n error.message.includes('already exists') ||\n error.message.includes('already configured') ||\n error.message.includes('already installed')\n ) {\n return true; // 已存在,视为成功\n }\n throw error;\n }\n }\n\n /**\n * 从市场获取插件列表(带版本和更新检测)\n */\n async getMarketPlugins(marketName: string): Promise<MarketplacePlugin[]> {\n try {\n const marketplacePath = this.getMarketplacePath(marketName);\n const manifestPath = path.join(\n marketplacePath,\n '.claude-plugin',\n 'marketplace.json',\n );\n\n if (!fs.existsSync(manifestPath)) {\n return [];\n }\n\n const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));\n\n if (!manifest.plugins || !Array.isArray(manifest.plugins)) {\n return [];\n }\n\n // 获取已安装插件的版本信息\n const installedVersions = await this.getInstalledPluginVersions();\n\n return manifest.plugins.map((plugin: any) => {\n const pluginFullId = `${plugin.name}@${marketName}`;\n const installedVersion = installedVersions.get(pluginFullId);\n const marketVersion = plugin.version || '1.0.0';\n\n return {\n id: plugin.name,\n name: plugin.name.charAt(0).toUpperCase() + plugin.name.slice(1),\n description: plugin.description,\n marketplace: marketName,\n category: plugin.category || 'development',\n recommended: true,\n version: marketVersion,\n installedVersion,\n hasUpdate: installedVersion\n ? this.compareVersions(marketVersion, installedVersion) > 0\n : false,\n };\n });\n } catch (error) {\n console.error('读取市场插件列表失败:', error);\n return [];\n }\n }\n\n /**\n * 获取已安装插件的版本信息\n */\n private async getInstalledPluginVersions(): Promise<Map<string, string>> {\n const versions = new Map<string, string>();\n try {\n const output = this.execClaude('plugin list --json');\n const data = JSON.parse(output);\n\n if (data.installed && Array.isArray(data.installed)) {\n for (const plugin of data.installed) {\n versions.set(plugin.id, plugin.version);\n }\n }\n } catch (error) {\n // 静默忽略错误\n }\n return versions;\n }\n\n /**\n * 比较版本号\n * @returns >0 如果 v1 > v2, =0 如果相等, <0 如果 v1 < v2\n */\n private compareVersions(v1: string, v2: string): number {\n const parts1 = v1.split('.').map(Number);\n const parts2 = v2.split('.').map(Number);\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const num1 = parts1[i] || 0;\n const num2 = parts2[i] || 0;\n if (num1 > num2) return 1;\n if (num1 < num2) return -1;\n }\n return 0;\n }\n\n /**\n * 刷新市场列表(清除缓存并重新获取)\n */\n async refreshMarkets(): Promise<Market[]> {\n this.cacheManager.clear();\n return this.fetchMarkets();\n }\n\n /**\n * 更新单个市场\n */\n async updateMarket(marketName: string): Promise<boolean> {\n try {\n this.execClaude(`plugin marketplace update \"${marketName}\"`);\n return true;\n } catch (error: any) {\n throw new Error(`更新市场失败: ${error.message}`);\n }\n }\n\n /**\n * 更新所有市场\n */\n async updateAllMarkets(): Promise<boolean> {\n try {\n this.execClaude('plugin marketplace update');\n return true;\n } catch (error: any) {\n throw new Error(`更新所有市场失败: ${error.message}`);\n }\n }\n\n /**\n * 更新单个插件\n */\n async updatePlugin(pluginName: string): Promise<boolean> {\n try {\n this.execClaude(`plugin update \"${pluginName}\"`);\n return true;\n } catch (error: any) {\n throw new Error(`更新插件失败: ${error.message}`);\n }\n }\n\n /**\n * 降级处理\n */\n private handleFallback(\n cached: { data: MarketRegistry; timestamp: number } | null,\n ): Market[] {\n if (cached) {\n showWarning('使用缓存的市场列表(API 暂时不可用)');\n return cached.data.markets;\n }\n\n showWarning('使用内置默认市场配置');\n return BUILTIN_DEFAULT_MARKETS;\n }\n\n /**\n * 解析 marketplace list 输出\n */\n private parseMarketplaceList(output: string): InstalledMarket[] {\n const markets: InstalledMarket[] = [];\n const lines = output.split('\\n');\n\n let currentMarket: InstalledMarket | null = null;\n for (const line of lines) {\n const trimmed = line.trim();\n\n // 匹配市场名称行(以 ❯ 开头)\n if (trimmed.startsWith('❯ ')) {\n if (currentMarket) {\n markets.push(currentMarket);\n }\n const name = trimmed.substring(2).trim();\n currentMarket = { name };\n }\n // 匹配源地址行\n else if (currentMarket && trimmed.startsWith('Source:')) {\n // 提取源地址,支持多种格式:\n // - Git (https://...)\n // - GitHub (org/repo)\n // - Directory (path)\n const match = trimmed.match(/Source:\\s+\\w+\\s+\\((.+)\\)/);\n if (match) {\n currentMarket.source = match[1];\n }\n }\n }\n\n // 添加最后一个市场\n if (currentMarket) {\n markets.push(currentMarket);\n }\n\n return markets;\n }\n\n /**\n * 获取市场仓库路径\n */\n private getMarketplacePath(marketName: string): string {\n // Claude CLI 将市场克隆到 ~/.claude/plugins/marketplaces/\n return path.join(\n os.homedir(),\n '.claude',\n 'plugins',\n 'marketplaces',\n marketName,\n );\n }\n\n /**\n * 执行 Claude 命令\n */\n private execClaude(command: string): string {\n try {\n return execSync(`claude ${command}`, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n } catch (error: any) {\n throw new Error(`执行命令失败: ${error.message}\\n${error.stderr || ''}`);\n }\n }\n}\n","/**\n * Claude Code 配置菜单\n */\nimport fs from 'fs';\nimport inquirer from 'inquirer';\nimport os from 'os';\nimport path from 'path';\nimport {\n createBoxTitle,\n showError,\n showHeader,\n showInfo,\n showSuccess,\n showWarning,\n theme,\n} from '../ui';\nimport { readClaudeSettings, writeClaudeSettings } from '../utils/config';\n\n// 配置文件路径\nconst SETTINGS_FILE = path.join(os.homedir(), '.claude', 'settings.json');\n\n/**\n * 配置菜单选项\n */\nenum SettingsChoice {\n BASIC = 'basic',\n VIEW_CONFIG = 'view_config',\n BACK = 'back',\n EXIT = 'exit',\n}\n\n/**\n * 基础设置选项\n */\nenum BasicSettingChoice {\n LANGUAGE = 'language',\n CLEANUP_DAYS = 'cleanupPeriodDays',\n PLANS_DIR = 'plansDirectory',\n SHOW_DURATION = 'showTurnDuration',\n SPINNER_TIPS = 'spinnerTipsEnabled',\n BACK = 'back',\n EXIT = 'exit',\n}\n\n/**\n * 语言选项\n */\nconst LANGUAGE_OPTIONS = [\n { name: '中文 (chinese)', value: 'chinese' },\n { name: 'English', value: 'english' },\n { name: '日本語 (japanese)', value: 'japanese' },\n { name: '한국어 (korean)', value: 'korean' },\n { name: 'Español (spanish)', value: 'spanish' },\n { name: 'Français (french)', value: 'french' },\n { name: 'Deutsch (german)', value: 'german' },\n { name: '其他(手动输入)', value: '__custom__' },\n];\n\n/**\n * 显示配置菜单\n */\nexport async function showSettingsMenu(): Promise<void> {\n while (true) {\n showHeader();\n\n console.log(createBoxTitle('Claude Code 配置'));\n console.log();\n\n const { choice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'choice',\n message: '请选择配置类别:',\n choices: [\n {\n name: `基础设置`,\n value: SettingsChoice.BASIC,\n },\n {\n name: `查看配置文件`,\n value: SettingsChoice.VIEW_CONFIG,\n },\n new inquirer.Separator(),\n {\n name: `${theme.dim('<-')} 返回`,\n value: SettingsChoice.BACK,\n },\n {\n name: `${theme.dim('X')} 退出`,\n value: SettingsChoice.EXIT,\n },\n ],\n },\n ]);\n\n switch (choice) {\n case SettingsChoice.BASIC:\n await showBasicSettings();\n break;\n case SettingsChoice.VIEW_CONFIG:\n await handleViewConfig();\n break;\n case SettingsChoice.BACK:\n return;\n case SettingsChoice.EXIT:\n process.exit(0);\n }\n }\n}\n\n/**\n * 显示基础设置\n */\nasync function showBasicSettings(): Promise<void> {\n while (true) {\n showHeader();\n\n console.log(createBoxTitle('基础设置'));\n console.log();\n\n const settings = readClaudeSettings();\n\n // 获取当前值\n const currentLanguage = settings.language || '未设置';\n const currentCleanupDays = settings.cleanupPeriodDays ?? 30;\n const currentPlansDir = settings.plansDirectory || './plans';\n const currentShowDuration = settings.showTurnDuration ?? false;\n const currentSpinnerTips = settings.spinnerTipsEnabled ?? true;\n\n const { choice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'choice',\n message: '请选择要修改的配置:',\n choices: [\n {\n name: `响应语言 ${theme.dim(`[当前: ${currentLanguage}]`)}`,\n value: BasicSettingChoice.LANGUAGE,\n },\n {\n name: `会话清理周期 ${theme.dim(\n `[当前: ${currentCleanupDays}天]`,\n )}`,\n value: BasicSettingChoice.CLEANUP_DAYS,\n },\n {\n name: `计划文件目录 ${theme.dim(`[当前: ${currentPlansDir}]`)}`,\n value: BasicSettingChoice.PLANS_DIR,\n },\n {\n name: `显示响应耗时 ${theme.dim(\n `[当前: ${currentShowDuration ? '开启' : '关闭'}]`,\n )}`,\n value: BasicSettingChoice.SHOW_DURATION,\n },\n {\n name: `显示加载提示 ${theme.dim(\n `[当前: ${currentSpinnerTips ? '开启' : '关闭'}]`,\n )}`,\n value: BasicSettingChoice.SPINNER_TIPS,\n },\n new inquirer.Separator(),\n {\n name: `${theme.dim('<-')} 返回`,\n value: BasicSettingChoice.BACK,\n },\n {\n name: `${theme.dim('X')} 退出`,\n value: BasicSettingChoice.EXIT,\n },\n ],\n },\n ]);\n\n switch (choice) {\n case BasicSettingChoice.LANGUAGE:\n await handleLanguageSetting();\n break;\n case BasicSettingChoice.CLEANUP_DAYS:\n await handleCleanupDaysSetting();\n break;\n case BasicSettingChoice.PLANS_DIR:\n await handlePlansDirSetting();\n break;\n case BasicSettingChoice.SHOW_DURATION:\n await handleBooleanSetting('showTurnDuration', '显示响应耗时');\n break;\n case BasicSettingChoice.SPINNER_TIPS:\n await handleBooleanSetting('spinnerTipsEnabled', '显示加载提示');\n break;\n case BasicSettingChoice.BACK:\n return;\n case BasicSettingChoice.EXIT:\n process.exit(0);\n }\n }\n}\n\n/**\n * 处理语言设置\n */\nasync function handleLanguageSetting(): Promise<void> {\n console.log();\n\n const { language } = await inquirer.prompt([\n {\n type: 'list',\n name: 'language',\n message: '请选择响应语言:',\n choices: LANGUAGE_OPTIONS,\n },\n ]);\n\n let finalLanguage = language;\n\n if (language === '__custom__') {\n const { customLanguage } = await inquirer.prompt([\n {\n type: 'input',\n name: 'customLanguage',\n message: '请输入语言名称(英文):',\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return '语言名称不能为空';\n }\n return true;\n },\n },\n ]);\n finalLanguage = customLanguage;\n }\n\n try {\n const settings = readClaudeSettings();\n settings.language = finalLanguage;\n writeClaudeSettings(settings);\n showSuccess(`响应语言已设置为: ${finalLanguage}`);\n } catch (error) {\n showError(`保存失败: ${(error as Error).message}`);\n }\n}\n\n/**\n * 处理会话清理周期设置\n */\nasync function handleCleanupDaysSetting(): Promise<void> {\n console.log();\n showInfo('设置为 0 表示每次启动都清理所有历史会话');\n console.log();\n\n const { days } = await inquirer.prompt([\n {\n type: 'number',\n name: 'days',\n message: '请输入会话清理周期(天):',\n default: 30,\n validate: (input: number) => {\n if (isNaN(input) || input < 0) {\n return '请输入有效的天数(>=0)';\n }\n return true;\n },\n },\n ]);\n\n try {\n const settings = readClaudeSettings();\n settings.cleanupPeriodDays = days;\n writeClaudeSettings(settings);\n showSuccess(`会话清理周期已设置为: ${days}天`);\n } catch (error) {\n showError(`保存失败: ${(error as Error).message}`);\n }\n}\n\n/**\n * 处理计划文件目录设置\n */\nasync function handlePlansDirSetting(): Promise<void> {\n console.log();\n showInfo('可使用相对路径(相对于项目根目录)或绝对路径');\n console.log();\n\n const { dir } = await inquirer.prompt([\n {\n type: 'input',\n name: 'dir',\n message: '请输入计划文件目录:',\n default: './plans',\n },\n ]);\n\n try {\n const settings = readClaudeSettings();\n settings.plansDirectory = dir;\n writeClaudeSettings(settings);\n showSuccess(`计划文件目录已设置为: ${dir}`);\n } catch (error) {\n showError(`保存失败: ${(error as Error).message}`);\n }\n}\n\n/**\n * 处理布尔值设置\n */\nasync function handleBooleanSetting(key: string, label: string): Promise<void> {\n console.log();\n\n const settings = readClaudeSettings();\n const currentValue = (settings as any)[key] ?? key === 'spinnerTipsEnabled';\n\n const { value } = await inquirer.prompt([\n {\n type: 'list',\n name: 'value',\n message: `${label}:`,\n choices: [\n { name: '开启', value: true },\n { name: '关闭', value: false },\n ],\n default: currentValue,\n },\n ]);\n\n try {\n (settings as any)[key] = value;\n writeClaudeSettings(settings);\n showSuccess(`${label}已${value ? '开启' : '关闭'}`);\n } catch (error) {\n showError(`保存失败: ${(error as Error).message}`);\n }\n}\n\n/**\n * 查看配置文件\n */\nasync function handleViewConfig(): Promise<void> {\n console.log();\n console.log(theme.primary(`配置文件路径: ${SETTINGS_FILE}`));\n console.log();\n\n try {\n if (fs.existsSync(SETTINGS_FILE)) {\n const content = fs.readFileSync(SETTINGS_FILE, 'utf-8');\n console.log(theme.dim('─'.repeat(50)));\n console.log(content);\n console.log(theme.dim('─'.repeat(50)));\n } else {\n showWarning('配置文件不存在');\n }\n } catch (error) {\n showError(`读取失败: ${(error as Error).message}`);\n }\n\n console.log();\n await inquirer.prompt([\n { type: 'input', name: 'continue', message: '按回车键继续...' },\n ]);\n}\n","/**\n * Code Helper CLI Main Program\n */\nimport { showMainMenu } from './menus/main';\nimport { showHeader } from './ui';\nimport { checkAndUpdate } from './utils/version';\n\n// 读取版本号\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst pkg = require('../../package.json');\n\nasync function main() {\n try {\n // 处理命令行参数\n const args = process.argv.slice(2);\n\n // 显示版本\n if (args.includes('--version') || args.includes('-v')) {\n console.log(`v${pkg.version}`);\n process.exit(0);\n }\n\n // 测试更新功能\n if (args.includes('--test-update')) {\n const { testUpdate } = require('./utils/version');\n await testUpdate();\n process.exit(0);\n }\n\n // 启动 Web UI\n if (args.includes('ui')) {\n const { launchWebUI } = require('./utils/webui');\n await launchWebUI();\n process.exit(0);\n }\n\n // 显示帮助\n if (args.includes('--help') || args.includes('-h')) {\n console.log(`\nCode Helper v${pkg.version}\nA unified tool to manage your Claude Code\n\nUsage:\n code-helper Launch interactive menu\n code-helper ui Launch Web UI interface\n code-helper --version Show version number\n code-helper --help Show help information\n code-helper --test-update Test version update functionality\n\n You can also use these command aliases:\n - ch\n - maco\n\nOptions:\n -v, --version Show version number\n -h, --help Show help information\n --test-update Test version update functionality\n ui Launch Web UI interface\n\nInstallation:\n Recommended global installation for better experience:\n npm install -g code-helper\n\n Global installation will automatically check for updates\n\nWeb UI Launch:\n 1. code-helper ui Launch via code-helper command\n 2. npx @siteboon/claude-code-ui Launch UI directly\n`);\n process.exit(0);\n }\n\n // 检查版本更新并自动更新\n await checkAndUpdate();\n\n // 显示头部\n showHeader();\n\n // 显示主菜单\n await showMainMenu();\n } catch (error) {\n if ((error as any)?.message === 'User force closed the prompt') {\n // 用户按 Ctrl+C 退出\n console.log('\\n再见!');\n process.exit(0);\n }\n console.error('发生错误:', error);\n process.exit(1);\n }\n}\n\nmain();\n"],"mappings":"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","names":["chalk","inquirer","chalk","ora","pkg","fs","os","path","inquirer","fs","os","path","path","os","fs","fs","inquirer","ora","execSync","inquirer","ora","os","execSync","method","inquirer","spinner","ora","fs","inquirer","ora","os","path","inquirer","ora","path","os","fs","ora","inquirer","inquirer","ora","fs","os","path","path","fs","os","path","path","os","fs","inquirer","execSync","fs","inquirer","ora","os","path","execSync","fs","os","path","fs","path","os","execSync","execSync","ora","inquirer","path","os","fs","fs","inquirer","os","path","SETTINGS_FILE","path","os","inquirer","SETTINGS_FILE","fs","inquirer","launchWebUI","pkg","testUpdate","launchWebUI"]}
@@ -0,0 +1,3 @@
1
+ declare function getFoo(): string;
2
+
3
+ export { getFoo };
@@ -0,0 +1,3 @@
1
+ declare function getFoo(): string;
2
+
3
+ export { getFoo };