@opengeni/react 1.0.1 → 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 +651 -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-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 +6 -3
- package/dist/realtime.js +133 -74
- 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 +133 -46
- 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
|
@@ -163,6 +163,7 @@ export function useVoiceInput({
|
|
|
163
163
|
const automaticRetryAttemptRef = useRef(0);
|
|
164
164
|
const ownerHeartbeatTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
165
165
|
const controllerRef = useRef<AbortController | null>(null);
|
|
166
|
+
const disabledRef = useRef(disabled);
|
|
166
167
|
const valueRef = useRef(value);
|
|
167
168
|
const storeRef = useRef<VoiceRecordingStore | null>(null);
|
|
168
169
|
const storePromiseRef = useRef<Promise<VoiceRecordingStore> | null>(null);
|
|
@@ -176,6 +177,7 @@ export function useVoiceInput({
|
|
|
176
177
|
const statusRef = useRef(status);
|
|
177
178
|
valueRef.current = value;
|
|
178
179
|
statusRef.current = status;
|
|
180
|
+
disabledRef.current = disabled;
|
|
179
181
|
workspaceIdRef.current = workspaceId;
|
|
180
182
|
|
|
181
183
|
const ensureOwnerId = useCallback(async (): Promise<string> => {
|
|
@@ -468,6 +470,14 @@ export function useVoiceInput({
|
|
|
468
470
|
return;
|
|
469
471
|
}
|
|
470
472
|
|
|
473
|
+
// Session creation can disable the composer while a recording is
|
|
474
|
+
// transcribing. Keep the durable transcript for explicit insertion
|
|
475
|
+
// later; never append text after Send captured its visible snapshot.
|
|
476
|
+
if (disabledRef.current) {
|
|
477
|
+
setStatus("transcript-ready");
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
|
|
471
481
|
const next = appendFinalTranscript(valueRef.current, response.text);
|
|
472
482
|
if (next !== valueRef.current) {
|
|
473
483
|
valueRef.current = next;
|
|
@@ -944,6 +954,7 @@ export function useVoiceInput({
|
|
|
944
954
|
const insertSavedTranscript = useCallback(async (): Promise<void> => {
|
|
945
955
|
const manifest = manifestRef.current;
|
|
946
956
|
if (
|
|
957
|
+
disabledRef.current ||
|
|
947
958
|
!manifest ||
|
|
948
959
|
manifest.workspaceId !== workspaceId ||
|
|
949
960
|
manifest.finalizationState !== "transcript-ready" ||
|
|
@@ -955,7 +966,7 @@ export function useVoiceInput({
|
|
|
955
966
|
controllerRef.current?.abort();
|
|
956
967
|
controllerRef.current = null;
|
|
957
968
|
const store = await ensureStore();
|
|
958
|
-
if (generation !== generationRef.current) return;
|
|
969
|
+
if (generation !== generationRef.current || disabledRef.current) return;
|
|
959
970
|
const next = appendFinalTranscript(valueRef.current, manifest.transcriptText);
|
|
960
971
|
if (next !== valueRef.current) {
|
|
961
972
|
valueRef.current = next;
|
|
@@ -194,8 +194,9 @@ export function useWorkspaceCapture(
|
|
|
194
194
|
return;
|
|
195
195
|
}
|
|
196
196
|
setDegradedReason(null);
|
|
197
|
-
//
|
|
198
|
-
//
|
|
197
|
+
// Expose metadata while a large signed manifest downloads. Consumers
|
|
198
|
+
// must distinguish this pending count from a resolved capture; zero
|
|
199
|
+
// working-tree files can still have committed-only branch changes.
|
|
199
200
|
setFileCount(res.stats.fileCount);
|
|
200
201
|
// Exactly one of manifest / manifestUrl is non-null (M2 contract). The inline
|
|
201
202
|
// manifest is the <200ms common case; a >2MB manifest is a signed URL hop.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { FileSystemRouteIdentity } from "@opengeni/sdk";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
3
|
import { useOpenGeni, type ClientOverride } from "../provider";
|
|
3
4
|
import { sandboxAcceptsLiveIo } from "../lib/sandbox-liveness";
|
|
4
5
|
|
|
@@ -39,6 +40,9 @@ export type UseWorkspaceEditOptions = ClientOverride & {
|
|
|
39
40
|
path?: string | null | undefined;
|
|
40
41
|
/** The capture-served content loaded into the editor — the flush base (C2). */
|
|
41
42
|
baseContent?: string | null | undefined;
|
|
43
|
+
/** Exact capability identity for the selected filesystem route. A route/root
|
|
44
|
+
* change discards the buffered edit and makes stale flushes fail retryably. */
|
|
45
|
+
route?: FileSystemRouteIdentity | undefined;
|
|
42
46
|
/** `capabilities.liveness` — "warm" | "draining" | "cold". Drives the flush. */
|
|
43
47
|
liveness?: string | undefined;
|
|
44
48
|
/** True while the host is actively warming the box (attach in flight, not warm
|
|
@@ -95,9 +99,18 @@ export function useWorkspaceEdit(
|
|
|
95
99
|
const { client, workspaceId } = useOpenGeni(options);
|
|
96
100
|
const path = options.path ?? null;
|
|
97
101
|
const baseContent = options.baseContent ?? null;
|
|
102
|
+
const routeEpoch = options.route?.epoch;
|
|
103
|
+
const routeRoot = options.route?.root;
|
|
104
|
+
const route = useMemo<FileSystemRouteIdentity | undefined>(
|
|
105
|
+
() =>
|
|
106
|
+
routeEpoch !== undefined && routeRoot !== undefined
|
|
107
|
+
? { epoch: routeEpoch, root: routeRoot }
|
|
108
|
+
: undefined,
|
|
109
|
+
[routeEpoch, routeRoot],
|
|
110
|
+
);
|
|
98
111
|
const live = isLive(options.liveness);
|
|
99
112
|
const offline = options.offline === true;
|
|
100
|
-
const identityKey = `${workspaceId}\u0000${sessionId ?? ""}\u0000${path ?? ""}`;
|
|
113
|
+
const identityKey = `${workspaceId}\u0000${sessionId ?? ""}\u0000${path ?? ""}\u0000${routeEpoch ?? ""}\u0000${routeRoot ?? ""}`;
|
|
101
114
|
|
|
102
115
|
const [buffer, setBuffer] = useState<string | null>(null);
|
|
103
116
|
const [wantsWarm, setWantsWarm] = useState(false);
|
|
@@ -178,7 +191,7 @@ export function useWorkspaceEdit(
|
|
|
178
191
|
const liveRead = await client.fsRead(
|
|
179
192
|
workspaceId,
|
|
180
193
|
sessionId,
|
|
181
|
-
{ path },
|
|
194
|
+
{ path, ...(route ? { route } : {}) },
|
|
182
195
|
{ signal: readAbort.signal },
|
|
183
196
|
);
|
|
184
197
|
if (readAbortRef.current === readAbort) readAbortRef.current = null;
|
|
@@ -190,7 +203,12 @@ export function useWorkspaceEdit(
|
|
|
190
203
|
return;
|
|
191
204
|
}
|
|
192
205
|
}
|
|
193
|
-
await client.fsWrite(workspaceId, sessionId, {
|
|
206
|
+
await client.fsWrite(workspaceId, sessionId, {
|
|
207
|
+
path,
|
|
208
|
+
content,
|
|
209
|
+
overwrite: true,
|
|
210
|
+
...(route ? { route } : {}),
|
|
211
|
+
});
|
|
194
212
|
if (identityGenerationRef.current !== identityGeneration) return;
|
|
195
213
|
setConflict(null);
|
|
196
214
|
setFlush("flushed");
|
|
@@ -207,7 +225,7 @@ export function useWorkspaceEdit(
|
|
|
207
225
|
}
|
|
208
226
|
}
|
|
209
227
|
},
|
|
210
|
-
[client, workspaceId, sessionId, path, baseContent, stateIdentity, identityKey],
|
|
228
|
+
[client, workspaceId, sessionId, path, baseContent, route, stateIdentity, identityKey],
|
|
211
229
|
);
|
|
212
230
|
|
|
213
231
|
// Auto-flush once the box is warm and a buffer is pending (the wake completed).
|
|
@@ -1,54 +1,96 @@
|
|
|
1
|
-
import type { Session } from "@opengeni/sdk";
|
|
1
|
+
import type { Session, SessionListEntry, SessionListTotals } from "@opengeni/sdk";
|
|
2
2
|
import { useCallback, useEffect, useRef } from "react";
|
|
3
3
|
import { useOpenGeni, type ClientOverride } from "../provider";
|
|
4
4
|
import { usePolledValue } from "./internal";
|
|
5
5
|
|
|
6
6
|
export type UseWorkspaceSessionsOptions = ClientOverride & {
|
|
7
|
+
includeTotals?: boolean | undefined;
|
|
8
|
+
needsYouOnly?: boolean | undefined;
|
|
9
|
+
/** Compact list records; detail reads remain full sessions. */
|
|
10
|
+
projection?: "summary" | undefined;
|
|
7
11
|
limit?: number | undefined;
|
|
8
12
|
parentSessionId?: string | null | undefined;
|
|
9
13
|
cursor?: string | undefined;
|
|
10
14
|
search?: string | undefined;
|
|
11
15
|
/** Return only the complete personal pinned projection. */
|
|
12
16
|
pinsOnly?: boolean | undefined;
|
|
17
|
+
/** Skip pinned details when the pinned section is loaded separately. */
|
|
18
|
+
includePinned?: boolean | undefined;
|
|
19
|
+
archivedOnly?: boolean | undefined;
|
|
20
|
+
sortBy?: "updatedAt" | "createdAt" | "name" | undefined;
|
|
21
|
+
archiveStatus?: "active" | "archived" | "all" | undefined;
|
|
13
22
|
/** Refresh interval (ms) for fleet/manager views. Off by default. */
|
|
14
23
|
pollIntervalMs?: number | undefined;
|
|
15
24
|
enabled?: boolean | undefined;
|
|
25
|
+
/** Optional shared causal clock invoked when each network read starts. */
|
|
26
|
+
beginRead?: (() => number) | undefined;
|
|
16
27
|
};
|
|
17
28
|
|
|
18
|
-
export type UseWorkspaceSessionsResult = {
|
|
29
|
+
export type UseWorkspaceSessionsResult<T extends Session | SessionListEntry = Session> = {
|
|
19
30
|
/**
|
|
20
31
|
* All visible rows, with pins first. This preserves the pre-pinning hook
|
|
21
32
|
* contract for consumers that only read `sessions`.
|
|
22
33
|
*/
|
|
23
|
-
sessions:
|
|
34
|
+
sessions: T[];
|
|
24
35
|
/** The complete personal pinned section, also present in `sessions`. */
|
|
25
|
-
pinned:
|
|
36
|
+
pinned: T[];
|
|
26
37
|
/** True when the server omitted older pins from its bounded pinned section. */
|
|
27
38
|
pinnedTruncated: boolean;
|
|
39
|
+
totals: SessionListTotals | null;
|
|
28
40
|
nextCursor: string | null;
|
|
29
41
|
loading: boolean;
|
|
30
42
|
error: Error | null;
|
|
43
|
+
/** Monotonic revision of accepted authoritative list-page reads. */
|
|
44
|
+
readRevision: number;
|
|
45
|
+
/** Causal generation captured when the accepted network read started. */
|
|
46
|
+
readGeneration: number;
|
|
31
47
|
refresh: () => Promise<void>;
|
|
32
48
|
};
|
|
33
49
|
|
|
34
50
|
/** List the workspace's sessions — the data behind fleet and manager views. */
|
|
51
|
+
export function useWorkspaceSessions(
|
|
52
|
+
options: UseWorkspaceSessionsOptions & { projection: "summary" },
|
|
53
|
+
): UseWorkspaceSessionsResult<SessionListEntry>;
|
|
54
|
+
export function useWorkspaceSessions(
|
|
55
|
+
options?: UseWorkspaceSessionsOptions & { projection?: undefined },
|
|
56
|
+
): UseWorkspaceSessionsResult;
|
|
57
|
+
export function useWorkspaceSessions(
|
|
58
|
+
options: UseWorkspaceSessionsOptions,
|
|
59
|
+
): UseWorkspaceSessionsResult<Session | SessionListEntry>;
|
|
35
60
|
export function useWorkspaceSessions(
|
|
36
61
|
options: UseWorkspaceSessionsOptions = {},
|
|
37
|
-
): UseWorkspaceSessionsResult {
|
|
62
|
+
): UseWorkspaceSessionsResult<Session | SessionListEntry> {
|
|
38
63
|
const { client, workspaceId } = useOpenGeni(options);
|
|
64
|
+
const projection = options.projection;
|
|
65
|
+
const includeTotals = options.includeTotals;
|
|
66
|
+
const needsYouOnly = options.needsYouOnly;
|
|
39
67
|
const limit = options.limit;
|
|
40
68
|
const parentSessionId = options.parentSessionId;
|
|
41
69
|
const cursor = options.cursor;
|
|
42
70
|
const search = options.search;
|
|
43
71
|
const pinsOnly = options.pinsOnly;
|
|
72
|
+
const includePinned = options.includePinned;
|
|
73
|
+
const archivedOnly = options.archivedOnly;
|
|
74
|
+
const sortBy = options.sortBy;
|
|
75
|
+
const archiveStatus = options.archiveStatus;
|
|
44
76
|
const enabled = options.enabled ?? true;
|
|
77
|
+
const nextReadRevision = useRef(0);
|
|
78
|
+
const nextReadGeneration = useRef(0);
|
|
79
|
+
const beginRead = options.beginRead;
|
|
45
80
|
const queryKey = [
|
|
46
81
|
workspaceId,
|
|
82
|
+
projection ?? "full",
|
|
83
|
+
includeTotals ? "totals" : "",
|
|
84
|
+
needsYouOnly ? "needs-you" : "",
|
|
47
85
|
limit ?? "",
|
|
48
86
|
parentSessionId === null ? "null" : (parentSessionId ?? ""),
|
|
49
87
|
cursor ?? "",
|
|
50
88
|
search ?? "",
|
|
51
89
|
pinsOnly ? "1" : "",
|
|
90
|
+
includePinned === false ? "no-pins" : "",
|
|
91
|
+
archivedOnly ? "archived" : "active",
|
|
92
|
+
sortBy ?? "",
|
|
93
|
+
archiveStatus ?? "",
|
|
52
94
|
].join("\u0000");
|
|
53
95
|
const previousQueryKey = useRef(queryKey);
|
|
54
96
|
const queryKeyTransition = previousQueryKey.current !== queryKey;
|
|
@@ -56,17 +98,60 @@ export function useWorkspaceSessions(
|
|
|
56
98
|
previousQueryKey.current = queryKey;
|
|
57
99
|
}, [queryKey]);
|
|
58
100
|
const load = useCallback(
|
|
59
|
-
async () =>
|
|
60
|
-
|
|
61
|
-
|
|
101
|
+
async (signal?: AbortSignal) => {
|
|
102
|
+
const readGeneration = beginRead?.() ?? ++nextReadGeneration.current;
|
|
103
|
+
const query = {
|
|
104
|
+
...(includeTotals ? { includeTotals: true } : {}),
|
|
105
|
+
...(needsYouOnly ? { needsYouOnly: true } : {}),
|
|
62
106
|
...(limit !== undefined ? { limit } : {}),
|
|
63
107
|
...(parentSessionId !== undefined ? { parentSessionId } : {}),
|
|
64
108
|
...(cursor !== undefined ? { cursor } : {}),
|
|
65
109
|
...(search !== undefined ? { search } : {}),
|
|
66
110
|
...(pinsOnly ? { pinsOnly: true } : {}),
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
111
|
+
...(includePinned === false ? { includePinned: false } : {}),
|
|
112
|
+
...(archivedOnly ? { archivedOnly: true } : {}),
|
|
113
|
+
...(sortBy ? { sortBy } : {}),
|
|
114
|
+
...(archiveStatus ? { archiveStatus } : {}),
|
|
115
|
+
signal,
|
|
116
|
+
};
|
|
117
|
+
const page =
|
|
118
|
+
projection === "summary"
|
|
119
|
+
? client.listSessionSummaryPage
|
|
120
|
+
? await client.listSessionSummaryPage(workspaceId, query)
|
|
121
|
+
: await client.listSessionPage(workspaceId, query).then(async (full) => {
|
|
122
|
+
const { sessionListEntry } = await import("@opengeni/sdk/session-list-entries");
|
|
123
|
+
return {
|
|
124
|
+
...full,
|
|
125
|
+
pinned: full.pinned.map(sessionListEntry),
|
|
126
|
+
sessions: full.sessions.map(sessionListEntry),
|
|
127
|
+
};
|
|
128
|
+
})
|
|
129
|
+
: await client.listSessionPage(workspaceId, query);
|
|
130
|
+
return {
|
|
131
|
+
queryKey,
|
|
132
|
+
page,
|
|
133
|
+
revision: ++nextReadRevision.current,
|
|
134
|
+
readGeneration,
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
[
|
|
138
|
+
beginRead,
|
|
139
|
+
client,
|
|
140
|
+
workspaceId,
|
|
141
|
+
projection,
|
|
142
|
+
includeTotals,
|
|
143
|
+
needsYouOnly,
|
|
144
|
+
limit,
|
|
145
|
+
parentSessionId,
|
|
146
|
+
cursor,
|
|
147
|
+
search,
|
|
148
|
+
pinsOnly,
|
|
149
|
+
includePinned,
|
|
150
|
+
archivedOnly,
|
|
151
|
+
sortBy,
|
|
152
|
+
archiveStatus,
|
|
153
|
+
queryKey,
|
|
154
|
+
],
|
|
70
155
|
);
|
|
71
156
|
const state = usePolledValue(load, {
|
|
72
157
|
pollIntervalMs: options.pollIntervalMs,
|
|
@@ -85,6 +170,7 @@ export function useWorkspaceSessions(
|
|
|
85
170
|
sessions: [...pinned, ...ordinary],
|
|
86
171
|
pinned,
|
|
87
172
|
pinnedTruncated: page?.pinnedTruncated ?? false,
|
|
173
|
+
totals: page?.totals ?? null,
|
|
88
174
|
nextCursor: page?.nextCursor ?? null,
|
|
89
175
|
// `usePolledValue` clears the old data and starts the new request in an
|
|
90
176
|
// effect. During that query-key transition render, its old loading flag
|
|
@@ -96,6 +182,8 @@ export function useWorkspaceSessions(
|
|
|
96
182
|
queryKeyTransition ||
|
|
97
183
|
(state.data !== null && state.data.queryKey !== queryKey)),
|
|
98
184
|
error: state.error,
|
|
185
|
+
readRevision: page ? (state.data?.revision ?? 0) : 0,
|
|
186
|
+
readGeneration: page ? (state.data?.readGeneration ?? 0) : 0,
|
|
99
187
|
refresh: state.refresh,
|
|
100
188
|
};
|
|
101
189
|
}
|
package/src/human-input.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HumanInputQuestion, SessionEvent } from "@opengeni/sdk";
|
|
1
|
+
import type { HumanInputQuestion, SessionEvent, SessionHumanInputRequest } from "@opengeni/sdk";
|
|
2
2
|
|
|
3
3
|
/** Minimal actionable request shape available from the durable event log. */
|
|
4
4
|
export type PendingHumanInputRequest = {
|
|
@@ -9,6 +9,17 @@ export type PendingHumanInputRequest = {
|
|
|
9
9
|
expiresAt: string | null;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
/** A pending row stops being actionable at its durable deadline, even before refresh. */
|
|
13
|
+
export function isActionableHumanInputRequest(
|
|
14
|
+
request: Pick<SessionHumanInputRequest, "status" | "expiresAt">,
|
|
15
|
+
nowMs = Date.now(),
|
|
16
|
+
): boolean {
|
|
17
|
+
if (request.status !== "pending") return false;
|
|
18
|
+
if (!request.expiresAt) return true;
|
|
19
|
+
const deadline = Date.parse(request.expiresAt);
|
|
20
|
+
return Number.isFinite(deadline) && deadline > nowMs;
|
|
21
|
+
}
|
|
22
|
+
|
|
12
23
|
/** Parse one generic `session.humanInput.requested` event defensively. */
|
|
13
24
|
export function humanInputRequestFromEvent(
|
|
14
25
|
event: Pick<SessionEvent, "type" | "payload" | "turnId">,
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import type { ExternalIdentityLink, ExternalIdentityLinkPage } from "@opengeni/sdk";
|
|
3
|
+
|
|
4
|
+
export type IdentityLinkAccountsClient = {
|
|
5
|
+
listIdentityLinks(workspaceId: string, cursor?: string): Promise<ExternalIdentityLinkPage>;
|
|
6
|
+
revokeIdentityLink(
|
|
7
|
+
workspaceId: string,
|
|
8
|
+
linkId: string,
|
|
9
|
+
expectedRevision: number,
|
|
10
|
+
): Promise<ExternalIdentityLink>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** Participant-scoped inventory. Revocation never deletes native work or merges
|
|
14
|
+
* identities. The caller remounts this component when the signed-in user changes. */
|
|
15
|
+
export function IdentityLinkAccounts({
|
|
16
|
+
client,
|
|
17
|
+
workspaceId,
|
|
18
|
+
}: {
|
|
19
|
+
client: IdentityLinkAccountsClient;
|
|
20
|
+
workspaceId: string;
|
|
21
|
+
}) {
|
|
22
|
+
const [links, setLinks] = useState<ExternalIdentityLink[]>([]);
|
|
23
|
+
const [cursor, setCursor] = useState<string | null>(null);
|
|
24
|
+
const [busy, setBusy] = useState(true);
|
|
25
|
+
const [error, setError] = useState(false);
|
|
26
|
+
const [revision, setRevision] = useState(0);
|
|
27
|
+
const generation = useRef(0);
|
|
28
|
+
const inFlight = useRef(false);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const current = ++generation.current;
|
|
31
|
+
inFlight.current = true;
|
|
32
|
+
setLinks([]);
|
|
33
|
+
setCursor(null);
|
|
34
|
+
setBusy(true);
|
|
35
|
+
setError(false);
|
|
36
|
+
void client
|
|
37
|
+
.listIdentityLinks(workspaceId)
|
|
38
|
+
.then(
|
|
39
|
+
(page) => {
|
|
40
|
+
if (current !== generation.current) return;
|
|
41
|
+
setLinks(page.links);
|
|
42
|
+
setCursor(page.nextCursor);
|
|
43
|
+
},
|
|
44
|
+
() => {
|
|
45
|
+
if (current === generation.current) setError(true);
|
|
46
|
+
},
|
|
47
|
+
)
|
|
48
|
+
.finally(() => {
|
|
49
|
+
if (current === generation.current) {
|
|
50
|
+
inFlight.current = false;
|
|
51
|
+
setBusy(false);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
return () => {
|
|
55
|
+
// Invalidate live async work, rather than cleaning up a captured DOM node.
|
|
56
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
+
generation.current++;
|
|
58
|
+
};
|
|
59
|
+
}, [client, workspaceId, revision]);
|
|
60
|
+
|
|
61
|
+
async function act(link?: ExternalIdentityLink) {
|
|
62
|
+
if (inFlight.current || (!link && !cursor)) return;
|
|
63
|
+
const current = generation.current;
|
|
64
|
+
inFlight.current = true;
|
|
65
|
+
setBusy(true);
|
|
66
|
+
setError(false);
|
|
67
|
+
try {
|
|
68
|
+
if (link) {
|
|
69
|
+
const updated = await client.revokeIdentityLink(workspaceId, link.id, link.revision);
|
|
70
|
+
if (current === generation.current)
|
|
71
|
+
setLinks((values) =>
|
|
72
|
+
values.map((value) => (value.id === updated.id ? { ...value, ...updated } : value)),
|
|
73
|
+
);
|
|
74
|
+
} else {
|
|
75
|
+
const page = await client.listIdentityLinks(workspaceId, cursor!);
|
|
76
|
+
if (current === generation.current) {
|
|
77
|
+
setLinks((values) => [
|
|
78
|
+
...new Map([...values, ...page.links].map((value) => [value.id, value])).values(),
|
|
79
|
+
]);
|
|
80
|
+
setCursor(page.nextCursor);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
} catch {
|
|
84
|
+
if (current === generation.current) setError(true);
|
|
85
|
+
} finally {
|
|
86
|
+
if (current === generation.current) {
|
|
87
|
+
inFlight.current = false;
|
|
88
|
+
setBusy(false);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return (
|
|
93
|
+
<section
|
|
94
|
+
className="og-connect og-identity-link"
|
|
95
|
+
aria-label="Linked product access"
|
|
96
|
+
aria-busy={busy}
|
|
97
|
+
>
|
|
98
|
+
<h2>Linked product access</h2>
|
|
99
|
+
<p>
|
|
100
|
+
Manage products allowed to act as your account in this organization. Revoking a link stops
|
|
101
|
+
future linked access; it does not delete your work or undo an operation already started.
|
|
102
|
+
</p>
|
|
103
|
+
{/* The links sit in one card under the heading, like a settings section;
|
|
104
|
+
the empty and loading lines are rows of that card. */}
|
|
105
|
+
<div className="og-identity-link-card">
|
|
106
|
+
{error && (
|
|
107
|
+
<div role="alert">
|
|
108
|
+
Could not update account links. Reload to see current access.
|
|
109
|
+
<button type="button" disabled={busy} onClick={() => setRevision((value) => value + 1)}>
|
|
110
|
+
Reload links
|
|
111
|
+
</button>
|
|
112
|
+
</div>
|
|
113
|
+
)}
|
|
114
|
+
{busy && <p role="status">Loading account links…</p>}
|
|
115
|
+
{!busy && !error && links.length === 0 && (
|
|
116
|
+
<p>No products have linked access to this account.</p>
|
|
117
|
+
)}
|
|
118
|
+
<ul>
|
|
119
|
+
{links.map((link) => (
|
|
120
|
+
<li key={link.id}>
|
|
121
|
+
<p>
|
|
122
|
+
{link.externalIdentity?.source || "Product identity"}{" "}
|
|
123
|
+
<code>{link.externalIdentity?.externalId ?? link.externalIdentityId}</code>
|
|
124
|
+
</p>
|
|
125
|
+
<p>
|
|
126
|
+
Status: {link.status}.{" "}
|
|
127
|
+
{link.expiresAt
|
|
128
|
+
? `Expires ${new Date(link.expiresAt).toLocaleString()}.`
|
|
129
|
+
: "No automatic expiry."}
|
|
130
|
+
</p>
|
|
131
|
+
<p>{link.permissions.join(", ")}</p>
|
|
132
|
+
{(link.status === "active" || link.status === "pending") && (
|
|
133
|
+
<button type="button" disabled={busy} onClick={() => void act(link)}>
|
|
134
|
+
Revoke access
|
|
135
|
+
</button>
|
|
136
|
+
)}
|
|
137
|
+
</li>
|
|
138
|
+
))}
|
|
139
|
+
</ul>
|
|
140
|
+
{cursor && (
|
|
141
|
+
<button type="button" disabled={busy} onClick={() => void act()}>
|
|
142
|
+
Load more links
|
|
143
|
+
</button>
|
|
144
|
+
)}
|
|
145
|
+
</div>
|
|
146
|
+
</section>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import type {
|
|
3
|
+
ExternalIdentityLink,
|
|
4
|
+
ConfirmExternalIdentityLinkRequest,
|
|
5
|
+
ExternalIdentityLinkPreview,
|
|
6
|
+
} from "@opengeni/sdk";
|
|
7
|
+
|
|
8
|
+
export type IdentityLinkClient = {
|
|
9
|
+
previewIdentityLink(
|
|
10
|
+
workspaceId: string,
|
|
11
|
+
linkId: string,
|
|
12
|
+
challenge: string,
|
|
13
|
+
): Promise<ExternalIdentityLinkPreview>;
|
|
14
|
+
confirmIdentityLink(
|
|
15
|
+
workspaceId: string,
|
|
16
|
+
linkId: string,
|
|
17
|
+
input: ConfirmExternalIdentityLinkRequest,
|
|
18
|
+
): Promise<ExternalIdentityLink>;
|
|
19
|
+
revokeIdentityLink(
|
|
20
|
+
workspaceId: string,
|
|
21
|
+
linkId: string,
|
|
22
|
+
expectedRevision: number,
|
|
23
|
+
): Promise<ExternalIdentityLink>;
|
|
24
|
+
};
|
|
25
|
+
export type IdentityLinkConsentProps = {
|
|
26
|
+
client: IdentityLinkClient;
|
|
27
|
+
workspaceId: string;
|
|
28
|
+
linkId: string;
|
|
29
|
+
challenge: string;
|
|
30
|
+
/** Host label is explanatory, never proof of the requesting application. */
|
|
31
|
+
className?: string;
|
|
32
|
+
onComplete?: (link: ExternalIdentityLink) => void;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Optional native-login consent. Ordinary Connect does not use this surface.
|
|
36
|
+
* Permission choices only narrow the server's request; no automatic approval. */
|
|
37
|
+
export function IdentityLinkConsent({
|
|
38
|
+
client,
|
|
39
|
+
workspaceId,
|
|
40
|
+
linkId,
|
|
41
|
+
challenge,
|
|
42
|
+
className,
|
|
43
|
+
onComplete,
|
|
44
|
+
}: IdentityLinkConsentProps) {
|
|
45
|
+
const [link, setLink] = useState<ExternalIdentityLink | null>(null);
|
|
46
|
+
const [preview, setPreview] = useState<ExternalIdentityLinkPreview | null>(null);
|
|
47
|
+
const [selected, setSelected] = useState<ExternalIdentityLink["permissions"]>([]);
|
|
48
|
+
const [busy, setBusy] = useState(false);
|
|
49
|
+
const [error, setError] = useState(false);
|
|
50
|
+
const [retry, setRetry] = useState(0);
|
|
51
|
+
const generation = useRef(0);
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
const current = ++generation.current;
|
|
54
|
+
setLink(null);
|
|
55
|
+
setPreview(null);
|
|
56
|
+
setSelected([]);
|
|
57
|
+
setBusy(true);
|
|
58
|
+
setError(false);
|
|
59
|
+
void client
|
|
60
|
+
.previewIdentityLink(workspaceId, linkId, challenge)
|
|
61
|
+
.then(
|
|
62
|
+
(result) => {
|
|
63
|
+
if (generation.current !== current) return;
|
|
64
|
+
setPreview(result);
|
|
65
|
+
setLink(result.link);
|
|
66
|
+
setSelected(result.link.permissions);
|
|
67
|
+
},
|
|
68
|
+
() => {
|
|
69
|
+
if (generation.current === current) setError(true);
|
|
70
|
+
},
|
|
71
|
+
)
|
|
72
|
+
.finally(() => {
|
|
73
|
+
if (generation.current === current) setBusy(false);
|
|
74
|
+
});
|
|
75
|
+
return () => {
|
|
76
|
+
// Invalidate live async work, rather than cleaning up a captured DOM node.
|
|
77
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
78
|
+
generation.current++;
|
|
79
|
+
};
|
|
80
|
+
}, [client, workspaceId, linkId, challenge, retry]);
|
|
81
|
+
async function mutate(revoke: boolean) {
|
|
82
|
+
if (!link || busy) return;
|
|
83
|
+
const current = generation.current;
|
|
84
|
+
setBusy(true);
|
|
85
|
+
setError(false);
|
|
86
|
+
try {
|
|
87
|
+
const result = revoke
|
|
88
|
+
? await client.revokeIdentityLink(workspaceId, linkId, link.revision)
|
|
89
|
+
: await client.confirmIdentityLink(workspaceId, linkId, {
|
|
90
|
+
challenge,
|
|
91
|
+
expectedRevision: link.revision,
|
|
92
|
+
permissions: selected,
|
|
93
|
+
});
|
|
94
|
+
if (generation.current !== current) return;
|
|
95
|
+
setLink(result);
|
|
96
|
+
onComplete?.(result);
|
|
97
|
+
} catch {
|
|
98
|
+
if (generation.current === current) setError(true);
|
|
99
|
+
} finally {
|
|
100
|
+
if (generation.current === current) setBusy(false);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return (
|
|
104
|
+
<section
|
|
105
|
+
className={["og-connect og-identity-link", className].filter(Boolean).join(" ")}
|
|
106
|
+
aria-label="Link your account"
|
|
107
|
+
aria-busy={busy}
|
|
108
|
+
>
|
|
109
|
+
<h2>Link your Opengeni account</h2>
|
|
110
|
+
<p>
|
|
111
|
+
Only continue if you started this request in a product you trust. Linking lets that product
|
|
112
|
+
act as your account with the permissions you select. It does not merge accounts or move
|
|
113
|
+
existing work.
|
|
114
|
+
</p>
|
|
115
|
+
{preview && (
|
|
116
|
+
<dl>
|
|
117
|
+
<dt>Organization</dt>
|
|
118
|
+
<dd>{preview.organizationId}</dd>
|
|
119
|
+
<dt>Product user</dt>
|
|
120
|
+
<dd>
|
|
121
|
+
{preview.externalIdentity.externalId} ({preview.externalIdentity.source})
|
|
122
|
+
</dd>
|
|
123
|
+
<dt>Your Opengeni identity</dt>
|
|
124
|
+
<dd>{preview.nativeSubjectId}</dd>
|
|
125
|
+
</dl>
|
|
126
|
+
)}
|
|
127
|
+
{error && (
|
|
128
|
+
<div role="alert">
|
|
129
|
+
This request could not be completed. It may have expired, changed, or require you to sign
|
|
130
|
+
in to the right organization.
|
|
131
|
+
{!link && (
|
|
132
|
+
<button type="button" disabled={busy} onClick={() => setRetry((value) => value + 1)}>
|
|
133
|
+
Try again
|
|
134
|
+
</button>
|
|
135
|
+
)}
|
|
136
|
+
</div>
|
|
137
|
+
)}
|
|
138
|
+
{!link && busy && <p role="status">Loading the account-link request…</p>}
|
|
139
|
+
{link?.status === "pending" && (
|
|
140
|
+
<>
|
|
141
|
+
<p>
|
|
142
|
+
{link.expiresAt
|
|
143
|
+
? `Access ends ${new Date(link.expiresAt).toLocaleString()}.`
|
|
144
|
+
: "Access lasts until you or the product revoke this link."}{" "}
|
|
145
|
+
Your current permissions still apply.
|
|
146
|
+
</p>
|
|
147
|
+
<fieldset disabled={busy}>
|
|
148
|
+
<legend>Allow these permissions</legend>
|
|
149
|
+
{link.permissions.map((permission) => (
|
|
150
|
+
<label key={permission}>
|
|
151
|
+
<input
|
|
152
|
+
type="checkbox"
|
|
153
|
+
checked={selected.includes(permission)}
|
|
154
|
+
onChange={(event) =>
|
|
155
|
+
setSelected((values) =>
|
|
156
|
+
event.target.checked
|
|
157
|
+
? [...values, permission]
|
|
158
|
+
: values.filter((value) => value !== permission),
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
/>
|
|
162
|
+
<span>{permission.replaceAll(":", " · ")}</span>
|
|
163
|
+
</label>
|
|
164
|
+
))}
|
|
165
|
+
</fieldset>
|
|
166
|
+
<button
|
|
167
|
+
type="button"
|
|
168
|
+
disabled={busy || selected.length === 0}
|
|
169
|
+
onClick={() => void mutate(false)}
|
|
170
|
+
>
|
|
171
|
+
{busy ? "Saving…" : "Allow selected access"}
|
|
172
|
+
</button>
|
|
173
|
+
<p>You can close this page without granting access.</p>
|
|
174
|
+
</>
|
|
175
|
+
)}
|
|
176
|
+
{link?.status === "active" && (
|
|
177
|
+
<>
|
|
178
|
+
<p role="status">Account linked. Return to your product to continue.</p>
|
|
179
|
+
<button type="button" disabled={busy} onClick={() => void mutate(true)}>
|
|
180
|
+
Revoke this link
|
|
181
|
+
</button>
|
|
182
|
+
</>
|
|
183
|
+
)}
|
|
184
|
+
{link?.status === "revoked" && (
|
|
185
|
+
<p role="status">Link revoked. Your Opengeni account and existing work are unchanged.</p>
|
|
186
|
+
)}
|
|
187
|
+
{link?.status === "expired" && (
|
|
188
|
+
<p role="status">This request has expired. Start a new request from your product.</p>
|
|
189
|
+
)}
|
|
190
|
+
</section>
|
|
191
|
+
);
|
|
192
|
+
}
|