@kitn.ai/ui 0.25.2 → 0.27.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 (603) hide show
  1. package/README.md +17 -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-b5A8hlHs.js → Icon-BnFKqqtY.js} +1 -1
  6. package/dist/action-icons-CBskfBMz.js +1 -0
  7. package/dist/arrow-down-Br0qtpsz.js +1 -0
  8. package/dist/arrow-left-Dj7xgE12.js +1 -0
  9. package/dist/artifact-CvXEm1lS.js +1 -0
  10. package/dist/assets/dev-5XzXYR21.js +91 -0
  11. package/dist/attachments-C43ZegEq.js +1 -0
  12. package/dist/audio-visualizer-B-79y1Tj.js +1 -0
  13. package/dist/badge-BpUbq8c0.js +1 -0
  14. package/dist/bash-InADTalH.js +1 -6
  15. package/dist/bell-sn17Ip9v.js +1 -0
  16. package/dist/{elements/chunks/button-B9okqG73.js → button-BH6rN0U-.js} +1 -1
  17. package/dist/card-renderer-Cb1gQmth.js +1 -0
  18. package/dist/card-routing-DifQgS7n.js +1 -0
  19. package/dist/check-DPeeMUYx.js +1 -0
  20. package/dist/checkbox-Dc9Yov_B.js +1 -0
  21. package/dist/checkbox-group-B1kDLLYk.js +1 -0
  22. package/dist/chevron-down-CHSWk7ZT.js +1 -0
  23. package/dist/chevron-right-B7l_fMgx.js +1 -0
  24. package/dist/choice-card-BT3c1S8g.js +1 -0
  25. package/dist/circle-Bb0yOpqM.js +1 -0
  26. package/dist/circle-check-BGZpCiz7.js +1 -0
  27. package/dist/circle-x-wobWkoSx.js +1 -0
  28. package/dist/{elements/chunks/cn-CU7UAWzk.js → cn-DN5AWfiS.js} +1 -1
  29. package/dist/code-block-CUQ5mtv0.js +1 -0
  30. package/dist/collapsible-CPJbf6FM.js +1 -0
  31. package/dist/components/attachment-types.d.ts +53 -1
  32. package/dist/components/attachments.d.ts +31 -0
  33. package/dist/components/audio-visualizer/fit-scale.d.ts +50 -0
  34. package/dist/components/audio-visualizer/index.d.ts +15 -1
  35. package/dist/components/audio-visualizer/variant-bar.d.ts +24 -1
  36. package/dist/components/card-renderer.d.ts +13 -0
  37. package/dist/components/card.d.ts +4 -0
  38. package/dist/components/chat-thread.d.ts +49 -42
  39. package/dist/components/code-block.d.ts +22 -0
  40. package/dist/components/conversation-item.d.ts +66 -1
  41. package/dist/components/conversation-list.d.ts +77 -0
  42. package/dist/components/form-widgets.d.ts +67 -2
  43. package/dist/components/form.d.ts +89 -0
  44. package/dist/components/message.d.ts +29 -0
  45. package/dist/components/reasoning.d.ts +6 -0
  46. package/dist/components/scroll-button.d.ts +11 -0
  47. package/dist/components/thread.d.ts +5 -0
  48. package/dist/components/toast.d.ts +2 -1
  49. package/dist/components/tool-types.d.ts +9 -0
  50. package/dist/components/voice-input.d.ts +8 -0
  51. package/dist/components/voice-output.d.ts +12 -1
  52. package/dist/components/workspace-shell.d.ts +87 -0
  53. package/dist/composer-CjngLzal.js +106 -0
  54. package/dist/confirm-card-DCx_A4bU.js +1 -0
  55. package/dist/construct-cli.es.js +1169 -0
  56. package/dist/context-BY8V-Nlp.js +1 -0
  57. package/dist/controllable-D43BKmtX.js +1 -0
  58. package/dist/conversation-list-D4lLU_yS.js +1 -0
  59. package/dist/copy-B6DO4PqB.js +1 -0
  60. package/dist/core-AYMC6_lb.js +12 -5874
  61. package/dist/{create-tween-CUzOlaMS.js → create-tween-BPzaefTp.js} +1 -1
  62. package/dist/{create-tween-B5Y4Im8G.js → create-tween-CnMHviKB.js} +1 -1
  63. package/dist/{create-tween-4z1XYLkR.js → create-tween-D1aiGZZh.js} +1 -1
  64. package/dist/{elements/chunks/create-tween-CUrM6D_o.js → create-tween-DUSQUKpr.js} +2 -2
  65. package/dist/css-M7EaDHN_.js +1 -6
  66. package/dist/custom-elements.json +3468 -1927
  67. package/dist/default-input-CucQEOqH.js +1 -0
  68. package/dist/define-CGGX-7Vg.js +1 -0
  69. package/dist/define.d.ts +4 -0
  70. package/dist/define.js +510 -0
  71. package/dist/define.server.d.ts +5 -0
  72. package/dist/define.server.js +506 -0
  73. package/dist/diagnostics/hook.d.ts +81 -0
  74. package/dist/diagnostics/index.d.ts +7 -0
  75. package/dist/diagnostics/report-request.d.ts +61 -0
  76. package/dist/diagnostics.d.ts +5 -0
  77. package/dist/diagnostics.js +209 -0
  78. package/dist/disclosure-CbLtajUQ.js +1 -0
  79. package/dist/dropdown-BwhViJFd.js +1 -0
  80. package/dist/elements/agent-card.js +1 -1
  81. package/dist/elements/artifact.js +1 -1
  82. package/dist/elements/attachments.js +1 -1
  83. package/dist/elements/audio-visualizer.js +1 -1
  84. package/dist/elements/autoloader.js +1 -1
  85. package/dist/elements/avatar.js +1 -1
  86. package/dist/elements/badge.js +1 -1
  87. package/dist/elements/button.js +1 -1
  88. package/dist/elements/card.js +1 -1
  89. package/dist/elements/cards.js +1 -1
  90. package/dist/elements/chain-of-thought.js +1 -1
  91. package/dist/elements/chat-scope-picker.js +1 -1
  92. package/dist/elements/chat-workspace.js +1 -1
  93. package/dist/elements/chat.js +1 -1
  94. package/dist/elements/checkbox-group.d.ts +1 -0
  95. package/dist/elements/checkbox-group.js +1 -0
  96. package/dist/elements/checkbox.d.ts +1 -0
  97. package/dist/elements/checkbox.js +1 -0
  98. package/dist/elements/checkpoint.js +1 -1
  99. package/dist/elements/choice.js +1 -1
  100. package/dist/elements/coachmark.js +1 -1
  101. package/dist/elements/code-block.js +1 -1
  102. package/dist/elements/command.js +1 -1
  103. package/dist/elements/compare.js +1 -1
  104. package/dist/elements/composer.js +1 -1
  105. package/dist/elements/confirm-card.js +1 -1
  106. package/dist/elements/context-meter.js +1 -1
  107. package/dist/elements/conversation-item.d.ts +1 -0
  108. package/dist/elements/conversation-item.js +1 -0
  109. package/dist/elements/conversation-list.js +1 -1
  110. package/dist/elements/default-input.d.ts +3 -3
  111. package/dist/elements/define-entry.d.ts +12 -0
  112. package/dist/elements/define.d.ts +27 -0
  113. package/dist/elements/diagnostic-events.d.ts +74 -0
  114. package/dist/elements/dialog.js +1 -1
  115. package/dist/elements/dock.d.ts +1 -0
  116. package/dist/elements/dock.js +243 -0
  117. package/dist/elements/dropdown.d.ts +1 -0
  118. package/dist/elements/dropdown.js +1 -0
  119. package/dist/elements/editable-label.js +1 -1
  120. package/dist/elements/element-data-types.d.ts +37 -0
  121. package/dist/elements/element-diagnostics.d.ts +81 -0
  122. package/dist/elements/embed.js +1 -1
  123. package/dist/elements/empty.js +1 -1
  124. package/dist/elements/feedback-bar.js +1 -1
  125. package/dist/elements/file-tree.js +1 -1
  126. package/dist/elements/file-upload.js +1 -1
  127. package/dist/elements/form.js +1 -1
  128. package/dist/elements/hover-card.js +1 -1
  129. package/dist/elements/icon.js +1 -1
  130. package/dist/elements/image.js +1 -1
  131. package/dist/elements/input.js +1 -1
  132. package/dist/elements/kbd.js +1 -1
  133. package/dist/elements/link-preview.js +1 -1
  134. package/dist/elements/loader.js +1 -1
  135. package/dist/elements/markdown.js +1 -1
  136. package/dist/elements/menu.js +1 -1
  137. package/dist/elements/message-skills.js +1 -1
  138. package/dist/elements/message.js +1 -1
  139. package/dist/elements/model-switcher.js +1 -1
  140. package/dist/elements/nav.js +1 -1
  141. package/dist/elements/notice.js +1 -1
  142. package/dist/elements/pane-grid.d.ts +1 -0
  143. package/dist/elements/pane-grid.js +1 -0
  144. package/dist/elements/pane-group.js +1 -1
  145. package/dist/elements/pane.js +1 -1
  146. package/dist/elements/popover.js +1 -1
  147. package/dist/elements/progress-bar.js +1 -1
  148. package/dist/elements/prompt-dock.js +1 -1
  149. package/dist/elements/prompt-input.js +1 -1
  150. package/dist/elements/prompt-suggestions.js +1 -1
  151. package/dist/elements/radio-group.d.ts +1 -0
  152. package/dist/elements/radio-group.js +1 -0
  153. package/dist/elements/reasoning.js +1 -1
  154. package/dist/elements/register.d.ts +2 -0
  155. package/dist/elements/remote.js +1 -1
  156. package/dist/elements/resizable.js +1 -1
  157. package/dist/elements/response-stream.js +3 -3
  158. package/dist/elements/screen.js +1 -1
  159. package/dist/elements/scroll-area.js +1 -1
  160. package/dist/elements/scroll-button.js +1 -1
  161. package/dist/elements/search.js +1 -1
  162. package/dist/elements/segmented.js +1 -1
  163. package/dist/elements/select.d.ts +1 -0
  164. package/dist/elements/select.js +1 -0
  165. package/dist/elements/separator.js +1 -1
  166. package/dist/elements/setting-item.js +1 -1
  167. package/dist/elements/settings-group.js +1 -1
  168. package/dist/elements/skeleton.js +1 -1
  169. package/dist/elements/slider.d.ts +1 -0
  170. package/dist/elements/slider.js +1 -0
  171. package/dist/elements/slots.d.ts +36 -4
  172. package/dist/elements/source.js +1 -1
  173. package/dist/elements/status.js +1 -1
  174. package/dist/elements/switch.js +1 -1
  175. package/dist/elements/tabs.js +1 -1
  176. package/dist/elements/tasks.js +1 -1
  177. package/dist/elements/text-shimmer.js +1 -1
  178. package/dist/elements/thinking-bar.js +1 -1
  179. package/dist/elements/thread.js +1 -1
  180. package/dist/elements/toast.js +1 -1
  181. package/dist/elements/tool.js +1 -1
  182. package/dist/elements/tooltip.js +1 -1
  183. package/dist/elements/voice-input.js +1 -1
  184. package/dist/elements/voice-output.js +1 -1
  185. package/dist/elements.d.ts +589 -167
  186. package/dist/{elements/chunks/ellipsis-CVxqfsDZ.js → ellipsis-DFr4Vqr3.js} +1 -1
  187. package/dist/embed-5s_vU4J0.js +1 -0
  188. package/dist/engine-javascript-vq0WuIJl.js +14 -2516
  189. package/dist/{elements/chunks/external-link-DG2sRdQL.js → external-link-u9d85ORQ.js} +1 -1
  190. package/dist/file-text-CX7_x42o.js +1 -0
  191. package/dist/{elements/chunks/file-tree-yGWNK0Js.js → file-tree-D3kBjXI5.js} +1 -1
  192. package/dist/folder-V-YdIL8f.js +1 -0
  193. package/dist/form-BRNUMCN2.js +1 -0
  194. package/dist/github-dark-dimmed-DUshB20C.js +1 -4
  195. package/dist/github-light-JYsPkUQd.js +1 -4
  196. package/dist/hover-card-DaeiYrTA.js +1 -0
  197. package/dist/html-CPZ3oZQ7.js +1 -10
  198. package/dist/icon-BpixdZNq.js +1 -0
  199. package/dist/{elements/chunks/index-BCRhi84a.js → index-xu_pdcPi.js} +1 -1
  200. package/dist/index.d.ts +3 -1
  201. package/dist/index.js +8473 -6470
  202. package/dist/index.server.js +6495 -4958
  203. package/dist/info-8mFsIjS3.js +1 -0
  204. package/dist/input-d1Yuu-hz.js +1 -0
  205. package/dist/javascript-C25yR2R2.js +1 -6
  206. package/dist/json-DxJze_jm.js +1 -6
  207. package/dist/kai-provider.es.js +40 -40
  208. package/dist/kai.es.js +1 -1
  209. package/dist/kbd-961zMPFB.js +1 -0
  210. package/dist/link-DlZZBGaR.js +1 -0
  211. package/dist/{elements/chunks/link-preview-Cf5KOP-i.js → link-preview-DIIbV2Sd.js} +1 -1
  212. package/dist/loader-YQszHFaW.js +1 -0
  213. package/dist/{elements/chunks/markdown-DbozyYqa.js → markdown-CVk1MPsj.js} +1 -1
  214. package/dist/mcp.es.js +3873 -544
  215. package/dist/message-CwKVEdZg.js +1 -0
  216. package/dist/message-DS8lzHc1.js +1 -0
  217. package/dist/message-circle-Xf8Q-vZp.js +1 -0
  218. package/dist/message-square-Cxnwgkns.js +1 -0
  219. package/dist/{elements/chunks/minimize-2-SegJ_oku.js → minimize-2-UEZmP2QT.js} +1 -1
  220. package/dist/{elements/chunks/model-switcher-D7JrFFHp.js → model-switcher-Kk1jEQ5t.js} +1 -1
  221. package/dist/{elements/chunks/overlay-CV7z2YuX.js → overlay-C1od6LOz.js} +1 -1
  222. package/dist/panel-right-ryET0yyn.js +1 -0
  223. package/dist/paperclip-BDNoZFJP.js +1 -0
  224. package/dist/play-OFIvYXUQ.js +1 -0
  225. package/dist/primitives/card-data-types.d.ts +49 -0
  226. package/dist/primitives/card-routing.d.ts +1 -33
  227. package/dist/primitives/card-validate.d.ts +2 -2
  228. package/dist/primitives/chat-config.d.ts +29 -2
  229. package/dist/primitives/field-mask.d.ts +96 -0
  230. package/dist/primitives/field-semantics.d.ts +36 -0
  231. package/dist/primitives/input-mask.d.ts +46 -0
  232. package/dist/primitives/url-scheme-policy.d.ts +34 -0
  233. package/dist/primitives/use-resize-observer.d.ts +23 -0
  234. package/dist/primitives/use-speech-recognition.d.ts +8 -0
  235. package/dist/primitives/use-text-stream.d.ts +5 -0
  236. package/dist/progress-bar-BvYX0aoy.js +1 -0
  237. package/dist/prompt-suggestion-BRFu2lcu.js +1 -0
  238. package/dist/radio-DcL23cNJ.js +1 -0
  239. package/dist/react/index.d.ts +306 -283
  240. package/dist/react.js +309 -247
  241. package/dist/reasoning-Cackq4Rh.js +1 -0
  242. package/dist/register-impl-C7rENvPK.js +424 -0
  243. package/dist/{elements/chunks/resizable-Dpzjlvp4.js → resizable-Cp9HUYih.js} +1 -1
  244. package/dist/rotate-ccw-0DLRDHH5.js +1 -0
  245. package/dist/rotate-cw-DOB9IGcU.js +1 -0
  246. package/dist/schemas/form.schema.json +21 -1
  247. package/dist/schemas/index.d.ts +1 -1
  248. package/dist/schemas/tool-defs.d.ts +45 -0
  249. package/dist/schemas.js +398 -305
  250. package/dist/scroll-area-emVmWP4K.js +1 -0
  251. package/dist/scroll-button-CeP_gv1x.js +1 -0
  252. package/dist/select-CWmu00tS.js +1 -0
  253. package/dist/{elements/chunks/separator-DH2r_ZSZ.js → separator-CE6vly6z.js} +1 -1
  254. package/dist/{elements/chunks/settings-BFMOd6yB.js → settings-CE-78SvZ.js} +1 -1
  255. package/dist/{elements/chunks/settings-group-B3VZKIcz.js → settings-group-ZFWNxFQR.js} +1 -1
  256. package/dist/{elements/chunks/skeleton-N8BuWYmf.js → skeleton-BebdP4mf.js} +1 -1
  257. package/dist/slider-BAKRYUlz.js +1 -0
  258. package/dist/slots-DaNjX0rc.js +1 -0
  259. package/dist/{solid-BMuDmFo_.js → solid-BE5ui6sy.js} +10672 -8116
  260. package/dist/{solid-CGYNdLRR.js → solid-DFhsce3O.js} +8137 -6056
  261. package/dist/solid.d.ts +15 -0
  262. package/dist/solid.js +248 -235
  263. package/dist/solid.server.js +248 -235
  264. package/dist/source-B0FlguSx.js +1 -0
  265. package/dist/star-CBMZvLuN.js +1 -0
  266. package/dist/state/index.d.ts +5 -1
  267. package/dist/state/mock.d.ts +32 -2
  268. package/dist/state/persistence.d.ts +51 -0
  269. package/dist/state/stream.d.ts +50 -0
  270. package/dist/state/threads.d.ts +71 -0
  271. package/dist/state.js +297 -172
  272. package/dist/store-7eoadydQ.js +1 -0
  273. package/dist/svelte--5p79yCD.js +1 -15
  274. package/dist/switch-CViARZCy.js +1 -0
  275. package/dist/tasks-card-MjCcOhR_.js +1 -0
  276. package/dist/text-shimmer-DKlwRF2G.js +1 -0
  277. package/dist/textarea-3ay2Me2-.js +1 -0
  278. package/dist/theme.tokens.css +82 -13
  279. package/dist/{elements/chunks/thumbs-up-DQe0hvkZ.js → thumbs-up-DQcu2HMO.js} +1 -1
  280. package/dist/toast-store-C6yKOhbk.js +1 -0
  281. package/dist/{elements/chunks/tool-C1YtxwPu.js → tool-BCYNlfKy.js} +1 -1
  282. package/dist/{elements/chunks/tooltip-BqwnFWhn.js → tooltip-05zI4hjs.js} +1 -1
  283. package/dist/trash-2-BR1RxGky.js +1 -0
  284. package/dist/{elements/chunks/triangle-alert-B6or7F5u.js → triangle-alert-DHohDOCy.js} +1 -1
  285. package/dist/tsx-B8rCNbgL.js +1 -6
  286. package/dist/types.d.ts +4 -2
  287. package/dist/typescript-RycA9KXf.js +1 -6
  288. package/dist/ui/checkbox-group.d.ts +83 -0
  289. package/dist/ui/checkbox.d.ts +40 -0
  290. package/dist/ui/dock.d.ts +131 -0
  291. package/dist/ui/hover-card.d.ts +44 -0
  292. package/dist/ui/icon.d.ts +3 -0
  293. package/dist/ui/input.d.ts +48 -2
  294. package/dist/ui/radio.d.ts +85 -0
  295. package/dist/ui/select.d.ts +71 -0
  296. package/dist/ui/slider.d.ts +65 -0
  297. package/dist/ui/switch.d.ts +9 -2
  298. package/dist/upload-BbGW6A_u.js +1 -0
  299. package/dist/url-scheme-policy-DHpoTJwB.js +1 -0
  300. package/dist/use-card-resolution-CJW4grFa.js +1 -0
  301. package/dist/{variant-aurora-DwSOfraQ.js → variant-aurora-BUOVgPOB.js} +27 -27
  302. package/dist/{variant-aurora-wKvAQ5wp.js → variant-aurora-CUsUJvFI.js} +28 -28
  303. package/dist/{variant-aurora-XEkPT0_z.js → variant-aurora-CW2i4bfr.js} +2 -2
  304. package/dist/{elements/chunks/variant-aurora-QXTZPyST.js → variant-aurora-xiMPty8f.js} +2 -2
  305. package/dist/variant-custom-BQtOnmeO.js +1 -0
  306. package/dist/{variant-custom-BhS9wIpU.js → variant-custom-CAm9L-E5.js} +65 -65
  307. package/dist/{variant-custom-eFIg2XWQ.js → variant-custom-CAnzzppW.js} +40 -40
  308. package/dist/variant-custom-D91HjAKz.js +1 -0
  309. package/dist/{variant-wave-CUWGx9Bn.js → variant-wave-Ca1Ls4_y.js} +21 -21
  310. package/dist/{variant-wave-CbVsmgwT.js → variant-wave-CxX39DKd.js} +25 -25
  311. package/dist/{variant-wave-BwzrHD1s.js → variant-wave-DYyzIIZv.js} +2 -2
  312. package/dist/{elements/chunks/variant-wave-DDCwhLas.js → variant-wave-uY5crU_K.js} +2 -2
  313. package/dist/vue-BmIZj4XD.js +1 -33
  314. package/dist/wire/chunk.d.ts +47 -0
  315. package/dist/wire/diagnostics.d.ts +575 -0
  316. package/dist/wire/encode-probe.d.ts +70 -0
  317. package/dist/wire/encode.d.ts +24 -0
  318. package/dist/wire/index.d.ts +2 -0
  319. package/dist/wire/sse.d.ts +10 -2
  320. package/dist/wire.js +917 -480
  321. package/dist/x-C5m1JFgi.js +1 -0
  322. package/frameworks/react/index.tsx +325 -108
  323. package/llms-full.txt +1354 -82
  324. package/llms.txt +6 -3
  325. package/package.json +39 -6
  326. package/src/agent-tooling/archetypes.ts +41 -9
  327. package/src/agent-tooling/catalog/README.md +676 -0
  328. package/src/agent-tooling/catalog/catalog-types.ts +231 -0
  329. package/src/agent-tooling/catalog/fabrications.ts +96 -0
  330. package/src/agent-tooling/catalog/invariants.ts +284 -0
  331. package/src/agent-tooling/catalog/labs-titles.ts +114 -0
  332. package/src/agent-tooling/catalog/scenarios.ts +87 -0
  333. package/src/agent-tooling/catalog/surfaces.ts +347 -0
  334. package/src/agent-tooling/construct/cli-entry.ts +8 -0
  335. package/src/agent-tooling/construct/cli.ts +131 -0
  336. package/src/agent-tooling/construct/codegen.ts +1353 -0
  337. package/src/agent-tooling/construct/construct.v1.schema.json +250 -0
  338. package/src/agent-tooling/construct/dev.ts +148 -0
  339. package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +7 -0
  340. package/src/agent-tooling/construct/fixtures/ops-console.construct.json +44 -0
  341. package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +23 -0
  342. package/src/agent-tooling/construct/schema.ts +371 -0
  343. package/src/agent-tooling/integrations/anthropic.ts +7 -1
  344. package/src/agent-tooling/integrations/cloudflare.ts +43 -2
  345. package/src/agent-tooling/integrations/langgraph.ts +7 -1
  346. package/src/agent-tooling/integrations/mastra.ts +7 -1
  347. package/src/agent-tooling/integrations/mock.ts +92 -17
  348. package/src/agent-tooling/integrations/ollama.ts +7 -1
  349. package/src/agent-tooling/integrations/openai.ts +7 -1
  350. package/src/agent-tooling/integrations/openrouter.ts +7 -1
  351. package/src/agent-tooling/integrations/pi.ts +56 -1
  352. package/src/agent-tooling/integrations/vercel-ai-sdk.ts +7 -1
  353. package/src/agent-tooling/mcp/css-raw.d.ts +12 -0
  354. package/src/agent-tooling/mcp/manifest.ts +100 -1
  355. package/src/agent-tooling/mcp/server.ts +63 -6
  356. package/src/agent-tooling/mcp/tools/construct.ts +130 -0
  357. package/src/agent-tooling/mcp/tools/debug.ts +126 -4
  358. package/src/agent-tooling/mcp/tools/reference.ts +542 -5
  359. package/src/agent-tooling/mcp/tools/scaffold.ts +1834 -307
  360. package/src/agent-tooling/mcp/tools/theme.ts +146 -30
  361. package/src/agent-tooling/mcp/validate-args.ts +141 -0
  362. package/src/agent-tooling/recipes/composed-thread.ts +714 -0
  363. package/src/agent-tooling/recipes/index.ts +22 -0
  364. package/src/agent-tooling/recipes/types.ts +32 -0
  365. package/src/agent-tooling/registry.ts +24 -7
  366. package/src/agent-tooling/route-emit.ts +26 -2
  367. package/src/components/attachment-types.ts +54 -1
  368. package/src/components/attachments.tsx +169 -22
  369. package/src/components/audio-visualizer/fit-scale.ts +112 -0
  370. package/src/components/audio-visualizer/index.tsx +80 -3
  371. package/src/components/audio-visualizer/variant-aurora.tsx +10 -4
  372. package/src/components/audio-visualizer/variant-bar.tsx +38 -6
  373. package/src/components/audio-visualizer/variant-custom.tsx +8 -2
  374. package/src/components/audio-visualizer/variant-grid.tsx +16 -11
  375. package/src/components/audio-visualizer/variant-radial.tsx +15 -10
  376. package/src/components/audio-visualizer/variant-wave.tsx +7 -2
  377. package/src/components/card-renderer.tsx +39 -8
  378. package/src/components/card.tsx +10 -2
  379. package/src/components/chat-container.tsx +4 -1
  380. package/src/components/chat-scope-picker.tsx +2 -2
  381. package/src/components/chat-thread.tsx +105 -13
  382. package/src/components/choice-card.tsx +102 -37
  383. package/src/components/coachmark.tsx +1 -1
  384. package/src/components/code-block.tsx +81 -5
  385. package/src/components/composer.tsx +89 -8
  386. package/src/components/confirm-card.tsx +20 -4
  387. package/src/components/conversation-item.tsx +138 -4
  388. package/src/components/conversation-list.tsx +230 -15
  389. package/src/components/embed.tsx +4 -0
  390. package/src/components/empty.tsx +14 -3
  391. package/src/components/file-tree.tsx +5 -1
  392. package/src/components/form-widgets.tsx +257 -195
  393. package/src/components/form.tsx +336 -21
  394. package/src/components/loader.tsx +12 -5
  395. package/src/components/message-skills.tsx +1 -1
  396. package/src/components/message.tsx +142 -12
  397. package/src/components/prompt-input.tsx +7 -1
  398. package/src/components/prompt-suggestion.tsx +4 -1
  399. package/src/components/reasoning.tsx +30 -3
  400. package/src/components/response-compare.tsx +2 -2
  401. package/src/components/response-stream.tsx +13 -7
  402. package/src/components/screen.tsx +5 -0
  403. package/src/components/scroll-button.tsx +63 -4
  404. package/src/components/source.tsx +6 -1
  405. package/src/components/tasks-card.tsx +58 -16
  406. package/src/components/thread.tsx +10 -1
  407. package/src/components/toast.tsx +11 -5
  408. package/src/components/tool-types.ts +9 -0
  409. package/src/components/voice-input.tsx +35 -3
  410. package/src/components/voice-output.tsx +46 -6
  411. package/src/components/workspace-shell.tsx +285 -0
  412. package/src/diagnostics/hook.ts +352 -0
  413. package/src/diagnostics/index.ts +82 -0
  414. package/src/diagnostics/report-request.ts +296 -0
  415. package/src/elements/attachments.tsx +9 -8
  416. package/src/elements/audio-visualizer.tsx +48 -4
  417. package/src/elements/chat-workspace.tsx +159 -287
  418. package/src/elements/chat.tsx +31 -10
  419. package/src/elements/checkbox-group.tsx +164 -0
  420. package/src/elements/checkbox.tsx +134 -0
  421. package/src/elements/code-block.tsx +19 -1
  422. package/src/elements/command.tsx +4 -1
  423. package/src/elements/compiled.css +1 -1
  424. package/src/elements/composer.tsx +12 -1
  425. package/src/elements/conversation-item.tsx +120 -0
  426. package/src/elements/conversation-list.tsx +60 -11
  427. package/src/elements/default-input.tsx +5 -5
  428. package/src/elements/define-entry.ts +12 -0
  429. package/src/elements/define.tsx +168 -8
  430. package/src/elements/diagnostic-events.ts +114 -0
  431. package/src/elements/dialog.tsx +47 -0
  432. package/src/elements/disclosure.ts +34 -12
  433. package/src/elements/dock.tsx +215 -0
  434. package/src/elements/dropdown.tsx +123 -0
  435. package/src/elements/element-data-types.ts +40 -0
  436. package/src/elements/element-diagnostics.ts +392 -0
  437. package/src/elements/element-manifest.json +36 -0
  438. package/src/elements/element-meta.json +1483 -560
  439. package/src/elements/element-nonscalar.json +185 -0
  440. package/src/elements/element-types.d.ts +589 -167
  441. package/src/elements/feedback-bar.tsx +5 -0
  442. package/src/elements/icon-names.json +29 -0
  443. package/src/elements/input.tsx +312 -23
  444. package/src/elements/menu.tsx +13 -0
  445. package/src/elements/message.tsx +2 -0
  446. package/src/elements/pane-grid.tsx +111 -0
  447. package/src/elements/prompt-dock.tsx +2 -1
  448. package/src/elements/prompt-input.tsx +16 -10
  449. package/src/elements/radio-group.tsx +129 -0
  450. package/src/elements/register-impl.ts +52 -0
  451. package/src/elements/register.ts +28 -0
  452. package/src/elements/resizable.tsx +52 -25
  453. package/src/elements/scroll-button.tsx +59 -6
  454. package/src/elements/select.tsx +165 -0
  455. package/src/elements/slider.tsx +171 -0
  456. package/src/elements/slots.ts +108 -13
  457. package/src/elements/styles.css +119 -9
  458. package/src/elements/thinking-bar.tsx +16 -7
  459. package/src/elements/thread.tsx +2 -0
  460. package/src/elements/toast.tsx +17 -1
  461. package/src/elements/tool.tsx +26 -5
  462. package/src/elements/voice-input.tsx +11 -2
  463. package/src/elements/voice-output.tsx +16 -3
  464. package/src/index.ts +4 -1
  465. package/src/primitives/card-data-types.ts +49 -0
  466. package/src/primitives/card-host.tsx +4 -2
  467. package/src/primitives/card-routing.ts +7 -56
  468. package/src/primitives/card-schemas/form.schema.json +21 -1
  469. package/src/primitives/card-validate.ts +10 -2
  470. package/src/primitives/chat-config.tsx +33 -6
  471. package/src/primitives/field-mask.ts +256 -0
  472. package/src/primitives/field-semantics.ts +115 -0
  473. package/src/primitives/input-mask.ts +853 -0
  474. package/src/primitives/toast-store.ts +66 -4
  475. package/src/primitives/url-scheme-policy.ts +70 -0
  476. package/src/primitives/use-resize-observer.ts +33 -0
  477. package/src/primitives/use-speech-recognition.ts +12 -1
  478. package/src/primitives/use-stick-to-bottom.ts +34 -2
  479. package/src/primitives/use-text-stream.ts +33 -2
  480. package/src/remote/provider-runtime.ts +6 -3
  481. package/src/schemas/index.ts +1 -0
  482. package/src/schemas/tool-defs.ts +307 -6
  483. package/src/solid.ts +15 -0
  484. package/src/state/index.ts +13 -1
  485. package/src/state/mock.ts +92 -6
  486. package/src/state/persistence.ts +180 -0
  487. package/src/state/stream.ts +71 -4
  488. package/src/state/threads.ts +142 -0
  489. package/src/types.ts +4 -2
  490. package/src/ui/agent-card.tsx +2 -2
  491. package/src/ui/avatar.tsx +1 -1
  492. package/src/ui/checkbox-group.tsx +153 -0
  493. package/src/ui/checkbox.tsx +63 -0
  494. package/src/ui/dialog.tsx +6 -0
  495. package/src/ui/dock.tsx +584 -0
  496. package/src/ui/dropdown.tsx +67 -23
  497. package/src/ui/hover-card.tsx +156 -6
  498. package/src/ui/icon.tsx +53 -0
  499. package/src/ui/input.tsx +275 -16
  500. package/src/ui/kbd.tsx +1 -1
  501. package/src/ui/nav.tsx +1 -1
  502. package/src/ui/pane-group.tsx +2 -2
  503. package/src/ui/radio.tsx +150 -0
  504. package/src/ui/resizable.tsx +11 -0
  505. package/src/ui/select.tsx +168 -0
  506. package/src/ui/slider.tsx +178 -0
  507. package/src/ui/switch.tsx +49 -18
  508. package/src/utils/cn.ts +11 -5
  509. package/src/wire/chunk.ts +47 -0
  510. package/src/wire/consume.ts +185 -26
  511. package/src/wire/diagnostics.ts +727 -0
  512. package/src/wire/encode-probe.ts +214 -0
  513. package/src/wire/encode.ts +267 -14
  514. package/src/wire/formats/anthropic.ts +8 -1
  515. package/src/wire/formats/openai.ts +5 -0
  516. package/src/wire/index.ts +22 -0
  517. package/src/wire/read.ts +250 -6
  518. package/src/wire/sse.ts +16 -3
  519. package/theme.css +84 -13
  520. package/dist/elements/chunks/action-icons-DW9muWrY.js +0 -1
  521. package/dist/elements/chunks/arrow-left-iJVnQmxA.js +0 -1
  522. package/dist/elements/chunks/artifact-BSuPYFHY.js +0 -1
  523. package/dist/elements/chunks/attachments-CL6TaqIb.js +0 -1
  524. package/dist/elements/chunks/audio-visualizer-BuUqQmaO.js +0 -1
  525. package/dist/elements/chunks/badge-TIMiJFKc.js +0 -1
  526. package/dist/elements/chunks/bash-InADTalH.js +0 -1
  527. package/dist/elements/chunks/card-renderer-CSoTL_e1.js +0 -1
  528. package/dist/elements/chunks/card-routing-BK09BdmL.js +0 -1
  529. package/dist/elements/chunks/chat-thread-DxoKaStk.js +0 -1
  530. package/dist/elements/chunks/check-MdLzbxrm.js +0 -1
  531. package/dist/elements/chunks/chevron-down-MK7IzDqe.js +0 -1
  532. package/dist/elements/chunks/chevron-right-C5jXhmtV.js +0 -1
  533. package/dist/elements/chunks/choice-card-CGMc3kek.js +0 -1
  534. package/dist/elements/chunks/circle-BG7VkPep.js +0 -1
  535. package/dist/elements/chunks/circle-check-GqvO2UBs.js +0 -1
  536. package/dist/elements/chunks/circle-x-mhH7pOK2.js +0 -1
  537. package/dist/elements/chunks/code-block-ClhQO9RW.js +0 -1
  538. package/dist/elements/chunks/collapsible-DBcBkFPh.js +0 -1
  539. package/dist/elements/chunks/composer-CZZmtYOT.js +0 -69
  540. package/dist/elements/chunks/confirm-card-BWjf2-xo.js +0 -1
  541. package/dist/elements/chunks/context-hKjNqiyQ.js +0 -1
  542. package/dist/elements/chunks/conversation-list-CsGJjSKG.js +0 -1
  543. package/dist/elements/chunks/core-AYMC6_lb.js +0 -12
  544. package/dist/elements/chunks/css-M7EaDHN_.js +0 -1
  545. package/dist/elements/chunks/default-input-B1Mem5wu.js +0 -1
  546. package/dist/elements/chunks/define-B_tXMYRm.js +0 -1
  547. package/dist/elements/chunks/disclosure-DAoYOKew.js +0 -1
  548. package/dist/elements/chunks/download-DnCyWFJE.js +0 -1
  549. package/dist/elements/chunks/dropdown-CmNna5lT.js +0 -1
  550. package/dist/elements/chunks/embed-CjAD2jSi.js +0 -1
  551. package/dist/elements/chunks/engine-javascript-vq0WuIJl.js +0 -141
  552. package/dist/elements/chunks/file-text-D0J9F6M7.js +0 -1
  553. package/dist/elements/chunks/folder-NV1pi_ud.js +0 -1
  554. package/dist/elements/chunks/form-Cp8Y00Wn.js +0 -1
  555. package/dist/elements/chunks/github-dark-dimmed-DUshB20C.js +0 -1
  556. package/dist/elements/chunks/github-light-JYsPkUQd.js +0 -1
  557. package/dist/elements/chunks/hover-card-6KtXpLwT.js +0 -1
  558. package/dist/elements/chunks/html-CPZ3oZQ7.js +0 -1
  559. package/dist/elements/chunks/icon-97R8SR2p.js +0 -1
  560. package/dist/elements/chunks/info-C8r5Q6cc.js +0 -1
  561. package/dist/elements/chunks/input-DrseEjhp.js +0 -1
  562. package/dist/elements/chunks/javascript-C25yR2R2.js +0 -1
  563. package/dist/elements/chunks/json-DxJze_jm.js +0 -1
  564. package/dist/elements/chunks/kbd-OGJDUT-O.js +0 -1
  565. package/dist/elements/chunks/link-BdsfLB7b.js +0 -1
  566. package/dist/elements/chunks/loader-B5QzK_8_.js +0 -1
  567. package/dist/elements/chunks/message-CE4k-qaj.js +0 -1
  568. package/dist/elements/chunks/message-DtXKPqiR.js +0 -1
  569. package/dist/elements/chunks/message-square-C9ovmtOo.js +0 -1
  570. package/dist/elements/chunks/paperclip-Bg0ITU3b.js +0 -1
  571. package/dist/elements/chunks/progress-bar-D1_rzt6N.js +0 -1
  572. package/dist/elements/chunks/prompt-suggestion-D5Sm8xF1.js +0 -1
  573. package/dist/elements/chunks/reasoning-BrxQfpfI.js +0 -1
  574. package/dist/elements/chunks/rotate-cw-DzVDJOA1.js +0 -1
  575. package/dist/elements/chunks/scroll-area-93A1bbeG.js +0 -1
  576. package/dist/elements/chunks/scroll-button-CrTo7wm4.js +0 -1
  577. package/dist/elements/chunks/share-DgNbkJKY.js +0 -1
  578. package/dist/elements/chunks/slots-CIw9RlAe.js +0 -1
  579. package/dist/elements/chunks/source-w9V0NnBn.js +0 -1
  580. package/dist/elements/chunks/star-DHvACxtm.js +0 -1
  581. package/dist/elements/chunks/store-HIPGhNz9.js +0 -1
  582. package/dist/elements/chunks/svelte--5p79yCD.js +0 -1
  583. package/dist/elements/chunks/tasks-card-lPxoodlA.js +0 -1
  584. package/dist/elements/chunks/text-shimmer-BY_rI3s5.js +0 -1
  585. package/dist/elements/chunks/textarea-DPfuhswM.js +0 -1
  586. package/dist/elements/chunks/toast-store-VUZZBhzH.js +0 -1
  587. package/dist/elements/chunks/tsx-B8rCNbgL.js +0 -1
  588. package/dist/elements/chunks/typescript-RycA9KXf.js +0 -1
  589. package/dist/elements/chunks/use-card-resolution-DJg32jGH.js +0 -1
  590. package/dist/elements/chunks/variant-custom-D5ZlmziF.js +0 -1
  591. package/dist/elements/chunks/video-Bb86fVYI.js +0 -1
  592. package/dist/elements/chunks/vue-BmIZj4XD.js +0 -1
  593. package/dist/elements/chunks/x-BOhjBeOd.js +0 -1
  594. package/dist/llms/llms-full.txt +0 -2834
  595. package/dist/llms/llms.txt +0 -156
  596. package/dist/primitives/card-validate-generator.testlib.d.ts +0 -20
  597. package/dist/register-impl-DGmGzrEM.js +0 -145
  598. package/dist/ui/stat.d.ts +0 -16
  599. package/dist/variant-custom-MkTNTycd.js +0 -1
  600. package/src/primitives/card-validate-generator.testlib.ts +0 -38
  601. package/src/ui/stat.tsx +0 -41
  602. /package/dist/{elements/chunks/card-tags-D8lZ-C_U.js → card-tags-D8lZ-C_U.js} +0 -0
  603. /package/dist/{elements/chunks/link-preview-DNILK391.js → link-preview-DNILK391.js} +0 -0
@@ -9,8 +9,29 @@ import {
9
9
  } from '@kitn.ai/ui/schemas';
10
10
  import type { CardSchemaName, ToolProvider } from '@kitn.ai/ui/schemas';
11
11
  import type { Tool } from './types';
12
- import { cardHostTags, cardTagForType, cardTypeForTag, getElement, listElements } from '../manifest';
12
+ import {
13
+ cardHostTags,
14
+ cardTagForType,
15
+ cardTypeForTag,
16
+ entryForTag,
17
+ getElement,
18
+ listElements,
19
+ optInEntryForTag,
20
+ } from '../manifest';
13
21
  import type { CemMember } from '../manifest';
22
+ // The RAW literals, not listInvariants() / listSurfaceRecipes(). Those re-run a
23
+ // zod parse over the whole catalog, and this is a per-lookup serving path called
24
+ // once for every element a harness asks about. The parse is not skipped, only
25
+ // moved: invariants.test.ts and surfaces.test.ts run it over these same literals
26
+ // in CI, so a malformed record fails a test rather than a request.
27
+ import { invariants } from '../../catalog/invariants';
28
+ import { surfaceRecipes } from '../../catalog/surfaces';
29
+ import type { TInvariant, TInvariantExample, TSurfaceRecipe } from '../../catalog/catalog-types';
30
+ import { listCodeRecipes, getCodeRecipe } from '../../recipes';
31
+ import type { CodeRecipe } from '../../recipes';
32
+ import { readFileSync, existsSync } from 'node:fs';
33
+ import { dirname, join } from 'node:path';
34
+ import { resolveManifestPath } from '../manifest';
14
35
 
15
36
  /**
16
37
  * component_reference — look up AI/UI (kai-*) web components, their props,
@@ -225,6 +246,420 @@ function renderCardHost(tag: string): string[] {
225
246
  ];
226
247
  }
227
248
 
249
+ // ─────────────────────────────────────────────────────────────────────────────
250
+ // The composition catalog: invariants, and recipe membership
251
+ // ─────────────────────────────────────────────────────────────────────────────
252
+
253
+ /**
254
+ * An invariant applies to a tag if it is unscoped by tag, or names it.
255
+ *
256
+ * `appliesTo.targets` deliberately does NOT filter here: `upgrade-race` is
257
+ * scoped to script-tag DELIVERY, which is a fact about how the page loads and
258
+ * not about which element is on it — every element can be dropped onto a CDN
259
+ * page. So it is served everywhere and the scope is RENDERED (see `scopeOf`),
260
+ * which is the difference between a conditional rule a reader can apply and an
261
+ * unqualified one they will either over-apply or stop trusting.
262
+ */
263
+ function invariantsFor(tag: string): TInvariant[] {
264
+ return invariants.filter((i) => !i.appliesTo.tags || i.appliesTo.tags.includes(tag));
265
+ }
266
+
267
+ /**
268
+ * The recipe's nesting, as markup a reader can paste.
269
+ *
270
+ * `noteSep` is how much of the record to print: the appendix passes ' — ' and
271
+ * gets the WHY, an element lookup passes '' and gets only the shape, on the same
272
+ * split the wiring rows already use. A recipe with no `composition` prints
273
+ * nothing at all rather than "flat" — the field being absent means nobody
274
+ * decided, and a rendered "(none)" would turn a gap into a claim.
275
+ */
276
+ function compositionLines(r: TSurfaceRecipe, noteSep: string): string[] {
277
+ if (!r.composition) return [];
278
+ return [
279
+ '- **Composition** — where the parts go (a slotted child, not a sibling):',
280
+ ...r.composition.map(
281
+ (c) =>
282
+ ` - \`<${c.child} slot="${c.slot}">\` goes INSIDE \`<${c.parent}>\`` +
283
+ (noteSep && c.note ? `${noteSep}${c.note}` : ''),
284
+ ),
285
+ ];
286
+ }
287
+
288
+ function recipesFor(tag: string): TSurfaceRecipe[] {
289
+ return surfaceRecipes.filter((r) => r.ingredients.includes(tag));
290
+ }
291
+
292
+ /**
293
+ * How the coverage of one invariant reads — never a bare status word, and never
294
+ * silence.
295
+ *
296
+ * Three of the catalog's records are enforced by NOTHING and two more by half of
297
+ * what they say. A section that printed every rule as an equal-looking bullet
298
+ * would put back exactly the overstatement those records were rewritten to
299
+ * remove, one layer further out where it is harder to see. The wording also says
300
+ * whose code the guard reads: every path here is inside the KIT's own repo, and
301
+ * none of them checks the consumer's.
302
+ */
303
+ function coverageOf(inv: TInvariant): string {
304
+ const by = inv.enforcedBy;
305
+ // `guard` is '' only for kind:'none', and that combination reaches neither the
306
+ // 'enforced' nor the 'partial' branch below: invariants.test.ts ("open ⟺
307
+ // enforcedBy.kind none") asserts the equivalence in BOTH directions, so a
308
+ // kind:'none' record is always status:'open'. Named here because a reader of
309
+ // this file alone cannot see what makes `enforced by ` with nothing after it
310
+ // unreachable.
311
+ const guard =
312
+ by.kind === 'test'
313
+ ? `the kit's own tests (${by.paths.join(', ')})`
314
+ : by.kind === 'lint'
315
+ ? `the kit's \`${by.script}\` script, in required CI`
316
+ : by.kind === 'structural'
317
+ ? `a structural guarantee in ${by.path}`
318
+ : '';
319
+
320
+ switch (inv.status) {
321
+ case 'enforced':
322
+ return `enforced by ${guard}`;
323
+ case 'partial':
324
+ return `PARTIALLY ENFORCED: one half is covered, by ${guard}; the statement says which half is not`;
325
+ case 'open':
326
+ return (
327
+ 'NOT ENFORCED: nothing in the kit checks this' +
328
+ (by.kind === 'none' && by.until ? `, until ${by.until}` : '') +
329
+ '. A rule you apply, not a guarantee you will be warned about'
330
+ );
331
+ }
332
+ }
333
+
334
+ /** What narrows an invariant, when something does. `targets` is not `tags`. */
335
+ function scopeOf(inv: TInvariant): string {
336
+ const { tags, targets, parts } = inv.appliesTo;
337
+ const bits: string[] = [];
338
+ if (tags) bits.push(`only ${tags.join(', ')}`);
339
+ if (targets) bits.push(`${targets.join(' / ')} delivery only`);
340
+ if (parts) bits.push(`parts ${parts.join(', ')}`);
341
+ return bits.join('; ');
342
+ }
343
+
344
+ /**
345
+ * The wrong/right pairs, as one fenced block per invariant.
346
+ *
347
+ * A fence rather than inline code because a `right` form is allowed to span
348
+ * lines (the URL guards do), and because the pairs are meant to be
349
+ * pattern-matched and grepped verbatim — the self-audit checklist greps emitted
350
+ * code for the `wrong` form and expects zero hits, which only works if what is
351
+ * served here is the literal and not a paraphrase of it.
352
+ */
353
+ function exampleLines(examples: TInvariantExample[]): string[] {
354
+ if (examples.length === 0) return [];
355
+ const out: string[] = ['', '```js'];
356
+ examples.forEach((ex, i) => {
357
+ if (i > 0) out.push('');
358
+ out.push('// WRONG', ex.wrong, '// RIGHT', ex.right);
359
+ if (ex.note) out.push(...ex.note.split('\n').map((l) => `// ${l}`));
360
+ });
361
+ out.push('```');
362
+ return out;
363
+ }
364
+
365
+ /**
366
+ * The one sentence saying how much of this section is actually guarded.
367
+ *
368
+ * BOTH numerators are derived and both are needed. `open` alone was the first
369
+ * form of this line, and it is the more quotable half: "3 of the 7 below are
370
+ * enforced by NOTHING" compresses, in any reader summarising it, into "3
371
+ * unenforced, 4 enforced" — and two of that four are `partial`, covered on one
372
+ * half only. That is this repo's own compression-drops-the-qualifier failure,
373
+ * sitting in the sentence written to prevent it. Naming both counts leaves the
374
+ * compression nothing to invent.
375
+ *
376
+ * Returns '' when every applicable record is fully enforced, so the line can
377
+ * never outlive the gap it describes and become a comfortable falsehood.
378
+ *
379
+ * Exported for reference.test.ts, which drives all four count combinations over
380
+ * synthetic records — the real catalog can only instance one of them at a time.
381
+ */
382
+ export function coverageSummary(applicable: TInvariant[]): string {
383
+ const open = applicable.filter((i) => i.status === 'open').length;
384
+ const partial = applicable.filter((i) => i.status === 'partial').length;
385
+ if (open === 0 && partial === 0) return '';
386
+
387
+ const total = applicable.length;
388
+ const half = (n: number) => `only half of what ${n === 1 ? 'it says' : 'they say'}`;
389
+ const clauses: string[] = [];
390
+
391
+ if (open > 0) {
392
+ clauses.push(`${open} of the ${total} below ${open === 1 ? 'is' : 'are'} enforced by NOTHING at all`);
393
+ }
394
+ if (partial > 0) {
395
+ clauses.push(
396
+ open > 0
397
+ ? `${partial} more by ${half(partial)}`
398
+ : `${partial} of the ${total} below ${partial === 1 ? 'is' : 'are'} enforced by ${half(partial)}`,
399
+ );
400
+ }
401
+ return ` ${clauses.join(', and ')}.`;
402
+ }
403
+
404
+ /**
405
+ * `###` to match every other section heading in this file (see '### Props'),
406
+ * `####` for the per-record blocks, matching the card contract's sub-headings.
407
+ *
408
+ * Each invariant gets its heading (id, scope, coverage) and its one-line
409
+ * `statement` — enough to apply the rule and to know how much to trust it —
410
+ * but NOT the diagnosis and wrong/right examples. Those are the bulk: measured
411
+ * on this tree, the full body of the 7 catalog records runs ~13 KB, and every
412
+ * unscoped record (5 of 7) applies to all 80 elements, so printing the full
413
+ * body here paid that in full on every lookup. `renderInvariantAppendix`
414
+ * carries the long form exactly once; this function points to it instead of
415
+ * repeating it.
416
+ */
417
+ function catalogSectionLines(tag: string): string[] {
418
+ const applicable = invariantsFor(tag);
419
+ const lines: string[] = [];
420
+
421
+ if (applicable.length > 0) {
422
+ lines.push(
423
+ '',
424
+ '### Invariants',
425
+ 'Rules that have already broken real consumers of this kit. Each block says what enforces ' +
426
+ 'it — read that line rather than assuming CI catches a violation, because nothing here ' +
427
+ 'reads YOUR code.' + coverageSummary(applicable) + ' Diagnosis and wrong/right examples for ' +
428
+ 'every invariant are served once, not repeated per element — call component_reference with ' +
429
+ '{ name: "invariants" }.',
430
+ );
431
+
432
+ for (const inv of applicable) {
433
+ const scope = scopeOf(inv);
434
+ lines.push('', `#### ${inv.id}${scope ? ` (${scope})` : ''} — ${coverageOf(inv)}`, inv.statement);
435
+ }
436
+ }
437
+
438
+ // No recipe, no section. An element that is in none gets its universal
439
+ // invariants and nothing else — a "part of: (none)" row would be a fabricated
440
+ // membership claim dressed as an empty one.
441
+ const recipes = recipesFor(tag);
442
+ if (recipes.length > 0) {
443
+ lines.push(
444
+ '',
445
+ '### Appears in surface recipes',
446
+ 'Compositions this element is part of, each with the whole ingredient list and the host ' +
447
+ 'wiring — nothing coordinates one element with another except your own code ' +
448
+ '(host-coordinates). The WHY behind each wiring edge, and the caveats on the nesting ' +
449
+ 'below, are served once rather than repeated per ingredient — call component_reference ' +
450
+ 'with { name: "recipes" }.',
451
+ );
452
+ for (const r of recipes) {
453
+ lines.push(
454
+ '',
455
+ `#### ${r.id} — ${r.intent}`,
456
+ `- **Ingredients:** ${r.ingredients.map((t) => `\`<${t}>\``).join(', ')}`,
457
+ `- **Delivery:** ${r.targets.join(', ')} · archetype: ${r.archetypes.join(', ')}`,
458
+ `- **Backend:** your own endpoint, read with \`${r.backend.reader}\` from \`@kitn.ai/ui/wire\``,
459
+ // WHERE the parts go. Printed per element and not only in the appendix,
460
+ // because this is the one fact a builder cannot infer from anything else
461
+ // on the page: the wiring rows say which event drives which property and
462
+ // are silent about nesting, so an element lookup that omitted this left
463
+ // the reader to guess between a child and a sibling. Short enough to
464
+ // repeat; the `note` (the WHY) stays in the appendix with the wiring notes.
465
+ ...compositionLines(r, ''),
466
+ // Bare ids, deliberately. This row is a DEPENDENCY list, not a coverage
467
+ // claim, and it can only ever be read a few lines below the full
468
+ // `### Invariants` section in the same response, where each of these ids
469
+ // already carries its own coverage line. Repeating the status here would
470
+ // print it a second (and, with two recipes, a third) time per element for
471
+ // no fact a reader does not already have on the page.
472
+ `- **Invariants it leans on:** ${r.invariants.join(', ')}`,
473
+ // Compact: the edge (event out of A, property into B) with no `note`.
474
+ // The note is the WHY — often a full sentence, sometimes several — and
475
+ // repeating it is the same shape of duplication task 4 removed from
476
+ // invariants: this recipe's ingredients (kai-chat, kai-conversations,
477
+ // kai-resizable, kai-artifact) all print this identical wiring list.
478
+ // `renderRecipeAppendix` carries the notes exactly once.
479
+ '- **Wiring** — event out of A, property into B, wired by the host:',
480
+ );
481
+ for (const w of r.wiring) {
482
+ lines.push(` - \`<${w.from}>\` fires \`${w.event}\` → host sets \`${w.to}.${w.property}\``);
483
+ }
484
+ }
485
+ }
486
+
487
+ return lines;
488
+ }
489
+
490
+ /**
491
+ * The long-form recipe reference, served exactly once rather than repeated on
492
+ * every ingredient. `catalogSectionLines` prints the ingredients, delivery,
493
+ * backend and a compact wiring list (edge only, no `note`) per element and
494
+ * points here for the rest — the WHY behind each wiring edge, which is the
495
+ * bulk: `workspace-chat` alone has 4 ingredients, and every one of them
496
+ * printed every wiring note in full before this moved. Reached via
497
+ * `component_reference({ name: "recipes" })`.
498
+ */
499
+ function renderRecipeAppendix(): string[] {
500
+ const lines: string[] = [
501
+ `## Surface recipe catalog (${surfaceRecipes.length} total) — wiring notes`,
502
+ '',
503
+ 'Every element lookup that appears in a recipe lists its ingredients, delivery, backend and ' +
504
+ 'a compact wiring list (event out of A, property into B). This is the long form: the WHY ' +
505
+ 'behind each wiring edge, written once here rather than repeated on every ingredient.',
506
+ ];
507
+
508
+ for (const r of surfaceRecipes) {
509
+ lines.push(
510
+ '',
511
+ `#### ${r.id} — ${r.intent}`,
512
+ `- **Ingredients:** ${r.ingredients.map((t) => `\`<${t}>\``).join(', ')}`,
513
+ `- **Delivery:** ${r.targets.join(', ')} · archetype: ${r.archetypes.join(', ')}`,
514
+ `- **Backend:** your own endpoint, read with \`${r.backend.reader}\` from \`@kitn.ai/ui/wire\``,
515
+ `- **Invariants it leans on:** ${r.invariants.join(', ')}`,
516
+ ...compositionLines(r, ' — '),
517
+ '- **Wiring** — event out of A, property into B, wired by the host:',
518
+ );
519
+ for (const w of r.wiring) {
520
+ lines.push(
521
+ ` - \`<${w.from}>\` fires \`${w.event}\` → host sets \`${w.to}.${w.property}\`` +
522
+ (w.note ? ` — ${w.note}` : ''),
523
+ );
524
+ }
525
+ }
526
+
527
+ return lines;
528
+ }
529
+
530
+ /**
531
+ * The long-form invariant reference, served exactly once rather than repeated
532
+ * on every element it applies to. `catalogSectionLines` prints only the id,
533
+ * scope and one-line statement per element and points here for the rest —
534
+ * this is that "rest": every record's full statement again for context, its
535
+ * diagnosis rows, and its wrong/right examples, each written once for the
536
+ * whole catalog regardless of how many of the 80 elements the record applies
537
+ * to. Reached via `component_reference({ name: "invariants" })`.
538
+ */
539
+ function renderInvariantAppendix(): string[] {
540
+ const lines: string[] = [
541
+ `## Invariant catalog (${invariants.length} total) — diagnosis and examples`,
542
+ '',
543
+ 'Every element lookup lists the invariants that apply to it by id and one-line statement. ' +
544
+ 'This is the long form: full statement, diagnosis and wrong/right examples for each record, ' +
545
+ 'written once here rather than repeated on every element it applies to.',
546
+ ];
547
+
548
+ for (const inv of invariants) {
549
+ const scope = scopeOf(inv);
550
+ lines.push('', `#### ${inv.id}${scope ? ` (${scope})` : ''} — ${coverageOf(inv)}`, inv.statement);
551
+ if (inv.diagnosis.length > 0) {
552
+ lines.push('', 'If you are debugging:');
553
+ for (const d of inv.diagnosis) lines.push(`- ${d.symptom} → ${d.cause}`);
554
+ }
555
+ lines.push(...exampleLines(inv.examples));
556
+ }
557
+
558
+ return lines;
559
+ }
560
+
561
+ // ─────────────────────────────────────────────────────────────────────────────
562
+ // The programmatic layer and the code recipes
563
+ // ─────────────────────────────────────────────────────────────────────────────
564
+
565
+ /** The topic names that all resolve to the programmatic-layer appendix. */
566
+ const PROGRAMMATIC_ALIASES = ['programmatic', 'state', 'wire', 'state-wire'] as const;
567
+
568
+ /**
569
+ * The `/state` + `/wire` appendix (rung-6 F-46): a marker-fenced section of the
570
+ * package-root `llms-full.txt`, which `build:api` DERIVES from the shipped
571
+ * `dist/state/*.d.ts` + `dist/wire/*.d.ts` (scripts/gen-llms-programmatic.mjs).
572
+ * Read, never restated: this tool restating one signature by hand is exactly
573
+ * the drift the generator exists to remove. The root copy is the CANONICAL and
574
+ * ONLY shipped copy (owner-ruled 2026-08-25): a second copy under `dist/llms/`
575
+ * used to ship too, ~293 KB of duplicate tarball weight — and it once went
576
+ * stale against the root while both claimed to be the artifact. It resolves
577
+ * relative to the manifest (`dist/custom-elements.json`), whose parent's
578
+ * parent is the package root in both contexts — bundled bin and source/vitest.
579
+ */
580
+ /**
581
+ * The fence gen-llms-programmatic.mjs writes around the section inside
582
+ * llms-full.txt. REGISTERED COPY of `PROGRAMMATIC_MARKERS` in that script —
583
+ * this TS module cannot import the generator .mjs. If either side moves, the
584
+ * slice below misses and the reference tests fail on the "Missing build
585
+ * artifact" branch, so the drift is loud.
586
+ */
587
+ const PROGRAMMATIC_START = '<!-- kai:programmatic:start -->';
588
+ const PROGRAMMATIC_END = '<!-- kai:programmatic:end -->';
589
+
590
+ function renderProgrammaticAppendix(): string {
591
+ // Sliced out of the SHIPPED llms-full.txt rather than served from a file of
592
+ // its own: a standalone copy was ~50 KB of duplicate tarball weight
593
+ // (verify:pack priced it), and slicing keeps one derivation with zero extra
594
+ // shipped bytes.
595
+ const path = join(dirname(resolveManifestPath()), '..', 'llms-full.txt');
596
+ const missing = (what: string) =>
597
+ `Missing build artifact: ${what}\n\n` +
598
+ 'The programmatic-layer reference is generated from the shipped dist/*.d.ts by the ' +
599
+ 'build (a marker-fenced section of the package-root llms-full.txt). Run `nx build ui` ' +
600
+ '(or `npm run build:api` in packages/ui) and ask again. It is deliberately not restated ' +
601
+ 'here: a hand-typed copy would drift from the declarations your editor shows.';
602
+ if (!existsSync(path)) return missing(path);
603
+ const full = readFileSync(path, 'utf-8');
604
+ const start = full.indexOf(PROGRAMMATIC_START);
605
+ const end = full.indexOf(PROGRAMMATIC_END);
606
+ if (start === -1 || end === -1 || end <= start) {
607
+ return missing(`the ${PROGRAMMATIC_START} section inside ${path}`);
608
+ }
609
+ return full.slice(start + PROGRAMMATIC_START.length, end).trim();
610
+ }
611
+
612
+ /**
613
+ * One code recipe as files a builder pastes. The catalog half (ingredients,
614
+ * wiring edges, invariants — each executed by surfaces.test.ts) is the surface
615
+ * recipe of the same id; this is the body a data record cannot carry, and
616
+ * `verify:scaffold` compiles every `lang: 'ts'` file of it.
617
+ */
618
+ function renderCodeRecipe(r: CodeRecipe): string {
619
+ const lines: string[] = [
620
+ `## Recipe: ${r.title} (\`${r.id}\`)`,
621
+ '',
622
+ r.intent,
623
+ '',
624
+ `**Elements composed:** ${r.ingredients.map((t) => `\`<${t}>\``).join(', ')}`,
625
+ '',
626
+ '**Read these before pasting:**',
627
+ ...r.notes.map((n) => `- ${n}`),
628
+ ];
629
+ for (const f of r.files) {
630
+ lines.push('', `### \`${f.path}\``, '', '```' + f.lang, f.code.trimEnd(), '```');
631
+ }
632
+ lines.push(
633
+ '',
634
+ 'The wiring topology, invariants and composition claims behind this recipe are the ' +
635
+ `surface recipe of the same id — call component_reference with { name: "recipes" }.`,
636
+ );
637
+ return lines.join('\n');
638
+ }
639
+
640
+ /**
641
+ * The payload out of `CustomEvent<T>`, or `undefined` when there is no payload.
642
+ *
643
+ * The manifest types every event, but as the wrapper — printing that raw teaches
644
+ * a reader to write `CustomEvent<...>` where a payload belongs. Anything that is
645
+ * not of the form `CustomEvent<…>` has NO payload to print, and this returns
646
+ * `undefined` so the caller omits the `detail` clause entirely.
647
+ *
648
+ * That is read off the generator rather than guessed at. gen-element-api.mjs
649
+ * writes the CEM type as ``CustomEvent<${e.detail}>`` when the element declares a
650
+ * detail and the bare string `CustomEvent` when it does not — exactly two shapes,
651
+ * and the bare one means the detail is `void` (e.g. `'kai-click': void` in
652
+ * button.tsx). Passing an unrecognised type through unchanged looked like a safe
653
+ * fallback for an already-unwrapped payload; what it actually caught was the void
654
+ * events, which then rendered ``Carries no detail. `detail`: `CustomEvent` `` — a
655
+ * line contradicting itself, on 13 events across 10 elements. The whole-manifest
656
+ * probe in reference.test.ts holds both directions of the rule.
657
+ */
658
+ function eventDetail(typeText: string | undefined): string | undefined {
659
+ const m = /^CustomEvent<([\s\S]*)>$/.exec(typeText?.trim() ?? '');
660
+ return m ? m[1].trim() || undefined : undefined;
661
+ }
662
+
228
663
  function formatReference(tag: string, provider: ToolProvider): string {
229
664
  const el = getElement(tag);
230
665
 
@@ -246,6 +681,66 @@ function formatReference(tag: string, provider: ToolProvider): string {
246
681
  lines.push('', el.description.trim());
247
682
  }
248
683
 
684
+ // ── Getting the element ────────────────────────────────────────────────────
685
+ // FIRST, above every other section. An element that never upgrades renders
686
+ // nothing and logs NOTHING: the property assigns and reads back fine, and
687
+ // whenDefined() never settles, so the listener is never attached. That symptom
688
+ // is also what props-not-attributes blames on a different cause, so a reader
689
+ // who has the invariants and not this line is steered to the wrong diagnosis.
690
+ const entry = entryForTag(tag);
691
+ const iface = el.name;
692
+ const neverUpgrades =
693
+ 'If you skip registering it the element never upgrades: nothing renders, ' +
694
+ '**no error and no warning is logged**, a property you set assigns and reads ' +
695
+ `back correctly, and \`customElements.whenDefined('${tag}')\` never resolves.`;
696
+ lines.push('', '### Getting the element');
697
+ if (entry) {
698
+ lines.push(
699
+ `Register it before you use it. ${neverUpgrades}`,
700
+ '',
701
+ '```ts',
702
+ "import '@kitn.ai/ui/elements';",
703
+ `import '@kitn.ai/ui/elements/${entry}'; // or just this one`,
704
+ '```',
705
+ );
706
+ } else {
707
+ // entryForTag is undefined exactly when register-impl.ts does not import this
708
+ // element's source file — i.e. it is NOT in the register-all bundle. The only
709
+ // current instance is kai-remote, a deliberate exception (opt-in cross-origin
710
+ // iframe card) documented at src/elements/element-diagnostics.ts:347-363 and
711
+ // vite.config.elements.ts:44-50. `import '@kitn.ai/ui/elements'` would NOT
712
+ // register a tag in this state, so asserting it here is exactly the false
713
+ // claim this section exists to prevent.
714
+ //
715
+ // The specifier is still NOT guessed — stripping `kai-` is wrong for ten of
716
+ // the eighty elements. `optInEntryForTag` reads it off the module the
717
+ // per-element build actually emitted, matched to this tag by the tag literal
718
+ // it registers; see the note there. Telling the reader to go look it up was
719
+ // the last place in this reference where "how to make the element exist" did
720
+ // not answer itself, and the answer was in the build config all along.
721
+ const optIn = optInEntryForTag(tag);
722
+ lines.push(
723
+ `**\`${tag}\` is opt-in — it is not part of \`import '@kitn.ai/ui/elements'\` ` +
724
+ '(register-all), and that import alone will NOT register it.** ' +
725
+ (optIn
726
+ ? `Import its own entry point instead. ${neverUpgrades}`
727
+ : // No built module claims this tag, so there is no specifier to name.
728
+ // Stay honest rather than inventing one.
729
+ 'Find its specific `@kitn.ai/ui/elements/<name>` entry point in the ' +
730
+ `package's published exports before using it. ${neverUpgrades}`),
731
+ );
732
+ if (optIn) {
733
+ lines.push('', '```ts', `import '@kitn.ai/ui/elements/${optIn}';`, '```');
734
+ }
735
+ }
736
+ if (iface) {
737
+ lines.push(
738
+ '',
739
+ `TypeScript: \`import type { ${iface} } from '@kitn.ai/ui/elements';\` — ` +
740
+ 'the element interface ships with the package; do not hand-roll a structural type.',
741
+ );
742
+ }
743
+
249
744
  // ── Contract note ──────────────────────────────────────────────────────────
250
745
  lines.push(
251
746
  '',
@@ -306,7 +801,12 @@ function formatReference(tag: string, provider: ToolProvider): string {
306
801
  lines.push('', '### Events (CustomEvent, listen via addEventListener)');
307
802
  for (const ev of events) {
308
803
  const desc = ev.description?.trim() ?? '';
309
- lines.push(`- **${ev.name}** — ${desc}`);
804
+ const detail = eventDetail(ev.type?.text);
805
+ lines.push(
806
+ detail
807
+ ? `- **${ev.name}** — ${desc} \`detail\`: \`${detail}\``
808
+ : `- **${ev.name}** — ${desc}`,
809
+ );
310
810
  }
311
811
  }
312
812
 
@@ -372,6 +872,9 @@ function formatReference(tag: string, provider: ToolProvider): string {
372
872
  }
373
873
  }
374
874
 
875
+ // ── The composition catalog ────────────────────────────────────────────────
876
+ lines.push(...catalogSectionLines(tag));
877
+
375
878
  return lines.join('\n');
376
879
  }
377
880
 
@@ -380,9 +883,24 @@ export const reference: Tool = {
380
883
  description:
381
884
  'Look up AI/UI (kai-*) web components: their tags, props, events, imperative methods, and usage examples. ' +
382
885
  'For a card-backed element it also returns the card\'s JSON Schema and a ready-to-send ' +
383
- 'tool definition generated from it — pass `provider` to get that provider\'s envelope.',
886
+ 'tool definition generated from it — pass `provider` to get that provider\'s envelope. ' +
887
+ 'Also serves the programmatic layer (name: "programmatic" — the @kitn.ai/ui/state + ' +
888
+ '@kitn.ai/ui/wire streaming/mock/encode API) and complete code recipes ' +
889
+ '(e.g. name: "composed-thread" — a hand-composed thread with no <kai-chat>).',
384
890
  inputSchema: z.object({
385
- name: z.string().optional(),
891
+ name: z
892
+ .string()
893
+ .optional()
894
+ .describe(
895
+ 'The element tag, e.g. "kai-chat". Omit it (or pass "list") to get the ' +
896
+ 'index of every element with a one-line summary, then ask again for the one you want. ' +
897
+ 'Pass "invariants" for the full diagnosis and wrong/right examples behind every ' +
898
+ 'invariant id an element lookup shows. Pass "recipes" for the full wiring notes ' +
899
+ 'behind every surface recipe an element lookup names. Pass "programmatic" (or ' +
900
+ '"state" / "wire") for the @kitn.ai/ui/state + @kitn.ai/ui/wire API — streaming ' +
901
+ 'folds, the mock responder, the SSE readers/encoders. Pass a code-recipe id ' +
902
+ '(e.g. "composed-thread") for a complete pasteable composition.',
903
+ ),
386
904
  provider: z
387
905
  .enum(PROVIDERS)
388
906
  .optional()
@@ -433,7 +951,26 @@ export const reference: Tool = {
433
951
  '\n\nCall component_reference with a specific name (e.g. { name: "kai-chat" }) for full API details.' +
434
952
  `\n\nCard-backed elements — ask for one of these to get its JSON Schema and a generated ` +
435
953
  `\`${KAI_TOOL_PREFIX}*\` tool definition:\n ${cardRows.join(', ')}` +
436
- `\nThe elements that HOST them (and carry the \`cardTypes\` / \`cardSchemas\` props): ${cardHostTags().join(', ')}`;
954
+ `\nThe elements that HOST them (and carry the \`cardTypes\` / \`cardSchemas\` props): ${cardHostTags().join(', ')}` +
955
+ `\n\nCall component_reference with { name: "invariants" } for the full diagnosis and ` +
956
+ 'wrong/right examples behind every invariant id shown on an element lookup.' +
957
+ `\n\nCall component_reference with { name: "recipes" } for the full wiring notes behind ` +
958
+ 'every surface recipe an element lookup names.' +
959
+ `\n\nCall component_reference with { name: "programmatic" } for the @kitn.ai/ui/state + ` +
960
+ '@kitn.ai/ui/wire API — createAssistantStream, the part folds, createMockResponder ' +
961
+ '(and its scripted tool calls), the SSE readers and the provider encoders. That layer ' +
962
+ 'is what a host wires when it composes elements by hand instead of using <kai-chat>.' +
963
+ `\n\nComplete pasteable compositions (code recipes): ${listCodeRecipes()
964
+ .map((r) => `{ name: "${r.id}" } — ${r.title}`)
965
+ .join('; ')}.`;
966
+ } else if (name === 'invariants') {
967
+ text = renderInvariantAppendix().join('\n');
968
+ } else if (name === 'recipes') {
969
+ text = renderRecipeAppendix().join('\n');
970
+ } else if ((PROGRAMMATIC_ALIASES as readonly string[]).includes(name)) {
971
+ text = renderProgrammaticAppendix();
972
+ } else if (getCodeRecipe(name)) {
973
+ text = renderCodeRecipe(getCodeRecipe(name)!);
437
974
  } else {
438
975
  text = formatReference(name, provider);
439
976
  }