@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
@@ -0,0 +1,168 @@
1
+ import { type JSX, For, Show, createEffect, splitProps } from 'solid-js';
2
+ import { ChevronDown } from 'lucide-solid';
3
+ import { cn } from '../utils/cn';
4
+ import { FIELD_BASE, FIELD_INVALID } from './input';
5
+
6
+ /** One choice in a {@link Select}. */
7
+ export interface SelectOption<T = string> {
8
+ /** The value this row selects. Compared to the select's `value` by identity. */
9
+ value: T;
10
+ /** Visible text. Defaults to `String(value)`. Native `<option>`s hold text, not markup. */
11
+ label?: string;
12
+ /** Disable this option alone (the select's `disabled` disables the whole control). */
13
+ disabled?: boolean;
14
+ }
15
+
16
+ export interface SelectProps<T = string>
17
+ extends Omit<JSX.SelectHTMLAttributes<HTMLSelectElement>, 'value' | 'children'> {
18
+ /**
19
+ * The choices, in display order. Rendered in full: the kit never truncates,
20
+ * re-orders or de-duplicates a consumer's option list.
21
+ *
22
+ * Omit it and pass `children` instead when you need `<optgroup>`s or anything else
23
+ * a flat list cannot express.
24
+ */
25
+ options?: readonly SelectOption<T>[];
26
+ /**
27
+ * The selected value, matched against each option's `value` by IDENTITY (so a
28
+ * numeric enum selects on the number, not on its string form). Pass an array for a
29
+ * `multiple` select.
30
+ */
31
+ value?: T | readonly T[];
32
+ /**
33
+ * Text for a leading, disabled, empty-valued option — the "nothing chosen yet" row.
34
+ * Omitted means no such row is rendered at all; there is no default placeholder,
35
+ * because inventing one would put words in the consumer's UI.
36
+ */
37
+ placeholder?: string;
38
+ /** Force the invalid (destructive-border) state. Matches `Input`'s. */
39
+ invalid?: boolean;
40
+ /** Raw `<option>` / `<optgroup>` children, for lists `options` cannot express.
41
+ * `value` still drives the selection when you use these: it is applied to the
42
+ * rendered options rather than quietly doing nothing. */
43
+ children?: JSX.Element;
44
+ /** Extra classes for the positioning wrapper that holds the chevron. */
45
+ containerClass?: string;
46
+ }
47
+
48
+ /**
49
+ * A select. A REAL native `<select>` behind `appearance: none`, in a box consistent
50
+ * with {@link Input}, with the kit's own chevron drawn over it.
51
+ *
52
+ * **Native, not a listbox, and that is the design.** A hand-built popup can be made to
53
+ * look identical and cannot be made to behave identically: the native control brings
54
+ * the platform picker on mobile, type-ahead on desktop, form participation, and the
55
+ * OS's own accessibility tree. This kit's control audit found every one of its
56
+ * accessibility defects in a control that had replaced a native element.
57
+ *
58
+ * The trade is that the *dropdown list itself* stays OS chrome — it renders outside the
59
+ * page and no stylesheet reaches it. What the kit can do is make it follow the kit's
60
+ * light/dark mode rather than the OS's, which `color-scheme` on the element host
61
+ * already does (`src/elements/styles.css`). Styling the closed control and leaving the
62
+ * open list to the platform is the whole of the bargain.
63
+ *
64
+ * Everything not listed in `SelectProps` is forwarded to the `<select>`, so `id`,
65
+ * `name`, `required`, `disabled`, `multiple`, `size`, `aria-*`, any `data-*` hook and
66
+ * the DOM events behave exactly as they do on a plain select. No validation is
67
+ * applied: `required` reaches the native attribute and stops there.
68
+ *
69
+ * ```tsx
70
+ * <Select
71
+ * options={[{ value: 'low' }, { value: 'high', label: 'High priority' }]}
72
+ * value={sev()}
73
+ * placeholder="Choose a severity…"
74
+ * onChange={(e) => setSev(e.currentTarget.value)}
75
+ * />
76
+ * ```
77
+ */
78
+ export function Select<T = string>(props: SelectProps<T>): JSX.Element {
79
+ const [local, rest] = splitProps(props, [
80
+ 'class', 'containerClass', 'options', 'value', 'placeholder', 'invalid', 'children', 'ref',
81
+ ]);
82
+
83
+ // A `multiple` select is a scrolling list box, not a closed control: there is no
84
+ // collapsed state for a chevron to point at, and `appearance: none` on one buys
85
+ // nothing. So the custom chrome applies to the single-value shape only.
86
+ const isMulti = () => !!rest.multiple;
87
+
88
+ const isSelected = (v: T): boolean => {
89
+ const sel = local.value;
90
+ if (Array.isArray(sel)) return (sel as readonly T[]).includes(v);
91
+ return sel === v;
92
+ };
93
+
94
+ // Nothing chosen yet, for deciding whether the placeholder row is the selected one.
95
+ // Array-aware on purpose: an empty array means nothing is selected, and without this
96
+ // branch the browser would fall through to auto-selecting the first NON-disabled
97
+ // option — i.e. showing a real choice while the caller's state said none was made.
98
+ const isEmpty = (): boolean => {
99
+ const v = local.value;
100
+ if (Array.isArray(v)) return v.length === 0;
101
+ return v === undefined || v === null || (v as unknown) === '';
102
+ };
103
+
104
+ return (
105
+ <div class={cn('relative block w-full', local.containerClass)}>
106
+ <select
107
+ {...rest}
108
+ ref={(el) => {
109
+ // `ref` is split out and re-applied by hand because this component needs the
110
+ // element itself for the `children` path below. Solid always hands a component
111
+ // a ref FUNCTION (a variable ref compiles into one), so the typeof guard is for
112
+ // the hand-written object case only.
113
+ const forward = local.ref;
114
+ if (typeof forward === 'function') (forward as (el: HTMLSelectElement) => void)(el);
115
+
116
+ // `value` drives the `options` list declaratively (each `<option selected>`),
117
+ // which cannot reach options the CALLER rendered as `children`. Applying it
118
+ // imperatively for that path is the difference between "children are an
119
+ // escape hatch" and "`value` silently does nothing once you use one".
120
+ createEffect(() => {
121
+ if (local.children === undefined) return;
122
+ const v = local.value;
123
+ if (v === undefined || v === null) return;
124
+ if (Array.isArray(v)) {
125
+ const wanted = new Set((v as readonly unknown[]).map(String));
126
+ for (const o of el.options) o.selected = wanted.has(o.value);
127
+ } else {
128
+ el.value = String(v);
129
+ }
130
+ });
131
+ }}
132
+ class={cn(
133
+ FIELD_BASE,
134
+ // `peer` so the chevron beside it can dim with the control.
135
+ 'peer',
136
+ // `pr-9` reserves the lane the chevron sits in, so a long option label never
137
+ // slides under it.
138
+ !isMulti() && 'cursor-pointer appearance-none pr-9',
139
+ local.invalid && FIELD_INVALID,
140
+ local.class,
141
+ )}
142
+ >
143
+ <Show when={local.placeholder !== undefined}>
144
+ <option value="" disabled selected={isEmpty()}>
145
+ {local.placeholder}
146
+ </option>
147
+ </Show>
148
+ <For each={local.options}>
149
+ {(opt) => (
150
+ <option value={String(opt.value)} disabled={opt.disabled} selected={isSelected(opt.value)}>
151
+ {opt.label ?? String(opt.value)}
152
+ </option>
153
+ )}
154
+ </For>
155
+ {local.children}
156
+ </select>
157
+ <Show when={!isMulti()}>
158
+ {/* `pointer-events-none` so the chevron is decoration and every click, including
159
+ one landing on the arrow, still opens the native picker. `aria-hidden`
160
+ because the select already announces itself as a combo box. */}
161
+ <ChevronDown
162
+ aria-hidden="true"
163
+ class="pointer-events-none absolute right-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground peer-disabled:opacity-50"
164
+ />
165
+ </Show>
166
+ </div>
167
+ );
168
+ }
@@ -0,0 +1,178 @@
1
+ import { type JSX, Show, splitProps, createSignal } from 'solid-js';
2
+ import { cn } from '../utils/cn';
3
+
4
+ export interface SliderProps
5
+ extends Omit<JSX.InputHTMLAttributes<HTMLInputElement>, 'type' | 'children' | 'min' | 'max' | 'step' | 'value'> {
6
+ /**
7
+ * Lowest selectable value. REQUIRED, and deliberately so.
8
+ *
9
+ * A range with no `min`/`max` is not a slider, it is a slider-shaped guess, and the
10
+ * guess belongs to whoever knows what the number means. `SliderWidget` reading a
11
+ * JSON-Schema field still defaults an absent `minimum` to 0 — that is the WIDGET's
12
+ * decision about a consumer-authored schema, and it stays there rather than being
13
+ * quietly adopted by every caller of this component.
14
+ */
15
+ min: number;
16
+ /** Highest selectable value. REQUIRED for the same reason as `min`. */
17
+ max: number;
18
+ /** Granularity. Omitted means the native default (1); `'any'` means continuous. */
19
+ step?: number | 'any';
20
+ /** The current value. Controlled — drive it from `onInput`. Omit for uncontrolled. */
21
+ value?: number;
22
+ /** Initial value when uncontrolled. */
23
+ defaultValue?: number;
24
+ /**
25
+ * Show the current value beside the track. Off by default.
26
+ *
27
+ * Two shapes, because one is not enough and three would be too many. `true` renders
28
+ * the raw number, which is what most sliders want. A FUNCTION renders whatever it
29
+ * returns, because plenty of sliders are not counting bare numbers: `60%`, `3 of 5`,
30
+ * `1m 30s`. A boolean alone cannot express those, and a formatter alone would make
31
+ * the common case read `valueLabel={(v) => v}`.
32
+ *
33
+ * The readout is `aria-hidden`. The input already reports the same number through
34
+ * `aria-valuenow` / `aria-valuetext`, so an exposed copy would be announced twice.
35
+ *
36
+ * NOTE ON STRUCTURE: with a readout the component renders a flex row around the
37
+ * input; without one it is still a bare `<input>` and nothing changes for existing
38
+ * callers. Toggling this at runtime therefore rebuilds the input element, which is
39
+ * fine for a control panel and not something a real app does mid-drag.
40
+ */
41
+ valueLabel?: boolean | ((value: number) => JSX.Element);
42
+ }
43
+
44
+ /**
45
+ * A slider. A REAL `<input type="range">` behind `appearance: none`, styled by the
46
+ * kit's `.kai-range` rule, never a `<div>` with a drag handler.
47
+ *
48
+ * The native control brings the whole keyboard contract (arrows, Home, End,
49
+ * PageUp/PageDown), pointer and touch dragging, form participation via `name`, and
50
+ * the `slider` role with a live value announcement — all of it for free and all of it
51
+ * correct. Every accessibility defect this kit's control audit found was in a control
52
+ * that had replaced the native element with something hand-rolled.
53
+ *
54
+ * What the component adds is the **filled track**. `.kai-range` paints the portion
55
+ * left of the thumb from a `--kai-range-fill` custom property, and until now every
56
+ * caller computed that percentage itself. It is arithmetic over `min`, `max` and the
57
+ * current value — three things this component already has — so no consumer should
58
+ * ever write it again.
59
+ *
60
+ * Everything not listed in `SliderProps` is forwarded to the input, so `id`, `name`,
61
+ * `disabled`, `required`, `aria-*` and any `data-*` hook behave exactly as they do on
62
+ * a plain `<input>`. No clamping and no validation is applied: a value outside
63
+ * `min`..`max` is the browser's business, not ours.
64
+ *
65
+ * ```tsx
66
+ * <Slider min={0} max={100} step={5} value={v()} onInput={(e) => setV(e.currentTarget.valueAsNumber)} />
67
+ * ```
68
+ */
69
+ export function Slider(props: SliderProps): JSX.Element {
70
+ const [local, rest] = splitProps(props, [
71
+ 'class', 'style', 'min', 'max', 'step', 'value', 'defaultValue', 'ref', 'valueLabel',
72
+ ]);
73
+
74
+ // The uncontrolled mirror. A slider's fill has to follow the thumb even when nobody
75
+ // is holding the value in a signal, so the component tracks the live value itself
76
+ // through a NATIVE `on:input` listener. That is `on:` and not `onInput` on purpose:
77
+ // `onInput` stays in `rest` and reaches the input untouched, so a caller's handler
78
+ // is neither wrapped nor swallowed, and the two listeners simply both run.
79
+ const [live, setLive] = createSignal<number | undefined>(props.defaultValue);
80
+
81
+ // HTML's own rule for a range with no value: the midpoint of the span. Restated here
82
+ // rather than left to the browser because the fill has to agree with the thumb on the
83
+ // very first paint, before any input event exists.
84
+ const current = () => local.value ?? live() ?? (local.min + local.max) / 2;
85
+
86
+ const fill = (): string => {
87
+ const lo = local.min;
88
+ const hi = local.max;
89
+ if (!(hi > lo)) return '0%';
90
+ // Clamp: a value outside the range is the caller's to fix, but a track painted
91
+ // 140% wide is a rendering artefact nobody asked for.
92
+ const pct = ((current() - lo) / (hi - lo)) * 100;
93
+ return `${Math.min(100, Math.max(0, pct))}%`;
94
+ };
95
+
96
+ // Merge rather than replace: `style` is a legitimate thing to pass a slider, and the
97
+ // fill is a custom property that has to survive alongside it. Solid accepts either a
98
+ // string or an object here, so both shapes are handled.
99
+ const style = (): string | JSX.CSSProperties => {
100
+ const s = local.style;
101
+ if (typeof s === 'string') return `${s.replace(/;\s*$/, '')};--kai-range-fill:${fill()}`;
102
+ return { ...(s ?? {}), '--kai-range-fill': fill() } as JSX.CSSProperties;
103
+ };
104
+
105
+ // CONTROLLED-MODE RECONCILIATION. A controlled `<input type="range">` in Solid can
106
+ // drift: the browser moves the thumb on a drag, and if the caller's `value` does not
107
+ // change in response, the bound expression is unchanged, so Solid never writes the
108
+ // DOM back. The thumb ends up somewhere the component's own state says it is not —
109
+ // and because the fill is derived from `value`, the two visibly DISAGREE. That is the
110
+ // exact symptom reported against the Storybook Playground: thumb slides, track does
111
+ // not. A pinned, writer-less `<Slider value={40} />` is a legitimate thing to render,
112
+ // and it should look pinned rather than half-moved.
113
+ //
114
+ // WHY A MICROTASK AND NOT THE HANDLER OR A BARE EFFECT. Both of those run too early
115
+ // and would break the ordinary controlled case. The `on:input` listener above is
116
+ // attached to the TARGET, so it runs before the caller's `onInput`, which Solid
117
+ // delegates at the document; snapping back there would hand the caller's handler a
118
+ // value we had already reset. A `createEffect` is flushed at the end of the update
119
+ // that `setLive` starts, which is still inside the target listener and therefore also
120
+ // before the delegated one. A microtask runs after the whole event turn: every input
121
+ // listener has run and any signal the caller set has propagated, so a value that
122
+ // still disagrees means the caller genuinely did not accept the edit.
123
+ let el: HTMLInputElement | undefined;
124
+ const reconcileControlled = () => {
125
+ const v = local.value;
126
+ // Uncontrolled: `live` is the truth and the DOM is already showing it.
127
+ if (v === undefined || el === undefined) return;
128
+ if (el.valueAsNumber !== v) el.value = String(v);
129
+ };
130
+
131
+ const readout = (): JSX.Element => {
132
+ const vl = local.valueLabel;
133
+ return typeof vl === 'function' ? vl(current()) : current();
134
+ };
135
+
136
+ const control = () => (
137
+ <input
138
+ {...rest}
139
+ type="range"
140
+ class={cn('kai-range', local.class)}
141
+ style={style()}
142
+ min={local.min}
143
+ max={local.max}
144
+ step={local.step}
145
+ value={local.value ?? live() ?? undefined}
146
+ ref={(node) => {
147
+ // `ref` is split out and re-applied by hand because this component needs the
148
+ // element for the reconciliation above. Solid always hands a component a ref
149
+ // FUNCTION (a variable ref compiles into one), so the typeof guard is for the
150
+ // hand-written object case only.
151
+ el = node;
152
+ const forward = local.ref;
153
+ if (typeof forward === 'function') (forward as (n: HTMLInputElement) => void)(node);
154
+ }}
155
+ on:input={(e) => {
156
+ setLive((e.currentTarget as HTMLInputElement).valueAsNumber);
157
+ queueMicrotask(reconcileControlled);
158
+ }}
159
+ />
160
+ );
161
+
162
+ return (
163
+ <Show when={local.valueLabel} fallback={control()}>
164
+ <div class="flex items-center gap-3">
165
+ {control()}
166
+ {/* aria-hidden: the input already announces this number. The readout is a
167
+ second copy for the eyes only, and exposing it would double the
168
+ announcement on every step of a drag. */}
169
+ <span
170
+ aria-hidden="true"
171
+ class="min-w-9 shrink-0 rounded-md bg-background px-2 py-1 text-center text-sm font-medium tabular-nums text-foreground shadow-sm"
172
+ >
173
+ {readout()}
174
+ </span>
175
+ </div>
176
+ </Show>
177
+ );
178
+ }
package/src/ui/switch.tsx CHANGED
@@ -1,7 +1,12 @@
1
- import { createSignal } from 'solid-js';
1
+ import { type JSX, createSignal, splitProps } from 'solid-js';
2
2
  import { cn } from '../utils/cn';
3
3
 
4
- export interface SwitchProps {
4
+ export interface SwitchProps
5
+ extends Omit<
6
+ JSX.ButtonHTMLAttributes<HTMLButtonElement>,
7
+ | 'type' | 'role' | 'aria-checked' | 'children' | 'ref'
8
+ | 'onChange' | 'onchange' | 'onClick' | 'onclick' | 'onKeyDown' | 'onkeydown'
9
+ > {
5
10
  /** Controlled checked state. When set, the component defers state to the
6
11
  * parent; drive it from `onChange`. Omit for uncontrolled (internal) state. */
7
12
  checked?: boolean;
@@ -26,51 +31,74 @@ export interface SwitchProps {
26
31
  /**
27
32
  * A toggle switch (`role="switch"`). Controlled via `checked`, or uncontrolled
28
33
  * from `defaultChecked`. Keyboard-operable (Space/Enter) and theme-tokened.
34
+ *
35
+ * Anything not named in `SwitchProps` is forwarded to the inner button, so `id`,
36
+ * `aria-required` / `aria-invalid` / `aria-describedby` and any `data-*` hook land
37
+ * on the focusable element without a caller stamping them through a `ref`. The
38
+ * switch keeps ownership of `type`, `role`, `aria-checked` and the toggle handlers:
39
+ * those are the control, not decoration.
29
40
  */
30
41
  export function Switch(props: SwitchProps) {
31
- const [internal, setInternal] = createSignal(props.defaultChecked ?? false);
32
- const isControlled = () => props.checked !== undefined;
33
- const isOn = () => (isControlled() ? !!props.checked : internal());
42
+ const [local, rest] = splitProps(props, [
43
+ 'checked', 'defaultChecked', 'disabled', 'label', 'name', 'value', 'onChange', 'buttonRef', 'class',
44
+ ]);
45
+ const [internal, setInternal] = createSignal(local.defaultChecked ?? false);
46
+ const isControlled = () => local.checked !== undefined;
47
+ const isOn = () => (isControlled() ? !!local.checked : internal());
34
48
 
35
49
  const toggle = () => {
36
- if (props.disabled) return;
50
+ if (local.disabled) return;
37
51
  const next = !isOn();
38
52
  if (!isControlled()) setInternal(next);
39
- props.onChange?.(next);
53
+ local.onChange?.(next);
40
54
  };
41
55
 
42
56
  return (
43
57
  <>
44
- {props.name != null && (
58
+ {local.name != null && (
45
59
  <input
46
60
  type="checkbox"
47
- name={props.name}
48
- value={props.value ?? 'on'}
61
+ name={local.name}
62
+ value={local.value ?? 'on'}
49
63
  checked={isOn()}
50
- disabled={props.disabled}
64
+ disabled={local.disabled}
51
65
  aria-hidden="true"
52
66
  tabindex={-1}
53
67
  style={{ position: 'absolute', width: '1px', height: '1px', overflow: 'hidden', clip: 'rect(0 0 0 0)', 'white-space': 'nowrap' }}
54
68
  onChange={() => { /* driven by the button; keep the input in sync only */ }}
55
69
  />
56
70
  )}
71
+ {/* `{...rest}` comes FIRST so the attributes below win: a caller can add an
72
+ `id` or an `aria-describedby`, but cannot turn this into something that is
73
+ no longer a switch. */}
57
74
  <button
75
+ {...rest}
58
76
  type="button"
59
77
  role="switch"
60
- ref={props.buttonRef}
78
+ ref={local.buttonRef}
61
79
  aria-checked={isOn()}
62
- aria-label={props.label}
63
- disabled={props.disabled}
80
+ aria-label={local.label}
81
+ disabled={local.disabled}
64
82
  onClick={toggle}
65
83
  onKeyDown={(e) => {
66
84
  if (e.key === ' ' || e.key === 'Enter') { e.preventDefault(); toggle(); }
67
85
  }}
68
86
  class={cn(
69
- 'relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full transition-colors',
87
+ 'relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border transition-colors',
70
88
  'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',
71
89
  'disabled:cursor-not-allowed disabled:opacity-50',
72
- isOn() ? 'bg-primary' : 'bg-muted',
73
- props.class,
90
+ // WCAG 2.1 SC 1.4.11: the track IS this control's visual boundary, so it
91
+ // needs 3:1 against the surface behind it. The OFF fill cannot carry that
92
+ // — `--color-muted` is a shared surface token (measured 1.10:1 light on
93
+ // `--color-background`) and darkening it to clear 3:1 would repaint every
94
+ // muted surface in the kit. So the boundary moves to a border on the
95
+ // control-edge token `--color-input`, which exists for exactly this and is
96
+ // already held to the 3:1 floor for radios, checkboxes and inputs
97
+ // (tests/primitives/control-contrast.test.ts). The ON track keeps its
98
+ // ~17:1 `--color-primary` fill and takes a transparent border purely so
99
+ // the two states stay the same size — the fill still paints under it.
100
+ isOn() ? 'border-transparent bg-primary' : 'border-input bg-muted',
101
+ local.class,
74
102
  )}
75
103
  >
76
104
  <span
@@ -79,7 +107,10 @@ export function Switch(props: SwitchProps) {
79
107
  // On the `primary` track use `primary-foreground` so the thumb stays
80
108
  // visible in both themes (in dark mode `primary` is light, where a
81
109
  // hard-coded white thumb vanished). Off-track stays white over `muted`.
82
- isOn() ? 'translate-x-[1.125rem] bg-primary-foreground' : 'translate-x-0.5 bg-white',
110
+ // The track is `border-box` with a 1px border, so the thumb travels
111
+ // inside a 34px box: 2px in from each inner edge keeps both end
112
+ // positions 3px from the track's outer edge.
113
+ isOn() ? 'translate-x-4 bg-primary-foreground' : 'translate-x-0.5 bg-white',
83
114
  )}
84
115
  />
85
116
  </button>
package/src/utils/cn.ts CHANGED
@@ -2,19 +2,25 @@ import { clsx, type ClassValue } from 'clsx';
2
2
  import { extendTailwindMerge } from 'tailwind-merge';
3
3
 
4
4
  // The kit defines custom font-size utilities via @theme tokens in theme.css:
5
- // text-caption / text-meta / text-body / text-title. tailwind-merge has no way
6
- // to know these are font sizes, so by default it buckets e.g. `text-body` with
7
- // text COLORS and drops a real color (`text-transparent`, `text-foreground`, …)
5
+ // text-micro / text-caption / text-meta / text-compact / text-body / text-title.
6
+ // tailwind-merge has no way to know these are font sizes, so by default it
7
+ // buckets `text-body` with text COLORS and drops a real color
8
+ // (`text-transparent`, `text-foreground`, …)
8
9
  // whenever both appear in the same cn() call — which silently broke TextShimmer
9
10
  // inside the web components (the element adds `text-body`, dropping
10
11
  // `text-transparent`, so the gradient stayed hidden behind opaque text).
11
12
  //
12
13
  // Register them in the `font-size` group so they conflict only with other font
13
- // sizes (text-xs/sm/base/lg/…) and never with text colors.
14
+ // sizes (text-xs/sm/base/lg/…) and never with text colors. Since theme.css now
15
+ // re-points Tailwind's own scale at the same tokens (text-xs ≡ text-meta,
16
+ // text-sm ≡ text-body, text-base ≡ text-title), the semantic name and its
17
+ // Tailwind alias are literally the same size — so they MUST land in one group
18
+ // or `cn('text-sm', 'text-body')` would emit two classes for one declaration.
19
+ // `text-lg` needs no entry: it is already a stock Tailwind font size.
14
20
  const twMerge = extendTailwindMerge({
15
21
  extend: {
16
22
  classGroups: {
17
- 'font-size': [{ text: ['caption', 'meta', 'body', 'title'] }],
23
+ 'font-size': [{ text: ['micro', 'caption', 'meta', 'compact', 'body', 'title'] }],
18
24
  },
19
25
  },
20
26
  });
package/src/wire/chunk.ts CHANGED
@@ -42,6 +42,21 @@ export interface ModelUsage {
42
42
 
43
43
  export interface ModelStreamChunk {
44
44
  text?: string;
45
+ /**
46
+ * The model id the RESPONSE stated, verbatim; REPORT, NEVER INFER.
47
+ *
48
+ * Read from the response rather than the request, which is what makes it work
49
+ * at all when the app builds its own fetch and the kit never sees what was
50
+ * asked for. Providers commonly resolve an alias (ask for `gpt-4o`, get
51
+ * `gpt-4o-2024-08-06`); through a gateway the value is the gateway's own id.
52
+ * Both are reasons to pass the string through untouched.
53
+ *
54
+ * It is NOT guaranteed. A proxy can strip or rewrite it and a custom endpoint
55
+ * may omit it, so a consumer renders it as ABSENT when it is absent. Filling
56
+ * the gap with the requested id would lie in exactly the requested-vs-served
57
+ * mismatch this field exists to catch.
58
+ */
59
+ model?: string;
45
60
  /**
46
61
  * Reasoning delta. `''` is MEANINGFUL, not a no-op: a redacted block has no
47
62
  * readable text but still carries a payload that must round-trip, and a format
@@ -170,6 +185,38 @@ export interface ModelTurn {
170
185
  export interface ConsumeOptions {
171
186
  /** Label for the reasoning disclosure. Defaults to 'Thinking'. */
172
187
  reasoningLabel?: string;
188
+ /**
189
+ * Correlates diagnostics and namespaces reasoning parts for this consume call;
190
+ * assigned automatically when absent.
191
+ *
192
+ * Supply one only to tie a read to an id you already hold. Two reads into the
193
+ * SAME sink must not share a value: the id is what keeps a second round's
194
+ * block 0 from merging into the first round's reasoning part.
195
+ */
196
+ streamId?: string;
197
+ /**
198
+ * The app's own grouping of several reads into ONE logical turn, carried onto
199
+ * every diagnostic event this read emits.
200
+ *
201
+ * THE KIT REPORTS WHAT THE APP DECLARES AND GROUPS NOTHING ON ITS OWN. A chat
202
+ * app running a tool loop, or fanning out to sub-agents, makes several model
203
+ * calls that belong to one turn; the kit sees one Response at a time and has
204
+ * no way to know which ones those are. So it does not guess:
205
+ *
206
+ * readOpenAIStream(res, sink, { traceId: 'turn-42', label: 'planner' })
207
+ *
208
+ * Absent when not supplied -- the key is not present on the events at all,
209
+ * rather than present and undefined. Purely diagnostic: nothing in the parse
210
+ * branches on it and it never reaches a provider.
211
+ */
212
+ traceId?: string;
213
+ /** The app's name for THIS read inside its trace (`'planner'`,
214
+ * `'executor'`, `'retry-2'`). Carried onto every diagnostic event, and
215
+ * absent when not supplied. Never derived from the format or the model.
216
+ *
217
+ * Not to be confused with `reasoningLabel`, which is UI copy for the
218
+ * reasoning disclosure; this one is never rendered to an end user. */
219
+ label?: string;
173
220
  /** Fires once per tool call the moment its arguments parse cleanly. This is
174
221
  * the hook a host's tool loop waits on. There is deliberately no
175
222
  * per-fragment callback: `ToolPart.rawInput` is written on every fragment,