UNPKG

void-cmd

Version:

AI-powered CLI tool that converts natural language to shell commands using Cerebras API

214 lines • 8.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExplainCommand = void 0; const cerebras_1 = require("../services/cerebras"); const utils_1 = require("../utils"); const inquirer_1 = __importDefault(require("inquirer")); const child_process_1 = require("child_process"); class ExplainCommand { constructor() { this.name = 'explain'; this.description = 'Analyze and explain shell commands'; } getCerebrasService() { if (!this.cerebrasService) { this.cerebrasService = new cerebras_1.CerebrasService(); } return this.cerebrasService; } async execute(options) { try { const providedCommand = options._?.join(' '); let commandToAnalyze; if (providedCommand) { commandToAnalyze = providedCommand; } else { const answer = await inquirer_1.default.prompt([ { type: 'input', name: 'command', message: 'Enter the command you want me to analyze:', validate: (input) => { if (!input.trim()) { return 'Please enter a command to analyze'; } return true; } } ]); commandToAnalyze = answer.command.trim(); } (0, utils_1.log)(`šŸ” Analyzing command: ${commandToAnalyze}`); (0, utils_1.log)('Getting analysis from AI...'); const analysis = await this.getCerebrasService().analyzeCommand(commandToAnalyze); process.stdout.write('\x1b[1A\x1b[2K'); await this.showAnalysisMenu(commandToAnalyze, analysis); } catch (error) { if (error && typeof error === 'object' && 'isTtyError' in error) { (0, utils_1.log)('āŒ Interactive mode not available. Please provide the command as an argument:'); (0, utils_1.log)('Usage: vcmd -e "ping 1.1.1.1.1"'); return; } if (error instanceof Error && error.message.includes('API key not configured')) { (0, utils_1.log)('āŒ CEREBRAS_API_KEY not configured!'); (0, utils_1.log)('\nPlease run: vcmd -settings'); (0, utils_1.log)('This will help you set up your API key interactively.'); } else { (0, utils_1.errorHandler)(error); } } } async showAnalysisMenu(originalCommand, analysis) { console.log('\nšŸ› ļø Command Analysis & Suggestions:'); console.log('====================================\n'); console.log(`šŸ”Ž Original Command: \x1b[36m${originalCommand}\x1b[0m\n`); console.log('šŸ“‹ Analysis:'); console.log(analysis.analysis); if (analysis.explanation) { console.log('\nšŸ“š How it works:'); console.log(analysis.explanation); } console.log('\n'); const choices = []; if (analysis.suggestedFix) { choices.push({ name: `šŸ”§ Execute Suggested Fix: ${analysis.suggestedFix}`, value: { type: 'execute', command: analysis.suggestedFix } }); } if (analysis.alternatives && analysis.alternatives.length > 0) { analysis.alternatives.forEach((alt, index) => { choices.push({ name: `šŸ”„ Execute Alternative ${index + 1}: ${alt}`, value: { type: 'execute', command: alt } }); }); } choices.push({ name: 'šŸ“– Get detailed explanation', value: { type: 'explain', command: originalCommand } }); choices.push({ name: 'āŒ Exit', value: { type: 'exit' } }); try { if (analysis.suggestedFix) { console.log('šŸ’” Suggested Fix:'); console.log('\x1b[32m' + analysis.suggestedFix + '\x1b[0m\n'); } if (analysis.alternatives && analysis.alternatives.length > 0) { console.log('šŸ”„ Alternative Commands:'); analysis.alternatives.forEach((alt, index) => { console.log(`${index + 1}. \x1b[36m${alt}\x1b[0m`); }); console.log(''); } const answer = await inquirer_1.default.prompt([ { type: 'list', name: 'action', message: 'What would you like to do?', choices: choices, pageSize: Math.min(choices.length, 8) } ]); if (answer.action.type === 'execute') { await this.executeCommand(answer.action.command); } else if (answer.action.type === 'explain') { await this.getDetailedExplanation(answer.action.command); } else { (0, utils_1.log)('Analysis completed.'); } } catch (error) { if (error && typeof error === 'object' && 'isTtyError' in error) { if (analysis.suggestedFix) { console.log('šŸ’” Suggested Fix:'); console.log('\x1b[32m' + analysis.suggestedFix + '\x1b[0m'); } if (analysis.alternatives && analysis.alternatives.length > 0) { console.log('\nšŸ”„ Alternative Commands:'); analysis.alternatives.forEach((alt, index) => { console.log(`${index + 1}. \x1b[36m${alt}\x1b[0m`); }); } } else { throw error; } } } async executeCommand(command) { try { console.log('\n⚔ Executing command...\n'); console.log('\x1b[36m' + command + '\x1b[0m\n'); const childProcess = (0, child_process_1.spawn)(command, [], { stdio: ['pipe', 'pipe', 'pipe'], shell: true }); childProcess.stdout.on('data', (data) => { process.stdout.write(data.toString()); }); childProcess.stderr.on('data', (data) => { process.stderr.write('\x1b[31m' + data.toString() + '\x1b[0m'); }); childProcess.on('close', (code) => { if (code === 0) { console.log('\nāœ… Command executed successfully!'); } else { console.log(`\nāŒ Command exited with code ${code}`); } }); childProcess.on('error', (error) => { console.error('\nāŒ Command execution failed:'); console.error(error.message); }); console.log('\n\x1b[90m(Press Ctrl+C to stop the command)\x1b[0m'); const signalHandler = () => { console.log('\n\nā¹ļø Command interrupted by user'); childProcess.kill('SIGTERM'); process.exit(0); }; process.on('SIGINT', signalHandler); await new Promise((resolve) => { childProcess.on('close', () => { process.removeListener('SIGINT', signalHandler); resolve(); }); }); } catch (error) { console.error('\nāŒ Command execution failed:'); console.error(error.message); } } async getDetailedExplanation(command) { try { (0, utils_1.log)('\nšŸ“š Getting detailed explanation...'); const explanation = await this.getCerebrasService().explainCommand(command); process.stdout.write('\x1b[1A\x1b[2K'); console.log('\nšŸ“– Detailed Command Explanation:'); console.log('=================================\n'); console.log('\x1b[36m' + command + '\x1b[0m\n'); console.log(explanation); console.log('\n'); } catch (error) { process.stdout.write('\x1b[1A\x1b[2K'); (0, utils_1.log)('āŒ Failed to get detailed explanation'); (0, utils_1.errorHandler)(error); } } } exports.ExplainCommand = ExplainCommand; //# sourceMappingURL=explain.js.map