@auto-engineer/component-implementor-react 1.108.0 → 1.109.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +6 -6
  3. package/.turbo/turbo-type-check.log +1 -1
  4. package/CHANGELOG.md +49 -0
  5. package/dist/src/commands/implement-component.d.ts +3 -0
  6. package/dist/src/commands/implement-component.d.ts.map +1 -1
  7. package/dist/src/commands/implement-component.js +11 -33
  8. package/dist/src/commands/implement-component.js.map +1 -1
  9. package/dist/src/commands/implement-component.test.js +6 -66
  10. package/dist/src/commands/implement-component.test.js.map +1 -1
  11. package/dist/src/pipeline/run-pipeline.d.ts +5 -25
  12. package/dist/src/pipeline/run-pipeline.d.ts.map +1 -1
  13. package/dist/src/pipeline/run-pipeline.js +17 -47
  14. package/dist/src/pipeline/run-pipeline.js.map +1 -1
  15. package/dist/src/pipeline/run-pipeline.test.js +29 -132
  16. package/dist/src/pipeline/run-pipeline.test.js.map +1 -1
  17. package/dist/src/pipeline/steps/fix-from-feedback.d.ts +4 -0
  18. package/dist/src/pipeline/steps/fix-from-feedback.d.ts.map +1 -0
  19. package/dist/src/pipeline/steps/fix-from-feedback.js +94 -0
  20. package/dist/src/pipeline/steps/fix-from-feedback.js.map +1 -0
  21. package/dist/src/pipeline/steps/generate-component.test.js +1 -5
  22. package/dist/src/pipeline/steps/generate-component.test.js.map +1 -1
  23. package/dist/src/pipeline/steps/generate-story.test.js +1 -5
  24. package/dist/src/pipeline/steps/generate-story.test.js.map +1 -1
  25. package/dist/src/pipeline/steps/generate-test.test.js +1 -5
  26. package/dist/src/pipeline/steps/generate-test.test.js.map +1 -1
  27. package/dist/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +3 -3
  29. package/src/commands/implement-component.test.ts +6 -66
  30. package/src/commands/implement-component.ts +16 -47
  31. package/src/pipeline/run-pipeline.test.ts +32 -141
  32. package/src/pipeline/run-pipeline.ts +22 -74
  33. package/src/pipeline/steps/fix-from-feedback.ts +105 -0
  34. package/src/pipeline/steps/generate-component.test.ts +1 -5
  35. package/src/pipeline/steps/generate-story.test.ts +1 -5
  36. package/src/pipeline/steps/generate-test.test.ts +1 -5
  37. package/dist/src/pipeline/steps/lint-fix-loop.d.ts +0 -4
  38. package/dist/src/pipeline/steps/lint-fix-loop.d.ts.map +0 -1
  39. package/dist/src/pipeline/steps/lint-fix-loop.js +0 -46
  40. package/dist/src/pipeline/steps/lint-fix-loop.js.map +0 -1
  41. package/dist/src/pipeline/steps/lint-fix-loop.test.d.ts +0 -2
  42. package/dist/src/pipeline/steps/lint-fix-loop.test.d.ts.map +0 -1
  43. package/dist/src/pipeline/steps/lint-fix-loop.test.js +0 -136
  44. package/dist/src/pipeline/steps/lint-fix-loop.test.js.map +0 -1
  45. package/dist/src/pipeline/steps/story-fix-loop.d.ts +0 -4
  46. package/dist/src/pipeline/steps/story-fix-loop.d.ts.map +0 -1
  47. package/dist/src/pipeline/steps/story-fix-loop.js +0 -35
  48. package/dist/src/pipeline/steps/story-fix-loop.js.map +0 -1
  49. package/dist/src/pipeline/steps/story-fix-loop.test.d.ts +0 -2
  50. package/dist/src/pipeline/steps/story-fix-loop.test.d.ts.map +0 -1
  51. package/dist/src/pipeline/steps/story-fix-loop.test.js +0 -98
  52. package/dist/src/pipeline/steps/story-fix-loop.test.js.map +0 -1
  53. package/dist/src/pipeline/steps/storybook-test.d.ts +0 -3
  54. package/dist/src/pipeline/steps/storybook-test.d.ts.map +0 -1
  55. package/dist/src/pipeline/steps/storybook-test.js +0 -22
  56. package/dist/src/pipeline/steps/storybook-test.js.map +0 -1
  57. package/dist/src/pipeline/steps/storybook-test.test.d.ts +0 -2
  58. package/dist/src/pipeline/steps/storybook-test.test.d.ts.map +0 -1
  59. package/dist/src/pipeline/steps/storybook-test.test.js +0 -70
  60. package/dist/src/pipeline/steps/storybook-test.test.js.map +0 -1
  61. package/dist/src/pipeline/steps/test-fix-loop.d.ts +0 -4
  62. package/dist/src/pipeline/steps/test-fix-loop.d.ts.map +0 -1
  63. package/dist/src/pipeline/steps/test-fix-loop.js +0 -45
  64. package/dist/src/pipeline/steps/test-fix-loop.js.map +0 -1
  65. package/dist/src/pipeline/steps/test-fix-loop.test.d.ts +0 -2
  66. package/dist/src/pipeline/steps/test-fix-loop.test.d.ts.map +0 -1
  67. package/dist/src/pipeline/steps/test-fix-loop.test.js +0 -172
  68. package/dist/src/pipeline/steps/test-fix-loop.test.js.map +0 -1
  69. package/dist/src/pipeline/steps/type-fix-loop.d.ts +0 -4
  70. package/dist/src/pipeline/steps/type-fix-loop.d.ts.map +0 -1
  71. package/dist/src/pipeline/steps/type-fix-loop.js +0 -44
  72. package/dist/src/pipeline/steps/type-fix-loop.js.map +0 -1
  73. package/dist/src/pipeline/steps/type-fix-loop.test.d.ts +0 -2
  74. package/dist/src/pipeline/steps/type-fix-loop.test.d.ts.map +0 -1
  75. package/dist/src/pipeline/steps/type-fix-loop.test.js +0 -116
  76. package/dist/src/pipeline/steps/type-fix-loop.test.js.map +0 -1
  77. package/dist/src/pipeline/steps/visual-test.d.ts +0 -3
  78. package/dist/src/pipeline/steps/visual-test.d.ts.map +0 -1
  79. package/dist/src/pipeline/steps/visual-test.js +0 -4
  80. package/dist/src/pipeline/steps/visual-test.js.map +0 -1
  81. package/dist/src/pipeline/steps/visual-test.test.d.ts +0 -2
  82. package/dist/src/pipeline/steps/visual-test.test.d.ts.map +0 -1
  83. package/dist/src/pipeline/steps/visual-test.test.js +0 -9
  84. package/dist/src/pipeline/steps/visual-test.test.js.map +0 -1
  85. package/src/pipeline/steps/lint-fix-loop.test.ts +0 -176
  86. package/src/pipeline/steps/lint-fix-loop.ts +0 -61
  87. package/src/pipeline/steps/story-fix-loop.test.ts +0 -127
  88. package/src/pipeline/steps/story-fix-loop.ts +0 -48
  89. package/src/pipeline/steps/storybook-test.test.ts +0 -86
  90. package/src/pipeline/steps/storybook-test.ts +0 -27
  91. package/src/pipeline/steps/test-fix-loop.test.ts +0 -205
  92. package/src/pipeline/steps/test-fix-loop.ts +0 -57
  93. package/src/pipeline/steps/type-fix-loop.test.ts +0 -149
  94. package/src/pipeline/steps/type-fix-loop.ts +0 -56
  95. package/src/pipeline/steps/visual-test.test.ts +0 -10
  96. package/src/pipeline/steps/visual-test.ts +0 -5
@@ -2,15 +2,10 @@ import type { LanguageModel } from 'ai';
2
2
  import createDebug from 'debug';
3
3
  import type { DeterministicStoryProp, StoryVariant } from '../generate-story-deterministic';
4
4
  import type { SpecDeltas } from '../spec-contract';
5
+ import { fixFromFeedbackStep } from './steps/fix-from-feedback';
5
6
  import { generateComponentStep } from './steps/generate-component';
6
7
  import { generateStoryStep } from './steps/generate-story';
7
8
  import { generateTestStep } from './steps/generate-test';
8
- import { lintFixLoop } from './steps/lint-fix-loop';
9
- import { storyFixLoop } from './steps/story-fix-loop';
10
- import { storybookTestStep } from './steps/storybook-test';
11
- import { testFixLoop } from './steps/test-fix-loop';
12
- import { typeFixLoop } from './steps/type-fix-loop';
13
- import { visualTestStep } from './steps/visual-test';
14
9
 
15
10
  const debug = createDebug('auto:component-implementor-react:pipeline');
16
11
 
@@ -43,58 +38,53 @@ export type PipelineContext = {
43
38
  componentCode?: string;
44
39
  storyCode?: string;
45
40
  llmCalls: number;
46
- fixIterations: number;
47
- typeFixIterations: number;
48
- testFixIterations: number;
49
- lintFixIterations: number;
50
- storyFixIterations: number;
41
+ errorFeedback?: string;
42
+ attemptNumber: number;
51
43
  };
52
44
 
53
45
  export type ModelConfig = {
54
46
  generateTest: string;
55
47
  generateComponent: string;
56
- typeFixer: string;
57
- testFixer: string;
58
- lintFixer: string;
59
- storyFixer: string;
48
+ fixer: string;
60
49
  };
61
50
 
62
51
  export type PipelineConfig = {
63
52
  models: ModelConfig;
64
- maxTypeFixIterations: number;
65
- maxTestFixIterations: number;
66
- maxLintFixIterations: number;
67
- maxStoryFixIterations: number;
68
- enableStorybookTest: boolean;
69
- enableVisualTest: boolean;
70
53
  };
71
54
 
72
55
  export type PipelineModels = {
73
56
  generateTest: LanguageModel;
74
57
  generateComponent: LanguageModel;
75
- typeFixer: LanguageModel;
76
- testFixer: LanguageModel;
77
- lintFixer: LanguageModel;
78
- storyFixer: LanguageModel;
58
+ fixer: LanguageModel;
79
59
  };
80
60
 
81
61
  export type PipelineResult = {
82
62
  success: boolean;
83
63
  error?: string;
84
64
  llmCalls: number;
85
- fixIterations: number;
86
- typeFixIterations: number;
87
- testFixIterations: number;
88
- lintFixIterations: number;
89
- storyFixIterations: number;
90
65
  };
91
66
 
92
67
  export function buildPipelineSteps(
93
68
  models: PipelineModels,
94
- config: PipelineConfig,
69
+ _config: PipelineConfig,
95
70
  ctx: PipelineContext,
96
71
  ): PipelineStep[] {
97
- const steps: PipelineStep[] = [
72
+ // On retry (attemptNumber > 0), fix from feedback then regenerate story
73
+ if (ctx.attemptNumber > 0 && ctx.errorFeedback) {
74
+ return [
75
+ {
76
+ name: 'Fix From Feedback',
77
+ run: () => fixFromFeedbackStep(models.fixer, ctx),
78
+ },
79
+ {
80
+ name: 'Generate Story',
81
+ run: () => generateStoryStep(ctx),
82
+ },
83
+ ];
84
+ }
85
+
86
+ // First attempt: generate everything
87
+ return [
98
88
  {
99
89
  name: 'Generate Test',
100
90
  run: () => generateTestStep(models.generateTest, ctx),
@@ -103,43 +93,11 @@ export function buildPipelineSteps(
103
93
  name: 'Generate Component',
104
94
  run: () => generateComponentStep(models.generateComponent, ctx),
105
95
  },
106
- {
107
- name: 'Type Fix Loop',
108
- run: () => typeFixLoop(models.typeFixer, ctx, config.maxTypeFixIterations),
109
- },
110
- {
111
- name: 'Test Fix Loop',
112
- run: () => testFixLoop(models.testFixer, ctx, config.maxTestFixIterations),
113
- },
114
- {
115
- name: 'Lint Fix Loop',
116
- run: () => lintFixLoop(models.lintFixer, ctx, config.maxLintFixIterations),
117
- },
118
96
  {
119
97
  name: 'Generate Story',
120
98
  run: () => generateStoryStep(ctx),
121
99
  },
122
- {
123
- name: 'Story Fix Loop',
124
- run: () => storyFixLoop(models.storyFixer, ctx, config.maxStoryFixIterations),
125
- },
126
100
  ];
127
-
128
- if (config.enableStorybookTest) {
129
- steps.push({
130
- name: 'Storybook Test',
131
- run: () => storybookTestStep(ctx, true),
132
- });
133
- }
134
-
135
- if (config.enableVisualTest) {
136
- steps.push({
137
- name: 'Visual Test',
138
- run: () => visualTestStep(),
139
- });
140
- }
141
-
142
- return steps;
143
101
  }
144
102
 
145
103
  export async function runPipeline(steps: PipelineStep[], ctx: PipelineContext): Promise<PipelineResult> {
@@ -153,11 +111,6 @@ export async function runPipeline(steps: PipelineStep[], ctx: PipelineContext):
153
111
  success: false,
154
112
  error: `Step "${step.name}" failed: ${result.error}`,
155
113
  llmCalls: ctx.llmCalls,
156
- fixIterations: ctx.fixIterations,
157
- typeFixIterations: ctx.typeFixIterations,
158
- testFixIterations: ctx.testFixIterations,
159
- lintFixIterations: ctx.lintFixIterations,
160
- storyFixIterations: ctx.storyFixIterations,
161
114
  };
162
115
  }
163
116
 
@@ -167,10 +120,5 @@ export async function runPipeline(steps: PipelineStep[], ctx: PipelineContext):
167
120
  return {
168
121
  success: true,
169
122
  llmCalls: ctx.llmCalls,
170
- fixIterations: ctx.fixIterations,
171
- typeFixIterations: ctx.typeFixIterations,
172
- testFixIterations: ctx.testFixIterations,
173
- lintFixIterations: ctx.lintFixIterations,
174
- storyFixIterations: ctx.storyFixIterations,
175
123
  };
176
124
  }
@@ -0,0 +1,105 @@
1
+ import { readFile, writeFile } from 'node:fs/promises';
2
+ import type { LanguageModel } from 'ai';
3
+ import { generateText } from 'ai';
4
+ import { extractCodeBlocks } from '../../extract-code-block';
5
+ import { buildLintFixPrompt, buildTestFixPrompt, buildTypeFixPrompt } from '../../prompt';
6
+ import type { PipelineContext, StepResult } from '../run-pipeline';
7
+
8
+ type ErrorCategory = 'type' | 'test' | 'lint' | 'mixed';
9
+
10
+ function categorizeErrors(errorFeedback: string): ErrorCategory {
11
+ const hasTypeError = /error TS\d+|type.*error|typescript/i.test(errorFeedback);
12
+ const hasTestFailure = /test.*fail|vitest|expect.*to|assertion/i.test(errorFeedback);
13
+ const hasLintError = /lint|biome|eslint/i.test(errorFeedback);
14
+
15
+ const categories = [hasTypeError, hasTestFailure, hasLintError].filter(Boolean).length;
16
+
17
+ if (categories > 1) return 'mixed';
18
+ if (hasTypeError) return 'type';
19
+ if (hasTestFailure) return 'test';
20
+ if (hasLintError) return 'lint';
21
+
22
+ // Default to test errors if we can't categorize
23
+ return 'test';
24
+ }
25
+
26
+ export async function fixFromFeedbackStep(model: LanguageModel, ctx: PipelineContext): Promise<StepResult> {
27
+ if (!ctx.errorFeedback) {
28
+ return { success: true };
29
+ }
30
+
31
+ // Read existing files
32
+ const componentCode = await readFile(ctx.componentPath, 'utf-8');
33
+ const testCode = await readFile(ctx.testPath, 'utf-8');
34
+
35
+ ctx.componentCode = componentCode;
36
+ ctx.testCode = testCode;
37
+
38
+ const errorCategory = categorizeErrors(ctx.errorFeedback);
39
+
40
+ let system: string;
41
+ let prompt: string;
42
+
43
+ switch (errorCategory) {
44
+ case 'type': {
45
+ const typePrompt = buildTypeFixPrompt({
46
+ componentCode,
47
+ testCode,
48
+ errors: [ctx.errorFeedback],
49
+ });
50
+ system = typePrompt.system;
51
+ prompt = typePrompt.prompt;
52
+ break;
53
+ }
54
+ case 'test': {
55
+ const testPrompt = buildTestFixPrompt({
56
+ componentCode,
57
+ testCode,
58
+ failures: [ctx.errorFeedback],
59
+ testOutput: ctx.errorFeedback,
60
+ });
61
+ system = testPrompt.system;
62
+ prompt = testPrompt.prompt;
63
+ break;
64
+ }
65
+ case 'lint': {
66
+ const lintPrompt = buildLintFixPrompt({
67
+ componentCode,
68
+ testCode,
69
+ errors: [ctx.errorFeedback],
70
+ });
71
+ system = lintPrompt.system;
72
+ prompt = lintPrompt.prompt;
73
+ break;
74
+ }
75
+ case 'mixed':
76
+ default: {
77
+ // For mixed errors, use test fix prompt (most comprehensive)
78
+ const mixedPrompt = buildTestFixPrompt({
79
+ componentCode,
80
+ testCode,
81
+ failures: [ctx.errorFeedback],
82
+ testOutput: ctx.errorFeedback,
83
+ });
84
+ system = mixedPrompt.system;
85
+ prompt = mixedPrompt.prompt;
86
+ break;
87
+ }
88
+ }
89
+
90
+ const { text } = await generateText({ model, system, prompt });
91
+ ctx.llmCalls++;
92
+
93
+ const blocks = extractCodeBlocks(text);
94
+ if (blocks.length >= 2) {
95
+ ctx.componentCode = blocks[0];
96
+ ctx.testCode = blocks[1];
97
+ await writeFile(ctx.componentPath, blocks[0], 'utf-8');
98
+ await writeFile(ctx.testPath, blocks[1], 'utf-8');
99
+ } else if (blocks.length === 1) {
100
+ ctx.componentCode = blocks[0];
101
+ await writeFile(ctx.componentPath, blocks[0], 'utf-8');
102
+ }
103
+
104
+ return { success: true };
105
+ }
@@ -36,11 +36,7 @@ function makeCtx(overrides: Partial<PipelineContext> = {}): PipelineContext {
36
36
  composes: [],
37
37
  isModify: false,
38
38
  llmCalls: 0,
39
- fixIterations: 0,
40
- typeFixIterations: 0,
41
- testFixIterations: 0,
42
- lintFixIterations: 0,
43
- storyFixIterations: 0,
39
+ attemptNumber: 0,
44
40
  testCode: 'import { render } from "@testing-library/react";',
45
41
  ...overrides,
46
42
  };
@@ -21,11 +21,7 @@ function makeCtx(overrides: Partial<PipelineContext> = {}): PipelineContext {
21
21
  composes: [],
22
22
  isModify: false,
23
23
  llmCalls: 0,
24
- fixIterations: 0,
25
- typeFixIterations: 0,
26
- testFixIterations: 0,
27
- lintFixIterations: 0,
28
- storyFixIterations: 0,
24
+ attemptNumber: 0,
29
25
  ...overrides,
30
26
  };
31
27
  }
@@ -35,11 +35,7 @@ function makeCtx(overrides: Partial<PipelineContext> = {}): PipelineContext {
35
35
  composes: [],
36
36
  isModify: false,
37
37
  llmCalls: 0,
38
- fixIterations: 0,
39
- typeFixIterations: 0,
40
- testFixIterations: 0,
41
- lintFixIterations: 0,
42
- storyFixIterations: 0,
38
+ attemptNumber: 0,
43
39
  ...overrides,
44
40
  };
45
41
  }
@@ -1,4 +0,0 @@
1
- import type { LanguageModel } from 'ai';
2
- import type { PipelineContext, StepResult } from '../run-pipeline';
3
- export declare function lintFixLoop(model: LanguageModel, ctx: PipelineContext, maxIterations: number): Promise<StepResult>;
4
- //# sourceMappingURL=lint-fix-loop.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lint-fix-loop.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/steps/lint-fix-loop.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAKxC,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnE,wBAAsB,WAAW,CAC/B,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,eAAe,EACpB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,UAAU,CAAC,CAgDrB"}
@@ -1,46 +0,0 @@
1
- import { readFile, writeFile } from 'node:fs/promises';
2
- import { generateText } from 'ai';
3
- import { extractCodeBlocks } from '../../extract-code-block.js';
4
- import { buildLintFixPrompt } from '../../prompt.js';
5
- import { runLint, runLintFix } from '../../tools/lint-runner.js';
6
- export async function lintFixLoop(model, ctx, maxIterations) {
7
- const filePaths = [ctx.componentPath, ctx.testPath];
8
- runLintFix(filePaths, ctx.targetDir);
9
- ctx.componentCode = await readFile(ctx.componentPath, 'utf-8');
10
- ctx.testCode = await readFile(ctx.testPath, 'utf-8');
11
- for (let i = 0; i < maxIterations; i++) {
12
- const result = runLint(filePaths, ctx.targetDir);
13
- if (result.passed) {
14
- return { success: true };
15
- }
16
- const { system, prompt } = buildLintFixPrompt({
17
- componentCode: ctx.componentCode ?? '',
18
- testCode: ctx.testCode ?? '',
19
- errors: result.errors,
20
- });
21
- const { text } = await generateText({ model, system, prompt });
22
- ctx.llmCalls++;
23
- ctx.fixIterations++;
24
- ctx.lintFixIterations++;
25
- const blocks = extractCodeBlocks(text);
26
- if (blocks.length >= 2) {
27
- await writeFile(ctx.componentPath, blocks[0], 'utf-8');
28
- await writeFile(ctx.testPath, blocks[1], 'utf-8');
29
- }
30
- else if (blocks.length === 1) {
31
- await writeFile(ctx.componentPath, blocks[0], 'utf-8');
32
- }
33
- runLintFix(filePaths, ctx.targetDir);
34
- ctx.componentCode = await readFile(ctx.componentPath, 'utf-8');
35
- ctx.testCode = await readFile(ctx.testPath, 'utf-8');
36
- }
37
- const finalResult = runLint(filePaths, ctx.targetDir);
38
- if (finalResult.passed) {
39
- return { success: true };
40
- }
41
- return {
42
- success: false,
43
- error: `Lint errors remain after ${maxIterations} iterations: ${finalResult.errors.slice(0, 3).join('; ')}`,
44
- };
45
- }
46
- //# sourceMappingURL=lint-fix-loop.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lint-fix-loop.js","sourceRoot":"","sources":["../../../../src/pipeline/steps/lint-fix-loop.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=lint-fix-loop.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lint-fix-loop.test.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/steps/lint-fix-loop.test.ts"],"names":[],"mappings":""}
@@ -1,136 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
- vi.mock('ai', () => ({
3
- generateText: vi.fn(),
4
- }));
5
- vi.mock('node:fs/promises', () => ({
6
- readFile: vi.fn(),
7
- writeFile: vi.fn(),
8
- }));
9
- vi.mock('../../tools/lint-runner', () => ({
10
- runLint: vi.fn(),
11
- runLintFix: vi.fn(),
12
- }));
13
- import { readFile, writeFile } from 'node:fs/promises';
14
- import { generateText } from 'ai';
15
- import { runLint, runLintFix } from '../../tools/lint-runner.js';
16
- import { lintFixLoop } from './lint-fix-loop.js';
17
- afterEach(() => {
18
- vi.clearAllMocks();
19
- });
20
- function makeCtx(overrides = {}) {
21
- return {
22
- componentName: 'MyButton',
23
- componentPath: '/project/src/MyButton.tsx',
24
- testPath: '/project/src/MyButton.test.tsx',
25
- storyPath: '/project/src/MyButton.stories.tsx',
26
- componentImportPath: '@/components/ui/MyButton',
27
- targetDir: '/project',
28
- specDeltas: { structure: [], rendering: [], interaction: [], styling: [] },
29
- projectSection: '',
30
- composes: [],
31
- isModify: false,
32
- llmCalls: 0,
33
- fixIterations: 0,
34
- typeFixIterations: 0,
35
- testFixIterations: 0,
36
- lintFixIterations: 0,
37
- storyFixIterations: 0,
38
- componentCode: 'original component',
39
- testCode: 'original test',
40
- ...overrides,
41
- };
42
- }
43
- describe('lintFixLoop', () => {
44
- it('runs auto-fix first, then returns success if lint passes', async () => {
45
- vi.mocked(runLintFix).mockReturnValue({ passed: true, errors: [] });
46
- vi.mocked(readFile).mockResolvedValue('auto-fixed code');
47
- vi.mocked(runLint).mockReturnValue({ passed: true, errors: [] });
48
- const result = await lintFixLoop('mock-model', makeCtx(), 2);
49
- expect(result).toEqual({ success: true });
50
- expect(runLintFix).toHaveBeenCalledWith(['/project/src/MyButton.tsx', '/project/src/MyButton.test.tsx'], '/project');
51
- expect(generateText).not.toHaveBeenCalled();
52
- });
53
- it('calls LLM for remaining lint errors after auto-fix', async () => {
54
- vi.mocked(runLintFix).mockReturnValue({ passed: false, errors: ['unfixable'] });
55
- vi.mocked(readFile).mockResolvedValue('auto-fixed partial');
56
- vi.mocked(runLint)
57
- .mockReturnValueOnce({ passed: false, errors: ['remaining error'] })
58
- .mockReturnValueOnce({ passed: true, errors: [] });
59
- vi.mocked(generateText).mockResolvedValue({
60
- text: '```tsx\nlint-fixed component\n```\n```tsx\nlint-fixed test\n```',
61
- });
62
- vi.mocked(writeFile).mockResolvedValue(undefined);
63
- const result = await lintFixLoop('mock-model', makeCtx(), 2);
64
- expect(result).toEqual({ success: true });
65
- expect(generateText).toHaveBeenCalledTimes(1);
66
- });
67
- it('returns failure after exhausting max iterations', async () => {
68
- vi.mocked(runLintFix).mockReturnValue({ passed: true, errors: [] });
69
- vi.mocked(readFile).mockResolvedValue('code');
70
- vi.mocked(runLint).mockReturnValue({ passed: false, errors: ['persistent lint error'] });
71
- vi.mocked(generateText).mockResolvedValue({
72
- text: '```tsx\nstill bad\n```\n```tsx\nstill bad test\n```',
73
- });
74
- vi.mocked(writeFile).mockResolvedValue(undefined);
75
- const result = await lintFixLoop('mock-model', makeCtx(), 1);
76
- expect(result).toEqual({
77
- success: false,
78
- error: expect.stringContaining('Lint errors remain after 1 iterations'),
79
- });
80
- });
81
- it('handles single code block response by updating only component', async () => {
82
- vi.mocked(runLintFix).mockReturnValue({ passed: true, errors: [] });
83
- vi.mocked(readFile).mockResolvedValue('auto-fixed');
84
- vi.mocked(runLint)
85
- .mockReturnValueOnce({ passed: false, errors: ['lint error'] })
86
- .mockReturnValueOnce({ passed: true, errors: [] });
87
- vi.mocked(generateText).mockResolvedValue({
88
- text: '```tsx\nfixed component only\n```',
89
- });
90
- vi.mocked(writeFile).mockResolvedValue(undefined);
91
- const result = await lintFixLoop('mock-model', makeCtx(), 2);
92
- expect(result).toEqual({ success: true });
93
- expect(writeFile).toHaveBeenCalledWith('/project/src/MyButton.tsx', 'fixed component only', 'utf-8');
94
- expect(writeFile).toHaveBeenCalledTimes(1);
95
- });
96
- it('returns success when final check passes after last iteration', async () => {
97
- vi.mocked(runLintFix).mockReturnValue({ passed: true, errors: [] });
98
- vi.mocked(readFile).mockResolvedValue('auto-fixed');
99
- vi.mocked(runLint)
100
- .mockReturnValueOnce({ passed: false, errors: ['error'] })
101
- .mockReturnValueOnce({ passed: true, errors: [] });
102
- vi.mocked(generateText).mockResolvedValue({
103
- text: '```tsx\nfixed\n```\n```tsx\nfixed test\n```',
104
- });
105
- vi.mocked(writeFile).mockResolvedValue(undefined);
106
- const result = await lintFixLoop('mock-model', makeCtx(), 1);
107
- expect(result).toEqual({ success: true });
108
- });
109
- it('re-runs auto-fix after each LLM write to handle formatting issues', async () => {
110
- vi.mocked(runLintFix).mockReturnValue({ passed: true, errors: [] });
111
- vi.mocked(readFile).mockResolvedValue('auto-fixed');
112
- vi.mocked(runLint)
113
- .mockReturnValueOnce({ passed: false, errors: ['format error'] })
114
- .mockReturnValueOnce({ passed: true, errors: [] });
115
- vi.mocked(generateText).mockResolvedValue({
116
- text: '```tsx\nfixed component\n```\n```tsx\nfixed test\n```',
117
- });
118
- vi.mocked(writeFile).mockResolvedValue(undefined);
119
- await lintFixLoop('mock-model', makeCtx(), 2);
120
- expect(runLintFix).toHaveBeenCalledTimes(2);
121
- });
122
- it('uses empty string fallback when componentCode and testCode are undefined after readFile', async () => {
123
- vi.mocked(runLintFix).mockReturnValue({ passed: true, errors: [] });
124
- vi.mocked(readFile).mockResolvedValue(undefined);
125
- vi.mocked(runLint)
126
- .mockReturnValueOnce({ passed: false, errors: ['error'] })
127
- .mockReturnValueOnce({ passed: true, errors: [] });
128
- vi.mocked(generateText).mockResolvedValue({
129
- text: '```tsx\nfixed\n```\n```tsx\nfixed test\n```',
130
- });
131
- vi.mocked(writeFile).mockResolvedValue(undefined);
132
- const result = await lintFixLoop('mock-model', makeCtx({ componentCode: undefined, testCode: undefined }), 1);
133
- expect(result).toEqual({ success: true });
134
- });
135
- });
136
- //# sourceMappingURL=lint-fix-loop.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lint-fix-loop.test.js","sourceRoot":"","sources":["../../../../src/pipeline/steps/lint-fix-loop.test.ts"],"names":[],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- import type { LanguageModel } from 'ai';
2
- import type { PipelineContext, StepResult } from '../run-pipeline';
3
- export declare function storyFixLoop(model: LanguageModel, ctx: PipelineContext, maxIterations: number): Promise<StepResult>;
4
- //# sourceMappingURL=story-fix-loop.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"story-fix-loop.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/steps/story-fix-loop.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAKxC,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnE,wBAAsB,YAAY,CAChC,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,eAAe,EACpB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,UAAU,CAAC,CAmCrB"}
@@ -1,35 +0,0 @@
1
- import { readFile, writeFile } from 'node:fs/promises';
2
- import { generateText } from 'ai';
3
- import { extractCodeBlock } from '../../extract-code-block.js';
4
- import { buildStoryFixPrompt } from '../../prompt.js';
5
- import { runTypeCheck } from '../../tools/type-checker.js';
6
- export async function storyFixLoop(model, ctx, maxIterations) {
7
- for (let i = 0; i < maxIterations; i++) {
8
- const result = runTypeCheck(ctx.targetDir, [ctx.storyPath]);
9
- if (result.passed) {
10
- return { success: true };
11
- }
12
- const { system, prompt } = buildStoryFixPrompt({
13
- storyCode: ctx.storyCode ?? '',
14
- componentCode: ctx.componentCode ?? '',
15
- errors: result.errors,
16
- });
17
- const { text } = await generateText({ model, system, prompt });
18
- ctx.llmCalls++;
19
- ctx.fixIterations++;
20
- ctx.storyFixIterations++;
21
- const fixedStory = extractCodeBlock(text);
22
- ctx.storyCode = fixedStory;
23
- await writeFile(ctx.storyPath, fixedStory, 'utf-8');
24
- }
25
- const finalResult = runTypeCheck(ctx.targetDir, [ctx.storyPath]);
26
- if (finalResult.passed) {
27
- return { success: true };
28
- }
29
- ctx.storyCode = await readFile(ctx.storyPath, 'utf-8');
30
- return {
31
- success: false,
32
- error: `Story type errors remain after ${maxIterations} iterations: ${finalResult.errors.join('; ')}`,
33
- };
34
- }
35
- //# sourceMappingURL=story-fix-loop.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"story-fix-loop.js","sourceRoot":"","sources":["../../../../src/pipeline/steps/story-fix-loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGxD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAoB,EACpB,GAAoB,EACpB,aAAqB;IAErB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QAE5D,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,mBAAmB,CAAC;YAC7C,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;YAC9B,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,EAAE;YACtC,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;QAEH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/D,GAAG,CAAC,QAAQ,EAAE,CAAC;QACf,GAAG,CAAC,aAAa,EAAE,CAAC;QACpB,GAAG,CAAC,kBAAkB,EAAE,CAAC;QAEzB,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC1C,GAAG,CAAC,SAAS,GAAG,UAAU,CAAC;QAC3B,MAAM,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IACjE,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,GAAG,CAAC,SAAS,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAEvD,OAAO;QACL,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,kCAAkC,aAAa,gBAAgB,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;KACtG,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=story-fix-loop.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"story-fix-loop.test.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/steps/story-fix-loop.test.ts"],"names":[],"mappings":""}