- Deleted the old cc.ts command and created a new cc.ts under src/command/claude for better organization. - Added support for a new model 'bailian' in the command. - Implemented remote app connection status and connection routes in assistant/src/routes/remote/index.ts. - Updated index.ts to reflect the new path for the cc command. - Added a placeholder for future management of plugin operations in src/command/opencode/plugin.ts.
150 lines
4.6 KiB
TypeScript
150 lines
4.6 KiB
TypeScript
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<Model, (token?: string) => object> = {
|
||
minimax: changeMinimax,
|
||
glm: changeGLM,
|
||
volcengine: changeVolcengine,
|
||
bailian: changeBailian,
|
||
};
|
||
|
||
const readOrCreateConfig = (configPath: string): Record<string, unknown> => {
|
||
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<string, unknown>) => {
|
||
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
||
};
|
||
|
||
export const command = new Command('cc')
|
||
.description('切换claude code模型,支持GLM4.7、Minimax和豆包')
|
||
.option('-m, --models <model:string>', `选择模型: ${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) |