sdd-mcp-server 3.3.0 → 3.5.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 +120 -54
- package/dist/adapters/cli/SDDToolAdapter.d.ts +5 -1
- package/dist/adapters/cli/SDDToolAdapter.js +111 -18
- package/dist/adapters/cli/SDDToolAdapter.js.map +1 -1
- package/dist/application/services/ContextCompactionService.d.ts +39 -0
- package/dist/application/services/ContextCompactionService.js +253 -0
- package/dist/application/services/ContextCompactionService.js.map +1 -0
- package/dist/application/services/ProjectService.d.ts +7 -1
- package/dist/application/services/ProjectService.js +56 -1
- package/dist/application/services/ProjectService.js.map +1 -1
- package/dist/application/services/TemplateService.js +27 -5
- package/dist/application/services/TemplateService.js.map +1 -1
- package/dist/application/services/WorkflowEngineService.d.ts +3 -1
- package/dist/application/services/WorkflowEngineService.js +20 -5
- package/dist/application/services/WorkflowEngineService.js.map +1 -1
- package/dist/application/services/WorkflowService.js +8 -0
- package/dist/application/services/WorkflowService.js.map +1 -1
- package/dist/application/services/staticSteering.js +12 -13
- package/dist/application/services/staticSteering.js.map +1 -1
- package/dist/cli/install-skills.d.ts +13 -31
- package/dist/cli/install-skills.js +230 -173
- package/dist/cli/install-skills.js.map +1 -1
- package/dist/cli/install-target.d.ts +127 -0
- package/dist/cli/install-target.js +127 -0
- package/dist/cli/install-target.js.map +1 -0
- package/dist/cli/migrate-steering.js +13 -13
- package/dist/cli/migrate-steering.js.map +1 -1
- package/dist/cli/sdd-mcp-cli.d.ts +1 -1
- package/dist/cli/sdd-mcp-cli.js +14 -10
- package/dist/cli/sdd-mcp-cli.js.map +1 -1
- package/dist/cli/tool-support/antigravity.d.ts +6 -1
- package/dist/cli/tool-support/antigravity.js +55 -12
- package/dist/cli/tool-support/antigravity.js.map +1 -1
- package/dist/cli/tool-support/claude-code.d.ts +5 -0
- package/dist/cli/tool-support/claude-code.js +93 -0
- package/dist/cli/tool-support/claude-code.js.map +1 -0
- package/dist/cli/tool-support/codex.d.ts +18 -1
- package/dist/cli/tool-support/codex.js +161 -36
- package/dist/cli/tool-support/codex.js.map +1 -1
- package/dist/cli/tool-support/index.d.ts +2 -2
- package/dist/cli/tool-support/root-guidance.d.ts +9 -0
- package/dist/cli/tool-support/root-guidance.js +40 -0
- package/dist/cli/tool-support/root-guidance.js.map +1 -0
- package/dist/cli/tool-support/target-agent-renderer.d.ts +11 -0
- package/dist/cli/tool-support/target-agent-renderer.js +52 -0
- package/dist/cli/tool-support/target-agent-renderer.js.map +1 -0
- package/dist/cli/tool-support/target-installer.d.ts +40 -0
- package/dist/cli/tool-support/target-installer.js +116 -0
- package/dist/cli/tool-support/target-installer.js.map +1 -0
- package/dist/cli/utils/gitignore-manager.d.ts +5 -0
- package/dist/cli/utils/gitignore-manager.js +85 -0
- package/dist/cli/utils/gitignore-manager.js.map +1 -0
- package/dist/cli/utils/preserving-writer.d.ts +13 -0
- package/dist/cli/utils/preserving-writer.js +106 -0
- package/dist/cli/utils/preserving-writer.js.map +1 -0
- package/dist/domain/services/DomainService.d.ts +1 -0
- package/dist/domain/services/DomainService.js +12 -2
- package/dist/domain/services/DomainService.js.map +1 -1
- package/dist/domain/types.d.ts +13 -0
- package/dist/domain/types.js.map +1 -1
- package/dist/domain/workflow/WorkflowStateMachine.js +7 -2
- package/dist/domain/workflow/WorkflowStateMachine.js.map +1 -1
- package/dist/hooks/HookLoader.js +9 -1
- package/dist/hooks/HookLoader.js.map +1 -1
- package/dist/index.js +347 -26
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/di/container.js +4 -0
- package/dist/infrastructure/di/container.js.map +1 -1
- package/dist/infrastructure/di/types.d.ts +1 -0
- package/dist/infrastructure/di/types.js +1 -0
- package/dist/infrastructure/di/types.js.map +1 -1
- package/dist/infrastructure/mcp/ResourceManager.js +21 -1
- package/dist/infrastructure/mcp/ResourceManager.js.map +1 -1
- package/dist/infrastructure/mcp/ToolRegistry.js +34 -2
- package/dist/infrastructure/mcp/ToolRegistry.js.map +1 -1
- package/dist/infrastructure/schemas/project.schema.d.ts +47 -4
- package/dist/infrastructure/schemas/project.schema.js +39 -2
- package/dist/infrastructure/schemas/project.schema.js.map +1 -1
- package/dist/shared/BaseManager.d.ts +10 -1
- package/dist/shared/BaseManager.js +34 -5
- package/dist/shared/BaseManager.js.map +1 -1
- package/dist/skills/SkillManager.d.ts +3 -1
- package/dist/skills/SkillManager.js +15 -3
- package/dist/skills/SkillManager.js.map +1 -1
- package/package.json +2 -2
- package/sdd-entry.js +2 -2
- package/skills/sdd-design/SKILL.md +4 -0
- package/skills/sdd-implement/SKILL.md +10 -4
- package/skills/sdd-requirements/SKILL.md +4 -0
- package/skills/sdd-review/SKILL.md +4 -0
- package/skills/sdd-security-check/SKILL.md +4 -0
- package/skills/sdd-steering/SKILL.md +4 -0
- package/skills/sdd-steering-custom/SKILL.md +4 -0
- package/skills/sdd-tasks/SKILL.md +24 -7
- package/skills/sdd-test-gen/SKILL.md +4 -0
- package/skills/simple-task/SKILL.md +4 -0
- package/templates/CLAUDE.md +2 -36
- package/templates/codex-AGENTS.md +1 -2
- package/templates/codex-hook-runner.js +85 -0
- package/dist/utils/sddPaths.d.ts +0 -69
- package/dist/utils/sddPaths.js +0 -138
- package/dist/utils/sddPaths.js.map +0 -1
package/dist/hooks/HookLoader.js
CHANGED
|
@@ -103,6 +103,7 @@ export class HookLoader extends BaseManager {
|
|
|
103
103
|
async installComponents(targetPath) {
|
|
104
104
|
const result = {
|
|
105
105
|
installed: [],
|
|
106
|
+
skipped: [],
|
|
106
107
|
failed: [],
|
|
107
108
|
};
|
|
108
109
|
try {
|
|
@@ -124,10 +125,14 @@ export class HookLoader extends BaseManager {
|
|
|
124
125
|
const fileName = path.basename(hook.path);
|
|
125
126
|
const targetFile = path.join(eventTargetPath, fileName);
|
|
126
127
|
try {
|
|
127
|
-
await fs.promises.copyFile(hook.path, targetFile);
|
|
128
|
+
await fs.promises.copyFile(hook.path, targetFile, fs.constants.COPYFILE_EXCL);
|
|
128
129
|
result.installed.push(hook.name);
|
|
129
130
|
}
|
|
130
131
|
catch (error) {
|
|
132
|
+
if (isAlreadyExists(error)) {
|
|
133
|
+
result.skipped?.push(hook.name);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
131
136
|
result.failed.push({
|
|
132
137
|
name: hook.name,
|
|
133
138
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -177,4 +182,7 @@ export class HookLoader extends BaseManager {
|
|
|
177
182
|
.sort((a, b) => b.priority - a.priority);
|
|
178
183
|
}
|
|
179
184
|
}
|
|
185
|
+
function isAlreadyExists(error) {
|
|
186
|
+
return typeof error === 'object' && error !== null && 'code' in error && error.code === 'EEXIST';
|
|
187
|
+
}
|
|
180
188
|
//# sourceMappingURL=HookLoader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HookLoader.js","sourceRoot":"","sources":["../../src/hooks/HookLoader.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"HookLoader.js","sourceRoot":"","sources":["../../src/hooks/HookLoader.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,8 @@ if (isMCPMode) {
|
|
|
20
20
|
console.error = (...args) => originalError("[SDD-DEBUG]", ...args);
|
|
21
21
|
}
|
|
22
22
|
import "reflect-metadata";
|
|
23
|
+
import { existsSync } from "fs";
|
|
24
|
+
import nodePath from "path";
|
|
23
25
|
import { createContainer } from "./infrastructure/di/container.js";
|
|
24
26
|
import { TYPES } from "./infrastructure/di/types.js";
|
|
25
27
|
export async function createMCPServer() {
|
|
@@ -98,6 +100,10 @@ async function createSimpleMCPServer() {
|
|
|
98
100
|
description: "Answers to clarification questions (second pass)",
|
|
99
101
|
additionalProperties: { type: "string" },
|
|
100
102
|
},
|
|
103
|
+
reviewTestCases: {
|
|
104
|
+
type: "boolean",
|
|
105
|
+
description: "Enable an optional TDD test-case review checkpoint before implementation",
|
|
106
|
+
},
|
|
101
107
|
},
|
|
102
108
|
required: ["projectName"],
|
|
103
109
|
},
|
|
@@ -134,6 +140,20 @@ async function createSimpleMCPServer() {
|
|
|
134
140
|
required: ["featureName", "phase"],
|
|
135
141
|
},
|
|
136
142
|
},
|
|
143
|
+
{
|
|
144
|
+
name: "sdd-review-test-cases",
|
|
145
|
+
description: "Mark optional TDD test-case review checkpoint as reviewed",
|
|
146
|
+
inputSchema: {
|
|
147
|
+
type: "object",
|
|
148
|
+
properties: {
|
|
149
|
+
featureName: {
|
|
150
|
+
type: "string",
|
|
151
|
+
description: "Feature name from spec initialization",
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
required: ["featureName"],
|
|
155
|
+
},
|
|
156
|
+
},
|
|
137
157
|
{
|
|
138
158
|
name: "sdd-quality-check",
|
|
139
159
|
description: "Code quality analysis",
|
|
@@ -162,6 +182,11 @@ async function createSimpleMCPServer() {
|
|
|
162
182
|
type: "string",
|
|
163
183
|
description: "Feature name to load context for",
|
|
164
184
|
},
|
|
185
|
+
mode: {
|
|
186
|
+
type: "string",
|
|
187
|
+
enum: ["compact", "standard", "full"],
|
|
188
|
+
description: "Context size mode. Defaults to compact handoff context.",
|
|
189
|
+
},
|
|
165
190
|
},
|
|
166
191
|
required: ["featureName"],
|
|
167
192
|
},
|
|
@@ -214,7 +239,7 @@ async function createSimpleMCPServer() {
|
|
|
214
239
|
},
|
|
215
240
|
{
|
|
216
241
|
name: "sdd-list-skills",
|
|
217
|
-
description: "List available SDD Agent Skills
|
|
242
|
+
description: "List available SDD Agent Skills for Codex or Claude Code",
|
|
218
243
|
inputSchema: {
|
|
219
244
|
type: "object",
|
|
220
245
|
properties: {},
|
|
@@ -234,15 +259,10 @@ async function createSimpleMCPServer() {
|
|
|
234
259
|
return await handleQualityCheckSimplified(args);
|
|
235
260
|
case "sdd-approve":
|
|
236
261
|
return await handleApproveSimplified(args);
|
|
262
|
+
case "sdd-review-test-cases":
|
|
263
|
+
return await handleReviewTestCasesSimplified(args);
|
|
237
264
|
case "sdd-context-load":
|
|
238
|
-
return
|
|
239
|
-
content: [
|
|
240
|
-
{
|
|
241
|
-
type: "text",
|
|
242
|
-
text: `Project context loaded for ${args.featureName}. (Simplified MCP mode)`,
|
|
243
|
-
},
|
|
244
|
-
],
|
|
245
|
-
};
|
|
265
|
+
return await handleContextLoadSimplified(args);
|
|
246
266
|
case "sdd-validate-design":
|
|
247
267
|
return {
|
|
248
268
|
content: [
|
|
@@ -316,7 +336,7 @@ No skills found in the package. Skills may not be installed correctly.
|
|
|
316
336
|
|
|
317
337
|
**Expected location**: \`${skillsPath}\`
|
|
318
338
|
|
|
319
|
-
**Installation**: Run \`npx sdd-mcp-server install
|
|
339
|
+
**Installation**: Run \`npx sdd-mcp-server install --target codex --skills\` or \`npx sdd-mcp-server install --target claude-code --skills\`.`,
|
|
320
340
|
},
|
|
321
341
|
],
|
|
322
342
|
};
|
|
@@ -330,15 +350,15 @@ No skills found in the package. Skills may not be installed correctly.
|
|
|
330
350
|
type: "text",
|
|
331
351
|
text: `## SDD Agent Skills
|
|
332
352
|
|
|
333
|
-
Available skills
|
|
353
|
+
Available skills for Codex or Claude Code:
|
|
334
354
|
|
|
335
355
|
${skillsList}
|
|
336
356
|
|
|
337
357
|
**Total**: ${skills.length} skills
|
|
338
358
|
|
|
339
|
-
**Installation**: Run \`npx sdd-mcp-server install
|
|
359
|
+
**Installation**: Run \`npx sdd-mcp-server install --target codex --skills\` or \`npx sdd-mcp-server install --target claude-code --skills\`.
|
|
340
360
|
|
|
341
|
-
After installation,
|
|
361
|
+
After installation, use these skills in the selected target agent:
|
|
342
362
|
- \`/sdd-requirements <feature-name>\`
|
|
343
363
|
- \`/sdd-design <feature-name>\`
|
|
344
364
|
- \`/sdd-tasks <feature-name>\`
|
|
@@ -433,6 +453,9 @@ async function handleStatusSimplified(args) {
|
|
|
433
453
|
status += `- Requirements: ${spec.approvals.requirements.generated ? "✅ Generated" : "❌ Not Generated"}${spec.approvals.requirements.approved ? ", ✅ Approved" : ", ❌ Not Approved"}\n`;
|
|
434
454
|
status += `- Design: ${spec.approvals.design.generated ? "✅ Generated" : "❌ Not Generated"}${spec.approvals.design.approved ? ", ✅ Approved" : ", ❌ Not Approved"}\n`;
|
|
435
455
|
status += `- Tasks: ${spec.approvals.tasks.generated ? "✅ Generated" : "❌ Not Generated"}${spec.approvals.tasks.approved ? ", ✅ Approved" : ", ❌ Not Approved"}\n\n`;
|
|
456
|
+
if (spec.checkpoints?.test_cases?.required) {
|
|
457
|
+
status += `**TDD Test Case Review**: ${spec.checkpoints.test_cases.reviewed ? "✅ Reviewed" : "❌ Pending"}\n`;
|
|
458
|
+
}
|
|
436
459
|
status += `**Ready for Implementation**: ${spec.ready_for_implementation ? "✅ Yes" : "❌ No"}\n\n`;
|
|
437
460
|
if (!spec.approvals.requirements.generated)
|
|
438
461
|
status += `**Next Step**: Run \`sdd-requirements ${featureName}\``;
|
|
@@ -440,6 +463,8 @@ async function handleStatusSimplified(args) {
|
|
|
440
463
|
status += `**Next Step**: Run \`sdd-design ${featureName}\``;
|
|
441
464
|
else if (!spec.approvals.tasks.generated)
|
|
442
465
|
status += `**Next Step**: Run \`sdd-tasks ${featureName}\``;
|
|
466
|
+
else if (spec.checkpoints?.test_cases?.required && !spec.checkpoints.test_cases.reviewed)
|
|
467
|
+
status += `**Next Step**: Review test cases, then run \`sdd-review-test-cases ${featureName}\``;
|
|
443
468
|
else
|
|
444
469
|
status += `**Next Step**: Run \`sdd-implement ${featureName}\` to begin implementation`;
|
|
445
470
|
return { content: [{ type: "text", text: status }] };
|
|
@@ -471,6 +496,9 @@ async function handleStatusSimplified(args) {
|
|
|
471
496
|
status += `- Requirements: ${spec.approvals.requirements.generated ? "✅" : "❌"}\n`;
|
|
472
497
|
status += `- Design: ${spec.approvals.design.generated ? "✅" : "❌"}\n`;
|
|
473
498
|
status += `- Tasks: ${spec.approvals.tasks.generated ? "✅" : "❌"}\n`;
|
|
499
|
+
if (spec.checkpoints?.test_cases?.required) {
|
|
500
|
+
status += `- Test cases reviewed: ${spec.checkpoints.test_cases.reviewed ? "✅" : "❌"}\n`;
|
|
501
|
+
}
|
|
474
502
|
status += `- Ready: ${spec.ready_for_implementation ? "✅" : "❌"}\n\n`;
|
|
475
503
|
}
|
|
476
504
|
}
|
|
@@ -503,14 +531,41 @@ async function handleApproveSimplified(args) {
|
|
|
503
531
|
],
|
|
504
532
|
};
|
|
505
533
|
}
|
|
534
|
+
if (phase === "tasks" &&
|
|
535
|
+
spec.checkpoints?.test_cases?.required &&
|
|
536
|
+
!spec.checkpoints.test_cases.reviewed) {
|
|
537
|
+
return {
|
|
538
|
+
content: [
|
|
539
|
+
{
|
|
540
|
+
type: "text",
|
|
541
|
+
text: `Error: TDD test cases must be reviewed before approving tasks. ` +
|
|
542
|
+
`After review, run sdd-review-test-cases ${featureName}.`,
|
|
543
|
+
},
|
|
544
|
+
],
|
|
545
|
+
isError: true,
|
|
546
|
+
};
|
|
547
|
+
}
|
|
506
548
|
spec.approvals[phase].approved = true;
|
|
507
549
|
spec.updated_at = new Date().toISOString();
|
|
550
|
+
spec.ready_for_implementation =
|
|
551
|
+
spec.approvals.requirements?.approved === true &&
|
|
552
|
+
spec.approvals.design?.approved === true &&
|
|
553
|
+
spec.approvals.tasks?.approved === true &&
|
|
554
|
+
(spec.checkpoints?.test_cases?.required !== true ||
|
|
555
|
+
spec.checkpoints.test_cases.reviewed === true);
|
|
508
556
|
fs.writeFileSync(specPath, JSON.stringify(spec, null, 2));
|
|
557
|
+
const handoff = await generateCompactHandoffSimplified(featureName, phase);
|
|
509
558
|
return {
|
|
510
559
|
content: [
|
|
511
560
|
{
|
|
512
561
|
type: "text",
|
|
513
|
-
text: `## Phase Approved\n\n
|
|
562
|
+
text: `## Phase Approved\n\n` +
|
|
563
|
+
`**Feature**: ${featureName}\n` +
|
|
564
|
+
`**Phase**: ${phase}\n` +
|
|
565
|
+
`**Status**: ✅ Approved\n` +
|
|
566
|
+
`**Context Handoff**: ${handoff.relativePath}\n` +
|
|
567
|
+
`**Estimated Context Reduction**: ${handoff.reductionPercentage}% ` +
|
|
568
|
+
`(~${handoff.sourceTokens} → ~${handoff.compactTokens} tokens)`,
|
|
514
569
|
},
|
|
515
570
|
],
|
|
516
571
|
};
|
|
@@ -527,6 +582,260 @@ async function handleApproveSimplified(args) {
|
|
|
527
582
|
};
|
|
528
583
|
}
|
|
529
584
|
}
|
|
585
|
+
async function handleContextLoadSimplified(args) {
|
|
586
|
+
const fs = await import("fs");
|
|
587
|
+
const path = await import("path");
|
|
588
|
+
const { featureName, mode = "compact" } = args || {};
|
|
589
|
+
if (!featureName) {
|
|
590
|
+
return {
|
|
591
|
+
content: [{ type: "text", text: "featureName is required" }],
|
|
592
|
+
isError: true,
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
if (!["compact", "standard", "full"].includes(mode)) {
|
|
596
|
+
return {
|
|
597
|
+
content: [{ type: "text", text: "mode must be compact, standard, or full" }],
|
|
598
|
+
isError: true,
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
try {
|
|
602
|
+
const { specDir, specPath } = ensureSimplifiedFeatureExists(featureName);
|
|
603
|
+
const handoffPath = path.join(specDir, "context", "handoff.md");
|
|
604
|
+
if (mode === "full") {
|
|
605
|
+
const context = await loadFullContextSimplified(featureName);
|
|
606
|
+
return { content: [{ type: "text", text: context }] };
|
|
607
|
+
}
|
|
608
|
+
if (!fs.existsSync(handoffPath)) {
|
|
609
|
+
await generateCompactHandoffSimplified(featureName, "requirements");
|
|
610
|
+
}
|
|
611
|
+
let context = fs.readFileSync(handoffPath, "utf8");
|
|
612
|
+
if (mode === "standard") {
|
|
613
|
+
context += `\n\n## Current Spec Metadata\n\n\`\`\`json\n${fs.readFileSync(specPath, "utf8")}\n\`\`\``;
|
|
614
|
+
}
|
|
615
|
+
return { content: [{ type: "text", text: context }] };
|
|
616
|
+
}
|
|
617
|
+
catch (error) {
|
|
618
|
+
return {
|
|
619
|
+
content: [
|
|
620
|
+
{
|
|
621
|
+
type: "text",
|
|
622
|
+
text: `Error loading context: ${error.message}`,
|
|
623
|
+
},
|
|
624
|
+
],
|
|
625
|
+
isError: true,
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
function getSimplifiedSpecDir(featureName) {
|
|
630
|
+
const sddDir = existsSync(nodePath.join(process.cwd(), ".spec")) ? ".spec" : ".kiro";
|
|
631
|
+
return nodePath.join(process.cwd(), sddDir, "specs", featureName);
|
|
632
|
+
}
|
|
633
|
+
function ensureSimplifiedFeatureExists(featureName) {
|
|
634
|
+
const specDir = getSimplifiedSpecDir(featureName);
|
|
635
|
+
const specPath = nodePath.join(specDir, "spec.json");
|
|
636
|
+
if (!existsSync(specPath)) {
|
|
637
|
+
throw new Error(`Feature "${featureName}" not found. Run sdd-init first or check the feature name.`);
|
|
638
|
+
}
|
|
639
|
+
return { specDir, specPath };
|
|
640
|
+
}
|
|
641
|
+
async function generateCompactHandoffSimplified(featureName, approvedPhase) {
|
|
642
|
+
const fs = await import("fs");
|
|
643
|
+
const path = await import("path");
|
|
644
|
+
const { specDir } = ensureSimplifiedFeatureExists(featureName);
|
|
645
|
+
const contextDir = path.join(specDir, "context");
|
|
646
|
+
const documents = ["requirements.md", "design.md", "tasks.md", "spec.json"]
|
|
647
|
+
.map((name) => {
|
|
648
|
+
const filePath = path.join(specDir, name);
|
|
649
|
+
return fs.existsSync(filePath)
|
|
650
|
+
? { name, filePath, content: fs.readFileSync(filePath, "utf8") }
|
|
651
|
+
: null;
|
|
652
|
+
})
|
|
653
|
+
.filter(Boolean);
|
|
654
|
+
if (documents.length === 0) {
|
|
655
|
+
throw new Error(`Feature "${featureName}" has no source documents to compact.`);
|
|
656
|
+
}
|
|
657
|
+
fs.mkdirSync(contextDir, { recursive: true });
|
|
658
|
+
const sourceCharacters = documents.reduce((sum, doc) => sum + doc.content.length, 0);
|
|
659
|
+
const spec = documents.find((doc) => doc.name === "spec.json");
|
|
660
|
+
const parsedSpec = spec ? JSON.parse(spec.content) : {};
|
|
661
|
+
const summaries = documents.map((doc) => summarizeDocumentSimplified(doc.name, doc.content));
|
|
662
|
+
const nextActions = getSimplifiedNextActions(approvedPhase, parsedSpec);
|
|
663
|
+
const draft = [
|
|
664
|
+
`# SDD Context Handoff: ${featureName}`,
|
|
665
|
+
"",
|
|
666
|
+
`Generated: ${new Date().toISOString()}`,
|
|
667
|
+
`Approved phase: ${approvedPhase}`,
|
|
668
|
+
"",
|
|
669
|
+
"## Workflow State",
|
|
670
|
+
"",
|
|
671
|
+
`- Requirements: ${formatSimplifiedApproval(parsedSpec.approvals?.requirements)}`,
|
|
672
|
+
`- Design: ${formatSimplifiedApproval(parsedSpec.approvals?.design)}`,
|
|
673
|
+
`- Tasks: ${formatSimplifiedApproval(parsedSpec.approvals?.tasks)}`,
|
|
674
|
+
parsedSpec.checkpoints?.test_cases?.required
|
|
675
|
+
? `- TDD test-case review: ${parsedSpec.checkpoints.test_cases.reviewed ? "reviewed" : "pending"}`
|
|
676
|
+
: "- TDD test-case review: not required",
|
|
677
|
+
"",
|
|
678
|
+
"## Compact Phase Summaries",
|
|
679
|
+
"",
|
|
680
|
+
summaries.join("\n\n"),
|
|
681
|
+
"",
|
|
682
|
+
"## Next Actions",
|
|
683
|
+
"",
|
|
684
|
+
...nextActions.map((action) => `- ${action}`),
|
|
685
|
+
"",
|
|
686
|
+
"## Source References",
|
|
687
|
+
"",
|
|
688
|
+
...documents.map((doc) => `- ${doc.filePath}`),
|
|
689
|
+
"",
|
|
690
|
+
"## Context Budget Estimate",
|
|
691
|
+
"",
|
|
692
|
+
`- Full source context: ~${estimateTokensSimplified(sourceCharacters)} tokens`,
|
|
693
|
+
"- Handoff context: ~0 tokens",
|
|
694
|
+
"- Use `sdd-context-load` default compact mode for routine continuation.",
|
|
695
|
+
'- Use `sdd-context-load` with `mode: "full"` only for audits or ambiguous decisions.'
|
|
696
|
+
].join("\n");
|
|
697
|
+
const compactTokens = estimateTokensSimplified(draft.length);
|
|
698
|
+
const sourceTokens = estimateTokensSimplified(sourceCharacters);
|
|
699
|
+
const reductionPercentage = sourceTokens === 0
|
|
700
|
+
? 0
|
|
701
|
+
: Math.max(0, Math.round((1 - compactTokens / sourceTokens) * 100));
|
|
702
|
+
const content = draft.replace("- Handoff context: ~0 tokens", `- Handoff context: ~${compactTokens} tokens`);
|
|
703
|
+
const handoffPath = path.join(contextDir, "handoff.md");
|
|
704
|
+
fs.writeFileSync(handoffPath, content);
|
|
705
|
+
fs.writeFileSync(path.join(contextDir, `${approvedPhase}-handoff.md`), content);
|
|
706
|
+
return {
|
|
707
|
+
relativePath: path.relative(process.cwd(), handoffPath),
|
|
708
|
+
sourceTokens,
|
|
709
|
+
compactTokens,
|
|
710
|
+
reductionPercentage,
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
async function loadFullContextSimplified(featureName) {
|
|
714
|
+
const fs = await import("fs");
|
|
715
|
+
const path = await import("path");
|
|
716
|
+
const { specDir } = ensureSimplifiedFeatureExists(featureName);
|
|
717
|
+
const parts = [`# Full SDD Context: ${featureName}`];
|
|
718
|
+
for (const name of ["requirements.md", "design.md", "tasks.md", "spec.json"]) {
|
|
719
|
+
const filePath = path.join(specDir, name);
|
|
720
|
+
if (fs.existsSync(filePath)) {
|
|
721
|
+
parts.push(`## ${name}\n\n${fs.readFileSync(filePath, "utf8")}`);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
return parts.join("\n\n");
|
|
725
|
+
}
|
|
726
|
+
function summarizeDocumentSimplified(name, content) {
|
|
727
|
+
const lines = content
|
|
728
|
+
.split(/\r?\n/)
|
|
729
|
+
.map((line) => line.trim())
|
|
730
|
+
.filter((line) => line.length > 0 && !line.startsWith("```"));
|
|
731
|
+
const headings = lines
|
|
732
|
+
.filter((line) => /^#{1,4}\s+/.test(line))
|
|
733
|
+
.map((line) => line.replace(/^#{1,4}\s+/, "").trim())
|
|
734
|
+
.filter(uniqueSimplifiedLine)
|
|
735
|
+
.slice(0, 8);
|
|
736
|
+
const bullets = lines
|
|
737
|
+
.filter((line) => /^[-*]\s+/.test(line) || /^\d+\.\s+/.test(line))
|
|
738
|
+
.map((line) => line.replace(/^[-*]\s+/, "").replace(/^\d+\.\s+/, "").trim())
|
|
739
|
+
.filter((line) => line.length <= 220)
|
|
740
|
+
.filter(uniqueSimplifiedLine)
|
|
741
|
+
.slice(0, 8);
|
|
742
|
+
const requirementLines = lines
|
|
743
|
+
.filter((line) => /\b(SHALL|MUST|WHEN|IF|THEN|WHERE|constraint|risk|security|performance|error|edge case)\b/i.test(line))
|
|
744
|
+
.map((line) => line.replace(/^[-*]\s+/, "").replace(/^\d+\.\s+/, "").trim())
|
|
745
|
+
.filter((line) => line.length <= 240)
|
|
746
|
+
.filter(uniqueSimplifiedLine)
|
|
747
|
+
.slice(0, 8);
|
|
748
|
+
return [
|
|
749
|
+
`### ${name}`,
|
|
750
|
+
headings.length > 0 ? "\n**Key sections:**" : "",
|
|
751
|
+
...headings.map((line) => `- ${line}`),
|
|
752
|
+
bullets.length > 0 ? "\n**Important points:**" : "",
|
|
753
|
+
...bullets.map((line) => `- ${line}`),
|
|
754
|
+
requirementLines.length > 0 ? "\n**Constraints and acceptance signals:**" : "",
|
|
755
|
+
...requirementLines.map((line) => `- ${line}`),
|
|
756
|
+
headings.length === 0 && bullets.length === 0 && requirementLines.length === 0
|
|
757
|
+
? "- No structured summary points found; open source document if this phase is active."
|
|
758
|
+
: "",
|
|
759
|
+
].filter(Boolean).join("\n");
|
|
760
|
+
}
|
|
761
|
+
function uniqueSimplifiedLine(line, index, lines) {
|
|
762
|
+
return lines.findIndex((candidate) => candidate.toLowerCase() === line.toLowerCase()) === index;
|
|
763
|
+
}
|
|
764
|
+
function getSimplifiedNextActions(approvedPhase, spec) {
|
|
765
|
+
if (approvedPhase === "requirements") {
|
|
766
|
+
return ["Generate or review design using the approved requirements handoff."];
|
|
767
|
+
}
|
|
768
|
+
if (approvedPhase === "design") {
|
|
769
|
+
return ["Generate TDD task breakdown from the approved design handoff."];
|
|
770
|
+
}
|
|
771
|
+
if (spec.checkpoints?.test_cases?.required && !spec.checkpoints.test_cases.reviewed) {
|
|
772
|
+
return ["Review TDD test cases, then run sdd-review-test-cases before approving tasks."];
|
|
773
|
+
}
|
|
774
|
+
return ["Begin implementation with compact context loaded; open full docs only for ambiguous details."];
|
|
775
|
+
}
|
|
776
|
+
function formatSimplifiedApproval(status) {
|
|
777
|
+
if (status?.generated && status?.approved)
|
|
778
|
+
return "generated, approved";
|
|
779
|
+
if (status?.generated)
|
|
780
|
+
return "generated, pending approval";
|
|
781
|
+
return "not generated";
|
|
782
|
+
}
|
|
783
|
+
function estimateTokensSimplified(characters) {
|
|
784
|
+
return Math.max(1, Math.ceil(characters / 4));
|
|
785
|
+
}
|
|
786
|
+
async function handleReviewTestCasesSimplified(args) {
|
|
787
|
+
const fs = await import("fs");
|
|
788
|
+
const path = await import("path");
|
|
789
|
+
const { featureName } = args || {};
|
|
790
|
+
if (!featureName) {
|
|
791
|
+
return {
|
|
792
|
+
content: [{ type: "text", text: "featureName is required" }],
|
|
793
|
+
isError: true,
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
try {
|
|
797
|
+
const sddDir = fs.existsSync(path.join(process.cwd(), ".spec")) ? ".spec" : ".kiro";
|
|
798
|
+
const specPath = path.join(process.cwd(), sddDir, "specs", featureName, "spec.json");
|
|
799
|
+
const spec = JSON.parse(fs.readFileSync(specPath, "utf8"));
|
|
800
|
+
spec.workflow_options = {
|
|
801
|
+
...(spec.workflow_options ?? {}),
|
|
802
|
+
review_test_cases: true,
|
|
803
|
+
};
|
|
804
|
+
spec.checkpoints = {
|
|
805
|
+
...(spec.checkpoints ?? {}),
|
|
806
|
+
test_cases: {
|
|
807
|
+
required: true,
|
|
808
|
+
reviewed: true,
|
|
809
|
+
reviewed_at: new Date().toISOString(),
|
|
810
|
+
},
|
|
811
|
+
};
|
|
812
|
+
spec.updated_at = new Date().toISOString();
|
|
813
|
+
spec.ready_for_implementation =
|
|
814
|
+
spec.approvals?.requirements?.approved === true &&
|
|
815
|
+
spec.approvals?.design?.approved === true &&
|
|
816
|
+
spec.approvals?.tasks?.approved === true;
|
|
817
|
+
fs.writeFileSync(specPath, JSON.stringify(spec, null, 2));
|
|
818
|
+
return {
|
|
819
|
+
content: [
|
|
820
|
+
{
|
|
821
|
+
type: "text",
|
|
822
|
+
text: `## TDD Test Cases Reviewed\n\n**Feature**: ${featureName}\n**Status**: ✅ Reviewed`,
|
|
823
|
+
},
|
|
824
|
+
],
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
catch (error) {
|
|
828
|
+
return {
|
|
829
|
+
content: [
|
|
830
|
+
{
|
|
831
|
+
type: "text",
|
|
832
|
+
text: `Error reviewing test cases: ${error.message}`,
|
|
833
|
+
},
|
|
834
|
+
],
|
|
835
|
+
isError: true,
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
}
|
|
530
839
|
// Simple quality check aligned with full server
|
|
531
840
|
async function handleQualityCheckSimplified(args) {
|
|
532
841
|
const { code = "", language = "javascript" } = args || {};
|
|
@@ -625,7 +934,7 @@ async function handleInitSimplified(args) {
|
|
|
625
934
|
const fs = await import("fs");
|
|
626
935
|
const path = await import("path");
|
|
627
936
|
try {
|
|
628
|
-
const { projectName, description } = args;
|
|
937
|
+
const { projectName, description, reviewTestCases = false } = args;
|
|
629
938
|
if (!description || typeof description !== "string") {
|
|
630
939
|
throw new Error("Description is required for project initialization");
|
|
631
940
|
}
|
|
@@ -661,6 +970,15 @@ async function handleInitSimplified(args) {
|
|
|
661
970
|
approved: false,
|
|
662
971
|
},
|
|
663
972
|
},
|
|
973
|
+
workflow_options: {
|
|
974
|
+
review_test_cases: reviewTestCases === true,
|
|
975
|
+
},
|
|
976
|
+
checkpoints: {
|
|
977
|
+
test_cases: {
|
|
978
|
+
required: reviewTestCases === true,
|
|
979
|
+
reviewed: reviewTestCases !== true,
|
|
980
|
+
},
|
|
981
|
+
},
|
|
664
982
|
ready_for_implementation: false,
|
|
665
983
|
};
|
|
666
984
|
fs.writeFileSync(path.join(specDir, "spec.json"), JSON.stringify(specContent, null, 2));
|
|
@@ -698,7 +1016,7 @@ Spec Driven Development implementation using MCP tools.
|
|
|
698
1016
|
### Paths
|
|
699
1017
|
- Steering: \`.spec/steering/\`
|
|
700
1018
|
- Specs: \`.spec/specs/\`
|
|
701
|
-
-
|
|
1019
|
+
- Skills: install with \`npx sdd-mcp-server install --target codex --skills\` or \`--target claude-code\`
|
|
702
1020
|
|
|
703
1021
|
### Steering vs Specification
|
|
704
1022
|
|
|
@@ -727,7 +1045,7 @@ Note: Optional for new features or small additions. You can proceed directly to
|
|
|
727
1045
|
1. \`sdd-init\` - Initialize spec with detailed project description
|
|
728
1046
|
2. \`sdd-requirements\` - Generate requirements document
|
|
729
1047
|
3. \`sdd-design\` - Interactive: "Have you reviewed requirements.md? [y/N]"
|
|
730
|
-
4. \`sdd-tasks\` - Interactive: Confirms
|
|
1048
|
+
4. \`sdd-tasks\` - Interactive: Confirms requirements/design review and asks whether TDD test cases need a review checkpoint
|
|
731
1049
|
|
|
732
1050
|
### Phase 2: Progress Tracking
|
|
733
1051
|
\`sdd-status\` - Check current progress and phases
|
|
@@ -747,14 +1065,15 @@ Note: Optional for new features or small additions. You can proceed directly to
|
|
|
747
1065
|
Managed by \`sdd-steering\` tool. Updates here reflect tool changes.
|
|
748
1066
|
|
|
749
1067
|
### Active Steering Files
|
|
750
|
-
|
|
751
|
-
- \`
|
|
752
|
-
- \`
|
|
753
|
-
- \`
|
|
754
|
-
- \`
|
|
755
|
-
- \`
|
|
756
|
-
- \`
|
|
757
|
-
- \`
|
|
1068
|
+
Load steering documents on demand to control token usage:
|
|
1069
|
+
- \`product.md\`: Product context and business objectives
|
|
1070
|
+
- \`tech.md\`: Technology stack and architectural decisions
|
|
1071
|
+
- \`structure.md\`: File organization and code patterns
|
|
1072
|
+
- \`linus-review.md\`: Code quality review standards
|
|
1073
|
+
- \`commit.md\`: Commit and PR conventions
|
|
1074
|
+
- \`security-check.md\`: OWASP Top 10 checklist for code generation and review
|
|
1075
|
+
- \`tdd-guideline.md\`: TDD workflow for new features
|
|
1076
|
+
- \`principles.md\`: SOLID, DRY, KISS, YAGNI, Separation of Concerns, Modularity
|
|
758
1077
|
|
|
759
1078
|
### Custom Steering Files
|
|
760
1079
|
<!-- Added by sdd-steering-custom tool -->
|
|
@@ -780,6 +1099,7 @@ Managed by \`sdd-steering\` tool. Updates here reflect tool changes.
|
|
|
780
1099
|
|
|
781
1100
|
**Feature Name**: \`${featureName}\`
|
|
782
1101
|
**Description**: ${description}
|
|
1102
|
+
**TDD Test Case Review Checkpoint**: ${reviewTestCases === true ? "Enabled" : "Disabled"}
|
|
783
1103
|
|
|
784
1104
|
**Created Files**:
|
|
785
1105
|
- \`.spec/specs/${featureName}/spec.json\` - Project metadata and phase tracking
|
|
@@ -841,7 +1161,7 @@ async function main() {
|
|
|
841
1161
|
templates: "Handlebars-based template generation with inheritance",
|
|
842
1162
|
},
|
|
843
1163
|
tools: {
|
|
844
|
-
count:
|
|
1164
|
+
count: 11,
|
|
845
1165
|
categories: [
|
|
846
1166
|
"sdd-init",
|
|
847
1167
|
"sdd-requirements",
|
|
@@ -850,6 +1170,7 @@ async function main() {
|
|
|
850
1170
|
"sdd-implement",
|
|
851
1171
|
"sdd-status",
|
|
852
1172
|
"sdd-approve",
|
|
1173
|
+
"sdd-review-test-cases",
|
|
853
1174
|
"sdd-quality-check",
|
|
854
1175
|
"sdd-context-load",
|
|
855
1176
|
"sdd-template-render",
|