@opengeni/react 1.0.1 → 1.0.2-canary.37202341988001
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 +660 -21
- 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-SHYKQRNX.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-26ZNDDLZ.js +453 -0
- package/dist/chunk-26ZNDDLZ.js.map +1 -0
- package/dist/chunk-3CTRFMAK.js +359 -0
- package/dist/chunk-3CTRFMAK.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-742CZ3L3.js +481 -0
- package/dist/chunk-742CZ3L3.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-6KLX2RH5.js → chunk-DO544OSV.js} +1075 -79
- package/dist/chunk-DO544OSV.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-HA46CYQK.js → chunk-EESD3PY3.js} +792 -537
- package/dist/chunk-EESD3PY3.js.map +1 -0
- package/dist/{chunk-5UQPNLIO.js → chunk-EN3YTHKR.js} +4117 -3896
- package/dist/chunk-EN3YTHKR.js.map +1 -0
- package/dist/chunk-ERGYJIBB.js +21 -0
- package/dist/chunk-ERGYJIBB.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-GYVRFZDY.js +2733 -0
- package/dist/chunk-GYVRFZDY.js.map +1 -0
- package/dist/{chunk-LLOLUHVG.js → chunk-HDJWDK7W.js} +1358 -2746
- package/dist/chunk-HDJWDK7W.js.map +1 -0
- package/dist/chunk-I7IWRQLN.js +1608 -0
- package/dist/chunk-I7IWRQLN.js.map +1 -0
- package/dist/chunk-IT4BJUGF.js +13055 -0
- package/dist/chunk-IT4BJUGF.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-J6DBS4T3.js +371 -0
- package/dist/chunk-J6DBS4T3.js.map +1 -0
- package/dist/{chunk-B6WPZSTT.js → chunk-JIQYUGVL.js} +1331 -1163
- package/dist/chunk-JIQYUGVL.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-PEI6RANI.js → chunk-PNY3JKBJ.js} +309 -74
- package/dist/chunk-PNY3JKBJ.js.map +1 -0
- package/dist/chunk-RHREZ7BO.js +11 -0
- package/dist/chunk-RHREZ7BO.js.map +1 -0
- package/dist/chunk-RLUSC2WA.js +299 -0
- package/dist/chunk-RLUSC2WA.js.map +1 -0
- package/dist/{chunk-IGC6A2ZI.js → chunk-RSI7XYXL.js} +777 -246
- package/dist/chunk-RSI7XYXL.js.map +1 -0
- package/dist/chunk-SCOTPE2I.js +589 -0
- package/dist/chunk-SCOTPE2I.js.map +1 -0
- package/dist/{chunk-C5ZPSSS5.js → chunk-TKOTKRWY.js} +5 -4
- package/dist/{chunk-C5ZPSSS5.js.map → chunk-TKOTKRWY.js.map} +1 -1
- 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-WGXVEJO5.js +319 -0
- package/dist/chunk-WGXVEJO5.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-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-YM2DE7BQ.js +3124 -0
- package/dist/chunk-YM2DE7BQ.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-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 +58 -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 +89 -0
- package/dist/components/session-list.d.ts +36 -0
- package/dist/components/session-mcp-capability-card.d.ts +41 -0
- package/dist/components/session-proxy-scope.d.ts +21 -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-6SRGWRUX.js +19 -0
- package/dist/computer-viewer-6SRGWRUX.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 +2238 -6201
- 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-HTRIS4KJ.js +117 -0
- package/dist/latest-question-HTRIS4KJ.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-M54ISBMN.js +14 -0
- package/dist/model-policy-picker-menu-M54ISBMN.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 +6 -3
- package/dist/realtime.js +133 -74
- package/dist/realtime.js.map +1 -1
- package/dist/sandbox-files-GORZOUUJ.js +20 -0
- package/dist/sandbox-files-GORZOUUJ.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 +34 -3
- package/dist/timeline/types.d.ts +147 -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 +2754 -665
- 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 +338 -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 +526 -0
- package/src/components/session-list.tsx +250 -0
- package/src/components/session-mcp-capability-card.tsx +680 -0
- package/src/components/session-proxy-scope.tsx +92 -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-video-artifact-playback.ts +1 -1
- 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 +133 -46
- package/src/session-auth-recommendation.ts +48 -0
- package/src/session-capability-policy.ts +83 -0
- package/src/session-context.ts +4 -3
- 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 +1609 -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 +218 -44
- package/src/timeline/types.ts +192 -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-SHYKQRNX.js.map} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
2
|
-
import { useEffect, useRef, useState, type MouseEvent, type ReactNode } from "react";
|
|
2
|
+
import { memo, useEffect, useRef, useState, type MouseEvent, type ReactNode } from "react";
|
|
3
3
|
import { cn } from "../lib/cn";
|
|
4
4
|
import { copyTextToClipboard } from "../lib/clipboard";
|
|
5
5
|
import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip";
|
|
@@ -22,8 +22,10 @@ export type CopyButtonProps = {
|
|
|
22
22
|
/**
|
|
23
23
|
* Ghost icon copy control — no chrome box, no "Copy code" label.
|
|
24
24
|
* Copy → check flash. Hover-reveal via `group/copy` on a parent.
|
|
25
|
+
* Keep unchanged controls out of parent message rerenders: mounting history
|
|
26
|
+
* already has to commit each new tooltip, without redoing the retained suffix.
|
|
25
27
|
*/
|
|
26
|
-
export function CopyButton({
|
|
28
|
+
export const CopyButton = memo(function CopyButton({
|
|
27
29
|
text,
|
|
28
30
|
label = "Copy",
|
|
29
31
|
className,
|
|
@@ -113,7 +115,7 @@ export function CopyButton({
|
|
|
113
115
|
<TooltipContent side="top">{tip}</TooltipContent>
|
|
114
116
|
</Tooltip>
|
|
115
117
|
);
|
|
116
|
-
}
|
|
118
|
+
});
|
|
117
119
|
|
|
118
120
|
/** Hover-reveal chrome around a message / turn so {@link CopyButton} can fade in. */
|
|
119
121
|
export function CopyHoverFrame({
|
|
@@ -140,12 +142,18 @@ export function CopyHoverFrame({
|
|
|
140
142
|
{children}
|
|
141
143
|
{/* Sit under the body — top-right overlay collided with the first line. */}
|
|
142
144
|
<div
|
|
145
|
+
data-og-annotation-chrome=""
|
|
143
146
|
className={cn(
|
|
144
|
-
"
|
|
147
|
+
"flex h-6 items-center gap-1.5 pointer-coarse:h-11",
|
|
145
148
|
align === "end" ? "justify-end" : "justify-start",
|
|
146
149
|
)}
|
|
147
150
|
>
|
|
148
|
-
<CopyButton
|
|
151
|
+
<CopyButton
|
|
152
|
+
text={copyText}
|
|
153
|
+
label={label}
|
|
154
|
+
reveal="group-hover"
|
|
155
|
+
className="size-6 pointer-coarse:size-11"
|
|
156
|
+
/>
|
|
149
157
|
{trailing}
|
|
150
158
|
</div>
|
|
151
159
|
</div>
|
|
@@ -30,7 +30,7 @@ export type DesktopViewerProps = {
|
|
|
30
30
|
/** Render the built-in Watching ⇄ Take control toggle (default true). */
|
|
31
31
|
showControlToggle?: boolean | undefined;
|
|
32
32
|
scaleViewport?: boolean | undefined;
|
|
33
|
-
/** Custom RFB factory (
|
|
33
|
+
/** Custom RFB factory; otherwise enableDesktopViewer() supplies lazy noVNC. */
|
|
34
34
|
rfbFactory?: DesktopRfbFactory | undefined;
|
|
35
35
|
/** Authenticated controller protocols for proxied RFB transports. */
|
|
36
36
|
webSocketProtocols?: string[] | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ReactNode, useState } from "react";
|
|
2
|
+
import type { ResourceAuthorityScope } from "@opengeni/sdk";
|
|
2
3
|
import {
|
|
3
4
|
CircleAlertIcon,
|
|
4
5
|
LaptopIcon,
|
|
@@ -30,8 +31,10 @@ export type EnrollmentConsentProps = {
|
|
|
30
31
|
userCode: string;
|
|
31
32
|
machine: EnrollmentConsentMachine;
|
|
32
33
|
phase?: EnrollmentConsentPhase | undefined;
|
|
33
|
-
/**
|
|
34
|
-
|
|
34
|
+
/** Whether this caller may publish the machine to the whole organization. */
|
|
35
|
+
allowOrganizationScope?: boolean | undefined;
|
|
36
|
+
/** Approve with the chosen screen-control consent and explicit access scope. */
|
|
37
|
+
onApprove?: ((allowScreenControl: boolean, scope: ResourceAuthorityScope) => void) | undefined;
|
|
35
38
|
onDeny?: (() => void) | undefined;
|
|
36
39
|
/** Error message when phase === "error". */
|
|
37
40
|
errorMessage?: string | undefined;
|
|
@@ -61,13 +64,29 @@ export function EnrollmentConsent({
|
|
|
61
64
|
userCode,
|
|
62
65
|
machine,
|
|
63
66
|
phase = "review",
|
|
67
|
+
allowOrganizationScope = false,
|
|
64
68
|
onApprove,
|
|
65
69
|
onDeny,
|
|
66
70
|
errorMessage,
|
|
67
71
|
className,
|
|
68
72
|
}: EnrollmentConsentProps) {
|
|
69
73
|
const [allowScreenControl, setAllowScreenControl] = useState(machine.requestsScreenControl);
|
|
74
|
+
const [scope, setScope] = useState<ResourceAuthorityScope>("user");
|
|
70
75
|
const busy = phase === "approving";
|
|
76
|
+
const scopeCopy = {
|
|
77
|
+
user: {
|
|
78
|
+
label: "Personal",
|
|
79
|
+
body: "Only you can use this machine, from any workspace you can access in this organization.",
|
|
80
|
+
},
|
|
81
|
+
workspace: {
|
|
82
|
+
label: "Workspace",
|
|
83
|
+
body: "Everyone with access to this workspace can use this machine.",
|
|
84
|
+
},
|
|
85
|
+
organization: {
|
|
86
|
+
label: "Organization",
|
|
87
|
+
body: "Members of this organization can use this machine from their workspaces.",
|
|
88
|
+
},
|
|
89
|
+
} satisfies Record<ResourceAuthorityScope, { label: string; body: string }>;
|
|
71
90
|
|
|
72
91
|
if (phase === "approved") {
|
|
73
92
|
return (
|
|
@@ -75,7 +94,7 @@ export function EnrollmentConsent({
|
|
|
75
94
|
className={className}
|
|
76
95
|
tone="ok"
|
|
77
96
|
title="Machine connected"
|
|
78
|
-
body={`${machine.machineName} is now
|
|
97
|
+
body={`${machine.machineName} is now connected with ${scopeCopy[scope].label.toLowerCase()} access. You can close this page — it will appear in your Machines dashboard.`}
|
|
79
98
|
/>
|
|
80
99
|
);
|
|
81
100
|
}
|
|
@@ -120,7 +139,7 @@ export function EnrollmentConsent({
|
|
|
120
139
|
Give the agent your whole machine?
|
|
121
140
|
</h1>
|
|
122
141
|
<p className="mt-1 text-og-base text-og-fg-muted">
|
|
123
|
-
Approving lets the
|
|
142
|
+
Approving lets the Opengeni agent run on{" "}
|
|
124
143
|
<span className="font-medium text-og-fg">{machine.machineName}</span> with full access.
|
|
125
144
|
This is your real computer — not a sandbox.
|
|
126
145
|
</p>
|
|
@@ -156,11 +175,50 @@ export function EnrollmentConsent({
|
|
|
156
175
|
) : null}
|
|
157
176
|
<Capability
|
|
158
177
|
icon={<UsersIcon className="size-4" aria-hidden />}
|
|
159
|
-
title=
|
|
160
|
-
body=
|
|
178
|
+
title={`${scopeCopy[scope].label} access while connected`}
|
|
179
|
+
body={`${scopeCopy[scope].body} Disconnect the agent to revoke access instantly.`}
|
|
161
180
|
/>
|
|
162
181
|
</ul>
|
|
163
182
|
|
|
183
|
+
<fieldset className="flex flex-col gap-2" disabled={busy}>
|
|
184
|
+
<legend className="mb-1 text-og-sm font-medium text-og-fg">
|
|
185
|
+
Who can use this machine?
|
|
186
|
+
</legend>
|
|
187
|
+
{(["user", "workspace", "organization"] as const).map((candidate) => {
|
|
188
|
+
const disabled = candidate === "organization" && !allowOrganizationScope;
|
|
189
|
+
return (
|
|
190
|
+
<label
|
|
191
|
+
key={candidate}
|
|
192
|
+
data-enrollment-scope={candidate}
|
|
193
|
+
data-disabled={disabled ? "true" : "false"}
|
|
194
|
+
className={cn(
|
|
195
|
+
"flex items-start gap-2.5 rounded-og-md border border-og-border bg-og-bg px-3 py-2.5",
|
|
196
|
+
disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer",
|
|
197
|
+
)}
|
|
198
|
+
>
|
|
199
|
+
<input
|
|
200
|
+
type="radio"
|
|
201
|
+
name="enrollment-scope"
|
|
202
|
+
value={candidate}
|
|
203
|
+
checked={scope === candidate}
|
|
204
|
+
disabled={disabled || busy}
|
|
205
|
+
onChange={() => setScope(candidate)}
|
|
206
|
+
className="mt-0.5 size-4 accent-og-accent"
|
|
207
|
+
/>
|
|
208
|
+
<span className="min-w-0">
|
|
209
|
+
<span className="block text-og-base font-medium text-og-fg">
|
|
210
|
+
{scopeCopy[candidate].label}
|
|
211
|
+
{disabled ? " · organization admin required" : ""}
|
|
212
|
+
</span>
|
|
213
|
+
<span className="block text-og-sm text-og-fg-muted">
|
|
214
|
+
{scopeCopy[candidate].body}
|
|
215
|
+
</span>
|
|
216
|
+
</span>
|
|
217
|
+
</label>
|
|
218
|
+
);
|
|
219
|
+
})}
|
|
220
|
+
</fieldset>
|
|
221
|
+
|
|
164
222
|
{machine.canOfferDisplay ? (
|
|
165
223
|
<label
|
|
166
224
|
data-screen-control-toggle
|
|
@@ -206,7 +264,7 @@ export function EnrollmentConsent({
|
|
|
206
264
|
type="button"
|
|
207
265
|
data-approve
|
|
208
266
|
disabled={busy}
|
|
209
|
-
onClick={() => onApprove?.(allowScreenControl)}
|
|
267
|
+
onClick={() => onApprove?.(allowScreenControl, scope)}
|
|
210
268
|
className="flex-1 rounded-og-sm bg-og-status-failed px-3 py-2 text-og-sm font-semibold text-og-accent-fg transition-colors hover:opacity-90 disabled:opacity-50 pointer-coarse:min-h-11"
|
|
211
269
|
>
|
|
212
270
|
{busy ? "Connecting…" : "Grant full access"}
|
|
@@ -156,7 +156,7 @@ export function EnrollmentDeviceFlow({
|
|
|
156
156
|
target="_blank"
|
|
157
157
|
rel="noreferrer"
|
|
158
158
|
onClick={onOpenVerification}
|
|
159
|
-
className="inline-flex items-center justify-center gap-1.5 rounded-og-sm bg-og-
|
|
159
|
+
className="inline-flex items-center justify-center gap-1.5 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-2 text-og-menu font-medium transition-colors hover:bg-og-primary-hover"
|
|
160
160
|
>
|
|
161
161
|
Open approval page
|
|
162
162
|
<ExternalLinkIcon className="size-3.5" aria-hidden />
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
import { AlertDialog } from "radix-ui";
|
|
25
25
|
import { VList, type VListHandle } from "virtua";
|
|
26
26
|
import { cn } from "../lib/cn";
|
|
27
|
+
import { MENU_BUTTON_CLASS, MENU_SEPARATOR_CLASS, MENU_SURFACE_CLASS } from "../lib/menu-styles";
|
|
27
28
|
import {
|
|
28
29
|
type PortalTokenStyle,
|
|
29
30
|
usePortalTokenSource,
|
|
@@ -31,6 +32,7 @@ import {
|
|
|
31
32
|
} from "../lib/use-portal-token-style";
|
|
32
33
|
import { useUnicodeFallbackFonts } from "../lib/use-unicode-fonts";
|
|
33
34
|
import type { FileTreeNode, UseSandboxFilesResult } from "../hooks/use-sandbox-files";
|
|
35
|
+
import { visibleFileTree, type FileNodeVisibilityPredicate } from "../file-node-visibility";
|
|
34
36
|
|
|
35
37
|
export type FileBrowserProps = {
|
|
36
38
|
/** From `useSandboxFiles(...)`. */
|
|
@@ -43,6 +45,14 @@ export type FileBrowserProps = {
|
|
|
43
45
|
/** Selection callback for the preview pane. */
|
|
44
46
|
onSelectFile?: ((path: string) => void) | undefined;
|
|
45
47
|
selectedPath?: string | undefined;
|
|
48
|
+
/** Presentation-only node filter. Hidden parents never expose their children. */
|
|
49
|
+
isNodeVisible?: FileNodeVisibilityPredicate | undefined;
|
|
50
|
+
/** Deliberately reveal this selected path by lazily opening every loaded
|
|
51
|
+
* ancestor and scrolling its row into view. The path is opaque and is never
|
|
52
|
+
* normalized or re-rooted here. */
|
|
53
|
+
revealPath?: string | undefined;
|
|
54
|
+
/** Increment/change to reveal the same path again after a user collapses it. */
|
|
55
|
+
revealPathRequestId?: string | number | undefined;
|
|
46
56
|
/** Render-prop to theme/replace a row entirely (the Pierre-swap escape hatch). */
|
|
47
57
|
renderNode?: ((node: FileTreeNode, depth: number, expanded: boolean) => ReactNode) | undefined;
|
|
48
58
|
/** Shown when the tree is empty (no files / not loaded yet). */
|
|
@@ -96,11 +106,18 @@ function itemKey(item: RenderItem): string {
|
|
|
96
106
|
}
|
|
97
107
|
}
|
|
98
108
|
|
|
99
|
-
|
|
109
|
+
function pathIsInsideDirectory(path: string, directory: string): boolean {
|
|
110
|
+
if (!path.startsWith(directory) || path === directory) return false;
|
|
111
|
+
if (directory.endsWith("/") || directory.endsWith("\\")) return true;
|
|
112
|
+
const boundary = path[directory.length];
|
|
113
|
+
return boundary === "/" || boundary === "\\";
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Walk the authoritative tree without assuming its target-owned separator. */
|
|
100
117
|
function findNode(nodes: FileTreeNode[], path: string): FileTreeNode | undefined {
|
|
101
118
|
for (const node of nodes) {
|
|
102
119
|
if (node.path === path) return node;
|
|
103
|
-
if (node.kind === "dir" && node.children && path
|
|
120
|
+
if (node.kind === "dir" && node.children && pathIsInsideDirectory(path, node.path)) {
|
|
104
121
|
const hit = findNode(node.children, path);
|
|
105
122
|
if (hit) return hit;
|
|
106
123
|
}
|
|
@@ -108,6 +125,34 @@ function findNode(nodes: FileTreeNode[], path: string): FileTreeNode | undefined
|
|
|
108
125
|
return undefined;
|
|
109
126
|
}
|
|
110
127
|
|
|
128
|
+
type RevealTrace = {
|
|
129
|
+
directories: string[];
|
|
130
|
+
frontier: string | null;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/** Follow only paths already named by the authoritative tree. This deliberately
|
|
134
|
+
* avoids manufacturing ancestors from a platform-specific path string. */
|
|
135
|
+
function traceRevealPath(nodes: FileTreeNode[], targetPath: string): RevealTrace {
|
|
136
|
+
for (const node of nodes) {
|
|
137
|
+
if (node.path === targetPath) {
|
|
138
|
+
return {
|
|
139
|
+
directories: node.kind === "dir" ? [node.path] : [],
|
|
140
|
+
frontier: node.kind === "dir" && node.children === undefined ? node.path : null,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (node.kind !== "dir" || !pathIsInsideDirectory(targetPath, node.path)) continue;
|
|
144
|
+
if (node.children === undefined) {
|
|
145
|
+
return { directories: [node.path], frontier: node.path };
|
|
146
|
+
}
|
|
147
|
+
const child = traceRevealPath(node.children, targetPath);
|
|
148
|
+
return {
|
|
149
|
+
directories: [node.path, ...child.directories],
|
|
150
|
+
frontier: child.frontier,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return { directories: [], frontier: null };
|
|
154
|
+
}
|
|
155
|
+
|
|
111
156
|
/** A pending inline-create: a phantom input row under `parent`. */
|
|
112
157
|
type DraftCreate = { parent: string; kind: "file" | "dir" };
|
|
113
158
|
/** A pending inline-rename of an existing node. */
|
|
@@ -142,6 +187,9 @@ export function FileBrowser({
|
|
|
142
187
|
fallback,
|
|
143
188
|
onSelectFile,
|
|
144
189
|
selectedPath,
|
|
190
|
+
isNodeVisible,
|
|
191
|
+
revealPath,
|
|
192
|
+
revealPathRequestId,
|
|
145
193
|
renderNode,
|
|
146
194
|
emptyState,
|
|
147
195
|
editable = true,
|
|
@@ -158,6 +206,15 @@ export function FileBrowser({
|
|
|
158
206
|
const [pendingDelete, setPendingDelete] = useState<FileTreeNode | null>(null);
|
|
159
207
|
const [busy, setBusy] = useState(false);
|
|
160
208
|
const [coarsePointer, setCoarsePointer] = useState(false);
|
|
209
|
+
const [revealRequest, setRevealRequest] = useState<{
|
|
210
|
+
path: string;
|
|
211
|
+
requestId: string | number;
|
|
212
|
+
} | null>(null);
|
|
213
|
+
const handledRevealRequestRef = useRef<{
|
|
214
|
+
path: string;
|
|
215
|
+
requestId: string | number;
|
|
216
|
+
} | null>(null);
|
|
217
|
+
const attemptedRevealPathsRef = useRef<Set<string>>(new Set());
|
|
161
218
|
const treeId = useId();
|
|
162
219
|
const container = usePortalTokenSource<HTMLDivElement>();
|
|
163
220
|
const containerRef = container.currentRef;
|
|
@@ -168,6 +225,10 @@ export function FileBrowser({
|
|
|
168
225
|
() => (typeof document === "undefined" ? null : document.getElementById(treeId)),
|
|
169
226
|
[treeId],
|
|
170
227
|
);
|
|
228
|
+
const visibleTree = useMemo(
|
|
229
|
+
() => visibleFileTree(result.tree, isNodeVisible),
|
|
230
|
+
[isNodeVisible, result.tree],
|
|
231
|
+
);
|
|
171
232
|
|
|
172
233
|
useBrowserLayoutEffect(() => {
|
|
173
234
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
@@ -184,13 +245,35 @@ export function FileBrowser({
|
|
|
184
245
|
}
|
|
185
246
|
}, []);
|
|
186
247
|
|
|
248
|
+
const effectiveRevealRequestId = revealPath ? (revealPathRequestId ?? revealPath) : null;
|
|
249
|
+
useEffect(() => {
|
|
250
|
+
if (!revealPath || effectiveRevealRequestId === null) {
|
|
251
|
+
setRevealRequest(null);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const handled = handledRevealRequestRef.current;
|
|
255
|
+
if (handled?.path === revealPath && handled.requestId === effectiveRevealRequestId) return;
|
|
256
|
+
handledRevealRequestRef.current = {
|
|
257
|
+
path: revealPath,
|
|
258
|
+
requestId: effectiveRevealRequestId,
|
|
259
|
+
};
|
|
260
|
+
attemptedRevealPathsRef.current = new Set();
|
|
261
|
+
setActive(null);
|
|
262
|
+
setRevealRequest({ path: revealPath, requestId: effectiveRevealRequestId });
|
|
263
|
+
}, [effectiveRevealRequestId, revealPath]);
|
|
264
|
+
|
|
187
265
|
// The keyboard cursor: an explicitly-navigated node falls back to the
|
|
188
266
|
// externally-selected file so arrow keys pick up where the preview pane is.
|
|
189
|
-
const
|
|
267
|
+
const visibleActive = active && findNode(visibleTree, active) ? active : null;
|
|
268
|
+
const cursor =
|
|
269
|
+
visibleActive ?? (selectedPath && findNode(visibleTree, selectedPath) ? selectedPath : null);
|
|
270
|
+
useEffect(() => {
|
|
271
|
+
if (active !== null && visibleActive === null) setActive(null);
|
|
272
|
+
}, [active, visibleActive]);
|
|
190
273
|
|
|
191
274
|
const expand = useCallback(
|
|
192
275
|
async (path: string) => {
|
|
193
|
-
const node = findNode(
|
|
276
|
+
const node = findNode(visibleTree, path);
|
|
194
277
|
if (node && node.kind === "dir" && node.children === undefined) {
|
|
195
278
|
setLoadingPaths((prev) => new Set(prev).add(path));
|
|
196
279
|
try {
|
|
@@ -204,7 +287,7 @@ export function FileBrowser({
|
|
|
204
287
|
}
|
|
205
288
|
}
|
|
206
289
|
},
|
|
207
|
-
[result],
|
|
290
|
+
[result, visibleTree],
|
|
208
291
|
);
|
|
209
292
|
|
|
210
293
|
const open = useCallback(
|
|
@@ -215,6 +298,34 @@ export function FileBrowser({
|
|
|
215
298
|
[expand],
|
|
216
299
|
);
|
|
217
300
|
|
|
301
|
+
useEffect(() => {
|
|
302
|
+
if (!revealRequest) return;
|
|
303
|
+
const trace = traceRevealPath(visibleTree, revealRequest.path);
|
|
304
|
+
if (trace.directories.length > 0) {
|
|
305
|
+
setExpanded((previous) => {
|
|
306
|
+
const next = new Set(previous);
|
|
307
|
+
let changed = false;
|
|
308
|
+
for (const path of trace.directories) {
|
|
309
|
+
if (next.has(path)) continue;
|
|
310
|
+
next.add(path);
|
|
311
|
+
changed = true;
|
|
312
|
+
}
|
|
313
|
+
return changed ? next : previous;
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
const frontier = trace.frontier;
|
|
317
|
+
if (
|
|
318
|
+
!frontier ||
|
|
319
|
+
attemptedRevealPathsRef.current.has(frontier) ||
|
|
320
|
+
loadingPaths.has(frontier) ||
|
|
321
|
+
result.expandingPaths.has(frontier)
|
|
322
|
+
) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
attemptedRevealPathsRef.current.add(frontier);
|
|
326
|
+
void expand(frontier);
|
|
327
|
+
}, [expand, loadingPaths, result.expandingPaths, revealRequest, visibleTree]);
|
|
328
|
+
|
|
218
329
|
const toggle = useCallback(
|
|
219
330
|
async (node: FileTreeNode) => {
|
|
220
331
|
if (node.kind !== "dir") return;
|
|
@@ -265,9 +376,9 @@ export function FileBrowser({
|
|
|
265
376
|
}
|
|
266
377
|
}
|
|
267
378
|
};
|
|
268
|
-
walk(
|
|
379
|
+
walk(visibleTree, 0);
|
|
269
380
|
return items;
|
|
270
|
-
}, [
|
|
381
|
+
}, [visibleTree, expanded, draftCreate, loadingPaths, result.expandingPaths, cold]);
|
|
271
382
|
const unicodeFontPaths = useMemo(
|
|
272
383
|
() => renderItems.flatMap((item) => (item.type === "node" ? [item.node.path] : [])),
|
|
273
384
|
[renderItems],
|
|
@@ -294,9 +405,9 @@ export function FileBrowser({
|
|
|
294
405
|
if (node.children) visit(node.children);
|
|
295
406
|
});
|
|
296
407
|
};
|
|
297
|
-
visit(
|
|
408
|
+
visit(visibleTree);
|
|
298
409
|
return positions;
|
|
299
|
-
}, [
|
|
410
|
+
}, [visibleTree]);
|
|
300
411
|
const cursorIndex = cursor ? (rowIndexByPath.get(cursor) ?? -1) : -1;
|
|
301
412
|
const activeDescendantId = cursorIndex >= 0 ? `${treeId}-item-${cursorIndex}` : undefined;
|
|
302
413
|
|
|
@@ -388,7 +499,7 @@ export function FileBrowser({
|
|
|
388
499
|
const draft = draftRename;
|
|
389
500
|
setDraftRename(null);
|
|
390
501
|
if (!draft || !supportsMutation) return;
|
|
391
|
-
const node = findNode(
|
|
502
|
+
const node = findNode(visibleTree, draft.path);
|
|
392
503
|
const trimmed = name.trim().replace(/\/+$/, "");
|
|
393
504
|
if (!node || !trimmed || trimmed === node.name) return;
|
|
394
505
|
const newPath = joinPath(parentOf(draft.path), trimmed);
|
|
@@ -405,21 +516,21 @@ export function FileBrowser({
|
|
|
405
516
|
setBusy(false);
|
|
406
517
|
}
|
|
407
518
|
},
|
|
408
|
-
[draftRename, supportsMutation, result, selectedPath, active, onSelectFile],
|
|
519
|
+
[draftRename, supportsMutation, result, selectedPath, active, onSelectFile, visibleTree],
|
|
409
520
|
);
|
|
410
521
|
|
|
411
522
|
// Begin a new file/folder under the active node's directory (or root).
|
|
412
523
|
const startCreate = useCallback(
|
|
413
524
|
(kind: "file" | "dir") => {
|
|
414
525
|
if (!supportsMutation) return;
|
|
415
|
-
const anchor = cursor ? findNode(
|
|
526
|
+
const anchor = cursor ? findNode(visibleTree, cursor) : undefined;
|
|
416
527
|
const parent = anchor ? (anchor.kind === "dir" ? anchor.path : parentOf(anchor.path)) : "";
|
|
417
528
|
if (parent) open(parent);
|
|
418
529
|
setDraftRename(null);
|
|
419
530
|
setMenu(null);
|
|
420
531
|
setDraftCreate({ parent, kind });
|
|
421
532
|
},
|
|
422
|
-
[supportsMutation, cursor,
|
|
533
|
+
[supportsMutation, cursor, open, visibleTree],
|
|
423
534
|
);
|
|
424
535
|
|
|
425
536
|
const startRename = useCallback(
|
|
@@ -437,7 +548,7 @@ export function FileBrowser({
|
|
|
437
548
|
async (targetDir: string, sourcePath: string) => {
|
|
438
549
|
setDragOver(null);
|
|
439
550
|
if (!supportsMutation || !sourcePath) return;
|
|
440
|
-
const src = findNode(
|
|
551
|
+
const src = findNode(visibleTree, sourcePath);
|
|
441
552
|
if (!src) return;
|
|
442
553
|
// No-op drops: onto its own current parent, onto itself, or into its own subtree.
|
|
443
554
|
if (parentOf(sourcePath) === targetDir) return;
|
|
@@ -457,7 +568,7 @@ export function FileBrowser({
|
|
|
457
568
|
setBusy(false);
|
|
458
569
|
}
|
|
459
570
|
},
|
|
460
|
-
[supportsMutation, result, selectedPath, active, onSelectFile],
|
|
571
|
+
[supportsMutation, result, selectedPath, active, onSelectFile, visibleTree],
|
|
461
572
|
);
|
|
462
573
|
|
|
463
574
|
const onKeyDown = useCallback(
|
|
@@ -594,9 +705,9 @@ export function FileBrowser({
|
|
|
594
705
|
};
|
|
595
706
|
}, [menu]);
|
|
596
707
|
|
|
597
|
-
const showErrorEmpty = result.error &&
|
|
598
|
-
const showDegradedTree = result.error &&
|
|
599
|
-
const showEmpty = !result.loading &&
|
|
708
|
+
const showErrorEmpty = result.error && visibleTree.length === 0 && !draftCreate;
|
|
709
|
+
const showDegradedTree = result.error && visibleTree.length > 0;
|
|
710
|
+
const showEmpty = !result.loading && visibleTree.length === 0 && !draftCreate;
|
|
600
711
|
// Retry lives next to the state it explains (the degraded/empty notice), so do
|
|
601
712
|
// not render a second toolbar retry for the same failure.
|
|
602
713
|
const showToolbar = supportsMutation || result.loading;
|
|
@@ -800,6 +911,24 @@ export function FileBrowser({
|
|
|
800
911
|
if (index >= 0) vlistRef.current?.scrollToIndex(index);
|
|
801
912
|
}, [cursor, renderItems]);
|
|
802
913
|
|
|
914
|
+
useEffect(() => {
|
|
915
|
+
if (!revealRequest) return;
|
|
916
|
+
const index = renderItems.findIndex(
|
|
917
|
+
(item) => item.type === "node" && item.node.path === revealRequest.path,
|
|
918
|
+
);
|
|
919
|
+
if (index < 0) return;
|
|
920
|
+
if (usesVirtualTree) {
|
|
921
|
+
vlistRef.current?.scrollToIndex(index);
|
|
922
|
+
} else {
|
|
923
|
+
document.getElementById(`${treeId}-item-${index}`)?.scrollIntoView?.({ block: "nearest" });
|
|
924
|
+
}
|
|
925
|
+
setRevealRequest((current) =>
|
|
926
|
+
current?.path === revealRequest.path && current.requestId === revealRequest.requestId
|
|
927
|
+
? null
|
|
928
|
+
: current,
|
|
929
|
+
);
|
|
930
|
+
}, [renderItems, revealRequest, treeId, usesVirtualTree]);
|
|
931
|
+
|
|
803
932
|
return (
|
|
804
933
|
<div className={cn("flex min-h-0 min-w-0 flex-col", className)}>
|
|
805
934
|
{showToolbar && (
|
|
@@ -819,7 +948,7 @@ export function FileBrowser({
|
|
|
819
948
|
<ToolbarButton
|
|
820
949
|
label="Rename"
|
|
821
950
|
onClick={() => {
|
|
822
|
-
const node = cursor ? findNode(
|
|
951
|
+
const node = cursor ? findNode(visibleTree, cursor) : undefined;
|
|
823
952
|
if (node) startRename(node);
|
|
824
953
|
}}
|
|
825
954
|
disabled={busy || !cursor}
|
|
@@ -829,7 +958,7 @@ export function FileBrowser({
|
|
|
829
958
|
<ToolbarButton
|
|
830
959
|
label="Delete"
|
|
831
960
|
onClick={(event) => {
|
|
832
|
-
const node = cursor ? findNode(
|
|
961
|
+
const node = cursor ? findNode(visibleTree, cursor) : undefined;
|
|
833
962
|
if (node) void runDelete(node, event.currentTarget);
|
|
834
963
|
}}
|
|
835
964
|
disabled={busy || !cursor}
|
|
@@ -1121,7 +1250,7 @@ function DeleteDialog({
|
|
|
1121
1250
|
closeIntentRef.current = "confirm";
|
|
1122
1251
|
}}
|
|
1123
1252
|
disabled={busy}
|
|
1124
|
-
className="min-h-9 rounded-og-md bg-og-
|
|
1253
|
+
className="min-h-9 rounded-og-md bg-og-danger-fill px-3 text-og-sm font-semibold text-og-danger-fg shadow-sm hover:brightness-110 disabled:opacity-50 pointer-coarse:min-h-11"
|
|
1125
1254
|
>
|
|
1126
1255
|
Delete permanently
|
|
1127
1256
|
</button>
|
|
@@ -1301,9 +1430,8 @@ function ContextMenu({
|
|
|
1301
1430
|
onClick();
|
|
1302
1431
|
}}
|
|
1303
1432
|
className={cn(
|
|
1304
|
-
|
|
1305
|
-
"
|
|
1306
|
-
danger ? "text-og-status-failed" : "text-og-fg",
|
|
1433
|
+
MENU_BUTTON_CLASS,
|
|
1434
|
+
danger && "text-og-status-failed [&_svg]:text-og-status-failed!",
|
|
1307
1435
|
)}
|
|
1308
1436
|
>
|
|
1309
1437
|
{icon}
|
|
@@ -1319,21 +1447,17 @@ function ContextMenu({
|
|
|
1319
1447
|
onKeyDown={onKeyDown}
|
|
1320
1448
|
onClick={(e) => e.stopPropagation()}
|
|
1321
1449
|
style={{ left, top }}
|
|
1322
|
-
className={cn(
|
|
1323
|
-
"fixed z-50 min-w-[160px] overflow-hidden rounded-md border py-1 shadow-lg",
|
|
1324
|
-
"border-og-border",
|
|
1325
|
-
"bg-og-surface-1",
|
|
1326
|
-
)}
|
|
1450
|
+
className={cn(MENU_SURFACE_CLASS, "fixed z-50 min-w-[180px] overflow-hidden")}
|
|
1327
1451
|
>
|
|
1328
1452
|
{isDir && (
|
|
1329
1453
|
<>
|
|
1330
|
-
{item("New file", <FilePlusIcon
|
|
1331
|
-
{item("New folder", <FolderPlusIcon
|
|
1332
|
-
<div role="separator" className=
|
|
1454
|
+
{item("New file", <FilePlusIcon />, onNewFile)}
|
|
1455
|
+
{item("New folder", <FolderPlusIcon />, onNewFolder)}
|
|
1456
|
+
<div role="separator" className={MENU_SEPARATOR_CLASS} />
|
|
1333
1457
|
</>
|
|
1334
1458
|
)}
|
|
1335
|
-
{item("Rename", <PencilIcon
|
|
1336
|
-
{item("Delete", <Trash2Icon
|
|
1459
|
+
{item("Rename", <PencilIcon />, onRename)}
|
|
1460
|
+
{item("Delete", <Trash2Icon />, onDelete, true)}
|
|
1337
1461
|
</div>
|
|
1338
1462
|
);
|
|
1339
1463
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { deriveSessionDisplayTitle, type Session } from "@opengeni/sdk";
|
|
2
|
+
import { modelDisplayName } from "@opengeni/sdk/model-display";
|
|
2
3
|
import { cn } from "../lib/cn";
|
|
3
|
-
import { formatRelativeTime
|
|
4
|
+
import { formatRelativeTime } from "../lib/format";
|
|
4
5
|
import { SessionStatus } from "./session-status";
|
|
5
6
|
|
|
7
|
+
const SESSION_METADATA_TITLE_KEYS = ["title", "name"] as const;
|
|
8
|
+
|
|
6
9
|
export type FleetTileProps = {
|
|
7
10
|
session: Session;
|
|
8
|
-
/** Overrides the derived title (
|
|
11
|
+
/** Overrides the derived title (durable title, metadata, prompt preview, or safe fallback). */
|
|
9
12
|
title?: string | undefined;
|
|
10
13
|
/** Extra line under the title — e.g. "drift check" or the worker's task. */
|
|
11
14
|
subtitle?: string | undefined;
|
|
@@ -15,18 +18,7 @@ export type FleetTileProps = {
|
|
|
15
18
|
|
|
16
19
|
/** Best-effort display title for a session. */
|
|
17
20
|
export function sessionDisplayTitle(session: Session): string {
|
|
18
|
-
|
|
19
|
-
// initial-message fallback.
|
|
20
|
-
if (typeof session.title === "string" && session.title.trim().length > 0) {
|
|
21
|
-
return session.title;
|
|
22
|
-
}
|
|
23
|
-
for (const key of ["title", "name"] as const) {
|
|
24
|
-
const value = session.metadata[key];
|
|
25
|
-
if (typeof value === "string" && value.trim().length > 0) {
|
|
26
|
-
return value;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return truncate(session.initialMessage, 100) || session.id.slice(0, 8);
|
|
21
|
+
return deriveSessionDisplayTitle(session, { metadataKeys: SESSION_METADATA_TITLE_KEYS });
|
|
30
22
|
}
|
|
31
23
|
|
|
32
24
|
/**
|
|
@@ -76,7 +68,7 @@ export function FleetTile({ session, title, subtitle, onOpen, className }: Fleet
|
|
|
76
68
|
<span className="mt-auto flex w-full items-center gap-2 text-og-xs text-og-fg-subtle">
|
|
77
69
|
<span className="font-og-mono">{session.id.slice(0, 8)}</span>
|
|
78
70
|
<span aria-hidden>·</span>
|
|
79
|
-
<span className="truncate">{session.model}</span>
|
|
71
|
+
<span className="truncate">{modelDisplayName(session.model)}</span>
|
|
80
72
|
<span className="ml-auto shrink-0" title={session.updatedAt}>
|
|
81
73
|
{formatRelativeTime(session.updatedAt)}
|
|
82
74
|
</span>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { GeneratedVideoReceipt, VideoArtifactPlaybackSource } from "@opengeni/sdk";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import { cn } from "../lib/cn";
|
|
4
|
+
import { useErrorMessage } from "../lib/error-message";
|
|
4
5
|
import type { VideoArtifactPlaybackLoader } from "../timeline";
|
|
5
6
|
|
|
6
7
|
export type GeneratedVideoPlayerProps = {
|
|
@@ -22,6 +23,7 @@ export function GeneratedVideoPlayer({
|
|
|
22
23
|
className,
|
|
23
24
|
label = "Generated video",
|
|
24
25
|
}: GeneratedVideoPlayerProps) {
|
|
26
|
+
const formatError = useErrorMessage();
|
|
25
27
|
const [retry, setRetry] = useState(0);
|
|
26
28
|
const [state, setState] = useState<SourceState>({ kind: "loading" });
|
|
27
29
|
|
|
@@ -36,12 +38,12 @@ export function GeneratedVideoPlayer({
|
|
|
36
38
|
if (controller.signal.aborted) return;
|
|
37
39
|
setState({
|
|
38
40
|
kind: "error",
|
|
39
|
-
message: error
|
|
41
|
+
message: formatError(error),
|
|
40
42
|
});
|
|
41
43
|
},
|
|
42
44
|
);
|
|
43
45
|
return () => controller.abort();
|
|
44
|
-
}, [loadPlaybackSource, receipt.artifact.artifactId, retry]);
|
|
46
|
+
}, [loadPlaybackSource, receipt.artifact.artifactId, retry, formatError]);
|
|
45
47
|
|
|
46
48
|
if (state.kind === "loading") {
|
|
47
49
|
return (
|