@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,9 +1,14 @@
1
1
  import { Suspense, lazy } from "react";
2
2
  import { KeyRound, Laptop, Puzzle, SlidersHorizontal } from "lucide-react";
3
3
  import { useUIStore, type SettingsTab } from "../../stores/ui-store.js";
4
- import { SlidePanel } from "../layout/slide-panel.js";
4
+ import { SlidePanel, type SlidePanelClosedBy } from "../layout/slide-panel.js";
5
5
  import { cn } from "../../lib/utils.js";
6
6
  import { usePrincipalStore } from "../../stores/principal-store.js";
7
+ import { useBrainUiRoot } from "../../root-context.js";
8
+ import { useMediaQuery } from "../../hooks/use-media-query.js";
9
+ import { ThemeToggle } from "../layout/theme.js";
10
+ import { ShortcutSwitch } from "../layout/shortcut-switch.js";
11
+ import { Button, Callout, Icon, Label, ScreenHeader, Surface, type IconName } from "@schlessera/brain-ui-kit";
7
12
 
8
13
  /**
9
14
  * Each tab is fetched the first time it is opened. Settings is the largest
@@ -17,7 +22,10 @@ const PasskeyTab = lazy(() => import("./passkey-tab.js").then((m) => ({ default:
17
22
  const DevicesAgentsTab = lazy(() => import("./devices-agents-tab.js").then((m) => ({ default: m.DevicesAgentsTab })));
18
23
  const SkillsTab = lazy(() => import("./skills-tab.js").then((m) => ({ default: m.SkillsTab })));
19
24
 
20
- const TABS: Array<{ id: SettingsTab; label: string; icon: typeof KeyRound }> = [
25
+ /** The phone strip's tabs. Appearance and input sit above the strip there. */
26
+ type StripTab = Exclude<SettingsTab, "appearance">;
27
+
28
+ const TABS: Array<{ id: StripTab; label: string; icon: typeof KeyRound }> = [
21
29
  { id: "models", label: "Models", icon: SlidersHorizontal },
22
30
  { id: "skills", label: "Skills", icon: Puzzle },
23
31
  { id: "security", label: "Security", icon: KeyRound },
@@ -25,9 +33,32 @@ const TABS: Array<{ id: SettingsTab; label: string; icon: typeof KeyRound }> = [
25
33
  ];
26
34
 
27
35
  /**
28
- * The settings surface: one panel, one entry point in the menus, a tab per
29
- * area. Only the selected tab is mounted each fetches its own data on becoming
30
- * active, so switching tabs (or reopening the panel) always shows current state.
36
+ * D5's section column, from `laptop:` up. The mono meta names what the
37
+ * section holds; it is not a count, because the column has no data of its
38
+ * own to count.
39
+ */
40
+ const SECTIONS: Array<{ id: SettingsTab; label: string; meta: string; icon: IconName }> = [
41
+ { id: "appearance", label: "Appearance & input", meta: "this device", icon: "settings" },
42
+ { id: "models", label: "Models", meta: "providers", icon: "model" },
43
+ { id: "skills", label: "Skills", meta: "catalog", icon: "capability" },
44
+ { id: "security", label: "Security", meta: "passkeys", icon: "passkey" },
45
+ { id: "devices", label: "Devices & agents", meta: "credentials", icon: "agent" },
46
+ ];
47
+
48
+ /** The rail is expanded from here (`laptop:`), and Settings becomes a pane. */
49
+ const PANE_QUERY = "(min-width: 900px)";
50
+
51
+ /**
52
+ * The settings surface: one panel, one entry point in the menus, a section
53
+ * per area. Only the selected section is mounted — each fetches its own data
54
+ * on becoming active, so switching (or reopening the panel) always shows
55
+ * current state.
56
+ *
57
+ * Two shapes. Below `laptop:` the drawer with its tab strip, unchanged: the
58
+ * theme toggle and the single-key switch sit above the tabs. From `laptop:`
59
+ * up it is D5's pane over the content area: a header row, a 216px section
60
+ * column, and the section's form at a 720px measure. There, Appearance &
61
+ * input is a section of its own.
31
62
  */
32
63
  export function SettingsPanel({
33
64
  open,
@@ -41,51 +72,234 @@ export function SettingsPanel({
41
72
  const mintPending = usePrincipalStore((s) => s.mintPending);
42
73
  const oneTimeCredential = usePrincipalStore((s) => s.oneTimeCredential);
43
74
  const credentialProtected = mintPending || oneTimeCredential !== null;
75
+ const pane = useMediaQuery(PANE_QUERY);
76
+ // While a mint is in flight or its one-time value is unacknowledged, the
77
+ // panel does not light-dismiss: a stray click or Escape must not hide the
78
+ // surface the credential is about to land on. Its close control stays live.
79
+ const closedBy = credentialProtected ? "none" : "any";
44
80
 
45
- function closeIfSafe() {
46
- if (!credentialProtected) onClose();
81
+ function select(id: SettingsTab) {
82
+ if (!credentialProtected) setTab(id);
47
83
  }
48
84
 
85
+ if (pane) {
86
+ return (
87
+ <SettingsPane
88
+ open={open}
89
+ tab={tab}
90
+ credentialProtected={credentialProtected}
91
+ closedBy={closedBy}
92
+ onSelect={select}
93
+ onClose={onClose}
94
+ />
95
+ );
96
+ }
97
+
98
+ // The strip has no Appearance tab: a pane selection that survives a resize
99
+ // down lands on the first tab, and the controls it named are right above.
100
+ const stripTab: StripTab = tab === "appearance" ? "models" : tab;
101
+
49
102
  return (
50
- <SlidePanel open={open} onClose={closeIfSafe} title="Settings" wide>
103
+ <SlidePanel open={open} onClose={onClose} title="Settings" wide closedBy={closedBy}>
51
104
  <div className="flex h-full flex-col">
52
105
  <div className="flex shrink-0 gap-1 border-b border-border px-2 pt-2">
53
- {TABS.map(({ id, label, icon: Icon }) => (
106
+ {TABS.map(({ id, label, icon: TabIcon }) => (
54
107
  <button
55
108
  key={id}
56
- onClick={() => {
57
- if (!credentialProtected) setTab(id);
58
- }}
59
- disabled={credentialProtected && tab !== id}
60
- aria-selected={tab === id}
109
+ onClick={() => select(id)}
110
+ disabled={credentialProtected && stripTab !== id}
111
+ aria-selected={stripTab === id}
61
112
  role="tab"
62
113
  className={cn(
63
114
  "flex items-center gap-1.5 rounded-t-lg px-3 py-2 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
64
- tab === id
115
+ stripTab === id
65
116
  ? "border-b-2 border-primary text-foreground"
66
117
  : "text-muted-foreground hover:text-foreground"
67
118
  )}
68
119
  >
69
- <Icon className="h-3.5 w-3.5" />
120
+ <TabIcon className="h-3.5 w-3.5" />
70
121
  {label}
71
122
  </button>
72
123
  ))}
73
124
  </div>
74
125
 
126
+ {/* Appearance is not a tab: it is one control, it applies everywhere,
127
+ and the design puts the three-way toggle in Settings without
128
+ giving it a section of its own. */}
129
+ <div className="flex shrink-0 items-center justify-between gap-3 border-b border-border px-3 py-2">
130
+ <span className="text-xs text-muted-foreground">Appearance</span>
131
+ <ThemeToggle />
132
+ </div>
133
+ {/* Settings › Input (D37, as D5 draws it): the off switch for
134
+ single-key shortcuts as a group row, with the banner that says what
135
+ turning it off does. One control, applies everywhere, so it sits
136
+ beside Appearance rather than in a tab. */}
137
+ <div className="flex shrink-0 flex-col gap-2 border-b border-border px-3 py-2">
138
+ <Label text="Input" icon="capability" />
139
+ <Surface pad={0}>
140
+ <ShortcutSwitch />
141
+ </Surface>
142
+ <ShortcutBanner />
143
+ </div>
144
+
75
145
  <div className="min-h-0 flex-1">
76
- <Suspense fallback={null}>
77
- {tab === "models" ? (
78
- <ModelsTab active={open && tab === "models"} />
79
- ) : tab === "skills" ? (
80
- <SkillsTab active={open && tab === "skills"} />
81
- ) : tab === "security" ? (
82
- <PasskeyTab active={open && tab === "security"} />
146
+ <SectionBody tab={stripTab} open={open} />
147
+ </div>
148
+ </div>
149
+ </SlidePanel>
150
+ );
151
+ }
152
+
153
+ /**
154
+ * D5 from `laptop:` up: the pane. The header row carries the serif title and
155
+ * the close control; under it the section column and the form area share the
156
+ * height, and only the form area scrolls.
157
+ */
158
+ function SettingsPane({
159
+ open,
160
+ tab,
161
+ credentialProtected,
162
+ closedBy,
163
+ onSelect,
164
+ onClose,
165
+ }: {
166
+ open: boolean;
167
+ tab: SettingsTab;
168
+ credentialProtected: boolean;
169
+ closedBy: SlidePanelClosedBy;
170
+ onSelect: (tab: SettingsTab) => void;
171
+ onClose: () => void;
172
+ }) {
173
+ const appName = useBrainUiRoot().config.appName;
174
+ return (
175
+ <SlidePanel open={open} onClose={onClose} title="Settings" mode="pane" closedBy={closedBy}>
176
+ {/* The kit header is `width: 100%`; it needs a shrinking flex child
177
+ around it, or it fills the row and pushes Close past the viewport
178
+ (the Files pane wraps its header the same way). */}
179
+ <div className="flex shrink-0 items-center border-b border-border pr-3">
180
+ <div className="min-w-0 flex-1">
181
+ <ScreenHeader variant="nav" title="Settings" back={false} divider={false} />
182
+ </div>
183
+ <div className="shrink-0">
184
+ <Button label="Close" icon="dismiss" tone="quiet" size="sm" block={false} onClick={onClose} />
185
+ </div>
186
+ </div>
187
+
188
+ <div className="flex min-h-0 flex-1">
189
+ <nav aria-label="Settings sections" className="flex w-[216px] shrink-0 flex-col border-r border-border">
190
+ <div role="tablist" aria-orientation="vertical" className="flex flex-1 flex-col gap-0.5 p-2">
191
+ {SECTIONS.map(({ id, label, meta, icon }) => {
192
+ const selected = tab === id;
193
+ return (
194
+ <button
195
+ key={id}
196
+ type="button"
197
+ role="tab"
198
+ aria-selected={selected}
199
+ // The name is the label alone: the mono meta beside it is a
200
+ // descriptor, and a test or a screen reader asking for
201
+ // "Security" should find it.
202
+ aria-label={label}
203
+ disabled={credentialProtected && !selected}
204
+ onClick={() => onSelect(id)}
205
+ className={cn(
206
+ "flex w-full items-center gap-2.5 rounded-lg px-2.5 py-2 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-50",
207
+ selected ? "bg-surface-raised" : "hover:bg-surface-raised"
208
+ )}
209
+ >
210
+ <Icon icon={icon} size={16} color={selected ? "var(--bk-amber-ink)" : "var(--bk-color-ink-mute)"} />
211
+ <span
212
+ className={cn("min-w-0 flex-1 truncate text-[12.5px] font-semibold", !selected && "text-foreground")}
213
+ style={selected ? { color: "var(--bk-amber-ink)" } : undefined}
214
+ >
215
+ {label}
216
+ </span>
217
+ <span className="shrink-0 font-[family-name:var(--font-mono)] text-[10px] text-muted-foreground">
218
+ {meta}
219
+ </span>
220
+ </button>
221
+ );
222
+ })}
223
+ </div>
224
+ <div className="shrink-0 border-t border-border px-4 py-3 font-[family-name:var(--font-mono)] text-[10px] text-muted-foreground">
225
+ {appName}
226
+ </div>
227
+ </nav>
228
+
229
+ <div className="min-h-0 flex-1 overflow-y-auto">
230
+ <div className="flex h-full max-w-[720px] flex-col">
231
+ {tab === "appearance" ? (
232
+ <AppearanceSection />
83
233
  ) : (
84
- <DevicesAgentsTab active={open && tab === "devices"} />
234
+ <SectionBody tab={tab} open={open} />
85
235
  )}
86
- </Suspense>
236
+ </div>
87
237
  </div>
88
238
  </div>
89
239
  </SlidePanel>
90
240
  );
91
241
  }
242
+
243
+ /**
244
+ * D5's first section, as the drop draws it: the theme under "Appearance",
245
+ * the single-key switch and its banner under "Input". Both controls apply to
246
+ * this device only, which the header says.
247
+ */
248
+ function AppearanceSection() {
249
+ return (
250
+ <div className="flex flex-col">
251
+ <ScreenHeader
252
+ variant="nav"
253
+ title="Appearance & input"
254
+ subtitle="applies on this device only"
255
+ back={false}
256
+ divider={false}
257
+ />
258
+ <div className="flex flex-col gap-2 px-4 pb-4">
259
+ <Label text="Appearance" icon="settings" />
260
+ <Surface pad={0}>
261
+ <div className="flex items-center gap-3 px-3 py-3">
262
+ <Icon icon="settings" size={17} color="var(--bk-color-ink-mute)" />
263
+ <span className="min-w-0 flex-1 text-[12.5px] font-semibold text-foreground">Theme</span>
264
+ <ThemeToggle />
265
+ </div>
266
+ </Surface>
267
+ </div>
268
+ <div className="flex flex-col gap-2 px-4 pb-4">
269
+ <Label text="Input" icon="capability" />
270
+ <Surface pad={0}>
271
+ <ShortcutSwitch />
272
+ </Surface>
273
+ <ShortcutBanner />
274
+ </div>
275
+ </div>
276
+ );
277
+ }
278
+
279
+ function ShortcutBanner() {
280
+ return (
281
+ <Callout
282
+ variant="banner"
283
+ tone="neutral"
284
+ icon="scope"
285
+ text="Turning single-key shortcuts off also removes the printed keys from buttons — a key that no longer fires should not be advertised."
286
+ />
287
+ );
288
+ }
289
+
290
+ /** The lazily fetched section, mounted only while it is the selected one. */
291
+ function SectionBody({ tab, open }: { tab: StripTab; open: boolean }) {
292
+ return (
293
+ <Suspense fallback={null}>
294
+ {tab === "models" ? (
295
+ <ModelsTab active={open} />
296
+ ) : tab === "skills" ? (
297
+ <SkillsTab active={open} />
298
+ ) : tab === "security" ? (
299
+ <PasskeyTab active={open} />
300
+ ) : (
301
+ <DevicesAgentsTab active={open} />
302
+ )}
303
+ </Suspense>
304
+ );
305
+ }
@@ -0,0 +1,276 @@
1
+ import { Button, Placeholder } from "@schlessera/brain-ui-kit";
2
+ import { Loader2, Pencil, Power, Trash2, Upload } from "lucide-react";
3
+ import type { SkillEntry, SkillInstallOutcome } from "../../lib/api-client.js";
4
+ import { cn } from "../../lib/utils.js";
5
+
6
+ /**
7
+ * Settings → Skills, rendered from props (S6). `SkillsTab` is the container:
8
+ * it owns the list request, the `active`-gated reload, every mutation and its
9
+ * generation guard, and the editor's fetch; these two views own what is on
10
+ * screen. `SkillsList` is the list with its create and install rows;
11
+ * `SkillEditor` is the one-file editor that replaces it while a skill is open.
12
+ *
13
+ * Text fields stay native (the kit has no text input); the create, install,
14
+ * save and close buttons are the kit's `Button`. The per-row edit / enable /
15
+ * delete controls stay native icon buttons: they are titled, and the kit has
16
+ * no icon-only button. The zip picker is a native file input behind a label.
17
+ *
18
+ * `busy` names the skill whose mutation is in flight, or `"*"` for none in
19
+ * particular — the container passes the skill name it is working on, and
20
+ * every row control is inert while any is running, as before.
21
+ */
22
+ export interface SkillsListProps {
23
+ skills: SkillEntry[];
24
+ /** The skill a mutation is running for, or null. */
25
+ busy: string | null;
26
+ installing: boolean;
27
+ error: string | null;
28
+ warning: string | null;
29
+ outcomes: SkillInstallOutcome[] | null;
30
+ newName: string;
31
+ githubSource: string;
32
+ overwrite: boolean;
33
+ onNewName: (value: string) => void;
34
+ onCreate: () => void;
35
+ onGithubSource: (value: string) => void;
36
+ onOverwrite: (value: boolean) => void;
37
+ onInstallZip: (file: File) => void;
38
+ onInstallGitHub: () => void;
39
+ onOpen: (skill: SkillEntry) => void;
40
+ onToggle: (skill: SkillEntry) => void;
41
+ onRemove: (skill: SkillEntry) => void;
42
+ }
43
+
44
+ export function SkillsList(p: SkillsListProps) {
45
+ const custom = p.skills.filter((s) => s.source === "custom");
46
+ const builtin = p.skills.filter((s) => s.source === "builtin");
47
+ const locked = p.busy !== null;
48
+ const canInstall = !p.installing && p.githubSource.trim().length > 0;
49
+
50
+ return (
51
+ <div className="h-full overflow-y-auto p-4">
52
+ <h3 className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
53
+ Your skills
54
+ </h3>
55
+ <p className="mt-1 text-xs text-muted-foreground">
56
+ Custom skills live in your brain repo (<code>.agents/skills/</code>) — they
57
+ survive redeployments, ride the repo's backups, and apply to every
58
+ backend. For guided authoring, ask the agent in chat to{" "}
59
+ <span className="font-medium text-foreground">add a skill</span> — the
60
+ built-in <code>add-skill</code> skill walks through design and setup.
61
+ </p>
62
+
63
+ <div className="mt-4 flex items-center gap-2">
64
+ <input
65
+ value={p.newName}
66
+ onChange={(e) => p.onNewName(e.target.value.toLowerCase())}
67
+ onKeyDown={(e) => {
68
+ if (e.key === "Enter" && p.newName.trim()) p.onCreate();
69
+ }}
70
+ placeholder="new-skill-name (kebab-case)"
71
+ className="min-w-0 flex-1 rounded-md border border-border-subtle bg-background px-2 py-1.5 text-sm text-foreground placeholder:text-muted-foreground focus:border-primary focus:outline-none"
72
+ />
73
+ <Button label="Create" icon="add" tone="primary" size="sm" block={false} disabled={!p.newName.trim()} onClick={p.onCreate} />
74
+ </div>
75
+
76
+ <div className="mt-3 rounded-lg border border-border-subtle bg-surface p-3">
77
+ <p className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
78
+ Install
79
+ </p>
80
+ <div className="mt-2 flex items-center gap-2">
81
+ <label
82
+ className={cn(
83
+ "flex cursor-pointer items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-foreground transition-colors hover:border-primary hover:text-primary",
84
+ p.installing && "pointer-events-none opacity-50",
85
+ )}
86
+ >
87
+ <Upload className="h-3 w-3" />
88
+ Upload .zip
89
+ <input
90
+ type="file"
91
+ accept=".zip,application/zip"
92
+ className="hidden"
93
+ onChange={(e) => {
94
+ const file = e.target.files?.[0];
95
+ e.target.value = "";
96
+ if (file) p.onInstallZip(file);
97
+ }}
98
+ />
99
+ </label>
100
+ <label className="flex items-center gap-1.5 text-[11px] text-muted-foreground">
101
+ <input type="checkbox" checked={p.overwrite} onChange={(e) => p.onOverwrite(e.target.checked)} />
102
+ overwrite existing
103
+ </label>
104
+ </div>
105
+ <div className="mt-2 flex items-center gap-2">
106
+ <input
107
+ value={p.githubSource}
108
+ onChange={(e) => p.onGithubSource(e.target.value)}
109
+ onKeyDown={(e) => {
110
+ if (e.key === "Enter" && canInstall) p.onInstallGitHub();
111
+ }}
112
+ placeholder="GitHub: owner/repo or https://github.com/…/tree/main/skills"
113
+ className="min-w-0 flex-1 rounded-md border border-border-subtle bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-muted-foreground focus:border-primary focus:outline-none"
114
+ />
115
+ {p.installing ? <Loader2 className="h-3 w-3 animate-spin text-muted-foreground" aria-hidden /> : null}
116
+ <Button label="Install" icon="install" tone="ghost" size="sm" block={false} disabled={!canInstall} onClick={p.onInstallGitHub} />
117
+ </div>
118
+ <p className="mt-1.5 text-[11px] text-muted-foreground">
119
+ A skill is any folder with a SKILL.md; one source may carry several.
120
+ Private repos use the server's GITHUB_TOKEN.
121
+ </p>
122
+ {p.outcomes && (
123
+ <ul className="mt-2 flex flex-col gap-1">
124
+ {p.outcomes.map((o, i) => (
125
+ <li key={`${o.name}-${i}`} className="text-[11px]">
126
+ {o.status === "skipped" ? (
127
+ <span className="text-muted-foreground">
128
+ ✗ {o.name} — {o.reason}
129
+ </span>
130
+ ) : (
131
+ <span className="text-primary">
132
+ ✓ {o.name} {o.status === "replaced" ? "replaced" : "installed"}
133
+ {typeof o.files === "number" ? ` (${o.files} file${o.files === 1 ? "" : "s"})` : ""}
134
+ </span>
135
+ )}
136
+ </li>
137
+ ))}
138
+ </ul>
139
+ )}
140
+ </div>
141
+
142
+ {p.error && <p className="mt-2 text-xs text-destructive">{p.error}</p>}
143
+ {p.warning && <p className="mt-2 text-xs text-muted-foreground">{p.warning}</p>}
144
+
145
+ <ul className="mt-4 flex flex-col gap-2">
146
+ {custom.length === 0 && (
147
+ <li>
148
+ <Placeholder variant="empty" message="No custom skills yet." icon="steps" pad={10} />
149
+ </li>
150
+ )}
151
+ {custom.map((skill) => (
152
+ <li key={skill.name} className="rounded-lg border border-border-subtle bg-surface p-3">
153
+ {/* A disabled skill is not faded (design-feedback §4): its state
154
+ word says so, at full contrast. */}
155
+ <div className="flex items-center gap-2">
156
+ <div className="min-w-0 flex-1">
157
+ <p className="truncate text-sm text-foreground">
158
+ {skill.name}
159
+ {!skill.enabled && (
160
+ <span className="ml-2 text-[11px] text-muted-foreground">disabled</span>
161
+ )}
162
+ </p>
163
+ <p className="truncate text-[11px] text-muted-foreground">
164
+ {skill.warning ? `⚠ ${skill.warning}` : skill.description}
165
+ </p>
166
+ </div>
167
+ <button
168
+ type="button"
169
+ onClick={() => p.onOpen(skill)}
170
+ disabled={locked}
171
+ title="Edit SKILL.md"
172
+ className="rounded-md border border-border-subtle p-1.5 text-muted-foreground transition-colors hover:border-primary hover:text-primary disabled:opacity-50"
173
+ >
174
+ <Pencil className="h-3.5 w-3.5" />
175
+ </button>
176
+ <button
177
+ type="button"
178
+ onClick={() => p.onToggle(skill)}
179
+ disabled={locked}
180
+ title={skill.enabled ? "Disable (all backends)" : "Enable"}
181
+ className={cn(
182
+ "rounded-md border border-border-subtle p-1.5 transition-colors disabled:opacity-50",
183
+ skill.enabled
184
+ ? "text-primary hover:border-primary"
185
+ : "text-muted-foreground hover:border-primary hover:text-primary",
186
+ )}
187
+ >
188
+ {p.busy === skill.name ? (
189
+ <Loader2 className="h-3.5 w-3.5 animate-spin" />
190
+ ) : (
191
+ <Power className="h-3.5 w-3.5" />
192
+ )}
193
+ </button>
194
+ <button
195
+ type="button"
196
+ onClick={() => p.onRemove(skill)}
197
+ disabled={locked}
198
+ title="Delete permanently"
199
+ className="rounded-md border border-border-subtle p-1.5 text-muted-foreground transition-colors hover:border-destructive hover:text-destructive disabled:opacity-50"
200
+ >
201
+ <Trash2 className="h-3.5 w-3.5" />
202
+ </button>
203
+ </div>
204
+ </li>
205
+ ))}
206
+ </ul>
207
+
208
+ <h3 className="mt-6 text-xs font-medium uppercase tracking-wide text-muted-foreground">
209
+ Built-in skills
210
+ </h3>
211
+ <p className="mt-1 text-xs text-muted-foreground">
212
+ Shipped by brain-kit and its modules; managed by <code>brain skills sync</code>.
213
+ A custom skill with the same name overrides a built-in.
214
+ </p>
215
+ <ul className="mt-3 flex flex-col gap-1.5">
216
+ {builtin.map((skill) => (
217
+ <li
218
+ key={skill.name}
219
+ className="flex items-center gap-2 rounded-lg border border-border-subtle bg-surface px-3 py-2"
220
+ >
221
+ <div className="min-w-0 flex-1">
222
+ <p className="truncate text-xs text-foreground">{skill.name}</p>
223
+ <p className="truncate text-[11px] text-muted-foreground">{skill.description}</p>
224
+ </div>
225
+ <span title="View SKILL.md" className="flex shrink-0">
226
+ <Button label="View" tone="quiet" size="sm" block={false} disabled={locked} onClick={() => p.onOpen(skill)} />
227
+ </span>
228
+ </li>
229
+ ))}
230
+ </ul>
231
+ </div>
232
+ );
233
+ }
234
+
235
+ export interface SkillEditorProps {
236
+ name: string;
237
+ content: string;
238
+ isNew: boolean;
239
+ readOnly: boolean;
240
+ /** A save is in flight. */
241
+ saving: boolean;
242
+ error: string | null;
243
+ onChange: (content: string) => void;
244
+ onSave: () => void;
245
+ onClose: () => void;
246
+ }
247
+
248
+ export function SkillEditor(p: SkillEditorProps) {
249
+ return (
250
+ <div className="flex h-full flex-col p-4">
251
+ <div className="flex items-center justify-between gap-2">
252
+ <h3 className="text-sm font-medium text-foreground">
253
+ {p.isNew ? "New skill" : p.name}
254
+ {p.readOnly && (
255
+ <span className="ml-2 text-[11px] text-muted-foreground">built-in · read-only</span>
256
+ )}
257
+ </h3>
258
+ <div className="flex gap-2">
259
+ {!p.readOnly && (
260
+ <Button label={p.saving ? "Saving…" : "Save"} icon="confirm" tone="primary" size="sm" block={false} disabled={p.saving} onClick={p.onSave} />
261
+ )}
262
+ <Button label="Close" icon="dismiss" tone="quiet" size="sm" block={false} onClick={p.onClose} />
263
+ </div>
264
+ </div>
265
+ {p.error && <p className="mt-2 text-xs text-destructive">{p.error}</p>}
266
+ <textarea
267
+ value={p.content}
268
+ readOnly={p.readOnly}
269
+ aria-label="SKILL.md"
270
+ onChange={(e) => p.onChange(e.target.value)}
271
+ spellCheck={false}
272
+ className="mt-3 min-h-0 flex-1 resize-none rounded-lg border border-border-subtle bg-background p-3 font-mono text-xs text-foreground focus:border-primary focus:outline-none"
273
+ />
274
+ </div>
275
+ );
276
+ }