@schlessera/brain-ui-react 0.34.1 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -4
- package/dist/components/activity/activity-page.d.ts +17 -5
- package/dist/components/activity/activity-page.d.ts.map +1 -1
- package/dist/components/activity/activity-page.js +144 -50
- package/dist/components/activity/activity-page.js.map +1 -1
- package/dist/components/activity/activity-run-detail.d.ts +16 -1
- package/dist/components/activity/activity-run-detail.d.ts.map +1 -1
- package/dist/components/activity/activity-run-detail.js +47 -4
- package/dist/components/activity/activity-run-detail.js.map +1 -1
- package/dist/components/activity/activity-run-list.d.ts +7 -1
- package/dist/components/activity/activity-run-list.d.ts.map +1 -1
- package/dist/components/activity/activity-run-list.js +16 -8
- package/dist/components/activity/activity-run-list.js.map +1 -1
- package/dist/components/activity/activity-views.d.ts +63 -0
- package/dist/components/activity/activity-views.d.ts.map +1 -0
- package/dist/components/activity/activity-views.js +52 -0
- package/dist/components/activity/activity-views.js.map +1 -0
- package/dist/components/activity/approval-card.d.ts +11 -0
- package/dist/components/activity/approval-card.d.ts.map +1 -0
- package/dist/components/activity/approval-card.js +46 -0
- package/dist/components/activity/approval-card.js.map +1 -0
- package/dist/components/activity/digest-card.d.ts +3 -0
- package/dist/components/activity/digest-card.d.ts.map +1 -1
- package/dist/components/activity/digest-card.js +20 -16
- package/dist/components/activity/digest-card.js.map +1 -1
- package/dist/components/activity/digest-summary.d.ts +19 -0
- package/dist/components/activity/digest-summary.d.ts.map +1 -0
- package/dist/components/activity/digest-summary.js +20 -0
- package/dist/components/activity/digest-summary.js.map +1 -0
- package/dist/components/activity/push-switch.d.ts +25 -0
- package/dist/components/activity/push-switch.d.ts.map +1 -0
- package/dist/components/activity/push-switch.js +14 -0
- package/dist/components/activity/push-switch.js.map +1 -0
- package/dist/components/activity/push-toggle.d.ts +7 -0
- package/dist/components/activity/push-toggle.d.ts.map +1 -1
- package/dist/components/activity/push-toggle.js +72 -47
- package/dist/components/activity/push-toggle.js.map +1 -1
- package/dist/components/activity/span-bits.d.ts.map +1 -1
- package/dist/components/activity/span-bits.js +9 -7
- package/dist/components/activity/span-bits.js.map +1 -1
- package/dist/components/chat/ask-user-card.d.ts +76 -3
- package/dist/components/chat/ask-user-card.d.ts.map +1 -1
- package/dist/components/chat/ask-user-card.js +208 -149
- package/dist/components/chat/ask-user-card.js.map +1 -1
- package/dist/components/chat/ask-user-typed.d.ts +42 -0
- package/dist/components/chat/ask-user-typed.d.ts.map +1 -0
- package/dist/components/chat/ask-user-typed.js +60 -0
- package/dist/components/chat/ask-user-typed.js.map +1 -0
- package/dist/components/chat/brain-markdown-links.d.ts +2 -1
- package/dist/components/chat/brain-markdown-links.d.ts.map +1 -1
- package/dist/components/chat/brain-markdown-links.js +3 -4
- package/dist/components/chat/brain-markdown-links.js.map +1 -1
- package/dist/components/chat/brain-markdown.d.ts.map +1 -1
- package/dist/components/chat/brain-markdown.js +4 -2
- package/dist/components/chat/brain-markdown.js.map +1 -1
- package/dist/components/chat/chat-page.d.ts.map +1 -1
- package/dist/components/chat/chat-page.js +24 -9
- package/dist/components/chat/chat-page.js.map +1 -1
- package/dist/components/chat/composer-view.d.ts +75 -0
- package/dist/components/chat/composer-view.d.ts.map +1 -0
- package/dist/components/chat/composer-view.js +31 -0
- package/dist/components/chat/composer-view.js.map +1 -0
- package/dist/components/chat/composer.d.ts +4 -0
- package/dist/components/chat/composer.d.ts.map +1 -1
- package/dist/components/chat/composer.js +76 -59
- package/dist/components/chat/composer.js.map +1 -1
- package/dist/components/chat/markdown-content.d.ts +16 -1
- package/dist/components/chat/markdown-content.d.ts.map +1 -1
- package/dist/components/chat/markdown-content.js +47 -3
- package/dist/components/chat/markdown-content.js.map +1 -1
- package/dist/components/chat/mermaid-block.d.ts +4 -0
- package/dist/components/chat/mermaid-block.d.ts.map +1 -1
- package/dist/components/chat/mermaid-block.js +13 -5
- package/dist/components/chat/mermaid-block.js.map +1 -1
- package/dist/components/chat/mermaid-share.d.ts +2 -1
- package/dist/components/chat/mermaid-share.d.ts.map +1 -1
- package/dist/components/chat/mermaid-share.js +7 -8
- package/dist/components/chat/mermaid-share.js.map +1 -1
- package/dist/components/chat/mermaid-viewer.d.ts.map +1 -1
- package/dist/components/chat/mermaid-viewer.js +3 -1
- package/dist/components/chat/mermaid-viewer.js.map +1 -1
- package/dist/components/chat/message-bubble.d.ts +8 -1
- package/dist/components/chat/message-bubble.d.ts.map +1 -1
- package/dist/components/chat/message-bubble.js +53 -24
- package/dist/components/chat/message-bubble.js.map +1 -1
- package/dist/components/chat/message-share.d.ts +2 -1
- package/dist/components/chat/message-share.d.ts.map +1 -1
- package/dist/components/chat/message-share.js +6 -7
- package/dist/components/chat/message-share.js.map +1 -1
- package/dist/components/chat/renderers/bind.d.ts +39 -0
- package/dist/components/chat/renderers/bind.d.ts.map +1 -0
- package/dist/components/chat/renderers/bind.js +43 -0
- package/dist/components/chat/renderers/bind.js.map +1 -0
- package/dist/components/chat/renderers/brain-ui-tools.d.ts +3 -0
- package/dist/components/chat/renderers/brain-ui-tools.d.ts.map +1 -0
- package/dist/components/chat/renderers/brain-ui-tools.js +41 -0
- package/dist/components/chat/renderers/brain-ui-tools.js.map +1 -0
- package/dist/components/chat/renderers/claude-tools.d.ts.map +1 -1
- package/dist/components/chat/renderers/claude-tools.js +3 -2
- package/dist/components/chat/renderers/claude-tools.js.map +1 -1
- package/dist/components/chat/renderers/index.d.ts +10 -2
- package/dist/components/chat/renderers/index.d.ts.map +1 -1
- package/dist/components/chat/renderers/index.js +15 -10
- package/dist/components/chat/renderers/index.js.map +1 -1
- package/dist/components/chat/session-drawer.d.ts +4 -0
- package/dist/components/chat/session-drawer.d.ts.map +1 -1
- package/dist/components/chat/session-drawer.js +55 -40
- package/dist/components/chat/session-drawer.js.map +1 -1
- package/dist/components/chat/session-list.d.ts +41 -0
- package/dist/components/chat/session-list.d.ts.map +1 -0
- package/dist/components/chat/session-list.js +10 -0
- package/dist/components/chat/session-list.js.map +1 -0
- package/dist/components/chat/share-block.d.ts.map +1 -1
- package/dist/components/chat/share-block.js +12 -11
- package/dist/components/chat/share-block.js.map +1 -1
- package/dist/components/chat/share-card.js +2 -2
- package/dist/components/chat/share-card.js.map +1 -1
- package/dist/components/chat/subagent-view.js +1 -1
- package/dist/components/chat/subagent-view.js.map +1 -1
- package/dist/components/chat/tool-call-timeline.d.ts.map +1 -1
- package/dist/components/chat/tool-call-timeline.js +37 -12
- package/dist/components/chat/tool-call-timeline.js.map +1 -1
- package/dist/components/chat/tool-cards/block-card.d.ts +28 -0
- package/dist/components/chat/tool-cards/block-card.d.ts.map +1 -0
- package/dist/components/chat/tool-cards/block-card.js +103 -0
- package/dist/components/chat/tool-cards/block-card.js.map +1 -0
- package/dist/components/chat/tool-cards/image-mask-card.d.ts +70 -0
- package/dist/components/chat/tool-cards/image-mask-card.d.ts.map +1 -0
- package/dist/components/chat/tool-cards/image-mask-card.js +142 -0
- package/dist/components/chat/tool-cards/image-mask-card.js.map +1 -0
- package/dist/components/chat/tool-cards/location-card.d.ts +45 -0
- package/dist/components/chat/tool-cards/location-card.d.ts.map +1 -0
- package/dist/components/chat/tool-cards/location-card.js +128 -0
- package/dist/components/chat/tool-cards/location-card.js.map +1 -0
- package/dist/components/chat/tool-views.d.ts +15 -4
- package/dist/components/chat/tool-views.d.ts.map +1 -1
- package/dist/components/chat/tool-views.js +22 -38
- package/dist/components/chat/tool-views.js.map +1 -1
- package/dist/components/chat/transcript-turn.d.ts +45 -0
- package/dist/components/chat/transcript-turn.d.ts.map +1 -0
- package/dist/components/chat/transcript-turn.js +25 -0
- package/dist/components/chat/transcript-turn.js.map +1 -0
- package/dist/components/chat/use-chat-commands.d.ts.map +1 -1
- package/dist/components/chat/use-chat-commands.js +13 -16
- package/dist/components/chat/use-chat-commands.js.map +1 -1
- package/dist/components/chat/welcome-state.d.ts +7 -0
- package/dist/components/chat/welcome-state.d.ts.map +1 -1
- package/dist/components/chat/welcome-state.js +13 -5
- package/dist/components/chat/welcome-state.js.map +1 -1
- package/dist/components/connectivity/connection-gate.d.ts.map +1 -1
- package/dist/components/connectivity/connection-gate.js +64 -6
- package/dist/components/connectivity/connection-gate.js.map +1 -1
- package/dist/components/connectivity/login-form.d.ts +31 -0
- package/dist/components/connectivity/login-form.d.ts.map +1 -0
- package/dist/components/connectivity/login-form.js +19 -0
- package/dist/components/connectivity/login-form.js.map +1 -0
- package/dist/components/connectivity/login-screen.d.ts +5 -2
- package/dist/components/connectivity/login-screen.d.ts.map +1 -1
- package/dist/components/connectivity/login-screen.js +41 -31
- package/dist/components/connectivity/login-screen.js.map +1 -1
- package/dist/components/dev/share-harness.js +1 -1
- package/dist/components/dev/share-harness.js.map +1 -1
- package/dist/components/files/file-panel.d.ts +1 -1
- package/dist/components/files/file-panel.d.ts.map +1 -1
- package/dist/components/files/file-panel.js +74 -0
- package/dist/components/files/file-panel.js.map +1 -1
- package/dist/components/files/file-tree-view.d.ts +45 -0
- package/dist/components/files/file-tree-view.d.ts.map +1 -0
- package/dist/components/files/file-tree-view.js +51 -0
- package/dist/components/files/file-tree-view.js.map +1 -0
- package/dist/components/files/file-tree.d.ts +6 -0
- package/dist/components/files/file-tree.d.ts.map +1 -1
- package/dist/components/files/file-tree.js +39 -43
- package/dist/components/files/file-tree.js.map +1 -1
- package/dist/components/files/file-viewer-binary.d.ts.map +1 -1
- package/dist/components/files/file-viewer-binary.js +3 -2
- package/dist/components/files/file-viewer-binary.js.map +1 -1
- package/dist/components/files/file-viewer-frame.d.ts +36 -0
- package/dist/components/files/file-viewer-frame.d.ts.map +1 -0
- package/dist/components/files/file-viewer-frame.js +26 -0
- package/dist/components/files/file-viewer-frame.js.map +1 -0
- package/dist/components/files/file-viewer.d.ts +5 -0
- package/dist/components/files/file-viewer.d.ts.map +1 -1
- package/dist/components/files/file-viewer.js +26 -32
- package/dist/components/files/file-viewer.js.map +1 -1
- package/dist/components/files/frontmatter-chips.d.ts +18 -0
- package/dist/components/files/frontmatter-chips.d.ts.map +1 -0
- package/dist/components/files/frontmatter-chips.js +11 -0
- package/dist/components/files/frontmatter-chips.js.map +1 -0
- package/dist/components/files/frontmatter-panel.d.ts +5 -1
- package/dist/components/files/frontmatter-panel.d.ts.map +1 -1
- package/dist/components/files/frontmatter-panel.js +7 -6
- package/dist/components/files/frontmatter-panel.js.map +1 -1
- package/dist/components/files/staleness.d.ts +18 -0
- package/dist/components/files/staleness.d.ts.map +1 -0
- package/dist/components/files/staleness.js +27 -0
- package/dist/components/files/staleness.js.map +1 -0
- package/dist/components/graph/graph-canvas.d.ts.map +1 -1
- package/dist/components/graph/graph-canvas.js +24 -1
- package/dist/components/graph/graph-canvas.js.map +1 -1
- package/dist/components/graph/graph-controls-column.d.ts +14 -0
- package/dist/components/graph/graph-controls-column.d.ts.map +1 -0
- package/dist/components/graph/graph-controls-column.js +44 -0
- package/dist/components/graph/graph-controls-column.js.map +1 -0
- package/dist/components/graph/graph-controls.d.ts +20 -5
- package/dist/components/graph/graph-controls.d.ts.map +1 -1
- package/dist/components/graph/graph-controls.js +58 -37
- package/dist/components/graph/graph-controls.js.map +1 -1
- package/dist/components/graph/graph-form.d.ts +82 -0
- package/dist/components/graph/graph-form.d.ts.map +1 -0
- package/dist/components/graph/graph-form.js +69 -0
- package/dist/components/graph/graph-form.js.map +1 -0
- package/dist/components/graph/graph-maintenance.d.ts.map +1 -1
- package/dist/components/graph/graph-maintenance.js +6 -10
- package/dist/components/graph/graph-maintenance.js.map +1 -1
- package/dist/components/graph/graph-node-rail.d.ts +13 -0
- package/dist/components/graph/graph-node-rail.d.ts.map +1 -0
- package/dist/components/graph/graph-node-rail.js +92 -0
- package/dist/components/graph/graph-node-rail.js.map +1 -0
- package/dist/components/graph/graph-page.d.ts +7 -0
- package/dist/components/graph/graph-page.d.ts.map +1 -1
- package/dist/components/graph/graph-page.js +102 -12
- package/dist/components/graph/graph-page.js.map +1 -1
- package/dist/components/graph/graph-scene.d.ts.map +1 -1
- package/dist/components/graph/graph-scene.js +100 -24
- package/dist/components/graph/graph-scene.js.map +1 -1
- package/dist/components/graph/lib/graph-helpers.d.ts +42 -12
- package/dist/components/graph/lib/graph-helpers.d.ts.map +1 -1
- package/dist/components/graph/lib/graph-helpers.js +33 -41
- package/dist/components/graph/lib/graph-helpers.js.map +1 -1
- package/dist/components/graph/node-card.d.ts +28 -0
- package/dist/components/graph/node-card.d.ts.map +1 -0
- package/dist/components/graph/node-card.js +7 -0
- package/dist/components/graph/node-card.js.map +1 -0
- package/dist/components/graph/node-popover.d.ts +6 -2
- package/dist/components/graph/node-popover.d.ts.map +1 -1
- package/dist/components/graph/node-popover.js +13 -31
- package/dist/components/graph/node-popover.js.map +1 -1
- package/dist/components/graph/use-graph-theme.d.ts +32 -4
- package/dist/components/graph/use-graph-theme.d.ts.map +1 -1
- package/dist/components/graph/use-graph-theme.js +44 -32
- package/dist/components/graph/use-graph-theme.js.map +1 -1
- package/dist/components/graph/use-node-actions.d.ts +26 -0
- package/dist/components/graph/use-node-actions.d.ts.map +1 -0
- package/dist/components/graph/use-node-actions.js +54 -0
- package/dist/components/graph/use-node-actions.js.map +1 -0
- package/dist/components/images/image-share.d.ts +2 -1
- package/dist/components/images/image-share.d.ts.map +1 -1
- package/dist/components/images/image-share.js +3 -3
- package/dist/components/images/image-share.js.map +1 -1
- package/dist/components/images/image-viewer.d.ts.map +1 -1
- package/dist/components/images/image-viewer.js +3 -1
- package/dist/components/images/image-viewer.js.map +1 -1
- package/dist/components/images/mask-editor.d.ts.map +1 -1
- package/dist/components/images/mask-editor.js +7 -5
- package/dist/components/images/mask-editor.js.map +1 -1
- package/dist/components/layout/app-shell.d.ts.map +1 -1
- package/dist/components/layout/app-shell.js +5 -1
- package/dist/components/layout/app-shell.js.map +1 -1
- package/dist/components/layout/desktop-palette.d.ts +23 -0
- package/dist/components/layout/desktop-palette.d.ts.map +1 -0
- package/dist/components/layout/desktop-palette.js +132 -0
- package/dist/components/layout/desktop-palette.js.map +1 -0
- package/dist/components/layout/key-cap.d.ts +9 -0
- package/dist/components/layout/key-cap.d.ts.map +1 -0
- package/dist/components/layout/key-cap.js +10 -0
- package/dist/components/layout/key-cap.js.map +1 -0
- package/dist/components/layout/mobile-tab-bar.d.ts +13 -0
- package/dist/components/layout/mobile-tab-bar.d.ts.map +1 -1
- package/dist/components/layout/mobile-tab-bar.js +58 -47
- package/dist/components/layout/mobile-tab-bar.js.map +1 -1
- package/dist/components/layout/shortcut-switch.d.ts +13 -0
- package/dist/components/layout/shortcut-switch.d.ts.map +1 -0
- package/dist/components/layout/shortcut-switch.js +22 -0
- package/dist/components/layout/shortcut-switch.js.map +1 -0
- package/dist/components/layout/side-rail.d.ts +24 -0
- package/dist/components/layout/side-rail.d.ts.map +1 -1
- package/dist/components/layout/side-rail.js +65 -27
- package/dist/components/layout/side-rail.js.map +1 -1
- package/dist/components/layout/slide-panel.d.ts +12 -2
- package/dist/components/layout/slide-panel.d.ts.map +1 -1
- package/dist/components/layout/slide-panel.js +11 -2
- package/dist/components/layout/slide-panel.js.map +1 -1
- package/dist/components/layout/theme.d.ts +22 -0
- package/dist/components/layout/theme.d.ts.map +1 -0
- package/dist/components/layout/theme.js +44 -0
- package/dist/components/layout/theme.js.map +1 -0
- package/dist/components/quick-actions/add-form.d.ts +44 -0
- package/dist/components/quick-actions/add-form.d.ts.map +1 -0
- package/dist/components/quick-actions/add-form.js +30 -0
- package/dist/components/quick-actions/add-form.js.map +1 -0
- package/dist/components/quick-actions/add-modal.d.ts +7 -0
- package/dist/components/quick-actions/add-modal.d.ts.map +1 -1
- package/dist/components/quick-actions/add-modal.js +66 -20
- package/dist/components/quick-actions/add-modal.js.map +1 -1
- package/dist/components/quick-actions/search-modal.d.ts.map +1 -1
- package/dist/components/quick-actions/search-modal.js +48 -19
- package/dist/components/quick-actions/search-modal.js.map +1 -1
- package/dist/components/quick-actions/streaming-modal.d.ts +6 -0
- package/dist/components/quick-actions/streaming-modal.d.ts.map +1 -1
- package/dist/components/quick-actions/streaming-modal.js +42 -17
- package/dist/components/quick-actions/streaming-modal.js.map +1 -1
- package/dist/components/quick-actions/streaming-output.d.ts +38 -0
- package/dist/components/quick-actions/streaming-output.d.ts.map +1 -0
- package/dist/components/quick-actions/streaming-output.js +22 -0
- package/dist/components/quick-actions/streaming-output.js.map +1 -0
- package/dist/components/quick-actions/whatsup-modal.d.ts +5 -0
- package/dist/components/quick-actions/whatsup-modal.d.ts.map +1 -1
- package/dist/components/quick-actions/whatsup-modal.js +36 -10
- package/dist/components/quick-actions/whatsup-modal.js.map +1 -1
- package/dist/components/settings/devices-agents-tab.d.ts +10 -0
- package/dist/components/settings/devices-agents-tab.d.ts.map +1 -0
- package/dist/components/settings/devices-agents-tab.js +131 -0
- package/dist/components/settings/devices-agents-tab.js.map +1 -0
- package/dist/components/settings/models-list.d.ts +39 -0
- package/dist/components/settings/models-list.d.ts.map +1 -0
- package/dist/components/settings/models-list.js +72 -0
- package/dist/components/settings/models-list.js.map +1 -0
- package/dist/components/settings/models-tab.d.ts +4 -0
- package/dist/components/settings/models-tab.d.ts.map +1 -1
- package/dist/components/settings/models-tab.js +52 -102
- package/dist/components/settings/models-tab.js.map +1 -1
- package/dist/components/settings/one-time-agent-credential.d.ts +3 -0
- package/dist/components/settings/one-time-agent-credential.d.ts.map +1 -0
- package/dist/components/settings/one-time-agent-credential.js +55 -0
- package/dist/components/settings/one-time-agent-credential.js.map +1 -0
- package/dist/components/settings/passkey-list.d.ts +35 -0
- package/dist/components/settings/passkey-list.d.ts.map +1 -0
- package/dist/components/settings/passkey-list.js +34 -0
- package/dist/components/settings/passkey-list.js.map +1 -0
- package/dist/components/settings/passkey-tab.d.ts +3 -0
- package/dist/components/settings/passkey-tab.d.ts.map +1 -1
- package/dist/components/settings/passkey-tab.js +53 -45
- package/dist/components/settings/passkey-tab.js.map +1 -1
- package/dist/components/settings/pi-accounts-list.d.ts +27 -0
- package/dist/components/settings/pi-accounts-list.d.ts.map +1 -0
- package/dist/components/settings/pi-accounts-list.js +15 -0
- package/dist/components/settings/pi-accounts-list.js.map +1 -0
- package/dist/components/settings/pi-accounts.d.ts +3 -0
- package/dist/components/settings/pi-accounts.d.ts.map +1 -1
- package/dist/components/settings/pi-accounts.js +73 -55
- package/dist/components/settings/pi-accounts.js.map +1 -1
- package/dist/components/settings/principal-list.d.ts +37 -0
- package/dist/components/settings/principal-list.d.ts.map +1 -0
- package/dist/components/settings/principal-list.js +18 -0
- package/dist/components/settings/principal-list.js.map +1 -0
- package/dist/components/settings/settings-panel.d.ts +10 -3
- package/dist/components/settings/settings-panel.d.ts.map +1 -1
- package/dist/components/settings/settings-panel.js +80 -6
- package/dist/components/settings/settings-panel.js.map +1 -1
- package/dist/components/settings/skills-list.d.ts +53 -0
- package/dist/components/settings/skills-list.d.ts.map +1 -0
- package/dist/components/settings/skills-list.js +28 -0
- package/dist/components/settings/skills-list.js.map +1 -0
- package/dist/components/settings/skills-tab.d.ts.map +1 -1
- package/dist/components/settings/skills-tab.js +65 -38
- package/dist/components/settings/skills-tab.js.map +1 -1
- package/dist/components/settings/tool-permissions-list.d.ts +18 -0
- package/dist/components/settings/tool-permissions-list.d.ts.map +1 -0
- package/dist/components/settings/tool-permissions-list.js +6 -0
- package/dist/components/settings/tool-permissions-list.js.map +1 -0
- package/dist/components/settings/tool-permissions.d.ts +2 -1
- package/dist/components/settings/tool-permissions.d.ts.map +1 -1
- package/dist/components/settings/tool-permissions.js +33 -16
- package/dist/components/settings/tool-permissions.js.map +1 -1
- package/dist/components/settings/web-search-chain.d.ts +41 -0
- package/dist/components/settings/web-search-chain.d.ts.map +1 -0
- package/dist/components/settings/web-search-chain.js +47 -0
- package/dist/components/settings/web-search-chain.js.map +1 -0
- package/dist/components/settings/web-search-settings.d.ts +4 -7
- package/dist/components/settings/web-search-settings.d.ts.map +1 -1
- package/dist/components/settings/web-search-settings.js +54 -76
- package/dist/components/settings/web-search-settings.js.map +1 -1
- package/dist/components/share/share-menu.d.ts.map +1 -1
- package/dist/components/share/share-menu.js +24 -4
- package/dist/components/share/share-menu.js.map +1 -1
- package/dist/components/voice/dictation-sheet.js +3 -3
- package/dist/components/voice/dictation-sheet.js.map +1 -1
- package/dist/components/voice/mic-button.js +1 -1
- package/dist/components/voice/mic-button.js.map +1 -1
- package/dist/components/voice/review-card.js +1 -1
- package/dist/components/voice/review-card.js.map +1 -1
- package/dist/config.d.ts +5 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +15 -5
- package/dist/config.js.map +1 -1
- package/dist/connection.d.ts +12 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +421 -0
- package/dist/connection.js.map +1 -0
- package/dist/default-root.d.ts +3 -0
- package/dist/default-root.d.ts.map +1 -0
- package/dist/default-root.js +16 -0
- package/dist/default-root.js.map +1 -0
- package/dist/hooks/use-color-scheme.d.ts +14 -0
- package/dist/hooks/use-color-scheme.d.ts.map +1 -0
- package/dist/hooks/use-color-scheme.js +37 -0
- package/dist/hooks/use-color-scheme.js.map +1 -0
- package/dist/hooks/use-hash-routes.d.ts.map +1 -1
- package/dist/hooks/use-hash-routes.js +4 -2
- package/dist/hooks/use-hash-routes.js.map +1 -1
- package/dist/hooks/use-media-query.d.ts +7 -0
- package/dist/hooks/use-media-query.d.ts.map +1 -0
- package/dist/hooks/use-media-query.js +34 -0
- package/dist/hooks/use-media-query.js.map +1 -0
- package/dist/hooks/use-share-intake.d.ts.map +1 -1
- package/dist/hooks/use-share-intake.js +37 -12
- package/dist/hooks/use-share-intake.js.map +1 -1
- package/dist/hooks/use-vpn-status.d.ts +1 -1
- package/dist/hooks/use-vpn-status.d.ts.map +1 -1
- package/dist/hooks/use-vpn-status.js +20 -16
- package/dist/hooks/use-vpn-status.js.map +1 -1
- package/dist/hooks/use-websocket.d.ts +5 -24
- package/dist/hooks/use-websocket.d.ts.map +1 -1
- package/dist/hooks/use-websocket.js +11 -382
- package/dist/hooks/use-websocket.js.map +1 -1
- package/dist/hooks/websocket-handlers/activity.d.ts +2 -2
- package/dist/hooks/websocket-handlers/activity.d.ts.map +1 -1
- package/dist/hooks/websocket-handlers/activity.js +4 -5
- package/dist/hooks/websocket-handlers/activity.js.map +1 -1
- package/dist/hooks/websocket-handlers/chat.d.ts +1 -0
- package/dist/hooks/websocket-handlers/chat.d.ts.map +1 -1
- package/dist/hooks/websocket-handlers/chat.js +27 -5
- package/dist/hooks/websocket-handlers/chat.js.map +1 -1
- package/dist/hooks/websocket-handlers/connection.d.ts.map +1 -1
- package/dist/hooks/websocket-handlers/connection.js +4 -6
- package/dist/hooks/websocket-handlers/connection.js.map +1 -1
- package/dist/hooks/websocket-handlers/mask.d.ts +1 -1
- package/dist/hooks/websocket-handlers/mask.d.ts.map +1 -1
- package/dist/hooks/websocket-handlers/mask.js +2 -3
- package/dist/hooks/websocket-handlers/mask.js.map +1 -1
- package/dist/hooks/websocket-handlers/provider.d.ts.map +1 -1
- package/dist/hooks/websocket-handlers/provider.js +4 -6
- package/dist/hooks/websocket-handlers/provider.js.map +1 -1
- package/dist/hooks/websocket-handlers/types.d.ts +6 -2
- package/dist/hooks/websocket-handlers/types.d.ts.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/api-client.d.ts +321 -0
- package/dist/lib/api-client.d.ts.map +1 -1
- package/dist/lib/api-client.js +243 -213
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/backend.d.ts +19 -2
- package/dist/lib/backend.d.ts.map +1 -1
- package/dist/lib/backend.js +15 -9
- package/dist/lib/backend.js.map +1 -1
- package/dist/lib/diff.d.ts +8 -10
- package/dist/lib/diff.d.ts.map +1 -1
- package/dist/lib/diff.js +26 -53
- package/dist/lib/diff.js.map +1 -1
- package/dist/lib/format-time.d.ts +3 -0
- package/dist/lib/format-time.d.ts.map +1 -0
- package/dist/lib/format-time.js +25 -0
- package/dist/lib/format-time.js.map +1 -0
- package/dist/lib/light-dark.d.ts +37 -0
- package/dist/lib/light-dark.d.ts.map +1 -0
- package/dist/lib/light-dark.js +83 -0
- package/dist/lib/light-dark.js.map +1 -0
- package/dist/lib/mermaid-theme.d.ts +7 -2
- package/dist/lib/mermaid-theme.d.ts.map +1 -1
- package/dist/lib/mermaid-theme.js +125 -203
- package/dist/lib/mermaid-theme.js.map +1 -1
- package/dist/lib/passkeys.d.ts +6 -3
- package/dist/lib/passkeys.d.ts.map +1 -1
- package/dist/lib/passkeys.js +10 -4
- package/dist/lib/passkeys.js.map +1 -1
- package/dist/lib/push-registration.d.ts +10 -0
- package/dist/lib/push-registration.d.ts.map +1 -0
- package/dist/lib/push-registration.js +44 -0
- package/dist/lib/push-registration.js.map +1 -0
- package/dist/lib/share-intake.d.ts +2 -1
- package/dist/lib/share-intake.d.ts.map +1 -1
- package/dist/lib/share-intake.js +3 -3
- package/dist/lib/share-intake.js.map +1 -1
- package/dist/lib/share.d.ts +4 -3
- package/dist/lib/share.d.ts.map +1 -1
- package/dist/lib/share.js +6 -7
- package/dist/lib/share.js.map +1 -1
- package/dist/lib/single-key.d.ts +30 -0
- package/dist/lib/single-key.d.ts.map +1 -0
- package/dist/lib/single-key.js +45 -0
- package/dist/lib/single-key.js.map +1 -0
- package/dist/lib/tool-names.d.ts +8 -6
- package/dist/lib/tool-names.d.ts.map +1 -1
- package/dist/lib/tool-names.js +17 -7
- package/dist/lib/tool-names.js.map +1 -1
- package/dist/root-context.d.ts +229 -0
- package/dist/root-context.d.ts.map +1 -0
- package/dist/root-context.js +33 -0
- package/dist/root-context.js.map +1 -0
- package/dist/root.d.ts +38 -0
- package/dist/root.d.ts.map +1 -0
- package/dist/root.js +47 -0
- package/dist/root.js.map +1 -0
- package/dist/stores/activity-state.d.ts +29 -0
- package/dist/stores/activity-state.d.ts.map +1 -0
- package/dist/stores/activity-state.js +282 -0
- package/dist/stores/activity-state.js.map +1 -0
- package/dist/stores/activity-store.d.ts +10 -41
- package/dist/stores/activity-store.d.ts.map +1 -1
- package/dist/stores/activity-store.js +9 -271
- package/dist/stores/activity-store.js.map +1 -1
- package/dist/stores/chat-state.d.ts +212 -0
- package/dist/stores/chat-state.d.ts.map +1 -0
- package/dist/stores/chat-state.js +466 -0
- package/dist/stores/chat-state.js.map +1 -0
- package/dist/stores/chat-store.d.ts +4 -162
- package/dist/stores/chat-store.d.ts.map +1 -1
- package/dist/stores/chat-store.js +7 -418
- package/dist/stores/chat-store.js.map +1 -1
- package/dist/stores/connection-state.d.ts +40 -0
- package/dist/stores/connection-state.d.ts.map +1 -0
- package/dist/stores/connection-state.js +30 -0
- package/dist/stores/connection-state.js.map +1 -0
- package/dist/stores/connection-store.d.ts +4 -40
- package/dist/stores/connection-store.d.ts.map +1 -1
- package/dist/stores/connection-store.js +7 -27
- package/dist/stores/connection-store.js.map +1 -1
- package/dist/stores/create-stores.d.ts +23 -0
- package/dist/stores/create-stores.d.ts.map +1 -0
- package/dist/stores/create-stores.js +28 -0
- package/dist/stores/create-stores.js.map +1 -0
- package/dist/stores/file-state.d.ts +53 -0
- package/dist/stores/file-state.d.ts.map +1 -0
- package/dist/stores/file-state.js +341 -0
- package/dist/stores/file-state.js.map +1 -0
- package/dist/stores/file-store.d.ts +4 -52
- package/dist/stores/file-store.d.ts.map +1 -1
- package/dist/stores/file-store.js +7 -300
- package/dist/stores/file-store.js.map +1 -1
- package/dist/stores/graph-state.d.ts +95 -0
- package/dist/stores/graph-state.d.ts.map +1 -0
- package/dist/stores/graph-state.js +252 -0
- package/dist/stores/graph-state.js.map +1 -0
- package/dist/stores/graph-store.d.ts +7 -83
- package/dist/stores/graph-store.d.ts.map +1 -1
- package/dist/stores/graph-store.js +8 -249
- package/dist/stores/graph-store.js.map +1 -1
- package/dist/stores/mask-state.d.ts +21 -0
- package/dist/stores/mask-state.d.ts.map +1 -0
- package/dist/stores/mask-state.js +9 -0
- package/dist/stores/mask-state.js.map +1 -0
- package/dist/stores/mask-store.d.ts +4 -21
- package/dist/stores/mask-store.d.ts.map +1 -1
- package/dist/stores/mask-store.js +7 -6
- package/dist/stores/mask-store.js.map +1 -1
- package/dist/stores/principal-state.d.ts +16 -0
- package/dist/stores/principal-state.d.ts.map +1 -0
- package/dist/stores/principal-state.js +31 -0
- package/dist/stores/principal-state.js.map +1 -0
- package/dist/stores/principal-store.d.ts +5 -0
- package/dist/stores/principal-store.d.ts.map +1 -0
- package/dist/stores/principal-store.js +8 -0
- package/dist/stores/principal-store.js.map +1 -0
- package/dist/stores/provider-state.d.ts +24 -0
- package/dist/stores/provider-state.d.ts.map +1 -0
- package/dist/stores/provider-state.js +68 -0
- package/dist/stores/provider-state.js.map +1 -0
- package/dist/stores/provider-store.d.ts +4 -23
- package/dist/stores/provider-store.d.ts.map +1 -1
- package/dist/stores/provider-store.js +7 -64
- package/dist/stores/provider-store.js.map +1 -1
- package/dist/stores/share-state.d.ts +29 -0
- package/dist/stores/share-state.d.ts.map +1 -0
- package/dist/stores/share-state.js +21 -0
- package/dist/stores/share-state.js.map +1 -0
- package/dist/stores/share-store.d.ts +4 -28
- package/dist/stores/share-store.d.ts.map +1 -1
- package/dist/stores/share-store.js +7 -18
- package/dist/stores/share-store.js.map +1 -1
- package/dist/stores/store-environment.d.ts +10 -0
- package/dist/stores/store-environment.d.ts.map +1 -0
- package/dist/stores/store-environment.js +2 -0
- package/dist/stores/store-environment.js.map +1 -0
- package/dist/stores/ui-state.d.ts +71 -0
- package/dist/stores/ui-state.d.ts.map +1 -0
- package/dist/stores/ui-state.js +58 -0
- package/dist/stores/ui-state.js.map +1 -0
- package/dist/stores/ui-store.d.ts +4 -45
- package/dist/stores/ui-store.d.ts.map +1 -1
- package/dist/stores/ui-store.js +7 -36
- package/dist/stores/ui-store.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/theme.css +150 -97
- package/dist/voice/asr-clients.d.ts +2 -1
- package/dist/voice/asr-clients.d.ts.map +1 -1
- package/dist/voice/asr-clients.js +16 -17
- package/dist/voice/asr-clients.js.map +1 -1
- package/dist/voice/use-dictation.d.ts.map +1 -1
- package/dist/voice/use-dictation.js +12 -8
- package/dist/voice/use-dictation.js.map +1 -1
- package/dist/voice/voice-state.d.ts +25 -0
- package/dist/voice/voice-state.d.ts.map +1 -0
- package/dist/voice/voice-state.js +29 -0
- package/dist/voice/voice-state.js.map +1 -0
- package/dist/voice/voice-store.d.ts +4 -25
- package/dist/voice/voice-store.d.ts.map +1 -1
- package/dist/voice/voice-store.js +7 -26
- package/dist/voice/voice-store.js.map +1 -1
- package/package.json +3 -2
- package/src/components/activity/activity-page.tsx +334 -160
- package/src/components/activity/activity-run-detail.tsx +81 -47
- package/src/components/activity/activity-run-list.tsx +27 -59
- package/src/components/activity/activity-views.tsx +155 -0
- package/src/components/activity/approval-card.tsx +80 -0
- package/src/components/activity/digest-card.tsx +25 -61
- package/src/components/activity/digest-summary.tsx +52 -0
- package/src/components/activity/push-switch.tsx +62 -0
- package/src/components/activity/push-toggle.tsx +51 -81
- package/src/components/activity/span-bits.tsx +8 -7
- package/src/components/chat/ask-user-card.tsx +292 -356
- package/src/components/chat/ask-user-typed.ts +77 -0
- package/src/components/chat/brain-markdown-links.tsx +4 -4
- package/src/components/chat/brain-markdown.tsx +4 -2
- package/src/components/chat/chat-page.tsx +38 -9
- package/src/components/chat/composer-view.tsx +194 -0
- package/src/components/chat/composer.tsx +117 -296
- package/src/components/chat/markdown-content.tsx +53 -2
- package/src/components/chat/mermaid-block.tsx +13 -5
- package/src/components/chat/mermaid-share.ts +8 -7
- package/src/components/chat/mermaid-viewer.tsx +3 -1
- package/src/components/chat/message-bubble.tsx +78 -94
- package/src/components/chat/message-share.ts +7 -7
- package/src/components/chat/renderers/bind.tsx +94 -0
- package/src/components/chat/renderers/brain-ui-tools.tsx +56 -0
- package/src/components/chat/renderers/claude-tools.tsx +3 -2
- package/src/components/chat/renderers/index.ts +15 -10
- package/src/components/chat/session-drawer.tsx +60 -138
- package/src/components/chat/session-list.tsx +113 -0
- package/src/components/chat/share-block.tsx +16 -12
- package/src/components/chat/share-card.tsx +2 -2
- package/src/components/chat/subagent-view.tsx +4 -4
- package/src/components/chat/tool-call-timeline.tsx +59 -22
- package/src/components/chat/tool-cards/block-card.tsx +145 -0
- package/src/components/chat/tool-cards/image-mask-card.tsx +214 -0
- package/src/components/chat/tool-cards/location-card.tsx +159 -0
- package/src/components/chat/tool-views.tsx +23 -73
- package/src/components/chat/transcript-turn.tsx +108 -0
- package/src/components/chat/use-chat-commands.ts +14 -16
- package/src/components/chat/welcome-state.tsx +36 -91
- package/src/components/connectivity/connection-gate.tsx +80 -9
- package/src/components/connectivity/login-form.tsx +122 -0
- package/src/components/connectivity/login-screen.tsx +45 -100
- package/src/components/dev/share-harness.tsx +2 -2
- package/src/components/files/file-panel.tsx +168 -0
- package/src/components/files/file-tree-view.tsx +127 -0
- package/src/components/files/file-tree.tsx +55 -109
- package/src/components/files/file-viewer-binary.tsx +3 -2
- package/src/components/files/file-viewer-frame.tsx +113 -0
- package/src/components/files/file-viewer.tsx +40 -95
- package/src/components/files/frontmatter-chips.tsx +42 -0
- package/src/components/files/frontmatter-panel.tsx +6 -71
- package/src/components/files/staleness.ts +29 -0
- package/src/components/graph/graph-canvas.tsx +24 -1
- package/src/components/graph/graph-controls-column.tsx +92 -0
- package/src/components/graph/graph-controls.tsx +83 -127
- package/src/components/graph/graph-form.tsx +183 -0
- package/src/components/graph/graph-maintenance.tsx +9 -14
- package/src/components/graph/graph-node-rail.tsx +147 -0
- package/src/components/graph/graph-page.tsx +189 -49
- package/src/components/graph/graph-scene.tsx +200 -30
- package/src/components/graph/lib/graph-helpers.ts +65 -43
- package/src/components/graph/node-card.tsx +64 -0
- package/src/components/graph/node-popover.tsx +28 -117
- package/src/components/graph/use-graph-theme.ts +69 -32
- package/src/components/graph/use-node-actions.ts +56 -0
- package/src/components/images/image-share.ts +4 -2
- package/src/components/images/image-viewer.tsx +3 -1
- package/src/components/images/mask-editor.tsx +7 -4
- package/src/components/layout/app-shell.tsx +7 -1
- package/src/components/layout/desktop-palette.tsx +151 -0
- package/src/components/layout/key-cap.tsx +15 -0
- package/src/components/layout/mobile-tab-bar.tsx +80 -157
- package/src/components/layout/shortcut-switch.tsx +32 -0
- package/src/components/layout/side-rail.tsx +70 -150
- package/src/components/layout/slide-panel.tsx +29 -2
- package/src/components/layout/theme.tsx +67 -0
- package/src/components/quick-actions/add-form.tsx +188 -0
- package/src/components/quick-actions/add-modal.tsx +68 -144
- package/src/components/quick-actions/search-modal.tsx +49 -19
- package/src/components/quick-actions/streaming-modal.tsx +44 -71
- package/src/components/quick-actions/streaming-output.tsx +112 -0
- package/src/components/quick-actions/whatsup-modal.tsx +38 -60
- package/src/components/settings/devices-agents-tab.tsx +139 -0
- package/src/components/settings/models-list.tsx +299 -0
- package/src/components/settings/models-tab.tsx +63 -337
- package/src/components/settings/one-time-agent-credential.tsx +131 -0
- package/src/components/settings/passkey-list.tsx +201 -0
- package/src/components/settings/passkey-tab.tsx +53 -197
- package/src/components/settings/pi-accounts-list.tsx +128 -0
- package/src/components/settings/pi-accounts.tsx +71 -170
- package/src/components/settings/principal-list.tsx +172 -0
- package/src/components/settings/settings-panel.tsx +245 -19
- package/src/components/settings/skills-list.tsx +276 -0
- package/src/components/settings/skills-tab.tsx +82 -269
- package/src/components/settings/tool-permissions-list.tsx +54 -0
- package/src/components/settings/tool-permissions.tsx +27 -46
- package/src/components/settings/web-search-chain.tsx +300 -0
- package/src/components/settings/web-search-settings.tsx +58 -328
- package/src/components/share/share-menu.tsx +19 -4
- package/src/components/voice/dictation-sheet.tsx +5 -5
- package/src/components/voice/mic-button.tsx +1 -1
- package/src/components/voice/review-card.tsx +1 -1
- package/src/config.ts +21 -7
- package/src/connection.ts +443 -0
- package/src/default-root.ts +16 -0
- package/src/hooks/use-color-scheme.ts +36 -0
- package/src/hooks/use-hash-routes.ts +4 -2
- package/src/hooks/use-media-query.ts +32 -0
- package/src/hooks/use-share-intake.ts +32 -12
- package/src/hooks/use-vpn-status.ts +23 -15
- package/src/hooks/use-websocket.ts +12 -426
- package/src/hooks/websocket-handlers/activity.ts +4 -5
- package/src/hooks/websocket-handlers/chat.ts +26 -5
- package/src/hooks/websocket-handlers/connection.ts +4 -6
- package/src/hooks/websocket-handlers/mask.ts +2 -3
- package/src/hooks/websocket-handlers/provider.ts +4 -6
- package/src/hooks/websocket-handlers/types.ts +6 -2
- package/src/index.ts +7 -3
- package/src/lib/api-client.ts +446 -365
- package/src/lib/backend.ts +20 -10
- package/src/lib/diff.ts +28 -62
- package/src/lib/format-time.ts +20 -0
- package/src/lib/light-dark.ts +83 -0
- package/src/lib/mermaid-theme.ts +183 -214
- package/src/lib/passkeys.ts +12 -4
- package/src/lib/push-registration.ts +46 -0
- package/src/lib/share-intake.ts +6 -3
- package/src/lib/share.ts +7 -4
- package/src/lib/single-key.ts +47 -0
- package/src/lib/tool-names.ts +31 -8
- package/src/root-context.tsx +40 -0
- package/src/root.ts +83 -0
- package/src/stores/activity-state.ts +295 -0
- package/src/stores/activity-store.ts +11 -285
- package/src/stores/chat-state.ts +795 -0
- package/src/stores/chat-store.ts +11 -705
- package/src/stores/connection-state.ts +78 -0
- package/src/stores/connection-store.ts +11 -76
- package/src/stores/create-stores.ts +31 -0
- package/src/stores/file-state.ts +399 -0
- package/src/stores/file-store.ts +9 -360
- package/src/stores/graph-state.ts +368 -0
- package/src/stores/graph-store.ts +10 -355
- package/src/stores/mask-state.ts +30 -0
- package/src/stores/mask-store.ts +10 -27
- package/src/stores/principal-state.ts +42 -0
- package/src/stores/principal-store.ts +11 -0
- package/src/stores/provider-state.ts +103 -0
- package/src/stores/provider-store.ts +10 -95
- package/src/stores/share-state.ts +56 -0
- package/src/stores/share-store.ts +11 -54
- package/src/stores/store-environment.ts +10 -0
- package/src/stores/ui-state.ts +143 -0
- package/src/stores/ui-store.ts +11 -93
- package/src/styles.css +4 -1
- package/src/theme.css +150 -97
- package/src/voice/asr-clients.ts +17 -17
- package/src/voice/use-dictation.ts +11 -8
- package/src/voice/voice-state.ts +57 -0
- package/src/voice/voice-store.ts +11 -55
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { Suspense, lazy } from "react";
|
|
2
|
-
import { KeyRound, Puzzle, SlidersHorizontal } from "lucide-react";
|
|
2
|
+
import { KeyRound, Laptop, Puzzle, SlidersHorizontal } from "lucide-react";
|
|
3
3
|
import { useUIStore, type SettingsTab } from "../../stores/ui-store.js";
|
|
4
4
|
import { SlidePanel } from "../layout/slide-panel.js";
|
|
5
5
|
import { cn } from "../../lib/utils.js";
|
|
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";
|
|
6
12
|
|
|
7
13
|
/**
|
|
8
14
|
* Each tab is fetched the first time it is opened. Settings is the largest
|
|
@@ -13,18 +19,46 @@ import { cn } from "../../lib/utils.js";
|
|
|
13
19
|
*/
|
|
14
20
|
const ModelsTab = lazy(() => import("./models-tab.js").then((m) => ({ default: m.ModelsTab })));
|
|
15
21
|
const PasskeyTab = lazy(() => import("./passkey-tab.js").then((m) => ({ default: m.PasskeyTab })));
|
|
22
|
+
const DevicesAgentsTab = lazy(() => import("./devices-agents-tab.js").then((m) => ({ default: m.DevicesAgentsTab })));
|
|
16
23
|
const SkillsTab = lazy(() => import("./skills-tab.js").then((m) => ({ default: m.SkillsTab })));
|
|
17
24
|
|
|
18
|
-
|
|
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 }> = [
|
|
19
29
|
{ id: "models", label: "Models", icon: SlidersHorizontal },
|
|
20
30
|
{ id: "skills", label: "Skills", icon: Puzzle },
|
|
21
31
|
{ id: "security", label: "Security", icon: KeyRound },
|
|
32
|
+
{ id: "devices", label: "Devices & agents", icon: Laptop },
|
|
22
33
|
];
|
|
23
34
|
|
|
24
35
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
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.
|
|
28
62
|
*/
|
|
29
63
|
export function SettingsPanel({
|
|
30
64
|
open,
|
|
@@ -35,42 +69,234 @@ export function SettingsPanel({
|
|
|
35
69
|
}) {
|
|
36
70
|
const tab = useUIStore((s) => s.settingsTab);
|
|
37
71
|
const setTab = useUIStore((s) => s.setSettingsTab);
|
|
72
|
+
const mintPending = usePrincipalStore((s) => s.mintPending);
|
|
73
|
+
const oneTimeCredential = usePrincipalStore((s) => s.oneTimeCredential);
|
|
74
|
+
const credentialProtected = mintPending || oneTimeCredential !== null;
|
|
75
|
+
const pane = useMediaQuery(PANE_QUERY);
|
|
76
|
+
|
|
77
|
+
function closeIfSafe() {
|
|
78
|
+
if (!credentialProtected) onClose();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function select(id: SettingsTab) {
|
|
82
|
+
if (!credentialProtected) setTab(id);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (pane) {
|
|
86
|
+
return (
|
|
87
|
+
<SettingsPane
|
|
88
|
+
open={open}
|
|
89
|
+
tab={tab}
|
|
90
|
+
credentialProtected={credentialProtected}
|
|
91
|
+
onSelect={select}
|
|
92
|
+
onClose={closeIfSafe}
|
|
93
|
+
/>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// The strip has no Appearance tab: a pane selection that survives a resize
|
|
98
|
+
// down lands on the first tab, and the controls it named are right above.
|
|
99
|
+
const stripTab: StripTab = tab === "appearance" ? "models" : tab;
|
|
38
100
|
|
|
39
101
|
return (
|
|
40
|
-
<SlidePanel open={open} onClose={
|
|
102
|
+
<SlidePanel open={open} onClose={closeIfSafe} title="Settings" wide>
|
|
41
103
|
<div className="flex h-full flex-col">
|
|
42
104
|
<div className="flex shrink-0 gap-1 border-b border-border px-2 pt-2">
|
|
43
|
-
{TABS.map(({ id, label, icon:
|
|
105
|
+
{TABS.map(({ id, label, icon: TabIcon }) => (
|
|
44
106
|
<button
|
|
45
107
|
key={id}
|
|
46
|
-
onClick={() =>
|
|
47
|
-
|
|
108
|
+
onClick={() => select(id)}
|
|
109
|
+
disabled={credentialProtected && stripTab !== id}
|
|
110
|
+
aria-selected={stripTab === id}
|
|
48
111
|
role="tab"
|
|
49
112
|
className={cn(
|
|
50
|
-
"flex items-center gap-1.5 rounded-t-lg px-3 py-2 text-xs font-medium transition-colors",
|
|
51
|
-
|
|
113
|
+
"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",
|
|
114
|
+
stripTab === id
|
|
52
115
|
? "border-b-2 border-primary text-foreground"
|
|
53
116
|
: "text-muted-foreground hover:text-foreground"
|
|
54
117
|
)}
|
|
55
118
|
>
|
|
56
|
-
<
|
|
119
|
+
<TabIcon className="h-3.5 w-3.5" />
|
|
57
120
|
{label}
|
|
58
121
|
</button>
|
|
59
122
|
))}
|
|
60
123
|
</div>
|
|
61
124
|
|
|
125
|
+
{/* Appearance is not a tab: it is one control, it applies everywhere,
|
|
126
|
+
and the design puts the three-way toggle in Settings without
|
|
127
|
+
giving it a section of its own. */}
|
|
128
|
+
<div className="flex shrink-0 items-center justify-between gap-3 border-b border-border px-3 py-2">
|
|
129
|
+
<span className="text-xs text-muted-foreground">Appearance</span>
|
|
130
|
+
<ThemeToggle />
|
|
131
|
+
</div>
|
|
132
|
+
{/* Settings › Input (D37, as D5 draws it): the off switch for
|
|
133
|
+
single-key shortcuts as a group row, with the banner that says what
|
|
134
|
+
turning it off does. One control, applies everywhere, so it sits
|
|
135
|
+
beside Appearance rather than in a tab. */}
|
|
136
|
+
<div className="flex shrink-0 flex-col gap-2 border-b border-border px-3 py-2">
|
|
137
|
+
<Label text="Input" icon="capability" />
|
|
138
|
+
<Surface pad={0}>
|
|
139
|
+
<ShortcutSwitch />
|
|
140
|
+
</Surface>
|
|
141
|
+
<ShortcutBanner />
|
|
142
|
+
</div>
|
|
143
|
+
|
|
62
144
|
<div className="min-h-0 flex-1">
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
145
|
+
<SectionBody tab={stripTab} open={open} />
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</SlidePanel>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* D5 from `laptop:` up: the pane. The header row carries the serif title and
|
|
154
|
+
* the close control; under it the section column and the form area share the
|
|
155
|
+
* height, and only the form area scrolls.
|
|
156
|
+
*/
|
|
157
|
+
function SettingsPane({
|
|
158
|
+
open,
|
|
159
|
+
tab,
|
|
160
|
+
credentialProtected,
|
|
161
|
+
onSelect,
|
|
162
|
+
onClose,
|
|
163
|
+
}: {
|
|
164
|
+
open: boolean;
|
|
165
|
+
tab: SettingsTab;
|
|
166
|
+
credentialProtected: boolean;
|
|
167
|
+
onSelect: (tab: SettingsTab) => void;
|
|
168
|
+
onClose: () => void;
|
|
169
|
+
}) {
|
|
170
|
+
const appName = useBrainUiRoot().config.appName;
|
|
171
|
+
return (
|
|
172
|
+
<SlidePanel open={open} onClose={onClose} title="Settings" mode="pane">
|
|
173
|
+
{/* The kit header is `width: 100%`; it needs a shrinking flex child
|
|
174
|
+
around it, or it fills the row and pushes Close past the viewport
|
|
175
|
+
(the Files pane wraps its header the same way). */}
|
|
176
|
+
<div className="flex shrink-0 items-center border-b border-border pr-3">
|
|
177
|
+
<div className="min-w-0 flex-1">
|
|
178
|
+
<ScreenHeader variant="nav" title="Settings" back={false} divider={false} />
|
|
179
|
+
</div>
|
|
180
|
+
<div className="shrink-0">
|
|
181
|
+
<Button label="Close" icon="dismiss" tone="quiet" size="sm" block={false} onClick={onClose} />
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<div className="flex min-h-0 flex-1">
|
|
186
|
+
<nav aria-label="Settings sections" className="flex w-[216px] shrink-0 flex-col border-r border-border">
|
|
187
|
+
<div role="tablist" aria-orientation="vertical" className="flex flex-1 flex-col gap-0.5 p-2">
|
|
188
|
+
{SECTIONS.map(({ id, label, meta, icon }) => {
|
|
189
|
+
const selected = tab === id;
|
|
190
|
+
return (
|
|
191
|
+
<button
|
|
192
|
+
key={id}
|
|
193
|
+
type="button"
|
|
194
|
+
role="tab"
|
|
195
|
+
aria-selected={selected}
|
|
196
|
+
// The name is the label alone: the mono meta beside it is a
|
|
197
|
+
// descriptor, and a test or a screen reader asking for
|
|
198
|
+
// "Security" should find it.
|
|
199
|
+
aria-label={label}
|
|
200
|
+
disabled={credentialProtected && !selected}
|
|
201
|
+
onClick={() => onSelect(id)}
|
|
202
|
+
className={cn(
|
|
203
|
+
"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",
|
|
204
|
+
selected ? "bg-surface-raised" : "hover:bg-surface-raised"
|
|
205
|
+
)}
|
|
206
|
+
>
|
|
207
|
+
<Icon icon={icon} size={16} color={selected ? "var(--bk-amber-ink)" : "var(--bk-color-ink-mute)"} />
|
|
208
|
+
<span
|
|
209
|
+
className={cn("min-w-0 flex-1 truncate text-[12.5px] font-semibold", !selected && "text-foreground")}
|
|
210
|
+
style={selected ? { color: "var(--bk-amber-ink)" } : undefined}
|
|
211
|
+
>
|
|
212
|
+
{label}
|
|
213
|
+
</span>
|
|
214
|
+
<span className="shrink-0 font-[family-name:var(--font-mono)] text-[10px] text-muted-foreground">
|
|
215
|
+
{meta}
|
|
216
|
+
</span>
|
|
217
|
+
</button>
|
|
218
|
+
);
|
|
219
|
+
})}
|
|
220
|
+
</div>
|
|
221
|
+
<div className="shrink-0 border-t border-border px-4 py-3 font-[family-name:var(--font-mono)] text-[10px] text-muted-foreground">
|
|
222
|
+
{appName}
|
|
223
|
+
</div>
|
|
224
|
+
</nav>
|
|
225
|
+
|
|
226
|
+
<div className="min-h-0 flex-1 overflow-y-auto">
|
|
227
|
+
<div className="flex h-full max-w-[720px] flex-col">
|
|
228
|
+
{tab === "appearance" ? (
|
|
229
|
+
<AppearanceSection />
|
|
68
230
|
) : (
|
|
69
|
-
<
|
|
231
|
+
<SectionBody tab={tab} open={open} />
|
|
70
232
|
)}
|
|
71
|
-
</
|
|
233
|
+
</div>
|
|
72
234
|
</div>
|
|
73
235
|
</div>
|
|
74
236
|
</SlidePanel>
|
|
75
237
|
);
|
|
76
238
|
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* D5's first section, as the drop draws it: the theme under "Appearance",
|
|
242
|
+
* the single-key switch and its banner under "Input". Both controls apply to
|
|
243
|
+
* this device only, which the header says.
|
|
244
|
+
*/
|
|
245
|
+
function AppearanceSection() {
|
|
246
|
+
return (
|
|
247
|
+
<div className="flex flex-col">
|
|
248
|
+
<ScreenHeader
|
|
249
|
+
variant="nav"
|
|
250
|
+
title="Appearance & input"
|
|
251
|
+
subtitle="applies on this device only"
|
|
252
|
+
back={false}
|
|
253
|
+
divider={false}
|
|
254
|
+
/>
|
|
255
|
+
<div className="flex flex-col gap-2 px-4 pb-4">
|
|
256
|
+
<Label text="Appearance" icon="settings" />
|
|
257
|
+
<Surface pad={0}>
|
|
258
|
+
<div className="flex items-center gap-3 px-3 py-3">
|
|
259
|
+
<Icon icon="settings" size={17} color="var(--bk-color-ink-mute)" />
|
|
260
|
+
<span className="min-w-0 flex-1 text-[12.5px] font-semibold text-foreground">Theme</span>
|
|
261
|
+
<ThemeToggle />
|
|
262
|
+
</div>
|
|
263
|
+
</Surface>
|
|
264
|
+
</div>
|
|
265
|
+
<div className="flex flex-col gap-2 px-4 pb-4">
|
|
266
|
+
<Label text="Input" icon="capability" />
|
|
267
|
+
<Surface pad={0}>
|
|
268
|
+
<ShortcutSwitch />
|
|
269
|
+
</Surface>
|
|
270
|
+
<ShortcutBanner />
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function ShortcutBanner() {
|
|
277
|
+
return (
|
|
278
|
+
<Callout
|
|
279
|
+
variant="banner"
|
|
280
|
+
tone="neutral"
|
|
281
|
+
icon="scope"
|
|
282
|
+
text="Turning single-key shortcuts off also removes the printed keys from buttons — a key that no longer fires should not be advertised."
|
|
283
|
+
/>
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** The lazily fetched section, mounted only while it is the selected one. */
|
|
288
|
+
function SectionBody({ tab, open }: { tab: StripTab; open: boolean }) {
|
|
289
|
+
return (
|
|
290
|
+
<Suspense fallback={null}>
|
|
291
|
+
{tab === "models" ? (
|
|
292
|
+
<ModelsTab active={open} />
|
|
293
|
+
) : tab === "skills" ? (
|
|
294
|
+
<SkillsTab active={open} />
|
|
295
|
+
) : tab === "security" ? (
|
|
296
|
+
<PasskeyTab active={open} />
|
|
297
|
+
) : (
|
|
298
|
+
<DevicesAgentsTab active={open} />
|
|
299
|
+
)}
|
|
300
|
+
</Suspense>
|
|
301
|
+
);
|
|
302
|
+
}
|
|
@@ -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
|
+
}
|