claude-switcher
Version:
Cross-platform CLI tool for switching between different Claude AI model configurations. Supports automatic backup, rollback, and multi-platform configuration management for Claude API integrations.
324 lines (316 loc) • 12 kB
JavaScript
#!/usr/bin/env node
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const commander_1 = require("commander");
const chalk_1 = __importDefault(require("chalk"));
const fs_1 = require("fs");
const path_1 = require("path");
const ConfigManager_1 = require("./core/ConfigManager");
const CommandHandler_1 = require("./handlers/CommandHandler");
const ErrorHandler_1 = require("./utils/ErrorHandler");
const OutputFormatter_1 = require("./utils/OutputFormatter");
function getPackageVersion() {
try {
const packageJsonPath = (0, path_1.join)(__dirname, '..', 'package.json');
const packageJson = JSON.parse((0, fs_1.readFileSync)(packageJsonPath, 'utf8'));
return packageJson.version;
}
catch (error) {
return '1.0.4';
}
}
const program = new commander_1.Command();
let configManager;
let commandHandler;
async function initializeApp() {
try {
configManager = await ErrorHandler_1.ErrorHandler.withErrorHandling(() => ConfigManager_1.ConfigManager.createWithAutoDetection(), {
operation: '初始化配置管理器',
severity: ErrorHandler_1.ErrorSeverity.CRITICAL,
suggestions: [
'确保 Claude 已正确安装',
'检查配置目录是否存在',
'运行 Claude 至少一次以创建配置目录'
]
});
commandHandler = new CommandHandler_1.CommandHandler(configManager);
}
catch (error) {
ErrorHandler_1.ErrorHandler.displayError(error, {
operation: '应用程序初始化',
severity: ErrorHandler_1.ErrorSeverity.CRITICAL
});
process.exit(1);
}
}
program
.name('claude-switch')
.alias('cs')
.description('CLI tool for switching between different Claude model configurations')
.version(getPackageVersion())
.addHelpText('after', `
Examples:
$ cs l List all available configurations (short)
$ cs list List all available configurations (full)
$ cs s Interactive configuration switching (short)
$ cs switch Interactive configuration switching (full)
$ cs s -r Switch and reload terminal automatically
$ cs st Show current active configuration
$ cs v Verify environment consistency
$ cs r Restore from backup
$ cs ui Launch web-based configuration interface
UI Interface:
$ cs ui Start UI server on default port (3001)
$ cs ui --port 8080 Start UI server on custom port
$ cs ui --no-open Start server without opening browser
$ cs ui --host 0.0.0.0 Allow external access to UI
Alternative usage:
$ claude-switch l Same as 'cs l'
$ claude-switch s Same as 'cs s'
$ claude-switch st Same as 'cs st'
$ claude-switch ui Same as 'cs ui'
Configuration Directory:
The tool manages configurations in your Claude directory
Expected file structure:
settings.json (Active configuration)
settings_deepseek.json (DeepSeek configuration)
settings_qwen.json (Qwen configuration)
settings_glm.json (GLM configuration)
settings_*.json (Other configurations)
settings.json.backup.* (Backup files)
Documentation:
README.md Complete installation and usage guide
HELP.md Comprehensive command reference
TROUBLESHOOTING.md Common issues and solutions
CONFIG_EXAMPLES.md Configuration file examples
COMMAND_SHORTCUTS.md Quick reference for all commands
Debug Mode:
DEBUG=claude-switcher cs <command> Enable detailed debug output
For more information and examples, check the documentation files above.
`);
program
.command('list')
.aliases(['ls', 'l'])
.description('List all available Claude model configurations')
.action(async () => {
try {
if (!commandHandler) {
throw new Error('应用程序未正确初始化');
}
await commandHandler.handleListCommand();
}
catch (error) {
ErrorHandler_1.ErrorHandler.displayError(error, {
operation: '列出配置',
severity: ErrorHandler_1.ErrorSeverity.HIGH
});
process.exit(1);
}
});
program
.command('switch')
.aliases(['sw', 's'])
.description('Switch to a different Claude model configuration')
.option('-r, --reload', 'Automatically reload terminal after switching')
.action(async (options) => {
try {
if (!commandHandler) {
throw new Error('应用程序未正确初始化');
}
if (options.reload) {
await commandHandler.handleSwitchWithReload();
}
else {
await commandHandler.handleSwitchCommand();
}
}
catch (error) {
ErrorHandler_1.ErrorHandler.displayError(error, {
operation: '切换配置',
severity: ErrorHandler_1.ErrorSeverity.HIGH
});
process.exit(1);
}
});
program
.command('status')
.aliases(['st', 'stat'])
.description('Show current active Claude model configuration')
.action(async () => {
try {
if (!commandHandler) {
throw new Error('应用程序未正确初始化');
}
await commandHandler.handleStatusCommand();
}
catch (error) {
ErrorHandler_1.ErrorHandler.displayError(error, {
operation: '显示状态',
severity: ErrorHandler_1.ErrorSeverity.HIGH
});
process.exit(1);
}
});
program
.command('verify')
.aliases(['check', 'v'])
.description('Verify that environment variables match the active configuration')
.action(async () => {
try {
if (!commandHandler) {
throw new Error('应用程序未正确初始化');
}
await commandHandler.handleVerifyCommand();
}
catch (error) {
ErrorHandler_1.ErrorHandler.displayError(error, {
operation: '验证环境',
severity: ErrorHandler_1.ErrorSeverity.HIGH
});
process.exit(1);
}
});
program
.command('restore')
.aliases(['rs', 'r'])
.description('Restore Claude configuration from backup')
.action(async () => {
try {
if (!commandHandler) {
throw new Error('应用程序未正确初始化');
}
await commandHandler.handleRestoreCommand();
}
catch (error) {
ErrorHandler_1.ErrorHandler.displayError(error, {
operation: '恢复备份',
severity: ErrorHandler_1.ErrorSeverity.HIGH
});
process.exit(1);
}
});
program
.command('ui')
.aliases(['web', 'gui'])
.description('Launch web-based configuration interface')
.option('-p, --port <port>', 'Server port', '3001')
.option('--no-open', 'Do not open browser automatically')
.option('--host <host>', 'Server host', 'localhost')
.action(async (options) => {
try {
if (!configManager) {
throw new Error('应用程序未正确初始化');
}
const { UIServer } = require('./ui/UIServer');
const serverOptions = {
port: parseInt(options.port, 10),
host: options.host,
open: options.open !== false
};
console.log(OutputFormatter_1.OutputFormatter.createHeader('Claude Switcher UI', {
level: 1,
color: chalk_1.default.blue.bold
}));
console.log(chalk_1.default.gray('Starting web-based configuration interface...\n'));
const server = new UIServer(configManager, serverOptions);
await server.start();
}
catch (error) {
ErrorHandler_1.ErrorHandler.displayError(error, {
operation: '启动 UI 服务器',
severity: ErrorHandler_1.ErrorSeverity.HIGH
});
process.exit(1);
}
});
process.on('uncaughtException', (error) => {
console.error(OutputFormatter_1.OutputFormatter.createBox([
'💥 应用程序遇到未处理的异常',
'',
`错误: ${error.message}`,
'',
'这通常表示程序中存在严重错误。',
'请报告此问题并提供以下信息:'
], {
title: '严重错误',
style: 'double',
color: chalk_1.default.red
}));
if (process.env.DEBUG) {
console.error(chalk_1.default.gray('\n调试信息:'));
console.error(chalk_1.default.gray(error.stack));
}
process.exit(1);
});
process.on('unhandledRejection', (reason, promise) => {
console.error(OutputFormatter_1.OutputFormatter.createBox([
'🚫 检测到未处理的 Promise 拒绝',
'',
`原因: ${String(reason)}`,
'',
'这可能导致应用程序行为异常。',
'请检查异步操作的错误处理。'
], {
title: 'Promise 错误',
style: 'double',
color: chalk_1.default.red
}));
if (process.env.DEBUG) {
console.error(chalk_1.default.gray('\n调试信息:'));
console.error(chalk_1.default.gray('Promise:'), promise);
}
process.exit(1);
});
process.on('SIGINT', () => {
console.log(chalk_1.default.yellow('\n\n👋 正在退出...'));
process.exit(0);
});
process.on('SIGTERM', () => {
console.log(chalk_1.default.yellow('\n\n🛑 收到终止信号,正在退出...'));
process.exit(0);
});
async function main() {
try {
await initializeApp();
program.parse();
if (!process.argv.slice(2).length) {
console.log(OutputFormatter_1.OutputFormatter.createHeader('Claude Model Switcher', {
level: 1,
color: chalk_1.default.blue.bold
}));
console.log();
console.log(chalk_1.default.gray('快速切换不同的 Claude 模型配置'));
console.log();
program.outputHelp();
console.log(chalk_1.default.blue('\n💡 快速开始:'));
console.log(chalk_1.default.gray(' cs l # 查看所有配置 (简短)'));
console.log(chalk_1.default.gray(' cs s # 交互式切换配置 (简短)'));
console.log(chalk_1.default.gray(' cs st # 查看当前状态 (简短)'));
console.log(chalk_1.default.gray(' cs ui # 启动图形界面 (新功能)'));
console.log();
console.log(chalk_1.default.blue('💡 完整命令:'));
console.log(chalk_1.default.gray(' claude-switch list # 查看所有配置'));
console.log(chalk_1.default.gray(' claude-switch switch # 交互式切换配置'));
console.log(chalk_1.default.gray(' claude-switch status # 查看当前状态'));
console.log(chalk_1.default.gray(' claude-switch ui # 启动图形界面'));
console.log();
}
}
catch (error) {
ErrorHandler_1.ErrorHandler.displayError(error, {
operation: '启动应用程序',
severity: ErrorHandler_1.ErrorSeverity.CRITICAL
});
process.exit(1);
}
}
main().catch((error) => {
ErrorHandler_1.ErrorHandler.displayError(error, {
operation: '应用程序启动',
severity: ErrorHandler_1.ErrorSeverity.CRITICAL
});
process.exit(1);
});