UNPKG

khodkar-cli

Version:

A TypeScript CLI application that extracts business rules and logic from codebases for customer support knowledge bases

137 lines 6.32 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.KhodkarCLI = void 0; const commander_1 = require("commander"); const chalk_1 = __importDefault(require("chalk")); const types_1 = require("../types"); const llm_processor_1 = require("../analysis/llm-processor"); const progress_tracker_1 = require("../utils/progress-tracker"); const package_json_1 = require("../../package.json"); const manager_1 = require("../mcp/manager"); const fs_1 = require("fs"); class KhodkarCLI { program; mcpManager; constructor() { this.program = new commander_1.Command(); this.mcpManager = new manager_1.McpManager(); this.setupCommands(); } setupCommands() { this.program .name('khodkar') .description('Extract business rules and logic from codebases for customer support knowledge bases') .version(package_json_1.version); this.program .command('analyze') .description('Analyze a codebase and extract business rules') .requiredOption('-d, --directory <path>', 'Target codebase directory to analyze') .requiredOption('-o, --output <path>', 'Output file path for extracted business rules') .requiredOption('--llm-base-url <url>', 'LLM API base URL (e.g., https://api.openai.com/v1, https://api.anthropic.com)') .requiredOption('--llm-api-key <key>', 'LLM API key for authentication') .requiredOption('--llm-model <model>', 'LLM model name (e.g., gpt-4, claude-3-sonnet-20240229)') .option('-f, --format <format>', 'Output format (json|markdown)', 'markdown') .option('-v, --verbose', 'Enable detailed progress logging', false) .option('--llm-max-tokens <number>', 'Maximum tokens for LLM response (1000-32000)', parseInt) .option('--llm-max-steps <number>', 'Maximum analysis steps for LLM (10-500)', parseInt) .action(async (options) => { await this.handleAnalyzeCommand(options); }); } async run(argv) { // try { await this.program.parseAsync(argv); // } catch (error) { // const message = error instanceof Error ? error.message : 'Unknown error'; // console.error(chalk.red(`Error: ${message}`)); // process.exit(1); // } } async handleAnalyzeCommand(rawOptions) { // Validate and parse options const options = this.validateOptions(rawOptions); // // Create and validate LLM configuration from CLI options const llmConfig = { baseUrl: options.llmBaseUrl, apiKey: options.llmApiKey, model: options.llmModel, maxSteps: options.llmMaxSteps || 50, }; // Validate LLM configuration try { types_1.LLMConfigSchema.parse(llmConfig); } catch (error) { const message = error instanceof Error ? error.message : 'Invalid LLM configuration'; throw new Error(`LLM Configuration Error: ${message}`); } // Initialize LLM processor with user configuration const llmProcessor = new llm_processor_1.LLMProcessor(llmConfig); const progressTracker = new progress_tracker_1.ProgressTracker({ verbose: options.verbose, showETA: true, }); // try { progressTracker.start('Initializing analysis...'); if (options.verbose) { console.log(chalk_1.default.blue('🔍 Starting business rules analysis...')); console.log(chalk_1.default.gray(`Directory: ${options.directory}`)); console.log(chalk_1.default.gray(`Output: ${options.output}`)); console.log(chalk_1.default.gray(`Format: ${options.format}`)); } // Initialize MCP servers progressTracker.updatePhase('scanning', 'Initializing MCP servers...'); await this.mcpManager.initializeServers(); // Analyze files with LLM progressTracker.updatePhase('analyzing', 'Analyzing codebase with LLM...'); const tools = await this.mcpManager.getTools(); const businessRules = await llmProcessor.analyze(tools); (0, fs_1.writeFileSync)(options.output, businessRules, { encoding: 'utf-8' }); progressTracker.succeed('Analysis complete!'); console.log(chalk_1.default.green('✅ Analysis complete!')); console.log(chalk_1.default.blue(`📄 Output saved to: ${options.output}`)); // Cleanup resources await llmProcessor.cleanup(); await this.mcpManager.shutdownServers(); // } catch (error) { // progressTracker.fail('Analysis failed'); // await this.handleError(error); // // Cleanup resources even on error // await llmProcessor.cleanup(); // await this.mcpManager.shutdownServers(); // } } validateOptions(rawOptions) { try { return types_1.CLIOptionsSchema.parse(rawOptions); } catch (error) { const message = error instanceof Error ? error.message : 'Unknown error'; throw new Error(`Invalid options: ${message}`); } } async handleError(error) { if (error instanceof types_1.LLMAnalysisError) { console.error(chalk_1.default.red(`LLM analysis error: ${error.message}`)); if (error.details?.filePath) { console.error(chalk_1.default.gray(`File: ${error.details.filePath}`)); } } else if (error instanceof types_1.MCPServerError) { console.error(chalk_1.default.red(`MCP server error: ${error.message}`)); if (error.details?.serverName) { console.error(chalk_1.default.gray(`Server: ${error.details.serverName}`)); } } else { const message = error instanceof Error ? error.message : 'Unknown error'; console.error(chalk_1.default.red(`Unexpected error: ${message}`)); } process.exit(1); } } exports.KhodkarCLI = KhodkarCLI; //# sourceMappingURL=commands.js.map