sdd-mcp-server 3.5.1 → 5.0.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 +92 -683
- package/agents/architect.md +15 -93
- package/agents/implementer.md +16 -141
- package/agents/planner.md +16 -84
- package/agents/reviewer.md +16 -239
- package/agents/security-auditor.md +16 -114
- package/agents/tdd-guide.md +17 -228
- package/dist/adapters/cli/SDDToolAdapter.d.ts +14 -8
- package/dist/adapters/cli/SDDToolAdapter.js +188 -405
- package/dist/adapters/cli/SDDToolAdapter.js.map +1 -1
- package/dist/application/services/ContextCompactionService.d.ts +88 -16
- package/dist/application/services/ContextCompactionService.js +474 -187
- package/dist/application/services/ContextCompactionService.js.map +1 -1
- package/dist/application/services/ProjectService.js +3 -3
- package/dist/application/services/ProjectService.js.map +1 -1
- package/dist/application/services/SpecPathResolver.d.ts +24 -0
- package/dist/application/services/SpecPathResolver.js +70 -0
- package/dist/application/services/SpecPathResolver.js.map +1 -0
- package/dist/application/services/WorkflowEngineService.d.ts +214 -50
- package/dist/application/services/WorkflowEngineService.js +1447 -292
- package/dist/application/services/WorkflowEngineService.js.map +1 -1
- package/dist/application/services/WorkflowErrors.d.ts +16 -0
- package/dist/application/services/WorkflowErrors.js +53 -0
- package/dist/application/services/WorkflowErrors.js.map +1 -0
- package/dist/application/services/WorkflowValidationService.d.ts +25 -46
- package/dist/application/services/WorkflowValidationService.js +284 -627
- package/dist/application/services/WorkflowValidationService.js.map +1 -1
- package/dist/cli/install-skills.d.ts +3 -9
- package/dist/cli/install-skills.js +129 -174
- package/dist/cli/install-skills.js.map +1 -1
- package/dist/cli/install-target.d.ts +42 -8
- package/dist/cli/install-target.js +27 -9
- package/dist/cli/install-target.js.map +1 -1
- package/dist/cli/sdd-mcp-cli.d.ts +1 -1
- package/dist/cli/sdd-mcp-cli.js +7 -6
- package/dist/cli/sdd-mcp-cli.js.map +1 -1
- package/dist/cli/tool-support/claude-code.js +17 -34
- package/dist/cli/tool-support/claude-code.js.map +1 -1
- package/dist/cli/tool-support/codex.d.ts +0 -53
- package/dist/cli/tool-support/codex.js +10 -94
- package/dist/cli/tool-support/codex.js.map +1 -1
- package/dist/cli/tool-support/index.d.ts +3 -2
- package/dist/cli/tool-support/index.js +3 -1
- package/dist/cli/tool-support/index.js.map +1 -1
- package/dist/cli/tool-support/mcp-registration.d.ts +22 -0
- package/dist/cli/tool-support/mcp-registration.js +275 -0
- package/dist/cli/tool-support/mcp-registration.js.map +1 -0
- package/dist/cli/tool-support/omp.d.ts +5 -0
- package/dist/cli/tool-support/omp.js +47 -0
- package/dist/cli/tool-support/omp.js.map +1 -0
- package/dist/cli/tool-support/root-guidance.d.ts +2 -9
- package/dist/cli/tool-support/root-guidance.js +44 -37
- package/dist/cli/tool-support/root-guidance.js.map +1 -1
- package/dist/cli/tool-support/target-agent-renderer.d.ts +1 -0
- package/dist/cli/tool-support/target-agent-renderer.js +37 -4
- package/dist/cli/tool-support/target-agent-renderer.js.map +1 -1
- package/dist/cli/tool-support/target-installer.d.ts +9 -3
- package/dist/cli/tool-support/target-installer.js +100 -26
- package/dist/cli/tool-support/target-installer.js.map +1 -1
- package/dist/cli/utils/preserving-writer.d.ts +56 -0
- package/dist/cli/utils/preserving-writer.js +603 -10
- package/dist/cli/utils/preserving-writer.js.map +1 -1
- package/dist/domain/ports.d.ts +4 -0
- package/dist/domain/types.d.ts +52 -7
- package/dist/domain/types.js +5 -4
- package/dist/domain/types.js.map +1 -1
- package/dist/index.d.ts +13 -10
- package/dist/index.js +16 -1199
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/adapters/NodeFileSystemAdapter.d.ts +3 -0
- package/dist/infrastructure/adapters/NodeFileSystemAdapter.js +10 -0
- package/dist/infrastructure/adapters/NodeFileSystemAdapter.js.map +1 -1
- package/dist/infrastructure/mcp/CapabilityNegotiator.js +3 -3
- package/dist/infrastructure/mcp/CapabilityNegotiator.js.map +1 -1
- package/dist/infrastructure/mcp/MCPServer.js +13 -13
- package/dist/infrastructure/mcp/MCPServer.js.map +1 -1
- package/dist/infrastructure/mcp/ToolRegistry.d.ts +5 -1
- package/dist/infrastructure/mcp/ToolRegistry.js +11 -4
- package/dist/infrastructure/mcp/ToolRegistry.js.map +1 -1
- package/dist/infrastructure/mcp/sddToolDefinitions.d.ts +6 -0
- package/dist/infrastructure/mcp/sddToolDefinitions.js +110 -0
- package/dist/infrastructure/mcp/sddToolDefinitions.js.map +1 -0
- package/dist/infrastructure/schemas/project.schema.d.ts +2 -2
- package/dist/infrastructure/schemas/project.schema.js +2 -2
- package/dist/infrastructure/schemas/project.schema.js.map +1 -1
- package/dist/shared/version.d.ts +3 -0
- package/dist/shared/version.js +4 -0
- package/dist/shared/version.js.map +1 -0
- package/dist/utils/atomicWrite.d.ts +8 -35
- package/dist/utils/atomicWrite.js +24 -57
- package/dist/utils/atomicWrite.js.map +1 -1
- package/dist/utils/withFilesystemLock.d.ts +22 -0
- package/dist/utils/withFilesystemLock.js +219 -0
- package/dist/utils/withFilesystemLock.js.map +1 -0
- package/mcp-server.js +5 -2883
- package/package.json +8 -3
- package/scripts/context-usage-report.mjs +602 -0
- package/sdd-entry.js +17 -6
- package/skills/sdd-commit/REFERENCE.md +31 -0
- package/skills/sdd-commit/SKILL.md +17 -273
- package/skills/sdd-design/REFERENCE.md +51 -0
- package/skills/sdd-design/SKILL.md +25 -262
- package/skills/sdd-implement/REFERENCE.md +30 -0
- package/skills/sdd-implement/SKILL.md +27 -284
- package/skills/sdd-requirements/REFERENCE.md +39 -0
- package/skills/sdd-requirements/SKILL.md +28 -132
- package/skills/sdd-review/REFERENCE.md +26 -0
- package/skills/sdd-review/SKILL.md +17 -181
- package/skills/sdd-security-check/REFERENCE.md +19 -0
- package/skills/sdd-security-check/SKILL.md +18 -184
- package/skills/sdd-steering/REFERENCE.md +25 -0
- package/skills/sdd-steering/SKILL.md +18 -216
- package/skills/sdd-steering-custom/REFERENCE.md +27 -0
- package/skills/sdd-steering-custom/SKILL.md +19 -203
- package/skills/sdd-tasks/REFERENCE.md +25 -0
- package/skills/sdd-tasks/SKILL.md +27 -244
- package/skills/sdd-test-gen/REFERENCE.md +15 -0
- package/skills/sdd-test-gen/SKILL.md +17 -287
- package/skills/simple-task/REFERENCE.md +22 -0
- package/skills/simple-task/SKILL.md +17 -138
- package/templates/CLAUDE.md +13 -31
- package/templates/codex-AGENTS.md +7 -9
- package/rules/git-workflow.md +0 -92
- package/rules/sdd-workflow.md +0 -116
|
@@ -13,434 +13,163 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
13
13
|
};
|
|
14
14
|
import { injectable, inject } from "inversify";
|
|
15
15
|
import { TYPES } from "../../infrastructure/di/types.js";
|
|
16
|
-
import { ProjectService } from "../../application/services/ProjectService.js";
|
|
17
|
-
import { WorkflowService } from "../../application/services/WorkflowService.js";
|
|
18
16
|
import { TemplateService } from "../../application/services/TemplateService.js";
|
|
19
17
|
import { QualityService } from "../../application/services/QualityService.js";
|
|
20
18
|
import { SteeringDocumentService } from "../../application/services/SteeringDocumentService.js";
|
|
21
19
|
import { CodebaseAnalysisService } from "../../application/services/CodebaseAnalysisService.js";
|
|
22
20
|
import { RequirementsClarificationService } from "../../application/services/RequirementsClarificationService.js";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
21
|
+
import { WorkflowEngineService } from "../../application/services/WorkflowEngineService.js";
|
|
22
|
+
import { GovernanceError } from "../../application/services/WorkflowErrors.js";
|
|
25
23
|
import { ensureStaticSteeringDocuments } from "../../application/services/staticSteering.js";
|
|
24
|
+
import { SDD_TOOL_DEFINITIONS, SDD_TOOL_NAMES, } from "../../infrastructure/mcp/sddToolDefinitions.js";
|
|
25
|
+
export { SDD_TOOL_NAMES };
|
|
26
26
|
let SDDToolAdapter = class SDDToolAdapter {
|
|
27
|
-
projectService;
|
|
28
|
-
workflowService;
|
|
29
27
|
templateService;
|
|
30
28
|
qualityService;
|
|
31
29
|
steeringService;
|
|
32
30
|
codebaseAnalysisService;
|
|
33
31
|
clarificationService;
|
|
34
|
-
|
|
32
|
+
workflowEngineService;
|
|
35
33
|
logger;
|
|
36
|
-
constructor(
|
|
37
|
-
this.projectService = projectService;
|
|
38
|
-
this.workflowService = workflowService;
|
|
34
|
+
constructor(templateService, qualityService, steeringService, codebaseAnalysisService, clarificationService, workflowEngineService, logger) {
|
|
39
35
|
this.templateService = templateService;
|
|
40
36
|
this.qualityService = qualityService;
|
|
41
37
|
this.steeringService = steeringService;
|
|
42
38
|
this.codebaseAnalysisService = codebaseAnalysisService;
|
|
43
39
|
this.clarificationService = clarificationService;
|
|
44
|
-
this.
|
|
40
|
+
this.workflowEngineService = workflowEngineService;
|
|
45
41
|
this.logger = logger;
|
|
46
42
|
}
|
|
47
43
|
getSDDTools() {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
type: "boolean",
|
|
72
|
-
description: "Enable an optional checkpoint requiring TDD test-case review before implementation",
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
required: ["projectName"],
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
handler: this.handleProjectInit.bind(this),
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
name: "sdd-status",
|
|
82
|
-
tool: {
|
|
83
|
-
name: "sdd-status",
|
|
84
|
-
description: "Get current project status and workflow phase information",
|
|
85
|
-
inputSchema: {
|
|
86
|
-
type: "object",
|
|
87
|
-
properties: {
|
|
88
|
-
projectId: { type: "string", description: "Project ID" },
|
|
89
|
-
projectPath: {
|
|
90
|
-
type: "string",
|
|
91
|
-
description: "Project path (alternative to ID)",
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
handler: this.handleProjectStatus.bind(this),
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: "sdd-requirements",
|
|
100
|
-
tool: {
|
|
101
|
-
name: "sdd-requirements",
|
|
102
|
-
description: "Generate requirements doc",
|
|
103
|
-
inputSchema: {
|
|
104
|
-
type: "object",
|
|
105
|
-
properties: {
|
|
106
|
-
projectId: { type: "string", description: "Project ID" },
|
|
107
|
-
},
|
|
108
|
-
required: ["projectId"],
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
handler: this.handleRequirements.bind(this),
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
name: "sdd-design",
|
|
115
|
-
tool: {
|
|
116
|
-
name: "sdd-design",
|
|
117
|
-
description: "Create design specifications",
|
|
118
|
-
inputSchema: {
|
|
119
|
-
type: "object",
|
|
120
|
-
properties: {
|
|
121
|
-
projectId: { type: "string", description: "Project ID" },
|
|
122
|
-
},
|
|
123
|
-
required: ["projectId"],
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
handler: this.handleDesign.bind(this),
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
name: "sdd-tasks",
|
|
130
|
-
tool: {
|
|
131
|
-
name: "sdd-tasks",
|
|
132
|
-
description: "Generate task breakdown",
|
|
133
|
-
inputSchema: {
|
|
134
|
-
type: "object",
|
|
135
|
-
properties: {
|
|
136
|
-
projectId: { type: "string", description: "Project ID" },
|
|
137
|
-
reviewTestCases: {
|
|
138
|
-
type: "boolean",
|
|
139
|
-
description: "When true, require an explicit TDD test-case review checkpoint before implementation",
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
|
-
required: ["projectId"],
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
handler: this.handleTasks.bind(this),
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
name: "sdd-review-test-cases",
|
|
149
|
-
tool: {
|
|
150
|
-
name: "sdd-review-test-cases",
|
|
151
|
-
description: "Mark the optional TDD test-case review checkpoint as reviewed",
|
|
152
|
-
inputSchema: {
|
|
153
|
-
type: "object",
|
|
154
|
-
properties: {
|
|
155
|
-
projectId: { type: "string", description: "Project ID" },
|
|
156
|
-
},
|
|
157
|
-
required: ["projectId"],
|
|
158
|
-
},
|
|
159
|
-
},
|
|
160
|
-
handler: this.handleReviewTestCases.bind(this),
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
name: "sdd-quality-check",
|
|
164
|
-
tool: {
|
|
165
|
-
name: "sdd-quality-check",
|
|
166
|
-
description: "Perform Linus-style code quality analysis",
|
|
167
|
-
inputSchema: {
|
|
168
|
-
type: "object",
|
|
169
|
-
properties: {
|
|
170
|
-
code: { type: "string", description: "Code to analyze" },
|
|
171
|
-
language: { type: "string", description: "Programming language" },
|
|
172
|
-
},
|
|
173
|
-
required: ["code"],
|
|
174
|
-
},
|
|
175
|
-
},
|
|
176
|
-
handler: this.handleQualityCheck.bind(this),
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
name: "sdd-context-load",
|
|
180
|
-
tool: {
|
|
181
|
-
name: "sdd-context-load",
|
|
182
|
-
description: "Load compact workflow handoff context by default; use mode=full only when necessary",
|
|
183
|
-
inputSchema: {
|
|
184
|
-
type: "object",
|
|
185
|
-
properties: {
|
|
186
|
-
projectId: { type: "string", description: "Project ID" },
|
|
187
|
-
mode: {
|
|
188
|
-
type: "string",
|
|
189
|
-
enum: ["compact", "standard", "full"],
|
|
190
|
-
description: "Context size mode. compact is default and uses handoff.md.",
|
|
191
|
-
},
|
|
192
|
-
},
|
|
193
|
-
required: ["projectId"],
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
handler: this.handleContextLoad.bind(this),
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
name: "sdd-steering",
|
|
200
|
-
tool: {
|
|
201
|
-
name: "sdd-steering",
|
|
202
|
-
description: "Create/update steering documents with project-specific analysis",
|
|
203
|
-
inputSchema: {
|
|
204
|
-
type: "object",
|
|
205
|
-
properties: {
|
|
206
|
-
updateMode: {
|
|
207
|
-
type: "string",
|
|
208
|
-
enum: ["create", "update"],
|
|
209
|
-
description: "Whether to create new or update existing documents",
|
|
210
|
-
},
|
|
211
|
-
},
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
handler: this.handleSteering.bind(this),
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
name: "sdd-steering-custom",
|
|
218
|
-
tool: {
|
|
219
|
-
name: "sdd-steering-custom",
|
|
220
|
-
description: "Create custom steering documents for specialized contexts",
|
|
221
|
-
inputSchema: {
|
|
222
|
-
type: "object",
|
|
223
|
-
properties: {
|
|
224
|
-
fileName: {
|
|
225
|
-
type: "string",
|
|
226
|
-
description: "Filename for the custom steering document",
|
|
227
|
-
},
|
|
228
|
-
topic: {
|
|
229
|
-
type: "string",
|
|
230
|
-
description: "Topic/purpose of the custom steering document",
|
|
231
|
-
},
|
|
232
|
-
inclusionMode: {
|
|
233
|
-
type: "string",
|
|
234
|
-
enum: ["always", "conditional", "manual"],
|
|
235
|
-
description: "How this steering document should be included",
|
|
236
|
-
},
|
|
237
|
-
filePattern: {
|
|
238
|
-
type: "string",
|
|
239
|
-
description: "File pattern for conditional inclusion",
|
|
240
|
-
},
|
|
241
|
-
},
|
|
242
|
-
required: ["fileName", "topic", "inclusionMode"],
|
|
243
|
-
},
|
|
244
|
-
},
|
|
245
|
-
handler: this.handleSteeringCustom.bind(this),
|
|
246
|
-
},
|
|
247
|
-
];
|
|
44
|
+
const handlers = {
|
|
45
|
+
"sdd-init": this.handleProjectInit.bind(this),
|
|
46
|
+
"sdd-requirements": this.handleRequirements.bind(this),
|
|
47
|
+
"sdd-design": this.handleDesign.bind(this),
|
|
48
|
+
"sdd-tasks": this.handleTasks.bind(this),
|
|
49
|
+
"sdd-implement": this.handleImplement.bind(this),
|
|
50
|
+
"sdd-status": this.handleProjectStatus.bind(this),
|
|
51
|
+
"sdd-approve": this.handleApprove.bind(this),
|
|
52
|
+
"sdd-review-test-cases": this.handleReviewTestCases.bind(this),
|
|
53
|
+
"sdd-quality-check": this.handleQualityCheck.bind(this),
|
|
54
|
+
"sdd-context-load": this.handleContextLoad.bind(this),
|
|
55
|
+
"sdd-template-render": this.handleTemplateRender.bind(this),
|
|
56
|
+
"sdd-steering": this.handleSteering.bind(this),
|
|
57
|
+
"sdd-steering-custom": this.handleSteeringCustom.bind(this),
|
|
58
|
+
"sdd-validate-design": this.handleValidateDesign.bind(this),
|
|
59
|
+
"sdd-validate-gap": this.handleValidateGap.bind(this),
|
|
60
|
+
"sdd-spec-impl": this.handleSpecImplementation.bind(this),
|
|
61
|
+
};
|
|
62
|
+
return SDD_TOOL_DEFINITIONS.map((tool) => ({
|
|
63
|
+
name: tool.name,
|
|
64
|
+
tool,
|
|
65
|
+
handler: handlers[tool.name],
|
|
66
|
+
}));
|
|
248
67
|
}
|
|
249
68
|
async handleProjectInit(args) {
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
69
|
+
const featureName = this.requireFeatureName(args.featureName);
|
|
70
|
+
const description = args.description;
|
|
71
|
+
if (typeof description !== "string") {
|
|
72
|
+
throw new Error("Invalid argument: description must be a string");
|
|
253
73
|
}
|
|
254
|
-
const
|
|
255
|
-
// FIRST PASS: Analyze description quality
|
|
74
|
+
const clarificationAnswers = args.clarificationAnswers;
|
|
256
75
|
if (!clarificationAnswers) {
|
|
257
|
-
const result = await this.clarificationService.analyzeDescription(description,
|
|
258
|
-
// If clarification needed, BLOCK and return questions
|
|
76
|
+
const result = await this.clarificationService.analyzeDescription(description, process.cwd());
|
|
259
77
|
if (result.needsClarification && result.questions) {
|
|
260
|
-
return
|
|
78
|
+
return { status: "clarification-required", featureName, questions: result.questions };
|
|
261
79
|
}
|
|
262
80
|
}
|
|
263
|
-
// SECOND PASS: Validate and synthesize enriched description
|
|
264
81
|
let enrichedDescription = description;
|
|
265
82
|
if (clarificationAnswers && typeof clarificationAnswers === "object") {
|
|
266
|
-
const result = await this.clarificationService.analyzeDescription(description,
|
|
83
|
+
const result = await this.clarificationService.analyzeDescription(description, process.cwd());
|
|
267
84
|
if (result.questions) {
|
|
268
85
|
const validation = this.clarificationService.validateAnswers(result.questions, clarificationAnswers);
|
|
269
86
|
if (!validation.valid) {
|
|
270
|
-
throw new
|
|
87
|
+
throw new GovernanceError('InvalidParams', `Missing required answers: ${validation.missingRequired.join(", ")}`);
|
|
271
88
|
}
|
|
272
|
-
|
|
273
|
-
enrichedDescription = enriched.enriched;
|
|
89
|
+
enrichedDescription = this.clarificationService.synthesizeDescription(description, result.questions, clarificationAnswers).enriched;
|
|
274
90
|
}
|
|
275
91
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
for (const q of questions) {
|
|
294
|
-
output += `**${questionNum}. ${q.question}**${q.required ? " *(required)*" : ""}\n`;
|
|
295
|
-
if (q.examples && q.examples.length > 0) {
|
|
296
|
-
output += ` Examples:\n`;
|
|
297
|
-
for (const ex of q.examples) {
|
|
298
|
-
output += ` - ${ex}\n`;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
output += ` Answer ID: \`${q.id}\`\n\n`;
|
|
302
|
-
questionNum++;
|
|
92
|
+
await this.workflowEngineService.initializeFeature({
|
|
93
|
+
projectRoot: process.cwd(),
|
|
94
|
+
featureName,
|
|
95
|
+
description: enrichedDescription,
|
|
96
|
+
language: args.language ?? "en",
|
|
97
|
+
});
|
|
98
|
+
return { status: "initialized", featureName, revision: 0 };
|
|
99
|
+
}
|
|
100
|
+
async requireFeatureProject(featureName) {
|
|
101
|
+
return this.workflowEngineService.loadProject({
|
|
102
|
+
projectRoot: process.cwd(),
|
|
103
|
+
featureName: this.requireFeatureName(featureName),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
requireFeatureName(featureName) {
|
|
107
|
+
if (typeof featureName !== "string" || featureName.length === 0) {
|
|
108
|
+
throw new Error("Invalid argument: featureName must be a non-empty string");
|
|
303
109
|
}
|
|
304
|
-
|
|
305
|
-
output +=
|
|
306
|
-
"Call sdd-init again with clarificationAnswers parameter containing your answers.\n";
|
|
307
|
-
return output;
|
|
110
|
+
return featureName;
|
|
308
111
|
}
|
|
309
112
|
async handleProjectStatus(args) {
|
|
310
|
-
const {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
project = await this.projectService.getProjectByPath(projectPath);
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
throw new Error("Either projectId or projectPath must be provided");
|
|
320
|
-
}
|
|
321
|
-
if (!project) {
|
|
322
|
-
return "Project not found";
|
|
323
|
-
}
|
|
324
|
-
const status = await this.workflowService.getWorkflowStatus(project.id);
|
|
325
|
-
if (!status) {
|
|
326
|
-
return "Unable to get workflow status";
|
|
327
|
-
}
|
|
328
|
-
let output = `Project: ${project.name}\n`;
|
|
329
|
-
output += `Current Phase: ${status.currentPhase}\n`;
|
|
330
|
-
output += `Next Phase: ${status.nextPhase ?? "Complete"}\n`;
|
|
331
|
-
output += `Can Progress: ${status.canProgress ? "Yes" : "No"}\n`;
|
|
332
|
-
const testCaseCheckpoint = project.metadata.checkpoints?.testCases;
|
|
333
|
-
if (testCaseCheckpoint?.required) {
|
|
334
|
-
output += `TDD Test Cases Reviewed: ${testCaseCheckpoint.reviewed ? "Yes" : "No"}\n`;
|
|
335
|
-
}
|
|
336
|
-
if (status.blockers && status.blockers.length > 0) {
|
|
337
|
-
output += `Blockers:\n`;
|
|
338
|
-
for (const blocker of status.blockers) {
|
|
339
|
-
output += `- ${blocker}\n`;
|
|
340
|
-
}
|
|
113
|
+
const { featureName } = args;
|
|
114
|
+
if (featureName === undefined) {
|
|
115
|
+
const features = await this.workflowEngineService.listFeatureStatuses({
|
|
116
|
+
projectRoot: process.cwd(),
|
|
117
|
+
});
|
|
118
|
+
return { features };
|
|
341
119
|
}
|
|
342
|
-
return
|
|
120
|
+
return this.workflowEngineService.getFeatureStatus({
|
|
121
|
+
projectRoot: process.cwd(),
|
|
122
|
+
featureName: this.requireFeatureName(featureName),
|
|
123
|
+
});
|
|
343
124
|
}
|
|
344
125
|
async handleRequirements(args) {
|
|
345
|
-
|
|
346
|
-
if (typeof projectId !== "string") {
|
|
347
|
-
throw new Error("Invalid argument: projectId must be a string");
|
|
348
|
-
}
|
|
349
|
-
const project = await this.projectService.getProject(projectId);
|
|
350
|
-
if (!project) {
|
|
351
|
-
throw new Error("Project not found");
|
|
352
|
-
}
|
|
353
|
-
// Check if can transition to requirements phase
|
|
354
|
-
const validation = await this.workflowService.validatePhaseTransition(projectId, WorkflowPhase.REQUIREMENTS);
|
|
355
|
-
if (!validation.canProgress) {
|
|
356
|
-
throw new Error(`Cannot generate requirements: ${validation.reason}`);
|
|
357
|
-
}
|
|
358
|
-
// Generate requirements template
|
|
359
|
-
const content = await this.templateService.generateRequirementsTemplate(project);
|
|
360
|
-
await this.templateService.writeProjectFile(project, "requirements.md", content);
|
|
361
|
-
// Update project phase and approval status
|
|
362
|
-
await this.projectService.updateProjectPhase(projectId, WorkflowPhase.REQUIREMENTS);
|
|
363
|
-
const updatedProject = await this.projectService.updateApprovalStatus(projectId, "requirements", {
|
|
364
|
-
generated: true,
|
|
365
|
-
approved: false,
|
|
366
|
-
});
|
|
367
|
-
const specContent = await this.templateService.generateSpecJson(updatedProject);
|
|
368
|
-
await this.templateService.writeProjectFile(updatedProject, "spec.json", specContent);
|
|
369
|
-
return `Requirements document generated for project "${project.name}"`;
|
|
126
|
+
return this.handlePhaseSubmission(args, "requirements");
|
|
370
127
|
}
|
|
371
128
|
async handleDesign(args) {
|
|
372
|
-
|
|
373
|
-
if (typeof projectId !== "string") {
|
|
374
|
-
throw new Error("Invalid argument: projectId must be a string");
|
|
375
|
-
}
|
|
376
|
-
const project = await this.projectService.getProject(projectId);
|
|
377
|
-
if (!project) {
|
|
378
|
-
throw new Error("Project not found");
|
|
379
|
-
}
|
|
380
|
-
// Check if can transition to design phase
|
|
381
|
-
const validation = await this.workflowService.validatePhaseTransition(projectId, WorkflowPhase.DESIGN);
|
|
382
|
-
if (!validation.canProgress) {
|
|
383
|
-
throw new Error(`Cannot generate design: ${validation.reason}`);
|
|
384
|
-
}
|
|
385
|
-
// Generate design template
|
|
386
|
-
const content = await this.templateService.generateDesignTemplate(project);
|
|
387
|
-
await this.templateService.writeProjectFile(project, "design.md", content);
|
|
388
|
-
// Update project phase and approval status
|
|
389
|
-
await this.projectService.updateProjectPhase(projectId, WorkflowPhase.DESIGN);
|
|
390
|
-
const updatedProject = await this.projectService.updateApprovalStatus(projectId, "design", {
|
|
391
|
-
generated: true,
|
|
392
|
-
approved: false,
|
|
393
|
-
});
|
|
394
|
-
const specContent = await this.templateService.generateSpecJson(updatedProject);
|
|
395
|
-
await this.templateService.writeProjectFile(updatedProject, "spec.json", specContent);
|
|
396
|
-
return `Design document generated for project "${project.name}"`;
|
|
129
|
+
return this.handlePhaseSubmission(args, "design");
|
|
397
130
|
}
|
|
398
131
|
async handleTasks(args) {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
132
|
+
return this.handlePhaseSubmission(args, "tasks");
|
|
133
|
+
}
|
|
134
|
+
async handlePhaseSubmission(args, phase) {
|
|
135
|
+
return this.workflowEngineService.submitPhaseArtifact({
|
|
136
|
+
projectRoot: process.cwd(),
|
|
137
|
+
featureName: this.requireFeatureName(args.featureName),
|
|
138
|
+
phase,
|
|
139
|
+
content: args.content,
|
|
140
|
+
expectedRevision: args.expectedRevision,
|
|
141
|
+
expectedArtifactSha256: args.expectedArtifactSha256,
|
|
142
|
+
reviewTestCases: phase === "tasks" ? args.reviewTestCases : undefined,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
async handleImplement(args) {
|
|
146
|
+
return this.workflowEngineService.beginImplementation({
|
|
147
|
+
projectRoot: process.cwd(),
|
|
148
|
+
featureName: this.requireFeatureName(args.featureName),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
async handleApprove(args) {
|
|
152
|
+
const featureName = this.requireFeatureName(args.featureName);
|
|
153
|
+
const phase = args.phase;
|
|
154
|
+
if (!["requirements", "design", "tasks"].includes(phase)) {
|
|
155
|
+
throw new Error("Invalid argument: phase must be requirements, design, or tasks");
|
|
156
|
+
}
|
|
157
|
+
return this.workflowEngineService.approve({
|
|
158
|
+
projectRoot: process.cwd(),
|
|
159
|
+
featureName,
|
|
160
|
+
phase: phase,
|
|
161
|
+
expectedRevision: args.expectedRevision,
|
|
162
|
+
expectedArtifactSha256: args.expectedArtifactSha256,
|
|
426
163
|
});
|
|
427
|
-
const specContent = await this.templateService.generateSpecJson(updatedProject);
|
|
428
|
-
await this.templateService.writeProjectFile(updatedProject, "spec.json", specContent);
|
|
429
|
-
return `Tasks document generated for project "${project.name}"`;
|
|
430
164
|
}
|
|
431
165
|
async handleReviewTestCases(args) {
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
const updatedProject = await this.projectService.updateTestCaseReviewCheckpoint(projectId, { required: true, reviewed: true });
|
|
441
|
-
const specContent = await this.templateService.generateSpecJson(updatedProject);
|
|
442
|
-
await this.templateService.writeProjectFile(updatedProject, "spec.json", specContent);
|
|
443
|
-
return `TDD test cases reviewed for project "${project.name}"`;
|
|
166
|
+
const featureName = this.requireFeatureName(args.featureName);
|
|
167
|
+
return this.workflowEngineService.reviewTestCases({
|
|
168
|
+
projectRoot: process.cwd(),
|
|
169
|
+
featureName,
|
|
170
|
+
expectedTasksRevision: args.expectedTasksRevision,
|
|
171
|
+
expectedArtifactSha256: args.expectedArtifactSha256,
|
|
172
|
+
});
|
|
444
173
|
}
|
|
445
174
|
async handleQualityCheck(args) {
|
|
446
175
|
const { code, language = "typescript" } = args;
|
|
@@ -454,19 +183,71 @@ let SDDToolAdapter = class SDDToolAdapter {
|
|
|
454
183
|
return this.qualityService.formatQualityReport(report);
|
|
455
184
|
}
|
|
456
185
|
async handleContextLoad(args) {
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
|
|
186
|
+
const featureName = this.requireFeatureName(args.featureName);
|
|
187
|
+
const { mode, phase, maxEstimatedTokens, ifNoneMatch, includeUnapproved, } = args;
|
|
188
|
+
return this.workflowEngineService.loadFeatureContext({
|
|
189
|
+
projectRoot: process.cwd(),
|
|
190
|
+
featureName,
|
|
191
|
+
mode: mode,
|
|
192
|
+
phase: phase,
|
|
193
|
+
maxEstimatedTokens: maxEstimatedTokens,
|
|
194
|
+
ifNoneMatch: ifNoneMatch,
|
|
195
|
+
includeUnapproved: includeUnapproved,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
async handleTemplateRender(args) {
|
|
199
|
+
const project = await this.requireFeatureProject(args.featureName);
|
|
200
|
+
const templateType = args.templateType;
|
|
201
|
+
if (args.customTemplate !== undefined) {
|
|
202
|
+
if (typeof args.customTemplate !== "string") {
|
|
203
|
+
throw new Error("Invalid argument: customTemplate must be a string");
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
featureName: project.name,
|
|
207
|
+
templateType,
|
|
208
|
+
content: args.customTemplate,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
let content;
|
|
212
|
+
switch (templateType) {
|
|
213
|
+
case "requirements":
|
|
214
|
+
content = await this.templateService.generateRequirementsTemplate(project);
|
|
215
|
+
break;
|
|
216
|
+
case "design":
|
|
217
|
+
content = await this.templateService.generateDesignTemplate(project);
|
|
218
|
+
break;
|
|
219
|
+
case "tasks":
|
|
220
|
+
content = await this.templateService.generateTasksTemplate(project);
|
|
221
|
+
break;
|
|
222
|
+
default:
|
|
223
|
+
throw new Error("Invalid argument: templateType must be requirements, design, or tasks");
|
|
224
|
+
}
|
|
225
|
+
return { featureName: project.name, templateType, content };
|
|
226
|
+
}
|
|
227
|
+
async handleValidateDesign(args) {
|
|
228
|
+
return this.workflowEngineService.validateDesignArtifact({
|
|
229
|
+
projectRoot: process.cwd(),
|
|
230
|
+
featureName: this.requireFeatureName(args.featureName),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
async handleValidateGap(args) {
|
|
234
|
+
const project = await this.requireFeatureProject(args.featureName);
|
|
235
|
+
return {
|
|
236
|
+
featureName: project.name,
|
|
237
|
+
analysis: await this.codebaseAnalysisService.analyzeCodebase(project.path),
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
async handleSpecImplementation(args) {
|
|
241
|
+
return this.workflowEngineService.recordTaskProgress({
|
|
242
|
+
projectRoot: process.cwd(),
|
|
243
|
+
featureName: this.requireFeatureName(args.featureName),
|
|
244
|
+
taskNumber: args.taskNumber,
|
|
245
|
+
action: args.action,
|
|
246
|
+
expectedRevision: args.expectedRevision,
|
|
247
|
+
evidence: args.evidence,
|
|
248
|
+
affectedArtifacts: args.affectedArtifacts,
|
|
249
|
+
blocker: args.blocker,
|
|
250
|
+
});
|
|
470
251
|
}
|
|
471
252
|
async handleSteering(args) {
|
|
472
253
|
const { updateMode = "update" } = args;
|
|
@@ -553,6 +334,12 @@ Choose Codex or Claude Code interactively, or pass \`--target\` explicitly in au
|
|
|
553
334
|
typeof inclusionMode !== "string") {
|
|
554
335
|
throw new Error("Invalid arguments: fileName, topic, and inclusionMode must be strings");
|
|
555
336
|
}
|
|
337
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*\.md$/.test(fileName)) {
|
|
338
|
+
throw new Error("Invalid argument: fileName must be a Markdown basename");
|
|
339
|
+
}
|
|
340
|
+
if (!["always", "conditional", "manual"].includes(inclusionMode)) {
|
|
341
|
+
throw new Error("Invalid argument: inclusionMode must be always, conditional, or manual");
|
|
342
|
+
}
|
|
556
343
|
const content = `# ${topic}
|
|
557
344
|
|
|
558
345
|
## Purpose
|
|
@@ -858,23 +645,19 @@ ${this.generateWorkflow(analysis)}`;
|
|
|
858
645
|
};
|
|
859
646
|
SDDToolAdapter = __decorate([
|
|
860
647
|
injectable(),
|
|
861
|
-
__param(0, inject(TYPES.
|
|
862
|
-
__param(1, inject(TYPES.
|
|
863
|
-
__param(2, inject(TYPES.
|
|
864
|
-
__param(3, inject(TYPES.
|
|
865
|
-
__param(4, inject(TYPES.
|
|
866
|
-
__param(5, inject(TYPES.
|
|
867
|
-
__param(6, inject(TYPES.
|
|
868
|
-
|
|
869
|
-
__param(8, inject(TYPES.LoggerPort)),
|
|
870
|
-
__metadata("design:paramtypes", [ProjectService,
|
|
871
|
-
WorkflowService,
|
|
872
|
-
TemplateService,
|
|
648
|
+
__param(0, inject(TYPES.TemplateService)),
|
|
649
|
+
__param(1, inject(TYPES.QualityService)),
|
|
650
|
+
__param(2, inject(TYPES.SteeringDocumentService)),
|
|
651
|
+
__param(3, inject(TYPES.CodebaseAnalysisService)),
|
|
652
|
+
__param(4, inject(TYPES.RequirementsClarificationService)),
|
|
653
|
+
__param(5, inject(TYPES.WorkflowEngineService)),
|
|
654
|
+
__param(6, inject(TYPES.LoggerPort)),
|
|
655
|
+
__metadata("design:paramtypes", [TemplateService,
|
|
873
656
|
QualityService,
|
|
874
657
|
SteeringDocumentService,
|
|
875
658
|
CodebaseAnalysisService,
|
|
876
659
|
RequirementsClarificationService,
|
|
877
|
-
|
|
660
|
+
WorkflowEngineService, Object])
|
|
878
661
|
], SDDToolAdapter);
|
|
879
662
|
export { SDDToolAdapter };
|
|
880
663
|
//# sourceMappingURL=SDDToolAdapter.js.map
|