mcp-adr-analysis-server 2.0.21 → 2.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.
- package/README.md +94 -839
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/config/ai-config.d.ts.map +1 -1
- package/dist/src/config/ai-config.js +9 -9
- package/dist/src/config/ai-config.js.map +1 -1
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1594 -837
- package/dist/src/index.js.map +1 -1
- package/dist/src/prompts/analysis-prompts.d.ts +4 -1
- package/dist/src/prompts/analysis-prompts.d.ts.map +1 -1
- package/dist/src/prompts/analysis-prompts.js +61 -30
- package/dist/src/prompts/analysis-prompts.js.map +1 -1
- package/dist/src/prompts/index.d.ts +17 -1
- package/dist/src/prompts/index.d.ts.map +1 -1
- package/dist/src/prompts/index.js +325 -1
- package/dist/src/prompts/index.js.map +1 -1
- package/dist/src/prompts/rule-generation-prompts.d.ts +5 -1
- package/dist/src/prompts/rule-generation-prompts.d.ts.map +1 -1
- package/dist/src/prompts/rule-generation-prompts.js +5 -1
- package/dist/src/prompts/rule-generation-prompts.js.map +1 -1
- package/dist/src/prompts/security-prompts.d.ts +6 -1
- package/dist/src/prompts/security-prompts.d.ts.map +1 -1
- package/dist/src/prompts/security-prompts.js +6 -1
- package/dist/src/prompts/security-prompts.js.map +1 -1
- package/dist/src/prompts/todo-prompts.d.ts +49 -0
- package/dist/src/prompts/todo-prompts.d.ts.map +1 -0
- package/dist/src/prompts/todo-prompts.js +824 -0
- package/dist/src/prompts/todo-prompts.js.map +1 -0
- package/dist/src/resources/index.d.ts.map +1 -1
- package/dist/src/resources/index.js +9 -7
- package/dist/src/resources/index.js.map +1 -1
- package/dist/src/tools/adr-bootstrap-validation-tool.d.ts +47 -0
- package/dist/src/tools/adr-bootstrap-validation-tool.d.ts.map +1 -0
- package/dist/src/tools/adr-bootstrap-validation-tool.js +979 -0
- package/dist/src/tools/adr-bootstrap-validation-tool.js.map +1 -0
- package/dist/src/tools/adr-suggestion-tool.d.ts +1 -0
- package/dist/src/tools/adr-suggestion-tool.d.ts.map +1 -1
- package/dist/src/tools/adr-suggestion-tool.js +330 -32
- package/dist/src/tools/adr-suggestion-tool.js.map +1 -1
- package/dist/src/tools/content-masking-tool.d.ts +5 -0
- package/dist/src/tools/content-masking-tool.d.ts.map +1 -1
- package/dist/src/tools/content-masking-tool.js +631 -28
- package/dist/src/tools/content-masking-tool.js.map +1 -1
- package/dist/src/tools/deployment-readiness-tool.d.ts +8 -5
- package/dist/src/tools/deployment-readiness-tool.d.ts.map +1 -1
- package/dist/src/tools/deployment-readiness-tool.js +1017 -93
- package/dist/src/tools/deployment-readiness-tool.js.map +1 -1
- package/dist/src/tools/environment-analysis-tool.d.ts +4 -0
- package/dist/src/tools/environment-analysis-tool.d.ts.map +1 -1
- package/dist/src/tools/environment-analysis-tool.js +568 -24
- package/dist/src/tools/environment-analysis-tool.js.map +1 -1
- package/dist/src/tools/interactive-adr-planning-tool.d.ts.map +1 -1
- package/dist/src/tools/interactive-adr-planning-tool.js +270 -108
- package/dist/src/tools/interactive-adr-planning-tool.js.map +1 -1
- package/dist/src/tools/mcp-planning-tool.d.ts.map +1 -1
- package/dist/src/tools/mcp-planning-tool.js +316 -183
- package/dist/src/tools/mcp-planning-tool.js.map +1 -1
- package/dist/src/tools/memory-loading-tool.d.ts +60 -0
- package/dist/src/tools/memory-loading-tool.d.ts.map +1 -0
- package/dist/src/tools/memory-loading-tool.js +457 -0
- package/dist/src/tools/memory-loading-tool.js.map +1 -0
- package/dist/src/tools/research-integration-tool.d.ts +4 -1
- package/dist/src/tools/research-integration-tool.d.ts.map +1 -1
- package/dist/src/tools/research-integration-tool.js +5 -1
- package/dist/src/tools/research-integration-tool.js.map +1 -1
- package/dist/src/tools/review-existing-adrs-tool.d.ts +19 -0
- package/dist/src/tools/review-existing-adrs-tool.d.ts.map +1 -0
- package/dist/src/tools/review-existing-adrs-tool.js +1204 -0
- package/dist/src/tools/review-existing-adrs-tool.js.map +1 -0
- package/dist/src/tools/rule-generation-tool.d.ts +2 -0
- package/dist/src/tools/rule-generation-tool.d.ts.map +1 -1
- package/dist/src/tools/rule-generation-tool.js +274 -33
- package/dist/src/tools/rule-generation-tool.js.map +1 -1
- package/dist/src/tools/smart-git-push-tool-v2.d.ts +4 -0
- package/dist/src/tools/smart-git-push-tool-v2.d.ts.map +1 -1
- package/dist/src/tools/smart-git-push-tool-v2.js +423 -229
- package/dist/src/tools/smart-git-push-tool-v2.js.map +1 -1
- package/dist/src/tools/smart-git-push-tool.d.ts +3 -0
- package/dist/src/tools/smart-git-push-tool.d.ts.map +1 -1
- package/dist/src/tools/smart-git-push-tool.js +241 -235
- package/dist/src/tools/smart-git-push-tool.js.map +1 -1
- package/dist/src/tools/tool-chain-orchestrator.d.ts +2 -2
- package/dist/src/tools/tool-chain-orchestrator.d.ts.map +1 -1
- package/dist/src/tools/tool-chain-orchestrator.js +152 -93
- package/dist/src/tools/tool-chain-orchestrator.js.map +1 -1
- package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts +22 -13
- package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts.map +1 -1
- package/dist/src/tools/troubleshoot-guided-workflow-tool.js +660 -28
- package/dist/src/tools/troubleshoot-guided-workflow-tool.js.map +1 -1
- package/dist/src/types/ape-framework.d.ts +93 -0
- package/dist/src/types/ape-framework.d.ts.map +1 -1
- package/dist/src/types/ape-framework.js +10 -10
- package/dist/src/types/ape-framework.js.map +1 -1
- package/dist/src/types/enhanced-errors.d.ts +173 -0
- package/dist/src/types/enhanced-errors.d.ts.map +1 -0
- package/dist/src/types/enhanced-errors.js +668 -0
- package/dist/src/types/enhanced-errors.js.map +1 -0
- package/dist/src/types/index.d.ts +129 -3
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js +15 -0
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/knowledge-generation.d.ts +78 -0
- package/dist/src/types/knowledge-generation.d.ts.map +1 -1
- package/dist/src/types/knowledge-generation.js +10 -6
- package/dist/src/types/knowledge-generation.js.map +1 -1
- package/dist/src/types/knowledge-graph-schemas.d.ts +92 -0
- package/dist/src/types/knowledge-graph-schemas.d.ts.map +1 -1
- package/dist/src/types/knowledge-graph-schemas.js +45 -17
- package/dist/src/types/knowledge-graph-schemas.js.map +1 -1
- package/dist/src/types/memory-entities.d.ts +7209 -0
- package/dist/src/types/memory-entities.d.ts.map +1 -0
- package/dist/src/types/memory-entities.js +395 -0
- package/dist/src/types/memory-entities.js.map +1 -0
- package/dist/src/types/reflexion-framework.d.ts +44 -0
- package/dist/src/types/reflexion-framework.d.ts.map +1 -1
- package/dist/src/types/reflexion-framework.js +7 -7
- package/dist/src/types/reflexion-framework.js.map +1 -1
- package/dist/src/types/todo-json-schemas.d.ts +7 -653
- package/dist/src/types/todo-json-schemas.d.ts.map +1 -1
- package/dist/src/types/todo-json-schemas.js +6 -110
- package/dist/src/types/todo-json-schemas.js.map +1 -1
- package/dist/src/types/tool-arguments.d.ts +224 -0
- package/dist/src/types/tool-arguments.d.ts.map +1 -0
- package/dist/src/types/tool-arguments.js +6 -0
- package/dist/src/types/tool-arguments.js.map +1 -0
- package/dist/src/utils/actual-file-operations.d.ts.map +1 -1
- package/dist/src/utils/actual-file-operations.js +25 -9
- package/dist/src/utils/actual-file-operations.js.map +1 -1
- package/dist/src/utils/adr-discovery.d.ts +33 -1
- package/dist/src/utils/adr-discovery.d.ts.map +1 -1
- package/dist/src/utils/adr-discovery.js +14 -9
- package/dist/src/utils/adr-discovery.js.map +1 -1
- package/dist/src/utils/adr-suggestions.d.ts +72 -0
- package/dist/src/utils/adr-suggestions.d.ts.map +1 -1
- package/dist/src/utils/adr-suggestions.js +6 -0
- package/dist/src/utils/adr-suggestions.js.map +1 -1
- package/dist/src/utils/cache.d.ts.map +1 -1
- package/dist/src/utils/cache.js +22 -19
- package/dist/src/utils/cache.js.map +1 -1
- package/dist/src/utils/chain-of-thought-template.d.ts +13 -1
- package/dist/src/utils/chain-of-thought-template.d.ts.map +1 -1
- package/dist/src/utils/chain-of-thought-template.js +31 -22
- package/dist/src/utils/chain-of-thought-template.js.map +1 -1
- package/dist/src/utils/config.d.ts.map +1 -1
- package/dist/src/utils/config.js +1 -0
- package/dist/src/utils/config.js.map +1 -1
- package/dist/src/utils/directory-compat.js +1 -1
- package/dist/src/utils/directory-compat.js.map +1 -1
- package/dist/src/utils/enhanced-logging.d.ts +195 -0
- package/dist/src/utils/enhanced-logging.d.ts.map +1 -0
- package/dist/src/utils/enhanced-logging.js +449 -0
- package/dist/src/utils/enhanced-logging.js.map +1 -0
- package/dist/src/utils/file-system.d.ts +182 -34
- package/dist/src/utils/file-system.d.ts.map +1 -1
- package/dist/src/utils/file-system.js +648 -774
- package/dist/src/utils/file-system.js.map +1 -1
- package/dist/src/utils/gitleaks-detector.d.ts +50 -0
- package/dist/src/utils/gitleaks-detector.d.ts.map +1 -0
- package/dist/src/utils/gitleaks-detector.js +334 -0
- package/dist/src/utils/gitleaks-detector.js.map +1 -0
- package/dist/src/utils/interactive-approval.d.ts +1 -1
- package/dist/src/utils/interactive-approval.d.ts.map +1 -1
- package/dist/src/utils/interactive-approval.js +22 -17
- package/dist/src/utils/interactive-approval.js.map +1 -1
- package/dist/src/utils/json-safe.d.ts.map +1 -1
- package/dist/src/utils/json-safe.js +9 -6
- package/dist/src/utils/json-safe.js.map +1 -1
- package/dist/src/utils/knowledge-graph-manager.d.ts +37 -1
- package/dist/src/utils/knowledge-graph-manager.d.ts.map +1 -1
- package/dist/src/utils/knowledge-graph-manager.js +315 -70
- package/dist/src/utils/knowledge-graph-manager.js.map +1 -1
- package/dist/src/utils/location-filter.d.ts +35 -10
- package/dist/src/utils/location-filter.d.ts.map +1 -1
- package/dist/src/utils/location-filter.js +360 -94
- package/dist/src/utils/location-filter.js.map +1 -1
- package/dist/src/utils/mcp-response-validator.d.ts.map +1 -1
- package/dist/src/utils/mcp-response-validator.js +34 -19
- package/dist/src/utils/mcp-response-validator.js.map +1 -1
- package/dist/src/utils/memory-entity-manager.d.ts +134 -0
- package/dist/src/utils/memory-entity-manager.d.ts.map +1 -0
- package/dist/src/utils/memory-entity-manager.js +851 -0
- package/dist/src/utils/memory-entity-manager.js.map +1 -0
- package/dist/src/utils/memory-health-scoring.d.ts +125 -0
- package/dist/src/utils/memory-health-scoring.d.ts.map +1 -0
- package/dist/src/utils/memory-health-scoring.js +277 -0
- package/dist/src/utils/memory-health-scoring.js.map +1 -0
- package/dist/src/utils/memory-migration-manager.d.ts +93 -0
- package/dist/src/utils/memory-migration-manager.d.ts.map +1 -0
- package/dist/src/utils/memory-migration-manager.js +842 -0
- package/dist/src/utils/memory-migration-manager.js.map +1 -0
- package/dist/src/utils/memory-relationship-mapper.d.ts +87 -0
- package/dist/src/utils/memory-relationship-mapper.d.ts.map +1 -0
- package/dist/src/utils/memory-relationship-mapper.js +482 -0
- package/dist/src/utils/memory-relationship-mapper.js.map +1 -0
- package/dist/src/utils/memory-rollback-manager.d.ts +105 -0
- package/dist/src/utils/memory-rollback-manager.d.ts.map +1 -0
- package/dist/src/utils/memory-rollback-manager.js +575 -0
- package/dist/src/utils/memory-rollback-manager.js.map +1 -0
- package/dist/src/utils/memory-transformation.d.ts +59 -0
- package/dist/src/utils/memory-transformation.d.ts.map +1 -0
- package/dist/src/utils/memory-transformation.js +742 -0
- package/dist/src/utils/memory-transformation.js.map +1 -0
- package/dist/src/utils/output-masking.d.ts +12 -0
- package/dist/src/utils/output-masking.d.ts.map +1 -1
- package/dist/src/utils/output-masking.js +5 -0
- package/dist/src/utils/output-masking.js.map +1 -1
- package/dist/src/utils/prompt-execution.d.ts.map +1 -1
- package/dist/src/utils/prompt-execution.js +72 -51
- package/dist/src/utils/prompt-execution.js.map +1 -1
- package/dist/src/utils/release-readiness-detector.d.ts.map +1 -1
- package/dist/src/utils/release-readiness-detector.js +43 -42
- package/dist/src/utils/release-readiness-detector.js.map +1 -1
- package/dist/src/utils/research-integration.d.ts.map +1 -1
- package/dist/src/utils/research-integration.js +73 -44
- package/dist/src/utils/research-integration.js.map +1 -1
- package/dist/src/utils/research-questions.d.ts.map +1 -1
- package/dist/src/utils/research-questions.js +40 -14
- package/dist/src/utils/research-questions.js.map +1 -1
- package/dist/src/utils/ripgrep-wrapper.d.ts +84 -0
- package/dist/src/utils/ripgrep-wrapper.d.ts.map +1 -0
- package/dist/src/utils/ripgrep-wrapper.js +255 -0
- package/dist/src/utils/ripgrep-wrapper.js.map +1 -0
- package/dist/src/utils/rule-generation.d.ts.map +1 -1
- package/dist/src/utils/rule-generation.js +26 -15
- package/dist/src/utils/rule-generation.js.map +1 -1
- package/dist/src/utils/todo-file-watcher.d.ts +11 -23
- package/dist/src/utils/todo-file-watcher.d.ts.map +1 -1
- package/dist/src/utils/todo-file-watcher.js +18 -156
- package/dist/src/utils/todo-file-watcher.js.map +1 -1
- package/dist/src/utils/tree-sitter-analyzer.d.ts +185 -0
- package/dist/src/utils/tree-sitter-analyzer.d.ts.map +1 -0
- package/dist/src/utils/tree-sitter-analyzer.js +885 -0
- package/dist/src/utils/tree-sitter-analyzer.js.map +1 -0
- package/package.json +51 -10
- package/dist/src/tools/smart-score-tool.d.ts +0 -173
- package/dist/src/tools/smart-score-tool.d.ts.map +0 -1
- package/dist/src/tools/smart-score-tool.js +0 -681
- package/dist/src/tools/smart-score-tool.js.map +0 -1
- package/dist/src/tools/todo-management-tool-v2.d.ts +0 -368
- package/dist/src/tools/todo-management-tool-v2.d.ts.map +0 -1
- package/dist/src/tools/todo-management-tool-v2.js +0 -922
- package/dist/src/tools/todo-management-tool-v2.js.map +0 -1
- package/dist/src/utils/enhanced-sensitive-detector.d.ts +0 -61
- package/dist/src/utils/enhanced-sensitive-detector.d.ts.map +0 -1
- package/dist/src/utils/enhanced-sensitive-detector.js +0 -437
- package/dist/src/utils/enhanced-sensitive-detector.js.map +0 -1
- package/dist/src/utils/project-health-scoring.d.ts +0 -177
- package/dist/src/utils/project-health-scoring.d.ts.map +0 -1
- package/dist/src/utils/project-health-scoring.js +0 -370
- package/dist/src/utils/project-health-scoring.js.map +0 -1
- package/dist/src/utils/todo-json-manager.d.ts +0 -71
- package/dist/src/utils/todo-json-manager.d.ts.map +0 -1
- package/dist/src/utils/todo-json-manager.js +0 -396
- package/dist/src/utils/todo-json-manager.js.map +0 -1
- package/dist/src/utils/todo-markdown-converter.d.ts +0 -16
- package/dist/src/utils/todo-markdown-converter.d.ts.map +0 -1
- package/dist/src/utils/todo-markdown-converter.js +0 -362
- package/dist/src/utils/todo-markdown-converter.js.map +0 -1
- package/dist/src/utils/todo-migration.d.ts +0 -47
- package/dist/src/utils/todo-migration.d.ts.map +0 -1
- package/dist/src/utils/todo-migration.js +0 -261
- package/dist/src/utils/todo-migration.js.map +0 -1
|
@@ -0,0 +1,1204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool for reviewing existing ADRs against actual code implementation
|
|
3
|
+
* Validates ADR compliance, identifies gaps, and suggests updates
|
|
4
|
+
* Uses tree-sitter for accurate code analysis
|
|
5
|
+
*/
|
|
6
|
+
import { McpAdrError } from '../types/index.js';
|
|
7
|
+
import { TreeSitterAnalyzer } from '../utils/tree-sitter-analyzer.js';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import * as fs from 'fs/promises';
|
|
10
|
+
/**
|
|
11
|
+
* Review existing ADRs and validate against actual code implementation
|
|
12
|
+
*/
|
|
13
|
+
export async function reviewExistingAdrs(args) {
|
|
14
|
+
const { adrDirectory = 'docs/adrs', projectPath = process.cwd(), specificAdr, analysisDepth = 'detailed', includeTreeSitter = true, generateUpdatePlan = true, } = args;
|
|
15
|
+
try {
|
|
16
|
+
// Step 1: Discover existing ADRs
|
|
17
|
+
const { discoverAdrsInDirectory } = await import('../utils/adr-discovery.js');
|
|
18
|
+
const discoveryResult = await discoverAdrsInDirectory(adrDirectory, true, projectPath);
|
|
19
|
+
if (discoveryResult.totalAdrs === 0) {
|
|
20
|
+
return {
|
|
21
|
+
content: [
|
|
22
|
+
{
|
|
23
|
+
type: 'text',
|
|
24
|
+
text: `# ADR Review: No ADRs Found
|
|
25
|
+
|
|
26
|
+
## Discovery Results
|
|
27
|
+
- **Directory**: ${adrDirectory}
|
|
28
|
+
- **Project Path**: ${projectPath}
|
|
29
|
+
- **ADRs Found**: 0
|
|
30
|
+
|
|
31
|
+
## Recommendations
|
|
32
|
+
1. **Create Initial ADRs**: Use the \`suggest_adrs\` tool to identify architectural decisions
|
|
33
|
+
2. **Set Up ADR Directory**: Create the ADR directory structure
|
|
34
|
+
3. **Establish ADR Process**: Implement ADR workflow for future decisions
|
|
35
|
+
|
|
36
|
+
## Next Steps
|
|
37
|
+
\`\`\`json
|
|
38
|
+
{
|
|
39
|
+
"tool": "suggest_adrs",
|
|
40
|
+
"args": {
|
|
41
|
+
"projectPath": "${projectPath}",
|
|
42
|
+
"analysisType": "comprehensive"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
\`\`\`
|
|
46
|
+
`,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Step 2: Filter ADRs if specific one requested
|
|
52
|
+
const adrsToReview = specificAdr
|
|
53
|
+
? discoveryResult.adrs.filter(adr => adr.filename.includes(specificAdr) ||
|
|
54
|
+
adr.title.toLowerCase().includes(specificAdr.toLowerCase()))
|
|
55
|
+
: discoveryResult.adrs;
|
|
56
|
+
if (adrsToReview.length === 0) {
|
|
57
|
+
throw new McpAdrError(`No ADRs found matching: ${specificAdr}`, 'ADR_NOT_FOUND');
|
|
58
|
+
}
|
|
59
|
+
// Step 3: Analyze code structure
|
|
60
|
+
const codeAnalysis = await analyzeCodeStructure(projectPath, includeTreeSitter);
|
|
61
|
+
// Step 4: Review each ADR
|
|
62
|
+
const reviewResults = [];
|
|
63
|
+
for (const adr of adrsToReview) {
|
|
64
|
+
const reviewResult = await reviewSingleAdr(adr, codeAnalysis, analysisDepth, projectPath);
|
|
65
|
+
reviewResults.push(reviewResult);
|
|
66
|
+
}
|
|
67
|
+
// Step 5: Generate comprehensive report
|
|
68
|
+
const overallScore = reviewResults.reduce((sum, result) => sum + result.complianceScore, 0) / reviewResults.length;
|
|
69
|
+
const totalGaps = reviewResults.reduce((sum, result) => sum + result.codeCompliance.gaps.length, 0);
|
|
70
|
+
const needsUpdate = reviewResults.filter(result => result.recommendations.updateAdr).length;
|
|
71
|
+
const needsCodeChanges = reviewResults.filter(result => result.recommendations.updateCode).length;
|
|
72
|
+
let updatePlan = '';
|
|
73
|
+
if (generateUpdatePlan) {
|
|
74
|
+
updatePlan = await generateUpdatePlanContent(reviewResults, codeAnalysis, projectPath);
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
content: [
|
|
78
|
+
{
|
|
79
|
+
type: 'text',
|
|
80
|
+
text: `# ADR Compliance Review Report
|
|
81
|
+
|
|
82
|
+
## Overview
|
|
83
|
+
- **Project**: ${path.basename(projectPath)}
|
|
84
|
+
- **ADRs Reviewed**: ${reviewResults.length}
|
|
85
|
+
- **Overall Compliance Score**: ${overallScore.toFixed(1)}/10
|
|
86
|
+
- **Analysis Depth**: ${analysisDepth}
|
|
87
|
+
- **Tree-sitter Analysis**: ${includeTreeSitter ? '✅ Enabled' : '❌ Disabled'}
|
|
88
|
+
|
|
89
|
+
## Summary Statistics
|
|
90
|
+
- **Total Gaps Identified**: ${totalGaps}
|
|
91
|
+
- **ADRs Needing Updates**: ${needsUpdate}
|
|
92
|
+
- **Code Changes Required**: ${needsCodeChanges}
|
|
93
|
+
- **Full Compliance**: ${reviewResults.filter(r => r.complianceScore >= 8).length}
|
|
94
|
+
- **Partial Compliance**: ${reviewResults.filter(r => r.complianceScore >= 5 && r.complianceScore < 8).length}
|
|
95
|
+
- **Non-Compliance**: ${reviewResults.filter(r => r.complianceScore < 5).length}
|
|
96
|
+
|
|
97
|
+
## Detailed Reviews
|
|
98
|
+
|
|
99
|
+
${reviewResults
|
|
100
|
+
.map(result => `
|
|
101
|
+
### ${result.title}
|
|
102
|
+
- **File**: ${path.basename(result.adrPath)}
|
|
103
|
+
- **Status**: ${result.status}
|
|
104
|
+
- **Compliance Score**: ${result.complianceScore}/10
|
|
105
|
+
|
|
106
|
+
#### Implementation Status
|
|
107
|
+
- **Implemented**: ${result.codeCompliance.implemented ? '✅' : '❌'}
|
|
108
|
+
- **Partially Implemented**: ${result.codeCompliance.partiallyImplemented ? '⚠️' : '❌'}
|
|
109
|
+
- **Not Implemented**: ${result.codeCompliance.notImplemented ? '🚨' : '✅'}
|
|
110
|
+
|
|
111
|
+
#### Evidence Found
|
|
112
|
+
${result.codeCompliance.evidence.length > 0
|
|
113
|
+
? result.codeCompliance.evidence.map(e => `- ${e}`).join('\n')
|
|
114
|
+
: '- No supporting evidence found in codebase'}
|
|
115
|
+
|
|
116
|
+
#### Gaps Identified
|
|
117
|
+
${result.codeCompliance.gaps.length > 0
|
|
118
|
+
? result.codeCompliance.gaps.map(g => `- ${g}`).join('\n')
|
|
119
|
+
: '- No gaps identified'}
|
|
120
|
+
|
|
121
|
+
#### Recommendations
|
|
122
|
+
${result.recommendations.actions.map(a => `- ${a}`).join('\n')}
|
|
123
|
+
|
|
124
|
+
#### Analysis
|
|
125
|
+
${result.analysis}
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
`)
|
|
129
|
+
.join('\n')}
|
|
130
|
+
|
|
131
|
+
## Code Structure Analysis
|
|
132
|
+
- **Files Analyzed**: ${codeAnalysis.files.length}
|
|
133
|
+
- **Technologies Detected**: ${codeAnalysis.technologies.join(', ')}
|
|
134
|
+
- **Architectural Patterns**: ${codeAnalysis.patterns.join(', ')}
|
|
135
|
+
|
|
136
|
+
### Architectural Elements
|
|
137
|
+
- **APIs**: ${codeAnalysis.architecturalElements.apis?.length || 0}
|
|
138
|
+
- **Databases**: ${codeAnalysis.architecturalElements.databases?.length || 0}
|
|
139
|
+
- **Frameworks**: ${codeAnalysis.architecturalElements.frameworks?.length || 0}
|
|
140
|
+
- **Patterns**: ${codeAnalysis.architecturalElements.patterns?.length || 0}
|
|
141
|
+
- **Infrastructure Resources**: ${codeAnalysis.architecturalElements.infrastructureResources?.length || 0}
|
|
142
|
+
- **DevOps Tools**: ${codeAnalysis.architecturalElements.devopsTools?.length || 0}
|
|
143
|
+
|
|
144
|
+
### Enterprise Security Analysis (Tree-sitter)
|
|
145
|
+
${includeTreeSitter
|
|
146
|
+
? `
|
|
147
|
+
- **Security Findings**: ${codeAnalysis.architecturalElements.securityFindings?.length || 0}
|
|
148
|
+
${(codeAnalysis.architecturalElements.securityFindings?.length || 0) > 0
|
|
149
|
+
? `
|
|
150
|
+
#### Critical Security Issues:
|
|
151
|
+
${codeAnalysis.architecturalElements
|
|
152
|
+
.securityFindings.slice(0, 10)
|
|
153
|
+
.map((finding) => `- ${finding}`)
|
|
154
|
+
.join('\n')}
|
|
155
|
+
${(codeAnalysis.architecturalElements.securityFindings.length || 0) > 10 ? `\n*... and ${(codeAnalysis.architecturalElements.securityFindings.length || 0) - 10} more security findings*` : ''}
|
|
156
|
+
`
|
|
157
|
+
: '- ✅ No security issues detected'}
|
|
158
|
+
`
|
|
159
|
+
: '- Tree-sitter security analysis disabled'}
|
|
160
|
+
|
|
161
|
+
### DevOps Stack Analysis
|
|
162
|
+
${includeTreeSitter && (codeAnalysis.architecturalElements.infrastructureResources?.length || 0) > 0
|
|
163
|
+
? `
|
|
164
|
+
#### Infrastructure Resources:
|
|
165
|
+
${codeAnalysis.architecturalElements
|
|
166
|
+
.infrastructureResources.slice(0, 10)
|
|
167
|
+
.map((resource) => `- ${resource}`)
|
|
168
|
+
.join('\n')}
|
|
169
|
+
${(codeAnalysis.architecturalElements.infrastructureResources.length || 0) > 10 ? `\n*... and ${(codeAnalysis.architecturalElements.infrastructureResources.length || 0) - 10} more resources*` : ''}
|
|
170
|
+
`
|
|
171
|
+
: '- No infrastructure resources detected'}
|
|
172
|
+
|
|
173
|
+
${includeTreeSitter && (codeAnalysis.architecturalElements.devopsTools?.length || 0) > 0
|
|
174
|
+
? `
|
|
175
|
+
#### DevOps Tools Detected:
|
|
176
|
+
${codeAnalysis.architecturalElements
|
|
177
|
+
.devopsTools.slice(0, 10)
|
|
178
|
+
.map((tool) => `- ${tool}`)
|
|
179
|
+
.join('\n')}
|
|
180
|
+
${(codeAnalysis.architecturalElements.devopsTools.length || 0) > 10 ? `\n*... and ${(codeAnalysis.architecturalElements.devopsTools.length || 0) - 10} more tools*` : ''}
|
|
181
|
+
`
|
|
182
|
+
: '- No DevOps tools detected'}
|
|
183
|
+
|
|
184
|
+
${generateUpdatePlan ? updatePlan : ''}
|
|
185
|
+
|
|
186
|
+
## Next Steps
|
|
187
|
+
|
|
188
|
+
### Immediate Actions (High Priority)
|
|
189
|
+
${reviewResults
|
|
190
|
+
.filter(r => r.complianceScore < 5)
|
|
191
|
+
.map(r => `- **${r.title}**: ${r.recommendations.actions[0] || 'Requires immediate attention'}`)
|
|
192
|
+
.join('\n') || '- No immediate actions required'}
|
|
193
|
+
|
|
194
|
+
### Medium Priority
|
|
195
|
+
${reviewResults
|
|
196
|
+
.filter(r => r.complianceScore >= 5 && r.complianceScore < 8)
|
|
197
|
+
.map(r => `- **${r.title}**: ${r.recommendations.actions[0] || 'Minor updates needed'}`)
|
|
198
|
+
.join('\n') || '- No medium priority items'}
|
|
199
|
+
|
|
200
|
+
### Maintenance
|
|
201
|
+
${reviewResults
|
|
202
|
+
.filter(r => r.complianceScore >= 8)
|
|
203
|
+
.map(r => `- **${r.title}**: Well implemented, monitor for changes`)
|
|
204
|
+
.join('\n') || '- No items in maintenance status'}
|
|
205
|
+
|
|
206
|
+
## Quality Assessment
|
|
207
|
+
|
|
208
|
+
### Best Practices Compliance
|
|
209
|
+
- **Documentation Quality**: ${calculateDocumentationQuality(reviewResults)}/10
|
|
210
|
+
- **Implementation Fidelity**: ${calculateImplementationFidelity(reviewResults)}/10
|
|
211
|
+
- **Architectural Consistency**: ${calculateArchitecturalConsistency(reviewResults)}/10
|
|
212
|
+
|
|
213
|
+
### Recommendations for Process Improvement
|
|
214
|
+
1. **Regular ADR Reviews**: Schedule quarterly compliance reviews
|
|
215
|
+
2. **Automated Validation**: Implement CI/CD checks for ADR compliance
|
|
216
|
+
3. **Developer Training**: Ensure team understands ADR importance
|
|
217
|
+
4. **Template Updates**: Standardize ADR format for better tracking
|
|
218
|
+
|
|
219
|
+
## Tools for Follow-up
|
|
220
|
+
|
|
221
|
+
### Update Specific ADRs
|
|
222
|
+
\`\`\`json
|
|
223
|
+
{
|
|
224
|
+
"tool": "generate_adr_from_decision",
|
|
225
|
+
"args": {
|
|
226
|
+
"decisionData": {
|
|
227
|
+
"title": "Updated [ADR Title]",
|
|
228
|
+
"context": "Review findings and current implementation",
|
|
229
|
+
"decision": "Refined decision based on analysis",
|
|
230
|
+
"consequences": "Updated consequences from review"
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
\`\`\`
|
|
235
|
+
|
|
236
|
+
### Generate Implementation Plan
|
|
237
|
+
\`\`\`json
|
|
238
|
+
{
|
|
239
|
+
"tool": "generate_implementation_plan",
|
|
240
|
+
"args": {
|
|
241
|
+
"adrPath": "[specific ADR path]",
|
|
242
|
+
"includeCodeChanges": true,
|
|
243
|
+
"priority": "high"
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
\`\`\`
|
|
247
|
+
`,
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
throw new McpAdrError(`Failed to review ADRs: ${error instanceof Error ? error.message : String(error)}`, 'REVIEW_ERROR');
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Analyze code structure to understand current implementation
|
|
258
|
+
* Enhanced with fast-glob for efficient file discovery
|
|
259
|
+
*/
|
|
260
|
+
async function analyzeCodeStructure(projectPath, useTreeSitter) {
|
|
261
|
+
const result = {
|
|
262
|
+
files: [],
|
|
263
|
+
patterns: [],
|
|
264
|
+
technologies: [],
|
|
265
|
+
architecturalElements: {
|
|
266
|
+
apis: [],
|
|
267
|
+
databases: [],
|
|
268
|
+
frameworks: [],
|
|
269
|
+
patterns: [],
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
try {
|
|
273
|
+
// Enhanced file system analysis using fast-glob
|
|
274
|
+
const { analyzeProjectStructure } = await import('../utils/file-system.js');
|
|
275
|
+
// Use the new analyzeProjectStructure function for comprehensive analysis
|
|
276
|
+
const projectAnalysis = await analyzeProjectStructure(projectPath);
|
|
277
|
+
// Extract file paths from the analysis
|
|
278
|
+
result.files = projectAnalysis.files.map(f => f.path);
|
|
279
|
+
result.technologies = projectAnalysis.technologies;
|
|
280
|
+
result.patterns = projectAnalysis.patterns;
|
|
281
|
+
// Legacy pattern detection for backward compatibility
|
|
282
|
+
const legacyPatterns = await detectArchitecturalPatterns(result.files);
|
|
283
|
+
result.patterns = [...new Set([...result.patterns, ...legacyPatterns])];
|
|
284
|
+
// If tree-sitter is enabled, perform detailed analysis
|
|
285
|
+
if (useTreeSitter) {
|
|
286
|
+
const detailedAnalysis = await performTreeSitterAnalysis(result.files);
|
|
287
|
+
result.architecturalElements = detailedAnalysis;
|
|
288
|
+
}
|
|
289
|
+
return result;
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
console.warn('Enhanced code analysis failed, falling back to legacy:', error);
|
|
293
|
+
// Fallback to legacy implementation
|
|
294
|
+
try {
|
|
295
|
+
const files = await findSourceFiles(projectPath);
|
|
296
|
+
result.files = files;
|
|
297
|
+
result.technologies = await detectTechnologies(projectPath);
|
|
298
|
+
result.patterns = await detectArchitecturalPatterns(files);
|
|
299
|
+
if (useTreeSitter) {
|
|
300
|
+
const detailedAnalysis = await performTreeSitterAnalysis(files);
|
|
301
|
+
result.architecturalElements = detailedAnalysis;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
catch (fallbackError) {
|
|
305
|
+
console.warn('Legacy code analysis also failed:', fallbackError);
|
|
306
|
+
}
|
|
307
|
+
return result;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Review a single ADR against code implementation
|
|
312
|
+
* Enhanced with Smart Code Linking to find related files
|
|
313
|
+
*/
|
|
314
|
+
async function reviewSingleAdr(adr, codeAnalysis, depth, projectPath) {
|
|
315
|
+
const result = {
|
|
316
|
+
adrPath: adr.path,
|
|
317
|
+
title: adr.title,
|
|
318
|
+
status: adr.status,
|
|
319
|
+
complianceScore: 0,
|
|
320
|
+
codeCompliance: {
|
|
321
|
+
implemented: false,
|
|
322
|
+
partiallyImplemented: false,
|
|
323
|
+
notImplemented: false,
|
|
324
|
+
evidence: [],
|
|
325
|
+
gaps: [],
|
|
326
|
+
},
|
|
327
|
+
recommendations: {
|
|
328
|
+
updateAdr: false,
|
|
329
|
+
updateCode: false,
|
|
330
|
+
createPlan: false,
|
|
331
|
+
actions: [],
|
|
332
|
+
},
|
|
333
|
+
analysis: '',
|
|
334
|
+
};
|
|
335
|
+
try {
|
|
336
|
+
// Parse ADR content for key architectural elements
|
|
337
|
+
const adrElements = extractAdrElements(adr.content || '');
|
|
338
|
+
// SMART CODE LINKING: Find related code files for this specific ADR
|
|
339
|
+
let relatedFiles = [];
|
|
340
|
+
try {
|
|
341
|
+
const { findRelatedCode } = await import('../utils/file-system.js');
|
|
342
|
+
const relatedCodeResult = await findRelatedCode(adr.path, adr.content || '', projectPath, {
|
|
343
|
+
useAI: true,
|
|
344
|
+
useRipgrep: true,
|
|
345
|
+
maxFiles: 25,
|
|
346
|
+
includeContent: false,
|
|
347
|
+
});
|
|
348
|
+
relatedFiles = relatedCodeResult.relatedFiles;
|
|
349
|
+
// Add Smart Code Linking results to evidence
|
|
350
|
+
if (relatedFiles.length > 0) {
|
|
351
|
+
result.codeCompliance.evidence.push(`Smart Code Linking found ${relatedFiles.length} related files (confidence: ${(relatedCodeResult.confidence * 100).toFixed(0)}%)`);
|
|
352
|
+
// Add top related files as evidence
|
|
353
|
+
const topFiles = relatedFiles.slice(0, 5);
|
|
354
|
+
topFiles.forEach(file => {
|
|
355
|
+
result.codeCompliance.evidence.push(`Related: ${file.path}`);
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
result.codeCompliance.gaps.push('No related code files found using Smart Code Linking');
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
console.warn('Smart Code Linking failed:', error);
|
|
364
|
+
result.codeCompliance.gaps.push('Smart Code Linking unavailable - manual review required');
|
|
365
|
+
}
|
|
366
|
+
// Compare ADR elements with code implementation (enhanced with related files)
|
|
367
|
+
const complianceAnalysis = await analyzeCompliance(adrElements, codeAnalysis, relatedFiles);
|
|
368
|
+
// Merge Smart Code Linking evidence with compliance analysis
|
|
369
|
+
result.codeCompliance.evidence.push(...complianceAnalysis.evidence);
|
|
370
|
+
result.codeCompliance.gaps.push(...complianceAnalysis.gaps);
|
|
371
|
+
result.codeCompliance.implemented = complianceAnalysis.implemented || relatedFiles.length > 0;
|
|
372
|
+
result.codeCompliance.partiallyImplemented =
|
|
373
|
+
complianceAnalysis.partiallyImplemented ||
|
|
374
|
+
(relatedFiles.length > 0 && relatedFiles.length < 5);
|
|
375
|
+
result.codeCompliance.notImplemented =
|
|
376
|
+
complianceAnalysis.notImplemented && relatedFiles.length === 0;
|
|
377
|
+
result.complianceScore = calculateComplianceScore(result.codeCompliance);
|
|
378
|
+
// Generate recommendations (enhanced with Smart Code Linking insights)
|
|
379
|
+
result.recommendations = generateRecommendations(result.codeCompliance, result.complianceScore, relatedFiles);
|
|
380
|
+
// Generate detailed analysis (include Smart Code Linking results)
|
|
381
|
+
result.analysis = generateDetailedAnalysis(adrElements, result.codeCompliance, depth, relatedFiles);
|
|
382
|
+
return result;
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
result.analysis = `Error analyzing ADR: ${error instanceof Error ? error.message : String(error)}`;
|
|
386
|
+
return result;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Extract architectural elements from ADR content
|
|
391
|
+
*/
|
|
392
|
+
function extractAdrElements(content) {
|
|
393
|
+
const elements = {
|
|
394
|
+
technologies: [],
|
|
395
|
+
apis: [],
|
|
396
|
+
databases: [],
|
|
397
|
+
patterns: [],
|
|
398
|
+
components: [],
|
|
399
|
+
constraints: [],
|
|
400
|
+
decisions: [],
|
|
401
|
+
};
|
|
402
|
+
// Extract from different sections of the ADR
|
|
403
|
+
const sections = {
|
|
404
|
+
context: extractSection(content, 'context'),
|
|
405
|
+
decision: extractSection(content, 'decision'),
|
|
406
|
+
consequences: extractSection(content, 'consequences'),
|
|
407
|
+
alternatives: extractSection(content, 'alternatives'),
|
|
408
|
+
};
|
|
409
|
+
// Technology extraction patterns
|
|
410
|
+
const techPatterns = [
|
|
411
|
+
/\b(React|Vue|Angular|Node\.js|Express|FastAPI|Django|Spring|Rails)\b/gi,
|
|
412
|
+
/\b(PostgreSQL|MySQL|MongoDB|Redis|Elasticsearch)\b/gi,
|
|
413
|
+
/\b(Docker|Kubernetes|AWS|Azure|GCP)\b/gi,
|
|
414
|
+
];
|
|
415
|
+
// API patterns
|
|
416
|
+
const apiPatterns = [
|
|
417
|
+
/\b(REST|GraphQL|gRPC|WebSocket)\b/gi,
|
|
418
|
+
/\b(API|endpoint|service|microservice)\b/gi,
|
|
419
|
+
];
|
|
420
|
+
// Extract elements from each section
|
|
421
|
+
for (const [, sectionContent] of Object.entries(sections)) {
|
|
422
|
+
if (sectionContent) {
|
|
423
|
+
elements.technologies.push(...extractMatches(sectionContent, techPatterns));
|
|
424
|
+
elements.apis.push(...extractMatches(sectionContent, apiPatterns));
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return elements;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Extract section content from ADR
|
|
431
|
+
*/
|
|
432
|
+
function extractSection(content, sectionName) {
|
|
433
|
+
const regex = new RegExp(`##\\s*${sectionName}[^#]*`, 'gi');
|
|
434
|
+
const match = content.match(regex);
|
|
435
|
+
return match ? match[0] : null;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Extract matches from content using patterns
|
|
439
|
+
*/
|
|
440
|
+
function extractMatches(content, patterns) {
|
|
441
|
+
const matches = [];
|
|
442
|
+
patterns.forEach(pattern => {
|
|
443
|
+
const found = content.match(pattern);
|
|
444
|
+
if (found) {
|
|
445
|
+
matches.push(...found);
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
return [...new Set(matches)]; // Remove duplicates
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Analyze compliance between ADR and code
|
|
452
|
+
*/
|
|
453
|
+
async function analyzeCompliance(adrElements, codeAnalysis, relatedFiles = []) {
|
|
454
|
+
const compliance = {
|
|
455
|
+
implemented: false,
|
|
456
|
+
partiallyImplemented: false,
|
|
457
|
+
notImplemented: false,
|
|
458
|
+
evidence: [],
|
|
459
|
+
gaps: [],
|
|
460
|
+
};
|
|
461
|
+
// Check technology alignment
|
|
462
|
+
const adrTechs = adrElements.technologies || [];
|
|
463
|
+
const codeTechs = codeAnalysis.technologies || [];
|
|
464
|
+
const techMatches = adrTechs.filter((tech) => codeTechs.some((codeTech) => codeTech.toLowerCase().includes(tech.toLowerCase()) ||
|
|
465
|
+
tech.toLowerCase().includes(codeTech.toLowerCase())));
|
|
466
|
+
if (techMatches.length > 0) {
|
|
467
|
+
compliance.evidence.push(`Technologies implemented: ${techMatches.join(', ')}`);
|
|
468
|
+
}
|
|
469
|
+
const missingTechs = adrTechs.filter((tech) => !techMatches.includes(tech));
|
|
470
|
+
if (missingTechs.length > 0) {
|
|
471
|
+
compliance.gaps.push(`Missing technologies: ${missingTechs.join(', ')}`);
|
|
472
|
+
}
|
|
473
|
+
// Smart Code Linking analysis: check if related files provide additional evidence
|
|
474
|
+
if (relatedFiles.length > 0) {
|
|
475
|
+
compliance.evidence.push(`Smart Code Linking identified ${relatedFiles.length} potentially related files`);
|
|
476
|
+
// Analyze file extensions to infer technologies used in related files
|
|
477
|
+
const relatedExtensions = [...new Set(relatedFiles.map((f) => f.extension))];
|
|
478
|
+
const relatedTechHints = relatedExtensions
|
|
479
|
+
.map(ext => {
|
|
480
|
+
switch (ext) {
|
|
481
|
+
case '.ts':
|
|
482
|
+
case '.tsx':
|
|
483
|
+
return 'TypeScript';
|
|
484
|
+
case '.js':
|
|
485
|
+
case '.jsx':
|
|
486
|
+
return 'JavaScript';
|
|
487
|
+
case '.py':
|
|
488
|
+
return 'Python';
|
|
489
|
+
case '.java':
|
|
490
|
+
return 'Java';
|
|
491
|
+
case '.cs':
|
|
492
|
+
return 'C#';
|
|
493
|
+
case '.go':
|
|
494
|
+
return 'Go';
|
|
495
|
+
case '.rs':
|
|
496
|
+
return 'Rust';
|
|
497
|
+
default:
|
|
498
|
+
return null;
|
|
499
|
+
}
|
|
500
|
+
})
|
|
501
|
+
.filter(Boolean);
|
|
502
|
+
if (relatedTechHints.length > 0) {
|
|
503
|
+
compliance.evidence.push(`Related files suggest technologies: ${relatedTechHints.join(', ')}`);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
compliance.gaps.push('No related files found - implementation may not exist');
|
|
508
|
+
}
|
|
509
|
+
// Check API implementation
|
|
510
|
+
const adrApis = adrElements.apis || [];
|
|
511
|
+
const codeApis = codeAnalysis.architecturalElements.apis || [];
|
|
512
|
+
const apiMatches = adrApis.filter((api) => codeApis.some((codeApi) => codeApi.toLowerCase().includes(api.toLowerCase())));
|
|
513
|
+
if (apiMatches.length > 0) {
|
|
514
|
+
compliance.evidence.push(`APIs implemented: ${apiMatches.join(', ')}`);
|
|
515
|
+
}
|
|
516
|
+
// Determine overall compliance status
|
|
517
|
+
const totalElements = adrTechs.length + adrApis.length;
|
|
518
|
+
const implementedElements = techMatches.length + apiMatches.length;
|
|
519
|
+
if (implementedElements === totalElements && totalElements > 0) {
|
|
520
|
+
compliance.implemented = true;
|
|
521
|
+
}
|
|
522
|
+
else if (implementedElements > 0) {
|
|
523
|
+
compliance.partiallyImplemented = true;
|
|
524
|
+
}
|
|
525
|
+
else {
|
|
526
|
+
compliance.notImplemented = true;
|
|
527
|
+
}
|
|
528
|
+
return compliance;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Calculate compliance score
|
|
532
|
+
*/
|
|
533
|
+
function calculateComplianceScore(compliance) {
|
|
534
|
+
if (compliance.implemented)
|
|
535
|
+
return 9;
|
|
536
|
+
if (compliance.partiallyImplemented)
|
|
537
|
+
return 6;
|
|
538
|
+
if (compliance.notImplemented)
|
|
539
|
+
return 2;
|
|
540
|
+
return 5; // Default/unknown
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Generate recommendations based on compliance analysis
|
|
544
|
+
*/
|
|
545
|
+
function generateRecommendations(compliance, score, relatedFiles = []) {
|
|
546
|
+
const recommendations = {
|
|
547
|
+
updateAdr: false,
|
|
548
|
+
updateCode: false,
|
|
549
|
+
createPlan: false,
|
|
550
|
+
actions: [],
|
|
551
|
+
};
|
|
552
|
+
if (score < 5) {
|
|
553
|
+
recommendations.createPlan = true;
|
|
554
|
+
recommendations.actions.push('Create implementation plan for missing elements');
|
|
555
|
+
recommendations.actions.push('Consider updating ADR if decisions have changed');
|
|
556
|
+
}
|
|
557
|
+
if (compliance.gaps.length > 0) {
|
|
558
|
+
recommendations.updateCode = true;
|
|
559
|
+
recommendations.actions.push('Implement missing architectural elements');
|
|
560
|
+
}
|
|
561
|
+
if (score < 7) {
|
|
562
|
+
recommendations.updateAdr = true;
|
|
563
|
+
recommendations.actions.push('Update ADR to reflect current implementation');
|
|
564
|
+
}
|
|
565
|
+
// Smart Code Linking enhancements
|
|
566
|
+
if (relatedFiles.length > 0) {
|
|
567
|
+
recommendations.actions.push(`Review ${relatedFiles.length} related files identified by Smart Code Linking`);
|
|
568
|
+
if (relatedFiles.length > 10) {
|
|
569
|
+
recommendations.actions.push('Consider refactoring - many files may indicate coupling issues');
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
recommendations.actions.push('Use Smart Code Linking to identify implementation files');
|
|
574
|
+
}
|
|
575
|
+
return recommendations;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Generate detailed analysis text
|
|
579
|
+
*/
|
|
580
|
+
function generateDetailedAnalysis(adrElements, compliance, depth, relatedFiles = []) {
|
|
581
|
+
let analysis = '';
|
|
582
|
+
if (depth === 'comprehensive') {
|
|
583
|
+
analysis += `
|
|
584
|
+
**Architectural Elements Analysis:**
|
|
585
|
+
- Technologies mentioned: ${adrElements.technologies?.length || 0}
|
|
586
|
+
- APIs referenced: ${adrElements.apis?.length || 0}
|
|
587
|
+
- Implementation evidence: ${compliance.evidence.length}
|
|
588
|
+
- Identified gaps: ${compliance.gaps.length}
|
|
589
|
+
|
|
590
|
+
**Smart Code Linking Results:**
|
|
591
|
+
- Related files found: ${relatedFiles.length}
|
|
592
|
+
${relatedFiles.length > 0
|
|
593
|
+
? `- Top related files:\n${relatedFiles
|
|
594
|
+
.slice(0, 3)
|
|
595
|
+
.map((f) => ` • ${f.path} (${f.name})`)
|
|
596
|
+
.join('\n')}`
|
|
597
|
+
: '- No related files identified'}
|
|
598
|
+
|
|
599
|
+
**Compliance Details:**
|
|
600
|
+
${compliance.evidence.map((e) => `✅ ${e}`).join('\n')}
|
|
601
|
+
${compliance.gaps.map((g) => `❌ ${g}`).join('\n')}
|
|
602
|
+
`;
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
analysis = `Implementation status: ${compliance.implemented
|
|
606
|
+
? 'Fully implemented'
|
|
607
|
+
: compliance.partiallyImplemented
|
|
608
|
+
? 'Partially implemented'
|
|
609
|
+
: 'Not implemented'}. Smart Code Linking found ${relatedFiles.length} related files.`;
|
|
610
|
+
}
|
|
611
|
+
return analysis;
|
|
612
|
+
}
|
|
613
|
+
// Helper functions for code analysis
|
|
614
|
+
async function findSourceFiles(projectPath) {
|
|
615
|
+
const files = [];
|
|
616
|
+
const extensions = ['.ts', '.js', '.py', '.java', '.cs', '.go', '.rs', '.rb'];
|
|
617
|
+
try {
|
|
618
|
+
const entries = await fs.readdir(projectPath, { withFileTypes: true });
|
|
619
|
+
for (const entry of entries) {
|
|
620
|
+
if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
|
|
621
|
+
const subFiles = await findSourceFiles(path.join(projectPath, entry.name));
|
|
622
|
+
files.push(...subFiles);
|
|
623
|
+
}
|
|
624
|
+
else if (entry.isFile() && extensions.some(ext => entry.name.endsWith(ext))) {
|
|
625
|
+
files.push(path.join(projectPath, entry.name));
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
catch (error) {
|
|
630
|
+
console.warn('Warning reading directory:', error);
|
|
631
|
+
}
|
|
632
|
+
return files;
|
|
633
|
+
}
|
|
634
|
+
async function detectTechnologies(projectPath) {
|
|
635
|
+
const technologies = [];
|
|
636
|
+
try {
|
|
637
|
+
// Check package.json for Node.js technologies
|
|
638
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
639
|
+
try {
|
|
640
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
|
|
641
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
642
|
+
Object.keys(deps).forEach(dep => {
|
|
643
|
+
if (dep.includes('react'))
|
|
644
|
+
technologies.push('React');
|
|
645
|
+
if (dep.includes('vue'))
|
|
646
|
+
technologies.push('Vue');
|
|
647
|
+
if (dep.includes('angular'))
|
|
648
|
+
technologies.push('Angular');
|
|
649
|
+
if (dep.includes('express'))
|
|
650
|
+
technologies.push('Express');
|
|
651
|
+
if (dep.includes('fastify'))
|
|
652
|
+
technologies.push('Fastify');
|
|
653
|
+
// Cloud SDKs
|
|
654
|
+
if (dep.includes('aws-sdk') || dep.includes('@aws-sdk'))
|
|
655
|
+
technologies.push('AWS SDK');
|
|
656
|
+
if (dep.includes('google-cloud') || dep.includes('@google-cloud'))
|
|
657
|
+
technologies.push('GCP SDK');
|
|
658
|
+
if (dep.includes('azure') || dep.includes('@azure'))
|
|
659
|
+
technologies.push('Azure SDK');
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
catch {
|
|
663
|
+
// package.json not found or invalid
|
|
664
|
+
}
|
|
665
|
+
// Check for other technology indicators
|
|
666
|
+
const files = await fs.readdir(projectPath);
|
|
667
|
+
// Container technologies
|
|
668
|
+
if (files.includes('Dockerfile'))
|
|
669
|
+
technologies.push('Docker');
|
|
670
|
+
if (files.includes('docker-compose.yml') || files.includes('docker-compose.yaml'))
|
|
671
|
+
technologies.push('Docker Compose');
|
|
672
|
+
// Kubernetes
|
|
673
|
+
if (files.includes('kubernetes.yaml') || files.includes('k8s.yaml'))
|
|
674
|
+
technologies.push('Kubernetes');
|
|
675
|
+
if (files.some(f => f.endsWith('.yaml') || f.endsWith('.yml'))) {
|
|
676
|
+
const yamlFiles = files.filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
|
|
677
|
+
for (const yamlFile of yamlFiles) {
|
|
678
|
+
try {
|
|
679
|
+
const content = await fs.readFile(path.join(projectPath, yamlFile), 'utf-8');
|
|
680
|
+
if (content.includes('apiVersion:') && content.includes('kind:')) {
|
|
681
|
+
technologies.push('Kubernetes');
|
|
682
|
+
break;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
catch {
|
|
686
|
+
// Skip unreadable files
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
// Infrastructure as Code
|
|
691
|
+
if (files.some(f => f.endsWith('.tf') || f.endsWith('.tfvars')))
|
|
692
|
+
technologies.push('Terraform');
|
|
693
|
+
if (files.includes('cloudformation.yaml') || files.includes('cloudformation.yml'))
|
|
694
|
+
technologies.push('CloudFormation');
|
|
695
|
+
if (files.includes('ansible.yml') || files.includes('playbook.yml'))
|
|
696
|
+
technologies.push('Ansible');
|
|
697
|
+
// Cloud-specific files
|
|
698
|
+
if (files.includes('.aws') || files.includes('aws-config.yml'))
|
|
699
|
+
technologies.push('AWS');
|
|
700
|
+
if (files.includes('gcp-config.json') || files.includes('.gcp'))
|
|
701
|
+
technologies.push('GCP');
|
|
702
|
+
if (files.includes('azure-pipelines.yml') || files.includes('.azure'))
|
|
703
|
+
technologies.push('Azure');
|
|
704
|
+
// DevOps and CI/CD
|
|
705
|
+
if (files.includes('.github'))
|
|
706
|
+
technologies.push('GitHub Actions');
|
|
707
|
+
if (files.includes('.gitlab-ci.yml'))
|
|
708
|
+
technologies.push('GitLab CI');
|
|
709
|
+
if (files.includes('Jenkinsfile'))
|
|
710
|
+
technologies.push('Jenkins');
|
|
711
|
+
if (files.includes('azure-pipelines.yml'))
|
|
712
|
+
technologies.push('Azure DevOps');
|
|
713
|
+
// Monitoring and observability
|
|
714
|
+
if (files.includes('prometheus.yml'))
|
|
715
|
+
technologies.push('Prometheus');
|
|
716
|
+
if (files.includes('grafana.yml') || files.includes('grafana.json'))
|
|
717
|
+
technologies.push('Grafana');
|
|
718
|
+
if (files.includes('jaeger.yml'))
|
|
719
|
+
technologies.push('Jaeger');
|
|
720
|
+
// Language-specific
|
|
721
|
+
if (files.includes('requirements.txt'))
|
|
722
|
+
technologies.push('Python');
|
|
723
|
+
if (files.includes('Gemfile'))
|
|
724
|
+
technologies.push('Ruby');
|
|
725
|
+
if (files.includes('pom.xml'))
|
|
726
|
+
technologies.push('Maven/Java');
|
|
727
|
+
if (files.includes('Cargo.toml'))
|
|
728
|
+
technologies.push('Rust');
|
|
729
|
+
if (files.includes('go.mod'))
|
|
730
|
+
technologies.push('Go');
|
|
731
|
+
// Check for cloud provider specific directories/files recursively
|
|
732
|
+
await checkCloudProviderIndicators(projectPath, technologies);
|
|
733
|
+
}
|
|
734
|
+
catch (error) {
|
|
735
|
+
console.warn('Technology detection warning:', error);
|
|
736
|
+
}
|
|
737
|
+
return [...new Set(technologies)];
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* Enhanced cloud provider detection based on Tosin Akinosho's expertise
|
|
741
|
+
* Principal Solution Architect at RedHat, specializing in AWS, GCP, Azure, Docker, Kubernetes, Terraform
|
|
742
|
+
*/
|
|
743
|
+
async function checkCloudProviderIndicators(projectPath, technologies) {
|
|
744
|
+
try {
|
|
745
|
+
const entries = await fs.readdir(projectPath, { withFileTypes: true });
|
|
746
|
+
for (const entry of entries) {
|
|
747
|
+
if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
|
|
748
|
+
const dirPath = path.join(projectPath, entry.name);
|
|
749
|
+
// AWS indicators
|
|
750
|
+
if (entry.name.includes('aws') ||
|
|
751
|
+
entry.name.includes('lambda') ||
|
|
752
|
+
entry.name.includes('ec2')) {
|
|
753
|
+
technologies.push('AWS');
|
|
754
|
+
}
|
|
755
|
+
// GCP indicators
|
|
756
|
+
if (entry.name.includes('gcp') ||
|
|
757
|
+
entry.name.includes('google-cloud') ||
|
|
758
|
+
entry.name.includes('gke')) {
|
|
759
|
+
technologies.push('GCP');
|
|
760
|
+
}
|
|
761
|
+
// Azure indicators
|
|
762
|
+
if (entry.name.includes('azure') || entry.name.includes('aks')) {
|
|
763
|
+
technologies.push('Azure');
|
|
764
|
+
}
|
|
765
|
+
// Kubernetes indicators
|
|
766
|
+
if (entry.name.includes('k8s') ||
|
|
767
|
+
entry.name.includes('kubernetes') ||
|
|
768
|
+
entry.name.includes('helm')) {
|
|
769
|
+
technologies.push('Kubernetes');
|
|
770
|
+
}
|
|
771
|
+
// Terraform indicators
|
|
772
|
+
if (entry.name.includes('terraform') || entry.name.includes('tf')) {
|
|
773
|
+
technologies.push('Terraform');
|
|
774
|
+
}
|
|
775
|
+
// Check for terraform files in subdirectories
|
|
776
|
+
try {
|
|
777
|
+
const subFiles = await fs.readdir(dirPath);
|
|
778
|
+
if (subFiles.some(f => f.endsWith('.tf') || f.endsWith('.tfvars'))) {
|
|
779
|
+
technologies.push('Terraform');
|
|
780
|
+
}
|
|
781
|
+
if (subFiles.some(f => f.includes('helm') || f.endsWith('.yaml') || f.endsWith('.yml'))) {
|
|
782
|
+
// Check if it's Kubernetes YAML
|
|
783
|
+
for (const file of subFiles.filter(f => f.endsWith('.yaml') || f.endsWith('.yml'))) {
|
|
784
|
+
try {
|
|
785
|
+
const content = await fs.readFile(path.join(dirPath, file), 'utf-8');
|
|
786
|
+
if (content.includes('apiVersion:') && content.includes('kind:')) {
|
|
787
|
+
technologies.push('Kubernetes');
|
|
788
|
+
break;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
catch {
|
|
792
|
+
// Skip unreadable files
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
catch {
|
|
798
|
+
// Skip unreadable directories
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
catch (error) {
|
|
804
|
+
console.warn('Cloud provider detection warning:', error);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
async function detectArchitecturalPatterns(files) {
|
|
808
|
+
const patterns = [];
|
|
809
|
+
// Pattern detection based on file structure
|
|
810
|
+
const fileNames = files.map(f => path.basename(f).toLowerCase());
|
|
811
|
+
const filePaths = files.map(f => f.toLowerCase());
|
|
812
|
+
// Traditional software patterns
|
|
813
|
+
if (fileNames.some(name => name.includes('controller')))
|
|
814
|
+
patterns.push('MVC');
|
|
815
|
+
if (fileNames.some(name => name.includes('service')))
|
|
816
|
+
patterns.push('Service Layer');
|
|
817
|
+
if (fileNames.some(name => name.includes('repository')))
|
|
818
|
+
patterns.push('Repository Pattern');
|
|
819
|
+
if (fileNames.some(name => name.includes('factory')))
|
|
820
|
+
patterns.push('Factory Pattern');
|
|
821
|
+
if (fileNames.some(name => name.includes('adapter')))
|
|
822
|
+
patterns.push('Adapter Pattern');
|
|
823
|
+
if (fileNames.some(name => name.includes('facade')))
|
|
824
|
+
patterns.push('Facade Pattern');
|
|
825
|
+
if (fileNames.some(name => name.includes('observer')))
|
|
826
|
+
patterns.push('Observer Pattern');
|
|
827
|
+
// Cloud and DevOps patterns (specialized for Tosin's expertise)
|
|
828
|
+
// Microservices patterns
|
|
829
|
+
if (filePaths.some(path => path.includes('microservice') || path.includes('service'))) {
|
|
830
|
+
patterns.push('Microservices Architecture');
|
|
831
|
+
}
|
|
832
|
+
// Container patterns
|
|
833
|
+
if (fileNames.some(name => name.includes('dockerfile')))
|
|
834
|
+
patterns.push('Containerization');
|
|
835
|
+
if (fileNames.some(name => name.includes('docker-compose')))
|
|
836
|
+
patterns.push('Multi-Container Application');
|
|
837
|
+
// Kubernetes patterns
|
|
838
|
+
if (fileNames.some(name => name.includes('deployment.yaml') || name.includes('deployment.yml'))) {
|
|
839
|
+
patterns.push('Kubernetes Deployment');
|
|
840
|
+
}
|
|
841
|
+
if (fileNames.some(name => name.includes('service.yaml') || name.includes('service.yml'))) {
|
|
842
|
+
patterns.push('Kubernetes Service Mesh');
|
|
843
|
+
}
|
|
844
|
+
if (fileNames.some(name => name.includes('ingress')))
|
|
845
|
+
patterns.push('Ingress Controller');
|
|
846
|
+
if (fileNames.some(name => name.includes('configmap') || name.includes('secret'))) {
|
|
847
|
+
patterns.push('Configuration Management');
|
|
848
|
+
}
|
|
849
|
+
// Infrastructure as Code patterns
|
|
850
|
+
if (fileNames.some(name => name.includes('.tf') || name.includes('terraform'))) {
|
|
851
|
+
patterns.push('Infrastructure as Code (Terraform)');
|
|
852
|
+
}
|
|
853
|
+
if (fileNames.some(name => name.includes('cloudformation'))) {
|
|
854
|
+
patterns.push('Infrastructure as Code (CloudFormation)');
|
|
855
|
+
}
|
|
856
|
+
// Cloud-native patterns
|
|
857
|
+
if (fileNames.some(name => name.includes('lambda') || name.includes('function'))) {
|
|
858
|
+
patterns.push('Serverless/FaaS');
|
|
859
|
+
}
|
|
860
|
+
if (fileNames.some(name => name.includes('api-gateway') || name.includes('gateway'))) {
|
|
861
|
+
patterns.push('API Gateway');
|
|
862
|
+
}
|
|
863
|
+
if (fileNames.some(name => name.includes('load-balancer') || name.includes('alb') || name.includes('nlb'))) {
|
|
864
|
+
patterns.push('Load Balancing');
|
|
865
|
+
}
|
|
866
|
+
// DevOps patterns
|
|
867
|
+
if (fileNames.some(name => name.includes('pipeline') || name.includes('ci') || name.includes('cd'))) {
|
|
868
|
+
patterns.push('CI/CD Pipeline');
|
|
869
|
+
}
|
|
870
|
+
if (fileNames.some(name => name.includes('ansible') || name.includes('playbook'))) {
|
|
871
|
+
patterns.push('Configuration Management (Ansible)');
|
|
872
|
+
}
|
|
873
|
+
// Monitoring and observability patterns
|
|
874
|
+
if (fileNames.some(name => name.includes('prometheus') || name.includes('metrics'))) {
|
|
875
|
+
patterns.push('Metrics Collection');
|
|
876
|
+
}
|
|
877
|
+
if (fileNames.some(name => name.includes('grafana') || name.includes('dashboard'))) {
|
|
878
|
+
patterns.push('Observability Dashboard');
|
|
879
|
+
}
|
|
880
|
+
if (fileNames.some(name => name.includes('jaeger') || name.includes('zipkin') || name.includes('tracing'))) {
|
|
881
|
+
patterns.push('Distributed Tracing');
|
|
882
|
+
}
|
|
883
|
+
if (fileNames.some(name => name.includes('logging') || name.includes('fluentd') || name.includes('logstash'))) {
|
|
884
|
+
patterns.push('Centralized Logging');
|
|
885
|
+
}
|
|
886
|
+
// Cloud provider specific patterns
|
|
887
|
+
if (fileNames.some(name => name.includes('vpc') || name.includes('subnet'))) {
|
|
888
|
+
patterns.push('Virtual Private Cloud');
|
|
889
|
+
}
|
|
890
|
+
if (fileNames.some(name => name.includes('s3') || name.includes('bucket'))) {
|
|
891
|
+
patterns.push('Object Storage');
|
|
892
|
+
}
|
|
893
|
+
if (fileNames.some(name => name.includes('rds') || name.includes('database'))) {
|
|
894
|
+
patterns.push('Managed Database');
|
|
895
|
+
}
|
|
896
|
+
if (fileNames.some(name => name.includes('eks') || name.includes('gke') || name.includes('aks'))) {
|
|
897
|
+
patterns.push('Managed Kubernetes');
|
|
898
|
+
}
|
|
899
|
+
// Security patterns
|
|
900
|
+
if (fileNames.some(name => name.includes('iam') || name.includes('rbac'))) {
|
|
901
|
+
patterns.push('Identity and Access Management');
|
|
902
|
+
}
|
|
903
|
+
if (fileNames.some(name => name.includes('security-group') || name.includes('firewall'))) {
|
|
904
|
+
patterns.push('Network Security');
|
|
905
|
+
}
|
|
906
|
+
if (fileNames.some(name => name.includes('vault') || name.includes('secrets'))) {
|
|
907
|
+
patterns.push('Secret Management');
|
|
908
|
+
}
|
|
909
|
+
// Data patterns
|
|
910
|
+
if (fileNames.some(name => name.includes('etl') || name.includes('pipeline'))) {
|
|
911
|
+
patterns.push('Data Pipeline');
|
|
912
|
+
}
|
|
913
|
+
if (fileNames.some(name => name.includes('kafka') || name.includes('pubsub') || name.includes('queue'))) {
|
|
914
|
+
patterns.push('Event-Driven Architecture');
|
|
915
|
+
}
|
|
916
|
+
return [...new Set(patterns)];
|
|
917
|
+
}
|
|
918
|
+
async function performTreeSitterAnalysis(files) {
|
|
919
|
+
const analyzer = new TreeSitterAnalyzer();
|
|
920
|
+
const architecturalElements = {
|
|
921
|
+
apis: [],
|
|
922
|
+
databases: [],
|
|
923
|
+
frameworks: [],
|
|
924
|
+
patterns: [],
|
|
925
|
+
securityFindings: [],
|
|
926
|
+
infrastructureResources: [],
|
|
927
|
+
devopsTools: [],
|
|
928
|
+
};
|
|
929
|
+
try {
|
|
930
|
+
for (const filePath of files.slice(0, 50)) {
|
|
931
|
+
// Limit to first 50 files for performance
|
|
932
|
+
try {
|
|
933
|
+
const analysis = await analyzer.analyzeFile(filePath);
|
|
934
|
+
// Extract API endpoints and routes
|
|
935
|
+
if (analysis.functions) {
|
|
936
|
+
analysis.functions.forEach(func => {
|
|
937
|
+
if (func.name && isApiFunction(func.name)) {
|
|
938
|
+
architecturalElements.apis.push(`${func.name} (${filePath})`);
|
|
939
|
+
}
|
|
940
|
+
// Enhanced: Add security-sensitive functions
|
|
941
|
+
if (func.securitySensitive) {
|
|
942
|
+
architecturalElements.securityFindings.push(`Security-sensitive function: ${func.name} in ${filePath}`);
|
|
943
|
+
}
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
// Enhanced database and framework detection
|
|
947
|
+
if (analysis.imports) {
|
|
948
|
+
analysis.imports.forEach(imp => {
|
|
949
|
+
if (isDatabaseImport(imp.module)) {
|
|
950
|
+
architecturalElements.databases.push(`${imp.module} (${filePath})`);
|
|
951
|
+
}
|
|
952
|
+
if (isFrameworkImport(imp.module)) {
|
|
953
|
+
architecturalElements.frameworks.push(`${imp.module} (${filePath})`);
|
|
954
|
+
}
|
|
955
|
+
// Enhanced: Add DevOps tools detection
|
|
956
|
+
if (isDevOpsImport(imp.module)) {
|
|
957
|
+
architecturalElements.devopsTools.push(`${imp.module} (${filePath})`);
|
|
958
|
+
}
|
|
959
|
+
// Enhanced: Track dangerous imports
|
|
960
|
+
if (imp.isDangerous) {
|
|
961
|
+
architecturalElements.securityFindings.push(`Dangerous import: ${imp.module} in ${filePath}${imp.reason ? ` - ${imp.reason}` : ''}`);
|
|
962
|
+
}
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
// Enhanced infrastructure analysis for enterprise DevOps
|
|
966
|
+
if (analysis.infraStructure) {
|
|
967
|
+
analysis.infraStructure.forEach(infra => {
|
|
968
|
+
architecturalElements.patterns.push(`${infra.resourceType}: ${infra.name} (${infra.provider})`);
|
|
969
|
+
architecturalElements.infrastructureResources.push(`${infra.provider}: ${infra.resourceType} (${filePath})`);
|
|
970
|
+
// Enhanced: Track security risks in infrastructure
|
|
971
|
+
if (infra.securityRisks.length > 0) {
|
|
972
|
+
infra.securityRisks.forEach(risk => {
|
|
973
|
+
architecturalElements.securityFindings.push(`Infrastructure security risk in ${filePath}: ${risk}`);
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
// Enhanced security analysis
|
|
979
|
+
if (analysis.hasSecrets) {
|
|
980
|
+
analysis.secrets.forEach(secret => {
|
|
981
|
+
architecturalElements.securityFindings.push(`${secret.type} detected in ${filePath} at line ${secret.location.line} (confidence: ${secret.confidence})`);
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
// Enhanced: Security issues from tree-sitter analysis
|
|
985
|
+
if (analysis.securityIssues && analysis.securityIssues.length > 0) {
|
|
986
|
+
analysis.securityIssues.forEach(issue => {
|
|
987
|
+
architecturalElements.securityFindings.push(`${issue.severity.toUpperCase()}: ${issue.message} in ${filePath} at line ${issue.location.line}`);
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
// Enhanced: Architectural violations
|
|
991
|
+
if (analysis.architecturalViolations && analysis.architecturalViolations.length > 0) {
|
|
992
|
+
analysis.architecturalViolations.forEach(violation => {
|
|
993
|
+
architecturalElements.patterns.push(`Architectural violation in ${filePath}: ${violation.message}`);
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
// Enhanced: Track language-specific patterns
|
|
997
|
+
if (analysis.language) {
|
|
998
|
+
switch (analysis.language) {
|
|
999
|
+
case 'python':
|
|
1000
|
+
architecturalElements.patterns.push(`Python microservice detected (${filePath})`);
|
|
1001
|
+
break;
|
|
1002
|
+
case 'typescript':
|
|
1003
|
+
case 'javascript':
|
|
1004
|
+
architecturalElements.patterns.push(`Node.js application detected (${filePath})`);
|
|
1005
|
+
break;
|
|
1006
|
+
case 'yaml':
|
|
1007
|
+
architecturalElements.patterns.push(`Configuration/Infrastructure YAML (${filePath})`);
|
|
1008
|
+
break;
|
|
1009
|
+
case 'hcl':
|
|
1010
|
+
architecturalElements.patterns.push(`Terraform infrastructure (${filePath})`);
|
|
1011
|
+
break;
|
|
1012
|
+
case 'dockerfile':
|
|
1013
|
+
architecturalElements.patterns.push(`Container configuration (${filePath})`);
|
|
1014
|
+
break;
|
|
1015
|
+
case 'bash':
|
|
1016
|
+
architecturalElements.patterns.push(`Shell automation script (${filePath})`);
|
|
1017
|
+
break;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
catch (fileError) {
|
|
1022
|
+
// Gracefully skip files that can't be analyzed
|
|
1023
|
+
console.warn(`Skipping file analysis for ${filePath}:`, fileError);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
// Deduplicate results
|
|
1027
|
+
architecturalElements.apis = [...new Set(architecturalElements.apis)];
|
|
1028
|
+
architecturalElements.databases = [...new Set(architecturalElements.databases)];
|
|
1029
|
+
architecturalElements.frameworks = [...new Set(architecturalElements.frameworks)];
|
|
1030
|
+
architecturalElements.patterns = [...new Set(architecturalElements.patterns)];
|
|
1031
|
+
architecturalElements.securityFindings = [...new Set(architecturalElements.securityFindings)];
|
|
1032
|
+
architecturalElements.infrastructureResources = [
|
|
1033
|
+
...new Set(architecturalElements.infrastructureResources),
|
|
1034
|
+
];
|
|
1035
|
+
architecturalElements.devopsTools = [...new Set(architecturalElements.devopsTools)];
|
|
1036
|
+
return architecturalElements;
|
|
1037
|
+
}
|
|
1038
|
+
catch (error) {
|
|
1039
|
+
console.warn('Tree-sitter analysis failed, using fallback:', error);
|
|
1040
|
+
return {
|
|
1041
|
+
apis: [],
|
|
1042
|
+
databases: [],
|
|
1043
|
+
frameworks: [],
|
|
1044
|
+
patterns: [],
|
|
1045
|
+
securityFindings: [],
|
|
1046
|
+
infrastructureResources: [],
|
|
1047
|
+
devopsTools: [],
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Helper functions for intelligent detection
|
|
1053
|
+
*/
|
|
1054
|
+
function isApiFunction(name) {
|
|
1055
|
+
const apiPatterns = [
|
|
1056
|
+
/^(get|post|put|delete|patch)_/i,
|
|
1057
|
+
/^handle_/i,
|
|
1058
|
+
/^endpoint_/i,
|
|
1059
|
+
/^route_/i,
|
|
1060
|
+
/^api_/i,
|
|
1061
|
+
/controller$/i,
|
|
1062
|
+
/handler$/i,
|
|
1063
|
+
];
|
|
1064
|
+
return apiPatterns.some(pattern => pattern.test(name));
|
|
1065
|
+
}
|
|
1066
|
+
function isDatabaseImport(module) {
|
|
1067
|
+
const dbPatterns = [
|
|
1068
|
+
'mongoose',
|
|
1069
|
+
'sequelize',
|
|
1070
|
+
'typeorm',
|
|
1071
|
+
'prisma',
|
|
1072
|
+
'knex',
|
|
1073
|
+
'mongodb',
|
|
1074
|
+
'mysql',
|
|
1075
|
+
'postgresql',
|
|
1076
|
+
'sqlite',
|
|
1077
|
+
'redis',
|
|
1078
|
+
'firebase',
|
|
1079
|
+
'dynamodb',
|
|
1080
|
+
'cassandra',
|
|
1081
|
+
'neo4j',
|
|
1082
|
+
'psycopg2',
|
|
1083
|
+
'pymongo',
|
|
1084
|
+
'sqlalchemy',
|
|
1085
|
+
'django.db',
|
|
1086
|
+
];
|
|
1087
|
+
return dbPatterns.some(pattern => module.toLowerCase().includes(pattern));
|
|
1088
|
+
}
|
|
1089
|
+
function isFrameworkImport(module) {
|
|
1090
|
+
const frameworkPatterns = [
|
|
1091
|
+
'express',
|
|
1092
|
+
'fastify',
|
|
1093
|
+
'koa',
|
|
1094
|
+
'hapi',
|
|
1095
|
+
'nest',
|
|
1096
|
+
'flask',
|
|
1097
|
+
'django',
|
|
1098
|
+
'fastapi',
|
|
1099
|
+
'tornado',
|
|
1100
|
+
'spring',
|
|
1101
|
+
'gin',
|
|
1102
|
+
'echo',
|
|
1103
|
+
'fiber',
|
|
1104
|
+
'react',
|
|
1105
|
+
'vue',
|
|
1106
|
+
'angular',
|
|
1107
|
+
'svelte',
|
|
1108
|
+
'next',
|
|
1109
|
+
'nuxt',
|
|
1110
|
+
'gatsby',
|
|
1111
|
+
];
|
|
1112
|
+
return frameworkPatterns.some(pattern => module.toLowerCase().includes(pattern));
|
|
1113
|
+
}
|
|
1114
|
+
function isDevOpsImport(module) {
|
|
1115
|
+
const devopsPatterns = [
|
|
1116
|
+
'docker',
|
|
1117
|
+
'kubernetes',
|
|
1118
|
+
'terraform',
|
|
1119
|
+
'ansible',
|
|
1120
|
+
'helm',
|
|
1121
|
+
'aws-sdk',
|
|
1122
|
+
'@aws-sdk',
|
|
1123
|
+
'boto3',
|
|
1124
|
+
'azure',
|
|
1125
|
+
'@azure',
|
|
1126
|
+
'google-cloud',
|
|
1127
|
+
'@google-cloud',
|
|
1128
|
+
'gcp',
|
|
1129
|
+
'prometheus',
|
|
1130
|
+
'grafana',
|
|
1131
|
+
'jaeger',
|
|
1132
|
+
'zipkin',
|
|
1133
|
+
'jenkins',
|
|
1134
|
+
'gitlab',
|
|
1135
|
+
'github',
|
|
1136
|
+
'ci',
|
|
1137
|
+
'cd',
|
|
1138
|
+
'vault',
|
|
1139
|
+
'consul',
|
|
1140
|
+
'etcd',
|
|
1141
|
+
'redis',
|
|
1142
|
+
'nginx',
|
|
1143
|
+
'elasticsearch',
|
|
1144
|
+
'logstash',
|
|
1145
|
+
'kibana',
|
|
1146
|
+
'fluentd',
|
|
1147
|
+
'kafka',
|
|
1148
|
+
'rabbitmq',
|
|
1149
|
+
'celery',
|
|
1150
|
+
'airflow',
|
|
1151
|
+
];
|
|
1152
|
+
return devopsPatterns.some(pattern => module.toLowerCase().includes(pattern));
|
|
1153
|
+
}
|
|
1154
|
+
async function generateUpdatePlanContent(reviewResults, _codeAnalysis, _projectPath) {
|
|
1155
|
+
const highPriority = reviewResults.filter(r => r.complianceScore < 5);
|
|
1156
|
+
const mediumPriority = reviewResults.filter(r => r.complianceScore >= 5 && r.complianceScore < 8);
|
|
1157
|
+
return `
|
|
1158
|
+
## Update Plan
|
|
1159
|
+
|
|
1160
|
+
### Phase 1: Critical Updates (${highPriority.length} ADRs)
|
|
1161
|
+
${highPriority
|
|
1162
|
+
.map(adr => `
|
|
1163
|
+
- **${adr.title}**
|
|
1164
|
+
- Score: ${adr.complianceScore}/10
|
|
1165
|
+
- Actions: ${adr.recommendations.actions.join(', ')}
|
|
1166
|
+
- Timeline: Immediate (1-2 weeks)
|
|
1167
|
+
`)
|
|
1168
|
+
.join('\n')}
|
|
1169
|
+
|
|
1170
|
+
### Phase 2: Moderate Updates (${mediumPriority.length} ADRs)
|
|
1171
|
+
${mediumPriority
|
|
1172
|
+
.map(adr => `
|
|
1173
|
+
- **${adr.title}**
|
|
1174
|
+
- Score: ${adr.complianceScore}/10
|
|
1175
|
+
- Actions: ${adr.recommendations.actions.join(', ')}
|
|
1176
|
+
- Timeline: Medium term (2-4 weeks)
|
|
1177
|
+
`)
|
|
1178
|
+
.join('\n')}
|
|
1179
|
+
|
|
1180
|
+
### Implementation Strategy
|
|
1181
|
+
1. **Document Review**: Update ADRs with current implementation status
|
|
1182
|
+
2. **Code Alignment**: Implement missing architectural elements
|
|
1183
|
+
3. **Process Improvement**: Establish regular ADR compliance checks
|
|
1184
|
+
4. **Team Training**: Ensure understanding of ADR importance
|
|
1185
|
+
|
|
1186
|
+
### Success Metrics
|
|
1187
|
+
- Target compliance score: 8.0+
|
|
1188
|
+
- Gap reduction: 80%
|
|
1189
|
+
- Process adherence: 95%
|
|
1190
|
+
`;
|
|
1191
|
+
}
|
|
1192
|
+
function calculateDocumentationQuality(results) {
|
|
1193
|
+
// Simplified calculation based on compliance scores
|
|
1194
|
+
return results.reduce((sum, r) => sum + r.complianceScore, 0) / results.length;
|
|
1195
|
+
}
|
|
1196
|
+
function calculateImplementationFidelity(results) {
|
|
1197
|
+
const implemented = results.filter(r => r.codeCompliance.implemented).length;
|
|
1198
|
+
return (implemented / results.length) * 10;
|
|
1199
|
+
}
|
|
1200
|
+
function calculateArchitecturalConsistency(results) {
|
|
1201
|
+
const consistent = results.filter(r => r.complianceScore >= 7).length;
|
|
1202
|
+
return (consistent / results.length) * 10;
|
|
1203
|
+
}
|
|
1204
|
+
//# sourceMappingURL=review-existing-adrs-tool.js.map
|