@schlessera/brain-ui-react 0.35.0 → 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 (755) hide show
  1. package/README.md +82 -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 +32 -32
  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 +13 -2
  136. package/dist/components/chat/tool-views.d.ts.map +1 -1
  137. package/dist/components/chat/tool-views.js +20 -22
  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 +27 -21
  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 +4 -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 +23 -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 +4 -3
  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 +39 -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 +6 -1
  312. package/dist/components/settings/devices-agents-tab.d.ts.map +1 -1
  313. package/dist/components/settings/devices-agents-tab.js +55 -20
  314. package/dist/components/settings/devices-agents-tab.js.map +1 -1
  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.js +1 -1
  324. package/dist/components/settings/one-time-agent-credential.js.map +1 -1
  325. package/dist/components/settings/passkey-list.d.ts +35 -0
  326. package/dist/components/settings/passkey-list.d.ts.map +1 -0
  327. package/dist/components/settings/passkey-list.js +34 -0
  328. package/dist/components/settings/passkey-list.js.map +1 -0
  329. package/dist/components/settings/passkey-tab.d.ts +3 -0
  330. package/dist/components/settings/passkey-tab.d.ts.map +1 -1
  331. package/dist/components/settings/passkey-tab.js +53 -45
  332. package/dist/components/settings/passkey-tab.js.map +1 -1
  333. package/dist/components/settings/pi-accounts-list.d.ts +27 -0
  334. package/dist/components/settings/pi-accounts-list.d.ts.map +1 -0
  335. package/dist/components/settings/pi-accounts-list.js +15 -0
  336. package/dist/components/settings/pi-accounts-list.js.map +1 -0
  337. package/dist/components/settings/pi-accounts.d.ts +3 -0
  338. package/dist/components/settings/pi-accounts.d.ts.map +1 -1
  339. package/dist/components/settings/pi-accounts.js +73 -55
  340. package/dist/components/settings/pi-accounts.js.map +1 -1
  341. package/dist/components/settings/principal-list.d.ts +37 -0
  342. package/dist/components/settings/principal-list.d.ts.map +1 -0
  343. package/dist/components/settings/principal-list.js +18 -0
  344. package/dist/components/settings/principal-list.js.map +1 -0
  345. package/dist/components/settings/settings-panel.d.ts +10 -3
  346. package/dist/components/settings/settings-panel.d.ts.map +1 -1
  347. package/dist/components/settings/settings-panel.js +69 -8
  348. package/dist/components/settings/settings-panel.js.map +1 -1
  349. package/dist/components/settings/skills-list.d.ts +53 -0
  350. package/dist/components/settings/skills-list.d.ts.map +1 -0
  351. package/dist/components/settings/skills-list.js +28 -0
  352. package/dist/components/settings/skills-list.js.map +1 -0
  353. package/dist/components/settings/skills-tab.d.ts.map +1 -1
  354. package/dist/components/settings/skills-tab.js +65 -38
  355. package/dist/components/settings/skills-tab.js.map +1 -1
  356. package/dist/components/settings/tool-permissions-list.d.ts +18 -0
  357. package/dist/components/settings/tool-permissions-list.d.ts.map +1 -0
  358. package/dist/components/settings/tool-permissions-list.js +6 -0
  359. package/dist/components/settings/tool-permissions-list.js.map +1 -0
  360. package/dist/components/settings/tool-permissions.d.ts +2 -1
  361. package/dist/components/settings/tool-permissions.d.ts.map +1 -1
  362. package/dist/components/settings/tool-permissions.js +33 -16
  363. package/dist/components/settings/tool-permissions.js.map +1 -1
  364. package/dist/components/settings/web-search-chain.d.ts +41 -0
  365. package/dist/components/settings/web-search-chain.d.ts.map +1 -0
  366. package/dist/components/settings/web-search-chain.js +47 -0
  367. package/dist/components/settings/web-search-chain.js.map +1 -0
  368. package/dist/components/settings/web-search-settings.d.ts +4 -7
  369. package/dist/components/settings/web-search-settings.d.ts.map +1 -1
  370. package/dist/components/settings/web-search-settings.js +54 -76
  371. package/dist/components/settings/web-search-settings.js.map +1 -1
  372. package/dist/components/share/share-menu.d.ts.map +1 -1
  373. package/dist/components/share/share-menu.js +24 -4
  374. package/dist/components/share/share-menu.js.map +1 -1
  375. package/dist/components/voice/dictation-sheet.js +3 -3
  376. package/dist/components/voice/dictation-sheet.js.map +1 -1
  377. package/dist/components/voice/mic-button.js +1 -1
  378. package/dist/components/voice/mic-button.js.map +1 -1
  379. package/dist/components/voice/review-card.js +1 -1
  380. package/dist/components/voice/review-card.js.map +1 -1
  381. package/dist/config.d.ts +5 -2
  382. package/dist/config.d.ts.map +1 -1
  383. package/dist/config.js +15 -5
  384. package/dist/config.js.map +1 -1
  385. package/dist/connection.d.ts +12 -0
  386. package/dist/connection.d.ts.map +1 -0
  387. package/dist/connection.js +421 -0
  388. package/dist/connection.js.map +1 -0
  389. package/dist/default-root.d.ts +3 -0
  390. package/dist/default-root.d.ts.map +1 -0
  391. package/dist/default-root.js +16 -0
  392. package/dist/default-root.js.map +1 -0
  393. package/dist/hooks/use-color-scheme.d.ts +14 -0
  394. package/dist/hooks/use-color-scheme.d.ts.map +1 -0
  395. package/dist/hooks/use-color-scheme.js +37 -0
  396. package/dist/hooks/use-color-scheme.js.map +1 -0
  397. package/dist/hooks/use-hash-routes.d.ts.map +1 -1
  398. package/dist/hooks/use-hash-routes.js +4 -2
  399. package/dist/hooks/use-hash-routes.js.map +1 -1
  400. package/dist/hooks/use-media-query.d.ts +7 -0
  401. package/dist/hooks/use-media-query.d.ts.map +1 -0
  402. package/dist/hooks/use-media-query.js +34 -0
  403. package/dist/hooks/use-media-query.js.map +1 -0
  404. package/dist/hooks/use-share-intake.d.ts.map +1 -1
  405. package/dist/hooks/use-share-intake.js +37 -12
  406. package/dist/hooks/use-share-intake.js.map +1 -1
  407. package/dist/hooks/use-vpn-status.d.ts.map +1 -1
  408. package/dist/hooks/use-vpn-status.js +17 -18
  409. package/dist/hooks/use-vpn-status.js.map +1 -1
  410. package/dist/hooks/use-websocket.d.ts +5 -24
  411. package/dist/hooks/use-websocket.d.ts.map +1 -1
  412. package/dist/hooks/use-websocket.js +11 -384
  413. package/dist/hooks/use-websocket.js.map +1 -1
  414. package/dist/hooks/websocket-handlers/activity.d.ts +2 -2
  415. package/dist/hooks/websocket-handlers/activity.d.ts.map +1 -1
  416. package/dist/hooks/websocket-handlers/activity.js +4 -5
  417. package/dist/hooks/websocket-handlers/activity.js.map +1 -1
  418. package/dist/hooks/websocket-handlers/chat.d.ts +1 -0
  419. package/dist/hooks/websocket-handlers/chat.d.ts.map +1 -1
  420. package/dist/hooks/websocket-handlers/chat.js +27 -5
  421. package/dist/hooks/websocket-handlers/chat.js.map +1 -1
  422. package/dist/hooks/websocket-handlers/connection.d.ts.map +1 -1
  423. package/dist/hooks/websocket-handlers/connection.js +4 -6
  424. package/dist/hooks/websocket-handlers/connection.js.map +1 -1
  425. package/dist/hooks/websocket-handlers/mask.d.ts +1 -1
  426. package/dist/hooks/websocket-handlers/mask.d.ts.map +1 -1
  427. package/dist/hooks/websocket-handlers/mask.js +2 -3
  428. package/dist/hooks/websocket-handlers/mask.js.map +1 -1
  429. package/dist/hooks/websocket-handlers/provider.d.ts.map +1 -1
  430. package/dist/hooks/websocket-handlers/provider.js +4 -6
  431. package/dist/hooks/websocket-handlers/provider.js.map +1 -1
  432. package/dist/hooks/websocket-handlers/types.d.ts +6 -2
  433. package/dist/hooks/websocket-handlers/types.d.ts.map +1 -1
  434. package/dist/index.d.ts +5 -3
  435. package/dist/index.d.ts.map +1 -1
  436. package/dist/index.js +6 -3
  437. package/dist/index.js.map +1 -1
  438. package/dist/lib/api-client.d.ts +289 -0
  439. package/dist/lib/api-client.d.ts.map +1 -1
  440. package/dist/lib/api-client.js +243 -224
  441. package/dist/lib/api-client.js.map +1 -1
  442. package/dist/lib/backend.d.ts +19 -2
  443. package/dist/lib/backend.d.ts.map +1 -1
  444. package/dist/lib/backend.js +15 -9
  445. package/dist/lib/backend.js.map +1 -1
  446. package/dist/lib/diff.d.ts +8 -10
  447. package/dist/lib/diff.d.ts.map +1 -1
  448. package/dist/lib/diff.js +26 -53
  449. package/dist/lib/diff.js.map +1 -1
  450. package/dist/lib/light-dark.d.ts +37 -0
  451. package/dist/lib/light-dark.d.ts.map +1 -0
  452. package/dist/lib/light-dark.js +83 -0
  453. package/dist/lib/light-dark.js.map +1 -0
  454. package/dist/lib/mermaid-theme.d.ts +7 -2
  455. package/dist/lib/mermaid-theme.d.ts.map +1 -1
  456. package/dist/lib/mermaid-theme.js +125 -203
  457. package/dist/lib/mermaid-theme.js.map +1 -1
  458. package/dist/lib/passkeys.d.ts +6 -3
  459. package/dist/lib/passkeys.d.ts.map +1 -1
  460. package/dist/lib/passkeys.js +10 -4
  461. package/dist/lib/passkeys.js.map +1 -1
  462. package/dist/lib/push-registration.d.ts +4 -1
  463. package/dist/lib/push-registration.d.ts.map +1 -1
  464. package/dist/lib/push-registration.js +20 -2
  465. package/dist/lib/push-registration.js.map +1 -1
  466. package/dist/lib/share-intake.d.ts +2 -1
  467. package/dist/lib/share-intake.d.ts.map +1 -1
  468. package/dist/lib/share-intake.js +3 -3
  469. package/dist/lib/share-intake.js.map +1 -1
  470. package/dist/lib/share.d.ts +4 -3
  471. package/dist/lib/share.d.ts.map +1 -1
  472. package/dist/lib/share.js +6 -7
  473. package/dist/lib/share.js.map +1 -1
  474. package/dist/lib/single-key.d.ts +30 -0
  475. package/dist/lib/single-key.d.ts.map +1 -0
  476. package/dist/lib/single-key.js +45 -0
  477. package/dist/lib/single-key.js.map +1 -0
  478. package/dist/lib/tool-names.d.ts +8 -6
  479. package/dist/lib/tool-names.d.ts.map +1 -1
  480. package/dist/lib/tool-names.js +17 -7
  481. package/dist/lib/tool-names.js.map +1 -1
  482. package/dist/root-context.d.ts +229 -0
  483. package/dist/root-context.d.ts.map +1 -0
  484. package/dist/root-context.js +33 -0
  485. package/dist/root-context.js.map +1 -0
  486. package/dist/root.d.ts +38 -0
  487. package/dist/root.d.ts.map +1 -0
  488. package/dist/root.js +47 -0
  489. package/dist/root.js.map +1 -0
  490. package/dist/stores/activity-state.d.ts +29 -0
  491. package/dist/stores/activity-state.d.ts.map +1 -0
  492. package/dist/stores/activity-state.js +282 -0
  493. package/dist/stores/activity-state.js.map +1 -0
  494. package/dist/stores/activity-store.d.ts +10 -41
  495. package/dist/stores/activity-store.d.ts.map +1 -1
  496. package/dist/stores/activity-store.js +9 -271
  497. package/dist/stores/activity-store.js.map +1 -1
  498. package/dist/stores/chat-state.d.ts +212 -0
  499. package/dist/stores/chat-state.d.ts.map +1 -0
  500. package/dist/stores/chat-state.js +466 -0
  501. package/dist/stores/chat-state.js.map +1 -0
  502. package/dist/stores/chat-store.d.ts +4 -162
  503. package/dist/stores/chat-store.d.ts.map +1 -1
  504. package/dist/stores/chat-store.js +7 -418
  505. package/dist/stores/chat-store.js.map +1 -1
  506. package/dist/stores/connection-state.d.ts +40 -0
  507. package/dist/stores/connection-state.d.ts.map +1 -0
  508. package/dist/stores/connection-state.js +30 -0
  509. package/dist/stores/connection-state.js.map +1 -0
  510. package/dist/stores/connection-store.d.ts +4 -40
  511. package/dist/stores/connection-store.d.ts.map +1 -1
  512. package/dist/stores/connection-store.js +7 -27
  513. package/dist/stores/connection-store.js.map +1 -1
  514. package/dist/stores/create-stores.d.ts +23 -0
  515. package/dist/stores/create-stores.d.ts.map +1 -0
  516. package/dist/stores/create-stores.js +28 -0
  517. package/dist/stores/create-stores.js.map +1 -0
  518. package/dist/stores/file-state.d.ts +53 -0
  519. package/dist/stores/file-state.d.ts.map +1 -0
  520. package/dist/stores/file-state.js +341 -0
  521. package/dist/stores/file-state.js.map +1 -0
  522. package/dist/stores/file-store.d.ts +4 -52
  523. package/dist/stores/file-store.d.ts.map +1 -1
  524. package/dist/stores/file-store.js +7 -336
  525. package/dist/stores/file-store.js.map +1 -1
  526. package/dist/stores/graph-state.d.ts +95 -0
  527. package/dist/stores/graph-state.d.ts.map +1 -0
  528. package/dist/stores/graph-state.js +252 -0
  529. package/dist/stores/graph-state.js.map +1 -0
  530. package/dist/stores/graph-store.d.ts +7 -83
  531. package/dist/stores/graph-store.d.ts.map +1 -1
  532. package/dist/stores/graph-store.js +8 -249
  533. package/dist/stores/graph-store.js.map +1 -1
  534. package/dist/stores/mask-state.d.ts +21 -0
  535. package/dist/stores/mask-state.d.ts.map +1 -0
  536. package/dist/stores/mask-state.js +9 -0
  537. package/dist/stores/mask-state.js.map +1 -0
  538. package/dist/stores/mask-store.d.ts +4 -21
  539. package/dist/stores/mask-store.d.ts.map +1 -1
  540. package/dist/stores/mask-store.js +7 -6
  541. package/dist/stores/mask-store.js.map +1 -1
  542. package/dist/stores/principal-state.d.ts +16 -0
  543. package/dist/stores/principal-state.d.ts.map +1 -0
  544. package/dist/stores/principal-state.js +31 -0
  545. package/dist/stores/principal-state.js.map +1 -0
  546. package/dist/stores/principal-store.d.ts +4 -15
  547. package/dist/stores/principal-store.d.ts.map +1 -1
  548. package/dist/stores/principal-store.js +7 -28
  549. package/dist/stores/principal-store.js.map +1 -1
  550. package/dist/stores/provider-state.d.ts +24 -0
  551. package/dist/stores/provider-state.d.ts.map +1 -0
  552. package/dist/stores/provider-state.js +68 -0
  553. package/dist/stores/provider-state.js.map +1 -0
  554. package/dist/stores/provider-store.d.ts +4 -23
  555. package/dist/stores/provider-store.d.ts.map +1 -1
  556. package/dist/stores/provider-store.js +7 -64
  557. package/dist/stores/provider-store.js.map +1 -1
  558. package/dist/stores/share-state.d.ts +29 -0
  559. package/dist/stores/share-state.d.ts.map +1 -0
  560. package/dist/stores/share-state.js +21 -0
  561. package/dist/stores/share-state.js.map +1 -0
  562. package/dist/stores/share-store.d.ts +4 -28
  563. package/dist/stores/share-store.d.ts.map +1 -1
  564. package/dist/stores/share-store.js +7 -18
  565. package/dist/stores/share-store.js.map +1 -1
  566. package/dist/stores/store-environment.d.ts +10 -0
  567. package/dist/stores/store-environment.d.ts.map +1 -0
  568. package/dist/stores/store-environment.js +2 -0
  569. package/dist/stores/store-environment.js.map +1 -0
  570. package/dist/stores/ui-state.d.ts +71 -0
  571. package/dist/stores/ui-state.d.ts.map +1 -0
  572. package/dist/stores/ui-state.js +58 -0
  573. package/dist/stores/ui-state.js.map +1 -0
  574. package/dist/stores/ui-store.d.ts +4 -45
  575. package/dist/stores/ui-store.d.ts.map +1 -1
  576. package/dist/stores/ui-store.js +7 -36
  577. package/dist/stores/ui-store.js.map +1 -1
  578. package/dist/styles.css +1 -1
  579. package/dist/theme.css +150 -97
  580. package/dist/voice/asr-clients.d.ts +2 -1
  581. package/dist/voice/asr-clients.d.ts.map +1 -1
  582. package/dist/voice/asr-clients.js +16 -17
  583. package/dist/voice/asr-clients.js.map +1 -1
  584. package/dist/voice/use-dictation.d.ts.map +1 -1
  585. package/dist/voice/use-dictation.js +12 -8
  586. package/dist/voice/use-dictation.js.map +1 -1
  587. package/dist/voice/voice-state.d.ts +25 -0
  588. package/dist/voice/voice-state.d.ts.map +1 -0
  589. package/dist/voice/voice-state.js +29 -0
  590. package/dist/voice/voice-state.js.map +1 -0
  591. package/dist/voice/voice-store.d.ts +4 -25
  592. package/dist/voice/voice-store.d.ts.map +1 -1
  593. package/dist/voice/voice-store.js +7 -26
  594. package/dist/voice/voice-store.js.map +1 -1
  595. package/package.json +3 -2
  596. package/src/components/activity/activity-page.tsx +334 -160
  597. package/src/components/activity/activity-run-detail.tsx +81 -47
  598. package/src/components/activity/activity-run-list.tsx +27 -59
  599. package/src/components/activity/activity-views.tsx +155 -0
  600. package/src/components/activity/approval-card.tsx +80 -0
  601. package/src/components/activity/digest-card.tsx +25 -61
  602. package/src/components/activity/digest-summary.tsx +52 -0
  603. package/src/components/activity/push-switch.tsx +62 -0
  604. package/src/components/activity/push-toggle.tsx +51 -81
  605. package/src/components/activity/span-bits.tsx +8 -7
  606. package/src/components/chat/ask-user-card.tsx +292 -356
  607. package/src/components/chat/ask-user-typed.ts +77 -0
  608. package/src/components/chat/brain-markdown-links.tsx +4 -4
  609. package/src/components/chat/brain-markdown.tsx +4 -2
  610. package/src/components/chat/chat-page.tsx +38 -9
  611. package/src/components/chat/composer-view.tsx +194 -0
  612. package/src/components/chat/composer.tsx +117 -296
  613. package/src/components/chat/markdown-content.tsx +53 -2
  614. package/src/components/chat/mermaid-block.tsx +13 -5
  615. package/src/components/chat/mermaid-share.ts +8 -7
  616. package/src/components/chat/mermaid-viewer.tsx +3 -1
  617. package/src/components/chat/message-bubble.tsx +78 -94
  618. package/src/components/chat/message-share.ts +7 -7
  619. package/src/components/chat/renderers/bind.tsx +94 -0
  620. package/src/components/chat/renderers/brain-ui-tools.tsx +56 -0
  621. package/src/components/chat/renderers/claude-tools.tsx +3 -2
  622. package/src/components/chat/renderers/index.ts +15 -10
  623. package/src/components/chat/session-drawer.tsx +41 -138
  624. package/src/components/chat/session-list.tsx +113 -0
  625. package/src/components/chat/share-block.tsx +16 -12
  626. package/src/components/chat/share-card.tsx +2 -2
  627. package/src/components/chat/subagent-view.tsx +4 -4
  628. package/src/components/chat/tool-call-timeline.tsx +59 -22
  629. package/src/components/chat/tool-cards/block-card.tsx +145 -0
  630. package/src/components/chat/tool-cards/image-mask-card.tsx +214 -0
  631. package/src/components/chat/tool-cards/location-card.tsx +159 -0
  632. package/src/components/chat/tool-views.tsx +21 -60
  633. package/src/components/chat/transcript-turn.tsx +108 -0
  634. package/src/components/chat/use-chat-commands.ts +14 -16
  635. package/src/components/chat/welcome-state.tsx +36 -91
  636. package/src/components/connectivity/connection-gate.tsx +32 -24
  637. package/src/components/connectivity/login-form.tsx +122 -0
  638. package/src/components/connectivity/login-screen.tsx +45 -100
  639. package/src/components/dev/share-harness.tsx +2 -2
  640. package/src/components/files/file-panel.tsx +168 -0
  641. package/src/components/files/file-tree-view.tsx +127 -0
  642. package/src/components/files/file-tree.tsx +55 -109
  643. package/src/components/files/file-viewer-binary.tsx +3 -2
  644. package/src/components/files/file-viewer-frame.tsx +113 -0
  645. package/src/components/files/file-viewer.tsx +40 -95
  646. package/src/components/files/frontmatter-chips.tsx +42 -0
  647. package/src/components/files/frontmatter-panel.tsx +6 -71
  648. package/src/components/files/staleness.ts +29 -0
  649. package/src/components/graph/graph-canvas.tsx +24 -1
  650. package/src/components/graph/graph-controls-column.tsx +92 -0
  651. package/src/components/graph/graph-controls.tsx +83 -127
  652. package/src/components/graph/graph-form.tsx +183 -0
  653. package/src/components/graph/graph-maintenance.tsx +9 -14
  654. package/src/components/graph/graph-node-rail.tsx +147 -0
  655. package/src/components/graph/graph-page.tsx +189 -49
  656. package/src/components/graph/graph-scene.tsx +200 -30
  657. package/src/components/graph/lib/graph-helpers.ts +65 -43
  658. package/src/components/graph/node-card.tsx +64 -0
  659. package/src/components/graph/node-popover.tsx +28 -117
  660. package/src/components/graph/use-graph-theme.ts +69 -32
  661. package/src/components/graph/use-node-actions.ts +56 -0
  662. package/src/components/images/image-share.ts +4 -2
  663. package/src/components/images/image-viewer.tsx +3 -1
  664. package/src/components/images/mask-editor.tsx +7 -4
  665. package/src/components/layout/app-shell.tsx +5 -1
  666. package/src/components/layout/desktop-palette.tsx +151 -0
  667. package/src/components/layout/key-cap.tsx +15 -0
  668. package/src/components/layout/mobile-tab-bar.tsx +80 -157
  669. package/src/components/layout/shortcut-switch.tsx +32 -0
  670. package/src/components/layout/side-rail.tsx +70 -150
  671. package/src/components/layout/slide-panel.tsx +29 -2
  672. package/src/components/layout/theme.tsx +67 -0
  673. package/src/components/quick-actions/add-form.tsx +188 -0
  674. package/src/components/quick-actions/add-modal.tsx +32 -153
  675. package/src/components/quick-actions/search-modal.tsx +5 -3
  676. package/src/components/quick-actions/streaming-modal.tsx +42 -71
  677. package/src/components/quick-actions/streaming-output.tsx +112 -0
  678. package/src/components/quick-actions/whatsup-modal.tsx +38 -60
  679. package/src/components/settings/devices-agents-tab.tsx +60 -152
  680. package/src/components/settings/models-list.tsx +299 -0
  681. package/src/components/settings/models-tab.tsx +63 -337
  682. package/src/components/settings/one-time-agent-credential.tsx +1 -1
  683. package/src/components/settings/passkey-list.tsx +201 -0
  684. package/src/components/settings/passkey-tab.tsx +53 -197
  685. package/src/components/settings/pi-accounts-list.tsx +128 -0
  686. package/src/components/settings/pi-accounts.tsx +71 -170
  687. package/src/components/settings/principal-list.tsx +172 -0
  688. package/src/components/settings/settings-panel.tsx +232 -21
  689. package/src/components/settings/skills-list.tsx +276 -0
  690. package/src/components/settings/skills-tab.tsx +82 -269
  691. package/src/components/settings/tool-permissions-list.tsx +54 -0
  692. package/src/components/settings/tool-permissions.tsx +27 -46
  693. package/src/components/settings/web-search-chain.tsx +300 -0
  694. package/src/components/settings/web-search-settings.tsx +58 -328
  695. package/src/components/share/share-menu.tsx +19 -4
  696. package/src/components/voice/dictation-sheet.tsx +5 -5
  697. package/src/components/voice/mic-button.tsx +1 -1
  698. package/src/components/voice/review-card.tsx +1 -1
  699. package/src/config.ts +21 -7
  700. package/src/connection.ts +443 -0
  701. package/src/default-root.ts +16 -0
  702. package/src/hooks/use-color-scheme.ts +36 -0
  703. package/src/hooks/use-hash-routes.ts +4 -2
  704. package/src/hooks/use-media-query.ts +32 -0
  705. package/src/hooks/use-share-intake.ts +32 -12
  706. package/src/hooks/use-vpn-status.ts +18 -17
  707. package/src/hooks/use-websocket.ts +12 -428
  708. package/src/hooks/websocket-handlers/activity.ts +4 -5
  709. package/src/hooks/websocket-handlers/chat.ts +26 -5
  710. package/src/hooks/websocket-handlers/connection.ts +4 -6
  711. package/src/hooks/websocket-handlers/mask.ts +2 -3
  712. package/src/hooks/websocket-handlers/provider.ts +4 -6
  713. package/src/hooks/websocket-handlers/types.ts +6 -2
  714. package/src/index.ts +7 -3
  715. package/src/lib/api-client.ts +426 -384
  716. package/src/lib/backend.ts +20 -10
  717. package/src/lib/diff.ts +28 -62
  718. package/src/lib/light-dark.ts +83 -0
  719. package/src/lib/mermaid-theme.ts +183 -214
  720. package/src/lib/passkeys.ts +12 -4
  721. package/src/lib/push-registration.ts +19 -2
  722. package/src/lib/share-intake.ts +6 -3
  723. package/src/lib/share.ts +7 -4
  724. package/src/lib/single-key.ts +47 -0
  725. package/src/lib/tool-names.ts +31 -8
  726. package/src/root-context.tsx +40 -0
  727. package/src/root.ts +83 -0
  728. package/src/stores/activity-state.ts +295 -0
  729. package/src/stores/activity-store.ts +11 -285
  730. package/src/stores/chat-state.ts +795 -0
  731. package/src/stores/chat-store.ts +11 -705
  732. package/src/stores/connection-state.ts +78 -0
  733. package/src/stores/connection-store.ts +11 -76
  734. package/src/stores/create-stores.ts +31 -0
  735. package/src/stores/file-state.ts +399 -0
  736. package/src/stores/file-store.ts +9 -390
  737. package/src/stores/graph-state.ts +368 -0
  738. package/src/stores/graph-store.ts +10 -355
  739. package/src/stores/mask-state.ts +30 -0
  740. package/src/stores/mask-store.ts +10 -27
  741. package/src/stores/principal-state.ts +42 -0
  742. package/src/stores/principal-store.ts +10 -37
  743. package/src/stores/provider-state.ts +103 -0
  744. package/src/stores/provider-store.ts +10 -95
  745. package/src/stores/share-state.ts +56 -0
  746. package/src/stores/share-store.ts +11 -54
  747. package/src/stores/store-environment.ts +10 -0
  748. package/src/stores/ui-state.ts +143 -0
  749. package/src/stores/ui-store.ts +11 -93
  750. package/src/styles.css +4 -1
  751. package/src/theme.css +150 -97
  752. package/src/voice/asr-clients.ts +17 -17
  753. package/src/voice/use-dictation.ts +11 -8
  754. package/src/voice/voice-state.ts +57 -0
  755. package/src/voice/voice-store.ts +11 -55
@@ -0,0 +1,188 @@
1
+ import { Button, Callout } from "@schlessera/brain-ui-kit";
2
+ import { CheckCircle2 } from "lucide-react";
3
+ import type { ReactNode, RefObject } from "react";
4
+ import { useId } from "react";
5
+ import { Kbd } from "../layout/kbd.js";
6
+
7
+ /**
8
+ * The "Add to brain" form, rendered from props (S6). `AddPanel` is the
9
+ * container: it owns the draft, the `brain add` / `brain index` requests and
10
+ * the `operation.epoch` guard that keeps a stale save from landing in a
11
+ * fresh form; this owns the two screens — the form, and the receipt after a
12
+ * save — and nothing else.
13
+ *
14
+ * `state` is the container's machine: `editing` and `error` show the form
15
+ * (with the error under it), `saving` is the form with the Add button inert,
16
+ * `saved` is the receipt. On the receipt, `indexed` is three-valued because
17
+ * an older server does not report it: `false` offers a retry, `true` says
18
+ * so, `undefined` says the server did not say.
19
+ *
20
+ * Fields stay native (the kit has no text input); the buttons are the kit's.
21
+ * The content field's ref is the container's, because focus after open and
22
+ * after "Add another" is timed against the panel's slide, which the
23
+ * container owns.
24
+ */
25
+ export type AddState = "editing" | "saving" | "saved" | "error";
26
+
27
+ export interface AddDraft {
28
+ content: string;
29
+ title: string;
30
+ type: string;
31
+ tags: string;
32
+ }
33
+
34
+ export interface AddFormProps {
35
+ state: AddState;
36
+ draft: AddDraft;
37
+ /** Types already in the brain, offered as completions — a hint list, not a closed set. */
38
+ knownTypes: string[];
39
+ error: string;
40
+ savedPath: string;
41
+ indexed: boolean | undefined;
42
+ indexing: boolean;
43
+ contentRef: RefObject<HTMLTextAreaElement | null>;
44
+ onDraft: (patch: Partial<AddDraft>) => void;
45
+ onSave: () => void;
46
+ onRetryIndex: () => void;
47
+ onAddAnother: () => void;
48
+ onClose: () => void;
49
+ }
50
+
51
+ export function AddForm(p: AddFormProps) {
52
+ const typesId = useId();
53
+ const saving = p.state === "saving";
54
+ const canSave = p.draft.content.trim().length > 0 && !saving;
55
+
56
+ function onKeyDown(e: React.KeyboardEvent) {
57
+ // Cmd/Ctrl+Enter saves from anywhere in the form. The container refuses
58
+ // a save that is not from `editing` or `error`, so the receipt is safe.
59
+ if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
60
+ e.preventDefault();
61
+ p.onSave();
62
+ }
63
+ }
64
+
65
+ if (p.state === "saved") {
66
+ return (
67
+ <div className="flex h-full flex-col" onKeyDown={onKeyDown}>
68
+ <div className="flex flex-1 flex-col items-center justify-center gap-4 px-8 text-center">
69
+ <CheckCircle2 className="h-8 w-8 text-primary" />
70
+ <p className="text-sm text-foreground">Added to your brain.</p>
71
+ <p className="text-xs text-muted-foreground">
72
+ {p.indexed === false
73
+ ? "Saved, but not indexed. Your content is safe; search may not find it yet."
74
+ : p.indexed === true
75
+ ? "Saved and indexed. Run a sync when you want to push it."
76
+ : "Saved. This server did not report whether indexing completed."}
77
+ </p>
78
+ {p.savedPath && <p className="break-all text-xs text-muted-foreground">{p.savedPath}</p>}
79
+ {p.indexed === false && (
80
+ <div className="flex flex-col items-center gap-2" role="status">
81
+ {p.error && <p className="text-xs text-destructive">{p.error}</p>}
82
+ <Button
83
+ label={p.indexing ? "Indexing…" : "Retry indexing"}
84
+ icon="retry"
85
+ tone="primary"
86
+ size="sm"
87
+ block={false}
88
+ disabled={p.indexing}
89
+ onClick={p.onRetryIndex}
90
+ />
91
+ </div>
92
+ )}
93
+ <div className="flex gap-2">
94
+ <Button label="Add another" icon="add" tone="ghost" size="sm" block={false} onClick={p.onAddAnother} />
95
+ <Button label="Done" icon="confirm" tone="primary" size="sm" block={false} onClick={p.onClose} />
96
+ </div>
97
+ </div>
98
+ </div>
99
+ );
100
+ }
101
+
102
+ return (
103
+ <div className="flex h-full flex-col" onKeyDown={onKeyDown}>
104
+ <div className="flex-1 space-y-4 overflow-y-auto p-5">
105
+ <Field label="Note">
106
+ <textarea
107
+ ref={p.contentRef}
108
+ value={p.draft.content}
109
+ onChange={(e) => p.onDraft({ content: e.target.value })}
110
+ rows={8}
111
+ placeholder="What do you want to remember?"
112
+ className="w-full resize-y rounded-lg border border-border bg-surface-raised px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary/40"
113
+ />
114
+ </Field>
115
+
116
+ <Field label="Title" hint="optional, derived from the note if empty">
117
+ <input
118
+ value={p.draft.title}
119
+ onChange={(e) => p.onDraft({ title: e.target.value })}
120
+ className="w-full rounded-lg border border-border bg-surface-raised px-3 py-2 text-sm text-foreground outline-none transition-colors focus:border-primary/40"
121
+ />
122
+ </Field>
123
+
124
+ <div className="grid grid-cols-2 gap-3">
125
+ <Field label="Type" hint="optional">
126
+ <input
127
+ value={p.draft.type}
128
+ onChange={(e) => p.onDraft({ type: e.target.value })}
129
+ list={typesId}
130
+ placeholder="note"
131
+ className="w-full rounded-lg border border-border bg-surface-raised px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary/40"
132
+ />
133
+ <datalist id={typesId}>
134
+ {p.knownTypes.map((t) => (
135
+ <option key={t} value={t} />
136
+ ))}
137
+ </datalist>
138
+ </Field>
139
+
140
+ <Field label="Tags" hint="comma-separated">
141
+ <input
142
+ value={p.draft.tags}
143
+ onChange={(e) => p.onDraft({ tags: e.target.value })}
144
+ placeholder="idea, reading"
145
+ className="w-full rounded-lg border border-border bg-surface-raised px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary/40"
146
+ />
147
+ </Field>
148
+ </div>
149
+
150
+ {p.state === "error" && (
151
+ <div role="alert">
152
+ <Callout tone="red" variant="banner" icon="failed" mono text={p.error} />
153
+ </div>
154
+ )}
155
+ </div>
156
+
157
+ <div className="flex items-center justify-between border-t border-border px-5 py-3">
158
+ <span className="text-[11px] text-muted-foreground">
159
+ <Kbd>Ctrl</Kbd>/<Kbd>Cmd</Kbd> + <Kbd>↵</Kbd> to save
160
+ </span>
161
+ <div className="flex gap-2">
162
+ <Button label="Cancel" tone="quiet" size="sm" block={false} onClick={p.onClose} />
163
+ <Button
164
+ label={saving ? "Saving…" : "Add"}
165
+ icon="add"
166
+ tone="primary"
167
+ size="sm"
168
+ block={false}
169
+ disabled={!canSave}
170
+ onClick={p.onSave}
171
+ />
172
+ </div>
173
+ </div>
174
+ </div>
175
+ );
176
+ }
177
+
178
+ function Field({ label, hint, children }: { label: string; hint?: string; children: ReactNode }) {
179
+ return (
180
+ <label className="block space-y-1.5">
181
+ <span className="text-xs font-medium text-foreground">
182
+ {label}
183
+ {hint && <span className="font-normal text-muted-foreground"> — {hint}</span>}
184
+ </span>
185
+ {children}
186
+ </label>
187
+ );
188
+ }
@@ -1,10 +1,7 @@
1
1
  import { useState, useEffect, useRef } from "react";
2
- import { Loader2, CheckCircle2, XCircle } from "lucide-react";
3
2
  import { SlidePanel } from "../layout/slide-panel.js";
4
- import { Kbd } from "../layout/kbd.js";
5
- import { api } from "../../lib/api-client.js";
6
-
7
- type State = "editing" | "saving" | "saved" | "error";
3
+ import { useBrainApi } from "../../root-context.js";
4
+ import { AddForm, type AddState as State } from "./add-form.js";
8
5
 
9
6
  /** Split the tags field on commas; empties dropped so "a,,b," is clean. */
10
7
  function parseTags(raw: string): string[] {
@@ -14,6 +11,13 @@ function parseTags(raw: string): string[] {
14
11
  .filter(Boolean);
15
12
  }
16
13
 
14
+ /**
15
+ * The container (S6): the draft, `brain add`, `brain index` and the
16
+ * `operation.epoch` guard live here; `AddForm` draws from props. The epoch
17
+ * is bumped on open, on close, on "Add another" and on every request, so a
18
+ * response from a form the user has already left cannot land in the one
19
+ * they are looking at.
20
+ */
17
21
  export function AddPanel({
18
22
  open,
19
23
  onClose,
@@ -21,6 +25,7 @@ export function AddPanel({
21
25
  open: boolean;
22
26
  onClose: () => void;
23
27
  }) {
28
+ const api = useBrainApi();
24
29
  const [content, setContent] = useState("");
25
30
  const [title, setTitle] = useState("");
26
31
  const [type, setType] = useState("");
@@ -40,6 +45,7 @@ export function AddPanel({
40
45
  useEffect(() => {
41
46
  if (!open) return;
42
47
  operation.epoch++;
48
+ setKnownTypes([]);
43
49
  setSavedPath("");
44
50
  setIndexed(undefined);
45
51
  setIndexing(false);
@@ -67,7 +73,7 @@ export function AddPanel({
67
73
  cancelled = true;
68
74
  clearTimeout(t);
69
75
  };
70
- }, [open, operation]);
76
+ }, [open, operation, api]);
71
77
 
72
78
  async function handleSave() {
73
79
  const body = content.trim();
@@ -122,155 +128,28 @@ export function AddPanel({
122
128
  setTimeout(() => contentRef.current?.focus(), 0);
123
129
  }
124
130
 
125
- function handleKeyDown(e: React.KeyboardEvent) {
126
- // Cmd/Ctrl+Enter saves from anywhere in the form.
127
- if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
128
- e.preventDefault();
129
- void handleSave();
130
- }
131
- }
132
-
133
- const saving = state === "saving";
134
- const canSave = content.trim().length > 0 && !saving;
135
-
136
131
  return (
137
132
  <SlidePanel open={open} onClose={onClose} title="Add to brain" wide>
138
- <div className="flex h-full flex-col" onKeyDown={handleKeyDown}>
139
- {state === "saved" ? (
140
- <div className="flex flex-1 flex-col items-center justify-center gap-4 px-8 text-center">
141
- <CheckCircle2 className="h-8 w-8 text-primary" />
142
- <p className="text-sm text-foreground">Added to your brain.</p>
143
- <p className="text-xs text-muted-foreground">
144
- {indexed === false ? "Saved, but not indexed. Your content is safe; search may not find it yet."
145
- : indexed === true ? "Saved and indexed. Run a sync when you want to push it."
146
- : "Saved. This server did not report whether indexing completed."}
147
- </p>
148
- {savedPath && <p className="break-all text-xs text-muted-foreground">{savedPath}</p>}
149
- {indexed === false && (
150
- <div className="space-y-2" role="status">
151
- {error && <p className="text-xs text-destructive">{error}</p>}
152
- <button onClick={retryIndex} disabled={indexing} className="rounded-lg bg-primary px-4 py-1.5 text-xs text-primary-foreground disabled:opacity-40">
153
- {indexing ? "Indexing..." : "Retry indexing"}
154
- </button>
155
- </div>
156
- )}
157
- <div className="flex gap-2">
158
- <button
159
- onClick={handleAddAnother}
160
- className="rounded-lg bg-surface-raised px-4 py-1.5 text-xs font-medium text-foreground transition-colors hover:bg-surface-overlay"
161
- >
162
- Add another
163
- </button>
164
- <button
165
- onClick={onClose}
166
- className="rounded-lg bg-primary px-4 py-1.5 text-xs font-medium text-primary-foreground transition-opacity hover:opacity-90"
167
- >
168
- Done
169
- </button>
170
- </div>
171
- </div>
172
- ) : (
173
- <>
174
- <div className="flex-1 space-y-4 overflow-y-auto p-5">
175
- <Field label="Note">
176
- <textarea
177
- ref={contentRef}
178
- value={content}
179
- onChange={(e) => setContent(e.target.value)}
180
- rows={8}
181
- placeholder="What do you want to remember?"
182
- className="w-full resize-y rounded-lg border border-border bg-surface-raised px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary/40"
183
- />
184
- </Field>
185
-
186
- <Field label="Title" hint="optional, derived from the note if empty">
187
- <input
188
- value={title}
189
- onChange={(e) => setTitle(e.target.value)}
190
- className="w-full rounded-lg border border-border bg-surface-raised px-3 py-2 text-sm text-foreground outline-none transition-colors focus:border-primary/40"
191
- />
192
- </Field>
193
-
194
- <div className="grid grid-cols-2 gap-3">
195
- <Field label="Type" hint="optional">
196
- <input
197
- value={type}
198
- onChange={(e) => setType(e.target.value)}
199
- list="brain-add-types"
200
- placeholder="note"
201
- className="w-full rounded-lg border border-border bg-surface-raised px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary/40"
202
- />
203
- <datalist id="brain-add-types">
204
- {knownTypes.map((t) => (
205
- <option key={t} value={t} />
206
- ))}
207
- </datalist>
208
- </Field>
209
-
210
- <Field label="Tags" hint="comma-separated">
211
- <input
212
- value={tags}
213
- onChange={(e) => setTags(e.target.value)}
214
- placeholder="idea, reading"
215
- className="w-full rounded-lg border border-border bg-surface-raised px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary/40"
216
- />
217
- </Field>
218
- </div>
219
-
220
- {state === "error" && (
221
- <div className="flex items-start gap-2 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2">
222
- <XCircle className="mt-0.5 h-3.5 w-3.5 shrink-0 text-destructive" />
223
- <span className="text-xs text-destructive">{error}</span>
224
- </div>
225
- )}
226
- </div>
227
-
228
- <div className="flex items-center justify-between border-t border-border px-5 py-3">
229
- <span className="text-[11px] text-muted-foreground">
230
- <Kbd>Ctrl</Kbd>/<Kbd>Cmd</Kbd> + <Kbd>↵</Kbd> to save
231
- </span>
232
- <div className="flex gap-2">
233
- <button
234
- onClick={onClose}
235
- className="rounded-lg bg-surface-raised px-4 py-1.5 text-xs font-medium text-foreground transition-colors hover:bg-surface-overlay"
236
- >
237
- Cancel
238
- </button>
239
- <button
240
- onClick={handleSave}
241
- disabled={!canSave}
242
- className="flex items-center gap-1.5 rounded-lg bg-primary px-4 py-1.5 text-xs font-medium text-primary-foreground transition-opacity hover:opacity-90 disabled:opacity-40"
243
- >
244
- {saving && <Loader2 className="h-3.5 w-3.5 animate-spin" />}
245
- {saving ? "Saving..." : "Add"}
246
- </button>
247
- </div>
248
- </div>
249
- </>
250
- )}
251
- </div>
133
+ <AddForm
134
+ state={state}
135
+ draft={{ content, title, type, tags }}
136
+ knownTypes={knownTypes}
137
+ error={error}
138
+ savedPath={savedPath}
139
+ indexed={indexed}
140
+ indexing={indexing}
141
+ contentRef={contentRef}
142
+ onDraft={(patch) => {
143
+ if (patch.content !== undefined) setContent(patch.content);
144
+ if (patch.title !== undefined) setTitle(patch.title);
145
+ if (patch.type !== undefined) setType(patch.type);
146
+ if (patch.tags !== undefined) setTags(patch.tags);
147
+ }}
148
+ onSave={() => void handleSave()}
149
+ onRetryIndex={() => void retryIndex()}
150
+ onAddAnother={handleAddAnother}
151
+ onClose={onClose}
152
+ />
252
153
  </SlidePanel>
253
154
  );
254
155
  }
255
-
256
- function Field({
257
- label,
258
- hint,
259
- children,
260
- }: {
261
- label: string;
262
- hint?: string;
263
- children: React.ReactNode;
264
- }) {
265
- return (
266
- <label className="block space-y-1.5">
267
- <span className="text-xs font-medium text-foreground">
268
- {label}
269
- {hint && (
270
- <span className="font-normal text-muted-foreground"> — {hint}</span>
271
- )}
272
- </span>
273
- {children}
274
- </label>
275
- );
276
- }
@@ -4,7 +4,8 @@ import { SlidePanel } from "../layout/slide-panel.js";
4
4
  import { Kbd } from "../layout/kbd.js";
5
5
  import { useFileStore } from "../../stores/file-store.js";
6
6
  import { useUIStore } from "../../stores/ui-store.js";
7
- import { api, type BrainSearchHit } from "../../lib/api-client.js";
7
+ import type { BrainSearchHit } from "../../lib/api-client.js";
8
+ import { useBrainApi } from "../../root-context.js";
8
9
  import { parseSnippet } from "../../lib/search-snippet.js";
9
10
  import { cn } from "../../lib/utils.js";
10
11
 
@@ -22,6 +23,7 @@ export function SearchPanel({
22
23
  open: boolean;
23
24
  onClose: () => void;
24
25
  }) {
26
+ const api = useBrainApi();
25
27
  const [query, setQuery] = useState("");
26
28
  const [state, setState] = useState<State>("idle");
27
29
  const [resultQuery, setResultQuery] = useState("");
@@ -90,7 +92,7 @@ export function SearchPanel({
90
92
  } finally {
91
93
  if (controllerRef.current === controller) controllerRef.current = null;
92
94
  }
93
- }, [cancelSearch]);
95
+ }, [cancelSearch, api]);
94
96
 
95
97
  // Fresh panel every time it opens: stale results from a previous query would
96
98
  // otherwise flash before the first search lands.
@@ -110,7 +112,7 @@ export function SearchPanel({
110
112
  // mobile keyboard on some browsers.
111
113
  const t = setTimeout(() => inputRef.current?.focus(), 120);
112
114
  return () => { clearTimeout(t); cancelSearch(); };
113
- }, [open, cancelSearch]);
115
+ }, [open, cancelSearch, api]);
114
116
 
115
117
  // Debounced search on typing.
116
118
  useEffect(() => {
@@ -1,10 +1,14 @@
1
+ import { useBrainUiRoot } from "../../root-context.js";
1
2
  import { useState, useEffect, useRef } from "react";
2
- import { Loader2, CheckCircle2, XCircle } from "lucide-react";
3
3
  import { SlidePanel } from "../layout/slide-panel.js";
4
4
  import { linkifyPaths } from "../chat/brain-markdown.js";
5
+ import { StreamingOutput, type StreamState } from "./streaming-output.js";
5
6
 
6
- type StreamState = "idle" | "running" | "success" | "error" | "cancelled";
7
-
7
+ /**
8
+ * The container (S6) for a streamed backend job: the request, the SSE reader
9
+ * loop, the abort controller and the "still my stream" checks live here;
10
+ * `StreamingOutput` draws from props.
11
+ */
8
12
  export function StreamingPanel({
9
13
  open,
10
14
  onClose,
@@ -15,9 +19,11 @@ export function StreamingPanel({
15
19
  open: boolean;
16
20
  onClose: () => void;
17
21
  title: string;
22
+ /** Backend-relative path, resolved against the current root. */
18
23
  endpoint: string;
19
24
  method?: string;
20
25
  }) {
26
+ const root = useBrainUiRoot();
21
27
  const [state, setState] = useState<StreamState>("idle");
22
28
  const [lines, setLines] = useState<string[]>([]);
23
29
  const scrollRef = useRef<HTMLDivElement>(null);
@@ -29,30 +35,41 @@ export function StreamingPanel({
29
35
  setState("running");
30
36
  setLines([]);
31
37
 
38
+ let disposed = false;
39
+ let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;
32
40
  const controller = new AbortController();
41
+ const cancelReader = () => { void reader?.cancel().catch(() => {}); };
42
+ controller.signal.addEventListener("abort", cancelReader);
33
43
  controllerRef.current = controller;
34
44
 
35
45
  (async () => {
36
46
  try {
37
- const res = await fetch(endpoint, {
47
+ const res = await root.request(root.backendUrl(endpoint), {
38
48
  method,
39
49
  signal: controller.signal,
40
50
  });
41
51
 
52
+ if (disposed || controller.signal.aborted) {
53
+ await res.body?.cancel();
54
+ return;
55
+ }
56
+
42
57
  if (!res.ok || !res.body) {
43
- setState("error");
44
58
  const body = await res.json().catch(() => null);
59
+ if (disposed || controller.signal.aborted) return;
60
+ setState("error");
45
61
  const message = typeof body?.error === "string" ? body.error : `HTTP ${res.status}: ${res.statusText}`;
46
62
  if (!controller.signal.aborted) setLines((l) => [...l, message]);
47
63
  return;
48
64
  }
49
65
 
50
- const reader = res.body.getReader();
66
+ reader = res.body.getReader();
51
67
  const decoder = new TextDecoder();
52
68
  let buffer = "";
53
69
 
54
70
  while (true) {
55
71
  const { done, value } = await reader.read();
72
+ if (disposed || controller.signal.aborted) return;
56
73
  if (done) break;
57
74
 
58
75
  buffer += decoder.decode(value, { stream: true });
@@ -77,6 +94,7 @@ export function StreamingPanel({
77
94
  }
78
95
  }
79
96
  } catch (err: any) {
97
+ if (disposed || controller.signal.aborted) return;
80
98
  if (err.name === "AbortError") {
81
99
  setLines((l) => [...l, "Cancelled."]);
82
100
  setState("cancelled");
@@ -85,15 +103,18 @@ export function StreamingPanel({
85
103
  setLines((l) => [...l, `Error: ${err.message}`]);
86
104
  }
87
105
  } finally {
88
- controllerRef.current = null;
106
+ controller.signal.removeEventListener("abort", cancelReader);
107
+ reader?.releaseLock();
108
+ if (controllerRef.current === controller) controllerRef.current = null;
89
109
  }
90
110
  })();
91
111
 
92
112
  return () => {
113
+ disposed = true;
93
114
  controller.abort();
94
- controllerRef.current = null;
115
+ if (controllerRef.current === controller) controllerRef.current = null;
95
116
  };
96
- }, [open, endpoint, method]);
117
+ }, [open, endpoint, method, root]);
97
118
 
98
119
  // Auto-scroll
99
120
  useEffect(() => {
@@ -103,68 +124,18 @@ export function StreamingPanel({
103
124
  const isRunning = state === "running";
104
125
 
105
126
  return (
106
- <SlidePanel
107
- open={open}
108
- onClose={isRunning ? () => {} : onClose}
109
- title={title}
110
- >
111
- <div className="flex h-full flex-col">
112
- {/* Status bar */}
113
- <div className="flex items-center gap-2 border-b border-border px-5 py-2">
114
- {isRunning && (
115
- <Loader2 className="h-3.5 w-3.5 animate-spin text-primary" />
116
- )}
117
- {state === "success" && (
118
- <CheckCircle2 className="h-3.5 w-3.5 text-green-500" />
119
- )}
120
- {(state === "error" || state === "cancelled") && (
121
- <XCircle className="h-3.5 w-3.5 text-destructive" />
122
- )}
123
- <span className="text-xs text-muted-foreground">
124
- {isRunning
125
- ? "Running..."
126
- : state === "success"
127
- ? "Complete"
128
- : state === "error"
129
- ? "Failed"
130
- : state === "cancelled"
131
- ? "Cancelled"
132
- : "Ready"}
133
- </span>
134
- </div>
135
-
136
- {/* Log output */}
137
- <div className="flex-1 overflow-y-auto p-4 font-[family-name:var(--font-mono)] text-xs leading-relaxed text-muted-foreground">
138
- {lines.map((line, i) => (
139
- <div key={i} className="whitespace-pre-wrap">
140
- {linkifyPaths(line)}
141
- </div>
142
- ))}
143
- {isRunning && lines.length === 0 && (
144
- <div className="text-muted-foreground/50">Starting...</div>
145
- )}
146
- <div ref={scrollRef} />
147
- </div>
148
-
149
- {/* Footer */}
150
- <div className="border-t border-border px-5 py-3 flex justify-end">
151
- {isRunning ? (
152
- <button
153
- onClick={() => controllerRef.current?.abort()}
154
- className="rounded-lg border border-destructive/30 px-4 py-1.5 text-xs font-medium text-destructive transition-colors hover:bg-destructive/10"
155
- >
156
- Cancel
157
- </button>
158
- ) : (
159
- <button
160
- onClick={onClose}
161
- className="rounded-lg bg-surface-raised px-4 py-1.5 text-xs font-medium text-foreground transition-colors hover:bg-surface-overlay"
162
- >
163
- Close
164
- </button>
165
- )}
166
- </div>
167
- </div>
127
+ <SlidePanel open={open} onClose={isRunning ? () => {} : onClose} title={title}>
128
+ <StreamingOutput
129
+ state={state}
130
+ lines={lines.map((line) => linkifyPaths(line))}
131
+ anchor={<div ref={scrollRef} />}
132
+ onCancel={() => {
133
+ controllerRef.current?.abort();
134
+ setState("cancelled");
135
+ setLines((lines) => [...lines, "Cancelled."]);
136
+ }}
137
+ onClose={onClose}
138
+ />
168
139
  </SlidePanel>
169
140
  );
170
141
  }