ai-sdlc 0.2.0-alpha.6 → 0.2.0-alpha.60

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 (135) hide show
  1. package/README.md +53 -1058
  2. package/dist/agents/implementation.d.ts +36 -1
  3. package/dist/agents/implementation.d.ts.map +1 -1
  4. package/dist/agents/implementation.js +259 -30
  5. package/dist/agents/implementation.js.map +1 -1
  6. package/dist/agents/index.d.ts +2 -0
  7. package/dist/agents/index.d.ts.map +1 -1
  8. package/dist/agents/index.js +2 -0
  9. package/dist/agents/index.js.map +1 -1
  10. package/dist/agents/orchestrator.d.ts +61 -0
  11. package/dist/agents/orchestrator.d.ts.map +1 -0
  12. package/dist/agents/orchestrator.js +443 -0
  13. package/dist/agents/orchestrator.js.map +1 -0
  14. package/dist/agents/planning.d.ts +1 -1
  15. package/dist/agents/planning.d.ts.map +1 -1
  16. package/dist/agents/planning.js +55 -4
  17. package/dist/agents/planning.js.map +1 -1
  18. package/dist/agents/refinement.d.ts.map +1 -1
  19. package/dist/agents/refinement.js +22 -3
  20. package/dist/agents/refinement.js.map +1 -1
  21. package/dist/agents/research.d.ts +85 -1
  22. package/dist/agents/research.d.ts.map +1 -1
  23. package/dist/agents/research.js +506 -16
  24. package/dist/agents/research.js.map +1 -1
  25. package/dist/agents/review.d.ts +103 -2
  26. package/dist/agents/review.d.ts.map +1 -1
  27. package/dist/agents/review.js +777 -93
  28. package/dist/agents/review.js.map +1 -1
  29. package/dist/agents/rework.d.ts.map +1 -1
  30. package/dist/agents/rework.js +25 -4
  31. package/dist/agents/rework.js.map +1 -1
  32. package/dist/agents/single-task.d.ts +41 -0
  33. package/dist/agents/single-task.d.ts.map +1 -0
  34. package/dist/agents/single-task.js +357 -0
  35. package/dist/agents/single-task.js.map +1 -0
  36. package/dist/agents/state-assessor.d.ts +3 -3
  37. package/dist/agents/state-assessor.d.ts.map +1 -1
  38. package/dist/agents/state-assessor.js +6 -6
  39. package/dist/agents/state-assessor.js.map +1 -1
  40. package/dist/agents/test-pattern-detector.d.ts +49 -0
  41. package/dist/agents/test-pattern-detector.d.ts.map +1 -0
  42. package/dist/agents/test-pattern-detector.js +273 -0
  43. package/dist/agents/test-pattern-detector.js.map +1 -0
  44. package/dist/agents/verification.d.ts +11 -0
  45. package/dist/agents/verification.d.ts.map +1 -1
  46. package/dist/agents/verification.js +99 -12
  47. package/dist/agents/verification.js.map +1 -1
  48. package/dist/cli/commands/migrate.js +1 -1
  49. package/dist/cli/commands/migrate.js.map +1 -1
  50. package/dist/cli/commands.d.ts +66 -3
  51. package/dist/cli/commands.d.ts.map +1 -1
  52. package/dist/cli/commands.js +1548 -198
  53. package/dist/cli/commands.js.map +1 -1
  54. package/dist/cli/daemon.d.ts.map +1 -1
  55. package/dist/cli/daemon.js +25 -3
  56. package/dist/cli/daemon.js.map +1 -1
  57. package/dist/cli/runner.d.ts.map +1 -1
  58. package/dist/cli/runner.js +35 -12
  59. package/dist/cli/runner.js.map +1 -1
  60. package/dist/core/auth.d.ts +43 -0
  61. package/dist/core/auth.d.ts.map +1 -1
  62. package/dist/core/auth.js +105 -1
  63. package/dist/core/auth.js.map +1 -1
  64. package/dist/core/client.d.ts +25 -1
  65. package/dist/core/client.d.ts.map +1 -1
  66. package/dist/core/client.js +247 -7
  67. package/dist/core/client.js.map +1 -1
  68. package/dist/core/config.d.ts +32 -1
  69. package/dist/core/config.d.ts.map +1 -1
  70. package/dist/core/config.js +146 -3
  71. package/dist/core/config.js.map +1 -1
  72. package/dist/core/conflict-detector.d.ts +108 -0
  73. package/dist/core/conflict-detector.d.ts.map +1 -0
  74. package/dist/core/conflict-detector.js +413 -0
  75. package/dist/core/conflict-detector.js.map +1 -0
  76. package/dist/core/git-utils.d.ts +28 -0
  77. package/dist/core/git-utils.d.ts.map +1 -0
  78. package/dist/core/git-utils.js +146 -0
  79. package/dist/core/git-utils.js.map +1 -0
  80. package/dist/core/index.d.ts +19 -0
  81. package/dist/core/index.d.ts.map +1 -0
  82. package/dist/core/index.js +19 -0
  83. package/dist/core/index.js.map +1 -0
  84. package/dist/core/kanban.d.ts +1 -1
  85. package/dist/core/kanban.d.ts.map +1 -1
  86. package/dist/core/kanban.js +3 -3
  87. package/dist/core/kanban.js.map +1 -1
  88. package/dist/core/llm-utils.d.ts +103 -0
  89. package/dist/core/llm-utils.d.ts.map +1 -0
  90. package/dist/core/llm-utils.js +368 -0
  91. package/dist/core/llm-utils.js.map +1 -0
  92. package/dist/core/logger.d.ts +92 -0
  93. package/dist/core/logger.d.ts.map +1 -0
  94. package/dist/core/logger.js +221 -0
  95. package/dist/core/logger.js.map +1 -0
  96. package/dist/core/process-manager.d.ts +15 -0
  97. package/dist/core/process-manager.d.ts.map +1 -0
  98. package/dist/core/process-manager.js +132 -0
  99. package/dist/core/process-manager.js.map +1 -0
  100. package/dist/core/story-logger.d.ts +102 -0
  101. package/dist/core/story-logger.d.ts.map +1 -0
  102. package/dist/core/story-logger.js +265 -0
  103. package/dist/core/story-logger.js.map +1 -0
  104. package/dist/core/story.d.ts +113 -20
  105. package/dist/core/story.d.ts.map +1 -1
  106. package/dist/core/story.js +328 -40
  107. package/dist/core/story.js.map +1 -1
  108. package/dist/core/task-parser.d.ts +59 -0
  109. package/dist/core/task-parser.d.ts.map +1 -0
  110. package/dist/core/task-parser.js +235 -0
  111. package/dist/core/task-parser.js.map +1 -0
  112. package/dist/core/task-progress.d.ts +92 -0
  113. package/dist/core/task-progress.d.ts.map +1 -0
  114. package/dist/core/task-progress.js +280 -0
  115. package/dist/core/task-progress.js.map +1 -0
  116. package/dist/core/workflow-state.d.ts +45 -6
  117. package/dist/core/workflow-state.d.ts.map +1 -1
  118. package/dist/core/workflow-state.js +201 -12
  119. package/dist/core/workflow-state.js.map +1 -1
  120. package/dist/core/worktree.d.ts +186 -0
  121. package/dist/core/worktree.d.ts.map +1 -0
  122. package/dist/core/worktree.js +554 -0
  123. package/dist/core/worktree.js.map +1 -0
  124. package/dist/index.js +145 -5
  125. package/dist/index.js.map +1 -1
  126. package/dist/services/error-classifier.d.ts +119 -0
  127. package/dist/services/error-classifier.d.ts.map +1 -0
  128. package/dist/services/error-classifier.js +182 -0
  129. package/dist/services/error-classifier.js.map +1 -0
  130. package/dist/types/index.d.ts +381 -1
  131. package/dist/types/index.d.ts.map +1 -1
  132. package/dist/types/index.js +1 -0
  133. package/dist/types/index.js.map +1 -1
  134. package/package.json +5 -2
  135. package/templates/story.md +5 -0
@@ -104,6 +104,22 @@ export interface RetryAttemptOptions {
104
104
  reworkContext?: string;
105
105
  onProgress?: AgentProgressCallback;
106
106
  }
107
+ /**
108
+ * Outcome type for retry attempts
109
+ */
110
+ export type AttemptOutcome = 'failed_tests' | 'failed_build' | 'no_change';
111
+ /**
112
+ * Result from a single retry attempt
113
+ */
114
+ export interface AttemptHistoryEntry {
115
+ attempt: number;
116
+ testFailures: number;
117
+ buildFailures: number;
118
+ testSnippet: string;
119
+ buildSnippet: string;
120
+ changesSummary: string;
121
+ outcome: AttemptOutcome;
122
+ }
107
123
  /**
108
124
  * Attempt implementation with retry logic
109
125
  *
@@ -134,6 +150,18 @@ export declare function captureCurrentDiffHash(workingDir: string): string;
134
150
  * @returns True if changes occurred (hashes are different)
135
151
  */
136
152
  export declare function hasChangesOccurred(previousHash: string, currentHash: string): boolean;
153
+ /**
154
+ * Extract list of changed files from git diff
155
+ * @param workingDir The working directory
156
+ * @returns Comma-separated list of changed files, or descriptive message
157
+ */
158
+ export declare function extractChangedFiles(workingDir: string): string;
159
+ /**
160
+ * Build formatted retry history section for agent prompts
161
+ * @param history Array of attempt history entries
162
+ * @returns Formatted string for inclusion in retry prompts
163
+ */
164
+ export declare function buildRetryHistorySection(history: AttemptHistoryEntry[]): string;
137
165
  /**
138
166
  * Sanitize test output to remove ANSI escape sequences and potential injection patterns
139
167
  * @param output Test output string
@@ -147,12 +175,19 @@ export declare function sanitizeTestOutput(output: string): string;
147
175
  * @returns Truncated and sanitized output with notice if truncated
148
176
  */
149
177
  export declare function truncateTestOutput(output: string, maxLength?: number): string;
178
+ /**
179
+ * Detect if errors are related to missing dependencies
180
+ * Returns module names that are missing, if any
181
+ */
182
+ export declare function detectMissingDependencies(output: string): string[];
150
183
  /**
151
184
  * Build retry prompt for implementation agent
152
185
  * @param testOutput Test failure output
186
+ * @param buildOutput Build output
153
187
  * @param attemptNumber Current attempt number (1-indexed)
154
188
  * @param maxRetries Maximum number of retries
189
+ * @param attemptHistory Optional history of previous attempts
155
190
  * @returns Prompt string for retry attempt
156
191
  */
157
- export declare function buildRetryPrompt(testOutput: string, buildOutput: string, attemptNumber: number, maxRetries: number): string;
192
+ export declare function buildRetryPrompt(testOutput: string, buildOutput: string, attemptNumber: number, maxRetries: number, attemptHistory?: AttemptHistoryEntry[]): string;
158
193
  //# sourceMappingURL=implementation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"implementation.d.ts","sourceRoot":"","sources":["../../src/agents/implementation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"implementation.d.ts","sourceRoot":"","sources":["../../src/agents/implementation.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,13 @@
1
1
  import { spawn, spawnSync } from 'child_process';
2
2
  import path from 'path';
3
- import { parseStory, writeStory, updateStoryStatus, updateStoryField, resetImplementationRetryCount, incrementImplementationRetryCount, getEffectiveMaxImplementationRetries, } from '../core/story.js';
3
+ import { ProcessManager } from '../core/process-manager.js';
4
+ import { parseStory, writeStory, updateStoryStatus, updateStoryField, resetImplementationRetryCount, incrementImplementationRetryCount, getEffectiveMaxImplementationRetries, incrementTotalRecoveryAttempts, } from '../core/story.js';
4
5
  import { runAgentQuery } from '../core/client.js';
6
+ import { getLogger } from '../core/logger.js';
5
7
  import { loadConfig, DEFAULT_TDD_CONFIG } from '../core/config.js';
6
8
  import { verifyImplementation } from './verification.js';
7
9
  import { createHash } from 'crypto';
10
+ import { parseTypeScriptErrors, classifyAndSortErrors } from '../services/error-classifier.js';
8
11
  export const TDD_SYSTEM_PROMPT = `You are practicing strict Test-Driven Development.
9
12
 
10
13
  Your workflow MUST follow this exact cycle:
@@ -59,6 +62,7 @@ export async function runSingleTest(testFile, workingDir, testTimeout) {
59
62
  cwd: workingDir,
60
63
  stdio: ['pipe', 'pipe', 'pipe'],
61
64
  });
65
+ ProcessManager.getInstance().registerChild(child);
62
66
  const timeoutId = setTimeout(() => {
63
67
  killed = true;
64
68
  child.kill('SIGTERM');
@@ -106,6 +110,7 @@ export async function runAllTests(workingDir, testTimeout) {
106
110
  cwd: workingDir,
107
111
  stdio: ['pipe', 'pipe', 'pipe'],
108
112
  });
113
+ ProcessManager.getInstance().registerChild(child);
109
114
  const timeoutId = setTimeout(() => {
110
115
  killed = true;
111
116
  child.kill('SIGTERM');
@@ -508,7 +513,7 @@ export async function runTDDImplementation(story, sdlcRoot, options = {}) {
508
513
  story.frontmatter.tdd_test_history = history.slice(-100);
509
514
  story.frontmatter.tdd_current_test = cycle;
510
515
  // Persist the TDD cycle history to disk
511
- writeStory(story);
516
+ await writeStory(story);
512
517
  changesMade.push(`Completed TDD cycle ${cycleNumber}`);
513
518
  // Check if all AC are now covered
514
519
  // Re-read story to get latest content (agent may have updated checkboxes)
@@ -568,7 +573,7 @@ severity issues - these must be resolved. Review the specific feedback and make
568
573
  }
569
574
  // Add retry context if this is a retry attempt
570
575
  if (attemptNumber > 1 && lastVerification) {
571
- prompt += '\n\n' + buildRetryPrompt(lastVerification.testsOutput, lastVerification.buildOutput, attemptNumber, maxRetries);
576
+ prompt += '\n\n' + buildRetryPrompt(lastVerification.testsOutput, lastVerification.buildOutput, attemptNumber, maxRetries, attemptHistory);
572
577
  }
573
578
  else {
574
579
  prompt += `
@@ -606,18 +611,43 @@ ${implementationResult}
606
611
  // Append to story content
607
612
  const updatedStory = parseStory(storyPath);
608
613
  updatedStory.content += '\n\n' + implementationNotes;
609
- writeStory(updatedStory);
614
+ await writeStory(updatedStory);
610
615
  changesMade.push(attemptNumber > 1 ? `Added retry ${attemptNumber - 1} notes` : 'Added implementation notes');
616
+ // PRE-FLIGHT CHECK: Capture diff hash BEFORE verification to detect no-change scenarios early
617
+ const currentDiffHash = captureCurrentDiffHash(workingDir);
618
+ const changesSummary = extractChangedFiles(workingDir);
619
+ // Check for no-change scenario BEFORE running verification (saves ~30 seconds)
620
+ if (attemptNumber > 1 && lastDiffHash && lastDiffHash === currentDiffHash) {
621
+ changesMade.push('No changes detected since last attempt - skipping verification');
622
+ // Record this no-change attempt in history
623
+ attemptHistory.push({
624
+ attempt: attemptNumber,
625
+ testFailures: 0,
626
+ buildFailures: 0,
627
+ testSnippet: '',
628
+ buildSnippet: '',
629
+ changesSummary: 'No changes detected',
630
+ outcome: 'no_change',
631
+ });
632
+ return {
633
+ success: false,
634
+ story: parseStory(storyPath),
635
+ changesMade,
636
+ error: 'No progress detected - agent made no file changes',
637
+ };
638
+ }
639
+ // Update lastDiffHash for next iteration
640
+ lastDiffHash = currentDiffHash;
611
641
  changesMade.push('Running verification before marking complete...');
612
642
  const verification = await verifyImplementation(updatedStory, workingDir);
613
- updateStoryField(updatedStory, 'last_test_run', {
643
+ await updateStoryField(updatedStory, 'last_test_run', {
614
644
  passed: verification.passed,
615
645
  failures: verification.failures,
616
646
  timestamp: verification.timestamp,
617
647
  });
618
648
  if (verification.passed) {
619
649
  // Success! Reset retry count and return success
620
- resetImplementationRetryCount(updatedStory);
650
+ await resetImplementationRetryCount(updatedStory);
621
651
  changesMade.push('Verification passed - implementation successful');
622
652
  // Send success progress callback
623
653
  if (onProgress) {
@@ -631,10 +661,10 @@ ${implementationResult}
631
661
  }
632
662
  // Verification failed - check for retry conditions
633
663
  lastVerification = verification;
634
- // Capture current diff hash for no-change detection
635
- const currentDiffHash = captureCurrentDiffHash(workingDir);
636
664
  // Track retry attempt
637
- incrementImplementationRetryCount(updatedStory);
665
+ await incrementImplementationRetryCount(updatedStory);
666
+ // Increment global recovery counter
667
+ await incrementTotalRecoveryAttempts(updatedStory);
638
668
  // Extract first 100 chars of test and build output for history
639
669
  const testSnippet = verification.testsOutput.substring(0, 100).replace(/\n/g, ' ');
640
670
  const buildSnippet = verification.buildOutput.substring(0, 100).replace(/\n/g, ' ');
@@ -644,6 +674,8 @@ ${implementationResult}
644
674
  verification.buildOutput.includes('Error') ||
645
675
  verification.buildOutput.includes('failed'));
646
676
  const buildFailures = hasBuildErrors ? 1 : 0;
677
+ // Determine outcome based on what failed
678
+ const outcome = hasBuildErrors ? 'failed_build' : 'failed_tests';
647
679
  // Record this attempt in history with both test and build failures
648
680
  attemptHistory.push({
649
681
  attempt: attemptNumber,
@@ -651,6 +683,8 @@ ${implementationResult}
651
683
  buildFailures,
652
684
  testSnippet,
653
685
  buildSnippet,
686
+ changesSummary,
687
+ outcome,
654
688
  });
655
689
  // Add structured retry entry to changes array
656
690
  if (attemptNumber > 1) {
@@ -659,17 +693,6 @@ ${implementationResult}
659
693
  else {
660
694
  changesMade.push(`Attempt ${attemptNumber}: ${verification.failures} test(s) failing`);
661
695
  }
662
- // Check for no-change scenario (agent made no progress)
663
- // Only check after first failure (attemptNumber > 1)
664
- // Check this BEFORE max retries to fail fast on identical changes
665
- if (attemptNumber > 1 && lastDiffHash && lastDiffHash === currentDiffHash) {
666
- return {
667
- success: false,
668
- story: parseStory(storyPath),
669
- changesMade,
670
- error: `Implementation blocked: No progress detected on retry attempt ${attemptNumber - 1}. Agent made identical changes. Stopping retries early.\n\nLast test output:\n${truncateTestOutput(verification.testsOutput, 1000)}`,
671
- };
672
- }
673
696
  // Check if we've reached max retries
674
697
  if (attemptHistory.length > maxRetries) {
675
698
  const attemptSummary = attemptHistory
@@ -700,7 +723,6 @@ ${implementationResult}
700
723
  error: `Implementation blocked after ${attemptNumber} attempts:\n${attemptSummary}\n\nLast test output:\n${truncateTestOutput(verification.testsOutput, 5000)}`,
701
724
  };
702
725
  }
703
- lastDiffHash = currentDiffHash;
704
726
  // Continue to next retry attempt - send progress update
705
727
  if (onProgress) {
706
728
  onProgress({ type: 'assistant_message', content: `Retry ${attemptNumber} failed: ${verification.failures} test(s) failing, attempting retry ${attemptNumber + 1}...` });
@@ -720,10 +742,16 @@ ${implementationResult}
720
742
  * Executes the implementation plan, creating code changes and tests.
721
743
  */
722
744
  export async function runImplementationAgent(storyPath, sdlcRoot, options = {}) {
745
+ const logger = getLogger();
746
+ const startTime = Date.now();
723
747
  let story = parseStory(storyPath);
724
748
  let currentStoryPath = storyPath;
725
749
  const changesMade = [];
726
750
  const workingDir = path.dirname(sdlcRoot);
751
+ logger.info('implementation', 'Starting implementation phase', {
752
+ storyId: story.frontmatter.id,
753
+ retryCount: story.frontmatter.implementation_retry_count || 0,
754
+ });
727
755
  try {
728
756
  // Security: Validate working directory before git operations
729
757
  validateWorkingDir(workingDir);
@@ -767,7 +795,7 @@ export async function runImplementationAgent(storyPath, sdlcRoot, options = {})
767
795
  }
768
796
  }
769
797
  // Update story with branch info
770
- updateStoryField(story, 'branch', branchName);
798
+ await updateStoryField(story, 'branch', branchName);
771
799
  }
772
800
  }
773
801
  catch {
@@ -776,13 +804,44 @@ export async function runImplementationAgent(storyPath, sdlcRoot, options = {})
776
804
  }
777
805
  // Update status to in-progress if not already there
778
806
  if (story.frontmatter.status !== 'in-progress') {
779
- story = updateStoryStatus(story, 'in-progress');
807
+ story = await updateStoryStatus(story, 'in-progress');
780
808
  currentStoryPath = story.path;
781
809
  changesMade.push('Updated status to in-progress');
782
810
  }
783
811
  // Check if TDD is enabled for this story
784
812
  const config = loadConfig(workingDir);
785
813
  const tddEnabled = story.frontmatter.tdd_enabled ?? config.tdd?.enabled ?? false;
814
+ // Check if orchestrator is enabled
815
+ if (config.useOrchestrator && !tddEnabled) {
816
+ changesMade.push('Using sequential task orchestrator for implementation');
817
+ const { runImplementationOrchestrator } = await import('./orchestrator.js');
818
+ const orchestratorResult = await runImplementationOrchestrator(currentStoryPath, sdlcRoot, {
819
+ maxRetriesPerTask: config.implementation.maxRetries,
820
+ commitAfterEachTask: true,
821
+ stopOnFirstFailure: true,
822
+ });
823
+ if (!orchestratorResult.success) {
824
+ // Orchestration failed
825
+ const errorDetails = orchestratorResult.failedTasks
826
+ .map((ft) => ` - ${ft.taskId}: ${ft.error} (${ft.attempts} attempts)`)
827
+ .join('\n');
828
+ return {
829
+ success: false,
830
+ story: parseStory(currentStoryPath),
831
+ changesMade,
832
+ error: `Implementation orchestration failed:\n${errorDetails}\n\nCompleted: ${orchestratorResult.tasksCompleted}, Failed: ${orchestratorResult.tasksFailed}, Remaining: ${orchestratorResult.tasksRemaining}`,
833
+ };
834
+ }
835
+ // Orchestration succeeded - mark implementation complete
836
+ await updateStoryField(story, 'implementation_complete', true);
837
+ changesMade.push('Marked implementation_complete: true');
838
+ changesMade.push(`Orchestration complete: ${orchestratorResult.tasksCompleted} tasks completed in ${orchestratorResult.totalAgentInvocations} agent invocations`);
839
+ return {
840
+ success: true,
841
+ story: parseStory(currentStoryPath),
842
+ changesMade,
843
+ };
844
+ }
786
845
  if (tddEnabled) {
787
846
  changesMade.push('TDD mode enabled - using Red-Green-Refactor implementation');
788
847
  // Run TDD implementation loop
@@ -795,7 +854,7 @@ export async function runImplementationAgent(storyPath, sdlcRoot, options = {})
795
854
  // TDD completed all cycles - now verify with retry support
796
855
  changesMade.push('Running final verification...');
797
856
  const verification = await verifyImplementation(tddResult.story, workingDir);
798
- updateStoryField(tddResult.story, 'last_test_run', {
857
+ await updateStoryField(tddResult.story, 'last_test_run', {
799
858
  passed: verification.passed,
800
859
  failures: verification.failures,
801
860
  timestamp: verification.timestamp,
@@ -803,7 +862,7 @@ export async function runImplementationAgent(storyPath, sdlcRoot, options = {})
803
862
  if (!verification.passed) {
804
863
  // TDD final verification failed - this is unexpected since TDD should ensure all tests pass
805
864
  // Reset retry count since this is the first failure at this stage
806
- resetImplementationRetryCount(tddResult.story);
865
+ await resetImplementationRetryCount(tddResult.story);
807
866
  return {
808
867
  success: false,
809
868
  story: parseStory(currentStoryPath),
@@ -812,8 +871,8 @@ export async function runImplementationAgent(storyPath, sdlcRoot, options = {})
812
871
  };
813
872
  }
814
873
  // Success - reset retry count
815
- resetImplementationRetryCount(tddResult.story);
816
- updateStoryField(tddResult.story, 'implementation_complete', true);
874
+ await resetImplementationRetryCount(tddResult.story);
875
+ await updateStoryField(tddResult.story, 'implementation_complete', true);
817
876
  changesMade.push('Marked implementation_complete: true');
818
877
  return {
819
878
  success: true,
@@ -862,8 +921,13 @@ export async function runImplementationAgent(storyPath, sdlcRoot, options = {})
862
921
  const errorMsg = error instanceof Error ? error.message : String(error);
863
922
  changesMade.push(`Commit warning: ${errorMsg} (continuing implementation)`);
864
923
  }
865
- updateStoryField(updatedStory, 'implementation_complete', true);
924
+ await updateStoryField(updatedStory, 'implementation_complete', true);
866
925
  changesMade.push('Marked implementation_complete: true');
926
+ logger.info('implementation', 'Implementation phase complete', {
927
+ storyId: story.frontmatter.id,
928
+ durationMs: Date.now() - startTime,
929
+ changesCount: changesMade.length,
930
+ });
867
931
  return {
868
932
  success: true,
869
933
  story: parseStory(currentStoryPath),
@@ -871,11 +935,17 @@ export async function runImplementationAgent(storyPath, sdlcRoot, options = {})
871
935
  };
872
936
  }
873
937
  catch (error) {
938
+ const errorMessage = error instanceof Error ? error.message : String(error);
939
+ logger.error('implementation', 'Implementation phase failed', {
940
+ storyId: story.frontmatter.id,
941
+ durationMs: Date.now() - startTime,
942
+ error: errorMessage,
943
+ });
874
944
  return {
875
945
  success: false,
876
946
  story,
877
947
  changesMade,
878
- error: error instanceof Error ? error.message : String(error),
948
+ error: errorMessage,
879
949
  };
880
950
  }
881
951
  }
@@ -942,6 +1012,72 @@ export function captureCurrentDiffHash(workingDir) {
942
1012
  export function hasChangesOccurred(previousHash, currentHash) {
943
1013
  return previousHash !== currentHash;
944
1014
  }
1015
+ /**
1016
+ * Extract list of changed files from git diff
1017
+ * @param workingDir The working directory
1018
+ * @returns Comma-separated list of changed files, or descriptive message
1019
+ */
1020
+ export function extractChangedFiles(workingDir) {
1021
+ try {
1022
+ validateWorkingDir(workingDir);
1023
+ const result = spawnSync('git', ['diff', 'HEAD', '--name-only'], {
1024
+ cwd: workingDir,
1025
+ shell: false,
1026
+ encoding: 'utf-8',
1027
+ stdio: ['ignore', 'pipe', 'pipe'],
1028
+ });
1029
+ if (result.status === 0 && result.stdout) {
1030
+ const files = result.stdout.trim().split('\n').filter(Boolean);
1031
+ if (files.length === 0) {
1032
+ return 'No changes detected';
1033
+ }
1034
+ return files.join(', ');
1035
+ }
1036
+ return 'No changes detected';
1037
+ }
1038
+ catch {
1039
+ return 'Unable to determine changes';
1040
+ }
1041
+ }
1042
+ /**
1043
+ * Build formatted retry history section for agent prompts
1044
+ * @param history Array of attempt history entries
1045
+ * @returns Formatted string for inclusion in retry prompts
1046
+ */
1047
+ export function buildRetryHistorySection(history) {
1048
+ if (!history || history.length === 0) {
1049
+ return '';
1050
+ }
1051
+ const recentHistory = history.slice(-3);
1052
+ let section = `PREVIOUS ATTEMPT HISTORY (Last ${recentHistory.length} attempts):
1053
+
1054
+ `;
1055
+ for (const entry of recentHistory) {
1056
+ const outcomeLabel = entry.outcome === 'failed_tests'
1057
+ ? 'Tests failed'
1058
+ : entry.outcome === 'failed_build'
1059
+ ? 'Build failed'
1060
+ : 'No changes made';
1061
+ section += `Attempt ${entry.attempt}: ${entry.changesSummary} -> ${outcomeLabel}\n`;
1062
+ const errors = [];
1063
+ if (entry.testSnippet && entry.testSnippet.trim()) {
1064
+ errors.push(entry.testSnippet.trim());
1065
+ }
1066
+ if (entry.buildSnippet && entry.buildSnippet.trim()) {
1067
+ errors.push(entry.buildSnippet.trim());
1068
+ }
1069
+ const errorsToShow = errors.slice(0, 2);
1070
+ if (errorsToShow.length > 0) {
1071
+ for (const err of errorsToShow) {
1072
+ section += ` - ${err.substring(0, 100)}\n`;
1073
+ }
1074
+ }
1075
+ }
1076
+ section += `
1077
+ **IMPORTANT: Do NOT repeat the same fixes. Try a different approach.**
1078
+ `;
1079
+ return section;
1080
+ }
945
1081
  /**
946
1082
  * Sanitize test output to remove ANSI escape sequences and potential injection patterns
947
1083
  * @param output Test output string
@@ -982,21 +1118,114 @@ export function truncateTestOutput(output, maxLength = 5000) {
982
1118
  const truncated = sanitized.substring(0, maxLength);
983
1119
  return truncated + `\n\n[Output truncated. Showing first ${maxLength} characters of ${sanitized.length} total.]`;
984
1120
  }
1121
+ /**
1122
+ * Detect if errors are related to missing dependencies
1123
+ * Returns module names that are missing, if any
1124
+ */
1125
+ export function detectMissingDependencies(output) {
1126
+ if (!output)
1127
+ return [];
1128
+ const missingModules = [];
1129
+ // Pattern: Cannot find module 'package-name'
1130
+ const cannotFindPattern = /Cannot find module ['"]([^'"]+)['"]/g;
1131
+ let match;
1132
+ while ((match = cannotFindPattern.exec(output)) !== null) {
1133
+ const moduleName = match[1];
1134
+ // Only include external packages, not relative imports
1135
+ if (!moduleName.startsWith('.') && !moduleName.startsWith('/')) {
1136
+ // Extract base package name (handle scoped packages like @types/foo)
1137
+ const baseName = moduleName.startsWith('@')
1138
+ ? moduleName.split('/').slice(0, 2).join('/')
1139
+ : moduleName.split('/')[0];
1140
+ if (!missingModules.includes(baseName)) {
1141
+ missingModules.push(baseName);
1142
+ }
1143
+ }
1144
+ }
1145
+ // Pattern: Module not found: Error: Can't resolve 'package-name'
1146
+ const cantResolvePattern = /(?:Module not found|Can't resolve)[:\s]+['"]([^'"]+)['"]/g;
1147
+ while ((match = cantResolvePattern.exec(output)) !== null) {
1148
+ const moduleName = match[1];
1149
+ if (!moduleName.startsWith('.') && !moduleName.startsWith('/')) {
1150
+ const baseName = moduleName.startsWith('@')
1151
+ ? moduleName.split('/').slice(0, 2).join('/')
1152
+ : moduleName.split('/')[0];
1153
+ if (!missingModules.includes(baseName)) {
1154
+ missingModules.push(baseName);
1155
+ }
1156
+ }
1157
+ }
1158
+ return missingModules;
1159
+ }
985
1160
  /**
986
1161
  * Build retry prompt for implementation agent
987
1162
  * @param testOutput Test failure output
1163
+ * @param buildOutput Build output
988
1164
  * @param attemptNumber Current attempt number (1-indexed)
989
1165
  * @param maxRetries Maximum number of retries
1166
+ * @param attemptHistory Optional history of previous attempts
990
1167
  * @returns Prompt string for retry attempt
991
1168
  */
992
- export function buildRetryPrompt(testOutput, buildOutput, attemptNumber, maxRetries) {
1169
+ export function buildRetryPrompt(testOutput, buildOutput, attemptNumber, maxRetries, attemptHistory) {
993
1170
  const truncatedTestOutput = truncateTestOutput(testOutput);
994
1171
  const truncatedBuildOutput = truncateTestOutput(buildOutput);
1172
+ // Detect if this is a dependency issue
1173
+ const combinedOutput = (buildOutput || '') + '\n' + (testOutput || '');
1174
+ const missingDeps = detectMissingDependencies(combinedOutput);
1175
+ // Parse and classify TypeScript errors from build output
1176
+ const tsErrors = parseTypeScriptErrors(buildOutput || '');
1177
+ const classified = classifyAndSortErrors(tsErrors);
995
1178
  let prompt = `CRITICAL: Tests are failing. You attempted implementation but verification failed.
996
1179
 
997
1180
  This is retry attempt ${attemptNumber} of ${maxRetries}. Previous attempts failed with similar errors.
998
1181
 
999
1182
  `;
1183
+ // Add special guidance for missing dependencies
1184
+ if (missingDeps.length > 0) {
1185
+ prompt += `**DEPENDENCY ISSUE DETECTED**
1186
+
1187
+ The errors indicate missing npm packages: ${missingDeps.join(', ')}
1188
+
1189
+ This is NOT a code bug - the packages need to be installed. Before making any code changes:
1190
+ 1. Run \`npm install ${missingDeps.join(' ')}\` to add the missing packages
1191
+ 2. If these are type definitions, also run \`npm install -D @types/${missingDeps.filter(d => !d.startsWith('@')).join(' @types/')}\`
1192
+ 3. Re-run the build/tests after installing
1193
+
1194
+ `;
1195
+ }
1196
+ // Add TypeScript error classification if errors were found
1197
+ if (classified.source.length > 0 || classified.cascading.length > 0) {
1198
+ prompt += `TYPESCRIPT ERROR CLASSIFICATION
1199
+
1200
+ `;
1201
+ if (classified.source.length > 0) {
1202
+ prompt += `⚠️ SOURCE ERRORS (Fix these first - root causes):
1203
+
1204
+ `;
1205
+ classified.source.forEach((err) => {
1206
+ const location = err.line ? `${err.filePath}:${err.line}` : err.filePath;
1207
+ prompt += `- ${err.code} in ${location}: ${err.message}\n`;
1208
+ });
1209
+ prompt += '\n';
1210
+ }
1211
+ if (classified.cascading.length > 0) {
1212
+ prompt += `💡 CASCADING ERRORS (may automatically resolve):
1213
+
1214
+ `;
1215
+ classified.cascading.forEach((err) => {
1216
+ const location = err.line ? `${err.filePath}:${err.line}` : err.filePath;
1217
+ prompt += `- ${err.code} in ${location}: ${err.message}\n`;
1218
+ });
1219
+ prompt += '\n';
1220
+ }
1221
+ prompt += `**Strategy:** Fix source errors first, as they may automatically resolve multiple cascading errors.
1222
+
1223
+ `;
1224
+ }
1225
+ if (attemptHistory && attemptHistory.length > 0) {
1226
+ prompt += buildRetryHistorySection(attemptHistory);
1227
+ prompt += '\n';
1228
+ }
1000
1229
  if (buildOutput && buildOutput.trim().length > 0) {
1001
1230
  prompt += `Build Output:
1002
1231
  \`\`\`