@schlessera/brain-ui-react 0.35.0 → 0.37.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 (761) 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 +148 -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 +29 -0
  19. package/dist/components/activity/approval-card.d.ts.map +1 -0
  20. package/dist/components/activity/approval-card.js +73 -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 +11 -0
  39. package/dist/components/activity/span-bits.d.ts.map +1 -1
  40. package/dist/components/activity/span-bits.js +50 -7
  41. package/dist/components/activity/span-bits.js.map +1 -1
  42. package/dist/components/chat/ask-user-card.d.ts +76 -3
  43. package/dist/components/chat/ask-user-card.d.ts.map +1 -1
  44. package/dist/components/chat/ask-user-card.js +208 -149
  45. package/dist/components/chat/ask-user-card.js.map +1 -1
  46. package/dist/components/chat/ask-user-typed.d.ts +42 -0
  47. package/dist/components/chat/ask-user-typed.d.ts.map +1 -0
  48. package/dist/components/chat/ask-user-typed.js +60 -0
  49. package/dist/components/chat/ask-user-typed.js.map +1 -0
  50. package/dist/components/chat/brain-markdown-links.d.ts +2 -1
  51. package/dist/components/chat/brain-markdown-links.d.ts.map +1 -1
  52. package/dist/components/chat/brain-markdown-links.js +3 -4
  53. package/dist/components/chat/brain-markdown-links.js.map +1 -1
  54. package/dist/components/chat/brain-markdown.d.ts.map +1 -1
  55. package/dist/components/chat/brain-markdown.js +4 -2
  56. package/dist/components/chat/brain-markdown.js.map +1 -1
  57. package/dist/components/chat/chat-page.d.ts.map +1 -1
  58. package/dist/components/chat/chat-page.js +27 -11
  59. package/dist/components/chat/chat-page.js.map +1 -1
  60. package/dist/components/chat/composer-view.d.ts +75 -0
  61. package/dist/components/chat/composer-view.d.ts.map +1 -0
  62. package/dist/components/chat/composer-view.js +31 -0
  63. package/dist/components/chat/composer-view.js.map +1 -0
  64. package/dist/components/chat/composer.d.ts +4 -0
  65. package/dist/components/chat/composer.d.ts.map +1 -1
  66. package/dist/components/chat/composer.js +76 -59
  67. package/dist/components/chat/composer.js.map +1 -1
  68. package/dist/components/chat/markdown-content.d.ts +16 -1
  69. package/dist/components/chat/markdown-content.d.ts.map +1 -1
  70. package/dist/components/chat/markdown-content.js +47 -3
  71. package/dist/components/chat/markdown-content.js.map +1 -1
  72. package/dist/components/chat/mermaid-block.d.ts +4 -0
  73. package/dist/components/chat/mermaid-block.d.ts.map +1 -1
  74. package/dist/components/chat/mermaid-block.js +13 -5
  75. package/dist/components/chat/mermaid-block.js.map +1 -1
  76. package/dist/components/chat/mermaid-share.d.ts +2 -1
  77. package/dist/components/chat/mermaid-share.d.ts.map +1 -1
  78. package/dist/components/chat/mermaid-share.js +7 -8
  79. package/dist/components/chat/mermaid-share.js.map +1 -1
  80. package/dist/components/chat/mermaid-viewer.d.ts.map +1 -1
  81. package/dist/components/chat/mermaid-viewer.js +3 -1
  82. package/dist/components/chat/mermaid-viewer.js.map +1 -1
  83. package/dist/components/chat/message-bubble.d.ts +8 -1
  84. package/dist/components/chat/message-bubble.d.ts.map +1 -1
  85. package/dist/components/chat/message-bubble.js +53 -24
  86. package/dist/components/chat/message-bubble.js.map +1 -1
  87. package/dist/components/chat/message-share.d.ts +2 -1
  88. package/dist/components/chat/message-share.d.ts.map +1 -1
  89. package/dist/components/chat/message-share.js +6 -7
  90. package/dist/components/chat/message-share.js.map +1 -1
  91. package/dist/components/chat/renderers/bind.d.ts +39 -0
  92. package/dist/components/chat/renderers/bind.d.ts.map +1 -0
  93. package/dist/components/chat/renderers/bind.js +43 -0
  94. package/dist/components/chat/renderers/bind.js.map +1 -0
  95. package/dist/components/chat/renderers/brain-ui-tools.d.ts +3 -0
  96. package/dist/components/chat/renderers/brain-ui-tools.d.ts.map +1 -0
  97. package/dist/components/chat/renderers/brain-ui-tools.js +41 -0
  98. package/dist/components/chat/renderers/brain-ui-tools.js.map +1 -0
  99. package/dist/components/chat/renderers/claude-tools.d.ts.map +1 -1
  100. package/dist/components/chat/renderers/claude-tools.js +3 -2
  101. package/dist/components/chat/renderers/claude-tools.js.map +1 -1
  102. package/dist/components/chat/renderers/index.d.ts +10 -2
  103. package/dist/components/chat/renderers/index.d.ts.map +1 -1
  104. package/dist/components/chat/renderers/index.js +15 -10
  105. package/dist/components/chat/renderers/index.js.map +1 -1
  106. package/dist/components/chat/session-drawer.d.ts +4 -0
  107. package/dist/components/chat/session-drawer.d.ts.map +1 -1
  108. package/dist/components/chat/session-drawer.js +32 -32
  109. package/dist/components/chat/session-drawer.js.map +1 -1
  110. package/dist/components/chat/session-list.d.ts +41 -0
  111. package/dist/components/chat/session-list.d.ts.map +1 -0
  112. package/dist/components/chat/session-list.js +10 -0
  113. package/dist/components/chat/session-list.js.map +1 -0
  114. package/dist/components/chat/share-block.d.ts.map +1 -1
  115. package/dist/components/chat/share-block.js +12 -11
  116. package/dist/components/chat/share-block.js.map +1 -1
  117. package/dist/components/chat/share-card.js +2 -2
  118. package/dist/components/chat/share-card.js.map +1 -1
  119. package/dist/components/chat/subagent-view.js +1 -1
  120. package/dist/components/chat/subagent-view.js.map +1 -1
  121. package/dist/components/chat/tool-call-timeline.d.ts.map +1 -1
  122. package/dist/components/chat/tool-call-timeline.js +45 -14
  123. package/dist/components/chat/tool-call-timeline.js.map +1 -1
  124. package/dist/components/chat/tool-cards/block-card.d.ts +28 -0
  125. package/dist/components/chat/tool-cards/block-card.d.ts.map +1 -0
  126. package/dist/components/chat/tool-cards/block-card.js +103 -0
  127. package/dist/components/chat/tool-cards/block-card.js.map +1 -0
  128. package/dist/components/chat/tool-cards/image-mask-card.d.ts +70 -0
  129. package/dist/components/chat/tool-cards/image-mask-card.d.ts.map +1 -0
  130. package/dist/components/chat/tool-cards/image-mask-card.js +142 -0
  131. package/dist/components/chat/tool-cards/image-mask-card.js.map +1 -0
  132. package/dist/components/chat/tool-cards/location-card.d.ts +45 -0
  133. package/dist/components/chat/tool-cards/location-card.d.ts.map +1 -0
  134. package/dist/components/chat/tool-cards/location-card.js +128 -0
  135. package/dist/components/chat/tool-cards/location-card.js.map +1 -0
  136. package/dist/components/chat/tool-views.d.ts +19 -2
  137. package/dist/components/chat/tool-views.d.ts.map +1 -1
  138. package/dist/components/chat/tool-views.js +28 -22
  139. package/dist/components/chat/tool-views.js.map +1 -1
  140. package/dist/components/chat/transcript-turn.d.ts +45 -0
  141. package/dist/components/chat/transcript-turn.d.ts.map +1 -0
  142. package/dist/components/chat/transcript-turn.js +25 -0
  143. package/dist/components/chat/transcript-turn.js.map +1 -0
  144. package/dist/components/chat/use-chat-commands.d.ts.map +1 -1
  145. package/dist/components/chat/use-chat-commands.js +13 -16
  146. package/dist/components/chat/use-chat-commands.js.map +1 -1
  147. package/dist/components/chat/welcome-state.d.ts +7 -0
  148. package/dist/components/chat/welcome-state.d.ts.map +1 -1
  149. package/dist/components/chat/welcome-state.js +13 -5
  150. package/dist/components/chat/welcome-state.js.map +1 -1
  151. package/dist/components/connectivity/connection-gate.d.ts.map +1 -1
  152. package/dist/components/connectivity/connection-gate.js +27 -21
  153. package/dist/components/connectivity/connection-gate.js.map +1 -1
  154. package/dist/components/connectivity/login-form.d.ts +31 -0
  155. package/dist/components/connectivity/login-form.d.ts.map +1 -0
  156. package/dist/components/connectivity/login-form.js +19 -0
  157. package/dist/components/connectivity/login-form.js.map +1 -0
  158. package/dist/components/connectivity/login-screen.d.ts +5 -2
  159. package/dist/components/connectivity/login-screen.d.ts.map +1 -1
  160. package/dist/components/connectivity/login-screen.js +41 -31
  161. package/dist/components/connectivity/login-screen.js.map +1 -1
  162. package/dist/components/dev/share-harness.js +1 -1
  163. package/dist/components/dev/share-harness.js.map +1 -1
  164. package/dist/components/files/file-panel.d.ts +1 -1
  165. package/dist/components/files/file-panel.d.ts.map +1 -1
  166. package/dist/components/files/file-panel.js +74 -0
  167. package/dist/components/files/file-panel.js.map +1 -1
  168. package/dist/components/files/file-tree-view.d.ts +45 -0
  169. package/dist/components/files/file-tree-view.d.ts.map +1 -0
  170. package/dist/components/files/file-tree-view.js +51 -0
  171. package/dist/components/files/file-tree-view.js.map +1 -0
  172. package/dist/components/files/file-tree.d.ts +6 -0
  173. package/dist/components/files/file-tree.d.ts.map +1 -1
  174. package/dist/components/files/file-tree.js +39 -43
  175. package/dist/components/files/file-tree.js.map +1 -1
  176. package/dist/components/files/file-viewer-binary.d.ts.map +1 -1
  177. package/dist/components/files/file-viewer-binary.js +3 -2
  178. package/dist/components/files/file-viewer-binary.js.map +1 -1
  179. package/dist/components/files/file-viewer-frame.d.ts +36 -0
  180. package/dist/components/files/file-viewer-frame.d.ts.map +1 -0
  181. package/dist/components/files/file-viewer-frame.js +26 -0
  182. package/dist/components/files/file-viewer-frame.js.map +1 -0
  183. package/dist/components/files/file-viewer.d.ts +5 -0
  184. package/dist/components/files/file-viewer.d.ts.map +1 -1
  185. package/dist/components/files/file-viewer.js +26 -32
  186. package/dist/components/files/file-viewer.js.map +1 -1
  187. package/dist/components/files/frontmatter-chips.d.ts +18 -0
  188. package/dist/components/files/frontmatter-chips.d.ts.map +1 -0
  189. package/dist/components/files/frontmatter-chips.js +11 -0
  190. package/dist/components/files/frontmatter-chips.js.map +1 -0
  191. package/dist/components/files/frontmatter-panel.d.ts +5 -1
  192. package/dist/components/files/frontmatter-panel.d.ts.map +1 -1
  193. package/dist/components/files/frontmatter-panel.js +7 -6
  194. package/dist/components/files/frontmatter-panel.js.map +1 -1
  195. package/dist/components/files/staleness.d.ts +18 -0
  196. package/dist/components/files/staleness.d.ts.map +1 -0
  197. package/dist/components/files/staleness.js +27 -0
  198. package/dist/components/files/staleness.js.map +1 -0
  199. package/dist/components/graph/graph-canvas.d.ts.map +1 -1
  200. package/dist/components/graph/graph-canvas.js +24 -1
  201. package/dist/components/graph/graph-canvas.js.map +1 -1
  202. package/dist/components/graph/graph-controls-column.d.ts +14 -0
  203. package/dist/components/graph/graph-controls-column.d.ts.map +1 -0
  204. package/dist/components/graph/graph-controls-column.js +44 -0
  205. package/dist/components/graph/graph-controls-column.js.map +1 -0
  206. package/dist/components/graph/graph-controls.d.ts +20 -5
  207. package/dist/components/graph/graph-controls.d.ts.map +1 -1
  208. package/dist/components/graph/graph-controls.js +58 -37
  209. package/dist/components/graph/graph-controls.js.map +1 -1
  210. package/dist/components/graph/graph-form.d.ts +82 -0
  211. package/dist/components/graph/graph-form.d.ts.map +1 -0
  212. package/dist/components/graph/graph-form.js +69 -0
  213. package/dist/components/graph/graph-form.js.map +1 -0
  214. package/dist/components/graph/graph-maintenance.d.ts.map +1 -1
  215. package/dist/components/graph/graph-maintenance.js +6 -10
  216. package/dist/components/graph/graph-maintenance.js.map +1 -1
  217. package/dist/components/graph/graph-node-rail.d.ts +13 -0
  218. package/dist/components/graph/graph-node-rail.d.ts.map +1 -0
  219. package/dist/components/graph/graph-node-rail.js +92 -0
  220. package/dist/components/graph/graph-node-rail.js.map +1 -0
  221. package/dist/components/graph/graph-page.d.ts +7 -0
  222. package/dist/components/graph/graph-page.d.ts.map +1 -1
  223. package/dist/components/graph/graph-page.js +102 -12
  224. package/dist/components/graph/graph-page.js.map +1 -1
  225. package/dist/components/graph/graph-scene.d.ts.map +1 -1
  226. package/dist/components/graph/graph-scene.js +100 -24
  227. package/dist/components/graph/graph-scene.js.map +1 -1
  228. package/dist/components/graph/lib/graph-helpers.d.ts +42 -12
  229. package/dist/components/graph/lib/graph-helpers.d.ts.map +1 -1
  230. package/dist/components/graph/lib/graph-helpers.js +33 -41
  231. package/dist/components/graph/lib/graph-helpers.js.map +1 -1
  232. package/dist/components/graph/node-card.d.ts +28 -0
  233. package/dist/components/graph/node-card.d.ts.map +1 -0
  234. package/dist/components/graph/node-card.js +7 -0
  235. package/dist/components/graph/node-card.js.map +1 -0
  236. package/dist/components/graph/node-popover.d.ts +6 -2
  237. package/dist/components/graph/node-popover.d.ts.map +1 -1
  238. package/dist/components/graph/node-popover.js +13 -31
  239. package/dist/components/graph/node-popover.js.map +1 -1
  240. package/dist/components/graph/use-graph-theme.d.ts +32 -4
  241. package/dist/components/graph/use-graph-theme.d.ts.map +1 -1
  242. package/dist/components/graph/use-graph-theme.js +44 -32
  243. package/dist/components/graph/use-graph-theme.js.map +1 -1
  244. package/dist/components/graph/use-node-actions.d.ts +26 -0
  245. package/dist/components/graph/use-node-actions.d.ts.map +1 -0
  246. package/dist/components/graph/use-node-actions.js +54 -0
  247. package/dist/components/graph/use-node-actions.js.map +1 -0
  248. package/dist/components/images/image-share.d.ts +2 -1
  249. package/dist/components/images/image-share.d.ts.map +1 -1
  250. package/dist/components/images/image-share.js +3 -3
  251. package/dist/components/images/image-share.js.map +1 -1
  252. package/dist/components/images/image-viewer.d.ts.map +1 -1
  253. package/dist/components/images/image-viewer.js +3 -1
  254. package/dist/components/images/image-viewer.js.map +1 -1
  255. package/dist/components/images/mask-editor.d.ts.map +1 -1
  256. package/dist/components/images/mask-editor.js +7 -5
  257. package/dist/components/images/mask-editor.js.map +1 -1
  258. package/dist/components/layout/app-shell.d.ts.map +1 -1
  259. package/dist/components/layout/app-shell.js +4 -1
  260. package/dist/components/layout/app-shell.js.map +1 -1
  261. package/dist/components/layout/desktop-palette.d.ts +23 -0
  262. package/dist/components/layout/desktop-palette.d.ts.map +1 -0
  263. package/dist/components/layout/desktop-palette.js +132 -0
  264. package/dist/components/layout/desktop-palette.js.map +1 -0
  265. package/dist/components/layout/key-cap.d.ts +9 -0
  266. package/dist/components/layout/key-cap.d.ts.map +1 -0
  267. package/dist/components/layout/key-cap.js +10 -0
  268. package/dist/components/layout/key-cap.js.map +1 -0
  269. package/dist/components/layout/mobile-tab-bar.d.ts +13 -0
  270. package/dist/components/layout/mobile-tab-bar.d.ts.map +1 -1
  271. package/dist/components/layout/mobile-tab-bar.js +58 -47
  272. package/dist/components/layout/mobile-tab-bar.js.map +1 -1
  273. package/dist/components/layout/shortcut-switch.d.ts +13 -0
  274. package/dist/components/layout/shortcut-switch.d.ts.map +1 -0
  275. package/dist/components/layout/shortcut-switch.js +22 -0
  276. package/dist/components/layout/shortcut-switch.js.map +1 -0
  277. package/dist/components/layout/side-rail.d.ts +28 -0
  278. package/dist/components/layout/side-rail.d.ts.map +1 -1
  279. package/dist/components/layout/side-rail.js +72 -27
  280. package/dist/components/layout/side-rail.js.map +1 -1
  281. package/dist/components/layout/slide-panel.d.ts +25 -2
  282. package/dist/components/layout/slide-panel.d.ts.map +1 -1
  283. package/dist/components/layout/slide-panel.js +13 -4
  284. package/dist/components/layout/slide-panel.js.map +1 -1
  285. package/dist/components/layout/theme.d.ts +22 -0
  286. package/dist/components/layout/theme.d.ts.map +1 -0
  287. package/dist/components/layout/theme.js +44 -0
  288. package/dist/components/layout/theme.js.map +1 -0
  289. package/dist/components/quick-actions/add-form.d.ts +44 -0
  290. package/dist/components/quick-actions/add-form.d.ts.map +1 -0
  291. package/dist/components/quick-actions/add-form.js +32 -0
  292. package/dist/components/quick-actions/add-form.js.map +1 -0
  293. package/dist/components/quick-actions/add-modal.d.ts +7 -0
  294. package/dist/components/quick-actions/add-modal.d.ts.map +1 -1
  295. package/dist/components/quick-actions/add-modal.js +23 -20
  296. package/dist/components/quick-actions/add-modal.js.map +1 -1
  297. package/dist/components/quick-actions/search-modal.d.ts.map +1 -1
  298. package/dist/components/quick-actions/search-modal.js +8 -5
  299. package/dist/components/quick-actions/search-modal.js.map +1 -1
  300. package/dist/components/quick-actions/streaming-modal.d.ts +6 -0
  301. package/dist/components/quick-actions/streaming-modal.d.ts.map +1 -1
  302. package/dist/components/quick-actions/streaming-modal.js +53 -18
  303. package/dist/components/quick-actions/streaming-modal.js.map +1 -1
  304. package/dist/components/quick-actions/streaming-output.d.ts +38 -0
  305. package/dist/components/quick-actions/streaming-output.d.ts.map +1 -0
  306. package/dist/components/quick-actions/streaming-output.js +22 -0
  307. package/dist/components/quick-actions/streaming-output.js.map +1 -0
  308. package/dist/components/quick-actions/whatsup-modal.d.ts +5 -0
  309. package/dist/components/quick-actions/whatsup-modal.d.ts.map +1 -1
  310. package/dist/components/quick-actions/whatsup-modal.js +51 -10
  311. package/dist/components/quick-actions/whatsup-modal.js.map +1 -1
  312. package/dist/components/settings/devices-agents-tab.d.ts +6 -1
  313. package/dist/components/settings/devices-agents-tab.d.ts.map +1 -1
  314. package/dist/components/settings/devices-agents-tab.js +55 -20
  315. package/dist/components/settings/devices-agents-tab.js.map +1 -1
  316. package/dist/components/settings/models-list.d.ts +39 -0
  317. package/dist/components/settings/models-list.d.ts.map +1 -0
  318. package/dist/components/settings/models-list.js +72 -0
  319. package/dist/components/settings/models-list.js.map +1 -0
  320. package/dist/components/settings/models-tab.d.ts +4 -0
  321. package/dist/components/settings/models-tab.d.ts.map +1 -1
  322. package/dist/components/settings/models-tab.js +52 -102
  323. package/dist/components/settings/models-tab.js.map +1 -1
  324. package/dist/components/settings/one-time-agent-credential.js +1 -1
  325. package/dist/components/settings/one-time-agent-credential.js.map +1 -1
  326. package/dist/components/settings/passkey-list.d.ts +35 -0
  327. package/dist/components/settings/passkey-list.d.ts.map +1 -0
  328. package/dist/components/settings/passkey-list.js +34 -0
  329. package/dist/components/settings/passkey-list.js.map +1 -0
  330. package/dist/components/settings/passkey-tab.d.ts +3 -0
  331. package/dist/components/settings/passkey-tab.d.ts.map +1 -1
  332. package/dist/components/settings/passkey-tab.js +53 -45
  333. package/dist/components/settings/passkey-tab.js.map +1 -1
  334. package/dist/components/settings/pi-accounts-list.d.ts +27 -0
  335. package/dist/components/settings/pi-accounts-list.d.ts.map +1 -0
  336. package/dist/components/settings/pi-accounts-list.js +15 -0
  337. package/dist/components/settings/pi-accounts-list.js.map +1 -0
  338. package/dist/components/settings/pi-accounts.d.ts +3 -0
  339. package/dist/components/settings/pi-accounts.d.ts.map +1 -1
  340. package/dist/components/settings/pi-accounts.js +73 -55
  341. package/dist/components/settings/pi-accounts.js.map +1 -1
  342. package/dist/components/settings/principal-list.d.ts +37 -0
  343. package/dist/components/settings/principal-list.d.ts.map +1 -0
  344. package/dist/components/settings/principal-list.js +18 -0
  345. package/dist/components/settings/principal-list.js.map +1 -0
  346. package/dist/components/settings/settings-panel.d.ts +10 -3
  347. package/dist/components/settings/settings-panel.d.ts.map +1 -1
  348. package/dist/components/settings/settings-panel.js +71 -10
  349. package/dist/components/settings/settings-panel.js.map +1 -1
  350. package/dist/components/settings/skills-list.d.ts +53 -0
  351. package/dist/components/settings/skills-list.d.ts.map +1 -0
  352. package/dist/components/settings/skills-list.js +28 -0
  353. package/dist/components/settings/skills-list.js.map +1 -0
  354. package/dist/components/settings/skills-tab.d.ts.map +1 -1
  355. package/dist/components/settings/skills-tab.js +65 -38
  356. package/dist/components/settings/skills-tab.js.map +1 -1
  357. package/dist/components/settings/tool-permissions-list.d.ts +18 -0
  358. package/dist/components/settings/tool-permissions-list.d.ts.map +1 -0
  359. package/dist/components/settings/tool-permissions-list.js +6 -0
  360. package/dist/components/settings/tool-permissions-list.js.map +1 -0
  361. package/dist/components/settings/tool-permissions.d.ts +2 -1
  362. package/dist/components/settings/tool-permissions.d.ts.map +1 -1
  363. package/dist/components/settings/tool-permissions.js +33 -16
  364. package/dist/components/settings/tool-permissions.js.map +1 -1
  365. package/dist/components/settings/web-search-chain.d.ts +41 -0
  366. package/dist/components/settings/web-search-chain.d.ts.map +1 -0
  367. package/dist/components/settings/web-search-chain.js +47 -0
  368. package/dist/components/settings/web-search-chain.js.map +1 -0
  369. package/dist/components/settings/web-search-settings.d.ts +4 -7
  370. package/dist/components/settings/web-search-settings.d.ts.map +1 -1
  371. package/dist/components/settings/web-search-settings.js +54 -76
  372. package/dist/components/settings/web-search-settings.js.map +1 -1
  373. package/dist/components/share/share-menu.d.ts.map +1 -1
  374. package/dist/components/share/share-menu.js +24 -4
  375. package/dist/components/share/share-menu.js.map +1 -1
  376. package/dist/components/voice/dictation-sheet.js +3 -3
  377. package/dist/components/voice/dictation-sheet.js.map +1 -1
  378. package/dist/components/voice/mic-button.js +1 -1
  379. package/dist/components/voice/mic-button.js.map +1 -1
  380. package/dist/components/voice/review-card.js +1 -1
  381. package/dist/components/voice/review-card.js.map +1 -1
  382. package/dist/config.d.ts +5 -2
  383. package/dist/config.d.ts.map +1 -1
  384. package/dist/config.js +15 -5
  385. package/dist/config.js.map +1 -1
  386. package/dist/connection.d.ts +12 -0
  387. package/dist/connection.d.ts.map +1 -0
  388. package/dist/connection.js +421 -0
  389. package/dist/connection.js.map +1 -0
  390. package/dist/default-root.d.ts +3 -0
  391. package/dist/default-root.d.ts.map +1 -0
  392. package/dist/default-root.js +16 -0
  393. package/dist/default-root.js.map +1 -0
  394. package/dist/hooks/use-color-scheme.d.ts +14 -0
  395. package/dist/hooks/use-color-scheme.d.ts.map +1 -0
  396. package/dist/hooks/use-color-scheme.js +37 -0
  397. package/dist/hooks/use-color-scheme.js.map +1 -0
  398. package/dist/hooks/use-fine-pointer.d.ts +12 -0
  399. package/dist/hooks/use-fine-pointer.d.ts.map +1 -0
  400. package/dist/hooks/use-fine-pointer.js +15 -0
  401. package/dist/hooks/use-fine-pointer.js.map +1 -0
  402. package/dist/hooks/use-hash-routes.d.ts.map +1 -1
  403. package/dist/hooks/use-hash-routes.js +4 -2
  404. package/dist/hooks/use-hash-routes.js.map +1 -1
  405. package/dist/hooks/use-media-query.d.ts +9 -0
  406. package/dist/hooks/use-media-query.d.ts.map +1 -0
  407. package/dist/hooks/use-media-query.js +38 -0
  408. package/dist/hooks/use-media-query.js.map +1 -0
  409. package/dist/hooks/use-share-intake.d.ts.map +1 -1
  410. package/dist/hooks/use-share-intake.js +37 -12
  411. package/dist/hooks/use-share-intake.js.map +1 -1
  412. package/dist/hooks/use-vpn-status.d.ts.map +1 -1
  413. package/dist/hooks/use-vpn-status.js +17 -18
  414. package/dist/hooks/use-vpn-status.js.map +1 -1
  415. package/dist/hooks/use-websocket.d.ts +5 -24
  416. package/dist/hooks/use-websocket.d.ts.map +1 -1
  417. package/dist/hooks/use-websocket.js +11 -384
  418. package/dist/hooks/use-websocket.js.map +1 -1
  419. package/dist/hooks/websocket-handlers/activity.d.ts +2 -2
  420. package/dist/hooks/websocket-handlers/activity.d.ts.map +1 -1
  421. package/dist/hooks/websocket-handlers/activity.js +4 -5
  422. package/dist/hooks/websocket-handlers/activity.js.map +1 -1
  423. package/dist/hooks/websocket-handlers/chat.d.ts +1 -0
  424. package/dist/hooks/websocket-handlers/chat.d.ts.map +1 -1
  425. package/dist/hooks/websocket-handlers/chat.js +28 -6
  426. package/dist/hooks/websocket-handlers/chat.js.map +1 -1
  427. package/dist/hooks/websocket-handlers/connection.d.ts.map +1 -1
  428. package/dist/hooks/websocket-handlers/connection.js +4 -6
  429. package/dist/hooks/websocket-handlers/connection.js.map +1 -1
  430. package/dist/hooks/websocket-handlers/mask.d.ts +1 -1
  431. package/dist/hooks/websocket-handlers/mask.d.ts.map +1 -1
  432. package/dist/hooks/websocket-handlers/mask.js +2 -3
  433. package/dist/hooks/websocket-handlers/mask.js.map +1 -1
  434. package/dist/hooks/websocket-handlers/provider.d.ts.map +1 -1
  435. package/dist/hooks/websocket-handlers/provider.js +4 -6
  436. package/dist/hooks/websocket-handlers/provider.js.map +1 -1
  437. package/dist/hooks/websocket-handlers/types.d.ts +6 -2
  438. package/dist/hooks/websocket-handlers/types.d.ts.map +1 -1
  439. package/dist/index.d.ts +5 -3
  440. package/dist/index.d.ts.map +1 -1
  441. package/dist/index.js +6 -3
  442. package/dist/index.js.map +1 -1
  443. package/dist/lib/api-client.d.ts +289 -0
  444. package/dist/lib/api-client.d.ts.map +1 -1
  445. package/dist/lib/api-client.js +243 -224
  446. package/dist/lib/api-client.js.map +1 -1
  447. package/dist/lib/backend.d.ts +19 -2
  448. package/dist/lib/backend.d.ts.map +1 -1
  449. package/dist/lib/backend.js +15 -9
  450. package/dist/lib/backend.js.map +1 -1
  451. package/dist/lib/diff.d.ts +8 -10
  452. package/dist/lib/diff.d.ts.map +1 -1
  453. package/dist/lib/diff.js +26 -53
  454. package/dist/lib/diff.js.map +1 -1
  455. package/dist/lib/light-dark.d.ts +37 -0
  456. package/dist/lib/light-dark.d.ts.map +1 -0
  457. package/dist/lib/light-dark.js +83 -0
  458. package/dist/lib/light-dark.js.map +1 -0
  459. package/dist/lib/mermaid-theme.d.ts +7 -2
  460. package/dist/lib/mermaid-theme.d.ts.map +1 -1
  461. package/dist/lib/mermaid-theme.js +125 -203
  462. package/dist/lib/mermaid-theme.js.map +1 -1
  463. package/dist/lib/passkeys.d.ts +6 -3
  464. package/dist/lib/passkeys.d.ts.map +1 -1
  465. package/dist/lib/passkeys.js +10 -4
  466. package/dist/lib/passkeys.js.map +1 -1
  467. package/dist/lib/push-registration.d.ts +4 -1
  468. package/dist/lib/push-registration.d.ts.map +1 -1
  469. package/dist/lib/push-registration.js +20 -2
  470. package/dist/lib/push-registration.js.map +1 -1
  471. package/dist/lib/share-intake.d.ts +2 -1
  472. package/dist/lib/share-intake.d.ts.map +1 -1
  473. package/dist/lib/share-intake.js +3 -3
  474. package/dist/lib/share-intake.js.map +1 -1
  475. package/dist/lib/share.d.ts +4 -3
  476. package/dist/lib/share.d.ts.map +1 -1
  477. package/dist/lib/share.js +6 -7
  478. package/dist/lib/share.js.map +1 -1
  479. package/dist/lib/single-key.d.ts +30 -0
  480. package/dist/lib/single-key.d.ts.map +1 -0
  481. package/dist/lib/single-key.js +45 -0
  482. package/dist/lib/single-key.js.map +1 -0
  483. package/dist/lib/tool-names.d.ts +8 -6
  484. package/dist/lib/tool-names.d.ts.map +1 -1
  485. package/dist/lib/tool-names.js +17 -7
  486. package/dist/lib/tool-names.js.map +1 -1
  487. package/dist/root-context.d.ts +229 -0
  488. package/dist/root-context.d.ts.map +1 -0
  489. package/dist/root-context.js +33 -0
  490. package/dist/root-context.js.map +1 -0
  491. package/dist/root.d.ts +38 -0
  492. package/dist/root.d.ts.map +1 -0
  493. package/dist/root.js +47 -0
  494. package/dist/root.js.map +1 -0
  495. package/dist/stores/activity-state.d.ts +29 -0
  496. package/dist/stores/activity-state.d.ts.map +1 -0
  497. package/dist/stores/activity-state.js +282 -0
  498. package/dist/stores/activity-state.js.map +1 -0
  499. package/dist/stores/activity-store.d.ts +10 -41
  500. package/dist/stores/activity-store.d.ts.map +1 -1
  501. package/dist/stores/activity-store.js +9 -271
  502. package/dist/stores/activity-store.js.map +1 -1
  503. package/dist/stores/chat-state.d.ts +233 -0
  504. package/dist/stores/chat-state.d.ts.map +1 -0
  505. package/dist/stores/chat-state.js +477 -0
  506. package/dist/stores/chat-state.js.map +1 -0
  507. package/dist/stores/chat-store.d.ts +4 -162
  508. package/dist/stores/chat-store.d.ts.map +1 -1
  509. package/dist/stores/chat-store.js +7 -418
  510. package/dist/stores/chat-store.js.map +1 -1
  511. package/dist/stores/connection-state.d.ts +40 -0
  512. package/dist/stores/connection-state.d.ts.map +1 -0
  513. package/dist/stores/connection-state.js +30 -0
  514. package/dist/stores/connection-state.js.map +1 -0
  515. package/dist/stores/connection-store.d.ts +4 -40
  516. package/dist/stores/connection-store.d.ts.map +1 -1
  517. package/dist/stores/connection-store.js +7 -27
  518. package/dist/stores/connection-store.js.map +1 -1
  519. package/dist/stores/create-stores.d.ts +23 -0
  520. package/dist/stores/create-stores.d.ts.map +1 -0
  521. package/dist/stores/create-stores.js +28 -0
  522. package/dist/stores/create-stores.js.map +1 -0
  523. package/dist/stores/file-state.d.ts +53 -0
  524. package/dist/stores/file-state.d.ts.map +1 -0
  525. package/dist/stores/file-state.js +341 -0
  526. package/dist/stores/file-state.js.map +1 -0
  527. package/dist/stores/file-store.d.ts +4 -52
  528. package/dist/stores/file-store.d.ts.map +1 -1
  529. package/dist/stores/file-store.js +7 -336
  530. package/dist/stores/file-store.js.map +1 -1
  531. package/dist/stores/graph-state.d.ts +95 -0
  532. package/dist/stores/graph-state.d.ts.map +1 -0
  533. package/dist/stores/graph-state.js +252 -0
  534. package/dist/stores/graph-state.js.map +1 -0
  535. package/dist/stores/graph-store.d.ts +7 -83
  536. package/dist/stores/graph-store.d.ts.map +1 -1
  537. package/dist/stores/graph-store.js +8 -249
  538. package/dist/stores/graph-store.js.map +1 -1
  539. package/dist/stores/mask-state.d.ts +21 -0
  540. package/dist/stores/mask-state.d.ts.map +1 -0
  541. package/dist/stores/mask-state.js +9 -0
  542. package/dist/stores/mask-state.js.map +1 -0
  543. package/dist/stores/mask-store.d.ts +4 -21
  544. package/dist/stores/mask-store.d.ts.map +1 -1
  545. package/dist/stores/mask-store.js +7 -6
  546. package/dist/stores/mask-store.js.map +1 -1
  547. package/dist/stores/principal-state.d.ts +16 -0
  548. package/dist/stores/principal-state.d.ts.map +1 -0
  549. package/dist/stores/principal-state.js +31 -0
  550. package/dist/stores/principal-state.js.map +1 -0
  551. package/dist/stores/principal-store.d.ts +4 -15
  552. package/dist/stores/principal-store.d.ts.map +1 -1
  553. package/dist/stores/principal-store.js +7 -28
  554. package/dist/stores/principal-store.js.map +1 -1
  555. package/dist/stores/provider-state.d.ts +24 -0
  556. package/dist/stores/provider-state.d.ts.map +1 -0
  557. package/dist/stores/provider-state.js +68 -0
  558. package/dist/stores/provider-state.js.map +1 -0
  559. package/dist/stores/provider-store.d.ts +4 -23
  560. package/dist/stores/provider-store.d.ts.map +1 -1
  561. package/dist/stores/provider-store.js +7 -64
  562. package/dist/stores/provider-store.js.map +1 -1
  563. package/dist/stores/share-state.d.ts +29 -0
  564. package/dist/stores/share-state.d.ts.map +1 -0
  565. package/dist/stores/share-state.js +21 -0
  566. package/dist/stores/share-state.js.map +1 -0
  567. package/dist/stores/share-store.d.ts +4 -28
  568. package/dist/stores/share-store.d.ts.map +1 -1
  569. package/dist/stores/share-store.js +7 -18
  570. package/dist/stores/share-store.js.map +1 -1
  571. package/dist/stores/store-environment.d.ts +10 -0
  572. package/dist/stores/store-environment.d.ts.map +1 -0
  573. package/dist/stores/store-environment.js +2 -0
  574. package/dist/stores/store-environment.js.map +1 -0
  575. package/dist/stores/ui-state.d.ts +71 -0
  576. package/dist/stores/ui-state.d.ts.map +1 -0
  577. package/dist/stores/ui-state.js +58 -0
  578. package/dist/stores/ui-state.js.map +1 -0
  579. package/dist/stores/ui-store.d.ts +4 -45
  580. package/dist/stores/ui-store.d.ts.map +1 -1
  581. package/dist/stores/ui-store.js +7 -36
  582. package/dist/stores/ui-store.js.map +1 -1
  583. package/dist/styles.css +1 -1
  584. package/dist/theme.css +150 -97
  585. package/dist/voice/asr-clients.d.ts +2 -1
  586. package/dist/voice/asr-clients.d.ts.map +1 -1
  587. package/dist/voice/asr-clients.js +16 -17
  588. package/dist/voice/asr-clients.js.map +1 -1
  589. package/dist/voice/use-dictation.d.ts.map +1 -1
  590. package/dist/voice/use-dictation.js +12 -8
  591. package/dist/voice/use-dictation.js.map +1 -1
  592. package/dist/voice/voice-state.d.ts +25 -0
  593. package/dist/voice/voice-state.d.ts.map +1 -0
  594. package/dist/voice/voice-state.js +29 -0
  595. package/dist/voice/voice-state.js.map +1 -0
  596. package/dist/voice/voice-store.d.ts +4 -25
  597. package/dist/voice/voice-store.d.ts.map +1 -1
  598. package/dist/voice/voice-store.js +7 -26
  599. package/dist/voice/voice-store.js.map +1 -1
  600. package/package.json +3 -2
  601. package/src/components/activity/activity-page.tsx +341 -160
  602. package/src/components/activity/activity-run-detail.tsx +81 -47
  603. package/src/components/activity/activity-run-list.tsx +27 -59
  604. package/src/components/activity/activity-views.tsx +155 -0
  605. package/src/components/activity/approval-card.tsx +117 -0
  606. package/src/components/activity/digest-card.tsx +25 -61
  607. package/src/components/activity/digest-summary.tsx +52 -0
  608. package/src/components/activity/push-switch.tsx +62 -0
  609. package/src/components/activity/push-toggle.tsx +51 -81
  610. package/src/components/activity/span-bits.tsx +60 -7
  611. package/src/components/chat/ask-user-card.tsx +292 -356
  612. package/src/components/chat/ask-user-typed.ts +77 -0
  613. package/src/components/chat/brain-markdown-links.tsx +4 -4
  614. package/src/components/chat/brain-markdown.tsx +4 -2
  615. package/src/components/chat/chat-page.tsx +41 -11
  616. package/src/components/chat/composer-view.tsx +194 -0
  617. package/src/components/chat/composer.tsx +117 -296
  618. package/src/components/chat/markdown-content.tsx +53 -2
  619. package/src/components/chat/mermaid-block.tsx +13 -5
  620. package/src/components/chat/mermaid-share.ts +8 -7
  621. package/src/components/chat/mermaid-viewer.tsx +3 -1
  622. package/src/components/chat/message-bubble.tsx +78 -94
  623. package/src/components/chat/message-share.ts +7 -7
  624. package/src/components/chat/renderers/bind.tsx +94 -0
  625. package/src/components/chat/renderers/brain-ui-tools.tsx +56 -0
  626. package/src/components/chat/renderers/claude-tools.tsx +3 -2
  627. package/src/components/chat/renderers/index.ts +15 -10
  628. package/src/components/chat/session-drawer.tsx +41 -138
  629. package/src/components/chat/session-list.tsx +113 -0
  630. package/src/components/chat/share-block.tsx +16 -12
  631. package/src/components/chat/share-card.tsx +2 -2
  632. package/src/components/chat/subagent-view.tsx +4 -4
  633. package/src/components/chat/tool-call-timeline.tsx +75 -26
  634. package/src/components/chat/tool-cards/block-card.tsx +145 -0
  635. package/src/components/chat/tool-cards/image-mask-card.tsx +214 -0
  636. package/src/components/chat/tool-cards/location-card.tsx +159 -0
  637. package/src/components/chat/tool-views.tsx +30 -60
  638. package/src/components/chat/transcript-turn.tsx +108 -0
  639. package/src/components/chat/use-chat-commands.ts +14 -16
  640. package/src/components/chat/welcome-state.tsx +36 -91
  641. package/src/components/connectivity/connection-gate.tsx +32 -24
  642. package/src/components/connectivity/login-form.tsx +122 -0
  643. package/src/components/connectivity/login-screen.tsx +45 -100
  644. package/src/components/dev/share-harness.tsx +2 -2
  645. package/src/components/files/file-panel.tsx +168 -0
  646. package/src/components/files/file-tree-view.tsx +127 -0
  647. package/src/components/files/file-tree.tsx +55 -109
  648. package/src/components/files/file-viewer-binary.tsx +3 -2
  649. package/src/components/files/file-viewer-frame.tsx +113 -0
  650. package/src/components/files/file-viewer.tsx +40 -95
  651. package/src/components/files/frontmatter-chips.tsx +42 -0
  652. package/src/components/files/frontmatter-panel.tsx +6 -71
  653. package/src/components/files/staleness.ts +29 -0
  654. package/src/components/graph/graph-canvas.tsx +24 -1
  655. package/src/components/graph/graph-controls-column.tsx +92 -0
  656. package/src/components/graph/graph-controls.tsx +83 -127
  657. package/src/components/graph/graph-form.tsx +183 -0
  658. package/src/components/graph/graph-maintenance.tsx +9 -14
  659. package/src/components/graph/graph-node-rail.tsx +147 -0
  660. package/src/components/graph/graph-page.tsx +189 -49
  661. package/src/components/graph/graph-scene.tsx +200 -30
  662. package/src/components/graph/lib/graph-helpers.ts +65 -43
  663. package/src/components/graph/node-card.tsx +64 -0
  664. package/src/components/graph/node-popover.tsx +28 -117
  665. package/src/components/graph/use-graph-theme.ts +69 -32
  666. package/src/components/graph/use-node-actions.ts +56 -0
  667. package/src/components/images/image-share.ts +4 -2
  668. package/src/components/images/image-viewer.tsx +3 -1
  669. package/src/components/images/mask-editor.tsx +7 -4
  670. package/src/components/layout/app-shell.tsx +5 -1
  671. package/src/components/layout/desktop-palette.tsx +151 -0
  672. package/src/components/layout/key-cap.tsx +15 -0
  673. package/src/components/layout/mobile-tab-bar.tsx +80 -157
  674. package/src/components/layout/shortcut-switch.tsx +32 -0
  675. package/src/components/layout/side-rail.tsx +77 -150
  676. package/src/components/layout/slide-panel.tsx +49 -6
  677. package/src/components/layout/theme.tsx +67 -0
  678. package/src/components/quick-actions/add-form.tsx +196 -0
  679. package/src/components/quick-actions/add-modal.tsx +32 -153
  680. package/src/components/quick-actions/search-modal.tsx +15 -5
  681. package/src/components/quick-actions/streaming-modal.tsx +57 -72
  682. package/src/components/quick-actions/streaming-output.tsx +112 -0
  683. package/src/components/quick-actions/whatsup-modal.tsx +53 -59
  684. package/src/components/settings/devices-agents-tab.tsx +60 -152
  685. package/src/components/settings/models-list.tsx +299 -0
  686. package/src/components/settings/models-tab.tsx +63 -337
  687. package/src/components/settings/one-time-agent-credential.tsx +1 -1
  688. package/src/components/settings/passkey-list.tsx +201 -0
  689. package/src/components/settings/passkey-tab.tsx +53 -197
  690. package/src/components/settings/pi-accounts-list.tsx +128 -0
  691. package/src/components/settings/pi-accounts.tsx +71 -170
  692. package/src/components/settings/principal-list.tsx +172 -0
  693. package/src/components/settings/settings-panel.tsx +239 -25
  694. package/src/components/settings/skills-list.tsx +276 -0
  695. package/src/components/settings/skills-tab.tsx +82 -269
  696. package/src/components/settings/tool-permissions-list.tsx +54 -0
  697. package/src/components/settings/tool-permissions.tsx +27 -46
  698. package/src/components/settings/web-search-chain.tsx +300 -0
  699. package/src/components/settings/web-search-settings.tsx +58 -328
  700. package/src/components/share/share-menu.tsx +19 -4
  701. package/src/components/voice/dictation-sheet.tsx +5 -5
  702. package/src/components/voice/mic-button.tsx +1 -1
  703. package/src/components/voice/review-card.tsx +1 -1
  704. package/src/config.ts +21 -7
  705. package/src/connection.ts +443 -0
  706. package/src/default-root.ts +16 -0
  707. package/src/hooks/use-color-scheme.ts +36 -0
  708. package/src/hooks/use-fine-pointer.ts +15 -0
  709. package/src/hooks/use-hash-routes.ts +4 -2
  710. package/src/hooks/use-media-query.ts +35 -0
  711. package/src/hooks/use-share-intake.ts +32 -12
  712. package/src/hooks/use-vpn-status.ts +18 -17
  713. package/src/hooks/use-websocket.ts +12 -428
  714. package/src/hooks/websocket-handlers/activity.ts +4 -5
  715. package/src/hooks/websocket-handlers/chat.ts +28 -6
  716. package/src/hooks/websocket-handlers/connection.ts +4 -6
  717. package/src/hooks/websocket-handlers/mask.ts +2 -3
  718. package/src/hooks/websocket-handlers/provider.ts +4 -6
  719. package/src/hooks/websocket-handlers/types.ts +6 -2
  720. package/src/index.ts +7 -3
  721. package/src/lib/api-client.ts +426 -384
  722. package/src/lib/backend.ts +20 -10
  723. package/src/lib/diff.ts +28 -62
  724. package/src/lib/light-dark.ts +83 -0
  725. package/src/lib/mermaid-theme.ts +183 -214
  726. package/src/lib/passkeys.ts +12 -4
  727. package/src/lib/push-registration.ts +19 -2
  728. package/src/lib/share-intake.ts +6 -3
  729. package/src/lib/share.ts +7 -4
  730. package/src/lib/single-key.ts +47 -0
  731. package/src/lib/tool-names.ts +31 -8
  732. package/src/root-context.tsx +40 -0
  733. package/src/root.ts +83 -0
  734. package/src/stores/activity-state.ts +295 -0
  735. package/src/stores/activity-store.ts +11 -285
  736. package/src/stores/chat-state.ts +822 -0
  737. package/src/stores/chat-store.ts +11 -705
  738. package/src/stores/connection-state.ts +78 -0
  739. package/src/stores/connection-store.ts +11 -76
  740. package/src/stores/create-stores.ts +31 -0
  741. package/src/stores/file-state.ts +399 -0
  742. package/src/stores/file-store.ts +9 -390
  743. package/src/stores/graph-state.ts +368 -0
  744. package/src/stores/graph-store.ts +10 -355
  745. package/src/stores/mask-state.ts +30 -0
  746. package/src/stores/mask-store.ts +10 -27
  747. package/src/stores/principal-state.ts +42 -0
  748. package/src/stores/principal-store.ts +10 -37
  749. package/src/stores/provider-state.ts +103 -0
  750. package/src/stores/provider-store.ts +10 -95
  751. package/src/stores/share-state.ts +56 -0
  752. package/src/stores/share-store.ts +11 -54
  753. package/src/stores/store-environment.ts +10 -0
  754. package/src/stores/ui-state.ts +143 -0
  755. package/src/stores/ui-store.ts +11 -93
  756. package/src/styles.css +4 -1
  757. package/src/theme.css +150 -97
  758. package/src/voice/asr-clients.ts +17 -17
  759. package/src/voice/use-dictation.ts +11 -8
  760. package/src/voice/voice-state.ts +57 -0
  761. package/src/voice/voice-store.ts +11 -55
@@ -1,7 +1,7 @@
1
- import { useEffect, useState } from "react";
2
- import { AlertTriangle, Check, Loader2, X } from "lucide-react";
3
- import { api, type WebSearchConfig, type WebSearchProvider } from "../../lib/api-client.js";
4
- import { cn } from "../../lib/utils.js";
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+ import type { WebSearchConfig } from "../../lib/api-client.js";
3
+ import { useBrainUiRoot } from "../../root-context.js";
4
+ import { WebSearchChain } from "./web-search-chain.js";
5
5
 
6
6
  /**
7
7
  * Web-search provider settings for the pi backend's web extension
@@ -13,15 +13,16 @@ import { cn } from "../../lib/utils.js";
13
13
  * same list and can name a specific provider per search when a question
14
14
  * warrants it.
15
15
  *
16
- * Enabling a provider that has no credential is blocked in the UI rather than
17
- * bounced by the server: the extension would skip it at search time anyway,
18
- * leaving a chain entry that silently never runs.
19
- *
20
- * Key values never come back from the server; the UI only ever learns "a key
21
- * is stored". Renders nothing when the server reports pi as not configured,
22
- * so the Models tab is unchanged for Claude-only deployments.
16
+ * This is the container (S6): it owns the load, the update round-trip, the
17
+ * per-root lifetime guards and the "saved" flash, and hands everything on
18
+ * screen to `WebSearchChain`. Renders nothing when the server reports pi as
19
+ * not configured, so the Models tab is unchanged for Claude-only deployments.
23
20
  */
24
21
  export function WebSearchSection({ active }: { active: boolean }) {
22
+ const root = useBrainUiRoot();
23
+ const api = root.api;
24
+ const lifetime = useRef(0);
25
+ const flashTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
25
26
  const [config, setConfig] = useState<WebSearchConfig | null>(null);
26
27
  const [error, setError] = useState<string | null>(null);
27
28
  const [busy, setBusy] = useState(false);
@@ -29,354 +30,83 @@ export function WebSearchSection({ active }: { active: boolean }) {
29
30
  const [keyDraft, setKeyDraft] = useState("");
30
31
  const [savedFlash, setSavedFlash] = useState(false);
31
32
 
32
- async function reload() {
33
+ const reload = useCallback(async () => {
34
+ const generation = lifetime.current;
33
35
  try {
34
36
  const next = await api.webSearchConfig();
37
+ if (generation !== lifetime.current) return;
35
38
  setConfig(next);
36
39
  setError(null);
37
40
  } catch (err) {
38
- setError(err instanceof Error ? err.message : "Could not load web-search settings");
41
+ if (generation === lifetime.current) setError(err instanceof Error ? err.message : "Could not load web-search settings");
39
42
  }
40
- }
43
+ }, [api]);
41
44
 
42
45
  useEffect(() => {
46
+ lifetime.current++;
47
+ setConfig(null);
48
+ setError(null);
49
+ setBusy(false);
50
+ setOpenKey(null);
51
+ setKeyDraft("");
52
+ setSavedFlash(false);
43
53
  if (active) void reload();
44
- }, [active]);
54
+ const invalidate = () => {
55
+ lifetime.current++;
56
+ if (flashTimer.current !== null) clearTimeout(flashTimer.current);
57
+ };
58
+ return invalidate;
59
+ }, [active, root, reload]);
45
60
 
46
61
  async function update(change: {
47
62
  enabled?: Record<string, boolean>;
48
63
  apiKeys?: Record<string, string | null>;
49
64
  clearOverride?: boolean;
50
65
  }) {
66
+ const generation = lifetime.current;
51
67
  setBusy(true);
52
68
  setError(null);
53
69
  try {
54
70
  const next = await api.webSearchUpdate(change);
71
+ if (generation !== lifetime.current) return;
55
72
  setConfig(next);
56
73
  if (change.apiKeys) {
57
74
  setKeyDraft("");
58
75
  setSavedFlash(true);
59
- setTimeout(() => setSavedFlash(false), 2000);
76
+ if (flashTimer.current !== null) clearTimeout(flashTimer.current);
77
+ flashTimer.current = setTimeout(() => {
78
+ if (generation === lifetime.current) setSavedFlash(false);
79
+ }, 2000);
60
80
  }
61
81
  } catch (err) {
62
- setError(err instanceof Error ? err.message : "Could not save web-search settings");
82
+ if (generation === lifetime.current) setError(err instanceof Error ? err.message : "Could not save web-search settings");
63
83
  } finally {
64
- setBusy(false);
84
+ if (generation === lifetime.current) setBusy(false);
65
85
  }
66
86
  }
67
87
 
68
88
  if (!config || !config.configured) return null;
69
89
 
70
- const byId = new Map(config.providers.map((p) => [p.id, p]));
71
- const orderLabels = config.order.map((id) => byId.get(id)?.label ?? id);
72
-
73
- return (
74
- <div className="mt-6">
75
- <h3 className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
76
- Web search
77
- </h3>
78
- <p className="mt-1 text-xs text-muted-foreground">
79
- Enable the providers this deployment may use. Searches run them
80
- cheapest-first and only fall through to the next when one fails, so a
81
- paid provider costs nothing until it is actually needed. The agent is
82
- told which are enabled and can pick one deliberately. Changes apply to
83
- new conversations.
84
- </p>
85
- <AppliesTo models={config.appliesTo} />
86
-
87
- <div className="mt-4 rounded-lg border border-border-subtle bg-surface p-3">
88
- {config.overriddenBy && (
89
- <OverrideWarning
90
- provider={config.overriddenBy}
91
- busy={busy}
92
- onClear={() => void update({ clearOverride: true })}
93
- />
94
- )}
95
-
96
- <p className="text-[11px] text-muted-foreground">
97
- {orderLabels.length > 0 ? (
98
- <>
99
- <span className="text-foreground">Order:</span>{" "}
100
- {orderLabels.join(" → ")}
101
- </>
102
- ) : (
103
- "Nothing enabled — the extension picks for itself, starting with a free rate-limited tier."
104
- )}
105
- </p>
106
-
107
- <ul className="mt-3 space-y-1.5">
108
- {config.providers.map((p) => (
109
- <ProviderRow
110
- key={p.id}
111
- provider={p}
112
- busy={busy}
113
- keyOpen={openKey === p.id}
114
- keyDraft={keyDraft}
115
- setKeyDraft={setKeyDraft}
116
- savedFlash={savedFlash}
117
- onToggleKey={() => {
118
- setKeyDraft("");
119
- setOpenKey(openKey === p.id ? null : p.id);
120
- }}
121
- onToggle={() => void update({ enabled: { [p.id]: !p.enabled } })}
122
- onSaveKey={() => void update({ apiKeys: { [p.id]: keyDraft } })}
123
- onClearKey={() => void update({ apiKeys: { [p.id]: null } })}
124
- />
125
- ))}
126
- </ul>
127
-
128
- {error && <p className="mt-2 text-xs text-destructive">{error}</p>}
129
- </div>
130
- </div>
131
- );
132
- }
133
-
134
- /**
135
- * Which models these toggles actually reach.
136
- *
137
- * The card is shown whenever the pi backend is configured, but a deployment
138
- * running both backends puts Claude models in the same picker — and those use
139
- * the Agent SDK's Anthropic-hosted WebSearch, which takes no provider setting.
140
- * Without this line the toggles look global and silently are not.
141
- */
142
- function AppliesTo({ models }: { models: string[] }) {
143
90
  return (
144
- <p className="mt-2 text-xs text-muted-foreground">
145
- Applies to{" "}
146
- <span className="text-foreground">
147
- {models.length > 0 ? models.join(", ") : "the pi models"}
148
- </span>
149
- . Claude models search through Anthropic instead, which has no provider
150
- setting.
151
- </p>
152
- );
153
- }
154
-
155
- /**
156
- * A single-provider selection in the config file beats `searchRouting`
157
- * outright in the extension, and pi's own /curator command writes one back —
158
- * so a chain can be configured here and quietly not be what runs. Say so
159
- * instead of showing toggles that lie.
160
- */
161
- function OverrideWarning({
162
- provider,
163
- busy,
164
- onClear,
165
- }: {
166
- provider: string;
167
- busy: boolean;
168
- onClear: () => void;
169
- }) {
170
- return (
171
- <div className="mb-3 flex items-start gap-2 rounded-md border border-primary/40 bg-primary/10 p-2">
172
- <AlertTriangle className="mt-0.5 h-3.5 w-3.5 shrink-0 text-primary" />
173
- <div className="min-w-0 flex-1">
174
- <p className="text-[11px] text-foreground">
175
- Searches are pinned to <span className="font-medium">{provider}</span>,
176
- which overrides the chain below. pi's own <code>/curator</code> command
177
- sets this.
178
- </p>
179
- <button
180
- onClick={onClear}
181
- disabled={busy}
182
- className="mt-1 rounded-md border border-border-subtle px-2 py-1 text-[11px] font-medium text-foreground transition-colors hover:border-primary hover:text-primary disabled:opacity-50"
183
- >
184
- Use the chain instead
185
- </button>
186
- </div>
187
- </div>
188
- );
189
- }
190
-
191
- function ProviderRow({
192
- provider,
193
- busy,
194
- keyOpen,
195
- keyDraft,
196
- setKeyDraft,
197
- savedFlash,
198
- onToggle,
199
- onToggleKey,
200
- onSaveKey,
201
- onClearKey,
202
- }: {
203
- provider: WebSearchProvider;
204
- busy: boolean;
205
- keyOpen: boolean;
206
- keyDraft: string;
207
- setKeyDraft: (value: string) => void;
208
- savedFlash: boolean;
209
- onToggle: () => void;
210
- onToggleKey: () => void;
211
- onSaveKey: () => void;
212
- onClearKey: () => void;
213
- }) {
214
- const hasCredential = provider.keyless || provider.keyConfigured || provider.keyFromEnv;
215
- return (
216
- <li className="rounded-lg border border-border-subtle bg-background p-2.5">
217
- {/* The switch sits in its own column; the label row carries the key chip,
218
- so the cost note and blurb below get the full width instead of a
219
- squeezed few characters. */}
220
- <div className="flex items-start gap-3">
221
- <Switch
222
- // A provider that lost its key must still be switchable OFF —
223
- // only turning one ON without a credential is blocked.
224
- checked={provider.enabled}
225
- disabled={busy || (!provider.enabled && !hasCredential)}
226
- label={provider.label}
227
- onToggle={onToggle}
228
- />
229
- <div className="min-w-0 flex-1">
230
- <div className="flex items-start justify-between gap-2">
231
- <p className="text-sm text-foreground">{provider.label}</p>
232
- {provider.hasKeyField && (
233
- <button
234
- onClick={onToggleKey}
235
- aria-expanded={keyOpen}
236
- className={cn(
237
- "shrink-0 rounded-md border px-2 py-1 text-[11px] font-medium transition-colors",
238
- provider.keyConfigured
239
- ? "border-border-subtle text-primary hover:border-primary"
240
- : hasCredential
241
- ? "border-border-subtle text-muted-foreground hover:border-primary hover:text-foreground"
242
- : "border-dashed border-border text-muted-foreground hover:border-primary hover:text-primary"
243
- )}
244
- >
245
- {provider.keyConfigured
246
- ? "Key stored"
247
- : provider.keyFromEnv
248
- ? "Key from env"
249
- : "Needs key"}
250
- </button>
251
- )}
252
- </div>
253
- {/* Not truncated: in a narrow settings panel a clipped "Paid —
254
- metered p…" tells the reader nothing, and the blurb is the whole
255
- reason to prefer one provider over another. */}
256
- <p className="text-[11px] text-muted-foreground">{provider.costNote}</p>
257
- <p className="text-[11px] text-muted-foreground/70">{provider.blurb}</p>
258
- </div>
259
- </div>
260
-
261
- {keyOpen && provider.hasKeyField && (
262
- <div className="mt-2">
263
- {provider.keyFromEnv && !provider.keyConfigured && (
264
- <p className="mb-1 text-[11px] text-muted-foreground">
265
- A key is already coming from the environment. One saved here
266
- takes its place.
267
- </p>
268
- )}
269
- {provider.keyless && !provider.keyConfigured && (
270
- <p className="mb-1 text-[11px] text-muted-foreground">
271
- Optional — the free tier works without one, a key lifts its rate
272
- limit.
273
- </p>
274
- )}
275
- <KeyEditor
276
- busy={busy}
277
- draft={keyDraft}
278
- setDraft={setKeyDraft}
279
- keyConfigured={provider.keyConfigured}
280
- savedFlash={savedFlash}
281
- onSave={onSaveKey}
282
- onClear={onClearKey}
283
- />
284
- </div>
285
- )}
286
- </li>
287
- );
288
- }
289
-
290
- function Switch({
291
- checked,
292
- disabled,
293
- label,
294
- onToggle,
295
- }: {
296
- checked: boolean;
297
- disabled: boolean;
298
- label: string;
299
- onToggle: () => void;
300
- }) {
301
- return (
302
- <button
303
- role="switch"
304
- aria-checked={checked}
305
- aria-label={`Enable ${label} for web search`}
306
- disabled={disabled}
307
- onClick={onToggle}
308
- title={disabled && !checked ? `${label} needs an API key first` : undefined}
309
- className={cn(
310
- "relative mt-0.5 h-5 w-9 shrink-0 rounded-full border transition-colors disabled:opacity-40",
311
- checked ? "border-primary bg-primary" : "border-border-subtle bg-surface-raised"
312
- )}
313
- >
314
- <span
315
- // left-0 is load-bearing: without it the knob lays out at its static
316
- // position (the track's right edge) and the translate pushes it clean
317
- // out of the pill.
318
- className={cn(
319
- "absolute left-0 top-0.5 h-3.5 w-3.5 rounded-full bg-background transition-transform",
320
- checked ? "translate-x-[18px]" : "translate-x-0.5"
321
- )}
322
- />
323
- </button>
324
- );
325
- }
326
-
327
- function KeyEditor({
328
- busy,
329
- draft,
330
- setDraft,
331
- keyConfigured,
332
- savedFlash,
333
- onSave,
334
- onClear,
335
- }: {
336
- busy: boolean;
337
- draft: string;
338
- setDraft: (value: string) => void;
339
- keyConfigured: boolean;
340
- savedFlash: boolean;
341
- onSave: () => void;
342
- onClear: () => void;
343
- }) {
344
- return (
345
- <div className="flex items-center gap-2">
346
- <input
347
- type="password"
348
- value={draft}
349
- disabled={busy}
350
- placeholder={keyConfigured ? "•••••••• (stored — enter to replace)" : "Paste API key"}
351
- onChange={(e) => setDraft(e.target.value)}
352
- onKeyDown={(e) => {
353
- if (e.key === "Enter" && draft.trim()) onSave();
354
- }}
355
- autoComplete="off"
356
- className="min-w-0 flex-1 rounded-md border border-border-subtle bg-background px-2 py-1.5 text-sm text-foreground placeholder:text-muted-foreground focus:border-primary focus:outline-none disabled:opacity-50"
357
- />
358
- <button
359
- onClick={onSave}
360
- disabled={busy || !draft.trim()}
361
- className={cn(
362
- "flex items-center gap-1 rounded-md border border-border-subtle px-2.5 py-1.5 text-xs font-medium transition-colors",
363
- "text-foreground hover:border-primary hover:text-primary disabled:opacity-50"
364
- )}
365
- >
366
- {busy ? <Loader2 className="h-3 w-3 animate-spin" /> : savedFlash ? <Check className="h-3 w-3" /> : null}
367
- Save
368
- </button>
369
- {keyConfigured && (
370
- <button
371
- onClick={onClear}
372
- disabled={busy}
373
- title="Remove the stored key"
374
- className="flex items-center gap-1 rounded-md border border-border-subtle px-2.5 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:border-destructive hover:text-destructive disabled:opacity-50"
375
- >
376
- <X className="h-3 w-3" />
377
- Clear
378
- </button>
379
- )}
380
- </div>
91
+ <WebSearchChain
92
+ config={config}
93
+ busy={busy}
94
+ error={error}
95
+ openKey={openKey}
96
+ keyDraft={keyDraft}
97
+ savedFlash={savedFlash}
98
+ onToggle={(id) => {
99
+ const provider = config.providers.find((p) => p.id === id);
100
+ if (provider) void update({ enabled: { [id]: !provider.enabled } });
101
+ }}
102
+ onToggleKey={(id) => {
103
+ setKeyDraft("");
104
+ setOpenKey(openKey === id ? null : id);
105
+ }}
106
+ onKeyDraft={setKeyDraft}
107
+ onSaveKey={(id) => void update({ apiKeys: { [id]: keyDraft } })}
108
+ onClearKey={(id) => void update({ apiKeys: { [id]: null } })}
109
+ onClearOverride={() => void update({ clearOverride: true })}
110
+ />
381
111
  );
382
112
  }
@@ -1,3 +1,4 @@
1
+ import { useBrainUiRoot } from "../../root-context.js";
1
2
  import { useEffect, useRef, useState } from "react";
2
3
  import { Share2, Loader2, Check, AlertCircle } from "lucide-react";
3
4
  import { cn } from "../../lib/utils.js";
@@ -33,11 +34,21 @@ interface ShareMenuProps {
33
34
  type Status = "idle" | "busy" | "done" | "error";
34
35
 
35
36
  export function ShareMenu({ options, title = "Share", className, renderTrigger }: ShareMenuProps) {
37
+ const root = useBrainUiRoot();
38
+ const lifetime = useRef(0);
39
+ const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
36
40
  const [open, setOpen] = useState(false);
37
41
  const [status, setStatus] = useState<Status>("idle");
38
42
  const [error, setError] = useState<string | null>(null);
39
43
  const wrapperRef = useRef<HTMLDivElement>(null);
40
44
 
45
+ useEffect(() => {
46
+ lifetime.current++;
47
+ setOpen(false); setStatus("idle"); setError(null);
48
+ const invalidate = () => { lifetime.current++; clearTimeout(timer.current); };
49
+ return invalidate;
50
+ }, [root]);
51
+
41
52
  useEffect(() => {
42
53
  if (!open) return;
43
54
  const onDocClick = (e: MouseEvent) => {
@@ -63,18 +74,22 @@ export function ShareMenu({ options, title = "Share", className, renderTrigger }
63
74
  const single = options.length === 1 ? options[0] : null;
64
75
 
65
76
  const runOption = async (opt: ShareOption) => {
77
+ const token = ++lifetime.current;
78
+ clearTimeout(timer.current);
66
79
  setOpen(false);
67
80
  setStatus("busy");
68
81
  setError(null);
69
82
  try {
70
- await opt.run();
71
- setStatus("done");
72
- setTimeout(() => setStatus("idle"), 1200);
83
+ const shared = await opt.run();
84
+ if (token !== lifetime.current) return;
85
+ setStatus(shared ? "done" : "idle");
86
+ timer.current = setTimeout(() => { if (token === lifetime.current) setStatus("idle"); }, 1200);
73
87
  } catch (err) {
88
+ if (token !== lifetime.current) return;
74
89
  console.error("[share-menu]", err);
75
90
  setError(err instanceof Error ? err.message : "Share failed");
76
91
  setStatus("error");
77
- setTimeout(() => setStatus("idle"), 3000);
92
+ timer.current = setTimeout(() => { if (token === lifetime.current) setStatus("idle"); }, 3000);
78
93
  }
79
94
  };
80
95
 
@@ -89,12 +89,12 @@ export function DictationSheet({
89
89
  {/* Pulse only once capture is actually live — a "connecting" dot
90
90
  must not imply the mic is already open. */}
91
91
  {!connecting && (
92
- <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-primary opacity-75" />
92
+ <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-primary-mark opacity-75" />
93
93
  )}
94
94
  <span
95
95
  className={cn(
96
96
  "relative inline-flex h-2 w-2 rounded-full",
97
- connecting ? "bg-muted-foreground/50" : "bg-primary"
97
+ connecting ? "bg-muted-foreground/50" : "bg-primary-mark"
98
98
  )}
99
99
  />
100
100
  </span>
@@ -135,7 +135,7 @@ export function DictationSheet({
135
135
  {/* Transcript */}
136
136
  <div ref={transcriptRef} className="flex-1 overflow-y-auto px-6 pb-6">
137
137
  {error ? (
138
- <div className="rounded-lg bg-destructive/10 p-4 text-sm text-destructive">
138
+ <div className="rounded-lg bg-destructive-fill/10 p-4 text-sm text-destructive">
139
139
  {error}
140
140
  </div>
141
141
  ) : (
@@ -160,7 +160,7 @@ export function DictationSheet({
160
160
  <button
161
161
  onClick={onStop}
162
162
  disabled={draining}
163
- className="flex h-14 w-full items-center justify-center gap-3 rounded-xl bg-primary text-primary-foreground transition-all duration-150 hover:brightness-110 active:scale-[0.99] disabled:opacity-60 disabled:cursor-progress"
163
+ className="flex h-14 w-full items-center justify-center gap-3 rounded-xl bg-primary-fill text-primary-foreground transition-all duration-150 hover:brightness-110 active:scale-[0.99] disabled:opacity-60 disabled:cursor-progress"
164
164
  >
165
165
  <Mic className="h-5 w-5" />
166
166
  <span className="text-sm font-semibold uppercase tracking-wider">
@@ -208,7 +208,7 @@ function Waveform({ level }: { level: number }) {
208
208
  <span
209
209
  key={i}
210
210
  style={{ height: `${h}px` }}
211
- className="w-1.5 rounded-full bg-primary transition-[height] duration-75 ease-linear"
211
+ className="w-1.5 rounded-full bg-primary-mark transition-[height] duration-75 ease-linear"
212
212
  />
213
213
  );
214
214
  })}
@@ -20,7 +20,7 @@ export function MicButton({
20
20
  className={cn(
21
21
  "flex h-8 w-8 items-center justify-center rounded-lg transition-all duration-150",
22
22
  active
23
- ? "bg-primary text-primary-foreground animate-pulse"
23
+ ? "bg-primary-fill text-primary-foreground animate-pulse"
24
24
  : "text-muted-foreground hover:bg-surface-raised hover:text-foreground",
25
25
  disabled && "opacity-30 cursor-not-allowed"
26
26
  )}
@@ -55,7 +55,7 @@ export function ReviewCard({
55
55
  <button
56
56
  type="button"
57
57
  onClick={onSend}
58
- className="flex h-10 items-center gap-2 rounded-xl bg-primary px-5 text-sm font-semibold text-primary-foreground transition-all duration-150 hover:brightness-110 active:scale-[0.98]"
58
+ className="flex h-10 items-center gap-2 rounded-xl bg-primary-fill px-5 text-sm font-semibold text-primary-foreground transition-all duration-150 hover:brightness-110 active:scale-[0.98]"
59
59
  >
60
60
  <Send className="h-4 w-4" />
61
61
  Send
package/src/config.ts CHANGED
@@ -14,8 +14,9 @@
14
14
  * `scripts/check-env-access.ts` now refuses `import.meta.env` anywhere in a
15
15
  * package's `src`, so the loophole cannot reopen.
16
16
  *
17
- * Values are a module-level singleton, matching the renderer/ASR registries.
18
- * Runtime plugin-style reconfiguration is deliberately unsupported.
17
+ * `createBrainUiConfig` makes independent configurations for UI roots. The
18
+ * existing `uiConfig` remains the application's default until root migration
19
+ * is complete. Runtime plugin-style reconfiguration is unsupported.
19
20
  */
20
21
  export interface BrainUiConfig {
21
22
  /** Product name shown on the login screen and connection status. */
@@ -46,7 +47,7 @@ export interface BrainUiConfig {
46
47
  devTools: boolean;
47
48
  }
48
49
 
49
- export const uiConfig: BrainUiConfig = {
50
+ const DEFAULT_CONFIG: Readonly<BrainUiConfig> = {
50
51
  appName: "Brain UI",
51
52
  assistantName: "Brain",
52
53
  shareTitle: "Shared from Brain",
@@ -55,6 +56,22 @@ export const uiConfig: BrainUiConfig = {
55
56
  devTools: false,
56
57
  };
57
58
 
59
+ /** Fresh values for one UI root; never reads or mutates the default instance. */
60
+ export function createBrainUiConfig(overrides: Partial<BrainUiConfig> = {}): BrainUiConfig {
61
+ const config = { ...DEFAULT_CONFIG };
62
+ applyConfig(config, overrides);
63
+ return config;
64
+ }
65
+
66
+ function applyConfig(config: BrainUiConfig, overrides: Partial<BrainUiConfig>): void {
67
+ Object.assign(config, overrides);
68
+ if (typeof overrides.backendUrl === "string") {
69
+ config.backendUrl = overrides.backendUrl.replace(/\/$/, "");
70
+ }
71
+ }
72
+
73
+ export const uiConfig = createBrainUiConfig();
74
+
58
75
  /**
59
76
  * Dev-handle installers, registered at module scope by the stores that own a
60
77
  * handle. They cannot read `uiConfig.devTools` themselves: ES imports are
@@ -78,9 +95,6 @@ export function registerDevHandle(install: () => void): void {
78
95
  }
79
96
 
80
97
  export function configureBrainUi(overrides: Partial<BrainUiConfig>): void {
81
- Object.assign(uiConfig, overrides);
82
- if (typeof overrides.backendUrl === "string") {
83
- uiConfig.backendUrl = overrides.backendUrl.replace(/\/$/, "");
84
- }
98
+ applyConfig(uiConfig, overrides);
85
99
  if (uiConfig.devTools) installDevHandles();
86
100
  }