@signalflare-ai/ui 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (765) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/README.md +527 -0
  3. package/ai/USAGE.md +200 -0
  4. package/ai/component-registry.json +7103 -0
  5. package/ai/component-registry.md +3046 -0
  6. package/ai/schemas.ts +1230 -0
  7. package/bin/intent.js +23 -0
  8. package/bin/sf.js +34 -0
  9. package/dist/.build-complete +1 -0
  10. package/dist/ai/schemas.d.ts +7056 -0
  11. package/dist/ai/schemas.d.ts.map +1 -0
  12. package/dist/ai-actions-DG1dhDMP.js +57 -0
  13. package/dist/ai-actions-DG1dhDMP.js.map +1 -0
  14. package/dist/ai-agent-card-BbtL4NII.js +171 -0
  15. package/dist/ai-agent-card-BbtL4NII.js.map +1 -0
  16. package/dist/ai-approval-Mb7-BY6i.js +184 -0
  17. package/dist/ai-approval-Mb7-BY6i.js.map +1 -0
  18. package/dist/ai-code-block-BI_z0UVR.js +110 -0
  19. package/dist/ai-code-block-BI_z0UVR.js.map +1 -0
  20. package/dist/ai-conversation-DYtExcrw.js +184 -0
  21. package/dist/ai-conversation-DYtExcrw.js.map +1 -0
  22. package/dist/ai-info-banner-BpzauUAY.js +76 -0
  23. package/dist/ai-info-banner-BpzauUAY.js.map +1 -0
  24. package/dist/ai-loader-Cr3eQkNS.js +134 -0
  25. package/dist/ai-loader-Cr3eQkNS.js.map +1 -0
  26. package/dist/ai-message-CV8SBoHM.js +286 -0
  27. package/dist/ai-message-CV8SBoHM.js.map +1 -0
  28. package/dist/ai-mission-header-ByYkJ6YP.js +171 -0
  29. package/dist/ai-mission-header-ByYkJ6YP.js.map +1 -0
  30. package/dist/ai-prompt-input-Bo1YuJly.js +769 -0
  31. package/dist/ai-prompt-input-Bo1YuJly.js.map +1 -0
  32. package/dist/ai-question-Dp1g9k2o.js +149 -0
  33. package/dist/ai-question-Dp1g9k2o.js.map +1 -0
  34. package/dist/ai-reasoning-UAmNx_LD.js +270 -0
  35. package/dist/ai-reasoning-UAmNx_LD.js.map +1 -0
  36. package/dist/ai-response-BWoVsNQG.js +42 -0
  37. package/dist/ai-response-BWoVsNQG.js.map +1 -0
  38. package/dist/ai-shimmer-BpOmfonu.js +43 -0
  39. package/dist/ai-shimmer-BpOmfonu.js.map +1 -0
  40. package/dist/ai-status-badge-WhbKVeqn.js +63 -0
  41. package/dist/ai-status-badge-WhbKVeqn.js.map +1 -0
  42. package/dist/ai-streaming-text-ClL7FwvD.js +81 -0
  43. package/dist/ai-streaming-text-ClL7FwvD.js.map +1 -0
  44. package/dist/ai-subagent-BruGN1UE.js +133 -0
  45. package/dist/ai-subagent-BruGN1UE.js.map +1 -0
  46. package/dist/ai-suggestion-CNsCZj5P.js +55 -0
  47. package/dist/ai-suggestion-CNsCZj5P.js.map +1 -0
  48. package/dist/ai-task-list-B9CpMDYN.js +120 -0
  49. package/dist/ai-task-list-B9CpMDYN.js.map +1 -0
  50. package/dist/ai-timeline-Bb5ntsr3.js +373 -0
  51. package/dist/ai-timeline-Bb5ntsr3.js.map +1 -0
  52. package/dist/ai-tool-BGH8nQ_D.js +437 -0
  53. package/dist/ai-tool-BGH8nQ_D.js.map +1 -0
  54. package/dist/ai-usage-bar-BI-p-JBk.js +70 -0
  55. package/dist/ai-usage-bar-BI-p-JBk.js.map +1 -0
  56. package/dist/badge-D_eaA6wv.js +128 -0
  57. package/dist/badge-D_eaA6wv.js.map +1 -0
  58. package/dist/banner-B_6oBrsu.js +54 -0
  59. package/dist/banner-B_6oBrsu.js.map +1 -0
  60. package/dist/breadcrumbs-BlmeYfgq.js +128 -0
  61. package/dist/breadcrumbs-BlmeYfgq.js.map +1 -0
  62. package/dist/button-De0267YU.js +170 -0
  63. package/dist/button-De0267YU.js.map +1 -0
  64. package/dist/catalog.js +506 -0
  65. package/dist/catalog.js.map +1 -0
  66. package/dist/chart-Bes4MN3C.js +618 -0
  67. package/dist/chart-Bes4MN3C.js.map +1 -0
  68. package/dist/checkbox-CPX7lBaU.js +153 -0
  69. package/dist/checkbox-CPX7lBaU.js.map +1 -0
  70. package/dist/clipboard-text-92YeCybc.js +176 -0
  71. package/dist/clipboard-text-92YeCybc.js.map +1 -0
  72. package/dist/cn-YROP2_ox.js +25 -0
  73. package/dist/cn-YROP2_ox.js.map +1 -0
  74. package/dist/code-DE1Yy1Cu.js +97 -0
  75. package/dist/code-DE1Yy1Cu.js.map +1 -0
  76. package/dist/collapsible-DWsXeXmS.js +72 -0
  77. package/dist/collapsible-DWsXeXmS.js.map +1 -0
  78. package/dist/combobox-B0bLdsX8.js +197 -0
  79. package/dist/combobox-B0bLdsX8.js.map +1 -0
  80. package/dist/command-line/cli.js +823 -0
  81. package/dist/command-palette-CBTY8EiF.js +484 -0
  82. package/dist/command-palette-CBTY8EiF.js.map +1 -0
  83. package/dist/components/ai-actions.js +3 -0
  84. package/dist/components/ai-agent-card.js +3 -0
  85. package/dist/components/ai-approval.js +3 -0
  86. package/dist/components/ai-code-block.js +3 -0
  87. package/dist/components/ai-conversation.js +3 -0
  88. package/dist/components/ai-info-banner.js +3 -0
  89. package/dist/components/ai-loader.js +3 -0
  90. package/dist/components/ai-message.js +3 -0
  91. package/dist/components/ai-mission-header.js +3 -0
  92. package/dist/components/ai-prompt-input.js +3 -0
  93. package/dist/components/ai-question.js +3 -0
  94. package/dist/components/ai-reasoning.js +3 -0
  95. package/dist/components/ai-response.js +3 -0
  96. package/dist/components/ai-shimmer.js +3 -0
  97. package/dist/components/ai-status-badge.js +3 -0
  98. package/dist/components/ai-streaming-text.js +3 -0
  99. package/dist/components/ai-subagent.js +3 -0
  100. package/dist/components/ai-suggestion.js +3 -0
  101. package/dist/components/ai-task-list.js +3 -0
  102. package/dist/components/ai-timeline.js +3 -0
  103. package/dist/components/ai-tool.js +3 -0
  104. package/dist/components/ai-usage-bar.js +3 -0
  105. package/dist/components/badge.js +3 -0
  106. package/dist/components/banner.js +3 -0
  107. package/dist/components/breadcrumbs.js +3 -0
  108. package/dist/components/button.js +3 -0
  109. package/dist/components/chart.js +3 -0
  110. package/dist/components/checkbox.js +3 -0
  111. package/dist/components/clipboard-text.js +3 -0
  112. package/dist/components/code.js +3 -0
  113. package/dist/components/collapsible.js +3 -0
  114. package/dist/components/combobox.js +3 -0
  115. package/dist/components/command-palette.js +3 -0
  116. package/dist/components/data-grid.js +3 -0
  117. package/dist/components/date-picker.js +3 -0
  118. package/dist/components/date-range-picker.js +3 -0
  119. package/dist/components/dialog.js +3 -0
  120. package/dist/components/dropdown.js +3 -0
  121. package/dist/components/empty.js +3 -0
  122. package/dist/components/field.js +3 -0
  123. package/dist/components/filters.js +3 -0
  124. package/dist/components/flow.js +3 -0
  125. package/dist/components/grid.js +3 -0
  126. package/dist/components/input.js +4 -0
  127. package/dist/components/label.js +3 -0
  128. package/dist/components/layer-card.js +3 -0
  129. package/dist/components/link.js +92 -0
  130. package/dist/components/link.js.map +1 -0
  131. package/dist/components/loader.js +4 -0
  132. package/dist/components/menubar.js +3 -0
  133. package/dist/components/meter.js +3 -0
  134. package/dist/components/pagination.js +3 -0
  135. package/dist/components/popover.js +3 -0
  136. package/dist/components/radio.js +3 -0
  137. package/dist/components/select.js +3 -0
  138. package/dist/components/sensitive-input.js +3 -0
  139. package/dist/components/sidebar.js +3 -0
  140. package/dist/components/signalflare-ai-logo.js +3 -0
  141. package/dist/components/surface.js +3 -0
  142. package/dist/components/switch.js +3 -0
  143. package/dist/components/table.js +3 -0
  144. package/dist/components/tabs.js +3 -0
  145. package/dist/components/text.js +3 -0
  146. package/dist/components/theme-toggle.js +3 -0
  147. package/dist/components/toast.js +3 -0
  148. package/dist/components/tooltip.js +3 -0
  149. package/dist/components/use-agent-harness.js +3 -0
  150. package/dist/data-grid-UJ9ja5cu.js +305 -0
  151. package/dist/data-grid-UJ9ja5cu.js.map +1 -0
  152. package/dist/date-picker-ebekkC3R.js +57 -0
  153. package/dist/date-picker-ebekkC3R.js.map +1 -0
  154. package/dist/date-range-picker-D75LLINc.js +347 -0
  155. package/dist/date-range-picker-D75LLINc.js.map +1 -0
  156. package/dist/dialog-CyHEQXEY.js +104 -0
  157. package/dist/dialog-CyHEQXEY.js.map +1 -0
  158. package/dist/dist-BNlyONdD.js +3546 -0
  159. package/dist/dist-BNlyONdD.js.map +1 -0
  160. package/dist/dropdown-J5T4pHaR.js +202 -0
  161. package/dist/dropdown-J5T4pHaR.js.map +1 -0
  162. package/dist/empty-D2TypIId.js +90 -0
  163. package/dist/empty-D2TypIId.js.map +1 -0
  164. package/dist/favicon.svg +4 -0
  165. package/dist/field-Y_UK1_Cg.js +57 -0
  166. package/dist/field-Y_UK1_Cg.js.map +1 -0
  167. package/dist/filters-BdBogf7D.js +682 -0
  168. package/dist/filters-BdBogf7D.js.map +1 -0
  169. package/dist/flow-BRsYUCJa.js +741 -0
  170. package/dist/flow-BRsYUCJa.js.map +1 -0
  171. package/dist/genui.js +40 -0
  172. package/dist/genui.js.map +1 -0
  173. package/dist/grid-qUAN9hFx.js +119 -0
  174. package/dist/grid-qUAN9hFx.js.map +1 -0
  175. package/dist/highlight-to-react-ClEfL81q.js +57 -0
  176. package/dist/highlight-to-react-ClEfL81q.js.map +1 -0
  177. package/dist/index.js +215 -0
  178. package/dist/index.js.map +1 -0
  179. package/dist/input-BxQAnXki.js +81 -0
  180. package/dist/input-BxQAnXki.js.map +1 -0
  181. package/dist/input-Cn25I4o5.js +121 -0
  182. package/dist/input-Cn25I4o5.js.map +1 -0
  183. package/dist/label-QtJxtJ4u.js +70 -0
  184. package/dist/label-QtJxtJ4u.js.map +1 -0
  185. package/dist/layer-card-BME0eljh.js +44 -0
  186. package/dist/layer-card-BME0eljh.js.map +1 -0
  187. package/dist/link-provider-BUZKXaNE.js +25 -0
  188. package/dist/link-provider-BUZKXaNE.js.map +1 -0
  189. package/dist/loader-DAcc-Uag.js +84 -0
  190. package/dist/loader-DAcc-Uag.js.map +1 -0
  191. package/dist/logo.svg +1 -0
  192. package/dist/menubar-C8NzAjfd.js +102 -0
  193. package/dist/menubar-C8NzAjfd.js.map +1 -0
  194. package/dist/meter-CpmTenEr.js +37 -0
  195. package/dist/meter-CpmTenEr.js.map +1 -0
  196. package/dist/pagination-C_YqCy8l.js +117 -0
  197. package/dist/pagination-C_YqCy8l.js.map +1 -0
  198. package/dist/popover-BRQZ2b6z.js +147 -0
  199. package/dist/popover-BRQZ2b6z.js.map +1 -0
  200. package/dist/primitives/accordion.js +2 -0
  201. package/dist/primitives/alert-dialog.js +2 -0
  202. package/dist/primitives/autocomplete.js +2 -0
  203. package/dist/primitives/avatar.js +2 -0
  204. package/dist/primitives/button.js +2 -0
  205. package/dist/primitives/checkbox-group.js +2 -0
  206. package/dist/primitives/checkbox.js +2 -0
  207. package/dist/primitives/collapsible.js +2 -0
  208. package/dist/primitives/combobox.js +2 -0
  209. package/dist/primitives/context-menu.js +2 -0
  210. package/dist/primitives/csp-provider.js +2 -0
  211. package/dist/primitives/dialog.js +2 -0
  212. package/dist/primitives/direction-provider.js +2 -0
  213. package/dist/primitives/drawer.js +2 -0
  214. package/dist/primitives/field.js +2 -0
  215. package/dist/primitives/fieldset.js +2 -0
  216. package/dist/primitives/form.js +2 -0
  217. package/dist/primitives/input.js +2 -0
  218. package/dist/primitives/menu.js +2 -0
  219. package/dist/primitives/menubar.js +2 -0
  220. package/dist/primitives/meter.js +2 -0
  221. package/dist/primitives/navigation-menu.js +2 -0
  222. package/dist/primitives/number-field.js +2 -0
  223. package/dist/primitives/popover.js +2 -0
  224. package/dist/primitives/preview-card.js +2 -0
  225. package/dist/primitives/progress.js +2 -0
  226. package/dist/primitives/radio-group.js +2 -0
  227. package/dist/primitives/radio.js +2 -0
  228. package/dist/primitives/scroll-area.js +2 -0
  229. package/dist/primitives/select.js +2 -0
  230. package/dist/primitives/separator.js +2 -0
  231. package/dist/primitives/slider.js +2 -0
  232. package/dist/primitives/switch.js +2 -0
  233. package/dist/primitives/tabs.js +2 -0
  234. package/dist/primitives/toast.js +2 -0
  235. package/dist/primitives/toggle-group.js +2 -0
  236. package/dist/primitives/toggle.js +2 -0
  237. package/dist/primitives/toolbar.js +2 -0
  238. package/dist/primitives/tooltip.js +2 -0
  239. package/dist/primitives.js +40 -0
  240. package/dist/radio-B7zg1wUI.js +101 -0
  241. package/dist/radio-B7zg1wUI.js.map +1 -0
  242. package/dist/registry.js +1 -0
  243. package/dist/select-9p721G00.js +95 -0
  244. package/dist/select-9p721G00.js.map +1 -0
  245. package/dist/sensitive-input-D5je2NLl.js +248 -0
  246. package/dist/sensitive-input-D5je2NLl.js.map +1 -0
  247. package/dist/sidebar-DOwBrq57.js +964 -0
  248. package/dist/sidebar-DOwBrq57.js.map +1 -0
  249. package/dist/signalflare-ai-logo-DDhxMJD6.js +260 -0
  250. package/dist/signalflare-ai-logo-DDhxMJD6.js.map +1 -0
  251. package/dist/skeleton-line-Do3UmGk9.js +36 -0
  252. package/dist/skeleton-line-Do3UmGk9.js.map +1 -0
  253. package/dist/src/blocks/agent-harness/agent-harness.d.ts +177 -0
  254. package/dist/src/blocks/agent-harness/agent-harness.d.ts.map +1 -0
  255. package/dist/src/blocks/agent-harness/agent-harness.tsx +1122 -0
  256. package/dist/src/blocks/agent-harness/index.d.ts +2 -0
  257. package/dist/src/blocks/agent-harness/index.d.ts.map +1 -0
  258. package/dist/src/blocks/commander/commander.d.ts +101 -0
  259. package/dist/src/blocks/commander/commander.d.ts.map +1 -0
  260. package/dist/src/blocks/commander/commander.tsx +477 -0
  261. package/dist/src/blocks/commander/index.d.ts +2 -0
  262. package/dist/src/blocks/commander/index.d.ts.map +1 -0
  263. package/dist/src/blocks/delete-resource/delete-resource.d.ts +46 -0
  264. package/dist/src/blocks/delete-resource/delete-resource.d.ts.map +1 -0
  265. package/dist/src/blocks/delete-resource/delete-resource.tsx +214 -0
  266. package/dist/src/blocks/delete-resource/index.d.ts +2 -0
  267. package/dist/src/blocks/delete-resource/index.d.ts.map +1 -0
  268. package/dist/src/blocks/map-block/index.d.ts +2 -0
  269. package/dist/src/blocks/map-block/index.d.ts.map +1 -0
  270. package/dist/src/blocks/map-block/map-block.d.ts +79 -0
  271. package/dist/src/blocks/map-block/map-block.d.ts.map +1 -0
  272. package/dist/src/blocks/map-block/map-block.tsx +522 -0
  273. package/dist/src/blocks/page-header/index.d.ts +2 -0
  274. package/dist/src/blocks/page-header/index.d.ts.map +1 -0
  275. package/dist/src/blocks/page-header/page-header.d.ts +38 -0
  276. package/dist/src/blocks/page-header/page-header.d.ts.map +1 -0
  277. package/dist/src/blocks/page-header/page-header.tsx +96 -0
  278. package/dist/src/blocks/resource-list/index.d.ts +2 -0
  279. package/dist/src/blocks/resource-list/index.d.ts.map +1 -0
  280. package/dist/src/blocks/resource-list/resource-list.d.ts +18 -0
  281. package/dist/src/blocks/resource-list/resource-list.d.ts.map +1 -0
  282. package/dist/src/blocks/resource-list/resource-list.test.tsx +27 -0
  283. package/dist/src/blocks/resource-list/resource-list.tsx +65 -0
  284. package/dist/src/catalog/catalog.d.ts +75 -0
  285. package/dist/src/catalog/catalog.d.ts.map +1 -0
  286. package/dist/src/catalog/data.d.ts +44 -0
  287. package/dist/src/catalog/data.d.ts.map +1 -0
  288. package/dist/src/catalog/index.d.ts +35 -0
  289. package/dist/src/catalog/index.d.ts.map +1 -0
  290. package/dist/src/catalog/sf-components.d.ts +8 -0
  291. package/dist/src/catalog/sf-components.d.ts.map +1 -0
  292. package/dist/src/catalog/sf-registry.d.ts +4 -0
  293. package/dist/src/catalog/sf-registry.d.ts.map +1 -0
  294. package/dist/src/catalog/types.d.ts +226 -0
  295. package/dist/src/catalog/types.d.ts.map +1 -0
  296. package/dist/src/catalog/visibility.d.ts +37 -0
  297. package/dist/src/catalog/visibility.d.ts.map +1 -0
  298. package/dist/src/command-line/build-cli.d.ts +7 -0
  299. package/dist/src/command-line/build-cli.d.ts.map +1 -0
  300. package/dist/src/command-line/cli.d.ts +13 -0
  301. package/dist/src/command-line/cli.d.ts.map +1 -0
  302. package/dist/src/command-line/commands/add.d.ts +10 -0
  303. package/dist/src/command-line/commands/add.d.ts.map +1 -0
  304. package/dist/src/command-line/commands/ai.d.ts +10 -0
  305. package/dist/src/command-line/commands/ai.d.ts.map +1 -0
  306. package/dist/src/command-line/commands/blocks.d.ts +10 -0
  307. package/dist/src/command-line/commands/blocks.d.ts.map +1 -0
  308. package/dist/src/command-line/commands/doc.d.ts +14 -0
  309. package/dist/src/command-line/commands/doc.d.ts.map +1 -0
  310. package/dist/src/command-line/commands/init.d.ts +18 -0
  311. package/dist/src/command-line/commands/init.d.ts.map +1 -0
  312. package/dist/src/command-line/commands/ls.d.ts +10 -0
  313. package/dist/src/command-line/commands/ls.d.ts.map +1 -0
  314. package/dist/src/command-line/commands/migrate.d.ts +10 -0
  315. package/dist/src/command-line/commands/migrate.d.ts.map +1 -0
  316. package/dist/src/command-line/utils/config.d.ts +42 -0
  317. package/dist/src/command-line/utils/config.d.ts.map +1 -0
  318. package/dist/src/command-line/utils/transformer.d.ts +21 -0
  319. package/dist/src/command-line/utils/transformer.d.ts.map +1 -0
  320. package/dist/src/components/ai-actions/ai-actions.d.ts +35 -0
  321. package/dist/src/components/ai-actions/ai-actions.d.ts.map +1 -0
  322. package/dist/src/components/ai-actions/index.d.ts +2 -0
  323. package/dist/src/components/ai-actions/index.d.ts.map +1 -0
  324. package/dist/src/components/ai-agent-card/ai-agent-card.d.ts +82 -0
  325. package/dist/src/components/ai-agent-card/ai-agent-card.d.ts.map +1 -0
  326. package/dist/src/components/ai-agent-card/index.d.ts +2 -0
  327. package/dist/src/components/ai-agent-card/index.d.ts.map +1 -0
  328. package/dist/src/components/ai-approval/ai-approval.d.ts +102 -0
  329. package/dist/src/components/ai-approval/ai-approval.d.ts.map +1 -0
  330. package/dist/src/components/ai-approval/index.d.ts +2 -0
  331. package/dist/src/components/ai-approval/index.d.ts.map +1 -0
  332. package/dist/src/components/ai-code-block/ai-code-block.d.ts +48 -0
  333. package/dist/src/components/ai-code-block/ai-code-block.d.ts.map +1 -0
  334. package/dist/src/components/ai-code-block/index.d.ts +2 -0
  335. package/dist/src/components/ai-code-block/index.d.ts.map +1 -0
  336. package/dist/src/components/ai-conversation/ai-conversation.d.ts +125 -0
  337. package/dist/src/components/ai-conversation/ai-conversation.d.ts.map +1 -0
  338. package/dist/src/components/ai-conversation/index.d.ts +2 -0
  339. package/dist/src/components/ai-conversation/index.d.ts.map +1 -0
  340. package/dist/src/components/ai-info-banner/ai-info-banner.d.ts +55 -0
  341. package/dist/src/components/ai-info-banner/ai-info-banner.d.ts.map +1 -0
  342. package/dist/src/components/ai-info-banner/index.d.ts +2 -0
  343. package/dist/src/components/ai-info-banner/index.d.ts.map +1 -0
  344. package/dist/src/components/ai-loader/ai-loader.d.ts +44 -0
  345. package/dist/src/components/ai-loader/ai-loader.d.ts.map +1 -0
  346. package/dist/src/components/ai-loader/index.d.ts +2 -0
  347. package/dist/src/components/ai-loader/index.d.ts.map +1 -0
  348. package/dist/src/components/ai-message/ai-message.d.ts +97 -0
  349. package/dist/src/components/ai-message/ai-message.d.ts.map +1 -0
  350. package/dist/src/components/ai-message/index.d.ts +2 -0
  351. package/dist/src/components/ai-message/index.d.ts.map +1 -0
  352. package/dist/src/components/ai-mission-header/ai-mission-header.d.ts +62 -0
  353. package/dist/src/components/ai-mission-header/ai-mission-header.d.ts.map +1 -0
  354. package/dist/src/components/ai-mission-header/index.d.ts +2 -0
  355. package/dist/src/components/ai-mission-header/index.d.ts.map +1 -0
  356. package/dist/src/components/ai-prompt-input/ai-prompt-input.d.ts +260 -0
  357. package/dist/src/components/ai-prompt-input/ai-prompt-input.d.ts.map +1 -0
  358. package/dist/src/components/ai-prompt-input/index.d.ts +2 -0
  359. package/dist/src/components/ai-prompt-input/index.d.ts.map +1 -0
  360. package/dist/src/components/ai-question/ai-question.d.ts +73 -0
  361. package/dist/src/components/ai-question/ai-question.d.ts.map +1 -0
  362. package/dist/src/components/ai-question/index.d.ts +2 -0
  363. package/dist/src/components/ai-question/index.d.ts.map +1 -0
  364. package/dist/src/components/ai-reasoning/ai-reasoning.d.ts +107 -0
  365. package/dist/src/components/ai-reasoning/ai-reasoning.d.ts.map +1 -0
  366. package/dist/src/components/ai-reasoning/index.d.ts +2 -0
  367. package/dist/src/components/ai-reasoning/index.d.ts.map +1 -0
  368. package/dist/src/components/ai-response/ai-response.d.ts +26 -0
  369. package/dist/src/components/ai-response/ai-response.d.ts.map +1 -0
  370. package/dist/src/components/ai-response/index.d.ts +2 -0
  371. package/dist/src/components/ai-response/index.d.ts.map +1 -0
  372. package/dist/src/components/ai-shimmer/ai-shimmer.d.ts +29 -0
  373. package/dist/src/components/ai-shimmer/ai-shimmer.d.ts.map +1 -0
  374. package/dist/src/components/ai-shimmer/index.d.ts +2 -0
  375. package/dist/src/components/ai-shimmer/index.d.ts.map +1 -0
  376. package/dist/src/components/ai-status-badge/ai-status-badge.d.ts +46 -0
  377. package/dist/src/components/ai-status-badge/ai-status-badge.d.ts.map +1 -0
  378. package/dist/src/components/ai-status-badge/index.d.ts +2 -0
  379. package/dist/src/components/ai-status-badge/index.d.ts.map +1 -0
  380. package/dist/src/components/ai-streaming-text/ai-streaming-text.d.ts +27 -0
  381. package/dist/src/components/ai-streaming-text/ai-streaming-text.d.ts.map +1 -0
  382. package/dist/src/components/ai-streaming-text/index.d.ts +2 -0
  383. package/dist/src/components/ai-streaming-text/index.d.ts.map +1 -0
  384. package/dist/src/components/ai-subagent/ai-subagent.d.ts +74 -0
  385. package/dist/src/components/ai-subagent/ai-subagent.d.ts.map +1 -0
  386. package/dist/src/components/ai-subagent/index.d.ts +2 -0
  387. package/dist/src/components/ai-subagent/index.d.ts.map +1 -0
  388. package/dist/src/components/ai-suggestion/ai-suggestion.d.ts +40 -0
  389. package/dist/src/components/ai-suggestion/ai-suggestion.d.ts.map +1 -0
  390. package/dist/src/components/ai-suggestion/index.d.ts +2 -0
  391. package/dist/src/components/ai-suggestion/index.d.ts.map +1 -0
  392. package/dist/src/components/ai-task-list/ai-task-list.d.ts +61 -0
  393. package/dist/src/components/ai-task-list/ai-task-list.d.ts.map +1 -0
  394. package/dist/src/components/ai-task-list/index.d.ts +2 -0
  395. package/dist/src/components/ai-task-list/index.d.ts.map +1 -0
  396. package/dist/src/components/ai-timeline/ai-timeline.d.ts +130 -0
  397. package/dist/src/components/ai-timeline/ai-timeline.d.ts.map +1 -0
  398. package/dist/src/components/ai-timeline/index.d.ts +2 -0
  399. package/dist/src/components/ai-timeline/index.d.ts.map +1 -0
  400. package/dist/src/components/ai-tool/ai-tool.d.ts +138 -0
  401. package/dist/src/components/ai-tool/ai-tool.d.ts.map +1 -0
  402. package/dist/src/components/ai-tool/index.d.ts +2 -0
  403. package/dist/src/components/ai-tool/index.d.ts.map +1 -0
  404. package/dist/src/components/ai-usage-bar/ai-usage-bar.d.ts +38 -0
  405. package/dist/src/components/ai-usage-bar/ai-usage-bar.d.ts.map +1 -0
  406. package/dist/src/components/ai-usage-bar/index.d.ts +2 -0
  407. package/dist/src/components/ai-usage-bar/index.d.ts.map +1 -0
  408. package/dist/src/components/badge/badge.d.ts +129 -0
  409. package/dist/src/components/badge/badge.d.ts.map +1 -0
  410. package/dist/src/components/badge/index.d.ts +2 -0
  411. package/dist/src/components/badge/index.d.ts.map +1 -0
  412. package/dist/src/components/banner/banner.d.ts +80 -0
  413. package/dist/src/components/banner/banner.d.ts.map +1 -0
  414. package/dist/src/components/banner/index.d.ts +2 -0
  415. package/dist/src/components/banner/index.d.ts.map +1 -0
  416. package/dist/src/components/breadcrumbs/breadcrumbs.d.ts +78 -0
  417. package/dist/src/components/breadcrumbs/breadcrumbs.d.ts.map +1 -0
  418. package/dist/src/components/breadcrumbs/index.d.ts +2 -0
  419. package/dist/src/components/breadcrumbs/index.d.ts.map +1 -0
  420. package/dist/src/components/button/button.d.ts +212 -0
  421. package/dist/src/components/button/button.d.ts.map +1 -0
  422. package/dist/src/components/button/index.d.ts +2 -0
  423. package/dist/src/components/button/index.d.ts.map +1 -0
  424. package/dist/src/components/chart/color.d.ts +98 -0
  425. package/dist/src/components/chart/color.d.ts.map +1 -0
  426. package/dist/src/components/chart/echart.d.ts +135 -0
  427. package/dist/src/components/chart/echart.d.ts.map +1 -0
  428. package/dist/src/components/chart/index.d.ts +5 -0
  429. package/dist/src/components/chart/index.d.ts.map +1 -0
  430. package/dist/src/components/chart/legend.d.ts +42 -0
  431. package/dist/src/components/chart/legend.d.ts.map +1 -0
  432. package/dist/src/components/chart/timeseries-chart.d.ts +119 -0
  433. package/dist/src/components/chart/timeseries-chart.d.ts.map +1 -0
  434. package/dist/src/components/checkbox/checkbox.d.ts +174 -0
  435. package/dist/src/components/checkbox/checkbox.d.ts.map +1 -0
  436. package/dist/src/components/checkbox/index.d.ts +2 -0
  437. package/dist/src/components/checkbox/index.d.ts.map +1 -0
  438. package/dist/src/components/clipboard-text/clipboard-text.d.ts +86 -0
  439. package/dist/src/components/clipboard-text/clipboard-text.d.ts.map +1 -0
  440. package/dist/src/components/clipboard-text/index.d.ts +2 -0
  441. package/dist/src/components/clipboard-text/index.d.ts.map +1 -0
  442. package/dist/src/components/code/code.d.ts +165 -0
  443. package/dist/src/components/code/code.d.ts.map +1 -0
  444. package/dist/src/components/code/index.d.ts +4 -0
  445. package/dist/src/components/code/index.d.ts.map +1 -0
  446. package/dist/src/components/collapsible/collapsible.d.ts +72 -0
  447. package/dist/src/components/collapsible/collapsible.d.ts.map +1 -0
  448. package/dist/src/components/collapsible/index.d.ts +2 -0
  449. package/dist/src/components/collapsible/index.d.ts.map +1 -0
  450. package/dist/src/components/combobox/combobox.d.ts +188 -0
  451. package/dist/src/components/combobox/combobox.d.ts.map +1 -0
  452. package/dist/src/components/combobox/index.d.ts +2 -0
  453. package/dist/src/components/combobox/index.d.ts.map +1 -0
  454. package/dist/src/components/command-palette/command-palette.d.ts +260 -0
  455. package/dist/src/components/command-palette/command-palette.d.ts.map +1 -0
  456. package/dist/src/components/command-palette/index.d.ts +3 -0
  457. package/dist/src/components/command-palette/index.d.ts.map +1 -0
  458. package/dist/src/components/command-palette/types.d.ts +149 -0
  459. package/dist/src/components/command-palette/types.d.ts.map +1 -0
  460. package/dist/src/components/data-grid/data-grid.d.ts +78 -0
  461. package/dist/src/components/data-grid/data-grid.d.ts.map +1 -0
  462. package/dist/src/components/data-grid/index.d.ts +3 -0
  463. package/dist/src/components/data-grid/index.d.ts.map +1 -0
  464. package/dist/src/components/data-grid/types.d.ts +236 -0
  465. package/dist/src/components/data-grid/types.d.ts.map +1 -0
  466. package/dist/src/components/date-picker/date-picker.d.ts +65 -0
  467. package/dist/src/components/date-picker/date-picker.d.ts.map +1 -0
  468. package/dist/src/components/date-picker/index.d.ts +4 -0
  469. package/dist/src/components/date-picker/index.d.ts.map +1 -0
  470. package/dist/src/components/date-range-picker/date-range-picker.d.ts +125 -0
  471. package/dist/src/components/date-range-picker/date-range-picker.d.ts.map +1 -0
  472. package/dist/src/components/date-range-picker/index.d.ts +5 -0
  473. package/dist/src/components/date-range-picker/index.d.ts.map +1 -0
  474. package/dist/src/components/dialog/dialog.d.ts +189 -0
  475. package/dist/src/components/dialog/dialog.d.ts.map +1 -0
  476. package/dist/src/components/dialog/index.d.ts +2 -0
  477. package/dist/src/components/dialog/index.d.ts.map +1 -0
  478. package/dist/src/components/dropdown/dropdown.d.ts +91 -0
  479. package/dist/src/components/dropdown/dropdown.d.ts.map +1 -0
  480. package/dist/src/components/dropdown/index.d.ts +2 -0
  481. package/dist/src/components/dropdown/index.d.ts.map +1 -0
  482. package/dist/src/components/empty/empty.d.ts +69 -0
  483. package/dist/src/components/empty/empty.d.ts.map +1 -0
  484. package/dist/src/components/empty/index.d.ts +2 -0
  485. package/dist/src/components/empty/index.d.ts.map +1 -0
  486. package/dist/src/components/field/field.d.ts +68 -0
  487. package/dist/src/components/field/field.d.ts.map +1 -0
  488. package/dist/src/components/field/index.d.ts +2 -0
  489. package/dist/src/components/field/index.d.ts.map +1 -0
  490. package/dist/src/components/filters/filters.d.ts +54 -0
  491. package/dist/src/components/filters/filters.d.ts.map +1 -0
  492. package/dist/src/components/filters/helpers.d.ts +56 -0
  493. package/dist/src/components/filters/helpers.d.ts.map +1 -0
  494. package/dist/src/components/filters/index.d.ts +3 -0
  495. package/dist/src/components/filters/index.d.ts.map +1 -0
  496. package/dist/src/components/filters/types.d.ts +148 -0
  497. package/dist/src/components/filters/types.d.ts.map +1 -0
  498. package/dist/src/components/flow/connectors.d.ts +35 -0
  499. package/dist/src/components/flow/connectors.d.ts.map +1 -0
  500. package/dist/src/components/flow/diagram.d.ts +62 -0
  501. package/dist/src/components/flow/diagram.d.ts.map +1 -0
  502. package/dist/src/components/flow/index.d.ts +26 -0
  503. package/dist/src/components/flow/index.d.ts.map +1 -0
  504. package/dist/src/components/flow/node.d.ts +52 -0
  505. package/dist/src/components/flow/node.d.ts.map +1 -0
  506. package/dist/src/components/flow/parallel.d.ts +5 -0
  507. package/dist/src/components/flow/parallel.d.ts.map +1 -0
  508. package/dist/src/components/flow/use-children.d.ts +69 -0
  509. package/dist/src/components/flow/use-children.d.ts.map +1 -0
  510. package/dist/src/components/grid/grid.d.ts +135 -0
  511. package/dist/src/components/grid/grid.d.ts.map +1 -0
  512. package/dist/src/components/grid/index.d.ts +2 -0
  513. package/dist/src/components/grid/index.d.ts.map +1 -0
  514. package/dist/src/components/input/index.d.ts +4 -0
  515. package/dist/src/components/input/index.d.ts.map +1 -0
  516. package/dist/src/components/input/input-area.d.ts +65 -0
  517. package/dist/src/components/input/input-area.d.ts.map +1 -0
  518. package/dist/src/components/input/input-group.d.ts +39 -0
  519. package/dist/src/components/input/input-group.d.ts.map +1 -0
  520. package/dist/src/components/input/input.d.ts +172 -0
  521. package/dist/src/components/input/input.d.ts.map +1 -0
  522. package/dist/src/components/label/index.d.ts +2 -0
  523. package/dist/src/components/label/index.d.ts.map +1 -0
  524. package/dist/src/components/label/label.d.ts +67 -0
  525. package/dist/src/components/label/label.d.ts.map +1 -0
  526. package/dist/src/components/layer-card/index.d.ts +2 -0
  527. package/dist/src/components/layer-card/index.d.ts.map +1 -0
  528. package/dist/src/components/layer-card/layer-card.d.ts +29 -0
  529. package/dist/src/components/layer-card/layer-card.d.ts.map +1 -0
  530. package/dist/src/components/link/index.d.ts +2 -0
  531. package/dist/src/components/link/index.d.ts.map +1 -0
  532. package/dist/src/components/link/link.d.ts +55 -0
  533. package/dist/src/components/link/link.d.ts.map +1 -0
  534. package/dist/src/components/loader/index.d.ts +3 -0
  535. package/dist/src/components/loader/index.d.ts.map +1 -0
  536. package/dist/src/components/loader/loader.d.ts +65 -0
  537. package/dist/src/components/loader/loader.d.ts.map +1 -0
  538. package/dist/src/components/loader/skeleton-line.d.ts +10 -0
  539. package/dist/src/components/loader/skeleton-line.d.ts.map +1 -0
  540. package/dist/src/components/menubar/index.d.ts +3 -0
  541. package/dist/src/components/menubar/index.d.ts.map +1 -0
  542. package/dist/src/components/menubar/menubar.d.ts +66 -0
  543. package/dist/src/components/menubar/menubar.d.ts.map +1 -0
  544. package/dist/src/components/menubar/use-menu-navigation.d.ts +8 -0
  545. package/dist/src/components/menubar/use-menu-navigation.d.ts.map +1 -0
  546. package/dist/src/components/meter/index.d.ts +2 -0
  547. package/dist/src/components/meter/index.d.ts.map +1 -0
  548. package/dist/src/components/meter/meter.d.ts +44 -0
  549. package/dist/src/components/meter/meter.d.ts.map +1 -0
  550. package/dist/src/components/pagination/index.d.ts +2 -0
  551. package/dist/src/components/pagination/index.d.ts.map +1 -0
  552. package/dist/src/components/pagination/pagination.d.ts +60 -0
  553. package/dist/src/components/pagination/pagination.d.ts.map +1 -0
  554. package/dist/src/components/popover/index.d.ts +3 -0
  555. package/dist/src/components/popover/index.d.ts.map +1 -0
  556. package/dist/src/components/popover/popover.d.ts +138 -0
  557. package/dist/src/components/popover/popover.d.ts.map +1 -0
  558. package/dist/src/components/radio/index.d.ts +2 -0
  559. package/dist/src/components/radio/index.d.ts.map +1 -0
  560. package/dist/src/components/radio/radio.d.ts +163 -0
  561. package/dist/src/components/radio/radio.d.ts.map +1 -0
  562. package/dist/src/components/select/index.d.ts +2 -0
  563. package/dist/src/components/select/index.d.ts.map +1 -0
  564. package/dist/src/components/select/select.d.ts +150 -0
  565. package/dist/src/components/select/select.d.ts.map +1 -0
  566. package/dist/src/components/sensitive-input/index.d.ts +2 -0
  567. package/dist/src/components/sensitive-input/index.d.ts.map +1 -0
  568. package/dist/src/components/sensitive-input/sensitive-input.d.ts +94 -0
  569. package/dist/src/components/sensitive-input/sensitive-input.d.ts.map +1 -0
  570. package/dist/src/components/sidebar/index.d.ts +2 -0
  571. package/dist/src/components/sidebar/index.d.ts.map +1 -0
  572. package/dist/src/components/sidebar/sidebar.d.ts +556 -0
  573. package/dist/src/components/sidebar/sidebar.d.ts.map +1 -0
  574. package/dist/src/components/signalflare-ai-logo/index.d.ts +2 -0
  575. package/dist/src/components/signalflare-ai-logo/index.d.ts.map +1 -0
  576. package/dist/src/components/signalflare-ai-logo/signalflare-ai-logo.d.ts +171 -0
  577. package/dist/src/components/signalflare-ai-logo/signalflare-ai-logo.d.ts.map +1 -0
  578. package/dist/src/components/surface/index.d.ts +2 -0
  579. package/dist/src/components/surface/index.d.ts.map +1 -0
  580. package/dist/src/components/surface/surface.d.ts +60 -0
  581. package/dist/src/components/surface/surface.d.ts.map +1 -0
  582. package/dist/src/components/switch/index.d.ts +2 -0
  583. package/dist/src/components/switch/index.d.ts.map +1 -0
  584. package/dist/src/components/switch/switch.d.ts +169 -0
  585. package/dist/src/components/switch/switch.d.ts.map +1 -0
  586. package/dist/src/components/table/index.d.ts +2 -0
  587. package/dist/src/components/table/index.d.ts.map +1 -0
  588. package/dist/src/components/table/table.d.ts +89 -0
  589. package/dist/src/components/table/table.d.ts.map +1 -0
  590. package/dist/src/components/tabs/index.d.ts +3 -0
  591. package/dist/src/components/tabs/index.d.ts.map +1 -0
  592. package/dist/src/components/tabs/tabs.d.ts +105 -0
  593. package/dist/src/components/tabs/tabs.d.ts.map +1 -0
  594. package/dist/src/components/text/index.d.ts +2 -0
  595. package/dist/src/components/text/index.d.ts.map +1 -0
  596. package/dist/src/components/text/text.d.ts +181 -0
  597. package/dist/src/components/text/text.d.ts.map +1 -0
  598. package/dist/src/components/theme-toggle/index.d.ts +2 -0
  599. package/dist/src/components/theme-toggle/index.d.ts.map +1 -0
  600. package/dist/src/components/theme-toggle/theme-toggle.d.ts +68 -0
  601. package/dist/src/components/theme-toggle/theme-toggle.d.ts.map +1 -0
  602. package/dist/src/components/toast/index.d.ts +5 -0
  603. package/dist/src/components/toast/index.d.ts.map +1 -0
  604. package/dist/src/components/toast/toast.d.ts +152 -0
  605. package/dist/src/components/toast/toast.d.ts.map +1 -0
  606. package/dist/src/components/tooltip/index.d.ts +2 -0
  607. package/dist/src/components/tooltip/index.d.ts.map +1 -0
  608. package/dist/src/components/tooltip/tooltip.d.ts +82 -0
  609. package/dist/src/components/tooltip/tooltip.d.ts.map +1 -0
  610. package/dist/src/components/use-agent-harness/index.d.ts +2 -0
  611. package/dist/src/components/use-agent-harness/index.d.ts.map +1 -0
  612. package/dist/src/components/use-agent-harness/use-agent-harness.d.ts +642 -0
  613. package/dist/src/components/use-agent-harness/use-agent-harness.d.ts.map +1 -0
  614. package/dist/src/genui/genui.d.ts +17 -0
  615. package/dist/src/genui/genui.d.ts.map +1 -0
  616. package/dist/src/genui/index.d.ts +19 -0
  617. package/dist/src/genui/index.d.ts.map +1 -0
  618. package/dist/src/index.d.ts +102 -0
  619. package/dist/src/index.d.ts.map +1 -0
  620. package/dist/src/lib/utils.d.ts +2 -0
  621. package/dist/src/lib/utils.d.ts.map +1 -0
  622. package/dist/src/primitives/accordion.d.ts +13 -0
  623. package/dist/src/primitives/accordion.d.ts.map +1 -0
  624. package/dist/src/primitives/alert-dialog.d.ts +13 -0
  625. package/dist/src/primitives/alert-dialog.d.ts.map +1 -0
  626. package/dist/src/primitives/autocomplete.d.ts +13 -0
  627. package/dist/src/primitives/autocomplete.d.ts.map +1 -0
  628. package/dist/src/primitives/avatar.d.ts +13 -0
  629. package/dist/src/primitives/avatar.d.ts.map +1 -0
  630. package/dist/src/primitives/button.d.ts +13 -0
  631. package/dist/src/primitives/button.d.ts.map +1 -0
  632. package/dist/src/primitives/checkbox-group.d.ts +13 -0
  633. package/dist/src/primitives/checkbox-group.d.ts.map +1 -0
  634. package/dist/src/primitives/checkbox.d.ts +13 -0
  635. package/dist/src/primitives/checkbox.d.ts.map +1 -0
  636. package/dist/src/primitives/collapsible.d.ts +13 -0
  637. package/dist/src/primitives/collapsible.d.ts.map +1 -0
  638. package/dist/src/primitives/combobox.d.ts +13 -0
  639. package/dist/src/primitives/combobox.d.ts.map +1 -0
  640. package/dist/src/primitives/context-menu.d.ts +13 -0
  641. package/dist/src/primitives/context-menu.d.ts.map +1 -0
  642. package/dist/src/primitives/csp-provider.d.ts +13 -0
  643. package/dist/src/primitives/csp-provider.d.ts.map +1 -0
  644. package/dist/src/primitives/dialog.d.ts +13 -0
  645. package/dist/src/primitives/dialog.d.ts.map +1 -0
  646. package/dist/src/primitives/direction-provider.d.ts +13 -0
  647. package/dist/src/primitives/direction-provider.d.ts.map +1 -0
  648. package/dist/src/primitives/drawer.d.ts +13 -0
  649. package/dist/src/primitives/drawer.d.ts.map +1 -0
  650. package/dist/src/primitives/field.d.ts +13 -0
  651. package/dist/src/primitives/field.d.ts.map +1 -0
  652. package/dist/src/primitives/fieldset.d.ts +13 -0
  653. package/dist/src/primitives/fieldset.d.ts.map +1 -0
  654. package/dist/src/primitives/form.d.ts +13 -0
  655. package/dist/src/primitives/form.d.ts.map +1 -0
  656. package/dist/src/primitives/index.d.ts +54 -0
  657. package/dist/src/primitives/index.d.ts.map +1 -0
  658. package/dist/src/primitives/input.d.ts +13 -0
  659. package/dist/src/primitives/input.d.ts.map +1 -0
  660. package/dist/src/primitives/menu.d.ts +13 -0
  661. package/dist/src/primitives/menu.d.ts.map +1 -0
  662. package/dist/src/primitives/menubar.d.ts +13 -0
  663. package/dist/src/primitives/menubar.d.ts.map +1 -0
  664. package/dist/src/primitives/meter.d.ts +13 -0
  665. package/dist/src/primitives/meter.d.ts.map +1 -0
  666. package/dist/src/primitives/navigation-menu.d.ts +13 -0
  667. package/dist/src/primitives/navigation-menu.d.ts.map +1 -0
  668. package/dist/src/primitives/number-field.d.ts +13 -0
  669. package/dist/src/primitives/number-field.d.ts.map +1 -0
  670. package/dist/src/primitives/popover.d.ts +13 -0
  671. package/dist/src/primitives/popover.d.ts.map +1 -0
  672. package/dist/src/primitives/preview-card.d.ts +13 -0
  673. package/dist/src/primitives/preview-card.d.ts.map +1 -0
  674. package/dist/src/primitives/progress.d.ts +13 -0
  675. package/dist/src/primitives/progress.d.ts.map +1 -0
  676. package/dist/src/primitives/radio-group.d.ts +13 -0
  677. package/dist/src/primitives/radio-group.d.ts.map +1 -0
  678. package/dist/src/primitives/radio.d.ts +13 -0
  679. package/dist/src/primitives/radio.d.ts.map +1 -0
  680. package/dist/src/primitives/scroll-area.d.ts +13 -0
  681. package/dist/src/primitives/scroll-area.d.ts.map +1 -0
  682. package/dist/src/primitives/select.d.ts +13 -0
  683. package/dist/src/primitives/select.d.ts.map +1 -0
  684. package/dist/src/primitives/separator.d.ts +13 -0
  685. package/dist/src/primitives/separator.d.ts.map +1 -0
  686. package/dist/src/primitives/slider.d.ts +13 -0
  687. package/dist/src/primitives/slider.d.ts.map +1 -0
  688. package/dist/src/primitives/switch.d.ts +13 -0
  689. package/dist/src/primitives/switch.d.ts.map +1 -0
  690. package/dist/src/primitives/tabs.d.ts +13 -0
  691. package/dist/src/primitives/tabs.d.ts.map +1 -0
  692. package/dist/src/primitives/toast.d.ts +13 -0
  693. package/dist/src/primitives/toast.d.ts.map +1 -0
  694. package/dist/src/primitives/toggle-group.d.ts +13 -0
  695. package/dist/src/primitives/toggle-group.d.ts.map +1 -0
  696. package/dist/src/primitives/toggle.d.ts +13 -0
  697. package/dist/src/primitives/toggle.d.ts.map +1 -0
  698. package/dist/src/primitives/toolbar.d.ts +13 -0
  699. package/dist/src/primitives/toolbar.d.ts.map +1 -0
  700. package/dist/src/primitives/tooltip.d.ts +13 -0
  701. package/dist/src/primitives/tooltip.d.ts.map +1 -0
  702. package/dist/src/registry/index.d.ts +8 -0
  703. package/dist/src/registry/index.d.ts.map +1 -0
  704. package/dist/src/registry/types.d.ts +191 -0
  705. package/dist/src/registry/types.d.ts.map +1 -0
  706. package/dist/src/utils/cn.d.ts +4 -0
  707. package/dist/src/utils/cn.d.ts.map +1 -0
  708. package/dist/src/utils/highlight-to-react.d.ts +12 -0
  709. package/dist/src/utils/highlight-to-react.d.ts.map +1 -0
  710. package/dist/src/utils/index.d.ts +3 -0
  711. package/dist/src/utils/index.d.ts.map +1 -0
  712. package/dist/src/utils/link-provider.d.ts +12 -0
  713. package/dist/src/utils/link-provider.d.ts.map +1 -0
  714. package/dist/src/utils/prop-examples.d.ts +36 -0
  715. package/dist/src/utils/prop-examples.d.ts.map +1 -0
  716. package/dist/styles/sf-binding.css +255 -0
  717. package/dist/styles/sf-standalone.css +2 -0
  718. package/dist/styles/sf.css +596 -0
  719. package/dist/styles/theme-fedramp.css +22 -0
  720. package/dist/styles/theme-minimal.css +127 -0
  721. package/dist/styles/theme-navigator.css +137 -0
  722. package/dist/styles/theme-sf.css +191 -0
  723. package/dist/surface-BduI7Ehl.js +18 -0
  724. package/dist/surface-BduI7Ehl.js.map +1 -0
  725. package/dist/switch-CzZBRBL7.js +169 -0
  726. package/dist/switch-CzZBRBL7.js.map +1 -0
  727. package/dist/table-CIMx0Oq0.js +200 -0
  728. package/dist/table-CIMx0Oq0.js.map +1 -0
  729. package/dist/tabs-1cHrYoel.js +54 -0
  730. package/dist/tabs-1cHrYoel.js.map +1 -0
  731. package/dist/text-KJmGkwnf.js +103 -0
  732. package/dist/text-KJmGkwnf.js.map +1 -0
  733. package/dist/theme-toggle-Dpgnoj_Q.js +129 -0
  734. package/dist/theme-toggle-Dpgnoj_Q.js.map +1 -0
  735. package/dist/toast-Nw28a5Cx.js +161 -0
  736. package/dist/toast-Nw28a5Cx.js.map +1 -0
  737. package/dist/tooltip-Cb7QW-7H.js +79 -0
  738. package/dist/tooltip-Cb7QW-7H.js.map +1 -0
  739. package/dist/use-agent-harness-DZzcn96L.js +929 -0
  740. package/dist/use-agent-harness-DZzcn96L.js.map +1 -0
  741. package/dist/utils.js +4 -0
  742. package/package.json +620 -0
  743. package/scripts/component-registry/cache.ts +124 -0
  744. package/scripts/component-registry/discovery.ts +464 -0
  745. package/scripts/component-registry/example-cleanup.ts +168 -0
  746. package/scripts/component-registry/index.test.ts +678 -0
  747. package/scripts/component-registry/index.ts +931 -0
  748. package/scripts/component-registry/markdown-generator.ts +222 -0
  749. package/scripts/component-registry/metadata.ts +653 -0
  750. package/scripts/component-registry/props-filter.ts +313 -0
  751. package/scripts/component-registry/schema-generator.ts +332 -0
  752. package/scripts/component-registry/sub-components.ts +350 -0
  753. package/scripts/component-registry/types.ts +156 -0
  754. package/scripts/component-registry/utils.ts +280 -0
  755. package/scripts/component-registry/variant-parser.ts +262 -0
  756. package/scripts/css-build.ts +117 -0
  757. package/scripts/generate-primitives.ts +178 -0
  758. package/scripts/theme-generator/config.ts +538 -0
  759. package/scripts/theme-generator/generate-css.ts +256 -0
  760. package/scripts/theme-generator/index.ts +161 -0
  761. package/scripts/theme-generator/migrate.ts +584 -0
  762. package/scripts/theme-generator/types.ts +86 -0
  763. package/skills/component-selection/SKILL.md +64 -0
  764. package/skills/installing-blocks/SKILL.md +47 -0
  765. package/skills/theming-and-tokens/SKILL.md +62 -0
@@ -0,0 +1,3546 @@
1
+ "use client";
2
+ import { t as Loader } from "./loader-DAcc-Uag.js";
3
+ import { t as Tooltip } from "./tooltip-Cb7QW-7H.js";
4
+ import { t as Badge } from "./badge-D_eaA6wv.js";
5
+ import { t as Banner } from "./banner-B_6oBrsu.js";
6
+ import { t as Button } from "./button-De0267YU.js";
7
+ import { t as Checkbox } from "./checkbox-CPX7lBaU.js";
8
+ import { t as Field } from "./field-Y_UK1_Cg.js";
9
+ import { t as Input } from "./input-BxQAnXki.js";
10
+ import { n as InputArea } from "./input-Cn25I4o5.js";
11
+ import { t as Code } from "./code-DE1Yy1Cu.js";
12
+ import { t as Surface } from "./surface-BduI7Ehl.js";
13
+ import { t as Dialog } from "./dialog-CyHEQXEY.js";
14
+ import { t as Collapsible } from "./collapsible-DWsXeXmS.js";
15
+ import { t as LayerCard } from "./layer-card-BME0eljh.js";
16
+ import { t as Meter } from "./meter-CpmTenEr.js";
17
+ import { t as Select } from "./select-9p721G00.js";
18
+ import { r as Switch } from "./switch-CzZBRBL7.js";
19
+ import { t as Tabs } from "./tabs-1cHrYoel.js";
20
+ import { r as Table } from "./table-CIMx0Oq0.js";
21
+ import { t as Popover } from "./popover-BRQZ2b6z.js";
22
+ import { t as Empty } from "./empty-D2TypIId.js";
23
+ import { t as Text } from "./text-KJmGkwnf.js";
24
+ import { t as Radio } from "./radio-B7zg1wUI.js";
25
+ import { Link } from "./components/link.js";
26
+ import { t as Grid } from "./grid-qUAN9hFx.js";
27
+ import { i as ChartPalette, r as Chart } from "./chart-Bes4MN3C.js";
28
+ import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
29
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
30
+ import { z } from "zod";
31
+ import { BarChart, LineChart, PieChart } from "echarts/charts";
32
+ import { GridComponent, LegendComponent, TitleComponent, TooltipComponent } from "echarts/components";
33
+ import * as echarts from "echarts/core";
34
+ import { CanvasRenderer } from "echarts/renderers";
35
+ //#region src/catalog/sf-registry.ts
36
+ echarts.use([
37
+ BarChart,
38
+ LineChart,
39
+ PieChart,
40
+ GridComponent,
41
+ TooltipComponent,
42
+ LegendComponent,
43
+ TitleComponent,
44
+ CanvasRenderer
45
+ ]);
46
+ /**
47
+ * Hardcoded SF theme color tokens for ECharts canvas rendering.
48
+ * ECharts draws on <canvas> so it cannot resolve CSS custom properties
49
+ * or `light-dark()`. We detect `data-mode` and return matching hex values
50
+ * derived from theme-sf.css oklch fallbacks.
51
+ */
52
+ var SF_CHART_THEME = {
53
+ light: {
54
+ text: "#6b6b6b",
55
+ mutedText: "#a3a3a3",
56
+ line: "#e5e5e5",
57
+ bg: "#ffffff"
58
+ },
59
+ dark: {
60
+ text: "#a1a1a1",
61
+ mutedText: "#636363",
62
+ line: "#333840",
63
+ bg: "#2a2d35"
64
+ }
65
+ };
66
+ function isDarkMode() {
67
+ if (typeof document === "undefined") return false;
68
+ return document.documentElement.dataset.mode === "dark";
69
+ }
70
+ function getChartThemeColors() {
71
+ return isDarkMode() ? SF_CHART_THEME.dark : SF_CHART_THEME.light;
72
+ }
73
+ /** Shared ECharts option overrides for axis / text / grid styling */
74
+ function chartBaseOptions() {
75
+ const c = getChartThemeColors();
76
+ return {
77
+ textStyle: {
78
+ color: c.mutedText,
79
+ fontFamily: "inherit",
80
+ fontSize: 12
81
+ },
82
+ title: { textStyle: {
83
+ color: c.text,
84
+ fontWeight: 500,
85
+ fontSize: 14
86
+ } },
87
+ legend: { textStyle: { color: c.mutedText } },
88
+ xAxis: {
89
+ axisLine: { lineStyle: { color: c.line } },
90
+ axisTick: { lineStyle: { color: c.line } },
91
+ axisLabel: { color: c.mutedText },
92
+ splitLine: { lineStyle: {
93
+ color: c.line,
94
+ type: "dashed"
95
+ } }
96
+ },
97
+ yAxis: {
98
+ axisLine: { show: false },
99
+ axisTick: { show: false },
100
+ axisLabel: { color: c.mutedText },
101
+ splitLine: { lineStyle: {
102
+ color: c.line,
103
+ type: "dashed"
104
+ } }
105
+ },
106
+ tooltip: {
107
+ backgroundColor: c.bg,
108
+ borderColor: c.line,
109
+ textStyle: { color: c.text }
110
+ }
111
+ };
112
+ }
113
+ /** Deep-merge base chart styling under user options (user wins on conflict) */
114
+ function mergeChartOptions(base, user) {
115
+ const result = {};
116
+ const keys = new Set([...Object.keys(base), ...Object.keys(user)]);
117
+ for (const key of keys) {
118
+ const bv = base[key];
119
+ const uv = user[key];
120
+ if (uv === void 0) result[key] = bv;
121
+ else if (bv === void 0 || typeof bv !== "object" || typeof uv !== "object" || Array.isArray(uv)) result[key] = uv;
122
+ else result[key] = mergeChartOptions(bv, uv);
123
+ }
124
+ return result;
125
+ }
126
+ /** Aggregate data by xKey: sum, count, or avg */
127
+ function processChartData(rawItems, xKey, yKey, aggregate) {
128
+ if (!aggregate) return {
129
+ labels: rawItems.map((item) => {
130
+ const v = item[xKey];
131
+ return typeof v === "string" || typeof v === "number" ? String(v) : "";
132
+ }),
133
+ values: rawItems.map((item) => Number(item[yKey]) || 0)
134
+ };
135
+ const groups = /* @__PURE__ */ new Map();
136
+ for (const item of rawItems) {
137
+ const raw = item[xKey];
138
+ const key = typeof raw === "string" || typeof raw === "number" ? String(raw) : "";
139
+ if (!groups.has(key)) groups.set(key, []);
140
+ groups.get(key).push(Number(item[yKey]) || 0);
141
+ }
142
+ const labels = [];
143
+ const values = [];
144
+ for (const [key, vals] of groups) {
145
+ labels.push(key);
146
+ if (aggregate === "count") values.push(vals.length);
147
+ else if (aggregate === "avg") values.push(vals.reduce((a, b) => a + b, 0) / vals.length);
148
+ else values.push(vals.reduce((a, b) => a + b, 0));
149
+ }
150
+ return {
151
+ labels,
152
+ values
153
+ };
154
+ }
155
+ function passthrough(Component) {
156
+ return ({ props, children }) => children != null ? React.createElement(Component, props, children) : React.createElement(Component, props);
157
+ }
158
+ var sfComponents = {
159
+ Stack: ({ props, children }) => {
160
+ const { direction, gap, align, wrap } = props;
161
+ const cn = ["flex"];
162
+ cn.push(direction === "horizontal" ? "flex-row" : "flex-col");
163
+ if (gap === "sm") cn.push("gap-2");
164
+ else if (gap === "lg") cn.push("gap-6");
165
+ else cn.push("gap-4");
166
+ if (align === "center") cn.push("items-center");
167
+ else if (align === "end") cn.push("items-end");
168
+ else if (align === "start") cn.push("items-start");
169
+ if (wrap) cn.push("flex-wrap");
170
+ return React.createElement("div", { className: cn.join(" ") }, children);
171
+ },
172
+ Surface: ({ props, children }) => {
173
+ const { padding, border, ...rest } = props;
174
+ const cn = [];
175
+ if (padding === "sm") cn.push("p-3");
176
+ else if (padding === "lg") cn.push("p-8");
177
+ else if (padding === "base") cn.push("p-5");
178
+ if (border) cn.push("border border-sf-line rounded-lg");
179
+ return React.createElement(Surface, {
180
+ ...rest,
181
+ className: cn.length ? cn.join(" ") : void 0
182
+ }, children);
183
+ },
184
+ Grid: passthrough(Grid),
185
+ LayerCard: passthrough(LayerCard),
186
+ Text: ({ props }) => {
187
+ const { text, ...rest } = props;
188
+ return React.createElement(Text, rest, text);
189
+ },
190
+ Code: passthrough(Code),
191
+ Button: ({ props }) => {
192
+ const { label, ...rest } = props;
193
+ return React.createElement(Button, rest, label);
194
+ },
195
+ Link: ({ props }) => {
196
+ const { text, ...rest } = props;
197
+ return React.createElement(Link, rest, text);
198
+ },
199
+ Badge: ({ props }) => {
200
+ const { text, ...rest } = props;
201
+ return React.createElement(Badge, rest, text);
202
+ },
203
+ Banner: ({ props }) => {
204
+ const { title, description, variant } = props;
205
+ return React.createElement(Banner, { variant }, React.createElement("strong", null, title), description ? React.createElement("p", null, description) : null);
206
+ },
207
+ Meter: passthrough(Meter),
208
+ Empty: passthrough(Empty),
209
+ Loader: passthrough(Loader),
210
+ Table: ({ props }) => {
211
+ const { data, columns } = props;
212
+ if (!columns?.length) return null;
213
+ const rows = Array.isArray(data) ? data : [];
214
+ return React.createElement(Table, null, React.createElement(Table.Header, null, React.createElement(Table.Row, null, columns.map((col) => React.createElement(Table.Head, { key: col.key }, col.label)))), React.createElement(Table.Body, null, rows.length > 0 ? rows.map((row, i) => React.createElement(Table.Row, { key: i }, columns.map((col) => React.createElement(Table.Cell, { key: col.key }, String(row[col.key] ?? ""))))) : React.createElement(Table.Row, null, React.createElement(Table.Cell, { colSpan: columns.length }, "No data"))));
215
+ },
216
+ Input: passthrough(Input),
217
+ InputArea: passthrough(InputArea),
218
+ Select: ({ props }) => {
219
+ const { options, ...rest } = props;
220
+ const items = Array.isArray(options) ? options : [];
221
+ return React.createElement(Select, rest, items.map((opt) => React.createElement(Select.Option, {
222
+ key: opt.value,
223
+ value: opt.value
224
+ }, opt.label)));
225
+ },
226
+ Checkbox: passthrough(Checkbox),
227
+ Switch: passthrough(Switch),
228
+ Radio: ({ props }) => {
229
+ const { options, ...rest } = props;
230
+ const items = Array.isArray(options) ? options : [];
231
+ return React.createElement(Radio.Group, rest, items.map((opt) => React.createElement(Radio.Item, {
232
+ key: opt.value,
233
+ value: opt.value,
234
+ label: opt.label
235
+ })));
236
+ },
237
+ Field: passthrough(Field),
238
+ Tabs: ({ props, children }) => {
239
+ const { defaultValue, ...rest } = props;
240
+ return children != null ? React.createElement(Tabs, {
241
+ ...rest,
242
+ selectedValue: defaultValue ?? rest.tabs?.[0]?.value
243
+ }, children) : React.createElement(Tabs, {
244
+ ...rest,
245
+ selectedValue: defaultValue ?? rest.tabs?.[0]?.value
246
+ });
247
+ },
248
+ Dialog: ({ props, children }) => {
249
+ const { trigger, title, description } = props;
250
+ return React.createElement(Dialog.Root, null, React.createElement(Dialog.Trigger, null, React.createElement(Button, null, trigger)), React.createElement(Dialog, null, title && React.createElement(Dialog.Title, null, title), description && React.createElement(Dialog.Description, null, description), children));
251
+ },
252
+ Collapsible: passthrough(Collapsible),
253
+ Tooltip: ({ props, children }) => {
254
+ const { content } = props;
255
+ return children != null ? React.createElement(Tooltip, { content }, children) : React.createElement(Tooltip, { content });
256
+ },
257
+ Popover: ({ props, children }) => {
258
+ const { trigger } = props;
259
+ return React.createElement(Popover, null, React.createElement(Popover.Trigger, null, React.createElement(Button, { variant: "outline" }, trigger)), React.createElement(Popover.Content, null, children));
260
+ },
261
+ BarChart: ({ props }) => {
262
+ const { title, data, xKey, yKey, aggregate, color, height } = props;
263
+ const { labels, values } = processChartData(Array.isArray(data) ? data : [], xKey, yKey, aggregate);
264
+ const chartColor = color ?? ChartPalette.color(0);
265
+ const userOpts = {
266
+ ...title ? { title: {
267
+ text: title,
268
+ left: "center"
269
+ } } : {},
270
+ tooltip: { trigger: "axis" },
271
+ xAxis: {
272
+ type: "category",
273
+ data: labels
274
+ },
275
+ yAxis: { type: "value" },
276
+ series: [{
277
+ type: "bar",
278
+ data: values,
279
+ itemStyle: { color: chartColor }
280
+ }]
281
+ };
282
+ return React.createElement(Chart, {
283
+ echarts,
284
+ options: mergeChartOptions(chartBaseOptions(), userOpts),
285
+ height: height ?? 350
286
+ });
287
+ },
288
+ LineChart: ({ props }) => {
289
+ const { title, data, xKey, yKey, aggregate, color, height } = props;
290
+ const { labels, values } = processChartData(Array.isArray(data) ? data : [], xKey, yKey, aggregate);
291
+ const chartColor = color ?? ChartPalette.color(0);
292
+ const userOpts = {
293
+ ...title ? { title: {
294
+ text: title,
295
+ left: "center"
296
+ } } : {},
297
+ tooltip: { trigger: "axis" },
298
+ xAxis: {
299
+ type: "category",
300
+ data: labels
301
+ },
302
+ yAxis: { type: "value" },
303
+ series: [{
304
+ type: "line",
305
+ data: values,
306
+ smooth: true,
307
+ lineStyle: { color: chartColor },
308
+ itemStyle: { color: chartColor }
309
+ }]
310
+ };
311
+ return React.createElement(Chart, {
312
+ echarts,
313
+ options: mergeChartOptions(chartBaseOptions(), userOpts),
314
+ height: height ?? 350
315
+ });
316
+ },
317
+ PieChart: ({ props }) => {
318
+ const { title, data, nameKey, valueKey, height } = props;
319
+ const pieData = (Array.isArray(data) ? data : []).map((item, i) => ({
320
+ name: typeof item[nameKey] === "string" || typeof item[nameKey] === "number" ? String(item[nameKey]) : "",
321
+ value: Number(item[valueKey]) || 0,
322
+ itemStyle: { color: ChartPalette.color(i) }
323
+ }));
324
+ const userOpts = {
325
+ ...title ? { title: {
326
+ text: title,
327
+ left: "center"
328
+ } } : {},
329
+ tooltip: { trigger: "item" },
330
+ legend: {
331
+ orient: "horizontal",
332
+ bottom: 0
333
+ },
334
+ series: [{
335
+ type: "pie",
336
+ radius: ["40%", "70%"],
337
+ data: pieData,
338
+ label: { color: getChartThemeColors().mutedText }
339
+ }]
340
+ };
341
+ return React.createElement(Chart, {
342
+ echarts,
343
+ options: mergeChartOptions(chartBaseOptions(), userOpts),
344
+ height: height ?? 350
345
+ });
346
+ },
347
+ Chart: ({ props }) => {
348
+ const { options, height } = props;
349
+ return React.createElement(Chart, {
350
+ echarts,
351
+ options: mergeChartOptions(chartBaseOptions(), options ?? {}),
352
+ height: height ?? 350
353
+ });
354
+ }
355
+ };
356
+ //#endregion
357
+ //#region ../../node_modules/.bun/@json-render+core@0.15.0/node_modules/@json-render/core/dist/chunk-AFLK3Q4T.mjs
358
+ var DynamicValueSchema = z.union([
359
+ z.string(),
360
+ z.number(),
361
+ z.boolean(),
362
+ z.null(),
363
+ z.object({ $state: z.string() })
364
+ ]);
365
+ z.union([z.string(), z.object({ $state: z.string() })]);
366
+ z.union([z.number(), z.object({ $state: z.string() })]);
367
+ z.union([z.boolean(), z.object({ $state: z.string() })]);
368
+ function resolveDynamicValue(value, stateModel) {
369
+ if (value === null || value === void 0) return;
370
+ if (typeof value === "object" && "$state" in value) return getByPath(stateModel, value.$state);
371
+ return value;
372
+ }
373
+ function unescapeJsonPointer(token) {
374
+ return token.replace(/~1/g, "/").replace(/~0/g, "~");
375
+ }
376
+ function parseJsonPointer(path) {
377
+ return (path.startsWith("/") ? path.slice(1).split("/") : path.split("/")).map(unescapeJsonPointer);
378
+ }
379
+ function getByPath(obj, path) {
380
+ if (!path || path === "/") return obj;
381
+ const segments = parseJsonPointer(path);
382
+ let current = obj;
383
+ for (const segment of segments) {
384
+ if (current === null || current === void 0) return;
385
+ if (Array.isArray(current)) current = current[parseInt(segment, 10)];
386
+ else if (typeof current === "object") current = current[segment];
387
+ else return;
388
+ }
389
+ return current;
390
+ }
391
+ function isNumericIndex(str) {
392
+ return /^\d+$/.test(str);
393
+ }
394
+ function setByPath(obj, path, value) {
395
+ const segments = parseJsonPointer(path);
396
+ if (segments.length === 0) return;
397
+ let current = obj;
398
+ for (let i = 0; i < segments.length - 1; i++) {
399
+ const segment = segments[i];
400
+ const nextSegment = segments[i + 1];
401
+ const nextIsNumeric = nextSegment !== void 0 && (isNumericIndex(nextSegment) || nextSegment === "-");
402
+ if (Array.isArray(current)) {
403
+ const index = parseInt(segment, 10);
404
+ if (current[index] === void 0 || typeof current[index] !== "object") current[index] = nextIsNumeric ? [] : {};
405
+ current = current[index];
406
+ } else {
407
+ if (!(segment in current) || typeof current[segment] !== "object") current[segment] = nextIsNumeric ? [] : {};
408
+ current = current[segment];
409
+ }
410
+ }
411
+ const lastSegment = segments[segments.length - 1];
412
+ if (Array.isArray(current)) if (lastSegment === "-") current.push(value);
413
+ else {
414
+ const index = parseInt(lastSegment, 10);
415
+ current[index] = value;
416
+ }
417
+ else current[lastSegment] = value;
418
+ }
419
+ function addByPath(obj, path, value) {
420
+ const segments = parseJsonPointer(path);
421
+ if (segments.length === 0) return;
422
+ let current = obj;
423
+ for (let i = 0; i < segments.length - 1; i++) {
424
+ const segment = segments[i];
425
+ const nextSegment = segments[i + 1];
426
+ const nextIsNumeric = nextSegment !== void 0 && (isNumericIndex(nextSegment) || nextSegment === "-");
427
+ if (Array.isArray(current)) {
428
+ const index = parseInt(segment, 10);
429
+ if (current[index] === void 0 || typeof current[index] !== "object") current[index] = nextIsNumeric ? [] : {};
430
+ current = current[index];
431
+ } else {
432
+ if (!(segment in current) || typeof current[segment] !== "object") current[segment] = nextIsNumeric ? [] : {};
433
+ current = current[segment];
434
+ }
435
+ }
436
+ const lastSegment = segments[segments.length - 1];
437
+ if (Array.isArray(current)) if (lastSegment === "-") current.push(value);
438
+ else {
439
+ const index = parseInt(lastSegment, 10);
440
+ current.splice(index, 0, value);
441
+ }
442
+ else current[lastSegment] = value;
443
+ }
444
+ function removeByPath(obj, path) {
445
+ const segments = parseJsonPointer(path);
446
+ if (segments.length === 0) return;
447
+ let current = obj;
448
+ for (let i = 0; i < segments.length - 1; i++) {
449
+ const segment = segments[i];
450
+ if (Array.isArray(current)) {
451
+ const index = parseInt(segment, 10);
452
+ if (current[index] === void 0 || typeof current[index] !== "object") return;
453
+ current = current[index];
454
+ } else {
455
+ if (!(segment in current) || typeof current[segment] !== "object") return;
456
+ current = current[segment];
457
+ }
458
+ }
459
+ const lastSegment = segments[segments.length - 1];
460
+ if (Array.isArray(current)) {
461
+ const index = parseInt(lastSegment, 10);
462
+ if (index >= 0 && index < current.length) current.splice(index, 1);
463
+ } else delete current[lastSegment];
464
+ }
465
+ function deepEqual(a, b) {
466
+ if (a === b) return true;
467
+ if (a === null || b === null) return false;
468
+ if (typeof a !== typeof b) return false;
469
+ if (typeof a !== "object") return false;
470
+ if (Array.isArray(a)) {
471
+ if (!Array.isArray(b)) return false;
472
+ if (a.length !== b.length) return false;
473
+ return a.every((item, i) => deepEqual(item, b[i]));
474
+ }
475
+ const aObj = a;
476
+ const bObj = b;
477
+ const aKeys = Object.keys(aObj);
478
+ const bKeys = Object.keys(bObj);
479
+ if (aKeys.length !== bKeys.length) return false;
480
+ return aKeys.every((key) => deepEqual(aObj[key], bObj[key]));
481
+ }
482
+ function parseSpecStreamLine(line) {
483
+ const trimmed = line.trim();
484
+ if (!trimmed || !trimmed.startsWith("{")) return null;
485
+ try {
486
+ const patch = JSON.parse(trimmed);
487
+ if (patch.op && patch.path !== void 0) return patch;
488
+ return null;
489
+ } catch {
490
+ return null;
491
+ }
492
+ }
493
+ function applySpecStreamPatch(obj, patch) {
494
+ switch (patch.op) {
495
+ case "add":
496
+ addByPath(obj, patch.path, patch.value);
497
+ break;
498
+ case "replace":
499
+ setByPath(obj, patch.path, patch.value);
500
+ break;
501
+ case "remove":
502
+ removeByPath(obj, patch.path);
503
+ break;
504
+ case "move": {
505
+ if (!patch.from) break;
506
+ const moveValue = getByPath(obj, patch.from);
507
+ removeByPath(obj, patch.from);
508
+ addByPath(obj, patch.path, moveValue);
509
+ break;
510
+ }
511
+ case "copy": {
512
+ if (!patch.from) break;
513
+ const copyValue = getByPath(obj, patch.from);
514
+ addByPath(obj, patch.path, copyValue);
515
+ break;
516
+ }
517
+ case "test":
518
+ if (!deepEqual(getByPath(obj, patch.path), patch.value)) throw new Error(`Test operation failed: value at "${patch.path}" does not match`);
519
+ break;
520
+ }
521
+ return obj;
522
+ }
523
+ function applySpecPatch(spec, patch) {
524
+ applySpecStreamPatch(spec, patch);
525
+ return spec;
526
+ }
527
+ function nestedToFlat(nested) {
528
+ const elements = {};
529
+ let counter = 0;
530
+ function walk(node) {
531
+ const key = `el-${counter++}`;
532
+ const { type, props, children: rawChildren, ...rest } = node;
533
+ const childKeys = [];
534
+ if (Array.isArray(rawChildren)) {
535
+ for (const child of rawChildren) if (child && typeof child === "object" && "type" in child) childKeys.push(walk(child));
536
+ }
537
+ const element = {
538
+ type: type ?? "unknown",
539
+ props: props ?? {},
540
+ children: childKeys
541
+ };
542
+ for (const [k, v] of Object.entries(rest)) if (k !== "state" && v !== void 0) element[k] = v;
543
+ elements[key] = element;
544
+ return key;
545
+ }
546
+ const spec = {
547
+ root: walk(nested),
548
+ elements
549
+ };
550
+ if (nested.state && typeof nested.state === "object" && !Array.isArray(nested.state)) spec.state = nested.state;
551
+ return spec;
552
+ }
553
+ function createMixedStreamParser(callbacks) {
554
+ let buffer = "";
555
+ let inSpecFence = false;
556
+ function processLine(line) {
557
+ const trimmed = line.trim();
558
+ if (!inSpecFence && trimmed.startsWith("```spec")) {
559
+ inSpecFence = true;
560
+ return;
561
+ }
562
+ if (inSpecFence && trimmed === "```") {
563
+ inSpecFence = false;
564
+ return;
565
+ }
566
+ if (!trimmed) return;
567
+ if (inSpecFence) {
568
+ const patch2 = parseSpecStreamLine(trimmed);
569
+ if (patch2) callbacks.onPatch(patch2);
570
+ return;
571
+ }
572
+ const patch = parseSpecStreamLine(trimmed);
573
+ if (patch) callbacks.onPatch(patch);
574
+ else callbacks.onText(line);
575
+ }
576
+ return {
577
+ push(chunk) {
578
+ buffer += chunk;
579
+ const lines = buffer.split("\n");
580
+ buffer = lines.pop() || "";
581
+ for (const line of lines) processLine(line);
582
+ },
583
+ flush() {
584
+ if (buffer.trim()) processLine(buffer);
585
+ buffer = "";
586
+ }
587
+ };
588
+ }
589
+ var SPEC_DATA_PART_TYPE = `data-spec`;
590
+ function immutableSetByPath(root, path, value) {
591
+ const segments = parseJsonPointer(path);
592
+ if (segments.length === 0) return root;
593
+ const result = { ...root };
594
+ let current = result;
595
+ for (let i = 0; i < segments.length - 1; i++) {
596
+ const seg = segments[i];
597
+ const child = current[seg];
598
+ if (Array.isArray(child)) current[seg] = [...child];
599
+ else if (child !== null && typeof child === "object") current[seg] = { ...child };
600
+ else {
601
+ const nextSeg = segments[i + 1];
602
+ current[seg] = nextSeg !== void 0 && /^\d+$/.test(nextSeg) ? [] : {};
603
+ }
604
+ current = current[seg];
605
+ }
606
+ const lastSeg = segments[segments.length - 1];
607
+ if (Array.isArray(current)) if (lastSeg === "-") current.push(value);
608
+ else current[parseInt(lastSeg, 10)] = value;
609
+ else current[lastSeg] = value;
610
+ return result;
611
+ }
612
+ function createStateStore(initialState = {}) {
613
+ let state = { ...initialState };
614
+ const listeners = /* @__PURE__ */ new Set();
615
+ function notify() {
616
+ for (const listener of listeners) listener();
617
+ }
618
+ return {
619
+ get(path) {
620
+ return getByPath(state, path);
621
+ },
622
+ set(path, value) {
623
+ if (getByPath(state, path) === value) return;
624
+ state = immutableSetByPath(state, path, value);
625
+ notify();
626
+ },
627
+ update(updates) {
628
+ let changed = false;
629
+ let next = state;
630
+ for (const [path, value] of Object.entries(updates)) if (getByPath(next, path) !== value) {
631
+ next = immutableSetByPath(next, path, value);
632
+ changed = true;
633
+ }
634
+ if (!changed) return;
635
+ state = next;
636
+ notify();
637
+ },
638
+ getSnapshot() {
639
+ return state;
640
+ },
641
+ getServerSnapshot() {
642
+ return state;
643
+ },
644
+ subscribe(listener) {
645
+ listeners.add(listener);
646
+ return () => {
647
+ listeners.delete(listener);
648
+ };
649
+ }
650
+ };
651
+ }
652
+ var MAX_FLATTEN_DEPTH = 20;
653
+ function flattenToPointers(obj, prefix = "", _depth = 0, _seen, _warned) {
654
+ const seen = _seen ?? /* @__PURE__ */ new Set();
655
+ const warned = _warned ?? { current: false };
656
+ const result = {};
657
+ for (const [key, value] of Object.entries(obj)) {
658
+ const pointer = `${prefix}/${key}`;
659
+ if (_depth < MAX_FLATTEN_DEPTH && value !== null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype && !seen.has(value)) {
660
+ seen.add(value);
661
+ Object.assign(result, flattenToPointers(value, pointer, _depth + 1, seen, warned));
662
+ } else {
663
+ if (process.env.NODE_ENV !== "production" && !warned.current && _depth >= MAX_FLATTEN_DEPTH && value !== null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype && !seen.has(value)) {
664
+ warned.current = true;
665
+ console.warn(`flattenToPointers: depth limit (${MAX_FLATTEN_DEPTH}) reached. Nested state beyond this depth will be treated as a leaf value.`);
666
+ }
667
+ result[pointer] = value;
668
+ }
669
+ }
670
+ return result;
671
+ }
672
+ //#endregion
673
+ //#region ../../node_modules/.bun/@json-render+core@0.15.0/node_modules/@json-render/core/dist/index.mjs
674
+ var numericOrStateRef = z.union([z.number(), z.object({ $state: z.string() })]);
675
+ var comparisonOps = {
676
+ eq: z.unknown().optional(),
677
+ neq: z.unknown().optional(),
678
+ gt: numericOrStateRef.optional(),
679
+ gte: numericOrStateRef.optional(),
680
+ lt: numericOrStateRef.optional(),
681
+ lte: numericOrStateRef.optional(),
682
+ not: z.literal(true).optional()
683
+ };
684
+ var StateConditionSchema = z.object({
685
+ $state: z.string(),
686
+ ...comparisonOps
687
+ });
688
+ var ItemConditionSchema = z.object({
689
+ $item: z.string(),
690
+ ...comparisonOps
691
+ });
692
+ var IndexConditionSchema = z.object({
693
+ $index: z.literal(true),
694
+ ...comparisonOps
695
+ });
696
+ var SingleConditionSchema = z.union([
697
+ StateConditionSchema,
698
+ ItemConditionSchema,
699
+ IndexConditionSchema
700
+ ]);
701
+ var VisibilityConditionSchema = z.lazy(() => z.union([
702
+ z.boolean(),
703
+ SingleConditionSchema,
704
+ z.array(SingleConditionSchema),
705
+ z.object({ $and: z.array(VisibilityConditionSchema) }),
706
+ z.object({ $or: z.array(VisibilityConditionSchema) })
707
+ ]));
708
+ function resolveComparisonValue(value, ctx) {
709
+ if (typeof value === "object" && value !== null) {
710
+ if ("$state" in value && typeof value.$state === "string") return getByPath(ctx.stateModel, value.$state);
711
+ }
712
+ return value;
713
+ }
714
+ function isItemCondition(cond) {
715
+ return "$item" in cond;
716
+ }
717
+ function isIndexCondition(cond) {
718
+ return "$index" in cond;
719
+ }
720
+ function resolveConditionValue(cond, ctx) {
721
+ if (isIndexCondition(cond)) return ctx.repeatIndex;
722
+ if (isItemCondition(cond)) {
723
+ if (ctx.repeatItem === void 0) return void 0;
724
+ return cond.$item === "" ? ctx.repeatItem : getByPath(ctx.repeatItem, cond.$item);
725
+ }
726
+ return getByPath(ctx.stateModel, cond.$state);
727
+ }
728
+ function evaluateCondition(cond, ctx) {
729
+ const value = resolveConditionValue(cond, ctx);
730
+ let result;
731
+ if (cond.eq !== void 0) result = value === resolveComparisonValue(cond.eq, ctx);
732
+ else if (cond.neq !== void 0) result = value !== resolveComparisonValue(cond.neq, ctx);
733
+ else if (cond.gt !== void 0) {
734
+ const rhs = resolveComparisonValue(cond.gt, ctx);
735
+ result = typeof value === "number" && typeof rhs === "number" ? value > rhs : false;
736
+ } else if (cond.gte !== void 0) {
737
+ const rhs = resolveComparisonValue(cond.gte, ctx);
738
+ result = typeof value === "number" && typeof rhs === "number" ? value >= rhs : false;
739
+ } else if (cond.lt !== void 0) {
740
+ const rhs = resolveComparisonValue(cond.lt, ctx);
741
+ result = typeof value === "number" && typeof rhs === "number" ? value < rhs : false;
742
+ } else if (cond.lte !== void 0) {
743
+ const rhs = resolveComparisonValue(cond.lte, ctx);
744
+ result = typeof value === "number" && typeof rhs === "number" ? value <= rhs : false;
745
+ } else result = Boolean(value);
746
+ return cond.not === true ? !result : result;
747
+ }
748
+ function isAndCondition(condition) {
749
+ return typeof condition === "object" && condition !== null && !Array.isArray(condition) && "$and" in condition;
750
+ }
751
+ function isOrCondition(condition) {
752
+ return typeof condition === "object" && condition !== null && !Array.isArray(condition) && "$or" in condition;
753
+ }
754
+ function evaluateVisibility(condition, ctx) {
755
+ if (condition === void 0) return true;
756
+ if (typeof condition === "boolean") return condition;
757
+ if (Array.isArray(condition)) return condition.every((c) => evaluateCondition(c, ctx));
758
+ if (isAndCondition(condition)) return condition.$and.every((child) => evaluateVisibility(child, ctx));
759
+ if (isOrCondition(condition)) return condition.$or.some((child) => evaluateVisibility(child, ctx));
760
+ return evaluateCondition(condition, ctx);
761
+ }
762
+ function isStateExpression(value) {
763
+ return typeof value === "object" && value !== null && "$state" in value && typeof value.$state === "string";
764
+ }
765
+ function isItemExpression(value) {
766
+ return typeof value === "object" && value !== null && "$item" in value && typeof value.$item === "string";
767
+ }
768
+ function isIndexExpression(value) {
769
+ return typeof value === "object" && value !== null && "$index" in value && value.$index === true;
770
+ }
771
+ function isBindStateExpression(value) {
772
+ return typeof value === "object" && value !== null && "$bindState" in value && typeof value.$bindState === "string";
773
+ }
774
+ function isBindItemExpression(value) {
775
+ return typeof value === "object" && value !== null && "$bindItem" in value && typeof value.$bindItem === "string";
776
+ }
777
+ function isCondExpression(value) {
778
+ return typeof value === "object" && value !== null && "$cond" in value && "$then" in value && "$else" in value;
779
+ }
780
+ function isComputedExpression(value) {
781
+ return typeof value === "object" && value !== null && "$computed" in value && typeof value.$computed === "string";
782
+ }
783
+ function isTemplateExpression(value) {
784
+ return typeof value === "object" && value !== null && "$template" in value && typeof value.$template === "string";
785
+ }
786
+ var WARNED_COMPUTED_MAX = 100;
787
+ var warnedComputedFns = /* @__PURE__ */ new Set();
788
+ var WARNED_TEMPLATE_MAX = 100;
789
+ var warnedTemplatePaths = /* @__PURE__ */ new Set();
790
+ function resolveBindItemPath(itemPath, ctx) {
791
+ if (ctx.repeatBasePath == null) {
792
+ console.warn(`$bindItem used outside repeat scope: "${itemPath}"`);
793
+ return;
794
+ }
795
+ if (itemPath === "") return ctx.repeatBasePath;
796
+ return ctx.repeatBasePath + "/" + itemPath;
797
+ }
798
+ function resolvePropValue(value, ctx) {
799
+ if (value === null || value === void 0) return value;
800
+ if (isStateExpression(value)) return getByPath(ctx.stateModel, value.$state);
801
+ if (isItemExpression(value)) {
802
+ if (ctx.repeatItem === void 0) return void 0;
803
+ return value.$item === "" ? ctx.repeatItem : getByPath(ctx.repeatItem, value.$item);
804
+ }
805
+ if (isIndexExpression(value)) return ctx.repeatIndex;
806
+ if (isBindStateExpression(value)) return getByPath(ctx.stateModel, value.$bindState);
807
+ if (isBindItemExpression(value)) {
808
+ const resolvedPath = resolveBindItemPath(value.$bindItem, ctx);
809
+ if (resolvedPath === void 0) return void 0;
810
+ return getByPath(ctx.stateModel, resolvedPath);
811
+ }
812
+ if (isCondExpression(value)) return resolvePropValue(evaluateVisibility(value.$cond, ctx) ? value.$then : value.$else, ctx);
813
+ if (isComputedExpression(value)) {
814
+ const fn = ctx.functions?.[value.$computed];
815
+ if (!fn) {
816
+ if (!warnedComputedFns.has(value.$computed)) {
817
+ if (warnedComputedFns.size < WARNED_COMPUTED_MAX) warnedComputedFns.add(value.$computed);
818
+ console.warn(`Unknown $computed function: "${value.$computed}"`);
819
+ }
820
+ return;
821
+ }
822
+ const resolvedArgs = {};
823
+ if (value.args) for (const [key, arg] of Object.entries(value.args)) resolvedArgs[key] = resolvePropValue(arg, ctx);
824
+ return fn(resolvedArgs);
825
+ }
826
+ if (isTemplateExpression(value)) return value.$template.replace(/\$\{([^}]+)\}/g, (_match, rawPath) => {
827
+ let path = rawPath;
828
+ if (!path.startsWith("/")) {
829
+ if (!warnedTemplatePaths.has(path)) {
830
+ if (warnedTemplatePaths.size < WARNED_TEMPLATE_MAX) warnedTemplatePaths.add(path);
831
+ console.warn(`$template path "${path}" should be a JSON Pointer starting with "/". Automatically resolving as "/${path}".`);
832
+ }
833
+ path = "/" + path;
834
+ }
835
+ const resolved = getByPath(ctx.stateModel, path);
836
+ return resolved != null ? String(resolved) : "";
837
+ });
838
+ if (Array.isArray(value)) return value.map((item) => resolvePropValue(item, ctx));
839
+ if (typeof value === "object") {
840
+ const resolved = {};
841
+ for (const [key, val] of Object.entries(value)) resolved[key] = resolvePropValue(val, ctx);
842
+ return resolved;
843
+ }
844
+ return value;
845
+ }
846
+ function resolveElementProps(props, ctx) {
847
+ const resolved = {};
848
+ for (const [key, value] of Object.entries(props)) resolved[key] = resolvePropValue(value, ctx);
849
+ return resolved;
850
+ }
851
+ function resolveBindings(props, ctx) {
852
+ let bindings;
853
+ for (const [key, value] of Object.entries(props)) if (isBindStateExpression(value)) {
854
+ if (!bindings) bindings = {};
855
+ bindings[key] = value.$bindState;
856
+ } else if (isBindItemExpression(value)) {
857
+ const resolved = resolveBindItemPath(value.$bindItem, ctx);
858
+ if (resolved !== void 0) {
859
+ if (!bindings) bindings = {};
860
+ bindings[key] = resolved;
861
+ }
862
+ }
863
+ return bindings;
864
+ }
865
+ function resolveActionParam(value, ctx) {
866
+ if (isItemExpression(value)) return resolveBindItemPath(value.$item, ctx);
867
+ if (isIndexExpression(value)) return ctx.repeatIndex;
868
+ return resolvePropValue(value, ctx);
869
+ }
870
+ var ActionConfirmSchema = z.object({
871
+ title: z.string(),
872
+ message: z.string(),
873
+ confirmLabel: z.string().optional(),
874
+ cancelLabel: z.string().optional(),
875
+ variant: z.enum(["default", "danger"]).optional()
876
+ });
877
+ var ActionOnSuccessSchema = z.union([
878
+ z.object({ navigate: z.string() }),
879
+ z.object({ set: z.record(z.string(), z.unknown()) }),
880
+ z.object({ action: z.string() })
881
+ ]);
882
+ var ActionOnErrorSchema = z.union([z.object({ set: z.record(z.string(), z.unknown()) }), z.object({ action: z.string() })]);
883
+ z.object({
884
+ action: z.string(),
885
+ params: z.record(z.string(), DynamicValueSchema).optional(),
886
+ confirm: ActionConfirmSchema.optional(),
887
+ onSuccess: ActionOnSuccessSchema.optional(),
888
+ onError: ActionOnErrorSchema.optional(),
889
+ preventDefault: z.boolean().optional()
890
+ });
891
+ function resolveAction(binding, stateModel) {
892
+ const resolvedParams = {};
893
+ if (binding.params) for (const [key, value] of Object.entries(binding.params)) resolvedParams[key] = resolveDynamicValue(value, stateModel);
894
+ let confirm = binding.confirm;
895
+ if (confirm) confirm = {
896
+ ...confirm,
897
+ message: interpolateString(confirm.message, stateModel),
898
+ title: interpolateString(confirm.title, stateModel)
899
+ };
900
+ return {
901
+ action: binding.action,
902
+ params: resolvedParams,
903
+ confirm,
904
+ onSuccess: binding.onSuccess,
905
+ onError: binding.onError
906
+ };
907
+ }
908
+ function interpolateString(template, stateModel) {
909
+ return template.replace(/\$\{([^}]+)\}/g, (_, path) => {
910
+ const value = resolveDynamicValue({ $state: path }, stateModel);
911
+ return String(value ?? "");
912
+ });
913
+ }
914
+ async function executeAction(ctx) {
915
+ const { action: action2, handler, setState, navigate, executeAction: executeAction2 } = ctx;
916
+ try {
917
+ await handler(action2.params);
918
+ if (action2.onSuccess) {
919
+ if ("navigate" in action2.onSuccess && navigate) navigate(action2.onSuccess.navigate);
920
+ else if ("set" in action2.onSuccess) for (const [path, value] of Object.entries(action2.onSuccess.set)) setState(path, value);
921
+ else if ("action" in action2.onSuccess && executeAction2) await executeAction2(action2.onSuccess.action);
922
+ }
923
+ } catch (error) {
924
+ if (action2.onError) {
925
+ if ("set" in action2.onError) for (const [path, value] of Object.entries(action2.onError.set)) setState(path, typeof value === "string" && value === "$error.message" ? error.message : value);
926
+ else if ("action" in action2.onError && executeAction2) await executeAction2(action2.onError.action);
927
+ } else throw error;
928
+ }
929
+ }
930
+ var ValidationCheckSchema = z.object({
931
+ type: z.string(),
932
+ args: z.record(z.string(), DynamicValueSchema).optional(),
933
+ message: z.string()
934
+ });
935
+ z.object({
936
+ checks: z.array(ValidationCheckSchema).optional(),
937
+ validateOn: z.enum([
938
+ "change",
939
+ "blur",
940
+ "submit"
941
+ ]).optional(),
942
+ enabled: VisibilityConditionSchema.optional()
943
+ });
944
+ var matchesImpl = (value, args) => {
945
+ return value === args?.other;
946
+ };
947
+ var builtInValidationFunctions = {
948
+ required: (value) => {
949
+ if (value === null || value === void 0) return false;
950
+ if (typeof value === "string") return value.trim().length > 0;
951
+ if (Array.isArray(value)) return value.length > 0;
952
+ return true;
953
+ },
954
+ email: (value) => {
955
+ if (typeof value !== "string") return false;
956
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
957
+ },
958
+ minLength: (value, args) => {
959
+ if (typeof value !== "string") return false;
960
+ const min = args?.min;
961
+ if (typeof min !== "number") return false;
962
+ return value.length >= min;
963
+ },
964
+ maxLength: (value, args) => {
965
+ if (typeof value !== "string") return false;
966
+ const max = args?.max;
967
+ if (typeof max !== "number") return false;
968
+ return value.length <= max;
969
+ },
970
+ pattern: (value, args) => {
971
+ if (typeof value !== "string") return false;
972
+ const pattern = args?.pattern;
973
+ if (typeof pattern !== "string") return false;
974
+ try {
975
+ return new RegExp(pattern).test(value);
976
+ } catch {
977
+ return false;
978
+ }
979
+ },
980
+ min: (value, args) => {
981
+ if (typeof value !== "number") return false;
982
+ const min = args?.min;
983
+ if (typeof min !== "number") return false;
984
+ return value >= min;
985
+ },
986
+ max: (value, args) => {
987
+ if (typeof value !== "number") return false;
988
+ const max = args?.max;
989
+ if (typeof max !== "number") return false;
990
+ return value <= max;
991
+ },
992
+ numeric: (value) => {
993
+ if (typeof value === "number") return !isNaN(value);
994
+ if (typeof value === "string") return !isNaN(parseFloat(value));
995
+ return false;
996
+ },
997
+ url: (value) => {
998
+ if (typeof value !== "string") return false;
999
+ try {
1000
+ new URL(value);
1001
+ return true;
1002
+ } catch {
1003
+ return false;
1004
+ }
1005
+ },
1006
+ matches: matchesImpl,
1007
+ equalTo: matchesImpl,
1008
+ lessThan: (value, args) => {
1009
+ const other = args?.other;
1010
+ if (value == null || other == null || value === "" || other === "") return false;
1011
+ if (typeof value === "number" && typeof other === "number") return value < other;
1012
+ if (typeof value === "string" && typeof other === "string") return value < other;
1013
+ const numVal = Number(value);
1014
+ const numOther = Number(other);
1015
+ if (!isNaN(numVal) && !isNaN(numOther)) return numVal < numOther;
1016
+ return false;
1017
+ },
1018
+ greaterThan: (value, args) => {
1019
+ const other = args?.other;
1020
+ if (value == null || other == null || value === "" || other === "") return false;
1021
+ if (typeof value === "number" && typeof other === "number") return value > other;
1022
+ if (typeof value === "string" && typeof other === "string") return value > other;
1023
+ const numVal = Number(value);
1024
+ const numOther = Number(other);
1025
+ if (!isNaN(numVal) && !isNaN(numOther)) return numVal > numOther;
1026
+ return false;
1027
+ },
1028
+ requiredIf: (value, args) => {
1029
+ if (!args?.field) return true;
1030
+ if (value === null || value === void 0) return false;
1031
+ if (typeof value === "string") return value.trim().length > 0;
1032
+ if (Array.isArray(value)) return value.length > 0;
1033
+ return true;
1034
+ }
1035
+ };
1036
+ function runValidationCheck(check2, ctx) {
1037
+ const { value, stateModel, customFunctions } = ctx;
1038
+ const resolvedArgs = {};
1039
+ if (check2.args) for (const [key, argValue] of Object.entries(check2.args)) resolvedArgs[key] = resolvePropValue(argValue, { stateModel });
1040
+ const validationFn = builtInValidationFunctions[check2.type] ?? customFunctions?.[check2.type];
1041
+ if (!validationFn) {
1042
+ console.warn(`Unknown validation function: ${check2.type}`);
1043
+ return {
1044
+ type: check2.type,
1045
+ valid: true,
1046
+ message: check2.message
1047
+ };
1048
+ }
1049
+ const valid = validationFn(value, resolvedArgs);
1050
+ return {
1051
+ type: check2.type,
1052
+ valid,
1053
+ message: check2.message
1054
+ };
1055
+ }
1056
+ function runValidation(config, ctx) {
1057
+ const checks = [];
1058
+ const errors = [];
1059
+ if (config.enabled) {
1060
+ if (!evaluateVisibility(config.enabled, { stateModel: ctx.stateModel })) return {
1061
+ valid: true,
1062
+ errors: [],
1063
+ checks: []
1064
+ };
1065
+ }
1066
+ if (config.checks) for (const check2 of config.checks) {
1067
+ const result = runValidationCheck(check2, ctx);
1068
+ checks.push(result);
1069
+ if (!result.valid) errors.push(result.message);
1070
+ }
1071
+ return {
1072
+ valid: errors.length === 0,
1073
+ errors,
1074
+ checks
1075
+ };
1076
+ }
1077
+ function validateSpec(spec, options = {}) {
1078
+ const { checkOrphans = false } = options;
1079
+ const issues = [];
1080
+ if (!spec.root) {
1081
+ issues.push({
1082
+ severity: "error",
1083
+ message: "Spec has no root element defined.",
1084
+ code: "missing_root"
1085
+ });
1086
+ return {
1087
+ valid: false,
1088
+ issues
1089
+ };
1090
+ }
1091
+ if (!spec.elements[spec.root]) issues.push({
1092
+ severity: "error",
1093
+ message: `Root element "${spec.root}" not found in elements map.`,
1094
+ code: "root_not_found"
1095
+ });
1096
+ if (Object.keys(spec.elements).length === 0) {
1097
+ issues.push({
1098
+ severity: "error",
1099
+ message: "Spec has no elements.",
1100
+ code: "empty_spec"
1101
+ });
1102
+ return {
1103
+ valid: false,
1104
+ issues
1105
+ };
1106
+ }
1107
+ for (const [key, element] of Object.entries(spec.elements)) {
1108
+ if (element.children) {
1109
+ for (const childKey of element.children) if (!spec.elements[childKey]) issues.push({
1110
+ severity: "error",
1111
+ message: `Element "${key}" references child "${childKey}" which does not exist in the elements map.`,
1112
+ elementKey: key,
1113
+ code: "missing_child"
1114
+ });
1115
+ }
1116
+ const props = element.props;
1117
+ if (props && "visible" in props && props.visible !== void 0) issues.push({
1118
+ severity: "error",
1119
+ message: `Element "${key}" has "visible" inside "props". It should be a top-level field on the element (sibling of type/props/children).`,
1120
+ elementKey: key,
1121
+ code: "visible_in_props"
1122
+ });
1123
+ if (props && "on" in props && props.on !== void 0) issues.push({
1124
+ severity: "error",
1125
+ message: `Element "${key}" has "on" inside "props". It should be a top-level field on the element (sibling of type/props/children).`,
1126
+ elementKey: key,
1127
+ code: "on_in_props"
1128
+ });
1129
+ if (props && "repeat" in props && props.repeat !== void 0) issues.push({
1130
+ severity: "error",
1131
+ message: `Element "${key}" has "repeat" inside "props". It should be a top-level field on the element (sibling of type/props/children).`,
1132
+ elementKey: key,
1133
+ code: "repeat_in_props"
1134
+ });
1135
+ if (props && "watch" in props && props.watch !== void 0) issues.push({
1136
+ severity: "error",
1137
+ message: `Element "${key}" has "watch" inside "props". It should be a top-level field on the element (sibling of type/props/children).`,
1138
+ elementKey: key,
1139
+ code: "watch_in_props"
1140
+ });
1141
+ }
1142
+ if (checkOrphans) {
1143
+ const reachable = /* @__PURE__ */ new Set();
1144
+ const walk = (key) => {
1145
+ if (reachable.has(key)) return;
1146
+ reachable.add(key);
1147
+ const el = spec.elements[key];
1148
+ if (el?.children) {
1149
+ for (const childKey of el.children) if (spec.elements[childKey]) walk(childKey);
1150
+ }
1151
+ };
1152
+ if (spec.elements[spec.root]) walk(spec.root);
1153
+ for (const key of Object.keys(spec.elements)) if (!reachable.has(key)) issues.push({
1154
+ severity: "warning",
1155
+ message: `Element "${key}" is not reachable from root "${spec.root}".`,
1156
+ elementKey: key,
1157
+ code: "orphaned_element"
1158
+ });
1159
+ }
1160
+ return {
1161
+ valid: !issues.some((i) => i.severity === "error"),
1162
+ issues
1163
+ };
1164
+ }
1165
+ function autoFixSpec(spec) {
1166
+ const fixes = [];
1167
+ const fixedElements = {};
1168
+ for (const [key, element] of Object.entries(spec.elements)) {
1169
+ const props = element.props;
1170
+ let fixed = element;
1171
+ if (props && "visible" in props && props.visible !== void 0) {
1172
+ const { visible, ...restProps } = fixed.props;
1173
+ fixed = {
1174
+ ...fixed,
1175
+ props: restProps,
1176
+ visible
1177
+ };
1178
+ fixes.push(`Moved "visible" from props to element level on "${key}".`);
1179
+ }
1180
+ let currentProps = fixed.props;
1181
+ if (currentProps && "on" in currentProps && currentProps.on !== void 0) {
1182
+ const { on, ...restProps } = currentProps;
1183
+ fixed = {
1184
+ ...fixed,
1185
+ props: restProps,
1186
+ on
1187
+ };
1188
+ fixes.push(`Moved "on" from props to element level on "${key}".`);
1189
+ }
1190
+ currentProps = fixed.props;
1191
+ if (currentProps && "repeat" in currentProps && currentProps.repeat !== void 0) {
1192
+ const { repeat, ...restProps } = currentProps;
1193
+ fixed = {
1194
+ ...fixed,
1195
+ props: restProps,
1196
+ repeat
1197
+ };
1198
+ fixes.push(`Moved "repeat" from props to element level on "${key}".`);
1199
+ }
1200
+ currentProps = fixed.props;
1201
+ if (currentProps && "watch" in currentProps && currentProps.watch !== void 0) {
1202
+ const { watch, ...restProps } = currentProps;
1203
+ fixed = {
1204
+ ...fixed,
1205
+ props: restProps,
1206
+ watch
1207
+ };
1208
+ fixes.push(`Moved "watch" from props to element level on "${key}".`);
1209
+ }
1210
+ fixedElements[key] = fixed;
1211
+ }
1212
+ return {
1213
+ spec: {
1214
+ root: spec.root,
1215
+ elements: fixedElements,
1216
+ state: spec.state
1217
+ },
1218
+ fixes
1219
+ };
1220
+ }
1221
+ var DEFAULT_MODES = ["patch"];
1222
+ function normalizeModes(config) {
1223
+ if (!config?.modes?.length) return DEFAULT_MODES;
1224
+ return config.modes;
1225
+ }
1226
+ function jsonPatchInstructions() {
1227
+ return [
1228
+ "PATCH MODE (RFC 6902 JSON Patch):",
1229
+ "Output one JSON object per line. Each line is a patch operation.",
1230
+ "- Add: {\"op\":\"add\",\"path\":\"/elements/new-key\",\"value\":{...}}",
1231
+ "- Replace: {\"op\":\"replace\",\"path\":\"/elements/existing-key\",\"value\":{...}}",
1232
+ "- Remove: {\"op\":\"remove\",\"path\":\"/elements/old-key\"}",
1233
+ "Only output patches for what needs to change."
1234
+ ].join("\n");
1235
+ }
1236
+ function jsonMergeInstructions() {
1237
+ return [
1238
+ "MERGE MODE (RFC 7396 JSON Merge Patch):",
1239
+ "Output a single JSON object on one line with __json_edit set to true.",
1240
+ "Include only the keys that changed. Unmentioned keys are preserved.",
1241
+ "Set a key to null to delete it.",
1242
+ "",
1243
+ "Example (update a title and add an element):",
1244
+ "{\"__json_edit\":true,\"elements\":{\"main\":{\"props\":{\"title\":\"New Title\"}},\"new-el\":{\"type\":\"Card\",\"props\":{},\"children\":[]}}}",
1245
+ "",
1246
+ "Example (delete an element):",
1247
+ "{\"__json_edit\":true,\"elements\":{\"old-widget\":null}}"
1248
+ ].join("\n");
1249
+ }
1250
+ function jsonDiffInstructions() {
1251
+ return [
1252
+ "DIFF MODE (unified diff):",
1253
+ "Output a unified diff inside a ```diff code fence.",
1254
+ "The diff applies against the JSON-serialized current spec.",
1255
+ "",
1256
+ "Example:",
1257
+ "```diff",
1258
+ "--- a/spec.json",
1259
+ "+++ b/spec.json",
1260
+ "@@ -3,1 +3,1 @@",
1261
+ "- \"title\": \"Login\"",
1262
+ "+ \"title\": \"Welcome Back\"",
1263
+ "```"
1264
+ ].join("\n");
1265
+ }
1266
+ function yamlPatchInstructions() {
1267
+ return [
1268
+ "PATCH MODE (RFC 6902 JSON Patch):",
1269
+ "Output RFC 6902 JSON Patch lines inside a ```yaml-patch code fence.",
1270
+ "Each line is one JSON patch operation.",
1271
+ "",
1272
+ "Example:",
1273
+ "```yaml-patch",
1274
+ "{\"op\":\"replace\",\"path\":\"/elements/main/props/title\",\"value\":\"New Title\"}",
1275
+ "{\"op\":\"add\",\"path\":\"/elements/new-el\",\"value\":{\"type\":\"Card\",\"props\":{},\"children\":[]}}",
1276
+ "```"
1277
+ ].join("\n");
1278
+ }
1279
+ function yamlMergeInstructions() {
1280
+ return [
1281
+ "MERGE MODE (RFC 7396 JSON Merge Patch):",
1282
+ "Output only the changed parts in a ```yaml-edit code fence.",
1283
+ "Uses deep merge semantics: only keys you include are updated. Unmentioned elements and props are preserved.",
1284
+ "Set a key to null to delete it.",
1285
+ "",
1286
+ "Example edit (update title, add a new element):",
1287
+ "```yaml-edit",
1288
+ "elements:",
1289
+ " main:",
1290
+ " props:",
1291
+ " title: Updated Title",
1292
+ " new-chart:",
1293
+ " type: Card",
1294
+ " props: {}",
1295
+ " children: []",
1296
+ "```",
1297
+ "",
1298
+ "Example deletion:",
1299
+ "```yaml-edit",
1300
+ "elements:",
1301
+ " old-widget: null",
1302
+ "```"
1303
+ ].join("\n");
1304
+ }
1305
+ function yamlDiffInstructions() {
1306
+ return [
1307
+ "DIFF MODE (unified diff):",
1308
+ "Output a unified diff inside a ```diff code fence.",
1309
+ "The diff applies against the YAML-serialized current spec.",
1310
+ "",
1311
+ "Example:",
1312
+ "```diff",
1313
+ "--- a/spec.yaml",
1314
+ "+++ b/spec.yaml",
1315
+ "@@ -6,1 +6,1 @@",
1316
+ "- title: Login",
1317
+ "+ title: Welcome Back",
1318
+ "```"
1319
+ ].join("\n");
1320
+ }
1321
+ function modeSelectionGuidance(modes) {
1322
+ if (modes.length === 1) return "";
1323
+ const parts = ["Choose the best edit strategy for the requested change:"];
1324
+ if (modes.includes("patch")) parts.push("- PATCH: best for precise, targeted single-field updates");
1325
+ if (modes.includes("merge")) parts.push("- MERGE: best for structural changes (add/remove elements, reparent children, update multiple props at once)");
1326
+ if (modes.includes("diff")) parts.push("- DIFF: best for small text-level changes when you can see the exact lines to change");
1327
+ return parts.join("\n");
1328
+ }
1329
+ function buildEditInstructions(config, format) {
1330
+ const modes = normalizeModes(config);
1331
+ const sections = [];
1332
+ sections.push("EDITING EXISTING SPECS:");
1333
+ sections.push("");
1334
+ const guidance = modeSelectionGuidance(modes);
1335
+ if (guidance) {
1336
+ sections.push(guidance);
1337
+ sections.push("");
1338
+ }
1339
+ for (const mode of modes) {
1340
+ if (format === "json") switch (mode) {
1341
+ case "patch":
1342
+ sections.push(jsonPatchInstructions());
1343
+ break;
1344
+ case "merge":
1345
+ sections.push(jsonMergeInstructions());
1346
+ break;
1347
+ case "diff":
1348
+ sections.push(jsonDiffInstructions());
1349
+ break;
1350
+ }
1351
+ else switch (mode) {
1352
+ case "patch":
1353
+ sections.push(yamlPatchInstructions());
1354
+ break;
1355
+ case "merge":
1356
+ sections.push(yamlMergeInstructions());
1357
+ break;
1358
+ case "diff":
1359
+ sections.push(yamlDiffInstructions());
1360
+ break;
1361
+ }
1362
+ sections.push("");
1363
+ }
1364
+ return sections.join("\n");
1365
+ }
1366
+ function addLineNumbers(text) {
1367
+ const lines = text.split("\n");
1368
+ const width = String(lines.length).length;
1369
+ return lines.map((line, i) => `${String(i + 1).padStart(width)}| ${line}`).join("\n");
1370
+ }
1371
+ function isNonEmptySpec(spec) {
1372
+ if (!spec || typeof spec !== "object") return false;
1373
+ const s = spec;
1374
+ return typeof s.root === "string" && typeof s.elements === "object" && s.elements !== null && Object.keys(s.elements).length > 0;
1375
+ }
1376
+ function buildEditUserPrompt(options) {
1377
+ const { prompt, currentSpec, config, format, maxPromptLength, serializer } = options;
1378
+ let userText = String(prompt || "");
1379
+ if (maxPromptLength !== void 0 && maxPromptLength > 0) userText = userText.slice(0, maxPromptLength);
1380
+ if (!isNonEmptySpec(currentSpec)) return userText;
1381
+ const modes = normalizeModes(config);
1382
+ const showLineNumbers = modes.includes("diff");
1383
+ const specText = (serializer ?? ((s) => JSON.stringify(s, null, 2)))(currentSpec);
1384
+ const parts = [];
1385
+ if (showLineNumbers) {
1386
+ parts.push("CURRENT UI STATE (line numbers for reference):");
1387
+ parts.push("```");
1388
+ parts.push(addLineNumbers(specText));
1389
+ parts.push("```");
1390
+ } else {
1391
+ parts.push("CURRENT UI STATE (already loaded, DO NOT recreate existing elements):");
1392
+ parts.push("```");
1393
+ parts.push(specText);
1394
+ parts.push("```");
1395
+ }
1396
+ parts.push("");
1397
+ parts.push(`USER REQUEST: ${userText}`);
1398
+ parts.push("");
1399
+ if (modes.length === 1) switch (modes[0]) {
1400
+ case "patch":
1401
+ parts.push(format === "yaml" ? "Output ONLY the patches in a ```yaml-patch fence." : "Output ONLY the JSON Patch lines needed for the change.");
1402
+ break;
1403
+ case "merge":
1404
+ parts.push(format === "yaml" ? "Output ONLY the changes in a ```yaml-edit fence. Include only keys that need to change." : "Output ONLY a single JSON merge line with __json_edit set to true. Include only keys that need to change.");
1405
+ break;
1406
+ case "diff":
1407
+ parts.push("Output ONLY the unified diff in a ```diff fence.");
1408
+ break;
1409
+ }
1410
+ else {
1411
+ const modeNames = modes.map((m) => {
1412
+ switch (m) {
1413
+ case "patch": return format === "yaml" ? "```yaml-patch fence" : "JSON Patch lines";
1414
+ case "merge": return format === "yaml" ? "```yaml-edit fence" : "JSON merge line (__json_edit)";
1415
+ case "diff": return "```diff fence";
1416
+ }
1417
+ });
1418
+ parts.push(`Choose the best edit strategy and output using one of: ${modeNames.join(", ")}`);
1419
+ }
1420
+ return parts.join("\n");
1421
+ }
1422
+ function createBuilder() {
1423
+ return {
1424
+ string: () => ({ kind: "string" }),
1425
+ number: () => ({ kind: "number" }),
1426
+ boolean: () => ({ kind: "boolean" }),
1427
+ array: (item) => ({
1428
+ kind: "array",
1429
+ inner: item
1430
+ }),
1431
+ object: (shape) => ({
1432
+ kind: "object",
1433
+ inner: shape
1434
+ }),
1435
+ record: (value) => ({
1436
+ kind: "record",
1437
+ inner: value
1438
+ }),
1439
+ any: () => ({ kind: "any" }),
1440
+ zod: () => ({ kind: "zod" }),
1441
+ ref: (path) => ({
1442
+ kind: "ref",
1443
+ inner: path
1444
+ }),
1445
+ propsOf: (path) => ({
1446
+ kind: "propsOf",
1447
+ inner: path
1448
+ }),
1449
+ map: (entryShape) => ({
1450
+ kind: "map",
1451
+ inner: entryShape
1452
+ }),
1453
+ optional: () => ({ optional: true })
1454
+ };
1455
+ }
1456
+ function defineSchema(builder, options) {
1457
+ return {
1458
+ definition: builder(createBuilder()),
1459
+ promptTemplate: options?.promptTemplate,
1460
+ defaultRules: options?.defaultRules,
1461
+ builtInActions: options?.builtInActions,
1462
+ createCatalog(catalog) {
1463
+ return createCatalogFromSchema(this, catalog);
1464
+ }
1465
+ };
1466
+ }
1467
+ function createCatalogFromSchema(schema, catalogData) {
1468
+ const components = catalogData.components;
1469
+ const actions = catalogData.actions;
1470
+ const componentNames = components ? Object.keys(components) : [];
1471
+ const actionNames = actions ? Object.keys(actions) : [];
1472
+ const zodSchema = buildZodSchemaFromDefinition(schema.definition, catalogData);
1473
+ return {
1474
+ schema,
1475
+ data: catalogData,
1476
+ componentNames,
1477
+ actionNames,
1478
+ prompt(options = {}) {
1479
+ return generatePrompt(this, options);
1480
+ },
1481
+ jsonSchema(options = {}) {
1482
+ return zodToJsonSchema(zodSchema, options.strict ?? false);
1483
+ },
1484
+ validate(spec) {
1485
+ const result = zodSchema.safeParse(spec);
1486
+ if (result.success) return {
1487
+ success: true,
1488
+ data: result.data
1489
+ };
1490
+ return {
1491
+ success: false,
1492
+ error: result.error
1493
+ };
1494
+ },
1495
+ zodSchema() {
1496
+ return zodSchema;
1497
+ },
1498
+ get _specType() {
1499
+ throw new Error("_specType is only for type inference");
1500
+ }
1501
+ };
1502
+ }
1503
+ function buildZodSchemaFromDefinition(definition, catalogData) {
1504
+ return buildZodType(definition.spec, catalogData);
1505
+ }
1506
+ function buildZodType(schemaType, catalogData) {
1507
+ switch (schemaType.kind) {
1508
+ case "string": return z.string();
1509
+ case "number": return z.number();
1510
+ case "boolean": return z.boolean();
1511
+ case "any": return z.any();
1512
+ case "array": {
1513
+ const inner = buildZodType(schemaType.inner, catalogData);
1514
+ return z.array(inner);
1515
+ }
1516
+ case "object": {
1517
+ const shape = schemaType.inner;
1518
+ const zodShape = {};
1519
+ for (const [key, value] of Object.entries(shape)) {
1520
+ let zodType = buildZodType(value, catalogData);
1521
+ if (value.optional) zodType = zodType.optional();
1522
+ zodShape[key] = zodType;
1523
+ }
1524
+ return z.object(zodShape);
1525
+ }
1526
+ case "record": {
1527
+ const inner = buildZodType(schemaType.inner, catalogData);
1528
+ return z.record(z.string(), inner);
1529
+ }
1530
+ case "ref": {
1531
+ const path = schemaType.inner;
1532
+ const keys = getKeysFromPath(path, catalogData);
1533
+ if (keys.length === 0) return z.string();
1534
+ if (keys.length === 1) return z.literal(keys[0]);
1535
+ return z.enum(keys);
1536
+ }
1537
+ case "propsOf": {
1538
+ const path = schemaType.inner;
1539
+ const propsSchemas = getPropsFromPath(path, catalogData);
1540
+ if (propsSchemas.length === 0) return z.record(z.string(), z.unknown());
1541
+ if (propsSchemas.length === 1) return propsSchemas[0];
1542
+ return z.record(z.string(), z.unknown());
1543
+ }
1544
+ default: return z.unknown();
1545
+ }
1546
+ }
1547
+ function getKeysFromPath(path, catalogData) {
1548
+ const parts = path.split(".");
1549
+ let current = { catalog: catalogData };
1550
+ for (const part of parts) if (current && typeof current === "object") current = current[part];
1551
+ else return [];
1552
+ if (current && typeof current === "object") return Object.keys(current);
1553
+ return [];
1554
+ }
1555
+ function getPropsFromPath(path, catalogData) {
1556
+ const parts = path.split(".");
1557
+ let current = { catalog: catalogData };
1558
+ for (const part of parts) if (current && typeof current === "object") current = current[part];
1559
+ else return [];
1560
+ if (current && typeof current === "object") return Object.values(current).map((entry) => entry.props).filter((props) => props !== void 0);
1561
+ return [];
1562
+ }
1563
+ function generatePrompt(catalog, options) {
1564
+ if (catalog.schema.promptTemplate) {
1565
+ const context = {
1566
+ catalog: catalog.data,
1567
+ componentNames: catalog.componentNames,
1568
+ actionNames: catalog.actionNames,
1569
+ options,
1570
+ formatZodType
1571
+ };
1572
+ return catalog.schema.promptTemplate(context);
1573
+ }
1574
+ const { system = "You are a UI generator that outputs JSON.", customRules = [], mode: rawMode = "standalone" } = options;
1575
+ const mode = rawMode === "chat" ? (console.warn("[json-render] mode \"chat\" is deprecated, use \"inline\" instead"), "inline") : rawMode === "generate" ? (console.warn("[json-render] mode \"generate\" is deprecated, use \"standalone\" instead"), "standalone") : rawMode;
1576
+ const lines = [];
1577
+ lines.push(system);
1578
+ lines.push("");
1579
+ if (mode === "inline") {
1580
+ lines.push("OUTPUT FORMAT (text + JSONL, RFC 6902 JSON Patch):");
1581
+ lines.push("You respond conversationally. When generating UI, first write a brief explanation (1-3 sentences), then output JSONL patch lines wrapped in a ```spec code fence.");
1582
+ lines.push("The JSONL lines use RFC 6902 JSON Patch operations to build a UI tree. Always wrap them in a ```spec fence block:");
1583
+ lines.push(" ```spec");
1584
+ lines.push(" {\"op\":\"add\",\"path\":\"/root\",\"value\":\"main\"}");
1585
+ lines.push(" {\"op\":\"add\",\"path\":\"/elements/main\",\"value\":{\"type\":\"Card\",\"props\":{\"title\":\"Hello\"},\"children\":[]}}");
1586
+ lines.push(" ```");
1587
+ lines.push("If the user's message does not require a UI (e.g. a greeting or clarifying question), respond with text only — no JSONL.");
1588
+ } else {
1589
+ lines.push("OUTPUT FORMAT (JSONL, RFC 6902 JSON Patch):");
1590
+ lines.push("Output JSONL (one JSON object per line) using RFC 6902 JSON Patch operations to build a UI tree.");
1591
+ }
1592
+ lines.push("Each line is a JSON patch operation (add, remove, replace). Start with /root, then stream /elements and /state patches interleaved so the UI fills in progressively as it streams.");
1593
+ lines.push("");
1594
+ lines.push("Example output (each line is a separate JSON object):");
1595
+ lines.push("");
1596
+ const allComponents = catalog.data.components;
1597
+ const cn = catalog.componentNames;
1598
+ const comp1 = cn[0] || "Component";
1599
+ const comp2 = cn.length > 1 ? cn[1] : comp1;
1600
+ const comp1Def = allComponents?.[comp1];
1601
+ const comp2Def = allComponents?.[comp2];
1602
+ const comp1Props = comp1Def ? getExampleProps(comp1Def) : {};
1603
+ const comp2Props = comp2Def ? getExampleProps(comp2Def) : {};
1604
+ const dynamicPropName = comp2Def?.props ? findFirstStringProp(comp2Def.props) : null;
1605
+ const dynamicProps = dynamicPropName ? {
1606
+ ...comp2Props,
1607
+ [dynamicPropName]: { $item: "title" }
1608
+ } : comp2Props;
1609
+ const exampleOutput = [
1610
+ JSON.stringify({
1611
+ op: "add",
1612
+ path: "/root",
1613
+ value: "main"
1614
+ }),
1615
+ JSON.stringify({
1616
+ op: "add",
1617
+ path: "/elements/main",
1618
+ value: {
1619
+ type: comp1,
1620
+ props: comp1Props,
1621
+ children: ["child-1", "list"]
1622
+ }
1623
+ }),
1624
+ JSON.stringify({
1625
+ op: "add",
1626
+ path: "/elements/child-1",
1627
+ value: {
1628
+ type: comp2,
1629
+ props: comp2Props,
1630
+ children: []
1631
+ }
1632
+ }),
1633
+ JSON.stringify({
1634
+ op: "add",
1635
+ path: "/elements/list",
1636
+ value: {
1637
+ type: comp1,
1638
+ props: comp1Props,
1639
+ repeat: {
1640
+ statePath: "/items",
1641
+ key: "id"
1642
+ },
1643
+ children: ["item"]
1644
+ }
1645
+ }),
1646
+ JSON.stringify({
1647
+ op: "add",
1648
+ path: "/elements/item",
1649
+ value: {
1650
+ type: comp2,
1651
+ props: dynamicProps,
1652
+ children: []
1653
+ }
1654
+ }),
1655
+ JSON.stringify({
1656
+ op: "add",
1657
+ path: "/state/items",
1658
+ value: []
1659
+ }),
1660
+ JSON.stringify({
1661
+ op: "add",
1662
+ path: "/state/items/0",
1663
+ value: {
1664
+ id: "1",
1665
+ title: "First Item"
1666
+ }
1667
+ }),
1668
+ JSON.stringify({
1669
+ op: "add",
1670
+ path: "/state/items/1",
1671
+ value: {
1672
+ id: "2",
1673
+ title: "Second Item"
1674
+ }
1675
+ })
1676
+ ].join("\n");
1677
+ lines.push(`${exampleOutput}
1678
+
1679
+ Note: state patches appear right after the elements that use them, so the UI fills in as it streams. ONLY use component types from the AVAILABLE COMPONENTS list below.`);
1680
+ lines.push("");
1681
+ lines.push("INITIAL STATE:");
1682
+ lines.push("Specs include a /state field to seed the state model. Components with { $bindState } or { $bindItem } read from and write to this state, and $state expressions read from it.");
1683
+ lines.push("CRITICAL: You MUST include state patches whenever your UI displays data via $state, $bindState, $bindItem, $item, or $index expressions, or uses repeat to iterate over arrays. Without state, these references resolve to nothing and repeat lists render zero items.");
1684
+ lines.push("Output state patches right after the elements that reference them, so the UI fills in progressively as it streams.");
1685
+ lines.push("Stream state progressively - output one patch per array item instead of one giant blob:");
1686
+ lines.push(" For arrays: {\"op\":\"add\",\"path\":\"/state/posts/0\",\"value\":{\"id\":\"1\",\"title\":\"First Post\",...}} then /state/posts/1, /state/posts/2, etc.");
1687
+ lines.push(" For scalars: {\"op\":\"add\",\"path\":\"/state/newTodoText\",\"value\":\"\"}");
1688
+ lines.push(" Initialize the array first if needed: {\"op\":\"add\",\"path\":\"/state/posts\",\"value\":[]}");
1689
+ lines.push("When content comes from the state model, use { \"$state\": \"/some/path\" } dynamic props to display it instead of hardcoding the same value in both state and props. The state model is the single source of truth.");
1690
+ lines.push("Include realistic sample data in state. For blogs: 3-4 posts with titles, excerpts, authors, dates. For product lists: 3-5 items with names, prices, descriptions. Never leave arrays empty.");
1691
+ lines.push("");
1692
+ lines.push("DYNAMIC LISTS (repeat field):");
1693
+ lines.push("Any element can have a top-level \"repeat\" field to render its children once per item in a state array: { \"repeat\": { \"statePath\": \"/arrayPath\", \"key\": \"id\" } }.");
1694
+ lines.push("The element itself renders once (as the container), and its children are expanded once per array item. \"statePath\" is the state array path. \"key\" is an optional field name on each item for stable React keys.");
1695
+ lines.push(`Example: ${JSON.stringify({
1696
+ type: comp1,
1697
+ props: comp1Props,
1698
+ repeat: {
1699
+ statePath: "/todos",
1700
+ key: "id"
1701
+ },
1702
+ children: ["todo-item"]
1703
+ })}`);
1704
+ lines.push("Inside children of a repeated element, use { \"$item\": \"field\" } to read a field from the current item, and { \"$index\": true } to get the current array index. For two-way binding to an item field use { \"$bindItem\": \"completed\" } on the appropriate prop.");
1705
+ lines.push("ALWAYS use the repeat field for lists backed by state arrays. NEVER hardcode individual elements for each array item.");
1706
+ lines.push("IMPORTANT: \"repeat\" is a top-level field on the element (sibling of type/props/children), NOT inside props.");
1707
+ lines.push("");
1708
+ lines.push("ARRAY STATE ACTIONS:");
1709
+ lines.push("Use action \"pushState\" to append items to arrays. Params: { statePath: \"/arrayPath\", value: { ...item }, clearStatePath: \"/inputPath\" }.");
1710
+ lines.push("Values inside pushState can contain { \"$state\": \"/statePath\" } references to read current state (e.g. the text from an input field).");
1711
+ lines.push("Use \"$id\" inside a pushState value to auto-generate a unique ID.");
1712
+ lines.push("Example: on: { \"press\": { \"action\": \"pushState\", \"params\": { \"statePath\": \"/todos\", \"value\": { \"id\": \"$id\", \"title\": { \"$state\": \"/newTodoText\" }, \"completed\": false }, \"clearStatePath\": \"/newTodoText\" } } }");
1713
+ lines.push(`Use action "removeState" to remove items from arrays by index. Params: { statePath: "/arrayPath", index: N }. Inside a repeated element's children, use { "$index": true } for the current item index. Action params support the same expressions as props: { "$item": "field" } resolves to the absolute state path, { "$index": true } resolves to the index number, and { "$state": "/path" } reads a value from state.`);
1714
+ lines.push("For lists where users can add/remove items (todos, carts, etc.), use pushState and removeState instead of hardcoding with setState.");
1715
+ lines.push("");
1716
+ lines.push("IMPORTANT: State paths use RFC 6901 JSON Pointer syntax (e.g. \"/todos/0/title\"). Do NOT use JavaScript-style dot notation (e.g. \"/todos.length\" is WRONG). To generate unique IDs for new items, use \"$id\" instead of trying to read array length.");
1717
+ lines.push("");
1718
+ const components = allComponents;
1719
+ if (components) {
1720
+ lines.push(`AVAILABLE COMPONENTS (${catalog.componentNames.length}):`);
1721
+ lines.push("");
1722
+ for (const [name, def] of Object.entries(components)) {
1723
+ const propsStr = def.props ? formatZodType(def.props) : "{}";
1724
+ const childrenStr = def.slots && def.slots.length > 0 ? " [accepts children]" : "";
1725
+ const eventsStr = def.events && def.events.length > 0 ? ` [events: ${def.events.join(", ")}]` : "";
1726
+ const descStr = def.description ? ` - ${def.description}` : "";
1727
+ lines.push(`- ${name}: ${propsStr}${descStr}${childrenStr}${eventsStr}`);
1728
+ }
1729
+ lines.push("");
1730
+ }
1731
+ const actions = catalog.data.actions;
1732
+ const builtInActions = catalog.schema.builtInActions ?? [];
1733
+ const hasCustomActions = actions && catalog.actionNames.length > 0;
1734
+ const hasBuiltInActions = builtInActions.length > 0;
1735
+ if (hasCustomActions || hasBuiltInActions) {
1736
+ lines.push("AVAILABLE ACTIONS:");
1737
+ lines.push("");
1738
+ for (const action2 of builtInActions) lines.push(`- ${action2.name}: ${action2.description} [built-in]`);
1739
+ if (hasCustomActions) for (const [name, def] of Object.entries(actions)) lines.push(`- ${name}${def.description ? `: ${def.description}` : ""}`);
1740
+ lines.push("");
1741
+ }
1742
+ lines.push("EVENTS (the `on` field):");
1743
+ lines.push("Elements can have an optional `on` field to bind events to actions. The `on` field is a top-level field on the element (sibling of type/props/children), NOT inside props.");
1744
+ lines.push("Each key in `on` is an event name (from the component's supported events), and the value is an action binding: `{ \"action\": \"<actionName>\", \"params\": { ... } }`.");
1745
+ lines.push("");
1746
+ lines.push("Example:");
1747
+ lines.push(` ${JSON.stringify({
1748
+ type: comp1,
1749
+ props: comp1Props,
1750
+ on: { press: {
1751
+ action: "setState",
1752
+ params: {
1753
+ statePath: "/saved",
1754
+ value: true
1755
+ }
1756
+ } },
1757
+ children: []
1758
+ })}`);
1759
+ lines.push("");
1760
+ lines.push("Action params can use dynamic references to read from state: { \"$state\": \"/statePath\" }.");
1761
+ lines.push("IMPORTANT: Do NOT put action/actionParams inside props. Always use the `on` field for event bindings.");
1762
+ lines.push("");
1763
+ lines.push("VISIBILITY CONDITIONS:");
1764
+ lines.push("Elements can have an optional `visible` field to conditionally show/hide based on state. IMPORTANT: `visible` is a top-level field on the element object (sibling of type/props/children), NOT inside props.");
1765
+ lines.push(`Correct: ${JSON.stringify({
1766
+ type: comp1,
1767
+ props: comp1Props,
1768
+ visible: {
1769
+ $state: "/activeTab",
1770
+ eq: "home"
1771
+ },
1772
+ children: ["..."]
1773
+ })}`);
1774
+ lines.push("- `{ \"$state\": \"/path\" }` - visible when state at path is truthy");
1775
+ lines.push("- `{ \"$state\": \"/path\", \"not\": true }` - visible when state at path is falsy");
1776
+ lines.push("- `{ \"$state\": \"/path\", \"eq\": \"value\" }` - visible when state equals value");
1777
+ lines.push("- `{ \"$state\": \"/path\", \"neq\": \"value\" }` - visible when state does not equal value");
1778
+ lines.push("- `{ \"$state\": \"/path\", \"gt\": N }` / `gte` / `lt` / `lte` - numeric comparisons");
1779
+ lines.push("- Use ONE operator per condition (eq, neq, gt, gte, lt, lte). Do not combine multiple operators.");
1780
+ lines.push("- Any condition can add `\"not\": true` to invert its result");
1781
+ lines.push("- `[condition, condition]` - all conditions must be true (implicit AND)");
1782
+ lines.push("- `{ \"$and\": [condition, condition] }` - explicit AND (use when nesting inside $or)");
1783
+ lines.push("- `{ \"$or\": [condition, condition] }` - at least one must be true (OR)");
1784
+ lines.push("- `true` / `false` - always visible/hidden");
1785
+ lines.push("");
1786
+ lines.push("Use a component with on.press bound to setState to update state and drive visibility.");
1787
+ lines.push(`Example: A ${comp1} with on: { "press": { "action": "setState", "params": { "statePath": "/activeTab", "value": "home" } } } sets state, then a container with visible: { "$state": "/activeTab", "eq": "home" } shows only when that tab is active.`);
1788
+ lines.push("");
1789
+ lines.push("For tab patterns where the first/default tab should be visible when no tab is selected yet, use $or to handle both cases: visible: { \"$or\": [{ \"$state\": \"/activeTab\", \"eq\": \"home\" }, { \"$state\": \"/activeTab\", \"not\": true }] }. This ensures the first tab is visible both when explicitly selected AND when /activeTab is not yet set.");
1790
+ lines.push("");
1791
+ lines.push("DYNAMIC PROPS:");
1792
+ lines.push("Any prop value can be a dynamic expression that resolves based on state. Three forms are supported:");
1793
+ lines.push("");
1794
+ lines.push("1. Read-only state: `{ \"$state\": \"/statePath\" }` - resolves to the value at that state path (one-way read).");
1795
+ lines.push(" Example: `\"color\": { \"$state\": \"/theme/primary\" }` reads the color from state.");
1796
+ lines.push("");
1797
+ lines.push("2. Two-way binding: `{ \"$bindState\": \"/statePath\" }` - resolves to the value at the state path AND enables write-back. Use on form input props (value, checked, pressed, etc.).");
1798
+ lines.push(" Example: `\"value\": { \"$bindState\": \"/form/email\" }` binds the input value to /form/email.");
1799
+ lines.push(" Inside repeat scopes: `\"checked\": { \"$bindItem\": \"completed\" }` binds to the current item's completed field.");
1800
+ lines.push("");
1801
+ lines.push("3. Conditional: `{ \"$cond\": <condition>, \"$then\": <value>, \"$else\": <value> }` - evaluates the condition (same syntax as visibility conditions) and picks the matching value.");
1802
+ lines.push(" Example: `\"color\": { \"$cond\": { \"$state\": \"/activeTab\", \"eq\": \"home\" }, \"$then\": \"#007AFF\", \"$else\": \"#8E8E93\" }`");
1803
+ lines.push("");
1804
+ lines.push("Use $bindState for form inputs (text fields, checkboxes, selects, sliders, etc.) and $state for read-only data display. Inside repeat scopes, use $bindItem for form inputs bound to the current item. Use dynamic props instead of duplicating elements with opposing visible conditions when only prop values differ.");
1805
+ lines.push("");
1806
+ lines.push("4. Template: `{ \"$template\": \"Hello, ${/name}!\" }` - interpolates `${/path}` references in the string with values from the state model.");
1807
+ lines.push(" Example: `\"label\": { \"$template\": \"Items: ${/cart/count} | Total: ${/cart/total}\" }` renders \"Items: 3 | Total: 42.00\" when /cart/count is 3 and /cart/total is 42.00.");
1808
+ lines.push("");
1809
+ const catalogFunctions = catalog.data.functions;
1810
+ if (catalogFunctions && Object.keys(catalogFunctions).length > 0) {
1811
+ lines.push("5. Computed: `{ \"$computed\": \"<functionName>\", \"args\": { \"key\": <expression> } }` - calls a registered function with resolved args and returns the result.");
1812
+ lines.push(" Example: `\"value\": { \"$computed\": \"fullName\", \"args\": { \"first\": { \"$state\": \"/form/firstName\" }, \"last\": { \"$state\": \"/form/lastName\" } } }`");
1813
+ lines.push(" Available functions:");
1814
+ for (const name of Object.keys(catalogFunctions)) lines.push(` - ${name}`);
1815
+ lines.push("");
1816
+ }
1817
+ if (allComponents ? Object.entries(allComponents).some(([, def]) => {
1818
+ if (!def.props) return false;
1819
+ return formatZodType(def.props).includes("checks");
1820
+ }) : false) {
1821
+ lines.push("VALIDATION:");
1822
+ lines.push("Form components that accept a `checks` prop support client-side validation.");
1823
+ lines.push("Each check is an object: { \"type\": \"<name>\", \"message\": \"...\", \"args\": { ... } }");
1824
+ lines.push("");
1825
+ lines.push("Built-in validation types:");
1826
+ lines.push(" - required — value must be non-empty");
1827
+ lines.push(" - email — valid email format");
1828
+ lines.push(" - minLength — minimum string length (args: { \"min\": N })");
1829
+ lines.push(" - maxLength — maximum string length (args: { \"max\": N })");
1830
+ lines.push(" - pattern — match a regex (args: { \"pattern\": \"regex\" })");
1831
+ lines.push(" - min — minimum numeric value (args: { \"min\": N })");
1832
+ lines.push(" - max — maximum numeric value (args: { \"max\": N })");
1833
+ lines.push(" - numeric — value must be a number");
1834
+ lines.push(" - url — valid URL format");
1835
+ lines.push(" - matches — must equal another field (args: { \"other\": { \"$state\": \"/path\" } })");
1836
+ lines.push(" - equalTo — alias for matches (args: { \"other\": { \"$state\": \"/path\" } })");
1837
+ lines.push(" - lessThan — value must be less than another field (args: { \"other\": { \"$state\": \"/path\" } })");
1838
+ lines.push(" - greaterThan — value must be greater than another field (args: { \"other\": { \"$state\": \"/path\" } })");
1839
+ lines.push(" - requiredIf — required only when another field is truthy (args: { \"field\": { \"$state\": \"/path\" } })");
1840
+ lines.push("");
1841
+ lines.push("Example:");
1842
+ lines.push(" \"checks\": [{ \"type\": \"required\", \"message\": \"Email is required\" }, { \"type\": \"email\", \"message\": \"Invalid email\" }]");
1843
+ lines.push("");
1844
+ lines.push("IMPORTANT: When using checks, the component must also have a { $bindState } or { $bindItem } on its value/checked prop for two-way binding.");
1845
+ lines.push("Always include validation checks on form inputs for a good user experience (e.g. required, email, minLength).");
1846
+ lines.push("");
1847
+ }
1848
+ if (hasCustomActions || hasBuiltInActions) {
1849
+ lines.push("STATE WATCHERS:");
1850
+ lines.push("Elements can have an optional `watch` field to react to state changes and trigger actions. The `watch` field is a top-level field on the element (sibling of type/props/children), NOT inside props.");
1851
+ lines.push("Maps state paths (JSON Pointers) to action bindings. When the value at a watched path changes, the bound actions fire automatically.");
1852
+ lines.push("");
1853
+ lines.push("Example (cascading select — country changes trigger city loading):");
1854
+ lines.push(` ${JSON.stringify({
1855
+ type: "Select",
1856
+ props: {
1857
+ value: { $bindState: "/form/country" },
1858
+ options: [
1859
+ "US",
1860
+ "Canada",
1861
+ "UK"
1862
+ ]
1863
+ },
1864
+ watch: { "/form/country": {
1865
+ action: "loadCities",
1866
+ params: { country: { $state: "/form/country" } }
1867
+ } },
1868
+ children: []
1869
+ })}`);
1870
+ lines.push("");
1871
+ lines.push("Use `watch` for cascading dependencies where changing one field should trigger side effects (loading data, resetting dependent fields, computing derived values).");
1872
+ lines.push("IMPORTANT: `watch` is a top-level field on the element (sibling of type/props/children), NOT inside props. Watchers only fire when the value changes, not on initial render.");
1873
+ lines.push("");
1874
+ }
1875
+ const editModes = options.editModes;
1876
+ if (editModes && editModes.length > 0) lines.push(buildEditInstructions({ modes: editModes }, "json"));
1877
+ lines.push("RULES:");
1878
+ const baseRules = mode === "inline" ? [
1879
+ "When generating UI, wrap all JSONL patches in a ```spec code fence - one JSON object per line inside the fence",
1880
+ "Write a brief conversational response before any JSONL output",
1881
+ "First set root: {\"op\":\"add\",\"path\":\"/root\",\"value\":\"<root-key>\"}",
1882
+ "Then add each element: {\"op\":\"add\",\"path\":\"/elements/<key>\",\"value\":{...}}",
1883
+ "Output /state patches right after the elements that use them, one per array item for progressive loading. REQUIRED whenever using $state, $bindState, $bindItem, $item, $index, or repeat.",
1884
+ "ONLY use components listed above",
1885
+ "Each element value needs: type, props, children (array of child keys)",
1886
+ "Use unique keys for the element map entries (e.g., 'header', 'metric-1', 'chart-revenue')"
1887
+ ] : [
1888
+ "Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences",
1889
+ "First set root: {\"op\":\"add\",\"path\":\"/root\",\"value\":\"<root-key>\"}",
1890
+ "Then add each element: {\"op\":\"add\",\"path\":\"/elements/<key>\",\"value\":{...}}",
1891
+ "Output /state patches right after the elements that use them, one per array item for progressive loading. REQUIRED whenever using $state, $bindState, $bindItem, $item, $index, or repeat.",
1892
+ "ONLY use components listed above",
1893
+ "Each element value needs: type, props, children (array of child keys)",
1894
+ "Use unique keys for the element map entries (e.g., 'header', 'metric-1', 'chart-revenue')"
1895
+ ];
1896
+ const schemaRules = catalog.schema.defaultRules ?? [];
1897
+ [
1898
+ ...baseRules,
1899
+ ...schemaRules,
1900
+ ...customRules
1901
+ ].forEach((rule, i) => {
1902
+ lines.push(`${i + 1}. ${rule}`);
1903
+ });
1904
+ return lines.join("\n");
1905
+ }
1906
+ function getExampleProps(def) {
1907
+ if (def.example && Object.keys(def.example).length > 0) return def.example;
1908
+ if (def.props) return generateExamplePropsFromZod(def.props);
1909
+ return {};
1910
+ }
1911
+ function generateExamplePropsFromZod(schema) {
1912
+ if (!schema || !schema._def) return {};
1913
+ const def = schema._def;
1914
+ const typeName = getZodTypeName(schema);
1915
+ if (typeName !== "ZodObject" && typeName !== "object") return {};
1916
+ const shape = typeof def.shape === "function" ? def.shape() : def.shape;
1917
+ if (!shape) return {};
1918
+ const result = {};
1919
+ for (const [key, value] of Object.entries(shape)) {
1920
+ const innerTypeName = getZodTypeName(value);
1921
+ if (innerTypeName === "ZodOptional" || innerTypeName === "optional" || innerTypeName === "ZodNullable" || innerTypeName === "nullable") continue;
1922
+ result[key] = generateExampleValue(value);
1923
+ }
1924
+ return result;
1925
+ }
1926
+ function generateExampleValue(schema) {
1927
+ if (!schema || !schema._def) return "...";
1928
+ const def = schema._def;
1929
+ switch (getZodTypeName(schema)) {
1930
+ case "ZodString":
1931
+ case "string": return "example";
1932
+ case "ZodNumber":
1933
+ case "number": return 0;
1934
+ case "ZodBoolean":
1935
+ case "boolean": return true;
1936
+ case "ZodLiteral":
1937
+ case "literal": return def.value;
1938
+ case "ZodEnum":
1939
+ case "enum":
1940
+ if (Array.isArray(def.values) && def.values.length > 0) return def.values[0];
1941
+ if (def.entries && typeof def.entries === "object") {
1942
+ const values = Object.values(def.entries);
1943
+ return values.length > 0 ? values[0] : "example";
1944
+ }
1945
+ return "example";
1946
+ case "ZodOptional":
1947
+ case "optional":
1948
+ case "ZodNullable":
1949
+ case "nullable":
1950
+ case "ZodDefault":
1951
+ case "default": {
1952
+ const inner = def.innerType ?? def.wrapped;
1953
+ return inner ? generateExampleValue(inner) : null;
1954
+ }
1955
+ case "ZodArray":
1956
+ case "array": return [];
1957
+ case "ZodObject":
1958
+ case "object": return generateExamplePropsFromZod(schema);
1959
+ case "ZodUnion":
1960
+ case "union": {
1961
+ const options = def.options;
1962
+ return options && options.length > 0 ? generateExampleValue(options[0]) : "...";
1963
+ }
1964
+ default: return "...";
1965
+ }
1966
+ }
1967
+ function findFirstStringProp(schema) {
1968
+ if (!schema || !schema._def) return null;
1969
+ const def = schema._def;
1970
+ const typeName = getZodTypeName(schema);
1971
+ if (typeName !== "ZodObject" && typeName !== "object") return null;
1972
+ const shape = typeof def.shape === "function" ? def.shape() : def.shape;
1973
+ if (!shape) return null;
1974
+ for (const [key, value] of Object.entries(shape)) {
1975
+ const innerTypeName = getZodTypeName(value);
1976
+ if (innerTypeName === "ZodOptional" || innerTypeName === "optional" || innerTypeName === "ZodNullable" || innerTypeName === "nullable") continue;
1977
+ if (innerTypeName === "ZodString" || innerTypeName === "string") return key;
1978
+ }
1979
+ return null;
1980
+ }
1981
+ function getZodTypeName(schema) {
1982
+ if (!schema || !schema._def) return "";
1983
+ const def = schema._def;
1984
+ return def.typeName ?? def.type ?? "";
1985
+ }
1986
+ function formatZodType(schema) {
1987
+ if (!schema || !schema._def) return "unknown";
1988
+ const def = schema._def;
1989
+ switch (getZodTypeName(schema)) {
1990
+ case "ZodString":
1991
+ case "string": return "string";
1992
+ case "ZodNumber":
1993
+ case "number": return "number";
1994
+ case "ZodBoolean":
1995
+ case "boolean": return "boolean";
1996
+ case "ZodLiteral":
1997
+ case "literal": return JSON.stringify(def.value);
1998
+ case "ZodEnum":
1999
+ case "enum": {
2000
+ let values;
2001
+ if (Array.isArray(def.values)) values = def.values;
2002
+ else if (def.entries && typeof def.entries === "object") values = Object.values(def.entries);
2003
+ else return "enum";
2004
+ return values.map((v) => `"${v}"`).join(" | ");
2005
+ }
2006
+ case "ZodArray":
2007
+ case "array": {
2008
+ const inner = typeof def.element === "object" ? def.element : typeof def.type === "object" ? def.type : void 0;
2009
+ return inner ? `Array<${formatZodType(inner)}>` : "Array<unknown>";
2010
+ }
2011
+ case "ZodObject":
2012
+ case "object": {
2013
+ const shape = typeof def.shape === "function" ? def.shape() : def.shape;
2014
+ if (!shape) return "object";
2015
+ return `{ ${Object.entries(shape).map(([key, value]) => {
2016
+ const innerTypeName = getZodTypeName(value);
2017
+ return `${key}${innerTypeName === "ZodOptional" || innerTypeName === "ZodNullable" || innerTypeName === "optional" || innerTypeName === "nullable" ? "?" : ""}: ${formatZodType(value)}`;
2018
+ }).join(", ")} }`;
2019
+ }
2020
+ case "ZodOptional":
2021
+ case "optional":
2022
+ case "ZodNullable":
2023
+ case "nullable": {
2024
+ const inner = def.innerType ?? def.wrapped;
2025
+ return inner ? formatZodType(inner) : "unknown";
2026
+ }
2027
+ case "ZodUnion":
2028
+ case "union": {
2029
+ const options = def.options;
2030
+ return options ? options.map((opt) => formatZodType(opt)).join(" | ") : "unknown";
2031
+ }
2032
+ default: return "unknown";
2033
+ }
2034
+ }
2035
+ function zodTypeName(def) {
2036
+ if (typeof def.type === "string") return def.type;
2037
+ if (typeof def.typeName === "string") return def.typeName;
2038
+ return "";
2039
+ }
2040
+ function normalizeTypeName(raw) {
2041
+ if (raw.startsWith("Zod")) return raw.slice(3).toLowerCase();
2042
+ return raw.toLowerCase();
2043
+ }
2044
+ function zodToJsonSchema(schema, strict = false) {
2045
+ const def = schema._def;
2046
+ switch (normalizeTypeName(zodTypeName(def))) {
2047
+ case "string": return { type: "string" };
2048
+ case "number": return { type: "number" };
2049
+ case "boolean": return { type: "boolean" };
2050
+ case "literal": {
2051
+ const values = def.values;
2052
+ return { const: values ? values[0] : def.value };
2053
+ }
2054
+ case "enum": {
2055
+ const entries = def.entries;
2056
+ return { enum: (entries ? Object.values(entries) : def.values) ?? [] };
2057
+ }
2058
+ case "array": {
2059
+ const inner = def.element ?? def.type;
2060
+ return {
2061
+ type: "array",
2062
+ items: inner ? zodToJsonSchema(inner, strict) : {}
2063
+ };
2064
+ }
2065
+ case "object": {
2066
+ const rawShape = def.shape;
2067
+ const shape = typeof rawShape === "function" ? rawShape() : rawShape;
2068
+ if (!shape) {
2069
+ if (strict) return {
2070
+ type: "object",
2071
+ properties: {},
2072
+ required: [],
2073
+ additionalProperties: false
2074
+ };
2075
+ return { type: "object" };
2076
+ }
2077
+ const properties = {};
2078
+ const required = [];
2079
+ for (const [key, value] of Object.entries(shape)) {
2080
+ const innerDef = value._def;
2081
+ const innerKind = normalizeTypeName(zodTypeName(innerDef));
2082
+ const isOptional = innerKind === "optional" || innerKind === "nullable";
2083
+ if (strict) {
2084
+ required.push(key);
2085
+ if (isOptional) properties[key] = { anyOf: [zodToJsonSchema(value, strict), { type: "null" }] };
2086
+ else properties[key] = zodToJsonSchema(value, strict);
2087
+ } else {
2088
+ properties[key] = zodToJsonSchema(value);
2089
+ if (!isOptional) required.push(key);
2090
+ }
2091
+ }
2092
+ return {
2093
+ type: "object",
2094
+ properties,
2095
+ required: required.length > 0 ? required : void 0,
2096
+ additionalProperties: false
2097
+ };
2098
+ }
2099
+ case "record": {
2100
+ const valueType = def.valueType;
2101
+ if (strict) return {
2102
+ type: "object",
2103
+ properties: {},
2104
+ required: [],
2105
+ additionalProperties: false
2106
+ };
2107
+ return {
2108
+ type: "object",
2109
+ additionalProperties: valueType ? zodToJsonSchema(valueType) : true
2110
+ };
2111
+ }
2112
+ case "optional":
2113
+ case "nullable": {
2114
+ const inner = def.innerType;
2115
+ return inner ? zodToJsonSchema(inner, strict) : {};
2116
+ }
2117
+ case "union": {
2118
+ const options = def.options;
2119
+ return options ? { anyOf: options.map((o) => zodToJsonSchema(o, strict)) } : {};
2120
+ }
2121
+ case "any":
2122
+ case "unknown":
2123
+ if (strict) return {
2124
+ type: "object",
2125
+ properties: {},
2126
+ required: [],
2127
+ additionalProperties: false
2128
+ };
2129
+ return {};
2130
+ default: return {};
2131
+ }
2132
+ }
2133
+ function defineCatalog(schema, catalog) {
2134
+ return schema.createCatalog(catalog);
2135
+ }
2136
+ function buildUserPrompt(options) {
2137
+ const { prompt, currentSpec, state, maxPromptLength, editModes, format, serializer } = options;
2138
+ let userText = String(prompt || "");
2139
+ if (maxPromptLength !== void 0 && maxPromptLength > 0) userText = userText.slice(0, maxPromptLength);
2140
+ if (isNonEmptySpec(currentSpec)) {
2141
+ const editPrompt = buildEditUserPrompt({
2142
+ prompt: userText,
2143
+ currentSpec,
2144
+ config: { modes: editModes ?? ["patch"] },
2145
+ format: format ?? "json",
2146
+ serializer
2147
+ });
2148
+ if (state && Object.keys(state).length > 0) return `${editPrompt}
2149
+
2150
+ AVAILABLE STATE:
2151
+ ${JSON.stringify(state, null, 2)}`;
2152
+ return editPrompt;
2153
+ }
2154
+ const parts = [userText];
2155
+ if (state && Object.keys(state).length > 0) parts.push(`
2156
+ AVAILABLE STATE:
2157
+ ${JSON.stringify(state, null, 2)}`);
2158
+ if (format === "yaml") parts.push(`
2159
+ Output the full spec in a \`\`\`yaml-spec fence. Stream progressively \u2014 output elements one at a time.`);
2160
+ else parts.push(`
2161
+ Remember: Output /root first, then interleave /elements and /state patches so the UI fills in progressively as it streams. Output each state patch right after the elements that use it, one per array item.`);
2162
+ return parts.join("\n");
2163
+ }
2164
+ function isPlainObject(value) {
2165
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2166
+ }
2167
+ function deepMergeSpec(base, patch) {
2168
+ const result = { ...base };
2169
+ for (const key of Object.keys(patch)) {
2170
+ const patchVal = patch[key];
2171
+ if (patchVal === null) {
2172
+ delete result[key];
2173
+ continue;
2174
+ }
2175
+ const baseVal = result[key];
2176
+ if (isPlainObject(patchVal) && isPlainObject(baseVal)) result[key] = deepMergeSpec(baseVal, patchVal);
2177
+ else result[key] = patchVal;
2178
+ }
2179
+ return result;
2180
+ }
2181
+ function escapeToken(token) {
2182
+ return token.replace(/~/g, "~0").replace(/\//g, "~1");
2183
+ }
2184
+ function buildPath(basePath, key) {
2185
+ return `${basePath}/${escapeToken(key)}`;
2186
+ }
2187
+ function isPlainObject2(value) {
2188
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2189
+ }
2190
+ function arraysEqual(a, b) {
2191
+ if (a.length !== b.length) return false;
2192
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
2193
+ return true;
2194
+ }
2195
+ function diffToPatches(oldObj, newObj, basePath = "") {
2196
+ const patches = [];
2197
+ for (const key of Object.keys(newObj)) {
2198
+ const path = buildPath(basePath, key);
2199
+ const oldVal = oldObj[key];
2200
+ const newVal = newObj[key];
2201
+ if (!(key in oldObj)) {
2202
+ patches.push({
2203
+ op: "add",
2204
+ path,
2205
+ value: newVal
2206
+ });
2207
+ continue;
2208
+ }
2209
+ if (isPlainObject2(oldVal) && isPlainObject2(newVal)) patches.push(...diffToPatches(oldVal, newVal, path));
2210
+ else if (Array.isArray(oldVal) && Array.isArray(newVal)) {
2211
+ if (!arraysEqual(oldVal, newVal)) patches.push({
2212
+ op: "replace",
2213
+ path,
2214
+ value: newVal
2215
+ });
2216
+ } else if (oldVal !== newVal) patches.push({
2217
+ op: "replace",
2218
+ path,
2219
+ value: newVal
2220
+ });
2221
+ }
2222
+ for (const key of Object.keys(oldObj)) if (!(key in newObj)) patches.push({
2223
+ op: "remove",
2224
+ path: buildPath(basePath, key)
2225
+ });
2226
+ return patches;
2227
+ }
2228
+ //#endregion
2229
+ //#region ../../node_modules/.bun/@json-render+react@0.15.0+b1ab299f0a400331/node_modules/@json-render/react/dist/chunk-WYDS23XB.mjs
2230
+ var schema = defineSchema((s) => ({
2231
+ spec: s.object({
2232
+ root: s.string(),
2233
+ elements: s.record(s.object({
2234
+ type: s.ref("catalog.components"),
2235
+ props: s.propsOf("catalog.components"),
2236
+ children: s.array(s.string()),
2237
+ visible: s.any()
2238
+ }))
2239
+ }),
2240
+ catalog: s.object({
2241
+ components: s.map({
2242
+ props: s.zod(),
2243
+ slots: s.array(s.string()),
2244
+ description: s.string(),
2245
+ example: s.any()
2246
+ }),
2247
+ actions: s.map({
2248
+ params: s.zod(),
2249
+ description: s.string()
2250
+ })
2251
+ })
2252
+ }), {
2253
+ builtInActions: [
2254
+ {
2255
+ name: "setState",
2256
+ description: "Update a value in the state model at the given statePath. Params: { statePath: string, value: any }"
2257
+ },
2258
+ {
2259
+ name: "pushState",
2260
+ description: "Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }. Value can contain {\"$state\":\"/path\"} refs and \"$id\" for auto IDs."
2261
+ },
2262
+ {
2263
+ name: "removeState",
2264
+ description: "Remove an item from an array in state by index. Params: { statePath: string, index: number }"
2265
+ },
2266
+ {
2267
+ name: "validateForm",
2268
+ description: "Validate all registered form fields and write the result to state. Params: { statePath?: string }. Defaults to /formValidation. Result: { valid: boolean, errors: Record<string, string[]> }."
2269
+ }
2270
+ ],
2271
+ defaultRules: [
2272
+ "CRITICAL INTEGRITY CHECK: Before outputting ANY element that references children, you MUST have already output (or will output) each child as its own element. If an element has children: ['a', 'b'], then elements 'a' and 'b' MUST exist. A missing child element causes that entire branch of the UI to be invisible.",
2273
+ "SELF-CHECK: After generating all elements, mentally walk the tree from root. Every key in every children array must resolve to a defined element. If you find a gap, output the missing element immediately.",
2274
+ "CRITICAL: The \"visible\" field goes on the ELEMENT object, NOT inside \"props\". Correct: {\"type\":\"<ComponentName>\",\"props\":{},\"visible\":{\"$state\":\"/tab\",\"eq\":\"home\"},\"children\":[...]}.",
2275
+ "CRITICAL: The \"on\" field goes on the ELEMENT object, NOT inside \"props\". Use on.press, on.change, on.submit etc. NEVER put action/actionParams inside props.",
2276
+ "When the user asks for a UI that displays data (e.g. blog posts, products, users), ALWAYS include a state field with realistic sample data. The state field is a top-level field on the spec (sibling of root/elements).",
2277
+ "When building repeating content backed by a state array (e.g. posts, products, items), use the \"repeat\" field on a container element. Example: { \"type\": \"<ContainerComponent>\", \"props\": {}, \"repeat\": { \"statePath\": \"/posts\", \"key\": \"id\" }, \"children\": [\"post-card\"] }. Replace <ContainerComponent> with an appropriate component from the AVAILABLE COMPONENTS list. Inside repeated children, use { \"$item\": \"field\" } to read a field from the current item, and { \"$index\": true } for the current array index. For two-way binding to an item field use { \"$bindItem\": \"completed\" }. Do NOT hardcode individual elements for each array item.",
2278
+ "Design with visual hierarchy: use container components to group content, heading components for section titles, proper spacing, and status indicators. ONLY use components from the AVAILABLE COMPONENTS list.",
2279
+ "For data-rich UIs, use multi-column layout components if available. For forms and single-column content, use vertical layout components. ONLY use components from the AVAILABLE COMPONENTS list.",
2280
+ "Always include realistic, professional-looking sample data. For blogs include 3-4 posts with varied titles, authors, dates, categories. For products include names, prices, images. Never leave data empty."
2281
+ ]
2282
+ });
2283
+ //#endregion
2284
+ //#region ../../node_modules/.bun/@json-render+react@0.15.0+b1ab299f0a400331/node_modules/@json-render/react/dist/index.mjs
2285
+ var StateContext = createContext(null);
2286
+ function computeInitialFlat(isControlled, initialState) {
2287
+ if (isControlled) return null;
2288
+ if (Object.keys(initialState).length === 0) return {};
2289
+ return flattenToPointers(initialState);
2290
+ }
2291
+ function StateProvider({ store: externalStore, initialState = {}, onStateChange, children }) {
2292
+ const internalStoreRef = useRef(void 0);
2293
+ if (!externalStore && !internalStoreRef.current) internalStoreRef.current = createStateStore(initialState);
2294
+ const store = externalStore ?? internalStoreRef.current;
2295
+ const storeRef = useRef(store);
2296
+ storeRef.current = store;
2297
+ const isControlledRef = useRef(!!externalStore);
2298
+ isControlledRef.current = !!externalStore;
2299
+ const initialModeRef = useRef(externalStore ? "controlled" : "uncontrolled");
2300
+ const modeWarnedRef = useRef(false);
2301
+ if (process.env.NODE_ENV !== "production") {
2302
+ const currentMode = externalStore ? "controlled" : "uncontrolled";
2303
+ if (currentMode !== initialModeRef.current && !modeWarnedRef.current) {
2304
+ modeWarnedRef.current = true;
2305
+ console.warn(`StateProvider: switching from ${initialModeRef.current} to ${currentMode} mode is not supported.`);
2306
+ }
2307
+ }
2308
+ const prevInitialStateRef = useRef(initialState);
2309
+ const prevFlatRef = useRef(computeInitialFlat(!!externalStore, initialState));
2310
+ useEffect(() => {
2311
+ if (externalStore) return;
2312
+ if (initialState === prevInitialStateRef.current) return;
2313
+ prevInitialStateRef.current = initialState;
2314
+ const nextFlat = initialState && Object.keys(initialState).length > 0 ? flattenToPointers(initialState) : {};
2315
+ const prevFlat = prevFlatRef.current ?? {};
2316
+ const allKeys = /* @__PURE__ */ new Set([...Object.keys(prevFlat), ...Object.keys(nextFlat)]);
2317
+ const updates = {};
2318
+ for (const key of allKeys) if (prevFlat[key] !== nextFlat[key]) updates[key] = key in nextFlat ? nextFlat[key] : void 0;
2319
+ prevFlatRef.current = nextFlat;
2320
+ if (Object.keys(updates).length > 0) store.update(updates);
2321
+ }, [
2322
+ externalStore,
2323
+ initialState,
2324
+ store
2325
+ ]);
2326
+ const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot ?? store.getSnapshot);
2327
+ const onStateChangeRef = useRef(onStateChange);
2328
+ onStateChangeRef.current = onStateChange;
2329
+ const set = useCallback((path, value2) => {
2330
+ const s = storeRef.current;
2331
+ const prev = s.getSnapshot();
2332
+ s.set(path, value2);
2333
+ if (!isControlledRef.current && s.getSnapshot() !== prev) onStateChangeRef.current?.([{
2334
+ path,
2335
+ value: value2
2336
+ }]);
2337
+ }, []);
2338
+ const update = useCallback((updates) => {
2339
+ const s = storeRef.current;
2340
+ const prev = s.getSnapshot();
2341
+ s.update(updates);
2342
+ if (!isControlledRef.current && s.getSnapshot() !== prev) {
2343
+ const changes = [];
2344
+ for (const [path, value2] of Object.entries(updates)) if (getByPath(prev, path) !== value2) changes.push({
2345
+ path,
2346
+ value: value2
2347
+ });
2348
+ if (changes.length > 0) onStateChangeRef.current?.(changes);
2349
+ }
2350
+ }, []);
2351
+ const get = useCallback((path) => storeRef.current.get(path), []);
2352
+ const getSnapshot = useCallback(() => storeRef.current.getSnapshot(), []);
2353
+ const value = useMemo(() => ({
2354
+ state,
2355
+ get,
2356
+ set,
2357
+ update,
2358
+ getSnapshot
2359
+ }), [
2360
+ state,
2361
+ get,
2362
+ set,
2363
+ update,
2364
+ getSnapshot
2365
+ ]);
2366
+ return /* @__PURE__ */ jsx(StateContext.Provider, {
2367
+ value,
2368
+ children
2369
+ });
2370
+ }
2371
+ function useStateStore() {
2372
+ const ctx = useContext(StateContext);
2373
+ if (!ctx) throw new Error("useStateStore must be used within a StateProvider");
2374
+ return ctx;
2375
+ }
2376
+ var VisibilityContext = createContext(null);
2377
+ function VisibilityProvider({ children }) {
2378
+ const { state } = useStateStore();
2379
+ const ctx = useMemo(() => ({ stateModel: state }), [state]);
2380
+ const isVisible = useMemo(() => (condition) => evaluateVisibility(condition, ctx), [ctx]);
2381
+ const value = useMemo(() => ({
2382
+ isVisible,
2383
+ ctx
2384
+ }), [isVisible, ctx]);
2385
+ return /* @__PURE__ */ jsx(VisibilityContext.Provider, {
2386
+ value,
2387
+ children
2388
+ });
2389
+ }
2390
+ function useVisibility() {
2391
+ const ctx = useContext(VisibilityContext);
2392
+ if (!ctx) throw new Error("useVisibility must be used within a VisibilityProvider");
2393
+ return ctx;
2394
+ }
2395
+ var ValidationContext = createContext(null);
2396
+ function dynamicArgsEqual(a, b) {
2397
+ if (a === b) return true;
2398
+ if (!a || !b) return false;
2399
+ const keysA = Object.keys(a);
2400
+ const keysB = Object.keys(b);
2401
+ if (keysA.length !== keysB.length) return false;
2402
+ for (const key of keysA) {
2403
+ const va = a[key];
2404
+ const vb = b[key];
2405
+ if (va === vb) continue;
2406
+ if (typeof va === "object" && va !== null && typeof vb === "object" && vb !== null) {
2407
+ const sa = va.$state;
2408
+ const sb = vb.$state;
2409
+ if (typeof sa === "string" && sa === sb) continue;
2410
+ }
2411
+ return false;
2412
+ }
2413
+ return true;
2414
+ }
2415
+ function validationConfigEqual(a, b) {
2416
+ if (a === b) return true;
2417
+ if (a.validateOn !== b.validateOn) return false;
2418
+ const ac = a.checks ?? [];
2419
+ const bc = b.checks ?? [];
2420
+ if (ac.length !== bc.length) return false;
2421
+ for (let i = 0; i < ac.length; i++) {
2422
+ const ca = ac[i];
2423
+ const cb = bc[i];
2424
+ if (ca.type !== cb.type) return false;
2425
+ if (ca.message !== cb.message) return false;
2426
+ if (!dynamicArgsEqual(ca.args, cb.args)) return false;
2427
+ }
2428
+ return true;
2429
+ }
2430
+ function ValidationProvider({ customFunctions = {}, children }) {
2431
+ const { state, getSnapshot } = useStateStore();
2432
+ const [fieldStates, setFieldStates] = useState({});
2433
+ const fieldStatesRef = useRef({});
2434
+ const [fieldConfigs, setFieldConfigs] = useState({});
2435
+ const registerField = useCallback((path, config) => {
2436
+ setFieldConfigs((prev) => {
2437
+ const existing = prev[path];
2438
+ if (existing && validationConfigEqual(existing, config)) return prev;
2439
+ return {
2440
+ ...prev,
2441
+ [path]: config
2442
+ };
2443
+ });
2444
+ }, []);
2445
+ const validate = useCallback((path, config) => {
2446
+ const currentState = getSnapshot();
2447
+ const segments = path.split("/").filter(Boolean);
2448
+ let value2 = currentState;
2449
+ for (const seg of segments) if (value2 != null && typeof value2 === "object") value2 = value2[seg];
2450
+ else {
2451
+ value2 = void 0;
2452
+ break;
2453
+ }
2454
+ const result = runValidation(config, {
2455
+ value: value2,
2456
+ stateModel: currentState,
2457
+ customFunctions
2458
+ });
2459
+ const newFieldState = {
2460
+ touched: fieldStatesRef.current[path]?.touched ?? true,
2461
+ validated: true,
2462
+ result
2463
+ };
2464
+ fieldStatesRef.current = {
2465
+ ...fieldStatesRef.current,
2466
+ [path]: newFieldState
2467
+ };
2468
+ setFieldStates(fieldStatesRef.current);
2469
+ return result;
2470
+ }, [customFunctions, getSnapshot]);
2471
+ const touch = useCallback((path) => {
2472
+ fieldStatesRef.current = {
2473
+ ...fieldStatesRef.current,
2474
+ [path]: {
2475
+ ...fieldStatesRef.current[path],
2476
+ touched: true,
2477
+ validated: fieldStatesRef.current[path]?.validated ?? false,
2478
+ result: fieldStatesRef.current[path]?.result ?? null
2479
+ }
2480
+ };
2481
+ setFieldStates(fieldStatesRef.current);
2482
+ }, []);
2483
+ const clear = useCallback((path) => {
2484
+ const { [path]: _, ...rest } = fieldStatesRef.current;
2485
+ fieldStatesRef.current = rest;
2486
+ setFieldStates(rest);
2487
+ }, []);
2488
+ const validateAll = useCallback(() => {
2489
+ let allValid = true;
2490
+ for (const [path, config] of Object.entries(fieldConfigs)) if (!validate(path, config).valid) allValid = false;
2491
+ return allValid;
2492
+ }, [fieldConfigs, validate]);
2493
+ const value = useMemo(() => ({
2494
+ customFunctions,
2495
+ get fieldStates() {
2496
+ return fieldStatesRef.current;
2497
+ },
2498
+ validate,
2499
+ touch,
2500
+ clear,
2501
+ validateAll,
2502
+ registerField
2503
+ }), [
2504
+ customFunctions,
2505
+ fieldStates,
2506
+ validate,
2507
+ touch,
2508
+ clear,
2509
+ validateAll,
2510
+ registerField
2511
+ ]);
2512
+ return /* @__PURE__ */ jsx(ValidationContext.Provider, {
2513
+ value,
2514
+ children
2515
+ });
2516
+ }
2517
+ function useOptionalValidation() {
2518
+ return useContext(ValidationContext);
2519
+ }
2520
+ var idCounter = 0;
2521
+ function generateUniqueId() {
2522
+ idCounter += 1;
2523
+ return `${Date.now()}-${idCounter}`;
2524
+ }
2525
+ function deepResolveValue(value, get) {
2526
+ if (value === null || value === void 0) return value;
2527
+ if (value === "$id") return generateUniqueId();
2528
+ if (typeof value === "object" && !Array.isArray(value)) {
2529
+ const obj = value;
2530
+ const keys = Object.keys(obj);
2531
+ if (keys.length === 1 && typeof obj.$state === "string") return get(obj.$state);
2532
+ if (keys.length === 1 && "$id" in obj) return generateUniqueId();
2533
+ }
2534
+ if (Array.isArray(value)) return value.map((item) => deepResolveValue(item, get));
2535
+ if (typeof value === "object") {
2536
+ const resolved = {};
2537
+ for (const [key, val] of Object.entries(value)) resolved[key] = deepResolveValue(val, get);
2538
+ return resolved;
2539
+ }
2540
+ return value;
2541
+ }
2542
+ var ActionContext = createContext(null);
2543
+ function ActionProvider({ handlers: initialHandlers = {}, navigate, children }) {
2544
+ const { get, set, getSnapshot } = useStateStore();
2545
+ const validation = useOptionalValidation();
2546
+ const [handlers, setHandlers] = useState(initialHandlers);
2547
+ const [loadingActions, setLoadingActions] = useState(/* @__PURE__ */ new Set());
2548
+ const [pendingConfirmation, setPendingConfirmation] = useState(null);
2549
+ const registerHandler = useCallback((name, handler) => {
2550
+ setHandlers((prev) => ({
2551
+ ...prev,
2552
+ [name]: handler
2553
+ }));
2554
+ }, []);
2555
+ const execute = useCallback(async (binding) => {
2556
+ const resolved = resolveAction(binding, getSnapshot());
2557
+ if (resolved.action === "setState" && resolved.params) {
2558
+ const statePath = resolved.params.statePath;
2559
+ const value2 = resolved.params.value;
2560
+ if (statePath) set(statePath, value2);
2561
+ return;
2562
+ }
2563
+ if (resolved.action === "pushState" && resolved.params) {
2564
+ const statePath = resolved.params.statePath;
2565
+ const rawValue = resolved.params.value;
2566
+ if (statePath) {
2567
+ const resolvedValue = deepResolveValue(rawValue, get);
2568
+ set(statePath, [...get(statePath) ?? [], resolvedValue]);
2569
+ const clearStatePath = resolved.params.clearStatePath;
2570
+ if (clearStatePath) set(clearStatePath, "");
2571
+ }
2572
+ return;
2573
+ }
2574
+ if (resolved.action === "removeState" && resolved.params) {
2575
+ const statePath = resolved.params.statePath;
2576
+ const index = resolved.params.index;
2577
+ if (statePath !== void 0 && index !== void 0) set(statePath, (get(statePath) ?? []).filter((_, i) => i !== index));
2578
+ return;
2579
+ }
2580
+ if (resolved.action === "push" && resolved.params) {
2581
+ const screen = resolved.params.screen;
2582
+ if (screen) {
2583
+ const currentScreen = get("/currentScreen");
2584
+ const navStack = get("/navStack") ?? [];
2585
+ if (currentScreen) set("/navStack", [...navStack, currentScreen]);
2586
+ else set("/navStack", [...navStack, ""]);
2587
+ set("/currentScreen", screen);
2588
+ }
2589
+ return;
2590
+ }
2591
+ if (resolved.action === "pop") {
2592
+ const navStack = get("/navStack") ?? [];
2593
+ if (navStack.length > 0) {
2594
+ const previousScreen = navStack[navStack.length - 1];
2595
+ set("/navStack", navStack.slice(0, -1));
2596
+ if (previousScreen) set("/currentScreen", previousScreen);
2597
+ else set("/currentScreen", void 0);
2598
+ }
2599
+ return;
2600
+ }
2601
+ if (resolved.action === "validateForm") {
2602
+ const validateAll = validation?.validateAll;
2603
+ if (!validateAll) {
2604
+ console.warn("validateForm action was dispatched but no ValidationProvider is connected. Ensure ValidationProvider is rendered inside the provider tree.");
2605
+ return;
2606
+ }
2607
+ const valid = validateAll();
2608
+ const errors = {};
2609
+ for (const [path, fs] of Object.entries(validation.fieldStates)) if (fs.result && !fs.result.valid) errors[path] = fs.result.errors;
2610
+ set(resolved.params?.statePath || "/formValidation", {
2611
+ valid,
2612
+ errors
2613
+ });
2614
+ return;
2615
+ }
2616
+ const handler = handlers[resolved.action];
2617
+ if (!handler) {
2618
+ console.warn(`No handler registered for action: ${resolved.action}`);
2619
+ return;
2620
+ }
2621
+ if (resolved.confirm) return new Promise((resolve, reject) => {
2622
+ setPendingConfirmation({
2623
+ action: resolved,
2624
+ handler,
2625
+ resolve: () => {
2626
+ setPendingConfirmation(null);
2627
+ resolve();
2628
+ },
2629
+ reject: () => {
2630
+ setPendingConfirmation(null);
2631
+ reject(/* @__PURE__ */ new Error("Action cancelled"));
2632
+ }
2633
+ });
2634
+ }).then(async () => {
2635
+ setLoadingActions((prev) => new Set(prev).add(resolved.action));
2636
+ try {
2637
+ await executeAction({
2638
+ action: resolved,
2639
+ handler,
2640
+ setState: set,
2641
+ navigate,
2642
+ executeAction: async (name) => {
2643
+ await execute({ action: name });
2644
+ }
2645
+ });
2646
+ } finally {
2647
+ setLoadingActions((prev) => {
2648
+ const next = new Set(prev);
2649
+ next.delete(resolved.action);
2650
+ return next;
2651
+ });
2652
+ }
2653
+ });
2654
+ setLoadingActions((prev) => new Set(prev).add(resolved.action));
2655
+ try {
2656
+ await executeAction({
2657
+ action: resolved,
2658
+ handler,
2659
+ setState: set,
2660
+ navigate,
2661
+ executeAction: async (name) => {
2662
+ await execute({ action: name });
2663
+ }
2664
+ });
2665
+ } finally {
2666
+ setLoadingActions((prev) => {
2667
+ const next = new Set(prev);
2668
+ next.delete(resolved.action);
2669
+ return next;
2670
+ });
2671
+ }
2672
+ }, [
2673
+ handlers,
2674
+ get,
2675
+ set,
2676
+ getSnapshot,
2677
+ navigate,
2678
+ validation
2679
+ ]);
2680
+ const confirm = useCallback(() => {
2681
+ pendingConfirmation?.resolve();
2682
+ }, [pendingConfirmation]);
2683
+ const cancel = useCallback(() => {
2684
+ pendingConfirmation?.reject();
2685
+ }, [pendingConfirmation]);
2686
+ const value = useMemo(() => ({
2687
+ handlers,
2688
+ loadingActions,
2689
+ pendingConfirmation,
2690
+ execute,
2691
+ confirm,
2692
+ cancel,
2693
+ registerHandler
2694
+ }), [
2695
+ handlers,
2696
+ loadingActions,
2697
+ pendingConfirmation,
2698
+ execute,
2699
+ confirm,
2700
+ cancel,
2701
+ registerHandler
2702
+ ]);
2703
+ return /* @__PURE__ */ jsx(ActionContext.Provider, {
2704
+ value,
2705
+ children
2706
+ });
2707
+ }
2708
+ function useActions() {
2709
+ const ctx = useContext(ActionContext);
2710
+ if (!ctx) throw new Error("useActions must be used within an ActionProvider");
2711
+ return ctx;
2712
+ }
2713
+ function ConfirmDialog({ confirm, onConfirm, onCancel }) {
2714
+ const isDanger = confirm.variant === "danger";
2715
+ return /* @__PURE__ */ jsx("div", {
2716
+ style: {
2717
+ position: "fixed",
2718
+ inset: 0,
2719
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
2720
+ display: "flex",
2721
+ alignItems: "center",
2722
+ justifyContent: "center",
2723
+ zIndex: 50
2724
+ },
2725
+ onClick: onCancel,
2726
+ children: /* @__PURE__ */ jsxs("div", {
2727
+ style: {
2728
+ backgroundColor: "white",
2729
+ borderRadius: "8px",
2730
+ padding: "24px",
2731
+ maxWidth: "400px",
2732
+ width: "100%",
2733
+ boxShadow: "0 20px 25px -5px rgba(0, 0, 0, 0.1)"
2734
+ },
2735
+ onClick: (e) => e.stopPropagation(),
2736
+ children: [
2737
+ /* @__PURE__ */ jsx("h3", {
2738
+ style: {
2739
+ margin: "0 0 8px 0",
2740
+ fontSize: "18px",
2741
+ fontWeight: 600
2742
+ },
2743
+ children: confirm.title
2744
+ }),
2745
+ /* @__PURE__ */ jsx("p", {
2746
+ style: {
2747
+ margin: "0 0 24px 0",
2748
+ color: "#6b7280"
2749
+ },
2750
+ children: confirm.message
2751
+ }),
2752
+ /* @__PURE__ */ jsxs("div", {
2753
+ style: {
2754
+ display: "flex",
2755
+ gap: "12px",
2756
+ justifyContent: "flex-end"
2757
+ },
2758
+ children: [/* @__PURE__ */ jsx("button", {
2759
+ onClick: onCancel,
2760
+ style: {
2761
+ padding: "8px 16px",
2762
+ borderRadius: "6px",
2763
+ border: "1px solid #d1d5db",
2764
+ backgroundColor: "white",
2765
+ cursor: "pointer"
2766
+ },
2767
+ children: confirm.cancelLabel ?? "Cancel"
2768
+ }), /* @__PURE__ */ jsx("button", {
2769
+ onClick: onConfirm,
2770
+ style: {
2771
+ padding: "8px 16px",
2772
+ borderRadius: "6px",
2773
+ border: "none",
2774
+ backgroundColor: isDanger ? "#dc2626" : "#3b82f6",
2775
+ color: "white",
2776
+ cursor: "pointer"
2777
+ },
2778
+ children: confirm.confirmLabel ?? "Confirm"
2779
+ })]
2780
+ })
2781
+ ]
2782
+ })
2783
+ });
2784
+ }
2785
+ var RepeatScopeContext = createContext(null);
2786
+ function RepeatScopeProvider({ item, index, basePath, children }) {
2787
+ return /* @__PURE__ */ jsx(RepeatScopeContext.Provider, {
2788
+ value: {
2789
+ item,
2790
+ index,
2791
+ basePath
2792
+ },
2793
+ children
2794
+ });
2795
+ }
2796
+ function useRepeatScope() {
2797
+ return useContext(RepeatScopeContext);
2798
+ }
2799
+ var ElementErrorBoundary = class extends React.Component {
2800
+ constructor(props) {
2801
+ super(props);
2802
+ this.state = { hasError: false };
2803
+ }
2804
+ static getDerivedStateFromError() {
2805
+ return { hasError: true };
2806
+ }
2807
+ componentDidCatch(error, info) {
2808
+ console.error(`[json-render] Rendering error in <${this.props.elementType}>:`, error, info.componentStack);
2809
+ }
2810
+ render() {
2811
+ if (this.state.hasError) return null;
2812
+ return this.props.children;
2813
+ }
2814
+ };
2815
+ var EMPTY_FUNCTIONS = {};
2816
+ var FunctionsContext = React.createContext(EMPTY_FUNCTIONS);
2817
+ function useFunctions() {
2818
+ return React.useContext(FunctionsContext);
2819
+ }
2820
+ var ElementRenderer = React.memo(function ElementRenderer2({ element, spec, registry, loading, fallback }) {
2821
+ const repeatScope = useRepeatScope();
2822
+ const { ctx } = useVisibility();
2823
+ const { execute } = useActions();
2824
+ const { getSnapshot, state: watchState } = useStateStore();
2825
+ const functions = useFunctions();
2826
+ const fullCtx = useMemo(() => {
2827
+ const base = repeatScope ? {
2828
+ ...ctx,
2829
+ repeatItem: repeatScope.item,
2830
+ repeatIndex: repeatScope.index,
2831
+ repeatBasePath: repeatScope.basePath
2832
+ } : { ...ctx };
2833
+ base.functions = functions;
2834
+ return base;
2835
+ }, [
2836
+ ctx,
2837
+ repeatScope,
2838
+ functions
2839
+ ]);
2840
+ const isVisible = element.visible === void 0 ? true : evaluateVisibility(element.visible, fullCtx);
2841
+ const onBindings = element.on;
2842
+ const emit = useCallback(async (eventName) => {
2843
+ const binding = onBindings?.[eventName];
2844
+ if (!binding) return;
2845
+ const actionBindings = Array.isArray(binding) ? binding : [binding];
2846
+ for (const b of actionBindings) {
2847
+ if (!b.params) {
2848
+ await execute(b);
2849
+ continue;
2850
+ }
2851
+ const liveCtx = {
2852
+ ...fullCtx,
2853
+ stateModel: getSnapshot()
2854
+ };
2855
+ const resolved = {};
2856
+ for (const [key, val] of Object.entries(b.params)) resolved[key] = resolveActionParam(val, liveCtx);
2857
+ await execute({
2858
+ ...b,
2859
+ params: resolved
2860
+ });
2861
+ }
2862
+ }, [
2863
+ onBindings,
2864
+ execute,
2865
+ fullCtx,
2866
+ getSnapshot
2867
+ ]);
2868
+ const on = useCallback((eventName) => {
2869
+ const binding = onBindings?.[eventName];
2870
+ if (!binding) return {
2871
+ emit: () => {},
2872
+ shouldPreventDefault: false,
2873
+ bound: false
2874
+ };
2875
+ return {
2876
+ emit: () => emit(eventName),
2877
+ shouldPreventDefault: (Array.isArray(binding) ? binding : [binding]).some((b) => b.preventDefault),
2878
+ bound: true
2879
+ };
2880
+ }, [onBindings, emit]);
2881
+ const watchConfig = element.watch;
2882
+ const prevWatchValues = useRef(null);
2883
+ const stableWatchRef = useRef(void 0);
2884
+ const watchedValues = useMemo(() => {
2885
+ if (!watchConfig) return void 0;
2886
+ const values = {};
2887
+ for (const path of Object.keys(watchConfig)) values[path] = getByPath(watchState, path);
2888
+ const prev = stableWatchRef.current;
2889
+ if (prev) {
2890
+ const keys = Object.keys(values);
2891
+ if (keys.length === Object.keys(prev).length && keys.every((k) => values[k] === prev[k])) return prev;
2892
+ }
2893
+ stableWatchRef.current = values;
2894
+ return values;
2895
+ }, [watchConfig, watchState]);
2896
+ useEffect(() => {
2897
+ if (!watchConfig || !watchedValues) return;
2898
+ const paths = Object.keys(watchConfig);
2899
+ if (paths.length === 0) return;
2900
+ const prev = prevWatchValues.current;
2901
+ prevWatchValues.current = watchedValues;
2902
+ if (prev === null) return;
2903
+ let cancelled = false;
2904
+ (async () => {
2905
+ for (const path of paths) {
2906
+ if (cancelled) break;
2907
+ if (watchedValues[path] !== prev[path]) {
2908
+ const binding = watchConfig[path];
2909
+ if (!binding) continue;
2910
+ const bindings = Array.isArray(binding) ? binding : [binding];
2911
+ for (const b of bindings) {
2912
+ if (cancelled) break;
2913
+ if (!b.params) {
2914
+ await execute(b);
2915
+ if (cancelled) break;
2916
+ continue;
2917
+ }
2918
+ const liveCtx = {
2919
+ ...fullCtx,
2920
+ stateModel: getSnapshot()
2921
+ };
2922
+ const resolved = {};
2923
+ for (const [key, val] of Object.entries(b.params)) resolved[key] = resolveActionParam(val, liveCtx);
2924
+ await execute({
2925
+ ...b,
2926
+ params: resolved
2927
+ });
2928
+ if (cancelled) break;
2929
+ }
2930
+ }
2931
+ }
2932
+ })().catch(console.error);
2933
+ return () => {
2934
+ cancelled = true;
2935
+ };
2936
+ }, [
2937
+ watchConfig,
2938
+ watchedValues,
2939
+ execute,
2940
+ fullCtx,
2941
+ getSnapshot
2942
+ ]);
2943
+ if (!isVisible) return null;
2944
+ const rawProps = element.props;
2945
+ const elementBindings = resolveBindings(rawProps, fullCtx);
2946
+ const resolvedProps = resolveElementProps(rawProps, fullCtx);
2947
+ const resolvedElement = resolvedProps !== element.props ? {
2948
+ ...element,
2949
+ props: resolvedProps
2950
+ } : element;
2951
+ const Component = registry[resolvedElement.type] ?? fallback;
2952
+ if (!Component) {
2953
+ console.warn(`No renderer for component type: ${resolvedElement.type}`);
2954
+ return null;
2955
+ }
2956
+ const children = resolvedElement.repeat ? /* @__PURE__ */ jsx(RepeatChildren, {
2957
+ element: resolvedElement,
2958
+ spec,
2959
+ registry,
2960
+ loading,
2961
+ fallback
2962
+ }) : resolvedElement.children?.map((childKey) => {
2963
+ const childElement = spec.elements[childKey];
2964
+ if (!childElement) {
2965
+ if (!loading) console.warn(`[json-render] Missing element "${childKey}" referenced as child of "${resolvedElement.type}". This element will not render.`);
2966
+ return null;
2967
+ }
2968
+ return /* @__PURE__ */ jsx(ElementRenderer2, {
2969
+ element: childElement,
2970
+ spec,
2971
+ registry,
2972
+ loading,
2973
+ fallback
2974
+ }, childKey);
2975
+ });
2976
+ return /* @__PURE__ */ jsx(ElementErrorBoundary, {
2977
+ elementType: resolvedElement.type,
2978
+ children: /* @__PURE__ */ jsx(Component, {
2979
+ element: resolvedElement,
2980
+ emit,
2981
+ on,
2982
+ bindings: elementBindings,
2983
+ loading,
2984
+ children
2985
+ })
2986
+ });
2987
+ });
2988
+ function RepeatChildren({ element, spec, registry, loading, fallback }) {
2989
+ const { state } = useStateStore();
2990
+ const repeat = element.repeat;
2991
+ const statePath = repeat.statePath;
2992
+ return /* @__PURE__ */ jsx(Fragment$1, { children: (getByPath(state, statePath) ?? []).map((itemValue, index) => {
2993
+ const key = repeat.key && typeof itemValue === "object" && itemValue !== null ? String(itemValue[repeat.key] ?? index) : String(index);
2994
+ return /* @__PURE__ */ jsx(RepeatScopeProvider, {
2995
+ item: itemValue,
2996
+ index,
2997
+ basePath: `${statePath}/${index}`,
2998
+ children: element.children?.map((childKey) => {
2999
+ const childElement = spec.elements[childKey];
3000
+ if (!childElement) {
3001
+ if (!loading) console.warn(`[json-render] Missing element "${childKey}" referenced as child of "${element.type}" (repeat). This element will not render.`);
3002
+ return null;
3003
+ }
3004
+ return /* @__PURE__ */ jsx(ElementRenderer, {
3005
+ element: childElement,
3006
+ spec,
3007
+ registry,
3008
+ loading,
3009
+ fallback
3010
+ }, childKey);
3011
+ })
3012
+ }, key);
3013
+ }) });
3014
+ }
3015
+ function Renderer({ spec, registry, loading, fallback }) {
3016
+ if (!spec || !spec.root) return null;
3017
+ const rootElement = spec.elements[spec.root];
3018
+ if (!rootElement) return null;
3019
+ return /* @__PURE__ */ jsx(ElementRenderer, {
3020
+ element: rootElement,
3021
+ spec,
3022
+ registry,
3023
+ loading,
3024
+ fallback
3025
+ });
3026
+ }
3027
+ function JSONUIProvider({ registry, store, initialState, handlers, navigate, validationFunctions, functions, onStateChange, children }) {
3028
+ return /* @__PURE__ */ jsx(StateProvider, {
3029
+ store,
3030
+ initialState,
3031
+ onStateChange,
3032
+ children: /* @__PURE__ */ jsx(VisibilityProvider, { children: /* @__PURE__ */ jsx(ValidationProvider, {
3033
+ customFunctions: validationFunctions,
3034
+ children: /* @__PURE__ */ jsx(ActionProvider, {
3035
+ handlers,
3036
+ navigate,
3037
+ children: /* @__PURE__ */ jsxs(FunctionsContext.Provider, {
3038
+ value: functions ?? EMPTY_FUNCTIONS,
3039
+ children: [children, /* @__PURE__ */ jsx(ConfirmationDialogManager, {})]
3040
+ })
3041
+ })
3042
+ }) })
3043
+ });
3044
+ }
3045
+ function ConfirmationDialogManager() {
3046
+ const { pendingConfirmation, confirm, cancel } = useActions();
3047
+ if (!pendingConfirmation?.action.confirm) return null;
3048
+ return /* @__PURE__ */ jsx(ConfirmDialog, {
3049
+ confirm: pendingConfirmation.action.confirm,
3050
+ onConfirm: confirm,
3051
+ onCancel: cancel
3052
+ });
3053
+ }
3054
+ function defineRegistry(_catalog, options) {
3055
+ const registry = {};
3056
+ if (options.components) for (const [name, componentFn] of Object.entries(options.components)) registry[name] = ({ element, children, emit, on, bindings, loading }) => {
3057
+ return componentFn({
3058
+ props: element.props,
3059
+ children,
3060
+ emit,
3061
+ on,
3062
+ bindings,
3063
+ loading
3064
+ });
3065
+ };
3066
+ const actionMap = options.actions ? Object.entries(options.actions) : [];
3067
+ const handlers = (getSetState, getState) => {
3068
+ const result = {};
3069
+ for (const [name, actionFn] of actionMap) result[name] = async (params) => {
3070
+ const setState = getSetState();
3071
+ const state = getState();
3072
+ if (setState) await actionFn(params, setState, state);
3073
+ };
3074
+ return result;
3075
+ };
3076
+ const executeAction2 = async (actionName, params, setState, state = {}) => {
3077
+ const entry = actionMap.find(([name]) => name === actionName);
3078
+ if (entry) await entry[1](params, setState, state);
3079
+ else console.warn(`Unknown action: ${actionName}`);
3080
+ };
3081
+ return {
3082
+ registry,
3083
+ handlers,
3084
+ executeAction: executeAction2
3085
+ };
3086
+ }
3087
+ function createRenderer(catalog, components) {
3088
+ const registry = components;
3089
+ return function CatalogRenderer({ spec, store, state, onAction, onStateChange, functions, loading, fallback }) {
3090
+ return /* @__PURE__ */ jsx(StateProvider, {
3091
+ store,
3092
+ initialState: state,
3093
+ onStateChange,
3094
+ children: /* @__PURE__ */ jsx(VisibilityProvider, { children: /* @__PURE__ */ jsx(ValidationProvider, { children: /* @__PURE__ */ jsx(ActionProvider, {
3095
+ handlers: onAction ? new Proxy({}, {
3096
+ get: (_target, prop) => {
3097
+ return (params) => onAction(prop, params);
3098
+ },
3099
+ has: () => true
3100
+ }) : void 0,
3101
+ children: /* @__PURE__ */ jsxs(FunctionsContext.Provider, {
3102
+ value: functions ?? EMPTY_FUNCTIONS,
3103
+ children: [/* @__PURE__ */ jsx(Renderer, {
3104
+ spec,
3105
+ registry,
3106
+ loading,
3107
+ fallback
3108
+ }), /* @__PURE__ */ jsx(ConfirmationDialogManager, {})]
3109
+ })
3110
+ }) }) })
3111
+ });
3112
+ };
3113
+ }
3114
+ function parseLine(line) {
3115
+ try {
3116
+ const trimmed = line.trim();
3117
+ if (!trimmed || trimmed.startsWith("//")) return null;
3118
+ const parsed = JSON.parse(trimmed);
3119
+ if (parsed.__meta === "usage") return {
3120
+ type: "usage",
3121
+ usage: {
3122
+ promptTokens: parsed.promptTokens ?? 0,
3123
+ completionTokens: parsed.completionTokens ?? 0,
3124
+ totalTokens: parsed.totalTokens ?? 0
3125
+ }
3126
+ };
3127
+ return {
3128
+ type: "patch",
3129
+ patch: parsed
3130
+ };
3131
+ } catch {
3132
+ return null;
3133
+ }
3134
+ }
3135
+ function setSpecValue(newSpec, path, value) {
3136
+ if (path === "/root") {
3137
+ newSpec.root = value;
3138
+ return;
3139
+ }
3140
+ if (path === "/state") {
3141
+ newSpec.state = value;
3142
+ return;
3143
+ }
3144
+ if (path.startsWith("/state/")) {
3145
+ if (!newSpec.state) newSpec.state = {};
3146
+ const statePath = path.slice(6);
3147
+ setByPath(newSpec.state, statePath, value);
3148
+ return;
3149
+ }
3150
+ if (path.startsWith("/elements/")) {
3151
+ const pathParts = path.slice(10).split("/");
3152
+ const elementKey = pathParts[0];
3153
+ if (!elementKey) return;
3154
+ if (pathParts.length === 1) newSpec.elements[elementKey] = value;
3155
+ else {
3156
+ const element = newSpec.elements[elementKey];
3157
+ if (element) {
3158
+ const propPath = "/" + pathParts.slice(1).join("/");
3159
+ const newElement = { ...element };
3160
+ setByPath(newElement, propPath, value);
3161
+ newSpec.elements[elementKey] = newElement;
3162
+ }
3163
+ }
3164
+ }
3165
+ }
3166
+ function removeSpecValue(newSpec, path) {
3167
+ if (path === "/state") {
3168
+ delete newSpec.state;
3169
+ return;
3170
+ }
3171
+ if (path.startsWith("/state/") && newSpec.state) {
3172
+ const statePath = path.slice(6);
3173
+ removeByPath(newSpec.state, statePath);
3174
+ return;
3175
+ }
3176
+ if (path.startsWith("/elements/")) {
3177
+ const pathParts = path.slice(10).split("/");
3178
+ const elementKey = pathParts[0];
3179
+ if (!elementKey) return;
3180
+ if (pathParts.length === 1) {
3181
+ const { [elementKey]: _, ...rest } = newSpec.elements;
3182
+ newSpec.elements = rest;
3183
+ } else {
3184
+ const element = newSpec.elements[elementKey];
3185
+ if (element) {
3186
+ const propPath = "/" + pathParts.slice(1).join("/");
3187
+ const newElement = { ...element };
3188
+ removeByPath(newElement, propPath);
3189
+ newSpec.elements[elementKey] = newElement;
3190
+ }
3191
+ }
3192
+ }
3193
+ }
3194
+ function getSpecValue(spec, path) {
3195
+ if (path === "/root") return spec.root;
3196
+ if (path === "/state") return spec.state;
3197
+ if (path.startsWith("/state/") && spec.state) {
3198
+ const statePath = path.slice(6);
3199
+ return getByPath(spec.state, statePath);
3200
+ }
3201
+ return getByPath(spec, path);
3202
+ }
3203
+ function applyPatch(spec, patch) {
3204
+ const newSpec = {
3205
+ ...spec,
3206
+ elements: { ...spec.elements },
3207
+ ...spec.state ? { state: { ...spec.state } } : {}
3208
+ };
3209
+ switch (patch.op) {
3210
+ case "add":
3211
+ case "replace":
3212
+ setSpecValue(newSpec, patch.path, patch.value);
3213
+ break;
3214
+ case "remove":
3215
+ removeSpecValue(newSpec, patch.path);
3216
+ break;
3217
+ case "move": {
3218
+ if (!patch.from) break;
3219
+ const moveValue = getSpecValue(newSpec, patch.from);
3220
+ removeSpecValue(newSpec, patch.from);
3221
+ setSpecValue(newSpec, patch.path, moveValue);
3222
+ break;
3223
+ }
3224
+ case "copy": {
3225
+ if (!patch.from) break;
3226
+ const copyValue = getSpecValue(newSpec, patch.from);
3227
+ setSpecValue(newSpec, patch.path, copyValue);
3228
+ break;
3229
+ }
3230
+ case "test": break;
3231
+ }
3232
+ return newSpec;
3233
+ }
3234
+ function useUIStream({ api, onComplete, onError }) {
3235
+ const [spec, setSpec] = useState(null);
3236
+ const [isStreaming, setIsStreaming] = useState(false);
3237
+ const [error, setError] = useState(null);
3238
+ const [usage, setUsage] = useState(null);
3239
+ const [rawLines, setRawLines] = useState([]);
3240
+ const abortControllerRef = useRef(null);
3241
+ const onCompleteRef = useRef(onComplete);
3242
+ onCompleteRef.current = onComplete;
3243
+ const onErrorRef = useRef(onError);
3244
+ onErrorRef.current = onError;
3245
+ const clear = useCallback(() => {
3246
+ setSpec(null);
3247
+ setError(null);
3248
+ }, []);
3249
+ const send = useCallback(async (prompt, context) => {
3250
+ abortControllerRef.current?.abort();
3251
+ abortControllerRef.current = new AbortController();
3252
+ setIsStreaming(true);
3253
+ setError(null);
3254
+ setUsage(null);
3255
+ setRawLines([]);
3256
+ const previousSpec = context?.previousSpec;
3257
+ let currentSpec = previousSpec && previousSpec.root ? {
3258
+ ...previousSpec,
3259
+ elements: { ...previousSpec.elements }
3260
+ } : {
3261
+ root: "",
3262
+ elements: {}
3263
+ };
3264
+ setSpec(currentSpec);
3265
+ try {
3266
+ const response = await fetch(api, {
3267
+ method: "POST",
3268
+ headers: { "Content-Type": "application/json" },
3269
+ body: JSON.stringify({
3270
+ prompt,
3271
+ context,
3272
+ currentSpec
3273
+ }),
3274
+ signal: abortControllerRef.current.signal
3275
+ });
3276
+ if (!response.ok) {
3277
+ let errorMessage = `HTTP error: ${response.status}`;
3278
+ try {
3279
+ const errorData = await response.json();
3280
+ if (errorData.message) errorMessage = errorData.message;
3281
+ else if (errorData.error) errorMessage = errorData.error;
3282
+ } catch {}
3283
+ throw new Error(errorMessage);
3284
+ }
3285
+ const reader = response.body?.getReader();
3286
+ if (!reader) throw new Error("No response body");
3287
+ const decoder = new TextDecoder();
3288
+ let buffer = "";
3289
+ while (true) {
3290
+ const { done, value } = await reader.read();
3291
+ if (done) break;
3292
+ buffer += decoder.decode(value, { stream: true });
3293
+ const lines = buffer.split("\n");
3294
+ buffer = lines.pop() ?? "";
3295
+ for (const line of lines) {
3296
+ const trimmed = line.trim();
3297
+ if (!trimmed) continue;
3298
+ const result = parseLine(trimmed);
3299
+ if (!result) continue;
3300
+ if (result.type === "usage") setUsage(result.usage);
3301
+ else {
3302
+ setRawLines((prev) => [...prev, trimmed]);
3303
+ currentSpec = applyPatch(currentSpec, result.patch);
3304
+ setSpec({ ...currentSpec });
3305
+ }
3306
+ }
3307
+ }
3308
+ if (buffer.trim()) {
3309
+ const trimmed = buffer.trim();
3310
+ const result = parseLine(trimmed);
3311
+ if (result) if (result.type === "usage") setUsage(result.usage);
3312
+ else {
3313
+ setRawLines((prev) => [...prev, trimmed]);
3314
+ currentSpec = applyPatch(currentSpec, result.patch);
3315
+ setSpec({ ...currentSpec });
3316
+ }
3317
+ }
3318
+ onCompleteRef.current?.(currentSpec);
3319
+ } catch (err) {
3320
+ if (err.name === "AbortError") return;
3321
+ const error2 = err instanceof Error ? err : new Error(String(err));
3322
+ setError(error2);
3323
+ onErrorRef.current?.(error2);
3324
+ } finally {
3325
+ setIsStreaming(false);
3326
+ }
3327
+ }, [api]);
3328
+ useEffect(() => {
3329
+ return () => {
3330
+ abortControllerRef.current?.abort();
3331
+ };
3332
+ }, []);
3333
+ return {
3334
+ spec,
3335
+ isStreaming,
3336
+ error,
3337
+ usage,
3338
+ rawLines,
3339
+ send,
3340
+ clear
3341
+ };
3342
+ }
3343
+ function useBoundProp(propValue, bindingPath) {
3344
+ const { set } = useStateStore();
3345
+ return [propValue, useCallback((value) => {
3346
+ if (bindingPath) set(bindingPath, value);
3347
+ }, [bindingPath, set])];
3348
+ }
3349
+ function isSpecDataPart(data) {
3350
+ if (typeof data !== "object" || data === null) return false;
3351
+ const obj = data;
3352
+ switch (obj.type) {
3353
+ case "patch": return typeof obj.patch === "object" && obj.patch !== null;
3354
+ case "flat":
3355
+ case "nested": return typeof obj.spec === "object" && obj.spec !== null;
3356
+ default: return false;
3357
+ }
3358
+ }
3359
+ function buildSpecFromParts(parts) {
3360
+ const spec = {
3361
+ root: "",
3362
+ elements: {}
3363
+ };
3364
+ let hasSpec = false;
3365
+ for (const part of parts) if (part.type === SPEC_DATA_PART_TYPE) {
3366
+ if (!isSpecDataPart(part.data)) continue;
3367
+ const payload = part.data;
3368
+ if (payload.type === "patch") {
3369
+ hasSpec = true;
3370
+ applySpecPatch(spec, payload.patch);
3371
+ } else if (payload.type === "flat") {
3372
+ hasSpec = true;
3373
+ Object.assign(spec, payload.spec);
3374
+ } else if (payload.type === "nested") {
3375
+ hasSpec = true;
3376
+ const flat = nestedToFlat(payload.spec);
3377
+ Object.assign(spec, flat);
3378
+ }
3379
+ }
3380
+ return hasSpec ? spec : null;
3381
+ }
3382
+ function getTextFromParts(parts) {
3383
+ return parts.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text.trim()).filter(Boolean).join("\n\n");
3384
+ }
3385
+ function useJsonRenderMessage(parts) {
3386
+ const prevPartsRef = useRef([]);
3387
+ const prevResultRef = useRef({
3388
+ spec: null,
3389
+ text: ""
3390
+ });
3391
+ if (parts !== prevPartsRef.current && (parts.length !== prevPartsRef.current.length || parts[parts.length - 1] !== prevPartsRef.current[prevPartsRef.current.length - 1]) || prevPartsRef.current.length === 0) {
3392
+ prevPartsRef.current = parts;
3393
+ prevResultRef.current = {
3394
+ spec: buildSpecFromParts(parts),
3395
+ text: getTextFromParts(parts)
3396
+ };
3397
+ }
3398
+ const { spec, text } = prevResultRef.current;
3399
+ return {
3400
+ spec,
3401
+ text,
3402
+ hasSpec: spec !== null && Object.keys(spec.elements || {}).length > 0
3403
+ };
3404
+ }
3405
+ var chatMessageIdCounter = 0;
3406
+ function generateChatId() {
3407
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
3408
+ chatMessageIdCounter += 1;
3409
+ return `msg-${Date.now()}-${chatMessageIdCounter}`;
3410
+ }
3411
+ function useChatUI({ api, onComplete, onError }) {
3412
+ const [messages, setMessages] = useState([]);
3413
+ const [isStreaming, setIsStreaming] = useState(false);
3414
+ const [error, setError] = useState(null);
3415
+ const abortControllerRef = useRef(null);
3416
+ const messagesRef = useRef(messages);
3417
+ messagesRef.current = messages;
3418
+ const onCompleteRef = useRef(onComplete);
3419
+ onCompleteRef.current = onComplete;
3420
+ const onErrorRef = useRef(onError);
3421
+ onErrorRef.current = onError;
3422
+ const clear = useCallback(() => {
3423
+ setMessages([]);
3424
+ setError(null);
3425
+ }, []);
3426
+ const send = useCallback(async (text) => {
3427
+ if (!text.trim()) return;
3428
+ abortControllerRef.current?.abort();
3429
+ abortControllerRef.current = new AbortController();
3430
+ const userMessage = {
3431
+ id: generateChatId(),
3432
+ role: "user",
3433
+ text: text.trim(),
3434
+ spec: null
3435
+ };
3436
+ const assistantId = generateChatId();
3437
+ const assistantMessage = {
3438
+ id: assistantId,
3439
+ role: "assistant",
3440
+ text: "",
3441
+ spec: null
3442
+ };
3443
+ setMessages((prev) => [
3444
+ ...prev,
3445
+ userMessage,
3446
+ assistantMessage
3447
+ ]);
3448
+ setIsStreaming(true);
3449
+ setError(null);
3450
+ const historyForApi = [...messagesRef.current.map((m) => ({
3451
+ role: m.role,
3452
+ content: m.text
3453
+ })), {
3454
+ role: "user",
3455
+ content: text.trim()
3456
+ }];
3457
+ let accumulatedText = "";
3458
+ let currentSpec = {
3459
+ root: "",
3460
+ elements: {}
3461
+ };
3462
+ let hasSpec = false;
3463
+ try {
3464
+ const response = await fetch(api, {
3465
+ method: "POST",
3466
+ headers: { "Content-Type": "application/json" },
3467
+ body: JSON.stringify({ messages: historyForApi }),
3468
+ signal: abortControllerRef.current.signal
3469
+ });
3470
+ if (!response.ok) {
3471
+ let errorMessage = `HTTP error: ${response.status}`;
3472
+ try {
3473
+ const errorData = await response.json();
3474
+ if (errorData.message) errorMessage = errorData.message;
3475
+ else if (errorData.error) errorMessage = errorData.error;
3476
+ } catch {}
3477
+ throw new Error(errorMessage);
3478
+ }
3479
+ const reader = response.body?.getReader();
3480
+ if (!reader) throw new Error("No response body");
3481
+ const decoder = new TextDecoder();
3482
+ const parser = createMixedStreamParser({
3483
+ onPatch(patch) {
3484
+ hasSpec = true;
3485
+ applySpecPatch(currentSpec, patch);
3486
+ setMessages((prev) => prev.map((m) => m.id === assistantId ? {
3487
+ ...m,
3488
+ spec: {
3489
+ root: currentSpec.root,
3490
+ elements: { ...currentSpec.elements },
3491
+ ...currentSpec.state ? { state: { ...currentSpec.state } } : {}
3492
+ }
3493
+ } : m));
3494
+ },
3495
+ onText(line) {
3496
+ accumulatedText += (accumulatedText ? "\n" : "") + line;
3497
+ setMessages((prev) => prev.map((m) => m.id === assistantId ? {
3498
+ ...m,
3499
+ text: accumulatedText
3500
+ } : m));
3501
+ }
3502
+ });
3503
+ while (true) {
3504
+ const { done, value } = await reader.read();
3505
+ if (done) break;
3506
+ parser.push(decoder.decode(value, { stream: true }));
3507
+ }
3508
+ parser.flush();
3509
+ const finalMessage = {
3510
+ id: assistantId,
3511
+ role: "assistant",
3512
+ text: accumulatedText,
3513
+ spec: hasSpec ? {
3514
+ root: currentSpec.root,
3515
+ elements: { ...currentSpec.elements },
3516
+ ...currentSpec.state ? { state: { ...currentSpec.state } } : {}
3517
+ } : null
3518
+ };
3519
+ onCompleteRef.current?.(finalMessage);
3520
+ } catch (err) {
3521
+ if (err.name === "AbortError") return;
3522
+ const resolvedError = err instanceof Error ? err : new Error(String(err));
3523
+ setError(resolvedError);
3524
+ setMessages((prev) => prev.filter((m) => m.id !== assistantId || m.text.length > 0));
3525
+ onErrorRef.current?.(resolvedError);
3526
+ } finally {
3527
+ setIsStreaming(false);
3528
+ }
3529
+ }, [api]);
3530
+ useEffect(() => {
3531
+ return () => {
3532
+ abortControllerRef.current?.abort();
3533
+ };
3534
+ }, []);
3535
+ return {
3536
+ messages,
3537
+ isStreaming,
3538
+ error,
3539
+ send,
3540
+ clear
3541
+ };
3542
+ }
3543
+ //#endregion
3544
+ export { resolveDynamicValue as C, getByPath as S, sfComponents as T, defineCatalog as _, ValidationProvider as a, validateSpec as b, defineRegistry as c, useJsonRenderMessage as d, useUIStream as f, deepMergeSpec as g, buildUserPrompt as h, StateProvider as i, useBoundProp as l, autoFixSpec as m, JSONUIProvider as n, VisibilityProvider as o, schema as p, Renderer as r, createRenderer as s, ActionProvider as t, useChatUI as u, diffToPatches as v, setByPath as w, createStateStore as x, evaluateVisibility as y };
3545
+
3546
+ //# sourceMappingURL=dist-BNlyONdD.js.map