void-cmd
Version:
AI-powered CLI tool that converts natural language to shell commands using Cerebras API
214 lines ⢠8.8 kB
JavaScript
;
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