@kitn.ai/ui 0.16.0 → 0.18.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 (493) hide show
  1. package/README.md +55 -17
  2. package/dist/components/artifact.d.ts +39 -1
  3. package/dist/components/attachment-types.d.ts +12 -0
  4. package/dist/components/attachments.d.ts +2 -10
  5. package/dist/components/card.d.ts +27 -0
  6. package/dist/components/chain-of-thought.d.ts +78 -2
  7. package/dist/components/chat-scope-picker.d.ts +7 -0
  8. package/dist/components/chat-thread.d.ts +39 -16
  9. package/dist/components/choice-card.d.ts +27 -0
  10. package/dist/components/coachmark.d.ts +49 -0
  11. package/dist/components/composer-dom.d.ts +35 -0
  12. package/dist/components/composer-highlight.d.ts +48 -0
  13. package/dist/components/composer-history.d.ts +34 -0
  14. package/dist/components/composer.d.ts +86 -0
  15. package/dist/components/confirm-card.d.ts +17 -0
  16. package/dist/components/conversation-item.d.ts +9 -0
  17. package/dist/components/conversation-list.d.ts +36 -1
  18. package/dist/components/dismissed-stub.d.ts +22 -0
  19. package/dist/components/file-tree.d.ts +15 -0
  20. package/dist/components/form.d.ts +34 -0
  21. package/dist/components/markdown.d.ts +3 -0
  22. package/dist/components/message.d.ts +71 -2
  23. package/dist/components/model-switcher.d.ts +7 -0
  24. package/dist/components/prompt-input.d.ts +13 -4
  25. package/dist/components/prompt-suggestion.d.ts +9 -1
  26. package/dist/components/reasoning.d.ts +14 -1
  27. package/dist/components/response-compare-types.d.ts +66 -0
  28. package/dist/components/response-compare.d.ts +65 -0
  29. package/dist/components/screen.d.ts +46 -0
  30. package/dist/components/tasks-card.d.ts +50 -1
  31. package/dist/components/toast.d.ts +58 -0
  32. package/dist/components/tool-types.d.ts +10 -0
  33. package/dist/components/tool.d.ts +8 -8
  34. package/dist/components/use-card-resolution.d.ts +10 -6
  35. package/dist/components/voice-input.d.ts +27 -0
  36. package/dist/components/voice-output.d.ts +33 -0
  37. package/dist/core-C8fzo39E.js +12 -0
  38. package/dist/custom-elements.json +8472 -1691
  39. package/dist/elements/agent-card.d.ts +1 -0
  40. package/dist/elements/agent-card.js +1 -0
  41. package/dist/elements/artifact.js +1 -0
  42. package/dist/elements/attachments.js +1 -0
  43. package/dist/elements/autoloader.d.ts +2 -0
  44. package/dist/elements/autoloader.js +1 -0
  45. package/dist/elements/avatar.d.ts +1 -0
  46. package/dist/elements/avatar.js +1 -0
  47. package/dist/elements/badge.d.ts +1 -0
  48. package/dist/elements/badge.js +1 -0
  49. package/dist/elements/button.d.ts +1 -0
  50. package/dist/elements/button.js +1 -0
  51. package/dist/elements/card.js +1 -0
  52. package/dist/elements/cards.d.ts +1 -0
  53. package/dist/elements/cards.js +1 -0
  54. package/dist/elements/chain-of-thought.d.ts +0 -12
  55. package/dist/elements/chain-of-thought.js +1 -0
  56. package/dist/elements/chat-scope-picker.js +1 -0
  57. package/dist/elements/chat-types.d.ts +8 -2
  58. package/dist/elements/chat-workspace.js +1 -0
  59. package/dist/elements/chat.js +1 -0
  60. package/dist/elements/checkpoint.js +1 -0
  61. package/dist/elements/choice.js +1 -0
  62. package/dist/elements/chunks/Icon-DLLBeLG5.js +1 -0
  63. package/dist/elements/chunks/action-icons-UB4V5FNq.js +1 -0
  64. package/dist/elements/chunks/arrow-left-C-gwlUmx.js +1 -0
  65. package/dist/elements/chunks/attachments-CgbErf1r.js +1 -0
  66. package/dist/elements/chunks/badge-DTQpgB6N.js +1 -0
  67. package/dist/elements/chunks/bash-InADTalH.js +1 -0
  68. package/dist/elements/chunks/button-XDUM6lXs.js +1 -0
  69. package/dist/elements/chunks/card-CBlFZ-7I.js +1 -0
  70. package/dist/elements/chunks/card-routing-C986KuUA.js +1 -0
  71. package/dist/elements/chunks/chat-thread-BIhmqwNL.js +1 -0
  72. package/dist/elements/chunks/check-hGUoVIKb.js +1 -0
  73. package/dist/elements/chunks/chevron-down-DDoaSUtO.js +1 -0
  74. package/dist/elements/chunks/chevron-right-CdGEUakB.js +1 -0
  75. package/dist/elements/chunks/circle-BKAZdmzb.js +1 -0
  76. package/dist/elements/chunks/circle-check-CmYG-y3I.js +1 -0
  77. package/dist/elements/chunks/circle-x-DewgAEym.js +1 -0
  78. package/dist/elements/chunks/cn-CU7UAWzk.js +1 -0
  79. package/dist/elements/chunks/code-block-DedwxwFI.js +1 -0
  80. package/dist/elements/chunks/collapsible-FfgmTHtM.js +1 -0
  81. package/dist/elements/chunks/composer-Cfbw5HKT.js +65 -0
  82. package/dist/elements/chunks/context-DwJmxlRE.js +1 -0
  83. package/dist/elements/chunks/conversation-list-DsCQMfPq.js +1 -0
  84. package/dist/elements/chunks/core-AYMC6_lb.js +12 -0
  85. package/dist/elements/chunks/css-M7EaDHN_.js +1 -0
  86. package/dist/elements/chunks/default-input-BuqsoENC.js +1 -0
  87. package/dist/elements/chunks/define-rGsaWsLL.js +1 -0
  88. package/dist/elements/chunks/disclosure-CwoAkpMH.js +1 -0
  89. package/dist/elements/chunks/download-DJ06G3Bz.js +1 -0
  90. package/dist/elements/chunks/dropdown-BFg8ri_R.js +1 -0
  91. package/dist/elements/chunks/ellipsis-dlN6YvGw.js +1 -0
  92. package/dist/elements/chunks/engine-javascript-vq0WuIJl.js +141 -0
  93. package/dist/elements/chunks/external-link-DBX2lc_R.js +1 -0
  94. package/dist/elements/chunks/file-text-HfwUx4F9.js +1 -0
  95. package/dist/elements/chunks/file-tree-C6Toj71u.js +1 -0
  96. package/dist/elements/chunks/folder-MYuqa9Xp.js +1 -0
  97. package/dist/elements/chunks/github-dark-dimmed-DUshB20C.js +1 -0
  98. package/dist/elements/chunks/github-light-JYsPkUQd.js +1 -0
  99. package/dist/elements/chunks/hover-card-gE7iyXdW.js +1 -0
  100. package/dist/elements/chunks/html-CPZ3oZQ7.js +1 -0
  101. package/dist/elements/chunks/icon-Vqz4ivrY.js +1 -0
  102. package/dist/elements/chunks/index-BCRhi84a.js +1 -0
  103. package/dist/elements/chunks/info-B_toFS0l.js +1 -0
  104. package/dist/elements/chunks/input-gzbHYZvQ.js +1 -0
  105. package/dist/elements/chunks/javascript-C25yR2R2.js +1 -0
  106. package/dist/elements/chunks/json-DxJze_jm.js +1 -0
  107. package/dist/elements/chunks/kbd-n49c4KZm.js +1 -0
  108. package/dist/elements/chunks/link-CKPs9yM0.js +1 -0
  109. package/dist/elements/chunks/loader-q6MamGus.js +1 -0
  110. package/dist/elements/chunks/markdown-DBrcqq4S.js +64 -0
  111. package/dist/elements/chunks/message-CTqaYI0s.js +1 -0
  112. package/dist/elements/chunks/message-feedback-Cvzm03w0.js +1 -0
  113. package/dist/elements/chunks/message-square-CUg9eRCi.js +1 -0
  114. package/dist/elements/chunks/minimize-2-l2klxP6K.js +1 -0
  115. package/dist/elements/chunks/model-switcher-CmyjiHO1.js +1 -0
  116. package/dist/elements/chunks/overlay-C8sOYqjT.js +1 -0
  117. package/dist/elements/chunks/paperclip-42Ia7xHD.js +1 -0
  118. package/dist/elements/chunks/progress-bar-tzKMWAwO.js +1 -0
  119. package/dist/elements/chunks/prompt-suggestion-D3F6vP_A.js +1 -0
  120. package/dist/elements/chunks/reasoning-BJNmmyov.js +1 -0
  121. package/dist/elements/chunks/resizable-BRsk19qI.js +1 -0
  122. package/dist/elements/chunks/rotate-cw-BgcggLHC.js +1 -0
  123. package/dist/elements/chunks/scroll-area-CgGbFFbT.js +1 -0
  124. package/dist/elements/chunks/separator-8hM4GdHE.js +1 -0
  125. package/dist/elements/chunks/settings-CaUIYOg-.js +1 -0
  126. package/dist/elements/chunks/settings-group-CYjOVIZQ.js +1 -0
  127. package/dist/elements/chunks/share-BTYM3Ddt.js +1 -0
  128. package/dist/elements/chunks/skeleton-DsTYrPUe.js +1 -0
  129. package/dist/elements/chunks/slots-DkZ-Cmha.js +1 -0
  130. package/dist/elements/chunks/star-9R3LBQ9n.js +1 -0
  131. package/dist/elements/chunks/store-CYl5Y0_u.js +1 -0
  132. package/dist/elements/chunks/svelte--5p79yCD.js +1 -0
  133. package/dist/elements/chunks/text-shimmer-CaYGv8Se.js +1 -0
  134. package/dist/elements/chunks/textarea-NEr2SLcD.js +1 -0
  135. package/dist/elements/chunks/thumbs-up-DZYZkFfc.js +1 -0
  136. package/dist/elements/chunks/toast-store-ClxVZRcc.js +1 -0
  137. package/dist/elements/chunks/tool-CHZOmoe9.js +1 -0
  138. package/dist/elements/chunks/tooltip-WpHElELC.js +1 -0
  139. package/dist/elements/chunks/triangle-alert-BlS80PUg.js +1 -0
  140. package/dist/elements/chunks/tsx-B8rCNbgL.js +1 -0
  141. package/dist/elements/chunks/typescript-RycA9KXf.js +1 -0
  142. package/dist/elements/chunks/use-card-resolution-VSVoxDeJ.js +1 -0
  143. package/dist/elements/chunks/video-DxTPZqT8.js +1 -0
  144. package/dist/elements/chunks/vue-BmIZj4XD.js +1 -0
  145. package/dist/elements/chunks/x-C1qtndxn.js +1 -0
  146. package/dist/elements/coachmark.d.ts +1 -0
  147. package/dist/elements/coachmark.js +1 -0
  148. package/dist/elements/code-block.js +1 -0
  149. package/dist/elements/command.d.ts +1 -0
  150. package/dist/elements/command.js +1 -0
  151. package/dist/elements/compare.d.ts +1 -0
  152. package/dist/elements/compare.js +1 -0
  153. package/dist/elements/composer.d.ts +1 -0
  154. package/dist/elements/composer.js +1 -0
  155. package/dist/elements/confirm-card.js +1 -0
  156. package/dist/elements/context-meter.js +1 -0
  157. package/dist/elements/conversation-list.d.ts +1 -11
  158. package/dist/elements/conversation-list.js +1 -0
  159. package/dist/elements/default-input.d.ts +20 -9
  160. package/dist/elements/define.d.ts +11 -0
  161. package/dist/elements/dialog.d.ts +1 -0
  162. package/dist/elements/dialog.js +1 -0
  163. package/dist/elements/disclosure.d.ts +37 -0
  164. package/dist/elements/editable-label.d.ts +1 -0
  165. package/dist/elements/editable-label.js +1 -0
  166. package/dist/elements/embed.js +1 -0
  167. package/dist/elements/empty.js +1 -0
  168. package/dist/elements/feedback-bar.js +1 -0
  169. package/dist/elements/file-tree.js +1 -0
  170. package/dist/elements/file-upload.js +1 -0
  171. package/dist/elements/form.js +1 -0
  172. package/dist/elements/hover-card.d.ts +1 -0
  173. package/dist/elements/hover-card.js +1 -0
  174. package/dist/elements/icon.d.ts +1 -0
  175. package/dist/elements/icon.js +1 -0
  176. package/dist/elements/image.js +1 -0
  177. package/dist/elements/input.d.ts +1 -0
  178. package/dist/elements/input.js +1 -0
  179. package/dist/elements/kbd.d.ts +1 -0
  180. package/dist/elements/kbd.js +1 -0
  181. package/dist/elements/link-preview.js +1 -0
  182. package/dist/elements/loader.js +1 -0
  183. package/dist/elements/markdown.js +1 -0
  184. package/dist/elements/menu.d.ts +1 -0
  185. package/dist/elements/menu.js +1 -0
  186. package/dist/elements/message-skills.d.ts +0 -16
  187. package/dist/elements/message-skills.js +1 -0
  188. package/dist/elements/message.js +1 -0
  189. package/dist/elements/model-switcher.d.ts +1 -11
  190. package/dist/elements/model-switcher.js +1 -0
  191. package/dist/elements/nav.d.ts +1 -0
  192. package/dist/elements/nav.js +1 -0
  193. package/dist/elements/notice.d.ts +1 -0
  194. package/dist/elements/notice.js +1 -0
  195. package/dist/elements/pane-group.d.ts +1 -0
  196. package/dist/elements/pane-group.js +1 -0
  197. package/dist/elements/pane.d.ts +1 -0
  198. package/dist/elements/pane.js +1 -0
  199. package/dist/elements/popover.js +1 -0
  200. package/dist/elements/progress-bar.d.ts +1 -0
  201. package/dist/elements/progress-bar.js +1 -0
  202. package/dist/elements/prompt-dock.d.ts +1 -0
  203. package/dist/elements/prompt-dock.js +1 -0
  204. package/dist/elements/prompt-input.d.ts +1 -9
  205. package/dist/elements/prompt-input.js +1 -0
  206. package/dist/elements/prompt-suggestions.d.ts +0 -6
  207. package/dist/elements/prompt-suggestions.js +1 -0
  208. package/dist/elements/reasoning.js +1 -0
  209. package/dist/elements/register.d.ts +10 -0
  210. package/dist/elements/remote.js +1 -0
  211. package/dist/elements/resizable.d.ts +1 -17
  212. package/dist/elements/resizable.js +1 -0
  213. package/dist/elements/response-stream.js +14 -0
  214. package/dist/elements/screen.d.ts +1 -0
  215. package/dist/elements/screen.js +1 -0
  216. package/dist/elements/scroll-area.d.ts +1 -0
  217. package/dist/elements/scroll-area.js +1 -0
  218. package/dist/elements/scroll-button.js +1 -0
  219. package/dist/elements/search.d.ts +1 -0
  220. package/dist/elements/search.js +1 -0
  221. package/dist/elements/segmented.d.ts +1 -0
  222. package/dist/elements/segmented.js +1 -0
  223. package/dist/elements/separator.d.ts +1 -0
  224. package/dist/elements/separator.js +1 -0
  225. package/dist/elements/setting-item.d.ts +1 -0
  226. package/dist/elements/setting-item.js +1 -0
  227. package/dist/elements/settings-group.d.ts +1 -0
  228. package/dist/elements/settings-group.js +1 -0
  229. package/dist/elements/skeleton.d.ts +1 -0
  230. package/dist/elements/skeleton.js +1 -0
  231. package/dist/elements/slots.d.ts +176 -0
  232. package/dist/elements/source.d.ts +0 -17
  233. package/dist/elements/source.js +1 -0
  234. package/dist/elements/status.d.ts +1 -0
  235. package/dist/elements/status.js +1 -0
  236. package/dist/elements/switch.js +1 -0
  237. package/dist/elements/tabs.d.ts +1 -0
  238. package/dist/elements/tabs.js +1 -0
  239. package/dist/elements/tasks.js +1 -0
  240. package/dist/elements/text-shimmer.js +1 -0
  241. package/dist/elements/thinking-bar.js +1 -0
  242. package/dist/elements/toast.d.ts +1 -0
  243. package/dist/elements/toast.js +1 -0
  244. package/dist/elements/tool.js +1 -0
  245. package/dist/elements/tooltip.d.ts +1 -0
  246. package/dist/elements/tooltip.js +1 -0
  247. package/dist/elements/voice-input.js +1 -0
  248. package/dist/elements/voice-output.d.ts +1 -0
  249. package/dist/elements/voice-output.js +1 -0
  250. package/dist/elements.d.ts +772 -61
  251. package/dist/engine-javascript-C1x7zo1_.js +141 -0
  252. package/dist/index.d.ts +15 -2
  253. package/dist/index.js +14405 -9810
  254. package/dist/kai.es.js +1 -0
  255. package/dist/llms/llms-full.txt +1234 -107
  256. package/dist/llms/llms.txt +4 -4
  257. package/dist/mcp.es.js +217 -6
  258. package/dist/primitives/card-contract.d.ts +20 -4
  259. package/dist/primitives/card-recovery.d.ts +55 -0
  260. package/dist/primitives/composer-model.d.ts +22 -0
  261. package/dist/primitives/composer-triggers.d.ts +19 -0
  262. package/dist/primitives/create-kai-chat.d.ts +38 -0
  263. package/dist/primitives/message-feedback.d.ts +35 -0
  264. package/dist/primitives/toast-store.d.ts +118 -0
  265. package/dist/primitives/use-speech-recognition.d.ts +26 -0
  266. package/dist/react/index.d.ts +1166 -98
  267. package/dist/react/runtime.d.ts +9 -2
  268. package/dist/react/use-kai-chat.d.ts +41 -0
  269. package/dist/react.js +575 -186
  270. package/dist/register-impl-CYWGkgbI.js +141 -0
  271. package/dist/schemas/choice.schema.json +5 -0
  272. package/dist/schemas/tasks.schema.json +7 -2
  273. package/dist/state/index.d.ts +4 -0
  274. package/dist/state/messages.d.ts +11 -0
  275. package/dist/state/stream.d.ts +22 -0
  276. package/dist/state/suggestions.d.ts +4 -0
  277. package/dist/state.js +117 -0
  278. package/dist/theme.tokens.css +87 -0
  279. package/dist/types.d.ts +4 -0
  280. package/dist/ui/agent-card.d.ts +61 -0
  281. package/dist/ui/button.d.ts +5 -2
  282. package/dist/ui/card.d.ts +61 -0
  283. package/dist/ui/collapsible.d.ts +15 -1
  284. package/dist/ui/command.d.ts +33 -0
  285. package/dist/ui/dialog.d.ts +42 -0
  286. package/dist/ui/dropdown.d.ts +95 -1
  287. package/dist/ui/editable-label.d.ts +26 -0
  288. package/dist/ui/hover-card.d.ts +13 -1
  289. package/dist/ui/icon.d.ts +18 -0
  290. package/dist/ui/input.d.ts +33 -0
  291. package/dist/ui/kbd.d.ts +21 -0
  292. package/dist/ui/nav.d.ts +62 -0
  293. package/dist/ui/notice.d.ts +31 -0
  294. package/dist/ui/overlay.d.ts +12 -0
  295. package/dist/ui/pane-grid.d.ts +58 -0
  296. package/dist/ui/pane-group.d.ts +75 -0
  297. package/dist/ui/pane.d.ts +78 -0
  298. package/dist/ui/popover.d.ts +11 -1
  299. package/dist/ui/progress-bar.d.ts +23 -0
  300. package/dist/ui/prompt-dock.d.ts +96 -0
  301. package/dist/ui/resizable.d.ts +12 -0
  302. package/dist/ui/scroll-area.d.ts +4 -0
  303. package/dist/ui/segmented.d.ts +28 -0
  304. package/dist/ui/settings-group.d.ts +32 -0
  305. package/dist/ui/skeleton.d.ts +12 -0
  306. package/dist/ui/stat.d.ts +16 -0
  307. package/dist/ui/status.d.ts +13 -0
  308. package/dist/ui/switch.d.ts +8 -1
  309. package/dist/ui/tabs.d.ts +35 -0
  310. package/dist/ui/tooltip.d.ts +20 -1
  311. package/frameworks/react/index.tsx +1100 -163
  312. package/frameworks/react/runtime.tsx +30 -1
  313. package/frameworks/react/use-kai-chat.tsx +87 -0
  314. package/llms-full.txt +1234 -107
  315. package/llms.txt +4 -4
  316. package/package.json +36 -12
  317. package/src/agent-tooling/mcp/manifest.ts +14 -0
  318. package/src/agent-tooling/mcp/tools/debug.ts +194 -6
  319. package/src/agent-tooling/mcp/tools/reference.ts +32 -0
  320. package/src/agent-tooling/mcp/tools/scaffold.ts +162 -1
  321. package/src/components/artifact.tsx +98 -13
  322. package/src/components/attachment-types.ts +13 -0
  323. package/src/components/attachments.tsx +4 -14
  324. package/src/components/card.tsx +109 -15
  325. package/src/components/chain-of-thought.tsx +210 -1
  326. package/src/components/chat-scope-picker.tsx +13 -3
  327. package/src/components/chat-thread.tsx +238 -137
  328. package/src/components/choice-card.tsx +136 -15
  329. package/src/components/coachmark.tsx +245 -0
  330. package/src/components/component-meta.json +921 -108
  331. package/src/components/composer-dom.ts +159 -0
  332. package/src/components/composer-highlight.ts +242 -0
  333. package/src/components/composer-history.ts +82 -0
  334. package/src/components/composer.tsx +979 -0
  335. package/src/components/confirm-card.tsx +69 -2
  336. package/src/components/conversation-item.tsx +69 -7
  337. package/src/components/conversation-list.tsx +134 -37
  338. package/src/components/dismissed-stub.tsx +80 -0
  339. package/src/components/file-tree.tsx +197 -47
  340. package/src/components/form-widgets.tsx +9 -7
  341. package/src/components/form.tsx +161 -20
  342. package/src/components/image.tsx +3 -5
  343. package/src/components/link-preview.tsx +5 -4
  344. package/src/components/markdown.tsx +5 -2
  345. package/src/components/message.tsx +174 -14
  346. package/src/components/model-switcher.tsx +19 -4
  347. package/src/components/prompt-input.tsx +46 -75
  348. package/src/components/prompt-suggestion.tsx +48 -16
  349. package/src/components/reasoning.tsx +29 -6
  350. package/src/components/response-compare-types.ts +127 -0
  351. package/src/components/response-compare.tsx +460 -0
  352. package/src/components/screen.tsx +176 -0
  353. package/src/components/tasks-card.tsx +374 -23
  354. package/src/components/toast.tsx +486 -0
  355. package/src/components/tool-types.ts +10 -0
  356. package/src/components/tool.tsx +22 -16
  357. package/src/components/use-card-resolution.ts +24 -8
  358. package/src/components/voice-input.tsx +102 -19
  359. package/src/components/voice-output.tsx +202 -0
  360. package/src/elements/agent-card.tsx +67 -0
  361. package/src/elements/artifact.tsx +53 -4
  362. package/src/elements/attachments.tsx +1 -0
  363. package/src/elements/autoloader.ts +89 -0
  364. package/src/elements/avatar.tsx +33 -0
  365. package/src/elements/badge.tsx +32 -0
  366. package/src/elements/button.tsx +126 -0
  367. package/src/elements/card-media.jpg +0 -0
  368. package/src/elements/card.tsx +124 -31
  369. package/src/elements/cards.tsx +81 -7
  370. package/src/elements/chain-of-thought.tsx +77 -32
  371. package/src/elements/chat-scope-picker.tsx +35 -8
  372. package/src/elements/chat-types.ts +9 -2
  373. package/src/elements/chat-workspace.tsx +157 -43
  374. package/src/elements/chat.tsx +49 -25
  375. package/src/elements/choice.tsx +71 -19
  376. package/src/elements/coachmark.tsx +90 -0
  377. package/src/elements/command.tsx +209 -0
  378. package/src/elements/compare.tsx +110 -0
  379. package/src/elements/compiled.css +1 -1
  380. package/src/elements/composer.tsx +151 -0
  381. package/src/elements/confirm-card.tsx +36 -11
  382. package/src/elements/conversation-list.tsx +80 -11
  383. package/src/elements/default-input.tsx +75 -53
  384. package/src/elements/define.tsx +47 -6
  385. package/src/elements/dialog.tsx +98 -0
  386. package/src/elements/disclosure.ts +73 -0
  387. package/src/elements/editable-label.tsx +125 -0
  388. package/src/elements/element-manifest.json +310 -0
  389. package/src/elements/element-meta.json +5954 -1605
  390. package/src/elements/element-types.d.ts +771 -60
  391. package/src/elements/file-tree.tsx +12 -2
  392. package/src/elements/file-upload.tsx +1 -1
  393. package/src/elements/form.tsx +54 -11
  394. package/src/elements/hover-card.tsx +80 -0
  395. package/src/elements/icon-names.json +48 -0
  396. package/src/elements/icon.tsx +41 -0
  397. package/src/elements/input.tsx +203 -0
  398. package/src/elements/kbd.tsx +45 -0
  399. package/src/elements/menu.tsx +217 -0
  400. package/src/elements/message.tsx +84 -55
  401. package/src/elements/model-switcher.tsx +27 -1
  402. package/src/elements/nav.tsx +87 -0
  403. package/src/elements/notice.tsx +53 -0
  404. package/src/elements/pane-group.tsx +119 -0
  405. package/src/elements/pane.tsx +129 -0
  406. package/src/elements/popover.tsx +39 -17
  407. package/src/elements/progress-bar.tsx +39 -0
  408. package/src/elements/prompt-dock.tsx +81 -0
  409. package/src/elements/prompt-input.tsx +112 -63
  410. package/src/elements/prompt-suggestions.tsx +25 -9
  411. package/src/elements/reasoning.tsx +30 -9
  412. package/src/elements/register-impl.ts +41 -3
  413. package/src/elements/register.ts +20 -3
  414. package/src/elements/remote.tsx +4 -0
  415. package/src/elements/resizable.tsx +48 -11
  416. package/src/elements/screen.tsx +90 -0
  417. package/src/elements/scroll-area.tsx +33 -0
  418. package/src/elements/search.tsx +180 -0
  419. package/src/elements/segmented.tsx +135 -0
  420. package/src/elements/separator.tsx +36 -0
  421. package/src/elements/setting-item.tsx +50 -0
  422. package/src/elements/settings-group.tsx +37 -0
  423. package/src/elements/skeleton.tsx +45 -0
  424. package/src/elements/slots.ts +607 -0
  425. package/src/elements/source.tsx +13 -6
  426. package/src/elements/status.tsx +42 -0
  427. package/src/elements/styles.css +19 -0
  428. package/src/elements/switch.tsx +89 -14
  429. package/src/elements/tabs.tsx +95 -0
  430. package/src/elements/tasks.tsx +70 -14
  431. package/src/elements/toast.tsx +89 -0
  432. package/src/elements/tool.tsx +43 -9
  433. package/src/elements/tooltip.tsx +85 -0
  434. package/src/elements/video-poster.jpg +0 -0
  435. package/src/elements/voice-input.tsx +66 -16
  436. package/src/elements/voice-output.tsx +69 -0
  437. package/src/index.ts +35 -2
  438. package/src/primitives/card-contract.ts +14 -5
  439. package/src/primitives/card-recovery.ts +149 -0
  440. package/src/primitives/card-routing.ts +3 -0
  441. package/src/primitives/card-schemas/choice.schema.json +5 -0
  442. package/src/primitives/card-schemas/tasks.schema.json +7 -2
  443. package/src/primitives/composer-model.ts +49 -0
  444. package/src/primitives/composer-triggers.ts +35 -0
  445. package/src/primitives/create-kai-chat.ts +66 -0
  446. package/src/primitives/message-feedback.ts +123 -0
  447. package/src/primitives/toast-store.ts +276 -0
  448. package/src/primitives/use-speech-recognition.ts +135 -0
  449. package/src/state/index.ts +6 -0
  450. package/src/state/messages.ts +36 -0
  451. package/src/state/stream.ts +92 -0
  452. package/src/state/suggestions.ts +9 -0
  453. package/src/types.ts +4 -0
  454. package/src/ui/agent-card.tsx +212 -0
  455. package/src/ui/button.tsx +16 -5
  456. package/src/ui/card.tsx +245 -0
  457. package/src/ui/collapsible.tsx +30 -4
  458. package/src/ui/command.tsx +99 -0
  459. package/src/ui/dialog.tsx +217 -0
  460. package/src/ui/dropdown.tsx +375 -13
  461. package/src/ui/editable-label.tsx +112 -0
  462. package/src/ui/hover-card.tsx +28 -5
  463. package/src/ui/icon.tsx +110 -0
  464. package/src/ui/input.tsx +132 -0
  465. package/src/ui/kbd.tsx +118 -0
  466. package/src/ui/nav.tsx +282 -0
  467. package/src/ui/notice.tsx +84 -0
  468. package/src/ui/overlay.tsx +108 -2
  469. package/src/ui/pane-grid.tsx +116 -0
  470. package/src/ui/pane-group.tsx +280 -0
  471. package/src/ui/pane.tsx +193 -0
  472. package/src/ui/popover.tsx +16 -2
  473. package/src/ui/progress-bar.tsx +83 -0
  474. package/src/ui/prompt-dock.tsx +145 -0
  475. package/src/ui/resizable.tsx +69 -1
  476. package/src/ui/scroll-area.tsx +14 -3
  477. package/src/ui/segmented.tsx +109 -0
  478. package/src/ui/settings-group.tsx +67 -0
  479. package/src/ui/skeleton.tsx +62 -5
  480. package/src/ui/stat.tsx +41 -0
  481. package/src/ui/status.tsx +48 -0
  482. package/src/ui/switch.tsx +49 -23
  483. package/src/ui/tabs.tsx +168 -0
  484. package/src/ui/tooltip.tsx +57 -7
  485. package/theme.css +113 -0
  486. package/dist/components/slash-command.d.ts +0 -15
  487. package/dist/kitn-chat.es.js +0 -1
  488. package/dist/register-impl-wCsFPoh9.js +0 -77
  489. package/dist/register-ujhr1nBS.js +0 -1
  490. package/src/components/slash-command.tsx +0 -232
  491. package/src/elements/framework-usage.json +0 -563
  492. /package/dist/{kitn-chat-provider.d.ts → kai-provider.d.ts} +0 -0
  493. /package/dist/{kitn-chat-provider.es.js → kai-provider.es.js} +0 -0
package/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  <!-- AUTO-GENERATED by scripts/gen-llms.mjs — do not edit by hand. Run `npm run build`. -->
2
2
  # @kitn.ai/ui
3
3
 
4
- > Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 44 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
4
+ > Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 78 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
5
5
 
6
6
  ## Install
7
7
 
@@ -13,7 +13,7 @@ npm install solid-js
13
13
 
14
14
  ## #1 rule: array/object data goes on JS PROPERTIES, not HTML attributes
15
15
 
16
- This is the single most common mistake. Arrays and objects (`messages`, `models`, `context`, `suggestions`, `slashCommands`, …) MUST be assigned as JavaScript properties on the element. They CANNOT be passed as HTML attributes — an HTML attribute is always a string and will be ignored or mis-parsed.
16
+ This is the single most common mistake. Arrays and objects (`messages`, `models`, `context`, `suggestions`, `triggers`, …) MUST be assigned as JavaScript properties on the element. They CANNOT be passed as HTML attributes — an HTML attribute is always a string and will be ignored or mis-parsed.
17
17
 
18
18
  ```js
19
19
  const chat = document.querySelector('kai-chat');
@@ -35,7 +35,7 @@ Drop an element into any framework (React, Vue, plain HTML). Data in via JS prop
35
35
  - `<kai-prompt-input>` — standalone composer with send button.
36
36
 
37
37
  **Layer 2 — composable primitives** (`import { … } from '@kitn.ai/ui'`):
38
- All 44 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
38
+ All 78 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
39
39
 
40
40
  ## Key rules for the web components
41
41
 
@@ -97,7 +97,7 @@ For Tailwind builds: `@import "@kitn.ai/ui/theme.css"` in your CSS.
97
97
 
98
98
  ## Docs
99
99
 
100
- - Full element reference (all 44 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
100
+ - Full element reference (all 78 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
101
101
  - Machine-readable Custom Elements Manifest: https://unpkg.com/@kitn.ai/ui/dist/custom-elements.json
102
102
  - Working examples: https://github.com/kitn-ai/ui/tree/main/examples
103
103
  - Storybook: https://storybook.kitn.dev
package/package.json CHANGED
@@ -1,7 +1,12 @@
1
1
  {
2
2
  "name": "@kitn.ai/ui",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "type": "module",
5
+ "sideEffects": [
6
+ "**/*.css",
7
+ "./dist/kai.es.js",
8
+ "./dist/elements/*.js"
9
+ ],
5
10
  "description": "Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. Authored in SolidJS.",
6
11
  "keywords": [
7
12
  "web-components",
@@ -33,8 +38,8 @@
33
38
  "main": "./dist/index.js",
34
39
  "module": "./dist/index.js",
35
40
  "types": "./dist/index.d.ts",
36
- "unpkg": "./dist/kitn-chat.es.js",
37
- "jsdelivr": "./dist/kitn-chat.es.js",
41
+ "unpkg": "./dist/kai.es.js",
42
+ "jsdelivr": "./dist/kai.es.js",
38
43
  "customElements": "dist/custom-elements.json",
39
44
  "bin": {
40
45
  "kai-mcp": "./bin/mcp.js"
@@ -46,7 +51,15 @@
46
51
  },
47
52
  "./elements": {
48
53
  "types": "./dist/elements.d.ts",
49
- "default": "./dist/kitn-chat.es.js"
54
+ "default": "./dist/kai.es.js"
55
+ },
56
+ "./elements/*": {
57
+ "types": "./dist/elements/*.d.ts",
58
+ "default": "./dist/elements/*.js"
59
+ },
60
+ "./autoloader": {
61
+ "types": "./dist/elements/autoloader.d.ts",
62
+ "default": "./dist/elements/autoloader.js"
50
63
  },
51
64
  "./theme.css": "./theme.css",
52
65
  "./theme.tokens.css": "./dist/theme.tokens.css",
@@ -54,9 +67,13 @@
54
67
  "types": "./dist/react/index.d.ts",
55
68
  "default": "./dist/react.js"
56
69
  },
70
+ "./state": {
71
+ "types": "./dist/state/index.d.ts",
72
+ "default": "./dist/state.js"
73
+ },
57
74
  "./provider": {
58
- "types": "./dist/kitn-chat-provider.d.ts",
59
- "default": "./dist/kitn-chat-provider.es.js"
75
+ "types": "./dist/kai-provider.d.ts",
76
+ "default": "./dist/kai-provider.es.js"
60
77
  }
61
78
  },
62
79
  "files": [
@@ -68,6 +85,7 @@
68
85
  "!src/**/*.test.tsx",
69
86
  "!src/**/*.mdx",
70
87
  "!src/stories",
88
+ "!src/elements/logos",
71
89
  "frameworks",
72
90
  "theme.css",
73
91
  "llms.txt",
@@ -76,7 +94,8 @@
76
94
  "scripts": {
77
95
  "prepublishOnly": "npm run build",
78
96
  "prebuild": "npm run build:css",
79
- "build": "vite build --config vite.config.ts && vite build --config vite.config.provider.ts && vite build --config vite.config.react.ts && vite build --config vite.config.barrel.ts && vite build --config vite.config.mcp.ts",
97
+ "build": "vite build --config vite.config.ts && vite build --config vite.config.provider.ts && vite build --config vite.config.react.ts && vite build --config vite.config.barrel.ts && vite build --config vite.config.state.ts && vite build --config vite.config.mcp.ts && npm run build:elements && node scripts/verify-elements-bundle.mjs && node scripts/verify-react-wrappers.mjs",
98
+ "build:elements": "node scripts/gen-elements-manifest.mjs && vite build --config vite.config.elements.ts && node scripts/gen-element-dts.mjs",
80
99
  "postbuild": "npm run build:theme && npm run build:api && npm run build:schemas",
81
100
  "build:theme": "node scripts/build-theme-tokens.mjs",
82
101
  "build:api": "node scripts/gen-element-api.mjs",
@@ -84,6 +103,7 @@
84
103
  "test": "vitest run",
85
104
  "test:react": "vitest run --config vitest.react.config.ts",
86
105
  "test:storybook": "vitest run --project=storybook",
106
+ "test:storybook:ci": "node scripts/run-storybook-tests.mjs",
87
107
  "test:watch": "vitest",
88
108
  "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.react.json && tsc --noEmit -p tsconfig.react.test.json && tsc --noEmit -p tsconfig.mcp.json",
89
109
  "examples": "echo 'Serving repo root on http://localhost:8000 — open http://localhost:8000/examples/composable/index.html' && python3 -m http.server 8000",
@@ -94,25 +114,28 @@
94
114
  "build:css:watch": "tailwindcss -i src/elements/styles.css -o src/elements/compiled.css --watch",
95
115
  "dev:provider": "vite examples/remote-provider --port 6007 --strictPort",
96
116
  "dev:host": "vite examples/remote-host --port 6006 --strictPort",
97
- "test:e2e": "playwright test"
117
+ "test:e2e": "playwright test",
118
+ "test:composer-ivp": "playwright test --config playwright.composer.config.ts",
119
+ "test:slots-ivp": "playwright test --config playwright.slots.config.ts",
120
+ "test:menu-ivp": "playwright test --config playwright.menu.config.ts",
121
+ "test:command-ivp": "playwright test --config playwright.command.config.ts"
98
122
  },
99
123
  "dependencies": {
100
124
  "@floating-ui/dom": "^1.7.6",
101
125
  "@modelcontextprotocol/sdk": "^1.29.0",
102
- "@shikijs/langs": "^4.2.0",
103
- "@shikijs/themes": "^4.2.0",
104
126
  "class-variance-authority": "^0.7.0",
105
127
  "clsx": "^2.1.0",
106
128
  "lucide-solid": "^0.400.0",
107
129
  "marked": "^18.0.0",
108
- "shiki": "^4.0.2",
109
130
  "solid-element": "^1.9.1",
110
131
  "solid-js": "^1.9.0",
111
- "tailwind-merge": "^2.5.0",
132
+ "tailwind-merge": "^3.0.0",
112
133
  "zod": "^4.4.3"
113
134
  },
114
135
  "devDependencies": {
115
136
  "@playwright/test": "^1.60.0",
137
+ "@shikijs/langs": "^4.2.0",
138
+ "@shikijs/themes": "^4.2.0",
116
139
  "@solidjs/testing-library": "^0.8.0",
117
140
  "@storybook/addon-a11y": "^10.4.2",
118
141
  "@storybook/addon-docs": "^10.3.5",
@@ -137,6 +160,7 @@
137
160
  "react": "^19.2.7",
138
161
  "react-dom": "^19.2.7",
139
162
  "remark-gfm": "^4.0.1",
163
+ "shiki": "^4.0.2",
140
164
  "storybook": "^10.3.5",
141
165
  "storybook-dark-mode": "^5.0.0",
142
166
  "storybook-solidjs-vite": "^10.0.12",
@@ -46,6 +46,18 @@ export interface CemCssProperty {
46
46
  default?: string;
47
47
  }
48
48
 
49
+ export interface CemSlot {
50
+ name: string;
51
+ description?: string;
52
+ }
53
+
54
+ export interface CemCssPart {
55
+ name: string;
56
+ description?: string;
57
+ /** Our extension: a copy-paste styling example. */
58
+ recipe?: string;
59
+ }
60
+
49
61
  export interface Declaration {
50
62
  tagName?: string;
51
63
  name: string;
@@ -55,6 +67,8 @@ export interface Declaration {
55
67
  attributes?: CemAttribute[];
56
68
  events?: CemEvent[];
57
69
  cssProperties?: CemCssProperty[];
70
+ slots?: CemSlot[];
71
+ cssParts?: CemCssPart[];
58
72
  }
59
73
 
60
74
  interface CemModule {
@@ -27,11 +27,11 @@ const RULES: Rule[] = [
27
27
  // Source: for-ai-agents.mdx §1; context7.json rule 2
28
28
  id: 'array-as-attribute',
29
29
  test: (t) =>
30
- /\b(messages|models|context|suggestions|slashCommands)\s*=\s*["']/.test(t),
30
+ /\b(messages|models|context|suggestions|triggers)\s*=\s*["']/.test(t),
31
31
  title: 'Array/object prop set as an HTML attribute (silent failure)',
32
32
  cause:
33
33
  'An HTML attribute is always a string. Passing `messages`, `models`, `context`, ' +
34
- '`suggestions`, or `slashCommands` as an HTML attribute silently fails — ' +
34
+ '`suggestions`, or `triggers` as an HTML attribute silently fails — ' +
35
35
  'the element receives a stringified value it cannot parse.',
36
36
  fix:
37
37
  'Set the property in JavaScript, not as an HTML attribute. ' +
@@ -72,7 +72,11 @@ const RULES: Rule[] = [
72
72
  '// ❌ Does NOT trigger re-render\n' +
73
73
  'chat.messages.push(newMsg);\n' +
74
74
  'chat.messages[i].content = accumulated;\n' +
75
- '```',
75
+ '```\n\n' +
76
+ 'The ergonomic path: helpers in `@kitn.ai/ui/state` (`appendMessage`, `updateMessage`, `appendContent`) ' +
77
+ 'and `createAssistantStream` handle the new-reference contract for you. ' +
78
+ '`useKaiChat` (React) and `createKaiChat` (Solid) own state entirely so mutation is never an option.\n\n' +
79
+ '// setMessages((m) => appendMessage(m, msg)) // new array, no footgun',
76
80
  },
77
81
  {
78
82
  // Rule 3 — listening for events on a parent / wrong element
@@ -108,15 +112,15 @@ const RULES: Rule[] = [
108
112
  title: 'Wrong element prefix `kitn-` (should be `kai-`)',
109
113
  cause:
110
114
  'The custom element prefix is `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`). ' +
111
- '`kitn-chat` is only a bundle filename — it is not a registered element name. ' +
112
- 'Using `<kitn-chat>` results in an unknown element that renders nothing.',
115
+ '`kitn-` is a legacy name (the register-all bundle is `kai.es.js`) — it is not a ' +
116
+ 'registered element name. Using `<kitn-chat>` results in an unknown element that renders nothing.',
113
117
  fix:
114
118
  'Replace the `kitn-` prefix with `kai-` everywhere.\n\n' +
115
119
  '```html\n' +
116
120
  '<!-- ✅ Correct element prefix -->\n' +
117
121
  '<kai-chat></kai-chat>\n' +
118
122
  '<kai-artifact></kai-artifact>\n\n' +
119
- '<!-- ❌ Wrong — kitn-chat is a bundle filename, not an element -->\n' +
123
+ '<!-- ❌ Wrong — kitn-chat is not an element (the bundle is kai.es.js) -->\n' +
120
124
  '<kitn-chat></kitn-chat>\n' +
121
125
  '```',
122
126
  },
@@ -223,6 +227,53 @@ const RULES: Rule[] = [
223
227
  "// Use `integration: 'mock'` in the scaffold tool\n" +
224
228
  '```',
225
229
  },
230
+ {
231
+ // Rule 9 — reduce bundle size / footprint / "how much does @kitn.ai/ui add"
232
+ // Source: dist/elements/<file>.js per-element exports; dist/autoloader.js
233
+ id: 'bundle-footprint',
234
+ test: (t) =>
235
+ /bundle\s*size|footprint|tree.?shak|how\s+much.*does.*@kitn|reduce.*import|import.*only.*element|per.?element\s+import|autoload|cdn.*no.?build|no.?build.*cdn/i.test(
236
+ t,
237
+ ),
238
+ title: 'Reducing bundle footprint — three load modes',
239
+ cause:
240
+ 'The default `import \'@kitn.ai/ui/elements\'` registers every `kai-*` element. ' +
241
+ 'If your page uses only one or two elements, that pulls in the full ~119 KB gz bundle. ' +
242
+ 'Two opt-in modes let you load only what you need.',
243
+ fix:
244
+ '**Mode 1 — register-all (default, SSR-safe):**\n' +
245
+ 'Best for multi-element apps or any SSR/meta-framework. ' +
246
+ 'Load once and every `kai-*` element is available.\n\n' +
247
+ '```js\n' +
248
+ "import '@kitn.ai/ui/elements'; // ~119 KB gz — registers everything\n" +
249
+ '```\n\n' +
250
+ '**Mode 2 — per-element import (tree-shaking, bundler apps):**\n' +
251
+ 'Use `import \'@kitn.ai/ui/elements/<file>\'` to register only one element. ' +
252
+ 'A bundler (Vite, webpack, Rollup) will tree-shake to just its chunks (~73 KB gz for `kai-chat` alone). ' +
253
+ 'Client-only — do not use in SSR entry points.\n\n' +
254
+ '```js\n' +
255
+ "// Registers only <kai-chat> (~73 KB gz vs ~119 KB gz register-all)\n" +
256
+ "import '@kitn.ai/ui/elements/chat';\n\n" +
257
+ "// Other examples:\n" +
258
+ "import '@kitn.ai/ui/elements/code-block'; // <kai-code-block>\n" +
259
+ "import '@kitn.ai/ui/elements/confirm-card'; // <kai-confirm>\n" +
260
+ '```\n\n' +
261
+ 'The file name is the element\'s source basename from `element-manifest.json` ' +
262
+ '(e.g. `kai-chat` → `chat`, `kai-confirm` → `confirm-card`).\n\n' +
263
+ '**Mode 3 — autoloader (no-build / CDN pages only):**\n' +
264
+ 'Watches the DOM and dynamically imports each `kai-*` element\'s module on demand. ' +
265
+ 'A page that uses only `<kai-chat>` never downloads the other elements. ' +
266
+ 'It is a CDN / static-file tool — load it from a `<script type="module">` tag. ' +
267
+ 'It is NOT importable through a bundler: Vite/webpack relocate it and the on-demand imports 404. ' +
268
+ 'Client-only.\n\n' +
269
+ '```html\n' +
270
+ '<script type="module" src="https://cdn.jsdelivr.net/npm/@kitn.ai/ui@<version>/dist/elements/autoloader.js"></script>\n' +
271
+ '```\n\n' +
272
+ 'In a BUNDLED app (Vite/webpack/Next) use Mode 1 or Mode 2 instead — not the autoloader.\n\n' +
273
+ '**SSR note:** use Mode 1 (register-all) in SSR apps — ' +
274
+ 'per-element imports and the autoloader are client-only (they call DOM APIs at module eval). ' +
275
+ 'Modes 1 & 2 are side-effect imports; keep them even if your linter flags them as "unused".',
276
+ },
226
277
  {
227
278
  // Rule 5 — SSR / server component / document is not defined
228
279
  // Source: for-ai-agents.mdx (client-only import); context7.json rule 2 (property rule requires DOM)
@@ -256,6 +307,143 @@ const RULES: Rule[] = [
256
307
  "import { Chat } from '@kitn.ai/ui/react';\n" +
257
308
  '```',
258
309
  },
310
+ {
311
+ // Rule 10 — toast() is the imperative API; there is no <kai-toast> to place
312
+ // Source: src/primitives/toast-store.ts (the `toast` fn + auto-mounted region)
313
+ id: 'toast-imperative',
314
+ test: (t) => {
315
+ // Placing a toast element by hand (the region auto-mounts — you never write it).
316
+ if (/<kai-toast(-region)?\b/.test(t)) return true;
317
+ // Asking how to show / trigger a toast or notification with kai context.
318
+ if (
319
+ /\btoast(s)?\b|notification|snackbar/i.test(t) &&
320
+ /how.*(show|raise|trigger|fire|display)|show.*toast|raise.*toast|trigger.*toast|toast.*(not|isn'?t|won'?t).*(show|appear|render)|where.*toast|add.*toast|kai-|@kitn/i.test(t)
321
+ )
322
+ return true;
323
+ return false;
324
+ },
325
+ title: 'Toast is an imperative call — `toast(\'…\')`, not a `<kai-toast>` you place',
326
+ cause:
327
+ 'Toasts are raised IMPERATIVELY by calling `toast(message)` — there is no ' +
328
+ '`<kai-toast>` element you add to your markup. The first call lazily mounts ONE ' +
329
+ '`<kai-toast-region>` on `document.body` (a real, kit-styled, viewport-positioned ' +
330
+ 'element) and every later toast feeds that same region. Trying to place a toast ' +
331
+ 'element by hand, or looking for a `messages`/`toasts` prop to push into, is the ' +
332
+ 'wrong model.',
333
+ fix:
334
+ 'Import `toast` and call it. It is exported from BOTH the root `@kitn.ai/ui` and ' +
335
+ 'the `@kitn.ai/ui/elements` bundle, so the web-components-only consumer gets it too. ' +
336
+ 'It is SSR-safe (no DOM is touched until the first call on the client).\n\n' +
337
+ '```js\n' +
338
+ "import { toast } from '@kitn.ai/ui/elements'; // or '@kitn.ai/ui'\n\n" +
339
+ "// ✅ Fire-and-forget\n" +
340
+ "toast('Copied to clipboard');\n" +
341
+ "toast.success('Saved');\n\n" +
342
+ "// ✅ With an Undo action + an imperative handle\n" +
343
+ "const t = toast('Item deleted', {\n" +
344
+ " action: { label: 'Undo', onAction: () => restore() },\n" +
345
+ '});\n' +
346
+ "t.update({ message: 'Restored', variant: 'success' });\n" +
347
+ 't.dismiss();\n' +
348
+ '```\n\n' +
349
+ 'The auto-mounted `<kai-toast-region>` carries its own shadow root + kit styles — ' +
350
+ 'do NOT add a `<kai-toast-region>` tag yourself unless you deliberately want a ' +
351
+ 'second, declaratively-controlled region.',
352
+ },
353
+ {
354
+ // Rule 11 — dismissed cards are DEFERRED (reopenable stub), not deleted
355
+ // Source: src/primitives/card-recovery.ts (dismissRecovery) + the dismissed stub
356
+ id: 'card-dismiss-deferred',
357
+ test: (t) => {
358
+ const cardCtx = /\bcard(s)?\b|envelope|kai-card|kai-cards|kai-confirm|kai-choice|kai-tasks|kai-form|generative.?ui|resolution|dismissRecovery/i;
359
+ if (!cardCtx.test(t)) return false;
360
+ // dismiss / reopen / undo / disappear / filter-out signals in a card context.
361
+ return /dismiss|reopen|re-?open|\bundo\b|disappear|remove.*card|card.*(gone|remove|delete|vanish)|filter.*out|stub/i.test(t);
362
+ },
363
+ title: 'Dismissed cards are DEFERRED (a reopenable stub), not deleted',
364
+ cause:
365
+ 'Dismissing a generative-UI card does NOT delete its envelope from history. The ' +
366
+ 'card stamps a `{ kind: \'dismissed\' }` resolution onto its envelope and collapses ' +
367
+ 'to a small reopenable stub ("Proposed: <title> — dismissed · Reopen"). If you ' +
368
+ 'filter `dismissed` envelopes out of your cards array, the stub vanishes and the ' +
369
+ 'user can never reopen it — and you lose the audit trail of what was proposed.',
370
+ fix:
371
+ 'Keep dismissed envelopes in the array. Wire dismiss/reopen with `dismissRecovery()` ' +
372
+ '(from `@kitn.ai/ui`), which builds the `onDismiss`/`onReopen` half of a `CardPolicy` ' +
373
+ 'over your store and can show a "Dismissed · Undo" toast via an injected adapter.\n\n' +
374
+ '```ts\n' +
375
+ "import { dismissRecovery } from '@kitn.ai/ui';\n" +
376
+ "import { toast } from '@kitn.ai/ui/elements';\n\n" +
377
+ '// Adapter: map dismissRecovery\'s toast shape onto the imperative toast().\n' +
378
+ 'const toastAdapter = {\n' +
379
+ ' show: ({ message, action, durationMs }) => {\n' +
380
+ " const handle = toast(message, {\n" +
381
+ ' duration: durationMs,\n' +
382
+ ' action: action && { label: action.label, onAction: action.onClick },\n' +
383
+ ' });\n' +
384
+ ' return { dismiss: handle.dismiss };\n' +
385
+ ' },\n' +
386
+ '};\n\n' +
387
+ 'const { onDismiss, onReopen } = dismissRecovery({\n' +
388
+ ' get: () => cards, // your current envelopes\n' +
389
+ ' set: (next) => setCards(next), // NEW array reference (never mutate in place)\n' +
390
+ ' toast: toastAdapter,\n' +
391
+ '});\n' +
392
+ '// Pass these on the CardPolicy you hand to <kai-cards> / <kai-remote>.\n' +
393
+ '```\n\n' +
394
+ '`onDismiss` writes `dismissed` immutably (Undo restores the prior resolution); ' +
395
+ '`onReopen` clears it back to live (or stamps `expired` when the host says the card ' +
396
+ 'is no longer reopenable). Never mutate the array in place — re-render needs a new ref.',
397
+ },
398
+ {
399
+ // Rule 12 — kai-compare contract: two candidates, JS data prop, stream both, terminal pick
400
+ // Source: src/elements/compare.tsx + src/components/response-compare-types.ts
401
+ id: 'compare-contract',
402
+ test: (t) => {
403
+ if (/<kai-compare\b|kai-compare-select|ResponseCompareData|response.?compare/i.test(t)) return true;
404
+ // "compare two responses / candidates / A vs B" with a kai/UI context.
405
+ if (
406
+ /compar(e|ing|ison)|side.by.side|a\/b|two\s+(responses|candidates|answers|completions)|dual.?response/i.test(t) &&
407
+ /kai-|@kitn|candidate|prefer(ence)?|chosen|reject/i.test(t)
408
+ )
409
+ return true;
410
+ return false;
411
+ },
412
+ title: '`kai-compare` — two candidates, `data` as a JS property, terminal pick',
413
+ cause:
414
+ '`<kai-compare>` shows EXACTLY two assistant candidates for one prompt and lets the ' +
415
+ 'user pick the better one. The `data` value is an array/object, so it must be set as ' +
416
+ 'a JS PROPERTY (never an HTML attribute). Both candidates can stream — but, like ' +
417
+ '`kai-chat`, that needs a NEW `data` reference per chunk (mutating in place will not ' +
418
+ 're-render). The pick is a COMMIT (not a Submit): it fires once and the card collapses.',
419
+ fix:
420
+ 'Set `data` in JS with two candidates, stream by reassigning a fresh `data` object ' +
421
+ 'per chunk, and listen for `kai-compare-select` directly on the element.\n\n' +
422
+ '```ts\n' +
423
+ "import { toast } from '@kitn.ai/ui/elements';\n" +
424
+ "import type { ResponseCompareData, CompareSelection } from '@kitn.ai/ui';\n\n" +
425
+ "const el = document.querySelector('kai-compare')!;\n" +
426
+ '// data is a JS PROPERTY — exactly two candidates, each with a unique id.\n' +
427
+ 'el.data = {\n' +
428
+ " prompt: 'Summarise the report',\n" +
429
+ ' candidates: [\n' +
430
+ " { id: 'a', content: '', streaming: true },\n" +
431
+ " { id: 'b', content: '', streaming: true },\n" +
432
+ ' ],\n' +
433
+ '} satisfies ResponseCompareData;\n\n' +
434
+ '// Stream BOTH columns: replace data with a NEW object per chunk.\n' +
435
+ "el.data = { ...el.data, candidates: [{ ...a, content: aText }, { ...b, content: bText }] };\n" +
436
+ '// Clear `streaming` on a candidate when it settles — the pick stays disabled\n' +
437
+ '// until BOTH have settled, then `kai-ready` fires.\n\n' +
438
+ "// Picking is terminal: emits { chosenId, rejectedIds, at } and collapses.\n" +
439
+ "el.addEventListener('kai-compare-select', (e) => {\n" +
440
+ ' const { chosenId, rejectedIds } = (e as CustomEvent<CompareSelection>).detail;\n' +
441
+ ' recordPreference({ prompt, chosen: chosenId, rejected: rejectedIds });\n' +
442
+ '});\n' +
443
+ '```\n\n' +
444
+ 'A malformed definition (not two candidates, missing/duplicate ids) fires `kai-error` ' +
445
+ 'instead. The event is non-bubbling — listen on the element, not on `document`.',
446
+ },
259
447
  ];
260
448
 
261
449
  function buildText(matched: Rule[]): string {
@@ -104,6 +104,38 @@ function formatReference(tag: string): string {
104
104
  }
105
105
  }
106
106
 
107
+ // ── Composition slots ──────────────────────────────────────────────────────
108
+ const slots = el.slots ?? [];
109
+ if (slots.length > 0) {
110
+ lines.push(
111
+ '',
112
+ '### Composition slots',
113
+ 'Project your own markup into these named regions — add a light-DOM child ' +
114
+ 'with a `slot="…"` attribute (e.g. `<div slot="sidebar">…</div>`).',
115
+ );
116
+ for (const slot of slots) {
117
+ const desc = slot.description?.trim() ?? '';
118
+ lines.push(`- **${slot.name}**${desc ? ` — ${desc}` : ''}`);
119
+ }
120
+ }
121
+
122
+ // ── Styleable parts (::part) ───────────────────────────────────────────────
123
+ const parts = el.cssParts ?? [];
124
+ if (parts.length > 0) {
125
+ lines.push(
126
+ '',
127
+ '### Styleable parts (`::part`)',
128
+ 'Restyle these from outside the Shadow DOM via `' + tag + '::part(name) { … }`.',
129
+ );
130
+ for (const part of parts) {
131
+ const desc = part.description?.trim() ?? '';
132
+ lines.push(`- **${part.name}**${desc ? ` — ${desc}` : ''}`);
133
+ if (part.recipe) {
134
+ lines.push(' ```css', ` ${part.recipe}`, ' ```');
135
+ }
136
+ }
137
+ }
138
+
107
139
  return lines.join('\n');
108
140
  }
109
141
 
@@ -1530,7 +1530,168 @@ function compose(
1530
1530
  envLines,
1531
1531
  ].join('\n');
1532
1532
 
1533
- return [header, block1, block2, block3].join('\n\n');
1533
+ // SCAF-16: loading-options note — inform consumers about the two opt-in load modes
1534
+ // (per-element tree-shaking + autoloader) without changing the default import above.
1535
+ // Leads with "the default is right" rather than a size headline; the debug tool
1536
+ // carries the full KB breakdown for developers who ask for it.
1537
+ const block4 = [
1538
+ `=== LOADING OPTIONS ===`,
1539
+ ``,
1540
+ `The scaffold uses \`import '@kitn.ai/ui/elements'\` (register-all) — the right`,
1541
+ `default: it registers every kai-* element and is SSR-safe, so leave it as is.`,
1542
+ `Two opt-in modes load less if a page only ever uses a few elements:`,
1543
+ ``,
1544
+ ` Per-element (bundler apps): import '@kitn.ai/ui/elements/<file>'`,
1545
+ ` Registers just that element; your bundler tree-shakes the rest away.`,
1546
+ ` Example: import '@kitn.ai/ui/elements/chat' (client-only — not for SSR)`,
1547
+ ``,
1548
+ ` Autoloader (no-build / CDN pages): a <script type="module"> tag pointing at`,
1549
+ ` dist/elements/autoloader.js — loads each kai-* element on demand as it`,
1550
+ ` appears in the DOM. A CDN/static-file tool; not importable through a bundler.`,
1551
+ ``,
1552
+ `Run the debug tool with "reduce bundle size" for the full breakdown and sizes.`,
1553
+ ].join('\n');
1554
+
1555
+ // SCAF-17: interaction patterns — small, copy-pasteable snippets for the
1556
+ // toast / card-recovery / preference-capture features. Appended as a reference
1557
+ // section so the consumer can wire confirmations, undo, and A/B preference
1558
+ // capture without leaving the scaffold. Does not change blocks 1–4.
1559
+ const block5 = interactionPatternsBlock();
1560
+
1561
+ return [header, block1, block2, block3, block4, block5].join('\n\n');
1562
+ }
1563
+
1564
+ // ── SCAF-17: reusable interaction-pattern snippets ─────────────────────────────
1565
+
1566
+ /**
1567
+ * The three interaction patterns from the chat-interactions feature set, emitted
1568
+ * as a labeled reference section the scaffolder always appends:
1569
+ * 1. `toast()` confirmation + Undo.
1570
+ * 2. `dismissRecovery()` card-policy wiring (with a toast adapter).
1571
+ * 3. `kai-compare` preference capture (two streams → kai-compare-select →
1572
+ * recordPreference({ prompt, chosen, rejected })).
1573
+ *
1574
+ * Framework-agnostic (plain TS / DOM) so it drops into any of the front-end
1575
+ * targets; the imports are valid from `@kitn.ai/ui` (and `toast` also from
1576
+ * `@kitn.ai/ui/elements`).
1577
+ */
1578
+ function interactionPatternsBlock(): string {
1579
+ const toastPattern = [
1580
+ `--- Pattern: toast() — confirmation + Undo ---`,
1581
+ `// toast is IMPERATIVE — call it; there is no <kai-toast> to place. The first`,
1582
+ `// call auto-mounts one <kai-toast-region> on document.body. Exported from`,
1583
+ `// both '@kitn.ai/ui' and '@kitn.ai/ui/elements'.`,
1584
+ `import { toast } from '@kitn.ai/ui/elements';`,
1585
+ ``,
1586
+ `toast('Copied to clipboard'); // neutral, auto-dismisses`,
1587
+ `toast.success('Saved'); // emerald success variant`,
1588
+ ``,
1589
+ `// Undo affordance: an action floors the duration so there's time to act.`,
1590
+ `const t = toast('Item deleted', {`,
1591
+ ` action: { label: 'Undo', onAction: () => restoreItem() },`,
1592
+ `});`,
1593
+ `// t.update({ message: 'Restored', variant: 'success' }); t.dismiss();`,
1594
+ ``,
1595
+ `// Collapsed (Sonner-style) stacking — toasts pile + expand on hover/focus.`,
1596
+ `// Opt in once at startup, or per-region via <kai-toast-region stack="collapsed">.`,
1597
+ `import { configureToasts } from '@kitn.ai/ui/elements';`,
1598
+ `configureToasts({ stack: 'collapsed' });`,
1599
+ ].join('\n');
1600
+
1601
+ const recoveryPattern = [
1602
+ `--- Pattern: dismissRecovery() — card dismiss + Undo (DEFERRED, not deleted) ---`,
1603
+ `// Dismissing a generative-UI card does NOT delete its envelope — it stamps a`,
1604
+ `// 'dismissed' resolution and collapses to a reopenable stub. Keep dismissed`,
1605
+ `// envelopes in your array; wire the policy with dismissRecovery().`,
1606
+ `import { dismissRecovery } from '@kitn.ai/ui';`,
1607
+ `import { toast } from '@kitn.ai/ui/elements';`,
1608
+ ``,
1609
+ `// Adapter: map dismissRecovery's toast shape onto the imperative toast().`,
1610
+ `const toastAdapter = {`,
1611
+ ` show: ({ message, action, durationMs }) => {`,
1612
+ ` const h = toast(message, {`,
1613
+ ` duration: durationMs,`,
1614
+ ` action: action && { label: action.label, onAction: action.onClick },`,
1615
+ ` });`,
1616
+ ` return { dismiss: h.dismiss };`,
1617
+ ` },`,
1618
+ `};`,
1619
+ ``,
1620
+ `const { onDismiss, onReopen } = dismissRecovery({`,
1621
+ ` get: () => cards, // your current envelopes`,
1622
+ ` set: (next) => setCards(next), // a NEW array reference (never mutate in place)`,
1623
+ ` toast: toastAdapter,`,
1624
+ `});`,
1625
+ `// Hand { onDismiss, onReopen } to the CardPolicy on <kai-cards> / <kai-remote>.`,
1626
+ ].join('\n');
1627
+
1628
+ const preferencePattern = [
1629
+ `--- Pattern: kai-compare — capture an A/B preference pair ---`,
1630
+ `// <kai-compare> shows EXACTLY two candidates for one prompt. data is a JS`,
1631
+ `// PROPERTY; stream both columns with a fresh data ref per chunk; picking is`,
1632
+ `// terminal and fires kai-compare-select { chosenId, rejectedIds }.`,
1633
+ `import type { ResponseCompareData, CompareSelection } from '@kitn.ai/ui';`,
1634
+ ``,
1635
+ `const el = document.querySelector('kai-compare')!;`,
1636
+ `el.data = {`,
1637
+ ` prompt,`,
1638
+ ` candidates: [`,
1639
+ ` { id: 'a', content: '', streaming: true },`,
1640
+ ` { id: 'b', content: '', streaming: true },`,
1641
+ ` ],`,
1642
+ `} satisfies ResponseCompareData;`,
1643
+ ``,
1644
+ `// Stream BOTH: replace data with a NEW object per chunk; clear streaming when`,
1645
+ `// a candidate settles. The pick unlocks once both have settled (kai-ready).`,
1646
+ `// el.data = { ...el.data, candidates: [{ ...a, content: aText }, { ...b, content: bText }] };`,
1647
+ ``,
1648
+ `el.addEventListener('kai-compare-select', (e) => {`,
1649
+ ` const { chosenId, rejectedIds } = (e as CustomEvent<CompareSelection>).detail;`,
1650
+ ` recordPreference({ prompt, chosen: chosenId, rejected: rejectedIds });`,
1651
+ `});`,
1652
+ ].join('\n');
1653
+
1654
+ const statePattern = [
1655
+ `--- Pattern: State helpers + streaming (new-array contract) ---`,
1656
+ `// Setter contract: always (prev) => next — every helper returns a new array.`,
1657
+ `// Vanilla adapter (works with any element ref):`,
1658
+ `// const set = (fn) => { el.messages = fn(el.messages ?? []); };`,
1659
+ ``,
1660
+ `// Low-level helpers from @kitn.ai/ui/state:`,
1661
+ `// import { appendMessage, updateMessage, appendContent, createAssistantStream } from '@kitn.ai/ui/state';`,
1662
+ ``,
1663
+ `// Streaming loop (framework-agnostic):`,
1664
+ `// const stream = createAssistantStream(set);`,
1665
+ `// stream.appendText(chunk); // text delta`,
1666
+ `// stream.appendReasoning(chunk); // reasoning delta`,
1667
+ `// stream.upsertTool(toolCall); // tool call delta`,
1668
+ `// stream.done(); // seal the message`,
1669
+ ``,
1670
+ `// One-liner for React (batteries-included):`,
1671
+ `// import { useKaiChat } from '@kitn.ai/ui/react';`,
1672
+ `// const chat = useKaiChat();`,
1673
+ `// <Chat {...chat.bind} />`,
1674
+ ``,
1675
+ `// One-liner for Solid (batteries-included):`,
1676
+ `// import { createKaiChat } from '@kitn.ai/ui';`,
1677
+ `// const chat = createKaiChat();`,
1678
+ `// <kai-chat {...chat.bind} on:kai-submit={chat.handleSubmit} />`,
1679
+ ].join('\n');
1680
+
1681
+ return [
1682
+ `=== INTERACTION PATTERNS ===`,
1683
+ ``,
1684
+ `Optional snippets for confirmations, card recovery, preference capture, and state/streaming helpers.`,
1685
+ `Drop in the one(s) you need; all imports resolve from @kitn.ai/ui.`,
1686
+ ``,
1687
+ toastPattern,
1688
+ ``,
1689
+ recoveryPattern,
1690
+ ``,
1691
+ preferencePattern,
1692
+ ``,
1693
+ statePattern,
1694
+ ].join('\n');
1534
1695
  }
1535
1696
 
1536
1697
  // ── error text ────────────────────────────────────────────────────────────────