@auto-engineer/component-implementor-react 1.98.0 → 1.100.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 (233) 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 +92 -0
  5. package/dist/src/commands/implement-component.d.ts +19 -0
  6. package/dist/src/commands/implement-component.d.ts.map +1 -1
  7. package/dist/src/commands/implement-component.js +109 -30
  8. package/dist/src/commands/implement-component.js.map +1 -1
  9. package/dist/src/commands/implement-component.test.js +259 -69
  10. package/dist/src/commands/implement-component.test.js.map +1 -1
  11. package/dist/src/extract-exports.d.ts +6 -0
  12. package/dist/src/extract-exports.d.ts.map +1 -0
  13. package/dist/src/extract-exports.js +46 -0
  14. package/dist/src/extract-exports.js.map +1 -0
  15. package/dist/src/generate-story-deterministic.d.ts +30 -0
  16. package/dist/src/generate-story-deterministic.d.ts.map +1 -0
  17. package/dist/src/generate-story-deterministic.js +229 -0
  18. package/dist/src/generate-story-deterministic.js.map +1 -0
  19. package/dist/src/index.d.ts +4 -0
  20. package/dist/src/index.d.ts.map +1 -1
  21. package/dist/src/index.js +3 -0
  22. package/dist/src/index.js.map +1 -1
  23. package/dist/src/pipeline/run-pipeline.d.ts +69 -0
  24. package/dist/src/pipeline/run-pipeline.d.ts.map +1 -0
  25. package/dist/src/pipeline/run-pipeline.js +78 -0
  26. package/dist/src/pipeline/run-pipeline.js.map +1 -0
  27. package/dist/src/pipeline/run-pipeline.test.d.ts +2 -0
  28. package/dist/src/pipeline/run-pipeline.test.d.ts.map +1 -0
  29. package/dist/src/pipeline/run-pipeline.test.js +247 -0
  30. package/dist/src/pipeline/run-pipeline.test.js.map +1 -0
  31. package/dist/src/pipeline/steps/generate-component.d.ts +4 -0
  32. package/dist/src/pipeline/steps/generate-component.d.ts.map +1 -0
  33. package/dist/src/pipeline/steps/generate-component.js +50 -0
  34. package/dist/src/pipeline/steps/generate-component.js.map +1 -0
  35. package/dist/src/pipeline/steps/generate-component.test.d.ts.map +1 -0
  36. package/dist/src/pipeline/steps/generate-component.test.js +106 -0
  37. package/dist/src/pipeline/steps/generate-component.test.js.map +1 -0
  38. package/dist/src/pipeline/steps/generate-story.d.ts +3 -0
  39. package/dist/src/pipeline/steps/generate-story.d.ts.map +1 -0
  40. package/dist/src/pipeline/steps/generate-story.js +14 -0
  41. package/dist/src/pipeline/steps/generate-story.js.map +1 -0
  42. package/dist/src/pipeline/steps/generate-story.test.d.ts.map +1 -0
  43. package/dist/src/pipeline/steps/generate-story.test.js +41 -0
  44. package/dist/src/pipeline/steps/generate-story.test.js.map +1 -0
  45. package/dist/src/pipeline/steps/generate-test.d.ts +4 -0
  46. package/dist/src/pipeline/steps/generate-test.d.ts.map +1 -0
  47. package/dist/src/pipeline/steps/generate-test.js +19 -0
  48. package/dist/src/pipeline/steps/generate-test.js.map +1 -0
  49. package/dist/src/pipeline/steps/generate-test.test.d.ts.map +1 -0
  50. package/dist/src/pipeline/steps/generate-test.test.js +60 -0
  51. package/dist/src/pipeline/steps/generate-test.test.js.map +1 -0
  52. package/dist/src/pipeline/steps/lint-fix-loop.d.ts +4 -0
  53. package/dist/src/pipeline/steps/lint-fix-loop.d.ts.map +1 -0
  54. package/dist/src/pipeline/steps/lint-fix-loop.js +45 -0
  55. package/dist/src/pipeline/steps/lint-fix-loop.js.map +1 -0
  56. package/dist/src/pipeline/steps/lint-fix-loop.test.d.ts +2 -0
  57. package/dist/src/pipeline/steps/lint-fix-loop.test.d.ts.map +1 -0
  58. package/dist/src/pipeline/steps/lint-fix-loop.test.js +119 -0
  59. package/dist/src/pipeline/steps/lint-fix-loop.test.js.map +1 -0
  60. package/dist/src/pipeline/steps/story-fix-loop.d.ts +4 -0
  61. package/dist/src/pipeline/steps/story-fix-loop.d.ts.map +1 -0
  62. package/dist/src/pipeline/steps/story-fix-loop.js +34 -0
  63. package/dist/src/pipeline/steps/story-fix-loop.js.map +1 -0
  64. package/dist/src/pipeline/steps/story-fix-loop.test.d.ts +2 -0
  65. package/dist/src/pipeline/steps/story-fix-loop.test.d.ts.map +1 -0
  66. package/dist/src/pipeline/steps/story-fix-loop.test.js +94 -0
  67. package/dist/src/pipeline/steps/story-fix-loop.test.js.map +1 -0
  68. package/dist/src/pipeline/steps/storybook-test.d.ts +3 -0
  69. package/dist/src/pipeline/steps/storybook-test.d.ts.map +1 -0
  70. package/dist/src/pipeline/steps/storybook-test.js +22 -0
  71. package/dist/src/pipeline/steps/storybook-test.js.map +1 -0
  72. package/dist/src/pipeline/steps/storybook-test.test.d.ts +2 -0
  73. package/dist/src/pipeline/steps/storybook-test.test.d.ts.map +1 -0
  74. package/dist/src/pipeline/steps/storybook-test.test.js +66 -0
  75. package/dist/src/pipeline/steps/storybook-test.test.js.map +1 -0
  76. package/dist/src/pipeline/steps/test-fix-loop.d.ts +4 -0
  77. package/dist/src/pipeline/steps/test-fix-loop.d.ts.map +1 -0
  78. package/dist/src/pipeline/steps/test-fix-loop.js +44 -0
  79. package/dist/src/pipeline/steps/test-fix-loop.js.map +1 -0
  80. package/dist/src/pipeline/steps/test-fix-loop.test.d.ts +2 -0
  81. package/dist/src/pipeline/steps/test-fix-loop.test.d.ts.map +1 -0
  82. package/dist/src/pipeline/steps/test-fix-loop.test.js +168 -0
  83. package/dist/src/pipeline/steps/test-fix-loop.test.js.map +1 -0
  84. package/dist/src/pipeline/steps/type-fix-loop.d.ts +4 -0
  85. package/dist/src/pipeline/steps/type-fix-loop.d.ts.map +1 -0
  86. package/dist/src/pipeline/steps/type-fix-loop.js +43 -0
  87. package/dist/src/pipeline/steps/type-fix-loop.js.map +1 -0
  88. package/dist/src/pipeline/steps/type-fix-loop.test.d.ts +2 -0
  89. package/dist/src/pipeline/steps/type-fix-loop.test.d.ts.map +1 -0
  90. package/dist/src/pipeline/steps/type-fix-loop.test.js +112 -0
  91. package/dist/src/pipeline/steps/type-fix-loop.test.js.map +1 -0
  92. package/dist/src/pipeline/steps/visual-test.d.ts +3 -0
  93. package/dist/src/pipeline/steps/visual-test.d.ts.map +1 -0
  94. package/dist/src/pipeline/steps/visual-test.js +4 -0
  95. package/dist/src/pipeline/steps/visual-test.js.map +1 -0
  96. package/dist/src/pipeline/steps/visual-test.test.d.ts +2 -0
  97. package/dist/src/pipeline/steps/visual-test.test.d.ts.map +1 -0
  98. package/dist/src/pipeline/steps/visual-test.test.js +9 -0
  99. package/dist/src/pipeline/steps/visual-test.test.js.map +1 -0
  100. package/dist/src/project-context.d.ts +10 -0
  101. package/dist/src/project-context.d.ts.map +1 -0
  102. package/dist/src/project-context.js +178 -0
  103. package/dist/src/project-context.js.map +1 -0
  104. package/dist/src/prompt.d.ts +39 -7
  105. package/dist/src/prompt.d.ts.map +1 -1
  106. package/dist/src/prompt.js +233 -23
  107. package/dist/src/prompt.js.map +1 -1
  108. package/dist/src/prompt.test.js +154 -9
  109. package/dist/src/prompt.test.js.map +1 -1
  110. package/dist/src/scaffold.d.ts +49 -0
  111. package/dist/src/scaffold.d.ts.map +1 -0
  112. package/dist/src/scaffold.js +208 -0
  113. package/dist/src/scaffold.js.map +1 -0
  114. package/dist/src/tools/lint-runner.d.ts +7 -0
  115. package/dist/src/tools/lint-runner.d.ts.map +1 -0
  116. package/dist/src/tools/lint-runner.js +48 -0
  117. package/dist/src/tools/lint-runner.js.map +1 -0
  118. package/dist/src/tools/lint-runner.test.d.ts +2 -0
  119. package/dist/src/tools/lint-runner.test.d.ts.map +1 -0
  120. package/dist/src/tools/lint-runner.test.js +90 -0
  121. package/dist/src/tools/lint-runner.test.js.map +1 -0
  122. package/dist/src/tools/storybook-runner.d.ts +6 -0
  123. package/dist/src/tools/storybook-runner.d.ts.map +1 -0
  124. package/dist/src/tools/storybook-runner.js +25 -0
  125. package/dist/src/tools/storybook-runner.js.map +1 -0
  126. package/dist/src/tools/storybook-runner.test.d.ts +2 -0
  127. package/dist/src/tools/storybook-runner.test.d.ts.map +1 -0
  128. package/dist/src/tools/storybook-runner.test.js +43 -0
  129. package/dist/src/tools/storybook-runner.test.js.map +1 -0
  130. package/dist/src/tools/test-runner.d.ts +9 -0
  131. package/dist/src/tools/test-runner.d.ts.map +1 -0
  132. package/dist/src/tools/test-runner.js +74 -0
  133. package/dist/src/tools/test-runner.js.map +1 -0
  134. package/dist/src/tools/test-runner.test.d.ts +2 -0
  135. package/dist/src/tools/test-runner.test.d.ts.map +1 -0
  136. package/dist/src/tools/test-runner.test.js +177 -0
  137. package/dist/src/tools/test-runner.test.js.map +1 -0
  138. package/dist/src/tools/type-checker.d.ts +6 -0
  139. package/dist/src/tools/type-checker.d.ts.map +1 -0
  140. package/dist/src/tools/type-checker.js +36 -0
  141. package/dist/src/tools/type-checker.js.map +1 -0
  142. package/dist/src/tools/type-checker.test.d.ts +2 -0
  143. package/dist/src/tools/type-checker.test.d.ts.map +1 -0
  144. package/dist/src/tools/type-checker.test.js +96 -0
  145. package/dist/src/tools/type-checker.test.js.map +1 -0
  146. package/dist/tsconfig.tsbuildinfo +1 -1
  147. package/inputs/model-a/spec-deltas.json +1460 -0
  148. package/inputs/model-b/spec-deltas.json +1424 -0
  149. package/inputs/model-c/spec-deltas.json +1432 -0
  150. package/inputs/model-d/spec-deltas.json +967 -0
  151. package/inputs/model-e/spec-deltas.json +2292 -0
  152. package/ketchup-plan.md +43 -8
  153. package/package.json +3 -3
  154. package/scoring-heuristic.md +138 -0
  155. package/scripts/improve.ts +23 -18
  156. package/src/commands/implement-component.test.ts +309 -76
  157. package/src/commands/implement-component.ts +155 -31
  158. package/src/extract-exports.ts +53 -0
  159. package/src/generate-story-deterministic.ts +267 -0
  160. package/src/index.ts +12 -0
  161. package/src/pipeline/run-pipeline.test.ts +292 -0
  162. package/src/pipeline/run-pipeline.ts +160 -0
  163. package/src/pipeline/steps/generate-component.test.ts +130 -0
  164. package/src/pipeline/steps/generate-component.ts +60 -0
  165. package/src/pipeline/steps/generate-story.test.ts +54 -0
  166. package/src/pipeline/steps/generate-story.ts +17 -0
  167. package/src/pipeline/steps/generate-test.test.ts +75 -0
  168. package/src/pipeline/steps/generate-test.ts +25 -0
  169. package/src/pipeline/steps/lint-fix-loop.test.ts +155 -0
  170. package/src/pipeline/steps/lint-fix-loop.ts +59 -0
  171. package/src/pipeline/steps/story-fix-loop.test.ts +123 -0
  172. package/src/pipeline/steps/story-fix-loop.ts +47 -0
  173. package/src/pipeline/steps/storybook-test.test.ts +82 -0
  174. package/src/pipeline/steps/storybook-test.ts +27 -0
  175. package/src/pipeline/steps/test-fix-loop.test.ts +201 -0
  176. package/src/pipeline/steps/test-fix-loop.ts +56 -0
  177. package/src/pipeline/steps/type-fix-loop.test.ts +145 -0
  178. package/src/pipeline/steps/type-fix-loop.ts +55 -0
  179. package/src/pipeline/steps/visual-test.test.ts +10 -0
  180. package/src/pipeline/steps/visual-test.ts +5 -0
  181. package/src/project-context.ts +205 -0
  182. package/src/prompt.test.ts +174 -8
  183. package/src/prompt.ts +301 -23
  184. package/src/scaffold.ts +281 -0
  185. package/src/tools/lint-runner.test.ts +112 -0
  186. package/src/tools/lint-runner.ts +52 -0
  187. package/src/tools/storybook-runner.test.ts +53 -0
  188. package/src/tools/storybook-runner.ts +29 -0
  189. package/src/tools/test-runner.test.ts +213 -0
  190. package/src/tools/test-runner.ts +84 -0
  191. package/src/tools/type-checker.test.ts +120 -0
  192. package/src/tools/type-checker.ts +42 -0
  193. package/vitest.config.ts +9 -1
  194. package/dist/src/generate-component.d.ts +0 -4
  195. package/dist/src/generate-component.d.ts.map +0 -1
  196. package/dist/src/generate-component.js +0 -14
  197. package/dist/src/generate-component.js.map +0 -1
  198. package/dist/src/generate-component.test.d.ts.map +0 -1
  199. package/dist/src/generate-component.test.js +0 -73
  200. package/dist/src/generate-component.test.js.map +0 -1
  201. package/dist/src/generate-story.d.ts +0 -4
  202. package/dist/src/generate-story.d.ts.map +0 -1
  203. package/dist/src/generate-story.js +0 -14
  204. package/dist/src/generate-story.js.map +0 -1
  205. package/dist/src/generate-story.test.d.ts.map +0 -1
  206. package/dist/src/generate-story.test.js +0 -58
  207. package/dist/src/generate-story.test.js.map +0 -1
  208. package/dist/src/generate-test.d.ts +0 -4
  209. package/dist/src/generate-test.d.ts.map +0 -1
  210. package/dist/src/generate-test.js +0 -14
  211. package/dist/src/generate-test.js.map +0 -1
  212. package/dist/src/generate-test.test.d.ts.map +0 -1
  213. package/dist/src/generate-test.test.js +0 -77
  214. package/dist/src/generate-test.test.js.map +0 -1
  215. package/dist/src/reconcile.d.ts +0 -8
  216. package/dist/src/reconcile.d.ts.map +0 -1
  217. package/dist/src/reconcile.js +0 -18
  218. package/dist/src/reconcile.js.map +0 -1
  219. package/dist/src/reconcile.test.d.ts +0 -2
  220. package/dist/src/reconcile.test.d.ts.map +0 -1
  221. package/dist/src/reconcile.test.js +0 -108
  222. package/dist/src/reconcile.test.js.map +0 -1
  223. package/src/generate-component.test.ts +0 -89
  224. package/src/generate-component.ts +0 -16
  225. package/src/generate-story.test.ts +0 -71
  226. package/src/generate-story.ts +0 -16
  227. package/src/generate-test.test.ts +0 -93
  228. package/src/generate-test.ts +0 -16
  229. package/src/reconcile.test.ts +0 -127
  230. package/src/reconcile.ts +0 -27
  231. /package/dist/src/{generate-component.test.d.ts → pipeline/steps/generate-component.test.d.ts} +0 -0
  232. /package/dist/src/{generate-story.test.d.ts → pipeline/steps/generate-story.test.d.ts} +0 -0
  233. /package/dist/src/{generate-test.test.d.ts → pipeline/steps/generate-test.test.d.ts} +0 -0
@@ -0,0 +1,247 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest';
2
+ vi.mock('./steps/generate-test', () => ({
3
+ generateTestStep: vi.fn(async () => ({ success: true })),
4
+ }));
5
+ vi.mock('./steps/generate-component', () => ({
6
+ generateComponentStep: vi.fn(async () => ({ success: true })),
7
+ }));
8
+ vi.mock('./steps/type-fix-loop', () => ({
9
+ typeFixLoop: vi.fn(async () => ({ success: true })),
10
+ }));
11
+ vi.mock('./steps/test-fix-loop', () => ({
12
+ testFixLoop: vi.fn(async () => ({ success: true })),
13
+ }));
14
+ vi.mock('./steps/lint-fix-loop', () => ({
15
+ lintFixLoop: vi.fn(async () => ({ success: true })),
16
+ }));
17
+ vi.mock('./steps/generate-story', () => ({
18
+ generateStoryStep: vi.fn(async () => ({ success: true })),
19
+ }));
20
+ vi.mock('./steps/story-fix-loop', () => ({
21
+ storyFixLoop: vi.fn(async () => ({ success: true })),
22
+ }));
23
+ vi.mock('./steps/storybook-test', () => ({
24
+ storybookTestStep: vi.fn(async () => ({ success: true })),
25
+ }));
26
+ vi.mock('./steps/visual-test', () => ({
27
+ visualTestStep: vi.fn(async () => ({ success: true })),
28
+ }));
29
+ import { buildPipelineSteps, runPipeline, } from './run-pipeline.js';
30
+ import { generateComponentStep } from './steps/generate-component.js';
31
+ import { generateStoryStep } from './steps/generate-story.js';
32
+ import { generateTestStep } from './steps/generate-test.js';
33
+ import { lintFixLoop } from './steps/lint-fix-loop.js';
34
+ import { storyFixLoop } from './steps/story-fix-loop.js';
35
+ import { storybookTestStep } from './steps/storybook-test.js';
36
+ import { testFixLoop } from './steps/test-fix-loop.js';
37
+ import { typeFixLoop } from './steps/type-fix-loop.js';
38
+ import { visualTestStep } from './steps/visual-test.js';
39
+ afterEach(() => {
40
+ vi.clearAllMocks();
41
+ });
42
+ function makeCtx(overrides = {}) {
43
+ return {
44
+ componentName: 'MyButton',
45
+ componentPath: '/project/src/MyButton.tsx',
46
+ testPath: '/project/src/MyButton.test.tsx',
47
+ storyPath: '/project/src/MyButton.stories.tsx',
48
+ componentImportPath: '@/components/ui/MyButton',
49
+ targetDir: '/project',
50
+ specDeltas: { structure: [], rendering: [], interaction: [], styling: [] },
51
+ projectSection: '',
52
+ composes: [],
53
+ isModify: false,
54
+ llmCalls: 0,
55
+ fixIterations: 0,
56
+ ...overrides,
57
+ };
58
+ }
59
+ function successStep(name) {
60
+ return { name, run: async () => ({ success: true }) };
61
+ }
62
+ function failStep(name, error) {
63
+ return { name, run: async () => ({ success: false, error }) };
64
+ }
65
+ describe('runPipeline', () => {
66
+ it('runs all steps in sequence and returns success', async () => {
67
+ const executionOrder = [];
68
+ const steps = [
69
+ {
70
+ name: 'Step A',
71
+ run: async () => {
72
+ executionOrder.push('A');
73
+ return { success: true };
74
+ },
75
+ },
76
+ {
77
+ name: 'Step B',
78
+ run: async () => {
79
+ executionOrder.push('B');
80
+ return { success: true };
81
+ },
82
+ },
83
+ {
84
+ name: 'Step C',
85
+ run: async () => {
86
+ executionOrder.push('C');
87
+ return { success: true };
88
+ },
89
+ },
90
+ ];
91
+ const result = await runPipeline(steps, makeCtx());
92
+ expect(result).toEqual({ success: true, llmCalls: 0, fixIterations: 0 });
93
+ expect(executionOrder).toEqual(['A', 'B', 'C']);
94
+ });
95
+ it('stops at first failing step and returns failure', async () => {
96
+ const executionOrder = [];
97
+ const steps = [
98
+ {
99
+ name: 'Step A',
100
+ run: async () => {
101
+ executionOrder.push('A');
102
+ return { success: true };
103
+ },
104
+ },
105
+ failStep('Step B', 'something broke'),
106
+ {
107
+ name: 'Step C',
108
+ run: async () => {
109
+ executionOrder.push('C');
110
+ return { success: true };
111
+ },
112
+ },
113
+ ];
114
+ const result = await runPipeline(steps, makeCtx());
115
+ expect(result).toEqual({
116
+ success: false,
117
+ error: 'Step "Step B" failed: something broke',
118
+ llmCalls: 0,
119
+ fixIterations: 0,
120
+ });
121
+ expect(executionOrder).toEqual(['A']);
122
+ });
123
+ it('returns success with empty steps', async () => {
124
+ const result = await runPipeline([], makeCtx());
125
+ expect(result).toEqual({ success: true, llmCalls: 0, fixIterations: 0 });
126
+ });
127
+ it('reports accumulated llmCalls and fixIterations from context', async () => {
128
+ const steps = [{ name: 'Step A', run: async () => ({ success: true }) }];
129
+ const ctx = makeCtx({ llmCalls: 5, fixIterations: 3 });
130
+ const result = await runPipeline(steps, ctx);
131
+ expect(result).toEqual({ success: true, llmCalls: 5, fixIterations: 3 });
132
+ });
133
+ it('reports context metrics on failure', async () => {
134
+ const steps = [failStep('Broken', 'oops')];
135
+ const ctx = makeCtx({ llmCalls: 2, fixIterations: 1 });
136
+ const result = await runPipeline(steps, ctx);
137
+ expect(result).toEqual({
138
+ success: false,
139
+ error: 'Step "Broken" failed: oops',
140
+ llmCalls: 2,
141
+ fixIterations: 1,
142
+ });
143
+ });
144
+ });
145
+ const fakeModel = {};
146
+ function makeModels() {
147
+ return {
148
+ generateTest: fakeModel,
149
+ generateComponent: fakeModel,
150
+ typeFixer: fakeModel,
151
+ testFixer: fakeModel,
152
+ lintFixer: fakeModel,
153
+ storyFixer: fakeModel,
154
+ };
155
+ }
156
+ function makeConfig(overrides = {}) {
157
+ return {
158
+ models: {
159
+ generateTest: '',
160
+ generateComponent: '',
161
+ typeFixer: '',
162
+ testFixer: '',
163
+ lintFixer: '',
164
+ storyFixer: '',
165
+ },
166
+ maxTypeFixIterations: 3,
167
+ maxTestFixIterations: 3,
168
+ maxLintFixIterations: 2,
169
+ maxStoryFixIterations: 2,
170
+ enableStorybookTest: false,
171
+ enableVisualTest: false,
172
+ ...overrides,
173
+ };
174
+ }
175
+ describe('buildPipelineSteps', () => {
176
+ it('returns 7 core steps by default', () => {
177
+ const steps = buildPipelineSteps(makeModels(), makeConfig(), makeCtx());
178
+ expect(steps.map((s) => s.name)).toEqual([
179
+ 'Generate Test',
180
+ 'Generate Component',
181
+ 'Type Fix Loop',
182
+ 'Test Fix Loop',
183
+ 'Lint Fix Loop',
184
+ 'Generate Story',
185
+ 'Story Fix Loop',
186
+ ]);
187
+ });
188
+ it('adds Storybook Test step when enabled', () => {
189
+ const steps = buildPipelineSteps(makeModels(), makeConfig({ enableStorybookTest: true }), makeCtx());
190
+ expect(steps.map((s) => s.name)).toEqual([
191
+ 'Generate Test',
192
+ 'Generate Component',
193
+ 'Type Fix Loop',
194
+ 'Test Fix Loop',
195
+ 'Lint Fix Loop',
196
+ 'Generate Story',
197
+ 'Story Fix Loop',
198
+ 'Storybook Test',
199
+ ]);
200
+ });
201
+ it('adds Visual Test step when enabled', () => {
202
+ const steps = buildPipelineSteps(makeModels(), makeConfig({ enableVisualTest: true }), makeCtx());
203
+ expect(steps.map((s) => s.name)).toEqual([
204
+ 'Generate Test',
205
+ 'Generate Component',
206
+ 'Type Fix Loop',
207
+ 'Test Fix Loop',
208
+ 'Lint Fix Loop',
209
+ 'Generate Story',
210
+ 'Story Fix Loop',
211
+ 'Visual Test',
212
+ ]);
213
+ });
214
+ it('adds both optional steps when both enabled', () => {
215
+ const steps = buildPipelineSteps(makeModels(), makeConfig({ enableStorybookTest: true, enableVisualTest: true }), makeCtx());
216
+ expect(steps.map((s) => s.name)).toEqual([
217
+ 'Generate Test',
218
+ 'Generate Component',
219
+ 'Type Fix Loop',
220
+ 'Test Fix Loop',
221
+ 'Lint Fix Loop',
222
+ 'Generate Story',
223
+ 'Story Fix Loop',
224
+ 'Storybook Test',
225
+ 'Visual Test',
226
+ ]);
227
+ });
228
+ it('wires each step to its corresponding function', async () => {
229
+ const models = makeModels();
230
+ const config = makeConfig({ enableStorybookTest: true, enableVisualTest: true });
231
+ const ctx = makeCtx();
232
+ const steps = buildPipelineSteps(models, config, ctx);
233
+ for (const step of steps) {
234
+ await step.run();
235
+ }
236
+ expect(generateTestStep).toHaveBeenCalledWith(models.generateTest, ctx);
237
+ expect(generateComponentStep).toHaveBeenCalledWith(models.generateComponent, ctx);
238
+ expect(typeFixLoop).toHaveBeenCalledWith(models.typeFixer, ctx, 3);
239
+ expect(testFixLoop).toHaveBeenCalledWith(models.testFixer, ctx, 3);
240
+ expect(lintFixLoop).toHaveBeenCalledWith(models.lintFixer, ctx, 2);
241
+ expect(generateStoryStep).toHaveBeenCalledWith(ctx);
242
+ expect(storyFixLoop).toHaveBeenCalledWith(models.storyFixer, ctx, 2);
243
+ expect(storybookTestStep).toHaveBeenCalledWith(ctx, true);
244
+ expect(visualTestStep).toHaveBeenCalled();
245
+ });
246
+ });
247
+ //# sourceMappingURL=run-pipeline.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-pipeline.test.js","sourceRoot":"","sources":["../../../src/pipeline/run-pipeline.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { LanguageModel } from 'ai';
2
+ import type { PipelineContext, StepResult } from '../run-pipeline';
3
+ export declare function generateComponentStep(model: LanguageModel, ctx: PipelineContext): Promise<StepResult>;
4
+ //# sourceMappingURL=generate-component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-component.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-component.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAMxC,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnE,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAiD3G"}
@@ -0,0 +1,50 @@
1
+ import { readFile, writeFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { generateText } from 'ai';
4
+ import { extractCodeBlock } from '../../extract-code-block.js';
5
+ import { extractExportedNames } from '../../extract-exports.js';
6
+ import { buildComponentPrompt } from '../../prompt.js';
7
+ import { generateScaffold } from '../../scaffold.js';
8
+ export async function generateComponentStep(model, ctx) {
9
+ const resolvedComposes = await Promise.all(ctx.composes.map(async (c) => {
10
+ const candidates = [
11
+ path.join(ctx.targetDir, c.path),
12
+ path.join(ctx.targetDir, `${c.path}.tsx`),
13
+ path.join(ctx.targetDir, `${c.path}.ts`),
14
+ ];
15
+ for (const candidate of candidates) {
16
+ try {
17
+ const content = await readFile(candidate, 'utf-8');
18
+ const exports = extractExportedNames(content);
19
+ return { ...c, exports };
20
+ }
21
+ catch { }
22
+ }
23
+ return c;
24
+ }));
25
+ let scaffoldSection = '';
26
+ if (ctx.props && ctx.props.length > 0) {
27
+ const scaffold = generateScaffold({
28
+ componentName: ctx.componentName,
29
+ props: ctx.props.map((p) => ({ ...p, category: p.category })),
30
+ composes: resolvedComposes,
31
+ specDeltas: ctx.specDeltas,
32
+ });
33
+ scaffoldSection = `\n\n## Component Scaffold\n\n\`\`\`tsx\n${scaffold.scaffoldedFile}\n\`\`\`\n\nUse the props type exactly as shown. Replace \`__BODY__\` with the full component body.`;
34
+ }
35
+ const { system, prompt: basePrompt } = buildComponentPrompt({
36
+ componentName: ctx.componentName,
37
+ specDeltas: ctx.specDeltas,
38
+ existingComponent: ctx.existingComponent,
39
+ projectSection: ctx.projectSection,
40
+ testCode: ctx.testCode,
41
+ });
42
+ const prompt = scaffoldSection ? basePrompt + scaffoldSection : basePrompt;
43
+ const { text } = await generateText({ model, system, prompt });
44
+ ctx.llmCalls++;
45
+ const componentCode = extractCodeBlock(text);
46
+ ctx.componentCode = componentCode;
47
+ await writeFile(ctx.componentPath, componentCode, 'utf-8');
48
+ return { success: true };
49
+ }
50
+ //# sourceMappingURL=generate-component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-component.js","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-component.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-component.test.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-component.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,106 @@
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
+ import { readFile, writeFile } from 'node:fs/promises';
10
+ import { generateText } from 'ai';
11
+ import { generateComponentStep } from './generate-component.js';
12
+ afterEach(() => {
13
+ vi.clearAllMocks();
14
+ });
15
+ function makeCtx(overrides = {}) {
16
+ return {
17
+ componentName: 'MyButton',
18
+ componentPath: '/project/src/MyButton.tsx',
19
+ testPath: '/project/src/MyButton.test.tsx',
20
+ storyPath: '/project/src/MyButton.stories.tsx',
21
+ componentImportPath: '@/components/ui/MyButton',
22
+ targetDir: '/project',
23
+ specDeltas: {
24
+ structure: ['renders a button'],
25
+ rendering: [],
26
+ interaction: [],
27
+ styling: [],
28
+ },
29
+ projectSection: '',
30
+ composes: [],
31
+ isModify: false,
32
+ llmCalls: 0,
33
+ fixIterations: 0,
34
+ testCode: 'import { render } from "@testing-library/react";',
35
+ ...overrides,
36
+ };
37
+ }
38
+ describe('generateComponentStep', () => {
39
+ it('generates component code and writes to componentPath', async () => {
40
+ vi.mocked(generateText).mockResolvedValue({
41
+ text: '```tsx\nexport function MyButton() { return <button>Click</button> }\n```',
42
+ });
43
+ vi.mocked(writeFile).mockResolvedValue(undefined);
44
+ const ctx = makeCtx();
45
+ const result = await generateComponentStep('mock-model', ctx);
46
+ expect(result).toEqual({ success: true });
47
+ expect(generateText).toHaveBeenCalledTimes(1);
48
+ expect(writeFile).toHaveBeenCalledWith('/project/src/MyButton.tsx', 'export function MyButton() { return <button>Click</button> }', 'utf-8');
49
+ });
50
+ it('includes test code in prompt when available', async () => {
51
+ vi.mocked(generateText).mockResolvedValue({
52
+ text: 'component code',
53
+ });
54
+ vi.mocked(writeFile).mockResolvedValue(undefined);
55
+ const ctx = makeCtx({ testCode: 'test source code' });
56
+ await generateComponentStep('mock-model', ctx);
57
+ const call = vi.mocked(generateText).mock.calls[0][0];
58
+ expect(call.prompt).toContain('## Test File');
59
+ expect(call.prompt).toContain('test source code');
60
+ });
61
+ it('resolves composed component exports and falls back on missing files', async () => {
62
+ vi.mocked(readFile).mockRejectedValue(new Error('ENOENT'));
63
+ vi.mocked(generateText).mockResolvedValue({
64
+ text: 'component code',
65
+ });
66
+ vi.mocked(writeFile).mockResolvedValue(undefined);
67
+ const ctx = makeCtx({
68
+ composes: [{ id: 'card', path: 'src/components/Card' }],
69
+ });
70
+ const result = await generateComponentStep('mock-model', ctx);
71
+ expect(result).toEqual({ success: true });
72
+ });
73
+ it('resolves composed component exports when file exists', async () => {
74
+ vi.mocked(readFile).mockResolvedValue('export function Card() {}');
75
+ vi.mocked(generateText).mockResolvedValue({
76
+ text: 'component code',
77
+ });
78
+ vi.mocked(writeFile).mockResolvedValue(undefined);
79
+ const ctx = makeCtx({
80
+ composes: [{ id: 'card', path: 'src/components/Card' }],
81
+ });
82
+ await generateComponentStep('mock-model', ctx);
83
+ expect(readFile).toHaveBeenCalled();
84
+ });
85
+ it('generates scaffold section when props are provided', async () => {
86
+ vi.mocked(generateText).mockResolvedValue({
87
+ text: 'component with scaffold',
88
+ });
89
+ vi.mocked(writeFile).mockResolvedValue(undefined);
90
+ const ctx = makeCtx({
91
+ props: [
92
+ {
93
+ name: 'label',
94
+ type: 'string',
95
+ required: true,
96
+ description: 'Button label',
97
+ category: 'data',
98
+ },
99
+ ],
100
+ });
101
+ await generateComponentStep('mock-model', ctx);
102
+ const call = vi.mocked(generateText).mock.calls[0][0];
103
+ expect(call.prompt).toContain('## Component Scaffold');
104
+ });
105
+ });
106
+ //# sourceMappingURL=generate-component.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-component.test.js","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-component.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { PipelineContext, StepResult } from '../run-pipeline';
2
+ export declare function generateStoryStep(ctx: PipelineContext): Promise<StepResult>;
3
+ //# sourceMappingURL=generate-story.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-story.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-story.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnE,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAYjF"}
@@ -0,0 +1,14 @@
1
+ import { writeFile } from 'node:fs/promises';
2
+ import { generateStoryDeterministic } from '../../generate-story-deterministic.js';
3
+ export async function generateStoryStep(ctx) {
4
+ const storyCode = generateStoryDeterministic({
5
+ componentName: ctx.componentName,
6
+ componentImportPath: ctx.componentImportPath,
7
+ props: ctx.props,
8
+ storyVariants: ctx.storyVariants,
9
+ });
10
+ ctx.storyCode = storyCode;
11
+ await writeFile(ctx.storyPath, storyCode, 'utf-8');
12
+ return { success: true };
13
+ }
14
+ //# sourceMappingURL=generate-story.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-story.js","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-story.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAGhF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAoB;IAC1D,MAAM,SAAS,GAAG,0BAA0B,CAAC;QAC3C,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;QAC5C,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,aAAa,EAAE,GAAG,CAAC,aAAa;KACjC,CAAC,CAAC;IAEH,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;IAC1B,MAAM,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAEnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-story.test.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-story.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ vi.mock('node:fs/promises', () => ({
3
+ writeFile: vi.fn(),
4
+ }));
5
+ import { writeFile } from 'node:fs/promises';
6
+ import { generateStoryStep } from './generate-story.js';
7
+ function makeCtx(overrides = {}) {
8
+ return {
9
+ componentName: 'MyButton',
10
+ componentPath: '/project/src/MyButton.tsx',
11
+ testPath: '/project/src/MyButton.test.tsx',
12
+ storyPath: '/project/src/MyButton.stories.tsx',
13
+ componentImportPath: '@/components/ui/MyButton',
14
+ targetDir: '/project',
15
+ specDeltas: { structure: [], rendering: [], interaction: [], styling: [] },
16
+ projectSection: '',
17
+ composes: [],
18
+ isModify: false,
19
+ llmCalls: 0,
20
+ fixIterations: 0,
21
+ ...overrides,
22
+ };
23
+ }
24
+ describe('generateStoryStep', () => {
25
+ it('generates story deterministically and writes to storyPath', async () => {
26
+ vi.mocked(writeFile).mockResolvedValue(undefined);
27
+ const ctx = makeCtx();
28
+ const result = await generateStoryStep(ctx);
29
+ expect(result).toEqual({ success: true });
30
+ expect(ctx.storyCode).toContain('export default meta');
31
+ expect(ctx.storyCode).toContain('MyButton');
32
+ expect(writeFile).toHaveBeenCalledWith('/project/src/MyButton.stories.tsx', expect.stringContaining('export default meta'), 'utf-8');
33
+ });
34
+ it('does not increment llmCalls since no LLM is used', async () => {
35
+ vi.mocked(writeFile).mockResolvedValue(undefined);
36
+ const ctx = makeCtx();
37
+ await generateStoryStep(ctx);
38
+ expect(ctx.llmCalls).toBe(0);
39
+ });
40
+ });
41
+ //# sourceMappingURL=generate-story.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-story.test.js","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-story.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAElD,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC;IACjC,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE;CACnB,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,SAAS,OAAO,CAAC,YAAsC,EAAE;IACvD,OAAO;QACL,aAAa,EAAE,UAAU;QACzB,aAAa,EAAE,2BAA2B;QAC1C,QAAQ,EAAE,gCAAgC;QAC1C,SAAS,EAAE,mCAAmC;QAC9C,mBAAmB,EAAE,0BAA0B;QAC/C,SAAS,EAAE,UAAU;QACrB,UAAU,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QAC1E,cAAc,EAAE,EAAE;QAClB,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,CAAC;QACX,aAAa,EAAE,CAAC;QAChB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAElD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAE5C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QACvD,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CACpC,mCAAmC,EACnC,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,EAC9C,OAAO,CACR,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAElD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAE7B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { LanguageModel } from 'ai';
2
+ import type { PipelineContext, StepResult } from '../run-pipeline';
3
+ export declare function generateTestStep(model: LanguageModel, ctx: PipelineContext): Promise<StepResult>;
4
+ //# sourceMappingURL=generate-test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-test.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-test.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAIxC,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnE,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAiBtG"}
@@ -0,0 +1,19 @@
1
+ import { writeFile } from 'node:fs/promises';
2
+ import { generateText } from 'ai';
3
+ import { extractCodeBlock } from '../../extract-code-block.js';
4
+ import { buildTestPrompt } from '../../prompt.js';
5
+ export async function generateTestStep(model, ctx) {
6
+ const { system, prompt } = buildTestPrompt({
7
+ componentName: ctx.componentName,
8
+ specDeltas: ctx.specDeltas,
9
+ existingComponent: ctx.existingComponent,
10
+ projectSection: ctx.projectSection,
11
+ });
12
+ const { text } = await generateText({ model, system, prompt });
13
+ ctx.llmCalls++;
14
+ const testCode = extractCodeBlock(text);
15
+ ctx.testCode = testCode;
16
+ await writeFile(ctx.testPath, testCode, 'utf-8');
17
+ return { success: true };
18
+ }
19
+ //# sourceMappingURL=generate-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-test.js","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAoB,EAAE,GAAoB;IAC/E,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC;QACzC,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;QACxC,cAAc,EAAE,GAAG,CAAC,cAAc;KACnC,CAAC,CAAC;IAEH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/D,GAAG,CAAC,QAAQ,EAAE,CAAC;IAEf,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACxC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAExB,MAAM,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEjD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-test.test.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-test.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,60 @@
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
+ writeFile: vi.fn(),
7
+ }));
8
+ import { writeFile } from 'node:fs/promises';
9
+ import { generateText } from 'ai';
10
+ import { generateTestStep } from './generate-test.js';
11
+ afterEach(() => {
12
+ vi.clearAllMocks();
13
+ });
14
+ function makeCtx(overrides = {}) {
15
+ return {
16
+ componentName: 'MyButton',
17
+ componentPath: '/project/src/MyButton.tsx',
18
+ testPath: '/project/src/MyButton.test.tsx',
19
+ storyPath: '/project/src/MyButton.stories.tsx',
20
+ componentImportPath: '@/components/ui/MyButton',
21
+ targetDir: '/project',
22
+ specDeltas: {
23
+ structure: ['renders a button'],
24
+ rendering: [],
25
+ interaction: [],
26
+ styling: [],
27
+ },
28
+ projectSection: '',
29
+ composes: [],
30
+ isModify: false,
31
+ llmCalls: 0,
32
+ fixIterations: 0,
33
+ ...overrides,
34
+ };
35
+ }
36
+ describe('generateTestStep', () => {
37
+ it('generates test code and writes to testPath', async () => {
38
+ vi.mocked(generateText).mockResolvedValue({
39
+ text: '```tsx\nimport { render } from "@testing-library/react";\n```',
40
+ });
41
+ vi.mocked(writeFile).mockResolvedValue(undefined);
42
+ const ctx = makeCtx();
43
+ const result = await generateTestStep('mock-model', ctx);
44
+ expect(result).toEqual({ success: true });
45
+ expect(generateText).toHaveBeenCalledTimes(1);
46
+ expect(writeFile).toHaveBeenCalledWith('/project/src/MyButton.test.tsx', 'import { render } from "@testing-library/react";', 'utf-8');
47
+ });
48
+ it('passes existing component to prompt when in modify mode', async () => {
49
+ vi.mocked(generateText).mockResolvedValue({
50
+ text: 'test code',
51
+ });
52
+ vi.mocked(writeFile).mockResolvedValue(undefined);
53
+ const ctx = makeCtx({ existingComponent: 'export function MyButton() {}', isModify: true });
54
+ await generateTestStep('mock-model', ctx);
55
+ const call = vi.mocked(generateText).mock.calls[0][0];
56
+ expect(call.prompt).toContain('## Existing Component');
57
+ expect(call.prompt).toContain('export function MyButton() {}');
58
+ });
59
+ });
60
+ //# sourceMappingURL=generate-test.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-test.test.js","sourceRoot":"","sources":["../../../../src/pipeline/steps/generate-test.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
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