@schlessera/brain-ui-react 0.35.0 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (761) hide show
  1. package/README.md +82 -4
  2. package/dist/components/activity/activity-page.d.ts +17 -5
  3. package/dist/components/activity/activity-page.d.ts.map +1 -1
  4. package/dist/components/activity/activity-page.js +148 -50
  5. package/dist/components/activity/activity-page.js.map +1 -1
  6. package/dist/components/activity/activity-run-detail.d.ts +16 -1
  7. package/dist/components/activity/activity-run-detail.d.ts.map +1 -1
  8. package/dist/components/activity/activity-run-detail.js +47 -4
  9. package/dist/components/activity/activity-run-detail.js.map +1 -1
  10. package/dist/components/activity/activity-run-list.d.ts +7 -1
  11. package/dist/components/activity/activity-run-list.d.ts.map +1 -1
  12. package/dist/components/activity/activity-run-list.js +16 -8
  13. package/dist/components/activity/activity-run-list.js.map +1 -1
  14. package/dist/components/activity/activity-views.d.ts +63 -0
  15. package/dist/components/activity/activity-views.d.ts.map +1 -0
  16. package/dist/components/activity/activity-views.js +52 -0
  17. package/dist/components/activity/activity-views.js.map +1 -0
  18. package/dist/components/activity/approval-card.d.ts +29 -0
  19. package/dist/components/activity/approval-card.d.ts.map +1 -0
  20. package/dist/components/activity/approval-card.js +73 -0
  21. package/dist/components/activity/approval-card.js.map +1 -0
  22. package/dist/components/activity/digest-card.d.ts +3 -0
  23. package/dist/components/activity/digest-card.d.ts.map +1 -1
  24. package/dist/components/activity/digest-card.js +20 -16
  25. package/dist/components/activity/digest-card.js.map +1 -1
  26. package/dist/components/activity/digest-summary.d.ts +19 -0
  27. package/dist/components/activity/digest-summary.d.ts.map +1 -0
  28. package/dist/components/activity/digest-summary.js +20 -0
  29. package/dist/components/activity/digest-summary.js.map +1 -0
  30. package/dist/components/activity/push-switch.d.ts +25 -0
  31. package/dist/components/activity/push-switch.d.ts.map +1 -0
  32. package/dist/components/activity/push-switch.js +14 -0
  33. package/dist/components/activity/push-switch.js.map +1 -0
  34. package/dist/components/activity/push-toggle.d.ts +7 -0
  35. package/dist/components/activity/push-toggle.d.ts.map +1 -1
  36. package/dist/components/activity/push-toggle.js +72 -47
  37. package/dist/components/activity/push-toggle.js.map +1 -1
  38. package/dist/components/activity/span-bits.d.ts +11 -0
  39. package/dist/components/activity/span-bits.d.ts.map +1 -1
  40. package/dist/components/activity/span-bits.js +50 -7
  41. package/dist/components/activity/span-bits.js.map +1 -1
  42. package/dist/components/chat/ask-user-card.d.ts +76 -3
  43. package/dist/components/chat/ask-user-card.d.ts.map +1 -1
  44. package/dist/components/chat/ask-user-card.js +208 -149
  45. package/dist/components/chat/ask-user-card.js.map +1 -1
  46. package/dist/components/chat/ask-user-typed.d.ts +42 -0
  47. package/dist/components/chat/ask-user-typed.d.ts.map +1 -0
  48. package/dist/components/chat/ask-user-typed.js +60 -0
  49. package/dist/components/chat/ask-user-typed.js.map +1 -0
  50. package/dist/components/chat/brain-markdown-links.d.ts +2 -1
  51. package/dist/components/chat/brain-markdown-links.d.ts.map +1 -1
  52. package/dist/components/chat/brain-markdown-links.js +3 -4
  53. package/dist/components/chat/brain-markdown-links.js.map +1 -1
  54. package/dist/components/chat/brain-markdown.d.ts.map +1 -1
  55. package/dist/components/chat/brain-markdown.js +4 -2
  56. package/dist/components/chat/brain-markdown.js.map +1 -1
  57. package/dist/components/chat/chat-page.d.ts.map +1 -1
  58. package/dist/components/chat/chat-page.js +27 -11
  59. package/dist/components/chat/chat-page.js.map +1 -1
  60. package/dist/components/chat/composer-view.d.ts +75 -0
  61. package/dist/components/chat/composer-view.d.ts.map +1 -0
  62. package/dist/components/chat/composer-view.js +31 -0
  63. package/dist/components/chat/composer-view.js.map +1 -0
  64. package/dist/components/chat/composer.d.ts +4 -0
  65. package/dist/components/chat/composer.d.ts.map +1 -1
  66. package/dist/components/chat/composer.js +76 -59
  67. package/dist/components/chat/composer.js.map +1 -1
  68. package/dist/components/chat/markdown-content.d.ts +16 -1
  69. package/dist/components/chat/markdown-content.d.ts.map +1 -1
  70. package/dist/components/chat/markdown-content.js +47 -3
  71. package/dist/components/chat/markdown-content.js.map +1 -1
  72. package/dist/components/chat/mermaid-block.d.ts +4 -0
  73. package/dist/components/chat/mermaid-block.d.ts.map +1 -1
  74. package/dist/components/chat/mermaid-block.js +13 -5
  75. package/dist/components/chat/mermaid-block.js.map +1 -1
  76. package/dist/components/chat/mermaid-share.d.ts +2 -1
  77. package/dist/components/chat/mermaid-share.d.ts.map +1 -1
  78. package/dist/components/chat/mermaid-share.js +7 -8
  79. package/dist/components/chat/mermaid-share.js.map +1 -1
  80. package/dist/components/chat/mermaid-viewer.d.ts.map +1 -1
  81. package/dist/components/chat/mermaid-viewer.js +3 -1
  82. package/dist/components/chat/mermaid-viewer.js.map +1 -1
  83. package/dist/components/chat/message-bubble.d.ts +8 -1
  84. package/dist/components/chat/message-bubble.d.ts.map +1 -1
  85. package/dist/components/chat/message-bubble.js +53 -24
  86. package/dist/components/chat/message-bubble.js.map +1 -1
  87. package/dist/components/chat/message-share.d.ts +2 -1
  88. package/dist/components/chat/message-share.d.ts.map +1 -1
  89. package/dist/components/chat/message-share.js +6 -7
  90. package/dist/components/chat/message-share.js.map +1 -1
  91. package/dist/components/chat/renderers/bind.d.ts +39 -0
  92. package/dist/components/chat/renderers/bind.d.ts.map +1 -0
  93. package/dist/components/chat/renderers/bind.js +43 -0
  94. package/dist/components/chat/renderers/bind.js.map +1 -0
  95. package/dist/components/chat/renderers/brain-ui-tools.d.ts +3 -0
  96. package/dist/components/chat/renderers/brain-ui-tools.d.ts.map +1 -0
  97. package/dist/components/chat/renderers/brain-ui-tools.js +41 -0
  98. package/dist/components/chat/renderers/brain-ui-tools.js.map +1 -0
  99. package/dist/components/chat/renderers/claude-tools.d.ts.map +1 -1
  100. package/dist/components/chat/renderers/claude-tools.js +3 -2
  101. package/dist/components/chat/renderers/claude-tools.js.map +1 -1
  102. package/dist/components/chat/renderers/index.d.ts +10 -2
  103. package/dist/components/chat/renderers/index.d.ts.map +1 -1
  104. package/dist/components/chat/renderers/index.js +15 -10
  105. package/dist/components/chat/renderers/index.js.map +1 -1
  106. package/dist/components/chat/session-drawer.d.ts +4 -0
  107. package/dist/components/chat/session-drawer.d.ts.map +1 -1
  108. package/dist/components/chat/session-drawer.js +32 -32
  109. package/dist/components/chat/session-drawer.js.map +1 -1
  110. package/dist/components/chat/session-list.d.ts +41 -0
  111. package/dist/components/chat/session-list.d.ts.map +1 -0
  112. package/dist/components/chat/session-list.js +10 -0
  113. package/dist/components/chat/session-list.js.map +1 -0
  114. package/dist/components/chat/share-block.d.ts.map +1 -1
  115. package/dist/components/chat/share-block.js +12 -11
  116. package/dist/components/chat/share-block.js.map +1 -1
  117. package/dist/components/chat/share-card.js +2 -2
  118. package/dist/components/chat/share-card.js.map +1 -1
  119. package/dist/components/chat/subagent-view.js +1 -1
  120. package/dist/components/chat/subagent-view.js.map +1 -1
  121. package/dist/components/chat/tool-call-timeline.d.ts.map +1 -1
  122. package/dist/components/chat/tool-call-timeline.js +45 -14
  123. package/dist/components/chat/tool-call-timeline.js.map +1 -1
  124. package/dist/components/chat/tool-cards/block-card.d.ts +28 -0
  125. package/dist/components/chat/tool-cards/block-card.d.ts.map +1 -0
  126. package/dist/components/chat/tool-cards/block-card.js +103 -0
  127. package/dist/components/chat/tool-cards/block-card.js.map +1 -0
  128. package/dist/components/chat/tool-cards/image-mask-card.d.ts +70 -0
  129. package/dist/components/chat/tool-cards/image-mask-card.d.ts.map +1 -0
  130. package/dist/components/chat/tool-cards/image-mask-card.js +142 -0
  131. package/dist/components/chat/tool-cards/image-mask-card.js.map +1 -0
  132. package/dist/components/chat/tool-cards/location-card.d.ts +45 -0
  133. package/dist/components/chat/tool-cards/location-card.d.ts.map +1 -0
  134. package/dist/components/chat/tool-cards/location-card.js +128 -0
  135. package/dist/components/chat/tool-cards/location-card.js.map +1 -0
  136. package/dist/components/chat/tool-views.d.ts +19 -2
  137. package/dist/components/chat/tool-views.d.ts.map +1 -1
  138. package/dist/components/chat/tool-views.js +28 -22
  139. package/dist/components/chat/tool-views.js.map +1 -1
  140. package/dist/components/chat/transcript-turn.d.ts +45 -0
  141. package/dist/components/chat/transcript-turn.d.ts.map +1 -0
  142. package/dist/components/chat/transcript-turn.js +25 -0
  143. package/dist/components/chat/transcript-turn.js.map +1 -0
  144. package/dist/components/chat/use-chat-commands.d.ts.map +1 -1
  145. package/dist/components/chat/use-chat-commands.js +13 -16
  146. package/dist/components/chat/use-chat-commands.js.map +1 -1
  147. package/dist/components/chat/welcome-state.d.ts +7 -0
  148. package/dist/components/chat/welcome-state.d.ts.map +1 -1
  149. package/dist/components/chat/welcome-state.js +13 -5
  150. package/dist/components/chat/welcome-state.js.map +1 -1
  151. package/dist/components/connectivity/connection-gate.d.ts.map +1 -1
  152. package/dist/components/connectivity/connection-gate.js +27 -21
  153. package/dist/components/connectivity/connection-gate.js.map +1 -1
  154. package/dist/components/connectivity/login-form.d.ts +31 -0
  155. package/dist/components/connectivity/login-form.d.ts.map +1 -0
  156. package/dist/components/connectivity/login-form.js +19 -0
  157. package/dist/components/connectivity/login-form.js.map +1 -0
  158. package/dist/components/connectivity/login-screen.d.ts +5 -2
  159. package/dist/components/connectivity/login-screen.d.ts.map +1 -1
  160. package/dist/components/connectivity/login-screen.js +41 -31
  161. package/dist/components/connectivity/login-screen.js.map +1 -1
  162. package/dist/components/dev/share-harness.js +1 -1
  163. package/dist/components/dev/share-harness.js.map +1 -1
  164. package/dist/components/files/file-panel.d.ts +1 -1
  165. package/dist/components/files/file-panel.d.ts.map +1 -1
  166. package/dist/components/files/file-panel.js +74 -0
  167. package/dist/components/files/file-panel.js.map +1 -1
  168. package/dist/components/files/file-tree-view.d.ts +45 -0
  169. package/dist/components/files/file-tree-view.d.ts.map +1 -0
  170. package/dist/components/files/file-tree-view.js +51 -0
  171. package/dist/components/files/file-tree-view.js.map +1 -0
  172. package/dist/components/files/file-tree.d.ts +6 -0
  173. package/dist/components/files/file-tree.d.ts.map +1 -1
  174. package/dist/components/files/file-tree.js +39 -43
  175. package/dist/components/files/file-tree.js.map +1 -1
  176. package/dist/components/files/file-viewer-binary.d.ts.map +1 -1
  177. package/dist/components/files/file-viewer-binary.js +3 -2
  178. package/dist/components/files/file-viewer-binary.js.map +1 -1
  179. package/dist/components/files/file-viewer-frame.d.ts +36 -0
  180. package/dist/components/files/file-viewer-frame.d.ts.map +1 -0
  181. package/dist/components/files/file-viewer-frame.js +26 -0
  182. package/dist/components/files/file-viewer-frame.js.map +1 -0
  183. package/dist/components/files/file-viewer.d.ts +5 -0
  184. package/dist/components/files/file-viewer.d.ts.map +1 -1
  185. package/dist/components/files/file-viewer.js +26 -32
  186. package/dist/components/files/file-viewer.js.map +1 -1
  187. package/dist/components/files/frontmatter-chips.d.ts +18 -0
  188. package/dist/components/files/frontmatter-chips.d.ts.map +1 -0
  189. package/dist/components/files/frontmatter-chips.js +11 -0
  190. package/dist/components/files/frontmatter-chips.js.map +1 -0
  191. package/dist/components/files/frontmatter-panel.d.ts +5 -1
  192. package/dist/components/files/frontmatter-panel.d.ts.map +1 -1
  193. package/dist/components/files/frontmatter-panel.js +7 -6
  194. package/dist/components/files/frontmatter-panel.js.map +1 -1
  195. package/dist/components/files/staleness.d.ts +18 -0
  196. package/dist/components/files/staleness.d.ts.map +1 -0
  197. package/dist/components/files/staleness.js +27 -0
  198. package/dist/components/files/staleness.js.map +1 -0
  199. package/dist/components/graph/graph-canvas.d.ts.map +1 -1
  200. package/dist/components/graph/graph-canvas.js +24 -1
  201. package/dist/components/graph/graph-canvas.js.map +1 -1
  202. package/dist/components/graph/graph-controls-column.d.ts +14 -0
  203. package/dist/components/graph/graph-controls-column.d.ts.map +1 -0
  204. package/dist/components/graph/graph-controls-column.js +44 -0
  205. package/dist/components/graph/graph-controls-column.js.map +1 -0
  206. package/dist/components/graph/graph-controls.d.ts +20 -5
  207. package/dist/components/graph/graph-controls.d.ts.map +1 -1
  208. package/dist/components/graph/graph-controls.js +58 -37
  209. package/dist/components/graph/graph-controls.js.map +1 -1
  210. package/dist/components/graph/graph-form.d.ts +82 -0
  211. package/dist/components/graph/graph-form.d.ts.map +1 -0
  212. package/dist/components/graph/graph-form.js +69 -0
  213. package/dist/components/graph/graph-form.js.map +1 -0
  214. package/dist/components/graph/graph-maintenance.d.ts.map +1 -1
  215. package/dist/components/graph/graph-maintenance.js +6 -10
  216. package/dist/components/graph/graph-maintenance.js.map +1 -1
  217. package/dist/components/graph/graph-node-rail.d.ts +13 -0
  218. package/dist/components/graph/graph-node-rail.d.ts.map +1 -0
  219. package/dist/components/graph/graph-node-rail.js +92 -0
  220. package/dist/components/graph/graph-node-rail.js.map +1 -0
  221. package/dist/components/graph/graph-page.d.ts +7 -0
  222. package/dist/components/graph/graph-page.d.ts.map +1 -1
  223. package/dist/components/graph/graph-page.js +102 -12
  224. package/dist/components/graph/graph-page.js.map +1 -1
  225. package/dist/components/graph/graph-scene.d.ts.map +1 -1
  226. package/dist/components/graph/graph-scene.js +100 -24
  227. package/dist/components/graph/graph-scene.js.map +1 -1
  228. package/dist/components/graph/lib/graph-helpers.d.ts +42 -12
  229. package/dist/components/graph/lib/graph-helpers.d.ts.map +1 -1
  230. package/dist/components/graph/lib/graph-helpers.js +33 -41
  231. package/dist/components/graph/lib/graph-helpers.js.map +1 -1
  232. package/dist/components/graph/node-card.d.ts +28 -0
  233. package/dist/components/graph/node-card.d.ts.map +1 -0
  234. package/dist/components/graph/node-card.js +7 -0
  235. package/dist/components/graph/node-card.js.map +1 -0
  236. package/dist/components/graph/node-popover.d.ts +6 -2
  237. package/dist/components/graph/node-popover.d.ts.map +1 -1
  238. package/dist/components/graph/node-popover.js +13 -31
  239. package/dist/components/graph/node-popover.js.map +1 -1
  240. package/dist/components/graph/use-graph-theme.d.ts +32 -4
  241. package/dist/components/graph/use-graph-theme.d.ts.map +1 -1
  242. package/dist/components/graph/use-graph-theme.js +44 -32
  243. package/dist/components/graph/use-graph-theme.js.map +1 -1
  244. package/dist/components/graph/use-node-actions.d.ts +26 -0
  245. package/dist/components/graph/use-node-actions.d.ts.map +1 -0
  246. package/dist/components/graph/use-node-actions.js +54 -0
  247. package/dist/components/graph/use-node-actions.js.map +1 -0
  248. package/dist/components/images/image-share.d.ts +2 -1
  249. package/dist/components/images/image-share.d.ts.map +1 -1
  250. package/dist/components/images/image-share.js +3 -3
  251. package/dist/components/images/image-share.js.map +1 -1
  252. package/dist/components/images/image-viewer.d.ts.map +1 -1
  253. package/dist/components/images/image-viewer.js +3 -1
  254. package/dist/components/images/image-viewer.js.map +1 -1
  255. package/dist/components/images/mask-editor.d.ts.map +1 -1
  256. package/dist/components/images/mask-editor.js +7 -5
  257. package/dist/components/images/mask-editor.js.map +1 -1
  258. package/dist/components/layout/app-shell.d.ts.map +1 -1
  259. package/dist/components/layout/app-shell.js +4 -1
  260. package/dist/components/layout/app-shell.js.map +1 -1
  261. package/dist/components/layout/desktop-palette.d.ts +23 -0
  262. package/dist/components/layout/desktop-palette.d.ts.map +1 -0
  263. package/dist/components/layout/desktop-palette.js +132 -0
  264. package/dist/components/layout/desktop-palette.js.map +1 -0
  265. package/dist/components/layout/key-cap.d.ts +9 -0
  266. package/dist/components/layout/key-cap.d.ts.map +1 -0
  267. package/dist/components/layout/key-cap.js +10 -0
  268. package/dist/components/layout/key-cap.js.map +1 -0
  269. package/dist/components/layout/mobile-tab-bar.d.ts +13 -0
  270. package/dist/components/layout/mobile-tab-bar.d.ts.map +1 -1
  271. package/dist/components/layout/mobile-tab-bar.js +58 -47
  272. package/dist/components/layout/mobile-tab-bar.js.map +1 -1
  273. package/dist/components/layout/shortcut-switch.d.ts +13 -0
  274. package/dist/components/layout/shortcut-switch.d.ts.map +1 -0
  275. package/dist/components/layout/shortcut-switch.js +22 -0
  276. package/dist/components/layout/shortcut-switch.js.map +1 -0
  277. package/dist/components/layout/side-rail.d.ts +28 -0
  278. package/dist/components/layout/side-rail.d.ts.map +1 -1
  279. package/dist/components/layout/side-rail.js +72 -27
  280. package/dist/components/layout/side-rail.js.map +1 -1
  281. package/dist/components/layout/slide-panel.d.ts +25 -2
  282. package/dist/components/layout/slide-panel.d.ts.map +1 -1
  283. package/dist/components/layout/slide-panel.js +13 -4
  284. package/dist/components/layout/slide-panel.js.map +1 -1
  285. package/dist/components/layout/theme.d.ts +22 -0
  286. package/dist/components/layout/theme.d.ts.map +1 -0
  287. package/dist/components/layout/theme.js +44 -0
  288. package/dist/components/layout/theme.js.map +1 -0
  289. package/dist/components/quick-actions/add-form.d.ts +44 -0
  290. package/dist/components/quick-actions/add-form.d.ts.map +1 -0
  291. package/dist/components/quick-actions/add-form.js +32 -0
  292. package/dist/components/quick-actions/add-form.js.map +1 -0
  293. package/dist/components/quick-actions/add-modal.d.ts +7 -0
  294. package/dist/components/quick-actions/add-modal.d.ts.map +1 -1
  295. package/dist/components/quick-actions/add-modal.js +23 -20
  296. package/dist/components/quick-actions/add-modal.js.map +1 -1
  297. package/dist/components/quick-actions/search-modal.d.ts.map +1 -1
  298. package/dist/components/quick-actions/search-modal.js +8 -5
  299. package/dist/components/quick-actions/search-modal.js.map +1 -1
  300. package/dist/components/quick-actions/streaming-modal.d.ts +6 -0
  301. package/dist/components/quick-actions/streaming-modal.d.ts.map +1 -1
  302. package/dist/components/quick-actions/streaming-modal.js +53 -18
  303. package/dist/components/quick-actions/streaming-modal.js.map +1 -1
  304. package/dist/components/quick-actions/streaming-output.d.ts +38 -0
  305. package/dist/components/quick-actions/streaming-output.d.ts.map +1 -0
  306. package/dist/components/quick-actions/streaming-output.js +22 -0
  307. package/dist/components/quick-actions/streaming-output.js.map +1 -0
  308. package/dist/components/quick-actions/whatsup-modal.d.ts +5 -0
  309. package/dist/components/quick-actions/whatsup-modal.d.ts.map +1 -1
  310. package/dist/components/quick-actions/whatsup-modal.js +51 -10
  311. package/dist/components/quick-actions/whatsup-modal.js.map +1 -1
  312. package/dist/components/settings/devices-agents-tab.d.ts +6 -1
  313. package/dist/components/settings/devices-agents-tab.d.ts.map +1 -1
  314. package/dist/components/settings/devices-agents-tab.js +55 -20
  315. package/dist/components/settings/devices-agents-tab.js.map +1 -1
  316. package/dist/components/settings/models-list.d.ts +39 -0
  317. package/dist/components/settings/models-list.d.ts.map +1 -0
  318. package/dist/components/settings/models-list.js +72 -0
  319. package/dist/components/settings/models-list.js.map +1 -0
  320. package/dist/components/settings/models-tab.d.ts +4 -0
  321. package/dist/components/settings/models-tab.d.ts.map +1 -1
  322. package/dist/components/settings/models-tab.js +52 -102
  323. package/dist/components/settings/models-tab.js.map +1 -1
  324. package/dist/components/settings/one-time-agent-credential.js +1 -1
  325. package/dist/components/settings/one-time-agent-credential.js.map +1 -1
  326. package/dist/components/settings/passkey-list.d.ts +35 -0
  327. package/dist/components/settings/passkey-list.d.ts.map +1 -0
  328. package/dist/components/settings/passkey-list.js +34 -0
  329. package/dist/components/settings/passkey-list.js.map +1 -0
  330. package/dist/components/settings/passkey-tab.d.ts +3 -0
  331. package/dist/components/settings/passkey-tab.d.ts.map +1 -1
  332. package/dist/components/settings/passkey-tab.js +53 -45
  333. package/dist/components/settings/passkey-tab.js.map +1 -1
  334. package/dist/components/settings/pi-accounts-list.d.ts +27 -0
  335. package/dist/components/settings/pi-accounts-list.d.ts.map +1 -0
  336. package/dist/components/settings/pi-accounts-list.js +15 -0
  337. package/dist/components/settings/pi-accounts-list.js.map +1 -0
  338. package/dist/components/settings/pi-accounts.d.ts +3 -0
  339. package/dist/components/settings/pi-accounts.d.ts.map +1 -1
  340. package/dist/components/settings/pi-accounts.js +73 -55
  341. package/dist/components/settings/pi-accounts.js.map +1 -1
  342. package/dist/components/settings/principal-list.d.ts +37 -0
  343. package/dist/components/settings/principal-list.d.ts.map +1 -0
  344. package/dist/components/settings/principal-list.js +18 -0
  345. package/dist/components/settings/principal-list.js.map +1 -0
  346. package/dist/components/settings/settings-panel.d.ts +10 -3
  347. package/dist/components/settings/settings-panel.d.ts.map +1 -1
  348. package/dist/components/settings/settings-panel.js +71 -10
  349. package/dist/components/settings/settings-panel.js.map +1 -1
  350. package/dist/components/settings/skills-list.d.ts +53 -0
  351. package/dist/components/settings/skills-list.d.ts.map +1 -0
  352. package/dist/components/settings/skills-list.js +28 -0
  353. package/dist/components/settings/skills-list.js.map +1 -0
  354. package/dist/components/settings/skills-tab.d.ts.map +1 -1
  355. package/dist/components/settings/skills-tab.js +65 -38
  356. package/dist/components/settings/skills-tab.js.map +1 -1
  357. package/dist/components/settings/tool-permissions-list.d.ts +18 -0
  358. package/dist/components/settings/tool-permissions-list.d.ts.map +1 -0
  359. package/dist/components/settings/tool-permissions-list.js +6 -0
  360. package/dist/components/settings/tool-permissions-list.js.map +1 -0
  361. package/dist/components/settings/tool-permissions.d.ts +2 -1
  362. package/dist/components/settings/tool-permissions.d.ts.map +1 -1
  363. package/dist/components/settings/tool-permissions.js +33 -16
  364. package/dist/components/settings/tool-permissions.js.map +1 -1
  365. package/dist/components/settings/web-search-chain.d.ts +41 -0
  366. package/dist/components/settings/web-search-chain.d.ts.map +1 -0
  367. package/dist/components/settings/web-search-chain.js +47 -0
  368. package/dist/components/settings/web-search-chain.js.map +1 -0
  369. package/dist/components/settings/web-search-settings.d.ts +4 -7
  370. package/dist/components/settings/web-search-settings.d.ts.map +1 -1
  371. package/dist/components/settings/web-search-settings.js +54 -76
  372. package/dist/components/settings/web-search-settings.js.map +1 -1
  373. package/dist/components/share/share-menu.d.ts.map +1 -1
  374. package/dist/components/share/share-menu.js +24 -4
  375. package/dist/components/share/share-menu.js.map +1 -1
  376. package/dist/components/voice/dictation-sheet.js +3 -3
  377. package/dist/components/voice/dictation-sheet.js.map +1 -1
  378. package/dist/components/voice/mic-button.js +1 -1
  379. package/dist/components/voice/mic-button.js.map +1 -1
  380. package/dist/components/voice/review-card.js +1 -1
  381. package/dist/components/voice/review-card.js.map +1 -1
  382. package/dist/config.d.ts +5 -2
  383. package/dist/config.d.ts.map +1 -1
  384. package/dist/config.js +15 -5
  385. package/dist/config.js.map +1 -1
  386. package/dist/connection.d.ts +12 -0
  387. package/dist/connection.d.ts.map +1 -0
  388. package/dist/connection.js +421 -0
  389. package/dist/connection.js.map +1 -0
  390. package/dist/default-root.d.ts +3 -0
  391. package/dist/default-root.d.ts.map +1 -0
  392. package/dist/default-root.js +16 -0
  393. package/dist/default-root.js.map +1 -0
  394. package/dist/hooks/use-color-scheme.d.ts +14 -0
  395. package/dist/hooks/use-color-scheme.d.ts.map +1 -0
  396. package/dist/hooks/use-color-scheme.js +37 -0
  397. package/dist/hooks/use-color-scheme.js.map +1 -0
  398. package/dist/hooks/use-fine-pointer.d.ts +12 -0
  399. package/dist/hooks/use-fine-pointer.d.ts.map +1 -0
  400. package/dist/hooks/use-fine-pointer.js +15 -0
  401. package/dist/hooks/use-fine-pointer.js.map +1 -0
  402. package/dist/hooks/use-hash-routes.d.ts.map +1 -1
  403. package/dist/hooks/use-hash-routes.js +4 -2
  404. package/dist/hooks/use-hash-routes.js.map +1 -1
  405. package/dist/hooks/use-media-query.d.ts +9 -0
  406. package/dist/hooks/use-media-query.d.ts.map +1 -0
  407. package/dist/hooks/use-media-query.js +38 -0
  408. package/dist/hooks/use-media-query.js.map +1 -0
  409. package/dist/hooks/use-share-intake.d.ts.map +1 -1
  410. package/dist/hooks/use-share-intake.js +37 -12
  411. package/dist/hooks/use-share-intake.js.map +1 -1
  412. package/dist/hooks/use-vpn-status.d.ts.map +1 -1
  413. package/dist/hooks/use-vpn-status.js +17 -18
  414. package/dist/hooks/use-vpn-status.js.map +1 -1
  415. package/dist/hooks/use-websocket.d.ts +5 -24
  416. package/dist/hooks/use-websocket.d.ts.map +1 -1
  417. package/dist/hooks/use-websocket.js +11 -384
  418. package/dist/hooks/use-websocket.js.map +1 -1
  419. package/dist/hooks/websocket-handlers/activity.d.ts +2 -2
  420. package/dist/hooks/websocket-handlers/activity.d.ts.map +1 -1
  421. package/dist/hooks/websocket-handlers/activity.js +4 -5
  422. package/dist/hooks/websocket-handlers/activity.js.map +1 -1
  423. package/dist/hooks/websocket-handlers/chat.d.ts +1 -0
  424. package/dist/hooks/websocket-handlers/chat.d.ts.map +1 -1
  425. package/dist/hooks/websocket-handlers/chat.js +28 -6
  426. package/dist/hooks/websocket-handlers/chat.js.map +1 -1
  427. package/dist/hooks/websocket-handlers/connection.d.ts.map +1 -1
  428. package/dist/hooks/websocket-handlers/connection.js +4 -6
  429. package/dist/hooks/websocket-handlers/connection.js.map +1 -1
  430. package/dist/hooks/websocket-handlers/mask.d.ts +1 -1
  431. package/dist/hooks/websocket-handlers/mask.d.ts.map +1 -1
  432. package/dist/hooks/websocket-handlers/mask.js +2 -3
  433. package/dist/hooks/websocket-handlers/mask.js.map +1 -1
  434. package/dist/hooks/websocket-handlers/provider.d.ts.map +1 -1
  435. package/dist/hooks/websocket-handlers/provider.js +4 -6
  436. package/dist/hooks/websocket-handlers/provider.js.map +1 -1
  437. package/dist/hooks/websocket-handlers/types.d.ts +6 -2
  438. package/dist/hooks/websocket-handlers/types.d.ts.map +1 -1
  439. package/dist/index.d.ts +5 -3
  440. package/dist/index.d.ts.map +1 -1
  441. package/dist/index.js +6 -3
  442. package/dist/index.js.map +1 -1
  443. package/dist/lib/api-client.d.ts +289 -0
  444. package/dist/lib/api-client.d.ts.map +1 -1
  445. package/dist/lib/api-client.js +243 -224
  446. package/dist/lib/api-client.js.map +1 -1
  447. package/dist/lib/backend.d.ts +19 -2
  448. package/dist/lib/backend.d.ts.map +1 -1
  449. package/dist/lib/backend.js +15 -9
  450. package/dist/lib/backend.js.map +1 -1
  451. package/dist/lib/diff.d.ts +8 -10
  452. package/dist/lib/diff.d.ts.map +1 -1
  453. package/dist/lib/diff.js +26 -53
  454. package/dist/lib/diff.js.map +1 -1
  455. package/dist/lib/light-dark.d.ts +37 -0
  456. package/dist/lib/light-dark.d.ts.map +1 -0
  457. package/dist/lib/light-dark.js +83 -0
  458. package/dist/lib/light-dark.js.map +1 -0
  459. package/dist/lib/mermaid-theme.d.ts +7 -2
  460. package/dist/lib/mermaid-theme.d.ts.map +1 -1
  461. package/dist/lib/mermaid-theme.js +125 -203
  462. package/dist/lib/mermaid-theme.js.map +1 -1
  463. package/dist/lib/passkeys.d.ts +6 -3
  464. package/dist/lib/passkeys.d.ts.map +1 -1
  465. package/dist/lib/passkeys.js +10 -4
  466. package/dist/lib/passkeys.js.map +1 -1
  467. package/dist/lib/push-registration.d.ts +4 -1
  468. package/dist/lib/push-registration.d.ts.map +1 -1
  469. package/dist/lib/push-registration.js +20 -2
  470. package/dist/lib/push-registration.js.map +1 -1
  471. package/dist/lib/share-intake.d.ts +2 -1
  472. package/dist/lib/share-intake.d.ts.map +1 -1
  473. package/dist/lib/share-intake.js +3 -3
  474. package/dist/lib/share-intake.js.map +1 -1
  475. package/dist/lib/share.d.ts +4 -3
  476. package/dist/lib/share.d.ts.map +1 -1
  477. package/dist/lib/share.js +6 -7
  478. package/dist/lib/share.js.map +1 -1
  479. package/dist/lib/single-key.d.ts +30 -0
  480. package/dist/lib/single-key.d.ts.map +1 -0
  481. package/dist/lib/single-key.js +45 -0
  482. package/dist/lib/single-key.js.map +1 -0
  483. package/dist/lib/tool-names.d.ts +8 -6
  484. package/dist/lib/tool-names.d.ts.map +1 -1
  485. package/dist/lib/tool-names.js +17 -7
  486. package/dist/lib/tool-names.js.map +1 -1
  487. package/dist/root-context.d.ts +229 -0
  488. package/dist/root-context.d.ts.map +1 -0
  489. package/dist/root-context.js +33 -0
  490. package/dist/root-context.js.map +1 -0
  491. package/dist/root.d.ts +38 -0
  492. package/dist/root.d.ts.map +1 -0
  493. package/dist/root.js +47 -0
  494. package/dist/root.js.map +1 -0
  495. package/dist/stores/activity-state.d.ts +29 -0
  496. package/dist/stores/activity-state.d.ts.map +1 -0
  497. package/dist/stores/activity-state.js +282 -0
  498. package/dist/stores/activity-state.js.map +1 -0
  499. package/dist/stores/activity-store.d.ts +10 -41
  500. package/dist/stores/activity-store.d.ts.map +1 -1
  501. package/dist/stores/activity-store.js +9 -271
  502. package/dist/stores/activity-store.js.map +1 -1
  503. package/dist/stores/chat-state.d.ts +233 -0
  504. package/dist/stores/chat-state.d.ts.map +1 -0
  505. package/dist/stores/chat-state.js +477 -0
  506. package/dist/stores/chat-state.js.map +1 -0
  507. package/dist/stores/chat-store.d.ts +4 -162
  508. package/dist/stores/chat-store.d.ts.map +1 -1
  509. package/dist/stores/chat-store.js +7 -418
  510. package/dist/stores/chat-store.js.map +1 -1
  511. package/dist/stores/connection-state.d.ts +40 -0
  512. package/dist/stores/connection-state.d.ts.map +1 -0
  513. package/dist/stores/connection-state.js +30 -0
  514. package/dist/stores/connection-state.js.map +1 -0
  515. package/dist/stores/connection-store.d.ts +4 -40
  516. package/dist/stores/connection-store.d.ts.map +1 -1
  517. package/dist/stores/connection-store.js +7 -27
  518. package/dist/stores/connection-store.js.map +1 -1
  519. package/dist/stores/create-stores.d.ts +23 -0
  520. package/dist/stores/create-stores.d.ts.map +1 -0
  521. package/dist/stores/create-stores.js +28 -0
  522. package/dist/stores/create-stores.js.map +1 -0
  523. package/dist/stores/file-state.d.ts +53 -0
  524. package/dist/stores/file-state.d.ts.map +1 -0
  525. package/dist/stores/file-state.js +341 -0
  526. package/dist/stores/file-state.js.map +1 -0
  527. package/dist/stores/file-store.d.ts +4 -52
  528. package/dist/stores/file-store.d.ts.map +1 -1
  529. package/dist/stores/file-store.js +7 -336
  530. package/dist/stores/file-store.js.map +1 -1
  531. package/dist/stores/graph-state.d.ts +95 -0
  532. package/dist/stores/graph-state.d.ts.map +1 -0
  533. package/dist/stores/graph-state.js +252 -0
  534. package/dist/stores/graph-state.js.map +1 -0
  535. package/dist/stores/graph-store.d.ts +7 -83
  536. package/dist/stores/graph-store.d.ts.map +1 -1
  537. package/dist/stores/graph-store.js +8 -249
  538. package/dist/stores/graph-store.js.map +1 -1
  539. package/dist/stores/mask-state.d.ts +21 -0
  540. package/dist/stores/mask-state.d.ts.map +1 -0
  541. package/dist/stores/mask-state.js +9 -0
  542. package/dist/stores/mask-state.js.map +1 -0
  543. package/dist/stores/mask-store.d.ts +4 -21
  544. package/dist/stores/mask-store.d.ts.map +1 -1
  545. package/dist/stores/mask-store.js +7 -6
  546. package/dist/stores/mask-store.js.map +1 -1
  547. package/dist/stores/principal-state.d.ts +16 -0
  548. package/dist/stores/principal-state.d.ts.map +1 -0
  549. package/dist/stores/principal-state.js +31 -0
  550. package/dist/stores/principal-state.js.map +1 -0
  551. package/dist/stores/principal-store.d.ts +4 -15
  552. package/dist/stores/principal-store.d.ts.map +1 -1
  553. package/dist/stores/principal-store.js +7 -28
  554. package/dist/stores/principal-store.js.map +1 -1
  555. package/dist/stores/provider-state.d.ts +24 -0
  556. package/dist/stores/provider-state.d.ts.map +1 -0
  557. package/dist/stores/provider-state.js +68 -0
  558. package/dist/stores/provider-state.js.map +1 -0
  559. package/dist/stores/provider-store.d.ts +4 -23
  560. package/dist/stores/provider-store.d.ts.map +1 -1
  561. package/dist/stores/provider-store.js +7 -64
  562. package/dist/stores/provider-store.js.map +1 -1
  563. package/dist/stores/share-state.d.ts +29 -0
  564. package/dist/stores/share-state.d.ts.map +1 -0
  565. package/dist/stores/share-state.js +21 -0
  566. package/dist/stores/share-state.js.map +1 -0
  567. package/dist/stores/share-store.d.ts +4 -28
  568. package/dist/stores/share-store.d.ts.map +1 -1
  569. package/dist/stores/share-store.js +7 -18
  570. package/dist/stores/share-store.js.map +1 -1
  571. package/dist/stores/store-environment.d.ts +10 -0
  572. package/dist/stores/store-environment.d.ts.map +1 -0
  573. package/dist/stores/store-environment.js +2 -0
  574. package/dist/stores/store-environment.js.map +1 -0
  575. package/dist/stores/ui-state.d.ts +71 -0
  576. package/dist/stores/ui-state.d.ts.map +1 -0
  577. package/dist/stores/ui-state.js +58 -0
  578. package/dist/stores/ui-state.js.map +1 -0
  579. package/dist/stores/ui-store.d.ts +4 -45
  580. package/dist/stores/ui-store.d.ts.map +1 -1
  581. package/dist/stores/ui-store.js +7 -36
  582. package/dist/stores/ui-store.js.map +1 -1
  583. package/dist/styles.css +1 -1
  584. package/dist/theme.css +150 -97
  585. package/dist/voice/asr-clients.d.ts +2 -1
  586. package/dist/voice/asr-clients.d.ts.map +1 -1
  587. package/dist/voice/asr-clients.js +16 -17
  588. package/dist/voice/asr-clients.js.map +1 -1
  589. package/dist/voice/use-dictation.d.ts.map +1 -1
  590. package/dist/voice/use-dictation.js +12 -8
  591. package/dist/voice/use-dictation.js.map +1 -1
  592. package/dist/voice/voice-state.d.ts +25 -0
  593. package/dist/voice/voice-state.d.ts.map +1 -0
  594. package/dist/voice/voice-state.js +29 -0
  595. package/dist/voice/voice-state.js.map +1 -0
  596. package/dist/voice/voice-store.d.ts +4 -25
  597. package/dist/voice/voice-store.d.ts.map +1 -1
  598. package/dist/voice/voice-store.js +7 -26
  599. package/dist/voice/voice-store.js.map +1 -1
  600. package/package.json +3 -2
  601. package/src/components/activity/activity-page.tsx +341 -160
  602. package/src/components/activity/activity-run-detail.tsx +81 -47
  603. package/src/components/activity/activity-run-list.tsx +27 -59
  604. package/src/components/activity/activity-views.tsx +155 -0
  605. package/src/components/activity/approval-card.tsx +117 -0
  606. package/src/components/activity/digest-card.tsx +25 -61
  607. package/src/components/activity/digest-summary.tsx +52 -0
  608. package/src/components/activity/push-switch.tsx +62 -0
  609. package/src/components/activity/push-toggle.tsx +51 -81
  610. package/src/components/activity/span-bits.tsx +60 -7
  611. package/src/components/chat/ask-user-card.tsx +292 -356
  612. package/src/components/chat/ask-user-typed.ts +77 -0
  613. package/src/components/chat/brain-markdown-links.tsx +4 -4
  614. package/src/components/chat/brain-markdown.tsx +4 -2
  615. package/src/components/chat/chat-page.tsx +41 -11
  616. package/src/components/chat/composer-view.tsx +194 -0
  617. package/src/components/chat/composer.tsx +117 -296
  618. package/src/components/chat/markdown-content.tsx +53 -2
  619. package/src/components/chat/mermaid-block.tsx +13 -5
  620. package/src/components/chat/mermaid-share.ts +8 -7
  621. package/src/components/chat/mermaid-viewer.tsx +3 -1
  622. package/src/components/chat/message-bubble.tsx +78 -94
  623. package/src/components/chat/message-share.ts +7 -7
  624. package/src/components/chat/renderers/bind.tsx +94 -0
  625. package/src/components/chat/renderers/brain-ui-tools.tsx +56 -0
  626. package/src/components/chat/renderers/claude-tools.tsx +3 -2
  627. package/src/components/chat/renderers/index.ts +15 -10
  628. package/src/components/chat/session-drawer.tsx +41 -138
  629. package/src/components/chat/session-list.tsx +113 -0
  630. package/src/components/chat/share-block.tsx +16 -12
  631. package/src/components/chat/share-card.tsx +2 -2
  632. package/src/components/chat/subagent-view.tsx +4 -4
  633. package/src/components/chat/tool-call-timeline.tsx +75 -26
  634. package/src/components/chat/tool-cards/block-card.tsx +145 -0
  635. package/src/components/chat/tool-cards/image-mask-card.tsx +214 -0
  636. package/src/components/chat/tool-cards/location-card.tsx +159 -0
  637. package/src/components/chat/tool-views.tsx +30 -60
  638. package/src/components/chat/transcript-turn.tsx +108 -0
  639. package/src/components/chat/use-chat-commands.ts +14 -16
  640. package/src/components/chat/welcome-state.tsx +36 -91
  641. package/src/components/connectivity/connection-gate.tsx +32 -24
  642. package/src/components/connectivity/login-form.tsx +122 -0
  643. package/src/components/connectivity/login-screen.tsx +45 -100
  644. package/src/components/dev/share-harness.tsx +2 -2
  645. package/src/components/files/file-panel.tsx +168 -0
  646. package/src/components/files/file-tree-view.tsx +127 -0
  647. package/src/components/files/file-tree.tsx +55 -109
  648. package/src/components/files/file-viewer-binary.tsx +3 -2
  649. package/src/components/files/file-viewer-frame.tsx +113 -0
  650. package/src/components/files/file-viewer.tsx +40 -95
  651. package/src/components/files/frontmatter-chips.tsx +42 -0
  652. package/src/components/files/frontmatter-panel.tsx +6 -71
  653. package/src/components/files/staleness.ts +29 -0
  654. package/src/components/graph/graph-canvas.tsx +24 -1
  655. package/src/components/graph/graph-controls-column.tsx +92 -0
  656. package/src/components/graph/graph-controls.tsx +83 -127
  657. package/src/components/graph/graph-form.tsx +183 -0
  658. package/src/components/graph/graph-maintenance.tsx +9 -14
  659. package/src/components/graph/graph-node-rail.tsx +147 -0
  660. package/src/components/graph/graph-page.tsx +189 -49
  661. package/src/components/graph/graph-scene.tsx +200 -30
  662. package/src/components/graph/lib/graph-helpers.ts +65 -43
  663. package/src/components/graph/node-card.tsx +64 -0
  664. package/src/components/graph/node-popover.tsx +28 -117
  665. package/src/components/graph/use-graph-theme.ts +69 -32
  666. package/src/components/graph/use-node-actions.ts +56 -0
  667. package/src/components/images/image-share.ts +4 -2
  668. package/src/components/images/image-viewer.tsx +3 -1
  669. package/src/components/images/mask-editor.tsx +7 -4
  670. package/src/components/layout/app-shell.tsx +5 -1
  671. package/src/components/layout/desktop-palette.tsx +151 -0
  672. package/src/components/layout/key-cap.tsx +15 -0
  673. package/src/components/layout/mobile-tab-bar.tsx +80 -157
  674. package/src/components/layout/shortcut-switch.tsx +32 -0
  675. package/src/components/layout/side-rail.tsx +77 -150
  676. package/src/components/layout/slide-panel.tsx +49 -6
  677. package/src/components/layout/theme.tsx +67 -0
  678. package/src/components/quick-actions/add-form.tsx +196 -0
  679. package/src/components/quick-actions/add-modal.tsx +32 -153
  680. package/src/components/quick-actions/search-modal.tsx +15 -5
  681. package/src/components/quick-actions/streaming-modal.tsx +57 -72
  682. package/src/components/quick-actions/streaming-output.tsx +112 -0
  683. package/src/components/quick-actions/whatsup-modal.tsx +53 -59
  684. package/src/components/settings/devices-agents-tab.tsx +60 -152
  685. package/src/components/settings/models-list.tsx +299 -0
  686. package/src/components/settings/models-tab.tsx +63 -337
  687. package/src/components/settings/one-time-agent-credential.tsx +1 -1
  688. package/src/components/settings/passkey-list.tsx +201 -0
  689. package/src/components/settings/passkey-tab.tsx +53 -197
  690. package/src/components/settings/pi-accounts-list.tsx +128 -0
  691. package/src/components/settings/pi-accounts.tsx +71 -170
  692. package/src/components/settings/principal-list.tsx +172 -0
  693. package/src/components/settings/settings-panel.tsx +239 -25
  694. package/src/components/settings/skills-list.tsx +276 -0
  695. package/src/components/settings/skills-tab.tsx +82 -269
  696. package/src/components/settings/tool-permissions-list.tsx +54 -0
  697. package/src/components/settings/tool-permissions.tsx +27 -46
  698. package/src/components/settings/web-search-chain.tsx +300 -0
  699. package/src/components/settings/web-search-settings.tsx +58 -328
  700. package/src/components/share/share-menu.tsx +19 -4
  701. package/src/components/voice/dictation-sheet.tsx +5 -5
  702. package/src/components/voice/mic-button.tsx +1 -1
  703. package/src/components/voice/review-card.tsx +1 -1
  704. package/src/config.ts +21 -7
  705. package/src/connection.ts +443 -0
  706. package/src/default-root.ts +16 -0
  707. package/src/hooks/use-color-scheme.ts +36 -0
  708. package/src/hooks/use-fine-pointer.ts +15 -0
  709. package/src/hooks/use-hash-routes.ts +4 -2
  710. package/src/hooks/use-media-query.ts +35 -0
  711. package/src/hooks/use-share-intake.ts +32 -12
  712. package/src/hooks/use-vpn-status.ts +18 -17
  713. package/src/hooks/use-websocket.ts +12 -428
  714. package/src/hooks/websocket-handlers/activity.ts +4 -5
  715. package/src/hooks/websocket-handlers/chat.ts +28 -6
  716. package/src/hooks/websocket-handlers/connection.ts +4 -6
  717. package/src/hooks/websocket-handlers/mask.ts +2 -3
  718. package/src/hooks/websocket-handlers/provider.ts +4 -6
  719. package/src/hooks/websocket-handlers/types.ts +6 -2
  720. package/src/index.ts +7 -3
  721. package/src/lib/api-client.ts +426 -384
  722. package/src/lib/backend.ts +20 -10
  723. package/src/lib/diff.ts +28 -62
  724. package/src/lib/light-dark.ts +83 -0
  725. package/src/lib/mermaid-theme.ts +183 -214
  726. package/src/lib/passkeys.ts +12 -4
  727. package/src/lib/push-registration.ts +19 -2
  728. package/src/lib/share-intake.ts +6 -3
  729. package/src/lib/share.ts +7 -4
  730. package/src/lib/single-key.ts +47 -0
  731. package/src/lib/tool-names.ts +31 -8
  732. package/src/root-context.tsx +40 -0
  733. package/src/root.ts +83 -0
  734. package/src/stores/activity-state.ts +295 -0
  735. package/src/stores/activity-store.ts +11 -285
  736. package/src/stores/chat-state.ts +822 -0
  737. package/src/stores/chat-store.ts +11 -705
  738. package/src/stores/connection-state.ts +78 -0
  739. package/src/stores/connection-store.ts +11 -76
  740. package/src/stores/create-stores.ts +31 -0
  741. package/src/stores/file-state.ts +399 -0
  742. package/src/stores/file-store.ts +9 -390
  743. package/src/stores/graph-state.ts +368 -0
  744. package/src/stores/graph-store.ts +10 -355
  745. package/src/stores/mask-state.ts +30 -0
  746. package/src/stores/mask-store.ts +10 -27
  747. package/src/stores/principal-state.ts +42 -0
  748. package/src/stores/principal-store.ts +10 -37
  749. package/src/stores/provider-state.ts +103 -0
  750. package/src/stores/provider-store.ts +10 -95
  751. package/src/stores/share-state.ts +56 -0
  752. package/src/stores/share-store.ts +11 -54
  753. package/src/stores/store-environment.ts +10 -0
  754. package/src/stores/ui-state.ts +143 -0
  755. package/src/stores/ui-store.ts +11 -93
  756. package/src/styles.css +4 -1
  757. package/src/theme.css +150 -97
  758. package/src/voice/asr-clients.ts +17 -17
  759. package/src/voice/use-dictation.ts +11 -8
  760. package/src/voice/voice-state.ts +57 -0
  761. package/src/voice/voice-store.ts +11 -55
@@ -1,184 +1,107 @@
1
1
  import { useEffect, useRef, useState } from "react";
2
- import {
3
- Activity,
4
- Brain,
5
- RefreshCw,
6
- History,
7
- SlidersHorizontal,
8
- FolderTree,
9
- SquarePen,
10
- MoreHorizontal,
11
- Waypoints,
12
- } from "lucide-react";
2
+ import { BottomSheet, ListRow, TabBar, type TabItem } from "@schlessera/brain-ui-kit";
13
3
  import { useUIStore } from "../../stores/ui-store.js";
14
- import { useChatStore } from "../../stores/chat-store.js";
4
+ import { useChatStore, activeChat, pendingApprovals } from "../../stores/chat-store.js";
15
5
  import { useActivityStore } from "../../stores/activity-store.js";
16
- import { cn } from "../../lib/utils.js";
17
- import { CountBadge } from "../activity/span-bits.js";
6
+ import { useConnectionStore } from "../../stores/connection-store.js";
7
+ import { useChatCommands } from "../chat/use-chat-commands.js";
18
8
 
9
+ /**
10
+ * The phone's bottom navigation, on the kit's `TabBar`. The five slots are
11
+ * the desktop rail's five destinations with Settings folded into More (D37):
12
+ * Chat · Actions · Files · Graph · More. Six into five does not go, and the
13
+ * one you live in least is the one to fold — never one of the four you live
14
+ * in. New chat is not a slot: a tab is a place and starting a chat is an
15
+ * act, so it is the Chat header's primary action and a ⌘K command.
16
+ *
17
+ * More is the kit `BottomSheet`, docked over a scrim, holding Settings and
18
+ * the acts — Sessions, Sync, Daily briefing, Brain statistics — as kit
19
+ * `ListRow`s. The sheet is a sibling of the bar rather than a child of the
20
+ * More slot, because a kit tab is a leaf and cannot host it.
21
+ */
19
22
  export function MobileTabBar() {
20
23
  const activeView = useUIStore((s) => s.activeView);
21
24
  const setActiveView = useUIStore((s) => s.setActiveView);
22
- const toggleSessionPanel = useUIStore((s) => s.toggleSessionPanel);
23
- const toggleSyncPanel = useUIStore((s) => s.toggleSyncPanel);
24
25
  const toggleFilePanel = useUIStore((s) => s.toggleFilePanel);
25
- const toggleSettingsPanel = useUIStore((s) => s.toggleSettingsPanel);
26
- const clearMessages = useChatStore((s) => s.clearMessages);
26
+ const setSessionPanelOpen = useUIStore((s) => s.setSessionPanelOpen);
27
+ const setSettingsPanelOpen = useUIStore((s) => s.setSettingsPanelOpen);
27
28
  const inboxCount = useActivityStore((s) => s.inbox.length);
28
-
29
- /** Chat-scoped panels live in the chat page — surface it before opening them. */
30
- function inChat(toggle: () => void) {
31
- return () => {
32
- if (activeView !== "chat") setActiveView("chat");
33
- toggle();
34
- };
35
- }
29
+ const approvalCount = useChatStore((s) => pendingApprovals(s).length);
30
+ const isStreaming = useChatStore((s) => activeChat(s).isStreaming);
31
+ const connected = useConnectionStore((s) => s.wsStatus === "connected");
32
+ const runCommand = useChatCommands();
33
+ const needsYou = inboxCount + approvalCount;
36
34
 
37
35
  const [moreOpen, setMoreOpen] = useState(false);
38
36
  const moreRef = useRef<HTMLDivElement>(null);
39
37
 
40
38
  useEffect(() => {
41
39
  if (!moreOpen) return;
42
- function onDocClick(e: MouseEvent) {
43
- if (!moreRef.current?.contains(e.target as Node)) setMoreOpen(false);
44
- }
45
40
  function onKey(e: KeyboardEvent) {
46
41
  if (e.key === "Escape") setMoreOpen(false);
47
42
  }
48
- document.addEventListener("mousedown", onDocClick);
49
43
  document.addEventListener("keydown", onKey);
50
- return () => {
51
- document.removeEventListener("mousedown", onDocClick);
52
- document.removeEventListener("keydown", onKey);
53
- };
44
+ // The sheet's first row takes focus; the More slot gets it back on close.
45
+ moreRef.current?.querySelector<HTMLElement>('[role="button"]')?.focus();
46
+ return () => document.removeEventListener("keydown", onKey);
54
47
  }, [moreOpen]);
55
48
 
56
- return (
57
- <nav className="md:hidden fixed bottom-0 inset-x-0 z-30 flex h-14 items-center justify-around border-t border-border bg-surface px-1 pb-[env(safe-area-inset-bottom)]">
58
- <TabIcon
59
- icon={Brain}
60
- label="Chat"
61
- active={activeView === "chat"}
62
- onClick={() => setActiveView("chat")}
63
- />
64
- <TabIcon
65
- icon={SquarePen}
66
- label="New chat"
67
- onClick={() => {
68
- setMoreOpen(false);
69
- setActiveView("chat");
70
- clearMessages();
71
- }}
72
- />
73
- {/* Activity holds the tab-bar slot; Graph moved into the More menu —
74
- the phone glance-check ("is real work happening?") is the headline
75
- flow and must stay one tap away (planning decision). */}
76
- <TabIcon
77
- icon={Activity}
78
- label="Activity"
79
- active={activeView === "activity"}
80
- badge={inboxCount}
81
- onClick={() => setActiveView("activity")}
82
- />
83
- <TabIcon icon={FolderTree} label="Files" onClick={toggleFilePanel} />
84
- <div ref={moreRef} className="relative">
85
- <TabIcon
86
- icon={MoreHorizontal}
87
- label="More"
88
- active={moreOpen}
89
- onClick={() => setMoreOpen((v) => !v)}
90
- />
91
- {moreOpen && (
92
- <div
93
- role="menu"
94
- className="absolute bottom-full right-0 z-50 mb-2 min-w-[10rem] overflow-hidden rounded-xl border border-border bg-surface-overlay py-1 shadow-2xl"
95
- >
96
- <MoreItem
97
- icon={Waypoints}
98
- label="Graph"
99
- onClick={() => {
100
- setMoreOpen(false);
101
- setActiveView("graph");
102
- }}
103
- />
104
- <MoreItem
105
- icon={RefreshCw}
106
- label="Sync"
107
- onClick={() => {
108
- setMoreOpen(false);
109
- inChat(toggleSyncPanel)();
110
- }}
111
- />
112
- <MoreItem
113
- icon={History}
114
- label="History"
115
- onClick={() => {
116
- setMoreOpen(false);
117
- inChat(toggleSessionPanel)();
118
- }}
119
- />
120
- <MoreItem
121
- icon={SlidersHorizontal}
122
- label="Settings"
123
- onClick={() => {
124
- setMoreOpen(false);
125
- toggleSettingsPanel();
126
- }}
127
- />
128
- </div>
129
- )}
130
- </div>
131
- </nav>
132
- );
133
- }
49
+ /** An act from the sheet: close it, land on chat, run. */
50
+ function act(fn: () => void) {
51
+ return () => {
52
+ setMoreOpen(false);
53
+ setActiveView("chat");
54
+ fn();
55
+ };
56
+ }
134
57
 
135
- function TabIcon({
136
- icon: Icon,
137
- label,
138
- active,
139
- onClick,
140
- badge,
141
- }: {
142
- icon: typeof Brain;
143
- label: string;
144
- active?: boolean;
145
- onClick?: () => void;
146
- /** Unread-count dot (the inbox badge). Hidden at 0. */
147
- badge?: number;
148
- }) {
149
- return (
150
- <button
151
- onClick={onClick}
152
- className={cn(
153
- "relative flex flex-col items-center gap-0.5 px-2 py-1 text-[10px]",
154
- active ? "text-primary" : "text-muted-foreground"
155
- )}
156
- >
157
- <Icon className="h-5 w-5" />
158
- {badge !== undefined && <CountBadge count={badge} className="right-0 top-0" />}
159
- {label}
160
- </button>
161
- );
162
- }
58
+ const items: TabItem[] = [
59
+ { icon: "brain", label: "Chat", onClick: () => setActiveView("chat") },
60
+ {
61
+ icon: "resolved",
62
+ label: "Actions",
63
+ badge: needsYou > 0 ? (needsYou > 9 ? "9+" : String(needsYou)) : undefined,
64
+ onClick: () => setActiveView("activity"),
65
+ },
66
+ { icon: "files", label: "Files", onClick: toggleFilePanel },
67
+ { icon: "graph", label: "Graph", onClick: () => setActiveView("graph") },
68
+ { icon: "more", label: "More", onClick: () => setMoreOpen((v) => !v) },
69
+ ];
70
+ // The amber slot. -1 is "none", which the kit renders as no active item
71
+ // and still keeps the bar reachable (its stop falls back to the first
72
+ // eligible slot).
73
+ const active = moreOpen ? 4 : activeView === "chat" ? 0 : activeView === "activity" ? 1 : activeView === "graph" ? 3 : -1;
74
+ const quiet = connected && !isStreaming;
163
75
 
164
- function MoreItem({
165
- icon: Icon,
166
- label,
167
- onClick,
168
- }: {
169
- icon: typeof Brain;
170
- label: string;
171
- onClick: () => void;
172
- }) {
173
76
  return (
174
- <button
175
- role="menuitem"
176
- type="button"
177
- onClick={onClick}
178
- className="flex w-full items-center gap-2.5 px-3 py-2.5 text-left text-xs text-foreground transition-colors hover:bg-surface-raised"
77
+ <nav
78
+ aria-label="Primary"
79
+ className="tablet:hidden fixed bottom-0 inset-x-0 z-30 pb-[env(safe-area-inset-bottom)]"
80
+ // The safe-area strip below the bar takes the bar's own ground, from the
81
+ // kit's token so it follows the theme.
82
+ style={{ background: "var(--bk-color-surface)" }}
179
83
  >
180
- <Icon className="h-4 w-4 shrink-0 text-muted-foreground" />
181
- {label}
182
- </button>
84
+ {moreOpen && (
85
+ <div
86
+ className="fixed inset-0 z-40 bg-black/60"
87
+ onMouseDown={(e) => {
88
+ if (e.target === e.currentTarget) setMoreOpen(false);
89
+ }}
90
+ >
91
+ <div ref={moreRef} role="dialog" aria-label="More" className="absolute inset-x-0 bottom-0">
92
+ <BottomSheet title="More" subtitle="Settings, and the things you run rather than visit." docked>
93
+ <div className="flex flex-col">
94
+ <ListRow variant="group" icon="settings" iconTone="neutral" title="Settings" chevron onClick={() => { setMoreOpen(false); setSettingsPanelOpen(true); }} />
95
+ <ListRow variant="group" icon="history" iconTone="blue" title="Sessions" subtitle="Resume an earlier conversation" chevron onClick={act(() => setSessionPanelOpen(true))} />
96
+ <ListRow variant="group" icon="repeat" iconTone="amber" title="Sync the brain" subtitle={quiet ? "Pull and push the repository" : "needs the host"} value={quiet ? "sync" : undefined} valueTone="amber" onClick={quiet ? act(() => runCommand("sync")) : undefined} />
97
+ <ListRow variant="group" icon="sunrise" iconTone="gold" title="Daily briefing" subtitle={quiet ? "What happened since you looked" : "needs the host"} onClick={quiet ? act(() => runCommand("whatsup")) : undefined} />
98
+ <ListRow variant="group" icon="ledger" iconTone="neutral" title="Brain statistics" subtitle={quiet ? "Documents, tags and links" : "needs the host"} last onClick={quiet ? act(() => runCommand("stats")) : undefined} />
99
+ </div>
100
+ </BottomSheet>
101
+ </div>
102
+ </div>
103
+ )}
104
+ <TabBar items={items} active={active} />
105
+ </nav>
183
106
  );
184
107
  }
@@ -0,0 +1,32 @@
1
+ import { Icon, Toggle } from "@schlessera/brain-ui-kit";
2
+ import { useId } from "react";
3
+ import { useUIStore } from "../../stores/ui-store.js";
4
+
5
+ /**
6
+ * The off switch for single-key shortcuts (D36, D37). WCAG 2.1.4 asks that
7
+ * a single-character shortcut can be turned off, remapped, or made active
8
+ * only on focus; the design chose focus scope AND an off switch, because a
9
+ * reader whose screen reader or speech input types letters into a focused
10
+ * card still needs the switch. Modifier shortcuts are not governed by it.
11
+ *
12
+ * Drawn as D5 draws it: a group row — icon, title, the mono hint as the
13
+ * subtitle — with the kit `Toggle` trailing, named by the row's title. The
14
+ * kit `ListRow`'s own toggle is decorative, so the row is composed here.
15
+ */
16
+ export function ShortcutSwitch() {
17
+ const on = useUIStore((s) => s.singleKeyShortcuts);
18
+ const set = useUIStore((s) => s.setSingleKeyShortcuts);
19
+ const id = useId();
20
+ return (
21
+ <div className="flex items-center gap-3 px-3 py-3">
22
+ <Icon icon="capability" size={17} color="var(--bk-amber-ink)" />
23
+ <span className="min-w-0 flex-1">
24
+ <span id={id} className="block text-[12.5px] font-semibold text-foreground">Single-key shortcuts</span>
25
+ <span className="mt-0.5 block font-[family-name:var(--font-mono)] text-[10px] text-muted-foreground">
26
+ a d on a focused approval · j k in a list
27
+ </span>
28
+ </span>
29
+ <Toggle on={on} tone="amber" labelledBy={id} onClick={() => set(!on)} />
30
+ </div>
31
+ );
32
+ }
@@ -1,169 +1,96 @@
1
- import {
2
- Activity,
3
- Brain,
4
- RefreshCw,
5
- Newspaper,
6
- History,
7
- SlidersHorizontal,
8
- SquarePen,
9
- FolderTree,
10
- Waypoints,
11
- } from "lucide-react";
1
+ import { SideRail as KitSideRail, type RailItem } from "@schlessera/brain-ui-kit";
2
+ import { useEffect } from "react";
12
3
  import { useConnectionStore } from "../../stores/connection-store.js";
13
4
  import { useActivityStore } from "../../stores/activity-store.js";
5
+ import { useChatStore, pendingApprovals } from "../../stores/chat-store.js";
14
6
  import { useUIStore } from "../../stores/ui-store.js";
15
- import { useChatStore, activeChat } from "../../stores/chat-store.js";
16
- import { cn } from "../../lib/utils.js";
17
- import { CountBadge } from "../activity/span-bits.js";
7
+ import { useMediaQuery } from "../../hooks/use-media-query.js";
8
+ import { useFinePointer } from "../../hooks/use-fine-pointer.js";
18
9
 
10
+ /**
11
+ * The desktop navigation, on the kit's `SideRail`. The kit owns the rail —
12
+ * the one roving tab stop, the amber destination, the badge, the collapsed
13
+ * and expanded widths; this file owns what the destinations DO, which of
14
+ * them is "here", and the ⌘1–⌘5 keys the design prints beside them (D36:
15
+ * anything global takes a modifier).
16
+ *
17
+ * The five destinations are the design's (D37): Chat · Actions · Files ·
18
+ * Graph · Settings, the same five and the same order as the phone bar.
19
+ * Activity is not among them — "what needs me" and "what has been happening"
20
+ * are two lenses on one queue, so the Actions pane carries a filter and the
21
+ * badge counts what needs you: pending approvals plus the inbox. The acts
22
+ * the old rail carried (New chat, Sessions, Sync, the briefing) live in the
23
+ * ⌘K palette and the Chat header.
24
+ *
25
+ * Widths follow D22's ladder: the phone bar to 479px, this rail collapsed
26
+ * to 60px from 480 (`tablet:`), expanded to 208px from 900 (`laptop:`). The
27
+ * rail appears at the breakpoint the phone bar disappears at, so the two
28
+ * never show together. Width is not a keyboard, though: a tablet in
29
+ * landscape crosses `tablet:` with nothing to press ⌘ on, so the caps are
30
+ * printed only while a fine pointer is present (#86). The bindings below
31
+ * stay registered either way — a paired keyboard fires them even if the
32
+ * query stays coarse.
33
+ *
34
+ * The connection status takes the wordmark's line: teal while live, amber
35
+ * while reconnecting, red when the socket is gone. No spend meter — the app
36
+ * tracks no spend — and the ⌘K cap is real, because the palette is.
37
+ */
19
38
  export function SideRail() {
20
39
  const wsStatus = useConnectionStore((s) => s.wsStatus);
21
40
  const activeView = useUIStore((s) => s.activeView);
22
41
  const setActiveView = useUIStore((s) => s.setActiveView);
23
- const toggleSessionPanel = useUIStore((s) => s.toggleSessionPanel);
24
- const toggleSyncPanel = useUIStore((s) => s.toggleSyncPanel);
25
- const toggleWhatsupPanel = useUIStore((s) => s.toggleWhatsupPanel);
42
+ const filePanelOpen = useUIStore((s) => s.filePanelOpen);
43
+ const settingsPanelOpen = useUIStore((s) => s.settingsPanelOpen);
26
44
  const toggleFilePanel = useUIStore((s) => s.toggleFilePanel);
27
45
  const toggleSettingsPanel = useUIStore((s) => s.toggleSettingsPanel);
28
- const clearMessages = useChatStore((s) => s.clearMessages);
29
- const hasMessages = useChatStore((s) => activeChat(s).messages.length > 0);
30
- const isStreaming = useChatStore((s) => activeChat(s).isStreaming);
31
46
  const inboxCount = useActivityStore((s) => s.inbox.length);
47
+ const approvalCount = useChatStore((s) => pendingApprovals(s).length);
48
+ const needsYou = inboxCount + approvalCount;
49
+ const expanded = useMediaQuery("(min-width: 900px)");
50
+ const finePointer = useFinePointer();
51
+ const cap = (key: string) => (finePointer ? key : undefined);
32
52
 
33
- /** Chat-scoped panels live in the chat page — surface it before opening them. */
34
- function inChat(toggle: () => void) {
35
- return () => {
36
- if (activeView !== "chat") setActiveView("chat");
37
- toggle();
38
- };
39
- }
53
+ const items: RailItem[] = [
54
+ { icon: "brain", label: "Chat", shortcut: cap("⌘1"), onClick: () => setActiveView("chat") },
55
+ {
56
+ icon: "resolved",
57
+ label: "Actions",
58
+ shortcut: cap("⌘2"),
59
+ badge: needsYou > 0 ? (needsYou > 9 ? "9+" : String(needsYou)) : undefined,
60
+ onClick: () => setActiveView("activity"),
61
+ },
62
+ { icon: "files", label: "Files", shortcut: cap("⌘3"), onClick: toggleFilePanel },
63
+ { icon: "graph", label: "Graph", shortcut: cap("⌘4"), onClick: () => setActiveView("graph") },
64
+ { icon: "settings", label: "Settings", shortcut: cap("⌘5"), onClick: toggleSettingsPanel },
65
+ ];
40
66
 
41
- return (
42
- <nav className="hidden md:flex w-16 shrink-0 flex-col items-center border-r border-border bg-surface py-4 gap-1">
43
- {/* Logo */}
44
- <div className="mb-4">
45
- <Brain className="h-7 w-7 text-primary" />
46
- </div>
47
-
48
- {/* New chat */}
49
- {hasMessages && (
50
- <RailButton
51
- icon={SquarePen}
52
- label="New chat"
53
- onClick={clearMessages}
54
- />
55
- )}
56
-
57
- {/* Divider */}
58
- <div className="my-2 h-px w-8 bg-border" />
59
-
60
- {/* Quick actions */}
61
- <RailButton
62
- icon={RefreshCw}
63
- label="Sync"
64
- onClick={inChat(toggleSyncPanel)}
65
- disabled={isStreaming}
66
- />
67
- <RailButton
68
- icon={Newspaper}
69
- label="Whatsup"
70
- onClick={inChat(toggleWhatsupPanel)}
71
- disabled={isStreaming}
72
- />
73
- <RailButton
74
- icon={FolderTree}
75
- label="Files"
76
- onClick={toggleFilePanel}
77
- />
78
- <RailButton
79
- icon={Waypoints}
80
- label="Graph"
81
- active={activeView === "graph"}
82
- onClick={() =>
83
- setActiveView(activeView === "graph" ? "chat" : "graph")
84
- }
85
- />
86
- <RailButton
87
- icon={Activity}
88
- label="Activity"
89
- active={activeView === "activity"}
90
- badge={inboxCount}
91
- onClick={() =>
92
- setActiveView(activeView === "activity" ? "chat" : "activity")
93
- }
94
- />
67
+ // A panel over the view is "here" while it is open; otherwise the view is.
68
+ const active = filePanelOpen ? 2 : settingsPanelOpen ? 4 : activeView === "chat" ? 0 : activeView === "activity" ? 1 : 3;
95
69
 
96
- {/* Spacer */}
97
- <div className="flex-1" />
70
+ useEffect(() => {
71
+ if (typeof window === "undefined") return;
72
+ function onKey(e: KeyboardEvent) {
73
+ if (!(e.metaKey || e.ctrlKey) || e.altKey || e.shiftKey) return;
74
+ const n = Number(e.key);
75
+ if (!Number.isInteger(n) || n < 1 || n > items.length) return;
76
+ e.preventDefault();
77
+ items[n - 1]!.onClick?.();
78
+ }
79
+ window.addEventListener("keydown", onKey);
80
+ return () => window.removeEventListener("keydown", onKey);
81
+ });
98
82
 
99
- {/* History */}
100
- <RailButton
101
- icon={History}
102
- label="Sessions"
103
- onClick={inChat(toggleSessionPanel)}
104
- />
105
-
106
- {/* Settings (models, passkeys, sign out) */}
107
- <RailButton
108
- icon={SlidersHorizontal}
109
- label="Settings"
110
- onClick={toggleSettingsPanel}
83
+ return (
84
+ <nav aria-label="Primary" className="hidden tablet:flex shrink-0">
85
+ <KitSideRail
86
+ items={items}
87
+ active={active}
88
+ expanded={expanded}
89
+ status={wsStatus === "connected" ? "live" : wsStatus === "connecting" ? "reconnecting" : "offline"}
90
+ statusTone={wsStatus === "connected" ? "teal" : wsStatus === "connecting" ? "amber" : "red"}
91
+ spendPct={null}
92
+ hint="Command palette"
111
93
  />
112
-
113
- {/* Connection status */}
114
- <div className="mt-2 flex flex-col items-center gap-1">
115
- <span
116
- className={cn(
117
- "inline-block h-2 w-2 rounded-full",
118
- wsStatus === "connected" && "bg-green-500",
119
- wsStatus === "connecting" && "bg-primary animate-pulse",
120
- wsStatus === "disconnected" && "bg-destructive"
121
- )}
122
- />
123
- <span className="text-[10px] text-muted-foreground">
124
- {wsStatus === "connected"
125
- ? "Live"
126
- : wsStatus === "connecting"
127
- ? "..."
128
- : "Off"}
129
- </span>
130
- </div>
131
94
  </nav>
132
95
  );
133
96
  }
134
-
135
- function RailButton({
136
- icon: Icon,
137
- label,
138
- onClick,
139
- disabled,
140
- active,
141
- badge,
142
- }: {
143
- icon: typeof Brain;
144
- label: string;
145
- onClick: () => void;
146
- disabled?: boolean;
147
- active?: boolean;
148
- /** Unread-count dot (the inbox badge). Hidden at 0. */
149
- badge?: number;
150
- }) {
151
- return (
152
- <button
153
- onClick={onClick}
154
- disabled={disabled}
155
- title={label}
156
- className={cn(
157
- "group relative flex h-10 w-10 items-center justify-center rounded-lg transition-all duration-150 hover:bg-surface-raised hover:text-foreground hover:scale-110 disabled:opacity-40 disabled:hover:scale-100",
158
- active ? "bg-surface-raised text-primary" : "text-muted-foreground"
159
- )}
160
- >
161
- <Icon className="h-4.5 w-4.5" />
162
- {badge !== undefined && <CountBadge count={badge} className="-right-0.5 -top-0.5" />}
163
- {/* Tooltip */}
164
- <span className="pointer-events-none absolute left-full ml-2 whitespace-nowrap rounded-md bg-surface-overlay px-2.5 py-1 text-xs font-medium text-foreground opacity-0 shadow-lg transition-opacity group-hover:opacity-100 border border-border">
165
- {label}
166
- </span>
167
- </button>
168
- );
169
- }
@@ -6,27 +6,54 @@ import { cn } from "../../lib/utils.js";
6
6
  /** Matches the `duration-300` slide-out below. */
7
7
  const SLIDE_OUT_MS = 300;
8
8
 
9
+ /**
10
+ * `drawer` slides in from the right over a backdrop and draws its own header.
11
+ * `pane` (D5, from `laptop:` up) is the design's settings PANE: a fixed layer
12
+ * over the content area, offset by the rail's width, with no backdrop and no
13
+ * header of its own — the children draw the header row, because a pane's
14
+ * chrome is a `ScreenHeader`, not a drawer's title bar. It renders nothing
15
+ * while closed: there is no slide to outlive.
16
+ */
17
+ export type SlidePanelMode = "drawer" | "pane";
18
+
19
+ /**
20
+ * What dismisses the panel besides its own close control, in `<dialog
21
+ * closedby>`'s vocabulary so a later move to the element is a rename-free
22
+ * step. `any` (the default) is light dismiss: a click on the backdrop or
23
+ * Escape — right for a preview you glance at and leave. `closerequest`
24
+ * keeps the backdrop inert but honours Escape — for a panel holding
25
+ * something a stray click must not discard, like a finished log. `none`
26
+ * ignores both — for a panel running a job, where a reflexive Escape would
27
+ * cancel it. The header's X closes the drawer under every value: a rendered
28
+ * close control is never inert.
29
+ */
30
+ export type SlidePanelClosedBy = "any" | "closerequest" | "none";
31
+
9
32
  export function SlidePanel({
10
33
  open,
11
34
  onClose,
12
35
  title,
13
36
  wide,
37
+ mode = "drawer",
38
+ closedBy = "any",
14
39
  children,
15
40
  }: {
16
41
  open: boolean;
17
42
  onClose: () => void;
18
43
  title: string;
19
44
  wide?: boolean;
45
+ mode?: SlidePanelMode;
46
+ closedBy?: SlidePanelClosedBy;
20
47
  children: ReactNode;
21
48
  }) {
22
49
  useEffect(() => {
23
- if (!open) return;
50
+ if (!open || closedBy === "none") return;
24
51
  const handler = (e: KeyboardEvent) => {
25
52
  if (e.key === "Escape") onClose();
26
53
  };
27
54
  document.addEventListener("keydown", handler);
28
55
  return () => document.removeEventListener("keydown", handler);
29
- }, [open, onClose]);
56
+ }, [open, onClose, closedBy]);
30
57
 
31
58
  /**
32
59
  * A closed panel renders nothing. The shell (the sliding frame and its
@@ -36,13 +63,25 @@ export function SlidePanel({
36
63
  */
37
64
  const showContent = useDeferredUnmount(open, SLIDE_OUT_MS);
38
65
 
66
+ if (mode === "pane") {
67
+ if (!open) return null;
68
+ return (
69
+ <section
70
+ aria-label={title}
71
+ className="fixed top-0 bottom-0 right-0 tablet:left-[60px] laptop:left-[208px] z-40 flex flex-col overflow-hidden bg-surface"
72
+ >
73
+ {children}
74
+ </section>
75
+ );
76
+ }
77
+
39
78
  return (
40
79
  <>
41
- {/* Backdrop */}
80
+ {/* Backdrop: a click on it dismisses only a light-dismiss drawer. */}
42
81
  {open && (
43
82
  <div
44
83
  className="fixed inset-0 z-40 bg-black/40 transition-opacity md:bg-black/20"
45
- onClick={onClose}
84
+ onClick={closedBy === "any" ? onClose : undefined}
46
85
  />
47
86
  )}
48
87
 
@@ -50,8 +89,11 @@ export function SlidePanel({
50
89
  <div
51
90
  className={cn(
52
91
  "fixed right-0 top-0 z-50 flex h-full flex-col border-l border-border bg-surface shadow-[0_16px_48px_rgba(0,0,0,0.5)]",
53
- "transform transition-transform duration-300 ease-out",
54
- open ? "translate-x-0" : "translate-x-full",
92
+ "transform transition-[transform,box-shadow] duration-300 ease-out",
93
+ // A closed drawer sits just past the right edge, and its 48px shadow
94
+ // would still bleed into the viewport: the shadow fades with the
95
+ // slide, and a closed drawer takes no clicks.
96
+ open ? "translate-x-0" : "translate-x-full shadow-none pointer-events-none",
55
97
  wide ? "w-full md:w-[480px]" : "w-full md:w-80"
56
98
  )}
57
99
  >
@@ -62,6 +104,7 @@ export function SlidePanel({
62
104
  </h2>
63
105
  <button
64
106
  onClick={onClose}
107
+ aria-label={`Close ${title}`}
65
108
  className="rounded-lg p-2.5 md:p-1.5 text-muted-foreground transition-colors hover:bg-surface-raised hover:text-foreground"
66
109
  >
67
110
  <X className="h-5 w-5 md:h-4 md:w-4" />