sdd-mcp-server 1.4.5 → 1.5.1

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.
@@ -11,16 +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';
23
- import { ensureStaticSteeringDocuments } from '../../application/services/staticSteering.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";
24
25
  let SDDToolAdapter = class SDDToolAdapter {
25
26
  projectService;
26
27
  workflowService;
@@ -28,179 +29,262 @@ let SDDToolAdapter = class SDDToolAdapter {
28
29
  qualityService;
29
30
  steeringService;
30
31
  codebaseAnalysisService;
32
+ clarificationService;
31
33
  logger;
32
- constructor(projectService, workflowService, templateService, qualityService, steeringService, codebaseAnalysisService, logger) {
34
+ constructor(projectService, workflowService, templateService, qualityService, steeringService, codebaseAnalysisService, clarificationService, logger) {
33
35
  this.projectService = projectService;
34
36
  this.workflowService = workflowService;
35
37
  this.templateService = templateService;
36
38
  this.qualityService = qualityService;
37
39
  this.steeringService = steeringService;
38
40
  this.codebaseAnalysisService = codebaseAnalysisService;
41
+ this.clarificationService = clarificationService;
39
42
  this.logger = logger;
40
43
  }
41
44
  getSDDTools() {
42
45
  return [
43
46
  {
44
- name: 'sdd-init',
47
+ name: "sdd-init",
45
48
  tool: {
46
- name: 'sdd-init',
47
- description: 'Initialize a new SDD project from description',
49
+ name: "sdd-init",
50
+ description: "Initialize a new SDD project with interactive requirements clarification",
48
51
  inputSchema: {
49
- type: 'object',
52
+ type: "object",
50
53
  properties: {
51
- 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
+ },
52
67
  },
53
- required: ['description']
54
- }
68
+ required: ["projectName"],
69
+ },
55
70
  },
56
- handler: this.handleProjectInit.bind(this)
71
+ handler: this.handleProjectInit.bind(this),
57
72
  },
58
73
  {
59
- name: 'sdd-status',
74
+ name: "sdd-status",
60
75
  tool: {
61
- name: 'sdd-status',
62
- description: 'Get current project status and workflow phase information',
76
+ name: "sdd-status",
77
+ description: "Get current project status and workflow phase information",
63
78
  inputSchema: {
64
- type: 'object',
79
+ type: "object",
65
80
  properties: {
66
- projectId: { type: 'string', description: 'Project ID' },
67
- projectPath: { type: 'string', description: 'Project path (alternative to ID)' }
68
- }
69
- }
81
+ projectId: { type: "string", description: "Project ID" },
82
+ projectPath: {
83
+ type: "string",
84
+ description: "Project path (alternative to ID)",
85
+ },
86
+ },
87
+ },
70
88
  },
71
- handler: this.handleProjectStatus.bind(this)
89
+ handler: this.handleProjectStatus.bind(this),
72
90
  },
73
91
  {
74
- name: 'sdd-requirements',
92
+ name: "sdd-requirements",
75
93
  tool: {
76
- name: 'sdd-requirements',
77
- description: 'Generate requirements doc',
94
+ name: "sdd-requirements",
95
+ description: "Generate requirements doc",
78
96
  inputSchema: {
79
- type: 'object',
97
+ type: "object",
80
98
  properties: {
81
- featureName: { type: 'string', description: 'Feature name' }
99
+ featureName: { type: "string", description: "Feature name" },
82
100
  },
83
- required: ['featureName']
84
- }
101
+ required: ["featureName"],
102
+ },
85
103
  },
86
- handler: this.handleRequirements.bind(this)
104
+ handler: this.handleRequirements.bind(this),
87
105
  },
88
106
  {
89
- name: 'sdd-design',
107
+ name: "sdd-design",
90
108
  tool: {
91
- name: 'sdd-design',
92
- description: 'Create design specifications',
109
+ name: "sdd-design",
110
+ description: "Create design specifications",
93
111
  inputSchema: {
94
- type: 'object',
112
+ type: "object",
95
113
  properties: {
96
- featureName: { type: 'string', description: 'Feature name' }
114
+ featureName: { type: "string", description: "Feature name" },
97
115
  },
98
- required: ['featureName']
99
- }
116
+ required: ["featureName"],
117
+ },
100
118
  },
101
- handler: this.handleDesign.bind(this)
119
+ handler: this.handleDesign.bind(this),
102
120
  },
103
121
  {
104
- name: 'sdd-tasks',
122
+ name: "sdd-tasks",
105
123
  tool: {
106
- name: 'sdd-tasks',
107
- description: 'Generate task breakdown',
124
+ name: "sdd-tasks",
125
+ description: "Generate task breakdown",
108
126
  inputSchema: {
109
- type: 'object',
127
+ type: "object",
110
128
  properties: {
111
- featureName: { type: 'string', description: 'Feature name' }
129
+ featureName: { type: "string", description: "Feature name" },
112
130
  },
113
- required: ['featureName']
114
- }
131
+ required: ["featureName"],
132
+ },
115
133
  },
116
- handler: this.handleTasks.bind(this)
134
+ handler: this.handleTasks.bind(this),
117
135
  },
118
136
  {
119
- name: 'sdd-quality-check',
137
+ name: "sdd-quality-check",
120
138
  tool: {
121
- name: 'sdd-quality-check',
122
- description: 'Perform Linus-style code quality analysis',
139
+ name: "sdd-quality-check",
140
+ description: "Perform Linus-style code quality analysis",
123
141
  inputSchema: {
124
- type: 'object',
142
+ type: "object",
125
143
  properties: {
126
- code: { type: 'string', description: 'Code to analyze' },
127
- language: { type: 'string', description: 'Programming language' }
144
+ code: { type: "string", description: "Code to analyze" },
145
+ language: { type: "string", description: "Programming language" },
128
146
  },
129
- required: ['code']
130
- }
147
+ required: ["code"],
148
+ },
131
149
  },
132
- handler: this.handleQualityCheck.bind(this)
150
+ handler: this.handleQualityCheck.bind(this),
133
151
  },
134
152
  {
135
- name: 'sdd-steering',
153
+ name: "sdd-steering",
136
154
  tool: {
137
- name: 'sdd-steering',
138
- description: 'Create/update steering documents with project-specific analysis',
155
+ name: "sdd-steering",
156
+ description: "Create/update steering documents with project-specific analysis",
139
157
  inputSchema: {
140
- type: 'object',
158
+ type: "object",
141
159
  properties: {
142
- updateMode: { type: 'string', enum: ['create', 'update'], description: 'Whether to create new or update existing documents' }
143
- }
144
- }
160
+ updateMode: {
161
+ type: "string",
162
+ enum: ["create", "update"],
163
+ description: "Whether to create new or update existing documents",
164
+ },
165
+ },
166
+ },
145
167
  },
146
- handler: this.handleSteering.bind(this)
168
+ handler: this.handleSteering.bind(this),
147
169
  },
148
170
  {
149
- name: 'sdd-steering-custom',
171
+ name: "sdd-steering-custom",
150
172
  tool: {
151
- name: 'sdd-steering-custom',
152
- description: 'Create custom steering documents for specialized contexts',
173
+ name: "sdd-steering-custom",
174
+ description: "Create custom steering documents for specialized contexts",
153
175
  inputSchema: {
154
- type: 'object',
176
+ type: "object",
155
177
  properties: {
156
- fileName: { type: 'string', description: 'Filename for the custom steering document' },
157
- topic: { type: 'string', description: 'Topic/purpose of the custom steering document' },
158
- inclusionMode: { type: 'string', enum: ['always', 'conditional', 'manual'], description: 'How this steering document should be included' },
159
- 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
+ },
160
195
  },
161
- required: ['fileName', 'topic', 'inclusionMode']
162
- }
196
+ required: ["fileName", "topic", "inclusionMode"],
197
+ },
163
198
  },
164
- handler: this.handleSteeringCustom.bind(this)
165
- }
199
+ handler: this.handleSteeringCustom.bind(this),
200
+ },
166
201
  ];
167
202
  }
168
203
  async handleProjectInit(args) {
169
- const { name, path, language = 'en' } = args;
170
- if (typeof name !== 'string' || typeof path !== 'string') {
171
- 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
+ }
216
+ }
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
+ }
172
229
  }
173
- const project = await this.projectService.createProject(name, path, language);
230
+ // Create project with enriched description
231
+ const project = await this.projectService.createProject(projectName, currentPath, "en");
174
232
  // Generate initial spec.json
175
233
  const specContent = await this.templateService.generateSpecJson(project);
176
- await this.templateService.writeProjectFile(project, 'spec.json', specContent);
234
+ await this.templateService.writeProjectFile(project, "spec.json", specContent);
177
235
  // Create AGENTS.md if it doesn't exist
178
- await this.createAgentsFile(path);
179
- 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;
180
264
  }
181
265
  async handleProjectStatus(args) {
182
266
  const { projectId, projectPath } = args;
183
267
  let project;
184
- if (projectId && typeof projectId === 'string') {
268
+ if (projectId && typeof projectId === "string") {
185
269
  project = await this.projectService.getProject(projectId);
186
270
  }
187
- else if (projectPath && typeof projectPath === 'string') {
271
+ else if (projectPath && typeof projectPath === "string") {
188
272
  project = await this.projectService.getProjectByPath(projectPath);
189
273
  }
190
274
  else {
191
- throw new Error('Either projectId or projectPath must be provided');
275
+ throw new Error("Either projectId or projectPath must be provided");
192
276
  }
193
277
  if (!project) {
194
- return 'Project not found';
278
+ return "Project not found";
195
279
  }
196
280
  const status = await this.workflowService.getWorkflowStatus(project.id);
197
281
  if (!status) {
198
- return 'Unable to get workflow status';
282
+ return "Unable to get workflow status";
199
283
  }
200
284
  let output = `Project: ${project.name}\n`;
201
285
  output += `Current Phase: ${status.currentPhase}\n`;
202
- output += `Next Phase: ${status.nextPhase ?? 'Complete'}\n`;
203
- 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`;
204
288
  if (status.blockers && status.blockers.length > 0) {
205
289
  output += `Blockers:\n`;
206
290
  for (const blocker of status.blockers) {
@@ -211,12 +295,12 @@ let SDDToolAdapter = class SDDToolAdapter {
211
295
  }
212
296
  async handleRequirements(args) {
213
297
  const { projectId } = args;
214
- if (typeof projectId !== 'string') {
215
- 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");
216
300
  }
217
301
  const project = await this.projectService.getProject(projectId);
218
302
  if (!project) {
219
- throw new Error('Project not found');
303
+ throw new Error("Project not found");
220
304
  }
221
305
  // Check if can transition to requirements phase
222
306
  const validation = await this.workflowService.validatePhaseTransition(projectId, WorkflowPhase.REQUIREMENTS);
@@ -225,23 +309,23 @@ let SDDToolAdapter = class SDDToolAdapter {
225
309
  }
226
310
  // Generate requirements template
227
311
  const content = await this.templateService.generateRequirementsTemplate(project);
228
- await this.templateService.writeProjectFile(project, 'requirements.md', content);
312
+ await this.templateService.writeProjectFile(project, "requirements.md", content);
229
313
  // Update project phase and approval status
230
314
  await this.projectService.updateProjectPhase(projectId, WorkflowPhase.REQUIREMENTS);
231
- await this.projectService.updateApprovalStatus(projectId, 'requirements', {
315
+ await this.projectService.updateApprovalStatus(projectId, "requirements", {
232
316
  generated: true,
233
- approved: false
317
+ approved: false,
234
318
  });
235
319
  return `Requirements document generated for project "${project.name}"`;
236
320
  }
237
321
  async handleDesign(args) {
238
322
  const { projectId } = args;
239
- if (typeof projectId !== 'string') {
240
- 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");
241
325
  }
242
326
  const project = await this.projectService.getProject(projectId);
243
327
  if (!project) {
244
- throw new Error('Project not found');
328
+ throw new Error("Project not found");
245
329
  }
246
330
  // Check if can transition to design phase
247
331
  const validation = await this.workflowService.validatePhaseTransition(projectId, WorkflowPhase.DESIGN);
@@ -250,23 +334,23 @@ let SDDToolAdapter = class SDDToolAdapter {
250
334
  }
251
335
  // Generate design template
252
336
  const content = await this.templateService.generateDesignTemplate(project);
253
- await this.templateService.writeProjectFile(project, 'design.md', content);
337
+ await this.templateService.writeProjectFile(project, "design.md", content);
254
338
  // Update project phase and approval status
255
339
  await this.projectService.updateProjectPhase(projectId, WorkflowPhase.DESIGN);
256
- await this.projectService.updateApprovalStatus(projectId, 'design', {
340
+ await this.projectService.updateApprovalStatus(projectId, "design", {
257
341
  generated: true,
258
- approved: false
342
+ approved: false,
259
343
  });
260
344
  return `Design document generated for project "${project.name}"`;
261
345
  }
262
346
  async handleTasks(args) {
263
347
  const { projectId } = args;
264
- if (typeof projectId !== 'string') {
265
- 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");
266
350
  }
267
351
  const project = await this.projectService.getProject(projectId);
268
352
  if (!project) {
269
- throw new Error('Project not found');
353
+ throw new Error("Project not found");
270
354
  }
271
355
  // Check if can transition to tasks phase
272
356
  const validation = await this.workflowService.validatePhaseTransition(projectId, WorkflowPhase.TASKS);
@@ -275,28 +359,28 @@ let SDDToolAdapter = class SDDToolAdapter {
275
359
  }
276
360
  // Generate tasks template
277
361
  const content = await this.templateService.generateTasksTemplate(project);
278
- await this.templateService.writeProjectFile(project, 'tasks.md', content);
362
+ await this.templateService.writeProjectFile(project, "tasks.md", content);
279
363
  // Update project phase and approval status
280
364
  await this.projectService.updateProjectPhase(projectId, WorkflowPhase.TASKS);
281
- await this.projectService.updateApprovalStatus(projectId, 'tasks', {
365
+ await this.projectService.updateApprovalStatus(projectId, "tasks", {
282
366
  generated: true,
283
- approved: false
367
+ approved: false,
284
368
  });
285
369
  return `Tasks document generated for project "${project.name}"`;
286
370
  }
287
371
  async handleQualityCheck(args) {
288
- const { code, language = 'typescript' } = args;
289
- if (typeof code !== 'string') {
290
- 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");
291
375
  }
292
376
  const report = await this.qualityService.performQualityCheck({
293
377
  code,
294
- language: language
378
+ language: language,
295
379
  });
296
380
  return this.qualityService.formatQualityReport(report);
297
381
  }
298
382
  async handleSteering(args) {
299
- const { updateMode = 'update' } = args;
383
+ const { updateMode = "update" } = args;
300
384
  const projectPath = process.cwd();
301
385
  try {
302
386
  // Analyze the project
@@ -307,22 +391,22 @@ let SDDToolAdapter = class SDDToolAdapter {
307
391
  const structureContent = await this.generateStructureSteering(analysis);
308
392
  // Create steering documents
309
393
  await this.steeringService.createSteeringDocument(projectPath, {
310
- name: 'product.md',
311
- type: 'PRODUCT',
312
- mode: 'ALWAYS',
313
- content: productContent
394
+ name: "product.md",
395
+ type: "PRODUCT",
396
+ mode: "ALWAYS",
397
+ content: productContent,
314
398
  });
315
399
  await this.steeringService.createSteeringDocument(projectPath, {
316
- name: 'tech.md',
317
- type: 'TECHNICAL',
318
- mode: 'ALWAYS',
319
- content: techContent
400
+ name: "tech.md",
401
+ type: "TECHNICAL",
402
+ mode: "ALWAYS",
403
+ content: techContent,
320
404
  });
321
405
  await this.steeringService.createSteeringDocument(projectPath, {
322
- name: 'structure.md',
323
- type: 'STRUCTURE',
324
- mode: 'ALWAYS',
325
- content: structureContent
406
+ name: "structure.md",
407
+ type: "STRUCTURE",
408
+ mode: "ALWAYS",
409
+ content: structureContent,
326
410
  });
327
411
  // Create static steering documents if they don't exist
328
412
  await this.createStaticSteeringDocuments(projectPath);
@@ -331,11 +415,11 @@ let SDDToolAdapter = class SDDToolAdapter {
331
415
  // Get project info from package.json
332
416
  let packageJson = {};
333
417
  try {
334
- const fs = await import('fs');
335
- const path = await import('path');
336
- 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");
337
421
  if (fs.existsSync(packagePath)) {
338
- const packageContent = fs.readFileSync(packagePath, 'utf8');
422
+ const packageContent = fs.readFileSync(packagePath, "utf8");
339
423
  packageJson = JSON.parse(packageContent);
340
424
  }
341
425
  }
@@ -344,31 +428,33 @@ let SDDToolAdapter = class SDDToolAdapter {
344
428
  }
345
429
  return `## Steering Documents Updated
346
430
 
347
- **Project**: ${packageJson.name || 'Unknown'}
431
+ **Project**: ${packageJson.name || "Unknown"}
348
432
  **Mode**: ${updateMode}
349
433
 
350
434
  **Updated Files**:
351
435
  - \`.kiro/steering/product.md\` - Product overview and business context
352
- - \`.kiro/steering/tech.md\` - Technology stack and development environment
436
+ - \`.kiro/steering/tech.md\` - Technology stack and development environment
353
437
  - \`.kiro/steering/structure.md\` - Project organization and architectural decisions
354
438
 
355
439
  **Analysis**:
356
440
  - Technology stack: ${Object.keys({ ...packageJson.dependencies, ...packageJson.devDependencies }).length} dependencies detected
357
- - Project type: ${packageJson.type || 'Unknown'}
441
+ - Project type: ${packageJson.type || "Unknown"}
358
442
  - Existing steering: Updated preserving customizations
359
443
 
360
444
  These steering documents provide consistent project context for all AI interactions and spec-driven development workflows.`;
361
445
  }
362
446
  catch (error) {
363
- this.logger.error('Failed to generate steering documents', error);
447
+ this.logger.error("Failed to generate steering documents", error);
364
448
  throw new Error(`Failed to generate steering documents: ${error.message}`);
365
449
  }
366
450
  }
367
451
  async handleSteeringCustom(args) {
368
452
  const { fileName, topic, inclusionMode, filePattern } = args;
369
453
  const projectPath = process.cwd();
370
- if (typeof fileName !== 'string' || typeof topic !== 'string' || typeof inclusionMode !== 'string') {
371
- 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");
372
458
  }
373
459
  const content = `# ${topic}
374
460
 
@@ -383,17 +469,19 @@ Define the purpose and scope of this steering document.
383
469
  Describe when and how this steering document should be applied.
384
470
 
385
471
  ## Inclusion Mode
386
- Mode: ${inclusionMode}${filePattern ? `
387
- Pattern: ${filePattern}` : ''}
472
+ Mode: ${inclusionMode}${filePattern
473
+ ? `
474
+ Pattern: ${filePattern}`
475
+ : ""}
388
476
 
389
477
  Generated on: ${new Date().toISOString()}
390
478
  `;
391
479
  await this.steeringService.createSteeringDocument(projectPath, {
392
480
  name: fileName,
393
- type: 'CUSTOM',
481
+ type: "CUSTOM",
394
482
  mode: inclusionMode.toUpperCase(),
395
483
  patterns: filePattern ? [filePattern] : [],
396
- content
484
+ content,
397
485
  });
398
486
  return `Custom steering document "${fileName}" created successfully with ${inclusionMode} inclusion mode.`;
399
487
  }
@@ -401,11 +489,11 @@ Generated on: ${new Date().toISOString()}
401
489
  // Try to read package.json for project info
402
490
  let packageJson = {};
403
491
  try {
404
- const fs = await import('fs');
405
- const path = await import('path');
406
- 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");
407
495
  if (fs.existsSync(packagePath)) {
408
- const packageContent = fs.readFileSync(packagePath, 'utf8');
496
+ const packageContent = fs.readFileSync(packagePath, "utf8");
409
497
  packageJson = JSON.parse(packageContent);
410
498
  }
411
499
  }
@@ -413,12 +501,14 @@ Generated on: ${new Date().toISOString()}
413
501
  // Ignore errors
414
502
  }
415
503
  return `# Product Overview
416
-
504
+
417
505
  ## Product Description
418
- ${packageJson.description || 'No description available'}
506
+ ${packageJson.description || "No description available"}
419
507
 
420
508
  ## Core Features
421
- ${this.extractFeatures(packageJson, analysis).map((feature) => `- ${feature}`).join('\n')}
509
+ ${this.extractFeatures(packageJson, analysis)
510
+ .map((feature) => `- ${feature}`)
511
+ .join("\n")}
422
512
 
423
513
  ## Target Use Case
424
514
  ${this.generateTargetUseCase(packageJson)}
@@ -433,11 +523,11 @@ ${this.generateTargetUsers(packageJson)}`;
433
523
  // Try to read package.json for project info
434
524
  let packageJson = {};
435
525
  try {
436
- const fs = await import('fs');
437
- const path = await import('path');
438
- 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");
439
529
  if (fs.existsSync(packagePath)) {
440
- const packageContent = fs.readFileSync(packagePath, 'utf8');
530
+ const packageContent = fs.readFileSync(packagePath, "utf8");
441
531
  packageJson = JSON.parse(packageContent);
442
532
  }
443
533
  }
@@ -450,7 +540,7 @@ ${this.generateTargetUsers(packageJson)}`;
450
540
  ${this.generateTechStack(packageJson, analysis)}
451
541
 
452
542
  ## Development Environment
453
- - Node.js: ${packageJson.engines?.node || 'Unknown'}
543
+ - Node.js: ${packageJson.engines?.node || "Unknown"}
454
544
  - Package Manager: npm
455
545
 
456
546
  ## Key Dependencies
@@ -482,124 +572,148 @@ ${this.generateWorkflow(analysis)}`;
482
572
  // Extract features from scripts
483
573
  if (packageJson.scripts) {
484
574
  if (packageJson.scripts.test)
485
- features.push('Testing framework');
575
+ features.push("Testing framework");
486
576
  if (packageJson.scripts.build)
487
- features.push('Build system');
577
+ features.push("Build system");
488
578
  if (packageJson.scripts.dev || packageJson.scripts.start)
489
- features.push('Development server');
579
+ features.push("Development server");
490
580
  if (packageJson.scripts.lint)
491
- features.push('Code linting');
581
+ features.push("Code linting");
492
582
  if (packageJson.scripts.typecheck)
493
- features.push('Type checking');
583
+ features.push("Type checking");
494
584
  }
495
585
  // Extract features from dependencies
496
- const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
586
+ const deps = {
587
+ ...packageJson.dependencies,
588
+ ...packageJson.devDependencies,
589
+ };
497
590
  if (deps?.express || deps?.fastify || deps?.koa)
498
- features.push('Web server');
591
+ features.push("Web server");
499
592
  if (deps?.react || deps?.vue || deps?.angular)
500
- features.push('Frontend framework');
593
+ features.push("Frontend framework");
501
594
  if (deps?.typescript)
502
- features.push('TypeScript support');
595
+ features.push("TypeScript support");
503
596
  if (deps?.jest || deps?.mocha || deps?.vitest)
504
- features.push('Unit testing');
597
+ features.push("Unit testing");
505
598
  if (deps?.eslint)
506
- features.push('Code quality enforcement');
507
- 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"];
508
603
  }
509
604
  generateTargetUseCase(packageJson) {
510
605
  if (packageJson.keywords) {
511
- return `This product is designed for ${packageJson.keywords.join(', ')} use cases.`;
606
+ return `This product is designed for ${packageJson.keywords.join(", ")} use cases.`;
512
607
  }
513
- return 'Target use cases to be defined based on project requirements.';
608
+ return "Target use cases to be defined based on project requirements.";
514
609
  }
515
610
  generateValueProposition(packageJson, analysis) {
516
611
  const features = this.extractFeatures(packageJson, analysis);
517
- return features.map(feature => `- **${feature}**: Enhanced development experience`).join('\n');
612
+ return features
613
+ .map((feature) => `- **${feature}**: Enhanced development experience`)
614
+ .join("\n");
518
615
  }
519
616
  generateTargetUsers(packageJson) {
520
- if (packageJson.keywords?.includes('cli')) {
521
- 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";
522
619
  }
523
- if (packageJson.keywords?.includes('api')) {
524
- return '- API consumers\n- Third-party integrators';
620
+ if (packageJson.keywords?.includes("api")) {
621
+ return "- API consumers\n- Third-party integrators";
525
622
  }
526
- return '- Primary user persona\n- Secondary user persona';
623
+ return "- Primary user persona\n- Secondary user persona";
527
624
  }
528
625
  generateTechStack(packageJson, analysis) {
529
- const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
626
+ const deps = {
627
+ ...packageJson.dependencies,
628
+ ...packageJson.devDependencies,
629
+ };
530
630
  const stack = [];
531
631
  if (deps?.typescript)
532
- stack.push('TypeScript');
632
+ stack.push("TypeScript");
533
633
  if (deps?.node || packageJson.engines?.node)
534
- stack.push('Node.js');
634
+ stack.push("Node.js");
535
635
  if (deps?.express)
536
- stack.push('Express.js');
636
+ stack.push("Express.js");
537
637
  if (deps?.react)
538
- stack.push('React');
638
+ stack.push("React");
539
639
  if (deps?.vue)
540
- stack.push('Vue.js');
541
- 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";
542
644
  }
543
645
  generateDependencyList(packageJson) {
544
646
  const production = Object.keys(packageJson.dependencies || {});
545
647
  const development = Object.keys(packageJson.devDependencies || {});
546
- let list = '';
648
+ let list = "";
547
649
  if (production.length > 0) {
548
- list += '### Production Dependencies\n';
549
- 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");
550
655
  }
551
656
  if (development.length > 0) {
552
- list += '\n### Development Dependencies\n';
553
- 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");
554
662
  }
555
- return list || 'Dependencies to be analyzed';
663
+ return list || "Dependencies to be analyzed";
556
664
  }
557
665
  generateArchitecturePatterns(analysis) {
558
666
  const patterns = [];
559
667
  // Try to analyze directory structure from filesystem
560
668
  try {
561
- const fs = require('fs');
669
+ const fs = require("fs");
562
670
  const projectPath = process.cwd();
563
671
  const items = fs.readdirSync(projectPath, { withFileTypes: true });
564
672
  const directories = items
565
673
  .filter((item) => item.isDirectory())
566
674
  .map((item) => item.name);
567
- if (directories.includes('src'))
568
- patterns.push('Source code organization');
569
- if (directories.includes('test') || directories.includes('__tests__'))
570
- patterns.push('Test-driven development');
571
- if (directories.includes('dist') || directories.includes('build'))
572
- 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");
573
681
  }
574
682
  catch (error) {
575
683
  // Ignore filesystem errors
576
684
  }
577
- 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";
578
688
  }
579
689
  generateQualityStandards(packageJson) {
580
690
  const standards = [];
581
691
  if (packageJson.scripts?.lint)
582
- standards.push('Code linting with ESLint');
692
+ standards.push("Code linting with ESLint");
583
693
  if (packageJson.scripts?.typecheck)
584
- standards.push('Type checking with TypeScript');
694
+ standards.push("Type checking with TypeScript");
585
695
  if (packageJson.scripts?.test)
586
- standards.push('Unit testing required');
587
- 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";
588
700
  }
589
701
  generateDirectoryStructure(analysis) {
590
702
  // Try to get directory structure from filesystem
591
703
  try {
592
- const fs = require('fs');
704
+ const fs = require("fs");
593
705
  const projectPath = process.cwd();
594
706
  const items = fs.readdirSync(projectPath, { withFileTypes: true });
595
707
  const directories = items
596
- .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")
597
711
  .map((item) => `- ${item.name}/`)
598
- .join('\n');
599
- return directories || 'Directory structure to be analyzed';
712
+ .join("\n");
713
+ return directories || "Directory structure to be analyzed";
600
714
  }
601
715
  catch (error) {
602
- return 'Directory structure to be analyzed';
716
+ return "Directory structure to be analyzed";
603
717
  }
604
718
  }
605
719
  generateNamingConventions(analysis) {
@@ -618,11 +732,11 @@ ${this.generateWorkflow(analysis)}`;
618
732
  // Try to read package.json for scripts
619
733
  let packageJson = {};
620
734
  try {
621
- const fs = require('fs');
622
- const path = require('path');
623
- 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");
624
738
  if (fs.existsSync(packagePath)) {
625
- const packageContent = fs.readFileSync(packagePath, 'utf8');
739
+ const packageContent = fs.readFileSync(packagePath, "utf8");
626
740
  packageJson = JSON.parse(packageContent);
627
741
  }
628
742
  }
@@ -630,7 +744,7 @@ ${this.generateWorkflow(analysis)}`;
630
744
  // Ignore errors
631
745
  }
632
746
  const scripts = packageJson.scripts || {};
633
- let workflow = '## Development Commands\n';
747
+ let workflow = "## Development Commands\n";
634
748
  if (scripts.dev)
635
749
  workflow += `- \`npm run dev\` - Start development server\n`;
636
750
  if (scripts.build)
@@ -645,23 +759,23 @@ ${this.generateWorkflow(analysis)}`;
645
759
  await ensureStaticSteeringDocuments(projectPath, this.steeringService);
646
760
  }
647
761
  async createAgentsFile(projectPath) {
648
- const fs = await import('fs');
649
- const path = await import('path');
762
+ const fs = await import("fs");
763
+ const path = await import("path");
650
764
  // Check if AGENTS.md exists, if not create it based on CLAUDE.md
651
- const agentsPath = path.join(projectPath, 'AGENTS.md');
765
+ const agentsPath = path.join(projectPath, "AGENTS.md");
652
766
  if (!fs.existsSync(agentsPath)) {
653
767
  // Try to read CLAUDE.md to use as template
654
- const claudePath = path.join(projectPath, 'CLAUDE.md');
655
- let agentsContent = '';
768
+ const claudePath = path.join(projectPath, "CLAUDE.md");
769
+ let agentsContent = "";
656
770
  if (fs.existsSync(claudePath)) {
657
771
  // Read CLAUDE.md and adapt it for general agents
658
- const claudeContent = fs.readFileSync(claudePath, 'utf8');
772
+ const claudeContent = fs.readFileSync(claudePath, "utf8");
659
773
  agentsContent = claudeContent
660
- .replace(/# Claude Code Spec-Driven Development/g, '# AI Agent Spec-Driven Development')
661
- .replace(/Claude Code/g, 'AI Agent')
662
- .replace(/claude code/g, 'ai agent')
663
- .replace(/Claude/g, 'AI Agent')
664
- .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");
665
779
  }
666
780
  else {
667
781
  // Fallback to basic template if CLAUDE.md doesn't exist
@@ -678,7 +792,7 @@ Kiro-style Spec Driven Development implementation for AI agents across different
678
792
 
679
793
  ### Steering vs Specification
680
794
 
681
- **Steering** (\`.kiro/steering/\`) - Guide AI with project-wide rules and context
795
+ **Steering** (\`.kiro/steering/\`) - Guide AI with project-wide rules and context
682
796
  **Specs** (\`.kiro/specs/\`) - Formalize development process for individual features
683
797
 
684
798
  ### Active Specifications
@@ -694,7 +808,7 @@ Kiro-style Spec Driven Development implementation for AI agents across different
694
808
  ## Workflow
695
809
 
696
810
  ### Phase 0: Steering (Optional)
697
- Agent steering commands - Create/update steering documents
811
+ Agent steering commands - Create/update steering documents
698
812
  Agent steering-custom commands - Create custom steering for specialized contexts
699
813
 
700
814
  Note: Optional for new features or small additions. You can proceed directly to spec-init.
@@ -731,7 +845,7 @@ Managed by agent steering commands. Updates here reflect command changes.
731
845
 
732
846
  ### Custom Steering Files
733
847
  <!-- Added by agent steering-custom commands -->
734
- <!-- Format:
848
+ <!-- Format:
735
849
  - \`filename.md\`: Mode - Pattern(s) - Description
736
850
  Mode: Always|Conditional|Manual
737
851
  Pattern: File patterns for Conditional mode
@@ -757,13 +871,15 @@ SDDToolAdapter = __decorate([
757
871
  __param(3, inject(TYPES.QualityService)),
758
872
  __param(4, inject(TYPES.SteeringDocumentService)),
759
873
  __param(5, inject(TYPES.CodebaseAnalysisService)),
760
- __param(6, inject(TYPES.LoggerPort)),
874
+ __param(6, inject(TYPES.RequirementsClarificationService)),
875
+ __param(7, inject(TYPES.LoggerPort)),
761
876
  __metadata("design:paramtypes", [ProjectService,
762
877
  WorkflowService,
763
878
  TemplateService,
764
879
  QualityService,
765
880
  SteeringDocumentService,
766
- CodebaseAnalysisService, Object])
881
+ CodebaseAnalysisService,
882
+ RequirementsClarificationService, Object])
767
883
  ], SDDToolAdapter);
768
884
  export { SDDToolAdapter };
769
885
  //# sourceMappingURL=SDDToolAdapter.js.map