@kitn.ai/ui 0.28.0 → 0.30.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 (615) hide show
  1. package/README.md +11 -7
  2. package/dist/{Icon-DObhsRtm.js → Icon-BzBET3E-.js} +1 -1
  3. package/dist/{action-icons-CcgNN2oT.js → action-icons-DaW2pU6m.js} +1 -1
  4. package/dist/agent-tooling/construct/public.d.ts +15 -0
  5. package/dist/agent-tooling/construct/schema.d.ts +111 -0
  6. package/dist/arrow-down-D783iMJj.js +1 -0
  7. package/dist/arrow-left-0VLM5kyg.js +1 -0
  8. package/dist/artifact-DGjzHYUT.js +1 -0
  9. package/dist/{attachments-Qr4kg-2b.js → attachments-YvXHlg88.js} +1 -1
  10. package/dist/{audio-visualizer-DToYdfSc.js → audio-visualizer-9lz5IHsL.js} +1 -1
  11. package/dist/{badge-CdEu_jn2.js → badge-Dh_vp8A5.js} +1 -1
  12. package/dist/{bell-DQAAOpDz.js → bell-CT7_WUwS.js} +1 -1
  13. package/dist/{button-DkuOnGLy.js → button-C_3te6fm.js} +1 -1
  14. package/dist/{card-renderer-Jx70m6_l.js → card-renderer-DZVaGH2e.js} +1 -1
  15. package/dist/check-CiEOVnEN.js +1 -0
  16. package/dist/{checkbox-D7iRB3nL.js → checkbox-Bu2T2e0U.js} +1 -1
  17. package/dist/{checkbox-group-B2_rpoPM.js → checkbox-group-BiryEXPQ.js} +1 -1
  18. package/dist/chevron-down-CSobuZRG.js +1 -0
  19. package/dist/chevron-right-DR9ZAP-2.js +1 -0
  20. package/dist/{choice-card-m0BYqqOK.js → choice-card-CM6IjkmL.js} +1 -1
  21. package/dist/circle-BC66EYF7.js +1 -0
  22. package/dist/circle-check-BqmahW0O.js +1 -0
  23. package/dist/{circle-x-BPG0iPst.js → circle-x-Bk-dA5Wf.js} +1 -1
  24. package/dist/{code-block-ClMLKb7C.js → code-block-B26t-Q7q.js} +1 -1
  25. package/dist/{collapsible-B4DlWicL.js → collapsible-Bhc636Cf.js} +1 -1
  26. package/dist/components/builder-composer-triggers.d.ts +62 -0
  27. package/dist/components/builder-layout.d.ts +54 -0
  28. package/dist/components/builder-message-actions.d.ts +72 -0
  29. package/dist/components/builder-panel.d.ts +189 -0
  30. package/dist/components/builder-preview.d.ts +11 -0
  31. package/dist/components/builder-shell-controls.d.ts +69 -0
  32. package/dist/components/builder-skeleton.d.ts +58 -0
  33. package/dist/components/builder-start.d.ts +75 -0
  34. package/dist/components/builder-workspace-variants.d.ts +23 -0
  35. package/dist/components/captions.d.ts +66 -0
  36. package/dist/{composer-sQ0HcvyG.js → composer-DMI85B6j.js} +1 -1
  37. package/dist/{confirm-card-rQWDQsnC.js → confirm-card-B0YIAwXp.js} +1 -1
  38. package/dist/construct-cli.es.js +3 -3
  39. package/dist/construct.d.ts +5 -0
  40. package/dist/construct.js +327 -0
  41. package/dist/{context-0kg4ZX1J.js → context-DWgfhqWp.js} +1 -1
  42. package/dist/controllable-BagRpyHv.js +1 -0
  43. package/dist/{conversation-item-BxwQLaFJ.js → conversation-item-BsOsVGmT.js} +1 -1
  44. package/dist/{conversation-list-BCfGN1JU.js → conversation-list-aX3Vtc7L.js} +1 -1
  45. package/dist/{copy-n9u9rqpi.js → copy-BmEwsNhJ.js} +1 -1
  46. package/dist/core-C8fzo39E.js +1 -12
  47. package/dist/{create-tween-uPkArjIG.js → create-tween-CNOAU3Fx.js} +1 -1
  48. package/dist/{create-tween-C-q-JCM-.js → create-tween-WfqiENls.js} +1 -1
  49. package/dist/{create-tween-CRrJXxBd.js → create-tween-wlFtW9Kh.js} +1 -1
  50. package/dist/{create-tween-DZ3RRDHD.js → create-tween-zt79ba32.js} +1 -1
  51. package/dist/{default-input-CaMrJkgH.js → default-input-DMV5Eaze.js} +1 -1
  52. package/dist/define-CI0y3eE4.js +1 -0
  53. package/dist/define.js +40 -40
  54. package/dist/define.server.js +45 -45
  55. package/dist/{disclosure-WUImBbDv.js → disclosure-NnACBxsC.js} +1 -1
  56. package/dist/{dropdown-wZVeJOMd.js → dropdown-DT7G0RGR.js} +1 -1
  57. package/dist/elements/agent-card.js +1 -1
  58. package/dist/elements/artifact.js +1 -1
  59. package/dist/elements/attachments.js +1 -1
  60. package/dist/elements/audio-visualizer.js +1 -1
  61. package/dist/elements/avatar.js +1 -1
  62. package/dist/elements/badge.js +1 -1
  63. package/dist/elements/button.js +1 -1
  64. package/dist/elements/card.js +1 -1
  65. package/dist/elements/cards.js +1 -1
  66. package/dist/elements/chain-of-thought.js +1 -1
  67. package/dist/elements/chat-scope-picker.js +1 -1
  68. package/dist/elements/chat-workspace.js +1 -1
  69. package/dist/elements/chat.js +1 -1
  70. package/dist/elements/checkbox-group.js +1 -1
  71. package/dist/elements/checkbox.js +1 -1
  72. package/dist/elements/checkpoint.js +1 -1
  73. package/dist/elements/choice.js +1 -1
  74. package/dist/elements/coachmark.js +1 -1
  75. package/dist/elements/code-block.js +1 -1
  76. package/dist/elements/command.js +1 -1
  77. package/dist/elements/compare.js +1 -1
  78. package/dist/elements/composer.js +1 -1
  79. package/dist/elements/confirm-card.js +1 -1
  80. package/dist/elements/context-meter.js +1 -1
  81. package/dist/elements/conversation-item.js +1 -1
  82. package/dist/elements/conversation-list.js +1 -1
  83. package/dist/elements/dialog.js +1 -1
  84. package/dist/elements/dock.js +1 -1
  85. package/dist/elements/dropdown.js +1 -1
  86. package/dist/elements/editable-label.js +1 -1
  87. package/dist/elements/embed.js +1 -1
  88. package/dist/elements/empty.js +1 -1
  89. package/dist/elements/feedback-bar.js +1 -1
  90. package/dist/elements/file-tree.js +1 -1
  91. package/dist/elements/file-upload.js +1 -1
  92. package/dist/elements/form.js +1 -1
  93. package/dist/elements/hover-card.js +1 -1
  94. package/dist/elements/icon.js +1 -1
  95. package/dist/elements/image.js +1 -1
  96. package/dist/elements/input.js +1 -1
  97. package/dist/elements/kbd.js +1 -1
  98. package/dist/elements/link-preview.js +1 -1
  99. package/dist/elements/loader.js +1 -1
  100. package/dist/elements/markdown.js +1 -1
  101. package/dist/elements/menu.js +1 -1
  102. package/dist/elements/message-skills.js +1 -1
  103. package/dist/elements/message.js +1 -1
  104. package/dist/elements/model-switcher.js +1 -1
  105. package/dist/elements/nav.js +1 -1
  106. package/dist/elements/notice.js +1 -1
  107. package/dist/elements/pane-grid.js +1 -1
  108. package/dist/elements/pane-group.js +1 -1
  109. package/dist/elements/pane.js +1 -1
  110. package/dist/elements/popover.js +1 -1
  111. package/dist/elements/progress-bar.js +1 -1
  112. package/dist/elements/prompt-dock.js +1 -1
  113. package/dist/elements/prompt-input.js +1 -1
  114. package/dist/elements/prompt-suggestions.js +1 -1
  115. package/dist/elements/radio-group.js +1 -1
  116. package/dist/elements/reasoning.js +1 -1
  117. package/dist/elements/remote.js +1 -1
  118. package/dist/elements/resizable.js +1 -1
  119. package/dist/elements/response-stream.js +1 -1
  120. package/dist/elements/screen.js +1 -1
  121. package/dist/elements/scroll-area.js +1 -1
  122. package/dist/elements/scroll-button.js +1 -1
  123. package/dist/elements/search.js +1 -1
  124. package/dist/elements/segmented.js +1 -1
  125. package/dist/elements/select.js +1 -1
  126. package/dist/elements/separator.js +1 -1
  127. package/dist/elements/setting-item.js +1 -1
  128. package/dist/elements/settings-group.js +1 -1
  129. package/dist/elements/skeleton.js +1 -1
  130. package/dist/elements/slider.js +1 -1
  131. package/dist/elements/source.js +1 -1
  132. package/dist/elements/status.js +1 -1
  133. package/dist/elements/switch.js +1 -1
  134. package/dist/elements/tabs.js +1 -1
  135. package/dist/elements/tasks.js +1 -1
  136. package/dist/elements/text-shimmer.js +1 -1
  137. package/dist/elements/thinking-bar.js +1 -1
  138. package/dist/elements/thread.js +1 -1
  139. package/dist/elements/toast.js +1 -1
  140. package/dist/elements/tool.js +1 -1
  141. package/dist/elements/tooltip.js +1 -1
  142. package/dist/elements/voice-input.js +1 -1
  143. package/dist/elements/voice-output.js +1 -1
  144. package/dist/{ellipsis-CbOpJnU3.js → ellipsis-6pJ7SxYT.js} +1 -1
  145. package/dist/{embed-CrfjkbUG.js → embed-BMje-nxj.js} +1 -1
  146. package/dist/engine-javascript-C1x7zo1_.js +1 -141
  147. package/dist/{external-link-ByXAwBBQ.js → external-link-Beh9DKeR.js} +1 -1
  148. package/dist/{file-text-DMib2qwt.js → file-text-D1GPfZ8Q.js} +1 -1
  149. package/dist/{file-tree-CJqM2aP7.js → file-tree-Dwj2lqg-.js} +1 -1
  150. package/dist/{folder-_BAb929C.js → folder-b6D8x1DY.js} +1 -1
  151. package/dist/{form-DSZgZQZk.js → form-DWgdxDXu.js} +1 -1
  152. package/dist/{hover-card-BQbul9eq.js → hover-card-CWRkqm40.js} +1 -1
  153. package/dist/{icon-CdcfRhYI.js → icon-CL0jdhsf.js} +1 -1
  154. package/dist/index.js +1741 -1725
  155. package/dist/index.server.js +1582 -1566
  156. package/dist/{info-DsFjGuI_.js → info-0cOUherQ.js} +1 -1
  157. package/dist/{input-DKbmkMos.js → input-BH6Ru91Q.js} +1 -1
  158. package/dist/kai.es.js +1 -1
  159. package/dist/{kbd-PvdGhX4s.js → kbd-DRAnVtNX.js} +1 -1
  160. package/dist/{link-zF8PzWfF.js → link-Dlr0vssB.js} +1 -1
  161. package/dist/{link-preview-DbM1866N.js → link-preview-DODgRyV9.js} +1 -1
  162. package/dist/loader-KvJB6NrT.js +1 -0
  163. package/dist/{markdown-LMvmAyBk.js → markdown-DX9tuJVj.js} +1 -1
  164. package/dist/mcp.es.js +9 -5
  165. package/dist/{message-BYZECyek.js → message-BqQ7Ot5q.js} +1 -1
  166. package/dist/{message-BSsgvHvf.js → message-DkaGfBd8.js} +1 -1
  167. package/dist/message-circle-BPpp5QKv.js +1 -0
  168. package/dist/message-square-BLbsd9BJ.js +1 -0
  169. package/dist/{minimize-2-BQRoBV1V.js → minimize-2-CyOHJwcN.js} +1 -1
  170. package/dist/{model-switcher-CMpCOYcB.js → model-switcher-0hrKDiK2.js} +1 -1
  171. package/dist/{overlay-Cb-MkyDa.js → overlay-DBMFXie6.js} +1 -1
  172. package/dist/{panel-right-i8warFxT.js → panel-right-t8SWJL6e.js} +1 -1
  173. package/dist/{paperclip-ByY3UVO6.js → paperclip-CdzuOjbU.js} +1 -1
  174. package/dist/play-BXy1u7rW.js +1 -0
  175. package/dist/primitives/use-auto-resize.d.ts +11 -0
  176. package/dist/{progress-bar-jVAHvMUf.js → progress-bar-CiBtxMWT.js} +1 -1
  177. package/dist/{prompt-suggestion-CD-qtNgC.js → prompt-suggestion-I_DHP21i.js} +1 -1
  178. package/dist/{radio-BsoBMhkF.js → radio-C_p3n39l.js} +1 -1
  179. package/dist/{reasoning-4kBPtlTx.js → reasoning-BDwy_tIe.js} +1 -1
  180. package/dist/register-impl-DvEnhIxx.js +424 -0
  181. package/dist/{resizable-uPmY9VY-.js → resizable-SYC-fStM.js} +1 -1
  182. package/dist/{rotate-ccw-B2xn93py.js → rotate-ccw-B1nwmwuY.js} +1 -1
  183. package/dist/{rotate-cw-CMVLoCyH.js → rotate-cw-CLAnBcm1.js} +1 -1
  184. package/dist/{scroll-area-BqLUo8ZZ.js → scroll-area-zRyXoLhI.js} +1 -1
  185. package/dist/{scroll-button-DslXiJyL.js → scroll-button-jzrbYCG9.js} +1 -1
  186. package/dist/{select-2cLRtPGT.js → select-DM-0nEe0.js} +1 -1
  187. package/dist/{separator-BWQtNJcM.js → separator-BToOOoOt.js} +1 -1
  188. package/dist/{settings-BBR63jLg.js → settings-PaGo_S4U.js} +1 -1
  189. package/dist/{settings-group-B2ciy-Iw.js → settings-group-BFXGIfXq.js} +1 -1
  190. package/dist/{skeleton-CkHI-HgC.js → skeleton-DYpmFnnm.js} +1 -1
  191. package/dist/{slider-DDR9U-i0.js → slider-ebutAmkQ.js} +1 -1
  192. package/dist/{solid-DruVOXnf.js → solid-15v_3WVL.js} +3563 -3412
  193. package/dist/{solid-BzCFdL25.js → solid-5P-otgdi.js} +4502 -4296
  194. package/dist/solid.d.ts +6 -0
  195. package/dist/solid.js +259 -254
  196. package/dist/solid.server.js +259 -254
  197. package/dist/{source-GEnFF528.js → source-c1gpRl9h.js} +1 -1
  198. package/dist/{star-CilHq8GP.js → star-pcV_3LqF.js} +1 -1
  199. package/dist/{store-Ciyk6eZG.js → store-CSgbFFCg.js} +1 -1
  200. package/dist/{switch-KkeQIbuH.js → switch-Bh2OdLV2.js} +1 -1
  201. package/dist/{tasks-card-BrN4bggJ.js → tasks-card-CbqQAn2S.js} +1 -1
  202. package/dist/text-shimmer-BSzgEnDH.js +1 -0
  203. package/dist/textarea-DrYNt_0z.js +1 -0
  204. package/dist/theme.tokens.css +22 -21
  205. package/dist/{thumbs-up-CsT9Wzb9.js → thumbs-up-BL3-NenK.js} +1 -1
  206. package/dist/{toast-store-tgK6MuMv.js → toast-store-DkOlYczt.js} +1 -1
  207. package/dist/{tool-DzUjIBT8.js → tool-CeIWUVUe.js} +1 -1
  208. package/dist/{tooltip-Bkkg_4t0.js → tooltip-GA-nmg06.js} +1 -1
  209. package/dist/{trash-2-jBKxjGGQ.js → trash-2-CT66QWlm.js} +1 -1
  210. package/dist/{triangle-alert-DlQ68ppf.js → triangle-alert-CeHLWxhD.js} +1 -1
  211. package/dist/ui/color-field.d.ts +48 -0
  212. package/dist/ui/textarea.d.ts +4 -0
  213. package/dist/ui/toggle-chip.d.ts +40 -0
  214. package/dist/{upload-TcAHXv9W.js → upload-9Csb0F0J.js} +1 -1
  215. package/dist/{use-card-resolution-DaZqAdWf.js → use-card-resolution-Zg0a08Z-.js} +1 -1
  216. package/dist/{variant-aurora-DbW_OWL2.js → variant-aurora-4VBQHIKV.js} +1 -1
  217. package/dist/{variant-aurora-CNmfHhcx.js → variant-aurora-DBeCAQNk.js} +2 -2
  218. package/dist/{variant-aurora-D6GsdTPA.js → variant-aurora-FzHVXHby.js} +2 -2
  219. package/dist/{variant-aurora-BhLuYxJR.js → variant-aurora-LE3fqxgw.js} +1 -1
  220. package/dist/{variant-custom-BvYHR62b.js → variant-custom-AFRGcOBS.js} +1 -1
  221. package/dist/{variant-custom-DV2x254s.js → variant-custom-BQkNuPpE.js} +2 -2
  222. package/dist/{variant-custom-BRvaNHSi.js → variant-custom-DI5R0rln.js} +1 -1
  223. package/dist/{variant-custom-DMTrEO5w.js → variant-custom-WWnrrRHS.js} +2 -2
  224. package/dist/{variant-wave-CyBueXj9.js → variant-wave-DUCbH5oI.js} +2 -2
  225. package/dist/{variant-wave-BNMGrDfj.js → variant-wave-DuQV7DhQ.js} +2 -2
  226. package/dist/{variant-wave-BpDd8t3Z.js → variant-wave-nSI2sfII.js} +1 -1
  227. package/dist/{variant-wave-sp-qwsdI.js → variant-wave-wTP5v_jU.js} +1 -1
  228. package/dist/x-eiO9V6J6.js +1 -0
  229. package/{src/elements/styles.css → kit-base.css} +27 -44
  230. package/package.json +32 -17
  231. package/solid.css +33 -0
  232. package/theme.css +39 -23
  233. package/bin/route.test.js +0 -58
  234. package/dist/arrow-down-CjRU3JgV.js +0 -1
  235. package/dist/arrow-left-Bnpb1UEW.js +0 -1
  236. package/dist/artifact-Bwt7OgcR.js +0 -1
  237. package/dist/check-njkVdZu2.js +0 -1
  238. package/dist/chevron-down-B72s6PXR.js +0 -1
  239. package/dist/chevron-right-BatuHzUm.js +0 -1
  240. package/dist/circle-check-B62pODB3.js +0 -1
  241. package/dist/circle-zx0ByzY9.js +0 -1
  242. package/dist/controllable-CnGpMF6r.js +0 -1
  243. package/dist/define-By-uL588.js +0 -1
  244. package/dist/loader-BM4CEz4G.js +0 -1
  245. package/dist/message-circle-DruwObfX.js +0 -1
  246. package/dist/message-square-BG6q6mlm.js +0 -1
  247. package/dist/play-BvKKq3fX.js +0 -1
  248. package/dist/register-impl-B1hLkrI8.js +0 -424
  249. package/dist/text-shimmer-Dcj1MHuq.js +0 -1
  250. package/dist/textarea-Dpvbngbg.js +0 -1
  251. package/dist/x-Z5UntkIJ.js +0 -1
  252. package/src/agent-tooling/README.md +0 -192
  253. package/src/agent-tooling/archetypes.ts +0 -205
  254. package/src/agent-tooling/catalog/README.md +0 -676
  255. package/src/agent-tooling/catalog/catalog-types.ts +0 -231
  256. package/src/agent-tooling/catalog/fabrications.ts +0 -96
  257. package/src/agent-tooling/catalog/invariants.ts +0 -284
  258. package/src/agent-tooling/catalog/labs-titles.ts +0 -114
  259. package/src/agent-tooling/catalog/scenarios.ts +0 -87
  260. package/src/agent-tooling/catalog/surfaces.ts +0 -347
  261. package/src/agent-tooling/construct/cli-entry.ts +0 -8
  262. package/src/agent-tooling/construct/cli.ts +0 -147
  263. package/src/agent-tooling/construct/codegen.ts +0 -1635
  264. package/src/agent-tooling/construct/construct.v1.schema.json +0 -319
  265. package/src/agent-tooling/construct/dev.ts +0 -148
  266. package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +0 -7
  267. package/src/agent-tooling/construct/fixtures/ops-console.construct.json +0 -44
  268. package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +0 -32
  269. package/src/agent-tooling/construct/schema.ts +0 -452
  270. package/src/agent-tooling/integrations/anthropic.ts +0 -442
  271. package/src/agent-tooling/integrations/cloudflare.ts +0 -218
  272. package/src/agent-tooling/integrations/langgraph.ts +0 -133
  273. package/src/agent-tooling/integrations/mastra.ts +0 -182
  274. package/src/agent-tooling/integrations/mock.ts +0 -148
  275. package/src/agent-tooling/integrations/ollama.ts +0 -97
  276. package/src/agent-tooling/integrations/openai.ts +0 -95
  277. package/src/agent-tooling/integrations/openrouter.ts +0 -82
  278. package/src/agent-tooling/integrations/pi.ts +0 -176
  279. package/src/agent-tooling/integrations/pydantic-ai.ts +0 -108
  280. package/src/agent-tooling/integrations/vercel-ai-sdk.ts +0 -398
  281. package/src/agent-tooling/mcp/css-raw.d.ts +0 -12
  282. package/src/agent-tooling/mcp/manifest.ts +0 -422
  283. package/src/agent-tooling/mcp/server.ts +0 -116
  284. package/src/agent-tooling/mcp/stdio.ts +0 -18
  285. package/src/agent-tooling/mcp/tools/construct.ts +0 -130
  286. package/src/agent-tooling/mcp/tools/debug.ts +0 -621
  287. package/src/agent-tooling/mcp/tools/reference.ts +0 -980
  288. package/src/agent-tooling/mcp/tools/scaffold.ts +0 -6708
  289. package/src/agent-tooling/mcp/tools/theme.ts +0 -456
  290. package/src/agent-tooling/mcp/tools/types.ts +0 -14
  291. package/src/agent-tooling/mcp/validate-args.ts +0 -141
  292. package/src/agent-tooling/recipes/composed-thread.ts +0 -714
  293. package/src/agent-tooling/recipes/index.ts +0 -22
  294. package/src/agent-tooling/recipes/types.ts +0 -32
  295. package/src/agent-tooling/registry.ts +0 -132
  296. package/src/agent-tooling/route-emit.ts +0 -305
  297. package/src/agent-tooling/types.ts +0 -390
  298. package/src/components/artifact-card.tsx +0 -120
  299. package/src/components/artifact.tsx +0 -914
  300. package/src/components/attachment-types.ts +0 -66
  301. package/src/components/attachments.tsx +0 -536
  302. package/src/components/audio-visualizer/audio-visualizer.voice-fixture.ts +0 -257
  303. package/src/components/audio-visualizer/aurora.glsl.ts +0 -330
  304. package/src/components/audio-visualizer/fit-scale.ts +0 -112
  305. package/src/components/audio-visualizer/index.tsx +0 -528
  306. package/src/components/audio-visualizer/labs/lab-choreography.ts +0 -187
  307. package/src/components/audio-visualizer/labs/lab-shaders.ts +0 -363
  308. package/src/components/audio-visualizer/labs/lab-visualizer.tsx +0 -102
  309. package/src/components/audio-visualizer/shader-canvas.tsx +0 -876
  310. package/src/components/audio-visualizer/sizes.ts +0 -54
  311. package/src/components/audio-visualizer/variant-aurora.tsx +0 -305
  312. package/src/components/audio-visualizer/variant-bar.tsx +0 -175
  313. package/src/components/audio-visualizer/variant-custom.tsx +0 -344
  314. package/src/components/audio-visualizer/variant-grid.tsx +0 -175
  315. package/src/components/audio-visualizer/variant-radial.tsx +0 -163
  316. package/src/components/audio-visualizer/variant-wave.tsx +0 -130
  317. package/src/components/audio-visualizer/wave.glsl.ts +0 -130
  318. package/src/components/card-fallback.tsx +0 -60
  319. package/src/components/card-renderer.tsx +0 -220
  320. package/src/components/card.tsx +0 -212
  321. package/src/components/chain-of-thought.tsx +0 -348
  322. package/src/components/chat-container.tsx +0 -89
  323. package/src/components/chat-scope-picker.tsx +0 -57
  324. package/src/components/chat-thread.tsx +0 -1014
  325. package/src/components/checkpoint.tsx +0 -88
  326. package/src/components/choice-card.tsx +0 -743
  327. package/src/components/coachmark.tsx +0 -249
  328. package/src/components/code-block.tsx +0 -181
  329. package/src/components/composer-dom.ts +0 -159
  330. package/src/components/composer-highlight.ts +0 -242
  331. package/src/components/composer-history.ts +0 -82
  332. package/src/components/composer.tsx +0 -1075
  333. package/src/components/confirm-card.tsx +0 -402
  334. package/src/components/context.tsx +0 -377
  335. package/src/components/conversation-item.tsx +0 -241
  336. package/src/components/conversation-list.tsx +0 -429
  337. package/src/components/conversation-panel.tsx +0 -118
  338. package/src/components/dismissed-stub.tsx +0 -80
  339. package/src/components/embed.tsx +0 -200
  340. package/src/components/empty.tsx +0 -177
  341. package/src/components/feedback-bar.tsx +0 -166
  342. package/src/components/file-tree.tsx +0 -530
  343. package/src/components/file-upload.tsx +0 -167
  344. package/src/components/form-widgets.tsx +0 -525
  345. package/src/components/form.tsx +0 -1296
  346. package/src/components/home-panel.tsx +0 -159
  347. package/src/components/image.tsx +0 -65
  348. package/src/components/link-preview.tsx +0 -195
  349. package/src/components/loader.tsx +0 -367
  350. package/src/components/markdown.tsx +0 -162
  351. package/src/components/message-skills.tsx +0 -40
  352. package/src/components/message.tsx +0 -765
  353. package/src/components/model-switcher.tsx +0 -132
  354. package/src/components/prompt-input.tsx +0 -188
  355. package/src/components/prompt-suggestion.tsx +0 -150
  356. package/src/components/reasoning.tsx +0 -293
  357. package/src/components/response-compare-types.ts +0 -152
  358. package/src/components/response-compare.tsx +0 -455
  359. package/src/components/response-stream.tsx +0 -109
  360. package/src/components/screen.tsx +0 -181
  361. package/src/components/scroll-button.tsx +0 -93
  362. package/src/components/source.tsx +0 -192
  363. package/src/components/tasks-card.tsx +0 -801
  364. package/src/components/text-shimmer.tsx +0 -37
  365. package/src/components/thinking-bar.tsx +0 -50
  366. package/src/components/thread.tsx +0 -228
  367. package/src/components/toast.tsx +0 -503
  368. package/src/components/tool-classify.ts +0 -26
  369. package/src/components/tool-types.ts +0 -49
  370. package/src/components/tool.tsx +0 -190
  371. package/src/components/use-card-resolution.ts +0 -44
  372. package/src/components/voice-input.tsx +0 -222
  373. package/src/components/voice-output.tsx +0 -242
  374. package/src/components/widget-tab-bar.tsx +0 -73
  375. package/src/components/workspace-shell.tsx +0 -285
  376. package/src/diagnostics/hook.ts +0 -352
  377. package/src/diagnostics/index.ts +0 -82
  378. package/src/diagnostics/report-request.ts +0 -296
  379. package/src/elements/agent-card.tsx +0 -67
  380. package/src/elements/artifact.tsx +0 -194
  381. package/src/elements/attachments.tsx +0 -140
  382. package/src/elements/audio-visualizer.tsx +0 -227
  383. package/src/elements/autoloader.ts +0 -89
  384. package/src/elements/avatar.tsx +0 -33
  385. package/src/elements/badge.tsx +0 -32
  386. package/src/elements/button.tsx +0 -149
  387. package/src/elements/card.tsx +0 -133
  388. package/src/elements/cards.tsx +0 -266
  389. package/src/elements/chain-of-thought.tsx +0 -141
  390. package/src/elements/chat-scope-picker.tsx +0 -65
  391. package/src/elements/chat-types.ts +0 -102
  392. package/src/elements/chat-workspace.tsx +0 -188
  393. package/src/elements/chat.tsx +0 -304
  394. package/src/elements/checkbox-group.tsx +0 -164
  395. package/src/elements/checkbox.tsx +0 -134
  396. package/src/elements/checkpoint.tsx +0 -47
  397. package/src/elements/choice.tsx +0 -100
  398. package/src/elements/coachmark.tsx +0 -90
  399. package/src/elements/code-block.tsx +0 -60
  400. package/src/elements/command.tsx +0 -197
  401. package/src/elements/compare.tsx +0 -111
  402. package/src/elements/compiled.css +0 -2
  403. package/src/elements/composer.tsx +0 -162
  404. package/src/elements/confirm-card.tsx +0 -76
  405. package/src/elements/context-meter.tsx +0 -107
  406. package/src/elements/conversation-item.tsx +0 -120
  407. package/src/elements/conversation-list.tsx +0 -203
  408. package/src/elements/css.ts +0 -5
  409. package/src/elements/default-input.tsx +0 -392
  410. package/src/elements/define-entry.ts +0 -12
  411. package/src/elements/define.tsx +0 -563
  412. package/src/elements/diagnostic-events.ts +0 -114
  413. package/src/elements/dialog.tsx +0 -145
  414. package/src/elements/disclosure.ts +0 -95
  415. package/src/elements/dock.tsx +0 -215
  416. package/src/elements/dropdown.tsx +0 -123
  417. package/src/elements/editable-label.tsx +0 -140
  418. package/src/elements/element-data-types.ts +0 -152
  419. package/src/elements/element-diagnostics.ts +0 -392
  420. package/src/elements/element-manifest.json +0 -354
  421. package/src/elements/element-nonscalar.json +0 -187
  422. package/src/elements/element-types.d.ts +0 -4353
  423. package/src/elements/embed.tsx +0 -35
  424. package/src/elements/empty.tsx +0 -29
  425. package/src/elements/feedback-bar.tsx +0 -66
  426. package/src/elements/file-tree.tsx +0 -62
  427. package/src/elements/file-upload.tsx +0 -44
  428. package/src/elements/form.tsx +0 -94
  429. package/src/elements/hover-card.tsx +0 -80
  430. package/src/elements/icon.tsx +0 -41
  431. package/src/elements/image.tsx +0 -32
  432. package/src/elements/input.tsx +0 -492
  433. package/src/elements/kbd.tsx +0 -45
  434. package/src/elements/link-preview.tsx +0 -34
  435. package/src/elements/loader.tsx +0 -25
  436. package/src/elements/markdown.tsx +0 -38
  437. package/src/elements/menu.tsx +0 -241
  438. package/src/elements/message-skills.tsx +0 -83
  439. package/src/elements/message.tsx +0 -361
  440. package/src/elements/model-switcher.tsx +0 -121
  441. package/src/elements/nav.tsx +0 -87
  442. package/src/elements/notice.tsx +0 -53
  443. package/src/elements/pane-grid.tsx +0 -111
  444. package/src/elements/pane-group.tsx +0 -119
  445. package/src/elements/pane.tsx +0 -129
  446. package/src/elements/popover.tsx +0 -81
  447. package/src/elements/progress-bar.tsx +0 -39
  448. package/src/elements/prompt-dock.tsx +0 -82
  449. package/src/elements/prompt-input.tsx +0 -240
  450. package/src/elements/prompt-suggestions.tsx +0 -113
  451. package/src/elements/radio-group.tsx +0 -129
  452. package/src/elements/reasoning.tsx +0 -71
  453. package/src/elements/register-impl.ts +0 -148
  454. package/src/elements/register.ts +0 -76
  455. package/src/elements/remote.tsx +0 -225
  456. package/src/elements/resizable.globals.d.ts +0 -36
  457. package/src/elements/resizable.tsx +0 -704
  458. package/src/elements/response-stream.tsx +0 -40
  459. package/src/elements/screen.tsx +0 -90
  460. package/src/elements/scroll-area.tsx +0 -33
  461. package/src/elements/scroll-button.tsx +0 -179
  462. package/src/elements/search.tsx +0 -185
  463. package/src/elements/segmented.tsx +0 -129
  464. package/src/elements/select.tsx +0 -165
  465. package/src/elements/separator.tsx +0 -36
  466. package/src/elements/setting-item.tsx +0 -50
  467. package/src/elements/settings-group.tsx +0 -37
  468. package/src/elements/skeleton.tsx +0 -45
  469. package/src/elements/slider.tsx +0 -171
  470. package/src/elements/slot-text.ts +0 -73
  471. package/src/elements/slots.ts +0 -787
  472. package/src/elements/source.tsx +0 -126
  473. package/src/elements/status.tsx +0 -42
  474. package/src/elements/switch.tsx +0 -118
  475. package/src/elements/tabs.tsx +0 -95
  476. package/src/elements/tasks.tsx +0 -103
  477. package/src/elements/text-shimmer.tsx +0 -28
  478. package/src/elements/thinking-bar.tsx +0 -43
  479. package/src/elements/thread.tsx +0 -139
  480. package/src/elements/toast.tsx +0 -106
  481. package/src/elements/tool.tsx +0 -78
  482. package/src/elements/tooltip.tsx +0 -85
  483. package/src/elements/validate-messages.ts +0 -76
  484. package/src/elements/voice-input.tsx +0 -100
  485. package/src/elements/voice-output.tsx +0 -82
  486. package/src/index.ts +0 -430
  487. package/src/primitives/audio-bands.ts +0 -174
  488. package/src/primitives/card-component-types.ts +0 -63
  489. package/src/primitives/card-contract.ts +0 -80
  490. package/src/primitives/card-data-types.ts +0 -361
  491. package/src/primitives/card-host.tsx +0 -37
  492. package/src/primitives/card-recovery.ts +0 -160
  493. package/src/primitives/card-registry.tsx +0 -78
  494. package/src/primitives/card-resolution.ts +0 -36
  495. package/src/primitives/card-routing.ts +0 -85
  496. package/src/primitives/card-schemas/artifact.schema.json +0 -92
  497. package/src/primitives/card-schemas/card-envelope.schema.json +0 -14
  498. package/src/primitives/card-schemas/card-event.schema.json +0 -12
  499. package/src/primitives/card-schemas/choice.schema.json +0 -75
  500. package/src/primitives/card-schemas/confirm.schema.json +0 -65
  501. package/src/primitives/card-schemas/embed.schema.json +0 -63
  502. package/src/primitives/card-schemas/form.result.schema.json +0 -7
  503. package/src/primitives/card-schemas/form.schema.json +0 -53
  504. package/src/primitives/card-schemas/link.schema.json +0 -54
  505. package/src/primitives/card-schemas/tasks.result.schema.json +0 -16
  506. package/src/primitives/card-schemas/tasks.schema.json +0 -83
  507. package/src/primitives/card-tags.ts +0 -61
  508. package/src/primitives/card-validate-cards.ts +0 -255
  509. package/src/primitives/card-validate-schemas.ts +0 -58
  510. package/src/primitives/card-validate.ts +0 -131
  511. package/src/primitives/chat-config.tsx +0 -103
  512. package/src/primitives/composer-model.ts +0 -49
  513. package/src/primitives/composer-triggers.ts +0 -35
  514. package/src/primitives/controllable.ts +0 -21
  515. package/src/primitives/conversation-store.ts +0 -248
  516. package/src/primitives/create-kai-chat.ts +0 -66
  517. package/src/primitives/create-tween.ts +0 -266
  518. package/src/primitives/embed-providers.ts +0 -254
  519. package/src/primitives/field-mask.ts +0 -256
  520. package/src/primitives/field-semantics.ts +0 -115
  521. package/src/primitives/highlighter.ts +0 -157
  522. package/src/primitives/input-mask.ts +0 -853
  523. package/src/primitives/link-preview.ts +0 -87
  524. package/src/primitives/message-feedback.ts +0 -124
  525. package/src/primitives/pdf-preview.ts +0 -121
  526. package/src/primitives/toast-store.ts +0 -338
  527. package/src/primitives/url-scheme-policy.ts +0 -70
  528. package/src/primitives/use-audio-analysis.ts +0 -340
  529. package/src/primitives/use-auto-resize.ts +0 -31
  530. package/src/primitives/use-resize-observer.ts +0 -45
  531. package/src/primitives/use-sequencer.ts +0 -72
  532. package/src/primitives/use-speech-recognition.ts +0 -146
  533. package/src/primitives/use-stick-to-bottom.ts +0 -75
  534. package/src/primitives/use-text-stream.ts +0 -143
  535. package/src/primitives/use-voice-recorder.ts +0 -62
  536. package/src/primitives/visualizer-sequences.ts +0 -350
  537. package/src/remote/host-embed.ts +0 -345
  538. package/src/remote/index.ts +0 -2
  539. package/src/remote/origin.ts +0 -30
  540. package/src/remote/provider-runtime.ts +0 -262
  541. package/src/remote/provider.ts +0 -2
  542. package/src/remote/validate.ts +0 -22
  543. package/src/remote/version.ts +0 -12
  544. package/src/remote/wire.ts +0 -48
  545. package/src/schemas/from-tool-call.ts +0 -151
  546. package/src/schemas/index.ts +0 -341
  547. package/src/schemas/provider-subsets.ts +0 -538
  548. package/src/schemas/registry.ts +0 -355
  549. package/src/schemas/tool-defs.ts +0 -793
  550. package/src/solid.ts +0 -173
  551. package/src/state/index.ts +0 -44
  552. package/src/state/messages.ts +0 -53
  553. package/src/state/mock.ts +0 -297
  554. package/src/state/parts.ts +0 -295
  555. package/src/state/persistence.ts +0 -180
  556. package/src/state/stream.ts +0 -246
  557. package/src/state/suggestions.ts +0 -9
  558. package/src/state/threads.ts +0 -142
  559. package/src/test-utils/fake-clock.ts +0 -88
  560. package/src/types.ts +0 -95
  561. package/src/ui/action-icons.ts +0 -53
  562. package/src/ui/agent-card.tsx +0 -218
  563. package/src/ui/avatar.tsx +0 -23
  564. package/src/ui/badge.tsx +0 -21
  565. package/src/ui/button.tsx +0 -49
  566. package/src/ui/card.tsx +0 -245
  567. package/src/ui/checkbox-group.tsx +0 -153
  568. package/src/ui/checkbox.tsx +0 -63
  569. package/src/ui/collapsible.tsx +0 -163
  570. package/src/ui/command.tsx +0 -103
  571. package/src/ui/dialog.tsx +0 -223
  572. package/src/ui/dock.tsx +0 -630
  573. package/src/ui/dropdown.tsx +0 -636
  574. package/src/ui/editable-label.tsx +0 -112
  575. package/src/ui/hover-card.tsx +0 -345
  576. package/src/ui/icon.tsx +0 -167
  577. package/src/ui/input.tsx +0 -391
  578. package/src/ui/kbd.tsx +0 -118
  579. package/src/ui/nav.tsx +0 -282
  580. package/src/ui/notice.tsx +0 -84
  581. package/src/ui/overlay.tsx +0 -277
  582. package/src/ui/pane-grid.tsx +0 -117
  583. package/src/ui/pane-group.tsx +0 -291
  584. package/src/ui/pane.tsx +0 -193
  585. package/src/ui/popover.tsx +0 -106
  586. package/src/ui/progress-bar.tsx +0 -83
  587. package/src/ui/prompt-dock.tsx +0 -145
  588. package/src/ui/radio.tsx +0 -150
  589. package/src/ui/resizable.tsx +0 -693
  590. package/src/ui/scroll-area.tsx +0 -26
  591. package/src/ui/segmented.tsx +0 -109
  592. package/src/ui/select.tsx +0 -168
  593. package/src/ui/separator.tsx +0 -10
  594. package/src/ui/settings-group.tsx +0 -67
  595. package/src/ui/skeleton.tsx +0 -73
  596. package/src/ui/slider.tsx +0 -178
  597. package/src/ui/status.tsx +0 -48
  598. package/src/ui/switch.tsx +0 -119
  599. package/src/ui/tabs.tsx +0 -168
  600. package/src/ui/textarea.tsx +0 -21
  601. package/src/ui/tooltip.tsx +0 -118
  602. package/src/utils/cn.ts +0 -30
  603. package/src/wire/chunk.ts +0 -248
  604. package/src/wire/consume.ts +0 -599
  605. package/src/wire/diagnostics.ts +0 -727
  606. package/src/wire/encode-probe.ts +0 -214
  607. package/src/wire/encode.ts +0 -947
  608. package/src/wire/files.ts +0 -342
  609. package/src/wire/formats/anthropic.ts +0 -274
  610. package/src/wire/formats/openai.ts +0 -228
  611. package/src/wire/index.ts +0 -95
  612. package/src/wire/media-types.ts +0 -344
  613. package/src/wire/read.ts +0 -396
  614. package/src/wire/sink-helpers.ts +0 -50
  615. package/src/wire/sse.ts +0 -153
@@ -1,787 +0,0 @@
1
- /**
2
- * Composition slots for `kai-*` elements. A slot is a named region a consumer
3
- * fills with their own markup. This registry is the SINGLE SOURCE OF TRUTH:
4
- * the facade derives its detection from it (and, later, docs are generated
5
- * from it).
6
- */
7
-
8
- /** `inject` = additive (the built-in region still renders, your markup is added
9
- * in). `replace` = your markup stands in for the whole region — you own that
10
- * region's data + events (a slotted light-DOM node can't read the component's
11
- * reactive state). */
12
- export type SlotMode = 'inject' | 'replace';
13
-
14
- export interface SlotDef {
15
- /** Slot name (kebab-case). Also the `::part` name when `part` is true. */
16
- name: string;
17
- mode: SlotMode;
18
- /** Expose `::part(name)` on the region wrapper for consumer styling. */
19
- part?: boolean;
20
- /** One-line contract: what the consumer projects / owns. Feeds the docs. */
21
- doc: string;
22
- }
23
-
24
- /** Slots of `<kai-chat>`, in render order. */
25
- export const CHAT_SLOTS: SlotDef[] = [
26
- { name: 'header-start', mode: 'inject', doc: 'Leading header controls, left of the title.' },
27
- { name: 'header-end', mode: 'inject', doc: 'Trailing header controls.' },
28
- { name: 'header', mode: 'replace', part: true, doc: 'Full custom header; replaces the built-in title/model/context bar.' },
29
- { name: 'sidebar', mode: 'inject', part: true, doc: 'Left column (your nav / conversation list). Fixed width; use compose-your-own for resizable.' },
30
- { name: 'empty', mode: 'replace', doc: 'Custom zero-state rendered in the message area while the thread is empty. Replaces the empty message list only; the composer and any suggestions still render.' },
31
- { name: 'composer', mode: 'replace', doc: 'Full custom composer; you own submit + loading, drive the thread via messages.' },
32
- { name: 'composer-actions', mode: 'inject', doc: 'Accessory row above the composer.' },
33
- { name: 'footer', mode: 'inject', part: true, doc: 'Row below the composer (disclaimers, token meter).' },
34
- ];
35
-
36
- /** Slots of `<kai-prompt-input>` (and the default composer inside `<kai-chat>`). Native
37
- * shadow slots — an empty slot renders nothing, so no facade flag-gating is required.
38
- *
39
- * These are ONLY positions inside the card's shadow boundary — places a consumer
40
- * cannot reach from their own DOM. Content ABOVE/BELOW the whole card is the
41
- * consumer's own light-DOM layout (a sibling element), so there is intentionally
42
- * no outer block slot here. (When the input is nested inside `<kai-chat>`'s shadow,
43
- * that surrounding hole belongs to `kai-chat` — see `composer-actions`/`footer`.) */
44
- export const PROMPT_INPUT_SLOTS: SlotDef[] = [
45
- { name: 'input-top', mode: 'inject', doc: 'Inside the card, above the textarea (e.g. an inline status strip). For content above/below the whole card, use your own layout; that is light DOM you control.' },
46
- { name: 'toolbar-start', mode: 'inject', doc: 'Leading controls in the input toolbar, where a + menu goes.' },
47
- { name: 'toolbar-end', mode: 'inject', doc: 'Trailing controls in the toolbar, before the Send button.' },
48
- ];
49
-
50
- /** Slots of `<kai-conversations>` (also used inside `<kai-chat>`'s `sidebar`).
51
- * Names mirror `<kai-chat>`'s so the two compose with one vocabulary. */
52
- export const CONVERSATIONS_SLOTS: SlotDef[] = [
53
- { name: 'header', mode: 'replace', doc: 'Full custom title bar; replaces the built-in toggle / "Chats" / New-chat row.' },
54
- { name: 'empty', mode: 'replace', doc: 'Custom zero-state shown when there are no conversations; replaces the built-in "No conversations yet".' },
55
- { name: 'footer', mode: 'inject', doc: 'A row below the list: account, settings, or usage.' },
56
- ];
57
-
58
- /** Styleable `::part`s of `<kai-conversations>`. */
59
- export const CONVERSATIONS_PARTS: PartDef[] = [
60
- {
61
- name: 'trailing',
62
- doc: 'The right-aligned trailing text on each conversation row (a count, status, or relative time). Set it per item via the `trailing` field; otherwise a short auto relative time is derived from `updatedAt`. Recolor or resize it from outside.',
63
- recipe: 'kai-conversations::part(trailing) { color: var(--color-primary); font-variant-numeric: tabular-nums }',
64
- },
65
- {
66
- name: 'items',
67
- doc: 'The item-mode listbox region wrapping your slotted `<kai-conversation-item>` children.',
68
- recipe: 'kai-conversations::part(items) { gap: 2px }',
69
- },
70
- ];
71
-
72
- /** Slots of `<kai-conversation-item>` — one composed row of a consumer-owned
73
- * conversation loop (the default slot is the title). */
74
- export const CONVERSATION_ITEM_SLOTS: SlotDef[] = [
75
- { name: 'leading', mode: 'inject', part: true, doc: 'Leading region before the title (an icon or avatar).' },
76
- { name: 'meta', mode: 'inject', part: true, doc: 'Meta region under the title (a timestamp or status line).' },
77
- { name: 'menu', mode: 'inject', part: true, doc: 'Your own row menu (a popover trigger). Never selects the row.' },
78
- ];
79
-
80
- /** Styleable `::part`s of `<kai-conversation-item>`. (`leading`/`meta`/`menu`
81
- * are covered by their slot defs' `part: true` flags.) */
82
- export const CONVERSATION_ITEM_PARTS: PartDef[] = [
83
- {
84
- name: 'body',
85
- doc: 'The activation surface inside the row (button role; carries aria-current and the roving tabindex). The focus ring paints here.',
86
- recipe: 'kai-conversation-item::part(body) { outline-offset: 2px }',
87
- },
88
- {
89
- name: 'row',
90
- doc: 'The whole row surface. Carries `data-active` while selected.',
91
- recipe: 'kai-conversation-item::part(row) { border-radius: 0.5rem }',
92
- },
93
- {
94
- name: 'title',
95
- doc: 'The title line (the default slot renders inside it).',
96
- recipe: 'kai-conversation-item::part(title) { font-weight: 600 }',
97
- },
98
- ];
99
-
100
- /** Slots of `<kai-message>` — per-message composition seams. `before-body` and
101
- * `after-body` are INJECT regions inside the message's body column; `avatar`
102
- * REPLACES the built-in avatar rail (pair it with `avatar="none"` to omit the
103
- * rail entirely). These are the keystone of compose-your-own message lists. */
104
- export const MESSAGE_SLOTS: SlotDef[] = [
105
- { name: 'before-body', mode: 'inject', doc: 'A per-message header at the TOP of the body, above reasoning/tools/content: a model-name label, a role + timestamp line.' },
106
- { name: 'after-body', mode: 'inject', doc: 'A row at the BOTTOM of the body, below the action bar: a citation/sources row, a token-cost/latency line.' },
107
- { name: 'avatar', mode: 'replace', part: true, doc: 'Replaces the built-in avatar rail with your own node. Use `avatar="none"` to omit the rail and let the body span the full row.' },
108
- ];
109
-
110
- /** Slots of `<kai-notice>`. The message is the default slot; these are the named seams. */
111
- export const NOTICE_SLOTS: SlotDef[] = [
112
- { name: 'action', mode: 'inject', doc: 'A trailing action beside the message: a link or button.' },
113
- { name: 'icon', mode: 'replace', doc: 'A custom leading icon (any inline SVG, inherits `currentColor`). Overrides the severity default and the `icon` prop, the same escape hatch as `kai-button`.' },
114
- ];
115
-
116
- /** Slots of `<kai-button>` (the label is the default slot). */
117
- export const BUTTON_SLOTS: SlotDef[] = [
118
- { name: 'icon', mode: 'replace', doc: 'A custom leading icon (any inline SVG, inherits `currentColor`). Wins over the `icon` prop.' },
119
- ];
120
-
121
- /** Slots of `<kai-hover-card>` (the trigger is the default slot). */
122
- export const HOVER_CARD_SLOTS: SlotDef[] = [
123
- { name: 'card', mode: 'inject', doc: 'The rich content shown in the floating hover card.' },
124
- ];
125
-
126
- /** Slots of `<kai-menu>` (the menu items come from the `items` prop). */
127
- export const MENU_SLOTS: SlotDef[] = [
128
- { name: 'trigger', mode: 'replace', doc: 'Your own trigger element; replaces the built-in button driven by the `trigger-icon` / `trigger-label` props.' },
129
- ];
130
-
131
- /** A styleable `::part` the kit renders (NOT a slot — you don't project into it;
132
- * you restyle it from outside via `::part(name)`). This registry is the source
133
- * of truth so the styling surface is discoverable: docs + the `kai` MCP
134
- * component reference are generated from it, the same way slots are. The
135
- * `recipe` is a copy-pasteable example — including the "just hide it" case that
136
- * is pure CSS and therefore intentionally NOT a prop. */
137
- export interface PartDef {
138
- /** `::part(name)` exposed for consumer styling. */
139
- name: string;
140
- /** One-line contract: what the part is. */
141
- doc: string;
142
- /** A copy-pasteable styling example for docs / the MCP reference. */
143
- recipe?: string;
144
- }
145
-
146
- /** Styleable `::part`s of `<kai-chat>` (beyond the slot-backed `header`/`sidebar`/
147
- * `footer` parts). */
148
- export const CHAT_PARTS: PartDef[] = [
149
- {
150
- name: 'header-bar',
151
- doc: 'The built-in header bar (the title / model-switcher / context row that hosts the header-start/header-end inject slots). Restyle its height, padding, or gap from outside without replacing the whole header via the `header` slot.',
152
- recipe: 'kai-chat::part(header-bar) { height: 3.5rem; padding-inline: 1rem; gap: 0.5rem }',
153
- },
154
- ];
155
-
156
- /** Styleable `::part`s of `<kai-prompt-input>`. */
157
- export const PROMPT_INPUT_PARTS: PartDef[] = [
158
- {
159
- name: 'send',
160
- doc: 'The send button. Restyle from outside, or hide it entirely (Enter-only). Hiding is pure CSS, which is why there is no `submit="never"`.',
161
- recipe: 'kai-prompt-input::part(send) { display: none } /* Enter-only; or restyle: background, border-radius, … */',
162
- },
163
- ];
164
-
165
- /** Styleable `::part`s of `<kai-button>`. */
166
- export const BUTTON_PARTS: PartDef[] = [
167
- {
168
- name: 'button',
169
- doc: 'The button element. Restyle radius, padding, colors, or weight from outside; the `variant`/`size` props set the defaults.',
170
- recipe: 'kai-button::part(button) { border-radius: 9999px; font-weight: 600 }',
171
- },
172
- ];
173
-
174
- /** Styleable `::part`s of `<kai-badge>`. */
175
- export const BADGE_PARTS: PartDef[] = [
176
- {
177
- name: 'badge',
178
- doc: 'The badge pill. Restyle its background, color, or shape; the `variant` prop (default/count/citation) sets the defaults.',
179
- recipe: 'kai-badge::part(badge) { background: var(--color-primary); color: var(--color-primary-foreground) }',
180
- },
181
- ];
182
-
183
- /** Styleable `::part`s of `<kai-icon>`. */
184
- export const ICON_PARTS: PartDef[] = [
185
- {
186
- name: 'icon',
187
- doc: 'The icon wrapper. Inherits `currentColor` and the `size` prop by default; recolor or resize it from outside.',
188
- recipe: 'kai-icon::part(icon) { color: var(--color-primary) }',
189
- },
190
- ];
191
-
192
- /** Styleable `::part`s of `<kai-separator>`. */
193
- export const SEPARATOR_PARTS: PartDef[] = [
194
- {
195
- name: 'separator',
196
- doc: 'The divider line. Restyle its color, thickness, or inset from outside.',
197
- recipe: 'kai-separator::part(separator) { background: var(--color-border) }',
198
- },
199
- ];
200
-
201
- /** Styleable `::part`s of `<kai-scroll-area>`. */
202
- export const SCROLL_AREA_PARTS: PartDef[] = [
203
- {
204
- name: 'viewport',
205
- doc: 'The scrolling container. Add padding or a max-height from outside; the thin scrollbar follows `--color-scrollbar-thumb`.',
206
- recipe: 'kai-scroll-area::part(viewport) { padding-right: 0.5rem }',
207
- },
208
- ];
209
-
210
- /** Styleable `::part`s of `<kai-skeleton>`. */
211
- export const SKELETON_PARTS: PartDef[] = [
212
- {
213
- name: 'skeleton',
214
- doc: 'The shimmer block(s). Recolor or change the opacity from outside; the default is a low-contrast foreground tint that reads in both light and dark.',
215
- recipe: 'kai-skeleton::part(skeleton) { background: var(--color-primary); opacity: 0.15 }',
216
- },
217
- ];
218
-
219
- /**
220
- * The parts of ONE attachment item, declared by `components/attachments.tsx`
221
- * and therefore surfaced by every element that renders an attachment — the
222
- * standalone `<kai-attachments>` AND the thread inside `<kai-message>` /
223
- * `<kai-chat>`. Shared rather than duplicated so the two can never document
224
- * different names for the same node.
225
- *
226
- * These are a styling seam and a TESTING seam, and the second is why they exist
227
- * at all. `examples/internal/openrouter-spike` proves "a user can see which file
228
- * was attached" by locating these; before they existed it pinned the chip by
229
- * `span.truncate` and broke the day the thread moved to the grid tile, while the
230
- * filename was still plainly on screen. A published part is what lets an
231
- * assertion name the thing rather than its current markup.
232
- */
233
- export const ATTACHMENT_ITEM_PARTS: PartDef[] = [
234
- {
235
- name: 'attachment',
236
- doc: 'One attachment item: the chip, row or tile, whichever variant is rendering. Restyle its background, radius or border from outside without caring which layout it is.',
237
- recipe: 'kai-chat::part(attachment) { border-radius: 0.25rem }',
238
- },
239
- {
240
- name: 'attachment-name',
241
- doc: 'The attachment’s filename label. Present in every variant that shows one (a grid tile omits it for an image, which is its own label). Retune its type or hide it entirely.',
242
- recipe: 'kai-chat::part(attachment-name) { font-size: 0.75rem }',
243
- },
244
- ];
245
-
246
- /** Styleable `::part`s of `<kai-message>`. (The `avatar` part is contributed by
247
- * the `avatar` slot's `part: true` flag, so it is not repeated here.) */
248
- export const MESSAGE_PARTS: PartDef[] = [
249
- {
250
- name: 'row',
251
- doc: 'The message row wrapper (avatar rail + body column). Restyle its gap or alignment from outside.',
252
- recipe: 'kai-message::part(row) { gap: 0.75rem }',
253
- },
254
- {
255
- name: 'bubble',
256
- doc: 'The content bubble wrapper. Restyle its background, radius, or padding; for a user message this is the rounded chat bubble.',
257
- recipe: 'kai-message::part(bubble) { background: var(--color-primary); color: var(--color-primary-foreground) }',
258
- },
259
- {
260
- name: 'content',
261
- doc: 'The rendered message text/markdown region (same node as `bubble`). Target it to tune typography from outside.',
262
- recipe: 'kai-message::part(content) { font-size: 0.9375rem }',
263
- },
264
- {
265
- name: 'actions',
266
- doc: 'The action-bar row (copy / like / regenerate …). Restyle its spacing or hide it entirely from outside.',
267
- recipe: 'kai-message::part(actions) { gap: 0.25rem }',
268
- },
269
- {
270
- name: 'citations',
271
- doc: 'The citation row rendered from the message’s `source` parts: a wrapped row of chips below the bubble, never inside it. Restyle its spacing or hide it entirely from outside.',
272
- recipe: 'kai-message::part(citations) { gap: 0.5rem }',
273
- },
274
- // A message renders its `file` parts through the same Attachment chrome
275
- // `<kai-attachments>` uses, so it exposes the same handles. Shared, not
276
- // restated — see ATTACHMENT_ITEM_PARTS.
277
- ...ATTACHMENT_ITEM_PARTS,
278
- ];
279
-
280
- /** Styleable `::part`s of `<kai-attachments>`. */
281
- export const ATTACHMENTS_PARTS: PartDef[] = [
282
- {
283
- name: 'preview',
284
- doc: 'The image shown in an attachment’s hover-card preview. Bounded by default (max ~320×256, aspect preserved) so a large image never blows up the card. Raise or lower the cap from outside.',
285
- recipe: 'kai-attachments::part(preview) { max-width: 32rem; max-height: 24rem }',
286
- },
287
- ...ATTACHMENT_ITEM_PARTS,
288
- ];
289
-
290
- /** Styleable `::part`s of `<kai-status>`. */
291
- export const STATUS_PARTS: PartDef[] = [
292
- {
293
- name: 'dot',
294
- doc: 'The status dot. Recolor or resize it from outside; the `status` prop sets the default hue.',
295
- recipe: 'kai-status::part(dot) { background: var(--color-tool-green) }',
296
- },
297
- ];
298
-
299
- /** Styleable `::part`s of `<kai-tabs>`. */
300
- export const TABS_PARTS: PartDef[] = [
301
- {
302
- name: 'tablist',
303
- doc: 'The tab strip container (role="tablist"). Restyle its gap, padding, background, or radius from outside; the `variant` prop sets the segmented/underline defaults.',
304
- recipe: 'kai-tabs::part(tablist) { gap: 0.5rem; background: var(--color-card) }',
305
- },
306
- {
307
- name: 'tab',
308
- doc: 'A single tab button. Restyle from outside; the active tab carries a `[data-active]` attribute, so target `::part(tab)[data-active]` for the selected look.',
309
- recipe: 'kai-tabs::part(tab)[data-active] { color: var(--color-primary); font-weight: 600 }',
310
- },
311
- ];
312
-
313
- /** Styleable `::part`s of `<kai-voice-output>`. */
314
- export const VOICE_OUTPUT_PARTS: PartDef[] = [
315
- {
316
- name: 'button',
317
- doc: 'The speaker/play button. Restyle radius, size, padding, or colors from outside; it is a ghost icon button by default.',
318
- recipe: 'kai-voice-output::part(button) { border-radius: 9999px; color: var(--color-primary) }',
319
- },
320
- ];
321
-
322
- /** Slots of `<kai-screen>` (the default slot is the screen body). */
323
- export const SCREEN_SLOTS: SlotDef[] = [
324
- { name: 'title', mode: 'replace', part: true, doc: 'Rich header title; overrides the `headline` prop.' },
325
- { name: 'actions', mode: 'inject', doc: 'Header trailing cluster (e.g. an avatar or overflow menu).' },
326
- ];
327
-
328
- /** Styleable `::part`s of `<kai-screen>`. */
329
- export const SCREEN_PARTS: PartDef[] = [
330
- {
331
- name: 'header',
332
- doc: 'The back-header bar (back button + title + actions). Restyle its height, padding, or border from outside.',
333
- recipe: 'kai-screen::part(header) { height: 3.25rem; padding-inline: 1rem }',
334
- },
335
- {
336
- name: 'back',
337
- doc: 'The back button. Restyle or hide it from outside; `back="false"` removes it entirely.',
338
- recipe: 'kai-screen::part(back) { border-radius: 9999px }',
339
- },
340
- {
341
- name: 'body',
342
- doc: 'The full-bleed surface that fills the mount point and scrolls its content. Tune padding or background from outside.',
343
- recipe: 'kai-screen::part(body) { background: var(--color-card) }',
344
- },
345
- ];
346
-
347
- /** Slots of `<kai-card>` — structural regions only (the title/description are body
348
- * or `slot="header"` content you mark up). The body is the default slot. */
349
- export const CARD_SLOTS: SlotDef[] = [
350
- { name: 'media', mode: 'inject', doc: 'Full-bleed media (image/video/illustration) at the top (vertical) or start (horizontal). Clipped to the card corners.' },
351
- { name: 'header', mode: 'inject', doc: 'Header content, e.g. a title. Rendered above the body.' },
352
- { name: 'header-actions', mode: 'inject', doc: 'An actions cluster pinned to the end of the header row.' },
353
- { name: 'footer', mode: 'inject', doc: 'Footer content rendered below the body.' },
354
- { name: 'footer-actions', mode: 'inject', doc: 'Action buttons pinned to the end of the footer. Do NOT combine with a clickable/href card (nested interactive).' },
355
- ];
356
-
357
- /** Styleable `::part`s of `<kai-card>`. */
358
- export const CARD_PARTS: PartDef[] = [
359
- {
360
- name: 'card',
361
- doc: 'The card root (a div, or an a when href is set). Restyle its radius, border, or background; set --kai-card-spacing for padding/gaps (the dense prop sets the compact default).',
362
- recipe: 'kai-card::part(card) { border-radius: 1rem; --kai-card-spacing: 1.5rem }',
363
- },
364
- {
365
- name: 'media',
366
- doc: 'The full-bleed media region. Cap or crop it from outside (e.g. a fixed height with object-fit).',
367
- recipe: 'kai-card::part(media) { max-height: 12rem }',
368
- },
369
- {
370
- name: 'header',
371
- doc: 'The header row (header content + header-actions). Add a divider or adjust its alignment.',
372
- recipe: 'kai-card::part(header) { border-bottom: 1px solid var(--color-border) }',
373
- },
374
- {
375
- name: 'body',
376
- doc: 'The default-slot body region.',
377
- recipe: 'kai-card::part(body) { font-size: 0.9375rem }',
378
- },
379
- {
380
- name: 'footer',
381
- doc: 'The footer row (footer content + footer-actions).',
382
- recipe: 'kai-card::part(footer) { border-top: 1px solid var(--color-border) }',
383
- },
384
- {
385
- name: 'dismiss',
386
- doc: 'The dismiss (×) button shown when dismissible. Recolor or reposition it from outside.',
387
- recipe: 'kai-card::part(dismiss) { color: var(--color-muted-foreground) }',
388
- },
389
- ];
390
-
391
- /** Slots of `<kai-workspace>` (the five shell regions; main also takes the default slot). */
392
- export const WORKSPACE_SLOTS: SlotDef[] = [
393
- { name: 'header', mode: 'inject', part: true, doc: 'The top band across the full shell width (app bar, tabs, breadcrumbs).' },
394
- { name: 'start', mode: 'inject', part: true, doc: 'The inline-start aside column (a conversation rail, a nav, a file tree). Resizable and collapsible.' },
395
- { name: 'main', mode: 'inject', part: true, doc: 'The main region. Unnamed children project here too, via the default slot.' },
396
- { name: 'end', mode: 'inject', part: true, doc: 'The inline-end aside column (inspector, notes, preview). Resizable and collapsible.' },
397
- { name: 'footer', mode: 'inject', part: true, doc: 'The bottom band across the full shell width (status bar, disclaimers).' },
398
- ];
399
-
400
- /** Styleable `::part`s of `<kai-workspace>` (beyond the slot-backed header/start/main/end/footer parts). */
401
- export const WORKSPACE_PARTS: PartDef[] = [
402
- {
403
- name: 'aside',
404
- doc: 'Both aside columns match this part (each also matches its own start/end part). Restyle the shared aside surface or border from outside; the --kai-workspace-start-* and --kai-workspace-end-* custom properties set the widths.',
405
- recipe: 'kai-workspace::part(aside) { background: var(--color-card) }',
406
- },
407
- ];
408
-
409
- /** Styleable `::part`s of `<kai-nav>`. */
410
- export const NAV_PARTS: PartDef[] = [
411
- {
412
- name: 'nav',
413
- doc: 'The nav list container. Restyle its gap or padding from outside.',
414
- recipe: 'kai-nav::part(nav) { gap: 0.25rem }',
415
- },
416
- {
417
- name: 'item',
418
- doc: 'A nav item button (leaf or group parent). The active leaf carries aria-current="page" and a group parent carries aria-expanded; target `::part(item)[aria-current]` for the selected look or `::part(item)[aria-expanded]` for a group row.',
419
- recipe: 'kai-nav::part(item)[aria-current] { background: var(--color-accent) }',
420
- },
421
- {
422
- name: 'group',
423
- doc: 'The nested child list rendered under an expanded group item. Add a left guide line or tune its indent from outside.',
424
- recipe: 'kai-nav::part(group) { border-left: 1px solid var(--color-border); margin-left: 1.1rem }',
425
- },
426
- {
427
- name: 'chevron',
428
- doc: 'The disclosure chevron on a group row (rotates when expanded). Recolor or resize it from outside.',
429
- recipe: 'kai-nav::part(chevron) { opacity: 1; color: var(--color-primary) }',
430
- },
431
- {
432
- name: 'status',
433
- doc: 'The per-item status cluster (a colored dot in the tone hue + an optional label). Shown only when an item carries a `status`; the `pulse` flag animates the dot. Restyle from outside.',
434
- recipe: 'kai-nav::part(status) { gap: 0.5rem }',
435
- },
436
- {
437
- name: 'meta',
438
- doc: 'The right-aligned muted trailing text on a row (e.g. a relative time). Shown only when an item carries `meta`; restyle from outside.',
439
- recipe: 'kai-nav::part(meta) { color: var(--color-foreground); font-variant-numeric: tabular-nums }',
440
- },
441
- {
442
- name: 'item-action',
443
- doc: 'The trailing per-item action / close button, a sibling of the item button. Shown only when an item carries `action` or `closable`; reveal it on hover or pin it visible from outside.',
444
- recipe: 'kai-nav::part(item-action) { opacity: 1 }',
445
- },
446
- ];
447
-
448
- /** Slots of `<kai-coachmark>` (the anchor/trigger is the default slot). */
449
- export const COACHMARK_SLOTS: SlotDef[] = [
450
- { name: 'content', mode: 'replace', doc: 'The bubble body text shown under the headline.' },
451
- ];
452
-
453
- /** Styleable `::part`s of `<kai-coachmark>`. */
454
- export const COACHMARK_PARTS: PartDef[] = [
455
- { name: 'bubble', doc: 'The hint bubble panel. Restyle its background, radius, or padding from outside; the default is bg-primary.', recipe: 'kai-coachmark::part(bubble) { border-radius: 1rem }' },
456
- { name: 'arrow', doc: 'The arrow pointing at the anchor. Inherits the bubble color; recolor it alongside the bubble.', recipe: 'kai-coachmark::part(arrow) { background: var(--color-accent) }' },
457
- { name: 'badge', doc: 'The small badge pill beside the headline (e.g. "New").', recipe: 'kai-coachmark::part(badge) { text-transform: none }' },
458
- { name: 'title', doc: 'The bold headline text.', recipe: 'kai-coachmark::part(title) { font-size: 0.9375rem }' },
459
- { name: 'dismiss', doc: 'The dismiss button. Recolor or reposition it from outside.', recipe: 'kai-coachmark::part(dismiss) { color: var(--color-primary-foreground) }' },
460
- ];
461
-
462
- /** Styleable `::part`s of `<kai-progress-bar>`. */
463
- export const PROGRESS_BAR_PARTS: PartDef[] = [
464
- { name: 'track', doc: 'The progress track (the background bar). Restyle its height, radius, or background from outside.', recipe: 'kai-progress-bar::part(track) { height: 0.5rem }' },
465
- { name: 'fill', doc: 'The filled portion; its width follows value/max. Recolor it from outside.', recipe: 'kai-progress-bar::part(fill) { background: var(--color-tool-green) }' },
466
- ];
467
-
468
- /** Styleable `::part`s of `<kai-context>`. The usage meter is the same shared
469
- * ProgressBar `<kai-progress-bar>` renders, mounted inside this element's own
470
- * shadow root, so `kai-context` exposes the same two names. Both sit inside the
471
- * hover-card breakdown and are in the DOM only while that card is open. */
472
- export const CONTEXT_PARTS: PartDef[] = [
473
- { name: 'track', doc: 'The usage meter track inside the hover-card breakdown. Carries `role="progressbar"` and is in the DOM only while the card is open. Restyle its height, radius, or background from outside.', recipe: 'kai-context::part(track) { height: 0.5rem }' },
474
- { name: 'fill', doc: 'The used-tokens portion of that meter. Its width follows `usedTokens / maxTokens`; its default color is the severity hue picked by `warnThreshold` / `dangerThreshold`, so recoloring it from outside replaces that signal.', recipe: 'kai-context::part(fill) { background: var(--color-tool-blue) }' },
475
- ];
476
-
477
- /** Styleable `::part`s of `<kai-file-tree>` — the changed-files / diff bits, shown
478
- * only when a file carries diff metadata (or the `summary` attribute is set). */
479
- export const FILE_TREE_PARTS: PartDef[] = [
480
- {
481
- name: 'summary',
482
- doc: 'The changed-files summary header (the file count, the summed +additions/-deletions, and the Collapse-all/Expand-all toggle). Rendered only when the `summary` attribute is set; restyle or hide it from outside.',
483
- recipe: 'kai-file-tree::part(summary) { border-bottom: none; padding-block: 0.5rem }',
484
- },
485
- {
486
- name: 'status',
487
- doc: 'The per-row change-status letter (A/M/D/R/U), shown when a file carries a `status`. Colored with the conventional VCS tool hues; restyle from outside.',
488
- recipe: 'kai-file-tree::part(status) { font-weight: 700 }',
489
- },
490
- {
491
- name: 'stat-additions',
492
- doc: 'The trailing `+N` additions stat on a file row (success/green tool hue, tabular-nums). Shown only when a file carries `additions`.',
493
- recipe: 'kai-file-tree::part(stat-additions) { color: var(--color-tool-green) }',
494
- },
495
- {
496
- name: 'stat-deletions',
497
- doc: 'The trailing `-N` deletions stat on a file row (error/red tool hue, tabular-nums). Shown only when a file carries `deletions`.',
498
- recipe: 'kai-file-tree::part(stat-deletions) { color: var(--color-tool-red) }',
499
- },
500
- ];
501
-
502
- /**
503
- * Per-element composition surface — the SINGLE registry the build extracts
504
- * (`scripts/gen-element-api.mjs`) into `element-meta.json`, the Custom Elements
505
- * Manifest (`cssParts`/`slots`), `docs/web-components.md`, and the `kai` MCP
506
- * `component_reference`. Each entry maps a `kai-*` tag to the slots it projects
507
- * and the `::part`s it exposes for styling. Slots flagged `part: true` are ALSO
508
- * styleable parts, so they surface in both places.
509
- *
510
- * Adding a `part="…"` in a facade/component without registering it here fails the
511
- * `slots.test.ts` drift guard — keep this in sync with the source.
512
- */
513
- export interface ElementComposition {
514
- slots?: SlotDef[];
515
- parts?: PartDef[];
516
- /**
517
- * What the element's DEFAULT (unnamed) `<slot>` projects — i.e. what a consumer
518
- * puts between the tags. Kept OUT of `slots` on purpose: those arrays are also
519
- * read at runtime by `readSlots()`, which would query a meaningless `[slot=""]`.
520
- * scripts/gen-element-api.mjs merges it back in as a slot with the empty name,
521
- * which is how the Custom Elements Manifest spells the default slot.
522
- *
523
- * Every facade that renders a bare `<slot />` needs one; guarded by
524
- * tests/elements/slot-registry-coverage.test.ts.
525
- */
526
- children?: string;
527
- }
528
-
529
- /** Slots + styleable `::part`s of `<kai-prompt-dock>`. */
530
- export const PROMPT_DOCK_SLOTS: SlotDef[] = [
531
- { name: 'top', mode: 'inject', part: true, doc: 'The top lip: a notice or banner above the input. Rendered only when filled.' },
532
- { name: 'bottom', mode: 'inject', part: true, doc: 'The bottom lip: a mode or controls row below the input. Rendered only when filled.' },
533
- ];
534
- export const PROMPT_DOCK_PARTS: PartDef[] = [
535
- {
536
- name: 'tray',
537
- doc: 'The recessed tray that frames the input. The `appearance`/`frame` props set the defaults; the --kai-prompt-dock-* tokens fine-tune surface/border/radius/inset.',
538
- recipe: 'kai-prompt-dock::part(tray) { --kai-prompt-dock-radius: 1rem }',
539
- },
540
- ];
541
-
542
- /** Slots + styleable `::part`s of `<kai-dock>` (the floating corner launcher — not
543
- * `<kai-prompt-dock>`, which is an in-flow tray around a prompt input). */
544
- export const DOCK_SLOTS: SlotDef[] = [
545
- { name: 'panel', mode: 'replace', part: true, doc: 'The panel body. ANY element: a `<kai-chat>`, a form, your own component. The dock never reads or types it, and the default slot is the same region.' },
546
- { name: 'launcher', mode: 'inject', doc: 'Content inside the built-in button while CLOSED; defaults to a chat glyph. Text works as well as an icon: the button keeps its height and grows sideways into a pill, so a label like "Support" is not clipped. The BUTTON is never slotted away, because it owns aria-expanded, aria-controls, the toggle wiring and the focus return.' },
547
- { name: 'launcher-open', mode: 'inject', doc: 'Content inside the button while OPEN; defaults to a ✕. Fill only `launcher` and that glyph stays while open rather than morphing into a built-in that clashes with it.' },
548
- ];
549
- export const DOCK_PARTS: PartDef[] = [
550
- { name: 'launcher', doc: 'The launcher button pinned to the corner: a disc by default, a pill once you slot a text label. Restyle its surface or shadow; --kai-dock-launcher-size sets its height and its minimum width.', recipe: 'kai-dock::part(launcher) { background: var(--color-info) }' },
551
- { name: 'badge', doc: 'The unread dot on the launcher, rendered only while closed and only when `unread` is set. Restyle its color or size.', recipe: 'kai-dock::part(badge) { background: var(--color-success) }' },
552
- ];
553
-
554
- /** Styleable `::part`s of `<kai-segmented>`. */
555
- export const SEGMENTED_PARTS: PartDef[] = [
556
- { name: 'track', doc: 'The segmented track (the pill container holding the segments). Restyle its background, radius, or padding.', recipe: 'kai-segmented::part(track) { border-radius: 9999px }' },
557
- { name: 'segment', doc: 'Each segment button. Restyle padding, font weight, or the selected look.', recipe: 'kai-segmented::part(segment) { font-weight: 600 }' },
558
- ];
559
-
560
- /** Styleable `::part`s of `<kai-settings-group>`. */
561
- export const SETTINGS_GROUP_PARTS: PartDef[] = [
562
- { name: 'header', doc: 'The group heading + description block. Restyle its spacing or typography.', recipe: 'kai-settings-group::part(header) { margin-bottom: 0.75rem }' },
563
- { name: 'body', doc: 'The bordered card holding the setting rows. Restyle its surface, border, or radius.', recipe: 'kai-settings-group::part(body) { border-radius: 1rem }' },
564
- ];
565
-
566
- /** Slots + styleable `::part`s of `<kai-setting-item>`. */
567
- export const SETTING_ITEM_SLOTS: SlotDef[] = [
568
- { name: 'control', mode: 'inject', part: true, doc: 'The row control (a switch, segmented, select, etc.), right-aligned. Omit it for a label-only row.' },
569
- ];
570
- export const SETTING_ITEM_PARTS: PartDef[] = [
571
- { name: 'label', doc: 'The label + description block on the left of the row. Restyle its typography or spacing.', recipe: 'kai-setting-item::part(label) { gap: 0.125rem }' },
572
- ];
573
-
574
- /** Slots + styleable `::part`s of `<kai-pane>` (the editor-group pane frame). */
575
- export const PANE_SLOTS: SlotDef[] = [
576
- { name: 'leading', mode: 'inject', doc: 'A glyph or avatar at the start of the pane header.' },
577
- { name: 'actions', mode: 'inject', doc: 'Extra header controls, before the built-in window controls.' },
578
- { name: 'footer', mode: 'inject', part: true, doc: 'A pinned row below the body (e.g. a composer).' },
579
- ];
580
- export const PANE_PARTS: PartDef[] = [
581
- { name: 'header', doc: 'The pane header bar (leading + title/status + actions + window controls).', recipe: 'kai-pane::part(header) { padding-inline: 0.75rem }' },
582
- { name: 'body', doc: 'The scrolling body region (the default slot).', recipe: 'kai-pane::part(body) { padding: 1rem }' },
583
- { name: 'controls', doc: 'The window-control cluster (maximize/close, and split/dock when enabled).', recipe: 'kai-pane::part(controls) { gap: 0.25rem }' },
584
- ];
585
-
586
- /** Styleable `::part`s of `<kai-agent-card>`. */
587
- export const AGENT_CARD_PARTS: PartDef[] = [
588
- { name: 'status', doc: 'The leading tone-colored status dot.', recipe: 'kai-agent-card::part(status) { width: 0.625rem; height: 0.625rem }' },
589
- { name: 'menu', doc: 'The trailing overflow ("...") menu button.', recipe: 'kai-agent-card::part(menu) { opacity: 1 }' },
590
- ];
591
-
592
- /** Styleable `::part`s of `<kai-code-block>` (one syntax-highlighted code block).
593
- * The code region itself is not a part — it is rebuilt when the highlight lands,
594
- * and its look is owned by the Shiki theme (`code-theme`). */
595
- export const CODE_BLOCK_PARTS: PartDef[] = [
596
- { name: 'copy', doc: 'The copy-to-clipboard button in the header row. Hide it with `copy="false"` rather than CSS.', recipe: 'kai-code-block::part(copy) { color: var(--color-primary) }' },
597
- ];
598
-
599
- /** Slots + styleable `::part`s of `<kai-dialog>` (the centered modal). */
600
- export const DIALOG_SLOTS: SlotDef[] = [
601
- { name: 'header', mode: 'inject', part: true, doc: 'Optional title region at the top of the panel.' },
602
- { name: 'footer', mode: 'inject', part: true, doc: 'Optional actions region at the bottom of the panel.' },
603
- ];
604
- export const DIALOG_PARTS: PartDef[] = [
605
- { name: 'backdrop', doc: 'The full-area scrim behind the panel. Restyle its color/blur.', recipe: 'kai-dialog::part(backdrop) { background: rgb(0 0 0 / 0.6) }' },
606
- { name: 'panel', doc: 'The centered modal panel. Restyle width, radius, padding.', recipe: 'kai-dialog::part(panel) { max-width: 32rem }' },
607
- { name: 'body', doc: 'The scrolling content region (the default slot).', recipe: 'kai-dialog::part(body) { padding: 1.25rem }' },
608
- ];
609
-
610
- /** Styleable `::part`s of `<kai-pane-group>` (the editor group: a tab strip over
611
- * the active tab's pane). The per-tab content slots are NAMED DYNAMICALLY by tab
612
- * id (`slot="<tab id>"`) plus a default slot, so they are not enumerable here —
613
- * only the styleable parts are registered. */
614
- export const PANE_GROUP_PARTS: PartDef[] = [
615
- { name: 'tabs', doc: 'The tab strip (role="tablist"). Restyle its background, height, padding, or gap from outside.', recipe: 'kai-pane-group::part(tabs) { background: var(--color-card); gap: 0.25rem }' },
616
- { name: 'tab', doc: 'A single tab button. The active tab carries `[aria-selected="true"]`; target `::part(tab)[aria-selected="true"]` for the selected look.', recipe: 'kai-pane-group::part(tab)[aria-selected="true"] { background: var(--color-accent) }' },
617
- { name: 'body', doc: 'The active tab\'s content region (the named/default slot host).', recipe: 'kai-pane-group::part(body) { padding: 0.75rem }' },
618
- { name: 'menu', doc: 'The per-tab "…" overflow button. Reveal it on hover or pin it visible from outside.', recipe: 'kai-pane-group::part(menu) { opacity: 1 }' },
619
- { name: 'close', doc: 'The per-tab close ("×") button. Recolor, resize, or hide it from outside.', recipe: 'kai-pane-group::part(close) { color: var(--color-muted-foreground) }' },
620
- ];
621
-
622
- /** Affix slots + styleable `::part`s of `<kai-input>` (the field shell). */
623
- export const INPUT_SLOTS: SlotDef[] = [
624
- { name: 'leading', mode: 'inject', doc: 'A glyph, prefix, or affix at the start of the field, inside the border.' },
625
- { name: 'trailing', mode: 'inject', doc: 'A button, unit, or affix at the end of the field, inside the border.' },
626
- ];
627
- export const INPUT_PARTS: PartDef[] = [
628
- { name: 'field', doc: 'The bordered control box (the row wrapping any affixes plus the input). Restyle its border, radius, surface, or focus ring.', recipe: 'kai-input::part(field) { border-radius: 0.75rem }' },
629
- { name: 'input', doc: 'The inner input element. Restyle its text, padding, or placeholder.', recipe: 'kai-input::part(input) { font-variant-numeric: tabular-nums }' },
630
- { name: 'label', doc: 'The field label above the control. Restyle its typography or spacing.', recipe: 'kai-input::part(label) { font-weight: 600 }' },
631
- { name: 'hint', doc: 'The hint or error line below the control. Restyle its typography.', recipe: 'kai-input::part(hint) { font-style: italic }' },
632
- ];
633
-
634
- /** Styleable `::part`s of `<kai-search>` (the debounced filter field; composes the
635
- * kai-input field plus a clear button). */
636
- export const SEARCH_PARTS: PartDef[] = [
637
- { name: 'field', doc: 'The bordered control box (the row wrapping the search icon, input, and clear button).', recipe: 'kai-search::part(field) { border-radius: 9999px }' },
638
- { name: 'input', doc: 'The inner search input element.', recipe: 'kai-search::part(input) { font-size: 0.875rem }' },
639
- { name: 'clear', doc: 'The trailing clear ("x") button, shown when the field is non-empty.', recipe: 'kai-search::part(clear) { opacity: 1 }' },
640
- ];
641
-
642
- /** Styleable `::part`s of `<kai-editable-label>` (inline rename; the edit field is the kai-input field). */
643
- export const EDITABLE_LABEL_PARTS: PartDef[] = [
644
- { name: 'text', doc: 'The read-mode label text. Restyle its typography; it swaps to the input on edit.', recipe: 'kai-editable-label::part(text) { font-weight: 600 }' },
645
- { name: 'input', doc: 'The edit-mode input (the composed kai-input field).', recipe: 'kai-editable-label::part(input) { font: inherit }' },
646
- ];
647
-
648
- /** Styleable `::part`s of `<kai-kbd>` (the keyboard-shortcut display). */
649
- export const KBD_PARTS: PartDef[] = [
650
- { name: 'key', doc: 'Each key cap. Restyle its surface, border, radius, or font.', recipe: 'kai-kbd::part(key) { border-radius: 0.375rem }' },
651
- { name: 'separator', doc: 'The gap between key caps. Inject a literal joiner (e.g. a plus sign) from outside.', recipe: 'kai-kbd::part(separator)::after { content: "+" }' },
652
- ];
653
-
654
- /** Styleable `::part`s of `<kai-command>` (the command palette). */
655
- export const COMMAND_PARTS: PartDef[] = [
656
- { name: 'shortcut', doc: 'The right-aligned per-row keyboard shortcut, rendered as kai-kbd key caps. Shown only when a row carries a `shortcut`.', recipe: 'kai-command::part(shortcut) { opacity: 0.8 }' },
657
- ];
658
-
659
- /** Styleable `::part`s of `<kai-menu>` (the actions dropdown). */
660
- export const MENU_PARTS: PartDef[] = [
661
- { name: 'shortcut', doc: 'The right-aligned per-item keyboard shortcut, rendered as kai-kbd key caps. Shown only when an item carries a `shortcut`.', recipe: 'kai-menu::part(shortcut) { opacity: 0.8 }' },
662
- ];
663
-
664
- /** Slots of `<kai-thread>` (the standalone scrolling message list; messages come
665
- * from the `messages` prop). */
666
- export const THREAD_SLOTS: SlotDef[] = [
667
- { name: 'empty', mode: 'replace', doc: 'Custom zero-state rendered in the message area while the thread is empty; replaces the built-in default.' },
668
- ];
669
-
670
- /** Slots of `<kai-empty>`. The body is the default slot; `media` is the named seam. */
671
- export const EMPTY_SLOTS: SlotDef[] = [
672
- { name: 'media', mode: 'replace', doc: 'The leading illustration or icon above the title (any inline SVG or <img>). Replaces the built-in media box.' },
673
- ];
674
-
675
- /** Slots of `<kai-popover>`. The panel body is the default slot; `trigger` is the
676
- * control the panel anchors to and opens from. */
677
- export const POPOVER_SLOTS: SlotDef[] = [
678
- { name: 'trigger', mode: 'replace', doc: 'The control that opens the popover (a button, an avatar, …). The panel anchors to it.' },
679
- ];
680
-
681
- /** Slots of `<kai-dropdown>`. The menu body is the default slot; `trigger` is the
682
- * VISUAL content of the built-in trigger button (never your own `<button>`/`<a>`,
683
- * which would nest interactive elements — the `kai-menu` rule). */
684
- export const DROPDOWN_SLOTS: SlotDef[] = [
685
- { name: 'trigger', mode: 'replace', doc: 'Visual content of the trigger button (an icon, text, an `<svg>`). Replaces the built-in trigger* content; name it with `label`.' },
686
- ];
687
-
688
- /** Styleable `::part`s of `<kai-audio-visualizer>`. Every DOM variant (`bar`,
689
- * `grid`, `radial`) shares the `bar`/`cell` markup pattern; the shader variants
690
- * (`wave`, `aurora`) share the `canvas` part. Lit items ALSO carry the
691
- * `highlighted` part token, so `::part(bar highlighted)`/`::part(cell
692
- * highlighted)` selects only the lit ones. `::part(bar)[data-kai-highlighted=
693
- * "true"]` looks plausible but is invalid CSS: a CSS attribute selector
694
- * cannot follow a pseudo-element (`CSS.supports(selector(...))` returns
695
- * `false` for it in Chromium, and `insertRule` throws). `data-kai-index` /
696
- * `data-kai-highlighted` still exist on the element for consumers reading
697
- * them from INSIDE the shadow root or via the Solid render-prop; they are
698
- * just not reachable from an external `::part()` selector. */
699
- export const AUDIO_VISUALIZER_PARTS: PartDef[] = [
700
- {
701
- name: 'bar',
702
- doc: 'A single bar in the `bar` variant, or a single spoke in the `radial` variant. Also carries `data-kai-index` and `data-kai-highlighted` ("true"/"false") for use inside the shadow root; to style the lit state from OUTSIDE, combine with the `highlighted` part below rather than an attribute selector.',
703
- recipe: 'kai-audio-visualizer::part(bar) { border-radius: 2px }\nkai-audio-visualizer::part(bar highlighted) { background: var(--brand) }',
704
- },
705
- {
706
- name: 'cell',
707
- doc: 'A single dot in the `grid` variant. Also carries `data-kai-index` and `data-kai-highlighted` ("true"/"false") for use inside the shadow root; to style the lit state from OUTSIDE, combine with the `highlighted` part below rather than an attribute selector.',
708
- recipe: 'kai-audio-visualizer::part(cell) { border-radius: 9999px }\nkai-audio-visualizer::part(cell highlighted) { background: var(--brand) }',
709
- },
710
- {
711
- name: 'highlighted',
712
- doc: 'A second part TOKEN present on a `bar` or `cell` exactly when the sequencer or live audio has it lit, not a standalone styleable element. Combine it in the same `::part()` argument: `::part(bar highlighted)` or `::part(cell highlighted)`. This is the external equivalent of the internal `data-kai-highlighted="true"` attribute, which a `::part()` selector cannot reach (an attribute selector cannot follow a pseudo-element).',
713
- recipe: 'kai-audio-visualizer::part(bar highlighted) { background: var(--brand) }\nkai-audio-visualizer::part(cell highlighted) { background: var(--brand) }',
714
- },
715
- {
716
- name: 'canvas',
717
- doc: 'The WebGL canvas backing the `wave` and `aurora` variants. Restyle its size or radius, or layer a mask/filter, from outside.',
718
- recipe: 'kai-audio-visualizer::part(canvas) { border-radius: 0.75rem }',
719
- },
720
- ];
721
-
722
- export const ELEMENT_COMPOSITION: Record<string, ElementComposition> = {
723
- 'kai-chat': { slots: CHAT_SLOTS, parts: CHAT_PARTS },
724
- 'kai-command': { parts: COMMAND_PARTS },
725
- 'kai-conversations': { slots: CONVERSATIONS_SLOTS, parts: CONVERSATIONS_PARTS, children: 'Your own `<kai-conversation-item>` rows (item mode: the consumer-owned loop). Data rows do not render while any are present.' },
726
- 'kai-conversation-item': { slots: CONVERSATION_ITEM_SLOTS, parts: CONVERSATION_ITEM_PARTS, children: 'The row title. `leading`, `meta` and `menu` are the named regions around it.' },
727
- 'kai-message': { slots: MESSAGE_SLOTS, parts: MESSAGE_PARTS },
728
- 'kai-thread': { slots: THREAD_SLOTS },
729
- 'kai-prompt-input': { slots: PROMPT_INPUT_SLOTS, parts: PROMPT_INPUT_PARTS },
730
- 'kai-button': { slots: BUTTON_SLOTS, parts: BUTTON_PARTS, children: 'The button\'s label. Omit it for an icon-only button (pair with `aria-label`).' },
731
- 'kai-badge': { parts: BADGE_PARTS, children: 'The badge\'s label: text, or a small inline icon plus text.' },
732
- 'kai-icon': { parts: ICON_PARTS },
733
- 'kai-separator': { parts: SEPARATOR_PARTS },
734
- 'kai-scroll-area': { parts: SCROLL_AREA_PARTS, children: 'The scrollable content.' },
735
- 'kai-notice': { slots: NOTICE_SLOTS, children: 'The notice message. `icon` and `action` are the named seams around it.' },
736
- 'kai-hover-card': { slots: HOVER_CARD_SLOTS, children: 'The TRIGGER the card hovers off. The card body is the `card` slot.' },
737
- 'kai-menu': { slots: MENU_SLOTS, parts: MENU_PARTS },
738
- 'kai-skeleton': { parts: SKELETON_PARTS },
739
- 'kai-attachments': { parts: ATTACHMENTS_PARTS },
740
- 'kai-status': { parts: STATUS_PARTS },
741
- 'kai-tabs': { parts: TABS_PARTS },
742
- 'kai-voice-output': { parts: VOICE_OUTPUT_PARTS },
743
- 'kai-screen': { slots: SCREEN_SLOTS, parts: SCREEN_PARTS, children: 'The screen body, below the title bar.' },
744
- 'kai-card': { slots: CARD_SLOTS, parts: CARD_PARTS, children: 'The card body, below the header/media regions.' },
745
- 'kai-workspace': { slots: WORKSPACE_SLOTS, parts: WORKSPACE_PARTS, children: 'The main region content (same region as the `main` slot): your `<kai-chat>`, or any app view.' },
746
- 'kai-nav': { parts: NAV_PARTS },
747
- 'kai-coachmark': { slots: COACHMARK_SLOTS, parts: COACHMARK_PARTS, children: 'The ANCHOR the coachmark points at: the element it attaches to and positions against. The bubble body is the `content` slot.' },
748
- 'kai-progress-bar': { parts: PROGRESS_BAR_PARTS },
749
- 'kai-context': { parts: CONTEXT_PARTS },
750
- 'kai-file-tree': { parts: FILE_TREE_PARTS },
751
- 'kai-prompt-dock': { slots: PROMPT_DOCK_SLOTS, parts: PROMPT_DOCK_PARTS, children: 'The input the dock wraps, typically a `<kai-prompt-input>`. The `top`/`bottom` slots are the lips around it.' },
752
- 'kai-segmented': { parts: SEGMENTED_PARTS },
753
- 'kai-settings-group': { parts: SETTINGS_GROUP_PARTS, children: 'The `<kai-setting-item>` rows in this group.' },
754
- 'kai-setting-item': { slots: SETTING_ITEM_SLOTS, parts: SETTING_ITEM_PARTS },
755
- 'kai-pane': { slots: PANE_SLOTS, parts: PANE_PARTS, children: 'The pane body, below the header row.' },
756
- 'kai-pane-group': { parts: PANE_GROUP_PARTS, children: 'Content shown for every tab. Use it INSTEAD of the per-tab `slot="<tab id>"` seams when you swap the content yourself.' },
757
- 'kai-agent-card': { parts: AGENT_CARD_PARTS },
758
- 'kai-dialog': { slots: DIALOG_SLOTS, parts: DIALOG_PARTS, children: 'The dialog body, between the `header` and `footer` slots.' },
759
- 'kai-dock': { slots: DOCK_SLOTS, parts: DOCK_PARTS, children: 'The panel body, the same region as `slot="panel"`.' },
760
- 'kai-input': { slots: INPUT_SLOTS, parts: INPUT_PARTS },
761
- 'kai-search': { parts: SEARCH_PARTS },
762
- 'kai-kbd': { parts: KBD_PARTS, children: 'Literal key text, when you are not using the `keys` prop to render key caps.' },
763
- 'kai-editable-label': { parts: EDITABLE_LABEL_PARTS },
764
- 'kai-empty': { slots: EMPTY_SLOTS, children: 'The empty-state body below the title/description, usually the call to action.' },
765
- 'kai-file-upload': { children: 'Custom dropzone content, replacing the default label (the `label` prop is the fallback).' },
766
- 'kai-popover': { slots: POPOVER_SLOTS, children: 'The popover panel body. The control that opens it is the `trigger` slot.' },
767
- 'kai-dropdown': { slots: DROPDOWN_SLOTS, children: 'The menu body: your own rows. Give each `role="menuitem"`. The control that opens it is the `trigger` slot.' },
768
- 'kai-resizable': { children: 'The `<kai-resizable-item>` panels, in order. Dividers are inserted between them.' },
769
- 'kai-resizable-item': { children: 'This panel\'s content.' },
770
- 'kai-tooltip': { children: 'The TRIGGER the tooltip describes. The tip text is the `text` prop.' },
771
- 'kai-code-block': { parts: CODE_BLOCK_PARTS },
772
- 'kai-audio-visualizer': { parts: AUDIO_VISUALIZER_PARTS },
773
- };
774
-
775
- /**
776
- * Which slots have projected light-DOM content — a DIRECT child of `host`
777
- * carrying the matching `slot` attribute. Pure and synchronous; safe in jsdom
778
- * and SSR (returns all-false when `host` has no matching children). The facade
779
- * calls this on mount and on every childList mutation.
780
- */
781
- export function readSlots(host: Element, defs: SlotDef[] = CHAT_SLOTS): Record<string, boolean> {
782
- const out: Record<string, boolean> = {};
783
- for (const def of defs) {
784
- out[def.name] = !!host.querySelector(`:scope > [slot="${def.name}"]`);
785
- }
786
- return out;
787
- }