mcp-adr-analysis-server 2.1.19 → 2.1.22
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 +1 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/config/ai-config.d.ts +54 -6
- package/dist/src/config/ai-config.d.ts.map +1 -1
- package/dist/src/config/ai-config.js +69 -6
- package/dist/src/config/ai-config.js.map +1 -1
- package/dist/src/config/ape-descriptions.d.ts +77 -0
- package/dist/src/config/ape-descriptions.d.ts.map +1 -0
- package/dist/src/config/ape-descriptions.js +177 -0
- package/dist/src/config/ape-descriptions.js.map +1 -0
- package/dist/src/index.d.ts +40 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +564 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/prompts/adr-suggestion-prompts.d.ts +5 -0
- package/dist/src/prompts/adr-suggestion-prompts.d.ts.map +1 -1
- package/dist/src/prompts/adr-suggestion-prompts.js +22 -1
- package/dist/src/prompts/adr-suggestion-prompts.js.map +1 -1
- package/dist/src/prompts/prompt-catalog.d.ts +95 -0
- package/dist/src/prompts/prompt-catalog.d.ts.map +1 -0
- package/dist/src/prompts/prompt-catalog.js +300 -0
- package/dist/src/prompts/prompt-catalog.js.map +1 -0
- package/dist/src/resources/adrs-discovered-resource.d.ts +124 -0
- package/dist/src/resources/adrs-discovered-resource.d.ts.map +1 -0
- package/dist/src/resources/adrs-discovered-resource.js +174 -0
- package/dist/src/resources/adrs-discovered-resource.js.map +1 -0
- package/dist/src/resources/adrs-review-resource.d.ts +82 -0
- package/dist/src/resources/adrs-review-resource.d.ts.map +1 -0
- package/dist/src/resources/adrs-review-resource.js +160 -0
- package/dist/src/resources/adrs-review-resource.js.map +1 -0
- package/dist/src/resources/architectural-context-resource.d.ts +95 -0
- package/dist/src/resources/architectural-context-resource.d.ts.map +1 -0
- package/dist/src/resources/architectural-context-resource.js +428 -0
- package/dist/src/resources/architectural-context-resource.js.map +1 -0
- package/dist/src/resources/conversation-snapshot-resource.d.ts +92 -0
- package/dist/src/resources/conversation-snapshot-resource.d.ts.map +1 -0
- package/dist/src/resources/conversation-snapshot-resource.js +122 -0
- package/dist/src/resources/conversation-snapshot-resource.js.map +1 -0
- package/dist/src/resources/deployment-status-resource.js +1 -1
- package/dist/src/resources/deployment-status-resource.js.map +1 -1
- package/dist/src/resources/environment-analysis-resource.js +1 -1
- package/dist/src/resources/environment-analysis-resource.js.map +1 -1
- package/dist/src/resources/knowledge-graph-resource.d.ts +129 -0
- package/dist/src/resources/knowledge-graph-resource.d.ts.map +1 -0
- package/dist/src/resources/knowledge-graph-resource.js +217 -0
- package/dist/src/resources/knowledge-graph-resource.js.map +1 -0
- package/dist/src/resources/memory-expand-resource.d.ts +90 -0
- package/dist/src/resources/memory-expand-resource.d.ts.map +1 -0
- package/dist/src/resources/memory-expand-resource.js +176 -0
- package/dist/src/resources/memory-expand-resource.js.map +1 -0
- package/dist/src/resources/memory-stats-resource.d.ts +77 -0
- package/dist/src/resources/memory-stats-resource.d.ts.map +1 -0
- package/dist/src/resources/memory-stats-resource.js +108 -0
- package/dist/src/resources/memory-stats-resource.js.map +1 -0
- package/dist/src/resources/project-metrics-resource.js +1 -1
- package/dist/src/resources/project-metrics-resource.js.map +1 -1
- package/dist/src/resources/resource-cache.d.ts.map +1 -1
- package/dist/src/resources/resource-cache.js +2 -1
- package/dist/src/resources/resource-cache.js.map +1 -1
- package/dist/src/resources/server-context-resource.d.ts +69 -0
- package/dist/src/resources/server-context-resource.d.ts.map +1 -0
- package/dist/src/resources/server-context-resource.js +104 -0
- package/dist/src/resources/server-context-resource.js.map +1 -0
- package/dist/src/resources/tool-catalog-resource.d.ts +122 -0
- package/dist/src/resources/tool-catalog-resource.d.ts.map +1 -0
- package/dist/src/resources/tool-catalog-resource.js +167 -0
- package/dist/src/resources/tool-catalog-resource.js.map +1 -0
- package/dist/src/tools/adr-bootstrap-validation-tool.d.ts.map +1 -1
- package/dist/src/tools/adr-bootstrap-validation-tool.js +7 -6
- package/dist/src/tools/adr-bootstrap-validation-tool.js.map +1 -1
- package/dist/src/tools/adr-suggestion-tool.d.ts +5 -0
- package/dist/src/tools/adr-suggestion-tool.d.ts.map +1 -1
- package/dist/src/tools/adr-suggestion-tool.js +40 -71
- package/dist/src/tools/adr-suggestion-tool.js.map +1 -1
- package/dist/src/tools/bootstrap-validation-loop-tool.d.ts +23 -1
- package/dist/src/tools/bootstrap-validation-loop-tool.d.ts.map +1 -1
- package/dist/src/tools/bootstrap-validation-loop-tool.js +15 -5
- package/dist/src/tools/bootstrap-validation-loop-tool.js.map +1 -1
- package/dist/src/tools/ce-mcp-tools.d.ts +291 -0
- package/dist/src/tools/ce-mcp-tools.d.ts.map +1 -0
- package/dist/src/tools/ce-mcp-tools.js +1188 -0
- package/dist/src/tools/ce-mcp-tools.js.map +1 -0
- package/dist/src/tools/content-masking-tool.d.ts +11 -0
- package/dist/src/tools/content-masking-tool.d.ts.map +1 -1
- package/dist/src/tools/content-masking-tool.js +13 -6
- package/dist/src/tools/content-masking-tool.js.map +1 -1
- package/dist/src/tools/deployment-readiness-tool.d.ts +11 -0
- package/dist/src/tools/deployment-readiness-tool.d.ts.map +1 -1
- package/dist/src/tools/deployment-readiness-tool.js +10 -4
- package/dist/src/tools/deployment-readiness-tool.js.map +1 -1
- package/dist/src/tools/environment-analysis-tool.d.ts +96 -1
- package/dist/src/tools/environment-analysis-tool.d.ts.map +1 -1
- package/dist/src/tools/environment-analysis-tool.js +38 -46
- package/dist/src/tools/environment-analysis-tool.js.map +1 -1
- package/dist/src/tools/research-question-tool.d.ts.map +1 -1
- package/dist/src/tools/research-question-tool.js +3 -2
- package/dist/src/tools/research-question-tool.js.map +1 -1
- package/dist/src/tools/review-existing-adrs-tool.d.ts +5 -0
- package/dist/src/tools/review-existing-adrs-tool.d.ts.map +1 -1
- package/dist/src/tools/review-existing-adrs-tool.js +123 -42
- package/dist/src/tools/review-existing-adrs-tool.js.map +1 -1
- package/dist/src/tools/rule-generation-tool.d.ts.map +1 -1
- package/dist/src/tools/rule-generation-tool.js +3 -5
- package/dist/src/tools/rule-generation-tool.js.map +1 -1
- package/dist/src/tools/search-codebase-tool.d.ts +148 -0
- package/dist/src/tools/search-codebase-tool.d.ts.map +1 -0
- package/dist/src/tools/search-codebase-tool.js +406 -0
- package/dist/src/tools/search-codebase-tool.js.map +1 -0
- package/dist/src/tools/smart-git-push-tool-v2.js +1 -1
- package/dist/src/tools/smart-git-push-tool-v2.js.map +1 -1
- package/dist/src/tools/tool-catalog.d.ts +134 -0
- package/dist/src/tools/tool-catalog.d.ts.map +1 -0
- package/dist/src/tools/tool-catalog.js +1431 -0
- package/dist/src/tools/tool-catalog.js.map +1 -0
- package/dist/src/tools/tool-chain-orchestrator.d.ts +11 -2
- package/dist/src/tools/tool-chain-orchestrator.d.ts.map +1 -1
- package/dist/src/tools/tool-chain-orchestrator.js +11 -2
- package/dist/src/tools/tool-chain-orchestrator.js.map +1 -1
- package/dist/src/tools/tool-dispatcher.d.ts +98 -0
- package/dist/src/tools/tool-dispatcher.d.ts.map +1 -0
- package/dist/src/tools/tool-dispatcher.js +225 -0
- package/dist/src/tools/tool-dispatcher.js.map +1 -0
- package/dist/src/tools/tree-sitter-code-tools.d.ts +184 -0
- package/dist/src/tools/tree-sitter-code-tools.d.ts.map +1 -0
- package/dist/src/tools/tree-sitter-code-tools.js +642 -0
- package/dist/src/tools/tree-sitter-code-tools.js.map +1 -0
- package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts +22 -0
- package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts.map +1 -1
- package/dist/src/tools/troubleshoot-guided-workflow-tool.js +20 -3
- package/dist/src/tools/troubleshoot-guided-workflow-tool.js.map +1 -1
- package/dist/src/tools/update-knowledge-tool.d.ts +89 -0
- package/dist/src/tools/update-knowledge-tool.d.ts.map +1 -0
- package/dist/src/tools/update-knowledge-tool.js +222 -0
- package/dist/src/tools/update-knowledge-tool.js.map +1 -0
- package/dist/src/types/ce-mcp.d.ts +248 -0
- package/dist/src/types/ce-mcp.d.ts.map +1 -0
- package/dist/src/types/ce-mcp.js +27 -0
- package/dist/src/types/ce-mcp.js.map +1 -0
- package/dist/src/utils/adr-context-detector.js +1 -1
- package/dist/src/utils/adr-context-detector.js.map +1 -1
- package/dist/src/utils/adr-planning-task-integration.d.ts +260 -0
- package/dist/src/utils/adr-planning-task-integration.d.ts.map +1 -0
- package/dist/src/utils/adr-planning-task-integration.js +466 -0
- package/dist/src/utils/adr-planning-task-integration.js.map +1 -0
- package/dist/src/utils/adr-timeline-extractor.d.ts.map +1 -1
- package/dist/src/utils/adr-timeline-extractor.js +3 -2
- package/dist/src/utils/adr-timeline-extractor.js.map +1 -1
- package/dist/src/utils/ai-executor.d.ts +10 -0
- package/dist/src/utils/ai-executor.d.ts.map +1 -1
- package/dist/src/utils/ai-executor.js +14 -3
- package/dist/src/utils/ai-executor.js.map +1 -1
- package/dist/src/utils/automatic-prompt-engineering.d.ts +5 -0
- package/dist/src/utils/automatic-prompt-engineering.d.ts.map +1 -1
- package/dist/src/utils/automatic-prompt-engineering.js +10 -90
- package/dist/src/utils/automatic-prompt-engineering.js.map +1 -1
- package/dist/src/utils/bootstrap-task-integration.d.ts +214 -0
- package/dist/src/utils/bootstrap-task-integration.d.ts.map +1 -0
- package/dist/src/utils/bootstrap-task-integration.js +365 -0
- package/dist/src/utils/bootstrap-task-integration.js.map +1 -0
- package/dist/src/utils/dag-executor.d.ts.map +1 -1
- package/dist/src/utils/dag-executor.js +48 -15
- package/dist/src/utils/dag-executor.js.map +1 -1
- package/dist/src/utils/deployment-task-integration.d.ts +260 -0
- package/dist/src/utils/deployment-task-integration.d.ts.map +1 -0
- package/dist/src/utils/deployment-task-integration.js +393 -0
- package/dist/src/utils/deployment-task-integration.js.map +1 -0
- package/dist/src/utils/dynamic-deployment-intelligence.js +1 -1
- package/dist/src/utils/dynamic-deployment-intelligence.js.map +1 -1
- package/dist/src/utils/enhanced-logging.d.ts +3 -0
- package/dist/src/utils/enhanced-logging.d.ts.map +1 -1
- package/dist/src/utils/enhanced-logging.js +9 -30
- package/dist/src/utils/enhanced-logging.js.map +1 -1
- package/dist/src/utils/environment-capability-registry.js +1 -1
- package/dist/src/utils/environment-capability-registry.js.map +1 -1
- package/dist/src/utils/file-system.d.ts.map +1 -1
- package/dist/src/utils/file-system.js +33 -3
- package/dist/src/utils/file-system.js.map +1 -1
- package/dist/src/utils/gitleaks-detector.js +1 -1
- package/dist/src/utils/gitleaks-detector.js.map +1 -1
- package/dist/src/utils/knowledge-graph-manager.d.ts +13 -0
- package/dist/src/utils/knowledge-graph-manager.d.ts.map +1 -1
- package/dist/src/utils/knowledge-graph-manager.js +13 -0
- package/dist/src/utils/knowledge-graph-manager.js.map +1 -1
- package/dist/src/utils/prompt-execution.d.ts +29 -1
- package/dist/src/utils/prompt-execution.d.ts.map +1 -1
- package/dist/src/utils/prompt-execution.js +29 -1
- package/dist/src/utils/prompt-execution.js.map +1 -1
- package/dist/src/utils/research-orchestrator.d.ts +87 -1
- package/dist/src/utils/research-orchestrator.d.ts.map +1 -1
- package/dist/src/utils/research-orchestrator.js +121 -17
- package/dist/src/utils/research-orchestrator.js.map +1 -1
- package/dist/src/utils/research-task-integration.d.ts +297 -0
- package/dist/src/utils/research-task-integration.d.ts.map +1 -0
- package/dist/src/utils/research-task-integration.js +449 -0
- package/dist/src/utils/research-task-integration.js.map +1 -0
- package/dist/src/utils/ripgrep-wrapper.d.ts.map +1 -1
- package/dist/src/utils/ripgrep-wrapper.js +17 -3
- package/dist/src/utils/ripgrep-wrapper.js.map +1 -1
- package/dist/src/utils/sandbox-executor.d.ts +145 -0
- package/dist/src/utils/sandbox-executor.d.ts.map +1 -0
- package/dist/src/utils/sandbox-executor.js +642 -0
- package/dist/src/utils/sandbox-executor.js.map +1 -0
- package/dist/src/utils/server-context-generator.d.ts +5 -0
- package/dist/src/utils/server-context-generator.d.ts.map +1 -1
- package/dist/src/utils/server-context-generator.js +38 -0
- package/dist/src/utils/server-context-generator.js.map +1 -1
- package/dist/src/utils/task-manager.d.ts +239 -0
- package/dist/src/utils/task-manager.d.ts.map +1 -0
- package/dist/src/utils/task-manager.js +528 -0
- package/dist/src/utils/task-manager.js.map +1 -0
- package/dist/src/utils/task-persistence.d.ts +82 -0
- package/dist/src/utils/task-persistence.d.ts.map +1 -0
- package/dist/src/utils/task-persistence.js +248 -0
- package/dist/src/utils/task-persistence.js.map +1 -0
- package/dist/src/utils/test-aware-defaults.d.ts +57 -0
- package/dist/src/utils/test-aware-defaults.d.ts.map +1 -0
- package/dist/src/utils/test-aware-defaults.js +71 -0
- package/dist/src/utils/test-aware-defaults.js.map +1 -0
- package/dist/src/utils/tree-sitter-analyzer.d.ts +42 -5
- package/dist/src/utils/tree-sitter-analyzer.d.ts.map +1 -1
- package/dist/src/utils/tree-sitter-analyzer.js +499 -17
- package/dist/src/utils/tree-sitter-analyzer.js.map +1 -1
- package/package.json +25 -20
- package/dist/src/tools/smart-git-push-tool.d.ts +0 -55
- package/dist/src/tools/smart-git-push-tool.d.ts.map +0 -1
- package/dist/src/tools/smart-git-push-tool.js +0 -1011
- package/dist/src/tools/smart-git-push-tool.js.map +0 -1
|
@@ -1,1011 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Smart Git Push MCP Tool - Knowledge Graph Enhanced
|
|
3
|
-
*
|
|
4
|
-
* AI-powered git push with full knowledge graph integration and architectural awareness
|
|
5
|
-
* Leverages the complete .mcp-adr-cache system for intelligent decision making
|
|
6
|
-
*
|
|
7
|
-
* IMPORTANT FOR AI ASSISTANTS: This tool is deeply integrated with the knowledge graph
|
|
8
|
-
* and cache system. It performs comprehensive analysis before allowing pushes:
|
|
9
|
-
*
|
|
10
|
-
* Knowledge Graph Integration:
|
|
11
|
-
* - Analyzes active intents and their progress toward goals
|
|
12
|
-
* - Checks ADR compliance of changes being pushed
|
|
13
|
-
* - Verifies architectural alignment with project decisions
|
|
14
|
-
* - Tracks tool execution chains and their impacts
|
|
15
|
-
*
|
|
16
|
-
* Cache System Dependencies:
|
|
17
|
-
* - REQUIRES: .mcp-adr-cache/knowledge-graph-snapshots.json (for context analysis)
|
|
18
|
-
* - REQUIRES: .mcp-adr-cache/todo-data.json (for task dependency checking)
|
|
19
|
-
* - UPDATES: .mcp-adr-cache/todo-sync-state.json (after successful pushes)
|
|
20
|
-
* - UPDATES: .mcp-adr-cache/project-health-scores.json (continuous scoring)
|
|
21
|
-
*
|
|
22
|
-
* Architectural Intelligence:
|
|
23
|
-
* - Blocks pushes that violate architectural decisions
|
|
24
|
-
* - Ensures critical tasks are completed before deployment-related pushes
|
|
25
|
-
* - Validates that changes advance stated project goals
|
|
26
|
-
* - Provides context-aware recommendations based on project state
|
|
27
|
-
*
|
|
28
|
-
* Use this tool when you want AI-powered git push decisions based on project context.
|
|
29
|
-
*/
|
|
30
|
-
import { McpAdrError } from '../types/index.js';
|
|
31
|
-
import { execSync } from 'child_process';
|
|
32
|
-
import { readFileSync, existsSync, statSync } from 'fs';
|
|
33
|
-
import { join, basename } from 'path';
|
|
34
|
-
import { jsonSafeFilePath, jsonSafeMarkdownList, jsonSafeError, jsonSafeUserInput, } from '../utils/json-safe.js';
|
|
35
|
-
import { validateMcpResponse } from '../utils/mcp-response-validator.js';
|
|
36
|
-
import { KnowledgeGraphManager } from '../utils/knowledge-graph-manager.js';
|
|
37
|
-
/**
|
|
38
|
-
* Main smart git push function - Knowledge Graph Enhanced Version
|
|
39
|
-
*/
|
|
40
|
-
async function _smartGitPushInternal(args) {
|
|
41
|
-
const { branch, message, skipValidation = false, allowedArtifacts = [], sensitivityLevel = 'moderate', dryRun = false, projectPath = process.cwd(), checkReleaseReadiness = false, releaseType = 'minor', skipKnowledgeGraphAnalysis = false, } = args;
|
|
42
|
-
try {
|
|
43
|
-
// Step 1: Get staged files using git CLI
|
|
44
|
-
const stagedFiles = await getStagedFiles(projectPath);
|
|
45
|
-
// Step 2: Perform Knowledge Graph Analysis (NEW - this is the smart part!)
|
|
46
|
-
let kgAnalysis = null;
|
|
47
|
-
if (!skipKnowledgeGraphAnalysis) {
|
|
48
|
-
try {
|
|
49
|
-
kgAnalysis = await analyzeKnowledgeGraphContext(projectPath, stagedFiles);
|
|
50
|
-
}
|
|
51
|
-
catch (kgError) {
|
|
52
|
-
// Knowledge graph analysis failed, continue with warning
|
|
53
|
-
console.error('Knowledge graph analysis failed:', kgError);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
// Step 3: Check release readiness if requested (enhanced with KG data)
|
|
57
|
-
let releaseReadinessResult = null;
|
|
58
|
-
if (checkReleaseReadiness) {
|
|
59
|
-
try {
|
|
60
|
-
const { analyzeReleaseReadiness } = await import('../utils/release-readiness-detector.js');
|
|
61
|
-
releaseReadinessResult = await analyzeReleaseReadiness({
|
|
62
|
-
projectPath,
|
|
63
|
-
releaseType,
|
|
64
|
-
includeAnalysis: true,
|
|
65
|
-
});
|
|
66
|
-
// Update deployment readiness score in health scoring system
|
|
67
|
-
try {
|
|
68
|
-
// ProjectHealthScoring removed - skip health scoring
|
|
69
|
-
console.warn('⚠️ ProjectHealthScoring is deprecated and was removed in memory-centric transformation');
|
|
70
|
-
// Skip health scoring update - ProjectHealthScoring removed
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
// Silently handle health scoring errors
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
// Silently handle release readiness analysis errors
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (stagedFiles.length === 0) {
|
|
81
|
-
let responseText = `# Smart Git Push - No Changes
|
|
82
|
-
|
|
83
|
-
## Status
|
|
84
|
-
No staged files found. Use \`git add\` to stage files before pushing.
|
|
85
|
-
|
|
86
|
-
## Available Commands
|
|
87
|
-
- \`git add .\` - Stage all changes
|
|
88
|
-
- \`git add <file>\` - Stage specific file
|
|
89
|
-
- \`git status\` - Check current status
|
|
90
|
-
`;
|
|
91
|
-
// Add knowledge graph context even when no files are staged
|
|
92
|
-
if (kgAnalysis) {
|
|
93
|
-
responseText += `
|
|
94
|
-
|
|
95
|
-
## Knowledge Graph Context
|
|
96
|
-
### Current Project Status
|
|
97
|
-
- **Active Intents**: ${kgAnalysis.activeIntents.length}
|
|
98
|
-
- **Goal Progress**: ${kgAnalysis.projectGoalProgress.overallProgress}%
|
|
99
|
-
- **Task Dependencies**: ${kgAnalysis.taskDependencies.completed.length} completed, ${kgAnalysis.taskDependencies.pending.length} pending
|
|
100
|
-
|
|
101
|
-
${kgAnalysis.activeIntents.length > 0
|
|
102
|
-
? `
|
|
103
|
-
### Active Intents
|
|
104
|
-
${kgAnalysis.activeIntents.map(intent => `- **${intent.currentStatus}**: ${jsonSafeUserInput(intent.humanRequest.substring(0, 80))}...`).join('\n')}
|
|
105
|
-
`
|
|
106
|
-
: ''}
|
|
107
|
-
|
|
108
|
-
${kgAnalysis.taskDependencies.pending.length > 0
|
|
109
|
-
? `
|
|
110
|
-
### Pending Tasks
|
|
111
|
-
Consider working on these tasks before your next push:
|
|
112
|
-
${kgAnalysis.taskDependencies.pending
|
|
113
|
-
.slice(0, 5)
|
|
114
|
-
.map(task => `- ${jsonSafeUserInput(task)}`)
|
|
115
|
-
.join('\n')}
|
|
116
|
-
`
|
|
117
|
-
: ''}
|
|
118
|
-
`;
|
|
119
|
-
}
|
|
120
|
-
// Add release readiness info if checked
|
|
121
|
-
if (releaseReadinessResult) {
|
|
122
|
-
responseText += `
|
|
123
|
-
|
|
124
|
-
## Release Readiness Analysis
|
|
125
|
-
${jsonSafeUserInput(releaseReadinessResult.summary)}
|
|
126
|
-
|
|
127
|
-
### Recommendations
|
|
128
|
-
${jsonSafeMarkdownList(releaseReadinessResult.recommendations)}
|
|
129
|
-
|
|
130
|
-
${releaseReadinessResult.isReady
|
|
131
|
-
? '✅ **Project is ready for release!** Consider creating a release after staging files.'
|
|
132
|
-
: '❌ **Project is not ready for release.** Address blockers before proceeding.'}
|
|
133
|
-
`;
|
|
134
|
-
}
|
|
135
|
-
return {
|
|
136
|
-
content: [
|
|
137
|
-
{
|
|
138
|
-
type: 'text',
|
|
139
|
-
text: responseText,
|
|
140
|
-
},
|
|
141
|
-
],
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
// Step 3: Analyze staged files if validation is enabled
|
|
145
|
-
let validationResults = [];
|
|
146
|
-
if (!skipValidation) {
|
|
147
|
-
validationResults = await validateStagedFiles(stagedFiles, {
|
|
148
|
-
sensitivityLevel,
|
|
149
|
-
allowedArtifacts,
|
|
150
|
-
projectPath,
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
// Step 4: Check for blocking conditions (Enhanced with Knowledge Graph)
|
|
154
|
-
const issues = validationResults.filter(r => r.issues.length > 0);
|
|
155
|
-
// Check if release readiness should block push
|
|
156
|
-
let releaseReadinessBlocked = false;
|
|
157
|
-
if (releaseReadinessResult && !releaseReadinessResult.isReady) {
|
|
158
|
-
const criticalBlockers = releaseReadinessResult.blockers.filter(b => b.severity === 'error');
|
|
159
|
-
if (criticalBlockers.length > 0) {
|
|
160
|
-
releaseReadinessBlocked = true;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
// Check Knowledge Graph for blocking conditions (NEW!)
|
|
164
|
-
let knowledgeGraphBlocked = false;
|
|
165
|
-
const kgBlockingConditions = kgAnalysis?.blockingConditions?.filter(bc => bc.severity === 'error') || [];
|
|
166
|
-
if (kgBlockingConditions.length > 0) {
|
|
167
|
-
knowledgeGraphBlocked = true;
|
|
168
|
-
}
|
|
169
|
-
// Check for blocking conditions
|
|
170
|
-
const hasBlockingErrors = issues.some(issue => issue.issues.some(i => i.severity === 'error'));
|
|
171
|
-
const shouldBlock = hasBlockingErrors || releaseReadinessBlocked || knowledgeGraphBlocked;
|
|
172
|
-
if (shouldBlock && !dryRun) {
|
|
173
|
-
let cancelText = `# Smart Git Push - Blocked
|
|
174
|
-
|
|
175
|
-
## Validation Issues
|
|
176
|
-
Push blocked due to critical issues that must be resolved.
|
|
177
|
-
|
|
178
|
-
## Issues Found
|
|
179
|
-
${issues
|
|
180
|
-
.map(issue => `
|
|
181
|
-
|
|
182
|
-
### ${jsonSafeFilePath(issue.file)}
|
|
183
|
-
${issue.issues.map(i => `- **${i.severity.toUpperCase()}**: ${jsonSafeUserInput(i.message)}`).join('\n')}
|
|
184
|
-
|
|
185
|
-
**Suggestions:**
|
|
186
|
-
${jsonSafeMarkdownList(issue.suggestions)}
|
|
187
|
-
`)
|
|
188
|
-
.join('\n')}
|
|
189
|
-
`;
|
|
190
|
-
// Add release readiness info if checked and blocked
|
|
191
|
-
if (releaseReadinessResult && releaseReadinessBlocked) {
|
|
192
|
-
cancelText += `
|
|
193
|
-
|
|
194
|
-
## Release Readiness Issues
|
|
195
|
-
${jsonSafeUserInput(releaseReadinessResult.summary)}
|
|
196
|
-
|
|
197
|
-
### Critical Blockers
|
|
198
|
-
${releaseReadinessResult.blockers
|
|
199
|
-
.filter(b => b.severity === 'error')
|
|
200
|
-
.map(b => `- **${b.type}**: ${jsonSafeUserInput(b.message)}`)
|
|
201
|
-
.join('\n')}
|
|
202
|
-
|
|
203
|
-
### Recommendations
|
|
204
|
-
${jsonSafeMarkdownList(releaseReadinessResult.recommendations)}
|
|
205
|
-
`;
|
|
206
|
-
}
|
|
207
|
-
// Add knowledge graph blocking information (NEW!)
|
|
208
|
-
if (kgAnalysis && knowledgeGraphBlocked) {
|
|
209
|
-
cancelText += `
|
|
210
|
-
|
|
211
|
-
## Knowledge Graph Analysis - Blocking Conditions
|
|
212
|
-
The following architectural and project context issues prevent this push:
|
|
213
|
-
|
|
214
|
-
### Critical Issues
|
|
215
|
-
${kgBlockingConditions.map(bc => `- **${bc.type}**: ${jsonSafeUserInput(bc.message)}`).join('\n')}
|
|
216
|
-
|
|
217
|
-
### Recommendations
|
|
218
|
-
${kgBlockingConditions.map(bc => `- ${jsonSafeUserInput(bc.recommendation)}`).join('\n')}
|
|
219
|
-
|
|
220
|
-
### Project Context
|
|
221
|
-
- **Active Intents**: ${kgAnalysis.activeIntents.length}
|
|
222
|
-
- **Architectural Alignment**: ${kgAnalysis.architecturalAlignment.score}%
|
|
223
|
-
- **Goal Progress**: ${kgAnalysis.projectGoalProgress.overallProgress}%
|
|
224
|
-
- **Pending Critical Tasks**: ${kgAnalysis.taskDependencies.blocking.length}
|
|
225
|
-
`;
|
|
226
|
-
}
|
|
227
|
-
// Add general knowledge graph insights if available
|
|
228
|
-
if (kgAnalysis && !knowledgeGraphBlocked) {
|
|
229
|
-
cancelText += `
|
|
230
|
-
|
|
231
|
-
## Knowledge Graph Insights
|
|
232
|
-
### Project Status
|
|
233
|
-
- **Active Intents**: ${kgAnalysis.activeIntents.length}
|
|
234
|
-
- **Architectural Alignment**: ${kgAnalysis.architecturalAlignment.score}%
|
|
235
|
-
- **Goal Progress**: ${kgAnalysis.projectGoalProgress.overallProgress}%
|
|
236
|
-
|
|
237
|
-
### Warnings
|
|
238
|
-
${kgAnalysis.blockingConditions
|
|
239
|
-
.filter(bc => bc.severity === 'warning')
|
|
240
|
-
.map(bc => `- **${bc.type}**: ${jsonSafeUserInput(bc.message)}`)
|
|
241
|
-
.join('\n')}
|
|
242
|
-
`;
|
|
243
|
-
}
|
|
244
|
-
return {
|
|
245
|
-
content: [
|
|
246
|
-
{
|
|
247
|
-
type: 'text',
|
|
248
|
-
text: cancelText,
|
|
249
|
-
},
|
|
250
|
-
],
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
// Step 5: Execute git push if not dry run
|
|
254
|
-
if (!dryRun) {
|
|
255
|
-
const pushResult = await executePush(projectPath, branch, message);
|
|
256
|
-
// Update TODO tasks with KG integration
|
|
257
|
-
if (kgAnalysis) {
|
|
258
|
-
try {
|
|
259
|
-
// TodoJsonManager removed - skipping todo validation
|
|
260
|
-
console.warn('⚠️ TodoJsonManager is deprecated and was removed in memory-centric transformation');
|
|
261
|
-
// Skip todo task update - TodoJsonManager removed
|
|
262
|
-
}
|
|
263
|
-
catch (todoError) {
|
|
264
|
-
console.error('Error updating TODO tasks with KG:', todoError);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
const successText = `# Smart Git Push - Success ✅
|
|
268
|
-
|
|
269
|
-
## Push Details
|
|
270
|
-
- **Branch**: ${branch || 'current'}
|
|
271
|
-
- **Files**: ${stagedFiles.length} staged files
|
|
272
|
-
- **Validation**: ${skipValidation ? 'Skipped' : 'Completed'}
|
|
273
|
-
- **Issues Found**: ${issues.length}
|
|
274
|
-
- **Sensitivity Level**: ${sensitivityLevel}
|
|
275
|
-
${checkReleaseReadiness ? `- **Release Readiness**: ${releaseReadinessResult?.isReady ? '✅ Ready' : '❌ Not Ready'}` : ''}
|
|
276
|
-
${kgAnalysis ? `- **Knowledge Graph Analysis**: ✅ Completed` : ''}
|
|
277
|
-
|
|
278
|
-
## Files Pushed
|
|
279
|
-
${stagedFiles.map(f => `- ${jsonSafeFilePath(f.path)} (${f.status})`).join('\n')}
|
|
280
|
-
|
|
281
|
-
${kgAnalysis
|
|
282
|
-
? `
|
|
283
|
-
## Knowledge Graph Analysis
|
|
284
|
-
### Project Context
|
|
285
|
-
- **Active Intents**: ${kgAnalysis.activeIntents.length}
|
|
286
|
-
- **Architectural Alignment**: ${kgAnalysis.architecturalAlignment.score}%
|
|
287
|
-
- **Goal Progress**: ${kgAnalysis.projectGoalProgress.overallProgress}%
|
|
288
|
-
- **Task Dependencies**: ${kgAnalysis.taskDependencies.completed.length} completed, ${kgAnalysis.taskDependencies.pending.length} pending
|
|
289
|
-
|
|
290
|
-
### Architectural Insights
|
|
291
|
-
${kgAnalysis.architecturalAlignment.details.map(detail => `- ${jsonSafeUserInput(detail)}`).join('\n')}
|
|
292
|
-
|
|
293
|
-
${kgAnalysis.blockingConditions.length > 0
|
|
294
|
-
? `
|
|
295
|
-
### Warnings & Recommendations
|
|
296
|
-
${kgAnalysis.blockingConditions
|
|
297
|
-
.filter(bc => bc.severity === 'warning')
|
|
298
|
-
.map(bc => `- **${bc.type}**: ${jsonSafeUserInput(bc.message)}`)
|
|
299
|
-
.join('\n')}
|
|
300
|
-
`
|
|
301
|
-
: ''}
|
|
302
|
-
|
|
303
|
-
${kgAnalysis.projectGoalProgress.intentProgress.length > 0
|
|
304
|
-
? `
|
|
305
|
-
### Intent Progress
|
|
306
|
-
${kgAnalysis.projectGoalProgress.intentProgress.map(intent => `- **${intent.status}**: ${jsonSafeUserInput(intent.humanRequest.substring(0, 60))}... (${intent.progress}%)`).join('\n')}
|
|
307
|
-
`
|
|
308
|
-
: ''}
|
|
309
|
-
`
|
|
310
|
-
: ''}
|
|
311
|
-
|
|
312
|
-
${issues.length > 0
|
|
313
|
-
? `
|
|
314
|
-
|
|
315
|
-
## Validation Issues (Auto-Approved)
|
|
316
|
-
${issues
|
|
317
|
-
.map(issue => `
|
|
318
|
-
|
|
319
|
-
### ${jsonSafeFilePath(issue.file)}
|
|
320
|
-
${issue.issues.map(i => `- **${i.severity.toUpperCase()}**: ${jsonSafeUserInput(i.message)}`).join('\n')}
|
|
321
|
-
`)
|
|
322
|
-
.join('\n')}
|
|
323
|
-
`
|
|
324
|
-
: ''}
|
|
325
|
-
|
|
326
|
-
${releaseReadinessResult
|
|
327
|
-
? `
|
|
328
|
-
|
|
329
|
-
## Release Readiness Analysis
|
|
330
|
-
${jsonSafeUserInput(releaseReadinessResult.summary)}
|
|
331
|
-
|
|
332
|
-
### Post-Push Recommendations
|
|
333
|
-
${jsonSafeMarkdownList(releaseReadinessResult.recommendations)}
|
|
334
|
-
|
|
335
|
-
${releaseReadinessResult.isReady
|
|
336
|
-
? '🎉 **Congratulations!** This push completed a release-ready state. Consider creating a release tag.'
|
|
337
|
-
: '📋 **Next Steps**: Address remaining blockers to achieve release readiness.'}
|
|
338
|
-
`
|
|
339
|
-
: ''}
|
|
340
|
-
|
|
341
|
-
## Git Output
|
|
342
|
-
\`\`\`
|
|
343
|
-
${jsonSafeUserInput(pushResult.output)}
|
|
344
|
-
\`\`\`
|
|
345
|
-
|
|
346
|
-
## Next Steps
|
|
347
|
-
- Monitor CI/CD pipeline for build status
|
|
348
|
-
- Review any deployment processes
|
|
349
|
-
- Check for any post-push hooks or workflows
|
|
350
|
-
${releaseReadinessResult?.isReady ? '- Consider creating a release tag or publishing' : ''}
|
|
351
|
-
${kgAnalysis ? '- Review knowledge graph insights for follow-up tasks' : ''}
|
|
352
|
-
`;
|
|
353
|
-
return {
|
|
354
|
-
content: [
|
|
355
|
-
{
|
|
356
|
-
type: 'text',
|
|
357
|
-
text: successText,
|
|
358
|
-
},
|
|
359
|
-
],
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
else {
|
|
363
|
-
// Dry run - show what would happen
|
|
364
|
-
const dryRunText = `# Smart Git Push - Dry Run 🔍
|
|
365
|
-
|
|
366
|
-
## Analysis Complete
|
|
367
|
-
- **Files to Push**: ${stagedFiles.length}
|
|
368
|
-
- **Validation Issues**: ${issues.length}
|
|
369
|
-
- **Sensitivity Level**: ${sensitivityLevel}
|
|
370
|
-
- **Would Push to**: ${branch || 'current branch'}
|
|
371
|
-
${checkReleaseReadiness ? `- **Release Readiness**: ${releaseReadinessResult?.isReady ? '✅ Ready' : '❌ Not Ready'}` : ''}
|
|
372
|
-
${kgAnalysis ? `- **Knowledge Graph Analysis**: ✅ Completed` : ''}
|
|
373
|
-
|
|
374
|
-
## Staged Files
|
|
375
|
-
${stagedFiles.map(f => `- ${jsonSafeFilePath(f.path)} (${f.status}) - ${f.size} bytes`).join('\n')}
|
|
376
|
-
|
|
377
|
-
${kgAnalysis
|
|
378
|
-
? `
|
|
379
|
-
## Knowledge Graph Analysis Preview
|
|
380
|
-
### Project Context
|
|
381
|
-
- **Active Intents**: ${kgAnalysis.activeIntents.length}
|
|
382
|
-
- **Architectural Alignment**: ${kgAnalysis.architecturalAlignment.score}%
|
|
383
|
-
- **Goal Progress**: ${kgAnalysis.projectGoalProgress.overallProgress}%
|
|
384
|
-
- **Task Dependencies**: ${kgAnalysis.taskDependencies.completed.length} completed, ${kgAnalysis.taskDependencies.pending.length} pending
|
|
385
|
-
|
|
386
|
-
### Architectural Assessment
|
|
387
|
-
${kgAnalysis.architecturalAlignment.details.map(detail => `- ${jsonSafeUserInput(detail)}`).join('\n')}
|
|
388
|
-
|
|
389
|
-
${kgAnalysis.blockingConditions.length > 0
|
|
390
|
-
? `
|
|
391
|
-
### Potential Issues
|
|
392
|
-
${kgAnalysis.blockingConditions.map(bc => `- **${bc.type}** (${bc.severity}): ${jsonSafeUserInput(bc.message)}`).join('\n')}
|
|
393
|
-
`
|
|
394
|
-
: ''}
|
|
395
|
-
|
|
396
|
-
${kgAnalysis.projectGoalProgress.intentProgress.length > 0
|
|
397
|
-
? `
|
|
398
|
-
### Intent Progress Impact
|
|
399
|
-
${kgAnalysis.projectGoalProgress.intentProgress.map(intent => `- **${intent.status}**: ${jsonSafeUserInput(intent.humanRequest.substring(0, 60))}... (${intent.progress}%)`).join('\n')}
|
|
400
|
-
`
|
|
401
|
-
: ''}
|
|
402
|
-
`
|
|
403
|
-
: ''}
|
|
404
|
-
|
|
405
|
-
${issues.length > 0
|
|
406
|
-
? `
|
|
407
|
-
|
|
408
|
-
## Validation Issues Found
|
|
409
|
-
${issues
|
|
410
|
-
.map(issue => `
|
|
411
|
-
|
|
412
|
-
### ${jsonSafeFilePath(issue.file)}
|
|
413
|
-
${issue.issues.map(i => `- **${i.severity.toUpperCase()}**: ${jsonSafeUserInput(i.message)}`).join('\n')}
|
|
414
|
-
|
|
415
|
-
**Suggestions:**
|
|
416
|
-
${jsonSafeMarkdownList(issue.suggestions)}
|
|
417
|
-
`)
|
|
418
|
-
.join('\n')}
|
|
419
|
-
`
|
|
420
|
-
: '## ✅ No Validation Issues Found'}
|
|
421
|
-
|
|
422
|
-
${releaseReadinessResult
|
|
423
|
-
? `
|
|
424
|
-
|
|
425
|
-
## Release Readiness Analysis
|
|
426
|
-
${jsonSafeUserInput(releaseReadinessResult.summary)}
|
|
427
|
-
|
|
428
|
-
### Pre-Push Recommendations
|
|
429
|
-
${jsonSafeMarkdownList(releaseReadinessResult.recommendations)}
|
|
430
|
-
|
|
431
|
-
${releaseReadinessResult.isReady
|
|
432
|
-
? '🎉 **Ready for Release!** This push would complete all release requirements.'
|
|
433
|
-
: '📋 **Release Blockers**: Address these issues before considering this a release.'}
|
|
434
|
-
`
|
|
435
|
-
: ''}
|
|
436
|
-
|
|
437
|
-
## Command to Execute
|
|
438
|
-
\`\`\`bash
|
|
439
|
-
# Run without dry run to actually push
|
|
440
|
-
git push${branch ? ` origin ${branch}` : ''}
|
|
441
|
-
\`\`\`
|
|
442
|
-
|
|
443
|
-
**Note:** This was a dry run. No files were actually pushed.
|
|
444
|
-
`;
|
|
445
|
-
return {
|
|
446
|
-
content: [
|
|
447
|
-
{
|
|
448
|
-
type: 'text',
|
|
449
|
-
text: dryRunText,
|
|
450
|
-
},
|
|
451
|
-
],
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
catch (error) {
|
|
456
|
-
throw new McpAdrError(`Smart git push failed: ${jsonSafeError(error)}`, 'GIT_PUSH_ERROR');
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
/**
|
|
460
|
-
* Get staged files using git CLI
|
|
461
|
-
*/
|
|
462
|
-
async function getStagedFiles(projectPath) {
|
|
463
|
-
try {
|
|
464
|
-
// Get staged files with status
|
|
465
|
-
const gitOutput = execSync('git diff --cached --name-status', {
|
|
466
|
-
cwd: projectPath,
|
|
467
|
-
encoding: 'utf8',
|
|
468
|
-
});
|
|
469
|
-
if (!gitOutput.trim()) {
|
|
470
|
-
return [];
|
|
471
|
-
}
|
|
472
|
-
const files = [];
|
|
473
|
-
const lines = gitOutput.trim().split('\n');
|
|
474
|
-
for (const line of lines) {
|
|
475
|
-
const [status, ...pathParts] = line.split('\t');
|
|
476
|
-
const path = pathParts.join('\t'); // Handle filenames with tabs
|
|
477
|
-
const fullPath = join(projectPath, path);
|
|
478
|
-
let content;
|
|
479
|
-
let size = 0;
|
|
480
|
-
// Read file content if it exists (not for deleted files)
|
|
481
|
-
if (status !== 'D' && existsSync(fullPath)) {
|
|
482
|
-
try {
|
|
483
|
-
const stats = statSync(fullPath);
|
|
484
|
-
size = stats.size;
|
|
485
|
-
// Only read content for small files (< 100KB)
|
|
486
|
-
if (size < 100 * 1024) {
|
|
487
|
-
content = readFileSync(fullPath, 'utf8');
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
catch {
|
|
491
|
-
// Silently handle file read errors
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
files.push({
|
|
495
|
-
path,
|
|
496
|
-
status: mapGitStatus(status || 'M'),
|
|
497
|
-
content: content || '',
|
|
498
|
-
size,
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
return files;
|
|
502
|
-
}
|
|
503
|
-
catch (error) {
|
|
504
|
-
throw new McpAdrError(`Failed to get staged files: ${jsonSafeError(error)}`, 'GIT_STATUS_ERROR');
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* Map git status codes to readable names
|
|
509
|
-
*/
|
|
510
|
-
function mapGitStatus(status) {
|
|
511
|
-
switch (status) {
|
|
512
|
-
case 'A':
|
|
513
|
-
return 'added';
|
|
514
|
-
case 'M':
|
|
515
|
-
return 'modified';
|
|
516
|
-
case 'D':
|
|
517
|
-
return 'deleted';
|
|
518
|
-
case 'R':
|
|
519
|
-
return 'renamed';
|
|
520
|
-
default:
|
|
521
|
-
return 'modified';
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
/**
|
|
525
|
-
* Validate staged files for issues
|
|
526
|
-
*/
|
|
527
|
-
async function validateStagedFiles(files, options) {
|
|
528
|
-
const results = [];
|
|
529
|
-
for (const file of files) {
|
|
530
|
-
const issues = [];
|
|
531
|
-
const suggestions = [];
|
|
532
|
-
// Skip validation for deleted files
|
|
533
|
-
if (file.status === 'deleted') {
|
|
534
|
-
results.push({ file: file.path, issues, suggestions, approved: true });
|
|
535
|
-
continue;
|
|
536
|
-
}
|
|
537
|
-
// 1. Check for sensitive content
|
|
538
|
-
if (file.content) {
|
|
539
|
-
const sensitiveIssues = await checkSensitiveContent(file.content, file.path);
|
|
540
|
-
issues.push(...sensitiveIssues);
|
|
541
|
-
}
|
|
542
|
-
// 2. Check for LLM artifacts
|
|
543
|
-
const llmIssues = await checkLLMArtifacts(file.path, file.content);
|
|
544
|
-
issues.push(...llmIssues);
|
|
545
|
-
// 3. Check location rules
|
|
546
|
-
const locationIssues = await checkLocationRules(file.path, options.allowedArtifacts);
|
|
547
|
-
issues.push(...locationIssues);
|
|
548
|
-
// 4. Generate suggestions
|
|
549
|
-
const fileSuggestions = generateSuggestions(file.path, issues);
|
|
550
|
-
suggestions.push(...fileSuggestions);
|
|
551
|
-
results.push({
|
|
552
|
-
file: file.path,
|
|
553
|
-
issues,
|
|
554
|
-
suggestions,
|
|
555
|
-
approved: issues.length === 0 || issues.every(i => i.severity === 'info'),
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
return results;
|
|
559
|
-
}
|
|
560
|
-
/**
|
|
561
|
-
* Check for sensitive content using enhanced sensitive detector
|
|
562
|
-
*/
|
|
563
|
-
async function checkSensitiveContent(content, filePath) {
|
|
564
|
-
try {
|
|
565
|
-
// Use gitleaks for industry-standard secret detection
|
|
566
|
-
const { analyzeSensitiveContent } = await import('../utils/gitleaks-detector.js');
|
|
567
|
-
const result = await analyzeSensitiveContent(filePath, content);
|
|
568
|
-
// Convert to ValidationIssue format
|
|
569
|
-
const issues = [];
|
|
570
|
-
for (const match of result.matches) {
|
|
571
|
-
issues.push({
|
|
572
|
-
type: 'sensitive-content',
|
|
573
|
-
severity: match.pattern.severity === 'critical'
|
|
574
|
-
? 'error'
|
|
575
|
-
: match.pattern.severity === 'high'
|
|
576
|
-
? 'error'
|
|
577
|
-
: match.pattern.severity === 'medium'
|
|
578
|
-
? 'warning'
|
|
579
|
-
: 'info',
|
|
580
|
-
message: `${match.pattern.description}: ${match.match}`,
|
|
581
|
-
pattern: match.pattern.name,
|
|
582
|
-
line: match.line,
|
|
583
|
-
});
|
|
584
|
-
}
|
|
585
|
-
return issues;
|
|
586
|
-
}
|
|
587
|
-
catch {
|
|
588
|
-
// Silently handle sensitive content check errors
|
|
589
|
-
return [];
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
/**
|
|
593
|
-
* Check for LLM artifacts using enhanced detector
|
|
594
|
-
*/
|
|
595
|
-
async function checkLLMArtifacts(filePath, content) {
|
|
596
|
-
try {
|
|
597
|
-
// Use enhanced LLM artifact detector
|
|
598
|
-
const { detectLLMArtifacts } = await import('../utils/llm-artifact-detector.js');
|
|
599
|
-
const result = detectLLMArtifacts(filePath, content || '');
|
|
600
|
-
// Convert to ValidationIssue format
|
|
601
|
-
const issues = [];
|
|
602
|
-
for (const match of result.matches) {
|
|
603
|
-
const issue = {
|
|
604
|
-
type: 'llm-artifact',
|
|
605
|
-
severity: match.pattern.severity === 'error'
|
|
606
|
-
? 'error'
|
|
607
|
-
: match.pattern.severity === 'warning'
|
|
608
|
-
? 'warning'
|
|
609
|
-
: 'info',
|
|
610
|
-
message: `${match.pattern.description}: ${match.match}`,
|
|
611
|
-
pattern: match.pattern.name,
|
|
612
|
-
};
|
|
613
|
-
if (match.line !== undefined) {
|
|
614
|
-
issue.line = match.line;
|
|
615
|
-
}
|
|
616
|
-
issues.push(issue);
|
|
617
|
-
}
|
|
618
|
-
return issues;
|
|
619
|
-
}
|
|
620
|
-
catch {
|
|
621
|
-
// Silently handle LLM artifact check errors
|
|
622
|
-
return [];
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
/**
|
|
626
|
-
* Check location rules using enhanced location filter
|
|
627
|
-
*/
|
|
628
|
-
async function checkLocationRules(filePath, allowedArtifacts) {
|
|
629
|
-
try {
|
|
630
|
-
// Use enhanced location filter
|
|
631
|
-
const { validateFileLocationIntelligent } = await import('../utils/location-filter.js');
|
|
632
|
-
// Skip if explicitly allowed
|
|
633
|
-
if (allowedArtifacts.includes(basename(filePath)) || allowedArtifacts.includes(filePath)) {
|
|
634
|
-
return [];
|
|
635
|
-
}
|
|
636
|
-
// Read file content for intelligent analysis
|
|
637
|
-
let fileContent;
|
|
638
|
-
try {
|
|
639
|
-
fileContent = readFileSync(filePath, 'utf-8');
|
|
640
|
-
}
|
|
641
|
-
catch {
|
|
642
|
-
console.warn(`Could not read file for analysis: ${filePath}`);
|
|
643
|
-
}
|
|
644
|
-
const result = await validateFileLocationIntelligent(filePath, fileContent);
|
|
645
|
-
if (!result.isValid) {
|
|
646
|
-
const issues = [
|
|
647
|
-
{
|
|
648
|
-
type: 'wrong-location',
|
|
649
|
-
severity: result.severity === 'error'
|
|
650
|
-
? 'error'
|
|
651
|
-
: result.severity === 'warning'
|
|
652
|
-
? 'warning'
|
|
653
|
-
: 'info',
|
|
654
|
-
message: result.message,
|
|
655
|
-
pattern: result.rule?.name || 'location-rule',
|
|
656
|
-
},
|
|
657
|
-
];
|
|
658
|
-
// Add tree-sitter security insights
|
|
659
|
-
if (result.treeSitterAnalysis) {
|
|
660
|
-
const analysis = result.treeSitterAnalysis;
|
|
661
|
-
// Critical security issues
|
|
662
|
-
if (analysis.hasSecrets) {
|
|
663
|
-
issues.push({
|
|
664
|
-
type: 'security-risk',
|
|
665
|
-
severity: 'error',
|
|
666
|
-
message: `🔐 Security Risk: File contains ${analysis.secrets.length} potential secret(s). Secrets should be in secure locations or environment variables.`,
|
|
667
|
-
pattern: 'tree-sitter-secrets',
|
|
668
|
-
});
|
|
669
|
-
}
|
|
670
|
-
// Dangerous imports
|
|
671
|
-
const dangerousImports = analysis.imports.filter(i => i.isDangerous);
|
|
672
|
-
if (dangerousImports.length > 0) {
|
|
673
|
-
issues.push({
|
|
674
|
-
type: 'security-risk',
|
|
675
|
-
severity: 'warning',
|
|
676
|
-
message: `⚠️ Dangerous imports detected: ${dangerousImports.map(i => i.module).join(', ')}. Consider safer alternatives.`,
|
|
677
|
-
pattern: 'tree-sitter-dangerous-imports',
|
|
678
|
-
});
|
|
679
|
-
}
|
|
680
|
-
// Infrastructure security risks
|
|
681
|
-
const riskyInfra = analysis.infraStructure.filter(i => i.securityRisks.length > 0);
|
|
682
|
-
if (riskyInfra.length > 0) {
|
|
683
|
-
const risks = riskyInfra.flatMap(i => i.securityRisks);
|
|
684
|
-
issues.push({
|
|
685
|
-
type: 'security-risk',
|
|
686
|
-
severity: 'error',
|
|
687
|
-
message: `🏗️ Infrastructure security risks: ${risks.join(', ')}. Review before deployment.`,
|
|
688
|
-
pattern: 'tree-sitter-infra-security',
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
|
-
// Architectural violations
|
|
692
|
-
if (result.intelligentReasons?.some(r => r.includes('violates'))) {
|
|
693
|
-
issues.push({
|
|
694
|
-
type: 'architecture-violation',
|
|
695
|
-
severity: 'error',
|
|
696
|
-
message: `🏗️ Architectural violation detected. This may affect system maintainability and scalability.`,
|
|
697
|
-
pattern: 'tree-sitter-architecture',
|
|
698
|
-
});
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
return issues;
|
|
702
|
-
}
|
|
703
|
-
return [];
|
|
704
|
-
}
|
|
705
|
-
catch {
|
|
706
|
-
// Silently handle location rule check errors
|
|
707
|
-
return [];
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
/**
|
|
711
|
-
* Generate suggestions for issues
|
|
712
|
-
*/
|
|
713
|
-
function generateSuggestions(filePath, issues) {
|
|
714
|
-
const suggestions = [];
|
|
715
|
-
const fileName = basename(filePath);
|
|
716
|
-
for (const issue of issues) {
|
|
717
|
-
switch (issue.type) {
|
|
718
|
-
case 'sensitive-content':
|
|
719
|
-
suggestions.push(`Use content masking tool: analyze_content_security`);
|
|
720
|
-
suggestions.push(`Move sensitive data to environment variables`);
|
|
721
|
-
suggestions.push(`Add ${filePath} to .gitignore if it's config`);
|
|
722
|
-
break;
|
|
723
|
-
case 'llm-artifact':
|
|
724
|
-
suggestions.push(`Move ${fileName} to tests/ directory`);
|
|
725
|
-
suggestions.push(`Move ${fileName} to scripts/ directory`);
|
|
726
|
-
suggestions.push(`Add ${filePath} to .gitignore`);
|
|
727
|
-
suggestions.push(`Remove file if it's temporary`);
|
|
728
|
-
break;
|
|
729
|
-
case 'wrong-location':
|
|
730
|
-
suggestions.push(`Move ${fileName} to tests/ directory`);
|
|
731
|
-
suggestions.push(`Move ${fileName} to scripts/ directory`);
|
|
732
|
-
suggestions.push(`Move ${fileName} to tools/ directory`);
|
|
733
|
-
break;
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
return [...new Set(suggestions)]; // Remove duplicates
|
|
737
|
-
}
|
|
738
|
-
/**
|
|
739
|
-
* Execute git push
|
|
740
|
-
*/
|
|
741
|
-
async function executePush(projectPath, branch, message) {
|
|
742
|
-
try {
|
|
743
|
-
let output = '';
|
|
744
|
-
// Commit if there are staged changes and a message is provided
|
|
745
|
-
if (message) {
|
|
746
|
-
const commitOutput = execSync(`git commit -m "${message}"`, {
|
|
747
|
-
cwd: projectPath,
|
|
748
|
-
encoding: 'utf8',
|
|
749
|
-
});
|
|
750
|
-
output += `Commit:\n${commitOutput}\n\n`;
|
|
751
|
-
}
|
|
752
|
-
// Push to the specified branch or current branch
|
|
753
|
-
const pushCommand = branch ? `git push origin ${branch}` : 'git push';
|
|
754
|
-
const pushOutput = execSync(pushCommand, {
|
|
755
|
-
cwd: projectPath,
|
|
756
|
-
encoding: 'utf8',
|
|
757
|
-
});
|
|
758
|
-
output += `Push:\n${pushOutput}`;
|
|
759
|
-
return { output, success: true };
|
|
760
|
-
}
|
|
761
|
-
catch (error) {
|
|
762
|
-
throw new McpAdrError(`Git push failed: ${jsonSafeError(error)}`, 'GIT_PUSH_FAILED');
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
/**
|
|
766
|
-
* Exported smart git push function with JSON-safe content escaping
|
|
767
|
-
*/
|
|
768
|
-
export async function smartGitPush(args) {
|
|
769
|
-
const result = await _smartGitPushInternal(args);
|
|
770
|
-
return validateMcpResponse(result);
|
|
771
|
-
}
|
|
772
|
-
/**
|
|
773
|
-
* MCP-safe wrapper for smart git push that never throws
|
|
774
|
-
*/
|
|
775
|
-
export async function smartGitPushMcpSafe(args) {
|
|
776
|
-
try {
|
|
777
|
-
const result = await _smartGitPushInternal(args);
|
|
778
|
-
return validateMcpResponse(result);
|
|
779
|
-
}
|
|
780
|
-
catch (error) {
|
|
781
|
-
// Always return a safe MCP response, never throw
|
|
782
|
-
const errorResponse = {
|
|
783
|
-
content: [
|
|
784
|
-
{
|
|
785
|
-
type: 'text',
|
|
786
|
-
text: `# Smart Git Push - Error\n\n**Error**: ${jsonSafeError(error)}\n\nPlease check your git configuration and try again.`,
|
|
787
|
-
},
|
|
788
|
-
],
|
|
789
|
-
isError: true,
|
|
790
|
-
};
|
|
791
|
-
return validateMcpResponse(errorResponse);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
/**
|
|
795
|
-
* Analyze Knowledge Graph Context for Smart Git Push Decisions
|
|
796
|
-
* This is the core "smart" functionality that makes push decisions based on project context
|
|
797
|
-
*/
|
|
798
|
-
async function analyzeKnowledgeGraphContext(projectPath, stagedFiles) {
|
|
799
|
-
const kgManager = new KnowledgeGraphManager();
|
|
800
|
-
// TodoJsonManager removed - use mcp-shrimp-task-manager for task management
|
|
801
|
-
console.warn('⚠️ TodoJsonManager is deprecated and was removed in memory-centric transformation');
|
|
802
|
-
// Load knowledge graph and TODO data
|
|
803
|
-
const kg = await kgManager.loadKnowledgeGraph();
|
|
804
|
-
// Skip todo data loading - TodoJsonManager removed
|
|
805
|
-
const todoData = { tasks: {}, metadata: { totalTasks: 0, completedTasks: 0 } };
|
|
806
|
-
// Get active intents
|
|
807
|
-
const activeIntents = kg.intents.filter(i => i.currentStatus === 'executing' || i.currentStatus === 'planning');
|
|
808
|
-
// Analyze file changes against project context
|
|
809
|
-
const fileAnalysis = await analyzeFileChangesContext(stagedFiles, activeIntents, todoData);
|
|
810
|
-
// Check architectural alignment
|
|
811
|
-
const architecturalAlignment = await analyzeArchitecturalAlignment(stagedFiles, activeIntents, projectPath);
|
|
812
|
-
// Check task dependencies
|
|
813
|
-
const taskDependencies = await analyzeTaskDependencies(stagedFiles, todoData, activeIntents);
|
|
814
|
-
// Calculate project goal progress
|
|
815
|
-
const projectGoalProgress = await analyzeProjectGoalProgress(kg, todoData, activeIntents);
|
|
816
|
-
// Determine blocking conditions
|
|
817
|
-
const blockingConditions = await determineBlockingConditions(fileAnalysis, architecturalAlignment, taskDependencies, projectGoalProgress, stagedFiles);
|
|
818
|
-
// Find relevant ADRs
|
|
819
|
-
const relevantAdrs = await findRelevantAdrs(stagedFiles, projectPath);
|
|
820
|
-
return {
|
|
821
|
-
activeIntents,
|
|
822
|
-
relevantAdrs,
|
|
823
|
-
blockingConditions,
|
|
824
|
-
architecturalAlignment,
|
|
825
|
-
taskDependencies,
|
|
826
|
-
projectGoalProgress,
|
|
827
|
-
};
|
|
828
|
-
}
|
|
829
|
-
/**
|
|
830
|
-
* Analyze file changes against project context
|
|
831
|
-
*/
|
|
832
|
-
async function analyzeFileChangesContext(stagedFiles, activeIntents, todoData) {
|
|
833
|
-
const fileAnalysis = {
|
|
834
|
-
intentAlignment: [],
|
|
835
|
-
todoTaskProgress: [],
|
|
836
|
-
};
|
|
837
|
-
// Check how files relate to active intents
|
|
838
|
-
for (const intent of activeIntents) {
|
|
839
|
-
const alignedFiles = [];
|
|
840
|
-
const conflictingFiles = [];
|
|
841
|
-
// Check if files mentioned in intent goals
|
|
842
|
-
for (const file of stagedFiles) {
|
|
843
|
-
const fileName = basename(file.path);
|
|
844
|
-
const isRelevant = intent.parsedGoals.some(goal => goal.toLowerCase().includes(fileName.toLowerCase()) ||
|
|
845
|
-
goal.toLowerCase().includes(file.path.toLowerCase()));
|
|
846
|
-
if (isRelevant) {
|
|
847
|
-
alignedFiles.push(file.path);
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
fileAnalysis.intentAlignment.push({
|
|
851
|
-
intentId: intent.intentId,
|
|
852
|
-
alignedFiles,
|
|
853
|
-
conflictingFiles,
|
|
854
|
-
});
|
|
855
|
-
}
|
|
856
|
-
// Check how files relate to TODO tasks
|
|
857
|
-
const tasks = Object.values(todoData.tasks);
|
|
858
|
-
for (const task of tasks) {
|
|
859
|
-
const relatedFiles = stagedFiles.filter(file => {
|
|
860
|
-
const fileName = basename(file.path);
|
|
861
|
-
return (task.title.toLowerCase().includes(fileName.toLowerCase()) ||
|
|
862
|
-
task.description?.toLowerCase().includes(fileName.toLowerCase()) ||
|
|
863
|
-
task.title.toLowerCase().includes(file.path.toLowerCase()));
|
|
864
|
-
});
|
|
865
|
-
if (relatedFiles.length > 0) {
|
|
866
|
-
fileAnalysis.todoTaskProgress.push({
|
|
867
|
-
taskId: task.id,
|
|
868
|
-
relatedFiles: relatedFiles.map(f => f.path),
|
|
869
|
-
progressImpact: 'positive', // Assume file changes indicate progress
|
|
870
|
-
});
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
return fileAnalysis;
|
|
874
|
-
}
|
|
875
|
-
/**
|
|
876
|
-
* Analyze architectural alignment of changes
|
|
877
|
-
*/
|
|
878
|
-
async function analyzeArchitecturalAlignment(stagedFiles, activeIntents, _projectPath) {
|
|
879
|
-
const details = [];
|
|
880
|
-
const recommendations = [];
|
|
881
|
-
// Check if files align with architectural patterns
|
|
882
|
-
let alignmentScore = 100;
|
|
883
|
-
// Check for architectural violations
|
|
884
|
-
for (const file of stagedFiles) {
|
|
885
|
-
// Check if source files follow architectural patterns
|
|
886
|
-
if (file.path.match(/\.(ts|js|py|java|cs|go|rb|php|swift|kt|rs|cpp|c|h)$/i)) {
|
|
887
|
-
// Check for architectural patterns
|
|
888
|
-
if (file.path.includes('/src/') || file.path.includes('/lib/')) {
|
|
889
|
-
details.push(`✅ ${file.path} follows architectural structure`);
|
|
890
|
-
}
|
|
891
|
-
else {
|
|
892
|
-
details.push(`⚠️ ${file.path} may not follow architectural structure`);
|
|
893
|
-
alignmentScore -= 10;
|
|
894
|
-
recommendations.push(`Consider moving ${file.path} to appropriate architectural directory`);
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
// Check for configuration files
|
|
898
|
-
if (file.path.match(/\.(json|yaml|yml|conf|ini|toml)$/i)) {
|
|
899
|
-
details.push(`🔧 ${file.path} is a configuration file`);
|
|
900
|
-
if (file.path.includes('package.json') || file.path.includes('tsconfig.json')) {
|
|
901
|
-
recommendations.push(`Review ${file.path} changes for breaking changes`);
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
// Check intent alignment
|
|
906
|
-
for (const intent of activeIntents) {
|
|
907
|
-
const intentFiles = stagedFiles.filter(file => {
|
|
908
|
-
return intent.parsedGoals.some(goal => goal.toLowerCase().includes(basename(file.path).toLowerCase()));
|
|
909
|
-
});
|
|
910
|
-
if (intentFiles.length > 0) {
|
|
911
|
-
details.push(`🎯 ${intentFiles.length} files align with intent: ${intent.humanRequest.substring(0, 50)}...`);
|
|
912
|
-
alignmentScore += 10;
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
return {
|
|
916
|
-
score: Math.max(0, Math.min(100, alignmentScore)),
|
|
917
|
-
details,
|
|
918
|
-
recommendations,
|
|
919
|
-
};
|
|
920
|
-
}
|
|
921
|
-
/**
|
|
922
|
-
* Analyze task dependencies
|
|
923
|
-
*/
|
|
924
|
-
async function analyzeTaskDependencies(_stagedFiles, todoData, _activeIntents) {
|
|
925
|
-
const tasks = Object.values(todoData.tasks);
|
|
926
|
-
const completed = [];
|
|
927
|
-
const pending = [];
|
|
928
|
-
const blocking = [];
|
|
929
|
-
for (const task of tasks) {
|
|
930
|
-
if (task.status === 'completed') {
|
|
931
|
-
completed.push(task.title);
|
|
932
|
-
}
|
|
933
|
-
else if (task.status === 'pending') {
|
|
934
|
-
pending.push(task.title);
|
|
935
|
-
}
|
|
936
|
-
else if (task.status === 'blocked' || task.priority === 'critical') {
|
|
937
|
-
blocking.push(task.title);
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
return { completed, pending, blocking };
|
|
941
|
-
}
|
|
942
|
-
/**
|
|
943
|
-
* Analyze project goal progress
|
|
944
|
-
*/
|
|
945
|
-
async function analyzeProjectGoalProgress(_kg, _todoData, activeIntents) {
|
|
946
|
-
const intentProgress = activeIntents.map(intent => {
|
|
947
|
-
const progress = intent.scoreTracking?.scoreProgress || 0;
|
|
948
|
-
return {
|
|
949
|
-
intentId: intent.intentId,
|
|
950
|
-
humanRequest: intent.humanRequest,
|
|
951
|
-
progress,
|
|
952
|
-
status: intent.currentStatus,
|
|
953
|
-
};
|
|
954
|
-
});
|
|
955
|
-
const overallProgress = intentProgress.length > 0
|
|
956
|
-
? intentProgress.reduce((sum, intent) => sum + intent.progress, 0) / intentProgress.length
|
|
957
|
-
: 0;
|
|
958
|
-
return {
|
|
959
|
-
overallProgress,
|
|
960
|
-
intentProgress,
|
|
961
|
-
};
|
|
962
|
-
}
|
|
963
|
-
/**
|
|
964
|
-
* Determine blocking conditions based on analysis
|
|
965
|
-
*/
|
|
966
|
-
async function determineBlockingConditions(_fileAnalysis, architecturalAlignment, taskDependencies, projectGoalProgress, stagedFiles) {
|
|
967
|
-
const blockingConditions = [];
|
|
968
|
-
// Check for critical task dependencies
|
|
969
|
-
if (taskDependencies.blocking.length > 0) {
|
|
970
|
-
blockingConditions.push({
|
|
971
|
-
type: 'critical-task',
|
|
972
|
-
severity: 'error',
|
|
973
|
-
message: `${taskDependencies.blocking.length} critical tasks are blocking this push`,
|
|
974
|
-
recommendation: 'Complete or unblock critical tasks before pushing',
|
|
975
|
-
affectedFiles: stagedFiles.map(f => f.path),
|
|
976
|
-
});
|
|
977
|
-
}
|
|
978
|
-
// Check architectural alignment
|
|
979
|
-
if (architecturalAlignment.score < 60) {
|
|
980
|
-
blockingConditions.push({
|
|
981
|
-
type: 'adr-violation',
|
|
982
|
-
severity: 'warning',
|
|
983
|
-
message: `Low architectural alignment score: ${architecturalAlignment.score}%`,
|
|
984
|
-
recommendation: 'Review architectural compliance of changes',
|
|
985
|
-
affectedFiles: stagedFiles.map(f => f.path),
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
|
-
// Check goal regression
|
|
989
|
-
if (projectGoalProgress.overallProgress < 20) {
|
|
990
|
-
blockingConditions.push({
|
|
991
|
-
type: 'goal-regression',
|
|
992
|
-
severity: 'warning',
|
|
993
|
-
message: `Low project goal progress: ${projectGoalProgress.overallProgress}%`,
|
|
994
|
-
recommendation: 'Focus on completing active project goals',
|
|
995
|
-
affectedFiles: stagedFiles.map(f => f.path),
|
|
996
|
-
});
|
|
997
|
-
}
|
|
998
|
-
return blockingConditions;
|
|
999
|
-
}
|
|
1000
|
-
/**
|
|
1001
|
-
* Find relevant ADRs for the file changes
|
|
1002
|
-
*/
|
|
1003
|
-
async function findRelevantAdrs(_stagedFiles, _projectPath) {
|
|
1004
|
-
// This would typically scan ADR directories and find relevant ADRs
|
|
1005
|
-
// For now, return empty array
|
|
1006
|
-
return [];
|
|
1007
|
-
}
|
|
1008
|
-
/**
|
|
1009
|
-
* Update TODO tasks based on successful git push with Knowledge Graph integration
|
|
1010
|
-
*/
|
|
1011
|
-
//# sourceMappingURL=smart-git-push-tool.js.map
|