mcp-adr-analysis-server 2.0.10 → 2.0.12
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 -1
- package/dist/src/index.d.ts +1 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +340 -492
- package/dist/src/index.js.map +1 -1
- package/dist/src/prompts/adr-suggestion-prompts.d.ts.map +1 -1
- package/dist/src/prompts/adr-suggestion-prompts.js +2 -0
- package/dist/src/prompts/adr-suggestion-prompts.js.map +1 -1
- package/dist/src/tools/adr-suggestion-tool.d.ts +16 -0
- package/dist/src/tools/adr-suggestion-tool.d.ts.map +1 -1
- package/dist/src/tools/adr-suggestion-tool.js +55 -2
- package/dist/src/tools/adr-suggestion-tool.js.map +1 -1
- package/dist/src/tools/smart-git-push-tool-v2.d.ts +55 -0
- package/dist/src/tools/smart-git-push-tool-v2.d.ts.map +1 -0
- package/dist/src/tools/smart-git-push-tool-v2.js +527 -0
- package/dist/src/tools/smart-git-push-tool-v2.js.map +1 -0
- package/dist/src/tools/smart-git-push-tool.d.ts +27 -3
- package/dist/src/tools/smart-git-push-tool.d.ts.map +1 -1
- package/dist/src/tools/smart-git-push-tool.js +490 -10
- package/dist/src/tools/smart-git-push-tool.js.map +1 -1
- package/dist/src/tools/smart-score-tool.d.ts +39 -4
- package/dist/src/tools/smart-score-tool.d.ts.map +1 -1
- package/dist/src/tools/smart-score-tool.js +94 -15
- package/dist/src/tools/smart-score-tool.js.map +1 -1
- package/dist/src/tools/todo-management-tool-v2.d.ts +329 -0
- package/dist/src/tools/todo-management-tool-v2.d.ts.map +1 -0
- package/dist/src/tools/todo-management-tool-v2.js +644 -0
- package/dist/src/tools/todo-management-tool-v2.js.map +1 -0
- package/dist/src/tools/tool-chain-orchestrator.d.ts +3 -41
- package/dist/src/tools/tool-chain-orchestrator.d.ts.map +1 -1
- package/dist/src/tools/tool-chain-orchestrator.js +10 -198
- package/dist/src/tools/tool-chain-orchestrator.js.map +1 -1
- package/dist/src/types/conversation-context.d.ts +6 -0
- package/dist/src/types/conversation-context.d.ts.map +1 -1
- package/dist/src/types/conversation-context.js +9 -1
- package/dist/src/types/conversation-context.js.map +1 -1
- package/dist/src/types/knowledge-graph-schemas.d.ts +298 -6
- package/dist/src/types/knowledge-graph-schemas.d.ts.map +1 -1
- package/dist/src/types/knowledge-graph-schemas.js +31 -3
- package/dist/src/types/knowledge-graph-schemas.js.map +1 -1
- package/dist/src/types/todo-json-schemas.d.ts +663 -0
- package/dist/src/types/todo-json-schemas.d.ts.map +1 -0
- package/dist/src/types/todo-json-schemas.js +113 -0
- package/dist/src/types/todo-json-schemas.js.map +1 -0
- package/dist/src/utils/chain-of-thought-template.d.ts.map +1 -1
- package/dist/src/utils/chain-of-thought-template.js.map +1 -1
- package/dist/src/utils/knowledge-graph-manager.d.ts +50 -0
- package/dist/src/utils/knowledge-graph-manager.d.ts.map +1 -1
- package/dist/src/utils/knowledge-graph-manager.js +209 -3
- package/dist/src/utils/knowledge-graph-manager.js.map +1 -1
- package/dist/src/utils/project-health-scoring.js +5 -5
- package/dist/src/utils/project-health-scoring.js.map +1 -1
- package/dist/src/utils/todo-json-manager.d.ts +71 -0
- package/dist/src/utils/todo-json-manager.d.ts.map +1 -0
- package/dist/src/utils/todo-json-manager.js +394 -0
- package/dist/src/utils/todo-json-manager.js.map +1 -0
- package/dist/src/utils/todo-markdown-converter.d.ts +16 -0
- package/dist/src/utils/todo-markdown-converter.d.ts.map +1 -0
- package/dist/src/utils/todo-markdown-converter.js +362 -0
- package/dist/src/utils/todo-markdown-converter.js.map +1 -0
- package/dist/src/utils/todo-migration.d.ts +47 -0
- package/dist/src/utils/todo-migration.d.ts.map +1 -0
- package/dist/src/utils/todo-migration.js +261 -0
- package/dist/src/utils/todo-migration.js.map +1 -0
- package/package.json +1 -1
- package/dist/src/tools/human-override-tool.d.ts +0 -42
- package/dist/src/tools/human-override-tool.d.ts.map +0 -1
- package/dist/src/tools/human-override-tool.js +0 -431
- package/dist/src/tools/human-override-tool.js.map +0 -1
- package/dist/src/tools/todo-management-tool.d.ts +0 -344
- package/dist/src/tools/todo-management-tool.d.ts.map +0 -1
- package/dist/src/tools/todo-management-tool.js +0 -1249
- package/dist/src/tools/todo-management-tool.js.map +0 -1
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Smart Git Push MCP Tool
|
|
2
|
+
* Smart Git Push MCP Tool - Knowledge Graph Enhanced
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* Leverages
|
|
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.
|
|
6
29
|
*/
|
|
7
30
|
import { McpAdrError } from '../types/index.js';
|
|
8
31
|
import { execSync } from 'child_process';
|
|
@@ -10,13 +33,27 @@ import { readFileSync, existsSync, statSync } from 'fs';
|
|
|
10
33
|
import { join, basename } from 'path';
|
|
11
34
|
import { jsonSafeFilePath, jsonSafeMarkdownList, jsonSafeError, jsonSafeUserInput } from '../utils/json-safe.js';
|
|
12
35
|
import { validateMcpResponse } from '../utils/mcp-response-validator.js';
|
|
36
|
+
import { KnowledgeGraphManager } from '../utils/knowledge-graph-manager.js';
|
|
13
37
|
/**
|
|
14
|
-
* Main smart git push function -
|
|
38
|
+
* Main smart git push function - Knowledge Graph Enhanced Version
|
|
15
39
|
*/
|
|
16
40
|
async function _smartGitPushInternal(args) {
|
|
17
|
-
const { branch, message, skipValidation = false, allowedArtifacts = [], sensitivityLevel = 'moderate', dryRun = false, projectPath = process.cwd(), checkReleaseReadiness = false, releaseType = 'minor' } = args;
|
|
41
|
+
const { branch, message, skipValidation = false, allowedArtifacts = [], sensitivityLevel = 'moderate', dryRun = false, projectPath = process.cwd(), checkReleaseReadiness = false, releaseType = 'minor', skipKnowledgeGraphAnalysis = false } = args;
|
|
18
42
|
try {
|
|
19
|
-
// Step 1:
|
|
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)
|
|
20
57
|
let releaseReadinessResult = null;
|
|
21
58
|
if (checkReleaseReadiness) {
|
|
22
59
|
try {
|
|
@@ -47,8 +84,6 @@ async function _smartGitPushInternal(args) {
|
|
|
47
84
|
// Silently handle release readiness analysis errors
|
|
48
85
|
}
|
|
49
86
|
}
|
|
50
|
-
// Step 2: Get staged files using git CLI
|
|
51
|
-
const stagedFiles = await getStagedFiles(projectPath);
|
|
52
87
|
if (stagedFiles.length === 0) {
|
|
53
88
|
let responseText = `# Smart Git Push - No Changes
|
|
54
89
|
|
|
@@ -60,6 +95,28 @@ No staged files found. Use \`git add\` to stage files before pushing.
|
|
|
60
95
|
- \`git add <file>\` - Stage specific file
|
|
61
96
|
- \`git status\` - Check current status
|
|
62
97
|
`;
|
|
98
|
+
// Add knowledge graph context even when no files are staged
|
|
99
|
+
if (kgAnalysis) {
|
|
100
|
+
responseText += `
|
|
101
|
+
|
|
102
|
+
## Knowledge Graph Context
|
|
103
|
+
### Current Project Status
|
|
104
|
+
- **Active Intents**: ${kgAnalysis.activeIntents.length}
|
|
105
|
+
- **Goal Progress**: ${kgAnalysis.projectGoalProgress.overallProgress}%
|
|
106
|
+
- **Task Dependencies**: ${kgAnalysis.taskDependencies.completed.length} completed, ${kgAnalysis.taskDependencies.pending.length} pending
|
|
107
|
+
|
|
108
|
+
${kgAnalysis.activeIntents.length > 0 ? `
|
|
109
|
+
### Active Intents
|
|
110
|
+
${kgAnalysis.activeIntents.map(intent => `- **${intent.currentStatus}**: ${jsonSafeUserInput(intent.humanRequest.substring(0, 80))}...`).join('\n')}
|
|
111
|
+
` : ''}
|
|
112
|
+
|
|
113
|
+
${kgAnalysis.taskDependencies.pending.length > 0 ? `
|
|
114
|
+
### Pending Tasks
|
|
115
|
+
Consider working on these tasks before your next push:
|
|
116
|
+
${kgAnalysis.taskDependencies.pending.slice(0, 5).map(task => `- ${jsonSafeUserInput(task)}`).join('\n')}
|
|
117
|
+
` : ''}
|
|
118
|
+
`;
|
|
119
|
+
}
|
|
63
120
|
// Add release readiness info if checked
|
|
64
121
|
if (releaseReadinessResult) {
|
|
65
122
|
responseText += `
|
|
@@ -91,7 +148,7 @@ ${releaseReadinessResult.isReady ?
|
|
|
91
148
|
projectPath
|
|
92
149
|
});
|
|
93
150
|
}
|
|
94
|
-
// Step 4: Check for blocking conditions (
|
|
151
|
+
// Step 4: Check for blocking conditions (Enhanced with Knowledge Graph)
|
|
95
152
|
const issues = validationResults.filter(r => r.issues.length > 0);
|
|
96
153
|
// Check if release readiness should block push
|
|
97
154
|
let releaseReadinessBlocked = false;
|
|
@@ -101,9 +158,15 @@ ${releaseReadinessResult.isReady ?
|
|
|
101
158
|
releaseReadinessBlocked = true;
|
|
102
159
|
}
|
|
103
160
|
}
|
|
161
|
+
// Check Knowledge Graph for blocking conditions (NEW!)
|
|
162
|
+
let knowledgeGraphBlocked = false;
|
|
163
|
+
const kgBlockingConditions = kgAnalysis?.blockingConditions?.filter(bc => bc.severity === 'error') || [];
|
|
164
|
+
if (kgBlockingConditions.length > 0) {
|
|
165
|
+
knowledgeGraphBlocked = true;
|
|
166
|
+
}
|
|
104
167
|
// Check for blocking conditions
|
|
105
168
|
const hasBlockingErrors = issues.some(issue => issue.issues.some(i => i.severity === 'error'));
|
|
106
|
-
const shouldBlock = hasBlockingErrors || releaseReadinessBlocked;
|
|
169
|
+
const shouldBlock = hasBlockingErrors || releaseReadinessBlocked || knowledgeGraphBlocked;
|
|
107
170
|
if (shouldBlock && !dryRun) {
|
|
108
171
|
let cancelText = `# Smart Git Push - Blocked
|
|
109
172
|
|
|
@@ -132,6 +195,40 @@ ${releaseReadinessResult.blockers.filter(b => b.severity === 'error').map(b => `
|
|
|
132
195
|
|
|
133
196
|
### Recommendations
|
|
134
197
|
${jsonSafeMarkdownList(releaseReadinessResult.recommendations)}
|
|
198
|
+
`;
|
|
199
|
+
}
|
|
200
|
+
// Add knowledge graph blocking information (NEW!)
|
|
201
|
+
if (kgAnalysis && knowledgeGraphBlocked) {
|
|
202
|
+
cancelText += `
|
|
203
|
+
|
|
204
|
+
## Knowledge Graph Analysis - Blocking Conditions
|
|
205
|
+
The following architectural and project context issues prevent this push:
|
|
206
|
+
|
|
207
|
+
### Critical Issues
|
|
208
|
+
${kgBlockingConditions.map(bc => `- **${bc.type}**: ${jsonSafeUserInput(bc.message)}`).join('\n')}
|
|
209
|
+
|
|
210
|
+
### Recommendations
|
|
211
|
+
${kgBlockingConditions.map(bc => `- ${jsonSafeUserInput(bc.recommendation)}`).join('\n')}
|
|
212
|
+
|
|
213
|
+
### Project Context
|
|
214
|
+
- **Active Intents**: ${kgAnalysis.activeIntents.length}
|
|
215
|
+
- **Architectural Alignment**: ${kgAnalysis.architecturalAlignment.score}%
|
|
216
|
+
- **Goal Progress**: ${kgAnalysis.projectGoalProgress.overallProgress}%
|
|
217
|
+
- **Pending Critical Tasks**: ${kgAnalysis.taskDependencies.blocking.length}
|
|
218
|
+
`;
|
|
219
|
+
}
|
|
220
|
+
// Add general knowledge graph insights if available
|
|
221
|
+
if (kgAnalysis && !knowledgeGraphBlocked) {
|
|
222
|
+
cancelText += `
|
|
223
|
+
|
|
224
|
+
## Knowledge Graph Insights
|
|
225
|
+
### Project Status
|
|
226
|
+
- **Active Intents**: ${kgAnalysis.activeIntents.length}
|
|
227
|
+
- **Architectural Alignment**: ${kgAnalysis.architecturalAlignment.score}%
|
|
228
|
+
- **Goal Progress**: ${kgAnalysis.projectGoalProgress.overallProgress}%
|
|
229
|
+
|
|
230
|
+
### Warnings
|
|
231
|
+
${kgAnalysis.blockingConditions.filter(bc => bc.severity === 'warning').map(bc => `- **${bc.type}**: ${jsonSafeUserInput(bc.message)}`).join('\n')}
|
|
135
232
|
`;
|
|
136
233
|
}
|
|
137
234
|
return {
|
|
@@ -144,6 +241,17 @@ ${jsonSafeMarkdownList(releaseReadinessResult.recommendations)}
|
|
|
144
241
|
// Step 5: Execute git push if not dry run
|
|
145
242
|
if (!dryRun) {
|
|
146
243
|
const pushResult = await executePush(projectPath, branch, message);
|
|
244
|
+
// Update TODO tasks with KG integration
|
|
245
|
+
if (kgAnalysis) {
|
|
246
|
+
try {
|
|
247
|
+
const { TodoJsonManager } = await import('../utils/todo-json-manager.js');
|
|
248
|
+
const todoManager = new TodoJsonManager(projectPath);
|
|
249
|
+
await updateTodoTasksFromGitPushWithKG(todoManager, stagedFiles, kgAnalysis, releaseReadinessResult);
|
|
250
|
+
}
|
|
251
|
+
catch (todoError) {
|
|
252
|
+
console.error('Error updating TODO tasks with KG:', todoError);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
147
255
|
let successText = `# Smart Git Push - Success ✅
|
|
148
256
|
|
|
149
257
|
## Push Details
|
|
@@ -153,10 +261,33 @@ ${jsonSafeMarkdownList(releaseReadinessResult.recommendations)}
|
|
|
153
261
|
- **Issues Found**: ${issues.length}
|
|
154
262
|
- **Sensitivity Level**: ${sensitivityLevel}
|
|
155
263
|
${checkReleaseReadiness ? `- **Release Readiness**: ${releaseReadinessResult?.isReady ? '✅ Ready' : '❌ Not Ready'}` : ''}
|
|
264
|
+
${kgAnalysis ? `- **Knowledge Graph Analysis**: ✅ Completed` : ''}
|
|
156
265
|
|
|
157
266
|
## Files Pushed
|
|
158
267
|
${stagedFiles.map(f => `- ${jsonSafeFilePath(f.path)} (${f.status})`).join('\n')}
|
|
159
268
|
|
|
269
|
+
${kgAnalysis ? `
|
|
270
|
+
## Knowledge Graph Analysis
|
|
271
|
+
### Project Context
|
|
272
|
+
- **Active Intents**: ${kgAnalysis.activeIntents.length}
|
|
273
|
+
- **Architectural Alignment**: ${kgAnalysis.architecturalAlignment.score}%
|
|
274
|
+
- **Goal Progress**: ${kgAnalysis.projectGoalProgress.overallProgress}%
|
|
275
|
+
- **Task Dependencies**: ${kgAnalysis.taskDependencies.completed.length} completed, ${kgAnalysis.taskDependencies.pending.length} pending
|
|
276
|
+
|
|
277
|
+
### Architectural Insights
|
|
278
|
+
${kgAnalysis.architecturalAlignment.details.map(detail => `- ${jsonSafeUserInput(detail)}`).join('\n')}
|
|
279
|
+
|
|
280
|
+
${kgAnalysis.blockingConditions.length > 0 ? `
|
|
281
|
+
### Warnings & Recommendations
|
|
282
|
+
${kgAnalysis.blockingConditions.filter(bc => bc.severity === 'warning').map(bc => `- **${bc.type}**: ${jsonSafeUserInput(bc.message)}`).join('\n')}
|
|
283
|
+
` : ''}
|
|
284
|
+
|
|
285
|
+
${kgAnalysis.projectGoalProgress.intentProgress.length > 0 ? `
|
|
286
|
+
### Intent Progress
|
|
287
|
+
${kgAnalysis.projectGoalProgress.intentProgress.map(intent => `- **${intent.status}**: ${jsonSafeUserInput(intent.humanRequest.substring(0, 60))}... (${intent.progress}%)`).join('\n')}
|
|
288
|
+
` : ''}
|
|
289
|
+
` : ''}
|
|
290
|
+
|
|
160
291
|
${issues.length > 0 ? `
|
|
161
292
|
|
|
162
293
|
## Validation Issues (Auto-Approved)
|
|
@@ -190,6 +321,7 @@ ${jsonSafeUserInput(pushResult.output)}
|
|
|
190
321
|
- Review any deployment processes
|
|
191
322
|
- Check for any post-push hooks or workflows
|
|
192
323
|
${releaseReadinessResult?.isReady ? '- Consider creating a release tag or publishing' : ''}
|
|
324
|
+
${kgAnalysis ? '- Review knowledge graph insights for follow-up tasks' : ''}
|
|
193
325
|
`;
|
|
194
326
|
return {
|
|
195
327
|
content: [{
|
|
@@ -208,10 +340,33 @@ ${releaseReadinessResult?.isReady ? '- Consider creating a release tag or publis
|
|
|
208
340
|
- **Sensitivity Level**: ${sensitivityLevel}
|
|
209
341
|
- **Would Push to**: ${branch || 'current branch'}
|
|
210
342
|
${checkReleaseReadiness ? `- **Release Readiness**: ${releaseReadinessResult?.isReady ? '✅ Ready' : '❌ Not Ready'}` : ''}
|
|
343
|
+
${kgAnalysis ? `- **Knowledge Graph Analysis**: ✅ Completed` : ''}
|
|
211
344
|
|
|
212
345
|
## Staged Files
|
|
213
346
|
${stagedFiles.map(f => `- ${jsonSafeFilePath(f.path)} (${f.status}) - ${f.size} bytes`).join('\n')}
|
|
214
347
|
|
|
348
|
+
${kgAnalysis ? `
|
|
349
|
+
## Knowledge Graph Analysis Preview
|
|
350
|
+
### Project Context
|
|
351
|
+
- **Active Intents**: ${kgAnalysis.activeIntents.length}
|
|
352
|
+
- **Architectural Alignment**: ${kgAnalysis.architecturalAlignment.score}%
|
|
353
|
+
- **Goal Progress**: ${kgAnalysis.projectGoalProgress.overallProgress}%
|
|
354
|
+
- **Task Dependencies**: ${kgAnalysis.taskDependencies.completed.length} completed, ${kgAnalysis.taskDependencies.pending.length} pending
|
|
355
|
+
|
|
356
|
+
### Architectural Assessment
|
|
357
|
+
${kgAnalysis.architecturalAlignment.details.map(detail => `- ${jsonSafeUserInput(detail)}`).join('\n')}
|
|
358
|
+
|
|
359
|
+
${kgAnalysis.blockingConditions.length > 0 ? `
|
|
360
|
+
### Potential Issues
|
|
361
|
+
${kgAnalysis.blockingConditions.map(bc => `- **${bc.type}** (${bc.severity}): ${jsonSafeUserInput(bc.message)}`).join('\n')}
|
|
362
|
+
` : ''}
|
|
363
|
+
|
|
364
|
+
${kgAnalysis.projectGoalProgress.intentProgress.length > 0 ? `
|
|
365
|
+
### Intent Progress Impact
|
|
366
|
+
${kgAnalysis.projectGoalProgress.intentProgress.map(intent => `- **${intent.status}**: ${jsonSafeUserInput(intent.humanRequest.substring(0, 60))}... (${intent.progress}%)`).join('\n')}
|
|
367
|
+
` : ''}
|
|
368
|
+
` : ''}
|
|
369
|
+
|
|
215
370
|
${issues.length > 0 ? `
|
|
216
371
|
|
|
217
372
|
## Validation Issues Found
|
|
@@ -522,4 +677,329 @@ export async function smartGitPushMcpSafe(args) {
|
|
|
522
677
|
return validateMcpResponse(errorResponse);
|
|
523
678
|
}
|
|
524
679
|
}
|
|
680
|
+
/**
|
|
681
|
+
* Analyze Knowledge Graph Context for Smart Git Push Decisions
|
|
682
|
+
* This is the core "smart" functionality that makes push decisions based on project context
|
|
683
|
+
*/
|
|
684
|
+
async function analyzeKnowledgeGraphContext(projectPath, stagedFiles) {
|
|
685
|
+
const kgManager = new KnowledgeGraphManager();
|
|
686
|
+
const { TodoJsonManager } = await import('../utils/todo-json-manager.js');
|
|
687
|
+
const todoManager = new TodoJsonManager(projectPath);
|
|
688
|
+
// Load knowledge graph and TODO data
|
|
689
|
+
const kg = await kgManager.loadKnowledgeGraph();
|
|
690
|
+
const todoData = await todoManager.loadTodoData();
|
|
691
|
+
// Get active intents
|
|
692
|
+
const activeIntents = kg.intents.filter(i => i.currentStatus === 'executing' || i.currentStatus === 'planning');
|
|
693
|
+
// Analyze file changes against project context
|
|
694
|
+
const fileAnalysis = await analyzeFileChangesContext(stagedFiles, activeIntents, todoData);
|
|
695
|
+
// Check architectural alignment
|
|
696
|
+
const architecturalAlignment = await analyzeArchitecturalAlignment(stagedFiles, activeIntents, projectPath);
|
|
697
|
+
// Check task dependencies
|
|
698
|
+
const taskDependencies = await analyzeTaskDependencies(stagedFiles, todoData, activeIntents);
|
|
699
|
+
// Calculate project goal progress
|
|
700
|
+
const projectGoalProgress = await analyzeProjectGoalProgress(kg, todoData, activeIntents);
|
|
701
|
+
// Determine blocking conditions
|
|
702
|
+
const blockingConditions = await determineBlockingConditions(fileAnalysis, architecturalAlignment, taskDependencies, projectGoalProgress, stagedFiles);
|
|
703
|
+
// Find relevant ADRs
|
|
704
|
+
const relevantAdrs = await findRelevantAdrs(stagedFiles, projectPath);
|
|
705
|
+
return {
|
|
706
|
+
activeIntents,
|
|
707
|
+
relevantAdrs,
|
|
708
|
+
blockingConditions,
|
|
709
|
+
architecturalAlignment,
|
|
710
|
+
taskDependencies,
|
|
711
|
+
projectGoalProgress
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Analyze file changes against project context
|
|
716
|
+
*/
|
|
717
|
+
async function analyzeFileChangesContext(stagedFiles, activeIntents, todoData) {
|
|
718
|
+
const fileAnalysis = {
|
|
719
|
+
intentAlignment: [],
|
|
720
|
+
todoTaskProgress: []
|
|
721
|
+
};
|
|
722
|
+
// Check how files relate to active intents
|
|
723
|
+
for (const intent of activeIntents) {
|
|
724
|
+
const alignedFiles = [];
|
|
725
|
+
const conflictingFiles = [];
|
|
726
|
+
// Check if files mentioned in intent goals
|
|
727
|
+
for (const file of stagedFiles) {
|
|
728
|
+
const fileName = basename(file.path);
|
|
729
|
+
const isRelevant = intent.parsedGoals.some(goal => goal.toLowerCase().includes(fileName.toLowerCase()) ||
|
|
730
|
+
goal.toLowerCase().includes(file.path.toLowerCase()));
|
|
731
|
+
if (isRelevant) {
|
|
732
|
+
alignedFiles.push(file.path);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
fileAnalysis.intentAlignment.push({
|
|
736
|
+
intentId: intent.intentId,
|
|
737
|
+
alignedFiles,
|
|
738
|
+
conflictingFiles
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
// Check how files relate to TODO tasks
|
|
742
|
+
const tasks = Object.values(todoData.tasks);
|
|
743
|
+
for (const task of tasks) {
|
|
744
|
+
const relatedFiles = stagedFiles.filter(file => {
|
|
745
|
+
const fileName = basename(file.path);
|
|
746
|
+
return task.title.toLowerCase().includes(fileName.toLowerCase()) ||
|
|
747
|
+
task.description?.toLowerCase().includes(fileName.toLowerCase()) ||
|
|
748
|
+
task.title.toLowerCase().includes(file.path.toLowerCase());
|
|
749
|
+
});
|
|
750
|
+
if (relatedFiles.length > 0) {
|
|
751
|
+
fileAnalysis.todoTaskProgress.push({
|
|
752
|
+
taskId: task.id,
|
|
753
|
+
relatedFiles: relatedFiles.map(f => f.path),
|
|
754
|
+
progressImpact: 'positive' // Assume file changes indicate progress
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
return fileAnalysis;
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Analyze architectural alignment of changes
|
|
762
|
+
*/
|
|
763
|
+
async function analyzeArchitecturalAlignment(stagedFiles, activeIntents, _projectPath) {
|
|
764
|
+
const details = [];
|
|
765
|
+
const recommendations = [];
|
|
766
|
+
// Check if files align with architectural patterns
|
|
767
|
+
let alignmentScore = 100;
|
|
768
|
+
// Check for architectural violations
|
|
769
|
+
for (const file of stagedFiles) {
|
|
770
|
+
// Check if source files follow architectural patterns
|
|
771
|
+
if (file.path.match(/\.(ts|js|py|java|cs|go|rb|php|swift|kt|rs|cpp|c|h)$/i)) {
|
|
772
|
+
// Check for architectural patterns
|
|
773
|
+
if (file.path.includes('/src/') || file.path.includes('/lib/')) {
|
|
774
|
+
details.push(`✅ ${file.path} follows architectural structure`);
|
|
775
|
+
}
|
|
776
|
+
else {
|
|
777
|
+
details.push(`⚠️ ${file.path} may not follow architectural structure`);
|
|
778
|
+
alignmentScore -= 10;
|
|
779
|
+
recommendations.push(`Consider moving ${file.path} to appropriate architectural directory`);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
// Check for configuration files
|
|
783
|
+
if (file.path.match(/\.(json|yaml|yml|conf|ini|toml)$/i)) {
|
|
784
|
+
details.push(`🔧 ${file.path} is a configuration file`);
|
|
785
|
+
if (file.path.includes('package.json') || file.path.includes('tsconfig.json')) {
|
|
786
|
+
recommendations.push(`Review ${file.path} changes for breaking changes`);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
// Check intent alignment
|
|
791
|
+
for (const intent of activeIntents) {
|
|
792
|
+
const intentFiles = stagedFiles.filter(file => {
|
|
793
|
+
return intent.parsedGoals.some(goal => goal.toLowerCase().includes(basename(file.path).toLowerCase()));
|
|
794
|
+
});
|
|
795
|
+
if (intentFiles.length > 0) {
|
|
796
|
+
details.push(`🎯 ${intentFiles.length} files align with intent: ${intent.humanRequest.substring(0, 50)}...`);
|
|
797
|
+
alignmentScore += 10;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
return {
|
|
801
|
+
score: Math.max(0, Math.min(100, alignmentScore)),
|
|
802
|
+
details,
|
|
803
|
+
recommendations
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* Analyze task dependencies
|
|
808
|
+
*/
|
|
809
|
+
async function analyzeTaskDependencies(_stagedFiles, todoData, _activeIntents) {
|
|
810
|
+
const tasks = Object.values(todoData.tasks);
|
|
811
|
+
const completed = [];
|
|
812
|
+
const pending = [];
|
|
813
|
+
const blocking = [];
|
|
814
|
+
for (const task of tasks) {
|
|
815
|
+
if (task.status === 'completed') {
|
|
816
|
+
completed.push(task.title);
|
|
817
|
+
}
|
|
818
|
+
else if (task.status === 'pending') {
|
|
819
|
+
pending.push(task.title);
|
|
820
|
+
}
|
|
821
|
+
else if (task.status === 'blocked' || task.priority === 'critical') {
|
|
822
|
+
blocking.push(task.title);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
return { completed, pending, blocking };
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Analyze project goal progress
|
|
829
|
+
*/
|
|
830
|
+
async function analyzeProjectGoalProgress(_kg, _todoData, activeIntents) {
|
|
831
|
+
const intentProgress = activeIntents.map(intent => {
|
|
832
|
+
const progress = intent.scoreTracking?.scoreProgress || 0;
|
|
833
|
+
return {
|
|
834
|
+
intentId: intent.intentId,
|
|
835
|
+
humanRequest: intent.humanRequest,
|
|
836
|
+
progress,
|
|
837
|
+
status: intent.currentStatus
|
|
838
|
+
};
|
|
839
|
+
});
|
|
840
|
+
const overallProgress = intentProgress.length > 0
|
|
841
|
+
? intentProgress.reduce((sum, intent) => sum + intent.progress, 0) / intentProgress.length
|
|
842
|
+
: 0;
|
|
843
|
+
return {
|
|
844
|
+
overallProgress,
|
|
845
|
+
intentProgress
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* Determine blocking conditions based on analysis
|
|
850
|
+
*/
|
|
851
|
+
async function determineBlockingConditions(_fileAnalysis, architecturalAlignment, taskDependencies, projectGoalProgress, stagedFiles) {
|
|
852
|
+
const blockingConditions = [];
|
|
853
|
+
// Check for critical task dependencies
|
|
854
|
+
if (taskDependencies.blocking.length > 0) {
|
|
855
|
+
blockingConditions.push({
|
|
856
|
+
type: 'critical-task',
|
|
857
|
+
severity: 'error',
|
|
858
|
+
message: `${taskDependencies.blocking.length} critical tasks are blocking this push`,
|
|
859
|
+
recommendation: 'Complete or unblock critical tasks before pushing',
|
|
860
|
+
affectedFiles: stagedFiles.map(f => f.path)
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
// Check architectural alignment
|
|
864
|
+
if (architecturalAlignment.score < 60) {
|
|
865
|
+
blockingConditions.push({
|
|
866
|
+
type: 'adr-violation',
|
|
867
|
+
severity: 'warning',
|
|
868
|
+
message: `Low architectural alignment score: ${architecturalAlignment.score}%`,
|
|
869
|
+
recommendation: 'Review architectural compliance of changes',
|
|
870
|
+
affectedFiles: stagedFiles.map(f => f.path)
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
// Check goal regression
|
|
874
|
+
if (projectGoalProgress.overallProgress < 20) {
|
|
875
|
+
blockingConditions.push({
|
|
876
|
+
type: 'goal-regression',
|
|
877
|
+
severity: 'warning',
|
|
878
|
+
message: `Low project goal progress: ${projectGoalProgress.overallProgress}%`,
|
|
879
|
+
recommendation: 'Focus on completing active project goals',
|
|
880
|
+
affectedFiles: stagedFiles.map(f => f.path)
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
return blockingConditions;
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Find relevant ADRs for the file changes
|
|
887
|
+
*/
|
|
888
|
+
async function findRelevantAdrs(_stagedFiles, _projectPath) {
|
|
889
|
+
// This would typically scan ADR directories and find relevant ADRs
|
|
890
|
+
// For now, return empty array
|
|
891
|
+
return [];
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Update TODO tasks based on successful git push with Knowledge Graph integration
|
|
895
|
+
*/
|
|
896
|
+
async function updateTodoTasksFromGitPushWithKG(todoManager, stagedFiles, kgAnalysis, releaseReadinessResult) {
|
|
897
|
+
try {
|
|
898
|
+
// Create intent for this git push
|
|
899
|
+
const kgManager = new KnowledgeGraphManager();
|
|
900
|
+
const intentId = await kgManager.createIntent(`Git push: ${stagedFiles.length} files`, [`Push ${stagedFiles.map(f => f.path).join(', ')}`], 'medium');
|
|
901
|
+
// Record tool execution
|
|
902
|
+
await kgManager.addToolExecution(intentId, 'smart_git_push', {
|
|
903
|
+
files: stagedFiles.map(f => f.path),
|
|
904
|
+
branch: 'current',
|
|
905
|
+
knowledgeGraphAnalysis: true
|
|
906
|
+
}, {
|
|
907
|
+
success: true,
|
|
908
|
+
filesProcessed: stagedFiles.length,
|
|
909
|
+
architecturalAlignment: kgAnalysis.architecturalAlignment.score
|
|
910
|
+
}, true, [], // todoTasksCreated
|
|
911
|
+
kgAnalysis.taskDependencies.completed // todoTasksModified
|
|
912
|
+
);
|
|
913
|
+
// Update intent status
|
|
914
|
+
await kgManager.updateIntentStatus(intentId, 'completed');
|
|
915
|
+
// Update TODO tasks
|
|
916
|
+
await updateTodoTasksFromGitPush(todoManager, stagedFiles, releaseReadinessResult);
|
|
917
|
+
}
|
|
918
|
+
catch (error) {
|
|
919
|
+
console.error('Error updating TODO tasks with KG:', error);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Update TODO tasks based on successful git push
|
|
924
|
+
*/
|
|
925
|
+
async function updateTodoTasksFromGitPush(todoManager, stagedFiles, releaseReadinessResult) {
|
|
926
|
+
try {
|
|
927
|
+
const data = await todoManager.loadTodoData();
|
|
928
|
+
const tasks = Object.values(data.tasks);
|
|
929
|
+
// 1. Auto-update tasks based on file changes
|
|
930
|
+
for (const file of stagedFiles) {
|
|
931
|
+
// Look for tasks that mention this file in their title or description
|
|
932
|
+
const relatedTasks = tasks.filter(task => task.title.toLowerCase().includes(basename(file.path).toLowerCase()) ||
|
|
933
|
+
task.description?.toLowerCase().includes(basename(file.path).toLowerCase()) ||
|
|
934
|
+
task.title.toLowerCase().includes(file.path.toLowerCase()));
|
|
935
|
+
for (const task of relatedTasks) {
|
|
936
|
+
if (task.status === 'pending' || task.status === 'in_progress') {
|
|
937
|
+
// Update to in_progress if pending, or completed if already in_progress
|
|
938
|
+
const newStatus = task.status === 'pending' ? 'in_progress' : 'completed';
|
|
939
|
+
await todoManager.updateTask({
|
|
940
|
+
taskId: task.id,
|
|
941
|
+
updates: {
|
|
942
|
+
status: newStatus,
|
|
943
|
+
notes: `Auto-updated: ${file.path} was ${file.status} in git push`
|
|
944
|
+
},
|
|
945
|
+
reason: `Git push: ${file.path} ${file.status}`,
|
|
946
|
+
triggeredBy: 'tool'
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
// 2. Create follow-up tasks based on what was pushed
|
|
952
|
+
const followUpTasks = [];
|
|
953
|
+
// If documentation files were changed, create review tasks
|
|
954
|
+
const docFiles = stagedFiles.filter(f => f.path.match(/\.(md|txt|rst)$/i) &&
|
|
955
|
+
!f.path.includes('TODO.md'));
|
|
956
|
+
if (docFiles.length > 0) {
|
|
957
|
+
followUpTasks.push({
|
|
958
|
+
title: `Review updated documentation`,
|
|
959
|
+
description: `Review changes to: ${docFiles.map(f => f.path).join(', ')}`,
|
|
960
|
+
priority: 'medium',
|
|
961
|
+
category: 'documentation',
|
|
962
|
+
tags: ['review', 'documentation']
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
// If source code was changed, create testing tasks
|
|
966
|
+
const codeFiles = stagedFiles.filter(f => f.path.match(/\.(ts|js|py|java|cs|go|rb|php|swift|kt|rs|cpp|c|h)$/i));
|
|
967
|
+
if (codeFiles.length > 0) {
|
|
968
|
+
followUpTasks.push({
|
|
969
|
+
title: `Test changes in ${codeFiles.length} code files`,
|
|
970
|
+
description: `Verify functionality of: ${codeFiles.map(f => f.path).join(', ')}`,
|
|
971
|
+
priority: 'high',
|
|
972
|
+
category: 'testing',
|
|
973
|
+
tags: ['testing', 'verification']
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
// If release readiness improved, create release tasks
|
|
977
|
+
if (releaseReadinessResult?.isReady) {
|
|
978
|
+
const existingReleaseTasks = tasks.filter(task => task.title.toLowerCase().includes('release') ||
|
|
979
|
+
task.tags?.includes('release'));
|
|
980
|
+
if (existingReleaseTasks.length === 0) {
|
|
981
|
+
followUpTasks.push({
|
|
982
|
+
title: `Prepare release - all requirements met`,
|
|
983
|
+
description: `Project is now release-ready. Create release tag and publish.`,
|
|
984
|
+
priority: 'critical',
|
|
985
|
+
category: 'release',
|
|
986
|
+
tags: ['release', 'deployment']
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
// Create follow-up tasks
|
|
991
|
+
for (const taskData of followUpTasks) {
|
|
992
|
+
await todoManager.createTask(taskData);
|
|
993
|
+
}
|
|
994
|
+
// 3. Update task metadata with git information
|
|
995
|
+
const now = new Date().toISOString();
|
|
996
|
+
data.metadata.lastGitPush = now;
|
|
997
|
+
data.metadata.lastPushFiles = stagedFiles.map(f => f.path);
|
|
998
|
+
await todoManager.saveTodoData(data);
|
|
999
|
+
}
|
|
1000
|
+
catch (error) {
|
|
1001
|
+
// Silently handle errors to avoid breaking git push
|
|
1002
|
+
console.error('Error updating TODO tasks from git push:', error);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
525
1005
|
//# sourceMappingURL=smart-git-push-tool.js.map
|