sdd-mcp-server 1.4.4 → 1.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 (29) hide show
  1. package/README.md +18 -9
  2. package/dist/__tests__/legacy/setup.d.ts +44 -0
  3. package/dist/__tests__/legacy/setup.js +178 -0
  4. package/dist/__tests__/legacy/setup.js.map +1 -0
  5. package/dist/__tests__/legacy/test-helpers/mock-factories.d.ts +26 -0
  6. package/dist/__tests__/legacy/test-helpers/mock-factories.js +466 -0
  7. package/dist/__tests__/legacy/test-helpers/mock-factories.js.map +1 -0
  8. package/dist/adapters/cli/SDDToolAdapter.d.ts +12 -9
  9. package/dist/adapters/cli/SDDToolAdapter.js +344 -462
  10. package/dist/adapters/cli/SDDToolAdapter.js.map +1 -1
  11. package/dist/application/services/RequirementsClarificationService.d.ts +73 -0
  12. package/dist/application/services/RequirementsClarificationService.js +523 -0
  13. package/dist/application/services/RequirementsClarificationService.js.map +1 -0
  14. package/dist/application/services/staticSteering.d.ts +6 -0
  15. package/dist/application/services/staticSteering.js +567 -0
  16. package/dist/application/services/staticSteering.js.map +1 -0
  17. package/dist/domain/types.d.ts +47 -0
  18. package/dist/domain/types.js +8 -0
  19. package/dist/domain/types.js.map +1 -1
  20. package/dist/index.js +118 -17
  21. package/dist/index.js.map +1 -1
  22. package/dist/infrastructure/di/container.d.ts +2 -2
  23. package/dist/infrastructure/di/container.js +102 -60
  24. package/dist/infrastructure/di/container.js.map +1 -1
  25. package/dist/infrastructure/di/types.d.ts +1 -0
  26. package/dist/infrastructure/di/types.js +39 -38
  27. package/dist/infrastructure/di/types.js.map +1 -1
  28. package/mcp-server.js +2030 -1324
  29. package/package.json +1 -1
@@ -11,15 +11,17 @@ var __metadata = (this && this.__metadata) || function (k, v) {
11
11
  var __param = (this && this.__param) || function (paramIndex, decorator) {
12
12
  return function (target, key) { decorator(target, key, paramIndex); }
13
13
  };
14
- import { injectable, inject } from 'inversify';
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
- import { TemplateService } from '../../application/services/TemplateService.js';
19
- import { QualityService } from '../../application/services/QualityService.js';
20
- import { SteeringDocumentService } from '../../application/services/SteeringDocumentService.js';
21
- import { CodebaseAnalysisService } from '../../application/services/CodebaseAnalysisService.js';
22
- import { WorkflowPhase } from '../../domain/types.js';
14
+ import { injectable, inject } from "inversify";
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
+ import { TemplateService } from "../../application/services/TemplateService.js";
19
+ import { QualityService } from "../../application/services/QualityService.js";
20
+ import { SteeringDocumentService } from "../../application/services/SteeringDocumentService.js";
21
+ import { CodebaseAnalysisService } from "../../application/services/CodebaseAnalysisService.js";
22
+ import { RequirementsClarificationService, } from "../../application/services/RequirementsClarificationService.js";
23
+ import { WorkflowPhase } from "../../domain/types.js";
24
+ import { ensureStaticSteeringDocuments } from "../../application/services/staticSteering.js";
23
25
  let SDDToolAdapter = class SDDToolAdapter {
24
26
  projectService;
25
27
  workflowService;
@@ -27,179 +29,262 @@ let SDDToolAdapter = class SDDToolAdapter {
27
29
  qualityService;
28
30
  steeringService;
29
31
  codebaseAnalysisService;
32
+ clarificationService;
30
33
  logger;
31
- constructor(projectService, workflowService, templateService, qualityService, steeringService, codebaseAnalysisService, logger) {
34
+ constructor(projectService, workflowService, templateService, qualityService, steeringService, codebaseAnalysisService, clarificationService, logger) {
32
35
  this.projectService = projectService;
33
36
  this.workflowService = workflowService;
34
37
  this.templateService = templateService;
35
38
  this.qualityService = qualityService;
36
39
  this.steeringService = steeringService;
37
40
  this.codebaseAnalysisService = codebaseAnalysisService;
41
+ this.clarificationService = clarificationService;
38
42
  this.logger = logger;
39
43
  }
40
44
  getSDDTools() {
41
45
  return [
42
46
  {
43
- name: 'sdd-init',
47
+ name: "sdd-init",
44
48
  tool: {
45
- name: 'sdd-init',
46
- description: 'Initialize a new SDD project from description',
49
+ name: "sdd-init",
50
+ description: "Initialize a new SDD project with interactive requirements clarification",
47
51
  inputSchema: {
48
- type: 'object',
52
+ type: "object",
49
53
  properties: {
50
- description: { type: 'string', description: 'Detailed project description' }
54
+ projectName: {
55
+ type: "string",
56
+ description: "The name of the project to initialize",
57
+ },
58
+ description: {
59
+ type: "string",
60
+ description: "Project description",
61
+ },
62
+ clarificationAnswers: {
63
+ type: "object",
64
+ description: "Answers to clarification questions (second pass)",
65
+ additionalProperties: { type: "string" },
66
+ },
51
67
  },
52
- required: ['description']
53
- }
68
+ required: ["projectName"],
69
+ },
54
70
  },
55
- handler: this.handleProjectInit.bind(this)
71
+ handler: this.handleProjectInit.bind(this),
56
72
  },
57
73
  {
58
- name: 'sdd-status',
74
+ name: "sdd-status",
59
75
  tool: {
60
- name: 'sdd-status',
61
- description: 'Get current project status and workflow phase information',
76
+ name: "sdd-status",
77
+ description: "Get current project status and workflow phase information",
62
78
  inputSchema: {
63
- type: 'object',
79
+ type: "object",
64
80
  properties: {
65
- projectId: { type: 'string', description: 'Project ID' },
66
- projectPath: { type: 'string', description: 'Project path (alternative to ID)' }
67
- }
68
- }
81
+ projectId: { type: "string", description: "Project ID" },
82
+ projectPath: {
83
+ type: "string",
84
+ description: "Project path (alternative to ID)",
85
+ },
86
+ },
87
+ },
69
88
  },
70
- handler: this.handleProjectStatus.bind(this)
89
+ handler: this.handleProjectStatus.bind(this),
71
90
  },
72
91
  {
73
- name: 'sdd-requirements',
92
+ name: "sdd-requirements",
74
93
  tool: {
75
- name: 'sdd-requirements',
76
- description: 'Generate requirements doc',
94
+ name: "sdd-requirements",
95
+ description: "Generate requirements doc",
77
96
  inputSchema: {
78
- type: 'object',
97
+ type: "object",
79
98
  properties: {
80
- featureName: { type: 'string', description: 'Feature name' }
99
+ featureName: { type: "string", description: "Feature name" },
81
100
  },
82
- required: ['featureName']
83
- }
101
+ required: ["featureName"],
102
+ },
84
103
  },
85
- handler: this.handleRequirements.bind(this)
104
+ handler: this.handleRequirements.bind(this),
86
105
  },
87
106
  {
88
- name: 'sdd-design',
107
+ name: "sdd-design",
89
108
  tool: {
90
- name: 'sdd-design',
91
- description: 'Create design specifications',
109
+ name: "sdd-design",
110
+ description: "Create design specifications",
92
111
  inputSchema: {
93
- type: 'object',
112
+ type: "object",
94
113
  properties: {
95
- featureName: { type: 'string', description: 'Feature name' }
114
+ featureName: { type: "string", description: "Feature name" },
96
115
  },
97
- required: ['featureName']
98
- }
116
+ required: ["featureName"],
117
+ },
99
118
  },
100
- handler: this.handleDesign.bind(this)
119
+ handler: this.handleDesign.bind(this),
101
120
  },
102
121
  {
103
- name: 'sdd-tasks',
122
+ name: "sdd-tasks",
104
123
  tool: {
105
- name: 'sdd-tasks',
106
- description: 'Generate task breakdown',
124
+ name: "sdd-tasks",
125
+ description: "Generate task breakdown",
107
126
  inputSchema: {
108
- type: 'object',
127
+ type: "object",
109
128
  properties: {
110
- featureName: { type: 'string', description: 'Feature name' }
129
+ featureName: { type: "string", description: "Feature name" },
111
130
  },
112
- required: ['featureName']
113
- }
131
+ required: ["featureName"],
132
+ },
114
133
  },
115
- handler: this.handleTasks.bind(this)
134
+ handler: this.handleTasks.bind(this),
116
135
  },
117
136
  {
118
- name: 'sdd-quality-check',
137
+ name: "sdd-quality-check",
119
138
  tool: {
120
- name: 'sdd-quality-check',
121
- description: 'Perform Linus-style code quality analysis',
139
+ name: "sdd-quality-check",
140
+ description: "Perform Linus-style code quality analysis",
122
141
  inputSchema: {
123
- type: 'object',
142
+ type: "object",
124
143
  properties: {
125
- code: { type: 'string', description: 'Code to analyze' },
126
- language: { type: 'string', description: 'Programming language' }
144
+ code: { type: "string", description: "Code to analyze" },
145
+ language: { type: "string", description: "Programming language" },
127
146
  },
128
- required: ['code']
129
- }
147
+ required: ["code"],
148
+ },
130
149
  },
131
- handler: this.handleQualityCheck.bind(this)
150
+ handler: this.handleQualityCheck.bind(this),
132
151
  },
133
152
  {
134
- name: 'sdd-steering',
153
+ name: "sdd-steering",
135
154
  tool: {
136
- name: 'sdd-steering',
137
- description: 'Create/update steering documents with project-specific analysis',
155
+ name: "sdd-steering",
156
+ description: "Create/update steering documents with project-specific analysis",
138
157
  inputSchema: {
139
- type: 'object',
158
+ type: "object",
140
159
  properties: {
141
- updateMode: { type: 'string', enum: ['create', 'update'], description: 'Whether to create new or update existing documents' }
142
- }
143
- }
160
+ updateMode: {
161
+ type: "string",
162
+ enum: ["create", "update"],
163
+ description: "Whether to create new or update existing documents",
164
+ },
165
+ },
166
+ },
144
167
  },
145
- handler: this.handleSteering.bind(this)
168
+ handler: this.handleSteering.bind(this),
146
169
  },
147
170
  {
148
- name: 'sdd-steering-custom',
171
+ name: "sdd-steering-custom",
149
172
  tool: {
150
- name: 'sdd-steering-custom',
151
- description: 'Create custom steering documents for specialized contexts',
173
+ name: "sdd-steering-custom",
174
+ description: "Create custom steering documents for specialized contexts",
152
175
  inputSchema: {
153
- type: 'object',
176
+ type: "object",
154
177
  properties: {
155
- fileName: { type: 'string', description: 'Filename for the custom steering document' },
156
- topic: { type: 'string', description: 'Topic/purpose of the custom steering document' },
157
- inclusionMode: { type: 'string', enum: ['always', 'conditional', 'manual'], description: 'How this steering document should be included' },
158
- filePattern: { type: 'string', description: 'File pattern for conditional inclusion' }
178
+ fileName: {
179
+ type: "string",
180
+ description: "Filename for the custom steering document",
181
+ },
182
+ topic: {
183
+ type: "string",
184
+ description: "Topic/purpose of the custom steering document",
185
+ },
186
+ inclusionMode: {
187
+ type: "string",
188
+ enum: ["always", "conditional", "manual"],
189
+ description: "How this steering document should be included",
190
+ },
191
+ filePattern: {
192
+ type: "string",
193
+ description: "File pattern for conditional inclusion",
194
+ },
159
195
  },
160
- required: ['fileName', 'topic', 'inclusionMode']
161
- }
196
+ required: ["fileName", "topic", "inclusionMode"],
197
+ },
162
198
  },
163
- handler: this.handleSteeringCustom.bind(this)
164
- }
199
+ handler: this.handleSteeringCustom.bind(this),
200
+ },
165
201
  ];
166
202
  }
167
203
  async handleProjectInit(args) {
168
- const { name, path, language = 'en' } = args;
169
- if (typeof name !== 'string' || typeof path !== 'string') {
170
- throw new Error('Invalid arguments: name and path must be strings');
204
+ const { projectName, description = "", clarificationAnswers } = args;
205
+ if (typeof projectName !== "string") {
206
+ throw new Error("Invalid arguments: projectName must be a string");
207
+ }
208
+ const currentPath = process.cwd();
209
+ // FIRST PASS: Analyze description quality
210
+ if (!clarificationAnswers) {
211
+ const result = await this.clarificationService.analyzeDescription(description, currentPath);
212
+ // If clarification needed, BLOCK and return questions
213
+ if (result.needsClarification && result.questions) {
214
+ return this.formatClarificationQuestions(result.questions, result.analysis);
215
+ }
171
216
  }
172
- const project = await this.projectService.createProject(name, path, language);
217
+ // SECOND PASS: Validate and synthesize enriched description
218
+ let enrichedDescription = description;
219
+ if (clarificationAnswers && typeof clarificationAnswers === "object") {
220
+ const result = await this.clarificationService.analyzeDescription(description, currentPath);
221
+ if (result.questions) {
222
+ const validation = this.clarificationService.validateAnswers(result.questions, clarificationAnswers);
223
+ if (!validation.valid) {
224
+ throw new Error(`Missing required answers: ${validation.missingRequired.join(", ")}`);
225
+ }
226
+ const enriched = this.clarificationService.synthesizeDescription(description, result.questions, clarificationAnswers);
227
+ enrichedDescription = enriched.enriched;
228
+ }
229
+ }
230
+ // Create project with enriched description
231
+ const project = await this.projectService.createProject(projectName, currentPath, "en");
173
232
  // Generate initial spec.json
174
233
  const specContent = await this.templateService.generateSpecJson(project);
175
- await this.templateService.writeProjectFile(project, 'spec.json', specContent);
234
+ await this.templateService.writeProjectFile(project, "spec.json", specContent);
176
235
  // Create AGENTS.md if it doesn't exist
177
- await this.createAgentsFile(path);
178
- return `Project "${name}" initialized successfully at ${path}\nProject ID: ${project.id}`;
236
+ await this.createAgentsFile(currentPath);
237
+ const clarificationNote = clarificationAnswers
238
+ ? "\n\n✅ Requirements Clarification: Your answers have been incorporated into an enriched project description."
239
+ : "";
240
+ return `Project "${projectName}" initialized successfully\nProject ID: ${project.id}\n\nDescription:\n${enrichedDescription}${clarificationNote}`;
241
+ }
242
+ formatClarificationQuestions(questions, analysis) {
243
+ let output = "## Requirements Clarification Needed\n\n";
244
+ output +=
245
+ "Your project description needs more detail to ensure we build the right solution.\n\n";
246
+ output += `**Quality Score**: ${Math.round(analysis.qualityScore)}/100 (need 70+ to proceed)\n\n`;
247
+ output += "### Please answer these questions:\n\n";
248
+ let questionNum = 1;
249
+ for (const q of questions) {
250
+ output += `**${questionNum}. ${q.question}**${q.required ? " *(required)*" : ""}\n`;
251
+ if (q.examples && q.examples.length > 0) {
252
+ output += ` Examples:\n`;
253
+ for (const ex of q.examples) {
254
+ output += ` - ${ex}\n`;
255
+ }
256
+ }
257
+ output += ` Answer ID: \`${q.id}\`\n\n`;
258
+ questionNum++;
259
+ }
260
+ output += "\n### How to Provide Answers\n\n";
261
+ output +=
262
+ "Call sdd-init again with clarificationAnswers parameter containing your answers.\n";
263
+ return output;
179
264
  }
180
265
  async handleProjectStatus(args) {
181
266
  const { projectId, projectPath } = args;
182
267
  let project;
183
- if (projectId && typeof projectId === 'string') {
268
+ if (projectId && typeof projectId === "string") {
184
269
  project = await this.projectService.getProject(projectId);
185
270
  }
186
- else if (projectPath && typeof projectPath === 'string') {
271
+ else if (projectPath && typeof projectPath === "string") {
187
272
  project = await this.projectService.getProjectByPath(projectPath);
188
273
  }
189
274
  else {
190
- throw new Error('Either projectId or projectPath must be provided');
275
+ throw new Error("Either projectId or projectPath must be provided");
191
276
  }
192
277
  if (!project) {
193
- return 'Project not found';
278
+ return "Project not found";
194
279
  }
195
280
  const status = await this.workflowService.getWorkflowStatus(project.id);
196
281
  if (!status) {
197
- return 'Unable to get workflow status';
282
+ return "Unable to get workflow status";
198
283
  }
199
284
  let output = `Project: ${project.name}\n`;
200
285
  output += `Current Phase: ${status.currentPhase}\n`;
201
- output += `Next Phase: ${status.nextPhase ?? 'Complete'}\n`;
202
- output += `Can Progress: ${status.canProgress ? 'Yes' : 'No'}\n`;
286
+ output += `Next Phase: ${status.nextPhase ?? "Complete"}\n`;
287
+ output += `Can Progress: ${status.canProgress ? "Yes" : "No"}\n`;
203
288
  if (status.blockers && status.blockers.length > 0) {
204
289
  output += `Blockers:\n`;
205
290
  for (const blocker of status.blockers) {
@@ -210,12 +295,12 @@ let SDDToolAdapter = class SDDToolAdapter {
210
295
  }
211
296
  async handleRequirements(args) {
212
297
  const { projectId } = args;
213
- if (typeof projectId !== 'string') {
214
- throw new Error('Invalid argument: projectId must be a string');
298
+ if (typeof projectId !== "string") {
299
+ throw new Error("Invalid argument: projectId must be a string");
215
300
  }
216
301
  const project = await this.projectService.getProject(projectId);
217
302
  if (!project) {
218
- throw new Error('Project not found');
303
+ throw new Error("Project not found");
219
304
  }
220
305
  // Check if can transition to requirements phase
221
306
  const validation = await this.workflowService.validatePhaseTransition(projectId, WorkflowPhase.REQUIREMENTS);
@@ -224,23 +309,23 @@ let SDDToolAdapter = class SDDToolAdapter {
224
309
  }
225
310
  // Generate requirements template
226
311
  const content = await this.templateService.generateRequirementsTemplate(project);
227
- await this.templateService.writeProjectFile(project, 'requirements.md', content);
312
+ await this.templateService.writeProjectFile(project, "requirements.md", content);
228
313
  // Update project phase and approval status
229
314
  await this.projectService.updateProjectPhase(projectId, WorkflowPhase.REQUIREMENTS);
230
- await this.projectService.updateApprovalStatus(projectId, 'requirements', {
315
+ await this.projectService.updateApprovalStatus(projectId, "requirements", {
231
316
  generated: true,
232
- approved: false
317
+ approved: false,
233
318
  });
234
319
  return `Requirements document generated for project "${project.name}"`;
235
320
  }
236
321
  async handleDesign(args) {
237
322
  const { projectId } = args;
238
- if (typeof projectId !== 'string') {
239
- throw new Error('Invalid argument: projectId must be a string');
323
+ if (typeof projectId !== "string") {
324
+ throw new Error("Invalid argument: projectId must be a string");
240
325
  }
241
326
  const project = await this.projectService.getProject(projectId);
242
327
  if (!project) {
243
- throw new Error('Project not found');
328
+ throw new Error("Project not found");
244
329
  }
245
330
  // Check if can transition to design phase
246
331
  const validation = await this.workflowService.validatePhaseTransition(projectId, WorkflowPhase.DESIGN);
@@ -249,23 +334,23 @@ let SDDToolAdapter = class SDDToolAdapter {
249
334
  }
250
335
  // Generate design template
251
336
  const content = await this.templateService.generateDesignTemplate(project);
252
- await this.templateService.writeProjectFile(project, 'design.md', content);
337
+ await this.templateService.writeProjectFile(project, "design.md", content);
253
338
  // Update project phase and approval status
254
339
  await this.projectService.updateProjectPhase(projectId, WorkflowPhase.DESIGN);
255
- await this.projectService.updateApprovalStatus(projectId, 'design', {
340
+ await this.projectService.updateApprovalStatus(projectId, "design", {
256
341
  generated: true,
257
- approved: false
342
+ approved: false,
258
343
  });
259
344
  return `Design document generated for project "${project.name}"`;
260
345
  }
261
346
  async handleTasks(args) {
262
347
  const { projectId } = args;
263
- if (typeof projectId !== 'string') {
264
- throw new Error('Invalid argument: projectId must be a string');
348
+ if (typeof projectId !== "string") {
349
+ throw new Error("Invalid argument: projectId must be a string");
265
350
  }
266
351
  const project = await this.projectService.getProject(projectId);
267
352
  if (!project) {
268
- throw new Error('Project not found');
353
+ throw new Error("Project not found");
269
354
  }
270
355
  // Check if can transition to tasks phase
271
356
  const validation = await this.workflowService.validatePhaseTransition(projectId, WorkflowPhase.TASKS);
@@ -274,28 +359,28 @@ let SDDToolAdapter = class SDDToolAdapter {
274
359
  }
275
360
  // Generate tasks template
276
361
  const content = await this.templateService.generateTasksTemplate(project);
277
- await this.templateService.writeProjectFile(project, 'tasks.md', content);
362
+ await this.templateService.writeProjectFile(project, "tasks.md", content);
278
363
  // Update project phase and approval status
279
364
  await this.projectService.updateProjectPhase(projectId, WorkflowPhase.TASKS);
280
- await this.projectService.updateApprovalStatus(projectId, 'tasks', {
365
+ await this.projectService.updateApprovalStatus(projectId, "tasks", {
281
366
  generated: true,
282
- approved: false
367
+ approved: false,
283
368
  });
284
369
  return `Tasks document generated for project "${project.name}"`;
285
370
  }
286
371
  async handleQualityCheck(args) {
287
- const { code, language = 'typescript' } = args;
288
- if (typeof code !== 'string') {
289
- throw new Error('Invalid argument: code must be a string');
372
+ const { code, language = "typescript" } = args;
373
+ if (typeof code !== "string") {
374
+ throw new Error("Invalid argument: code must be a string");
290
375
  }
291
376
  const report = await this.qualityService.performQualityCheck({
292
377
  code,
293
- language: language
378
+ language: language,
294
379
  });
295
380
  return this.qualityService.formatQualityReport(report);
296
381
  }
297
382
  async handleSteering(args) {
298
- const { updateMode = 'update' } = args;
383
+ const { updateMode = "update" } = args;
299
384
  const projectPath = process.cwd();
300
385
  try {
301
386
  // Analyze the project
@@ -306,22 +391,22 @@ let SDDToolAdapter = class SDDToolAdapter {
306
391
  const structureContent = await this.generateStructureSteering(analysis);
307
392
  // Create steering documents
308
393
  await this.steeringService.createSteeringDocument(projectPath, {
309
- name: 'product.md',
310
- type: 'PRODUCT',
311
- mode: 'ALWAYS',
312
- content: productContent
394
+ name: "product.md",
395
+ type: "PRODUCT",
396
+ mode: "ALWAYS",
397
+ content: productContent,
313
398
  });
314
399
  await this.steeringService.createSteeringDocument(projectPath, {
315
- name: 'tech.md',
316
- type: 'TECHNICAL',
317
- mode: 'ALWAYS',
318
- content: techContent
400
+ name: "tech.md",
401
+ type: "TECHNICAL",
402
+ mode: "ALWAYS",
403
+ content: techContent,
319
404
  });
320
405
  await this.steeringService.createSteeringDocument(projectPath, {
321
- name: 'structure.md',
322
- type: 'STRUCTURE',
323
- mode: 'ALWAYS',
324
- content: structureContent
406
+ name: "structure.md",
407
+ type: "STRUCTURE",
408
+ mode: "ALWAYS",
409
+ content: structureContent,
325
410
  });
326
411
  // Create static steering documents if they don't exist
327
412
  await this.createStaticSteeringDocuments(projectPath);
@@ -330,11 +415,11 @@ let SDDToolAdapter = class SDDToolAdapter {
330
415
  // Get project info from package.json
331
416
  let packageJson = {};
332
417
  try {
333
- const fs = await import('fs');
334
- const path = await import('path');
335
- const packagePath = path.join(projectPath, 'package.json');
418
+ const fs = await import("fs");
419
+ const path = await import("path");
420
+ const packagePath = path.join(projectPath, "package.json");
336
421
  if (fs.existsSync(packagePath)) {
337
- const packageContent = fs.readFileSync(packagePath, 'utf8');
422
+ const packageContent = fs.readFileSync(packagePath, "utf8");
338
423
  packageJson = JSON.parse(packageContent);
339
424
  }
340
425
  }
@@ -343,31 +428,33 @@ let SDDToolAdapter = class SDDToolAdapter {
343
428
  }
344
429
  return `## Steering Documents Updated
345
430
 
346
- **Project**: ${packageJson.name || 'Unknown'}
431
+ **Project**: ${packageJson.name || "Unknown"}
347
432
  **Mode**: ${updateMode}
348
433
 
349
434
  **Updated Files**:
350
435
  - \`.kiro/steering/product.md\` - Product overview and business context
351
- - \`.kiro/steering/tech.md\` - Technology stack and development environment
436
+ - \`.kiro/steering/tech.md\` - Technology stack and development environment
352
437
  - \`.kiro/steering/structure.md\` - Project organization and architectural decisions
353
438
 
354
439
  **Analysis**:
355
440
  - Technology stack: ${Object.keys({ ...packageJson.dependencies, ...packageJson.devDependencies }).length} dependencies detected
356
- - Project type: ${packageJson.type || 'Unknown'}
441
+ - Project type: ${packageJson.type || "Unknown"}
357
442
  - Existing steering: Updated preserving customizations
358
443
 
359
444
  These steering documents provide consistent project context for all AI interactions and spec-driven development workflows.`;
360
445
  }
361
446
  catch (error) {
362
- this.logger.error('Failed to generate steering documents', error);
447
+ this.logger.error("Failed to generate steering documents", error);
363
448
  throw new Error(`Failed to generate steering documents: ${error.message}`);
364
449
  }
365
450
  }
366
451
  async handleSteeringCustom(args) {
367
452
  const { fileName, topic, inclusionMode, filePattern } = args;
368
453
  const projectPath = process.cwd();
369
- if (typeof fileName !== 'string' || typeof topic !== 'string' || typeof inclusionMode !== 'string') {
370
- throw new Error('Invalid arguments: fileName, topic, and inclusionMode must be strings');
454
+ if (typeof fileName !== "string" ||
455
+ typeof topic !== "string" ||
456
+ typeof inclusionMode !== "string") {
457
+ throw new Error("Invalid arguments: fileName, topic, and inclusionMode must be strings");
371
458
  }
372
459
  const content = `# ${topic}
373
460
 
@@ -382,17 +469,19 @@ Define the purpose and scope of this steering document.
382
469
  Describe when and how this steering document should be applied.
383
470
 
384
471
  ## Inclusion Mode
385
- Mode: ${inclusionMode}${filePattern ? `
386
- Pattern: ${filePattern}` : ''}
472
+ Mode: ${inclusionMode}${filePattern
473
+ ? `
474
+ Pattern: ${filePattern}`
475
+ : ""}
387
476
 
388
477
  Generated on: ${new Date().toISOString()}
389
478
  `;
390
479
  await this.steeringService.createSteeringDocument(projectPath, {
391
480
  name: fileName,
392
- type: 'CUSTOM',
481
+ type: "CUSTOM",
393
482
  mode: inclusionMode.toUpperCase(),
394
483
  patterns: filePattern ? [filePattern] : [],
395
- content
484
+ content,
396
485
  });
397
486
  return `Custom steering document "${fileName}" created successfully with ${inclusionMode} inclusion mode.`;
398
487
  }
@@ -400,11 +489,11 @@ Generated on: ${new Date().toISOString()}
400
489
  // Try to read package.json for project info
401
490
  let packageJson = {};
402
491
  try {
403
- const fs = await import('fs');
404
- const path = await import('path');
405
- const packagePath = path.join(process.cwd(), 'package.json');
492
+ const fs = await import("fs");
493
+ const path = await import("path");
494
+ const packagePath = path.join(process.cwd(), "package.json");
406
495
  if (fs.existsSync(packagePath)) {
407
- const packageContent = fs.readFileSync(packagePath, 'utf8');
496
+ const packageContent = fs.readFileSync(packagePath, "utf8");
408
497
  packageJson = JSON.parse(packageContent);
409
498
  }
410
499
  }
@@ -412,12 +501,14 @@ Generated on: ${new Date().toISOString()}
412
501
  // Ignore errors
413
502
  }
414
503
  return `# Product Overview
415
-
504
+
416
505
  ## Product Description
417
- ${packageJson.description || 'No description available'}
506
+ ${packageJson.description || "No description available"}
418
507
 
419
508
  ## Core Features
420
- ${this.extractFeatures(packageJson, analysis).map((feature) => `- ${feature}`).join('\n')}
509
+ ${this.extractFeatures(packageJson, analysis)
510
+ .map((feature) => `- ${feature}`)
511
+ .join("\n")}
421
512
 
422
513
  ## Target Use Case
423
514
  ${this.generateTargetUseCase(packageJson)}
@@ -432,11 +523,11 @@ ${this.generateTargetUsers(packageJson)}`;
432
523
  // Try to read package.json for project info
433
524
  let packageJson = {};
434
525
  try {
435
- const fs = await import('fs');
436
- const path = await import('path');
437
- const packagePath = path.join(process.cwd(), 'package.json');
526
+ const fs = await import("fs");
527
+ const path = await import("path");
528
+ const packagePath = path.join(process.cwd(), "package.json");
438
529
  if (fs.existsSync(packagePath)) {
439
- const packageContent = fs.readFileSync(packagePath, 'utf8');
530
+ const packageContent = fs.readFileSync(packagePath, "utf8");
440
531
  packageJson = JSON.parse(packageContent);
441
532
  }
442
533
  }
@@ -449,7 +540,7 @@ ${this.generateTargetUsers(packageJson)}`;
449
540
  ${this.generateTechStack(packageJson, analysis)}
450
541
 
451
542
  ## Development Environment
452
- - Node.js: ${packageJson.engines?.node || 'Unknown'}
543
+ - Node.js: ${packageJson.engines?.node || "Unknown"}
453
544
  - Package Manager: npm
454
545
 
455
546
  ## Key Dependencies
@@ -481,124 +572,148 @@ ${this.generateWorkflow(analysis)}`;
481
572
  // Extract features from scripts
482
573
  if (packageJson.scripts) {
483
574
  if (packageJson.scripts.test)
484
- features.push('Testing framework');
575
+ features.push("Testing framework");
485
576
  if (packageJson.scripts.build)
486
- features.push('Build system');
577
+ features.push("Build system");
487
578
  if (packageJson.scripts.dev || packageJson.scripts.start)
488
- features.push('Development server');
579
+ features.push("Development server");
489
580
  if (packageJson.scripts.lint)
490
- features.push('Code linting');
581
+ features.push("Code linting");
491
582
  if (packageJson.scripts.typecheck)
492
- features.push('Type checking');
583
+ features.push("Type checking");
493
584
  }
494
585
  // Extract features from dependencies
495
- const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
586
+ const deps = {
587
+ ...packageJson.dependencies,
588
+ ...packageJson.devDependencies,
589
+ };
496
590
  if (deps?.express || deps?.fastify || deps?.koa)
497
- features.push('Web server');
591
+ features.push("Web server");
498
592
  if (deps?.react || deps?.vue || deps?.angular)
499
- features.push('Frontend framework');
593
+ features.push("Frontend framework");
500
594
  if (deps?.typescript)
501
- features.push('TypeScript support');
595
+ features.push("TypeScript support");
502
596
  if (deps?.jest || deps?.mocha || deps?.vitest)
503
- features.push('Unit testing');
597
+ features.push("Unit testing");
504
598
  if (deps?.eslint)
505
- features.push('Code quality enforcement');
506
- return features.length > 0 ? features : ['Core functionality to be defined'];
599
+ features.push("Code quality enforcement");
600
+ return features.length > 0
601
+ ? features
602
+ : ["Core functionality to be defined"];
507
603
  }
508
604
  generateTargetUseCase(packageJson) {
509
605
  if (packageJson.keywords) {
510
- return `This product is designed for ${packageJson.keywords.join(', ')} use cases.`;
606
+ return `This product is designed for ${packageJson.keywords.join(", ")} use cases.`;
511
607
  }
512
- return 'Target use cases to be defined based on project requirements.';
608
+ return "Target use cases to be defined based on project requirements.";
513
609
  }
514
610
  generateValueProposition(packageJson, analysis) {
515
611
  const features = this.extractFeatures(packageJson, analysis);
516
- return features.map(feature => `- **${feature}**: Enhanced development experience`).join('\n');
612
+ return features
613
+ .map((feature) => `- **${feature}**: Enhanced development experience`)
614
+ .join("\n");
517
615
  }
518
616
  generateTargetUsers(packageJson) {
519
- if (packageJson.keywords?.includes('cli')) {
520
- return '- Command-line tool users\n- Developers and system administrators';
617
+ if (packageJson.keywords?.includes("cli")) {
618
+ return "- Command-line tool users\n- Developers and system administrators";
521
619
  }
522
- if (packageJson.keywords?.includes('api')) {
523
- return '- API consumers\n- Third-party integrators';
620
+ if (packageJson.keywords?.includes("api")) {
621
+ return "- API consumers\n- Third-party integrators";
524
622
  }
525
- return '- Primary user persona\n- Secondary user persona';
623
+ return "- Primary user persona\n- Secondary user persona";
526
624
  }
527
625
  generateTechStack(packageJson, analysis) {
528
- const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
626
+ const deps = {
627
+ ...packageJson.dependencies,
628
+ ...packageJson.devDependencies,
629
+ };
529
630
  const stack = [];
530
631
  if (deps?.typescript)
531
- stack.push('TypeScript');
632
+ stack.push("TypeScript");
532
633
  if (deps?.node || packageJson.engines?.node)
533
- stack.push('Node.js');
634
+ stack.push("Node.js");
534
635
  if (deps?.express)
535
- stack.push('Express.js');
636
+ stack.push("Express.js");
536
637
  if (deps?.react)
537
- stack.push('React');
638
+ stack.push("React");
538
639
  if (deps?.vue)
539
- stack.push('Vue.js');
540
- return stack.length > 0 ? stack.join(', ') : 'Technology stack to be defined';
640
+ stack.push("Vue.js");
641
+ return stack.length > 0
642
+ ? stack.join(", ")
643
+ : "Technology stack to be defined";
541
644
  }
542
645
  generateDependencyList(packageJson) {
543
646
  const production = Object.keys(packageJson.dependencies || {});
544
647
  const development = Object.keys(packageJson.devDependencies || {});
545
- let list = '';
648
+ let list = "";
546
649
  if (production.length > 0) {
547
- list += '### Production Dependencies\n';
548
- list += production.slice(0, 10).map((dep) => `- ${dep}`).join('\n');
650
+ list += "### Production Dependencies\n";
651
+ list += production
652
+ .slice(0, 10)
653
+ .map((dep) => `- ${dep}`)
654
+ .join("\n");
549
655
  }
550
656
  if (development.length > 0) {
551
- list += '\n### Development Dependencies\n';
552
- list += development.slice(0, 10).map((dep) => `- ${dep}`).join('\n');
657
+ list += "\n### Development Dependencies\n";
658
+ list += development
659
+ .slice(0, 10)
660
+ .map((dep) => `- ${dep}`)
661
+ .join("\n");
553
662
  }
554
- return list || 'Dependencies to be analyzed';
663
+ return list || "Dependencies to be analyzed";
555
664
  }
556
665
  generateArchitecturePatterns(analysis) {
557
666
  const patterns = [];
558
667
  // Try to analyze directory structure from filesystem
559
668
  try {
560
- const fs = require('fs');
669
+ const fs = require("fs");
561
670
  const projectPath = process.cwd();
562
671
  const items = fs.readdirSync(projectPath, { withFileTypes: true });
563
672
  const directories = items
564
673
  .filter((item) => item.isDirectory())
565
674
  .map((item) => item.name);
566
- if (directories.includes('src'))
567
- patterns.push('Source code organization');
568
- if (directories.includes('test') || directories.includes('__tests__'))
569
- patterns.push('Test-driven development');
570
- if (directories.includes('dist') || directories.includes('build'))
571
- patterns.push('Build artifact separation');
675
+ if (directories.includes("src"))
676
+ patterns.push("Source code organization");
677
+ if (directories.includes("test") || directories.includes("__tests__"))
678
+ patterns.push("Test-driven development");
679
+ if (directories.includes("dist") || directories.includes("build"))
680
+ patterns.push("Build artifact separation");
572
681
  }
573
682
  catch (error) {
574
683
  // Ignore filesystem errors
575
684
  }
576
- return patterns.length > 0 ? patterns.map(p => `- ${p}`).join('\n') : '- Patterns to be defined';
685
+ return patterns.length > 0
686
+ ? patterns.map((p) => `- ${p}`).join("\n")
687
+ : "- Patterns to be defined";
577
688
  }
578
689
  generateQualityStandards(packageJson) {
579
690
  const standards = [];
580
691
  if (packageJson.scripts?.lint)
581
- standards.push('Code linting with ESLint');
692
+ standards.push("Code linting with ESLint");
582
693
  if (packageJson.scripts?.typecheck)
583
- standards.push('Type checking with TypeScript');
694
+ standards.push("Type checking with TypeScript");
584
695
  if (packageJson.scripts?.test)
585
- standards.push('Unit testing required');
586
- return standards.length > 0 ? standards.map(s => `- ${s}`).join('\n') : '- Quality standards to be defined';
696
+ standards.push("Unit testing required");
697
+ return standards.length > 0
698
+ ? standards.map((s) => `- ${s}`).join("\n")
699
+ : "- Quality standards to be defined";
587
700
  }
588
701
  generateDirectoryStructure(analysis) {
589
702
  // Try to get directory structure from filesystem
590
703
  try {
591
- const fs = require('fs');
704
+ const fs = require("fs");
592
705
  const projectPath = process.cwd();
593
706
  const items = fs.readdirSync(projectPath, { withFileTypes: true });
594
707
  const directories = items
595
- .filter((item) => item.isDirectory() && !item.name.startsWith('.') && item.name !== 'node_modules')
708
+ .filter((item) => item.isDirectory() &&
709
+ !item.name.startsWith(".") &&
710
+ item.name !== "node_modules")
596
711
  .map((item) => `- ${item.name}/`)
597
- .join('\n');
598
- return directories || 'Directory structure to be analyzed';
712
+ .join("\n");
713
+ return directories || "Directory structure to be analyzed";
599
714
  }
600
715
  catch (error) {
601
- return 'Directory structure to be analyzed';
716
+ return "Directory structure to be analyzed";
602
717
  }
603
718
  }
604
719
  generateNamingConventions(analysis) {
@@ -617,11 +732,11 @@ ${this.generateWorkflow(analysis)}`;
617
732
  // Try to read package.json for scripts
618
733
  let packageJson = {};
619
734
  try {
620
- const fs = require('fs');
621
- const path = require('path');
622
- const packagePath = path.join(process.cwd(), 'package.json');
735
+ const fs = require("fs");
736
+ const path = require("path");
737
+ const packagePath = path.join(process.cwd(), "package.json");
623
738
  if (fs.existsSync(packagePath)) {
624
- const packageContent = fs.readFileSync(packagePath, 'utf8');
739
+ const packageContent = fs.readFileSync(packagePath, "utf8");
625
740
  packageJson = JSON.parse(packageContent);
626
741
  }
627
742
  }
@@ -629,7 +744,7 @@ ${this.generateWorkflow(analysis)}`;
629
744
  // Ignore errors
630
745
  }
631
746
  const scripts = packageJson.scripts || {};
632
- let workflow = '## Development Commands\n';
747
+ let workflow = "## Development Commands\n";
633
748
  if (scripts.dev)
634
749
  workflow += `- \`npm run dev\` - Start development server\n`;
635
750
  if (scripts.build)
@@ -641,261 +756,26 @@ ${this.generateWorkflow(analysis)}`;
641
756
  return workflow;
642
757
  }
643
758
  async createStaticSteeringDocuments(projectPath) {
644
- const fs = await import('fs');
645
- const path = await import('path');
646
- // Check if linus-review.md exists, if not create it
647
- const linusReviewPath = path.join(projectPath, '.kiro', 'steering', 'linus-review.md');
648
- if (!fs.existsSync(linusReviewPath)) {
649
- const linusReviewContent = `# Linus Torvalds Code Review Steering Document
650
-
651
- ## Role Definition
652
-
653
- You are channeling Linus Torvalds, creator and chief architect of the Linux kernel. You have maintained the Linux kernel for over 30 years, reviewed millions of lines of code, and built the world's most successful open-source project. Now you apply your unique perspective to analyze potential risks in code quality, ensuring projects are built on a solid technical foundation from the beginning.
654
-
655
- ## Core Philosophy
656
-
657
- **1. "Good Taste" - The First Principle**
658
- "Sometimes you can look at a problem from a different angle, rewrite it to make special cases disappear and become normal cases."
659
- - Classic example: Linked list deletion, optimized from 10 lines with if statements to 4 lines without conditional branches
660
- - Good taste is an intuition that requires accumulated experience
661
- - Eliminating edge cases is always better than adding conditional checks
662
-
663
- **2. "Never break userspace" - The Iron Rule**
664
- "We do not break userspace!"
665
- - Any change that crashes existing programs is a bug, no matter how "theoretically correct"
666
- - The kernel's duty is to serve users, not educate them
667
- - Backward compatibility is sacred and inviolable
668
-
669
- **3. Pragmatism - The Belief**
670
- "I'm a damn pragmatist."
671
- - Solve actual problems, not imagined threats
672
- - Reject "theoretically perfect" but practically complex solutions like microkernels
673
- - Code should serve reality, not papers
674
-
675
- **4. Simplicity Obsession - The Standard**
676
- "If you need more than 3 levels of indentation, you're screwed and should fix your program."
677
- - Functions must be short and focused, do one thing and do it well
678
- - C is a Spartan language, naming should be too
679
- - Complexity is the root of all evil
680
-
681
- ## Communication Principles
682
-
683
- ### Basic Communication Standards
684
-
685
- - **Expression Style**: Direct, sharp, zero nonsense. If code is garbage, call it garbage and explain why.
686
- - **Technical Priority**: Criticism is always about technical issues, not personal. Don't blur technical judgment for "niceness."
687
-
688
- ### Requirements Confirmation Process
689
-
690
- When analyzing any code or technical need, follow these steps:
691
-
692
- #### 0. **Thinking Premise - Linus's Three Questions**
693
- Before starting any analysis, ask yourself:
694
- 1. "Is this a real problem or imagined?" - Reject over-engineering
695
- 2. "Is there a simpler way?" - Always seek the simplest solution
696
- 3. "Will it break anything?" - Backward compatibility is the iron rule
697
-
698
- #### 1. **Requirements Understanding**
699
- Based on the existing information, understand the requirement and restate it using Linus's thinking/communication style.
700
-
701
- #### 2. **Linus-style Problem Decomposition Thinking**
702
-
703
- **First Layer: Data Structure Analysis**
704
- "Bad programmers worry about the code. Good programmers worry about data structures."
705
-
706
- - What is the core data? How do they relate?
707
- - Where does data flow? Who owns it? Who modifies it?
708
- - Is there unnecessary data copying or transformation?
709
-
710
- **Second Layer: Special Case Identification**
711
- "Good code has no special cases"
712
-
713
- - Find all if/else branches
714
- - Which are real business logic? Which are patches for bad design?
715
- - Can we redesign data structures to eliminate these branches?
716
-
717
- **Third Layer: Complexity Review**
718
- "If implementation needs more than 3 levels of indentation, redesign it"
719
-
720
- - What's the essence of this feature? (Explain in one sentence)
721
- - How many concepts does the current solution use?
722
- - Can it be reduced by half? Half again?
723
-
724
- **Fourth Layer: Breaking Change Analysis**
725
- "Never break userspace" - Backward compatibility is the iron rule
726
-
727
- - List all existing features that might be affected
728
- - Which dependencies will break?
729
- - How to improve without breaking anything?
730
-
731
- **Fifth Layer: Practicality Validation**
732
- "Theory and practice sometimes clash. Theory loses. Every single time."
733
-
734
- - Does this problem really exist in production?
735
- - How many users actually encounter this problem?
736
- - Does the solution's complexity match the problem's severity?
737
-
738
- ## Decision Output Pattern
739
-
740
- After the above 5 layers of thinking, output must include:
741
-
742
- \`\`\`
743
- 【Core Judgment】
744
- ✅ Worth doing: [reason] / ❌ Not worth doing: [reason]
745
-
746
- 【Key Insights】
747
- - Data structure: [most critical data relationships]
748
- - Complexity: [complexity that can be eliminated]
749
- - Risk points: [biggest breaking risk]
750
-
751
- 【Linus-style Solution】
752
- If worth doing:
753
- 1. First step is always simplifying data structures
754
- 2. Eliminate all special cases
755
- 3. Implement in the dumbest but clearest way
756
- 4. Ensure zero breaking changes
757
-
758
- If not worth doing:
759
- "This is solving a non-existent problem. The real problem is [XXX]."
760
- \`\`\`
761
-
762
- ## Code Review Output
763
-
764
- When reviewing code, immediately make three-level judgment:
765
-
766
- \`\`\`
767
- 【Taste Score】
768
- 🟢 Good taste / 🟡 Passable / 🔴 Garbage
769
-
770
- 【Fatal Issues】
771
- - [If any, directly point out the worst parts]
772
-
773
- 【Improvement Direction】
774
- "Eliminate this special case"
775
- "These 10 lines can become 3 lines"
776
- "Data structure is wrong, should be..."
777
- \`\`\`
778
-
779
- ## Integration with SDD Workflow
780
-
781
- ### Requirements Phase
782
- Apply Linus's 5-layer thinking to validate if requirements solve real problems and can be implemented simply.
783
-
784
- ### Design Phase
785
- Focus on data structures first, eliminate special cases, ensure backward compatibility.
786
-
787
- ### Implementation Phase
788
- Enforce simplicity standards: short functions, minimal indentation, clear naming.
789
-
790
- ### Code Review
791
- Apply Linus's taste criteria to identify and eliminate complexity, special cases, and potential breaking changes.
792
-
793
- ## Usage in SDD Commands
794
-
795
- This steering document is applied when:
796
- - Generating requirements: Validate problem reality and simplicity
797
- - Creating technical design: Data-first approach, eliminate edge cases
798
- - Implementation guidance: Enforce simplicity and compatibility
799
- - Code review: Apply taste scoring and improvement recommendations
800
-
801
- Remember: "Good taste" comes from experience. Question everything. Simplify ruthlessly. Never break userspace.
802
- `;
803
- await this.steeringService.createSteeringDocument(projectPath, {
804
- name: 'linus-review.md',
805
- type: 'LINUS_REVIEW',
806
- mode: 'ALWAYS',
807
- content: linusReviewContent
808
- });
809
- }
810
- // Check if commit.md exists, if not create it
811
- const commitPath = path.join(projectPath, '.kiro', 'steering', 'commit.md');
812
- if (!fs.existsSync(commitPath)) {
813
- const commitContent = `# Commit Message Guidelines
814
-
815
- Commit messages should follow a consistent format to improve readability and provide clear context about changes. Each commit message should start with a type prefix that indicates the nature of the change.
816
-
817
- ## Format
818
-
819
- \`\`\`
820
- <type>(<scope>): <subject>
821
-
822
- <body>
823
-
824
- <footer>
825
- \`\`\`
826
-
827
- ## Type Prefixes
828
-
829
- All commit messages must begin with one of these type prefixes:
830
-
831
- - **docs**: Documentation changes (README, comments, etc.)
832
- - **chore**: Maintenance tasks, dependency updates, etc.
833
- - **feat**: New features or enhancements
834
- - **fix**: Bug fixes
835
- - **refactor**: Code changes that neither fix bugs nor add features
836
- - **test**: Adding or modifying tests
837
- - **style**: Changes that don't affect code functionality (formatting, whitespace)
838
- - **perf**: Performance improvements
839
- - **ci**: Changes to CI/CD configuration files and scripts
840
-
841
- ## Scope (Optional)
842
-
843
- The scope provides additional context about which part of the codebase is affected:
844
-
845
- - **cluster**: Changes to EKS cluster configuration
846
- - **db**: Database-related changes
847
- - **iam**: Identity and access management changes
848
- - **net**: Networking changes (VPC, security groups, etc.)
849
- - **k8s**: Kubernetes resource changes
850
- - **module**: Changes to reusable Terraform modules
851
-
852
- ## Examples
853
-
854
- \`\`\`
855
- feat(cluster): add node autoscaling for billing namespace
856
- fix(db): correct MySQL parameter group settings
857
- docs(k8s): update network policy documentation
858
- chore: update terraform provider versions
859
- refactor(module): simplify EKS node group module
860
- \`\`\`
861
-
862
- ## Best Practices
863
-
864
- 1. Keep the subject line under 72 characters
865
- 2. Use imperative mood in the subject line ("add" not "added")
866
- 3. Don't end the subject line with a period
867
- 4. Separate subject from body with a blank line
868
- 5. Use the body to explain what and why, not how
869
- 6. Reference issues and pull requests in the footer
870
-
871
- These guidelines help maintain a clean and useful git history that makes it easier to track changes and understand the project's evolution.
872
- `;
873
- await this.steeringService.createSteeringDocument(projectPath, {
874
- name: 'commit.md',
875
- type: 'CUSTOM',
876
- mode: 'ALWAYS',
877
- content: commitContent
878
- });
879
- }
759
+ await ensureStaticSteeringDocuments(projectPath, this.steeringService);
880
760
  }
881
761
  async createAgentsFile(projectPath) {
882
- const fs = await import('fs');
883
- const path = await import('path');
762
+ const fs = await import("fs");
763
+ const path = await import("path");
884
764
  // Check if AGENTS.md exists, if not create it based on CLAUDE.md
885
- const agentsPath = path.join(projectPath, 'AGENTS.md');
765
+ const agentsPath = path.join(projectPath, "AGENTS.md");
886
766
  if (!fs.existsSync(agentsPath)) {
887
767
  // Try to read CLAUDE.md to use as template
888
- const claudePath = path.join(projectPath, 'CLAUDE.md');
889
- let agentsContent = '';
768
+ const claudePath = path.join(projectPath, "CLAUDE.md");
769
+ let agentsContent = "";
890
770
  if (fs.existsSync(claudePath)) {
891
771
  // Read CLAUDE.md and adapt it for general agents
892
- const claudeContent = fs.readFileSync(claudePath, 'utf8');
772
+ const claudeContent = fs.readFileSync(claudePath, "utf8");
893
773
  agentsContent = claudeContent
894
- .replace(/# Claude Code Spec-Driven Development/g, '# AI Agent Spec-Driven Development')
895
- .replace(/Claude Code/g, 'AI Agent')
896
- .replace(/claude code/g, 'ai agent')
897
- .replace(/Claude/g, 'AI Agent')
898
- .replace(/claude/g, 'ai agent');
774
+ .replace(/# Claude Code Spec-Driven Development/g, "# AI Agent Spec-Driven Development")
775
+ .replace(/Claude Code/g, "AI Agent")
776
+ .replace(/claude code/g, "ai agent")
777
+ .replace(/Claude/g, "AI Agent")
778
+ .replace(/claude/g, "ai agent");
899
779
  }
900
780
  else {
901
781
  // Fallback to basic template if CLAUDE.md doesn't exist
@@ -912,7 +792,7 @@ Kiro-style Spec Driven Development implementation for AI agents across different
912
792
 
913
793
  ### Steering vs Specification
914
794
 
915
- **Steering** (\`.kiro/steering/\`) - Guide AI with project-wide rules and context
795
+ **Steering** (\`.kiro/steering/\`) - Guide AI with project-wide rules and context
916
796
  **Specs** (\`.kiro/specs/\`) - Formalize development process for individual features
917
797
 
918
798
  ### Active Specifications
@@ -928,7 +808,7 @@ Kiro-style Spec Driven Development implementation for AI agents across different
928
808
  ## Workflow
929
809
 
930
810
  ### Phase 0: Steering (Optional)
931
- Agent steering commands - Create/update steering documents
811
+ Agent steering commands - Create/update steering documents
932
812
  Agent steering-custom commands - Create custom steering for specialized contexts
933
813
 
934
814
  Note: Optional for new features or small additions. You can proceed directly to spec-init.
@@ -965,7 +845,7 @@ Managed by agent steering commands. Updates here reflect command changes.
965
845
 
966
846
  ### Custom Steering Files
967
847
  <!-- Added by agent steering-custom commands -->
968
- <!-- Format:
848
+ <!-- Format:
969
849
  - \`filename.md\`: Mode - Pattern(s) - Description
970
850
  Mode: Always|Conditional|Manual
971
851
  Pattern: File patterns for Conditional mode
@@ -991,13 +871,15 @@ SDDToolAdapter = __decorate([
991
871
  __param(3, inject(TYPES.QualityService)),
992
872
  __param(4, inject(TYPES.SteeringDocumentService)),
993
873
  __param(5, inject(TYPES.CodebaseAnalysisService)),
994
- __param(6, inject(TYPES.LoggerPort)),
874
+ __param(6, inject(TYPES.RequirementsClarificationService)),
875
+ __param(7, inject(TYPES.LoggerPort)),
995
876
  __metadata("design:paramtypes", [ProjectService,
996
877
  WorkflowService,
997
878
  TemplateService,
998
879
  QualityService,
999
880
  SteeringDocumentService,
1000
- CodebaseAnalysisService, Object])
881
+ CodebaseAnalysisService,
882
+ RequirementsClarificationService, Object])
1001
883
  ], SDDToolAdapter);
1002
884
  export { SDDToolAdapter };
1003
885
  //# sourceMappingURL=SDDToolAdapter.js.map