UNPKG

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.

230 lines (229 loc) 8.62 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProgressUtils = exports.ProgressIndicator = void 0; const chalk_1 = __importDefault(require("chalk")); class ProgressIndicator { constructor(message) { this.interval = null; this.currentFrame = 0; this.isRunning = false; this.message = message; } start() { if (this.isRunning) return; this.isRunning = true; this.currentFrame = 0; process.stdout.write('\x1B[?25l'); this.interval = setInterval(() => { this.render(); this.currentFrame = (this.currentFrame + 1) % ProgressIndicator.SPINNER_FRAMES.length; }, 100); } stop(successMessage) { if (!this.isRunning) return; this.isRunning = false; if (this.interval) { clearInterval(this.interval); this.interval = null; } process.stdout.write('\r\x1B[K'); process.stdout.write('\x1B[?25h'); if (successMessage) { console.log(chalk_1.default.green('✓'), successMessage); } } stopWithError(errorMessage) { this.stop(); console.log(chalk_1.default.red('✗'), errorMessage); } updateMessage(newMessage) { this.message = newMessage; } render() { const spinner = ProgressIndicator.SPINNER_FRAMES[this.currentFrame]; const output = `${chalk_1.default.cyan(spinner)} ${this.message}`; process.stdout.write(`\r${output}`); } static createProgressBar(current, total, width = 30) { const percentage = Math.min(100, Math.max(0, (current / total) * 100)); const completed = Math.floor((percentage / 100) * width); const remaining = width - completed; const completedBar = ProgressIndicator.PROGRESS_CHARS.complete.repeat(completed); const remainingBar = ProgressIndicator.PROGRESS_CHARS.incomplete.repeat(remaining); const percentageText = `${Math.round(percentage)}%`.padStart(4); return `${chalk_1.default.green(completedBar)}${chalk_1.default.gray(remainingBar)} ${chalk_1.default.cyan(percentageText)}`; } static displayStepProgress(steps, currentStep) { console.log(chalk_1.default.blue.bold('\n进度:')); steps.forEach((step, index) => { let icon; let color; if (index < currentStep) { icon = '✓'; color = chalk_1.default.green; } else if (index === currentStep) { icon = '▶'; color = chalk_1.default.cyan; } else { icon = '○'; color = chalk_1.default.gray; } console.log(` ${color(icon)} ${color(step)}`); }); console.log(); } static async confirmWithTimeout(message, timeoutSeconds = 30) { return new Promise((resolve) => { const inquirer = require('inquirer'); let answered = false; const timeoutId = setTimeout(() => { if (!answered) { answered = true; console.log(chalk_1.default.yellow(`\n⏰ 超时 (${timeoutSeconds}秒),默认选择: 否`)); resolve(false); } }, timeoutSeconds * 1000); let remainingTime = timeoutSeconds; const countdownInterval = setInterval(() => { if (answered) { clearInterval(countdownInterval); return; } remainingTime--; if (remainingTime > 0) { process.stdout.write(`\r${message} (${remainingTime}秒后自动选择"否") `); } }, 1000); inquirer.prompt([ { type: 'confirm', name: 'confirmed', message: message, default: false } ]).then((answers) => { if (!answered) { answered = true; clearTimeout(timeoutId); clearInterval(countdownInterval); resolve(answers.confirmed); } }).catch(() => { if (!answered) { answered = true; clearTimeout(timeoutId); clearInterval(countdownInterval); resolve(false); } }); }); } static async withLoading(promise, message) { const indicator = new ProgressIndicator(message); try { indicator.start(); const result = await promise; indicator.stop(); return result; } catch (error) { indicator.stopWithError('操作失败'); throw error; } } static async withMultipleProgress(operations) { console.log(chalk_1.default.blue.bold('\n执行多个操作:\n')); const results = []; const statuses = operations.map(() => 'pending'); const updateDisplay = () => { process.stdout.write(`\x1B[${operations.length}A`); operations.forEach((op, index) => { let icon; let color; switch (statuses[index]) { case 'pending': icon = '⏳'; color = chalk_1.default.yellow; break; case 'running': icon = '🔄'; color = chalk_1.default.cyan; break; case 'completed': icon = '✅'; color = chalk_1.default.green; break; case 'failed': icon = '❌'; color = chalk_1.default.red; break; default: icon = '❓'; color = chalk_1.default.gray; } console.log(` ${icon} ${color(op.label)}`); }); }; operations.forEach(op => console.log(` ⏳ ${chalk_1.default.yellow(op.label)}`)); const promises = operations.map(async (op, index) => { try { statuses[index] = 'running'; updateDisplay(); const result = await op.promise; results[index] = result; statuses[index] = 'completed'; updateDisplay(); return result; } catch (error) { statuses[index] = 'failed'; updateDisplay(); throw error; } }); await Promise.all(promises); console.log(); return results; } } exports.ProgressIndicator = ProgressIndicator; ProgressIndicator.SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; ProgressIndicator.PROGRESS_CHARS = { complete: '█', incomplete: '░', current: '▓' }; class ProgressUtils { static showFileOperation(operation, fileName) { const message = `${operation} ${chalk_1.default.cyan(fileName)}`; const indicator = new ProgressIndicator(message); indicator.start(); return indicator; } static showConfigOperation(operation, configName) { const message = `${operation} ${chalk_1.default.cyan(configName)} 配置`; const indicator = new ProgressIndicator(message); indicator.start(); return indicator; } static displaySummary(operations, totalTime) { console.log(chalk_1.default.blue.bold('\n操作摘要:')); console.log(chalk_1.default.green(`✓ 成功完成 ${operations.length} 个操作`)); console.log(chalk_1.default.gray(`⏱️ 总耗时: ${(totalTime / 1000).toFixed(2)} 秒`)); if (operations.length > 0) { console.log(chalk_1.default.gray('\n已完成的操作:')); operations.forEach((op, index) => { console.log(chalk_1.default.gray(` ${index + 1}. ${op}`)); }); } console.log(); } } exports.ProgressUtils = ProgressUtils;