tachibot-mcp 2.0.2
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.
- package/.env.example +260 -0
- package/CHANGELOG.md +54 -0
- package/CODE_OF_CONDUCT.md +56 -0
- package/CONTRIBUTING.md +54 -0
- package/Dockerfile +36 -0
- package/LICENSE +644 -0
- package/README.md +201 -0
- package/SECURITY.md +95 -0
- package/dist/personality/komaai-expressions.js +12 -0
- package/dist/profiles/balanced.json +33 -0
- package/dist/profiles/code_focus.json +33 -0
- package/dist/profiles/full.json +33 -0
- package/dist/profiles/minimal.json +33 -0
- package/dist/profiles/research_power.json +33 -0
- package/dist/scripts/build-profiles.js +46 -0
- package/dist/src/application/services/focus/FocusModeRegistry.js +46 -0
- package/dist/src/application/services/focus/FocusTool.service.js +109 -0
- package/dist/src/application/services/focus/ModeRegistry.js +46 -0
- package/dist/src/application/services/focus/modes/focus-deep.mode.js +27 -0
- package/dist/src/application/services/focus/modes/status.mode.js +50 -0
- package/dist/src/application/services/focus/modes/tachibot-status.mode.js +50 -0
- package/dist/src/collaborative-orchestrator.js +391 -0
- package/dist/src/config/model-constants.js +188 -0
- package/dist/src/config/model-defaults.js +57 -0
- package/dist/src/config/model-preferences.js +382 -0
- package/dist/src/config/timeout-config.js +130 -0
- package/dist/src/config.js +173 -0
- package/dist/src/domain/interfaces/IFocusMode.js +5 -0
- package/dist/src/domain/interfaces/IProvider.js +6 -0
- package/dist/src/domain/interfaces/ITool.js +5 -0
- package/dist/src/focus-deep.js +245 -0
- package/dist/src/infrastructure/ascii/art/robots.ascii.js +16 -0
- package/dist/src/mcp-client.js +90 -0
- package/dist/src/memory/index.js +17 -0
- package/dist/src/memory/memory-config.js +135 -0
- package/dist/src/memory/memory-interface.js +174 -0
- package/dist/src/memory/memory-manager.js +383 -0
- package/dist/src/memory/providers/devlog-provider.js +385 -0
- package/dist/src/memory/providers/hybrid-provider.js +399 -0
- package/dist/src/memory/providers/local-provider.js +388 -0
- package/dist/src/memory/providers/mem0-provider.js +337 -0
- package/dist/src/modes/architect.js +477 -0
- package/dist/src/modes/auditor.js +362 -0
- package/dist/src/modes/challenger.js +841 -0
- package/dist/src/modes/code-reviewer.js +382 -0
- package/dist/src/modes/commit-guardian.js +424 -0
- package/dist/src/modes/documentation-writer.js +572 -0
- package/dist/src/modes/scout.js +587 -0
- package/dist/src/modes/shared/helpers/challenger-helpers.js +454 -0
- package/dist/src/modes/shared/helpers/index.js +17 -0
- package/dist/src/modes/shared/helpers/scout-helpers.js +270 -0
- package/dist/src/modes/shared/helpers/verifier-helpers.js +332 -0
- package/dist/src/modes/test-architect.js +767 -0
- package/dist/src/modes/verifier.js +378 -0
- package/dist/src/monitoring/performance-monitor.js +435 -0
- package/dist/src/optimization/batch-executor.js +121 -0
- package/dist/src/optimization/context-pruner.js +196 -0
- package/dist/src/optimization/cost-monitor.js +338 -0
- package/dist/src/optimization/index.js +65 -0
- package/dist/src/optimization/model-router.js +264 -0
- package/dist/src/optimization/result-cache.js +114 -0
- package/dist/src/optimization/token-optimizer.js +257 -0
- package/dist/src/optimization/token-tracker.js +118 -0
- package/dist/src/orchestrator-instructions.js +128 -0
- package/dist/src/orchestrator-lite.js +139 -0
- package/dist/src/orchestrator.js +191 -0
- package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionEngine.js +1 -0
- package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionStrategy.js +5 -0
- package/dist/src/orchestrators/collaborative/interfaces/IVisualizationRenderer.js +1 -0
- package/dist/src/orchestrators/collaborative/registries/ModelProviderRegistry.js +95 -0
- package/dist/src/orchestrators/collaborative/registries/ToolAdapterRegistry.js +64 -0
- package/dist/src/orchestrators/collaborative/services/tool-execution/ToolExecutionService.js +502 -0
- package/dist/src/orchestrators/collaborative/services/visualization/VisualizationService.js +206 -0
- package/dist/src/orchestrators/collaborative/types/session-types.js +5 -0
- package/dist/src/profiles/balanced.js +37 -0
- package/dist/src/profiles/code_focus.js +37 -0
- package/dist/src/profiles/debug_intensive.js +59 -0
- package/dist/src/profiles/full.js +37 -0
- package/dist/src/profiles/minimal.js +37 -0
- package/dist/src/profiles/research_code.js +59 -0
- package/dist/src/profiles/research_power.js +37 -0
- package/dist/src/profiles/types.js +5 -0
- package/dist/src/profiles/workflow_builder.js +53 -0
- package/dist/src/prompt-engineer-lite.js +78 -0
- package/dist/src/prompt-engineer.js +399 -0
- package/dist/src/reasoning-chain.js +508 -0
- package/dist/src/sequential-thinking.js +291 -0
- package/dist/src/server-diagnostic.js +74 -0
- package/dist/src/server-raw.js +158 -0
- package/dist/src/server-simple.js +58 -0
- package/dist/src/server.js +514 -0
- package/dist/src/session/session-logger.js +617 -0
- package/dist/src/session/session-manager.js +571 -0
- package/dist/src/session/session-tools.js +400 -0
- package/dist/src/tools/advanced-modes.js +200 -0
- package/dist/src/tools/claude-integration.js +356 -0
- package/dist/src/tools/consolidated/ai-router.js +174 -0
- package/dist/src/tools/consolidated/ai-tool.js +48 -0
- package/dist/src/tools/consolidated/brainstorm-tool.js +87 -0
- package/dist/src/tools/consolidated/environment-detector.js +80 -0
- package/dist/src/tools/consolidated/index.js +50 -0
- package/dist/src/tools/consolidated/search-tool.js +110 -0
- package/dist/src/tools/consolidated/workflow-tool.js +238 -0
- package/dist/src/tools/gemini-tools.js +329 -0
- package/dist/src/tools/grok-enhanced.js +376 -0
- package/dist/src/tools/grok-tools.js +299 -0
- package/dist/src/tools/lmstudio-tools.js +223 -0
- package/dist/src/tools/openai-tools.js +498 -0
- package/dist/src/tools/openrouter-tools.js +317 -0
- package/dist/src/tools/optimized-wrapper.js +204 -0
- package/dist/src/tools/perplexity-tools.js +294 -0
- package/dist/src/tools/pingpong-tool.js +343 -0
- package/dist/src/tools/qwen-wrapper.js +74 -0
- package/dist/src/tools/tool-router.js +444 -0
- package/dist/src/tools/unified-ai-provider.js +260 -0
- package/dist/src/tools/workflow-runner.js +425 -0
- package/dist/src/tools/workflow-validator-tool.js +107 -0
- package/dist/src/types.js +23 -0
- package/dist/src/utils/input-validator.js +130 -0
- package/dist/src/utils/model-router.js +91 -0
- package/dist/src/utils/progress-stream.js +255 -0
- package/dist/src/utils/provider-router.js +88 -0
- package/dist/src/utils/smart-api-client.js +146 -0
- package/dist/src/utils/table-builder.js +218 -0
- package/dist/src/utils/timestamp-formatter.js +134 -0
- package/dist/src/utils/tool-compressor.js +257 -0
- package/dist/src/utils/tool-config.js +201 -0
- package/dist/src/validators/dependency-graph-validator.js +147 -0
- package/dist/src/validators/interpolation-validator.js +222 -0
- package/dist/src/validators/output-usage-validator.js +151 -0
- package/dist/src/validators/syntax-validator.js +102 -0
- package/dist/src/validators/tool-registry-validator.js +123 -0
- package/dist/src/validators/tool-types.js +97 -0
- package/dist/src/validators/types.js +8 -0
- package/dist/src/validators/workflow-validator.js +134 -0
- package/dist/src/visualizer-lite.js +42 -0
- package/dist/src/visualizer.js +179 -0
- package/dist/src/workflows/circuit-breaker.js +199 -0
- package/dist/src/workflows/custom-workflows.js +451 -0
- package/dist/src/workflows/engine/AutoSynthesizer.js +97 -0
- package/dist/src/workflows/engine/StepParameterResolver.js +74 -0
- package/dist/src/workflows/engine/VariableInterpolator.js +123 -0
- package/dist/src/workflows/engine/WorkflowDiscovery.js +125 -0
- package/dist/src/workflows/engine/WorkflowExecutionEngine.js +485 -0
- package/dist/src/workflows/engine/WorkflowExecutor.js +113 -0
- package/dist/src/workflows/engine/WorkflowFileManager.js +244 -0
- package/dist/src/workflows/engine/WorkflowHelpers.js +114 -0
- package/dist/src/workflows/engine/WorkflowOutputFormatter.js +83 -0
- package/dist/src/workflows/engine/events/WorkflowEventBus.js +132 -0
- package/dist/src/workflows/engine/events/interfaces/IEventBus.js +5 -0
- package/dist/src/workflows/engine/handlers/ErrorRecoveryHandler.js +162 -0
- package/dist/src/workflows/engine/handlers/PromptEnhancementHandler.js +115 -0
- package/dist/src/workflows/engine/handlers/SessionPersistenceHandler.js +167 -0
- package/dist/src/workflows/engine/handlers/StepExecutionHandler.js +231 -0
- package/dist/src/workflows/engine/handlers/ToolInvocationHandler.js +46 -0
- package/dist/src/workflows/engine/interfaces/IAutoSynthesizer.js +5 -0
- package/dist/src/workflows/engine/interfaces/IStepParameterResolver.js +5 -0
- package/dist/src/workflows/engine/interfaces/IVariableInterpolator.js +5 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowDiscovery.js +4 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowFileManager.js +5 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowOutputFormatter.js +5 -0
- package/dist/src/workflows/engine/state/WorkflowStateMachine.js +194 -0
- package/dist/src/workflows/engine/state/interfaces/IStateMachine.js +17 -0
- package/dist/src/workflows/fallback-strategies.js +373 -0
- package/dist/src/workflows/message-queue.js +455 -0
- package/dist/src/workflows/model-router.js +189 -0
- package/dist/src/workflows/orchestrator-examples.js +174 -0
- package/dist/src/workflows/orchestrator-integration.js +200 -0
- package/dist/src/workflows/self-healing.js +524 -0
- package/dist/src/workflows/tool-mapper.js +407 -0
- package/dist/src/workflows/tool-orchestrator.js +796 -0
- package/dist/src/workflows/workflow-engine.js +573 -0
- package/dist/src/workflows/workflow-parser.js +283 -0
- package/dist/src/workflows/workflow-types.js +95 -0
- package/dist/src/workflows.js +568 -0
- package/dist/test-workflow-file-output.js +93 -0
- package/docs/API_KEYS.md +570 -0
- package/docs/CLAUDE_CODE_SETUP.md +181 -0
- package/docs/CLAUDE_DESKTOP_MANUAL.md +127 -0
- package/docs/CONFIGURATION.md +745 -0
- package/docs/FOCUS_MODES.md +240 -0
- package/docs/INSTALLATION_BOTH.md +145 -0
- package/docs/TERMS.md +352 -0
- package/docs/TOOLS_REFERENCE.md +1622 -0
- package/docs/TOOL_PARAMETERS.md +496 -0
- package/docs/TOOL_PROFILES.md +236 -0
- package/docs/WORKFLOWS.md +987 -0
- package/docs/WORKFLOW_OUTPUT.md +198 -0
- package/docs/WORKFLOW_PROGRESS_TRACKING.md +305 -0
- package/docs/workflows/design-brainstorm.md +335 -0
- package/package.json +97 -0
- package/profiles/balanced.json +37 -0
- package/profiles/code_focus.json +37 -0
- package/profiles/debug_intensive.json +34 -0
- package/profiles/full.json +37 -0
- package/profiles/minimal.json +37 -0
- package/profiles/research_power.json +37 -0
- package/profiles/workflow_builder.json +37 -0
- package/smithery.yaml +66 -0
- package/start.sh +8 -0
- package/tools.config.json +81 -0
- package/tsconfig.json +18 -0
- package/workflows/accessibility-code-audit.yaml +92 -0
- package/workflows/code-architecture-review.yaml +202 -0
- package/workflows/code-review.yaml +142 -0
- package/workflows/core/iterative-problem-solver.yaml +283 -0
- package/workflows/creative-brainstorm-yaml.yaml +215 -0
- package/workflows/pingpong.yaml +141 -0
- package/workflows/system/README.md +412 -0
- package/workflows/system/challenger.yaml +175 -0
- package/workflows/system/scout.yaml +164 -0
- package/workflows/system/verifier.yaml +133 -0
- package/workflows/ultra-creative-brainstorm.yaml +318 -0
- package/workflows/ux-research-flow.yaml +92 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
export class CodeReviewer {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.defaultModel = 'gemini-2.5-flash';
|
|
4
|
+
this.defaultMaxTokens = 4000;
|
|
5
|
+
this.defaultFocusAreas = [
|
|
6
|
+
'security', 'performance', 'readability', 'bugs', 'best-practices'
|
|
7
|
+
];
|
|
8
|
+
}
|
|
9
|
+
async review(code, options = {}) {
|
|
10
|
+
const model = options.model || this.defaultModel;
|
|
11
|
+
const maxTokens = options.maxTokens || this.defaultMaxTokens;
|
|
12
|
+
const focusAreas = options.focusAreas || this.defaultFocusAreas;
|
|
13
|
+
const language = options.language || this.detectLanguage(code);
|
|
14
|
+
// Analyze code structure and extract basic metrics
|
|
15
|
+
const metrics = await this.calculateMetrics(code);
|
|
16
|
+
// Identify issues based on focus areas
|
|
17
|
+
const issues = await this.identifyIssues(code, focusAreas || [], language, model);
|
|
18
|
+
// Generate improvement suggestions
|
|
19
|
+
const suggestions = await this.generateSuggestions(code, issues, language, model);
|
|
20
|
+
// Generate Socratic questions for learning
|
|
21
|
+
const socraticQuestions = await this.generateSocraticQuestions(code, issues, language);
|
|
22
|
+
// Synthesize findings
|
|
23
|
+
const synthesis = this.synthesizeReview(issues, suggestions, metrics, socraticQuestions);
|
|
24
|
+
return {
|
|
25
|
+
issues,
|
|
26
|
+
suggestions,
|
|
27
|
+
metrics,
|
|
28
|
+
socraticQuestions,
|
|
29
|
+
synthesis
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
detectLanguage(code) {
|
|
33
|
+
// Simple language detection based on patterns
|
|
34
|
+
if (code.includes('import ') && code.includes('from '))
|
|
35
|
+
return 'typescript';
|
|
36
|
+
if (code.includes('function ') || code.includes('const ') || code.includes('let '))
|
|
37
|
+
return 'javascript';
|
|
38
|
+
if (code.includes('def ') && code.includes(':'))
|
|
39
|
+
return 'python';
|
|
40
|
+
if (code.includes('public class ') || code.includes('private '))
|
|
41
|
+
return 'java';
|
|
42
|
+
if (code.includes('#include') || code.includes('int main'))
|
|
43
|
+
return 'cpp';
|
|
44
|
+
if (code.includes('fn ') && code.includes('->'))
|
|
45
|
+
return 'rust';
|
|
46
|
+
if (code.includes('package ') && code.includes('func '))
|
|
47
|
+
return 'go';
|
|
48
|
+
return 'unknown';
|
|
49
|
+
}
|
|
50
|
+
async calculateMetrics(code) {
|
|
51
|
+
const lines = code.split('\n');
|
|
52
|
+
const linesOfCode = lines.filter(line => line.trim() && !line.trim().startsWith('//') && !line.trim().startsWith('*')).length;
|
|
53
|
+
// Basic complexity analysis
|
|
54
|
+
const complexityIndicators = [
|
|
55
|
+
'if', 'else', 'for', 'while', 'switch', 'case', 'try', 'catch', '?'
|
|
56
|
+
];
|
|
57
|
+
const complexityCount = complexityIndicators.reduce((count, indicator) => {
|
|
58
|
+
const matches = code.split(indicator).length - 1;
|
|
59
|
+
return count + matches;
|
|
60
|
+
}, 0);
|
|
61
|
+
const complexity = complexityCount > 20 ? 'high' :
|
|
62
|
+
complexityCount > 8 ? 'medium' : 'low';
|
|
63
|
+
// Duplicate line detection (simplified)
|
|
64
|
+
const lineMap = new Map();
|
|
65
|
+
lines.forEach(line => {
|
|
66
|
+
const trimmed = line.trim();
|
|
67
|
+
if (trimmed.length > 10) {
|
|
68
|
+
lineMap.set(trimmed, (lineMap.get(trimmed) || 0) + 1);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
const duplicateLines = Array.from(lineMap.values()).reduce((sum, count) => sum + (count > 1 ? count - 1 : 0), 0);
|
|
72
|
+
// Maintainability score (0-100)
|
|
73
|
+
let maintainabilityScore = 100;
|
|
74
|
+
maintainabilityScore -= Math.min(30, linesOfCode / 10); // Penalize long files
|
|
75
|
+
maintainabilityScore -= Math.min(20, complexityCount * 2); // Penalize complexity
|
|
76
|
+
maintainabilityScore -= Math.min(15, duplicateLines * 3); // Penalize duplication
|
|
77
|
+
maintainabilityScore = Math.max(0, maintainabilityScore);
|
|
78
|
+
const technicalDebt = maintainabilityScore < 50 ? 'high' :
|
|
79
|
+
maintainabilityScore < 75 ? 'medium' : 'low';
|
|
80
|
+
return {
|
|
81
|
+
linesOfCode,
|
|
82
|
+
complexity,
|
|
83
|
+
maintainabilityScore,
|
|
84
|
+
duplicateLines,
|
|
85
|
+
technicalDebt
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async identifyIssues(code, focusAreas, language, model) {
|
|
89
|
+
const issues = [];
|
|
90
|
+
let issueId = 1;
|
|
91
|
+
// Security issues
|
|
92
|
+
if (focusAreas.includes('security')) {
|
|
93
|
+
const securityPatterns = [
|
|
94
|
+
{ pattern: /eval\s*\(/, title: 'Dangerous eval() usage', severity: 'critical' },
|
|
95
|
+
{ pattern: /document\.write\s*\(/, title: 'XSS vulnerability with document.write', severity: 'high' },
|
|
96
|
+
{ pattern: /innerHTML\s*=/, title: 'Potential XSS via innerHTML', severity: 'medium' },
|
|
97
|
+
{ pattern: /password.*=.*['"][^'"]*['"]/, title: 'Hardcoded password', severity: 'critical' },
|
|
98
|
+
{ pattern: /api[_-]?key.*=.*['"][^'"]*['"]/, title: 'Hardcoded API key', severity: 'high' }
|
|
99
|
+
];
|
|
100
|
+
securityPatterns.forEach(({ pattern, title, severity }) => {
|
|
101
|
+
const matches = code.match(new RegExp(pattern.source, 'gi'));
|
|
102
|
+
if (matches) {
|
|
103
|
+
issues.push({
|
|
104
|
+
id: `issue-${issueId++}`,
|
|
105
|
+
type: 'security',
|
|
106
|
+
severity,
|
|
107
|
+
title,
|
|
108
|
+
description: `Found ${matches.length} instance(s) of ${title.toLowerCase()}`,
|
|
109
|
+
reasoning: 'Security vulnerabilities can lead to data breaches and system compromises',
|
|
110
|
+
suggestion: this.getSecuritySuggestion(pattern.source)
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// Performance issues
|
|
116
|
+
if (focusAreas.includes('performance')) {
|
|
117
|
+
const performancePatterns = [
|
|
118
|
+
{ pattern: /for\s*\([^)]*\.length[^)]*\)/, title: 'Array length calculated in loop', severity: 'medium' },
|
|
119
|
+
{ pattern: /document\.getElementById.*loop/s, title: 'DOM query in loop', severity: 'high' },
|
|
120
|
+
{ pattern: /\+\s*=['"].*['"]/, title: 'String concatenation in loop', severity: 'medium' }
|
|
121
|
+
];
|
|
122
|
+
performancePatterns.forEach(({ pattern, title, severity }) => {
|
|
123
|
+
if (pattern.test(code)) {
|
|
124
|
+
issues.push({
|
|
125
|
+
id: `issue-${issueId++}`,
|
|
126
|
+
type: 'performance',
|
|
127
|
+
severity,
|
|
128
|
+
title,
|
|
129
|
+
description: `Performance issue detected: ${title}`,
|
|
130
|
+
reasoning: 'This pattern can cause performance bottlenecks in large datasets',
|
|
131
|
+
suggestion: this.getPerformanceSuggestion(title)
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// Readability issues
|
|
137
|
+
if (focusAreas.includes('readability')) {
|
|
138
|
+
const lines = code.split('\n');
|
|
139
|
+
const longLines = lines.filter(line => line.length > 120);
|
|
140
|
+
if (longLines.length > 0) {
|
|
141
|
+
issues.push({
|
|
142
|
+
id: `issue-${issueId++}`,
|
|
143
|
+
type: 'readability',
|
|
144
|
+
severity: 'low',
|
|
145
|
+
title: `Long lines detected (${longLines.length})`,
|
|
146
|
+
description: 'Lines longer than 120 characters reduce readability',
|
|
147
|
+
reasoning: 'Shorter lines are easier to read and understand',
|
|
148
|
+
suggestion: 'Break long lines into multiple lines or extract complex expressions'
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
// Deep nesting detection
|
|
152
|
+
const maxNesting = this.calculateMaxNesting(code);
|
|
153
|
+
if (maxNesting > 4) {
|
|
154
|
+
issues.push({
|
|
155
|
+
id: `issue-${issueId++}`,
|
|
156
|
+
type: 'readability',
|
|
157
|
+
severity: maxNesting > 6 ? 'high' : 'medium',
|
|
158
|
+
title: `Deep nesting detected (${maxNesting} levels)`,
|
|
159
|
+
description: 'Deeply nested code is harder to understand and maintain',
|
|
160
|
+
reasoning: 'Excessive nesting increases cognitive load',
|
|
161
|
+
suggestion: 'Extract nested logic into separate functions or use early returns'
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Bug patterns
|
|
166
|
+
if (focusAreas.includes('bugs')) {
|
|
167
|
+
const bugPatterns = [
|
|
168
|
+
{ pattern: /==\s*null(?!\s*\|\||&&)/, title: 'Loose equality with null', severity: 'medium' },
|
|
169
|
+
{ pattern: /if\s*\([^)]*=\s*[^=]/, title: 'Assignment in if condition', severity: 'high' },
|
|
170
|
+
{ pattern: /catch\s*\([^)]*\)\s*\{\s*\}/, title: 'Empty catch block', severity: 'medium' }
|
|
171
|
+
];
|
|
172
|
+
bugPatterns.forEach(({ pattern, title, severity }) => {
|
|
173
|
+
if (pattern.test(code)) {
|
|
174
|
+
issues.push({
|
|
175
|
+
id: `issue-${issueId++}`,
|
|
176
|
+
type: 'bug',
|
|
177
|
+
severity,
|
|
178
|
+
title,
|
|
179
|
+
description: `Potential bug pattern: ${title}`,
|
|
180
|
+
reasoning: 'This pattern often leads to unexpected behavior',
|
|
181
|
+
suggestion: this.getBugSuggestion(title)
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return issues;
|
|
187
|
+
}
|
|
188
|
+
calculateMaxNesting(code) {
|
|
189
|
+
let maxNesting = 0;
|
|
190
|
+
let currentNesting = 0;
|
|
191
|
+
const lines = code.split('\n');
|
|
192
|
+
for (const line of lines) {
|
|
193
|
+
const trimmed = line.trim();
|
|
194
|
+
const openBraces = (trimmed.match(/\{/g) || []).length;
|
|
195
|
+
const closeBraces = (trimmed.match(/\}/g) || []).length;
|
|
196
|
+
currentNesting += openBraces - closeBraces;
|
|
197
|
+
maxNesting = Math.max(maxNesting, currentNesting);
|
|
198
|
+
}
|
|
199
|
+
return maxNesting;
|
|
200
|
+
}
|
|
201
|
+
getSecuritySuggestion(pattern) {
|
|
202
|
+
const suggestions = {
|
|
203
|
+
'eval': 'Use JSON.parse() for data parsing or safer alternatives to eval()',
|
|
204
|
+
'document.write': 'Use DOM manipulation methods like createElement() and appendChild()',
|
|
205
|
+
'innerHTML': 'Use textContent or create elements safely with createElement()',
|
|
206
|
+
'password': 'Use environment variables or secure configuration management',
|
|
207
|
+
'api[_-]?key': 'Store API keys in environment variables or secure vaults'
|
|
208
|
+
};
|
|
209
|
+
for (const [key, suggestion] of Object.entries(suggestions)) {
|
|
210
|
+
if (pattern.includes(key))
|
|
211
|
+
return suggestion;
|
|
212
|
+
}
|
|
213
|
+
return 'Review security implications and use safer alternatives';
|
|
214
|
+
}
|
|
215
|
+
getPerformanceSuggestion(title) {
|
|
216
|
+
if (title.includes('Array length')) {
|
|
217
|
+
return 'Cache array length: const len = array.length; for (let i = 0; i < len; i++)';
|
|
218
|
+
}
|
|
219
|
+
if (title.includes('DOM query')) {
|
|
220
|
+
return 'Cache DOM elements outside loops or use more efficient selectors';
|
|
221
|
+
}
|
|
222
|
+
if (title.includes('String concatenation')) {
|
|
223
|
+
return 'Use array.join() or template literals for multiple concatenations';
|
|
224
|
+
}
|
|
225
|
+
return 'Consider optimizing this pattern for better performance';
|
|
226
|
+
}
|
|
227
|
+
getBugSuggestion(title) {
|
|
228
|
+
if (title.includes('Loose equality')) {
|
|
229
|
+
return 'Use strict equality (=== or !==) instead of loose equality';
|
|
230
|
+
}
|
|
231
|
+
if (title.includes('Assignment in if')) {
|
|
232
|
+
return 'Use === for comparison or move assignment outside if condition';
|
|
233
|
+
}
|
|
234
|
+
if (title.includes('Empty catch')) {
|
|
235
|
+
return 'Handle errors appropriately or at least log them for debugging';
|
|
236
|
+
}
|
|
237
|
+
return 'Review this pattern to prevent potential bugs';
|
|
238
|
+
}
|
|
239
|
+
async generateSuggestions(code, issues, language, model) {
|
|
240
|
+
const suggestions = [];
|
|
241
|
+
let suggestionId = 1;
|
|
242
|
+
// Generate refactoring suggestions for high complexity
|
|
243
|
+
const lines = code.split('\n');
|
|
244
|
+
if (lines.length > 100) {
|
|
245
|
+
suggestions.push({
|
|
246
|
+
id: `suggestion-${suggestionId++}`,
|
|
247
|
+
type: 'refactor',
|
|
248
|
+
title: 'Extract functions from large file',
|
|
249
|
+
description: 'This file is quite large. Consider breaking it into smaller, focused modules.',
|
|
250
|
+
impact: 'high',
|
|
251
|
+
effort: 'moderate'
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
// Suggest modern language features
|
|
255
|
+
if (language === 'javascript' || language === 'typescript') {
|
|
256
|
+
if (code.includes('var ')) {
|
|
257
|
+
suggestions.push({
|
|
258
|
+
id: `suggestion-${suggestionId++}`,
|
|
259
|
+
type: 'modernize',
|
|
260
|
+
title: 'Replace var with const/let',
|
|
261
|
+
description: 'Use const for immutable values and let for mutable ones.',
|
|
262
|
+
beforeCode: 'var name = "value";',
|
|
263
|
+
afterCode: 'const name = "value";',
|
|
264
|
+
impact: 'medium',
|
|
265
|
+
effort: 'minimal'
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
if (code.includes('function(')) {
|
|
269
|
+
suggestions.push({
|
|
270
|
+
id: `suggestion-${suggestionId++}`,
|
|
271
|
+
type: 'modernize',
|
|
272
|
+
title: 'Consider arrow functions',
|
|
273
|
+
description: 'Arrow functions provide cleaner syntax for simple functions.',
|
|
274
|
+
beforeCode: 'array.map(function(item) { return item.name; })',
|
|
275
|
+
afterCode: 'array.map(item => item.name)',
|
|
276
|
+
impact: 'low',
|
|
277
|
+
effort: 'minimal'
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// Generate suggestions based on critical issues
|
|
282
|
+
const criticalIssues = issues.filter(issue => issue.severity === 'critical');
|
|
283
|
+
criticalIssues.forEach(issue => {
|
|
284
|
+
suggestions.push({
|
|
285
|
+
id: `suggestion-${suggestionId++}`,
|
|
286
|
+
type: 'refactor',
|
|
287
|
+
title: `Fix critical issue: ${issue.title}`,
|
|
288
|
+
description: `Address the critical ${issue.type} issue found in the code.`,
|
|
289
|
+
impact: 'high',
|
|
290
|
+
effort: 'moderate'
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
return suggestions;
|
|
294
|
+
}
|
|
295
|
+
async generateSocraticQuestions(code, issues, language) {
|
|
296
|
+
const questions = [];
|
|
297
|
+
// Questions based on code structure
|
|
298
|
+
const lines = code.split('\n').filter(line => line.trim()).length;
|
|
299
|
+
if (lines > 50) {
|
|
300
|
+
questions.push('What would happen if this file grew to 1000 lines? How would you maintain it?');
|
|
301
|
+
}
|
|
302
|
+
// Questions based on complexity
|
|
303
|
+
const complexityIssues = issues.filter(issue => issue.type === 'readability');
|
|
304
|
+
if (complexityIssues.length > 0) {
|
|
305
|
+
questions.push('Why is simple code often better than clever code?');
|
|
306
|
+
questions.push('How would a new team member understand this code in 6 months?');
|
|
307
|
+
}
|
|
308
|
+
// Questions based on security
|
|
309
|
+
const securityIssues = issues.filter(issue => issue.type === 'security');
|
|
310
|
+
if (securityIssues.length > 0) {
|
|
311
|
+
questions.push('What could an attacker do if they could control the input to this function?');
|
|
312
|
+
questions.push('How would you protect sensitive data in this implementation?');
|
|
313
|
+
}
|
|
314
|
+
// Questions based on performance
|
|
315
|
+
const performanceIssues = issues.filter(issue => issue.type === 'performance');
|
|
316
|
+
if (performanceIssues.length > 0) {
|
|
317
|
+
questions.push('What happens to performance when the data size increases by 100x?');
|
|
318
|
+
questions.push('Where would you expect bottlenecks to appear under load?');
|
|
319
|
+
}
|
|
320
|
+
// General architectural questions
|
|
321
|
+
questions.push('What assumptions is this code making about its environment?');
|
|
322
|
+
questions.push('How would you test the edge cases in this implementation?');
|
|
323
|
+
questions.push('What would break if the requirements changed slightly?');
|
|
324
|
+
return questions.slice(0, 5); // Limit to 5 questions
|
|
325
|
+
}
|
|
326
|
+
synthesizeReview(issues, suggestions, metrics, socraticQuestions) {
|
|
327
|
+
let synthesis = `## Code Review Summary\n\n`;
|
|
328
|
+
// Overview
|
|
329
|
+
synthesis += `**Code Metrics:**\n`;
|
|
330
|
+
synthesis += `- Lines of Code: ${metrics.linesOfCode}\n`;
|
|
331
|
+
synthesis += `- Complexity: ${metrics.complexity}\n`;
|
|
332
|
+
synthesis += `- Maintainability Score: ${metrics.maintainabilityScore}/100\n`;
|
|
333
|
+
synthesis += `- Technical Debt: ${metrics.technicalDebt}\n\n`;
|
|
334
|
+
// Issues breakdown
|
|
335
|
+
const criticalIssues = issues.filter(i => i.severity === 'critical');
|
|
336
|
+
const highIssues = issues.filter(i => i.severity === 'high');
|
|
337
|
+
const mediumIssues = issues.filter(i => i.severity === 'medium');
|
|
338
|
+
if (criticalIssues.length > 0) {
|
|
339
|
+
synthesis += `🚨 **Critical Issues (${criticalIssues.length}):** Immediate attention required\n`;
|
|
340
|
+
criticalIssues.forEach(issue => {
|
|
341
|
+
synthesis += `- ${issue.title}: ${issue.description}\n`;
|
|
342
|
+
});
|
|
343
|
+
synthesis += '\n';
|
|
344
|
+
}
|
|
345
|
+
if (highIssues.length > 0) {
|
|
346
|
+
synthesis += `⚠️ **High Priority Issues (${highIssues.length}):** Should be addressed soon\n`;
|
|
347
|
+
highIssues.slice(0, 3).forEach(issue => {
|
|
348
|
+
synthesis += `- ${issue.title}\n`;
|
|
349
|
+
});
|
|
350
|
+
synthesis += '\n';
|
|
351
|
+
}
|
|
352
|
+
// Top suggestions
|
|
353
|
+
const highImpactSuggestions = suggestions.filter(s => s.impact === 'high');
|
|
354
|
+
if (highImpactSuggestions.length > 0) {
|
|
355
|
+
synthesis += `💡 **Top Improvement Suggestions:**\n`;
|
|
356
|
+
highImpactSuggestions.slice(0, 3).forEach(suggestion => {
|
|
357
|
+
synthesis += `- ${suggestion.title} (${suggestion.effort} effort, ${suggestion.impact} impact)\n`;
|
|
358
|
+
});
|
|
359
|
+
synthesis += '\n';
|
|
360
|
+
}
|
|
361
|
+
// Learning opportunities
|
|
362
|
+
if (socraticQuestions.length > 0) {
|
|
363
|
+
synthesis += `🤔 **Questions to Consider:**\n`;
|
|
364
|
+
socraticQuestions.slice(0, 3).forEach(question => {
|
|
365
|
+
synthesis += `- ${question}\n`;
|
|
366
|
+
});
|
|
367
|
+
synthesis += '\n';
|
|
368
|
+
}
|
|
369
|
+
// Overall assessment
|
|
370
|
+
let overallScore = 'Good';
|
|
371
|
+
if (criticalIssues.length > 0 || metrics.maintainabilityScore < 50) {
|
|
372
|
+
overallScore = 'Needs Improvement';
|
|
373
|
+
}
|
|
374
|
+
else if (metrics.maintainabilityScore > 80 && highIssues.length === 0) {
|
|
375
|
+
overallScore = 'Excellent';
|
|
376
|
+
}
|
|
377
|
+
synthesis += `**Overall Assessment:** ${overallScore}\n`;
|
|
378
|
+
synthesis += `**Total Issues Found:** ${issues.length} (${criticalIssues.length} critical, ${highIssues.length} high, ${mediumIssues.length} medium)\n`;
|
|
379
|
+
synthesis += `**Improvement Suggestions:** ${suggestions.length}\n`;
|
|
380
|
+
return synthesis;
|
|
381
|
+
}
|
|
382
|
+
}
|