@kitn.ai/ui 0.20.0 → 0.21.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 (500) hide show
  1. package/README.md +44 -45
  2. package/dist/components/artifact-card.d.ts +51 -0
  3. package/dist/components/artifact.d.ts +1 -1
  4. package/dist/components/attachments.d.ts +2 -2
  5. package/dist/components/audio-visualizer/index.d.ts +3 -3
  6. package/dist/components/audio-visualizer/labs/lab-choreography.d.ts +59 -0
  7. package/dist/components/audio-visualizer/labs/lab-shaders.d.ts +22 -0
  8. package/dist/components/audio-visualizer/labs/lab-visualizer.d.ts +18 -0
  9. package/dist/components/audio-visualizer/variant-aurora.d.ts +2 -2
  10. package/dist/components/audio-visualizer/variant-bar.d.ts +2 -2
  11. package/dist/components/audio-visualizer/variant-custom.d.ts +2 -2
  12. package/dist/components/audio-visualizer/variant-grid.d.ts +1 -1
  13. package/dist/components/audio-visualizer/variant-radial.d.ts +1 -1
  14. package/dist/components/audio-visualizer/variant-wave.d.ts +1 -1
  15. package/dist/components/card-fallback.d.ts +12 -2
  16. package/dist/components/card-renderer.d.ts +63 -2
  17. package/dist/components/chat-container.d.ts +3 -0
  18. package/dist/components/chat-scope-picker.d.ts +2 -2
  19. package/dist/components/chat-thread.d.ts +68 -18
  20. package/dist/components/choice-card.d.ts +3 -28
  21. package/dist/components/composer-dom.d.ts +1 -1
  22. package/dist/components/composer-highlight.d.ts +1 -1
  23. package/dist/components/composer-history.d.ts +1 -1
  24. package/dist/components/composer.d.ts +1 -1
  25. package/dist/components/confirm-card.d.ts +3 -18
  26. package/dist/components/context.d.ts +8 -4
  27. package/dist/components/conversation-item.d.ts +1 -1
  28. package/dist/components/conversation-list.d.ts +4 -3
  29. package/dist/components/embed.d.ts +3 -3
  30. package/dist/components/file-tree.d.ts +11 -22
  31. package/dist/components/form-widgets.d.ts +1 -1
  32. package/dist/components/form.d.ts +3 -44
  33. package/dist/components/link-preview.d.ts +3 -3
  34. package/dist/components/loader.d.ts +30 -48
  35. package/dist/components/message-skills.d.ts +4 -0
  36. package/dist/components/message.d.ts +84 -21
  37. package/dist/components/model-switcher.d.ts +2 -2
  38. package/dist/components/prompt-input.d.ts +2 -2
  39. package/dist/components/response-compare-types.d.ts +11 -2
  40. package/dist/components/response-compare.d.ts +3 -3
  41. package/dist/components/source.d.ts +12 -3
  42. package/dist/components/tasks-card.d.ts +3 -31
  43. package/dist/components/thread.d.ts +17 -5
  44. package/dist/components/toast.d.ts +2 -2
  45. package/dist/components/tool-classify.d.ts +8 -0
  46. package/dist/components/tool-types.d.ts +29 -1
  47. package/dist/components/tool.d.ts +3 -3
  48. package/dist/components/use-card-resolution.d.ts +1 -1
  49. package/dist/create-tween-D3Y5qiij.js +338 -0
  50. package/dist/create-tween-DGKY1FDY.js +341 -0
  51. package/dist/create-tween-paho5Rh-.js +7 -0
  52. package/dist/custom-elements.json +1681 -454
  53. package/dist/elements/agent-card.js +1 -1
  54. package/dist/elements/artifact.js +1 -1
  55. package/dist/elements/attachments.js +1 -1
  56. package/dist/elements/audio-visualizer.js +1 -1
  57. package/dist/elements/avatar.js +1 -1
  58. package/dist/elements/badge.js +1 -1
  59. package/dist/elements/button.js +1 -1
  60. package/dist/elements/card.js +1 -1
  61. package/dist/elements/cards.js +1 -1
  62. package/dist/elements/chain-of-thought.js +1 -1
  63. package/dist/elements/chat-scope-picker.js +1 -1
  64. package/dist/elements/chat-types.d.ts +70 -10
  65. package/dist/elements/chat-workspace.js +1 -1
  66. package/dist/elements/chat.js +1 -1
  67. package/dist/elements/checkpoint.js +1 -1
  68. package/dist/elements/choice.js +1 -1
  69. package/dist/elements/chunks/{Icon-Tj58ES_d.js → Icon-C-2LvGDG.js} +1 -1
  70. package/dist/elements/chunks/{action-icons-ns1Fnedj.js → action-icons-CaYoImEk.js} +1 -1
  71. package/dist/elements/chunks/arrow-left-Bb46H7w9.js +1 -0
  72. package/dist/elements/chunks/artifact-BBIscOxJ.js +1 -0
  73. package/dist/elements/chunks/{attachments-mCB5F1Fq.js → attachments-BB56zoji.js} +1 -1
  74. package/dist/elements/chunks/audio-visualizer-BxOx4THz.js +1 -0
  75. package/dist/elements/chunks/{badge-B4Zuajl2.js → badge-SxLSZ19R.js} +1 -1
  76. package/dist/elements/chunks/{button-ZWNif3--.js → button-CmkUkz6c.js} +1 -1
  77. package/dist/elements/chunks/card-renderer-Db4ffkWv.js +1 -0
  78. package/dist/elements/chunks/card-tags-D8lZ-C_U.js +1 -0
  79. package/dist/elements/chunks/chat-thread-B3Ks-cKr.js +1 -0
  80. package/dist/elements/chunks/check-C8desc_h.js +1 -0
  81. package/dist/elements/chunks/chevron-down-DKtc2HNB.js +1 -0
  82. package/dist/elements/chunks/chevron-right-Dw4GPhwL.js +1 -0
  83. package/dist/elements/chunks/choice-card-Q9cYYDyM.js +1 -0
  84. package/dist/elements/chunks/circle-BeokBsvB.js +1 -0
  85. package/dist/elements/chunks/circle-check-wJSqt859.js +1 -0
  86. package/dist/elements/chunks/{circle-x-B7faJFlY.js → circle-x-D0MEfxOM.js} +1 -1
  87. package/dist/elements/chunks/code-block-C8VzAraE.js +1 -0
  88. package/dist/elements/chunks/{collapsible-DM1Ckd4e.js → collapsible-Cvj61obE.js} +1 -1
  89. package/dist/elements/chunks/{composer-BguS0QL_.js → composer-D86ztyL0.js} +2 -2
  90. package/dist/elements/chunks/confirm-card-BdyDAGLw.js +1 -0
  91. package/dist/elements/chunks/context-WHDl-xSx.js +1 -0
  92. package/dist/elements/chunks/conversation-list-CdR14_Y4.js +1 -0
  93. package/dist/elements/chunks/create-tween-C_A_B638.js +7 -0
  94. package/dist/elements/chunks/{default-input-Cqqilg9t.js → default-input-CSZqUM81.js} +1 -1
  95. package/dist/elements/chunks/define-BzPnNsXg.js +1 -0
  96. package/dist/elements/chunks/{disclosure-CIZ5c8nO.js → disclosure-DVKsoc1F.js} +1 -1
  97. package/dist/elements/chunks/{download-Dsbg3ste.js → download-BjA54IMJ.js} +1 -1
  98. package/dist/elements/chunks/{dropdown-BDd1-Zgi.js → dropdown-BjVVHWXH.js} +1 -1
  99. package/dist/elements/chunks/{ellipsis-Dw6qrss-.js → ellipsis-BNedmqfi.js} +1 -1
  100. package/dist/elements/chunks/embed-DQsl4XEq.js +1 -0
  101. package/dist/elements/chunks/{external-link-Vt74zAoL.js → external-link-Di-dw2CU.js} +1 -1
  102. package/dist/elements/chunks/{file-text-CZrZF6_v.js → file-text-B3sAODCV.js} +1 -1
  103. package/dist/elements/chunks/{file-tree-DF4okKyo.js → file-tree-Dgto-bMn.js} +1 -1
  104. package/dist/elements/chunks/{folder-glP5rha4.js → folder-D6rMadFV.js} +1 -1
  105. package/dist/elements/chunks/form-CILxvhQ7.js +1 -0
  106. package/dist/elements/chunks/hover-card-BtiF4XiU.js +1 -0
  107. package/dist/elements/chunks/{icon-BLb8beoi.js → icon-DKkmze3y.js} +1 -1
  108. package/dist/elements/chunks/{info-CIsv92JK.js → info-CWRjZkuy.js} +1 -1
  109. package/dist/elements/chunks/{input-Dds1kFyt.js → input--QJBK6BA.js} +1 -1
  110. package/dist/elements/chunks/{kbd-De_xbgi9.js → kbd-C3zuKh8R.js} +1 -1
  111. package/dist/elements/chunks/{link-i4r_k7z4.js → link-BL5JA7Q0.js} +1 -1
  112. package/dist/elements/chunks/link-preview-CU37bbXh.js +1 -0
  113. package/dist/elements/chunks/{loader-BmQH4s3V.js → loader-XmpyxyRH.js} +1 -1
  114. package/dist/elements/chunks/{markdown-Zi21WhUz.js → markdown-3Gv5UZ_o.js} +1 -1
  115. package/dist/elements/chunks/message-CnBA2OUt.js +1 -0
  116. package/dist/elements/chunks/message-X5NZbq-W.js +1 -0
  117. package/dist/elements/chunks/message-square-CnpAm_P0.js +1 -0
  118. package/dist/elements/chunks/{minimize-2--ifeCGrl.js → minimize-2-DwyrUTcM.js} +1 -1
  119. package/dist/elements/chunks/{model-switcher-B94YAKsM.js → model-switcher-CclaJEHt.js} +1 -1
  120. package/dist/elements/chunks/{overlay-kD8dwRv_.js → overlay-Cepd-KcS.js} +1 -1
  121. package/dist/elements/chunks/{paperclip-q21dYOSK.js → paperclip-CdwKjrlu.js} +1 -1
  122. package/dist/elements/chunks/{progress-bar-BrAIIaaJ.js → progress-bar-DMVXBD3b.js} +1 -1
  123. package/dist/elements/chunks/{prompt-suggestion-Bjn2K-fR.js → prompt-suggestion-Di_WZE_5.js} +1 -1
  124. package/dist/elements/chunks/reasoning-D0jMch5u.js +1 -0
  125. package/dist/elements/chunks/{resizable-Dp4JExql.js → resizable-1znbL1Gv.js} +1 -1
  126. package/dist/elements/chunks/{rotate-cw-CFWWkpj2.js → rotate-cw-DVhhgx8n.js} +1 -1
  127. package/dist/elements/chunks/{scroll-area-Bb0kHH1j.js → scroll-area-Bs4bFS1P.js} +1 -1
  128. package/dist/elements/chunks/scroll-button-Bet5NLc4.js +1 -0
  129. package/dist/elements/chunks/{separator-9kRgr1X9.js → separator-C5Gh8qGC.js} +1 -1
  130. package/dist/elements/chunks/{settings-B8lmec4D.js → settings-5vmEFg0K.js} +1 -1
  131. package/dist/elements/chunks/{settings-group-I0hEuXiN.js → settings-group-BWLB38kz.js} +1 -1
  132. package/dist/elements/chunks/{share-C3lTiYGt.js → share-BZ3G_DaB.js} +1 -1
  133. package/dist/elements/chunks/skeleton-DafPJQTp.js +1 -0
  134. package/dist/elements/chunks/slots-CIw9RlAe.js +1 -0
  135. package/dist/elements/chunks/source-D_qj_6uJ.js +1 -0
  136. package/dist/elements/chunks/{star-CSJtGxgv.js → star-Cuv7j2IE.js} +1 -1
  137. package/dist/elements/chunks/{store-CHyW95TP.js → store-C1StPHfW.js} +1 -1
  138. package/dist/elements/chunks/tasks-card-EyoBZfpA.js +1 -0
  139. package/dist/elements/chunks/{text-shimmer-Cn9TmNpI.js → text-shimmer-D9gRSh34.js} +1 -1
  140. package/dist/elements/chunks/textarea-DuhtHfcm.js +1 -0
  141. package/dist/elements/chunks/{thumbs-up-PNVVThEF.js → thumbs-up-B9hwv43w.js} +1 -1
  142. package/dist/elements/chunks/{toast-store-DKbQn3Wn.js → toast-store-Bm3DUEDe.js} +1 -1
  143. package/dist/elements/chunks/{tool-DjTRpIpl.js → tool-CDtW7L0z.js} +1 -1
  144. package/dist/elements/chunks/tooltip-eB226mGK.js +1 -0
  145. package/dist/elements/chunks/{triangle-alert-DsHTHCPm.js → triangle-alert-C1SNzTqK.js} +1 -1
  146. package/dist/elements/chunks/use-card-resolution-YZh2MvI5.js +1 -0
  147. package/dist/elements/chunks/{variant-aurora-Dc4nQUia.js → variant-aurora-Cj1F7D0l.js} +2 -2
  148. package/dist/elements/chunks/{variant-custom-y_3kVQhS.js → variant-custom-T9gpt7QE.js} +1 -1
  149. package/dist/elements/chunks/{variant-wave-D5OR1-9Z.js → variant-wave-CxU9z-TE.js} +2 -2
  150. package/dist/elements/chunks/{video-B7vmenoC.js → video-CK4R7Rus.js} +1 -1
  151. package/dist/elements/chunks/x-D1qx0aLd.js +1 -0
  152. package/dist/elements/coachmark.js +1 -1
  153. package/dist/elements/code-block.js +1 -1
  154. package/dist/elements/command.js +1 -1
  155. package/dist/elements/compare.js +1 -1
  156. package/dist/elements/composer.js +1 -1
  157. package/dist/elements/confirm-card.js +1 -1
  158. package/dist/elements/context-meter.js +1 -1
  159. package/dist/elements/conversation-list.js +1 -1
  160. package/dist/elements/default-input.d.ts +7 -7
  161. package/dist/elements/define.d.ts +1 -0
  162. package/dist/elements/dialog.js +1 -1
  163. package/dist/elements/disclosure.d.ts +1 -1
  164. package/dist/elements/editable-label.js +1 -1
  165. package/dist/elements/element-data-types.d.ts +107 -0
  166. package/dist/elements/embed.js +1 -1
  167. package/dist/elements/empty.js +1 -1
  168. package/dist/elements/feedback-bar.js +1 -1
  169. package/dist/elements/file-tree.js +1 -1
  170. package/dist/elements/file-upload.js +1 -1
  171. package/dist/elements/form.js +1 -1
  172. package/dist/elements/hover-card.js +1 -1
  173. package/dist/elements/icon.js +1 -1
  174. package/dist/elements/image.js +1 -1
  175. package/dist/elements/input.js +1 -1
  176. package/dist/elements/kbd.js +1 -1
  177. package/dist/elements/link-preview.js +1 -1
  178. package/dist/elements/loader.js +1 -1
  179. package/dist/elements/markdown.js +1 -1
  180. package/dist/elements/menu.js +1 -1
  181. package/dist/elements/message-skills.js +1 -1
  182. package/dist/elements/message.js +1 -1
  183. package/dist/elements/model-switcher.js +1 -1
  184. package/dist/elements/nav.js +1 -1
  185. package/dist/elements/notice.js +1 -1
  186. package/dist/elements/pane-group.js +1 -1
  187. package/dist/elements/pane.js +1 -1
  188. package/dist/elements/popover.js +1 -1
  189. package/dist/elements/progress-bar.js +1 -1
  190. package/dist/elements/prompt-dock.js +1 -1
  191. package/dist/elements/prompt-input.js +1 -1
  192. package/dist/elements/prompt-suggestions.js +1 -1
  193. package/dist/elements/reasoning.js +1 -1
  194. package/dist/elements/register.d.ts +8 -6
  195. package/dist/elements/remote.js +1 -1
  196. package/dist/elements/resizable.js +1 -1
  197. package/dist/elements/response-stream.js +2 -2
  198. package/dist/elements/screen.js +1 -1
  199. package/dist/elements/scroll-area.js +1 -1
  200. package/dist/elements/scroll-button.js +1 -1
  201. package/dist/elements/search.js +1 -1
  202. package/dist/elements/segmented.js +1 -1
  203. package/dist/elements/separator.js +1 -1
  204. package/dist/elements/setting-item.js +1 -1
  205. package/dist/elements/settings-group.js +1 -1
  206. package/dist/elements/skeleton.js +1 -1
  207. package/dist/elements/slots.d.ts +16 -0
  208. package/dist/elements/source.js +1 -1
  209. package/dist/elements/status.js +1 -1
  210. package/dist/elements/switch.js +1 -1
  211. package/dist/elements/tabs.js +1 -1
  212. package/dist/elements/tasks.js +1 -1
  213. package/dist/elements/text-shimmer.js +1 -1
  214. package/dist/elements/thinking-bar.js +1 -1
  215. package/dist/elements/thread.js +1 -1
  216. package/dist/elements/toast.js +1 -1
  217. package/dist/elements/tool.js +1 -1
  218. package/dist/elements/tooltip.js +1 -1
  219. package/dist/elements/validate-messages.d.ts +25 -0
  220. package/dist/elements/voice-input.js +1 -1
  221. package/dist/elements/voice-output.js +1 -1
  222. package/dist/elements.d.ts +2725 -214
  223. package/dist/index.d.ts +163 -125
  224. package/dist/index.js +6336 -5802
  225. package/dist/index.server.d.ts +5 -0
  226. package/dist/index.server.js +16913 -0
  227. package/dist/kai-provider.es.d.ts +5 -0
  228. package/dist/kai-provider.es.js +79 -77
  229. package/dist/kai.es.d.ts +5 -0
  230. package/dist/kai.es.js +1 -1
  231. package/dist/llms/llms-full.txt +762 -148
  232. package/dist/llms/llms.txt +57 -5
  233. package/dist/mcp.es.js +4010 -770
  234. package/dist/primitives/card-component-types.d.ts +11 -0
  235. package/dist/primitives/card-data-types.d.ts +196 -0
  236. package/dist/primitives/card-host.d.ts +1 -1
  237. package/dist/primitives/card-recovery.d.ts +3 -3
  238. package/dist/primitives/card-registry.d.ts +4 -14
  239. package/dist/primitives/card-resolution.d.ts +1 -1
  240. package/dist/primitives/card-routing.d.ts +1 -1
  241. package/dist/primitives/card-tags.d.ts +11 -0
  242. package/dist/primitives/card-validate-cards.d.ts +57 -0
  243. package/dist/primitives/card-validate-generator.testlib.d.ts +20 -0
  244. package/dist/primitives/card-validate-schemas.d.ts +17 -0
  245. package/dist/primitives/card-validate.d.ts +24 -0
  246. package/dist/primitives/create-kai-chat.d.ts +3 -3
  247. package/dist/primitives/embed-providers.d.ts +1 -1
  248. package/dist/primitives/link-preview.d.ts +1 -1
  249. package/dist/primitives/message-feedback.d.ts +2 -2
  250. package/dist/primitives/toast-store.d.ts +1 -1
  251. package/dist/react/index.d.ts +717 -299
  252. package/dist/react/use-kai-chat.d.ts +8 -4
  253. package/dist/react.d.ts +5 -0
  254. package/dist/react.js +417 -316
  255. package/dist/register-impl-bzrZ44ft.js +145 -0
  256. package/dist/remote/host-embed.d.ts +1 -1
  257. package/dist/remote/index.d.ts +2 -2
  258. package/dist/remote/provider-runtime.d.ts +2 -2
  259. package/dist/remote/provider.d.ts +2 -2
  260. package/dist/remote/validate.d.ts +1 -1
  261. package/dist/remote/wire.d.ts +1 -1
  262. package/dist/schemas/artifact.schema.json +92 -0
  263. package/dist/schemas/embed.schema.json +0 -2
  264. package/dist/schemas/from-tool-call.d.ts +48 -0
  265. package/dist/schemas/index.d.ts +48 -0
  266. package/dist/schemas/link.schema.json +0 -2
  267. package/dist/schemas/provider-subsets.d.ts +136 -0
  268. package/dist/schemas/registry.d.ts +140 -0
  269. package/dist/schemas/tool-defs.d.ts +121 -0
  270. package/dist/schemas.d.ts +5 -0
  271. package/dist/schemas.js +717 -0
  272. package/dist/solid-BCJUQqwS.js +22750 -0
  273. package/dist/solid-BdENBcEq.js +20108 -0
  274. package/dist/solid.d.ts +66 -0
  275. package/dist/solid.js +261 -0
  276. package/dist/solid.server.d.ts +5 -0
  277. package/dist/solid.server.js +261 -0
  278. package/dist/state/index.d.ts +14 -4
  279. package/dist/state/messages.d.ts +8 -3
  280. package/dist/state/mock.d.ts +46 -0
  281. package/dist/state/parts.d.ts +85 -0
  282. package/dist/state/stream.d.ts +15 -9
  283. package/dist/state.d.ts +5 -0
  284. package/dist/state.js +253 -84
  285. package/dist/ui/action-icons.d.ts +1 -1
  286. package/dist/ui/collapsible.d.ts +11 -6
  287. package/dist/ui/dropdown.d.ts +47 -42
  288. package/dist/ui/pane-group.d.ts +1 -1
  289. package/dist/variant-aurora-1wMcXRUS.js +381 -0
  290. package/dist/variant-aurora-BKHHiOgL.js +391 -0
  291. package/dist/{variant-aurora-DVtGqVH6.js → variant-aurora-DOb_o4pC.js} +1 -1
  292. package/dist/{variant-custom-Dif-IV4u.js → variant-custom-CJGB0Kbw.js} +1 -1
  293. package/dist/variant-custom-Co0CkXJF.js +200 -0
  294. package/dist/variant-custom-DWSSgmd2.js +170 -0
  295. package/dist/variant-wave-C3-45cL6.js +218 -0
  296. package/dist/{variant-wave-DbfNdvSi.js → variant-wave-CEODq-9q.js} +1 -1
  297. package/dist/variant-wave-jdXBnCUZ.js +208 -0
  298. package/dist/wire/chunk.d.ts +171 -0
  299. package/dist/wire/consume.d.ts +26 -0
  300. package/dist/wire/encode.d.ts +148 -0
  301. package/dist/wire/formats/anthropic.d.ts +2 -0
  302. package/dist/wire/formats/openai.d.ts +5 -0
  303. package/dist/wire/index.d.ts +14 -0
  304. package/dist/wire/read.d.ts +26 -0
  305. package/dist/wire/sink-helpers.d.ts +21 -0
  306. package/dist/wire/sse.d.ts +33 -0
  307. package/dist/wire.d.ts +5 -53
  308. package/dist/wire.js +898 -0
  309. package/frameworks/react/index.tsx +183 -154
  310. package/frameworks/react/runtime.tsx +21 -1
  311. package/frameworks/react/use-kai-chat.tsx +11 -1
  312. package/llms-full.txt +762 -148
  313. package/llms.txt +57 -5
  314. package/package.json +65 -7
  315. package/src/agent-tooling/archetypes.ts +96 -0
  316. package/src/agent-tooling/integrations/anthropic.ts +412 -0
  317. package/src/agent-tooling/integrations/cloudflare.ts +136 -52
  318. package/src/agent-tooling/integrations/langgraph.ts +67 -13
  319. package/src/agent-tooling/integrations/mastra.ts +120 -12
  320. package/src/agent-tooling/integrations/mock.ts +43 -8
  321. package/src/agent-tooling/integrations/ollama.ts +61 -24
  322. package/src/agent-tooling/integrations/openai.ts +87 -0
  323. package/src/agent-tooling/integrations/openrouter.ts +56 -8
  324. package/src/agent-tooling/integrations/pi.ts +79 -23
  325. package/src/agent-tooling/integrations/pydantic-ai.ts +24 -2
  326. package/src/agent-tooling/integrations/vercel-ai-sdk.ts +84 -13
  327. package/src/agent-tooling/mcp/manifest.ts +206 -25
  328. package/src/agent-tooling/mcp/tools/debug.ts +13 -7
  329. package/src/agent-tooling/mcp/tools/reference.ts +285 -6
  330. package/src/agent-tooling/mcp/tools/scaffold.ts +3345 -675
  331. package/src/agent-tooling/registry.ts +17 -0
  332. package/src/agent-tooling/types.ts +229 -1
  333. package/src/components/artifact-card.tsx +120 -0
  334. package/src/components/audio-visualizer/index.tsx +9 -0
  335. package/src/components/audio-visualizer/labs/lab-choreography.ts +187 -0
  336. package/src/components/audio-visualizer/labs/lab-shaders.ts +363 -0
  337. package/src/components/audio-visualizer/labs/lab-visualizer.tsx +102 -0
  338. package/src/components/audio-visualizer/shader-canvas.tsx +31 -1
  339. package/src/components/card-fallback.tsx +42 -10
  340. package/src/components/card-renderer.tsx +146 -9
  341. package/src/components/chat-container.tsx +4 -0
  342. package/src/components/chat-thread.tsx +118 -51
  343. package/src/components/choice-card.tsx +17 -29
  344. package/src/components/composer.tsx +12 -2
  345. package/src/components/confirm-card.tsx +24 -20
  346. package/src/components/context.tsx +12 -4
  347. package/src/components/conversation-list.tsx +18 -2
  348. package/src/components/file-tree.tsx +11 -22
  349. package/src/components/file-upload.tsx +14 -8
  350. package/src/components/form.tsx +14 -47
  351. package/src/components/loader.tsx +39 -12
  352. package/src/components/message-skills.tsx +4 -0
  353. package/src/components/message.tsx +294 -46
  354. package/src/components/reasoning.tsx +92 -5
  355. package/src/components/response-compare-types.ts +25 -0
  356. package/src/components/response-compare.tsx +4 -9
  357. package/src/components/source.tsx +50 -24
  358. package/src/components/tasks-card.tsx +10 -33
  359. package/src/components/thread.tsx +84 -42
  360. package/src/components/toast.tsx +11 -5
  361. package/src/components/tool-classify.ts +26 -0
  362. package/src/components/tool-types.ts +31 -1
  363. package/src/elements/agent-card.tsx +11 -11
  364. package/src/elements/artifact.tsx +15 -7
  365. package/src/elements/attachments.tsx +6 -4
  366. package/src/elements/avatar.tsx +1 -1
  367. package/src/elements/button.tsx +3 -3
  368. package/src/elements/card.tsx +2 -2
  369. package/src/elements/cards.tsx +109 -14
  370. package/src/elements/chain-of-thought.tsx +14 -10
  371. package/src/elements/chat-scope-picker.tsx +9 -7
  372. package/src/elements/chat-types.ts +59 -6
  373. package/src/elements/chat-workspace.tsx +50 -9
  374. package/src/elements/chat.tsx +64 -3
  375. package/src/elements/choice.tsx +8 -8
  376. package/src/elements/coachmark.tsx +1 -1
  377. package/src/elements/command.tsx +8 -23
  378. package/src/elements/compare.tsx +7 -6
  379. package/src/elements/compiled.css +1 -1
  380. package/src/elements/composer.tsx +8 -8
  381. package/src/elements/confirm-card.tsx +9 -9
  382. package/src/elements/context-meter.tsx +4 -18
  383. package/src/elements/conversation-list.tsx +14 -9
  384. package/src/elements/default-input.tsx +3 -3
  385. package/src/elements/define.tsx +178 -43
  386. package/src/elements/editable-label.tsx +17 -2
  387. package/src/elements/element-data-types.ts +112 -0
  388. package/src/elements/element-meta.json +1596 -304
  389. package/src/elements/element-types.d.ts +2636 -211
  390. package/src/elements/feedback-bar.tsx +1 -1
  391. package/src/elements/file-tree.tsx +1 -1
  392. package/src/elements/file-upload.tsx +1 -1
  393. package/src/elements/form.tsx +14 -6
  394. package/src/elements/input.tsx +1 -1
  395. package/src/elements/kbd.tsx +1 -1
  396. package/src/elements/menu.tsx +10 -29
  397. package/src/elements/message-skills.tsx +7 -9
  398. package/src/elements/message.tsx +200 -32
  399. package/src/elements/model-switcher.tsx +5 -3
  400. package/src/elements/pane.tsx +1 -1
  401. package/src/elements/prompt-dock.tsx +8 -8
  402. package/src/elements/prompt-input.tsx +10 -10
  403. package/src/elements/prompt-suggestions.tsx +7 -4
  404. package/src/elements/reasoning.tsx +1 -1
  405. package/src/elements/register.ts +9 -0
  406. package/src/elements/resizable.globals.d.ts +36 -0
  407. package/src/elements/resizable.tsx +24 -13
  408. package/src/elements/response-stream.tsx +1 -1
  409. package/src/elements/scroll-button.tsx +1 -1
  410. package/src/elements/search.tsx +6 -1
  411. package/src/elements/segmented.tsx +5 -11
  412. package/src/elements/separator.tsx +1 -1
  413. package/src/elements/slots.ts +57 -24
  414. package/src/elements/source.tsx +21 -22
  415. package/src/elements/switch.tsx +3 -3
  416. package/src/elements/tasks.tsx +5 -4
  417. package/src/elements/thread.tsx +36 -4
  418. package/src/elements/toast.tsx +3 -2
  419. package/src/elements/tool.tsx +1 -1
  420. package/src/elements/validate-messages.ts +76 -0
  421. package/src/elements/voice-input.tsx +7 -7
  422. package/src/elements/voice-output.tsx +4 -4
  423. package/src/index.ts +141 -6
  424. package/src/primitives/card-component-types.ts +63 -0
  425. package/src/primitives/card-data-types.ts +312 -0
  426. package/src/primitives/card-recovery.ts +13 -2
  427. package/src/primitives/card-registry.tsx +34 -23
  428. package/src/primitives/card-schemas/artifact.schema.json +92 -0
  429. package/src/primitives/card-schemas/embed.schema.json +0 -2
  430. package/src/primitives/card-schemas/link.schema.json +0 -2
  431. package/src/primitives/card-tags.ts +61 -0
  432. package/src/primitives/card-validate-cards.ts +255 -0
  433. package/src/primitives/card-validate-generator.testlib.ts +38 -0
  434. package/src/primitives/card-validate-schemas.ts +58 -0
  435. package/src/primitives/card-validate.ts +48 -20
  436. package/src/primitives/create-tween.ts +54 -2
  437. package/src/primitives/message-feedback.ts +3 -2
  438. package/src/primitives/use-audio-analysis.ts +20 -1
  439. package/src/primitives/use-sequencer.ts +20 -1
  440. package/src/schemas/from-tool-call.ts +151 -0
  441. package/src/schemas/index.ts +340 -0
  442. package/src/schemas/provider-subsets.ts +538 -0
  443. package/src/schemas/registry.ts +355 -0
  444. package/src/schemas/tool-defs.ts +492 -0
  445. package/src/solid.ts +150 -0
  446. package/src/state/index.ts +27 -1
  447. package/src/state/messages.ts +21 -4
  448. package/src/state/mock.ts +211 -0
  449. package/src/state/parts.ts +295 -0
  450. package/src/state/stream.ts +56 -58
  451. package/src/ui/collapsible.tsx +17 -5
  452. package/src/ui/dropdown.tsx +46 -12
  453. package/src/ui/overlay.tsx +10 -4
  454. package/src/wire/chunk.ts +201 -0
  455. package/src/wire/consume.ts +440 -0
  456. package/src/wire/encode.ts +474 -0
  457. package/src/wire/formats/anthropic.ts +267 -0
  458. package/src/wire/formats/openai.ts +187 -0
  459. package/src/wire/index.ts +52 -0
  460. package/src/wire/read.ts +152 -0
  461. package/src/wire/sink-helpers.ts +50 -0
  462. package/src/wire/sse.ts +140 -0
  463. package/dist/create-tween-hvpmSuwW.js +0 -7
  464. package/dist/elements/chunks/arrow-left-DQocUFvy.js +0 -1
  465. package/dist/elements/chunks/audio-visualizer-BqNy7dfm.js +0 -1
  466. package/dist/elements/chunks/card-BkHbp4BA.js +0 -1
  467. package/dist/elements/chunks/chat-thread-CkRN6pZ7.js +0 -1
  468. package/dist/elements/chunks/check-B9-gn6SS.js +0 -1
  469. package/dist/elements/chunks/chevron-down-BNsxc2hk.js +0 -1
  470. package/dist/elements/chunks/chevron-right-Hv00StBO.js +0 -1
  471. package/dist/elements/chunks/circle-0e3KJTDr.js +0 -1
  472. package/dist/elements/chunks/circle-check-BNAS0JEy.js +0 -1
  473. package/dist/elements/chunks/code-block-BFUHn6Va.js +0 -1
  474. package/dist/elements/chunks/context-Cb7k4F-v.js +0 -1
  475. package/dist/elements/chunks/conversation-list-CvoAkWhN.js +0 -1
  476. package/dist/elements/chunks/create-tween-oVvAIG8r.js +0 -7
  477. package/dist/elements/chunks/define-D1din7Ld.js +0 -1
  478. package/dist/elements/chunks/hover-card-Cmm6Q53m.js +0 -1
  479. package/dist/elements/chunks/message-BqyXDN3-.js +0 -1
  480. package/dist/elements/chunks/message-feedback-Djr3z6Yb.js +0 -1
  481. package/dist/elements/chunks/message-square-vFAgbDaX.js +0 -1
  482. package/dist/elements/chunks/reasoning-DTpCGtnY.js +0 -1
  483. package/dist/elements/chunks/scroll-button-B0cH5fXf.js +0 -1
  484. package/dist/elements/chunks/skeleton-DSXW5Yya.js +0 -1
  485. package/dist/elements/chunks/slots--V19HwUb.js +0 -1
  486. package/dist/elements/chunks/textarea-CUwqAX0G.js +0 -1
  487. package/dist/elements/chunks/tooltip-CgBZCVKp.js +0 -1
  488. package/dist/elements/chunks/use-card-resolution-BSu_XHjH.js +0 -1
  489. package/dist/elements/chunks/x-GRUeeQFT.js +0 -1
  490. package/dist/host-embed.d.ts +0 -33
  491. package/dist/kai-provider.d.ts +0 -2
  492. package/dist/origin.d.ts +0 -5
  493. package/dist/provider-runtime.d.ts +0 -27
  494. package/dist/register-impl-DQyejdfb.js +0 -145
  495. package/dist/validate.d.ts +0 -4
  496. package/dist/version.d.ts +0 -4
  497. package/src/components/component-meta.json +0 -4550
  498. package/src/elements/card-media.jpg +0 -0
  499. package/src/elements/resizable.d.ts +0 -27
  500. package/src/elements/video-poster.jpg +0 -0
@@ -31,7 +31,7 @@ export function parseKaiTriggerItemElement(n: Element, char: string, kind: strin
31
31
  }
32
32
 
33
33
  interface Props extends Record<string, unknown> {
34
- /** Controlled value string or a full ComposerDoc (set as JS property). */
34
+ /** Controlled value: a string or a full ComposerDoc (set as JS property). */
35
35
  value?: string | ComposerDoc;
36
36
  /** Placeholder text shown when the composer is empty. */
37
37
  placeholder?: string;
@@ -43,9 +43,9 @@ interface Props extends Record<string, unknown> {
43
43
  maxHeight?: number | string;
44
44
  /** Whether pressing Enter (without Shift) submits. Default true. */
45
45
  submitOnEnter?: boolean;
46
- /** Trigger definitions set as a JS property. */
46
+ /** Trigger definitions. Set as a JS property. */
47
47
  triggers?: TriggerDef[];
48
- /** Keyword highlight rules set as a JS property. */
48
+ /** Keyword highlight rules. Set as a JS property. */
49
49
  highlights?: HighlightRule[];
50
50
  /** Default icon per entity kind (kind → image URL/data-URI) for items without
51
51
  * their own `icon`. Overrides the built-in agent/plugin glyphs. JS property. */
@@ -67,7 +67,7 @@ interface Events {
67
67
  /** The active trigger was dismissed (Escape, space, or outside click). */
68
68
  'kai-trigger-close': Record<string, never>;
69
69
  /** The composer gained focus. `focus`/`blur` are NOT composed natively, so they
70
- * don't escape the shadow root these re-expose them on the host. (For
70
+ * don't escape the shadow root; these re-expose them on the host. (For
71
71
  * `keydown`/`paste`/`focusin`/`focusout`, listen NATIVELY on `<kai-composer>`:
72
72
  * they're composed and already cross the shadow boundary.) */
73
73
  'kai-focus': { originalEvent: FocusEvent };
@@ -100,7 +100,7 @@ defineWebComponent<Props, Events>('kai-composer', {
100
100
  let controller: ComposerController | undefined;
101
101
  expose({
102
102
  /** Focus the editable element. `focus`/`blur` are NOT composed natively, so a
103
- * host-level focus() can't reach the editable inside the shadow root this is
103
+ * host-level focus() can't reach the editable inside the shadow root. This is
104
104
  * the only way to focus the composer programmatically. */
105
105
  focus: (options?: FocusOptions) => controller?.focus(options),
106
106
  /** Blur the editable element. */
@@ -108,9 +108,9 @@ defineWebComponent<Props, Events>('kai-composer', {
108
108
  /** Empty the composer to a blank doc (resets the internal value + history
109
109
  * baseline; fires kai-value-change). */
110
110
  clear: () => controller?.clear(),
111
- /** Submit the current content programmatically same path as Enter (fires
112
- * kai-submit). Named `send`, not `submit`, to match the shared vocabulary and
113
- * avoid any submit collision. */
111
+ /** Submit the current content programmatically, on the same path as Enter
112
+ * (fires kai-submit). Named `send`, not `submit`, to match the shared
113
+ * vocabulary and avoid any submit collision. */
114
114
  send: () => controller?.send(),
115
115
  /** Insert an atomic entity pill (skill/agent/plugin) at the caret without
116
116
  * typing a trigger (fires kai-entity-add). */
@@ -6,13 +6,13 @@ interface Props extends Record<string, unknown> {
6
6
  /** The confirm definition (the CardEnvelope.data). Set as a JS PROPERTY:
7
7
  * `el.data = { body, tone, actions:[…] }`. Import `ConfirmCardData` from
8
8
  * `@kitn.ai/ui` for the full shape. */
9
- data?: Record<string, unknown>;
9
+ data?: ConfirmCardData;
10
10
  /** Stable card id correlating every emitted CardEvent. Attribute: `card-id`. */
11
11
  cardId?: string;
12
12
  /** Heading rendered in the card chrome (= CardEnvelope.title). Attribute: `heading`. */
13
13
  heading?: string;
14
- /** Focus the default action on mount (off by default no focus-stealing).
15
- * Attribute: `autofocus`. */
14
+ /** Focus the default action on mount (off by default, so nothing steals
15
+ * focus). Attribute: `autofocus`. */
16
16
  autofocus?: boolean;
17
17
  /** Set when the user resolved this card; renders the read-only view. Property:
18
18
  * `el.resolution = { kind:'action', action:'…' }`. */
@@ -48,22 +48,22 @@ defineWebComponent<Props>(
48
48
  // `dismiss`/`reopen`).
49
49
  let controller: ConfirmController | undefined;
50
50
  expose({
51
- /** Focus the default action button (or the first action if none is default)
52
- * the same target `autofocus` focuses on mount, but on demand. */
51
+ /** Focus the default action button (or the first action if none is default).
52
+ * The same target `autofocus` focuses on mount, but on demand. */
53
53
  focus: (options?: FocusOptions) => controller?.focus(options),
54
- /** Activate an action by id emits the `action` verb on kai-card and resolves
54
+ /** Activate an action by id: emits the `action` verb on kai-card and resolves
55
55
  * the card (single-shot). With no id, invokes the default action. */
56
56
  confirm: (actionId?: string) => controller?.confirm(actionId),
57
- /** Trigger the dismiss path emits `dismiss` on kai-card and optimistically
57
+ /** Trigger the dismiss path: emits `dismiss` on kai-card and optimistically
58
58
  * collapses the card to its re-openable stub. */
59
59
  dismiss: () => controller?.dismiss(),
60
- /** Re-open a dismissed card from its stub emits `reopen` on kai-card. */
60
+ /** Re-open a dismissed card from its stub: emits `reopen` on kai-card. */
61
61
  reopen: () => controller?.reopen(),
62
62
  });
63
63
 
64
64
  return (
65
65
  <ConfirmCard
66
- data={props.data as ConfirmCardData | undefined}
66
+ data={props.data}
67
67
  cardId={props.cardId ?? (element.id || 'kai-confirm')}
68
68
  heading={props.heading}
69
69
  autofocus={flag('autofocus')}
@@ -16,27 +16,13 @@ import {
16
16
  DEFAULT_DANGER_THRESHOLD,
17
17
  type ContextSeverity,
18
18
  } from '../components/context';
19
-
20
- interface ContextUsage {
21
- /** Tokens consumed so far in the context window (drives the meter fill). */
22
- usedTokens: number;
23
- /** The model's total context-window size in tokens. */
24
- maxTokens: number;
25
- /** Tokens attributed to the prompt/input, shown in the breakdown. */
26
- inputTokens?: number;
27
- /** Tokens attributed to the generated output, shown in the breakdown. */
28
- outputTokens?: number;
29
- /** Tokens attributed to reasoning/thinking, shown when present. */
30
- reasoningTokens?: number;
31
- /** Tokens served from prompt cache, shown when present. */
32
- cacheTokens?: number;
33
- /** Estimated cost in dollars for this usage, shown in the footer. */
34
- estimatedCost?: number;
35
- }
19
+ // Public shape of the `context` prop; lives in ./element-data-types so the ROOT
20
+ // entry can re-export it (see that file's header).
21
+ import type { KaiContextUsage } from './element-data-types';
36
22
 
37
23
  interface Props extends Record<string, unknown> {
38
24
  /** Token-usage data. Set as a JS property. */
39
- context?: ContextUsage;
25
+ context?: KaiContextUsage;
40
26
  /**
41
27
  * Fraction (0–1) above which the meter turns yellow.
42
28
  * Defaults to `0.7` (70%).
@@ -6,13 +6,18 @@ import { ConversationList, CollapsedRail, type ConversationListController } from
6
6
  import type { ConversationGroup, ConversationSummary, ConversationScope } from '../types';
7
7
 
8
8
  interface Props extends Record<string, unknown> {
9
- /** Pre-bucketed conversation groups (e.g. "Today", "Yesterday"), each with its
10
- * own conversations. Use this when you want to control the grouping/headers
11
- * yourself; otherwise pass a flat `conversations` array. Set as a JS property. */
12
- groups: ConversationGroup[];
13
- /** A flat list of conversation summaries; the component buckets them by recency
14
- * for you. Ignored when `groups` is provided. Set as a JS property. */
15
- conversations: ConversationSummary[];
9
+ /** The list's section headers (`{ id, name, sortOrder, createdAt }`), rendered
10
+ * in array order. A group carries no conversations of its own; it is matched
11
+ * against `conversations` by id, so the two props are complementary rather
12
+ * than alternatives. Omit for an ungrouped list. Set as a JS property. */
13
+ groups?: ConversationGroup[];
14
+ /** Every conversation the list renders, flat. Each one is filed under the group
15
+ * whose `id` equals its `groupId`; one with no `groupId`, or with a `groupId`
16
+ * matching no entry in `groups`, falls into a trailing "Ungrouped" section, so
17
+ * nothing you pass in is ever dropped. There is no recency bucketing. Set as a
18
+ * JS property. Omit to supply them as `<kai-conversation>` light-DOM children
19
+ * instead, or for the empty state. */
20
+ conversations?: ConversationSummary[];
16
21
  /** The id of the currently-open conversation, highlighted in the list. */
17
22
  activeId?: string;
18
23
  /** Controlled collapsed state. Set as a JS property (`el.collapsed = true`) to
@@ -115,7 +120,7 @@ defineWebComponent<Props, Events>('kai-conversations', {
115
120
  /** Clear the internal search query (resets the list filter) and fire
116
121
  * kai-search with an empty string. */
117
122
  clear: () => controller?.clearSearch(),
118
- /** Programmatically select a conversation by id mirror of the
123
+ /** Programmatically select a conversation by id. The mirror of the
119
124
  * kai-conversation-select event (a convenience over driving `activeId`). */
120
125
  select: (id: string) => dispatch('kai-conversation-select', { id }),
121
126
  /** Collapse the rail to its floating reopen button (fires `kai-collapse-toggle`). */
@@ -132,7 +137,7 @@ defineWebComponent<Props, Events>('kai-conversations', {
132
137
  fallback={<CollapsedRail onExpand={() => setCollapsedTo(false)} />}
133
138
  >
134
139
  <ConversationList
135
- groups={props.groups}
140
+ groups={props.groups ?? []}
136
141
  conversations={allConversations()}
137
142
  activeId={props.activeId}
138
143
  onSelect={(id) => dispatch('kai-conversation-select', { id })}
@@ -36,9 +36,9 @@ export interface DefaultPromptInputProps {
36
36
  /** Show a Voice (Mic) button in the left toolbar; calls `onVoice`. */
37
37
  voice?: boolean;
38
38
  /** Send-button visibility. `'always'` (default) always shows it; `'auto'` shows
39
- * it only when there's text/attachments (an empty composer hides it — Enter
40
- * still submits). To hide it entirely (Enter-only), it's pure CSS:
41
- * `::part(send){display:none}` no prop needed. Restyle via `::part(send)`.
39
+ * it only when there's text/attachments (an empty composer hides it, though
40
+ * Enter still submits). To hide it entirely (Enter-only), it's pure CSS:
41
+ * `::part(send){display:none}`, no prop needed. Restyle via `::part(send)`.
42
42
  * The Stop button (stoppable + loading) is unaffected. */
43
43
  submit?: 'always' | 'auto';
44
44
  onValueChange: (v: string) => void;
@@ -96,6 +96,147 @@ function toAttr(name: string): string {
96
96
  return name.replace(/([A-Z])/g, '-$1').toLowerCase();
97
97
  }
98
98
 
99
+ /**
100
+ * Every property name the built-in element prototype chain exposes as an ACCESSOR
101
+ * — `role`, `hidden`, `autofocus`, `dir`, `title`, `className`, … — i.e. the
102
+ * reflected IDL attributes plus the handful of read-only accessors. Methods
103
+ * (`focus`, `append`) are plain data properties and are deliberately not included:
104
+ * assigning over one shadows it on the instance but destroys nothing on the DOM.
105
+ *
106
+ * DERIVED, not listed. A hand-written list is a list someone has to remember to
107
+ * extend: the collision set is (this element's prop names) × (whatever the browser
108
+ * reflects), and both sides move — the kit adds props, and the platform keeps
109
+ * adding globals (`inert`, `popover`, `writingSuggestions` are all recent). Reading
110
+ * it off the live prototype chain means a prop that starts colliding tomorrow is
111
+ * protected the day it lands, in whichever engines have shipped the accessor,
112
+ * without a code change. It also self-limits: in an engine that has NOT shipped a
113
+ * given accessor (jsdom has no `autofocus`) the name is simply not a collision
114
+ * there, which is exactly right.
115
+ *
116
+ * Computed once — the chain does not change at runtime.
117
+ */
118
+ let globalAccessorNames: Set<string> | undefined;
119
+ export function reflectedGlobalPropNames(): Set<string> {
120
+ if (globalAccessorNames) return globalAccessorNames;
121
+ const names = new Set<string>();
122
+ let proto: object | null =
123
+ typeof HTMLElement === 'undefined' ? null : (HTMLElement.prototype as object);
124
+ while (proto && proto !== Object.prototype) {
125
+ for (const [name, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(proto))) {
126
+ if (descriptor.get || descriptor.set) names.add(name);
127
+ }
128
+ proto = Object.getPrototypeOf(proto) as object | null;
129
+ }
130
+ globalAccessorNames = names;
131
+ return names;
132
+ }
133
+
134
+ /**
135
+ * Replace inherited reflected accessors with plain, non-reflecting per-instance
136
+ * stores on this element class's prototype. Setting the property then only STORES
137
+ * the value — component-register still reads it back to seed the styling prop, and
138
+ * later shadows this with its own (also non-reflecting) instance accessor — and it
139
+ * can never touch a host attribute.
140
+ */
141
+ function installNonReflectingProps(proto: object, keys: readonly string[]): void {
142
+ for (const key of keys) {
143
+ const store = Symbol(`kai-prop:${key}`);
144
+ Object.defineProperty(proto, key, {
145
+ get(this: Record<symbol, unknown>) {
146
+ return this[store];
147
+ },
148
+ set(this: Record<symbol, unknown>, value: unknown) {
149
+ this[store] = value;
150
+ },
151
+ enumerable: true,
152
+ configurable: true,
153
+ });
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Run `define` (solid-element's `customElement`, which calls
159
+ * `customElements.define` internally) with `keys` already shadowed on the element
160
+ * class — BEFORE the registry ever sees it.
161
+ *
162
+ * THE ORDER IS THE WHOLE POINT. `customElements.define()` synchronously upgrades
163
+ * every matching element the parser has already produced, and component-register's
164
+ * constructor runs `this[prop] = undefined` for every declared prop. If the
165
+ * non-reflecting accessor is installed AFTER the define call, that assignment lands
166
+ * on the NATIVE setter, which for a reflected IDL attribute means the author's
167
+ * markup is destroyed before a line of facade code runs — `undefined` coerces to
168
+ * `null`/`false` and the setter removes the attribute. Measured in chromium from
169
+ * parsed HTML (`node scripts/probe-upgrade-attribute-loss.mjs`):
170
+ *
171
+ * <kai-message role="user"> → role attr gone, el.role "assistant",
172
+ * the row renders as "Assistant message"
173
+ * <kai-resizable-item hidden> → hidden attr gone, el.hidden false, the
174
+ * panel is slotted and RENDERS VISIBLE
175
+ * <kai-confirm autofocus> → autofocus attr gone, nothing focused
176
+ *
177
+ * Two of those are silent: `hidden` and `autofocus` are legitimate global
178
+ * attributes, so no a11y rule and no console warning fires — the value simply
179
+ * evaporates. Only `role` was loud enough to get noticed.
180
+ *
181
+ * WHY A TRANSIENT REGISTRY WRAP and not something tidier: the class does not exist
182
+ * until `register()` builds it, and `register()` defines it in the same statement.
183
+ * component-register can take a `BaseElement` (a prototype we control) or a
184
+ * `customElements`-alike (a registry we control) via its third argument — either
185
+ * would be cleaner — but solid-element's `customElement()` calls `register(tag,
186
+ * props)` with no options and forwards nothing, and `component-register` is not a
187
+ * declared dependency of this package, so reaching past solid-element to call
188
+ * `register` ourselves would ship an undeclared import to consumers. Intercepting
189
+ * the one `define` call is the smallest seam that exists.
190
+ *
191
+ * The wrap is synchronous, restored in a `finally`, delegates to whatever was
192
+ * installed (so a polyfilled or consumer-wrapped registry keeps working), acts only
193
+ * on OUR tag, and is re-entrancy safe: a facade that defines another element during
194
+ * its upgrade nests a second wrap and unwinds it in order.
195
+ */
196
+ function defineWithNonReflectingProps<T>(
197
+ tag: string,
198
+ keys: readonly string[],
199
+ define: () => T,
200
+ ): { result: T; handled: boolean } {
201
+ // `handled` = nothing more for the caller to do. With no colliding props there is
202
+ // nothing to install at all, so that case is trivially handled.
203
+ if (keys.length === 0) return { result: define(), handled: true };
204
+ const registry = customElements;
205
+ const hadOwnDefine = Object.prototype.hasOwnProperty.call(registry, 'define');
206
+ const inner = registry.define;
207
+ let handled = false;
208
+ let restore: (() => void) | undefined;
209
+ try {
210
+ registry.define = function (
211
+ this: CustomElementRegistry,
212
+ name: string,
213
+ constructor: CustomElementConstructor,
214
+ options?: ElementDefinitionOptions,
215
+ ) {
216
+ if (name === tag) {
217
+ installNonReflectingProps(constructor.prototype, keys);
218
+ handled = true;
219
+ }
220
+ return inner.call(this, name, constructor, options);
221
+ };
222
+ restore = () => {
223
+ if (hadOwnDefine) registry.define = inner;
224
+ else delete (registry as unknown as Record<string, unknown>).define;
225
+ };
226
+ } catch {
227
+ // A frozen registry (SES lockdown, a sealed polyfill, a hardened extension
228
+ // page): we cannot get ahead of define() there. Leave `handled` false so the
229
+ // caller installs on the returned class instead — the OLD, too-late timing, but
230
+ // registration itself still succeeds. Getting this wrong the other way would
231
+ // take all 80 elements down in that environment to fix three props in it.
232
+ }
233
+ try {
234
+ return { result: define(), handled };
235
+ } finally {
236
+ restore?.();
237
+ }
238
+ }
239
+
99
240
  /** Underlying flag resolution; see `WebComponentContext.flag`. */
100
241
  function resolveFlag(element: HTMLElement, value: unknown, attribute: string): boolean {
101
242
  if (value === true) return true;
@@ -148,27 +289,33 @@ export function defineWebComponent<P extends Record<string, unknown>, E = Record
148
289
  }
149
290
  }
150
291
 
151
- // Props that NAME a reflected global IDL accessor (today: only `role`, from
152
- // ARIAMixin's Element.prototype.role). Unlike RESERVED (which throws), these are
153
- // allowed as plain styling props, but they must NEVER reach the host as an
154
- // attribute: kai-message uses role='user'|'assistant' to pick its layout, and
155
- // those are not valid ARIA roles, so a reflected role="user" / role="assistant"
156
- // fails axe's aria-roles rule. The native IDL setter reflects to an attribute
157
- // whenever the property is set BEFORE connectedCallback (e.g. in a framework
158
- // `ref`: `el.role = 'user'`), which is the window before component-register
159
- // installs its own (non-reflecting) per-instance accessor in initializeProps. We
160
- // shadow the native accessor on the element prototype with a plain non-reflecting
161
- // one, so setting the property only STORES the value (component-register still
162
- // reads it back for styling) and never touches a host attribute.
163
- const NON_REFLECTING = ['role'];
292
+ // Every element gets a `theme` property/attribute. It drives a `.dark` class on
293
+ // an inner wrapper, which the injected kit CSS already styles — so dark mode
294
+ // works in standalone Shadow-DOM usage with no token duplication.
295
+ //
296
+ // The `as` annotation is load-bearing, not decoration: scripts/gen-element-api.mjs
297
+ // reads THIS object literal to learn which props every element gets for free, and
298
+ // takes each one's type and doc comment off the checker. Without it the inferred
299
+ // type is the literal `"auto"`. Add a universal prop here and it appears in
300
+ // element-meta.json, the generated .d.ts, custom-elements.json and llms-full.txt
301
+ // for all 79 elements, with no second list to update.
302
+ const defaults = {
303
+ /** Color mode (`auto` follows prefers-color-scheme). */
304
+ theme: 'auto' as 'light' | 'dark' | 'auto',
305
+ ...propDefaults,
306
+ };
164
307
 
165
- // Every element gets a `theme` property/attribute: 'light' | 'dark' | 'auto'
166
- // (default 'auto' = follow the OS `prefers-color-scheme`). It drives a `.dark`
167
- // class on an inner wrapper, which the injected kit CSS already styles — so dark
168
- // mode works in standalone Shadow-DOM usage with no token duplication.
169
- const defaults = { theme: 'auto', ...propDefaults };
308
+ // Props that NAME a reflected global IDL accessor (today, across all 80 elements:
309
+ // `role` on kai-message, `hidden` on kai-resizable-item, `autofocus` on
310
+ // kai-confirm). Unlike RESERVED (which throws), these are legitimate domain props
311
+ // `role` is the SPEAKER, `hidden` and `autofocus` mean what they say — and they
312
+ // stay usable, but the native accessor must not be the one that receives them.
313
+ // See defineWithNonReflectingProps for what the native setter does to the author's
314
+ // markup if it is, and why the shadowing has to be in place before the registry
315
+ // sees the class. RESERVED names never get here; they already threw above.
316
+ const shadowedProps = Object.keys(defaults).filter((key) => reflectedGlobalPropNames().has(key));
170
317
 
171
- const Ctor = customElement(tag, defaults, (props: typeof defaults, options: { element: object }) => {
318
+ const renderFacade = (props: typeof defaults, options: { element: object }) => {
172
319
  const element = options.element as HTMLElement;
173
320
  let portalNode!: HTMLDivElement;
174
321
 
@@ -239,30 +386,18 @@ export function defineWebComponent<P extends Record<string, unknown>, E = Record
239
386
  </div>
240
387
  </>
241
388
  );
242
- });
389
+ };
390
+
391
+ const { result: Ctor, handled } = defineWithNonReflectingProps(tag, shadowedProps, () =>
392
+ customElement(tag, defaults, renderFacade),
393
+ );
243
394
 
244
- // Shadow any reflected native IDL accessor this element re-uses as a prop (see
245
- // NON_REFLECTING) with a plain, non-reflecting store on the element prototype.
246
- // This must live on the prototype (not the instance) so it is already in place
247
- // when the value is set before connectedCallback, the window in which the native
248
- // setter would otherwise reflect it to a host attribute. component-register reads
249
- // the property back during initializeProps to seed the styling prop, and later
250
- // shadows this with its own (also non-reflecting) per-instance accessor.
395
+ // Belt and braces for the one path the wrap cannot see: if `customElements.define`
396
+ // was never reached for this tag (a registry that defines lazily, or a future
397
+ // solid-element that stops calling it synchronously), install on the returned class
398
+ // instead. That is the OLD, too-late timing it still protects every element
399
+ // constructed from here on, it just cannot rescue an already-upgraded one. Skipped
400
+ // in the normal case, where the accessors are already on this same prototype.
251
401
  const proto = (Ctor as unknown as { prototype?: object } | undefined)?.prototype;
252
- if (proto) {
253
- for (const key of NON_REFLECTING) {
254
- if (!(key in defaults)) continue;
255
- const store = Symbol(`kai-prop:${key}`);
256
- Object.defineProperty(proto, key, {
257
- get(this: Record<symbol, unknown>) {
258
- return this[store];
259
- },
260
- set(this: Record<symbol, unknown>, value: unknown) {
261
- this[store] = value;
262
- },
263
- enumerable: true,
264
- configurable: true,
265
- });
266
- }
267
- }
402
+ if (!handled && proto) installNonReflectingProps(proto, shadowedProps);
268
403
  }
@@ -3,7 +3,7 @@ import { defineWebComponent } from './define';
3
3
  import { EditableLabel } from '../ui/editable-label';
4
4
 
5
5
  interface Props extends Record<string, unknown> {
6
- /** The label text settable and reflected to the `value` attribute. Read
6
+ /** The label text. Settable and reflected to the `value` attribute. Read
7
7
  * `el.value` for live state. */
8
8
  value?: string;
9
9
  /** Controlled edit state. `el.editing = true` opens the field; reflected to the
@@ -104,7 +104,22 @@ defineWebComponent<Props, Events>('kai-editable-label', {
104
104
  }
105
105
  };
106
106
 
107
- expose({ edit: enter, commit, cancel });
107
+ expose({
108
+ /** Switch the label into its editing field, which autofocuses and selects the
109
+ * current text. Same entry point as a user double-click, and a no-op while
110
+ * `disabled`. Commit with `commit()` or by blurring, abandon with `cancel()`
111
+ * or Escape. */
112
+ edit: enter,
113
+ /** Close the field and keep what was typed, exactly as blurring it does.
114
+ * `kai-rename` fires only when the text actually changed, so committing an
115
+ * untouched field is silent. A no-op while the field is closed. */
116
+ commit,
117
+ /** Abandon the edit, exactly as Escape does: the original text is restored,
118
+ * the field closes and `kai-cancel` fires. `kai-rename` never fires, even if
119
+ * the field was edited. Also works when `editing` was set programmatically
120
+ * and the field has not rendered yet. */
121
+ cancel,
122
+ });
108
123
 
109
124
  return (
110
125
  <>
@@ -0,0 +1,112 @@
1
+ /**
2
+ * The data shapes a consumer assigns to a `kai-*` element's array/object
3
+ * properties, when that shape has no Solid-layer twin they could import instead.
4
+ *
5
+ * WHY THIS FILE EXISTS. The generated `.d.ts` for `./elements` and the React
6
+ * wrappers expand every prop type STRUCTURALLY (see the `IMPORTS = {}` note in
7
+ * scripts/gen-element-api.mjs — self-contained declarations are what keeps a
8
+ * consumer's tsc from resolving library `.ts` source). That is right for the
9
+ * generated files, but it means a consumer who wants to name the shape — a
10
+ * `const items: … = [...]` in their own code, a helper that builds one — has no
11
+ * type to import and ends up writing
12
+ * `NonNullable<KaiCommandElementProps['items']>`. Every named element-prop type
13
+ * must therefore be reachable from the ROOT entry (`@kitn.ai/ui`), which is what
14
+ * a React / Vue / Svelte / vanilla consumer imports. Enforced by
15
+ * tests/elements/prop-types-exported.test.ts.
16
+ *
17
+ * These live in their own module (not in the facades that use them) because the
18
+ * facades compile to per-element side-effect entry points whose shipped
19
+ * declarations are `export {};` — a type re-exported from one of those would not
20
+ * resolve for a consumer. Types with a Solid twin (`TriggerDef`, `KaiNavItem`,
21
+ * `ChatThreadContextUsage`, …) stay in their own layer's module and are
22
+ * re-exported from `src/index.ts` directly.
23
+ *
24
+ * Type-only: fully erased by the build, so the root barrel pays nothing.
25
+ */
26
+
27
+ /** A single segment of `<kai-segmented>`.
28
+ *
29
+ * Distinct from the Solid `SegmentedOption`, whose `icon` is a JSX node: on the
30
+ * element, `icon` is an icon-NAME string (web-component-friendly) — a curated
31
+ * name (e.g. `"code"`), a URL/data-URI, or plain text — resolved to a glyph via
32
+ * the kit's icon renderer (the same path `kai-button`'s `icon` uses). */
33
+ export interface KaiSegmentedOption {
34
+ value: string;
35
+ label: string;
36
+ icon?: string;
37
+ }
38
+
39
+ /** A single citation in `<kai-sources>`' `sources` property. Also the shape
40
+ * `<kai-source>` light-DOM children are parsed into. */
41
+ export interface KaiSourceItem {
42
+ href: string;
43
+ title?: string;
44
+ description?: string;
45
+ label?: string;
46
+ showFavicon?: boolean;
47
+ }
48
+
49
+ /** Token-usage data for `<kai-context>`' `context` property. */
50
+ export interface KaiContextUsage {
51
+ /** Tokens consumed so far in the context window (drives the meter fill). */
52
+ usedTokens: number;
53
+ /** The model's total context-window size in tokens. */
54
+ maxTokens: number;
55
+ /** Tokens attributed to the prompt/input, shown in the breakdown. */
56
+ inputTokens?: number;
57
+ /** Tokens attributed to the generated output, shown in the breakdown. */
58
+ outputTokens?: number;
59
+ /** Tokens attributed to reasoning/thinking, shown when present. */
60
+ reasoningTokens?: number;
61
+ /** Tokens served from prompt cache, shown when present. */
62
+ cacheTokens?: number;
63
+ /** Estimated cost in dollars for this usage, shown in the footer. */
64
+ estimatedCost?: number;
65
+ }
66
+
67
+ /** One item in `<kai-menu>`'s `items` tree. */
68
+ export interface KaiMenuItem {
69
+ /** Emitted in `kai-select` for actionable items. */
70
+ id?: string;
71
+ label?: string;
72
+ /** Named icon (e.g. "paperclip"), image URL / data-URI, or plain text. */
73
+ icon?: string;
74
+ /** e.g. '⌘U' — shown right-aligned, muted. */
75
+ shortcut?: string;
76
+ /** Presence ⇒ a checkbox item (role=menuitemcheckbox). With `radioGroup` set,
77
+ * marks the SELECTED radio item in that group instead. */
78
+ checked?: boolean;
79
+ /** Membership in a single-select group (role=menuitemradio). Items sharing a
80
+ * `radioGroup` are mutually exclusive — the one with `checked: true` shows the
81
+ * checkmark; selecting one emits `{ id, radioGroup }` so the consumer moves
82
+ * the checkmark (the consumer owns state, like checkbox items). */
83
+ radioGroup?: string;
84
+ disabled?: boolean;
85
+ /** A divider (ignores other fields). */
86
+ separator?: boolean;
87
+ /** A non-interactive section label (uses `label`). */
88
+ heading?: boolean;
89
+ /** ⇒ a submenu. */
90
+ items?: KaiMenuItem[];
91
+ }
92
+
93
+ /**
94
+ * A single command/mention item for `<kai-command>`.
95
+ *
96
+ * Set `items` as a JS property (array ref) — not an HTML attribute.
97
+ */
98
+ export interface KaiCommandItem {
99
+ /** Unique identifier emitted in `kai-select`. */
100
+ id: string;
101
+ /** Display name shown in the list row. */
102
+ label: string;
103
+ /** Named icon (e.g. "search"), image URL / data-URI, or plain text. */
104
+ icon?: string;
105
+ /** Muted supplementary text (e.g. a file path or a short description). */
106
+ description?: string;
107
+ /** Optional keyboard shortcut shown as right-aligned key caps; uses the
108
+ * kai-kbd `keys` syntax (e.g. "Mod+K", "Alt+1"). */
109
+ shortcut?: string;
110
+ /** Group name that buckets this item under a section header. */
111
+ group?: string;
112
+ }