UNPKG

cc-code-status

Version:

Enhanced Claude Code launcher with statusline - supports multiple custom API configurations and code statistics

514 lines 20 kB
#!/usr/bin/env node "use strict"; /** * CLI 主入口 * v2.0.0 - 增强版 Claude Code 启动器 + 状态栏插件 */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.main = main; const chalk_1 = __importDefault(require("chalk")); const inquirer_1 = __importDefault(require("inquirer")); const extended_manager_1 = require("./config/extended-manager"); const extended_launcher_1 = require("./launcher/extended-launcher"); const prompts_1 = require("./ui/prompts"); const welcome_1 = require("./ui/welcome"); const ccgo_1 = require("ccgo"); const logger_1 = require("./utils/logger"); const packageJson = require('../package.json'); // 解析命令行参数 const args = process.argv.slice(2); const command = args[0]; // 主函数 async function main() { try { // ========== 版本和帮助 ========== if (args.includes('-v') || args.includes('--version')) { console.log('CC Code Status v' + packageJson.version); return; } if (command === 'help' || command === '--help' || command === '-h') { (0, welcome_1.showHelp)(); return; } // ========== 配置命令 ========== if (command === 'config') { await handleConfigCommand(args.slice(1)); return; } // ========== 统计命令 ========== if (command === 'stats' || command === 'week') { await handleStatsCommand(args); return; } // ========== 同步命令 ========== if (command === 'sync-enable' || command === 'sync-disable' || command === 'sync-status' || command === 'sync-now' || command === 'sync' || command === 'custom-sync') { await handleSyncCommand(args); return; } // ========== 排除命令 ========== if (command === 'exclude') { await handleExcludeCommand(args.slice(1)); return; } // ========== 旧版命令(向后兼容)========== if (command === 'setup' || command === 'install') { await handleSetup(); return; } if (command === 'uninstall') { await handleUninstall(); return; } // ========== 状态栏模式 ========== // 检测是否为状态栏模式(通过 stdin 调用) if (command === '--statusline' || !process.stdin.isTTY) { await runAsStatusLine(); return; } // ========== 默认:启动器模式 ========== await runAsLauncher(args); } catch (error) { logger_1.Logger.error('程序执行失败: ' + error.message); if (process.env.DEBUG) { console.error(error); } process.exit(1); } } /** * 处理 config 命令 */ async function handleConfigCommand(subArgs) { const config = new extended_manager_1.ExtendedConfigManager(); const subCommand = subArgs[0]; // config list - 列出所有配置 if (subCommand === 'list') { const profiles = config.getAllProfiles(); if (profiles.length === 0) { logger_1.Logger.warning('当前没有配置'); logger_1.Logger.info('运行 ccs config add 添加配置'); return; } console.log(chalk_1.default.cyan('\n📋 配置列表\n')); console.log(chalk_1.default.gray('─'.repeat(70))); profiles.forEach(p => { const safeKey = p.apiKey.length > 12 ? `${p.apiKey.substring(0, 8)}...${p.apiKey.substring(p.apiKey.length - 4)}` : '***'; // 从 baseUrl 提取域名 let domain = p.baseUrl; try { const url = new URL(p.baseUrl); domain = url.hostname; } catch (e) { // 如果不是有效 URL,使用原始值 } console.log(chalk_1.default.white.bold('● ' + p.name)); console.log(chalk_1.default.gray(` Base URL: ${p.baseUrl}`)); console.log(chalk_1.default.gray(` API Key: ${safeKey}`)); if (p.model) { console.log(chalk_1.default.gray(` Model: ${p.model}`)); } if (p.smallFastModel) { console.log(chalk_1.default.gray(` Small Fast Model: ${p.smallFastModel}`)); } console.log(''); }); console.log(chalk_1.default.gray('─'.repeat(70))); console.log(chalk_1.default.gray(`\n配置文件: ${config.getConfigPath()}\n`)); return; } // config add - 添加新配置 if (subCommand === 'add') { (0, welcome_1.showWelcome)(); const answers = await (0, prompts_1.showConfigPrompts)(); // 检查配置是否已存在 if (config.hasProfile(answers.name)) { const { confirm } = await inquirer_1.default.prompt([ { type: 'confirm', name: 'confirm', message: chalk_1.default.yellow(`配置 "${answers.name}" 已存在,是否覆盖?`), default: false } ]); if (!confirm) { logger_1.Logger.info('已取消'); return; } } config.saveProfile(answers.name, { apiKey: answers.apiKey, baseUrl: answers.baseUrl, model: answers.model, smallFastModel: answers.smallFastModel }); logger_1.Logger.success(`配置 "${answers.name}" 已保存`); console.log(''); return; } // config remove <name> - 删除配置 if (subCommand === 'remove' || subCommand === 'rm') { const name = subArgs[1]; if (!name) { logger_1.Logger.error('请指定要删除的配置名称'); console.log(''); console.log('用法: ccs config remove <配置名称>'); console.log(''); return; } if (!config.hasProfile(name)) { logger_1.Logger.error(`配置 "${name}" 不存在`); console.log(''); console.log('使用 ccs config list 查看所有配置'); console.log(''); return; } const { confirm } = await inquirer_1.default.prompt([ { type: 'confirm', name: 'confirm', message: chalk_1.default.yellow(`确定要删除配置 "${name}" 吗?`), default: false } ]); if (!confirm) { logger_1.Logger.info('已取消'); return; } config.removeProfile(name); logger_1.Logger.success(`配置 "${name}" 已删除`); console.log(''); return; } // config show / config --show - 显示配置(单个配置时显示详情,多个配置时显示列表) if (subCommand === 'show' || subArgs.includes('--show')) { const profiles = config.getAllProfiles(); if (profiles.length === 0) { logger_1.Logger.warning('当前没有配置'); logger_1.Logger.info('运行 ccs config add 添加配置'); return; } // 如果只有一个配置,显示详情 if (profiles.length === 1) { const current = profiles[0]; const safeKey = current.apiKey.length > 12 ? `${current.apiKey.substring(0, 8)}...${current.apiKey.substring(current.apiKey.length - 4)}` : '***'; console.log(chalk_1.default.cyan('\n📝 当前配置')); console.log(chalk_1.default.gray('─'.repeat(70))); console.log(chalk_1.default.white('配置名称: ') + chalk_1.default.green(current.name)); console.log(chalk_1.default.white('Base URL: ') + chalk_1.default.cyan(current.baseUrl)); console.log(chalk_1.default.white('API Key: ') + chalk_1.default.yellow(safeKey)); if (current.model) { console.log(chalk_1.default.white('Model: ') + chalk_1.default.gray(current.model)); } if (current.smallFastModel) { console.log(chalk_1.default.white('Small Fast Model: ') + chalk_1.default.gray(current.smallFastModel)); } console.log(chalk_1.default.white('配置时间: ') + chalk_1.default.gray(new Date(current.configuredAt).toLocaleString('zh-CN'))); console.log(chalk_1.default.gray('─'.repeat(70))); console.log(chalk_1.default.gray(`配置文件: ${config.getConfigPath()}\n`)); } else { // 多个配置时,显示提示 logger_1.Logger.info(`当前有 ${profiles.length} 个配置,启动时将提示选择`); console.log(''); console.log('使用 ccs config list 查看所有配置'); console.log(''); } return; } // config --reset - 重置所有配置 if (subArgs.includes('--reset')) { if (!config.hasAnyProfile()) { logger_1.Logger.warning('当前没有配置'); return; } const { confirm } = await inquirer_1.default.prompt([ { type: 'confirm', name: 'confirm', message: chalk_1.default.red('⚠️ 确定要删除所有配置吗?此操作不可恢复!'), default: false } ]); if (!confirm) { logger_1.Logger.info('已取消'); return; } config.reset(); logger_1.Logger.success('所有配置已重置'); logger_1.Logger.info('下次运行 ccs 时将重新配置'); console.log(''); return; } // config (无子命令) - 显示帮助或添加第一个配置 if (!subCommand) { if (!config.hasAnyProfile()) { // 如果没有配置,引导添加第一个配置 (0, welcome_1.showWelcome)(); const answers = await (0, prompts_1.showConfigPrompts)('default'); config.saveProfile(answers.name, { apiKey: answers.apiKey, baseUrl: answers.baseUrl, model: answers.model, smallFastModel: answers.smallFastModel }); (0, welcome_1.showConfigSuccess)(); console.log(''); } else { // 如果已有配置,显示配置管理帮助 console.log(chalk_1.default.cyan('\n⚙️ 配置管理\n')); console.log('可用命令:'); console.log(''); console.log(chalk_1.default.white(' ccs config list ') + chalk_1.default.gray('列出所有配置')); console.log(chalk_1.default.white(' ccs config add ') + chalk_1.default.gray('添加新配置')); console.log(chalk_1.default.white(' ccs config remove <名称> ') + chalk_1.default.gray('删除指定配置')); console.log(chalk_1.default.white(' ccs config show ') + chalk_1.default.gray('显示当前配置')); console.log(chalk_1.default.white(' ccs config --reset ') + chalk_1.default.gray('重置所有配置')); console.log(''); } return; } // 未知子命令 logger_1.Logger.error(`未知的子命令: ${subCommand}`); console.log(''); console.log('运行 ccs config 查看帮助'); console.log(''); } /** * 处理统计命令 */ async function handleStatsCommand(args) { const subCommand = args[0] === 'stats' ? args[1] : args[0]; if (subCommand === 'week' || args[0] === 'week') { // 引入旧版的 showWeekStats 函数 const { showWeekStats } = await Promise.resolve().then(() => __importStar(require('./cli-legacy'))); showWeekStats(); } else if (subCommand === 'today') { // 显示今日统计 const { StatusLinePlugin } = await Promise.resolve().then(() => __importStar(require('./index'))); const plugin = new StatusLinePlugin(); const stats = await plugin.getTodayStats(); console.log(''); console.log(chalk_1.default.cyan('📊 今日统计')); console.log(''); console.log(`对话: ${stats.conversations}次/${stats.rounds}轮`); console.log(`代码: +${stats.codeAdded}/-${stats.codeDeleted} 行`); console.log(''); } else { logger_1.Logger.error('未知的统计命令'); console.log(''); console.log('可用命令:'); console.log(' ccs stats today 显示今日统计'); console.log(' ccs stats week 显示本周统计'); console.log(''); } } /** * 处理同步命令 */ async function handleSyncCommand(args) { const command = args[0]; // 引入旧版的同步函数 const { setSyncEnabled, showSyncStatus, manualSync, customSync } = await Promise.resolve().then(() => __importStar(require('./cli-legacy'))); if (command === 'sync-enable') { setSyncEnabled(true); } else if (command === 'sync-disable') { setSyncEnabled(false); } else if (command === 'sync-status') { showSyncStatus(); } else if (command === 'sync-now' || command === 'sync') { await manualSync(); } else if (command === 'custom-sync') { await customSync(); } } /** * 处理排除命令 */ async function handleExcludeCommand(subArgs) { const { handleExclude } = await Promise.resolve().then(() => __importStar(require('./cli-legacy'))); handleExclude(subArgs); } /** * 处理 setup 命令(旧版兼容) */ async function handleSetup() { const { setup } = await Promise.resolve().then(() => __importStar(require('./cli-legacy'))); setup(); } /** * 处理 uninstall 命令(旧版兼容) */ async function handleUninstall() { const { uninstall } = await Promise.resolve().then(() => __importStar(require('./cli-legacy'))); uninstall(); } /** * 作为状态栏插件运行 */ async function runAsStatusLine() { const { StatusLinePlugin } = await Promise.resolve().then(() => __importStar(require('./index'))); const plugin = new StatusLinePlugin(); await plugin.run().catch(() => { console.log('Error'); }); } /** * 作为启动器运行 */ async function runAsLauncher(args) { const config = new extended_manager_1.ExtendedConfigManager(); // 检查是否有配置 if (!config.hasAnyProfile()) { console.log(''); logger_1.Logger.info('首次使用需要配置 API'); console.log(''); // 显示欢迎信息 (0, welcome_1.showWelcome)(); // 交互式配置 const answers = await (0, prompts_1.showConfigPrompts)('default'); // 保存配置 config.saveProfile(answers.name, { apiKey: answers.apiKey, baseUrl: answers.baseUrl, model: answers.model, smallFastModel: answers.smallFastModel }); // 显示成功信息 (0, welcome_1.showConfigSuccess)(); // 短暂延迟 await new Promise(resolve => setTimeout(resolve, 1000)); } // 如果有配置,检查是否需要选择配置 let selectedProfileName; if (config.hasAnyProfile()) { // 如果有多个配置,需要用户选择 const profileCount = config.getProfileCount(); // 检查命令行参数中是否指定了配置 const profileArgIndex = args.findIndex(arg => arg === '--profile' || arg === '-p'); if (profileArgIndex !== -1 && args[profileArgIndex + 1]) { // 通过命令行参数指定配置 selectedProfileName = args[profileArgIndex + 1]; if (!config.hasProfile(selectedProfileName)) { logger_1.Logger.error(`配置 "${selectedProfileName}" 不存在`); console.log(''); console.log('使用 ccs config list 查看所有配置'); console.log(''); process.exit(1); } // 移除 --profile 参数(避免传递给 Claude) args.splice(profileArgIndex, 2); } else if (profileCount > 1) { // 如果有多个配置,让用户选择 const profiles = config.getAllProfiles().map(p => ({ name: p.name, config: p })); console.log(''); logger_1.Logger.info('检测到多个配置,请选择要使用的配置'); console.log(''); selectedProfileName = await (0, prompts_1.selectProfile)(profiles); console.log(''); logger_1.Logger.success(`已选择配置: ${selectedProfileName}`); console.log(''); // 短暂延迟 await new Promise(resolve => setTimeout(resolve, 500)); } } // 检查 Claude Code 是否已安装 if (!(0, ccgo_1.checkClaudeInstallation)()) { process.exit(1); } // 显示当前使用的配置 let displayProfile; if (selectedProfileName) { // 使用选中的配置 const profile = config.getProfile(selectedProfileName); if (profile) { displayProfile = { name: selectedProfileName, baseUrl: profile.baseUrl }; } } else { // 使用唯一配置 const current = config.getCurrentProfile(); if (current) { displayProfile = { name: current.name, baseUrl: current.config.baseUrl }; } } if (displayProfile) { // 从 baseUrl 提取域名 let domain = displayProfile.baseUrl; try { const url = new URL(displayProfile.baseUrl); domain = url.hostname; } catch (e) { // 如果不是有效 URL,使用原始值 } console.log(chalk_1.default.gray(`使用配置: ${displayProfile.name} (${domain})\n`)); } // 启动 Claude Code const launcher = new extended_launcher_1.ExtendedClaudeLauncher(config, selectedProfileName); const { exitCode } = await launcher.launch({ args, skipPermissions: true, showStats: true }); process.exit(exitCode); } // 运行主函数 if (require.main === module) { main(); } //# sourceMappingURL=cli.js.map