UNPKG

claude-key-manager

Version:

🚀 Claude Key Manager 4.1.3 - 修复密钥验证问题,支持更多密钥格式

337 lines (299 loc) 10.1 kB
const inquirer = require('inquirer'); const chalk = require('chalk'); const KeyManager = require('./key-manager'); class InlineMenu { constructor(keyManager) { this.keyManager = keyManager; this.options = [ { key: '1', name: '📝 添加新的API密钥', description: '添加Claude API密钥到安全存储', action: 'add' }, { key: '2', name: '📋 列出所有密钥', description: '显示已保存的所有密钥信息', action: 'list' }, { key: '3', name: '🔄 切换当前密钥', description: '切换到不同的API密钥', action: 'switch' }, { key: '4', name: '🗑️ 删除密钥', description: '安全删除指定的密钥', action: 'delete' }, { key: '5', name: '👁️ 查看当前密钥', description: '显示当前活跃密钥信息', action: 'current' }, { key: '6', name: '📋 版本信息', description: '检查版本和更新', action: 'version' }, { key: '7', name: '🔄 检查更新', description: '检查并更新到最新版本', action: 'update' }, { key: '8', name: '❓ 帮助信息', description: '显示详细使用帮助', action: 'help' } ]; } /** * 显示内联选项菜单 (你要的功能!) */ async showInlineOptions() { console.log(chalk.blue('\n💡 Claude Key Manager - 快速命令')); console.log(chalk.gray('─'.repeat(50))); // 显示选项 this.options.forEach(option => { console.log(`${chalk.yellow(option.key)}. ${option.name}`); console.log(` ${chalk.gray(option.description)}`); }); console.log(chalk.gray('─'.repeat(50))); console.log(chalk.blue('输入数字选择操作,按 Esc 或 Ctrl+C 退出')); // 监听单个按键输入 return new Promise((resolve) => { process.stdin.setRawMode(true); process.stdin.resume(); process.stdin.setEncoding('utf8'); const handleKeypress = (key) => { // ESC键 (ASCII 27) if (key === '\u001b') { process.stdin.setRawMode(false); process.stdin.removeListener('data', handleKeypress); console.log(chalk.gray('\n已退出命令选择')); resolve(null); return; } // Ctrl+C if (key === '\u0003') { process.stdin.setRawMode(false); process.stdin.removeListener('data', handleKeypress); console.log(chalk.gray('\n已退出')); process.exit(0); } // 数字键选择 const choice = parseInt(key); if (choice >= 1 && choice <= this.options.length) { process.stdin.setRawMode(false); process.stdin.removeListener('data', handleKeypress); const selectedOption = this.options[choice - 1]; console.log(chalk.green(`\n✅ 已选择: ${selectedOption.name}`)); console.log(''); // 空行分隔 resolve(selectedOption.action); } else { // 无效输入,显示提示但不退出 process.stdout.write(`\r${chalk.red('请输入 1-' + this.options.length + ' 或按 Esc 退出')}`); setTimeout(() => { process.stdout.write('\r' + ' '.repeat(30) + '\r'); }, 1500); } }; process.stdin.on('data', handleKeypress); }); } /** * 执行选中的操作 */ async executeAction(action) { if (!action) return; try { switch (action) { case 'add': await this.handleAdd(); break; case 'list': await this.handleList(); break; case 'switch': await this.handleSwitch(); break; case 'delete': await this.handleDelete(); break; case 'current': await this.handleCurrent(); break; case 'version': await this.handleVersion(); break; case 'update': await this.handleUpdate(); break; case 'help': await this.handleHelp(); break; default: console.log(chalk.yellow('未知操作')); } } catch (error) { console.log(chalk.red('❌ 错误:'), error.message); } } async handleAdd() { console.log(chalk.blue('📝 添加新的API密钥\n')); const answers = await inquirer.prompt([ { type: 'input', name: 'key', message: '请输入Claude API密钥:', validate: (input) => { try { this.keyManager.validateKey(input); return true; } catch (error) { return error.message; } } }, { type: 'input', name: 'name', message: '为此密钥设置名称:', default: 'default', validate: (input) => input.trim() ? true : '名称不能为空' }, { type: 'input', name: 'description', message: '密钥描述 (可选):', default: '' }, { type: 'input', name: 'apiUrl', message: 'API Base URL (按回车使用默认):', default: 'https://api.anthropic.com', validate: (input) => { if (!input.trim()) return true; try { new URL(input.trim()); return true; } catch { return '请输入有效的URL格式'; } } } ]); await this.keyManager.addKey( answers.key.trim(), answers.name.trim(), answers.description.trim(), answers.apiUrl.trim() ); console.log(chalk.green('✅ 密钥添加成功!')); } async handleList() { console.log(chalk.blue('📋 已保存的密钥\n')); const keys = await this.keyManager.listKeys(true); if (keys.length === 0) { console.log(chalk.yellow('⚠️ 没有找到任何密钥')); return; } keys.forEach(k => { const status = k.active ? chalk.green('👉 [当前]') : ' '; const name = chalk.bold(k.name); const desc = k.description ? chalk.gray(` - ${k.description}`) : ''; const apiUrl = chalk.blue(`\n API: ${k.apiUrl}`); const created = chalk.gray(`\n 创建: ${new Date(k.createdAt).toLocaleString()}`); const preview = k.preview ? chalk.gray(`\n 预览: ${k.preview}`) : ''; console.log(`${status} ${name}${desc}${apiUrl}${created}${preview}\n`); }); } async handleSwitch() { console.log(chalk.blue('🔄 切换当前使用的密钥\n')); const keys = await this.keyManager.listKeys(); if (keys.length === 0) { console.log(chalk.yellow('⚠️ 没有可用的密钥')); return; } const choices = keys.map(k => ({ name: `${k.name}${k.description ? ` - ${k.description}` : ''}${k.active ? chalk.green(' (当前)') : ''}`, value: k.name, disabled: k.active ? '已经是当前密钥' : false })); const { selectedKey } = await inquirer.prompt([{ type: 'list', name: 'selectedKey', message: '选择要切换到的密钥:', choices: choices }]); await this.keyManager.switchKey(selectedKey); console.log(chalk.green(`✅ 已切换到密钥: ${selectedKey}`)); } async handleDelete() { console.log(chalk.blue('🗑️ 删除密钥\n')); const keys = await this.keyManager.listKeys(); if (keys.length === 0) { console.log(chalk.yellow('⚠️ 没有可删除的密钥')); return; } const choices = keys.map(k => ({ name: `${k.name}${k.description ? ` - ${k.description}` : ''}${k.active ? chalk.red(' (当前使用中!)') : ''}`, value: k.name })); const { keyToDelete } = await inquirer.prompt([{ type: 'list', name: 'keyToDelete', message: '选择要删除的密钥:', choices: choices }]); await this.keyManager.deleteKey(keyToDelete); } async handleCurrent() { console.log(chalk.blue('👁️ 当前密钥详情\n')); const current = await this.keyManager.getCurrentKey(); if (!current) { console.log(chalk.yellow('⚠️ 没有设置当前密钥')); return; } console.log(`🔑 名称: ${chalk.bold(current.name)}`); console.log(`📝 描述: ${current.description || chalk.gray('无')}`); console.log(`🌐 API URL: ${chalk.blue(current.apiUrl || 'https://api.anthropic.com')}`); console.log(`🔍 预览: ${current.preview}`); console.log(`⏰ 完整密钥长度: ${current.key.length} 字符`); } async handleVersion() { const VersionManager = require('./version-manager'); const versionManager = new VersionManager(); await versionManager.showVersionInfo(); } async handleUpdate() { const VersionManager = require('./version-manager'); const versionManager = new VersionManager(); await versionManager.updateHelper(); } async handleHelp() { console.log(chalk.blue('❓ Claude Key Manager 帮助\n')); console.log(`${chalk.bold('基本命令:')}`); console.log(` claude-key add <key> 添加新密钥`); console.log(` claude-key list 列出所有密钥`); console.log(` claude-key switch <name> 切换密钥`); console.log(` claude-key delete <name> 删除密钥`); console.log(` claude-key current 显示当前密钥`); console.log(` claude-key version 显示版本信息`); console.log(` claude-key update 更新到最新版本`); console.log(''); console.log(`${chalk.bold('快速操作:')}`); console.log(` 输入 claude-key 然后按 "/" 打开此命令面板`); console.log(` 或直接运行 claude-key interactive`); } } module.exports = InlineMenu;