UNPKG

@claude-vector/claude-tools

Version:

Claude integration tools for AI-powered development assistance

508 lines (460 loc) 16.2 kB
/** * Error Assistant for Claude Vector Search * Analyzes errors and provides intelligent solutions * * Responsibilities: * - Parse and categorize error messages * - Search for related code patterns and solutions * - Provide actionable debugging steps * - Integrate with context management for error tracking */ import { VectorSearchEngine } from '@claude-vector/core'; export class ErrorAssistant { constructor(config = {}) { this.searchEngine = null; this.contextManager = null; this.sessionManager = null; // Error categorization patterns this.errorPatterns = { 'syntax': { patterns: [ /SyntaxError/i, /Unexpected token/i, /Missing semicolon/i, /Unterminated string/i, /Unexpected end of input/i ], severity: 'high', category: 'syntax', urgency: 'immediate' }, 'reference': { patterns: [ /ReferenceError/i, /is not defined/i, /Cannot access before initialization/i, /Undeclared variable/i ], severity: 'high', category: 'reference', urgency: 'immediate' }, 'type': { patterns: [ /TypeError/i, /Cannot read propert(y|ies) of/i, /is not a function/i, /Cannot call method/i, /null is not an object/i, /undefined is not an object/i ], severity: 'high', category: 'type', urgency: 'high' }, 'module': { patterns: [ /Module not found/i, /Cannot resolve module/i, /Error: Cannot find module/i, /ENOENT.*no such file/i, /Failed to import/i ], severity: 'medium', category: 'module', urgency: 'high' }, 'network': { patterns: [ /ECONNREFUSED/i, /ENOTFOUND/i, /ETIMEDOUT/i, /Network error/i, /Fetch failed/i, /CORS error/i ], severity: 'medium', category: 'network', urgency: 'medium' }, 'runtime': { patterns: [ /RangeError/i, /Stack overflow/i, /Out of memory/i, /Maximum call stack/i ], severity: 'high', category: 'runtime', urgency: 'high' }, 'permission': { patterns: [ /EACCES/i, /Permission denied/i, /EPERM/i, /Access denied/i ], severity: 'medium', category: 'permission', urgency: 'medium' } }; // Solution templates for common error patterns this.solutionTemplates = { 'syntax': [ 'Check for missing brackets, braces, or parentheses', 'Verify proper quotation mark matching', 'Look for trailing commas in object literals', 'Ensure proper function declaration syntax' ], 'reference': [ 'Check if the variable is declared before use', 'Verify import statements and module paths', 'Look for typos in variable names', 'Ensure proper scope and hoisting rules' ], 'type': [ 'Add null/undefined checks before property access', 'Verify the object/variable type before calling methods', 'Check for proper initialization of variables', 'Use optional chaining (?.) for safer property access' ], 'module': [ 'Check if the module is installed: npm install [module-name]', 'Verify the file path and extension', 'Check for typos in the import/require statement', 'Ensure the module exists in node_modules or is a valid relative path' ], 'network': [ 'Check network connectivity', 'Verify the URL and endpoint availability', 'Check firewall and proxy settings', 'Verify API keys and authentication' ], 'runtime': [ 'Check for infinite loops or recursive calls', 'Optimize memory usage and data structures', 'Review algorithm complexity', 'Add proper base cases for recursive functions' ], 'permission': [ 'Check file/directory permissions', 'Run with appropriate user privileges', 'Verify access to required resources', 'Check environment variables and configuration' ] }; // Debug step templates this.debugSteps = { 'syntax': [ 'Use your editor\'s syntax highlighting to spot errors', 'Run a linter (ESLint, JSHint) to identify syntax issues', 'Check the console for the exact line number of the error', 'Use a code formatter to identify mismatched brackets' ], 'reference': [ 'Check the declaration order of variables and functions', 'Use console.log to verify variable values at runtime', 'Check the import/export statements', 'Use your IDE\'s "Go to Definition" feature' ], 'type': [ 'Add console.log statements to check variable types', 'Use typeof operator to verify data types', 'Check the return values of functions', 'Use browser developer tools or Node.js debugger' ], 'module': [ 'Check if node_modules directory exists', 'Verify package.json dependencies', 'Try reinstalling node_modules: rm -rf node_modules && npm install', 'Check for case-sensitive file system issues' ], 'network': [ 'Test the endpoint with curl or Postman', 'Check browser developer tools Network tab', 'Verify environment variables for API endpoints', 'Test with different network conditions' ], 'runtime': [ 'Use profiling tools to identify performance bottlenecks', 'Add logging to trace execution flow', 'Set breakpoints to examine variable states', 'Monitor memory usage during execution' ], 'permission': [ 'Check file permissions with ls -la', 'Try running with sudo (if appropriate)', 'Verify the user has access to required directories', 'Check environment variables for paths and credentials' ] }; } /** * Set module dependencies */ setModules({ searchEngine, contextManager, sessionManager }) { this.searchEngine = searchEngine; this.contextManager = contextManager; this.sessionManager = sessionManager; } /** * Analyze an error message and provide solutions */ async analyzeError(errorMessage, options = {}) { try { // Parse and categorize the error const errorInfo = this.parseError(errorMessage); // Search for related solutions if search engine is available const relatedSolutions = await this.searchForSolutions(errorMessage, errorInfo); // Generate specific solutions const solutions = this.generateSolutions(errorInfo, relatedSolutions); // Generate debug steps const debugSteps = this.generateDebugSteps(errorInfo); // Add to context if context manager is available if (this.contextManager && options.addToContext !== false) { await this.addErrorToContext(errorMessage, errorInfo, solutions); } // Log activity if session manager is available if (this.sessionManager) { await this.logErrorActivity(errorMessage, errorInfo); } return { originalError: errorMessage, category: errorInfo.category, severity: errorInfo.severity, urgency: errorInfo.urgency, type: errorInfo.type, component: errorInfo.component, lineNumber: errorInfo.lineNumber, solutions, debugSteps, relatedSolutions: relatedSolutions.slice(0, 3), // Top 3 most relevant suggestions: this.generateSuggestions(errorInfo) }; } catch (error) { console.error('Error during error analysis:', error); // Fallback analysis return { originalError: errorMessage, category: 'unknown', severity: 'medium', urgency: 'medium', type: 'unknown', component: 'unknown', solutions: [ 'Search for the error message in your codebase', 'Check recent changes that might have caused this error', 'Look for similar error patterns in documentation' ], debugSteps: [ 'Check the full error stack trace', 'Verify recent code changes', 'Search online for the specific error message' ], relatedSolutions: [], suggestions: [ 'Try breaking down the problem into smaller parts', 'Check if the error is reproducible', 'Look for error handling patterns in the codebase' ] }; } } /** * Parse error message and extract information */ parseError(errorMessage) { let bestMatch = null; let bestCategory = 'unknown'; // Find the best matching error pattern for (const [category, config] of Object.entries(this.errorPatterns)) { for (const pattern of config.patterns) { if (pattern.test(errorMessage)) { if (!bestMatch) { bestMatch = config; bestCategory = category; } } } } // Extract additional information const lineNumberMatch = errorMessage.match(/line (\d+)/i) || errorMessage.match(/:(\d+):/); const lineNumber = lineNumberMatch ? parseInt(lineNumberMatch[1]) : null; // Extract component/file information const fileMatch = errorMessage.match(/at (.+?):/i) || errorMessage.match(/in (.+?\.js)/i) || errorMessage.match(/from (.+?\.js)/i); const component = fileMatch ? fileMatch[1].split('/').pop() : 'unknown'; return { category: bestCategory, severity: bestMatch?.severity || 'medium', urgency: bestMatch?.urgency || 'medium', type: bestCategory, component, lineNumber, fullMessage: errorMessage }; } /** * Search for solutions using vector search */ async searchForSolutions(errorMessage, errorInfo) { if (!this.searchEngine) { return []; } try { // Create search queries based on error information const queries = [ `error ${errorInfo.category} ${errorInfo.component}`, `fix ${errorMessage.split('\n')[0]}`, // First line of error `solution ${errorInfo.type} error`, `handle ${errorInfo.category} exception` ]; const solutions = []; for (const query of queries) { try { const results = await this.searchEngine.search(query, { maxResults: 3, threshold: 0.6 }); if (results && results.results) { solutions.push(...results.results.map(result => ({ content: result.chunk?.content || result.content, score: result.score, file: result.chunk?.file, query, type: 'code_solution' }))); } } catch (error) { console.warn(`Search failed for query "${query}":`, error.message); } } // Remove duplicates and sort by score const uniqueSolutions = solutions .filter((solution, index, array) => array.findIndex(s => s.content === solution.content) === index ) .sort((a, b) => b.score - a.score); return uniqueSolutions; } catch (error) { console.warn('Search for solutions failed:', error.message); return []; } } /** * Generate specific solutions based on error type */ generateSolutions(errorInfo, relatedSolutions = []) { const templateSolutions = this.solutionTemplates[errorInfo.category] || this.solutionTemplates['syntax']; const solutions = [...templateSolutions]; // Add solutions from search results relatedSolutions.slice(0, 2).forEach(solution => { if (solution.content && solution.content.length > 20) { solutions.push(`Based on similar code: ${solution.content.substring(0, 100)}...`); } }); // Add component-specific solutions if (errorInfo.component && errorInfo.component !== 'unknown') { solutions.push(`Check the ${errorInfo.component} component for recent changes`); solutions.push(`Look for similar patterns in other parts of ${errorInfo.component}`); } // Add line-specific solutions if (errorInfo.lineNumber) { solutions.push(`Focus on line ${errorInfo.lineNumber} and surrounding context`); solutions.push(`Check if line ${errorInfo.lineNumber} has proper syntax and dependencies`); } return solutions.slice(0, 8); // Limit to 8 solutions } /** * Generate debug steps based on error type */ generateDebugSteps(errorInfo) { const templateSteps = this.debugSteps[errorInfo.category] || this.debugSteps['syntax']; const steps = [...templateSteps]; // Add context-specific debug steps if (errorInfo.lineNumber) { steps.unshift(`Examine line ${errorInfo.lineNumber} and the lines immediately before and after`); } if (errorInfo.component && errorInfo.component !== 'unknown') { steps.push(`Test the ${errorInfo.component} component in isolation`); } return steps.slice(0, 6); // Limit to 6 steps } /** * Generate suggestions for next actions */ generateSuggestions(errorInfo) { const suggestions = [ `Search for more examples: claude-search search "${errorInfo.category} error solution"`, `Look for related issues: claude-search search "${errorInfo.component} ${errorInfo.type}"` ]; if (errorInfo.category === 'module') { suggestions.push('Check package.json dependencies and run npm install'); } if (errorInfo.category === 'type') { suggestions.push('Add TypeScript for better type checking'); } if (errorInfo.category === 'syntax') { suggestions.push('Use a linter like ESLint to catch syntax errors early'); } return suggestions; } /** * Add error information to context */ async addErrorToContext(errorMessage, errorInfo, solutions) { if (!this.contextManager) return; try { await this.contextManager.addItem({ type: 'error_solution', content: `Error: ${errorMessage}\nCategory: ${errorInfo.category}\nSolutions: ${solutions.slice(0, 3).join('; ')}`, metadata: { errorCategory: errorInfo.category, severity: errorInfo.severity, component: errorInfo.component, lineNumber: errorInfo.lineNumber, timestamp: Date.now() }, source: 'error-analysis' }, 'high'); // High priority for error solutions } catch (error) { console.warn('Failed to add error to context:', error.message); } } /** * Log error analysis activity */ async logErrorActivity(errorMessage, errorInfo) { // This would need to be implemented in SessionManager // For now, we'll just log the activity console.log(`Error analysis: ${errorInfo.category} error in ${errorInfo.component}`); } /** * Get error statistics from current session */ getErrorStatistics() { // This would analyze errors from the current session // Implementation would depend on SessionManager integration return { totalErrors: 0, errorsByCategory: {}, commonPatterns: [], resolutionRate: 0 }; } /** * Learn from error resolution */ async learnFromResolution(errorMessage, solution, wasHelpful = true) { // This would implement learning from user feedback // Could update solution rankings or add custom patterns console.log(`Learning from resolution: ${wasHelpful ? 'helpful' : 'not helpful'}`); } } export default ErrorAssistant;