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.
Files changed (102) hide show
  1. package/README.md +120 -54
  2. package/dist/adapters/cli/SDDToolAdapter.d.ts +5 -1
  3. package/dist/adapters/cli/SDDToolAdapter.js +111 -18
  4. package/dist/adapters/cli/SDDToolAdapter.js.map +1 -1
  5. package/dist/application/services/ContextCompactionService.d.ts +39 -0
  6. package/dist/application/services/ContextCompactionService.js +253 -0
  7. package/dist/application/services/ContextCompactionService.js.map +1 -0
  8. package/dist/application/services/ProjectService.d.ts +7 -1
  9. package/dist/application/services/ProjectService.js +56 -1
  10. package/dist/application/services/ProjectService.js.map +1 -1
  11. package/dist/application/services/TemplateService.js +27 -5
  12. package/dist/application/services/TemplateService.js.map +1 -1
  13. package/dist/application/services/WorkflowEngineService.d.ts +3 -1
  14. package/dist/application/services/WorkflowEngineService.js +20 -5
  15. package/dist/application/services/WorkflowEngineService.js.map +1 -1
  16. package/dist/application/services/WorkflowService.js +8 -0
  17. package/dist/application/services/WorkflowService.js.map +1 -1
  18. package/dist/application/services/staticSteering.js +12 -13
  19. package/dist/application/services/staticSteering.js.map +1 -1
  20. package/dist/cli/install-skills.d.ts +13 -31
  21. package/dist/cli/install-skills.js +230 -173
  22. package/dist/cli/install-skills.js.map +1 -1
  23. package/dist/cli/install-target.d.ts +127 -0
  24. package/dist/cli/install-target.js +127 -0
  25. package/dist/cli/install-target.js.map +1 -0
  26. package/dist/cli/migrate-steering.js +13 -13
  27. package/dist/cli/migrate-steering.js.map +1 -1
  28. package/dist/cli/sdd-mcp-cli.d.ts +1 -1
  29. package/dist/cli/sdd-mcp-cli.js +14 -10
  30. package/dist/cli/sdd-mcp-cli.js.map +1 -1
  31. package/dist/cli/tool-support/antigravity.d.ts +6 -1
  32. package/dist/cli/tool-support/antigravity.js +55 -12
  33. package/dist/cli/tool-support/antigravity.js.map +1 -1
  34. package/dist/cli/tool-support/claude-code.d.ts +5 -0
  35. package/dist/cli/tool-support/claude-code.js +93 -0
  36. package/dist/cli/tool-support/claude-code.js.map +1 -0
  37. package/dist/cli/tool-support/codex.d.ts +18 -1
  38. package/dist/cli/tool-support/codex.js +161 -36
  39. package/dist/cli/tool-support/codex.js.map +1 -1
  40. package/dist/cli/tool-support/index.d.ts +2 -2
  41. package/dist/cli/tool-support/root-guidance.d.ts +9 -0
  42. package/dist/cli/tool-support/root-guidance.js +40 -0
  43. package/dist/cli/tool-support/root-guidance.js.map +1 -0
  44. package/dist/cli/tool-support/target-agent-renderer.d.ts +11 -0
  45. package/dist/cli/tool-support/target-agent-renderer.js +52 -0
  46. package/dist/cli/tool-support/target-agent-renderer.js.map +1 -0
  47. package/dist/cli/tool-support/target-installer.d.ts +40 -0
  48. package/dist/cli/tool-support/target-installer.js +116 -0
  49. package/dist/cli/tool-support/target-installer.js.map +1 -0
  50. package/dist/cli/utils/gitignore-manager.d.ts +5 -0
  51. package/dist/cli/utils/gitignore-manager.js +85 -0
  52. package/dist/cli/utils/gitignore-manager.js.map +1 -0
  53. package/dist/cli/utils/preserving-writer.d.ts +13 -0
  54. package/dist/cli/utils/preserving-writer.js +106 -0
  55. package/dist/cli/utils/preserving-writer.js.map +1 -0
  56. package/dist/domain/services/DomainService.d.ts +1 -0
  57. package/dist/domain/services/DomainService.js +12 -2
  58. package/dist/domain/services/DomainService.js.map +1 -1
  59. package/dist/domain/types.d.ts +13 -0
  60. package/dist/domain/types.js.map +1 -1
  61. package/dist/domain/workflow/WorkflowStateMachine.js +7 -2
  62. package/dist/domain/workflow/WorkflowStateMachine.js.map +1 -1
  63. package/dist/hooks/HookLoader.js +9 -1
  64. package/dist/hooks/HookLoader.js.map +1 -1
  65. package/dist/index.js +347 -26
  66. package/dist/index.js.map +1 -1
  67. package/dist/infrastructure/di/container.js +4 -0
  68. package/dist/infrastructure/di/container.js.map +1 -1
  69. package/dist/infrastructure/di/types.d.ts +1 -0
  70. package/dist/infrastructure/di/types.js +1 -0
  71. package/dist/infrastructure/di/types.js.map +1 -1
  72. package/dist/infrastructure/mcp/ResourceManager.js +21 -1
  73. package/dist/infrastructure/mcp/ResourceManager.js.map +1 -1
  74. package/dist/infrastructure/mcp/ToolRegistry.js +34 -2
  75. package/dist/infrastructure/mcp/ToolRegistry.js.map +1 -1
  76. package/dist/infrastructure/schemas/project.schema.d.ts +47 -4
  77. package/dist/infrastructure/schemas/project.schema.js +39 -2
  78. package/dist/infrastructure/schemas/project.schema.js.map +1 -1
  79. package/dist/shared/BaseManager.d.ts +10 -1
  80. package/dist/shared/BaseManager.js +34 -5
  81. package/dist/shared/BaseManager.js.map +1 -1
  82. package/dist/skills/SkillManager.d.ts +3 -1
  83. package/dist/skills/SkillManager.js +15 -3
  84. package/dist/skills/SkillManager.js.map +1 -1
  85. package/package.json +2 -2
  86. package/sdd-entry.js +2 -2
  87. package/skills/sdd-design/SKILL.md +4 -0
  88. package/skills/sdd-implement/SKILL.md +10 -4
  89. package/skills/sdd-requirements/SKILL.md +4 -0
  90. package/skills/sdd-review/SKILL.md +4 -0
  91. package/skills/sdd-security-check/SKILL.md +4 -0
  92. package/skills/sdd-steering/SKILL.md +4 -0
  93. package/skills/sdd-steering-custom/SKILL.md +4 -0
  94. package/skills/sdd-tasks/SKILL.md +24 -7
  95. package/skills/sdd-test-gen/SKILL.md +4 -0
  96. package/skills/simple-task/SKILL.md +4 -0
  97. package/templates/CLAUDE.md +2 -36
  98. package/templates/codex-AGENTS.md +1 -2
  99. package/templates/codex-hook-runner.js +85 -0
  100. package/dist/utils/sddPaths.d.ts +0 -69
  101. package/dist/utils/sddPaths.js +0 -138
  102. package/dist/utils/sddPaths.js.map +0 -1
@@ -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 that can be installed for Claude Code",
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-skills\` to install skills to your project.`,
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 that can be installed for Claude Code:
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-skills\` to install all skills to \`.claude/skills/\`
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, you can use these skills in Claude Code with:
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**Feature**: ${featureName}\n**Phase**: ${phase}\n**Status**: ✅ Approved`,
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
- - Commands: \`.claude/commands/\`
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 both requirements and design review
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
- - \`product.md\`: Always included - Product context and business objectives
751
- - \`tech.md\`: Always included - Technology stack and architectural decisions
752
- - \`structure.md\`: Always included - File organization and code patterns
753
- - \`linus-review.md\`: Always included - Ensuring code quality of the projects
754
- - \`commit.md\`: Always included - Ensuring the commit / merge request / pull request title and message context
755
- - \`security-check.md\`: Always included - OWASP Top 10 security checklist (REQUIRED for code generation and review)
756
- - \`tdd-guideline.md\`: Always included - Test-Driven Development workflow (REQUIRED for all new features)
757
- - \`principles.md\`: Always included - Core coding principles (SOLID, DRY, KISS, YAGNI, Separation of Concerns, Modularity)
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: 10,
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",