@schlessera/brain-ui-react 0.35.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (755) hide show
  1. package/README.md +82 -4
  2. package/dist/components/activity/activity-page.d.ts +17 -5
  3. package/dist/components/activity/activity-page.d.ts.map +1 -1
  4. package/dist/components/activity/activity-page.js +144 -50
  5. package/dist/components/activity/activity-page.js.map +1 -1
  6. package/dist/components/activity/activity-run-detail.d.ts +16 -1
  7. package/dist/components/activity/activity-run-detail.d.ts.map +1 -1
  8. package/dist/components/activity/activity-run-detail.js +47 -4
  9. package/dist/components/activity/activity-run-detail.js.map +1 -1
  10. package/dist/components/activity/activity-run-list.d.ts +7 -1
  11. package/dist/components/activity/activity-run-list.d.ts.map +1 -1
  12. package/dist/components/activity/activity-run-list.js +16 -8
  13. package/dist/components/activity/activity-run-list.js.map +1 -1
  14. package/dist/components/activity/activity-views.d.ts +63 -0
  15. package/dist/components/activity/activity-views.d.ts.map +1 -0
  16. package/dist/components/activity/activity-views.js +52 -0
  17. package/dist/components/activity/activity-views.js.map +1 -0
  18. package/dist/components/activity/approval-card.d.ts +11 -0
  19. package/dist/components/activity/approval-card.d.ts.map +1 -0
  20. package/dist/components/activity/approval-card.js +46 -0
  21. package/dist/components/activity/approval-card.js.map +1 -0
  22. package/dist/components/activity/digest-card.d.ts +3 -0
  23. package/dist/components/activity/digest-card.d.ts.map +1 -1
  24. package/dist/components/activity/digest-card.js +20 -16
  25. package/dist/components/activity/digest-card.js.map +1 -1
  26. package/dist/components/activity/digest-summary.d.ts +19 -0
  27. package/dist/components/activity/digest-summary.d.ts.map +1 -0
  28. package/dist/components/activity/digest-summary.js +20 -0
  29. package/dist/components/activity/digest-summary.js.map +1 -0
  30. package/dist/components/activity/push-switch.d.ts +25 -0
  31. package/dist/components/activity/push-switch.d.ts.map +1 -0
  32. package/dist/components/activity/push-switch.js +14 -0
  33. package/dist/components/activity/push-switch.js.map +1 -0
  34. package/dist/components/activity/push-toggle.d.ts +7 -0
  35. package/dist/components/activity/push-toggle.d.ts.map +1 -1
  36. package/dist/components/activity/push-toggle.js +72 -47
  37. package/dist/components/activity/push-toggle.js.map +1 -1
  38. package/dist/components/activity/span-bits.d.ts.map +1 -1
  39. package/dist/components/activity/span-bits.js +9 -7
  40. package/dist/components/activity/span-bits.js.map +1 -1
  41. package/dist/components/chat/ask-user-card.d.ts +76 -3
  42. package/dist/components/chat/ask-user-card.d.ts.map +1 -1
  43. package/dist/components/chat/ask-user-card.js +208 -149
  44. package/dist/components/chat/ask-user-card.js.map +1 -1
  45. package/dist/components/chat/ask-user-typed.d.ts +42 -0
  46. package/dist/components/chat/ask-user-typed.d.ts.map +1 -0
  47. package/dist/components/chat/ask-user-typed.js +60 -0
  48. package/dist/components/chat/ask-user-typed.js.map +1 -0
  49. package/dist/components/chat/brain-markdown-links.d.ts +2 -1
  50. package/dist/components/chat/brain-markdown-links.d.ts.map +1 -1
  51. package/dist/components/chat/brain-markdown-links.js +3 -4
  52. package/dist/components/chat/brain-markdown-links.js.map +1 -1
  53. package/dist/components/chat/brain-markdown.d.ts.map +1 -1
  54. package/dist/components/chat/brain-markdown.js +4 -2
  55. package/dist/components/chat/brain-markdown.js.map +1 -1
  56. package/dist/components/chat/chat-page.d.ts.map +1 -1
  57. package/dist/components/chat/chat-page.js +24 -9
  58. package/dist/components/chat/chat-page.js.map +1 -1
  59. package/dist/components/chat/composer-view.d.ts +75 -0
  60. package/dist/components/chat/composer-view.d.ts.map +1 -0
  61. package/dist/components/chat/composer-view.js +31 -0
  62. package/dist/components/chat/composer-view.js.map +1 -0
  63. package/dist/components/chat/composer.d.ts +4 -0
  64. package/dist/components/chat/composer.d.ts.map +1 -1
  65. package/dist/components/chat/composer.js +76 -59
  66. package/dist/components/chat/composer.js.map +1 -1
  67. package/dist/components/chat/markdown-content.d.ts +16 -1
  68. package/dist/components/chat/markdown-content.d.ts.map +1 -1
  69. package/dist/components/chat/markdown-content.js +47 -3
  70. package/dist/components/chat/markdown-content.js.map +1 -1
  71. package/dist/components/chat/mermaid-block.d.ts +4 -0
  72. package/dist/components/chat/mermaid-block.d.ts.map +1 -1
  73. package/dist/components/chat/mermaid-block.js +13 -5
  74. package/dist/components/chat/mermaid-block.js.map +1 -1
  75. package/dist/components/chat/mermaid-share.d.ts +2 -1
  76. package/dist/components/chat/mermaid-share.d.ts.map +1 -1
  77. package/dist/components/chat/mermaid-share.js +7 -8
  78. package/dist/components/chat/mermaid-share.js.map +1 -1
  79. package/dist/components/chat/mermaid-viewer.d.ts.map +1 -1
  80. package/dist/components/chat/mermaid-viewer.js +3 -1
  81. package/dist/components/chat/mermaid-viewer.js.map +1 -1
  82. package/dist/components/chat/message-bubble.d.ts +8 -1
  83. package/dist/components/chat/message-bubble.d.ts.map +1 -1
  84. package/dist/components/chat/message-bubble.js +53 -24
  85. package/dist/components/chat/message-bubble.js.map +1 -1
  86. package/dist/components/chat/message-share.d.ts +2 -1
  87. package/dist/components/chat/message-share.d.ts.map +1 -1
  88. package/dist/components/chat/message-share.js +6 -7
  89. package/dist/components/chat/message-share.js.map +1 -1
  90. package/dist/components/chat/renderers/bind.d.ts +39 -0
  91. package/dist/components/chat/renderers/bind.d.ts.map +1 -0
  92. package/dist/components/chat/renderers/bind.js +43 -0
  93. package/dist/components/chat/renderers/bind.js.map +1 -0
  94. package/dist/components/chat/renderers/brain-ui-tools.d.ts +3 -0
  95. package/dist/components/chat/renderers/brain-ui-tools.d.ts.map +1 -0
  96. package/dist/components/chat/renderers/brain-ui-tools.js +41 -0
  97. package/dist/components/chat/renderers/brain-ui-tools.js.map +1 -0
  98. package/dist/components/chat/renderers/claude-tools.d.ts.map +1 -1
  99. package/dist/components/chat/renderers/claude-tools.js +3 -2
  100. package/dist/components/chat/renderers/claude-tools.js.map +1 -1
  101. package/dist/components/chat/renderers/index.d.ts +10 -2
  102. package/dist/components/chat/renderers/index.d.ts.map +1 -1
  103. package/dist/components/chat/renderers/index.js +15 -10
  104. package/dist/components/chat/renderers/index.js.map +1 -1
  105. package/dist/components/chat/session-drawer.d.ts +4 -0
  106. package/dist/components/chat/session-drawer.d.ts.map +1 -1
  107. package/dist/components/chat/session-drawer.js +32 -32
  108. package/dist/components/chat/session-drawer.js.map +1 -1
  109. package/dist/components/chat/session-list.d.ts +41 -0
  110. package/dist/components/chat/session-list.d.ts.map +1 -0
  111. package/dist/components/chat/session-list.js +10 -0
  112. package/dist/components/chat/session-list.js.map +1 -0
  113. package/dist/components/chat/share-block.d.ts.map +1 -1
  114. package/dist/components/chat/share-block.js +12 -11
  115. package/dist/components/chat/share-block.js.map +1 -1
  116. package/dist/components/chat/share-card.js +2 -2
  117. package/dist/components/chat/share-card.js.map +1 -1
  118. package/dist/components/chat/subagent-view.js +1 -1
  119. package/dist/components/chat/subagent-view.js.map +1 -1
  120. package/dist/components/chat/tool-call-timeline.d.ts.map +1 -1
  121. package/dist/components/chat/tool-call-timeline.js +37 -12
  122. package/dist/components/chat/tool-call-timeline.js.map +1 -1
  123. package/dist/components/chat/tool-cards/block-card.d.ts +28 -0
  124. package/dist/components/chat/tool-cards/block-card.d.ts.map +1 -0
  125. package/dist/components/chat/tool-cards/block-card.js +103 -0
  126. package/dist/components/chat/tool-cards/block-card.js.map +1 -0
  127. package/dist/components/chat/tool-cards/image-mask-card.d.ts +70 -0
  128. package/dist/components/chat/tool-cards/image-mask-card.d.ts.map +1 -0
  129. package/dist/components/chat/tool-cards/image-mask-card.js +142 -0
  130. package/dist/components/chat/tool-cards/image-mask-card.js.map +1 -0
  131. package/dist/components/chat/tool-cards/location-card.d.ts +45 -0
  132. package/dist/components/chat/tool-cards/location-card.d.ts.map +1 -0
  133. package/dist/components/chat/tool-cards/location-card.js +128 -0
  134. package/dist/components/chat/tool-cards/location-card.js.map +1 -0
  135. package/dist/components/chat/tool-views.d.ts +13 -2
  136. package/dist/components/chat/tool-views.d.ts.map +1 -1
  137. package/dist/components/chat/tool-views.js +20 -22
  138. package/dist/components/chat/tool-views.js.map +1 -1
  139. package/dist/components/chat/transcript-turn.d.ts +45 -0
  140. package/dist/components/chat/transcript-turn.d.ts.map +1 -0
  141. package/dist/components/chat/transcript-turn.js +25 -0
  142. package/dist/components/chat/transcript-turn.js.map +1 -0
  143. package/dist/components/chat/use-chat-commands.d.ts.map +1 -1
  144. package/dist/components/chat/use-chat-commands.js +13 -16
  145. package/dist/components/chat/use-chat-commands.js.map +1 -1
  146. package/dist/components/chat/welcome-state.d.ts +7 -0
  147. package/dist/components/chat/welcome-state.d.ts.map +1 -1
  148. package/dist/components/chat/welcome-state.js +13 -5
  149. package/dist/components/chat/welcome-state.js.map +1 -1
  150. package/dist/components/connectivity/connection-gate.d.ts.map +1 -1
  151. package/dist/components/connectivity/connection-gate.js +27 -21
  152. package/dist/components/connectivity/connection-gate.js.map +1 -1
  153. package/dist/components/connectivity/login-form.d.ts +31 -0
  154. package/dist/components/connectivity/login-form.d.ts.map +1 -0
  155. package/dist/components/connectivity/login-form.js +19 -0
  156. package/dist/components/connectivity/login-form.js.map +1 -0
  157. package/dist/components/connectivity/login-screen.d.ts +5 -2
  158. package/dist/components/connectivity/login-screen.d.ts.map +1 -1
  159. package/dist/components/connectivity/login-screen.js +41 -31
  160. package/dist/components/connectivity/login-screen.js.map +1 -1
  161. package/dist/components/dev/share-harness.js +1 -1
  162. package/dist/components/dev/share-harness.js.map +1 -1
  163. package/dist/components/files/file-panel.d.ts +1 -1
  164. package/dist/components/files/file-panel.d.ts.map +1 -1
  165. package/dist/components/files/file-panel.js +74 -0
  166. package/dist/components/files/file-panel.js.map +1 -1
  167. package/dist/components/files/file-tree-view.d.ts +45 -0
  168. package/dist/components/files/file-tree-view.d.ts.map +1 -0
  169. package/dist/components/files/file-tree-view.js +51 -0
  170. package/dist/components/files/file-tree-view.js.map +1 -0
  171. package/dist/components/files/file-tree.d.ts +6 -0
  172. package/dist/components/files/file-tree.d.ts.map +1 -1
  173. package/dist/components/files/file-tree.js +39 -43
  174. package/dist/components/files/file-tree.js.map +1 -1
  175. package/dist/components/files/file-viewer-binary.d.ts.map +1 -1
  176. package/dist/components/files/file-viewer-binary.js +3 -2
  177. package/dist/components/files/file-viewer-binary.js.map +1 -1
  178. package/dist/components/files/file-viewer-frame.d.ts +36 -0
  179. package/dist/components/files/file-viewer-frame.d.ts.map +1 -0
  180. package/dist/components/files/file-viewer-frame.js +26 -0
  181. package/dist/components/files/file-viewer-frame.js.map +1 -0
  182. package/dist/components/files/file-viewer.d.ts +5 -0
  183. package/dist/components/files/file-viewer.d.ts.map +1 -1
  184. package/dist/components/files/file-viewer.js +26 -32
  185. package/dist/components/files/file-viewer.js.map +1 -1
  186. package/dist/components/files/frontmatter-chips.d.ts +18 -0
  187. package/dist/components/files/frontmatter-chips.d.ts.map +1 -0
  188. package/dist/components/files/frontmatter-chips.js +11 -0
  189. package/dist/components/files/frontmatter-chips.js.map +1 -0
  190. package/dist/components/files/frontmatter-panel.d.ts +5 -1
  191. package/dist/components/files/frontmatter-panel.d.ts.map +1 -1
  192. package/dist/components/files/frontmatter-panel.js +7 -6
  193. package/dist/components/files/frontmatter-panel.js.map +1 -1
  194. package/dist/components/files/staleness.d.ts +18 -0
  195. package/dist/components/files/staleness.d.ts.map +1 -0
  196. package/dist/components/files/staleness.js +27 -0
  197. package/dist/components/files/staleness.js.map +1 -0
  198. package/dist/components/graph/graph-canvas.d.ts.map +1 -1
  199. package/dist/components/graph/graph-canvas.js +24 -1
  200. package/dist/components/graph/graph-canvas.js.map +1 -1
  201. package/dist/components/graph/graph-controls-column.d.ts +14 -0
  202. package/dist/components/graph/graph-controls-column.d.ts.map +1 -0
  203. package/dist/components/graph/graph-controls-column.js +44 -0
  204. package/dist/components/graph/graph-controls-column.js.map +1 -0
  205. package/dist/components/graph/graph-controls.d.ts +20 -5
  206. package/dist/components/graph/graph-controls.d.ts.map +1 -1
  207. package/dist/components/graph/graph-controls.js +58 -37
  208. package/dist/components/graph/graph-controls.js.map +1 -1
  209. package/dist/components/graph/graph-form.d.ts +82 -0
  210. package/dist/components/graph/graph-form.d.ts.map +1 -0
  211. package/dist/components/graph/graph-form.js +69 -0
  212. package/dist/components/graph/graph-form.js.map +1 -0
  213. package/dist/components/graph/graph-maintenance.d.ts.map +1 -1
  214. package/dist/components/graph/graph-maintenance.js +6 -10
  215. package/dist/components/graph/graph-maintenance.js.map +1 -1
  216. package/dist/components/graph/graph-node-rail.d.ts +13 -0
  217. package/dist/components/graph/graph-node-rail.d.ts.map +1 -0
  218. package/dist/components/graph/graph-node-rail.js +92 -0
  219. package/dist/components/graph/graph-node-rail.js.map +1 -0
  220. package/dist/components/graph/graph-page.d.ts +7 -0
  221. package/dist/components/graph/graph-page.d.ts.map +1 -1
  222. package/dist/components/graph/graph-page.js +102 -12
  223. package/dist/components/graph/graph-page.js.map +1 -1
  224. package/dist/components/graph/graph-scene.d.ts.map +1 -1
  225. package/dist/components/graph/graph-scene.js +100 -24
  226. package/dist/components/graph/graph-scene.js.map +1 -1
  227. package/dist/components/graph/lib/graph-helpers.d.ts +42 -12
  228. package/dist/components/graph/lib/graph-helpers.d.ts.map +1 -1
  229. package/dist/components/graph/lib/graph-helpers.js +33 -41
  230. package/dist/components/graph/lib/graph-helpers.js.map +1 -1
  231. package/dist/components/graph/node-card.d.ts +28 -0
  232. package/dist/components/graph/node-card.d.ts.map +1 -0
  233. package/dist/components/graph/node-card.js +7 -0
  234. package/dist/components/graph/node-card.js.map +1 -0
  235. package/dist/components/graph/node-popover.d.ts +6 -2
  236. package/dist/components/graph/node-popover.d.ts.map +1 -1
  237. package/dist/components/graph/node-popover.js +13 -31
  238. package/dist/components/graph/node-popover.js.map +1 -1
  239. package/dist/components/graph/use-graph-theme.d.ts +32 -4
  240. package/dist/components/graph/use-graph-theme.d.ts.map +1 -1
  241. package/dist/components/graph/use-graph-theme.js +44 -32
  242. package/dist/components/graph/use-graph-theme.js.map +1 -1
  243. package/dist/components/graph/use-node-actions.d.ts +26 -0
  244. package/dist/components/graph/use-node-actions.d.ts.map +1 -0
  245. package/dist/components/graph/use-node-actions.js +54 -0
  246. package/dist/components/graph/use-node-actions.js.map +1 -0
  247. package/dist/components/images/image-share.d.ts +2 -1
  248. package/dist/components/images/image-share.d.ts.map +1 -1
  249. package/dist/components/images/image-share.js +3 -3
  250. package/dist/components/images/image-share.js.map +1 -1
  251. package/dist/components/images/image-viewer.d.ts.map +1 -1
  252. package/dist/components/images/image-viewer.js +3 -1
  253. package/dist/components/images/image-viewer.js.map +1 -1
  254. package/dist/components/images/mask-editor.d.ts.map +1 -1
  255. package/dist/components/images/mask-editor.js +7 -5
  256. package/dist/components/images/mask-editor.js.map +1 -1
  257. package/dist/components/layout/app-shell.d.ts.map +1 -1
  258. package/dist/components/layout/app-shell.js +4 -1
  259. package/dist/components/layout/app-shell.js.map +1 -1
  260. package/dist/components/layout/desktop-palette.d.ts +23 -0
  261. package/dist/components/layout/desktop-palette.d.ts.map +1 -0
  262. package/dist/components/layout/desktop-palette.js +132 -0
  263. package/dist/components/layout/desktop-palette.js.map +1 -0
  264. package/dist/components/layout/key-cap.d.ts +9 -0
  265. package/dist/components/layout/key-cap.d.ts.map +1 -0
  266. package/dist/components/layout/key-cap.js +10 -0
  267. package/dist/components/layout/key-cap.js.map +1 -0
  268. package/dist/components/layout/mobile-tab-bar.d.ts +13 -0
  269. package/dist/components/layout/mobile-tab-bar.d.ts.map +1 -1
  270. package/dist/components/layout/mobile-tab-bar.js +58 -47
  271. package/dist/components/layout/mobile-tab-bar.js.map +1 -1
  272. package/dist/components/layout/shortcut-switch.d.ts +13 -0
  273. package/dist/components/layout/shortcut-switch.d.ts.map +1 -0
  274. package/dist/components/layout/shortcut-switch.js +22 -0
  275. package/dist/components/layout/shortcut-switch.js.map +1 -0
  276. package/dist/components/layout/side-rail.d.ts +24 -0
  277. package/dist/components/layout/side-rail.d.ts.map +1 -1
  278. package/dist/components/layout/side-rail.js +65 -27
  279. package/dist/components/layout/side-rail.js.map +1 -1
  280. package/dist/components/layout/slide-panel.d.ts +12 -2
  281. package/dist/components/layout/slide-panel.d.ts.map +1 -1
  282. package/dist/components/layout/slide-panel.js +11 -2
  283. package/dist/components/layout/slide-panel.js.map +1 -1
  284. package/dist/components/layout/theme.d.ts +22 -0
  285. package/dist/components/layout/theme.d.ts.map +1 -0
  286. package/dist/components/layout/theme.js +44 -0
  287. package/dist/components/layout/theme.js.map +1 -0
  288. package/dist/components/quick-actions/add-form.d.ts +44 -0
  289. package/dist/components/quick-actions/add-form.d.ts.map +1 -0
  290. package/dist/components/quick-actions/add-form.js +30 -0
  291. package/dist/components/quick-actions/add-form.js.map +1 -0
  292. package/dist/components/quick-actions/add-modal.d.ts +7 -0
  293. package/dist/components/quick-actions/add-modal.d.ts.map +1 -1
  294. package/dist/components/quick-actions/add-modal.js +23 -20
  295. package/dist/components/quick-actions/add-modal.js.map +1 -1
  296. package/dist/components/quick-actions/search-modal.d.ts.map +1 -1
  297. package/dist/components/quick-actions/search-modal.js +4 -3
  298. package/dist/components/quick-actions/search-modal.js.map +1 -1
  299. package/dist/components/quick-actions/streaming-modal.d.ts +6 -0
  300. package/dist/components/quick-actions/streaming-modal.d.ts.map +1 -1
  301. package/dist/components/quick-actions/streaming-modal.js +39 -17
  302. package/dist/components/quick-actions/streaming-modal.js.map +1 -1
  303. package/dist/components/quick-actions/streaming-output.d.ts +38 -0
  304. package/dist/components/quick-actions/streaming-output.d.ts.map +1 -0
  305. package/dist/components/quick-actions/streaming-output.js +22 -0
  306. package/dist/components/quick-actions/streaming-output.js.map +1 -0
  307. package/dist/components/quick-actions/whatsup-modal.d.ts +5 -0
  308. package/dist/components/quick-actions/whatsup-modal.d.ts.map +1 -1
  309. package/dist/components/quick-actions/whatsup-modal.js +36 -10
  310. package/dist/components/quick-actions/whatsup-modal.js.map +1 -1
  311. package/dist/components/settings/devices-agents-tab.d.ts +6 -1
  312. package/dist/components/settings/devices-agents-tab.d.ts.map +1 -1
  313. package/dist/components/settings/devices-agents-tab.js +55 -20
  314. package/dist/components/settings/devices-agents-tab.js.map +1 -1
  315. package/dist/components/settings/models-list.d.ts +39 -0
  316. package/dist/components/settings/models-list.d.ts.map +1 -0
  317. package/dist/components/settings/models-list.js +72 -0
  318. package/dist/components/settings/models-list.js.map +1 -0
  319. package/dist/components/settings/models-tab.d.ts +4 -0
  320. package/dist/components/settings/models-tab.d.ts.map +1 -1
  321. package/dist/components/settings/models-tab.js +52 -102
  322. package/dist/components/settings/models-tab.js.map +1 -1
  323. package/dist/components/settings/one-time-agent-credential.js +1 -1
  324. package/dist/components/settings/one-time-agent-credential.js.map +1 -1
  325. package/dist/components/settings/passkey-list.d.ts +35 -0
  326. package/dist/components/settings/passkey-list.d.ts.map +1 -0
  327. package/dist/components/settings/passkey-list.js +34 -0
  328. package/dist/components/settings/passkey-list.js.map +1 -0
  329. package/dist/components/settings/passkey-tab.d.ts +3 -0
  330. package/dist/components/settings/passkey-tab.d.ts.map +1 -1
  331. package/dist/components/settings/passkey-tab.js +53 -45
  332. package/dist/components/settings/passkey-tab.js.map +1 -1
  333. package/dist/components/settings/pi-accounts-list.d.ts +27 -0
  334. package/dist/components/settings/pi-accounts-list.d.ts.map +1 -0
  335. package/dist/components/settings/pi-accounts-list.js +15 -0
  336. package/dist/components/settings/pi-accounts-list.js.map +1 -0
  337. package/dist/components/settings/pi-accounts.d.ts +3 -0
  338. package/dist/components/settings/pi-accounts.d.ts.map +1 -1
  339. package/dist/components/settings/pi-accounts.js +73 -55
  340. package/dist/components/settings/pi-accounts.js.map +1 -1
  341. package/dist/components/settings/principal-list.d.ts +37 -0
  342. package/dist/components/settings/principal-list.d.ts.map +1 -0
  343. package/dist/components/settings/principal-list.js +18 -0
  344. package/dist/components/settings/principal-list.js.map +1 -0
  345. package/dist/components/settings/settings-panel.d.ts +10 -3
  346. package/dist/components/settings/settings-panel.d.ts.map +1 -1
  347. package/dist/components/settings/settings-panel.js +69 -8
  348. package/dist/components/settings/settings-panel.js.map +1 -1
  349. package/dist/components/settings/skills-list.d.ts +53 -0
  350. package/dist/components/settings/skills-list.d.ts.map +1 -0
  351. package/dist/components/settings/skills-list.js +28 -0
  352. package/dist/components/settings/skills-list.js.map +1 -0
  353. package/dist/components/settings/skills-tab.d.ts.map +1 -1
  354. package/dist/components/settings/skills-tab.js +65 -38
  355. package/dist/components/settings/skills-tab.js.map +1 -1
  356. package/dist/components/settings/tool-permissions-list.d.ts +18 -0
  357. package/dist/components/settings/tool-permissions-list.d.ts.map +1 -0
  358. package/dist/components/settings/tool-permissions-list.js +6 -0
  359. package/dist/components/settings/tool-permissions-list.js.map +1 -0
  360. package/dist/components/settings/tool-permissions.d.ts +2 -1
  361. package/dist/components/settings/tool-permissions.d.ts.map +1 -1
  362. package/dist/components/settings/tool-permissions.js +33 -16
  363. package/dist/components/settings/tool-permissions.js.map +1 -1
  364. package/dist/components/settings/web-search-chain.d.ts +41 -0
  365. package/dist/components/settings/web-search-chain.d.ts.map +1 -0
  366. package/dist/components/settings/web-search-chain.js +47 -0
  367. package/dist/components/settings/web-search-chain.js.map +1 -0
  368. package/dist/components/settings/web-search-settings.d.ts +4 -7
  369. package/dist/components/settings/web-search-settings.d.ts.map +1 -1
  370. package/dist/components/settings/web-search-settings.js +54 -76
  371. package/dist/components/settings/web-search-settings.js.map +1 -1
  372. package/dist/components/share/share-menu.d.ts.map +1 -1
  373. package/dist/components/share/share-menu.js +24 -4
  374. package/dist/components/share/share-menu.js.map +1 -1
  375. package/dist/components/voice/dictation-sheet.js +3 -3
  376. package/dist/components/voice/dictation-sheet.js.map +1 -1
  377. package/dist/components/voice/mic-button.js +1 -1
  378. package/dist/components/voice/mic-button.js.map +1 -1
  379. package/dist/components/voice/review-card.js +1 -1
  380. package/dist/components/voice/review-card.js.map +1 -1
  381. package/dist/config.d.ts +5 -2
  382. package/dist/config.d.ts.map +1 -1
  383. package/dist/config.js +15 -5
  384. package/dist/config.js.map +1 -1
  385. package/dist/connection.d.ts +12 -0
  386. package/dist/connection.d.ts.map +1 -0
  387. package/dist/connection.js +421 -0
  388. package/dist/connection.js.map +1 -0
  389. package/dist/default-root.d.ts +3 -0
  390. package/dist/default-root.d.ts.map +1 -0
  391. package/dist/default-root.js +16 -0
  392. package/dist/default-root.js.map +1 -0
  393. package/dist/hooks/use-color-scheme.d.ts +14 -0
  394. package/dist/hooks/use-color-scheme.d.ts.map +1 -0
  395. package/dist/hooks/use-color-scheme.js +37 -0
  396. package/dist/hooks/use-color-scheme.js.map +1 -0
  397. package/dist/hooks/use-hash-routes.d.ts.map +1 -1
  398. package/dist/hooks/use-hash-routes.js +4 -2
  399. package/dist/hooks/use-hash-routes.js.map +1 -1
  400. package/dist/hooks/use-media-query.d.ts +7 -0
  401. package/dist/hooks/use-media-query.d.ts.map +1 -0
  402. package/dist/hooks/use-media-query.js +34 -0
  403. package/dist/hooks/use-media-query.js.map +1 -0
  404. package/dist/hooks/use-share-intake.d.ts.map +1 -1
  405. package/dist/hooks/use-share-intake.js +37 -12
  406. package/dist/hooks/use-share-intake.js.map +1 -1
  407. package/dist/hooks/use-vpn-status.d.ts.map +1 -1
  408. package/dist/hooks/use-vpn-status.js +17 -18
  409. package/dist/hooks/use-vpn-status.js.map +1 -1
  410. package/dist/hooks/use-websocket.d.ts +5 -24
  411. package/dist/hooks/use-websocket.d.ts.map +1 -1
  412. package/dist/hooks/use-websocket.js +11 -384
  413. package/dist/hooks/use-websocket.js.map +1 -1
  414. package/dist/hooks/websocket-handlers/activity.d.ts +2 -2
  415. package/dist/hooks/websocket-handlers/activity.d.ts.map +1 -1
  416. package/dist/hooks/websocket-handlers/activity.js +4 -5
  417. package/dist/hooks/websocket-handlers/activity.js.map +1 -1
  418. package/dist/hooks/websocket-handlers/chat.d.ts +1 -0
  419. package/dist/hooks/websocket-handlers/chat.d.ts.map +1 -1
  420. package/dist/hooks/websocket-handlers/chat.js +27 -5
  421. package/dist/hooks/websocket-handlers/chat.js.map +1 -1
  422. package/dist/hooks/websocket-handlers/connection.d.ts.map +1 -1
  423. package/dist/hooks/websocket-handlers/connection.js +4 -6
  424. package/dist/hooks/websocket-handlers/connection.js.map +1 -1
  425. package/dist/hooks/websocket-handlers/mask.d.ts +1 -1
  426. package/dist/hooks/websocket-handlers/mask.d.ts.map +1 -1
  427. package/dist/hooks/websocket-handlers/mask.js +2 -3
  428. package/dist/hooks/websocket-handlers/mask.js.map +1 -1
  429. package/dist/hooks/websocket-handlers/provider.d.ts.map +1 -1
  430. package/dist/hooks/websocket-handlers/provider.js +4 -6
  431. package/dist/hooks/websocket-handlers/provider.js.map +1 -1
  432. package/dist/hooks/websocket-handlers/types.d.ts +6 -2
  433. package/dist/hooks/websocket-handlers/types.d.ts.map +1 -1
  434. package/dist/index.d.ts +5 -3
  435. package/dist/index.d.ts.map +1 -1
  436. package/dist/index.js +6 -3
  437. package/dist/index.js.map +1 -1
  438. package/dist/lib/api-client.d.ts +289 -0
  439. package/dist/lib/api-client.d.ts.map +1 -1
  440. package/dist/lib/api-client.js +243 -224
  441. package/dist/lib/api-client.js.map +1 -1
  442. package/dist/lib/backend.d.ts +19 -2
  443. package/dist/lib/backend.d.ts.map +1 -1
  444. package/dist/lib/backend.js +15 -9
  445. package/dist/lib/backend.js.map +1 -1
  446. package/dist/lib/diff.d.ts +8 -10
  447. package/dist/lib/diff.d.ts.map +1 -1
  448. package/dist/lib/diff.js +26 -53
  449. package/dist/lib/diff.js.map +1 -1
  450. package/dist/lib/light-dark.d.ts +37 -0
  451. package/dist/lib/light-dark.d.ts.map +1 -0
  452. package/dist/lib/light-dark.js +83 -0
  453. package/dist/lib/light-dark.js.map +1 -0
  454. package/dist/lib/mermaid-theme.d.ts +7 -2
  455. package/dist/lib/mermaid-theme.d.ts.map +1 -1
  456. package/dist/lib/mermaid-theme.js +125 -203
  457. package/dist/lib/mermaid-theme.js.map +1 -1
  458. package/dist/lib/passkeys.d.ts +6 -3
  459. package/dist/lib/passkeys.d.ts.map +1 -1
  460. package/dist/lib/passkeys.js +10 -4
  461. package/dist/lib/passkeys.js.map +1 -1
  462. package/dist/lib/push-registration.d.ts +4 -1
  463. package/dist/lib/push-registration.d.ts.map +1 -1
  464. package/dist/lib/push-registration.js +20 -2
  465. package/dist/lib/push-registration.js.map +1 -1
  466. package/dist/lib/share-intake.d.ts +2 -1
  467. package/dist/lib/share-intake.d.ts.map +1 -1
  468. package/dist/lib/share-intake.js +3 -3
  469. package/dist/lib/share-intake.js.map +1 -1
  470. package/dist/lib/share.d.ts +4 -3
  471. package/dist/lib/share.d.ts.map +1 -1
  472. package/dist/lib/share.js +6 -7
  473. package/dist/lib/share.js.map +1 -1
  474. package/dist/lib/single-key.d.ts +30 -0
  475. package/dist/lib/single-key.d.ts.map +1 -0
  476. package/dist/lib/single-key.js +45 -0
  477. package/dist/lib/single-key.js.map +1 -0
  478. package/dist/lib/tool-names.d.ts +8 -6
  479. package/dist/lib/tool-names.d.ts.map +1 -1
  480. package/dist/lib/tool-names.js +17 -7
  481. package/dist/lib/tool-names.js.map +1 -1
  482. package/dist/root-context.d.ts +229 -0
  483. package/dist/root-context.d.ts.map +1 -0
  484. package/dist/root-context.js +33 -0
  485. package/dist/root-context.js.map +1 -0
  486. package/dist/root.d.ts +38 -0
  487. package/dist/root.d.ts.map +1 -0
  488. package/dist/root.js +47 -0
  489. package/dist/root.js.map +1 -0
  490. package/dist/stores/activity-state.d.ts +29 -0
  491. package/dist/stores/activity-state.d.ts.map +1 -0
  492. package/dist/stores/activity-state.js +282 -0
  493. package/dist/stores/activity-state.js.map +1 -0
  494. package/dist/stores/activity-store.d.ts +10 -41
  495. package/dist/stores/activity-store.d.ts.map +1 -1
  496. package/dist/stores/activity-store.js +9 -271
  497. package/dist/stores/activity-store.js.map +1 -1
  498. package/dist/stores/chat-state.d.ts +212 -0
  499. package/dist/stores/chat-state.d.ts.map +1 -0
  500. package/dist/stores/chat-state.js +466 -0
  501. package/dist/stores/chat-state.js.map +1 -0
  502. package/dist/stores/chat-store.d.ts +4 -162
  503. package/dist/stores/chat-store.d.ts.map +1 -1
  504. package/dist/stores/chat-store.js +7 -418
  505. package/dist/stores/chat-store.js.map +1 -1
  506. package/dist/stores/connection-state.d.ts +40 -0
  507. package/dist/stores/connection-state.d.ts.map +1 -0
  508. package/dist/stores/connection-state.js +30 -0
  509. package/dist/stores/connection-state.js.map +1 -0
  510. package/dist/stores/connection-store.d.ts +4 -40
  511. package/dist/stores/connection-store.d.ts.map +1 -1
  512. package/dist/stores/connection-store.js +7 -27
  513. package/dist/stores/connection-store.js.map +1 -1
  514. package/dist/stores/create-stores.d.ts +23 -0
  515. package/dist/stores/create-stores.d.ts.map +1 -0
  516. package/dist/stores/create-stores.js +28 -0
  517. package/dist/stores/create-stores.js.map +1 -0
  518. package/dist/stores/file-state.d.ts +53 -0
  519. package/dist/stores/file-state.d.ts.map +1 -0
  520. package/dist/stores/file-state.js +341 -0
  521. package/dist/stores/file-state.js.map +1 -0
  522. package/dist/stores/file-store.d.ts +4 -52
  523. package/dist/stores/file-store.d.ts.map +1 -1
  524. package/dist/stores/file-store.js +7 -336
  525. package/dist/stores/file-store.js.map +1 -1
  526. package/dist/stores/graph-state.d.ts +95 -0
  527. package/dist/stores/graph-state.d.ts.map +1 -0
  528. package/dist/stores/graph-state.js +252 -0
  529. package/dist/stores/graph-state.js.map +1 -0
  530. package/dist/stores/graph-store.d.ts +7 -83
  531. package/dist/stores/graph-store.d.ts.map +1 -1
  532. package/dist/stores/graph-store.js +8 -249
  533. package/dist/stores/graph-store.js.map +1 -1
  534. package/dist/stores/mask-state.d.ts +21 -0
  535. package/dist/stores/mask-state.d.ts.map +1 -0
  536. package/dist/stores/mask-state.js +9 -0
  537. package/dist/stores/mask-state.js.map +1 -0
  538. package/dist/stores/mask-store.d.ts +4 -21
  539. package/dist/stores/mask-store.d.ts.map +1 -1
  540. package/dist/stores/mask-store.js +7 -6
  541. package/dist/stores/mask-store.js.map +1 -1
  542. package/dist/stores/principal-state.d.ts +16 -0
  543. package/dist/stores/principal-state.d.ts.map +1 -0
  544. package/dist/stores/principal-state.js +31 -0
  545. package/dist/stores/principal-state.js.map +1 -0
  546. package/dist/stores/principal-store.d.ts +4 -15
  547. package/dist/stores/principal-store.d.ts.map +1 -1
  548. package/dist/stores/principal-store.js +7 -28
  549. package/dist/stores/principal-store.js.map +1 -1
  550. package/dist/stores/provider-state.d.ts +24 -0
  551. package/dist/stores/provider-state.d.ts.map +1 -0
  552. package/dist/stores/provider-state.js +68 -0
  553. package/dist/stores/provider-state.js.map +1 -0
  554. package/dist/stores/provider-store.d.ts +4 -23
  555. package/dist/stores/provider-store.d.ts.map +1 -1
  556. package/dist/stores/provider-store.js +7 -64
  557. package/dist/stores/provider-store.js.map +1 -1
  558. package/dist/stores/share-state.d.ts +29 -0
  559. package/dist/stores/share-state.d.ts.map +1 -0
  560. package/dist/stores/share-state.js +21 -0
  561. package/dist/stores/share-state.js.map +1 -0
  562. package/dist/stores/share-store.d.ts +4 -28
  563. package/dist/stores/share-store.d.ts.map +1 -1
  564. package/dist/stores/share-store.js +7 -18
  565. package/dist/stores/share-store.js.map +1 -1
  566. package/dist/stores/store-environment.d.ts +10 -0
  567. package/dist/stores/store-environment.d.ts.map +1 -0
  568. package/dist/stores/store-environment.js +2 -0
  569. package/dist/stores/store-environment.js.map +1 -0
  570. package/dist/stores/ui-state.d.ts +71 -0
  571. package/dist/stores/ui-state.d.ts.map +1 -0
  572. package/dist/stores/ui-state.js +58 -0
  573. package/dist/stores/ui-state.js.map +1 -0
  574. package/dist/stores/ui-store.d.ts +4 -45
  575. package/dist/stores/ui-store.d.ts.map +1 -1
  576. package/dist/stores/ui-store.js +7 -36
  577. package/dist/stores/ui-store.js.map +1 -1
  578. package/dist/styles.css +1 -1
  579. package/dist/theme.css +150 -97
  580. package/dist/voice/asr-clients.d.ts +2 -1
  581. package/dist/voice/asr-clients.d.ts.map +1 -1
  582. package/dist/voice/asr-clients.js +16 -17
  583. package/dist/voice/asr-clients.js.map +1 -1
  584. package/dist/voice/use-dictation.d.ts.map +1 -1
  585. package/dist/voice/use-dictation.js +12 -8
  586. package/dist/voice/use-dictation.js.map +1 -1
  587. package/dist/voice/voice-state.d.ts +25 -0
  588. package/dist/voice/voice-state.d.ts.map +1 -0
  589. package/dist/voice/voice-state.js +29 -0
  590. package/dist/voice/voice-state.js.map +1 -0
  591. package/dist/voice/voice-store.d.ts +4 -25
  592. package/dist/voice/voice-store.d.ts.map +1 -1
  593. package/dist/voice/voice-store.js +7 -26
  594. package/dist/voice/voice-store.js.map +1 -1
  595. package/package.json +3 -2
  596. package/src/components/activity/activity-page.tsx +334 -160
  597. package/src/components/activity/activity-run-detail.tsx +81 -47
  598. package/src/components/activity/activity-run-list.tsx +27 -59
  599. package/src/components/activity/activity-views.tsx +155 -0
  600. package/src/components/activity/approval-card.tsx +80 -0
  601. package/src/components/activity/digest-card.tsx +25 -61
  602. package/src/components/activity/digest-summary.tsx +52 -0
  603. package/src/components/activity/push-switch.tsx +62 -0
  604. package/src/components/activity/push-toggle.tsx +51 -81
  605. package/src/components/activity/span-bits.tsx +8 -7
  606. package/src/components/chat/ask-user-card.tsx +292 -356
  607. package/src/components/chat/ask-user-typed.ts +77 -0
  608. package/src/components/chat/brain-markdown-links.tsx +4 -4
  609. package/src/components/chat/brain-markdown.tsx +4 -2
  610. package/src/components/chat/chat-page.tsx +38 -9
  611. package/src/components/chat/composer-view.tsx +194 -0
  612. package/src/components/chat/composer.tsx +117 -296
  613. package/src/components/chat/markdown-content.tsx +53 -2
  614. package/src/components/chat/mermaid-block.tsx +13 -5
  615. package/src/components/chat/mermaid-share.ts +8 -7
  616. package/src/components/chat/mermaid-viewer.tsx +3 -1
  617. package/src/components/chat/message-bubble.tsx +78 -94
  618. package/src/components/chat/message-share.ts +7 -7
  619. package/src/components/chat/renderers/bind.tsx +94 -0
  620. package/src/components/chat/renderers/brain-ui-tools.tsx +56 -0
  621. package/src/components/chat/renderers/claude-tools.tsx +3 -2
  622. package/src/components/chat/renderers/index.ts +15 -10
  623. package/src/components/chat/session-drawer.tsx +41 -138
  624. package/src/components/chat/session-list.tsx +113 -0
  625. package/src/components/chat/share-block.tsx +16 -12
  626. package/src/components/chat/share-card.tsx +2 -2
  627. package/src/components/chat/subagent-view.tsx +4 -4
  628. package/src/components/chat/tool-call-timeline.tsx +59 -22
  629. package/src/components/chat/tool-cards/block-card.tsx +145 -0
  630. package/src/components/chat/tool-cards/image-mask-card.tsx +214 -0
  631. package/src/components/chat/tool-cards/location-card.tsx +159 -0
  632. package/src/components/chat/tool-views.tsx +21 -60
  633. package/src/components/chat/transcript-turn.tsx +108 -0
  634. package/src/components/chat/use-chat-commands.ts +14 -16
  635. package/src/components/chat/welcome-state.tsx +36 -91
  636. package/src/components/connectivity/connection-gate.tsx +32 -24
  637. package/src/components/connectivity/login-form.tsx +122 -0
  638. package/src/components/connectivity/login-screen.tsx +45 -100
  639. package/src/components/dev/share-harness.tsx +2 -2
  640. package/src/components/files/file-panel.tsx +168 -0
  641. package/src/components/files/file-tree-view.tsx +127 -0
  642. package/src/components/files/file-tree.tsx +55 -109
  643. package/src/components/files/file-viewer-binary.tsx +3 -2
  644. package/src/components/files/file-viewer-frame.tsx +113 -0
  645. package/src/components/files/file-viewer.tsx +40 -95
  646. package/src/components/files/frontmatter-chips.tsx +42 -0
  647. package/src/components/files/frontmatter-panel.tsx +6 -71
  648. package/src/components/files/staleness.ts +29 -0
  649. package/src/components/graph/graph-canvas.tsx +24 -1
  650. package/src/components/graph/graph-controls-column.tsx +92 -0
  651. package/src/components/graph/graph-controls.tsx +83 -127
  652. package/src/components/graph/graph-form.tsx +183 -0
  653. package/src/components/graph/graph-maintenance.tsx +9 -14
  654. package/src/components/graph/graph-node-rail.tsx +147 -0
  655. package/src/components/graph/graph-page.tsx +189 -49
  656. package/src/components/graph/graph-scene.tsx +200 -30
  657. package/src/components/graph/lib/graph-helpers.ts +65 -43
  658. package/src/components/graph/node-card.tsx +64 -0
  659. package/src/components/graph/node-popover.tsx +28 -117
  660. package/src/components/graph/use-graph-theme.ts +69 -32
  661. package/src/components/graph/use-node-actions.ts +56 -0
  662. package/src/components/images/image-share.ts +4 -2
  663. package/src/components/images/image-viewer.tsx +3 -1
  664. package/src/components/images/mask-editor.tsx +7 -4
  665. package/src/components/layout/app-shell.tsx +5 -1
  666. package/src/components/layout/desktop-palette.tsx +151 -0
  667. package/src/components/layout/key-cap.tsx +15 -0
  668. package/src/components/layout/mobile-tab-bar.tsx +80 -157
  669. package/src/components/layout/shortcut-switch.tsx +32 -0
  670. package/src/components/layout/side-rail.tsx +70 -150
  671. package/src/components/layout/slide-panel.tsx +29 -2
  672. package/src/components/layout/theme.tsx +67 -0
  673. package/src/components/quick-actions/add-form.tsx +188 -0
  674. package/src/components/quick-actions/add-modal.tsx +32 -153
  675. package/src/components/quick-actions/search-modal.tsx +5 -3
  676. package/src/components/quick-actions/streaming-modal.tsx +42 -71
  677. package/src/components/quick-actions/streaming-output.tsx +112 -0
  678. package/src/components/quick-actions/whatsup-modal.tsx +38 -60
  679. package/src/components/settings/devices-agents-tab.tsx +60 -152
  680. package/src/components/settings/models-list.tsx +299 -0
  681. package/src/components/settings/models-tab.tsx +63 -337
  682. package/src/components/settings/one-time-agent-credential.tsx +1 -1
  683. package/src/components/settings/passkey-list.tsx +201 -0
  684. package/src/components/settings/passkey-tab.tsx +53 -197
  685. package/src/components/settings/pi-accounts-list.tsx +128 -0
  686. package/src/components/settings/pi-accounts.tsx +71 -170
  687. package/src/components/settings/principal-list.tsx +172 -0
  688. package/src/components/settings/settings-panel.tsx +232 -21
  689. package/src/components/settings/skills-list.tsx +276 -0
  690. package/src/components/settings/skills-tab.tsx +82 -269
  691. package/src/components/settings/tool-permissions-list.tsx +54 -0
  692. package/src/components/settings/tool-permissions.tsx +27 -46
  693. package/src/components/settings/web-search-chain.tsx +300 -0
  694. package/src/components/settings/web-search-settings.tsx +58 -328
  695. package/src/components/share/share-menu.tsx +19 -4
  696. package/src/components/voice/dictation-sheet.tsx +5 -5
  697. package/src/components/voice/mic-button.tsx +1 -1
  698. package/src/components/voice/review-card.tsx +1 -1
  699. package/src/config.ts +21 -7
  700. package/src/connection.ts +443 -0
  701. package/src/default-root.ts +16 -0
  702. package/src/hooks/use-color-scheme.ts +36 -0
  703. package/src/hooks/use-hash-routes.ts +4 -2
  704. package/src/hooks/use-media-query.ts +32 -0
  705. package/src/hooks/use-share-intake.ts +32 -12
  706. package/src/hooks/use-vpn-status.ts +18 -17
  707. package/src/hooks/use-websocket.ts +12 -428
  708. package/src/hooks/websocket-handlers/activity.ts +4 -5
  709. package/src/hooks/websocket-handlers/chat.ts +26 -5
  710. package/src/hooks/websocket-handlers/connection.ts +4 -6
  711. package/src/hooks/websocket-handlers/mask.ts +2 -3
  712. package/src/hooks/websocket-handlers/provider.ts +4 -6
  713. package/src/hooks/websocket-handlers/types.ts +6 -2
  714. package/src/index.ts +7 -3
  715. package/src/lib/api-client.ts +426 -384
  716. package/src/lib/backend.ts +20 -10
  717. package/src/lib/diff.ts +28 -62
  718. package/src/lib/light-dark.ts +83 -0
  719. package/src/lib/mermaid-theme.ts +183 -214
  720. package/src/lib/passkeys.ts +12 -4
  721. package/src/lib/push-registration.ts +19 -2
  722. package/src/lib/share-intake.ts +6 -3
  723. package/src/lib/share.ts +7 -4
  724. package/src/lib/single-key.ts +47 -0
  725. package/src/lib/tool-names.ts +31 -8
  726. package/src/root-context.tsx +40 -0
  727. package/src/root.ts +83 -0
  728. package/src/stores/activity-state.ts +295 -0
  729. package/src/stores/activity-store.ts +11 -285
  730. package/src/stores/chat-state.ts +795 -0
  731. package/src/stores/chat-store.ts +11 -705
  732. package/src/stores/connection-state.ts +78 -0
  733. package/src/stores/connection-store.ts +11 -76
  734. package/src/stores/create-stores.ts +31 -0
  735. package/src/stores/file-state.ts +399 -0
  736. package/src/stores/file-store.ts +9 -390
  737. package/src/stores/graph-state.ts +368 -0
  738. package/src/stores/graph-store.ts +10 -355
  739. package/src/stores/mask-state.ts +30 -0
  740. package/src/stores/mask-store.ts +10 -27
  741. package/src/stores/principal-state.ts +42 -0
  742. package/src/stores/principal-store.ts +10 -37
  743. package/src/stores/provider-state.ts +103 -0
  744. package/src/stores/provider-store.ts +10 -95
  745. package/src/stores/share-state.ts +56 -0
  746. package/src/stores/share-store.ts +11 -54
  747. package/src/stores/store-environment.ts +10 -0
  748. package/src/stores/ui-state.ts +143 -0
  749. package/src/stores/ui-store.ts +11 -93
  750. package/src/styles.css +4 -1
  751. package/src/theme.css +150 -97
  752. package/src/voice/asr-clients.ts +17 -17
  753. package/src/voice/use-dictation.ts +11 -8
  754. package/src/voice/voice-state.ts +57 -0
  755. package/src/voice/voice-store.ts +11 -55
@@ -15,23 +15,26 @@ import type {
15
15
  import { useGraphStore } from "../../stores/graph-store.js";
16
16
  import { useUIStore } from "../../stores/ui-store.js";
17
17
  import { useFileStore } from "../../stores/file-store.js";
18
- import { apiBase } from "../../lib/backend.js";
19
- import { GraphControls } from "./graph-controls.js";
18
+ import { useBrainUiRoot } from "../../root-context.js";
19
+ import { GraphControls, WIDE_QUERY } from "./graph-controls.js";
20
20
  import { NodePopover } from "./node-popover.js";
21
+ import { useMediaQuery } from "../../hooks/use-media-query.js";
21
22
  import { GraphEmptyState, Mono } from "./graph-empty-state.js";
22
23
  import { GraphCanvas } from "./graph-canvas-lazy.js";
23
24
  import { CenteredSpinner } from "./graph-spinner.js";
24
25
  import {
25
- OTHER_COLOR,
26
26
  assignFolderColors,
27
27
  buildQuery,
28
28
  communityColor,
29
29
  distanceColor,
30
+ entityKind,
31
+ entityLegend,
30
32
  groupCommunities,
31
33
  matchScene,
32
34
  topLevelDir,
35
+ type CanvasPalette,
33
36
  } from "./lib/graph-helpers.js";
34
- import { useGraphTheme } from "./use-graph-theme.js";
37
+ import { useGraphTheme, type EntityColors } from "./use-graph-theme.js";
35
38
  import { cn } from "../../lib/utils.js";
36
39
 
37
40
  /** Client force layout is a fallback for repos whose FA2 layout was skipped —
@@ -52,6 +55,9 @@ export function SceneBody() {
52
55
  const discoveryColorBy = useGraphStore((s) => s.discoveryColorBy);
53
56
  const theme = useGraphTheme();
54
57
  const [listOpen, setListOpen] = useState(false);
58
+ // From `wide:` the D6 right rail draws the selected node; the floating
59
+ // card would double it.
60
+ const wide = useMediaQuery(WIDE_QUERY);
55
61
 
56
62
  const matchIds = useMemo(
57
63
  () => matchScene(subgraph.nodes, sceneQuery),
@@ -72,28 +78,58 @@ export function SceneBody() {
72
78
  [subgraph.nodes]
73
79
  );
74
80
 
81
+ // The colouring rule (sixth pass §7) applies to the two modes drawn
82
+ // around a focus node; Clusters IS the topic colouring. The focus node
83
+ // (Discovery's root, Local's centre — distance 0, or the virtual root)
84
+ // wears the amber of "the thing in focus" under every rule, as the kit's
85
+ // `GraphView` draws it.
86
+ const focused = mode === "discovery" || mode === "local";
87
+ const rule = focused ? discoveryColorBy : "topic";
88
+
89
+ // What the categorical legends describe: every node painted BY its category.
90
+ // The focus node (the local centre, an explicit root, or a virtual node) is
91
+ // painted amber whatever its type, folder or topic, so counting it under
92
+ // one would make the legend disagree with the canvas.
93
+ const legendNodes = useMemo(
94
+ () => subgraph.nodes.filter((n) => !(n.virtual === true || (focused && n.distance === 0))),
95
+ [subgraph.nodes, focused]
96
+ );
97
+
75
98
  const folderColors = useMemo(
76
99
  () =>
77
- mode === "discovery" && discoveryColorBy === "folder"
78
- ? assignFolderColors(subgraph.nodes.map((n) => n.path))
100
+ focused && rule === "folder"
101
+ ? assignFolderColors(legendNodes.map((n) => n.path), theme.palette)
79
102
  : null,
80
- [mode, discoveryColorBy, subgraph.nodes]
103
+ [focused, rule, legendNodes, theme.palette]
81
104
  );
82
105
 
83
106
  const nodeColor = useMemo(() => {
84
- if (mode === "discovery") {
85
- if (folderColors) {
107
+ const isFocus = (node: GraphNodePayload) => node.virtual === true || (focused && node.distance === 0);
108
+ if (focused) {
109
+ if (rule === "folder" && folderColors) {
110
+ return (node: GraphNodePayload) =>
111
+ isFocus(node)
112
+ ? theme.nodeSelected
113
+ : (folderColors.get(topLevelDir(node.path)) ?? theme.palette.other);
114
+ }
115
+ if (rule === "entity") {
116
+ return (node: GraphNodePayload) =>
117
+ isFocus(node) ? theme.entity.focus : entityColor(node.type, theme.entity);
118
+ }
119
+ if (rule === "topic") {
86
120
  return (node: GraphNodePayload) =>
87
- node.virtual
121
+ isFocus(node)
88
122
  ? theme.nodeSelected
89
- : (folderColors.get(topLevelDir(node.path)) ?? OTHER_COLOR);
123
+ : node.community !== undefined
124
+ ? communityColor(node.community, theme.palette)
125
+ : theme.palette.other;
90
126
  }
91
127
  return (node: GraphNodePayload) =>
92
- node.virtual ? theme.nodeSelected : distanceColor(node.distance ?? maxDistance);
128
+ isFocus(node) ? theme.nodeSelected : distanceColor(node.distance ?? maxDistance, theme.palette);
93
129
  }
94
130
  return (node: GraphNodePayload) =>
95
- node.community !== undefined ? communityColor(node.community) : theme.node;
96
- }, [mode, folderColors, maxDistance, theme]);
131
+ node.community !== undefined ? communityColor(node.community, theme.palette) : theme.node;
132
+ }, [focused, rule, folderColors, maxDistance, theme]);
97
133
 
98
134
  const centerId = useMemo(
99
135
  () =>
@@ -162,9 +198,18 @@ export function SceneBody() {
162
198
 
163
199
  <GraphControls />
164
200
 
165
- {mode === "clusters" && <ClusterLegend />}
166
- {mode === "discovery" && folderColors && (
167
- <FolderLegend colors={folderColors} />
201
+ {/* The legend redraws per rule (sixth pass §7): it names what the
202
+ canvas is doing right now, never a constant. */}
203
+ {mode === "clusters" && <ClusterLegend palette={theme.palette} />}
204
+ {focused && rule === "folder" && folderColors && (
205
+ <FolderLegend colors={folderColors} other={theme.palette.other} />
206
+ )}
207
+ {focused && rule === "entity" && (
208
+ <EntityLegend nodes={legendNodes} colors={theme.entity} />
209
+ )}
210
+ {focused && rule === "topic" && <TopicLegend nodes={legendNodes} palette={theme.palette} />}
211
+ {focused && rule === "distance" && (
212
+ <DistanceLegend maxDistance={maxDistance} focus={mode === "local" ? "centre" : "root"} palette={theme.palette} />
168
213
  )}
169
214
  {mode === "discovery" && (
170
215
  <UnreachableTray count={subgraph.unreachableCount} />
@@ -181,7 +226,7 @@ export function SceneBody() {
181
226
  </button>
182
227
  {listOpen && <NodeList onClose={() => setListOpen(false)} />}
183
228
 
184
- {selectedNode && (
229
+ {selectedNode && !wide && (
185
230
  <NodePopover node={selectedNode} communityLabel={communityLabel} />
186
231
  )}
187
232
  </>
@@ -189,7 +234,7 @@ export function SceneBody() {
189
234
  }
190
235
 
191
236
  /** Clusters mode: interactive community legend, top-left. */
192
- function ClusterLegend() {
237
+ function ClusterLegend({ palette }: { palette: CanvasPalette }) {
193
238
  const meta = useGraphStore((s) => s.meta);
194
239
  const clusters = useGraphStore((s) => s.clusters);
195
240
  const setClustersParams = useGraphStore((s) => s.setClustersParams);
@@ -241,7 +286,7 @@ function ClusterLegend() {
241
286
  >
242
287
  <span
243
288
  className="h-2.5 w-2.5 shrink-0 rounded-full"
244
- style={{ backgroundColor: communityColor(c.community) }}
289
+ style={{ backgroundColor: communityColor(c.community, palette) }}
245
290
  />
246
291
  <span className="min-w-0 flex-1 truncate text-xs text-foreground">
247
292
  {c.label ?? `Topic ${c.community + 1}`}
@@ -256,7 +301,7 @@ function ClusterLegend() {
256
301
  <div className="flex items-center gap-2 px-2 py-1.5">
257
302
  <span
258
303
  className="h-2.5 w-2.5 shrink-0 rounded-full"
259
- style={{ backgroundColor: OTHER_COLOR }}
304
+ style={{ backgroundColor: palette.other }}
260
305
  />
261
306
  <span className="text-[11px] text-muted-foreground">
262
307
  {foldedCount} smaller topic{foldedCount === 1 ? "" : "s"}
@@ -278,9 +323,130 @@ function ClusterLegend() {
278
323
  );
279
324
  }
280
325
 
326
+ /** The kit's entity colour for a document type; neutral for the rest. */
327
+ function entityColor(type: string, colors: EntityColors): string {
328
+ const kind = entityKind(type);
329
+ return kind ? colors[kind] : colors.other;
330
+ }
331
+
332
+ /**
333
+ * Colour-by-entity: the document types in the scene, the three entity kinds
334
+ * in their kit colours first, every other type in the neutral ink under its
335
+ * own name. The focus node is listed as what it is — amber, "focus" — so the
336
+ * one node whose colour is not its type is accounted for.
337
+ */
338
+ function EntityLegend({ nodes, colors }: { nodes: GraphNodePayload[]; colors: EntityColors }) {
339
+ const rows = useMemo(() => entityLegend(nodes), [nodes]);
340
+ return (
341
+ <div
342
+ className="absolute left-3 top-3 z-10 w-48 rounded-xl border border-border bg-surface-overlay/95 px-3 py-2 shadow-xl backdrop-blur"
343
+ data-legend="entity"
344
+ >
345
+ <div className="mb-1 text-xs font-medium text-foreground">Entity type</div>
346
+ <LegendRow color={colors.focus} label="focus" mono={false} />
347
+ {rows.map((row) => (
348
+ <LegendRow
349
+ key={row.type}
350
+ color={row.kind ? colors[row.kind] : colors.other}
351
+ label={row.type}
352
+ count={row.count}
353
+ />
354
+ ))}
355
+ </div>
356
+ );
357
+ }
358
+
359
+ /**
360
+ * Colour-by-topic outside Clusters mode: read-only — the topic FILTER is
361
+ * Clusters' own — listing the communities present in this scene. A corpus
362
+ * with no computed topics says so rather than showing an empty box.
363
+ */
364
+ function TopicLegend({ nodes, palette }: { nodes: GraphNodePayload[]; palette: CanvasPalette }) {
365
+ const meta = useGraphStore((s) => s.meta);
366
+ const rows = useMemo(() => {
367
+ const counts = new Map<number, number>();
368
+ for (const node of nodes) {
369
+ if (node.community === undefined || node.virtual) continue;
370
+ counts.set(node.community, (counts.get(node.community) ?? 0) + 1);
371
+ }
372
+ // The eight largest, folded past that like the cluster legend: a node
373
+ // on the canvas whose colour has no row is a legend that lies by
374
+ // omission. (Communities past the palette share the recessive colour anyway.)
375
+ const all = [...counts.entries()].sort((a, b) => b[1] - a[1] || a[0] - b[0]);
376
+ return { rows: all.slice(0, 8), folded: all.slice(8).reduce((n, [, c]) => n + c, 0), foldedTopics: Math.max(0, all.length - 8) };
377
+ }, [nodes]);
378
+ return (
379
+ <div
380
+ className="absolute left-3 top-3 z-10 w-48 rounded-xl border border-border bg-surface-overlay/95 px-3 py-2 shadow-xl backdrop-blur"
381
+ data-legend="topic"
382
+ >
383
+ <div className="mb-1 text-xs font-medium text-foreground">Topics</div>
384
+ {rows.rows.length === 0 ? (
385
+ <div className="font-mono text-[10px] text-muted-foreground">
386
+ no topics computed · run <Mono>brain sync</Mono>
387
+ </div>
388
+ ) : (
389
+ <>
390
+ {rows.rows.map(([community, count]) => (
391
+ <LegendRow
392
+ key={community}
393
+ color={communityColor(community, palette)}
394
+ label={meta?.communities.find((c) => c.community === community)?.label ?? `Topic ${community + 1}`}
395
+ count={count}
396
+ mono={false}
397
+ />
398
+ ))}
399
+ {rows.foldedTopics > 0 && (
400
+ <LegendRow
401
+ color={palette.other}
402
+ label={`${rows.foldedTopics} smaller topic${rows.foldedTopics === 1 ? "" : "s"}`}
403
+ count={rows.folded}
404
+ mono={false}
405
+ />
406
+ )}
407
+ </>
408
+ )}
409
+ </div>
410
+ );
411
+ }
412
+
413
+ /** Colour-by-distance: the amber focus, then the ramp one hop at a time. */
414
+ function DistanceLegend({ maxDistance, focus, palette }: { maxDistance: number; focus: "root" | "centre"; palette: CanvasPalette }) {
415
+ const hops = Array.from({ length: Math.min(maxDistance, 5) }, (_, i) => i + 1);
416
+ return (
417
+ <div
418
+ className="absolute left-3 top-3 z-10 w-48 rounded-xl border border-border bg-surface-overlay/95 px-3 py-2 shadow-xl backdrop-blur"
419
+ data-legend="distance"
420
+ >
421
+ <div className="mb-1 text-xs font-medium text-foreground">Distance</div>
422
+ <LegendRow color={distanceColor(0, palette)} label={focus} mono={false} />
423
+ {hops.map((hop) => (
424
+ <LegendRow
425
+ key={hop}
426
+ color={distanceColor(hop, palette)}
427
+ label={hop === 5 && maxDistance > 5 ? `${hop}+ hops` : `${hop} hop${hop === 1 ? "" : "s"}`}
428
+ mono={false}
429
+ />
430
+ ))}
431
+ </div>
432
+ );
433
+ }
434
+
435
+ function LegendRow({ color, label, count, mono = true }: { color: string; label: string; count?: number; mono?: boolean }) {
436
+ return (
437
+ <div className="flex min-h-6 items-center gap-2">
438
+ <span className="h-2.5 w-2.5 shrink-0 rounded-full" style={{ backgroundColor: color }} />
439
+ <span className={cn("min-w-0 flex-1 truncate text-muted-foreground", mono ? "font-mono text-[11px]" : "text-[11px]")}>
440
+ {label}
441
+ </span>
442
+ {count !== undefined && <span className="shrink-0 text-[10px] text-muted-foreground">{count}</span>}
443
+ </div>
444
+ );
445
+ }
446
+
281
447
  /** Discovery + color-by-folder: which top-level dir wears which color. */
282
- function FolderLegend({ colors }: { colors: Map<string, string> }) {
283
- const entries = [...colors.entries()].filter(([, c]) => c !== OTHER_COLOR);
448
+ function FolderLegend({ colors, other }: { colors: Map<string, string>; other: string }) {
449
+ const entries = [...colors.entries()].filter(([, c]) => c !== other);
284
450
  const otherCount = colors.size - entries.length;
285
451
  if (entries.length === 0) return null;
286
452
  return (
@@ -301,7 +467,7 @@ function FolderLegend({ colors }: { colors: Map<string, string> }) {
301
467
  <div className="flex min-h-6 items-center gap-2">
302
468
  <span
303
469
  className="h-2.5 w-2.5 shrink-0 rounded-full"
304
- style={{ backgroundColor: OTHER_COLOR }}
470
+ style={{ backgroundColor: other }}
305
471
  />
306
472
  <span className="text-[11px] text-muted-foreground">
307
473
  {otherCount} more
@@ -320,6 +486,7 @@ function FolderLegend({ colors }: { colors: Map<string, string> }) {
320
486
  * maintenance findings still provide the exact list, and shows no number.
321
487
  */
322
488
  function UnreachableTray({ count }: { count: number | undefined }) {
489
+ const root = useBrainUiRoot();
323
490
  const discovery = useGraphStore((s) => s.discovery);
324
491
  const staleDays = useGraphStore((s) => s.maintenance.staleDays);
325
492
  const openFile = useFileStore((s) => s.openFile);
@@ -327,6 +494,7 @@ function UnreachableTray({ count }: { count: number | undefined }) {
327
494
  const [open, setOpen] = useState(false);
328
495
  const [nodes, setNodes] = useState<GraphNodePayload[] | null>(null);
329
496
 
497
+ useEffect(() => { setNodes(null); setOpen(false); }, [root]);
330
498
  const isDefaultRoot = !discovery.root;
331
499
  // Older server, no count field: the maintenance list is the only honest
332
500
  // source, so it must be fetched EAGERLY — the chip may only appear once
@@ -339,8 +507,8 @@ function UnreachableTray({ count }: { count: number | undefined }) {
339
507
  let cancelled = false;
340
508
  void (async () => {
341
509
  try {
342
- const res = await fetch(
343
- `${apiBase()}/graph/maintenance?${buildQuery({ staleDays })}`
510
+ const res = await root.request(
511
+ `${root.apiBase()}/graph/maintenance?${buildQuery({ staleDays })}`
344
512
  );
345
513
  if (!res.ok) return;
346
514
  const data = (await res.json()) as GraphMaintenanceResponse;
@@ -352,7 +520,7 @@ function UnreachableTray({ count }: { count: number | undefined }) {
352
520
  return () => {
353
521
  cancelled = true;
354
522
  };
355
- }, [open, needsFallbackProof, isDefaultRoot, nodes, staleDays]);
523
+ }, [open, needsFallbackProof, isDefaultRoot, nodes, staleDays, root]);
356
524
 
357
525
  if (count === 0) return null;
358
526
  // No server count and no exact list available: nothing honest to show.
@@ -414,17 +582,19 @@ function UnreachableTray({ count }: { count: number | undefined }) {
414
582
  * inviting — index notes are the natural candidates.
415
583
  */
416
584
  export function DiscoveryStart() {
585
+ const root = useBrainUiRoot();
417
586
  const setDiscoveryParams = useGraphStore((s) => s.setDiscoveryParams);
418
587
  const [candidates, setCandidates] = useState<
419
588
  { path: string; title: string }[] | null
420
589
  >(null);
421
590
 
422
591
  useEffect(() => {
592
+ setCandidates(null);
423
593
  let cancelled = false;
424
594
  void (async () => {
425
595
  try {
426
- const res = await fetch(
427
- `${apiBase()}/brain/list?${buildQuery({ type: "index", limit: 6 })}`
596
+ const res = await root.request(
597
+ `${root.apiBase()}/brain/list?${buildQuery({ type: "index", limit: 6 })}`
428
598
  );
429
599
  if (!res.ok) return;
430
600
  const data = (await res.json()) as {
@@ -444,7 +614,7 @@ export function DiscoveryStart() {
444
614
  return () => {
445
615
  cancelled = true;
446
616
  };
447
- }, []);
617
+ }, [root]);
448
618
 
449
619
  return (
450
620
  <>
@@ -129,39 +129,29 @@ export function nodeSize(
129
129
 
130
130
  // --- Palettes ----------------------------------------------------------------
131
131
  //
132
- // Both palettes ran through the dataviz validator against the app surface
133
- // (#0c0e12, dark): the categorical set passes lightness band, chroma floor,
134
- // CVD separation (worst adjacent ΔE 8.4), normal-vision floor and 3:1
135
- // contrast; the distance ramp passes monotone-lightness, step-gap, light-end
136
- // contrast and single-hue checks. Slot ORDER is the CVD-safety mechanism —
137
- // do not reorder without re-validating.
138
-
139
- /** Fixed categorical slots (validated, dark). Community/folder identity. */
140
- export const CATEGORICAL_SLOTS = [
141
- "#3987e5", // blue
142
- "#d95926", // orange
143
- "#199e70", // aqua
144
- "#c98500", // yellow
145
- "#d55181", // magenta
146
- "#008300", // green
147
- "#9085e9", // violet
148
- "#e66767", // red
149
- ] as const;
150
-
151
- /** Recessive slot for everything past the eight distinguishable ones. */
152
- export const OTHER_COLOR = "#565b66";
153
-
154
- /** The root's own color in discovery mode (the app's amber primary). */
155
- export const ROOT_COLOR = "#e09f3e";
156
-
157
- /** Ordinal distance ramp, near → far (validated, 5 visible steps). */
158
- export const DISTANCE_RAMP = [
159
- "#b7d3f6",
160
- "#86b6ef",
161
- "#5598e7",
162
- "#2a78d6",
163
- "#184f95",
164
- ] as const;
132
+ // The canvas draws with VALUES, not CSS, so its palette arrives resolved: the
133
+ // kit's `--bk-canvas-*` tokens read for the scheme the page is in (see
134
+ // `use-graph-theme.ts`). Both sets are the kit's — the dark one ran through
135
+ // the dataviz validator against #0c0e12 (lightness band, chroma floor, CVD
136
+ // separation, 3:1), the paper one is the design's, each mark at 3:1 against
137
+ // #ece7dc. Slot ORDER is the CVD-safety mechanism and is the same in both
138
+ // themes: a theme may respell a slot, never reorder one.
139
+
140
+ export interface CanvasPalette {
141
+ /** Eight categorical slots, in the frozen order. Community/folder identity. */
142
+ slots: readonly string[];
143
+ /** Ordinal distance ramp, near to far (five visible steps). */
144
+ ramp: readonly string[];
145
+ /** The root's own colour in discovery mode (the focus amber). */
146
+ root: string;
147
+ /** Recessive slot for everything past the eight distinguishable ones. */
148
+ other: string;
149
+ /** The maintenance lenses. */
150
+ lens: { orphan: string; unreachable: string; broken: string; stale: string };
151
+ }
152
+
153
+ /** How many communities or folders get a slot of their own before the tail folds. */
154
+ export const SLOT_COUNT = 8;
165
155
 
166
156
  /**
167
157
  * Linear blend of two hex colors: t=0 → a, t=1 → b. Used for the gentle
@@ -191,16 +181,14 @@ function parseHex(color: string): [number, number, number] | null {
191
181
  * index time, so the first eight — the ones a legend can carry — get the
192
182
  * distinguishable slots and the long tail shares one recessive color.
193
183
  */
194
- export function communityColor(community: number): string {
195
- return community < CATEGORICAL_SLOTS.length
196
- ? CATEGORICAL_SLOTS[community]!
197
- : OTHER_COLOR;
184
+ export function communityColor(community: number, palette: CanvasPalette): string {
185
+ return community < palette.slots.length ? palette.slots[community]! : palette.other;
198
186
  }
199
187
 
200
- /** Color for a BFS distance: amber root, then the blue ramp fading out. */
201
- export function distanceColor(distance: number): string {
202
- if (distance <= 0) return ROOT_COLOR;
203
- return DISTANCE_RAMP[Math.min(distance - 1, DISTANCE_RAMP.length - 1)]!;
188
+ /** Color for a BFS distance: the root, then the ramp fading out hop by hop. */
189
+ export function distanceColor(distance: number, palette: CanvasPalette): string {
190
+ if (distance <= 0) return palette.root;
191
+ return palette.ramp[Math.min(distance - 1, palette.ramp.length - 1)]!;
204
192
  }
205
193
 
206
194
  /** First path segment — "career/opportunities/x.md" → "career". */
@@ -213,7 +201,7 @@ export function topLevelDir(path: string): string {
213
201
  * Assign categorical slots to top-level directories, biggest first — the
214
202
  * same eight-then-other policy as communities. Returns dir → color.
215
203
  */
216
- export function assignFolderColors(paths: string[]): Map<string, string> {
204
+ export function assignFolderColors(paths: string[], palette: CanvasPalette): Map<string, string> {
217
205
  const counts = new Map<string, number>();
218
206
  for (const path of paths) {
219
207
  const dir = topLevelDir(path);
@@ -224,7 +212,7 @@ export function assignFolderColors(paths: string[]): Map<string, string> {
224
212
  );
225
213
  const colors = new Map<string, string>();
226
214
  ranked.forEach(([dir], i) => {
227
- colors.set(dir, i < CATEGORICAL_SLOTS.length ? CATEGORICAL_SLOTS[i]! : OTHER_COLOR);
215
+ colors.set(dir, i < palette.slots.length ? palette.slots[i]! : palette.other);
228
216
  });
229
217
  return colors;
230
218
  }
@@ -309,3 +297,37 @@ export function matchScene(
309
297
  }
310
298
  return matches;
311
299
  }
300
+
301
+ // --- Entity colouring ---------------------------------------------------------
302
+
303
+ /**
304
+ * The kit's entity mapping (its `GraphView`, `PathRef` and inline mentions):
305
+ * which document types wear which of the three entity colours. Every other
306
+ * type — note, journal, study, whatever the taxonomy names — takes the
307
+ * neutral ink and is listed in the legend under its own name, because a
308
+ * legend that hides a type is a legend that lies about a node.
309
+ */
310
+ export type EntityKind = "person" | "company" | "project";
311
+
312
+ export function entityKind(type: string): EntityKind | null {
313
+ return type === "person" || type === "company" || type === "project" ? type : null;
314
+ }
315
+
316
+ /** The scene's document types, entity kinds first in the kit's order, then
317
+ * the rest by count. Each carries how many nodes wear it. */
318
+ export function entityLegend(nodes: { type: string; virtual?: boolean }[]): { type: string; kind: EntityKind | null; count: number }[] {
319
+ const counts = new Map<string, number>();
320
+ for (const node of nodes) {
321
+ if (node.virtual) continue;
322
+ counts.set(node.type, (counts.get(node.type) ?? 0) + 1);
323
+ }
324
+ const order: string[] = ["person", "company", "project"];
325
+ return [...counts.entries()]
326
+ .map(([type, count]) => ({ type, kind: entityKind(type), count }))
327
+ .sort((a, b) => {
328
+ const ia = order.indexOf(a.type);
329
+ const ib = order.indexOf(b.type);
330
+ if (ia !== -1 || ib !== -1) return (ia === -1 ? order.length : ia) - (ib === -1 ? order.length : ib);
331
+ return b.count - a.count || a.type.localeCompare(b.type);
332
+ });
333
+ }
@@ -0,0 +1,64 @@
1
+ import { Button, Chip, PathRef, Surface } from "@schlessera/brain-ui-kit";
2
+
3
+ /**
4
+ * The selected node's card, rendered from props (S7). `NodePopover` is the
5
+ * container: it reads the graph, file and UI stores and decides which
6
+ * actions apply; this draws a kit `Surface` with the node's kind and topic
7
+ * as chips, its path as a `PathRef`, its degrees as machine meta, and the
8
+ * actions as kit `Button`s — "Open note" primary, the rest ghost.
9
+ */
10
+ export interface NodeCardProps {
11
+ kind: string;
12
+ title: string;
13
+ path: string;
14
+ topic?: string | null;
15
+ /** The topic cluster's swatch colour, from the canvas's own palette. */
16
+ topicColor?: string;
17
+ inDegree: number;
18
+ outDegree: number;
19
+ /** Hops from the centre; 0 or undefined draws nothing. */
20
+ distance?: number;
21
+ canOpen: boolean;
22
+ canFocus: boolean;
23
+ canExpand: boolean;
24
+ onOpen: () => void;
25
+ onFocus: () => void;
26
+ onExpand: () => void;
27
+ onClose: () => void;
28
+ }
29
+
30
+ export function NodeCard(p: NodeCardProps) {
31
+ const hops = p.distance !== undefined && p.distance > 0 ? `${p.distance} hop${p.distance === 1 ? "" : "s"}` : null;
32
+ return (
33
+ <div className="pointer-events-auto absolute inset-x-2 bottom-2 z-10 shadow-2xl md:inset-x-auto md:bottom-4 md:left-4 md:w-80">
34
+ <Surface emphasis="strong" pad={12}>
35
+ <div className="flex items-start justify-between gap-2">
36
+ <div className="flex min-w-0 flex-wrap items-center gap-1.5">
37
+ <Chip label={p.kind} variant="kv" tone="neutral" caps />
38
+ {p.topic && (
39
+ <span title="Topic cluster inferred from this note's links" className="flex min-w-0 items-center gap-1.5">
40
+ {p.topicColor && <span aria-hidden="true" className="h-1.5 w-1.5 shrink-0 rounded-full" style={{ backgroundColor: p.topicColor }} />}
41
+ <Chip label={`topic: ${p.topic}`} variant="kv" tone="purple" />
42
+ </span>
43
+ )}
44
+ </div>
45
+ <Button label="Close" icon="dismiss" tone="quiet" size="sm" block={false} onClick={p.onClose} />
46
+ </div>
47
+ <h3 className="mt-2 truncate text-sm font-medium text-foreground">{p.title}</h3>
48
+ <div className="mt-1 flex min-w-0">
49
+ <PathRef text={p.path} variant="inline" tone="teal" icon="file" />
50
+ </div>
51
+ <div className="mt-2 flex gap-4 font-[family-name:var(--font-mono)] text-[11px] text-muted-foreground">
52
+ <span>{p.inDegree} in</span>
53
+ <span>{p.outDegree} out</span>
54
+ {hops && <span>{hops}</span>}
55
+ </div>
56
+ <div className="mt-3 flex flex-wrap gap-2">
57
+ {p.canOpen && <Button label="Open note" icon="file" tone="primary" size="sm" block={false} onClick={p.onOpen} />}
58
+ {p.canFocus && <Button label="Focus here" icon="graph" tone="ghost" size="sm" block={false} onClick={p.onFocus} />}
59
+ {p.canExpand && <Button label="Expand" icon="expand" tone="ghost" size="sm" block={false} onClick={p.onExpand} />}
60
+ </div>
61
+ </Surface>
62
+ </div>
63
+ );
64
+ }