@opengeni/react 3.1.0 → 3.1.3-canary.38890816741001
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 +769 -22
- package/dist/accounts.js +89 -11
- package/dist/accounts.js.map +1 -1
- package/dist/approvals.d.ts +2 -1
- package/dist/artifacts-document.js +5 -3
- package/dist/artifacts-presentation.js +5 -3
- package/dist/artifacts-spreadsheet.d.ts +1 -1
- package/dist/artifacts-spreadsheet.js +5 -3
- package/dist/artifacts.d.ts +5 -1
- package/dist/artifacts.js +536 -42
- package/dist/artifacts.js.map +1 -1
- package/dist/browser-viewer-ZWR6MWJ7.js +19 -0
- package/dist/capability-catalog-row.d.ts +20 -0
- package/dist/capability-logo-fallback.d.ts +3 -0
- package/dist/chat-interactive-block-BO2IWXVK.js +14 -0
- package/dist/chunk-2DDJ6YH6.js +41 -0
- package/dist/chunk-2DDJ6YH6.js.map +1 -0
- package/dist/chunk-2HVLQ26H.js +183 -0
- package/dist/chunk-2HVLQ26H.js.map +1 -0
- package/dist/{chunk-RGALCTWO.js → chunk-2I6R3GCZ.js} +4285 -3980
- package/dist/chunk-2I6R3GCZ.js.map +1 -0
- package/dist/{chunk-D3UIAJKY.js → chunk-2SFFYIH3.js} +1179 -166
- package/dist/chunk-2SFFYIH3.js.map +1 -0
- package/dist/chunk-3PVDYTTB.js +24 -0
- package/dist/chunk-3PVDYTTB.js.map +1 -0
- package/dist/chunk-3UZCWK46.js +298 -0
- package/dist/chunk-3UZCWK46.js.map +1 -0
- package/dist/chunk-47CKUXTW.js +293 -0
- package/dist/chunk-47CKUXTW.js.map +1 -0
- package/dist/chunk-4QYP6QUI.js +109 -0
- package/dist/chunk-4QYP6QUI.js.map +1 -0
- package/dist/chunk-5EY26VZ7.js +1053 -0
- package/dist/chunk-5EY26VZ7.js.map +1 -0
- package/dist/chunk-5I4VRWBB.js +56 -0
- package/dist/chunk-5I4VRWBB.js.map +1 -0
- package/dist/chunk-5WOR7UCL.js +191 -0
- package/dist/chunk-5WOR7UCL.js.map +1 -0
- package/dist/chunk-5YJLGOM5.js +51 -0
- package/dist/chunk-5YJLGOM5.js.map +1 -0
- package/dist/chunk-6JFN3OWG.js +386 -0
- package/dist/chunk-6JFN3OWG.js.map +1 -0
- package/dist/chunk-7QJT5O4S.js +35 -0
- package/dist/chunk-7QJT5O4S.js.map +1 -0
- package/dist/chunk-A55KV72M.js +402 -0
- package/dist/chunk-A55KV72M.js.map +1 -0
- package/dist/chunk-ADWCLI4G.js +2028 -0
- package/dist/chunk-ADWCLI4G.js.map +1 -0
- package/dist/chunk-B27E3V37.js +29 -0
- package/dist/chunk-B27E3V37.js.map +1 -0
- package/dist/chunk-B7TC2A33.js +83 -0
- package/dist/chunk-B7TC2A33.js.map +1 -0
- package/dist/chunk-BLL56F7R.js +385 -0
- package/dist/chunk-BLL56F7R.js.map +1 -0
- package/dist/chunk-BOFEQC6K.js +162 -0
- package/dist/chunk-BOFEQC6K.js.map +1 -0
- package/dist/chunk-CM7LVUKC.js +35 -0
- package/dist/chunk-CM7LVUKC.js.map +1 -0
- package/dist/chunk-CORUP6JB.js +122 -0
- package/dist/chunk-CORUP6JB.js.map +1 -0
- package/dist/chunk-CSX5FFKZ.js +35 -0
- package/dist/chunk-CSX5FFKZ.js.map +1 -0
- package/dist/chunk-EGVHJKGJ.js +3125 -0
- package/dist/chunk-EGVHJKGJ.js.map +1 -0
- package/dist/{chunk-NEXLLTP4.js → chunk-G76LSA76.js} +6 -5
- package/dist/chunk-G76LSA76.js.map +1 -0
- package/dist/{chunk-PEI6RANI.js → chunk-GQMRL52F.js} +311 -75
- package/dist/chunk-GQMRL52F.js.map +1 -0
- package/dist/{chunk-ELIYWBZR.js → chunk-GUUXOISA.js} +1113 -457
- package/dist/chunk-GUUXOISA.js.map +1 -0
- package/dist/{chunk-HUIKIDM5.js → chunk-I7X2P4FU.js} +225 -116
- package/dist/chunk-I7X2P4FU.js.map +1 -0
- package/dist/chunk-IGFZFLI2.js +1390 -0
- package/dist/chunk-IGFZFLI2.js.map +1 -0
- package/dist/{chunk-4MDLEHXL.js → chunk-IMSUVYQB.js} +26 -13
- package/dist/chunk-IMSUVYQB.js.map +1 -0
- package/dist/chunk-IOYHDEP3.js +38 -0
- package/dist/chunk-IOYHDEP3.js.map +1 -0
- package/dist/chunk-IZV5FTJC.js +55 -0
- package/dist/chunk-IZV5FTJC.js.map +1 -0
- package/dist/chunk-KF33GTWN.js +343 -0
- package/dist/chunk-KF33GTWN.js.map +1 -0
- package/dist/chunk-KSGQ5ODA.js +457 -0
- package/dist/chunk-KSGQ5ODA.js.map +1 -0
- package/dist/{chunk-OAM4WAAM.js → chunk-KZC6QRNR.js} +1513 -697
- package/dist/chunk-KZC6QRNR.js.map +1 -0
- package/dist/chunk-LJUMYUBO.js +218 -0
- package/dist/chunk-LJUMYUBO.js.map +1 -0
- package/dist/chunk-LSW2OJVV.js +380 -0
- package/dist/chunk-LSW2OJVV.js.map +1 -0
- package/dist/chunk-M357MHH3.js +2 -0
- package/dist/chunk-M357MHH3.js.map +1 -0
- package/dist/chunk-MK2TQO4Y.js +24 -0
- package/dist/chunk-MK2TQO4Y.js.map +1 -0
- package/dist/chunk-N7S72EXK.js +25 -0
- package/dist/chunk-N7S72EXK.js.map +1 -0
- package/dist/{chunk-XXWH2JLC.js → chunk-NKMYZFHA.js} +616 -621
- package/dist/chunk-NKMYZFHA.js.map +1 -0
- package/dist/chunk-NX4ADH73.js +14 -0
- package/dist/chunk-NX4ADH73.js.map +1 -0
- package/dist/chunk-O7F6UJO4.js +71 -0
- package/dist/chunk-O7F6UJO4.js.map +1 -0
- package/dist/chunk-OVB5WIG5.js +14064 -0
- package/dist/chunk-OVB5WIG5.js.map +1 -0
- package/dist/chunk-OYQQJL3J.js +16 -0
- package/dist/chunk-OYQQJL3J.js.map +1 -0
- package/dist/{chunk-H5YGYNXS.js → chunk-P4BNUO57.js} +60 -17
- package/dist/chunk-P4BNUO57.js.map +1 -0
- package/dist/{chunk-JVYQRRC4.js → chunk-PEHTX3V7.js} +21 -1
- package/dist/chunk-PEHTX3V7.js.map +1 -0
- package/dist/chunk-PMV53IMM.js +26 -0
- package/dist/chunk-PMV53IMM.js.map +1 -0
- package/dist/{chunk-KCGXPP5V.js → chunk-PYEOPA4M.js} +13 -7
- package/dist/chunk-PYEOPA4M.js.map +1 -0
- package/dist/{chunk-KZ73RL76.js → chunk-QHUE7E4N.js} +8 -3
- package/dist/chunk-QHUE7E4N.js.map +1 -0
- package/dist/chunk-QV3DJVRZ.js +11 -0
- package/dist/chunk-QV3DJVRZ.js.map +1 -0
- package/dist/chunk-R5SBNG7S.js +810 -0
- package/dist/chunk-R5SBNG7S.js.map +1 -0
- package/dist/chunk-RI42H5IU.js +326 -0
- package/dist/chunk-RI42H5IU.js.map +1 -0
- package/dist/chunk-S2QH6EZ5.js +211 -0
- package/dist/chunk-S2QH6EZ5.js.map +1 -0
- package/dist/chunk-SHLZMAJN.js +304 -0
- package/dist/chunk-SHLZMAJN.js.map +1 -0
- package/dist/chunk-TGXK4BAZ.js +293 -0
- package/dist/chunk-TGXK4BAZ.js.map +1 -0
- package/dist/{chunk-5YK2ZDIG.js → chunk-TNEZNMSN.js} +4 -10
- package/dist/chunk-TNEZNMSN.js.map +1 -0
- package/dist/{chunk-22KP6LR5.js → chunk-TXS65BB2.js} +3 -1
- package/dist/{chunk-22KP6LR5.js.map → chunk-TXS65BB2.js.map} +1 -1
- package/dist/chunk-UNJPZGNK.js +63 -0
- package/dist/chunk-UNJPZGNK.js.map +1 -0
- package/dist/{chunk-MZ2G2XBA.js → chunk-V5ZUJT2T.js} +205 -45
- package/dist/chunk-V5ZUJT2T.js.map +1 -0
- package/dist/chunk-VIUEOHXY.js +394 -0
- package/dist/chunk-VIUEOHXY.js.map +1 -0
- package/dist/chunk-WIUKB3LD.js +1911 -0
- package/dist/chunk-WIUKB3LD.js.map +1 -0
- package/dist/{chunk-ICA6R6TW.js → chunk-WNN7NO2N.js} +1451 -355
- package/dist/chunk-WNN7NO2N.js.map +1 -0
- package/dist/{chunk-YJFGAFBD.js → chunk-X5UVUIMF.js} +1892 -1223
- package/dist/chunk-X5UVUIMF.js.map +1 -0
- package/dist/chunk-XDA5QJE7.js +402 -0
- package/dist/chunk-XDA5QJE7.js.map +1 -0
- package/dist/{chunk-VZTQ73XT.js → chunk-XEA5BCMA.js} +3 -1
- package/dist/{chunk-VZTQ73XT.js.map → chunk-XEA5BCMA.js.map} +1 -1
- package/dist/chunk-XHF7OYAN.js +1150 -0
- package/dist/chunk-XHF7OYAN.js.map +1 -0
- package/dist/chunk-YSRBFJMQ.js +43 -0
- package/dist/chunk-YSRBFJMQ.js.map +1 -0
- package/dist/chunk-ZOZAPAUO.js +174 -0
- package/dist/chunk-ZOZAPAUO.js.map +1 -0
- package/dist/chunk-ZQV5W7YC.js +809 -0
- package/dist/chunk-ZQV5W7YC.js.map +1 -0
- package/dist/chunk-ZUWF4NF7.js +13 -0
- package/dist/chunk-ZUWF4NF7.js.map +1 -0
- package/dist/client.d.ts +16 -7
- package/dist/clipboard.js +3 -1
- package/dist/commands/types.d.ts +2 -0
- package/dist/components/anthropic-mark.d.ts +3 -0
- package/dist/components/approval-surface.d.ts +19 -6
- package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
- package/dist/components/artifacts/artifact-sandbox.d.ts +30 -0
- package/dist/components/artifacts/artifact-surface.d.ts +4 -2
- package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
- package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
- package/dist/components/artifacts/document-editor.d.ts +4 -2
- package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
- package/dist/components/artifacts/editable-artifact-view.d.ts +48 -0
- package/dist/components/artifacts/editable-document.d.ts +1 -1
- package/dist/components/artifacts/editable-presentation.d.ts +2 -2
- package/dist/components/artifacts/editable-spreadsheet.d.ts +8 -3
- package/dist/components/artifacts/index.d.ts +9 -2
- package/dist/components/artifacts/inline-html-document.d.ts +2 -0
- package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
- package/dist/components/artifacts/presentation-editor.d.ts +6 -2
- package/dist/components/artifacts/published-html-artifact-frame.d.ts +23 -3
- package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
- package/dist/components/artifacts/site-view.d.ts +26 -0
- package/dist/components/artifacts/spreadsheet-command-queue.d.ts +20 -0
- package/dist/components/artifacts/spreadsheet-download.d.ts +7 -0
- package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
- package/dist/components/artifacts/spreadsheet-grid.d.ts +10 -3
- package/dist/components/artifacts/spreadsheet-resize.d.ts +50 -0
- package/dist/components/artifacts/spreadsheet-submissions.d.ts +9 -0
- package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
- package/dist/components/browser-select-control.d.ts +16 -0
- package/dist/components/browser-viewer.d.ts +11 -2
- package/dist/components/chat-composer.d.ts +21 -3
- package/dist/components/child-session-link.d.ts +9 -0
- package/dist/components/claude-mark.d.ts +3 -0
- package/dist/components/code-editor.d.ts +1 -4
- package/dist/components/composer-transcription-control.d.ts +7 -0
- package/dist/components/composer.d.ts +34 -67
- package/dist/components/computer-viewer.d.ts +1 -1
- package/dist/components/copy-button.d.ts +3 -1
- package/dist/components/desktop-viewer.d.ts +1 -1
- package/dist/components/fleet-tile.d.ts +2 -2
- package/dist/components/grok-mark.d.ts +26 -0
- package/dist/components/human-input-form.d.ts +28 -32
- package/dist/components/human-input-surface.d.ts +7 -2
- package/dist/components/linkified-text.d.ts +18 -0
- package/dist/components/machine-input-display.d.ts +22 -1
- package/dist/components/machines/agent-status-icon.d.ts +6 -0
- package/dist/components/machines/machine-detail.d.ts +7 -1
- package/dist/components/machines/machine-status.d.ts +48 -0
- package/dist/components/markdown-table-layout.d.ts +18 -0
- package/dist/components/markdown.d.ts +37 -4
- package/dist/components/message-timeline.d.ts +86 -7
- package/dist/components/model-mark.d.ts +29 -0
- package/dist/components/model-policy-picker-menu.d.ts +9 -0
- package/dist/components/model-policy-picker.d.ts +41 -25
- package/dist/components/new-conversation.d.ts +32 -0
- package/dist/components/open-geni-chat.d.ts +73 -0
- package/dist/components/open-geni-links.d.ts +68 -0
- package/dist/components/openrouter-mark.d.ts +6 -0
- package/dist/components/opper-mark.d.ts +7 -0
- package/dist/components/preview-loading.d.ts +2 -0
- package/dist/components/provider-recovery-notice.d.ts +16 -0
- package/dist/components/queue-item-content.d.ts +9 -0
- package/dist/components/rehype-secret-refs.d.ts +23 -0
- package/dist/components/remark-soft-line-breaks.d.ts +38 -0
- package/dist/components/sandbox-files.d.ts +3 -1
- package/dist/components/sandbox-workspace.d.ts +18 -0
- package/dist/components/secret-question-field.d.ts +31 -0
- package/dist/components/secret-ref-chip.d.ts +35 -0
- package/dist/components/session-capability-frame.d.ts +37 -0
- package/dist/components/session-chrome.d.ts +57 -8
- package/dist/components/session-commands-panel.d.ts +6 -0
- package/dist/components/session-commands.d.ts +6 -0
- package/dist/components/session-connection-request.d.ts +8 -0
- package/dist/components/session-conversation.d.ts +157 -0
- package/dist/components/session-list.d.ts +39 -0
- package/dist/components/session-mcp-capability-card.d.ts +41 -0
- package/dist/components/session-proxy-scope.d.ts +35 -0
- package/dist/components/session-status.d.ts +4 -1
- package/dist/components/session-usage-limit-notice.d.ts +39 -0
- package/dist/components/timeline-anchor.d.ts +24 -0
- package/dist/components/timeline-annotation-chrome.d.ts +25 -0
- package/dist/components/timeline-annotation-layout.d.ts +42 -0
- package/dist/components/timeline-annotation-markers.d.ts +8 -0
- package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
- package/dist/components/timeline-annotation-shared.d.ts +31 -0
- package/dist/components/timeline-annotations-dialog.d.ts +3 -2
- package/dist/components/timeline-annotations.d.ts +13 -3
- package/dist/components/timeline-reading-progress.d.ts +11 -0
- package/dist/components/timeline-search.d.ts +34 -0
- package/dist/components/timeline-settlement.d.ts +16 -0
- package/dist/components/tip-follow.d.ts +16 -0
- package/dist/components/tool-action-review.d.ts +47 -0
- package/dist/components/tool-review-history.d.ts +25 -0
- package/dist/components/usage-limit-notice.d.ts +49 -0
- package/dist/components/usage-member-list.d.ts +91 -0
- package/dist/components/usage-meter.d.ts +73 -0
- package/dist/components/use-viewer-menu-dismiss.d.ts +2 -0
- package/dist/components/user-message-body.d.ts +10 -1
- package/dist/composer-messages.d.ts +74 -0
- package/dist/composer-messages.js +9 -0
- package/dist/composer-messages.js.map +1 -0
- package/dist/composer-voice-events.d.ts +8 -0
- package/dist/composer.d.ts +5 -4
- package/dist/composer.js +26 -13
- package/dist/computer-viewer-GMLDXPON.js +20 -0
- package/dist/computer-viewer-GMLDXPON.js.map +1 -0
- package/dist/connect-account-identity.d.ts +8 -0
- package/dist/connect-accounts.d.ts +15 -0
- package/dist/connect-chooser.d.ts +18 -0
- package/dist/connect-panel.d.ts +18 -0
- package/dist/connect-setup.d.ts +18 -0
- package/dist/connect.d.ts +21 -0
- package/dist/connect.js +2149 -0
- package/dist/connect.js.map +1 -0
- package/dist/connection-catalog.d.ts +38 -0
- package/dist/connection-discovery.d.ts +12 -0
- package/dist/connection-installed.d.ts +17 -0
- package/dist/connection-logo.d.ts +9 -0
- package/dist/connection-service-logo.d.ts +8 -0
- package/dist/connection-service-presentation.d.ts +13 -0
- package/dist/connection-skeleton.d.ts +5 -0
- package/dist/connection-type-picker.d.ts +6 -0
- package/dist/conversation-timeline.d.ts +5 -0
- package/dist/desktop.d.ts +7 -0
- package/dist/desktop.js +27 -0
- package/dist/desktop.js.map +1 -0
- package/dist/device-authorization.d.ts +23 -0
- package/dist/diffs.d.ts +8 -0
- package/dist/diffs.js +15 -0
- package/dist/diffs.js.map +1 -0
- package/dist/discovery-cache.d.ts +5 -0
- package/dist/editor.d.ts +7 -0
- package/dist/editor.js +22 -0
- package/dist/editor.js.map +1 -0
- package/dist/embedded-new-voice-OCRNT6U5.js +18 -0
- package/dist/embedded-new-voice-OCRNT6U5.js.map +1 -0
- package/dist/embedded-voice-RPHPYVBT.js +18 -0
- package/dist/embedded-voice-RPHPYVBT.js.map +1 -0
- package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-SI63O5V4.js} +4 -1
- package/dist/fleet-decision-row-SI63O5V4.js.map +1 -0
- package/dist/hooks/latest-question.d.ts +25 -0
- package/dist/hooks/shared-machines-list.d.ts +4 -0
- package/dist/hooks/shared-query.d.ts +113 -0
- package/dist/hooks/use-attached-browsers.d.ts +1 -1
- package/dist/hooks/use-auth-runs.d.ts +1 -4
- package/dist/hooks/use-available-models.d.ts +1 -1
- package/dist/hooks/use-browser-frame-stream.d.ts +1 -1
- package/dist/hooks/use-browser-session.d.ts +12 -1
- package/dist/hooks/use-client-config-flags.d.ts +49 -0
- package/dist/hooks/use-codex-accounts.d.ts +59 -10
- package/dist/hooks/use-composer.d.ts +24 -2
- package/dist/hooks/use-computer-frame-stream.d.ts +1 -1
- package/dist/hooks/use-computer-input-posture.d.ts +13 -0
- package/dist/hooks/use-computer-session.d.ts +4 -0
- package/dist/hooks/use-connect.d.ts +23 -0
- package/dist/hooks/use-desktop-stream.d.ts +1 -1
- package/dist/hooks/use-file-attachments.d.ts +12 -0
- package/dist/hooks/use-goal.d.ts +2 -1
- package/dist/hooks/use-last-started-turn-policy.d.ts +5 -1
- package/dist/hooks/use-new-conversation.d.ts +56 -0
- package/dist/hooks/use-new-session-draft.d.ts +74 -0
- package/dist/hooks/use-realtime-voice-models.d.ts +7 -0
- package/dist/hooks/use-sandbox-files.d.ts +4 -1
- package/dist/hooks/use-session-conversation.d.ts +49 -0
- package/dist/hooks/use-session-events.d.ts +28 -7
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
- package/dist/hooks/use-session-model-account.d.ts +48 -0
- package/dist/hooks/use-supergrok-accounts.d.ts +7 -1
- package/dist/hooks/use-terminal-stream.d.ts +11 -5
- package/dist/hooks/use-usage.d.ts +40 -0
- package/dist/hooks/use-vaults.d.ts +53 -0
- package/dist/hooks/use-voice-input.d.ts +8 -1
- package/dist/hooks/use-workspace-edit.d.ts +4 -0
- package/dist/hooks/use-workspace-sessions.d.ts +22 -5
- package/dist/human-input-model.d.ts +122 -0
- package/dist/identity-link-accounts.d.ts +11 -0
- package/dist/identity-link-consent.d.ts +18 -0
- package/dist/index.d.ts +82 -20
- package/dist/index.js +2350 -6605
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +1 -1
- package/dist/interaction.js +14 -24
- package/dist/interaction.js.map +1 -1
- package/dist/latest-question-R77KWSUP.js +118 -0
- package/dist/latest-question-R77KWSUP.js.map +1 -0
- package/dist/lib/clipboard.d.ts +7 -0
- package/dist/lib/error-message.d.ts +7 -0
- package/dist/lib/format.d.ts +58 -4
- package/dist/lib/host-theme.d.ts +77 -0
- package/dist/lib/interaction-errors.d.ts +3 -0
- package/dist/lib/menu-styles.d.ts +22 -0
- package/dist/lib/notify-observer.d.ts +2 -0
- package/dist/lib/pierre-diffs-loader.d.ts +20 -0
- package/dist/lib/provider-recovery.d.ts +55 -0
- package/dist/lib/scrollbars.d.ts +11 -0
- package/dist/lib/terminal-input-readiness.d.ts +11 -0
- package/dist/lib/transient-retry.d.ts +25 -0
- package/dist/lib/workbench-peers.d.ts +36 -0
- package/dist/lib/xterm-theme.d.ts +7 -5
- package/dist/machines.js +9 -5
- package/dist/markdown-table-layout-3PV2UAAH.js +113 -0
- package/dist/markdown-table-layout-3PV2UAAH.js.map +1 -0
- package/dist/mcp-connection-status.d.ts +14 -0
- package/dist/model-mark-paths.d.ts +34 -0
- package/dist/model-mark-paths.js +16 -0
- package/dist/model-mark-paths.js.map +1 -0
- package/dist/model-picker-model.d.ts +111 -0
- package/dist/model-picker-model.js +25 -0
- package/dist/model-picker-model.js.map +1 -0
- package/dist/model-policy-picker-menu-7GJ5URPR.js +17 -0
- package/dist/model-policy-picker-menu-7GJ5URPR.js.map +1 -0
- package/dist/model-policy.d.ts +30 -3
- package/dist/model-policy.js +14 -1
- package/dist/native-previews.d.ts +28 -0
- package/dist/native-previews.js +82 -0
- package/dist/native-previews.js.map +1 -0
- package/dist/new-session-draft.d.ts +7 -0
- package/dist/new-session-draft.js +639 -0
- package/dist/new-session-draft.js.map +1 -0
- package/dist/notification-text.d.ts +27 -0
- package/dist/{noto-sans-arabic-loader-IA2T4X2A.js → noto-sans-arabic-loader-XSH2KYWJ.js} +3 -1
- package/dist/{noto-sans-arabic-loader-IA2T4X2A.js.map → noto-sans-arabic-loader-XSH2KYWJ.js.map} +1 -1
- package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js → noto-sans-jp-loader.generated-MR5L6V7K.js} +3 -1
- package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js.map → noto-sans-jp-loader.generated-MR5L6V7K.js.map} +1 -1
- package/dist/older-history.d.ts +3 -2
- package/dist/organization-model.d.ts +32 -0
- package/dist/organization-model.js +65 -0
- package/dist/organization-model.js.map +1 -0
- package/dist/{platform-activity-row-BJHUHXAT.js → platform-activity-row-5OCKOQWZ.js} +16 -78
- package/dist/platform-activity-row-5OCKOQWZ.js.map +1 -0
- package/dist/plugin-details.d.ts +14 -0
- package/dist/plugin-discovery.d.ts +25 -0
- package/dist/preview-loading-paint.d.ts +20 -0
- package/dist/provider.d.ts +25 -2
- package/dist/queue-presentation-model.d.ts +72 -0
- package/dist/queue-presentation-model.js +38 -0
- package/dist/queue-presentation-model.js.map +1 -0
- package/dist/{queue-surface-implementation-BSKUWHRI.js → queue-surface-implementation-GJBH7NKO.js} +65 -265
- package/dist/queue-surface-implementation-GJBH7NKO.js.map +1 -0
- package/dist/realtime/embedded-new-voice.d.ts +1 -0
- package/dist/realtime/embedded-voice.d.ts +1 -0
- package/dist/realtime/realtime-control.d.ts +4 -65
- package/dist/realtime/session-realtime.d.ts +78 -0
- package/dist/realtime.js +25 -1294
- package/dist/realtime.js.map +1 -1
- package/dist/sandbox-files-O27IPOZW.js +21 -0
- package/dist/sandbox-files-O27IPOZW.js.map +1 -0
- package/dist/sandbox-label-model.d.ts +30 -0
- package/dist/sandbox-label-model.js +20 -0
- package/dist/sandbox-label-model.js.map +1 -0
- package/dist/scrollbars.d.ts +1 -0
- package/dist/scrollbars.js +10 -0
- package/dist/scrollbars.js.map +1 -0
- package/dist/secret-reference-label.d.ts +14 -0
- package/dist/secrets-ui.d.ts +57 -0
- package/dist/session-agents-model.d.ts +10 -0
- package/dist/session-agents-model.js +25 -0
- package/dist/session-agents-model.js.map +1 -0
- package/dist/session-attention-model.d.ts +8 -0
- package/dist/session-attention-model.js +47 -0
- package/dist/session-attention-model.js.map +1 -0
- package/dist/session-auth-recommendation.d.ts +5 -0
- package/dist/session-capability-policy.d.ts +31 -0
- package/dist/session-feedback-model.d.ts +20 -0
- package/dist/session-feedback-model.js +56 -0
- package/dist/session-feedback-model.js.map +1 -0
- package/dist/session-list-model.d.ts +138 -0
- package/dist/session-list-model.js +274 -0
- package/dist/session-list-model.js.map +1 -0
- package/dist/session-realtime-7DJOIHQW.js +21 -0
- package/dist/session-realtime-7DJOIHQW.js.map +1 -0
- package/dist/session-realtime.d.ts +7 -0
- package/dist/session-realtime.js +19 -0
- package/dist/session-realtime.js.map +1 -0
- package/dist/session-status-model.d.ts +36 -0
- package/dist/session-ui.d.ts +39 -1
- package/dist/session-ui.js +126 -12
- package/dist/session-ui.js.map +1 -1
- package/dist/session.d.ts +8 -2
- package/dist/session.js +35 -20
- package/dist/site-snapshot.d.ts +14 -0
- package/dist/sites-ui.d.ts +24 -0
- package/dist/sites.d.ts +3 -0
- package/dist/sites.js +14 -0
- package/dist/sites.js.map +1 -0
- package/dist/skill-discovery.d.ts +47 -0
- package/dist/terminal.d.ts +8 -0
- package/dist/terminal.js +32 -0
- package/dist/terminal.js.map +1 -0
- package/dist/testing/session-scenarios.d.ts +10 -0
- package/dist/testing/session-scenarios.js +367 -0
- package/dist/testing/session-scenarios.js.map +1 -0
- package/dist/timeline/activity-rail.d.ts +11 -2
- package/dist/timeline/agent-identity.d.ts +30 -0
- package/dist/timeline/agent-row.d.ts +31 -0
- package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
- package/dist/timeline/compaction-copy.d.ts +46 -0
- package/dist/timeline/entrance.d.ts +13 -1
- package/dist/timeline/focus-sequence.d.ts +9 -0
- package/dist/timeline/genie-copy.d.ts +3 -0
- package/dist/timeline/genie-loading.d.ts +47 -0
- package/dist/timeline/index.d.ts +10 -5
- package/dist/timeline/knowledge-receipt.d.ts +17 -0
- package/dist/timeline/message-sender.d.ts +19 -0
- package/dist/timeline/notice-presentation.d.ts +13 -0
- package/dist/timeline/parsers.d.ts +11 -0
- package/dist/timeline/patch-apply-command.d.ts +18 -0
- package/dist/timeline/platform-activity-presentation.d.ts +21 -0
- package/dist/timeline/platform-activity-row.d.ts +1 -2
- package/dist/timeline/presented-image.d.ts +11 -0
- package/dist/timeline/projection.d.ts +31 -2
- package/dist/timeline/provider-logo.d.ts +15 -0
- package/dist/timeline/question-nav-model.d.ts +23 -0
- package/dist/timeline/registry.d.ts +12 -1
- package/dist/timeline/retained-image.d.ts +18 -0
- package/dist/timeline/retained-loaders.d.ts +27 -0
- package/dist/timeline/rolling-activity.d.ts +11 -0
- package/dist/timeline/screenshot-lightbox.d.ts +23 -1
- package/dist/timeline/session-usage-limit-row.d.ts +11 -0
- package/dist/timeline/shared.d.ts +4 -1
- package/dist/timeline/startup-dispatch-details.d.ts +5 -0
- package/dist/timeline/startup-preference.d.ts +3 -0
- package/dist/timeline/startup-timings.d.ts +4 -0
- package/dist/timeline/tool-display-name.d.ts +5 -2
- package/dist/timeline/tool-presentation.d.ts +172 -0
- package/dist/timeline/turn-summary-model.d.ts +95 -0
- package/dist/timeline/turn-summary.d.ts +20 -54
- package/dist/timeline/types.d.ts +179 -7
- package/dist/timeline/work-presentation.d.ts +60 -0
- package/dist/timeline-annotation-markers-U3G66KUD.js +166 -0
- package/dist/timeline-annotation-markers-U3G66KUD.js.map +1 -0
- package/dist/timeline-annotation-selection-BI7QTPTZ.js +242 -0
- package/dist/timeline-annotation-selection-BI7QTPTZ.js.map +1 -0
- package/dist/timeline-annotations-dialog-FOMHSDTE.js +274 -0
- package/dist/timeline-annotations-dialog-FOMHSDTE.js.map +1 -0
- package/dist/timeline-model.d.ts +29 -0
- package/dist/timeline-model.js +254 -0
- package/dist/timeline-model.js.map +1 -0
- package/dist/usage/allowance-copy.d.ts +25 -0
- package/dist/usage/session-usage-limit.d.ts +88 -0
- package/dist/usage/summary.d.ts +35 -0
- package/dist/usage.d.ts +17 -0
- package/dist/usage.js +1187 -0
- package/dist/usage.js.map +1 -0
- package/dist/voice-recording-owner.d.ts +7 -0
- package/package.json +107 -7
- package/src/accounts.tsx +116 -14
- package/src/approvals.ts +8 -1
- package/src/artifacts-spreadsheet.ts +1 -0
- package/src/artifacts.ts +44 -0
- package/src/assets/README.md +8 -0
- package/src/assets/gmail.ico +0 -0
- package/src/assets/outlook.ico +0 -0
- package/src/capability-catalog-row.tsx +94 -0
- package/src/capability-logo-fallback.ts +22 -0
- package/src/client.ts +20 -31
- package/src/commands/registry.ts +18 -15
- package/src/commands/types.ts +2 -0
- package/src/components/anthropic-mark.tsx +10 -0
- package/src/components/approval-surface.tsx +401 -138
- package/src/components/artifacts/artifact-chrome.tsx +413 -0
- package/src/components/artifacts/artifact-sandbox.tsx +189 -0
- package/src/components/artifacts/artifact-surface.tsx +40 -20
- package/src/components/artifacts/chat-interactive-block.tsx +260 -0
- package/src/components/artifacts/deferred-chat-media.tsx +67 -0
- package/src/components/artifacts/document-editor.tsx +141 -16
- package/src/components/artifacts/editable-artifact-ui.tsx +4 -2
- package/src/components/artifacts/editable-artifact-view.tsx +197 -0
- package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
- package/src/components/artifacts/editable-document.tsx +37 -36
- package/src/components/artifacts/editable-presentation.tsx +36 -18
- package/src/components/artifacts/editable-spreadsheet.tsx +543 -103
- package/src/components/artifacts/index.ts +45 -0
- package/src/components/artifacts/inline-html-document.ts +24 -0
- package/src/components/artifacts/latest-task-runner.ts +49 -0
- package/src/components/artifacts/presentation-editor.tsx +323 -67
- package/src/components/artifacts/published-html-artifact-frame.tsx +122 -5
- package/src/components/artifacts/session-artifact-viewer.tsx +378 -0
- package/src/components/artifacts/site-view.tsx +121 -0
- package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
- package/src/components/artifacts/spreadsheet-command-queue.ts +184 -0
- package/src/components/artifacts/spreadsheet-download.tsx +109 -0
- package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
- package/src/components/artifacts/spreadsheet-grid.tsx +344 -144
- package/src/components/artifacts/spreadsheet-resize.tsx +421 -0
- package/src/components/artifacts/spreadsheet-submissions.tsx +46 -0
- package/src/components/artifacts/visualization-assets/base.css +1015 -0
- package/src/components/artifacts/visualization-assets/helpers.html +349 -0
- package/src/components/artifacts/visualization-assets.gen.ts +3 -0
- package/src/components/browser-select-control.tsx +312 -0
- package/src/components/browser-viewer.tsx +778 -318
- package/src/components/chat-composer.tsx +47 -5
- package/src/components/child-session-link.tsx +36 -0
- package/src/components/claude-mark.tsx +11 -0
- package/src/components/code-editor.tsx +13 -16
- package/src/components/composer-transcription-control.tsx +128 -30
- package/src/components/composer.tsx +404 -195
- package/src/components/computer-viewer.tsx +880 -253
- package/src/components/copy-button.tsx +13 -5
- package/src/components/desktop-viewer.tsx +1 -1
- package/src/components/enrollment-consent.tsx +1 -1
- package/src/components/enrollment-device-flow.tsx +1 -1
- package/src/components/file-browser.tsx +10 -14
- package/src/components/fleet-tile.tsx +9 -18
- package/src/components/generated-video-player.tsx +4 -2
- package/src/components/grok-mark.tsx +34 -0
- package/src/components/human-input-form.tsx +590 -283
- package/src/components/human-input-surface.tsx +11 -0
- package/src/components/interaction-intervention-banner.tsx +2 -2
- package/src/components/linkified-text.tsx +79 -0
- package/src/components/machine-card.tsx +35 -78
- package/src/components/machine-dock-bar.tsx +1 -1
- package/src/components/machine-input-display.ts +197 -3
- package/src/components/machines/agent-status-icon.tsx +31 -0
- package/src/components/machines/machine-detail.tsx +200 -31
- package/src/components/machines/machine-operation-policy.tsx +1 -1
- package/src/components/machines/machine-status.ts +241 -0
- package/src/components/machines-dashboard.tsx +2 -17
- package/src/components/markdown-table-layout.ts +143 -0
- package/src/components/markdown.tsx +466 -129
- package/src/components/message-timeline.tsx +2567 -728
- package/src/components/model-mark.tsx +102 -0
- package/src/components/model-picker.tsx +15 -4
- package/src/components/model-policy-picker-menu.tsx +371 -0
- package/src/components/model-policy-picker.tsx +256 -412
- package/src/components/new-conversation.tsx +221 -0
- package/src/components/open-geni-chat.tsx +309 -0
- package/src/components/open-geni-links.tsx +179 -0
- package/src/components/openrouter-mark.tsx +13 -0
- package/src/components/opper-mark.tsx +18 -0
- package/src/components/pierre-diff.tsx +41 -16
- package/src/components/pierre-file.tsx +35 -10
- package/src/components/preview-loading.tsx +109 -0
- package/src/components/provider-recovery-notice.tsx +49 -0
- package/src/components/queue-item-content.ts +14 -0
- package/src/components/queue-surface-implementation.tsx +51 -356
- package/src/components/queue-surface-state.tsx +3 -1
- package/src/components/rehype-secret-refs.ts +98 -0
- package/src/components/remark-soft-line-breaks.ts +166 -0
- package/src/components/sandbox-files.tsx +91 -15
- package/src/components/sandbox-terminal.tsx +84 -13
- package/src/components/sandbox-workspace.tsx +147 -51
- package/src/components/secret-question-field.tsx +324 -0
- package/src/components/secret-ref-chip.tsx +185 -0
- package/src/components/session-capability-frame.tsx +197 -0
- package/src/components/session-chrome.tsx +842 -251
- package/src/components/session-commands-panel.tsx +126 -0
- package/src/components/session-commands.tsx +18 -0
- package/src/components/session-connection-request.tsx +97 -0
- package/src/components/session-conversation.tsx +876 -0
- package/src/components/session-list.tsx +257 -0
- package/src/components/session-mcp-capability-card.tsx +680 -0
- package/src/components/session-proxy-scope.tsx +153 -0
- package/src/components/session-status.tsx +26 -17
- package/src/components/session-usage-limit-notice.tsx +174 -0
- package/src/components/timeline-anchor.tsx +119 -0
- package/src/components/timeline-annotation-chrome.tsx +196 -0
- package/src/components/timeline-annotation-layout.ts +268 -0
- package/src/components/timeline-annotation-markers.tsx +185 -0
- package/src/components/timeline-annotation-reveal-context.ts +9 -0
- package/src/components/timeline-annotation-selection.tsx +106 -54
- package/src/components/timeline-annotation-shared.ts +245 -0
- package/src/components/timeline-annotations-dialog.tsx +185 -128
- package/src/components/timeline-annotations.tsx +189 -45
- package/src/components/timeline-reading-progress.ts +80 -0
- package/src/components/timeline-search.tsx +168 -0
- package/src/components/timeline-settlement.ts +60 -0
- package/src/components/tip-follow.ts +52 -0
- package/src/components/tool-action-review.tsx +650 -0
- package/src/components/tool-review-history.tsx +88 -0
- package/src/components/tooltip.tsx +38 -5
- package/src/components/usage-limit-notice.tsx +179 -0
- package/src/components/usage-member-list.tsx +792 -0
- package/src/components/usage-meter.tsx +382 -0
- package/src/components/use-viewer-menu-dismiss.ts +33 -0
- package/src/components/user-message-body.tsx +27 -2
- package/src/components/workspace-dock.tsx +18 -1
- package/src/composer-messages.ts +150 -0
- package/src/composer-voice-events.ts +12 -0
- package/src/composer.ts +6 -1
- package/src/connect-account-identity.tsx +34 -0
- package/src/connect-accounts.tsx +233 -0
- package/src/connect-chooser.tsx +336 -0
- package/src/connect-panel.tsx +99 -0
- package/src/connect-setup.tsx +355 -0
- package/src/connect.ts +60 -0
- package/src/connection-assets.d.ts +4 -0
- package/src/connection-catalog.tsx +162 -0
- package/src/connection-discovery.tsx +238 -0
- package/src/connection-installed.tsx +51 -0
- package/src/connection-logo.tsx +37 -0
- package/src/connection-service-logo.tsx +55 -0
- package/src/connection-service-presentation.ts +46 -0
- package/src/connection-skeleton.tsx +16 -0
- package/src/connection-type-picker.tsx +36 -0
- package/src/conversation-timeline.ts +92 -0
- package/src/desktop.ts +24 -0
- package/src/device-authorization.tsx +98 -0
- package/src/diffs.ts +16 -0
- package/src/discovery-cache.ts +42 -0
- package/src/editor.ts +13 -0
- package/src/hooks/internal.ts +3 -2
- package/src/hooks/latest-question.ts +164 -0
- package/src/hooks/shared-machines-list.ts +34 -1
- package/src/hooks/shared-query.ts +721 -0
- package/src/hooks/use-attached-browsers.ts +1 -1
- package/src/hooks/use-auth-runs.ts +0 -27
- package/src/hooks/use-available-models.ts +21 -15
- package/src/hooks/use-browser-frame-stream.ts +19 -2
- package/src/hooks/use-browser-session.ts +680 -205
- package/src/hooks/use-browser-sessions.ts +32 -1
- package/src/hooks/use-client-config-flags.ts +118 -0
- package/src/hooks/use-codex-accounts.ts +247 -47
- package/src/hooks/use-composer.ts +276 -47
- package/src/hooks/use-computer-frame-stream.ts +25 -7
- package/src/hooks/use-computer-input-posture.ts +94 -0
- package/src/hooks/use-computer-session.ts +409 -95
- package/src/hooks/use-connect.ts +23 -0
- package/src/hooks/use-desktop-stream.ts +19 -28
- package/src/hooks/use-file-attachments.ts +80 -4
- package/src/hooks/use-goal.ts +107 -13
- package/src/hooks/use-last-started-turn-policy.ts +46 -14
- package/src/hooks/use-machines.ts +4 -0
- package/src/hooks/use-new-conversation.ts +374 -0
- package/src/hooks/use-new-session-draft.ts +813 -0
- package/src/hooks/use-realtime-voice-models.ts +46 -0
- package/src/hooks/use-sandbox-files.ts +68 -20
- package/src/hooks/use-session-background-commands.ts +22 -11
- package/src/hooks/use-session-capabilities.ts +3 -2
- package/src/hooks/use-session-conversation.ts +150 -0
- package/src/hooks/use-session-events.ts +703 -382
- package/src/hooks/use-session-lineage.ts +20 -16
- package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
- package/src/hooks/use-session-model-account.ts +174 -0
- package/src/hooks/use-session.ts +53 -21
- package/src/hooks/use-slash-commands.ts +6 -11
- package/src/hooks/use-supergrok-accounts.ts +22 -8
- package/src/hooks/use-terminal-stream.ts +153 -27
- package/src/hooks/use-transcription.ts +6 -0
- package/src/hooks/use-turn-queue.ts +2 -1
- package/src/hooks/use-usage.ts +100 -0
- package/src/hooks/use-vaults.ts +153 -0
- package/src/hooks/use-video-artifact-playback.ts +1 -1
- package/src/hooks/use-voice-input.ts +127 -19
- package/src/hooks/use-workspace-capture.ts +3 -2
- package/src/hooks/use-workspace-edit.ts +23 -5
- package/src/hooks/use-workspace-sessions.ts +97 -32
- package/src/human-input-model.ts +359 -0
- package/src/identity-link-accounts.tsx +148 -0
- package/src/identity-link-consent.tsx +192 -0
- package/src/index.ts +262 -16
- package/src/interaction.ts +1 -0
- package/src/lib/clipboard.ts +29 -0
- package/src/lib/error-message.ts +37 -0
- package/src/lib/format.ts +213 -16
- package/src/lib/host-theme.ts +529 -0
- package/src/lib/interaction-errors.ts +15 -0
- package/src/lib/menu-styles.ts +44 -0
- package/src/lib/notify-observer.ts +15 -0
- package/src/lib/pierre-diffs-loader.ts +53 -0
- package/src/lib/provider-recovery.ts +243 -0
- package/src/lib/scrollbars.ts +30 -0
- package/src/lib/terminal-input-readiness.ts +51 -0
- package/src/lib/transient-retry.ts +99 -0
- package/src/lib/workbench-peers.ts +62 -0
- package/src/lib/xterm-theme.ts +23 -21
- package/src/mcp-connection-status.ts +35 -0
- package/src/model-mark-paths.ts +53 -0
- package/src/model-picker-model.ts +330 -0
- package/src/model-policy.ts +299 -74
- package/src/native-previews.ts +100 -0
- package/src/new-session-draft.ts +22 -0
- package/src/notification-text.ts +81 -0
- package/src/older-history.ts +22 -4
- package/src/organization-model.ts +118 -0
- package/src/plugin-details.tsx +185 -0
- package/src/plugin-discovery.tsx +196 -0
- package/src/preview-loading-paint.ts +68 -0
- package/src/provider.tsx +74 -15
- package/src/queue-presentation-model.ts +464 -0
- package/src/realtime/dropdown-menu.tsx +19 -12
- package/src/realtime/embedded-new-voice.tsx +1 -0
- package/src/realtime/embedded-voice.tsx +3 -0
- package/src/realtime/realtime-control.tsx +138 -501
- package/src/realtime/session-realtime.ts +566 -0
- package/src/sandbox-label-model.ts +53 -0
- package/src/scrollbars.ts +3 -0
- package/src/secret-reference-label.ts +43 -0
- package/src/secrets-ui.tsx +59 -0
- package/src/session-agents-model.ts +33 -0
- package/src/session-attention-model.ts +62 -0
- package/src/session-auth-recommendation.ts +48 -0
- package/src/session-capability-policy.ts +196 -0
- package/src/session-context.ts +3 -4
- package/src/session-feedback-model.ts +95 -0
- package/src/session-list-model.ts +434 -0
- package/src/session-realtime.ts +18 -0
- package/src/session-status-model.ts +99 -0
- package/src/session-ui.ts +98 -1
- package/src/session.ts +17 -1
- package/src/site-snapshot.ts +74 -0
- package/src/sites-ui.tsx +348 -0
- package/src/sites.ts +3 -0
- package/src/skill-discovery.tsx +208 -0
- package/src/terminal.ts +26 -0
- package/src/testing/session-scenarios.ts +404 -0
- package/src/timeline/activity-rail.tsx +242 -101
- package/src/timeline/agent-identity.tsx +84 -0
- package/src/timeline/agent-row.tsx +231 -0
- package/src/timeline/allowance-exhausted-row.tsx +86 -0
- package/src/timeline/compaction-copy.ts +115 -0
- package/src/timeline/entrance.tsx +28 -3
- package/src/timeline/fleet-decision-projection.ts +2 -1
- package/src/timeline/fleet-decision-row.tsx +1 -0
- package/src/timeline/focus-sequence.ts +44 -0
- package/src/timeline/genie-copy.ts +19 -0
- package/src/timeline/genie-loading.tsx +143 -0
- package/src/timeline/index.ts +30 -2
- package/src/timeline/knowledge-receipt.tsx +100 -0
- package/src/timeline/message-sender.tsx +71 -0
- package/src/timeline/notice-presentation.ts +48 -0
- package/src/timeline/parsers.ts +42 -2
- package/src/timeline/patch-apply-command.tsx +135 -0
- package/src/timeline/platform-activity-presentation.ts +166 -0
- package/src/timeline/platform-activity-row.tsx +15 -90
- package/src/timeline/presented-image.ts +63 -0
- package/src/timeline/projection.ts +1746 -76
- package/src/timeline/provider-logo.tsx +53 -0
- package/src/timeline/question-nav-model.ts +28 -0
- package/src/timeline/registry.ts +26 -4
- package/src/timeline/retained-image.ts +97 -0
- package/src/timeline/retained-loaders.ts +91 -0
- package/src/timeline/rolling-activity.tsx +80 -0
- package/src/timeline/screenshot-lightbox.tsx +228 -5
- package/src/timeline/session-usage-limit-row.tsx +42 -0
- package/src/timeline/shared.tsx +42 -15
- package/src/timeline/startup-dispatch-details.tsx +36 -0
- package/src/timeline/startup-preference.ts +33 -0
- package/src/timeline/startup-timings.tsx +145 -0
- package/src/timeline/tool-display-name.ts +19 -7
- package/src/timeline/tool-presentation.ts +1316 -0
- package/src/timeline/tool-renderers.tsx +835 -1138
- package/src/timeline/turn-summary-model.ts +343 -0
- package/src/timeline/turn-summary.tsx +272 -365
- package/src/timeline/types.ts +189 -6
- package/src/timeline/work-presentation.ts +189 -0
- package/src/timeline-model.ts +143 -0
- package/src/usage/allowance-copy.ts +64 -0
- package/src/usage/session-usage-limit.ts +266 -0
- package/src/usage/summary.ts +93 -0
- package/src/usage.ts +70 -0
- package/src/voice-recording-owner.ts +22 -0
- package/styles/compiled.css +2319 -748
- package/styles/connect.css +290 -0
- package/styles/connect.d.ts +1 -0
- package/styles/effective-tokens.css +1 -0
- package/styles/index.css +309 -9
- package/styles/responsive.css +99 -7
- package/styles/session-capability.css +44 -0
- package/styles/tokens.css +134 -66
- package/dist/browser-viewer-AEFHUYZK.js +0 -14
- package/dist/chunk-4MDLEHXL.js.map +0 -1
- package/dist/chunk-5YK2ZDIG.js.map +0 -1
- package/dist/chunk-D3UIAJKY.js.map +0 -1
- package/dist/chunk-ELIYWBZR.js.map +0 -1
- package/dist/chunk-H5YGYNXS.js.map +0 -1
- package/dist/chunk-HQVCKCLG.js +0 -9458
- package/dist/chunk-HQVCKCLG.js.map +0 -1
- package/dist/chunk-HUIKIDM5.js.map +0 -1
- package/dist/chunk-ICA6R6TW.js.map +0 -1
- package/dist/chunk-JVYQRRC4.js.map +0 -1
- package/dist/chunk-KCGXPP5V.js.map +0 -1
- package/dist/chunk-KZ73RL76.js.map +0 -1
- package/dist/chunk-LAKLF4PA.js +0 -141
- package/dist/chunk-LAKLF4PA.js.map +0 -1
- package/dist/chunk-MZ2G2XBA.js.map +0 -1
- package/dist/chunk-NEXLLTP4.js.map +0 -1
- package/dist/chunk-OAM4WAAM.js.map +0 -1
- package/dist/chunk-PEI6RANI.js.map +0 -1
- package/dist/chunk-RGALCTWO.js.map +0 -1
- package/dist/chunk-W6NFJXSA.js +0 -454
- package/dist/chunk-W6NFJXSA.js.map +0 -1
- package/dist/chunk-WSK7G5LE.js +0 -170
- package/dist/chunk-WSK7G5LE.js.map +0 -1
- package/dist/chunk-X4A66EWZ.js +0 -223
- package/dist/chunk-X4A66EWZ.js.map +0 -1
- package/dist/chunk-XXWH2JLC.js.map +0 -1
- package/dist/chunk-YFKJ7VZH.js +0 -268
- package/dist/chunk-YFKJ7VZH.js.map +0 -1
- package/dist/chunk-YJFGAFBD.js.map +0 -1
- package/dist/computer-viewer-FWEZISW4.js +0 -16
- package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
- package/dist/hooks/use-environments.d.ts +0 -41
- package/dist/hooks/use-packs.d.ts +0 -32
- package/dist/platform-activity-row-BJHUHXAT.js.map +0 -1
- package/dist/queue-surface-implementation-BSKUWHRI.js.map +0 -1
- package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
- package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
- package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
- package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
- package/src/hooks/use-environments.ts +0 -182
- package/src/hooks/use-packs.ts +0 -157
- /package/dist/{browser-viewer-AEFHUYZK.js.map → browser-viewer-ZWR6MWJ7.js.map} +0 -0
- /package/dist/{computer-viewer-FWEZISW4.js.map → chat-interactive-block-BO2IWXVK.js.map} +0 -0
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
PauseIcon,
|
|
10
10
|
PlayIcon,
|
|
11
11
|
RotateCwIcon,
|
|
12
|
+
SquareIcon,
|
|
12
13
|
XIcon,
|
|
13
14
|
} from "lucide-react";
|
|
14
15
|
import { AnimatePresence, motion } from "motion/react";
|
|
@@ -36,6 +37,7 @@ import {
|
|
|
36
37
|
type RefObject,
|
|
37
38
|
} from "react";
|
|
38
39
|
import { argHint, defaultCommands } from "../commands/registry";
|
|
40
|
+
import { useErrorMessage } from "../lib/error-message";
|
|
39
41
|
import type { Notice, SlashCommand } from "../commands/types";
|
|
40
42
|
import type { ComposerState } from "../hooks/use-composer";
|
|
41
43
|
import { shouldSteerOnKey, shouldSubmitOnKey } from "../hooks/use-composer";
|
|
@@ -50,7 +52,8 @@ import {
|
|
|
50
52
|
ComposerResponsiveContext,
|
|
51
53
|
type ResponsiveBasis,
|
|
52
54
|
} from "../lib/composer-responsive-context";
|
|
53
|
-
import { composerSubmissionErrorMessage
|
|
55
|
+
import { composerSubmissionErrorMessage } from "../lib/format";
|
|
56
|
+
import { defaultChatComposerMessages, type ChatComposerMessages } from "../composer-messages";
|
|
54
57
|
import type { PickerModelRow } from "../model-policy";
|
|
55
58
|
import { useLightboxOptional } from "../timeline/screenshot-lightbox";
|
|
56
59
|
import { OPEN_WORKSTREAM_CONTROL_EVENT } from "../workstream-control-event";
|
|
@@ -74,7 +77,16 @@ function ComposerTip({
|
|
|
74
77
|
|
|
75
78
|
export type ComposerDelivery = Pick<
|
|
76
79
|
ComposerState,
|
|
77
|
-
|
|
80
|
+
| "value"
|
|
81
|
+
| "setValue"
|
|
82
|
+
| "send"
|
|
83
|
+
| "steer"
|
|
84
|
+
| "sending"
|
|
85
|
+
| "canSend"
|
|
86
|
+
| "error"
|
|
87
|
+
| "clearError"
|
|
88
|
+
| "annotations"
|
|
89
|
+
| "requestAnnotationReview"
|
|
78
90
|
>;
|
|
79
91
|
|
|
80
92
|
export type ComposerDraftState = Pick<
|
|
@@ -96,138 +108,8 @@ export type ComposerControlLinks = {
|
|
|
96
108
|
sessionHref?: ((sessionId: string) => string) | undefined;
|
|
97
109
|
};
|
|
98
110
|
|
|
99
|
-
export
|
|
100
|
-
|
|
101
|
-
pausedPlaceholder: string;
|
|
102
|
-
inputLabel: string;
|
|
103
|
-
keyboardHint: string;
|
|
104
|
-
slashCommandBlocked: string;
|
|
105
|
-
controlChangedError: string;
|
|
106
|
-
sendFailedError: string;
|
|
107
|
-
dropFiles: string;
|
|
108
|
-
attachFiles: string;
|
|
109
|
-
pauseAriaLabel: string;
|
|
110
|
-
pauseTitle: string;
|
|
111
|
-
sendMessageAriaLabel: string;
|
|
112
|
-
sendAndResumeAriaLabel: string;
|
|
113
|
-
sendTitle: string;
|
|
114
|
-
sendAndResumeTitle: string;
|
|
115
|
-
workspacePaused: string;
|
|
116
|
-
pausedHere: string;
|
|
117
|
-
parentBlocker: string;
|
|
118
|
-
narrowerPause: string;
|
|
119
|
-
pausedBy: (displayName: string) => string;
|
|
120
|
-
queuedAhead: (count: number) => string;
|
|
121
|
-
resumingAndSending: string;
|
|
122
|
-
nextMessageResumes: string;
|
|
123
|
-
resumeThisWorkstream: string;
|
|
124
|
-
resumeShort: string;
|
|
125
|
-
hidePauseDetails: string;
|
|
126
|
-
showPauseDetails: string;
|
|
127
|
-
pauseReasonsLabel: string;
|
|
128
|
-
pausedByLabel: string;
|
|
129
|
-
alsoPausedByLabel: string;
|
|
130
|
-
resumeWorkspace: string;
|
|
131
|
-
resumeFromSession: string;
|
|
132
|
-
sessionCanRun: string;
|
|
133
|
-
stillPausedBy: (displayName: string) => string;
|
|
134
|
-
restoredResourcesLabel: string;
|
|
135
|
-
restoredFile: (fileId: string) => string;
|
|
136
|
-
removeRestoredResource: (index: number) => string;
|
|
137
|
-
uploading: string;
|
|
138
|
-
uploadFailed: string;
|
|
139
|
-
previewAttachment: (name: string) => string;
|
|
140
|
-
attachmentPreviewLabel: string;
|
|
141
|
-
downloadAttachment: (name: string) => string;
|
|
142
|
-
closeAttachmentPreview: string;
|
|
143
|
-
retryAttachment: (name: string) => string;
|
|
144
|
-
retryUpload: string;
|
|
145
|
-
removeAttachment: (name: string) => string;
|
|
146
|
-
confirmCommand: (name: string) => string;
|
|
147
|
-
confirmDescription: (command: SlashCommand) => string;
|
|
148
|
-
cancel: string;
|
|
149
|
-
runCommand: (name: string) => string;
|
|
150
|
-
commands: string;
|
|
151
|
-
slashCommandsLabel: string;
|
|
152
|
-
modelLabel: string;
|
|
153
|
-
close: string;
|
|
154
|
-
danger: string;
|
|
155
|
-
draftConflict: string;
|
|
156
|
-
useOtherDraft: string;
|
|
157
|
-
keepMine: string;
|
|
158
|
-
savingDraft: string;
|
|
159
|
-
formatBytes: (bytes: number) => string;
|
|
160
|
-
formatRelativeTime: (changedAt: string) => string;
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
export const defaultChatComposerMessages: ChatComposerMessages = {
|
|
164
|
-
messagePlaceholder: "Message the agent…",
|
|
165
|
-
pausedPlaceholder: "Message the agent — it will wait in the queue…",
|
|
166
|
-
inputLabel: "Message the agent",
|
|
167
|
-
keyboardHint: "Enter to queue · Cmd/Ctrl+Enter to steer · Shift+Enter for a new line",
|
|
168
|
-
slashCommandBlocked:
|
|
169
|
-
"That's a slash command — press Enter in the command list to run it, or edit the line to send a message.",
|
|
170
|
-
controlChangedError:
|
|
171
|
-
"This workstream was paused while you were sending. Nothing was sent, and your draft is still here.",
|
|
172
|
-
sendFailedError: "Sending failed — your draft is still here. Try again.",
|
|
173
|
-
dropFiles: "Drop files to attach",
|
|
174
|
-
attachFiles: "Attach files",
|
|
175
|
-
pauseAriaLabel: "Pause this workstream",
|
|
176
|
-
pauseTitle: "Pause this workstream; queued prompts and approvals are preserved",
|
|
177
|
-
sendMessageAriaLabel: "Send message",
|
|
178
|
-
sendAndResumeAriaLabel: "Add message to queue",
|
|
179
|
-
sendTitle: "Queue message (Enter); steer with Cmd/Ctrl+Enter",
|
|
180
|
-
sendAndResumeTitle: "Add to queue (Enter); steer now with Cmd/Ctrl+Enter",
|
|
181
|
-
workspacePaused: "Workspace paused",
|
|
182
|
-
pausedHere: "Paused here",
|
|
183
|
-
parentBlocker: "parent",
|
|
184
|
-
narrowerPause: "a narrower pause",
|
|
185
|
-
pausedBy: (displayName) => `Paused by ${displayName}`,
|
|
186
|
-
queuedAhead: (count) =>
|
|
187
|
-
`${count} waiting prompt${count === 1 ? "" : "s"}; your message joins the queue.`,
|
|
188
|
-
resumingAndSending: "Sending…",
|
|
189
|
-
nextMessageResumes: "Messages wait in the queue until you resume.",
|
|
190
|
-
resumeThisWorkstream: "Resume this workstream",
|
|
191
|
-
resumeShort: "Resume",
|
|
192
|
-
hidePauseDetails: "Hide pause details",
|
|
193
|
-
showPauseDetails: "Show pause details",
|
|
194
|
-
pauseReasonsLabel: "Reasons this workstream is paused",
|
|
195
|
-
pausedByLabel: "Paused by ",
|
|
196
|
-
alsoPausedByLabel: "Also paused by ",
|
|
197
|
-
resumeWorkspace: "Resume workspace",
|
|
198
|
-
resumeFromSession: "Resume from this session",
|
|
199
|
-
sessionCanRun: "This session will be able to run",
|
|
200
|
-
stillPausedBy: (displayName) => `Still paused by ${displayName}`,
|
|
201
|
-
restoredResourcesLabel: "Restored prompt resources",
|
|
202
|
-
restoredFile: (fileId) => `File ${fileId.slice(0, 8)}`,
|
|
203
|
-
removeRestoredResource: (index) => `Remove restored resource ${index + 1}`,
|
|
204
|
-
uploading: "Uploading",
|
|
205
|
-
uploadFailed: "Upload failed",
|
|
206
|
-
previewAttachment: (name) => `Preview ${name}`,
|
|
207
|
-
attachmentPreviewLabel: "Attachment preview",
|
|
208
|
-
downloadAttachment: (name) => `Download ${name}`,
|
|
209
|
-
closeAttachmentPreview: "Close",
|
|
210
|
-
retryAttachment: (name) => `Retry ${name}`,
|
|
211
|
-
retryUpload: "Retry upload",
|
|
212
|
-
removeAttachment: (name) => `Remove ${name}`,
|
|
213
|
-
confirmCommand: (name) => `Confirm /${name}`,
|
|
214
|
-
confirmDescription: (command) => `Run /${command.name}? ${command.description}`,
|
|
215
|
-
cancel: "Cancel",
|
|
216
|
-
runCommand: (name) => `Run /${name}`,
|
|
217
|
-
commands: "Commands",
|
|
218
|
-
slashCommandsLabel: "Slash commands",
|
|
219
|
-
modelLabel: "Model",
|
|
220
|
-
close: "Close",
|
|
221
|
-
danger: "danger",
|
|
222
|
-
draftConflict: "This draft changed in another tab. Your local draft is still here.",
|
|
223
|
-
useOtherDraft: "Use other draft",
|
|
224
|
-
keepMine: "Keep mine",
|
|
225
|
-
// Kept for embedder message overrides / back-compat. Routine autosave is
|
|
226
|
-
// silent — only draft conflicts surface under the composer.
|
|
227
|
-
savingDraft: "Saving draft…",
|
|
228
|
-
formatBytes,
|
|
229
|
-
formatRelativeTime,
|
|
230
|
-
};
|
|
111
|
+
export { defaultChatComposerMessages } from "../composer-messages";
|
|
112
|
+
export type { ChatComposerMessages } from "../composer-messages";
|
|
231
113
|
|
|
232
114
|
export type ComposerSubmitMode = "queue" | "steer";
|
|
233
115
|
export type ComposerSubmitBlocker =
|
|
@@ -235,9 +117,21 @@ export type ComposerSubmitBlocker =
|
|
|
235
117
|
| "attachment"
|
|
236
118
|
| "sending"
|
|
237
119
|
| "command"
|
|
120
|
+
| "annotations"
|
|
238
121
|
| "empty"
|
|
239
122
|
| null;
|
|
240
123
|
|
|
124
|
+
/**
|
|
125
|
+
* How the composer offers run control.
|
|
126
|
+
* - `pause`: the workstream Pause control and paused-state strip (default; the
|
|
127
|
+
* Opengeni console).
|
|
128
|
+
* - `stop`: a Stop control only while a response runs. Stopping pauses this
|
|
129
|
+
* conversation; the next message continues it, so people never see a paused
|
|
130
|
+
* state they have to resume. Pauses applied elsewhere still show.
|
|
131
|
+
* - `none`: no run control.
|
|
132
|
+
*/
|
|
133
|
+
export type ComposerRunControl = "pause" | "stop" | "none";
|
|
134
|
+
|
|
241
135
|
export type UseChatComposerControllerOptions = {
|
|
242
136
|
delivery: ComposerDelivery;
|
|
243
137
|
draft?: ComposerDraftState | undefined;
|
|
@@ -253,6 +147,10 @@ export type UseChatComposerControllerOptions = {
|
|
|
253
147
|
onClearView?: (() => void) | undefined;
|
|
254
148
|
onPaste?: ((event: ClipboardEvent<HTMLTextAreaElement>) => void) | undefined;
|
|
255
149
|
messages?: Partial<ChatComposerMessages> | undefined;
|
|
150
|
+
/** Run control presentation. Defaults to `pause`. */
|
|
151
|
+
runControl?: ComposerRunControl | undefined;
|
|
152
|
+
/** A response is in progress; shows the Stop control under `runControl="stop"`. */
|
|
153
|
+
running?: boolean | undefined;
|
|
256
154
|
};
|
|
257
155
|
|
|
258
156
|
/**
|
|
@@ -279,7 +177,7 @@ function measureComposerContentHeight(textarea: HTMLTextAreaElement): number {
|
|
|
279
177
|
mirror.tabIndex = -1;
|
|
280
178
|
mirror.rows = 1;
|
|
281
179
|
mirror.style.cssText =
|
|
282
|
-
"position:
|
|
180
|
+
"position:fixed;top:0;left:-100000px;visibility:hidden;pointer-events:none;height:auto;min-height:0;max-height:none;overflow:hidden;z-index:-1;";
|
|
283
181
|
composerHeightMirror = mirror;
|
|
284
182
|
}
|
|
285
183
|
|
|
@@ -359,7 +257,10 @@ export function useChatComposerController({
|
|
|
359
257
|
onClearView,
|
|
360
258
|
onPaste,
|
|
361
259
|
messages: messageOverrides,
|
|
260
|
+
runControl = "pause",
|
|
261
|
+
running = false,
|
|
362
262
|
}: UseChatComposerControllerOptions) {
|
|
263
|
+
const formatError = useErrorMessage();
|
|
363
264
|
const messages = useMemo(
|
|
364
265
|
() => ({ ...defaultChatComposerMessages, ...messageOverrides }),
|
|
365
266
|
[messageOverrides],
|
|
@@ -370,7 +271,24 @@ export function useChatComposerController({
|
|
|
370
271
|
const pauseButtonRef = useRef<HTMLButtonElement | null>(null);
|
|
371
272
|
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
|
372
273
|
const listboxId = useId();
|
|
373
|
-
const
|
|
274
|
+
const controlPaused = effectiveControl?.state === "paused";
|
|
275
|
+
// Set when this composer's Stop paused the conversation; cleared once it runs
|
|
276
|
+
// again. Pauses from anyone or anywhere else are never reinterpreted.
|
|
277
|
+
const [stoppedHere, setStoppedHere] = useState(false);
|
|
278
|
+
useEffect(() => {
|
|
279
|
+
if (!controlPaused) setStoppedHere(false);
|
|
280
|
+
}, [controlPaused]);
|
|
281
|
+
// Under Stop, the stopped response is not a state to manage: hide it and let
|
|
282
|
+
// the next message continue (a Steer resumes a paused branch). It applies
|
|
283
|
+
// only to this conversation's own pause with nothing queued behind it.
|
|
284
|
+
const resumesOnSend =
|
|
285
|
+
runControl === "stop" &&
|
|
286
|
+
stoppedHere &&
|
|
287
|
+
controlPaused &&
|
|
288
|
+
effectiveControl?.directState === "paused" &&
|
|
289
|
+
effectiveControl.additionalBlockerCount === 0 &&
|
|
290
|
+
queuedAheadCount === 0;
|
|
291
|
+
const paused = controlPaused && !resumesOnSend;
|
|
374
292
|
const [controlDetailsOpen, setControlDetailsOpen] = useState(false);
|
|
375
293
|
const [paletteMounted, setPaletteMounted] = useState(false);
|
|
376
294
|
const [submitting, setSubmitting] = useState(false);
|
|
@@ -435,7 +353,6 @@ export function useChatComposerController({
|
|
|
435
353
|
}, [id, paused]);
|
|
436
354
|
|
|
437
355
|
const blockedByAttachment = attachments?.hasUnresolved === true;
|
|
438
|
-
const hasReadyAttachment = (attachments?.readyResources.length ?? 0) > 0;
|
|
439
356
|
|
|
440
357
|
const [dragging, setDragging] = useState(false);
|
|
441
358
|
const dragCarriesFiles = (event: { dataTransfer: DataTransfer | null }): boolean =>
|
|
@@ -444,9 +361,9 @@ export function useChatComposerController({
|
|
|
444
361
|
(event: DragEvent<HTMLDivElement>) => {
|
|
445
362
|
if (!attachments || !dragCarriesFiles(event)) return;
|
|
446
363
|
event.preventDefault();
|
|
447
|
-
setDragging(true);
|
|
364
|
+
if (!disabled) setDragging(true);
|
|
448
365
|
},
|
|
449
|
-
[attachments],
|
|
366
|
+
[attachments, disabled],
|
|
450
367
|
);
|
|
451
368
|
const handleDragLeave = useCallback(
|
|
452
369
|
(event: DragEvent<HTMLDivElement>) => {
|
|
@@ -461,11 +378,16 @@ export function useChatComposerController({
|
|
|
461
378
|
if (!attachments || !dragCarriesFiles(event)) return;
|
|
462
379
|
event.preventDefault();
|
|
463
380
|
setDragging(false);
|
|
464
|
-
if (event.dataTransfer.files.length > 0)
|
|
381
|
+
if (!disabled && event.dataTransfer.files.length > 0)
|
|
382
|
+
attachments.addFiles(event.dataTransfer.files);
|
|
465
383
|
},
|
|
466
|
-
[attachments],
|
|
384
|
+
[attachments, disabled],
|
|
467
385
|
);
|
|
468
386
|
|
|
387
|
+
useEffect(() => {
|
|
388
|
+
if (disabled) setDragging(false);
|
|
389
|
+
}, [disabled]);
|
|
390
|
+
|
|
469
391
|
const [notice, setNotice] = useState<Notice | null>(null);
|
|
470
392
|
const [helpOpen, setHelpOpen] = useState(false);
|
|
471
393
|
const [confirmState, setConfirmState] = useState<ConfirmState>(null);
|
|
@@ -545,6 +467,9 @@ export function useChatComposerController({
|
|
|
545
467
|
});
|
|
546
468
|
const paletteEnabled = commandContext !== undefined;
|
|
547
469
|
const commandDraftBlocked = paletteEnabled && palette.isCommandDraft;
|
|
470
|
+
const annotationsIncomplete = (delivery.annotations ?? []).some(
|
|
471
|
+
(annotation) => annotation.note.trim().length === 0,
|
|
472
|
+
);
|
|
548
473
|
|
|
549
474
|
const submitBlocker: ComposerSubmitBlocker = disabled
|
|
550
475
|
? "disabled"
|
|
@@ -554,9 +479,11 @@ export function useChatComposerController({
|
|
|
554
479
|
? "sending"
|
|
555
480
|
: commandDraftBlocked
|
|
556
481
|
? "command"
|
|
557
|
-
:
|
|
558
|
-
?
|
|
559
|
-
:
|
|
482
|
+
: annotationsIncomplete
|
|
483
|
+
? "annotations"
|
|
484
|
+
: delivery.canSend
|
|
485
|
+
? null
|
|
486
|
+
: "empty";
|
|
560
487
|
const canSubmit = submitBlocker === null;
|
|
561
488
|
|
|
562
489
|
const submit = useCallback(
|
|
@@ -568,23 +495,31 @@ export function useChatComposerController({
|
|
|
568
495
|
}
|
|
569
496
|
if (disabled || blockedByAttachment || delivery.sending || submittingRef.current)
|
|
570
497
|
return false;
|
|
571
|
-
if (
|
|
498
|
+
if (annotationsIncomplete) {
|
|
499
|
+
setNotice({ tone: "error", message: messages.annotationNotesRequired });
|
|
500
|
+
delivery.clearError();
|
|
501
|
+
delivery.requestAnnotationReview?.();
|
|
502
|
+
return false;
|
|
503
|
+
}
|
|
504
|
+
if (!delivery.canSend) return false;
|
|
572
505
|
submittingRef.current = true;
|
|
573
506
|
setSubmitting(true);
|
|
574
507
|
try {
|
|
575
|
-
return mode === "steer" ? await delivery.steer() : await delivery.send();
|
|
508
|
+
return mode === "steer" || resumesOnSend ? await delivery.steer() : await delivery.send();
|
|
576
509
|
} finally {
|
|
577
510
|
submittingRef.current = false;
|
|
578
511
|
if (mountedRef.current) setSubmitting(false);
|
|
579
512
|
}
|
|
580
513
|
},
|
|
581
514
|
[
|
|
515
|
+
annotationsIncomplete,
|
|
582
516
|
blockedByAttachment,
|
|
583
517
|
commandDraftBlocked,
|
|
584
518
|
delivery,
|
|
585
519
|
disabled,
|
|
586
|
-
|
|
520
|
+
messages.annotationNotesRequired,
|
|
587
521
|
messages.slashCommandBlocked,
|
|
522
|
+
resumesOnSend,
|
|
588
523
|
],
|
|
589
524
|
);
|
|
590
525
|
|
|
@@ -599,17 +534,18 @@ export function useChatComposerController({
|
|
|
599
534
|
);
|
|
600
535
|
const handlePaste = useCallback(
|
|
601
536
|
(event: ClipboardEvent<HTMLTextAreaElement>) => {
|
|
537
|
+
if (disabled) return;
|
|
602
538
|
onPaste?.(event);
|
|
603
539
|
attachments?.addFromPaste(event);
|
|
604
540
|
},
|
|
605
|
-
[attachments, onPaste],
|
|
541
|
+
[attachments, disabled, onPaste],
|
|
606
542
|
);
|
|
607
543
|
const handleFileChange = useCallback(
|
|
608
544
|
(event: ChangeEvent<HTMLInputElement>) => {
|
|
609
|
-
if (event.target.files) attachments?.addFiles(event.target.files);
|
|
545
|
+
if (!disabled && event.target.files) attachments?.addFiles(event.target.files);
|
|
610
546
|
event.target.value = "";
|
|
611
547
|
},
|
|
612
|
-
[attachments],
|
|
548
|
+
[attachments, disabled],
|
|
613
549
|
);
|
|
614
550
|
|
|
615
551
|
const helpCommands = useMemo(
|
|
@@ -632,7 +568,10 @@ export function useChatComposerController({
|
|
|
632
568
|
tone: "error" as const,
|
|
633
569
|
message: /control changed|paused while/i.test(delivery.error.message)
|
|
634
570
|
? messages.controlChangedError
|
|
635
|
-
:
|
|
571
|
+
: formatError(
|
|
572
|
+
delivery.error,
|
|
573
|
+
composerSubmissionErrorMessage(delivery.error) || messages.sendFailedError,
|
|
574
|
+
),
|
|
636
575
|
}
|
|
637
576
|
: null);
|
|
638
577
|
useEffect(() => {
|
|
@@ -643,6 +582,12 @@ export function useChatComposerController({
|
|
|
643
582
|
);
|
|
644
583
|
return () => window.clearTimeout(timer);
|
|
645
584
|
}, [notice]);
|
|
585
|
+
useEffect(() => {
|
|
586
|
+
if (annotationsIncomplete) return;
|
|
587
|
+
setNotice((current) =>
|
|
588
|
+
current?.message === messages.annotationNotesRequired ? null : current,
|
|
589
|
+
);
|
|
590
|
+
}, [annotationsIncomplete, messages.annotationNotesRequired]);
|
|
646
591
|
|
|
647
592
|
const runControlOperation = useCallback(async (operation: () => Promise<void>) => {
|
|
648
593
|
if (controlOperationRef.current) return false;
|
|
@@ -677,6 +622,12 @@ export function useChatComposerController({
|
|
|
677
622
|
[control, runControlOperation],
|
|
678
623
|
);
|
|
679
624
|
|
|
625
|
+
const stop = useCallback(async (): Promise<boolean> => {
|
|
626
|
+
const stopped = await pause();
|
|
627
|
+
if (stopped && mountedRef.current) setStoppedHere(true);
|
|
628
|
+
return stopped;
|
|
629
|
+
}, [pause]);
|
|
630
|
+
|
|
680
631
|
return {
|
|
681
632
|
id,
|
|
682
633
|
rootRef,
|
|
@@ -701,9 +652,12 @@ export function useChatComposerController({
|
|
|
701
652
|
removeRestoredResource: draft?.removeRestoredResource,
|
|
702
653
|
resolveDraftConflict: draft?.resolveDraftConflict,
|
|
703
654
|
hasControl: control !== undefined,
|
|
655
|
+
runControl,
|
|
656
|
+
running,
|
|
704
657
|
pausing: control?.pausing ?? false,
|
|
705
658
|
resuming: control?.resuming ?? false,
|
|
706
659
|
pause,
|
|
660
|
+
stop,
|
|
707
661
|
resume,
|
|
708
662
|
resumeScope,
|
|
709
663
|
paused,
|
|
@@ -873,6 +827,7 @@ export const Surface = forwardRef<HTMLDivElement, ComposerSurfaceProps>(function
|
|
|
873
827
|
const controller = useComposerController();
|
|
874
828
|
return (
|
|
875
829
|
<div
|
|
830
|
+
data-og-composer-surface=""
|
|
876
831
|
{...props}
|
|
877
832
|
ref={ref}
|
|
878
833
|
onDragOver={controller.attachments ? controller.handleDragOver : undefined}
|
|
@@ -944,9 +899,11 @@ export function Attachments() {
|
|
|
944
899
|
<AttachmentChips
|
|
945
900
|
attachments={controller.attachments.attachments}
|
|
946
901
|
messages={controller.messages}
|
|
902
|
+
disabled={controller.disabled}
|
|
947
903
|
onRemove={controller.attachments.remove}
|
|
948
904
|
onRetry={controller.attachments.retry}
|
|
949
905
|
onRetainPreview={controller.attachments.retainPreview}
|
|
906
|
+
onLoadPreview={controller.attachments.loadPreview}
|
|
950
907
|
/>
|
|
951
908
|
);
|
|
952
909
|
}
|
|
@@ -964,6 +921,31 @@ type OwnedInputProps =
|
|
|
964
921
|
| "aria-keyshortcuts";
|
|
965
922
|
export type ComposerInputProps = Omit<ComponentPropsWithoutRef<"textarea">, OwnedInputProps>;
|
|
966
923
|
|
|
924
|
+
const EDITING_FOCUS_SELECTOR =
|
|
925
|
+
'input, textarea, select, [contenteditable="true"], [role="textbox"]';
|
|
926
|
+
const POPUP_FOCUS_SELECTOR =
|
|
927
|
+
'[role="menu"], [role="menubar"], [role="listbox"], [role="dialog"], [role="alertdialog"]';
|
|
928
|
+
|
|
929
|
+
/**
|
|
930
|
+
* Initial focus is a convenience, not authority to move focus the person has
|
|
931
|
+
* placed elsewhere. It yields to a field they started editing and to an open
|
|
932
|
+
* menu, listbox, or dialog that does not contain the composer: moving focus
|
|
933
|
+
* behind a non-modal popup dismisses it, and a modal surface owns focus until
|
|
934
|
+
* it closes.
|
|
935
|
+
*/
|
|
936
|
+
function focusBelongsElsewhere(textarea: HTMLTextAreaElement): boolean {
|
|
937
|
+
const active = textarea.ownerDocument.activeElement;
|
|
938
|
+
if (!active || active === textarea) return false;
|
|
939
|
+
if (active.closest(EDITING_FOCUS_SELECTOR)) return true;
|
|
940
|
+
const popup = active.closest(POPUP_FOCUS_SELECTOR);
|
|
941
|
+
if (popup) return !popup.contains(textarea);
|
|
942
|
+
// A dismissed popup can restore a button or link while draft hydration is
|
|
943
|
+
// still pending. Its focus remains intentional after the popup disappears.
|
|
944
|
+
return (
|
|
945
|
+
active !== textarea.ownerDocument.body && active !== textarea.ownerDocument.documentElement
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
|
|
967
949
|
export const Input = forwardRef<HTMLTextAreaElement, ComposerInputProps>(function ComposerInput(
|
|
968
950
|
{ rows = 1, placeholder, className, "aria-label": ariaLabel, autoFocus = false, ...props },
|
|
969
951
|
forwardedRef,
|
|
@@ -973,19 +955,45 @@ export const Input = forwardRef<HTMLTextAreaElement, ComposerInputProps>(functio
|
|
|
973
955
|
const paletteOpen =
|
|
974
956
|
controller.paletteEnabled && controller.paletteMounted && controller.palette.open;
|
|
975
957
|
|
|
976
|
-
//
|
|
977
|
-
// hydrate)
|
|
958
|
+
// Focus once the controller is interactive. The textarea can mount disabled
|
|
959
|
+
// (create-session draft hydrate), and the route can finish loading after the
|
|
960
|
+
// person has already moved on, so this deliberately does not use the native
|
|
961
|
+
// autoFocus attribute: that would take focus at mount without the guard.
|
|
978
962
|
useEffect(() => {
|
|
979
963
|
if (!autoFocus || controller.disabled || autoFocusedRef.current) return;
|
|
980
964
|
const frame = window.requestAnimationFrame(() => {
|
|
981
965
|
const textarea = controller.textareaRef.current;
|
|
982
966
|
if (!textarea || textarea.disabled) return;
|
|
983
967
|
autoFocusedRef.current = true;
|
|
968
|
+
if (focusBelongsElsewhere(textarea)) return;
|
|
984
969
|
textarea.focus();
|
|
985
970
|
});
|
|
986
971
|
return () => window.cancelAnimationFrame(frame);
|
|
987
972
|
}, [autoFocus, controller.disabled, controller.textareaRef]);
|
|
988
973
|
|
|
974
|
+
// Text rewraps when the box gets narrower or wider (panel resize, viewport
|
|
975
|
+
// change), so refit the height on width changes, not only on edits.
|
|
976
|
+
useEffect(() => {
|
|
977
|
+
const textarea = controller.textareaRef.current;
|
|
978
|
+
if (!textarea || typeof ResizeObserver === "undefined") return;
|
|
979
|
+
let width = textarea.clientWidth;
|
|
980
|
+
let frame: number | null = null;
|
|
981
|
+
const observer = new ResizeObserver(() => {
|
|
982
|
+
if (textarea.clientWidth === width) return;
|
|
983
|
+
width = textarea.clientWidth;
|
|
984
|
+
if (frame !== null) return;
|
|
985
|
+
frame = window.requestAnimationFrame(() => {
|
|
986
|
+
frame = null;
|
|
987
|
+
applyComposerTextareaHeight(textarea, 220);
|
|
988
|
+
});
|
|
989
|
+
});
|
|
990
|
+
observer.observe(textarea);
|
|
991
|
+
return () => {
|
|
992
|
+
observer.disconnect();
|
|
993
|
+
if (frame !== null) window.cancelAnimationFrame(frame);
|
|
994
|
+
};
|
|
995
|
+
}, [controller.textareaRef]);
|
|
996
|
+
|
|
989
997
|
return (
|
|
990
998
|
<textarea
|
|
991
999
|
{...props}
|
|
@@ -1001,7 +1009,6 @@ export const Input = forwardRef<HTMLTextAreaElement, ComposerInputProps>(functio
|
|
|
1001
1009
|
: (placeholder ?? controller.messages.messagePlaceholder)
|
|
1002
1010
|
}
|
|
1003
1011
|
disabled={controller.disabled}
|
|
1004
|
-
autoFocus={autoFocus && !controller.disabled}
|
|
1005
1012
|
aria-label={ariaLabel ?? controller.messages.inputLabel}
|
|
1006
1013
|
aria-keyshortcuts="Enter Meta+Enter Control+Enter Shift+Enter"
|
|
1007
1014
|
aria-autocomplete={
|
|
@@ -1066,7 +1073,9 @@ export const Controls = forwardRef<HTMLSpanElement, ComposerControlsProps>(
|
|
|
1066
1073
|
ref={ref}
|
|
1067
1074
|
className={cn(
|
|
1068
1075
|
"og-composer-controls flex min-w-0 flex-1 flex-wrap items-center gap-1.5",
|
|
1069
|
-
|
|
1076
|
+
// Phone: 44px touch targets already space themselves; tight gaps leave
|
|
1077
|
+
// the model pill room for its name.
|
|
1078
|
+
"max-sm:flex-nowrap max-sm:gap-0.5",
|
|
1070
1079
|
className,
|
|
1071
1080
|
)}
|
|
1072
1081
|
/>
|
|
@@ -1107,7 +1116,7 @@ export const Actions = forwardRef<HTMLSpanElement, ComposerActionsProps>(functio
|
|
|
1107
1116
|
ref={ref}
|
|
1108
1117
|
className={cn(
|
|
1109
1118
|
"og-composer-actions ml-auto flex shrink-0 items-center gap-1.5",
|
|
1110
|
-
"max-sm:flex-nowrap max-sm:gap-
|
|
1119
|
+
"max-sm:flex-nowrap max-sm:gap-0.5",
|
|
1111
1120
|
className,
|
|
1112
1121
|
)}
|
|
1113
1122
|
/>
|
|
@@ -1212,12 +1221,19 @@ export const PauseButton = forwardRef<HTMLButtonElement, ComposerPauseButtonProp
|
|
|
1212
1221
|
ref,
|
|
1213
1222
|
) {
|
|
1214
1223
|
const controller = useComposerController();
|
|
1215
|
-
if (
|
|
1224
|
+
if (
|
|
1225
|
+
controller.runControl !== "pause" ||
|
|
1226
|
+
!controller.effectiveControl ||
|
|
1227
|
+
controller.paused ||
|
|
1228
|
+
!controller.hasControl
|
|
1229
|
+
)
|
|
1230
|
+
return null;
|
|
1216
1231
|
const busy = controller.pausing || controller.resuming;
|
|
1217
1232
|
const tip = title ?? controller.messages.pauseTitle;
|
|
1218
1233
|
return (
|
|
1219
1234
|
<ComposerTip tip={tip}>
|
|
1220
1235
|
<button
|
|
1236
|
+
data-analytics-action="pause"
|
|
1221
1237
|
{...props}
|
|
1222
1238
|
ref={mergeRefs(controller.pauseButtonRef, ref)}
|
|
1223
1239
|
type="button"
|
|
@@ -1244,6 +1260,62 @@ export const PauseButton = forwardRef<HTMLButtonElement, ComposerPauseButtonProp
|
|
|
1244
1260
|
},
|
|
1245
1261
|
);
|
|
1246
1262
|
|
|
1263
|
+
export type ComposerStopButtonProps = Omit<
|
|
1264
|
+
ButtonHTMLAttributes<HTMLButtonElement>,
|
|
1265
|
+
OwnedButtonProps
|
|
1266
|
+
>;
|
|
1267
|
+
|
|
1268
|
+
/**
|
|
1269
|
+
* Stop the running response. Rendered only under `runControl="stop"` while a
|
|
1270
|
+
* response runs; stopping pauses this conversation and the next message
|
|
1271
|
+
* continues it.
|
|
1272
|
+
*/
|
|
1273
|
+
export const StopButton = forwardRef<HTMLButtonElement, ComposerStopButtonProps>(
|
|
1274
|
+
function ComposerStopButton(
|
|
1275
|
+
{ className, "aria-label": ariaLabel, title, children, ...props },
|
|
1276
|
+
ref,
|
|
1277
|
+
) {
|
|
1278
|
+
const controller = useComposerController();
|
|
1279
|
+
if (
|
|
1280
|
+
controller.runControl !== "stop" ||
|
|
1281
|
+
!controller.running ||
|
|
1282
|
+
!controller.hasControl ||
|
|
1283
|
+
controller.effectiveControl?.state === "paused"
|
|
1284
|
+
)
|
|
1285
|
+
return null;
|
|
1286
|
+
const busy = controller.pausing;
|
|
1287
|
+
const label = ariaLabel ?? controller.messages.stopAriaLabel ?? "Stop";
|
|
1288
|
+
const tip = title ?? controller.messages.stopTitle ?? label;
|
|
1289
|
+
return (
|
|
1290
|
+
<ComposerTip tip={tip}>
|
|
1291
|
+
<button
|
|
1292
|
+
data-analytics-action="stop"
|
|
1293
|
+
data-og-composer-stop=""
|
|
1294
|
+
{...props}
|
|
1295
|
+
ref={ref}
|
|
1296
|
+
type="button"
|
|
1297
|
+
onClick={() => void controller.stop()}
|
|
1298
|
+
disabled={busy}
|
|
1299
|
+
aria-label={label}
|
|
1300
|
+
className={cn(
|
|
1301
|
+
"inline-flex size-8 items-center justify-center rounded-og-md border border-og-border pointer-coarse:size-11",
|
|
1302
|
+
"bg-og-surface-1 text-og-fg transition-colors duration-150",
|
|
1303
|
+
"hover:bg-og-surface-2 disabled:opacity-50",
|
|
1304
|
+
className,
|
|
1305
|
+
)}
|
|
1306
|
+
>
|
|
1307
|
+
{children ??
|
|
1308
|
+
(busy ? (
|
|
1309
|
+
<LoaderCircleIcon className="size-3.5 animate-og-spin" />
|
|
1310
|
+
) : (
|
|
1311
|
+
<SquareIcon className="size-3 fill-current" />
|
|
1312
|
+
))}
|
|
1313
|
+
</button>
|
|
1314
|
+
</ComposerTip>
|
|
1315
|
+
);
|
|
1316
|
+
},
|
|
1317
|
+
);
|
|
1318
|
+
|
|
1247
1319
|
export type ComposerSendButtonProps = Omit<
|
|
1248
1320
|
ButtonHTMLAttributes<HTMLButtonElement>,
|
|
1249
1321
|
OwnedButtonProps
|
|
@@ -1257,10 +1329,15 @@ export const SendButton = forwardRef<HTMLButtonElement, ComposerSendButtonProps>
|
|
|
1257
1329
|
const controller = useComposerController();
|
|
1258
1330
|
const tip =
|
|
1259
1331
|
title ??
|
|
1260
|
-
(controller.
|
|
1332
|
+
(controller.submitBlocker === "annotations"
|
|
1333
|
+
? controller.messages.annotationNotesRequired
|
|
1334
|
+
: controller.paused
|
|
1335
|
+
? controller.messages.sendAndResumeTitle
|
|
1336
|
+
: controller.messages.sendTitle);
|
|
1261
1337
|
return (
|
|
1262
1338
|
<ComposerTip tip={tip}>
|
|
1263
1339
|
<button
|
|
1340
|
+
data-analytics-action="send"
|
|
1264
1341
|
{...props}
|
|
1265
1342
|
ref={ref}
|
|
1266
1343
|
type="button"
|
|
@@ -1275,10 +1352,10 @@ export const SendButton = forwardRef<HTMLButtonElement, ComposerSendButtonProps>
|
|
|
1275
1352
|
}
|
|
1276
1353
|
className={cn(
|
|
1277
1354
|
"inline-flex size-8 items-center justify-center rounded-og-md pointer-coarse:size-11",
|
|
1278
|
-
"bg-og-
|
|
1355
|
+
"border border-og-primary-border bg-og-primary text-og-primary-fg",
|
|
1279
1356
|
"transition-[background-color,transform,opacity] duration-150 ease-og-spring",
|
|
1280
|
-
"hover:bg-og-
|
|
1281
|
-
"disabled:cursor-not-allowed disabled:
|
|
1357
|
+
"hover:bg-og-primary-hover active:scale-95",
|
|
1358
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
1282
1359
|
className,
|
|
1283
1360
|
)}
|
|
1284
1361
|
>
|
|
@@ -1435,7 +1512,7 @@ function WorkstreamPausedStrip({
|
|
|
1435
1512
|
<button
|
|
1436
1513
|
type="button"
|
|
1437
1514
|
aria-label={messages.resumeThisWorkstream}
|
|
1438
|
-
className="inline-flex min-h-8 shrink-0 items-center gap-1.5 rounded-og-md border border-og-
|
|
1515
|
+
className="inline-flex min-h-8 shrink-0 items-center gap-1.5 rounded-og-md border border-og-primary-border bg-og-primary px-2.5 text-og-xs font-medium text-og-primary-fg hover:bg-og-primary-hover disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:min-h-11"
|
|
1439
1516
|
disabled={busy}
|
|
1440
1517
|
onClick={onResume}
|
|
1441
1518
|
>
|
|
@@ -1635,23 +1712,143 @@ function ConfirmBar({
|
|
|
1635
1712
|
function AttachmentChips({
|
|
1636
1713
|
attachments,
|
|
1637
1714
|
messages,
|
|
1715
|
+
disabled,
|
|
1638
1716
|
onRemove,
|
|
1639
1717
|
onRetry,
|
|
1640
1718
|
onRetainPreview,
|
|
1719
|
+
onLoadPreview,
|
|
1641
1720
|
}: {
|
|
1642
1721
|
attachments: UseFileAttachmentsResult["attachments"];
|
|
1643
1722
|
messages: ChatComposerMessages;
|
|
1723
|
+
disabled: boolean;
|
|
1644
1724
|
onRemove: (id: string) => void;
|
|
1645
1725
|
onRetry?: ((id: string) => void) | undefined;
|
|
1646
1726
|
onRetainPreview: UseFileAttachmentsResult["retainPreview"];
|
|
1727
|
+
onLoadPreview: UseFileAttachmentsResult["loadPreview"];
|
|
1647
1728
|
}) {
|
|
1648
1729
|
const lightbox = useLightboxOptional();
|
|
1730
|
+
const previewRequest = useRef<AbortController | null>(null);
|
|
1731
|
+
const [previewLoadingId, setPreviewLoadingId] = useState<string | null>(null);
|
|
1732
|
+
const [previewErrorId, setPreviewErrorId] = useState<string | null>(null);
|
|
1733
|
+
// Thumbnails always show: an uploaded image without a live local preview (a
|
|
1734
|
+
// restored draft, a revoked or broken object URL) loads its stored copy.
|
|
1735
|
+
const [storedThumbs, setStoredThumbs] = useState<Record<string, string>>({});
|
|
1736
|
+
const [brokenLocal, setBrokenLocal] = useState<ReadonlySet<string>>(() => new Set());
|
|
1737
|
+
const thumbRequests = useRef<Map<string, AbortController>>(new Map());
|
|
1738
|
+
const localPreview = (attachment: UseFileAttachmentsResult["attachments"][number]) =>
|
|
1739
|
+
attachment.previewUrl && !brokenLocal.has(attachment.id) ? attachment.previewUrl : undefined;
|
|
1740
|
+
|
|
1741
|
+
useEffect(() => {
|
|
1742
|
+
if (!onLoadPreview) return;
|
|
1743
|
+
for (const attachment of attachments) {
|
|
1744
|
+
const id = attachment.id;
|
|
1745
|
+
if (
|
|
1746
|
+
attachment.status !== "ready" ||
|
|
1747
|
+
!attachment.file ||
|
|
1748
|
+
!attachment.contentType.startsWith("image/") ||
|
|
1749
|
+
(attachment.previewUrl && !brokenLocal.has(id)) ||
|
|
1750
|
+
storedThumbs[id] ||
|
|
1751
|
+
thumbRequests.current.has(id)
|
|
1752
|
+
) {
|
|
1753
|
+
continue;
|
|
1754
|
+
}
|
|
1755
|
+
const controller = new AbortController();
|
|
1756
|
+
thumbRequests.current.set(id, controller);
|
|
1757
|
+
void onLoadPreview(id, controller.signal)
|
|
1758
|
+
.then((url) => {
|
|
1759
|
+
if (url && !controller.signal.aborted) {
|
|
1760
|
+
setStoredThumbs((current) => ({ ...current, [id]: url }));
|
|
1761
|
+
}
|
|
1762
|
+
})
|
|
1763
|
+
.catch(() => undefined)
|
|
1764
|
+
.finally(() => {
|
|
1765
|
+
if (thumbRequests.current.get(id) === controller) thumbRequests.current.delete(id);
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
}, [attachments, brokenLocal, onLoadPreview, storedThumbs]);
|
|
1769
|
+
useEffect(() => {
|
|
1770
|
+
const requests = thumbRequests.current;
|
|
1771
|
+
return () => {
|
|
1772
|
+
for (const controller of requests.values()) controller.abort();
|
|
1773
|
+
requests.clear();
|
|
1774
|
+
};
|
|
1775
|
+
}, []);
|
|
1776
|
+
|
|
1777
|
+
useEffect(() => () => previewRequest.current?.abort(), [onLoadPreview]);
|
|
1778
|
+
|
|
1779
|
+
async function openPreview(
|
|
1780
|
+
attachment: UseFileAttachmentsResult["attachments"][number],
|
|
1781
|
+
source: HTMLButtonElement,
|
|
1782
|
+
canLoadPreview: boolean,
|
|
1783
|
+
) {
|
|
1784
|
+
previewRequest.current?.abort();
|
|
1785
|
+
const attachmentId = attachment.id;
|
|
1786
|
+
const local = localPreview(attachment);
|
|
1787
|
+
const releaseSource = local ? onRetainPreview(attachmentId) : undefined;
|
|
1788
|
+
let src = local ?? storedThumbs[attachmentId];
|
|
1789
|
+
// An unretained local URL may already be revoked: prefer the stored copy.
|
|
1790
|
+
if (!releaseSource && canLoadPreview) src = storedThumbs[attachmentId];
|
|
1791
|
+
if (!src && canLoadPreview) {
|
|
1792
|
+
const controller = new AbortController();
|
|
1793
|
+
previewRequest.current = controller;
|
|
1794
|
+
setPreviewLoadingId(attachmentId);
|
|
1795
|
+
setPreviewErrorId(null);
|
|
1796
|
+
try {
|
|
1797
|
+
src = await onLoadPreview!(attachmentId, controller.signal);
|
|
1798
|
+
if (controller.signal.aborted) return;
|
|
1799
|
+
if (!src) {
|
|
1800
|
+
setPreviewErrorId(attachmentId);
|
|
1801
|
+
return;
|
|
1802
|
+
}
|
|
1803
|
+
} catch {
|
|
1804
|
+
if (!controller.signal.aborted) setPreviewErrorId(attachmentId);
|
|
1805
|
+
return;
|
|
1806
|
+
} finally {
|
|
1807
|
+
if (previewRequest.current === controller) {
|
|
1808
|
+
setPreviewLoadingId(null);
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
lightbox!.open(
|
|
1813
|
+
src!,
|
|
1814
|
+
attachment.name,
|
|
1815
|
+
source,
|
|
1816
|
+
messages.attachmentPreviewLabel,
|
|
1817
|
+
attachment.name,
|
|
1818
|
+
{
|
|
1819
|
+
download: messages.downloadAttachment(attachment.name),
|
|
1820
|
+
close: messages.closeAttachmentPreview,
|
|
1821
|
+
},
|
|
1822
|
+
releaseSource,
|
|
1823
|
+
);
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1649
1826
|
return (
|
|
1650
1827
|
<div className="flex flex-wrap gap-2 px-3 py-2">
|
|
1651
1828
|
{attachments.map((attachment) => {
|
|
1652
1829
|
const failed = attachment.status === "failed";
|
|
1653
|
-
const
|
|
1654
|
-
|
|
1830
|
+
const secureContextRequired = attachment.errorCode === "secure_context_required";
|
|
1831
|
+
const previewFailed = previewErrorId === attachment.id;
|
|
1832
|
+
const previewLoading = previewLoadingId === attachment.id;
|
|
1833
|
+
const local = localPreview(attachment);
|
|
1834
|
+
const thumb = local ?? storedThumbs[attachment.id];
|
|
1835
|
+
// A local object URL that fails (revoked, unreadable) falls back to the stored copy.
|
|
1836
|
+
const onThumbError = local
|
|
1837
|
+
? () =>
|
|
1838
|
+
setBrokenLocal((current) =>
|
|
1839
|
+
current.has(attachment.id) ? current : new Set(current).add(attachment.id),
|
|
1840
|
+
)
|
|
1841
|
+
: undefined;
|
|
1842
|
+
const canLoadPreview = Boolean(
|
|
1843
|
+
lightbox &&
|
|
1844
|
+
onLoadPreview &&
|
|
1845
|
+
attachment.status === "ready" &&
|
|
1846
|
+
attachment.file &&
|
|
1847
|
+
attachment.contentType.startsWith("image/"),
|
|
1848
|
+
);
|
|
1849
|
+
const statusText = previewFailed
|
|
1850
|
+
? (messages.previewUnavailable ?? "Preview unavailable")
|
|
1851
|
+
: attachment.status === "uploading"
|
|
1655
1852
|
? messages.uploading
|
|
1656
1853
|
: failed
|
|
1657
1854
|
? attachment.error || messages.uploadFailed
|
|
@@ -1660,43 +1857,49 @@ function AttachmentChips({
|
|
|
1660
1857
|
<div
|
|
1661
1858
|
key={attachment.id}
|
|
1662
1859
|
className={cn(
|
|
1663
|
-
"flex min-w-0
|
|
1860
|
+
"flex min-w-0 items-center gap-2 rounded-og-md border px-2 py-1.5 text-og-sm",
|
|
1664
1861
|
failed
|
|
1665
|
-
?
|
|
1666
|
-
|
|
1862
|
+
? cn(
|
|
1863
|
+
"border-og-status-failed/40 bg-og-status-failed/10",
|
|
1864
|
+
secureContextRequired
|
|
1865
|
+
? "max-w-full items-start sm:max-w-[32rem]"
|
|
1866
|
+
: "max-w-[240px]",
|
|
1867
|
+
)
|
|
1868
|
+
: "max-w-[240px] border-og-border bg-og-surface-2",
|
|
1667
1869
|
)}
|
|
1668
1870
|
>
|
|
1669
|
-
{
|
|
1871
|
+
{lightbox && (thumb || canLoadPreview) ? (
|
|
1670
1872
|
<button
|
|
1671
1873
|
type="button"
|
|
1672
|
-
className=
|
|
1874
|
+
className={cn(
|
|
1875
|
+
"size-8 shrink-0 overflow-hidden rounded outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent",
|
|
1876
|
+
!thumb && "flex items-center justify-center disabled:cursor-wait",
|
|
1877
|
+
)}
|
|
1673
1878
|
aria-label={messages.previewAttachment(attachment.name)}
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
event.currentTarget,
|
|
1680
|
-
messages.attachmentPreviewLabel,
|
|
1681
|
-
attachment.name,
|
|
1682
|
-
{
|
|
1683
|
-
download: messages.downloadAttachment(attachment.name),
|
|
1684
|
-
close: messages.closeAttachmentPreview,
|
|
1685
|
-
},
|
|
1686
|
-
releasePreview,
|
|
1687
|
-
);
|
|
1688
|
-
}}
|
|
1879
|
+
aria-busy={previewLoading || undefined}
|
|
1880
|
+
disabled={previewLoading}
|
|
1881
|
+
onClick={(event) =>
|
|
1882
|
+
void openPreview(attachment, event.currentTarget, canLoadPreview)
|
|
1883
|
+
}
|
|
1689
1884
|
>
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1885
|
+
{thumb ? (
|
|
1886
|
+
<img
|
|
1887
|
+
src={thumb}
|
|
1888
|
+
alt=""
|
|
1889
|
+
onError={onThumbError}
|
|
1890
|
+
className="h-full w-full object-cover transition-opacity hover:opacity-80"
|
|
1891
|
+
/>
|
|
1892
|
+
) : previewLoading ? (
|
|
1893
|
+
<LoaderCircleIcon className="size-4 animate-og-spin text-og-fg-muted" />
|
|
1894
|
+
) : (
|
|
1895
|
+
<ImageIcon className="size-4 text-og-fg-muted" />
|
|
1896
|
+
)}
|
|
1695
1897
|
</button>
|
|
1696
|
-
) :
|
|
1898
|
+
) : thumb ? (
|
|
1697
1899
|
<img
|
|
1698
|
-
src={
|
|
1900
|
+
src={thumb}
|
|
1699
1901
|
alt=""
|
|
1902
|
+
onError={onThumbError}
|
|
1700
1903
|
className="size-8 shrink-0 rounded object-cover"
|
|
1701
1904
|
/>
|
|
1702
1905
|
) : attachment.contentType.startsWith("image/") ? (
|
|
@@ -1706,7 +1909,11 @@ function AttachmentChips({
|
|
|
1706
1909
|
)}
|
|
1707
1910
|
<div className="min-w-0 flex-1">
|
|
1708
1911
|
<div className="truncate font-medium text-og-fg">{attachment.name}</div>
|
|
1709
|
-
{
|
|
1912
|
+
{secureContextRequired ? (
|
|
1913
|
+
<div className="break-words text-og-xs leading-4 text-og-status-failed">
|
|
1914
|
+
{statusText}
|
|
1915
|
+
</div>
|
|
1916
|
+
) : failed || previewFailed ? (
|
|
1710
1917
|
<ComposerTip tip={statusText}>
|
|
1711
1918
|
<div className="truncate text-og-xs text-og-status-failed">{statusText}</div>
|
|
1712
1919
|
</ComposerTip>
|
|
@@ -1717,12 +1924,13 @@ function AttachmentChips({
|
|
|
1717
1924
|
{attachment.status === "uploading" ? (
|
|
1718
1925
|
<LoaderCircleIcon className="size-3.5 shrink-0 animate-og-spin" />
|
|
1719
1926
|
) : null}
|
|
1720
|
-
{failed && onRetry ? (
|
|
1927
|
+
{failed && !secureContextRequired && onRetry ? (
|
|
1721
1928
|
<ComposerTip tip={messages.retryUpload}>
|
|
1722
1929
|
<button
|
|
1723
1930
|
type="button"
|
|
1724
1931
|
onClick={() => onRetry(attachment.id)}
|
|
1725
|
-
|
|
1932
|
+
disabled={disabled}
|
|
1933
|
+
className="shrink-0 rounded-og-xs p-1 text-og-fg-muted hover:bg-og-surface-1 hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-10"
|
|
1726
1934
|
aria-label={messages.retryAttachment(attachment.name)}
|
|
1727
1935
|
>
|
|
1728
1936
|
<RotateCwIcon className="size-3.5" />
|
|
@@ -1732,7 +1940,8 @@ function AttachmentChips({
|
|
|
1732
1940
|
<button
|
|
1733
1941
|
type="button"
|
|
1734
1942
|
onClick={() => onRemove(attachment.id)}
|
|
1735
|
-
|
|
1943
|
+
disabled={disabled}
|
|
1944
|
+
className="shrink-0 rounded-og-xs p-1 text-og-fg-muted hover:bg-og-surface-1 hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-10"
|
|
1736
1945
|
aria-label={messages.removeAttachment(attachment.name)}
|
|
1737
1946
|
>
|
|
1738
1947
|
<XIcon className="size-3.5" />
|