@schlessera/brain-ui-react 0.35.0 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (761) hide show
  1. package/README.md +82 -4
  2. package/dist/components/activity/activity-page.d.ts +17 -5
  3. package/dist/components/activity/activity-page.d.ts.map +1 -1
  4. package/dist/components/activity/activity-page.js +148 -50
  5. package/dist/components/activity/activity-page.js.map +1 -1
  6. package/dist/components/activity/activity-run-detail.d.ts +16 -1
  7. package/dist/components/activity/activity-run-detail.d.ts.map +1 -1
  8. package/dist/components/activity/activity-run-detail.js +47 -4
  9. package/dist/components/activity/activity-run-detail.js.map +1 -1
  10. package/dist/components/activity/activity-run-list.d.ts +7 -1
  11. package/dist/components/activity/activity-run-list.d.ts.map +1 -1
  12. package/dist/components/activity/activity-run-list.js +16 -8
  13. package/dist/components/activity/activity-run-list.js.map +1 -1
  14. package/dist/components/activity/activity-views.d.ts +63 -0
  15. package/dist/components/activity/activity-views.d.ts.map +1 -0
  16. package/dist/components/activity/activity-views.js +52 -0
  17. package/dist/components/activity/activity-views.js.map +1 -0
  18. package/dist/components/activity/approval-card.d.ts +29 -0
  19. package/dist/components/activity/approval-card.d.ts.map +1 -0
  20. package/dist/components/activity/approval-card.js +73 -0
  21. package/dist/components/activity/approval-card.js.map +1 -0
  22. package/dist/components/activity/digest-card.d.ts +3 -0
  23. package/dist/components/activity/digest-card.d.ts.map +1 -1
  24. package/dist/components/activity/digest-card.js +20 -16
  25. package/dist/components/activity/digest-card.js.map +1 -1
  26. package/dist/components/activity/digest-summary.d.ts +19 -0
  27. package/dist/components/activity/digest-summary.d.ts.map +1 -0
  28. package/dist/components/activity/digest-summary.js +20 -0
  29. package/dist/components/activity/digest-summary.js.map +1 -0
  30. package/dist/components/activity/push-switch.d.ts +25 -0
  31. package/dist/components/activity/push-switch.d.ts.map +1 -0
  32. package/dist/components/activity/push-switch.js +14 -0
  33. package/dist/components/activity/push-switch.js.map +1 -0
  34. package/dist/components/activity/push-toggle.d.ts +7 -0
  35. package/dist/components/activity/push-toggle.d.ts.map +1 -1
  36. package/dist/components/activity/push-toggle.js +72 -47
  37. package/dist/components/activity/push-toggle.js.map +1 -1
  38. package/dist/components/activity/span-bits.d.ts +11 -0
  39. package/dist/components/activity/span-bits.d.ts.map +1 -1
  40. package/dist/components/activity/span-bits.js +50 -7
  41. package/dist/components/activity/span-bits.js.map +1 -1
  42. package/dist/components/chat/ask-user-card.d.ts +76 -3
  43. package/dist/components/chat/ask-user-card.d.ts.map +1 -1
  44. package/dist/components/chat/ask-user-card.js +208 -149
  45. package/dist/components/chat/ask-user-card.js.map +1 -1
  46. package/dist/components/chat/ask-user-typed.d.ts +42 -0
  47. package/dist/components/chat/ask-user-typed.d.ts.map +1 -0
  48. package/dist/components/chat/ask-user-typed.js +60 -0
  49. package/dist/components/chat/ask-user-typed.js.map +1 -0
  50. package/dist/components/chat/brain-markdown-links.d.ts +2 -1
  51. package/dist/components/chat/brain-markdown-links.d.ts.map +1 -1
  52. package/dist/components/chat/brain-markdown-links.js +3 -4
  53. package/dist/components/chat/brain-markdown-links.js.map +1 -1
  54. package/dist/components/chat/brain-markdown.d.ts.map +1 -1
  55. package/dist/components/chat/brain-markdown.js +4 -2
  56. package/dist/components/chat/brain-markdown.js.map +1 -1
  57. package/dist/components/chat/chat-page.d.ts.map +1 -1
  58. package/dist/components/chat/chat-page.js +27 -11
  59. package/dist/components/chat/chat-page.js.map +1 -1
  60. package/dist/components/chat/composer-view.d.ts +75 -0
  61. package/dist/components/chat/composer-view.d.ts.map +1 -0
  62. package/dist/components/chat/composer-view.js +31 -0
  63. package/dist/components/chat/composer-view.js.map +1 -0
  64. package/dist/components/chat/composer.d.ts +4 -0
  65. package/dist/components/chat/composer.d.ts.map +1 -1
  66. package/dist/components/chat/composer.js +76 -59
  67. package/dist/components/chat/composer.js.map +1 -1
  68. package/dist/components/chat/markdown-content.d.ts +16 -1
  69. package/dist/components/chat/markdown-content.d.ts.map +1 -1
  70. package/dist/components/chat/markdown-content.js +47 -3
  71. package/dist/components/chat/markdown-content.js.map +1 -1
  72. package/dist/components/chat/mermaid-block.d.ts +4 -0
  73. package/dist/components/chat/mermaid-block.d.ts.map +1 -1
  74. package/dist/components/chat/mermaid-block.js +13 -5
  75. package/dist/components/chat/mermaid-block.js.map +1 -1
  76. package/dist/components/chat/mermaid-share.d.ts +2 -1
  77. package/dist/components/chat/mermaid-share.d.ts.map +1 -1
  78. package/dist/components/chat/mermaid-share.js +7 -8
  79. package/dist/components/chat/mermaid-share.js.map +1 -1
  80. package/dist/components/chat/mermaid-viewer.d.ts.map +1 -1
  81. package/dist/components/chat/mermaid-viewer.js +3 -1
  82. package/dist/components/chat/mermaid-viewer.js.map +1 -1
  83. package/dist/components/chat/message-bubble.d.ts +8 -1
  84. package/dist/components/chat/message-bubble.d.ts.map +1 -1
  85. package/dist/components/chat/message-bubble.js +53 -24
  86. package/dist/components/chat/message-bubble.js.map +1 -1
  87. package/dist/components/chat/message-share.d.ts +2 -1
  88. package/dist/components/chat/message-share.d.ts.map +1 -1
  89. package/dist/components/chat/message-share.js +6 -7
  90. package/dist/components/chat/message-share.js.map +1 -1
  91. package/dist/components/chat/renderers/bind.d.ts +39 -0
  92. package/dist/components/chat/renderers/bind.d.ts.map +1 -0
  93. package/dist/components/chat/renderers/bind.js +43 -0
  94. package/dist/components/chat/renderers/bind.js.map +1 -0
  95. package/dist/components/chat/renderers/brain-ui-tools.d.ts +3 -0
  96. package/dist/components/chat/renderers/brain-ui-tools.d.ts.map +1 -0
  97. package/dist/components/chat/renderers/brain-ui-tools.js +41 -0
  98. package/dist/components/chat/renderers/brain-ui-tools.js.map +1 -0
  99. package/dist/components/chat/renderers/claude-tools.d.ts.map +1 -1
  100. package/dist/components/chat/renderers/claude-tools.js +3 -2
  101. package/dist/components/chat/renderers/claude-tools.js.map +1 -1
  102. package/dist/components/chat/renderers/index.d.ts +10 -2
  103. package/dist/components/chat/renderers/index.d.ts.map +1 -1
  104. package/dist/components/chat/renderers/index.js +15 -10
  105. package/dist/components/chat/renderers/index.js.map +1 -1
  106. package/dist/components/chat/session-drawer.d.ts +4 -0
  107. package/dist/components/chat/session-drawer.d.ts.map +1 -1
  108. package/dist/components/chat/session-drawer.js +32 -32
  109. package/dist/components/chat/session-drawer.js.map +1 -1
  110. package/dist/components/chat/session-list.d.ts +41 -0
  111. package/dist/components/chat/session-list.d.ts.map +1 -0
  112. package/dist/components/chat/session-list.js +10 -0
  113. package/dist/components/chat/session-list.js.map +1 -0
  114. package/dist/components/chat/share-block.d.ts.map +1 -1
  115. package/dist/components/chat/share-block.js +12 -11
  116. package/dist/components/chat/share-block.js.map +1 -1
  117. package/dist/components/chat/share-card.js +2 -2
  118. package/dist/components/chat/share-card.js.map +1 -1
  119. package/dist/components/chat/subagent-view.js +1 -1
  120. package/dist/components/chat/subagent-view.js.map +1 -1
  121. package/dist/components/chat/tool-call-timeline.d.ts.map +1 -1
  122. package/dist/components/chat/tool-call-timeline.js +45 -14
  123. package/dist/components/chat/tool-call-timeline.js.map +1 -1
  124. package/dist/components/chat/tool-cards/block-card.d.ts +28 -0
  125. package/dist/components/chat/tool-cards/block-card.d.ts.map +1 -0
  126. package/dist/components/chat/tool-cards/block-card.js +103 -0
  127. package/dist/components/chat/tool-cards/block-card.js.map +1 -0
  128. package/dist/components/chat/tool-cards/image-mask-card.d.ts +70 -0
  129. package/dist/components/chat/tool-cards/image-mask-card.d.ts.map +1 -0
  130. package/dist/components/chat/tool-cards/image-mask-card.js +142 -0
  131. package/dist/components/chat/tool-cards/image-mask-card.js.map +1 -0
  132. package/dist/components/chat/tool-cards/location-card.d.ts +45 -0
  133. package/dist/components/chat/tool-cards/location-card.d.ts.map +1 -0
  134. package/dist/components/chat/tool-cards/location-card.js +128 -0
  135. package/dist/components/chat/tool-cards/location-card.js.map +1 -0
  136. package/dist/components/chat/tool-views.d.ts +19 -2
  137. package/dist/components/chat/tool-views.d.ts.map +1 -1
  138. package/dist/components/chat/tool-views.js +28 -22
  139. package/dist/components/chat/tool-views.js.map +1 -1
  140. package/dist/components/chat/transcript-turn.d.ts +45 -0
  141. package/dist/components/chat/transcript-turn.d.ts.map +1 -0
  142. package/dist/components/chat/transcript-turn.js +25 -0
  143. package/dist/components/chat/transcript-turn.js.map +1 -0
  144. package/dist/components/chat/use-chat-commands.d.ts.map +1 -1
  145. package/dist/components/chat/use-chat-commands.js +13 -16
  146. package/dist/components/chat/use-chat-commands.js.map +1 -1
  147. package/dist/components/chat/welcome-state.d.ts +7 -0
  148. package/dist/components/chat/welcome-state.d.ts.map +1 -1
  149. package/dist/components/chat/welcome-state.js +13 -5
  150. package/dist/components/chat/welcome-state.js.map +1 -1
  151. package/dist/components/connectivity/connection-gate.d.ts.map +1 -1
  152. package/dist/components/connectivity/connection-gate.js +27 -21
  153. package/dist/components/connectivity/connection-gate.js.map +1 -1
  154. package/dist/components/connectivity/login-form.d.ts +31 -0
  155. package/dist/components/connectivity/login-form.d.ts.map +1 -0
  156. package/dist/components/connectivity/login-form.js +19 -0
  157. package/dist/components/connectivity/login-form.js.map +1 -0
  158. package/dist/components/connectivity/login-screen.d.ts +5 -2
  159. package/dist/components/connectivity/login-screen.d.ts.map +1 -1
  160. package/dist/components/connectivity/login-screen.js +41 -31
  161. package/dist/components/connectivity/login-screen.js.map +1 -1
  162. package/dist/components/dev/share-harness.js +1 -1
  163. package/dist/components/dev/share-harness.js.map +1 -1
  164. package/dist/components/files/file-panel.d.ts +1 -1
  165. package/dist/components/files/file-panel.d.ts.map +1 -1
  166. package/dist/components/files/file-panel.js +74 -0
  167. package/dist/components/files/file-panel.js.map +1 -1
  168. package/dist/components/files/file-tree-view.d.ts +45 -0
  169. package/dist/components/files/file-tree-view.d.ts.map +1 -0
  170. package/dist/components/files/file-tree-view.js +51 -0
  171. package/dist/components/files/file-tree-view.js.map +1 -0
  172. package/dist/components/files/file-tree.d.ts +6 -0
  173. package/dist/components/files/file-tree.d.ts.map +1 -1
  174. package/dist/components/files/file-tree.js +39 -43
  175. package/dist/components/files/file-tree.js.map +1 -1
  176. package/dist/components/files/file-viewer-binary.d.ts.map +1 -1
  177. package/dist/components/files/file-viewer-binary.js +3 -2
  178. package/dist/components/files/file-viewer-binary.js.map +1 -1
  179. package/dist/components/files/file-viewer-frame.d.ts +36 -0
  180. package/dist/components/files/file-viewer-frame.d.ts.map +1 -0
  181. package/dist/components/files/file-viewer-frame.js +26 -0
  182. package/dist/components/files/file-viewer-frame.js.map +1 -0
  183. package/dist/components/files/file-viewer.d.ts +5 -0
  184. package/dist/components/files/file-viewer.d.ts.map +1 -1
  185. package/dist/components/files/file-viewer.js +26 -32
  186. package/dist/components/files/file-viewer.js.map +1 -1
  187. package/dist/components/files/frontmatter-chips.d.ts +18 -0
  188. package/dist/components/files/frontmatter-chips.d.ts.map +1 -0
  189. package/dist/components/files/frontmatter-chips.js +11 -0
  190. package/dist/components/files/frontmatter-chips.js.map +1 -0
  191. package/dist/components/files/frontmatter-panel.d.ts +5 -1
  192. package/dist/components/files/frontmatter-panel.d.ts.map +1 -1
  193. package/dist/components/files/frontmatter-panel.js +7 -6
  194. package/dist/components/files/frontmatter-panel.js.map +1 -1
  195. package/dist/components/files/staleness.d.ts +18 -0
  196. package/dist/components/files/staleness.d.ts.map +1 -0
  197. package/dist/components/files/staleness.js +27 -0
  198. package/dist/components/files/staleness.js.map +1 -0
  199. package/dist/components/graph/graph-canvas.d.ts.map +1 -1
  200. package/dist/components/graph/graph-canvas.js +24 -1
  201. package/dist/components/graph/graph-canvas.js.map +1 -1
  202. package/dist/components/graph/graph-controls-column.d.ts +14 -0
  203. package/dist/components/graph/graph-controls-column.d.ts.map +1 -0
  204. package/dist/components/graph/graph-controls-column.js +44 -0
  205. package/dist/components/graph/graph-controls-column.js.map +1 -0
  206. package/dist/components/graph/graph-controls.d.ts +20 -5
  207. package/dist/components/graph/graph-controls.d.ts.map +1 -1
  208. package/dist/components/graph/graph-controls.js +58 -37
  209. package/dist/components/graph/graph-controls.js.map +1 -1
  210. package/dist/components/graph/graph-form.d.ts +82 -0
  211. package/dist/components/graph/graph-form.d.ts.map +1 -0
  212. package/dist/components/graph/graph-form.js +69 -0
  213. package/dist/components/graph/graph-form.js.map +1 -0
  214. package/dist/components/graph/graph-maintenance.d.ts.map +1 -1
  215. package/dist/components/graph/graph-maintenance.js +6 -10
  216. package/dist/components/graph/graph-maintenance.js.map +1 -1
  217. package/dist/components/graph/graph-node-rail.d.ts +13 -0
  218. package/dist/components/graph/graph-node-rail.d.ts.map +1 -0
  219. package/dist/components/graph/graph-node-rail.js +92 -0
  220. package/dist/components/graph/graph-node-rail.js.map +1 -0
  221. package/dist/components/graph/graph-page.d.ts +7 -0
  222. package/dist/components/graph/graph-page.d.ts.map +1 -1
  223. package/dist/components/graph/graph-page.js +102 -12
  224. package/dist/components/graph/graph-page.js.map +1 -1
  225. package/dist/components/graph/graph-scene.d.ts.map +1 -1
  226. package/dist/components/graph/graph-scene.js +100 -24
  227. package/dist/components/graph/graph-scene.js.map +1 -1
  228. package/dist/components/graph/lib/graph-helpers.d.ts +42 -12
  229. package/dist/components/graph/lib/graph-helpers.d.ts.map +1 -1
  230. package/dist/components/graph/lib/graph-helpers.js +33 -41
  231. package/dist/components/graph/lib/graph-helpers.js.map +1 -1
  232. package/dist/components/graph/node-card.d.ts +28 -0
  233. package/dist/components/graph/node-card.d.ts.map +1 -0
  234. package/dist/components/graph/node-card.js +7 -0
  235. package/dist/components/graph/node-card.js.map +1 -0
  236. package/dist/components/graph/node-popover.d.ts +6 -2
  237. package/dist/components/graph/node-popover.d.ts.map +1 -1
  238. package/dist/components/graph/node-popover.js +13 -31
  239. package/dist/components/graph/node-popover.js.map +1 -1
  240. package/dist/components/graph/use-graph-theme.d.ts +32 -4
  241. package/dist/components/graph/use-graph-theme.d.ts.map +1 -1
  242. package/dist/components/graph/use-graph-theme.js +44 -32
  243. package/dist/components/graph/use-graph-theme.js.map +1 -1
  244. package/dist/components/graph/use-node-actions.d.ts +26 -0
  245. package/dist/components/graph/use-node-actions.d.ts.map +1 -0
  246. package/dist/components/graph/use-node-actions.js +54 -0
  247. package/dist/components/graph/use-node-actions.js.map +1 -0
  248. package/dist/components/images/image-share.d.ts +2 -1
  249. package/dist/components/images/image-share.d.ts.map +1 -1
  250. package/dist/components/images/image-share.js +3 -3
  251. package/dist/components/images/image-share.js.map +1 -1
  252. package/dist/components/images/image-viewer.d.ts.map +1 -1
  253. package/dist/components/images/image-viewer.js +3 -1
  254. package/dist/components/images/image-viewer.js.map +1 -1
  255. package/dist/components/images/mask-editor.d.ts.map +1 -1
  256. package/dist/components/images/mask-editor.js +7 -5
  257. package/dist/components/images/mask-editor.js.map +1 -1
  258. package/dist/components/layout/app-shell.d.ts.map +1 -1
  259. package/dist/components/layout/app-shell.js +4 -1
  260. package/dist/components/layout/app-shell.js.map +1 -1
  261. package/dist/components/layout/desktop-palette.d.ts +23 -0
  262. package/dist/components/layout/desktop-palette.d.ts.map +1 -0
  263. package/dist/components/layout/desktop-palette.js +132 -0
  264. package/dist/components/layout/desktop-palette.js.map +1 -0
  265. package/dist/components/layout/key-cap.d.ts +9 -0
  266. package/dist/components/layout/key-cap.d.ts.map +1 -0
  267. package/dist/components/layout/key-cap.js +10 -0
  268. package/dist/components/layout/key-cap.js.map +1 -0
  269. package/dist/components/layout/mobile-tab-bar.d.ts +13 -0
  270. package/dist/components/layout/mobile-tab-bar.d.ts.map +1 -1
  271. package/dist/components/layout/mobile-tab-bar.js +58 -47
  272. package/dist/components/layout/mobile-tab-bar.js.map +1 -1
  273. package/dist/components/layout/shortcut-switch.d.ts +13 -0
  274. package/dist/components/layout/shortcut-switch.d.ts.map +1 -0
  275. package/dist/components/layout/shortcut-switch.js +22 -0
  276. package/dist/components/layout/shortcut-switch.js.map +1 -0
  277. package/dist/components/layout/side-rail.d.ts +28 -0
  278. package/dist/components/layout/side-rail.d.ts.map +1 -1
  279. package/dist/components/layout/side-rail.js +72 -27
  280. package/dist/components/layout/side-rail.js.map +1 -1
  281. package/dist/components/layout/slide-panel.d.ts +25 -2
  282. package/dist/components/layout/slide-panel.d.ts.map +1 -1
  283. package/dist/components/layout/slide-panel.js +13 -4
  284. package/dist/components/layout/slide-panel.js.map +1 -1
  285. package/dist/components/layout/theme.d.ts +22 -0
  286. package/dist/components/layout/theme.d.ts.map +1 -0
  287. package/dist/components/layout/theme.js +44 -0
  288. package/dist/components/layout/theme.js.map +1 -0
  289. package/dist/components/quick-actions/add-form.d.ts +44 -0
  290. package/dist/components/quick-actions/add-form.d.ts.map +1 -0
  291. package/dist/components/quick-actions/add-form.js +32 -0
  292. package/dist/components/quick-actions/add-form.js.map +1 -0
  293. package/dist/components/quick-actions/add-modal.d.ts +7 -0
  294. package/dist/components/quick-actions/add-modal.d.ts.map +1 -1
  295. package/dist/components/quick-actions/add-modal.js +23 -20
  296. package/dist/components/quick-actions/add-modal.js.map +1 -1
  297. package/dist/components/quick-actions/search-modal.d.ts.map +1 -1
  298. package/dist/components/quick-actions/search-modal.js +8 -5
  299. package/dist/components/quick-actions/search-modal.js.map +1 -1
  300. package/dist/components/quick-actions/streaming-modal.d.ts +6 -0
  301. package/dist/components/quick-actions/streaming-modal.d.ts.map +1 -1
  302. package/dist/components/quick-actions/streaming-modal.js +53 -18
  303. package/dist/components/quick-actions/streaming-modal.js.map +1 -1
  304. package/dist/components/quick-actions/streaming-output.d.ts +38 -0
  305. package/dist/components/quick-actions/streaming-output.d.ts.map +1 -0
  306. package/dist/components/quick-actions/streaming-output.js +22 -0
  307. package/dist/components/quick-actions/streaming-output.js.map +1 -0
  308. package/dist/components/quick-actions/whatsup-modal.d.ts +5 -0
  309. package/dist/components/quick-actions/whatsup-modal.d.ts.map +1 -1
  310. package/dist/components/quick-actions/whatsup-modal.js +51 -10
  311. package/dist/components/quick-actions/whatsup-modal.js.map +1 -1
  312. package/dist/components/settings/devices-agents-tab.d.ts +6 -1
  313. package/dist/components/settings/devices-agents-tab.d.ts.map +1 -1
  314. package/dist/components/settings/devices-agents-tab.js +55 -20
  315. package/dist/components/settings/devices-agents-tab.js.map +1 -1
  316. package/dist/components/settings/models-list.d.ts +39 -0
  317. package/dist/components/settings/models-list.d.ts.map +1 -0
  318. package/dist/components/settings/models-list.js +72 -0
  319. package/dist/components/settings/models-list.js.map +1 -0
  320. package/dist/components/settings/models-tab.d.ts +4 -0
  321. package/dist/components/settings/models-tab.d.ts.map +1 -1
  322. package/dist/components/settings/models-tab.js +52 -102
  323. package/dist/components/settings/models-tab.js.map +1 -1
  324. package/dist/components/settings/one-time-agent-credential.js +1 -1
  325. package/dist/components/settings/one-time-agent-credential.js.map +1 -1
  326. package/dist/components/settings/passkey-list.d.ts +35 -0
  327. package/dist/components/settings/passkey-list.d.ts.map +1 -0
  328. package/dist/components/settings/passkey-list.js +34 -0
  329. package/dist/components/settings/passkey-list.js.map +1 -0
  330. package/dist/components/settings/passkey-tab.d.ts +3 -0
  331. package/dist/components/settings/passkey-tab.d.ts.map +1 -1
  332. package/dist/components/settings/passkey-tab.js +53 -45
  333. package/dist/components/settings/passkey-tab.js.map +1 -1
  334. package/dist/components/settings/pi-accounts-list.d.ts +27 -0
  335. package/dist/components/settings/pi-accounts-list.d.ts.map +1 -0
  336. package/dist/components/settings/pi-accounts-list.js +15 -0
  337. package/dist/components/settings/pi-accounts-list.js.map +1 -0
  338. package/dist/components/settings/pi-accounts.d.ts +3 -0
  339. package/dist/components/settings/pi-accounts.d.ts.map +1 -1
  340. package/dist/components/settings/pi-accounts.js +73 -55
  341. package/dist/components/settings/pi-accounts.js.map +1 -1
  342. package/dist/components/settings/principal-list.d.ts +37 -0
  343. package/dist/components/settings/principal-list.d.ts.map +1 -0
  344. package/dist/components/settings/principal-list.js +18 -0
  345. package/dist/components/settings/principal-list.js.map +1 -0
  346. package/dist/components/settings/settings-panel.d.ts +10 -3
  347. package/dist/components/settings/settings-panel.d.ts.map +1 -1
  348. package/dist/components/settings/settings-panel.js +71 -10
  349. package/dist/components/settings/settings-panel.js.map +1 -1
  350. package/dist/components/settings/skills-list.d.ts +53 -0
  351. package/dist/components/settings/skills-list.d.ts.map +1 -0
  352. package/dist/components/settings/skills-list.js +28 -0
  353. package/dist/components/settings/skills-list.js.map +1 -0
  354. package/dist/components/settings/skills-tab.d.ts.map +1 -1
  355. package/dist/components/settings/skills-tab.js +65 -38
  356. package/dist/components/settings/skills-tab.js.map +1 -1
  357. package/dist/components/settings/tool-permissions-list.d.ts +18 -0
  358. package/dist/components/settings/tool-permissions-list.d.ts.map +1 -0
  359. package/dist/components/settings/tool-permissions-list.js +6 -0
  360. package/dist/components/settings/tool-permissions-list.js.map +1 -0
  361. package/dist/components/settings/tool-permissions.d.ts +2 -1
  362. package/dist/components/settings/tool-permissions.d.ts.map +1 -1
  363. package/dist/components/settings/tool-permissions.js +33 -16
  364. package/dist/components/settings/tool-permissions.js.map +1 -1
  365. package/dist/components/settings/web-search-chain.d.ts +41 -0
  366. package/dist/components/settings/web-search-chain.d.ts.map +1 -0
  367. package/dist/components/settings/web-search-chain.js +47 -0
  368. package/dist/components/settings/web-search-chain.js.map +1 -0
  369. package/dist/components/settings/web-search-settings.d.ts +4 -7
  370. package/dist/components/settings/web-search-settings.d.ts.map +1 -1
  371. package/dist/components/settings/web-search-settings.js +54 -76
  372. package/dist/components/settings/web-search-settings.js.map +1 -1
  373. package/dist/components/share/share-menu.d.ts.map +1 -1
  374. package/dist/components/share/share-menu.js +24 -4
  375. package/dist/components/share/share-menu.js.map +1 -1
  376. package/dist/components/voice/dictation-sheet.js +3 -3
  377. package/dist/components/voice/dictation-sheet.js.map +1 -1
  378. package/dist/components/voice/mic-button.js +1 -1
  379. package/dist/components/voice/mic-button.js.map +1 -1
  380. package/dist/components/voice/review-card.js +1 -1
  381. package/dist/components/voice/review-card.js.map +1 -1
  382. package/dist/config.d.ts +5 -2
  383. package/dist/config.d.ts.map +1 -1
  384. package/dist/config.js +15 -5
  385. package/dist/config.js.map +1 -1
  386. package/dist/connection.d.ts +12 -0
  387. package/dist/connection.d.ts.map +1 -0
  388. package/dist/connection.js +421 -0
  389. package/dist/connection.js.map +1 -0
  390. package/dist/default-root.d.ts +3 -0
  391. package/dist/default-root.d.ts.map +1 -0
  392. package/dist/default-root.js +16 -0
  393. package/dist/default-root.js.map +1 -0
  394. package/dist/hooks/use-color-scheme.d.ts +14 -0
  395. package/dist/hooks/use-color-scheme.d.ts.map +1 -0
  396. package/dist/hooks/use-color-scheme.js +37 -0
  397. package/dist/hooks/use-color-scheme.js.map +1 -0
  398. package/dist/hooks/use-fine-pointer.d.ts +12 -0
  399. package/dist/hooks/use-fine-pointer.d.ts.map +1 -0
  400. package/dist/hooks/use-fine-pointer.js +15 -0
  401. package/dist/hooks/use-fine-pointer.js.map +1 -0
  402. package/dist/hooks/use-hash-routes.d.ts.map +1 -1
  403. package/dist/hooks/use-hash-routes.js +4 -2
  404. package/dist/hooks/use-hash-routes.js.map +1 -1
  405. package/dist/hooks/use-media-query.d.ts +9 -0
  406. package/dist/hooks/use-media-query.d.ts.map +1 -0
  407. package/dist/hooks/use-media-query.js +38 -0
  408. package/dist/hooks/use-media-query.js.map +1 -0
  409. package/dist/hooks/use-share-intake.d.ts.map +1 -1
  410. package/dist/hooks/use-share-intake.js +37 -12
  411. package/dist/hooks/use-share-intake.js.map +1 -1
  412. package/dist/hooks/use-vpn-status.d.ts.map +1 -1
  413. package/dist/hooks/use-vpn-status.js +17 -18
  414. package/dist/hooks/use-vpn-status.js.map +1 -1
  415. package/dist/hooks/use-websocket.d.ts +5 -24
  416. package/dist/hooks/use-websocket.d.ts.map +1 -1
  417. package/dist/hooks/use-websocket.js +11 -384
  418. package/dist/hooks/use-websocket.js.map +1 -1
  419. package/dist/hooks/websocket-handlers/activity.d.ts +2 -2
  420. package/dist/hooks/websocket-handlers/activity.d.ts.map +1 -1
  421. package/dist/hooks/websocket-handlers/activity.js +4 -5
  422. package/dist/hooks/websocket-handlers/activity.js.map +1 -1
  423. package/dist/hooks/websocket-handlers/chat.d.ts +1 -0
  424. package/dist/hooks/websocket-handlers/chat.d.ts.map +1 -1
  425. package/dist/hooks/websocket-handlers/chat.js +28 -6
  426. package/dist/hooks/websocket-handlers/chat.js.map +1 -1
  427. package/dist/hooks/websocket-handlers/connection.d.ts.map +1 -1
  428. package/dist/hooks/websocket-handlers/connection.js +4 -6
  429. package/dist/hooks/websocket-handlers/connection.js.map +1 -1
  430. package/dist/hooks/websocket-handlers/mask.d.ts +1 -1
  431. package/dist/hooks/websocket-handlers/mask.d.ts.map +1 -1
  432. package/dist/hooks/websocket-handlers/mask.js +2 -3
  433. package/dist/hooks/websocket-handlers/mask.js.map +1 -1
  434. package/dist/hooks/websocket-handlers/provider.d.ts.map +1 -1
  435. package/dist/hooks/websocket-handlers/provider.js +4 -6
  436. package/dist/hooks/websocket-handlers/provider.js.map +1 -1
  437. package/dist/hooks/websocket-handlers/types.d.ts +6 -2
  438. package/dist/hooks/websocket-handlers/types.d.ts.map +1 -1
  439. package/dist/index.d.ts +5 -3
  440. package/dist/index.d.ts.map +1 -1
  441. package/dist/index.js +6 -3
  442. package/dist/index.js.map +1 -1
  443. package/dist/lib/api-client.d.ts +289 -0
  444. package/dist/lib/api-client.d.ts.map +1 -1
  445. package/dist/lib/api-client.js +243 -224
  446. package/dist/lib/api-client.js.map +1 -1
  447. package/dist/lib/backend.d.ts +19 -2
  448. package/dist/lib/backend.d.ts.map +1 -1
  449. package/dist/lib/backend.js +15 -9
  450. package/dist/lib/backend.js.map +1 -1
  451. package/dist/lib/diff.d.ts +8 -10
  452. package/dist/lib/diff.d.ts.map +1 -1
  453. package/dist/lib/diff.js +26 -53
  454. package/dist/lib/diff.js.map +1 -1
  455. package/dist/lib/light-dark.d.ts +37 -0
  456. package/dist/lib/light-dark.d.ts.map +1 -0
  457. package/dist/lib/light-dark.js +83 -0
  458. package/dist/lib/light-dark.js.map +1 -0
  459. package/dist/lib/mermaid-theme.d.ts +7 -2
  460. package/dist/lib/mermaid-theme.d.ts.map +1 -1
  461. package/dist/lib/mermaid-theme.js +125 -203
  462. package/dist/lib/mermaid-theme.js.map +1 -1
  463. package/dist/lib/passkeys.d.ts +6 -3
  464. package/dist/lib/passkeys.d.ts.map +1 -1
  465. package/dist/lib/passkeys.js +10 -4
  466. package/dist/lib/passkeys.js.map +1 -1
  467. package/dist/lib/push-registration.d.ts +4 -1
  468. package/dist/lib/push-registration.d.ts.map +1 -1
  469. package/dist/lib/push-registration.js +20 -2
  470. package/dist/lib/push-registration.js.map +1 -1
  471. package/dist/lib/share-intake.d.ts +2 -1
  472. package/dist/lib/share-intake.d.ts.map +1 -1
  473. package/dist/lib/share-intake.js +3 -3
  474. package/dist/lib/share-intake.js.map +1 -1
  475. package/dist/lib/share.d.ts +4 -3
  476. package/dist/lib/share.d.ts.map +1 -1
  477. package/dist/lib/share.js +6 -7
  478. package/dist/lib/share.js.map +1 -1
  479. package/dist/lib/single-key.d.ts +30 -0
  480. package/dist/lib/single-key.d.ts.map +1 -0
  481. package/dist/lib/single-key.js +45 -0
  482. package/dist/lib/single-key.js.map +1 -0
  483. package/dist/lib/tool-names.d.ts +8 -6
  484. package/dist/lib/tool-names.d.ts.map +1 -1
  485. package/dist/lib/tool-names.js +17 -7
  486. package/dist/lib/tool-names.js.map +1 -1
  487. package/dist/root-context.d.ts +229 -0
  488. package/dist/root-context.d.ts.map +1 -0
  489. package/dist/root-context.js +33 -0
  490. package/dist/root-context.js.map +1 -0
  491. package/dist/root.d.ts +38 -0
  492. package/dist/root.d.ts.map +1 -0
  493. package/dist/root.js +47 -0
  494. package/dist/root.js.map +1 -0
  495. package/dist/stores/activity-state.d.ts +29 -0
  496. package/dist/stores/activity-state.d.ts.map +1 -0
  497. package/dist/stores/activity-state.js +282 -0
  498. package/dist/stores/activity-state.js.map +1 -0
  499. package/dist/stores/activity-store.d.ts +10 -41
  500. package/dist/stores/activity-store.d.ts.map +1 -1
  501. package/dist/stores/activity-store.js +9 -271
  502. package/dist/stores/activity-store.js.map +1 -1
  503. package/dist/stores/chat-state.d.ts +233 -0
  504. package/dist/stores/chat-state.d.ts.map +1 -0
  505. package/dist/stores/chat-state.js +477 -0
  506. package/dist/stores/chat-state.js.map +1 -0
  507. package/dist/stores/chat-store.d.ts +4 -162
  508. package/dist/stores/chat-store.d.ts.map +1 -1
  509. package/dist/stores/chat-store.js +7 -418
  510. package/dist/stores/chat-store.js.map +1 -1
  511. package/dist/stores/connection-state.d.ts +40 -0
  512. package/dist/stores/connection-state.d.ts.map +1 -0
  513. package/dist/stores/connection-state.js +30 -0
  514. package/dist/stores/connection-state.js.map +1 -0
  515. package/dist/stores/connection-store.d.ts +4 -40
  516. package/dist/stores/connection-store.d.ts.map +1 -1
  517. package/dist/stores/connection-store.js +7 -27
  518. package/dist/stores/connection-store.js.map +1 -1
  519. package/dist/stores/create-stores.d.ts +23 -0
  520. package/dist/stores/create-stores.d.ts.map +1 -0
  521. package/dist/stores/create-stores.js +28 -0
  522. package/dist/stores/create-stores.js.map +1 -0
  523. package/dist/stores/file-state.d.ts +53 -0
  524. package/dist/stores/file-state.d.ts.map +1 -0
  525. package/dist/stores/file-state.js +341 -0
  526. package/dist/stores/file-state.js.map +1 -0
  527. package/dist/stores/file-store.d.ts +4 -52
  528. package/dist/stores/file-store.d.ts.map +1 -1
  529. package/dist/stores/file-store.js +7 -336
  530. package/dist/stores/file-store.js.map +1 -1
  531. package/dist/stores/graph-state.d.ts +95 -0
  532. package/dist/stores/graph-state.d.ts.map +1 -0
  533. package/dist/stores/graph-state.js +252 -0
  534. package/dist/stores/graph-state.js.map +1 -0
  535. package/dist/stores/graph-store.d.ts +7 -83
  536. package/dist/stores/graph-store.d.ts.map +1 -1
  537. package/dist/stores/graph-store.js +8 -249
  538. package/dist/stores/graph-store.js.map +1 -1
  539. package/dist/stores/mask-state.d.ts +21 -0
  540. package/dist/stores/mask-state.d.ts.map +1 -0
  541. package/dist/stores/mask-state.js +9 -0
  542. package/dist/stores/mask-state.js.map +1 -0
  543. package/dist/stores/mask-store.d.ts +4 -21
  544. package/dist/stores/mask-store.d.ts.map +1 -1
  545. package/dist/stores/mask-store.js +7 -6
  546. package/dist/stores/mask-store.js.map +1 -1
  547. package/dist/stores/principal-state.d.ts +16 -0
  548. package/dist/stores/principal-state.d.ts.map +1 -0
  549. package/dist/stores/principal-state.js +31 -0
  550. package/dist/stores/principal-state.js.map +1 -0
  551. package/dist/stores/principal-store.d.ts +4 -15
  552. package/dist/stores/principal-store.d.ts.map +1 -1
  553. package/dist/stores/principal-store.js +7 -28
  554. package/dist/stores/principal-store.js.map +1 -1
  555. package/dist/stores/provider-state.d.ts +24 -0
  556. package/dist/stores/provider-state.d.ts.map +1 -0
  557. package/dist/stores/provider-state.js +68 -0
  558. package/dist/stores/provider-state.js.map +1 -0
  559. package/dist/stores/provider-store.d.ts +4 -23
  560. package/dist/stores/provider-store.d.ts.map +1 -1
  561. package/dist/stores/provider-store.js +7 -64
  562. package/dist/stores/provider-store.js.map +1 -1
  563. package/dist/stores/share-state.d.ts +29 -0
  564. package/dist/stores/share-state.d.ts.map +1 -0
  565. package/dist/stores/share-state.js +21 -0
  566. package/dist/stores/share-state.js.map +1 -0
  567. package/dist/stores/share-store.d.ts +4 -28
  568. package/dist/stores/share-store.d.ts.map +1 -1
  569. package/dist/stores/share-store.js +7 -18
  570. package/dist/stores/share-store.js.map +1 -1
  571. package/dist/stores/store-environment.d.ts +10 -0
  572. package/dist/stores/store-environment.d.ts.map +1 -0
  573. package/dist/stores/store-environment.js +2 -0
  574. package/dist/stores/store-environment.js.map +1 -0
  575. package/dist/stores/ui-state.d.ts +71 -0
  576. package/dist/stores/ui-state.d.ts.map +1 -0
  577. package/dist/stores/ui-state.js +58 -0
  578. package/dist/stores/ui-state.js.map +1 -0
  579. package/dist/stores/ui-store.d.ts +4 -45
  580. package/dist/stores/ui-store.d.ts.map +1 -1
  581. package/dist/stores/ui-store.js +7 -36
  582. package/dist/stores/ui-store.js.map +1 -1
  583. package/dist/styles.css +1 -1
  584. package/dist/theme.css +150 -97
  585. package/dist/voice/asr-clients.d.ts +2 -1
  586. package/dist/voice/asr-clients.d.ts.map +1 -1
  587. package/dist/voice/asr-clients.js +16 -17
  588. package/dist/voice/asr-clients.js.map +1 -1
  589. package/dist/voice/use-dictation.d.ts.map +1 -1
  590. package/dist/voice/use-dictation.js +12 -8
  591. package/dist/voice/use-dictation.js.map +1 -1
  592. package/dist/voice/voice-state.d.ts +25 -0
  593. package/dist/voice/voice-state.d.ts.map +1 -0
  594. package/dist/voice/voice-state.js +29 -0
  595. package/dist/voice/voice-state.js.map +1 -0
  596. package/dist/voice/voice-store.d.ts +4 -25
  597. package/dist/voice/voice-store.d.ts.map +1 -1
  598. package/dist/voice/voice-store.js +7 -26
  599. package/dist/voice/voice-store.js.map +1 -1
  600. package/package.json +3 -2
  601. package/src/components/activity/activity-page.tsx +341 -160
  602. package/src/components/activity/activity-run-detail.tsx +81 -47
  603. package/src/components/activity/activity-run-list.tsx +27 -59
  604. package/src/components/activity/activity-views.tsx +155 -0
  605. package/src/components/activity/approval-card.tsx +117 -0
  606. package/src/components/activity/digest-card.tsx +25 -61
  607. package/src/components/activity/digest-summary.tsx +52 -0
  608. package/src/components/activity/push-switch.tsx +62 -0
  609. package/src/components/activity/push-toggle.tsx +51 -81
  610. package/src/components/activity/span-bits.tsx +60 -7
  611. package/src/components/chat/ask-user-card.tsx +292 -356
  612. package/src/components/chat/ask-user-typed.ts +77 -0
  613. package/src/components/chat/brain-markdown-links.tsx +4 -4
  614. package/src/components/chat/brain-markdown.tsx +4 -2
  615. package/src/components/chat/chat-page.tsx +41 -11
  616. package/src/components/chat/composer-view.tsx +194 -0
  617. package/src/components/chat/composer.tsx +117 -296
  618. package/src/components/chat/markdown-content.tsx +53 -2
  619. package/src/components/chat/mermaid-block.tsx +13 -5
  620. package/src/components/chat/mermaid-share.ts +8 -7
  621. package/src/components/chat/mermaid-viewer.tsx +3 -1
  622. package/src/components/chat/message-bubble.tsx +78 -94
  623. package/src/components/chat/message-share.ts +7 -7
  624. package/src/components/chat/renderers/bind.tsx +94 -0
  625. package/src/components/chat/renderers/brain-ui-tools.tsx +56 -0
  626. package/src/components/chat/renderers/claude-tools.tsx +3 -2
  627. package/src/components/chat/renderers/index.ts +15 -10
  628. package/src/components/chat/session-drawer.tsx +41 -138
  629. package/src/components/chat/session-list.tsx +113 -0
  630. package/src/components/chat/share-block.tsx +16 -12
  631. package/src/components/chat/share-card.tsx +2 -2
  632. package/src/components/chat/subagent-view.tsx +4 -4
  633. package/src/components/chat/tool-call-timeline.tsx +75 -26
  634. package/src/components/chat/tool-cards/block-card.tsx +145 -0
  635. package/src/components/chat/tool-cards/image-mask-card.tsx +214 -0
  636. package/src/components/chat/tool-cards/location-card.tsx +159 -0
  637. package/src/components/chat/tool-views.tsx +30 -60
  638. package/src/components/chat/transcript-turn.tsx +108 -0
  639. package/src/components/chat/use-chat-commands.ts +14 -16
  640. package/src/components/chat/welcome-state.tsx +36 -91
  641. package/src/components/connectivity/connection-gate.tsx +32 -24
  642. package/src/components/connectivity/login-form.tsx +122 -0
  643. package/src/components/connectivity/login-screen.tsx +45 -100
  644. package/src/components/dev/share-harness.tsx +2 -2
  645. package/src/components/files/file-panel.tsx +168 -0
  646. package/src/components/files/file-tree-view.tsx +127 -0
  647. package/src/components/files/file-tree.tsx +55 -109
  648. package/src/components/files/file-viewer-binary.tsx +3 -2
  649. package/src/components/files/file-viewer-frame.tsx +113 -0
  650. package/src/components/files/file-viewer.tsx +40 -95
  651. package/src/components/files/frontmatter-chips.tsx +42 -0
  652. package/src/components/files/frontmatter-panel.tsx +6 -71
  653. package/src/components/files/staleness.ts +29 -0
  654. package/src/components/graph/graph-canvas.tsx +24 -1
  655. package/src/components/graph/graph-controls-column.tsx +92 -0
  656. package/src/components/graph/graph-controls.tsx +83 -127
  657. package/src/components/graph/graph-form.tsx +183 -0
  658. package/src/components/graph/graph-maintenance.tsx +9 -14
  659. package/src/components/graph/graph-node-rail.tsx +147 -0
  660. package/src/components/graph/graph-page.tsx +189 -49
  661. package/src/components/graph/graph-scene.tsx +200 -30
  662. package/src/components/graph/lib/graph-helpers.ts +65 -43
  663. package/src/components/graph/node-card.tsx +64 -0
  664. package/src/components/graph/node-popover.tsx +28 -117
  665. package/src/components/graph/use-graph-theme.ts +69 -32
  666. package/src/components/graph/use-node-actions.ts +56 -0
  667. package/src/components/images/image-share.ts +4 -2
  668. package/src/components/images/image-viewer.tsx +3 -1
  669. package/src/components/images/mask-editor.tsx +7 -4
  670. package/src/components/layout/app-shell.tsx +5 -1
  671. package/src/components/layout/desktop-palette.tsx +151 -0
  672. package/src/components/layout/key-cap.tsx +15 -0
  673. package/src/components/layout/mobile-tab-bar.tsx +80 -157
  674. package/src/components/layout/shortcut-switch.tsx +32 -0
  675. package/src/components/layout/side-rail.tsx +77 -150
  676. package/src/components/layout/slide-panel.tsx +49 -6
  677. package/src/components/layout/theme.tsx +67 -0
  678. package/src/components/quick-actions/add-form.tsx +196 -0
  679. package/src/components/quick-actions/add-modal.tsx +32 -153
  680. package/src/components/quick-actions/search-modal.tsx +15 -5
  681. package/src/components/quick-actions/streaming-modal.tsx +57 -72
  682. package/src/components/quick-actions/streaming-output.tsx +112 -0
  683. package/src/components/quick-actions/whatsup-modal.tsx +53 -59
  684. package/src/components/settings/devices-agents-tab.tsx +60 -152
  685. package/src/components/settings/models-list.tsx +299 -0
  686. package/src/components/settings/models-tab.tsx +63 -337
  687. package/src/components/settings/one-time-agent-credential.tsx +1 -1
  688. package/src/components/settings/passkey-list.tsx +201 -0
  689. package/src/components/settings/passkey-tab.tsx +53 -197
  690. package/src/components/settings/pi-accounts-list.tsx +128 -0
  691. package/src/components/settings/pi-accounts.tsx +71 -170
  692. package/src/components/settings/principal-list.tsx +172 -0
  693. package/src/components/settings/settings-panel.tsx +239 -25
  694. package/src/components/settings/skills-list.tsx +276 -0
  695. package/src/components/settings/skills-tab.tsx +82 -269
  696. package/src/components/settings/tool-permissions-list.tsx +54 -0
  697. package/src/components/settings/tool-permissions.tsx +27 -46
  698. package/src/components/settings/web-search-chain.tsx +300 -0
  699. package/src/components/settings/web-search-settings.tsx +58 -328
  700. package/src/components/share/share-menu.tsx +19 -4
  701. package/src/components/voice/dictation-sheet.tsx +5 -5
  702. package/src/components/voice/mic-button.tsx +1 -1
  703. package/src/components/voice/review-card.tsx +1 -1
  704. package/src/config.ts +21 -7
  705. package/src/connection.ts +443 -0
  706. package/src/default-root.ts +16 -0
  707. package/src/hooks/use-color-scheme.ts +36 -0
  708. package/src/hooks/use-fine-pointer.ts +15 -0
  709. package/src/hooks/use-hash-routes.ts +4 -2
  710. package/src/hooks/use-media-query.ts +35 -0
  711. package/src/hooks/use-share-intake.ts +32 -12
  712. package/src/hooks/use-vpn-status.ts +18 -17
  713. package/src/hooks/use-websocket.ts +12 -428
  714. package/src/hooks/websocket-handlers/activity.ts +4 -5
  715. package/src/hooks/websocket-handlers/chat.ts +28 -6
  716. package/src/hooks/websocket-handlers/connection.ts +4 -6
  717. package/src/hooks/websocket-handlers/mask.ts +2 -3
  718. package/src/hooks/websocket-handlers/provider.ts +4 -6
  719. package/src/hooks/websocket-handlers/types.ts +6 -2
  720. package/src/index.ts +7 -3
  721. package/src/lib/api-client.ts +426 -384
  722. package/src/lib/backend.ts +20 -10
  723. package/src/lib/diff.ts +28 -62
  724. package/src/lib/light-dark.ts +83 -0
  725. package/src/lib/mermaid-theme.ts +183 -214
  726. package/src/lib/passkeys.ts +12 -4
  727. package/src/lib/push-registration.ts +19 -2
  728. package/src/lib/share-intake.ts +6 -3
  729. package/src/lib/share.ts +7 -4
  730. package/src/lib/single-key.ts +47 -0
  731. package/src/lib/tool-names.ts +31 -8
  732. package/src/root-context.tsx +40 -0
  733. package/src/root.ts +83 -0
  734. package/src/stores/activity-state.ts +295 -0
  735. package/src/stores/activity-store.ts +11 -285
  736. package/src/stores/chat-state.ts +822 -0
  737. package/src/stores/chat-store.ts +11 -705
  738. package/src/stores/connection-state.ts +78 -0
  739. package/src/stores/connection-store.ts +11 -76
  740. package/src/stores/create-stores.ts +31 -0
  741. package/src/stores/file-state.ts +399 -0
  742. package/src/stores/file-store.ts +9 -390
  743. package/src/stores/graph-state.ts +368 -0
  744. package/src/stores/graph-store.ts +10 -355
  745. package/src/stores/mask-state.ts +30 -0
  746. package/src/stores/mask-store.ts +10 -27
  747. package/src/stores/principal-state.ts +42 -0
  748. package/src/stores/principal-store.ts +10 -37
  749. package/src/stores/provider-state.ts +103 -0
  750. package/src/stores/provider-store.ts +10 -95
  751. package/src/stores/share-state.ts +56 -0
  752. package/src/stores/share-store.ts +11 -54
  753. package/src/stores/store-environment.ts +10 -0
  754. package/src/stores/ui-state.ts +143 -0
  755. package/src/stores/ui-store.ts +11 -93
  756. package/src/styles.css +4 -1
  757. package/src/theme.css +150 -97
  758. package/src/voice/asr-clients.ts +17 -17
  759. package/src/voice/use-dictation.ts +11 -8
  760. package/src/voice/voice-state.ts +57 -0
  761. package/src/voice/voice-store.ts +11 -55
@@ -2,14 +2,16 @@ import { Fragment, useEffect, useMemo, useState } from "react";
2
2
  import { ArrowLeft, ChevronRight } from "lucide-react";
3
3
  import { useShallow } from "zustand/react/shallow";
4
4
  import { isFailureOutcome, type ActivitySpan } from "@schlessera/brain-ui-sdk/protocol";
5
+ import { TraceSteps, type TraceStep } from "@schlessera/brain-ui-kit";
5
6
 
6
- import { api, type ActivityRunRollup } from "../../lib/api-client.js";
7
+ import type { ActivityRunRollup } from "../../lib/api-client.js";
7
8
  import {
8
9
  useActivityStore,
9
10
  narrativeEventsFor,
10
11
  runEvents,
11
12
  runSpans,
12
13
  } from "../../stores/activity-store.js";
14
+ import { useBrainApi } from "../../root-context.js";
13
15
  import { cn } from "../../lib/utils.js";
14
16
  import { formatDuration, formatRelativeTime } from "../chat/tool-views.js";
15
17
  import {
@@ -20,14 +22,29 @@ import {
20
22
  formatSpanUsage,
21
23
  spanToolLabel,
22
24
  } from "./span-bits.js";
25
+ import { RunRollupReceipt } from "./activity-views.js";
23
26
 
24
27
  /**
25
28
  * Chat-less run detail (cron runs; pruned runs show their rollup) — the full
26
29
  * view of one run: its rollup header, the span tree with per-span usage,
27
30
  * attributes and recorded events, and a raw-trace escape hatch for anything
28
31
  * the rendered view does not have an opinion about.
32
+ *
33
+ * `embedded` is the D4 desktop pane: the Actions list sits beside this view
34
+ * from `laptop:` up, so the back chevron only renders below that width, and
35
+ * from `wide:` the span tree moves out to the page's evidence rail
36
+ * (`RunTraceSteps`) — the same store slice, fetched once here.
29
37
  */
30
- export function RunDetail({ runId, onBack }: { runId: string; onBack: () => void }) {
38
+ export function RunDetail({
39
+ runId,
40
+ onBack,
41
+ embedded = false,
42
+ }: {
43
+ runId: string;
44
+ onBack: () => void;
45
+ embedded?: boolean;
46
+ }) {
47
+ const api = useBrainApi();
31
48
  const streamed = useActivityStore(useShallow((s) => runSpans(s, runId)));
32
49
  const events = useActivityStore(useShallow((s) => runEvents(s, runId)));
33
50
  const applySnapshot = useActivityStore((s) => s.applySnapshot);
@@ -38,6 +55,10 @@ export function RunDetail({ runId, onBack }: { runId: string; onBack: () => void
38
55
 
39
56
  useEffect(() => {
40
57
  let active = true;
58
+ setPruned(null);
59
+ setRollup(null);
60
+ setMissing(false);
61
+ setRawOpen(false);
41
62
  api
42
63
  // Payload bodies are excluded from run detail by default; this view's
43
64
  // rows expand to them, so opt in.
@@ -64,7 +85,7 @@ export function RunDetail({ runId, onBack }: { runId: string; onBack: () => void
64
85
  return () => {
65
86
  active = false;
66
87
  };
67
- }, [runId, applySnapshot]);
88
+ }, [runId, applySnapshot, api]);
68
89
 
69
90
  const root = streamed.find((s) => !s.parentSpanId);
70
91
  const title = rollup?.jobName ?? rollup?.name ?? (root ? spanToolLabel(root) : runId);
@@ -93,7 +114,10 @@ export function RunDetail({ runId, onBack }: { runId: string; onBack: () => void
93
114
  <button
94
115
  type="button"
95
116
  onClick={onBack}
96
- className="rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-surface-raised hover:text-foreground"
117
+ className={cn(
118
+ "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-surface-raised hover:text-foreground",
119
+ embedded && "laptop:hidden"
120
+ )}
97
121
  aria-label="Back"
98
122
  >
99
123
  <ArrowLeft className="h-4 w-4" />
@@ -108,46 +132,18 @@ export function RunDetail({ runId, onBack }: { runId: string; onBack: () => void
108
132
  <div className="mx-auto w-full max-w-3xl space-y-1 p-4">
109
133
  {missing && <p className="text-xs text-muted-foreground">Unknown run.</p>}
110
134
  {rollup && (
111
- <div className="mb-2 flex flex-wrap items-center gap-x-3 gap-y-0.5 rounded-lg border border-border-subtle bg-surface px-3 py-2 text-[11px] text-muted-foreground">
112
- <span className="text-foreground/80">{rollup.origin}</span>
113
- {rollup.outcome && (
114
- <span className={cn(isFailureOutcome(rollup.outcome) && "text-destructive")}>
115
- {rollup.outcome}
116
- </span>
117
- )}
118
- <span>{formatRelativeTime(rollup.startedAt)}</span>
119
- {rollup.durationMs !== null && <span>{formatDuration(rollup.durationMs)}</span>}
120
- <span>
121
- list{" "}
122
- <span className="font-[family-name:var(--font-mono)] text-foreground/80">
123
- {formatEffectiveCost(rollup.costUsd)}
124
- </span>
125
- </span>
126
- <span>
127
- effective{" "}
128
- <span className="font-[family-name:var(--font-mono)] text-foreground/80">
129
- {formatEffectiveCost(
130
- rollup.effectiveCostUsd,
131
- rollup.pricingEstimate,
132
- rollup.billingMode
133
- )}
134
- </span>
135
- </span>
136
- {rollup.billingMode && (
137
- <span>{rollup.billingMode === "api" ? "API billed" : "subscription billed"}</span>
138
- )}
139
- {rollup.pricingEstimate && <span>~ estimated rates</span>}
140
- {totalUsage && (
141
- <span className="font-[family-name:var(--font-mono)] text-foreground/80">
142
- {totalUsage}
143
- </span>
144
- )}
145
- {rollup.failureReason && (
146
- <span className="w-full whitespace-pre-wrap break-words pt-1 text-destructive/80">
147
- {rollup.failureReason}
148
- </span>
149
- )}
150
- </div>
135
+ <RunRollupReceipt
136
+ origin={rollup.origin}
137
+ outcome={rollup.outcome}
138
+ when={formatRelativeTime(rollup.startedAt)}
139
+ duration={rollup.durationMs !== null ? formatDuration(rollup.durationMs) : null}
140
+ listCost={formatEffectiveCost(rollup.costUsd)}
141
+ effectiveCost={formatEffectiveCost(rollup.effectiveCostUsd, rollup.pricingEstimate, rollup.billingMode)}
142
+ billing={rollup.billingMode ? (rollup.billingMode === "api" ? "API billed" : "subscription billed") : null}
143
+ estimated={Boolean(rollup.pricingEstimate)}
144
+ usage={totalUsage}
145
+ failureReason={rollup.failureReason}
146
+ />
151
147
  )}
152
148
  {pruned && (
153
149
  <div className="rounded-lg border border-border-subtle bg-surface p-3 text-xs text-muted-foreground">
@@ -155,9 +151,11 @@ export function RunDetail({ runId, onBack }: { runId: string; onBack: () => void
155
151
  <pre className="mt-2 overflow-x-auto text-[11px]">{JSON.stringify(pruned, null, 2)}</pre>
156
152
  </div>
157
153
  )}
158
- {streamed.map((span) => (
159
- <DetailSpanRow key={span.spanId} span={span} depth={depthOf(span, streamed)} />
160
- ))}
154
+ <div className={cn("space-y-1", embedded && "wide:hidden")}>
155
+ {streamed.map((span) => (
156
+ <DetailSpanRow key={span.spanId} span={span} depth={depthOf(span, streamed)} />
157
+ ))}
158
+ </div>
161
159
  {!pruned && !missing && streamed.length === 0 && (
162
160
  <p className="text-xs text-muted-foreground">No spans recorded for this run.</p>
163
161
  )}
@@ -187,6 +185,42 @@ export function RunDetail({ runId, onBack }: { runId: string; onBack: () => void
187
185
  );
188
186
  }
189
187
 
188
+ /**
189
+ * The run's trace as the kit's list timeline, for the D4 evidence rail. Reads
190
+ * the store slice `RunDetail` filled — no second fetch — and stays a record:
191
+ * the rail's steps do not expand, the escape hatch for that is the detail's
192
+ * raw trace.
193
+ */
194
+ export function RunTraceSteps({ runId }: { runId: string }) {
195
+ const streamed = useActivityStore(useShallow((s) => runSpans(s, runId)));
196
+ const steps = useMemo<TraceStep[]>(
197
+ () =>
198
+ streamed.map((span) => ({
199
+ state: traceState(span),
200
+ tool: spanToolLabel(span),
201
+ text: span.outcomeReason ?? (span.kind !== "tool" ? span.kind : undefined),
202
+ time:
203
+ span.endedAt !== undefined
204
+ ? formatDuration(span.endedAt - (span.waitUntil ?? span.startedAt))
205
+ : undefined,
206
+ })),
207
+ [streamed]
208
+ );
209
+ if (steps.length === 0) {
210
+ return <p className="text-xs text-muted-foreground/70">No spans recorded for this run.</p>;
211
+ }
212
+ return <TraceSteps variant="list" steps={steps} />;
213
+ }
214
+
215
+ /** Same boundary `toolState` draws for the run cards: open is active, a
216
+ * failure outcome is failed and any other non-success outcome (cancelled,
217
+ * skipped) is skipped. */
218
+ function traceState(span: ActivitySpan): TraceStep["state"] {
219
+ if (span.outcome === undefined || span.outcome === null) return "active";
220
+ if (span.outcome === "success") return "done";
221
+ return isFailureOutcome(span.outcome) ? "failed" : "skipped";
222
+ }
223
+
190
224
  /**
191
225
  * One span tree row. EVERY span expands — a tool span to its recorded payload
192
226
  * (AE7), any span to its usage, attributes and recorded events. The uniform
@@ -1,14 +1,19 @@
1
- import { AlertTriangle, Bot, Clock, Timer } from "lucide-react";
2
1
  import { useShallow } from "zustand/react/shallow";
3
- import { isFailureOutcome, type ActivitySpan } from "@schlessera/brain-ui-sdk/protocol";
2
+ import type { ActivitySpan } from "@schlessera/brain-ui-sdk/protocol";
4
3
 
5
4
  import type { ActivityRunSummary } from "../../lib/api-client.js";
6
5
  import { useNow } from "../../hooks/use-now.js";
7
6
  import { useActivityStore } from "../../stores/activity-store.js";
8
- import { cn } from "../../lib/utils.js";
9
7
  import { formatDuration, formatRelativeTime } from "../chat/tool-views.js";
8
+ import { HistoryRow, LiveRunCard, toolState } from "./activity-views.js";
10
9
  import { runCostText, spanToolLabel } from "./span-bits.js";
11
10
 
11
+ /**
12
+ * The containers (S7) for the Activity index's rows: `LiveRow` subscribes to
13
+ * a running run's child spans and renders a `LiveRunCard`; `RunRow` is a
14
+ * recorded run rendered as a `HistoryRow`. The views are in
15
+ * `activity-views.tsx`.
16
+ */
12
17
  export function LiveRow({
13
18
  span,
14
19
  onOpen,
@@ -21,31 +26,16 @@ export function LiveRow({
21
26
  );
22
27
  const now = useNow();
23
28
  const current = children.filter((c) => c.outcome === undefined).at(-1);
24
- const currentLabel = current ? spanToolLabel(current) : null;
25
29
  return (
26
- <button
27
- type="button"
28
- onClick={() => onOpen({ runId: span.runId, origin: span.origin, sessionId: span.sessionId })}
29
- className="flex w-full items-center gap-2 rounded-lg border border-border-subtle bg-surface px-3 py-2 text-left text-xs transition-colors hover:bg-surface-raised"
30
- >
31
- <span className="h-2 w-2 shrink-0 animate-pulse rounded-full bg-primary" />
32
- {span.origin === "cron" ? (
33
- <Clock className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
34
- ) : (
35
- <Bot className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
36
- )}
37
- <span className="truncate font-medium">
38
- {span.jobName ?? span.name}
39
- </span>
40
- {/* A span-only run (plain cron job) has no current step — name+elapsed
41
- is its whole live story. */}
42
- {currentLabel && (
43
- <span className="truncate text-muted-foreground">· {currentLabel}</span>
44
- )}
45
- <span className="ml-auto shrink-0 font-[family-name:var(--font-mono)] text-[10px] text-muted-foreground/60">
46
- {formatDuration(now - span.startedAt)}
47
- </span>
48
- </button>
30
+ <LiveRunCard
31
+ name={span.jobName ?? span.name}
32
+ // A span-only run (plain cron job) has no current step — name+elapsed
33
+ // is its whole live story.
34
+ current={current ? spanToolLabel(current) : null}
35
+ elapsed={formatDuration(now - span.startedAt)}
36
+ tools={children.map((c) => ({ label: spanToolLabel(c), state: toolState(c.outcome) }))}
37
+ onOpen={() => onOpen({ runId: span.runId, origin: span.origin, sessionId: span.sessionId })}
38
+ />
49
39
  );
50
40
  }
51
41
 
@@ -56,42 +46,20 @@ export function RunRow({
56
46
  run: ActivityRunSummary;
57
47
  onOpen: (row: ActivityRunSummary) => void;
58
48
  }) {
59
- const failed = isFailureOutcome(run.outcome);
60
49
  // Effective cost only — list price lives on the Spend card and the detail
61
50
  // view. "—" is unknown, never $0.00 (AE3); a pre-pricing server that never
62
51
  // sent the field keeps the original list-cost span instead (see runCostText).
63
52
  const cost = runCostText(run);
53
+ const meta = [cost, run.durationMs !== null ? formatDuration(run.durationMs) : null, formatRelativeTime(run.startedAt)]
54
+ .filter((s): s is string => Boolean(s))
55
+ .join(" · ");
64
56
  return (
65
- <button
66
- type="button"
67
- onClick={() => onOpen(run)}
68
- className={cn(
69
- "flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left text-xs transition-colors hover:bg-surface-raised",
70
- failed && "border border-destructive/30 bg-destructive/5"
71
- )}
72
- >
73
- {run.origin === "cron" ? (
74
- <Clock className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
75
- ) : (
76
- <Bot className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
77
- )}
78
- <span className="truncate">{run.jobName ?? run.name}</span>
79
- {failed && <AlertTriangle className="h-3 w-3 shrink-0 text-destructive" />}
80
- {run.outcome && run.outcome !== "success" && (
81
- <span className={cn("text-[10px] uppercase", failed ? "text-destructive" : "text-muted-foreground")}>
82
- {run.outcome}
83
- </span>
84
- )}
85
- <span className="ml-auto flex shrink-0 items-center gap-2 font-[family-name:var(--font-mono)] text-[10px] text-muted-foreground/60">
86
- {cost !== null && <span>{cost}</span>}
87
- {run.durationMs !== null && (
88
- <span className="flex items-center gap-0.5">
89
- <Timer className="h-3 w-3" />
90
- {formatDuration(run.durationMs)}
91
- </span>
92
- )}
93
- <span>{formatRelativeTime(run.startedAt)}</span>
94
- </span>
95
- </button>
57
+ <HistoryRow
58
+ name={run.jobName ?? run.name}
59
+ cron={run.origin === "cron"}
60
+ outcome={run.outcome}
61
+ meta={meta}
62
+ onOpen={() => onOpen(run)}
63
+ />
96
64
  );
97
65
  }
@@ -0,0 +1,155 @@
1
+ import { ActionCard, AgentRunCard, Button, ListRow, Receipt } from "@schlessera/brain-ui-kit";
2
+ import type { AgentRunTool, ReceiptRow, RunToolState } from "@schlessera/brain-ui-kit";
3
+ import { isFailureOutcome, type ActivityIntent, type ActivitySpanOutcome } from "@schlessera/brain-ui-sdk/protocol";
4
+
5
+ /**
6
+ * The Activity surface's rows, rendered from props (S7, the `activity`
7
+ * directory). The design's `1c` screen draws a running run as an
8
+ * `AgentRunCard` (the tool strip is "the shortest honest answer to 'is real
9
+ * work happening?'") and the day's history as plain `ListRow`s; `1c`/`2a`
10
+ * draw a thing that needs you as an `ActionCard`. The containers in
11
+ * `activity-run-list.tsx`, `activity-page.tsx` and `activity-run-detail.tsx`
12
+ * read the store and the API; these decide how a row looks.
13
+ */
14
+
15
+ /** A child span's outcome as the kit's tool-strip state. */
16
+ export function toolState(outcome: ActivitySpanOutcome | undefined | null): RunToolState {
17
+ if (outcome === undefined || outcome === null) return "active";
18
+ if (outcome === "success") return "done";
19
+ return isFailureOutcome(outcome) ? "failed" : "idle";
20
+ }
21
+
22
+ export interface LiveRunCardProps {
23
+ name: string;
24
+ /** The step in flight, if the run has steps at all (a plain cron job has none). */
25
+ current: string | null;
26
+ elapsed: string;
27
+ tools: AgentRunTool[];
28
+ onOpen: () => void;
29
+ }
30
+
31
+ /**
32
+ * A running run. The kit card carries no handler of its own — the design
33
+ * draws it as a monitor — so the row is a native button around it, named
34
+ * for what opening it does.
35
+ */
36
+ export function LiveRunCard(p: LiveRunCardProps) {
37
+ return (
38
+ <button
39
+ type="button"
40
+ onClick={p.onOpen}
41
+ aria-label={`Open run ${p.name}`}
42
+ className="block w-full rounded-[13px] text-left transition-[filter] hover:brightness-110 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--bk-focus-ring)]"
43
+ >
44
+ <AgentRunCard
45
+ agent={p.name}
46
+ state="running"
47
+ meta={p.elapsed}
48
+ task={p.current ? `▸ ${p.current}` : undefined}
49
+ progress={null}
50
+ tools={p.tools.length ? p.tools : undefined}
51
+ />
52
+ </button>
53
+ );
54
+ }
55
+
56
+ export interface HistoryRowProps {
57
+ name: string;
58
+ cron: boolean;
59
+ /** The run's outcome, or null while unknown. */
60
+ outcome: ActivitySpanOutcome | null;
61
+ /** Cost, duration and when — already formatted, joined with a middle dot. */
62
+ meta: string;
63
+ onOpen: () => void;
64
+ }
65
+
66
+ export function HistoryRow(p: HistoryRowProps) {
67
+ const failed = isFailureOutcome(p.outcome);
68
+ return (
69
+ <ListRow
70
+ variant="plain"
71
+ icon={p.cron ? "repeat" : "agent"}
72
+ iconTone={failed ? "red" : "neutral"}
73
+ title={p.name}
74
+ subtitle={p.outcome && p.outcome !== "success" ? p.outcome : undefined}
75
+ subMono
76
+ value={p.meta}
77
+ valueTone={failed ? "red" : "neutral"}
78
+ onClick={p.onOpen}
79
+ />
80
+ );
81
+ }
82
+
83
+ export interface IntentCardProps {
84
+ intent: ActivityIntent;
85
+ /** When it was raised, already formatted. */
86
+ when: string;
87
+ onOpen: () => void;
88
+ onDismiss: () => void;
89
+ /** Print `d` on Dismiss: the list binds it while the card holds focus (D36). */
90
+ keyHint?: boolean;
91
+ }
92
+
93
+ /** A thing that needs attention: failure, stuck, or a completion to note. */
94
+ export function IntentCard(p: IntentCardProps) {
95
+ const kind = p.intent.kind;
96
+ return (
97
+ <ActionCard
98
+ kind={kind === "failure" ? "dead-letter" : "fyi"}
99
+ icon={kind === "stuck" ? "deadline" : undefined}
100
+ kindLabel={kind === "failure" ? "Failed" : kind === "stuck" ? "Stuck" : "Completed"}
101
+ title={p.intent.title}
102
+ body={p.intent.body || undefined}
103
+ footMeta={p.when}
104
+ footDot={kind === "failure" ? "red" : kind === "stuck" ? "amber" : "teal"}
105
+ footPulse={kind === "stuck"}
106
+ chevron={false}
107
+ onClick={p.onOpen}
108
+ >
109
+ <div className="mt-2 flex justify-end" onClick={(e) => e.stopPropagation()}>
110
+ <Button label={p.keyHint ? "Dismiss · d" : "Dismiss"} tone="quiet" size="sm" block={false} onClick={p.onDismiss} />
111
+ </div>
112
+ </ActionCard>
113
+ );
114
+ }
115
+
116
+ export interface RunRollupReceiptProps {
117
+ origin: string;
118
+ outcome: ActivitySpanOutcome | null;
119
+ when: string;
120
+ duration: string | null;
121
+ listCost: string;
122
+ effectiveCost: string;
123
+ billing: string | null;
124
+ estimated: boolean;
125
+ usage: string | null;
126
+ failureReason: string | null;
127
+ }
128
+
129
+ /** The rollup header of a run's detail: machine facts, key/value, as a `Receipt`. */
130
+ export function RunRollupReceipt(p: RunRollupReceiptProps) {
131
+ const failed = isFailureOutcome(p.outcome);
132
+ const rows: ReceiptRow[] = [
133
+ { k: "origin", v: p.origin },
134
+ ...(p.outcome ? [{ k: "outcome", v: p.outcome, tone: failed ? ("red" as const) : ("teal" as const) }] : []),
135
+ { k: "started", v: p.when },
136
+ ...(p.duration ? [{ k: "took", v: p.duration }] : []),
137
+ { k: "list", v: p.listCost },
138
+ { k: "effective", v: `${p.effectiveCost}${p.billing ? ` · ${p.billing}` : ""}${p.estimated ? " · ~ estimated rates" : ""}` },
139
+ ...(p.usage ? [{ k: "usage", v: p.usage }] : []),
140
+ ];
141
+ return (
142
+ <div className="mb-2">
143
+ <Receipt
144
+ title="This run"
145
+ titleIcon="ledger"
146
+ titleTone={failed ? "red" : "teal"}
147
+ rows={rows}
148
+ footnote={p.failureReason ?? ""}
149
+ footIcon={p.failureReason ? "failed" : undefined}
150
+ footTone={p.failureReason ? "red" : undefined}
151
+ keyWidth={66}
152
+ />
153
+ </div>
154
+ );
155
+ }
@@ -0,0 +1,117 @@
1
+ import { ActionCard, Button } from "@schlessera/brain-ui-kit";
2
+ import type { KeyboardEvent } from "react";
3
+ import type { ClientMessage } from "@schlessera/brain-ui-sdk/protocol";
4
+ import { offersAlwaysAllow, type ToolCall } from "../../stores/chat-store.js";
5
+ import { focusAfterDecision, singleKey } from "../../lib/single-key.js";
6
+ import { effectOf, getToolLabel, getToolSummary } from "../chat/tool-views.js";
7
+ import { KeyCap } from "../layout/key-cap.js";
8
+ import { useFinePointer } from "../../hooks/use-fine-pointer.js";
9
+
10
+ /**
11
+ * A pending tool approval as an Actions-pane card (D37): the transcript copy
12
+ * and this row are the same item in two places, and deciding either
13
+ * resolves both. The kit `ActionCard kind="approval"` carries the bold
14
+ * border that says "a run is stopped on this"; the buttons are the same
15
+ * three the transcript draws, with the same keys — `a` / `d` while the card
16
+ * holds focus, printed on the buttons, and "Always allow" deliberately
17
+ * without one, carrying its `write_policy` effect chip instead. The hint
18
+ * is printed only while a fine pointer is present (#86); the letters follow
19
+ * `keys` alone, so a paired keyboard works even if the pointer query stays coarse.
20
+ *
21
+ * The buttons follow the kit `ApprovalCard`'s rule (seventh drop, ruling 10):
22
+ * Allow takes the remaining width, Deny is content-sized with a 96 x 44 floor
23
+ * so it can never become a sliver, and no even split claims the two answers
24
+ * are equally likely. The title — the tool and its target — is the kit
25
+ * `ActionCard`'s, which wraps; the target is the record and never truncates.
26
+ */
27
+ const ALLOW_MOUNT = { flex: "1 1 auto", minWidth: 0, width: "auto" } as const;
28
+ const DENY_MOUNT = { flex: "0 0 auto", minWidth: 96, minHeight: 44, width: "auto" } as const;
29
+ export interface ApprovalCardProps {
30
+ tool: ToolCall;
31
+ /** Where it came from, for the foot line. */
32
+ origin: string;
33
+ keys: boolean;
34
+ onDecide: (approved: boolean, always?: boolean) => void;
35
+ }
36
+
37
+ export const APPROVAL_CARD = "[data-approval-card]";
38
+
39
+ /**
40
+ * What a decision on an Actions card prints and sends. The receipt follows
41
+ * what the card was allowed to offer, not the click (#147): "Always allowed"
42
+ * claims a policy write, and the host refuses one the card did not offer —
43
+ * so an `always` the card could not have offered is neither printed nor
44
+ * sent. A card no longer in the list (`tool` undefined) offered nothing.
45
+ */
46
+ export function approvalOutcome(
47
+ tool: ToolCall | undefined,
48
+ toolUseId: string,
49
+ approved: boolean,
50
+ asked?: boolean
51
+ ): {
52
+ receipt: { text: string; target: string; effect: string };
53
+ frame: Extract<ClientMessage, { type: "tool_approval" | "tool_denial" }>;
54
+ } {
55
+ const always = approved && asked === true && tool !== undefined && offersAlwaysAllow(tool);
56
+ return {
57
+ receipt: {
58
+ text: approved ? (always ? "Always allowed" : "Allowed") : "Denied",
59
+ target: tool ? tool.name : toolUseId,
60
+ effect: always ? "write_policy" : approved ? "tool_approval" : "tool_denial",
61
+ },
62
+ // Every decision on this surface is made on the card (#113).
63
+ frame: approved
64
+ ? { type: "tool_approval", toolUseId, ...(always ? { always: true } : {}), channel: "card" }
65
+ : { type: "tool_denial", toolUseId, message: "Denied by user", channel: "card" },
66
+ };
67
+ }
68
+
69
+ export function ApprovalCard(p: ApprovalCardProps) {
70
+ const label = getToolLabel(p.tool.name);
71
+ const summary = getToolSummary(p.tool);
72
+ const finePointer = useFinePointer();
73
+ const printKeys = p.keys && finePointer;
74
+ function decide(card: HTMLElement | null, approved: boolean, always?: boolean) {
75
+ if (card) focusAfterDecision(card, APPROVAL_CARD, "[data-needs-you-heading]");
76
+ p.onDecide(approved, always);
77
+ }
78
+ function onKeyDown(event: KeyboardEvent<HTMLDivElement>) {
79
+ if (!p.keys) return;
80
+ const key = singleKey(event);
81
+ if (key !== "a" && key !== "d") return;
82
+ event.preventDefault();
83
+ decide(event.currentTarget, key === "a");
84
+ }
85
+ return (
86
+ <div data-approval-card="" role="group" aria-label={`Approval: ${label}`} tabIndex={0} onKeyDown={onKeyDown} className="rounded-[14px] outline-none focus-visible:ring-2 focus-visible:ring-primary/50">
87
+ <ActionCard
88
+ kind="approval"
89
+ title={summary ? `${label} · ${summary}` : label}
90
+ rightMeta="blocks a run"
91
+ rightMetaTone="red"
92
+ {...(effectOf(p.tool) ? { body: effectOf(p.tool) } : {})}
93
+ footMeta={p.origin}
94
+ footDot="amber"
95
+ footPulse
96
+ chevron={false}
97
+ >
98
+ <div className="mt-2 flex flex-wrap gap-2">
99
+ <Button label="Allow" icon="confirm" tone="primary" size="sm" center block={false} style={ALLOW_MOUNT} onClick={() => decide(cardOf(), true)} />
100
+ {offersAlwaysAllow(p.tool) && (
101
+ <Button label="Always allow" effect="write_policy" tone="ghost" size="sm" block={false} onClick={() => decide(cardOf(), true, true)} />
102
+ )}
103
+ <Button label="Deny" icon="deny" tone="danger" size="sm" center block={false} style={DENY_MOUNT} onClick={() => decide(cardOf(), false)} />
104
+ {printKeys && (
105
+ <span className="ml-auto flex items-center gap-2 text-[10px] text-muted-foreground" aria-hidden="true">
106
+ <span>allow <KeyCap>a</KeyCap></span>
107
+ <span>deny <KeyCap>d</KeyCap></span>
108
+ </span>
109
+ )}
110
+ </div>
111
+ </ActionCard>
112
+ </div>
113
+ );
114
+ function cardOf(): HTMLElement | null {
115
+ return (document.activeElement as HTMLElement | null)?.closest(APPROVAL_CARD) ?? null;
116
+ }
117
+ }