@schlessera/brain-ui-react 0.34.1 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (763) hide show
  1. package/README.md +89 -4
  2. package/dist/components/activity/activity-page.d.ts +17 -5
  3. package/dist/components/activity/activity-page.d.ts.map +1 -1
  4. package/dist/components/activity/activity-page.js +144 -50
  5. package/dist/components/activity/activity-page.js.map +1 -1
  6. package/dist/components/activity/activity-run-detail.d.ts +16 -1
  7. package/dist/components/activity/activity-run-detail.d.ts.map +1 -1
  8. package/dist/components/activity/activity-run-detail.js +47 -4
  9. package/dist/components/activity/activity-run-detail.js.map +1 -1
  10. package/dist/components/activity/activity-run-list.d.ts +7 -1
  11. package/dist/components/activity/activity-run-list.d.ts.map +1 -1
  12. package/dist/components/activity/activity-run-list.js +16 -8
  13. package/dist/components/activity/activity-run-list.js.map +1 -1
  14. package/dist/components/activity/activity-views.d.ts +63 -0
  15. package/dist/components/activity/activity-views.d.ts.map +1 -0
  16. package/dist/components/activity/activity-views.js +52 -0
  17. package/dist/components/activity/activity-views.js.map +1 -0
  18. package/dist/components/activity/approval-card.d.ts +11 -0
  19. package/dist/components/activity/approval-card.d.ts.map +1 -0
  20. package/dist/components/activity/approval-card.js +46 -0
  21. package/dist/components/activity/approval-card.js.map +1 -0
  22. package/dist/components/activity/digest-card.d.ts +3 -0
  23. package/dist/components/activity/digest-card.d.ts.map +1 -1
  24. package/dist/components/activity/digest-card.js +20 -16
  25. package/dist/components/activity/digest-card.js.map +1 -1
  26. package/dist/components/activity/digest-summary.d.ts +19 -0
  27. package/dist/components/activity/digest-summary.d.ts.map +1 -0
  28. package/dist/components/activity/digest-summary.js +20 -0
  29. package/dist/components/activity/digest-summary.js.map +1 -0
  30. package/dist/components/activity/push-switch.d.ts +25 -0
  31. package/dist/components/activity/push-switch.d.ts.map +1 -0
  32. package/dist/components/activity/push-switch.js +14 -0
  33. package/dist/components/activity/push-switch.js.map +1 -0
  34. package/dist/components/activity/push-toggle.d.ts +7 -0
  35. package/dist/components/activity/push-toggle.d.ts.map +1 -1
  36. package/dist/components/activity/push-toggle.js +72 -47
  37. package/dist/components/activity/push-toggle.js.map +1 -1
  38. package/dist/components/activity/span-bits.d.ts.map +1 -1
  39. package/dist/components/activity/span-bits.js +9 -7
  40. package/dist/components/activity/span-bits.js.map +1 -1
  41. package/dist/components/chat/ask-user-card.d.ts +76 -3
  42. package/dist/components/chat/ask-user-card.d.ts.map +1 -1
  43. package/dist/components/chat/ask-user-card.js +208 -149
  44. package/dist/components/chat/ask-user-card.js.map +1 -1
  45. package/dist/components/chat/ask-user-typed.d.ts +42 -0
  46. package/dist/components/chat/ask-user-typed.d.ts.map +1 -0
  47. package/dist/components/chat/ask-user-typed.js +60 -0
  48. package/dist/components/chat/ask-user-typed.js.map +1 -0
  49. package/dist/components/chat/brain-markdown-links.d.ts +2 -1
  50. package/dist/components/chat/brain-markdown-links.d.ts.map +1 -1
  51. package/dist/components/chat/brain-markdown-links.js +3 -4
  52. package/dist/components/chat/brain-markdown-links.js.map +1 -1
  53. package/dist/components/chat/brain-markdown.d.ts.map +1 -1
  54. package/dist/components/chat/brain-markdown.js +4 -2
  55. package/dist/components/chat/brain-markdown.js.map +1 -1
  56. package/dist/components/chat/chat-page.d.ts.map +1 -1
  57. package/dist/components/chat/chat-page.js +24 -9
  58. package/dist/components/chat/chat-page.js.map +1 -1
  59. package/dist/components/chat/composer-view.d.ts +75 -0
  60. package/dist/components/chat/composer-view.d.ts.map +1 -0
  61. package/dist/components/chat/composer-view.js +31 -0
  62. package/dist/components/chat/composer-view.js.map +1 -0
  63. package/dist/components/chat/composer.d.ts +4 -0
  64. package/dist/components/chat/composer.d.ts.map +1 -1
  65. package/dist/components/chat/composer.js +76 -59
  66. package/dist/components/chat/composer.js.map +1 -1
  67. package/dist/components/chat/markdown-content.d.ts +16 -1
  68. package/dist/components/chat/markdown-content.d.ts.map +1 -1
  69. package/dist/components/chat/markdown-content.js +47 -3
  70. package/dist/components/chat/markdown-content.js.map +1 -1
  71. package/dist/components/chat/mermaid-block.d.ts +4 -0
  72. package/dist/components/chat/mermaid-block.d.ts.map +1 -1
  73. package/dist/components/chat/mermaid-block.js +13 -5
  74. package/dist/components/chat/mermaid-block.js.map +1 -1
  75. package/dist/components/chat/mermaid-share.d.ts +2 -1
  76. package/dist/components/chat/mermaid-share.d.ts.map +1 -1
  77. package/dist/components/chat/mermaid-share.js +7 -8
  78. package/dist/components/chat/mermaid-share.js.map +1 -1
  79. package/dist/components/chat/mermaid-viewer.d.ts.map +1 -1
  80. package/dist/components/chat/mermaid-viewer.js +3 -1
  81. package/dist/components/chat/mermaid-viewer.js.map +1 -1
  82. package/dist/components/chat/message-bubble.d.ts +8 -1
  83. package/dist/components/chat/message-bubble.d.ts.map +1 -1
  84. package/dist/components/chat/message-bubble.js +53 -24
  85. package/dist/components/chat/message-bubble.js.map +1 -1
  86. package/dist/components/chat/message-share.d.ts +2 -1
  87. package/dist/components/chat/message-share.d.ts.map +1 -1
  88. package/dist/components/chat/message-share.js +6 -7
  89. package/dist/components/chat/message-share.js.map +1 -1
  90. package/dist/components/chat/renderers/bind.d.ts +39 -0
  91. package/dist/components/chat/renderers/bind.d.ts.map +1 -0
  92. package/dist/components/chat/renderers/bind.js +43 -0
  93. package/dist/components/chat/renderers/bind.js.map +1 -0
  94. package/dist/components/chat/renderers/brain-ui-tools.d.ts +3 -0
  95. package/dist/components/chat/renderers/brain-ui-tools.d.ts.map +1 -0
  96. package/dist/components/chat/renderers/brain-ui-tools.js +41 -0
  97. package/dist/components/chat/renderers/brain-ui-tools.js.map +1 -0
  98. package/dist/components/chat/renderers/claude-tools.d.ts.map +1 -1
  99. package/dist/components/chat/renderers/claude-tools.js +3 -2
  100. package/dist/components/chat/renderers/claude-tools.js.map +1 -1
  101. package/dist/components/chat/renderers/index.d.ts +10 -2
  102. package/dist/components/chat/renderers/index.d.ts.map +1 -1
  103. package/dist/components/chat/renderers/index.js +15 -10
  104. package/dist/components/chat/renderers/index.js.map +1 -1
  105. package/dist/components/chat/session-drawer.d.ts +4 -0
  106. package/dist/components/chat/session-drawer.d.ts.map +1 -1
  107. package/dist/components/chat/session-drawer.js +55 -40
  108. package/dist/components/chat/session-drawer.js.map +1 -1
  109. package/dist/components/chat/session-list.d.ts +41 -0
  110. package/dist/components/chat/session-list.d.ts.map +1 -0
  111. package/dist/components/chat/session-list.js +10 -0
  112. package/dist/components/chat/session-list.js.map +1 -0
  113. package/dist/components/chat/share-block.d.ts.map +1 -1
  114. package/dist/components/chat/share-block.js +12 -11
  115. package/dist/components/chat/share-block.js.map +1 -1
  116. package/dist/components/chat/share-card.js +2 -2
  117. package/dist/components/chat/share-card.js.map +1 -1
  118. package/dist/components/chat/subagent-view.js +1 -1
  119. package/dist/components/chat/subagent-view.js.map +1 -1
  120. package/dist/components/chat/tool-call-timeline.d.ts.map +1 -1
  121. package/dist/components/chat/tool-call-timeline.js +37 -12
  122. package/dist/components/chat/tool-call-timeline.js.map +1 -1
  123. package/dist/components/chat/tool-cards/block-card.d.ts +28 -0
  124. package/dist/components/chat/tool-cards/block-card.d.ts.map +1 -0
  125. package/dist/components/chat/tool-cards/block-card.js +103 -0
  126. package/dist/components/chat/tool-cards/block-card.js.map +1 -0
  127. package/dist/components/chat/tool-cards/image-mask-card.d.ts +70 -0
  128. package/dist/components/chat/tool-cards/image-mask-card.d.ts.map +1 -0
  129. package/dist/components/chat/tool-cards/image-mask-card.js +142 -0
  130. package/dist/components/chat/tool-cards/image-mask-card.js.map +1 -0
  131. package/dist/components/chat/tool-cards/location-card.d.ts +45 -0
  132. package/dist/components/chat/tool-cards/location-card.d.ts.map +1 -0
  133. package/dist/components/chat/tool-cards/location-card.js +128 -0
  134. package/dist/components/chat/tool-cards/location-card.js.map +1 -0
  135. package/dist/components/chat/tool-views.d.ts +15 -4
  136. package/dist/components/chat/tool-views.d.ts.map +1 -1
  137. package/dist/components/chat/tool-views.js +22 -38
  138. package/dist/components/chat/tool-views.js.map +1 -1
  139. package/dist/components/chat/transcript-turn.d.ts +45 -0
  140. package/dist/components/chat/transcript-turn.d.ts.map +1 -0
  141. package/dist/components/chat/transcript-turn.js +25 -0
  142. package/dist/components/chat/transcript-turn.js.map +1 -0
  143. package/dist/components/chat/use-chat-commands.d.ts.map +1 -1
  144. package/dist/components/chat/use-chat-commands.js +13 -16
  145. package/dist/components/chat/use-chat-commands.js.map +1 -1
  146. package/dist/components/chat/welcome-state.d.ts +7 -0
  147. package/dist/components/chat/welcome-state.d.ts.map +1 -1
  148. package/dist/components/chat/welcome-state.js +13 -5
  149. package/dist/components/chat/welcome-state.js.map +1 -1
  150. package/dist/components/connectivity/connection-gate.d.ts.map +1 -1
  151. package/dist/components/connectivity/connection-gate.js +64 -6
  152. package/dist/components/connectivity/connection-gate.js.map +1 -1
  153. package/dist/components/connectivity/login-form.d.ts +31 -0
  154. package/dist/components/connectivity/login-form.d.ts.map +1 -0
  155. package/dist/components/connectivity/login-form.js +19 -0
  156. package/dist/components/connectivity/login-form.js.map +1 -0
  157. package/dist/components/connectivity/login-screen.d.ts +5 -2
  158. package/dist/components/connectivity/login-screen.d.ts.map +1 -1
  159. package/dist/components/connectivity/login-screen.js +41 -31
  160. package/dist/components/connectivity/login-screen.js.map +1 -1
  161. package/dist/components/dev/share-harness.js +1 -1
  162. package/dist/components/dev/share-harness.js.map +1 -1
  163. package/dist/components/files/file-panel.d.ts +1 -1
  164. package/dist/components/files/file-panel.d.ts.map +1 -1
  165. package/dist/components/files/file-panel.js +74 -0
  166. package/dist/components/files/file-panel.js.map +1 -1
  167. package/dist/components/files/file-tree-view.d.ts +45 -0
  168. package/dist/components/files/file-tree-view.d.ts.map +1 -0
  169. package/dist/components/files/file-tree-view.js +51 -0
  170. package/dist/components/files/file-tree-view.js.map +1 -0
  171. package/dist/components/files/file-tree.d.ts +6 -0
  172. package/dist/components/files/file-tree.d.ts.map +1 -1
  173. package/dist/components/files/file-tree.js +39 -43
  174. package/dist/components/files/file-tree.js.map +1 -1
  175. package/dist/components/files/file-viewer-binary.d.ts.map +1 -1
  176. package/dist/components/files/file-viewer-binary.js +3 -2
  177. package/dist/components/files/file-viewer-binary.js.map +1 -1
  178. package/dist/components/files/file-viewer-frame.d.ts +36 -0
  179. package/dist/components/files/file-viewer-frame.d.ts.map +1 -0
  180. package/dist/components/files/file-viewer-frame.js +26 -0
  181. package/dist/components/files/file-viewer-frame.js.map +1 -0
  182. package/dist/components/files/file-viewer.d.ts +5 -0
  183. package/dist/components/files/file-viewer.d.ts.map +1 -1
  184. package/dist/components/files/file-viewer.js +26 -32
  185. package/dist/components/files/file-viewer.js.map +1 -1
  186. package/dist/components/files/frontmatter-chips.d.ts +18 -0
  187. package/dist/components/files/frontmatter-chips.d.ts.map +1 -0
  188. package/dist/components/files/frontmatter-chips.js +11 -0
  189. package/dist/components/files/frontmatter-chips.js.map +1 -0
  190. package/dist/components/files/frontmatter-panel.d.ts +5 -1
  191. package/dist/components/files/frontmatter-panel.d.ts.map +1 -1
  192. package/dist/components/files/frontmatter-panel.js +7 -6
  193. package/dist/components/files/frontmatter-panel.js.map +1 -1
  194. package/dist/components/files/staleness.d.ts +18 -0
  195. package/dist/components/files/staleness.d.ts.map +1 -0
  196. package/dist/components/files/staleness.js +27 -0
  197. package/dist/components/files/staleness.js.map +1 -0
  198. package/dist/components/graph/graph-canvas.d.ts.map +1 -1
  199. package/dist/components/graph/graph-canvas.js +24 -1
  200. package/dist/components/graph/graph-canvas.js.map +1 -1
  201. package/dist/components/graph/graph-controls-column.d.ts +14 -0
  202. package/dist/components/graph/graph-controls-column.d.ts.map +1 -0
  203. package/dist/components/graph/graph-controls-column.js +44 -0
  204. package/dist/components/graph/graph-controls-column.js.map +1 -0
  205. package/dist/components/graph/graph-controls.d.ts +20 -5
  206. package/dist/components/graph/graph-controls.d.ts.map +1 -1
  207. package/dist/components/graph/graph-controls.js +58 -37
  208. package/dist/components/graph/graph-controls.js.map +1 -1
  209. package/dist/components/graph/graph-form.d.ts +82 -0
  210. package/dist/components/graph/graph-form.d.ts.map +1 -0
  211. package/dist/components/graph/graph-form.js +69 -0
  212. package/dist/components/graph/graph-form.js.map +1 -0
  213. package/dist/components/graph/graph-maintenance.d.ts.map +1 -1
  214. package/dist/components/graph/graph-maintenance.js +6 -10
  215. package/dist/components/graph/graph-maintenance.js.map +1 -1
  216. package/dist/components/graph/graph-node-rail.d.ts +13 -0
  217. package/dist/components/graph/graph-node-rail.d.ts.map +1 -0
  218. package/dist/components/graph/graph-node-rail.js +92 -0
  219. package/dist/components/graph/graph-node-rail.js.map +1 -0
  220. package/dist/components/graph/graph-page.d.ts +7 -0
  221. package/dist/components/graph/graph-page.d.ts.map +1 -1
  222. package/dist/components/graph/graph-page.js +102 -12
  223. package/dist/components/graph/graph-page.js.map +1 -1
  224. package/dist/components/graph/graph-scene.d.ts.map +1 -1
  225. package/dist/components/graph/graph-scene.js +100 -24
  226. package/dist/components/graph/graph-scene.js.map +1 -1
  227. package/dist/components/graph/lib/graph-helpers.d.ts +42 -12
  228. package/dist/components/graph/lib/graph-helpers.d.ts.map +1 -1
  229. package/dist/components/graph/lib/graph-helpers.js +33 -41
  230. package/dist/components/graph/lib/graph-helpers.js.map +1 -1
  231. package/dist/components/graph/node-card.d.ts +28 -0
  232. package/dist/components/graph/node-card.d.ts.map +1 -0
  233. package/dist/components/graph/node-card.js +7 -0
  234. package/dist/components/graph/node-card.js.map +1 -0
  235. package/dist/components/graph/node-popover.d.ts +6 -2
  236. package/dist/components/graph/node-popover.d.ts.map +1 -1
  237. package/dist/components/graph/node-popover.js +13 -31
  238. package/dist/components/graph/node-popover.js.map +1 -1
  239. package/dist/components/graph/use-graph-theme.d.ts +32 -4
  240. package/dist/components/graph/use-graph-theme.d.ts.map +1 -1
  241. package/dist/components/graph/use-graph-theme.js +44 -32
  242. package/dist/components/graph/use-graph-theme.js.map +1 -1
  243. package/dist/components/graph/use-node-actions.d.ts +26 -0
  244. package/dist/components/graph/use-node-actions.d.ts.map +1 -0
  245. package/dist/components/graph/use-node-actions.js +54 -0
  246. package/dist/components/graph/use-node-actions.js.map +1 -0
  247. package/dist/components/images/image-share.d.ts +2 -1
  248. package/dist/components/images/image-share.d.ts.map +1 -1
  249. package/dist/components/images/image-share.js +3 -3
  250. package/dist/components/images/image-share.js.map +1 -1
  251. package/dist/components/images/image-viewer.d.ts.map +1 -1
  252. package/dist/components/images/image-viewer.js +3 -1
  253. package/dist/components/images/image-viewer.js.map +1 -1
  254. package/dist/components/images/mask-editor.d.ts.map +1 -1
  255. package/dist/components/images/mask-editor.js +7 -5
  256. package/dist/components/images/mask-editor.js.map +1 -1
  257. package/dist/components/layout/app-shell.d.ts.map +1 -1
  258. package/dist/components/layout/app-shell.js +5 -1
  259. package/dist/components/layout/app-shell.js.map +1 -1
  260. package/dist/components/layout/desktop-palette.d.ts +23 -0
  261. package/dist/components/layout/desktop-palette.d.ts.map +1 -0
  262. package/dist/components/layout/desktop-palette.js +132 -0
  263. package/dist/components/layout/desktop-palette.js.map +1 -0
  264. package/dist/components/layout/key-cap.d.ts +9 -0
  265. package/dist/components/layout/key-cap.d.ts.map +1 -0
  266. package/dist/components/layout/key-cap.js +10 -0
  267. package/dist/components/layout/key-cap.js.map +1 -0
  268. package/dist/components/layout/mobile-tab-bar.d.ts +13 -0
  269. package/dist/components/layout/mobile-tab-bar.d.ts.map +1 -1
  270. package/dist/components/layout/mobile-tab-bar.js +58 -47
  271. package/dist/components/layout/mobile-tab-bar.js.map +1 -1
  272. package/dist/components/layout/shortcut-switch.d.ts +13 -0
  273. package/dist/components/layout/shortcut-switch.d.ts.map +1 -0
  274. package/dist/components/layout/shortcut-switch.js +22 -0
  275. package/dist/components/layout/shortcut-switch.js.map +1 -0
  276. package/dist/components/layout/side-rail.d.ts +24 -0
  277. package/dist/components/layout/side-rail.d.ts.map +1 -1
  278. package/dist/components/layout/side-rail.js +65 -27
  279. package/dist/components/layout/side-rail.js.map +1 -1
  280. package/dist/components/layout/slide-panel.d.ts +12 -2
  281. package/dist/components/layout/slide-panel.d.ts.map +1 -1
  282. package/dist/components/layout/slide-panel.js +11 -2
  283. package/dist/components/layout/slide-panel.js.map +1 -1
  284. package/dist/components/layout/theme.d.ts +22 -0
  285. package/dist/components/layout/theme.d.ts.map +1 -0
  286. package/dist/components/layout/theme.js +44 -0
  287. package/dist/components/layout/theme.js.map +1 -0
  288. package/dist/components/quick-actions/add-form.d.ts +44 -0
  289. package/dist/components/quick-actions/add-form.d.ts.map +1 -0
  290. package/dist/components/quick-actions/add-form.js +30 -0
  291. package/dist/components/quick-actions/add-form.js.map +1 -0
  292. package/dist/components/quick-actions/add-modal.d.ts +7 -0
  293. package/dist/components/quick-actions/add-modal.d.ts.map +1 -1
  294. package/dist/components/quick-actions/add-modal.js +66 -20
  295. package/dist/components/quick-actions/add-modal.js.map +1 -1
  296. package/dist/components/quick-actions/search-modal.d.ts.map +1 -1
  297. package/dist/components/quick-actions/search-modal.js +48 -19
  298. package/dist/components/quick-actions/search-modal.js.map +1 -1
  299. package/dist/components/quick-actions/streaming-modal.d.ts +6 -0
  300. package/dist/components/quick-actions/streaming-modal.d.ts.map +1 -1
  301. package/dist/components/quick-actions/streaming-modal.js +42 -17
  302. package/dist/components/quick-actions/streaming-modal.js.map +1 -1
  303. package/dist/components/quick-actions/streaming-output.d.ts +38 -0
  304. package/dist/components/quick-actions/streaming-output.d.ts.map +1 -0
  305. package/dist/components/quick-actions/streaming-output.js +22 -0
  306. package/dist/components/quick-actions/streaming-output.js.map +1 -0
  307. package/dist/components/quick-actions/whatsup-modal.d.ts +5 -0
  308. package/dist/components/quick-actions/whatsup-modal.d.ts.map +1 -1
  309. package/dist/components/quick-actions/whatsup-modal.js +36 -10
  310. package/dist/components/quick-actions/whatsup-modal.js.map +1 -1
  311. package/dist/components/settings/devices-agents-tab.d.ts +10 -0
  312. package/dist/components/settings/devices-agents-tab.d.ts.map +1 -0
  313. package/dist/components/settings/devices-agents-tab.js +131 -0
  314. package/dist/components/settings/devices-agents-tab.js.map +1 -0
  315. package/dist/components/settings/models-list.d.ts +39 -0
  316. package/dist/components/settings/models-list.d.ts.map +1 -0
  317. package/dist/components/settings/models-list.js +72 -0
  318. package/dist/components/settings/models-list.js.map +1 -0
  319. package/dist/components/settings/models-tab.d.ts +4 -0
  320. package/dist/components/settings/models-tab.d.ts.map +1 -1
  321. package/dist/components/settings/models-tab.js +52 -102
  322. package/dist/components/settings/models-tab.js.map +1 -1
  323. package/dist/components/settings/one-time-agent-credential.d.ts +3 -0
  324. package/dist/components/settings/one-time-agent-credential.d.ts.map +1 -0
  325. package/dist/components/settings/one-time-agent-credential.js +55 -0
  326. package/dist/components/settings/one-time-agent-credential.js.map +1 -0
  327. package/dist/components/settings/passkey-list.d.ts +35 -0
  328. package/dist/components/settings/passkey-list.d.ts.map +1 -0
  329. package/dist/components/settings/passkey-list.js +34 -0
  330. package/dist/components/settings/passkey-list.js.map +1 -0
  331. package/dist/components/settings/passkey-tab.d.ts +3 -0
  332. package/dist/components/settings/passkey-tab.d.ts.map +1 -1
  333. package/dist/components/settings/passkey-tab.js +53 -45
  334. package/dist/components/settings/passkey-tab.js.map +1 -1
  335. package/dist/components/settings/pi-accounts-list.d.ts +27 -0
  336. package/dist/components/settings/pi-accounts-list.d.ts.map +1 -0
  337. package/dist/components/settings/pi-accounts-list.js +15 -0
  338. package/dist/components/settings/pi-accounts-list.js.map +1 -0
  339. package/dist/components/settings/pi-accounts.d.ts +3 -0
  340. package/dist/components/settings/pi-accounts.d.ts.map +1 -1
  341. package/dist/components/settings/pi-accounts.js +73 -55
  342. package/dist/components/settings/pi-accounts.js.map +1 -1
  343. package/dist/components/settings/principal-list.d.ts +37 -0
  344. package/dist/components/settings/principal-list.d.ts.map +1 -0
  345. package/dist/components/settings/principal-list.js +18 -0
  346. package/dist/components/settings/principal-list.js.map +1 -0
  347. package/dist/components/settings/settings-panel.d.ts +10 -3
  348. package/dist/components/settings/settings-panel.d.ts.map +1 -1
  349. package/dist/components/settings/settings-panel.js +80 -6
  350. package/dist/components/settings/settings-panel.js.map +1 -1
  351. package/dist/components/settings/skills-list.d.ts +53 -0
  352. package/dist/components/settings/skills-list.d.ts.map +1 -0
  353. package/dist/components/settings/skills-list.js +28 -0
  354. package/dist/components/settings/skills-list.js.map +1 -0
  355. package/dist/components/settings/skills-tab.d.ts.map +1 -1
  356. package/dist/components/settings/skills-tab.js +65 -38
  357. package/dist/components/settings/skills-tab.js.map +1 -1
  358. package/dist/components/settings/tool-permissions-list.d.ts +18 -0
  359. package/dist/components/settings/tool-permissions-list.d.ts.map +1 -0
  360. package/dist/components/settings/tool-permissions-list.js +6 -0
  361. package/dist/components/settings/tool-permissions-list.js.map +1 -0
  362. package/dist/components/settings/tool-permissions.d.ts +2 -1
  363. package/dist/components/settings/tool-permissions.d.ts.map +1 -1
  364. package/dist/components/settings/tool-permissions.js +33 -16
  365. package/dist/components/settings/tool-permissions.js.map +1 -1
  366. package/dist/components/settings/web-search-chain.d.ts +41 -0
  367. package/dist/components/settings/web-search-chain.d.ts.map +1 -0
  368. package/dist/components/settings/web-search-chain.js +47 -0
  369. package/dist/components/settings/web-search-chain.js.map +1 -0
  370. package/dist/components/settings/web-search-settings.d.ts +4 -7
  371. package/dist/components/settings/web-search-settings.d.ts.map +1 -1
  372. package/dist/components/settings/web-search-settings.js +54 -76
  373. package/dist/components/settings/web-search-settings.js.map +1 -1
  374. package/dist/components/share/share-menu.d.ts.map +1 -1
  375. package/dist/components/share/share-menu.js +24 -4
  376. package/dist/components/share/share-menu.js.map +1 -1
  377. package/dist/components/voice/dictation-sheet.js +3 -3
  378. package/dist/components/voice/dictation-sheet.js.map +1 -1
  379. package/dist/components/voice/mic-button.js +1 -1
  380. package/dist/components/voice/mic-button.js.map +1 -1
  381. package/dist/components/voice/review-card.js +1 -1
  382. package/dist/components/voice/review-card.js.map +1 -1
  383. package/dist/config.d.ts +5 -2
  384. package/dist/config.d.ts.map +1 -1
  385. package/dist/config.js +15 -5
  386. package/dist/config.js.map +1 -1
  387. package/dist/connection.d.ts +12 -0
  388. package/dist/connection.d.ts.map +1 -0
  389. package/dist/connection.js +421 -0
  390. package/dist/connection.js.map +1 -0
  391. package/dist/default-root.d.ts +3 -0
  392. package/dist/default-root.d.ts.map +1 -0
  393. package/dist/default-root.js +16 -0
  394. package/dist/default-root.js.map +1 -0
  395. package/dist/hooks/use-color-scheme.d.ts +14 -0
  396. package/dist/hooks/use-color-scheme.d.ts.map +1 -0
  397. package/dist/hooks/use-color-scheme.js +37 -0
  398. package/dist/hooks/use-color-scheme.js.map +1 -0
  399. package/dist/hooks/use-hash-routes.d.ts.map +1 -1
  400. package/dist/hooks/use-hash-routes.js +4 -2
  401. package/dist/hooks/use-hash-routes.js.map +1 -1
  402. package/dist/hooks/use-media-query.d.ts +7 -0
  403. package/dist/hooks/use-media-query.d.ts.map +1 -0
  404. package/dist/hooks/use-media-query.js +34 -0
  405. package/dist/hooks/use-media-query.js.map +1 -0
  406. package/dist/hooks/use-share-intake.d.ts.map +1 -1
  407. package/dist/hooks/use-share-intake.js +37 -12
  408. package/dist/hooks/use-share-intake.js.map +1 -1
  409. package/dist/hooks/use-vpn-status.d.ts +1 -1
  410. package/dist/hooks/use-vpn-status.d.ts.map +1 -1
  411. package/dist/hooks/use-vpn-status.js +20 -16
  412. package/dist/hooks/use-vpn-status.js.map +1 -1
  413. package/dist/hooks/use-websocket.d.ts +5 -24
  414. package/dist/hooks/use-websocket.d.ts.map +1 -1
  415. package/dist/hooks/use-websocket.js +11 -382
  416. package/dist/hooks/use-websocket.js.map +1 -1
  417. package/dist/hooks/websocket-handlers/activity.d.ts +2 -2
  418. package/dist/hooks/websocket-handlers/activity.d.ts.map +1 -1
  419. package/dist/hooks/websocket-handlers/activity.js +4 -5
  420. package/dist/hooks/websocket-handlers/activity.js.map +1 -1
  421. package/dist/hooks/websocket-handlers/chat.d.ts +1 -0
  422. package/dist/hooks/websocket-handlers/chat.d.ts.map +1 -1
  423. package/dist/hooks/websocket-handlers/chat.js +27 -5
  424. package/dist/hooks/websocket-handlers/chat.js.map +1 -1
  425. package/dist/hooks/websocket-handlers/connection.d.ts.map +1 -1
  426. package/dist/hooks/websocket-handlers/connection.js +4 -6
  427. package/dist/hooks/websocket-handlers/connection.js.map +1 -1
  428. package/dist/hooks/websocket-handlers/mask.d.ts +1 -1
  429. package/dist/hooks/websocket-handlers/mask.d.ts.map +1 -1
  430. package/dist/hooks/websocket-handlers/mask.js +2 -3
  431. package/dist/hooks/websocket-handlers/mask.js.map +1 -1
  432. package/dist/hooks/websocket-handlers/provider.d.ts.map +1 -1
  433. package/dist/hooks/websocket-handlers/provider.js +4 -6
  434. package/dist/hooks/websocket-handlers/provider.js.map +1 -1
  435. package/dist/hooks/websocket-handlers/types.d.ts +6 -2
  436. package/dist/hooks/websocket-handlers/types.d.ts.map +1 -1
  437. package/dist/index.d.ts +5 -3
  438. package/dist/index.d.ts.map +1 -1
  439. package/dist/index.js +6 -3
  440. package/dist/index.js.map +1 -1
  441. package/dist/lib/api-client.d.ts +321 -0
  442. package/dist/lib/api-client.d.ts.map +1 -1
  443. package/dist/lib/api-client.js +243 -213
  444. package/dist/lib/api-client.js.map +1 -1
  445. package/dist/lib/backend.d.ts +19 -2
  446. package/dist/lib/backend.d.ts.map +1 -1
  447. package/dist/lib/backend.js +15 -9
  448. package/dist/lib/backend.js.map +1 -1
  449. package/dist/lib/diff.d.ts +8 -10
  450. package/dist/lib/diff.d.ts.map +1 -1
  451. package/dist/lib/diff.js +26 -53
  452. package/dist/lib/diff.js.map +1 -1
  453. package/dist/lib/format-time.d.ts +3 -0
  454. package/dist/lib/format-time.d.ts.map +1 -0
  455. package/dist/lib/format-time.js +25 -0
  456. package/dist/lib/format-time.js.map +1 -0
  457. package/dist/lib/light-dark.d.ts +37 -0
  458. package/dist/lib/light-dark.d.ts.map +1 -0
  459. package/dist/lib/light-dark.js +83 -0
  460. package/dist/lib/light-dark.js.map +1 -0
  461. package/dist/lib/mermaid-theme.d.ts +7 -2
  462. package/dist/lib/mermaid-theme.d.ts.map +1 -1
  463. package/dist/lib/mermaid-theme.js +125 -203
  464. package/dist/lib/mermaid-theme.js.map +1 -1
  465. package/dist/lib/passkeys.d.ts +6 -3
  466. package/dist/lib/passkeys.d.ts.map +1 -1
  467. package/dist/lib/passkeys.js +10 -4
  468. package/dist/lib/passkeys.js.map +1 -1
  469. package/dist/lib/push-registration.d.ts +10 -0
  470. package/dist/lib/push-registration.d.ts.map +1 -0
  471. package/dist/lib/push-registration.js +44 -0
  472. package/dist/lib/push-registration.js.map +1 -0
  473. package/dist/lib/share-intake.d.ts +2 -1
  474. package/dist/lib/share-intake.d.ts.map +1 -1
  475. package/dist/lib/share-intake.js +3 -3
  476. package/dist/lib/share-intake.js.map +1 -1
  477. package/dist/lib/share.d.ts +4 -3
  478. package/dist/lib/share.d.ts.map +1 -1
  479. package/dist/lib/share.js +6 -7
  480. package/dist/lib/share.js.map +1 -1
  481. package/dist/lib/single-key.d.ts +30 -0
  482. package/dist/lib/single-key.d.ts.map +1 -0
  483. package/dist/lib/single-key.js +45 -0
  484. package/dist/lib/single-key.js.map +1 -0
  485. package/dist/lib/tool-names.d.ts +8 -6
  486. package/dist/lib/tool-names.d.ts.map +1 -1
  487. package/dist/lib/tool-names.js +17 -7
  488. package/dist/lib/tool-names.js.map +1 -1
  489. package/dist/root-context.d.ts +229 -0
  490. package/dist/root-context.d.ts.map +1 -0
  491. package/dist/root-context.js +33 -0
  492. package/dist/root-context.js.map +1 -0
  493. package/dist/root.d.ts +38 -0
  494. package/dist/root.d.ts.map +1 -0
  495. package/dist/root.js +47 -0
  496. package/dist/root.js.map +1 -0
  497. package/dist/stores/activity-state.d.ts +29 -0
  498. package/dist/stores/activity-state.d.ts.map +1 -0
  499. package/dist/stores/activity-state.js +282 -0
  500. package/dist/stores/activity-state.js.map +1 -0
  501. package/dist/stores/activity-store.d.ts +10 -41
  502. package/dist/stores/activity-store.d.ts.map +1 -1
  503. package/dist/stores/activity-store.js +9 -271
  504. package/dist/stores/activity-store.js.map +1 -1
  505. package/dist/stores/chat-state.d.ts +212 -0
  506. package/dist/stores/chat-state.d.ts.map +1 -0
  507. package/dist/stores/chat-state.js +466 -0
  508. package/dist/stores/chat-state.js.map +1 -0
  509. package/dist/stores/chat-store.d.ts +4 -162
  510. package/dist/stores/chat-store.d.ts.map +1 -1
  511. package/dist/stores/chat-store.js +7 -418
  512. package/dist/stores/chat-store.js.map +1 -1
  513. package/dist/stores/connection-state.d.ts +40 -0
  514. package/dist/stores/connection-state.d.ts.map +1 -0
  515. package/dist/stores/connection-state.js +30 -0
  516. package/dist/stores/connection-state.js.map +1 -0
  517. package/dist/stores/connection-store.d.ts +4 -40
  518. package/dist/stores/connection-store.d.ts.map +1 -1
  519. package/dist/stores/connection-store.js +7 -27
  520. package/dist/stores/connection-store.js.map +1 -1
  521. package/dist/stores/create-stores.d.ts +23 -0
  522. package/dist/stores/create-stores.d.ts.map +1 -0
  523. package/dist/stores/create-stores.js +28 -0
  524. package/dist/stores/create-stores.js.map +1 -0
  525. package/dist/stores/file-state.d.ts +53 -0
  526. package/dist/stores/file-state.d.ts.map +1 -0
  527. package/dist/stores/file-state.js +341 -0
  528. package/dist/stores/file-state.js.map +1 -0
  529. package/dist/stores/file-store.d.ts +4 -52
  530. package/dist/stores/file-store.d.ts.map +1 -1
  531. package/dist/stores/file-store.js +7 -300
  532. package/dist/stores/file-store.js.map +1 -1
  533. package/dist/stores/graph-state.d.ts +95 -0
  534. package/dist/stores/graph-state.d.ts.map +1 -0
  535. package/dist/stores/graph-state.js +252 -0
  536. package/dist/stores/graph-state.js.map +1 -0
  537. package/dist/stores/graph-store.d.ts +7 -83
  538. package/dist/stores/graph-store.d.ts.map +1 -1
  539. package/dist/stores/graph-store.js +8 -249
  540. package/dist/stores/graph-store.js.map +1 -1
  541. package/dist/stores/mask-state.d.ts +21 -0
  542. package/dist/stores/mask-state.d.ts.map +1 -0
  543. package/dist/stores/mask-state.js +9 -0
  544. package/dist/stores/mask-state.js.map +1 -0
  545. package/dist/stores/mask-store.d.ts +4 -21
  546. package/dist/stores/mask-store.d.ts.map +1 -1
  547. package/dist/stores/mask-store.js +7 -6
  548. package/dist/stores/mask-store.js.map +1 -1
  549. package/dist/stores/principal-state.d.ts +16 -0
  550. package/dist/stores/principal-state.d.ts.map +1 -0
  551. package/dist/stores/principal-state.js +31 -0
  552. package/dist/stores/principal-state.js.map +1 -0
  553. package/dist/stores/principal-store.d.ts +5 -0
  554. package/dist/stores/principal-store.d.ts.map +1 -0
  555. package/dist/stores/principal-store.js +8 -0
  556. package/dist/stores/principal-store.js.map +1 -0
  557. package/dist/stores/provider-state.d.ts +24 -0
  558. package/dist/stores/provider-state.d.ts.map +1 -0
  559. package/dist/stores/provider-state.js +68 -0
  560. package/dist/stores/provider-state.js.map +1 -0
  561. package/dist/stores/provider-store.d.ts +4 -23
  562. package/dist/stores/provider-store.d.ts.map +1 -1
  563. package/dist/stores/provider-store.js +7 -64
  564. package/dist/stores/provider-store.js.map +1 -1
  565. package/dist/stores/share-state.d.ts +29 -0
  566. package/dist/stores/share-state.d.ts.map +1 -0
  567. package/dist/stores/share-state.js +21 -0
  568. package/dist/stores/share-state.js.map +1 -0
  569. package/dist/stores/share-store.d.ts +4 -28
  570. package/dist/stores/share-store.d.ts.map +1 -1
  571. package/dist/stores/share-store.js +7 -18
  572. package/dist/stores/share-store.js.map +1 -1
  573. package/dist/stores/store-environment.d.ts +10 -0
  574. package/dist/stores/store-environment.d.ts.map +1 -0
  575. package/dist/stores/store-environment.js +2 -0
  576. package/dist/stores/store-environment.js.map +1 -0
  577. package/dist/stores/ui-state.d.ts +71 -0
  578. package/dist/stores/ui-state.d.ts.map +1 -0
  579. package/dist/stores/ui-state.js +58 -0
  580. package/dist/stores/ui-state.js.map +1 -0
  581. package/dist/stores/ui-store.d.ts +4 -45
  582. package/dist/stores/ui-store.d.ts.map +1 -1
  583. package/dist/stores/ui-store.js +7 -36
  584. package/dist/stores/ui-store.js.map +1 -1
  585. package/dist/styles.css +1 -1
  586. package/dist/theme.css +150 -97
  587. package/dist/voice/asr-clients.d.ts +2 -1
  588. package/dist/voice/asr-clients.d.ts.map +1 -1
  589. package/dist/voice/asr-clients.js +16 -17
  590. package/dist/voice/asr-clients.js.map +1 -1
  591. package/dist/voice/use-dictation.d.ts.map +1 -1
  592. package/dist/voice/use-dictation.js +12 -8
  593. package/dist/voice/use-dictation.js.map +1 -1
  594. package/dist/voice/voice-state.d.ts +25 -0
  595. package/dist/voice/voice-state.d.ts.map +1 -0
  596. package/dist/voice/voice-state.js +29 -0
  597. package/dist/voice/voice-state.js.map +1 -0
  598. package/dist/voice/voice-store.d.ts +4 -25
  599. package/dist/voice/voice-store.d.ts.map +1 -1
  600. package/dist/voice/voice-store.js +7 -26
  601. package/dist/voice/voice-store.js.map +1 -1
  602. package/package.json +3 -2
  603. package/src/components/activity/activity-page.tsx +334 -160
  604. package/src/components/activity/activity-run-detail.tsx +81 -47
  605. package/src/components/activity/activity-run-list.tsx +27 -59
  606. package/src/components/activity/activity-views.tsx +155 -0
  607. package/src/components/activity/approval-card.tsx +80 -0
  608. package/src/components/activity/digest-card.tsx +25 -61
  609. package/src/components/activity/digest-summary.tsx +52 -0
  610. package/src/components/activity/push-switch.tsx +62 -0
  611. package/src/components/activity/push-toggle.tsx +51 -81
  612. package/src/components/activity/span-bits.tsx +8 -7
  613. package/src/components/chat/ask-user-card.tsx +292 -356
  614. package/src/components/chat/ask-user-typed.ts +77 -0
  615. package/src/components/chat/brain-markdown-links.tsx +4 -4
  616. package/src/components/chat/brain-markdown.tsx +4 -2
  617. package/src/components/chat/chat-page.tsx +38 -9
  618. package/src/components/chat/composer-view.tsx +194 -0
  619. package/src/components/chat/composer.tsx +117 -296
  620. package/src/components/chat/markdown-content.tsx +53 -2
  621. package/src/components/chat/mermaid-block.tsx +13 -5
  622. package/src/components/chat/mermaid-share.ts +8 -7
  623. package/src/components/chat/mermaid-viewer.tsx +3 -1
  624. package/src/components/chat/message-bubble.tsx +78 -94
  625. package/src/components/chat/message-share.ts +7 -7
  626. package/src/components/chat/renderers/bind.tsx +94 -0
  627. package/src/components/chat/renderers/brain-ui-tools.tsx +56 -0
  628. package/src/components/chat/renderers/claude-tools.tsx +3 -2
  629. package/src/components/chat/renderers/index.ts +15 -10
  630. package/src/components/chat/session-drawer.tsx +60 -138
  631. package/src/components/chat/session-list.tsx +113 -0
  632. package/src/components/chat/share-block.tsx +16 -12
  633. package/src/components/chat/share-card.tsx +2 -2
  634. package/src/components/chat/subagent-view.tsx +4 -4
  635. package/src/components/chat/tool-call-timeline.tsx +59 -22
  636. package/src/components/chat/tool-cards/block-card.tsx +145 -0
  637. package/src/components/chat/tool-cards/image-mask-card.tsx +214 -0
  638. package/src/components/chat/tool-cards/location-card.tsx +159 -0
  639. package/src/components/chat/tool-views.tsx +23 -73
  640. package/src/components/chat/transcript-turn.tsx +108 -0
  641. package/src/components/chat/use-chat-commands.ts +14 -16
  642. package/src/components/chat/welcome-state.tsx +36 -91
  643. package/src/components/connectivity/connection-gate.tsx +80 -9
  644. package/src/components/connectivity/login-form.tsx +122 -0
  645. package/src/components/connectivity/login-screen.tsx +45 -100
  646. package/src/components/dev/share-harness.tsx +2 -2
  647. package/src/components/files/file-panel.tsx +168 -0
  648. package/src/components/files/file-tree-view.tsx +127 -0
  649. package/src/components/files/file-tree.tsx +55 -109
  650. package/src/components/files/file-viewer-binary.tsx +3 -2
  651. package/src/components/files/file-viewer-frame.tsx +113 -0
  652. package/src/components/files/file-viewer.tsx +40 -95
  653. package/src/components/files/frontmatter-chips.tsx +42 -0
  654. package/src/components/files/frontmatter-panel.tsx +6 -71
  655. package/src/components/files/staleness.ts +29 -0
  656. package/src/components/graph/graph-canvas.tsx +24 -1
  657. package/src/components/graph/graph-controls-column.tsx +92 -0
  658. package/src/components/graph/graph-controls.tsx +83 -127
  659. package/src/components/graph/graph-form.tsx +183 -0
  660. package/src/components/graph/graph-maintenance.tsx +9 -14
  661. package/src/components/graph/graph-node-rail.tsx +147 -0
  662. package/src/components/graph/graph-page.tsx +189 -49
  663. package/src/components/graph/graph-scene.tsx +200 -30
  664. package/src/components/graph/lib/graph-helpers.ts +65 -43
  665. package/src/components/graph/node-card.tsx +64 -0
  666. package/src/components/graph/node-popover.tsx +28 -117
  667. package/src/components/graph/use-graph-theme.ts +69 -32
  668. package/src/components/graph/use-node-actions.ts +56 -0
  669. package/src/components/images/image-share.ts +4 -2
  670. package/src/components/images/image-viewer.tsx +3 -1
  671. package/src/components/images/mask-editor.tsx +7 -4
  672. package/src/components/layout/app-shell.tsx +7 -1
  673. package/src/components/layout/desktop-palette.tsx +151 -0
  674. package/src/components/layout/key-cap.tsx +15 -0
  675. package/src/components/layout/mobile-tab-bar.tsx +80 -157
  676. package/src/components/layout/shortcut-switch.tsx +32 -0
  677. package/src/components/layout/side-rail.tsx +70 -150
  678. package/src/components/layout/slide-panel.tsx +29 -2
  679. package/src/components/layout/theme.tsx +67 -0
  680. package/src/components/quick-actions/add-form.tsx +188 -0
  681. package/src/components/quick-actions/add-modal.tsx +68 -144
  682. package/src/components/quick-actions/search-modal.tsx +49 -19
  683. package/src/components/quick-actions/streaming-modal.tsx +44 -71
  684. package/src/components/quick-actions/streaming-output.tsx +112 -0
  685. package/src/components/quick-actions/whatsup-modal.tsx +38 -60
  686. package/src/components/settings/devices-agents-tab.tsx +139 -0
  687. package/src/components/settings/models-list.tsx +299 -0
  688. package/src/components/settings/models-tab.tsx +63 -337
  689. package/src/components/settings/one-time-agent-credential.tsx +131 -0
  690. package/src/components/settings/passkey-list.tsx +201 -0
  691. package/src/components/settings/passkey-tab.tsx +53 -197
  692. package/src/components/settings/pi-accounts-list.tsx +128 -0
  693. package/src/components/settings/pi-accounts.tsx +71 -170
  694. package/src/components/settings/principal-list.tsx +172 -0
  695. package/src/components/settings/settings-panel.tsx +245 -19
  696. package/src/components/settings/skills-list.tsx +276 -0
  697. package/src/components/settings/skills-tab.tsx +82 -269
  698. package/src/components/settings/tool-permissions-list.tsx +54 -0
  699. package/src/components/settings/tool-permissions.tsx +27 -46
  700. package/src/components/settings/web-search-chain.tsx +300 -0
  701. package/src/components/settings/web-search-settings.tsx +58 -328
  702. package/src/components/share/share-menu.tsx +19 -4
  703. package/src/components/voice/dictation-sheet.tsx +5 -5
  704. package/src/components/voice/mic-button.tsx +1 -1
  705. package/src/components/voice/review-card.tsx +1 -1
  706. package/src/config.ts +21 -7
  707. package/src/connection.ts +443 -0
  708. package/src/default-root.ts +16 -0
  709. package/src/hooks/use-color-scheme.ts +36 -0
  710. package/src/hooks/use-hash-routes.ts +4 -2
  711. package/src/hooks/use-media-query.ts +32 -0
  712. package/src/hooks/use-share-intake.ts +32 -12
  713. package/src/hooks/use-vpn-status.ts +23 -15
  714. package/src/hooks/use-websocket.ts +12 -426
  715. package/src/hooks/websocket-handlers/activity.ts +4 -5
  716. package/src/hooks/websocket-handlers/chat.ts +26 -5
  717. package/src/hooks/websocket-handlers/connection.ts +4 -6
  718. package/src/hooks/websocket-handlers/mask.ts +2 -3
  719. package/src/hooks/websocket-handlers/provider.ts +4 -6
  720. package/src/hooks/websocket-handlers/types.ts +6 -2
  721. package/src/index.ts +7 -3
  722. package/src/lib/api-client.ts +446 -365
  723. package/src/lib/backend.ts +20 -10
  724. package/src/lib/diff.ts +28 -62
  725. package/src/lib/format-time.ts +20 -0
  726. package/src/lib/light-dark.ts +83 -0
  727. package/src/lib/mermaid-theme.ts +183 -214
  728. package/src/lib/passkeys.ts +12 -4
  729. package/src/lib/push-registration.ts +46 -0
  730. package/src/lib/share-intake.ts +6 -3
  731. package/src/lib/share.ts +7 -4
  732. package/src/lib/single-key.ts +47 -0
  733. package/src/lib/tool-names.ts +31 -8
  734. package/src/root-context.tsx +40 -0
  735. package/src/root.ts +83 -0
  736. package/src/stores/activity-state.ts +295 -0
  737. package/src/stores/activity-store.ts +11 -285
  738. package/src/stores/chat-state.ts +795 -0
  739. package/src/stores/chat-store.ts +11 -705
  740. package/src/stores/connection-state.ts +78 -0
  741. package/src/stores/connection-store.ts +11 -76
  742. package/src/stores/create-stores.ts +31 -0
  743. package/src/stores/file-state.ts +399 -0
  744. package/src/stores/file-store.ts +9 -360
  745. package/src/stores/graph-state.ts +368 -0
  746. package/src/stores/graph-store.ts +10 -355
  747. package/src/stores/mask-state.ts +30 -0
  748. package/src/stores/mask-store.ts +10 -27
  749. package/src/stores/principal-state.ts +42 -0
  750. package/src/stores/principal-store.ts +11 -0
  751. package/src/stores/provider-state.ts +103 -0
  752. package/src/stores/provider-store.ts +10 -95
  753. package/src/stores/share-state.ts +56 -0
  754. package/src/stores/share-store.ts +11 -54
  755. package/src/stores/store-environment.ts +10 -0
  756. package/src/stores/ui-state.ts +143 -0
  757. package/src/stores/ui-store.ts +11 -93
  758. package/src/styles.css +4 -1
  759. package/src/theme.css +150 -97
  760. package/src/voice/asr-clients.ts +17 -17
  761. package/src/voice/use-dictation.ts +11 -8
  762. package/src/voice/voice-state.ts +57 -0
  763. package/src/voice/voice-store.ts +11 -55
@@ -1,15 +1,14 @@
1
1
  import { useEffect, useRef, useState } from "react";
2
- import { Eye, EyeOff, Loader2, RefreshCw, X } from "lucide-react";
3
2
  import {
4
- THINKING_LEVELS,
5
3
  type BillingMode,
6
4
  type ModelCatalogEntry,
7
5
  type ModelCatalogResponse,
8
6
  type ThinkingLevel,
9
7
  } from "@schlessera/brain-ui-sdk/protocol";
10
- import { api } from "../../lib/api-client.js";
8
+ import { useBrainUiRoot } from "../../root-context.js";
9
+ import type { BrainUiRoot } from "../../root.js";
11
10
  import { useProviderStore } from "../../stores/provider-store.js";
12
- import { cn } from "../../lib/utils.js";
11
+ import { ModelsCatalogView } from "./models-list.js";
13
12
  import { PiAccountsSection } from "./pi-accounts.js";
14
13
  import { WebSearchSection } from "./web-search-settings.js";
15
14
  import { ToolPermissionsSection } from "./tool-permissions.js";
@@ -20,8 +19,15 @@ import { ToolPermissionsSection } from "./tool-permissions.js";
20
19
  * The roster comes from the server (Anthropic model discovery plus any
21
20
  * host-declared profiles), so this tab never hardcodes model names. Hiding is
22
21
  * presentation only — a session already pinned to a hidden model keeps running.
22
+ *
23
+ * This is the container (S7): the request, the optimistic commits, their
24
+ * ordering gate and their write queue live here; `ModelsCatalogView` draws
25
+ * the roster.
23
26
  */
24
27
  export function ModelsTab({ active }: { active: boolean }) {
28
+ const root = useBrainUiRoot();
29
+ const api = root.api;
30
+ const lifetime = useRef(0);
25
31
  const [catalog, setCatalog] = useState<ModelCatalogResponse | null>(null);
26
32
  const [loading, setLoading] = useState(false);
27
33
  const [refreshing, setRefreshing] = useState(false);
@@ -29,30 +35,29 @@ export function ModelsTab({ active }: { active: boolean }) {
29
35
  const loadProviders = useProviderStore((s) => s.loadProviders);
30
36
  const commitGate = useRef(createRequestGate());
31
37
  /** Serializes full-record PUTs — see commitCatalog. */
32
- const commitQueue = useRef<Promise<void>>(Promise.resolve());
38
+ const commitQueues = useRef(new WeakMap<BrainUiRoot, Promise<void>>());
33
39
 
34
40
  useEffect(() => {
35
- if (!active) return;
36
- let cancelled = false;
37
- setLoading(true);
41
+ const generation = ++lifetime.current;
42
+ const latest = commitGate.current.begin();
43
+ const current = () => generation === lifetime.current && latest();
44
+ setCatalog(null);
45
+ setLoading(active);
46
+ setRefreshing(false);
38
47
  setError(null);
39
- api
40
- .models()
41
- .then((data) => {
42
- if (!cancelled) setCatalog(data);
43
- })
44
- .catch((err: unknown) => {
45
- if (!cancelled) {
46
- setError(err instanceof Error ? err.message : "Could not load models");
47
- }
48
- })
49
- .finally(() => {
50
- if (!cancelled) setLoading(false);
51
- });
52
- return () => {
53
- cancelled = true;
54
- };
55
- }, [active]);
48
+ if (active) {
49
+ // Returning to a root waits for its accepted writes before reading.
50
+ void (commitQueues.current.get(root) ?? Promise.resolve())
51
+ .then(() => current() ? api.models() : null)
52
+ .then((data) => { if (data && current()) setCatalog(data); })
53
+ .catch((err: unknown) => {
54
+ if (current()) setError(err instanceof Error ? err.message : "Could not load models");
55
+ })
56
+ .finally(() => { if (generation === lifetime.current) setLoading(false); });
57
+ }
58
+ const invalidate = () => { lifetime.current++; };
59
+ return invalidate;
60
+ }, [active, root, api]);
56
61
 
57
62
  /**
58
63
  * Optimistic-update skeleton shared by the hidden toggle and the billing
@@ -72,7 +77,9 @@ export function ModelsTab({ active }: { active: boolean }) {
72
77
  optimistic: ModelCatalogResponse,
73
78
  commit: () => Promise<ModelCatalogResponse>
74
79
  ) {
75
- const isCurrent = commitGate.current.begin();
80
+ const generation = lifetime.current;
81
+ const latest = commitGate.current.begin();
82
+ const isCurrent = () => generation === lifetime.current && latest();
76
83
  const previous = catalog;
77
84
  setCatalog(optimistic);
78
85
  setError(null);
@@ -82,7 +89,7 @@ export function ModelsTab({ active }: { active: boolean }) {
82
89
  // even while the client looked right. Each commit waits for the previous
83
90
  // one to settle; payloads are built on optimistic state, so the newest
84
91
  // write already carries every earlier edit.
85
- const run = commitQueue.current.then(async () => {
92
+ const run = (commitQueues.current.get(root) ?? Promise.resolve()).then(async () => {
86
93
  try {
87
94
  const confirmed = await commit();
88
95
  if (isCurrent()) setCatalog(confirmed);
@@ -94,7 +101,7 @@ export function ModelsTab({ active }: { active: boolean }) {
94
101
  }
95
102
  }
96
103
  });
97
- commitQueue.current = run;
104
+ commitQueues.current.set(root, run);
98
105
  await run;
99
106
  }
100
107
 
@@ -171,230 +178,46 @@ export function ModelsTab({ active }: { active: boolean }) {
171
178
 
172
179
  async function onRefresh() {
173
180
  if (refreshing) return;
181
+ const generation = lifetime.current;
182
+ const latest = commitGate.current.begin();
183
+ const current = () => generation === lifetime.current && latest();
174
184
  setRefreshing(true);
175
185
  setError(null);
176
186
  try {
177
- setCatalog(await api.refreshModels());
187
+ await (commitQueues.current.get(root) ?? Promise.resolve());
188
+ if (generation !== lifetime.current) return;
189
+ const next = await api.refreshModels();
190
+ if (current()) setCatalog(next);
178
191
  // A refresh can surface newly released models — put them in the picker
179
192
  // now, not on next load.
180
193
  void loadProviders();
181
194
  } catch (err) {
182
- setError(err instanceof Error ? err.message : "Refresh failed");
195
+ if (current()) setError(err instanceof Error ? err.message : "Refresh failed");
183
196
  } finally {
184
- setRefreshing(false);
197
+ if (generation === lifetime.current) setRefreshing(false);
185
198
  }
186
199
  }
187
200
 
188
- const visibleCount = catalog?.models.filter((m) => !m.hidden).length ?? 0;
189
-
190
- return (
191
- <div className="flex h-full flex-col">
192
- <div className="flex-1 overflow-y-auto p-4">
193
- <h3 className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
194
- Models
195
- </h3>
196
- <p className="mt-1 text-xs text-muted-foreground">
197
- The list is read from the provider and refreshes on its own. Hide the
198
- ones you never pick — running sessions are unaffected.
199
- </p>
200
-
201
- {catalog && (
202
- <DefaultModelSelect catalog={catalog} onChange={changeDefault} />
203
- )}
204
-
205
- {loading ? (
206
- <div className="mt-6 flex justify-center">
207
- <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
208
- </div>
209
- ) : (
210
- <ul className="mt-4 flex flex-col gap-2">
211
- {catalog?.models.map((entry) => (
212
- <ModelRow
213
- key={entry.id}
214
- entry={entry}
215
- onToggle={() => toggleHidden(entry)}
216
- onBilling={(next) => changeBilling(entry, next)}
217
- onThinking={(next) => changeThinking(entry, next)}
218
- />
219
- ))}
220
- {catalog?.models.length === 0 && (
221
- <li className="rounded-lg border border-dashed border-border-subtle p-4 text-center text-xs text-muted-foreground">
222
- No models available.
223
- </li>
224
- )}
225
- </ul>
226
- )}
227
-
228
- {error && (
229
- <p role="alert" className="mt-3 text-xs text-destructive">
230
- {error}
231
- </p>
232
- )}
233
-
234
- {catalog?.discovery.error && (
235
- <p className="mt-3 text-xs text-muted-foreground">
236
- Last refresh failed ({catalog.discovery.error}). Showing the last
237
- known list.
238
- </p>
239
- )}
240
- {catalog && !catalog.discovery.enabled && (
241
- <p className="mt-3 text-xs text-muted-foreground">
242
- Discovery is disabled (BRAIN_UI_MODEL_DISCOVERY). Only configured
243
- profiles are listed.
244
- </p>
245
- )}
246
-
247
- {catalog && (
248
- <OpenRouterSection
249
- models={catalog.customModels ?? []}
250
- onChange={setCustom}
251
- />
252
- )}
253
-
254
- <PiAccountsSection active={active} />
255
-
256
- <WebSearchSection active={active} />
257
-
258
- <ToolPermissionsSection active={active} />
259
- </div>
260
-
261
- <div className="flex items-center justify-between gap-3 border-t border-border p-4">
262
- <span className="text-[11px] text-muted-foreground">
263
- {visibleCount} in picker · {formatRefreshed(catalog?.refreshedAt ?? null)}
264
- </span>
265
- <button
266
- onClick={onRefresh}
267
- disabled={refreshing}
268
- className="flex items-center gap-2 rounded-lg border border-border-subtle bg-surface px-3 py-2 text-xs font-medium text-foreground transition-colors hover:border-primary hover:text-primary disabled:opacity-50"
269
- >
270
- <RefreshCw className={cn("h-3.5 w-3.5", refreshing && "animate-spin")} />
271
- Refresh
272
- </button>
273
- </div>
274
- </div>
275
- );
276
- }
277
-
278
- /**
279
- * The default-model choice: which profile answers when a turn names none —
280
- * a fresh device's first conversation, a share filed into the brain, any
281
- * host-initiated action. "Auto" prefers a connected subscription account
282
- * (e.g. ChatGPT for the gpt profiles) and falls back to the built-in default.
283
- */
284
- function DefaultModelSelect({
285
- catalog,
286
- onChange,
287
- }: {
288
- catalog: ModelCatalogResponse;
289
- onChange: (next: string | null) => void;
290
- }) {
291
- const stored = catalog.defaultModelId ?? null;
292
- const byId = new Map(catalog.models.map((model) => [model.id, model]));
293
- const resolved = catalog.resolvedDefaultId
294
- ? byId.get(catalog.resolvedDefaultId)
295
- : undefined;
296
- // Offer everything visible, plus a stored default that has since been
297
- // hidden (dropping it from the list would silently rewrite the choice).
298
- const options = catalog.models.filter(
299
- (model) => !model.hidden || model.id === stored
300
- );
301
- return (
302
- <div className="mt-4 flex items-center gap-3 rounded-lg border border-border-subtle bg-surface p-3">
303
- <div className="min-w-0 flex-1">
304
- <p className="text-sm text-foreground">Default model</p>
305
- <p className="text-[11px] text-muted-foreground">
306
- Used for new conversations, shares, and actions that don't pick one.
307
- </p>
308
- </div>
309
- <select
310
- value={stored ?? "auto"}
311
- onChange={(e) => onChange(e.target.value === "auto" ? null : e.target.value)}
312
- aria-label="Default model"
313
- className="h-8 max-w-[45%] shrink-0 truncate rounded-lg border border-border-subtle bg-surface px-1.5 text-[11px] text-muted-foreground transition-colors hover:border-primary hover:text-foreground"
314
- >
315
- <option value="auto">
316
- {!stored && resolved ? `Auto (${resolved.label})` : "Auto"}
317
- </option>
318
- {options.map((model) => (
319
- <option key={model.id} value={model.id}>
320
- {model.label}
321
- </option>
322
- ))}
323
- </select>
324
- </div>
325
- );
326
- }
327
-
328
- /**
329
- * User-managed OpenRouter models: added and removed here by model id, no env
330
- * change or redeploy. They appear in the roster above as ordinary profiles
331
- * (api-billed via OPENROUTER_API_KEY).
332
- */
333
- function OpenRouterSection({
334
- models,
335
- onChange,
336
- }: {
337
- models: string[];
338
- onChange: (models: string[]) => void;
339
- }) {
340
- const [draft, setDraft] = useState("");
341
-
342
- function add() {
343
- const id = draft.trim();
344
- if (!id || models.includes(id)) return;
345
- onChange([...models, id]);
346
- setDraft("");
347
- }
348
-
349
201
  return (
350
- <div className="mt-6">
351
- <h3 className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
352
- OpenRouter models
353
- </h3>
354
- <p className="mt-1 text-xs text-muted-foreground">
355
- Add any OpenRouter model by its id (needs OPENROUTER_API_KEY on the
356
- server). Added models join the list above.
357
- </p>
358
- {models.length > 0 && (
359
- <ul className="mt-3 flex flex-col gap-1.5">
360
- {models.map((model) => (
361
- <li
362
- key={model}
363
- className="flex items-center gap-2 rounded-lg border border-border-subtle bg-surface px-3 py-2"
364
- >
365
- <span className="min-w-0 flex-1 truncate font-[family-name:var(--font-mono)] text-xs text-foreground">
366
- {model}
367
- </span>
368
- <button
369
- onClick={() => onChange(models.filter((m) => m !== model))}
370
- title={`Remove ${model}`}
371
- className="flex h-6 w-6 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-surface-raised hover:text-destructive"
372
- >
373
- <X className="h-3.5 w-3.5" />
374
- </button>
375
- </li>
376
- ))}
377
- </ul>
378
- )}
379
- <div className="mt-3 flex gap-2">
380
- <input
381
- value={draft}
382
- onChange={(e) => setDraft(e.target.value)}
383
- onKeyDown={(e) => {
384
- if (e.key === "Enter") add();
385
- }}
386
- placeholder="z.ai/glm-5.3-flash"
387
- className="h-8 min-w-0 flex-1 rounded-lg border border-border-subtle bg-surface px-2 font-[family-name:var(--font-mono)] text-xs text-foreground placeholder:text-muted-foreground/50 focus:border-primary focus:outline-none"
388
- />
389
- <button
390
- onClick={add}
391
- disabled={!draft.trim()}
392
- className="h-8 shrink-0 rounded-lg border border-border-subtle bg-surface px-3 text-xs font-medium text-foreground transition-colors hover:border-primary hover:text-primary disabled:opacity-50"
393
- >
394
- Add
395
- </button>
396
- </div>
397
- </div>
202
+ <ModelsCatalogView
203
+ catalog={catalog}
204
+ loading={loading}
205
+ refreshing={refreshing}
206
+ error={error}
207
+ sections={
208
+ <>
209
+ <PiAccountsSection active={active} />
210
+ <WebSearchSection active={active} />
211
+ <ToolPermissionsSection active={active} />
212
+ </>
213
+ }
214
+ onToggleHidden={(entry) => void toggleHidden(entry)}
215
+ onBilling={(entry, next) => void changeBilling(entry, next)}
216
+ onThinking={(entry, next) => void changeThinking(entry, next)}
217
+ onDefault={(next) => void changeDefault(next)}
218
+ onCustomModels={(models) => void setCustom(models)}
219
+ onRefresh={() => void onRefresh()}
220
+ />
398
221
  );
399
222
  }
400
223
 
@@ -431,10 +254,6 @@ export function nextBillingOverrides(
431
254
  return billing;
432
255
  }
433
256
 
434
- function billingLabel(mode: BillingMode): string {
435
- return mode === "api" ? "API" : "Subscription";
436
- }
437
-
438
257
  /**
439
258
  * The effort-override record PUT after changing one profile: every other
440
259
  * profile keeps its stored override, the changed one is set — or, for "auto",
@@ -453,96 +272,3 @@ export function nextThinkingOverrides(
453
272
  }
454
273
  return thinking;
455
274
  }
456
-
457
- function ModelRow({
458
- entry,
459
- onToggle,
460
- onBilling,
461
- onThinking,
462
- }: {
463
- entry: ModelCatalogEntry;
464
- onToggle: () => void;
465
- onBilling: (next: BillingMode | "auto") => void;
466
- onThinking: (next: ThinkingLevel | "auto") => void;
467
- }) {
468
- const Icon = entry.hidden ? EyeOff : Eye;
469
- return (
470
- <li
471
- className={cn(
472
- "flex items-center gap-3 rounded-lg border border-border-subtle bg-surface p-3",
473
- entry.hidden && "opacity-50"
474
- )}
475
- >
476
- <div className="min-w-0 flex-1">
477
- <p className="truncate text-sm text-foreground">{entry.label}</p>
478
- <p className="truncate text-[11px] text-muted-foreground">
479
- {entry.id}
480
- {entry.contextWindow ? ` · ${formatTokens(entry.contextWindow)}` : ""}
481
- {entry.source === "declared" ? " · configured" : ""}
482
- </p>
483
- </div>
484
- {/* Reasoning effort — only for profiles that take one (the gpt models).
485
- Same tri-state pattern as billing: Default shows what it resolves
486
- to, an explicit pick is stored as an override. */}
487
- {entry.thinkingLevel && (
488
- <select
489
- value={entry.thinkingOverride ?? "auto"}
490
- onChange={(e) => onThinking(e.target.value as ThinkingLevel | "auto")}
491
- aria-label={`Reasoning effort for ${entry.label}`}
492
- className="h-8 shrink-0 rounded-lg border border-border-subtle bg-surface px-1.5 text-[11px] text-muted-foreground transition-colors hover:border-primary hover:text-foreground"
493
- >
494
- <option value="auto">
495
- {!entry.thinkingOverride ? `Default (${entry.thinkingLevel})` : "Default"}
496
- </option>
497
- {THINKING_LEVELS.map((level) => (
498
- <option key={level} value={level}>
499
- {level}
500
- </option>
501
- ))}
502
- </select>
503
- )}
504
- {/* Tri-state billing: the collapsed control always reads as the
505
- RESOLVED mode — the Auto option carries what auto resolves to, so
506
- "Auto (subscription)" and a forced "Subscription" are both legible
507
- at a glance. */}
508
- <select
509
- value={entry.billingOverride ?? "auto"}
510
- onChange={(e) => onBilling(e.target.value as BillingMode | "auto")}
511
- aria-label={`Billing for ${entry.label}`}
512
- className="h-8 shrink-0 rounded-lg border border-border-subtle bg-surface px-1.5 text-[11px] text-muted-foreground transition-colors hover:border-primary hover:text-foreground"
513
- >
514
- <option value="auto">
515
- {!entry.billingOverride && entry.billingMode
516
- ? `Auto (${billingLabel(entry.billingMode).toLowerCase()})`
517
- : "Auto"}
518
- </option>
519
- <option value="subscription">Subscription</option>
520
- <option value="api">API</option>
521
- </select>
522
- <button
523
- onClick={onToggle}
524
- title={entry.hidden ? "Show in picker" : "Hide from picker"}
525
- aria-pressed={!entry.hidden}
526
- className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-surface-raised hover:text-foreground"
527
- >
528
- <Icon className="h-4 w-4" />
529
- </button>
530
- </li>
531
- );
532
- }
533
-
534
- function formatTokens(tokens: number): string {
535
- if (tokens >= 1_000_000) return `${tokens / 1_000_000}M context`;
536
- if (tokens >= 1_000) return `${Math.round(tokens / 1_000)}K context`;
537
- return `${tokens} context`;
538
- }
539
-
540
- function formatRefreshed(refreshedAt: number | null): string {
541
- if (refreshedAt === null) return "never refreshed";
542
- const minutes = Math.round((Date.now() - refreshedAt) / 60_000);
543
- if (minutes < 1) return "refreshed just now";
544
- if (minutes < 60) return `refreshed ${minutes}m ago`;
545
- const hours = Math.round(minutes / 60);
546
- if (hours < 24) return `refreshed ${hours}h ago`;
547
- return `refreshed ${Math.round(hours / 24)}d ago`;
548
- }
@@ -0,0 +1,131 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ import { createPortal } from "react-dom";
3
+ import { Check, Copy } from "lucide-react";
4
+ import type { MintedAgent } from "../../lib/api-client.js";
5
+ import { usePrincipalStore } from "../../stores/principal-store.js";
6
+
7
+ /** App-level portal for the unrecoverable value returned by an agent mint. */
8
+ export function OneTimeAgentCredentialDialog() {
9
+ const credential = usePrincipalStore((state) => state.oneTimeCredential);
10
+ const acknowledge = usePrincipalStore(
11
+ (state) => state.acknowledgeAgentCredential
12
+ );
13
+
14
+ return credential ? (
15
+ <OneTimeCredential
16
+ key={credential.id}
17
+ credential={credential}
18
+ onDone={acknowledge}
19
+ />
20
+ ) : null;
21
+ }
22
+
23
+ function OneTimeCredential({
24
+ credential,
25
+ onDone,
26
+ }: {
27
+ credential: MintedAgent;
28
+ onDone: () => void;
29
+ }) {
30
+ const [copied, setCopied] = useState(false);
31
+ const [saved, setSaved] = useState(false);
32
+ const [copyError, setCopyError] = useState(false);
33
+ const dialogRef = useRef<HTMLDivElement>(null);
34
+
35
+ useEffect(() => {
36
+ const keepDialogOpen = (event: KeyboardEvent) => {
37
+ if (event.key === "Escape") {
38
+ event.preventDefault();
39
+ event.stopPropagation();
40
+ return;
41
+ }
42
+ if (event.key !== "Tab") return;
43
+ const focusable = Array.from(
44
+ dialogRef.current?.querySelectorAll<HTMLElement>(
45
+ 'button:not([disabled]), input:not([disabled])'
46
+ ) ?? []
47
+ );
48
+ if (focusable.length === 0) return;
49
+ const first = focusable[0]!;
50
+ const last = focusable[focusable.length - 1]!;
51
+ if (event.shiftKey && document.activeElement === first) {
52
+ event.preventDefault();
53
+ last.focus();
54
+ } else if (!event.shiftKey && document.activeElement === last) {
55
+ event.preventDefault();
56
+ first.focus();
57
+ }
58
+ };
59
+ window.addEventListener("keydown", keepDialogOpen, true);
60
+ return () => window.removeEventListener("keydown", keepDialogOpen, true);
61
+ }, []);
62
+
63
+ async function copyCredential() {
64
+ try {
65
+ await navigator.clipboard.writeText(credential.cookie);
66
+ setCopied(true);
67
+ setCopyError(false);
68
+ } catch {
69
+ setCopyError(true);
70
+ }
71
+ }
72
+
73
+ return createPortal(
74
+ <div
75
+ role="dialog"
76
+ aria-modal="true"
77
+ aria-labelledby="one-time-credential-title"
78
+ className="fixed inset-0 z-[60] flex items-center justify-center bg-black/60 p-4"
79
+ >
80
+ <div
81
+ ref={dialogRef}
82
+ className="w-full max-w-md rounded-xl border border-border bg-surface p-5 shadow-[0_16px_48px_rgba(0,0,0,0.5)]"
83
+ >
84
+ <h3 id="one-time-credential-title" className="text-base font-semibold text-foreground">
85
+ Save this credential now
86
+ </h3>
87
+ <p className="mt-2 text-sm font-medium text-destructive">
88
+ This is the only time you will see this value.
89
+ </p>
90
+ <p className="mt-1 text-xs text-muted-foreground">
91
+ Store it somewhere safe before continuing. It cannot be recovered later.
92
+ </p>
93
+ <div className="mt-4 rounded-lg border border-border-subtle bg-background p-3">
94
+ <code className="block break-all text-xs text-foreground">{credential.cookie}</code>
95
+ </div>
96
+ <button
97
+ autoFocus
98
+ type="button"
99
+ onClick={() => void copyCredential()}
100
+ className="mt-3 flex w-full items-center justify-center gap-2 rounded-lg border border-border-subtle bg-surface px-4 py-2 text-sm font-medium text-foreground transition-colors hover:border-primary"
101
+ >
102
+ {copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
103
+ {copied ? "Copied" : "Copy credential"}
104
+ </button>
105
+ {copyError ? (
106
+ <p role="alert" className="mt-2 text-xs text-destructive">
107
+ Copy failed. Select the value above and copy it manually.
108
+ </p>
109
+ ) : null}
110
+ <label className="mt-4 flex items-start gap-2 text-xs text-foreground">
111
+ <input
112
+ type="checkbox"
113
+ checked={saved}
114
+ onChange={(event) => setSaved(event.target.checked)}
115
+ className="mt-0.5"
116
+ />
117
+ I have saved this credential somewhere safe.
118
+ </label>
119
+ <button
120
+ type="button"
121
+ disabled={!saved}
122
+ onClick={onDone}
123
+ className="mt-3 w-full rounded-lg bg-primary-fill px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:brightness-110 disabled:opacity-50"
124
+ >
125
+ Done
126
+ </button>
127
+ </div>
128
+ </div>,
129
+ document.body
130
+ );
131
+ }