UNPKG

openai-cli-unofficial

Version:

A powerful OpenAI CLI Coding Agent built with TypeScript

330 lines 13.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WelcomeScreen = void 0; const prompts_1 = require("@inquirer/prompts"); const chalk_1 = __importDefault(require("chalk")); const figlet_1 = __importDefault(require("figlet")); const language_1 = require("../../services/language"); const storage_1 = require("../../services/storage"); const update_checker_1 = require("../../services/update-checker"); const animation_1 = require("../../utils/animation"); const menu_1 = require("../components/menu"); const config_1 = require("../pages/config"); const help_1 = require("../pages/help"); const main_1 = require("../pages/main"); const packageJson = require('../../../package.json'); class WelcomeScreen { constructor() { this.gradients = animation_1.AnimationUtils.getGradients(); } /** * 从 package.json 读取版本信息 */ getVersion() { try { return packageJson.version || '0.0.0'; } catch (error) { console.debug('Failed to read version from package.json:', error); return '0.0.0'; } } async show() { await this.showSplashScreen(); // 在显示主菜单前进行更新检查 await this.checkForUpdates(); await this.showMainMenu(); } /** * 检查更新并提示用户 */ async checkForUpdates() { try { const updateInfo = await update_checker_1.updateChecker.checkForUpdates(); if (updateInfo.hasUpdate) { const shouldUpdate = await update_checker_1.updateChecker.showUpdatePrompt(updateInfo); if (shouldUpdate) { await update_checker_1.updateChecker.performUpdate(); // 显示按键继续提示 const messages = language_1.languageService.getMessages(); await (0, prompts_1.input)({ message: ' ' + chalk_1.default.gray(messages.welcome.actions.pressEnter) }); } } } catch (error) { // 静默处理更新检查错误,不影响正常启动 console.debug('Update check failed:', error); } } async showSplashScreen() { // 隐藏光标减少闪烁 process.stdout.write('\x1B[?25l'); animation_1.AnimationUtils.forceClearScreen(); // 显示加载动画 await this.showLoadingAnimation(); // 显示大标题 this.showGrandTitle(); // 显示副标题和描述 this.showDescription(); // 显示装饰性分割线 this.showDivider(); // 恢复光标 process.stdout.write('\x1B[?25h'); } async showLoadingAnimation() { const messages = language_1.languageService.getMessages(); // 使用统一的动画工具 const controller = animation_1.AnimationUtils.showLoadingAnimation({ text: messages.welcome.starting, interval: 80 }); await new Promise(resolve => setTimeout(resolve, 100)); controller.stop(); } showGrandTitle() { // 创建更大气的标题 const title1 = figlet_1.default.textSync('OPENAI', { font: 'ANSI Shadow', horizontalLayout: 'default', verticalLayout: 'default', width: 120, whitespaceBreak: true }); const title2 = figlet_1.default.textSync('CLI AGENT', { font: 'ANSI Shadow', horizontalLayout: 'default', verticalLayout: 'default', width: 120, whitespaceBreak: true }); // 使用多层渐变效果 console.log(this.gradients.primary(title1)); console.log(this.gradients.accent(title2)); console.log(); // 添加版本信息和徽章 const versionBadge = ` [ v${this.getVersion()} ] `; const statusBadge = ' [ BETA ] '; const aiBadge = ' [ AI-POWERED ] '; console.log(' ' + chalk_1.default.bgBlue.white.bold(versionBadge) + ' ' + chalk_1.default.bgGreen.white.bold(statusBadge) + ' ' + chalk_1.default.bgMagenta.white.bold(aiBadge)); console.log(); } showDescription() { const messages = language_1.languageService.getMessages(); // 主标题和副标题 console.log(' ' + this.gradients.primary(messages.welcome.tagline)); console.log(' ' + this.gradients.accent('Github: https://github.com/MayDay-wpf/openai-cli')); console.log(); } showDivider() { console.log(' ' + chalk_1.default.gray('─'.repeat(60))); console.log(); } async showMainMenu() { const messages = language_1.languageService.getMessages(); const choices = [ { name: messages.welcome.menuOptions.start, value: 'start', description: messages.welcome.menuDescription.start }, { name: messages.welcome.menuOptions.config, value: 'config', description: messages.welcome.menuDescription.config }, { name: messages.welcome.menuOptions.language, value: 'language', description: messages.welcome.menuDescription.language }, { name: messages.welcome.menuOptions.help, value: 'help', description: messages.welcome.menuDescription.help }, { name: messages.welcome.menuOptions.exit, value: 'exit', description: messages.welcome.menuDescription.exit } ]; const action = await menu_1.InteractiveMenu.show({ message: messages.welcome.menuPrompt + ':', choices }); await this.handleMenuSelection(action); } async handleMenuSelection(action) { const messages = language_1.languageService.getMessages(); console.log(); switch (action) { case 'start': try { // 检查配置是否完整 const configValidation = storage_1.StorageService.validateApiConfig(); if (!configValidation.isValid) { // 显示配置不完整的警告 const shouldGoToConfig = await this.showConfigWarning(configValidation.missing); if (shouldGoToConfig) { // 用户选择配置,跳转到配置页面 const configPage = new config_1.ConfigPage(); await configPage.show(); // 配置完成后确保终端状态重置 await this.ensureTerminalReset(); // 重新显示欢迎页面 await this.show(); } else { // 用户选择返回主菜单,清屏并重新显示整个欢迎页面 await this.show(); } return; } // 配置完整,启动主页面 const mainPage = new main_1.MainPage(); await mainPage.show(); // 确保MainPage实例被正确清理 mainPage.destroy(); // 对话页面结束后,直接重新显示欢迎页面,不需要等待用户按键 await this.show(); } catch (error) { console.error(' ' + chalk_1.default.red('对话页面出现错误:'), error); // 出错时也重新显示欢迎页面 await this.show(); } return; case 'config': const configPage = new config_1.ConfigPage(); await configPage.show(); // 配置页面完成后,确保终端状态完全重置 await this.ensureTerminalReset(); // 重新显示完整的欢迎页 await this.show(); return; case 'language': await this.handleLanguageSelection(); return; // 直接返回,语言切换后会重新显示界面 case 'help': const helpPage = new help_1.HelpPage(); await helpPage.show(); // 帮助页面结束后,等待用户按键继续 console.log(); await (0, prompts_1.input)({ message: ' ' + chalk_1.default.gray(messages.welcome.actions.pressEnter) }); // 强制清屏后重新显示完整的欢迎页面 process.stdout.write('\x1B[2J\x1B[3J\x1B[H'); console.clear(); process.stdout.write('\x1Bc'); await this.show(); break; case 'exit': await this.showExitAnimation(); return; default: console.log(' ' + chalk_1.default.red(messages.welcome.actions.unknownAction)); await this.showMainMenu(); } } async handleLanguageSelection() { const choices = language_1.languageService.createLanguageMenuChoices(); const selectedLanguage = await menu_1.InteractiveMenu.show({ message: 'Select Language / 选择语言:', choices }); const currentLanguage = language_1.languageService.getCurrentLanguage(); if (selectedLanguage !== currentLanguage) { language_1.languageService.setLanguage(selectedLanguage); const messages = language_1.languageService.getMessages(); await animation_1.AnimationUtils.showActionAnimation(messages.welcome.actions.changingLanguage); // 重新显示整个界面 await this.show(); } else { await this.showMainMenu(); } } async showExitAnimation() { console.log('\n'.repeat(5)); const messages = language_1.languageService.getMessages(); // 显示告别消息 const farewell = figlet_1.default.textSync('GOODBYE', { font: 'ANSI Shadow', horizontalLayout: 'default', verticalLayout: 'default', width: 80 }); await animation_1.AnimationUtils.showExitAnimation(farewell, messages.welcome.actions.farewell); process.exit(0); } async showConfigWarning(missingItems) { const messages = language_1.languageService.getMessages(); const configCheck = messages.welcome.configCheck; // 显示配置警告 console.log(); console.log(' ' + chalk_1.default.yellow.bold(configCheck.incompleteConfig)); console.log(); console.log(' ' + chalk_1.default.gray(configCheck.missingItems)); // 显示缺少的配置项 missingItems.forEach(item => { let itemName = ''; switch (item) { case 'baseUrl': itemName = configCheck.baseUrl; break; case 'apiKey': itemName = configCheck.apiKey; break; case 'model': itemName = configCheck.model; break; } console.log(' ' + chalk_1.default.red(itemName)); }); console.log(); // 显示选择菜单 - 只允许前往配置或返回主菜单 const choices = [ { name: configCheck.goToConfig, value: 'config', description: messages.welcome.menuDescription.config }, { name: configCheck.backToMenu, value: 'back', description: messages.welcome.menuDescription.backToMenu } ]; const choice = await menu_1.InteractiveMenu.show({ message: ' ' + configCheck.prompt, choices }); return choice === 'config'; } /** * 确保终端状态完全重置,防止外部编辑器等工具影响后续交互 */ async ensureTerminalReset() { // 恢复光标显示 process.stdout.write('\x1B[?25h'); // 确保stdin处于正确状态 if (process.stdin.isTTY) { process.stdin.setRawMode(false); process.stdin.pause(); // 短暂延迟确保状态重置完成 await new Promise(resolve => setTimeout(resolve, 100)); process.stdin.resume(); } } } exports.WelcomeScreen = WelcomeScreen; //# sourceMappingURL=welcome.js.map