@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
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-story.test.js","sourceRoot":"","sources":["../../src/generate-story.test.ts"],"names":[],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- import { type TestPromptInput } from './prompt';
2
- export type GenerateTestInput = TestPromptInput;
3
- export declare function generateTestFile(input: GenerateTestInput): Promise<string>;
4
- //# sourceMappingURL=generate-test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-test.d.ts","sourceRoot":"","sources":["../../src/generate-test.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAEjE,MAAM,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAEhD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAQhF"}
@@ -1,14 +0,0 @@
1
- import { createModelFromEnv } from '@auto-engineer/model-factory';
2
- import { generateText } from 'ai';
3
- import { extractCodeBlock } from './extract-code-block.js';
4
- import { buildTestPrompt } from './prompt.js';
5
- export async function generateTestFile(input) {
6
- const { system, prompt } = buildTestPrompt(input);
7
- const { text } = await generateText({
8
- model: createModelFromEnv(),
9
- system,
10
- prompt,
11
- });
12
- return extractCodeBlock(text);
13
- }
14
- //# sourceMappingURL=generate-test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-test.js","sourceRoot":"","sources":["../../src/generate-test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAwB,MAAM,UAAU,CAAC;AAIjE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAwB;IAC7D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,CAAC;QAClC,KAAK,EAAE,kBAAkB,EAAE;QAC3B,MAAM;QACN,MAAM;KACP,CAAC,CAAC;IACH,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-test.test.d.ts","sourceRoot":"","sources":["../../src/generate-test.test.ts"],"names":[],"mappings":""}
@@ -1,77 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
- import { generateTestFile } from './generate-test.js';
3
- vi.mock('ai', () => ({
4
- generateText: vi.fn(),
5
- }));
6
- vi.mock('@auto-engineer/model-factory', () => ({
7
- createModelFromEnv: vi.fn(() => 'mock-model'),
8
- }));
9
- import { generateText } from 'ai';
10
- const specDeltas = {
11
- structure: ['renders a Button element', 'accepts children prop'],
12
- rendering: ['shows loading spinner when loading=true'],
13
- interaction: ['calls onClick when clicked'],
14
- styling: ['applies primary variant by default'],
15
- };
16
- describe('generateTestFile', () => {
17
- afterEach(() => {
18
- vi.clearAllMocks();
19
- });
20
- it('returns generated test code from AI', async () => {
21
- const mockGenerateText = vi.mocked(generateText);
22
- mockGenerateText.mockResolvedValue({
23
- text: '```tsx\nimport { render } from "@testing-library/react";\n```',
24
- });
25
- const result = await generateTestFile({
26
- componentName: 'Button',
27
- specDeltas,
28
- });
29
- expect(result).toBe('import { render } from "@testing-library/react";');
30
- });
31
- it('passes system prompt with methodology, rules, and checklist', async () => {
32
- const mockGenerateText = vi.mocked(generateText);
33
- mockGenerateText.mockResolvedValue({
34
- text: 'test code',
35
- });
36
- await generateTestFile({ componentName: 'Button', specDeltas });
37
- const system = mockGenerateText.mock.calls[0][0].system;
38
- expect(system).toContain('senior frontend engineer who specializes in testing');
39
- expect(system).toContain('METHODOLOGY');
40
- expect(system).toContain('RULES');
41
- expect(system).toContain('QUALITY CHECKLIST');
42
- expect(system).toContain('Semantic queries first');
43
- expect(system).toContain('source of truth');
44
- });
45
- it('includes all spec delta sections in the user prompt', async () => {
46
- const mockGenerateText = vi.mocked(generateText);
47
- mockGenerateText.mockResolvedValue({
48
- text: 'test code',
49
- });
50
- await generateTestFile({ componentName: 'Button', specDeltas });
51
- const prompt = mockGenerateText.mock.calls[0][0].prompt;
52
- expect(prompt).toContain('## Spec Deltas');
53
- expect(prompt).toContain('## Structure');
54
- expect(prompt).toContain('renders a Button element');
55
- expect(prompt).toContain('## Rendering');
56
- expect(prompt).toContain('shows loading spinner when loading=true');
57
- expect(prompt).toContain('## Interaction');
58
- expect(prompt).toContain('calls onClick when clicked');
59
- expect(prompt).toContain('## Styling');
60
- expect(prompt).toContain('applies primary variant by default');
61
- });
62
- it('includes existing component code as context when provided', async () => {
63
- const mockGenerateText = vi.mocked(generateText);
64
- mockGenerateText.mockResolvedValue({
65
- text: 'test code',
66
- });
67
- await generateTestFile({
68
- componentName: 'Button',
69
- specDeltas,
70
- existingComponent: 'export function Button() { return <button />; }',
71
- });
72
- const prompt = mockGenerateText.mock.calls[0][0].prompt;
73
- expect(prompt).toContain('## Existing Component');
74
- expect(prompt).toContain('export function Button() { return <button />; }');
75
- });
76
- });
77
- //# sourceMappingURL=generate-test.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-test.test.js","sourceRoot":"","sources":["../../src/generate-test.test.ts"],"names":[],"mappings":"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"}
@@ -1,8 +0,0 @@
1
- import { type ReconcilerPromptInput } from './prompt';
2
- export type ReconcileInput = ReconcilerPromptInput;
3
- export type ReconcileOutput = {
4
- componentCode: string;
5
- storyCode: string;
6
- };
7
- export declare function reconcile(input: ReconcileInput): Promise<ReconcileOutput>;
8
- //# sourceMappingURL=reconcile.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/reconcile.ts"],"names":[],"mappings":"AAGA,OAAO,EAAyB,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAE7E,MAAM,MAAM,cAAc,GAAG,qBAAqB,CAAC;AAEnD,MAAM,MAAM,eAAe,GAAG;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAsB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAc/E"}
@@ -1,18 +0,0 @@
1
- import { createModelFromEnv } from '@auto-engineer/model-factory';
2
- import { generateText } from 'ai';
3
- import { extractCodeBlocks } from './extract-code-block.js';
4
- import { buildReconcilerPrompt } from './prompt.js';
5
- export async function reconcile(input) {
6
- const { system, prompt } = buildReconcilerPrompt(input);
7
- const { text } = await generateText({
8
- model: createModelFromEnv(),
9
- system,
10
- prompt,
11
- });
12
- const blocks = extractCodeBlocks(text);
13
- return {
14
- componentCode: blocks[0] ?? input.componentCode,
15
- storyCode: blocks[1] ?? input.storyCode,
16
- };
17
- }
18
- //# sourceMappingURL=reconcile.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAA8B,MAAM,UAAU,CAAC;AAS7E,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAqB;IACnD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,CAAC;QAClC,KAAK,EAAE,kBAAkB,EAAE;QAC3B,MAAM;QACN,MAAM;KACP,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAEvC,OAAO;QACL,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,aAAa;QAC/C,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS;KACxC,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=reconcile.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reconcile.test.d.ts","sourceRoot":"","sources":["../../src/reconcile.test.ts"],"names":[],"mappings":""}
@@ -1,108 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
- import { reconcile } from './reconcile.js';
3
- vi.mock('ai', () => ({
4
- generateText: vi.fn(),
5
- }));
6
- vi.mock('@auto-engineer/model-factory', () => ({
7
- createModelFromEnv: vi.fn(() => 'mock-model'),
8
- }));
9
- import { generateText } from 'ai';
10
- const specDeltas = {
11
- structure: ['renders a Button element'],
12
- rendering: ['shows loading spinner when loading=true'],
13
- interaction: ['calls onClick when clicked'],
14
- styling: ['applies primary variant by default'],
15
- };
16
- describe('reconcile', () => {
17
- afterEach(() => {
18
- vi.clearAllMocks();
19
- });
20
- it('passes system prompt with methodology, rules, and checklist', async () => {
21
- const mockGenerateText = vi.mocked(generateText);
22
- mockGenerateText.mockResolvedValue({
23
- text: '```tsx\nc\n```\n```tsx\ns\n```',
24
- });
25
- await reconcile({
26
- componentName: 'Button',
27
- specDeltas,
28
- componentCode: 'c',
29
- testCode: 't',
30
- storyCode: 's',
31
- });
32
- const system = mockGenerateText.mock.calls[0][0].system;
33
- expect(system).toContain('staff frontend engineer');
34
- expect(system).toContain('integration review');
35
- expect(system).toContain('METHODOLOGY');
36
- expect(system).toContain('RULES');
37
- expect(system).toContain('QUALITY CHECKLIST');
38
- expect(system).toContain('Tests are immutable');
39
- });
40
- it('sends component, test, and story code in the user prompt', async () => {
41
- const mockGenerateText = vi.mocked(generateText);
42
- mockGenerateText.mockResolvedValue({
43
- text: '```tsx\nfixed component\n```\n\n```tsx\nfixed story\n```',
44
- });
45
- await reconcile({
46
- componentName: 'Button',
47
- specDeltas,
48
- componentCode: 'original component',
49
- testCode: 'test code here',
50
- storyCode: 'original story',
51
- });
52
- const prompt = mockGenerateText.mock.calls[0][0].prompt;
53
- expect(prompt).toContain('## Component Code');
54
- expect(prompt).toContain('original component');
55
- expect(prompt).toContain('## Test File (source of truth');
56
- expect(prompt).toContain('test code here');
57
- expect(prompt).toContain('## Story File');
58
- expect(prompt).toContain('original story');
59
- });
60
- it('parses two code blocks and returns component + story', async () => {
61
- const mockGenerateText = vi.mocked(generateText);
62
- mockGenerateText.mockResolvedValue({
63
- text: '```tsx\nfixed component code\n```\n\n```tsx\nfixed story code\n```',
64
- });
65
- const result = await reconcile({
66
- componentName: 'Button',
67
- specDeltas,
68
- componentCode: 'original component',
69
- testCode: 'test code',
70
- storyCode: 'original story',
71
- });
72
- expect(result.componentCode).toBe('fixed component code');
73
- expect(result.storyCode).toBe('fixed story code');
74
- });
75
- it('falls back to original code when blocks are missing', async () => {
76
- const mockGenerateText = vi.mocked(generateText);
77
- mockGenerateText.mockResolvedValue({
78
- text: 'no code blocks at all',
79
- });
80
- const result = await reconcile({
81
- componentName: 'Button',
82
- specDeltas,
83
- componentCode: 'original component',
84
- testCode: 'test code',
85
- storyCode: 'original story',
86
- });
87
- expect(result.componentCode).toBe('no code blocks at all');
88
- expect(result.storyCode).toBe('original story');
89
- });
90
- it('includes existing component in prompt when provided', async () => {
91
- const mockGenerateText = vi.mocked(generateText);
92
- mockGenerateText.mockResolvedValue({
93
- text: '```tsx\nfixed\n```\n```tsx\nstory\n```',
94
- });
95
- await reconcile({
96
- componentName: 'Button',
97
- specDeltas,
98
- componentCode: 'new component',
99
- testCode: 'test code',
100
- storyCode: 'story code',
101
- existingComponent: 'old component',
102
- });
103
- const prompt = mockGenerateText.mock.calls[0][0].prompt;
104
- expect(prompt).toContain('## Existing Component');
105
- expect(prompt).toContain('old component');
106
- });
107
- });
108
- //# sourceMappingURL=reconcile.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reconcile.test.js","sourceRoot":"","sources":["../../src/reconcile.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACnB,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE;CACtB,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,8BAA8B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7C,kBAAkB,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC;CAC9C,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAElC,MAAM,UAAU,GAAG;IACjB,SAAS,EAAE,CAAC,0BAA0B,CAAC;IACvC,SAAS,EAAE,CAAC,yCAAyC,CAAC;IACtD,WAAW,EAAE,CAAC,4BAA4B,CAAC;IAC3C,OAAO,EAAE,CAAC,oCAAoC,CAAC;CAChD,CAAC;AAEF,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,gBAAgB,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACjD,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,IAAI,EAAE,gCAAgC;SACK,CAAC,CAAC;QAE/C,MAAM,SAAS,CAAC;YACd,aAAa,EAAE,QAAQ;YACvB,UAAU;YACV,aAAa,EAAE,GAAG;YAClB,QAAQ,EAAE,GAAG;YACb,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAgB,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,gBAAgB,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACjD,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,IAAI,EAAE,0DAA0D;SACrB,CAAC,CAAC;QAE/C,MAAM,SAAS,CAAC;YACd,aAAa,EAAE,QAAQ;YACvB,UAAU;YACV,aAAa,EAAE,oBAAoB;YACnC,QAAQ,EAAE,gBAAgB;YAC1B,SAAS,EAAE,gBAAgB;SAC5B,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAgB,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,gBAAgB,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACjD,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,IAAI,EAAE,oEAAoE;SAC/B,CAAC,CAAC;QAE/C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;YAC7B,aAAa,EAAE,QAAQ;YACvB,UAAU;YACV,aAAa,EAAE,oBAAoB;YACnC,QAAQ,EAAE,WAAW;YACrB,SAAS,EAAE,gBAAgB;SAC5B,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,gBAAgB,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACjD,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,IAAI,EAAE,uBAAuB;SACc,CAAC,CAAC;QAE/C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;YAC7B,aAAa,EAAE,QAAQ;YACvB,UAAU;YACV,aAAa,EAAE,oBAAoB;YACnC,QAAQ,EAAE,WAAW;YACrB,SAAS,EAAE,gBAAgB;SAC5B,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,gBAAgB,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACjD,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,IAAI,EAAE,wCAAwC;SACH,CAAC,CAAC;QAE/C,MAAM,SAAS,CAAC;YACd,aAAa,EAAE,QAAQ;YACvB,UAAU;YACV,aAAa,EAAE,eAAe;YAC9B,QAAQ,EAAE,WAAW;YACrB,SAAS,EAAE,YAAY;YACvB,iBAAiB,EAAE,eAAe;SACnC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAgB,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,89 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
- import { generateComponentFile } from './generate-component';
3
-
4
- vi.mock('ai', () => ({
5
- generateText: vi.fn(),
6
- }));
7
-
8
- vi.mock('@auto-engineer/model-factory', () => ({
9
- createModelFromEnv: vi.fn(() => 'mock-model'),
10
- }));
11
-
12
- import { generateText } from 'ai';
13
-
14
- const specDeltas = {
15
- structure: ['renders a Button element'],
16
- rendering: ['shows loading spinner when loading=true'],
17
- interaction: ['calls onClick when clicked'],
18
- styling: ['applies primary variant by default'],
19
- };
20
-
21
- describe('generateComponentFile', () => {
22
- afterEach(() => {
23
- vi.clearAllMocks();
24
- });
25
-
26
- it('returns generated component code from AI', async () => {
27
- const mockGenerateText = vi.mocked(generateText);
28
- mockGenerateText.mockResolvedValue({
29
- text: '```tsx\nexport function Button() { return <button />; }\n```',
30
- } as Awaited<ReturnType<typeof generateText>>);
31
-
32
- const result = await generateComponentFile({
33
- componentName: 'Button',
34
- specDeltas,
35
- });
36
-
37
- expect(result).toBe('export function Button() { return <button />; }');
38
- });
39
-
40
- it('passes system prompt with methodology, rules, and checklist', async () => {
41
- const mockGenerateText = vi.mocked(generateText);
42
- mockGenerateText.mockResolvedValue({
43
- text: 'component code',
44
- } as Awaited<ReturnType<typeof generateText>>);
45
-
46
- await generateComponentFile({ componentName: 'Button', specDeltas });
47
-
48
- const system = mockGenerateText.mock.calls[0][0].system as string;
49
- expect(system).toContain('staff-level frontend engineer');
50
- expect(system).toContain('METHODOLOGY');
51
- expect(system).toContain('RULES');
52
- expect(system).toContain('QUALITY CHECKLIST');
53
- expect(system).toContain('Named exports');
54
- expect(system).toContain('Tailwind CSS');
55
- expect(system).toContain('ARIA roles');
56
- });
57
-
58
- it('includes spec deltas in the user prompt', async () => {
59
- const mockGenerateText = vi.mocked(generateText);
60
- mockGenerateText.mockResolvedValue({
61
- text: 'component code',
62
- } as Awaited<ReturnType<typeof generateText>>);
63
-
64
- await generateComponentFile({ componentName: 'Button', specDeltas });
65
-
66
- const prompt = mockGenerateText.mock.calls[0][0].prompt as string;
67
- expect(prompt).toContain('## Spec Deltas');
68
- expect(prompt).toContain('## Structure');
69
- expect(prompt).toContain('renders a Button element');
70
- expect(prompt).toContain('**Button**');
71
- });
72
-
73
- it('includes existing component code when provided', async () => {
74
- const mockGenerateText = vi.mocked(generateText);
75
- mockGenerateText.mockResolvedValue({
76
- text: 'updated code',
77
- } as Awaited<ReturnType<typeof generateText>>);
78
-
79
- await generateComponentFile({
80
- componentName: 'Button',
81
- specDeltas,
82
- existingComponent: 'export function Button() {}',
83
- });
84
-
85
- const prompt = mockGenerateText.mock.calls[0][0].prompt as string;
86
- expect(prompt).toContain('## Existing Component');
87
- expect(prompt).toContain('export function Button() {}');
88
- });
89
- });
@@ -1,16 +0,0 @@
1
- import { createModelFromEnv } from '@auto-engineer/model-factory';
2
- import { generateText } from 'ai';
3
- import { extractCodeBlock } from './extract-code-block';
4
- import { buildComponentPrompt, type ComponentPromptInput } from './prompt';
5
-
6
- export type GenerateComponentInput = ComponentPromptInput;
7
-
8
- export async function generateComponentFile(input: GenerateComponentInput): Promise<string> {
9
- const { system, prompt } = buildComponentPrompt(input);
10
- const { text } = await generateText({
11
- model: createModelFromEnv(),
12
- system,
13
- prompt,
14
- });
15
- return extractCodeBlock(text);
16
- }
@@ -1,71 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
- import { generateStoryFile } from './generate-story';
3
-
4
- vi.mock('ai', () => ({
5
- generateText: vi.fn(),
6
- }));
7
-
8
- vi.mock('@auto-engineer/model-factory', () => ({
9
- createModelFromEnv: vi.fn(() => 'mock-model'),
10
- }));
11
-
12
- import { generateText } from 'ai';
13
-
14
- const specDeltas = {
15
- structure: ['renders a Button element'],
16
- rendering: ['shows loading spinner when loading=true'],
17
- interaction: ['calls onClick when clicked'],
18
- styling: ['applies primary variant by default'],
19
- };
20
-
21
- describe('generateStoryFile', () => {
22
- afterEach(() => {
23
- vi.clearAllMocks();
24
- });
25
-
26
- it('returns generated story code from AI', async () => {
27
- const mockGenerateText = vi.mocked(generateText);
28
- mockGenerateText.mockResolvedValue({
29
- text: '```tsx\nimport type { Meta } from "@storybook/react";\n```',
30
- } as Awaited<ReturnType<typeof generateText>>);
31
-
32
- const result = await generateStoryFile({
33
- componentName: 'Button',
34
- specDeltas,
35
- });
36
-
37
- expect(result).toBe('import type { Meta } from "@storybook/react";');
38
- });
39
-
40
- it('passes system prompt with methodology, rules, and checklist', async () => {
41
- const mockGenerateText = vi.mocked(generateText);
42
- mockGenerateText.mockResolvedValue({
43
- text: 'story code',
44
- } as Awaited<ReturnType<typeof generateText>>);
45
-
46
- await generateStoryFile({ componentName: 'Button', specDeltas });
47
-
48
- const system = mockGenerateText.mock.calls[0][0].system as string;
49
- expect(system).toContain('design systems engineer');
50
- expect(system).toContain('METHODOLOGY');
51
- expect(system).toContain('RULES');
52
- expect(system).toContain('QUALITY CHECKLIST');
53
- expect(system).toContain('CSF3 format');
54
- expect(system).toContain('Named import');
55
- });
56
-
57
- it('includes spec deltas in the user prompt but not component code', async () => {
58
- const mockGenerateText = vi.mocked(generateText);
59
- mockGenerateText.mockResolvedValue({
60
- text: 'story code',
61
- } as Awaited<ReturnType<typeof generateText>>);
62
-
63
- await generateStoryFile({ componentName: 'Button', specDeltas });
64
-
65
- const prompt = mockGenerateText.mock.calls[0][0].prompt as string;
66
- expect(prompt).toContain('## Spec Deltas');
67
- expect(prompt).toContain('## Structure');
68
- expect(prompt).toContain('renders a Button element');
69
- expect(prompt).not.toContain('## Component Code');
70
- });
71
- });
@@ -1,16 +0,0 @@
1
- import { createModelFromEnv } from '@auto-engineer/model-factory';
2
- import { generateText } from 'ai';
3
- import { extractCodeBlock } from './extract-code-block';
4
- import { buildStoryPrompt, type StoryPromptInput } from './prompt';
5
-
6
- export type GenerateStoryInput = StoryPromptInput;
7
-
8
- export async function generateStoryFile(input: GenerateStoryInput): Promise<string> {
9
- const { system, prompt } = buildStoryPrompt(input);
10
- const { text } = await generateText({
11
- model: createModelFromEnv(),
12
- system,
13
- prompt,
14
- });
15
- return extractCodeBlock(text);
16
- }
@@ -1,93 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
- import { generateTestFile } from './generate-test';
3
-
4
- vi.mock('ai', () => ({
5
- generateText: vi.fn(),
6
- }));
7
-
8
- vi.mock('@auto-engineer/model-factory', () => ({
9
- createModelFromEnv: vi.fn(() => 'mock-model'),
10
- }));
11
-
12
- import { generateText } from 'ai';
13
-
14
- const specDeltas = {
15
- structure: ['renders a Button element', 'accepts children prop'],
16
- rendering: ['shows loading spinner when loading=true'],
17
- interaction: ['calls onClick when clicked'],
18
- styling: ['applies primary variant by default'],
19
- };
20
-
21
- describe('generateTestFile', () => {
22
- afterEach(() => {
23
- vi.clearAllMocks();
24
- });
25
-
26
- it('returns generated test code from AI', async () => {
27
- const mockGenerateText = vi.mocked(generateText);
28
- mockGenerateText.mockResolvedValue({
29
- text: '```tsx\nimport { render } from "@testing-library/react";\n```',
30
- } as Awaited<ReturnType<typeof generateText>>);
31
-
32
- const result = await generateTestFile({
33
- componentName: 'Button',
34
- specDeltas,
35
- });
36
-
37
- expect(result).toBe('import { render } from "@testing-library/react";');
38
- });
39
-
40
- it('passes system prompt with methodology, rules, and checklist', async () => {
41
- const mockGenerateText = vi.mocked(generateText);
42
- mockGenerateText.mockResolvedValue({
43
- text: 'test code',
44
- } as Awaited<ReturnType<typeof generateText>>);
45
-
46
- await generateTestFile({ componentName: 'Button', specDeltas });
47
-
48
- const system = mockGenerateText.mock.calls[0][0].system as string;
49
- expect(system).toContain('senior frontend engineer who specializes in testing');
50
- expect(system).toContain('METHODOLOGY');
51
- expect(system).toContain('RULES');
52
- expect(system).toContain('QUALITY CHECKLIST');
53
- expect(system).toContain('Semantic queries first');
54
- expect(system).toContain('source of truth');
55
- });
56
-
57
- it('includes all spec delta sections in the user prompt', async () => {
58
- const mockGenerateText = vi.mocked(generateText);
59
- mockGenerateText.mockResolvedValue({
60
- text: 'test code',
61
- } as Awaited<ReturnType<typeof generateText>>);
62
-
63
- await generateTestFile({ componentName: 'Button', specDeltas });
64
-
65
- const prompt = mockGenerateText.mock.calls[0][0].prompt as string;
66
- expect(prompt).toContain('## Spec Deltas');
67
- expect(prompt).toContain('## Structure');
68
- expect(prompt).toContain('renders a Button element');
69
- expect(prompt).toContain('## Rendering');
70
- expect(prompt).toContain('shows loading spinner when loading=true');
71
- expect(prompt).toContain('## Interaction');
72
- expect(prompt).toContain('calls onClick when clicked');
73
- expect(prompt).toContain('## Styling');
74
- expect(prompt).toContain('applies primary variant by default');
75
- });
76
-
77
- it('includes existing component code as context when provided', async () => {
78
- const mockGenerateText = vi.mocked(generateText);
79
- mockGenerateText.mockResolvedValue({
80
- text: 'test code',
81
- } as Awaited<ReturnType<typeof generateText>>);
82
-
83
- await generateTestFile({
84
- componentName: 'Button',
85
- specDeltas,
86
- existingComponent: 'export function Button() { return <button />; }',
87
- });
88
-
89
- const prompt = mockGenerateText.mock.calls[0][0].prompt as string;
90
- expect(prompt).toContain('## Existing Component');
91
- expect(prompt).toContain('export function Button() { return <button />; }');
92
- });
93
- });
@@ -1,16 +0,0 @@
1
- import { createModelFromEnv } from '@auto-engineer/model-factory';
2
- import { generateText } from 'ai';
3
- import { extractCodeBlock } from './extract-code-block';
4
- import { buildTestPrompt, type TestPromptInput } from './prompt';
5
-
6
- export type GenerateTestInput = TestPromptInput;
7
-
8
- export async function generateTestFile(input: GenerateTestInput): Promise<string> {
9
- const { system, prompt } = buildTestPrompt(input);
10
- const { text } = await generateText({
11
- model: createModelFromEnv(),
12
- system,
13
- prompt,
14
- });
15
- return extractCodeBlock(text);
16
- }