@opengeni/react 3.3.2 → 3.4.1-canary.38960406141001
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +769 -22
- package/dist/accounts.js +2 -0
- package/dist/accounts.js.map +1 -1
- package/dist/approvals.d.ts +2 -1
- package/dist/artifacts-document.js +5 -3
- package/dist/artifacts-presentation.js +5 -3
- package/dist/artifacts-spreadsheet.d.ts +1 -1
- package/dist/artifacts-spreadsheet.js +5 -3
- package/dist/artifacts.d.ts +5 -1
- package/dist/artifacts.js +536 -42
- package/dist/artifacts.js.map +1 -1
- package/dist/browser-viewer-ZWR6MWJ7.js +19 -0
- package/dist/capability-catalog-row.d.ts +20 -0
- package/dist/capability-logo-fallback.d.ts +3 -0
- package/dist/chat-interactive-block-4EUKJXUO.js +14 -0
- package/dist/chunk-2DDJ6YH6.js +41 -0
- package/dist/chunk-2DDJ6YH6.js.map +1 -0
- package/dist/chunk-2HVLQ26H.js +183 -0
- package/dist/chunk-2HVLQ26H.js.map +1 -0
- package/dist/{chunk-XYRDDSXF.js → chunk-2I6R3GCZ.js} +4285 -3980
- package/dist/chunk-2I6R3GCZ.js.map +1 -0
- package/dist/{chunk-JAQ5K7W6.js → chunk-2SFFYIH3.js} +1178 -166
- package/dist/chunk-2SFFYIH3.js.map +1 -0
- package/dist/chunk-3PVDYTTB.js +24 -0
- package/dist/chunk-3PVDYTTB.js.map +1 -0
- package/dist/chunk-3RJKUVCA.js +14068 -0
- package/dist/chunk-3RJKUVCA.js.map +1 -0
- package/dist/chunk-3UZCWK46.js +298 -0
- package/dist/chunk-3UZCWK46.js.map +1 -0
- package/dist/chunk-47CKUXTW.js +293 -0
- package/dist/chunk-47CKUXTW.js.map +1 -0
- package/dist/chunk-4QYP6QUI.js +109 -0
- package/dist/chunk-4QYP6QUI.js.map +1 -0
- package/dist/chunk-5EY26VZ7.js +1053 -0
- package/dist/chunk-5EY26VZ7.js.map +1 -0
- package/dist/chunk-5I4VRWBB.js +56 -0
- package/dist/chunk-5I4VRWBB.js.map +1 -0
- package/dist/chunk-5WOR7UCL.js +191 -0
- package/dist/chunk-5WOR7UCL.js.map +1 -0
- package/dist/chunk-5YJLGOM5.js +51 -0
- package/dist/chunk-5YJLGOM5.js.map +1 -0
- package/dist/chunk-6JFN3OWG.js +386 -0
- package/dist/chunk-6JFN3OWG.js.map +1 -0
- package/dist/chunk-7QJT5O4S.js +35 -0
- package/dist/chunk-7QJT5O4S.js.map +1 -0
- package/dist/chunk-A55KV72M.js +402 -0
- package/dist/chunk-A55KV72M.js.map +1 -0
- package/dist/chunk-ADWCLI4G.js +2028 -0
- package/dist/chunk-ADWCLI4G.js.map +1 -0
- package/dist/chunk-B27E3V37.js +29 -0
- package/dist/chunk-B27E3V37.js.map +1 -0
- package/dist/chunk-B7TC2A33.js +83 -0
- package/dist/chunk-B7TC2A33.js.map +1 -0
- package/dist/chunk-BLL56F7R.js +385 -0
- package/dist/chunk-BLL56F7R.js.map +1 -0
- package/dist/chunk-BOFEQC6K.js +162 -0
- package/dist/chunk-BOFEQC6K.js.map +1 -0
- package/dist/chunk-CM7LVUKC.js +35 -0
- package/dist/chunk-CM7LVUKC.js.map +1 -0
- package/dist/chunk-CORUP6JB.js +122 -0
- package/dist/chunk-CORUP6JB.js.map +1 -0
- package/dist/chunk-CSX5FFKZ.js +35 -0
- package/dist/chunk-CSX5FFKZ.js.map +1 -0
- package/dist/chunk-EGVHJKGJ.js +3125 -0
- package/dist/chunk-EGVHJKGJ.js.map +1 -0
- package/dist/{chunk-NEXLLTP4.js → chunk-G76LSA76.js} +6 -5
- package/dist/chunk-G76LSA76.js.map +1 -0
- package/dist/{chunk-PEI6RANI.js → chunk-GQMRL52F.js} +311 -75
- package/dist/chunk-GQMRL52F.js.map +1 -0
- package/dist/{chunk-ELIYWBZR.js → chunk-GUUXOISA.js} +1113 -457
- package/dist/chunk-GUUXOISA.js.map +1 -0
- package/dist/{chunk-HUIKIDM5.js → chunk-I7X2P4FU.js} +225 -116
- package/dist/chunk-I7X2P4FU.js.map +1 -0
- package/dist/chunk-IGFZFLI2.js +1390 -0
- package/dist/chunk-IGFZFLI2.js.map +1 -0
- package/dist/{chunk-4MDLEHXL.js → chunk-IMSUVYQB.js} +26 -13
- package/dist/chunk-IMSUVYQB.js.map +1 -0
- package/dist/chunk-IOYHDEP3.js +38 -0
- package/dist/chunk-IOYHDEP3.js.map +1 -0
- package/dist/chunk-IZV5FTJC.js +55 -0
- package/dist/chunk-IZV5FTJC.js.map +1 -0
- package/dist/chunk-KF33GTWN.js +343 -0
- package/dist/chunk-KF33GTWN.js.map +1 -0
- package/dist/chunk-KSGQ5ODA.js +457 -0
- package/dist/chunk-KSGQ5ODA.js.map +1 -0
- package/dist/{chunk-ZPBTI3TE.js → chunk-KZC6QRNR.js} +1513 -697
- package/dist/chunk-KZC6QRNR.js.map +1 -0
- package/dist/chunk-LJUMYUBO.js +218 -0
- package/dist/chunk-LJUMYUBO.js.map +1 -0
- package/dist/chunk-LSW2OJVV.js +380 -0
- package/dist/chunk-LSW2OJVV.js.map +1 -0
- package/dist/chunk-M357MHH3.js +2 -0
- package/dist/chunk-M357MHH3.js.map +1 -0
- package/dist/chunk-MK2TQO4Y.js +24 -0
- package/dist/chunk-MK2TQO4Y.js.map +1 -0
- package/dist/chunk-N7S72EXK.js +25 -0
- package/dist/chunk-N7S72EXK.js.map +1 -0
- package/dist/{chunk-YVCHAQZY.js → chunk-NKMYZFHA.js} +616 -621
- package/dist/chunk-NKMYZFHA.js.map +1 -0
- package/dist/chunk-NX4ADH73.js +14 -0
- package/dist/chunk-NX4ADH73.js.map +1 -0
- package/dist/chunk-O7F6UJO4.js +71 -0
- package/dist/chunk-O7F6UJO4.js.map +1 -0
- package/dist/chunk-OYQQJL3J.js +16 -0
- package/dist/chunk-OYQQJL3J.js.map +1 -0
- package/dist/{chunk-H5YGYNXS.js → chunk-P4BNUO57.js} +60 -17
- package/dist/chunk-P4BNUO57.js.map +1 -0
- package/dist/{chunk-JVYQRRC4.js → chunk-PEHTX3V7.js} +21 -1
- package/dist/chunk-PEHTX3V7.js.map +1 -0
- package/dist/chunk-PMV53IMM.js +26 -0
- package/dist/chunk-PMV53IMM.js.map +1 -0
- package/dist/{chunk-KCGXPP5V.js → chunk-PYEOPA4M.js} +13 -7
- package/dist/chunk-PYEOPA4M.js.map +1 -0
- package/dist/{chunk-KZ73RL76.js → chunk-QHUE7E4N.js} +8 -3
- package/dist/chunk-QHUE7E4N.js.map +1 -0
- package/dist/chunk-QV3DJVRZ.js +11 -0
- package/dist/chunk-QV3DJVRZ.js.map +1 -0
- package/dist/chunk-R5SBNG7S.js +810 -0
- package/dist/chunk-R5SBNG7S.js.map +1 -0
- package/dist/chunk-RI42H5IU.js +326 -0
- package/dist/chunk-RI42H5IU.js.map +1 -0
- package/dist/chunk-S2QH6EZ5.js +211 -0
- package/dist/chunk-S2QH6EZ5.js.map +1 -0
- package/dist/chunk-SHLZMAJN.js +304 -0
- package/dist/chunk-SHLZMAJN.js.map +1 -0
- package/dist/chunk-TGXK4BAZ.js +293 -0
- package/dist/chunk-TGXK4BAZ.js.map +1 -0
- package/dist/{chunk-5YK2ZDIG.js → chunk-TNEZNMSN.js} +4 -10
- package/dist/chunk-TNEZNMSN.js.map +1 -0
- package/dist/{chunk-22KP6LR5.js → chunk-TXS65BB2.js} +3 -1
- package/dist/{chunk-22KP6LR5.js.map → chunk-TXS65BB2.js.map} +1 -1
- package/dist/chunk-UNJPZGNK.js +63 -0
- package/dist/chunk-UNJPZGNK.js.map +1 -0
- package/dist/{chunk-IOLVN74D.js → chunk-V5ZUJT2T.js} +175 -42
- package/dist/chunk-V5ZUJT2T.js.map +1 -0
- package/dist/chunk-WBJY57A3.js +402 -0
- package/dist/chunk-WBJY57A3.js.map +1 -0
- package/dist/chunk-WIUKB3LD.js +1911 -0
- package/dist/chunk-WIUKB3LD.js.map +1 -0
- package/dist/{chunk-ICA6R6TW.js → chunk-WNN7NO2N.js} +1451 -355
- package/dist/chunk-WNN7NO2N.js.map +1 -0
- package/dist/{chunk-3AGBGTRT.js → chunk-X5UVUIMF.js} +1712 -1174
- package/dist/chunk-X5UVUIMF.js.map +1 -0
- package/dist/chunk-XDA5QJE7.js +402 -0
- package/dist/chunk-XDA5QJE7.js.map +1 -0
- package/dist/{chunk-VZTQ73XT.js → chunk-XEA5BCMA.js} +3 -1
- package/dist/{chunk-VZTQ73XT.js.map → chunk-XEA5BCMA.js.map} +1 -1
- package/dist/chunk-XHF7OYAN.js +1150 -0
- package/dist/chunk-XHF7OYAN.js.map +1 -0
- package/dist/chunk-YSRBFJMQ.js +43 -0
- package/dist/chunk-YSRBFJMQ.js.map +1 -0
- package/dist/chunk-ZOZAPAUO.js +174 -0
- package/dist/chunk-ZOZAPAUO.js.map +1 -0
- package/dist/chunk-ZQV5W7YC.js +809 -0
- package/dist/chunk-ZQV5W7YC.js.map +1 -0
- package/dist/chunk-ZUWF4NF7.js +13 -0
- package/dist/chunk-ZUWF4NF7.js.map +1 -0
- package/dist/client.d.ts +16 -7
- package/dist/clipboard.js +3 -1
- package/dist/commands/types.d.ts +2 -0
- package/dist/components/anthropic-mark.d.ts +3 -0
- package/dist/components/approval-surface.d.ts +19 -6
- package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
- package/dist/components/artifacts/artifact-sandbox.d.ts +30 -0
- package/dist/components/artifacts/artifact-surface.d.ts +4 -2
- package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
- package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
- package/dist/components/artifacts/document-editor.d.ts +4 -2
- package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
- package/dist/components/artifacts/editable-artifact-view.d.ts +48 -0
- package/dist/components/artifacts/editable-document.d.ts +1 -1
- package/dist/components/artifacts/editable-presentation.d.ts +2 -2
- package/dist/components/artifacts/editable-spreadsheet.d.ts +8 -3
- package/dist/components/artifacts/index.d.ts +9 -2
- package/dist/components/artifacts/inline-html-document.d.ts +2 -0
- package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
- package/dist/components/artifacts/presentation-editor.d.ts +6 -2
- package/dist/components/artifacts/published-html-artifact-frame.d.ts +23 -3
- package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
- package/dist/components/artifacts/site-view.d.ts +26 -0
- package/dist/components/artifacts/spreadsheet-command-queue.d.ts +20 -0
- package/dist/components/artifacts/spreadsheet-download.d.ts +7 -0
- package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
- package/dist/components/artifacts/spreadsheet-grid.d.ts +10 -3
- package/dist/components/artifacts/spreadsheet-resize.d.ts +50 -0
- package/dist/components/artifacts/spreadsheet-submissions.d.ts +9 -0
- package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
- package/dist/components/browser-select-control.d.ts +16 -0
- package/dist/components/browser-viewer.d.ts +11 -2
- package/dist/components/chat-composer.d.ts +21 -3
- package/dist/components/child-session-link.d.ts +9 -0
- package/dist/components/claude-mark.d.ts +3 -0
- package/dist/components/code-editor.d.ts +1 -4
- package/dist/components/composer-transcription-control.d.ts +7 -0
- package/dist/components/composer.d.ts +34 -67
- package/dist/components/computer-viewer.d.ts +1 -1
- package/dist/components/copy-button.d.ts +3 -1
- package/dist/components/desktop-viewer.d.ts +1 -1
- package/dist/components/grok-mark.d.ts +26 -0
- package/dist/components/human-input-form.d.ts +28 -32
- package/dist/components/human-input-surface.d.ts +7 -2
- package/dist/components/linkified-text.d.ts +18 -0
- package/dist/components/machine-input-display.d.ts +22 -1
- package/dist/components/machines/agent-status-icon.d.ts +6 -0
- package/dist/components/machines/machine-detail.d.ts +7 -1
- package/dist/components/machines/machine-status.d.ts +48 -0
- package/dist/components/markdown-table-layout.d.ts +18 -0
- package/dist/components/markdown.d.ts +37 -4
- package/dist/components/message-timeline.d.ts +86 -7
- package/dist/components/model-mark.d.ts +29 -0
- package/dist/components/model-policy-picker-menu.d.ts +9 -0
- package/dist/components/model-policy-picker.d.ts +35 -28
- package/dist/components/new-conversation.d.ts +32 -0
- package/dist/components/open-geni-chat.d.ts +73 -0
- package/dist/components/open-geni-links.d.ts +68 -0
- package/dist/components/openrouter-mark.d.ts +6 -0
- package/dist/components/opper-mark.d.ts +7 -0
- package/dist/components/preview-loading.d.ts +2 -0
- package/dist/components/provider-recovery-notice.d.ts +16 -0
- package/dist/components/queue-item-content.d.ts +9 -0
- package/dist/components/rehype-secret-refs.d.ts +23 -0
- package/dist/components/remark-soft-line-breaks.d.ts +38 -0
- package/dist/components/sandbox-files.d.ts +3 -1
- package/dist/components/sandbox-workspace.d.ts +18 -0
- package/dist/components/secret-question-field.d.ts +31 -0
- package/dist/components/secret-ref-chip.d.ts +35 -0
- package/dist/components/session-capability-frame.d.ts +37 -0
- package/dist/components/session-chrome.d.ts +57 -8
- package/dist/components/session-commands-panel.d.ts +6 -0
- package/dist/components/session-commands.d.ts +6 -0
- package/dist/components/session-connection-request.d.ts +8 -0
- package/dist/components/session-conversation.d.ts +157 -0
- package/dist/components/session-list.d.ts +39 -0
- package/dist/components/session-mcp-capability-card.d.ts +41 -0
- package/dist/components/session-proxy-scope.d.ts +35 -0
- package/dist/components/session-status.d.ts +4 -1
- package/dist/components/session-usage-limit-notice.d.ts +39 -0
- package/dist/components/timeline-anchor.d.ts +24 -0
- package/dist/components/timeline-annotation-chrome.d.ts +25 -0
- package/dist/components/timeline-annotation-layout.d.ts +42 -0
- package/dist/components/timeline-annotation-markers.d.ts +8 -0
- package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
- package/dist/components/timeline-annotation-shared.d.ts +31 -0
- package/dist/components/timeline-annotations-dialog.d.ts +3 -2
- package/dist/components/timeline-annotations.d.ts +13 -3
- package/dist/components/timeline-reading-progress.d.ts +11 -0
- package/dist/components/timeline-search.d.ts +34 -0
- package/dist/components/timeline-settlement.d.ts +16 -0
- package/dist/components/tool-action-review.d.ts +47 -0
- package/dist/components/tool-review-history.d.ts +25 -0
- package/dist/components/usage-limit-notice.d.ts +49 -0
- package/dist/components/usage-member-list.d.ts +91 -0
- package/dist/components/usage-meter.d.ts +73 -0
- package/dist/components/use-viewer-menu-dismiss.d.ts +2 -0
- package/dist/components/user-message-body.d.ts +10 -1
- package/dist/composer-messages.d.ts +74 -0
- package/dist/composer-messages.js +9 -0
- package/dist/composer-messages.js.map +1 -0
- package/dist/composer-voice-events.d.ts +8 -0
- package/dist/composer.d.ts +5 -4
- package/dist/composer.js +26 -13
- package/dist/computer-viewer-GMLDXPON.js +20 -0
- package/dist/computer-viewer-GMLDXPON.js.map +1 -0
- package/dist/connect-account-identity.d.ts +8 -0
- package/dist/connect-accounts.d.ts +15 -0
- package/dist/connect-chooser.d.ts +18 -0
- package/dist/connect-panel.d.ts +18 -0
- package/dist/connect-setup.d.ts +18 -0
- package/dist/connect.d.ts +21 -0
- package/dist/connect.js +2149 -0
- package/dist/connect.js.map +1 -0
- package/dist/connection-catalog.d.ts +38 -0
- package/dist/connection-discovery.d.ts +12 -0
- package/dist/connection-installed.d.ts +17 -0
- package/dist/connection-logo.d.ts +9 -0
- package/dist/connection-service-logo.d.ts +8 -0
- package/dist/connection-service-presentation.d.ts +13 -0
- package/dist/connection-skeleton.d.ts +5 -0
- package/dist/connection-type-picker.d.ts +6 -0
- package/dist/conversation-timeline.d.ts +5 -0
- package/dist/desktop.d.ts +7 -0
- package/dist/desktop.js +27 -0
- package/dist/desktop.js.map +1 -0
- package/dist/device-authorization.d.ts +23 -0
- package/dist/diffs.d.ts +8 -0
- package/dist/diffs.js +15 -0
- package/dist/diffs.js.map +1 -0
- package/dist/discovery-cache.d.ts +5 -0
- package/dist/editor.d.ts +7 -0
- package/dist/editor.js +22 -0
- package/dist/editor.js.map +1 -0
- package/dist/embedded-new-voice-OCRNT6U5.js +18 -0
- package/dist/embedded-new-voice-OCRNT6U5.js.map +1 -0
- package/dist/embedded-voice-RPHPYVBT.js +18 -0
- package/dist/embedded-voice-RPHPYVBT.js.map +1 -0
- package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-SI63O5V4.js} +4 -1
- package/dist/fleet-decision-row-SI63O5V4.js.map +1 -0
- package/dist/hooks/latest-question.d.ts +25 -0
- package/dist/hooks/shared-machines-list.d.ts +4 -0
- package/dist/hooks/shared-query.d.ts +113 -0
- package/dist/hooks/use-attached-browsers.d.ts +1 -1
- package/dist/hooks/use-auth-runs.d.ts +1 -4
- package/dist/hooks/use-available-models.d.ts +1 -1
- package/dist/hooks/use-browser-frame-stream.d.ts +1 -1
- package/dist/hooks/use-browser-session.d.ts +12 -1
- package/dist/hooks/use-client-config-flags.d.ts +49 -0
- package/dist/hooks/use-codex-accounts.d.ts +59 -10
- package/dist/hooks/use-composer.d.ts +24 -2
- package/dist/hooks/use-computer-frame-stream.d.ts +1 -1
- package/dist/hooks/use-computer-input-posture.d.ts +13 -0
- package/dist/hooks/use-computer-session.d.ts +4 -0
- package/dist/hooks/use-connect.d.ts +23 -0
- package/dist/hooks/use-desktop-stream.d.ts +1 -1
- package/dist/hooks/use-file-attachments.d.ts +12 -0
- package/dist/hooks/use-goal.d.ts +2 -1
- package/dist/hooks/use-last-started-turn-policy.d.ts +5 -1
- package/dist/hooks/use-new-conversation.d.ts +56 -0
- package/dist/hooks/use-new-session-draft.d.ts +74 -0
- package/dist/hooks/use-realtime-voice-models.d.ts +7 -0
- package/dist/hooks/use-sandbox-files.d.ts +4 -1
- package/dist/hooks/use-session-conversation.d.ts +49 -0
- package/dist/hooks/use-session-events.d.ts +26 -5
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
- package/dist/hooks/use-session-model-account.d.ts +48 -0
- package/dist/hooks/use-supergrok-accounts.d.ts +7 -1
- package/dist/hooks/use-terminal-stream.d.ts +11 -5
- package/dist/hooks/use-usage.d.ts +40 -0
- package/dist/hooks/use-vaults.d.ts +53 -0
- package/dist/hooks/use-voice-input.d.ts +8 -1
- package/dist/hooks/use-workspace-edit.d.ts +4 -0
- package/dist/hooks/use-workspace-sessions.d.ts +24 -5
- package/dist/human-input-model.d.ts +122 -0
- package/dist/identity-link-accounts.d.ts +11 -0
- package/dist/identity-link-consent.d.ts +18 -0
- package/dist/index.d.ts +82 -20
- package/dist/index.js +2340 -6603
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +1 -1
- package/dist/interaction.js +14 -24
- package/dist/interaction.js.map +1 -1
- package/dist/latest-question-R77KWSUP.js +118 -0
- package/dist/latest-question-R77KWSUP.js.map +1 -0
- package/dist/lib/clipboard.d.ts +7 -0
- package/dist/lib/error-message.d.ts +7 -0
- package/dist/lib/format.d.ts +58 -4
- package/dist/lib/host-theme.d.ts +77 -0
- package/dist/lib/interaction-errors.d.ts +3 -0
- package/dist/lib/menu-styles.d.ts +22 -0
- package/dist/lib/notify-observer.d.ts +2 -0
- package/dist/lib/pierre-diffs-loader.d.ts +20 -0
- package/dist/lib/provider-recovery.d.ts +55 -0
- package/dist/lib/scrollbars.d.ts +11 -0
- package/dist/lib/terminal-input-readiness.d.ts +11 -0
- package/dist/lib/transient-retry.d.ts +25 -0
- package/dist/lib/workbench-peers.d.ts +36 -0
- package/dist/lib/xterm-theme.d.ts +7 -5
- package/dist/machines.js +9 -5
- package/dist/markdown-table-layout-3PV2UAAH.js +113 -0
- package/dist/markdown-table-layout-3PV2UAAH.js.map +1 -0
- package/dist/mcp-connection-status.d.ts +14 -0
- package/dist/model-mark-paths.d.ts +34 -0
- package/dist/model-mark-paths.js +16 -0
- package/dist/model-mark-paths.js.map +1 -0
- package/dist/model-picker-model.d.ts +111 -0
- package/dist/model-picker-model.js +25 -0
- package/dist/model-picker-model.js.map +1 -0
- package/dist/model-policy-picker-menu-7GJ5URPR.js +17 -0
- package/dist/model-policy-picker-menu-7GJ5URPR.js.map +1 -0
- package/dist/model-policy.d.ts +30 -3
- package/dist/model-policy.js +14 -1
- package/dist/native-previews.d.ts +28 -0
- package/dist/native-previews.js +82 -0
- package/dist/native-previews.js.map +1 -0
- package/dist/new-session-draft.d.ts +7 -0
- package/dist/new-session-draft.js +639 -0
- package/dist/new-session-draft.js.map +1 -0
- package/dist/notification-text.d.ts +27 -0
- package/dist/{noto-sans-arabic-loader-IA2T4X2A.js → noto-sans-arabic-loader-XSH2KYWJ.js} +3 -1
- package/dist/{noto-sans-arabic-loader-IA2T4X2A.js.map → noto-sans-arabic-loader-XSH2KYWJ.js.map} +1 -1
- package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js → noto-sans-jp-loader.generated-MR5L6V7K.js} +3 -1
- package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js.map → noto-sans-jp-loader.generated-MR5L6V7K.js.map} +1 -1
- package/dist/older-history.d.ts +3 -2
- package/dist/organization-model.d.ts +32 -0
- package/dist/organization-model.js +65 -0
- package/dist/organization-model.js.map +1 -0
- package/dist/{platform-activity-row-BJHUHXAT.js → platform-activity-row-5OCKOQWZ.js} +16 -78
- package/dist/platform-activity-row-5OCKOQWZ.js.map +1 -0
- package/dist/plugin-details.d.ts +14 -0
- package/dist/plugin-discovery.d.ts +25 -0
- package/dist/preview-loading-paint.d.ts +20 -0
- package/dist/provider.d.ts +25 -2
- package/dist/queue-presentation-model.d.ts +72 -0
- package/dist/queue-presentation-model.js +38 -0
- package/dist/queue-presentation-model.js.map +1 -0
- package/dist/{queue-surface-implementation-BSKUWHRI.js → queue-surface-implementation-GJBH7NKO.js} +65 -265
- package/dist/queue-surface-implementation-GJBH7NKO.js.map +1 -0
- package/dist/realtime/embedded-new-voice.d.ts +1 -0
- package/dist/realtime/embedded-voice.d.ts +1 -0
- package/dist/realtime/realtime-control.d.ts +4 -65
- package/dist/realtime/session-realtime.d.ts +78 -0
- package/dist/realtime.js +25 -1333
- package/dist/realtime.js.map +1 -1
- package/dist/sandbox-files-O27IPOZW.js +21 -0
- package/dist/sandbox-files-O27IPOZW.js.map +1 -0
- package/dist/sandbox-label-model.d.ts +30 -0
- package/dist/sandbox-label-model.js +20 -0
- package/dist/sandbox-label-model.js.map +1 -0
- package/dist/scrollbars.d.ts +1 -0
- package/dist/scrollbars.js +10 -0
- package/dist/scrollbars.js.map +1 -0
- package/dist/secret-reference-label.d.ts +14 -0
- package/dist/secrets-ui.d.ts +57 -0
- package/dist/session-agents-model.d.ts +10 -0
- package/dist/session-agents-model.js +25 -0
- package/dist/session-agents-model.js.map +1 -0
- package/dist/session-attention-model.d.ts +8 -0
- package/dist/session-attention-model.js +47 -0
- package/dist/session-attention-model.js.map +1 -0
- package/dist/session-auth-recommendation.d.ts +5 -0
- package/dist/session-capability-policy.d.ts +31 -0
- package/dist/session-feedback-model.d.ts +20 -0
- package/dist/session-feedback-model.js +56 -0
- package/dist/session-feedback-model.js.map +1 -0
- package/dist/session-list-model.d.ts +138 -0
- package/dist/session-list-model.js +274 -0
- package/dist/session-list-model.js.map +1 -0
- package/dist/session-realtime-7DJOIHQW.js +21 -0
- package/dist/session-realtime-7DJOIHQW.js.map +1 -0
- package/dist/session-realtime.d.ts +7 -0
- package/dist/session-realtime.js +19 -0
- package/dist/session-realtime.js.map +1 -0
- package/dist/session-status-model.d.ts +36 -0
- package/dist/session-ui.d.ts +39 -1
- package/dist/session-ui.js +126 -12
- package/dist/session-ui.js.map +1 -1
- package/dist/session.d.ts +8 -2
- package/dist/session.js +35 -20
- package/dist/site-snapshot.d.ts +14 -0
- package/dist/sites-ui.d.ts +24 -0
- package/dist/sites.d.ts +3 -0
- package/dist/sites.js +14 -0
- package/dist/sites.js.map +1 -0
- package/dist/skill-discovery.d.ts +47 -0
- package/dist/terminal.d.ts +8 -0
- package/dist/terminal.js +32 -0
- package/dist/terminal.js.map +1 -0
- package/dist/testing/session-scenarios.d.ts +10 -0
- package/dist/testing/session-scenarios.js +367 -0
- package/dist/testing/session-scenarios.js.map +1 -0
- package/dist/timeline/activity-rail.d.ts +11 -2
- package/dist/timeline/agent-identity.d.ts +30 -0
- package/dist/timeline/agent-row.d.ts +31 -0
- package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
- package/dist/timeline/compaction-copy.d.ts +46 -0
- package/dist/timeline/focus-sequence.d.ts +9 -0
- package/dist/timeline/genie-copy.d.ts +3 -0
- package/dist/timeline/genie-loading.d.ts +47 -0
- package/dist/timeline/index.d.ts +10 -5
- package/dist/timeline/knowledge-receipt.d.ts +17 -0
- package/dist/timeline/message-sender.d.ts +19 -0
- package/dist/timeline/notice-presentation.d.ts +13 -0
- package/dist/timeline/parsers.d.ts +11 -0
- package/dist/timeline/patch-apply-command.d.ts +18 -0
- package/dist/timeline/platform-activity-presentation.d.ts +21 -0
- package/dist/timeline/platform-activity-row.d.ts +1 -2
- package/dist/timeline/presented-image.d.ts +11 -0
- package/dist/timeline/projection.d.ts +31 -2
- package/dist/timeline/provider-logo.d.ts +15 -0
- package/dist/timeline/question-nav-model.d.ts +23 -0
- package/dist/timeline/registry.d.ts +12 -1
- package/dist/timeline/retained-image.d.ts +18 -0
- package/dist/timeline/retained-loaders.d.ts +27 -0
- package/dist/timeline/rolling-activity.d.ts +11 -0
- package/dist/timeline/screenshot-lightbox.d.ts +23 -1
- package/dist/timeline/session-usage-limit-row.d.ts +11 -0
- package/dist/timeline/shared.d.ts +4 -1
- package/dist/timeline/startup-dispatch-details.d.ts +5 -0
- package/dist/timeline/startup-preference.d.ts +3 -0
- package/dist/timeline/startup-timings.d.ts +4 -0
- package/dist/timeline/tool-display-name.d.ts +5 -2
- package/dist/timeline/tool-presentation.d.ts +172 -0
- package/dist/timeline/turn-summary-model.d.ts +95 -0
- package/dist/timeline/turn-summary.d.ts +20 -54
- package/dist/timeline/types.d.ts +179 -7
- package/dist/timeline/work-presentation.d.ts +60 -0
- package/dist/timeline-annotation-markers-U3G66KUD.js +166 -0
- package/dist/timeline-annotation-markers-U3G66KUD.js.map +1 -0
- package/dist/timeline-annotation-selection-BI7QTPTZ.js +242 -0
- package/dist/timeline-annotation-selection-BI7QTPTZ.js.map +1 -0
- package/dist/timeline-annotations-dialog-FOMHSDTE.js +274 -0
- package/dist/timeline-annotations-dialog-FOMHSDTE.js.map +1 -0
- package/dist/timeline-model.d.ts +29 -0
- package/dist/timeline-model.js +254 -0
- package/dist/timeline-model.js.map +1 -0
- package/dist/usage/allowance-copy.d.ts +25 -0
- package/dist/usage/session-usage-limit.d.ts +88 -0
- package/dist/usage/summary.d.ts +35 -0
- package/dist/usage.d.ts +17 -0
- package/dist/usage.js +1187 -0
- package/dist/usage.js.map +1 -0
- package/dist/voice-recording-owner.d.ts +7 -0
- package/package.json +106 -7
- package/src/approvals.ts +8 -1
- package/src/artifacts-spreadsheet.ts +1 -0
- package/src/artifacts.ts +44 -0
- package/src/assets/README.md +8 -0
- package/src/assets/gmail.ico +0 -0
- package/src/assets/outlook.ico +0 -0
- package/src/capability-catalog-row.tsx +94 -0
- package/src/capability-logo-fallback.ts +22 -0
- package/src/client.ts +20 -31
- package/src/commands/registry.ts +18 -15
- package/src/commands/types.ts +2 -0
- package/src/components/anthropic-mark.tsx +10 -0
- package/src/components/approval-surface.tsx +401 -138
- package/src/components/artifacts/artifact-chrome.tsx +413 -0
- package/src/components/artifacts/artifact-sandbox.tsx +193 -0
- package/src/components/artifacts/artifact-surface.tsx +40 -20
- package/src/components/artifacts/chat-interactive-block.tsx +260 -0
- package/src/components/artifacts/deferred-chat-media.tsx +67 -0
- package/src/components/artifacts/document-editor.tsx +141 -16
- package/src/components/artifacts/editable-artifact-ui.tsx +4 -2
- package/src/components/artifacts/editable-artifact-view.tsx +197 -0
- package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
- package/src/components/artifacts/editable-document.tsx +37 -36
- package/src/components/artifacts/editable-presentation.tsx +36 -18
- package/src/components/artifacts/editable-spreadsheet.tsx +543 -103
- package/src/components/artifacts/index.ts +45 -0
- package/src/components/artifacts/inline-html-document.ts +24 -0
- package/src/components/artifacts/latest-task-runner.ts +49 -0
- package/src/components/artifacts/presentation-editor.tsx +323 -67
- package/src/components/artifacts/published-html-artifact-frame.tsx +122 -5
- package/src/components/artifacts/session-artifact-viewer.tsx +378 -0
- package/src/components/artifacts/site-view.tsx +121 -0
- package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
- package/src/components/artifacts/spreadsheet-command-queue.ts +184 -0
- package/src/components/artifacts/spreadsheet-download.tsx +109 -0
- package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
- package/src/components/artifacts/spreadsheet-grid.tsx +344 -144
- package/src/components/artifacts/spreadsheet-resize.tsx +421 -0
- package/src/components/artifacts/spreadsheet-submissions.tsx +46 -0
- package/src/components/artifacts/visualization-assets/base.css +1015 -0
- package/src/components/artifacts/visualization-assets/helpers.html +349 -0
- package/src/components/artifacts/visualization-assets.gen.ts +3 -0
- package/src/components/browser-select-control.tsx +312 -0
- package/src/components/browser-viewer.tsx +778 -318
- package/src/components/chat-composer.tsx +47 -5
- package/src/components/child-session-link.tsx +36 -0
- package/src/components/claude-mark.tsx +11 -0
- package/src/components/code-editor.tsx +13 -16
- package/src/components/composer-transcription-control.tsx +128 -30
- package/src/components/composer.tsx +404 -195
- package/src/components/computer-viewer.tsx +880 -253
- package/src/components/copy-button.tsx +13 -5
- package/src/components/desktop-viewer.tsx +1 -1
- package/src/components/enrollment-consent.tsx +1 -1
- package/src/components/enrollment-device-flow.tsx +1 -1
- package/src/components/file-browser.tsx +10 -14
- package/src/components/fleet-tile.tsx +5 -3
- package/src/components/generated-video-player.tsx +4 -2
- package/src/components/grok-mark.tsx +34 -0
- package/src/components/human-input-form.tsx +590 -283
- package/src/components/human-input-surface.tsx +11 -0
- package/src/components/interaction-intervention-banner.tsx +2 -2
- package/src/components/linkified-text.tsx +79 -0
- package/src/components/machine-card.tsx +35 -78
- package/src/components/machine-dock-bar.tsx +1 -1
- package/src/components/machine-input-display.ts +197 -3
- package/src/components/machines/agent-status-icon.tsx +31 -0
- package/src/components/machines/machine-detail.tsx +200 -31
- package/src/components/machines/machine-operation-policy.tsx +1 -1
- package/src/components/machines/machine-status.ts +241 -0
- package/src/components/machines-dashboard.tsx +2 -17
- package/src/components/markdown-table-layout.ts +143 -0
- package/src/components/markdown.tsx +466 -129
- package/src/components/message-timeline.tsx +2370 -667
- package/src/components/model-mark.tsx +102 -0
- package/src/components/model-picker.tsx +15 -4
- package/src/components/model-policy-picker-menu.tsx +371 -0
- package/src/components/model-policy-picker.tsx +252 -429
- package/src/components/new-conversation.tsx +221 -0
- package/src/components/open-geni-chat.tsx +309 -0
- package/src/components/open-geni-links.tsx +179 -0
- package/src/components/openrouter-mark.tsx +13 -0
- package/src/components/opper-mark.tsx +18 -0
- package/src/components/pierre-diff.tsx +41 -16
- package/src/components/pierre-file.tsx +35 -10
- package/src/components/preview-loading.tsx +109 -0
- package/src/components/provider-recovery-notice.tsx +49 -0
- package/src/components/queue-item-content.ts +14 -0
- package/src/components/queue-surface-implementation.tsx +51 -356
- package/src/components/queue-surface-state.tsx +3 -1
- package/src/components/rehype-secret-refs.ts +98 -0
- package/src/components/remark-soft-line-breaks.ts +166 -0
- package/src/components/sandbox-files.tsx +91 -15
- package/src/components/sandbox-terminal.tsx +84 -13
- package/src/components/sandbox-workspace.tsx +147 -51
- package/src/components/secret-question-field.tsx +324 -0
- package/src/components/secret-ref-chip.tsx +185 -0
- package/src/components/session-capability-frame.tsx +197 -0
- package/src/components/session-chrome.tsx +842 -251
- package/src/components/session-commands-panel.tsx +126 -0
- package/src/components/session-commands.tsx +18 -0
- package/src/components/session-connection-request.tsx +97 -0
- package/src/components/session-conversation.tsx +876 -0
- package/src/components/session-list.tsx +257 -0
- package/src/components/session-mcp-capability-card.tsx +680 -0
- package/src/components/session-proxy-scope.tsx +153 -0
- package/src/components/session-status.tsx +26 -17
- package/src/components/session-usage-limit-notice.tsx +174 -0
- package/src/components/timeline-anchor.tsx +119 -0
- package/src/components/timeline-annotation-chrome.tsx +196 -0
- package/src/components/timeline-annotation-layout.ts +268 -0
- package/src/components/timeline-annotation-markers.tsx +185 -0
- package/src/components/timeline-annotation-reveal-context.ts +9 -0
- package/src/components/timeline-annotation-selection.tsx +106 -54
- package/src/components/timeline-annotation-shared.ts +245 -0
- package/src/components/timeline-annotations-dialog.tsx +185 -128
- package/src/components/timeline-annotations.tsx +189 -45
- package/src/components/timeline-reading-progress.ts +80 -0
- package/src/components/timeline-search.tsx +168 -0
- package/src/components/timeline-settlement.ts +60 -0
- package/src/components/tool-action-review.tsx +650 -0
- package/src/components/tool-review-history.tsx +88 -0
- package/src/components/usage-limit-notice.tsx +179 -0
- package/src/components/usage-member-list.tsx +792 -0
- package/src/components/usage-meter.tsx +382 -0
- package/src/components/use-viewer-menu-dismiss.ts +33 -0
- package/src/components/user-message-body.tsx +27 -2
- package/src/components/workspace-dock.tsx +18 -1
- package/src/composer-messages.ts +150 -0
- package/src/composer-voice-events.ts +12 -0
- package/src/composer.ts +6 -1
- package/src/connect-account-identity.tsx +34 -0
- package/src/connect-accounts.tsx +233 -0
- package/src/connect-chooser.tsx +336 -0
- package/src/connect-panel.tsx +99 -0
- package/src/connect-setup.tsx +355 -0
- package/src/connect.ts +60 -0
- package/src/connection-assets.d.ts +4 -0
- package/src/connection-catalog.tsx +162 -0
- package/src/connection-discovery.tsx +238 -0
- package/src/connection-installed.tsx +51 -0
- package/src/connection-logo.tsx +37 -0
- package/src/connection-service-logo.tsx +55 -0
- package/src/connection-service-presentation.ts +46 -0
- package/src/connection-skeleton.tsx +16 -0
- package/src/connection-type-picker.tsx +36 -0
- package/src/conversation-timeline.ts +92 -0
- package/src/desktop.ts +24 -0
- package/src/device-authorization.tsx +98 -0
- package/src/diffs.ts +16 -0
- package/src/discovery-cache.ts +42 -0
- package/src/editor.ts +13 -0
- package/src/hooks/internal.ts +3 -2
- package/src/hooks/latest-question.ts +164 -0
- package/src/hooks/shared-machines-list.ts +34 -1
- package/src/hooks/shared-query.ts +721 -0
- package/src/hooks/use-attached-browsers.ts +1 -1
- package/src/hooks/use-auth-runs.ts +0 -27
- package/src/hooks/use-available-models.ts +2 -2
- package/src/hooks/use-browser-frame-stream.ts +19 -2
- package/src/hooks/use-browser-session.ts +680 -205
- package/src/hooks/use-browser-sessions.ts +32 -1
- package/src/hooks/use-client-config-flags.ts +118 -0
- package/src/hooks/use-codex-accounts.ts +247 -47
- package/src/hooks/use-composer.ts +227 -44
- package/src/hooks/use-computer-frame-stream.ts +25 -7
- package/src/hooks/use-computer-input-posture.ts +94 -0
- package/src/hooks/use-computer-session.ts +409 -95
- package/src/hooks/use-connect.ts +23 -0
- package/src/hooks/use-desktop-stream.ts +19 -28
- package/src/hooks/use-file-attachments.ts +80 -4
- package/src/hooks/use-goal.ts +79 -9
- package/src/hooks/use-last-started-turn-policy.ts +37 -11
- package/src/hooks/use-machines.ts +4 -0
- package/src/hooks/use-new-conversation.ts +374 -0
- package/src/hooks/use-new-session-draft.ts +813 -0
- package/src/hooks/use-realtime-voice-models.ts +46 -0
- package/src/hooks/use-sandbox-files.ts +68 -20
- package/src/hooks/use-session-background-commands.ts +22 -11
- package/src/hooks/use-session-capabilities.ts +3 -2
- package/src/hooks/use-session-conversation.ts +150 -0
- package/src/hooks/use-session-events.ts +531 -335
- package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
- package/src/hooks/use-session-model-account.ts +174 -0
- package/src/hooks/use-session.ts +30 -2
- package/src/hooks/use-slash-commands.ts +6 -11
- package/src/hooks/use-supergrok-accounts.ts +22 -8
- package/src/hooks/use-terminal-stream.ts +153 -27
- package/src/hooks/use-transcription.ts +6 -0
- package/src/hooks/use-turn-queue.ts +2 -1
- package/src/hooks/use-usage.ts +100 -0
- package/src/hooks/use-vaults.ts +153 -0
- package/src/hooks/use-video-artifact-playback.ts +1 -1
- package/src/hooks/use-voice-input.ts +127 -19
- package/src/hooks/use-workspace-capture.ts +3 -2
- package/src/hooks/use-workspace-edit.ts +23 -5
- package/src/hooks/use-workspace-sessions.ts +74 -7
- package/src/human-input-model.ts +359 -0
- package/src/identity-link-accounts.tsx +148 -0
- package/src/identity-link-consent.tsx +192 -0
- package/src/index.ts +262 -16
- package/src/interaction.ts +1 -0
- package/src/lib/clipboard.ts +29 -0
- package/src/lib/error-message.ts +37 -0
- package/src/lib/format.ts +205 -10
- package/src/lib/host-theme.ts +529 -0
- package/src/lib/interaction-errors.ts +15 -0
- package/src/lib/menu-styles.ts +44 -0
- package/src/lib/notify-observer.ts +15 -0
- package/src/lib/pierre-diffs-loader.ts +53 -0
- package/src/lib/provider-recovery.ts +243 -0
- package/src/lib/scrollbars.ts +30 -0
- package/src/lib/terminal-input-readiness.ts +51 -0
- package/src/lib/transient-retry.ts +99 -0
- package/src/lib/workbench-peers.ts +62 -0
- package/src/lib/xterm-theme.ts +23 -21
- package/src/mcp-connection-status.ts +35 -0
- package/src/model-mark-paths.ts +53 -0
- package/src/model-picker-model.ts +330 -0
- package/src/model-policy.ts +299 -74
- package/src/native-previews.ts +100 -0
- package/src/new-session-draft.ts +22 -0
- package/src/notification-text.ts +81 -0
- package/src/older-history.ts +22 -4
- package/src/organization-model.ts +118 -0
- package/src/plugin-details.tsx +185 -0
- package/src/plugin-discovery.tsx +196 -0
- package/src/preview-loading-paint.ts +68 -0
- package/src/provider.tsx +74 -15
- package/src/queue-presentation-model.ts +464 -0
- package/src/realtime/dropdown-menu.tsx +19 -12
- package/src/realtime/embedded-new-voice.tsx +1 -0
- package/src/realtime/embedded-voice.tsx +3 -0
- package/src/realtime/realtime-control.tsx +138 -550
- package/src/realtime/session-realtime.ts +566 -0
- package/src/sandbox-label-model.ts +53 -0
- package/src/scrollbars.ts +3 -0
- package/src/secret-reference-label.ts +43 -0
- package/src/secrets-ui.tsx +59 -0
- package/src/session-agents-model.ts +33 -0
- package/src/session-attention-model.ts +62 -0
- package/src/session-auth-recommendation.ts +48 -0
- package/src/session-capability-policy.ts +196 -0
- package/src/session-context.ts +3 -4
- package/src/session-feedback-model.ts +95 -0
- package/src/session-list-model.ts +434 -0
- package/src/session-realtime.ts +18 -0
- package/src/session-status-model.ts +99 -0
- package/src/session-ui.ts +98 -1
- package/src/session.ts +17 -1
- package/src/site-snapshot.ts +74 -0
- package/src/sites-ui.tsx +348 -0
- package/src/sites.ts +3 -0
- package/src/skill-discovery.tsx +208 -0
- package/src/terminal.ts +26 -0
- package/src/testing/session-scenarios.ts +404 -0
- package/src/timeline/activity-rail.tsx +242 -101
- package/src/timeline/agent-identity.tsx +84 -0
- package/src/timeline/agent-row.tsx +231 -0
- package/src/timeline/allowance-exhausted-row.tsx +86 -0
- package/src/timeline/compaction-copy.ts +115 -0
- package/src/timeline/fleet-decision-projection.ts +2 -1
- package/src/timeline/fleet-decision-row.tsx +1 -0
- package/src/timeline/focus-sequence.ts +44 -0
- package/src/timeline/genie-copy.ts +19 -0
- package/src/timeline/genie-loading.tsx +143 -0
- package/src/timeline/index.ts +30 -2
- package/src/timeline/knowledge-receipt.tsx +100 -0
- package/src/timeline/message-sender.tsx +71 -0
- package/src/timeline/notice-presentation.ts +48 -0
- package/src/timeline/parsers.ts +42 -2
- package/src/timeline/patch-apply-command.tsx +135 -0
- package/src/timeline/platform-activity-presentation.ts +166 -0
- package/src/timeline/platform-activity-row.tsx +15 -90
- package/src/timeline/presented-image.ts +63 -0
- package/src/timeline/projection.ts +1742 -76
- package/src/timeline/provider-logo.tsx +53 -0
- package/src/timeline/question-nav-model.ts +28 -0
- package/src/timeline/registry.ts +26 -4
- package/src/timeline/retained-image.ts +97 -0
- package/src/timeline/retained-loaders.ts +91 -0
- package/src/timeline/rolling-activity.tsx +80 -0
- package/src/timeline/screenshot-lightbox.tsx +228 -5
- package/src/timeline/session-usage-limit-row.tsx +42 -0
- package/src/timeline/shared.tsx +42 -15
- package/src/timeline/startup-dispatch-details.tsx +36 -0
- package/src/timeline/startup-preference.ts +33 -0
- package/src/timeline/startup-timings.tsx +145 -0
- package/src/timeline/tool-display-name.ts +19 -7
- package/src/timeline/tool-presentation.ts +1316 -0
- package/src/timeline/tool-renderers.tsx +835 -1138
- package/src/timeline/turn-summary-model.ts +343 -0
- package/src/timeline/turn-summary.tsx +272 -365
- package/src/timeline/types.ts +189 -6
- package/src/timeline/work-presentation.ts +189 -0
- package/src/timeline-model.ts +143 -0
- package/src/usage/allowance-copy.ts +64 -0
- package/src/usage/session-usage-limit.ts +266 -0
- package/src/usage/summary.ts +93 -0
- package/src/usage.ts +70 -0
- package/src/voice-recording-owner.ts +22 -0
- package/styles/compiled.css +2319 -748
- package/styles/connect.css +290 -0
- package/styles/connect.d.ts +1 -0
- package/styles/effective-tokens.css +1 -0
- package/styles/index.css +309 -9
- package/styles/responsive.css +99 -7
- package/styles/session-capability.css +44 -0
- package/styles/tokens.css +134 -66
- package/dist/browser-viewer-MKKFRRRV.js +0 -14
- package/dist/chunk-2DZVYHVO.js +0 -470
- package/dist/chunk-2DZVYHVO.js.map +0 -1
- package/dist/chunk-3AGBGTRT.js.map +0 -1
- package/dist/chunk-4MDLEHXL.js.map +0 -1
- package/dist/chunk-5YK2ZDIG.js.map +0 -1
- package/dist/chunk-7EAFGICR.js +0 -302
- package/dist/chunk-7EAFGICR.js.map +0 -1
- package/dist/chunk-ELIYWBZR.js.map +0 -1
- package/dist/chunk-H5YGYNXS.js.map +0 -1
- package/dist/chunk-HUIKIDM5.js.map +0 -1
- package/dist/chunk-ICA6R6TW.js.map +0 -1
- package/dist/chunk-IOLVN74D.js.map +0 -1
- package/dist/chunk-JAQ5K7W6.js.map +0 -1
- package/dist/chunk-JVYQRRC4.js.map +0 -1
- package/dist/chunk-KCGXPP5V.js.map +0 -1
- package/dist/chunk-KZ73RL76.js.map +0 -1
- package/dist/chunk-NEXLLTP4.js.map +0 -1
- package/dist/chunk-PEI6RANI.js.map +0 -1
- package/dist/chunk-VTOREEXF.js +0 -142
- package/dist/chunk-VTOREEXF.js.map +0 -1
- package/dist/chunk-WSK7G5LE.js +0 -170
- package/dist/chunk-WSK7G5LE.js.map +0 -1
- package/dist/chunk-X4A66EWZ.js +0 -223
- package/dist/chunk-X4A66EWZ.js.map +0 -1
- package/dist/chunk-XYRDDSXF.js.map +0 -1
- package/dist/chunk-YG4QEQF5.js +0 -9557
- package/dist/chunk-YG4QEQF5.js.map +0 -1
- package/dist/chunk-YVCHAQZY.js.map +0 -1
- package/dist/chunk-ZPBTI3TE.js.map +0 -1
- package/dist/computer-viewer-FWEZISW4.js +0 -16
- package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
- package/dist/hooks/use-environments.d.ts +0 -41
- package/dist/hooks/use-packs.d.ts +0 -32
- package/dist/platform-activity-row-BJHUHXAT.js.map +0 -1
- package/dist/queue-surface-implementation-BSKUWHRI.js.map +0 -1
- package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
- package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
- package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
- package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
- package/src/hooks/use-environments.ts +0 -182
- package/src/hooks/use-packs.ts +0 -157
- /package/dist/{browser-viewer-MKKFRRRV.js.map → browser-viewer-ZWR6MWJ7.js.map} +0 -0
- /package/dist/{computer-viewer-FWEZISW4.js.map → chat-interactive-block-4EUKJXUO.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-terminal-stream.ts","../src/lib/terminal-input-readiness.ts","../src/lib/xterm-theme.ts","../src/components/sandbox-terminal.tsx","../src/lib/terminal-capability.ts","../src/lib/xterm-renderer.ts"],"sourcesContent":["import {\n TTYD_SUBPROTOCOL,\n TerminalCapability,\n terminalSocketUrl,\n ttydAuthFrame,\n ttydInputFrame,\n ttydResizeFrame,\n TtydServerCommand,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n decodeStreamFrame,\n decodeStreamOpenAck,\n encodeStreamFrame,\n encodeStreamOpen,\n type RelayChannel,\n STREAM_KIND_PTY,\n STREAM_ROLE_CLIENT,\n} from \"../lib/relay-wire\";\nimport {\n TERMINAL_INPUT_READY_PREFERENCE,\n TERMINAL_INPUT_READY_PROTOCOL,\n terminalInputReadyDecoder,\n} from \"../lib/terminal-input-readiness\";\n\n/** The ttyd connection lifecycle as surfaced to the component. */\nexport type TerminalStreamStatus = \"connecting\" | \"open\" | \"closed\" | \"error\";\n\nexport type UseTerminalStreamOptions = {\n /** The Terminal cell of the negotiated capabilities (`capabilities.Terminal`).\n * The stream connects ONLY when `transport === \"pty-ws\"` and `url` is set; on a\n * cold box (`transport === \"sse-events\"` / no url) it stays idle and the caller\n * falls back to the Channel-A firehose. Explicit PTY-capable cold cells may\n * buffer input, but cannot connect or flush until the grant arrives. */\n capability:\n | (Pick<TerminalCapability, \"transport\" | \"url\" | \"token\" | \"expiresAt\"> &\n Partial<Pick<TerminalCapability, \"ptyCapable\" | \"reason\">>)\n | null;\n /** Called for each OUTPUT payload from ttyd (write verbatim into xterm). */\n onOutput?: ((data: string) => void) | undefined;\n /** Called when ttyd sends a SET_WINDOW_TITLE frame. */\n onTitle?: ((title: string) => void) | undefined;\n /** Requests a fresh negotiated terminal grant after an unexpected transport\n * failure. Intentional disconnects and effect cleanup never call it. */\n onReconnectNeeded?: (() => void) | undefined;\n /** Initial PTY size to seed the ttyd auth frame + first resize. */\n initialCols?: number | undefined;\n initialRows?: number | undefined;\n};\n\nexport type UseTerminalStreamResult = {\n /** True when input can be sent. Legacy ttyd does not guarantee shell readiness. */\n connected: boolean;\n status: TerminalStreamStatus;\n /** `waiting` requires explicit shell readiness; `legacy` has no such guarantee. */\n inputReadiness: \"pending\" | \"waiting\" | \"ready\" | \"legacy\";\n /** Deliberate escape for startup prompts/no-Readline shells. Clears queued\n * typing without executing it, then enables unguaranteed manual input. */\n useLegacyInput: () => void;\n /** Pipe a keystroke/paste to PTY stdin. Input during CONNECTING is bounded and\n * replayed after negotiated readiness (or legacy ttyd preferences). */\n write: (data: string) => void;\n /** Tell ttyd the PTY window changed size (on xterm fit/resize). */\n resize: (cols: number, rows: number) => void;\n /** Tear the socket down (the effect also tears down on unmount / url change). */\n disconnect: () => void;\n};\n\n// Keystrokes entered during startup are held until the negotiated input boundary.\n// Old ttyd servers retain explicitly legacy semantics. Bound by UTF-16 code units (a hard\n// <=128 KiB string payload in current JS engines) so a paste cannot turn a slow\n// handshake into unbounded renderer memory. Overflow rejects the whole pending\n// input rather than ever executing a truncated shell command.\nexport const MAX_PENDING_TERMINAL_INPUT_CODE_UNITS = 64 * 1024;\nconst TERMINAL_CONNECT_EXPIRY_SKEW_MS = 5_000;\nconst TERMINAL_RECONNECT_INITIAL_MS = 100;\nconst TERMINAL_RECONNECT_MAX_MS = 3_000;\nconst RELAY_TAG_OPEN = 1;\nconst RELAY_TAG_OPEN_ACK = 2;\nconst RELAY_TAG_FRAME = 3;\n\nfunction relayDatagram(tag: number, body: Uint8Array): ArrayBuffer {\n const bytes = new Uint8Array(body.length + 1);\n bytes[0] = tag;\n bytes.set(body, 1);\n return bytes.buffer;\n}\n\nfunction relayChannelFromUrl(url: string): RelayChannel {\n const endpoint = new URL(url);\n const channel: RelayChannel = {\n channelId: endpoint.searchParams.get(\"channel\") ?? \"\",\n workspaceId: endpoint.searchParams.get(\"ws\") ?? \"\",\n agentId: endpoint.searchParams.get(\"agent\") ?? \"\",\n kind: STREAM_KIND_PTY,\n port: Number(endpoint.searchParams.get(\"port\") ?? \"0\"),\n };\n if (\n !channel.channelId ||\n !channel.workspaceId ||\n !channel.agentId ||\n !Number.isSafeInteger(channel.port) ||\n channel.port <= 0\n ) {\n throw new Error(\"terminal relay endpoint is incomplete\");\n }\n return channel;\n}\n\nfunction sendRelayInput(\n socket: WebSocket,\n channel: RelayChannel,\n sequence: bigint,\n data: string,\n): void {\n socket.send(\n relayDatagram(\n RELAY_TAG_FRAME,\n encodeStreamFrame({\n channelId: channel.channelId,\n seq: sequence.toString(),\n data: new TextEncoder().encode(data),\n producedAtMs: String(Date.now()),\n }),\n ),\n );\n}\n\n/** A bearer must remain valid long enough to finish a new websocket handshake.\n * Existing open sockets are unaffected: this is evaluated only when the\n * credential identity changes and the connection effect attempts a new socket. */\nexport function terminalStreamCredentialUsable(\n capability: Pick<TerminalCapability, \"transport\" | \"url\" | \"expiresAt\"> | null | undefined,\n nowMs = Date.now(),\n): boolean {\n if (\n (capability?.transport !== \"pty-ws\" && capability?.transport !== \"relay-pty\") ||\n !capability.url\n ) {\n return false;\n }\n if (!capability.expiresAt) return true;\n const expiresAt = Date.parse(capability.expiresAt);\n return Number.isFinite(expiresAt) && expiresAt > nowMs + TERMINAL_CONNECT_EXPIRY_SKEW_MS;\n}\n\n/** Decode an inbound ttyd frame's payload (everything after the 1-char command).\n * ttyd may send either a text frame (string) or a binary frame (ArrayBuffer);\n * for binary we slice off the first byte (the command) and utf-8 decode the rest. */\nfunction decodeFrame(data: string | ArrayBuffer): { command: string; payload: string } {\n if (typeof data === \"string\") {\n return { command: data.charAt(0), payload: data.slice(1) };\n }\n const bytes = new Uint8Array(data);\n const command = bytes.length > 0 ? String.fromCharCode(bytes[0]!) : \"\";\n const payload = bytes.length > 1 ? new TextDecoder().decode(bytes.subarray(1)) : \"\";\n return { command, payload };\n}\n\nfunction closeSocket(socket: WebSocket | null): void {\n try {\n socket?.close();\n } catch {\n // Already closed or rejected by the host WebSocket implementation.\n }\n}\n\n/**\n * Drive a ttyd PTY-over-websocket connection from a `pty-ws` Terminal capability,\n * symmetric with `use-desktop-stream` (the noVNC-over-tunnel hook). The scoped\n * stream token is already embedded in the minted tunnel `url`; the WebSocket is\n * opened with the REQUIRED ttyd subprotocol \"tty\".\n *\n * ttyd wire protocol (see `@opengeni/sdk/terminal`):\n * - first frame: `JSON.stringify({ AuthToken: \"\" })` (+ optional columns/rows).\n * - client→server: INPUT = \"0\"+data ; RESIZE = \"1\"+JSON({columns,rows}).\n * - server→client: \"0\" = OUTPUT (→ xterm) ; \"1\" = SET_WINDOW_TITLE ;\n * \"2\" = SET_PREFERENCES (readiness negotiation). Binary frames decode identically.\n *\n * On a `url`/`token` rotation (a box rollover folds a fresh address into the cell)\n * the effect re-runs: the old socket closes and a fresh one connects — a brief\n * terminal blink, acceptable on rollover (mirrors the desktop's RFB hot-swap).\n * SSR-safe: the socket open lives in `useEffect`, so a server render is a no-op.\n */\nexport function useTerminalStream(options: UseTerminalStreamOptions): UseTerminalStreamResult {\n const { capability, onOutput, onTitle, onReconnectNeeded, initialCols, initialRows } = options;\n const [status, setStatus] = useState<TerminalStreamStatus>(\"closed\");\n const [inputReadiness, setInputReadiness] =\n useState<UseTerminalStreamResult[\"inputReadiness\"]>(\"pending\");\n const [reconnectGeneration, setReconnectGeneration] = useState(0);\n const wsRef = useRef<WebSocket | null>(null);\n const pendingInputRef = useRef(\"\");\n const socketFailedRef = useRef(false);\n const socketAuthenticatedRef = useRef(false);\n const legacyInputRef = useRef<(() => void) | null>(null);\n const manuallyDisconnectedRef = useRef(false);\n const relayChannelRef = useRef<RelayChannel | null>(null);\n const relayIdentityRef = useRef<string | null>(null);\n const relayInputSequenceRef = useRef(0n);\n const relayOutputSequenceRef = useRef(0n);\n const reconnectAttemptRef = useRef(0);\n const credentialIdentityRef = useRef<string | null>(null);\n const refreshRequestedRef = useRef(false);\n const intentionalCloseRef = useRef<WeakSet<WebSocket>>(new WeakSet());\n // Latest size, so a resize() before the socket opens is replayed on open, and a\n // reconnect seeds the right geometry.\n const sizeRef = useRef<{ cols: number; rows: number }>({\n cols: initialCols ?? 80,\n rows: initialRows ?? 24,\n });\n // Keep the callbacks current without re-running the connect effect on every\n // render (the parent passes fresh closures each time).\n const onOutputRef = useRef(onOutput);\n const onTitleRef = useRef(onTitle);\n const onReconnectNeededRef = useRef(onReconnectNeeded);\n onOutputRef.current = onOutput;\n onTitleRef.current = onTitle;\n onReconnectNeededRef.current = onReconnectNeeded;\n\n const transport = capability?.transport ?? null;\n const url = capability?.url ?? null;\n const token = capability?.token ?? null;\n const expiresAt = capability?.expiresAt ?? null;\n const transportRef = useRef(transport);\n transportRef.current = transport;\n // A cold, explicitly PTY-capable cell may collect input before its viewer\n // grant arrives. This is not a socket credential or a readiness assertion.\n const acquiringPty =\n transport === \"sse-events\" &&\n capability?.ptyCapable === true &&\n (capability.reason === \"lease_cold\" || capability.reason === \"not_provisioned\");\n const acquiringPtyRef = useRef(acquiringPty);\n acquiringPtyRef.current = acquiringPty;\n\n useEffect(() => {\n manuallyDisconnectedRef.current = false;\n setInputReadiness(\"pending\");\n // SSR / no WebSocket / not a live pty-ws cell: stay closed; the caller falls\n // back to the Channel-A read-only firehose.\n if (typeof window === \"undefined\" || typeof WebSocket === \"undefined\") return;\n const relay = transport === \"relay-pty\";\n if (transport !== \"pty-ws\" && !relay) {\n // A transport downgrade is a real semantic boundary. Do not replay input\n // captured for a PTY if this surface later changes back from firehose mode.\n pendingInputRef.current = \"\";\n socketAuthenticatedRef.current = false;\n relayIdentityRef.current = null;\n relayInputSequenceRef.current = 0n;\n relayOutputSequenceRef.current = 0n;\n reconnectAttemptRef.current = 0;\n credentialIdentityRef.current = null;\n refreshRequestedRef.current = false;\n socketFailedRef.current = false;\n setStatus(\"closed\");\n return;\n }\n const credentialIdentity = `${transport}\\u0000${url ?? \"\"}\\u0000${token ?? \"\"}\\u0000${expiresAt ?? \"\"}`;\n if (credentialIdentityRef.current !== credentialIdentity) {\n credentialIdentityRef.current = credentialIdentity;\n reconnectAttemptRef.current = 0;\n refreshRequestedRef.current = false;\n }\n // A changed/cleared credential is a new connection attempt boundary. It may\n // receive input while its exact grant is pending even if the prior socket\n // failed; the unchanged failed identity remains fenced because this effect\n // does not re-run for a status-only render.\n socketFailedRef.current = false;\n socketAuthenticatedRef.current = false;\n if (!url) {\n // Exact grants arrive asynchronously. Preserve the bounded first input\n // while the descriptor remains pty-ws, but never open without a credential.\n setStatus(\"closed\");\n return;\n }\n if (!terminalStreamCredentialUsable({ transport, url, expiresAt })) {\n // A descriptor from an older rolling server may still carry a bearer that\n // aged out before this surface mounted. Ask once for the exact fresh grant.\n setStatus(\"closed\");\n if (!refreshRequestedRef.current) {\n refreshRequestedRef.current = true;\n onReconnectNeededRef.current?.();\n }\n return;\n }\n\n let disposed = false;\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let socket: WebSocket;\n let relayChannel: RelayChannel | null = null;\n let authSent = false;\n let preferencesReceived = false;\n let readinessNegotiated = false;\n let sentSize: { cols: number; rows: number } | null = null;\n const decodeReadyOutput = terminalInputReadyDecoder();\n const relayOutputDecoder = new TextDecoder();\n setStatus(\"connecting\");\n try {\n if (relay) {\n relayChannel = relayChannelFromUrl(url);\n const relayIdentity = [\n relayChannel.workspaceId,\n relayChannel.agentId,\n relayChannel.port,\n relayChannel.channelId,\n ].join(\"\\u0000\");\n if (relayIdentityRef.current !== relayIdentity) {\n relayIdentityRef.current = relayIdentity;\n relayInputSequenceRef.current = 0n;\n relayOutputSequenceRef.current = 0n;\n }\n relayChannelRef.current = relayChannel;\n socket = new WebSocket(url);\n } else {\n // The ttyd \"tty\" subprotocol is REQUIRED — ttyd rejects a handshake without\n // it. The scoped token is already in the tunnel `url`.\n socket = new WebSocket(terminalSocketUrl({ url }), TTYD_SUBPROTOCOL);\n }\n } catch {\n socketFailedRef.current = true;\n setStatus(\"error\");\n return;\n }\n socket.binaryType = \"arraybuffer\";\n wsRef.current = socket;\n\n const requestFreshGrant = () => {\n if (disposed || refreshRequestedRef.current || intentionalCloseRef.current.has(socket))\n return;\n refreshRequestedRef.current = true;\n onReconnectNeededRef.current?.();\n };\n\n const scheduleTransportReconnect = () => {\n if (disposed || reconnectTimer !== null || intentionalCloseRef.current.has(socket)) return;\n if (refreshRequestedRef.current) return;\n if (!terminalStreamCredentialUsable({ transport, url, expiresAt })) {\n requestFreshGrant();\n return;\n }\n const attempt = reconnectAttemptRef.current++;\n const delay = Math.min(\n TERMINAL_RECONNECT_INITIAL_MS * 2 ** Math.min(attempt, 8),\n TERMINAL_RECONNECT_MAX_MS,\n );\n setStatus(\"connecting\");\n reconnectTimer = setTimeout(() => {\n reconnectTimer = null;\n if (!disposed && !manuallyDisconnectedRef.current)\n setReconnectGeneration((generation) => generation + 1);\n }, delay);\n };\n\n const openTtydInput = (mode: \"ready\" | \"legacy\", discardPending = false) => {\n if (\n disposed ||\n wsRef.current !== socket ||\n socket.readyState !== WebSocket.OPEN ||\n !authSent ||\n socketFailedRef.current\n )\n return;\n if (discardPending) pendingInputRef.current = \"\";\n try {\n // A fit/resize may have happened while shell readiness was pending.\n if (sentSize?.cols !== sizeRef.current.cols || sentSize.rows !== sizeRef.current.rows) {\n socket.send(ttydResizeFrame(sizeRef.current.cols, sizeRef.current.rows));\n sentSize = { ...sizeRef.current };\n }\n if (pendingInputRef.current.length > 0) {\n socket.send(ttydInputFrame(pendingInputRef.current));\n pendingInputRef.current = \"\";\n }\n socketAuthenticatedRef.current = true;\n legacyInputRef.current = null;\n setInputReadiness(mode);\n setStatus(\"open\");\n reconnectAttemptRef.current = 0;\n refreshRequestedRef.current = false;\n } catch {\n socketAuthenticatedRef.current = false;\n setInputReadiness(\"pending\");\n setStatus(\"connecting\");\n closeSocket(socket);\n }\n };\n\n socket.onopen = () => {\n if (disposed || wsRef.current !== socket || socketFailedRef.current) return;\n if (relay && relayChannel) {\n try {\n socket.send(\n relayDatagram(\n RELAY_TAG_OPEN,\n encodeStreamOpen({\n channel: relayChannel,\n token: token ?? \"\",\n role: STREAM_ROLE_CLIENT,\n resumeFromSeq: relayOutputSequenceRef.current.toString(),\n }),\n ),\n );\n } catch {\n socketFailedRef.current = false;\n setStatus(\"connecting\");\n closeSocket(socket);\n }\n return;\n }\n // ttyd's required first frame: the auth message (empty token — the gate is\n // the tunnel url + scoped stream token, not a ttyd -c credential), seeded\n // with the current PTY geometry. Then an explicit resize to be safe.\n try {\n socket.send(ttydAuthFrame({ columns: sizeRef.current.cols, rows: sizeRef.current.rows }));\n socket.send(ttydResizeFrame(sizeRef.current.cols, sizeRef.current.rows));\n sentSize = { ...sizeRef.current };\n authSent = true;\n } catch {\n socketFailedRef.current = false;\n setStatus(\"connecting\");\n closeSocket(socket);\n return;\n }\n };\n\n socket.onmessage = (ev: MessageEvent) => {\n if (disposed || wsRef.current !== socket || socketFailedRef.current) return;\n if (relay) {\n if (!(ev.data instanceof ArrayBuffer) || !relayChannel) return;\n const bytes = new Uint8Array(ev.data);\n if (bytes.length < 1) return;\n const tag = bytes[0];\n const body = bytes.subarray(1);\n if (tag === RELAY_TAG_OPEN_ACK) {\n try {\n const ack = decodeStreamOpenAck(body);\n if (!ack.accepted) throw new Error(ack.error?.message ?? \"terminal relay rejected\");\n reconnectAttemptRef.current = 0;\n refreshRequestedRef.current = false;\n socketAuthenticatedRef.current = true;\n if (pendingInputRef.current.length > 0) {\n sendRelayInput(\n socket,\n relayChannel,\n relayInputSequenceRef.current++,\n pendingInputRef.current,\n );\n pendingInputRef.current = \"\";\n }\n setStatus(\"open\");\n setInputReadiness(\"ready\");\n } catch {\n socketFailedRef.current = true;\n setStatus(\"error\");\n requestFreshGrant();\n closeSocket(socket);\n }\n } else if (tag === RELAY_TAG_FRAME && socketAuthenticatedRef.current) {\n try {\n const frame = decodeStreamFrame(body);\n const sequence = BigInt(frame.seq);\n if (sequence < relayOutputSequenceRef.current) return;\n relayOutputSequenceRef.current = sequence + 1n;\n if (frame.data.length > 0) {\n onOutputRef.current?.(relayOutputDecoder.decode(frame.data, { stream: true }));\n }\n } catch {\n // Ignore one malformed frame; the live PTY remains usable.\n }\n }\n return;\n }\n const { command, payload } = decodeFrame(ev.data as string | ArrayBuffer);\n switch (command) {\n case TtydServerCommand.OUTPUT:\n if (readinessNegotiated) {\n const decoded = decodeReadyOutput(payload);\n if (decoded.output) onOutputRef.current?.(decoded.output);\n if (decoded.ready && !socketAuthenticatedRef.current) openTtydInput(\"ready\");\n } else {\n onOutputRef.current?.(payload);\n }\n break;\n case TtydServerCommand.SET_WINDOW_TITLE:\n onTitleRef.current?.(payload);\n break;\n case TtydServerCommand.SET_PREFERENCES:\n if (!authSent || preferencesReceived || socketAuthenticatedRef.current) break;\n preferencesReceived = true;\n try {\n const preferences = JSON.parse(payload) as Record<string, unknown>;\n if (!preferences || typeof preferences !== \"object\" || Array.isArray(preferences)) {\n throw new Error(\"invalid ttyd preferences\");\n }\n const protocol = preferences[TERMINAL_INPUT_READY_PREFERENCE];\n if (protocol === undefined) {\n // Old images/running daemons do not acquire a guarantee merely\n // because this client is new. Preserve their legacy input path.\n openTtydInput(\"legacy\");\n } else {\n readinessNegotiated = protocol === TERMINAL_INPUT_READY_PROTOCOL;\n setInputReadiness(\"waiting\");\n legacyInputRef.current = () => openTtydInput(\"legacy\", true);\n }\n } catch {\n // Invalid negotiation is not readiness. Manual input remains a\n // deliberate escape, never an automatic fallback or timer flush.\n setInputReadiness(\"waiting\");\n legacyInputRef.current = () => openTtydInput(\"legacy\", true);\n }\n break;\n default:\n break;\n }\n };\n\n socket.onerror = () => {\n if (!disposed && wsRef.current === socket && !intentionalCloseRef.current.has(socket)) {\n // A network/relay outage is retryable with the same credential and PTY.\n // Keep accepting bounded input while the transport comes back.\n socketFailedRef.current = false;\n setStatus(\"connecting\");\n closeSocket(socket);\n }\n };\n socket.onclose = () => {\n if (disposed || wsRef.current !== socket) return;\n if (wsRef.current === socket) wsRef.current = null;\n socketAuthenticatedRef.current = false;\n legacyInputRef.current = null;\n setInputReadiness(\"pending\");\n if (!disposed) {\n if (socketFailedRef.current) setStatus(\"error\");\n else scheduleTransportReconnect();\n }\n };\n\n return () => {\n disposed = true;\n wsRef.current = null;\n socketAuthenticatedRef.current = false;\n legacyInputRef.current = null;\n relayChannelRef.current = null;\n if (reconnectTimer !== null) clearTimeout(reconnectTimer);\n // Drop handlers so an in-flight close/error doesn't mutate state post-unmount.\n socket.onopen = null;\n socket.onmessage = null;\n socket.onerror = null;\n socket.onclose = null;\n closeSocket(socket);\n };\n // A url/token change (rotation) re-runs this effect → close old, open new.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [transport, url, token, expiresAt, acquiringPty, reconnectGeneration]);\n\n const write = useCallback((data: string) => {\n const currentTransport = transportRef.current;\n const ws = wsRef.current;\n if (ws && ws.readyState === WebSocket.OPEN && socketAuthenticatedRef.current) {\n try {\n const relayChannel = relayChannelRef.current;\n if (currentTransport === \"relay-pty\" && relayChannel) {\n sendRelayInput(ws, relayChannel, relayInputSequenceRef.current++, data);\n } else {\n ws.send(ttydInputFrame(data));\n }\n } catch {\n // A synchronous ttyd send failure did not enqueue these bytes. Retain\n // them for the next explicit readiness boundary, never replay a send\n // which returned successfully. Relay sequencing keeps its own contract.\n if (currentTransport === \"pty-ws\") {\n const nextSize = pendingInputRef.current.length + data.length;\n if (nextSize > MAX_PENDING_TERMINAL_INPUT_CODE_UNITS) {\n pendingInputRef.current = \"\";\n socketFailedRef.current = true;\n socketAuthenticatedRef.current = false;\n setStatus(\"error\");\n closeSocket(ws);\n return;\n }\n pendingInputRef.current += data;\n }\n socketAuthenticatedRef.current = false;\n socketFailedRef.current = false;\n setStatus(\"connecting\");\n closeSocket(ws);\n }\n } else if (\n (currentTransport === \"pty-ws\" ||\n currentTransport === \"relay-pty\" ||\n acquiringPtyRef.current) &&\n !socketFailedRef.current\n ) {\n const nextSize = pendingInputRef.current.length + data.length;\n if (nextSize > MAX_PENDING_TERMINAL_INPUT_CODE_UNITS) {\n pendingInputRef.current = \"\";\n socketFailedRef.current = true;\n setStatus(\"error\");\n closeSocket(ws);\n return;\n }\n pendingInputRef.current += data;\n }\n }, []);\n const resize = useCallback((cols: number, rows: number) => {\n if (cols <= 0 || rows <= 0) return;\n sizeRef.current = { cols, rows };\n const ws = wsRef.current;\n if (ws && ws.readyState === WebSocket.OPEN && socketAuthenticatedRef.current) {\n try {\n // Self-hosted relay PTYs carry raw input/output frames. Resize remains\n // an out-of-band control operation; do not send ttyd framing into them.\n if (transportRef.current === \"pty-ws\") ws.send(ttydResizeFrame(cols, rows));\n } catch {\n // socket raced closed — geometry is replayed on the next open.\n }\n }\n }, []);\n const disconnect = useCallback(() => {\n manuallyDisconnectedRef.current = true;\n const ws = wsRef.current;\n wsRef.current = null;\n pendingInputRef.current = \"\";\n socketFailedRef.current = false;\n socketAuthenticatedRef.current = false;\n legacyInputRef.current = null;\n relayChannelRef.current = null;\n setStatus(\"closed\");\n setInputReadiness(\"pending\");\n if (ws) intentionalCloseRef.current.add(ws);\n closeSocket(ws);\n }, []);\n const useLegacyInput = useCallback(() => legacyInputRef.current?.(), []);\n\n return useMemo<UseTerminalStreamResult>(() => {\n return {\n connected: status === \"open\",\n status,\n inputReadiness,\n useLegacyInput,\n write,\n resize,\n disconnect,\n };\n }, [status, inputReadiness, useLegacyInput, write, resize, disconnect]);\n}\n","/** Negotiated by the stock ttyd launcher, never inferred from ordinary output.\n * The Bash Readline adapter emits this OSC only at its first input boundary.\n * It is metadata (ignored by older xterm clients), not a prompt string. */\nexport const TERMINAL_INPUT_READY_PREFERENCE = \"opengeniInputReady\";\nexport const TERMINAL_INPUT_READY_PROTOCOL = \"bash-readline-v1\";\nconst PREFIX = \"\\x1b]777;opengeni-input;\";\nconst FRAME = /^\\x1b\\]777;opengeni-input;(hello|ready);([a-f0-9]{32})\\x07$/;\nconst MAX_FRAME = PREFIX.length + \"hello;\".length + 32 + 1;\n\n/** One decoder per WebSocket/PTY generation. Retains at most a partial marker,\n * rather than buffering terminal output while the shell initializes. */\nexport function terminalInputReadyDecoder() {\n let pending = \"\";\n let received = false;\n let identity: string | null = null;\n return (data: string): { output: string; ready: boolean } => {\n let input = pending + data;\n let output = \"\";\n let ready = false;\n pending = \"\";\n while (input.length > 0) {\n const marker = input.indexOf(PREFIX);\n if (marker < 0) break;\n output += input.slice(0, marker);\n input = input.slice(marker);\n const end = input.indexOf(\"\\x07\", PREFIX.length);\n if (end < 0 && input.length < MAX_FRAME) {\n pending = input;\n return { output, ready };\n }\n const match = end >= 0 && end < MAX_FRAME ? FRAME.exec(input.slice(0, end + 1)) : null;\n if (!match) {\n // Malformed/overlong metadata is ordinary output, never an unbounded\n // parser buffer or permission to deliver input.\n output += input[0];\n input = input.slice(1);\n continue;\n }\n input = input.slice(end + 1);\n if (match[1] === \"hello\" && identity === null) identity = match[2]!;\n if (match[1] === \"ready\" && match[2] === identity && !received) {\n ready = true;\n received = true;\n }\n }\n let suffix = Math.min(input.length, PREFIX.length - 1);\n while (suffix > 0 && !PREFIX.startsWith(input.slice(-suffix))) suffix--;\n pending = suffix > 0 ? input.slice(-suffix) : \"\";\n return { output: output + (suffix > 0 ? input.slice(0, -suffix) : input), ready };\n };\n}\n","import type { XtermTheme } from \"../components/sandbox-terminal\";\n\n/* ----------------------------------------------------------------------------\n xterm theming + font resolution from the `--og-*` token system.\n\n xterm paints glyphs into a canvas (WebGL / 2D) and builds its font strings by\n hand, so it can consume NEITHER CSS custom properties (`var(--og-font-mono)`\n never resolves in a canvas font string) NOR a partial palette (an unset ANSI\n slot falls back to xterm's stock VGA color). This module resolves both to\n concrete values: a full 16-color ANSI ITheme designed against the og palette\n for BOTH themes, and a concrete monospace family + px size.\n\n The color-building + font-resolution cores are pure over a token `read`\n function so they unit-test without a DOM; thin `*FromTokens` / `resolve*`\n wrappers do the `getComputedStyle` read on the client.\n -------------------------------------------------------------------------- */\n\nexport type ThemeMode = \"dark\" | \"light\";\n\n/** Reads a resolved token value (already `getComputedStyle`-flattened). */\nexport type TokenReader = (name: string) => string | undefined;\n\n/**\n * The 16 ANSI colors + selection/cursor treatment, designed against the og\n * OKLCH palette. Hues are borrowed from the og status ramp so terminal color\n * reads as part of the same system: red≈status-failed(22), green≈status-idle\n * (155), yellow≈status-running(80), magenta(305), cyan≈200. The ANSI blue and\n * magenta slots stay chromatic because program output means them; the app\n * chrome around the terminal is neutral. Dark uses lifted lightness on the\n * dark neutral ground; light uses deeper, more saturated inks on the\n * near-white ground. Bright variants add lightness + a touch of chroma.\n * `black`/`white` and the selection are neutral grey ramp stops (never pure\n * #000/#fff — that clashes with the calm neutral ground).\n */\nexport type AnsiPalette = {\n black: string;\n red: string;\n green: string;\n yellow: string;\n blue: string;\n magenta: string;\n cyan: string;\n white: string;\n brightBlack: string;\n brightRed: string;\n brightGreen: string;\n brightYellow: string;\n brightBlue: string;\n brightMagenta: string;\n brightCyan: string;\n brightWhite: string;\n /** Selection wash + its foreground; sits over the terminal ground. */\n selectionBackground: string;\n selectionForeground: string;\n selectionInactiveBackground: string;\n};\n\nconst DARK_ANSI: AnsiPalette = {\n black: \"oklch(0.3 0 0)\",\n red: \"oklch(0.68 0.17 22)\",\n green: \"oklch(0.75 0.13 155)\",\n yellow: \"oklch(0.8 0.11 80)\",\n blue: \"oklch(0.7 0.14 255)\",\n magenta: \"oklch(0.72 0.13 305)\",\n cyan: \"oklch(0.75 0.1 210)\",\n white: \"oklch(0.8 0 0)\",\n brightBlack: \"oklch(0.45 0 0)\",\n brightRed: \"oklch(0.76 0.17 22)\",\n brightGreen: \"oklch(0.82 0.14 155)\",\n brightYellow: \"oklch(0.86 0.12 85)\",\n brightBlue: \"oklch(0.78 0.13 255)\",\n brightMagenta: \"oklch(0.8 0.13 305)\",\n brightCyan: \"oklch(0.83 0.1 200)\",\n brightWhite: \"oklch(0.97 0 0)\",\n selectionBackground: \"oklch(0.8 0 0 / 0.3)\",\n selectionForeground: \"oklch(0.985 0 0)\",\n selectionInactiveBackground: \"oklch(0.72 0 0 / 0.2)\",\n};\n\nconst LIGHT_ANSI: AnsiPalette = {\n black: \"oklch(0.35 0 0)\",\n red: \"oklch(0.52 0.19 22)\",\n green: \"oklch(0.5 0.13 155)\",\n yellow: \"oklch(0.56 0.13 80)\",\n blue: \"oklch(0.52 0.18 255)\",\n magenta: \"oklch(0.52 0.16 305)\",\n cyan: \"oklch(0.52 0.1 210)\",\n white: \"oklch(0.7 0 0)\",\n brightBlack: \"oklch(0.5 0 0)\",\n brightRed: \"oklch(0.55 0.2 22)\",\n brightGreen: \"oklch(0.54 0.14 155)\",\n brightYellow: \"oklch(0.6 0.14 80)\",\n brightBlue: \"oklch(0.48 0.19 255)\",\n brightMagenta: \"oklch(0.54 0.17 305)\",\n brightCyan: \"oklch(0.54 0.11 210)\",\n brightWhite: \"oklch(0.3 0 0)\",\n selectionBackground: \"oklch(0.45 0 0 / 0.2)\",\n selectionForeground: \"oklch(0.21 0 0)\",\n selectionInactiveBackground: \"oklch(0.6 0 0 / 0.14)\",\n};\n\n/** The designed ANSI-16 palette for a theme mode. Pure. */\nexport function ogAnsiPalette(mode: ThemeMode): AnsiPalette {\n return mode === \"light\" ? LIGHT_ANSI : DARK_ANSI;\n}\n\n/**\n * Build a COMPLETE xterm ITheme from token values. Background/foreground/cursor\n * come from the live `--og-*` tokens (so an embedder's rebrand flows through);\n * the ANSI-16 + selection come from the designed palette for `mode`. Every ANSI\n * slot is always set — xterm never falls back to its stock VGA colors. Pure.\n */\nexport function buildXtermTheme(read: TokenReader, mode: ThemeMode): XtermTheme {\n const ansi = ogAnsiPalette(mode);\n const bgFallback = mode === \"light\" ? \"#ffffff\" : \"#202020\";\n const fgFallback = mode === \"light\" ? \"#242424\" : \"#e6e6e6\";\n const bg = read(\"--og-color-bg\") ?? bgFallback;\n const fg = read(\"--og-color-fg\") ?? fgFallback;\n const accent = read(\"--og-color-accent\") ?? ansi.brightBlue;\n return {\n // Match the dock surface the terminal paints on (`--og-color-bg`).\n background: bg,\n foreground: fg,\n cursor: accent,\n cursorAccent: bg,\n selectionBackground: ansi.selectionBackground,\n selectionForeground: ansi.selectionForeground,\n selectionInactiveBackground: ansi.selectionInactiveBackground,\n black: ansi.black,\n red: ansi.red,\n green: ansi.green,\n yellow: ansi.yellow,\n blue: ansi.blue,\n magenta: ansi.magenta,\n cyan: ansi.cyan,\n white: ansi.white,\n brightBlack: ansi.brightBlack,\n brightRed: ansi.brightRed,\n brightGreen: ansi.brightGreen,\n brightYellow: ansi.brightYellow,\n brightBlue: ansi.brightBlue,\n brightMagenta: ansi.brightMagenta,\n brightCyan: ansi.brightCyan,\n brightWhite: ansi.brightWhite,\n };\n}\n\n/** Which og theme is active for `el`, matching the `use-theme-type` convention\n * (nearest `data-og-theme` / `.og-light` ancestor; else the computed\n * `color-scheme`; else dark, the first-class default). */\nfunction detectMode(el: Element, style: CSSStyleDeclaration): ThemeMode {\n const closest = el.closest?.bind(el);\n if (closest) {\n if (closest('[data-og-theme=\"light\"]') || closest(\".og-light\")) return \"light\";\n const explicit = closest(\"[data-og-theme]\");\n if (explicit) return explicit.getAttribute(\"data-og-theme\") === \"light\" ? \"light\" : \"dark\";\n }\n const scheme = (\n style.getPropertyValue(\"color-scheme\").trim() ||\n style.colorScheme ||\n \"\"\n ).toLowerCase();\n if (scheme.includes(\"light\") && !scheme.includes(\"dark\")) return \"light\";\n return \"dark\";\n}\n\n/**\n * Derive a COMPLETE xterm `ITheme` from the live `--og-*` token system on the\n * DOM. Reads the COMPUTED values so xterm gets concrete colors, detects the\n * active theme mode, and fills every ANSI slot. Call on mount + re-derive on a\n * `data-og-theme` flip. SSR-safe: returns undefined off the DOM.\n *\n * `root` should be an element INSIDE the themed subtree (e.g. the terminal\n * container) so nested `[data-og-theme]` themes resolve correctly; when omitted\n * it falls back to the nearest `[data-og-theme]` element, then documentElement.\n */\nexport function xtermThemeFromTokens(root?: HTMLElement | null): XtermTheme | undefined {\n if (typeof window === \"undefined\" || typeof getComputedStyle === \"undefined\") return undefined;\n const el =\n root ??\n (typeof document !== \"undefined\"\n ? ((document.querySelector(\"[data-og-theme]\") as HTMLElement | null) ??\n document.documentElement)\n : null);\n if (!el) return undefined;\n const style = getComputedStyle(el);\n const read: TokenReader = (name) => {\n const value = style.getPropertyValue(name).trim();\n return value || undefined;\n };\n return buildXtermTheme(read, detectMode(el, style));\n}\n\n// ── Font resolution ──────────────────────────────────────────────────────────\n\nexport type ResolvedTerminalFont = { fontFamily: string; fontSize: number; lineHeight: number };\n\n/** Concrete fallback if the token is unset or (defensively) still a `var()`. */\nconst FALLBACK_MONO = \"ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace\";\n\nexport type FontOverrides = { fontFamily?: string | undefined; fontSize?: number | undefined };\n\n/**\n * Resolve xterm's font from token values. The critical bug this fixes:\n * `fontFamily: \"var(--og-font-mono)\"` is measured by xterm via a canvas font\n * string where `var()` does NOT resolve, so xterm silently mis-measures every\n * glyph. Here the family is a CONCRETE stack; a `var(` in the input is treated\n * as unresolved and replaced with the fallback. Pure over a token `read`.\n */\nexport function resolveTerminalFontFromReader(\n read: TokenReader,\n overrides?: FontOverrides,\n): ResolvedTerminalFont {\n const rawFamily = overrides?.fontFamily ?? read(\"--og-font-mono\");\n const fontFamily =\n rawFamily && rawFamily.trim() && !rawFamily.includes(\"var(\") ? rawFamily.trim() : FALLBACK_MONO;\n\n let fontSize = overrides?.fontSize;\n if (fontSize == null) {\n const raw = read(\"--og-code-font-size\");\n const parsed = raw ? Number.parseFloat(raw) : Number.NaN;\n fontSize = Number.isFinite(parsed) && parsed > 0 ? parsed : 13;\n }\n\n return { fontFamily, fontSize, lineHeight: 1.3 };\n}\n\n/** DOM wrapper: resolve the terminal font from an element's computed tokens. */\nexport function resolveTerminalFont(\n el: HTMLElement,\n overrides?: FontOverrides,\n): ResolvedTerminalFont {\n const style = getComputedStyle(el);\n const read: TokenReader = (name) => {\n const value = style.getPropertyValue(name).trim();\n return value || undefined;\n };\n return resolveTerminalFontFromReader(read, overrides);\n}\n","import type { TerminalCapability } from \"@opengeni/sdk\";\nimport {\n type ReactNode,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { type TerminalStreamStatus, useTerminalStream } from \"../hooks/use-terminal-stream\";\nimport type { UseSandboxTerminalResult } from \"../hooks/use-sandbox-terminal\";\nimport { resolveTerminalFont, xtermThemeFromTokens } from \"../lib/xterm-theme\";\nimport { sandboxAcceptsLiveIo } from \"../lib/sandbox-liveness\";\nimport { terminalCanAcquirePty } from \"../lib/terminal-capability\";\nimport { attachRenderer, type RendererLoaders, type RendererTier } from \"../lib/xterm-renderer\";\nimport { sandboxTerminalPeers } from \"../lib/workbench-peers\";\n\n/**\n * A COMPLETE xterm `ITheme` (subset by intent, but every field xterm colors a\n * cell with is present so it never falls back to its stock VGA palette). Built\n * from the og tokens via `xtermThemeFromTokens`.\n */\nexport type XtermTheme = {\n background?: string;\n foreground?: string;\n cursor?: string;\n cursorAccent?: string;\n selectionBackground?: string;\n selectionForeground?: string;\n selectionInactiveBackground?: string;\n black?: string;\n red?: string;\n green?: string;\n yellow?: string;\n blue?: string;\n magenta?: string;\n cyan?: string;\n white?: string;\n brightBlack?: string;\n brightRed?: string;\n brightGreen?: string;\n brightYellow?: string;\n brightBlue?: string;\n brightMagenta?: string;\n brightCyan?: string;\n brightWhite?: string;\n};\n\nexport type SandboxTerminalProps = {\n /** From `useSandboxTerminal(...)`. */\n result: UseSandboxTerminalResult;\n /**\n * The negotiated Terminal capability cell. When it advertises `transport:\n * \"pty-ws\"` + a live `url` (a warm box with a viewer attached), the terminal is\n * driven by a REAL bidirectional PTY over the Modal tunnel (ttyd-over-websocket)\n * INSTEAD of the broken ptyWrite-over-HTTP path: xterm input → the socket, the\n * socket's output → xterm, xterm resize → the socket. On a cold box / no url\n * (`transport: \"sse-events\"`) it stays on the read-only Channel-A firehose\n * (`result.chunks`). Omit to force the legacy firehose-only behavior.\n */\n terminalCapability?: TerminalCapability | null | undefined;\n /**\n * Full xterm theme. When omitted the terminal self-derives it from the `--og-*`\n * tokens of its own container (correct even inside a nested `data-og-theme`\n * subtree). Passing it lets the host drive re-theme on a theme flip.\n */\n theme?: XtermTheme | undefined;\n fontFamily?: string | undefined;\n fontSize?: number | undefined;\n /**\n * Lease liveness (`cold` | `warming` | `warm` | `draining`). Drives the\n * boot-in-terminal status lines: once the user has engaged the terminal and\n * the box is not yet warm, a styled \"● waking machine — Ns…\" line is rendered\n * INSIDE xterm (no overlay/spinner) until the live PTY connects.\n */\n liveness?: string | undefined;\n /**\n * Force read-only even when the PTY accepts stdin. Default: interactive\n * whenever a live pty-ws stream is connected OR `result.write !== null` (the box\n * advertises an interactive PTY); otherwise the read-only agent firehose.\n */\n readOnly?: boolean | undefined;\n /** Shown on the server / before xterm hydrates (SSR-safe placeholder). */\n placeholder?: ReactNode | undefined;\n /** Render the small status header (pty/shell + running dot + read-only pill). */\n showHeader?: boolean | undefined;\n /** Shell label for the header (e.g. `/bin/bash`). */\n shell?: string | undefined;\n /**\n * Fired the first time the user engages the terminal surface (focus or click).\n * The host wires this to warm the box for the REAL pty-ws terminal (the viewer\n * attach), so a cold box upgrades from the read-only firehose to a live PTY ON\n * INTERACT — never on mere mount (which would force a box spin-up and regress\n * the firehose-only default).\n */\n onActivate?: (() => void) | undefined;\n /** Re-negotiate the terminal capability after an unexpected socket failure. */\n onReconnectNeeded?: (() => void) | undefined;\n className?: string | undefined;\n};\n\n// The xterm.js handle the effect owns. `any`-free structural shape so we can\n// drive it without a hard type dep on the lazily-imported lib.\ntype XtermLike = {\n open: (el: HTMLElement) => void;\n focus: () => void;\n write: (data: string) => void;\n clear: () => void;\n onData: (cb: (data: string) => void) => { dispose: () => void };\n onResize: (cb: (size: { cols: number; rows: number }) => void) => { dispose: () => void };\n loadAddon: (addon: unknown) => void;\n dispose: () => void;\n cols: number;\n rows: number;\n options: {\n theme?: XtermTheme;\n disableStdin?: boolean;\n cursorBlink?: boolean;\n fontFamily?: string;\n fontSize?: number;\n };\n};\ntype FitAddonLike = { fit: () => void };\ntype TerminalPeerBundle = {\n Terminal: new (options: Record<string, unknown>) => XtermLike;\n FitAddon: new () => FitAddonLike;\n WebLinksAddon: new (handler: (event: MouseEvent, uri: string) => void) => unknown;\n loadWebgl?:\n | (() => Promise<{\n WebglAddon: new () => {\n dispose: () => void;\n onContextLoss?: (callback: () => void) => void;\n };\n }>)\n | undefined;\n};\n\nexport type TerminalSurfaceState =\n | \"loading\"\n | \"connecting\"\n | \"error\"\n | \"waking\"\n | \"output-only\"\n | \"interactive\";\n\n/**\n * Stable semantic state for hosts and browser acceptance. The xterm helper\n * textarea exists before the live PTY socket is ready, so its presence alone\n * must never be treated as proof that keystrokes can reach the sandbox.\n */\nexport function terminalSurfaceState(input: {\n ready: boolean;\n acceptsInput: boolean;\n inputPending: boolean;\n ptyStatus: TerminalStreamStatus;\n booting: boolean;\n}): TerminalSurfaceState {\n if (!input.ready) return \"loading\";\n if (input.acceptsInput) return \"interactive\";\n if (input.inputPending) return \"connecting\";\n if (input.ptyStatus === \"connecting\") return \"connecting\";\n if (input.ptyStatus === \"error\") return \"error\";\n if (input.booting) return \"waking\";\n return \"output-only\";\n}\n\nexport function subscribeTerminalInput(\n term: Pick<XtermLike, \"onData\"> | null,\n sink: ((data: string) => void) | null,\n enabled: boolean,\n): { dispose: () => void } | null {\n if (!enabled || !term || !sink) return null;\n return term.onData(sink);\n}\n\n/** Clear the transient wake line and put the first live prompt at cell 1,1.\n * `Terminal.clear()` removes scrollback but deliberately preserves the cursor,\n * which lets the first PTY frame append to the old wake message. */\nexport function clearTerminalBootStatus(term: Pick<XtermLike, \"write\">): void {\n term.write(\"\\r\\x1b[2K\\x1b[2J\\x1b[H\");\n}\n\n/** Debug seam (dev/evidence only, never a typed public API): a global hook the\n * screenshot harness reads to probe the settled renderer tier + resolved font\n * without mounting a real WebGL context in unit tests. */\ntype TerminalDebugInfo = {\n renderer: RendererTier | null;\n fontFamily: string | undefined;\n fontSize: number | undefined;\n hasVarInFont: boolean;\n theme: XtermTheme | undefined;\n /** The live xterm instance (opaque) — the evidence harness reads its buffer to\n * prove screen preservation (E5) and drive the burst-responsiveness probe. */\n term: unknown;\n};\ndeclare global {\n // eslint-disable-next-line no-var\n var __OG_TERMINAL_DEBUG__: ((info: TerminalDebugInfo) => void) | undefined;\n // A space/comma list of renderer tiers to force-fail, so the demo can prove the\n // WebGL→canvas→DOM fallback ladder without a real GPU context loss.\n // eslint-disable-next-line no-var\n var __OG_FORCE_RENDERER_FAIL__: string | undefined;\n}\n\n/** Which renderer tiers are force-failed (demo/evidence only). */\nfunction forcedRendererFailures(): Set<RendererTier> {\n const raw = typeof globalThis !== \"undefined\" ? globalThis.__OG_FORCE_RENDERER_FAIL__ : undefined;\n const set = new Set<RendererTier>();\n if (typeof raw === \"string\") {\n for (const tier of raw.split(/[\\s,]+/)) {\n if (tier === \"webgl\" || tier === \"canvas\") set.add(tier);\n }\n }\n return set;\n}\n\n/**\n * An xterm.js terminal fed by the Channel-A event projection\n * (`useSandboxTerminal`) or a live ttyd PTY. xterm + its addons are lazy-imported\n * inside an effect, so SSR renders the placeholder and the terminal mounts on\n * hydration.\n *\n * Renderer: WebGL (GPU-composited cells) with a canvas → DOM fallback ladder\n * (`attachRenderer`), so bursty output stays smooth but a lost/blocklisted\n * context degrades gracefully. Font + theme are resolved to CONCRETE values\n * from the og tokens BEFORE construction (xterm measures glyphs in a canvas\n * where `var()` never resolves, and colors every cell from a full ANSI palette).\n *\n * The terminal is mounted ONCE and its data source is swapped in place: the\n * read-only firehose (`result.chunks`) → the live PTY. Stdin is toggled via\n * `term.options.disableStdin` at runtime (not a remount), so scrollback and the\n * visible screen survive the projection→PTY handoff.\n *\n * Resizes are tracked with a `ResizeObserver` on the container (not just\n * `window.resize`) so dragging the dock handle refits the grid.\n */\nexport function SandboxTerminal({\n result,\n terminalCapability,\n theme,\n fontFamily,\n fontSize,\n liveness,\n readOnly,\n placeholder,\n showHeader,\n shell,\n onActivate,\n onReconnectNeeded,\n className,\n}: SandboxTerminalProps) {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const termRef = useRef<XtermLike | null>(null);\n const fitRef = useRef<FitAddonLike | null>(null);\n const rendererRef = useRef<RendererTier | null>(null);\n const writtenRef = useRef<Set<string>>(new Set());\n const wroteFirehoseRef = useRef(false);\n const bootActiveRef = useRef(false);\n const [ready, setReady] = useState(false);\n const [loadError, setLoadError] = useState<Error | null>(null);\n const peerRevision = useSyncExternalStore(\n sandboxTerminalPeers.subscribe,\n sandboxTerminalPeers.revision,\n sandboxTerminalPeers.revision,\n );\n const [inputReady, setInputReady] = useState(false);\n const [activated, setActivated] = useState(false);\n\n // ── Interactive transport switch ─────────────────────────────────────────────\n const ptyDescriptor =\n terminalCapability?.transport === \"pty-ws\" || terminalCapability?.transport === \"relay-pty\";\n const ptyAttachable = terminalCanAcquirePty(terminalCapability);\n const {\n status: ptyStatus,\n write: ptyWrite,\n resize: resizePty,\n connected: ptyConnected,\n inputReadiness,\n useLegacyInput,\n } = useTerminalStream({\n // Connect only after xterm exists. This makes the renderer the sole output\n // owner from the first websocket frame and removes an otherwise unbounded\n // pre-mount output queue during large command bursts.\n capability:\n ptyAttachable && ready\n ? {\n transport: terminalCapability!.transport,\n url: ptyDescriptor ? terminalCapability!.url : null,\n token: ptyDescriptor ? terminalCapability!.token : null,\n expiresAt: ptyDescriptor ? terminalCapability!.expiresAt : null,\n ptyCapable: terminalCapability!.ptyCapable,\n reason: terminalCapability!.reason,\n }\n : null,\n onOutput: (data) => {\n termRef.current?.write(data);\n },\n onReconnectNeeded,\n });\n\n // A pty-ws capability exclusively owns the screen even while connecting or\n // after a visible connection failure; never silently switch one terminal UI\n // between two PTYs. Input is enabled during the handshake because the stream\n // hook buffers it strictly until negotiated readiness. Old servers are\n // explicitly legacy: their transport-open state is not shell readiness.\n const ptyMode = ptyDescriptor;\n // Keep xterm stdin live for an attachable descriptor even before its URL has\n // arrived. Focus/click triggers the grant; any immediately following input is\n // bounded in the stream hook instead of disappearing in that HTTP interval.\n const ptyCapturesInput = ptyAttachable && ptyStatus !== \"error\";\n const interactive = !readOnly && (ptyAttachable ? ptyCapturesInput : result.write !== null);\n // Public \"interactive\" means the mounted input subscription can reach a live\n // PTY now. Before that point xterm still captures into the bounded queue, but\n // acceptance and embedders see an explicit connecting state.\n const acceptsInput = inputReady && (!ptyAttachable || ptyConnected);\n const inputPending = inputReady && ptyAttachable && !ptyConnected && activated;\n let terminalModeLabel: string | null;\n if (readOnly) terminalModeLabel = \"read-only\";\n else if (!ptyAttachable) terminalModeLabel = acceptsInput ? null : \"output only\";\n else if (ptyStatus === \"error\") terminalModeLabel = \"connection error\";\n else if (acceptsInput) terminalModeLabel = inputReadiness === \"legacy\" ? \"legacy input\" : null;\n else terminalModeLabel = activated ? \"connecting\" : \"connect on input\";\n\n // Boot-in-terminal: after the user engages a not-yet-warm box, show styled\n // status lines INSIDE xterm instead of an overlay — but only when there is no\n // firehose transcript to show yet (otherwise the projected output is shown).\n const warm = sandboxAcceptsLiveIo(liveness);\n const booting =\n activated &&\n !ptyMode &&\n !warm &&\n liveness !== null &&\n liveness !== undefined &&\n result.chunks.length === 0;\n const surfaceState = terminalSurfaceState({\n ready,\n acceptsInput,\n inputPending,\n ptyStatus,\n booting,\n });\n\n function handleActivate() {\n // Capture-phase activation may synchronously negotiate a fresh terminal\n // capability and rerender the shell. Focus xterm before that state change so\n // the user's first keystroke or paste reaches its already-bounded input\n // queue instead of landing on the surrounding dock.\n const term = termRef.current;\n if (term && !readOnly && (ptyAttachable || result.write !== null)) {\n term.options.disableStdin = false;\n term.options.cursorBlink = true;\n }\n term?.focus();\n if (!activated) setActivated(true);\n onActivate?.();\n }\n\n // Mount xterm once (client-only). Never re-mounts on interactive/theme flips —\n // stdin + theme are runtime options synced by the effects below, so the visible\n // screen survives the projection→PTY handoff (E5).\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const el = containerRef.current;\n if (!el) return;\n let disposed = false;\n\n // Wait for a real measured size before opening xterm so the first fit is at\n // the true width (belt-and-braces with the visibility gate below).\n const waitForSize = (node: HTMLElement) =>\n new Promise<void>((resolve) => {\n if (node.clientWidth > 0 && node.clientHeight > 0) return resolve();\n const ro = new ResizeObserver(() => {\n if (node.clientWidth > 0 && node.clientHeight > 0) {\n ro.disconnect();\n resolve();\n }\n });\n ro.observe(node);\n setTimeout(() => {\n ro.disconnect();\n resolve();\n }, 1000);\n });\n\n ensureXtermBaseCss();\n\n setLoadError(null);\n void (async () => {\n const { Terminal, FitAddon, WebLinksAddon, loadWebgl } =\n (await sandboxTerminalPeers.load()) as TerminalPeerBundle;\n if (disposed) return;\n await waitForSize(el);\n if (disposed) return;\n\n // Resolve font + theme to CONCRETE values BEFORE construction. `var()` in a\n // font family never resolves in xterm's canvas measurement, so we read the\n // computed `--og-font-mono` here; the theme is a full ANSI palette.\n const font = resolveTerminalFont(el, { fontFamily, fontSize });\n const initialTheme = theme ?? xtermThemeFromTokens(el);\n\n const term = new Terminal({\n convertEol: true,\n disableStdin: !interactive,\n cursorBlink: interactive,\n fontFamily: font.fontFamily,\n fontSize: font.fontSize,\n lineHeight: font.lineHeight,\n ...(initialTheme ? { theme: initialTheme } : {}),\n }) as unknown as XtermLike;\n const fit = new FitAddon() as unknown as FitAddonLike;\n term.loadAddon(fit);\n term.loadAddon(\n new WebLinksAddon((_e: MouseEvent, uri: string) =>\n window.open(uri, \"_blank\", \"noopener,noreferrer\"),\n ) as unknown,\n );\n term.open(el);\n termRef.current = term;\n fitRef.current = fit;\n\n // Attach the fastest available renderer. For xterm-6 the supported ladder\n // is WebGL → DOM (the standalone 2D-canvas addon targets xterm-5 internals,\n // so it is intentionally NOT in the shipped path). Init failure / context\n // loss steps down to xterm's built-in DOM renderer; the settled tier is\n // exposed for evidence.\n const failSet = forcedRendererFailures();\n const loaders: RendererLoaders = {\n webgl: async (onLoss) => {\n if (disposed) throw new Error(\"Terminal was disposed\");\n if (failSet.has(\"webgl\")) throw new Error(\"forced webgl failure\");\n if (!loadWebgl) throw new Error(\"WebGL terminal renderer is not enabled\");\n const { WebglAddon } = await loadWebgl();\n if (disposed) throw new Error(\"Terminal was disposed\");\n const addon = new WebglAddon() as unknown as {\n dispose: () => void;\n onContextLoss?: (cb: () => void) => void;\n };\n addon.onContextLoss?.(() => {\n if (disposed) return;\n try {\n addon.dispose();\n } catch {\n // already disposed\n }\n onLoss();\n });\n term.loadAddon(addon);\n return addon;\n },\n };\n await attachRenderer(\"webgl\", loaders, (tier) => {\n if (disposed) return;\n rendererRef.current = tier;\n el.setAttribute(\"data-og-term-renderer\", tier);\n });\n if (disposed) return;\n\n // Fit BEFORE reveal so the first visible frame is already correctly sized\n // (no 80×24 rasterize-then-reflow flash — the container stays hidden until\n // now via the `ready` visibility gate).\n const settle = () => {\n try {\n fit.fit();\n } catch {\n // ignore fit before layout\n }\n };\n settle();\n requestAnimationFrame(() => {\n if (disposed) return;\n settle();\n el.setAttribute(\"data-og-term-ready\", \"true\");\n if (typeof globalThis.__OG_TERMINAL_DEBUG__ === \"function\") {\n globalThis.__OG_TERMINAL_DEBUG__({\n renderer: rendererRef.current,\n fontFamily: term.options.fontFamily,\n fontSize: term.options.fontSize,\n hasVarInFont: String(term.options.fontFamily ?? \"\").includes(\"var(\"),\n theme: term.options.theme,\n term,\n });\n }\n setReady(true);\n });\n })().catch((cause: unknown) => {\n if (!disposed) setLoadError(cause instanceof Error ? cause : new Error(String(cause)));\n });\n\n return () => {\n disposed = true;\n termRef.current?.dispose();\n termRef.current = null;\n fitRef.current = null;\n rendererRef.current = null;\n writtenRef.current = new Set();\n wroteFirehoseRef.current = false;\n bootActiveRef.current = false;\n setReady(false);\n };\n // Mount once per peer registration; runtime options sync without a remount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [peerRevision]);\n\n // Sync stdin/cursor at runtime (NOT a remount) when interactivity flips, so the\n // projection→PTY handoff keeps the single Terminal instance + its scrollback.\n useLayoutEffect(() => {\n const term = termRef.current;\n if (!ready || !term) return;\n term.options.disableStdin = !interactive;\n term.options.cursorBlink = interactive;\n }, [ready, interactive]);\n\n // Re-theme live (dark↔light flip) without re-mounting / losing scrollback. Uses\n // the passed theme, or self-derives from the container's tokens.\n useEffect(() => {\n const term = termRef.current;\n if (!ready || !term) return;\n const next = theme ?? xtermThemeFromTokens(containerRef.current);\n if (next) term.options.theme = next;\n }, [ready, theme]);\n\n // Boot-in-terminal status lines. While `booting`, paint a styled \"● waking\n // machine — Ns…\" line and tick it. On exit, if those lines were the ONLY\n // content (no firehose transcript), clear them for the incoming live screen —\n // never clear a real transcript (E5 preservation).\n useEffect(() => {\n const term = termRef.current;\n if (!ready || !term) return;\n if (!booting) {\n if (bootActiveRef.current) {\n bootActiveRef.current = false;\n if (!wroteFirehoseRef.current) clearTerminalBootStatus(term);\n }\n return;\n }\n bootActiveRef.current = true;\n const start = Date.now();\n const paint = () => {\n const s = Math.max(0, Math.round((Date.now() - start) / 1000));\n // Bright-blue dot (accent) + dim label; `\\r` + clear-line keeps it on one\n // line so the counter updates in place.\n term.write(`\\r\\x1b[2K\\x1b[94m●\\x1b[0m \\x1b[2mwaking machine — ${s}s…\\x1b[0m`);\n };\n term.write(\"\\r\\n\");\n paint();\n const id = setInterval(paint, 1000);\n return () => clearInterval(id);\n }, [ready, booting]);\n\n // Write new firehose chunks incrementally — ONLY in firehose mode. In PTY mode\n // the ttyd socket owns the screen. Records that a real transcript exists so the\n // boot cleanup never wipes it.\n useEffect(() => {\n const term = termRef.current;\n if (!ready || !term || ptyMode) return;\n for (const chunk of result.chunks) {\n if (writtenRef.current.has(chunk.id)) continue;\n writtenRef.current.add(chunk.id);\n wroteFirehoseRef.current = true;\n term.write(chunk.text);\n }\n }, [ready, result.chunks, ptyMode]);\n\n // Wire interactive input when allowed. `ptyWrite` is stable across socket\n // status changes, so this subscription does not tear down while a grant opens\n // or rotates and cannot create a first-keystroke gap.\n useLayoutEffect(() => {\n const term = termRef.current;\n if (!ready || !term || !interactive) {\n setInputReady(false);\n return;\n }\n const sink = ptyAttachable ? ptyWrite : result.write;\n if (!sink) {\n setInputReady(false);\n return;\n }\n const sub = subscribeTerminalInput(term, sink, true);\n setInputReady(sub !== null);\n return () => sub?.dispose();\n }, [ready, interactive, ptyAttachable, ptyWrite, result.write]);\n\n // In PTY mode, tell ttyd the window size on the xterm resize event.\n useEffect(() => {\n const term = termRef.current;\n if (!ready || !term || !ptyMode) return;\n resizePty(term.cols, term.rows);\n const sub = term.onResize(({ cols, rows }) => resizePty(cols, rows));\n return () => sub.dispose();\n }, [ready, ptyMode, ptyConnected, resizePty]);\n\n // Refit on container resize (dock drag) AND window resize.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const refit = () => {\n try {\n fitRef.current?.fit();\n } catch {\n // ignore\n }\n };\n window.addEventListener(\"resize\", refit);\n let observer: ResizeObserver | null = null;\n const el = containerRef.current;\n if (el && typeof ResizeObserver !== \"undefined\") {\n observer = new ResizeObserver(() => refit());\n observer.observe(el);\n }\n return () => {\n window.removeEventListener(\"resize\", refit);\n observer?.disconnect();\n };\n }, [ready]);\n\n return (\n <div className={cn(\"relative flex h-full w-full flex-col overflow-hidden\", className)}>\n {showHeader && (\n <div className=\"flex shrink-0 items-center justify-between gap-2 border-b border-og-border px-2 py-1 text-og-xs text-og-fg-subtle\">\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <span\n className={cn(\n \"size-1.5 shrink-0 rounded-full\",\n result.running ? \"bg-og-status-running\" : \"bg-og-fg-subtle\",\n )}\n />\n <span className=\"truncate font-og-mono\">pty: {shell ?? \"shell\"}</span>\n </span>\n <span className=\"flex shrink-0 items-center gap-2\">\n {terminalModeLabel && (\n <span\n className=\"rounded-og-sm bg-og-surface-2 px-1.5 py-0.5 text-og-xs uppercase tracking-wide\"\n role=\"status\"\n title={\n inputReadiness === \"legacy\"\n ? \"Shell readiness is not guaranteed. Wait for startup before typing.\"\n : undefined\n }\n >\n {terminalModeLabel}\n </span>\n )}\n <button\n type=\"button\"\n onClick={() => {\n termRef.current?.clear();\n writtenRef.current = new Set();\n wroteFirehoseRef.current = false;\n }}\n className=\"rounded-og-sm px-1.5 py-0.5 text-og-xs hover:text-og-fg pointer-coarse:min-h-11\"\n >\n Clear\n </button>\n </span>\n </div>\n )}\n {ptyAttachable && !readOnly && !showHeader && inputReadiness === \"legacy\" && (\n <p role=\"status\" className=\"shrink-0 px-3 py-1 text-og-xs text-og-fg-subtle\">\n Legacy input — wait for shell startup before typing.\n </p>\n )}\n {ptyAttachable && !readOnly && inputReadiness === \"waiting\" && (\n <div className=\"flex shrink-0 flex-wrap items-center justify-between gap-2 border-b border-og-border px-3 py-2 text-og-xs text-og-fg-subtle\">\n <span role=\"status\">\n Waiting for shell readiness. Manual input clears buffered typing.\n </span>\n <button\n type=\"button\"\n onClick={() => {\n useLegacyInput();\n termRef.current?.focus();\n }}\n title=\"Use for startup prompts or shells without readiness support. Early input is not guaranteed.\"\n className=\"shrink-0 rounded-og-sm px-2 py-1 text-og-fg hover:bg-og-surface-2 focus-visible:outline focus-visible:outline-2 focus-visible:outline-og-accent pointer-coarse:min-h-11\"\n >\n Use manual input\n </button>\n </div>\n )}\n {/* `onPointerDownCapture`/`onFocusCapture` fire on the FIRST user engagement\n with the terminal surface (capture so they win even though xterm's own\n listeners stop propagation). The host warms the box for pty-ws here. The\n 12px inset + `--og-color-bg` ground match the dock surface. */}\n <div\n className=\"relative min-h-0 flex-1 bg-og-bg p-3\"\n onPointerDownCapture={handleActivate}\n onFocusCapture={handleActivate}\n >\n {!ready &&\n (loadError ? (\n <p role=\"alert\">{loadError.message}</p>\n ) : (\n (placeholder ?? <TerminalPlaceholder />)\n ))}\n {/* Kept `visibility:hidden` until the first successful fit so the first\n VISIBLE frame is already correctly sized (no 80×24 flash — E4). */}\n <div\n ref={containerRef}\n className=\"h-full w-full\"\n style={{ visibility: ready ? \"visible\" : \"hidden\" }}\n data-opengeni-terminal\n data-opengeni-terminal-ready={ready ? \"true\" : \"false\"}\n data-opengeni-terminal-interactive={surfaceState === \"interactive\" ? \"true\" : \"false\"}\n data-opengeni-terminal-state={surfaceState}\n data-opengeni-terminal-status={ptyAttachable ? ptyStatus : \"firehose\"}\n data-opengeni-terminal-input-readiness={ptyAttachable ? inputReadiness : \"firehose\"}\n />\n </div>\n </div>\n );\n}\n\n// xterm.js ships a stylesheet (`@xterm/xterm/css/xterm.css`) that is REQUIRED for\n// correct layout — without it the `.xterm-helper-textarea` (an off-screen input\n// xterm uses for IME/keystrokes) is NOT clipped and renders as a visible 1-line\n// box in the top-left (the \"weird input box\" bug), and the viewport/screen aren't\n// positioned. The host app never imports that CSS (no global stylesheet here), so\n// we inject the structural rules once, idempotently (keyed by id), the first time\n// any terminal mounts. Scoped under `.xterm` so it can't leak into host styles.\nconst XTERM_STYLE_ID = \"opengeni-xterm-base-css\";\nconst XTERM_BASE_CSS = `\n.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}\n.xterm.focus,.xterm:focus{outline:none}\n.xterm .xterm-helpers{position:absolute;top:0;z-index:5}\n.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}\n.xterm .composition-view{background:var(--og-color-bg);color:var(--og-color-fg);display:none;position:absolute;white-space:nowrap;z-index:1}\n.xterm .composition-view.active{display:block}\n.xterm .xterm-viewport{background-color:transparent;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}\n.xterm .xterm-screen{position:relative}\n.xterm .xterm-screen canvas{position:absolute;left:0;top:0}\n.xterm .xterm-scroll-area{visibility:hidden}\n.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}\n.xterm.enable-mouse-events{cursor:default}\n.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}\n.xterm.column-select.focus{cursor:crosshair}\n.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}\n.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}\n.xterm .xterm-accessibility-tree{user-select:text;white-space:pre}\n.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}\n.xterm-dim{opacity:1!important}\n.xterm-underline-1{text-decoration:underline}\n.xterm-underline-2{text-decoration:double underline}\n.xterm-underline-3{text-decoration:wavy underline}\n.xterm-underline-4{text-decoration:dotted underline}\n.xterm-underline-5{text-decoration:dashed underline}\n.xterm-overline{text-decoration:overline}\n.xterm-strikethrough{text-decoration:line-through}\n.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}\n.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}\n.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}\n.xterm-decoration-top{z-index:2;position:relative}\n`;\n\nfunction ensureXtermBaseCss(): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(XTERM_STYLE_ID)) return;\n const style = document.createElement(\"style\");\n style.id = XTERM_STYLE_ID;\n style.textContent = XTERM_BASE_CSS;\n document.head.appendChild(style);\n}\n\nfunction TerminalPlaceholder() {\n return (\n <div className=\"absolute inset-0 flex items-center justify-center text-og-sm text-og-fg-subtle\">\n Loading terminal…\n </div>\n );\n}\n","import type { TerminalCapability } from \"@opengeni/sdk\";\n\n/** Whether an explicit viewer grant can upgrade this cell to a real PTY.\n * Keep acquisition feasibility separate from the current transport: a cold\n * real-PTY backend reports sse-events until the just-in-time grant warms it. */\nexport function terminalCanAcquirePty(cell: TerminalCapability | null | undefined): boolean {\n if (!cell?.ptyCapable) return false;\n if (cell.transport === \"pty-ws\" || cell.transport === \"relay-pty\") return true;\n return cell.reason === \"lease_cold\" || cell.reason === \"not_provisioned\";\n}\n","/* ----------------------------------------------------------------------------\n xterm renderer selection ladder: WebGL → 2D canvas → DOM.\n\n WebGL is the fast path (GPU-composited cells — the whole point of the burst\n responsiveness win). But a WebGL context can fail to init (headless / no GPU /\n blocklisted driver) or be LOST at runtime (GPU reset, tab backgrounded). On\n either, we dispose the addon and step down one tier so the terminal keeps\n painting via the 2D canvas addon, and failing that xterm's built-in DOM\n renderer (no addon).\n\n `attachRenderer` is pure over its `loaders` (each closes over the xterm\n instance and constructs+loads its addon, throwing on failure), so the ladder\n + context-loss downgrade unit-test without a real WebGL context.\n -------------------------------------------------------------------------- */\n\nexport type RendererTier = \"webgl\" | \"canvas\" | \"dom\";\n\nexport type RendererAddon = { dispose: () => void };\n\n/** A loader constructs + `loadAddon`s its renderer, wiring `onLoss` to the\n * addon's context-loss event, and throws if the renderer can't initialize. */\nexport type RendererLoaders = {\n webgl?: ((onLoss: () => void) => Promise<RendererAddon>) | undefined;\n canvas?: (() => Promise<RendererAddon>) | undefined;\n};\n\nconst ORDER: RendererTier[] = [\"webgl\", \"canvas\", \"dom\"];\n\n/** The next lower renderer tier, or null at the bottom (DOM). Pure. */\nexport function nextRendererTier(tier: RendererTier): RendererTier | null {\n const i = ORDER.indexOf(tier);\n return i >= 0 && i < ORDER.length - 1 ? ORDER[i + 1]! : null;\n}\n\n/**\n * Attach the highest renderer tier at or below `prefer` that initializes,\n * reporting the settled tier via `onTier`. On a WebGL/canvas context loss the\n * loader's `onLoss` re-enters at the next tier down, so `onTier` is called again\n * with the downgraded tier. Returns the tier chosen on this pass.\n */\nexport async function attachRenderer(\n prefer: RendererTier,\n loaders: RendererLoaders,\n onTier: (tier: RendererTier) => void,\n): Promise<RendererTier> {\n const start = Math.max(0, ORDER.indexOf(prefer));\n for (let i = start; i < ORDER.length; i++) {\n const tier = ORDER[i]!;\n if (tier === \"dom\") break;\n const loader = tier === \"webgl\" ? loaders.webgl : loaders.canvas;\n if (!loader) continue;\n try {\n const downgrade = nextRendererTier(tier) ?? \"dom\";\n await loader(() => {\n void attachRenderer(downgrade, loaders, onTier);\n });\n onTier(tier);\n return tier;\n } catch {\n // Initialization failed — fall through to the next tier down.\n }\n }\n onTier(\"dom\");\n return \"dom\";\n}\n"],"mappings":"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","names":["useEffect","useRef","useState","useRef","useState","useEffect"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/lib/pierre-diffs-loader.ts
|
|
4
|
+
var loader = null;
|
|
5
|
+
var loaded = null;
|
|
6
|
+
var revision = 0;
|
|
7
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
8
|
+
function registerPierreDiffs(next) {
|
|
9
|
+
if (next === loader) return;
|
|
10
|
+
loader = next;
|
|
11
|
+
loaded = null;
|
|
12
|
+
revision += 1;
|
|
13
|
+
for (const listener of listeners) listener();
|
|
14
|
+
}
|
|
15
|
+
function pierreDiffsRevision() {
|
|
16
|
+
return revision;
|
|
17
|
+
}
|
|
18
|
+
function subscribePierreDiffs(listener) {
|
|
19
|
+
listeners.add(listener);
|
|
20
|
+
return () => listeners.delete(listener);
|
|
21
|
+
}
|
|
22
|
+
function loadPierreDiffs() {
|
|
23
|
+
if (!loader) {
|
|
24
|
+
return Promise.reject(
|
|
25
|
+
new Error(
|
|
26
|
+
"@pierre/diffs is not enabled; call enablePierreDiffs() from @opengeni/react/diffs"
|
|
27
|
+
)
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
loaded ??= loader().catch((error) => {
|
|
31
|
+
loaded = null;
|
|
32
|
+
throw error;
|
|
33
|
+
});
|
|
34
|
+
return loaded;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
registerPierreDiffs,
|
|
39
|
+
pierreDiffsRevision,
|
|
40
|
+
subscribePierreDiffs,
|
|
41
|
+
loadPierreDiffs
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=chunk-YSRBFJMQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/pierre-diffs-loader.ts"],"sourcesContent":["/**\n * `@pierre/diffs` is an optional heavy peer. The package never names it in an\n * `import()` that the conversation surfaces can reach: bundlers such as\n * Turbopack resolve every reachable dynamic import at build time, so a host\n * without the peer would fail to build. Hosts that install it opt in once with\n * `enablePierreDiffs()` from `@opengeni/react/diffs` (or register their own\n * loader); otherwise diffs and file views use the plain-text renderer.\n */\nexport type PierreDiffsLoader = () => Promise<unknown>;\n\nlet loader: PierreDiffsLoader | null = null;\nlet loaded: Promise<unknown> | null = null;\nlet revision = 0;\nconst listeners = new Set<() => void>();\n\n/**\n * Register (or clear with `null`) the loader for `@pierre/diffs/react`.\n * Views already on screen retry with the new loader, so a host may register\n * lazily (for example from the route that renders diffs).\n */\nexport function registerPierreDiffs(next: PierreDiffsLoader | null): void {\n if (next === loader) return;\n loader = next;\n loaded = null;\n revision += 1;\n for (const listener of listeners) listener();\n}\n\n/** Changes whenever the registered loader changes (for `useSyncExternalStore`). */\nexport function pierreDiffsRevision(): number {\n return revision;\n}\n\nexport function subscribePierreDiffs(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\n/** Resolve the registered `@pierre/diffs/react` module; rejects when none is registered. */\nexport function loadPierreDiffs(): Promise<unknown> {\n if (!loader) {\n return Promise.reject(\n new Error(\n \"@pierre/diffs is not enabled; call enablePierreDiffs() from @opengeni/react/diffs\",\n ),\n );\n }\n loaded ??= loader().catch((error: unknown) => {\n loaded = null;\n throw error;\n });\n return loaded;\n}\n"],"mappings":";;;AAUA,IAAI,SAAmC;AACvC,IAAI,SAAkC;AACtC,IAAI,WAAW;AACf,IAAM,YAAY,oBAAI,IAAgB;AAO/B,SAAS,oBAAoB,MAAsC;AACxE,MAAI,SAAS,OAAQ;AACrB,WAAS;AACT,WAAS;AACT,cAAY;AACZ,aAAW,YAAY,UAAW,UAAS;AAC7C;AAGO,SAAS,sBAA8B;AAC5C,SAAO;AACT;AAEO,SAAS,qBAAqB,UAAkC;AACrE,YAAU,IAAI,QAAQ;AACtB,SAAO,MAAM,UAAU,OAAO,QAAQ;AACxC;AAGO,SAAS,kBAAoC;AAClD,MAAI,CAAC,QAAQ;AACX,WAAO,QAAQ;AAAA,MACb,IAAI;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,aAAW,OAAO,EAAE,MAAM,CAAC,UAAmB;AAC5C,aAAS;AACT,UAAM;AAAA,EACR,CAAC;AACD,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
coerceReasoningEffortForModel,
|
|
4
|
+
effortOptionsForModel,
|
|
5
|
+
findPickerRow,
|
|
6
|
+
groupPickerRowsByBillingClass,
|
|
7
|
+
payerSummaryForModel,
|
|
8
|
+
projectClientModelRows,
|
|
9
|
+
runnableLatencyModesForModel,
|
|
10
|
+
scopedBillingClassLabel
|
|
11
|
+
} from "./chunk-KF33GTWN.js";
|
|
12
|
+
|
|
13
|
+
// src/model-picker-model.ts
|
|
14
|
+
var defaultModelPolicyPickerMessages = {
|
|
15
|
+
label: "Model and effort",
|
|
16
|
+
loading: "Loading model catalog\u2026",
|
|
17
|
+
noModels: "No models available.",
|
|
18
|
+
connectTitle: "Connect a model",
|
|
19
|
+
connectBody: "Use a subscription or a provider key you already have.",
|
|
20
|
+
connectAction: "Open Models",
|
|
21
|
+
thinking: "Thinking",
|
|
22
|
+
fast: "Fast",
|
|
23
|
+
fastRateHint: "2\xD7 rate",
|
|
24
|
+
codexOnly: "Codex-only session",
|
|
25
|
+
searchLabel: "Search models or providers",
|
|
26
|
+
searchPlaceholder: "Search models or providers\u2026",
|
|
27
|
+
currentModel: "Current model",
|
|
28
|
+
noMatches: "No matching models. Try a model or provider name.",
|
|
29
|
+
unsupportedAttachments: "This model cannot view the attached images.",
|
|
30
|
+
thinkingEffort: "Thinking effort",
|
|
31
|
+
selected: "Selected",
|
|
32
|
+
free: "Free",
|
|
33
|
+
billingHints: {
|
|
34
|
+
opengeni_credits: "Provided by Opengeni",
|
|
35
|
+
external: "Provider terms and limits apply",
|
|
36
|
+
codex_subscription: "ChatGPT / Codex plan",
|
|
37
|
+
supergrok_subscription: "SuperGrok / xAI plan",
|
|
38
|
+
claude_subscription: "Claude plan",
|
|
39
|
+
byok: "Billed to the connected provider account",
|
|
40
|
+
organization_byok: "Billed to the connected provider account"
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var SCOPED_BILLING_HINTS = {
|
|
44
|
+
byok: "Billed to the workspace provider account",
|
|
45
|
+
organization_byok: "Billed to the organization provider account"
|
|
46
|
+
};
|
|
47
|
+
function isCodexPickerModel(model) {
|
|
48
|
+
return model.id.startsWith("codex/") || model.source === "codex";
|
|
49
|
+
}
|
|
50
|
+
function billingClassForMissingSelection(modelId) {
|
|
51
|
+
if (modelId.startsWith("workspace-claude-subscription/")) return "claude_subscription";
|
|
52
|
+
if (modelId.startsWith("workspace-anthropic/")) return "byok";
|
|
53
|
+
if (modelId.startsWith("organization-claude-subscription/")) return "claude_subscription";
|
|
54
|
+
if (modelId.startsWith("organization-anthropic/")) return "organization_byok";
|
|
55
|
+
if (modelId.startsWith("workspace-gateway/")) return "byok";
|
|
56
|
+
if (modelId.startsWith("workspace-openrouter/")) return "byok";
|
|
57
|
+
if (modelId.startsWith("workspace-opper/")) return "byok";
|
|
58
|
+
if (modelId.startsWith("openrouter/")) return "opengeni_credits";
|
|
59
|
+
if (modelId.startsWith("opper/")) return "opengeni_credits";
|
|
60
|
+
if (modelId.startsWith("codex/")) return "codex_subscription";
|
|
61
|
+
if (modelId.startsWith("supergrok/")) return "supergrok_subscription";
|
|
62
|
+
return "opengeni_credits";
|
|
63
|
+
}
|
|
64
|
+
function applyCodexOnly(rows, codexOnly, unavailableReason) {
|
|
65
|
+
if (!codexOnly) return rows;
|
|
66
|
+
return rows.map(
|
|
67
|
+
(row) => isCodexPickerModel(row.catalog) ? row : {
|
|
68
|
+
...row,
|
|
69
|
+
selectable: false,
|
|
70
|
+
unavailableReason: row.unavailableReason ?? unavailableReason
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
function groupPresentationFor(props, billingClass) {
|
|
75
|
+
const own = props.groupPresentation?.[billingClass];
|
|
76
|
+
if (own !== void 0 || props.collapseScopes === false) return own;
|
|
77
|
+
if (billingClass === "byok") return props.groupPresentation?.organization_byok;
|
|
78
|
+
if (billingClass === "organization_byok") return props.groupPresentation?.byok;
|
|
79
|
+
return void 0;
|
|
80
|
+
}
|
|
81
|
+
function effectiveRows(props) {
|
|
82
|
+
const rows = props.rows !== void 0 ? props.rows : projectClientModelRows(props.models ?? []);
|
|
83
|
+
const messages = { ...defaultModelPolicyPickerMessages, ...props.messages };
|
|
84
|
+
return applyCodexOnly(rows, props.codexOnly === true, messages.codexOnly).map((row) => {
|
|
85
|
+
const scoped = props.collapseScopes === false ? {
|
|
86
|
+
...row,
|
|
87
|
+
label: row.catalog.label,
|
|
88
|
+
billingClassLabel: scopedBillingClassLabel(row.billingClass)
|
|
89
|
+
} : row;
|
|
90
|
+
if (props.collapseScopes === false) {
|
|
91
|
+
if (row.catalog.shortLabel) scoped.shortLabel = row.catalog.shortLabel;
|
|
92
|
+
else delete scoped.shortLabel;
|
|
93
|
+
}
|
|
94
|
+
const label = groupPresentationFor(props, row.billingClass)?.label;
|
|
95
|
+
return label === void 0 ? scoped : { ...scoped, billingClassLabel: label };
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function modelPickerMenuView(props, query) {
|
|
99
|
+
const messages = { ...defaultModelPolicyPickerMessages, ...props.messages };
|
|
100
|
+
const rows = effectiveRows(props);
|
|
101
|
+
const selected = findPickerRow(rows, props.model);
|
|
102
|
+
const words = query.toLowerCase().trim().split(/\s+/).filter(Boolean);
|
|
103
|
+
const filtered = rows.filter((row) => {
|
|
104
|
+
const description = groupPresentationFor(props, row.billingClass)?.description;
|
|
105
|
+
const text = `${row.label} ${row.id} ${row.providerLabel} ${row.billingClassLabel} ${description === void 0 ? payerSummaryForModel(row.catalog) : description ?? ""}`.toLowerCase();
|
|
106
|
+
return words.every((word) => text.includes(word));
|
|
107
|
+
});
|
|
108
|
+
const matchingIds = new Set(filtered.map((row) => row.id));
|
|
109
|
+
const groups = groupPickerRowsByBillingClass(rows, {
|
|
110
|
+
codexOnly: props.codexOnly === true,
|
|
111
|
+
selectedId: props.model,
|
|
112
|
+
collapseScopes: props.collapseScopes !== false
|
|
113
|
+
}).map((group) => {
|
|
114
|
+
const presentation = groupPresentationFor(props, group.billingClass);
|
|
115
|
+
const override = presentation?.description;
|
|
116
|
+
const defaultHint = props.collapseScopes === false && messages.billingHints[group.billingClass] === defaultModelPolicyPickerMessages.billingHints[group.billingClass] ? SCOPED_BILLING_HINTS[group.billingClass] ?? messages.billingHints[group.billingClass] : messages.billingHints[group.billingClass];
|
|
117
|
+
return {
|
|
118
|
+
billingClass: group.billingClass,
|
|
119
|
+
label: presentation?.label ?? group.label,
|
|
120
|
+
rows: group.rows.filter((row) => matchingIds.has(row.id)),
|
|
121
|
+
description: override === void 0 ? group.billingClass === "opengeni_credits" ? null : defaultHint : override
|
|
122
|
+
};
|
|
123
|
+
}).filter((group) => group.rows.length > 0);
|
|
124
|
+
const anySelectable = rows.some((row) => row.selectable);
|
|
125
|
+
const unsupportedAttachments = props.hasImageAttachments === true && selected?.catalog.capabilities?.inputModalities.includes("image") === false;
|
|
126
|
+
return {
|
|
127
|
+
messages,
|
|
128
|
+
rows,
|
|
129
|
+
selected,
|
|
130
|
+
anySelectable,
|
|
131
|
+
searching: words.length > 0,
|
|
132
|
+
groups,
|
|
133
|
+
matchCount: filtered.length,
|
|
134
|
+
thinking: selected ? modelPickerThinking(props, selected) : null,
|
|
135
|
+
unsupportedAttachments
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function modelPickerThinking(props, selected) {
|
|
139
|
+
const efforts = effortOptionsForModel(selected.catalog);
|
|
140
|
+
const showThinking = efforts.length > 1 && selected.catalog.capabilities?.reasoning.runnable !== false;
|
|
141
|
+
const showFast = props.allowLatencyMode !== false && runnableLatencyModesForModel(selected.catalog).includes("fast");
|
|
142
|
+
if (!showThinking && !showFast) return null;
|
|
143
|
+
return {
|
|
144
|
+
efforts,
|
|
145
|
+
value: coerceReasoningEffortForModel(selected.catalog, props.effort),
|
|
146
|
+
showThinking,
|
|
147
|
+
showFast,
|
|
148
|
+
disabled: !selected.selectable
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function modelPickerChoice(props, row) {
|
|
152
|
+
if (!row.selectable) return null;
|
|
153
|
+
return {
|
|
154
|
+
model: row.id === props.model ? null : row.id,
|
|
155
|
+
effort: coerceReasoningEffortForModel(row.catalog, props.effort),
|
|
156
|
+
latencyMode: props.latencyMode !== "standard" && !runnableLatencyModesForModel(row.catalog).includes(props.latencyMode) ? "standard" : null
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function compactEffortLabel(effort, label) {
|
|
160
|
+
return effort === "xhigh" ? "X-high" : label;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export {
|
|
164
|
+
defaultModelPolicyPickerMessages,
|
|
165
|
+
SCOPED_BILLING_HINTS,
|
|
166
|
+
isCodexPickerModel,
|
|
167
|
+
billingClassForMissingSelection,
|
|
168
|
+
groupPresentationFor,
|
|
169
|
+
effectiveRows,
|
|
170
|
+
modelPickerMenuView,
|
|
171
|
+
modelPickerChoice,
|
|
172
|
+
compactEffortLabel
|
|
173
|
+
};
|
|
174
|
+
//# sourceMappingURL=chunk-ZOZAPAUO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/model-picker-model.ts"],"sourcesContent":["/**\n * The model picker's presentation logic, free of any renderer: which rows show,\n * how they group and filter, and which thinking/latency controls apply. The web\n * menu and native sheets both render from this.\n */\nimport type { ClientModel, LatencyMode, ReasoningEffort } from \"@opengeni/sdk\";\nimport {\n coerceReasoningEffortForModel,\n effortOptionsForModel,\n findPickerRow,\n groupPickerRowsByBillingClass,\n payerSummaryForModel,\n projectClientModelRows,\n runnableLatencyModesForModel,\n scopedBillingClassLabel,\n type PickerBillingClass,\n type PickerModelRow,\n} from \"./model-policy\";\n\ntype ClientPickerModelRow = PickerModelRow<ClientModel>;\n\nexport type ModelPolicyPickerMessages = {\n label: string;\n loading: string;\n noModels: string;\n connectTitle: string;\n connectBody: string;\n connectAction: string;\n thinking: string;\n fast: string;\n fastRateHint: string;\n codexOnly: string;\n searchLabel?: string;\n searchPlaceholder?: string;\n currentModel?: string;\n noMatches?: string;\n unsupportedAttachments?: string;\n thinkingEffort?: string;\n selected?: string;\n free?: string;\n\n billingHints: Record<PickerBillingClass, string>;\n};\n\nexport const defaultModelPolicyPickerMessages: ModelPolicyPickerMessages = {\n label: \"Model and effort\",\n loading: \"Loading model catalog…\",\n noModels: \"No models available.\",\n connectTitle: \"Connect a model\",\n connectBody: \"Use a subscription or a provider key you already have.\",\n connectAction: \"Open Models\",\n thinking: \"Thinking\",\n fast: \"Fast\",\n fastRateHint: \"2× rate\",\n codexOnly: \"Codex-only session\",\n searchLabel: \"Search models or providers\",\n searchPlaceholder: \"Search models or providers…\",\n currentModel: \"Current model\",\n noMatches: \"No matching models. Try a model or provider name.\",\n unsupportedAttachments: \"This model cannot view the attached images.\",\n thinkingEffort: \"Thinking effort\",\n selected: \"Selected\",\n free: \"Free\",\n\n billingHints: {\n opengeni_credits: \"Provided by Opengeni\",\n external: \"Provider terms and limits apply\",\n codex_subscription: \"ChatGPT / Codex plan\",\n supergrok_subscription: \"SuperGrok / xAI plan\",\n claude_subscription: \"Claude plan\",\n byok: \"Billed to the connected provider account\",\n organization_byok: \"Billed to the connected provider account\",\n },\n};\n\n/** Host branding for one payment group; the icon type belongs to the renderer. */\nexport type ModelPickerGroupBranding<TIcon = unknown> = {\n label?: string | undefined;\n /** Omit to preserve the default; null hides the supporting text. */\n description?: string | null | undefined;\n /** Decorative, non-interactive content. Omit for the default; null hides it. */\n icon?: TIcon | undefined;\n};\n\nexport type ModelPickerGroupPresentation<TIcon = unknown> = Partial<\n Record<PickerBillingClass, ModelPickerGroupBranding<TIcon>>\n>;\n\n/** The renderer-neutral inputs every picker surface shares. */\nexport type ModelPickerInput<TIcon = unknown> = {\n groupPresentation?: ModelPickerGroupPresentation<TIcon> | undefined;\n models?: ClientModel[] | undefined;\n rows?: PickerModelRow[] | undefined;\n hasImageAttachments?: boolean | undefined;\n model: string;\n effort: ReasoningEffort;\n latencyMode: LatencyMode;\n codexOnly?: boolean | undefined;\n collapseScopes?: boolean | undefined;\n allowLatencyMode?: boolean | undefined;\n messages?: Partial<ModelPolicyPickerMessages> | undefined;\n};\n\n/** Models settings keeps naming who is billed for a key. */\nexport const SCOPED_BILLING_HINTS: Partial<Record<PickerBillingClass, string>> = {\n byok: \"Billed to the workspace provider account\",\n organization_byok: \"Billed to the organization provider account\",\n};\n\nexport function isCodexPickerModel(model: ClientModel): boolean {\n return model.id.startsWith(\"codex/\") || model.source === \"codex\";\n}\n\n/** The payment group a selection the catalog no longer lists most likely belonged to. */\nexport function billingClassForMissingSelection(modelId: string): PickerBillingClass {\n if (modelId.startsWith(\"workspace-claude-subscription/\")) return \"claude_subscription\";\n if (modelId.startsWith(\"workspace-anthropic/\")) return \"byok\";\n if (modelId.startsWith(\"organization-claude-subscription/\")) return \"claude_subscription\";\n if (modelId.startsWith(\"organization-anthropic/\")) return \"organization_byok\";\n if (modelId.startsWith(\"workspace-gateway/\")) return \"byok\";\n if (modelId.startsWith(\"workspace-openrouter/\")) return \"byok\";\n if (modelId.startsWith(\"workspace-opper/\")) return \"byok\";\n // A deployment OpenRouter or Opper ID does not encode its workspace-facing cost.\n // Missing rows therefore use the credits-safe rail instead of falsely\n // claiming that an unknown former selection was externally funded.\n if (modelId.startsWith(\"openrouter/\")) return \"opengeni_credits\";\n if (modelId.startsWith(\"opper/\")) return \"opengeni_credits\";\n if (modelId.startsWith(\"codex/\")) return \"codex_subscription\";\n if (modelId.startsWith(\"supergrok/\")) return \"supergrok_subscription\";\n return \"opengeni_credits\";\n}\n\nfunction applyCodexOnly(\n rows: ClientPickerModelRow[],\n codexOnly: boolean,\n unavailableReason: string,\n): ClientPickerModelRow[] {\n if (!codexOnly) return rows;\n return rows.map((row) =>\n isCodexPickerModel(row.catalog)\n ? row\n : {\n ...row,\n selectable: false,\n unavailableReason: row.unavailableReason ?? unavailableReason,\n },\n );\n}\n\n/**\n * Host branding for a payment group. While scopes are collapsed, API keys are\n * one group, so either API-key presentation serves both.\n */\nexport function groupPresentationFor<TIcon>(\n props: {\n groupPresentation?: ModelPickerGroupPresentation<TIcon> | undefined;\n collapseScopes?: boolean | undefined;\n },\n billingClass: PickerBillingClass,\n): ModelPickerGroupBranding<TIcon> | undefined {\n const own = props.groupPresentation?.[billingClass];\n if (own !== undefined || props.collapseScopes === false) return own;\n if (billingClass === \"byok\") return props.groupPresentation?.organization_byok;\n if (billingClass === \"organization_byok\") return props.groupPresentation?.byok;\n return undefined;\n}\n\nexport function effectiveRows<TIcon>(props: ModelPickerInput<TIcon>): ClientPickerModelRow[] {\n const rows = props.rows !== undefined ? props.rows : projectClientModelRows(props.models ?? []);\n const messages = { ...defaultModelPolicyPickerMessages, ...props.messages };\n return applyCodexOnly(rows, props.codexOnly === true, messages.codexOnly).map((row) => {\n const scoped =\n props.collapseScopes === false\n ? {\n ...row,\n label: row.catalog.label,\n billingClassLabel: scopedBillingClassLabel(row.billingClass),\n }\n : row;\n if (props.collapseScopes === false) {\n if (row.catalog.shortLabel) scoped.shortLabel = row.catalog.shortLabel;\n else delete scoped.shortLabel;\n }\n const label = groupPresentationFor(props, row.billingClass)?.label;\n return label === undefined ? scoped : { ...scoped, billingClassLabel: label };\n });\n}\n\nexport type ModelPickerMenuGroup = {\n billingClass: PickerBillingClass;\n label: string;\n description: string | null;\n rows: ClientPickerModelRow[];\n};\n\nexport type ModelPickerThinking = {\n efforts: ReasoningEffort[];\n value: ReasoningEffort;\n showThinking: boolean;\n showFast: boolean;\n /** The selected row cannot run, so its controls are read-only. */\n disabled: boolean;\n};\n\nexport type ModelPickerMenuView = {\n messages: ModelPolicyPickerMessages;\n rows: ClientPickerModelRow[];\n selected: ClientPickerModelRow | null;\n /** Any row can run; otherwise the surface offers to connect models instead. */\n anySelectable: boolean;\n /** Whether the query is non-empty (decides \"no matches\" versus \"no models\"). */\n searching: boolean;\n groups: ModelPickerMenuGroup[];\n matchCount: number;\n /** Thinking and Fast controls for the selected model, or null when it has none. */\n thinking: ModelPickerThinking | null;\n /** The selected model cannot view images the draft carries. */\n unsupportedAttachments: boolean;\n};\n\n/** Everything a picker menu shows for this input and search query. */\nexport function modelPickerMenuView<TIcon>(\n props: ModelPickerInput<TIcon>,\n query: string,\n): ModelPickerMenuView {\n const messages = { ...defaultModelPolicyPickerMessages, ...props.messages };\n const rows = effectiveRows(props);\n const selected = findPickerRow(rows, props.model);\n const words = query.toLowerCase().trim().split(/\\s+/).filter(Boolean);\n const filtered = rows.filter((row) => {\n const description = groupPresentationFor(props, row.billingClass)?.description;\n const text =\n `${row.label} ${row.id} ${row.providerLabel} ${row.billingClassLabel} ${description === undefined ? payerSummaryForModel(row.catalog) : (description ?? \"\")}`.toLowerCase();\n return words.every((word) => text.includes(word));\n });\n const matchingIds = new Set(filtered.map((row) => row.id));\n const groups = groupPickerRowsByBillingClass(rows, {\n codexOnly: props.codexOnly === true,\n selectedId: props.model,\n collapseScopes: props.collapseScopes !== false,\n })\n .map((group) => {\n const presentation = groupPresentationFor(props, group.billingClass);\n const override = presentation?.description;\n const defaultHint =\n props.collapseScopes === false &&\n messages.billingHints[group.billingClass] ===\n defaultModelPolicyPickerMessages.billingHints[group.billingClass]\n ? (SCOPED_BILLING_HINTS[group.billingClass] ?? messages.billingHints[group.billingClass])\n : messages.billingHints[group.billingClass];\n return {\n billingClass: group.billingClass,\n label: presentation?.label ?? group.label,\n rows: group.rows.filter((row) => matchingIds.has(row.id)),\n description:\n override === undefined\n ? group.billingClass === \"opengeni_credits\"\n ? null\n : defaultHint\n : override,\n };\n })\n .filter((group) => group.rows.length > 0);\n const anySelectable = rows.some((row) => row.selectable);\n const unsupportedAttachments =\n props.hasImageAttachments === true &&\n selected?.catalog.capabilities?.inputModalities.includes(\"image\") === false;\n return {\n messages,\n rows,\n selected,\n anySelectable,\n searching: words.length > 0,\n groups,\n matchCount: filtered.length,\n thinking: selected ? modelPickerThinking(props, selected) : null,\n unsupportedAttachments,\n };\n}\n\nfunction modelPickerThinking(\n props: Pick<ModelPickerInput, \"effort\" | \"allowLatencyMode\">,\n selected: ClientPickerModelRow,\n): ModelPickerThinking | null {\n const efforts = effortOptionsForModel(selected.catalog);\n const showThinking =\n efforts.length > 1 && selected.catalog.capabilities?.reasoning.runnable !== false;\n const showFast =\n props.allowLatencyMode !== false &&\n runnableLatencyModesForModel(selected.catalog).includes(\"fast\");\n if (!showThinking && !showFast) return null;\n return {\n efforts,\n value: coerceReasoningEffortForModel(selected.catalog, props.effort),\n showThinking,\n showFast,\n disabled: !selected.selectable,\n };\n}\n\nexport type ModelPickerChoice = {\n /** The new model, or null when the row is already selected. */\n model: string | null;\n /** Always reported, so hosts can commit model and effort together. */\n effort: ReasoningEffort;\n /** Fast falls back to standard when the new model cannot run it. */\n latencyMode: LatencyMode | null;\n};\n\n/** What choosing a row changes, or null when the row cannot be chosen. */\nexport function modelPickerChoice(\n props: Pick<ModelPickerInput, \"model\" | \"effort\" | \"latencyMode\">,\n row: ClientPickerModelRow,\n): ModelPickerChoice | null {\n if (!row.selectable) return null;\n return {\n model: row.id === props.model ? null : row.id,\n effort: coerceReasoningEffortForModel(row.catalog, props.effort),\n latencyMode:\n props.latencyMode !== \"standard\" &&\n !runnableLatencyModesForModel(row.catalog).includes(props.latencyMode)\n ? \"standard\"\n : null,\n };\n}\n\n/** The web segmented control's short labels (\"X-high\" fits a phone row). */\nexport function compactEffortLabel(effort: ReasoningEffort, label: string): string {\n return effort === \"xhigh\" ? \"X-high\" : label;\n}\n"],"mappings":"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","names":[]}
|