mcp-adr-analysis-server 2.0.21 → 2.0.24

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.
Files changed (119) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/src/index.d.ts +9 -0
  3. package/dist/src/index.d.ts.map +1 -1
  4. package/dist/src/index.js +1380 -781
  5. package/dist/src/index.js.map +1 -1
  6. package/dist/src/tools/adr-suggestion-tool.d.ts.map +1 -1
  7. package/dist/src/tools/adr-suggestion-tool.js +32 -30
  8. package/dist/src/tools/adr-suggestion-tool.js.map +1 -1
  9. package/dist/src/tools/content-masking-tool.d.ts +4 -0
  10. package/dist/src/tools/content-masking-tool.d.ts.map +1 -1
  11. package/dist/src/tools/content-masking-tool.js +531 -28
  12. package/dist/src/tools/content-masking-tool.js.map +1 -1
  13. package/dist/src/tools/deployment-readiness-tool.d.ts +8 -5
  14. package/dist/src/tools/deployment-readiness-tool.d.ts.map +1 -1
  15. package/dist/src/tools/deployment-readiness-tool.js +741 -79
  16. package/dist/src/tools/deployment-readiness-tool.js.map +1 -1
  17. package/dist/src/tools/environment-analysis-tool.d.ts +4 -0
  18. package/dist/src/tools/environment-analysis-tool.d.ts.map +1 -1
  19. package/dist/src/tools/environment-analysis-tool.js +568 -24
  20. package/dist/src/tools/environment-analysis-tool.js.map +1 -1
  21. package/dist/src/tools/mcp-planning-tool.d.ts.map +1 -1
  22. package/dist/src/tools/mcp-planning-tool.js +298 -173
  23. package/dist/src/tools/mcp-planning-tool.js.map +1 -1
  24. package/dist/src/tools/memory-loading-tool.d.ts +60 -0
  25. package/dist/src/tools/memory-loading-tool.d.ts.map +1 -0
  26. package/dist/src/tools/memory-loading-tool.js +457 -0
  27. package/dist/src/tools/memory-loading-tool.js.map +1 -0
  28. package/dist/src/tools/smart-git-push-tool.d.ts +3 -0
  29. package/dist/src/tools/smart-git-push-tool.d.ts.map +1 -1
  30. package/dist/src/tools/smart-git-push-tool.js +177 -223
  31. package/dist/src/tools/smart-git-push-tool.js.map +1 -1
  32. package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts +20 -11
  33. package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts.map +1 -1
  34. package/dist/src/tools/troubleshoot-guided-workflow-tool.js +506 -22
  35. package/dist/src/tools/troubleshoot-guided-workflow-tool.js.map +1 -1
  36. package/dist/src/types/enhanced-errors.d.ts +173 -0
  37. package/dist/src/types/enhanced-errors.d.ts.map +1 -0
  38. package/dist/src/types/enhanced-errors.js +668 -0
  39. package/dist/src/types/enhanced-errors.js.map +1 -0
  40. package/dist/src/types/knowledge-graph-schemas.d.ts +92 -0
  41. package/dist/src/types/knowledge-graph-schemas.d.ts.map +1 -1
  42. package/dist/src/types/knowledge-graph-schemas.js +45 -17
  43. package/dist/src/types/knowledge-graph-schemas.js.map +1 -1
  44. package/dist/src/types/memory-entities.d.ts +7209 -0
  45. package/dist/src/types/memory-entities.d.ts.map +1 -0
  46. package/dist/src/types/memory-entities.js +395 -0
  47. package/dist/src/types/memory-entities.js.map +1 -0
  48. package/dist/src/types/todo-json-schemas.d.ts +7 -653
  49. package/dist/src/types/todo-json-schemas.d.ts.map +1 -1
  50. package/dist/src/types/todo-json-schemas.js +6 -110
  51. package/dist/src/types/todo-json-schemas.js.map +1 -1
  52. package/dist/src/utils/enhanced-logging.d.ts +195 -0
  53. package/dist/src/utils/enhanced-logging.d.ts.map +1 -0
  54. package/dist/src/utils/enhanced-logging.js +449 -0
  55. package/dist/src/utils/enhanced-logging.js.map +1 -0
  56. package/dist/src/utils/interactive-approval.d.ts +1 -1
  57. package/dist/src/utils/interactive-approval.d.ts.map +1 -1
  58. package/dist/src/utils/interactive-approval.js +20 -16
  59. package/dist/src/utils/interactive-approval.js.map +1 -1
  60. package/dist/src/utils/knowledge-graph-manager.d.ts +23 -1
  61. package/dist/src/utils/knowledge-graph-manager.d.ts.map +1 -1
  62. package/dist/src/utils/knowledge-graph-manager.js +297 -69
  63. package/dist/src/utils/knowledge-graph-manager.js.map +1 -1
  64. package/dist/src/utils/memory-entity-manager.d.ts +134 -0
  65. package/dist/src/utils/memory-entity-manager.d.ts.map +1 -0
  66. package/dist/src/utils/memory-entity-manager.js +848 -0
  67. package/dist/src/utils/memory-entity-manager.js.map +1 -0
  68. package/dist/src/utils/memory-health-scoring.d.ts +125 -0
  69. package/dist/src/utils/memory-health-scoring.d.ts.map +1 -0
  70. package/dist/src/utils/memory-health-scoring.js +277 -0
  71. package/dist/src/utils/memory-health-scoring.js.map +1 -0
  72. package/dist/src/utils/memory-migration-manager.d.ts +93 -0
  73. package/dist/src/utils/memory-migration-manager.d.ts.map +1 -0
  74. package/dist/src/utils/memory-migration-manager.js +834 -0
  75. package/dist/src/utils/memory-migration-manager.js.map +1 -0
  76. package/dist/src/utils/memory-relationship-mapper.d.ts +87 -0
  77. package/dist/src/utils/memory-relationship-mapper.d.ts.map +1 -0
  78. package/dist/src/utils/memory-relationship-mapper.js +481 -0
  79. package/dist/src/utils/memory-relationship-mapper.js.map +1 -0
  80. package/dist/src/utils/memory-rollback-manager.d.ts +93 -0
  81. package/dist/src/utils/memory-rollback-manager.d.ts.map +1 -0
  82. package/dist/src/utils/memory-rollback-manager.js +542 -0
  83. package/dist/src/utils/memory-rollback-manager.js.map +1 -0
  84. package/dist/src/utils/memory-transformation.d.ts +59 -0
  85. package/dist/src/utils/memory-transformation.d.ts.map +1 -0
  86. package/dist/src/utils/memory-transformation.js +742 -0
  87. package/dist/src/utils/memory-transformation.js.map +1 -0
  88. package/dist/src/utils/prompt-execution.d.ts.map +1 -1
  89. package/dist/src/utils/prompt-execution.js +72 -51
  90. package/dist/src/utils/prompt-execution.js.map +1 -1
  91. package/dist/src/utils/todo-file-watcher.d.ts +11 -23
  92. package/dist/src/utils/todo-file-watcher.d.ts.map +1 -1
  93. package/dist/src/utils/todo-file-watcher.js +18 -156
  94. package/dist/src/utils/todo-file-watcher.js.map +1 -1
  95. package/package.json +22 -6
  96. package/dist/src/tools/smart-score-tool.d.ts +0 -173
  97. package/dist/src/tools/smart-score-tool.d.ts.map +0 -1
  98. package/dist/src/tools/smart-score-tool.js +0 -681
  99. package/dist/src/tools/smart-score-tool.js.map +0 -1
  100. package/dist/src/tools/todo-management-tool-v2.d.ts +0 -368
  101. package/dist/src/tools/todo-management-tool-v2.d.ts.map +0 -1
  102. package/dist/src/tools/todo-management-tool-v2.js +0 -922
  103. package/dist/src/tools/todo-management-tool-v2.js.map +0 -1
  104. package/dist/src/utils/project-health-scoring.d.ts +0 -177
  105. package/dist/src/utils/project-health-scoring.d.ts.map +0 -1
  106. package/dist/src/utils/project-health-scoring.js +0 -370
  107. package/dist/src/utils/project-health-scoring.js.map +0 -1
  108. package/dist/src/utils/todo-json-manager.d.ts +0 -71
  109. package/dist/src/utils/todo-json-manager.d.ts.map +0 -1
  110. package/dist/src/utils/todo-json-manager.js +0 -396
  111. package/dist/src/utils/todo-json-manager.js.map +0 -1
  112. package/dist/src/utils/todo-markdown-converter.d.ts +0 -16
  113. package/dist/src/utils/todo-markdown-converter.d.ts.map +0 -1
  114. package/dist/src/utils/todo-markdown-converter.js +0 -362
  115. package/dist/src/utils/todo-markdown-converter.js.map +0 -1
  116. package/dist/src/utils/todo-migration.d.ts +0 -47
  117. package/dist/src/utils/todo-migration.d.ts.map +0 -1
  118. package/dist/src/utils/todo-migration.js +0 -261
  119. package/dist/src/utils/todo-migration.js.map +0 -1
@@ -1,681 +0,0 @@
1
- /**
2
- * Smart Score Tool - Central Coordination for Project Health Scoring
3
- *
4
- * Provides comprehensive scoring coordination across all MCP tools:
5
- * - Cross-tool score synchronization
6
- * - Manual score recalculation and rebalancing
7
- * - Health score diagnostics and validation
8
- * - Automated score updates and maintenance
9
- *
10
- * IMPORTANT FOR AI ASSISTANTS: This tool depends on cache infrastructure and
11
- * works best when other tools have already populated data.
12
- *
13
- * Cache Dependencies:
14
- * - Requires: .mcp-adr-cache/project-health-scores.json (main scoring data)
15
- * - May read: .mcp-adr-cache/todo-data.json (for task completion scoring)
16
- * - Updates: .mcp-adr-cache/project-health-scores.json (with new scores)
17
- *
18
- * Workflow Timing:
19
- * - Run AFTER other tools have populated cache data
20
- * - Use 'recalculate_scores' to refresh stale data
21
- * - Use 'sync_scores' to synchronize across tools
22
- * - Use 'optimize_weights' for score tuning
23
- */
24
- import { z } from 'zod';
25
- import { McpAdrError } from '../types/index.js';
26
- // Operation schemas for smart scoring
27
- const RecalculateScoresSchema = z.object({
28
- operation: z.literal('recalculate_scores'),
29
- projectPath: z.string().describe('Path to project directory'),
30
- components: z.array(z.enum(['task_completion', 'deployment_readiness', 'architecture_compliance', 'security_posture', 'code_quality', 'all'])).default(['all']).describe('Score components to recalculate'),
31
- forceUpdate: z.boolean().default(false).describe('Force update even if data is fresh'),
32
- updateSources: z.boolean().default(true).describe('Trigger source tool updates before recalculating')
33
- });
34
- const SyncScoresSchema = z.object({
35
- operation: z.literal('sync_scores'),
36
- projectPath: z.string().describe('Path to project directory'),
37
- todoPath: z.string().default('TODO.md').describe('Path to TODO.md file'),
38
- triggerTools: z.array(z.enum(['manage_todo', 'smart_git_push', 'compare_adr_progress', 'analyze_content_security', 'validate_rules'])).optional().describe('Tools to trigger for fresh data'),
39
- rebalanceWeights: z.boolean().default(false).describe('Recalculate optimal scoring weights')
40
- });
41
- const DiagnoseScoresSchema = z.object({
42
- operation: z.literal('diagnose_scores'),
43
- projectPath: z.string().describe('Path to project directory'),
44
- includeHistory: z.boolean().default(true).describe('Include score history analysis'),
45
- checkDataFreshness: z.boolean().default(true).describe('Validate data freshness across tools'),
46
- suggestImprovements: z.boolean().default(true).describe('Provide score improvement suggestions')
47
- });
48
- const OptimizeWeightsSchema = z.object({
49
- operation: z.literal('optimize_weights'),
50
- projectPath: z.string().describe('Path to project directory'),
51
- analysisMode: z.enum(['current_state', 'historical_data', 'project_type']).default('current_state').describe('Method for weight optimization'),
52
- customWeights: z.object({
53
- taskCompletion: z.number().min(0).max(1).optional(),
54
- deploymentReadiness: z.number().min(0).max(1).optional(),
55
- architectureCompliance: z.number().min(0).max(1).optional(),
56
- securityPosture: z.number().min(0).max(1).optional(),
57
- codeQuality: z.number().min(0).max(1).optional()
58
- }).optional().describe('Custom weight overrides'),
59
- previewOnly: z.boolean().default(false).describe('Preview changes without applying')
60
- });
61
- const ResetScoresSchema = z.object({
62
- operation: z.literal('reset_scores'),
63
- projectPath: z.string().describe('Path to project directory'),
64
- component: z.enum(['task_completion', 'deployment_readiness', 'architecture_compliance', 'security_posture', 'code_quality', 'all']).default('all').describe('Score component to reset'),
65
- preserveHistory: z.boolean().default(true).describe('Preserve score history in backup'),
66
- recalculateAfterReset: z.boolean().default(true).describe('Immediately recalculate after reset')
67
- });
68
- // Main operation schema
69
- const GetScoreTrendsSchema = z.object({
70
- operation: z.literal('get_score_trends'),
71
- projectPath: z.string().describe('Path to project directory')
72
- });
73
- const GetIntentScoresSchema = z.object({
74
- operation: z.literal('get_intent_scores'),
75
- projectPath: z.string().describe('Path to project directory'),
76
- intentId: z.string().describe('Intent ID to get score trends for')
77
- });
78
- const SmartScoreSchema = z.union([
79
- RecalculateScoresSchema,
80
- SyncScoresSchema,
81
- DiagnoseScoresSchema,
82
- OptimizeWeightsSchema,
83
- ResetScoresSchema,
84
- GetScoreTrendsSchema,
85
- GetIntentScoresSchema
86
- ]);
87
- /**
88
- * Trigger score updates from source tools
89
- */
90
- async function triggerSourceToolUpdates(projectPath, tools) {
91
- const results = {};
92
- for (const tool of tools) {
93
- try {
94
- switch (tool) {
95
- case 'manage_todo':
96
- // Trigger TODO analysis to update task completion scores
97
- const { manageTodoV2 } = await import('./todo-management-tool-v2.js');
98
- results[tool] = await manageTodoV2({
99
- operation: 'get_analytics',
100
- projectPath,
101
- timeframe: 'all',
102
- includeVelocity: true,
103
- includeScoring: true
104
- });
105
- break;
106
- case 'smart_git_push':
107
- // Trigger git release readiness analysis
108
- const { smartGitPush } = await import('./smart-git-push-tool.js');
109
- results[tool] = await smartGitPush({
110
- projectPath,
111
- checkReleaseReadiness: true,
112
- dryRun: true // Don't actually push, just analyze
113
- });
114
- break;
115
- case 'compare_adr_progress':
116
- // Trigger ADR progress comparison
117
- // This would need to be implemented in the main server
118
- results[tool] = { status: 'tool_not_available', message: 'compare_adr_progress integration pending' };
119
- break;
120
- case 'analyze_content_security':
121
- // Trigger content security analysis
122
- // This would need to be implemented in the main server
123
- results[tool] = { status: 'tool_not_available', message: 'analyze_content_security integration pending' };
124
- break;
125
- case 'validate_rules':
126
- // Trigger rule validation
127
- // This would need to be implemented in the main server
128
- results[tool] = { status: 'tool_not_available', message: 'validate_rules integration pending' };
129
- break;
130
- default:
131
- results[tool] = { status: 'unknown_tool', message: `Tool ${tool} not recognized` };
132
- }
133
- }
134
- catch (error) {
135
- results[tool] = {
136
- status: 'error',
137
- message: `Failed to trigger ${tool}: ${error instanceof Error ? error.message : String(error)}`
138
- };
139
- }
140
- }
141
- return results;
142
- }
143
- /**
144
- * Calculate optimal weights based on project characteristics
145
- */
146
- async function calculateOptimalWeights(projectPath, _analysisMode) {
147
- const fs = await import('fs/promises');
148
- const path = await import('path');
149
- // Default weights
150
- const defaultWeights = {
151
- taskCompletion: 0.25,
152
- deploymentReadiness: 0.30,
153
- architectureCompliance: 0.20,
154
- securityPosture: 0.15,
155
- codeQuality: 0.10
156
- };
157
- try {
158
- // Analyze project characteristics
159
- const packageJsonPath = path.join(projectPath, 'package.json');
160
- let projectType = 'general';
161
- let hasTests = false;
162
- let hasCi = false;
163
- try {
164
- const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
165
- // Determine project type
166
- if (packageJson.dependencies?.['express'] || packageJson.dependencies?.['fastify']) {
167
- projectType = 'backend_api';
168
- }
169
- else if (packageJson.dependencies?.['react'] || packageJson.dependencies?.['vue'] || packageJson.dependencies?.['angular']) {
170
- projectType = 'frontend';
171
- }
172
- else if (packageJson.dependencies?.['electron']) {
173
- projectType = 'desktop_app';
174
- }
175
- else if (packageJson.type === 'module' || packageJson.main?.endsWith('.mjs')) {
176
- projectType = 'library';
177
- }
178
- // Check for testing setup
179
- hasTests = Boolean(packageJson.scripts?.test ||
180
- packageJson.devDependencies?.jest ||
181
- packageJson.devDependencies?.mocha ||
182
- packageJson.devDependencies?.vitest);
183
- // Check for CI/CD
184
- const ciFiles = ['.github/workflows', '.gitlab-ci.yml', 'azure-pipelines.yml', '.circleci'];
185
- hasCi = false;
186
- for (const ciFile of ciFiles) {
187
- try {
188
- await fs.access(path.join(projectPath, ciFile));
189
- hasCi = true;
190
- break;
191
- }
192
- catch { }
193
- }
194
- }
195
- catch (error) {
196
- // Fall back to default weights if package.json analysis fails
197
- }
198
- // Adjust weights based on project characteristics
199
- let optimizedWeights = { ...defaultWeights };
200
- switch (projectType) {
201
- case 'backend_api':
202
- // APIs prioritize security and deployment
203
- optimizedWeights = {
204
- taskCompletion: 0.20,
205
- deploymentReadiness: 0.35,
206
- architectureCompliance: 0.15,
207
- securityPosture: 0.25,
208
- codeQuality: 0.05
209
- };
210
- break;
211
- case 'frontend':
212
- // Frontend prioritizes task completion and code quality
213
- optimizedWeights = {
214
- taskCompletion: 0.35,
215
- deploymentReadiness: 0.25,
216
- architectureCompliance: 0.15,
217
- securityPosture: 0.10,
218
- codeQuality: 0.15
219
- };
220
- break;
221
- case 'library':
222
- // Libraries prioritize code quality and architecture
223
- optimizedWeights = {
224
- taskCompletion: 0.20,
225
- deploymentReadiness: 0.20,
226
- architectureCompliance: 0.30,
227
- securityPosture: 0.15,
228
- codeQuality: 0.15
229
- };
230
- break;
231
- case 'desktop_app':
232
- // Desktop apps balance all aspects
233
- optimizedWeights = {
234
- taskCompletion: 0.25,
235
- deploymentReadiness: 0.25,
236
- architectureCompliance: 0.20,
237
- securityPosture: 0.15,
238
- codeQuality: 0.15
239
- };
240
- break;
241
- }
242
- // Adjust for testing maturity
243
- if (hasTests) {
244
- optimizedWeights.codeQuality += 0.05;
245
- optimizedWeights.taskCompletion -= 0.05;
246
- }
247
- // Adjust for CI/CD maturity
248
- if (hasCi) {
249
- optimizedWeights.deploymentReadiness += 0.05;
250
- optimizedWeights.taskCompletion -= 0.05;
251
- }
252
- // Ensure weights sum to 1.0
253
- const total = Object.values(optimizedWeights).reduce((sum, weight) => sum + weight, 0);
254
- if (total !== 1.0) {
255
- const factor = 1.0 / total;
256
- Object.keys(optimizedWeights).forEach(key => {
257
- optimizedWeights[key] *= factor;
258
- });
259
- }
260
- return optimizedWeights;
261
- }
262
- catch (error) {
263
- return defaultWeights;
264
- }
265
- }
266
- /**
267
- * Main smart score function
268
- */
269
- export async function smartScore(args) {
270
- try {
271
- const validatedArgs = SmartScoreSchema.parse(args);
272
- switch (validatedArgs.operation) {
273
- case 'recalculate_scores': {
274
- const { ProjectHealthScoring } = await import('../utils/project-health-scoring.js');
275
- const healthScoring = new ProjectHealthScoring(validatedArgs.projectPath);
276
- // Trigger source updates if requested
277
- let sourceResults = {};
278
- let todoData = null;
279
- if (validatedArgs.updateSources) {
280
- const allTools = ['manage_todo', 'smart_git_push', 'compare_adr_progress', 'analyze_content_security', 'validate_rules'];
281
- sourceResults = await triggerSourceToolUpdates(validatedArgs.projectPath, allTools);
282
- // Extract TODO data if available
283
- if (sourceResults['manage_todo']?.content?.[0]?.text) {
284
- const analysisText = sourceResults['manage_todo'].content[0].text;
285
- const completionMatch = analysisText.match(/(\d+)\/(\d+) tasks? completed \((\d+)%\)/);
286
- if (completionMatch) {
287
- todoData = {
288
- completed: parseInt(completionMatch[1]),
289
- total: parseInt(completionMatch[2]),
290
- percentage: parseInt(completionMatch[3])
291
- };
292
- }
293
- }
294
- }
295
- // Get current scores
296
- const currentScores = await healthScoring.getProjectHealthScore();
297
- return {
298
- content: [{
299
- type: 'text',
300
- text: `# 🔄 Scores Recalculated Successfully
301
-
302
- ## Updated Project Health Scores:
303
- - 🎯 **Overall**: ${currentScores.overall}% (${currentScores.confidence}% confidence)
304
- - 📋 **Task Completion**: ${currentScores.taskCompletion}%
305
- - 🚀 **Deployment Readiness**: ${currentScores.deploymentReadiness}%
306
- - 🏗️ **Architecture Compliance**: ${currentScores.architectureCompliance}%
307
- - 🔒 **Security Posture**: ${currentScores.securityPosture}%
308
- - 🛠️ **Code Quality**: ${currentScores.codeQuality}%
309
-
310
- ## Components Recalculated:
311
- ${validatedArgs.components.includes('all') ? '- All components updated' : validatedArgs.components.map(c => `- ${c.replace('_', ' ')}`).join('\n')}${todoData ? `\n\n## TODO.md Balance Check:
312
- - Task Completion from TODO.md: ${todoData.percentage}%
313
- - Health Score Task Completion: ${currentScores.taskCompletion}%
314
- - ${Math.abs(todoData.percentage - currentScores.taskCompletion) > 10 ? '⚠️ Significant difference detected - consider running sync_scores' : '✅ Scores are well balanced'}` : ''}
315
-
316
- ## Source Tool Updates:
317
- ${Object.entries(sourceResults).map(([tool, result]) => `- **${tool}**: ${result.status || 'success'}`).join('\n')}
318
-
319
- ## Data Freshness:
320
- - **Last Updated**: ${new Date(currentScores.lastUpdated).toLocaleString()}
321
- - **Contributing Tools**: ${currentScores.influencingTools.join(', ') || 'None'}
322
-
323
- *All TODO.md files will automatically display updated health scores on next access.*`
324
- }]
325
- };
326
- }
327
- case 'sync_scores': {
328
- const { ProjectHealthScoring } = await import('../utils/project-health-scoring.js');
329
- const healthScoring = new ProjectHealthScoring(validatedArgs.projectPath);
330
- // Trigger specific tools if requested
331
- let triggerResults = {};
332
- if (validatedArgs.triggerTools && validatedArgs.triggerTools.length > 0) {
333
- triggerResults = await triggerSourceToolUpdates(validatedArgs.projectPath, validatedArgs.triggerTools);
334
- }
335
- // Force a TODO update to sync task completion scores
336
- const { manageTodoV2 } = await import('./todo-management-tool-v2.js');
337
- const todoAnalysis = await manageTodoV2({
338
- operation: 'get_analytics',
339
- projectPath: validatedArgs.projectPath,
340
- timeframe: 'all',
341
- includeVelocity: true,
342
- includeScoring: true
343
- });
344
- // Extract task completion data from TODO analysis
345
- let todoCompletionData = null;
346
- if (todoAnalysis?.content?.[0]?.text) {
347
- const analysisText = todoAnalysis.content[0].text;
348
- // Parse completion metrics from the analysis
349
- const completionMatch = analysisText.match(/(\d+)\/(\d+) tasks? completed \((\d+)%\)/);
350
- const criticalMatch = analysisText.match(/(\d+) critical\/high priority tasks? remaining/);
351
- if (completionMatch) {
352
- todoCompletionData = {
353
- completed: parseInt(completionMatch[1]),
354
- total: parseInt(completionMatch[2]),
355
- percentage: parseInt(completionMatch[3]),
356
- criticalRemaining: criticalMatch ? parseInt(criticalMatch[1]) : 0
357
- };
358
- }
359
- }
360
- // Get synchronized scores
361
- const syncedScores = await healthScoring.getProjectHealthScore();
362
- // Optimize weights if requested
363
- let weightOptimization = null;
364
- if (validatedArgs.rebalanceWeights) {
365
- const optimalWeights = await calculateOptimalWeights(validatedArgs.projectPath, 'current_state');
366
- weightOptimization = {
367
- current: {
368
- taskCompletion: 0.25,
369
- deploymentReadiness: 0.30,
370
- architectureCompliance: 0.20,
371
- securityPosture: 0.15,
372
- codeQuality: 0.10
373
- },
374
- optimal: optimalWeights
375
- };
376
- }
377
- return {
378
- content: [{
379
- type: 'text',
380
- text: `# 🔄 Cross-Tool Score Synchronization Complete
381
-
382
- ## Synchronized Health Scores:
383
- - 🎯 **Overall Project Health**: ${syncedScores.overall}% (${syncedScores.confidence}% confidence)
384
-
385
- ### 📊 Component Breakdown:
386
- - 📋 **Task Completion**: ${syncedScores.taskCompletion}% (${syncedScores.breakdown.taskCompletion.completed}/${syncedScores.breakdown.taskCompletion.total} tasks)${todoCompletionData ? `
387
- - TODO.md Analysis: ${todoCompletionData.completed}/${todoCompletionData.total} (${todoCompletionData.percentage}%)
388
- - Critical/High Priority Remaining: ${todoCompletionData.criticalRemaining}` : ''}
389
- - 🚀 **Deployment Readiness**: ${syncedScores.deploymentReadiness}% (${syncedScores.breakdown.deploymentReadiness.criticalBlockers} critical blockers)
390
- - 🏗️ **Architecture Compliance**: ${syncedScores.architectureCompliance}%
391
- - 🔒 **Security Posture**: ${syncedScores.securityPosture}% (${syncedScores.breakdown.securityPosture.vulnerabilityCount} vulnerabilities)
392
- - 🛠️ **Code Quality**: ${syncedScores.codeQuality}% (${syncedScores.breakdown.codeQuality.ruleViolations} violations)
393
-
394
- ## Tool Synchronization Results:
395
- ${Object.entries(triggerResults).map(([tool, result]) => `- **${tool}**: ${result.status === 'error' ? '❌ Failed' : '✅ Updated'}`).join('\n')}
396
-
397
- ${weightOptimization ? `
398
- ## Weight Optimization Analysis:
399
- ### Current Weights vs Optimal:
400
- ${Object.entries(weightOptimization.optimal).map(([key, value]) => `- **${key}**: ${(weightOptimization.current[key] * 100).toFixed(0)}% → ${(Number(value) * 100).toFixed(0)}%`).join('\n')}
401
-
402
- *Use \`optimize_weights\` operation to apply optimal weights.*
403
- ` : ''}
404
-
405
- ## Data Status:
406
- - **Last Synchronized**: ${new Date().toLocaleString()}
407
- - **Data Confidence**: ${syncedScores.confidence}%
408
- - **Contributing Tools**: ${syncedScores.influencingTools.join(', ') || 'manage_todo (default)'}
409
-
410
- *All health dashboards will reflect these synchronized scores.*`
411
- }]
412
- };
413
- }
414
- case 'diagnose_scores': {
415
- const { ProjectHealthScoring } = await import('../utils/project-health-scoring.js');
416
- const healthScoring = new ProjectHealthScoring(validatedArgs.projectPath);
417
- const currentScores = await healthScoring.getProjectHealthScore();
418
- // Check data freshness
419
- const now = new Date();
420
- const lastUpdate = new Date(currentScores.lastUpdated);
421
- const hoursSinceUpdate = (now.getTime() - lastUpdate.getTime()) / (1000 * 60 * 60);
422
- const dataFreshness = hoursSinceUpdate < 1 ? 'Fresh' :
423
- hoursSinceUpdate < 24 ? 'Recent' :
424
- hoursSinceUpdate < 72 ? 'Stale' : 'Very Stale';
425
- // Analyze component health
426
- const componentAnalysis = [
427
- { name: 'Task Completion', score: currentScores.taskCompletion, threshold: 70 },
428
- { name: 'Deployment Readiness', score: currentScores.deploymentReadiness, threshold: 75 },
429
- { name: 'Architecture Compliance', score: currentScores.architectureCompliance, threshold: 60 },
430
- { name: 'Security Posture', score: currentScores.securityPosture, threshold: 80 },
431
- { name: 'Code Quality', score: currentScores.codeQuality, threshold: 65 }
432
- ];
433
- const weakComponents = componentAnalysis.filter(c => c.score < c.threshold);
434
- const strongComponents = componentAnalysis.filter(c => c.score >= c.threshold + 15);
435
- // Generate improvement suggestions
436
- const suggestions = [];
437
- if (currentScores.breakdown.taskCompletion.criticalTasksRemaining > 0) {
438
- suggestions.push('🔴 Address critical/blocked tasks to improve task completion score');
439
- }
440
- if (currentScores.breakdown.deploymentReadiness.criticalBlockers > 0) {
441
- suggestions.push('🚀 Resolve deployment blockers to improve readiness score');
442
- }
443
- if (currentScores.breakdown.securityPosture.vulnerabilityCount > 0) {
444
- suggestions.push('🔒 Fix security vulnerabilities to boost security posture');
445
- }
446
- if (currentScores.breakdown.codeQuality.ruleViolations > 3) {
447
- suggestions.push('🛠️ Address code quality violations to improve standards');
448
- }
449
- if (currentScores.confidence < 70) {
450
- suggestions.push('🔄 Run score synchronization to refresh stale data');
451
- }
452
- return {
453
- content: [{
454
- type: 'text',
455
- text: `# 🔍 Project Health Score Diagnostics
456
-
457
- ## Overall Assessment:
458
- - 🎯 **Overall Health**: ${currentScores.overall}% ${currentScores.overall >= 80 ? '🟢 Excellent' : currentScores.overall >= 60 ? '🟡 Good' : '🔴 Needs Improvement'}
459
- - 📊 **Data Confidence**: ${currentScores.confidence}% (${dataFreshness})
460
- - ⏰ **Last Updated**: ${lastUpdate.toLocaleString()} (${Math.round(hoursSinceUpdate)} hours ago)
461
-
462
- ## Component Analysis:
463
-
464
- ### 💪 Strong Areas:
465
- ${strongComponents.length > 0 ? strongComponents.map(c => `- **${c.name}**: ${c.score}% 🟢`).join('\n') : '- No components currently exceeding excellence thresholds'}
466
-
467
- ### ⚠️ Areas for Improvement:
468
- ${weakComponents.length > 0 ? weakComponents.map(c => `- **${c.name}**: ${c.score}% (target: ${c.threshold}%)`).join('\n') : '- All components meeting target thresholds! 🎉'}
469
-
470
- ## Detailed Breakdown:
471
- - 📋 **Task Completion**: ${currentScores.taskCompletion}% | ${currentScores.breakdown.taskCompletion.completed}/${currentScores.breakdown.taskCompletion.total} tasks | ${currentScores.breakdown.taskCompletion.criticalTasksRemaining} critical remaining
472
- - 🚀 **Deployment**: ${currentScores.deploymentReadiness}% | ${currentScores.breakdown.deploymentReadiness.criticalBlockers} critical blockers | ${currentScores.breakdown.deploymentReadiness.warningBlockers} warnings
473
- - 🏗️ **Architecture**: ${currentScores.architectureCompliance}% | ADR compliance tracking
474
- - 🔒 **Security**: ${currentScores.securityPosture}% | ${currentScores.breakdown.securityPosture.vulnerabilityCount} vulnerabilities | ${currentScores.breakdown.securityPosture.contentMaskingEffectiveness}% masking effectiveness
475
- - 🛠️ **Code Quality**: ${currentScores.codeQuality}% | ${currentScores.breakdown.codeQuality.ruleViolations} violations | ${currentScores.breakdown.codeQuality.patternAdherence}% pattern adherence
476
-
477
- ## Data Source Status:
478
- ${currentScores.influencingTools.length > 0 ?
479
- currentScores.influencingTools.map(tool => `- ✅ **${tool}**: Contributing data`).join('\n') :
480
- '- ⚠️ **Limited data sources**: Only basic scoring available'}
481
-
482
- ${validatedArgs.suggestImprovements && suggestions.length > 0 ? `
483
- ## 🎯 Recommended Actions:
484
- ${suggestions.map(s => `${s}`).join('\n')}
485
-
486
- ## Quick Fixes:
487
- 1. Run \`sync_scores\` to refresh all data sources
488
- 2. Use \`recalculate_scores\` with \`updateSources: true\` for comprehensive refresh
489
- 3. Address highest-impact issues first (critical tasks, security vulnerabilities)
490
- ` : ''}
491
-
492
- *Use \`sync_scores\` or \`recalculate_scores\` to refresh diagnostic data.*`
493
- }]
494
- };
495
- }
496
- case 'optimize_weights': {
497
- const optimalWeights = await calculateOptimalWeights(validatedArgs.projectPath, validatedArgs.analysisMode);
498
- // Apply custom weight overrides if provided
499
- let finalWeights = { ...optimalWeights };
500
- if (validatedArgs.customWeights) {
501
- Object.entries(validatedArgs.customWeights).forEach(([key, value]) => {
502
- if (value !== undefined) {
503
- finalWeights[key] = value;
504
- }
505
- });
506
- // Renormalize to ensure sum = 1.0
507
- const total = Object.values(finalWeights).reduce((sum, weight) => sum + weight, 0);
508
- if (total !== 1.0) {
509
- const factor = 1.0 / total;
510
- Object.keys(finalWeights).forEach(key => {
511
- finalWeights[key] *= factor;
512
- });
513
- }
514
- }
515
- if (!validatedArgs.previewOnly) {
516
- // Apply the optimized weights
517
- const { ProjectHealthScoring } = await import('../utils/project-health-scoring.js');
518
- new ProjectHealthScoring(validatedArgs.projectPath, finalWeights);
519
- // Note: Weight application would require updating the ProjectHealthScoring class constructor
520
- // For now, we return the preview showing what would change
521
- return {
522
- content: [{
523
- type: 'text',
524
- text: `# ⚖️ Scoring Weights Preview
525
-
526
- ## New Weight Configuration Would Be Applied:
527
- ${Object.entries(finalWeights).map(([key, value]) => `- **${key.replace(/([A-Z])/g, ' $1').toLowerCase()}**: ${(Number(value) * 100).toFixed(1)}%`).join('\n')}
528
-
529
- ## Optimization Method: ${validatedArgs.analysisMode}
530
- ${validatedArgs.customWeights ? '## Custom Overrides Applied: Yes' : ''}
531
-
532
- *Note: Weight application requires ProjectHealthScoring class enhancement.*
533
- *For now, this shows the optimal configuration that would be applied.*`
534
- }]
535
- };
536
- }
537
- else {
538
- // Preview mode - show what would change
539
- const currentWeights = {
540
- taskCompletion: 0.25,
541
- deploymentReadiness: 0.30,
542
- architectureCompliance: 0.20,
543
- securityPosture: 0.15,
544
- codeQuality: 0.10
545
- };
546
- return {
547
- content: [{
548
- type: 'text',
549
- text: `# ⚖️ Weight Optimization Preview
550
-
551
- ## Current vs Optimal Weights:
552
- ${Object.entries(finalWeights).map(([key, value]) => {
553
- const current = currentWeights[key] * 100;
554
- const optimal = Number(value) * 100;
555
- const change = optimal - current;
556
- const arrow = change > 0 ? '↗️' : change < 0 ? '↘️' : '➡️';
557
- return `- **${key.replace(/([A-Z])/g, ' $1').toLowerCase()}**: ${current.toFixed(1)}% ${arrow} ${optimal.toFixed(1)}% ${change !== 0 ? `(${change > 0 ? '+' : ''}${change.toFixed(1)}%)` : ''}`;
558
- }).join('\n')}
559
-
560
- ## Optimization Rationale:
561
- - **Analysis Method**: ${validatedArgs.analysisMode}
562
- - **Project Type**: Detected from package.json and project structure
563
- - **Customizations**: ${validatedArgs.customWeights ? 'Custom weights provided' : 'Auto-detected optimal weights'}
564
-
565
- **To apply these weights, run the same command with \`previewOnly: false\`**`
566
- }]
567
- };
568
- }
569
- }
570
- case 'reset_scores': {
571
- const { ProjectHealthScoring } = await import('../utils/project-health-scoring.js');
572
- // Create backup if preserving history
573
- let backupPath = null;
574
- if (validatedArgs.preserveHistory) {
575
- const fs = await import('fs/promises');
576
- const path = await import('path');
577
- const cachePath = path.join(validatedArgs.projectPath, '.mcp-adr-cache', 'project-health-scores.json');
578
- backupPath = `${cachePath}.backup.${Date.now()}`;
579
- try {
580
- const currentScores = await fs.readFile(cachePath, 'utf-8');
581
- await fs.writeFile(backupPath, currentScores, 'utf-8');
582
- }
583
- catch (error) {
584
- // Backup failed, but continue with reset
585
- backupPath = null;
586
- }
587
- }
588
- // Reset scores by creating fresh instance
589
- const resetScoring = new ProjectHealthScoring(validatedArgs.projectPath);
590
- const resetScores = await resetScoring.getProjectHealthScore();
591
- // Recalculate if requested
592
- if (validatedArgs.recalculateAfterReset) {
593
- const allTools = ['manage_todo', 'smart_git_push'];
594
- await triggerSourceToolUpdates(validatedArgs.projectPath, allTools);
595
- }
596
- return {
597
- content: [{
598
- type: 'text',
599
- text: `# 🔄 Scores Reset Successfully
600
-
601
- ## Reset Component: ${validatedArgs.component}
602
-
603
- ## Fresh Baseline Scores:
604
- - 🎯 **Overall**: ${resetScores.overall}%
605
- - 📋 **Task Completion**: ${resetScores.taskCompletion}%
606
- - 🚀 **Deployment Readiness**: ${resetScores.deploymentReadiness}%
607
- - 🏗️ **Architecture Compliance**: ${resetScores.architectureCompliance}%
608
- - 🔒 **Security Posture**: ${resetScores.securityPosture}%
609
- - 🛠️ **Code Quality**: ${resetScores.codeQuality}%
610
-
611
- ${backupPath ? `## Backup Created: \`${backupPath}\`` : ''}
612
- ${validatedArgs.recalculateAfterReset ? '## Recalculation: ✅ Fresh data collected from available tools' : '## Recalculation: ⏸️ Skipped (use recalculate_scores to refresh)'}
613
-
614
- *Health scoring system has been reset to baseline values.*`
615
- }]
616
- };
617
- }
618
- case 'get_score_trends': {
619
- const { KnowledgeGraphManager } = await import('../utils/knowledge-graph-manager.js');
620
- const kgManager = new KnowledgeGraphManager();
621
- const trends = await kgManager.getProjectScoreTrends();
622
- return {
623
- content: [{
624
- type: 'text',
625
- text: `# 📊 Project Score Trends
626
-
627
- ## Current Score: ${trends.currentScore}%
628
-
629
- ## Score History (${trends.scoreHistory.length} entries):
630
- ${trends.scoreHistory.slice(-10).map(entry => `- **${new Date(entry.timestamp).toLocaleString()}**: ${entry.score}% (${entry.triggerEvent})`).join('\n')}
631
-
632
- ## Performance Analytics:
633
- - **Average Improvement**: ${trends.averageImprovement.toFixed(1)}%
634
- - **Score Entries**: ${trends.scoreHistory.length}
635
-
636
- ## Top Impacting Intents:
637
- ${trends.topImpactingIntents.map(intent => `- **${intent.scoreImprovement > 0 ? '+' : ''}${intent.scoreImprovement.toFixed(1)}%**: ${intent.humanRequest.substring(0, 80)}...`).join('\n')}
638
-
639
- *Score trends track the impact of human intents on project health over time.*`
640
- }]
641
- };
642
- }
643
- case 'get_intent_scores': {
644
- const { KnowledgeGraphManager } = await import('../utils/knowledge-graph-manager.js');
645
- const kgManager = new KnowledgeGraphManager();
646
- if (!validatedArgs.intentId) {
647
- throw new McpAdrError('intentId is required for get_intent_scores operation', 'INVALID_INPUT');
648
- }
649
- const intentTrends = await kgManager.getIntentScoreTrends(validatedArgs.intentId);
650
- return {
651
- content: [{
652
- type: 'text',
653
- text: `# 🎯 Intent Score Analysis
654
-
655
- ## Intent Progress:
656
- - **Initial Score**: ${intentTrends.initialScore}%
657
- - **Current Score**: ${intentTrends.currentScore}%
658
- - **Progress**: ${intentTrends.progress.toFixed(1)}%
659
-
660
- ## Component Scores:
661
- ${Object.entries(intentTrends.componentTrends).map(([component, score]) => `- **${component.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase())}**: ${score}%`).join('\n')}
662
-
663
- ## Score History for this Intent:
664
- ${intentTrends.scoreHistory.map(entry => `- **${new Date(entry.timestamp).toLocaleString()}**: ${entry.score}% (${entry.triggerEvent})`).join('\n')}
665
-
666
- *Intent scores track how specific human requests impact project health metrics.*`
667
- }]
668
- };
669
- }
670
- default:
671
- throw new McpAdrError(`Unknown smart score operation: ${validatedArgs.operation}`, 'INVALID_INPUT');
672
- }
673
- }
674
- catch (error) {
675
- if (error instanceof z.ZodError) {
676
- throw new McpAdrError(`Invalid input: ${error.errors.map(e => e.message).join(', ')}`, 'INVALID_INPUT');
677
- }
678
- throw new McpAdrError(`Smart score operation failed: ${error instanceof Error ? error.message : String(error)}`, 'SMART_SCORE_ERROR');
679
- }
680
- }
681
- //# sourceMappingURL=smart-score-tool.js.map