sdd-mcp-server 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2,12 +2,12 @@
2
2
  // MCP SDD Server entry point
3
3
  // IMPORTANT: Detect MCP mode and silence console output BEFORE any imports
4
4
  // Check multiple indicators for MCP mode
5
- const isMCPMode = process.argv[1]?.includes('sdd-mcp-server') ||
6
- process.argv[0]?.includes('sdd-mcp-server') ||
7
- process.env.npm_execpath?.includes('npx') || // Executed via npx
8
- (process.stdin.isTTY === false) || // MCP servers communicate via stdio pipes
9
- process.argv.includes('--mcp-mode') || // Explicit MCP mode flag
10
- process.argv.includes('--simplified') || // Use simplified mode flag
5
+ const isMCPMode = process.argv[1]?.includes("sdd-mcp-server") ||
6
+ process.argv[0]?.includes("sdd-mcp-server") ||
7
+ process.env.npm_execpath?.includes("npx") || // Executed via npx
8
+ process.stdin.isTTY === false || // MCP servers communicate via stdio pipes
9
+ process.argv.includes("--mcp-mode") || // Explicit MCP mode flag
10
+ process.argv.includes("--simplified") || // Use simplified mode flag
11
11
  false; // Default to full server for better functionality
12
12
  if (isMCPMode) {
13
13
  // Completely silence all console output for MCP mode
@@ -17,12 +17,13 @@ if (isMCPMode) {
17
17
  console.debug = () => { };
18
18
  // Keep error for debugging but send to stderr
19
19
  const originalError = console.error;
20
- console.error = (...args) => originalError('[SDD-DEBUG]', ...args);
20
+ console.error = (...args) => originalError("[SDD-DEBUG]", ...args);
21
21
  }
22
- import 'reflect-metadata';
23
- import { createContainer } from './infrastructure/di/container.js';
24
- import { TYPES } from './infrastructure/di/types.js';
25
- import { ensureStaticSteeringDocuments } from './application/services/staticSteering.js';
22
+ import "reflect-metadata";
23
+ import { createContainer } from "./infrastructure/di/container.js";
24
+ import { TYPES } from "./infrastructure/di/types.js";
25
+ import { ensureStaticSteeringDocuments } from "./application/services/staticSteering.js";
26
+ import { loadDocumentGenerator, loadSpecGenerator, } from "./utils/moduleLoader.js";
26
27
  export async function createMCPServer() {
27
28
  const container = createContainer();
28
29
  const logger = container.get(TYPES.LoggerPort);
@@ -46,21 +47,21 @@ export async function createMCPServer() {
46
47
  },
47
48
  async close() {
48
49
  await mcpServer.stop();
49
- }
50
+ },
50
51
  };
51
52
  }
52
53
  async function createSimpleMCPServer() {
53
- const { Server } = await import('@modelcontextprotocol/sdk/server/index.js');
54
- const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
55
- const { ListToolsRequestSchema, CallToolRequestSchema, InitializedNotificationSchema } = await import('@modelcontextprotocol/sdk/types.js');
54
+ const { Server } = await import("@modelcontextprotocol/sdk/server/index.js");
55
+ const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
56
+ const { ListToolsRequestSchema, CallToolRequestSchema, InitializedNotificationSchema, } = await import("@modelcontextprotocol/sdk/types.js");
56
57
  // Resolve version dynamically from package.json when possible
57
- let pkgVersion = '0.0.0';
58
+ let pkgVersion = "0.0.0";
58
59
  try {
59
- const fs = await import('fs');
60
- const path = await import('path');
61
- const pkgPath = path.join(process.cwd(), 'package.json');
60
+ const fs = await import("fs");
61
+ const path = await import("path");
62
+ const pkgPath = path.join(process.cwd(), "package.json");
62
63
  if (fs.existsSync(pkgPath)) {
63
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
64
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
64
65
  pkgVersion = pkg.version || pkgVersion;
65
66
  }
66
67
  }
@@ -68,248 +69,270 @@ async function createSimpleMCPServer() {
68
69
  // fall back to hardcoded default if needed
69
70
  }
70
71
  const server = new Server({
71
- name: 'sdd-mcp-server',
72
- version: pkgVersion
72
+ name: "sdd-mcp-server",
73
+ version: pkgVersion,
73
74
  }, {
74
75
  capabilities: {
75
- tools: {}
76
- }
76
+ tools: {},
77
+ },
77
78
  });
78
79
  // Add ALL SDD tools (not just basic ones)
79
80
  server.setRequestHandler(ListToolsRequestSchema, async () => {
80
81
  return {
81
82
  tools: [
82
83
  {
83
- name: 'sdd-init',
84
- description: 'Initialize a new SDD project from description',
84
+ name: "sdd-init",
85
+ description: "Initialize a new SDD project from description",
85
86
  inputSchema: {
86
- type: 'object',
87
+ type: "object",
87
88
  properties: {
88
- description: { type: 'string', description: 'Detailed project description' }
89
+ description: {
90
+ type: "string",
91
+ description: "Detailed project description",
92
+ },
89
93
  },
90
- required: ['description']
91
- }
94
+ required: ["description"],
95
+ },
92
96
  },
93
97
  {
94
- name: 'sdd-requirements',
95
- description: 'Generate requirements doc',
98
+ name: "sdd-requirements",
99
+ description: "Generate requirements doc",
96
100
  inputSchema: {
97
- type: 'object',
101
+ type: "object",
98
102
  properties: {
99
- featureName: { type: 'string' }
103
+ featureName: { type: "string" },
100
104
  },
101
- required: ['featureName']
102
- }
105
+ required: ["featureName"],
106
+ },
103
107
  },
104
108
  {
105
- name: 'sdd-design',
106
- description: 'Create design specifications',
109
+ name: "sdd-design",
110
+ description: "Create design specifications",
107
111
  inputSchema: {
108
- type: 'object',
112
+ type: "object",
109
113
  properties: {
110
- featureName: { type: 'string' }
114
+ featureName: { type: "string" },
111
115
  },
112
- required: ['featureName']
113
- }
116
+ required: ["featureName"],
117
+ },
114
118
  },
115
119
  {
116
- name: 'sdd-tasks',
117
- description: 'Generate task breakdown',
120
+ name: "sdd-tasks",
121
+ description: "Generate task breakdown",
118
122
  inputSchema: {
119
- type: 'object',
123
+ type: "object",
120
124
  properties: {
121
- featureName: { type: 'string' }
125
+ featureName: { type: "string" },
122
126
  },
123
- required: ['featureName']
124
- }
127
+ required: ["featureName"],
128
+ },
125
129
  },
126
130
  {
127
- name: 'sdd-status',
128
- description: 'Check workflow progress',
131
+ name: "sdd-status",
132
+ description: "Check workflow progress",
129
133
  inputSchema: {
130
- type: 'object',
134
+ type: "object",
131
135
  properties: {
132
- featureName: { type: 'string' }
133
- }
134
- }
136
+ featureName: { type: "string" },
137
+ },
138
+ },
135
139
  },
136
140
  {
137
- name: 'sdd-steering',
138
- description: 'Create/update steering documents',
141
+ name: "sdd-steering",
142
+ description: "Create/update steering documents",
139
143
  inputSchema: {
140
- type: 'object',
144
+ type: "object",
141
145
  properties: {
142
- updateMode: { type: 'string', enum: ['create', 'update'] }
143
- }
144
- }
146
+ updateMode: { type: "string", enum: ["create", "update"] },
147
+ },
148
+ },
145
149
  },
146
150
  {
147
- name: 'sdd-steering-custom',
148
- description: 'Create custom steering documents',
151
+ name: "sdd-steering-custom",
152
+ description: "Create custom steering documents",
149
153
  inputSchema: {
150
- type: 'object',
154
+ type: "object",
151
155
  properties: {
152
- fileName: { type: 'string' },
153
- topic: { type: 'string' },
154
- inclusionMode: { type: 'string', enum: ['always', 'conditional', 'manual'] },
155
- filePattern: { type: 'string' }
156
+ fileName: { type: "string" },
157
+ topic: { type: "string" },
158
+ inclusionMode: {
159
+ type: "string",
160
+ enum: ["always", "conditional", "manual"],
161
+ },
162
+ filePattern: { type: "string" },
156
163
  },
157
- required: ['fileName', 'topic', 'inclusionMode']
158
- }
164
+ required: ["fileName", "topic", "inclusionMode"],
165
+ },
159
166
  },
160
167
  {
161
- name: 'sdd-quality-check',
162
- description: 'Code quality analysis',
168
+ name: "sdd-quality-check",
169
+ description: "Code quality analysis",
163
170
  inputSchema: {
164
- type: 'object',
171
+ type: "object",
165
172
  properties: {
166
- code: { type: 'string' },
167
- language: { type: 'string' }
173
+ code: { type: "string" },
174
+ language: { type: "string" },
168
175
  },
169
- required: ['code']
170
- }
176
+ required: ["code"],
177
+ },
171
178
  },
172
179
  {
173
- name: 'sdd-approve',
174
- description: 'Approve workflow phases',
180
+ name: "sdd-approve",
181
+ description: "Approve workflow phases",
175
182
  inputSchema: {
176
- type: 'object',
183
+ type: "object",
177
184
  properties: {
178
- featureName: { type: 'string' },
179
- phase: { type: 'string', enum: ['requirements', 'design', 'tasks'] }
185
+ featureName: { type: "string" },
186
+ phase: {
187
+ type: "string",
188
+ enum: ["requirements", "design", "tasks"],
189
+ },
180
190
  },
181
- required: ['featureName', 'phase']
182
- }
191
+ required: ["featureName", "phase"],
192
+ },
183
193
  },
184
194
  {
185
- name: 'sdd-implement',
186
- description: 'Implementation guidelines',
195
+ name: "sdd-implement",
196
+ description: "Implementation guidelines",
187
197
  inputSchema: {
188
- type: 'object',
198
+ type: "object",
189
199
  properties: {
190
- featureName: { type: 'string' }
200
+ featureName: { type: "string" },
191
201
  },
192
- required: ['featureName']
193
- }
202
+ required: ["featureName"],
203
+ },
194
204
  },
195
205
  {
196
- name: 'sdd-context-load',
197
- description: 'Load project context',
206
+ name: "sdd-context-load",
207
+ description: "Load project context",
198
208
  inputSchema: {
199
- type: 'object',
209
+ type: "object",
200
210
  properties: {
201
- featureName: { type: 'string' }
211
+ featureName: { type: "string" },
202
212
  },
203
- required: ['featureName']
204
- }
213
+ required: ["featureName"],
214
+ },
205
215
  },
206
216
  {
207
- name: 'sdd-template-render',
208
- description: 'Render templates',
217
+ name: "sdd-template-render",
218
+ description: "Render templates",
209
219
  inputSchema: {
210
- type: 'object',
220
+ type: "object",
211
221
  properties: {
212
- templateType: { type: 'string', enum: ['requirements', 'design', 'tasks', 'custom'] },
213
- featureName: { type: 'string' },
214
- customTemplate: { type: 'string' }
222
+ templateType: {
223
+ type: "string",
224
+ enum: ["requirements", "design", "tasks", "custom"],
225
+ },
226
+ featureName: { type: "string" },
227
+ customTemplate: { type: "string" },
215
228
  },
216
- required: ['templateType', 'featureName']
217
- }
229
+ required: ["templateType", "featureName"],
230
+ },
218
231
  },
219
232
  {
220
- name: 'sdd-validate-design',
221
- description: 'Validate design quality',
233
+ name: "sdd-validate-design",
234
+ description: "Validate design quality",
222
235
  inputSchema: {
223
- type: 'object',
236
+ type: "object",
224
237
  properties: {
225
- featureName: { type: 'string' }
238
+ featureName: { type: "string" },
226
239
  },
227
- required: ['featureName']
228
- }
240
+ required: ["featureName"],
241
+ },
229
242
  },
230
243
  {
231
- name: 'sdd-validate-gap',
232
- description: 'Validate implementation gap',
244
+ name: "sdd-validate-gap",
245
+ description: "Validate implementation gap",
233
246
  inputSchema: {
234
- type: 'object',
247
+ type: "object",
235
248
  properties: {
236
- featureName: { type: 'string' }
249
+ featureName: { type: "string" },
237
250
  },
238
- required: ['featureName']
239
- }
251
+ required: ["featureName"],
252
+ },
240
253
  },
241
254
  {
242
- name: 'sdd-spec-impl',
243
- description: 'Execute spec tasks using TDD',
255
+ name: "sdd-spec-impl",
256
+ description: "Execute spec tasks using TDD",
244
257
  inputSchema: {
245
- type: 'object',
258
+ type: "object",
246
259
  properties: {
247
- featureName: { type: 'string' },
248
- taskNumbers: { type: 'string' }
260
+ featureName: { type: "string" },
261
+ taskNumbers: { type: "string" },
249
262
  },
250
- required: ['featureName']
251
- }
252
- }
253
- ]
263
+ required: ["featureName"],
264
+ },
265
+ },
266
+ ],
254
267
  };
255
268
  });
256
269
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
257
270
  const { name, arguments: args } = request.params;
258
271
  switch (name) {
259
- case 'sdd-init':
272
+ case "sdd-init":
260
273
  return await handleInitSimplified(args);
261
- case 'sdd-status':
274
+ case "sdd-status":
262
275
  return await handleStatusSimplified(args);
263
- case 'sdd-steering':
276
+ case "sdd-steering":
264
277
  return await handleSteeringSimplified(args);
265
- case 'sdd-steering-custom':
278
+ case "sdd-steering-custom":
266
279
  return await handleSteeringCustomSimplified(args);
267
- case 'sdd-requirements':
280
+ case "sdd-requirements":
268
281
  return await handleRequirementsSimplified(args);
269
- case 'sdd-design':
282
+ case "sdd-design":
270
283
  return await handleDesignSimplified(args);
271
- case 'sdd-tasks':
284
+ case "sdd-tasks":
272
285
  return await handleTasksSimplified(args);
273
- case 'sdd-quality-check':
286
+ case "sdd-quality-check":
274
287
  return await handleQualityCheckSimplified(args);
275
- case 'sdd-approve':
288
+ case "sdd-approve":
276
289
  return await handleApproveSimplified(args);
277
- case 'sdd-implement':
290
+ case "sdd-implement":
278
291
  return await handleImplementSimplified(args);
279
- case 'sdd-context-load':
292
+ case "sdd-context-load":
280
293
  return {
281
- content: [{
282
- type: 'text',
283
- text: `Project context loaded for ${args.featureName}. (Simplified MCP mode)`
284
- }]
294
+ content: [
295
+ {
296
+ type: "text",
297
+ text: `Project context loaded for ${args.featureName}. (Simplified MCP mode)`,
298
+ },
299
+ ],
285
300
  };
286
- case 'sdd-template-render':
301
+ case "sdd-template-render":
287
302
  return {
288
- content: [{
289
- type: 'text',
290
- text: `Template ${args.templateType} rendered for ${args.featureName}. (Simplified MCP mode)`
291
- }]
303
+ content: [
304
+ {
305
+ type: "text",
306
+ text: `Template ${args.templateType} rendered for ${args.featureName}. (Simplified MCP mode)`,
307
+ },
308
+ ],
292
309
  };
293
- case 'sdd-validate-design':
310
+ case "sdd-validate-design":
294
311
  return {
295
- content: [{
296
- type: 'text',
297
- text: `Design validation for ${args.featureName}. (Simplified MCP mode)`
298
- }]
312
+ content: [
313
+ {
314
+ type: "text",
315
+ text: `Design validation for ${args.featureName}. (Simplified MCP mode)`,
316
+ },
317
+ ],
299
318
  };
300
- case 'sdd-validate-gap':
319
+ case "sdd-validate-gap":
301
320
  return {
302
- content: [{
303
- type: 'text',
304
- text: `Implementation gap analysis for ${args.featureName}. (Simplified MCP mode)`
305
- }]
321
+ content: [
322
+ {
323
+ type: "text",
324
+ text: `Implementation gap analysis for ${args.featureName}. (Simplified MCP mode)`,
325
+ },
326
+ ],
306
327
  };
307
- case 'sdd-spec-impl':
328
+ case "sdd-spec-impl":
308
329
  return {
309
- content: [{
310
- type: 'text',
311
- text: `TDD implementation for ${args.featureName}. (Simplified MCP mode)`
312
- }]
330
+ content: [
331
+ {
332
+ type: "text",
333
+ text: `TDD implementation for ${args.featureName}. (Simplified MCP mode)`,
334
+ },
335
+ ],
313
336
  };
314
337
  default:
315
338
  throw new Error(`Unknown tool: ${name}`);
@@ -322,17 +345,37 @@ async function createSimpleMCPServer() {
322
345
  const transport = new StdioServerTransport();
323
346
  await server.connect(transport);
324
347
  }
348
+ /**
349
+ * Helper function to handle module loader failures consistently
350
+ *
351
+ * @param context - Description of what was being loaded (e.g., "documentGenerator", "specGenerator")
352
+ * @param error - The error that occurred during loading
353
+ * @param allowFallback - Whether to allow fallback templates (from env var or args)
354
+ * @returns Object with fallback content if allowed, or throws error
355
+ * @throws Error if fallback is not allowed
356
+ */
357
+ function handleLoaderFailure(context, error, allowFallback = false) {
358
+ const errorMessage = `Failed to load ${context}: ${error.message}\n\nTo use template fallbacks, set SDD_ALLOW_TEMPLATE_FALLBACK=true environment variable or run 'npm run build' to generate required files.`;
359
+ console.error(`[SDD-DEBUG] Loader failure for ${context}:`, error.message);
360
+ console.error(`[SDD-DEBUG] Fallback allowed:`, allowFallback);
361
+ if (!allowFallback) {
362
+ // Propagate error - do not use fallback
363
+ throw new Error(errorMessage);
364
+ }
365
+ console.error(`[SDD-DEBUG] Using fallback templates for ${context}`);
366
+ return { useFallback: true, error };
367
+ }
325
368
  // Simplified steering implementation for MCP mode
326
369
  async function handleSteeringSimplified(args) {
327
- const fs = await import('fs');
328
- const path = await import('path');
370
+ const fs = await import("fs");
371
+ const path = await import("path");
329
372
  const fsPromises = fs.promises;
330
373
  const projectPath = process.cwd();
331
374
  const stubSteeringService = {
332
375
  async createSteeringDocument(projectDir, config) {
333
- const docPath = path.join(projectDir, '.kiro', 'steering', config.name);
376
+ const docPath = path.join(projectDir, ".kiro", "steering", config.name);
334
377
  await fsPromises.mkdir(path.dirname(docPath), { recursive: true });
335
- await fsPromises.writeFile(docPath, config.content, 'utf8');
378
+ await fsPromises.writeFile(docPath, config.content, "utf8");
336
379
  return {
337
380
  name: config.name,
338
381
  path: docPath,
@@ -342,13 +385,13 @@ async function handleSteeringSimplified(args) {
342
385
  patterns: config.patterns ?? [],
343
386
  priority: config.priority ?? 50,
344
387
  lastModified: new Date(),
345
- isValid: true
388
+ isValid: true,
346
389
  };
347
- }
390
+ },
348
391
  };
349
392
  try {
350
393
  // Create .kiro/steering directory if it doesn't exist
351
- const steeringDir = path.join(projectPath, '.kiro', 'steering');
394
+ const steeringDir = path.join(projectPath, ".kiro", "steering");
352
395
  if (!fs.existsSync(steeringDir)) {
353
396
  fs.mkdirSync(steeringDir, { recursive: true });
354
397
  }
@@ -356,42 +399,44 @@ async function handleSteeringSimplified(args) {
356
399
  let techContent;
357
400
  let structureContent;
358
401
  let projectAnalysis;
402
+ // Check if fallback is allowed via environment variable or args
403
+ const allowFallback = process.env.SDD_ALLOW_TEMPLATE_FALLBACK === "true" ||
404
+ args?.allowFallback === true;
359
405
  try {
360
- // Attempt to import and use the dynamic document generator (from utils directory)
361
- console.error('[SDD-DEBUG] Attempting to import documentGenerator from ./utils/documentGenerator.js');
362
- const { analyzeProject, generateProductDocument, generateTechDocument, generateStructureDocument } = await import('./utils/documentGenerator.js');
363
- console.error('[SDD-DEBUG] DocumentGenerator imported successfully, analyzing project...');
406
+ // Attempt to import and use the dynamic document generator (using unified module loader)
407
+ console.error("[SDD-DEBUG] Attempting to load documentGenerator using moduleLoader");
408
+ const { analyzeProject, generateProductDocument, generateTechDocument, generateStructureDocument, } = await loadDocumentGenerator();
409
+ console.error("[SDD-DEBUG] DocumentGenerator imported successfully, analyzing project...");
364
410
  // Analyze project dynamically
365
411
  projectAnalysis = await analyzeProject(projectPath);
366
- console.error('[SDD-DEBUG] Project analysis completed, generating documents...');
412
+ console.error("[SDD-DEBUG] Project analysis completed, generating documents...");
367
413
  // Generate documents dynamically
368
414
  productContent = generateProductDocument(projectAnalysis);
369
415
  techContent = generateTechDocument(projectAnalysis);
370
416
  structureContent = generateStructureDocument(projectAnalysis);
371
- console.error('[SDD-DEBUG] Dynamic document generation completed successfully');
417
+ console.error("[SDD-DEBUG] Dynamic document generation completed successfully");
372
418
  }
373
419
  catch (importError) {
374
- console.error('[SDD-DEBUG] Failed to import or use documentGenerator:', importError.message);
375
- console.error('[SDD-DEBUG] Attempted import path: ./utils/documentGenerator.js');
376
- console.error('[SDD-DEBUG] Falling back to basic templates with warning...');
420
+ // Use shared error handler
421
+ const { useFallback, error } = handleLoaderFailure("documentGenerator", importError, allowFallback);
377
422
  // Fallback to basic templates
378
- const packageJsonPath = path.join(projectPath, 'package.json');
379
- let projectName = 'Unknown Project';
380
- let projectVersion = '0.0.0';
423
+ const packageJsonPath = path.join(projectPath, "package.json");
424
+ let projectName = "Unknown Project";
425
+ let projectVersion = "0.0.0";
381
426
  try {
382
427
  if (fs.existsSync(packageJsonPath)) {
383
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
428
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
384
429
  projectName = packageJson.name || projectName;
385
430
  projectVersion = packageJson.version || projectVersion;
386
431
  }
387
432
  }
388
433
  catch (pkgError) {
389
- console.error('[SDD-DEBUG] Could not read package.json, using defaults');
434
+ console.error("[SDD-DEBUG] Could not read package.json, using defaults");
390
435
  }
391
436
  productContent = `# Product Overview
392
437
 
393
438
  ⚠️ **Warning**: This document was generated using fallback templates due to documentGenerator import failure.
394
- Error: ${importError.message}
439
+ Error: ${error.message}
395
440
 
396
441
  ## Product Description
397
442
  ${projectName}
@@ -416,7 +461,7 @@ Generated on: ${new Date().toISOString()}
416
461
  techContent = `# Technology Stack
417
462
 
418
463
  ⚠️ **Warning**: This document was generated using fallback templates due to documentGenerator import failure.
419
- Error: ${importError.message}
464
+ Error: ${error.message}
420
465
 
421
466
  ## Architecture
422
467
  **Type**: MCP Server Application
@@ -440,7 +485,7 @@ Generated on: ${new Date().toISOString()}
440
485
  structureContent = `# Project Structure
441
486
 
442
487
  ⚠️ **Warning**: This document was generated using fallback templates due to documentGenerator import failure.
443
- Error: ${importError.message}
488
+ Error: ${error.message}
444
489
 
445
490
  ## Directory Organization
446
491
  \`\`\`
@@ -468,38 +513,38 @@ Generated on: ${new Date().toISOString()}
468
513
  const fallbackAnalysis = {
469
514
  name: projectName,
470
515
  version: projectVersion,
471
- architecture: 'MCP Server Application',
472
- language: 'typescript',
473
- framework: 'MCP SDK',
516
+ architecture: "MCP Server Application",
517
+ language: "typescript",
518
+ framework: "MCP SDK",
474
519
  dependencies: [],
475
520
  devDependencies: [],
476
521
  testFramework: null,
477
- buildTool: 'TypeScript Compiler',
478
- directories: ['src', 'dist'],
522
+ buildTool: "TypeScript Compiler",
523
+ directories: ["src", "dist"],
479
524
  hasCI: false,
480
- hasDocker: false
525
+ hasDocker: false,
481
526
  };
482
527
  // Use fallback analysis for the return message
483
528
  projectAnalysis = fallbackAnalysis;
484
529
  }
485
530
  // Write the dynamically generated files
486
- fs.writeFileSync(path.join(steeringDir, 'product.md'), productContent);
487
- fs.writeFileSync(path.join(steeringDir, 'tech.md'), techContent);
488
- fs.writeFileSync(path.join(steeringDir, 'structure.md'), structureContent);
531
+ fs.writeFileSync(path.join(steeringDir, "product.md"), productContent);
532
+ fs.writeFileSync(path.join(steeringDir, "tech.md"), techContent);
533
+ fs.writeFileSync(path.join(steeringDir, "structure.md"), structureContent);
489
534
  await ensureStaticSteeringDocuments(projectPath, stubSteeringService);
490
535
  // Ensure AGENTS.md exists (based on CLAUDE.md if available)
491
- const agentsPath = path.join(projectPath, 'AGENTS.md');
536
+ const agentsPath = path.join(projectPath, "AGENTS.md");
492
537
  if (!fs.existsSync(agentsPath)) {
493
- const claudePath = path.join(projectPath, 'CLAUDE.md');
494
- let agentsContent = '';
538
+ const claudePath = path.join(projectPath, "CLAUDE.md");
539
+ let agentsContent = "";
495
540
  if (fs.existsSync(claudePath)) {
496
- const claudeContent = fs.readFileSync(claudePath, 'utf8');
541
+ const claudeContent = fs.readFileSync(claudePath, "utf8");
497
542
  agentsContent = claudeContent
498
- .replace(/# Claude Code Spec-Driven Development/g, '# AI Agent Spec-Driven Development')
499
- .replace(/Claude Code/g, 'AI Agent')
500
- .replace(/claude code/g, 'ai agent')
501
- .replace(/\.claude\//g, '.ai agent/')
502
- .replace(/\/claude/g, '/agent');
543
+ .replace(/# Claude Code Spec-Driven Development/g, "# AI Agent Spec-Driven Development")
544
+ .replace(/Claude Code/g, "AI Agent")
545
+ .replace(/claude code/g, "ai agent")
546
+ .replace(/\.claude\//g, ".ai agent/")
547
+ .replace(/\/claude/g, "/agent");
503
548
  }
504
549
  else {
505
550
  agentsContent = `# AI Agent Spec-Driven Development
@@ -585,8 +630,9 @@ Generated on: ${new Date().toISOString()}
585
630
  fs.writeFileSync(agentsPath, agentsContent);
586
631
  }
587
632
  return {
588
- content: [{
589
- type: 'text',
633
+ content: [
634
+ {
635
+ type: "text",
590
636
  text: `## Steering Documents Updated
591
637
 
592
638
  **Project**: ${projectAnalysis.name}
@@ -604,39 +650,42 @@ Generated on: ${new Date().toISOString()}
604
650
  - \`.kiro/steering/principles.md\` - Core coding principles: SOLID, DRY, KISS, YAGNI, SoC, Modularity (static)
605
651
 
606
652
  **Dynamic Analysis Results**:
607
- - **Language**: ${projectAnalysis.language === 'typescript' ? 'TypeScript' : 'JavaScript'}
608
- - **Framework**: ${projectAnalysis.framework || 'None detected'}
653
+ - **Language**: ${projectAnalysis.language === "typescript" ? "TypeScript" : "JavaScript"}
654
+ - **Framework**: ${projectAnalysis.framework || "None detected"}
609
655
  - **Dependencies**: ${projectAnalysis.dependencies.length} production, ${projectAnalysis.devDependencies.length} development
610
- - **Test Framework**: ${projectAnalysis.testFramework || 'None detected'}
611
- - **Build Tool**: ${projectAnalysis.buildTool || 'None detected'}
656
+ - **Test Framework**: ${projectAnalysis.testFramework || "None detected"}
657
+ - **Build Tool**: ${projectAnalysis.buildTool || "None detected"}
612
658
  - **Project Structure**: ${projectAnalysis.directories.length} directories analyzed
613
- - **CI/CD**: ${projectAnalysis.hasCI ? 'Configured' : 'Not configured'}
614
- - **Docker**: ${projectAnalysis.hasDocker ? 'Configured' : 'Not configured'}
659
+ - **CI/CD**: ${projectAnalysis.hasCI ? "Configured" : "Not configured"}
660
+ - **Docker**: ${projectAnalysis.hasDocker ? "Configured" : "Not configured"}
615
661
 
616
- These steering documents were dynamically generated based on actual project analysis and provide accurate, up-to-date context for AI interactions.`
617
- }]
662
+ These steering documents were dynamically generated based on actual project analysis and provide accurate, up-to-date context for AI interactions.`,
663
+ },
664
+ ],
618
665
  };
619
666
  }
620
667
  catch (error) {
621
668
  return {
622
- content: [{
623
- type: 'text',
624
- text: `Error generating steering documents: ${error.message}`
625
- }],
626
- isError: true
669
+ content: [
670
+ {
671
+ type: "text",
672
+ text: `Error generating steering documents: ${error.message}`,
673
+ },
674
+ ],
675
+ isError: true,
627
676
  };
628
677
  }
629
678
  }
630
679
  async function handleSteeringCustomSimplified(args) {
631
- const fs = await import('fs');
632
- const path = await import('path');
680
+ const fs = await import("fs");
681
+ const path = await import("path");
633
682
  try {
634
683
  const { fileName, topic, inclusionMode, filePattern } = args;
635
684
  if (!fileName || !topic || !inclusionMode) {
636
- throw new Error('fileName, topic, and inclusionMode are required');
685
+ throw new Error("fileName, topic, and inclusionMode are required");
637
686
  }
638
687
  const projectPath = process.cwd();
639
- const steeringDir = path.join(projectPath, '.kiro', 'steering');
688
+ const steeringDir = path.join(projectPath, ".kiro", "steering");
640
689
  if (!fs.existsSync(steeringDir)) {
641
690
  fs.mkdirSync(steeringDir, { recursive: true });
642
691
  }
@@ -653,59 +702,85 @@ Define the purpose and scope of this steering document.
653
702
  Describe when and how this steering document should be applied.
654
703
 
655
704
  ## Inclusion Mode
656
- Mode: ${inclusionMode}${filePattern ? `
657
- Pattern: ${filePattern}` : ''}
705
+ Mode: ${inclusionMode}${filePattern
706
+ ? `
707
+ Pattern: ${filePattern}`
708
+ : ""}
658
709
 
659
710
  Generated on: ${new Date().toISOString()}
660
711
  `;
661
712
  fs.writeFileSync(path.join(steeringDir, fileName), content);
662
713
  return {
663
- content: [{
664
- type: 'text',
665
- text: `Custom steering document "${fileName}" created successfully with ${inclusionMode} inclusion mode.`
666
- }]
714
+ content: [
715
+ {
716
+ type: "text",
717
+ text: `Custom steering document "${fileName}" created successfully with ${inclusionMode} inclusion mode.`,
718
+ },
719
+ ],
667
720
  };
668
721
  }
669
722
  catch (error) {
670
723
  return {
671
- content: [{
672
- type: 'text',
673
- text: `Error creating custom steering document: ${error.message}`
674
- }],
675
- isError: true
724
+ content: [
725
+ {
726
+ type: "text",
727
+ text: `Error creating custom steering document: ${error.message}`,
728
+ },
729
+ ],
730
+ isError: true,
676
731
  };
677
732
  }
678
733
  }
679
734
  // Status handler aligned with full server behavior
680
735
  async function handleStatusSimplified(args) {
681
- const fs = await import('fs');
682
- const path = await import('path');
736
+ const fs = await import("fs");
737
+ const path = await import("path");
683
738
  const { featureName } = args || {};
684
739
  const currentPath = process.cwd();
685
- const kiroPath = path.join(currentPath, '.kiro');
686
- const exists = await fs.promises.access(kiroPath).then(() => true).catch(() => false);
740
+ const kiroPath = path.join(currentPath, ".kiro");
741
+ const exists = await fs.promises
742
+ .access(kiroPath)
743
+ .then(() => true)
744
+ .catch(() => false);
687
745
  if (!exists) {
688
- return { content: [{ type: 'text', text: 'SDD project status: No active project found. Use sdd-init to create a new project.' }] };
746
+ return {
747
+ content: [
748
+ {
749
+ type: "text",
750
+ text: "SDD project status: No active project found. Use sdd-init to create a new project.",
751
+ },
752
+ ],
753
+ };
689
754
  }
690
- const specsPath = path.join(kiroPath, 'specs');
755
+ const specsPath = path.join(kiroPath, "specs");
691
756
  if (featureName) {
692
757
  const featurePath = path.join(specsPath, featureName);
693
- const specPath = path.join(featurePath, 'spec.json');
694
- const specExists = await fs.promises.access(specPath).then(() => true).catch(() => false);
758
+ const specPath = path.join(featurePath, "spec.json");
759
+ const specExists = await fs.promises
760
+ .access(specPath)
761
+ .then(() => true)
762
+ .catch(() => false);
695
763
  if (!specExists) {
696
- return { content: [{ type: 'text', text: `Feature "${featureName}" not found. Use sdd-init to create it.` }] };
764
+ return {
765
+ content: [
766
+ {
767
+ type: "text",
768
+ text: `Feature "${featureName}" not found. Use sdd-init to create it.`,
769
+ },
770
+ ],
771
+ };
697
772
  }
698
- const spec = JSON.parse(fs.readFileSync(specPath, 'utf8'));
773
+ const spec = JSON.parse(fs.readFileSync(specPath, "utf8"));
699
774
  let status = `## SDD Project Status: ${spec.feature_name}\n\n`;
700
775
  status += `**Current Phase**: ${spec.phase}\n`;
701
776
  status += `**Language**: ${spec.language}\n`;
702
777
  status += `**Created**: ${spec.created_at}\n`;
703
778
  status += `**Updated**: ${spec.updated_at}\n\n`;
704
779
  status += `**Phase Progress**:\n`;
705
- status += `- Requirements: ${spec.approvals.requirements.generated ? '✅ Generated' : '❌ Not Generated'}${spec.approvals.requirements.approved ? ', ✅ Approved' : ', ❌ Not Approved'}\n`;
706
- status += `- Design: ${spec.approvals.design.generated ? '✅ Generated' : '❌ Not Generated'}${spec.approvals.design.approved ? ', ✅ Approved' : ', ❌ Not Approved'}\n`;
707
- status += `- Tasks: ${spec.approvals.tasks.generated ? '✅ Generated' : '❌ Not Generated'}${spec.approvals.tasks.approved ? ', ✅ Approved' : ', ❌ Not Approved'}\n\n`;
708
- status += `**Ready for Implementation**: ${spec.ready_for_implementation ? '✅ Yes' : '❌ No'}\n\n`;
780
+ status += `- Requirements: ${spec.approvals.requirements.generated ? "✅ Generated" : "❌ Not Generated"}${spec.approvals.requirements.approved ? ", ✅ Approved" : ", ❌ Not Approved"}\n`;
781
+ status += `- Design: ${spec.approvals.design.generated ? "✅ Generated" : "❌ Not Generated"}${spec.approvals.design.approved ? ", ✅ Approved" : ", ❌ Not Approved"}\n`;
782
+ status += `- Tasks: ${spec.approvals.tasks.generated ? "✅ Generated" : "❌ Not Generated"}${spec.approvals.tasks.approved ? ", ✅ Approved" : ", ❌ Not Approved"}\n\n`;
783
+ status += `**Ready for Implementation**: ${spec.ready_for_implementation ? "✅ Yes" : "❌ No"}\n\n`;
709
784
  if (!spec.approvals.requirements.generated)
710
785
  status += `**Next Step**: Run \`sdd-requirements ${featureName}\``;
711
786
  else if (!spec.approvals.design.generated)
@@ -714,95 +789,168 @@ async function handleStatusSimplified(args) {
714
789
  status += `**Next Step**: Run \`sdd-tasks ${featureName}\``;
715
790
  else
716
791
  status += `**Next Step**: Run \`sdd-implement ${featureName}\` to begin implementation`;
717
- return { content: [{ type: 'text', text: status }] };
792
+ return { content: [{ type: "text", text: status }] };
718
793
  }
719
- const features = await fs.promises.readdir(specsPath).catch(() => []);
794
+ const features = await fs.promises
795
+ .readdir(specsPath)
796
+ .catch(() => []);
720
797
  if (features.length === 0) {
721
- return { content: [{ type: 'text', text: 'No SDD features found. Use sdd-init to create a new project.' }] };
798
+ return {
799
+ content: [
800
+ {
801
+ type: "text",
802
+ text: "No SDD features found. Use sdd-init to create a new project.",
803
+ },
804
+ ],
805
+ };
722
806
  }
723
- let status = '## SDD Project Status - All Features\n\n';
807
+ let status = "## SDD Project Status - All Features\n\n";
724
808
  for (const feature of features) {
725
- const specPath = path.join(specsPath, feature, 'spec.json');
726
- const specExists = await fs.promises.access(specPath).then(() => true).catch(() => false);
809
+ const specPath = path.join(specsPath, feature, "spec.json");
810
+ const specExists = await fs.promises
811
+ .access(specPath)
812
+ .then(() => true)
813
+ .catch(() => false);
727
814
  if (specExists) {
728
- const spec = JSON.parse(fs.readFileSync(specPath, 'utf8'));
815
+ const spec = JSON.parse(fs.readFileSync(specPath, "utf8"));
729
816
  status += `**${spec.feature_name}**:\n`;
730
817
  status += `- Phase: ${spec.phase}\n`;
731
- status += `- Requirements: ${spec.approvals.requirements.generated ? '' : ''}\n`;
732
- status += `- Design: ${spec.approvals.design.generated ? '' : ''}\n`;
733
- status += `- Tasks: ${spec.approvals.tasks.generated ? '' : ''}\n`;
734
- status += `- Ready: ${spec.ready_for_implementation ? '' : ''}\n\n`;
818
+ status += `- Requirements: ${spec.approvals.requirements.generated ? "" : ""}\n`;
819
+ status += `- Design: ${spec.approvals.design.generated ? "" : ""}\n`;
820
+ status += `- Tasks: ${spec.approvals.tasks.generated ? "" : ""}\n`;
821
+ status += `- Ready: ${spec.ready_for_implementation ? "" : ""}\n\n`;
735
822
  }
736
823
  }
737
- return { content: [{ type: 'text', text: status }] };
824
+ return { content: [{ type: "text", text: status }] };
738
825
  }
739
826
  // Approve handler to update spec.json
740
827
  async function handleApproveSimplified(args) {
741
- const fs = await import('fs');
742
- const path = await import('path');
828
+ const fs = await import("fs");
829
+ const path = await import("path");
743
830
  const { featureName, phase } = args || {};
744
831
  if (!featureName || !phase) {
745
- return { content: [{ type: 'text', text: 'featureName and phase are required' }], isError: true };
832
+ return {
833
+ content: [{ type: "text", text: "featureName and phase are required" }],
834
+ isError: true,
835
+ };
746
836
  }
747
837
  try {
748
- const featurePath = path.join(process.cwd(), '.kiro', 'specs', featureName);
749
- const specPath = path.join(featurePath, 'spec.json');
750
- const spec = JSON.parse(fs.readFileSync(specPath, 'utf8'));
838
+ const featurePath = path.join(process.cwd(), ".kiro", "specs", featureName);
839
+ const specPath = path.join(featurePath, "spec.json");
840
+ const spec = JSON.parse(fs.readFileSync(specPath, "utf8"));
751
841
  if (!spec.approvals?.[phase]?.generated) {
752
- return { content: [{ type: 'text', text: `Error: ${phase} must be generated before approval. Run sdd-${phase} ${featureName} first.` }] };
842
+ return {
843
+ content: [
844
+ {
845
+ type: "text",
846
+ text: `Error: ${phase} must be generated before approval. Run sdd-${phase} ${featureName} first.`,
847
+ },
848
+ ],
849
+ };
753
850
  }
754
851
  spec.approvals[phase].approved = true;
755
852
  spec.updated_at = new Date().toISOString();
756
853
  fs.writeFileSync(specPath, JSON.stringify(spec, null, 2));
757
- return { content: [{ type: 'text', text: `## Phase Approved\n\n**Feature**: ${featureName}\n**Phase**: ${phase}\n**Status**: ✅ Approved` }] };
854
+ return {
855
+ content: [
856
+ {
857
+ type: "text",
858
+ text: `## Phase Approved\n\n**Feature**: ${featureName}\n**Phase**: ${phase}\n**Status**: ✅ Approved`,
859
+ },
860
+ ],
861
+ };
758
862
  }
759
863
  catch (error) {
760
- return { content: [{ type: 'text', text: `Error approving phase: ${error.message}` }], isError: true };
864
+ return {
865
+ content: [
866
+ {
867
+ type: "text",
868
+ text: `Error approving phase: ${error.message}`,
869
+ },
870
+ ],
871
+ isError: true,
872
+ };
761
873
  }
762
874
  }
763
875
  // Simple quality check aligned with full server
764
876
  async function handleQualityCheckSimplified(args) {
765
- const { code = '', language = 'javascript' } = args || {};
877
+ const { code = "", language = "javascript" } = args || {};
766
878
  try {
767
- const lines = String(code).split('\n');
879
+ const lines = String(code).split("\n");
768
880
  const issues = [];
769
- if (code.includes('console.log'))
770
- issues.push('L1: Remove debug console.log statements');
771
- if (code.includes('var '))
772
- issues.push('L1: Use let/const instead of var');
773
- if (!/^[a-z]/.test(code.split('function ')[1]?.split('(')[0] || '')) {
774
- if (code.includes('function '))
775
- issues.push('L2: Function names should start with lowercase');
881
+ if (code.includes("console.log"))
882
+ issues.push("L1: Remove debug console.log statements");
883
+ if (code.includes("var "))
884
+ issues.push("L1: Use let/const instead of var");
885
+ if (!/^[a-z]/.test(code.split("function ")[1]?.split("(")[0] || "")) {
886
+ if (code.includes("function "))
887
+ issues.push("L2: Function names should start with lowercase");
776
888
  }
777
- if (code.includes('for') && !code.includes('const'))
778
- issues.push('L3: Prefer const in for loops');
889
+ if (code.includes("for") && !code.includes("const"))
890
+ issues.push("L3: Prefer const in for loops");
779
891
  if (lines.length > 50)
780
- issues.push('L4: Consider splitting large blocks into smaller functions');
781
- const report = `## Code Quality Analysis (${language})\n\n` + (issues.length ? issues.map(i => `- ${i}`).join('\n') : 'No significant issues detected');
782
- return { content: [{ type: 'text', text: report }] };
892
+ issues.push("L4: Consider splitting large blocks into smaller functions");
893
+ const report = `## Code Quality Analysis (${language})\n\n` +
894
+ (issues.length
895
+ ? issues.map((i) => `- ${i}`).join("\n")
896
+ : "No significant issues detected");
897
+ return { content: [{ type: "text", text: report }] };
783
898
  }
784
899
  catch (error) {
785
- return { content: [{ type: 'text', text: `Error analyzing code quality: ${error.message}` }], isError: true };
900
+ return {
901
+ content: [
902
+ {
903
+ type: "text",
904
+ text: `Error analyzing code quality: ${error.message}`,
905
+ },
906
+ ],
907
+ isError: true,
908
+ };
786
909
  }
787
910
  }
788
911
  // Implement guidelines check
789
912
  async function handleImplementSimplified(args) {
790
- const fs = await import('fs');
791
- const path = await import('path');
913
+ const fs = await import("fs");
914
+ const path = await import("path");
792
915
  const { featureName } = args || {};
793
916
  if (!featureName)
794
- return { content: [{ type: 'text', text: 'featureName is required' }], isError: true };
917
+ return {
918
+ content: [{ type: "text", text: "featureName is required" }],
919
+ isError: true,
920
+ };
795
921
  try {
796
- const featurePath = path.join(process.cwd(), '.kiro', 'specs', featureName);
797
- const specPath = path.join(featurePath, 'spec.json');
798
- const spec = JSON.parse(fs.readFileSync(specPath, 'utf8'));
922
+ const featurePath = path.join(process.cwd(), ".kiro", "specs", featureName);
923
+ const specPath = path.join(featurePath, "spec.json");
924
+ const spec = JSON.parse(fs.readFileSync(specPath, "utf8"));
799
925
  if (!spec.ready_for_implementation) {
800
- return { content: [{ type: 'text', text: 'Error: Project not ready for implementation. Complete requirements, design, and tasks phases first.' }] };
926
+ return {
927
+ content: [
928
+ {
929
+ type: "text",
930
+ text: "Error: Project not ready for implementation. Complete requirements, design, and tasks phases first.",
931
+ },
932
+ ],
933
+ };
801
934
  }
802
- return { content: [{ type: 'text', text: `## Implementation Guidelines for ${featureName}\n\nFollow tasks in tasks.md, implement per design.md, and validate against requirements.md. Use sdd-quality-check during development.` }] };
935
+ return {
936
+ content: [
937
+ {
938
+ type: "text",
939
+ text: `## Implementation Guidelines for ${featureName}\n\nFollow tasks in tasks.md, implement per design.md, and validate against requirements.md. Use sdd-quality-check during development.`,
940
+ },
941
+ ],
942
+ };
803
943
  }
804
944
  catch (error) {
805
- return { content: [{ type: 'text', text: `Error getting implementation guidelines: ${error.message}` }], isError: true };
945
+ return {
946
+ content: [
947
+ {
948
+ type: "text",
949
+ text: `Error getting implementation guidelines: ${error.message}`,
950
+ },
951
+ ],
952
+ isError: true,
953
+ };
806
954
  }
807
955
  }
808
956
  // Helper functions for simplified analysis
@@ -811,73 +959,79 @@ function extractFeaturesSimplified(packageJson) {
811
959
  // Extract features from scripts
812
960
  if (packageJson.scripts) {
813
961
  if (packageJson.scripts.test)
814
- features.push('Testing framework');
962
+ features.push("Testing framework");
815
963
  if (packageJson.scripts.build)
816
- features.push('Build system');
964
+ features.push("Build system");
817
965
  if (packageJson.scripts.dev || packageJson.scripts.start)
818
- features.push('Development server');
966
+ features.push("Development server");
819
967
  if (packageJson.scripts.lint)
820
- features.push('Code linting');
968
+ features.push("Code linting");
821
969
  if (packageJson.scripts.typecheck)
822
- features.push('Type checking');
970
+ features.push("Type checking");
823
971
  }
824
972
  // Extract features from dependencies
825
973
  const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
826
974
  if (deps?.express || deps?.fastify || deps?.koa)
827
- features.push('Web server');
975
+ features.push("Web server");
828
976
  if (deps?.react || deps?.vue || deps?.angular)
829
- features.push('Frontend framework');
977
+ features.push("Frontend framework");
830
978
  if (deps?.typescript)
831
- features.push('TypeScript support');
979
+ features.push("TypeScript support");
832
980
  if (deps?.jest || deps?.mocha || deps?.vitest)
833
- features.push('Unit testing');
981
+ features.push("Unit testing");
834
982
  if (deps?.eslint)
835
- features.push('Code quality enforcement');
836
- return features.length > 0 ? features : ['Core functionality'];
983
+ features.push("Code quality enforcement");
984
+ return features.length > 0 ? features : ["Core functionality"];
837
985
  }
838
986
  function generateTargetUsersSimplified(packageJson) {
839
- if (packageJson.keywords?.includes('cli')) {
840
- return '- Command-line tool users\n- Developers and system administrators';
987
+ if (packageJson.keywords?.includes("cli")) {
988
+ return "- Command-line tool users\n- Developers and system administrators";
841
989
  }
842
- if (packageJson.keywords?.includes('api')) {
843
- return '- API consumers\n- Third-party integrators';
990
+ if (packageJson.keywords?.includes("api")) {
991
+ return "- API consumers\n- Third-party integrators";
844
992
  }
845
- return '- Primary user persona\n- Secondary user persona';
993
+ return "- Primary user persona\n- Secondary user persona";
846
994
  }
847
995
  function generateTechStackSimplified(packageJson) {
848
996
  const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
849
997
  const stack = [];
850
998
  if (deps?.typescript)
851
- stack.push('TypeScript');
999
+ stack.push("TypeScript");
852
1000
  if (deps?.node || packageJson.engines?.node)
853
- stack.push('Node.js');
1001
+ stack.push("Node.js");
854
1002
  if (deps?.express)
855
- stack.push('Express.js');
1003
+ stack.push("Express.js");
856
1004
  if (deps?.react)
857
- stack.push('React');
1005
+ stack.push("React");
858
1006
  if (deps?.vue)
859
- stack.push('Vue.js');
860
- return stack.length > 0 ? stack.join(', ') : 'Technology stack to be defined';
1007
+ stack.push("Vue.js");
1008
+ return stack.length > 0 ? stack.join(", ") : "Technology stack to be defined";
861
1009
  }
862
1010
  function generateDependencyListSimplified(packageJson) {
863
1011
  const deps = packageJson.dependencies || {};
864
1012
  const devDeps = packageJson.devDependencies || {};
865
- let list = '';
1013
+ let list = "";
866
1014
  const depList = Object.keys(deps);
867
1015
  const devDepList = Object.keys(devDeps);
868
1016
  if (depList.length > 0) {
869
- list += '### Production Dependencies\n';
870
- list += depList.slice(0, 10).map(dep => `- ${dep}`).join('\n');
1017
+ list += "### Production Dependencies\n";
1018
+ list += depList
1019
+ .slice(0, 10)
1020
+ .map((dep) => `- ${dep}`)
1021
+ .join("\n");
871
1022
  }
872
1023
  if (devDepList.length > 0) {
873
- list += '\n### Development Dependencies\n';
874
- list += devDepList.slice(0, 10).map(dep => `- ${dep}`).join('\n');
1024
+ list += "\n### Development Dependencies\n";
1025
+ list += devDepList
1026
+ .slice(0, 10)
1027
+ .map((dep) => `- ${dep}`)
1028
+ .join("\n");
875
1029
  }
876
- return list || 'Dependencies to be analyzed';
1030
+ return list || "Dependencies to be analyzed";
877
1031
  }
878
1032
  function generateWorkflowSimplified(packageJson) {
879
1033
  const scripts = packageJson.scripts || {};
880
- let workflow = '## Development Commands\n';
1034
+ let workflow = "## Development Commands\n";
881
1035
  if (scripts.dev)
882
1036
  workflow += `- \`npm run dev\` - Start development server\n`;
883
1037
  if (scripts.build)
@@ -889,27 +1043,29 @@ function generateWorkflowSimplified(packageJson) {
889
1043
  return workflow;
890
1044
  }
891
1045
  function generateDirectoryStructureSimplified(projectPath) {
892
- const fs = require('fs');
1046
+ const fs = require("fs");
893
1047
  try {
894
1048
  const items = fs.readdirSync(projectPath, { withFileTypes: true });
895
1049
  const directories = items
896
- .filter((item) => item.isDirectory() && !item.name.startsWith('.') && item.name !== 'node_modules')
1050
+ .filter((item) => item.isDirectory() &&
1051
+ !item.name.startsWith(".") &&
1052
+ item.name !== "node_modules")
897
1053
  .map((item) => `- ${item.name}/`)
898
- .join('\n');
899
- return directories || 'Directory structure to be analyzed';
1054
+ .join("\n");
1055
+ return directories || "Directory structure to be analyzed";
900
1056
  }
901
1057
  catch (error) {
902
- return 'Directory structure to be analyzed';
1058
+ return "Directory structure to be analyzed";
903
1059
  }
904
1060
  }
905
1061
  // Additional context-aware SDD tools
906
1062
  async function handleRequirementsSimplified(args) {
907
- const fs = await import('fs');
908
- const path = await import('path');
1063
+ const fs = await import("fs");
1064
+ const path = await import("path");
909
1065
  try {
910
1066
  const { featureName } = args;
911
- if (!featureName || typeof featureName !== 'string') {
912
- throw new Error('Feature name is required for requirements generation');
1067
+ if (!featureName || typeof featureName !== "string") {
1068
+ throw new Error("Feature name is required for requirements generation");
913
1069
  }
914
1070
  // Load spec context
915
1071
  const { spec, requirements } = await loadSpecContext(featureName);
@@ -917,7 +1073,7 @@ async function handleRequirementsSimplified(args) {
917
1073
  throw new Error(`Feature "${featureName}" not found. Run sdd-init first.`);
918
1074
  }
919
1075
  // Extract project description from spec
920
- let projectDescription = 'Feature requirements specification';
1076
+ let projectDescription = "Feature requirements specification";
921
1077
  if (requirements) {
922
1078
  const descMatch = requirements.match(/## Project Description \(Input\)\n([\s\S]*?)(?:\n##|$)/);
923
1079
  if (descMatch) {
@@ -927,21 +1083,23 @@ async function handleRequirementsSimplified(args) {
927
1083
  // Generate analysis-backed requirements with proper error handling
928
1084
  let requirementsContent;
929
1085
  let analysisUsed = false;
1086
+ // Check if fallback is allowed
1087
+ const allowFallback = process.env.SDD_ALLOW_TEMPLATE_FALLBACK === "true" ||
1088
+ args?.allowFallback === true;
930
1089
  try {
931
- console.error('[SDD-DEBUG] Attempting to import specGenerator for comprehensive analysis...');
932
- const { generateRequirementsDocument } = await import('./utils/specGenerator.js');
933
- console.error('[SDD-DEBUG] specGenerator imported successfully, generating requirements...');
1090
+ console.error("[SDD-DEBUG] Attempting to load specGenerator for comprehensive analysis...");
1091
+ const { generateRequirementsDocument } = await loadSpecGenerator();
1092
+ console.error("[SDD-DEBUG] specGenerator imported successfully, generating requirements...");
934
1093
  requirementsContent = await generateRequirementsDocument(process.cwd(), featureName);
935
1094
  analysisUsed = true;
936
- console.error('[SDD-DEBUG] ✅ Requirements generated using comprehensive codebase analysis');
1095
+ console.error("[SDD-DEBUG] ✅ Requirements generated using comprehensive codebase analysis");
937
1096
  }
938
1097
  catch (genErr) {
939
- console.error('[SDD-DEBUG] ⚠️ Comprehensive analysis failed, using fallback template');
940
- console.error('[SDD-DEBUG] Error details:', genErr.message);
941
- console.error('[SDD-DEBUG] Stack:', genErr.stack);
1098
+ // Use shared error handler
1099
+ const { useFallback, error } = handleLoaderFailure("specGenerator", genErr, allowFallback);
942
1100
  requirementsContent = `# Requirements Document
943
1101
 
944
- <!-- Note: Using basic template due to analysis error: ${genErr.message} -->
1102
+ <!-- Note: Using basic template due to analysis error: ${error.message} -->
945
1103
 
946
1104
  ## Introduction
947
1105
  ${generateIntroductionFromDescription(projectDescription)}
@@ -952,7 +1110,9 @@ ${generateIntroductionFromDescription(projectDescription)}
952
1110
  **Objective:** As a user, I want ${extractPrimaryObjective(projectDescription)}, so that ${extractPrimaryBenefit(projectDescription)}
953
1111
 
954
1112
  #### Acceptance Criteria
955
- ${generateEARSRequirements(projectDescription).map((req, index) => `${index + 1}. ${req}`).join('\n')}
1113
+ ${generateEARSRequirements(projectDescription)
1114
+ .map((req, index) => `${index + 1}. ${req}`)
1115
+ .join("\n")}
956
1116
 
957
1117
  ### Requirement 2: System Quality
958
1118
  **Objective:** As a user, I want the system to be reliable and performant, so that I can depend on it for my work
@@ -972,60 +1132,64 @@ ${generateEARSRequirements(projectDescription).map((req, index) => `${index + 1}
972
1132
  `;
973
1133
  }
974
1134
  // Update spec.json with phase information
975
- const specDir = path.join(process.cwd(), '.kiro', 'specs', featureName);
1135
+ const specDir = path.join(process.cwd(), ".kiro", "specs", featureName);
976
1136
  const updatedSpec = {
977
1137
  ...spec,
978
- phase: 'requirements-generated',
1138
+ phase: "requirements-generated",
979
1139
  approvals: {
980
1140
  ...spec.approvals,
981
1141
  requirements: {
982
1142
  generated: true,
983
- approved: false
984
- }
1143
+ approved: false,
1144
+ },
985
1145
  },
986
- updated_at: new Date().toISOString()
1146
+ updated_at: new Date().toISOString(),
987
1147
  };
988
- fs.writeFileSync(path.join(specDir, 'spec.json'), JSON.stringify(updatedSpec, null, 2));
989
- fs.writeFileSync(path.join(specDir, 'requirements.md'), requirementsContent);
1148
+ fs.writeFileSync(path.join(specDir, "spec.json"), JSON.stringify(updatedSpec, null, 2));
1149
+ fs.writeFileSync(path.join(specDir, "requirements.md"), requirementsContent);
990
1150
  return {
991
- content: [{
992
- type: 'text',
1151
+ content: [
1152
+ {
1153
+ type: "text",
993
1154
  text: `## Requirements Document Generated
994
1155
 
995
1156
  **Feature**: \`${featureName}\`
996
1157
  **File**: \`.kiro/specs/${featureName}/requirements.md\`
997
1158
 
998
- **Analysis Method**: ${analysisUsed ? '✅ Comprehensive codebase analysis (multi-language support)' : '⚠️ Basic template (analysis failed)'}
1159
+ **Analysis Method**: ${analysisUsed ? "✅ Comprehensive codebase analysis (multi-language support)" : "⚠️ Basic template (analysis failed)"}
999
1160
 
1000
1161
  **Generated Requirements**:
1001
1162
  - Core functionality requirements with EARS format
1002
1163
  - System quality and reliability requirements
1003
1164
  - Usability and user experience requirements
1004
1165
 
1005
- **Project Description**: "${projectDescription.substring(0, 100)}${projectDescription.length > 100 ? '...' : ''}"
1166
+ **Project Description**: "${projectDescription.substring(0, 100)}${projectDescription.length > 100 ? "..." : ""}"
1006
1167
 
1007
1168
  **Workflow Phase**: Requirements Generated
1008
- **Next Step**: Run \`sdd-design ${featureName}\` to create technical design (after requirements review)`
1009
- }]
1169
+ **Next Step**: Run \`sdd-design ${featureName}\` to create technical design (after requirements review)`,
1170
+ },
1171
+ ],
1010
1172
  };
1011
1173
  }
1012
1174
  catch (error) {
1013
1175
  return {
1014
- content: [{
1015
- type: 'text',
1016
- text: `Error generating requirements document: ${error.message}`
1017
- }],
1018
- isError: true
1176
+ content: [
1177
+ {
1178
+ type: "text",
1179
+ text: `Error generating requirements document: ${error.message}`,
1180
+ },
1181
+ ],
1182
+ isError: true,
1019
1183
  };
1020
1184
  }
1021
1185
  }
1022
1186
  async function handleDesignSimplified(args) {
1023
- const fs = await import('fs');
1024
- const path = await import('path');
1187
+ const fs = await import("fs");
1188
+ const path = await import("path");
1025
1189
  try {
1026
1190
  const { featureName } = args;
1027
- if (!featureName || typeof featureName !== 'string') {
1028
- throw new Error('Feature name is required for design generation');
1191
+ if (!featureName || typeof featureName !== "string") {
1192
+ throw new Error("Feature name is required for design generation");
1029
1193
  }
1030
1194
  // Load spec context
1031
1195
  const { spec, requirements } = await loadSpecContext(featureName);
@@ -1037,7 +1201,7 @@ async function handleDesignSimplified(args) {
1037
1201
  throw new Error(`Requirements must be generated before design. Run sdd-requirements ${featureName} first.`);
1038
1202
  }
1039
1203
  // Extract project description from requirements
1040
- let projectDescription = 'Technical design specification';
1204
+ let projectDescription = "Technical design specification";
1041
1205
  if (requirements) {
1042
1206
  const descMatch = requirements.match(/## Project Description \(Input\)\n([\s\S]*?)(?:\n##|$)/);
1043
1207
  if (descMatch) {
@@ -1047,20 +1211,23 @@ async function handleDesignSimplified(args) {
1047
1211
  // Generate analysis-backed design with proper error handling
1048
1212
  let designContent;
1049
1213
  let analysisUsed = false;
1214
+ // Check if fallback is allowed
1215
+ const allowFallback = process.env.SDD_ALLOW_TEMPLATE_FALLBACK === "true" ||
1216
+ args?.allowFallback === true;
1050
1217
  try {
1051
- console.error('[SDD-DEBUG] Attempting to import specGenerator for comprehensive design analysis...');
1052
- const { generateDesignDocument } = await import('./utils/specGenerator.js');
1053
- console.error('[SDD-DEBUG] specGenerator imported successfully, generating design...');
1218
+ console.error("[SDD-DEBUG] Attempting to load specGenerator for comprehensive design analysis...");
1219
+ const { generateDesignDocument } = await loadSpecGenerator();
1220
+ console.error("[SDD-DEBUG] specGenerator imported successfully, generating design...");
1054
1221
  designContent = await generateDesignDocument(process.cwd(), featureName);
1055
1222
  analysisUsed = true;
1056
- console.error('[SDD-DEBUG] ✅ Design generated using comprehensive codebase analysis');
1223
+ console.error("[SDD-DEBUG] ✅ Design generated using comprehensive codebase analysis");
1057
1224
  }
1058
1225
  catch (genErr) {
1059
- console.error('[SDD-DEBUG] ⚠️ Comprehensive analysis failed, using fallback template');
1060
- console.error('[SDD-DEBUG] Error details:', genErr.message);
1226
+ // Use shared error handler
1227
+ const { useFallback, error } = handleLoaderFailure("specGenerator", genErr, allowFallback);
1061
1228
  designContent = `# Technical Design Document
1062
1229
 
1063
- <!-- Note: Using basic template due to analysis error: ${genErr.message} -->
1230
+ <!-- Note: Using basic template due to analysis error: ${error.message} -->
1064
1231
 
1065
1232
  ## Overview
1066
1233
  This design document specifies the technical implementation approach for ${spec.feature_name}.
@@ -1075,30 +1242,31 @@ This design document specifies the technical implementation approach for ${spec.
1075
1242
  `;
1076
1243
  }
1077
1244
  // Update spec.json with phase information
1078
- const specDir = path.join(process.cwd(), '.kiro', 'specs', featureName);
1245
+ const specDir = path.join(process.cwd(), ".kiro", "specs", featureName);
1079
1246
  const updatedSpec = {
1080
1247
  ...spec,
1081
- phase: 'design-generated',
1248
+ phase: "design-generated",
1082
1249
  approvals: {
1083
1250
  ...spec.approvals,
1084
1251
  design: {
1085
1252
  generated: true,
1086
- approved: false
1087
- }
1253
+ approved: false,
1254
+ },
1088
1255
  },
1089
- updated_at: new Date().toISOString()
1256
+ updated_at: new Date().toISOString(),
1090
1257
  };
1091
- fs.writeFileSync(path.join(specDir, 'spec.json'), JSON.stringify(updatedSpec, null, 2));
1092
- fs.writeFileSync(path.join(specDir, 'design.md'), designContent);
1258
+ fs.writeFileSync(path.join(specDir, "spec.json"), JSON.stringify(updatedSpec, null, 2));
1259
+ fs.writeFileSync(path.join(specDir, "design.md"), designContent);
1093
1260
  return {
1094
- content: [{
1095
- type: 'text',
1261
+ content: [
1262
+ {
1263
+ type: "text",
1096
1264
  text: `## Design Document Generated
1097
1265
 
1098
1266
  **Feature**: \`${featureName}\`
1099
1267
  **File**: \`.kiro/specs/${featureName}/design.md\`
1100
1268
 
1101
- **Analysis Method**: ${analysisUsed ? '✅ Comprehensive codebase analysis (architecture patterns detected)' : '⚠️ Basic template (analysis failed)'}
1269
+ **Analysis Method**: ${analysisUsed ? "✅ Comprehensive codebase analysis (architecture patterns detected)" : "⚠️ Basic template (analysis failed)"}
1102
1270
 
1103
1271
  **Design Elements**:
1104
1272
  - Modular architecture with clear component separation
@@ -1106,30 +1274,33 @@ This design document specifies the technical implementation approach for ${spec.
1106
1274
  - Data models and error handling strategy
1107
1275
  - Complete testing approach
1108
1276
 
1109
- **Project Description**: "${projectDescription.substring(0, 100)}${projectDescription.length > 100 ? '...' : ''}"
1277
+ **Project Description**: "${projectDescription.substring(0, 100)}${projectDescription.length > 100 ? "..." : ""}"
1110
1278
 
1111
1279
  **Workflow Phase**: Design Generated
1112
- **Next Step**: Run \`sdd-tasks ${featureName}\` to generate implementation tasks (after design review)`
1113
- }]
1280
+ **Next Step**: Run \`sdd-tasks ${featureName}\` to generate implementation tasks (after design review)`,
1281
+ },
1282
+ ],
1114
1283
  };
1115
1284
  }
1116
1285
  catch (error) {
1117
1286
  return {
1118
- content: [{
1119
- type: 'text',
1120
- text: `Error generating design document: ${error.message}`
1121
- }],
1122
- isError: true
1287
+ content: [
1288
+ {
1289
+ type: "text",
1290
+ text: `Error generating design document: ${error.message}`,
1291
+ },
1292
+ ],
1293
+ isError: true,
1123
1294
  };
1124
1295
  }
1125
1296
  }
1126
1297
  async function handleTasksSimplified(args) {
1127
- const fs = await import('fs');
1128
- const path = await import('path');
1298
+ const fs = await import("fs");
1299
+ const path = await import("path");
1129
1300
  try {
1130
1301
  const { featureName } = args;
1131
- if (!featureName || typeof featureName !== 'string') {
1132
- throw new Error('Feature name is required for tasks generation');
1302
+ if (!featureName || typeof featureName !== "string") {
1303
+ throw new Error("Feature name is required for tasks generation");
1133
1304
  }
1134
1305
  // Load spec context
1135
1306
  const { spec } = await loadSpecContext(featureName);
@@ -1143,20 +1314,23 @@ async function handleTasksSimplified(args) {
1143
1314
  // Generate analysis-backed tasks with proper error handling
1144
1315
  let tasksContent;
1145
1316
  let analysisUsed = false;
1317
+ // Check if fallback is allowed
1318
+ const allowFallback = process.env.SDD_ALLOW_TEMPLATE_FALLBACK === "true" ||
1319
+ args?.allowFallback === true;
1146
1320
  try {
1147
- console.error('[SDD-DEBUG] Attempting to import specGenerator for comprehensive task analysis...');
1148
- const { generateTasksDocument } = await import('./utils/specGenerator.js');
1149
- console.error('[SDD-DEBUG] specGenerator imported successfully, generating tasks...');
1321
+ console.error("[SDD-DEBUG] Attempting to load specGenerator for comprehensive task analysis...");
1322
+ const { generateTasksDocument } = await loadSpecGenerator();
1323
+ console.error("[SDD-DEBUG] specGenerator imported successfully, generating tasks...");
1150
1324
  tasksContent = await generateTasksDocument(process.cwd(), featureName);
1151
1325
  analysisUsed = true;
1152
- console.error('[SDD-DEBUG] ✅ Tasks generated using comprehensive codebase analysis');
1326
+ console.error("[SDD-DEBUG] ✅ Tasks generated using comprehensive codebase analysis");
1153
1327
  }
1154
1328
  catch (genErr) {
1155
- console.error('[SDD-DEBUG] ⚠️ Comprehensive analysis failed, using fallback template');
1156
- console.error('[SDD-DEBUG] Error details:', genErr.message);
1329
+ // Use shared error handler
1330
+ const { useFallback, error } = handleLoaderFailure("specGenerator", genErr, allowFallback);
1157
1331
  tasksContent = `# Implementation Plan
1158
1332
 
1159
- <!-- Note: Using basic template due to analysis error: ${genErr.message} -->
1333
+ <!-- Note: Using basic template due to analysis error: ${error.message} -->
1160
1334
 
1161
1335
  - [ ] 1. Set up project foundation and infrastructure
1162
1336
  - [ ] 2. Implement core functionality
@@ -1166,31 +1340,32 @@ async function handleTasksSimplified(args) {
1166
1340
  `;
1167
1341
  }
1168
1342
  // Update spec.json with phase information
1169
- const specDir = path.join(process.cwd(), '.kiro', 'specs', featureName);
1343
+ const specDir = path.join(process.cwd(), ".kiro", "specs", featureName);
1170
1344
  const updatedSpec = {
1171
1345
  ...spec,
1172
- phase: 'tasks-generated',
1346
+ phase: "tasks-generated",
1173
1347
  approvals: {
1174
1348
  ...spec.approvals,
1175
1349
  tasks: {
1176
1350
  generated: true,
1177
- approved: false
1178
- }
1351
+ approved: false,
1352
+ },
1179
1353
  },
1180
1354
  ready_for_implementation: true,
1181
- updated_at: new Date().toISOString()
1355
+ updated_at: new Date().toISOString(),
1182
1356
  };
1183
- fs.writeFileSync(path.join(specDir, 'spec.json'), JSON.stringify(updatedSpec, null, 2));
1184
- fs.writeFileSync(path.join(specDir, 'tasks.md'), tasksContent);
1357
+ fs.writeFileSync(path.join(specDir, "spec.json"), JSON.stringify(updatedSpec, null, 2));
1358
+ fs.writeFileSync(path.join(specDir, "tasks.md"), tasksContent);
1185
1359
  return {
1186
- content: [{
1187
- type: 'text',
1360
+ content: [
1361
+ {
1362
+ type: "text",
1188
1363
  text: `## Implementation Tasks Generated
1189
1364
 
1190
1365
  **Feature**: \`${featureName}\`
1191
1366
  **File**: \`.kiro/specs/${featureName}/tasks.md\`
1192
1367
 
1193
- **Analysis Method**: ${analysisUsed ? '✅ Comprehensive codebase analysis (tech stack-aware tasks)' : '⚠️ Basic template (analysis failed)'}
1368
+ **Analysis Method**: ${analysisUsed ? "✅ Comprehensive codebase analysis (tech stack-aware tasks)" : "⚠️ Basic template (analysis failed)"}
1194
1369
 
1195
1370
  **Generated Tasks**:
1196
1371
  - Development, integration, quality, and deployment phases
@@ -1200,31 +1375,42 @@ async function handleTasksSimplified(args) {
1200
1375
 
1201
1376
  **Workflow Phase**: Tasks Generated
1202
1377
  **Status**: Ready for Implementation
1203
- **Next Step**: Begin implementation following the task sequence`
1204
- }]
1378
+ **Next Step**: Begin implementation following the task sequence`,
1379
+ },
1380
+ ],
1205
1381
  };
1206
1382
  }
1207
1383
  catch (error) {
1208
1384
  return {
1209
- content: [{
1210
- type: 'text',
1211
- text: `Error generating tasks document: ${error.message}`
1212
- }],
1213
- isError: true
1385
+ content: [
1386
+ {
1387
+ type: "text",
1388
+ text: `Error generating tasks document: ${error.message}`,
1389
+ },
1390
+ ],
1391
+ isError: true,
1214
1392
  };
1215
1393
  }
1216
1394
  }
1217
1395
  // Helper functions for simplified tool implementations
1218
1396
  function analyzeProjectStructureSync(projectPath) {
1219
- const fs = require('fs');
1397
+ const fs = require("fs");
1220
1398
  try {
1221
1399
  const items = fs.readdirSync(projectPath, { withFileTypes: true });
1222
1400
  return {
1223
- directories: items.filter((item) => item.isDirectory() && !item.name.startsWith('.') && item.name !== 'node_modules').map((item) => item.name),
1224
- files: items.filter((item) => item.isFile()).map((item) => item.name),
1225
- hasSource: items.some((item) => item.isDirectory() && item.name === 'src'),
1226
- hasTests: items.some((item) => item.isDirectory() && (item.name === 'test' || item.name === '__tests__')),
1227
- hasDocs: items.some((item) => item.isDirectory() && (item.name === 'docs' || item.name === 'documentation'))
1401
+ directories: items
1402
+ .filter((item) => item.isDirectory() &&
1403
+ !item.name.startsWith(".") &&
1404
+ item.name !== "node_modules")
1405
+ .map((item) => item.name),
1406
+ files: items
1407
+ .filter((item) => item.isFile())
1408
+ .map((item) => item.name),
1409
+ hasSource: items.some((item) => item.isDirectory() && item.name === "src"),
1410
+ hasTests: items.some((item) => item.isDirectory() &&
1411
+ (item.name === "test" || item.name === "__tests__")),
1412
+ hasDocs: items.some((item) => item.isDirectory() &&
1413
+ (item.name === "docs" || item.name === "documentation")),
1228
1414
  };
1229
1415
  }
1230
1416
  catch (error) {
@@ -1236,149 +1422,180 @@ function generateCoreObjectiveSimplified(packageJson, projectAnalysis) {
1236
1422
  return `Deliver ${packageJson.description} with full functionality and reliability`;
1237
1423
  }
1238
1424
  if (packageJson.keywords?.length > 0) {
1239
- return `Implement ${packageJson.keywords.join(', ')} functionality`;
1425
+ return `Implement ${packageJson.keywords.join(", ")} functionality`;
1240
1426
  }
1241
- return 'Deliver core application functionality';
1427
+ return "Deliver core application functionality";
1242
1428
  }
1243
1429
  function generateAcceptanceCriteriaSimplified(packageJson, projectAnalysis) {
1244
1430
  const criteria = [];
1245
1431
  if (packageJson.scripts?.test) {
1246
- criteria.push('WHEN tests are run THEN all tests SHALL pass');
1432
+ criteria.push("WHEN tests are run THEN all tests SHALL pass");
1247
1433
  }
1248
1434
  if (packageJson.scripts?.build) {
1249
- criteria.push('WHEN build is executed THEN system SHALL compile without errors');
1435
+ criteria.push("WHEN build is executed THEN system SHALL compile without errors");
1250
1436
  }
1251
1437
  if (packageJson.scripts?.lint) {
1252
- criteria.push('WHERE code quality is checked THE system SHALL meet linting standards');
1438
+ criteria.push("WHERE code quality is checked THE system SHALL meet linting standards");
1253
1439
  }
1254
1440
  if (packageJson.main || packageJson.bin) {
1255
- criteria.push('WHEN application starts THEN system SHALL initialize successfully');
1441
+ criteria.push("WHEN application starts THEN system SHALL initialize successfully");
1256
1442
  }
1257
- criteria.push('IF errors occur THEN system SHALL handle them gracefully');
1258
- return criteria.length > 0 ? criteria : ['System SHALL meet functional requirements'];
1443
+ criteria.push("IF errors occur THEN system SHALL handle them gracefully");
1444
+ return criteria.length > 0
1445
+ ? criteria
1446
+ : ["System SHALL meet functional requirements"];
1259
1447
  }
1260
1448
  function generateTechRequirementsSimplified(packageJson) {
1261
1449
  const requirements = [];
1262
1450
  const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
1263
1451
  if (deps?.typescript) {
1264
- requirements.push('System SHALL use TypeScript for type safety');
1452
+ requirements.push("System SHALL use TypeScript for type safety");
1265
1453
  }
1266
1454
  if (deps?.express || deps?.fastify) {
1267
- requirements.push('System SHALL implement RESTful API endpoints');
1455
+ requirements.push("System SHALL implement RESTful API endpoints");
1268
1456
  }
1269
1457
  if (deps?.react || deps?.vue || deps?.angular) {
1270
- requirements.push('System SHALL provide responsive user interface');
1458
+ requirements.push("System SHALL provide responsive user interface");
1271
1459
  }
1272
1460
  if (deps?.jest || deps?.mocha || deps?.vitest) {
1273
- requirements.push('System SHALL include comprehensive test coverage');
1461
+ requirements.push("System SHALL include comprehensive test coverage");
1274
1462
  }
1275
- return requirements.length > 0 ? requirements : ['System SHALL integrate required technologies'];
1463
+ return requirements.length > 0
1464
+ ? requirements
1465
+ : ["System SHALL integrate required technologies"];
1276
1466
  }
1277
1467
  function generateQualityRequirementsSimplified(packageJson) {
1278
1468
  const requirements = [];
1279
1469
  if (packageJson.scripts?.lint) {
1280
- requirements.push('Code SHALL pass linting checks');
1470
+ requirements.push("Code SHALL pass linting checks");
1281
1471
  }
1282
1472
  if (packageJson.scripts?.typecheck) {
1283
- requirements.push('Code SHALL pass type checking');
1473
+ requirements.push("Code SHALL pass type checking");
1284
1474
  }
1285
1475
  if (packageJson.scripts?.test) {
1286
- requirements.push('Code SHALL maintain test coverage standards');
1476
+ requirements.push("Code SHALL maintain test coverage standards");
1287
1477
  }
1288
- requirements.push('Code SHALL follow established conventions');
1478
+ requirements.push("Code SHALL follow established conventions");
1289
1479
  return requirements;
1290
1480
  }
1291
1481
  function generateArchitectureDescriptionSimplified(packageJson, projectAnalysis) {
1292
- let description = '';
1293
- if (packageJson.type === 'module') {
1294
- description += 'Modern ES Module-based architecture. ';
1482
+ let description = "";
1483
+ if (packageJson.type === "module") {
1484
+ description += "Modern ES Module-based architecture. ";
1295
1485
  }
1296
1486
  if (projectAnalysis.hasSource) {
1297
- description += 'Modular source code organization with clear separation of concerns. ';
1487
+ description +=
1488
+ "Modular source code organization with clear separation of concerns. ";
1298
1489
  }
1299
1490
  if (packageJson.dependencies?.express) {
1300
- description += 'RESTful API server architecture using Express.js framework. ';
1491
+ description +=
1492
+ "RESTful API server architecture using Express.js framework. ";
1301
1493
  }
1302
- if (packageJson.dependencies?.typescript || packageJson.devDependencies?.typescript) {
1303
- description += 'Type-safe development with TypeScript compilation. ';
1494
+ if (packageJson.dependencies?.typescript ||
1495
+ packageJson.devDependencies?.typescript) {
1496
+ description += "Type-safe development with TypeScript compilation. ";
1304
1497
  }
1305
- return description || 'Application architecture to be defined based on requirements.';
1498
+ return (description ||
1499
+ "Application architecture to be defined based on requirements.");
1306
1500
  }
1307
1501
  function generateComponentDescriptionsSimplified(projectAnalysis) {
1308
1502
  const components = [];
1309
1503
  if (projectAnalysis.hasSource) {
1310
- components.push({ name: 'Core Module', description: 'Main application logic and business rules' });
1504
+ components.push({
1505
+ name: "Core Module",
1506
+ description: "Main application logic and business rules",
1507
+ });
1311
1508
  }
1312
1509
  if (projectAnalysis.hasTests) {
1313
- components.push({ name: 'Test Suite', description: 'Automated testing framework and test cases' });
1510
+ components.push({
1511
+ name: "Test Suite",
1512
+ description: "Automated testing framework and test cases",
1513
+ });
1314
1514
  }
1315
1515
  if (projectAnalysis.hasDocs) {
1316
- components.push({ name: 'Documentation', description: 'Project documentation and API specifications' });
1516
+ components.push({
1517
+ name: "Documentation",
1518
+ description: "Project documentation and API specifications",
1519
+ });
1317
1520
  }
1318
- return components.length > 0 ? components : [
1319
- { name: 'Application Core', description: 'Main application functionality' }
1320
- ];
1521
+ return components.length > 0
1522
+ ? components
1523
+ : [
1524
+ {
1525
+ name: "Application Core",
1526
+ description: "Main application functionality",
1527
+ },
1528
+ ];
1321
1529
  }
1322
1530
  function generateDataModelsSimplified(packageJson, projectAnalysis) {
1323
1531
  const models = [];
1324
1532
  if (packageJson.dependencies?.mongoose || packageJson.dependencies?.mongodb) {
1325
- models.push('MongoDB Document Models');
1533
+ models.push("MongoDB Document Models");
1326
1534
  }
1327
- if (packageJson.dependencies?.sequelize || packageJson.dependencies?.typeorm) {
1328
- models.push('Relational Database Models');
1535
+ if (packageJson.dependencies?.sequelize ||
1536
+ packageJson.dependencies?.typeorm) {
1537
+ models.push("Relational Database Models");
1329
1538
  }
1330
1539
  if (packageJson.dependencies?.graphql) {
1331
- models.push('GraphQL Schema Models');
1540
+ models.push("GraphQL Schema Models");
1332
1541
  }
1333
- return models.length > 0 ? models : ['Application Data Models'];
1542
+ return models.length > 0 ? models : ["Application Data Models"];
1334
1543
  }
1335
1544
  function generateDetailedTechStackSimplified(packageJson) {
1336
1545
  const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
1337
1546
  const stack = [];
1338
1547
  if (deps?.typescript)
1339
- stack.push('- **TypeScript**: Type-safe JavaScript development');
1548
+ stack.push("- **TypeScript**: Type-safe JavaScript development");
1340
1549
  if (deps?.node || packageJson.engines?.node)
1341
- stack.push(`- **Node.js**: ${packageJson.engines?.node || 'Runtime environment'}`);
1550
+ stack.push(`- **Node.js**: ${packageJson.engines?.node || "Runtime environment"}`);
1342
1551
  if (deps?.express)
1343
- stack.push('- **Express.js**: Web application framework');
1552
+ stack.push("- **Express.js**: Web application framework");
1344
1553
  if (deps?.react)
1345
- stack.push('- **React**: User interface library');
1554
+ stack.push("- **React**: User interface library");
1346
1555
  if (deps?.vue)
1347
- stack.push('- **Vue.js**: Progressive frontend framework');
1556
+ stack.push("- **Vue.js**: Progressive frontend framework");
1348
1557
  if (deps?.jest)
1349
- stack.push('- **Jest**: Testing framework');
1350
- return stack.length > 0 ? stack.join('\n') : '- Technology stack to be defined';
1558
+ stack.push("- **Jest**: Testing framework");
1559
+ return stack.length > 0
1560
+ ? stack.join("\n")
1561
+ : "- Technology stack to be defined";
1351
1562
  }
1352
1563
  function generateDesignPatternsSimplified(packageJson, projectAnalysis) {
1353
1564
  const patterns = [];
1354
1565
  if (packageJson.dependencies?.inversify) {
1355
- patterns.push('Dependency Injection');
1566
+ patterns.push("Dependency Injection");
1356
1567
  }
1357
1568
  if (projectAnalysis.hasSource) {
1358
- patterns.push('Modular Architecture');
1569
+ patterns.push("Modular Architecture");
1359
1570
  }
1360
1571
  if (packageJson.dependencies?.express || packageJson.dependencies?.fastify) {
1361
- patterns.push('MVC Pattern');
1572
+ patterns.push("MVC Pattern");
1362
1573
  }
1363
- return patterns.length > 0 ? patterns : ['Standard Design Patterns'];
1574
+ return patterns.length > 0 ? patterns : ["Standard Design Patterns"];
1364
1575
  }
1365
1576
  function generateDependencyAnalysisSimplified(packageJson) {
1366
1577
  const production = Object.keys(packageJson.dependencies || {});
1367
1578
  const development = Object.keys(packageJson.devDependencies || {});
1368
- let analysis = '';
1579
+ let analysis = "";
1369
1580
  if (production.length > 0) {
1370
1581
  analysis += `**Production Dependencies:** ${production.length} packages\n`;
1371
- analysis += production.slice(0, 5).map(dep => `- ${dep}`).join('\n');
1582
+ analysis += production
1583
+ .slice(0, 5)
1584
+ .map((dep) => `- ${dep}`)
1585
+ .join("\n");
1372
1586
  if (production.length > 5)
1373
1587
  analysis += `\n- ... and ${production.length - 5} more`;
1374
1588
  }
1375
1589
  if (development.length > 0) {
1376
1590
  analysis += `\n\n**Development Dependencies:** ${development.length} packages\n`;
1377
- analysis += development.slice(0, 5).map(dep => `- ${dep}`).join('\n');
1591
+ analysis += development
1592
+ .slice(0, 5)
1593
+ .map((dep) => `- ${dep}`)
1594
+ .join("\n");
1378
1595
  if (development.length > 5)
1379
1596
  analysis += `\n- ... and ${development.length - 5} more`;
1380
1597
  }
1381
- return analysis || 'Dependencies to be analyzed';
1598
+ return analysis || "Dependencies to be analyzed";
1382
1599
  }
1383
1600
  function generateAPIInterfacesSimplified(packageJson, projectAnalysis) {
1384
1601
  if (packageJson.dependencies?.express || packageJson.dependencies?.fastify) {
@@ -1388,7 +1605,7 @@ function generateAPIInterfacesSimplified(packageJson, projectAnalysis) {
1388
1605
  - Request/response validation
1389
1606
  - Error handling middleware`;
1390
1607
  }
1391
- return 'Interface specifications to be defined';
1608
+ return "Interface specifications to be defined";
1392
1609
  }
1393
1610
  function generateModuleInterfacesSimplified(projectAnalysis) {
1394
1611
  if (projectAnalysis.hasSource) {
@@ -1397,87 +1614,115 @@ function generateModuleInterfacesSimplified(projectAnalysis) {
1397
1614
  - Consistent API patterns across modules
1398
1615
  - Type definitions for all public interfaces`;
1399
1616
  }
1400
- return 'Module interfaces to be defined';
1617
+ return "Module interfaces to be defined";
1401
1618
  }
1402
1619
  function generateEnvVarSpecsSimplified(packageJson) {
1403
1620
  const envVars = [];
1404
1621
  if (packageJson.dependencies?.express || packageJson.dependencies?.fastify) {
1405
- envVars.push('- `PORT`: Server port (default: 3000)');
1406
- envVars.push('- `NODE_ENV`: Environment mode (development/production)');
1622
+ envVars.push("- `PORT`: Server port (default: 3000)");
1623
+ envVars.push("- `NODE_ENV`: Environment mode (development/production)");
1407
1624
  }
1408
- envVars.push('- `LOG_LEVEL`: Logging level (debug/info/warn/error)');
1409
- return envVars.join('\n');
1625
+ envVars.push("- `LOG_LEVEL`: Logging level (debug/info/warn/error)");
1626
+ return envVars.join("\n");
1410
1627
  }
1411
1628
  function generateBuildConfigSimplified(packageJson) {
1412
- let config = '';
1629
+ let config = "";
1413
1630
  if (packageJson.scripts?.build) {
1414
1631
  config += `Build process: \`${packageJson.scripts.build}\`\n`;
1415
1632
  }
1416
1633
  if (packageJson.scripts?.start) {
1417
1634
  config += `Start command: \`${packageJson.scripts.start}\`\n`;
1418
1635
  }
1419
- if (packageJson.type === 'module') {
1420
- config += 'Module type: ES Modules\n';
1636
+ if (packageJson.type === "module") {
1637
+ config += "Module type: ES Modules\n";
1421
1638
  }
1422
- return config || 'Build configuration to be defined';
1639
+ return config || "Build configuration to be defined";
1423
1640
  }
1424
1641
  function generateImplementationTasksSimplified(packageJson, projectAnalysis) {
1425
1642
  const tasks = {
1426
1643
  development: [],
1427
1644
  integration: [],
1428
1645
  quality: [],
1429
- deployment: []
1646
+ deployment: [],
1430
1647
  };
1431
1648
  // Development tasks
1432
1649
  if (projectAnalysis.hasSource) {
1433
1650
  tasks.development.push({
1434
- title: 'Implement Core Modules',
1435
- subtasks: ['Set up module structure', 'Implement business logic', 'Add error handling'],
1436
- requirements: 'FR-1, FR-2'
1651
+ title: "Implement Core Modules",
1652
+ subtasks: [
1653
+ "Set up module structure",
1654
+ "Implement business logic",
1655
+ "Add error handling",
1656
+ ],
1657
+ requirements: "FR-1, FR-2",
1437
1658
  });
1438
1659
  }
1439
1660
  if (packageJson.dependencies?.express) {
1440
1661
  tasks.development.push({
1441
- title: 'Develop API Endpoints',
1442
- subtasks: ['Create route handlers', 'Add middleware', 'Implement validation'],
1443
- requirements: 'FR-2'
1662
+ title: "Develop API Endpoints",
1663
+ subtasks: [
1664
+ "Create route handlers",
1665
+ "Add middleware",
1666
+ "Implement validation",
1667
+ ],
1668
+ requirements: "FR-2",
1444
1669
  });
1445
1670
  }
1446
1671
  // Integration tasks
1447
1672
  if (packageJson.dependencies?.mongodb || packageJson.dependencies?.mongoose) {
1448
1673
  tasks.integration.push({
1449
- title: 'Database Integration',
1450
- subtasks: ['Set up database connection', 'Create data models', 'Implement queries'],
1451
- requirements: 'NFR-2'
1674
+ title: "Database Integration",
1675
+ subtasks: [
1676
+ "Set up database connection",
1677
+ "Create data models",
1678
+ "Implement queries",
1679
+ ],
1680
+ requirements: "NFR-2",
1452
1681
  });
1453
1682
  }
1454
1683
  // Quality tasks
1455
1684
  if (packageJson.scripts?.test) {
1456
1685
  tasks.quality.push({
1457
- title: 'Test Implementation',
1458
- subtasks: ['Write unit tests', 'Add integration tests', 'Ensure test coverage'],
1459
- requirements: 'FR-3, NFR-3'
1686
+ title: "Test Implementation",
1687
+ subtasks: [
1688
+ "Write unit tests",
1689
+ "Add integration tests",
1690
+ "Ensure test coverage",
1691
+ ],
1692
+ requirements: "FR-3, NFR-3",
1460
1693
  });
1461
1694
  }
1462
1695
  if (packageJson.scripts?.lint) {
1463
1696
  tasks.quality.push({
1464
- title: 'Code Quality Assurance',
1465
- subtasks: ['Run linting checks', 'Fix code style issues', 'Add documentation'],
1466
- requirements: 'NFR-3'
1697
+ title: "Code Quality Assurance",
1698
+ subtasks: [
1699
+ "Run linting checks",
1700
+ "Fix code style issues",
1701
+ "Add documentation",
1702
+ ],
1703
+ requirements: "NFR-3",
1467
1704
  });
1468
1705
  }
1469
1706
  // Deployment tasks
1470
1707
  if (packageJson.scripts?.build) {
1471
1708
  tasks.deployment.push({
1472
- title: 'Build and Package',
1473
- subtasks: ['Run build process', 'Optimize for production', 'Create deployment artifacts'],
1474
- requirements: 'NFR-1'
1709
+ title: "Build and Package",
1710
+ subtasks: [
1711
+ "Run build process",
1712
+ "Optimize for production",
1713
+ "Create deployment artifacts",
1714
+ ],
1715
+ requirements: "NFR-1",
1475
1716
  });
1476
1717
  }
1477
1718
  tasks.deployment.push({
1478
- title: 'Deployment Configuration',
1479
- subtasks: ['Set up environment variables', 'Configure production settings', 'Deploy to target environment'],
1480
- requirements: 'NFR-1, NFR-2'
1719
+ title: "Deployment Configuration",
1720
+ subtasks: [
1721
+ "Set up environment variables",
1722
+ "Configure production settings",
1723
+ "Deploy to target environment",
1724
+ ],
1725
+ requirements: "NFR-1, NFR-2",
1481
1726
  });
1482
1727
  return tasks;
1483
1728
  }
@@ -1488,45 +1733,49 @@ function generateIntroductionFromDescription(description) {
1488
1733
  }
1489
1734
  function extractSystemName(description) {
1490
1735
  // Extract a system name from description
1491
- const words = description.split(' ');
1736
+ const words = description.split(" ");
1492
1737
  if (words.length >= 2) {
1493
- return `the ${words.slice(0, 3).join(' ')}`;
1738
+ return `the ${words.slice(0, 3).join(" ")}`;
1494
1739
  }
1495
- return 'the system';
1740
+ return "the system";
1496
1741
  }
1497
1742
  function extractPrimaryObjective(description) {
1498
1743
  // Convert description into user objective
1499
- if (description.toLowerCase().includes('tool') || description.toLowerCase().includes('cli')) {
1744
+ if (description.toLowerCase().includes("tool") ||
1745
+ description.toLowerCase().includes("cli")) {
1500
1746
  return `use a tool that ${description.toLowerCase()}`;
1501
1747
  }
1502
- if (description.toLowerCase().includes('system') || description.toLowerCase().includes('application')) {
1748
+ if (description.toLowerCase().includes("system") ||
1749
+ description.toLowerCase().includes("application")) {
1503
1750
  return `access a system that ${description.toLowerCase()}`;
1504
1751
  }
1505
1752
  return `have functionality that ${description.toLowerCase()}`;
1506
1753
  }
1507
1754
  function extractPrimaryBenefit(description) {
1508
1755
  // Infer benefit from description
1509
- if (description.toLowerCase().includes('automate')) {
1510
- return 'I can save time and reduce manual effort';
1756
+ if (description.toLowerCase().includes("automate")) {
1757
+ return "I can save time and reduce manual effort";
1511
1758
  }
1512
- if (description.toLowerCase().includes('analyze') || description.toLowerCase().includes('review')) {
1513
- return 'I can make better informed decisions';
1759
+ if (description.toLowerCase().includes("analyze") ||
1760
+ description.toLowerCase().includes("review")) {
1761
+ return "I can make better informed decisions";
1514
1762
  }
1515
- if (description.toLowerCase().includes('manage') || description.toLowerCase().includes('organize')) {
1516
- return 'I can maintain better control and organization';
1763
+ if (description.toLowerCase().includes("manage") ||
1764
+ description.toLowerCase().includes("organize")) {
1765
+ return "I can maintain better control and organization";
1517
1766
  }
1518
- return 'I can accomplish my goals more effectively';
1767
+ return "I can accomplish my goals more effectively";
1519
1768
  }
1520
1769
  function generateEARSRequirements(description) {
1521
1770
  const requirements = [];
1522
1771
  // Core functional requirement
1523
1772
  requirements.push(`WHEN I use the system THEN it SHALL provide ${description.toLowerCase()} functionality`);
1524
1773
  // Input/output handling
1525
- requirements.push('WHEN I provide input THEN the system SHALL validate and process it correctly');
1774
+ requirements.push("WHEN I provide input THEN the system SHALL validate and process it correctly");
1526
1775
  // Error handling
1527
- requirements.push('IF invalid input is provided THEN the system SHALL reject it with clear error messages');
1776
+ requirements.push("IF invalid input is provided THEN the system SHALL reject it with clear error messages");
1528
1777
  // Success condition
1529
- requirements.push('WHEN all inputs are valid THEN the system SHALL complete the requested operation successfully');
1778
+ requirements.push("WHEN all inputs are valid THEN the system SHALL complete the requested operation successfully");
1530
1779
  return requirements;
1531
1780
  }
1532
1781
  // Helper functions for kiro-style workflow
@@ -1534,18 +1783,18 @@ function generateFeatureName(description) {
1534
1783
  // Extract feature name from description - similar to kiro spec-init
1535
1784
  const cleaned = description
1536
1785
  .toLowerCase()
1537
- .replace(/[^a-z0-9\s]/g, '')
1786
+ .replace(/[^a-z0-9\s]/g, "")
1538
1787
  .trim()
1539
1788
  .split(/\s+/)
1540
1789
  .slice(0, 4) // Take first 4 words
1541
- .join('-');
1790
+ .join("-");
1542
1791
  // Ensure it's not empty
1543
- return cleaned || 'new-feature';
1792
+ return cleaned || "new-feature";
1544
1793
  }
1545
1794
  async function ensureUniqueFeatureName(baseName) {
1546
- const fs = await import('fs');
1547
- const path = await import('path');
1548
- const specsDir = path.join(process.cwd(), '.kiro', 'specs');
1795
+ const fs = await import("fs");
1796
+ const path = await import("path");
1797
+ const specsDir = path.join(process.cwd(), ".kiro", "specs");
1549
1798
  if (!fs.existsSync(specsDir)) {
1550
1799
  return baseName;
1551
1800
  }
@@ -1558,16 +1807,16 @@ async function ensureUniqueFeatureName(baseName) {
1558
1807
  return featureName;
1559
1808
  }
1560
1809
  async function loadSpecContext(featureName) {
1561
- const fs = await import('fs');
1562
- const path = await import('path');
1563
- const specDir = path.join(process.cwd(), '.kiro', 'specs', featureName);
1564
- const specJsonPath = path.join(specDir, 'spec.json');
1565
- const requirementsPath = path.join(specDir, 'requirements.md');
1810
+ const fs = await import("fs");
1811
+ const path = await import("path");
1812
+ const specDir = path.join(process.cwd(), ".kiro", "specs", featureName);
1813
+ const specJsonPath = path.join(specDir, "spec.json");
1814
+ const requirementsPath = path.join(specDir, "requirements.md");
1566
1815
  let spec = null;
1567
1816
  let requirements = null;
1568
1817
  try {
1569
1818
  if (fs.existsSync(specJsonPath)) {
1570
- const specContent = fs.readFileSync(specJsonPath, 'utf8');
1819
+ const specContent = fs.readFileSync(specJsonPath, "utf8");
1571
1820
  spec = JSON.parse(specContent);
1572
1821
  }
1573
1822
  }
@@ -1576,7 +1825,7 @@ async function loadSpecContext(featureName) {
1576
1825
  }
1577
1826
  try {
1578
1827
  if (fs.existsSync(requirementsPath)) {
1579
- requirements = fs.readFileSync(requirementsPath, 'utf8');
1828
+ requirements = fs.readFileSync(requirementsPath, "utf8");
1580
1829
  }
1581
1830
  }
1582
1831
  catch (error) {
@@ -1585,19 +1834,19 @@ async function loadSpecContext(featureName) {
1585
1834
  return { spec, requirements };
1586
1835
  }
1587
1836
  async function handleInitSimplified(args) {
1588
- const fs = await import('fs');
1589
- const path = await import('path');
1837
+ const fs = await import("fs");
1838
+ const path = await import("path");
1590
1839
  try {
1591
1840
  const { description } = args;
1592
- if (!description || typeof description !== 'string') {
1593
- throw new Error('Description is required for project initialization');
1841
+ if (!description || typeof description !== "string") {
1842
+ throw new Error("Description is required for project initialization");
1594
1843
  }
1595
1844
  const projectPath = process.cwd();
1596
1845
  // Generate feature name from description
1597
1846
  const baseFeatureName = generateFeatureName(description);
1598
1847
  const featureName = await ensureUniqueFeatureName(baseFeatureName);
1599
1848
  // Create .kiro/specs/[feature-name] directory
1600
- const specDir = path.join(projectPath, '.kiro', 'specs', featureName);
1849
+ const specDir = path.join(projectPath, ".kiro", "specs", featureName);
1601
1850
  if (!fs.existsSync(specDir)) {
1602
1851
  fs.mkdirSync(specDir, { recursive: true });
1603
1852
  }
@@ -1606,25 +1855,25 @@ async function handleInitSimplified(args) {
1606
1855
  feature_name: featureName,
1607
1856
  created_at: new Date().toISOString(),
1608
1857
  updated_at: new Date().toISOString(),
1609
- language: 'en',
1610
- phase: 'initialized',
1858
+ language: "en",
1859
+ phase: "initialized",
1611
1860
  approvals: {
1612
1861
  requirements: {
1613
1862
  generated: false,
1614
- approved: false
1863
+ approved: false,
1615
1864
  },
1616
1865
  design: {
1617
1866
  generated: false,
1618
- approved: false
1867
+ approved: false,
1619
1868
  },
1620
1869
  tasks: {
1621
1870
  generated: false,
1622
- approved: false
1623
- }
1871
+ approved: false,
1872
+ },
1624
1873
  },
1625
- ready_for_implementation: false
1874
+ ready_for_implementation: false,
1626
1875
  };
1627
- fs.writeFileSync(path.join(specDir, 'spec.json'), JSON.stringify(specContent, null, 2));
1876
+ fs.writeFileSync(path.join(specDir, "spec.json"), JSON.stringify(specContent, null, 2));
1628
1877
  // Create requirements.md template with project description
1629
1878
  const requirementsTemplate = `# Requirements Document
1630
1879
 
@@ -1634,20 +1883,20 @@ ${description}
1634
1883
  ## Requirements
1635
1884
  <!-- Will be generated in sdd-requirements phase -->
1636
1885
  `;
1637
- fs.writeFileSync(path.join(specDir, 'requirements.md'), requirementsTemplate);
1886
+ fs.writeFileSync(path.join(specDir, "requirements.md"), requirementsTemplate);
1638
1887
  // Ensure AGENTS.md exists (static, derived from CLAUDE.md when available)
1639
- const agentsPath = path.join(process.cwd(), 'AGENTS.md');
1888
+ const agentsPath = path.join(process.cwd(), "AGENTS.md");
1640
1889
  if (!fs.existsSync(agentsPath)) {
1641
- const claudePath = path.join(process.cwd(), 'CLAUDE.md');
1642
- let agentsContent = '';
1890
+ const claudePath = path.join(process.cwd(), "CLAUDE.md");
1891
+ let agentsContent = "";
1643
1892
  if (fs.existsSync(claudePath)) {
1644
- const claudeContent = fs.readFileSync(claudePath, 'utf8');
1893
+ const claudeContent = fs.readFileSync(claudePath, "utf8");
1645
1894
  agentsContent = claudeContent
1646
- .replace(/# Claude Code Spec-Driven Development/g, '# AI Agent Spec-Driven Development')
1647
- .replace(/Claude Code/g, 'AI Agent')
1648
- .replace(/claude code/g, 'ai agent')
1649
- .replace(/Claude/g, 'AI Agent')
1650
- .replace(/claude/g, 'ai agent');
1895
+ .replace(/# Claude Code Spec-Driven Development/g, "# AI Agent Spec-Driven Development")
1896
+ .replace(/Claude Code/g, "AI Agent")
1897
+ .replace(/claude code/g, "ai agent")
1898
+ .replace(/Claude/g, "AI Agent")
1899
+ .replace(/claude/g, "ai agent");
1651
1900
  }
1652
1901
  else {
1653
1902
  agentsContent = `# AI Agent Spec-Driven Development
@@ -1730,8 +1979,9 @@ Managed by \`/kiro:steering\` command. Updates here reflect command changes.
1730
1979
  fs.writeFileSync(agentsPath, agentsContent);
1731
1980
  }
1732
1981
  return {
1733
- content: [{
1734
- type: 'text',
1982
+ content: [
1983
+ {
1984
+ type: "text",
1735
1985
  text: `## SDD Project Initialized Successfully
1736
1986
 
1737
1987
  **Feature Name**: \`${featureName}\`
@@ -1746,17 +1996,20 @@ Managed by \`/kiro:steering\` command. Updates here reflect command changes.
1746
1996
  2. Follow the SDD workflow: Requirements → Design → Tasks → Implementation
1747
1997
 
1748
1998
  **Workflow Phase**: Initialized
1749
- **Ready for**: Requirements generation`
1750
- }]
1999
+ **Ready for**: Requirements generation`,
2000
+ },
2001
+ ],
1751
2002
  };
1752
2003
  }
1753
2004
  catch (error) {
1754
2005
  return {
1755
- content: [{
1756
- type: 'text',
1757
- text: `Error initializing SDD project: ${error.message}`
1758
- }],
1759
- isError: true
2006
+ content: [
2007
+ {
2008
+ type: "text",
2009
+ text: `Error initializing SDD project: ${error.message}`,
2010
+ },
2011
+ ],
2012
+ isError: true,
1760
2013
  };
1761
2014
  }
1762
2015
  }
@@ -1769,11 +2022,11 @@ async function main() {
1769
2022
  else {
1770
2023
  // Use full featured server for development/testing mode
1771
2024
  const server = await createMCPServer();
1772
- const { logger, mcpServer, pluginManager, hookSystem, toolRegistry, steeringRegistry } = server;
1773
- logger.info('MCP SDD Server starting...', {
1774
- version: process.env.npm_package_version ?? '1.0.0',
2025
+ const { logger, mcpServer, pluginManager, hookSystem, toolRegistry, steeringRegistry, } = server;
2026
+ logger.info("MCP SDD Server starting...", {
2027
+ version: process.env.npm_package_version ?? "1.0.0",
1775
2028
  nodeVersion: process.version,
1776
- pid: process.pid
2029
+ pid: process.pid,
1777
2030
  });
1778
2031
  await mcpServer.start();
1779
2032
  // Get plugin system statistics
@@ -1781,41 +2034,63 @@ async function main() {
1781
2034
  const hookStats = await hookSystem.getAllHooks();
1782
2035
  const toolStats = await toolRegistry.getAllTools();
1783
2036
  const steeringStats = await steeringRegistry.getSteeringStatistics();
1784
- logger.info('MCP SDD Server ready for connections', {
2037
+ logger.info("MCP SDD Server ready for connections", {
1785
2038
  capabilities: {
1786
- workflow: '5-phase SDD workflow state machine (INIT→REQUIREMENTS→DESIGN→TASKS→IMPLEMENTATION)',
1787
- validation: 'Cross-phase validation with approval gates and rollback support',
1788
- initialization: 'Project setup with .kiro directory structure and spec.json',
1789
- context: 'Project memory with codebase analysis and context persistence',
1790
- steering: 'Dynamic steering document management with Always/Conditional/Manual modes',
1791
- quality: 'Linus-style code review with 5-layer analysis framework',
1792
- i18n: '10-language support with cultural adaptation',
2039
+ workflow: "5-phase SDD workflow state machine (INIT→REQUIREMENTS→DESIGN→TASKS→IMPLEMENTATION)",
2040
+ validation: "Cross-phase validation with approval gates and rollback support",
2041
+ initialization: "Project setup with .kiro directory structure and spec.json",
2042
+ context: "Project memory with codebase analysis and context persistence",
2043
+ steering: "Dynamic steering document management with Always/Conditional/Manual modes",
2044
+ quality: "Linus-style code review with 5-layer analysis framework",
2045
+ i18n: "10-language support with cultural adaptation",
1793
2046
  plugins: `${pluginStats.length} plugins loaded with extensibility framework`,
1794
- templates: 'Handlebars-based template generation with inheritance'
2047
+ templates: "Handlebars-based template generation with inheritance",
1795
2048
  },
1796
2049
  tools: {
1797
2050
  count: 10,
1798
- categories: ['sdd-init', 'sdd-requirements', 'sdd-design', 'sdd-tasks', 'sdd-implement', 'sdd-status', 'sdd-approve', 'sdd-quality-check', 'sdd-context-load', 'sdd-template-render'],
1799
- pluginTools: Object.keys(toolStats).length
2051
+ categories: [
2052
+ "sdd-init",
2053
+ "sdd-requirements",
2054
+ "sdd-design",
2055
+ "sdd-tasks",
2056
+ "sdd-implement",
2057
+ "sdd-status",
2058
+ "sdd-approve",
2059
+ "sdd-quality-check",
2060
+ "sdd-context-load",
2061
+ "sdd-template-render",
2062
+ ],
2063
+ pluginTools: Object.keys(toolStats).length,
1800
2064
  },
1801
2065
  hooks: {
1802
2066
  registered: Object.keys(hookStats).length,
1803
- phases: ['PRE_INIT', 'POST_INIT', 'PRE_REQUIREMENTS', 'POST_REQUIREMENTS', 'PRE_DESIGN', 'POST_DESIGN', 'PRE_TASKS', 'POST_TASKS', 'PRE_IMPLEMENTATION', 'POST_IMPLEMENTATION']
2067
+ phases: [
2068
+ "PRE_INIT",
2069
+ "POST_INIT",
2070
+ "PRE_REQUIREMENTS",
2071
+ "POST_REQUIREMENTS",
2072
+ "PRE_DESIGN",
2073
+ "POST_DESIGN",
2074
+ "PRE_TASKS",
2075
+ "POST_TASKS",
2076
+ "PRE_IMPLEMENTATION",
2077
+ "POST_IMPLEMENTATION",
2078
+ ],
1804
2079
  },
1805
2080
  steering: {
1806
2081
  documents: steeringStats.totalDocuments,
1807
2082
  plugins: Object.keys(steeringStats.documentsByPlugin).length,
1808
- modes: steeringStats.documentsByMode
1809
- }
2083
+ modes: steeringStats.documentsByMode,
2084
+ },
1810
2085
  });
1811
2086
  // Handle graceful shutdown
1812
- process.on('SIGINT', async () => {
1813
- logger.info('Received SIGINT, shutting down gracefully...');
2087
+ process.on("SIGINT", async () => {
2088
+ logger.info("Received SIGINT, shutting down gracefully...");
1814
2089
  await mcpServer.stop();
1815
2090
  process.exit(0);
1816
2091
  });
1817
- process.on('SIGTERM', async () => {
1818
- logger.info('Received SIGTERM, shutting down gracefully...');
2092
+ process.on("SIGTERM", async () => {
2093
+ logger.info("Received SIGTERM, shutting down gracefully...");
1819
2094
  await mcpServer.stop();
1820
2095
  process.exit(0);
1821
2096
  });
@@ -1824,7 +2099,7 @@ async function main() {
1824
2099
  catch (error) {
1825
2100
  // Only log startup errors in non-MCP mode
1826
2101
  if (!isMCPMode) {
1827
- console.error('Failed to start MCP SDD Server:', error);
2102
+ console.error("Failed to start MCP SDD Server:", error);
1828
2103
  }
1829
2104
  process.exit(1);
1830
2105
  }