nova-terminal-assistant 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nova-terminal-assistant might be problematic. Click here for more details.
- package/README.md +358 -0
- package/bin/nova +38 -0
- package/bin/nova.js +12 -0
- package/package.json +67 -0
- package/src/cli/commands/SmartCompletion.ts +458 -0
- package/src/cli/index.ts +5 -0
- package/src/cli/startup/IFlowRepl.ts +212 -0
- package/src/cli/startup/InkBasedRepl.ts +1056 -0
- package/src/cli/startup/InteractiveRepl.ts +2833 -0
- package/src/cli/startup/NovaApp.ts +1861 -0
- package/src/cli/startup/index.ts +4 -0
- package/src/cli/startup/parseArgs.ts +293 -0
- package/src/cli/test-modules.ts +27 -0
- package/src/cli/ui/IFlowDropdown.ts +425 -0
- package/src/cli/ui/ModernReplUI.ts +276 -0
- package/src/cli/ui/SimpleSelector2.ts +215 -0
- package/src/cli/ui/components/ConfirmDialog.ts +176 -0
- package/src/cli/ui/components/ErrorPanel.ts +364 -0
- package/src/cli/ui/components/InkAppRunner.tsx +67 -0
- package/src/cli/ui/components/InkComponents.tsx +613 -0
- package/src/cli/ui/components/NovaInkApp.tsx +312 -0
- package/src/cli/ui/components/ProgressBar.ts +177 -0
- package/src/cli/ui/components/ProgressIndicator.ts +298 -0
- package/src/cli/ui/components/QuickActions.ts +396 -0
- package/src/cli/ui/components/SimpleErrorPanel.ts +231 -0
- package/src/cli/ui/components/StatusBar.ts +194 -0
- package/src/cli/ui/components/ThinkingBlockRenderer.ts +401 -0
- package/src/cli/ui/components/index.ts +27 -0
- package/src/cli/ui/ink-prototype.tsx +347 -0
- package/src/cli/utils/CliUI.ts +336 -0
- package/src/cli/utils/CompletionHelper.ts +388 -0
- package/src/cli/utils/EnhancedCompleter.test.ts +226 -0
- package/src/cli/utils/EnhancedCompleter.ts +513 -0
- package/src/cli/utils/ErrorEnhancer.ts +429 -0
- package/src/cli/utils/OutputFormatter.ts +193 -0
- package/src/cli/utils/index.ts +9 -0
- package/src/core/agents/AgentOrchestrator.ts +515 -0
- package/src/core/agents/index.ts +17 -0
- package/src/core/audit/AuditLogger.ts +509 -0
- package/src/core/audit/index.ts +11 -0
- package/src/core/auth/AuthManager.d.ts.map +1 -0
- package/src/core/auth/AuthManager.ts +138 -0
- package/src/core/auth/index.d.ts.map +1 -0
- package/src/core/auth/index.ts +2 -0
- package/src/core/config/ConfigManager.d.ts.map +1 -0
- package/src/core/config/ConfigManager.test.ts +183 -0
- package/src/core/config/ConfigManager.ts +1219 -0
- package/src/core/config/index.d.ts.map +1 -0
- package/src/core/config/index.ts +1 -0
- package/src/core/context/ContextBuilder.d.ts.map +1 -0
- package/src/core/context/ContextBuilder.ts +171 -0
- package/src/core/context/ContextCompressor.d.ts.map +1 -0
- package/src/core/context/ContextCompressor.ts +642 -0
- package/src/core/context/LayeredMemoryManager.ts +657 -0
- package/src/core/context/MemoryDiscovery.d.ts.map +1 -0
- package/src/core/context/MemoryDiscovery.ts +175 -0
- package/src/core/context/defaultSystemPrompt.d.ts.map +1 -0
- package/src/core/context/defaultSystemPrompt.ts +35 -0
- package/src/core/context/index.d.ts.map +1 -0
- package/src/core/context/index.ts +22 -0
- package/src/core/extensions/SkillGenerator.ts +421 -0
- package/src/core/extensions/SkillInstaller.d.ts.map +1 -0
- package/src/core/extensions/SkillInstaller.ts +257 -0
- package/src/core/extensions/SkillRegistry.d.ts.map +1 -0
- package/src/core/extensions/SkillRegistry.ts +361 -0
- package/src/core/extensions/SkillValidator.ts +525 -0
- package/src/core/extensions/index.ts +15 -0
- package/src/core/index.d.ts.map +1 -0
- package/src/core/index.ts +42 -0
- package/src/core/mcp/McpManager.d.ts.map +1 -0
- package/src/core/mcp/McpManager.ts +632 -0
- package/src/core/mcp/index.d.ts.map +1 -0
- package/src/core/mcp/index.ts +2 -0
- package/src/core/model/ModelClient.d.ts.map +1 -0
- package/src/core/model/ModelClient.ts +217 -0
- package/src/core/model/ModelConnectionTester.ts +363 -0
- package/src/core/model/ModelValidator.ts +348 -0
- package/src/core/model/index.d.ts.map +1 -0
- package/src/core/model/index.ts +6 -0
- package/src/core/model/providers/AnthropicProvider.d.ts.map +1 -0
- package/src/core/model/providers/AnthropicProvider.ts +279 -0
- package/src/core/model/providers/CodingPlanProvider.d.ts.map +1 -0
- package/src/core/model/providers/CodingPlanProvider.ts +210 -0
- package/src/core/model/providers/OllamaCloudProvider.d.ts.map +1 -0
- package/src/core/model/providers/OllamaCloudProvider.ts +405 -0
- package/src/core/model/providers/OllamaManager.d.ts.map +1 -0
- package/src/core/model/providers/OllamaManager.ts +201 -0
- package/src/core/model/providers/OllamaProvider.d.ts.map +1 -0
- package/src/core/model/providers/OllamaProvider.ts +73 -0
- package/src/core/model/providers/OpenAICompatibleProvider.d.ts.map +1 -0
- package/src/core/model/providers/OpenAICompatibleProvider.ts +327 -0
- package/src/core/model/providers/OpenAIProvider.d.ts.map +1 -0
- package/src/core/model/providers/OpenAIProvider.ts +29 -0
- package/src/core/model/providers/index.d.ts.map +1 -0
- package/src/core/model/providers/index.ts +12 -0
- package/src/core/model/types.d.ts.map +1 -0
- package/src/core/model/types.ts +77 -0
- package/src/core/security/ApprovalManager.d.ts.map +1 -0
- package/src/core/security/ApprovalManager.ts +174 -0
- package/src/core/security/FileFilter.d.ts.map +1 -0
- package/src/core/security/FileFilter.ts +141 -0
- package/src/core/security/HookExecutor.d.ts.map +1 -0
- package/src/core/security/HookExecutor.ts +178 -0
- package/src/core/security/SandboxExecutor.ts +447 -0
- package/src/core/security/index.d.ts.map +1 -0
- package/src/core/security/index.ts +8 -0
- package/src/core/session/AgentLoop.d.ts.map +1 -0
- package/src/core/session/AgentLoop.ts +501 -0
- package/src/core/session/SessionManager.d.ts.map +1 -0
- package/src/core/session/SessionManager.test.ts +183 -0
- package/src/core/session/SessionManager.ts +460 -0
- package/src/core/session/index.d.ts.map +1 -0
- package/src/core/session/index.ts +3 -0
- package/src/core/telemetry/Telemetry.d.ts.map +1 -0
- package/src/core/telemetry/Telemetry.ts +90 -0
- package/src/core/telemetry/TelemetryService.ts +531 -0
- package/src/core/telemetry/index.d.ts.map +1 -0
- package/src/core/telemetry/index.ts +12 -0
- package/src/core/testing/AutoFixer.ts +385 -0
- package/src/core/testing/ErrorAnalyzer.ts +499 -0
- package/src/core/testing/TestRunner.ts +265 -0
- package/src/core/testing/agent-cli-tests.ts +538 -0
- package/src/core/testing/index.ts +11 -0
- package/src/core/tools/ToolRegistry.d.ts.map +1 -0
- package/src/core/tools/ToolRegistry.test.ts +206 -0
- package/src/core/tools/ToolRegistry.ts +260 -0
- package/src/core/tools/impl/EditFileTool.d.ts.map +1 -0
- package/src/core/tools/impl/EditFileTool.ts +97 -0
- package/src/core/tools/impl/ListDirectoryTool.d.ts.map +1 -0
- package/src/core/tools/impl/ListDirectoryTool.ts +142 -0
- package/src/core/tools/impl/MemoryTool.d.ts.map +1 -0
- package/src/core/tools/impl/MemoryTool.ts +102 -0
- package/src/core/tools/impl/ReadFileTool.d.ts.map +1 -0
- package/src/core/tools/impl/ReadFileTool.ts +58 -0
- package/src/core/tools/impl/SearchContentTool.d.ts.map +1 -0
- package/src/core/tools/impl/SearchContentTool.ts +94 -0
- package/src/core/tools/impl/SearchFileTool.d.ts.map +1 -0
- package/src/core/tools/impl/SearchFileTool.ts +61 -0
- package/src/core/tools/impl/ShellTool.d.ts.map +1 -0
- package/src/core/tools/impl/ShellTool.ts +118 -0
- package/src/core/tools/impl/TaskTool.d.ts.map +1 -0
- package/src/core/tools/impl/TaskTool.ts +207 -0
- package/src/core/tools/impl/TodoTool.d.ts.map +1 -0
- package/src/core/tools/impl/TodoTool.ts +122 -0
- package/src/core/tools/impl/WebFetchTool.d.ts.map +1 -0
- package/src/core/tools/impl/WebFetchTool.ts +103 -0
- package/src/core/tools/impl/WebSearchTool.d.ts.map +1 -0
- package/src/core/tools/impl/WebSearchTool.ts +89 -0
- package/src/core/tools/impl/WriteFileTool.d.ts.map +1 -0
- package/src/core/tools/impl/WriteFileTool.ts +49 -0
- package/src/core/tools/impl/index.d.ts.map +1 -0
- package/src/core/tools/impl/index.ts +16 -0
- package/src/core/tools/index.d.ts.map +1 -0
- package/src/core/tools/index.ts +7 -0
- package/src/core/tools/schemas/execution.d.ts.map +1 -0
- package/src/core/tools/schemas/execution.ts +42 -0
- package/src/core/tools/schemas/file.d.ts.map +1 -0
- package/src/core/tools/schemas/file.ts +119 -0
- package/src/core/tools/schemas/index.d.ts.map +1 -0
- package/src/core/tools/schemas/index.ts +11 -0
- package/src/core/tools/schemas/memory.d.ts.map +1 -0
- package/src/core/tools/schemas/memory.ts +52 -0
- package/src/core/tools/schemas/orchestration.d.ts.map +1 -0
- package/src/core/tools/schemas/orchestration.ts +44 -0
- package/src/core/tools/schemas/search.d.ts.map +1 -0
- package/src/core/tools/schemas/search.ts +112 -0
- package/src/core/tools/schemas/todo.d.ts.map +1 -0
- package/src/core/tools/schemas/todo.ts +32 -0
- package/src/core/tools/schemas/web.d.ts.map +1 -0
- package/src/core/tools/schemas/web.ts +86 -0
- package/src/core/types/config.d.ts.map +1 -0
- package/src/core/types/config.ts +200 -0
- package/src/core/types/errors.d.ts.map +1 -0
- package/src/core/types/errors.ts +204 -0
- package/src/core/types/index.d.ts.map +1 -0
- package/src/core/types/index.ts +8 -0
- package/src/core/types/session.d.ts.map +1 -0
- package/src/core/types/session.ts +216 -0
- package/src/core/types/tools.d.ts.map +1 -0
- package/src/core/types/tools.ts +157 -0
- package/src/core/utils/CheckpointManager.d.ts.map +1 -0
- package/src/core/utils/CheckpointManager.ts +327 -0
- package/src/core/utils/Logger.d.ts.map +1 -0
- package/src/core/utils/Logger.ts +98 -0
- package/src/core/utils/RetryManager.ts +471 -0
- package/src/core/utils/TokenCounter.d.ts.map +1 -0
- package/src/core/utils/TokenCounter.ts +414 -0
- package/src/core/utils/VectorMemoryStore.ts +440 -0
- package/src/core/utils/helpers.d.ts.map +1 -0
- package/src/core/utils/helpers.ts +89 -0
- package/src/core/utils/index.d.ts.map +1 -0
- package/src/core/utils/index.ts +19 -0
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// ErrorAnalyzer - Analyze errors from tests/builds and generate fix suggestions
|
|
3
|
+
// Reference: Aider-style error classification and fix recommendations
|
|
4
|
+
// ============================================================================
|
|
5
|
+
|
|
6
|
+
import type { FailedTest } from './TestRunner.js';
|
|
7
|
+
|
|
8
|
+
export type ErrorType =
|
|
9
|
+
| 'syntax'
|
|
10
|
+
| 'type'
|
|
11
|
+
| 'reference'
|
|
12
|
+
| 'import'
|
|
13
|
+
| 'runtime'
|
|
14
|
+
| 'assertion'
|
|
15
|
+
| 'timeout'
|
|
16
|
+
| 'permission'
|
|
17
|
+
| 'network'
|
|
18
|
+
| 'dependency'
|
|
19
|
+
| 'unknown';
|
|
20
|
+
|
|
21
|
+
export interface FixSuggestion {
|
|
22
|
+
/** The type of error detected */
|
|
23
|
+
errorType: ErrorType;
|
|
24
|
+
/** Human-readable description of the error */
|
|
25
|
+
description: string;
|
|
26
|
+
/** The file where the error occurred */
|
|
27
|
+
file: string;
|
|
28
|
+
/** Line number (if available) */
|
|
29
|
+
line?: number;
|
|
30
|
+
/** Confidence score 0-1 */
|
|
31
|
+
confidence: number;
|
|
32
|
+
/** Suggested fix approach */
|
|
33
|
+
fixApproach: string;
|
|
34
|
+
/** Specific code patterns to look for */
|
|
35
|
+
searchPatterns: string[];
|
|
36
|
+
/** Suggested replacement patterns */
|
|
37
|
+
replacePatterns?: Array<{ from: string; to: string }>;
|
|
38
|
+
/** Whether this error is likely auto-fixable */
|
|
39
|
+
autoFixable: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ErrorAnalysisResult {
|
|
43
|
+
/** All identified errors with suggestions */
|
|
44
|
+
suggestions: FixSuggestion[];
|
|
45
|
+
/** Critical errors that need immediate attention */
|
|
46
|
+
criticalErrors: FixSuggestion[];
|
|
47
|
+
/** Errors that can be auto-fixed */
|
|
48
|
+
autoFixableErrors: FixSuggestion[];
|
|
49
|
+
/** Summary of the error analysis */
|
|
50
|
+
summary: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// --- Error pattern database ---
|
|
54
|
+
|
|
55
|
+
interface ErrorPattern {
|
|
56
|
+
type: ErrorType;
|
|
57
|
+
pattern: RegExp;
|
|
58
|
+
description: string;
|
|
59
|
+
fixApproach: string;
|
|
60
|
+
autoFixable: boolean;
|
|
61
|
+
confidence: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const ERROR_PATTERNS: ErrorPattern[] = [
|
|
65
|
+
// TypeScript/JavaScript syntax errors
|
|
66
|
+
{
|
|
67
|
+
type: 'syntax',
|
|
68
|
+
pattern: /SyntaxError[:\s]+(?:unexpected token|Unexpected token)/i,
|
|
69
|
+
description: 'Syntax error - unexpected token in code',
|
|
70
|
+
fixApproach: 'Check for missing brackets, parentheses, commas, or invalid syntax near the reported line',
|
|
71
|
+
autoFixable: false,
|
|
72
|
+
confidence: 0.9,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: 'syntax',
|
|
76
|
+
pattern: /Parsing error[:\s]+(?:Unexpected token|unexpected)/i,
|
|
77
|
+
description: 'Parsing error - invalid JavaScript/TypeScript syntax',
|
|
78
|
+
fixApproach: 'Review the syntax near the error line for missing semicolons, brackets, or operator issues',
|
|
79
|
+
autoFixable: false,
|
|
80
|
+
confidence: 0.85,
|
|
81
|
+
},
|
|
82
|
+
// TypeScript type errors
|
|
83
|
+
{
|
|
84
|
+
type: 'type',
|
|
85
|
+
pattern: /error TS(\d+):[\s\S]*?Property '(\w+)' does not exist on type/,
|
|
86
|
+
description: 'TypeScript type error - property does not exist on type',
|
|
87
|
+
fixApproach: 'Check the type definition and ensure the property exists or use a type assertion',
|
|
88
|
+
autoFixable: true,
|
|
89
|
+
confidence: 0.95,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
type: 'type',
|
|
93
|
+
pattern: /error TS(\d+):[\s\S]*?Type '(\w+)' is not assignable to type/,
|
|
94
|
+
description: 'TypeScript type error - incompatible type assignment',
|
|
95
|
+
fixApproach: 'Add a type cast or ensure the value matches the expected type',
|
|
96
|
+
autoFixable: true,
|
|
97
|
+
confidence: 0.9,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
type: 'type',
|
|
101
|
+
pattern: /error TS(\d+):[\s\S]*?Argument of type '(\w+)' is not assignable/,
|
|
102
|
+
description: 'TypeScript type error - argument type mismatch',
|
|
103
|
+
fixApproach: 'Check the function signature and ensure the argument type matches the parameter type',
|
|
104
|
+
autoFixable: true,
|
|
105
|
+
confidence: 0.9,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
type: 'type',
|
|
109
|
+
pattern: /error TS(\d+):[\s\S]*?Cannot find name '(\w+)'/,
|
|
110
|
+
description: 'TypeScript error - undefined identifier',
|
|
111
|
+
fixApproach: 'Import the missing identifier or check for typos',
|
|
112
|
+
autoFixable: true,
|
|
113
|
+
confidence: 0.85,
|
|
114
|
+
},
|
|
115
|
+
// Import errors
|
|
116
|
+
{
|
|
117
|
+
type: 'import',
|
|
118
|
+
pattern: /Cannot find module '([^']+)'/,
|
|
119
|
+
description: 'Module not found error',
|
|
120
|
+
fixApproach: 'Install the missing module with npm/yarn or check the import path',
|
|
121
|
+
autoFixable: true,
|
|
122
|
+
confidence: 0.95,
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
type: 'import',
|
|
126
|
+
pattern: /Module not found[:\s]+Error[:\s]+Can't resolve '([^']+)'/,
|
|
127
|
+
description: 'Module resolution error',
|
|
128
|
+
fixApproach: 'Check the import path and ensure the module is installed',
|
|
129
|
+
autoFixable: true,
|
|
130
|
+
confidence: 0.9,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
type: 'import',
|
|
134
|
+
pattern: /ERR_MODULE_NOT_FOUND/,
|
|
135
|
+
description: 'ESM module not found',
|
|
136
|
+
fixApproach: 'Check the import path, ensure .js extension is included for ESM imports',
|
|
137
|
+
autoFixable: true,
|
|
138
|
+
confidence: 0.9,
|
|
139
|
+
},
|
|
140
|
+
// Reference errors
|
|
141
|
+
{
|
|
142
|
+
type: 'reference',
|
|
143
|
+
pattern: /(?:ReferenceError|TypeError)[:\s]+(\w+) is not (?:defined|a function|a constructor)/,
|
|
144
|
+
description: 'Reference error - accessing undefined variable or function',
|
|
145
|
+
fixApproach: 'Ensure the variable or function is declared and in scope before use',
|
|
146
|
+
autoFixable: false,
|
|
147
|
+
confidence: 0.85,
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'reference',
|
|
151
|
+
pattern: /TypeError[:\s]+Cannot read (?:properties of )?(?:undefined|null) \(reading '(\w+)'\)/,
|
|
152
|
+
description: 'TypeError - accessing property on null/undefined',
|
|
153
|
+
fixApproach: 'Add a null check before accessing the property, or ensure the object is properly initialized',
|
|
154
|
+
autoFixable: true,
|
|
155
|
+
confidence: 0.9,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
type: 'reference',
|
|
159
|
+
pattern: /TypeError[:\s]+(?:\w+)\.(?:\w+) is not a function/,
|
|
160
|
+
description: 'TypeError - calling a non-function value',
|
|
161
|
+
fixApproach: 'Ensure the value is a function before calling it, check for typos in method names',
|
|
162
|
+
autoFixable: false,
|
|
163
|
+
confidence: 0.8,
|
|
164
|
+
},
|
|
165
|
+
// Runtime errors
|
|
166
|
+
{
|
|
167
|
+
type: 'runtime',
|
|
168
|
+
pattern: /RangeError[:\s]+Maximum call stack size exceeded/,
|
|
169
|
+
description: 'Stack overflow - infinite recursion detected',
|
|
170
|
+
fixApproach: 'Check for infinite recursion, missing base case in recursive functions, or circular dependencies',
|
|
171
|
+
autoFixable: false,
|
|
172
|
+
confidence: 0.9,
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
type: 'runtime',
|
|
176
|
+
pattern: /RangeError[:\s]+Invalid array length/,
|
|
177
|
+
description: 'Invalid array length - likely negative or too large',
|
|
178
|
+
fixApproach: 'Add bounds checking before creating arrays or check for negative values',
|
|
179
|
+
autoFixable: true,
|
|
180
|
+
confidence: 0.85,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
type: 'runtime',
|
|
184
|
+
pattern: /Error[:\s]+ENOSPC|no space left/,
|
|
185
|
+
description: 'Disk space exhausted',
|
|
186
|
+
fixApproach: 'Free up disk space or check for large temporary files',
|
|
187
|
+
autoFixable: false,
|
|
188
|
+
confidence: 0.95,
|
|
189
|
+
},
|
|
190
|
+
// Assertion errors
|
|
191
|
+
{
|
|
192
|
+
type: 'assertion',
|
|
193
|
+
pattern: /AssertionError[:\s]+expected\s+.+?\s+to\s+(?:equal|be|contain|have)/i,
|
|
194
|
+
description: 'Test assertion failed - value mismatch',
|
|
195
|
+
fixApproach: 'Review the test expectation and the actual value, update either the code or the test',
|
|
196
|
+
autoFixable: false,
|
|
197
|
+
confidence: 0.8,
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
type: 'assertion',
|
|
201
|
+
pattern: /expect\((.+?)\)\.(?:to[Be|Equal|Have|Contain]+)\((.+?)\)/,
|
|
202
|
+
description: 'Jest/Vitest assertion failure',
|
|
203
|
+
fixApproach: 'Compare expected vs actual values and fix the implementation or update the test expectation',
|
|
204
|
+
autoFixable: false,
|
|
205
|
+
confidence: 0.85,
|
|
206
|
+
},
|
|
207
|
+
// Timeout errors
|
|
208
|
+
{
|
|
209
|
+
type: 'timeout',
|
|
210
|
+
pattern: /Timeout\s*-\s*(?:Async callback|test|operation)/i,
|
|
211
|
+
description: 'Test or operation timed out',
|
|
212
|
+
fixApproach: 'Increase the timeout value or optimize the operation',
|
|
213
|
+
autoFixable: true,
|
|
214
|
+
confidence: 0.7,
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
type: 'timeout',
|
|
218
|
+
pattern: /ETIMEOUT|ETIMEDOUT|socket hang up/,
|
|
219
|
+
description: 'Network or I/O operation timed out',
|
|
220
|
+
fixApproach: 'Check network connectivity, increase timeout, or add retry logic',
|
|
221
|
+
autoFixable: true,
|
|
222
|
+
confidence: 0.8,
|
|
223
|
+
},
|
|
224
|
+
// Permission errors
|
|
225
|
+
{
|
|
226
|
+
type: 'permission',
|
|
227
|
+
pattern: /EACCES[:\s]+permission denied/i,
|
|
228
|
+
description: 'File system permission denied',
|
|
229
|
+
fixApproach: 'Check file/directory permissions or run with appropriate privileges',
|
|
230
|
+
autoFixable: false,
|
|
231
|
+
confidence: 0.95,
|
|
232
|
+
},
|
|
233
|
+
// Dependency errors
|
|
234
|
+
{
|
|
235
|
+
type: 'dependency',
|
|
236
|
+
pattern: /npm ERR!|yarn error|pnpm ERR!/,
|
|
237
|
+
description: 'Package manager error',
|
|
238
|
+
fixApproach: 'Check the error details for missing dependencies, version conflicts, or registry issues',
|
|
239
|
+
autoFixable: true,
|
|
240
|
+
confidence: 0.8,
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
type: 'dependency',
|
|
244
|
+
pattern: /peer dep[^\n]*?MISSING|UNMET PEER DEPENDENCY/i,
|
|
245
|
+
description: 'Missing peer dependency',
|
|
246
|
+
fixApproach: 'Install the missing peer dependency',
|
|
247
|
+
autoFixable: true,
|
|
248
|
+
confidence: 0.9,
|
|
249
|
+
},
|
|
250
|
+
// Python runtime errors
|
|
251
|
+
{
|
|
252
|
+
type: 'runtime',
|
|
253
|
+
pattern: /NameError[:\s]+name '(\S+)' is not defined/i,
|
|
254
|
+
description: 'Python NameError - undefined variable',
|
|
255
|
+
fixApproach: 'Check for typos in the variable name, ensure the variable is defined before use, or import the required module',
|
|
256
|
+
autoFixable: true,
|
|
257
|
+
confidence: 0.9,
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
type: 'runtime',
|
|
261
|
+
pattern: /TypeError[:\s]+(.+)/i,
|
|
262
|
+
description: 'Type error in operation',
|
|
263
|
+
fixApproach: 'Check the types of operands and ensure they support the operation being performed',
|
|
264
|
+
autoFixable: false,
|
|
265
|
+
confidence: 0.85,
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
type: 'runtime',
|
|
269
|
+
pattern: /IndentationError[:\s]+(.+)/i,
|
|
270
|
+
description: 'Python indentation error',
|
|
271
|
+
fixApproach: 'Fix the indentation to use consistent spaces or tabs',
|
|
272
|
+
autoFixable: true,
|
|
273
|
+
confidence: 0.9,
|
|
274
|
+
},
|
|
275
|
+
];
|
|
276
|
+
|
|
277
|
+
// --- ErrorAnalyzer ---
|
|
278
|
+
|
|
279
|
+
export class ErrorAnalyzer {
|
|
280
|
+
/**
|
|
281
|
+
* Analyze raw error output and generate fix suggestions.
|
|
282
|
+
*/
|
|
283
|
+
analyze(errorOutput: string): ErrorAnalysisResult {
|
|
284
|
+
const suggestions: FixSuggestion[] = [];
|
|
285
|
+
|
|
286
|
+
// Try each error pattern against the output
|
|
287
|
+
for (const pattern of ERROR_PATTERNS) {
|
|
288
|
+
const flags = pattern.pattern.flags.includes('g') ? pattern.pattern.flags : pattern.pattern.flags + 'g';
|
|
289
|
+
const regex = new RegExp(pattern.pattern.source, flags);
|
|
290
|
+
const matches = errorOutput.matchAll(regex);
|
|
291
|
+
|
|
292
|
+
for (const match of matches) {
|
|
293
|
+
const file = this.extractFile(errorOutput, match.index || 0);
|
|
294
|
+
const line = this.extractLine(errorOutput, match.index || 0);
|
|
295
|
+
|
|
296
|
+
suggestions.push({
|
|
297
|
+
errorType: pattern.type,
|
|
298
|
+
description: pattern.description.replace(/\(.*?\)/, `('${match[1] || 'unknown'}')`),
|
|
299
|
+
file,
|
|
300
|
+
line,
|
|
301
|
+
confidence: pattern.confidence,
|
|
302
|
+
fixApproach: pattern.fixApproach,
|
|
303
|
+
searchPatterns: this.generateSearchPatterns(pattern.type, match),
|
|
304
|
+
autoFixable: pattern.autoFixable,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Deduplicate suggestions
|
|
310
|
+
const deduped = this.deduplicateSuggestions(suggestions);
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
suggestions: deduped,
|
|
314
|
+
criticalErrors: deduped.filter(
|
|
315
|
+
(s) => s.confidence >= 0.85 && s.errorType !== 'assertion'
|
|
316
|
+
),
|
|
317
|
+
autoFixableErrors: deduped.filter((s) => s.autoFixable),
|
|
318
|
+
summary: this.generateSummary(deduped),
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Analyze test failures specifically.
|
|
324
|
+
*/
|
|
325
|
+
analyzeTestFailures(
|
|
326
|
+
testResult: { failedTests: FailedTest[]; output: string; errors: string }
|
|
327
|
+
): ErrorAnalysisResult {
|
|
328
|
+
const combinedOutput = `${testResult.output}\n${testResult.errors}`;
|
|
329
|
+
const analysis = this.analyze(combinedOutput);
|
|
330
|
+
|
|
331
|
+
// If no specific errors found, create generic suggestions from failed test names
|
|
332
|
+
if (analysis.suggestions.length === 0 && testResult.failedTests.length > 0) {
|
|
333
|
+
for (const failed of testResult.failedTests) {
|
|
334
|
+
analysis.suggestions.push({
|
|
335
|
+
errorType: 'assertion',
|
|
336
|
+
description: `Test failure in ${failed.file}`,
|
|
337
|
+
file: failed.file,
|
|
338
|
+
line: failed.line,
|
|
339
|
+
confidence: 0.6,
|
|
340
|
+
fixApproach: 'Review the test assertion and the code under test',
|
|
341
|
+
searchPatterns: [failed.file],
|
|
342
|
+
autoFixable: false,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return {
|
|
348
|
+
...analysis,
|
|
349
|
+
summary: this.generateSummary(analysis.suggestions, testResult.failedTests.length),
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Categorize and prioritize errors for the auto-fixer.
|
|
355
|
+
*/
|
|
356
|
+
prioritizeErrors(suggestions: FixSuggestion[]): FixSuggestion[] {
|
|
357
|
+
const priorityOrder: Record<ErrorType, number> = {
|
|
358
|
+
syntax: 0,
|
|
359
|
+
import: 1,
|
|
360
|
+
type: 2,
|
|
361
|
+
reference: 3,
|
|
362
|
+
dependency: 4,
|
|
363
|
+
permission: 5,
|
|
364
|
+
runtime: 6,
|
|
365
|
+
timeout: 7,
|
|
366
|
+
network: 8,
|
|
367
|
+
assertion: 9,
|
|
368
|
+
unknown: 10,
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
return [...suggestions].sort((a, b) => {
|
|
372
|
+
// First by priority
|
|
373
|
+
const priorityDiff = priorityOrder[a.errorType] - priorityOrder[b.errorType];
|
|
374
|
+
if (priorityDiff !== 0) return priorityDiff;
|
|
375
|
+
// Then by confidence (higher first)
|
|
376
|
+
return b.confidence - a.confidence;
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Extract the file path from error context.
|
|
382
|
+
*/
|
|
383
|
+
private extractFile(output: string, matchIndex: number): string {
|
|
384
|
+
// Look backwards from the match for a file path
|
|
385
|
+
const before = output.substring(Math.max(0, matchIndex - 200), matchIndex);
|
|
386
|
+
const filePatterns = [
|
|
387
|
+
/(?:at |in |file )([^\s:()]+\.(?:ts|tsx|js|jsx|py|go|rs|java|rb))/g,
|
|
388
|
+
/([A-Za-z]:\\[^\s:()]+\.(?:ts|tsx|js|jsx|py|go|rs|java|rb))/g,
|
|
389
|
+
/(?:\/[^\s:()]+\/)([^\s:()]+\.(?:ts|tsx|js|jsx|py|go|rs|java|rb))/g,
|
|
390
|
+
];
|
|
391
|
+
|
|
392
|
+
for (const pattern of filePatterns) {
|
|
393
|
+
let lastMatch: string | null = null;
|
|
394
|
+
let match: RegExpExecArray | null;
|
|
395
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
396
|
+
while ((match = regex.exec(before)) !== null) {
|
|
397
|
+
lastMatch = match[1] || match[0];
|
|
398
|
+
}
|
|
399
|
+
if (lastMatch) return lastMatch;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return 'unknown';
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Extract the line number from error context.
|
|
407
|
+
*/
|
|
408
|
+
private extractLine(output: string, matchIndex: number): number | undefined {
|
|
409
|
+
const after = output.substring(matchIndex, matchIndex + 200);
|
|
410
|
+
const linePatterns = [
|
|
411
|
+
/(?:line |:)(\d+)(?:[:\s]|\))/,
|
|
412
|
+
/:(\d+):\d+/, // file:line:column format
|
|
413
|
+
];
|
|
414
|
+
|
|
415
|
+
for (const pattern of linePatterns) {
|
|
416
|
+
const match = after.match(pattern);
|
|
417
|
+
if (match) return parseInt(match[1], 10);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return undefined;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Generate search patterns for finding the error in code.
|
|
425
|
+
*/
|
|
426
|
+
private generateSearchPatterns(
|
|
427
|
+
type: ErrorType,
|
|
428
|
+
match: RegExpMatchArray
|
|
429
|
+
): string[] {
|
|
430
|
+
const patterns: string[] = [];
|
|
431
|
+
|
|
432
|
+
if (match[1]) {
|
|
433
|
+
patterns.push(match[1]);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
switch (type) {
|
|
437
|
+
case 'import':
|
|
438
|
+
if (match[1]) patterns.push(`import.*${match[1]}`);
|
|
439
|
+
break;
|
|
440
|
+
case 'type':
|
|
441
|
+
if (match[1]) patterns.push(match[1]);
|
|
442
|
+
if (match[2]) patterns.push(match[2]);
|
|
443
|
+
break;
|
|
444
|
+
case 'reference':
|
|
445
|
+
if (match[1]) patterns.push(match[1]);
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return patterns.filter(Boolean);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Remove duplicate suggestions.
|
|
454
|
+
*/
|
|
455
|
+
private deduplicateSuggestions(suggestions: FixSuggestion[]): FixSuggestion[] {
|
|
456
|
+
const seen = new Set<string>();
|
|
457
|
+
return suggestions.filter((s) => {
|
|
458
|
+
const key = `${s.file}:${s.line}:${s.errorType}`;
|
|
459
|
+
if (seen.has(key)) return false;
|
|
460
|
+
seen.add(key);
|
|
461
|
+
return true;
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Generate a human-readable summary.
|
|
467
|
+
*/
|
|
468
|
+
private generateSummary(
|
|
469
|
+
suggestions: FixSuggestion[],
|
|
470
|
+
failedTestCount?: number
|
|
471
|
+
): string {
|
|
472
|
+
if (suggestions.length === 0) {
|
|
473
|
+
return 'No specific error patterns detected. Manual analysis required.';
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const typeCounts: Record<string, number> = {};
|
|
477
|
+
for (const s of suggestions) {
|
|
478
|
+
typeCounts[s.errorType] = (typeCounts[s.errorType] || 0) + 1;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
const parts: string[] = [];
|
|
482
|
+
|
|
483
|
+
if (failedTestCount !== undefined) {
|
|
484
|
+
parts.push(`${failedTestCount} test(s) failed.`);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
const typeEntries = Object.entries(typeCounts).sort((a, b) => b[1] - a[1]);
|
|
488
|
+
parts.push(
|
|
489
|
+
`Detected ${typeEntries.map(([t, c]) => `${c} ${t}(s)`).join(', ')}.`
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
const autoFixable = suggestions.filter((s) => s.autoFixable).length;
|
|
493
|
+
if (autoFixable > 0) {
|
|
494
|
+
parts.push(`${autoFixable} error(s) may be auto-fixable.`);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
return parts.join(' ');
|
|
498
|
+
}
|
|
499
|
+
}
|