@kitn.ai/ui 0.25.1 → 0.26.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 (409) hide show
  1. package/README.md +5 -7
  2. package/dist/components/attachment-types.d.ts +46 -1
  3. package/dist/components/attachments.d.ts +31 -0
  4. package/dist/components/audio-visualizer/fit-scale.d.ts +50 -0
  5. package/dist/components/audio-visualizer/index.d.ts +15 -1
  6. package/dist/components/audio-visualizer/variant-bar.d.ts +24 -1
  7. package/dist/components/chat-thread.d.ts +3 -41
  8. package/dist/components/code-block.d.ts +22 -0
  9. package/dist/components/conversation-item.d.ts +54 -1
  10. package/dist/components/conversation-list.d.ts +65 -0
  11. package/dist/components/form.d.ts +42 -0
  12. package/dist/components/message.d.ts +7 -0
  13. package/dist/components/toast.d.ts +2 -1
  14. package/dist/components/voice-input.d.ts +8 -0
  15. package/dist/components/voice-output.d.ts +12 -1
  16. package/dist/components/workspace-shell.d.ts +87 -0
  17. package/dist/{create-tween-B5Y4Im8G.js → create-tween-BFT6c-Y8.js} +1 -1
  18. package/dist/{create-tween-4z1XYLkR.js → create-tween-CJNlzoaO.js} +1 -1
  19. package/dist/{create-tween-CUzOlaMS.js → create-tween-CQED4T0g.js} +1 -1
  20. package/dist/custom-elements.json +2931 -2572
  21. package/dist/diagnostics/hook.d.ts +81 -0
  22. package/dist/diagnostics/index.d.ts +7 -0
  23. package/dist/diagnostics/report-request.d.ts +61 -0
  24. package/dist/diagnostics.d.ts +5 -0
  25. package/dist/diagnostics.js +209 -0
  26. package/dist/elements/agent-card.js +1 -1
  27. package/dist/elements/artifact.js +1 -1
  28. package/dist/elements/attachments.js +1 -1
  29. package/dist/elements/audio-visualizer.js +1 -1
  30. package/dist/elements/autoloader.js +1 -1
  31. package/dist/elements/avatar.js +1 -1
  32. package/dist/elements/badge.js +1 -1
  33. package/dist/elements/button.js +1 -1
  34. package/dist/elements/card.js +1 -1
  35. package/dist/elements/cards.js +1 -1
  36. package/dist/elements/chain-of-thought.js +1 -1
  37. package/dist/elements/chat-scope-picker.js +1 -1
  38. package/dist/elements/chat-workspace.js +1 -1
  39. package/dist/elements/chat.js +1 -1
  40. package/dist/elements/checkpoint.js +1 -1
  41. package/dist/elements/choice.js +1 -1
  42. package/dist/elements/chunks/{Icon-b5A8hlHs.js → Icon--Y8vsFal.js} +1 -1
  43. package/dist/elements/chunks/action-icons-D9u3OzYW.js +1 -0
  44. package/dist/elements/chunks/arrow-left-CVh1TeN7.js +1 -0
  45. package/dist/elements/chunks/{artifact-BSuPYFHY.js → artifact-BkYcfIlZ.js} +1 -1
  46. package/dist/elements/chunks/attachments-DwfNlubq.js +1 -0
  47. package/dist/elements/chunks/audio-visualizer-D7lB6mvR.js +1 -0
  48. package/dist/elements/chunks/{badge-TIMiJFKc.js → badge-Q0-Cmwzz.js} +1 -1
  49. package/dist/elements/chunks/{button-B9okqG73.js → button-flUbeufF.js} +1 -1
  50. package/dist/elements/chunks/{card-renderer-CSoTL_e1.js → card-renderer-3Dyl-FpN.js} +1 -1
  51. package/dist/elements/chunks/check-B5kBPKeo.js +1 -0
  52. package/dist/elements/chunks/chevron-down-DZ1GS39h.js +1 -0
  53. package/dist/elements/chunks/chevron-right-CvP7OUd2.js +1 -0
  54. package/dist/elements/chunks/{choice-card-CGMc3kek.js → choice-card-D4QUIOWZ.js} +1 -1
  55. package/dist/elements/chunks/circle-CDf9g6MQ.js +1 -0
  56. package/dist/elements/chunks/circle-check-CA47Nqbz.js +1 -0
  57. package/dist/elements/chunks/{circle-x-mhH7pOK2.js → circle-x-CJ_HVbC8.js} +1 -1
  58. package/dist/elements/chunks/code-block-BdLiTitd.js +1 -0
  59. package/dist/elements/chunks/collapsible-BzbXpPzr.js +1 -0
  60. package/dist/elements/chunks/{composer-CZZmtYOT.js → composer-Byve-n8K.js} +2 -2
  61. package/dist/elements/chunks/{confirm-card-BWjf2-xo.js → confirm-card-B0flE3MN.js} +1 -1
  62. package/dist/elements/chunks/context-VLIL3sJ-.js +1 -0
  63. package/dist/elements/chunks/controllable-DTwTIlwp.js +1 -0
  64. package/dist/elements/chunks/conversation-item-BDztezOG.js +1 -0
  65. package/dist/elements/chunks/copy-Nf-kqxXH.js +1 -0
  66. package/dist/elements/chunks/{create-tween-CUrM6D_o.js → create-tween-c4Z8TDYz.js} +2 -2
  67. package/dist/elements/chunks/default-input-C2iLFq0b.js +1 -0
  68. package/dist/elements/chunks/define-wjHR1MkU.js +1 -0
  69. package/dist/elements/chunks/disclosure-CcNbyLy0.js +1 -0
  70. package/dist/elements/chunks/{download-DnCyWFJE.js → download-C4V7tBdb.js} +1 -1
  71. package/dist/elements/chunks/dropdown-BgWTthUx.js +1 -0
  72. package/dist/elements/chunks/{ellipsis-CVxqfsDZ.js → ellipsis-7gU33mL2.js} +1 -1
  73. package/dist/elements/chunks/embed-D3KewsIJ.js +1 -0
  74. package/dist/elements/chunks/{external-link-DG2sRdQL.js → external-link-CSOEsNlx.js} +1 -1
  75. package/dist/elements/chunks/{file-text-D0J9F6M7.js → file-text-D1G8khle.js} +1 -1
  76. package/dist/elements/chunks/{file-tree-yGWNK0Js.js → file-tree-zvB2i7P9.js} +1 -1
  77. package/dist/elements/chunks/{folder-NV1pi_ud.js → folder-WW2LGLid.js} +1 -1
  78. package/dist/elements/chunks/form-CQirdC4W.js +1 -0
  79. package/dist/elements/chunks/hover-card-CJJkfHTK.js +1 -0
  80. package/dist/elements/chunks/icon-Cfgmf4fa.js +1 -0
  81. package/dist/elements/chunks/{info-C8r5Q6cc.js → info-DX3YMOt6.js} +1 -1
  82. package/dist/elements/chunks/input-BtW9U6Sq.js +1 -0
  83. package/dist/elements/chunks/{kbd-OGJDUT-O.js → kbd-LGXwuT_V.js} +1 -1
  84. package/dist/elements/chunks/{link-BdsfLB7b.js → link-2My69BqT.js} +1 -1
  85. package/dist/elements/chunks/{link-preview-Cf5KOP-i.js → link-preview-OQ9IEq0f.js} +1 -1
  86. package/dist/elements/chunks/{loader-B5QzK_8_.js → loader-iOxc_Tu-.js} +1 -1
  87. package/dist/elements/chunks/{markdown-DbozyYqa.js → markdown-DgBFaGAz.js} +1 -1
  88. package/dist/elements/chunks/{message-DtXKPqiR.js → message-VMZohrXx.js} +1 -1
  89. package/dist/elements/chunks/message-circle-CpXMM-_n.js +1 -0
  90. package/dist/elements/chunks/message-square-DxcWtETQ.js +1 -0
  91. package/dist/elements/chunks/message-tZmV2A3p.js +1 -0
  92. package/dist/elements/chunks/{minimize-2-SegJ_oku.js → minimize-2-DPIUKTrT.js} +1 -1
  93. package/dist/elements/chunks/{model-switcher-D7JrFFHp.js → model-switcher-DsT8tFB0.js} +1 -1
  94. package/dist/elements/chunks/{overlay-CV7z2YuX.js → overlay-DuiwdXjm.js} +1 -1
  95. package/dist/elements/chunks/{paperclip-Bg0ITU3b.js → paperclip-CRZVp4z_.js} +1 -1
  96. package/dist/elements/chunks/{progress-bar-D1_rzt6N.js → progress-bar-DNy66e_E.js} +1 -1
  97. package/dist/elements/chunks/{prompt-suggestion-D5Sm8xF1.js → prompt-suggestion-Bn64Nl7L.js} +1 -1
  98. package/dist/elements/chunks/reasoning-Emn9N4-T.js +1 -0
  99. package/dist/elements/chunks/{resizable-Dpzjlvp4.js → resizable-D181b4fM.js} +1 -1
  100. package/dist/elements/chunks/{rotate-cw-DzVDJOA1.js → rotate-cw-CPWe37D9.js} +1 -1
  101. package/dist/elements/chunks/{scroll-area-93A1bbeG.js → scroll-area-ClZkZxIk.js} +1 -1
  102. package/dist/elements/chunks/scroll-button-DPE-t3x_.js +1 -0
  103. package/dist/elements/chunks/{separator-DH2r_ZSZ.js → separator-CeJHQqLW.js} +1 -1
  104. package/dist/elements/chunks/{settings-BFMOd6yB.js → settings-CqaHgJF9.js} +1 -1
  105. package/dist/elements/chunks/{settings-group-B3VZKIcz.js → settings-group-CjqjLCOn.js} +1 -1
  106. package/dist/elements/chunks/share-CyfnNEqp.js +1 -0
  107. package/dist/elements/chunks/{skeleton-N8BuWYmf.js → skeleton-D8akBnKS.js} +1 -1
  108. package/dist/elements/chunks/slots-DaNjX0rc.js +1 -0
  109. package/dist/elements/chunks/{source-w9V0NnBn.js → source-UWCvmVak.js} +1 -1
  110. package/dist/elements/chunks/{star-DHvACxtm.js → star-DoHFAikQ.js} +1 -1
  111. package/dist/elements/chunks/store-Cjq0qwYN.js +1 -0
  112. package/dist/elements/chunks/{tasks-card-lPxoodlA.js → tasks-card-CmZ5xh6v.js} +1 -1
  113. package/dist/elements/chunks/{text-shimmer-BY_rI3s5.js → text-shimmer-DYn09zrz.js} +1 -1
  114. package/dist/elements/chunks/textarea-skiGHURM.js +1 -0
  115. package/dist/elements/chunks/{thumbs-up-DQe0hvkZ.js → thumbs-up-DX2Ijk3H.js} +1 -1
  116. package/dist/elements/chunks/{toast-store-VUZZBhzH.js → toast-store-CFnQpThX.js} +1 -1
  117. package/dist/elements/chunks/{tool-C1YtxwPu.js → tool-DKQ2D1DP.js} +1 -1
  118. package/dist/elements/chunks/{tooltip-BqwnFWhn.js → tooltip-B0G99y8w.js} +1 -1
  119. package/dist/elements/chunks/{triangle-alert-B6or7F5u.js → triangle-alert-F9cyUEyy.js} +1 -1
  120. package/dist/elements/chunks/{use-card-resolution-DJg32jGH.js → use-card-resolution-DoA2f_EU.js} +1 -1
  121. package/dist/elements/chunks/{variant-aurora-QXTZPyST.js → variant-aurora-qt6Zct8M.js} +2 -2
  122. package/dist/elements/chunks/variant-custom-tJp22_BQ.js +1 -0
  123. package/dist/{variant-wave-BwzrHD1s.js → elements/chunks/variant-wave-CaQ5ti39.js} +2 -2
  124. package/dist/elements/chunks/x-B6UnOiLw.js +1 -0
  125. package/dist/elements/coachmark.js +1 -1
  126. package/dist/elements/code-block.js +1 -1
  127. package/dist/elements/command.js +1 -1
  128. package/dist/elements/compare.js +1 -1
  129. package/dist/elements/composer.js +1 -1
  130. package/dist/elements/confirm-card.js +1 -1
  131. package/dist/elements/context-meter.js +1 -1
  132. package/dist/elements/conversation-item.d.ts +1 -0
  133. package/dist/elements/conversation-item.js +1 -0
  134. package/dist/elements/conversation-list.js +1 -1
  135. package/dist/elements/default-input.d.ts +3 -3
  136. package/dist/elements/define.d.ts +27 -0
  137. package/dist/elements/diagnostic-events.d.ts +74 -0
  138. package/dist/elements/dialog.js +1 -1
  139. package/dist/elements/dock.d.ts +1 -0
  140. package/dist/elements/dock.js +149 -0
  141. package/dist/elements/dropdown.d.ts +1 -0
  142. package/dist/elements/dropdown.js +1 -0
  143. package/dist/elements/editable-label.js +1 -1
  144. package/dist/elements/element-diagnostics.d.ts +81 -0
  145. package/dist/elements/embed.js +1 -1
  146. package/dist/elements/empty.js +1 -1
  147. package/dist/elements/feedback-bar.js +1 -1
  148. package/dist/elements/file-tree.js +1 -1
  149. package/dist/elements/file-upload.js +1 -1
  150. package/dist/elements/form.js +1 -1
  151. package/dist/elements/hover-card.js +1 -1
  152. package/dist/elements/icon.js +1 -1
  153. package/dist/elements/image.js +1 -1
  154. package/dist/elements/input.js +1 -1
  155. package/dist/elements/kbd.js +1 -1
  156. package/dist/elements/link-preview.js +1 -1
  157. package/dist/elements/loader.js +1 -1
  158. package/dist/elements/markdown.js +1 -1
  159. package/dist/elements/menu.js +1 -1
  160. package/dist/elements/message-skills.js +1 -1
  161. package/dist/elements/message.js +1 -1
  162. package/dist/elements/model-switcher.js +1 -1
  163. package/dist/elements/nav.js +1 -1
  164. package/dist/elements/notice.js +1 -1
  165. package/dist/elements/pane-group.js +1 -1
  166. package/dist/elements/pane.js +1 -1
  167. package/dist/elements/popover.js +1 -1
  168. package/dist/elements/progress-bar.js +1 -1
  169. package/dist/elements/prompt-dock.js +1 -1
  170. package/dist/elements/prompt-input.js +1 -1
  171. package/dist/elements/prompt-suggestions.js +1 -1
  172. package/dist/elements/reasoning.js +1 -1
  173. package/dist/elements/register.d.ts +2 -0
  174. package/dist/elements/remote.js +1 -1
  175. package/dist/elements/resizable.js +1 -1
  176. package/dist/elements/response-stream.js +3 -3
  177. package/dist/elements/screen.js +1 -1
  178. package/dist/elements/scroll-area.js +1 -1
  179. package/dist/elements/scroll-button.js +1 -1
  180. package/dist/elements/search.js +1 -1
  181. package/dist/elements/segmented.js +1 -1
  182. package/dist/elements/separator.js +1 -1
  183. package/dist/elements/setting-item.js +1 -1
  184. package/dist/elements/settings-group.js +1 -1
  185. package/dist/elements/skeleton.js +1 -1
  186. package/dist/elements/slots.d.ts +35 -3
  187. package/dist/elements/source.js +1 -1
  188. package/dist/elements/status.js +1 -1
  189. package/dist/elements/switch.js +1 -1
  190. package/dist/elements/tabs.js +1 -1
  191. package/dist/elements/tasks.js +1 -1
  192. package/dist/elements/text-shimmer.js +1 -1
  193. package/dist/elements/thinking-bar.js +1 -1
  194. package/dist/elements/thread.js +1 -1
  195. package/dist/elements/toast.js +1 -1
  196. package/dist/elements/tool.js +1 -1
  197. package/dist/elements/tooltip.js +1 -1
  198. package/dist/elements/voice-input.js +1 -1
  199. package/dist/elements/voice-output.js +1 -1
  200. package/dist/elements.d.ts +232 -148
  201. package/dist/index.d.ts +2 -0
  202. package/dist/index.js +5456 -4931
  203. package/dist/index.server.js +4142 -3669
  204. package/dist/kai-provider.es.js +40 -40
  205. package/dist/kai.es.js +1 -1
  206. package/dist/llms/llms-full.txt +184 -69
  207. package/dist/llms/llms.txt +3 -3
  208. package/dist/mcp.es.js +2669 -546
  209. package/dist/primitives/use-resize-observer.d.ts +23 -0
  210. package/dist/primitives/use-speech-recognition.d.ts +8 -0
  211. package/dist/primitives/use-text-stream.d.ts +5 -0
  212. package/dist/react/index.d.ts +115 -266
  213. package/dist/react.js +247 -221
  214. package/dist/register-impl-DpE7icIb.js +293 -0
  215. package/dist/schemas/index.d.ts +1 -1
  216. package/dist/schemas/tool-defs.d.ts +35 -0
  217. package/dist/schemas.js +403 -310
  218. package/dist/{solid-BMuDmFo_.js → solid-BtdqNZI7.js} +8435 -7394
  219. package/dist/{solid-CGYNdLRR.js → solid-CnavwBye.js} +5987 -5035
  220. package/dist/solid.d.ts +5 -0
  221. package/dist/solid.js +210 -203
  222. package/dist/solid.server.js +210 -203
  223. package/dist/state/index.d.ts +4 -0
  224. package/dist/state/persistence.d.ts +51 -0
  225. package/dist/state/stream.d.ts +50 -0
  226. package/dist/state/threads.d.ts +71 -0
  227. package/dist/state.js +269 -169
  228. package/dist/types.d.ts +4 -2
  229. package/dist/ui/dock.d.ts +109 -0
  230. package/dist/ui/hover-card.d.ts +44 -0
  231. package/dist/{variant-aurora-DwSOfraQ.js → variant-aurora-B8II3-I1.js} +27 -27
  232. package/dist/{variant-aurora-wKvAQ5wp.js → variant-aurora-CMNWOSJR.js} +28 -28
  233. package/dist/{variant-aurora-XEkPT0_z.js → variant-aurora-CcuDMWwQ.js} +2 -2
  234. package/dist/{variant-custom-eFIg2XWQ.js → variant-custom-BdvYC7af.js} +40 -40
  235. package/dist/{variant-custom-BhS9wIpU.js → variant-custom-C714mqKl.js} +65 -65
  236. package/dist/variant-custom-L16JLLZy.js +1 -0
  237. package/dist/{elements/chunks/variant-wave-DDCwhLas.js → variant-wave-2S4La2Ka.js} +2 -2
  238. package/dist/{variant-wave-CbVsmgwT.js → variant-wave-D7ruiA1W.js} +25 -25
  239. package/dist/{variant-wave-CUWGx9Bn.js → variant-wave-ecwykeyL.js} +21 -21
  240. package/dist/wire/chunk.d.ts +47 -0
  241. package/dist/wire/diagnostics.d.ts +575 -0
  242. package/dist/wire/encode-probe.d.ts +70 -0
  243. package/dist/wire/encode.d.ts +24 -0
  244. package/dist/wire/index.d.ts +2 -0
  245. package/dist/wire/sse.d.ts +10 -2
  246. package/dist/wire.js +917 -480
  247. package/frameworks/react/index.tsx +132 -93
  248. package/llms-full.txt +184 -69
  249. package/llms.txt +3 -3
  250. package/package.json +27 -7
  251. package/src/agent-tooling/archetypes.ts +41 -9
  252. package/src/agent-tooling/catalog/README.md +676 -0
  253. package/src/agent-tooling/catalog/catalog-types.ts +231 -0
  254. package/src/agent-tooling/catalog/fabrications.ts +96 -0
  255. package/src/agent-tooling/catalog/invariants.ts +284 -0
  256. package/src/agent-tooling/catalog/labs-titles.ts +114 -0
  257. package/src/agent-tooling/catalog/scenarios.ts +87 -0
  258. package/src/agent-tooling/catalog/surfaces.ts +275 -0
  259. package/src/agent-tooling/integrations/anthropic.ts +7 -1
  260. package/src/agent-tooling/integrations/cloudflare.ts +43 -2
  261. package/src/agent-tooling/integrations/langgraph.ts +7 -1
  262. package/src/agent-tooling/integrations/mastra.ts +7 -1
  263. package/src/agent-tooling/integrations/mock.ts +92 -17
  264. package/src/agent-tooling/integrations/ollama.ts +7 -1
  265. package/src/agent-tooling/integrations/openai.ts +7 -1
  266. package/src/agent-tooling/integrations/openrouter.ts +7 -1
  267. package/src/agent-tooling/integrations/pi.ts +56 -1
  268. package/src/agent-tooling/integrations/vercel-ai-sdk.ts +7 -1
  269. package/src/agent-tooling/mcp/css-raw.d.ts +12 -0
  270. package/src/agent-tooling/mcp/manifest.ts +100 -1
  271. package/src/agent-tooling/mcp/server.ts +61 -5
  272. package/src/agent-tooling/mcp/tools/reference.ts +440 -4
  273. package/src/agent-tooling/mcp/tools/scaffold.ts +1834 -307
  274. package/src/agent-tooling/mcp/tools/theme.ts +146 -30
  275. package/src/agent-tooling/mcp/validate-args.ts +141 -0
  276. package/src/agent-tooling/registry.ts +19 -7
  277. package/src/agent-tooling/route-emit.ts +26 -2
  278. package/src/components/attachment-types.ts +47 -1
  279. package/src/components/attachments.tsx +169 -22
  280. package/src/components/audio-visualizer/fit-scale.ts +112 -0
  281. package/src/components/audio-visualizer/index.tsx +80 -3
  282. package/src/components/audio-visualizer/variant-aurora.tsx +10 -4
  283. package/src/components/audio-visualizer/variant-bar.tsx +38 -6
  284. package/src/components/audio-visualizer/variant-custom.tsx +8 -2
  285. package/src/components/audio-visualizer/variant-grid.tsx +16 -11
  286. package/src/components/audio-visualizer/variant-radial.tsx +15 -10
  287. package/src/components/audio-visualizer/variant-wave.tsx +7 -2
  288. package/src/components/chat-container.tsx +4 -1
  289. package/src/components/chat-thread.tsx +36 -7
  290. package/src/components/code-block.tsx +79 -3
  291. package/src/components/composer.tsx +8 -1
  292. package/src/components/conversation-item.tsx +114 -4
  293. package/src/components/conversation-list.tsx +212 -12
  294. package/src/components/embed.tsx +4 -0
  295. package/src/components/form.tsx +41 -14
  296. package/src/components/message.tsx +75 -5
  297. package/src/components/response-stream.tsx +13 -7
  298. package/src/components/screen.tsx +5 -0
  299. package/src/components/scroll-button.tsx +7 -0
  300. package/src/components/toast.tsx +11 -5
  301. package/src/components/voice-input.tsx +35 -3
  302. package/src/components/voice-output.tsx +46 -6
  303. package/src/components/workspace-shell.tsx +285 -0
  304. package/src/diagnostics/hook.ts +352 -0
  305. package/src/diagnostics/index.ts +82 -0
  306. package/src/diagnostics/report-request.ts +296 -0
  307. package/src/elements/attachments.tsx +6 -7
  308. package/src/elements/audio-visualizer.tsx +48 -4
  309. package/src/elements/chat-workspace.tsx +159 -287
  310. package/src/elements/chat.tsx +12 -9
  311. package/src/elements/code-block.tsx +19 -1
  312. package/src/elements/command.tsx +4 -1
  313. package/src/elements/compiled.css +1 -1
  314. package/src/elements/conversation-item.tsx +80 -0
  315. package/src/elements/conversation-list.tsx +60 -11
  316. package/src/elements/default-input.tsx +5 -5
  317. package/src/elements/define.tsx +168 -8
  318. package/src/elements/diagnostic-events.ts +114 -0
  319. package/src/elements/dialog.tsx +47 -0
  320. package/src/elements/disclosure.ts +34 -12
  321. package/src/elements/dock.tsx +204 -0
  322. package/src/elements/dropdown.tsx +123 -0
  323. package/src/elements/element-diagnostics.ts +392 -0
  324. package/src/elements/element-manifest.json +12 -0
  325. package/src/elements/element-meta.json +672 -439
  326. package/src/elements/element-nonscalar.json +170 -0
  327. package/src/elements/element-types.d.ts +232 -148
  328. package/src/elements/menu.tsx +13 -0
  329. package/src/elements/prompt-dock.tsx +2 -1
  330. package/src/elements/prompt-input.tsx +8 -8
  331. package/src/elements/register-impl.ts +46 -0
  332. package/src/elements/register.ts +28 -0
  333. package/src/elements/resizable.tsx +52 -25
  334. package/src/elements/scroll-button.tsx +5 -0
  335. package/src/elements/slots.ts +107 -12
  336. package/src/elements/styles.css +30 -6
  337. package/src/elements/thinking-bar.tsx +16 -7
  338. package/src/elements/toast.tsx +3 -0
  339. package/src/elements/tool.tsx +26 -5
  340. package/src/elements/voice-input.tsx +11 -2
  341. package/src/elements/voice-output.tsx +16 -3
  342. package/src/index.ts +2 -0
  343. package/src/primitives/use-resize-observer.ts +33 -0
  344. package/src/primitives/use-speech-recognition.ts +12 -1
  345. package/src/primitives/use-stick-to-bottom.ts +34 -2
  346. package/src/primitives/use-text-stream.ts +33 -2
  347. package/src/remote/provider-runtime.ts +6 -3
  348. package/src/schemas/index.ts +1 -0
  349. package/src/schemas/tool-defs.ts +297 -6
  350. package/src/solid.ts +5 -0
  351. package/src/state/index.ts +12 -0
  352. package/src/state/persistence.ts +180 -0
  353. package/src/state/stream.ts +71 -4
  354. package/src/state/threads.ts +142 -0
  355. package/src/types.ts +4 -2
  356. package/src/ui/dialog.tsx +6 -0
  357. package/src/ui/dock.tsx +445 -0
  358. package/src/ui/dropdown.tsx +67 -23
  359. package/src/ui/hover-card.tsx +156 -6
  360. package/src/ui/input.tsx +29 -10
  361. package/src/ui/resizable.tsx +11 -0
  362. package/src/wire/chunk.ts +47 -0
  363. package/src/wire/consume.ts +185 -26
  364. package/src/wire/diagnostics.ts +727 -0
  365. package/src/wire/encode-probe.ts +214 -0
  366. package/src/wire/encode.ts +267 -14
  367. package/src/wire/formats/anthropic.ts +8 -1
  368. package/src/wire/formats/openai.ts +5 -0
  369. package/src/wire/index.ts +22 -0
  370. package/src/wire/read.ts +250 -6
  371. package/src/wire/sse.ts +16 -3
  372. package/dist/elements/chunks/action-icons-DW9muWrY.js +0 -1
  373. package/dist/elements/chunks/arrow-left-iJVnQmxA.js +0 -1
  374. package/dist/elements/chunks/attachments-CL6TaqIb.js +0 -1
  375. package/dist/elements/chunks/audio-visualizer-BuUqQmaO.js +0 -1
  376. package/dist/elements/chunks/chat-thread-DxoKaStk.js +0 -1
  377. package/dist/elements/chunks/check-MdLzbxrm.js +0 -1
  378. package/dist/elements/chunks/chevron-down-MK7IzDqe.js +0 -1
  379. package/dist/elements/chunks/chevron-right-C5jXhmtV.js +0 -1
  380. package/dist/elements/chunks/circle-BG7VkPep.js +0 -1
  381. package/dist/elements/chunks/circle-check-GqvO2UBs.js +0 -1
  382. package/dist/elements/chunks/code-block-ClhQO9RW.js +0 -1
  383. package/dist/elements/chunks/collapsible-DBcBkFPh.js +0 -1
  384. package/dist/elements/chunks/context-hKjNqiyQ.js +0 -1
  385. package/dist/elements/chunks/conversation-list-CsGJjSKG.js +0 -1
  386. package/dist/elements/chunks/default-input-B1Mem5wu.js +0 -1
  387. package/dist/elements/chunks/define-B_tXMYRm.js +0 -1
  388. package/dist/elements/chunks/disclosure-DAoYOKew.js +0 -1
  389. package/dist/elements/chunks/dropdown-CmNna5lT.js +0 -1
  390. package/dist/elements/chunks/embed-CjAD2jSi.js +0 -1
  391. package/dist/elements/chunks/form-Cp8Y00Wn.js +0 -1
  392. package/dist/elements/chunks/hover-card-6KtXpLwT.js +0 -1
  393. package/dist/elements/chunks/icon-97R8SR2p.js +0 -1
  394. package/dist/elements/chunks/input-DrseEjhp.js +0 -1
  395. package/dist/elements/chunks/message-CE4k-qaj.js +0 -1
  396. package/dist/elements/chunks/message-square-C9ovmtOo.js +0 -1
  397. package/dist/elements/chunks/reasoning-BrxQfpfI.js +0 -1
  398. package/dist/elements/chunks/scroll-button-CrTo7wm4.js +0 -1
  399. package/dist/elements/chunks/share-DgNbkJKY.js +0 -1
  400. package/dist/elements/chunks/slots-CIw9RlAe.js +0 -1
  401. package/dist/elements/chunks/store-HIPGhNz9.js +0 -1
  402. package/dist/elements/chunks/textarea-DPfuhswM.js +0 -1
  403. package/dist/elements/chunks/variant-custom-D5ZlmziF.js +0 -1
  404. package/dist/elements/chunks/video-Bb86fVYI.js +0 -1
  405. package/dist/elements/chunks/x-BOhjBeOd.js +0 -1
  406. package/dist/primitives/card-validate-generator.testlib.d.ts +0 -20
  407. package/dist/register-impl-DGmGzrEM.js +0 -145
  408. package/dist/variant-custom-MkTNTycd.js +0 -1
  409. package/src/primitives/card-validate-generator.testlib.ts +0 -38
package/dist/schemas.js CHANGED
@@ -1,114 +1,114 @@
1
- var R = Object.defineProperty;
2
- var P = (e, t, i) => t in e ? R(e, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : e[t] = i;
3
- var w = (e, t, i) => P(e, typeof t != "symbol" ? t + "" : t, i);
4
- const N = "https://json-schema.org/draft/2020-12/schema", _ = "https://kitn.ai/schemas/card/artifact.schema.json", D = "ArtifactCardData", z = "Generated-artifact viewer payload: a framed preview plus the source files behind it. A deliberately NARROW subset of the Artifact component's props — it says WHAT to show, never how the viewer behaves. Toolbar composition, view-state and the iframe `sandbox` are host-owned and stay off the wire, so a model cannot widen its own sandbox or hide the chrome the user needs to inspect what it built.", M = "object";
5
- const U = [{ required: ["src"] }, { required: ["files"] }], F = { src: { type: "string", format: "uri", description: "URL the preview iframe frames, and the target of the Home button. Omit for a source-only artifact (`tab: 'code'` with `files`).", "x-kai-format": "url" }, files: { type: "array", description: "Files behind the artifact: the Code tab's tree, each optionally carrying its own preview url and source.", maxItems: 500, items: { type: "object", required: ["path"], additionalProperties: !1, properties: { path: { type: "string", description: "Tree label/key. Folders are built from `/`-delimited segments.", maxLength: 1024 }, url: { type: "string", format: "uri", description: "Where the preview loads this file. Defaults to `path` resolved against `src`.", "x-kai-format": "url" }, code: { type: "string", description: "Source shown in the Code tab. Omit for binary files (image/pdf), which have no code view." }, language: { type: "string", description: "Language id for syntax highlighting (e.g. 'html', 'css', 'tsx').", maxLength: 40 }, type: { type: "string", enum: ["html", "pdf", "image", "other"], description: "File kind. Drives the tree icon and whether the Code view applies; 'pdf' also routes the preview to the inline PDF viewer.", "x-kai-control": "select" }, additions: { type: "integer", minimum: 0, description: "Lines added vs the base. Rendered as a trailing '+N' stat." }, deletions: { type: "integer", minimum: 0, description: "Lines removed vs the base. Rendered as a trailing '-N' stat." }, status: { type: "string", enum: ["added", "modified", "deleted", "renamed", "untracked"], description: "Change status vs the base. Drives a trailing status letter in the conventional VCS hue.", "x-kai-control": "select" } } } }, tab: { type: "string", enum: ["preview", "code"], default: "preview", description: "Which view the card OPENS on. SEED ONLY: the user can switch freely afterwards and a revision of this card will NOT move them back, because the user's choice wins over the model's. A switch is reported back as a `state` patch.", "x-kai-control": "select" }, activeFile: { type: "string", description: "Path of the file selected in the tree when the card FIRST renders (must match a `files[].path`). Seeds the tree highlight, the Code source and the preview. SEED ONLY, like `tab`: revising this card will not move a user who has since selected a different file.", maxLength: 1024 }, displayUrl: { type: "string", description: "Friendly address shown in the path field INSTEAD of the real url, which also makes the field read-only. Use when `src` is not consumer-facing (e.g. a `data:` blob) so a clean address is shown rather than leaking it.", maxLength: 2048 }, height: { description: "Frame height. A bare number is px; a string is any CSS length. Defaults to 420px. REQUIRED CONCEPT, not decoration: the viewer is built to fill its container, and a message thread supplies no height, so the card sets one explicitly or the artifact collapses to zero and renders invisible.", oneOf: [{ type: "number", minimum: 1 }, { type: "string", maxLength: 32 }] } }, J = {
6
- $schema: N,
7
- $id: _,
8
- title: D,
9
- description: z,
10
- type: M,
1
+ var z = Object.defineProperty;
2
+ var M = (e, t, i) => t in e ? z(e, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : e[t] = i;
3
+ var w = (e, t, i) => M(e, typeof t != "symbol" ? t + "" : t, i);
4
+ const U = "https://json-schema.org/draft/2020-12/schema", F = "https://kitn.ai/schemas/card/artifact.schema.json", J = "ArtifactCardData", B = "Generated-artifact viewer payload: a framed preview plus the source files behind it. A deliberately NARROW subset of the Artifact component's props — it says WHAT to show, never how the viewer behaves. Toolbar composition, view-state and the iframe `sandbox` are host-owned and stay off the wire, so a model cannot widen its own sandbox or hide the chrome the user needs to inspect what it built.", Y = "object";
5
+ const H = [{ required: ["src"] }, { required: ["files"] }], K = { src: { type: "string", format: "uri", description: "URL the preview iframe frames, and the target of the Home button. Omit for a source-only artifact (`tab: 'code'` with `files`).", "x-kai-format": "url" }, files: { type: "array", description: "Files behind the artifact: the Code tab's tree, each optionally carrying its own preview url and source.", maxItems: 500, items: { type: "object", required: ["path"], additionalProperties: !1, properties: { path: { type: "string", description: "Tree label/key. Folders are built from `/`-delimited segments.", maxLength: 1024 }, url: { type: "string", format: "uri", description: "Where the preview loads this file. Defaults to `path` resolved against `src`.", "x-kai-format": "url" }, code: { type: "string", description: "Source shown in the Code tab. Omit for binary files (image/pdf), which have no code view." }, language: { type: "string", description: "Language id for syntax highlighting (e.g. 'html', 'css', 'tsx').", maxLength: 40 }, type: { type: "string", enum: ["html", "pdf", "image", "other"], description: "File kind. Drives the tree icon and whether the Code view applies; 'pdf' also routes the preview to the inline PDF viewer.", "x-kai-control": "select" }, additions: { type: "integer", minimum: 0, description: "Lines added vs the base. Rendered as a trailing '+N' stat." }, deletions: { type: "integer", minimum: 0, description: "Lines removed vs the base. Rendered as a trailing '-N' stat." }, status: { type: "string", enum: ["added", "modified", "deleted", "renamed", "untracked"], description: "Change status vs the base. Drives a trailing status letter in the conventional VCS hue.", "x-kai-control": "select" } } } }, tab: { type: "string", enum: ["preview", "code"], default: "preview", description: "Which view the card OPENS on. SEED ONLY: the user can switch freely afterwards and a revision of this card will NOT move them back, because the user's choice wins over the model's. A switch is reported back as a `state` patch.", "x-kai-control": "select" }, activeFile: { type: "string", description: "Path of the file selected in the tree when the card FIRST renders (must match a `files[].path`). Seeds the tree highlight, the Code source and the preview. SEED ONLY, like `tab`: revising this card will not move a user who has since selected a different file.", maxLength: 1024 }, displayUrl: { type: "string", description: "Friendly address shown in the path field INSTEAD of the real url, which also makes the field read-only. Use when `src` is not consumer-facing (e.g. a `data:` blob) so a clean address is shown rather than leaking it.", maxLength: 2048 }, height: { description: "Frame height. A bare number is px; a string is any CSS length. Defaults to 420px. REQUIRED CONCEPT, not decoration: the viewer is built to fill its container, and a message thread supplies no height, so the card sets one explicitly or the artifact collapses to zero and renders invisible.", oneOf: [{ type: "number", minimum: 1 }, { type: "string", maxLength: 32 }] } }, W = {
6
+ $schema: U,
7
+ $id: F,
8
+ title: J,
9
+ description: B,
10
+ type: Y,
11
11
  additionalProperties: !1,
12
- anyOf: U,
13
- properties: F
14
- }, Y = "https://json-schema.org/draft/2020-12/schema", B = "https://kitn.ai/schemas/card/card-envelope.schema.json", H = "CardEnvelope", K = "A card the agent/server asks the chat to render. `data` validates against the per-type schema.", W = "object", V = ["type", "id", "data"], G = { type: { type: "string", minLength: 1 }, id: { type: "string", minLength: 1 }, data: {}, title: { type: "string" } }, Q = {
15
- $schema: Y,
16
- $id: B,
17
- title: H,
18
- description: K,
19
- type: W,
20
- required: V,
21
- properties: G
22
- }, X = "https://json-schema.org/draft/2020-12/schema", Z = "https://kitn.ai/schemas/card/card-event.schema.json", ee = "CardEvent", te = "An event a card emits up to the host. `kind` discriminates the payload.", ie = "object", ne = ["kind"], se = { kind: { enum: ["ready", "submit", "action", "send-prompt", "open", "resize", "state", "dismiss", "error"] }, cardId: { type: "string" } }, oe = {
23
- $schema: X,
24
- $id: Z,
25
- title: ee,
26
- description: te,
27
- type: ie,
28
- required: ne,
29
- properties: se
30
- }, re = "https://json-schema.org/draft/2020-12/schema", ae = "https://kitn.ai/schemas/card/choice.schema.json", pe = "ChoiceCardData", de = "Data payload for a `choice` card (CardEnvelope.data when type='choice'). A single-select 'pick one of N rich options' card; activating an option emits the `action` verb.", ce = "object", ue = ["options"], le = { prompt: { type: "string", description: "Optional question/body text rendered above the options. Distinct from CardEnvelope.title (the card chrome heading)." }, submitLabel: { type: "string", description: "Label for the Submit button; default 'Submit'." }, options: { type: "array", minItems: 1, description: "The selectable options, rendered in order. Exactly one can be chosen.", items: { type: "object", required: ["id", "label"], properties: { id: { type: "string", minLength: 1, description: "Emitted as CardEvent.action. Must be unique within `options`. (The reserved id '__other__' is used by the allowOther escape.)", "x-kai-unique": !0 }, label: { type: "string", minLength: 1, description: "Visible option label." }, description: { type: "string", description: "Optional secondary line under the label." }, media: { type: "object", description: "Optional leading media: an image URL or a named icon.", properties: { image: { type: "string", description: "Image URL rendered as a leading thumbnail in the row." }, imageAlt: { type: "string", description: "Accessible alt text for `image` (decorative if omitted)." }, icon: { type: "string", description: "Named icon rendered as a leading glyph." } } }, meta: { type: "string", description: "Trailing freeform text (e.g. a price or badge), right-aligned in the row." }, recommended: { type: "boolean", default: !1, description: "Renders a small 'Recommended' pill near the label." }, disabled: { type: "boolean", default: !1, description: "Option is shown but not selectable, and skipped in keyboard nav." }, payload: { description: "Optional opaque payload echoed back in CardEvent.payload (any JSON)." } } } }, allowOther: { description: "Optional free-text escape ('none of these / specify'). `true` appends a final 'Other…' option; an object customizes its `label`/`placeholder`. Selecting it reveals a text input; the shared Submit button then emits `{ kind:'action', action:'__other__', payload:{ text } }`.", "x-kai-control": "allow-other" }, dismissible: { type: "boolean", default: !1, description: "Show a close affordance that emits the `dismiss` verb. The card collapses to a re-openable 'dismissed' stub; the host decides via `onReopen` whether it comes back live or `expired`." } }, me = {
31
- $schema: re,
32
- $id: ae,
33
- title: pe,
34
- description: de,
35
- type: ce,
36
- required: ue,
37
- properties: le
38
- }, he = "https://json-schema.org/draft/2020-12/schema", ye = "https://kitn.ai/schemas/card/confirm.schema.json", fe = "ConfirmCardData", ge = "Data payload for a `confirm` card (CardEnvelope.data when type='confirm').", be = "object", $e = ["actions"], ve = { heading: { type: "string", description: "Optional in-body heading. Distinct from CardEnvelope.title (the card chrome title)." }, body: { type: "string", description: "Body text. Plain text in v1 (rendered safely; no HTML injection)." }, tone: { type: "string", enum: ["default", "warning", "danger"], default: "default", description: "Overall card tone; 'danger' adds a warning icon + accent for destructive approvals.", "x-kai-control": "tone" }, actions: { type: "array", minItems: 1, maxItems: 4, description: "The choice set. Rendered as buttons in order; max 4 keeps it a decision, not a menu.", items: { type: "object", required: ["id", "label"], properties: { id: { type: "string", minLength: 1, description: "Emitted as CardEvent.action. Must be unique within `actions`.", "x-kai-unique": !0 }, label: { type: "string", minLength: 1, description: "Visible button label." }, style: { type: "string", enum: ["primary", "default", "destructive"], default: "default", description: "Button emphasis. 'destructive' = red/danger; 'primary' = filled accent.", "x-kai-control": "button-style" }, payload: { description: "Optional opaque payload echoed back in CardEvent.payload (any JSON)." }, default: { type: "boolean", default: !1, description: "If true, this action is the keyboard default (Enter) and gets initial focus. At most one should be true; the card uses the first if several are.", "x-kai-default-action": !0 } } } }, dismissible: { type: "boolean", default: !1, description: "Show a close affordance that emits the `dismiss` verb." } }, we = {
39
- $schema: he,
40
- $id: ye,
41
- title: fe,
42
- description: ge,
43
- type: be,
44
- required: $e,
45
- properties: ve
46
- }, xe = "https://json-schema.org/draft/2020-12/schema", ke = "https://kitn.ai/schemas/card/embed.schema.json", Oe = "EmbedCardData", je = "Lazy media-embed payload (YouTube / Vimeo / generic player URL).", Se = "object", Ae = ["provider"], Ie = !1, qe = { provider: { type: "string", enum: ["youtube", "vimeo", "generic"], description: "Media provider. 'generic' frames `url` directly (must be an https embeddable player URL whose origin is app-allowlisted).", "x-kai-control": "select" }, id: { type: "string", description: "Provider video id (required for youtube/vimeo when `url` is absent). e.g. 'dQw4w9WgXcQ'.", maxLength: 64, pattern: "^[A-Za-z0-9_-]+$" }, url: { type: "string", format: "uri", description: "Full media/watch URL. For youtube/vimeo it is parsed to an id; for 'generic' it is the embeddable player src (https only).", "x-kai-format": "url" }, title: { type: "string", description: "Accessible title for the player iframe + the poster label. Strongly recommended for a11y.", maxLength: 300 }, poster: { type: "string", format: "uri", description: "Thumbnail shown before play. When omitted, youtube/vimeo derive a default thumbnail; 'generic' shows a neutral play placeholder.", "x-kai-format": "url" }, start: { type: "integer", minimum: 0, description: "Optional start offset in seconds.", "x-kai-unit": "seconds" }, aspectRatio: { type: "string", enum: ["16:9", "4:3", "1:1", "9:16"], default: "16:9", description: "Player box aspect ratio (CSS aspect-ratio).", "x-kai-control": "select" } }, Le = [{ if: { properties: { provider: { const: "generic" } } }, then: { required: ["url"] } }, { if: { properties: { provider: { enum: ["youtube", "vimeo"] } } }, then: { anyOf: [{ required: ["id"] }, { required: ["url"] }] } }], Ce = {
47
- $schema: xe,
48
- $id: ke,
49
- title: Oe,
50
- description: je,
51
- type: Se,
52
- required: Ae,
53
- additionalProperties: Ie,
54
- properties: qe,
55
- allOf: Le
56
- }, Ee = "https://json-schema.org/draft/2020-12/schema", Te = "https://kitn.ai/schemas/card/form.result.schema.json", Re = "kai-form submit payload", Pe = "The CardEvent {kind:'submit'} `data` for a form card: an object that validates against the form-definition schema that was sent down in CardEnvelope.data. Standard JSON Schema validation (type/enum/required/min-max/length/pattern) holds. Optional empty strings are omitted.", Ne = "object", _e = {
57
- $schema: Ee,
58
- $id: Te,
59
- title: Re,
60
- description: Pe,
61
- type: Ne
62
- }, De = "https://json-schema.org/draft/2020-12/schema", ze = "https://kitn.ai/schemas/card/form.schema.json", Me = "kai-form data (a form definition)", Ue = "The CardEnvelope.data for a card of type 'form': a JSON Schema (type:'object') describing the fields kai-form renders, plus optional x-kai-* UI hints. The same schema validates the submission.", Fe = "object", Je = ["type", "properties"], Ye = { type: { const: "object" }, title: { type: "string" }, description: { type: "string" }, required: { type: "array", items: { type: "string" } }, properties: { type: "object" }, "x-kai-order": { type: "array", items: { type: "string" } }, "x-kai-inlineMax": { type: "integer", minimum: 1 }, "x-kai-submitLabel": { type: "string" }, "x-kai-dismissible": { type: "boolean" }, "x-kai-actions": { type: "array", items: { type: "object", required: ["id", "label"], properties: { id: { type: "string" }, label: { type: "string" }, variant: { enum: ["default", "ghost", "outline"] } } } } }, Be = {
63
- $schema: De,
64
- $id: ze,
65
- title: Me,
66
- description: Ue,
67
- type: Fe,
68
- required: Je,
69
- properties: Ye
70
- }, He = "https://json-schema.org/draft/2020-12/schema", Ke = "https://kitn.ai/schemas/card/link.schema.json", We = "LinkPreviewData", Ve = "Rich link / Open-Graph preview payload. The card renders from this; it never fetches.", Ge = "object", Qe = ["url"], Xe = !1, Ze = { url: { type: "string", format: "uri", description: "Canonical destination. Opened via the contract `open` verb (target 'tab').", "x-kai-format": "url" }, title: { type: "string", description: "OG title (og:title). Falls back to the domain when absent.", maxLength: 300 }, description: { type: "string", description: "OG description (og:description). Clamped to 3 lines in the UI.", maxLength: 1e3 }, image: { type: "string", format: "uri", description: "Preview image (og:image). Optional; the card degrades gracefully when missing or it fails to load.", "x-kai-format": "url" }, imageAlt: { type: "string", description: "Alt text for the preview image. Defaults to the title (or empty = decorative) when omitted.", maxLength: 300 }, favicon: { type: "string", format: "uri", description: "Site favicon shown next to the domain.", "x-kai-format": "url" }, domain: { type: "string", description: "Display domain (e.g. 'example.com'). Derived from `url` when omitted.", maxLength: 253 }, siteName: { type: "string", description: "OG site name (og:site_name). Shown in place of the domain when present.", maxLength: 200 } }, et = {
71
- $schema: He,
72
- $id: Ke,
73
- title: We,
74
- description: Ve,
75
- type: Ge,
76
- required: Qe,
77
- additionalProperties: Xe,
78
- properties: Ze
79
- }, tt = "https://json-schema.org/draft/2020-12/schema", it = "https://kitn.ai/schemas/card/tasks.result.schema.json", nt = "TasksCardResult", st = "Payload of CardEvent { kind: 'submit' } from a tasks card.", ot = "object", rt = ["selected"], at = { selected: { type: "array", description: "Ids of the checked tasks, in the order they appear in `tasks`. Subset of the input task ids.", items: { type: "string", minLength: 1 }, uniqueItems: !0 } }, pt = {
80
- $schema: tt,
81
- $id: it,
82
- title: nt,
83
- description: st,
84
- type: ot,
85
- required: rt,
86
- properties: at
87
- }, dt = "https://json-schema.org/draft/2020-12/schema", ct = "https://kitn.ai/schemas/card/tasks.schema.json", ut = "TasksCardData", lt = "Data payload for a `tasks` card (CardEnvelope.data when type='tasks').", mt = "object", ht = ["tasks"], yt = { mode: { type: "string", enum: ["select", "progress"], default: "select", description: "'select' (default) = toggle + a confirm button that emits `submit`. 'progress' = an onboarding-checklist look (header `done / total` count, circular indicators, per-item title/description, no confirm button, where checking a row IS the action). Both share the selection model.", "x-kai-mode": !0 }, heading: { type: "string", description: "Optional in-body heading; distinct from CardEnvelope.title." }, tasks: { type: "array", minItems: 1, description: "The selectable rows, rendered in order.", items: { type: "object", required: ["id", "label"], properties: { id: { type: "string", minLength: 1, description: "Stable id; the selected ids are returned in the result. Unique within `tasks`.", "x-kai-unique": !0 }, label: { type: "string", minLength: 1, description: "Row label." }, description: { type: "string", description: "Optional secondary line under the label." }, checked: { type: "boolean", default: !1, description: "Initial checked state of the row." }, disabled: { type: "boolean", default: !1, description: "Row is shown but not toggleable (and excluded from select-all)." } } } }, selectAll: { type: "boolean", default: !1, description: "Render a master select-all checkbox above the list.", "x-kai-control": "select-all" }, confirmLabel: { type: "string", default: "Confirm", description: "Label for the confirm button." }, allowEmpty: { type: "boolean", default: !1, description: "If true, confirm is enabled with zero selected (emits { selected: [] }). If false, confirm is disabled until >=1 selected." }, min: { type: "integer", minimum: 0, description: "Optional minimum number that must be selected to confirm.", "x-kai-select-min": !0 }, max: { type: "integer", minimum: 1, description: "Optional maximum selectable; further toggles are blocked once reached.", "x-kai-select-max": !0 }, dismissible: { type: "boolean", default: !1, description: "Show a close affordance that emits the `dismiss` verb. The card collapses to a re-openable 'dismissed' stub; the host decides via `onReopen` whether it comes back live or `expired`." } }, ft = {
88
- $schema: dt,
89
- $id: ct,
90
- title: ut,
91
- description: lt,
92
- type: mt,
93
- required: ht,
94
- properties: yt
12
+ anyOf: H,
13
+ properties: K
14
+ }, V = "https://json-schema.org/draft/2020-12/schema", G = "https://kitn.ai/schemas/card/card-envelope.schema.json", X = "CardEnvelope", Q = "A card the agent/server asks the chat to render. `data` validates against the per-type schema.", Z = "object", ee = ["type", "id", "data"], te = { type: { type: "string", minLength: 1 }, id: { type: "string", minLength: 1 }, data: {}, title: { type: "string" } }, ie = {
15
+ $schema: V,
16
+ $id: G,
17
+ title: X,
18
+ description: Q,
19
+ type: Z,
20
+ required: ee,
21
+ properties: te
22
+ }, ne = "https://json-schema.org/draft/2020-12/schema", oe = "https://kitn.ai/schemas/card/card-event.schema.json", re = "CardEvent", se = "An event a card emits up to the host. `kind` discriminates the payload.", ae = "object", pe = ["kind"], de = { kind: { enum: ["ready", "submit", "action", "send-prompt", "open", "resize", "state", "dismiss", "error"] }, cardId: { type: "string" } }, ce = {
23
+ $schema: ne,
24
+ $id: oe,
25
+ title: re,
26
+ description: se,
27
+ type: ae,
28
+ required: pe,
29
+ properties: de
30
+ }, ue = "https://json-schema.org/draft/2020-12/schema", le = "https://kitn.ai/schemas/card/choice.schema.json", me = "ChoiceCardData", he = "Data payload for a `choice` card (CardEnvelope.data when type='choice'). A single-select 'pick one of N rich options' card; activating an option emits the `action` verb.", fe = "object", ye = ["options"], ge = { prompt: { type: "string", description: "Optional question/body text rendered above the options. Distinct from CardEnvelope.title (the card chrome heading)." }, submitLabel: { type: "string", description: "Label for the Submit button; default 'Submit'." }, options: { type: "array", minItems: 1, description: "The selectable options, rendered in order. Exactly one can be chosen.", items: { type: "object", required: ["id", "label"], properties: { id: { type: "string", minLength: 1, description: "Emitted as CardEvent.action. Must be unique within `options`. (The reserved id '__other__' is used by the allowOther escape.)", "x-kai-unique": !0 }, label: { type: "string", minLength: 1, description: "Visible option label." }, description: { type: "string", description: "Optional secondary line under the label." }, media: { type: "object", description: "Optional leading media: an image URL or a named icon.", properties: { image: { type: "string", description: "Image URL rendered as a leading thumbnail in the row." }, imageAlt: { type: "string", description: "Accessible alt text for `image` (decorative if omitted)." }, icon: { type: "string", description: "Named icon rendered as a leading glyph." } } }, meta: { type: "string", description: "Trailing freeform text (e.g. a price or badge), right-aligned in the row." }, recommended: { type: "boolean", default: !1, description: "Renders a small 'Recommended' pill near the label." }, disabled: { type: "boolean", default: !1, description: "Option is shown but not selectable, and skipped in keyboard nav." }, payload: { description: "Optional opaque payload echoed back in CardEvent.payload (any JSON)." } } } }, allowOther: { description: "Optional free-text escape ('none of these / specify'). `true` appends a final 'Other…' option; an object customizes its `label`/`placeholder`. Selecting it reveals a text input; the shared Submit button then emits `{ kind:'action', action:'__other__', payload:{ text } }`.", "x-kai-control": "allow-other" }, dismissible: { type: "boolean", default: !1, description: "Show a close affordance that emits the `dismiss` verb. The card collapses to a re-openable 'dismissed' stub; the host decides via `onReopen` whether it comes back live or `expired`." } }, be = {
31
+ $schema: ue,
32
+ $id: le,
33
+ title: me,
34
+ description: he,
35
+ type: fe,
36
+ required: ye,
37
+ properties: ge
38
+ }, ve = "https://json-schema.org/draft/2020-12/schema", $e = "https://kitn.ai/schemas/card/confirm.schema.json", we = "ConfirmCardData", xe = "Data payload for a `confirm` card (CardEnvelope.data when type='confirm').", ke = "object", Oe = ["actions"], je = { heading: { type: "string", description: "Optional in-body heading. Distinct from CardEnvelope.title (the card chrome title)." }, body: { type: "string", description: "Body text. Plain text in v1 (rendered safely; no HTML injection)." }, tone: { type: "string", enum: ["default", "warning", "danger"], default: "default", description: "Overall card tone; 'danger' adds a warning icon + accent for destructive approvals.", "x-kai-control": "tone" }, actions: { type: "array", minItems: 1, maxItems: 4, description: "The choice set. Rendered as buttons in order; max 4 keeps it a decision, not a menu.", items: { type: "object", required: ["id", "label"], properties: { id: { type: "string", minLength: 1, description: "Emitted as CardEvent.action. Must be unique within `actions`.", "x-kai-unique": !0 }, label: { type: "string", minLength: 1, description: "Visible button label." }, style: { type: "string", enum: ["primary", "default", "destructive"], default: "default", description: "Button emphasis. 'destructive' = red/danger; 'primary' = filled accent.", "x-kai-control": "button-style" }, payload: { description: "Optional opaque payload echoed back in CardEvent.payload (any JSON)." }, default: { type: "boolean", default: !1, description: "If true, this action is the keyboard default (Enter) and gets initial focus. At most one should be true; the card uses the first if several are.", "x-kai-default-action": !0 } } } }, dismissible: { type: "boolean", default: !1, description: "Show a close affordance that emits the `dismiss` verb." } }, Se = {
39
+ $schema: ve,
40
+ $id: $e,
41
+ title: we,
42
+ description: xe,
43
+ type: ke,
44
+ required: Oe,
45
+ properties: je
46
+ }, Ae = "https://json-schema.org/draft/2020-12/schema", qe = "https://kitn.ai/schemas/card/embed.schema.json", Ie = "EmbedCardData", Le = "Lazy media-embed payload (YouTube / Vimeo / generic player URL).", Ee = "object", Te = ["provider"], Ce = !1, Re = { provider: { type: "string", enum: ["youtube", "vimeo", "generic"], description: "Media provider. 'generic' frames `url` directly (must be an https embeddable player URL whose origin is app-allowlisted).", "x-kai-control": "select" }, id: { type: "string", description: "Provider video id (required for youtube/vimeo when `url` is absent). e.g. 'dQw4w9WgXcQ'.", maxLength: 64, pattern: "^[A-Za-z0-9_-]+$" }, url: { type: "string", format: "uri", description: "Full media/watch URL. For youtube/vimeo it is parsed to an id; for 'generic' it is the embeddable player src (https only).", "x-kai-format": "url" }, title: { type: "string", description: "Accessible title for the player iframe + the poster label. Strongly recommended for a11y.", maxLength: 300 }, poster: { type: "string", format: "uri", description: "Thumbnail shown before play. When omitted, youtube/vimeo derive a default thumbnail; 'generic' shows a neutral play placeholder.", "x-kai-format": "url" }, start: { type: "integer", minimum: 0, description: "Optional start offset in seconds.", "x-kai-unit": "seconds" }, aspectRatio: { type: "string", enum: ["16:9", "4:3", "1:1", "9:16"], default: "16:9", description: "Player box aspect ratio (CSS aspect-ratio).", "x-kai-control": "select" } }, Ne = [{ if: { properties: { provider: { const: "generic" } } }, then: { required: ["url"] } }, { if: { properties: { provider: { enum: ["youtube", "vimeo"] } } }, then: { anyOf: [{ required: ["id"] }, { required: ["url"] }] } }], Pe = {
47
+ $schema: Ae,
48
+ $id: qe,
49
+ title: Ie,
50
+ description: Le,
51
+ type: Ee,
52
+ required: Te,
53
+ additionalProperties: Ce,
54
+ properties: Re,
55
+ allOf: Ne
56
+ }, _e = "https://json-schema.org/draft/2020-12/schema", De = "https://kitn.ai/schemas/card/form.result.schema.json", ze = "kai-form submit payload", Me = "The CardEvent {kind:'submit'} `data` for a form card: an object that validates against the form-definition schema that was sent down in CardEnvelope.data. Standard JSON Schema validation (type/enum/required/min-max/length/pattern) holds. Optional empty strings are omitted.", Ue = "object", Fe = {
57
+ $schema: _e,
58
+ $id: De,
59
+ title: ze,
60
+ description: Me,
61
+ type: Ue
62
+ }, Je = "https://json-schema.org/draft/2020-12/schema", Be = "https://kitn.ai/schemas/card/form.schema.json", Ye = "kai-form data (a form definition)", He = "The CardEnvelope.data for a card of type 'form': a JSON Schema (type:'object') describing the fields kai-form renders, plus optional x-kai-* UI hints. The same schema validates the submission.", Ke = "object", We = ["type", "properties"], Ve = { type: { const: "object" }, title: { type: "string" }, description: { type: "string" }, required: { type: "array", items: { type: "string" } }, properties: { type: "object" }, "x-kai-order": { type: "array", items: { type: "string" } }, "x-kai-inlineMax": { type: "integer", minimum: 1 }, "x-kai-submitLabel": { type: "string" }, "x-kai-dismissible": { type: "boolean" }, "x-kai-actions": { type: "array", items: { type: "object", required: ["id", "label"], properties: { id: { type: "string" }, label: { type: "string" }, variant: { enum: ["default", "ghost", "outline"] } } } } }, Ge = {
63
+ $schema: Je,
64
+ $id: Be,
65
+ title: Ye,
66
+ description: He,
67
+ type: Ke,
68
+ required: We,
69
+ properties: Ve
70
+ }, Xe = "https://json-schema.org/draft/2020-12/schema", Qe = "https://kitn.ai/schemas/card/link.schema.json", Ze = "LinkPreviewData", et = "Rich link / Open-Graph preview payload. The card renders from this; it never fetches.", tt = "object", it = ["url"], nt = !1, ot = { url: { type: "string", format: "uri", description: "Canonical destination. Opened via the contract `open` verb (target 'tab').", "x-kai-format": "url" }, title: { type: "string", description: "OG title (og:title). Falls back to the domain when absent.", maxLength: 300 }, description: { type: "string", description: "OG description (og:description). Clamped to 3 lines in the UI.", maxLength: 1e3 }, image: { type: "string", format: "uri", description: "Preview image (og:image). Optional; the card degrades gracefully when missing or it fails to load.", "x-kai-format": "url" }, imageAlt: { type: "string", description: "Alt text for the preview image. Defaults to the title (or empty = decorative) when omitted.", maxLength: 300 }, favicon: { type: "string", format: "uri", description: "Site favicon shown next to the domain.", "x-kai-format": "url" }, domain: { type: "string", description: "Display domain (e.g. 'example.com'). Derived from `url` when omitted.", maxLength: 253 }, siteName: { type: "string", description: "OG site name (og:site_name). Shown in place of the domain when present.", maxLength: 200 } }, rt = {
71
+ $schema: Xe,
72
+ $id: Qe,
73
+ title: Ze,
74
+ description: et,
75
+ type: tt,
76
+ required: it,
77
+ additionalProperties: nt,
78
+ properties: ot
79
+ }, st = "https://json-schema.org/draft/2020-12/schema", at = "https://kitn.ai/schemas/card/tasks.result.schema.json", pt = "TasksCardResult", dt = "Payload of CardEvent { kind: 'submit' } from a tasks card.", ct = "object", ut = ["selected"], lt = { selected: { type: "array", description: "Ids of the checked tasks, in the order they appear in `tasks`. Subset of the input task ids.", items: { type: "string", minLength: 1 }, uniqueItems: !0 } }, mt = {
80
+ $schema: st,
81
+ $id: at,
82
+ title: pt,
83
+ description: dt,
84
+ type: ct,
85
+ required: ut,
86
+ properties: lt
87
+ }, ht = "https://json-schema.org/draft/2020-12/schema", ft = "https://kitn.ai/schemas/card/tasks.schema.json", yt = "TasksCardData", gt = "Data payload for a `tasks` card (CardEnvelope.data when type='tasks').", bt = "object", vt = ["tasks"], $t = { mode: { type: "string", enum: ["select", "progress"], default: "select", description: "'select' (default) = toggle + a confirm button that emits `submit`. 'progress' = an onboarding-checklist look (header `done / total` count, circular indicators, per-item title/description, no confirm button, where checking a row IS the action). Both share the selection model.", "x-kai-mode": !0 }, heading: { type: "string", description: "Optional in-body heading; distinct from CardEnvelope.title." }, tasks: { type: "array", minItems: 1, description: "The selectable rows, rendered in order.", items: { type: "object", required: ["id", "label"], properties: { id: { type: "string", minLength: 1, description: "Stable id; the selected ids are returned in the result. Unique within `tasks`.", "x-kai-unique": !0 }, label: { type: "string", minLength: 1, description: "Row label." }, description: { type: "string", description: "Optional secondary line under the label." }, checked: { type: "boolean", default: !1, description: "Initial checked state of the row." }, disabled: { type: "boolean", default: !1, description: "Row is shown but not toggleable (and excluded from select-all)." } } } }, selectAll: { type: "boolean", default: !1, description: "Render a master select-all checkbox above the list.", "x-kai-control": "select-all" }, confirmLabel: { type: "string", default: "Confirm", description: "Label for the confirm button." }, allowEmpty: { type: "boolean", default: !1, description: "If true, confirm is enabled with zero selected (emits { selected: [] }). If false, confirm is disabled until >=1 selected." }, min: { type: "integer", minimum: 0, description: "Optional minimum number that must be selected to confirm.", "x-kai-select-min": !0 }, max: { type: "integer", minimum: 1, description: "Optional maximum selectable; further toggles are blocked once reached.", "x-kai-select-max": !0 }, dismissible: { type: "boolean", default: !1, description: "Show a close affordance that emits the `dismiss` verb. The card collapses to a re-openable 'dismissed' stub; the host decides via `onReopen` whether it comes back live or `expired`." } }, wt = {
88
+ $schema: ht,
89
+ $id: ft,
90
+ title: yt,
91
+ description: gt,
92
+ type: bt,
93
+ required: vt,
94
+ properties: $t
95
95
  }, S = "kai_";
96
- function q(e) {
96
+ function C(e) {
97
97
  if (!e.startsWith(S)) return null;
98
98
  const t = e.slice(S.length);
99
99
  return t.length > 0 ? t : null;
100
100
  }
101
- function gt(e) {
101
+ function R(e) {
102
102
  return `${S}${e}`;
103
103
  }
104
- function Ht(e) {
105
- return q(e) !== null;
104
+ function oi(e) {
105
+ return C(e) !== null;
106
106
  }
107
- function Kt(e, t, i) {
108
- const s = q(e);
109
- return s === null ? null : { type: s, id: i.id, data: t === void 0 ? {} : t };
107
+ function ri(e, t, i) {
108
+ const n = C(e);
109
+ return n === null ? null : { type: n, id: i.id, data: t === void 0 ? {} : t };
110
110
  }
111
- const L = (e) => Object.freeze(e), C = Object.freeze({
111
+ const N = (e) => Object.freeze(e), P = Object.freeze({
112
112
  id: "openai",
113
113
  label: "OpenAI strict",
114
114
  source: "https://developers.openai.com/api/docs/guides/structured-outputs",
@@ -117,7 +117,7 @@ const L = (e) => Object.freeze(e), C = Object.freeze({
117
117
  requireAllPropertiesRequired: !0,
118
118
  allowRootAnyOf: !1,
119
119
  allowRecursion: !0,
120
- keywords: L({
120
+ keywords: N({
121
121
  // core
122
122
  type: { status: "supported", note: "String, Number, Boolean, Integer, Object, Array are the supported types" },
123
123
  properties: { status: "supported", note: "objects are a supported type" },
@@ -196,7 +196,7 @@ const L = (e) => Object.freeze(e), C = Object.freeze({
196
196
  dependentRequired: { status: "unsupported", note: "explicitly listed as not supported under Composition" },
197
197
  dependentSchemas: { status: "unsupported", note: "explicitly listed as not supported under Composition" }
198
198
  })
199
- }), E = Object.freeze({
199
+ }), _ = Object.freeze({
200
200
  id: "anthropic",
201
201
  label: "Anthropic strict",
202
202
  source: "https://platform.claude.com/docs/en/build-with-claude/structured-outputs#json-schema-limitations",
@@ -206,7 +206,7 @@ const L = (e) => Object.freeze(e), C = Object.freeze({
206
206
  requireAllPropertiesRequired: !1,
207
207
  allowRootAnyOf: !0,
208
208
  allowRecursion: !1,
209
- keywords: L({
209
+ keywords: N({
210
210
  // core
211
211
  type: { status: "supported", note: "all basic types: object, array, string, integer, number, boolean, null" },
212
212
  properties: { status: "supported", note: "objects are a supported type" },
@@ -286,93 +286,93 @@ const L = (e) => Object.freeze(e), C = Object.freeze({
286
286
  dependentRequired: { status: "unsupported", note: "not in the supported list" },
287
287
  dependentSchemas: { status: "unsupported", note: "not in the supported list" }
288
288
  })
289
- }), Wt = Object.freeze({
290
- openai: C,
291
- anthropic: E
292
- }), bt = ["items", "if", "then", "else", "not", "contains", "propertyNames", "unevaluatedItems", "additionalItems"], $t = ["properties", "patternProperties", "$defs", "definitions", "dependentSchemas"], vt = ["allOf", "anyOf", "oneOf", "prefixItems"], O = (e) => typeof e == "object" && e !== null && !Array.isArray(e);
293
- function wt(e, t) {
289
+ }), si = Object.freeze({
290
+ openai: P,
291
+ anthropic: _
292
+ }), xt = ["items", "if", "then", "else", "not", "contains", "propertyNames", "unevaluatedItems", "additionalItems"], kt = ["properties", "patternProperties", "$defs", "definitions", "dependentSchemas"], Ot = ["allOf", "anyOf", "oneOf", "prefixItems"], O = (e) => typeof e == "object" && e !== null && !Array.isArray(e);
293
+ function jt(e, t) {
294
294
  return e === "(root)" ? t : `${e}.${t}`;
295
295
  }
296
- function xt(e, t) {
296
+ function St(e, t) {
297
297
  const i = [];
298
298
  return x(e, t, "(root)", !0, i), i;
299
299
  }
300
- function x(e, t, i, s, a) {
300
+ function x(e, t, i, n, r) {
301
301
  if (typeof e == "boolean") return;
302
302
  if (!O(e)) {
303
- a.push({ path: i, keyword: "(schema)", reason: `expected a schema object, got ${e === null ? "null" : typeof e}` });
303
+ r.push({ path: i, keyword: "(schema)", reason: `expected a schema object, got ${e === null ? "null" : typeof e}` });
304
304
  return;
305
305
  }
306
306
  for (const [p, c] of Object.entries(e)) {
307
- const u = t.keywords[p];
308
- if (!u) {
309
- a.push({
307
+ const l = t.keywords[p];
308
+ if (!l) {
309
+ r.push({
310
310
  path: i,
311
311
  keyword: p,
312
312
  reason: p.startsWith("x-") ? `vendor extension keyword, not in the ${t.label} subset` : `unknown keyword, not classified by the ${t.label} subset`
313
313
  });
314
314
  continue;
315
315
  }
316
- if (u.status === "unsupported") {
317
- a.push({ path: i, keyword: p, reason: `not supported (${u.note})` });
316
+ if (l.status === "unsupported") {
317
+ r.push({ path: i, keyword: p, reason: `not supported (${l.note})` });
318
318
  continue;
319
319
  }
320
- if (u.status === "supported" && u.value) {
321
- const h = u.value(c);
322
- h && a.push({ path: i, keyword: p, reason: h });
320
+ if (l.status === "supported" && l.value) {
321
+ const h = l.value(c);
322
+ h && r.push({ path: i, keyword: p, reason: h });
323
323
  }
324
324
  }
325
- const n = O(e.properties), r = e.type === "object" || n;
326
- if (r && t.requireAdditionalPropertiesFalse && e.additionalProperties !== !1 && a.push({
325
+ const o = O(e.properties), a = e.type === "object" || o;
326
+ if (a && t.requireAdditionalPropertiesFalse && e.additionalProperties !== !1 && r.push({
327
327
  path: i,
328
328
  keyword: "additionalProperties",
329
329
  reason: `missing; ${t.label} requires \`additionalProperties: false\` on every object`
330
- }), r && !n && a.push({
330
+ }), a && !o && r.push({
331
331
  path: i,
332
332
  keyword: "properties",
333
333
  reason: `a free-form object (\`type: "object"\` with no \`properties\`) has no grammar under ${t.label}; with the mandatory \`additionalProperties: false\` it can only ever be \`{}\`, which is not what the schema means`
334
- }), r && t.requireAllPropertiesRequired && n) {
335
- const p = Array.isArray(e.required) ? e.required.map(String) : [], c = Object.keys(e.properties).filter((u) => !p.includes(u));
336
- c.length > 0 && a.push({
334
+ }), a && t.requireAllPropertiesRequired && o) {
335
+ const p = Array.isArray(e.required) ? e.required.map(String) : [], c = Object.keys(e.properties).filter((l) => !p.includes(l));
336
+ c.length > 0 && r.push({
337
337
  path: i,
338
338
  keyword: "required",
339
- reason: `${t.label} requires every property in \`required\`; missing ${c.map((u) => `\`${u}\``).join(", ")} (emulate optional with a \`null\` union)`
339
+ reason: `${t.label} requires every property in \`required\`; missing ${c.map((l) => `\`${l}\``).join(", ")} (emulate optional with a \`null\` union)`
340
340
  });
341
341
  }
342
- s && !t.allowRootAnyOf && "anyOf" in e && a.push({
342
+ n && !t.allowRootAnyOf && "anyOf" in e && r.push({
343
343
  path: i,
344
344
  keyword: "anyOf",
345
345
  reason: `${t.label} forbids \`anyOf\` at the ROOT ("Root level object of a schema must be an object, and not use anyOf")`
346
346
  }), Object.keys(e).filter((p) => {
347
347
  var c;
348
348
  return ((c = t.keywords[p]) == null ? void 0 : c.status) !== "annotation";
349
- }).length === 0 && a.push({
349
+ }).length === 0 && r.push({
350
350
  path: i,
351
351
  keyword: "type",
352
352
  reason: `unconstrained subschema (annotations only); ${t.label} compiles the schema to a grammar and has no way to express "any JSON". Give it a \`type\``
353
353
  });
354
- const m = (p) => {
354
+ const u = (p) => {
355
355
  var c;
356
356
  return ((c = t.keywords[p]) == null ? void 0 : c.status) === "unsupported";
357
357
  };
358
- for (const p of $t) {
358
+ for (const p of kt) {
359
359
  const c = e[p];
360
- if (!(!O(c) || m(p)))
361
- for (const [u, h] of Object.entries(c))
362
- x(h, t, p === "properties" ? wt(i, u) : `${i}/${p}[${u}]`, !1, a);
360
+ if (!(!O(c) || u(p)))
361
+ for (const [l, h] of Object.entries(c))
362
+ x(h, t, p === "properties" ? jt(i, l) : `${i}/${p}[${l}]`, !1, r);
363
363
  }
364
- for (const p of bt) {
365
- if (!(p in e) || m(p)) continue;
364
+ for (const p of xt) {
365
+ if (!(p in e) || u(p)) continue;
366
366
  const c = e[p];
367
- typeof c != "boolean" && x(c, t, p === "items" ? `${i === "(root)" ? "(root)" : i}[]` : `${i}/${p}`, !1, a);
367
+ typeof c != "boolean" && x(c, t, p === "items" ? `${i === "(root)" ? "(root)" : i}[]` : `${i}/${p}`, !1, r);
368
368
  }
369
- O(e.additionalProperties) && x(e.additionalProperties, t, `${i}/additionalProperties`, !1, a);
370
- for (const p of vt) {
369
+ O(e.additionalProperties) && x(e.additionalProperties, t, `${i}/additionalProperties`, !1, r);
370
+ for (const p of Ot) {
371
371
  const c = e[p];
372
- !Array.isArray(c) || m(p) || c.forEach((u, h) => x(u, t, `${i}/${p}[${h}]`, !1, a));
372
+ !Array.isArray(c) || u(p) || c.forEach((l, h) => x(l, t, `${i}/${p}[${h}]`, !1, r));
373
373
  }
374
374
  }
375
- const kt = Object.freeze({
375
+ const At = Object.freeze({
376
376
  confirm: "Show the user an approval card and wait for their decision before you act. Use this whenever you are about to do something consequential, destructive or irreversible.",
377
377
  choice: "Ask the user to pick exactly one option from a list of rich choices. Use this instead of asking in prose when the options are known and finite.",
378
378
  tasks: "Show the user a checklist they can tick, either to select several items for you to act on or to track progress through a sequence of steps.",
@@ -381,137 +381,230 @@ const kt = Object.freeze({
381
381
  embed: "Embed a video player (YouTube, Vimeo, or a direct player URL) inline in the conversation.",
382
382
  artifact: "Show something you built (a page, an app, a set of files) in a framed preview with its source alongside, so the user can look at both."
383
383
  });
384
- class Ot extends Error {
385
- constructor(i, s) {
386
- super(jt(i, s));
384
+ class qt extends Error {
385
+ constructor(i, n) {
386
+ super(It(i, n));
387
387
  w(this, "name", "UnsupportedCardToolSchemaError");
388
388
  w(this, "provider");
389
389
  w(this, "source");
390
390
  w(this, "cards");
391
- this.provider = i.id, this.source = i.source, this.cards = s;
391
+ this.provider = i.id, this.source = i.source, this.cards = n;
392
392
  }
393
393
  /** Every distinct keyword named across every failing card, deduped, in order. */
394
394
  get keywords() {
395
395
  const i = /* @__PURE__ */ new Set();
396
- for (const s of this.cards) for (const a of s.violations) i.add(a.keyword);
396
+ for (const n of this.cards) for (const r of n.violations) i.add(r.keyword);
397
397
  return [...i];
398
398
  }
399
399
  }
400
- function jt(e, t) {
401
- const i = [], s = t.length === 1 ? "card type" : "card types";
402
- i.push(`${t.length} ${s} cannot be a STRICT tool definition under ${e.label}:`);
403
- for (const a of t) {
404
- i.push(""), i.push(` ${a.toolName} (card type "${a.cardType}") — ${a.violations.length} problem(s):`);
405
- for (const n of a.violations)
406
- i.push(` ${n.path}: \`${n.keyword}\` — ${n.reason}`);
400
+ function It(e, t) {
401
+ const i = [], n = t.length === 1 ? "card type" : "card types";
402
+ i.push(`${t.length} ${n} cannot be a STRICT tool definition under ${e.label}:`);
403
+ for (const r of t) {
404
+ i.push(""), i.push(` ${r.toolName} (card type "${r.cardType}") — ${r.violations.length} problem(s):`);
405
+ for (const o of r.violations)
406
+ i.push(` ${o.path}: \`${o.keyword}\` — ${o.reason}`);
407
407
  }
408
408
  return i.push(""), i.push(` subset source: ${e.source} (read ${e.checkedOn})`), i.push(
409
- " Fix: drop `strict: true`. Non-strict is the default and is the mode the kit's cards are proven in; both providers accept a loose schema there and ignore what they do not compile. Rewriting a built-in card schema to fit a strict subset would change what a valid card IS, which is a card-contract change, not a projection setting."
409
+ " Fix: drop `strict: true`. Non-strict mode projects a provider-valid schema (root combinators are relaxed with the constraint restated in the description and still enforced by card validation). Rewriting a built-in card schema to fit a strict subset would change what a valid card IS, which is a card-contract change, not a projection setting."
410
410
  ), i.join(`
411
411
  `);
412
412
  }
413
- const g = (e) => typeof e == "object" && e !== null && !Array.isArray(e);
414
- function St(e) {
413
+ const f = (e) => typeof e == "object" && e !== null && !Array.isArray(e), Lt = {
414
+ artifact: "Provide `src` (a preview URL) or `files` — at least one. An envelope with neither is rejected.",
415
+ embed: "For provider 'generic', include `url`. For 'youtube'/'vimeo', include `id` or `url`."
416
+ }, Et = "The root constraint of this schema was relaxed for this provider; consult the card registry for what a valid payload is.", Tt = ["anyOf", "allOf", "oneOf", "not", "enum", "const"];
417
+ function T(e) {
418
+ if (!f(e)) return null;
419
+ const t = {};
420
+ for (const [i, n] of Object.entries(e)) t[i] = { const: n };
421
+ return { type: "object", properties: t, required: Object.keys(e) };
422
+ }
423
+ function Ct(e, t) {
424
+ return e === "anyOf" || e === "oneOf" || e === "allOf" ? Array.isArray(t) ? t.filter(f) : [] : e === "const" ? [T(t)].filter((i) => i !== null) : e === "enum" ? Array.isArray(t) ? t.map(T).filter((i) => i !== null) : [] : [];
425
+ }
426
+ function Rt(e, t) {
427
+ const i = f(e.properties) ? { ...e.properties } : {}, n = new Set(
428
+ Array.isArray(e.required) ? e.required.map(String) : []
429
+ );
430
+ for (const o of t) {
431
+ const a = Ct(o, e[o]);
432
+ if (a.length === 0) continue;
433
+ for (const u of a)
434
+ if (f(u.properties))
435
+ for (const [p, c] of Object.entries(u.properties))
436
+ p in i || (i[p] = c);
437
+ const s = a.map(
438
+ (u) => new Set(Array.isArray(u.required) ? u.required.map(String) : [])
439
+ );
440
+ if (o === "allOf")
441
+ for (const u of s) for (const p of u) n.add(p);
442
+ else {
443
+ const [u, ...p] = s;
444
+ for (const c of u)
445
+ p.every((l) => l.has(c)) && n.add(c);
446
+ }
447
+ }
448
+ Object.keys(i).length > 0 && (e.properties = i);
449
+ const r = [...n].filter((o) => o in i);
450
+ r.length > 0 && (e.required = r);
451
+ }
452
+ function Nt(e, t) {
453
+ const i = e.type;
454
+ if (i !== void 0 && i !== "object")
455
+ throw new TypeError(
456
+ `cardTools: the '${t}' card schema declares root type '${String(i)}', but a provider tool schema root must be an object (OpenAI and Anthropic reject anything else with HTTP 400). Wrap the payload in an object, or project this card with provider 'jsonschema'.`
457
+ );
458
+ e.type = "object";
459
+ }
460
+ function Pt(e, t) {
461
+ const i = Lt[t], n = Tt.filter((r) => r in e);
462
+ if (Nt(e, t), n.length !== 0) {
463
+ Rt(e, n);
464
+ for (const r of n) delete e[r];
465
+ return console.warn(
466
+ `[kai-card-tools] relaxed root ${n.join("/")} on the projected '${R(t)}' tool schema for this provider (it would be refused with HTTP 400); the constraint now lives in the description and is still enforced by card validation.`
467
+ ), i ?? Et;
468
+ }
469
+ }
470
+ function _t(e, t, i) {
471
+ for (const n of i) {
472
+ let r = e;
473
+ if (n.path !== "")
474
+ for (const a of n.path.split(".")) {
475
+ const s = f(r.properties) ? r.properties : void 0, u = s == null ? void 0 : s[a];
476
+ if (!f(u))
477
+ throw new TypeError(
478
+ `cardTools: require on '${t}': path '${n.path}' does not resolve in the schema`
479
+ );
480
+ r = u;
481
+ }
482
+ const o = r.type === "array" || r.type === void 0 && "items" in r;
483
+ if (o && n.minItems !== void 0 && (r.minItems = n.minItems), !o && n.minItems !== void 0)
484
+ throw new TypeError(
485
+ `cardTools: minItems at require path '${n.path}' applies to array nodes only, but '${n.path}' in the '${t}' schema is not one`
486
+ );
487
+ if (n.required !== void 0) {
488
+ const a = o && f(r.items) ? r.items : r, s = f(a.properties) ? a.properties : void 0;
489
+ for (const p of n.required)
490
+ if (!s || !(p in s))
491
+ throw new TypeError(
492
+ `cardTools: require on '${t}' at path '${n.path}': '${p}' is not a property of that node — a required name with no property would make the tool unsatisfiable`
493
+ );
494
+ const u = Array.isArray(a.required) ? a.required.map(String) : [];
495
+ a.required = [.../* @__PURE__ */ new Set([...u, ...n.required])];
496
+ }
497
+ }
498
+ }
499
+ function Dt(e) {
415
500
  return e === "$schema" || e === "$id" || e.startsWith("x-");
416
501
  }
417
- const At = ["items", "if", "then", "else", "not", "contains", "propertyNames", "unevaluatedItems", "additionalItems"], It = ["properties", "patternProperties", "$defs", "definitions", "dependentSchemas"], qt = ["allOf", "anyOf", "oneOf", "prefixItems"];
502
+ const zt = ["items", "if", "then", "else", "not", "contains", "propertyNames", "unevaluatedItems", "additionalItems"], Mt = ["properties", "patternProperties", "$defs", "definitions", "dependentSchemas"], Ut = ["allOf", "anyOf", "oneOf", "prefixItems"];
418
503
  function k(e, t) {
419
- if (!g(e)) return e;
504
+ if (!f(e)) return e;
420
505
  const i = {};
421
- for (const [n, r] of Object.entries(e))
422
- St(n) || (i[n] = r);
423
- for (const n of It) {
424
- const r = i[n];
425
- if (!g(r)) continue;
426
- const o = {};
427
- for (const [m, p] of Object.entries(r)) o[m] = k(p, t);
428
- i[n] = o;
506
+ for (const [o, a] of Object.entries(e))
507
+ Dt(o) || (i[o] = a);
508
+ for (const o of Mt) {
509
+ const a = i[o];
510
+ if (!f(a)) continue;
511
+ const s = {};
512
+ for (const [u, p] of Object.entries(a)) s[u] = k(p, t);
513
+ i[o] = s;
429
514
  }
430
- for (const n of At)
431
- !(n in i) || typeof i[n] == "boolean" || (i[n] = k(i[n], t));
432
- g(i.additionalProperties) && (i.additionalProperties = k(i.additionalProperties, t));
433
- for (const n of qt) {
434
- const r = i[n];
435
- Array.isArray(r) && (i[n] = r.map((o) => k(o, t)));
515
+ for (const o of zt)
516
+ !(o in i) || typeof i[o] == "boolean" || (i[o] = k(i[o], t));
517
+ f(i.additionalProperties) && (i.additionalProperties = k(i.additionalProperties, t));
518
+ for (const o of Ut) {
519
+ const a = i[o];
520
+ Array.isArray(a) && (i[o] = a.map((s) => k(s, t)));
436
521
  }
437
- const s = g(i.properties) ? i.properties : void 0, a = i.type === "object" || s !== void 0;
438
- if (a && t.closeObjects && !("additionalProperties" in i) && (i.additionalProperties = !1), a && t.requireEveryProperty && s) {
439
- const n = Array.isArray(i.required) ? i.required.map(String) : [], r = Object.keys(s);
440
- for (const o of r)
441
- n.includes(o) || (s[o] = Lt(s[o]));
442
- i.required = r;
522
+ const n = f(i.properties) ? i.properties : void 0, r = i.type === "object" || n !== void 0;
523
+ if (r && t.closeObjects && !("additionalProperties" in i) && (i.additionalProperties = !1), r && t.requireEveryProperty && n) {
524
+ const o = Array.isArray(i.required) ? i.required.map(String) : [], a = Object.keys(n);
525
+ for (const s of a)
526
+ o.includes(s) || (n[s] = Ft(n[s]));
527
+ i.required = a;
443
528
  }
444
529
  return i;
445
530
  }
446
- function Lt(e) {
447
- if (!g(e)) return e;
531
+ function Ft(e) {
532
+ if (!f(e)) return e;
448
533
  const t = { ...e };
449
534
  if ("type" in t) {
450
535
  const i = Array.isArray(t.type) ? t.type.map(String) : [String(t.type)];
451
536
  i.includes("null") || (t.type = [...i, "null"]);
452
537
  } else if (Array.isArray(t.anyOf))
453
- t.anyOf.some((i) => g(i) && i.type === "null") || (t.anyOf = [...t.anyOf, { type: "null" }]);
538
+ t.anyOf.some((i) => f(i) && i.type === "null") || (t.anyOf = [...t.anyOf, { type: "null" }]);
454
539
  else
455
540
  return t;
456
541
  return Array.isArray(t.enum) && !t.enum.includes(null) && (t.enum = [...t.enum, null]), t;
457
542
  }
458
- function Ct(e) {
543
+ function Jt(e) {
459
544
  const t = e;
460
- return g(t.schemas) ? { schemas: t.schemas, descriptions: t.descriptions ?? {} } : { schemas: e, descriptions: {} };
545
+ return f(t.schemas) ? { schemas: t.schemas, descriptions: t.descriptions ?? {} } : { schemas: e, descriptions: {} };
461
546
  }
462
- function Et(e, t, i) {
463
- const s = i[e];
464
- if (typeof s == "string" && s.length > 0) return s;
465
- const a = kt[e];
466
- if (typeof a == "string" && a.length > 0) return a;
467
- const n = t.description;
468
- return typeof n == "string" && n.length > 0 ? n : `Render a \`${e}\` card.`;
547
+ function Bt(e, t, i) {
548
+ const n = i[e];
549
+ if (typeof n == "string" && n.length > 0) return n;
550
+ const r = At[e];
551
+ if (typeof r == "string" && r.length > 0) return r;
552
+ const o = t.description;
553
+ return typeof o == "string" && o.length > 0 ? o : `Render a \`${e}\` card.`;
469
554
  }
470
555
  function v(e, t) {
471
- const i = t === void 0, s = i ? e : t;
472
- if (!g(s) || typeof s.provider != "string")
556
+ var l;
557
+ const i = t === void 0, n = i ? e : t;
558
+ if (!f(n) || typeof n.provider != "string")
473
559
  throw new TypeError('cardTools: an options object with a `provider` is required, e.g. cardTools({ provider: "openai" })');
474
- const { schemas: a, descriptions: n } = Ct(
475
- i ? Tt() : e
476
- ), r = s.strict === !0;
477
- if (s.provider === "jsonschema" && r)
560
+ const { schemas: r, descriptions: o } = Jt(
561
+ i ? Yt() : e
562
+ ), a = n.strict === !0;
563
+ if (n.provider === "jsonschema" && a)
478
564
  throw new TypeError(
479
565
  'cardTools: `strict: true` is provider-specific and cannot be checked for `provider: "jsonschema"`, because the two documented strict subsets differ (see @kitn.ai/ui/schemas provider-subsets). Pass provider "openai" or "anthropic" to project and check strictly, or drop `strict`.'
480
566
  );
481
- const o = r ? s.provider === "openai" ? C : E : null, m = {
482
- closeObjects: o !== null,
483
- requireEveryProperty: o !== null && o.requireAllPropertiesRequired
567
+ const s = a ? n.provider === "openai" ? P : _ : null, u = {
568
+ closeObjects: s !== null,
569
+ requireEveryProperty: s !== null && s.requireAllPropertiesRequired
484
570
  }, p = [], c = [];
485
- for (const [u, h] of Object.entries(a)) {
486
- const b = gt(u), f = Et(u, h, n), $ = k(h, m);
487
- if (o) {
488
- const d = xt($, o);
489
- if (d.length > 0) {
490
- c.push({ cardType: u, toolName: b, violations: d });
571
+ if (n.require !== void 0) {
572
+ for (const h of Object.keys(n.require))
573
+ if (!(h in r))
574
+ throw new TypeError(
575
+ `cardTools: require names card type '${h}', which this call does not carry (carries: ${Object.keys(r).join(", ") || "none"})`
576
+ );
577
+ }
578
+ for (const [h, $] of Object.entries(r)) {
579
+ const g = R(h), b = Bt(h, $, o), d = k($, u), m = s === null && n.provider !== "jsonschema" ? Pt(d, h) : void 0, I = m ? `${b} ${m}` : b, L = (l = n.require) == null ? void 0 : l[h];
580
+ if (L !== void 0 && _t(d, h, L), s) {
581
+ const E = St(d, s);
582
+ if (E.length > 0) {
583
+ c.push({ cardType: h, toolName: g, violations: E });
491
584
  continue;
492
585
  }
493
586
  }
494
- s.provider === "openai" ? p.push({ type: "function", function: { name: b, description: f, parameters: $, ...r ? { strict: !0 } : {} } }) : s.provider === "anthropic" ? p.push({ name: b, description: f, input_schema: $, ...r ? { strict: !0 } : {} }) : p.push({ name: b, description: f, schema: $ });
587
+ n.provider === "openai" ? p.push({ type: "function", function: { name: g, description: I, parameters: d, ...a ? { strict: !0 } : {} } }) : n.provider === "anthropic" ? p.push({ name: g, description: I, input_schema: d, ...a ? { strict: !0 } : {} }) : p.push({ name: g, description: b, schema: d });
495
588
  }
496
- if (o && c.length > 0) throw new Ot(o, c);
589
+ if (s && c.length > 0) throw new qt(s, c);
497
590
  return p;
498
591
  }
499
- function Tt() {
592
+ function Yt() {
500
593
  return j;
501
594
  }
502
- function Vt(e, t) {
595
+ function ai(e, t) {
503
596
  return e === void 0 ? v({ provider: "openai", strict: t == null ? void 0 : t.strict }) : v(e, { provider: "openai", strict: t == null ? void 0 : t.strict });
504
597
  }
505
- function Gt(e, t) {
598
+ function pi(e, t) {
506
599
  return e === void 0 ? v({ provider: "anthropic", strict: t == null ? void 0 : t.strict }) : v(e, { provider: "anthropic", strict: t == null ? void 0 : t.strict });
507
600
  }
508
- function Qt(e) {
601
+ function di(e) {
509
602
  return e === void 0 ? v({ provider: "jsonschema" }) : v(e, { provider: "jsonschema" });
510
603
  }
511
604
  function A(e) {
512
605
  return e === null ? "null" : Array.isArray(e) ? "array" : typeof e;
513
606
  }
514
- function Rt(e, t) {
607
+ function Ht(e, t) {
515
608
  switch (t) {
516
609
  case "integer":
517
610
  return typeof e == "number" && Number.isInteger(e);
@@ -527,28 +620,28 @@ function Rt(e, t) {
527
620
  return typeof e === t;
528
621
  }
529
622
  }
530
- function I(e, t, i, s) {
531
- const a = i || "(root)", n = (r, o, m = a) => {
532
- s.push({ path: m, keyword: r, message: `${m}: ${o}` });
623
+ function q(e, t, i, n) {
624
+ const r = i || "(root)", o = (a, s, u = r) => {
625
+ n.push({ path: u, keyword: a, message: `${u}: ${s}` });
533
626
  };
534
- if (e.type && !Rt(t, e.type)) {
535
- n("type", `expected ${e.type}, got ${A(t)}`);
627
+ if (e.type && !Ht(t, e.type)) {
628
+ o("type", `expected ${e.type}, got ${A(t)}`);
536
629
  return;
537
630
  }
538
- if ("const" in e && JSON.stringify(t) !== JSON.stringify(e.const) && n("const", `must equal const ${JSON.stringify(e.const)}`), e.enum && !e.enum.some((r) => JSON.stringify(r) === JSON.stringify(t)) && n("enum", `must be one of ${JSON.stringify(e.enum)}`), typeof t == "number" && (e.minimum !== void 0 && t < e.minimum && n("minimum", `< minimum ${e.minimum}`), e.maximum !== void 0 && t > e.maximum && n("maximum", `> maximum ${e.maximum}`), e.exclusiveMinimum !== void 0 && t <= e.exclusiveMinimum && n("exclusiveMinimum", "<= exclusiveMinimum"), e.exclusiveMaximum !== void 0 && t >= e.exclusiveMaximum && n("exclusiveMaximum", ">= exclusiveMaximum")), typeof t == "string" && (e.minLength !== void 0 && t.length < e.minLength && n("minLength", `shorter than minLength ${e.minLength}`), e.maxLength !== void 0 && t.length > e.maxLength && n("maxLength", `longer than maxLength ${e.maxLength}`), e.pattern !== void 0 && !new RegExp(e.pattern).test(t) && n("pattern", "does not match pattern")), Array.isArray(t) && (e.minItems !== void 0 && t.length < e.minItems && n("minItems", `fewer than minItems ${e.minItems}`), e.maxItems !== void 0 && t.length > e.maxItems && n("maxItems", `more than maxItems ${e.maxItems}`), e.uniqueItems && new Set(t.map((o) => JSON.stringify(o))).size !== t.length && n("uniqueItems", "items not unique"), e.items && t.forEach((r, o) => I(e.items, r, `${a}[${o}]`, s))), A(t) === "object") {
539
- const r = t;
540
- for (const o of e.required ?? [])
541
- (!(o in r) || r[o] === void 0) && n("required", "required", `${a}.${o}`);
631
+ if ("const" in e && JSON.stringify(t) !== JSON.stringify(e.const) && o("const", `must equal const ${JSON.stringify(e.const)}`), e.enum && !e.enum.some((a) => JSON.stringify(a) === JSON.stringify(t)) && o("enum", `must be one of ${JSON.stringify(e.enum)}`), typeof t == "number" && (e.minimum !== void 0 && t < e.minimum && o("minimum", `< minimum ${e.minimum}`), e.maximum !== void 0 && t > e.maximum && o("maximum", `> maximum ${e.maximum}`), e.exclusiveMinimum !== void 0 && t <= e.exclusiveMinimum && o("exclusiveMinimum", "<= exclusiveMinimum"), e.exclusiveMaximum !== void 0 && t >= e.exclusiveMaximum && o("exclusiveMaximum", ">= exclusiveMaximum")), typeof t == "string" && (e.minLength !== void 0 && t.length < e.minLength && o("minLength", `shorter than minLength ${e.minLength}`), e.maxLength !== void 0 && t.length > e.maxLength && o("maxLength", `longer than maxLength ${e.maxLength}`), e.pattern !== void 0 && !new RegExp(e.pattern).test(t) && o("pattern", "does not match pattern")), Array.isArray(t) && (e.minItems !== void 0 && t.length < e.minItems && o("minItems", `fewer than minItems ${e.minItems}`), e.maxItems !== void 0 && t.length > e.maxItems && o("maxItems", `more than maxItems ${e.maxItems}`), e.uniqueItems && new Set(t.map((s) => JSON.stringify(s))).size !== t.length && o("uniqueItems", "items not unique"), e.items && t.forEach((a, s) => q(e.items, a, `${r}[${s}]`, n))), A(t) === "object") {
632
+ const a = t;
633
+ for (const s of e.required ?? [])
634
+ (!(s in a) || a[s] === void 0) && o("required", "required", `${r}.${s}`);
542
635
  if (e.properties)
543
- for (const [o, m] of Object.entries(e.properties))
544
- o in r && r[o] !== void 0 && I(m, r[o], `${a}.${o}`, s);
636
+ for (const [s, u] of Object.entries(e.properties))
637
+ s in a && a[s] !== void 0 && q(u, a[s], `${r}.${s}`, n);
545
638
  }
546
639
  }
547
- function Pt(e, t) {
640
+ function Kt(e, t) {
548
641
  const i = [];
549
- return I(e, t, "", i), { valid: i.length === 0, errors: i.map((s) => s.message), issues: i };
642
+ return q(e, t, "", i), { valid: i.length === 0, errors: i.map((n) => n.message), issues: i };
550
643
  }
551
- const T = {
644
+ const D = {
552
645
  artifact: { type: "object", properties: { src: { type: "string" }, files: { type: "array", maxItems: 500, items: { type: "object", required: ["path"], properties: { path: { type: "string", maxLength: 1024 }, url: { type: "string" }, code: { type: "string" }, language: { type: "string", maxLength: 40 }, type: { type: "string", enum: ["html", "pdf", "image", "other"] }, additions: { type: "integer", minimum: 0 }, deletions: { type: "integer", minimum: 0 }, status: { type: "string", enum: ["added", "modified", "deleted", "renamed", "untracked"] } } } }, tab: { type: "string", enum: ["preview", "code"] }, activeFile: { type: "string", maxLength: 1024 }, displayUrl: { type: "string", maxLength: 2048 } } },
553
646
  choice: { type: "object", required: ["options"], properties: { prompt: { type: "string" }, submitLabel: { type: "string" }, options: { type: "array", minItems: 1, items: { type: "object", required: ["id", "label"], properties: { id: { type: "string", minLength: 1 }, label: { type: "string", minLength: 1 }, description: { type: "string" }, media: { type: "object", properties: { image: { type: "string" }, imageAlt: { type: "string" }, icon: { type: "string" } } }, meta: { type: "string" }, recommended: { type: "boolean" }, disabled: { type: "boolean" } } } }, dismissible: { type: "boolean" } } },
554
647
  confirm: { type: "object", required: ["actions"], properties: { heading: { type: "string" }, body: { type: "string" }, tone: { type: "string", enum: ["default", "warning", "danger"] }, actions: { type: "array", minItems: 1, maxItems: 4, items: { type: "object", required: ["id", "label"], properties: { id: { type: "string", minLength: 1 }, label: { type: "string", minLength: 1 }, style: { type: "string", enum: ["primary", "default", "destructive"] }, default: { type: "boolean" } } } }, dismissible: { type: "boolean" } } },
@@ -556,7 +649,7 @@ const T = {
556
649
  form: { type: "object", required: ["type", "properties"], properties: { type: { const: "object" }, title: { type: "string" }, description: { type: "string" }, required: { type: "array", items: { type: "string" } }, properties: { type: "object" }, "x-kai-order": { type: "array", items: { type: "string" } }, "x-kai-inlineMax": { type: "integer", minimum: 1 }, "x-kai-submitLabel": { type: "string" }, "x-kai-dismissible": { type: "boolean" }, "x-kai-actions": { type: "array", items: { type: "object", required: ["id", "label"], properties: { id: { type: "string" }, label: { type: "string" }, variant: { enum: ["default", "ghost", "outline"] } } } } } },
557
650
  link: { type: "object", required: ["url"], properties: { url: { type: "string" }, title: { type: "string", maxLength: 300 }, description: { type: "string", maxLength: 1e3 }, image: { type: "string" }, imageAlt: { type: "string", maxLength: 300 }, favicon: { type: "string" }, domain: { type: "string", maxLength: 253 }, siteName: { type: "string", maxLength: 200 } } },
558
651
  tasks: { type: "object", required: ["tasks"], properties: { mode: { type: "string", enum: ["select", "progress"] }, heading: { type: "string" }, tasks: { type: "array", minItems: 1, items: { type: "object", required: ["id", "label"], properties: { id: { type: "string", minLength: 1 }, label: { type: "string", minLength: 1 }, description: { type: "string" }, checked: { type: "boolean" }, disabled: { type: "boolean" } } } }, selectAll: { type: "boolean" }, confirmLabel: { type: "string" }, allowEmpty: { type: "boolean" }, min: { type: "integer", minimum: 0 }, max: { type: "integer", minimum: 1 }, dismissible: { type: "boolean" } } }
559
- }, Nt = Object.freeze({
652
+ }, Wt = Object.freeze({
560
653
  // hard: nothing to render
561
654
  type: "hard",
562
655
  required: "hard",
@@ -575,44 +668,44 @@ const T = {
575
668
  exclusiveMinimum: "soft",
576
669
  exclusiveMaximum: "soft",
577
670
  uniqueItems: "soft"
578
- }), _t = "soft";
579
- function Dt(e) {
580
- return Object.prototype.hasOwnProperty.call(T, e);
671
+ }), Vt = "soft";
672
+ function Gt(e) {
673
+ return Object.prototype.hasOwnProperty.call(D, e);
581
674
  }
582
- function zt(e, t) {
675
+ function Xt(e, t) {
583
676
  if (t && Object.prototype.hasOwnProperty.call(t, e)) {
584
677
  const i = t[e];
585
678
  if (i && typeof i == "object") return i;
586
679
  }
587
- return Dt(e) ? T[e] : null;
680
+ return Gt(e) ? D[e] : null;
588
681
  }
589
- function Mt(e) {
590
- const t = e.slice(0, 3).map((s) => s.message), i = e.length - t.length;
682
+ function Qt(e) {
683
+ const t = e.slice(0, 3).map((n) => n.message), i = e.length - t.length;
591
684
  return t.join("; ") + (i > 0 ? `; and ${i} more` : "");
592
685
  }
593
- function Ut(e, t, i) {
594
- const s = zt(e, i);
595
- if (s === null) return null;
596
- const a = Pt(s, t);
597
- if (a.valid) return { ok: !0, tier: "ok", issues: [], hard: [], summary: "" };
598
- const n = a.issues.map((o) => ({
599
- ...o,
600
- tier: Nt[o.keyword] ?? _t
601
- })), r = n.filter((o) => o.tier === "hard");
686
+ function Zt(e, t, i) {
687
+ const n = Xt(e, i);
688
+ if (n === null) return null;
689
+ const r = Kt(n, t);
690
+ if (r.valid) return { ok: !0, tier: "ok", issues: [], hard: [], summary: "" };
691
+ const o = r.issues.map((s) => ({
692
+ ...s,
693
+ tier: Wt[s.keyword] ?? Vt
694
+ })), a = o.filter((s) => s.tier === "hard");
602
695
  return {
603
696
  ok: !1,
604
- tier: r.length > 0 ? "hard" : "soft",
605
- issues: n,
606
- hard: r,
607
- summary: Mt(r.length > 0 ? r : n)
697
+ tier: a.length > 0 ? "hard" : "soft",
698
+ issues: o,
699
+ hard: a,
700
+ summary: Qt(a.length > 0 ? a : o)
608
701
  };
609
702
  }
610
- function Xt(e) {
703
+ function ci(e) {
611
704
  return `invalid card data (${e.tier}): ${e.summary}`;
612
705
  }
613
- const Ft = (e) => typeof e == "object" && e !== null && !Array.isArray(e);
614
- function Jt(e) {
615
- const t = e.map((s) => `"${s}"`).join(", "), i = e.length === 1 ? "type" : "types";
706
+ const ei = (e) => typeof e == "object" && e !== null && !Array.isArray(e);
707
+ function ti(e) {
708
+ const t = e.map((n) => `"${n}"`).join(", "), i = e.length === 1 ? "type" : "types";
616
709
  return [
617
710
  `createCardRegistry: ${e.length} custom card ${i} registered with no \`schema\`: ${t}.`,
618
711
  " They will still RENDER (their tag/component is registered), but:",
@@ -624,46 +717,46 @@ function Jt(e) {
624
717
  ].join(`
625
718
  `);
626
719
  }
627
- function Zt(e = {}) {
720
+ function ui(e = {}) {
628
721
  if (typeof e != "object" || e === null || Array.isArray(e))
629
722
  throw new TypeError('createCardRegistry: expected a spec object, e.g. createCardRegistry({ use: ["confirm"] })');
630
- const t = j, i = e.use ?? Object.keys(t), s = i.filter((d) => !Yt(d));
631
- if (s.length > 0)
723
+ const t = j, i = e.use ?? Object.keys(t), n = i.filter((d) => !ii(d));
724
+ if (n.length > 0)
632
725
  throw new TypeError(
633
- `createCardRegistry: \`use\` names ${s.length} type(s) that are not built in: ${s.map((d) => `"${d}"`).join(", ")}. The built-in types are ${Object.keys(t).join(", ")}. A card type of your own goes in \`custom\`, with its schema, not in \`use\`.`
726
+ `createCardRegistry: \`use\` names ${n.length} type(s) that are not built in: ${n.map((d) => `"${d}"`).join(", ")}. The built-in types are ${Object.keys(t).join(", ")}. A card type of your own goes in \`custom\`, with its schema, not in \`use\`.`
634
727
  );
635
- const a = new Set(i), n = Object.keys(t).filter((d) => a.has(d)), r = e.custom ?? {}, o = Object.keys(r);
636
- if (o.find((d) => d.trim().length === 0) !== void 0)
728
+ const r = new Set(i), o = Object.keys(t).filter((d) => r.has(d)), a = e.custom ?? {}, s = Object.keys(a);
729
+ if (s.find((d) => d.trim().length === 0) !== void 0)
637
730
  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.");
638
731
  const p = {};
639
- for (const d of n) p[d] = t[d];
640
- const c = {}, u = {}, h = {}, b = {}, f = [];
641
- for (const d of o) {
642
- const l = r[d];
643
- if (typeof l != "object" || l === null || Array.isArray(l))
732
+ for (const d of o) p[d] = t[d];
733
+ const c = {}, l = {}, h = {}, $ = {}, g = [];
734
+ for (const d of s) {
735
+ const m = a[d];
736
+ if (typeof m != "object" || m === null || Array.isArray(m))
644
737
  throw new TypeError(`createCardRegistry: custom card type "${d}" must be an object, e.g. { schema, tag }.`);
645
- Ft(l.schema) ? (p[d] = l.schema, b[d] = l.schema) : (delete p[d], f.push(d)), typeof l.tag == "string" && l.tag.length > 0 && (u[d] = l.tag), typeof l.component == "function" && (h[d] = l.component), typeof l.description == "string" && l.description.length > 0 && (c[d] = l.description);
738
+ ei(m.schema) ? (p[d] = m.schema, $[d] = m.schema) : (delete p[d], g.push(d)), typeof m.tag == "string" && m.tag.length > 0 && (l[d] = m.tag), typeof m.component == "function" && (h[d] = m.component), typeof m.description == "string" && m.description.length > 0 && (c[d] = m.description);
646
739
  }
647
- if (f.length > 0) {
648
- const d = e.onIncomplete ?? "warn", l = Jt(f);
649
- if (d === "throw") throw new TypeError(l);
650
- d !== "silent" && console.warn(l);
740
+ if (g.length > 0) {
741
+ const d = e.onIncomplete ?? "warn", m = ti(g);
742
+ if (d === "throw") throw new TypeError(m);
743
+ d !== "silent" && console.warn(m);
651
744
  }
652
- const $ = Object.freeze({ ...b });
745
+ const b = Object.freeze({ ...$ });
653
746
  return Object.freeze({
654
747
  schemas: Object.freeze(p),
655
748
  descriptions: Object.freeze(c),
656
- tags: Object.freeze(u),
749
+ tags: Object.freeze(l),
657
750
  components: Object.freeze(h),
658
- types: Object.freeze([...n, ...o]),
659
- builtIn: Object.freeze(n),
660
- custom: Object.freeze([...o]),
661
- incomplete: Object.freeze([...f]),
662
- validationSchemas: $,
663
- validate: (d, l) => Ut(d, l, $)
751
+ types: Object.freeze([...o, ...s]),
752
+ builtIn: Object.freeze(o),
753
+ custom: Object.freeze([...s]),
754
+ incomplete: Object.freeze([...g]),
755
+ validationSchemas: b,
756
+ validate: (d, m) => Zt(d, m, b)
664
757
  });
665
758
  }
666
- const ei = {
759
+ const li = {
667
760
  form: "kai-form",
668
761
  confirm: "kai-confirm",
669
762
  tasks: "kai-tasks",
@@ -672,46 +765,46 @@ const ei = {
672
765
  embed: "kai-embed",
673
766
  artifact: "kai-artifact"
674
767
  }, y = (e) => e, j = Object.freeze({
675
- artifact: y(J),
676
- choice: y(me),
677
- confirm: y(we),
678
- embed: y(Ce),
679
- form: y(Be),
680
- link: y(et),
681
- tasks: y(ft)
682
- }), ti = Object.freeze({
683
- "card-envelope": y(Q),
684
- "card-event": y(oe),
685
- "form.result": y(_e),
686
- "tasks.result": y(pt)
687
- }), ii = Object.freeze(
768
+ artifact: y(W),
769
+ choice: y(be),
770
+ confirm: y(Se),
771
+ embed: y(Pe),
772
+ form: y(Ge),
773
+ link: y(rt),
774
+ tasks: y(wt)
775
+ }), mi = Object.freeze({
776
+ "card-envelope": y(ie),
777
+ "card-event": y(ce),
778
+ "form.result": y(Fe),
779
+ "tasks.result": y(mt)
780
+ }), hi = Object.freeze(
688
781
  Object.keys(j)
689
782
  );
690
- function Yt(e) {
783
+ function ii(e) {
691
784
  return Object.prototype.hasOwnProperty.call(j, e);
692
785
  }
693
786
  export {
694
- E as ANTHROPIC_STRICT,
695
- ei as BUILTIN_CARD_TAGS,
696
- kt as CARD_TOOL_DESCRIPTIONS,
787
+ _ as ANTHROPIC_STRICT,
788
+ li as BUILTIN_CARD_TAGS,
789
+ At as CARD_TOOL_DESCRIPTIONS,
697
790
  S as KAI_TOOL_PREFIX,
698
- C as OPENAI_STRICT,
699
- Ot as UnsupportedCardToolSchemaError,
700
- Kt as cardFromToolCall,
701
- ii as cardSchemaNames,
791
+ P as OPENAI_STRICT,
792
+ qt as UnsupportedCardToolSchemaError,
793
+ ri as cardFromToolCall,
794
+ hi as cardSchemaNames,
702
795
  j as cardSchemas,
703
796
  v as cardTools,
704
- q as cardTypeFromToolName,
705
- Xt as cardValidationMessage,
706
- xt as checkProviderSubset,
707
- ti as contractSchemas,
708
- Zt as createCardRegistry,
709
- Yt as isCardSchemaName,
710
- Ht as isCardTool,
711
- Wt as providerSubsets,
712
- Gt as toAnthropicTools,
713
- Qt as toJsonSchemaTools,
714
- Vt as toOpenAITools,
715
- gt as toolNameForCardType,
716
- Ut as validateCardData
797
+ C as cardTypeFromToolName,
798
+ ci as cardValidationMessage,
799
+ St as checkProviderSubset,
800
+ mi as contractSchemas,
801
+ ui as createCardRegistry,
802
+ ii as isCardSchemaName,
803
+ oi as isCardTool,
804
+ si as providerSubsets,
805
+ pi as toAnthropicTools,
806
+ di as toJsonSchemaTools,
807
+ ai as toOpenAITools,
808
+ R as toolNameForCardType,
809
+ Zt as validateCardData
717
810
  };