@schlessera/brain-ui-react 0.34.1 → 0.36.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 (763) hide show
  1. package/README.md +89 -4
  2. package/dist/components/activity/activity-page.d.ts +17 -5
  3. package/dist/components/activity/activity-page.d.ts.map +1 -1
  4. package/dist/components/activity/activity-page.js +144 -50
  5. package/dist/components/activity/activity-page.js.map +1 -1
  6. package/dist/components/activity/activity-run-detail.d.ts +16 -1
  7. package/dist/components/activity/activity-run-detail.d.ts.map +1 -1
  8. package/dist/components/activity/activity-run-detail.js +47 -4
  9. package/dist/components/activity/activity-run-detail.js.map +1 -1
  10. package/dist/components/activity/activity-run-list.d.ts +7 -1
  11. package/dist/components/activity/activity-run-list.d.ts.map +1 -1
  12. package/dist/components/activity/activity-run-list.js +16 -8
  13. package/dist/components/activity/activity-run-list.js.map +1 -1
  14. package/dist/components/activity/activity-views.d.ts +63 -0
  15. package/dist/components/activity/activity-views.d.ts.map +1 -0
  16. package/dist/components/activity/activity-views.js +52 -0
  17. package/dist/components/activity/activity-views.js.map +1 -0
  18. package/dist/components/activity/approval-card.d.ts +11 -0
  19. package/dist/components/activity/approval-card.d.ts.map +1 -0
  20. package/dist/components/activity/approval-card.js +46 -0
  21. package/dist/components/activity/approval-card.js.map +1 -0
  22. package/dist/components/activity/digest-card.d.ts +3 -0
  23. package/dist/components/activity/digest-card.d.ts.map +1 -1
  24. package/dist/components/activity/digest-card.js +20 -16
  25. package/dist/components/activity/digest-card.js.map +1 -1
  26. package/dist/components/activity/digest-summary.d.ts +19 -0
  27. package/dist/components/activity/digest-summary.d.ts.map +1 -0
  28. package/dist/components/activity/digest-summary.js +20 -0
  29. package/dist/components/activity/digest-summary.js.map +1 -0
  30. package/dist/components/activity/push-switch.d.ts +25 -0
  31. package/dist/components/activity/push-switch.d.ts.map +1 -0
  32. package/dist/components/activity/push-switch.js +14 -0
  33. package/dist/components/activity/push-switch.js.map +1 -0
  34. package/dist/components/activity/push-toggle.d.ts +7 -0
  35. package/dist/components/activity/push-toggle.d.ts.map +1 -1
  36. package/dist/components/activity/push-toggle.js +72 -47
  37. package/dist/components/activity/push-toggle.js.map +1 -1
  38. package/dist/components/activity/span-bits.d.ts.map +1 -1
  39. package/dist/components/activity/span-bits.js +9 -7
  40. package/dist/components/activity/span-bits.js.map +1 -1
  41. package/dist/components/chat/ask-user-card.d.ts +76 -3
  42. package/dist/components/chat/ask-user-card.d.ts.map +1 -1
  43. package/dist/components/chat/ask-user-card.js +208 -149
  44. package/dist/components/chat/ask-user-card.js.map +1 -1
  45. package/dist/components/chat/ask-user-typed.d.ts +42 -0
  46. package/dist/components/chat/ask-user-typed.d.ts.map +1 -0
  47. package/dist/components/chat/ask-user-typed.js +60 -0
  48. package/dist/components/chat/ask-user-typed.js.map +1 -0
  49. package/dist/components/chat/brain-markdown-links.d.ts +2 -1
  50. package/dist/components/chat/brain-markdown-links.d.ts.map +1 -1
  51. package/dist/components/chat/brain-markdown-links.js +3 -4
  52. package/dist/components/chat/brain-markdown-links.js.map +1 -1
  53. package/dist/components/chat/brain-markdown.d.ts.map +1 -1
  54. package/dist/components/chat/brain-markdown.js +4 -2
  55. package/dist/components/chat/brain-markdown.js.map +1 -1
  56. package/dist/components/chat/chat-page.d.ts.map +1 -1
  57. package/dist/components/chat/chat-page.js +24 -9
  58. package/dist/components/chat/chat-page.js.map +1 -1
  59. package/dist/components/chat/composer-view.d.ts +75 -0
  60. package/dist/components/chat/composer-view.d.ts.map +1 -0
  61. package/dist/components/chat/composer-view.js +31 -0
  62. package/dist/components/chat/composer-view.js.map +1 -0
  63. package/dist/components/chat/composer.d.ts +4 -0
  64. package/dist/components/chat/composer.d.ts.map +1 -1
  65. package/dist/components/chat/composer.js +76 -59
  66. package/dist/components/chat/composer.js.map +1 -1
  67. package/dist/components/chat/markdown-content.d.ts +16 -1
  68. package/dist/components/chat/markdown-content.d.ts.map +1 -1
  69. package/dist/components/chat/markdown-content.js +47 -3
  70. package/dist/components/chat/markdown-content.js.map +1 -1
  71. package/dist/components/chat/mermaid-block.d.ts +4 -0
  72. package/dist/components/chat/mermaid-block.d.ts.map +1 -1
  73. package/dist/components/chat/mermaid-block.js +13 -5
  74. package/dist/components/chat/mermaid-block.js.map +1 -1
  75. package/dist/components/chat/mermaid-share.d.ts +2 -1
  76. package/dist/components/chat/mermaid-share.d.ts.map +1 -1
  77. package/dist/components/chat/mermaid-share.js +7 -8
  78. package/dist/components/chat/mermaid-share.js.map +1 -1
  79. package/dist/components/chat/mermaid-viewer.d.ts.map +1 -1
  80. package/dist/components/chat/mermaid-viewer.js +3 -1
  81. package/dist/components/chat/mermaid-viewer.js.map +1 -1
  82. package/dist/components/chat/message-bubble.d.ts +8 -1
  83. package/dist/components/chat/message-bubble.d.ts.map +1 -1
  84. package/dist/components/chat/message-bubble.js +53 -24
  85. package/dist/components/chat/message-bubble.js.map +1 -1
  86. package/dist/components/chat/message-share.d.ts +2 -1
  87. package/dist/components/chat/message-share.d.ts.map +1 -1
  88. package/dist/components/chat/message-share.js +6 -7
  89. package/dist/components/chat/message-share.js.map +1 -1
  90. package/dist/components/chat/renderers/bind.d.ts +39 -0
  91. package/dist/components/chat/renderers/bind.d.ts.map +1 -0
  92. package/dist/components/chat/renderers/bind.js +43 -0
  93. package/dist/components/chat/renderers/bind.js.map +1 -0
  94. package/dist/components/chat/renderers/brain-ui-tools.d.ts +3 -0
  95. package/dist/components/chat/renderers/brain-ui-tools.d.ts.map +1 -0
  96. package/dist/components/chat/renderers/brain-ui-tools.js +41 -0
  97. package/dist/components/chat/renderers/brain-ui-tools.js.map +1 -0
  98. package/dist/components/chat/renderers/claude-tools.d.ts.map +1 -1
  99. package/dist/components/chat/renderers/claude-tools.js +3 -2
  100. package/dist/components/chat/renderers/claude-tools.js.map +1 -1
  101. package/dist/components/chat/renderers/index.d.ts +10 -2
  102. package/dist/components/chat/renderers/index.d.ts.map +1 -1
  103. package/dist/components/chat/renderers/index.js +15 -10
  104. package/dist/components/chat/renderers/index.js.map +1 -1
  105. package/dist/components/chat/session-drawer.d.ts +4 -0
  106. package/dist/components/chat/session-drawer.d.ts.map +1 -1
  107. package/dist/components/chat/session-drawer.js +55 -40
  108. package/dist/components/chat/session-drawer.js.map +1 -1
  109. package/dist/components/chat/session-list.d.ts +41 -0
  110. package/dist/components/chat/session-list.d.ts.map +1 -0
  111. package/dist/components/chat/session-list.js +10 -0
  112. package/dist/components/chat/session-list.js.map +1 -0
  113. package/dist/components/chat/share-block.d.ts.map +1 -1
  114. package/dist/components/chat/share-block.js +12 -11
  115. package/dist/components/chat/share-block.js.map +1 -1
  116. package/dist/components/chat/share-card.js +2 -2
  117. package/dist/components/chat/share-card.js.map +1 -1
  118. package/dist/components/chat/subagent-view.js +1 -1
  119. package/dist/components/chat/subagent-view.js.map +1 -1
  120. package/dist/components/chat/tool-call-timeline.d.ts.map +1 -1
  121. package/dist/components/chat/tool-call-timeline.js +37 -12
  122. package/dist/components/chat/tool-call-timeline.js.map +1 -1
  123. package/dist/components/chat/tool-cards/block-card.d.ts +28 -0
  124. package/dist/components/chat/tool-cards/block-card.d.ts.map +1 -0
  125. package/dist/components/chat/tool-cards/block-card.js +103 -0
  126. package/dist/components/chat/tool-cards/block-card.js.map +1 -0
  127. package/dist/components/chat/tool-cards/image-mask-card.d.ts +70 -0
  128. package/dist/components/chat/tool-cards/image-mask-card.d.ts.map +1 -0
  129. package/dist/components/chat/tool-cards/image-mask-card.js +142 -0
  130. package/dist/components/chat/tool-cards/image-mask-card.js.map +1 -0
  131. package/dist/components/chat/tool-cards/location-card.d.ts +45 -0
  132. package/dist/components/chat/tool-cards/location-card.d.ts.map +1 -0
  133. package/dist/components/chat/tool-cards/location-card.js +128 -0
  134. package/dist/components/chat/tool-cards/location-card.js.map +1 -0
  135. package/dist/components/chat/tool-views.d.ts +15 -4
  136. package/dist/components/chat/tool-views.d.ts.map +1 -1
  137. package/dist/components/chat/tool-views.js +22 -38
  138. package/dist/components/chat/tool-views.js.map +1 -1
  139. package/dist/components/chat/transcript-turn.d.ts +45 -0
  140. package/dist/components/chat/transcript-turn.d.ts.map +1 -0
  141. package/dist/components/chat/transcript-turn.js +25 -0
  142. package/dist/components/chat/transcript-turn.js.map +1 -0
  143. package/dist/components/chat/use-chat-commands.d.ts.map +1 -1
  144. package/dist/components/chat/use-chat-commands.js +13 -16
  145. package/dist/components/chat/use-chat-commands.js.map +1 -1
  146. package/dist/components/chat/welcome-state.d.ts +7 -0
  147. package/dist/components/chat/welcome-state.d.ts.map +1 -1
  148. package/dist/components/chat/welcome-state.js +13 -5
  149. package/dist/components/chat/welcome-state.js.map +1 -1
  150. package/dist/components/connectivity/connection-gate.d.ts.map +1 -1
  151. package/dist/components/connectivity/connection-gate.js +64 -6
  152. package/dist/components/connectivity/connection-gate.js.map +1 -1
  153. package/dist/components/connectivity/login-form.d.ts +31 -0
  154. package/dist/components/connectivity/login-form.d.ts.map +1 -0
  155. package/dist/components/connectivity/login-form.js +19 -0
  156. package/dist/components/connectivity/login-form.js.map +1 -0
  157. package/dist/components/connectivity/login-screen.d.ts +5 -2
  158. package/dist/components/connectivity/login-screen.d.ts.map +1 -1
  159. package/dist/components/connectivity/login-screen.js +41 -31
  160. package/dist/components/connectivity/login-screen.js.map +1 -1
  161. package/dist/components/dev/share-harness.js +1 -1
  162. package/dist/components/dev/share-harness.js.map +1 -1
  163. package/dist/components/files/file-panel.d.ts +1 -1
  164. package/dist/components/files/file-panel.d.ts.map +1 -1
  165. package/dist/components/files/file-panel.js +74 -0
  166. package/dist/components/files/file-panel.js.map +1 -1
  167. package/dist/components/files/file-tree-view.d.ts +45 -0
  168. package/dist/components/files/file-tree-view.d.ts.map +1 -0
  169. package/dist/components/files/file-tree-view.js +51 -0
  170. package/dist/components/files/file-tree-view.js.map +1 -0
  171. package/dist/components/files/file-tree.d.ts +6 -0
  172. package/dist/components/files/file-tree.d.ts.map +1 -1
  173. package/dist/components/files/file-tree.js +39 -43
  174. package/dist/components/files/file-tree.js.map +1 -1
  175. package/dist/components/files/file-viewer-binary.d.ts.map +1 -1
  176. package/dist/components/files/file-viewer-binary.js +3 -2
  177. package/dist/components/files/file-viewer-binary.js.map +1 -1
  178. package/dist/components/files/file-viewer-frame.d.ts +36 -0
  179. package/dist/components/files/file-viewer-frame.d.ts.map +1 -0
  180. package/dist/components/files/file-viewer-frame.js +26 -0
  181. package/dist/components/files/file-viewer-frame.js.map +1 -0
  182. package/dist/components/files/file-viewer.d.ts +5 -0
  183. package/dist/components/files/file-viewer.d.ts.map +1 -1
  184. package/dist/components/files/file-viewer.js +26 -32
  185. package/dist/components/files/file-viewer.js.map +1 -1
  186. package/dist/components/files/frontmatter-chips.d.ts +18 -0
  187. package/dist/components/files/frontmatter-chips.d.ts.map +1 -0
  188. package/dist/components/files/frontmatter-chips.js +11 -0
  189. package/dist/components/files/frontmatter-chips.js.map +1 -0
  190. package/dist/components/files/frontmatter-panel.d.ts +5 -1
  191. package/dist/components/files/frontmatter-panel.d.ts.map +1 -1
  192. package/dist/components/files/frontmatter-panel.js +7 -6
  193. package/dist/components/files/frontmatter-panel.js.map +1 -1
  194. package/dist/components/files/staleness.d.ts +18 -0
  195. package/dist/components/files/staleness.d.ts.map +1 -0
  196. package/dist/components/files/staleness.js +27 -0
  197. package/dist/components/files/staleness.js.map +1 -0
  198. package/dist/components/graph/graph-canvas.d.ts.map +1 -1
  199. package/dist/components/graph/graph-canvas.js +24 -1
  200. package/dist/components/graph/graph-canvas.js.map +1 -1
  201. package/dist/components/graph/graph-controls-column.d.ts +14 -0
  202. package/dist/components/graph/graph-controls-column.d.ts.map +1 -0
  203. package/dist/components/graph/graph-controls-column.js +44 -0
  204. package/dist/components/graph/graph-controls-column.js.map +1 -0
  205. package/dist/components/graph/graph-controls.d.ts +20 -5
  206. package/dist/components/graph/graph-controls.d.ts.map +1 -1
  207. package/dist/components/graph/graph-controls.js +58 -37
  208. package/dist/components/graph/graph-controls.js.map +1 -1
  209. package/dist/components/graph/graph-form.d.ts +82 -0
  210. package/dist/components/graph/graph-form.d.ts.map +1 -0
  211. package/dist/components/graph/graph-form.js +69 -0
  212. package/dist/components/graph/graph-form.js.map +1 -0
  213. package/dist/components/graph/graph-maintenance.d.ts.map +1 -1
  214. package/dist/components/graph/graph-maintenance.js +6 -10
  215. package/dist/components/graph/graph-maintenance.js.map +1 -1
  216. package/dist/components/graph/graph-node-rail.d.ts +13 -0
  217. package/dist/components/graph/graph-node-rail.d.ts.map +1 -0
  218. package/dist/components/graph/graph-node-rail.js +92 -0
  219. package/dist/components/graph/graph-node-rail.js.map +1 -0
  220. package/dist/components/graph/graph-page.d.ts +7 -0
  221. package/dist/components/graph/graph-page.d.ts.map +1 -1
  222. package/dist/components/graph/graph-page.js +102 -12
  223. package/dist/components/graph/graph-page.js.map +1 -1
  224. package/dist/components/graph/graph-scene.d.ts.map +1 -1
  225. package/dist/components/graph/graph-scene.js +100 -24
  226. package/dist/components/graph/graph-scene.js.map +1 -1
  227. package/dist/components/graph/lib/graph-helpers.d.ts +42 -12
  228. package/dist/components/graph/lib/graph-helpers.d.ts.map +1 -1
  229. package/dist/components/graph/lib/graph-helpers.js +33 -41
  230. package/dist/components/graph/lib/graph-helpers.js.map +1 -1
  231. package/dist/components/graph/node-card.d.ts +28 -0
  232. package/dist/components/graph/node-card.d.ts.map +1 -0
  233. package/dist/components/graph/node-card.js +7 -0
  234. package/dist/components/graph/node-card.js.map +1 -0
  235. package/dist/components/graph/node-popover.d.ts +6 -2
  236. package/dist/components/graph/node-popover.d.ts.map +1 -1
  237. package/dist/components/graph/node-popover.js +13 -31
  238. package/dist/components/graph/node-popover.js.map +1 -1
  239. package/dist/components/graph/use-graph-theme.d.ts +32 -4
  240. package/dist/components/graph/use-graph-theme.d.ts.map +1 -1
  241. package/dist/components/graph/use-graph-theme.js +44 -32
  242. package/dist/components/graph/use-graph-theme.js.map +1 -1
  243. package/dist/components/graph/use-node-actions.d.ts +26 -0
  244. package/dist/components/graph/use-node-actions.d.ts.map +1 -0
  245. package/dist/components/graph/use-node-actions.js +54 -0
  246. package/dist/components/graph/use-node-actions.js.map +1 -0
  247. package/dist/components/images/image-share.d.ts +2 -1
  248. package/dist/components/images/image-share.d.ts.map +1 -1
  249. package/dist/components/images/image-share.js +3 -3
  250. package/dist/components/images/image-share.js.map +1 -1
  251. package/dist/components/images/image-viewer.d.ts.map +1 -1
  252. package/dist/components/images/image-viewer.js +3 -1
  253. package/dist/components/images/image-viewer.js.map +1 -1
  254. package/dist/components/images/mask-editor.d.ts.map +1 -1
  255. package/dist/components/images/mask-editor.js +7 -5
  256. package/dist/components/images/mask-editor.js.map +1 -1
  257. package/dist/components/layout/app-shell.d.ts.map +1 -1
  258. package/dist/components/layout/app-shell.js +5 -1
  259. package/dist/components/layout/app-shell.js.map +1 -1
  260. package/dist/components/layout/desktop-palette.d.ts +23 -0
  261. package/dist/components/layout/desktop-palette.d.ts.map +1 -0
  262. package/dist/components/layout/desktop-palette.js +132 -0
  263. package/dist/components/layout/desktop-palette.js.map +1 -0
  264. package/dist/components/layout/key-cap.d.ts +9 -0
  265. package/dist/components/layout/key-cap.d.ts.map +1 -0
  266. package/dist/components/layout/key-cap.js +10 -0
  267. package/dist/components/layout/key-cap.js.map +1 -0
  268. package/dist/components/layout/mobile-tab-bar.d.ts +13 -0
  269. package/dist/components/layout/mobile-tab-bar.d.ts.map +1 -1
  270. package/dist/components/layout/mobile-tab-bar.js +58 -47
  271. package/dist/components/layout/mobile-tab-bar.js.map +1 -1
  272. package/dist/components/layout/shortcut-switch.d.ts +13 -0
  273. package/dist/components/layout/shortcut-switch.d.ts.map +1 -0
  274. package/dist/components/layout/shortcut-switch.js +22 -0
  275. package/dist/components/layout/shortcut-switch.js.map +1 -0
  276. package/dist/components/layout/side-rail.d.ts +24 -0
  277. package/dist/components/layout/side-rail.d.ts.map +1 -1
  278. package/dist/components/layout/side-rail.js +65 -27
  279. package/dist/components/layout/side-rail.js.map +1 -1
  280. package/dist/components/layout/slide-panel.d.ts +12 -2
  281. package/dist/components/layout/slide-panel.d.ts.map +1 -1
  282. package/dist/components/layout/slide-panel.js +11 -2
  283. package/dist/components/layout/slide-panel.js.map +1 -1
  284. package/dist/components/layout/theme.d.ts +22 -0
  285. package/dist/components/layout/theme.d.ts.map +1 -0
  286. package/dist/components/layout/theme.js +44 -0
  287. package/dist/components/layout/theme.js.map +1 -0
  288. package/dist/components/quick-actions/add-form.d.ts +44 -0
  289. package/dist/components/quick-actions/add-form.d.ts.map +1 -0
  290. package/dist/components/quick-actions/add-form.js +30 -0
  291. package/dist/components/quick-actions/add-form.js.map +1 -0
  292. package/dist/components/quick-actions/add-modal.d.ts +7 -0
  293. package/dist/components/quick-actions/add-modal.d.ts.map +1 -1
  294. package/dist/components/quick-actions/add-modal.js +66 -20
  295. package/dist/components/quick-actions/add-modal.js.map +1 -1
  296. package/dist/components/quick-actions/search-modal.d.ts.map +1 -1
  297. package/dist/components/quick-actions/search-modal.js +48 -19
  298. package/dist/components/quick-actions/search-modal.js.map +1 -1
  299. package/dist/components/quick-actions/streaming-modal.d.ts +6 -0
  300. package/dist/components/quick-actions/streaming-modal.d.ts.map +1 -1
  301. package/dist/components/quick-actions/streaming-modal.js +42 -17
  302. package/dist/components/quick-actions/streaming-modal.js.map +1 -1
  303. package/dist/components/quick-actions/streaming-output.d.ts +38 -0
  304. package/dist/components/quick-actions/streaming-output.d.ts.map +1 -0
  305. package/dist/components/quick-actions/streaming-output.js +22 -0
  306. package/dist/components/quick-actions/streaming-output.js.map +1 -0
  307. package/dist/components/quick-actions/whatsup-modal.d.ts +5 -0
  308. package/dist/components/quick-actions/whatsup-modal.d.ts.map +1 -1
  309. package/dist/components/quick-actions/whatsup-modal.js +36 -10
  310. package/dist/components/quick-actions/whatsup-modal.js.map +1 -1
  311. package/dist/components/settings/devices-agents-tab.d.ts +10 -0
  312. package/dist/components/settings/devices-agents-tab.d.ts.map +1 -0
  313. package/dist/components/settings/devices-agents-tab.js +131 -0
  314. package/dist/components/settings/devices-agents-tab.js.map +1 -0
  315. package/dist/components/settings/models-list.d.ts +39 -0
  316. package/dist/components/settings/models-list.d.ts.map +1 -0
  317. package/dist/components/settings/models-list.js +72 -0
  318. package/dist/components/settings/models-list.js.map +1 -0
  319. package/dist/components/settings/models-tab.d.ts +4 -0
  320. package/dist/components/settings/models-tab.d.ts.map +1 -1
  321. package/dist/components/settings/models-tab.js +52 -102
  322. package/dist/components/settings/models-tab.js.map +1 -1
  323. package/dist/components/settings/one-time-agent-credential.d.ts +3 -0
  324. package/dist/components/settings/one-time-agent-credential.d.ts.map +1 -0
  325. package/dist/components/settings/one-time-agent-credential.js +55 -0
  326. package/dist/components/settings/one-time-agent-credential.js.map +1 -0
  327. package/dist/components/settings/passkey-list.d.ts +35 -0
  328. package/dist/components/settings/passkey-list.d.ts.map +1 -0
  329. package/dist/components/settings/passkey-list.js +34 -0
  330. package/dist/components/settings/passkey-list.js.map +1 -0
  331. package/dist/components/settings/passkey-tab.d.ts +3 -0
  332. package/dist/components/settings/passkey-tab.d.ts.map +1 -1
  333. package/dist/components/settings/passkey-tab.js +53 -45
  334. package/dist/components/settings/passkey-tab.js.map +1 -1
  335. package/dist/components/settings/pi-accounts-list.d.ts +27 -0
  336. package/dist/components/settings/pi-accounts-list.d.ts.map +1 -0
  337. package/dist/components/settings/pi-accounts-list.js +15 -0
  338. package/dist/components/settings/pi-accounts-list.js.map +1 -0
  339. package/dist/components/settings/pi-accounts.d.ts +3 -0
  340. package/dist/components/settings/pi-accounts.d.ts.map +1 -1
  341. package/dist/components/settings/pi-accounts.js +73 -55
  342. package/dist/components/settings/pi-accounts.js.map +1 -1
  343. package/dist/components/settings/principal-list.d.ts +37 -0
  344. package/dist/components/settings/principal-list.d.ts.map +1 -0
  345. package/dist/components/settings/principal-list.js +18 -0
  346. package/dist/components/settings/principal-list.js.map +1 -0
  347. package/dist/components/settings/settings-panel.d.ts +10 -3
  348. package/dist/components/settings/settings-panel.d.ts.map +1 -1
  349. package/dist/components/settings/settings-panel.js +80 -6
  350. package/dist/components/settings/settings-panel.js.map +1 -1
  351. package/dist/components/settings/skills-list.d.ts +53 -0
  352. package/dist/components/settings/skills-list.d.ts.map +1 -0
  353. package/dist/components/settings/skills-list.js +28 -0
  354. package/dist/components/settings/skills-list.js.map +1 -0
  355. package/dist/components/settings/skills-tab.d.ts.map +1 -1
  356. package/dist/components/settings/skills-tab.js +65 -38
  357. package/dist/components/settings/skills-tab.js.map +1 -1
  358. package/dist/components/settings/tool-permissions-list.d.ts +18 -0
  359. package/dist/components/settings/tool-permissions-list.d.ts.map +1 -0
  360. package/dist/components/settings/tool-permissions-list.js +6 -0
  361. package/dist/components/settings/tool-permissions-list.js.map +1 -0
  362. package/dist/components/settings/tool-permissions.d.ts +2 -1
  363. package/dist/components/settings/tool-permissions.d.ts.map +1 -1
  364. package/dist/components/settings/tool-permissions.js +33 -16
  365. package/dist/components/settings/tool-permissions.js.map +1 -1
  366. package/dist/components/settings/web-search-chain.d.ts +41 -0
  367. package/dist/components/settings/web-search-chain.d.ts.map +1 -0
  368. package/dist/components/settings/web-search-chain.js +47 -0
  369. package/dist/components/settings/web-search-chain.js.map +1 -0
  370. package/dist/components/settings/web-search-settings.d.ts +4 -7
  371. package/dist/components/settings/web-search-settings.d.ts.map +1 -1
  372. package/dist/components/settings/web-search-settings.js +54 -76
  373. package/dist/components/settings/web-search-settings.js.map +1 -1
  374. package/dist/components/share/share-menu.d.ts.map +1 -1
  375. package/dist/components/share/share-menu.js +24 -4
  376. package/dist/components/share/share-menu.js.map +1 -1
  377. package/dist/components/voice/dictation-sheet.js +3 -3
  378. package/dist/components/voice/dictation-sheet.js.map +1 -1
  379. package/dist/components/voice/mic-button.js +1 -1
  380. package/dist/components/voice/mic-button.js.map +1 -1
  381. package/dist/components/voice/review-card.js +1 -1
  382. package/dist/components/voice/review-card.js.map +1 -1
  383. package/dist/config.d.ts +5 -2
  384. package/dist/config.d.ts.map +1 -1
  385. package/dist/config.js +15 -5
  386. package/dist/config.js.map +1 -1
  387. package/dist/connection.d.ts +12 -0
  388. package/dist/connection.d.ts.map +1 -0
  389. package/dist/connection.js +421 -0
  390. package/dist/connection.js.map +1 -0
  391. package/dist/default-root.d.ts +3 -0
  392. package/dist/default-root.d.ts.map +1 -0
  393. package/dist/default-root.js +16 -0
  394. package/dist/default-root.js.map +1 -0
  395. package/dist/hooks/use-color-scheme.d.ts +14 -0
  396. package/dist/hooks/use-color-scheme.d.ts.map +1 -0
  397. package/dist/hooks/use-color-scheme.js +37 -0
  398. package/dist/hooks/use-color-scheme.js.map +1 -0
  399. package/dist/hooks/use-hash-routes.d.ts.map +1 -1
  400. package/dist/hooks/use-hash-routes.js +4 -2
  401. package/dist/hooks/use-hash-routes.js.map +1 -1
  402. package/dist/hooks/use-media-query.d.ts +7 -0
  403. package/dist/hooks/use-media-query.d.ts.map +1 -0
  404. package/dist/hooks/use-media-query.js +34 -0
  405. package/dist/hooks/use-media-query.js.map +1 -0
  406. package/dist/hooks/use-share-intake.d.ts.map +1 -1
  407. package/dist/hooks/use-share-intake.js +37 -12
  408. package/dist/hooks/use-share-intake.js.map +1 -1
  409. package/dist/hooks/use-vpn-status.d.ts +1 -1
  410. package/dist/hooks/use-vpn-status.d.ts.map +1 -1
  411. package/dist/hooks/use-vpn-status.js +20 -16
  412. package/dist/hooks/use-vpn-status.js.map +1 -1
  413. package/dist/hooks/use-websocket.d.ts +5 -24
  414. package/dist/hooks/use-websocket.d.ts.map +1 -1
  415. package/dist/hooks/use-websocket.js +11 -382
  416. package/dist/hooks/use-websocket.js.map +1 -1
  417. package/dist/hooks/websocket-handlers/activity.d.ts +2 -2
  418. package/dist/hooks/websocket-handlers/activity.d.ts.map +1 -1
  419. package/dist/hooks/websocket-handlers/activity.js +4 -5
  420. package/dist/hooks/websocket-handlers/activity.js.map +1 -1
  421. package/dist/hooks/websocket-handlers/chat.d.ts +1 -0
  422. package/dist/hooks/websocket-handlers/chat.d.ts.map +1 -1
  423. package/dist/hooks/websocket-handlers/chat.js +27 -5
  424. package/dist/hooks/websocket-handlers/chat.js.map +1 -1
  425. package/dist/hooks/websocket-handlers/connection.d.ts.map +1 -1
  426. package/dist/hooks/websocket-handlers/connection.js +4 -6
  427. package/dist/hooks/websocket-handlers/connection.js.map +1 -1
  428. package/dist/hooks/websocket-handlers/mask.d.ts +1 -1
  429. package/dist/hooks/websocket-handlers/mask.d.ts.map +1 -1
  430. package/dist/hooks/websocket-handlers/mask.js +2 -3
  431. package/dist/hooks/websocket-handlers/mask.js.map +1 -1
  432. package/dist/hooks/websocket-handlers/provider.d.ts.map +1 -1
  433. package/dist/hooks/websocket-handlers/provider.js +4 -6
  434. package/dist/hooks/websocket-handlers/provider.js.map +1 -1
  435. package/dist/hooks/websocket-handlers/types.d.ts +6 -2
  436. package/dist/hooks/websocket-handlers/types.d.ts.map +1 -1
  437. package/dist/index.d.ts +5 -3
  438. package/dist/index.d.ts.map +1 -1
  439. package/dist/index.js +6 -3
  440. package/dist/index.js.map +1 -1
  441. package/dist/lib/api-client.d.ts +321 -0
  442. package/dist/lib/api-client.d.ts.map +1 -1
  443. package/dist/lib/api-client.js +243 -213
  444. package/dist/lib/api-client.js.map +1 -1
  445. package/dist/lib/backend.d.ts +19 -2
  446. package/dist/lib/backend.d.ts.map +1 -1
  447. package/dist/lib/backend.js +15 -9
  448. package/dist/lib/backend.js.map +1 -1
  449. package/dist/lib/diff.d.ts +8 -10
  450. package/dist/lib/diff.d.ts.map +1 -1
  451. package/dist/lib/diff.js +26 -53
  452. package/dist/lib/diff.js.map +1 -1
  453. package/dist/lib/format-time.d.ts +3 -0
  454. package/dist/lib/format-time.d.ts.map +1 -0
  455. package/dist/lib/format-time.js +25 -0
  456. package/dist/lib/format-time.js.map +1 -0
  457. package/dist/lib/light-dark.d.ts +37 -0
  458. package/dist/lib/light-dark.d.ts.map +1 -0
  459. package/dist/lib/light-dark.js +83 -0
  460. package/dist/lib/light-dark.js.map +1 -0
  461. package/dist/lib/mermaid-theme.d.ts +7 -2
  462. package/dist/lib/mermaid-theme.d.ts.map +1 -1
  463. package/dist/lib/mermaid-theme.js +125 -203
  464. package/dist/lib/mermaid-theme.js.map +1 -1
  465. package/dist/lib/passkeys.d.ts +6 -3
  466. package/dist/lib/passkeys.d.ts.map +1 -1
  467. package/dist/lib/passkeys.js +10 -4
  468. package/dist/lib/passkeys.js.map +1 -1
  469. package/dist/lib/push-registration.d.ts +10 -0
  470. package/dist/lib/push-registration.d.ts.map +1 -0
  471. package/dist/lib/push-registration.js +44 -0
  472. package/dist/lib/push-registration.js.map +1 -0
  473. package/dist/lib/share-intake.d.ts +2 -1
  474. package/dist/lib/share-intake.d.ts.map +1 -1
  475. package/dist/lib/share-intake.js +3 -3
  476. package/dist/lib/share-intake.js.map +1 -1
  477. package/dist/lib/share.d.ts +4 -3
  478. package/dist/lib/share.d.ts.map +1 -1
  479. package/dist/lib/share.js +6 -7
  480. package/dist/lib/share.js.map +1 -1
  481. package/dist/lib/single-key.d.ts +30 -0
  482. package/dist/lib/single-key.d.ts.map +1 -0
  483. package/dist/lib/single-key.js +45 -0
  484. package/dist/lib/single-key.js.map +1 -0
  485. package/dist/lib/tool-names.d.ts +8 -6
  486. package/dist/lib/tool-names.d.ts.map +1 -1
  487. package/dist/lib/tool-names.js +17 -7
  488. package/dist/lib/tool-names.js.map +1 -1
  489. package/dist/root-context.d.ts +229 -0
  490. package/dist/root-context.d.ts.map +1 -0
  491. package/dist/root-context.js +33 -0
  492. package/dist/root-context.js.map +1 -0
  493. package/dist/root.d.ts +38 -0
  494. package/dist/root.d.ts.map +1 -0
  495. package/dist/root.js +47 -0
  496. package/dist/root.js.map +1 -0
  497. package/dist/stores/activity-state.d.ts +29 -0
  498. package/dist/stores/activity-state.d.ts.map +1 -0
  499. package/dist/stores/activity-state.js +282 -0
  500. package/dist/stores/activity-state.js.map +1 -0
  501. package/dist/stores/activity-store.d.ts +10 -41
  502. package/dist/stores/activity-store.d.ts.map +1 -1
  503. package/dist/stores/activity-store.js +9 -271
  504. package/dist/stores/activity-store.js.map +1 -1
  505. package/dist/stores/chat-state.d.ts +212 -0
  506. package/dist/stores/chat-state.d.ts.map +1 -0
  507. package/dist/stores/chat-state.js +466 -0
  508. package/dist/stores/chat-state.js.map +1 -0
  509. package/dist/stores/chat-store.d.ts +4 -162
  510. package/dist/stores/chat-store.d.ts.map +1 -1
  511. package/dist/stores/chat-store.js +7 -418
  512. package/dist/stores/chat-store.js.map +1 -1
  513. package/dist/stores/connection-state.d.ts +40 -0
  514. package/dist/stores/connection-state.d.ts.map +1 -0
  515. package/dist/stores/connection-state.js +30 -0
  516. package/dist/stores/connection-state.js.map +1 -0
  517. package/dist/stores/connection-store.d.ts +4 -40
  518. package/dist/stores/connection-store.d.ts.map +1 -1
  519. package/dist/stores/connection-store.js +7 -27
  520. package/dist/stores/connection-store.js.map +1 -1
  521. package/dist/stores/create-stores.d.ts +23 -0
  522. package/dist/stores/create-stores.d.ts.map +1 -0
  523. package/dist/stores/create-stores.js +28 -0
  524. package/dist/stores/create-stores.js.map +1 -0
  525. package/dist/stores/file-state.d.ts +53 -0
  526. package/dist/stores/file-state.d.ts.map +1 -0
  527. package/dist/stores/file-state.js +341 -0
  528. package/dist/stores/file-state.js.map +1 -0
  529. package/dist/stores/file-store.d.ts +4 -52
  530. package/dist/stores/file-store.d.ts.map +1 -1
  531. package/dist/stores/file-store.js +7 -300
  532. package/dist/stores/file-store.js.map +1 -1
  533. package/dist/stores/graph-state.d.ts +95 -0
  534. package/dist/stores/graph-state.d.ts.map +1 -0
  535. package/dist/stores/graph-state.js +252 -0
  536. package/dist/stores/graph-state.js.map +1 -0
  537. package/dist/stores/graph-store.d.ts +7 -83
  538. package/dist/stores/graph-store.d.ts.map +1 -1
  539. package/dist/stores/graph-store.js +8 -249
  540. package/dist/stores/graph-store.js.map +1 -1
  541. package/dist/stores/mask-state.d.ts +21 -0
  542. package/dist/stores/mask-state.d.ts.map +1 -0
  543. package/dist/stores/mask-state.js +9 -0
  544. package/dist/stores/mask-state.js.map +1 -0
  545. package/dist/stores/mask-store.d.ts +4 -21
  546. package/dist/stores/mask-store.d.ts.map +1 -1
  547. package/dist/stores/mask-store.js +7 -6
  548. package/dist/stores/mask-store.js.map +1 -1
  549. package/dist/stores/principal-state.d.ts +16 -0
  550. package/dist/stores/principal-state.d.ts.map +1 -0
  551. package/dist/stores/principal-state.js +31 -0
  552. package/dist/stores/principal-state.js.map +1 -0
  553. package/dist/stores/principal-store.d.ts +5 -0
  554. package/dist/stores/principal-store.d.ts.map +1 -0
  555. package/dist/stores/principal-store.js +8 -0
  556. package/dist/stores/principal-store.js.map +1 -0
  557. package/dist/stores/provider-state.d.ts +24 -0
  558. package/dist/stores/provider-state.d.ts.map +1 -0
  559. package/dist/stores/provider-state.js +68 -0
  560. package/dist/stores/provider-state.js.map +1 -0
  561. package/dist/stores/provider-store.d.ts +4 -23
  562. package/dist/stores/provider-store.d.ts.map +1 -1
  563. package/dist/stores/provider-store.js +7 -64
  564. package/dist/stores/provider-store.js.map +1 -1
  565. package/dist/stores/share-state.d.ts +29 -0
  566. package/dist/stores/share-state.d.ts.map +1 -0
  567. package/dist/stores/share-state.js +21 -0
  568. package/dist/stores/share-state.js.map +1 -0
  569. package/dist/stores/share-store.d.ts +4 -28
  570. package/dist/stores/share-store.d.ts.map +1 -1
  571. package/dist/stores/share-store.js +7 -18
  572. package/dist/stores/share-store.js.map +1 -1
  573. package/dist/stores/store-environment.d.ts +10 -0
  574. package/dist/stores/store-environment.d.ts.map +1 -0
  575. package/dist/stores/store-environment.js +2 -0
  576. package/dist/stores/store-environment.js.map +1 -0
  577. package/dist/stores/ui-state.d.ts +71 -0
  578. package/dist/stores/ui-state.d.ts.map +1 -0
  579. package/dist/stores/ui-state.js +58 -0
  580. package/dist/stores/ui-state.js.map +1 -0
  581. package/dist/stores/ui-store.d.ts +4 -45
  582. package/dist/stores/ui-store.d.ts.map +1 -1
  583. package/dist/stores/ui-store.js +7 -36
  584. package/dist/stores/ui-store.js.map +1 -1
  585. package/dist/styles.css +1 -1
  586. package/dist/theme.css +150 -97
  587. package/dist/voice/asr-clients.d.ts +2 -1
  588. package/dist/voice/asr-clients.d.ts.map +1 -1
  589. package/dist/voice/asr-clients.js +16 -17
  590. package/dist/voice/asr-clients.js.map +1 -1
  591. package/dist/voice/use-dictation.d.ts.map +1 -1
  592. package/dist/voice/use-dictation.js +12 -8
  593. package/dist/voice/use-dictation.js.map +1 -1
  594. package/dist/voice/voice-state.d.ts +25 -0
  595. package/dist/voice/voice-state.d.ts.map +1 -0
  596. package/dist/voice/voice-state.js +29 -0
  597. package/dist/voice/voice-state.js.map +1 -0
  598. package/dist/voice/voice-store.d.ts +4 -25
  599. package/dist/voice/voice-store.d.ts.map +1 -1
  600. package/dist/voice/voice-store.js +7 -26
  601. package/dist/voice/voice-store.js.map +1 -1
  602. package/package.json +3 -2
  603. package/src/components/activity/activity-page.tsx +334 -160
  604. package/src/components/activity/activity-run-detail.tsx +81 -47
  605. package/src/components/activity/activity-run-list.tsx +27 -59
  606. package/src/components/activity/activity-views.tsx +155 -0
  607. package/src/components/activity/approval-card.tsx +80 -0
  608. package/src/components/activity/digest-card.tsx +25 -61
  609. package/src/components/activity/digest-summary.tsx +52 -0
  610. package/src/components/activity/push-switch.tsx +62 -0
  611. package/src/components/activity/push-toggle.tsx +51 -81
  612. package/src/components/activity/span-bits.tsx +8 -7
  613. package/src/components/chat/ask-user-card.tsx +292 -356
  614. package/src/components/chat/ask-user-typed.ts +77 -0
  615. package/src/components/chat/brain-markdown-links.tsx +4 -4
  616. package/src/components/chat/brain-markdown.tsx +4 -2
  617. package/src/components/chat/chat-page.tsx +38 -9
  618. package/src/components/chat/composer-view.tsx +194 -0
  619. package/src/components/chat/composer.tsx +117 -296
  620. package/src/components/chat/markdown-content.tsx +53 -2
  621. package/src/components/chat/mermaid-block.tsx +13 -5
  622. package/src/components/chat/mermaid-share.ts +8 -7
  623. package/src/components/chat/mermaid-viewer.tsx +3 -1
  624. package/src/components/chat/message-bubble.tsx +78 -94
  625. package/src/components/chat/message-share.ts +7 -7
  626. package/src/components/chat/renderers/bind.tsx +94 -0
  627. package/src/components/chat/renderers/brain-ui-tools.tsx +56 -0
  628. package/src/components/chat/renderers/claude-tools.tsx +3 -2
  629. package/src/components/chat/renderers/index.ts +15 -10
  630. package/src/components/chat/session-drawer.tsx +60 -138
  631. package/src/components/chat/session-list.tsx +113 -0
  632. package/src/components/chat/share-block.tsx +16 -12
  633. package/src/components/chat/share-card.tsx +2 -2
  634. package/src/components/chat/subagent-view.tsx +4 -4
  635. package/src/components/chat/tool-call-timeline.tsx +59 -22
  636. package/src/components/chat/tool-cards/block-card.tsx +145 -0
  637. package/src/components/chat/tool-cards/image-mask-card.tsx +214 -0
  638. package/src/components/chat/tool-cards/location-card.tsx +159 -0
  639. package/src/components/chat/tool-views.tsx +23 -73
  640. package/src/components/chat/transcript-turn.tsx +108 -0
  641. package/src/components/chat/use-chat-commands.ts +14 -16
  642. package/src/components/chat/welcome-state.tsx +36 -91
  643. package/src/components/connectivity/connection-gate.tsx +80 -9
  644. package/src/components/connectivity/login-form.tsx +122 -0
  645. package/src/components/connectivity/login-screen.tsx +45 -100
  646. package/src/components/dev/share-harness.tsx +2 -2
  647. package/src/components/files/file-panel.tsx +168 -0
  648. package/src/components/files/file-tree-view.tsx +127 -0
  649. package/src/components/files/file-tree.tsx +55 -109
  650. package/src/components/files/file-viewer-binary.tsx +3 -2
  651. package/src/components/files/file-viewer-frame.tsx +113 -0
  652. package/src/components/files/file-viewer.tsx +40 -95
  653. package/src/components/files/frontmatter-chips.tsx +42 -0
  654. package/src/components/files/frontmatter-panel.tsx +6 -71
  655. package/src/components/files/staleness.ts +29 -0
  656. package/src/components/graph/graph-canvas.tsx +24 -1
  657. package/src/components/graph/graph-controls-column.tsx +92 -0
  658. package/src/components/graph/graph-controls.tsx +83 -127
  659. package/src/components/graph/graph-form.tsx +183 -0
  660. package/src/components/graph/graph-maintenance.tsx +9 -14
  661. package/src/components/graph/graph-node-rail.tsx +147 -0
  662. package/src/components/graph/graph-page.tsx +189 -49
  663. package/src/components/graph/graph-scene.tsx +200 -30
  664. package/src/components/graph/lib/graph-helpers.ts +65 -43
  665. package/src/components/graph/node-card.tsx +64 -0
  666. package/src/components/graph/node-popover.tsx +28 -117
  667. package/src/components/graph/use-graph-theme.ts +69 -32
  668. package/src/components/graph/use-node-actions.ts +56 -0
  669. package/src/components/images/image-share.ts +4 -2
  670. package/src/components/images/image-viewer.tsx +3 -1
  671. package/src/components/images/mask-editor.tsx +7 -4
  672. package/src/components/layout/app-shell.tsx +7 -1
  673. package/src/components/layout/desktop-palette.tsx +151 -0
  674. package/src/components/layout/key-cap.tsx +15 -0
  675. package/src/components/layout/mobile-tab-bar.tsx +80 -157
  676. package/src/components/layout/shortcut-switch.tsx +32 -0
  677. package/src/components/layout/side-rail.tsx +70 -150
  678. package/src/components/layout/slide-panel.tsx +29 -2
  679. package/src/components/layout/theme.tsx +67 -0
  680. package/src/components/quick-actions/add-form.tsx +188 -0
  681. package/src/components/quick-actions/add-modal.tsx +68 -144
  682. package/src/components/quick-actions/search-modal.tsx +49 -19
  683. package/src/components/quick-actions/streaming-modal.tsx +44 -71
  684. package/src/components/quick-actions/streaming-output.tsx +112 -0
  685. package/src/components/quick-actions/whatsup-modal.tsx +38 -60
  686. package/src/components/settings/devices-agents-tab.tsx +139 -0
  687. package/src/components/settings/models-list.tsx +299 -0
  688. package/src/components/settings/models-tab.tsx +63 -337
  689. package/src/components/settings/one-time-agent-credential.tsx +131 -0
  690. package/src/components/settings/passkey-list.tsx +201 -0
  691. package/src/components/settings/passkey-tab.tsx +53 -197
  692. package/src/components/settings/pi-accounts-list.tsx +128 -0
  693. package/src/components/settings/pi-accounts.tsx +71 -170
  694. package/src/components/settings/principal-list.tsx +172 -0
  695. package/src/components/settings/settings-panel.tsx +245 -19
  696. package/src/components/settings/skills-list.tsx +276 -0
  697. package/src/components/settings/skills-tab.tsx +82 -269
  698. package/src/components/settings/tool-permissions-list.tsx +54 -0
  699. package/src/components/settings/tool-permissions.tsx +27 -46
  700. package/src/components/settings/web-search-chain.tsx +300 -0
  701. package/src/components/settings/web-search-settings.tsx +58 -328
  702. package/src/components/share/share-menu.tsx +19 -4
  703. package/src/components/voice/dictation-sheet.tsx +5 -5
  704. package/src/components/voice/mic-button.tsx +1 -1
  705. package/src/components/voice/review-card.tsx +1 -1
  706. package/src/config.ts +21 -7
  707. package/src/connection.ts +443 -0
  708. package/src/default-root.ts +16 -0
  709. package/src/hooks/use-color-scheme.ts +36 -0
  710. package/src/hooks/use-hash-routes.ts +4 -2
  711. package/src/hooks/use-media-query.ts +32 -0
  712. package/src/hooks/use-share-intake.ts +32 -12
  713. package/src/hooks/use-vpn-status.ts +23 -15
  714. package/src/hooks/use-websocket.ts +12 -426
  715. package/src/hooks/websocket-handlers/activity.ts +4 -5
  716. package/src/hooks/websocket-handlers/chat.ts +26 -5
  717. package/src/hooks/websocket-handlers/connection.ts +4 -6
  718. package/src/hooks/websocket-handlers/mask.ts +2 -3
  719. package/src/hooks/websocket-handlers/provider.ts +4 -6
  720. package/src/hooks/websocket-handlers/types.ts +6 -2
  721. package/src/index.ts +7 -3
  722. package/src/lib/api-client.ts +446 -365
  723. package/src/lib/backend.ts +20 -10
  724. package/src/lib/diff.ts +28 -62
  725. package/src/lib/format-time.ts +20 -0
  726. package/src/lib/light-dark.ts +83 -0
  727. package/src/lib/mermaid-theme.ts +183 -214
  728. package/src/lib/passkeys.ts +12 -4
  729. package/src/lib/push-registration.ts +46 -0
  730. package/src/lib/share-intake.ts +6 -3
  731. package/src/lib/share.ts +7 -4
  732. package/src/lib/single-key.ts +47 -0
  733. package/src/lib/tool-names.ts +31 -8
  734. package/src/root-context.tsx +40 -0
  735. package/src/root.ts +83 -0
  736. package/src/stores/activity-state.ts +295 -0
  737. package/src/stores/activity-store.ts +11 -285
  738. package/src/stores/chat-state.ts +795 -0
  739. package/src/stores/chat-store.ts +11 -705
  740. package/src/stores/connection-state.ts +78 -0
  741. package/src/stores/connection-store.ts +11 -76
  742. package/src/stores/create-stores.ts +31 -0
  743. package/src/stores/file-state.ts +399 -0
  744. package/src/stores/file-store.ts +9 -360
  745. package/src/stores/graph-state.ts +368 -0
  746. package/src/stores/graph-store.ts +10 -355
  747. package/src/stores/mask-state.ts +30 -0
  748. package/src/stores/mask-store.ts +10 -27
  749. package/src/stores/principal-state.ts +42 -0
  750. package/src/stores/principal-store.ts +11 -0
  751. package/src/stores/provider-state.ts +103 -0
  752. package/src/stores/provider-store.ts +10 -95
  753. package/src/stores/share-state.ts +56 -0
  754. package/src/stores/share-store.ts +11 -54
  755. package/src/stores/store-environment.ts +10 -0
  756. package/src/stores/ui-state.ts +143 -0
  757. package/src/stores/ui-store.ts +11 -93
  758. package/src/styles.css +4 -1
  759. package/src/theme.css +150 -97
  760. package/src/voice/asr-clients.ts +17 -17
  761. package/src/voice/use-dictation.ts +11 -8
  762. package/src/voice/voice-state.ts +57 -0
  763. package/src/voice/voice-store.ts +11 -55
@@ -0,0 +1,159 @@
1
+ /**
2
+ * The `get_current_location` result, drawn on the kit's `MapView` (S9: the
3
+ * first in-chat component rendered end to end from its contract; D37 moved
4
+ * the span rule, the uncertainty ring, the note and the width cap into the
5
+ * kit, so the card is now the fetch and the caption).
6
+ *
7
+ * Typed `LocationPayload` — the contract's payload type — so the fields it
8
+ * reads are the fields the handler is contracted to send. The pin, the
9
+ * span and the caption are pure functions of that payload. What is not pure
10
+ * is the shoreline: `MapView` fetches nothing (kit D13), so this card is the
11
+ * container that asks the server's `/geo/coastline` for the geometry around
12
+ * the fix and hands it down as `paths` and `land`. The request is cancelled
13
+ * on unmount, and any failure — no server, an older server without the
14
+ * route, an Overpass outage — leaves a map with a correct pin, a graticule
15
+ * and a true scale bar, which is a good locator on its own.
16
+ *
17
+ * The bounding box asked for is the envelope of every box `MapView` can draw
18
+ * for the pin — 1.5 spans across, 1.0 down, the same rule the kit's fixture
19
+ * generator uses (`viewBox` says why those numbers). The server clips to the
20
+ * box it is given and quantises its cache key to ~110 m, so the request has
21
+ * to cover the drawn frame itself; and because the envelope is a function of
22
+ * the pin and the span alone, the same fix at any card width is one cache
23
+ * entry rather than a fresh request to a shared service.
24
+ */
25
+
26
+ import { MapView, type MapLand, type MapPath } from "@schlessera/brain-ui-kit";
27
+ import type { LocationPayload } from "@schlessera/brain-ui-sdk/client";
28
+ import { useEffect, useState } from "react";
29
+ import { useBrainApi } from "../../../root-context.js";
30
+ import type { CoastlineGeometry } from "../../../lib/api-client.js";
31
+
32
+ /** 4 decimal places is ~11 m — finer than any browser fix is honest about. */
33
+ function coord(value: number): string {
34
+ return value.toFixed(4);
35
+ }
36
+
37
+ function accuracy(meters: number): string {
38
+ return meters >= 1000
39
+ ? `±${(meters / 1000).toFixed(meters >= 10_000 ? 0 : 1)} km`
40
+ : `±${Math.round(meters)} m`;
41
+ }
42
+
43
+ /** `MapView`'s own default projection width. */
44
+ const WIDTH = 330;
45
+
46
+ /**
47
+ * How far past the span to fetch, per axis, as a multiple of `spanKm`. The
48
+ * kit's ruling (README, sixth pass, §10) bounds a card at 420px wide with a
49
+ * viewport of 110-260px, and `MapView` draws a single pin as 1.24 spans across
50
+ * (12% margins each side) at any width and 1.24 × H/W spans down: 0.32 for
51
+ * 420×110, 0.77 for 420×260, and this card leaves the height at its 170
52
+ * default, so 1.0 down covers it at any width from 211px up. The square
53
+ * 2.4-span bleed this replaced fetched geometry of which only 23% could ever
54
+ * be drawn (measured on the kit's Messina fixture).
55
+ */
56
+ const BLEED_ACROSS = 1.5;
57
+ const BLEED_DOWN = 1.0;
58
+
59
+ /**
60
+ * The view's span across its width, in kilometres — the kit's own rule
61
+ * (`max(1.6 km, 6 × accuracy)`, D37), repeated here only so the coastline
62
+ * request covers the box the kit will draw. The kit computes it again from
63
+ * `accuracyM`; the two must agree, and `tests/location-card.test.ts` pins
64
+ * this one.
65
+ */
66
+ export function spanFor(accuracyMeters: number): number {
67
+ return Math.max(1.6, (accuracyMeters * 6) / 1000);
68
+ }
69
+
70
+ /**
71
+ * The box to fetch for one pin, as `[west, south, east, north]`: the span at
72
+ * the pin's latitude, grown to the envelope above and centred on the pin.
73
+ * Clamped to the server's 5° limit and to the poles.
74
+ */
75
+ export function viewBox(lat: number, lon: number, spanKm: number): [number, number, number, number] {
76
+ const cos = Math.max(0.2, Math.cos((lat * Math.PI) / 180));
77
+ const degLon = Math.min(4.5, (spanKm / 111 / cos) * BLEED_ACROSS);
78
+ const degLat = Math.min(4.5, (spanKm / 111) * BLEED_DOWN);
79
+ const west = Math.max(-180, lon - degLon / 2);
80
+ const east = Math.min(180, lon + degLon / 2);
81
+ const south = Math.max(-89, lat - degLat / 2);
82
+ const north = Math.min(89, lat + degLat / 2);
83
+ return [west, south, east, north];
84
+ }
85
+
86
+ /** The server's tiers as `MapView` paths, at the kit fixtures' weights. */
87
+ export function geometryPaths(geo: CoastlineGeometry): MapPath[] {
88
+ return [
89
+ ...geo.coastline.map((coords) => ({ coords, tone: "neutral" as const, width: 1 })),
90
+ ...geo.roads.map((coords) => ({ coords, tone: "neutral" as const, width: 0.6 })),
91
+ ...geo.streets.map((coords) => ({ coords, tone: "neutral" as const, width: 0.35 })),
92
+ ];
93
+ }
94
+
95
+ export function LocationResultCard({
96
+ latitude,
97
+ longitude,
98
+ accuracyMeters,
99
+ place,
100
+ address,
101
+ note,
102
+ retrievedAt,
103
+ }: LocationPayload) {
104
+ const api = useBrainApi();
105
+ const spanKm = spanFor(accuracyMeters);
106
+ const [geo, setGeo] = useState<CoastlineGeometry | null>(null);
107
+
108
+ useEffect(() => {
109
+ const controller = new AbortController();
110
+ setGeo(null);
111
+ // The box is BLEED_ACROSS times the drawn span, so the width sent with it
112
+ // is BLEED_ACROSS times the drawn width: the server takes its tolerance
113
+ // and its detail tier from the box's width over that many pixels, and the
114
+ // bare 330 would ask for a view half again coarser than the one drawn —
115
+ // a 2 km span asking for streets and getting roads. The server buckets
116
+ // 495 up to 660, which errs on the fine side, never towards an empty map.
117
+ api
118
+ .geoCoastline(viewBox(latitude, longitude, spanKm), {
119
+ width: WIDTH * BLEED_ACROSS,
120
+ signal: controller.signal,
121
+ })
122
+ .then((result) => {
123
+ if (!controller.signal.aborted) setGeo(result);
124
+ })
125
+ .catch(() => {
126
+ // A plainer map, on purpose. The pin is the answer; the shore is
127
+ // context, and context that cannot be had is not an error to show.
128
+ });
129
+ return () => controller.abort();
130
+ }, [api, latitude, longitude, spanKm]);
131
+
132
+ const when = new Date(retrievedAt);
133
+ const stamp = Number.isNaN(when.getTime())
134
+ ? retrievedAt
135
+ : when.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
136
+ const paths = geo ? geometryPaths(geo) : [];
137
+ const land: MapLand | undefined = geo && geo.land.length ? { rings: geo.land } : undefined;
138
+ const drawn = paths.length > 0 || land !== undefined;
139
+
140
+ return (
141
+ // The kit owns the span rule, the uncertainty ring, the note and the
142
+ // 420px cap (D37); the card passes the payload through.
143
+ <MapView
144
+ pins={[{ lat: latitude, lon: longitude, label: place ?? "Here", meta: accuracy(accuracyMeters), tone: "amber" }]}
145
+ accuracyM={accuracyMeters}
146
+ paths={paths}
147
+ land={land}
148
+ // The place name is the answer; coordinates are the evidence for it,
149
+ // so they stay visible but quiet rather than leading.
150
+ title={place ?? "Coordinates only"}
151
+ subtitle={address && address !== place ? address : undefined}
152
+ meta={`${coord(latitude)}, ${coord(longitude)} · ${accuracy(accuracyMeters)} · ${stamp}`}
153
+ note={note}
154
+ // The credit is the licence's, not the design's: it appears exactly
155
+ // when OpenStreetMap geometry is on the map.
156
+ attribution={drawn ? geo?.attribution : undefined}
157
+ />
158
+ );
159
+ }
@@ -15,16 +15,19 @@ import {
15
15
  MapPin,
16
16
  ChevronRight,
17
17
  } from "lucide-react";
18
+ import { DiffBlock } from "@schlessera/brain-ui-kit";
18
19
  import type { ToolCall } from "../../stores/chat-store.js";
19
20
  import { cn } from "../../lib/utils.js";
20
21
  import { linkifyPaths, FileLink } from "./brain-markdown.js";
21
22
  import { MarkdownContent } from "./markdown-content.js";
22
23
  import { isInternalRepoPath } from "../../stores/file-store.js";
23
24
  import { GET_LOCATION_TOOL_NAME, normalizeToolName } from "../../lib/tool-names.js";
24
- import { computeDiffRows, type WordToken } from "../../lib/diff.js";
25
+ import { computeDiffRows, diffText } from "../../lib/diff.js";
26
+ import { formatRelativeTime } from "../../lib/format-time.js";
25
27
 
26
28
  // Re-exported so existing imports of the diff engine from this module keep working.
27
- export { computeDiffRows };
29
+ export { computeDiffRows, diffText };
30
+ export { formatRelativeTime };
28
31
 
29
32
  // ============================================================
30
33
  // Shared helpers
@@ -84,19 +87,6 @@ export function formatTokenCount(n: number): string {
84
87
  return String(n);
85
88
  }
86
89
 
87
- /** Relative timestamp for list rows ("3m ago"); dates beyond a week. */
88
- export function formatRelativeTime(ms: number): string {
89
- const diff = Date.now() - ms;
90
- const minutes = Math.floor(diff / 60000);
91
- if (minutes < 1) return "just now";
92
- if (minutes < 60) return `${minutes}m ago`;
93
- const hours = Math.floor(minutes / 60);
94
- if (hours < 24) return `${hours}h ago`;
95
- const days = Math.floor(hours / 24);
96
- if (days < 7) return `${days}d ago`;
97
- return new Date(ms).toLocaleDateString();
98
- }
99
-
100
90
  export function countLines(text: string): number {
101
91
  let n = 1;
102
92
  for (let i = 0; i < text.length; i++) if (text[i] === "\n") n++;
@@ -243,7 +233,7 @@ export function ToolInputView({ tool }: { tool: ToolCall }) {
243
233
  return (
244
234
  <div className="flex items-center gap-2 rounded-md bg-background/60 p-2 text-[11px] text-muted-foreground/60">
245
235
  <span
246
- className="inline-block h-1.5 w-1.5 rounded-full bg-primary"
236
+ className="inline-block h-1.5 w-1.5 rounded-full bg-primary-mark"
247
237
  style={{ animation: "breathe 1.5s ease-in-out infinite" }}
248
238
  />
249
239
  Preparing input…
@@ -283,7 +273,7 @@ function PathHeader({ path, badge }: { path: string | null; badge?: string | nul
283
273
  {path ? fileLabel(path) : "unknown file"}
284
274
  </span>
285
275
  {badge && (
286
- <span className="ml-auto shrink-0 rounded bg-primary/15 px-1.5 py-0.5 text-[10px] text-primary">
276
+ <span className="ml-auto shrink-0 rounded bg-primary-fill/15 px-1.5 py-0.5 text-[10px] text-primary">
287
277
  {badge}
288
278
  </span>
289
279
  )}
@@ -291,28 +281,17 @@ function PathHeader({ path, badge }: { path: string | null; badge?: string | nul
291
281
  );
292
282
  }
293
283
 
294
- /** Render a diff line, emphasizing changed word tokens when refined. */
295
- function DiffLine({ tokens, line, changedClass }: {
296
- tokens: WordToken[] | null;
297
- line: string;
298
- changedClass: string;
299
- }) {
300
- if (!tokens) return <>{line}</>;
301
- return (
302
- <>
303
- {tokens.map((t, i) =>
304
- t.changed ? (
305
- <span key={i} className={cn("rounded-sm", changedClass)}>
306
- {t.text}
307
- </span>
308
- ) : (
309
- <span key={i}>{t.text}</span>
310
- )
311
- )}
312
- </>
313
- );
314
- }
315
-
284
+ /**
285
+ * The Edit tool's diff, on the kit `DiffBlock` in its `tinted` mode: this is
286
+ * the one diff where the lines ARE the decision — an edit the user may still
287
+ * be asked to approve — so removed rows take the red ground and added rows the
288
+ * teal one, with the sign column at full tone weight. Long lines wrap with the
289
+ * kit's hanging indent; nothing scrolls sideways and nothing truncates.
290
+ *
291
+ * The app used to add a word-level highlight inside a single changed line
292
+ * pair. The design's diff has no such thing — the sign and the ground are the
293
+ * whole vocabulary — so it was dropped with the seventh drop.
294
+ */
316
295
  export function EditDiffView({ tool }: { tool: ToolCall }) {
317
296
  const rows = computeDiffRows(str(tool.input.old_string) ?? "", str(tool.input.new_string) ?? "");
318
297
  return (
@@ -321,37 +300,8 @@ export function EditDiffView({ tool }: { tool: ToolCall }) {
321
300
  path={str(tool.input.file_path)}
322
301
  badge={tool.input.replace_all ? "replace all" : null}
323
302
  />
324
- <div className="max-h-64 overflow-y-auto bg-background/60 py-1 font-[family-name:var(--font-mono)] text-[11px] leading-relaxed">
325
- {rows.map((row, i) => {
326
- if (row.kind === "same") {
327
- return (
328
- <div key={`s${i}`} className="flex">
329
- <span className="w-5 shrink-0 select-none text-center text-muted-foreground/30"> </span>
330
- <span className="min-w-0 whitespace-pre-wrap break-all pr-2 text-muted-foreground/70">
331
- {row.line}
332
- </span>
333
- </div>
334
- );
335
- }
336
- if (row.kind === "del") {
337
- return (
338
- <div key={`d${i}`} className="flex bg-red-500/10">
339
- <span className="w-5 shrink-0 select-none text-center text-red-400/70">-</span>
340
- <span className="min-w-0 whitespace-pre-wrap break-all pr-2 text-red-200/90">
341
- <DiffLine tokens={row.tokens} line={row.line} changedClass="bg-red-500/30" />
342
- </span>
343
- </div>
344
- );
345
- }
346
- return (
347
- <div key={`i${i}`} className="flex bg-emerald-500/10">
348
- <span className="w-5 shrink-0 select-none text-center text-emerald-400/70">+</span>
349
- <span className="min-w-0 whitespace-pre-wrap break-all pr-2 text-emerald-200/90">
350
- <DiffLine tokens={row.tokens} line={row.line} changedClass="bg-emerald-500/30" />
351
- </span>
352
- </div>
353
- );
354
- })}
303
+ <div className="max-h-64 overflow-y-auto" data-edit-diff>
304
+ <DiffBlock tinted variant="inset" text={diffText(rows)} />
355
305
  </div>
356
306
  </div>
357
307
  );
@@ -402,7 +352,7 @@ export function BashCommandView({ tool }: { tool: ToolCall }) {
402
352
  className={cn(
403
353
  "rounded px-1.5 py-0.5 text-[10px]",
404
354
  f === "sandbox disabled"
405
- ? "bg-destructive/15 text-destructive"
355
+ ? "bg-destructive-fill/15 text-destructive"
406
356
  : "bg-surface-raised text-muted-foreground"
407
357
  )}
408
358
  >
@@ -511,7 +461,7 @@ export function ClampedPre({ text, isError }: { text: string; isError?: boolean
511
461
  className={cn(
512
462
  "overflow-x-auto rounded-md p-2 pr-7 font-[family-name:var(--font-mono)] text-[11px] leading-relaxed",
513
463
  isError
514
- ? "bg-destructive/10 text-destructive"
464
+ ? "bg-destructive-fill/10 text-destructive"
515
465
  : "bg-background/60 text-muted-foreground"
516
466
  )}
517
467
  >
@@ -646,7 +596,7 @@ export function FileRowsView({ output, pattern }: { output: string; pattern?: st
646
596
  {prefix && <span>{linkifyPaths(prefix)}</span>}
647
597
  {splitMatches(content, re).map((seg, i) =>
648
598
  seg.match ? (
649
- <mark key={i} className="rounded-sm bg-amber-400/25 px-0.5 text-amber-100">
599
+ <mark key={i} className="rounded-sm bg-primary-fill/25 px-0.5 text-foreground">
650
600
  {seg.text}
651
601
  </mark>
652
602
  ) : (
@@ -0,0 +1,108 @@
1
+ import { Chip, Disclosure, Icon, MessageBubble, StatusDot } from "@schlessera/brain-ui-kit";
2
+ import type { ReactNode } from "react";
3
+ import { cn } from "../../lib/utils.js";
4
+
5
+ /**
6
+ * The pieces of one transcript turn that are pure presentation (S7, the
7
+ * `chat` directory). `MessageBubble` in `message-bubble.tsx` stays the
8
+ * memoized container that reads the message, groups its parts and routes
9
+ * the tool timelines, ask cards and markdown; these draw the frame around
10
+ * them on the kit.
11
+ *
12
+ * A user turn is the design's tucked bubble (kit `MessageBubble role="user"`,
13
+ * right-aligned, one corner cut); a brain turn has no bubble — "the answer is
14
+ * the page" — and the kit's decorative action row is off, because the app's
15
+ * share menu is real and sits under the last text block. The thinking blurb
16
+ * is a kit `Disclosure` whose summary says what is hidden ("Thought for ~N
17
+ * tokens"), controlled by the container so it can auto-collapse when the
18
+ * stream ends.
19
+ */
20
+ export interface TurnHeaderProps {
21
+ who: string;
22
+ /** Mono time, already formatted. */
23
+ when: string;
24
+ /** The user turn came in by voice: which kind. */
25
+ voice?: "voice-dictate" | "voice-conversation";
26
+ tone: "user" | "brain";
27
+ }
28
+
29
+ export function TurnHeader(p: TurnHeaderProps) {
30
+ return (
31
+ <div className="mb-2 flex items-center gap-3">
32
+ <span
33
+ className={cn(
34
+ "select-none font-[family-name:var(--font-mono)] text-xs font-semibold uppercase tracking-widest",
35
+ p.tone === "user" ? "text-primary/80" : "text-accent/80",
36
+ )}
37
+ >
38
+ {p.who}
39
+ </span>
40
+ <div className="h-px flex-1 bg-border/40" />
41
+ {p.voice && (
42
+ <span
43
+ role="img"
44
+ aria-label={p.voice === "voice-conversation" ? "Voice conversation" : "Voice dictation"}
45
+ className={p.voice === "voice-conversation" ? "flex text-primary/70" : "flex text-primary/50"}
46
+ >
47
+ <Icon icon="mic" size={12} />
48
+ </span>
49
+ )}
50
+ <span className="font-[family-name:var(--font-mono)] text-[10px] text-muted-foreground/40">{p.when}</span>
51
+ </div>
52
+ );
53
+ }
54
+
55
+ /** The user's bubble: attachments above the text, both the container's. */
56
+ export function UserTurn({ children }: { children: ReactNode }) {
57
+ return (
58
+ <MessageBubble role="user" text="">
59
+ <div className="space-y-2 text-left">{children}</div>
60
+ </MessageBubble>
61
+ );
62
+ }
63
+
64
+ /** A resumed message knows only how many images it carried. */
65
+ export function AttachmentCount({ count }: { count: number }) {
66
+ return <Chip label={`${count} image${count === 1 ? "" : "s"}`} icon="image" variant="outline" tone="neutral" mono={false} />;
67
+ }
68
+
69
+ export interface ThinkingBlockProps {
70
+ content: ReactNode;
71
+ /** Roughly how much was thought; the collapsed summary's number. */
72
+ chars: number;
73
+ streaming: boolean;
74
+ open: boolean;
75
+ onOpenChange: (open: boolean) => void;
76
+ }
77
+
78
+ export function ThinkingBlock(p: ThinkingBlockProps) {
79
+ if (p.streaming) {
80
+ return (
81
+ <div className="rounded-lg bg-surface/50 px-4 py-3">
82
+ <div className="font-[family-name:var(--font-mono)] text-xs italic leading-relaxed text-muted-foreground/60 whitespace-pre-wrap">
83
+ {p.content}
84
+ <span className="ml-1 inline-flex align-middle">
85
+ <StatusDot tone="amber" pulse size={6} />
86
+ </span>
87
+ </div>
88
+ </div>
89
+ );
90
+ }
91
+ return (
92
+ <Disclosure label={`Thought for ~${Math.round(p.chars / 4)} tokens`} icon="agent" open={p.open} onOpenChange={p.onOpenChange}>
93
+ <div className="font-[family-name:var(--font-mono)] text-xs italic leading-relaxed text-muted-foreground/60 whitespace-pre-wrap">
94
+ {p.content}
95
+ </div>
96
+ </Disclosure>
97
+ );
98
+ }
99
+
100
+ /** Nothing has arrived yet: the one breathing dot the design allows. */
101
+ export function ThinkingIndicator() {
102
+ return (
103
+ <div className="flex items-center gap-2 text-xs text-muted-foreground" aria-live="polite">
104
+ <StatusDot tone="amber" pulse size={6} />
105
+ Thinking...
106
+ </div>
107
+ );
108
+ }
@@ -1,8 +1,6 @@
1
+ import type { BrainUiRoot } from "../../root.js";
2
+ import { useBrainUiRoot } from "../../root-context.js";
1
3
  import { useCallback } from "react";
2
- import { useChatStore } from "../../stores/chat-store.js";
3
- import { useConnectionStore } from "../../stores/connection-store.js";
4
- import { useUIStore } from "../../stores/ui-store.js";
5
- import { api } from "../../lib/api-client.js";
6
4
 
7
5
  /**
8
6
  * Slash-command dispatch, shared by the composer's palette and the welcome
@@ -15,8 +13,9 @@ import { api } from "../../lib/api-client.js";
15
13
  * identity per character would defeat the memoization around it.
16
14
  */
17
15
  export function useChatCommands(): (command: string) => void {
16
+ const root = useBrainUiRoot();
18
17
  return useCallback((command: string) => {
19
- const ui = useUIStore.getState();
18
+ const ui = root.stores.ui.getState();
20
19
 
21
20
  // Search and add talk to the brain CLI over REST, not to the agent — they
22
21
  // stay available while a turn streams or the socket is down.
@@ -29,11 +28,11 @@ export function useChatCommands(): (command: string) => void {
29
28
  return;
30
29
  }
31
30
 
32
- const chat = useChatStore.getState();
31
+ const chat = root.stores.chat.getState();
33
32
  const sessionId = chat.activeSessionId;
34
33
  const buffer = sessionId ? chat.buffers[sessionId] : chat.draft;
35
34
  const disabled =
36
- useConnectionStore.getState().wsStatus !== "connected" ||
35
+ root.stores.connection.getState().wsStatus !== "connected" ||
37
36
  Boolean(buffer?.isStreaming);
38
37
  if (disabled) return;
39
38
 
@@ -45,19 +44,19 @@ export function useChatCommands(): (command: string) => void {
45
44
  ui.setWhatsupPanelOpen(true);
46
45
  break;
47
46
  case "stats":
48
- void runStats(sessionId);
47
+ void runStats(root, sessionId);
49
48
  break;
50
49
  }
51
- }, []);
50
+ }, [root]);
52
51
  }
53
52
 
54
53
  /** Brain statistics rendered into the transcript as an assistant turn. */
55
- async function runStats(sessionId: string | null): Promise<void> {
56
- const chat = useChatStore.getState();
54
+ async function runStats(root: BrainUiRoot, sessionId: string | null): Promise<void> {
55
+ const chat = root.stores.chat.getState();
57
56
  chat.addUserMessage(sessionId, "Stats");
58
57
  chat.startAssistantMessage(sessionId);
59
58
  try {
60
- const stats = await api.brainStats();
59
+ const stats = await root.api.brainStats();
61
60
  const result = [
62
61
  `**Brain Statistics**`,
63
62
  `- Documents: ${stats.documents}`,
@@ -73,15 +72,14 @@ async function runStats(sessionId: string | null): Promise<void> {
73
72
  .map(([s, n]) => `${s} (${n})`)
74
73
  .join(", ")}`,
75
74
  ].join("\n");
76
- useChatStore.getState().appendText(sessionId, result);
75
+ root.stores.chat.getState().appendText(sessionId, result);
77
76
  } catch (err) {
78
- useChatStore
79
- .getState()
77
+ root.stores.chat.getState()
80
78
  .appendText(
81
79
  sessionId,
82
80
  `**Error:** ${err instanceof Error ? err.message : "Action failed"}`
83
81
  );
84
82
  } finally {
85
- useChatStore.getState().finishAssistantMessage(sessionId);
83
+ root.stores.chat.getState().finishAssistantMessage(sessionId);
86
84
  }
87
85
  }
@@ -1,6 +1,13 @@
1
- import { Brain, Newspaper, Search, BarChart3 } from "lucide-react";
1
+ import { EmptyState, SuggestionChips } from "@schlessera/brain-ui-kit";
2
2
  import { motion } from "framer-motion";
3
3
 
4
+ /**
5
+ * The chat's empty transcript, on the kit (S7): the design's `1h` first-run
6
+ * `EmptyState` — a medallion, a serif title, one sentence — and the three
7
+ * starting points as `SuggestionChips`, "follow-ups phrased as prompts the
8
+ * user could have typed". Already props-only; the chat page routes the
9
+ * action.
10
+ */
4
11
  export function WelcomeState({
5
12
  onAction,
6
13
  }: {
@@ -8,98 +15,36 @@ export function WelcomeState({
8
15
  }) {
9
16
  return (
10
17
  <div className="flex min-h-full items-center justify-center px-4 py-8">
11
- <div className="flex flex-col items-center gap-8 text-center">
12
- {/* Brain icon with breathe animation */}
13
- <motion.div
14
- initial={{ opacity: 0, y: 8 }}
15
- animate={{ opacity: 1, y: 0 }}
16
- transition={{ duration: 0.4, ease: "easeOut" }}
17
- >
18
- <div className="flex h-16 w-16 items-center justify-center rounded-2xl bg-surface">
19
- <Brain className="h-8 w-8 text-primary" style={{ animation: "breathe 3s ease-in-out infinite" }} />
20
- </div>
21
- </motion.div>
22
-
23
- {/* Headline */}
24
- <motion.h1
25
- className="font-[family-name:var(--font-display)] text-3xl text-foreground"
26
- initial={{ opacity: 0, y: 8 }}
27
- animate={{ opacity: 1, y: 0 }}
28
- transition={{ duration: 0.4, delay: 0.1, ease: "easeOut" }}
29
- >
30
- What do you need to know?
31
- </motion.h1>
32
-
33
- {/* Suggestion cards */}
34
- <motion.div
35
- className="flex flex-col sm:flex-row gap-3"
36
- initial={{ opacity: 0, y: 8 }}
37
- animate={{ opacity: 1, y: 0 }}
38
- transition={{ duration: 0.4, delay: 0.2, ease: "easeOut" }}
39
- >
40
- <SuggestionCard
41
- icon={Newspaper}
42
- label="What's new?"
43
- description="Daily briefing"
44
- onClick={() => onAction("whatsup")}
45
- delay={0}
46
- />
47
- <SuggestionCard
48
- icon={Search}
49
- label="Search..."
50
- description="Find anything"
51
- onClick={() => onAction("search")}
52
- delay={0.05}
18
+ <motion.div
19
+ className="flex w-full max-w-md flex-col items-center gap-4"
20
+ initial={{ opacity: 0, y: 8 }}
21
+ animate={{ opacity: 1, y: 0 }}
22
+ transition={{ duration: 0.4, ease: "easeOut" }}
23
+ >
24
+ <EmptyState
25
+ variant="first-run"
26
+ icon="brain"
27
+ tone="amber"
28
+ title="What do you need to know?"
29
+ body="Ask in your own words. The brain reads its files, cites what it used, and asks before it writes."
30
+ meta=""
31
+ titleSize={26}
32
+ pad={8}
33
+ />
34
+ <div className="w-full">
35
+ <SuggestionChips
36
+ label="Start with"
37
+ items={[
38
+ { label: "What's new?", icon: "digest", tone: "amber", onClick: () => onAction("whatsup") },
39
+ { label: "Search…", icon: "search", onClick: () => onAction("search") },
40
+ { label: "Brain stats", icon: "health", tone: "teal", onClick: () => onAction("stats") },
41
+ ]}
53
42
  />
54
- <SuggestionCard
55
- icon={BarChart3}
56
- label="Brain stats"
57
- description="Overview"
58
- onClick={() => onAction("stats")}
59
- delay={0.1}
60
- />
61
- </motion.div>
62
-
63
- {/* Keyboard hints */}
64
- <motion.div
65
- className="text-xs text-muted-foreground/40"
66
- initial={{ opacity: 0 }}
67
- animate={{ opacity: 1 }}
68
- transition={{ duration: 0.4, delay: 0.4 }}
69
- >
43
+ </div>
44
+ <div className="text-xs text-muted-foreground/60">
70
45
  <span className="font-mono">/</span> for commands
71
- </motion.div>
72
- </div>
46
+ </div>
47
+ </motion.div>
73
48
  </div>
74
49
  );
75
50
  }
76
-
77
- function SuggestionCard({
78
- icon: Icon,
79
- label,
80
- description,
81
- onClick,
82
- delay,
83
- }: {
84
- icon: typeof Brain;
85
- label: string;
86
- description: string;
87
- onClick: () => void;
88
- delay: number;
89
- }) {
90
- return (
91
- <motion.button
92
- onClick={onClick}
93
- className="flex w-44 flex-col items-center gap-2 rounded-xl border border-border bg-surface p-4 text-center transition-all duration-200 hover:border-primary/40 hover:bg-surface-raised"
94
- initial={{ opacity: 0, y: 8 }}
95
- animate={{ opacity: 1, y: 0 }}
96
- transition={{ duration: 0.3, delay: 0.25 + delay, ease: "easeOut" }}
97
- >
98
- <Icon className="h-5 w-5 text-primary" />
99
- <div>
100
- <div className="text-sm font-medium text-foreground">{label}</div>
101
- <div className="text-[11px] text-muted-foreground">{description}</div>
102
- </div>
103
- </motion.button>
104
- );
105
- }