UNPKG

cortexweaver

Version:

CortexWeaver is a command-line interface (CLI) tool that orchestrates a swarm of specialized AI agents, powered by Claude Code and Gemini CLI, to assist in software development. It transforms a high-level project plan (plan.md) into a series of coordinate

242 lines 11.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CodeSavant = void 0; /** * CodeSavant - A Gemini-powered helper agent that provides alternative solutions * and root cause analysis when the Coder agent gets stuck. */ class CodeSavant { constructor() { this.maxSuggestionLength = 150; this.maxAnalysisLength = 500; } /** * Analyzes a problem by examining failed code and error messages * @param problemDescription - Original task description * @param failedCode - Code that failed to work * @param errorMessage - Error message or failure reason * @returns Analysis of the problem */ async analyzeProblem(problemDescription, failedCode, errorMessage) { if (!problemDescription && !failedCode && !errorMessage) { return 'Insufficient information provided for analysis.'; } // Sanitize inputs const sanitizedCode = this.sanitizeInput(failedCode); const sanitizedError = this.sanitizeInput(errorMessage); // Analyze error patterns const errorPatterns = this.identifyErrorPatterns(sanitizedError); const codePatterns = this.identifyCodePatterns(sanitizedCode); let analysis = `Problem Analysis for: ${problemDescription}\n\n`; // Add error classification if (errorPatterns.isReferenceError) { analysis += 'Issue Type: Variable reference error - undefined variable or scope issue\n'; } else if (errorPatterns.isTypeError) { analysis += 'Issue Type: Type error - null/undefined access or type mismatch\n'; } else if (errorPatterns.isStackOverflow) { analysis += 'Issue Type: stack overflow - infinite recursion or deep call stack\n'; } else if (errorPatterns.isSyntaxError) { analysis += 'Issue Type: Syntax error - code structure or format issue\n'; } else if (errorPatterns.isModuleError) { analysis += 'Issue Type: Module error - missing dependency or import issue\n'; } else { analysis += 'Issue Type: Generic error - requires detailed investigation\n'; } // Add code context analysis if (codePatterns.hasRecursion) { analysis += 'Code Context: Recursive function detected\n'; } if (codePatterns.hasNullAccess) { analysis += 'Code Context: Potential null/undefined property access\n'; } if (codePatterns.hasUndefinedVariable) { analysis += 'Code Context: Undefined variable usage detected\n'; } analysis += `\nError Details: ${sanitizedError}`; return analysis.substring(0, this.maxAnalysisLength); } /** * Generates concrete alternative suggestions for the failed code * @param problemDescription - Original task description * @param failedCode - Code that failed to work * @param errorMessage - Error message or failure reason * @returns Array of 3 specific suggestions */ async generateSuggestions(problemDescription, failedCode, errorMessage) { const suggestions = []; const errorPatterns = this.identifyErrorPatterns(errorMessage); const codePatterns = this.identifyCodePatterns(failedCode); if (errorPatterns.isReferenceError) { suggestions.push('import or declare the missing variable/module at the top of the file'); suggestions.push('declare the variable in the current scope before using it'); suggestions.push('Pass the required object as a parameter'); } else if (errorPatterns.isTypeError || codePatterns.hasNullAccess) { suggestions.push('Add null check before accessing properties (if obj && obj.prop)'); suggestions.push('Use optional chaining operator (obj?.prop?.method())'); suggestions.push('Initialize variables with default values or use fallback logic'); } else if (codePatterns.hasUndefinedVariable) { suggestions.push('import or declare the missing variable/module at the top of the file'); suggestions.push('declare the variable in the current scope before using it'); suggestions.push('Pass the required object as a parameter'); } else if (errorPatterns.isStackOverflow || codePatterns.hasRecursion) { suggestions.push('Replace recursion with iterative approach using loops'); suggestions.push('Add proper base case condition to stop recursion'); suggestions.push('Use memoization to cache results and reduce recursive calls'); } else if (errorPatterns.isModuleError) { suggestions.push('Install missing dependency using npm install or yarn add'); suggestions.push('Check import path spelling and file location'); suggestions.push('Use alternative built-in library or different implementation'); } else if (errorPatterns.isSyntaxError) { suggestions.push('Check bracket/parentheses matching and proper syntax'); suggestions.push('Verify string quotes are properly escaped'); suggestions.push('Ensure proper indentation and statement termination'); } else { // Generic fallback suggestions suggestions.push('Add error handling with try-catch blocks'); suggestions.push('Validate input parameters before processing'); suggestions.push('Break down complex logic into smaller, testable functions'); } return suggestions.slice(0, 3); } /** * Identifies the root cause of the error * @param errorMessage - Error message to analyze * @param failedCode - Code that caused the error * @returns Root cause analysis */ async identifyRootCause(errorMessage, failedCode) { const errorPatterns = this.identifyErrorPatterns(errorMessage); const codePatterns = this.identifyCodePatterns(failedCode); if (errorPatterns.isReferenceError) { return 'Root cause: variable not declared in current scope or missing import statement'; } if (errorPatterns.isTypeError && codePatterns.hasNullAccess) { return 'Root cause: Attempting to access property on null/undefined object - needs validation'; } if (errorPatterns.isStackOverflow) { if (codePatterns.hasRecursion) { return 'Root cause: infinite recursion due to missing or incorrect base case condition'; } return 'Root cause: Deep call stack exceeded - consider iterative approach'; } if (errorPatterns.isModuleError) { return 'Root cause: Missing dependency or incorrect import path specification'; } if (errorPatterns.isSyntaxError) { return 'Root cause: Code syntax violation - check brackets, quotes, and structure'; } if (errorMessage.toLowerCase().includes('type')) { return 'Root cause: Type mismatch - incorrect data type usage or conversion needed'; } return 'Root cause: Complex issue requiring step-by-step debugging and analysis'; } /** * Formats suggestions into structured output for the Orchestrator * @param suggestions - Array of suggestion strings * @returns Formatted suggestion string */ formatSuggestions(suggestions) { if (suggestions.length === 0) { return 'No specific suggestions available.'; } return suggestions .map((suggestion, index) => { const truncated = suggestion.length > this.maxSuggestionLength ? suggestion.substring(0, this.maxSuggestionLength - 3) + '...' : suggestion; return `Suggestion ${index + 1}: ${truncated}`; }) .join('\n'); } /** * Sanitizes input to prevent injection and handle special characters */ sanitizeInput(input) { if (!input) return ''; return input .replace(/[\x00-\x1F\x7F]/g, '') // Remove control characters .substring(0, 1000) // Limit length .trim(); } /** * Identifies patterns in error messages */ identifyErrorPatterns(errorMessage) { const lowerError = errorMessage.toLowerCase(); return { isReferenceError: lowerError.includes('referenceerror') || lowerError.includes('is not defined'), isTypeError: lowerError.includes('typeerror') || lowerError.includes('cannot read property'), isStackOverflow: lowerError.includes('maximum call stack') || lowerError.includes('stack overflow'), isSyntaxError: lowerError.includes('syntaxerror') || lowerError.includes('unexpected token'), isModuleError: lowerError.includes('module not found') || lowerError.includes('cannot resolve') }; } /** * Identifies patterns in code structure */ identifyCodePatterns(code) { if (!code) return { hasRecursion: false, hasNullAccess: false, hasUndefinedVariable: false }; const lowerCode = code.toLowerCase(); // Simple pattern detection const functionName = this.extractFunctionName(code); const hasRecursion = functionName ? lowerCode.includes(functionName.toLowerCase()) : false; return { hasRecursion, hasNullAccess: lowerCode.includes('.') && !lowerCode.includes('?.'), hasUndefinedVariable: this.hasUndeclaredVariablePattern(code) }; } /** * Extracts function name from code for recursion detection */ extractFunctionName(code) { const functionMatch = code.match(/function\s+(\w+)/); const arrowMatch = code.match(/const\s+(\w+)\s*=/); return functionMatch?.[1] || arrowMatch?.[1] || null; } /** * Simple heuristic to detect undeclared variable usage */ hasUndeclaredVariablePattern(code) { // This is a simplified check - in real implementation would use AST const lines = code.split('\n'); const declaredVars = new Set(); for (const line of lines) { // Track variable declarations const varMatch = line.match(/(?:var|let|const)\s+(\w+)/); if (varMatch) { declaredVars.add(varMatch[1]); } // Check for function parameters const paramMatch = line.match(/function\s+\w+\s*\(([^)]*)\)/); if (paramMatch) { const params = paramMatch[1].split(',').map(p => p.trim().split(' ')[0]); params.forEach(p => declaredVars.add(p)); } } // Look for variable usage that might be undeclared for (const line of lines) { const usageMatch = line.match(/\b(\w+)\./); if (usageMatch && !declaredVars.has(usageMatch[1]) && !['console', 'window', 'document', 'process'].includes(usageMatch[1])) { return true; } } return false; } } exports.CodeSavant = CodeSavant; //# sourceMappingURL=code-savant.js.map