@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
@@ -0,0 +1,355 @@
1
+ // createCardRegistry: the one place an app writes down which cards it renders.
2
+ //
3
+ // WHY THIS EXISTS, AND WHY IT IS NOT "A WAY TO REGISTER CUSTOM CARDS"
4
+ // ------------------------------------------------------------------
5
+ // Registering a custom card already worked: `chat.cardTypes = { 'pricing-table':
6
+ // 'my-pricing-table' }` goes through `mergeCardTags` and has since the card contract
7
+ // landed, and `cardTools({ 'pricing-table': schema }, { provider })` already emitted
8
+ // `kai_pricing-table` before this file existed. Measured on 4b33cd8, both halves of
9
+ // the custom round trip passed already. Nothing here unlocks them.
10
+ //
11
+ // Two things did not work, and they are what this file is for.
12
+ //
13
+ // 1. NOTHING TIED THE TWO ENDS TOGETHER. `cardTypes` is a per-element PROP, so there
14
+ // is no ambient registry a backend route could consult. The developer wrote their
15
+ // card types on the client, wrote them again in the tool definitions, and nothing
16
+ // made the two agree. This is the fifth-copy problem the emit contract exists to
17
+ // kill, one layer up from the schema itself.
18
+ //
19
+ // 2. THE MODEL WAS TOLD ABOUT ALL SEVEN BUILT-INS REGARDLESS. `cardTools({ provider })`
20
+ // has no way to say "this app renders confirm and choice, do not offer the model an
21
+ // artifact card". Every request paid for seven tool definitions, five of which the
22
+ // app had no intention of using, and the model could pick one of them.
23
+ //
24
+ // So the goal is not the seam, which existed. It is to make the NORMAL path go through
25
+ // the seam, so it cannot rot the way it did once already: the only end-to-end user of
26
+ // `cardTypes` was a workaround in the conformance spike that registered `spike-artifact`
27
+ // because the kit had no artifact card, and when the kit grew one the workaround was
28
+ // correctly deleted and the coverage went with it. Coverage that exists only because
29
+ // something is missing is coverage on a timer.
30
+ //
31
+ // WHAT `use` DOES AND DOES NOT NARROW
32
+ // -----------------------------------
33
+ // `use` narrows what the MODEL IS TOLD ABOUT. It does not narrow what renders, and it
34
+ // must not be read as if it did. `mergeCardTags`/`mergeCardComponents` union the seven
35
+ // built-ins in unconditionally (consumer overrides win), so an app declaring
36
+ // `use: ['confirm']` still renders a `choice` envelope if one arrives. That is the
37
+ // right behaviour: an envelope that turns up from somewhere else should draw, not
38
+ // degrade to a fallback because it was left off a tool list. Narrowing rendering would
39
+ // be a `primitives/card-registry.tsx` change, and a worse product.
40
+ //
41
+ // Likewise `registry.validate()` covers all seven built-ins regardless of `use`.
42
+ // Validation is about what ARRIVED, not about what was offered.
43
+ //
44
+ // NO `toolPrefix`, DELIBERATELY
45
+ // -----------------------------
46
+ // The plan reserves `createCardRegistry({ toolPrefix })` and this file does not ship
47
+ // it, for the reason tool-defs.ts already gives: the inverse (`cardTypeFromToolName`)
48
+ // hard-codes `kai_`, so a prefix honoured on the emit side alone would generate tools
49
+ // the loop's parser cannot recognise, and the card would vanish into `runTool` with no
50
+ // error anywhere. Worse than not having the option. It lands in both directions in one
51
+ // change, or not at all.
52
+ //
53
+ // SERVER-SAFE
54
+ // -----------
55
+ // This module is imported by a backend route (it is half the point) so it stays free
56
+ // of DOM and of the Solid runtime. `CardComponentMap`/`CardTagMap` are TYPE imports
57
+ // and erase completely; the values in `components` are passed through untouched and
58
+ // never called here. `verify:ssr` imports the built entry under the `node` condition
59
+ // and proves the runtime half.
60
+ //
61
+ // It does NOT prove the compile-time half, and the two imports below are deliberately
62
+ // aimed at `.ts` modules rather than at primitives/card-registry.tsx for a reason no
63
+ // runtime guard can see. A type import still has to RESOLVE, and a Node/no-DOM project
64
+ // (tsconfig.mcp.json: `lib: ["ESNext"]`, no `jsx`) cannot resolve a `.tsx` at all:
65
+ // pointing either of these back at card-registry.tsx puts TS6142 on this exact line on
66
+ // any unbuilt tree. Both types are re-exported from card-registry.tsx, so importing
67
+ // them from there LOOKS equivalent and compiles everywhere else. It is not. The check
68
+ // that tells the difference is `tsc --noEmit -p tsconfig.mcp.json` with no dist/
69
+ // present; see the header of primitives/card-component-types.ts.
70
+
71
+ import type { CardComponentMap } from '../primitives/card-component-types';
72
+ import type { CardTagMap } from '../primitives/card-tags';
73
+ import type { JsonSchema } from '../primitives/card-validate';
74
+ import {
75
+ validateCardData,
76
+ type CardValidationReport,
77
+ } from '../primitives/card-validate-cards';
78
+ import { cardSchemas, isCardSchemaName, type CardSchema, type CardSchemaName } from './index';
79
+ import type { CardToolSource } from './tool-defs';
80
+
81
+ /**
82
+ * One custom card type: what the model should be told, and what draws it.
83
+ *
84
+ * Every member is optional because the useful combinations genuinely differ. A
85
+ * web-component consumer supplies `tag`; a Solid consumer supplies `component`; a
86
+ * backend-only registry (a route that builds tool definitions and never renders)
87
+ * supplies neither. Only `schema` carries a warning when absent, and the reason is on
88
+ * {@link CardRegistrySpec.onIncomplete}.
89
+ */
90
+ export interface CustomCardSpec {
91
+ /**
92
+ * The JSON Schema for this card type's `data` payload.
93
+ *
94
+ * Used for BOTH ends: `cardTools()` projects it into a tool definition, and
95
+ * `registry.validate()` checks arriving data against it. Authored form is fine, with
96
+ * the descriptions left in: the projection strips what a provider cannot take, and
97
+ * the validator ignores keywords it does not implement.
98
+ *
99
+ * That last clause is a real limit, not a formality, and it is the same one the
100
+ * built-ins carry. `validateAgainstSchema` has no applicators, so `allOf`, `anyOf`,
101
+ * `oneOf`, `if`/`then`, `$ref` and `additionalProperties` in a custom schema are
102
+ * carried faithfully to the model and NOT enforced on the way back. See the
103
+ * NOT_ENFORCED table at the top of primitives/card-validate-schemas.ts.
104
+ */
105
+ readonly schema?: CardSchema | JsonSchema;
106
+ /** The custom element that renders it, e.g. `'my-pricing-table'`. Feeds `mergeCardTags`. */
107
+ readonly tag?: string;
108
+ /** The Solid component that renders it. Feeds `mergeCardComponents`. */
109
+ readonly component?: CardComponentMap[string];
110
+ /**
111
+ * One sentence of PURPOSE, addressed to the model: when should it reach for this
112
+ * card? Not a restatement of the shape, which the schema already carries.
113
+ *
114
+ * Falls back to the schema's own `description`, then to a generated stub. See
115
+ * `describe()` in tool-defs.ts.
116
+ */
117
+ readonly description?: string;
118
+ }
119
+
120
+ /** What to do about a custom card type registered with no schema. */
121
+ export type IncompletePolicy = 'warn' | 'throw' | 'silent';
122
+
123
+ export interface CardRegistrySpec {
124
+ /**
125
+ * Which BUILT-IN card types this app renders, and therefore which ones the model is
126
+ * offered.
127
+ *
128
+ * Omitted means all seven, which is what `cardTools({ provider })` already does and
129
+ * what `<kai-chat>` actually renders, so the default describes reality rather than
130
+ * quietly shrinking it. `use: []` means none of ours: an app whose generative UI is
131
+ * entirely its own.
132
+ */
133
+ readonly use?: readonly CardSchemaName[];
134
+ /** This app's own card types, keyed by `CardEnvelope.type`. */
135
+ readonly custom?: Readonly<Record<string, CustomCardSpec>>;
136
+ /**
137
+ * How a schema-less custom type is reported. Default `'warn'`.
138
+ *
139
+ * `'throw'` for a build or a CI check that wants the hole to be fatal; `'silent'` for
140
+ * a card type your own code populates and a model never emits, where the warning is
141
+ * noise. `'silent'` is deliberately a word you have to type, so the acknowledgement is
142
+ * greppable instead of implied.
143
+ */
144
+ readonly onIncomplete?: IncompletePolicy;
145
+ }
146
+
147
+ /**
148
+ * An app's card types, in the one shape both ends take.
149
+ *
150
+ * ```ts
151
+ * // cards.ts, imported by the client AND the route
152
+ * export const cards = createCardRegistry({
153
+ * use: ['confirm', 'choice'],
154
+ * custom: { 'pricing-table': { schema: pricingSchema, tag: 'my-pricing-table' } },
155
+ * });
156
+ *
157
+ * // client
158
+ * chat.cardTypes = cards.tags;
159
+ * // server
160
+ * const tools = cardTools(cards, { provider: 'anthropic' });
161
+ * ```
162
+ *
163
+ * Extends {@link CardToolSource}, so `cardTools(registry, opts)` takes it with no
164
+ * signature change on that side. That interface was left open for exactly this.
165
+ */
166
+ export interface CardRegistry extends CardToolSource {
167
+ /**
168
+ * The card types the model is offered, keyed by type. `use`d built-ins plus every
169
+ * custom type that HAS a schema. What `cardTools()` reads.
170
+ */
171
+ readonly schemas: Readonly<Record<string, CardSchema>>;
172
+ /** Purpose sentences for custom types (and for any built-in a custom entry overrode). */
173
+ readonly descriptions: Readonly<Record<string, string>>;
174
+ /**
175
+ * Custom `type -> tag`, for `chat.cardTypes` / `mergeCardTags`.
176
+ *
177
+ * Custom entries ONLY. The built-in tags are not restated here because
178
+ * `mergeCardTags` adds all seven itself; listing the `use`d ones would read as if the
179
+ * others had been excluded, which is not what happens.
180
+ */
181
+ readonly tags: CardTagMap;
182
+ /** Custom `type -> Solid component`, for `<CardRenderer types>` / `mergeCardComponents`. */
183
+ readonly components: CardComponentMap;
184
+ /** Every type this registry declares, schema-less ones included. Built-ins first. */
185
+ readonly types: readonly string[];
186
+ /** The built-in types in `use`, in `cardSchemas` order. */
187
+ readonly builtIn: readonly CardSchemaName[];
188
+ /** The custom types, in declaration order, schema-less ones included. */
189
+ readonly custom: readonly string[];
190
+ /** Custom types with no schema: registered, renderable, invisible to the model. */
191
+ readonly incomplete: readonly string[];
192
+ /**
193
+ * Custom schemas in the shape `validateCardData`'s third argument takes, so a caller
194
+ * that already has a `validateCardData` call can widen it without going through
195
+ * {@link CardRegistry.validate}.
196
+ */
197
+ readonly validationSchemas: Readonly<Record<string, JsonSchema>>;
198
+ /**
199
+ * Validate an envelope's `data` against this registry's schema for `type`.
200
+ *
201
+ * Custom schemas win over a built-in of the same name, matching `mergeCardTags`'s
202
+ * consumer-wins rule. `null` means there was nothing to check (a type with no
203
+ * schema anywhere), which is kept distinguishable from a clean pass so a caller
204
+ * cannot report the second as the first.
205
+ *
206
+ * Covers all seven built-ins regardless of `use`: see the module header.
207
+ */
208
+ validate(type: string, data: unknown): CardValidationReport | null;
209
+ }
210
+
211
+ const isRecord = (v: unknown): v is Record<string, unknown> =>
212
+ typeof v === 'object' && v !== null && !Array.isArray(v);
213
+
214
+ function warnIncomplete(incomplete: readonly string[]): string {
215
+ const names = incomplete.map((t) => `"${t}"`).join(', ');
216
+ const plural = incomplete.length === 1 ? 'type' : 'types';
217
+ return [
218
+ `createCardRegistry: ${incomplete.length} custom card ${plural} registered with no \`schema\`: ${names}.`,
219
+ ' They will still RENDER (their tag/component is registered), but:',
220
+ ' - cardTools() skips them, so the model is never told the type exists and will never emit one;',
221
+ ' - registry.validate() returns null for them, so nothing checks what does arrive.',
222
+ ' A card type the model is never told about and that nothing validates is a silent hole.',
223
+ ' Fix: give each one a `schema`. If the type is populated by your own code and never by a',
224
+ " model, say so with `onIncomplete: 'silent'`; use `onIncomplete: 'throw'` to make it fatal.",
225
+ ].join('\n');
226
+ }
227
+
228
+ /**
229
+ * Declare the card types this app renders, once, for both ends.
230
+ *
231
+ * @throws {TypeError} if `use` names something that is not a built-in card type (a
232
+ * typo, or a custom type that belongs in `custom`), if a custom key is empty, or if
233
+ * `onIncomplete: 'throw'` and a custom type has no schema.
234
+ */
235
+ export function createCardRegistry(spec: CardRegistrySpec = {}): CardRegistry {
236
+ // A plain typeof check rather than the `isRecord` predicate used everywhere else in
237
+ // this file. `isRecord` narrows to `Record<string, unknown>`, and intersecting that
238
+ // with `CardRegistrySpec` makes the INDEX SIGNATURE win over the declared members:
239
+ // `spec.use` becomes `unknown`, `spec.use ?? […]` becomes `{}`, and the rest of the
240
+ // function loses its types while still compiling in places. Measured, not guessed —
241
+ // it produced seven `tsc` errors on the first pass of this file.
242
+ if (typeof spec !== 'object' || spec === null || Array.isArray(spec)) {
243
+ throw new TypeError('createCardRegistry: expected a spec object, e.g. createCardRegistry({ use: ["confirm"] })');
244
+ }
245
+
246
+ // `cardSchemas` is read HERE, inside the function, for the reason `builtInSchemas()`
247
+ // in tool-defs.ts spells out: ./index re-exports this module and this module imports
248
+ // back out of it, a real ESM cycle that is safe only while the read happens after
249
+ // both module bodies have evaluated. Do not hoist it to a module-scope const.
250
+ const builtInSource = cardSchemas;
251
+
252
+ const useList = spec.use ?? (Object.keys(builtInSource) as CardSchemaName[]);
253
+ const unknownUse = useList.filter((t) => !isCardSchemaName(t));
254
+ if (unknownUse.length > 0) {
255
+ throw new TypeError(
256
+ `createCardRegistry: \`use\` names ${unknownUse.length} type(s) that are not built in: ` +
257
+ `${unknownUse.map((t) => `"${t}"`).join(', ')}. ` +
258
+ `The built-in types are ${Object.keys(builtInSource).join(', ')}. ` +
259
+ 'A card type of your own goes in `custom`, with its schema, not in `use`.',
260
+ );
261
+ }
262
+
263
+ // Deduped and put back into cardSchemas order, so two registries listing the same
264
+ // types in a different order produce byte-identical tool arrays.
265
+ const used = new Set(useList);
266
+ const builtIn = (Object.keys(builtInSource) as CardSchemaName[]).filter((t) => used.has(t));
267
+
268
+ const customSpecs = spec.custom ?? {};
269
+ const customNames = Object.keys(customSpecs);
270
+ const emptyKey = customNames.find((n) => n.trim().length === 0);
271
+ if (emptyKey !== undefined) {
272
+ throw new TypeError('createCardRegistry: a custom card type name must be a non-empty string; it becomes `CardEnvelope.type` and the `kai_<type>` tool name.');
273
+ }
274
+
275
+ const schemas: Record<string, CardSchema> = {};
276
+ for (const type of builtIn) schemas[type] = builtInSource[type];
277
+
278
+ const descriptions: Record<string, string> = {};
279
+ const tags: CardTagMap = {};
280
+ const components: CardComponentMap = {};
281
+ const validationSchemas: Record<string, JsonSchema> = {};
282
+ const incomplete: string[] = [];
283
+
284
+ for (const type of customNames) {
285
+ const entry: CustomCardSpec = customSpecs[type];
286
+ // Same reason as the `spec` check above: narrowing with `isRecord` here would swap
287
+ // `CustomCardSpec`'s members for an index signature and lose `component`'s type.
288
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {
289
+ throw new TypeError(`createCardRegistry: custom card type "${type}" must be an object, e.g. { schema, tag }.`);
290
+ }
291
+ // A custom entry OVERRIDES a built-in of the same name rather than colliding with
292
+ // it, matching mergeCardTags/mergeCardComponents where the consumer wins. That is
293
+ // how you replace our confirm card with yours and still get one tool definition.
294
+ if (isRecord(entry.schema)) {
295
+ schemas[type] = entry.schema as CardSchema;
296
+ validationSchemas[type] = entry.schema as JsonSchema;
297
+ } else {
298
+ // No schema: keep it out of `schemas` so `cardTools` skips it with no special
299
+ // case over there, and record it so the policy below can speak up.
300
+ //
301
+ // The `delete` is not dead code. It fires when a custom entry SHADOWS a `use`d
302
+ // built-in without supplying a schema (`use: ['confirm']` plus
303
+ // `custom: { confirm: { tag: 'my-confirm' } }`). Keeping our confirm schema there
304
+ // would hand the model a shape describing OUR card while the developer's card
305
+ // renders it, which is the drift this whole contract exists to prevent. Dropping
306
+ // it instead puts the type in `incomplete`, where it gets said out loud.
307
+ delete schemas[type];
308
+ incomplete.push(type);
309
+ }
310
+ if (typeof entry.tag === 'string' && entry.tag.length > 0) tags[type] = entry.tag;
311
+ if (typeof entry.component === 'function') components[type] = entry.component;
312
+ if (typeof entry.description === 'string' && entry.description.length > 0) {
313
+ descriptions[type] = entry.description;
314
+ }
315
+ }
316
+
317
+ if (incomplete.length > 0) {
318
+ const policy: IncompletePolicy = spec.onIncomplete ?? 'warn';
319
+ const message = warnIncomplete(incomplete);
320
+ if (policy === 'throw') throw new TypeError(message);
321
+ // WHY THIS WARNS UNCONDITIONALLY RATHER THAN ONLY IN DEV.
322
+ // ------------------------------------------------------
323
+ // There is no `process.env.NODE_ENV` / `import.meta.env` convention anywhere in
324
+ // this package's src/, and the emit-contract plan rejected introducing one for
325
+ // exactly this shape of thing: a stripping contract has to hold across seven
326
+ // consumer bundlers on a PRE-BUILT dist, where substitution into node_modules is
327
+ // not guaranteed, and getting it wrong means the developer's laptop looks fine
328
+ // while production is silently the broken one. The same argument applies here,
329
+ // and the cost side is far smaller than it was there: a registry is built ONCE at
330
+ // module load, not per render, so this is one line per process and not a hot path.
331
+ // `onIncomplete: 'silent'` is the escape hatch, and it is a word you have to type.
332
+ //
333
+ // `!== 'silent'` rather than `=== 'warn'`, so an unrecognised policy is LOUD.
334
+ // TypeScript rejects one, but this is shipped JS a consumer can call untyped, and
335
+ // `onIncomplete: 'quiet'` reaching the silent branch would be a typo that disables
336
+ // the warning about a silent hole. Defaulting the unknown case to noise is the only
337
+ // direction that fails safe.
338
+ if (policy !== 'silent') console.warn(message);
339
+ }
340
+
341
+ const frozenValidationSchemas = Object.freeze({ ...validationSchemas });
342
+
343
+ return Object.freeze({
344
+ schemas: Object.freeze(schemas),
345
+ descriptions: Object.freeze(descriptions),
346
+ tags: Object.freeze(tags),
347
+ components: Object.freeze(components),
348
+ types: Object.freeze([...builtIn, ...customNames]),
349
+ builtIn: Object.freeze(builtIn),
350
+ custom: Object.freeze([...customNames]),
351
+ incomplete: Object.freeze([...incomplete]),
352
+ validationSchemas: frozenValidationSchemas,
353
+ validate: (type: string, data: unknown) => validateCardData(type, data, frozenValidationSchemas),
354
+ });
355
+ }