import { program, Command } from '@/program.ts'; import { chalk } from '../../module/chalk.ts'; import path from 'node:path'; import { spawn } from 'node:child_process'; import { useKey } from '@kevisual/use-config'; import os from 'node:os' import fs from 'node:fs'; import { select } from '@inquirer/prompts'; const MODELS = ['minimax', 'glm', 'volcengine', 'bailian'] as const; type Model = typeof MODELS[number]; const changeMinimax = (token?: string) => { const auth_token = token || useKey("MINIMAX_API_KEY") return { "env": { "ANTHROPIC_AUTH_TOKEN": auth_token, "ANTHROPIC_BASE_URL": "https://api.minimaxi.com/anthropic", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "MiniMax-M2.1", "ANTHROPIC_DEFAULT_OPUS_MODEL": "MiniMax-M2.1", "ANTHROPIC_DEFAULT_SONNET_MODEL": "MiniMax-M2.1", "ANTHROPIC_MODEL": "MiniMax-M2.1", "API_TIMEOUT_MS": "3000000", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": 1 } } } const changeGLM = (token?: string) => { const auth_token = token || useKey('ZHIPU_API_KEY') return { "env": { "ANTHROPIC_AUTH_TOKEN": auth_token, "ANTHROPIC_BASE_URL": "https://open.bigmodel.cn/api/anthropic", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-4.7", "ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-4.7", "ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-4.7", "ANTHROPIC_MODEL": "glm-4.7" } } } const changeVolcengine = (token?: string) => { const auth_token = token || useKey('VOLCENGINE_API_KEY') return { "env": { "ANTHROPIC_AUTH_TOKEN": auth_token, "ANTHROPIC_BASE_URL": "https://ark.cn-beijing.volces.com/api/coding", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "ark-code-latest", "ANTHROPIC_DEFAULT_OPUS_MODEL": "ark-code-latest", "ANTHROPIC_DEFAULT_SONNET_MODEL": "ark-code-latest", "ANTHROPIC_MODEL": "ark-code-latest", "API_TIMEOUT_MS": "3000000" } } } const changeBailian = (token?: string) => { const auth_token = token || useKey('BAILIAN_API_KEY') return { "env": { "ANTHROPIC_AUTH_TOKEN": auth_token, "ANTHROPIC_BASE_URL": "https://coding.dashscope.aliyuncs.com/apps/anthropic", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "qwen3-coder-plus", "ANTHROPIC_DEFAULT_OPUS_MODEL": "qwen3-coder-plus", "ANTHROPIC_DEFAULT_SONNET_MODEL": "qwen3-coder-plus", "ANTHROPIC_MODEL": "qwen3-coder-plus" }, "includeCoAuthoredBy": false } } /** * 跳过登录检查,在~/.claude.json的配置中添加字段 "hasCompletedOnboarding": true */ const changeNoCheck = () => { const homeDir = os.homedir(); const claudeConfigPath = path.join(homeDir, '.claude.json'); let claudeConfig = {}; if (fs.existsSync(claudeConfigPath)) { const content = fs.readFileSync(claudeConfigPath, 'utf-8'); try { claudeConfig = JSON.parse(content); } catch { claudeConfig = {}; } } claudeConfig = { ...claudeConfig, hasCompletedOnboarding: true }; fs.writeFileSync(claudeConfigPath, JSON.stringify(claudeConfig, null, 2)); } const modelConfig: Record object> = { minimax: changeMinimax, glm: changeGLM, volcengine: changeVolcengine, bailian: changeBailian, }; const readOrCreateConfig = (configPath: string): Record => { if (fs.existsSync(configPath)) { const content = fs.readFileSync(configPath, 'utf-8'); try { return JSON.parse(content); } catch { return {}; } } return {}; }; const saveConfig = (configPath: string, config: Record) => { fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); }; export const command = new Command('cc') .description('切换claude code模型,支持GLM4.7、Minimax和豆包') .option('-m, --models ', `选择模型: ${MODELS.join(' | ')}`) .action(async (options) => { const configPath = path.join(os.homedir(), '.claude/settings.json'); // 读取或创建配置 const config = readOrCreateConfig(configPath); // 如果没有指定模型,使用 inquire 选择 let selectedModel: Model; if (options.models && MODELS.includes(options.models as Model)) { selectedModel = options.models as Model; } else { selectedModel = await select({ message: '请选择模型:', choices: MODELS, }); } // 更新配置 const updateConfig = modelConfig[selectedModel](); Object.assign(config, updateConfig); // 保存配置 saveConfig(configPath, config); changeNoCheck(); console.log(`已切换到模型: ${chalk.green(selectedModel)}`); console.log(`配置已保存到: ${configPath}`); }); program.addCommand(command)