UNPKG

faj-cli

Version:

FAJ - A powerful CLI resume builder with AI enhancement and multi-format export

345 lines 14.1 kB
"use strict"; 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.ConfigCommand = void 0; const chalk_1 = __importDefault(require("chalk")); const inquirer_1 = __importDefault(require("inquirer")); const fs = __importStar(require("fs")); const path = __importStar(require("path")); const ConfigManager_1 = require("../../core/config/ConfigManager"); const Logger_1 = require("../../utils/Logger"); class ConfigCommand { logger; configManager; constructor() { this.logger = new Logger_1.Logger('ConfigCommand'); this.configManager = ConfigManager_1.ConfigManager.getInstance(); } register(program) { const config = program .command('config') .description('Manage configuration settings'); config .command('get <key>') .description('Get configuration value') .action(async (key) => { try { const value = await this.configManager.getNested(key); if (value !== undefined) { console.log(chalk_1.default.green(`${key}: ${JSON.stringify(value, null, 2)}`)); } else { console.log(chalk_1.default.yellow(`Configuration key '${key}' not found`)); } } catch (error) { this.logger.error('Failed to get configuration', error); } }); config .command('set <key> <value>') .description('Set configuration value') .action(async (key, value) => { try { await this.configManager.setNested(key, value); console.log(chalk_1.default.green(`✓ ${key} set to: ${value}`)); } catch (error) { this.logger.error('Failed to set configuration', error); } }); config .command('list') .description('List all configuration') .action(async () => { try { await this.configManager.load(); const config = await this.configManager.get('profile'); console.log(chalk_1.default.cyan('Current configuration:')); console.log(JSON.stringify(config, null, 2)); } catch (error) { this.logger.error('Failed to list configuration', error); } }); // New command: config ai config .command('ai') .description('Configure AI settings (provider, model, language)') .option('-p, --provider <provider>', 'AI provider (gemini, openai, anthropic)') .option('-m, --model <model>', 'AI model (e.g., gemini-1.5-flash, gpt-4)') .option('-k, --api-key <key>', 'API key for the provider') .option('-l, --language <lang>', 'Resume language (zh, en, ja, etc.)') .option('--interactive', 'Interactive configuration mode') .action(async (options) => { try { if (options.interactive) { await this.configureAIInteractive(); } else { await this.configureAI(options); } } catch (error) { this.logger.error('Failed to configure AI settings', error); console.error(chalk_1.default.red('Failed to configure AI settings')); } }); // New command: config language config .command('language <lang>') .description('Set resume language (zh=中文, en=English, ja=日本語, etc.)') .action(async (lang) => { try { await this.setLanguage(lang); } catch (error) { this.logger.error('Failed to set language', error); } }); // New command: config api-key config .command('api-key') .description('Securely configure API keys') .option('-p, --provider <provider>', 'Provider name (gemini, openai, anthropic)') .action(async (options) => { try { await this.configureApiKey(options.provider); } catch (error) { this.logger.error('Failed to configure API key', error); } }); // New command: config show config .command('show') .description('Show current AI configuration') .action(async () => { try { await this.showConfiguration(); } catch (error) { this.logger.error('Failed to show configuration', error); } }); } async configureAIInteractive() { console.log(chalk_1.default.cyan('\n🤖 AI Configuration Setup\n')); const answers = await inquirer_1.default.prompt([ { type: 'list', name: 'provider', message: 'Select AI provider:', choices: [ { name: 'Google Gemini', value: 'gemini' }, { name: 'OpenAI', value: 'openai' }, { name: 'Anthropic Claude', value: 'anthropic' }, ], default: 'gemini', }, { type: 'input', name: 'model', message: 'Enter AI model (or press Enter for default):', default: (answers) => { switch (answers.provider) { case 'gemini': return 'gemini-1.5-flash'; case 'openai': return 'gpt-3.5-turbo'; case 'anthropic': return 'claude-3-sonnet'; default: return ''; } }, }, { type: 'password', name: 'apiKey', message: 'Enter API key:', mask: '*', validate: (input) => input.length > 0 || 'API key is required', }, { type: 'list', name: 'language', message: 'Select resume language:', choices: [ { name: '中文 (Chinese)', value: 'zh' }, { name: 'English', value: 'en' }, { name: '日本語 (Japanese)', value: 'ja' }, { name: '한국어 (Korean)', value: 'ko' }, { name: 'Español (Spanish)', value: 'es' }, { name: 'Français (French)', value: 'fr' }, { name: 'Deutsch (German)', value: 'de' }, ], default: 'zh', }, ]); await this.saveConfiguration(answers); } async configureAI(options) { const updates = {}; if (options.provider) { updates.provider = options.provider; console.log(chalk_1.default.green(`✓ AI provider set to: ${options.provider}`)); } if (options.model) { updates.model = options.model; console.log(chalk_1.default.green(`✓ AI model set to: ${options.model}`)); } if (options.language) { updates.language = options.language; console.log(chalk_1.default.green(`✓ Resume language set to: ${options.language}`)); } if (options.apiKey) { updates.apiKey = options.apiKey; console.log(chalk_1.default.green('✓ API key configured')); } if (Object.keys(updates).length > 0) { await this.saveConfiguration(updates); } else { console.log(chalk_1.default.yellow('No changes made. Use --interactive for guided setup.')); } } async setLanguage(lang) { const languageMap = { 'zh': '中文', 'en': 'English', 'ja': '日本語', 'ko': '한국어', 'es': 'Español', 'fr': 'Français', 'de': 'Deutsch', }; if (!languageMap[lang]) { console.log(chalk_1.default.yellow(`Unsupported language: ${lang}`)); console.log('Supported languages:', Object.keys(languageMap).join(', ')); return; } await this.updateEnvFile({ FAJ_RESUME_LANGUAGE: lang }); console.log(chalk_1.default.green(`✓ Resume language set to: ${languageMap[lang]} (${lang})`)); } async configureApiKey(provider) { if (!provider) { const answer = await inquirer_1.default.prompt({ type: 'list', name: 'provider', message: 'Select provider:', choices: ['gemini', 'openai', 'anthropic'], }); provider = answer.provider; } const answer = await inquirer_1.default.prompt({ type: 'password', name: 'apiKey', message: `Enter ${provider.toUpperCase()} API key:`, mask: '*', validate: (input) => input.length > 0 || 'API key is required', }); const envKey = `FAJ_${provider.toUpperCase()}_API_KEY`; await this.updateEnvFile({ [envKey]: answer.apiKey }); console.log(chalk_1.default.green(`✓ ${provider} API key configured`)); console.log(chalk_1.default.gray('API key saved to .env file')); } async saveConfiguration(config) { const envUpdates = {}; if (config.provider) { envUpdates.FAJ_AI_PROVIDER = config.provider; } if (config.model) { envUpdates.FAJ_AI_MODEL = config.model; } if (config.language) { envUpdates.FAJ_RESUME_LANGUAGE = config.language; } if (config.apiKey && config.provider) { const envKey = `FAJ_${config.provider.toUpperCase()}_API_KEY`; envUpdates[envKey] = config.apiKey; } await this.updateEnvFile(envUpdates); console.log(chalk_1.default.green('\n✓ Configuration saved successfully!')); console.log(chalk_1.default.gray('Settings saved to .env file')); } async updateEnvFile(updates) { const envPath = path.join(process.cwd(), '.env'); let content = ''; // Read existing .env file try { content = await fs.promises.readFile(envPath, 'utf-8'); } catch { // File doesn't exist, create new } // Update or add each key for (const [key, value] of Object.entries(updates)) { const regex = new RegExp(`^${key}=.*$`, 'gm'); if (regex.test(content)) { // Update existing content = content.replace(regex, `${key}=${value}`); } else { // Add new content += `\n${key}=${value}`; } } // Write back to file await fs.promises.writeFile(envPath, content.trim() + '\n'); } async showConfiguration() { console.log(chalk_1.default.cyan('\n📋 Current AI Configuration\n')); // Read from environment const provider = process.env.FAJ_AI_PROVIDER || 'Not set'; const model = process.env.FAJ_AI_MODEL || 'Using default'; const language = process.env.FAJ_RESUME_LANGUAGE || 'zh (default)'; // Check API keys (don't show actual keys) const geminiKey = process.env.FAJ_GEMINI_API_KEY ? '✓ Configured' : '✗ Not set'; const openaiKey = process.env.FAJ_OPENAI_API_KEY ? '✓ Configured' : '✗ Not set'; const anthropicKey = process.env.FAJ_ANTHROPIC_API_KEY ? '✓ Configured' : '✗ Not set'; console.log(chalk_1.default.white('AI Provider:'), chalk_1.default.yellow(provider)); console.log(chalk_1.default.white('AI Model:'), chalk_1.default.yellow(model)); console.log(chalk_1.default.white('Resume Language:'), chalk_1.default.yellow(language)); console.log(); console.log(chalk_1.default.white('API Keys:')); console.log(' Gemini:', geminiKey); console.log(' OpenAI:', openaiKey); console.log(' Anthropic:', anthropicKey); console.log(); console.log(chalk_1.default.gray('Use "faj config ai --interactive" to change settings')); } } exports.ConfigCommand = ConfigCommand; //# sourceMappingURL=config.js.map