@kitn.ai/ui 0.26.0 → 0.28.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 (488) hide show
  1. package/README.md +25 -6
  2. package/bin/mcp.js +16 -3
  3. package/bin/route.js +23 -0
  4. package/bin/route.test.js +58 -0
  5. package/dist/{elements/chunks/Icon--Y8vsFal.js → Icon-DObhsRtm.js} +1 -1
  6. package/dist/action-icons-CcgNN2oT.js +1 -0
  7. package/dist/arrow-down-CjRU3JgV.js +1 -0
  8. package/dist/arrow-left-Bnpb1UEW.js +1 -0
  9. package/dist/artifact-Bwt7OgcR.js +1 -0
  10. package/dist/assets/dev-5XzXYR21.js +91 -0
  11. package/dist/attachments-Qr4kg-2b.js +1 -0
  12. package/dist/{elements/chunks/audio-visualizer-D7lB6mvR.js → audio-visualizer-DToYdfSc.js} +1 -1
  13. package/dist/badge-CdEu_jn2.js +1 -0
  14. package/dist/bash-InADTalH.js +1 -6
  15. package/dist/bell-DQAAOpDz.js +1 -0
  16. package/dist/{elements/chunks/button-flUbeufF.js → button-DkuOnGLy.js} +1 -1
  17. package/dist/card-renderer-Jx70m6_l.js +1 -0
  18. package/dist/card-routing-0YidER_3.js +1 -0
  19. package/dist/check-njkVdZu2.js +1 -0
  20. package/dist/checkbox-D7iRB3nL.js +1 -0
  21. package/dist/checkbox-group-B2_rpoPM.js +1 -0
  22. package/dist/chevron-down-B72s6PXR.js +1 -0
  23. package/dist/chevron-right-BatuHzUm.js +1 -0
  24. package/dist/choice-card-m0BYqqOK.js +1 -0
  25. package/dist/circle-check-B62pODB3.js +1 -0
  26. package/dist/circle-x-BPG0iPst.js +1 -0
  27. package/dist/circle-zx0ByzY9.js +1 -0
  28. package/dist/{elements/chunks/cn-CU7UAWzk.js → cn-DN5AWfiS.js} +1 -1
  29. package/dist/code-block-ClMLKb7C.js +1 -0
  30. package/dist/{elements/chunks/collapsible-BzbXpPzr.js → collapsible-B4DlWicL.js} +1 -1
  31. package/dist/components/attachment-types.d.ts +7 -0
  32. package/dist/components/audio-visualizer/fit-scale.d.ts +1 -1
  33. package/dist/components/card-renderer.d.ts +13 -0
  34. package/dist/components/card.d.ts +4 -0
  35. package/dist/components/chat-thread.d.ts +135 -2
  36. package/dist/components/conversation-item.d.ts +35 -7
  37. package/dist/components/conversation-list.d.ts +17 -5
  38. package/dist/components/conversation-panel.d.ts +29 -0
  39. package/dist/components/form-widgets.d.ts +67 -2
  40. package/dist/components/form.d.ts +48 -1
  41. package/dist/components/home-panel.d.ts +34 -0
  42. package/dist/components/message.d.ts +25 -3
  43. package/dist/components/reasoning.d.ts +6 -0
  44. package/dist/components/scroll-button.d.ts +11 -0
  45. package/dist/components/thread.d.ts +5 -0
  46. package/dist/components/tool-types.d.ts +9 -0
  47. package/dist/components/widget-tab-bar.d.ts +16 -0
  48. package/dist/composer-sQ0HcvyG.js +106 -0
  49. package/dist/confirm-card-rQWDQsnC.js +1 -0
  50. package/dist/construct-cli.es.js +1337 -0
  51. package/dist/{elements/chunks/context-VLIL3sJ-.js → context-0kg4ZX1J.js} +1 -1
  52. package/dist/controllable-CnGpMF6r.js +1 -0
  53. package/dist/conversation-item-BxwQLaFJ.js +1 -0
  54. package/dist/conversation-list-BCfGN1JU.js +1 -0
  55. package/dist/copy-n9u9rqpi.js +1 -0
  56. package/dist/core-AYMC6_lb.js +12 -5874
  57. package/dist/{create-tween-BFT6c-Y8.js → create-tween-C-q-JCM-.js} +1 -1
  58. package/dist/{create-tween-CJNlzoaO.js → create-tween-CRrJXxBd.js} +1 -1
  59. package/dist/{create-tween-CQED4T0g.js → create-tween-DZ3RRDHD.js} +1 -1
  60. package/dist/{elements/chunks/create-tween-c4Z8TDYz.js → create-tween-uPkArjIG.js} +2 -2
  61. package/dist/css-M7EaDHN_.js +1 -6
  62. package/dist/custom-elements.json +1433 -202
  63. package/dist/default-input-CaMrJkgH.js +1 -0
  64. package/dist/define-By-uL588.js +1 -0
  65. package/dist/define.d.ts +4 -0
  66. package/dist/define.js +510 -0
  67. package/dist/define.server.d.ts +5 -0
  68. package/dist/define.server.js +506 -0
  69. package/dist/{elements/chunks/disclosure-CcNbyLy0.js → disclosure-WUImBbDv.js} +1 -1
  70. package/dist/{elements/chunks/dropdown-BgWTthUx.js → dropdown-wZVeJOMd.js} +1 -1
  71. package/dist/elements/agent-card.js +1 -1
  72. package/dist/elements/artifact.js +1 -1
  73. package/dist/elements/attachments.js +1 -1
  74. package/dist/elements/audio-visualizer.js +1 -1
  75. package/dist/elements/autoloader.js +1 -1
  76. package/dist/elements/avatar.js +1 -1
  77. package/dist/elements/badge.js +1 -1
  78. package/dist/elements/button.js +1 -1
  79. package/dist/elements/card.js +1 -1
  80. package/dist/elements/cards.js +1 -1
  81. package/dist/elements/chain-of-thought.js +1 -1
  82. package/dist/elements/chat-scope-picker.js +1 -1
  83. package/dist/elements/chat-workspace.js +1 -1
  84. package/dist/elements/chat.js +1 -1
  85. package/dist/elements/checkbox-group.d.ts +1 -0
  86. package/dist/elements/checkbox-group.js +1 -0
  87. package/dist/elements/checkbox.d.ts +1 -0
  88. package/dist/elements/checkbox.js +1 -0
  89. package/dist/elements/checkpoint.js +1 -1
  90. package/dist/elements/choice.js +1 -1
  91. package/dist/elements/coachmark.js +1 -1
  92. package/dist/elements/code-block.js +1 -1
  93. package/dist/elements/command.js +1 -1
  94. package/dist/elements/compare.js +1 -1
  95. package/dist/elements/composer.js +1 -1
  96. package/dist/elements/confirm-card.js +1 -1
  97. package/dist/elements/context-meter.js +1 -1
  98. package/dist/elements/conversation-item.js +1 -1
  99. package/dist/elements/conversation-list.js +1 -1
  100. package/dist/elements/define-entry.d.ts +12 -0
  101. package/dist/elements/dialog.js +1 -1
  102. package/dist/elements/dock.js +102 -8
  103. package/dist/elements/dropdown.js +1 -1
  104. package/dist/elements/editable-label.js +1 -1
  105. package/dist/elements/element-data-types.d.ts +37 -0
  106. package/dist/elements/embed.js +1 -1
  107. package/dist/elements/empty.js +1 -1
  108. package/dist/elements/feedback-bar.js +1 -1
  109. package/dist/elements/file-tree.js +1 -1
  110. package/dist/elements/file-upload.js +1 -1
  111. package/dist/elements/form.js +1 -1
  112. package/dist/elements/hover-card.js +1 -1
  113. package/dist/elements/icon.js +1 -1
  114. package/dist/elements/image.js +1 -1
  115. package/dist/elements/input.js +1 -1
  116. package/dist/elements/kbd.js +1 -1
  117. package/dist/elements/link-preview.js +1 -1
  118. package/dist/elements/loader.js +1 -1
  119. package/dist/elements/markdown.js +1 -1
  120. package/dist/elements/menu.js +1 -1
  121. package/dist/elements/message-skills.js +1 -1
  122. package/dist/elements/message.js +1 -1
  123. package/dist/elements/model-switcher.js +1 -1
  124. package/dist/elements/nav.js +1 -1
  125. package/dist/elements/notice.js +1 -1
  126. package/dist/elements/pane-grid.d.ts +1 -0
  127. package/dist/elements/pane-grid.js +1 -0
  128. package/dist/elements/pane-group.js +1 -1
  129. package/dist/elements/pane.js +1 -1
  130. package/dist/elements/popover.js +1 -1
  131. package/dist/elements/progress-bar.js +1 -1
  132. package/dist/elements/prompt-dock.js +1 -1
  133. package/dist/elements/prompt-input.js +1 -1
  134. package/dist/elements/prompt-suggestions.js +1 -1
  135. package/dist/elements/radio-group.d.ts +1 -0
  136. package/dist/elements/radio-group.js +1 -0
  137. package/dist/elements/reasoning.js +1 -1
  138. package/dist/elements/remote.js +1 -1
  139. package/dist/elements/resizable.js +1 -1
  140. package/dist/elements/response-stream.js +2 -2
  141. package/dist/elements/screen.js +1 -1
  142. package/dist/elements/scroll-area.js +1 -1
  143. package/dist/elements/scroll-button.js +1 -1
  144. package/dist/elements/search.js +1 -1
  145. package/dist/elements/segmented.js +1 -1
  146. package/dist/elements/select.d.ts +1 -0
  147. package/dist/elements/select.js +1 -0
  148. package/dist/elements/separator.js +1 -1
  149. package/dist/elements/setting-item.js +1 -1
  150. package/dist/elements/settings-group.js +1 -1
  151. package/dist/elements/skeleton.js +1 -1
  152. package/dist/elements/slider.d.ts +1 -0
  153. package/dist/elements/slider.js +1 -0
  154. package/dist/elements/slots.d.ts +1 -1
  155. package/dist/elements/source.js +1 -1
  156. package/dist/elements/status.js +1 -1
  157. package/dist/elements/switch.js +1 -1
  158. package/dist/elements/tabs.js +1 -1
  159. package/dist/elements/tasks.js +1 -1
  160. package/dist/elements/text-shimmer.js +1 -1
  161. package/dist/elements/thinking-bar.js +1 -1
  162. package/dist/elements/thread.js +1 -1
  163. package/dist/elements/toast.js +1 -1
  164. package/dist/elements/tool.js +1 -1
  165. package/dist/elements/tooltip.js +1 -1
  166. package/dist/elements/voice-input.js +1 -1
  167. package/dist/elements/voice-output.js +1 -1
  168. package/dist/elements.d.ts +380 -26
  169. package/dist/{elements/chunks/ellipsis-7gU33mL2.js → ellipsis-CbOpJnU3.js} +1 -1
  170. package/dist/embed-CrfjkbUG.js +1 -0
  171. package/dist/engine-javascript-vq0WuIJl.js +14 -2516
  172. package/dist/{elements/chunks/external-link-CSOEsNlx.js → external-link-ByXAwBBQ.js} +1 -1
  173. package/dist/file-text-DMib2qwt.js +1 -0
  174. package/dist/{elements/chunks/file-tree-zvB2i7P9.js → file-tree-CJqM2aP7.js} +1 -1
  175. package/dist/folder-_BAb929C.js +1 -0
  176. package/dist/form-DSZgZQZk.js +1 -0
  177. package/dist/github-dark-dimmed-DUshB20C.js +1 -4
  178. package/dist/github-light-JYsPkUQd.js +1 -4
  179. package/dist/hover-card-BQbul9eq.js +1 -0
  180. package/dist/html-CPZ3oZQ7.js +1 -10
  181. package/dist/icon-CdcfRhYI.js +1 -0
  182. package/dist/{elements/chunks/index-BCRhi84a.js → index-xu_pdcPi.js} +1 -1
  183. package/dist/index.d.ts +4 -2
  184. package/dist/index.js +7474 -5857
  185. package/dist/index.server.js +5965 -4762
  186. package/dist/info-DsFjGuI_.js +1 -0
  187. package/dist/input-DKbmkMos.js +1 -0
  188. package/dist/javascript-C25yR2R2.js +1 -6
  189. package/dist/json-DxJze_jm.js +1 -6
  190. package/dist/kai.es.js +1 -1
  191. package/dist/kbd-PvdGhX4s.js +1 -0
  192. package/dist/{elements/chunks/link-preview-OQ9IEq0f.js → link-preview-DbM1866N.js} +1 -1
  193. package/dist/link-zF8PzWfF.js +1 -0
  194. package/dist/loader-BM4CEz4G.js +1 -0
  195. package/dist/{elements/chunks/markdown-DgBFaGAz.js → markdown-LMvmAyBk.js} +7 -7
  196. package/dist/mcp.es.js +1361 -81
  197. package/dist/message-BSsgvHvf.js +1 -0
  198. package/dist/message-BYZECyek.js +1 -0
  199. package/dist/message-circle-DruwObfX.js +1 -0
  200. package/dist/message-square-BG6q6mlm.js +1 -0
  201. package/dist/{elements/chunks/minimize-2-DPIUKTrT.js → minimize-2-BQRoBV1V.js} +1 -1
  202. package/dist/{elements/chunks/model-switcher-DsT8tFB0.js → model-switcher-CMpCOYcB.js} +1 -1
  203. package/dist/{elements/chunks/overlay-DuiwdXjm.js → overlay-Cb-MkyDa.js} +1 -1
  204. package/dist/panel-right-i8warFxT.js +1 -0
  205. package/dist/paperclip-ByY3UVO6.js +1 -0
  206. package/dist/play-BvKKq3fX.js +1 -0
  207. package/dist/primitives/card-data-types.d.ts +49 -0
  208. package/dist/primitives/card-routing.d.ts +1 -33
  209. package/dist/primitives/card-validate.d.ts +2 -2
  210. package/dist/primitives/chat-config.d.ts +29 -2
  211. package/dist/primitives/conversation-store.d.ts +54 -0
  212. package/dist/primitives/field-mask.d.ts +96 -0
  213. package/dist/primitives/field-semantics.d.ts +36 -0
  214. package/dist/primitives/input-mask.d.ts +46 -0
  215. package/dist/primitives/url-scheme-policy.d.ts +34 -0
  216. package/dist/primitives/use-resize-observer.d.ts +2 -2
  217. package/dist/progress-bar-jVAHvMUf.js +1 -0
  218. package/dist/prompt-suggestion-CD-qtNgC.js +1 -0
  219. package/dist/radio-BsoBMhkF.js +1 -0
  220. package/dist/react/index.d.ts +586 -19
  221. package/dist/react.js +223 -187
  222. package/dist/reasoning-4kBPtlTx.js +1 -0
  223. package/dist/register-impl-B1hLkrI8.js +424 -0
  224. package/dist/{elements/chunks/resizable-D181b4fM.js → resizable-uPmY9VY-.js} +1 -1
  225. package/dist/rotate-ccw-B2xn93py.js +1 -0
  226. package/dist/rotate-cw-CMVLoCyH.js +1 -0
  227. package/dist/schemas/form.schema.json +21 -1
  228. package/dist/schemas/tool-defs.d.ts +11 -1
  229. package/dist/schemas.js +81 -81
  230. package/dist/scroll-area-BqLUo8ZZ.js +1 -0
  231. package/dist/scroll-button-DslXiJyL.js +1 -0
  232. package/dist/select-2cLRtPGT.js +1 -0
  233. package/dist/{elements/chunks/separator-CeJHQqLW.js → separator-BWQtNJcM.js} +1 -1
  234. package/dist/{elements/chunks/settings-CqaHgJF9.js → settings-BBR63jLg.js} +1 -1
  235. package/dist/{elements/chunks/settings-group-CjqjLCOn.js → settings-group-B2ciy-Iw.js} +1 -1
  236. package/dist/{elements/chunks/skeleton-D8akBnKS.js → skeleton-CkHI-HgC.js} +1 -1
  237. package/dist/slider-DDR9U-i0.js +1 -0
  238. package/dist/{solid-BtdqNZI7.js → solid-BzCFdL25.js} +9771 -7594
  239. package/dist/{solid-CnavwBye.js → solid-DruVOXnf.js} +7893 -6183
  240. package/dist/solid.d.ts +16 -2
  241. package/dist/solid.js +256 -243
  242. package/dist/solid.server.js +256 -243
  243. package/dist/source-GEnFF528.js +1 -0
  244. package/dist/star-CilHq8GP.js +1 -0
  245. package/dist/state/index.d.ts +1 -1
  246. package/dist/state/mock.d.ts +32 -2
  247. package/dist/state.js +133 -108
  248. package/dist/store-Ciyk6eZG.js +1 -0
  249. package/dist/svelte--5p79yCD.js +1 -15
  250. package/dist/switch-KkeQIbuH.js +1 -0
  251. package/dist/tasks-card-BrN4bggJ.js +1 -0
  252. package/dist/text-shimmer-Dcj1MHuq.js +1 -0
  253. package/dist/textarea-Dpvbngbg.js +1 -0
  254. package/dist/theme.tokens.css +110 -13
  255. package/dist/{elements/chunks/thumbs-up-DX2Ijk3H.js → thumbs-up-CsT9Wzb9.js} +1 -1
  256. package/dist/toast-store-tgK6MuMv.js +1 -0
  257. package/dist/{elements/chunks/tool-DKQ2D1DP.js → tool-DzUjIBT8.js} +1 -1
  258. package/dist/{elements/chunks/tooltip-B0G99y8w.js → tooltip-Bkkg_4t0.js} +1 -1
  259. package/dist/trash-2-jBKxjGGQ.js +1 -0
  260. package/dist/{elements/chunks/triangle-alert-F9cyUEyy.js → triangle-alert-DlQ68ppf.js} +1 -1
  261. package/dist/tsx-B8rCNbgL.js +1 -6
  262. package/dist/types.d.ts +48 -3
  263. package/dist/typescript-RycA9KXf.js +1 -6
  264. package/dist/ui/checkbox-group.d.ts +83 -0
  265. package/dist/ui/checkbox.d.ts +40 -0
  266. package/dist/ui/dock.d.ts +51 -0
  267. package/dist/ui/icon.d.ts +3 -0
  268. package/dist/ui/input.d.ts +48 -2
  269. package/dist/ui/radio.d.ts +85 -0
  270. package/dist/ui/select.d.ts +71 -0
  271. package/dist/ui/slider.d.ts +65 -0
  272. package/dist/ui/switch.d.ts +9 -2
  273. package/dist/upload-TcAHXv9W.js +1 -0
  274. package/dist/url-scheme-policy-DR5DgvkM.js +1 -0
  275. package/dist/use-card-resolution-DaZqAdWf.js +1 -0
  276. package/dist/{elements/chunks/variant-aurora-qt6Zct8M.js → variant-aurora-BhLuYxJR.js} +1 -1
  277. package/dist/{variant-aurora-B8II3-I1.js → variant-aurora-CNmfHhcx.js} +2 -2
  278. package/dist/{variant-aurora-CMNWOSJR.js → variant-aurora-D6GsdTPA.js} +2 -2
  279. package/dist/{variant-aurora-CcuDMWwQ.js → variant-aurora-DbW_OWL2.js} +1 -1
  280. package/dist/{elements/chunks/variant-custom-tJp22_BQ.js → variant-custom-BRvaNHSi.js} +1 -1
  281. package/dist/{variant-custom-L16JLLZy.js → variant-custom-BvYHR62b.js} +1 -1
  282. package/dist/{variant-custom-BdvYC7af.js → variant-custom-DMTrEO5w.js} +2 -2
  283. package/dist/{variant-custom-C714mqKl.js → variant-custom-DV2x254s.js} +2 -2
  284. package/dist/{variant-wave-ecwykeyL.js → variant-wave-BNMGrDfj.js} +2 -2
  285. package/dist/{variant-wave-2S4La2Ka.js → variant-wave-BpDd8t3Z.js} +1 -1
  286. package/dist/{variant-wave-D7ruiA1W.js → variant-wave-CyBueXj9.js} +2 -2
  287. package/dist/{elements/chunks/variant-wave-CaQ5ti39.js → variant-wave-sp-qwsdI.js} +1 -1
  288. package/dist/vue-BmIZj4XD.js +1 -33
  289. package/dist/x-Z5UntkIJ.js +1 -0
  290. package/frameworks/react/index.tsx +210 -22
  291. package/llms-full.txt +1184 -22
  292. package/llms.txt +6 -3
  293. package/package.json +17 -4
  294. package/src/agent-tooling/README.md +192 -0
  295. package/src/agent-tooling/catalog/invariants.ts +3 -3
  296. package/src/agent-tooling/catalog/surfaces.ts +72 -0
  297. package/src/agent-tooling/construct/cli-entry.ts +8 -0
  298. package/src/agent-tooling/construct/cli.ts +147 -0
  299. package/src/agent-tooling/construct/codegen.ts +1635 -0
  300. package/src/agent-tooling/construct/construct.v1.schema.json +319 -0
  301. package/src/agent-tooling/construct/dev.ts +148 -0
  302. package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +7 -0
  303. package/src/agent-tooling/construct/fixtures/ops-console.construct.json +44 -0
  304. package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +32 -0
  305. package/src/agent-tooling/construct/schema.ts +452 -0
  306. package/src/agent-tooling/mcp/server.ts +2 -1
  307. package/src/agent-tooling/mcp/tools/construct.ts +130 -0
  308. package/src/agent-tooling/mcp/tools/debug.ts +126 -4
  309. package/src/agent-tooling/mcp/tools/reference.ts +104 -3
  310. package/src/agent-tooling/recipes/composed-thread.ts +714 -0
  311. package/src/agent-tooling/recipes/index.ts +22 -0
  312. package/src/agent-tooling/recipes/types.ts +32 -0
  313. package/src/agent-tooling/registry.ts +5 -0
  314. package/src/components/attachment-types.ts +7 -0
  315. package/src/components/audio-visualizer/fit-scale.ts +1 -1
  316. package/src/components/card-renderer.tsx +39 -8
  317. package/src/components/card.tsx +10 -2
  318. package/src/components/chat-scope-picker.tsx +2 -2
  319. package/src/components/chat-thread.tsx +602 -43
  320. package/src/components/choice-card.tsx +102 -37
  321. package/src/components/coachmark.tsx +1 -1
  322. package/src/components/code-block.tsx +2 -2
  323. package/src/components/composer.tsx +89 -15
  324. package/src/components/confirm-card.tsx +20 -4
  325. package/src/components/conversation-item.tsx +56 -9
  326. package/src/components/conversation-list.tsx +25 -10
  327. package/src/components/conversation-panel.tsx +118 -0
  328. package/src/components/empty.tsx +14 -3
  329. package/src/components/file-tree.tsx +5 -1
  330. package/src/components/form-widgets.tsx +257 -195
  331. package/src/components/form.tsx +297 -9
  332. package/src/components/home-panel.tsx +159 -0
  333. package/src/components/loader.tsx +12 -5
  334. package/src/components/message-skills.tsx +1 -1
  335. package/src/components/message.tsx +71 -11
  336. package/src/components/prompt-input.tsx +7 -1
  337. package/src/components/prompt-suggestion.tsx +4 -1
  338. package/src/components/reasoning.tsx +30 -3
  339. package/src/components/response-compare.tsx +2 -2
  340. package/src/components/scroll-button.tsx +56 -4
  341. package/src/components/source.tsx +6 -1
  342. package/src/components/tasks-card.tsx +58 -16
  343. package/src/components/thread.tsx +10 -1
  344. package/src/components/toast.tsx +1 -1
  345. package/src/components/tool-types.ts +9 -0
  346. package/src/components/widget-tab-bar.tsx +73 -0
  347. package/src/elements/attachments.tsx +3 -1
  348. package/src/elements/chat-workspace.tsx +1 -1
  349. package/src/elements/chat.tsx +115 -5
  350. package/src/elements/checkbox-group.tsx +164 -0
  351. package/src/elements/checkbox.tsx +134 -0
  352. package/src/elements/compiled.css +1 -1
  353. package/src/elements/composer.tsx +12 -1
  354. package/src/elements/conversation-item.tsx +62 -22
  355. package/src/elements/conversation-list.tsx +2 -2
  356. package/src/elements/define-entry.ts +12 -0
  357. package/src/elements/dock.tsx +11 -0
  358. package/src/elements/element-data-types.ts +40 -0
  359. package/src/elements/element-manifest.json +24 -0
  360. package/src/elements/element-meta.json +767 -34
  361. package/src/elements/element-nonscalar.json +17 -0
  362. package/src/elements/element-types.d.ts +380 -26
  363. package/src/elements/feedback-bar.tsx +5 -0
  364. package/src/elements/icon-names.json +29 -0
  365. package/src/elements/input.tsx +312 -23
  366. package/src/elements/message.tsx +2 -0
  367. package/src/elements/pane-grid.tsx +111 -0
  368. package/src/elements/prompt-input.tsx +8 -2
  369. package/src/elements/radio-group.tsx +129 -0
  370. package/src/elements/register-impl.ts +6 -0
  371. package/src/elements/scroll-button.tsx +54 -6
  372. package/src/elements/select.tsx +165 -0
  373. package/src/elements/slider.tsx +171 -0
  374. package/src/elements/slots.ts +1 -1
  375. package/src/elements/styles.css +89 -3
  376. package/src/elements/thread.tsx +2 -0
  377. package/src/elements/toast.tsx +14 -1
  378. package/src/index.ts +5 -2
  379. package/src/primitives/card-data-types.ts +49 -0
  380. package/src/primitives/card-host.tsx +4 -2
  381. package/src/primitives/card-routing.ts +7 -56
  382. package/src/primitives/card-schemas/form.schema.json +21 -1
  383. package/src/primitives/card-validate.ts +10 -2
  384. package/src/primitives/chat-config.tsx +33 -6
  385. package/src/primitives/conversation-store.ts +248 -0
  386. package/src/primitives/field-mask.ts +256 -0
  387. package/src/primitives/field-semantics.ts +115 -0
  388. package/src/primitives/input-mask.ts +853 -0
  389. package/src/primitives/toast-store.ts +66 -4
  390. package/src/primitives/url-scheme-policy.ts +70 -0
  391. package/src/primitives/use-resize-observer.ts +2 -2
  392. package/src/schemas/tool-defs.ts +12 -2
  393. package/src/solid.ts +20 -2
  394. package/src/state/index.ts +1 -1
  395. package/src/state/mock.ts +92 -6
  396. package/src/types.ts +45 -3
  397. package/src/ui/agent-card.tsx +2 -2
  398. package/src/ui/avatar.tsx +1 -1
  399. package/src/ui/checkbox-group.tsx +153 -0
  400. package/src/ui/checkbox.tsx +63 -0
  401. package/src/ui/dock.tsx +192 -7
  402. package/src/ui/icon.tsx +53 -0
  403. package/src/ui/input.tsx +249 -9
  404. package/src/ui/kbd.tsx +1 -1
  405. package/src/ui/nav.tsx +1 -1
  406. package/src/ui/pane-group.tsx +2 -2
  407. package/src/ui/radio.tsx +150 -0
  408. package/src/ui/select.tsx +168 -0
  409. package/src/ui/slider.tsx +178 -0
  410. package/src/ui/switch.tsx +49 -18
  411. package/src/utils/cn.ts +11 -5
  412. package/theme.css +112 -13
  413. package/dist/elements/chunks/action-icons-D9u3OzYW.js +0 -1
  414. package/dist/elements/chunks/arrow-left-CVh1TeN7.js +0 -1
  415. package/dist/elements/chunks/artifact-BkYcfIlZ.js +0 -1
  416. package/dist/elements/chunks/attachments-DwfNlubq.js +0 -1
  417. package/dist/elements/chunks/badge-Q0-Cmwzz.js +0 -1
  418. package/dist/elements/chunks/bash-InADTalH.js +0 -1
  419. package/dist/elements/chunks/card-renderer-3Dyl-FpN.js +0 -1
  420. package/dist/elements/chunks/card-routing-BK09BdmL.js +0 -1
  421. package/dist/elements/chunks/check-B5kBPKeo.js +0 -1
  422. package/dist/elements/chunks/chevron-down-DZ1GS39h.js +0 -1
  423. package/dist/elements/chunks/chevron-right-CvP7OUd2.js +0 -1
  424. package/dist/elements/chunks/choice-card-D4QUIOWZ.js +0 -1
  425. package/dist/elements/chunks/circle-CDf9g6MQ.js +0 -1
  426. package/dist/elements/chunks/circle-check-CA47Nqbz.js +0 -1
  427. package/dist/elements/chunks/circle-x-CJ_HVbC8.js +0 -1
  428. package/dist/elements/chunks/code-block-BdLiTitd.js +0 -1
  429. package/dist/elements/chunks/composer-Byve-n8K.js +0 -69
  430. package/dist/elements/chunks/confirm-card-B0flE3MN.js +0 -1
  431. package/dist/elements/chunks/controllable-DTwTIlwp.js +0 -1
  432. package/dist/elements/chunks/conversation-item-BDztezOG.js +0 -1
  433. package/dist/elements/chunks/copy-Nf-kqxXH.js +0 -1
  434. package/dist/elements/chunks/core-AYMC6_lb.js +0 -12
  435. package/dist/elements/chunks/css-M7EaDHN_.js +0 -1
  436. package/dist/elements/chunks/default-input-C2iLFq0b.js +0 -1
  437. package/dist/elements/chunks/define-wjHR1MkU.js +0 -1
  438. package/dist/elements/chunks/download-C4V7tBdb.js +0 -1
  439. package/dist/elements/chunks/embed-D3KewsIJ.js +0 -1
  440. package/dist/elements/chunks/engine-javascript-vq0WuIJl.js +0 -141
  441. package/dist/elements/chunks/file-text-D1G8khle.js +0 -1
  442. package/dist/elements/chunks/folder-WW2LGLid.js +0 -1
  443. package/dist/elements/chunks/form-CQirdC4W.js +0 -1
  444. package/dist/elements/chunks/github-dark-dimmed-DUshB20C.js +0 -1
  445. package/dist/elements/chunks/github-light-JYsPkUQd.js +0 -1
  446. package/dist/elements/chunks/hover-card-CJJkfHTK.js +0 -1
  447. package/dist/elements/chunks/html-CPZ3oZQ7.js +0 -1
  448. package/dist/elements/chunks/icon-Cfgmf4fa.js +0 -1
  449. package/dist/elements/chunks/info-DX3YMOt6.js +0 -1
  450. package/dist/elements/chunks/input-BtW9U6Sq.js +0 -1
  451. package/dist/elements/chunks/javascript-C25yR2R2.js +0 -1
  452. package/dist/elements/chunks/json-DxJze_jm.js +0 -1
  453. package/dist/elements/chunks/kbd-LGXwuT_V.js +0 -1
  454. package/dist/elements/chunks/link-2My69BqT.js +0 -1
  455. package/dist/elements/chunks/loader-iOxc_Tu-.js +0 -1
  456. package/dist/elements/chunks/message-VMZohrXx.js +0 -1
  457. package/dist/elements/chunks/message-circle-CpXMM-_n.js +0 -1
  458. package/dist/elements/chunks/message-square-DxcWtETQ.js +0 -1
  459. package/dist/elements/chunks/message-tZmV2A3p.js +0 -1
  460. package/dist/elements/chunks/paperclip-CRZVp4z_.js +0 -1
  461. package/dist/elements/chunks/progress-bar-DNy66e_E.js +0 -1
  462. package/dist/elements/chunks/prompt-suggestion-Bn64Nl7L.js +0 -1
  463. package/dist/elements/chunks/reasoning-Emn9N4-T.js +0 -1
  464. package/dist/elements/chunks/rotate-cw-CPWe37D9.js +0 -1
  465. package/dist/elements/chunks/scroll-area-ClZkZxIk.js +0 -1
  466. package/dist/elements/chunks/scroll-button-DPE-t3x_.js +0 -1
  467. package/dist/elements/chunks/share-CyfnNEqp.js +0 -1
  468. package/dist/elements/chunks/source-UWCvmVak.js +0 -1
  469. package/dist/elements/chunks/star-DoHFAikQ.js +0 -1
  470. package/dist/elements/chunks/store-Cjq0qwYN.js +0 -1
  471. package/dist/elements/chunks/svelte--5p79yCD.js +0 -1
  472. package/dist/elements/chunks/tasks-card-CmZ5xh6v.js +0 -1
  473. package/dist/elements/chunks/text-shimmer-DYn09zrz.js +0 -1
  474. package/dist/elements/chunks/textarea-skiGHURM.js +0 -1
  475. package/dist/elements/chunks/toast-store-CFnQpThX.js +0 -1
  476. package/dist/elements/chunks/tsx-B8rCNbgL.js +0 -1
  477. package/dist/elements/chunks/typescript-RycA9KXf.js +0 -1
  478. package/dist/elements/chunks/use-card-resolution-DoA2f_EU.js +0 -1
  479. package/dist/elements/chunks/vue-BmIZj4XD.js +0 -1
  480. package/dist/elements/chunks/x-B6UnOiLw.js +0 -1
  481. package/dist/llms/llms-full.txt +0 -2949
  482. package/dist/llms/llms.txt +0 -156
  483. package/dist/register-impl-DpE7icIb.js +0 -293
  484. package/dist/ui/stat.d.ts +0 -16
  485. package/src/ui/stat.tsx +0 -41
  486. /package/dist/{elements/chunks/card-tags-D8lZ-C_U.js → card-tags-D8lZ-C_U.js} +0 -0
  487. /package/dist/{elements/chunks/link-preview-DNILK391.js → link-preview-DNILK391.js} +0 -0
  488. /package/dist/{elements/chunks/slots-DaNjX0rc.js → slots-DaNjX0rc.js} +0 -0
package/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  <!-- AUTO-GENERATED by scripts/gen-llms.mjs — do not edit by hand. Run `npm run build`. -->
2
2
  # @kitn.ai/ui
3
3
 
4
- > Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 83 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
4
+ > Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 89 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
5
5
 
6
6
  ## Install
7
7
 
@@ -35,7 +35,7 @@ Drop an element into any framework (React, Vue, plain HTML). Data in via JS prop
35
35
  - `<kai-prompt-input>` — standalone composer with send button.
36
36
 
37
37
  **Layer 2 — composable primitives** (`import { … } from '@kitn.ai/ui'`):
38
- All 83 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
38
+ All 89 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
39
39
 
40
40
  ## Key rules for the web components
41
41
 
@@ -149,7 +149,10 @@ For Tailwind builds: `@import "@kitn.ai/ui/theme.css"` in your CSS.
149
149
 
150
150
  ## Docs
151
151
 
152
- - Full element reference (all 83 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
152
+ - Element reference (all 89 elements, every prop/event/method/slot/part): the "Element reference" section of ./llms-full.txt — https://kitn.dev/llms-full.txt
153
+ - Programmatic layer (`@kitn.ai/ui/state` + `@kitn.ai/ui/wire`: streaming folds, the mock responder, the SSE readers/encoders): the "Programmatic layer" section of llms-full.txt
154
+ - How to build a chat app in 5 steps (install → pick a layer → handle submit + stream → wire features → theme, with working code): the "How to build a chat app in 5 steps" section of llms-full.txt
155
+ - Streaming recipe (the two rules that bite: reassign new references per chunk, fold deltas onto the trailing text part): the "Streaming recipe" section of llms-full.txt
153
156
  - Machine-readable Custom Elements Manifest: https://unpkg.com/@kitn.ai/ui/dist/custom-elements.json
154
157
  - Working examples: https://github.com/kitn-ai/ui/tree/main/examples
155
158
  - Storybook: https://storybook.kitn.dev
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitn.ai/ui",
3
- "version": "0.26.0",
3
+ "version": "0.28.0",
4
4
  "nx": {
5
5
  "name": "ui",
6
6
  "targets": {
@@ -116,6 +116,14 @@
116
116
  "types": "./dist/wire/index.d.ts",
117
117
  "default": "./dist/wire.js"
118
118
  },
119
+ "./define": {
120
+ "types": "./dist/define.d.ts",
121
+ "worker": "./dist/define.server.js",
122
+ "browser": "./dist/define.js",
123
+ "deno": "./dist/define.server.js",
124
+ "node": "./dist/define.server.js",
125
+ "default": "./dist/define.js"
126
+ },
119
127
  "./diagnostics": {
120
128
  "types": "./dist/diagnostics/index.d.ts",
121
129
  "default": "./dist/diagnostics.js"
@@ -162,16 +170,17 @@
162
170
  "scripts": {
163
171
  "prepublishOnly": "npm run build",
164
172
  "prebuild": "npm run build:css && npm run build:card-validation",
165
- "build": "vite build --config vite.config.ts && vite build --config vite.config.provider.ts && vite build --config vite.config.react.ts && vite build --config vite.config.barrel.ts && vite build --config vite.config.barrel.server.ts && vite build --config vite.config.solid.ts && vite build --config vite.config.solid.server.ts && vite build --config vite.config.state.ts && vite build --config vite.config.wire.ts && vite build --config vite.config.diagnostics.ts && vite build --config vite.config.schemas.ts && vite build --config vite.config.mcp.ts && npm run build:elements && npm run verify:elements-bundle && npm run verify:react-wrappers && npm run verify:shader-lazy",
173
+ "build": "vite build --config vite.config.ts && vite build --config vite.config.provider.ts && vite build --config vite.config.react.ts && vite build --config vite.config.barrel.ts && vite build --config vite.config.barrel.server.ts && vite build --config vite.config.solid.ts && vite build --config vite.config.solid.server.ts && vite build --config vite.config.state.ts && vite build --config vite.config.wire.ts && vite build --config vite.config.define.ts && vite build --config vite.config.define.server.ts && vite build --config vite.config.diagnostics.ts && vite build --config vite.config.schemas.ts && vite build --config vite.config.mcp.ts && vite build --config vite.config.construct-cli.ts && npm run build:elements && npm run verify:elements-bundle && npm run verify:react-wrappers && npm run verify:shader-lazy",
166
174
  "build:elements": "node scripts/gen-elements-manifest.mjs && vite build --config vite.config.elements.ts && node scripts/gen-element-dts.mjs",
167
175
  "postbuild": "npm run build:theme && npm run build:api && npm run build:schemas && npm run build:subpath-dts && npm run verify:dts",
168
176
  "build:theme": "node scripts/build-theme-tokens.mjs",
169
- "build:api": "node scripts/gen-elements-manifest.mjs && node scripts/gen-element-api.mjs && node scripts/gen-element-nonscalar.mjs && node scripts/gen-catalog.mjs",
177
+ "build:api": "node scripts/gen-elements-manifest.mjs && node scripts/gen-element-api.mjs && node scripts/gen-element-nonscalar.mjs && node scripts/gen-catalog.mjs && node scripts/gen-construct-schema.mjs",
170
178
  "build:schemas": "node scripts/copy-card-schemas.mjs",
171
179
  "build:card-validation": "node scripts/gen-card-validation-schemas.mjs",
172
180
  "build:subpath-dts": "node scripts/emit-subpath-dts.mjs",
173
181
  "verify:card-validation": "node scripts/gen-card-validation-schemas.mjs --self-test && node scripts/gen-card-validation-schemas.mjs --check",
174
182
  "verify:consumer": "node scripts/verify-consumer-sideeffects.mjs",
183
+ "verify:construct": "node scripts/verify-construct.mjs --self-test && node scripts/verify-construct.mjs",
175
184
  "verify:dts": "node scripts/verify-dts-boundaries.mjs --self-test && node scripts/verify-dts-boundaries.mjs",
176
185
  "verify:elements-bundle": "node scripts/verify-elements-bundle.mjs --self-test && node scripts/verify-elements-bundle.mjs",
177
186
  "verify:fresh": "node scripts/verify-artifact-fresh.mjs --self-test && node scripts/verify-artifact-fresh.mjs",
@@ -194,6 +203,7 @@
194
203
  "verify:starters": "node scripts/verify-starters.mjs",
195
204
  "lint:attachment-object-urls": "node scripts/lint-attachment-object-urls.mjs --self-test && node scripts/lint-attachment-object-urls.mjs",
196
205
  "lint:cdn-pins": "node scripts/lint-cdn-pins.mjs --self-test && node scripts/lint-cdn-pins.mjs --check-release-wiring && node scripts/lint-cdn-pins.mjs",
206
+ "lint:llms-size": "node scripts/lint-llms-size.mjs --self-test && node scripts/lint-llms-size.mjs",
197
207
  "lint:pack-parse": "node scripts/lint-pack-json-parse.mjs --self-test && node scripts/lint-pack-json-parse.mjs",
198
208
  "fix:cdn-pins": "node scripts/lint-cdn-pins.mjs --fix",
199
209
  "lint:silent-drops": "node scripts/lint-silent-drops.mjs --self-test && node scripts/lint-silent-drops.mjs",
@@ -220,7 +230,10 @@
220
230
  "test:slots-ivp": "playwright test --config playwright.slots.config.ts",
221
231
  "test:menu-ivp": "playwright test --config playwright.menu.config.ts",
222
232
  "test:command-ivp": "playwright test --config playwright.command.config.ts",
223
- "test:focus-ring": "playwright test --config playwright.focus-ring.config.ts"
233
+ "test:focus-ring": "playwright test --config playwright.focus-ring.config.ts",
234
+ "test:input-mask-ivp": "playwright test --config playwright.input-mask.config.ts",
235
+ "test:message-text-token": "playwright test --config playwright.message-text-token.config.ts",
236
+ "test:content-brand-bleed": "playwright test --config playwright.content-brand-bleed.config.ts"
224
237
  },
225
238
  "dependencies": {
226
239
  "@floating-ui/dom": "^1.7.6",
@@ -0,0 +1,192 @@
1
+ # `agent-tooling/`
2
+
3
+ The kit's machine-facing front door: everything that makes AI coding agents
4
+ and CLIs fluent building with `@kitn.ai/ui`. It is packaging and tooling on
5
+ top of the library, not part of it — `grep -rn "agent-tooling"
6
+ packages/ui/src/components packages/ui/src/elements` returns no imports (only
7
+ a code comment and a test's `UNSCANNED_DIRS` entry mention the directory by
8
+ name). Nothing a consumer's chat UI renders depends on anything in here.
9
+
10
+ ## The four parts
11
+
12
+ ```
13
+ ┌─────────────────────────┐
14
+ │ kai MCP server (mcp/) │
15
+ │ construct · scaffold · │
16
+ │ reference · theme · │
17
+ │ debug │
18
+ └───────┬─────────┬────────┘
19
+ consumes consumes
20
+ │ │
21
+ ▼ ▼
22
+ ┌────────────────┐ ┌──────────────────┐
23
+ │ construct/ │ │ catalog/ │
24
+ │ (schema→codegen │ │ (invariants, │
25
+ │ →cli engine) │ │ surfaces, │
26
+ └────────▲────────┘ │ fabrications, …) │
27
+ │ └───────────────────┘
28
+ standalone,
29
+ no MCP involved
30
+
31
+ ┌────────┴────────┐
32
+ │ bin/mcp.js CLI │
33
+ │ validate/dev/ │
34
+ │ compile/eject │
35
+ └──────────────────┘
36
+ ```
37
+
38
+ - **`mcp/`** — the `kai` MCP server. The tools in `mcp/tools/`:
39
+ - `construct.ts` — turn-by-turn authoring of a construct JSON file (one
40
+ JSON file → one web component); stateless, the harness owns the file.
41
+ - `scaffold.ts` — generates a full chat integration (framework + backend
42
+ route + integration wiring) from `agent-tooling/registry.ts` and
43
+ `agent-tooling/archetypes.ts` (backed by `agent-tooling/integrations/`).
44
+ - `reference.ts` — component/element/card lookup for an agent deciding what
45
+ to use.
46
+ - `theme.ts` — produces a `--kai-*` CSS token override block from a brand
47
+ color or description, resolved against the kit's own `theme.css`.
48
+ - `debug.ts` — diagnoses common `kai-*` integration failures from a
49
+ symptom/snippet, sourced from `apps/docs/src/content/docs/guides/for-ai-agents.mdx`.
50
+ - **`construct/`** — the construct engine: a declarative JSON format compiled
51
+ to a self-registering web component. Pipeline is `schema.ts` (Zod, single
52
+ source of truth) → `codegen.ts` (the one generation path — `kai dev`,
53
+ `kai compile`, and `kai eject` all call the same `generateProject`) →
54
+ `cli.ts` (the `validate | eject | dev | compile` subcommands). Fixtures
55
+ live in `construct/fixtures/` (`demo-widget`, `ops-console`,
56
+ `owner-widget`). The published JSON Schema artifact is
57
+ `construct/construct.v1.schema.json`, mirrored byte-identical at
58
+ `apps/docs/public/schemas/construct/v1.json`; both are guarded against
59
+ drift from the Zod source by `construct/schema-artifact.test.ts` (asserts
60
+ the checked-in artifact equals `z.toJSONSchema(ConstructSchema)` right now)
61
+ and regenerated by `scripts/gen-construct-schema.mjs` via `build:api`.
62
+ - **`catalog/`** — Zod-typed reference data, mostly independent of the
63
+ construct engine, each file feeding a specific consumer:
64
+ - `catalog-types.ts` — the shared Zod types (`SurfaceArchetype`,
65
+ `DeliveryTarget`, `WireReader`, `Backend`, …) the rest of the catalog is
66
+ built from.
67
+ - `invariants.ts` — the composition invariants an agent must hold, each
68
+ with an `enforcedBy` path and a `lint` script name; feeds
69
+ `invariants.test.ts` and the acceptance harness.
70
+ - `surfaces.ts` — the sorted inventory of product-shaped surfaces vs.
71
+ ingredients vs. corpus; feeds `surfaces.test.ts` and `derived.json`.
72
+ - `fabrications.ts` — tags agents have invented while working from an
73
+ acceptance pack (and what they should have used instead); renders the
74
+ pack's `FABRICATED.md`, checked against `derived.json` in both directions
75
+ by `fabrications.test.ts`.
76
+ - `scenarios.ts` — the acceptance deck (spec §6): prompts + what each
77
+ needs, written before the catalog it measures.
78
+ - `labs-titles.ts` — parses the real `Labs/…` story titles registered by
79
+ story files (TypeScript AST, not a regex), used to keep the catalog's
80
+ story inventory honest.
81
+ - `derived.json` — generated inventory of elements/props read by
82
+ `catalog-types.ts`, `fabrications.ts`, and `surfaces.ts` (and their
83
+ tests) rather than by anything outside the catalog.
84
+ - `catalog/README.md` — the catalog's own deeper documentation.
85
+
86
+ How they relate: the MCP's `construct` and `scaffold` tools **consume** the
87
+ construct engine and the catalogs — they don't reimplement authoring logic,
88
+ they call into `construct/schema.ts` / `construct/codegen.ts` and read the
89
+ registry/catalog data. The construct CLI (`bin/mcp.js validate|dev|compile|eject`,
90
+ built from `construct/cli-entry.ts` → `dist/construct-cli.es.js`) runs the
91
+ engine standalone, with no MCP server involved at all.
92
+
93
+ ## Usage
94
+
95
+ - **`npx @kitn.ai/ui mcp`** starts the MCP server (the historical default
96
+ subcommand). For wiring it into a multi-harness setup, see the docs site's
97
+ agents guide: `apps/docs/src/content/docs/guides/for-ai-agents.mdx`.
98
+ - **CLI form**, no MCP: `node bin/mcp.js validate|dev|compile|eject <construct.json>`
99
+ (`bin/mcp.js` dispatches `dev`/`compile`/`eject`/`validate` to the construct
100
+ CLI and anything else, including `mcp` or no argument, to the MCP server;
101
+ an unrecognized subcommand is a loud error, not a silent fallthrough).
102
+ `eject` writes a real Solid project you own; `dev` gives a live-reload
103
+ preview; `compile` emits one self-registering `.js`.
104
+ - **Acceptance harness** (`packages/ui/scripts/acceptance-*.mjs`:
105
+ `acceptance-pack.mjs`, `acceptance-run.mjs`, `acceptance-eval.mjs`,
106
+ `acceptance-gate-compiles.mjs`) — builds and grades a coding agent's
107
+ from-scratch attempt at using the catalog with no kit source, per the
108
+ scenarios in `catalog/scenarios.ts`; this is how the catalog's own claims
109
+ get checked against a real agent rather than asserted.
110
+
111
+ ## Worked example
112
+
113
+ `construct/fixtures/owner-widget.construct.json`, field by field:
114
+
115
+ - `"$schema"` — points at the published schema URL for editor validation.
116
+ - `"name": "acme-support"` — the construct's name; also the emitted custom
117
+ element's tag basis.
118
+ - `"layout": "widget"` — a floating launcher widget, not full-screen or docked.
119
+ - `"provider": { "mode": "mock" }` — no backend; canned responses (vs.
120
+ `mode: "endpoint"`, the consumer's own chat route).
121
+ - `"userId": "user_123"` — the identity value threaded through for
122
+ history/persistence.
123
+ - `"header": { "title": "Acme Support" }` — the chat header's title text.
124
+ - `"theme": { "unreadColor": "#38BDF8" }` — one branded token override.
125
+ - `"empty": { "title": ..., "description": ... }` — the empty-state copy
126
+ shown before the first message.
127
+ - `"widget": { "position": "top-start", "defaultOpen": true }` — widget-layout
128
+ placement and initial open state.
129
+ - `"capabilities.attachments.accept"` — allowed MIME patterns for uploads.
130
+ - `"capabilities.history.persistence": "local"` — history persisted in the
131
+ browser, not the consumer's backend.
132
+ - `"capabilities.starters"` — suggested first prompts.
133
+ - `"capabilities.reasoningOpen": true` — reasoning panels start expanded.
134
+ - `"capabilities.conversations": true` — enables the conversations sidebar.
135
+
136
+ `codegen.ts` turns this into a small, deterministic (no dates, no randomness,
137
+ fixed key order) Solid project: pure Solid interior composing
138
+ `@kitn.ai/ui/solid` components, provider glue built on `@kitn.ai/ui/state` +
139
+ `@kitn.ai/ui/wire` (never a hand-rolled SSE reader), and one
140
+ `defineWebComponent` facade carrying the tag, theme default, and slots. The
141
+ facade injects the kit's compiled CSS into the shadow root, so the generated
142
+ project needs no Tailwind and no CSS build step. `kai dev`, `kai compile`,
143
+ and `kai eject` all go through this same generation path — the preview is
144
+ the artifact, there is no separate interpreter to drift from it.
145
+
146
+ ## Rules that bind changes here
147
+
148
+ - **Vocabulary never logic** — the construct format has no handlers and no
149
+ expressions; it describes, it doesn't script. `schema.ts` is `.strict()`
150
+ everywhere, so an unknown key is a loud rejection.
151
+ - **Widen, never restructure `schema.ts`** — it's the single source of truth;
152
+ never hand-edit the generated JSON Schema artifacts or restate an enum
153
+ elsewhere, read it off `ConstructSchema.shape` or the generated artifact.
154
+ - **Derive, don't type** — the published schema artifact is generated from
155
+ Zod (`scripts/gen-construct-schema.mjs`, run by `build:api`) and pinned by
156
+ `construct/schema-artifact.test.ts`; `verify:construct`'s layout and
157
+ capability axes are read off that same drift-guarded artifact rather than
158
+ hand-listed, so adding a layout or capability to the Zod schema moves what
159
+ the gate covers on its own.
160
+ - **`verify:construct`** (`scripts/verify-construct.mjs`) drives the real CLI
161
+ end to end against this checkout's own packed tarball — eject, install,
162
+ compile under the emitted tsconfig, build, and bundle inside a real
163
+ consumer app — for every layout/capability combination the schema
164
+ currently declares. No unit test in this tree leaves the process; this is
165
+ the one that does.
166
+ - **`verify:scaffold`** (`scripts/verify-scaffold-compiles.mjs`) compiles the
167
+ scaffolder's emitted front ends and backend routes under `tsc --strict`
168
+ across the integration × surface × framework axes derived from the
169
+ registry, plus structural checks (e.g. the Solid emit branches on every
170
+ `MessagePart` variant).
171
+ - **`verify:generated`** (`scripts/verify-generated-sync.mjs`) re-runs
172
+ `build:api` and fails if any derived artifact in the tree (including
173
+ catalog/manifest files this directory reads) differs from what the
174
+ generator produces right now — catches drift `nx build ui`'s NX cache can
175
+ hide.
176
+ - **The schema-artifact test pair** (`construct/schema-artifact.test.ts`)
177
+ catches a `schema.ts` edit that shipped without a regen, in the unit suite
178
+ itself rather than only in CI's `verify:generated`.
179
+
180
+ ## Where deeper docs live
181
+
182
+ - Repo root [`CLAUDE.md`](../../../../CLAUDE.md)'s **Map** section for how
183
+ this directory sits relative to `primitives/`, `ui/`, `components/`, and
184
+ `elements/`.
185
+ - [`.claude/README.md`](../../../../.claude/README.md) for the project-local
186
+ skills/agents that exercise this tooling (notably `/consumer-regression`).
187
+ - The docs site's agents guide,
188
+ `apps/docs/src/content/docs/guides/for-ai-agents.mdx` — the rules
189
+ `debug.ts` and the MCP's contract enforcement are sourced from.
190
+ - `docs/superpowers/specs/2026-08-25-construct-engine-design.md` — the
191
+ construct engine's design spec (decisions ledger, format rules, success
192
+ criteria).
@@ -142,9 +142,9 @@ export const invariants: TInvariant[] = [
142
142
  ],
143
143
  examples: [
144
144
  {
145
- wrong: 'chat.conversations = rows;',
145
+ wrong: 'chat.conversationRows = rows;',
146
146
  right: 'conversations.conversations = rows;',
147
- note: 'kai-chat has no conversations prop the sidebar is its own element. One element never holds the whole app state.',
147
+ note: "kai-chat's own `conversations` prop is a boolean flag (turns the built-in list panel on); it has no `conversationRows`-shaped data prop, and the sidebar is its own element. One element never holds the whole app state.",
148
148
  },
149
149
  {
150
150
  wrong: "chat.addEventListener('kai-conversation-select', (e) => load(e.detail.id));",
@@ -199,7 +199,7 @@ export const invariants: TInvariant[] = [
199
199
  wrong: "window.open(card.url, '_blank');",
200
200
  right:
201
201
  "const isNavigable = (u) => { try { return ['http:', 'https:', 'mailto:'].includes(new URL(u, location.href).protocol); } catch { return false; } };\nif (isNavigable(card.url)) window.open(card.url, '_blank', 'noopener,noreferrer');",
202
- note: "THE try/catch IS NOT OPTIONAL: new URL() THROWS on an unparseable input like 'http://[', and an uncaught throw here crashes the render instead of blocking the link — worse than the bug you are fixing. Returning false is the whole contract. Resolving against location.href is deliberate: a relative or fragment href inherits http: and is allowed, which is what makes ordinary links keep working. REPO-INTERNAL ONLY: contributors inside this package use isSafeUrl/SAFE_SCHEMES from src/primitives/card-routing.ts, which has this exact shape — neither is reachable from the published package, so never emit an import for them.",
202
+ note: "THE try/catch IS NOT OPTIONAL: new URL() THROWS on an unparseable input like 'http://[', and an uncaught throw here crashes the render instead of blocking the link — worse than the bug you are fixing. Returning false is the whole contract. Resolving against location.href is deliberate: a relative or fragment href inherits http: and is allowed, which is what makes ordinary links keep working. REPO-INTERNAL ONLY: contributors inside this package use isSafeUrl/SAFE_SCHEMES from src/primitives/url-scheme-policy.ts (re-exported from src/primitives/card-routing.ts for the existing call sites), which has this exact shape — neither is reachable from the published package, so never emit an import for them.",
203
203
  },
204
204
  {
205
205
  wrong: '<a href={source.url}>{source.title}</a>',
@@ -239,6 +239,78 @@ export const surfaceRecipes: TSurfaceRecipe[] = [
239
239
  ],
240
240
  corpus: ['packages/ui/README.md'],
241
241
  },
242
+ {
243
+ // The hand-composed thread (rung-6 F-49): kai-chat deliberately absent —
244
+ // kai-thread renders the transcript, kai-composer takes input, and the
245
+ // HOST is every line of wiring between them. This record is the catalog
246
+ // half; the full compiling host module is the `composed-thread` CODE
247
+ // recipe (../recipes/composed-thread.ts, served by component_reference
248
+ // { name: "composed-thread" } and compiled by verify:scaffold), which is
249
+ // also this record's corpus. Ingredients with no wiring edge below are
250
+ // still real members of the composition: kai-feedback-bar's events
251
+ // terminate in the host rather than setting another element's property.
252
+ // (kai-conversation-item used to be in that list as "presentational
253
+ // standalone"; since F-45 tier 2 a standalone row activates itself, so
254
+ // the rail is a real kai-select edge below.)
255
+ id: 'composed-thread',
256
+ intent:
257
+ 'A full chat surface composed by hand from standalone elements — no <kai-chat>. ' +
258
+ 'The host module owns the store, streams through createAssistantStream + the wire ' +
259
+ 'reader, stages attachments as data: URIs, and drives the toast region as data.',
260
+ archetypes: ['full-screen'],
261
+ targets: ['bundler'],
262
+ ingredients: [
263
+ 'kai-thread',
264
+ 'kai-composer',
265
+ 'kai-attachments',
266
+ 'kai-toast-region',
267
+ 'kai-conversation-item',
268
+ 'kai-feedback-bar',
269
+ ],
270
+ backend: { endpoint: 'consumer-owned', reader: 'readOpenAIStream' },
271
+ wiring: [
272
+ {
273
+ from: 'kai-composer',
274
+ event: 'kai-submit',
275
+ to: 'kai-thread',
276
+ property: 'messages',
277
+ note: 'detail is {doc, text, entities} — read detail.text (NOT detail.value, which is kai-chat/kai-prompt-input\'s shape). The host appends the user turn plus any staged file parts and assigns a NEW array; the reply then streams onto the same property via createAssistantStream',
278
+ },
279
+ {
280
+ from: 'kai-attachments',
281
+ event: 'kai-remove',
282
+ to: 'kai-attachments',
283
+ property: 'items',
284
+ note: 'detail is {id}; the tray never mutates its own list — the host filters and reassigns items, and a data: URI needs no revocation on removal (attachment-blob-url is the rule this recipe corrects: F-44)',
285
+ },
286
+ {
287
+ from: 'kai-toast-region',
288
+ event: 'kai-dismiss',
289
+ to: 'kai-toast-region',
290
+ property: 'toasts',
291
+ note: 'detail is {id}; the region is driven as DATA because this app places its own and owns the array — the imperative toast() would ADOPT this markup-placed region (it mounts its own only when none exists) and bind its store over the toasts property, so pick one API per region',
292
+ },
293
+ {
294
+ from: 'kai-conversation-item',
295
+ event: 'kai-select',
296
+ to: 'kai-thread',
297
+ property: 'messages',
298
+ note: 'detail is {id}; STANDALONE rows only (F-45 tier 2) — outside <kai-conversations> the row body is a tabbable button and click / Enter / Space fire kai-select on the item (non-bubbling: listen on the row). Inside a container this never fires; the container\'s kai-conversation-select is the one activation event. The container\'s list story (roving tabindex, arrow keys) stays the host\'s job in a hand-rolled rail',
299
+ },
300
+ ],
301
+ invariants: [
302
+ 'reactivity-two-halves',
303
+ 'props-not-attributes',
304
+ 'events-non-bubbling',
305
+ 'host-coordinates',
306
+ 'kit-parses-consumer-fetches',
307
+ 'untrusted-model-output',
308
+ ],
309
+ corpus: [
310
+ 'packages/ui/src/agent-tooling/recipes/composed-thread.ts',
311
+ 'packages/ui/src/agent-tooling/catalog/surfaces.test.ts',
312
+ ],
313
+ },
242
314
  ];
243
315
 
244
316
  /**
@@ -0,0 +1,8 @@
1
+ /** Build entry for dist/construct-cli.es.js (vite.config.construct-cli.ts).
2
+ * bin/mcp.js imports this with the subcommand argv; process handling stays in
3
+ * the bin (this file stays free of exit calls, same split as mcp/stdio.ts). */
4
+ import { runCli } from './cli';
5
+
6
+ runCli(process.argv.slice(2)).then((code) => {
7
+ process.exitCode = code;
8
+ });
@@ -0,0 +1,147 @@
1
+ /**
2
+ * The kai construct CLI: validate | eject | dev | compile.
3
+ * Launched by bin/mcp.js (the package's one bin) via dist/construct-cli.es.js.
4
+ * Every subcommand goes through validateConstruct first — a validation failure
5
+ * never reaches codegen; the problems print with paths and the exit code says so.
6
+ */
7
+ import { readFileSync, mkdirSync, copyFileSync, writeFileSync } from 'node:fs';
8
+ import { spawn } from 'node:child_process';
9
+ import { join, resolve } from 'node:path';
10
+ import { validateConstruct, type Construct } from './schema';
11
+ import { accentContrastNotice, emitTypes, generateProject, writeProject } from './codegen';
12
+
13
+ export interface CliIo {
14
+ log: (s: string) => void;
15
+ error: (s: string) => void;
16
+ }
17
+
18
+ const defaultIo: CliIo = { log: (s) => console.log(s), error: (s) => console.error(s) };
19
+
20
+ const USAGE = `usage: kai <command>
21
+
22
+ kai validate <construct.json> check a construct, print problems with paths
23
+ kai eject <construct.json> <outDir> write the generated Solid project (it's yours)
24
+ kai dev <construct.json> live preview with reload-on-edit (Task 5)
25
+ kai compile <construct.json> [outDir] one self-registering .js (Task 6)
26
+ `;
27
+
28
+ /** H-3, decide loudly: `home.recentConversation` renders nothing without
29
+ * `capabilities.conversations` to draw the card from — never fatal (the
30
+ * schema explicitly does NOT require conversations for `home`, see
31
+ * schema.ts's own doc on `home`), just a non-blocking heads-up at validate
32
+ * time, the same idiom `validate`'s success line already uses (io.log, not
33
+ * a bare console call). Extracted so it can be unit-tested without going
34
+ * through the CLI's stdout wiring. */
35
+ export function homeRecentConversationWarning(construct: Construct): string | null {
36
+ if (construct.home?.recentConversation && !construct.capabilities?.conversations) {
37
+ return 'warning: home.recentConversation is set but capabilities.conversations is not — the recent-conversation card will render nothing without it.';
38
+ }
39
+ return null;
40
+ }
41
+
42
+ export function loadConstruct(path: string, io: CliIo): Construct | null {
43
+ const abs = resolve(path);
44
+ let raw: string;
45
+ try {
46
+ raw = readFileSync(abs, 'utf8');
47
+ } catch {
48
+ io.error(`cannot read ${abs}`);
49
+ return null;
50
+ }
51
+ let json: unknown;
52
+ try {
53
+ json = JSON.parse(raw);
54
+ } catch (err) {
55
+ io.error(`${abs} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
56
+ return null;
57
+ }
58
+ const out = validateConstruct(json);
59
+ if (!out.ok) {
60
+ io.error(`${abs} is not a valid construct:`);
61
+ for (const p of out.problems) io.error(` ${p.path || '(root)'}: ${p.message}`);
62
+ return null;
63
+ }
64
+ return out.construct;
65
+ }
66
+
67
+ /** `--ui <spec>` extraction shared by `dev` and `compile`. NB: guard the -1
68
+ * case — `i !== uiFlag + 1` with uiFlag === -1 would drop index 0. */
69
+ function parseUiFlag(rest: string[]): { uiSpec: string | undefined; positional: string[] } {
70
+ const uiFlag = rest.indexOf('--ui');
71
+ const uiSpec = uiFlag >= 0 ? rest[uiFlag + 1] : undefined;
72
+ const positional = uiFlag >= 0 ? rest.filter((_, i) => i !== uiFlag && i !== uiFlag + 1) : rest;
73
+ return { uiSpec, positional };
74
+ }
75
+
76
+ export async function runCli(argv: string[], io: CliIo = defaultIo): Promise<number> {
77
+ const [command, ...rest] = argv;
78
+ switch (command) {
79
+ case 'validate': {
80
+ const construct = loadConstruct(rest[0] ?? '', io);
81
+ if (!construct) return 1;
82
+ io.log(`valid construct: <${construct.name}> (layout: ${construct.layout}, provider: ${construct.provider.mode})`);
83
+ const warning = homeRecentConversationWarning(construct);
84
+ if (warning) io.log(warning);
85
+ return 0;
86
+ }
87
+ case 'eject': {
88
+ const { uiSpec, positional } = parseUiFlag(rest);
89
+ const [path, outDir] = positional;
90
+ if (!path || !outDir) {
91
+ io.error(USAGE);
92
+ return 2;
93
+ }
94
+ const construct = loadConstruct(path, io);
95
+ if (!construct) return 1;
96
+ const overwritten = writeProject(generateProject(construct, { uiSpec }), resolve(outDir));
97
+ if (overwritten.length > 0) {
98
+ io.log(`overwriting ${overwritten.length} existing file(s)`);
99
+ }
100
+ const notice = accentContrastNotice(construct);
101
+ if (notice) io.log(notice);
102
+ io.log(`ejected <${construct.name}> to ${resolve(outDir)} — npm install && npm run dev. The source is yours.`);
103
+ return 0;
104
+ }
105
+ case 'dev': {
106
+ const { uiSpec, positional } = parseUiFlag(rest);
107
+ const path = positional[0];
108
+ if (!path) {
109
+ io.error(USAGE);
110
+ return 2;
111
+ }
112
+ const { dev } = await import('./dev');
113
+ await dev(path, { io, uiSpec });
114
+ return 0; // unreachable; dev() never resolves
115
+ }
116
+ case 'compile': {
117
+ const { uiSpec, positional } = parseUiFlag(rest);
118
+ const [path, outArg] = positional;
119
+ if (!path) {
120
+ io.error(USAGE);
121
+ return 2;
122
+ }
123
+ const construct = loadConstruct(path, io);
124
+ if (!construct) return 1;
125
+ const outDir = resolve(outArg ?? 'dist-construct');
126
+ const { workDirFor, ensureInstalled } = await import('./dev');
127
+ const dir = workDirFor(construct.name, process.cwd());
128
+ const files = generateProject(construct, { uiSpec });
129
+ writeProject(files, dir);
130
+ await ensureInstalled(dir, files, io);
131
+ await new Promise<void>((done, fail) => {
132
+ const child = spawn('npm', ['run', 'build'], { cwd: dir, stdio: 'inherit' });
133
+ child.on('exit', (code) => (code === 0 ? done() : fail(new Error(`vite build exited ${code}`))));
134
+ });
135
+ mkdirSync(outDir, { recursive: true });
136
+ copyFileSync(join(dir, 'dist', `${construct.name}.js`), join(outDir, `${construct.name}.js`));
137
+ writeFileSync(join(outDir, `${construct.name}.d.ts`), emitTypes(construct));
138
+ writeProject(files, join(outDir, 'source'));
139
+ io.log(`compiled <${construct.name}> → ${outDir}/${construct.name}.js (source beside it in source/).`);
140
+ io.log(`endpoint backends: the kai MCP scaffold tool emits a matching route — see its output for your framework.`);
141
+ return 0;
142
+ }
143
+ default:
144
+ io.error(USAGE);
145
+ return 2;
146
+ }
147
+ }