@schlessera/brain-ui-react 0.35.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (755) hide show
  1. package/README.md +82 -4
  2. package/dist/components/activity/activity-page.d.ts +17 -5
  3. package/dist/components/activity/activity-page.d.ts.map +1 -1
  4. package/dist/components/activity/activity-page.js +144 -50
  5. package/dist/components/activity/activity-page.js.map +1 -1
  6. package/dist/components/activity/activity-run-detail.d.ts +16 -1
  7. package/dist/components/activity/activity-run-detail.d.ts.map +1 -1
  8. package/dist/components/activity/activity-run-detail.js +47 -4
  9. package/dist/components/activity/activity-run-detail.js.map +1 -1
  10. package/dist/components/activity/activity-run-list.d.ts +7 -1
  11. package/dist/components/activity/activity-run-list.d.ts.map +1 -1
  12. package/dist/components/activity/activity-run-list.js +16 -8
  13. package/dist/components/activity/activity-run-list.js.map +1 -1
  14. package/dist/components/activity/activity-views.d.ts +63 -0
  15. package/dist/components/activity/activity-views.d.ts.map +1 -0
  16. package/dist/components/activity/activity-views.js +52 -0
  17. package/dist/components/activity/activity-views.js.map +1 -0
  18. package/dist/components/activity/approval-card.d.ts +11 -0
  19. package/dist/components/activity/approval-card.d.ts.map +1 -0
  20. package/dist/components/activity/approval-card.js +46 -0
  21. package/dist/components/activity/approval-card.js.map +1 -0
  22. package/dist/components/activity/digest-card.d.ts +3 -0
  23. package/dist/components/activity/digest-card.d.ts.map +1 -1
  24. package/dist/components/activity/digest-card.js +20 -16
  25. package/dist/components/activity/digest-card.js.map +1 -1
  26. package/dist/components/activity/digest-summary.d.ts +19 -0
  27. package/dist/components/activity/digest-summary.d.ts.map +1 -0
  28. package/dist/components/activity/digest-summary.js +20 -0
  29. package/dist/components/activity/digest-summary.js.map +1 -0
  30. package/dist/components/activity/push-switch.d.ts +25 -0
  31. package/dist/components/activity/push-switch.d.ts.map +1 -0
  32. package/dist/components/activity/push-switch.js +14 -0
  33. package/dist/components/activity/push-switch.js.map +1 -0
  34. package/dist/components/activity/push-toggle.d.ts +7 -0
  35. package/dist/components/activity/push-toggle.d.ts.map +1 -1
  36. package/dist/components/activity/push-toggle.js +72 -47
  37. package/dist/components/activity/push-toggle.js.map +1 -1
  38. package/dist/components/activity/span-bits.d.ts.map +1 -1
  39. package/dist/components/activity/span-bits.js +9 -7
  40. package/dist/components/activity/span-bits.js.map +1 -1
  41. package/dist/components/chat/ask-user-card.d.ts +76 -3
  42. package/dist/components/chat/ask-user-card.d.ts.map +1 -1
  43. package/dist/components/chat/ask-user-card.js +208 -149
  44. package/dist/components/chat/ask-user-card.js.map +1 -1
  45. package/dist/components/chat/ask-user-typed.d.ts +42 -0
  46. package/dist/components/chat/ask-user-typed.d.ts.map +1 -0
  47. package/dist/components/chat/ask-user-typed.js +60 -0
  48. package/dist/components/chat/ask-user-typed.js.map +1 -0
  49. package/dist/components/chat/brain-markdown-links.d.ts +2 -1
  50. package/dist/components/chat/brain-markdown-links.d.ts.map +1 -1
  51. package/dist/components/chat/brain-markdown-links.js +3 -4
  52. package/dist/components/chat/brain-markdown-links.js.map +1 -1
  53. package/dist/components/chat/brain-markdown.d.ts.map +1 -1
  54. package/dist/components/chat/brain-markdown.js +4 -2
  55. package/dist/components/chat/brain-markdown.js.map +1 -1
  56. package/dist/components/chat/chat-page.d.ts.map +1 -1
  57. package/dist/components/chat/chat-page.js +24 -9
  58. package/dist/components/chat/chat-page.js.map +1 -1
  59. package/dist/components/chat/composer-view.d.ts +75 -0
  60. package/dist/components/chat/composer-view.d.ts.map +1 -0
  61. package/dist/components/chat/composer-view.js +31 -0
  62. package/dist/components/chat/composer-view.js.map +1 -0
  63. package/dist/components/chat/composer.d.ts +4 -0
  64. package/dist/components/chat/composer.d.ts.map +1 -1
  65. package/dist/components/chat/composer.js +76 -59
  66. package/dist/components/chat/composer.js.map +1 -1
  67. package/dist/components/chat/markdown-content.d.ts +16 -1
  68. package/dist/components/chat/markdown-content.d.ts.map +1 -1
  69. package/dist/components/chat/markdown-content.js +47 -3
  70. package/dist/components/chat/markdown-content.js.map +1 -1
  71. package/dist/components/chat/mermaid-block.d.ts +4 -0
  72. package/dist/components/chat/mermaid-block.d.ts.map +1 -1
  73. package/dist/components/chat/mermaid-block.js +13 -5
  74. package/dist/components/chat/mermaid-block.js.map +1 -1
  75. package/dist/components/chat/mermaid-share.d.ts +2 -1
  76. package/dist/components/chat/mermaid-share.d.ts.map +1 -1
  77. package/dist/components/chat/mermaid-share.js +7 -8
  78. package/dist/components/chat/mermaid-share.js.map +1 -1
  79. package/dist/components/chat/mermaid-viewer.d.ts.map +1 -1
  80. package/dist/components/chat/mermaid-viewer.js +3 -1
  81. package/dist/components/chat/mermaid-viewer.js.map +1 -1
  82. package/dist/components/chat/message-bubble.d.ts +8 -1
  83. package/dist/components/chat/message-bubble.d.ts.map +1 -1
  84. package/dist/components/chat/message-bubble.js +53 -24
  85. package/dist/components/chat/message-bubble.js.map +1 -1
  86. package/dist/components/chat/message-share.d.ts +2 -1
  87. package/dist/components/chat/message-share.d.ts.map +1 -1
  88. package/dist/components/chat/message-share.js +6 -7
  89. package/dist/components/chat/message-share.js.map +1 -1
  90. package/dist/components/chat/renderers/bind.d.ts +39 -0
  91. package/dist/components/chat/renderers/bind.d.ts.map +1 -0
  92. package/dist/components/chat/renderers/bind.js +43 -0
  93. package/dist/components/chat/renderers/bind.js.map +1 -0
  94. package/dist/components/chat/renderers/brain-ui-tools.d.ts +3 -0
  95. package/dist/components/chat/renderers/brain-ui-tools.d.ts.map +1 -0
  96. package/dist/components/chat/renderers/brain-ui-tools.js +41 -0
  97. package/dist/components/chat/renderers/brain-ui-tools.js.map +1 -0
  98. package/dist/components/chat/renderers/claude-tools.d.ts.map +1 -1
  99. package/dist/components/chat/renderers/claude-tools.js +3 -2
  100. package/dist/components/chat/renderers/claude-tools.js.map +1 -1
  101. package/dist/components/chat/renderers/index.d.ts +10 -2
  102. package/dist/components/chat/renderers/index.d.ts.map +1 -1
  103. package/dist/components/chat/renderers/index.js +15 -10
  104. package/dist/components/chat/renderers/index.js.map +1 -1
  105. package/dist/components/chat/session-drawer.d.ts +4 -0
  106. package/dist/components/chat/session-drawer.d.ts.map +1 -1
  107. package/dist/components/chat/session-drawer.js +32 -32
  108. package/dist/components/chat/session-drawer.js.map +1 -1
  109. package/dist/components/chat/session-list.d.ts +41 -0
  110. package/dist/components/chat/session-list.d.ts.map +1 -0
  111. package/dist/components/chat/session-list.js +10 -0
  112. package/dist/components/chat/session-list.js.map +1 -0
  113. package/dist/components/chat/share-block.d.ts.map +1 -1
  114. package/dist/components/chat/share-block.js +12 -11
  115. package/dist/components/chat/share-block.js.map +1 -1
  116. package/dist/components/chat/share-card.js +2 -2
  117. package/dist/components/chat/share-card.js.map +1 -1
  118. package/dist/components/chat/subagent-view.js +1 -1
  119. package/dist/components/chat/subagent-view.js.map +1 -1
  120. package/dist/components/chat/tool-call-timeline.d.ts.map +1 -1
  121. package/dist/components/chat/tool-call-timeline.js +37 -12
  122. package/dist/components/chat/tool-call-timeline.js.map +1 -1
  123. package/dist/components/chat/tool-cards/block-card.d.ts +28 -0
  124. package/dist/components/chat/tool-cards/block-card.d.ts.map +1 -0
  125. package/dist/components/chat/tool-cards/block-card.js +103 -0
  126. package/dist/components/chat/tool-cards/block-card.js.map +1 -0
  127. package/dist/components/chat/tool-cards/image-mask-card.d.ts +70 -0
  128. package/dist/components/chat/tool-cards/image-mask-card.d.ts.map +1 -0
  129. package/dist/components/chat/tool-cards/image-mask-card.js +142 -0
  130. package/dist/components/chat/tool-cards/image-mask-card.js.map +1 -0
  131. package/dist/components/chat/tool-cards/location-card.d.ts +45 -0
  132. package/dist/components/chat/tool-cards/location-card.d.ts.map +1 -0
  133. package/dist/components/chat/tool-cards/location-card.js +128 -0
  134. package/dist/components/chat/tool-cards/location-card.js.map +1 -0
  135. package/dist/components/chat/tool-views.d.ts +13 -2
  136. package/dist/components/chat/tool-views.d.ts.map +1 -1
  137. package/dist/components/chat/tool-views.js +20 -22
  138. package/dist/components/chat/tool-views.js.map +1 -1
  139. package/dist/components/chat/transcript-turn.d.ts +45 -0
  140. package/dist/components/chat/transcript-turn.d.ts.map +1 -0
  141. package/dist/components/chat/transcript-turn.js +25 -0
  142. package/dist/components/chat/transcript-turn.js.map +1 -0
  143. package/dist/components/chat/use-chat-commands.d.ts.map +1 -1
  144. package/dist/components/chat/use-chat-commands.js +13 -16
  145. package/dist/components/chat/use-chat-commands.js.map +1 -1
  146. package/dist/components/chat/welcome-state.d.ts +7 -0
  147. package/dist/components/chat/welcome-state.d.ts.map +1 -1
  148. package/dist/components/chat/welcome-state.js +13 -5
  149. package/dist/components/chat/welcome-state.js.map +1 -1
  150. package/dist/components/connectivity/connection-gate.d.ts.map +1 -1
  151. package/dist/components/connectivity/connection-gate.js +27 -21
  152. package/dist/components/connectivity/connection-gate.js.map +1 -1
  153. package/dist/components/connectivity/login-form.d.ts +31 -0
  154. package/dist/components/connectivity/login-form.d.ts.map +1 -0
  155. package/dist/components/connectivity/login-form.js +19 -0
  156. package/dist/components/connectivity/login-form.js.map +1 -0
  157. package/dist/components/connectivity/login-screen.d.ts +5 -2
  158. package/dist/components/connectivity/login-screen.d.ts.map +1 -1
  159. package/dist/components/connectivity/login-screen.js +41 -31
  160. package/dist/components/connectivity/login-screen.js.map +1 -1
  161. package/dist/components/dev/share-harness.js +1 -1
  162. package/dist/components/dev/share-harness.js.map +1 -1
  163. package/dist/components/files/file-panel.d.ts +1 -1
  164. package/dist/components/files/file-panel.d.ts.map +1 -1
  165. package/dist/components/files/file-panel.js +74 -0
  166. package/dist/components/files/file-panel.js.map +1 -1
  167. package/dist/components/files/file-tree-view.d.ts +45 -0
  168. package/dist/components/files/file-tree-view.d.ts.map +1 -0
  169. package/dist/components/files/file-tree-view.js +51 -0
  170. package/dist/components/files/file-tree-view.js.map +1 -0
  171. package/dist/components/files/file-tree.d.ts +6 -0
  172. package/dist/components/files/file-tree.d.ts.map +1 -1
  173. package/dist/components/files/file-tree.js +39 -43
  174. package/dist/components/files/file-tree.js.map +1 -1
  175. package/dist/components/files/file-viewer-binary.d.ts.map +1 -1
  176. package/dist/components/files/file-viewer-binary.js +3 -2
  177. package/dist/components/files/file-viewer-binary.js.map +1 -1
  178. package/dist/components/files/file-viewer-frame.d.ts +36 -0
  179. package/dist/components/files/file-viewer-frame.d.ts.map +1 -0
  180. package/dist/components/files/file-viewer-frame.js +26 -0
  181. package/dist/components/files/file-viewer-frame.js.map +1 -0
  182. package/dist/components/files/file-viewer.d.ts +5 -0
  183. package/dist/components/files/file-viewer.d.ts.map +1 -1
  184. package/dist/components/files/file-viewer.js +26 -32
  185. package/dist/components/files/file-viewer.js.map +1 -1
  186. package/dist/components/files/frontmatter-chips.d.ts +18 -0
  187. package/dist/components/files/frontmatter-chips.d.ts.map +1 -0
  188. package/dist/components/files/frontmatter-chips.js +11 -0
  189. package/dist/components/files/frontmatter-chips.js.map +1 -0
  190. package/dist/components/files/frontmatter-panel.d.ts +5 -1
  191. package/dist/components/files/frontmatter-panel.d.ts.map +1 -1
  192. package/dist/components/files/frontmatter-panel.js +7 -6
  193. package/dist/components/files/frontmatter-panel.js.map +1 -1
  194. package/dist/components/files/staleness.d.ts +18 -0
  195. package/dist/components/files/staleness.d.ts.map +1 -0
  196. package/dist/components/files/staleness.js +27 -0
  197. package/dist/components/files/staleness.js.map +1 -0
  198. package/dist/components/graph/graph-canvas.d.ts.map +1 -1
  199. package/dist/components/graph/graph-canvas.js +24 -1
  200. package/dist/components/graph/graph-canvas.js.map +1 -1
  201. package/dist/components/graph/graph-controls-column.d.ts +14 -0
  202. package/dist/components/graph/graph-controls-column.d.ts.map +1 -0
  203. package/dist/components/graph/graph-controls-column.js +44 -0
  204. package/dist/components/graph/graph-controls-column.js.map +1 -0
  205. package/dist/components/graph/graph-controls.d.ts +20 -5
  206. package/dist/components/graph/graph-controls.d.ts.map +1 -1
  207. package/dist/components/graph/graph-controls.js +58 -37
  208. package/dist/components/graph/graph-controls.js.map +1 -1
  209. package/dist/components/graph/graph-form.d.ts +82 -0
  210. package/dist/components/graph/graph-form.d.ts.map +1 -0
  211. package/dist/components/graph/graph-form.js +69 -0
  212. package/dist/components/graph/graph-form.js.map +1 -0
  213. package/dist/components/graph/graph-maintenance.d.ts.map +1 -1
  214. package/dist/components/graph/graph-maintenance.js +6 -10
  215. package/dist/components/graph/graph-maintenance.js.map +1 -1
  216. package/dist/components/graph/graph-node-rail.d.ts +13 -0
  217. package/dist/components/graph/graph-node-rail.d.ts.map +1 -0
  218. package/dist/components/graph/graph-node-rail.js +92 -0
  219. package/dist/components/graph/graph-node-rail.js.map +1 -0
  220. package/dist/components/graph/graph-page.d.ts +7 -0
  221. package/dist/components/graph/graph-page.d.ts.map +1 -1
  222. package/dist/components/graph/graph-page.js +102 -12
  223. package/dist/components/graph/graph-page.js.map +1 -1
  224. package/dist/components/graph/graph-scene.d.ts.map +1 -1
  225. package/dist/components/graph/graph-scene.js +100 -24
  226. package/dist/components/graph/graph-scene.js.map +1 -1
  227. package/dist/components/graph/lib/graph-helpers.d.ts +42 -12
  228. package/dist/components/graph/lib/graph-helpers.d.ts.map +1 -1
  229. package/dist/components/graph/lib/graph-helpers.js +33 -41
  230. package/dist/components/graph/lib/graph-helpers.js.map +1 -1
  231. package/dist/components/graph/node-card.d.ts +28 -0
  232. package/dist/components/graph/node-card.d.ts.map +1 -0
  233. package/dist/components/graph/node-card.js +7 -0
  234. package/dist/components/graph/node-card.js.map +1 -0
  235. package/dist/components/graph/node-popover.d.ts +6 -2
  236. package/dist/components/graph/node-popover.d.ts.map +1 -1
  237. package/dist/components/graph/node-popover.js +13 -31
  238. package/dist/components/graph/node-popover.js.map +1 -1
  239. package/dist/components/graph/use-graph-theme.d.ts +32 -4
  240. package/dist/components/graph/use-graph-theme.d.ts.map +1 -1
  241. package/dist/components/graph/use-graph-theme.js +44 -32
  242. package/dist/components/graph/use-graph-theme.js.map +1 -1
  243. package/dist/components/graph/use-node-actions.d.ts +26 -0
  244. package/dist/components/graph/use-node-actions.d.ts.map +1 -0
  245. package/dist/components/graph/use-node-actions.js +54 -0
  246. package/dist/components/graph/use-node-actions.js.map +1 -0
  247. package/dist/components/images/image-share.d.ts +2 -1
  248. package/dist/components/images/image-share.d.ts.map +1 -1
  249. package/dist/components/images/image-share.js +3 -3
  250. package/dist/components/images/image-share.js.map +1 -1
  251. package/dist/components/images/image-viewer.d.ts.map +1 -1
  252. package/dist/components/images/image-viewer.js +3 -1
  253. package/dist/components/images/image-viewer.js.map +1 -1
  254. package/dist/components/images/mask-editor.d.ts.map +1 -1
  255. package/dist/components/images/mask-editor.js +7 -5
  256. package/dist/components/images/mask-editor.js.map +1 -1
  257. package/dist/components/layout/app-shell.d.ts.map +1 -1
  258. package/dist/components/layout/app-shell.js +4 -1
  259. package/dist/components/layout/app-shell.js.map +1 -1
  260. package/dist/components/layout/desktop-palette.d.ts +23 -0
  261. package/dist/components/layout/desktop-palette.d.ts.map +1 -0
  262. package/dist/components/layout/desktop-palette.js +132 -0
  263. package/dist/components/layout/desktop-palette.js.map +1 -0
  264. package/dist/components/layout/key-cap.d.ts +9 -0
  265. package/dist/components/layout/key-cap.d.ts.map +1 -0
  266. package/dist/components/layout/key-cap.js +10 -0
  267. package/dist/components/layout/key-cap.js.map +1 -0
  268. package/dist/components/layout/mobile-tab-bar.d.ts +13 -0
  269. package/dist/components/layout/mobile-tab-bar.d.ts.map +1 -1
  270. package/dist/components/layout/mobile-tab-bar.js +58 -47
  271. package/dist/components/layout/mobile-tab-bar.js.map +1 -1
  272. package/dist/components/layout/shortcut-switch.d.ts +13 -0
  273. package/dist/components/layout/shortcut-switch.d.ts.map +1 -0
  274. package/dist/components/layout/shortcut-switch.js +22 -0
  275. package/dist/components/layout/shortcut-switch.js.map +1 -0
  276. package/dist/components/layout/side-rail.d.ts +24 -0
  277. package/dist/components/layout/side-rail.d.ts.map +1 -1
  278. package/dist/components/layout/side-rail.js +65 -27
  279. package/dist/components/layout/side-rail.js.map +1 -1
  280. package/dist/components/layout/slide-panel.d.ts +12 -2
  281. package/dist/components/layout/slide-panel.d.ts.map +1 -1
  282. package/dist/components/layout/slide-panel.js +11 -2
  283. package/dist/components/layout/slide-panel.js.map +1 -1
  284. package/dist/components/layout/theme.d.ts +22 -0
  285. package/dist/components/layout/theme.d.ts.map +1 -0
  286. package/dist/components/layout/theme.js +44 -0
  287. package/dist/components/layout/theme.js.map +1 -0
  288. package/dist/components/quick-actions/add-form.d.ts +44 -0
  289. package/dist/components/quick-actions/add-form.d.ts.map +1 -0
  290. package/dist/components/quick-actions/add-form.js +30 -0
  291. package/dist/components/quick-actions/add-form.js.map +1 -0
  292. package/dist/components/quick-actions/add-modal.d.ts +7 -0
  293. package/dist/components/quick-actions/add-modal.d.ts.map +1 -1
  294. package/dist/components/quick-actions/add-modal.js +23 -20
  295. package/dist/components/quick-actions/add-modal.js.map +1 -1
  296. package/dist/components/quick-actions/search-modal.d.ts.map +1 -1
  297. package/dist/components/quick-actions/search-modal.js +4 -3
  298. package/dist/components/quick-actions/search-modal.js.map +1 -1
  299. package/dist/components/quick-actions/streaming-modal.d.ts +6 -0
  300. package/dist/components/quick-actions/streaming-modal.d.ts.map +1 -1
  301. package/dist/components/quick-actions/streaming-modal.js +39 -17
  302. package/dist/components/quick-actions/streaming-modal.js.map +1 -1
  303. package/dist/components/quick-actions/streaming-output.d.ts +38 -0
  304. package/dist/components/quick-actions/streaming-output.d.ts.map +1 -0
  305. package/dist/components/quick-actions/streaming-output.js +22 -0
  306. package/dist/components/quick-actions/streaming-output.js.map +1 -0
  307. package/dist/components/quick-actions/whatsup-modal.d.ts +5 -0
  308. package/dist/components/quick-actions/whatsup-modal.d.ts.map +1 -1
  309. package/dist/components/quick-actions/whatsup-modal.js +36 -10
  310. package/dist/components/quick-actions/whatsup-modal.js.map +1 -1
  311. package/dist/components/settings/devices-agents-tab.d.ts +6 -1
  312. package/dist/components/settings/devices-agents-tab.d.ts.map +1 -1
  313. package/dist/components/settings/devices-agents-tab.js +55 -20
  314. package/dist/components/settings/devices-agents-tab.js.map +1 -1
  315. package/dist/components/settings/models-list.d.ts +39 -0
  316. package/dist/components/settings/models-list.d.ts.map +1 -0
  317. package/dist/components/settings/models-list.js +72 -0
  318. package/dist/components/settings/models-list.js.map +1 -0
  319. package/dist/components/settings/models-tab.d.ts +4 -0
  320. package/dist/components/settings/models-tab.d.ts.map +1 -1
  321. package/dist/components/settings/models-tab.js +52 -102
  322. package/dist/components/settings/models-tab.js.map +1 -1
  323. package/dist/components/settings/one-time-agent-credential.js +1 -1
  324. package/dist/components/settings/one-time-agent-credential.js.map +1 -1
  325. package/dist/components/settings/passkey-list.d.ts +35 -0
  326. package/dist/components/settings/passkey-list.d.ts.map +1 -0
  327. package/dist/components/settings/passkey-list.js +34 -0
  328. package/dist/components/settings/passkey-list.js.map +1 -0
  329. package/dist/components/settings/passkey-tab.d.ts +3 -0
  330. package/dist/components/settings/passkey-tab.d.ts.map +1 -1
  331. package/dist/components/settings/passkey-tab.js +53 -45
  332. package/dist/components/settings/passkey-tab.js.map +1 -1
  333. package/dist/components/settings/pi-accounts-list.d.ts +27 -0
  334. package/dist/components/settings/pi-accounts-list.d.ts.map +1 -0
  335. package/dist/components/settings/pi-accounts-list.js +15 -0
  336. package/dist/components/settings/pi-accounts-list.js.map +1 -0
  337. package/dist/components/settings/pi-accounts.d.ts +3 -0
  338. package/dist/components/settings/pi-accounts.d.ts.map +1 -1
  339. package/dist/components/settings/pi-accounts.js +73 -55
  340. package/dist/components/settings/pi-accounts.js.map +1 -1
  341. package/dist/components/settings/principal-list.d.ts +37 -0
  342. package/dist/components/settings/principal-list.d.ts.map +1 -0
  343. package/dist/components/settings/principal-list.js +18 -0
  344. package/dist/components/settings/principal-list.js.map +1 -0
  345. package/dist/components/settings/settings-panel.d.ts +10 -3
  346. package/dist/components/settings/settings-panel.d.ts.map +1 -1
  347. package/dist/components/settings/settings-panel.js +69 -8
  348. package/dist/components/settings/settings-panel.js.map +1 -1
  349. package/dist/components/settings/skills-list.d.ts +53 -0
  350. package/dist/components/settings/skills-list.d.ts.map +1 -0
  351. package/dist/components/settings/skills-list.js +28 -0
  352. package/dist/components/settings/skills-list.js.map +1 -0
  353. package/dist/components/settings/skills-tab.d.ts.map +1 -1
  354. package/dist/components/settings/skills-tab.js +65 -38
  355. package/dist/components/settings/skills-tab.js.map +1 -1
  356. package/dist/components/settings/tool-permissions-list.d.ts +18 -0
  357. package/dist/components/settings/tool-permissions-list.d.ts.map +1 -0
  358. package/dist/components/settings/tool-permissions-list.js +6 -0
  359. package/dist/components/settings/tool-permissions-list.js.map +1 -0
  360. package/dist/components/settings/tool-permissions.d.ts +2 -1
  361. package/dist/components/settings/tool-permissions.d.ts.map +1 -1
  362. package/dist/components/settings/tool-permissions.js +33 -16
  363. package/dist/components/settings/tool-permissions.js.map +1 -1
  364. package/dist/components/settings/web-search-chain.d.ts +41 -0
  365. package/dist/components/settings/web-search-chain.d.ts.map +1 -0
  366. package/dist/components/settings/web-search-chain.js +47 -0
  367. package/dist/components/settings/web-search-chain.js.map +1 -0
  368. package/dist/components/settings/web-search-settings.d.ts +4 -7
  369. package/dist/components/settings/web-search-settings.d.ts.map +1 -1
  370. package/dist/components/settings/web-search-settings.js +54 -76
  371. package/dist/components/settings/web-search-settings.js.map +1 -1
  372. package/dist/components/share/share-menu.d.ts.map +1 -1
  373. package/dist/components/share/share-menu.js +24 -4
  374. package/dist/components/share/share-menu.js.map +1 -1
  375. package/dist/components/voice/dictation-sheet.js +3 -3
  376. package/dist/components/voice/dictation-sheet.js.map +1 -1
  377. package/dist/components/voice/mic-button.js +1 -1
  378. package/dist/components/voice/mic-button.js.map +1 -1
  379. package/dist/components/voice/review-card.js +1 -1
  380. package/dist/components/voice/review-card.js.map +1 -1
  381. package/dist/config.d.ts +5 -2
  382. package/dist/config.d.ts.map +1 -1
  383. package/dist/config.js +15 -5
  384. package/dist/config.js.map +1 -1
  385. package/dist/connection.d.ts +12 -0
  386. package/dist/connection.d.ts.map +1 -0
  387. package/dist/connection.js +421 -0
  388. package/dist/connection.js.map +1 -0
  389. package/dist/default-root.d.ts +3 -0
  390. package/dist/default-root.d.ts.map +1 -0
  391. package/dist/default-root.js +16 -0
  392. package/dist/default-root.js.map +1 -0
  393. package/dist/hooks/use-color-scheme.d.ts +14 -0
  394. package/dist/hooks/use-color-scheme.d.ts.map +1 -0
  395. package/dist/hooks/use-color-scheme.js +37 -0
  396. package/dist/hooks/use-color-scheme.js.map +1 -0
  397. package/dist/hooks/use-hash-routes.d.ts.map +1 -1
  398. package/dist/hooks/use-hash-routes.js +4 -2
  399. package/dist/hooks/use-hash-routes.js.map +1 -1
  400. package/dist/hooks/use-media-query.d.ts +7 -0
  401. package/dist/hooks/use-media-query.d.ts.map +1 -0
  402. package/dist/hooks/use-media-query.js +34 -0
  403. package/dist/hooks/use-media-query.js.map +1 -0
  404. package/dist/hooks/use-share-intake.d.ts.map +1 -1
  405. package/dist/hooks/use-share-intake.js +37 -12
  406. package/dist/hooks/use-share-intake.js.map +1 -1
  407. package/dist/hooks/use-vpn-status.d.ts.map +1 -1
  408. package/dist/hooks/use-vpn-status.js +17 -18
  409. package/dist/hooks/use-vpn-status.js.map +1 -1
  410. package/dist/hooks/use-websocket.d.ts +5 -24
  411. package/dist/hooks/use-websocket.d.ts.map +1 -1
  412. package/dist/hooks/use-websocket.js +11 -384
  413. package/dist/hooks/use-websocket.js.map +1 -1
  414. package/dist/hooks/websocket-handlers/activity.d.ts +2 -2
  415. package/dist/hooks/websocket-handlers/activity.d.ts.map +1 -1
  416. package/dist/hooks/websocket-handlers/activity.js +4 -5
  417. package/dist/hooks/websocket-handlers/activity.js.map +1 -1
  418. package/dist/hooks/websocket-handlers/chat.d.ts +1 -0
  419. package/dist/hooks/websocket-handlers/chat.d.ts.map +1 -1
  420. package/dist/hooks/websocket-handlers/chat.js +27 -5
  421. package/dist/hooks/websocket-handlers/chat.js.map +1 -1
  422. package/dist/hooks/websocket-handlers/connection.d.ts.map +1 -1
  423. package/dist/hooks/websocket-handlers/connection.js +4 -6
  424. package/dist/hooks/websocket-handlers/connection.js.map +1 -1
  425. package/dist/hooks/websocket-handlers/mask.d.ts +1 -1
  426. package/dist/hooks/websocket-handlers/mask.d.ts.map +1 -1
  427. package/dist/hooks/websocket-handlers/mask.js +2 -3
  428. package/dist/hooks/websocket-handlers/mask.js.map +1 -1
  429. package/dist/hooks/websocket-handlers/provider.d.ts.map +1 -1
  430. package/dist/hooks/websocket-handlers/provider.js +4 -6
  431. package/dist/hooks/websocket-handlers/provider.js.map +1 -1
  432. package/dist/hooks/websocket-handlers/types.d.ts +6 -2
  433. package/dist/hooks/websocket-handlers/types.d.ts.map +1 -1
  434. package/dist/index.d.ts +5 -3
  435. package/dist/index.d.ts.map +1 -1
  436. package/dist/index.js +6 -3
  437. package/dist/index.js.map +1 -1
  438. package/dist/lib/api-client.d.ts +289 -0
  439. package/dist/lib/api-client.d.ts.map +1 -1
  440. package/dist/lib/api-client.js +243 -224
  441. package/dist/lib/api-client.js.map +1 -1
  442. package/dist/lib/backend.d.ts +19 -2
  443. package/dist/lib/backend.d.ts.map +1 -1
  444. package/dist/lib/backend.js +15 -9
  445. package/dist/lib/backend.js.map +1 -1
  446. package/dist/lib/diff.d.ts +8 -10
  447. package/dist/lib/diff.d.ts.map +1 -1
  448. package/dist/lib/diff.js +26 -53
  449. package/dist/lib/diff.js.map +1 -1
  450. package/dist/lib/light-dark.d.ts +37 -0
  451. package/dist/lib/light-dark.d.ts.map +1 -0
  452. package/dist/lib/light-dark.js +83 -0
  453. package/dist/lib/light-dark.js.map +1 -0
  454. package/dist/lib/mermaid-theme.d.ts +7 -2
  455. package/dist/lib/mermaid-theme.d.ts.map +1 -1
  456. package/dist/lib/mermaid-theme.js +125 -203
  457. package/dist/lib/mermaid-theme.js.map +1 -1
  458. package/dist/lib/passkeys.d.ts +6 -3
  459. package/dist/lib/passkeys.d.ts.map +1 -1
  460. package/dist/lib/passkeys.js +10 -4
  461. package/dist/lib/passkeys.js.map +1 -1
  462. package/dist/lib/push-registration.d.ts +4 -1
  463. package/dist/lib/push-registration.d.ts.map +1 -1
  464. package/dist/lib/push-registration.js +20 -2
  465. package/dist/lib/push-registration.js.map +1 -1
  466. package/dist/lib/share-intake.d.ts +2 -1
  467. package/dist/lib/share-intake.d.ts.map +1 -1
  468. package/dist/lib/share-intake.js +3 -3
  469. package/dist/lib/share-intake.js.map +1 -1
  470. package/dist/lib/share.d.ts +4 -3
  471. package/dist/lib/share.d.ts.map +1 -1
  472. package/dist/lib/share.js +6 -7
  473. package/dist/lib/share.js.map +1 -1
  474. package/dist/lib/single-key.d.ts +30 -0
  475. package/dist/lib/single-key.d.ts.map +1 -0
  476. package/dist/lib/single-key.js +45 -0
  477. package/dist/lib/single-key.js.map +1 -0
  478. package/dist/lib/tool-names.d.ts +8 -6
  479. package/dist/lib/tool-names.d.ts.map +1 -1
  480. package/dist/lib/tool-names.js +17 -7
  481. package/dist/lib/tool-names.js.map +1 -1
  482. package/dist/root-context.d.ts +229 -0
  483. package/dist/root-context.d.ts.map +1 -0
  484. package/dist/root-context.js +33 -0
  485. package/dist/root-context.js.map +1 -0
  486. package/dist/root.d.ts +38 -0
  487. package/dist/root.d.ts.map +1 -0
  488. package/dist/root.js +47 -0
  489. package/dist/root.js.map +1 -0
  490. package/dist/stores/activity-state.d.ts +29 -0
  491. package/dist/stores/activity-state.d.ts.map +1 -0
  492. package/dist/stores/activity-state.js +282 -0
  493. package/dist/stores/activity-state.js.map +1 -0
  494. package/dist/stores/activity-store.d.ts +10 -41
  495. package/dist/stores/activity-store.d.ts.map +1 -1
  496. package/dist/stores/activity-store.js +9 -271
  497. package/dist/stores/activity-store.js.map +1 -1
  498. package/dist/stores/chat-state.d.ts +212 -0
  499. package/dist/stores/chat-state.d.ts.map +1 -0
  500. package/dist/stores/chat-state.js +466 -0
  501. package/dist/stores/chat-state.js.map +1 -0
  502. package/dist/stores/chat-store.d.ts +4 -162
  503. package/dist/stores/chat-store.d.ts.map +1 -1
  504. package/dist/stores/chat-store.js +7 -418
  505. package/dist/stores/chat-store.js.map +1 -1
  506. package/dist/stores/connection-state.d.ts +40 -0
  507. package/dist/stores/connection-state.d.ts.map +1 -0
  508. package/dist/stores/connection-state.js +30 -0
  509. package/dist/stores/connection-state.js.map +1 -0
  510. package/dist/stores/connection-store.d.ts +4 -40
  511. package/dist/stores/connection-store.d.ts.map +1 -1
  512. package/dist/stores/connection-store.js +7 -27
  513. package/dist/stores/connection-store.js.map +1 -1
  514. package/dist/stores/create-stores.d.ts +23 -0
  515. package/dist/stores/create-stores.d.ts.map +1 -0
  516. package/dist/stores/create-stores.js +28 -0
  517. package/dist/stores/create-stores.js.map +1 -0
  518. package/dist/stores/file-state.d.ts +53 -0
  519. package/dist/stores/file-state.d.ts.map +1 -0
  520. package/dist/stores/file-state.js +341 -0
  521. package/dist/stores/file-state.js.map +1 -0
  522. package/dist/stores/file-store.d.ts +4 -52
  523. package/dist/stores/file-store.d.ts.map +1 -1
  524. package/dist/stores/file-store.js +7 -336
  525. package/dist/stores/file-store.js.map +1 -1
  526. package/dist/stores/graph-state.d.ts +95 -0
  527. package/dist/stores/graph-state.d.ts.map +1 -0
  528. package/dist/stores/graph-state.js +252 -0
  529. package/dist/stores/graph-state.js.map +1 -0
  530. package/dist/stores/graph-store.d.ts +7 -83
  531. package/dist/stores/graph-store.d.ts.map +1 -1
  532. package/dist/stores/graph-store.js +8 -249
  533. package/dist/stores/graph-store.js.map +1 -1
  534. package/dist/stores/mask-state.d.ts +21 -0
  535. package/dist/stores/mask-state.d.ts.map +1 -0
  536. package/dist/stores/mask-state.js +9 -0
  537. package/dist/stores/mask-state.js.map +1 -0
  538. package/dist/stores/mask-store.d.ts +4 -21
  539. package/dist/stores/mask-store.d.ts.map +1 -1
  540. package/dist/stores/mask-store.js +7 -6
  541. package/dist/stores/mask-store.js.map +1 -1
  542. package/dist/stores/principal-state.d.ts +16 -0
  543. package/dist/stores/principal-state.d.ts.map +1 -0
  544. package/dist/stores/principal-state.js +31 -0
  545. package/dist/stores/principal-state.js.map +1 -0
  546. package/dist/stores/principal-store.d.ts +4 -15
  547. package/dist/stores/principal-store.d.ts.map +1 -1
  548. package/dist/stores/principal-store.js +7 -28
  549. package/dist/stores/principal-store.js.map +1 -1
  550. package/dist/stores/provider-state.d.ts +24 -0
  551. package/dist/stores/provider-state.d.ts.map +1 -0
  552. package/dist/stores/provider-state.js +68 -0
  553. package/dist/stores/provider-state.js.map +1 -0
  554. package/dist/stores/provider-store.d.ts +4 -23
  555. package/dist/stores/provider-store.d.ts.map +1 -1
  556. package/dist/stores/provider-store.js +7 -64
  557. package/dist/stores/provider-store.js.map +1 -1
  558. package/dist/stores/share-state.d.ts +29 -0
  559. package/dist/stores/share-state.d.ts.map +1 -0
  560. package/dist/stores/share-state.js +21 -0
  561. package/dist/stores/share-state.js.map +1 -0
  562. package/dist/stores/share-store.d.ts +4 -28
  563. package/dist/stores/share-store.d.ts.map +1 -1
  564. package/dist/stores/share-store.js +7 -18
  565. package/dist/stores/share-store.js.map +1 -1
  566. package/dist/stores/store-environment.d.ts +10 -0
  567. package/dist/stores/store-environment.d.ts.map +1 -0
  568. package/dist/stores/store-environment.js +2 -0
  569. package/dist/stores/store-environment.js.map +1 -0
  570. package/dist/stores/ui-state.d.ts +71 -0
  571. package/dist/stores/ui-state.d.ts.map +1 -0
  572. package/dist/stores/ui-state.js +58 -0
  573. package/dist/stores/ui-state.js.map +1 -0
  574. package/dist/stores/ui-store.d.ts +4 -45
  575. package/dist/stores/ui-store.d.ts.map +1 -1
  576. package/dist/stores/ui-store.js +7 -36
  577. package/dist/stores/ui-store.js.map +1 -1
  578. package/dist/styles.css +1 -1
  579. package/dist/theme.css +150 -97
  580. package/dist/voice/asr-clients.d.ts +2 -1
  581. package/dist/voice/asr-clients.d.ts.map +1 -1
  582. package/dist/voice/asr-clients.js +16 -17
  583. package/dist/voice/asr-clients.js.map +1 -1
  584. package/dist/voice/use-dictation.d.ts.map +1 -1
  585. package/dist/voice/use-dictation.js +12 -8
  586. package/dist/voice/use-dictation.js.map +1 -1
  587. package/dist/voice/voice-state.d.ts +25 -0
  588. package/dist/voice/voice-state.d.ts.map +1 -0
  589. package/dist/voice/voice-state.js +29 -0
  590. package/dist/voice/voice-state.js.map +1 -0
  591. package/dist/voice/voice-store.d.ts +4 -25
  592. package/dist/voice/voice-store.d.ts.map +1 -1
  593. package/dist/voice/voice-store.js +7 -26
  594. package/dist/voice/voice-store.js.map +1 -1
  595. package/package.json +3 -2
  596. package/src/components/activity/activity-page.tsx +334 -160
  597. package/src/components/activity/activity-run-detail.tsx +81 -47
  598. package/src/components/activity/activity-run-list.tsx +27 -59
  599. package/src/components/activity/activity-views.tsx +155 -0
  600. package/src/components/activity/approval-card.tsx +80 -0
  601. package/src/components/activity/digest-card.tsx +25 -61
  602. package/src/components/activity/digest-summary.tsx +52 -0
  603. package/src/components/activity/push-switch.tsx +62 -0
  604. package/src/components/activity/push-toggle.tsx +51 -81
  605. package/src/components/activity/span-bits.tsx +8 -7
  606. package/src/components/chat/ask-user-card.tsx +292 -356
  607. package/src/components/chat/ask-user-typed.ts +77 -0
  608. package/src/components/chat/brain-markdown-links.tsx +4 -4
  609. package/src/components/chat/brain-markdown.tsx +4 -2
  610. package/src/components/chat/chat-page.tsx +38 -9
  611. package/src/components/chat/composer-view.tsx +194 -0
  612. package/src/components/chat/composer.tsx +117 -296
  613. package/src/components/chat/markdown-content.tsx +53 -2
  614. package/src/components/chat/mermaid-block.tsx +13 -5
  615. package/src/components/chat/mermaid-share.ts +8 -7
  616. package/src/components/chat/mermaid-viewer.tsx +3 -1
  617. package/src/components/chat/message-bubble.tsx +78 -94
  618. package/src/components/chat/message-share.ts +7 -7
  619. package/src/components/chat/renderers/bind.tsx +94 -0
  620. package/src/components/chat/renderers/brain-ui-tools.tsx +56 -0
  621. package/src/components/chat/renderers/claude-tools.tsx +3 -2
  622. package/src/components/chat/renderers/index.ts +15 -10
  623. package/src/components/chat/session-drawer.tsx +41 -138
  624. package/src/components/chat/session-list.tsx +113 -0
  625. package/src/components/chat/share-block.tsx +16 -12
  626. package/src/components/chat/share-card.tsx +2 -2
  627. package/src/components/chat/subagent-view.tsx +4 -4
  628. package/src/components/chat/tool-call-timeline.tsx +59 -22
  629. package/src/components/chat/tool-cards/block-card.tsx +145 -0
  630. package/src/components/chat/tool-cards/image-mask-card.tsx +214 -0
  631. package/src/components/chat/tool-cards/location-card.tsx +159 -0
  632. package/src/components/chat/tool-views.tsx +21 -60
  633. package/src/components/chat/transcript-turn.tsx +108 -0
  634. package/src/components/chat/use-chat-commands.ts +14 -16
  635. package/src/components/chat/welcome-state.tsx +36 -91
  636. package/src/components/connectivity/connection-gate.tsx +32 -24
  637. package/src/components/connectivity/login-form.tsx +122 -0
  638. package/src/components/connectivity/login-screen.tsx +45 -100
  639. package/src/components/dev/share-harness.tsx +2 -2
  640. package/src/components/files/file-panel.tsx +168 -0
  641. package/src/components/files/file-tree-view.tsx +127 -0
  642. package/src/components/files/file-tree.tsx +55 -109
  643. package/src/components/files/file-viewer-binary.tsx +3 -2
  644. package/src/components/files/file-viewer-frame.tsx +113 -0
  645. package/src/components/files/file-viewer.tsx +40 -95
  646. package/src/components/files/frontmatter-chips.tsx +42 -0
  647. package/src/components/files/frontmatter-panel.tsx +6 -71
  648. package/src/components/files/staleness.ts +29 -0
  649. package/src/components/graph/graph-canvas.tsx +24 -1
  650. package/src/components/graph/graph-controls-column.tsx +92 -0
  651. package/src/components/graph/graph-controls.tsx +83 -127
  652. package/src/components/graph/graph-form.tsx +183 -0
  653. package/src/components/graph/graph-maintenance.tsx +9 -14
  654. package/src/components/graph/graph-node-rail.tsx +147 -0
  655. package/src/components/graph/graph-page.tsx +189 -49
  656. package/src/components/graph/graph-scene.tsx +200 -30
  657. package/src/components/graph/lib/graph-helpers.ts +65 -43
  658. package/src/components/graph/node-card.tsx +64 -0
  659. package/src/components/graph/node-popover.tsx +28 -117
  660. package/src/components/graph/use-graph-theme.ts +69 -32
  661. package/src/components/graph/use-node-actions.ts +56 -0
  662. package/src/components/images/image-share.ts +4 -2
  663. package/src/components/images/image-viewer.tsx +3 -1
  664. package/src/components/images/mask-editor.tsx +7 -4
  665. package/src/components/layout/app-shell.tsx +5 -1
  666. package/src/components/layout/desktop-palette.tsx +151 -0
  667. package/src/components/layout/key-cap.tsx +15 -0
  668. package/src/components/layout/mobile-tab-bar.tsx +80 -157
  669. package/src/components/layout/shortcut-switch.tsx +32 -0
  670. package/src/components/layout/side-rail.tsx +70 -150
  671. package/src/components/layout/slide-panel.tsx +29 -2
  672. package/src/components/layout/theme.tsx +67 -0
  673. package/src/components/quick-actions/add-form.tsx +188 -0
  674. package/src/components/quick-actions/add-modal.tsx +32 -153
  675. package/src/components/quick-actions/search-modal.tsx +5 -3
  676. package/src/components/quick-actions/streaming-modal.tsx +42 -71
  677. package/src/components/quick-actions/streaming-output.tsx +112 -0
  678. package/src/components/quick-actions/whatsup-modal.tsx +38 -60
  679. package/src/components/settings/devices-agents-tab.tsx +60 -152
  680. package/src/components/settings/models-list.tsx +299 -0
  681. package/src/components/settings/models-tab.tsx +63 -337
  682. package/src/components/settings/one-time-agent-credential.tsx +1 -1
  683. package/src/components/settings/passkey-list.tsx +201 -0
  684. package/src/components/settings/passkey-tab.tsx +53 -197
  685. package/src/components/settings/pi-accounts-list.tsx +128 -0
  686. package/src/components/settings/pi-accounts.tsx +71 -170
  687. package/src/components/settings/principal-list.tsx +172 -0
  688. package/src/components/settings/settings-panel.tsx +232 -21
  689. package/src/components/settings/skills-list.tsx +276 -0
  690. package/src/components/settings/skills-tab.tsx +82 -269
  691. package/src/components/settings/tool-permissions-list.tsx +54 -0
  692. package/src/components/settings/tool-permissions.tsx +27 -46
  693. package/src/components/settings/web-search-chain.tsx +300 -0
  694. package/src/components/settings/web-search-settings.tsx +58 -328
  695. package/src/components/share/share-menu.tsx +19 -4
  696. package/src/components/voice/dictation-sheet.tsx +5 -5
  697. package/src/components/voice/mic-button.tsx +1 -1
  698. package/src/components/voice/review-card.tsx +1 -1
  699. package/src/config.ts +21 -7
  700. package/src/connection.ts +443 -0
  701. package/src/default-root.ts +16 -0
  702. package/src/hooks/use-color-scheme.ts +36 -0
  703. package/src/hooks/use-hash-routes.ts +4 -2
  704. package/src/hooks/use-media-query.ts +32 -0
  705. package/src/hooks/use-share-intake.ts +32 -12
  706. package/src/hooks/use-vpn-status.ts +18 -17
  707. package/src/hooks/use-websocket.ts +12 -428
  708. package/src/hooks/websocket-handlers/activity.ts +4 -5
  709. package/src/hooks/websocket-handlers/chat.ts +26 -5
  710. package/src/hooks/websocket-handlers/connection.ts +4 -6
  711. package/src/hooks/websocket-handlers/mask.ts +2 -3
  712. package/src/hooks/websocket-handlers/provider.ts +4 -6
  713. package/src/hooks/websocket-handlers/types.ts +6 -2
  714. package/src/index.ts +7 -3
  715. package/src/lib/api-client.ts +426 -384
  716. package/src/lib/backend.ts +20 -10
  717. package/src/lib/diff.ts +28 -62
  718. package/src/lib/light-dark.ts +83 -0
  719. package/src/lib/mermaid-theme.ts +183 -214
  720. package/src/lib/passkeys.ts +12 -4
  721. package/src/lib/push-registration.ts +19 -2
  722. package/src/lib/share-intake.ts +6 -3
  723. package/src/lib/share.ts +7 -4
  724. package/src/lib/single-key.ts +47 -0
  725. package/src/lib/tool-names.ts +31 -8
  726. package/src/root-context.tsx +40 -0
  727. package/src/root.ts +83 -0
  728. package/src/stores/activity-state.ts +295 -0
  729. package/src/stores/activity-store.ts +11 -285
  730. package/src/stores/chat-state.ts +795 -0
  731. package/src/stores/chat-store.ts +11 -705
  732. package/src/stores/connection-state.ts +78 -0
  733. package/src/stores/connection-store.ts +11 -76
  734. package/src/stores/create-stores.ts +31 -0
  735. package/src/stores/file-state.ts +399 -0
  736. package/src/stores/file-store.ts +9 -390
  737. package/src/stores/graph-state.ts +368 -0
  738. package/src/stores/graph-store.ts +10 -355
  739. package/src/stores/mask-state.ts +30 -0
  740. package/src/stores/mask-store.ts +10 -27
  741. package/src/stores/principal-state.ts +42 -0
  742. package/src/stores/principal-store.ts +10 -37
  743. package/src/stores/provider-state.ts +103 -0
  744. package/src/stores/provider-store.ts +10 -95
  745. package/src/stores/share-state.ts +56 -0
  746. package/src/stores/share-store.ts +11 -54
  747. package/src/stores/store-environment.ts +10 -0
  748. package/src/stores/ui-state.ts +143 -0
  749. package/src/stores/ui-store.ts +11 -93
  750. package/src/styles.css +4 -1
  751. package/src/theme.css +150 -97
  752. package/src/voice/asr-clients.ts +17 -17
  753. package/src/voice/use-dictation.ts +11 -8
  754. package/src/voice/voice-state.ts +57 -0
  755. package/src/voice/voice-store.ts +11 -55
@@ -0,0 +1,201 @@
1
+ import { Button, Chip, Placeholder } from "@schlessera/brain-ui-kit";
2
+ import { Check, Fingerprint, Pencil, Trash2, X } from "lucide-react";
3
+ import type { PasskeySummary } from "@schlessera/brain-ui-sdk/protocol";
4
+ import { useState } from "react";
5
+
6
+ /**
7
+ * The Security tab's surface, rendered from props (S6). `PasskeyTab` is the
8
+ * container: it owns the list request, the registration ceremony, the
9
+ * per-root abort signal and the confirm dialog; this owns what is on screen.
10
+ *
11
+ * `status` is the three-way answer the list request gives: `loading` while
12
+ * it is in flight, `ready` when the server is in password mode, and
13
+ * `unavailable` when it is not (a 400 from the list route, or anything else
14
+ * that degrades the same way). The Add button appears only when passkeys are
15
+ * possible here — server mode AND a browser that can do WebAuthn.
16
+ *
17
+ * The Add and Sign-out buttons are the kit's. The per-row rename and remove
18
+ * controls stay native icon buttons: the kit has no icon-only button and a
19
+ * `ListRow`'s trailing action is decorative. Rename state (which row is being
20
+ * edited, the draft) is the row's own and never leaves the view.
21
+ */
22
+ export type PasskeyStatus = "loading" | "ready" | "unavailable";
23
+
24
+ export interface PasskeyListProps {
25
+ credentials: PasskeySummary[];
26
+ status: PasskeyStatus;
27
+ /** A registration ceremony is in flight. */
28
+ busy: boolean;
29
+ error: string | null;
30
+ /** The browser can do WebAuthn at all. */
31
+ supported: boolean;
32
+ /** The hostname this page is served from; a credential registered elsewhere is badged. */
33
+ hostname: string;
34
+ onAdd: () => void;
35
+ onRename: (id: string, label: string) => void;
36
+ onDelete: (id: string) => void;
37
+ onSignOut: () => void;
38
+ }
39
+
40
+ export function PasskeyList(p: PasskeyListProps) {
41
+ const canAdd = p.status === "ready" && p.supported;
42
+ return (
43
+ <div className="flex h-full flex-col">
44
+ <div className="flex-1 overflow-y-auto p-4">
45
+ <h3 className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
46
+ Passkeys
47
+ </h3>
48
+ <p className="mt-1 text-xs text-muted-foreground">
49
+ Sign in with Face ID, fingerprint, or a security key instead of the
50
+ password. Passkeys only work on the site they were added on.
51
+ </p>
52
+
53
+ {p.status === "loading" ? (
54
+ <div className="mt-4">
55
+ <Placeholder variant="loading" lines={2} />
56
+ </div>
57
+ ) : (
58
+ <ul className="mt-4 flex flex-col gap-2">
59
+ {p.credentials.map((credential) => (
60
+ <PasskeyRow
61
+ key={credential.id}
62
+ credential={credential}
63
+ foreign={credential.rpId !== p.hostname}
64
+ onDelete={() => p.onDelete(credential.id)}
65
+ onRename={(label) => p.onRename(credential.id, label)}
66
+ />
67
+ ))}
68
+ {p.credentials.length === 0 && p.status === "ready" && (
69
+ <li>
70
+ <Placeholder variant="empty" message="No passkeys yet." icon="passkey" />
71
+ </li>
72
+ )}
73
+ </ul>
74
+ )}
75
+
76
+ {p.error && (
77
+ <p role="alert" className="mt-3 text-xs text-destructive">
78
+ {p.error}
79
+ </p>
80
+ )}
81
+
82
+ {canAdd ? (
83
+ <div className="mt-4">
84
+ <Button
85
+ label={p.busy ? "Adding a passkey…" : "Add a passkey"}
86
+ icon="add"
87
+ tone="primary"
88
+ size="md"
89
+ center
90
+ disabled={p.busy}
91
+ onClick={p.onAdd}
92
+ />
93
+ </div>
94
+ ) : (
95
+ <p className="mt-4 text-xs text-muted-foreground">
96
+ {p.status === "unavailable"
97
+ ? "Passkeys need password auth mode on the server."
98
+ : "This browser does not support passkeys."}
99
+ </p>
100
+ )}
101
+ </div>
102
+
103
+ {/* Sign out everywhere */}
104
+ <div className="border-t border-border p-4">
105
+ <Button label="Sign out everywhere" icon="hand" tone="danger" size="md" center onClick={p.onSignOut} />
106
+ </div>
107
+ </div>
108
+ );
109
+ }
110
+
111
+ function PasskeyRow({
112
+ credential,
113
+ foreign,
114
+ onDelete,
115
+ onRename,
116
+ }: {
117
+ credential: PasskeySummary;
118
+ foreign: boolean;
119
+ onDelete: () => void;
120
+ onRename: (label: string) => void;
121
+ }) {
122
+ const [editing, setEditing] = useState(false);
123
+ const [draft, setDraft] = useState(credential.label);
124
+
125
+ const displayName =
126
+ credential.label ||
127
+ `Passkey · ${new Date(credential.createdAt).toLocaleDateString()}`;
128
+
129
+ function commit() {
130
+ setEditing(false);
131
+ const label = draft.trim();
132
+ if (label !== credential.label) onRename(label);
133
+ }
134
+
135
+ return (
136
+ <li className="rounded-lg border border-border-subtle bg-surface p-3">
137
+ <div className="flex items-center gap-2">
138
+ <Fingerprint className="h-4 w-4 shrink-0 text-primary" />
139
+ {editing ? (
140
+ <span className="flex flex-1 items-center gap-1">
141
+ <input
142
+ autoFocus
143
+ value={draft}
144
+ aria-label="Passkey name"
145
+ onChange={(e) => setDraft(e.target.value)}
146
+ onKeyDown={(e) => {
147
+ if (e.key === "Enter") commit();
148
+ if (e.key === "Escape") setEditing(false);
149
+ }}
150
+ className="w-full rounded border border-border-subtle bg-background px-2 py-0.5 text-sm text-foreground outline-none focus:border-primary"
151
+ />
152
+ <button type="button" onClick={commit} title="Save" className="p-1 text-muted-foreground hover:text-foreground">
153
+ <Check className="h-3.5 w-3.5" />
154
+ </button>
155
+ <button type="button" onClick={() => setEditing(false)} title="Cancel" className="p-1 text-muted-foreground hover:text-foreground">
156
+ <X className="h-3.5 w-3.5" />
157
+ </button>
158
+ </span>
159
+ ) : (
160
+ <span className="flex-1 truncate text-sm text-foreground">{displayName}</span>
161
+ )}
162
+ {!editing && (
163
+ <>
164
+ <button
165
+ type="button"
166
+ onClick={() => {
167
+ setDraft(credential.label);
168
+ setEditing(true);
169
+ }}
170
+ title="Rename"
171
+ className="p-1 text-muted-foreground transition-colors hover:text-foreground"
172
+ >
173
+ <Pencil className="h-3.5 w-3.5" />
174
+ </button>
175
+ <button
176
+ type="button"
177
+ onClick={onDelete}
178
+ title="Remove"
179
+ className="p-1 text-muted-foreground transition-colors hover:text-destructive"
180
+ >
181
+ <Trash2 className="h-3.5 w-3.5" />
182
+ </button>
183
+ </>
184
+ )}
185
+ </div>
186
+ <div className="mt-1.5 flex flex-wrap items-center gap-x-2 gap-y-1 pl-6 text-[11px] text-muted-foreground">
187
+ {credential.backedUp && <Chip label="synced" variant="kv" tone="teal" />}
188
+ {foreign && (
189
+ <span title={`Registered on ${credential.rpId}; only usable there.`} className="flex">
190
+ <Chip label={credential.rpId} variant="mono" tone="neutral" />
191
+ </span>
192
+ )}
193
+ <span>
194
+ {credential.lastUsedAt
195
+ ? `Last used ${new Date(credential.lastUsedAt).toLocaleDateString()}`
196
+ : `Added ${new Date(credential.createdAt).toLocaleDateString()}`}
197
+ </span>
198
+ </div>
199
+ </li>
200
+ );
201
+ }
@@ -1,19 +1,8 @@
1
- import { useEffect, useState } from "react";
2
- import {
3
- Check,
4
- Cloud,
5
- Fingerprint,
6
- Loader2,
7
- LogOut,
8
- Pencil,
9
- Plus,
10
- Trash2,
11
- X,
12
- } from "lucide-react";
1
+ import { useCallback, useEffect, useRef, useState } from "react";
13
2
  import type { PasskeySummary } from "@schlessera/brain-ui-sdk/protocol";
14
- import { api } from "../../lib/api-client.js";
3
+ import { useBrainUiRoot } from "../../root-context.js";
15
4
  import { isUserCancel, registerPasskey, supportsPasskeys } from "../../lib/passkeys.js";
16
- import { cn } from "../../lib/utils.js";
5
+ import { PasskeyList } from "./passkey-list.js";
17
6
 
18
7
  /**
19
8
  * Passkey management + sign out — the Security tab of the settings panel.
@@ -23,8 +12,15 @@ import { cn } from "../../lib/utils.js";
23
12
  *
24
13
  * `active` is "this tab is on screen": the list reloads when it becomes visible
25
14
  * rather than on mount, so switching tabs picks up changes made elsewhere.
15
+ *
16
+ * This is the container (S6): the request, the ceremony, the per-root abort
17
+ * signal and the confirm dialog live here; `PasskeyList` draws from props.
26
18
  */
27
19
  export function PasskeyTab({ active }: { active: boolean }) {
20
+ const root = useBrainUiRoot();
21
+ const api = root.api;
22
+ const lifetime = useRef(new AbortController());
23
+ const listRequest = useRef(0);
28
24
  const [credentials, setCredentials] = useState<PasskeySummary[]>([]);
29
25
  const [loading, setLoading] = useState(false);
30
26
  const [busy, setBusy] = useState(false);
@@ -33,244 +29,104 @@ export function PasskeyTab({ active }: { active: boolean }) {
33
29
 
34
30
  const webAuthnSupported = supportsPasskeys();
35
31
 
36
- async function refresh() {
32
+ const refresh = useCallback(async () => {
33
+ const signal = lifetime.current.signal;
34
+ const request = ++listRequest.current;
35
+ const current = () => !signal.aborted && request === listRequest.current;
37
36
  setLoading(true);
38
37
  try {
39
38
  const data = await api.passkeyList();
39
+ if (!current()) return;
40
40
  setCredentials(data.credentials);
41
41
  setPasskeyMode(true);
42
42
  } catch {
43
+ if (!current()) return;
43
44
  // 400 = server not in password mode; anything else degrades the same way.
44
45
  setPasskeyMode(false);
45
46
  setCredentials([]);
46
47
  } finally {
47
- setLoading(false);
48
+ if (current()) setLoading(false);
48
49
  }
49
- }
50
+ }, [api]);
50
51
 
51
52
  useEffect(() => {
52
- if (active) {
53
- setError(null);
54
- void refresh();
55
- }
56
- }, [active]);
53
+ const controller = new AbortController();
54
+ lifetime.current = controller;
55
+ setCredentials([]);
56
+ setLoading(false);
57
+ setBusy(false);
58
+ setError(null);
59
+ setPasskeyMode(true);
60
+ if (active) void refresh();
61
+ return () => controller.abort();
62
+ }, [active, root, refresh]);
57
63
 
58
64
  async function onAdd() {
59
65
  if (busy) return;
66
+ const signal = lifetime.current.signal;
60
67
  setBusy(true);
61
68
  setError(null);
62
69
  try {
63
- await registerPasskey();
70
+ await registerPasskey(api, undefined, signal);
71
+ if (signal.aborted) return;
64
72
  await refresh();
65
73
  } catch (err) {
66
- if (!isUserCancel(err)) {
74
+ if (!signal.aborted && !isUserCancel(err)) {
67
75
  setError(err instanceof Error ? err.message : "Registration failed");
68
76
  }
69
77
  } finally {
70
- setBusy(false);
78
+ if (!signal.aborted) setBusy(false);
71
79
  }
72
80
  }
73
81
 
74
82
  async function onDelete(id: string) {
75
83
  if (!window.confirm("Remove this passkey? You can't undo this.")) return;
84
+ const signal = lifetime.current.signal;
76
85
  setError(null);
77
86
  try {
78
87
  await api.passkeyDelete(id);
88
+ if (signal.aborted) return;
79
89
  setCredentials((rows) => rows.filter((row) => row.id !== id));
80
90
  } catch (err) {
81
- setError(err instanceof Error ? err.message : "Delete failed");
91
+ if (!signal.aborted) setError(err instanceof Error ? err.message : "Delete failed");
82
92
  }
83
93
  }
84
94
 
85
95
  async function onRename(id: string, label: string) {
96
+ const signal = lifetime.current.signal;
86
97
  setError(null);
87
98
  try {
88
99
  await api.passkeyRename(id, label);
100
+ if (signal.aborted) return;
89
101
  setCredentials((rows) =>
90
102
  rows.map((row) => (row.id === id ? { ...row, label } : row))
91
103
  );
92
104
  } catch (err) {
93
- setError(err instanceof Error ? err.message : "Rename failed");
105
+ if (!signal.aborted) setError(err instanceof Error ? err.message : "Rename failed");
94
106
  }
95
107
  }
96
108
 
97
109
  async function onSignOut() {
110
+ const signal = lifetime.current.signal;
98
111
  try {
99
112
  await api.logout();
100
113
  } finally {
101
- window.location.reload();
114
+ if (!signal.aborted) window.location.reload();
102
115
  }
103
116
  }
104
117
 
105
118
  return (
106
- <div className="flex h-full flex-col">
107
- <div className="flex-1 overflow-y-auto p-4">
108
- <h3 className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
109
- Passkeys
110
- </h3>
111
- <p className="mt-1 text-xs text-muted-foreground">
112
- Sign in with Face ID, fingerprint, or a security key instead of the
113
- password. Passkeys only work on the site they were added on.
114
- </p>
115
-
116
- {loading ? (
117
- <div className="mt-6 flex justify-center">
118
- <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
119
- </div>
120
- ) : (
121
- <ul className="mt-4 flex flex-col gap-2">
122
- {credentials.map((credential) => (
123
- <PasskeyRow
124
- key={credential.id}
125
- credential={credential}
126
- onDelete={() => onDelete(credential.id)}
127
- onRename={(label) => onRename(credential.id, label)}
128
- />
129
- ))}
130
- {credentials.length === 0 && passkeyMode && (
131
- <li className="rounded-lg border border-dashed border-border-subtle p-4 text-center text-xs text-muted-foreground">
132
- No passkeys yet.
133
- </li>
134
- )}
135
- </ul>
136
- )}
137
-
138
- {error && (
139
- <p role="alert" className="mt-3 text-xs text-destructive">
140
- {error}
141
- </p>
142
- )}
143
-
144
- {passkeyMode && webAuthnSupported ? (
145
- <button
146
- onClick={onAdd}
147
- disabled={busy}
148
- className="mt-4 flex w-full items-center justify-center gap-2 rounded-lg bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:brightness-110 disabled:opacity-50"
149
- >
150
- {busy ? (
151
- <Loader2 className="h-4 w-4 animate-spin" />
152
- ) : (
153
- <Plus className="h-4 w-4" />
154
- )}
155
- Add a passkey
156
- </button>
157
- ) : (
158
- <p className="mt-4 text-xs text-muted-foreground">
159
- {passkeyMode
160
- ? "This browser does not support passkeys."
161
- : "Passkeys need password auth mode on the server."}
162
- </p>
163
- )}
164
- </div>
165
-
166
- {/* Sign out everywhere */}
167
- <div className="border-t border-border p-4">
168
- <button
169
- onClick={onSignOut}
170
- className="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-destructive hover:text-destructive"
171
- >
172
- <LogOut className="h-4 w-4" />
173
- Sign out everywhere
174
- </button>
175
- </div>
176
- </div>
177
- );
178
- }
179
-
180
- function PasskeyRow({
181
- credential,
182
- onDelete,
183
- onRename,
184
- }: {
185
- credential: PasskeySummary;
186
- onDelete: () => void;
187
- onRename: (label: string) => void;
188
- }) {
189
- const [editing, setEditing] = useState(false);
190
- const [draft, setDraft] = useState(credential.label);
191
- const foreignRp =
192
- typeof window !== "undefined" && credential.rpId !== window.location.hostname;
193
-
194
- const displayName =
195
- credential.label ||
196
- `Passkey · ${new Date(credential.createdAt).toLocaleDateString()}`;
197
-
198
- function commit() {
199
- setEditing(false);
200
- const label = draft.trim();
201
- if (label !== credential.label) onRename(label);
202
- }
203
-
204
- return (
205
- <li className="rounded-lg border border-border-subtle bg-surface p-3">
206
- <div className="flex items-center gap-2">
207
- <Fingerprint className="h-4 w-4 shrink-0 text-primary" />
208
- {editing ? (
209
- <span className="flex flex-1 items-center gap-1">
210
- <input
211
- autoFocus
212
- value={draft}
213
- onChange={(e) => setDraft(e.target.value)}
214
- onKeyDown={(e) => {
215
- if (e.key === "Enter") commit();
216
- if (e.key === "Escape") setEditing(false);
217
- }}
218
- className="w-full rounded border border-border-subtle bg-background px-2 py-0.5 text-sm text-foreground outline-none focus:border-primary"
219
- />
220
- <button onClick={commit} title="Save" className="p-1 text-muted-foreground hover:text-foreground">
221
- <Check className="h-3.5 w-3.5" />
222
- </button>
223
- <button onClick={() => setEditing(false)} title="Cancel" className="p-1 text-muted-foreground hover:text-foreground">
224
- <X className="h-3.5 w-3.5" />
225
- </button>
226
- </span>
227
- ) : (
228
- <span className="flex-1 truncate text-sm text-foreground">{displayName}</span>
229
- )}
230
- {!editing && (
231
- <>
232
- <button
233
- onClick={() => {
234
- setDraft(credential.label);
235
- setEditing(true);
236
- }}
237
- title="Rename"
238
- className="p-1 text-muted-foreground transition-colors hover:text-foreground"
239
- >
240
- <Pencil className="h-3.5 w-3.5" />
241
- </button>
242
- <button
243
- onClick={onDelete}
244
- title="Remove"
245
- className="p-1 text-muted-foreground transition-colors hover:text-destructive"
246
- >
247
- <Trash2 className="h-3.5 w-3.5" />
248
- </button>
249
- </>
250
- )}
251
- </div>
252
- <div className="mt-1.5 flex flex-wrap items-center gap-x-3 gap-y-1 pl-6 text-[11px] text-muted-foreground">
253
- {credential.backedUp && (
254
- <span className="flex items-center gap-1">
255
- <Cloud className="h-3 w-3" /> Synced
256
- </span>
257
- )}
258
- {foreignRp && (
259
- <span
260
- className={cn(
261
- "rounded bg-surface-raised px-1.5 py-0.5 font-medium text-foreground/70"
262
- )}
263
- title={`Registered on ${credential.rpId}; only usable there.`}
264
- >
265
- {credential.rpId}
266
- </span>
267
- )}
268
- <span>
269
- {credential.lastUsedAt
270
- ? `Last used ${new Date(credential.lastUsedAt).toLocaleDateString()}`
271
- : `Added ${new Date(credential.createdAt).toLocaleDateString()}`}
272
- </span>
273
- </div>
274
- </li>
119
+ <PasskeyList
120
+ credentials={credentials}
121
+ status={loading ? "loading" : passkeyMode ? "ready" : "unavailable"}
122
+ busy={busy}
123
+ error={error}
124
+ supported={webAuthnSupported}
125
+ hostname={typeof window !== "undefined" ? window.location.hostname : ""}
126
+ onAdd={() => void onAdd()}
127
+ onRename={(id, label) => void onRename(id, label)}
128
+ onDelete={(id) => void onDelete(id)}
129
+ onSignOut={() => void onSignOut()}
130
+ />
275
131
  );
276
132
  }
@@ -0,0 +1,128 @@
1
+ import { Button, Callout, ListRow, StatusDot } from "@schlessera/brain-ui-kit";
2
+ import type { PiAuthProviderStatus, PiLoginFlow } from "../../lib/api-client.js";
3
+
4
+ /**
5
+ * Provider accounts, rendered from props (S7, the `settings` directory).
6
+ * `PiAccountsSection` is the container: the providers request, the login
7
+ * flow and its polling, the cancel and the disconnect live there; this
8
+ * draws the rows and the device-code card.
9
+ *
10
+ * A provider is a kit card `ListRow` with its state as the trailing value
11
+ * (teal "connected"); Connect and Disconnect are kit `Button`s beside it.
12
+ * The pending flow is an amber `Callout` carrying the code the user types
13
+ * at the provider's page — the verification link stays an anchor, because
14
+ * a link is what it is — and the settled flow is a teal or red `Callout`
15
+ * with a dismiss.
16
+ */
17
+ export interface AccountsListProps {
18
+ providers: PiAuthProviderStatus[];
19
+ /** The provider whose connect or disconnect is in flight. */
20
+ busy: string | null;
21
+ flow: PiLoginFlow | null;
22
+ error: string | null;
23
+ onConnect: (providerId: string) => void;
24
+ onDisconnect: (providerId: string) => void;
25
+ onCancelFlow: () => void;
26
+ onDismissFlow: () => void;
27
+ }
28
+
29
+ export function AccountsList(p: AccountsListProps) {
30
+ const pending = p.flow?.status === "pending";
31
+ return (
32
+ <div className="mt-6">
33
+ <h3 className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
34
+ Accounts
35
+ </h3>
36
+ <p className="mt-1 text-xs text-muted-foreground">
37
+ Model providers that sign in with an account instead of an API key.
38
+ </p>
39
+ <ul className="mt-4 flex flex-col gap-2">
40
+ {p.providers.map((provider) => (
41
+ <li key={provider.providerId} className="flex flex-col gap-2">
42
+ <div className="flex items-center gap-2">
43
+ <div className="min-w-0 flex-1">
44
+ <ListRow
45
+ variant="card"
46
+ icon="model"
47
+ iconTone={provider.configured ? "teal" : "neutral"}
48
+ title={provider.name}
49
+ subtitle={provider.configured ? `Connected${provider.source ? ` · ${provider.source}` : ""}` : "Not connected"}
50
+ value={provider.configured ? "connected" : undefined}
51
+ valueTone="teal"
52
+ />
53
+ </div>
54
+ {provider.oauth && !provider.configured && (
55
+ <Button
56
+ label={p.busy === provider.providerId ? "Connecting…" : "Connect"}
57
+ icon="passkey"
58
+ tone="ghost"
59
+ size="sm"
60
+ block={false}
61
+ disabled={p.busy !== null || pending}
62
+ onClick={() => p.onConnect(provider.providerId)}
63
+ />
64
+ )}
65
+ {provider.configured && provider.source === "stored" && (
66
+ <span title="Disconnect" className="flex">
67
+ <Button label="Disconnect" icon="hand" tone="quiet" size="sm" block={false} disabled={p.busy !== null} onClick={() => p.onDisconnect(provider.providerId)} />
68
+ </span>
69
+ )}
70
+ </div>
71
+ {p.flow && p.flow.providerId === provider.providerId && (
72
+ <LoginFlowCard flow={p.flow} onCancel={p.onCancelFlow} onDismiss={p.onDismissFlow} />
73
+ )}
74
+ </li>
75
+ ))}
76
+ </ul>
77
+ {p.error && (
78
+ <div role="alert" className="mt-3">
79
+ <Callout tone="red" variant="banner" icon="failed" mono text={p.error} />
80
+ </div>
81
+ )}
82
+ </div>
83
+ );
84
+ }
85
+
86
+ function LoginFlowCard({ flow, onCancel, onDismiss }: { flow: PiLoginFlow; onCancel: () => void; onDismiss: () => void }) {
87
+ if (flow.status === "pending") {
88
+ return (
89
+ <Callout tone="amber" variant="boxed" icon="passkey">
90
+ <div className="flex flex-col gap-2">
91
+ <p className="text-xs text-muted-foreground">
92
+ Enter this code at the provider's device page — on this or any other device:
93
+ </p>
94
+ <p className="select-all text-center font-[family-name:var(--font-mono)] text-xl font-semibold tracking-widest text-foreground">
95
+ {flow.userCode ?? "…"}
96
+ </p>
97
+ <div className="flex flex-wrap items-center justify-center gap-2">
98
+ {flow.verificationUri && (
99
+ <a
100
+ href={flow.verificationUri}
101
+ target="_blank"
102
+ rel="noreferrer"
103
+ className="flex items-center gap-1.5 rounded-[9px] bg-[var(--bk-amber-fill)] px-3 py-1.5 text-[11.5px] font-semibold text-[var(--bk-on-fill)] transition-[filter] hover:brightness-110"
104
+ >
105
+ Open verification page ↗
106
+ </a>
107
+ )}
108
+ <Button label="Cancel" icon="cancel" tone="quiet" size="sm" block={false} onClick={onCancel} />
109
+ </div>
110
+ <p className="flex items-center justify-center gap-1.5 text-center text-[11px] text-muted-foreground" aria-live="polite">
111
+ <StatusDot tone="amber" pulse size={6} />
112
+ Waiting for approval…
113
+ </p>
114
+ </div>
115
+ </Callout>
116
+ );
117
+ }
118
+ const ok = flow.status === "success";
119
+ const message = ok ? "Connected." : flow.status === "cancelled" ? "Login cancelled." : flow.error ?? "Login failed.";
120
+ return (
121
+ <div className="flex items-center gap-2">
122
+ <div className="min-w-0 flex-1">
123
+ <Callout tone={ok ? "teal" : "red"} variant="banner" icon={ok ? "confirm" : "failed"} mono text={message} />
124
+ </div>
125
+ <Button label="Dismiss" tone="quiet" size="sm" block={false} onClick={onDismiss} />
126
+ </div>
127
+ );
128
+ }