@autoview/cli 0.1.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 (297) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +407 -0
  3. package/lib/AutoViewAgent.d.ts +109 -0
  4. package/lib/AutoViewAgent.js +123 -0
  5. package/lib/AutoViewAgent.js.map +1 -0
  6. package/lib/agent/emitMcpServer.d.ts +15 -0
  7. package/lib/agent/emitMcpServer.js +157 -0
  8. package/lib/agent/emitMcpServer.js.map +1 -0
  9. package/lib/agent/emitReport.d.ts +14 -0
  10. package/lib/agent/emitReport.js +85 -0
  11. package/lib/agent/emitReport.js.map +1 -0
  12. package/lib/agent/toolSurface.d.ts +130 -0
  13. package/lib/agent/toolSurface.js +342 -0
  14. package/lib/agent/toolSurface.js.map +1 -0
  15. package/lib/agent/verifyAgentTasks.d.ts +87 -0
  16. package/lib/agent/verifyAgentTasks.js +126 -0
  17. package/lib/agent/verifyAgentTasks.js.map +1 -0
  18. package/lib/cli/main.d.ts +2 -0
  19. package/lib/cli/main.js +295 -0
  20. package/lib/cli/main.js.map +1 -0
  21. package/lib/compiler/AutoViewInterfaceCompiler.d.ts +27 -0
  22. package/lib/compiler/AutoViewInterfaceCompiler.js +68 -0
  23. package/lib/compiler/AutoViewInterfaceCompiler.js.map +1 -0
  24. package/lib/constants/AutoViewFrontendTemplate.d.ts +1 -0
  25. package/lib/constants/AutoViewFrontendTemplate.js +46 -0
  26. package/lib/constants/AutoViewFrontendTemplate.js.map +1 -0
  27. package/lib/constants/AutoViewSystemPromptConstant.d.ts +5 -0
  28. package/lib/constants/AutoViewSystemPromptConstant.js +4 -0
  29. package/lib/constants/AutoViewSystemPromptConstant.js.map +1 -0
  30. package/lib/context/IAutoViewAgentContext.d.ts +60 -0
  31. package/lib/context/IAutoViewAgentContext.js +3 -0
  32. package/lib/context/IAutoViewAgentContext.js.map +1 -0
  33. package/lib/fromSwagger.d.ts +53 -0
  34. package/lib/fromSwagger.js +513 -0
  35. package/lib/fromSwagger.js.map +1 -0
  36. package/lib/generateDeterministic.d.ts +26 -0
  37. package/lib/generateDeterministic.js +75 -0
  38. package/lib/generateDeterministic.js.map +1 -0
  39. package/lib/index.d.ts +15 -0
  40. package/lib/index.js +41 -0
  41. package/lib/index.js.map +1 -0
  42. package/lib/orchestrate/orchestrateAutoView.d.ts +17 -0
  43. package/lib/orchestrate/orchestrateAutoView.js +491 -0
  44. package/lib/orchestrate/orchestrateAutoView.js.map +1 -0
  45. package/lib/orchestrate/orchestrateAutoViewProductPlan.d.ts +37 -0
  46. package/lib/orchestrate/orchestrateAutoViewProductPlan.js +109 -0
  47. package/lib/orchestrate/orchestrateAutoViewProductPlan.js.map +1 -0
  48. package/lib/orchestrate/orchestrateAutoViewRender.d.ts +133 -0
  49. package/lib/orchestrate/orchestrateAutoViewRender.js +943 -0
  50. package/lib/orchestrate/orchestrateAutoViewRender.js.map +1 -0
  51. package/lib/orchestrate/orchestrateAutoViewRenderDeterministic.d.ts +24 -0
  52. package/lib/orchestrate/orchestrateAutoViewRenderDeterministic.js +92 -0
  53. package/lib/orchestrate/orchestrateAutoViewRenderDeterministic.js.map +1 -0
  54. package/lib/orchestrate/orchestrateAutoViewReview.d.ts +48 -0
  55. package/lib/orchestrate/orchestrateAutoViewReview.js +328 -0
  56. package/lib/orchestrate/orchestrateAutoViewReview.js.map +1 -0
  57. package/lib/orchestrate/orchestrateAutoViewScaffold.d.ts +45 -0
  58. package/lib/orchestrate/orchestrateAutoViewScaffold.js +586 -0
  59. package/lib/orchestrate/orchestrateAutoViewScaffold.js.map +1 -0
  60. package/lib/orchestrate/orchestrateAutoViewSdkStudy.d.ts +26 -0
  61. package/lib/orchestrate/orchestrateAutoViewSdkStudy.js +85 -0
  62. package/lib/orchestrate/orchestrateAutoViewSdkStudy.js.map +1 -0
  63. package/lib/orchestrate/structures/IAutoViewProductPlan.d.ts +96 -0
  64. package/lib/orchestrate/structures/IAutoViewProductPlan.js +3 -0
  65. package/lib/orchestrate/structures/IAutoViewProductPlan.js.map +1 -0
  66. package/lib/orchestrate/structures/IAutoViewProductPlanApplication.d.ts +38 -0
  67. package/lib/orchestrate/structures/IAutoViewProductPlanApplication.js +3 -0
  68. package/lib/orchestrate/structures/IAutoViewProductPlanApplication.js.map +1 -0
  69. package/lib/orchestrate/structures/IAutoViewRenderApplication.d.ts +38 -0
  70. package/lib/orchestrate/structures/IAutoViewRenderApplication.js +3 -0
  71. package/lib/orchestrate/structures/IAutoViewRenderApplication.js.map +1 -0
  72. package/lib/orchestrate/structures/IAutoViewReviewApplication.d.ts +40 -0
  73. package/lib/orchestrate/structures/IAutoViewReviewApplication.js +3 -0
  74. package/lib/orchestrate/structures/IAutoViewReviewApplication.js.map +1 -0
  75. package/lib/orchestrate/structures/IAutoViewSdkMap.d.ts +63 -0
  76. package/lib/orchestrate/structures/IAutoViewSdkMap.js +3 -0
  77. package/lib/orchestrate/structures/IAutoViewSdkMap.js.map +1 -0
  78. package/lib/orchestrate/structures/IAutoViewSdkStudyApplication.d.ts +37 -0
  79. package/lib/orchestrate/structures/IAutoViewSdkStudyApplication.js +3 -0
  80. package/lib/orchestrate/structures/IAutoViewSdkStudyApplication.js.map +1 -0
  81. package/lib/orchestrate/utils/HistoryMessage.d.ts +10 -0
  82. package/lib/orchestrate/utils/HistoryMessage.js +25 -0
  83. package/lib/orchestrate/utils/HistoryMessage.js.map +1 -0
  84. package/lib/orchestrate/utils/auditFrontendRuntime.d.ts +53 -0
  85. package/lib/orchestrate/utils/auditFrontendRuntime.js +362 -0
  86. package/lib/orchestrate/utils/auditFrontendRuntime.js.map +1 -0
  87. package/lib/orchestrate/utils/buildDeterministicPlan.d.ts +4 -0
  88. package/lib/orchestrate/utils/buildDeterministicPlan.js +233 -0
  89. package/lib/orchestrate/utils/buildDeterministicPlan.js.map +1 -0
  90. package/lib/orchestrate/utils/buildDeterministicSdkMap.d.ts +22 -0
  91. package/lib/orchestrate/utils/buildDeterministicSdkMap.js +154 -0
  92. package/lib/orchestrate/utils/buildDeterministicSdkMap.js.map +1 -0
  93. package/lib/orchestrate/utils/cacheNodeModules.d.ts +31 -0
  94. package/lib/orchestrate/utils/cacheNodeModules.js +134 -0
  95. package/lib/orchestrate/utils/cacheNodeModules.js.map +1 -0
  96. package/lib/orchestrate/utils/describeEndpointPropsShape.d.ts +37 -0
  97. package/lib/orchestrate/utils/describeEndpointPropsShape.js +192 -0
  98. package/lib/orchestrate/utils/describeEndpointPropsShape.js.map +1 -0
  99. package/lib/orchestrate/utils/describeEndpointRequestBodyShape.d.ts +22 -0
  100. package/lib/orchestrate/utils/describeEndpointRequestBodyShape.js +29 -0
  101. package/lib/orchestrate/utils/describeEndpointRequestBodyShape.js.map +1 -0
  102. package/lib/orchestrate/utils/describeEndpointResponseShape.d.ts +19 -0
  103. package/lib/orchestrate/utils/describeEndpointResponseShape.js +30 -0
  104. package/lib/orchestrate/utils/describeEndpointResponseShape.js.map +1 -0
  105. package/lib/orchestrate/utils/executeCachedBatch.d.ts +22 -0
  106. package/lib/orchestrate/utils/executeCachedBatch.js +64 -0
  107. package/lib/orchestrate/utils/executeCachedBatch.js.map +1 -0
  108. package/lib/orchestrate/utils/loadShoppingFixture.d.ts +33 -0
  109. package/lib/orchestrate/utils/loadShoppingFixture.js +17 -0
  110. package/lib/orchestrate/utils/loadShoppingFixture.js.map +1 -0
  111. package/lib/orchestrate/utils/normalizeProductPlanPaths.d.ts +24 -0
  112. package/lib/orchestrate/utils/normalizeProductPlanPaths.js +77 -0
  113. package/lib/orchestrate/utils/normalizeProductPlanPaths.js.map +1 -0
  114. package/lib/orchestrate/utils/renderJsonSchema.d.ts +23 -0
  115. package/lib/orchestrate/utils/renderJsonSchema.js +122 -0
  116. package/lib/orchestrate/utils/renderJsonSchema.js.map +1 -0
  117. package/lib/orchestrate/utils/renderResourcePage.d.ts +36 -0
  118. package/lib/orchestrate/utils/renderResourcePage.js +1415 -0
  119. package/lib/orchestrate/utils/renderResourcePage.js.map +1 -0
  120. package/lib/orchestrate/utils/validateFrontendTypecheck.d.ts +109 -0
  121. package/lib/orchestrate/utils/validateFrontendTypecheck.js +274 -0
  122. package/lib/orchestrate/utils/validateFrontendTypecheck.js.map +1 -0
  123. package/lib/preview/renderPreview.d.ts +22 -0
  124. package/lib/preview/renderPreview.js +198 -0
  125. package/lib/preview/renderPreview.js.map +1 -0
  126. package/lib/typings/compiler.d.ts +39 -0
  127. package/lib/typings/compiler.js +3 -0
  128. package/lib/typings/compiler.js.map +1 -0
  129. package/lib/typings/events.d.ts +106 -0
  130. package/lib/typings/events.js +3 -0
  131. package/lib/typings/events.js.map +1 -0
  132. package/lib/typings/index.d.ts +10 -0
  133. package/lib/typings/index.js +27 -0
  134. package/lib/typings/index.js.map +1 -0
  135. package/lib/typings/misc.d.ts +78 -0
  136. package/lib/typings/misc.js +3 -0
  137. package/lib/typings/misc.js.map +1 -0
  138. package/lib/utils/ArrayUtil.d.ts +8 -0
  139. package/lib/utils/ArrayUtil.js +30 -0
  140. package/lib/utils/ArrayUtil.js.map +1 -0
  141. package/lib/utils/StringUtil.d.ts +11 -0
  142. package/lib/utils/StringUtil.js +28 -0
  143. package/lib/utils/StringUtil.js.map +1 -0
  144. package/lib/utils/classifyEndpoints.d.ts +62 -0
  145. package/lib/utils/classifyEndpoints.js +216 -0
  146. package/lib/utils/classifyEndpoints.js.map +1 -0
  147. package/lib/utils/endpointFilter.d.ts +26 -0
  148. package/lib/utils/endpointFilter.js +0 -0
  149. package/lib/utils/endpointFilter.js.map +1 -0
  150. package/lib/utils/extractFields.d.ts +85 -0
  151. package/lib/utils/extractFields.js +231 -0
  152. package/lib/utils/extractFields.js.map +1 -0
  153. package/lib/utils/index.d.ts +13 -0
  154. package/lib/utils/index.js +30 -0
  155. package/lib/utils/index.js.map +1 -0
  156. package/lib/utils/normalizeForNestia.d.ts +34 -0
  157. package/lib/utils/normalizeForNestia.js +133 -0
  158. package/lib/utils/normalizeForNestia.js.map +1 -0
  159. package/lib/utils/resourcePlan.d.ts +39 -0
  160. package/lib/utils/resourcePlan.js +95 -0
  161. package/lib/utils/resourcePlan.js.map +1 -0
  162. package/lib/utils/sliceDocument.d.ts +17 -0
  163. package/lib/utils/sliceDocument.js +114 -0
  164. package/lib/utils/sliceDocument.js.map +1 -0
  165. package/lib/utils/toEndpoints.d.ts +90 -0
  166. package/lib/utils/toEndpoints.js +227 -0
  167. package/lib/utils/toEndpoints.js.map +1 -0
  168. package/lib/verify/runWorkflows.d.ts +25 -0
  169. package/lib/verify/runWorkflows.js +366 -0
  170. package/lib/verify/runWorkflows.js.map +1 -0
  171. package/lib/verify/workflows.d.ts +53 -0
  172. package/lib/verify/workflows.js +107 -0
  173. package/lib/verify/workflows.js.map +1 -0
  174. package/package.json +82 -0
  175. package/prompts/AUTOVIEW_RENDER.md +398 -0
  176. package/prompts/AUTOVIEW_REVIEW.md +60 -0
  177. package/prompts/AUTOVIEW_SDK_STUDY.md +89 -0
  178. package/src/AutoViewAgent.ts +222 -0
  179. package/src/agent/emitMcpServer.integration.test.ts +168 -0
  180. package/src/agent/emitMcpServer.test.ts +51 -0
  181. package/src/agent/emitMcpServer.ts +178 -0
  182. package/src/agent/emitReport.ts +117 -0
  183. package/src/agent/toolSurface.test.ts +243 -0
  184. package/src/agent/toolSurface.ts +501 -0
  185. package/src/agent/verifyAgentTasks.test.ts +106 -0
  186. package/src/agent/verifyAgentTasks.ts +171 -0
  187. package/src/cli/main.ts +363 -0
  188. package/src/compiler/AutoViewInterfaceCompiler.ts +69 -0
  189. package/src/constants/AutoViewFrontendTemplate.ts +42 -0
  190. package/src/constants/AutoViewSystemPromptConstant.ts +6 -0
  191. package/src/context/IAutoViewAgentContext.ts +84 -0
  192. package/src/fromSwagger.test.ts +269 -0
  193. package/src/fromSwagger.ts +500 -0
  194. package/src/generateDeterministic.test.ts +39 -0
  195. package/src/generateDeterministic.ts +77 -0
  196. package/src/index.ts +30 -0
  197. package/src/orchestrate/orchestrateAutoView.ts +590 -0
  198. package/src/orchestrate/orchestrateAutoViewProductPlan.ts +121 -0
  199. package/src/orchestrate/orchestrateAutoViewRender.ts +1117 -0
  200. package/src/orchestrate/orchestrateAutoViewRenderDeterministic.ts +101 -0
  201. package/src/orchestrate/orchestrateAutoViewReview.ts +272 -0
  202. package/src/orchestrate/orchestrateAutoViewScaffold.ts +627 -0
  203. package/src/orchestrate/orchestrateAutoViewSdkStudy.ts +90 -0
  204. package/src/orchestrate/renderNavTs.test.ts +74 -0
  205. package/src/orchestrate/structures/IAutoViewProductPlan.ts +119 -0
  206. package/src/orchestrate/structures/IAutoViewProductPlanApplication.ts +41 -0
  207. package/src/orchestrate/structures/IAutoViewRenderApplication.ts +40 -0
  208. package/src/orchestrate/structures/IAutoViewReviewApplication.ts +42 -0
  209. package/src/orchestrate/structures/IAutoViewSdkMap.ts +72 -0
  210. package/src/orchestrate/structures/IAutoViewSdkStudyApplication.ts +40 -0
  211. package/src/orchestrate/utils/HistoryMessage.ts +41 -0
  212. package/src/orchestrate/utils/auditFrontendRuntime.test.ts +18 -0
  213. package/src/orchestrate/utils/auditFrontendRuntime.ts +454 -0
  214. package/src/orchestrate/utils/buildDeterministicPlan.test.ts +170 -0
  215. package/src/orchestrate/utils/buildDeterministicPlan.ts +289 -0
  216. package/src/orchestrate/utils/buildDeterministicSdkMap.test.ts +90 -0
  217. package/src/orchestrate/utils/buildDeterministicSdkMap.ts +169 -0
  218. package/src/orchestrate/utils/cacheNodeModules.ts +136 -0
  219. package/src/orchestrate/utils/describeEndpointPropsShape.test.ts +86 -0
  220. package/src/orchestrate/utils/describeEndpointPropsShape.ts +202 -0
  221. package/src/orchestrate/utils/describeEndpointRequestBodyShape.test.ts +87 -0
  222. package/src/orchestrate/utils/describeEndpointRequestBodyShape.ts +31 -0
  223. package/src/orchestrate/utils/describeEndpointResponseShape.test.ts +70 -0
  224. package/src/orchestrate/utils/describeEndpointResponseShape.ts +32 -0
  225. package/src/orchestrate/utils/executeCachedBatch.ts +59 -0
  226. package/src/orchestrate/utils/loadShoppingFixture.ts +52 -0
  227. package/src/orchestrate/utils/normalizeProductPlanPaths.ts +92 -0
  228. package/src/orchestrate/utils/renderJsonSchema.test.ts +162 -0
  229. package/src/orchestrate/utils/renderJsonSchema.ts +133 -0
  230. package/src/orchestrate/utils/renderResourcePage.test.ts +468 -0
  231. package/src/orchestrate/utils/renderResourcePage.ts +1624 -0
  232. package/src/orchestrate/utils/validateFrontendTypecheck.test.ts +32 -0
  233. package/src/orchestrate/utils/validateFrontendTypecheck.ts +335 -0
  234. package/src/preview/renderPreview.ts +273 -0
  235. package/src/typings/compiler.ts +47 -0
  236. package/src/typings/events.ts +155 -0
  237. package/src/typings/index.ts +10 -0
  238. package/src/typings/misc.ts +93 -0
  239. package/src/utils/ArrayUtil.ts +16 -0
  240. package/src/utils/StringUtil.ts +29 -0
  241. package/src/utils/classifyEndpoints.test.ts +86 -0
  242. package/src/utils/classifyEndpoints.ts +291 -0
  243. package/src/utils/endpointFilter.test.ts +50 -0
  244. package/src/utils/endpointFilter.ts +0 -0
  245. package/src/utils/extractFields.test.ts +82 -0
  246. package/src/utils/extractFields.ts +306 -0
  247. package/src/utils/index.ts +13 -0
  248. package/src/utils/normalizeForNestia.test.ts +93 -0
  249. package/src/utils/normalizeForNestia.ts +139 -0
  250. package/src/utils/resourcePlan.test.ts +104 -0
  251. package/src/utils/resourcePlan.ts +180 -0
  252. package/src/utils/sliceDocument.test.ts +85 -0
  253. package/src/utils/sliceDocument.ts +119 -0
  254. package/src/utils/toEndpoints.test.ts +251 -0
  255. package/src/utils/toEndpoints.ts +343 -0
  256. package/src/verify/runWorkflows.ts +403 -0
  257. package/src/verify/workflows.test.ts +117 -0
  258. package/src/verify/workflows.ts +154 -0
  259. package/template/CLAUDE.md +140 -0
  260. package/template/Dockerfile +31 -0
  261. package/template/PROMPT.md +80 -0
  262. package/template/SANDBOX.md +70 -0
  263. package/template/app/api/health/route.ts +10 -0
  264. package/template/app/globals.css +97 -0
  265. package/template/app/layout.tsx +30 -0
  266. package/template/app/page.tsx +19 -0
  267. package/template/components/AppShell.tsx +114 -0
  268. package/template/components/auto/CatalogGrid.tsx +159 -0
  269. package/template/components/auto/ConfirmButton.tsx +67 -0
  270. package/template/components/auto/EmbeddedCollection.tsx +144 -0
  271. package/template/components/auto/ResourceDashboard.tsx +104 -0
  272. package/template/components/auto/ResourceDetail.tsx +93 -0
  273. package/template/components/auto/ResourceForm.tsx +235 -0
  274. package/template/components/auto/ResourceIcon.tsx +88 -0
  275. package/template/components/auto/ResourceLanding.tsx +155 -0
  276. package/template/components/auto/ResourceTable.tsx +223 -0
  277. package/template/components/auto/formatValue.tsx +186 -0
  278. package/template/components/auto/types.ts +42 -0
  279. package/template/components/ui/badge.tsx +40 -0
  280. package/template/components/ui/button.tsx +57 -0
  281. package/template/components/ui/card.tsx +86 -0
  282. package/template/components/ui/dialog.tsx +119 -0
  283. package/template/components/ui/input.tsx +23 -0
  284. package/template/components/ui/label.tsx +24 -0
  285. package/template/components/ui/pagination.tsx +117 -0
  286. package/template/components/ui/select.tsx +92 -0
  287. package/template/components/ui/sheet.tsx +135 -0
  288. package/template/components/ui/skeleton.tsx +15 -0
  289. package/template/components/ui/table.tsx +120 -0
  290. package/template/components/ui/tabs.tsx +55 -0
  291. package/template/lib/utils.ts +35 -0
  292. package/template/next.config.mjs +52 -0
  293. package/template/package.json +46 -0
  294. package/template/postcss.config.js +6 -0
  295. package/template/scripts/start-shopping-backend.sh +56 -0
  296. package/template/tailwind.config.ts +96 -0
  297. package/template/tsconfig.json +29 -0
@@ -0,0 +1,590 @@
1
+ import { OpenApi } from "@typia/interface";
2
+ import {
3
+ AutoBeAutoViewCompleteEvent,
4
+ AutoBeAutoViewStartEvent,
5
+ IAutoBeRunAutoViewOptions,
6
+ } from "../typings";
7
+ import { v7 } from "uuid";
8
+
9
+ import { IAutoViewAgentContext } from "../context/IAutoViewAgentContext";
10
+ import { orchestrateAutoViewProductPlan } from "./orchestrateAutoViewProductPlan";
11
+ import {
12
+ fileToScreenPath,
13
+ rerenderScreenForRuntime,
14
+ rerenderScreenForTypecheck,
15
+ screenPathToFile,
16
+ } from "./orchestrateAutoViewRender";
17
+ import { orchestrateAutoViewRenderDeterministic } from "./orchestrateAutoViewRenderDeterministic";
18
+ import { orchestrateAutoViewReview } from "./orchestrateAutoViewReview";
19
+ import { orchestrateAutoViewScaffold } from "./orchestrateAutoViewScaffold";
20
+ import { orchestrateAutoViewSdkStudy } from "./orchestrateAutoViewSdkStudy";
21
+ import {
22
+ type IAuditFrontendRuntimeResult,
23
+ auditFrontendRuntime,
24
+ } from "./utils/auditFrontendRuntime";
25
+ import { executeCachedBatch } from "./utils/executeCachedBatch";
26
+ import { loadShoppingFixture } from "./utils/loadShoppingFixture";
27
+ import { normalizeProductPlanPaths } from "./utils/normalizeProductPlanPaths";
28
+ import {
29
+ FrontendTypecheckSession,
30
+ type IValidateFrontendTypecheckResult,
31
+ } from "./utils/validateFrontendTypecheck";
32
+ import { deriveWorkflows } from "../verify/workflows";
33
+ import { runWorkflows } from "../verify/runWorkflows";
34
+ import { sliceDocument } from "../utils/sliceDocument";
35
+
36
+ /**
37
+ * Top-level AutoView orchestrator.
38
+ *
39
+ * Walks through the five phases — SDK Study, Product Plan, Scaffold, Render,
40
+ * Review — emitting one event per phase plus per-page progress during Render.
41
+ * The final `autoViewComplete` event carries the assembled frontend project as
42
+ * a flat `path → content` map ready for Sandbox deploy.
43
+ *
44
+ * All five phases (SDK Study → Product Plan → Scaffold → Render → UI Review)
45
+ * are implemented. Visual screenshot capture is intentionally out of scope for
46
+ * the agent itself — the operator runs Playwright against the Sandbox deploy —
47
+ * but the Review phase still produces the `wiki/sdk-feedback.md` audit so the
48
+ * SDK-quality signal lands in the archive.
49
+ */
50
+ export async function orchestrateAutoView(
51
+ ctx: IAutoViewAgentContext,
52
+ options: IAutoBeRunAutoViewOptions = {},
53
+ ): Promise<void> {
54
+ const source = options.source ?? "interface";
55
+ const designTheme = (options.designTheme ?? "").trim();
56
+ const {
57
+ document: fullDocument,
58
+ step,
59
+ reason,
60
+ backend,
61
+ } = resolveSource(ctx, source, {
62
+ backend: options.backend ?? null,
63
+ });
64
+ // Apply `--include` / `--exclude` at the DOCUMENT level, not just the screen
65
+ // list: slicing the paths AND pruning component schemas to their transitive
66
+ // closure is what lets a large swagger (Box, Stripe) actually run — otherwise
67
+ // SDK Study compiles all ~180 schemas and overflows the model's context.
68
+ const document = sliceDocument(fullDocument, {
69
+ include: options.include,
70
+ exclude: options.exclude,
71
+ });
72
+ const startedAt = Date.now();
73
+
74
+ ctx.dispatch({
75
+ type: "autoViewStart",
76
+ id: v7(),
77
+ created_at: new Date().toISOString(),
78
+ source,
79
+ step,
80
+ designTheme,
81
+ reason,
82
+ } satisfies AutoBeAutoViewStartEvent);
83
+
84
+ // Phase 1 — SDK Study.
85
+ const { map: sdkMap, markdown: sdkMapMarkdown } =
86
+ await orchestrateAutoViewSdkStudy(ctx, { document, step });
87
+
88
+ // Phase 2 — Product Plan.
89
+ const { plan: rawProductPlan, markdown: productPlanMarkdown } =
90
+ await orchestrateAutoViewProductPlan(ctx, {
91
+ document,
92
+ sdkMap,
93
+ designTheme,
94
+ step,
95
+ filter: { include: options.include, exclude: options.exclude },
96
+ });
97
+ // Next.js refuses to start when sibling routes under the same parent
98
+ // disagree on the dynamic-segment name (e.g. `/sales/[id]` vs.
99
+ // `/sales/[saleId]`). The planner cannot always avoid that — run the
100
+ // plan through a deterministic normalizer before the scaffold step
101
+ // bakes the paths into the file tree.
102
+ const productPlan = normalizeProductPlanPaths(rawProductPlan);
103
+
104
+ // Phase 3 — Scaffold (deterministic).
105
+ const scaffolded = await orchestrateAutoViewScaffold(ctx, {
106
+ document,
107
+ sdkMap,
108
+ sdkMapMarkdown,
109
+ productPlan,
110
+ productPlanMarkdown,
111
+ step,
112
+ backend,
113
+ });
114
+
115
+ // Phase 4 — Render (deterministic). Emits one thin `page.tsx` per screen
116
+ // that wires the typed SDK call to a universal `Resource*` component, with
117
+ // column / field metadata baked from the swagger schema. No LLM, no
118
+ // parser-retry roulette: every screen gets a page and every property of its
119
+ // row / response / request type becomes a column / row / input. The rendered
120
+ // pages overwrite the scaffold placeholders in place.
121
+ const render = await orchestrateAutoViewRenderDeterministic(ctx, {
122
+ document,
123
+ productPlan,
124
+ step,
125
+ });
126
+ for (const [key, value] of Object.entries(render.files)) {
127
+ scaffolded[key] = value;
128
+ }
129
+
130
+ // Phase 4.5 — deterministic `tsc --noEmit` against the assembled tree,
131
+ // plus a typecheck-driven retry pass for screens whose pages failed
132
+ // the gate. The per-screen parser check inside Render only catches
133
+ // grammar failures; type errors against the SDK (the model inventing
134
+ // properties on response types, wrong-casing fields, sending a second
135
+ // argument to a parameterless endpoint, etc.) escape every render
136
+ // attempt unless we actually compile the project the way the user
137
+ // will. Materializing into a temp dir + `npm install` + `tsc` is
138
+ // expensive (~30s on first run) but the typecheck session reuses the
139
+ // installed node_modules across retry rounds, so subsequent
140
+ // typecheck runs cost only the actual compile time.
141
+ const { typecheck, recovered } = await runTypecheckPhase(ctx, {
142
+ scaffolded,
143
+ document,
144
+ sdkMap,
145
+ productPlan,
146
+ designTheme,
147
+ });
148
+ scaffolded["wiki/typecheck.md"] = typecheck.markdown;
149
+
150
+ // Phase 6 — runtime audit (opt-in). After typecheck closes the static
151
+ // gate, boot `next dev` against the assembled tree, walk every screen
152
+ // with a headless Chromium, capture console / pageerror / navigation
153
+ // diagnostics, and re-render broken pages with the live errors in the
154
+ // prompt. The retry pass closes the class of bugs `tsc --noEmit`
155
+ // cannot see — `obj?.array.method(...)` undefined-access patterns,
156
+ // react render crashes against simulator data, hydration mismatches.
157
+ // Skipped when `options.runtimeAudit !== true` because the gate
158
+ // installs Playwright + Chromium (~150MB) and boots `next dev` twice
159
+ // per run, adding ~10–20 minutes to the agent's wall clock.
160
+ let runtimeAudit: IAuditFrontendRuntimeResult | null = null;
161
+ let runtimeRecovered = 0;
162
+ if (options.runtimeAudit === true) {
163
+ const result = await runRuntimeAuditPhase(ctx, {
164
+ scaffolded,
165
+ document,
166
+ sdkMap,
167
+ productPlan,
168
+ designTheme,
169
+ });
170
+ runtimeAudit = result.audit;
171
+ runtimeRecovered = result.recovered;
172
+ scaffolded["wiki/runtime-audit.md"] = runtimeAudit.markdown;
173
+ }
174
+
175
+ // Phase 7 — workflow verification (opt-in). Derive the user workflows from
176
+ // the plan and drive them in a real headless browser, asserting each step's
177
+ // positive outcome (data rendered, navigation moved). Writes
178
+ // `wiki/verification.md` — the evidence that the generated app actually works
179
+ // for a user, not just that it compiles. Skipped unless `options.verify`
180
+ // because it installs Chromium and boots `next dev`.
181
+ if (options.verify === true) {
182
+ try {
183
+ const workflows = deriveWorkflows(productPlan);
184
+ const verification = await runWorkflows(scaffolded, workflows);
185
+ scaffolded["wiki/verification.md"] = verification.markdown;
186
+ } catch (err) {
187
+ const message = err instanceof Error ? err.message : String(err);
188
+ scaffolded["wiki/verification.md"] = [
189
+ "# Workflow verification",
190
+ "",
191
+ "Verification could not run against the assembled project:",
192
+ "",
193
+ "```",
194
+ message,
195
+ "```",
196
+ ].join("\n");
197
+ }
198
+ }
199
+
200
+ // Phase 5 — UI Review. Code-and-spec audit; produces the
201
+ // operator-facing `wiki/sdk-feedback.md` document. Visual
202
+ // verification is left to the Sandbox deploy step.
203
+ const review = await orchestrateAutoViewReview(ctx, {
204
+ document,
205
+ sdkMap,
206
+ productPlan,
207
+ render,
208
+ typecheck,
209
+ recovered: recovered + runtimeRecovered,
210
+ step,
211
+ });
212
+ scaffolded["wiki/sdk-feedback.md"] = review.markdown;
213
+
214
+ ctx.dispatch({
215
+ type: "autoViewComplete",
216
+ id: v7(),
217
+ created_at: new Date().toISOString(),
218
+ step,
219
+ source,
220
+ elapsed: Date.now() - startedAt,
221
+ pages: productPlan.screens.length,
222
+ files: scaffolded,
223
+ } satisfies AutoBeAutoViewCompleteEvent);
224
+ }
225
+
226
+ interface IResolvedSource {
227
+ document: OpenApi.IDocument;
228
+ step: number;
229
+ reason: string;
230
+ /**
231
+ * Backend hint surfaced from the source. When the swagger ships a real
232
+ * `servers[].url`, scaffold the generated frontend with that host + live mode
233
+ * so the demo renders real product data instead of typia-random gibberish.
234
+ * When omitted, scaffold falls back to localhost + simulate.
235
+ */
236
+ backend: { host: string | null };
237
+ }
238
+
239
+ function resolveSource(
240
+ ctx: IAutoViewAgentContext,
241
+ source: "interface" | "shopping",
242
+ overrides: { backend: { host: string } | null },
243
+ ): IResolvedSource {
244
+ if (source === "shopping") {
245
+ // Stable reference SDK derived from `@samchon/shopping-api`. Lets
246
+ // the AutoView pipeline run end-to-end without waiting for the
247
+ // live AutoBE interface phase to complete, which is the whole
248
+ // reason the bundled fixture exists.
249
+ //
250
+ // Default the backend at `http://127.0.0.1:37001` instead of the
251
+ // swagger's `servers[0].url` (the public host is not reachable from
252
+ // most networks). The frontend pack ships
253
+ // `scripts/start-shopping-backend.sh`, which clones
254
+ // `samchon/shopping` and boots its NestJS server on that port — so
255
+ // the demo runs end-to-end against the real backend with seeded
256
+ // product data instead of typia-random gibberish.
257
+ const fixture = loadShoppingFixture();
258
+ return {
259
+ document: fixture.document,
260
+ step: 0,
261
+ reason:
262
+ "User triggered AutoView against the bundled @samchon/shopping-api reference.",
263
+ backend: overrides.backend ?? { host: "http://127.0.0.1:37001" },
264
+ };
265
+ }
266
+ const interfaceHistory = ctx.state().interface;
267
+ if (interfaceHistory === null) {
268
+ throw new Error(
269
+ "AutoView requires the interface phase to be complete first. " +
270
+ 'Run with source: "shopping" to use the bundled reference instead.',
271
+ );
272
+ }
273
+ return {
274
+ document: interfaceHistory.document,
275
+ step: interfaceHistory.step,
276
+ reason: "User triggered AutoView against the AutoBE interface output.",
277
+ // Honor the caller's backend hint (CLI extracts it from swagger
278
+ // `servers[]`, or accepts a `--backend <url>` flag). When none was
279
+ // given the scaffold falls back to simulate-only mode — only useful
280
+ // for swaggers that genuinely have no backend (AutoBE's interface
281
+ // phase before the operator wires their own server).
282
+ backend: overrides.backend ?? { host: null },
283
+ };
284
+ }
285
+
286
+ /**
287
+ * Maximum number of full typecheck+rerender rounds. Initial render counts as
288
+ * round 0, so this many additional rounds may follow it.
289
+ */
290
+ const MAX_TYPECHECK_RETRY_ROUNDS = 2;
291
+
292
+ /**
293
+ * Phase 4.5 in full: open a typecheck session against the assembled file map,
294
+ * iterate "typecheck → re-render broken screens → typecheck" up to
295
+ * {@link MAX_TYPECHECK_RETRY_ROUNDS} rounds, and return the final result. The
296
+ * scaffolded map is mutated in place — each successful re-render overwrites the
297
+ * broken file so the assembled output reflects the final state seen by the
298
+ * typecheck gate.
299
+ *
300
+ * Returns the last typecheck result + `recovered` count (screens that the loop
301
+ * fixed) so the Review event can report both honestly. On infra failure (npm
302
+ * install crash, etc.) returns a marker typecheck result and a recovered count
303
+ * of zero — the operator still gets the file map.
304
+ */
305
+ async function runTypecheckPhase(
306
+ ctx: IAutoViewAgentContext,
307
+ args: {
308
+ scaffolded: Record<string, string>;
309
+ document: OpenApi.IDocument;
310
+ sdkMap: ReturnType<typeof loadShoppingFixture> extends { document: infer _ }
311
+ ? Awaited<ReturnType<typeof orchestrateAutoViewSdkStudy>>["map"]
312
+ : never;
313
+ productPlan: Awaited<
314
+ ReturnType<typeof orchestrateAutoViewProductPlan>
315
+ >["plan"];
316
+ designTheme: string;
317
+ },
318
+ ): Promise<{
319
+ typecheck: IValidateFrontendTypecheckResult;
320
+ recovered: number;
321
+ }> {
322
+ let session: FrontendTypecheckSession;
323
+ try {
324
+ session = await FrontendTypecheckSession.open(args.scaffolded);
325
+ } catch (err) {
326
+ const message = err instanceof Error ? err.message : String(err);
327
+ return {
328
+ typecheck: {
329
+ diagnostics: new Map(),
330
+ totalErrors: 0,
331
+ markdown: [
332
+ "# Typecheck report",
333
+ "",
334
+ "`tsc --noEmit` could not be run against the assembled project:",
335
+ "",
336
+ "```",
337
+ message,
338
+ "```",
339
+ "",
340
+ "Re-run the project locally with `npm install && npm run typecheck` to validate.",
341
+ ].join("\n"),
342
+ elapsedMs: 0,
343
+ },
344
+ recovered: 0,
345
+ };
346
+ }
347
+
348
+ try {
349
+ let typecheck = await session.typecheck();
350
+ let recovered = 0;
351
+ const allScreenPaths = args.productPlan.screens.map((s) => s.path);
352
+ const semaphoreCap =
353
+ typeof ctx.vendor.semaphore === "number"
354
+ ? ctx.vendor.semaphore
355
+ : ctx.vendor.semaphore !== undefined
356
+ ? ctx.vendor.semaphore.max()
357
+ : 8;
358
+
359
+ for (
360
+ let round = 0;
361
+ round < MAX_TYPECHECK_RETRY_ROUNDS && typecheck.totalErrors > 0;
362
+ round++
363
+ ) {
364
+ // Build the set of (screen, previousTsx, errors) tuples for every
365
+ // broken file that maps back to a known screen. Non-screen files
366
+ // (scaffold components, generated SDK, wiki) are not fixable by
367
+ // re-rendering a single screen — they are left to fail loudly.
368
+ const tasks: {
369
+ screen: (typeof args.productPlan.screens)[number];
370
+ filePath: string;
371
+ previousTsx: string;
372
+ errors: {
373
+ line: number;
374
+ column: number;
375
+ code: string;
376
+ message: string;
377
+ }[];
378
+ }[] = [];
379
+ for (const [filePath, diagnostics] of typecheck.diagnostics) {
380
+ const screenPath = fileToScreenPath(filePath);
381
+ if (screenPath === null) continue;
382
+ const screen = args.productPlan.screens.find(
383
+ (s) => s.path === screenPath,
384
+ );
385
+ if (screen === undefined) continue;
386
+ const previousTsx = args.scaffolded[filePath];
387
+ if (previousTsx === undefined) continue;
388
+ tasks.push({
389
+ screen,
390
+ filePath,
391
+ previousTsx,
392
+ errors: diagnostics.map((d) => ({
393
+ line: d.line,
394
+ column: d.column,
395
+ code: d.code,
396
+ message: d.message,
397
+ })),
398
+ });
399
+ }
400
+ if (tasks.length === 0) break;
401
+
402
+ const fixed = new Set<string>();
403
+ await executeCachedBatch(
404
+ semaphoreCap,
405
+ tasks.map((task) => async (promptCacheKey) => {
406
+ const result = await rerenderScreenForTypecheck(ctx, {
407
+ screen: task.screen,
408
+ document: args.document,
409
+ sdkMap: args.sdkMap,
410
+ designTheme: args.designTheme,
411
+ promptCacheKey,
412
+ allScreenPaths,
413
+ previousTsx: task.previousTsx,
414
+ typecheckErrors: task.errors,
415
+ });
416
+ if (result === null || !result.ok) return;
417
+ args.scaffolded[task.filePath] = result.tsx;
418
+ await session.writeFile(task.filePath, result.tsx);
419
+ fixed.add(task.filePath);
420
+ }),
421
+ );
422
+
423
+ if (fixed.size === 0) break;
424
+ const next = await session.typecheck();
425
+ const errorsBefore = new Set(typecheck.diagnostics.keys());
426
+ const errorsAfter = new Set(next.diagnostics.keys());
427
+ for (const filePath of fixed) {
428
+ if (errorsBefore.has(filePath) && !errorsAfter.has(filePath)) {
429
+ recovered++;
430
+ }
431
+ }
432
+ typecheck = next;
433
+ }
434
+
435
+ return { typecheck, recovered };
436
+ } finally {
437
+ await session.dispose();
438
+ }
439
+ }
440
+
441
+ /**
442
+ * Phase 6 in full: open a runtime audit session (npm install + playwright +
443
+ * chromium + `next dev`), capture per-page console / pageerror / navigation
444
+ * diagnostics, re-render the broken pages with the diagnostics in the prompt,
445
+ * and audit one more time. The orchestrator mutates `scaffolded` in place so
446
+ * the next phase sees the corrected output.
447
+ *
448
+ * Returns the final audit + `recovered` count (pages that the loop fixed) so
449
+ * the Review event can report runtime quality alongside the typecheck quality.
450
+ * On infra failure (Playwright install crashed, next dev never became ready,
451
+ * Chromium download blocked) returns a marker audit body and a recovered count
452
+ * of zero — the operator still gets the file map.
453
+ */
454
+ async function runRuntimeAuditPhase(
455
+ ctx: IAutoViewAgentContext,
456
+ args: {
457
+ scaffolded: Record<string, string>;
458
+ document: OpenApi.IDocument;
459
+ sdkMap: Awaited<ReturnType<typeof orchestrateAutoViewSdkStudy>>["map"];
460
+ productPlan: Awaited<
461
+ ReturnType<typeof orchestrateAutoViewProductPlan>
462
+ >["plan"];
463
+ designTheme: string;
464
+ },
465
+ ): Promise<{ audit: IAuditFrontendRuntimeResult; recovered: number }> {
466
+ const pages = args.productPlan.screens.map((s) => s.path);
467
+ let firstAudit: IAuditFrontendRuntimeResult;
468
+ try {
469
+ firstAudit = await auditFrontendRuntime(args.scaffolded, pages);
470
+ } catch (err) {
471
+ const message = err instanceof Error ? err.message : String(err);
472
+ return {
473
+ audit: {
474
+ diagnostics: [],
475
+ byPage: new Map(),
476
+ visited: pages,
477
+ markdown: [
478
+ "# Runtime audit",
479
+ "",
480
+ "Playwright runtime audit could not be run against the assembled project:",
481
+ "",
482
+ "```",
483
+ message,
484
+ "```",
485
+ "",
486
+ "Re-run the project locally with `npm install && npm run dev` and visit pages by hand to validate.",
487
+ ].join("\n"),
488
+ elapsedMs: 0,
489
+ },
490
+ recovered: 0,
491
+ };
492
+ }
493
+ if (firstAudit.byPage.size === 0) {
494
+ return { audit: firstAudit, recovered: 0 };
495
+ }
496
+
497
+ // Identify broken pages whose screens we own — only `app/.../page.tsx`
498
+ // files map back to a planned screen; component / wiki / SDK files are
499
+ // out of this loop's scope.
500
+ type IRuntimeTask = {
501
+ screen: (typeof args.productPlan.screens)[number];
502
+ filePath: string;
503
+ previousTsx: string;
504
+ runtimeErrors: {
505
+ type: "console" | "pageerror" | "navigation";
506
+ message: string;
507
+ }[];
508
+ };
509
+ const tasks: IRuntimeTask[] = [];
510
+ for (const [pagePath, diagnostics] of firstAudit.byPage) {
511
+ const screen = args.productPlan.screens.find((s) => s.path === pagePath);
512
+ if (screen === undefined) continue;
513
+ const filePath = screenPathToFile(screen.path);
514
+ const previousTsx = args.scaffolded[filePath];
515
+ if (previousTsx === undefined) continue;
516
+ tasks.push({
517
+ screen,
518
+ filePath,
519
+ previousTsx,
520
+ runtimeErrors: diagnostics.map((d) => ({
521
+ type: d.type,
522
+ message: d.message,
523
+ })),
524
+ });
525
+ }
526
+ if (tasks.length === 0) return { audit: firstAudit, recovered: 0 };
527
+
528
+ const allScreenPaths = args.productPlan.screens.map((s) => s.path);
529
+ const semaphoreCap =
530
+ typeof ctx.vendor.semaphore === "number"
531
+ ? ctx.vendor.semaphore
532
+ : ctx.vendor.semaphore !== undefined
533
+ ? ctx.vendor.semaphore.max()
534
+ : 8;
535
+
536
+ const fixed = new Set<string>();
537
+ await executeCachedBatch(
538
+ semaphoreCap,
539
+ tasks.map((task) => async (promptCacheKey) => {
540
+ const result = await rerenderScreenForRuntime(ctx, {
541
+ screen: task.screen,
542
+ document: args.document,
543
+ sdkMap: args.sdkMap,
544
+ designTheme: args.designTheme,
545
+ promptCacheKey,
546
+ allScreenPaths,
547
+ previousTsx: task.previousTsx,
548
+ runtimeErrors: task.runtimeErrors,
549
+ });
550
+ if (result === null || !result.ok) return;
551
+ args.scaffolded[task.filePath] = result.tsx;
552
+ fixed.add(task.screen.path);
553
+ }),
554
+ );
555
+ if (fixed.size === 0) return { audit: firstAudit, recovered: 0 };
556
+
557
+ // Re-audit to measure recovery. Only one retry round to keep the gate
558
+ // bounded; further rounds rarely help once a page survived the prompt
559
+ // rewrite with the diagnostics in hand.
560
+ let secondAudit: IAuditFrontendRuntimeResult;
561
+ try {
562
+ secondAudit = await auditFrontendRuntime(args.scaffolded, pages);
563
+ } catch (err) {
564
+ const message = err instanceof Error ? err.message : String(err);
565
+ secondAudit = {
566
+ diagnostics: [],
567
+ byPage: new Map(),
568
+ visited: pages,
569
+ markdown: [
570
+ "# Runtime audit (post-retry)",
571
+ "",
572
+ "Second-round Playwright audit could not be run:",
573
+ "",
574
+ "```",
575
+ message,
576
+ "```",
577
+ "",
578
+ "First-round results above are the last known runtime state.",
579
+ ].join("\n"),
580
+ elapsedMs: 0,
581
+ };
582
+ }
583
+ let recovered = 0;
584
+ for (const pagePath of fixed) {
585
+ if (firstAudit.byPage.has(pagePath) && !secondAudit.byPage.has(pagePath)) {
586
+ recovered++;
587
+ }
588
+ }
589
+ return { audit: secondAudit, recovered };
590
+ }