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,979 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool for ADR Bootstrap Validation
|
|
3
|
+
* Guides LLMs to create bootstrap.sh and validate_bootstrap.sh scripts
|
|
4
|
+
* that ensure code deployment follows ADR architectural decisions
|
|
5
|
+
*/
|
|
6
|
+
import { McpAdrError } from '../types/index.js';
|
|
7
|
+
import { TreeSitterAnalyzer } from '../utils/tree-sitter-analyzer.js';
|
|
8
|
+
import { findRelatedCode } from '../utils/file-system.js';
|
|
9
|
+
/**
|
|
10
|
+
* Generate bootstrap and validation scripts for ADR-compliant deployment
|
|
11
|
+
* This tool tells the LLM HOW to create deployment scripts that validate
|
|
12
|
+
* the implemented code matches ADR requirements
|
|
13
|
+
*/
|
|
14
|
+
export async function generateAdrBootstrapScripts(args) {
|
|
15
|
+
const { projectPath = process.cwd(), adrDirectory = 'docs/adrs', outputPath = projectPath, scriptType = 'both', includeTests = true, includeDeployment = true, customValidations = [], enableTreeSitterAnalysis = true,
|
|
16
|
+
// conversationContext is available but not used currently
|
|
17
|
+
} = args;
|
|
18
|
+
try {
|
|
19
|
+
// Discover ADRs in the target project
|
|
20
|
+
const { discoverAdrsInDirectory } = await import('../utils/adr-discovery.js');
|
|
21
|
+
const discoveryResult = await discoverAdrsInDirectory(adrDirectory, true, projectPath);
|
|
22
|
+
// Smart Code Linking - Find related implementation files
|
|
23
|
+
let relatedCodeAnalysis = '';
|
|
24
|
+
let relatedFiles = [];
|
|
25
|
+
if (discoveryResult.adrs.length > 0) {
|
|
26
|
+
try {
|
|
27
|
+
// Combine all ADR content for comprehensive analysis
|
|
28
|
+
const combinedAdrContent = discoveryResult.adrs
|
|
29
|
+
.map(adr => `# ${adr.title}\n${adr.content || ''}`)
|
|
30
|
+
.join('\n\n');
|
|
31
|
+
const relatedCodeResult = await findRelatedCode('bootstrap-validation-analysis', combinedAdrContent, projectPath, {
|
|
32
|
+
useAI: true,
|
|
33
|
+
useRipgrep: true,
|
|
34
|
+
maxFiles: 20,
|
|
35
|
+
includeContent: false,
|
|
36
|
+
});
|
|
37
|
+
relatedFiles = relatedCodeResult.relatedFiles;
|
|
38
|
+
if (relatedFiles.length > 0) {
|
|
39
|
+
relatedCodeAnalysis = `
|
|
40
|
+
## 🔗 Smart Code Linking Analysis
|
|
41
|
+
|
|
42
|
+
Found ${relatedFiles.length} code files related to ADR implementations that should be included in validation:
|
|
43
|
+
|
|
44
|
+
### Critical Implementation Files
|
|
45
|
+
${relatedFiles
|
|
46
|
+
.slice(0, 8)
|
|
47
|
+
.map((file, index) => `
|
|
48
|
+
${index + 1}. **${file.path}**
|
|
49
|
+
- Type: ${file.extension} file
|
|
50
|
+
- Size: ${file.size} bytes
|
|
51
|
+
- Directory: ${file.directory}
|
|
52
|
+
`)
|
|
53
|
+
.join('')}
|
|
54
|
+
|
|
55
|
+
### Validation Targets
|
|
56
|
+
- **Keywords Found**: ${relatedCodeResult.keywords.join(', ')}
|
|
57
|
+
- **Search Patterns**: ${relatedCodeResult.searchPatterns.join(', ')}
|
|
58
|
+
- **Implementation Confidence**: ${(relatedCodeResult.confidence * 100).toFixed(1)}%
|
|
59
|
+
|
|
60
|
+
**Bootstrap Integration**: These files will be included in validation scripts to ensure ADR compliance during deployment.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
relatedCodeAnalysis = `
|
|
67
|
+
## 🔗 Smart Code Linking Analysis
|
|
68
|
+
|
|
69
|
+
**Status**: No related implementation files found for ADRs
|
|
70
|
+
**Keywords Searched**: ${relatedCodeResult.keywords.join(', ')}
|
|
71
|
+
**Analysis**: ADRs may be high-level decisions not yet implemented in code
|
|
72
|
+
|
|
73
|
+
**Recommendation**: Focus validation on configuration files, deployment scripts, and architectural constraints rather than implementation details.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.warn('[WARNING] Smart Code Linking for bootstrap validation failed:', error);
|
|
81
|
+
relatedCodeAnalysis = `
|
|
82
|
+
## 🔗 Smart Code Linking Analysis
|
|
83
|
+
|
|
84
|
+
**Status**: ⚠️ Analysis failed - continuing with standard validation
|
|
85
|
+
**Error**: ${error instanceof Error ? error.message : 'Unknown error'}
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Extract validation requirements from ADRs
|
|
92
|
+
const complianceChecks = await extractComplianceChecks(discoveryResult.adrs, relatedFiles);
|
|
93
|
+
// Perform tree-sitter analysis for ADR compliance validation
|
|
94
|
+
let codeAnalysisResults = null;
|
|
95
|
+
let complianceValidation = '';
|
|
96
|
+
if (enableTreeSitterAnalysis) {
|
|
97
|
+
try {
|
|
98
|
+
codeAnalysisResults = await performAdrComplianceAnalysis(projectPath, discoveryResult.adrs, complianceChecks);
|
|
99
|
+
if (codeAnalysisResults.violations.length > 0 ||
|
|
100
|
+
codeAnalysisResults.implementations.length > 0) {
|
|
101
|
+
complianceValidation = `
|
|
102
|
+
|
|
103
|
+
## 🔍 Tree-sitter ADR Compliance Analysis
|
|
104
|
+
|
|
105
|
+
**Analysis Results:**
|
|
106
|
+
- **Files Analyzed**: ${codeAnalysisResults.filesAnalyzed}
|
|
107
|
+
- **ADR Implementations Found**: ${codeAnalysisResults.implementations.length}
|
|
108
|
+
- **Compliance Violations**: ${codeAnalysisResults.violations.length}
|
|
109
|
+
- **Architecture Patterns Detected**: ${codeAnalysisResults.patterns.join(', ') || 'None'}
|
|
110
|
+
|
|
111
|
+
${codeAnalysisResults.implementations.length > 0
|
|
112
|
+
? `
|
|
113
|
+
### ✅ Detected ADR Implementations
|
|
114
|
+
${codeAnalysisResults.implementations.map((impl) => `- **${impl.adrTitle}**: ${impl.evidence} (${impl.file}:${impl.line})`).join('\n')}
|
|
115
|
+
`
|
|
116
|
+
: ''}
|
|
117
|
+
|
|
118
|
+
${codeAnalysisResults.violations.length > 0
|
|
119
|
+
? `
|
|
120
|
+
### ❌ ADR Compliance Violations
|
|
121
|
+
${codeAnalysisResults.violations.map((violation) => `- **${violation.adrTitle}**: ${violation.issue} (${violation.file}:${violation.line})`).join('\n')}
|
|
122
|
+
`
|
|
123
|
+
: ''}
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.warn('Tree-sitter ADR compliance analysis failed:', error);
|
|
131
|
+
complianceValidation = `
|
|
132
|
+
|
|
133
|
+
## 🔍 Tree-sitter ADR Compliance Analysis
|
|
134
|
+
|
|
135
|
+
**Status**: ⚠️ Analysis failed - continuing with basic validation
|
|
136
|
+
**Error**: ${error instanceof Error ? error.message : 'Unknown error'}
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Generate bootstrap.sh script
|
|
143
|
+
const bootstrapScript = generateBootstrapScript(complianceChecks, projectPath, includeTests, includeDeployment, customValidations);
|
|
144
|
+
// Generate validate_bootstrap.sh script
|
|
145
|
+
const validationScript = generateValidationScript(complianceChecks, projectPath, discoveryResult.adrs);
|
|
146
|
+
const response = {
|
|
147
|
+
instructions: `
|
|
148
|
+
# ADR Bootstrap Validation Scripts Generation
|
|
149
|
+
|
|
150
|
+
## Purpose
|
|
151
|
+
These scripts ensure that code deployed to production follows the architectural decisions documented in ADRs.
|
|
152
|
+
The bootstrap script deploys the code while the validation script verifies ADR compliance.
|
|
153
|
+
|
|
154
|
+
## Discovered ADRs (${discoveryResult.totalAdrs} total)
|
|
155
|
+
${discoveryResult.adrs.map(adr => `- ${adr.title} (${adr.status})`).join('\n')}
|
|
156
|
+
|
|
157
|
+
${relatedCodeAnalysis}
|
|
158
|
+
|
|
159
|
+
${complianceValidation}
|
|
160
|
+
|
|
161
|
+
## Generated Scripts
|
|
162
|
+
|
|
163
|
+
### 1. bootstrap.sh - Deployment Script
|
|
164
|
+
This script deploys the code that was created based on ADR planning.
|
|
165
|
+
It ensures the deployment follows architectural requirements.
|
|
166
|
+
|
|
167
|
+
**Location**: ${outputPath}/bootstrap.sh
|
|
168
|
+
**Purpose**: Deploy ADR-compliant code to the environment
|
|
169
|
+
**Key Features**:
|
|
170
|
+
- Validates prerequisites from ADRs
|
|
171
|
+
- Deploys code components in correct order
|
|
172
|
+
- Runs ADR compliance checks during deployment
|
|
173
|
+
- Provides rollback on failure
|
|
174
|
+
|
|
175
|
+
### 2. validate_bootstrap.sh - Validation Script
|
|
176
|
+
This script validates that deployed code matches ADR requirements.
|
|
177
|
+
It catches integration issues that unit tests miss.
|
|
178
|
+
|
|
179
|
+
**Location**: ${outputPath}/validate_bootstrap.sh
|
|
180
|
+
**Purpose**: Verify deployed code follows ADR decisions
|
|
181
|
+
**Key Features**:
|
|
182
|
+
- Checks implementation against each ADR
|
|
183
|
+
- Validates architectural constraints
|
|
184
|
+
- Tests integration points
|
|
185
|
+
- Reports compliance status
|
|
186
|
+
|
|
187
|
+
## Implementation Instructions for LLM
|
|
188
|
+
|
|
189
|
+
1. **Create bootstrap.sh**:
|
|
190
|
+
- Save the generated bootstrap script to ${outputPath}/bootstrap.sh
|
|
191
|
+
- Make it executable: chmod +x bootstrap.sh
|
|
192
|
+
- Include ADR-specific deployment steps
|
|
193
|
+
- Add rollback functionality for failures
|
|
194
|
+
|
|
195
|
+
2. **Create validate_bootstrap.sh**:
|
|
196
|
+
- Save the validation script to ${outputPath}/validate_bootstrap.sh
|
|
197
|
+
- Make it executable: chmod +x validate_bootstrap.sh
|
|
198
|
+
- Include comprehensive ADR compliance checks
|
|
199
|
+
- Generate detailed compliance report
|
|
200
|
+
|
|
201
|
+
3. **Integration Steps**:
|
|
202
|
+
- Run bootstrap.sh to deploy the code
|
|
203
|
+
- Run validate_bootstrap.sh to verify compliance
|
|
204
|
+
- Include both in CI/CD pipeline
|
|
205
|
+
- Document any failures with ADR references
|
|
206
|
+
|
|
207
|
+
## Compliance Checks Generated
|
|
208
|
+
${complianceChecks.length} validation rules extracted from ADRs:
|
|
209
|
+
${complianceChecks
|
|
210
|
+
.slice(0, 5)
|
|
211
|
+
.map(check => `- ${check.adrId}: ${check.requirement} (${check.severity})`)
|
|
212
|
+
.join('\n')}
|
|
213
|
+
${complianceChecks.length > 5 ? `... and ${complianceChecks.length - 5} more checks` : ''}
|
|
214
|
+
|
|
215
|
+
## Usage
|
|
216
|
+
\`\`\`bash
|
|
217
|
+
# Deploy code following ADR requirements
|
|
218
|
+
./bootstrap.sh
|
|
219
|
+
|
|
220
|
+
# Validate deployment matches ADRs
|
|
221
|
+
./validate_bootstrap.sh
|
|
222
|
+
|
|
223
|
+
# Both scripts exit with:
|
|
224
|
+
# 0 - Success, ADR compliant
|
|
225
|
+
# 1 - Failure, ADR violations found
|
|
226
|
+
\`\`\`
|
|
227
|
+
`,
|
|
228
|
+
scripts: scriptType === 'both'
|
|
229
|
+
? {
|
|
230
|
+
bootstrap: bootstrapScript,
|
|
231
|
+
validation: validationScript,
|
|
232
|
+
}
|
|
233
|
+
: scriptType === 'bootstrap'
|
|
234
|
+
? {
|
|
235
|
+
bootstrap: bootstrapScript,
|
|
236
|
+
}
|
|
237
|
+
: {
|
|
238
|
+
validation: validationScript,
|
|
239
|
+
},
|
|
240
|
+
complianceChecks,
|
|
241
|
+
adrSummary: {
|
|
242
|
+
total: discoveryResult.totalAdrs,
|
|
243
|
+
byStatus: discoveryResult.summary.byStatus,
|
|
244
|
+
withImplementationTasks: discoveryResult.adrs.filter(adr => adr.content?.includes('Implementation') ||
|
|
245
|
+
adr.content?.includes('TODO') ||
|
|
246
|
+
adr.content?.includes('Tasks')).length,
|
|
247
|
+
smartCodeLinking: {
|
|
248
|
+
enabled: relatedFiles.length > 0,
|
|
249
|
+
relatedFilesCount: relatedFiles.length,
|
|
250
|
+
fileTypes: relatedFiles.length > 0
|
|
251
|
+
? [...new Set(relatedFiles.map(f => f.extension))].join(', ')
|
|
252
|
+
: 'none',
|
|
253
|
+
validationEnhancements: relatedFiles.length > 0
|
|
254
|
+
? 'File-specific validation commands generated'
|
|
255
|
+
: 'Standard validation only',
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
return {
|
|
260
|
+
content: [
|
|
261
|
+
{
|
|
262
|
+
type: 'text',
|
|
263
|
+
text: JSON.stringify(response, null, 2),
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
throw new McpAdrError(`Failed to generate ADR bootstrap scripts: ${error instanceof Error ? error.message : String(error)}`, 'BOOTSTRAP_GENERATION_ERROR');
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Extract compliance checks from ADR content
|
|
274
|
+
* Enhanced with Smart Code Linking for related file validation
|
|
275
|
+
*/
|
|
276
|
+
async function extractComplianceChecks(adrs, relatedFiles = []) {
|
|
277
|
+
const checks = [];
|
|
278
|
+
for (const adr of adrs) {
|
|
279
|
+
if (!adr.content)
|
|
280
|
+
continue;
|
|
281
|
+
// Extract requirements from ADR content
|
|
282
|
+
const requirements = extractRequirements(adr.content);
|
|
283
|
+
requirements.forEach((req, index) => {
|
|
284
|
+
checks.push({
|
|
285
|
+
adrId: adr.filename || `adr-${index}`,
|
|
286
|
+
adrTitle: adr.title || 'Unknown ADR',
|
|
287
|
+
requirement: req.text,
|
|
288
|
+
validationCommand: generateValidationCommand(req),
|
|
289
|
+
expectedOutcome: req.expected,
|
|
290
|
+
severity: determineSeverity(req.text),
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
// Add Smart Code Linking validation checks
|
|
295
|
+
if (relatedFiles.length > 0) {
|
|
296
|
+
// Group related files by type for validation
|
|
297
|
+
const filesByType = relatedFiles.reduce((acc, file) => {
|
|
298
|
+
const type = file.extension || 'unknown';
|
|
299
|
+
if (!acc[type])
|
|
300
|
+
acc[type] = [];
|
|
301
|
+
acc[type].push(file);
|
|
302
|
+
return acc;
|
|
303
|
+
}, {});
|
|
304
|
+
// Add file-specific validation checks
|
|
305
|
+
Object.entries(filesByType).forEach(([fileType, files]) => {
|
|
306
|
+
const typedFiles = files; // Type assertion for files array
|
|
307
|
+
const fileCount = typedFiles.length;
|
|
308
|
+
// Configuration file validation
|
|
309
|
+
if (['json', 'yml', 'yaml', 'env'].includes(fileType)) {
|
|
310
|
+
checks.push({
|
|
311
|
+
adrId: 'smart-code-linking',
|
|
312
|
+
adrTitle: 'Configuration File Validation',
|
|
313
|
+
requirement: `Validate ${fileCount} ${fileType.toUpperCase()} configuration file(s) comply with ADR requirements`,
|
|
314
|
+
validationCommand: generateConfigValidationCommand(typedFiles),
|
|
315
|
+
expectedOutcome: 'Configuration files are valid and ADR-compliant',
|
|
316
|
+
severity: 'error',
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
// Source code validation
|
|
320
|
+
if (['ts', 'js', 'py', 'java', 'go'].includes(fileType)) {
|
|
321
|
+
checks.push({
|
|
322
|
+
adrId: 'smart-code-linking',
|
|
323
|
+
adrTitle: 'Implementation File Validation',
|
|
324
|
+
requirement: `Validate ${fileCount} ${fileType.toUpperCase()} implementation file(s) follow architectural patterns`,
|
|
325
|
+
validationCommand: generateImplementationValidationCommand(typedFiles, fileType),
|
|
326
|
+
expectedOutcome: 'Implementation files follow ADR architectural decisions',
|
|
327
|
+
severity: 'warning',
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
// Infrastructure as Code validation
|
|
331
|
+
if (['tf', 'hcl', 'dockerfile'].includes(fileType)) {
|
|
332
|
+
checks.push({
|
|
333
|
+
adrId: 'smart-code-linking',
|
|
334
|
+
adrTitle: 'Infrastructure Validation',
|
|
335
|
+
requirement: `Validate ${fileCount} infrastructure file(s) match deployment requirements`,
|
|
336
|
+
validationCommand: generateInfrastructureValidationCommand(typedFiles, fileType),
|
|
337
|
+
expectedOutcome: 'Infrastructure configurations comply with ADR deployment decisions',
|
|
338
|
+
severity: 'critical',
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
// Add overall integration check
|
|
343
|
+
checks.push({
|
|
344
|
+
adrId: 'smart-code-linking',
|
|
345
|
+
adrTitle: 'Smart Code Linking Integration',
|
|
346
|
+
requirement: `Verify ${relatedFiles.length} ADR-related files are properly integrated`,
|
|
347
|
+
validationCommand: `echo "Checking integration of ADR-related files..." && find . -type f \\( ${relatedFiles.map(f => `-name "${f.name}"`).join(' -o ')} \\) | wc -l`,
|
|
348
|
+
expectedOutcome: `${relatedFiles.length} files found and accessible`,
|
|
349
|
+
severity: 'info',
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
return checks;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Generate validation command for configuration files
|
|
356
|
+
*/
|
|
357
|
+
function generateConfigValidationCommand(files) {
|
|
358
|
+
const filePaths = files.map(f => f.path).slice(0, 5); // Limit to first 5 files
|
|
359
|
+
const fileType = files[0]?.extension || 'unknown';
|
|
360
|
+
if (fileType === 'json') {
|
|
361
|
+
return `echo "Validating JSON configuration files..." && for file in ${filePaths.join(' ')}; do echo "Checking $file" && cat "$file" | jq . > /dev/null || echo "Invalid JSON: $file"; done`;
|
|
362
|
+
}
|
|
363
|
+
else if (['yml', 'yaml'].includes(fileType)) {
|
|
364
|
+
return `echo "Validating YAML configuration files..." && for file in ${filePaths.join(' ')}; do echo "Checking $file" && python -c "import yaml; yaml.safe_load(open('$file'))" || echo "Invalid YAML: $file"; done`;
|
|
365
|
+
}
|
|
366
|
+
else if (fileType === 'env') {
|
|
367
|
+
return `echo "Validating environment files..." && for file in ${filePaths.join(' ')}; do echo "Checking $file" && grep -E '^[A-Z_]+=.*$' "$file" > /dev/null || echo "Invalid ENV format: $file"; done`;
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
return `echo "Checking configuration files exist..." && ls -la ${filePaths.join(' ')}`;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Generate validation command for implementation files
|
|
375
|
+
*/
|
|
376
|
+
function generateImplementationValidationCommand(files, fileType) {
|
|
377
|
+
const filePaths = files.map(f => f.path).slice(0, 3); // Limit to first 3 files
|
|
378
|
+
if (['ts', 'js'].includes(fileType)) {
|
|
379
|
+
return `echo "Validating TypeScript/JavaScript files..." && for file in ${filePaths.join(' ')}; do echo "Checking $file" && node -c "$file" > /dev/null 2>&1 || echo "Syntax error: $file"; done`;
|
|
380
|
+
}
|
|
381
|
+
else if (fileType === 'py') {
|
|
382
|
+
return `echo "Validating Python files..." && for file in ${filePaths.join(' ')}; do echo "Checking $file" && python -m py_compile "$file" > /dev/null 2>&1 || echo "Syntax error: $file"; done`;
|
|
383
|
+
}
|
|
384
|
+
else if (fileType === 'java') {
|
|
385
|
+
return `echo "Validating Java files..." && for file in ${filePaths.join(' ')}; do echo "Checking $file" && javac -cp . "$file" > /dev/null 2>&1 || echo "Compilation error: $file"; done`;
|
|
386
|
+
}
|
|
387
|
+
else if (fileType === 'go') {
|
|
388
|
+
return `echo "Validating Go files..." && for file in ${filePaths.join(' ')}; do echo "Checking $file" && go fmt "$file" > /dev/null || echo "Format error: $file"; done`;
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
return `echo "Checking implementation files exist..." && ls -la ${filePaths.join(' ')}`;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Generate validation command for infrastructure files
|
|
396
|
+
*/
|
|
397
|
+
function generateInfrastructureValidationCommand(files, fileType) {
|
|
398
|
+
const filePaths = files.map(f => f.path).slice(0, 3); // Limit to first 3 files
|
|
399
|
+
if (['tf', 'hcl'].includes(fileType)) {
|
|
400
|
+
return `echo "Validating Terraform files..." && for file in ${filePaths.join(' ')}; do echo "Checking $file" && terraform validate "$file" > /dev/null 2>&1 || echo "Terraform validation failed: $file"; done`;
|
|
401
|
+
}
|
|
402
|
+
else if (fileType === 'dockerfile') {
|
|
403
|
+
return `echo "Validating Dockerfile..." && for file in ${filePaths.join(' ')}; do echo "Checking $file" && docker build -f "$file" --dry-run . > /dev/null 2>&1 || echo "Dockerfile validation failed: $file"; done`;
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
return `echo "Checking infrastructure files exist..." && ls -la ${filePaths.join(' ')}`;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Extract requirements from ADR content
|
|
411
|
+
*/
|
|
412
|
+
function extractRequirements(content) {
|
|
413
|
+
const requirements = [];
|
|
414
|
+
// Look for common requirement patterns
|
|
415
|
+
const patterns = [
|
|
416
|
+
/(?:must|should|shall|will)\s+([^.]+)/gi,
|
|
417
|
+
/(?:requirement|constraint):\s*([^.]+)/gi,
|
|
418
|
+
/(?:decision|approach):\s*([^.]+)/gi,
|
|
419
|
+
/\[x?\]\s+([^[\n]+)/g, // Checklist items
|
|
420
|
+
];
|
|
421
|
+
patterns.forEach(pattern => {
|
|
422
|
+
const matches = content.matchAll(pattern);
|
|
423
|
+
for (const match of matches) {
|
|
424
|
+
if (match[1]) {
|
|
425
|
+
requirements.push({
|
|
426
|
+
text: match[1].trim(),
|
|
427
|
+
expected: 'Requirement satisfied',
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
return requirements;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Generate validation command for a requirement
|
|
436
|
+
*/
|
|
437
|
+
function generateValidationCommand(requirement) {
|
|
438
|
+
const text = requirement.text.toLowerCase();
|
|
439
|
+
// Generate appropriate validation based on requirement type
|
|
440
|
+
if (text.includes('database') || text.includes('postgres') || text.includes('mysql')) {
|
|
441
|
+
return 'echo "Checking database configuration..." && psql --version || mysql --version';
|
|
442
|
+
}
|
|
443
|
+
else if (text.includes('api') || text.includes('rest') || text.includes('http')) {
|
|
444
|
+
return 'echo "Validating API endpoints..." && curl -s http://localhost:3000/health || echo "API not responding"';
|
|
445
|
+
}
|
|
446
|
+
else if (text.includes('auth') || text.includes('jwt') || text.includes('token')) {
|
|
447
|
+
return 'echo "Checking authentication setup..." && grep -r "jwt\\|auth" src/ | head -5';
|
|
448
|
+
}
|
|
449
|
+
else if (text.includes('test') || text.includes('coverage')) {
|
|
450
|
+
return 'echo "Running tests..." && npm test -- --coverage --silent';
|
|
451
|
+
}
|
|
452
|
+
else if (text.includes('docker') || text.includes('container')) {
|
|
453
|
+
return 'echo "Checking Docker setup..." && docker ps || docker-compose ps';
|
|
454
|
+
}
|
|
455
|
+
else if (text.includes('cache') || text.includes('redis')) {
|
|
456
|
+
return 'echo "Validating cache configuration..." && redis-cli ping || echo "Redis not available"';
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
return `echo "Checking: ${requirement.text.substring(0, 50)}..."`;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Determine severity based on requirement text
|
|
464
|
+
*/
|
|
465
|
+
function determineSeverity(text) {
|
|
466
|
+
const lower = text.toLowerCase();
|
|
467
|
+
if (lower.includes('must') || lower.includes('critical') || lower.includes('required')) {
|
|
468
|
+
return 'critical';
|
|
469
|
+
}
|
|
470
|
+
else if (lower.includes('shall') || lower.includes('error')) {
|
|
471
|
+
return 'error';
|
|
472
|
+
}
|
|
473
|
+
else if (lower.includes('should') || lower.includes('warning')) {
|
|
474
|
+
return 'warning';
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
return 'info';
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Generate bootstrap.sh script content
|
|
482
|
+
*/
|
|
483
|
+
function generateBootstrapScript(checks, projectPath, includeTests, includeDeployment, customValidations) {
|
|
484
|
+
return `#!/bin/bash
|
|
485
|
+
# ADR Bootstrap Deployment Script
|
|
486
|
+
# Generated by MCP ADR Analysis Server
|
|
487
|
+
# Purpose: Deploy code that follows ADR architectural decisions
|
|
488
|
+
|
|
489
|
+
set -e # Exit on error
|
|
490
|
+
|
|
491
|
+
echo "🚀 ADR Bootstrap Deployment Starting..."
|
|
492
|
+
echo "📍 Project: ${projectPath}"
|
|
493
|
+
echo "📋 ADR Compliance Checks: ${checks.length}"
|
|
494
|
+
echo ""
|
|
495
|
+
|
|
496
|
+
# Color codes for output
|
|
497
|
+
RED='\\033[0;31m'
|
|
498
|
+
GREEN='\\033[0;32m'
|
|
499
|
+
YELLOW='\\033[1;33m'
|
|
500
|
+
NC='\\033[0m' # No Color
|
|
501
|
+
|
|
502
|
+
# Track deployment status
|
|
503
|
+
DEPLOYMENT_SUCCESS=true
|
|
504
|
+
FAILED_CHECKS=()
|
|
505
|
+
|
|
506
|
+
# Function to check ADR compliance
|
|
507
|
+
check_adr_compliance() {
|
|
508
|
+
local adr_id="$1"
|
|
509
|
+
local requirement="$2"
|
|
510
|
+
local command="$3"
|
|
511
|
+
local expected="$4"
|
|
512
|
+
local severity="$5"
|
|
513
|
+
|
|
514
|
+
echo -n " Checking $adr_id: $requirement... "
|
|
515
|
+
|
|
516
|
+
if eval "$command" > /dev/null 2>&1; then
|
|
517
|
+
echo -e "\${GREEN}✓\${NC}"
|
|
518
|
+
return 0
|
|
519
|
+
else
|
|
520
|
+
echo -e "\${RED}✗\${NC}"
|
|
521
|
+
FAILED_CHECKS+=("$adr_id: $requirement [$severity]")
|
|
522
|
+
if [ "$severity" = "critical" ]; then
|
|
523
|
+
DEPLOYMENT_SUCCESS=false
|
|
524
|
+
fi
|
|
525
|
+
return 1
|
|
526
|
+
fi
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
# Phase 1: Pre-deployment validation
|
|
530
|
+
echo "📋 Phase 1: Pre-deployment ADR Validation"
|
|
531
|
+
echo "=========================================="
|
|
532
|
+
|
|
533
|
+
${checks
|
|
534
|
+
.filter(c => c.severity === 'critical')
|
|
535
|
+
.map(check => `
|
|
536
|
+
check_adr_compliance \\
|
|
537
|
+
"${check.adrId}" \\
|
|
538
|
+
"${check.requirement.substring(0, 50)}..." \\
|
|
539
|
+
"${check.validationCommand}" \\
|
|
540
|
+
"${check.expectedOutcome}" \\
|
|
541
|
+
"${check.severity}"`)
|
|
542
|
+
.join('\n')}
|
|
543
|
+
|
|
544
|
+
if [ "$DEPLOYMENT_SUCCESS" = false ]; then
|
|
545
|
+
echo -e "\${RED}❌ Critical ADR violations found. Deployment aborted.\${NC}"
|
|
546
|
+
exit 1
|
|
547
|
+
fi
|
|
548
|
+
|
|
549
|
+
# Phase 2: Build and prepare deployment
|
|
550
|
+
echo ""
|
|
551
|
+
echo "🔨 Phase 2: Build and Prepare"
|
|
552
|
+
echo "============================="
|
|
553
|
+
|
|
554
|
+
# Install dependencies if needed
|
|
555
|
+
if [ -f "package.json" ]; then
|
|
556
|
+
echo " Installing dependencies..."
|
|
557
|
+
npm ci || npm install
|
|
558
|
+
fi
|
|
559
|
+
|
|
560
|
+
# Build the project
|
|
561
|
+
if [ -f "package.json" ] && grep -q '"build"' package.json; then
|
|
562
|
+
echo " Building project..."
|
|
563
|
+
npm run build
|
|
564
|
+
fi
|
|
565
|
+
|
|
566
|
+
${includeTests
|
|
567
|
+
? `
|
|
568
|
+
# Phase 3: Run tests
|
|
569
|
+
echo ""
|
|
570
|
+
echo "🧪 Phase 3: Test Execution"
|
|
571
|
+
echo "========================="
|
|
572
|
+
|
|
573
|
+
if [ -f "package.json" ] && grep -q '"test"' package.json; then
|
|
574
|
+
echo " Running tests..."
|
|
575
|
+
npm test || {
|
|
576
|
+
echo -e "\${YELLOW}⚠️ Tests failed but continuing...\${NC}"
|
|
577
|
+
}
|
|
578
|
+
fi
|
|
579
|
+
`
|
|
580
|
+
: ''}
|
|
581
|
+
|
|
582
|
+
${includeDeployment
|
|
583
|
+
? `
|
|
584
|
+
# Phase 4: Deploy application
|
|
585
|
+
echo ""
|
|
586
|
+
echo "🚢 Phase 4: Deployment"
|
|
587
|
+
echo "====================="
|
|
588
|
+
|
|
589
|
+
# Start the application
|
|
590
|
+
if [ -f "docker-compose.yml" ]; then
|
|
591
|
+
echo " Starting with Docker Compose..."
|
|
592
|
+
docker-compose up -d
|
|
593
|
+
elif [ -f "package.json" ] && grep -q '"start"' package.json; then
|
|
594
|
+
echo " Starting application..."
|
|
595
|
+
npm start &
|
|
596
|
+
sleep 5 # Wait for startup
|
|
597
|
+
else
|
|
598
|
+
echo " No deployment method detected"
|
|
599
|
+
fi
|
|
600
|
+
`
|
|
601
|
+
: ''}
|
|
602
|
+
|
|
603
|
+
# Phase 5: Post-deployment validation
|
|
604
|
+
echo ""
|
|
605
|
+
echo "✅ Phase 5: Post-deployment ADR Validation"
|
|
606
|
+
echo "========================================="
|
|
607
|
+
|
|
608
|
+
${checks
|
|
609
|
+
.filter(c => c.severity !== 'critical')
|
|
610
|
+
.map(check => `
|
|
611
|
+
check_adr_compliance \\
|
|
612
|
+
"${check.adrId}" \\
|
|
613
|
+
"${check.requirement.substring(0, 50)}..." \\
|
|
614
|
+
"${check.validationCommand}" \\
|
|
615
|
+
"${check.expectedOutcome}" \\
|
|
616
|
+
"${check.severity}"`)
|
|
617
|
+
.join('\n')}
|
|
618
|
+
|
|
619
|
+
${customValidations.length > 0
|
|
620
|
+
? `
|
|
621
|
+
# Custom validations
|
|
622
|
+
echo ""
|
|
623
|
+
echo "🔧 Custom Validations"
|
|
624
|
+
echo "===================="
|
|
625
|
+
${customValidations.map(v => `eval "${v}"`).join('\n')}
|
|
626
|
+
`
|
|
627
|
+
: ''}
|
|
628
|
+
|
|
629
|
+
# Final report
|
|
630
|
+
echo ""
|
|
631
|
+
echo "📊 Deployment Summary"
|
|
632
|
+
echo "===================="
|
|
633
|
+
|
|
634
|
+
if [ \${#FAILED_CHECKS[@]} -eq 0 ]; then
|
|
635
|
+
echo -e "\${GREEN}✅ All ADR compliance checks passed!\${NC}"
|
|
636
|
+
echo "🎉 Deployment successful and ADR-compliant!"
|
|
637
|
+
exit 0
|
|
638
|
+
else
|
|
639
|
+
echo -e "\${YELLOW}⚠️ Some ADR checks failed:\${NC}"
|
|
640
|
+
for check in "\${FAILED_CHECKS[@]}"; do
|
|
641
|
+
echo " - $check"
|
|
642
|
+
done
|
|
643
|
+
|
|
644
|
+
if [ "$DEPLOYMENT_SUCCESS" = false ]; then
|
|
645
|
+
echo -e "\${RED}❌ Deployment failed due to critical ADR violations\${NC}"
|
|
646
|
+
exit 1
|
|
647
|
+
else
|
|
648
|
+
echo -e "\${YELLOW}⚠️ Deployment completed with warnings\${NC}"
|
|
649
|
+
exit 0
|
|
650
|
+
fi
|
|
651
|
+
fi
|
|
652
|
+
`;
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Generate validate_bootstrap.sh script content
|
|
656
|
+
*/
|
|
657
|
+
function generateValidationScript(checks, projectPath, adrs) {
|
|
658
|
+
return `#!/bin/bash
|
|
659
|
+
# ADR Validation Script
|
|
660
|
+
# Generated by MCP ADR Analysis Server
|
|
661
|
+
# Purpose: Validate deployed code follows ADR requirements
|
|
662
|
+
|
|
663
|
+
set -e # Exit on error
|
|
664
|
+
|
|
665
|
+
echo "🔍 ADR Compliance Validation"
|
|
666
|
+
echo "============================"
|
|
667
|
+
echo "📍 Project: ${projectPath}"
|
|
668
|
+
echo "📋 ADRs to validate: ${adrs.length}"
|
|
669
|
+
echo "✓ Validation checks: ${checks.length}"
|
|
670
|
+
echo ""
|
|
671
|
+
|
|
672
|
+
# Color codes
|
|
673
|
+
RED='\\033[0;31m'
|
|
674
|
+
GREEN='\\033[0;32m'
|
|
675
|
+
YELLOW='\\033[1;33m'
|
|
676
|
+
BLUE='\\033[0;34m'
|
|
677
|
+
NC='\\033[0m' # No Color
|
|
678
|
+
|
|
679
|
+
# Tracking variables
|
|
680
|
+
TOTAL_CHECKS=${checks.length}
|
|
681
|
+
PASSED_CHECKS=0
|
|
682
|
+
FAILED_CHECKS=0
|
|
683
|
+
CRITICAL_FAILURES=0
|
|
684
|
+
|
|
685
|
+
# Results array
|
|
686
|
+
declare -a RESULTS
|
|
687
|
+
|
|
688
|
+
# Validation function
|
|
689
|
+
validate_adr() {
|
|
690
|
+
local adr_id="$1"
|
|
691
|
+
local adr_title="$2"
|
|
692
|
+
local requirement="$3"
|
|
693
|
+
local command="$4"
|
|
694
|
+
local severity="$5"
|
|
695
|
+
local status="FAIL"
|
|
696
|
+
local color=$RED
|
|
697
|
+
|
|
698
|
+
echo -e "\${BLUE}Validating:\${NC} $adr_id - $adr_title"
|
|
699
|
+
echo " Requirement: $requirement"
|
|
700
|
+
echo -n " Status: "
|
|
701
|
+
|
|
702
|
+
if eval "$command" > /dev/null 2>&1; then
|
|
703
|
+
status="PASS"
|
|
704
|
+
color=$GREEN
|
|
705
|
+
PASSED_CHECKS=$((PASSED_CHECKS + 1))
|
|
706
|
+
echo -e "\${color}✓ PASSED\${NC}"
|
|
707
|
+
else
|
|
708
|
+
FAILED_CHECKS=$((FAILED_CHECKS + 1))
|
|
709
|
+
if [ "$severity" = "critical" ]; then
|
|
710
|
+
CRITICAL_FAILURES=$((CRITICAL_FAILURES + 1))
|
|
711
|
+
fi
|
|
712
|
+
echo -e "\${color}✗ FAILED [$severity]\${NC}"
|
|
713
|
+
fi
|
|
714
|
+
|
|
715
|
+
RESULTS+=("$adr_id|$adr_title|$requirement|$status|$severity")
|
|
716
|
+
echo ""
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
# Run all validations
|
|
720
|
+
echo "🔍 Running ADR Compliance Checks"
|
|
721
|
+
echo "================================"
|
|
722
|
+
echo ""
|
|
723
|
+
|
|
724
|
+
${checks
|
|
725
|
+
.map(check => `
|
|
726
|
+
validate_adr \\
|
|
727
|
+
"${check.adrId}" \\
|
|
728
|
+
"${check.adrTitle}" \\
|
|
729
|
+
"${check.requirement}" \\
|
|
730
|
+
"${check.validationCommand}" \\
|
|
731
|
+
"${check.severity}"`)
|
|
732
|
+
.join('\n')}
|
|
733
|
+
|
|
734
|
+
# Generate compliance report
|
|
735
|
+
echo ""
|
|
736
|
+
echo "📊 ADR Compliance Report"
|
|
737
|
+
echo "======================="
|
|
738
|
+
echo ""
|
|
739
|
+
echo "Summary:"
|
|
740
|
+
echo "--------"
|
|
741
|
+
echo " Total ADRs: ${adrs.length}"
|
|
742
|
+
echo " Total Checks: $TOTAL_CHECKS"
|
|
743
|
+
echo -e " \${GREEN}Passed: $PASSED_CHECKS\${NC}"
|
|
744
|
+
echo -e " \${RED}Failed: $FAILED_CHECKS\${NC}"
|
|
745
|
+
echo -e " \${RED}Critical Failures: $CRITICAL_FAILURES\${NC}"
|
|
746
|
+
echo ""
|
|
747
|
+
|
|
748
|
+
# Calculate compliance percentage
|
|
749
|
+
COMPLIANCE_PERCENT=0
|
|
750
|
+
if [ $TOTAL_CHECKS -gt 0 ]; then
|
|
751
|
+
COMPLIANCE_PERCENT=$((PASSED_CHECKS * 100 / TOTAL_CHECKS))
|
|
752
|
+
fi
|
|
753
|
+
|
|
754
|
+
echo "Compliance Score: $COMPLIANCE_PERCENT%"
|
|
755
|
+
echo ""
|
|
756
|
+
|
|
757
|
+
# Detailed results table
|
|
758
|
+
echo "Detailed Results:"
|
|
759
|
+
echo "-----------------"
|
|
760
|
+
printf "%-20s %-40s %-10s %-10s\\n" "ADR" "Requirement" "Status" "Severity"
|
|
761
|
+
echo "--------------------------------------------------------------------------------"
|
|
762
|
+
|
|
763
|
+
for result in "\${RESULTS[@]}"; do
|
|
764
|
+
IFS='|' read -r adr_id adr_title requirement status severity <<< "$result"
|
|
765
|
+
|
|
766
|
+
if [ "$status" = "PASS" ]; then
|
|
767
|
+
status_color=$GREEN
|
|
768
|
+
else
|
|
769
|
+
status_color=$RED
|
|
770
|
+
fi
|
|
771
|
+
|
|
772
|
+
printf "%-20s %-40s \${status_color}%-10s\${NC} %-10s\\n" \\
|
|
773
|
+
"$adr_id" \\
|
|
774
|
+
"\${requirement:0:40}" \\
|
|
775
|
+
"$status" \\
|
|
776
|
+
"$severity"
|
|
777
|
+
done
|
|
778
|
+
|
|
779
|
+
echo ""
|
|
780
|
+
echo "=================================================================================="
|
|
781
|
+
|
|
782
|
+
# Exit with appropriate code
|
|
783
|
+
if [ $CRITICAL_FAILURES -gt 0 ]; then
|
|
784
|
+
echo -e "\${RED}❌ Validation FAILED: Critical ADR violations detected\${NC}"
|
|
785
|
+
echo ""
|
|
786
|
+
echo "Action Required:"
|
|
787
|
+
echo " 1. Review failed critical checks above"
|
|
788
|
+
echo " 2. Update implementation to match ADR requirements"
|
|
789
|
+
echo " 3. Re-run this validation script"
|
|
790
|
+
exit 1
|
|
791
|
+
elif [ $FAILED_CHECKS -gt 0 ]; then
|
|
792
|
+
echo -e "\${YELLOW}⚠️ Validation PASSED with warnings\${NC}"
|
|
793
|
+
echo ""
|
|
794
|
+
echo "Recommended Actions:"
|
|
795
|
+
echo " 1. Review non-critical failures"
|
|
796
|
+
echo " 2. Plan remediation for next iteration"
|
|
797
|
+
exit 0
|
|
798
|
+
else
|
|
799
|
+
echo -e "\${GREEN}✅ Validation PASSED: Full ADR compliance achieved!\${NC}"
|
|
800
|
+
exit 0
|
|
801
|
+
fi
|
|
802
|
+
`;
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* Perform tree-sitter analysis for ADR compliance validation
|
|
806
|
+
*/
|
|
807
|
+
async function performAdrComplianceAnalysis(projectPath, adrs, complianceChecks) {
|
|
808
|
+
const analyzer = new TreeSitterAnalyzer();
|
|
809
|
+
const { readdirSync, statSync } = await import('fs');
|
|
810
|
+
const { join } = await import('path');
|
|
811
|
+
const results = {
|
|
812
|
+
filesAnalyzed: 0,
|
|
813
|
+
implementations: [],
|
|
814
|
+
violations: [],
|
|
815
|
+
patterns: [],
|
|
816
|
+
};
|
|
817
|
+
// Find source files to analyze
|
|
818
|
+
const sourceFiles = [];
|
|
819
|
+
const findSourceFiles = (dir, depth = 0) => {
|
|
820
|
+
if (depth > 3)
|
|
821
|
+
return; // Limit recursion depth
|
|
822
|
+
try {
|
|
823
|
+
const items = readdirSync(dir);
|
|
824
|
+
for (const item of items) {
|
|
825
|
+
if (item.startsWith('.') || item === 'node_modules')
|
|
826
|
+
continue;
|
|
827
|
+
const fullPath = join(dir, item);
|
|
828
|
+
const stat = statSync(fullPath);
|
|
829
|
+
if (stat.isDirectory()) {
|
|
830
|
+
findSourceFiles(fullPath, depth + 1);
|
|
831
|
+
}
|
|
832
|
+
else if (stat.isFile()) {
|
|
833
|
+
const ext = item.split('.').pop()?.toLowerCase();
|
|
834
|
+
if (['ts', 'js', 'py', 'yml', 'yaml', 'tf', 'hcl', 'json'].includes(ext || '')) {
|
|
835
|
+
sourceFiles.push(fullPath);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
catch {
|
|
841
|
+
// Skip directories we can't read
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
findSourceFiles(projectPath);
|
|
845
|
+
// Analyze files (limit to first 15 for performance)
|
|
846
|
+
const filesToAnalyze = sourceFiles.slice(0, 15);
|
|
847
|
+
results.filesAnalyzed = filesToAnalyze.length;
|
|
848
|
+
for (const filePath of filesToAnalyze) {
|
|
849
|
+
try {
|
|
850
|
+
const analysis = await analyzer.analyzeFile(filePath);
|
|
851
|
+
// Check for ADR implementation evidence
|
|
852
|
+
for (const adr of adrs) {
|
|
853
|
+
if (!adr.content)
|
|
854
|
+
continue;
|
|
855
|
+
// Look for technology/framework mentions in ADR
|
|
856
|
+
const adrTechnologies = extractTechnologiesFromAdr(adr.content);
|
|
857
|
+
// Check if file implements required technologies
|
|
858
|
+
if (analysis.imports) {
|
|
859
|
+
for (const imp of analysis.imports) {
|
|
860
|
+
for (const tech of adrTechnologies) {
|
|
861
|
+
if (imp.module.toLowerCase().includes(tech.toLowerCase())) {
|
|
862
|
+
results.implementations.push({
|
|
863
|
+
adrTitle: adr.title || 'Unknown ADR',
|
|
864
|
+
evidence: `Uses required technology: ${tech} (import: ${imp.module})`,
|
|
865
|
+
file: filePath,
|
|
866
|
+
line: imp.location.line,
|
|
867
|
+
confidence: 0.8,
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
// Check for architectural pattern compliance
|
|
874
|
+
if (analysis.functions) {
|
|
875
|
+
const adrPatterns = extractPatternsFromAdr(adr.content);
|
|
876
|
+
for (const pattern of adrPatterns) {
|
|
877
|
+
// Look for functions that match architectural patterns
|
|
878
|
+
const matchingFunctions = analysis.functions.filter(func => func.name.toLowerCase().includes(pattern.toLowerCase()) ||
|
|
879
|
+
(pattern.includes('service') && func.name.toLowerCase().includes('service')) ||
|
|
880
|
+
(pattern.includes('controller') && func.name.toLowerCase().includes('controller')));
|
|
881
|
+
if (matchingFunctions.length > 0) {
|
|
882
|
+
results.implementations.push({
|
|
883
|
+
adrTitle: adr.title || 'Unknown ADR',
|
|
884
|
+
evidence: `Implements ${pattern} pattern (${matchingFunctions.length} functions)`,
|
|
885
|
+
file: filePath,
|
|
886
|
+
line: matchingFunctions[0]?.location.line || 1,
|
|
887
|
+
confidence: 0.7,
|
|
888
|
+
});
|
|
889
|
+
if (!results.patterns.includes(pattern)) {
|
|
890
|
+
results.patterns.push(pattern);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
// Check for compliance violations
|
|
897
|
+
for (const check of complianceChecks) {
|
|
898
|
+
// Security-related violations
|
|
899
|
+
if (analysis.hasSecrets && check.requirement.toLowerCase().includes('security')) {
|
|
900
|
+
results.violations.push({
|
|
901
|
+
adrTitle: check.adrTitle,
|
|
902
|
+
issue: `Security violation: ${analysis.secrets.length} secrets detected`,
|
|
903
|
+
file: filePath,
|
|
904
|
+
line: analysis.secrets[0]?.location.line || 1,
|
|
905
|
+
severity: check.severity,
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
// Architecture violations
|
|
909
|
+
if (analysis.architecturalViolations && analysis.architecturalViolations.length > 0) {
|
|
910
|
+
for (const violation of analysis.architecturalViolations) {
|
|
911
|
+
results.violations.push({
|
|
912
|
+
adrTitle: check.adrTitle,
|
|
913
|
+
issue: `Architectural violation: ${violation.message}`,
|
|
914
|
+
file: filePath,
|
|
915
|
+
line: violation.location.line,
|
|
916
|
+
severity: check.severity,
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
catch (error) {
|
|
923
|
+
// Skip files that can't be analyzed
|
|
924
|
+
console.warn(`Could not analyze file ${filePath}:`, error);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return results;
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Extract technologies mentioned in ADR content
|
|
931
|
+
*/
|
|
932
|
+
function extractTechnologiesFromAdr(content) {
|
|
933
|
+
const technologies = [];
|
|
934
|
+
const techPatterns = [
|
|
935
|
+
/\b(react|vue|angular|express|fastapi|django|flask|spring|laravel)\b/gi,
|
|
936
|
+
/\b(postgres|mysql|mongodb|redis|elasticsearch)\b/gi,
|
|
937
|
+
/\b(docker|kubernetes|terraform|ansible)\b/gi,
|
|
938
|
+
/\b(aws|azure|gcp|cloudflare)\b/gi,
|
|
939
|
+
];
|
|
940
|
+
for (const pattern of techPatterns) {
|
|
941
|
+
const matches = content.match(pattern);
|
|
942
|
+
if (matches) {
|
|
943
|
+
technologies.push(...matches.map(m => m.toLowerCase()));
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
return [...new Set(technologies)]; // Remove duplicates
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Extract architectural patterns mentioned in ADR content
|
|
950
|
+
*/
|
|
951
|
+
function extractPatternsFromAdr(content) {
|
|
952
|
+
const patterns = [];
|
|
953
|
+
const patternKeywords = [
|
|
954
|
+
'microservice',
|
|
955
|
+
'service',
|
|
956
|
+
'controller',
|
|
957
|
+
'repository',
|
|
958
|
+
'factory',
|
|
959
|
+
'singleton',
|
|
960
|
+
'observer',
|
|
961
|
+
'strategy',
|
|
962
|
+
'adapter',
|
|
963
|
+
'facade',
|
|
964
|
+
'mvc',
|
|
965
|
+
'mvp',
|
|
966
|
+
'mvvm',
|
|
967
|
+
'layered',
|
|
968
|
+
'hexagonal',
|
|
969
|
+
'clean',
|
|
970
|
+
];
|
|
971
|
+
for (const keyword of patternKeywords) {
|
|
972
|
+
if (content.toLowerCase().includes(keyword)) {
|
|
973
|
+
patterns.push(keyword);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
return patterns;
|
|
977
|
+
}
|
|
978
|
+
export default generateAdrBootstrapScripts;
|
|
979
|
+
//# sourceMappingURL=adr-bootstrap-validation-tool.js.map
|