ai-sdlc 0.2.0-alpha.21 → 0.2.0-alpha.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/agents/implementation.d.ts.map +1 -1
  2. package/dist/agents/implementation.js +19 -1
  3. package/dist/agents/implementation.js.map +1 -1
  4. package/dist/agents/planning.d.ts.map +1 -1
  5. package/dist/agents/planning.js +20 -1
  6. package/dist/agents/planning.js.map +1 -1
  7. package/dist/agents/refinement.d.ts.map +1 -1
  8. package/dist/agents/refinement.js +20 -1
  9. package/dist/agents/refinement.js.map +1 -1
  10. package/dist/agents/research.d.ts +71 -1
  11. package/dist/agents/research.d.ts.map +1 -1
  12. package/dist/agents/research.js +401 -6
  13. package/dist/agents/research.js.map +1 -1
  14. package/dist/agents/review.d.ts.map +1 -1
  15. package/dist/agents/review.js +19 -0
  16. package/dist/agents/review.js.map +1 -1
  17. package/dist/agents/rework.d.ts.map +1 -1
  18. package/dist/agents/rework.js +19 -0
  19. package/dist/agents/rework.js.map +1 -1
  20. package/dist/cli/commands.d.ts.map +1 -1
  21. package/dist/cli/commands.js +132 -52
  22. package/dist/cli/commands.js.map +1 -1
  23. package/dist/cli/daemon.d.ts.map +1 -1
  24. package/dist/cli/daemon.js +17 -0
  25. package/dist/cli/daemon.js.map +1 -1
  26. package/dist/core/client.d.ts.map +1 -1
  27. package/dist/core/client.js +34 -2
  28. package/dist/core/client.js.map +1 -1
  29. package/dist/core/index.d.ts +1 -0
  30. package/dist/core/index.d.ts.map +1 -1
  31. package/dist/core/index.js +1 -0
  32. package/dist/core/index.js.map +1 -1
  33. package/dist/core/story-logger.d.ts +102 -0
  34. package/dist/core/story-logger.d.ts.map +1 -0
  35. package/dist/core/story-logger.js +265 -0
  36. package/dist/core/story-logger.js.map +1 -0
  37. package/dist/core/workflow-state.d.ts.map +1 -1
  38. package/dist/core/workflow-state.js +16 -0
  39. package/dist/core/workflow-state.js.map +1 -1
  40. package/dist/index.js +85 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/types/index.d.ts +25 -0
  43. package/dist/types/index.d.ts.map +1 -1
  44. package/dist/types/index.js.map +1 -1
  45. package/package.json +1 -1
@@ -3,6 +3,7 @@ import path from 'path';
3
3
  import { glob } from 'glob';
4
4
  import { parseStory, appendToSection, updateStoryField } from '../core/story.js';
5
5
  import { runAgentQuery } from '../core/client.js';
6
+ import { getLogger } from '../core/logger.js';
6
7
  const RESEARCH_SYSTEM_PROMPT = `You are a technical research specialist. Your job is to research how to implement a user story by analyzing the existing codebase and external best practices.
7
8
 
8
9
  When researching a story, you should:
@@ -13,6 +14,118 @@ When researching a story, you should:
13
14
  5. Note any dependencies or prerequisites
14
15
 
15
16
  Output your research findings in markdown format. Be specific about file paths and code patterns.`;
17
+ /**
18
+ * Keywords that indicate a story is purely internal and does not require web research.
19
+ * These keywords suggest refactoring, code organization, or internal maintenance tasks.
20
+ */
21
+ const WEB_RESEARCH_INTERNAL_KEYWORDS = [
22
+ 'refactor internal',
23
+ 'move function',
24
+ 'rename variable',
25
+ 'rename function',
26
+ 'move utility',
27
+ 'internal refactor',
28
+ 'move code',
29
+ 'reorganize internal',
30
+ ];
31
+ /**
32
+ * Keywords that indicate external dependencies or integrations requiring web research.
33
+ * These keywords suggest the need for library documentation, API references, or best practices.
34
+ */
35
+ const WEB_RESEARCH_EXTERNAL_KEYWORDS = [
36
+ 'integrate',
37
+ 'api',
38
+ 'library',
39
+ 'framework',
40
+ 'best practices',
41
+ 'npm package',
42
+ 'external',
43
+ 'third-party',
44
+ 'sdk',
45
+ 'documentation',
46
+ 'webhook',
47
+ 'rest api',
48
+ 'graphql',
49
+ 'oauth',
50
+ 'authentication provider',
51
+ ];
52
+ /**
53
+ * Web research prompt template for supplementary research phase.
54
+ * Instructs the agent on tool usage, FAR evaluation, and output formatting.
55
+ */
56
+ const WEB_RESEARCH_PROMPT_TEMPLATE = (storyTitle, storyContent, codebaseContext) => `You are performing supplementary web research for a software development story.
57
+
58
+ **Story Title**: ${storyTitle}
59
+
60
+ **Story Content**:
61
+ ${storyContent}
62
+
63
+ **Codebase Context** (already analyzed):
64
+ ${codebaseContext}... [truncated]
65
+
66
+ ---
67
+
68
+ ## Web Research Instructions
69
+
70
+ You have access to these web research tools:
71
+
72
+ 1. **Context7** (if available) - Use FIRST for library/framework documentation
73
+ - Best for: npm packages, Python libraries, popular frameworks
74
+ - Example: "Search Context7 for React Query documentation on data fetching"
75
+
76
+ 2. **WebSearch** - Use for community knowledge and best practices
77
+ - Best for: Stack Overflow patterns, blog posts, tutorials
78
+ - Example: "Search the web for TypeScript error handling best practices"
79
+
80
+ 3. **WebFetch** - Use to read specific authoritative URLs
81
+ - Best for: Official documentation, specific articles
82
+ - Example: "Fetch https://docs.anthropic.com/claude/reference"
83
+
84
+ ## Research Strategy
85
+
86
+ - Try Context7 FIRST for any npm packages or popular frameworks mentioned in the story
87
+ - Fall back to WebSearch for general solutions and community patterns
88
+ - Use WebFetch only when you have specific authoritative URLs to read
89
+ - Limit research to 3-5 high-quality sources to avoid information overload
90
+ - Focus on actionable information that directly addresses the story requirements
91
+
92
+ ## Output Format
93
+
94
+ For EACH finding, provide:
95
+
96
+ ### [Topic Name]
97
+ **Source**: [Context7 - Library Name] or [Web Search Result] or [URL]
98
+ **FAR Score**: Factuality: [1-5], Actionability: [1-5], Relevance: [1-5]
99
+ **Justification**: [Why these scores? How does this help the story?]
100
+
101
+ [Finding content with code examples, patterns, or instructions]
102
+
103
+ ---
104
+
105
+ ## FAR Scale Definitions
106
+
107
+ **Factuality (1-5)**: How accurate and verifiable is the information?
108
+ - 1: Unverified/speculative
109
+ - 3: Community knowledge (Stack Overflow, blogs)
110
+ - 5: Official documentation or peer-reviewed
111
+
112
+ **Actionability (1-5)**: Can this be directly applied to the task?
113
+ - 1: Abstract concepts only
114
+ - 3: General patterns or approaches
115
+ - 5: Copy-paste code examples or step-by-step instructions
116
+
117
+ **Relevance (1-5)**: How closely does this match the story requirements?
118
+ - 1: Tangentially related
119
+ - 3: Related but not specific to story
120
+ - 5: Directly addresses a story acceptance criterion
121
+
122
+ ## Important Notes
123
+
124
+ - If web tools are unavailable (offline, not configured), simply state: "Web research tools unavailable - skipping web research"
125
+ - If a finding contradicts patterns in the codebase context, note the discrepancy and defer to local patterns
126
+ - Focus on NEW information not already present in codebase analysis
127
+
128
+ Begin web research now. Provide 3-5 high-quality findings with FAR evaluations.`;
16
129
  /**
17
130
  * Research Agent
18
131
  *
@@ -25,6 +138,8 @@ export async function runResearchAgent(storyPath, sdlcRoot, options = {}) {
25
138
  try {
26
139
  // Gather codebase context
27
140
  const codebaseContext = await gatherCodebaseContext(sdlcRoot);
141
+ // Sanitize codebase context before including in prompt (prevent prompt injection)
142
+ const sanitizedContext = sanitizeCodebaseContext(codebaseContext);
28
143
  // Build the prompt, including rework context if this is a refinement iteration
29
144
  let prompt = `Please research how to implement this story:
30
145
 
@@ -34,7 +149,7 @@ Story content:
34
149
  ${story.content}
35
150
 
36
151
  Codebase context:
37
- ${codebaseContext}`;
152
+ ${sanitizedContext}`;
38
153
  if (options.reworkContext) {
39
154
  prompt += `
40
155
 
@@ -62,11 +177,33 @@ Format your response as markdown for the Research section of the story.`;
62
177
  workingDirectory: path.dirname(sdlcRoot),
63
178
  onProgress: options.onProgress,
64
179
  });
65
- // Append research to the story
66
- await appendToSection(story, 'Research', researchContent);
67
- changesMade.push('Added research findings');
68
- // Mark research as complete
69
- await updateStoryField(story, 'research_complete', true);
180
+ // Sanitize research content before storage (prevent ANSI/markdown injection)
181
+ const sanitizedResearch = sanitizeWebResearchContent(researchContent);
182
+ // Append codebase research to the story
183
+ await appendToSection(story, 'Research', sanitizedResearch);
184
+ changesMade.push('Added codebase research findings');
185
+ // Phase 2: Web Research (conditional)
186
+ if (shouldPerformWebResearch(story, sanitizedContext)) {
187
+ const webResearchContent = await performWebResearch(story, sanitizedContext, path.dirname(sdlcRoot), options.onProgress);
188
+ if (webResearchContent.trim()) {
189
+ // Sanitize web research content before storage (prevent ANSI/markdown injection)
190
+ const sanitizedWebResearch = sanitizeWebResearchContent(webResearchContent);
191
+ // Re-parse story to get updated content after codebase research
192
+ const updatedStory = parseStory(storyPath);
193
+ await appendToSection(updatedStory, 'Research', '\n## Web Research Findings\n\n' + sanitizedWebResearch);
194
+ changesMade.push('Added web research findings');
195
+ }
196
+ else {
197
+ getLogger().info('web-research', 'Web research returned empty - tools may be unavailable');
198
+ changesMade.push('Web research skipped: tools unavailable');
199
+ }
200
+ }
201
+ else {
202
+ changesMade.push('Web research skipped: no external dependencies detected');
203
+ }
204
+ // Mark research as complete - re-parse to get latest content including web research
205
+ const finalStory = parseStory(storyPath);
206
+ await updateStoryField(finalStory, 'research_complete', true);
70
207
  changesMade.push('Marked research_complete: true');
71
208
  return {
72
209
  success: true,
@@ -138,4 +275,262 @@ async function gatherCodebaseContext(sdlcRoot) {
138
275
  }
139
276
  return context.join('\n\n') || 'No codebase context available.';
140
277
  }
278
+ /**
279
+ * Determine if web research would add value based on story content and codebase context.
280
+ *
281
+ * Web research is triggered when:
282
+ * 1. External dependencies are referenced (libraries, APIs, frameworks)
283
+ * 2. Unfamiliar APIs/patterns are mentioned
284
+ * 3. Library-specific documentation is needed
285
+ * 4. Best practices are requested
286
+ *
287
+ * Web research is skipped when:
288
+ * - Topic is purely internal (refactoring, moving code, internal utilities)
289
+ * - No external dependencies mentioned
290
+ */
291
+ export function shouldPerformWebResearch(story, codebaseContext) {
292
+ const content = story.content.toLowerCase();
293
+ const title = story.frontmatter.title.toLowerCase();
294
+ const combinedText = `${title} ${content}`;
295
+ // Skip if purely internal keywords are dominant
296
+ for (const keyword of WEB_RESEARCH_INTERNAL_KEYWORDS) {
297
+ if (combinedText.includes(keyword)) {
298
+ // Sanitize keyword for logging (prevent log injection)
299
+ getLogger().info('web-research', `Skipping web research: purely internal topic detected (${sanitizeForLogging(keyword)})`);
300
+ return false;
301
+ }
302
+ }
303
+ // Trigger if external library/API/framework mentioned
304
+ for (const keyword of WEB_RESEARCH_EXTERNAL_KEYWORDS) {
305
+ if (combinedText.includes(keyword)) {
306
+ // Sanitize keyword for logging (prevent log injection)
307
+ getLogger().info('web-research', `Web research triggered: external keyword detected (${sanitizeForLogging(keyword)})`);
308
+ return true;
309
+ }
310
+ }
311
+ // Check for package.json mentions (suggests npm dependencies)
312
+ if (codebaseContext.includes('package.json') &&
313
+ (combinedText.includes('npm') || combinedText.includes('install') || combinedText.includes('dependency'))) {
314
+ getLogger().info('web-research', 'Web research triggered: npm dependency context detected');
315
+ return true;
316
+ }
317
+ // Default: skip web research for codebase-only topics
318
+ getLogger().info('web-research', 'Skipping web research: no external dependencies detected');
319
+ return false;
320
+ }
321
+ /**
322
+ * Maximum input length to prevent DoS attacks.
323
+ * Set to 10,000 chars to accommodate long research findings
324
+ * while preventing memory exhaustion from malicious inputs.
325
+ */
326
+ const MAX_INPUT_LENGTH = 10000;
327
+ /**
328
+ * Maximum log string length for readability and security.
329
+ * Prevents log injection and maintains log file readability.
330
+ */
331
+ const MAX_LOG_LENGTH = 200;
332
+ /**
333
+ * Sanitize web research content for safe storage and display.
334
+ * Removes ANSI escape sequences, control characters, and potential injection vectors.
335
+ *
336
+ * Security rationale: Web research content comes from external sources (LLM, web tools)
337
+ * and must be sanitized before storage to prevent:
338
+ * - ANSI injection (terminal control sequence attacks)
339
+ * - Markdown injection (malicious formatting)
340
+ * - Control character injection (null bytes, bell characters, etc.)
341
+ *
342
+ * @param text - Raw web research content from external source
343
+ * @returns Sanitized text safe for storage in markdown files
344
+ */
345
+ export function sanitizeWebResearchContent(text) {
346
+ if (!text)
347
+ return '';
348
+ // Enforce maximum length to prevent DoS
349
+ if (text.length > MAX_INPUT_LENGTH) {
350
+ text = text.substring(0, MAX_INPUT_LENGTH);
351
+ }
352
+ // Remove ANSI CSI sequences (colors, cursor movement) - e.g., \x1B[31m
353
+ text = text.replace(/\x1B\[[^a-zA-Z\x1B]*[a-zA-Z]?/g, '');
354
+ // Remove OSC sequences (hyperlinks, window titles) - terminated by BEL (\x07) or ST (\x1B\\)
355
+ text = text.replace(/\x1B\][^\x07]*\x07/g, '');
356
+ text = text.replace(/\x1B\][^\x1B]*\x1B\\/g, '');
357
+ // Remove any remaining standalone escape characters
358
+ text = text.replace(/\x1B/g, '');
359
+ // Remove control characters (0x00-0x08, 0x0B-0x0C, 0x0E-0x1F, 0x7F-0x9F)
360
+ // eslint-disable-next-line no-control-regex
361
+ text = text.replace(/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F-\x9F]/g, '');
362
+ // Normalize Unicode to prevent homograph attacks and ensure consistent representation
363
+ text = text.normalize('NFC');
364
+ // Validate markdown structure - escape dangerous patterns
365
+ // Triple backticks could be used to break out of code blocks
366
+ text = text.replace(/```/g, '\\`\\`\\`');
367
+ return text;
368
+ }
369
+ /**
370
+ * Sanitize text for logging to prevent log injection attacks.
371
+ * Replaces newlines with spaces and truncates for readability.
372
+ *
373
+ * Security rationale: Log injection attacks use newlines to inject fake log entries.
374
+ * By replacing newlines with spaces, we ensure each log() call produces exactly one log line.
375
+ *
376
+ * @param text - Raw text that will be logged
377
+ * @returns Sanitized text safe for logging (single line, truncated)
378
+ */
379
+ export function sanitizeForLogging(text) {
380
+ if (!text)
381
+ return '';
382
+ // Remove ANSI escape sequences
383
+ text = text.replace(/\x1B\[[^a-zA-Z\x1B]*[a-zA-Z]?/g, '');
384
+ text = text.replace(/\x1B\][^\x07]*\x07/g, '');
385
+ text = text.replace(/\x1B\][^\x1B]*\x1B\\/g, '');
386
+ text = text.replace(/\x1B/g, '');
387
+ // Replace newlines and carriage returns with spaces to prevent log injection
388
+ text = text.replace(/[\n\r]/g, ' ');
389
+ // Truncate to reasonable length for logs
390
+ if (text.length > MAX_LOG_LENGTH) {
391
+ text = text.substring(0, MAX_LOG_LENGTH) + '...';
392
+ }
393
+ return text.trim();
394
+ }
395
+ /**
396
+ * Sanitize codebase context before including in LLM prompts.
397
+ * Escapes dangerous patterns that could cause prompt injection.
398
+ *
399
+ * Security rationale: Codebase files may contain malicious content from:
400
+ * - Compromised dependencies
401
+ * - Malicious commits
402
+ * - Untrusted contributors
403
+ *
404
+ * We must prevent prompt injection by escaping patterns that could:
405
+ * - Terminate the prompt early (triple backticks)
406
+ * - Inject commands or instructions
407
+ * - Confuse the LLM's understanding of structure
408
+ *
409
+ * @param text - Raw codebase context
410
+ * @returns Sanitized text safe for LLM prompts
411
+ */
412
+ export function sanitizeCodebaseContext(text) {
413
+ if (!text)
414
+ return '';
415
+ // Remove ANSI escape sequences
416
+ text = text.replace(/\x1B\[[^a-zA-Z\x1B]*[a-zA-Z]?/g, '');
417
+ text = text.replace(/\x1B\][^\x07]*\x07/g, '');
418
+ text = text.replace(/\x1B\][^\x1B]*\x1B\\/g, '');
419
+ text = text.replace(/\x1B/g, '');
420
+ // Escape triple backticks to prevent breaking out of code blocks
421
+ text = text.replace(/```/g, '\\`\\`\\`');
422
+ // Validate UTF-8 boundaries at truncation points
423
+ // If we need to truncate, ensure we don't split multi-byte characters
424
+ if (text.length > MAX_INPUT_LENGTH) {
425
+ // Use substring which is UTF-16 safe, then validate
426
+ let truncated = text.substring(0, MAX_INPUT_LENGTH);
427
+ // Check if we split a surrogate pair (0xD800-0xDFFF)
428
+ const lastCharCode = truncated.charCodeAt(truncated.length - 1);
429
+ if (lastCharCode >= 0xD800 && lastCharCode <= 0xDFFF) {
430
+ // We split a surrogate pair, remove the incomplete character
431
+ truncated = truncated.substring(0, truncated.length - 1);
432
+ }
433
+ text = truncated;
434
+ }
435
+ return text;
436
+ }
437
+ /**
438
+ * Parse FAR evaluation from web research finding text.
439
+ * Expected format from LLM:
440
+ * **FAR Score**: Factuality: 5, Actionability: 4, Relevance: 5
441
+ * **Justification**: Official documentation provides...
442
+ *
443
+ * Returns default scores (2, 2, 2) with parsingSucceeded: false if parsing fails.
444
+ * Default of 2 (rather than 3) indicates uncertainty rather than average quality.
445
+ *
446
+ * @param finding - Web research finding text to parse
447
+ * @returns FARScore with parsed or default values and parsing status
448
+ */
449
+ export function evaluateFAR(finding) {
450
+ // Enforce maximum length to prevent ReDoS attacks
451
+ if (finding.length > MAX_INPUT_LENGTH) {
452
+ finding = finding.substring(0, MAX_INPUT_LENGTH);
453
+ }
454
+ try {
455
+ // Look for FAR score pattern
456
+ const scoreMatch = finding.match(/\*\*FAR Score\*\*:.*?Factuality:\s*(\d+).*?Actionability:\s*(\d+).*?Relevance:\s*(\d+)/i);
457
+ const justificationMatch = finding.match(/\*\*Justification\*\*:\s*(.+?)(?:\n\n|\n#|$)/is);
458
+ if (scoreMatch && justificationMatch) {
459
+ const factuality = parseInt(scoreMatch[1], 10);
460
+ const actionability = parseInt(scoreMatch[2], 10);
461
+ const relevance = parseInt(scoreMatch[3], 10);
462
+ const justification = justificationMatch[1].trim();
463
+ // Validate scores are in range 1-5
464
+ if ([factuality, actionability, relevance].every(s => s >= 1 && s <= 5)) {
465
+ return {
466
+ factuality,
467
+ actionability,
468
+ relevance,
469
+ justification,
470
+ parsingSucceeded: true,
471
+ };
472
+ }
473
+ else {
474
+ getLogger().warn('web-research', 'FAR scores out of valid range (1-5), using defaults');
475
+ }
476
+ }
477
+ else if (scoreMatch && !justificationMatch) {
478
+ getLogger().warn('web-research', 'FAR justification missing, using defaults');
479
+ }
480
+ else if (!scoreMatch && justificationMatch) {
481
+ getLogger().warn('web-research', 'FAR scores not found in finding, using defaults');
482
+ }
483
+ else {
484
+ getLogger().warn('web-research', 'FAR scores and justification not found in finding, using defaults');
485
+ }
486
+ // If parsing failed, return default scores (2/5 indicates uncertainty)
487
+ return {
488
+ factuality: 2,
489
+ actionability: 2,
490
+ relevance: 2,
491
+ justification: 'FAR scores could not be parsed from finding. Default scores (2/5) applied.',
492
+ parsingSucceeded: false,
493
+ };
494
+ }
495
+ catch (error) {
496
+ getLogger().error('web-research', 'Error parsing FAR scores', { error });
497
+ return {
498
+ factuality: 2,
499
+ actionability: 2,
500
+ relevance: 2,
501
+ justification: 'Error parsing FAR evaluation',
502
+ parsingSucceeded: false,
503
+ };
504
+ }
505
+ }
506
+ /**
507
+ * Perform web research using Context7/WebSearch/WebFetch.
508
+ * Returns formatted markdown with FAR evaluations, or empty string if all tools unavailable.
509
+ */
510
+ async function performWebResearch(story, codebaseContext, workingDir, onProgress) {
511
+ const logger = getLogger();
512
+ logger.info('web-research', 'Starting web research phase', { storyId: story.frontmatter.id });
513
+ try {
514
+ const sanitizedContext = sanitizeCodebaseContext(codebaseContext.substring(0, 2000));
515
+ const webResearchPrompt = WEB_RESEARCH_PROMPT_TEMPLATE(story.frontmatter.title, story.content, sanitizedContext);
516
+ const webResearchResult = await runAgentQuery({
517
+ prompt: webResearchPrompt,
518
+ systemPrompt: 'You are a web research specialist. Use available tools to find authoritative documentation and best practices.',
519
+ workingDirectory: workingDir,
520
+ onProgress,
521
+ });
522
+ // Check if web tools were unavailable
523
+ if (webResearchResult.toLowerCase().includes('web research tools unavailable')) {
524
+ logger.info('web-research', 'Web research tools unavailable, skipping');
525
+ return '';
526
+ }
527
+ logger.info('web-research', 'Web research completed successfully');
528
+ return webResearchResult;
529
+ }
530
+ catch (error) {
531
+ logger.error('web-research', 'Web research failed', { error });
532
+ // Gracefully degrade - return empty string to continue with codebase-only research
533
+ return '';
534
+ }
535
+ }
141
536
  //# sourceMappingURL=research.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"research.js","sourceRoot":"","sources":["../../src/agents/research.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"research.js","sourceRoot":"","sources":["../../src/agents/research.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/agents/review.ts"],"names":[],"mappings":"AAOA,OAAO,EAAS,WAAW,EAAE,YAAY,EAAE,WAAW,EAA8E,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAkH5K;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CA0BlE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAOrE;AAiBD;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAsVrJ;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CA+F1F;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,sBAAsB,CAAC,EAAE,4BAA4B,CAAC;CACvD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,YAAY,CAAC,CA0PvB;AAgCD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC,CAgItB"}
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/agents/review.ts"],"names":[],"mappings":"AAQA,OAAO,EAAS,WAAW,EAAE,YAAY,EAAE,WAAW,EAA8E,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAkH5K;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CA0BlE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAOrE;AAiBD;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAsVrJ;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CA+F1F;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,sBAAsB,CAAC,EAAE,4BAA4B,CAAC;CACvD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,YAAY,CAAC,CA+QvB;AAgCD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC,CAgItB"}
@@ -4,6 +4,7 @@ import fs from 'fs';
4
4
  import { z } from 'zod';
5
5
  import { parseStory, updateStoryStatus, appendToSection, updateStoryField, isAtMaxRetries, appendReviewHistory, snapshotMaxRetries, getEffectiveMaxRetries } from '../core/story.js';
6
6
  import { runAgentQuery } from '../core/client.js';
7
+ import { getLogger } from '../core/logger.js';
7
8
  import { loadConfig, DEFAULT_TIMEOUTS } from '../core/config.js';
8
9
  import { ReviewDecision, ReviewSeverity } from '../types/index.js';
9
10
  import { sanitizeInput, truncateText } from '../cli/formatting.js';
@@ -526,9 +527,15 @@ export function generateReviewSummary(issues, terminalWidth) {
526
527
  * Now returns structured ReviewResult with pass/fail and issues.
527
528
  */
528
529
  export async function runReviewAgent(storyPath, sdlcRoot, options) {
530
+ const logger = getLogger();
531
+ const startTime = Date.now();
529
532
  const story = parseStory(storyPath);
530
533
  const changesMade = [];
531
534
  const workingDir = path.dirname(sdlcRoot);
535
+ logger.info('review', 'Starting review phase', {
536
+ storyId: story.frontmatter.id,
537
+ retryCount: story.frontmatter.retry_count || 0,
538
+ });
532
539
  // Security: Validate working directory before any operations
533
540
  try {
534
541
  validateWorkingDirectory(workingDir);
@@ -724,6 +731,13 @@ ${passed ? '✅ **PASSED** - All reviews approved' : '❌ **FAILED** - Issues mu
724
731
  changesMade.push(`Reviews failed with ${allIssues.length} issue(s) - rework required`);
725
732
  // Don't mark reviews_complete, this will trigger rework
726
733
  }
734
+ logger.info('review', 'Review phase complete', {
735
+ storyId: story.frontmatter.id,
736
+ durationMs: Date.now() - startTime,
737
+ passed,
738
+ decision,
739
+ issueCount: allIssues.length,
740
+ });
727
741
  return {
728
742
  success: true,
729
743
  story: parseStory(storyPath),
@@ -739,6 +753,11 @@ ${passed ? '✅ **PASSED** - All reviews approved' : '❌ **FAILED** - Issues mu
739
753
  catch (error) {
740
754
  // Review agent failure - return FAILED decision (doesn't count as retry)
741
755
  const errorMsg = error instanceof Error ? error.message : String(error);
756
+ logger.error('review', 'Review phase failed', {
757
+ storyId: story.frontmatter.id,
758
+ durationMs: Date.now() - startTime,
759
+ error: errorMsg,
760
+ });
742
761
  return {
743
762
  success: false,
744
763
  story,