@adia-ai/gen-ui 0.8.37

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 (631) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +77 -0
  3. package/compose/CHANGELOG.md +1707 -0
  4. package/compose/README.md +215 -0
  5. package/compose/core/artifacts.js +262 -0
  6. package/compose/core/context-store.js +218 -0
  7. package/compose/core/generator.d.ts +4 -0
  8. package/compose/core/generator.js +602 -0
  9. package/compose/core/pipeline/engine.js +289 -0
  10. package/compose/core/pipeline/types.js +91 -0
  11. package/compose/core/plan-primitives.js +120 -0
  12. package/compose/core/plan-turn.js +145 -0
  13. package/compose/core/reference.js +150 -0
  14. package/compose/core/state.js +15 -0
  15. package/compose/evals/harness.d.ts +4 -0
  16. package/compose/evals/harness.mjs +193 -0
  17. package/compose/index.d.ts +4 -0
  18. package/compose/index.js +16 -0
  19. package/compose/shared/validate-and-repair.js +122 -0
  20. package/compose/strategies/_shared/chunk-loader.js +282 -0
  21. package/compose/strategies/cascade.d.ts +67 -0
  22. package/compose/strategies/cascade.js +165 -0
  23. package/compose/strategies/escalation.d.ts +13 -0
  24. package/compose/strategies/escalation.js +132 -0
  25. package/compose/strategies/free-form-composer/index.js +254 -0
  26. package/compose/strategies/free-form-composer/system-prompt.js +205 -0
  27. package/compose/strategies/free-form-composer/transpile.js +279 -0
  28. package/compose/strategies/monolithic/_shared.js +1619 -0
  29. package/compose/strategies/monolithic/generate-instant.js +228 -0
  30. package/compose/strategies/monolithic/generate-pro.js +490 -0
  31. package/compose/strategies/monolithic/generate-thinking.js +206 -0
  32. package/compose/strategies/registry.d.ts +20 -0
  33. package/compose/strategies/registry.js +495 -0
  34. package/compose/strategies/zettel/_smoke.js +27 -0
  35. package/compose/strategies/zettel/chunk-composer.js +214 -0
  36. package/compose/strategies/zettel/chunk-refiner.js +582 -0
  37. package/compose/strategies/zettel/chunk-synthesizer.js +458 -0
  38. package/compose/strategies/zettel/composer.js +78 -0
  39. package/compose/strategies/zettel/composition-library.js +418 -0
  40. package/compose/strategies/zettel/generate.js +15 -0
  41. package/compose/strategies/zettel/generator-adapter.d.ts +4 -0
  42. package/compose/strategies/zettel/generator-adapter.js +242 -0
  43. package/compose/strategies/zettel/issue-reporter.js +607 -0
  44. package/compose/strategies/zettel/session-store.js +121 -0
  45. package/compose/strategies/zettel/state-cache.js +158 -0
  46. package/compose/transpiler/transpiler-maps.js +675 -0
  47. package/compose/transpiler/transpiler.d.ts +4 -0
  48. package/compose/transpiler/transpiler.js +962 -0
  49. package/corpus/CHANGELOG.md +1957 -0
  50. package/corpus/README.md +279 -0
  51. package/corpus/catalog-a2ui_0_9.d.ts +4 -0
  52. package/corpus/catalog-a2ui_0_9.json +29571 -0
  53. package/corpus/catalog-a2ui_0_9_rules.txt +1215 -0
  54. package/corpus/chunk-embeddings.d.ts +4 -0
  55. package/corpus/chunk-embeddings.json +1 -0
  56. package/corpus/chunks/_index.json +16658 -0
  57. package/corpus/chunks/_source-hashes.json +571 -0
  58. package/corpus/chunks/access-denied-with-request.json +124 -0
  59. package/corpus/chunks/access-request-form.json +166 -0
  60. package/corpus/chunks/access-request-pending.json +133 -0
  61. package/corpus/chunks/accordion-settings.json +176 -0
  62. package/corpus/chunks/achievement-badges.json +413 -0
  63. package/corpus/chunks/achievement-unlock.json +104 -0
  64. package/corpus/chunks/action-list-record-actions.json +84 -0
  65. package/corpus/chunks/activity-feed.json +390 -0
  66. package/corpus/chunks/admin-page-header-flush.json +83 -0
  67. package/corpus/chunks/admin-page-header-title-description.json +80 -0
  68. package/corpus/chunks/admin-page-header-with-actions.json +107 -0
  69. package/corpus/chunks/admin-page-header-with-tabs.json +144 -0
  70. package/corpus/chunks/admin-shell-rounded-borderless.json +287 -0
  71. package/corpus/chunks/admin-shell-standard.json +310 -0
  72. package/corpus/chunks/admin-sidebar-brand-signin.json +158 -0
  73. package/corpus/chunks/admin-sidebar-brand-version.json +130 -0
  74. package/corpus/chunks/admin-sidebar-flat-nav.json +131 -0
  75. package/corpus/chunks/admin-sidebar-nav-dividers.json +150 -0
  76. package/corpus/chunks/admin-sidebar-nav-groups.json +171 -0
  77. package/corpus/chunks/admin-sidebar-workspace-switcher.json +139 -0
  78. package/corpus/chunks/admin-topbar-breadcrumb-actions.json +130 -0
  79. package/corpus/chunks/admin-topbar-breadcrumb-minimal.json +79 -0
  80. package/corpus/chunks/admin-topbar-deep-breadcrumb.json +129 -0
  81. package/corpus/chunks/admin-topbar-search.json +104 -0
  82. package/corpus/chunks/admin-topbar-status-indicator.json +122 -0
  83. package/corpus/chunks/admin-topbar-trailing-toggle.json +114 -0
  84. package/corpus/chunks/agent-activity-feed.json +163 -0
  85. package/corpus/chunks/agent-artifact-stub-card.json +115 -0
  86. package/corpus/chunks/agent-canvas-shell.json +305 -0
  87. package/corpus/chunks/agent-citations-source-chips.json +82 -0
  88. package/corpus/chunks/agent-command-palette-search.json +120 -0
  89. package/corpus/chunks/agent-cost-detailed.json +260 -0
  90. package/corpus/chunks/agent-cost-inline.json +78 -0
  91. package/corpus/chunks/agent-memory-detail.json +181 -0
  92. package/corpus/chunks/agent-memory-editor.json +173 -0
  93. package/corpus/chunks/agent-memory-list.json +207 -0
  94. package/corpus/chunks/agent-pipeline-status-stages.json +61 -0
  95. package/corpus/chunks/agent-prompt-card.json +179 -0
  96. package/corpus/chunks/agent-prompt-library-grid.json +341 -0
  97. package/corpus/chunks/agent-prompt-picker.json +282 -0
  98. package/corpus/chunks/agent-rate-limit.json +100 -0
  99. package/corpus/chunks/agent-reasoning-collapsed.json +128 -0
  100. package/corpus/chunks/agent-tool-call-accordion.json +109 -0
  101. package/corpus/chunks/agent-tool-call-collapsed.json +98 -0
  102. package/corpus/chunks/agent-tool-call-error.json +112 -0
  103. package/corpus/chunks/agent-tool-call-result.json +145 -0
  104. package/corpus/chunks/agent-tool-call-running.json +85 -0
  105. package/corpus/chunks/agent-tool-call-success.json +137 -0
  106. package/corpus/chunks/agent-trace-timeline.json +244 -0
  107. package/corpus/chunks/ai-streaming-response.json +147 -0
  108. package/corpus/chunks/alert-banner-stack.json +78 -0
  109. package/corpus/chunks/alert-banner.json +55 -0
  110. package/corpus/chunks/alert-dialog-simple.json +72 -0
  111. package/corpus/chunks/alert-dialog-typed.json +107 -0
  112. package/corpus/chunks/alert-dialog-unsaved.json +81 -0
  113. package/corpus/chunks/analytics-chart.json +213 -0
  114. package/corpus/chunks/analytics-sparklines-dashboard.json +259 -0
  115. package/corpus/chunks/anchor-bar-selection-bar.json +226 -0
  116. package/corpus/chunks/api-key-table.json +148 -0
  117. package/corpus/chunks/api-keys-create.json +140 -0
  118. package/corpus/chunks/api-keys-list.json +271 -0
  119. package/corpus/chunks/app-nav-badges-counts.json +77 -0
  120. package/corpus/chunks/app-nav-badges-group-rollup-badges.json +100 -0
  121. package/corpus/chunks/app-nav-badges-plan-tiers.json +76 -0
  122. package/corpus/chunks/app-nav-badges-status-callouts.json +75 -0
  123. package/corpus/chunks/app-nav-full-example.json +195 -0
  124. package/corpus/chunks/app-nav-groups.json +103 -0
  125. package/corpus/chunks/app-nav-items.json +74 -0
  126. package/corpus/chunks/app-nav-labels-and-dividers.json +92 -0
  127. package/corpus/chunks/app-nav-spacer.json +77 -0
  128. package/corpus/chunks/app-product-listing-card.json +214 -0
  129. package/corpus/chunks/approvals-detail.json +240 -0
  130. package/corpus/chunks/approvals-queue.json +321 -0
  131. package/corpus/chunks/audit-log-basic.json +184 -0
  132. package/corpus/chunks/audit-log.json +174 -0
  133. package/corpus/chunks/auth-account-deleted-actions.json +51 -0
  134. package/corpus/chunks/auth-account-deleted.json +202 -0
  135. package/corpus/chunks/auth-card-content.json +260 -0
  136. package/corpus/chunks/auth-card-header.json +205 -0
  137. package/corpus/chunks/auth-email-entry.json +65 -0
  138. package/corpus/chunks/auth-email-verify-confirm.json +52 -0
  139. package/corpus/chunks/auth-email-verify.json +196 -0
  140. package/corpus/chunks/auth-forbidden-actions.json +59 -0
  141. package/corpus/chunks/auth-forbidden.json +203 -0
  142. package/corpus/chunks/auth-invite-actions.json +49 -0
  143. package/corpus/chunks/auth-invite-team-card.json +86 -0
  144. package/corpus/chunks/auth-link-expired-form.json +65 -0
  145. package/corpus/chunks/auth-link-expired.json +196 -0
  146. package/corpus/chunks/auth-locked-account.json +211 -0
  147. package/corpus/chunks/auth-locked-recovery-options.json +60 -0
  148. package/corpus/chunks/auth-mfa-enrollment-submit.json +54 -0
  149. package/corpus/chunks/auth-mfa-enrollment.json +284 -0
  150. package/corpus/chunks/auth-mfa-fallback-actions.json +52 -0
  151. package/corpus/chunks/auth-mfa-recovery.json +61 -0
  152. package/corpus/chunks/auth-new-password-form.json +75 -0
  153. package/corpus/chunks/auth-new-password.json +217 -0
  154. package/corpus/chunks/auth-oauth-fallback-actions.json +52 -0
  155. package/corpus/chunks/auth-oauth-interstitial.json +160 -0
  156. package/corpus/chunks/auth-password-challenge.json +94 -0
  157. package/corpus/chunks/auth-password-reset-form.json +64 -0
  158. package/corpus/chunks/auth-password-reset.json +195 -0
  159. package/corpus/chunks/auth-profile-form.json +72 -0
  160. package/corpus/chunks/auth-profile-setup.json +194 -0
  161. package/corpus/chunks/auth-reset-sent.json +188 -0
  162. package/corpus/chunks/auth-session-expired-actions.json +52 -0
  163. package/corpus/chunks/auth-session-expired.json +201 -0
  164. package/corpus/chunks/auth-signin-card-email.json +245 -0
  165. package/corpus/chunks/auth-signin-card-magic-link.json +147 -0
  166. package/corpus/chunks/auth-signin-card-mfa.json +231 -0
  167. package/corpus/chunks/auth-signin-card-otp.json +205 -0
  168. package/corpus/chunks/auth-signin-card-password.json +264 -0
  169. package/corpus/chunks/auth-signin-card-recovery.json +218 -0
  170. package/corpus/chunks/auth-signout-actions.json +51 -0
  171. package/corpus/chunks/auth-signout.json +184 -0
  172. package/corpus/chunks/auth-signup-email-entry.json +66 -0
  173. package/corpus/chunks/auth-signup-entry.json +281 -0
  174. package/corpus/chunks/auth-signup-social-auths.json +54 -0
  175. package/corpus/chunks/auth-signup-verify.json +227 -0
  176. package/corpus/chunks/auth-social-auths.json +62 -0
  177. package/corpus/chunks/auth-sso-providers.json +55 -0
  178. package/corpus/chunks/auth-sso-required.json +213 -0
  179. package/corpus/chunks/auth-team-invite.json +288 -0
  180. package/corpus/chunks/avatar-group-overflow.json +137 -0
  181. package/corpus/chunks/avatar-stack-overflow.json +124 -0
  182. package/corpus/chunks/banner-announcement-beta.json +99 -0
  183. package/corpus/chunks/banner-announcement-promo.json +102 -0
  184. package/corpus/chunks/banner-live-update.json +102 -0
  185. package/corpus/chunks/banner-system-maintenance.json +101 -0
  186. package/corpus/chunks/banner-system-offline.json +85 -0
  187. package/corpus/chunks/banner-system-update.json +102 -0
  188. package/corpus/chunks/bell-menu-empty.json +107 -0
  189. package/corpus/chunks/bell-menu-unread.json +395 -0
  190. package/corpus/chunks/billing-cancel-subscription-danger.json +61 -0
  191. package/corpus/chunks/billing-invoice-history-table.json +75 -0
  192. package/corpus/chunks/billing-overview.json +202 -0
  193. package/corpus/chunks/billing-payment-method-card-on-file.json +157 -0
  194. package/corpus/chunks/billing-progress-label.json +101 -0
  195. package/corpus/chunks/blog-post-card.json +212 -0
  196. package/corpus/chunks/breadcrumb-navigation.json +72 -0
  197. package/corpus/chunks/bulk-action-toolbar-floating.json +199 -0
  198. package/corpus/chunks/bulk-action-toolbar-swap.json +158 -0
  199. package/corpus/chunks/bulk-selection-actions-bar.json +162 -0
  200. package/corpus/chunks/business-address-form.json +953 -0
  201. package/corpus/chunks/calendar-month-view.json +74 -0
  202. package/corpus/chunks/card-grid-images.json +459 -0
  203. package/corpus/chunks/card-header-with-description.json +47 -0
  204. package/corpus/chunks/card-with-empty-state.json +96 -0
  205. package/corpus/chunks/card-with-form.json +143 -0
  206. package/corpus/chunks/card-with-sparkline.json +90 -0
  207. package/corpus/chunks/card-with-stat-kpi.json +86 -0
  208. package/corpus/chunks/changelog-feed-basic.json +470 -0
  209. package/corpus/chunks/chart-in-card-chart-plus-breakdown.json +188 -0
  210. package/corpus/chunks/chart-in-card-chart-plus-stat.json +89 -0
  211. package/corpus/chunks/chart-in-card-chart-with-filter-pills.json +124 -0
  212. package/corpus/chunks/chart-in-card-full-bleed-legend.json +116 -0
  213. package/corpus/chunks/chart-in-card-full-chart.json +107 -0
  214. package/corpus/chunks/chart-in-card-sparkline-tile.json +93 -0
  215. package/corpus/chunks/chart-in-card-stat-with-sparkline.json +73 -0
  216. package/corpus/chunks/chart-in-card-trend-footer.json +115 -0
  217. package/corpus/chunks/chart-with-filter-pills.json +169 -0
  218. package/corpus/chunks/chat-empty-state-hero.json +102 -0
  219. package/corpus/chunks/chat-message-assistant-byline.json +85 -0
  220. package/corpus/chunks/chat-message-user-byline.json +84 -0
  221. package/corpus/chunks/chat-page-shell.json +379 -0
  222. package/corpus/chunks/chat-streaming-surface.json +169 -0
  223. package/corpus/chunks/checkout-order-summary-card.json +140 -0
  224. package/corpus/chunks/code-snippet.json +107 -0
  225. package/corpus/chunks/col-form-stack.json +93 -0
  226. package/corpus/chunks/col-heading-body-action.json +79 -0
  227. package/corpus/chunks/col-stat-label.json +63 -0
  228. package/corpus/chunks/color-picker-swatches.json +153 -0
  229. package/corpus/chunks/command-palette.json +327 -0
  230. package/corpus/chunks/comments-composer.json +158 -0
  231. package/corpus/chunks/comments-mention-menu.json +237 -0
  232. package/corpus/chunks/comments-thread.json +344 -0
  233. package/corpus/chunks/commerce-pricing-tiers.json +401 -0
  234. package/corpus/chunks/comparison-table.json +246 -0
  235. package/corpus/chunks/contact-form-card.json +197 -0
  236. package/corpus/chunks/contact-form.json +157 -0
  237. package/corpus/chunks/contact-support-form.json +702 -0
  238. package/corpus/chunks/conversion-funnel-4-step-funnel.json +139 -0
  239. package/corpus/chunks/conversion-funnel-6step.json +151 -0
  240. package/corpus/chunks/conversion-funnel-wide-summary.json +192 -0
  241. package/corpus/chunks/conversion-funnel-with-segment-compare.json +202 -0
  242. package/corpus/chunks/cta-banner-centered.json +102 -0
  243. package/corpus/chunks/dashboard-acquisition-panel.json +212 -0
  244. package/corpus/chunks/dashboard-admin-page.json +104 -0
  245. package/corpus/chunks/dashboard-audience-kpis.json +165 -0
  246. package/corpus/chunks/dashboard-audience-panel.json +756 -0
  247. package/corpus/chunks/dashboard-behavior-panel.json +114 -0
  248. package/corpus/chunks/dashboard-chart-recent.json +566 -0
  249. package/corpus/chunks/dashboard-cohort-retention.json +83 -0
  250. package/corpus/chunks/dashboard-conversion-panel.json +234 -0
  251. package/corpus/chunks/dashboard-country-list.json +304 -0
  252. package/corpus/chunks/dashboard-filter-bar.json +118 -0
  253. package/corpus/chunks/dashboard-funnel.json +142 -0
  254. package/corpus/chunks/dashboard-notifications-panel.json +423 -0
  255. package/corpus/chunks/dashboard-overview-panel.json +1644 -0
  256. package/corpus/chunks/dashboard-page-header.json +166 -0
  257. package/corpus/chunks/dashboard-pages-table.json +86 -0
  258. package/corpus/chunks/dashboard-quick-actions.json +116 -0
  259. package/corpus/chunks/dashboard-reports-panel.json +166 -0
  260. package/corpus/chunks/dashboard-reports-table.json +138 -0
  261. package/corpus/chunks/dashboard-storage-card.json +117 -0
  262. package/corpus/chunks/dashboard-tabs.json +86 -0
  263. package/corpus/chunks/dashboard-team-actions-storage.json +605 -0
  264. package/corpus/chunks/dashboard-team-list.json +334 -0
  265. package/corpus/chunks/dashboard-traffic-channels.json +184 -0
  266. package/corpus/chunks/dashboard-transactions-table.json +145 -0
  267. package/corpus/chunks/data-export-history.json +192 -0
  268. package/corpus/chunks/data-export-request.json +197 -0
  269. package/corpus/chunks/data-import-wizard.json +391 -0
  270. package/corpus/chunks/date-range-picker.json +156 -0
  271. package/corpus/chunks/date-time-picker-form.json +222 -0
  272. package/corpus/chunks/departments-checkbox-form.json +390 -0
  273. package/corpus/chunks/destructive-confirm-modal.json +149 -0
  274. package/corpus/chunks/diff-inline.json +84 -0
  275. package/corpus/chunks/diff-side-by-side.json +131 -0
  276. package/corpus/chunks/diff-structured.json +216 -0
  277. package/corpus/chunks/digest-email-preview.json +374 -0
  278. package/corpus/chunks/divider-text-label.json +87 -0
  279. package/corpus/chunks/doc-editor-shell.json +356 -0
  280. package/corpus/chunks/drawer-2fa-key.json +273 -0
  281. package/corpus/chunks/drawer-2fa-sms.json +261 -0
  282. package/corpus/chunks/drawer-2fa-totp.json +385 -0
  283. package/corpus/chunks/drawer-cancel-sub.json +636 -0
  284. package/corpus/chunks/drawer-change-plan.json +561 -0
  285. package/corpus/chunks/drawer-custom-roles.json +696 -0
  286. package/corpus/chunks/drawer-data-start.json +171 -0
  287. package/corpus/chunks/drawer-delete-account.json +341 -0
  288. package/corpus/chunks/drawer-delete-workspace.json +362 -0
  289. package/corpus/chunks/drawer-discord.json +434 -0
  290. package/corpus/chunks/drawer-figma.json +401 -0
  291. package/corpus/chunks/drawer-first-dashboard.json +220 -0
  292. package/corpus/chunks/drawer-gcal.json +475 -0
  293. package/corpus/chunks/drawer-github.json +589 -0
  294. package/corpus/chunks/drawer-invite.json +397 -0
  295. package/corpus/chunks/drawer-record-detail.json +44 -0
  296. package/corpus/chunks/drawer-report.json +528 -0
  297. package/corpus/chunks/drawer-revoke-session.json +331 -0
  298. package/corpus/chunks/drawer-role.json +190 -0
  299. package/corpus/chunks/drawer-slack.json +429 -0
  300. package/corpus/chunks/drawer-smtp.json +476 -0
  301. package/corpus/chunks/drawer-source.json +294 -0
  302. package/corpus/chunks/drawer-transaction.json +493 -0
  303. package/corpus/chunks/drawer-with-create-form.json +43 -0
  304. package/corpus/chunks/editor-code-pane.json +204 -0
  305. package/corpus/chunks/editor-page-shell.json +149 -0
  306. package/corpus/chunks/editor-preview-pane.json +136 -0
  307. package/corpus/chunks/editor-statusbar-ready.json +99 -0
  308. package/corpus/chunks/editor-toolbar-import-export.json +195 -0
  309. package/corpus/chunks/email-inbox-list.json +678 -0
  310. package/corpus/chunks/empty-state-danger.json +58 -0
  311. package/corpus/chunks/empty-state-minimal.json +44 -0
  312. package/corpus/chunks/empty-state-warning.json +53 -0
  313. package/corpus/chunks/empty-state.json +65 -0
  314. package/corpus/chunks/error-404-actions.json +54 -0
  315. package/corpus/chunks/error-404.json +204 -0
  316. package/corpus/chunks/error-500-actions.json +61 -0
  317. package/corpus/chunks/error-500.json +220 -0
  318. package/corpus/chunks/error-maintenance-actions.json +53 -0
  319. package/corpus/chunks/error-maintenance.json +203 -0
  320. package/corpus/chunks/error-page-shell.json +132 -0
  321. package/corpus/chunks/export-flow-async.json +210 -0
  322. package/corpus/chunks/export-flow-delivery.json +163 -0
  323. package/corpus/chunks/export-flow-sync.json +162 -0
  324. package/corpus/chunks/extended-profile-form.json +512 -0
  325. package/corpus/chunks/faq-accordion.json +123 -0
  326. package/corpus/chunks/feature-grid-icons.json +314 -0
  327. package/corpus/chunks/feature-grid-three-cards.json +187 -0
  328. package/corpus/chunks/feature-toggle-switch-grid.json +213 -0
  329. package/corpus/chunks/file-upload-dnd.json +166 -0
  330. package/corpus/chunks/file-upload-field.json +97 -0
  331. package/corpus/chunks/file-upload-form.json +251 -0
  332. package/corpus/chunks/filter-bar-active-filters.json +176 -0
  333. package/corpus/chunks/filter-bar-filter-bar-with-table.json +113 -0
  334. package/corpus/chunks/filter-bar-saved-views.json +117 -0
  335. package/corpus/chunks/filter-popover-form.json +137 -0
  336. package/corpus/chunks/footer-multi-column.json +270 -0
  337. package/corpus/chunks/footer-primary-only.json +41 -0
  338. package/corpus/chunks/form-checkbox-group.json +65 -0
  339. package/corpus/chunks/form-drawer-edit-form.json +178 -0
  340. package/corpus/chunks/form-drawer-simple-form.json +151 -0
  341. package/corpus/chunks/form-drawer-tall-form.json +325 -0
  342. package/corpus/chunks/form-field-email-hint.json +53 -0
  343. package/corpus/chunks/form-field-range.json +54 -0
  344. package/corpus/chunks/form-field-required.json +52 -0
  345. package/corpus/chunks/form-field-select.json +66 -0
  346. package/corpus/chunks/form-field-textarea.json +51 -0
  347. package/corpus/chunks/form-field-with-error.json +151 -0
  348. package/corpus/chunks/form-fields-two-column.json +69 -0
  349. package/corpus/chunks/form-page-shell.json +146 -0
  350. package/corpus/chunks/form-switch-toggle.json +41 -0
  351. package/corpus/chunks/form-system-live-demo.json +123 -0
  352. package/corpus/chunks/forms-address-autocomplete.json +277 -0
  353. package/corpus/chunks/forms-address-fields.json +221 -0
  354. package/corpus/chunks/forms-conditional-reveal.json +195 -0
  355. package/corpus/chunks/gallery-page-shell.json +444 -0
  356. package/corpus/chunks/grid-2col-entry-cards.json +140 -0
  357. package/corpus/chunks/grid-kpi-4col.json +164 -0
  358. package/corpus/chunks/grid-responsive-kpi.json +165 -0
  359. package/corpus/chunks/hero-cta-simple.json +107 -0
  360. package/corpus/chunks/hero-cta-split.json +183 -0
  361. package/corpus/chunks/hero-section-split.json +111 -0
  362. package/corpus/chunks/icon-text-row.json +60 -0
  363. package/corpus/chunks/image-caption-tile.json +99 -0
  364. package/corpus/chunks/image-carousel.json +156 -0
  365. package/corpus/chunks/image-thumbnail-grid.json +77 -0
  366. package/corpus/chunks/image-upload-preview.json +118 -0
  367. package/corpus/chunks/import-mapping-flow.json +972 -0
  368. package/corpus/chunks/inline-dialog-rename.json +128 -0
  369. package/corpus/chunks/inline-dialog-schedule.json +154 -0
  370. package/corpus/chunks/inline-dialog-status.json +179 -0
  371. package/corpus/chunks/integrations-api-keys-card-list.json +475 -0
  372. package/corpus/chunks/integrations-connect-form.json +550 -0
  373. package/corpus/chunks/integrations-grid.json +141 -0
  374. package/corpus/chunks/integrations-webhooks-empty-state.json +66 -0
  375. package/corpus/chunks/inventory-list-stock.json +137 -0
  376. package/corpus/chunks/invite-members.json +153 -0
  377. package/corpus/chunks/invoice-line-items.json +493 -0
  378. package/corpus/chunks/kanban-board-3col.json +713 -0
  379. package/corpus/chunks/kanban-page-shell.json +671 -0
  380. package/corpus/chunks/key-value-detail-list.json +242 -0
  381. package/corpus/chunks/keyboard-shortcut-display.json +250 -0
  382. package/corpus/chunks/labeled-textarea.json +45 -0
  383. package/corpus/chunks/leaderboard-table.json +140 -0
  384. package/corpus/chunks/library-browser-search-filter.json +109 -0
  385. package/corpus/chunks/linked-record-row.json +61 -0
  386. package/corpus/chunks/loading-skeleton-placeholder.json +387 -0
  387. package/corpus/chunks/login-form-card.json +207 -0
  388. package/corpus/chunks/logo-cloud-trusted-by.json +235 -0
  389. package/corpus/chunks/map-with-location-list.json +293 -0
  390. package/corpus/chunks/marketing-hero-cta.json +102 -0
  391. package/corpus/chunks/marketing-page-shell.json +352 -0
  392. package/corpus/chunks/masonry-gallery.json +154 -0
  393. package/corpus/chunks/member-edit-drawer.json +236 -0
  394. package/corpus/chunks/members-active-table-search-filter.json +184 -0
  395. package/corpus/chunks/members-pending-invites-cards.json +251 -0
  396. package/corpus/chunks/members-roles-permissions-list.json +146 -0
  397. package/corpus/chunks/menu-context-actions.json +113 -0
  398. package/corpus/chunks/metadata-description-list.json +178 -0
  399. package/corpus/chunks/modal-create-project-form.json +133 -0
  400. package/corpus/chunks/modal-preferences-tabs.json +147 -0
  401. package/corpus/chunks/multi-field-form-validation.json +394 -0
  402. package/corpus/chunks/nav-menu-icons.json +74 -0
  403. package/corpus/chunks/newsletter-subscription.json +190 -0
  404. package/corpus/chunks/notification-badges-feed.json +411 -0
  405. package/corpus/chunks/notification-preferences-panel.json +238 -0
  406. package/corpus/chunks/onb-completion.json +139 -0
  407. package/corpus/chunks/onb-extension-install.json +172 -0
  408. package/corpus/chunks/onb-hero-welcome.json +156 -0
  409. package/corpus/chunks/onb-import-picker.json +86 -0
  410. package/corpus/chunks/onb-mobile-handoff.json +121 -0
  411. package/corpus/chunks/onb-notification-prefs.json +83 -0
  412. package/corpus/chunks/onb-persona-picker.json +82 -0
  413. package/corpus/chunks/onb-provider-tiles.json +137 -0
  414. package/corpus/chunks/onb-settings-review.json +257 -0
  415. package/corpus/chunks/onb-step-footer.json +121 -0
  416. package/corpus/chunks/onb-step-header.json +121 -0
  417. package/corpus/chunks/onb-step-progress.json +140 -0
  418. package/corpus/chunks/onb-step-shell.json +380 -0
  419. package/corpus/chunks/onb-story-pane.json +121 -0
  420. package/corpus/chunks/onb-tutorial-steps.json +193 -0
  421. package/corpus/chunks/order-confirmation-success-card.json +177 -0
  422. package/corpus/chunks/order-tracking-timeline.json +131 -0
  423. package/corpus/chunks/pagination-controls.json +82 -0
  424. package/corpus/chunks/pane-settings-sidebar.json +204 -0
  425. package/corpus/chunks/patient-visit-shell.json +191 -0
  426. package/corpus/chunks/payment-checkout-form.json +341 -0
  427. package/corpus/chunks/payment-method-form.json +328 -0
  428. package/corpus/chunks/period-comparison.json +236 -0
  429. package/corpus/chunks/permission-matrix-table.json +438 -0
  430. package/corpus/chunks/permissions-matrix-grid.json +111 -0
  431. package/corpus/chunks/permissions-matrix-summary.json +157 -0
  432. package/corpus/chunks/permissions-role-picker-radio.json +107 -0
  433. package/corpus/chunks/permissions-role-picker-select.json +101 -0
  434. package/corpus/chunks/permissions-share-link.json +256 -0
  435. package/corpus/chunks/permissions-share-people.json +297 -0
  436. package/corpus/chunks/permissions-sharing-scopes.json +109 -0
  437. package/corpus/chunks/plan-selection-form.json +529 -0
  438. package/corpus/chunks/playground-a2ui.json +181 -0
  439. package/corpus/chunks/playground-agent-admin.json +117 -0
  440. package/corpus/chunks/playground-agent-chat.json +126 -0
  441. package/corpus/chunks/playground-app-shell.json +488 -0
  442. package/corpus/chunks/playground-chat.json +265 -0
  443. package/corpus/chunks/playground-construct-canvas.json +118 -0
  444. package/corpus/chunks/playground-css-channel.json +487 -0
  445. package/corpus/chunks/playground-gen-ui.json +224 -0
  446. package/corpus/chunks/playground-render-preview.json +369 -0
  447. package/corpus/chunks/playground-streams-bridge.json +437 -0
  448. package/corpus/chunks/playground-table-toolbar.json +38 -0
  449. package/corpus/chunks/popover-with-content.json +118 -0
  450. package/corpus/chunks/pricing-tiers.json +561 -0
  451. package/corpus/chunks/product-tour.json +158 -0
  452. package/corpus/chunks/profile-public.json +297 -0
  453. package/corpus/chunks/progress-tracker-milestones.json +294 -0
  454. package/corpus/chunks/radio-button-group.json +83 -0
  455. package/corpus/chunks/rating-stars-review-summary.json +259 -0
  456. package/corpus/chunks/reactions-bar.json +75 -0
  457. package/corpus/chunks/reactions-picker.json +245 -0
  458. package/corpus/chunks/real-time-metrics-dashboard.json +344 -0
  459. package/corpus/chunks/record-detail-drawer-simple-detail.json +296 -0
  460. package/corpus/chunks/record-detail-drawer-tabbed-detail.json +443 -0
  461. package/corpus/chunks/referral-share-link.json +128 -0
  462. package/corpus/chunks/referral-status.json +243 -0
  463. package/corpus/chunks/reg-address-form.json +825 -0
  464. package/corpus/chunks/reg-billing-card.json +210 -0
  465. package/corpus/chunks/reg-brand-scrape.json +599 -0
  466. package/corpus/chunks/reg-departments-toggle.json +259 -0
  467. package/corpus/chunks/reg-extended-profile.json +356 -0
  468. package/corpus/chunks/reg-final-done.json +457 -0
  469. package/corpus/chunks/reg-helpdesk-grid.json +571 -0
  470. package/corpus/chunks/reg-import-picker.json +112 -0
  471. package/corpus/chunks/reg-integrations-grid.json +418 -0
  472. package/corpus/chunks/reg-invite-form.json +245 -0
  473. package/corpus/chunks/reg-legal-entity.json +260 -0
  474. package/corpus/chunks/reg-org-chart-review.json +891 -0
  475. package/corpus/chunks/reg-profile-identity.json +188 -0
  476. package/corpus/chunks/reg-step-footer.json +201 -0
  477. package/corpus/chunks/reg-step-header.json +201 -0
  478. package/corpus/chunks/reg-step-progress.json +236 -0
  479. package/corpus/chunks/reg-step-shell.json +605 -0
  480. package/corpus/chunks/reg-story-pane.json +201 -0
  481. package/corpus/chunks/reg-success-summary.json +257 -0
  482. package/corpus/chunks/reg-team-size.json +128 -0
  483. package/corpus/chunks/reg-usecase-picker.json +104 -0
  484. package/corpus/chunks/reg-workspace-name.json +159 -0
  485. package/corpus/chunks/responsive-grid-pattern.json +71 -0
  486. package/corpus/chunks/responsive-kpi-grid.json +166 -0
  487. package/corpus/chunks/responsive-row-pattern.json +71 -0
  488. package/corpus/chunks/responsive-shell-sidebar.json +308 -0
  489. package/corpus/chunks/responsive-wrap-at-pattern.json +124 -0
  490. package/corpus/chunks/retention-cohort-default-retention.json +80 -0
  491. package/corpus/chunks/retention-cohort-stat-pair.json +163 -0
  492. package/corpus/chunks/retention-cohort-with-legend.json +135 -0
  493. package/corpus/chunks/revenue-heatmap.json +82 -0
  494. package/corpus/chunks/role-management.json +272 -0
  495. package/corpus/chunks/row-action-cluster.json +54 -0
  496. package/corpus/chunks/row-avatar-name-role.json +71 -0
  497. package/corpus/chunks/row-icon-label.json +52 -0
  498. package/corpus/chunks/row-spread-label-value.json +54 -0
  499. package/corpus/chunks/row-wrap-tags.json +72 -0
  500. package/corpus/chunks/schedule-meeting-form-card.json +229 -0
  501. package/corpus/chunks/search-recents-menu.json +195 -0
  502. package/corpus/chunks/search-results-grouped.json +357 -0
  503. package/corpus/chunks/search-results-list.json +202 -0
  504. package/corpus/chunks/search-saved-views.json +356 -0
  505. package/corpus/chunks/search-with-filters.json +311 -0
  506. package/corpus/chunks/searchable-picker-modal.json +164 -0
  507. package/corpus/chunks/section-with-stack.json +48 -0
  508. package/corpus/chunks/security-active-sessions-devices.json +287 -0
  509. package/corpus/chunks/security-change-password-form.json +102 -0
  510. package/corpus/chunks/security-delete-account-danger.json +79 -0
  511. package/corpus/chunks/segmented-control-billing-tabs.json +164 -0
  512. package/corpus/chunks/select-multiple-preselected.json +70 -0
  513. package/corpus/chunks/settings-2fa-setup.json +307 -0
  514. package/corpus/chunks/settings-admin-page.json +1205 -0
  515. package/corpus/chunks/settings-appearance-primitives.json +145 -0
  516. package/corpus/chunks/settings-appearance-theme-panel.json +55 -0
  517. package/corpus/chunks/settings-appearance.json +81 -0
  518. package/corpus/chunks/settings-danger-zone-delete-workspace.json +93 -0
  519. package/corpus/chunks/settings-general-form.json +69 -0
  520. package/corpus/chunks/settings-integrations.json +298 -0
  521. package/corpus/chunks/settings-members-invite.json +112 -0
  522. package/corpus/chunks/settings-notification-activity-checkboxes.json +108 -0
  523. package/corpus/chunks/settings-notification-channels-switches.json +101 -0
  524. package/corpus/chunks/settings-page-shell.json +190 -0
  525. package/corpus/chunks/settings-privacy.json +83 -0
  526. package/corpus/chunks/settings-profile-security.json +122 -0
  527. package/corpus/chunks/settings-toggle-switches.json +66 -0
  528. package/corpus/chunks/sidebar-nav.json +120 -0
  529. package/corpus/chunks/sidebar-navigation-panel.json +165 -0
  530. package/corpus/chunks/signup-form-card.json +218 -0
  531. package/corpus/chunks/signup-team-size-form.json +259 -0
  532. package/corpus/chunks/single-select-card-form.json +231 -0
  533. package/corpus/chunks/slider-range-controls.json +119 -0
  534. package/corpus/chunks/social-media-post-card.json +159 -0
  535. package/corpus/chunks/sortable-list.json +307 -0
  536. package/corpus/chunks/sortable-search-paginate-table.json +162 -0
  537. package/corpus/chunks/split-pane-editor.json +146 -0
  538. package/corpus/chunks/stack-avatar-badge-overlay.json +53 -0
  539. package/corpus/chunks/stack-image-shimmer.json +51 -0
  540. package/corpus/chunks/stat-cards-kpi-dashboard.json +178 -0
  541. package/corpus/chunks/stats-band-big-numbers.json +175 -0
  542. package/corpus/chunks/status-dashboard.json +282 -0
  543. package/corpus/chunks/stepper-form-wizard.json +165 -0
  544. package/corpus/chunks/subscription-status-renewal-card.json +285 -0
  545. package/corpus/chunks/survey-rating-form.json +165 -0
  546. package/corpus/chunks/swiper-product-carousel.json +349 -0
  547. package/corpus/chunks/swiper-testimonial-carousel.json +279 -0
  548. package/corpus/chunks/table-empty-state.json +116 -0
  549. package/corpus/chunks/table-inline-edit-row.json +269 -0
  550. package/corpus/chunks/table-spreadsheet-cells.json +334 -0
  551. package/corpus/chunks/table-toolbar-no-search.json +42 -0
  552. package/corpus/chunks/table-toolbar-with-table.json +208 -0
  553. package/corpus/chunks/table-with-toolbar-card.json +80 -0
  554. package/corpus/chunks/tabs-with-panels.json +187 -0
  555. package/corpus/chunks/tag-chips-filter.json +100 -0
  556. package/corpus/chunks/team-invite-form.json +380 -0
  557. package/corpus/chunks/team-members-list.json +341 -0
  558. package/corpus/chunks/testimonial-grid.json +269 -0
  559. package/corpus/chunks/testimonial-pull-quote.json +137 -0
  560. package/corpus/chunks/testimonials-avatar-cards.json +286 -0
  561. package/corpus/chunks/timeline-events.json +89 -0
  562. package/corpus/chunks/timezone-selector-basic.json +99 -0
  563. package/corpus/chunks/timezone-selector-preview.json +104 -0
  564. package/corpus/chunks/toolbar-icons.json +216 -0
  565. package/corpus/chunks/toolbar-rich-text-editor.json +230 -0
  566. package/corpus/chunks/toolbar-tooltips.json +191 -0
  567. package/corpus/chunks/tooltip-hover-button.json +106 -0
  568. package/corpus/chunks/tree-file-explorer.json +136 -0
  569. package/corpus/chunks/tree-table-basic.json +171 -0
  570. package/corpus/chunks/trial-banner.json +158 -0
  571. package/corpus/chunks/url-import-form.json +728 -0
  572. package/corpus/chunks/usage-quota-meter-card.json +217 -0
  573. package/corpus/chunks/user-identity-row.json +81 -0
  574. package/corpus/chunks/user-onboarding-checklist.json +301 -0
  575. package/corpus/chunks/user-profile-card.json +192 -0
  576. package/corpus/chunks/users-table-badge.json +135 -0
  577. package/corpus/chunks/verification-document-upload.json +179 -0
  578. package/corpus/chunks/verification-status.json +97 -0
  579. package/corpus/chunks/verification-stepper.json +111 -0
  580. package/corpus/chunks/video-player-controls.json +120 -0
  581. package/corpus/chunks/webhook-config.json +209 -0
  582. package/corpus/chunks/webhooks-list.json +204 -0
  583. package/corpus/chunks/wizard-drawer-three-step-wizard.json +443 -0
  584. package/corpus/manifest.d.ts +4 -0
  585. package/corpus/manifest.json +6 -0
  586. package/corpus/scripts/chunk-library.d.ts +4 -0
  587. package/corpus/scripts/chunk-library.js +335 -0
  588. package/node-shims.d.ts +48 -0
  589. package/package.json +215 -0
  590. package/retrieval/CHANGELOG.md +1073 -0
  591. package/retrieval/README.md +71 -0
  592. package/retrieval/anti-patterns.js +189 -0
  593. package/retrieval/authoring/index.d.ts +4 -0
  594. package/retrieval/authoring/index.js +9 -0
  595. package/retrieval/authoring/web-research.js +220 -0
  596. package/retrieval/catalog.js +250 -0
  597. package/retrieval/component-catalog.js +168 -0
  598. package/retrieval/component-entry.js +80 -0
  599. package/retrieval/context-assembler.js +174 -0
  600. package/retrieval/domain-router.js +417 -0
  601. package/retrieval/embedding/chunk-embedding-retriever.js +117 -0
  602. package/retrieval/embedding/embedding-provider.js +72 -0
  603. package/retrieval/embedding/index.d.ts +4 -0
  604. package/retrieval/embedding/index.js +2 -0
  605. package/retrieval/feedback/dialog-recorder.js +107 -0
  606. package/retrieval/feedback/feedback-analyzer.js +180 -0
  607. package/retrieval/feedback/feedback-store.js +194 -0
  608. package/retrieval/feedback/feedback.js +117 -0
  609. package/retrieval/feedback/gap-registry.js +80 -0
  610. package/retrieval/feedback/human-signal.js +113 -0
  611. package/retrieval/feedback/index.d.ts +4 -0
  612. package/retrieval/feedback/index.js +24 -0
  613. package/retrieval/feedback/submit-feedback.js +45 -0
  614. package/retrieval/index.d.ts +4 -0
  615. package/retrieval/index.js +53 -0
  616. package/retrieval/intent/clarity.js +139 -0
  617. package/retrieval/intent/decomposer.js +124 -0
  618. package/retrieval/intent/index.d.ts +4 -0
  619. package/retrieval/intent/index.js +18 -0
  620. package/retrieval/intent/intent-alignment.js +172 -0
  621. package/retrieval/intent/intent-categorizer.js +69 -0
  622. package/retrieval/intent/intent-gate.js +96 -0
  623. package/retrieval/intent/prompt-analyzer.js +162 -0
  624. package/retrieval/wiring-catalog.js +168 -0
  625. package/validate/catalog-validator.d.ts +4 -0
  626. package/validate/catalog-validator.js +327 -0
  627. package/validate/semantic/cache.js +54 -0
  628. package/validate/semantic/classify-intent.js +128 -0
  629. package/validate/semantic/index.js +163 -0
  630. package/validate/semantic/intent-specs.js +162 -0
  631. package/validate/semantic/judge.js +180 -0
@@ -0,0 +1,602 @@
1
+ /**
2
+ * generate_ui — UI generation from natural language intent.
3
+ *
4
+ * Four modes:
5
+ * instant — pattern matching, no LLM (synchronous)
6
+ * pro — pattern search + LLM adaptation (async, blocking)
7
+ * thinking — A003 intelligence + LLM adapter (async, blocking)
8
+ * stream — same as thinking but yields progressive updates via async generator
9
+ *
10
+ * Multi-turn: pass executionId from a previous run to iterate on the same surface.
11
+ * The previous A2UI output is fed back as assistant context so the LLM can refine.
12
+ */
13
+
14
+ import { validateSchema } from '@adia-ai/a2ui/validate';
15
+ import { getContext, searchBlocks, searchBlocksSemantic, lookupDomain, listPatterns } from './reference.js';
16
+ import { store, engine } from './state.js';
17
+ import { checkIntentAlignment } from '../../retrieval/intent/intent-alignment.js';
18
+ import { decomposeIntent, composeSubtasks } from '../../retrieval/intent/decomposer.js';
19
+ import { getWiringCatalog } from '../../retrieval/wiring-catalog.js';
20
+
21
+ import { StubLLMAdapter } from '@adia-ai/llm/stub';
22
+ import { createAdapter } from '@adia-ai/llm/bridge';
23
+ import { assessClarity } from '../../retrieval/intent/clarity.js';
24
+ import { isConversational } from '../../retrieval/intent/intent-gate.js';
25
+ import { classifyIntent } from '../../retrieval/domain-router.js';
26
+ import { researchIntent, detectReferences } from '../../retrieval/authoring/web-research.js';
27
+ import { feedbackStore } from '../../retrieval/feedback/feedback-store.js';
28
+ import { pick as pickEngine, registerMonolithicEngines } from '../strategies/registry.js';
29
+ import { analyzePrompt } from '../../retrieval/intent/prompt-analyzer.js';
30
+ import { recordTurn, isRecording } from '../../retrieval/feedback/dialog-recorder.js';
31
+ import {
32
+ buildSystemPrompt,
33
+ buildChatMessages,
34
+ tryParsePartial,
35
+ mergeCanvasDiff,
36
+ buildCanvasDiffPrompt,
37
+ parseA2UIResponse,
38
+ buildRepairPrompt,
39
+ generateSuggestions,
40
+ foldInAntiPatterns,
41
+ } from '../strategies/monolithic/_shared.js';
42
+ import { validateAndRepair } from '../shared/validate-and-repair.js';
43
+ import { generateInstant } from '../strategies/monolithic/generate-instant.js';
44
+ import { generatePro } from '../strategies/monolithic/generate-pro.js';
45
+ import { generateThinking } from '../strategies/monolithic/generate-thinking.js';
46
+
47
+
48
+ /**
49
+ * Generate a UI surface from a natural language intent.
50
+ *
51
+ * @param {object} opts
52
+ * @param {string} opts.intent — Natural language intent
53
+ * @param {'instant'|'pro'|'thinking'|'stream'} [opts.mode='instant'] — Generation mode
54
+ * @param {string} [opts.executionId] — Existing execution ID (for multi-turn iteration)
55
+ * @param {object} [opts.currentCanvas] — Client-owned canvas state, enables
56
+ * stateless iteration. Shape is a discriminated union:
57
+ * { components: A2UIComponent[] } — flat component array
58
+ * { messages: A2UIMessage[] } — full message sequence
59
+ * When provided, the pipeline uses this as the iteration baseline instead
60
+ * of looking up prior turns in the ArtifactStore. This makes generation
61
+ * stateless — the client can iterate across server restarts, multiple tabs,
62
+ * or from a saved-canvas JSON file. Backward compatible: if omitted, the
63
+ * store lookup via `executionId` still works.
64
+ * @param {object} [opts.llmAdapter] — LLM adapter (defaults to auto-detected)
65
+ * @param {object} [opts.context] — Ontology context parsed by plan_app_state:
66
+ * the four-block shape { intent, domain, tasks, experience } validated by
67
+ * @adia-ai/mcp's gen-ui surface's ontologyContextSchema (REQ-03, gh#1208). Only
68
+ * domain.entities, domain.metrics, tasks.primary, experience.mode, and
69
+ * experience.shell are currently interpolated into the monolithic system
70
+ * prompt (strategies/monolithic/_shared.js); intent.* and tasks.inspection
71
+ * validate but are not yet read downstream (gh#1208 review finding 4/6).
72
+ * @returns {Promise<{ executionId: string, messages: object[], validation: object, suggestions: string[] }>}
73
+ */
74
+ export async function generateUI({ intent, engine: engineName = 'monolithic', mode = 'instant', executionId, currentCanvas, llmAdapter, model, sessionId, context }) {
75
+ // Iteration signal: either an executionId (server-stateful path) OR a
76
+ // currentCanvas (client-stateless path). Both mean "refine existing UI".
77
+ const hasClientCanvas = !!(currentCanvas && (currentCanvas.components?.length || currentCanvas.messages?.length));
78
+ const isIteration = !!executionId || hasClientCanvas;
79
+
80
+ // ── Intent gate: reject non-UI prompts before entering the pipeline ──
81
+ // This prevents the LLM from hallucinating UIs from vague/abstract text.
82
+ // EXCEPTION: skip the gate on iteration turns. Modifiers like "make it 3D",
83
+ // "remove the avatar", "try a rose theme" rarely contain UI nouns the gate
84
+ // recognizes — they're refinements of the prior canvas, not fresh intents.
85
+ if (!isIteration) {
86
+ const classification = classifyIntent(intent);
87
+ const intentCheck = isConversational(intent, classification);
88
+ if (intentCheck.conversational) {
89
+ const clarity = assessClarity(intent, classification);
90
+ return {
91
+ executionId: executionId || 'rejected',
92
+ messages: [],
93
+ validation: { score: 0, valid: false, errors: [`Intent rejected: ${intentCheck.reason}`] },
94
+ suggestions: clarity.questions.map(q => q.text),
95
+ rejected: true,
96
+ reason: intentCheck.reason,
97
+ };
98
+ }
99
+ }
100
+
101
+ // For multi-turn: keep the old executionId for artifact history,
102
+ // but always start a fresh pipeline execution for stage tracking.
103
+ const previousExecId = executionId;
104
+ executionId = engine.start({ intent, mode, previousExecId });
105
+
106
+ // ── Engine dispatch (Phase 5) ──
107
+ // Zettel engine: single mode (instant), fragment-graph composition.
108
+ // Monolithic engine: three modes (instant | pro | thinking | stream→thinking).
109
+ // Analyzer is BASELINE for every reasoning level — every mode gets an LLM
110
+ // adapter (instant included). The analyzer call adds ~1-2s to the floor but
111
+ // the structured signals it produces (steelman, concepts, impliedComponents)
112
+ // dramatically improve downstream pattern retrieval and LLM generation
113
+ // quality. Adapter is always created upfront so all modes can analyze.
114
+ const effectiveMode = mode === 'stream' ? 'thinking' : mode;
115
+ const adapter = llmAdapter || await createAdapter({ model });
116
+
117
+ // ── Stage 0: Prompt Analysis (baseline ingestion) ──
118
+ // Extract structured signals from the raw prompt so every downstream stage
119
+ // — pattern search, concept-mapping retrieval, system prompt construction
120
+ // — reasons against an enriched brief instead of the raw text.
121
+ // Skipped on iteration turns where the user's modifier ("make it 3D") is
122
+ // most useful as-is for the LLM iteration prompt.
123
+ let analysis = null;
124
+ if (!isIteration) {
125
+ analysis = await analyzePrompt({ intent, llmAdapter: adapter });
126
+ }
127
+
128
+ // ── Normalize currentCanvas into a uniform priorComponents array ──
129
+ // Engines consume a single array; the shape union is collapsed here so
130
+ // engine code doesn't branch on input form.
131
+ let priorComponentsFromPayload = null;
132
+ if (hasClientCanvas) {
133
+ if (Array.isArray(currentCanvas.components)) {
134
+ priorComponentsFromPayload = currentCanvas.components;
135
+ } else if (Array.isArray(currentCanvas.messages)) {
136
+ priorComponentsFromPayload = currentCanvas.messages.flatMap(m => m?.components || []);
137
+ }
138
+ }
139
+
140
+ const fn = pickEngine({ engine: engineName, mode: effectiveMode });
141
+ const t0 = Date.now();
142
+ const result = await fn({
143
+ intent,
144
+ executionId,
145
+ storeId: previousExecId || executionId,
146
+ llmAdapter: adapter,
147
+ sessionId,
148
+ analysis,
149
+ priorComponentsFromPayload,
150
+ context, // Pass the ontology context to the engine
151
+ });
152
+ const totalMs = Date.now() - t0;
153
+
154
+ // ── Dialog recording (fire-and-forget, gated by ADIA_LOG_DIALOGS) ──
155
+ // Captures the entire turn — intent, analysis, system prompt, raw LLM
156
+ // response, parsed messages, validation, drift, telemetry — to disk for
157
+ // debugging, regression analysis, and training-data bootstrapping. The
158
+ // recorder no-ops when the env var is unset; the engine's _debug payload
159
+ // is also only populated when recording is on (see generate-pro.js).
160
+ if (isRecording()) {
161
+ const debug = result._debug || {};
162
+ // Anything the engine put on _debug beyond the canonical fields lands
163
+ // in engineDebug — useful for engine-specific reasoning (zettel strategy
164
+ // / composition / fragmentsUsed; instant patternName / strategy).
165
+ const { systemPrompt, rawLLMResponse, tokens, patterns, ...engineDebug } = debug;
166
+ recordTurn({
167
+ sessionId: previousExecId || result.executionId || null,
168
+ intent,
169
+ mode: effectiveMode,
170
+ engine: engineName,
171
+ model: model || null,
172
+ analysis,
173
+ currentCanvas: hasClientCanvas ? currentCanvas : null,
174
+ patterns: patterns || [],
175
+ systemPrompt: systemPrompt || null,
176
+ rawLLMResponse: rawLLMResponse || null,
177
+ messages: result.messages || [],
178
+ validation: result.validation || null,
179
+ drift: result.drift || null,
180
+ suggestions: result.suggestions || [],
181
+ timing: { totalMs },
182
+ tokens: tokens || null,
183
+ engineDebug: Object.keys(engineDebug).length ? engineDebug : null,
184
+ isIteration,
185
+ }).catch(() => { /* logger swallows internally; this is just last-resort */ });
186
+ }
187
+
188
+ // Strip the _debug payload before returning — it's an internal collaboration
189
+ // channel between engines and the recorder, not part of the public API.
190
+ // Without this strip the proxy would echo a 12KB+ system prompt to clients.
191
+ //
192
+ // Compose-trace flag: A2UI_COMPOSE_TRACE=<dir> writes the full debug payload
193
+ // (system prompt, raw LLM response, retrieval log, strategy decisions) to
194
+ // a per-request JSON file BEFORE the strip. Useful for debugging
195
+ // strategy-label decisions or reproducing eval failures. Off by default;
196
+ // file writes happen synchronously and add ~1-5ms per request.
197
+ //
198
+ // Node-only: `process` is undefined in the browser. Guard the env lookup
199
+ // so the post-await codepath doesn't throw `ReferenceError: process is
200
+ // not defined` when generator.js runs in the gen-ui playground. The
201
+ // dynamic node:fs/path imports below would also fail in the browser, but
202
+ // the guard short-circuits before we get there.
203
+ const IS_NODE = typeof process !== 'undefined' && process.versions?.node;
204
+ const traceDir = IS_NODE ? process.env.A2UI_COMPOSE_TRACE : null;
205
+ if (traceDir && result._debug) {
206
+ try {
207
+ const { writeFile, mkdir } = await import('node:fs/promises');
208
+ const { join: pathJoin } = await import('node:path');
209
+ await mkdir(traceDir, { recursive: true });
210
+ const ts = new Date().toISOString().replace(/[:.]/g, '-');
211
+ const safeIntent = String(intent || 'unknown').slice(0, 40).replace(/[^a-zA-Z0-9_-]/g, '_');
212
+ const tracePath = pathJoin(traceDir, `${ts}-${engineName}-${safeIntent}.json`);
213
+ await writeFile(tracePath, JSON.stringify({
214
+ timestamp: ts,
215
+ intent,
216
+ engine: engineName,
217
+ mode: effectiveMode,
218
+ executionId: result.executionId,
219
+ strategy: result.strategy || null,
220
+ validation: result.validation || null,
221
+ messageCount: result.messages?.length || 0,
222
+ debug: result._debug,
223
+ }, null, 2));
224
+ } catch (err) {
225
+ // Tracing is diagnostic — never let it break the request path.
226
+ console.error('[compose:trace] failed to write trace:', err.message);
227
+ }
228
+ }
229
+ if (result._debug) delete result._debug;
230
+ return result;
231
+ }
232
+
233
+ /**
234
+ * Streaming UI generation — yields progressive events as the LLM generates.
235
+ *
236
+ * Events:
237
+ * { type: 'status', stage, message } — pipeline stage transition
238
+ * { type: 'clarify', questions, score, dimensions } — intent needs clarification (consumer should pause)
239
+ * { type: 'text_delta', text, snapshot } — raw LLM text chunk
240
+ * { type: 'partial', messages } — parseable partial A2UI (render immediately)
241
+ * { type: 'complete', messages, validation, suggestions, executionId } — final result
242
+ * { type: 'error', error } — generation error
243
+ *
244
+ * @param {object} opts
245
+ * @param {string} opts.intent
246
+ * @param {string} [opts.executionId]
247
+ * @param {object} [opts.llmAdapter]
248
+ * @param {(query: string) => Promise<{ results: { title: string, snippet: string, url: string }[] }>} [opts.search] — Web search function
249
+ * @param {object} [opts.context] — Ontology context parsed by plan_app_state:
250
+ * the four-block shape { intent, domain, tasks, experience } validated by
251
+ * @adia-ai/mcp's gen-ui surface's ontologyContextSchema (REQ-03, gh#1208). Only
252
+ * domain.entities, domain.metrics, tasks.primary, experience.mode, and
253
+ * experience.shell are currently interpolated into the monolithic system
254
+ * prompt (strategies/monolithic/_shared.js); intent.* and tasks.inspection
255
+ * validate but are not yet read downstream (gh#1208 review finding 4/6).
256
+ * @yields {object}
257
+ */
258
+ export async function* generateUIStream({ intent, executionId, llmAdapter, model, search, currentCanvas, context }) {
259
+ // currentCanvas accepted for API parity with generateUI. The streaming
260
+ // path's downstream consumers don't yet read it, but parity prevents the
261
+ // client from having to branch its call shape per mode. Tier-2 will
262
+ // wire it through the same way generatePro does.
263
+ void currentCanvas;
264
+ // ── Intent gate: reject non-UI prompts before entering the pipeline ──
265
+ // Same iteration bypass as generateUI() — modifiers don't need to clear the
266
+ // conversational gate when there's a prior turn to refine.
267
+ const isIteration = !!executionId;
268
+ if (!isIteration) {
269
+ const classification = classifyIntent(intent);
270
+ const intentCheck = isConversational(intent, classification);
271
+ if (intentCheck.conversational) {
272
+ const clarity = assessClarity(intent, classification);
273
+ yield {
274
+ type: 'clarify',
275
+ questions: clarity.questions.length > 0
276
+ ? clarity.questions
277
+ : [{ text: 'What would you like me to build?', dimension: 'domain', priority: 1 }],
278
+ score: clarity.score,
279
+ dimensions: clarity.dimensions,
280
+ summary: `Not a UI request (${intentCheck.reason}). ${clarity.summary}`,
281
+ rejected: true,
282
+ reason: intentCheck.reason,
283
+ };
284
+ return; // Do NOT continue to generation pipeline
285
+ }
286
+ }
287
+
288
+ const adapter = llmAdapter || await createAdapter({ model });
289
+ // For multi-turn: keep the old executionId for artifact history lookup,
290
+ // but always start a fresh pipeline execution for stage tracking.
291
+ const previousExecId = executionId;
292
+ executionId = engine.start({ intent, mode: 'stream', previousExecId });
293
+
294
+ // ── Stage 1: Interpret ──
295
+ // Include confidence + matched signals in the status message so a reader can
296
+ // distinguish a strong domain match from a 3% tie-breaker. The bare label
297
+ // "Domain: data" is indistinguishable between "build a data dashboard" (high
298
+ // confidence, many signals) and "tier pricing page" (0.03 confidence, one
299
+ // weak signal) — same text, very different reliability.
300
+ const domain = lookupDomain(intent);
301
+ engine.submitStage(executionId, 'interpret', { domain, intent, confidence: domain.confidence });
302
+ const conf = domain.confidence != null ? Math.round(domain.confidence * 100) : null;
303
+ const signals = Array.isArray(domain.matchedSignals) && domain.matchedSignals.length
304
+ ? domain.matchedSignals.slice(0, 4)
305
+ : null;
306
+ yield {
307
+ type: 'status',
308
+ stage: 'interpret',
309
+ message: `Domain: ${domain.domain}${conf != null ? ` (${conf}% confidence)` : ''}`,
310
+ outcomes: signals ? [`Matched signals: ${signals.join(', ')}`] : [],
311
+ };
312
+
313
+ // ── Clarity gate: yield clarify event if intent is vague ──
314
+ // Only for fresh intents (not multi-turn iterations which have prior context)
315
+ if (!previousExecId) {
316
+ const clarity = assessClarity(intent, domain);
317
+ if (!clarity.clear && clarity.questions.length > 0) {
318
+ yield {
319
+ type: 'clarify',
320
+ questions: clarity.questions,
321
+ score: clarity.score,
322
+ dimensions: clarity.dimensions,
323
+ summary: clarity.summary,
324
+ };
325
+ // The consumer decides whether to pause or continue.
326
+ // If they continue iterating, generation proceeds with what we have.
327
+ // If they stop iterating and re-submit with more detail, a new stream starts.
328
+ }
329
+ }
330
+
331
+ // ── Stage 2: Analyze ──
332
+ // Surface the actual top-N retrieval candidates with scores. Two reasons the
333
+ // previous `${...patterns.length} patterns` line was misleading:
334
+ // (a) `getContext(intent, 2)` runs at tier=2, but the context-assembler
335
+ // only populates `result.patterns` at tier≥3 — so `context.patterns`
336
+ // was STRUCTURALLY empty. "0 patterns" wasn't a retrieval result; it
337
+ // was a tier mismatch. Fixed by running a fast keyword search here.
338
+ // (b) The synthesizer composes from below-threshold patterns too; "0
339
+ // patterns" reading as "nothing relevant" actively misleads the user.
340
+ const catalogContext = await getContext(intent, 2);
341
+ const topPatternsRaw = searchBlocks(intent).slice(0, 5);
342
+ const candidateLines = topPatternsRaw.length
343
+ ? topPatternsRaw.map(p => {
344
+ const score = p.score != null ? ` · ${Number(p.score).toFixed(2)}` : '';
345
+ const domainTag = p.domain ? ` (${p.domain})` : '';
346
+ return ` • ${p.name}${domainTag}${score}`;
347
+ })
348
+ : [' (no keyword match — synthesizer will compose from components)'];
349
+ engine.submitStage(executionId, 'analyze', {
350
+ context: catalogContext, componentCount: catalogContext.components.length, patternCount: topPatternsRaw.length,
351
+ topPatterns: topPatternsRaw.map(p => ({ name: p.name, score: p.score, domain: p.domain })),
352
+ confidence: catalogContext.components.length > 0 ? 0.85 : 0.5,
353
+ });
354
+ yield {
355
+ type: 'status',
356
+ stage: 'analyze',
357
+ message: `${catalogContext.components.length} components inspected · ${topPatternsRaw.length} pattern candidate${topPatternsRaw.length === 1 ? '' : 's'}`,
358
+ outcomes: ['Top retrievals:', ...candidateLines],
359
+ };
360
+
361
+ // ── Research: web search enrichment (optional) ──
362
+ let researchContext = '';
363
+ const { references } = detectReferences(intent);
364
+ if (references.length > 0 || search) {
365
+ yield { type: 'status', stage: 'research', message: references.length > 0 ? `Researching: ${references.join(', ')}` : 'Searching for patterns...' };
366
+ try {
367
+ const research = await researchIntent(intent, { search, llmAdapter: adapter });
368
+ researchContext = research.context;
369
+ if (research.references.length > 0) {
370
+ yield { type: 'research', references: research.references, insights: research.insights };
371
+ }
372
+ } catch {
373
+ // Research failed — continue without it
374
+ }
375
+ }
376
+
377
+ // ── Stage 3: Plan ──
378
+ // Use semantic search in LLM modes — feeds pattern index to LLM for conceptual matching
379
+ const { matches: patterns, remix: remixSuggestion } = await searchBlocksSemantic(intent, { llmAdapter: adapter, remix: true });
380
+ engine.submitStage(executionId, 'plan', {
381
+ patterns: patterns.map(p => p.name),
382
+ strategy: patterns.length > 0 ? 'adapt-pattern' : 'generate-fresh',
383
+ confidence: patterns.length > 0 ? 0.9 : 0.7,
384
+ hasRemix: !!remixSuggestion,
385
+ });
386
+ yield { type: 'status', stage: 'plan', message: patterns.length > 0 ? `Adapting: ${patterns[0].name}${remixSuggestion ? ' (with remix)' : ''}` : 'Generating fresh' };
387
+
388
+ // ── Decomposition: split complex intents into subtasks ──
389
+ // Skip decomposition when a pattern match exists — the pattern already handles composition
390
+ const decomposition = patterns.length === 0 ? decomposeIntent(intent) : { shouldDecompose: false, subtasks: [], layout: null, original: intent };
391
+ if (decomposition.shouldDecompose && decomposition.subtasks.length >= 3) {
392
+ yield { type: 'status', stage: 'decompose', message: `Splitting into ${decomposition.subtasks.length} subtasks: ${decomposition.subtasks.map(s => s.label).join(', ')}` };
393
+ yield { type: 'decompose', subtasks: decomposition.subtasks, layout: decomposition.layout };
394
+
395
+ // Generate each subtask independently
396
+ const subtaskResults = [];
397
+ for (const subtask of decomposition.subtasks) {
398
+ yield { type: 'status', stage: 'generate', message: `Generating: ${subtask.label}...` };
399
+ try {
400
+ const subResult = await adapter.complete({
401
+ messages: [{ role: 'user', content: subtask.intent }],
402
+ systemPrompt: await buildSystemPrompt(catalogContext, patterns, researchContext, intent, null, context),
403
+ });
404
+ const subMessages = parseA2UIResponse(subResult.content, { executionId, mode: 'stream', intent: subtask.intent });
405
+ subtaskResults.push({ label: subtask.label, messages: subMessages });
406
+ } catch {
407
+ // Failed subtask — skip it
408
+ subtaskResults.push({ label: subtask.label, messages: [{ type: 'updateComponents', surfaceId: 'default', components: [{ id: 'root', component: 'Text', variant: 'body', textContent: `${subtask.label} (generation failed)` }] }] });
409
+ }
410
+ }
411
+
412
+ // Compose into layout
413
+ const composed = composeSubtasks(decomposition.layout, subtaskResults);
414
+
415
+ engine.submitStage(executionId, 'generate', {
416
+ messages: composed, source: 'decomposed', decomposed: true,
417
+ subtasks: decomposition.subtasks.length, confidence: 0.8,
418
+ });
419
+
420
+ const composedValidation = validateSchema(composed, { intent, context });
421
+
422
+ engine.submitStage(executionId, 'validate', {
423
+ ...composedValidation, confidence: composedValidation.score / 100,
424
+ });
425
+
426
+ // Alignment check
427
+ const alignment = checkIntentAlignment(intent, composed[0]?.components || []);
428
+
429
+ const storeId = previousExecId || executionId;
430
+ store.record(storeId, { messages: composed, summary: intent, validation: composedValidation, intent });
431
+ engine.submitStage(executionId, 'render', { stored: true, decomposed: true, subtasks: decomposition.subtasks.length });
432
+
433
+ // Fire-and-forget feedback logging (decomposed stream)
434
+ feedbackStore.logExecution({
435
+ executionId: storeId, intent, mode: 'stream',
436
+ domain: domain.domain, patternMatch: null,
437
+ score: composedValidation?.score, componentCount: composed[0]?.components?.length || 0,
438
+ }).catch(() => {});
439
+
440
+ yield {
441
+ type: 'complete',
442
+ executionId: storeId,
443
+ messages: composed,
444
+ validation: composedValidation,
445
+ alignment,
446
+ suggestions: generateSuggestions(intent, domain, composed),
447
+ pipeline: engine.getState(executionId),
448
+ };
449
+ return;
450
+ }
451
+
452
+ // ── Stage 4: Generate via LLM stream ──
453
+ const systemPrompt = await buildSystemPrompt(catalogContext, patterns, researchContext, intent, null, context);
454
+ const chatMessages = buildChatMessages(intent, previousExecId || executionId);
455
+
456
+ yield { type: 'status', stage: 'generate', message: 'Streaming from LLM...' };
457
+
458
+ let fullText = '';
459
+ let lastPartialRender = '';
460
+
461
+ try {
462
+ if (typeof adapter.stream === 'function') {
463
+ for await (const chunk of adapter.stream({ messages: chatMessages, systemPrompt })) {
464
+ if (chunk.type === 'text') {
465
+ fullText += chunk.content;
466
+ yield { type: 'text_delta', text: chunk.content, snapshot: fullText };
467
+
468
+ // Try to parse partial JSON and render incrementally
469
+ const partial = tryParsePartial(fullText);
470
+ if (partial && JSON.stringify(partial) !== lastPartialRender) {
471
+ lastPartialRender = JSON.stringify(partial);
472
+ yield { type: 'partial', messages: partial };
473
+ }
474
+ }
475
+ }
476
+ } else {
477
+ // Fallback: non-streaming adapter
478
+ const response = await adapter.complete({ messages: chatMessages, systemPrompt });
479
+ fullText = response.content;
480
+ yield { type: 'text_delta', text: fullText, snapshot: fullText };
481
+ }
482
+ } catch (err) {
483
+ yield { type: 'error', error: err };
484
+ return;
485
+ }
486
+
487
+ // ── Stage 5: Parse final + validate ──
488
+ let messages = parseA2UIResponse(fullText, { executionId, mode: 'stream', intent });
489
+ engine.submitStage(executionId, 'generate', {
490
+ messages, source: 'llm-stream', confidence: 0.8,
491
+ });
492
+
493
+ // gh#583 (GK-3): this used to be a hand-rolled ONE-shot repair calling
494
+ // `adapter.complete()` directly and re-running only `validateSchema` — it
495
+ // never ran the catalog check, so a schema-valid-but-catalog-invalid
496
+ // candidate (unknown component, prop the YAML contract doesn't declare)
497
+ // could reach the wire from this streaming path alone, unlike every other
498
+ // engine (see validate-and-repair.js's docstring: this generator was the
499
+ // only one skipping it). Routing through the shared loop closes that gap
500
+ // and gets the same bounded multi-attempt retry every other LLM-calling
501
+ // engine already has, instead of exactly one attempt.
502
+ const repairResult = await validateAndRepair({
503
+ messages,
504
+ llmAdapter: adapter,
505
+ buildRepairPrompt,
506
+ parseResponse: (repairResponse) => parseA2UIResponse(
507
+ repairResponse.content,
508
+ { executionId, mode: 'stream', intent },
509
+ ),
510
+ systemPrompt,
511
+ validateContext: { intent, context },
512
+ foldInAntiPatterns,
513
+ maxAttempts: 3,
514
+ onAttempt: () => {
515
+ // No dialog-recorder hook here (unlike generate-thinking.js) — the
516
+ // streaming path already emits its own `text_delta`/`partial` events
517
+ // as the primary trace surface; adding a second capture point would
518
+ // duplicate, not improve, that record.
519
+ },
520
+ });
521
+ messages = repairResult.messages;
522
+ let validation = repairResult.validation;
523
+ if (repairResult.attempts > 0) {
524
+ yield { type: 'status', stage: 'validate', message: `Score ${validation.score}/100 — repaired in ${repairResult.attempts} attempt(s)` };
525
+ }
526
+
527
+ engine.submitStage(executionId, 'validate', {
528
+ ...validation, confidence: validation.score / 100,
529
+ });
530
+
531
+ // ── Stage 6: Store artifact ──
532
+ // Store under the previous execution ID if iterating (keeps multi-turn history together)
533
+ const storeId = previousExecId || executionId;
534
+ store.record(storeId, { messages, summary: intent, validation, intent });
535
+ engine.submitStage(executionId, 'render', { stored: true, success: validation.valid, confidence: validation.valid ? 1 : 0.5 });
536
+
537
+ // ── Intent alignment check ──
538
+ const alignment = checkIntentAlignment(intent, messages[0]?.components || []);
539
+
540
+ const suggestions = generateSuggestions(intent, domain, messages);
541
+
542
+ // Fire-and-forget feedback logging (stream mode)
543
+ feedbackStore.logExecution({
544
+ executionId: storeId, intent, mode: 'stream',
545
+ domain: domain.domain, patternMatch: patterns[0]?.name,
546
+ score: validation?.score, componentCount: messages[0]?.components?.length || 0,
547
+ }).catch(() => {});
548
+
549
+ // ── Drift detection ──
550
+ const driftMetrics = store.getDriftMetrics(storeId);
551
+
552
+ yield {
553
+ type: 'complete',
554
+ executionId: storeId,
555
+ messages,
556
+ validation,
557
+ alignment,
558
+ drift: driftMetrics,
559
+ suggestions,
560
+ pipeline: engine.getState(executionId),
561
+ };
562
+ }
563
+
564
+ // ── Pro mode (pattern-aware LLM adaptation) ─────────────────────────
565
+
566
+
567
+ // ═══════════════════════════════════════════════════════════════════════
568
+ // SYSTEM PROMPT (Feature 2: improved with card-ui rules)
569
+ // ═══════════════════════════════════════════════════════════════════════
570
+
571
+ /**
572
+ * Build a concise system prompt for the LLM with component catalog,
573
+ * card-ui content model, layout rules, and example patterns.
574
+ *
575
+ * @param {object} context — Assembled context from A003
576
+ * @param {object[]} patterns — Matched patterns from pattern library
577
+ * @returns {string}
578
+ */
579
+
580
+ /**
581
+ * Get the shared artifact store (for external inspection).
582
+ * @returns {ArtifactStore}
583
+ */
584
+ export function getArtifactStore() {
585
+ return store;
586
+ }
587
+
588
+ /**
589
+ * Get the shared pipeline engine (for external inspection).
590
+ * @returns {PipelineEngine}
591
+ */
592
+ export function getPipelineEngine() {
593
+ return engine;
594
+ }
595
+
596
+ // ── Register the three monolithic engines with the dispatcher ──
597
+ // Done at module load so the registry is ready before the first generateUI() call.
598
+ registerMonolithicEngines({
599
+ instant: generateInstant,
600
+ pro: generatePro,
601
+ thinking: generateThinking,
602
+ });