@schlessera/brain-ui-react 0.35.0 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -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 +32 -32
- 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 +13 -2
- package/dist/components/chat/tool-views.d.ts.map +1 -1
- package/dist/components/chat/tool-views.js +20 -22
- 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 +27 -21
- 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 +4 -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 +23 -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 +4 -3
- 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 +39 -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 +6 -1
- package/dist/components/settings/devices-agents-tab.d.ts.map +1 -1
- package/dist/components/settings/devices-agents-tab.js +55 -20
- package/dist/components/settings/devices-agents-tab.js.map +1 -1
- 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.js +1 -1
- package/dist/components/settings/one-time-agent-credential.js.map +1 -1
- 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 +69 -8
- 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.map +1 -1
- package/dist/hooks/use-vpn-status.js +17 -18
- 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 -384
- 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 +289 -0
- package/dist/lib/api-client.d.ts.map +1 -1
- package/dist/lib/api-client.js +243 -224
- 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/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 +4 -1
- package/dist/lib/push-registration.d.ts.map +1 -1
- package/dist/lib/push-registration.js +20 -2
- package/dist/lib/push-registration.js.map +1 -1
- 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 -336
- 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 +4 -15
- package/dist/stores/principal-store.d.ts.map +1 -1
- package/dist/stores/principal-store.js +7 -28
- package/dist/stores/principal-store.js.map +1 -1
- 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 +41 -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 +21 -60
- 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 +32 -24
- 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 +5 -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 +32 -153
- package/src/components/quick-actions/search-modal.tsx +5 -3
- package/src/components/quick-actions/streaming-modal.tsx +42 -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 +60 -152
- 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 +1 -1
- 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 +232 -21
- 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 +18 -17
- package/src/hooks/use-websocket.ts +12 -428
- 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 +426 -384
- package/src/lib/backend.ts +20 -10
- package/src/lib/diff.ts +28 -62
- 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 +19 -2
- 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 -390
- 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 +10 -37
- 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,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BrainUiRoot } from "../../root.js";
|
|
2
2
|
import { renderMermaidSvg, sizeSvgForExport } from "../../lib/mermaid.js";
|
|
3
3
|
import { renderAndShare, shareFile, shareText } from "../../lib/share.js";
|
|
4
4
|
import type { ShareOption } from "../share/share-menu.js";
|
|
@@ -41,6 +41,7 @@ async function exportHtml(source: string, tight: boolean): Promise<string> {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export function buildDiagramShareOptions(
|
|
44
|
+
root: BrainUiRoot,
|
|
44
45
|
source: string,
|
|
45
46
|
opts: { filename?: string } = {}
|
|
46
47
|
): ShareOption[] {
|
|
@@ -51,12 +52,12 @@ export function buildDiagramShareOptions(
|
|
|
51
52
|
label: "Image (PNG)",
|
|
52
53
|
hint: "Cropped to the diagram",
|
|
53
54
|
run: async () =>
|
|
54
|
-
renderAndShare({
|
|
55
|
+
renderAndShare(root, {
|
|
55
56
|
content: await exportHtml(source, true),
|
|
56
57
|
contentType: "html",
|
|
57
58
|
format: "png",
|
|
58
59
|
filename,
|
|
59
|
-
title:
|
|
60
|
+
title: root.config.shareTitle,
|
|
60
61
|
}),
|
|
61
62
|
},
|
|
62
63
|
{
|
|
@@ -64,12 +65,12 @@ export function buildDiagramShareOptions(
|
|
|
64
65
|
label: "PDF",
|
|
65
66
|
hint: "Vector PDF, A4",
|
|
66
67
|
run: async () =>
|
|
67
|
-
renderAndShare({
|
|
68
|
+
renderAndShare(root, {
|
|
68
69
|
content: await exportHtml(source, false),
|
|
69
70
|
contentType: "html",
|
|
70
71
|
format: "pdf",
|
|
71
72
|
filename,
|
|
72
|
-
title:
|
|
73
|
+
title: root.config.shareTitle,
|
|
73
74
|
}),
|
|
74
75
|
},
|
|
75
76
|
{
|
|
@@ -78,14 +79,14 @@ export function buildDiagramShareOptions(
|
|
|
78
79
|
hint: "Scales to any size",
|
|
79
80
|
run: async () =>
|
|
80
81
|
shareFile(new File([await exportSvg(source)], `${filename}.svg`, { type: "image/svg+xml" }), {
|
|
81
|
-
title:
|
|
82
|
+
title: root.config.shareTitle,
|
|
82
83
|
}),
|
|
83
84
|
},
|
|
84
85
|
{
|
|
85
86
|
id: "source",
|
|
86
87
|
label: "Mermaid source",
|
|
87
88
|
hint: "Paste into another tool",
|
|
88
|
-
run: () => shareText({ text: source, title:
|
|
89
|
+
run: () => shareText({ text: source, title: root.config.shareTitle }),
|
|
89
90
|
},
|
|
90
91
|
];
|
|
91
92
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useBrainUiRoot } from "../../root-context.js";
|
|
1
2
|
import { useMemo } from "react";
|
|
2
3
|
import { sizeSvgForExport } from "../../lib/mermaid.js";
|
|
3
4
|
import { ShareMenu } from "../share/share-menu.js";
|
|
@@ -23,6 +24,7 @@ export function MermaidViewer({
|
|
|
23
24
|
source: string;
|
|
24
25
|
onClose: () => void;
|
|
25
26
|
}) {
|
|
27
|
+
const root = useBrainUiRoot();
|
|
26
28
|
// Mermaid ships `width: 100%` + `max-width` on the svg, which has no
|
|
27
29
|
// intrinsic size to measure or to scale from. Reuse the export sizer to pin
|
|
28
30
|
// it to its viewBox pixels; the viewer's transform does all the scaling.
|
|
@@ -33,7 +35,7 @@ export function MermaidViewer({
|
|
|
33
35
|
onClose={onClose}
|
|
34
36
|
refitKey={sizedSvg}
|
|
35
37
|
label="Diagram viewer"
|
|
36
|
-
actions={<ShareMenu options={buildDiagramShareOptions(source)} title="Share diagram" />}
|
|
38
|
+
actions={<ShareMenu options={buildDiagramShareOptions(root, source)} title="Share diagram" />}
|
|
37
39
|
>
|
|
38
40
|
<div dangerouslySetInnerHTML={{ __html: sizedSvg }} />
|
|
39
41
|
</ZoomViewer>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useBrainUiRoot } from "../../root-context.js";
|
|
2
2
|
import { memo, useEffect, useRef, useState } from "react";
|
|
3
|
-
import { ChevronDown, Sparkles, Mic, Image as ImageIcon } from "lucide-react";
|
|
4
3
|
import type {
|
|
5
4
|
ChatMessage,
|
|
6
5
|
ToolCall,
|
|
@@ -12,11 +11,14 @@ import { ToolCallTimeline } from "./tool-call-timeline.js";
|
|
|
12
11
|
import { MarkdownContent } from "./markdown-content.js";
|
|
13
12
|
import { linkifyPaths } from "./brain-markdown.js";
|
|
14
13
|
import { AskUserCard } from "./ask-user-card.js";
|
|
15
|
-
import { isAskUserTool } from "../../lib/tool-names.js";
|
|
14
|
+
import { isAskUserTool, isShowBlockTool } from "../../lib/tool-names.js";
|
|
15
|
+
import { BlockCard } from "./tool-cards/block-card.js";
|
|
16
|
+
import { SHOW_BLOCK_CONTRACT, parseToolPayload, type ShowBlockPayload } from "@schlessera/brain-ui-sdk/client";
|
|
16
17
|
import { motion } from "framer-motion";
|
|
17
18
|
import { buildMessageShareOptions } from "./message-share.js";
|
|
18
19
|
import { ShareMenu } from "../share/share-menu.js";
|
|
19
20
|
import { ZoomableImage } from "../images/zoomable-image.js";
|
|
21
|
+
import { AttachmentCount, ThinkingBlock, ThinkingIndicator, TurnHeader, UserTurn } from "./transcript-turn.js";
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
24
|
* One message in the transcript.
|
|
@@ -28,12 +30,18 @@ import { ZoomableImage } from "../images/zoomable-image.js";
|
|
|
28
30
|
*
|
|
29
31
|
* The contract that keeps it working: every callback prop must be stable.
|
|
30
32
|
* ChatPage wraps all three in useCallback for exactly this reason.
|
|
33
|
+
*
|
|
34
|
+
* This is the container (S7): it reads the message, groups its parts and
|
|
35
|
+
* routes the tool timelines, ask cards and markdown; the frame — header,
|
|
36
|
+
* user bubble, thinking disclosure, the streaming dot — is
|
|
37
|
+
* `transcript-turn.tsx`, on the kit.
|
|
31
38
|
*/
|
|
32
39
|
export const MessageBubble = memo(function MessageBubble({
|
|
33
40
|
message,
|
|
34
41
|
onToolApproval,
|
|
35
42
|
onAskUserSubmit,
|
|
36
43
|
onAskUserCancel,
|
|
44
|
+
onAskUserReask,
|
|
37
45
|
}: {
|
|
38
46
|
message: ChatMessage;
|
|
39
47
|
onToolApproval: (toolUseId: string, approved: boolean) => void;
|
|
@@ -43,7 +51,10 @@ export const MessageBubble = memo(function MessageBubble({
|
|
|
43
51
|
annotations?: Record<string, AskUserAnnotation>
|
|
44
52
|
) => void;
|
|
45
53
|
onAskUserCancel: (requestId: string) => void;
|
|
54
|
+
/** A dismissed question asked again answers by composer message. */
|
|
55
|
+
onAskUserReask?: (text: string) => void;
|
|
46
56
|
}) {
|
|
57
|
+
const root = useBrainUiRoot();
|
|
47
58
|
const isUser = message.role === "user";
|
|
48
59
|
|
|
49
60
|
return (
|
|
@@ -53,53 +64,30 @@ export const MessageBubble = memo(function MessageBubble({
|
|
|
53
64
|
transition={{ duration: 0.2, ease: "easeOut" }}
|
|
54
65
|
className="py-4"
|
|
55
66
|
>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
: "select-none font-[family-name:var(--font-mono)] text-xs font-semibold uppercase tracking-widest text-accent/80"
|
|
63
|
-
}
|
|
64
|
-
>
|
|
65
|
-
{isUser ? "You" : uiConfig.assistantName}
|
|
66
|
-
</span>
|
|
67
|
-
<div className="h-px flex-1 bg-border/40" />
|
|
68
|
-
{isUser && message.source && message.source !== "typed" && (
|
|
69
|
-
<Mic
|
|
70
|
-
className={
|
|
71
|
-
message.source === "voice-conversation"
|
|
72
|
-
? "h-3 w-3 text-primary/70"
|
|
73
|
-
: "h-3 w-3 text-primary/50"
|
|
74
|
-
}
|
|
75
|
-
aria-label={
|
|
76
|
-
message.source === "voice-conversation"
|
|
77
|
-
? "Voice conversation"
|
|
78
|
-
: "Voice dictation"
|
|
79
|
-
}
|
|
80
|
-
/>
|
|
81
|
-
)}
|
|
82
|
-
<span className="font-[family-name:var(--font-mono)] text-[10px] text-muted-foreground/40">
|
|
83
|
-
{formatTime(message.timestamp)}
|
|
84
|
-
</span>
|
|
85
|
-
</div>
|
|
67
|
+
<TurnHeader
|
|
68
|
+
who={isUser ? "You" : root.config.assistantName}
|
|
69
|
+
when={formatTime(message.timestamp)}
|
|
70
|
+
voice={isUser && message.source && message.source !== "typed" ? message.source : undefined}
|
|
71
|
+
tone={isUser ? "user" : "brain"}
|
|
72
|
+
/>
|
|
86
73
|
|
|
87
74
|
{/* Content */}
|
|
88
75
|
{isUser ? (
|
|
89
|
-
<
|
|
76
|
+
<UserTurn>
|
|
90
77
|
<UserAttachments message={message} />
|
|
91
78
|
{message.content && (
|
|
92
79
|
<div className="chat-message-body text-sm leading-relaxed text-foreground whitespace-pre-wrap">
|
|
93
80
|
{linkifyPaths(message.content)}
|
|
94
81
|
</div>
|
|
95
82
|
)}
|
|
96
|
-
</
|
|
83
|
+
</UserTurn>
|
|
97
84
|
) : (
|
|
98
85
|
<AssistantContent
|
|
99
86
|
message={message}
|
|
100
87
|
onToolApproval={onToolApproval}
|
|
101
88
|
onAskUserSubmit={onAskUserSubmit}
|
|
102
89
|
onAskUserCancel={onAskUserCancel}
|
|
90
|
+
onAskUserReask={onAskUserReask}
|
|
103
91
|
/>
|
|
104
92
|
)}
|
|
105
93
|
</motion.div>
|
|
@@ -131,12 +119,7 @@ function UserAttachments({ message }: { message: ChatMessage }) {
|
|
|
131
119
|
}
|
|
132
120
|
|
|
133
121
|
if (message.attachmentCount && message.attachmentCount > 0) {
|
|
134
|
-
return
|
|
135
|
-
<div className="inline-flex items-center gap-1.5 rounded-lg border border-border/40 bg-surface/50 px-2.5 py-1 text-xs text-muted-foreground">
|
|
136
|
-
<ImageIcon className="h-3.5 w-3.5" />
|
|
137
|
-
{message.attachmentCount} image{message.attachmentCount === 1 ? "" : "s"}
|
|
138
|
-
</div>
|
|
139
|
-
);
|
|
122
|
+
return <AttachmentCount count={message.attachmentCount} />;
|
|
140
123
|
}
|
|
141
124
|
|
|
142
125
|
return null;
|
|
@@ -149,9 +132,10 @@ function UserAttachments({ message }: { message: ChatMessage }) {
|
|
|
149
132
|
*/
|
|
150
133
|
type PartGroup =
|
|
151
134
|
| { kind: "thinking"; text: string; isLast: boolean }
|
|
152
|
-
| { kind: "text"; text: string; isLast: boolean; isLastText: boolean }
|
|
135
|
+
| { kind: "text"; text: string; isLast: boolean; isLastText: boolean; textIndex: number }
|
|
153
136
|
| { kind: "tools"; toolCalls: ToolCall[]; isLast: boolean }
|
|
154
|
-
| { kind: "askUser"; exchange: AskUserExchange; isLast: boolean }
|
|
137
|
+
| { kind: "askUser"; exchange: AskUserExchange; isLast: boolean }
|
|
138
|
+
| { kind: "block"; payload: ShowBlockPayload; isLast: boolean };
|
|
155
139
|
|
|
156
140
|
function groupParts(
|
|
157
141
|
parts: MessagePart[],
|
|
@@ -163,6 +147,8 @@ function groupParts(
|
|
|
163
147
|
// to its exchange and renders as its own AskUserCard at that chronological
|
|
164
148
|
// spot, so it collapses and scrolls away like the surrounding events.
|
|
165
149
|
let askUserSeen = 0;
|
|
150
|
+
// Ordinal among TEXT parts: classified blocks (D42) are anchored to it.
|
|
151
|
+
let textSeen = 0;
|
|
166
152
|
for (const part of parts) {
|
|
167
153
|
if (part.kind === "tool") {
|
|
168
154
|
const tool = toolCalls[part.toolIndex];
|
|
@@ -176,6 +162,17 @@ function groupParts(
|
|
|
176
162
|
}
|
|
177
163
|
continue;
|
|
178
164
|
}
|
|
165
|
+
if (isShowBlockTool(tool.name)) {
|
|
166
|
+
// A block is part of the answer, not a step in the trace (D41): it
|
|
167
|
+
// renders inline where it was called. Until the echo arrives, and
|
|
168
|
+
// when it does not parse (a rejected call, an older server), the
|
|
169
|
+
// call stays in the timeline, where its bound fallback states why.
|
|
170
|
+
const payload = parseToolPayload(SHOW_BLOCK_CONTRACT, tool.output);
|
|
171
|
+
if (payload) {
|
|
172
|
+
groups.push({ kind: "block", payload, isLast: false });
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
179
176
|
const last = groups[groups.length - 1];
|
|
180
177
|
if (last?.kind === "tools") {
|
|
181
178
|
last.toolCalls.push(tool);
|
|
@@ -183,7 +180,14 @@ function groupParts(
|
|
|
183
180
|
groups.push({ kind: "tools", toolCalls: [tool], isLast: false });
|
|
184
181
|
}
|
|
185
182
|
} else if (part.text.trim()) {
|
|
186
|
-
|
|
183
|
+
if (part.kind === "text") {
|
|
184
|
+
groups.push({ kind: "text", text: part.text, isLast: false, isLastText: false, textIndex: textSeen++ });
|
|
185
|
+
} else {
|
|
186
|
+
groups.push({ kind: "thinking", text: part.text, isLast: false });
|
|
187
|
+
}
|
|
188
|
+
} else if (part.kind === "text") {
|
|
189
|
+
// An all-whitespace text part still counts toward the ordinal.
|
|
190
|
+
textSeen++;
|
|
187
191
|
}
|
|
188
192
|
}
|
|
189
193
|
const last = groups[groups.length - 1];
|
|
@@ -198,11 +202,19 @@ function groupParts(
|
|
|
198
202
|
return groups;
|
|
199
203
|
}
|
|
200
204
|
|
|
205
|
+
/** The classified blocks anchored to the n-th text part, or nothing. */
|
|
206
|
+
function blocksFor(message: ChatMessage, textIndex: number) {
|
|
207
|
+
if (!message.blocks || message.blocks.length === 0) return undefined;
|
|
208
|
+
const own = message.blocks.filter((b) => b.partIndex === textIndex);
|
|
209
|
+
return own.length ? own : undefined;
|
|
210
|
+
}
|
|
211
|
+
|
|
201
212
|
function AssistantContent({
|
|
202
213
|
message,
|
|
203
214
|
onToolApproval,
|
|
204
215
|
onAskUserSubmit,
|
|
205
216
|
onAskUserCancel,
|
|
217
|
+
onAskUserReask,
|
|
206
218
|
}: {
|
|
207
219
|
message: ChatMessage;
|
|
208
220
|
onToolApproval: (toolUseId: string, approved: boolean) => void;
|
|
@@ -212,12 +224,15 @@ function AssistantContent({
|
|
|
212
224
|
annotations?: Record<string, AskUserAnnotation>
|
|
213
225
|
) => void;
|
|
214
226
|
onAskUserCancel: (requestId: string) => void;
|
|
227
|
+
/** A dismissed question asked again answers by composer message. */
|
|
228
|
+
onAskUserReask?: (text: string) => void;
|
|
215
229
|
}) {
|
|
230
|
+
const root = useBrainUiRoot();
|
|
216
231
|
const contentRef = useRef<HTMLDivElement>(null);
|
|
217
232
|
const showShare =
|
|
218
233
|
!message.isStreaming && !!message.content && message.content.trim().length > 0;
|
|
219
234
|
const shareOptions = showShare
|
|
220
|
-
? buildMessageShareOptions({
|
|
235
|
+
? buildMessageShareOptions(root, {
|
|
221
236
|
content: message.content,
|
|
222
237
|
renderedRef: contentRef,
|
|
223
238
|
})
|
|
@@ -263,6 +278,8 @@ function AssistantContent({
|
|
|
263
278
|
live={message.isStreaming}
|
|
264
279
|
/>
|
|
265
280
|
);
|
|
281
|
+
case "block":
|
|
282
|
+
return <BlockCard key={i} {...group.payload} />;
|
|
266
283
|
case "askUser":
|
|
267
284
|
return (
|
|
268
285
|
<AskUserCard
|
|
@@ -271,9 +288,11 @@ function AssistantContent({
|
|
|
271
288
|
questions={group.exchange.questions}
|
|
272
289
|
answered={group.exchange.answers}
|
|
273
290
|
cancelled={group.exchange.cancelled}
|
|
274
|
-
|
|
291
|
+
typed={group.exchange.typed}
|
|
292
|
+
answeredAt={group.exchange.answeredAt}
|
|
275
293
|
onSubmit={onAskUserSubmit}
|
|
276
294
|
onCancel={onAskUserCancel}
|
|
295
|
+
onReask={onAskUserReask}
|
|
277
296
|
/>
|
|
278
297
|
);
|
|
279
298
|
case "text":
|
|
@@ -285,7 +304,7 @@ function AssistantContent({
|
|
|
285
304
|
wrapper: content-visibility implies paint containment,
|
|
286
305
|
which would clip a dropdown that opens past the box. */}
|
|
287
306
|
<div className="chat-message-body">
|
|
288
|
-
<MarkdownContent content={group.text} />
|
|
307
|
+
<MarkdownContent content={group.text} blocks={blocksFor(message, group.textIndex)} />
|
|
289
308
|
</div>
|
|
290
309
|
{showShare && shareOptions.length > 0 && (
|
|
291
310
|
<div className="mt-1 flex justify-end opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100">
|
|
@@ -295,7 +314,7 @@ function AssistantContent({
|
|
|
295
314
|
</div>
|
|
296
315
|
) : (
|
|
297
316
|
<div key={i} className="chat-message-body">
|
|
298
|
-
<MarkdownContent content={group.text} />
|
|
317
|
+
<MarkdownContent content={group.text} blocks={blocksFor(message, group.textIndex)} />
|
|
299
318
|
</div>
|
|
300
319
|
);
|
|
301
320
|
}
|
|
@@ -308,21 +327,15 @@ function AssistantContent({
|
|
|
308
327
|
questions={ex.questions}
|
|
309
328
|
answered={ex.answers}
|
|
310
329
|
cancelled={ex.cancelled}
|
|
311
|
-
|
|
330
|
+
typed={ex.typed}
|
|
331
|
+
answeredAt={ex.answeredAt}
|
|
312
332
|
onSubmit={onAskUserSubmit}
|
|
313
333
|
onCancel={onAskUserCancel}
|
|
334
|
+
onReask={onAskUserReask}
|
|
314
335
|
/>
|
|
315
336
|
))}
|
|
316
337
|
|
|
317
|
-
{message.isStreaming && groups.length === 0 && unmatchedExchanges.length === 0 &&
|
|
318
|
-
<div className="flex items-center gap-2 text-xs text-muted-foreground">
|
|
319
|
-
<span
|
|
320
|
-
className="inline-block h-1.5 w-1.5 rounded-full bg-primary"
|
|
321
|
-
style={{ animation: "breathe 2s ease-in-out infinite" }}
|
|
322
|
-
/>
|
|
323
|
-
Thinking...
|
|
324
|
-
</div>
|
|
325
|
-
)}
|
|
338
|
+
{message.isStreaming && groups.length === 0 && unmatchedExchanges.length === 0 && <ThinkingIndicator />}
|
|
326
339
|
</div>
|
|
327
340
|
);
|
|
328
341
|
}
|
|
@@ -344,43 +357,14 @@ function ThinkingSection({
|
|
|
344
357
|
prevStreaming.current = isStreaming;
|
|
345
358
|
}, [isStreaming]);
|
|
346
359
|
|
|
347
|
-
if (!isStreaming && !expanded) {
|
|
348
|
-
// Collapsed: minimal clickable text
|
|
349
|
-
const estimatedTokens = Math.round(content.length / 4);
|
|
350
|
-
return (
|
|
351
|
-
<button
|
|
352
|
-
onClick={() => setExpanded(true)}
|
|
353
|
-
className="flex items-center gap-1.5 text-xs text-muted-foreground/50 transition-colors hover:text-muted-foreground"
|
|
354
|
-
>
|
|
355
|
-
<Sparkles className="h-3 w-3" />
|
|
356
|
-
<span className="font-[family-name:var(--font-mono)]">
|
|
357
|
-
Thought for ~{estimatedTokens} tokens
|
|
358
|
-
</span>
|
|
359
|
-
<ChevronDown className="h-3 w-3" />
|
|
360
|
-
</button>
|
|
361
|
-
);
|
|
362
|
-
}
|
|
363
|
-
|
|
364
360
|
return (
|
|
365
|
-
<
|
|
366
|
-
{
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
</button>
|
|
373
|
-
)}
|
|
374
|
-
<div className="font-[family-name:var(--font-mono)] text-xs leading-relaxed text-muted-foreground/60 italic whitespace-pre-wrap">
|
|
375
|
-
{linkifyPaths(content)}
|
|
376
|
-
{isStreaming && (
|
|
377
|
-
<span
|
|
378
|
-
className="inline-block h-1.5 w-1.5 rounded-full bg-primary ml-1"
|
|
379
|
-
style={{ animation: "breathe 2s ease-in-out infinite" }}
|
|
380
|
-
/>
|
|
381
|
-
)}
|
|
382
|
-
</div>
|
|
383
|
-
</div>
|
|
361
|
+
<ThinkingBlock
|
|
362
|
+
content={linkifyPaths(content)}
|
|
363
|
+
chars={content.length}
|
|
364
|
+
streaming={isStreaming}
|
|
365
|
+
open={expanded}
|
|
366
|
+
onOpenChange={setExpanded}
|
|
367
|
+
/>
|
|
384
368
|
);
|
|
385
369
|
}
|
|
386
370
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BrainUiRoot } from "../../root.js";
|
|
2
2
|
import type { RefObject } from "react";
|
|
3
3
|
import { renderAndShare, shareFile, shareText, copyRichText } from "../../lib/share.js";
|
|
4
4
|
import { stripMarkdown } from "../../lib/strip-markdown.js";
|
|
@@ -11,7 +11,7 @@ interface BuildOpts {
|
|
|
11
11
|
renderedRef: RefObject<HTMLElement | null>;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export function buildMessageShareOptions({ content, renderedRef }: BuildOpts): ShareOption[] {
|
|
14
|
+
export function buildMessageShareOptions(root: BrainUiRoot, { content, renderedRef }: BuildOpts): ShareOption[] {
|
|
15
15
|
const plain = () => stripMarkdown(content);
|
|
16
16
|
|
|
17
17
|
return [
|
|
@@ -20,14 +20,14 @@ export function buildMessageShareOptions({ content, renderedRef }: BuildOpts): S
|
|
|
20
20
|
label: "Image (PNG)",
|
|
21
21
|
hint: "Rendered snapshot",
|
|
22
22
|
run: async () =>
|
|
23
|
-
renderAndShare({
|
|
23
|
+
renderAndShare(root, {
|
|
24
24
|
// The render page runs without JavaScript, so mermaid fences are
|
|
25
25
|
// pre-rendered to inline SVG here on the client.
|
|
26
26
|
content: await inlineMermaidDiagrams(content),
|
|
27
27
|
contentType: "markdown",
|
|
28
28
|
format: "png",
|
|
29
29
|
filename: "message",
|
|
30
|
-
title:
|
|
30
|
+
title: root.config.shareTitle,
|
|
31
31
|
}),
|
|
32
32
|
},
|
|
33
33
|
{
|
|
@@ -35,12 +35,12 @@ export function buildMessageShareOptions({ content, renderedRef }: BuildOpts): S
|
|
|
35
35
|
label: "PDF",
|
|
36
36
|
hint: "Vector PDF, A4",
|
|
37
37
|
run: async () =>
|
|
38
|
-
renderAndShare({
|
|
38
|
+
renderAndShare(root, {
|
|
39
39
|
content: await inlineMermaidDiagrams(content),
|
|
40
40
|
contentType: "markdown",
|
|
41
41
|
format: "pdf",
|
|
42
42
|
filename: "message",
|
|
43
|
-
title:
|
|
43
|
+
title: root.config.shareTitle,
|
|
44
44
|
}),
|
|
45
45
|
},
|
|
46
46
|
{
|
|
@@ -55,7 +55,7 @@ export function buildMessageShareOptions({ content, renderedRef }: BuildOpts): S
|
|
|
55
55
|
hint: "Raw markdown verbatim",
|
|
56
56
|
run: () =>
|
|
57
57
|
shareFile(new File([content], "message.md", { type: "text/markdown" }), {
|
|
58
|
-
title:
|
|
58
|
+
title: root.config.shareTitle,
|
|
59
59
|
}),
|
|
60
60
|
},
|
|
61
61
|
{
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `bind(contract, Component)` — the client half of D3.
|
|
3
|
+
*
|
|
4
|
+
* The contract owns the payload schema; the component is typed
|
|
5
|
+
* `ToolPayload<contract>`, so a component that reads a field the tool stopped
|
|
6
|
+
* sending is a `tsc` error rather than an empty line in a chat log. At runtime
|
|
7
|
+
* the payload is parsed through the same schema, and a result that does not
|
|
8
|
+
* parse falls through to the caller's fallback view instead of throwing: the
|
|
9
|
+
* work already happened and the reader still wants to see it.
|
|
10
|
+
*
|
|
11
|
+
* One contract produces several renderers, because the same tool has a
|
|
12
|
+
* different name on each backend — `mcp__brain-ui__x` on Claude, bare `x` on
|
|
13
|
+
* pi, plus the pre-rename `mcp__brain_ui__x` that old transcripts carry. The
|
|
14
|
+
* timeline resolves on the raw streamed name, so all three are registered
|
|
15
|
+
* globally rather than scoped to one backend.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { ComponentType } from "react";
|
|
19
|
+
import {
|
|
20
|
+
parseToolPayload,
|
|
21
|
+
visibleToolName,
|
|
22
|
+
type ToolCallView,
|
|
23
|
+
type ToolComponentContract,
|
|
24
|
+
type ToolPayload,
|
|
25
|
+
type ToolRenderer,
|
|
26
|
+
} from "@schlessera/brain-ui-sdk/client";
|
|
27
|
+
|
|
28
|
+
/** Pre-rename MCP server prefix, still present in resumed transcripts. */
|
|
29
|
+
const LEGACY_MCP_PREFIX = "mcp__brain_ui__";
|
|
30
|
+
|
|
31
|
+
/** Every spelling of a contract's tool name that can arrive in the stream. */
|
|
32
|
+
export function boundToolNames(contract: ToolComponentContract): string[] {
|
|
33
|
+
return [
|
|
34
|
+
visibleToolName(contract.name, "pi"),
|
|
35
|
+
visibleToolName(contract.name, "claude"),
|
|
36
|
+
`${LEGACY_MCP_PREFIX}${contract.name}`,
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface BindOptions<Contract extends ToolComponentContract> {
|
|
41
|
+
icon?: ToolRenderer["icon"];
|
|
42
|
+
label?: string;
|
|
43
|
+
/** Collapsed one-liner, from the parsed payload. */
|
|
44
|
+
summary?: (payload: ToolPayload<Contract>, tool: ToolCallView) => string | null;
|
|
45
|
+
/** Secondary metadata line, from the parsed payload. */
|
|
46
|
+
meta?: (payload: ToolPayload<Contract>, tool: ToolCallView) => string | null;
|
|
47
|
+
/** Input view; the contract does not type this, the tool's own input does. */
|
|
48
|
+
Input?: ToolRenderer["Input"];
|
|
49
|
+
/**
|
|
50
|
+
* Rendered when the output is absent, is prose, or fails the payload schema
|
|
51
|
+
* — an errored call, an older server, a tool that answered with a message.
|
|
52
|
+
*/
|
|
53
|
+
Fallback?: ComponentType<{ tool: ToolCallView }>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function bind<Contract extends ToolComponentContract>(
|
|
57
|
+
contract: Contract,
|
|
58
|
+
Component: ComponentType<ToolPayload<Contract>>,
|
|
59
|
+
options: BindOptions<Contract> = {}
|
|
60
|
+
): ToolRenderer[] {
|
|
61
|
+
const { Fallback } = options;
|
|
62
|
+
|
|
63
|
+
// TS cannot spread an unresolved generic into JSX, so the spread — and only
|
|
64
|
+
// the spread — goes through an untyped alias. The public parameter above is
|
|
65
|
+
// what carries the guarantee: `Component` must accept the contract's payload.
|
|
66
|
+
const Spread = Component as ComponentType<Record<string, unknown>>;
|
|
67
|
+
|
|
68
|
+
function Output({ tool }: { tool: ToolCallView }) {
|
|
69
|
+
const payload = parseToolPayload(contract, tool.output);
|
|
70
|
+
if (payload === null) return Fallback ? <Fallback tool={tool} /> : null;
|
|
71
|
+
return <Spread {...(payload as Record<string, unknown>)} />;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function fromPayload(
|
|
75
|
+
read: ((payload: ToolPayload<Contract>, tool: ToolCallView) => string | null) | undefined
|
|
76
|
+
): ((tool: ToolCallView) => string | null) | undefined {
|
|
77
|
+
if (!read) return undefined;
|
|
78
|
+
return (tool: ToolCallView) => {
|
|
79
|
+
const payload = parseToolPayload(contract, tool.output);
|
|
80
|
+
return payload === null ? null : read(payload, tool);
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const renderer: Omit<ToolRenderer, "match"> = {
|
|
85
|
+
...(options.icon ? { icon: options.icon } : {}),
|
|
86
|
+
...(options.label ? { label: options.label } : {}),
|
|
87
|
+
...(options.summary ? { summary: fromPayload(options.summary)! } : {}),
|
|
88
|
+
...(options.meta ? { meta: fromPayload(options.meta)! } : {}),
|
|
89
|
+
...(options.Input ? { Input: options.Input } : {}),
|
|
90
|
+
Output,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return boundToolNames(contract).map((match) => ({ match, ...renderer }));
|
|
94
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// The chat UI's own in-process tools, rendered from their contracts.
|
|
2
|
+
//
|
|
3
|
+
// Unlike the per-backend packs, this one is GLOBAL: the same contract is
|
|
4
|
+
// exposed by every backend under that backend's spelling of the name, so
|
|
5
|
+
// `bind()` registers each spelling and resolution does not depend on which
|
|
6
|
+
// backend owns the session. That also fixes a real gap — the location result
|
|
7
|
+
// only ever had a renderer under Claude's MCP-prefixed name, so the identical
|
|
8
|
+
// tool on pi fell through to the generic JSON view.
|
|
9
|
+
|
|
10
|
+
import type { RendererPack } from "@schlessera/brain-ui-sdk/client";
|
|
11
|
+
import {
|
|
12
|
+
GET_CURRENT_LOCATION_CONTRACT,
|
|
13
|
+
REQUEST_IMAGE_MASK_CONTRACT,
|
|
14
|
+
SHOW_BLOCK_CONTRACT,
|
|
15
|
+
} from "@schlessera/brain-ui-sdk/client";
|
|
16
|
+
import { LayoutGrid, MapPin, Scissors } from "lucide-react";
|
|
17
|
+
import { BlockCard, blockSummary } from "../tool-cards/block-card.js";
|
|
18
|
+
import { LocationResultCard } from "../tool-cards/location-card.js";
|
|
19
|
+
import { ImageMaskResultCard, ImageMaskFallback } from "../tool-cards/image-mask-card.js";
|
|
20
|
+
import { ClampedPre } from "../tool-views.js";
|
|
21
|
+
import { bind } from "./bind.js";
|
|
22
|
+
|
|
23
|
+
export const brainUiToolPack: RendererPack = {
|
|
24
|
+
renderers: [
|
|
25
|
+
...bind(GET_CURRENT_LOCATION_CONTRACT, LocationResultCard, {
|
|
26
|
+
icon: MapPin,
|
|
27
|
+
label: "Location",
|
|
28
|
+
summary: (payload) => payload.place ?? payload.address ?? null,
|
|
29
|
+
meta: (payload) => `±${Math.round(payload.accuracyMeters)} m`,
|
|
30
|
+
// A denial, a timeout or a browser without geolocation answers with a
|
|
31
|
+
// message, not a payload — the reader needs to see WHY there is no fix.
|
|
32
|
+
Fallback: ({ tool }) =>
|
|
33
|
+
tool.output ? <ClampedPre text={tool.output} isError={tool.isError} /> : null,
|
|
34
|
+
}),
|
|
35
|
+
...bind(REQUEST_IMAGE_MASK_CONTRACT, ImageMaskResultCard, {
|
|
36
|
+
icon: Scissors,
|
|
37
|
+
label: "Mask",
|
|
38
|
+
summary: (payload) => payload.imagePath,
|
|
39
|
+
meta: (payload) => `mask ${payload.maskPath}`,
|
|
40
|
+
// A declined mask is an error with a message, not a payload. The fact
|
|
41
|
+
// belongs in the transcript in red, from the result's own words.
|
|
42
|
+
Fallback: ImageMaskFallback,
|
|
43
|
+
}),
|
|
44
|
+
// Rendered inline at the call's position by the transcript, not in the
|
|
45
|
+
// timeline; this binding is what the timeline uses when the payload does
|
|
46
|
+
// not parse (a rejected call, an older server), so the fact reaches the
|
|
47
|
+
// reader in the result's own words rather than as a blank.
|
|
48
|
+
...bind(SHOW_BLOCK_CONTRACT, BlockCard, {
|
|
49
|
+
icon: LayoutGrid,
|
|
50
|
+
label: "Block",
|
|
51
|
+
summary: (payload) => blockSummary(payload),
|
|
52
|
+
Fallback: ({ tool }) =>
|
|
53
|
+
tool.output ? <ClampedPre text={tool.output} isError={tool.isError} /> : null,
|
|
54
|
+
}),
|
|
55
|
+
],
|
|
56
|
+
};
|
|
@@ -10,7 +10,6 @@ import type {
|
|
|
10
10
|
ToolSemantics,
|
|
11
11
|
} from "@schlessera/brain-ui-sdk/client";
|
|
12
12
|
import type { ToolCall } from "../../../stores/chat-store.js";
|
|
13
|
-
import { GET_LOCATION_TOOL_NAME } from "../../../lib/tool-names.js";
|
|
14
13
|
import {
|
|
15
14
|
getToolIcon,
|
|
16
15
|
getToolSummary,
|
|
@@ -34,7 +33,9 @@ const CLAUDE_TOOL_NAMES = [
|
|
|
34
33
|
"Skill",
|
|
35
34
|
"NotebookEdit",
|
|
36
35
|
"LSP",
|
|
37
|
-
|
|
36
|
+
// `mcp__brain-ui__get_current_location` is deliberately NOT here: it is one
|
|
37
|
+
// of the chat UI's own contract-bound tools (`brain-ui-tools.tsx`), and a
|
|
38
|
+
// backend-scoped entry would beat that global renderer.
|
|
38
39
|
];
|
|
39
40
|
|
|
40
41
|
// The shared views read brain-ui's richer ToolCall (status, inputJson, timing).
|