@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,40 +1,53 @@
1
- import { useEffect, useMemo, useState } from "react";
2
- import {
3
- Activity as ActivityIcon,
4
- AlertTriangle,
5
- RefreshCw,
6
- Timer,
7
- } from "lucide-react";
1
+ import { useBrainUiRoot } from "../../root-context.js";
2
+ import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent } from "react";
3
+ import { Activity as ActivityIcon, AlertTriangle, RefreshCw } from "lucide-react";
8
4
  import type { ActivitySpan } from "@schlessera/brain-ui-sdk/protocol";
9
5
 
10
- import {
11
- api,
12
- type ActivityIntent,
13
- type ActivityRollups,
14
- type ActivityRunSummary,
6
+ import type {
7
+ ActivityIntent,
8
+ ActivityRollups,
9
+ ActivityRunSummary,
15
10
  } from "../../lib/api-client.js";
16
- import { sendClientMessage } from "../../hooks/use-websocket.js";
17
11
  import { useActivityStore } from "../../stores/activity-store.js";
18
- import { useChatStore } from "../../stores/chat-store.js";
19
- import { useUIStore } from "../../stores/ui-store.js";
12
+ import { useChatStore, pendingApprovals } from "../../stores/chat-store.js";
13
+ import { EmptyState, FilterRow, InlineToast, Label } from "@schlessera/brain-ui-kit";
20
14
  import { cn } from "../../lib/utils.js";
15
+ import { ApprovalCard } from "./approval-card.js";
16
+ import { useUIStore } from "../../stores/ui-store.js";
21
17
  import { formatRelativeTime } from "../chat/tool-views.js";
22
18
  import { RollupCards } from "./activity-rollups.js";
23
19
  import { LiveRow, RunRow } from "./activity-run-list.js";
24
- import { RunDetail } from "./activity-run-detail.js";
20
+ import { RunDetail, RunTraceSteps } from "./activity-run-detail.js";
21
+ import { IntentCard } from "./activity-views.js";
22
+ import { focusAfterDecision, singleKey } from "../../lib/single-key.js";
25
23
  import { PushToggle } from "./push-toggle.js";
26
24
  import { SettingsPanel } from "../settings/settings-panel.js";
27
25
 
28
26
  /**
29
- * The Activity surface: an INDEX of all agent activity live runs first,
30
- * then history with cost/token rollups. Deliberately not a residence:
31
- * a session run deep-links back into its chat, a subagent into the drill-in
32
- * stack; only a cron run (which has no chat around it) details here.
27
+ * The Actions surface (D37): one queue, three lenses`needs you` (pending
28
+ * approvals from every transcript, then the inbox), `running` (live runs),
29
+ * `done` (history and the rollups). "What needs me" and "what has been
30
+ * happening" are two lenses on one queue, so the rail has one destination
31
+ * and this page has a filter. Deliberately not a residence: a session run
32
+ * deep-links back into its chat, a subagent into the drill-in stack; only a
33
+ * cron run (which has no chat around it) details here.
33
34
  *
34
35
  * Live rows ride the index-view activity subscription while this surface is
35
- * open; history and rollups come from the REST activity API.
36
+ * open; history and rollups come from the REST activity API. The hash stays
37
+ * `#/activity` — the route is a contract with push notifications.
38
+ *
39
+ * Panes (D4): below `laptop:` the run detail replaces the queue, as on the
40
+ * phone. From `laptop:` the queue is a 360px list column beside the detail
41
+ * pane, and from `wide:` a 300px evidence rail on the right carries the
42
+ * run's trace and the last decision's receipt. Each pane scrolls on its own.
43
+ * The detail is one element at every width — the list hides under it below
44
+ * `laptop:` — so a deep link selects the same run everywhere.
36
45
  */
46
+ export type ActionsLens = "needs-you" | "running" | "done";
37
47
  export function ActivityPage() {
48
+ const root = useBrainUiRoot();
49
+ const api = root.api;
50
+ const request = useRef(0);
38
51
  const supported = useActivityStore((s) => s.supported);
39
52
  const connectionEpoch = useActivityStore((s) => s.connectionEpoch);
40
53
  const liveSpans = useActivityStore((s) => s.spans);
@@ -50,39 +63,80 @@ export function ActivityPage() {
50
63
  const [pricingStale, setPricingStale] = useState(false);
51
64
 
52
65
  const inbox = useActivityStore((s) => s.inbox);
66
+ // Derived from the buffer references, not selected as a fresh array: a
67
+ // selector returning a new array every call re-renders without end.
68
+ const buffers = useChatStore((s) => s.buffers);
69
+ const draft = useChatStore((s) => s.draft);
70
+ const approvals = useMemo(() => pendingApprovals({ buffers, draft }), [buffers, draft]);
71
+ const resolveToolApproval = useChatStore((s) => s.resolveToolApproval);
72
+ /**
73
+ * The lens the reader picked, or — until they pick one — the one that has
74
+ * something in it: what needs you, else what is running, else what is
75
+ * done. A page that opens on an empty "needs you" when a run is live would
76
+ * be reassurance in the wrong place.
77
+ */
78
+ const [picked, setLens] = useState<ActionsLens | null>(null);
79
+ /**
80
+ * The receipt for the last DECISION — Allowed, Always allowed, Denied —
81
+ * shown above the `EmptyState` that replaces a drained section (D37) and
82
+ * in the evidence rail: a keyboard user is told "that is done" instead of
83
+ * being dropped at the document top. A decision earns a toast by the
84
+ * sixth pass's own criterion (§4: "a toast is for effects you can take
85
+ * back or that happen out of sight"): its effect happens in the run, out
86
+ * of sight, and the card leaving says nothing about what the run did
87
+ * with the answer.
88
+ *
89
+ * A DISMISSAL sets no receipt. Acknowledging an inbox item is neither —
90
+ * it cannot be taken back (the activity API has no un-acknowledge) and
91
+ * the row vanishing under the cursor is the whole effect. An `InlineToast`
92
+ * whose point is Undo, shipped without Undo, "teaches that the kit's
93
+ * receipts are decorative"; so until un-acknowledge exists, dismissal is
94
+ * silent and the row leaving the list is the receipt. Grow un-acknowledge
95
+ * and the toast returns with its Undo.
96
+ */
97
+ const [receipt, setReceipt] = useState<{ text: string; target: string; effect: string } | null>(null);
98
+ const [drained, setDrained] = useState(false);
53
99
  const loadInbox = useActivityStore((s) => s.loadInbox);
54
100
  const acknowledgeIntent = useActivityStore((s) => s.acknowledgeIntent);
55
101
  const acknowledgeAllIntents = useActivityStore((s) => s.acknowledgeAllIntents);
56
102
 
57
- const refresh = () => {
58
- api
59
- .activityRuns({ limit: 100 })
60
- .then(setRuns)
61
- .catch((err) => setError(err instanceof Error ? err.message : String(err)));
62
- api.activityRollups(7).then(setRollups).catch(() => {});
63
- // Surface the pricing warning only when the table is stale AND refreshes
64
- // are failing — a merely-aging table heals itself. A rejection (including
65
- // 404 from a server that predates the route) means no signal: stay quiet.
66
- api
67
- .pricingState()
68
- .then((s) => setPricingStale(Boolean(s.stale && s.error)))
69
- .catch(() => setPricingStale(false));
103
+ const refresh = useCallback(() => {
104
+ const token = ++request.current;
105
+ const current = () => token === request.current;
106
+ setError(null);
107
+ api.activityRuns({ limit: 100 })
108
+ .then((runs) => { if (current()) setRuns(runs); })
109
+ .catch((err) => { if (current()) setError(err instanceof Error ? err.message : String(err)); });
110
+ api.activityRollups(7)
111
+ .then((rollups) => { if (current()) setRollups(rollups); })
112
+ .catch(() => {});
113
+ // A stale table is only a warning while refreshes are failing. Older
114
+ // servers have no pricing route, so a rejection remains a quiet state.
115
+ api.pricingState()
116
+ .then((s) => { if (current()) setPricingStale(Boolean(s.stale && s.error)); })
117
+ .catch(() => { if (current()) setPricingStale(false); });
70
118
  void loadInbox();
71
- };
119
+ }, [api, loadInbox]);
72
120
 
73
- // Re-runs on every reconnect (connectionEpoch): the new socket has no
74
- // server-side subscriptions, and the REST refresh heals whatever finished
75
- // while disconnected.
121
+ useEffect(() => {
122
+ setRuns(null);
123
+ setRollups(null);
124
+ setError(null);
125
+ setPricingStale(false);
126
+ setDetailRunId(null);
127
+ }, [root]);
128
+
129
+ // Reconnects heal the REST snapshot and establish a new subscription.
130
+ // Cleanup also invalidates responses from the old root or request generation.
76
131
  useEffect(() => {
77
132
  refresh();
78
- if (supported) {
79
- sendClientMessage({ type: "activity_subscribe", view: "index" });
80
- return () => {
81
- sendClientMessage({ type: "activity_unsubscribe", view: "index" });
82
- };
83
- }
84
- return undefined;
85
- }, [supported, connectionEpoch]);
133
+ if (supported) root.connection.send({ type: "activity_subscribe", view: "index" });
134
+ const invalidate = () => { request.current++; };
135
+ return () => {
136
+ invalidate();
137
+ if (supported) root.connection.send({ type: "activity_unsubscribe", view: "index" });
138
+ };
139
+ }, [supported, connectionEpoch, root, refresh]);
86
140
 
87
141
  // Deep-link consumer: `#/activity/<runId>` (the push notification landing
88
142
  // spot — the shell routes it here but leaves the hash intact) opens that
@@ -154,12 +208,55 @@ export function ActivityPage() {
154
208
  }
155
209
  }
156
210
 
157
- if (detailRunId) {
158
- return <RunDetail runId={detailRunId} onBack={() => showDetail(null)} />;
211
+ const keys = useUIStore((s) => s.singleKeyShortcuts);
212
+ const INTENT_CARD = "[data-intent-card] > [role=\"button\"]";
213
+ /**
214
+ * `j` / `k` move inside the focused list and `d` dismisses the focused
215
+ * card (D36): all three act only while a card in this list holds focus,
216
+ * and the footer prints them. After a dismiss, focus goes to the next
217
+ * card, else the previous, else the page heading.
218
+ */
219
+ function onInboxKeyDown(event: KeyboardEvent<HTMLDivElement>) {
220
+ if (!keys) return;
221
+ const key = singleKey(event);
222
+ if (key !== "j" && key !== "k" && key !== "d") return;
223
+ const cards = [...event.currentTarget.querySelectorAll<HTMLElement>(INTENT_CARD)];
224
+ const here = cards.findIndex((card) => card.contains(event.target as Node));
225
+ if (here === -1) return;
226
+ event.preventDefault();
227
+ if (key === "d") {
228
+ const intent = inbox[here];
229
+ focusAfterDecision(cards[here]!, INTENT_CARD, "[data-needs-you-heading]");
230
+ if (intent) dismiss(intent);
231
+ return;
232
+ }
233
+ cards[(here + (key === "j" ? 1 : -1) + cards.length) % cards.length]?.focus();
234
+ }
235
+
236
+ /** Silent by rule (see `receipt`): the row leaving is the receipt. `drained`
237
+ * still flips so the empty state's heading takes focus after the last one. */
238
+ function dismiss(intent: ActivityIntent) {
239
+ setDrained(inbox.length + approvals.length <= 1);
240
+ void acknowledgeIntent(intent.id);
241
+ }
242
+ function dismissAll() {
243
+ setDrained(approvals.length === 0);
244
+ void acknowledgeAllIntents();
159
245
  }
246
+ function decideApproval(key: string | null, toolUseId: string, approved: boolean, always?: boolean) {
247
+ const tool = approvals.find((a) => a.tool.id === toolUseId)?.tool;
248
+ setReceipt({ text: approved ? (always ? "Always allowed" : "Allowed") : "Denied", target: tool ? tool.name : toolUseId, effect: always ? "write_policy" : approved ? "tool_approval" : "tool_denial" });
249
+ setDrained(inbox.length + approvals.length <= 1);
250
+ resolveToolApproval(key, toolUseId, approved);
251
+ if (approved) root.connection.send({ type: "tool_approval", toolUseId, ...(always ? { always: true } : {}) });
252
+ else root.connection.send({ type: "tool_denial", toolUseId, message: "Denied by user" });
253
+ }
254
+ const needsYouCount = inbox.length + approvals.length;
255
+ const runningCount = liveRoots.length + restLive.length;
256
+ const lens: ActionsLens = picked ?? (needsYouCount > 0 || drained ? "needs-you" : runningCount > 0 ? "running" : "done");
160
257
 
161
258
  return (
162
- <div className="flex h-full flex-col overflow-y-auto">
259
+ <div className="flex h-full min-h-0 flex-1 flex-col laptop:flex-row">
163
260
  {/* Hosted here like GraphPage does: the chat page (the usual host) is
164
261
  hidden while this view is active, so the staleness deep-link below
165
262
  needs its own panel mount. */}
@@ -167,133 +264,210 @@ export function ActivityPage() {
167
264
  open={settingsPanelOpen}
168
265
  onClose={() => setSettingsPanelOpen(false)}
169
266
  />
170
- <div className="flex items-center gap-2 border-b border-border-subtle px-4 py-3">
171
- <ActivityIcon className="h-4 w-4 text-muted-foreground" />
172
- <h1 className="text-sm font-medium">Activity</h1>
173
- <div className="ml-auto flex items-center gap-2">
174
- {pricingStale && (
175
- <button
176
- type="button"
177
- onClick={() => openSettings("models")}
178
- className="flex items-center gap-1 rounded-md p-1.5 text-amber-500 transition-colors hover:bg-surface-raised hover:text-amber-400"
179
- aria-label="Pricing refresh is failing — costs may use stale rates. Open Settings"
180
- title="Pricing refresh is failing — costs may use stale rates. Open Settings"
181
- >
182
- <AlertTriangle className="h-3.5 w-3.5" />
183
- <span className="hidden text-[10px] sm:inline">Pricing stale</span>
184
- </button>
185
- )}
186
- <PushToggle />
187
- </div>
188
- <button
189
- type="button"
190
- onClick={refresh}
191
- className="rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-surface-raised hover:text-foreground"
192
- aria-label="Refresh"
193
- >
194
- <RefreshCw className="h-3.5 w-3.5" />
195
- </button>
196
- </div>
197
-
198
- <div className="mx-auto w-full max-w-3xl space-y-6 p-4">
199
- {error && (
200
- <p className="text-xs text-destructive">Could not load activity: {error}</p>
267
+ {/* The list column. Below `laptop:` it is the whole page and an open
268
+ detail replaces it; from `laptop:` it is 360px beside the detail. */}
269
+ <section
270
+ aria-label="Actions queue"
271
+ className={cn(
272
+ "min-h-0 flex-col overflow-y-auto laptop:flex laptop:w-[360px] laptop:flex-none laptop:border-r laptop:border-border-subtle",
273
+ detailRunId ? "hidden" : "flex flex-1"
201
274
  )}
202
-
203
- {inbox.length > 0 && (
204
- <section>
205
- <div className="mb-2 flex items-center">
206
- <h2 className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
207
- Needs attention
208
- </h2>
275
+ >
276
+ <div className="flex items-center gap-2 border-b border-border-subtle px-4 py-3">
277
+ <ActivityIcon className="h-4 w-4 text-muted-foreground" />
278
+ <h1 className="text-sm font-medium outline-none" tabIndex={-1} data-activity-heading="">Actions</h1>
279
+ <div className="ml-auto flex items-center gap-2">
280
+ {pricingStale && (
209
281
  <button
210
282
  type="button"
211
- onClick={() => void acknowledgeAllIntents()}
212
- className="ml-auto text-[11px] text-muted-foreground transition-colors hover:text-foreground"
283
+ onClick={() => openSettings("models")}
284
+ className="flex items-center gap-1 rounded-md p-1.5 text-primary transition-colors hover:bg-surface-raised hover:text-primary/80"
285
+ aria-label="Pricing refresh is failing — costs may use stale rates. Open Settings"
286
+ title="Pricing refresh is failing — costs may use stale rates. Open Settings"
213
287
  >
214
- Dismiss all
288
+ <AlertTriangle className="h-3.5 w-3.5" />
289
+ <span className="hidden text-[10px] sm:inline">Pricing stale</span>
215
290
  </button>
216
- </div>
217
- <div className="space-y-1">
218
- {inbox.map((intent) => (
219
- <div
220
- key={intent.id}
221
- className={cn(
222
- "flex items-center gap-2 rounded-lg border px-3 py-2 text-xs",
223
- intent.kind === "failure"
224
- ? "border-destructive/30 bg-destructive/5"
225
- : "border-border-subtle bg-surface"
226
- )}
227
- >
228
- {intent.kind === "failure" ? (
229
- <AlertTriangle className="h-3.5 w-3.5 shrink-0 text-destructive" />
230
- ) : intent.kind === "stuck" ? (
231
- <Timer className="h-3.5 w-3.5 shrink-0 text-amber-500" />
232
- ) : (
233
- <ActivityIcon className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
234
- )}
235
- <button
236
- type="button"
237
- className="min-w-0 flex-1 truncate text-left hover:underline"
238
- onClick={() => {
239
- void acknowledgeIntent(intent.id);
240
- openIntent(intent);
241
- }}
242
- >
243
- {intent.title}
244
- </button>
245
- <span className="shrink-0 text-[10px] text-muted-foreground/60">
246
- {formatRelativeTime(intent.createdAt)}
247
- </span>
291
+ )}
292
+ <PushToggle />
293
+ </div>
294
+ <button
295
+ type="button"
296
+ onClick={refresh}
297
+ className="rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-surface-raised hover:text-foreground"
298
+ aria-label="Refresh"
299
+ >
300
+ <RefreshCw className="h-3.5 w-3.5" />
301
+ </button>
302
+ </div>
303
+
304
+ <div className="mx-auto w-full max-w-3xl space-y-6 p-4 laptop:max-w-none">
305
+ {error && (
306
+ <p className="text-xs text-destructive">Could not load activity: {error}</p>
307
+ )}
308
+
309
+ <FilterRow
310
+ items={[
311
+ { label: `needs you ${needsYouCount}`, onClick: () => setLens("needs-you") },
312
+ { label: `running ${runningCount}`, onClick: () => setLens("running") },
313
+ { label: `done ${history.length}`, onClick: () => setLens("done") },
314
+ ]}
315
+ active={lens === "needs-you" ? 0 : lens === "running" ? 1 : 2}
316
+ />
317
+
318
+ {lens === "needs-you" && (
319
+ <section aria-labelledby="needs-you-heading">
320
+ <div className="mb-2 flex items-center">
321
+ <h2 id="needs-you-heading" className="text-xs font-medium uppercase tracking-wide text-muted-foreground outline-none" tabIndex={-1} data-needs-you-heading="">
322
+ Needs you
323
+ </h2>
324
+ {inbox.length > 0 && (
248
325
  <button
249
326
  type="button"
250
- onClick={() => void acknowledgeIntent(intent.id)}
251
- className="shrink-0 rounded p-1 text-muted-foreground transition-colors hover:text-foreground"
252
- aria-label="Dismiss"
327
+ onClick={dismissAll}
328
+ className="ml-auto text-[11px] text-muted-foreground transition-colors hover:text-foreground"
253
329
  >
254
- ×
330
+ Dismiss all
255
331
  </button>
332
+ )}
333
+ </div>
334
+ {needsYouCount === 0 ? (
335
+ <div className="flex flex-col gap-3">
336
+ {receipt && <InlineToast text={receipt.text} target={receipt.target} effect={receipt.effect} tone="teal" undoLabel="" />}
337
+ {/* A drained section becomes the empty state, and its heading
338
+ takes focus after the last decision (D37) — never the
339
+ document top. */}
340
+ <EmptyState variant="caught_up" meta="" focusTitle={drained} />
256
341
  </div>
257
- ))}
258
- </div>
259
- </section>
260
- )}
342
+ ) : (
343
+ <>
344
+ {approvals.length > 0 && (
345
+ <div className="mb-3 space-y-2">
346
+ {approvals.map(({ key, tool }) => (
347
+ <ApprovalCard
348
+ key={tool.id}
349
+ tool={tool}
350
+ origin={key ? `session ${key.slice(0, 8)}` : "this conversation"}
351
+ keys={keys}
352
+ onDecide={(approved, always) => decideApproval(key, tool.id, approved, always)}
353
+ />
354
+ ))}
355
+ </div>
356
+ )}
357
+ <div className="space-y-2" onKeyDown={onInboxKeyDown}>
358
+ {inbox.map((intent) => (
359
+ <div key={intent.id} data-intent-card="">
360
+ <IntentCard
361
+ intent={intent}
362
+ when={formatRelativeTime(intent.createdAt)}
363
+ keyHint={keys}
364
+ onOpen={() => {
365
+ void acknowledgeIntent(intent.id);
366
+ openIntent(intent);
367
+ }}
368
+ onDismiss={() => dismiss(intent)}
369
+ />
370
+ </div>
371
+ ))}
372
+ </div>
373
+ {keys && (
374
+ <p className="mt-1.5 font-[family-name:var(--font-mono)] text-[10px] text-muted-foreground/70 laptop:hidden">
375
+ j / k move · d dismiss · ⏎ open{approvals.length > 0 ? " · a allow" : ""}
376
+ </p>
377
+ )}
378
+ </>
379
+ )}
380
+ </section>
381
+ )}
261
382
 
262
- {rollups && <RollupCards rollups={rollups} />}
383
+ {lens === "running" && (
384
+ <section>
385
+ <h2 className="mb-2 text-xs font-medium uppercase tracking-wide text-muted-foreground">
386
+ Running now
387
+ </h2>
388
+ {liveRoots.length === 0 && restLive.length === 0 ? (
389
+ <p className="text-xs text-muted-foreground/70">Nothing is running.</p>
390
+ ) : (
391
+ <div className="space-y-1">
392
+ {liveRoots.map((span) => (
393
+ <LiveRow key={span.runId} span={span} onOpen={openRun} />
394
+ ))}
395
+ {restLive.map((run) => (
396
+ <RunRow key={run.runId} run={run} onOpen={openRun} />
397
+ ))}
398
+ </div>
399
+ )}
400
+ </section>
401
+ )}
263
402
 
264
- <section>
265
- <h2 className="mb-2 text-xs font-medium uppercase tracking-wide text-muted-foreground">
266
- Running now
267
- </h2>
268
- {liveRoots.length === 0 && restLive.length === 0 ? (
269
- <p className="text-xs text-muted-foreground/70">Nothing is running.</p>
270
- ) : (
271
- <div className="space-y-1">
272
- {liveRoots.map((span) => (
273
- <LiveRow key={span.runId} span={span} onOpen={openRun} />
274
- ))}
275
- {restLive.map((run) => (
276
- <RunRow key={run.runId} run={run} onOpen={openRun} />
277
- ))}
278
- </div>
403
+ {lens === "done" && (
404
+ <>
405
+ {rollups && <RollupCards rollups={rollups} />}
406
+ <section>
407
+ <h2 className="mb-2 text-xs font-medium uppercase tracking-wide text-muted-foreground">
408
+ History
409
+ </h2>
410
+ {history.length === 0 ? (
411
+ <p className="text-xs text-muted-foreground/70">No recorded runs yet.</p>
412
+ ) : (
413
+ <div className="space-y-1">
414
+ {history.map((run) => (
415
+ <RunRow key={run.runId} run={run} onOpen={openRun} />
416
+ ))}
417
+ </div>
418
+ )}
419
+ </section>
420
+ </>
279
421
  )}
280
- </section>
422
+ </div>
423
+ {/* The column's footer (D4): the printed keys, pinned under the list
424
+ from `laptop:`. Only while the keys can fire — they act inside the
425
+ inbox list — so a lens without cards advertises nothing. */}
426
+ {keys && lens === "needs-you" && inbox.length > 0 && (
427
+ <p className="sticky bottom-0 mt-auto hidden border-t border-border-subtle bg-background px-4 py-2 font-[family-name:var(--font-mono)] text-[10px] text-muted-foreground/70 laptop:block">
428
+ j / k move · d dismiss
429
+ </p>
430
+ )}
431
+ </section>
432
+
433
+ {/* The detail pane. Below `laptop:` it shows only with a selection and
434
+ takes the whole page; from `laptop:` it is always there, holding the
435
+ selected run or the prompt to pick one. */}
436
+ <div className={cn("min-h-0 min-w-0 flex-1 flex-col", detailRunId ? "flex" : "hidden laptop:flex")}>
437
+ {detailRunId ? (
438
+ <RunDetail runId={detailRunId} onBack={() => showDetail(null)} embedded />
439
+ ) : (
440
+ <div className="flex h-full items-center justify-center overflow-y-auto p-4">
441
+ <EmptyState
442
+ variant="quiet"
443
+ title="Pick a run"
444
+ body="Its trace, attempts and what it was holding show here."
445
+ meta=""
446
+ minHeight={0}
447
+ />
448
+ </div>
449
+ )}
450
+ </div>
281
451
 
282
- <section>
283
- <h2 className="mb-2 text-xs font-medium uppercase tracking-wide text-muted-foreground">
284
- History
285
- </h2>
286
- {history.length === 0 ? (
287
- <p className="text-xs text-muted-foreground/70">No recorded runs yet.</p>
288
- ) : (
289
- <div className="space-y-1">
290
- {history.map((run) => (
291
- <RunRow key={run.runId} run={run} onOpen={openRun} />
292
- ))}
452
+ {/* The evidence rail, `wide:` only: the run's trace as a record, and
453
+ the receipt for the last decision made on this page. */}
454
+ {detailRunId && (
455
+ <aside
456
+ aria-label="Run evidence"
457
+ className="hidden min-h-0 w-[300px] shrink-0 flex-col gap-4 overflow-y-auto border-l border-border-subtle bg-surface p-4 wide:flex"
458
+ >
459
+ <div className="flex flex-col gap-2">
460
+ <Label text="Trace" icon="steps" meta="this run" />
461
+ <RunTraceSteps runId={detailRunId} />
462
+ </div>
463
+ {receipt && (
464
+ <div className="flex flex-col gap-2">
465
+ <Label text="Last decision" icon="resolved" />
466
+ <InlineToast text={receipt.text} target={receipt.target} effect={receipt.effect} tone="teal" undoLabel="" />
293
467
  </div>
294
468
  )}
295
- </section>
296
- </div>
469
+ </aside>
470
+ )}
297
471
  </div>
298
472
  );
299
473
  }