mcp-adr-analysis-server 2.0.21 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -839
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/config/ai-config.d.ts.map +1 -1
- package/dist/src/config/ai-config.js +9 -9
- package/dist/src/config/ai-config.js.map +1 -1
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1594 -837
- package/dist/src/index.js.map +1 -1
- package/dist/src/prompts/analysis-prompts.d.ts +4 -1
- package/dist/src/prompts/analysis-prompts.d.ts.map +1 -1
- package/dist/src/prompts/analysis-prompts.js +61 -30
- package/dist/src/prompts/analysis-prompts.js.map +1 -1
- package/dist/src/prompts/index.d.ts +17 -1
- package/dist/src/prompts/index.d.ts.map +1 -1
- package/dist/src/prompts/index.js +325 -1
- package/dist/src/prompts/index.js.map +1 -1
- package/dist/src/prompts/rule-generation-prompts.d.ts +5 -1
- package/dist/src/prompts/rule-generation-prompts.d.ts.map +1 -1
- package/dist/src/prompts/rule-generation-prompts.js +5 -1
- package/dist/src/prompts/rule-generation-prompts.js.map +1 -1
- package/dist/src/prompts/security-prompts.d.ts +6 -1
- package/dist/src/prompts/security-prompts.d.ts.map +1 -1
- package/dist/src/prompts/security-prompts.js +6 -1
- package/dist/src/prompts/security-prompts.js.map +1 -1
- package/dist/src/prompts/todo-prompts.d.ts +49 -0
- package/dist/src/prompts/todo-prompts.d.ts.map +1 -0
- package/dist/src/prompts/todo-prompts.js +824 -0
- package/dist/src/prompts/todo-prompts.js.map +1 -0
- package/dist/src/resources/index.d.ts.map +1 -1
- package/dist/src/resources/index.js +9 -7
- package/dist/src/resources/index.js.map +1 -1
- package/dist/src/tools/adr-bootstrap-validation-tool.d.ts +47 -0
- package/dist/src/tools/adr-bootstrap-validation-tool.d.ts.map +1 -0
- package/dist/src/tools/adr-bootstrap-validation-tool.js +979 -0
- package/dist/src/tools/adr-bootstrap-validation-tool.js.map +1 -0
- package/dist/src/tools/adr-suggestion-tool.d.ts +1 -0
- package/dist/src/tools/adr-suggestion-tool.d.ts.map +1 -1
- package/dist/src/tools/adr-suggestion-tool.js +330 -32
- package/dist/src/tools/adr-suggestion-tool.js.map +1 -1
- package/dist/src/tools/content-masking-tool.d.ts +5 -0
- package/dist/src/tools/content-masking-tool.d.ts.map +1 -1
- package/dist/src/tools/content-masking-tool.js +631 -28
- package/dist/src/tools/content-masking-tool.js.map +1 -1
- package/dist/src/tools/deployment-readiness-tool.d.ts +8 -5
- package/dist/src/tools/deployment-readiness-tool.d.ts.map +1 -1
- package/dist/src/tools/deployment-readiness-tool.js +1017 -93
- package/dist/src/tools/deployment-readiness-tool.js.map +1 -1
- package/dist/src/tools/environment-analysis-tool.d.ts +4 -0
- package/dist/src/tools/environment-analysis-tool.d.ts.map +1 -1
- package/dist/src/tools/environment-analysis-tool.js +568 -24
- package/dist/src/tools/environment-analysis-tool.js.map +1 -1
- package/dist/src/tools/interactive-adr-planning-tool.d.ts.map +1 -1
- package/dist/src/tools/interactive-adr-planning-tool.js +270 -108
- package/dist/src/tools/interactive-adr-planning-tool.js.map +1 -1
- package/dist/src/tools/mcp-planning-tool.d.ts.map +1 -1
- package/dist/src/tools/mcp-planning-tool.js +316 -183
- package/dist/src/tools/mcp-planning-tool.js.map +1 -1
- package/dist/src/tools/memory-loading-tool.d.ts +60 -0
- package/dist/src/tools/memory-loading-tool.d.ts.map +1 -0
- package/dist/src/tools/memory-loading-tool.js +457 -0
- package/dist/src/tools/memory-loading-tool.js.map +1 -0
- package/dist/src/tools/research-integration-tool.d.ts +4 -1
- package/dist/src/tools/research-integration-tool.d.ts.map +1 -1
- package/dist/src/tools/research-integration-tool.js +5 -1
- package/dist/src/tools/research-integration-tool.js.map +1 -1
- package/dist/src/tools/review-existing-adrs-tool.d.ts +19 -0
- package/dist/src/tools/review-existing-adrs-tool.d.ts.map +1 -0
- package/dist/src/tools/review-existing-adrs-tool.js +1204 -0
- package/dist/src/tools/review-existing-adrs-tool.js.map +1 -0
- package/dist/src/tools/rule-generation-tool.d.ts +2 -0
- package/dist/src/tools/rule-generation-tool.d.ts.map +1 -1
- package/dist/src/tools/rule-generation-tool.js +274 -33
- package/dist/src/tools/rule-generation-tool.js.map +1 -1
- package/dist/src/tools/smart-git-push-tool-v2.d.ts +4 -0
- package/dist/src/tools/smart-git-push-tool-v2.d.ts.map +1 -1
- package/dist/src/tools/smart-git-push-tool-v2.js +423 -229
- package/dist/src/tools/smart-git-push-tool-v2.js.map +1 -1
- package/dist/src/tools/smart-git-push-tool.d.ts +3 -0
- package/dist/src/tools/smart-git-push-tool.d.ts.map +1 -1
- package/dist/src/tools/smart-git-push-tool.js +241 -235
- package/dist/src/tools/smart-git-push-tool.js.map +1 -1
- package/dist/src/tools/tool-chain-orchestrator.d.ts +2 -2
- package/dist/src/tools/tool-chain-orchestrator.d.ts.map +1 -1
- package/dist/src/tools/tool-chain-orchestrator.js +152 -93
- package/dist/src/tools/tool-chain-orchestrator.js.map +1 -1
- package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts +22 -13
- package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts.map +1 -1
- package/dist/src/tools/troubleshoot-guided-workflow-tool.js +660 -28
- package/dist/src/tools/troubleshoot-guided-workflow-tool.js.map +1 -1
- package/dist/src/types/ape-framework.d.ts +93 -0
- package/dist/src/types/ape-framework.d.ts.map +1 -1
- package/dist/src/types/ape-framework.js +10 -10
- package/dist/src/types/ape-framework.js.map +1 -1
- package/dist/src/types/enhanced-errors.d.ts +173 -0
- package/dist/src/types/enhanced-errors.d.ts.map +1 -0
- package/dist/src/types/enhanced-errors.js +668 -0
- package/dist/src/types/enhanced-errors.js.map +1 -0
- package/dist/src/types/index.d.ts +129 -3
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js +15 -0
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/knowledge-generation.d.ts +78 -0
- package/dist/src/types/knowledge-generation.d.ts.map +1 -1
- package/dist/src/types/knowledge-generation.js +10 -6
- package/dist/src/types/knowledge-generation.js.map +1 -1
- package/dist/src/types/knowledge-graph-schemas.d.ts +92 -0
- package/dist/src/types/knowledge-graph-schemas.d.ts.map +1 -1
- package/dist/src/types/knowledge-graph-schemas.js +45 -17
- package/dist/src/types/knowledge-graph-schemas.js.map +1 -1
- package/dist/src/types/memory-entities.d.ts +7209 -0
- package/dist/src/types/memory-entities.d.ts.map +1 -0
- package/dist/src/types/memory-entities.js +395 -0
- package/dist/src/types/memory-entities.js.map +1 -0
- package/dist/src/types/reflexion-framework.d.ts +44 -0
- package/dist/src/types/reflexion-framework.d.ts.map +1 -1
- package/dist/src/types/reflexion-framework.js +7 -7
- package/dist/src/types/reflexion-framework.js.map +1 -1
- package/dist/src/types/todo-json-schemas.d.ts +7 -653
- package/dist/src/types/todo-json-schemas.d.ts.map +1 -1
- package/dist/src/types/todo-json-schemas.js +6 -110
- package/dist/src/types/todo-json-schemas.js.map +1 -1
- package/dist/src/types/tool-arguments.d.ts +224 -0
- package/dist/src/types/tool-arguments.d.ts.map +1 -0
- package/dist/src/types/tool-arguments.js +6 -0
- package/dist/src/types/tool-arguments.js.map +1 -0
- package/dist/src/utils/actual-file-operations.d.ts.map +1 -1
- package/dist/src/utils/actual-file-operations.js +25 -9
- package/dist/src/utils/actual-file-operations.js.map +1 -1
- package/dist/src/utils/adr-discovery.d.ts +33 -1
- package/dist/src/utils/adr-discovery.d.ts.map +1 -1
- package/dist/src/utils/adr-discovery.js +14 -9
- package/dist/src/utils/adr-discovery.js.map +1 -1
- package/dist/src/utils/adr-suggestions.d.ts +72 -0
- package/dist/src/utils/adr-suggestions.d.ts.map +1 -1
- package/dist/src/utils/adr-suggestions.js +6 -0
- package/dist/src/utils/adr-suggestions.js.map +1 -1
- package/dist/src/utils/cache.d.ts.map +1 -1
- package/dist/src/utils/cache.js +22 -19
- package/dist/src/utils/cache.js.map +1 -1
- package/dist/src/utils/chain-of-thought-template.d.ts +13 -1
- package/dist/src/utils/chain-of-thought-template.d.ts.map +1 -1
- package/dist/src/utils/chain-of-thought-template.js +31 -22
- package/dist/src/utils/chain-of-thought-template.js.map +1 -1
- package/dist/src/utils/config.d.ts.map +1 -1
- package/dist/src/utils/config.js +1 -0
- package/dist/src/utils/config.js.map +1 -1
- package/dist/src/utils/directory-compat.js +1 -1
- package/dist/src/utils/directory-compat.js.map +1 -1
- package/dist/src/utils/enhanced-logging.d.ts +195 -0
- package/dist/src/utils/enhanced-logging.d.ts.map +1 -0
- package/dist/src/utils/enhanced-logging.js +449 -0
- package/dist/src/utils/enhanced-logging.js.map +1 -0
- package/dist/src/utils/file-system.d.ts +182 -34
- package/dist/src/utils/file-system.d.ts.map +1 -1
- package/dist/src/utils/file-system.js +648 -774
- package/dist/src/utils/file-system.js.map +1 -1
- package/dist/src/utils/gitleaks-detector.d.ts +50 -0
- package/dist/src/utils/gitleaks-detector.d.ts.map +1 -0
- package/dist/src/utils/gitleaks-detector.js +334 -0
- package/dist/src/utils/gitleaks-detector.js.map +1 -0
- package/dist/src/utils/interactive-approval.d.ts +1 -1
- package/dist/src/utils/interactive-approval.d.ts.map +1 -1
- package/dist/src/utils/interactive-approval.js +22 -17
- package/dist/src/utils/interactive-approval.js.map +1 -1
- package/dist/src/utils/json-safe.d.ts.map +1 -1
- package/dist/src/utils/json-safe.js +9 -6
- package/dist/src/utils/json-safe.js.map +1 -1
- package/dist/src/utils/knowledge-graph-manager.d.ts +37 -1
- package/dist/src/utils/knowledge-graph-manager.d.ts.map +1 -1
- package/dist/src/utils/knowledge-graph-manager.js +315 -70
- package/dist/src/utils/knowledge-graph-manager.js.map +1 -1
- package/dist/src/utils/location-filter.d.ts +35 -10
- package/dist/src/utils/location-filter.d.ts.map +1 -1
- package/dist/src/utils/location-filter.js +360 -94
- package/dist/src/utils/location-filter.js.map +1 -1
- package/dist/src/utils/mcp-response-validator.d.ts.map +1 -1
- package/dist/src/utils/mcp-response-validator.js +34 -19
- package/dist/src/utils/mcp-response-validator.js.map +1 -1
- package/dist/src/utils/memory-entity-manager.d.ts +134 -0
- package/dist/src/utils/memory-entity-manager.d.ts.map +1 -0
- package/dist/src/utils/memory-entity-manager.js +851 -0
- package/dist/src/utils/memory-entity-manager.js.map +1 -0
- package/dist/src/utils/memory-health-scoring.d.ts +125 -0
- package/dist/src/utils/memory-health-scoring.d.ts.map +1 -0
- package/dist/src/utils/memory-health-scoring.js +277 -0
- package/dist/src/utils/memory-health-scoring.js.map +1 -0
- package/dist/src/utils/memory-migration-manager.d.ts +93 -0
- package/dist/src/utils/memory-migration-manager.d.ts.map +1 -0
- package/dist/src/utils/memory-migration-manager.js +842 -0
- package/dist/src/utils/memory-migration-manager.js.map +1 -0
- package/dist/src/utils/memory-relationship-mapper.d.ts +87 -0
- package/dist/src/utils/memory-relationship-mapper.d.ts.map +1 -0
- package/dist/src/utils/memory-relationship-mapper.js +482 -0
- package/dist/src/utils/memory-relationship-mapper.js.map +1 -0
- package/dist/src/utils/memory-rollback-manager.d.ts +105 -0
- package/dist/src/utils/memory-rollback-manager.d.ts.map +1 -0
- package/dist/src/utils/memory-rollback-manager.js +575 -0
- package/dist/src/utils/memory-rollback-manager.js.map +1 -0
- package/dist/src/utils/memory-transformation.d.ts +59 -0
- package/dist/src/utils/memory-transformation.d.ts.map +1 -0
- package/dist/src/utils/memory-transformation.js +742 -0
- package/dist/src/utils/memory-transformation.js.map +1 -0
- package/dist/src/utils/output-masking.d.ts +12 -0
- package/dist/src/utils/output-masking.d.ts.map +1 -1
- package/dist/src/utils/output-masking.js +5 -0
- package/dist/src/utils/output-masking.js.map +1 -1
- package/dist/src/utils/prompt-execution.d.ts.map +1 -1
- package/dist/src/utils/prompt-execution.js +72 -51
- package/dist/src/utils/prompt-execution.js.map +1 -1
- package/dist/src/utils/release-readiness-detector.d.ts.map +1 -1
- package/dist/src/utils/release-readiness-detector.js +43 -42
- package/dist/src/utils/release-readiness-detector.js.map +1 -1
- package/dist/src/utils/research-integration.d.ts.map +1 -1
- package/dist/src/utils/research-integration.js +73 -44
- package/dist/src/utils/research-integration.js.map +1 -1
- package/dist/src/utils/research-questions.d.ts.map +1 -1
- package/dist/src/utils/research-questions.js +40 -14
- package/dist/src/utils/research-questions.js.map +1 -1
- package/dist/src/utils/ripgrep-wrapper.d.ts +84 -0
- package/dist/src/utils/ripgrep-wrapper.d.ts.map +1 -0
- package/dist/src/utils/ripgrep-wrapper.js +255 -0
- package/dist/src/utils/ripgrep-wrapper.js.map +1 -0
- package/dist/src/utils/rule-generation.d.ts.map +1 -1
- package/dist/src/utils/rule-generation.js +26 -15
- package/dist/src/utils/rule-generation.js.map +1 -1
- package/dist/src/utils/todo-file-watcher.d.ts +11 -23
- package/dist/src/utils/todo-file-watcher.d.ts.map +1 -1
- package/dist/src/utils/todo-file-watcher.js +18 -156
- package/dist/src/utils/todo-file-watcher.js.map +1 -1
- package/dist/src/utils/tree-sitter-analyzer.d.ts +185 -0
- package/dist/src/utils/tree-sitter-analyzer.d.ts.map +1 -0
- package/dist/src/utils/tree-sitter-analyzer.js +885 -0
- package/dist/src/utils/tree-sitter-analyzer.js.map +1 -0
- package/package.json +51 -10
- package/dist/src/tools/smart-score-tool.d.ts +0 -173
- package/dist/src/tools/smart-score-tool.d.ts.map +0 -1
- package/dist/src/tools/smart-score-tool.js +0 -681
- package/dist/src/tools/smart-score-tool.js.map +0 -1
- package/dist/src/tools/todo-management-tool-v2.d.ts +0 -368
- package/dist/src/tools/todo-management-tool-v2.d.ts.map +0 -1
- package/dist/src/tools/todo-management-tool-v2.js +0 -922
- package/dist/src/tools/todo-management-tool-v2.js.map +0 -1
- package/dist/src/utils/enhanced-sensitive-detector.d.ts +0 -61
- package/dist/src/utils/enhanced-sensitive-detector.d.ts.map +0 -1
- package/dist/src/utils/enhanced-sensitive-detector.js +0 -437
- package/dist/src/utils/enhanced-sensitive-detector.js.map +0 -1
- package/dist/src/utils/project-health-scoring.d.ts +0 -177
- package/dist/src/utils/project-health-scoring.d.ts.map +0 -1
- package/dist/src/utils/project-health-scoring.js +0 -370
- package/dist/src/utils/project-health-scoring.js.map +0 -1
- package/dist/src/utils/todo-json-manager.d.ts +0 -71
- package/dist/src/utils/todo-json-manager.d.ts.map +0 -1
- package/dist/src/utils/todo-json-manager.js +0 -396
- package/dist/src/utils/todo-json-manager.js.map +0 -1
- package/dist/src/utils/todo-markdown-converter.d.ts +0 -16
- package/dist/src/utils/todo-markdown-converter.d.ts.map +0 -1
- package/dist/src/utils/todo-markdown-converter.js +0 -362
- package/dist/src/utils/todo-markdown-converter.js.map +0 -1
- package/dist/src/utils/todo-migration.d.ts +0 -47
- package/dist/src/utils/todo-migration.d.ts.map +0 -1
- package/dist/src/utils/todo-migration.js +0 -261
- package/dist/src/utils/todo-migration.js.map +0 -1
|
@@ -21,9 +21,10 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import { z } from 'zod';
|
|
23
23
|
import { promises as fs } from 'fs';
|
|
24
|
-
import { join } from 'path';
|
|
24
|
+
import { join, basename } from 'path';
|
|
25
|
+
import * as os from 'os';
|
|
25
26
|
import { McpAdrError } from '../types/index.js';
|
|
26
|
-
|
|
27
|
+
// TodoJsonManager removed - use mcp-shrimp-task-manager for task management
|
|
27
28
|
// Project phase schema
|
|
28
29
|
const ProjectPhaseSchema = z.object({
|
|
29
30
|
id: z.string(),
|
|
@@ -42,13 +43,15 @@ const ProjectPhaseSchema = z.object({
|
|
|
42
43
|
completion: z.number().min(0).max(100).default(0),
|
|
43
44
|
riskLevel: z.enum(['low', 'medium', 'high', 'critical']).default('medium'),
|
|
44
45
|
riskFactors: z.array(z.string()).default([]),
|
|
45
|
-
resources: z
|
|
46
|
+
resources: z
|
|
47
|
+
.array(z.object({
|
|
46
48
|
role: z.string(),
|
|
47
49
|
capacity: z.string(), // e.g., "40h/week"
|
|
48
|
-
allocation: z.number().min(0).max(100) // percentage allocated to this phase
|
|
49
|
-
}))
|
|
50
|
+
allocation: z.number().min(0).max(100), // percentage allocated to this phase
|
|
51
|
+
}))
|
|
52
|
+
.default([]),
|
|
50
53
|
createdAt: z.string(),
|
|
51
|
-
updatedAt: z.string()
|
|
54
|
+
updatedAt: z.string(),
|
|
52
55
|
});
|
|
53
56
|
// Team member schema
|
|
54
57
|
const TeamMemberSchema = z.object({
|
|
@@ -58,11 +61,13 @@ const TeamMemberSchema = z.object({
|
|
|
58
61
|
skills: z.array(z.string()).default([]),
|
|
59
62
|
capacity: z.string(), // e.g., "40h/week"
|
|
60
63
|
currentWorkload: z.number().min(0).max(100).default(0), // percentage utilization
|
|
61
|
-
availability: z
|
|
64
|
+
availability: z
|
|
65
|
+
.object({
|
|
62
66
|
startDate: z.string().optional(),
|
|
63
67
|
endDate: z.string().optional(),
|
|
64
|
-
unavailableDates: z.array(z.string()).default([])
|
|
65
|
-
})
|
|
68
|
+
unavailableDates: z.array(z.string()).default([]),
|
|
69
|
+
})
|
|
70
|
+
.optional(),
|
|
66
71
|
});
|
|
67
72
|
// Project schema
|
|
68
73
|
const ProjectPlanSchema = z.object({
|
|
@@ -72,37 +77,43 @@ const ProjectPlanSchema = z.object({
|
|
|
72
77
|
status: z.enum(['planning', 'active', 'completed', 'on_hold', 'cancelled']),
|
|
73
78
|
phases: z.array(ProjectPhaseSchema).default([]),
|
|
74
79
|
team: z.array(TeamMemberSchema).default([]),
|
|
75
|
-
milestones: z
|
|
80
|
+
milestones: z
|
|
81
|
+
.array(z.object({
|
|
76
82
|
id: z.string(),
|
|
77
83
|
name: z.string(),
|
|
78
84
|
description: z.string().optional(),
|
|
79
85
|
dueDate: z.string(),
|
|
80
86
|
status: z.enum(['pending', 'achieved', 'delayed', 'cancelled']),
|
|
81
87
|
criteria: z.array(z.string()).default([]),
|
|
82
|
-
linkedPhases: z.array(z.string()).default([])
|
|
83
|
-
}))
|
|
84
|
-
|
|
88
|
+
linkedPhases: z.array(z.string()).default([]),
|
|
89
|
+
}))
|
|
90
|
+
.default([]),
|
|
91
|
+
risks: z
|
|
92
|
+
.array(z.object({
|
|
85
93
|
id: z.string(),
|
|
86
94
|
description: z.string(),
|
|
87
95
|
impact: z.enum(['low', 'medium', 'high', 'critical']),
|
|
88
96
|
probability: z.enum(['low', 'medium', 'high']),
|
|
89
97
|
mitigation: z.string().optional(),
|
|
90
98
|
owner: z.string().optional(),
|
|
91
|
-
status: z.enum(['open', 'mitigated', 'closed'])
|
|
92
|
-
}))
|
|
99
|
+
status: z.enum(['open', 'mitigated', 'closed']),
|
|
100
|
+
}))
|
|
101
|
+
.default([]),
|
|
93
102
|
metadata: z.object({
|
|
94
103
|
createdAt: z.string(),
|
|
95
104
|
updatedAt: z.string(),
|
|
96
105
|
createdBy: z.string(),
|
|
97
106
|
projectPath: z.string(),
|
|
98
107
|
adrDirectory: z.string().default('docs/adrs'),
|
|
99
|
-
linkedAdrs: z.array(z.string()).default([])
|
|
108
|
+
linkedAdrs: z.array(z.string()).default([]),
|
|
100
109
|
}),
|
|
101
|
-
settings: z
|
|
110
|
+
settings: z
|
|
111
|
+
.object({
|
|
102
112
|
autoPhaseTransition: z.boolean().default(false),
|
|
103
113
|
riskAssessmentInterval: z.string().default('weekly'),
|
|
104
|
-
progressUpdateFrequency: z.string().default('daily')
|
|
105
|
-
})
|
|
114
|
+
progressUpdateFrequency: z.string().default('daily'),
|
|
115
|
+
})
|
|
116
|
+
.default({}),
|
|
106
117
|
});
|
|
107
118
|
// Operation schemas
|
|
108
119
|
const CreateProjectSchema = z.object({
|
|
@@ -110,76 +121,111 @@ const CreateProjectSchema = z.object({
|
|
|
110
121
|
projectPath: z.string().describe('Project root path'),
|
|
111
122
|
projectName: z.string().describe('Project name'),
|
|
112
123
|
description: z.string().optional().describe('Project description'),
|
|
113
|
-
phases: z
|
|
124
|
+
phases: z
|
|
125
|
+
.array(z.object({
|
|
114
126
|
name: z.string(),
|
|
115
127
|
duration: z.string(),
|
|
116
128
|
dependencies: z.array(z.string()).default([]),
|
|
117
|
-
milestones: z.array(z.string()).default([])
|
|
118
|
-
}))
|
|
119
|
-
|
|
129
|
+
milestones: z.array(z.string()).default([]),
|
|
130
|
+
}))
|
|
131
|
+
.describe('Initial project phases'),
|
|
132
|
+
team: z
|
|
133
|
+
.array(z.object({
|
|
120
134
|
name: z.string(),
|
|
121
135
|
role: z.string(),
|
|
122
136
|
skills: z.array(z.string()).default([]),
|
|
123
|
-
capacity: z.string()
|
|
124
|
-
}))
|
|
137
|
+
capacity: z.string(),
|
|
138
|
+
}))
|
|
139
|
+
.default([])
|
|
140
|
+
.describe('Team structure'),
|
|
125
141
|
importFromAdrs: z.boolean().default(true).describe('Import phases from existing ADRs'),
|
|
126
|
-
importFromTodos: z.boolean().default(true).describe('Import tasks from TODO system')
|
|
142
|
+
importFromTodos: z.boolean().default(true).describe('Import tasks from TODO system'),
|
|
127
143
|
});
|
|
128
144
|
const ManagePhasesSchema = z.object({
|
|
129
145
|
operation: z.literal('manage_phases'),
|
|
130
146
|
projectPath: z.string().describe('Project root path'),
|
|
131
|
-
action: z
|
|
147
|
+
action: z
|
|
148
|
+
.enum(['list', 'create', 'update', 'delete', 'transition'])
|
|
149
|
+
.describe('Phase management action'),
|
|
132
150
|
phaseId: z.string().optional().describe('Phase ID for update/delete/transition'),
|
|
133
|
-
phaseData: z
|
|
151
|
+
phaseData: z
|
|
152
|
+
.object({
|
|
134
153
|
name: z.string().optional(),
|
|
135
154
|
description: z.string().optional(),
|
|
136
155
|
estimatedDuration: z.string().optional(),
|
|
137
156
|
dependencies: z.array(z.string()).optional(),
|
|
138
157
|
milestones: z.array(z.string()).optional(),
|
|
139
|
-
linkedAdrs: z.array(z.string()).optional()
|
|
140
|
-
})
|
|
141
|
-
|
|
158
|
+
linkedAdrs: z.array(z.string()).optional(),
|
|
159
|
+
})
|
|
160
|
+
.optional()
|
|
161
|
+
.describe('Phase data for create/update'),
|
|
162
|
+
targetStatus: z
|
|
163
|
+
.enum(['planning', 'active', 'completed', 'blocked', 'cancelled'])
|
|
164
|
+
.optional()
|
|
165
|
+
.describe('Target status for transition'),
|
|
142
166
|
});
|
|
143
167
|
const TrackProgressSchema = z.object({
|
|
144
168
|
operation: z.literal('track_progress'),
|
|
145
169
|
projectPath: z.string().describe('Project root path'),
|
|
146
|
-
reportType: z
|
|
147
|
-
|
|
170
|
+
reportType: z
|
|
171
|
+
.enum(['summary', 'detailed', 'gantt', 'milestones', 'risks'])
|
|
172
|
+
.default('summary')
|
|
173
|
+
.describe('Type of progress report'),
|
|
174
|
+
timeframe: z
|
|
175
|
+
.enum(['current', 'weekly', 'monthly', 'quarterly'])
|
|
176
|
+
.default('current')
|
|
177
|
+
.describe('Time frame for progress tracking'),
|
|
148
178
|
includeVisuals: z.boolean().default(true).describe('Include visual progress indicators'),
|
|
149
|
-
updateTaskProgress: z.boolean().default(true).describe('Sync progress from TODO system')
|
|
179
|
+
updateTaskProgress: z.boolean().default(true).describe('Sync progress from TODO system'),
|
|
150
180
|
});
|
|
151
181
|
const ManageResourcesSchema = z.object({
|
|
152
182
|
operation: z.literal('manage_resources'),
|
|
153
183
|
projectPath: z.string().describe('Project root path'),
|
|
154
|
-
action: z
|
|
184
|
+
action: z
|
|
185
|
+
.enum(['list', 'add', 'update', 'remove', 'allocate', 'optimize'])
|
|
186
|
+
.describe('Resource management action'),
|
|
155
187
|
memberId: z.string().optional().describe('Team member ID for individual actions'),
|
|
156
|
-
memberData: z
|
|
188
|
+
memberData: z
|
|
189
|
+
.object({
|
|
157
190
|
name: z.string().optional(),
|
|
158
191
|
role: z.string().optional(),
|
|
159
192
|
skills: z.array(z.string()).optional(),
|
|
160
|
-
capacity: z.string().optional()
|
|
161
|
-
})
|
|
162
|
-
|
|
193
|
+
capacity: z.string().optional(),
|
|
194
|
+
})
|
|
195
|
+
.optional()
|
|
196
|
+
.describe('Team member data'),
|
|
197
|
+
allocationData: z
|
|
198
|
+
.object({
|
|
163
199
|
phaseId: z.string(),
|
|
164
|
-
allocation: z.number().min(0).max(100)
|
|
165
|
-
})
|
|
200
|
+
allocation: z.number().min(0).max(100),
|
|
201
|
+
})
|
|
202
|
+
.optional()
|
|
203
|
+
.describe('Resource allocation data'),
|
|
166
204
|
});
|
|
167
205
|
const RiskAnalysisSchema = z.object({
|
|
168
206
|
operation: z.literal('risk_analysis'),
|
|
169
207
|
projectPath: z.string().describe('Project root path'),
|
|
170
|
-
analysisType: z
|
|
208
|
+
analysisType: z
|
|
209
|
+
.enum(['automated', 'manual', 'comprehensive'])
|
|
210
|
+
.default('comprehensive')
|
|
211
|
+
.describe('Type of risk analysis'),
|
|
171
212
|
includeAdrRisks: z.boolean().default(true).describe('Analyze risks from ADR complexity'),
|
|
172
213
|
includeDependencyRisks: z.boolean().default(true).describe('Analyze dependency chain risks'),
|
|
173
214
|
includeResourceRisks: z.boolean().default(true).describe('Analyze resource allocation risks'),
|
|
174
|
-
generateMitigation: z.boolean().default(true).describe('Generate mitigation strategies')
|
|
215
|
+
generateMitigation: z.boolean().default(true).describe('Generate mitigation strategies'),
|
|
175
216
|
});
|
|
176
217
|
const GenerateReportsSchema = z.object({
|
|
177
218
|
operation: z.literal('generate_reports'),
|
|
178
219
|
projectPath: z.string().describe('Project root path'),
|
|
179
|
-
reportType: z
|
|
220
|
+
reportType: z
|
|
221
|
+
.enum(['executive', 'status', 'health', 'team_performance', 'milestone_tracking'])
|
|
222
|
+
.describe('Type of report to generate'),
|
|
180
223
|
format: z.enum(['markdown', 'json', 'html']).default('markdown').describe('Report output format'),
|
|
181
224
|
includeCharts: z.boolean().default(true).describe('Include progress charts and graphs'),
|
|
182
|
-
timeframe: z
|
|
225
|
+
timeframe: z
|
|
226
|
+
.enum(['week', 'month', 'quarter', 'project'])
|
|
227
|
+
.default('month')
|
|
228
|
+
.describe('Report time frame'),
|
|
183
229
|
});
|
|
184
230
|
// Main operation schema
|
|
185
231
|
const McpPlanningSchema = z.union([
|
|
@@ -188,13 +234,14 @@ const McpPlanningSchema = z.union([
|
|
|
188
234
|
TrackProgressSchema,
|
|
189
235
|
ManageResourcesSchema,
|
|
190
236
|
RiskAnalysisSchema,
|
|
191
|
-
GenerateReportsSchema
|
|
237
|
+
GenerateReportsSchema,
|
|
192
238
|
]);
|
|
193
239
|
/**
|
|
194
240
|
* Get planning cache directory
|
|
195
241
|
*/
|
|
196
242
|
function getPlanningCacheDir(projectPath) {
|
|
197
|
-
|
|
243
|
+
const projectName = basename(projectPath);
|
|
244
|
+
return join(os.tmpdir(), projectName, 'cache');
|
|
198
245
|
}
|
|
199
246
|
/**
|
|
200
247
|
* Get planning data file path
|
|
@@ -210,7 +257,7 @@ async function ensureCacheDir(projectPath) {
|
|
|
210
257
|
try {
|
|
211
258
|
await fs.mkdir(cacheDir, { recursive: true });
|
|
212
259
|
}
|
|
213
|
-
catch
|
|
260
|
+
catch {
|
|
214
261
|
// Directory might already exist, that's ok
|
|
215
262
|
}
|
|
216
263
|
}
|
|
@@ -223,7 +270,7 @@ async function loadPlanningData(projectPath) {
|
|
|
223
270
|
const data = await fs.readFile(planningPath, 'utf-8');
|
|
224
271
|
return ProjectPlanSchema.parse(JSON.parse(data));
|
|
225
272
|
}
|
|
226
|
-
catch
|
|
273
|
+
catch {
|
|
227
274
|
return null;
|
|
228
275
|
}
|
|
229
276
|
}
|
|
@@ -272,7 +319,7 @@ async function createProject(args) {
|
|
|
272
319
|
riskFactors: [],
|
|
273
320
|
resources: [],
|
|
274
321
|
createdAt: now,
|
|
275
|
-
updatedAt: now
|
|
322
|
+
updatedAt: now,
|
|
276
323
|
}));
|
|
277
324
|
// Create team members
|
|
278
325
|
const teamMembers = team.map(member => ({
|
|
@@ -281,7 +328,7 @@ async function createProject(args) {
|
|
|
281
328
|
role: member.role,
|
|
282
329
|
skills: member.skills,
|
|
283
330
|
capacity: member.capacity,
|
|
284
|
-
currentWorkload: 0
|
|
331
|
+
currentWorkload: 0,
|
|
285
332
|
}));
|
|
286
333
|
// Import from ADRs if requested
|
|
287
334
|
if (importFromAdrs) {
|
|
@@ -302,8 +349,10 @@ async function createProject(args) {
|
|
|
302
349
|
// Import from TODO system if requested
|
|
303
350
|
if (importFromTodos) {
|
|
304
351
|
try {
|
|
305
|
-
|
|
306
|
-
|
|
352
|
+
// TodoJsonManager removed - use mcp-shrimp-task-manager for task management
|
|
353
|
+
console.warn('⚠️ TodoJsonManager is deprecated and was removed in memory-centric transformation');
|
|
354
|
+
// todoManager removed - skip loading todo data
|
|
355
|
+
const todoData = null;
|
|
307
356
|
if (todoData && todoData.tasks && Object.values(todoData.tasks).length > 0) {
|
|
308
357
|
// Distribute tasks across phases based on categories or ADR links
|
|
309
358
|
const tasksArray = Object.values(todoData.tasks);
|
|
@@ -334,17 +383,18 @@ async function createProject(args) {
|
|
|
334
383
|
createdBy: 'mcp-planning-tool',
|
|
335
384
|
projectPath,
|
|
336
385
|
adrDirectory: 'docs/adrs',
|
|
337
|
-
linkedAdrs: projectPhases.flatMap(p => p.linkedAdrs)
|
|
386
|
+
linkedAdrs: projectPhases.flatMap(p => p.linkedAdrs),
|
|
338
387
|
},
|
|
339
388
|
settings: {
|
|
340
389
|
autoPhaseTransition: false,
|
|
341
390
|
riskAssessmentInterval: 'weekly',
|
|
342
|
-
progressUpdateFrequency: 'daily'
|
|
343
|
-
}
|
|
391
|
+
progressUpdateFrequency: 'daily',
|
|
392
|
+
},
|
|
344
393
|
};
|
|
345
394
|
await savePlanningData(projectPath, projectPlan);
|
|
346
395
|
return {
|
|
347
|
-
content: [
|
|
396
|
+
content: [
|
|
397
|
+
{
|
|
348
398
|
type: 'text',
|
|
349
399
|
text: `# Project Created Successfully
|
|
350
400
|
|
|
@@ -356,22 +406,26 @@ async function createProject(args) {
|
|
|
356
406
|
- **Team Members**: ${teamMembers.length}
|
|
357
407
|
|
|
358
408
|
## Project Phases
|
|
359
|
-
${projectPhases
|
|
409
|
+
${projectPhases
|
|
410
|
+
.map((phase, index) => `
|
|
360
411
|
### Phase ${index + 1}: ${phase.name}
|
|
361
412
|
- **Duration**: ${phase.estimatedDuration}
|
|
362
413
|
- **Dependencies**: ${phase.dependencies.length > 0 ? phase.dependencies.join(', ') : 'None'}
|
|
363
414
|
- **Milestones**: ${phase.milestones.length > 0 ? phase.milestones.join(', ') : 'None'}
|
|
364
415
|
- **Linked ADRs**: ${phase.linkedAdrs.length}
|
|
365
416
|
- **Tasks**: ${phase.tasks.length}
|
|
366
|
-
`)
|
|
417
|
+
`)
|
|
418
|
+
.join('')}
|
|
367
419
|
|
|
368
420
|
## Team Structure
|
|
369
|
-
${teamMembers
|
|
421
|
+
${teamMembers
|
|
422
|
+
.map(member => `
|
|
370
423
|
### ${member.name} - ${member.role}
|
|
371
424
|
- **Capacity**: ${member.capacity}
|
|
372
425
|
- **Skills**: ${member.skills.join(', ')}
|
|
373
426
|
- **Current Workload**: ${member.currentWorkload}%
|
|
374
|
-
`)
|
|
427
|
+
`)
|
|
428
|
+
.join('')}
|
|
375
429
|
|
|
376
430
|
## Next Steps
|
|
377
431
|
1. Use \`manage_phases\` to refine phase details
|
|
@@ -384,8 +438,9 @@ ${teamMembers.map(member => `
|
|
|
384
438
|
- **TODO Import**: ${importFromTodos ? `✅ Imported tasks from TODO system` : '❌ Skipped'}
|
|
385
439
|
|
|
386
440
|
Project planning data saved to: \`.mcp-adr-cache/project-planning.json\`
|
|
387
|
-
|
|
388
|
-
}
|
|
441
|
+
`,
|
|
442
|
+
},
|
|
443
|
+
],
|
|
389
444
|
};
|
|
390
445
|
}
|
|
391
446
|
/**
|
|
@@ -401,13 +456,15 @@ async function managePhases(args) {
|
|
|
401
456
|
switch (action) {
|
|
402
457
|
case 'list':
|
|
403
458
|
return {
|
|
404
|
-
content: [
|
|
459
|
+
content: [
|
|
460
|
+
{
|
|
405
461
|
type: 'text',
|
|
406
462
|
text: `# Project Phases
|
|
407
463
|
|
|
408
464
|
## ${projectPlan.name}
|
|
409
465
|
|
|
410
|
-
${projectPlan.phases
|
|
466
|
+
${projectPlan.phases
|
|
467
|
+
.map((phase, index) => `
|
|
411
468
|
### Phase ${index + 1}: ${phase.name}
|
|
412
469
|
- **Status**: ${phase.status}
|
|
413
470
|
- **Progress**: ${phase.completion}%
|
|
@@ -417,13 +474,15 @@ ${projectPlan.phases.map((phase, index) => `
|
|
|
417
474
|
- **Risk Level**: ${phase.riskLevel}
|
|
418
475
|
- **Tasks**: ${phase.tasks.length}
|
|
419
476
|
- **Linked ADRs**: ${phase.linkedAdrs.length}
|
|
420
|
-
`)
|
|
477
|
+
`)
|
|
478
|
+
.join('')}
|
|
421
479
|
|
|
422
480
|
Total phases: ${projectPlan.phases.length}
|
|
423
|
-
|
|
424
|
-
}
|
|
481
|
+
`,
|
|
482
|
+
},
|
|
483
|
+
],
|
|
425
484
|
};
|
|
426
|
-
case 'create':
|
|
485
|
+
case 'create': {
|
|
427
486
|
if (!phaseData?.name) {
|
|
428
487
|
throw new McpAdrError('Phase name is required for creation', 'INVALID_INPUT');
|
|
429
488
|
}
|
|
@@ -443,12 +502,13 @@ Total phases: ${projectPlan.phases.length}
|
|
|
443
502
|
riskFactors: [],
|
|
444
503
|
resources: [],
|
|
445
504
|
createdAt: now,
|
|
446
|
-
updatedAt: now
|
|
505
|
+
updatedAt: now,
|
|
447
506
|
};
|
|
448
507
|
projectPlan.phases.push(newPhase);
|
|
449
508
|
await savePlanningData(projectPath, projectPlan);
|
|
450
509
|
return {
|
|
451
|
-
content: [
|
|
510
|
+
content: [
|
|
511
|
+
{
|
|
452
512
|
type: 'text',
|
|
453
513
|
text: `# Phase Created
|
|
454
514
|
|
|
@@ -460,10 +520,12 @@ Total phases: ${projectPlan.phases.length}
|
|
|
460
520
|
- **Dependencies**: ${newPhase.dependencies.join(', ') || 'None'}
|
|
461
521
|
|
|
462
522
|
Use \`manage_resources\` to allocate team members to this phase.
|
|
463
|
-
|
|
464
|
-
}
|
|
523
|
+
`,
|
|
524
|
+
},
|
|
525
|
+
],
|
|
465
526
|
};
|
|
466
|
-
|
|
527
|
+
}
|
|
528
|
+
case 'update': {
|
|
467
529
|
if (!phaseId) {
|
|
468
530
|
throw new McpAdrError('Phase ID is required for update', 'INVALID_INPUT');
|
|
469
531
|
}
|
|
@@ -478,22 +540,25 @@ Use \`manage_resources\` to allocate team members to this phase.
|
|
|
478
540
|
if (phaseData) {
|
|
479
541
|
Object.assign(phase, {
|
|
480
542
|
...phaseData,
|
|
481
|
-
updatedAt: now
|
|
543
|
+
updatedAt: now,
|
|
482
544
|
});
|
|
483
545
|
}
|
|
484
546
|
await savePlanningData(projectPath, projectPlan);
|
|
485
547
|
return {
|
|
486
|
-
content: [
|
|
548
|
+
content: [
|
|
549
|
+
{
|
|
487
550
|
type: 'text',
|
|
488
551
|
text: `# Phase Updated
|
|
489
552
|
|
|
490
553
|
**${phase.name}** has been updated successfully.
|
|
491
554
|
|
|
492
555
|
Updated fields: ${Object.keys(phaseData || {}).join(', ')}
|
|
493
|
-
|
|
494
|
-
}
|
|
556
|
+
`,
|
|
557
|
+
},
|
|
558
|
+
],
|
|
495
559
|
};
|
|
496
|
-
|
|
560
|
+
}
|
|
561
|
+
case 'transition': {
|
|
497
562
|
if (!phaseId || !targetStatus) {
|
|
498
563
|
throw new McpAdrError('Phase ID and target status are required for transition', 'INVALID_INPUT');
|
|
499
564
|
}
|
|
@@ -517,17 +582,20 @@ Updated fields: ${Object.keys(phaseData || {}).join(', ')}
|
|
|
517
582
|
}
|
|
518
583
|
await savePlanningData(projectPath, projectPlan);
|
|
519
584
|
return {
|
|
520
|
-
content: [
|
|
585
|
+
content: [
|
|
586
|
+
{
|
|
521
587
|
type: 'text',
|
|
522
588
|
text: `# Phase Transition Complete
|
|
523
589
|
|
|
524
590
|
**${transitionPhase.name}** status changed from **${oldStatus}** to **${targetStatus}**.
|
|
525
591
|
|
|
526
592
|
Current completion: ${transitionPhase.completion}%
|
|
527
|
-
|
|
528
|
-
}
|
|
593
|
+
`,
|
|
594
|
+
},
|
|
595
|
+
],
|
|
529
596
|
};
|
|
530
|
-
|
|
597
|
+
}
|
|
598
|
+
case 'delete': {
|
|
531
599
|
if (!phaseId) {
|
|
532
600
|
throw new McpAdrError('Phase ID is required for deletion', 'INVALID_INPUT');
|
|
533
601
|
}
|
|
@@ -541,16 +609,19 @@ Current completion: ${transitionPhase.completion}%
|
|
|
541
609
|
}
|
|
542
610
|
await savePlanningData(projectPath, projectPlan);
|
|
543
611
|
return {
|
|
544
|
-
content: [
|
|
612
|
+
content: [
|
|
613
|
+
{
|
|
545
614
|
type: 'text',
|
|
546
615
|
text: `# Phase Deleted
|
|
547
616
|
|
|
548
617
|
**${deletedPhase.name}** has been removed from the project.
|
|
549
618
|
|
|
550
619
|
Remaining phases: ${projectPlan.phases.length}
|
|
551
|
-
|
|
552
|
-
}
|
|
620
|
+
`,
|
|
621
|
+
},
|
|
622
|
+
],
|
|
553
623
|
};
|
|
624
|
+
}
|
|
554
625
|
default:
|
|
555
626
|
throw new McpAdrError(`Unknown phase action: ${action}`, 'INVALID_INPUT');
|
|
556
627
|
}
|
|
@@ -567,8 +638,10 @@ async function trackProgress(args) {
|
|
|
567
638
|
// Update task progress from TODO system if requested
|
|
568
639
|
if (updateTaskProgress) {
|
|
569
640
|
try {
|
|
570
|
-
|
|
571
|
-
|
|
641
|
+
// TodoJsonManager removed - use mcp-shrimp-task-manager for task management
|
|
642
|
+
console.warn('⚠️ TodoJsonManager is deprecated and was removed in memory-centric transformation');
|
|
643
|
+
// todoManager removed - skip loading todo data
|
|
644
|
+
const todoData = null;
|
|
572
645
|
if (todoData && todoData.tasks) {
|
|
573
646
|
const tasksArray = Object.values(todoData.tasks);
|
|
574
647
|
for (const phase of projectPlan.phases) {
|
|
@@ -590,11 +663,14 @@ async function trackProgress(args) {
|
|
|
590
663
|
const completedPhases = projectPlan.phases.filter(p => p.status === 'completed').length;
|
|
591
664
|
const activePhases = projectPlan.phases.filter(p => p.status === 'active').length;
|
|
592
665
|
const blockedPhases = projectPlan.phases.filter(p => p.status === 'blocked').length;
|
|
593
|
-
const overallProgress = totalPhases > 0
|
|
666
|
+
const overallProgress = totalPhases > 0
|
|
667
|
+
? Math.round(projectPlan.phases.reduce((sum, phase) => sum + phase.completion, 0) / totalPhases)
|
|
668
|
+
: 0;
|
|
594
669
|
switch (reportType) {
|
|
595
670
|
case 'summary':
|
|
596
671
|
return {
|
|
597
|
-
content: [
|
|
672
|
+
content: [
|
|
673
|
+
{
|
|
598
674
|
type: 'text',
|
|
599
675
|
text: `# Project Progress Summary
|
|
600
676
|
|
|
@@ -609,28 +685,38 @@ async function trackProgress(args) {
|
|
|
609
685
|
- **Blocked**: ${blockedPhases}
|
|
610
686
|
|
|
611
687
|
### Phase Progress
|
|
612
|
-
${projectPlan.phases
|
|
688
|
+
${projectPlan.phases
|
|
689
|
+
.map(phase => `
|
|
613
690
|
#### ${phase.name}
|
|
614
691
|
- **Status**: ${phase.status}
|
|
615
692
|
- **Progress**: ${phase.completion}% ${includeVisuals ? getProgressBar(phase.completion) : ''}
|
|
616
693
|
- **Tasks**: ${phase.tasks.length}
|
|
617
694
|
- **Blockers**: ${phase.blockers.length}
|
|
618
|
-
`)
|
|
695
|
+
`)
|
|
696
|
+
.join('')}
|
|
619
697
|
|
|
620
698
|
### Current Focus
|
|
621
|
-
${activePhases > 0
|
|
622
|
-
`Currently working on ${activePhases} phase(s):\n${projectPlan.phases
|
|
623
|
-
|
|
699
|
+
${activePhases > 0
|
|
700
|
+
? `Currently working on ${activePhases} phase(s):\n${projectPlan.phases
|
|
701
|
+
.filter(p => p.status === 'active')
|
|
702
|
+
.map(p => `- ${p.name}`)
|
|
703
|
+
.join('\n')}`
|
|
704
|
+
: 'No active phases'}
|
|
624
705
|
|
|
625
|
-
${blockedPhases > 0
|
|
626
|
-
`\n⚠️ **Blocked Phases**: ${projectPlan.phases
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
706
|
+
${blockedPhases > 0
|
|
707
|
+
? `\n⚠️ **Blocked Phases**: ${projectPlan.phases
|
|
708
|
+
.filter(p => p.status === 'blocked')
|
|
709
|
+
.map(p => p.name)
|
|
710
|
+
.join(', ')}`
|
|
711
|
+
: ''}
|
|
712
|
+
`,
|
|
713
|
+
},
|
|
714
|
+
],
|
|
630
715
|
};
|
|
631
716
|
case 'detailed':
|
|
632
717
|
return {
|
|
633
|
-
content: [
|
|
718
|
+
content: [
|
|
719
|
+
{
|
|
634
720
|
type: 'text',
|
|
635
721
|
text: `# Detailed Progress Report
|
|
636
722
|
|
|
@@ -642,7 +728,8 @@ ${blockedPhases > 0 ?
|
|
|
642
728
|
- **Risk Level**: ${calculateProjectRisk(projectPlan)}
|
|
643
729
|
- **Timeline Status**: ${calculateTimelineStatus(projectPlan)}
|
|
644
730
|
|
|
645
|
-
${projectPlan.phases
|
|
731
|
+
${projectPlan.phases
|
|
732
|
+
.map(phase => `
|
|
646
733
|
### ${phase.name}
|
|
647
734
|
- **Status**: ${phase.status}
|
|
648
735
|
- **Progress**: ${phase.completion}% ${includeVisuals ? getProgressBar(phase.completion) : ''}
|
|
@@ -655,45 +742,55 @@ ${projectPlan.phases.map(phase => `
|
|
|
655
742
|
- **Resources**: ${phase.resources.length} team members allocated
|
|
656
743
|
|
|
657
744
|
${phase.riskFactors.length > 0 ? `**Risk Factors**:\n${phase.riskFactors.map(r => `- ${r}`).join('\n')}` : ''}
|
|
658
|
-
`)
|
|
659
|
-
|
|
660
|
-
|
|
745
|
+
`)
|
|
746
|
+
.join('')}
|
|
747
|
+
`,
|
|
748
|
+
},
|
|
749
|
+
],
|
|
661
750
|
};
|
|
662
751
|
case 'milestones':
|
|
663
752
|
return {
|
|
664
|
-
content: [
|
|
753
|
+
content: [
|
|
754
|
+
{
|
|
665
755
|
type: 'text',
|
|
666
756
|
text: `# Milestone Tracking
|
|
667
757
|
|
|
668
758
|
## ${projectPlan.name}
|
|
669
759
|
|
|
670
760
|
### Project Milestones
|
|
671
|
-
${projectPlan.milestones.length > 0
|
|
672
|
-
projectPlan.milestones
|
|
761
|
+
${projectPlan.milestones.length > 0
|
|
762
|
+
? projectPlan.milestones
|
|
763
|
+
.map(milestone => `
|
|
673
764
|
#### ${milestone.name}
|
|
674
765
|
- **Status**: ${milestone.status}
|
|
675
766
|
- **Due Date**: ${milestone.dueDate}
|
|
676
767
|
- **Linked Phases**: ${milestone.linkedPhases.join(', ') || 'None'}
|
|
677
768
|
- **Criteria**: ${milestone.criteria.join(', ') || 'None'}
|
|
678
|
-
`)
|
|
679
|
-
|
|
769
|
+
`)
|
|
770
|
+
.join('')
|
|
771
|
+
: 'No project milestones defined'}
|
|
680
772
|
|
|
681
773
|
### Phase Milestones
|
|
682
|
-
${projectPlan.phases
|
|
774
|
+
${projectPlan.phases
|
|
775
|
+
.map(phase => `
|
|
683
776
|
#### ${phase.name}
|
|
684
|
-
${phase.milestones.length > 0
|
|
685
|
-
phase.milestones.map(m => `- ${m}`).join('\n')
|
|
686
|
-
'- No milestones defined'}
|
|
687
|
-
`)
|
|
688
|
-
|
|
689
|
-
|
|
777
|
+
${phase.milestones.length > 0
|
|
778
|
+
? phase.milestones.map(m => `- ${m}`).join('\n')
|
|
779
|
+
: '- No milestones defined'}
|
|
780
|
+
`)
|
|
781
|
+
.join('')}
|
|
782
|
+
`,
|
|
783
|
+
},
|
|
784
|
+
],
|
|
690
785
|
};
|
|
691
786
|
default:
|
|
692
787
|
return {
|
|
693
|
-
content: [
|
|
788
|
+
content: [
|
|
789
|
+
{
|
|
694
790
|
type: 'text',
|
|
695
|
-
text: `Progress tracking for report type "${reportType}" is not yet implemented
|
|
696
|
-
}
|
|
791
|
+
text: `Progress tracking for report type "${reportType}" is not yet implemented.`,
|
|
792
|
+
},
|
|
793
|
+
],
|
|
697
794
|
};
|
|
698
795
|
}
|
|
699
796
|
}
|
|
@@ -709,34 +806,42 @@ async function manageResources(args) {
|
|
|
709
806
|
switch (action) {
|
|
710
807
|
case 'list':
|
|
711
808
|
return {
|
|
712
|
-
content: [
|
|
809
|
+
content: [
|
|
810
|
+
{
|
|
713
811
|
type: 'text',
|
|
714
812
|
text: `# Team Resources
|
|
715
813
|
|
|
716
814
|
## ${projectPlan.name}
|
|
717
815
|
|
|
718
816
|
### Team Members
|
|
719
|
-
${projectPlan.team
|
|
817
|
+
${projectPlan.team
|
|
818
|
+
.map(member => `
|
|
720
819
|
#### ${member.name} - ${member.role}
|
|
721
820
|
- **Capacity**: ${member.capacity}
|
|
722
821
|
- **Current Workload**: ${member.currentWorkload}%
|
|
723
822
|
- **Skills**: ${member.skills.join(', ') || 'None specified'}
|
|
724
823
|
- **Availability**: ${member.availability ? 'Configured' : 'Not set'}
|
|
725
|
-
`)
|
|
824
|
+
`)
|
|
825
|
+
.join('')}
|
|
726
826
|
|
|
727
827
|
### Resource Allocation
|
|
728
|
-
${projectPlan.phases
|
|
828
|
+
${projectPlan.phases
|
|
829
|
+
.map(phase => `
|
|
729
830
|
#### ${phase.name}
|
|
730
|
-
${phase.resources.length > 0
|
|
731
|
-
phase.resources
|
|
732
|
-
|
|
733
|
-
|
|
831
|
+
${phase.resources.length > 0
|
|
832
|
+
? phase.resources
|
|
833
|
+
.map(resource => `- ${resource.role}: ${resource.allocation}% (${resource.capacity})`)
|
|
834
|
+
.join('\n')
|
|
835
|
+
: '- No resources allocated'}
|
|
836
|
+
`)
|
|
837
|
+
.join('')}
|
|
734
838
|
|
|
735
839
|
Total team members: ${projectPlan.team.length}
|
|
736
|
-
|
|
737
|
-
}
|
|
840
|
+
`,
|
|
841
|
+
},
|
|
842
|
+
],
|
|
738
843
|
};
|
|
739
|
-
case 'add':
|
|
844
|
+
case 'add': {
|
|
740
845
|
if (!memberData?.name || !memberData?.role) {
|
|
741
846
|
throw new McpAdrError('Member name and role are required', 'INVALID_INPUT');
|
|
742
847
|
}
|
|
@@ -746,12 +851,13 @@ Total team members: ${projectPlan.team.length}
|
|
|
746
851
|
role: memberData.role,
|
|
747
852
|
skills: memberData.skills || [],
|
|
748
853
|
capacity: memberData.capacity || '40h/week',
|
|
749
|
-
currentWorkload: 0
|
|
854
|
+
currentWorkload: 0,
|
|
750
855
|
};
|
|
751
856
|
projectPlan.team.push(newMember);
|
|
752
857
|
await savePlanningData(projectPath, projectPlan);
|
|
753
858
|
return {
|
|
754
|
-
content: [
|
|
859
|
+
content: [
|
|
860
|
+
{
|
|
755
861
|
type: 'text',
|
|
756
862
|
text: `# Team Member Added
|
|
757
863
|
|
|
@@ -762,15 +868,19 @@ Total team members: ${projectPlan.team.length}
|
|
|
762
868
|
- **Skills**: ${newMember.skills.join(', ') || 'None specified'}
|
|
763
869
|
|
|
764
870
|
Use \`allocate\` action to assign them to project phases.
|
|
765
|
-
|
|
766
|
-
}
|
|
871
|
+
`,
|
|
872
|
+
},
|
|
873
|
+
],
|
|
767
874
|
};
|
|
875
|
+
}
|
|
768
876
|
default:
|
|
769
877
|
return {
|
|
770
|
-
content: [
|
|
878
|
+
content: [
|
|
879
|
+
{
|
|
771
880
|
type: 'text',
|
|
772
|
-
text: `Resource management for action "${action}" is not yet implemented
|
|
773
|
-
}
|
|
881
|
+
text: `Resource management for action "${action}" is not yet implemented.`,
|
|
882
|
+
},
|
|
883
|
+
],
|
|
774
884
|
};
|
|
775
885
|
}
|
|
776
886
|
}
|
|
@@ -778,7 +888,7 @@ Use \`allocate\` action to assign them to project phases.
|
|
|
778
888
|
* Risk analysis operation
|
|
779
889
|
*/
|
|
780
890
|
async function riskAnalysis(args) {
|
|
781
|
-
const { projectPath, includeAdrRisks, includeDependencyRisks, includeResourceRisks, generateMitigation } = args;
|
|
891
|
+
const { projectPath, includeAdrRisks, includeDependencyRisks, includeResourceRisks, generateMitigation, } = args;
|
|
782
892
|
const projectPlan = await loadPlanningData(projectPath);
|
|
783
893
|
if (!projectPlan) {
|
|
784
894
|
throw new McpAdrError(`No project found at ${projectPath}. Use create_project first.`, 'PROJECT_NOT_FOUND');
|
|
@@ -792,7 +902,7 @@ async function riskAnalysis(args) {
|
|
|
792
902
|
category: 'Architecture',
|
|
793
903
|
description: `Phase "${phase.name}" has no linked ADRs - architectural decisions may be unclear`,
|
|
794
904
|
impact: 'medium',
|
|
795
|
-
probability: 'high'
|
|
905
|
+
probability: 'high',
|
|
796
906
|
};
|
|
797
907
|
if (generateMitigation) {
|
|
798
908
|
riskObj.mitigation = 'Review and create ADRs for architectural decisions in this phase';
|
|
@@ -804,10 +914,11 @@ async function riskAnalysis(args) {
|
|
|
804
914
|
category: 'Complexity',
|
|
805
915
|
description: `Phase "${phase.name}" has many ADRs (${phase.linkedAdrs.length}) - high complexity risk`,
|
|
806
916
|
impact: 'high',
|
|
807
|
-
probability: 'medium'
|
|
917
|
+
probability: 'medium',
|
|
808
918
|
};
|
|
809
919
|
if (generateMitigation) {
|
|
810
|
-
riskObj.mitigation =
|
|
920
|
+
riskObj.mitigation =
|
|
921
|
+
'Consider breaking this phase into smaller, more manageable sub-phases';
|
|
811
922
|
}
|
|
812
923
|
risks.push(riskObj);
|
|
813
924
|
}
|
|
@@ -821,10 +932,11 @@ async function riskAnalysis(args) {
|
|
|
821
932
|
category: 'Dependencies',
|
|
822
933
|
description: `Phase "${phase.name}" has multiple dependencies (${phase.dependencies.length}) - high coordination risk`,
|
|
823
934
|
impact: 'high',
|
|
824
|
-
probability: 'medium'
|
|
935
|
+
probability: 'medium',
|
|
825
936
|
};
|
|
826
937
|
if (generateMitigation) {
|
|
827
|
-
riskObj.mitigation =
|
|
938
|
+
riskObj.mitigation =
|
|
939
|
+
'Review and simplify dependencies, create detailed coordination plan';
|
|
828
940
|
}
|
|
829
941
|
risks.push(riskObj);
|
|
830
942
|
}
|
|
@@ -835,10 +947,11 @@ async function riskAnalysis(args) {
|
|
|
835
947
|
category: 'Dependencies',
|
|
836
948
|
description: `Potential circular dependency detected between "${phase.name}" and other phases`,
|
|
837
949
|
impact: 'critical',
|
|
838
|
-
probability: 'high'
|
|
950
|
+
probability: 'high',
|
|
839
951
|
};
|
|
840
952
|
if (generateMitigation) {
|
|
841
|
-
riskObj.mitigation =
|
|
953
|
+
riskObj.mitigation =
|
|
954
|
+
'Review and restructure phase dependencies to eliminate circular references';
|
|
842
955
|
}
|
|
843
956
|
risks.push(riskObj);
|
|
844
957
|
}
|
|
@@ -853,7 +966,7 @@ async function riskAnalysis(args) {
|
|
|
853
966
|
category: 'Resources',
|
|
854
967
|
description: `Team is overallocated (${avgWorkload.toFixed(1)}% average workload)`,
|
|
855
968
|
impact: 'high',
|
|
856
|
-
probability: 'high'
|
|
969
|
+
probability: 'high',
|
|
857
970
|
};
|
|
858
971
|
if (generateMitigation) {
|
|
859
972
|
riskObj.mitigation = 'Rebalance workload or consider adding team members';
|
|
@@ -865,7 +978,7 @@ async function riskAnalysis(args) {
|
|
|
865
978
|
category: 'Resources',
|
|
866
979
|
description: `Limited team size (${projectPlan.team.length} members) for ${projectPlan.phases.length} phases`,
|
|
867
980
|
impact: 'medium',
|
|
868
|
-
probability: 'medium'
|
|
981
|
+
probability: 'medium',
|
|
869
982
|
};
|
|
870
983
|
if (generateMitigation) {
|
|
871
984
|
riskObj.mitigation = 'Consider increasing team size or extending timeline';
|
|
@@ -877,7 +990,7 @@ async function riskAnalysis(args) {
|
|
|
877
990
|
const criticalRisks = risks.filter(r => r.impact === 'critical').length;
|
|
878
991
|
const highRisks = risks.filter(r => r.impact === 'high').length;
|
|
879
992
|
const mediumRisks = risks.filter(r => r.impact === 'medium').length;
|
|
880
|
-
const riskScore =
|
|
993
|
+
const riskScore = criticalRisks * 10 + highRisks * 5 + mediumRisks * 2;
|
|
881
994
|
let riskLevel = 'low';
|
|
882
995
|
if (riskScore > 20)
|
|
883
996
|
riskLevel = 'critical';
|
|
@@ -886,7 +999,8 @@ async function riskAnalysis(args) {
|
|
|
886
999
|
else if (riskScore > 5)
|
|
887
1000
|
riskLevel = 'medium';
|
|
888
1001
|
return {
|
|
889
|
-
content: [
|
|
1002
|
+
content: [
|
|
1003
|
+
{
|
|
890
1004
|
type: 'text',
|
|
891
1005
|
text: `# Risk Analysis Report
|
|
892
1006
|
|
|
@@ -902,29 +1016,32 @@ async function riskAnalysis(args) {
|
|
|
902
1016
|
|
|
903
1017
|
### Identified Risks
|
|
904
1018
|
|
|
905
|
-
${risks
|
|
1019
|
+
${risks
|
|
1020
|
+
.map((risk, index) => `
|
|
906
1021
|
#### Risk ${index + 1}: ${risk.category}
|
|
907
1022
|
- **Description**: ${risk.description}
|
|
908
1023
|
- **Impact**: ${risk.impact}
|
|
909
1024
|
- **Probability**: ${risk.probability}
|
|
910
1025
|
${risk.mitigation ? `- **Mitigation**: ${risk.mitigation}` : ''}
|
|
911
|
-
`)
|
|
1026
|
+
`)
|
|
1027
|
+
.join('')}
|
|
912
1028
|
|
|
913
1029
|
### Recommendations
|
|
914
1030
|
|
|
915
|
-
${riskLevel === 'critical'
|
|
916
|
-
'🚨 **Critical risks detected** - Immediate action required before proceeding'
|
|
917
|
-
riskLevel === 'high'
|
|
918
|
-
'⚠️ **High risks present** - Review and mitigate before major milestones'
|
|
919
|
-
'✅ **Manageable risk level** - Continue with normal monitoring'}
|
|
1031
|
+
${riskLevel === 'critical'
|
|
1032
|
+
? '🚨 **Critical risks detected** - Immediate action required before proceeding'
|
|
1033
|
+
: riskLevel === 'high'
|
|
1034
|
+
? '⚠️ **High risks present** - Review and mitigate before major milestones'
|
|
1035
|
+
: '✅ **Manageable risk level** - Continue with normal monitoring'}
|
|
920
1036
|
|
|
921
1037
|
### Next Steps
|
|
922
1038
|
1. Review and prioritize risk mitigation strategies
|
|
923
1039
|
2. Assign risk owners for high-impact items
|
|
924
1040
|
3. Schedule regular risk assessment reviews
|
|
925
1041
|
4. Update project timeline if necessary
|
|
926
|
-
|
|
927
|
-
}
|
|
1042
|
+
`,
|
|
1043
|
+
},
|
|
1044
|
+
],
|
|
928
1045
|
};
|
|
929
1046
|
}
|
|
930
1047
|
/**
|
|
@@ -937,12 +1054,13 @@ async function generateReports(args) {
|
|
|
937
1054
|
throw new McpAdrError(`No project found at ${projectPath}. Use create_project first.`, 'PROJECT_NOT_FOUND');
|
|
938
1055
|
}
|
|
939
1056
|
switch (reportType) {
|
|
940
|
-
case 'executive':
|
|
1057
|
+
case 'executive': {
|
|
941
1058
|
const overallProgress = calculateOverallProgress(projectPlan);
|
|
942
1059
|
const teamUtilization = calculateTeamUtilization(projectPlan);
|
|
943
1060
|
const riskLevel = calculateProjectRisk(projectPlan);
|
|
944
1061
|
return {
|
|
945
|
-
content: [
|
|
1062
|
+
content: [
|
|
1063
|
+
{
|
|
946
1064
|
type: 'text',
|
|
947
1065
|
text: `# Executive Summary
|
|
948
1066
|
|
|
@@ -956,11 +1074,11 @@ async function generateReports(args) {
|
|
|
956
1074
|
- **Completed Phases**: ${projectPlan.phases.filter(p => p.status === 'completed').length}
|
|
957
1075
|
|
|
958
1076
|
### Current Status
|
|
959
|
-
${projectPlan.status === 'active'
|
|
960
|
-
'🟢 Project is actively progressing'
|
|
961
|
-
projectPlan.status === 'completed'
|
|
962
|
-
'✅ Project completed successfully'
|
|
963
|
-
'🟡 Project in planning phase'}
|
|
1077
|
+
${projectPlan.status === 'active'
|
|
1078
|
+
? '🟢 Project is actively progressing'
|
|
1079
|
+
: projectPlan.status === 'completed'
|
|
1080
|
+
? '✅ Project completed successfully'
|
|
1081
|
+
: '🟡 Project in planning phase'}
|
|
964
1082
|
|
|
965
1083
|
### Key Highlights
|
|
966
1084
|
- Total phases: ${projectPlan.phases.length}
|
|
@@ -969,56 +1087,70 @@ ${projectPlan.status === 'active' ?
|
|
|
969
1087
|
- Risk level: ${riskLevel}
|
|
970
1088
|
|
|
971
1089
|
### Next Milestones
|
|
972
|
-
${projectPlan.milestones
|
|
1090
|
+
${projectPlan.milestones
|
|
1091
|
+
.filter(m => m.status === 'pending')
|
|
1092
|
+
.slice(0, 3)
|
|
1093
|
+
.map(milestone => `- ${milestone.name} (Due: ${milestone.dueDate})`)
|
|
1094
|
+
.join('\n') || 'No upcoming milestones'}
|
|
973
1095
|
|
|
974
1096
|
### Blockers & Risks
|
|
975
|
-
${projectPlan.phases.filter(p => p.blockers.length > 0).length > 0
|
|
976
|
-
`⚠️ ${projectPlan.phases.filter(p => p.blockers.length > 0).length} phases have blockers`
|
|
977
|
-
'✅ No major blockers reported'}
|
|
1097
|
+
${projectPlan.phases.filter(p => p.blockers.length > 0).length > 0
|
|
1098
|
+
? `⚠️ ${projectPlan.phases.filter(p => p.blockers.length > 0).length} phases have blockers`
|
|
1099
|
+
: '✅ No major blockers reported'}
|
|
978
1100
|
|
|
979
1101
|
*Report generated: ${new Date().toISOString()}*
|
|
980
|
-
|
|
981
|
-
}
|
|
1102
|
+
`,
|
|
1103
|
+
},
|
|
1104
|
+
],
|
|
982
1105
|
};
|
|
1106
|
+
}
|
|
983
1107
|
case 'status':
|
|
984
1108
|
return {
|
|
985
|
-
content: [
|
|
1109
|
+
content: [
|
|
1110
|
+
{
|
|
986
1111
|
type: 'text',
|
|
987
1112
|
text: `# Status Report - ${timeframe}
|
|
988
1113
|
|
|
989
1114
|
## ${projectPlan.name}
|
|
990
1115
|
|
|
991
1116
|
### Phase Status
|
|
992
|
-
${projectPlan.phases
|
|
1117
|
+
${projectPlan.phases
|
|
1118
|
+
.map(phase => `
|
|
993
1119
|
#### ${phase.name}
|
|
994
1120
|
- **Status**: ${phase.status}
|
|
995
1121
|
- **Progress**: ${phase.completion}%
|
|
996
1122
|
- **Timeline**: ${phase.estimatedDuration}
|
|
997
1123
|
- **Team**: ${phase.resources.length} members
|
|
998
1124
|
- **Blockers**: ${phase.blockers.length}
|
|
999
|
-
`)
|
|
1125
|
+
`)
|
|
1126
|
+
.join('')}
|
|
1000
1127
|
|
|
1001
1128
|
### Team Status
|
|
1002
|
-
${projectPlan.team
|
|
1129
|
+
${projectPlan.team
|
|
1130
|
+
.map(member => `
|
|
1003
1131
|
#### ${member.name}
|
|
1004
1132
|
- **Role**: ${member.role}
|
|
1005
1133
|
- **Workload**: ${member.currentWorkload}%
|
|
1006
1134
|
- **Capacity**: ${member.capacity}
|
|
1007
|
-
`)
|
|
1135
|
+
`)
|
|
1136
|
+
.join('')}
|
|
1008
1137
|
|
|
1009
1138
|
### Recent Updates
|
|
1010
1139
|
- Last updated: ${projectPlan.metadata.updatedAt}
|
|
1011
1140
|
- Total phases: ${projectPlan.phases.length}
|
|
1012
1141
|
- Active work streams: ${projectPlan.phases.filter(p => p.status === 'active').length}
|
|
1013
|
-
|
|
1014
|
-
}
|
|
1142
|
+
`,
|
|
1143
|
+
},
|
|
1144
|
+
],
|
|
1015
1145
|
};
|
|
1016
1146
|
default:
|
|
1017
1147
|
return {
|
|
1018
|
-
content: [
|
|
1148
|
+
content: [
|
|
1149
|
+
{
|
|
1019
1150
|
type: 'text',
|
|
1020
|
-
text: `Report generation for type "${reportType}" is not yet implemented
|
|
1021
|
-
}
|
|
1151
|
+
text: `Report generation for type "${reportType}" is not yet implemented.`,
|
|
1152
|
+
},
|
|
1153
|
+
],
|
|
1022
1154
|
};
|
|
1023
1155
|
}
|
|
1024
1156
|
}
|
|
@@ -1038,7 +1170,8 @@ function calculateOverallProgress(projectPlan) {
|
|
|
1038
1170
|
function calculateTeamUtilization(projectPlan) {
|
|
1039
1171
|
if (projectPlan.team.length === 0)
|
|
1040
1172
|
return 0;
|
|
1041
|
-
return Math.round(projectPlan.team.reduce((sum, member) => sum + member.currentWorkload, 0) /
|
|
1173
|
+
return Math.round(projectPlan.team.reduce((sum, member) => sum + member.currentWorkload, 0) /
|
|
1174
|
+
projectPlan.team.length);
|
|
1042
1175
|
}
|
|
1043
1176
|
function calculateProjectRisk(projectPlan) {
|
|
1044
1177
|
const blockedPhases = projectPlan.phases.filter(p => p.status === 'blocked').length;
|