@kitn.ai/ui 0.27.0 → 0.29.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 (612) hide show
  1. package/README.md +10 -2
  2. package/dist/{Icon-BnFKqqtY.js → Icon-DObhsRtm.js} +1 -1
  3. package/dist/{action-icons-CBskfBMz.js → action-icons-CcgNN2oT.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-CjRU3JgV.js +1 -0
  7. package/dist/arrow-left-Bnpb1UEW.js +1 -0
  8. package/dist/{artifact-CvXEm1lS.js → artifact-Bwt7OgcR.js} +1 -1
  9. package/dist/{attachments-C43ZegEq.js → attachments-Qr4kg-2b.js} +1 -1
  10. package/dist/{audio-visualizer-B-79y1Tj.js → audio-visualizer-DToYdfSc.js} +1 -1
  11. package/dist/{badge-BpUbq8c0.js → badge-CdEu_jn2.js} +1 -1
  12. package/dist/{bell-sn17Ip9v.js → bell-DQAAOpDz.js} +1 -1
  13. package/dist/{button-BH6rN0U-.js → button-DkuOnGLy.js} +1 -1
  14. package/dist/{card-renderer-Cb1gQmth.js → card-renderer-Jx70m6_l.js} +1 -1
  15. package/dist/{card-routing-DifQgS7n.js → card-routing-0YidER_3.js} +1 -1
  16. package/dist/check-njkVdZu2.js +1 -0
  17. package/dist/{checkbox-Dc9Yov_B.js → checkbox-D7iRB3nL.js} +1 -1
  18. package/dist/{checkbox-group-B1kDLLYk.js → checkbox-group-B2_rpoPM.js} +1 -1
  19. package/dist/chevron-down-B72s6PXR.js +1 -0
  20. package/dist/chevron-right-BatuHzUm.js +1 -0
  21. package/dist/{choice-card-BT3c1S8g.js → choice-card-m0BYqqOK.js} +1 -1
  22. package/dist/circle-check-B62pODB3.js +1 -0
  23. package/dist/{circle-x-wobWkoSx.js → circle-x-BPG0iPst.js} +1 -1
  24. package/dist/circle-zx0ByzY9.js +1 -0
  25. package/dist/code-block-ClMLKb7C.js +1 -0
  26. package/dist/{collapsible-CPJbf6FM.js → collapsible-B4DlWicL.js} +1 -1
  27. package/dist/components/chat-thread.d.ts +89 -1
  28. package/dist/components/conversation-item.d.ts +16 -0
  29. package/dist/components/conversation-panel.d.ts +29 -0
  30. package/dist/components/home-panel.d.ts +34 -0
  31. package/dist/components/widget-tab-bar.d.ts +16 -0
  32. package/dist/{composer-CjngLzal.js → composer-sQ0HcvyG.js} +3 -3
  33. package/dist/{confirm-card-DCx_A4bU.js → confirm-card-rQWDQsnC.js} +1 -1
  34. package/dist/construct-cli.es.js +185 -17
  35. package/dist/construct.d.ts +5 -0
  36. package/dist/construct.js +327 -0
  37. package/dist/{context-BY8V-Nlp.js → context-0kg4ZX1J.js} +1 -1
  38. package/dist/controllable-CnGpMF6r.js +1 -0
  39. package/dist/conversation-item-BxwQLaFJ.js +1 -0
  40. package/dist/conversation-list-BCfGN1JU.js +1 -0
  41. package/dist/{copy-B6DO4PqB.js → copy-n9u9rqpi.js} +1 -1
  42. package/dist/core-C8fzo39E.js +1 -12
  43. package/dist/{create-tween-CnMHviKB.js → create-tween-C-q-JCM-.js} +1 -1
  44. package/dist/{create-tween-D1aiGZZh.js → create-tween-CRrJXxBd.js} +1 -1
  45. package/dist/{create-tween-BPzaefTp.js → create-tween-DZ3RRDHD.js} +1 -1
  46. package/dist/{create-tween-DUSQUKpr.js → create-tween-uPkArjIG.js} +1 -1
  47. package/dist/custom-elements.json +51 -2
  48. package/dist/{default-input-CucQEOqH.js → default-input-CaMrJkgH.js} +1 -1
  49. package/dist/define-By-uL588.js +1 -0
  50. package/dist/define.js +2 -2
  51. package/dist/define.server.js +2 -2
  52. package/dist/{disclosure-CbLtajUQ.js → disclosure-WUImBbDv.js} +1 -1
  53. package/dist/{dropdown-BwhViJFd.js → dropdown-wZVeJOMd.js} +1 -1
  54. package/dist/elements/agent-card.js +1 -1
  55. package/dist/elements/artifact.js +1 -1
  56. package/dist/elements/attachments.js +1 -1
  57. package/dist/elements/audio-visualizer.js +1 -1
  58. package/dist/elements/avatar.js +1 -1
  59. package/dist/elements/badge.js +1 -1
  60. package/dist/elements/button.js +1 -1
  61. package/dist/elements/card.js +1 -1
  62. package/dist/elements/cards.js +1 -1
  63. package/dist/elements/chain-of-thought.js +1 -1
  64. package/dist/elements/chat-scope-picker.js +1 -1
  65. package/dist/elements/chat-workspace.js +1 -1
  66. package/dist/elements/chat.js +1 -1
  67. package/dist/elements/checkbox-group.js +1 -1
  68. package/dist/elements/checkbox.js +1 -1
  69. package/dist/elements/checkpoint.js +1 -1
  70. package/dist/elements/choice.js +1 -1
  71. package/dist/elements/coachmark.js +1 -1
  72. package/dist/elements/code-block.js +1 -1
  73. package/dist/elements/command.js +1 -1
  74. package/dist/elements/compare.js +1 -1
  75. package/dist/elements/composer.js +1 -1
  76. package/dist/elements/confirm-card.js +1 -1
  77. package/dist/elements/context-meter.js +1 -1
  78. package/dist/elements/conversation-item.js +1 -1
  79. package/dist/elements/conversation-list.js +1 -1
  80. package/dist/elements/dialog.js +1 -1
  81. package/dist/elements/dock.js +3 -3
  82. package/dist/elements/dropdown.js +1 -1
  83. package/dist/elements/editable-label.js +1 -1
  84. package/dist/elements/embed.js +1 -1
  85. package/dist/elements/empty.js +1 -1
  86. package/dist/elements/feedback-bar.js +1 -1
  87. package/dist/elements/file-tree.js +1 -1
  88. package/dist/elements/file-upload.js +1 -1
  89. package/dist/elements/form.js +1 -1
  90. package/dist/elements/hover-card.js +1 -1
  91. package/dist/elements/icon.js +1 -1
  92. package/dist/elements/image.js +1 -1
  93. package/dist/elements/input.js +1 -1
  94. package/dist/elements/kbd.js +1 -1
  95. package/dist/elements/link-preview.js +1 -1
  96. package/dist/elements/loader.js +1 -1
  97. package/dist/elements/markdown.js +1 -1
  98. package/dist/elements/menu.js +1 -1
  99. package/dist/elements/message-skills.js +1 -1
  100. package/dist/elements/message.js +1 -1
  101. package/dist/elements/model-switcher.js +1 -1
  102. package/dist/elements/nav.js +1 -1
  103. package/dist/elements/notice.js +1 -1
  104. package/dist/elements/pane-grid.js +1 -1
  105. package/dist/elements/pane-group.js +1 -1
  106. package/dist/elements/pane.js +1 -1
  107. package/dist/elements/popover.js +1 -1
  108. package/dist/elements/progress-bar.js +1 -1
  109. package/dist/elements/prompt-dock.js +1 -1
  110. package/dist/elements/prompt-input.js +1 -1
  111. package/dist/elements/prompt-suggestions.js +1 -1
  112. package/dist/elements/radio-group.js +1 -1
  113. package/dist/elements/reasoning.js +1 -1
  114. package/dist/elements/remote.js +1 -1
  115. package/dist/elements/resizable.js +1 -1
  116. package/dist/elements/response-stream.js +1 -1
  117. package/dist/elements/screen.js +1 -1
  118. package/dist/elements/scroll-area.js +1 -1
  119. package/dist/elements/scroll-button.js +1 -1
  120. package/dist/elements/search.js +1 -1
  121. package/dist/elements/segmented.js +1 -1
  122. package/dist/elements/select.js +1 -1
  123. package/dist/elements/separator.js +1 -1
  124. package/dist/elements/setting-item.js +1 -1
  125. package/dist/elements/settings-group.js +1 -1
  126. package/dist/elements/skeleton.js +1 -1
  127. package/dist/elements/slider.js +1 -1
  128. package/dist/elements/source.js +1 -1
  129. package/dist/elements/status.js +1 -1
  130. package/dist/elements/switch.js +1 -1
  131. package/dist/elements/tabs.js +1 -1
  132. package/dist/elements/tasks.js +1 -1
  133. package/dist/elements/text-shimmer.js +1 -1
  134. package/dist/elements/thinking-bar.js +1 -1
  135. package/dist/elements/thread.js +1 -1
  136. package/dist/elements/toast.js +1 -1
  137. package/dist/elements/tool.js +1 -1
  138. package/dist/elements/tooltip.js +1 -1
  139. package/dist/elements/voice-input.js +1 -1
  140. package/dist/elements/voice-output.js +1 -1
  141. package/dist/elements.d.ts +20 -4
  142. package/dist/{ellipsis-DFr4Vqr3.js → ellipsis-CbOpJnU3.js} +1 -1
  143. package/dist/{embed-5s_vU4J0.js → embed-CrfjkbUG.js} +1 -1
  144. package/dist/engine-javascript-C1x7zo1_.js +1 -141
  145. package/dist/{external-link-u9d85ORQ.js → external-link-ByXAwBBQ.js} +1 -1
  146. package/dist/{file-text-CX7_x42o.js → file-text-DMib2qwt.js} +1 -1
  147. package/dist/{file-tree-D3kBjXI5.js → file-tree-CJqM2aP7.js} +1 -1
  148. package/dist/{folder-V-YdIL8f.js → folder-_BAb929C.js} +1 -1
  149. package/dist/{form-BRNUMCN2.js → form-DSZgZQZk.js} +1 -1
  150. package/dist/{hover-card-DaeiYrTA.js → hover-card-BQbul9eq.js} +1 -1
  151. package/dist/{icon-BpixdZNq.js → icon-CdcfRhYI.js} +1 -1
  152. package/dist/index.d.ts +3 -1
  153. package/dist/index.js +2842 -2703
  154. package/dist/index.server.js +2820 -2681
  155. package/dist/{info-8mFsIjS3.js → info-DsFjGuI_.js} +1 -1
  156. package/dist/{input-d1Yuu-hz.js → input-DKbmkMos.js} +1 -1
  157. package/dist/kai.es.js +1 -1
  158. package/dist/{kbd-961zMPFB.js → kbd-PvdGhX4s.js} +1 -1
  159. package/dist/{link-preview-DIIbV2Sd.js → link-preview-DbM1866N.js} +1 -1
  160. package/dist/{link-DlZZBGaR.js → link-zF8PzWfF.js} +1 -1
  161. package/dist/{loader-YQszHFaW.js → loader-BM4CEz4G.js} +1 -1
  162. package/dist/{markdown-CVk1MPsj.js → markdown-LMvmAyBk.js} +7 -7
  163. package/dist/mcp.es.js +79 -5
  164. package/dist/{message-CwKVEdZg.js → message-BSsgvHvf.js} +1 -1
  165. package/dist/{message-DS8lzHc1.js → message-BYZECyek.js} +1 -1
  166. package/dist/message-circle-DruwObfX.js +1 -0
  167. package/dist/message-square-BG6q6mlm.js +1 -0
  168. package/dist/{minimize-2-UEZmP2QT.js → minimize-2-BQRoBV1V.js} +1 -1
  169. package/dist/{model-switcher-Kk1jEQ5t.js → model-switcher-CMpCOYcB.js} +1 -1
  170. package/dist/{overlay-C1od6LOz.js → overlay-Cb-MkyDa.js} +1 -1
  171. package/dist/{panel-right-ryET0yyn.js → panel-right-i8warFxT.js} +1 -1
  172. package/dist/{paperclip-BDNoZFJP.js → paperclip-ByY3UVO6.js} +1 -1
  173. package/dist/play-BvKKq3fX.js +1 -0
  174. package/dist/primitives/conversation-store.d.ts +54 -0
  175. package/dist/{progress-bar-BvYX0aoy.js → progress-bar-jVAHvMUf.js} +1 -1
  176. package/dist/{prompt-suggestion-BRFu2lcu.js → prompt-suggestion-CD-qtNgC.js} +1 -1
  177. package/dist/{radio-DcL23cNJ.js → radio-BsoBMhkF.js} +1 -1
  178. package/dist/react/index.d.ts +393 -0
  179. package/dist/react.js +20 -20
  180. package/dist/{reasoning-Cackq4Rh.js → reasoning-4kBPtlTx.js} +1 -1
  181. package/dist/register-impl-B1hLkrI8.js +424 -0
  182. package/dist/{resizable-Cp9HUYih.js → resizable-uPmY9VY-.js} +1 -1
  183. package/dist/{rotate-ccw-0DLRDHH5.js → rotate-ccw-B2xn93py.js} +1 -1
  184. package/dist/{rotate-cw-DOB9IGcU.js → rotate-cw-CMVLoCyH.js} +1 -1
  185. package/dist/{scroll-area-emVmWP4K.js → scroll-area-BqLUo8ZZ.js} +1 -1
  186. package/dist/{scroll-button-CeP_gv1x.js → scroll-button-DslXiJyL.js} +1 -1
  187. package/dist/{select-CWmu00tS.js → select-2cLRtPGT.js} +1 -1
  188. package/dist/{separator-CE6vly6z.js → separator-BWQtNJcM.js} +1 -1
  189. package/dist/{settings-CE-78SvZ.js → settings-BBR63jLg.js} +1 -1
  190. package/dist/{settings-group-ZFWNxFQR.js → settings-group-B2ciy-Iw.js} +1 -1
  191. package/dist/{skeleton-BebdP4mf.js → skeleton-CkHI-HgC.js} +1 -1
  192. package/dist/{slider-BAKRYUlz.js → slider-DDR9U-i0.js} +1 -1
  193. package/dist/{solid-BE5ui6sy.js → solid-BzCFdL25.js} +7720 -7058
  194. package/dist/{solid-DFhsce3O.js → solid-DruVOXnf.js} +5864 -5283
  195. package/dist/solid.d.ts +6 -2
  196. package/dist/solid.js +217 -210
  197. package/dist/solid.server.js +217 -210
  198. package/dist/{source-B0FlguSx.js → source-GEnFF528.js} +1 -1
  199. package/dist/{star-CBMZvLuN.js → star-CilHq8GP.js} +1 -1
  200. package/dist/store-Ciyk6eZG.js +1 -0
  201. package/dist/{switch-CViARZCy.js → switch-KkeQIbuH.js} +1 -1
  202. package/dist/{tasks-card-MjCcOhR_.js → tasks-card-BrN4bggJ.js} +1 -1
  203. package/dist/{text-shimmer-DKlwRF2G.js → text-shimmer-Dcj1MHuq.js} +1 -1
  204. package/dist/{textarea-3ay2Me2-.js → textarea-Dpvbngbg.js} +1 -1
  205. package/dist/theme.tokens.css +28 -0
  206. package/dist/{thumbs-up-DQcu2HMO.js → thumbs-up-CsT9Wzb9.js} +1 -1
  207. package/dist/{toast-store-C6yKOhbk.js → toast-store-tgK6MuMv.js} +1 -1
  208. package/dist/{tool-BCYNlfKy.js → tool-DzUjIBT8.js} +1 -1
  209. package/dist/{tooltip-05zI4hjs.js → tooltip-Bkkg_4t0.js} +1 -1
  210. package/dist/{trash-2-BR1RxGky.js → trash-2-jBKxjGGQ.js} +1 -1
  211. package/dist/{triangle-alert-DHohDOCy.js → triangle-alert-DlQ68ppf.js} +1 -1
  212. package/dist/types.d.ts +48 -3
  213. package/dist/ui/dock.d.ts +29 -0
  214. package/dist/{upload-BbGW6A_u.js → upload-TcAHXv9W.js} +1 -1
  215. package/dist/{url-scheme-policy-DHpoTJwB.js → url-scheme-policy-DR5DgvkM.js} +1 -1
  216. package/dist/{use-card-resolution-CJW4grFa.js → use-card-resolution-DaZqAdWf.js} +1 -1
  217. package/dist/{variant-aurora-xiMPty8f.js → variant-aurora-BhLuYxJR.js} +1 -1
  218. package/dist/{variant-aurora-BUOVgPOB.js → variant-aurora-CNmfHhcx.js} +2 -2
  219. package/dist/{variant-aurora-CUsUJvFI.js → variant-aurora-D6GsdTPA.js} +2 -2
  220. package/dist/{variant-aurora-CW2i4bfr.js → variant-aurora-DbW_OWL2.js} +1 -1
  221. package/dist/{variant-custom-D91HjAKz.js → variant-custom-BRvaNHSi.js} +1 -1
  222. package/dist/{variant-custom-BQtOnmeO.js → variant-custom-BvYHR62b.js} +1 -1
  223. package/dist/{variant-custom-CAnzzppW.js → variant-custom-DMTrEO5w.js} +2 -2
  224. package/dist/{variant-custom-CAm9L-E5.js → variant-custom-DV2x254s.js} +2 -2
  225. package/dist/{variant-wave-Ca1Ls4_y.js → variant-wave-BNMGrDfj.js} +2 -2
  226. package/dist/{variant-wave-uY5crU_K.js → variant-wave-BpDd8t3Z.js} +1 -1
  227. package/dist/{variant-wave-CxX39DKd.js → variant-wave-CyBueXj9.js} +2 -2
  228. package/dist/{variant-wave-DYyzIIZv.js → variant-wave-sp-qwsdI.js} +1 -1
  229. package/dist/x-Z5UntkIJ.js +1 -0
  230. package/frameworks/react/index.tsx +14 -4
  231. package/llms-full.txt +7 -2
  232. package/package.json +16 -16
  233. package/src/elements/element-meta.json +49 -6
  234. package/theme.css +28 -0
  235. package/bin/route.test.js +0 -58
  236. package/dist/arrow-down-Br0qtpsz.js +0 -1
  237. package/dist/arrow-left-Dj7xgE12.js +0 -1
  238. package/dist/check-DPeeMUYx.js +0 -1
  239. package/dist/chevron-down-CHSWk7ZT.js +0 -1
  240. package/dist/chevron-right-B7l_fMgx.js +0 -1
  241. package/dist/circle-Bb0yOpqM.js +0 -1
  242. package/dist/circle-check-BGZpCiz7.js +0 -1
  243. package/dist/code-block-CUQ5mtv0.js +0 -1
  244. package/dist/controllable-D43BKmtX.js +0 -1
  245. package/dist/conversation-list-D4lLU_yS.js +0 -1
  246. package/dist/define-CGGX-7Vg.js +0 -1
  247. package/dist/message-circle-Xf8Q-vZp.js +0 -1
  248. package/dist/message-square-Cxnwgkns.js +0 -1
  249. package/dist/play-OFIvYXUQ.js +0 -1
  250. package/dist/register-impl-C7rENvPK.js +0 -424
  251. package/dist/store-7eoadydQ.js +0 -1
  252. package/dist/x-C5m1JFgi.js +0 -1
  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 -131
  263. package/src/agent-tooling/construct/codegen.ts +0 -1353
  264. package/src/agent-tooling/construct/construct.v1.schema.json +0 -250
  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 -23
  269. package/src/agent-tooling/construct/schema.ts +0 -371
  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 -518
  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 -218
  336. package/src/components/conversation-list.tsx +0 -429
  337. package/src/components/dismissed-stub.tsx +0 -80
  338. package/src/components/embed.tsx +0 -200
  339. package/src/components/empty.tsx +0 -177
  340. package/src/components/feedback-bar.tsx +0 -166
  341. package/src/components/file-tree.tsx +0 -530
  342. package/src/components/file-upload.tsx +0 -167
  343. package/src/components/form-widgets.tsx +0 -525
  344. package/src/components/form.tsx +0 -1296
  345. package/src/components/image.tsx +0 -65
  346. package/src/components/link-preview.tsx +0 -195
  347. package/src/components/loader.tsx +0 -367
  348. package/src/components/markdown.tsx +0 -162
  349. package/src/components/message-skills.tsx +0 -40
  350. package/src/components/message.tsx +0 -765
  351. package/src/components/model-switcher.tsx +0 -132
  352. package/src/components/prompt-input.tsx +0 -188
  353. package/src/components/prompt-suggestion.tsx +0 -150
  354. package/src/components/reasoning.tsx +0 -293
  355. package/src/components/response-compare-types.ts +0 -152
  356. package/src/components/response-compare.tsx +0 -455
  357. package/src/components/response-stream.tsx +0 -109
  358. package/src/components/screen.tsx +0 -181
  359. package/src/components/scroll-button.tsx +0 -93
  360. package/src/components/source.tsx +0 -192
  361. package/src/components/tasks-card.tsx +0 -801
  362. package/src/components/text-shimmer.tsx +0 -37
  363. package/src/components/thinking-bar.tsx +0 -50
  364. package/src/components/thread.tsx +0 -228
  365. package/src/components/toast.tsx +0 -503
  366. package/src/components/tool-classify.ts +0 -26
  367. package/src/components/tool-types.ts +0 -49
  368. package/src/components/tool.tsx +0 -190
  369. package/src/components/use-card-resolution.ts +0 -44
  370. package/src/components/voice-input.tsx +0 -222
  371. package/src/components/voice-output.tsx +0 -242
  372. package/src/components/workspace-shell.tsx +0 -285
  373. package/src/diagnostics/hook.ts +0 -352
  374. package/src/diagnostics/index.ts +0 -82
  375. package/src/diagnostics/report-request.ts +0 -296
  376. package/src/elements/agent-card.tsx +0 -67
  377. package/src/elements/artifact.tsx +0 -194
  378. package/src/elements/attachments.tsx +0 -140
  379. package/src/elements/audio-visualizer.tsx +0 -227
  380. package/src/elements/autoloader.ts +0 -89
  381. package/src/elements/avatar.tsx +0 -33
  382. package/src/elements/badge.tsx +0 -32
  383. package/src/elements/button.tsx +0 -149
  384. package/src/elements/card.tsx +0 -133
  385. package/src/elements/cards.tsx +0 -266
  386. package/src/elements/chain-of-thought.tsx +0 -141
  387. package/src/elements/chat-scope-picker.tsx +0 -65
  388. package/src/elements/chat-types.ts +0 -102
  389. package/src/elements/chat-workspace.tsx +0 -188
  390. package/src/elements/chat.tsx +0 -212
  391. package/src/elements/checkbox-group.tsx +0 -164
  392. package/src/elements/checkbox.tsx +0 -134
  393. package/src/elements/checkpoint.tsx +0 -47
  394. package/src/elements/choice.tsx +0 -100
  395. package/src/elements/coachmark.tsx +0 -90
  396. package/src/elements/code-block.tsx +0 -60
  397. package/src/elements/command.tsx +0 -197
  398. package/src/elements/compare.tsx +0 -111
  399. package/src/elements/compiled.css +0 -2
  400. package/src/elements/composer.tsx +0 -162
  401. package/src/elements/confirm-card.tsx +0 -76
  402. package/src/elements/context-meter.tsx +0 -107
  403. package/src/elements/conversation-item.tsx +0 -120
  404. package/src/elements/conversation-list.tsx +0 -203
  405. package/src/elements/css.ts +0 -5
  406. package/src/elements/default-input.tsx +0 -392
  407. package/src/elements/define-entry.ts +0 -12
  408. package/src/elements/define.tsx +0 -563
  409. package/src/elements/diagnostic-events.ts +0 -114
  410. package/src/elements/dialog.tsx +0 -145
  411. package/src/elements/disclosure.ts +0 -95
  412. package/src/elements/dock.tsx +0 -215
  413. package/src/elements/dropdown.tsx +0 -123
  414. package/src/elements/editable-label.tsx +0 -140
  415. package/src/elements/element-data-types.ts +0 -152
  416. package/src/elements/element-diagnostics.ts +0 -392
  417. package/src/elements/element-manifest.json +0 -354
  418. package/src/elements/element-nonscalar.json +0 -185
  419. package/src/elements/element-types.d.ts +0 -4337
  420. package/src/elements/embed.tsx +0 -35
  421. package/src/elements/empty.tsx +0 -29
  422. package/src/elements/feedback-bar.tsx +0 -66
  423. package/src/elements/file-tree.tsx +0 -62
  424. package/src/elements/file-upload.tsx +0 -44
  425. package/src/elements/form.tsx +0 -94
  426. package/src/elements/hover-card.tsx +0 -80
  427. package/src/elements/icon.tsx +0 -41
  428. package/src/elements/image.tsx +0 -32
  429. package/src/elements/input.tsx +0 -492
  430. package/src/elements/kbd.tsx +0 -45
  431. package/src/elements/link-preview.tsx +0 -34
  432. package/src/elements/loader.tsx +0 -25
  433. package/src/elements/markdown.tsx +0 -38
  434. package/src/elements/menu.tsx +0 -241
  435. package/src/elements/message-skills.tsx +0 -83
  436. package/src/elements/message.tsx +0 -361
  437. package/src/elements/model-switcher.tsx +0 -121
  438. package/src/elements/nav.tsx +0 -87
  439. package/src/elements/notice.tsx +0 -53
  440. package/src/elements/pane-grid.tsx +0 -111
  441. package/src/elements/pane-group.tsx +0 -119
  442. package/src/elements/pane.tsx +0 -129
  443. package/src/elements/popover.tsx +0 -81
  444. package/src/elements/progress-bar.tsx +0 -39
  445. package/src/elements/prompt-dock.tsx +0 -82
  446. package/src/elements/prompt-input.tsx +0 -240
  447. package/src/elements/prompt-suggestions.tsx +0 -113
  448. package/src/elements/radio-group.tsx +0 -129
  449. package/src/elements/reasoning.tsx +0 -71
  450. package/src/elements/register-impl.ts +0 -148
  451. package/src/elements/register.ts +0 -76
  452. package/src/elements/remote.tsx +0 -225
  453. package/src/elements/resizable.globals.d.ts +0 -36
  454. package/src/elements/resizable.tsx +0 -704
  455. package/src/elements/response-stream.tsx +0 -40
  456. package/src/elements/screen.tsx +0 -90
  457. package/src/elements/scroll-area.tsx +0 -33
  458. package/src/elements/scroll-button.tsx +0 -179
  459. package/src/elements/search.tsx +0 -185
  460. package/src/elements/segmented.tsx +0 -129
  461. package/src/elements/select.tsx +0 -165
  462. package/src/elements/separator.tsx +0 -36
  463. package/src/elements/setting-item.tsx +0 -50
  464. package/src/elements/settings-group.tsx +0 -37
  465. package/src/elements/skeleton.tsx +0 -45
  466. package/src/elements/slider.tsx +0 -171
  467. package/src/elements/slot-text.ts +0 -73
  468. package/src/elements/slots.ts +0 -787
  469. package/src/elements/source.tsx +0 -126
  470. package/src/elements/status.tsx +0 -42
  471. package/src/elements/styles.css +0 -328
  472. package/src/elements/switch.tsx +0 -118
  473. package/src/elements/tabs.tsx +0 -95
  474. package/src/elements/tasks.tsx +0 -103
  475. package/src/elements/text-shimmer.tsx +0 -28
  476. package/src/elements/thinking-bar.tsx +0 -43
  477. package/src/elements/thread.tsx +0 -139
  478. package/src/elements/toast.tsx +0 -106
  479. package/src/elements/tool.tsx +0 -78
  480. package/src/elements/tooltip.tsx +0 -85
  481. package/src/elements/validate-messages.ts +0 -76
  482. package/src/elements/voice-input.tsx +0 -100
  483. package/src/elements/voice-output.tsx +0 -82
  484. package/src/index.ts +0 -428
  485. package/src/primitives/audio-bands.ts +0 -174
  486. package/src/primitives/card-component-types.ts +0 -63
  487. package/src/primitives/card-contract.ts +0 -80
  488. package/src/primitives/card-data-types.ts +0 -361
  489. package/src/primitives/card-host.tsx +0 -37
  490. package/src/primitives/card-recovery.ts +0 -160
  491. package/src/primitives/card-registry.tsx +0 -78
  492. package/src/primitives/card-resolution.ts +0 -36
  493. package/src/primitives/card-routing.ts +0 -85
  494. package/src/primitives/card-schemas/artifact.schema.json +0 -92
  495. package/src/primitives/card-schemas/card-envelope.schema.json +0 -14
  496. package/src/primitives/card-schemas/card-event.schema.json +0 -12
  497. package/src/primitives/card-schemas/choice.schema.json +0 -75
  498. package/src/primitives/card-schemas/confirm.schema.json +0 -65
  499. package/src/primitives/card-schemas/embed.schema.json +0 -63
  500. package/src/primitives/card-schemas/form.result.schema.json +0 -7
  501. package/src/primitives/card-schemas/form.schema.json +0 -53
  502. package/src/primitives/card-schemas/link.schema.json +0 -54
  503. package/src/primitives/card-schemas/tasks.result.schema.json +0 -16
  504. package/src/primitives/card-schemas/tasks.schema.json +0 -83
  505. package/src/primitives/card-tags.ts +0 -61
  506. package/src/primitives/card-validate-cards.ts +0 -255
  507. package/src/primitives/card-validate-schemas.ts +0 -58
  508. package/src/primitives/card-validate.ts +0 -131
  509. package/src/primitives/chat-config.tsx +0 -103
  510. package/src/primitives/composer-model.ts +0 -49
  511. package/src/primitives/composer-triggers.ts +0 -35
  512. package/src/primitives/controllable.ts +0 -21
  513. package/src/primitives/create-kai-chat.ts +0 -66
  514. package/src/primitives/create-tween.ts +0 -266
  515. package/src/primitives/embed-providers.ts +0 -254
  516. package/src/primitives/field-mask.ts +0 -256
  517. package/src/primitives/field-semantics.ts +0 -115
  518. package/src/primitives/highlighter.ts +0 -157
  519. package/src/primitives/input-mask.ts +0 -853
  520. package/src/primitives/link-preview.ts +0 -87
  521. package/src/primitives/message-feedback.ts +0 -124
  522. package/src/primitives/pdf-preview.ts +0 -121
  523. package/src/primitives/toast-store.ts +0 -338
  524. package/src/primitives/url-scheme-policy.ts +0 -70
  525. package/src/primitives/use-audio-analysis.ts +0 -340
  526. package/src/primitives/use-auto-resize.ts +0 -31
  527. package/src/primitives/use-resize-observer.ts +0 -45
  528. package/src/primitives/use-sequencer.ts +0 -72
  529. package/src/primitives/use-speech-recognition.ts +0 -146
  530. package/src/primitives/use-stick-to-bottom.ts +0 -75
  531. package/src/primitives/use-text-stream.ts +0 -143
  532. package/src/primitives/use-voice-recorder.ts +0 -62
  533. package/src/primitives/visualizer-sequences.ts +0 -350
  534. package/src/remote/host-embed.ts +0 -345
  535. package/src/remote/index.ts +0 -2
  536. package/src/remote/origin.ts +0 -30
  537. package/src/remote/provider-runtime.ts +0 -262
  538. package/src/remote/provider.ts +0 -2
  539. package/src/remote/validate.ts +0 -22
  540. package/src/remote/version.ts +0 -12
  541. package/src/remote/wire.ts +0 -48
  542. package/src/schemas/from-tool-call.ts +0 -151
  543. package/src/schemas/index.ts +0 -341
  544. package/src/schemas/provider-subsets.ts +0 -538
  545. package/src/schemas/registry.ts +0 -355
  546. package/src/schemas/tool-defs.ts +0 -793
  547. package/src/solid.ts +0 -165
  548. package/src/state/index.ts +0 -44
  549. package/src/state/messages.ts +0 -53
  550. package/src/state/mock.ts +0 -297
  551. package/src/state/parts.ts +0 -295
  552. package/src/state/persistence.ts +0 -180
  553. package/src/state/stream.ts +0 -246
  554. package/src/state/suggestions.ts +0 -9
  555. package/src/state/threads.ts +0 -142
  556. package/src/test-utils/fake-clock.ts +0 -88
  557. package/src/types.ts +0 -53
  558. package/src/ui/action-icons.ts +0 -53
  559. package/src/ui/agent-card.tsx +0 -218
  560. package/src/ui/avatar.tsx +0 -23
  561. package/src/ui/badge.tsx +0 -21
  562. package/src/ui/button.tsx +0 -49
  563. package/src/ui/card.tsx +0 -245
  564. package/src/ui/checkbox-group.tsx +0 -153
  565. package/src/ui/checkbox.tsx +0 -63
  566. package/src/ui/collapsible.tsx +0 -163
  567. package/src/ui/command.tsx +0 -103
  568. package/src/ui/dialog.tsx +0 -223
  569. package/src/ui/dock.tsx +0 -584
  570. package/src/ui/dropdown.tsx +0 -636
  571. package/src/ui/editable-label.tsx +0 -112
  572. package/src/ui/hover-card.tsx +0 -345
  573. package/src/ui/icon.tsx +0 -167
  574. package/src/ui/input.tsx +0 -391
  575. package/src/ui/kbd.tsx +0 -118
  576. package/src/ui/nav.tsx +0 -282
  577. package/src/ui/notice.tsx +0 -84
  578. package/src/ui/overlay.tsx +0 -277
  579. package/src/ui/pane-grid.tsx +0 -117
  580. package/src/ui/pane-group.tsx +0 -291
  581. package/src/ui/pane.tsx +0 -193
  582. package/src/ui/popover.tsx +0 -106
  583. package/src/ui/progress-bar.tsx +0 -83
  584. package/src/ui/prompt-dock.tsx +0 -145
  585. package/src/ui/radio.tsx +0 -150
  586. package/src/ui/resizable.tsx +0 -693
  587. package/src/ui/scroll-area.tsx +0 -26
  588. package/src/ui/segmented.tsx +0 -109
  589. package/src/ui/select.tsx +0 -168
  590. package/src/ui/separator.tsx +0 -10
  591. package/src/ui/settings-group.tsx +0 -67
  592. package/src/ui/skeleton.tsx +0 -73
  593. package/src/ui/slider.tsx +0 -178
  594. package/src/ui/status.tsx +0 -48
  595. package/src/ui/switch.tsx +0 -119
  596. package/src/ui/tabs.tsx +0 -168
  597. package/src/ui/textarea.tsx +0 -21
  598. package/src/ui/tooltip.tsx +0 -118
  599. package/src/utils/cn.ts +0 -30
  600. package/src/wire/chunk.ts +0 -248
  601. package/src/wire/consume.ts +0 -599
  602. package/src/wire/diagnostics.ts +0 -727
  603. package/src/wire/encode-probe.ts +0 -214
  604. package/src/wire/encode.ts +0 -947
  605. package/src/wire/files.ts +0 -342
  606. package/src/wire/formats/anthropic.ts +0 -274
  607. package/src/wire/formats/openai.ts +0 -228
  608. package/src/wire/index.ts +0 -95
  609. package/src/wire/media-types.ts +0 -344
  610. package/src/wire/read.ts +0 -396
  611. package/src/wire/sink-helpers.ts +0 -50
  612. package/src/wire/sse.ts +0 -153
@@ -1,429 +0,0 @@
1
- import { splitProps, For, Show, createSignal, createMemo, onMount, type JSX } from 'solid-js';
2
- import { PanelLeftOpen } from 'lucide-solid';
3
- import { cn } from '../utils/cn';
4
- import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '../ui/collapsible';
5
- import { Button } from '../ui/button';
6
- import { Badge } from '../ui/badge';
7
- import { ScrollArea } from '../ui/scroll-area';
8
- import { ConversationItem } from './conversation-item';
9
- import type { ConversationSummary, ConversationGroup } from '../types';
10
-
11
- /**
12
- * The collapsed-rail fallback: a floating reopen button shown when the
13
- * conversation sidebar is collapsed. Shared by `kai-workspace` (its collapsed
14
- * branch) and the standalone `kai-conversations` (collapsed mode), so the rail
15
- * collapses identically in both. Renders only the button; the host owns the
16
- * surrounding region (the workspace puts the thread beside it, the standalone
17
- * element stands alone). `onExpand` reopens the rail.
18
- */
19
- export interface CollapsedRailProps { onExpand: () => void; class?: string }
20
-
21
- export function CollapsedRail(props: CollapsedRailProps) {
22
- return (
23
- <Button
24
- variant="ghost" size="icon-sm" aria-label="Open sidebar"
25
- class={cn('rounded-full bg-card/80 shadow-sm backdrop-blur', props.class)}
26
- onClick={props.onExpand}
27
- >
28
- <PanelLeftOpen class="size-4" />
29
- </Button>
30
- );
31
- }
32
-
33
- /** Read a conversation item's identity the way the container does: the
34
- * `conversationId` property, else the `conversation-id` attribute, else the
35
- * host `id`. The property is what a framework loop sets; the attributes are
36
- * the plain-HTML spellings (host `id` matches the `<kai-conversation>`
37
- * data-carrier precedent). */
38
- export function readConversationItemId(el: Element): string {
39
- const prop = (el as Element & { conversationId?: unknown }).conversationId;
40
- if (typeof prop === 'string' && prop) return prop;
41
- return el.getAttribute('conversation-id') ?? el.id;
42
- }
43
-
44
- /** Whether a `<kai-conversation-item>` is STANDALONE — outside the management
45
- * of a `<kai-conversations>` container — and therefore activates ITSELF:
46
- * the facade makes its row body a
47
- * tabbable button and fires `kai-select` on click / Enter / Space. Derived
48
- * from the container's own membership rule, not from mere ancestry: item mode
49
- * queries `:scope > kai-conversation-item` (direct children only), so an item
50
- * wrapped in another element inside a container is standalone too — the
51
- * container's controller never stamps or activates it. Inside a container
52
- * (a direct child), the parent-item contract is the ONLY activation
53
- * path: the container dispatches `kai-conversation-select` and owns roving
54
- * tabindex, and the item fires nothing of its own. */
55
- export function isStandaloneConversationItem(el: Element): boolean {
56
- return el.parentElement?.localName !== 'kai-conversations';
57
- }
58
-
59
- export interface ConversationItemsControllerOptions {
60
- /** The current slotted item hosts, in DOM order. */
61
- getItems: () => HTMLElement[];
62
- /** The container's active conversation id. */
63
- getActiveId: () => string | undefined;
64
- /** Item activation (click / Enter / Space). Surfaces as
65
- * `kai-conversation-select` on the element. */
66
- onSelect: (id: string) => void;
67
- }
68
-
69
- export interface ConversationItemsController {
70
- /** Re-derive the ARIA/roving-tabindex bookkeeping over the current items.
71
- * Call on slotchange / child mutation and whenever `activeId` changes. */
72
- sync(): void;
73
- /** The container's items-region click handler (composed-path aware). */
74
- handleClick(e: MouseEvent): void;
75
- /** The container's items-region keydown handler (arrows, Home/End,
76
- * Enter/Space). */
77
- handleKeyDown(e: KeyboardEvent): void;
78
- }
79
-
80
- /**
81
- * The parent-item contract of item mode, as a pure-DOM
82
- * controller so it is host-agnostic: the `kai-conversations` facade wires it over
83
- * its slotted `kai-conversation-item` children, and the jsdom contract tests
84
- * drive it over plain nodes. Solid context cannot cross the element boundary
85
- * (each facade is its own Solid root), so the channel is DOM traversal by
86
- * construction:
87
- *
88
- * - selection flows container to item — exactly one item's BODY node (the
89
- * shadow body of a `kai-conversation-item`, else the node itself; see
90
- * `bodyOf`) is `aria-current="true"`, plus the `active` property on the
91
- * host for the item's own styling hook;
92
- * - `role="button"` is ensured on each item's body node (an authored role is
93
- * left alone);
94
- * - roving tabindex — exactly one body node `tabindex="0"` (the active
95
- * item's, else the first's), the rest `-1`, re-derived on every `sync()`;
96
- * menu content keeps its natural tab order (it is the body's SIBLING, not a
97
- * descendant);
98
- * - activation (click / Enter / Space) calls `onSelect` with the item's id, and
99
- * is SUPPRESSED when the composed path crosses the item's `menu` region
100
- * (light-DOM `slot="menu"` content or the shadow `data-kai-item-menu`
101
- * wrapper), so the consumer's own popover never also selects the row;
102
- * - ArrowUp/ArrowDown/Home/End move focus item-to-item, tabindex following the
103
- * focused item.
104
- */
105
- export function createConversationItemsController(
106
- opts: ConversationItemsControllerOptions,
107
- ): ConversationItemsController {
108
- const itemFromEvent = (e: Event): HTMLElement | undefined => {
109
- const items = opts.getItems();
110
- return e.composedPath().find((n): n is HTMLElement => items.includes(n as HTMLElement));
111
- };
112
- /** The item's ACTIVATION node — the target of role/aria-current/tabindex/
113
- * focus. For a `kai-conversation-item` host that is its shadow body (the
114
- * sibling restructure: the host is the row listitem
115
- * wrapping the body AND the consumer's tabbable menu, so the control
116
- * semantics must sit below it). A bare node with no such body is its own
117
- * control. */
118
- const bodyOf = (item: HTMLElement): HTMLElement =>
119
- (item.shadowRoot?.querySelector('[data-kai-item-body]') as HTMLElement | null) ?? item;
120
- const menuInPath = (e: Event): boolean =>
121
- e.composedPath().some(
122
- (n) =>
123
- n instanceof Element &&
124
- (n.hasAttribute('data-kai-item-menu') || n.getAttribute('slot') === 'menu'),
125
- );
126
- // Write-on-change only. `setAttribute` records a mutation even when the value
127
- // is identical, and the facade re-syncs from a MutationObserver over these very
128
- // nodes — unconditional writes would feed the observer forever.
129
- const setAttr = (el: Element, name: string, value: string) => {
130
- if (el.getAttribute(name) !== value) el.setAttribute(name, value);
131
- };
132
- /** An item whose shadow body has not RENDERED yet must not be stamped: the
133
- * fallback would write control semantics onto the HOST, they would stick
134
- * (the item facade defers to an authored role), and axe then sees exactly
135
- * the role="button"-host-with-focusable-menu shape the restructure removed.
136
- * Measured in the focus-order probe: the container's first sync can run
137
- * before the item elements upgrade. A later sync catches them — the
138
- * facade's own mount mutates host attributes, which re-runs sync through
139
- * the container's MutationObserver read(). Bare nodes (no dash: the jsdom
140
- * stand-ins) are always ready. */
141
- const readyBodies = (items: HTMLElement[]) => {
142
- const out = new Map<HTMLElement, HTMLElement>();
143
- for (const item of items) {
144
- const body = bodyOf(item);
145
- if (body === item && item.localName.includes('-')) continue;
146
- out.set(item, body);
147
- }
148
- return out;
149
- };
150
-
151
- const rove = (items: HTMLElement[], target: HTMLElement | undefined) => {
152
- for (const [item, body] of readyBodies(items)) setAttr(body, 'tabindex', item === target ? '0' : '-1');
153
- };
154
-
155
- const sync = () => {
156
- const items = opts.getItems();
157
- const activeId = opts.getActiveId();
158
- const bodies = readyBodies(items);
159
- let anchor: HTMLElement | undefined;
160
- for (const [item, body] of bodies) {
161
- const isActive = activeId !== undefined && readConversationItemId(item) === activeId;
162
- if (!body.hasAttribute('role')) body.setAttribute('role', 'button');
163
- setAttr(body, 'aria-current', isActive ? 'true' : 'false');
164
- const host = item as HTMLElement & { active?: boolean };
165
- if (host.active !== isActive) host.active = isActive;
166
- if (isActive) anchor = item;
167
- }
168
- rove(items, anchor ?? (bodies.keys().next().value as HTMLElement | undefined));
169
- };
170
-
171
- return {
172
- sync,
173
- handleClick(e) {
174
- const item = itemFromEvent(e);
175
- if (!item || menuInPath(e)) return;
176
- opts.onSelect(readConversationItemId(item));
177
- },
178
- handleKeyDown(e) {
179
- const items = opts.getItems();
180
- if (items.length === 0) return;
181
- const item = itemFromEvent(e);
182
- if (e.key === 'Enter' || e.key === ' ') {
183
- if (!item || menuInPath(e)) return;
184
- e.preventDefault();
185
- opts.onSelect(readConversationItemId(item));
186
- return;
187
- }
188
- let next: HTMLElement | undefined;
189
- const idx = item ? items.indexOf(item) : items.findIndex((i) => bodyOf(i).getAttribute('tabindex') === '0');
190
- if (e.key === 'ArrowDown') next = items[Math.min(idx + 1, items.length - 1)];
191
- else if (e.key === 'ArrowUp') next = items[Math.max(idx - 1, 0)];
192
- else if (e.key === 'Home') next = items[0];
193
- else if (e.key === 'End') next = items[items.length - 1];
194
- if (!next) return;
195
- e.preventDefault();
196
- rove(items, next);
197
- bodyOf(next).focus();
198
- },
199
- };
200
- }
201
-
202
- export interface ConversationListProps {
203
- groups: ConversationGroup[];
204
- conversations: ConversationSummary[];
205
- activeId?: string;
206
- onSelect: (id: string) => void;
207
- onNewChat: () => void;
208
- onToggleSidebar?: () => void;
209
- /** Replaces the built-in title bar (toggle / "Chats" / New chat). */
210
- header?: JSX.Element;
211
- /** A row below the list (e.g. account / settings / usage). */
212
- footer?: JSX.Element;
213
- /** Replaces the built-in "no conversations yet" state. */
214
- empty?: JSX.Element;
215
- /** Dense single-line rows (a leading dot + title, no message count). */
216
- compact?: boolean;
217
- /** Fired whenever the built-in search box query changes (typing or a
218
- * programmatic `clear()`). Lets the facade surface a `kai-search` event. */
219
- onSearchChange?: (query: string) => void;
220
- /** Receive the imperative controller once mounted. The `kai-conversations`
221
- * facade uses it to focus / clear the internal search input. */
222
- controllerRef?: (controller: ConversationListController) => void;
223
- /** Item mode: your OWN rows, rendered inside a list region in place of the
224
- * data rows. When set, the built-in search
225
- * filter, grouping and empty/no-match states do not apply — the consumer's
226
- * loop owns them — while the chrome (header, search box, new-chat, footer)
227
- * still renders and `onSearchChange` still reports queries. The
228
- * `kai-conversations` facade passes its default `<slot>` here when it detects
229
- * `kai-conversation-item` children. */
230
- items?: JSX.Element;
231
- /** Keydown handler for the item-mode list region (the facade wires
232
- * `createConversationItemsController.handleKeyDown`). */
233
- itemsKeyDown?: (e: KeyboardEvent) => void;
234
- /** Click handler for the item-mode list region (the facade wires
235
- * `createConversationItemsController.handleClick`). */
236
- itemsClick?: (e: MouseEvent) => void;
237
- class?: string;
238
- }
239
-
240
- /** Imperative handle exposed via `controllerRef` — surfaces the internal search
241
- * box to the `kai-conversations` facade (the searchQuery signal lives here). */
242
- export interface ConversationListController {
243
- /** Focus the built-in search `<input>`. */
244
- focus(options?: FocusOptions): void;
245
- /** Clear the internal search query (resets the list filter). */
246
- clearSearch(): void;
247
- }
248
-
249
- export function ConversationList(props: ConversationListProps) {
250
- const [local] = splitProps(props, ['groups', 'conversations', 'activeId', 'onSelect', 'onNewChat', 'onToggleSidebar', 'header', 'footer', 'empty', 'compact', 'onSearchChange', 'controllerRef', 'items', 'itemsKeyDown', 'itemsClick', 'class']);
251
- const [searchQuery, setSearchQuery] = createSignal('');
252
- // Item mode: the consumer's own rows replace the data rendering wholesale.
253
- const itemMode = createMemo(() => local.items != null);
254
- const isEmpty = createMemo(() => local.conversations.length === 0);
255
- // The search query is owned here; setQuery is the single mutation point so both
256
- // typing and the imperative clearSearch() notify the facade (→ kai-search).
257
- let searchInput: HTMLInputElement | undefined;
258
- const setQuery = (q: string) => { setSearchQuery(q); local.onSearchChange?.(q); };
259
-
260
- // Hand the imperative controller (focus / clear the search box) to the facade.
261
- onMount(() => {
262
- local.controllerRef?.({
263
- focus: (options) => searchInput?.focus(options),
264
- clearSearch: () => setQuery(''),
265
- });
266
- });
267
-
268
- const filteredConversations = createMemo(() => {
269
- const q = searchQuery().toLowerCase();
270
- if (!q) return local.conversations;
271
- return local.conversations.filter((c) => c.title.toLowerCase().includes(q));
272
- });
273
-
274
- const groupedConversations = createMemo(() => {
275
- const grouped = new Map<string | undefined, ConversationSummary[]>();
276
- for (const conv of filteredConversations()) {
277
- const key = conv.groupId;
278
- if (!grouped.has(key)) grouped.set(key, []);
279
- grouped.get(key)!.push(conv);
280
- }
281
- return grouped;
282
- });
283
-
284
- /**
285
- * Everything that is NOT filed under a rendered group heading: no `groupId` at
286
- * all, OR a `groupId` that matches no entry in `groups`.
287
- *
288
- * The second half used to be dropped on the floor. `groups` drives the render
289
- * loop, so a conversation pointing at a group the consumer had not declared
290
- * (a stale id, a group removed from the array, a filtered/paginated `groups`
291
- * response) vanished from the sidebar with no error and no empty state — the
292
- * list just silently held fewer rows than the data it was given. Falling through
293
- * to "Ungrouped" keeps every conversation the consumer passed in reachable.
294
- */
295
- const ungrouped = createMemo(() => {
296
- const known = new Set((local.groups ?? []).map((g) => g.id));
297
- return filteredConversations().filter((c) => c.groupId == null || !known.has(c.groupId));
298
- });
299
-
300
- return (
301
- <div class={cn('flex flex-col h-full bg-sidebar', local.class)}>
302
- {/* header (replace): the consumer's own title bar, else the built-in one. */}
303
- <Show
304
- when={local.header}
305
- fallback={
306
- <div class="flex items-center justify-between p-3 pb-2">
307
- <div class="flex items-center gap-2">
308
- <Button variant="ghost" size="icon-sm" aria-label="Toggle sidebar" onClick={local.onToggleSidebar}>
309
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
310
- </Button>
311
- <span class="text-sm font-semibold text-foreground">Chats</span>
312
- </div>
313
- <Button variant="ghost" size="icon-sm" aria-label="New chat" onClick={local.onNewChat}>
314
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
315
- </Button>
316
- </div>
317
- }
318
- >
319
- {local.header}
320
- </Show>
321
- <Show when={itemMode() || !isEmpty()}>
322
- <div class="px-3 pb-2">
323
- <div class="flex items-center gap-2 rounded-md bg-surface-strong px-2.5 py-1.5">
324
- <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-muted-foreground"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
325
- <input ref={searchInput} type="text" value={searchQuery()} onInput={(e) => setQuery(e.currentTarget.value)} placeholder="Search chats..."
326
- aria-label="Search chats"
327
- class="bg-transparent text-compact text-foreground placeholder:text-muted-foreground rounded-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring w-full" />
328
- </div>
329
- </div>
330
- </Show>
331
- {/* Item mode: the consumer's own rows in a list region. The container's
332
- filter/grouping/empty states do not apply — the consumer's loop owns
333
- them. */}
334
- <Show when={itemMode()}>
335
- <ScrollArea class="flex-1 px-2">
336
- <div
337
- role="list"
338
- aria-label="Conversations"
339
- part="items"
340
- class="space-y-0.5 py-1"
341
- onKeyDown={(e) => local.itemsKeyDown?.(e)}
342
- onClick={(e) => local.itemsClick?.(e)}
343
- >
344
- {local.items}
345
- </div>
346
- </ScrollArea>
347
- </Show>
348
- {/* list, or the empty state (replace) when there are no conversations. */}
349
- <Show
350
- when={!itemMode() && !isEmpty()}
351
- fallback={
352
- <Show when={!itemMode()}>
353
- <Show
354
- when={local.empty}
355
- fallback={
356
- <div class="flex flex-1 flex-col items-center justify-center gap-1 p-6 text-center text-sm text-muted-foreground">
357
- No conversations yet
358
- </div>
359
- }
360
- >
361
- {local.empty}
362
- </Show>
363
- </Show>
364
- }
365
- >
366
- {/* F-04, decide loudly: a query matching nothing renders a VISIBLE
367
- no-match state, keyed off the FILTERED count — distinct from the
368
- zero-conversations empty state above, which keys off the unfiltered
369
- list (and still owns the `empty` override). */}
370
- <Show when={filteredConversations().length === 0}>
371
- <div class="flex flex-1 flex-col items-center justify-center gap-1 p-6 text-center text-sm text-muted-foreground">
372
- No conversations match your search
373
- </div>
374
- </Show>
375
- <Show when={filteredConversations().length > 0}>
376
- <ScrollArea class="flex-1 px-2">
377
- <For each={local.groups}>
378
- {(group) => {
379
- const convs = createMemo(() => groupedConversations().get(group.id) ?? []);
380
- return (
381
- <Show when={convs().length > 0}>
382
- <GroupSection name={group.name} count={convs().length} conversations={convs()} activeId={local.activeId} onSelect={local.onSelect} compact={local.compact} />
383
- </Show>
384
- );
385
- }}
386
- </For>
387
- <Show when={ungrouped().length > 0}>
388
- <Show
389
- when={local.compact}
390
- fallback={<GroupSection name="Ungrouped" count={ungrouped().length} conversations={ungrouped()} activeId={local.activeId} onSelect={local.onSelect} />}
391
- >
392
- <div class="space-y-0.5 py-1">
393
- <For each={ungrouped()}>
394
- {(conv) => <ConversationItem conversation={conv} isActive={conv.id === local.activeId} onSelect={local.onSelect} compact />}
395
- </For>
396
- </div>
397
- </Show>
398
- </Show>
399
- </ScrollArea>
400
- </Show>
401
- </Show>
402
- {/* footer (inject): a row below the list (account / settings / …). */}
403
- <Show when={local.footer}>
404
- <div class="shrink-0 border-t border-border">{local.footer}</div>
405
- </Show>
406
- </div>
407
- );
408
- }
409
-
410
- function GroupSection(props: { name: string; count: number; conversations: ConversationSummary[]; activeId?: string; onSelect: (id: string) => void; compact?: boolean }) {
411
- const [open, setOpen] = createSignal(true);
412
- return (
413
- <Collapsible open={open()} onOpenChange={setOpen}>
414
- <CollapsibleTrigger class="flex items-center gap-1.5 w-full px-1.5 py-1 rounded-md text-compact text-muted-foreground font-medium hover:bg-muted/30 transition-colors cursor-pointer mt-1.5">
415
- <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
416
- class={cn('transition-transform', !open() && '-rotate-90')}><polyline points="6 9 12 15 18 9"/></svg>
417
- <span>{props.name}</span>
418
- <Badge variant="count" class="ml-auto text-caption">{props.count}</Badge>
419
- </CollapsibleTrigger>
420
- <CollapsibleContent>
421
- <div class="pl-2 mt-0.5 space-y-0.5">
422
- <For each={props.conversations}>
423
- {(conv) => <ConversationItem conversation={conv} isActive={conv.id === props.activeId} onSelect={props.onSelect} compact={props.compact} />}
424
- </For>
425
- </div>
426
- </CollapsibleContent>
427
- </Collapsible>
428
- );
429
- }
@@ -1,80 +0,0 @@
1
- import { type JSX, Show } from 'solid-js';
2
- import { cn } from '../utils/cn';
3
- import { Button } from '../ui/button';
4
- import { Card } from './card';
5
- import { RotateCcw } from 'lucide-solid';
6
-
7
- // ─────────────────────────────────────────────────────────────────────────────
8
- // DismissedStub — the collapsed, re-openable read-only view a card renders once
9
- // the user has dismissed it (a DEFERRED resolution, not a terminal one). It's a
10
- // dense `Card` showing "<intent>: <title> — dismissed" + a ghost Reopen button.
11
- // Pure/presentational: the owning card wires `onReopen` to emit `{kind:'reopen'}`.
12
- // ─────────────────────────────────────────────────────────────────────────────
13
-
14
- /** The card types that render a dismissed stub, mapped to their intent verb. */
15
- export type DismissedCardType = 'confirm' | 'choice' | 'form' | 'tasks';
16
-
17
- const INTENT_LABELS: Record<DismissedCardType, string> = {
18
- confirm: 'Proposed',
19
- choice: 'Choose',
20
- form: 'Form',
21
- tasks: 'Tasks',
22
- };
23
-
24
- /** Map a card `type` to its dismissed-stub intent label ("Proposed:", "Choose:",
25
- * "Form:", "Tasks:"). Falls back to a capitalized type for unknown card types. */
26
- export function stubIntent(type: string): string {
27
- const known = INTENT_LABELS[type as DismissedCardType];
28
- if (known) return `${known}:`;
29
- if (type.length === 0) return 'Card:';
30
- return `${type.charAt(0).toUpperCase()}${type.slice(1)}:`;
31
- }
32
-
33
- export interface DismissedStubProps {
34
- /** The card type, used to derive the intent label ("Proposed:" etc.). */
35
- type: string;
36
- /** The card's title/heading; shown after the intent label. Falls back gracefully. */
37
- title?: string;
38
- /** Re-open handler. The owning card emits `{ kind:'reopen', cardId }`. */
39
- onReopen: () => void;
40
- /** The Reopen button label. Default 'Reopen'. */
41
- reopenLabel?: string;
42
- class?: string;
43
- }
44
-
45
- /**
46
- * `DismissedStub` — the compact stub a card collapses to after it's been dismissed.
47
- * Group-labelled for a11y; the Reopen affordance is a ghost button.
48
- */
49
- export function DismissedStub(props: DismissedStubProps): JSX.Element {
50
- const intent = (): string => stubIntent(props.type);
51
- const title = (): string => props.title ?? 'this card';
52
- const label = (): string => props.reopenLabel ?? 'Reopen';
53
- const groupLabel = (): string => `${intent()} ${title()} — dismissed`;
54
-
55
- return (
56
- <Card dense class={props.class}>
57
- <div
58
- role="group"
59
- aria-label={groupLabel()}
60
- class="flex flex-wrap items-center gap-x-2 gap-y-1"
61
- >
62
- <span class="min-w-0 text-sm text-muted-foreground">
63
- <span class="font-medium text-foreground">{intent()}</span>{' '}
64
- <span class="text-foreground">{title()}</span>
65
- <span class="text-muted-foreground"> — dismissed</span>
66
- </span>
67
- <Button
68
- type="button"
69
- variant="ghost"
70
- size="sm"
71
- class={cn('ml-auto gap-1.5')}
72
- onClick={() => props.onReopen()}
73
- >
74
- <RotateCcw size={14} aria-hidden="true" />
75
- <Show when={label()}>{label()}</Show>
76
- </Button>
77
- </div>
78
- </Card>
79
- );
80
- }