@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,4 @@
1
+ // v0.5.21 hotfix stub — TS-migration Phase 1 (568bb998d) declared this
2
+ // types: export but Phase 2 hasn't generated real declarations yet.
3
+ // Replace with real type declarations when Phase 2 lands.
4
+ export {};
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Catalog-backed structural validator — checks that every emitted A2UI
3
+ * component conforms to its catalog schema (allOf: ComponentCommon +
4
+ * CatalogComponentCommon + component-specific props, with
5
+ * unevaluatedProperties: false so unknown props are rejected).
6
+ *
7
+ * The catalog at gen-ui/corpus/catalog-a2ui_0_9.json is a freestanding
8
+ * JSON Schema draft-2020-12 document produced by scripts/build-components.mjs.
9
+ * At first use we compile one validator per component type and cache them,
10
+ * then dispatch per-component by the `component` discriminator.
11
+ *
12
+ * Load order (gh#748): the `@adia-ai/gen-ui/corpus` bare specifier first — that
13
+ * package IS the catalog and is a declared dependency, so it resolves for a
14
+ * plain npm consumer — then the in-repo/browser fallbacks (fetch, JSON import
15
+ * attributes, node fs) against the workspace-relative path.
16
+ *
17
+ * When the catalog genuinely can't load we degrade LOUDLY — one console.warn
18
+ * per session naming the lost coverage — and expose the state via
19
+ * `getCatalogStatus()` (also mirrored on
20
+ * `globalThis.__a2uiValidatorCatalogStatus` so a host/dev console can read it).
21
+ * Per-component calls still return { valid: true, skipped: true } so the
22
+ * scoring validator keeps running.
23
+ */
24
+
25
+ import Ajv2020 from 'ajv/dist/2020.js';
26
+ import addFormats from 'ajv-formats';
27
+
28
+ const IS_NODE = typeof process !== 'undefined' && !!process.versions?.node;
29
+ const CATALOG_FILE = '../corpus/catalog-a2ui_0_9.json';
30
+ // `@adia-ai/gen-ui/corpus`'s "." export IS the catalog JSON, and this package
31
+ // depends on it — so the bare specifier is the ONLY path that resolves for a
32
+ // published-tarball consumer (gh#748); the relative paths below only work in
33
+ // this repo, where workspace symlinks put corpus/ next to validator/. Held in
34
+ // a const so bundlers see a dynamic specifier and leave resolution to runtime.
35
+ const CORPUS_PACKAGE = '@adia-ai/gen-ui/corpus';
36
+
37
+ let _catalog = null;
38
+ let _ajv = null;
39
+ let _validators = null; // Map<componentName, compiledValidator>
40
+ let _loadPromise = null;
41
+ let _status = { loaded: false, degraded: false, source: null, reason: null };
42
+ let _warned = false;
43
+
44
+ function _publishStatus(next) {
45
+ _status = { ..._status, ...next };
46
+ try { globalThis.__a2uiValidatorCatalogStatus = _status; } catch { /* frozen global */ }
47
+ return _status;
48
+ }
49
+
50
+ function _warnDegraded(reason) {
51
+ _publishStatus({ loaded: false, degraded: true, source: null, reason });
52
+ if (_warned) return;
53
+ _warned = true;
54
+ console.warn(
55
+ '[catalog-validator] component catalog could not be loaded — ' +
56
+ 'catalog-backed STRUCTURAL VALIDATION IS OFF for every turn in this session ' +
57
+ '(unknown props, wrong enums and bad component names will NOT be caught). ' +
58
+ `Reason: ${reason}. Read globalThis.__a2uiValidatorCatalogStatus for details.`
59
+ );
60
+ }
61
+
62
+ function _looksLikeCatalog(json) {
63
+ return !!json && typeof json === 'object' && !!json.components;
64
+ }
65
+
66
+ /**
67
+ * Package catalog load — the published-consumer path (gh#748).
68
+ *
69
+ * `@adia-ai/gen-ui/corpus` is a real dependency of this package and its "."
70
+ * export resolves straight to catalog-a2ui_0_9.json, so this works from a
71
+ * plain `npm i @adia-ai/a2ui-validator` install with no repo layout, no
72
+ * static asset server and no bundler config. Tried FIRST; the relative-path
73
+ * chain below stays as the in-repo / browser fallback.
74
+ *
75
+ * @param {string[]} reasons — accumulator, so a total failure reports every try
76
+ * @returns {Promise<{ json: object, source: 'package'|'package-fs' }|null>}
77
+ */
78
+ async function _loadPackageCatalog(reasons) {
79
+ try {
80
+ const mod = await import(/* @vite-ignore */ CORPUS_PACKAGE, { with: { type: 'json' } });
81
+ const json = mod?.default ?? mod;
82
+ if (_looksLikeCatalog(json)) return { json, source: 'package' };
83
+ reasons.push(`${CORPUS_PACKAGE} import produced no catalog object`);
84
+ } catch (e) {
85
+ reasons.push(`${CORPUS_PACKAGE} import failed: ${e?.message || e}`);
86
+ }
87
+
88
+ if (!IS_NODE) return null;
89
+
90
+ // Node runtimes that reject JSON import attributes still resolve the
91
+ // package specifier — resolve it to a path and read the file.
92
+ try {
93
+ const { createRequire } = await import(/* @vite-ignore */ 'node:module');
94
+ const fs = await import(/* @vite-ignore */ 'node:fs/promises');
95
+ const resolved = createRequire(import.meta.url).resolve(CORPUS_PACKAGE);
96
+ const json = JSON.parse(await fs.readFile(resolved, 'utf8'));
97
+ if (_looksLikeCatalog(json)) return { json, source: 'package-fs' };
98
+ reasons.push(`${CORPUS_PACKAGE} resolved file is not a catalog`);
99
+ } catch (e) {
100
+ reasons.push(`${CORPUS_PACKAGE} resolve+read failed: ${e?.message || e}`);
101
+ }
102
+ return null;
103
+ }
104
+
105
+ async function _loadNodeCatalog() {
106
+ const fs = await import(/* @vite-ignore */ 'node:fs/promises');
107
+ const path = await import(/* @vite-ignore */ 'node:path');
108
+ const url = await import(/* @vite-ignore */ 'node:url');
109
+ const here = path.dirname(url.fileURLToPath(import.meta.url));
110
+ // gen-ui/validate → gen-ui/corpus/catalog-a2ui_0_9.json
111
+ const raw = await fs.readFile(path.resolve(here, CATALOG_FILE), 'utf8');
112
+ return JSON.parse(raw);
113
+ }
114
+
115
+ /**
116
+ * Browser catalog load.
117
+ *
118
+ * `import(json, { with: { type: 'json' } })` is the spec-correct form but
119
+ * Vite's dev server transforms JSON into a JS module served as
120
+ * `text/javascript`, which the browser's strict MIME check rejects — so under
121
+ * `npm run dev` that import ALWAYS throws. The estate's browser-JSON idiom is
122
+ * a plain fetch of the module-relative URL (retrieval/catalog.js,
123
+ * retrieval/component-catalog.js, compose/strategies/monolithic/_shared.js all
124
+ * do exactly this); a fetch is untouched by Vite's JSON transform and works on
125
+ * the static deploy too. The import-attributes path stays as a second try for
126
+ * bundlers that inline the JSON and serve no static asset.
127
+ */
128
+ async function _loadBrowserCatalog(reasons) {
129
+ try {
130
+ const res = await fetch(new URL(CATALOG_FILE, import.meta.url));
131
+ if (res.ok) {
132
+ const json = await res.json();
133
+ if (json && typeof json === 'object') {
134
+ _publishStatus({ loaded: true, degraded: false, source: 'fetch', reason: null });
135
+ return json;
136
+ }
137
+ reasons.push('fetch returned non-object JSON');
138
+ } else {
139
+ reasons.push(`fetch HTTP ${res.status}`);
140
+ }
141
+ } catch (e) {
142
+ reasons.push(`fetch failed: ${e?.message || e}`);
143
+ }
144
+
145
+ try {
146
+ const mod = await import(/* @vite-ignore */ CATALOG_FILE, { with: { type: 'json' } });
147
+ const json = mod?.default ?? null;
148
+ if (json && typeof json === 'object') {
149
+ _publishStatus({ loaded: true, degraded: false, source: 'import-attributes', reason: null });
150
+ return json;
151
+ }
152
+ reasons.push('json import produced no default export');
153
+ } catch (e) {
154
+ reasons.push(`json import failed: ${e?.message || e}`);
155
+ }
156
+
157
+ _warnDegraded(reasons.join('; '));
158
+ return null;
159
+ }
160
+
161
+ async function _loadCatalog() {
162
+ if (_catalog) return _catalog;
163
+ if (_loadPromise) return _loadPromise;
164
+ _loadPromise = (async () => {
165
+ const reasons = [];
166
+ const fromPackage = await _loadPackageCatalog(reasons);
167
+ if (fromPackage) {
168
+ _catalog = fromPackage.json;
169
+ _publishStatus({ loaded: true, degraded: false, source: fromPackage.source, reason: null });
170
+ return _catalog;
171
+ }
172
+ try {
173
+ if (IS_NODE) {
174
+ _catalog = await _loadNodeCatalog();
175
+ _publishStatus({ loaded: true, degraded: false, source: 'node-fs', reason: null });
176
+ } else {
177
+ _catalog = await _loadBrowserCatalog(reasons);
178
+ }
179
+ } catch (e) {
180
+ _catalog = null;
181
+ reasons.push(`${IS_NODE ? 'node read' : 'browser load'} failed: ${e?.message || e}`);
182
+ _warnDegraded(reasons.join('; '));
183
+ }
184
+ return _catalog;
185
+ })();
186
+ return _loadPromise;
187
+ }
188
+
189
+ function _getAjv() {
190
+ if (_ajv) return _ajv;
191
+ _ajv = new Ajv2020({
192
+ strict: false, // our schemas are authored, not hardened; silence warnings
193
+ allErrors: true, // return every violation, not just the first
194
+ verbose: false,
195
+ allowUnionTypes: true,
196
+ validateFormats: false, // formats cost compilation time and aren't strictly needed
197
+ });
198
+ addFormats(_ajv);
199
+ return _ajv;
200
+ }
201
+
202
+ async function _getValidatorFor(componentName) {
203
+ if (_validators && _validators.has(componentName)) return _validators.get(componentName);
204
+ const catalog = await _loadCatalog();
205
+ if (!catalog) return null;
206
+
207
+ if (!_validators) {
208
+ _validators = new Map();
209
+ const ajv = _getAjv();
210
+ // Register the catalog as a single addressable document; sub-schemas are
211
+ // retrieved by JSON Pointer via getSchema(). Intra-catalog `$ref`s (#/$defs/X)
212
+ // resolve naturally because the catalog IS the root.
213
+ const catalogId = catalog.$id || 'adiaui-catalog';
214
+ try {
215
+ ajv.addSchema(catalog, catalogId);
216
+ } catch (e) {
217
+ _warnDegraded(`catalog registration failed: ${e.message}`);
218
+ return null;
219
+ }
220
+
221
+ for (const name of Object.keys(catalog.components || {})) {
222
+ try {
223
+ // Get a compiled validator for the sub-schema at #/components/<name>.
224
+ // AJV resolves it against the already-registered catalog.
225
+ const validate = ajv.getSchema(`${catalogId}#/components/${name}`);
226
+ if (validate) _validators.set(name, validate);
227
+ } catch (e) {
228
+ console.warn(`[catalog-validator] skip ${name}: ${e.message}`);
229
+ }
230
+ }
231
+ }
232
+ return _validators.get(componentName) || null;
233
+ }
234
+
235
+ /**
236
+ * Validate one A2UI component object against its catalog schema.
237
+ *
238
+ * @param {object} component — A2UI component ({ id, component, ...props })
239
+ * @returns {Promise<{ valid: boolean, errors?: string[], skipped?: boolean }>}
240
+ */
241
+ export async function validateComponent(component) {
242
+ if (!component || typeof component !== 'object') {
243
+ return { valid: false, errors: ['not an object'] };
244
+ }
245
+ const typeName = component.component;
246
+ if (!typeName) return { valid: false, errors: ['missing `component` discriminator'] };
247
+
248
+ const validate = await _getValidatorFor(typeName);
249
+ if (!validate) {
250
+ // Catalog missing OR component type not in catalog → structural-only fallback.
251
+ return { valid: true, skipped: true };
252
+ }
253
+
254
+ const ok = validate(component);
255
+ if (ok) return { valid: true };
256
+
257
+ const errors = (validate.errors || []).map(e => {
258
+ const path = e.instancePath || '/';
259
+ return `${path} ${e.message}${e.params && Object.keys(e.params).length ? ` (${JSON.stringify(e.params)})` : ''}`;
260
+ });
261
+ return { valid: false, errors };
262
+ }
263
+
264
+ /**
265
+ * Validate an array of A2UI messages ({ type: 'updateComponents', components: [...] }).
266
+ * Flattens all updateComponents.components[] across messages and runs per-component validation.
267
+ *
268
+ * `catalogDegraded: true` means the catalog never loaded and NOTHING was
269
+ * structurally checked — a green `valid` there is absence of evidence, not
270
+ * evidence of absence.
271
+ *
272
+ * @returns {Promise<{ valid: boolean, totalChecked: number, failures: Array<{ id, component, errors }>, catalogDegraded: boolean }>}
273
+ */
274
+ export async function validateMessages(messages) {
275
+ const failures = [];
276
+ let totalChecked = 0;
277
+ await _loadCatalog();
278
+
279
+ for (const msg of messages || []) {
280
+ if (msg?.type !== 'updateComponents') continue;
281
+ for (const comp of msg.components || []) {
282
+ totalChecked++;
283
+ const { valid, errors, skipped } = await validateComponent(comp);
284
+ if (skipped) continue;
285
+ if (!valid) {
286
+ failures.push({
287
+ id: comp.id || '(no id)',
288
+ component: comp.component || '(no component)',
289
+ errors: errors || ['unknown validation failure'],
290
+ });
291
+ }
292
+ }
293
+ }
294
+
295
+ return {
296
+ valid: failures.length === 0,
297
+ totalChecked,
298
+ failures,
299
+ catalogDegraded: _status.degraded,
300
+ };
301
+ }
302
+
303
+ /** Diagnostics: has the catalog loaded successfully? */
304
+ export async function isCatalogLoaded() {
305
+ await _loadCatalog();
306
+ return _catalog !== null;
307
+ }
308
+
309
+ /**
310
+ * Queryable load state — hosts (dev overlays, QA probes) read this to tell
311
+ * "validated clean" apart from "validated nothing".
312
+ *
313
+ * @returns {{ loaded: boolean, degraded: boolean, source: 'package'|'package-fs'|'node-fs'|'fetch'|'import-attributes'|null, reason: string|null }}
314
+ */
315
+ export function getCatalogStatus() {
316
+ return { ..._status };
317
+ }
318
+
319
+ /** Test-only: drop caches so a fresh load path can be exercised. */
320
+ export function __resetCatalogForTests() {
321
+ _catalog = null;
322
+ _ajv = null;
323
+ _validators = null;
324
+ _loadPromise = null;
325
+ _warned = false;
326
+ _publishStatus({ loaded: false, degraded: false, source: null, reason: null });
327
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Content-hash cache for semantic verdicts.
3
+ *
4
+ * Key: (rubricVersion, intent, a2ui-hash).
5
+ * Store: one JSON file per key under evals/mcp/runs/.semantic-cache/.
6
+ *
7
+ * Phase 1 scope: read/write; no eviction. Bump rubricVersion to invalidate.
8
+ */
9
+ import { createHash } from 'node:crypto';
10
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
11
+ import { existsSync } from 'node:fs';
12
+ import { dirname, join } from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const repoRoot = join(__dirname, '..', '..', '..', '..');
17
+ const DEFAULT_DIR = join(repoRoot, 'evals', 'mcp', 'runs', '.semantic-cache');
18
+
19
+ export function hashA2UI(messages) {
20
+ const h = createHash('sha256');
21
+ h.update(JSON.stringify(messages ?? []));
22
+ return h.digest('hex').slice(0, 16);
23
+ }
24
+
25
+ export function cacheKey({ rubricVersion, intent, messages }) {
26
+ const h = createHash('sha256');
27
+ h.update(String(rubricVersion || 'v1'));
28
+ h.update('\x1f');
29
+ h.update(String(intent || ''));
30
+ h.update('\x1f');
31
+ h.update(hashA2UI(messages));
32
+ return h.digest('hex').slice(0, 32);
33
+ }
34
+
35
+ export function makeCache({ dir = DEFAULT_DIR } = {}) {
36
+ return {
37
+ dir,
38
+ async get(key) {
39
+ const p = join(dir, `${key}.json`);
40
+ if (!existsSync(p)) return null;
41
+ try {
42
+ const raw = await readFile(p, 'utf8');
43
+ return JSON.parse(raw);
44
+ } catch {
45
+ return null;
46
+ }
47
+ },
48
+ async set(key, verdict) {
49
+ await mkdir(dir, { recursive: true });
50
+ const p = join(dir, `${key}.json`);
51
+ await writeFile(p, JSON.stringify(verdict, null, 2));
52
+ },
53
+ };
54
+ }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Intent classifier — Phase 3 kickoff (semantic-validator)
3
+ *
4
+ * Spec: .claude/docs/specs/semantic-validator.md § Phase 3
5
+ *
6
+ * Two-stage classification:
7
+ *
8
+ * 1. Find the best-matching IntentSpec from the registry via regex
9
+ * 2. Score the emitted A2UI tree against the spec deterministically
10
+ *
11
+ * High-confidence matches (intent.confidence ≥ 0.9 AND verdict.certainty ≥ 0.9)
12
+ * can short-circuit the LLM judge per § 3c (hybrid).
13
+ *
14
+ * Status: kickoff — not yet wired into validateSemantics(). Use for
15
+ * shadow-compare runs (the test harness in classify-intent.test.js).
16
+ */
17
+
18
+ import { findIntentSpec } from './intent-specs.js';
19
+
20
+ /**
21
+ * Classify an intent prompt against the IntentSpec registry.
22
+ *
23
+ * @param {string} intent — natural-language prompt
24
+ * @returns {{ spec: IntentSpec | null, confidence: number }}
25
+ */
26
+ export function classifyIntent(intent) {
27
+ return findIntentSpec(intent);
28
+ }
29
+
30
+ /**
31
+ * Score an A2UI tree against an IntentSpec deterministically.
32
+ *
33
+ * Returns a SemanticVerdict-shaped object with rule-based certainty.
34
+ * The caller decides whether to skip the LLM judge based on `certainty`.
35
+ *
36
+ * @param {object} a2ui — emitted A2UI tree (root object with `nodes` or
37
+ * equivalent traversable shape)
38
+ * @param {IntentSpec} spec — the classified IntentSpec
39
+ * @returns {RuleVerdict}
40
+ */
41
+ export function scoreAgainstSpec(a2ui, spec) {
42
+ const { distinct, instances } = collectComponentTypes(a2ui);
43
+
44
+ const requiredMissing = spec.required.filter((t) => !distinct.includes(t));
45
+ const forbiddenPresent = spec.forbidden.filter((t) => distinct.includes(t));
46
+ const componentCount = instances; // total instance count (matches existing validator semantics)
47
+
48
+ // Clean pass: all required present, no forbidden, meets minComponents
49
+ const cleanPass =
50
+ requiredMissing.length === 0 &&
51
+ forbiddenPresent.length === 0 &&
52
+ componentCount >= spec.minComponents;
53
+
54
+ // Clean fail: 2+ required missing (per spec § 3c "cleanly fails")
55
+ const cleanFail = requiredMissing.length >= 2;
56
+
57
+ // Certainty: 1.0 on clean pass/fail; 0.5 on partial (ambiguous)
58
+ let certainty = 0.5;
59
+ let verdict = 'partial';
60
+ if (cleanPass) {
61
+ certainty = 1.0;
62
+ verdict = 'pass';
63
+ } else if (cleanFail) {
64
+ certainty = 1.0;
65
+ verdict = 'fail';
66
+ }
67
+
68
+ // Build a structured findings payload — useful as hints to the LLM
69
+ // judge on fall-through
70
+ return {
71
+ verdict,
72
+ certainty,
73
+ score: cleanPass ? 100 : cleanFail ? 0 : 50,
74
+ spec: spec.id,
75
+ findings: {
76
+ required_missing: requiredMissing,
77
+ forbidden_present: forbiddenPresent,
78
+ component_count: componentCount,
79
+ min_components: spec.minComponents,
80
+ },
81
+ };
82
+ }
83
+
84
+ /**
85
+ * Walk an A2UI tree and collect (a) the set of distinct component types
86
+ * and (b) the total instance count. The A2UI tree shape varies — sometimes
87
+ * flat arrays, sometimes nested under `nodes` / `children` / `body`. This
88
+ * walker handles both.
89
+ *
90
+ * @param {*} node — root or nested A2UI shape
91
+ * @returns {{ distinct: string[], instances: number }}
92
+ */
93
+ function collectComponentTypes(node) {
94
+ const distinct = new Set();
95
+ const counter = { n: 0 };
96
+ walk(node, distinct, counter);
97
+ return { distinct: Array.from(distinct), instances: counter.n };
98
+ }
99
+
100
+ function walk(node, distinct, counter) {
101
+ if (!node) return;
102
+ if (Array.isArray(node)) {
103
+ for (const item of node) walk(item, distinct, counter);
104
+ return;
105
+ }
106
+ if (typeof node !== 'object') return;
107
+ // Count instances + collect distinct
108
+ if (typeof node.component === 'string') {
109
+ distinct.add(node.component);
110
+ counter.n += 1;
111
+ } else if (typeof node.type === 'string') {
112
+ distinct.add(node.type);
113
+ counter.n += 1;
114
+ }
115
+ // Recurse children
116
+ if (node.children) walk(node.children, distinct, counter);
117
+ if (node.nodes) walk(node.nodes, distinct, counter);
118
+ if (node.body) walk(node.body, distinct, counter);
119
+ }
120
+
121
+ /**
122
+ * @typedef {object} RuleVerdict
123
+ * @property {'pass' | 'fail' | 'partial'} verdict
124
+ * @property {number} certainty — 0..1; ≥ 0.9 allows LLM-skip per § 3c
125
+ * @property {number} score — 0..100; aligned with LLM judge scale
126
+ * @property {string} spec — IntentSpec.id that produced this verdict
127
+ * @property {object} findings — required_missing / forbidden_present / counts
128
+ */
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Semantic validator — public API (Phase 1: LLM-only, shadow mode).
3
+ *
4
+ * See .claude/docs/specs/semantic-validator.md §5.2 for the SemanticVerdict shape.
5
+ * Phase 1: LLM-judge only. Hybrid rule path is Phase 3.
6
+ *
7
+ * Usage:
8
+ * import { validateSemantics } from 'packages/gen-ui/validate/semantic/index.js';
9
+ * const v = await validateSemantics({ intent, messages }, { cache: true });
10
+ */
11
+ import { cacheKey, makeCache } from './cache.js';
12
+ import { callJudge, getRubric, summarizeA2UI } from './judge.js';
13
+
14
+ function clamp(n, lo = 0, hi = 100) {
15
+ const x = Number.isFinite(n) ? n : 0;
16
+ return Math.max(lo, Math.min(hi, Math.round(x)));
17
+ }
18
+
19
+ function shapeVerdict(parsed, { rubricVersion, cost }) {
20
+ const axes = parsed?.axes || {};
21
+ const dp = axes.dominantPattern || {};
22
+ const rc = axes.requiredCapabilities || {};
23
+ const fn = axes.forbiddenNoise || {};
24
+
25
+ const dpScore = clamp(dp.score);
26
+ const rcScore = clamp(rc.score);
27
+ const fnScore = clamp(fn.score);
28
+
29
+ // Trust the judge's score if sane; otherwise recompute from axes.
30
+ let score = parsed?.score;
31
+ if (!Number.isFinite(score) || score < 0 || score > 100) {
32
+ score = Math.round(0.5 * dpScore + 0.35 * rcScore + 0.15 * fnScore);
33
+ } else {
34
+ score = clamp(score);
35
+ }
36
+
37
+ const verdictIn = String(parsed?.verdict || '').toLowerCase();
38
+ const verdict = ['aligned', 'partial', 'misaligned', 'off-topic'].includes(verdictIn)
39
+ ? verdictIn
40
+ : (() => {
41
+ if (dpScore < 15) return 'off-topic';
42
+ if (dpScore < 40 || [dpScore, rcScore, fnScore].filter((s) => s < 60).length >= 2) return 'misaligned';
43
+ if (score >= 75 && dpScore >= 75 && rcScore >= 75 && fnScore >= 75) return 'aligned';
44
+ return 'partial';
45
+ })();
46
+
47
+ return {
48
+ score,
49
+ verdict,
50
+ path: 'llm-only',
51
+ axes: {
52
+ dominantPattern: {
53
+ expected: String(dp.expected || ''),
54
+ observed: String(dp.observed || ''),
55
+ score: dpScore,
56
+ },
57
+ requiredCapabilities: {
58
+ expected: Array.isArray(rc.expected) ? rc.expected.map(String) : [],
59
+ missing: Array.isArray(rc.missing) ? rc.missing.map(String) : [],
60
+ score: rcScore,
61
+ },
62
+ forbiddenNoise: {
63
+ observed: Array.isArray(fn.observed) ? fn.observed.map(String) : [],
64
+ score: fnScore,
65
+ },
66
+ },
67
+ rationale: String(parsed?.rationale || '').slice(0, 240),
68
+ evidence: Array.isArray(parsed?.evidence) ? parsed.evidence.map(String).slice(0, 10) : [],
69
+ cost,
70
+ rubricVersion,
71
+ };
72
+ }
73
+
74
+ /**
75
+ * validateSemantics — Phase 1 implementation (LLM-only + cache).
76
+ */
77
+ export async function validateSemantics(input, opts = {}) {
78
+ const { intent, messages } = input || {};
79
+ const {
80
+ cache = true,
81
+ timeoutMs = 15000,
82
+ model,
83
+ rubricVersion = getRubric().version,
84
+ } = opts;
85
+
86
+ if (!intent || !Array.isArray(messages) || messages.length === 0) {
87
+ return {
88
+ score: 0,
89
+ verdict: 'off-topic',
90
+ path: 'llm-only',
91
+ axes: {
92
+ dominantPattern: { expected: '', observed: 'none', score: 0 },
93
+ requiredCapabilities: { expected: [], missing: [], score: 0 },
94
+ forbiddenNoise: { observed: [], score: 100 },
95
+ },
96
+ rationale: 'No messages emitted; nothing to score.',
97
+ evidence: [],
98
+ cost: { cached: false, latencyMs: 0 },
99
+ rubricVersion,
100
+ error: 'no-messages',
101
+ };
102
+ }
103
+
104
+ const key = cacheKey({ rubricVersion, intent, messages });
105
+ const store = cache ? makeCache() : null;
106
+
107
+ if (store) {
108
+ const hit = await store.get(key);
109
+ if (hit) {
110
+ return { ...hit, cost: { ...(hit.cost || {}), cached: true } };
111
+ }
112
+ }
113
+
114
+ const summary = summarizeA2UI(messages);
115
+ let judgeRes;
116
+ try {
117
+ judgeRes = await callJudge({
118
+ intent,
119
+ componentSummary: summary,
120
+ rubricVersion,
121
+ timeoutMs,
122
+ ...(model ? { model } : {}),
123
+ });
124
+ } catch (err) {
125
+ return {
126
+ score: 0,
127
+ verdict: 'partial',
128
+ path: 'llm-only',
129
+ axes: {
130
+ dominantPattern: { expected: '', observed: '', score: 0 },
131
+ requiredCapabilities: { expected: [], missing: [], score: 0 },
132
+ forbiddenNoise: { observed: [], score: 0 },
133
+ },
134
+ rationale: `Judge error: ${err.message || String(err)}`.slice(0, 240),
135
+ evidence: [],
136
+ cost: { cached: false, latencyMs: 0 },
137
+ rubricVersion,
138
+ error: 'judge-failed',
139
+ };
140
+ }
141
+
142
+ const cost = {
143
+ provider: judgeRes.provider,
144
+ model: judgeRes.model,
145
+ inputTokens: judgeRes.usage.inputTokens,
146
+ outputTokens: judgeRes.usage.outputTokens,
147
+ cached: false,
148
+ latencyMs: judgeRes.latencyMs,
149
+ };
150
+
151
+ const verdict = shapeVerdict(judgeRes.parsed, { rubricVersion, cost });
152
+
153
+ if (store) {
154
+ try {
155
+ await store.set(key, verdict);
156
+ } catch {
157
+ /* cache write failure is non-fatal */
158
+ }
159
+ }
160
+ return verdict;
161
+ }
162
+
163
+ export { getRubric, summarizeA2UI };