@opengeni/react 0.57.0 → 1.0.2-canary.37191796234001
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 +654 -22
- package/dist/accounts.d.ts +64 -0
- package/dist/accounts.js +822 -0
- package/dist/accounts.js.map +1 -0
- package/dist/approvals.d.ts +2 -1
- package/dist/artifacts-document.js +3 -2
- package/dist/artifacts-presentation.js +3 -2
- package/dist/artifacts-spreadsheet.js +2 -2
- package/dist/artifacts.d.ts +4 -1
- package/dist/artifacts.js +518 -42
- package/dist/artifacts.js.map +1 -1
- package/dist/browser-viewer-GTR5XQ7X.js +16 -0
- package/dist/capability-catalog-row.d.ts +20 -0
- package/dist/capability-logo-fallback.d.ts +3 -0
- package/dist/chat-interactive-block-UGBTNB3L.js +11 -0
- package/dist/chat-interactive-block-UGBTNB3L.js.map +1 -0
- package/dist/{chunk-5UQPNLIO.js → chunk-23J2ZNXT.js} +4117 -3896
- package/dist/chunk-23J2ZNXT.js.map +1 -0
- package/dist/chunk-447JLCBU.js +209 -0
- package/dist/chunk-447JLCBU.js.map +1 -0
- package/dist/chunk-4RVYOY4O.js +379 -0
- package/dist/chunk-4RVYOY4O.js.map +1 -0
- package/dist/chunk-5CVXZA3Y.js +292 -0
- package/dist/chunk-5CVXZA3Y.js.map +1 -0
- package/dist/chunk-5J4FOW6Q.js +108 -0
- package/dist/chunk-5J4FOW6Q.js.map +1 -0
- package/dist/chunk-A2PI6UMY.js +41 -0
- package/dist/chunk-A2PI6UMY.js.map +1 -0
- package/dist/{chunk-7WCLAEFV.js → chunk-A4UJB2MM.js} +37 -27
- package/dist/chunk-A4UJB2MM.js.map +1 -0
- package/dist/chunk-B3V6TG77.js +41 -0
- package/dist/chunk-B3V6TG77.js.map +1 -0
- package/dist/chunk-BRM6FVZA.js +302 -0
- package/dist/chunk-BRM6FVZA.js.map +1 -0
- package/dist/chunk-C5X5AJXK.js +182 -0
- package/dist/chunk-C5X5AJXK.js.map +1 -0
- package/dist/chunk-CR7U7HAR.js +453 -0
- package/dist/chunk-CR7U7HAR.js.map +1 -0
- package/dist/{chunk-R3AZOAB5.js → chunk-DYWBUX5Q.js} +29 -123
- package/dist/chunk-DYWBUX5Q.js.map +1 -0
- package/dist/chunk-E3G7SAYZ.js +3124 -0
- package/dist/chunk-E3G7SAYZ.js.map +1 -0
- package/dist/chunk-ELCE5SXV.js +359 -0
- package/dist/chunk-ELCE5SXV.js.map +1 -0
- package/dist/chunk-ERGYJIBB.js +21 -0
- package/dist/chunk-ERGYJIBB.js.map +1 -0
- package/dist/chunk-FFA2OVOV.js +319 -0
- package/dist/chunk-FFA2OVOV.js.map +1 -0
- package/dist/chunk-FZCP527Y.js +116 -0
- package/dist/chunk-FZCP527Y.js.map +1 -0
- package/dist/chunk-GIMRELBW.js +14 -0
- package/dist/chunk-GIMRELBW.js.map +1 -0
- package/dist/{chunk-6KLX2RH5.js → chunk-H2NJQORO.js} +1069 -79
- package/dist/chunk-H2NJQORO.js.map +1 -0
- package/dist/chunk-I7IWRQLN.js +1608 -0
- package/dist/chunk-I7IWRQLN.js.map +1 -0
- package/dist/{chunk-HA46CYQK.js → chunk-IQUCRAT7.js} +792 -537
- package/dist/chunk-IQUCRAT7.js.map +1 -0
- package/dist/chunk-IWIDV7SB.js +1 -0
- package/dist/chunk-IWIDV7SB.js.map +1 -0
- package/dist/chunk-J2QWVSQY.js +312 -0
- package/dist/chunk-J2QWVSQY.js.map +1 -0
- package/dist/chunk-JFNEV4LU.js +2733 -0
- package/dist/chunk-JFNEV4LU.js.map +1 -0
- package/dist/chunk-JT4JW7BC.js +54 -0
- package/dist/chunk-JT4JW7BC.js.map +1 -0
- package/dist/chunk-K3HQAKQX.js +24 -0
- package/dist/chunk-K3HQAKQX.js.map +1 -0
- package/dist/{chunk-C5ZPSSS5.js → chunk-NEXLLTP4.js} +2 -1
- package/dist/{chunk-C5ZPSSS5.js.map → chunk-NEXLLTP4.js.map} +1 -1
- package/dist/chunk-NZUI76EM.js +371 -0
- package/dist/chunk-NZUI76EM.js.map +1 -0
- package/dist/{chunk-PEI6RANI.js → chunk-PNY3JKBJ.js} +309 -74
- package/dist/chunk-PNY3JKBJ.js.map +1 -0
- package/dist/{chunk-IGC6A2ZI.js → chunk-Q5QBEZIQ.js} +777 -246
- package/dist/chunk-Q5QBEZIQ.js.map +1 -0
- package/dist/chunk-RHREZ7BO.js +11 -0
- package/dist/chunk-RHREZ7BO.js.map +1 -0
- package/dist/chunk-SCOTPE2I.js +589 -0
- package/dist/chunk-SCOTPE2I.js.map +1 -0
- package/dist/{chunk-B6WPZSTT.js → chunk-SJZDKVW2.js} +1331 -1163
- package/dist/chunk-SJZDKVW2.js.map +1 -0
- package/dist/chunk-TMJRG4YC.js +12803 -0
- package/dist/chunk-TMJRG4YC.js.map +1 -0
- package/dist/chunk-TMYGL6X5.js +742 -0
- package/dist/chunk-TMYGL6X5.js.map +1 -0
- package/dist/chunk-UGLEYEMP.js +33 -0
- package/dist/chunk-UGLEYEMP.js.map +1 -0
- package/dist/chunk-UK4TINKT.js +27 -0
- package/dist/chunk-UK4TINKT.js.map +1 -0
- package/dist/chunk-UTRTG6LH.js +220 -0
- package/dist/chunk-UTRTG6LH.js.map +1 -0
- package/dist/chunk-WEHMPOXK.js +39 -0
- package/dist/chunk-WEHMPOXK.js.map +1 -0
- package/dist/chunk-WRHIZYZF.js +988 -0
- package/dist/chunk-WRHIZYZF.js.map +1 -0
- package/dist/{chunk-HUIKIDM5.js → chunk-WUISZ3WU.js} +223 -115
- package/dist/chunk-WUISZ3WU.js.map +1 -0
- package/dist/chunk-XCHWDJ22.js +107 -0
- package/dist/chunk-XCHWDJ22.js.map +1 -0
- package/dist/chunk-XOAMRDDK.js +481 -0
- package/dist/chunk-XOAMRDDK.js.map +1 -0
- package/dist/chunk-XUW2UWQM.js +299 -0
- package/dist/chunk-XUW2UWQM.js.map +1 -0
- package/dist/{chunk-KCGXPP5V.js → chunk-Y2PRMYLC.js} +11 -6
- package/dist/chunk-Y2PRMYLC.js.map +1 -0
- package/dist/chunk-YBXQDQFX.js +1772 -0
- package/dist/chunk-YBXQDQFX.js.map +1 -0
- package/dist/{chunk-KZ73RL76.js → chunk-YQEAA6LT.js} +7 -3
- package/dist/chunk-YQEAA6LT.js.map +1 -0
- package/dist/chunk-YV4L3ILF.js +9 -0
- package/dist/chunk-YV4L3ILF.js.map +1 -0
- package/dist/{chunk-LLOLUHVG.js → chunk-YWFG7ZX7.js} +1358 -2746
- package/dist/chunk-YWFG7ZX7.js.map +1 -0
- package/dist/chunk-ZYRGEKWS.js +216 -0
- package/dist/chunk-ZYRGEKWS.js.map +1 -0
- package/dist/client.d.ts +7 -4
- package/dist/clipboard.js +1 -0
- package/dist/commands/types.d.ts +2 -0
- package/dist/components/anthropic-mark.d.ts +3 -0
- package/dist/components/approval-surface.d.ts +15 -0
- package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
- package/dist/components/artifacts/artifact-sandbox.d.ts +27 -0
- package/dist/components/artifacts/artifact-surface.d.ts +3 -1
- 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 +46 -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 +2 -1
- package/dist/components/artifacts/index.d.ts +8 -1
- 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 +48 -3
- package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
- package/dist/components/artifacts/site-view.d.ts +23 -0
- package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -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 +10 -1
- package/dist/components/chat-composer.d.ts +21 -3
- package/dist/components/child-session-link.d.ts +5 -0
- package/dist/components/claude-mark.d.ts +3 -0
- package/dist/components/code-editor.d.ts +1 -4
- package/dist/components/composer.d.ts +45 -4
- package/dist/components/computer-viewer.d.ts +4 -1
- package/dist/components/copy-button.d.ts +3 -1
- package/dist/components/desktop-viewer.d.ts +1 -1
- package/dist/components/enrollment-consent.d.ts +6 -3
- package/dist/components/file-browser.d.ts +10 -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 +21 -2
- package/dist/components/human-input-surface.d.ts +6 -3
- package/dist/components/machine-card.d.ts +4 -1
- package/dist/components/machines/machine-detail.d.ts +4 -1
- package/dist/components/machines/machine-operation-policy.d.ts +11 -0
- package/dist/components/machines-dashboard.d.ts +3 -1
- package/dist/components/markdown-table-layout.d.ts +12 -0
- package/dist/components/markdown.d.ts +47 -3
- package/dist/components/message-timeline.d.ts +72 -9
- 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 +62 -13
- package/dist/components/open-geni-chat.d.ts +55 -0
- package/dist/components/open-geni-links.d.ts +68 -0
- package/dist/components/openrouter-mark.d.ts +6 -0
- package/dist/components/pierre-file.d.ts +1 -1
- package/dist/components/preview-loading.d.ts +2 -0
- package/dist/components/queue-item-content.d.ts +9 -0
- package/dist/components/sandbox-files.d.ts +13 -2
- package/dist/components/sandbox-workspace.d.ts +43 -3
- package/dist/components/session-capability-frame.d.ts +35 -0
- package/dist/components/session-chrome.d.ts +66 -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 +86 -0
- package/dist/components/session-list.d.ts +36 -0
- package/dist/components/session-mcp-capability-card.d.ts +41 -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/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/components/workspace-dock.d.ts +6 -2
- package/dist/composer.d.ts +5 -4
- package/dist/composer.js +15 -9
- package/dist/computer-viewer-ENHVAZ2Q.js +19 -0
- package/dist/computer-viewer-ENHVAZ2Q.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 +16 -0
- package/dist/connect.d.ts +21 -0
- package/dist/connect.js +2129 -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 +26 -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 +14 -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 +21 -0
- package/dist/editor.js.map +1 -0
- package/dist/embedded-session-client.d.ts +23 -0
- package/dist/file-node-visibility.d.ts +15 -0
- package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-YZ3ZKWMM.js} +2 -1
- package/dist/fleet-decision-row-YZ3ZKWMM.js.map +1 -0
- package/dist/hooks/channel-cache.d.ts +23 -0
- package/dist/hooks/latest-question.d.ts +25 -0
- package/dist/hooks/shared-machines-list.d.ts +14 -0
- package/dist/hooks/use-attached-browsers.d.ts +2 -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-channels.d.ts +1 -0
- package/dist/hooks/use-codex-accounts.d.ts +25 -7
- package/dist/hooks/use-composer.d.ts +45 -9
- 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 +2 -0
- package/dist/hooks/use-connect.d.ts +22 -0
- package/dist/hooks/use-desktop-stream.d.ts +1 -1
- package/dist/hooks/use-file-attachments.d.ts +21 -2
- package/dist/hooks/use-machine-chip.d.ts +3 -3
- package/dist/hooks/use-machines.d.ts +19 -1
- package/dist/hooks/use-sandbox-files.d.ts +5 -1
- package/dist/hooks/use-session-background-commands.d.ts +14 -0
- package/dist/hooks/use-session-events.d.ts +30 -8
- package/dist/hooks/use-session-lineage.d.ts +4 -0
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
- package/dist/hooks/use-session.d.ts +6 -0
- package/dist/hooks/use-turn-queue.d.ts +12 -0
- package/dist/hooks/use-usage.d.ts +40 -0
- package/dist/hooks/use-workspace-edit.d.ts +4 -0
- package/dist/hooks/use-workspace-sessions.d.ts +27 -5
- package/dist/human-input.d.ts +3 -1
- package/dist/identity-link-accounts.d.ts +11 -0
- package/dist/identity-link-consent.d.ts +18 -0
- package/dist/index.d.ts +60 -17
- package/dist/index.js +2237 -6200
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +1 -1
- package/dist/interaction.js +35 -184
- package/dist/interaction.js.map +1 -1
- package/dist/latest-question-755OW5DS.js +117 -0
- package/dist/latest-question-755OW5DS.js.map +1 -0
- package/dist/lib/error-message.d.ts +7 -0
- package/dist/lib/format.d.ts +36 -2
- package/dist/lib/host-theme.d.ts +70 -0
- package/dist/lib/interaction-errors.d.ts +6 -0
- package/dist/lib/menu-styles.d.ts +22 -0
- package/dist/lib/pierre-diffs-loader.d.ts +20 -0
- package/dist/lib/workbench-peers.d.ts +36 -0
- package/dist/lib/xterm-theme.d.ts +7 -5
- package/dist/machines.d.ts +4 -2
- package/dist/machines.js +14 -4
- package/dist/markdown-table-layout-QXSLK4BY.js +106 -0
- package/dist/markdown-table-layout-QXSLK4BY.js.map +1 -0
- package/dist/mcp-connection-status.d.ts +14 -0
- package/dist/model-policy-picker-menu-PWRI7R2X.js +14 -0
- package/dist/model-policy-picker-menu-PWRI7R2X.js.map +1 -0
- package/dist/model-policy.d.ts +19 -3
- package/dist/model-policy.js +9 -1
- package/dist/older-history.d.ts +30 -0
- package/dist/platform-activity-row-627BFZ46.js +182 -0
- package/dist/platform-activity-row-627BFZ46.js.map +1 -0
- package/dist/plugin-details.d.ts +14 -0
- package/dist/plugin-discovery.d.ts +25 -0
- package/dist/provider.d.ts +13 -1
- package/dist/{queue-surface-implementation-2KVJTYXH.js → queue-surface-implementation-ZHFI5JBP.js} +131 -44
- package/dist/queue-surface-implementation-ZHFI5JBP.js.map +1 -0
- package/dist/realtime/realtime-control.d.ts +10 -3
- package/dist/realtime.js +229 -83
- package/dist/realtime.js.map +1 -1
- package/dist/sandbox-files-BBC47SLD.js +20 -0
- package/dist/sandbox-files-BBC47SLD.js.map +1 -0
- package/dist/session-auth-recommendation.d.ts +5 -0
- package/dist/session-capability-policy.d.ts +12 -0
- package/dist/session-ui.d.ts +30 -2
- package/dist/session-ui.js +85 -7
- package/dist/session-ui.js.map +1 -1
- package/dist/session.d.ts +8 -2
- package/dist/session.js +30 -19
- package/dist/sites-ui.d.ts +34 -0
- package/dist/sites.d.ts +3 -0
- package/dist/sites.js +11 -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 +31 -0
- package/dist/terminal.js.map +1 -0
- package/dist/timeline/activity-rail.d.ts +11 -2
- package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
- package/dist/timeline/compaction-copy.d.ts +10 -0
- package/dist/timeline/entrance.d.ts +13 -1
- package/dist/timeline/genie-loading.d.ts +34 -0
- package/dist/timeline/index.d.ts +6 -2
- package/dist/timeline/knowledge-receipt.d.ts +17 -0
- package/dist/timeline/platform-activity-row.d.ts +14 -0
- package/dist/timeline/presented-image.d.ts +6 -0
- package/dist/timeline/projection.d.ts +31 -2
- package/dist/timeline/registry.d.ts +2 -0
- package/dist/timeline/retained-image.d.ts +18 -0
- package/dist/timeline/rolling-activity.d.ts +11 -0
- package/dist/timeline/screenshot-lightbox.d.ts +16 -1
- package/dist/timeline/shared.d.ts +8 -3
- 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 +2 -1
- package/dist/timeline/turn-summary.d.ts +32 -3
- package/dist/timeline/types.d.ts +141 -7
- package/dist/timeline-annotation-markers-GNDHTGBD.js +165 -0
- package/dist/timeline-annotation-markers-GNDHTGBD.js.map +1 -0
- package/dist/timeline-annotation-selection-DMLMM2TX.js +241 -0
- package/dist/timeline-annotation-selection-DMLMM2TX.js.map +1 -0
- package/dist/timeline-annotations-dialog-ELRDBHTS.js +273 -0
- package/dist/timeline-annotations-dialog-ELRDBHTS.js.map +1 -0
- package/dist/types/machines.d.ts +2 -2
- package/dist/usage/allowance-copy.d.ts +25 -0
- package/dist/usage/summary.d.ts +35 -0
- package/dist/usage.d.ts +13 -0
- package/dist/usage.js +1074 -0
- package/dist/usage.js.map +1 -0
- package/package.json +44 -4
- package/src/accounts.tsx +1072 -0
- package/src/approvals.ts +8 -1
- package/src/artifacts.ts +42 -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 +22 -13
- 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 +171 -37
- package/src/components/artifacts/artifact-chrome.tsx +413 -0
- package/src/components/artifacts/artifact-sandbox.tsx +185 -0
- package/src/components/artifacts/artifact-surface.tsx +39 -19
- 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 +187 -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 +5 -2
- package/src/components/artifacts/index.ts +44 -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 +338 -5
- package/src/components/artifacts/session-artifact-viewer.tsx +376 -0
- package/src/components/artifacts/site-view.tsx +116 -0
- package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
- package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
- package/src/components/artifacts/spreadsheet-grid.tsx +12 -13
- 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 +1054 -314
- package/src/components/chat-composer.tsx +131 -85
- package/src/components/child-session-link.tsx +27 -0
- package/src/components/claude-mark.tsx +10 -0
- package/src/components/code-editor.tsx +13 -16
- package/src/components/composer-transcription-control.tsx +7 -5
- package/src/components/composer.tsx +376 -49
- package/src/components/computer-viewer.tsx +1041 -329
- package/src/components/copy-button.tsx +13 -5
- package/src/components/desktop-viewer.tsx +1 -1
- package/src/components/enrollment-consent.tsx +65 -7
- package/src/components/enrollment-device-flow.tsx +1 -1
- package/src/components/file-browser.tsx +158 -34
- package/src/components/fleet-tile.tsx +8 -16
- package/src/components/generated-video-player.tsx +4 -2
- package/src/components/grok-mark.tsx +33 -0
- package/src/components/human-input-form.tsx +455 -114
- package/src/components/human-input-surface.tsx +18 -7
- package/src/components/interaction-intervention-banner.tsx +2 -2
- package/src/components/machine-card.tsx +119 -4
- package/src/components/machine-dock-bar.tsx +1 -1
- package/src/components/machine-input-display.ts +23 -2
- package/src/components/machines/machine-detail.tsx +52 -2
- package/src/components/machines/machine-operation-policy.tsx +179 -0
- package/src/components/machines-dashboard.tsx +8 -17
- package/src/components/markdown-table-layout.ts +132 -0
- package/src/components/markdown.tsx +473 -44
- package/src/components/message-timeline.tsx +2498 -663
- package/src/components/model-mark.tsx +90 -0
- package/src/components/model-picker.tsx +15 -4
- package/src/components/model-policy-picker-menu.tsx +424 -0
- package/src/components/model-policy-picker.tsx +337 -381
- package/src/components/open-geni-chat.tsx +319 -0
- package/src/components/open-geni-links.tsx +179 -0
- package/src/components/openrouter-mark.tsx +13 -0
- package/src/components/pierre-diff.tsx +41 -16
- package/src/components/pierre-file.tsx +36 -11
- package/src/components/preview-loading.tsx +154 -0
- package/src/components/queue-item-content.ts +14 -0
- package/src/components/queue-surface-implementation.tsx +132 -42
- package/src/components/queue-surface-state.tsx +3 -1
- package/src/components/sandbox-files.tsx +267 -35
- package/src/components/sandbox-terminal.tsx +48 -11
- package/src/components/sandbox-workspace.tsx +337 -135
- package/src/components/session-capability-frame.tsx +192 -0
- package/src/components/session-chrome.tsx +1027 -328
- 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 +512 -0
- package/src/components/session-list.tsx +250 -0
- package/src/components/session-mcp-capability-card.tsx +680 -0
- package/src/components/session-status.tsx +1 -1
- 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 +70 -7
- 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 +194 -49
- package/src/components/workspace-dock.tsx +141 -175
- 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 +307 -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 +235 -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/embedded-session-client.ts +104 -0
- package/src/file-node-visibility.ts +66 -0
- package/src/hooks/channel-cache.ts +104 -0
- package/src/hooks/internal.ts +3 -2
- package/src/hooks/latest-question.ts +164 -0
- package/src/hooks/shared-machines-list.ts +239 -0
- package/src/hooks/use-attached-browsers.ts +5 -1
- package/src/hooks/use-available-models.ts +20 -14
- package/src/hooks/use-browser-frame-stream.ts +25 -3
- package/src/hooks/use-browser-session.ts +271 -71
- package/src/hooks/use-browser-sessions.ts +7 -1
- package/src/hooks/use-channels.ts +32 -10
- package/src/hooks/use-codex-accounts.ts +78 -21
- package/src/hooks/use-composer.ts +1034 -320
- package/src/hooks/use-computer-frame-stream.ts +39 -16
- package/src/hooks/use-computer-input-posture.ts +94 -0
- package/src/hooks/use-computer-session.ts +110 -32
- package/src/hooks/use-computer-sessions.ts +8 -1
- package/src/hooks/use-connect.ts +23 -0
- package/src/hooks/use-desktop-stream.ts +19 -28
- package/src/hooks/use-file-attachments.ts +118 -10
- package/src/hooks/use-goal.ts +36 -9
- package/src/hooks/use-human-input.ts +31 -4
- package/src/hooks/use-last-started-turn-policy.ts +15 -13
- package/src/hooks/use-machine-chip.ts +23 -6
- package/src/hooks/use-machines.ts +104 -6
- package/src/hooks/use-sandbox-files.ts +253 -150
- package/src/hooks/use-sandbox-git.ts +58 -29
- package/src/hooks/use-session-background-commands.ts +67 -0
- package/src/hooks/use-session-capabilities.ts +21 -2
- package/src/hooks/use-session-events.ts +759 -433
- package/src/hooks/use-session-lineage.ts +28 -6
- package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
- package/src/hooks/use-session.ts +75 -16
- package/src/hooks/use-slash-commands.ts +6 -11
- package/src/hooks/use-turn-queue.ts +113 -13
- package/src/hooks/use-usage.ts +100 -0
- package/src/hooks/use-voice-input.ts +12 -1
- 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 +99 -11
- package/src/human-input.ts +12 -1
- package/src/identity-link-accounts.tsx +148 -0
- package/src/identity-link-consent.tsx +192 -0
- package/src/index.ts +157 -12
- package/src/interaction.ts +1 -0
- package/src/lib/error-message.ts +37 -0
- package/src/lib/format.ts +150 -14
- package/src/lib/host-theme.ts +511 -0
- package/src/lib/interaction-errors.ts +33 -0
- package/src/lib/menu-styles.ts +44 -0
- package/src/lib/pierre-diffs-loader.ts +53 -0
- package/src/lib/workbench-peers.ts +62 -0
- package/src/lib/xterm-theme.ts +23 -21
- package/src/machines.ts +9 -1
- package/src/mcp-connection-status.ts +35 -0
- package/src/model-policy.ts +223 -69
- package/src/older-history.ts +87 -0
- package/src/plugin-details.tsx +185 -0
- package/src/plugin-discovery.tsx +196 -0
- package/src/provider.tsx +55 -14
- package/src/realtime/dropdown-menu.tsx +19 -12
- package/src/realtime/realtime-control.tsx +274 -60
- package/src/session-auth-recommendation.ts +48 -0
- package/src/session-capability-policy.ts +83 -0
- package/src/session-context.ts +1 -0
- package/src/session-ui.ts +66 -2
- package/src/session.ts +18 -1
- package/src/sites-ui.tsx +402 -0
- package/src/sites.ts +3 -0
- package/src/skill-discovery.tsx +208 -0
- package/src/terminal.ts +26 -0
- package/src/timeline/activity-rail.tsx +171 -80
- package/src/timeline/allowance-exhausted-row.tsx +86 -0
- package/src/timeline/compaction-copy.ts +42 -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/genie-loading.tsx +136 -0
- package/src/timeline/index.ts +11 -0
- package/src/timeline/knowledge-receipt.tsx +100 -0
- package/src/timeline/parsers.ts +2 -2
- package/src/timeline/platform-activity-row.tsx +216 -0
- package/src/timeline/presented-image.ts +49 -0
- package/src/timeline/projection.ts +1600 -84
- package/src/timeline/registry.ts +15 -3
- package/src/timeline/retained-image.ts +97 -0
- package/src/timeline/rolling-activity.tsx +92 -0
- package/src/timeline/screenshot-lightbox.tsx +115 -17
- package/src/timeline/shared.tsx +47 -15
- package/src/timeline/startup-preference.ts +33 -0
- package/src/timeline/startup-timings.tsx +145 -0
- package/src/timeline/tool-display-name.ts +8 -6
- package/src/timeline/tool-renderers.tsx +497 -128
- package/src/timeline/turn-summary.tsx +208 -44
- package/src/timeline/types.ts +186 -7
- package/src/types/machines.ts +10 -0
- package/src/usage/allowance-copy.ts +64 -0
- package/src/usage/summary.ts +93 -0
- package/src/usage.ts +50 -0
- package/styles/compiled.css +2098 -757
- package/styles/connect.css +284 -0
- package/styles/connect.d.ts +1 -0
- package/styles/effective-tokens.css +1 -0
- package/styles/index.css +201 -9
- package/styles/responsive.css +27 -1
- package/styles/session-capability.css +44 -0
- package/styles/tokens.css +135 -65
- package/dist/chunk-5UQPNLIO.js.map +0 -1
- package/dist/chunk-6KLX2RH5.js.map +0 -1
- package/dist/chunk-7WCLAEFV.js.map +0 -1
- package/dist/chunk-B6WPZSTT.js.map +0 -1
- package/dist/chunk-FK6VG4LL.js +0 -90
- package/dist/chunk-FK6VG4LL.js.map +0 -1
- package/dist/chunk-HA46CYQK.js.map +0 -1
- package/dist/chunk-HUIKIDM5.js.map +0 -1
- package/dist/chunk-IGC6A2ZI.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-LLOLUHVG.js.map +0 -1
- package/dist/chunk-MKPIAGVL.js +0 -465
- package/dist/chunk-MKPIAGVL.js.map +0 -1
- package/dist/chunk-PEI6RANI.js.map +0 -1
- package/dist/chunk-R3AZOAB5.js.map +0 -1
- package/dist/chunk-WSK7G5LE.js +0 -170
- package/dist/chunk-WSK7G5LE.js.map +0 -1
- package/dist/chunk-XBZWOM2K.js +0 -218
- package/dist/chunk-XBZWOM2K.js.map +0 -1
- package/dist/chunk-Y7OEDUJ5.js +0 -8810
- package/dist/chunk-Y7OEDUJ5.js.map +0 -1
- package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
- package/dist/hooks/use-packs.d.ts +0 -32
- package/dist/interactive-workbench-viewers-TOHBXJEE.js +0 -15
- package/dist/queue-surface-implementation-2KVJTYXH.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-packs.ts +0 -157
- /package/dist/{interactive-workbench-viewers-TOHBXJEE.js.map → browser-viewer-GTR5XQ7X.js.map} +0 -0
|
@@ -45,6 +45,7 @@ import { xtermThemeFromTokens } from "../lib/xterm-theme";
|
|
|
45
45
|
import { sandboxAcceptsLiveIo } from "../lib/sandbox-liveness";
|
|
46
46
|
import type { BrowserFrameWebSocketFactory } from "../hooks/use-browser-frame-stream";
|
|
47
47
|
import type { ComputerFrameWebSocketFactory } from "../hooks/use-computer-frame-stream";
|
|
48
|
+
import type { FileNodeVisibilityPredicate } from "../file-node-visibility";
|
|
48
49
|
import { useSessionCapabilities } from "../hooks/use-session-capabilities";
|
|
49
50
|
import { useSandboxFiles } from "../hooks/use-sandbox-files";
|
|
50
51
|
import {
|
|
@@ -55,21 +56,49 @@ import {
|
|
|
55
56
|
import { useSandboxTerminal } from "../hooks/use-sandbox-terminal";
|
|
56
57
|
import { useWorkspaceCapture } from "../hooks/use-workspace-capture";
|
|
57
58
|
import { useMachineChip, type MachineChip } from "../hooks/use-machine-chip";
|
|
58
|
-
import { useMachines } from "../hooks/use-machines";
|
|
59
|
+
import { MACHINES_SESSION_POLL_MS, useMachines } from "../hooks/use-machines";
|
|
59
60
|
import type { MachineView } from "../types/machines";
|
|
60
|
-
import {
|
|
61
|
+
import type { SandboxFilesProps } from "./sandbox-files";
|
|
61
62
|
import { WorkbenchChanges } from "./workbench-changes";
|
|
62
63
|
import { SandboxTerminal, type XtermTheme } from "./sandbox-terminal";
|
|
63
64
|
import { WorkspaceDock, type WorkspaceDockProps, type WorkspaceTab } from "./workspace-dock";
|
|
64
65
|
|
|
66
|
+
const LazySandboxFiles = lazy(() =>
|
|
67
|
+
import("./sandbox-files")
|
|
68
|
+
.then(({ SandboxFiles }) => ({ default: SandboxFiles }))
|
|
69
|
+
// A host may already have attempted stale-deployment recovery. Keep an
|
|
70
|
+
// optional chunk failure inside Files rather than unmounting the chat.
|
|
71
|
+
.catch(() => ({ default: FilesLoadFailed })),
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
function FilesLoadFailed() {
|
|
75
|
+
return (
|
|
76
|
+
<CenteredState tone="danger" icon={<TriangleAlertIcon className="size-5" aria-hidden />}>
|
|
77
|
+
<p className="text-og-sm font-medium text-og-fg">Files could not be loaded.</p>
|
|
78
|
+
<DockActionButton onClick={() => window.location.reload()}>
|
|
79
|
+
<RefreshCwIcon className="size-3" aria-hidden />
|
|
80
|
+
Reload
|
|
81
|
+
</DockActionButton>
|
|
82
|
+
</CenteredState>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function FilesTabBody(props: SandboxFilesProps) {
|
|
87
|
+
return (
|
|
88
|
+
<Suspense fallback={<WorkbenchSurfaceLoading name="Files" />}>
|
|
89
|
+
<LazySandboxFiles {...props} />
|
|
90
|
+
</Suspense>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
65
94
|
const LazyBrowserViewer = lazy(async () => {
|
|
66
|
-
const
|
|
67
|
-
return { default:
|
|
95
|
+
const { BrowserViewer } = await import("./browser-viewer");
|
|
96
|
+
return { default: BrowserViewer };
|
|
68
97
|
});
|
|
69
98
|
|
|
70
99
|
const LazyComputerViewer = lazy(async () => {
|
|
71
|
-
const
|
|
72
|
-
return { default:
|
|
100
|
+
const { ComputerViewer } = await import("./computer-viewer");
|
|
101
|
+
return { default: ComputerViewer };
|
|
73
102
|
});
|
|
74
103
|
|
|
75
104
|
/** A host-routed notification (replaces the app-only `sonner` toast coupling). */
|
|
@@ -101,6 +130,12 @@ function isWorkbenchSurface(value: string): value is SandboxWorkspaceSurface {
|
|
|
101
130
|
return (WORKBENCH_SURFACES as readonly string[]).includes(value);
|
|
102
131
|
}
|
|
103
132
|
|
|
133
|
+
function isCanonicalAbsoluteSandboxPath(value: string | null | undefined): boolean {
|
|
134
|
+
if (!value) return false;
|
|
135
|
+
const portable = value.replaceAll("\\", "/");
|
|
136
|
+
return portable.startsWith("/") || /^[A-Za-z]:\//u.test(portable);
|
|
137
|
+
}
|
|
138
|
+
|
|
104
139
|
function sourceDrivenDefaultTab(
|
|
105
140
|
hasChanges: boolean,
|
|
106
141
|
changesEnabled: boolean,
|
|
@@ -112,31 +147,7 @@ function sourceDrivenDefaultTab(
|
|
|
112
147
|
return null;
|
|
113
148
|
}
|
|
114
149
|
|
|
115
|
-
function
|
|
116
|
-
switch (reason) {
|
|
117
|
-
case "repository_discovery_timed_out":
|
|
118
|
-
return "Workspace capture is incomplete because repository discovery timed out. Live files remain authoritative.";
|
|
119
|
-
case "repository_discovery_result_limit_exceeded":
|
|
120
|
-
return "Workspace capture is incomplete because the repository limit was exceeded. Live files remain authoritative.";
|
|
121
|
-
case "repository_read_unavailable":
|
|
122
|
-
return "Workspace capture is incomplete because repository changes could not be read. Live files remain authoritative.";
|
|
123
|
-
default:
|
|
124
|
-
return "Workspace capture is incomplete because repository discovery failed. Live files remain authoritative.";
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function WorkbenchTabLabel({ icon, children }: { icon: ReactNode; children: ReactNode }) {
|
|
129
|
-
return (
|
|
130
|
-
<span className="inline-flex items-center gap-1.5">
|
|
131
|
-
<span className="[&>svg]:size-3.5" aria-hidden>
|
|
132
|
-
{icon}
|
|
133
|
-
</span>
|
|
134
|
-
<span>{children}</span>
|
|
135
|
-
</span>
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function WorkbenchSurfaceLoading({ name }: { name: "Browser" | "Computer" }) {
|
|
150
|
+
function WorkbenchSurfaceLoading({ name }: { name: "Files" | "Browser" | "Desktop" }) {
|
|
140
151
|
return (
|
|
141
152
|
<CenteredState
|
|
142
153
|
icon={
|
|
@@ -218,10 +229,51 @@ function sandboxProvisionInFlight(events: SessionEvent[]): boolean {
|
|
|
218
229
|
return inFlight;
|
|
219
230
|
}
|
|
220
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Whether this session currently owns an admitted agent turn. Automatic live
|
|
234
|
+
* Files/Git reads pause across the whole turn: command boundaries are not a safe
|
|
235
|
+
* gap because the next tool can dispatch before a remote provider read releases
|
|
236
|
+
* its sandbox holder. Existing/captured content remains usable, and the terminal
|
|
237
|
+
* turn event resumes one authoritative refresh.
|
|
238
|
+
*/
|
|
239
|
+
function workspaceTurnInFlight(events: SessionEvent[]): boolean {
|
|
240
|
+
const activeTurnIds = new Set<string>();
|
|
241
|
+
let anonymousTurnInFlight = false;
|
|
242
|
+
let sessionOwnsWorkspace = false;
|
|
243
|
+
for (const event of events) {
|
|
244
|
+
if (event.type === "session.status.changed") {
|
|
245
|
+
const status =
|
|
246
|
+
event.payload && typeof event.payload === "object" && !Array.isArray(event.payload)
|
|
247
|
+
? (event.payload as Record<string, unknown>).status
|
|
248
|
+
: null;
|
|
249
|
+
sessionOwnsWorkspace = status === "running" || status === "recovering";
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
if (event.type === "turn.started") {
|
|
253
|
+
if (event.turnId) activeTurnIds.add(event.turnId);
|
|
254
|
+
else anonymousTurnInFlight = true;
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
if (
|
|
258
|
+
event.type !== "turn.completed" &&
|
|
259
|
+
event.type !== "turn.failed" &&
|
|
260
|
+
event.type !== "turn.cancelled" &&
|
|
261
|
+
event.type !== "turn.superseded"
|
|
262
|
+
) {
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
if (event.turnId) activeTurnIds.delete(event.turnId);
|
|
266
|
+
else anonymousTurnInFlight = false;
|
|
267
|
+
}
|
|
268
|
+
// The retained event window preserves the latest status even after a very
|
|
269
|
+
// long turn has evicted its original turn.started event.
|
|
270
|
+
return sessionOwnsWorkspace || anonymousTurnInFlight || activeTurnIds.size > 0;
|
|
271
|
+
}
|
|
272
|
+
|
|
221
273
|
export type WorkspaceMachine = {
|
|
222
274
|
/** Whether at least one built-in workbench surface is enabled. */
|
|
223
275
|
enabled: boolean;
|
|
224
|
-
/** The derived live/waking/offline chip model. */
|
|
276
|
+
/** The derived live/waking/sleeping-or-offline chip model. */
|
|
225
277
|
chip: MachineChip;
|
|
226
278
|
/** The machine these surfaces are bound to (the Modal group box or a
|
|
227
279
|
* self-hosted machine), or null while the fleet is still resolving. */
|
|
@@ -256,14 +308,27 @@ export type UseSandboxWorkspaceTabsOptions = ClientOverride & {
|
|
|
256
308
|
browserWebSocketFactory?: BrowserFrameWebSocketFactory | undefined;
|
|
257
309
|
/** Alternate Computer frame transport for non-browser runtimes and deterministic tests. */
|
|
258
310
|
computerWebSocketFactory?: ComputerFrameWebSocketFactory | undefined;
|
|
311
|
+
/** Host-owned setup page or store listing for attaching an existing Chrome profile. */
|
|
312
|
+
browserExtensionSetupUrl?: string | undefined;
|
|
259
313
|
/** File requested by a Changes guard. The Files surface defers the read until
|
|
260
314
|
* the sandbox is live, then reveals this path. */
|
|
261
315
|
requestedFilePath?: string | null | undefined;
|
|
262
316
|
/** Unique identity for `requestedFilePath`, including repeated requests for the
|
|
263
317
|
* same path. */
|
|
264
318
|
requestedFileRequestId?: string | number | null | undefined;
|
|
319
|
+
/** 1-based line to reveal after `requestedFilePath` opens. */
|
|
320
|
+
requestedFileLine?: number | null | undefined;
|
|
265
321
|
/** Route a guarded diff into the host's Files tab. */
|
|
266
322
|
onOpenFile?: ((path: string) => void) | undefined;
|
|
323
|
+
/** Restore and report navigation inside the built-in workbench surfaces. */
|
|
324
|
+
initialFilePath?: string | null | undefined;
|
|
325
|
+
onFilePathChange?: ((path: string | null) => void) | undefined;
|
|
326
|
+
/** Presentation-only filter for Files tree nodes and selected-file viewing. */
|
|
327
|
+
isFileNodeVisible?: FileNodeVisibilityPredicate | undefined;
|
|
328
|
+
initialBrowserSessionId?: string | null | undefined;
|
|
329
|
+
onBrowserSessionIdChange?: ((browserSessionId: string | null) => void) | undefined;
|
|
330
|
+
initialComputerSessionId?: string | null | undefined;
|
|
331
|
+
onComputerSessionIdChange?: ((computerSessionId: string | null) => void) | undefined;
|
|
267
332
|
/** Navigate the host dock to one exact linked ComputerSession. */
|
|
268
333
|
onOpenComputerSession?: ((computerSessionId: string) => void) | undefined;
|
|
269
334
|
requestedComputerSessionId?: string | null | undefined;
|
|
@@ -274,7 +339,8 @@ export type UseSandboxWorkspaceTabsResult = {
|
|
|
274
339
|
/** Changes | Files | Terminal | Browser | Desktop (capability-gated where noted). */
|
|
275
340
|
tabs: WorkspaceTab[];
|
|
276
341
|
/** The source-driven default tab: Changes when the first authoritative capture
|
|
277
|
-
*
|
|
342
|
+
* has changes, else Files (a host `initialTab` overrides). Choosing a tab
|
|
343
|
+
* never performs hidden live workspace I/O.
|
|
278
344
|
* null while that source resolves, or permanently when neither Changes nor
|
|
279
345
|
* Files is enabled; the choice latches once. */
|
|
280
346
|
defaultTab: string | null;
|
|
@@ -312,9 +378,18 @@ export function useSandboxWorkspaceTabs(
|
|
|
312
378
|
onNotify,
|
|
313
379
|
browserWebSocketFactory,
|
|
314
380
|
computerWebSocketFactory,
|
|
381
|
+
browserExtensionSetupUrl,
|
|
315
382
|
requestedFilePath,
|
|
316
383
|
requestedFileRequestId,
|
|
384
|
+
requestedFileLine,
|
|
317
385
|
onOpenFile,
|
|
386
|
+
initialFilePath,
|
|
387
|
+
onFilePathChange,
|
|
388
|
+
isFileNodeVisible,
|
|
389
|
+
initialBrowserSessionId,
|
|
390
|
+
onBrowserSessionIdChange,
|
|
391
|
+
initialComputerSessionId,
|
|
392
|
+
onComputerSessionIdChange,
|
|
318
393
|
onOpenComputerSession,
|
|
319
394
|
requestedComputerSessionId,
|
|
320
395
|
requestedComputerRequestId,
|
|
@@ -338,7 +413,7 @@ export function useSandboxWorkspaceTabs(
|
|
|
338
413
|
...(placement ? { placement } : {}),
|
|
339
414
|
});
|
|
340
415
|
if (response.operation.state !== "completed" || response.session.lifecycle !== "active") {
|
|
341
|
-
throw new Error(response.operation.error?.message ?? "The
|
|
416
|
+
throw new Error(response.operation.error?.message ?? "The desktop could not be opened.");
|
|
342
417
|
}
|
|
343
418
|
return {
|
|
344
419
|
id: response.session.id,
|
|
@@ -356,6 +431,7 @@ export function useSandboxWorkspaceTabs(
|
|
|
356
431
|
const resolvedActiveTab = activeTab ?? initialTab;
|
|
357
432
|
const changesActive = resolvedActiveTab === WORKBENCH_TAB_CHANGES;
|
|
358
433
|
const filesActive = resolvedActiveTab === WORKBENCH_TAB_FILES;
|
|
434
|
+
const turnInFlight = workspaceTurnInFlight(events);
|
|
359
435
|
const surfaceIdentity = WORKBENCH_SURFACES.filter((surface) => surfaceSet.has(surface)).join(",");
|
|
360
436
|
|
|
361
437
|
// The two box-warming INTENTS, each off by default and each
|
|
@@ -369,6 +445,11 @@ export function useSandboxWorkspaceTabs(
|
|
|
369
445
|
const warmIntents =
|
|
370
446
|
storedWarmIntents.sessionId === sessionId ? storedWarmIntents : emptyWarmIntents(sessionId);
|
|
371
447
|
const { warmTerminal, warmFiles } = warmIntents;
|
|
448
|
+
// A host-requested file is itself explicit live-file intent. Derive the wake
|
|
449
|
+
// directly from the request instead of relying on a follow-up effect to copy
|
|
450
|
+
// it into local state; otherwise a missing or delayed effect leaves the file
|
|
451
|
+
// waiting for a sandbox that this hook never asks to start.
|
|
452
|
+
const filesWarmRequested = warmFiles || Boolean(requestedFilePath);
|
|
372
453
|
const requestWarmIntent = useCallback(
|
|
373
454
|
(intent: Exclude<keyof SessionWarmIntents, "sessionId">) => {
|
|
374
455
|
setStoredWarmIntents((previous) => {
|
|
@@ -378,13 +459,12 @@ export function useSandboxWorkspaceTabs(
|
|
|
378
459
|
},
|
|
379
460
|
[sessionId],
|
|
380
461
|
);
|
|
381
|
-
|
|
382
462
|
// The session's machine fleet + the active-sandbox pointer. Drives the header
|
|
383
|
-
// chip (which machine + its connection state).
|
|
463
|
+
// chip (which machine + its connection state). Shares the session list poll.
|
|
384
464
|
const machines = useMachines({
|
|
385
465
|
workspaceId,
|
|
386
466
|
sessionId,
|
|
387
|
-
pollIntervalMs:
|
|
467
|
+
pollIntervalMs: MACHINES_SESSION_POLL_MS,
|
|
388
468
|
enabled: machineSurfaceEnabled,
|
|
389
469
|
});
|
|
390
470
|
const activeMachine: MachineView | null =
|
|
@@ -399,7 +479,7 @@ export function useSandboxWorkspaceTabs(
|
|
|
399
479
|
attachTerminal: terminalEnabled && warmTerminal,
|
|
400
480
|
// Explicit live-file intent only — NOT "the Files tab is open". A cold edit
|
|
401
481
|
// or guarded-file open wakes the box; a glance at the tree/diff does not.
|
|
402
|
-
attachFiles: workspaceDataEnabled &&
|
|
482
|
+
attachFiles: workspaceDataEnabled && filesWarmRequested,
|
|
403
483
|
});
|
|
404
484
|
const capabilities = caps.capabilities;
|
|
405
485
|
const liveness = capabilities?.liveness;
|
|
@@ -409,6 +489,9 @@ export function useSandboxWorkspaceTabs(
|
|
|
409
489
|
// is still pending.
|
|
410
490
|
const liveIoLiveness = liveness ?? null;
|
|
411
491
|
const fileSystemOn = capabilities?.FileSystem.available ?? false;
|
|
492
|
+
const fileSystemRoute = capabilities
|
|
493
|
+
? { epoch: capabilities.leaseEpoch, root: capabilities.FileSystem.root }
|
|
494
|
+
: undefined;
|
|
412
495
|
// The FS is writable only when it's live AND not read-only. A self-hosted box
|
|
413
496
|
// that's offline (or any read-only advertisement) or a capture-served cold tree
|
|
414
497
|
// must not offer create/rename/delete/edit affordances — you cannot mutate a
|
|
@@ -487,29 +570,22 @@ export function useSandboxWorkspaceTabs(
|
|
|
487
570
|
if (advertised.length > 0) return advertised;
|
|
488
571
|
return captureState.capture?.repos.map((repo) => repo.root) ?? [];
|
|
489
572
|
}, [capabilities?.Git.repos, captureState.capture]);
|
|
490
|
-
const notifiedCaptureDegradedReason = useRef<{
|
|
491
|
-
sessionId: string;
|
|
492
|
-
reason: string | null;
|
|
493
|
-
}>({
|
|
494
|
-
sessionId,
|
|
495
|
-
reason: null,
|
|
496
|
-
});
|
|
497
|
-
if (notifiedCaptureDegradedReason.current.sessionId !== sessionId) {
|
|
498
|
-
notifiedCaptureDegradedReason.current = { sessionId, reason: null };
|
|
499
|
-
}
|
|
500
|
-
useEffect(() => {
|
|
501
|
-
const reason = captureState.degradedReason;
|
|
502
|
-
if (!reason || notifiedCaptureDegradedReason.current.reason === reason) return;
|
|
503
|
-
notifiedCaptureDegradedReason.current = { sessionId, reason };
|
|
504
|
-
onNotify?.({ kind: "error", message: captureDegradedMessage(reason) });
|
|
505
|
-
}, [sessionId, captureState.degradedReason, onNotify]);
|
|
506
|
-
|
|
507
573
|
const files = useSandboxFiles(sessionId, {
|
|
508
574
|
events,
|
|
509
575
|
// No passive Channel-A reads while cold, even after a conclusive capture
|
|
510
576
|
// miss. A missing capture gets an explicit "Open live workspace" gate.
|
|
511
577
|
enabled: filesEnabled && (captureAvailable || (fileSystemOn && liveWorkspaceExpected)),
|
|
512
|
-
|
|
578
|
+
// A cold sandbox can become warm while the first agent command still owns
|
|
579
|
+
// startup. Do not race that command with an automatic Files read. Keeping
|
|
580
|
+
// this fence at turn scope also avoids unsafe millisecond gaps between
|
|
581
|
+
// sequential tool calls; rendered state and explicit user actions remain.
|
|
582
|
+
active: filesActive && !turnInFlight,
|
|
583
|
+
// A deliberate canonical absolute-path open browses in the selected target's
|
|
584
|
+
// advertised namespace, so the authoritative tree and link share exact paths.
|
|
585
|
+
...(isCanonicalAbsoluteSandboxPath(requestedFilePath) && capabilities?.FileSystem.root
|
|
586
|
+
? { rootPath: capabilities.FileSystem.root }
|
|
587
|
+
: {}),
|
|
588
|
+
...(fileSystemRoute ? { route: fileSystemRoute } : {}),
|
|
513
589
|
repoPaths,
|
|
514
590
|
liveness: liveIoLiveness,
|
|
515
591
|
capture: captureState.capture,
|
|
@@ -550,10 +626,11 @@ export function useSandboxWorkspaceTabs(
|
|
|
550
626
|
: changesComparison === "branch"
|
|
551
627
|
? workspaceDataEnabled && (captureSupportsBranch || (gitOn && liveWorkspaceExpected))
|
|
552
628
|
: workspaceDataEnabled && gitOn && liveWorkspaceExpected,
|
|
553
|
-
//
|
|
554
|
-
//
|
|
555
|
-
//
|
|
556
|
-
|
|
629
|
+
// Live Git belongs to the visible Changes surface. In particular, do not
|
|
630
|
+
// turn an unresolved/default tab into a hidden provider read: that races the
|
|
631
|
+
// agent's own sandbox commands and used to refresh after every tool output
|
|
632
|
+
// even while Files was visibly selected.
|
|
633
|
+
active: changesActive && !turnInFlight,
|
|
557
634
|
repoPaths,
|
|
558
635
|
liveness: liveIoLiveness,
|
|
559
636
|
comparison: changesComparison,
|
|
@@ -597,19 +674,17 @@ export function useSandboxWorkspaceTabs(
|
|
|
597
674
|
capabilitiesState: caps.state,
|
|
598
675
|
activeMachineState: activeMachine?.state ?? null,
|
|
599
676
|
activeIsSelfhosted: activeMachine?.kind === "selfhosted",
|
|
600
|
-
wantsWarm: (terminalEnabled && warmTerminal) || (workspaceDataEnabled &&
|
|
677
|
+
wantsWarm: (terminalEnabled && warmTerminal) || (workspaceDataEnabled && filesWarmRequested),
|
|
601
678
|
capturedAt: captureState.capturedAt,
|
|
602
679
|
});
|
|
603
680
|
const workspaceWaking = chip.state === "waking";
|
|
604
681
|
|
|
605
|
-
// The pre-paint default
|
|
606
|
-
//
|
|
607
|
-
//
|
|
608
|
-
//
|
|
609
|
-
//
|
|
610
|
-
//
|
|
611
|
-
// the correct live default. The choice latches once so later edits never steal
|
|
612
|
-
// the user's current tab.
|
|
682
|
+
// The pre-paint default comes only from the durable capture. Default selection
|
|
683
|
+
// must never dispatch live provider work: a live Git probe can overlap the
|
|
684
|
+
// agent's first command, and an uncontrolled dock used to keep that probe
|
|
685
|
+
// active forever after it visibly selected Files. A capture with reviewable
|
|
686
|
+
// changes opens Changes; no capture (or an empty one) opens Files. The choice
|
|
687
|
+
// latches once so later edits never steal the user's current tab.
|
|
613
688
|
const defaultIdentity = `${sessionId}\u0000${surfaceIdentity}`;
|
|
614
689
|
const defaultTabRef = useRef<{ identity: string; value: string | null }>({
|
|
615
690
|
identity: defaultIdentity,
|
|
@@ -618,62 +693,32 @@ export function useSandboxWorkspaceTabs(
|
|
|
618
693
|
if (defaultTabRef.current.identity !== defaultIdentity) {
|
|
619
694
|
defaultTabRef.current = { identity: defaultIdentity, value: null };
|
|
620
695
|
}
|
|
621
|
-
const captureIsAuthoritative =
|
|
622
|
-
!liveWorkspaceExpected && (liveness !== undefined || caps.error !== null);
|
|
623
696
|
const captureHasChanges =
|
|
624
697
|
(captureState.fileCount ?? 0) > 0 ||
|
|
625
698
|
(captureState.capture?.repos.some((repo) => (repo.branchDiff?.length ?? 0) > 0) ?? false);
|
|
626
699
|
const captureUnavailable =
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
changesComparison === "branch" &&
|
|
630
|
-
git.error !== null &&
|
|
631
|
-
storedChangesComparison?.sessionId !== sessionId;
|
|
700
|
+
!captureState.loading &&
|
|
701
|
+
((captureState.fileCount === 0 && !captureHasChanges) || captureState.error !== null);
|
|
632
702
|
if (defaultTabRef.current.value === null) {
|
|
633
703
|
if (initialTab && (!isWorkbenchSurface(initialTab) || surfaceSet.has(initialTab))) {
|
|
634
704
|
defaultTabRef.current.value = initialTab;
|
|
635
|
-
} else if (
|
|
636
|
-
defaultTabRef.current.value = sourceDrivenDefaultTab(
|
|
637
|
-
git.diff.length > 0,
|
|
638
|
-
changesEnabled,
|
|
639
|
-
filesEnabled,
|
|
640
|
-
);
|
|
641
|
-
} else if (
|
|
642
|
-
captureIsAuthoritative &&
|
|
643
|
-
captureState.fileCount !== null &&
|
|
644
|
-
captureState.available
|
|
645
|
-
) {
|
|
705
|
+
} else if (captureState.fileCount !== null && captureState.available) {
|
|
646
706
|
defaultTabRef.current.value = sourceDrivenDefaultTab(
|
|
647
707
|
captureHasChanges,
|
|
648
708
|
changesEnabled,
|
|
649
709
|
filesEnabled,
|
|
650
710
|
);
|
|
711
|
+
} else if (captureUnavailable && initialWorkspaceTab(events) === WORKBENCH_TAB_CHANGES) {
|
|
712
|
+
defaultTabRef.current.value = sourceDrivenDefaultTab(true, changesEnabled, filesEnabled);
|
|
651
713
|
} else if (
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
initialWorkspaceTab(events) === WORKBENCH_TAB_CHANGES
|
|
714
|
+
!captureState.loading &&
|
|
715
|
+
(captureState.fileCount !== null || captureState.error !== null)
|
|
655
716
|
) {
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
//
|
|
659
|
-
//
|
|
660
|
-
|
|
661
|
-
} else if (captureIsAuthoritative && captureState.fileCount !== null && captureUnavailable) {
|
|
662
|
-
// No durable review surface exists and the machine is resting. Files owns
|
|
663
|
-
// the explicit wake gate; do not issue a live Git probe merely to choose a
|
|
664
|
-
// tab.
|
|
665
|
-
defaultTabRef.current.value = sourceDrivenDefaultTab(false, changesEnabled, filesEnabled);
|
|
666
|
-
} else if (captureState.available && git.error && captureState.fileCount !== null) {
|
|
667
|
-
// A warm live read failed but the durable capture is intact: retain an
|
|
668
|
-
// immediate, deterministic review surface instead of hanging unresolved.
|
|
669
|
-
defaultTabRef.current.value = sourceDrivenDefaultTab(
|
|
670
|
-
captureHasChanges,
|
|
671
|
-
changesEnabled,
|
|
672
|
-
filesEnabled,
|
|
673
|
-
);
|
|
674
|
-
} else if (captureUnavailable && git.error && !implicitBranchFallbackPending) {
|
|
675
|
-
// No capture and live Git failed: Files is the least surprising fallback
|
|
676
|
-
// after the implicit branch-to-working fallback has also had its chance.
|
|
717
|
+
// Metadata may arrive before a signed manifest. While that manifest is
|
|
718
|
+
// loading, neither a positive count nor zero (committed-only changes)
|
|
719
|
+
// proves an unavailable capture, so leave the default unresolved.
|
|
720
|
+
// No durable review surface exists. Files owns the explicit live-workspace
|
|
721
|
+
// gate; a user can open Changes deliberately if they need a fresh Git read.
|
|
677
722
|
defaultTabRef.current.value = sourceDrivenDefaultTab(false, changesEnabled, filesEnabled);
|
|
678
723
|
}
|
|
679
724
|
}
|
|
@@ -687,7 +732,8 @@ export function useSandboxWorkspaceTabs(
|
|
|
687
732
|
if (changesEnabled)
|
|
688
733
|
list.push({
|
|
689
734
|
id: WORKBENCH_TAB_CHANGES,
|
|
690
|
-
label:
|
|
735
|
+
label: "Changes",
|
|
736
|
+
icon: <GitCompareArrowsIcon />,
|
|
691
737
|
badge: dirtyCount > 0 ? <DirtyBadge count={dirtyCount} /> : undefined,
|
|
692
738
|
content: (
|
|
693
739
|
<ChangesTabBody
|
|
@@ -695,6 +741,7 @@ export function useSandboxWorkspaceTabs(
|
|
|
695
741
|
comparison={changesComparison}
|
|
696
742
|
onComparisonChange={setChangesComparison}
|
|
697
743
|
captureAvailable={captureAvailable}
|
|
744
|
+
captureDegraded={captureState.degradedReason !== null}
|
|
698
745
|
captureRevision={captureState.revision}
|
|
699
746
|
capturePending={capturePending}
|
|
700
747
|
liveWorkspaceExpected={liveWorkspaceExpected}
|
|
@@ -719,12 +766,14 @@ export function useSandboxWorkspaceTabs(
|
|
|
719
766
|
if (filesEnabled)
|
|
720
767
|
list.push({
|
|
721
768
|
id: WORKBENCH_TAB_FILES,
|
|
722
|
-
label:
|
|
769
|
+
label: "Files",
|
|
770
|
+
icon: <FileCode2Icon />,
|
|
723
771
|
content: (
|
|
724
|
-
<
|
|
772
|
+
<FilesTabBody
|
|
725
773
|
key={sessionId}
|
|
726
774
|
files={files}
|
|
727
775
|
git={git}
|
|
776
|
+
isNodeVisible={isFileNodeVisible}
|
|
728
777
|
fileSystemAvailable={fileSystemOn || captureAvailable}
|
|
729
778
|
editable={
|
|
730
779
|
filesEditable && files.source === "live" && files.error === null && !files.loading
|
|
@@ -738,7 +787,20 @@ export function useSandboxWorkspaceTabs(
|
|
|
738
787
|
}
|
|
739
788
|
workspaceWaking={!liveWorkspaceExpected && !captureAvailable && workspaceWaking}
|
|
740
789
|
liveWorkspaceReady={liveWorkspaceExpected}
|
|
741
|
-
|
|
790
|
+
workspaceError={
|
|
791
|
+
caps.error ??
|
|
792
|
+
(caps.viewerCapReached
|
|
793
|
+
? new Error(
|
|
794
|
+
"The live workspace viewer limit has been reached. Close another viewer and retry.",
|
|
795
|
+
)
|
|
796
|
+
: filesWarmRequested && caps.state === "on-demand" && !fileSystemOn
|
|
797
|
+
? new Error("This machine does not currently expose a live file system.")
|
|
798
|
+
: null)
|
|
799
|
+
}
|
|
800
|
+
onWakeWorkspace={() => {
|
|
801
|
+
if (filesWarmRequested) caps.renegotiate();
|
|
802
|
+
else requestWarmIntent("warmFiles");
|
|
803
|
+
}}
|
|
742
804
|
{...(requestedFilePath
|
|
743
805
|
? {
|
|
744
806
|
requestedPath: requestedFilePath,
|
|
@@ -746,11 +808,16 @@ export function useSandboxWorkspaceTabs(
|
|
|
746
808
|
? { requestedPathRequestId: requestedFileRequestId }
|
|
747
809
|
: {}),
|
|
748
810
|
requestedPathReady: sandboxAcceptsLiveIo(liveness),
|
|
811
|
+
...(requestedFileLine != null && requestedFileLine > 0
|
|
812
|
+
? { requestedLine: requestedFileLine }
|
|
813
|
+
: {}),
|
|
749
814
|
}
|
|
750
815
|
: {})}
|
|
751
816
|
// Ordinary capture browsing does not warm a box. The first edit — or an
|
|
752
817
|
// explicit guarded-file open from Changes — is deliberate live-file intent.
|
|
753
818
|
onEditIntent={() => requestWarmIntent("warmFiles")}
|
|
819
|
+
initialSelectedPath={initialFilePath}
|
|
820
|
+
onSelectedPathChange={onFilePathChange}
|
|
754
821
|
className="h-full"
|
|
755
822
|
/>
|
|
756
823
|
),
|
|
@@ -760,7 +827,8 @@ export function useSandboxWorkspaceTabs(
|
|
|
760
827
|
if (terminalOn) {
|
|
761
828
|
list.push({
|
|
762
829
|
id: WORKBENCH_TAB_TERMINAL,
|
|
763
|
-
label:
|
|
830
|
+
label: "Terminal",
|
|
831
|
+
icon: <SquareTerminalIcon />,
|
|
764
832
|
content: (
|
|
765
833
|
<div className="h-full bg-og-bg p-1">
|
|
766
834
|
<SandboxTerminal
|
|
@@ -785,7 +853,8 @@ export function useSandboxWorkspaceTabs(
|
|
|
785
853
|
if (browserEnabled) {
|
|
786
854
|
list.push({
|
|
787
855
|
id: WORKBENCH_TAB_BROWSER,
|
|
788
|
-
label:
|
|
856
|
+
label: "Browser",
|
|
857
|
+
icon: <Globe2Icon />,
|
|
789
858
|
content: (
|
|
790
859
|
<Suspense fallback={<WorkbenchSurfaceLoading name="Browser" />}>
|
|
791
860
|
<LazyBrowserViewer
|
|
@@ -802,10 +871,14 @@ export function useSandboxWorkspaceTabs(
|
|
|
802
871
|
// start BrowserViewer—the lazy panel is still unmounted until the
|
|
803
872
|
// user/agent first visits it.
|
|
804
873
|
enabled={workspaceVisible}
|
|
874
|
+
active={resolvedActiveTab === WORKBENCH_TAB_BROWSER}
|
|
805
875
|
onNotify={onNotify}
|
|
876
|
+
initialBrowserSessionId={initialBrowserSessionId}
|
|
877
|
+
onBrowserSessionIdChange={onBrowserSessionIdChange}
|
|
806
878
|
{...(desktopEnabled ? { createLinkedComputer } : {})}
|
|
807
879
|
{...(onOpenComputerSession ? { onOpenComputer: onOpenComputerSession } : {})}
|
|
808
880
|
{...(browserWebSocketFactory ? { webSocketFactory: browserWebSocketFactory } : {})}
|
|
881
|
+
{...(browserExtensionSetupUrl ? { browserExtensionSetupUrl } : {})}
|
|
809
882
|
className="h-full"
|
|
810
883
|
/>
|
|
811
884
|
</Suspense>
|
|
@@ -818,9 +891,10 @@ export function useSandboxWorkspaceTabs(
|
|
|
818
891
|
if (desktopEnabled) {
|
|
819
892
|
list.push({
|
|
820
893
|
id: WORKBENCH_TAB_DESKTOP,
|
|
821
|
-
label:
|
|
894
|
+
label: "Desktop",
|
|
895
|
+
icon: <MonitorIcon />,
|
|
822
896
|
content: (
|
|
823
|
-
<Suspense fallback={<WorkbenchSurfaceLoading name="
|
|
897
|
+
<Suspense fallback={<WorkbenchSurfaceLoading name="Desktop" />}>
|
|
824
898
|
<LazyComputerViewer
|
|
825
899
|
key={sessionId}
|
|
826
900
|
client={client}
|
|
@@ -832,6 +906,8 @@ export function useSandboxWorkspaceTabs(
|
|
|
832
906
|
// second and later Computer opens local-machine fast.
|
|
833
907
|
enabled={workspaceVisible}
|
|
834
908
|
onNotify={onNotify}
|
|
909
|
+
initialComputerSessionId={initialComputerSessionId}
|
|
910
|
+
onComputerSessionIdChange={onComputerSessionIdChange}
|
|
835
911
|
requestedComputerSessionId={requestedComputerSessionId}
|
|
836
912
|
requestedComputerRequestId={requestedComputerRequestId}
|
|
837
913
|
{...(computerWebSocketFactory ? { webSocketFactory: computerWebSocketFactory } : {})}
|
|
@@ -852,11 +928,20 @@ export function useSandboxWorkspaceTabs(
|
|
|
852
928
|
browserEnabled,
|
|
853
929
|
desktopEnabled,
|
|
854
930
|
captureAvailable,
|
|
931
|
+
captureState.degradedReason,
|
|
855
932
|
dirtyCount,
|
|
856
933
|
warmTerminal,
|
|
857
934
|
requestedFilePath,
|
|
858
935
|
requestedFileRequestId,
|
|
936
|
+
requestedFileLine,
|
|
859
937
|
onOpenFile,
|
|
938
|
+
initialFilePath,
|
|
939
|
+
onFilePathChange,
|
|
940
|
+
isFileNodeVisible,
|
|
941
|
+
initialBrowserSessionId,
|
|
942
|
+
onBrowserSessionIdChange,
|
|
943
|
+
initialComputerSessionId,
|
|
944
|
+
onComputerSessionIdChange,
|
|
860
945
|
onOpenComputerSession,
|
|
861
946
|
requestedComputerSessionId,
|
|
862
947
|
requestedComputerRequestId,
|
|
@@ -879,6 +964,8 @@ export function useSandboxWorkspaceTabs(
|
|
|
879
964
|
caps.state,
|
|
880
965
|
caps.error,
|
|
881
966
|
caps.viewerCapReached,
|
|
967
|
+
caps.renegotiate,
|
|
968
|
+
filesWarmRequested,
|
|
882
969
|
requestWarmIntent,
|
|
883
970
|
createLinkedComputer,
|
|
884
971
|
]);
|
|
@@ -913,14 +1000,39 @@ export type SandboxWorkspaceProps = ClientOverride & {
|
|
|
913
1000
|
/** Host tabs injected AFTER the workbench tabs (e.g. a "Debug" tab). */
|
|
914
1001
|
trailingTabs?: WorkspaceTab[] | undefined;
|
|
915
1002
|
/** Override the pre-paint default tab (e.g. a host landing tab id). When
|
|
916
|
-
* omitted the workbench decides from
|
|
1003
|
+
* omitted the workbench decides from the durable workspace capture. */
|
|
917
1004
|
initialTab?: string | undefined;
|
|
1005
|
+
onActiveTabChange?: ((activeTab: string) => void) | undefined;
|
|
1006
|
+
/** Open a built-in or host-injected tab. A new requestId reopens the same tab. */
|
|
1007
|
+
openTabRequest?: { tab: string; requestId: number } | null | undefined;
|
|
1008
|
+
initialFilePath?: string | null | undefined;
|
|
1009
|
+
onFilePathChange?: ((path: string | null) => void) | undefined;
|
|
1010
|
+
/** Presentation-only filter for Files tree nodes and selected-file viewing. */
|
|
1011
|
+
isFileNodeVisible?: FileNodeVisibilityPredicate | undefined;
|
|
1012
|
+
/**
|
|
1013
|
+
* Host request to open a workspace file (and optional line) in Files. A new
|
|
1014
|
+
* `requestId` re-opens even the same path.
|
|
1015
|
+
*/
|
|
1016
|
+
openFileRequest?:
|
|
1017
|
+
| {
|
|
1018
|
+
path: string;
|
|
1019
|
+
line?: number | null;
|
|
1020
|
+
requestId: number;
|
|
1021
|
+
}
|
|
1022
|
+
| null
|
|
1023
|
+
| undefined;
|
|
1024
|
+
initialBrowserSessionId?: string | null | undefined;
|
|
1025
|
+
onBrowserSessionIdChange?: ((browserSessionId: string | null) => void) | undefined;
|
|
1026
|
+
initialComputerSessionId?: string | null | undefined;
|
|
1027
|
+
onComputerSessionIdChange?: ((computerSessionId: string | null) => void) | undefined;
|
|
918
1028
|
/** Host-routed notifications (no toast dependency in the package). */
|
|
919
1029
|
onNotify?: ((notification: WorkspaceNotification) => void) | undefined;
|
|
920
1030
|
/** Alternate Browser frame transport for non-browser runtimes and deterministic tests. */
|
|
921
1031
|
browserWebSocketFactory?: BrowserFrameWebSocketFactory | undefined;
|
|
922
1032
|
/** Alternate Computer frame transport for non-browser runtimes and deterministic tests. */
|
|
923
1033
|
computerWebSocketFactory?: ComputerFrameWebSocketFactory | undefined;
|
|
1034
|
+
/** Host-owned setup page or store listing for attaching an existing Chrome profile. */
|
|
1035
|
+
browserExtensionSetupUrl?: string | undefined;
|
|
924
1036
|
/** Controlled collapsed state for hosts with their own dock toggle. */
|
|
925
1037
|
collapsed?: boolean | undefined;
|
|
926
1038
|
onCollapsedChange?: ((collapsed: boolean) => void) | undefined;
|
|
@@ -951,9 +1063,20 @@ export function SandboxWorkspace(props: SandboxWorkspaceProps): ReactNode {
|
|
|
951
1063
|
leadingTabs,
|
|
952
1064
|
trailingTabs,
|
|
953
1065
|
initialTab,
|
|
1066
|
+
onActiveTabChange,
|
|
1067
|
+
openTabRequest,
|
|
1068
|
+
initialFilePath,
|
|
1069
|
+
onFilePathChange,
|
|
1070
|
+
isFileNodeVisible,
|
|
1071
|
+
openFileRequest,
|
|
1072
|
+
initialBrowserSessionId,
|
|
1073
|
+
onBrowserSessionIdChange,
|
|
1074
|
+
initialComputerSessionId,
|
|
1075
|
+
onComputerSessionIdChange,
|
|
954
1076
|
onNotify,
|
|
955
1077
|
browserWebSocketFactory,
|
|
956
1078
|
computerWebSocketFactory,
|
|
1079
|
+
browserExtensionSetupUrl,
|
|
957
1080
|
collapsed,
|
|
958
1081
|
onCollapsedChange,
|
|
959
1082
|
showCollapseControl,
|
|
@@ -972,6 +1095,7 @@ export function SandboxWorkspace(props: SandboxWorkspaceProps): ReactNode {
|
|
|
972
1095
|
const [requestedFile, setRequestedFile] = useState<{
|
|
973
1096
|
sessionId: string;
|
|
974
1097
|
path: string;
|
|
1098
|
+
line: number | null;
|
|
975
1099
|
requestId: number;
|
|
976
1100
|
} | null>(null);
|
|
977
1101
|
const [requestedComputer, setRequestedComputer] = useState<{
|
|
@@ -982,15 +1106,55 @@ export function SandboxWorkspace(props: SandboxWorkspaceProps): ReactNode {
|
|
|
982
1106
|
const nextFileRequestId = useRef(0);
|
|
983
1107
|
const nextComputerRequestId = useRef(0);
|
|
984
1108
|
const selectedTab = storedSelection?.sessionId === sessionId ? storedSelection.tab : null;
|
|
1109
|
+
const handledTabRequest = useRef<{ sessionId: string; requestId: number } | null>(null);
|
|
1110
|
+
useEffect(() => {
|
|
1111
|
+
if (
|
|
1112
|
+
!openTabRequest ||
|
|
1113
|
+
(handledTabRequest.current?.sessionId === sessionId &&
|
|
1114
|
+
handledTabRequest.current.requestId === openTabRequest.requestId)
|
|
1115
|
+
)
|
|
1116
|
+
return;
|
|
1117
|
+
const available =
|
|
1118
|
+
[...(leadingTabs ?? []), ...(trailingTabs ?? [])].some(
|
|
1119
|
+
(tab) => tab.id === openTabRequest.tab,
|
|
1120
|
+
) || (surfaces ?? WORKBENCH_SURFACES).some((tab) => tab === openTabRequest.tab);
|
|
1121
|
+
if (!available) return;
|
|
1122
|
+
handledTabRequest.current = { sessionId, requestId: openTabRequest.requestId };
|
|
1123
|
+
setStoredSelection({ sessionId, tab: openTabRequest.tab });
|
|
1124
|
+
onActiveTabChange?.(openTabRequest.tab);
|
|
1125
|
+
onCollapsedChange?.(false);
|
|
1126
|
+
}, [
|
|
1127
|
+
openTabRequest,
|
|
1128
|
+
sessionId,
|
|
1129
|
+
leadingTabs,
|
|
1130
|
+
trailingTabs,
|
|
1131
|
+
surfaces,
|
|
1132
|
+
onActiveTabChange,
|
|
1133
|
+
onCollapsedChange,
|
|
1134
|
+
]);
|
|
985
1135
|
const activeTabHint = selectedTab ?? initialTab ?? leadingTabs?.[0]?.id ?? null;
|
|
986
1136
|
const openFile = useCallback(
|
|
987
|
-
(path: string) => {
|
|
988
|
-
|
|
989
|
-
|
|
1137
|
+
(path: string, line?: number | null) => {
|
|
1138
|
+
setRequestedFile({
|
|
1139
|
+
sessionId,
|
|
1140
|
+
path,
|
|
1141
|
+
line: line != null && line > 0 ? line : null,
|
|
1142
|
+
requestId: ++nextFileRequestId.current,
|
|
1143
|
+
});
|
|
990
1144
|
setStoredSelection({ sessionId, tab: WORKBENCH_TAB_FILES });
|
|
1145
|
+
onActiveTabChange?.(WORKBENCH_TAB_FILES);
|
|
1146
|
+
onFilePathChange?.(path);
|
|
1147
|
+
onCollapsedChange?.(false);
|
|
991
1148
|
},
|
|
992
|
-
[sessionId],
|
|
1149
|
+
[onActiveTabChange, onCollapsedChange, onFilePathChange, sessionId],
|
|
993
1150
|
);
|
|
1151
|
+
const handledOpenFileRequestId = useRef<number | null>(null);
|
|
1152
|
+
useEffect(() => {
|
|
1153
|
+
if (!openFileRequest) return;
|
|
1154
|
+
if (handledOpenFileRequestId.current === openFileRequest.requestId) return;
|
|
1155
|
+
handledOpenFileRequestId.current = openFileRequest.requestId;
|
|
1156
|
+
openFile(openFileRequest.path, openFileRequest.line);
|
|
1157
|
+
}, [openFile, openFileRequest]);
|
|
994
1158
|
const openComputer = useCallback(
|
|
995
1159
|
(computerSessionId: string) => {
|
|
996
1160
|
nextComputerRequestId.current += 1;
|
|
@@ -1000,8 +1164,10 @@ export function SandboxWorkspace(props: SandboxWorkspaceProps): ReactNode {
|
|
|
1000
1164
|
requestId: nextComputerRequestId.current,
|
|
1001
1165
|
});
|
|
1002
1166
|
setStoredSelection({ sessionId, tab: WORKBENCH_TAB_DESKTOP });
|
|
1167
|
+
onActiveTabChange?.(WORKBENCH_TAB_DESKTOP);
|
|
1168
|
+
onComputerSessionIdChange?.(computerSessionId);
|
|
1003
1169
|
},
|
|
1004
|
-
[sessionId],
|
|
1170
|
+
[onActiveTabChange, onComputerSessionIdChange, sessionId],
|
|
1005
1171
|
);
|
|
1006
1172
|
|
|
1007
1173
|
const {
|
|
@@ -1020,8 +1186,17 @@ export function SandboxWorkspace(props: SandboxWorkspaceProps): ReactNode {
|
|
|
1020
1186
|
...(onNotify ? { onNotify } : {}),
|
|
1021
1187
|
...(browserWebSocketFactory ? { browserWebSocketFactory } : {}),
|
|
1022
1188
|
...(computerWebSocketFactory ? { computerWebSocketFactory } : {}),
|
|
1189
|
+
...(browserExtensionSetupUrl ? { browserExtensionSetupUrl } : {}),
|
|
1190
|
+
initialFilePath,
|
|
1191
|
+
onFilePathChange,
|
|
1192
|
+
isFileNodeVisible,
|
|
1193
|
+
initialBrowserSessionId,
|
|
1194
|
+
onBrowserSessionIdChange,
|
|
1195
|
+
initialComputerSessionId,
|
|
1196
|
+
onComputerSessionIdChange,
|
|
1023
1197
|
requestedFilePath: requestedFile?.sessionId === sessionId ? requestedFile.path : null,
|
|
1024
1198
|
requestedFileRequestId: requestedFile?.sessionId === sessionId ? requestedFile.requestId : null,
|
|
1199
|
+
requestedFileLine: requestedFile?.sessionId === sessionId ? requestedFile.line : null,
|
|
1025
1200
|
onOpenFile: openFile,
|
|
1026
1201
|
onOpenComputerSession: openComputer,
|
|
1027
1202
|
requestedComputerSessionId:
|
|
@@ -1040,9 +1215,19 @@ export function SandboxWorkspace(props: SandboxWorkspaceProps): ReactNode {
|
|
|
1040
1215
|
const activeTab =
|
|
1041
1216
|
preferredTab && tabs.some((tab) => tab.id === preferredTab) ? preferredTab : tabs[0]?.id;
|
|
1042
1217
|
const selectTab = useCallback(
|
|
1043
|
-
(tab: string) =>
|
|
1044
|
-
|
|
1218
|
+
(tab: string) => {
|
|
1219
|
+
setStoredSelection({ sessionId, tab });
|
|
1220
|
+
onActiveTabChange?.(tab);
|
|
1221
|
+
},
|
|
1222
|
+
[onActiveTabChange, sessionId],
|
|
1045
1223
|
);
|
|
1224
|
+
useEffect(() => {
|
|
1225
|
+
if (selectedTab !== null || defaultTab === null) return;
|
|
1226
|
+
// Once the source-driven choice resolves, make it the real controlled
|
|
1227
|
+
// selection. Without this handoff the dock could visibly show Files while
|
|
1228
|
+
// the data hooks continued treating the selection as unresolved.
|
|
1229
|
+
setStoredSelection({ sessionId, tab: defaultTab });
|
|
1230
|
+
}, [defaultTab, selectedTab, sessionId]);
|
|
1046
1231
|
|
|
1047
1232
|
return (
|
|
1048
1233
|
<WorkspaceDock
|
|
@@ -1050,7 +1235,12 @@ export function SandboxWorkspace(props: SandboxWorkspaceProps): ReactNode {
|
|
|
1050
1235
|
tabs={tabs}
|
|
1051
1236
|
{...(activeTab !== undefined ? { activeTab } : {})}
|
|
1052
1237
|
onActiveTabChange={selectTab}
|
|
1053
|
-
|
|
1238
|
+
// Browser and Desktop select independent workspace resources, potentially
|
|
1239
|
+
// on another placement. Their own viewers report runtime status; the
|
|
1240
|
+
// agent-session machine chip must not describe those resources.
|
|
1241
|
+
{...(machine.enabled &&
|
|
1242
|
+
activeTab !== WORKBENCH_TAB_BROWSER &&
|
|
1243
|
+
activeTab !== WORKBENCH_TAB_DESKTOP
|
|
1054
1244
|
? {
|
|
1055
1245
|
headerAccessory: <MachineStateChip chip={machine.chip} />,
|
|
1056
1246
|
}
|
|
@@ -1086,7 +1276,7 @@ function chipDotClass(state: MachineChip["state"]): string {
|
|
|
1086
1276
|
}
|
|
1087
1277
|
|
|
1088
1278
|
/**
|
|
1089
|
-
* The dock-header machine status: one quiet, truthful live/waking/
|
|
1279
|
+
* The dock-header machine status: one quiet, truthful live/waking/resting
|
|
1090
1280
|
* indicator. It is intentionally not interactive; detailed machine controls do
|
|
1091
1281
|
* not belong in a transient popover above the workspace tabs.
|
|
1092
1282
|
*/
|
|
@@ -1170,6 +1360,7 @@ function ChangesTabContent({
|
|
|
1170
1360
|
git,
|
|
1171
1361
|
comparison,
|
|
1172
1362
|
captureAvailable,
|
|
1363
|
+
captureDegraded,
|
|
1173
1364
|
captureRevision,
|
|
1174
1365
|
capturePending,
|
|
1175
1366
|
liveWorkspaceExpected,
|
|
@@ -1183,6 +1374,7 @@ function ChangesTabContent({
|
|
|
1183
1374
|
git: UseSandboxGitResult;
|
|
1184
1375
|
comparison: SandboxGitComparison;
|
|
1185
1376
|
captureAvailable: boolean;
|
|
1377
|
+
captureDegraded: boolean;
|
|
1186
1378
|
captureRevision: number | null;
|
|
1187
1379
|
capturePending: boolean;
|
|
1188
1380
|
liveWorkspaceExpected: boolean;
|
|
@@ -1276,6 +1468,8 @@ function ChangesTabContent({
|
|
|
1276
1468
|
}
|
|
1277
1469
|
|
|
1278
1470
|
if (!liveWorkspaceExpected && (comparison !== "working" || !captureAvailable)) {
|
|
1471
|
+
// Staged changes are live-only; a failed saved preview is not their blocker.
|
|
1472
|
+
const previewUnavailable = captureDegraded && !captureAvailable && comparison !== "staged";
|
|
1279
1473
|
return (
|
|
1280
1474
|
<CenteredState
|
|
1281
1475
|
icon={
|
|
@@ -1284,22 +1478,30 @@ function ChangesTabContent({
|
|
|
1284
1478
|
className="size-5 animate-spin motion-reduce:animate-none"
|
|
1285
1479
|
aria-hidden
|
|
1286
1480
|
/>
|
|
1481
|
+
) : previewUnavailable ? (
|
|
1482
|
+
<TriangleAlertIcon className="size-5" aria-hidden />
|
|
1287
1483
|
) : (
|
|
1288
1484
|
<CpuIcon className="size-5" aria-hidden />
|
|
1289
1485
|
)
|
|
1290
1486
|
}
|
|
1291
1487
|
>
|
|
1292
1488
|
<p className="text-og-sm font-medium text-og-fg">
|
|
1293
|
-
{workspaceWaking
|
|
1489
|
+
{workspaceWaking
|
|
1490
|
+
? "Waking workspace"
|
|
1491
|
+
: previewUnavailable
|
|
1492
|
+
? "Saved changes preview is unavailable"
|
|
1493
|
+
: "Workspace is resting"}
|
|
1294
1494
|
</p>
|
|
1295
1495
|
<p className="text-og-sm leading-5 text-og-fg-subtle">
|
|
1296
1496
|
{workspaceWaking
|
|
1297
1497
|
? "Connecting to the live working tree…"
|
|
1298
|
-
:
|
|
1299
|
-
? "
|
|
1300
|
-
: comparison === "
|
|
1301
|
-
? "Wake the sandbox to
|
|
1302
|
-
:
|
|
1498
|
+
: previewUnavailable
|
|
1499
|
+
? "Open the live workspace to view current changes."
|
|
1500
|
+
: comparison === "branch"
|
|
1501
|
+
? "Wake the sandbox to compare this branch with the remote default branch."
|
|
1502
|
+
: comparison === "staged"
|
|
1503
|
+
? "Wake the sandbox to inspect staged changes."
|
|
1504
|
+
: "No captured revision is available yet. Wake the sandbox to inspect uncommitted changes."}
|
|
1303
1505
|
</p>
|
|
1304
1506
|
{!workspaceWaking ? (
|
|
1305
1507
|
<DockActionButton onClick={onWake}>
|