@opengeni/react 4.3.3-canary.39786771332001 → 4.5.0
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/dist/app/app-state.js +29 -29
- package/dist/app/components/Composer.js +27 -27
- package/dist/app/components/agent/agent-capability-picker.js +4 -4
- package/dist/app/components/artifacts/artifact-browse-controls.js +2 -2
- package/dist/app/components/artifacts/artifact-library.js +19 -19
- package/dist/app/components/artifacts/artifact-page-chrome.js +2 -2
- package/dist/app/components/artifacts/chat-interactive-block.js +16 -16
- package/dist/app/components/artifacts/inline-chat-image.js +31 -30
- package/dist/app/components/artifacts/retained-file-preview.js +35 -34
- package/dist/app/components/artifacts/retained-text-preview.js +5 -5
- package/dist/app/components/artifacts/site-audience.js +4 -4
- package/dist/app/components/artifacts/site-conversations.js +22 -21
- package/dist/app/components/artifacts/site-data.js +19 -19
- package/dist/app/components/artifacts/site-publishing.js +41 -41
- package/dist/app/components/artifacts/site-settings.js +50 -50
- package/dist/app/components/billing-class-mark.js +5 -5
- package/dist/app/components/capabilities/capability-detail-sheet.js +9 -9
- package/dist/app/components/capabilities/capability-logo-source.js +12 -12
- package/dist/app/components/capabilities/connector-tool-permissions.js +3 -3
- package/dist/app/components/capabilities/native-connect-setup.js +14 -14
- package/dist/app/components/capabilities/perform-capability-action.js +1 -1
- package/dist/app/components/capabilities/prepared-mcp-setup-card.js +16 -16
- package/dist/app/components/capabilities/session-capability-card.js +94 -76
- package/dist/app/components/capabilities/session-capability-card.js.map +1 -1
- package/dist/app/components/capabilities/session-chrome-card.css +1023 -0
- package/dist/app/components/capabilities/session-chrome-card.css.map +1 -0
- package/dist/app/components/capabilities/session-chrome-card.d.ts +18 -0
- package/dist/app/components/capabilities/session-chrome-card.js +72 -0
- package/dist/app/components/capabilities/session-custom-mcp-card.js +20 -20
- package/dist/app/components/capabilities/session-github-card.js +24 -24
- package/dist/app/components/capabilities/session-machine-card.d.ts +27 -1
- package/dist/app/components/capabilities/session-machine-card.js +40 -36
- package/dist/app/components/capabilities/use-capabilities-catalog.js +3 -3
- package/dist/app/components/capabilities/use-connection-accounts.js +1 -1
- package/dist/app/components/command-menu/chat-status.js +18 -17
- package/dist/app/components/command-menu/chat-switcher.js +19 -18
- package/dist/app/components/command-menu/chat-switcher.js.map +1 -1
- package/dist/app/components/command-menu/command-menu.js +36 -114
- package/dist/app/components/command-menu/command-menu.js.map +1 -1
- package/dist/app/components/command-menu/shortcut-sheet.js +17 -17
- package/dist/app/components/composer-capabilities-menu-body.js +3 -3
- package/dist/app/components/composer-mobile-plus-panel.js +20 -20
- package/dist/app/components/composer-mobile-plus.js +1 -1
- package/dist/app/components/credit-required-gate.js +1 -1
- package/dist/app/components/credit-required-prompt.js +12 -12
- package/dist/app/components/credits/coupon-redeem.js +2 -2
- package/dist/app/components/credits/credit-refusal-notice.js +2 -2
- package/dist/app/components/desktop/app-shots.js +7 -7
- package/dist/app/components/desktop/this-computer.js +4 -4
- package/dist/app/components/feedback.js +4 -4
- package/dist/app/components/follow-up-repository-menu-body.js +5 -5
- package/dist/app/components/follow-up-repository-picker.js +1 -1
- package/dist/app/components/github-app-connect-launcher.js +2 -2
- package/dist/app/components/in-app-help-link.js +2 -2
- package/dist/app/components/knowledge/agent-learning-settings.js +3 -3
- package/dist/app/components/machines/connect-machine-dialog.js +18 -18
- package/dist/app/components/markdown.js +9 -9
- package/dist/app/components/message-context-pills.js +2 -2
- package/dist/app/components/models/models-ui.js +8 -8
- package/dist/app/components/new-session-starters.js +2 -2
- package/dist/app/components/pickers.js +9 -9
- package/dist/app/components/rail/rail-context.js +2 -2
- package/dist/app/components/rail/rail-sections.js +69 -66
- package/dist/app/components/rail/session-header.js +49 -48
- package/dist/app/components/rail/session-list.js +68 -65
- package/dist/app/components/rail/session-row-content.d.ts +6 -2
- package/dist/app/components/rail/session-row-content.js +1 -1
- package/dist/app/components/rail/session-row-hover-details.js +24 -23
- package/dist/app/components/rail/session-shell.js +107 -104
- package/dist/app/components/rail/site-session-group-heading.d.ts +7 -1
- package/dist/app/components/rail/site-session-group-heading.js +20 -3
- package/dist/app/components/repository-picker.js +5 -5
- package/dist/app/components/secrets/session-secrets-panel.js +3 -3
- package/dist/app/components/session/agent-configuration-panel.js +38 -38
- package/dist/app/components/session/artifact-link-boundary.js +2 -2
- package/dist/app/components/session/artifact-session-page.js +4 -4
- package/dist/app/components/session/banners.js +11 -11
- package/dist/app/components/session/codex-account-indicator.js +12 -12
- package/dist/app/components/session/editable-artifacts-workspace.js +45 -45
- package/dist/app/components/session/failed-session-banner.js +11 -11
- package/dist/app/components/session/human-input.js +59 -55
- package/dist/app/components/session/inspector.js +91 -87
- package/dist/app/components/session/inspector.js.map +1 -1
- package/dist/app/components/session/message-actions.js +4 -4
- package/dist/app/components/session/message-resource-attachments.js +21 -20
- package/dist/app/components/session/message-resource-attachments.js.map +1 -1
- package/dist/app/components/session/model-account-indicator.js +11 -11
- package/dist/app/components/session/model-context-inspector.js +2 -2
- package/dist/app/components/session/model-recovery-notice.js +3 -3
- package/dist/app/components/session/new-session-settings-menu.js +12 -12
- package/dist/app/components/session/sandbox-switcher.js +16 -16
- package/dist/app/components/session/sandbox-workspace.js +83 -79
- package/dist/app/components/session/search-markdown-highlight.js +10 -10
- package/dist/app/components/session/search-results-view.js +11 -11
- package/dist/app/components/session/session-admin-access.js +9 -9
- package/dist/app/components/session/session-admission-notice.js +6 -6
- package/dist/app/components/session/session-machine-access-notice.js +6 -6
- package/dist/app/components/session/session-retention.js +4 -4
- package/dist/app/components/session/session-search-dialog.js +12 -12
- package/dist/app/components/session/session-skill-reviews.js +1 -1
- package/dist/app/components/session/session-tenancy-control.d.ts +2 -0
- package/dist/app/components/session/session-tenancy-control.js +41 -26
- package/dist/app/components/session/session-tenancy-control.js.map +1 -1
- package/dist/app/components/session/session-usage-limit-section.js +11 -11
- package/dist/app/components/session/session-wait-status.js +10 -9
- package/dist/app/components/session/session-wait-status.js.map +1 -1
- package/dist/app/components/session/site-origin-link.d.ts +1 -0
- package/dist/app/components/session/site-origin-link.js +2 -2
- package/dist/app/components/session/subagents.js +17 -16
- package/dist/app/components/session-connectors-menu-body.js +5 -5
- package/dist/app/components/settings/row-select.js +1 -1
- package/dist/app/components/transcription-settings.js +2 -2
- package/dist/app/components/ui/destructive-confirm.js +6 -6
- package/dist/app/components/usage/usage-entry.js +8 -8
- package/dist/app/components/workspace-composer-plus.js +22 -22
- package/dist/app/embed/memory-navigation.js +2 -2
- package/dist/app/embed/session-app.js +275 -269
- package/dist/app/lib/actions/actions-provider.js +14 -14
- package/dist/app/lib/actions/held-modifier.d.ts +11 -0
- package/dist/app/lib/app-surfaces.js +2 -2
- package/dist/app/lib/codex-usage-query.js +6 -6
- package/dist/app/lib/composer-connectors.js +13 -13
- package/dist/app/lib/console-site.d.ts +6 -0
- package/dist/app/lib/console-site.js +14 -0
- package/dist/app/lib/console-text.js +2 -2
- package/dist/app/lib/events.js +18 -17
- package/dist/app/lib/failed-session-copy.js +3 -3
- package/dist/app/lib/model-access-onboarding.js +3 -3
- package/dist/app/lib/move-chat-to-machine.js +3 -3
- package/dist/app/lib/navigation.d.ts +5 -0
- package/dist/app/lib/navigation.js +1 -1
- package/dist/app/lib/routes.d.ts +17 -0
- package/dist/app/lib/routes.js +9 -3
- package/dist/app/lib/session-branch-cache.js +14 -13
- package/dist/app/lib/session-create.js +2 -2
- package/dist/app/lib/session-deep-link.js +2 -2
- package/dist/app/lib/session-failure-toasts.d.ts +8 -0
- package/dist/app/lib/session-group-pagination.js +14 -13
- package/dist/app/lib/session-hover-facts.js +15 -14
- package/dist/app/lib/session-model.js +3 -3
- package/dist/app/lib/session-rail.js +10 -9
- package/dist/app/lib/session-rename.js +3 -3
- package/dist/app/lib/session-ui-features.d.ts +6 -1
- package/dist/app/lib/session-ui-features.js +1 -1
- package/dist/app/lib/sessions-group.d.ts +43 -3
- package/dist/app/lib/sessions-group.js +22 -15
- package/dist/app/lib/shared-query.js +3 -3
- package/dist/app/lib/site-opened.d.ts +6 -0
- package/dist/app/lib/site-opened.js +10 -0
- package/dist/app/lib/turn-failure-analytics.js +5 -5
- package/dist/app/lib/use-duplicate-site.js +3 -3
- package/dist/app/lib/use-follow-up-repositories.js +4 -4
- package/dist/app/lib/use-session-list-hint-refresh.d.ts +20 -2
- package/dist/app/lib/use-session-list-hint-refresh.js +5 -1
- package/dist/app/lib/use-workspace-machines.js +6 -6
- package/dist/app/lib/use-workspace-model-catalog.js +8 -8
- package/dist/app/lib/use-workspace-rigs.js +8 -8
- package/dist/app/lib/workspace-navigation-preference.js +5 -5
- package/dist/app/lib/workspace-scope-context.js +4 -4
- package/dist/app/routes/artifacts.js +136 -153
- package/dist/app/routes/artifacts.js.map +1 -1
- package/dist/app/routes/retained-artifact.js +63 -62
- package/dist/app/routes/retained-artifact.js.map +1 -1
- package/dist/app/routes/session-unavailable.js +7 -5
- package/dist/app/routes/session.js +177 -173
- package/dist/app/routes/sessions-index-hydration.js +3 -3
- package/dist/app/routes/sessions-index.js +123 -121
- package/dist/app/routes/site-view.d.ts +11 -0
- package/dist/app/routes/site-view.js +597 -0
- package/dist/app/routes/site-view.js.map +1 -0
- package/dist/artifacts-document.js +4 -4
- package/dist/artifacts-presentation.js +4 -4
- package/dist/artifacts-spreadsheet.js +4 -4
- package/dist/artifacts.js +39 -39
- package/dist/{browser-viewer-RYYQSRTC.js → browser-viewer-QMCNV4RI.js} +9 -7
- package/dist/{chat-interactive-block-ABCRKXJ4.js → chat-interactive-block-PMIAUXSO.js} +6 -6
- package/dist/{chunk-GIZGNFIX.js → chunk-22FFOHPT.js} +11 -11
- package/dist/chunk-22GTC4MZ.js +15 -0
- package/dist/chunk-22GTC4MZ.js.map +1 -0
- package/dist/{chunk-Z5WMLJKI.js → chunk-22JFMNMF.js} +92 -4
- package/dist/chunk-22JFMNMF.js.map +1 -0
- package/dist/{chunk-UHFWF6ZU.js → chunk-2FPS5H2D.js} +2 -2
- package/dist/{chunk-NAWXARTY.js → chunk-2KO2G3RI.js} +72 -6
- package/dist/chunk-2KO2G3RI.js.map +1 -0
- package/dist/{chunk-5POTDNQT.js → chunk-2NC7NZCE.js} +6 -6
- package/dist/{chunk-ZKYYZH6L.js → chunk-2QBYDGWO.js} +9 -9
- package/dist/{chunk-TWXIFWBD.js → chunk-34EU25RL.js} +2 -2
- package/dist/{chunk-LQKKSUCR.js → chunk-35BC2FU2.js} +19 -19
- package/dist/{chunk-PTGRFAMH.js → chunk-3ABPIUCK.js} +2 -2
- package/dist/{chunk-S4SC5SSV.js → chunk-3GU7AWG7.js} +18 -18
- package/dist/{chunk-722UO6YQ.js → chunk-3PEXVG4D.js} +2 -2
- package/dist/{chunk-OQAAI33Y.js → chunk-3RMKPHBL.js} +3 -3
- package/dist/{chunk-6JKZILLF.js → chunk-3RQUWFZT.js} +67 -67
- package/dist/{chunk-6JKZILLF.js.map → chunk-3RQUWFZT.js.map} +1 -1
- package/dist/{chunk-GCGTYXJJ.js → chunk-3STBLX4O.js} +9 -9
- package/dist/{chunk-YXIW7H4N.js → chunk-3X5FKDYQ.js} +28 -28
- package/dist/{chunk-KTRKZRID.js → chunk-4GLLWX33.js} +11 -11
- package/dist/{chunk-ROQOVH4N.js → chunk-4HEXNAFI.js} +20 -20
- package/dist/chunk-4HEXNAFI.js.map +1 -0
- package/dist/{chunk-SD2K5ZN5.js → chunk-4LPA25NQ.js} +4 -4
- package/dist/{chunk-DKCX643S.js → chunk-4RMN4E2Y.js} +13 -13
- package/dist/{chunk-E5FCEDMU.js → chunk-4SAGYEVB.js} +2 -2
- package/dist/{chunk-HTT3FB7T.js → chunk-4VK2R5QC.js} +3 -3
- package/dist/{chunk-CKG2EG62.js → chunk-4XQC7VLT.js} +14 -14
- package/dist/{chunk-IVOA3DXA.js → chunk-4YXAQMTD.js} +12 -12
- package/dist/{chunk-HOJGAJAB.js → chunk-52WK2GGK.js} +8 -8
- package/dist/{chunk-NYZQ7LO7.js → chunk-552UYIQ7.js} +20 -20
- package/dist/{chunk-LEXPBQ56.js → chunk-5DSKMG2I.js} +4 -4
- package/dist/{chunk-WNG757ID.js → chunk-5FA455GR.js} +4 -4
- package/dist/{chunk-MNWQAYY3.js → chunk-5FEN3KYH.js} +11 -11
- package/dist/{chunk-OSVHU2WU.js → chunk-5JHRMUAZ.js} +12 -12
- package/dist/{chunk-PM3OSANE.js → chunk-5MJHH72T.js} +14 -3
- package/dist/chunk-5MJHH72T.js.map +1 -0
- package/dist/{chunk-RKB2Z457.js → chunk-5VGJXWQ2.js} +2 -2
- package/dist/{chunk-GFUUFM2O.js → chunk-5W6ZDKRR.js} +6 -6
- package/dist/{chunk-NDETTZQA.js → chunk-5W7KJ5NQ.js} +37 -37
- package/dist/{chunk-Q35YZVDZ.js → chunk-5Y2FPLZE.js} +9 -9
- package/dist/{chunk-6W3LF3DB.js → chunk-5YFY4SFC.js} +2 -12
- package/dist/chunk-5YFY4SFC.js.map +1 -0
- package/dist/{chunk-F3NERYBQ.js → chunk-62VER7O4.js} +6 -6
- package/dist/{chunk-FBMU3VK5.js → chunk-6DCEDIF6.js} +2 -2
- package/dist/{chunk-WUHB422G.js → chunk-73WI7FL2.js} +18 -18
- package/dist/chunk-756MKA2J.js +45 -0
- package/dist/chunk-756MKA2J.js.map +1 -0
- package/dist/{chunk-QECZVL7S.js → chunk-7FJMRJDG.js} +2 -2
- package/dist/{chunk-7KGKDWWR.js → chunk-7HFLYNWN.js} +2 -2
- package/dist/{chunk-XVM566II.js → chunk-7KIENXRE.js} +2 -2
- package/dist/{chunk-CBY5CXBD.js → chunk-7NPCEBZE.js} +5 -5
- package/dist/{chunk-46VBQG2D.js → chunk-7P4AQMGA.js} +13 -13
- package/dist/{chunk-CKZW7A5S.js → chunk-7TCT7KPQ.js} +742 -644
- package/dist/chunk-7TCT7KPQ.js.map +1 -0
- package/dist/{chunk-O77Q4NG2.js → chunk-7XO7YKPC.js} +283 -1038
- package/dist/chunk-7XO7YKPC.js.map +1 -0
- package/dist/{chunk-S7PVL7XH.js → chunk-A4BD4ZVB.js} +4 -4
- package/dist/{chunk-VSQHDBHU.js → chunk-ACL2V2KE.js} +68 -35
- package/dist/chunk-ACL2V2KE.js.map +1 -0
- package/dist/{chunk-73SOCVLS.js → chunk-AIEXYO2X.js} +3 -3
- package/dist/{chunk-U7TC2XJQ.js → chunk-AJPW3SV4.js} +3 -3
- package/dist/{chunk-HRJQAFKR.js → chunk-AX6YJA5U.js} +2 -2
- package/dist/{chunk-P5WABK2H.js → chunk-BCM7C3MJ.js} +9 -9
- package/dist/{chunk-DT7BORXG.js → chunk-BMJTNPWK.js} +2 -2
- package/dist/{chunk-HIHO2QE7.js → chunk-BT2MVGHT.js} +2 -2
- package/dist/{chunk-3XOISKZC.js → chunk-BXQYAAVE.js} +4 -4
- package/dist/{chunk-IBTXYLBW.js → chunk-CCFWY4GF.js} +2 -2
- package/dist/{chunk-ZOC3OP6F.js → chunk-CCR33J7L.js} +2 -2
- package/dist/{chunk-GTQ3SNEI.js → chunk-CD3MO3IC.js} +2 -2
- package/dist/{chunk-WSMYOLHG.js → chunk-CDEXRJB6.js} +5 -5
- package/dist/{chunk-3GLAPCVI.js → chunk-CFFNT2OY.js} +8 -8
- package/dist/{chunk-FUSFVUIJ.js → chunk-CMLJSF2F.js} +12 -12
- package/dist/{chunk-O4DYOSOL.js → chunk-CP7ZQHBW.js} +13 -13
- package/dist/{chunk-IOKSNX74.js → chunk-D5OWJZQR.js} +2 -2
- package/dist/{chunk-SQGXMHJO.js → chunk-DGLRZMXL.js} +3 -3
- package/dist/{chunk-GNEHAPKV.js → chunk-DJFTH2DI.js} +3 -3
- package/dist/{chunk-HQG4SLTE.js → chunk-DYJGYGPB.js} +2 -2
- package/dist/{chunk-4EAF3HSD.js → chunk-EJ7WARW7.js} +2 -2
- package/dist/{chunk-3AA6RNGE.js → chunk-ENS6E4RZ.js} +2 -2
- package/dist/{chunk-OOEO4MKY.js → chunk-EPWD4KRA.js} +2 -2
- package/dist/{chunk-V5RJAWRP.js → chunk-EQE3MNQN.js} +5 -5
- package/dist/{chunk-TSBE4KOQ.js → chunk-EWL6NDOO.js} +3 -3
- package/dist/{chunk-OO2T63BY.js → chunk-EYS4ZOF5.js} +2 -2
- package/dist/{chunk-IC7KNOBB.js → chunk-FDAV72IX.js} +7 -7
- package/dist/{chunk-AG7VGUIW.js → chunk-FFNPUSVO.js} +7 -7
- package/dist/{chunk-P5T36BA3.js → chunk-FRP64DEK.js} +2 -2
- package/dist/{chunk-KBF3SE7G.js → chunk-FSP334UU.js} +2 -2
- package/dist/{chunk-ZHFKMMOT.js → chunk-FTX5CNHA.js} +6 -6
- package/dist/{chunk-KYBALSWW.js → chunk-FWOBNL2A.js} +1 -1
- package/dist/{chunk-HJ5XWW62.js → chunk-FWYEZ3LE.js} +34 -34
- package/dist/{chunk-WSLPZ43N.js → chunk-G4HQUBO4.js} +12 -12
- package/dist/{chunk-CSHBR2IZ.js → chunk-GDLDBR6B.js} +2 -2
- package/dist/chunk-GGV4NSG3.js +792 -0
- package/dist/chunk-GGV4NSG3.js.map +1 -0
- package/dist/{chunk-G3S2F35T.js → chunk-GHHM6WN4.js} +3 -3
- package/dist/{chunk-OANSIX34.js → chunk-GRSODLVO.js} +4 -4
- package/dist/{chunk-DDIBZA4X.js → chunk-GT7JFQ4E.js} +405 -148
- package/dist/chunk-GT7JFQ4E.js.map +1 -0
- package/dist/{chunk-EU6XSQFM.js → chunk-GXW2I2M2.js} +2 -2
- package/dist/{chunk-4246UYVG.js → chunk-GZS37O3G.js} +1 -1
- package/dist/{chunk-XFNLU7EW.js → chunk-H5M33DAL.js} +15 -6
- package/dist/chunk-H5M33DAL.js.map +1 -0
- package/dist/{chunk-Y7WMW74G.js → chunk-HQWVDQXW.js} +7 -7
- package/dist/{chunk-YTZQV2DD.js → chunk-HU6JTNWF.js} +2 -2
- package/dist/{chunk-QRVNI5V6.js → chunk-I6KIQKU6.js} +3 -3
- package/dist/{chunk-Q262Y2YX.js → chunk-IBA5FMRE.js} +141 -137
- package/dist/chunk-IBA5FMRE.js.map +1 -0
- package/dist/{chunk-BNUPYHHZ.js → chunk-IDXTASGN.js} +4 -4
- package/dist/{chunk-KF3MF6FP.js → chunk-IECRGM6K.js} +3 -2
- package/dist/chunk-IECRGM6K.js.map +1 -0
- package/dist/chunk-IJYL5BZM.js +38 -0
- package/dist/chunk-IJYL5BZM.js.map +1 -0
- package/dist/{chunk-L6RXRRN3.js → chunk-ILDOW2IQ.js} +3 -3
- package/dist/{chunk-VUHPA3XQ.js → chunk-ITX2TB4K.js} +6 -6
- package/dist/{chunk-ETCB6SUJ.js → chunk-J22HD2PB.js} +6 -6
- package/dist/{chunk-U47YDYLQ.js → chunk-J5MEDX7C.js} +8 -8
- package/dist/{chunk-6VQTHC4W.js → chunk-J7FBBLHF.js} +36 -36
- package/dist/{chunk-5JZYPZ72.js → chunk-JFK7NTEA.js} +4 -4
- package/dist/chunk-JFK7NTEA.js.map +1 -0
- package/dist/{chunk-QZRDCFHI.js → chunk-JM4HQPAI.js} +5 -5
- package/dist/{chunk-PIVGX42P.js → chunk-JNY5MT3I.js} +2 -2
- package/dist/{chunk-XWWXIZFP.js → chunk-JO6R5EXF.js} +7 -7
- package/dist/{chunk-MM7OKOTE.js → chunk-JQCGPTZ6.js} +9 -9
- package/dist/chunk-JRSNCSZN.js +37 -0
- package/dist/chunk-JRSNCSZN.js.map +1 -0
- package/dist/{chunk-KNFDWNCH.js → chunk-JXT5QDJC.js} +5 -5
- package/dist/{chunk-OR37STQZ.js → chunk-KEXYBG7Q.js} +3 -3
- package/dist/{chunk-AZVANYMB.js → chunk-KUNFUSZ7.js} +2 -2
- package/dist/{chunk-DXZNDKQD.js → chunk-LEEJBZ5B.js} +2 -2
- package/dist/{chunk-STUCI6QA.js → chunk-LEKBNKLD.js} +1 -1
- package/dist/{chunk-STUCI6QA.js.map → chunk-LEKBNKLD.js.map} +1 -1
- package/dist/{chunk-C535KSTY.js → chunk-LF5CBAOS.js} +4 -4
- package/dist/{chunk-BJIZ7PL7.js → chunk-LHLK7FUA.js} +145 -29
- package/dist/chunk-LHLK7FUA.js.map +1 -0
- package/dist/{chunk-RIMKJBCD.js → chunk-LMPTC4CX.js} +2 -2
- package/dist/{chunk-3KVWXKD6.js → chunk-LQ47YL6E.js} +2 -2
- package/dist/{chunk-H5WGWAYX.js → chunk-LT4J7RHI.js} +13 -13
- package/dist/{chunk-DSGMYES6.js → chunk-MCTTONOW.js} +28 -28
- package/dist/{chunk-IGHELZI7.js → chunk-MIECLOQC.js} +9 -9
- package/dist/{chunk-FM4OUCC2.js → chunk-MOKYT3X3.js} +3 -3
- package/dist/{chunk-GZ64CASI.js → chunk-MVZYNZXE.js} +5 -4
- package/dist/chunk-MVZYNZXE.js.map +1 -0
- package/dist/{chunk-RKILMLA7.js → chunk-MXLKI7BI.js} +3 -3
- package/dist/{chunk-45WYYFP6.js → chunk-N3ZP4IDU.js} +2 -2
- package/dist/{chunk-XRRSFQEV.js → chunk-NAZZLAWX.js} +2 -2
- package/dist/{chunk-UWJ5P5CU.js → chunk-NEK4WB5P.js} +3 -3
- package/dist/{chunk-6L7U46Y2.js → chunk-NKNVIO66.js} +2 -2
- package/dist/{chunk-JKUICTLM.js → chunk-NLAFNMPK.js} +2 -2
- package/dist/{chunk-4LKNIGHB.js → chunk-O2SBHS2N.js} +2 -2
- package/dist/{chunk-D3RK3NGM.js → chunk-PCFK7HKD.js} +17 -17
- package/dist/{chunk-VVCDB2T7.js → chunk-PCJLH45G.js} +3 -3
- package/dist/{chunk-PZ24CYDO.js → chunk-PFAUGEV5.js} +2 -2
- package/dist/{chunk-HGMWMK5K.js → chunk-PO3BH3KQ.js} +2 -2
- package/dist/{chunk-B74GSYR6.js → chunk-PUTS4DYW.js} +2 -2
- package/dist/{chunk-JSIDLTTG.js → chunk-PZ2V2XIK.js} +2 -2
- package/dist/{chunk-TMEQPODK.js → chunk-PZ37VDB5.js} +2 -2
- package/dist/{chunk-QIYBOFUV.js → chunk-QFMLAT7L.js} +246 -237
- package/dist/chunk-QFMLAT7L.js.map +1 -0
- package/dist/{chunk-LVONK3YQ.js → chunk-QRKTESVE.js} +2 -2
- package/dist/{chunk-HT5WSUC7.js → chunk-QXEDIDBZ.js} +3 -3
- package/dist/{chunk-WURSS6MP.js → chunk-R66YMYJU.js} +2 -2
- package/dist/{chunk-HDHK3SXK.js → chunk-RFLYID6H.js} +5 -5
- package/dist/{chunk-V77JK73U.js → chunk-RIYZFKIM.js} +37 -35
- package/dist/chunk-RIYZFKIM.js.map +1 -0
- package/dist/{chunk-VMFID36H.js → chunk-RQNZDTKT.js} +19 -19
- package/dist/{chunk-EHCUFCXM.js → chunk-RYSRFAHN.js} +32 -22
- package/dist/chunk-RYSRFAHN.js.map +1 -0
- package/dist/{chunk-I6VUUEXH.js → chunk-S2U4CDAC.js} +150 -150
- package/dist/chunk-S2U4CDAC.js.map +1 -0
- package/dist/chunk-S37GP7LX.js +204 -0
- package/dist/chunk-S37GP7LX.js.map +1 -0
- package/dist/{chunk-A2EWJQXX.js → chunk-SM5QX6UK.js} +4 -4
- package/dist/{chunk-FBE6AIIW.js → chunk-SOKNCW5U.js} +2 -2
- package/dist/{chunk-Q4NM77K7.js → chunk-SSOO4GWN.js} +193 -194
- package/dist/chunk-SSOO4GWN.js.map +1 -0
- package/dist/{chunk-PFKTGZKE.js → chunk-SY2AAZNB.js} +2 -2
- package/dist/{chunk-DFZMKCVP.js → chunk-TIQPKOFW.js} +4 -4
- package/dist/{chunk-HPPKLBTJ.js → chunk-TJQDL3JH.js} +2 -2
- package/dist/chunk-TL7BOFFL.js +89 -0
- package/dist/chunk-TL7BOFFL.js.map +1 -0
- package/dist/{chunk-FD4Q5KFL.js → chunk-TLL22FFO.js} +2 -2
- package/dist/{chunk-QM5H4FPT.js → chunk-TV6BWONY.js} +3 -3
- package/dist/{chunk-EDFJBX3V.js → chunk-U6MPB3K6.js} +9 -9
- package/dist/{chunk-TZD3U2S5.js → chunk-ULJAOMJA.js} +4 -4
- package/dist/chunk-ULYQEFNH.js +529 -0
- package/dist/chunk-ULYQEFNH.js.map +1 -0
- package/dist/{chunk-H5EVWF6L.js → chunk-UNNJUJVD.js} +2 -2
- package/dist/{chunk-324X6T6G.js → chunk-UP7I3W6O.js} +57 -55
- package/dist/chunk-UP7I3W6O.js.map +1 -0
- package/dist/{chunk-VU2EWALC.js → chunk-UUGR3X5I.js} +19 -12
- package/dist/chunk-UUGR3X5I.js.map +1 -0
- package/dist/{chunk-Z6DKXQG7.js → chunk-UXXFMF4X.js} +2 -2
- package/dist/{chunk-OBQVTCTW.js → chunk-UYNCMZX5.js} +4 -4
- package/dist/{chunk-RGPYMHKI.js → chunk-V3K4RQO7.js} +9 -3
- package/dist/chunk-V3K4RQO7.js.map +1 -0
- package/dist/{chunk-KZHW27BV.js → chunk-V4QZ7UBK.js} +2 -2
- package/dist/{chunk-NEVRLD77.js → chunk-VH5EGTH2.js} +3 -3
- package/dist/{chunk-MYNUBDU7.js → chunk-VYKW6TB2.js} +1 -1
- package/dist/chunk-VYKW6TB2.js.map +1 -0
- package/dist/{chunk-QEJTQTF5.js → chunk-W6T5HR3Z.js} +3 -3
- package/dist/{chunk-H6WWEKEV.js → chunk-WCMG4HYI.js} +10 -10
- package/dist/{chunk-GZLLDA6P.js → chunk-WEFN327U.js} +2 -2
- package/dist/{chunk-VW3BBTMA.js → chunk-WKHUZIOW.js} +1 -1
- package/dist/{chunk-ANHUMDJX.js → chunk-WNDTLK44.js} +2 -2
- package/dist/{chunk-2DS4UOYQ.js → chunk-WSZQNTVN.js} +2 -2
- package/dist/{chunk-Z2DAWUO3.js → chunk-XMNUZUUA.js} +6 -6
- package/dist/{chunk-GAIM5RNE.js → chunk-XN7NSPE6.js} +3 -3
- package/dist/chunk-XV6ZYRHK.js +59 -0
- package/dist/chunk-XV6ZYRHK.js.map +1 -0
- package/dist/{chunk-FLGUVRR7.js → chunk-Y5BSA3I7.js} +5 -5
- package/dist/{chunk-WRLWLGEF.js → chunk-Y5E3XQ2S.js} +25 -2
- package/dist/{chunk-WRLWLGEF.js.map → chunk-Y5E3XQ2S.js.map} +1 -1
- package/dist/{chunk-QILLL4JE.js → chunk-YEROLKOA.js} +16 -16
- package/dist/{chunk-NDF3SH3X.js → chunk-YJPKDRI2.js} +15 -15
- package/dist/{chunk-TQGJN5UZ.js → chunk-YV56F4UP.js} +318 -700
- package/dist/chunk-YV56F4UP.js.map +1 -0
- package/dist/{chunk-VAIESMPY.js → chunk-YVBHGMKC.js} +4 -4
- package/dist/{chunk-AD22P5X3.js → chunk-YXA2EKV3.js} +3 -3
- package/dist/{chunk-FDNJVZRE.js → chunk-YYCOSTUU.js} +17 -17
- package/dist/{chunk-NLMTNEWW.js → chunk-Z6E6TUAE.js} +2 -2
- package/dist/{chunk-BJW7G6EF.js → chunk-Z7IGO5EA.js} +3 -3
- package/dist/{chunk-N7JKT4ZU.js → chunk-ZEIFJ6PX.js} +7 -7
- package/dist/{chunk-Q4OHNGGB.js → chunk-ZS2UQ3DV.js} +68 -11
- package/dist/chunk-ZS2UQ3DV.js.map +1 -0
- package/dist/{chunk-VRGOOVDB.js → chunk-ZVVT72MT.js} +2 -2
- package/dist/components/browser-viewer.d.ts +1 -1
- package/dist/composer.js +14 -14
- package/dist/{computer-viewer-KEDVLD42.js → computer-viewer-25AJIDYA.js} +9 -9
- package/dist/connect.js +11 -11
- package/dist/desktop.js +2 -2
- package/dist/editor.js +2 -2
- package/dist/{embedded-new-voice-5PYRDZ6T.js → embedded-new-voice-RZZEJT6M.js} +8 -8
- package/dist/{embedded-voice-PABC5NBD.js → embedded-voice-6OKSSPLW.js} +8 -8
- package/dist/{fleet-decision-row-QNSTP3VX.js → fleet-decision-row-NN2HXDX3.js} +2 -2
- package/dist/hooks/internal.d.ts +38 -0
- package/dist/hooks/use-client-config-flags.d.ts +12 -0
- package/dist/hooks/use-workspace-sessions.d.ts +10 -1
- package/dist/index.js +233 -227
- package/dist/interaction.js +11 -9
- package/dist/interaction.js.map +1 -1
- package/dist/{latest-question-5LIRVG4G.js → latest-question-2PFWQSSG.js} +4 -3
- package/dist/{latest-question-5LIRVG4G.js.map → latest-question-2PFWQSSG.js.map} +1 -1
- package/dist/machines.js +5 -5
- package/dist/messages/en.d.ts +3 -3
- package/dist/messages.js +1 -1
- package/dist/{model-policy-picker-menu-CURJ247L.js → model-policy-picker-menu-VVFGGAI6.js} +6 -6
- package/dist/model-policy-picker-menu-VVFGGAI6.js.map +1 -0
- package/dist/native-previews.js +3 -3
- package/dist/{platform-activity-row-BMXXNZKX.js → platform-activity-row-ENQVIFTL.js} +2 -2
- package/dist/{queue-surface-implementation-2X5AXB6I.js → queue-surface-implementation-4SHOQPQQ.js} +10 -8
- package/dist/{queue-surface-implementation-2X5AXB6I.js.map → queue-surface-implementation-4SHOQPQQ.js.map} +1 -1
- package/dist/realtime.js +7 -7
- package/dist/{sandbox-files-4FBG3GS2.js → sandbox-files-CCOTGXXA.js} +11 -11
- package/dist/sandbox-files-CCOTGXXA.js.map +1 -0
- package/dist/session-app.js +277 -271
- package/dist/session-list-model.d.ts +1 -0
- package/dist/session-list-model.js +8 -2
- package/dist/{session-realtime-2XIB254N.js → session-realtime-JNKDSGH7.js} +3 -3
- package/dist/session-realtime-JNKDSGH7.js.map +1 -0
- package/dist/session-realtime.js +2 -2
- package/dist/session-ui.js +77 -72
- package/dist/session.js +27 -25
- package/dist/sites.js +2 -2
- package/dist/terminal.js +2 -2
- package/dist/this-computer.js +3 -3
- package/dist/timeline/invoked-tool.d.ts +5 -0
- package/dist/timeline/tool-display-name.d.ts +2 -2
- package/dist/timeline/tool-icon.d.ts +14 -0
- package/dist/timeline/tool-presentation.d.ts +8 -3
- package/dist/timeline/types.d.ts +2 -0
- package/dist/{timeline-annotation-markers-X4K2IEOO.js → timeline-annotation-markers-KHNYNY2J.js} +5 -5
- package/dist/{timeline-annotation-selection-MEHBW676.js → timeline-annotation-selection-AXEDJHBP.js} +7 -7
- package/dist/{timeline-annotations-dialog-U2FPQ3UY.js → timeline-annotations-dialog-AV4ZBXRC.js} +9 -9
- package/dist/timeline-model.js +28 -26
- package/dist/ui/access-list.js +20 -20
- package/dist/ui/choice-cards.js +2 -2
- package/dist/ui/detail-page.js +2 -2
- package/dist/ui/detail-sheet.js +2 -2
- package/dist/ui/diff-view.js +2 -2
- package/dist/ui/disclosure.js +4 -4
- package/dist/ui/flush-form-page.js +3 -3
- package/dist/ui/form-dialog.js +2 -2
- package/dist/ui/list-row.js +5 -5
- package/dist/ui/revision-history.js +11 -11
- package/dist/ui/role-select.js +6 -6
- package/dist/ui/settings-nav.js +3 -3
- package/dist/usage.js +3 -3
- package/dist/workbench.js +11 -11
- package/package.json +4 -4
- package/src/app/app-state.tsx +3 -1
- package/src/app/components/capabilities/session-capability-card.tsx +14 -1
- package/src/app/components/capabilities/session-chrome-card.dom-fixture.tsx +377 -0
- package/src/app/components/capabilities/session-chrome-card.test.tsx +18 -0
- package/src/app/components/capabilities/session-chrome-card.tsx +243 -0
- package/src/app/components/capabilities/session-machine-card.dom-fixture.tsx +2 -0
- package/src/app/components/capabilities/session-machine-card.tsx +74 -16
- package/src/app/components/rail/session-list.tsx +254 -44
- package/src/app/components/rail/session-row-content.tsx +24 -2
- package/src/app/components/rail/session-shell.tsx +14 -9
- package/src/app/components/rail/site-session-group-heading.tsx +59 -20
- package/src/app/components/session/session-tenancy-control.tsx +18 -0
- package/src/app/components/session/site-origin-link.test.tsx +73 -0
- package/src/app/components/session/site-origin-link.tsx +4 -2
- package/src/app/embed/memory-navigation.tsx +1 -0
- package/src/app/lib/actions/held-modifier.test.ts +101 -0
- package/src/app/lib/actions/held-modifier.ts +108 -0
- package/src/app/lib/console-site.tsx +38 -0
- package/src/app/lib/navigation.tsx +4 -0
- package/src/app/lib/routes.tsx +42 -0
- package/src/app/lib/session-failure-toasts.ts +26 -0
- package/src/app/lib/session-ui-features.tsx +18 -4
- package/src/app/lib/sessions-group.tsx +219 -30
- package/src/app/lib/site-opened.tsx +48 -0
- package/src/app/lib/site-session-groups.test.ts +173 -6
- package/src/app/lib/site-view-routes.test.ts +55 -0
- package/src/app/lib/use-session-list-hint-refresh.tsx +44 -4
- package/src/app/routes/artifacts.tsx +2 -29
- package/src/app/routes/session-transient-failures.test.tsx +343 -0
- package/src/app/routes/session-unavailable.tsx +74 -3
- package/src/app/routes/session.tsx +4 -13
- package/src/app/routes/sessions-index.tsx +13 -9
- package/src/app/routes/site-view.test.tsx +476 -0
- package/src/app/routes/site-view.tsx +583 -0
- package/src/components/browser-viewer.tsx +16 -2
- package/src/hooks/internal.ts +129 -6
- package/src/hooks/use-client-config-flags.ts +8 -0
- package/src/hooks/use-session-events.ts +83 -9
- package/src/hooks/use-workspace-sessions.ts +21 -1
- package/src/messages/en.ts +3 -3
- package/src/session-list-model.ts +4 -0
- package/src/timeline/activity-rail.tsx +3 -2
- package/src/timeline/invoked-tool.ts +14 -4
- package/src/timeline/projection.ts +15 -8
- package/src/timeline/rolling-activity.tsx +6 -2
- package/src/timeline/tool-display-name.ts +2 -2
- package/src/timeline/tool-icon.tsx +165 -0
- package/src/timeline/tool-presentation.ts +207 -48
- package/src/timeline/tool-renderers.tsx +1 -70
- package/src/timeline/types.ts +2 -0
- package/styles/compiled.css +38 -0
- package/dist/chunk-22ZBT6CN.js +0 -50
- package/dist/chunk-22ZBT6CN.js.map +0 -1
- package/dist/chunk-324X6T6G.js.map +0 -1
- package/dist/chunk-5JZYPZ72.js.map +0 -1
- package/dist/chunk-6W3LF3DB.js.map +0 -1
- package/dist/chunk-BJIZ7PL7.js.map +0 -1
- package/dist/chunk-CKZW7A5S.js.map +0 -1
- package/dist/chunk-DDIBZA4X.js.map +0 -1
- package/dist/chunk-EHCUFCXM.js.map +0 -1
- package/dist/chunk-GZ64CASI.js.map +0 -1
- package/dist/chunk-I6VUUEXH.js.map +0 -1
- package/dist/chunk-KF3MF6FP.js.map +0 -1
- package/dist/chunk-MYNUBDU7.js.map +0 -1
- package/dist/chunk-NAWXARTY.js.map +0 -1
- package/dist/chunk-O77Q4NG2.js.map +0 -1
- package/dist/chunk-PM3OSANE.js.map +0 -1
- package/dist/chunk-Q262Y2YX.js.map +0 -1
- package/dist/chunk-Q4NM77K7.js.map +0 -1
- package/dist/chunk-Q4OHNGGB.js.map +0 -1
- package/dist/chunk-QIYBOFUV.js.map +0 -1
- package/dist/chunk-R25ZKOZR.js +0 -24
- package/dist/chunk-R25ZKOZR.js.map +0 -1
- package/dist/chunk-RGPYMHKI.js.map +0 -1
- package/dist/chunk-ROQOVH4N.js.map +0 -1
- package/dist/chunk-TQGJN5UZ.js.map +0 -1
- package/dist/chunk-V77JK73U.js.map +0 -1
- package/dist/chunk-VSQHDBHU.js.map +0 -1
- package/dist/chunk-VU2EWALC.js.map +0 -1
- package/dist/chunk-XFNLU7EW.js.map +0 -1
- package/dist/chunk-Z5WMLJKI.js.map +0 -1
- /package/dist/{browser-viewer-RYYQSRTC.js.map → app/components/capabilities/session-chrome-card.js.map} +0 -0
- /package/dist/{chat-interactive-block-ABCRKXJ4.js.map → app/lib/console-site.js.map} +0 -0
- /package/dist/{computer-viewer-KEDVLD42.js.map → app/lib/site-opened.js.map} +0 -0
- /package/dist/{embedded-new-voice-5PYRDZ6T.js.map → browser-viewer-QMCNV4RI.js.map} +0 -0
- /package/dist/{embedded-voice-PABC5NBD.js.map → chat-interactive-block-PMIAUXSO.js.map} +0 -0
- /package/dist/{chunk-GIZGNFIX.js.map → chunk-22FFOHPT.js.map} +0 -0
- /package/dist/{chunk-UHFWF6ZU.js.map → chunk-2FPS5H2D.js.map} +0 -0
- /package/dist/{chunk-5POTDNQT.js.map → chunk-2NC7NZCE.js.map} +0 -0
- /package/dist/{chunk-ZKYYZH6L.js.map → chunk-2QBYDGWO.js.map} +0 -0
- /package/dist/{chunk-TWXIFWBD.js.map → chunk-34EU25RL.js.map} +0 -0
- /package/dist/{chunk-LQKKSUCR.js.map → chunk-35BC2FU2.js.map} +0 -0
- /package/dist/{chunk-PTGRFAMH.js.map → chunk-3ABPIUCK.js.map} +0 -0
- /package/dist/{chunk-S4SC5SSV.js.map → chunk-3GU7AWG7.js.map} +0 -0
- /package/dist/{chunk-722UO6YQ.js.map → chunk-3PEXVG4D.js.map} +0 -0
- /package/dist/{chunk-OQAAI33Y.js.map → chunk-3RMKPHBL.js.map} +0 -0
- /package/dist/{chunk-GCGTYXJJ.js.map → chunk-3STBLX4O.js.map} +0 -0
- /package/dist/{chunk-YXIW7H4N.js.map → chunk-3X5FKDYQ.js.map} +0 -0
- /package/dist/{chunk-KTRKZRID.js.map → chunk-4GLLWX33.js.map} +0 -0
- /package/dist/{chunk-SD2K5ZN5.js.map → chunk-4LPA25NQ.js.map} +0 -0
- /package/dist/{chunk-DKCX643S.js.map → chunk-4RMN4E2Y.js.map} +0 -0
- /package/dist/{chunk-E5FCEDMU.js.map → chunk-4SAGYEVB.js.map} +0 -0
- /package/dist/{chunk-HTT3FB7T.js.map → chunk-4VK2R5QC.js.map} +0 -0
- /package/dist/{chunk-CKG2EG62.js.map → chunk-4XQC7VLT.js.map} +0 -0
- /package/dist/{chunk-IVOA3DXA.js.map → chunk-4YXAQMTD.js.map} +0 -0
- /package/dist/{chunk-HOJGAJAB.js.map → chunk-52WK2GGK.js.map} +0 -0
- /package/dist/{chunk-NYZQ7LO7.js.map → chunk-552UYIQ7.js.map} +0 -0
- /package/dist/{chunk-LEXPBQ56.js.map → chunk-5DSKMG2I.js.map} +0 -0
- /package/dist/{chunk-WNG757ID.js.map → chunk-5FA455GR.js.map} +0 -0
- /package/dist/{chunk-MNWQAYY3.js.map → chunk-5FEN3KYH.js.map} +0 -0
- /package/dist/{chunk-OSVHU2WU.js.map → chunk-5JHRMUAZ.js.map} +0 -0
- /package/dist/{chunk-RKB2Z457.js.map → chunk-5VGJXWQ2.js.map} +0 -0
- /package/dist/{chunk-GFUUFM2O.js.map → chunk-5W6ZDKRR.js.map} +0 -0
- /package/dist/{chunk-NDETTZQA.js.map → chunk-5W7KJ5NQ.js.map} +0 -0
- /package/dist/{chunk-Q35YZVDZ.js.map → chunk-5Y2FPLZE.js.map} +0 -0
- /package/dist/{chunk-F3NERYBQ.js.map → chunk-62VER7O4.js.map} +0 -0
- /package/dist/{chunk-FBMU3VK5.js.map → chunk-6DCEDIF6.js.map} +0 -0
- /package/dist/{chunk-WUHB422G.js.map → chunk-73WI7FL2.js.map} +0 -0
- /package/dist/{chunk-QECZVL7S.js.map → chunk-7FJMRJDG.js.map} +0 -0
- /package/dist/{chunk-7KGKDWWR.js.map → chunk-7HFLYNWN.js.map} +0 -0
- /package/dist/{chunk-XVM566II.js.map → chunk-7KIENXRE.js.map} +0 -0
- /package/dist/{chunk-CBY5CXBD.js.map → chunk-7NPCEBZE.js.map} +0 -0
- /package/dist/{chunk-46VBQG2D.js.map → chunk-7P4AQMGA.js.map} +0 -0
- /package/dist/{chunk-S7PVL7XH.js.map → chunk-A4BD4ZVB.js.map} +0 -0
- /package/dist/{chunk-73SOCVLS.js.map → chunk-AIEXYO2X.js.map} +0 -0
- /package/dist/{chunk-U7TC2XJQ.js.map → chunk-AJPW3SV4.js.map} +0 -0
- /package/dist/{chunk-HRJQAFKR.js.map → chunk-AX6YJA5U.js.map} +0 -0
- /package/dist/{chunk-P5WABK2H.js.map → chunk-BCM7C3MJ.js.map} +0 -0
- /package/dist/{chunk-DT7BORXG.js.map → chunk-BMJTNPWK.js.map} +0 -0
- /package/dist/{chunk-HIHO2QE7.js.map → chunk-BT2MVGHT.js.map} +0 -0
- /package/dist/{chunk-3XOISKZC.js.map → chunk-BXQYAAVE.js.map} +0 -0
- /package/dist/{chunk-IBTXYLBW.js.map → chunk-CCFWY4GF.js.map} +0 -0
- /package/dist/{chunk-ZOC3OP6F.js.map → chunk-CCR33J7L.js.map} +0 -0
- /package/dist/{chunk-GTQ3SNEI.js.map → chunk-CD3MO3IC.js.map} +0 -0
- /package/dist/{chunk-WSMYOLHG.js.map → chunk-CDEXRJB6.js.map} +0 -0
- /package/dist/{chunk-3GLAPCVI.js.map → chunk-CFFNT2OY.js.map} +0 -0
- /package/dist/{chunk-FUSFVUIJ.js.map → chunk-CMLJSF2F.js.map} +0 -0
- /package/dist/{chunk-O4DYOSOL.js.map → chunk-CP7ZQHBW.js.map} +0 -0
- /package/dist/{chunk-IOKSNX74.js.map → chunk-D5OWJZQR.js.map} +0 -0
- /package/dist/{chunk-SQGXMHJO.js.map → chunk-DGLRZMXL.js.map} +0 -0
- /package/dist/{chunk-GNEHAPKV.js.map → chunk-DJFTH2DI.js.map} +0 -0
- /package/dist/{chunk-HQG4SLTE.js.map → chunk-DYJGYGPB.js.map} +0 -0
- /package/dist/{chunk-4EAF3HSD.js.map → chunk-EJ7WARW7.js.map} +0 -0
- /package/dist/{chunk-3AA6RNGE.js.map → chunk-ENS6E4RZ.js.map} +0 -0
- /package/dist/{chunk-OOEO4MKY.js.map → chunk-EPWD4KRA.js.map} +0 -0
- /package/dist/{chunk-V5RJAWRP.js.map → chunk-EQE3MNQN.js.map} +0 -0
- /package/dist/{chunk-TSBE4KOQ.js.map → chunk-EWL6NDOO.js.map} +0 -0
- /package/dist/{chunk-OO2T63BY.js.map → chunk-EYS4ZOF5.js.map} +0 -0
- /package/dist/{chunk-IC7KNOBB.js.map → chunk-FDAV72IX.js.map} +0 -0
- /package/dist/{chunk-AG7VGUIW.js.map → chunk-FFNPUSVO.js.map} +0 -0
- /package/dist/{chunk-P5T36BA3.js.map → chunk-FRP64DEK.js.map} +0 -0
- /package/dist/{chunk-KBF3SE7G.js.map → chunk-FSP334UU.js.map} +0 -0
- /package/dist/{chunk-ZHFKMMOT.js.map → chunk-FTX5CNHA.js.map} +0 -0
- /package/dist/{chunk-KYBALSWW.js.map → chunk-FWOBNL2A.js.map} +0 -0
- /package/dist/{chunk-HJ5XWW62.js.map → chunk-FWYEZ3LE.js.map} +0 -0
- /package/dist/{chunk-WSLPZ43N.js.map → chunk-G4HQUBO4.js.map} +0 -0
- /package/dist/{chunk-CSHBR2IZ.js.map → chunk-GDLDBR6B.js.map} +0 -0
- /package/dist/{chunk-G3S2F35T.js.map → chunk-GHHM6WN4.js.map} +0 -0
- /package/dist/{chunk-OANSIX34.js.map → chunk-GRSODLVO.js.map} +0 -0
- /package/dist/{chunk-EU6XSQFM.js.map → chunk-GXW2I2M2.js.map} +0 -0
- /package/dist/{chunk-4246UYVG.js.map → chunk-GZS37O3G.js.map} +0 -0
- /package/dist/{chunk-Y7WMW74G.js.map → chunk-HQWVDQXW.js.map} +0 -0
- /package/dist/{chunk-YTZQV2DD.js.map → chunk-HU6JTNWF.js.map} +0 -0
- /package/dist/{chunk-QRVNI5V6.js.map → chunk-I6KIQKU6.js.map} +0 -0
- /package/dist/{chunk-BNUPYHHZ.js.map → chunk-IDXTASGN.js.map} +0 -0
- /package/dist/{chunk-L6RXRRN3.js.map → chunk-ILDOW2IQ.js.map} +0 -0
- /package/dist/{chunk-VUHPA3XQ.js.map → chunk-ITX2TB4K.js.map} +0 -0
- /package/dist/{chunk-ETCB6SUJ.js.map → chunk-J22HD2PB.js.map} +0 -0
- /package/dist/{chunk-U47YDYLQ.js.map → chunk-J5MEDX7C.js.map} +0 -0
- /package/dist/{chunk-6VQTHC4W.js.map → chunk-J7FBBLHF.js.map} +0 -0
- /package/dist/{chunk-QZRDCFHI.js.map → chunk-JM4HQPAI.js.map} +0 -0
- /package/dist/{chunk-PIVGX42P.js.map → chunk-JNY5MT3I.js.map} +0 -0
- /package/dist/{chunk-XWWXIZFP.js.map → chunk-JO6R5EXF.js.map} +0 -0
- /package/dist/{chunk-MM7OKOTE.js.map → chunk-JQCGPTZ6.js.map} +0 -0
- /package/dist/{chunk-KNFDWNCH.js.map → chunk-JXT5QDJC.js.map} +0 -0
- /package/dist/{chunk-OR37STQZ.js.map → chunk-KEXYBG7Q.js.map} +0 -0
- /package/dist/{chunk-AZVANYMB.js.map → chunk-KUNFUSZ7.js.map} +0 -0
- /package/dist/{chunk-DXZNDKQD.js.map → chunk-LEEJBZ5B.js.map} +0 -0
- /package/dist/{chunk-C535KSTY.js.map → chunk-LF5CBAOS.js.map} +0 -0
- /package/dist/{chunk-RIMKJBCD.js.map → chunk-LMPTC4CX.js.map} +0 -0
- /package/dist/{chunk-3KVWXKD6.js.map → chunk-LQ47YL6E.js.map} +0 -0
- /package/dist/{chunk-H5WGWAYX.js.map → chunk-LT4J7RHI.js.map} +0 -0
- /package/dist/{chunk-DSGMYES6.js.map → chunk-MCTTONOW.js.map} +0 -0
- /package/dist/{chunk-IGHELZI7.js.map → chunk-MIECLOQC.js.map} +0 -0
- /package/dist/{chunk-FM4OUCC2.js.map → chunk-MOKYT3X3.js.map} +0 -0
- /package/dist/{chunk-RKILMLA7.js.map → chunk-MXLKI7BI.js.map} +0 -0
- /package/dist/{chunk-45WYYFP6.js.map → chunk-N3ZP4IDU.js.map} +0 -0
- /package/dist/{chunk-XRRSFQEV.js.map → chunk-NAZZLAWX.js.map} +0 -0
- /package/dist/{chunk-UWJ5P5CU.js.map → chunk-NEK4WB5P.js.map} +0 -0
- /package/dist/{chunk-6L7U46Y2.js.map → chunk-NKNVIO66.js.map} +0 -0
- /package/dist/{chunk-JKUICTLM.js.map → chunk-NLAFNMPK.js.map} +0 -0
- /package/dist/{chunk-4LKNIGHB.js.map → chunk-O2SBHS2N.js.map} +0 -0
- /package/dist/{chunk-D3RK3NGM.js.map → chunk-PCFK7HKD.js.map} +0 -0
- /package/dist/{chunk-VVCDB2T7.js.map → chunk-PCJLH45G.js.map} +0 -0
- /package/dist/{chunk-PZ24CYDO.js.map → chunk-PFAUGEV5.js.map} +0 -0
- /package/dist/{chunk-HGMWMK5K.js.map → chunk-PO3BH3KQ.js.map} +0 -0
- /package/dist/{chunk-B74GSYR6.js.map → chunk-PUTS4DYW.js.map} +0 -0
- /package/dist/{chunk-JSIDLTTG.js.map → chunk-PZ2V2XIK.js.map} +0 -0
- /package/dist/{chunk-TMEQPODK.js.map → chunk-PZ37VDB5.js.map} +0 -0
- /package/dist/{chunk-LVONK3YQ.js.map → chunk-QRKTESVE.js.map} +0 -0
- /package/dist/{chunk-HT5WSUC7.js.map → chunk-QXEDIDBZ.js.map} +0 -0
- /package/dist/{chunk-WURSS6MP.js.map → chunk-R66YMYJU.js.map} +0 -0
- /package/dist/{chunk-HDHK3SXK.js.map → chunk-RFLYID6H.js.map} +0 -0
- /package/dist/{chunk-VMFID36H.js.map → chunk-RQNZDTKT.js.map} +0 -0
- /package/dist/{chunk-A2EWJQXX.js.map → chunk-SM5QX6UK.js.map} +0 -0
- /package/dist/{chunk-FBE6AIIW.js.map → chunk-SOKNCW5U.js.map} +0 -0
- /package/dist/{chunk-PFKTGZKE.js.map → chunk-SY2AAZNB.js.map} +0 -0
- /package/dist/{chunk-DFZMKCVP.js.map → chunk-TIQPKOFW.js.map} +0 -0
- /package/dist/{chunk-HPPKLBTJ.js.map → chunk-TJQDL3JH.js.map} +0 -0
- /package/dist/{chunk-FD4Q5KFL.js.map → chunk-TLL22FFO.js.map} +0 -0
- /package/dist/{chunk-QM5H4FPT.js.map → chunk-TV6BWONY.js.map} +0 -0
- /package/dist/{chunk-EDFJBX3V.js.map → chunk-U6MPB3K6.js.map} +0 -0
- /package/dist/{chunk-TZD3U2S5.js.map → chunk-ULJAOMJA.js.map} +0 -0
- /package/dist/{chunk-H5EVWF6L.js.map → chunk-UNNJUJVD.js.map} +0 -0
- /package/dist/{chunk-Z6DKXQG7.js.map → chunk-UXXFMF4X.js.map} +0 -0
- /package/dist/{chunk-OBQVTCTW.js.map → chunk-UYNCMZX5.js.map} +0 -0
- /package/dist/{chunk-KZHW27BV.js.map → chunk-V4QZ7UBK.js.map} +0 -0
- /package/dist/{chunk-NEVRLD77.js.map → chunk-VH5EGTH2.js.map} +0 -0
- /package/dist/{chunk-QEJTQTF5.js.map → chunk-W6T5HR3Z.js.map} +0 -0
- /package/dist/{chunk-H6WWEKEV.js.map → chunk-WCMG4HYI.js.map} +0 -0
- /package/dist/{chunk-GZLLDA6P.js.map → chunk-WEFN327U.js.map} +0 -0
- /package/dist/{chunk-VW3BBTMA.js.map → chunk-WKHUZIOW.js.map} +0 -0
- /package/dist/{chunk-ANHUMDJX.js.map → chunk-WNDTLK44.js.map} +0 -0
- /package/dist/{chunk-2DS4UOYQ.js.map → chunk-WSZQNTVN.js.map} +0 -0
- /package/dist/{chunk-Z2DAWUO3.js.map → chunk-XMNUZUUA.js.map} +0 -0
- /package/dist/{chunk-GAIM5RNE.js.map → chunk-XN7NSPE6.js.map} +0 -0
- /package/dist/{chunk-FLGUVRR7.js.map → chunk-Y5BSA3I7.js.map} +0 -0
- /package/dist/{chunk-QILLL4JE.js.map → chunk-YEROLKOA.js.map} +0 -0
- /package/dist/{chunk-NDF3SH3X.js.map → chunk-YJPKDRI2.js.map} +0 -0
- /package/dist/{chunk-VAIESMPY.js.map → chunk-YVBHGMKC.js.map} +0 -0
- /package/dist/{chunk-AD22P5X3.js.map → chunk-YXA2EKV3.js.map} +0 -0
- /package/dist/{chunk-FDNJVZRE.js.map → chunk-YYCOSTUU.js.map} +0 -0
- /package/dist/{chunk-NLMTNEWW.js.map → chunk-Z6E6TUAE.js.map} +0 -0
- /package/dist/{chunk-BJW7G6EF.js.map → chunk-Z7IGO5EA.js.map} +0 -0
- /package/dist/{chunk-N7JKT4ZU.js.map → chunk-ZEIFJ6PX.js.map} +0 -0
- /package/dist/{chunk-VRGOOVDB.js.map → chunk-ZVVT72MT.js.map} +0 -0
- /package/dist/{model-policy-picker-menu-CURJ247L.js.map → computer-viewer-25AJIDYA.js.map} +0 -0
- /package/dist/{sandbox-files-4FBG3GS2.js.map → embedded-new-voice-RZZEJT6M.js.map} +0 -0
- /package/dist/{session-realtime-2XIB254N.js.map → embedded-voice-6OKSSPLW.js.map} +0 -0
- /package/dist/{fleet-decision-row-QNSTP3VX.js.map → fleet-decision-row-NN2HXDX3.js.map} +0 -0
- /package/dist/{platform-activity-row-BMXXNZKX.js.map → platform-activity-row-ENQVIFTL.js.map} +0 -0
- /package/dist/{timeline-annotation-markers-X4K2IEOO.js.map → timeline-annotation-markers-KHNYNY2J.js.map} +0 -0
- /package/dist/{timeline-annotation-selection-MEHBW676.js.map → timeline-annotation-selection-AXEDJHBP.js.map} +0 -0
- /package/dist/{timeline-annotations-dialog-U2FPQ3UY.js.map → timeline-annotations-dialog-AV4ZBXRC.js.map} +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { t } from "../lib/console-text";
|
|
2
2
|
import { ArtifactSessionPage } from "../components/session/artifact-session-page";
|
|
3
3
|
import type {
|
|
4
|
-
SiteViewer,
|
|
5
4
|
ToolGatewayIdentity,
|
|
6
5
|
WorkspaceArtifactContentResponse,
|
|
7
6
|
WorkspaceArtifactDetailResponse,
|
|
@@ -12,7 +11,6 @@ import {
|
|
|
12
11
|
artifactLoadErrorMessage,
|
|
13
12
|
artifactLoadErrorView,
|
|
14
13
|
type PublishedHtmlArtifactToolBridge,
|
|
15
|
-
type SiteToolBridgeFactory,
|
|
16
14
|
} from "../../artifacts";
|
|
17
15
|
import { loadSiteSnapshot } from "../../sites";
|
|
18
16
|
import { SiteConversations } from "../components/artifacts/site-conversations";
|
|
@@ -62,6 +60,7 @@ import { useAppContext } from "../app-context";
|
|
|
62
60
|
import { ARTIFACT_ACCESS_REQUIRED, isArtifactReadDenied } from "../lib/artifact-access";
|
|
63
61
|
import { useAppApi } from "../lib/app-api";
|
|
64
62
|
import { createSiteToolBridge } from "../lib/site-tool-bridge";
|
|
63
|
+
import { useConsoleSiteToolBridge, useConsoleSiteViewer } from "../lib/console-site";
|
|
65
64
|
import { readyNewChat } from "../lib/ready-new-chat";
|
|
66
65
|
import { userErrorText } from "../../ui/api-error";
|
|
67
66
|
import { newArtifactPrompt, siteEditPrompt } from "../lib/site-edit-prompt";
|
|
@@ -78,18 +77,6 @@ import type { ArtifactReturnSearch, SiteDetailTab } from "../lib/routes";
|
|
|
78
77
|
|
|
79
78
|
const NO_SITE_TOOLS: readonly ToolGatewayIdentity[] = [];
|
|
80
79
|
|
|
81
|
-
/** The signed-in member as Site code sees them (`site.viewer`) in the console. */
|
|
82
|
-
function useConsoleSiteViewer(): SiteViewer {
|
|
83
|
-
const { accessContext, authSession } = useAppContext();
|
|
84
|
-
const subjectId = accessContext.subjectId;
|
|
85
|
-
const name = authSession?.user?.name ?? null;
|
|
86
|
-
const email = authSession?.user?.email ?? null;
|
|
87
|
-
return useMemo(
|
|
88
|
-
() => ({ kind: "member", id: `user:${subjectId}`, name, email, signedIn: true }),
|
|
89
|
-
[email, name, subjectId],
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
80
|
function formatSize(bytes: number): string {
|
|
94
81
|
if (bytes < 1024) return `${bytes} B`;
|
|
95
82
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
@@ -420,22 +407,8 @@ function EmbeddedSiteDetail({
|
|
|
420
407
|
controls?: EmbeddedSiteControls | undefined;
|
|
421
408
|
}) {
|
|
422
409
|
const { client } = useAppContext();
|
|
423
|
-
const api = useAppApi();
|
|
424
410
|
const viewer = useConsoleSiteViewer();
|
|
425
|
-
const toolBridge =
|
|
426
|
-
(site) => {
|
|
427
|
-
const scope = { workspaceTools: client.tools.forWorkspace(workspaceId), workspaceId };
|
|
428
|
-
return site
|
|
429
|
-
? createSiteToolBridge(api, {
|
|
430
|
-
...scope,
|
|
431
|
-
artifactId: site.artifactId,
|
|
432
|
-
siteVersionId: site.siteVersionId,
|
|
433
|
-
requestedTools: site.requestedTools,
|
|
434
|
-
})
|
|
435
|
-
: createSiteToolBridge(api, scope);
|
|
436
|
-
},
|
|
437
|
-
[api, client, workspaceId],
|
|
438
|
-
);
|
|
411
|
+
const toolBridge = useConsoleSiteToolBridge(workspaceId);
|
|
439
412
|
return (
|
|
440
413
|
<SiteView
|
|
441
414
|
client={client}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/* ----------------------------------------------------------------------------
|
|
2
|
+
The session page during an API rolling deploy or a network blip: no
|
|
3
|
+
"Failed to load session" / "Event stream disconnected" toast and no failure
|
|
4
|
+
panel while transient failures are retried quietly; one toast and a
|
|
5
|
+
"Try again" panel only when the failure persists; recovery on its own.
|
|
6
|
+
Definitive errors stay exactly as visible as before.
|
|
7
|
+
-------------------------------------------------------------------------- */
|
|
8
|
+
import { describe, expect, mock, test } from "bun:test";
|
|
9
|
+
import { OpenGeniApiError, type AccessContext, type Session } from "@opengeni/sdk";
|
|
10
|
+
import { act, type ReactNode } from "react";
|
|
11
|
+
import * as SonnerPackage from "sonner";
|
|
12
|
+
|
|
13
|
+
import { flush, registerDom, renderComponent } from "../../../test/render-hook";
|
|
14
|
+
import { fakeClient, SESSION_ID, WORKSPACE_ID } from "../../../test/fake-client";
|
|
15
|
+
import { DEFAULT_TRANSIENT_READ_RETRY } from "../../hooks/internal";
|
|
16
|
+
import { useSession } from "../../hooks/use-session";
|
|
17
|
+
import { useSessionEvents } from "../../hooks/use-session-events";
|
|
18
|
+
import { AppContext, type AppContextValue } from "../app-context";
|
|
19
|
+
import { AppHostProvider, type AppHost } from "../lib/app-host";
|
|
20
|
+
import type { PageHost } from "../lib/navigation";
|
|
21
|
+
|
|
22
|
+
const toastError = mock((_message: string, _data?: unknown) => undefined);
|
|
23
|
+
mock.module("sonner", () => ({
|
|
24
|
+
...SonnerPackage,
|
|
25
|
+
toast: Object.assign(
|
|
26
|
+
mock((_message: string) => undefined),
|
|
27
|
+
{ ...SonnerPackage.toast, error: toastError },
|
|
28
|
+
),
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
const { useSessionFailureToasts } = await import("../lib/session-failure-toasts");
|
|
32
|
+
const { SessionUnavailableRoute } = await import("./session-unavailable");
|
|
33
|
+
const { default: SessionRouteAuxiliary } =
|
|
34
|
+
await import("../components/session/session-tenancy-control");
|
|
35
|
+
|
|
36
|
+
registerDom({ clock: "virtual" });
|
|
37
|
+
|
|
38
|
+
const session = {
|
|
39
|
+
id: SESSION_ID,
|
|
40
|
+
workspaceId: WORKSPACE_ID,
|
|
41
|
+
lastSequence: 0,
|
|
42
|
+
title: "Deploy-safe",
|
|
43
|
+
titleSource: "user",
|
|
44
|
+
} as Session;
|
|
45
|
+
|
|
46
|
+
const unavailable = () => new OpenGeniApiError(503, "", { mutation: false });
|
|
47
|
+
|
|
48
|
+
function toastTitles(): string[] {
|
|
49
|
+
return toastError.mock.calls.map(([message]) => message);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The session page's read hooks plus its failure toasts. */
|
|
53
|
+
function SessionPageReads(props: { client: ReturnType<typeof fakeClient> }) {
|
|
54
|
+
const events = useSessionEvents(SESSION_ID, { client: props.client, workspaceId: WORKSPACE_ID });
|
|
55
|
+
const detail = useSession(SESSION_ID, {
|
|
56
|
+
client: props.client,
|
|
57
|
+
workspaceId: WORKSPACE_ID,
|
|
58
|
+
events: events.events,
|
|
59
|
+
});
|
|
60
|
+
useSessionFailureToasts(detail.error, events.error);
|
|
61
|
+
return <p>{detail.session?.title ?? (detail.error ? "failed" : "loading")}</p>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function RouteProviders(props: { host: AppHost; value: AppContextValue; children: ReactNode }) {
|
|
65
|
+
return (
|
|
66
|
+
<AppHostProvider host={props.host}>
|
|
67
|
+
<AppContext.Provider value={props.value}>{props.children}</AppContext.Provider>
|
|
68
|
+
</AppHostProvider>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function liveStream(): ReturnType<typeof fakeClient>["streamEvents"] {
|
|
73
|
+
return (_workspaceId, _sessionId, options = {}) =>
|
|
74
|
+
(async function* () {
|
|
75
|
+
options.onOpen?.();
|
|
76
|
+
await new Promise<void>((resolve) =>
|
|
77
|
+
options.signal?.addEventListener("abort", () => resolve(), { once: true }),
|
|
78
|
+
);
|
|
79
|
+
yield* [];
|
|
80
|
+
})();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
describe("session page failure toasts", () => {
|
|
84
|
+
test("a transient outage that recovers raises no toast", async () => {
|
|
85
|
+
toastError.mockClear();
|
|
86
|
+
let failing = true;
|
|
87
|
+
const client = fakeClient({
|
|
88
|
+
getSession: async () => {
|
|
89
|
+
if (failing) throw new TypeError("Failed to fetch");
|
|
90
|
+
return session;
|
|
91
|
+
},
|
|
92
|
+
listEvents: async () => {
|
|
93
|
+
if (failing) throw unavailable();
|
|
94
|
+
return [];
|
|
95
|
+
},
|
|
96
|
+
streamEvents: liveStream(),
|
|
97
|
+
});
|
|
98
|
+
const rendered = await renderComponent(<SessionPageReads client={client} />);
|
|
99
|
+
try {
|
|
100
|
+
await flush(8_000);
|
|
101
|
+
expect(rendered.container.textContent).toBe("loading");
|
|
102
|
+
failing = false;
|
|
103
|
+
await flush(8_000);
|
|
104
|
+
expect(rendered.container.textContent).toBe("Deploy-safe");
|
|
105
|
+
expect(toastTitles()).toEqual([]);
|
|
106
|
+
} finally {
|
|
107
|
+
await rendered.unmount();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test("a persistent transient outage toasts each failure once, despite background retries", async () => {
|
|
112
|
+
toastError.mockClear();
|
|
113
|
+
const client = fakeClient({
|
|
114
|
+
getSession: async () => {
|
|
115
|
+
throw unavailable();
|
|
116
|
+
},
|
|
117
|
+
listEvents: async () => {
|
|
118
|
+
throw new TypeError("Failed to fetch");
|
|
119
|
+
},
|
|
120
|
+
streamEvents: liveStream(),
|
|
121
|
+
});
|
|
122
|
+
const rendered = await renderComponent(<SessionPageReads client={client} />);
|
|
123
|
+
try {
|
|
124
|
+
await flush(DEFAULT_TRANSIENT_READ_RETRY.quietWindowMs - 3_000);
|
|
125
|
+
expect(toastTitles()).toEqual([]);
|
|
126
|
+
await flush(DEFAULT_TRANSIENT_READ_RETRY.backgroundDelayMs * 4);
|
|
127
|
+
expect(toastTitles().sort()).toEqual(["Event stream disconnected", "Failed to load session"]);
|
|
128
|
+
} finally {
|
|
129
|
+
await rendered.unmount();
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test("a definitive error toasts at once, and a 404 does not toast", async () => {
|
|
134
|
+
toastError.mockClear();
|
|
135
|
+
const forbidden = fakeClient({
|
|
136
|
+
getSession: async () => {
|
|
137
|
+
throw new OpenGeniApiError(403, "", { mutation: false });
|
|
138
|
+
},
|
|
139
|
+
listEvents: async () => [],
|
|
140
|
+
streamEvents: liveStream(),
|
|
141
|
+
});
|
|
142
|
+
const first = await renderComponent(<SessionPageReads client={forbidden} />);
|
|
143
|
+
await flush(10);
|
|
144
|
+
expect(toastTitles()).toEqual(["Failed to load session"]);
|
|
145
|
+
await first.unmount();
|
|
146
|
+
|
|
147
|
+
toastError.mockClear();
|
|
148
|
+
const missing = fakeClient({
|
|
149
|
+
getSession: async () => {
|
|
150
|
+
throw new OpenGeniApiError(404, "", { mutation: false });
|
|
151
|
+
},
|
|
152
|
+
listEvents: async () => [],
|
|
153
|
+
streamEvents: liveStream(),
|
|
154
|
+
});
|
|
155
|
+
const second = await renderComponent(<SessionPageReads client={missing} />);
|
|
156
|
+
await flush(10);
|
|
157
|
+
expect(toastTitles()).toEqual([]);
|
|
158
|
+
await second.unmount();
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
describe("session load failure panel", () => {
|
|
163
|
+
test("a persistent transient failure offers Try again instead of a dead end", async () => {
|
|
164
|
+
const onRetry = mock(() => undefined);
|
|
165
|
+
const rendered = await renderComponent(
|
|
166
|
+
<SessionRouteAuxiliary
|
|
167
|
+
workspaceId={WORKSPACE_ID}
|
|
168
|
+
sessionId={SESSION_ID}
|
|
169
|
+
loadError={unavailable()}
|
|
170
|
+
onRetry={onRetry}
|
|
171
|
+
/>,
|
|
172
|
+
);
|
|
173
|
+
try {
|
|
174
|
+
expect(rendered.container.textContent).toContain("Temporarily unavailable");
|
|
175
|
+
expect(rendered.container.textContent).toContain("Retrying automatically.");
|
|
176
|
+
expect(rendered.container.textContent).not.toContain("Unable to open session");
|
|
177
|
+
const button = [...rendered.container.querySelectorAll("button")].find(
|
|
178
|
+
(candidate) => candidate.textContent === "Try again",
|
|
179
|
+
);
|
|
180
|
+
await act(async () => button?.click());
|
|
181
|
+
expect(onRetry).toHaveBeenCalledTimes(1);
|
|
182
|
+
} finally {
|
|
183
|
+
await rendered.unmount();
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test("a definitive failure keeps the existing panel", async () => {
|
|
188
|
+
const rendered = await renderComponent(
|
|
189
|
+
<SessionRouteAuxiliary
|
|
190
|
+
workspaceId={WORKSPACE_ID}
|
|
191
|
+
sessionId={SESSION_ID}
|
|
192
|
+
loadError={new OpenGeniApiError(403, "", { mutation: false })}
|
|
193
|
+
onRetry={() => undefined}
|
|
194
|
+
/>,
|
|
195
|
+
);
|
|
196
|
+
try {
|
|
197
|
+
expect(rendered.container.textContent).toContain("Unable to open session");
|
|
198
|
+
expect(rendered.container.querySelector("a")?.textContent).toBe("Back to sessions");
|
|
199
|
+
expect(rendered.container.textContent).not.toContain("Try again");
|
|
200
|
+
} finally {
|
|
201
|
+
await rendered.unmount();
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
describe("SessionUnavailableRoute", () => {
|
|
207
|
+
const otherWorkspaceId = "33333333-3333-4333-8333-333333333333";
|
|
208
|
+
const accessContext = {
|
|
209
|
+
subjectId: "subject-a",
|
|
210
|
+
defaultWorkspaceId: WORKSPACE_ID,
|
|
211
|
+
accountGrants: [],
|
|
212
|
+
workspaceGrants: [WORKSPACE_ID, otherWorkspaceId].map((workspaceId) => ({
|
|
213
|
+
workspaceId,
|
|
214
|
+
accountId: "account-a",
|
|
215
|
+
subjectId: "subject-a",
|
|
216
|
+
permissions: ["sessions:read"],
|
|
217
|
+
})),
|
|
218
|
+
} as unknown as AccessContext;
|
|
219
|
+
const workspaces = [
|
|
220
|
+
{ id: WORKSPACE_ID, accountId: "account-a" },
|
|
221
|
+
{ id: otherWorkspaceId, accountId: "account-a" },
|
|
222
|
+
];
|
|
223
|
+
|
|
224
|
+
function renderRoute(getSession: () => Promise<Session>) {
|
|
225
|
+
const assigned: string[] = [];
|
|
226
|
+
const page = {
|
|
227
|
+
href: () => `https://app.example.test/workspaces/${WORKSPACE_ID}/sessions/${SESSION_ID}`,
|
|
228
|
+
origin: () => "https://app.example.test",
|
|
229
|
+
readQuery: () => new URLSearchParams(),
|
|
230
|
+
replaceQuery: () => undefined,
|
|
231
|
+
assign: (url: string) => void assigned.push(url),
|
|
232
|
+
opensBeside: false,
|
|
233
|
+
} as unknown as PageHost;
|
|
234
|
+
const value = {
|
|
235
|
+
accessContext,
|
|
236
|
+
workspaces,
|
|
237
|
+
client: { getSession },
|
|
238
|
+
} as unknown as AppContextValue;
|
|
239
|
+
const host = { navigation: { page } } as unknown as AppHost;
|
|
240
|
+
const tree = (node: ReactNode) => (
|
|
241
|
+
<RouteProviders host={host} value={value}>
|
|
242
|
+
{node}
|
|
243
|
+
</RouteProviders>
|
|
244
|
+
);
|
|
245
|
+
return { assigned, tree };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
test("keeps looking through a transient failure, then shows Try again, then recovers", async () => {
|
|
249
|
+
let failing = true;
|
|
250
|
+
let reads = 0;
|
|
251
|
+
const route = renderRoute(async () => {
|
|
252
|
+
reads += 1;
|
|
253
|
+
if (failing) throw unavailable();
|
|
254
|
+
return session;
|
|
255
|
+
});
|
|
256
|
+
const rendered = await renderComponent(
|
|
257
|
+
route.tree(<SessionUnavailableRoute workspaceId={WORKSPACE_ID} sessionId={SESSION_ID} />),
|
|
258
|
+
);
|
|
259
|
+
try {
|
|
260
|
+
await flush(DEFAULT_TRANSIENT_READ_RETRY.quietWindowMs - 3_000);
|
|
261
|
+
expect(reads).toBeGreaterThan(2);
|
|
262
|
+
expect(rendered.container.textContent).toContain("Looking for this session");
|
|
263
|
+
expect(rendered.container.textContent).not.toContain("Session unavailable");
|
|
264
|
+
|
|
265
|
+
await flush(8_000);
|
|
266
|
+
expect(rendered.container.textContent).toContain("Temporarily unavailable");
|
|
267
|
+
const tryAgain = [...rendered.container.querySelectorAll("button")].find(
|
|
268
|
+
(candidate) => candidate.textContent === "Try again",
|
|
269
|
+
);
|
|
270
|
+
expect(tryAgain).toBeDefined();
|
|
271
|
+
|
|
272
|
+
failing = false;
|
|
273
|
+
await act(async () => tryAgain?.click());
|
|
274
|
+
await flush(10);
|
|
275
|
+
expect(route.assigned).toEqual([`/workspaces/${otherWorkspaceId}/sessions/${SESSION_ID}`]);
|
|
276
|
+
} finally {
|
|
277
|
+
await rendered.unmount();
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
test("a definitive server error keeps the existing Session unavailable panel", async () => {
|
|
282
|
+
let reads = 0;
|
|
283
|
+
const route = renderRoute(async () => {
|
|
284
|
+
reads += 1;
|
|
285
|
+
throw new OpenGeniApiError(500, "", { mutation: false });
|
|
286
|
+
});
|
|
287
|
+
const rendered = await renderComponent(
|
|
288
|
+
route.tree(<SessionUnavailableRoute workspaceId={WORKSPACE_ID} sessionId={SESSION_ID} />),
|
|
289
|
+
);
|
|
290
|
+
try {
|
|
291
|
+
await flush(10);
|
|
292
|
+
expect(rendered.container.textContent).toContain("Session unavailable");
|
|
293
|
+
await flush(60_000);
|
|
294
|
+
expect(reads).toBe(1);
|
|
295
|
+
} finally {
|
|
296
|
+
await rendered.unmount();
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
test("a hidden page defers its retries and looks again when it returns", async () => {
|
|
301
|
+
const originalVisibility = Object.getOwnPropertyDescriptor(document, "visibilityState");
|
|
302
|
+
let visibility: DocumentVisibilityState = "visible";
|
|
303
|
+
Object.defineProperty(document, "visibilityState", {
|
|
304
|
+
configurable: true,
|
|
305
|
+
get: () => visibility,
|
|
306
|
+
});
|
|
307
|
+
const setVisibility = async (next: DocumentVisibilityState) => {
|
|
308
|
+
visibility = next;
|
|
309
|
+
await act(async () => document.dispatchEvent(new Event("visibilitychange")));
|
|
310
|
+
};
|
|
311
|
+
let failing = true;
|
|
312
|
+
let reads = 0;
|
|
313
|
+
const route = renderRoute(async () => {
|
|
314
|
+
reads += 1;
|
|
315
|
+
if (failing) throw unavailable();
|
|
316
|
+
return session;
|
|
317
|
+
});
|
|
318
|
+
const rendered = await renderComponent(
|
|
319
|
+
route.tree(<SessionUnavailableRoute workspaceId={WORKSPACE_ID} sessionId={SESSION_ID} />),
|
|
320
|
+
);
|
|
321
|
+
try {
|
|
322
|
+
await flush(5_000);
|
|
323
|
+
await setVisibility("hidden");
|
|
324
|
+
await flush(10_000);
|
|
325
|
+
const hiddenReads = reads;
|
|
326
|
+
await flush(120_000);
|
|
327
|
+
expect(reads).toBe(hiddenReads);
|
|
328
|
+
|
|
329
|
+
failing = false;
|
|
330
|
+
await setVisibility("visible");
|
|
331
|
+
await flush(10);
|
|
332
|
+
expect(reads).toBe(hiddenReads + 1);
|
|
333
|
+
expect(route.assigned).toEqual([`/workspaces/${otherWorkspaceId}/sessions/${SESSION_ID}`]);
|
|
334
|
+
} finally {
|
|
335
|
+
await rendered.unmount();
|
|
336
|
+
if (originalVisibility) {
|
|
337
|
+
Object.defineProperty(document, "visibilityState", originalVisibility);
|
|
338
|
+
} else {
|
|
339
|
+
Reflect.deleteProperty(document, "visibilityState");
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
});
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isTransientRequestError } from "@opengeni/sdk";
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
2
3
|
|
|
3
4
|
import { LoadingPanel, ProblemPanel } from "../components/common";
|
|
4
5
|
import { Button } from "../../ui/button";
|
|
5
6
|
import { CrossSlotDeepLinkRecovery } from "../components/cross-slot-deep-link-recovery";
|
|
6
7
|
import { useAppContext } from "../app-context";
|
|
8
|
+
import {
|
|
9
|
+
DEFAULT_TRANSIENT_READ_RETRY,
|
|
10
|
+
transientReadRetryStep,
|
|
11
|
+
usePageLiveActivity,
|
|
12
|
+
} from "../../hooks/internal";
|
|
7
13
|
import {
|
|
8
14
|
authorizedSessionReadWorkspaceIds,
|
|
9
15
|
canonicalSessionDeepLinkTarget,
|
|
@@ -15,7 +21,29 @@ import { usePage } from "../lib/navigation";
|
|
|
15
21
|
export function SessionUnavailableRoute(props: { workspaceId: string; sessionId: string }) {
|
|
16
22
|
const page = usePage();
|
|
17
23
|
const context = useAppContext();
|
|
18
|
-
const [state, setState] = useState<"resolving" | "not-found" | "error">(
|
|
24
|
+
const [state, setState] = useState<"resolving" | "not-found" | "error" | "transient">(
|
|
25
|
+
"resolving",
|
|
26
|
+
);
|
|
27
|
+
// Each attempt re-runs the lookup; transient failures schedule the next one.
|
|
28
|
+
const [attempt, setAttempt] = useState(0);
|
|
29
|
+
const transientStreakRef = useRef<{
|
|
30
|
+
key: string;
|
|
31
|
+
since: number;
|
|
32
|
+
attempts: number;
|
|
33
|
+
surfaced: boolean;
|
|
34
|
+
} | null>(null);
|
|
35
|
+
// A hidden page defers its next retry until it is visible again, and then
|
|
36
|
+
// looks with a fresh quiet window.
|
|
37
|
+
const pageLive = usePageLiveActivity();
|
|
38
|
+
const pageLiveRef = useRef(pageLive);
|
|
39
|
+
pageLiveRef.current = pageLive;
|
|
40
|
+
const deferredRetryRef = useRef(false);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (!pageLive || !deferredRetryRef.current) return;
|
|
43
|
+
deferredRetryRef.current = false;
|
|
44
|
+
transientStreakRef.current = null;
|
|
45
|
+
setAttempt((value) => value + 1);
|
|
46
|
+
}, [pageLive]);
|
|
19
47
|
const sessionWorkspaceIds = useMemo(
|
|
20
48
|
() => authorizedSessionReadWorkspaceIds(context.accessContext, context.workspaces),
|
|
21
49
|
[context.accessContext, context.workspaces],
|
|
@@ -30,7 +58,14 @@ export function SessionUnavailableRoute(props: { workspaceId: string; sessionId:
|
|
|
30
58
|
|
|
31
59
|
useEffect(() => {
|
|
32
60
|
let cancelled = false;
|
|
33
|
-
|
|
61
|
+
let retryTimer: ReturnType<typeof setTimeout> | null = null;
|
|
62
|
+
deferredRetryRef.current = false;
|
|
63
|
+
const key = `${props.workspaceId}\u0000${props.sessionId}`;
|
|
64
|
+
if (transientStreakRef.current?.key !== key) transientStreakRef.current = null;
|
|
65
|
+
// While a transient failure is already shown, background retries keep it.
|
|
66
|
+
setState((current) =>
|
|
67
|
+
current === "transient" && transientStreakRef.current ? current : "resolving",
|
|
68
|
+
);
|
|
34
69
|
void resolveAuthorizedSessionWorkspace(
|
|
35
70
|
context.client,
|
|
36
71
|
context.accessContext.workspaceGrants,
|
|
@@ -42,6 +77,7 @@ export function SessionUnavailableRoute(props: { workspaceId: string; sessionId:
|
|
|
42
77
|
).then((resolution) => {
|
|
43
78
|
if (cancelled) return;
|
|
44
79
|
if (resolution.status === "resolved") {
|
|
80
|
+
transientStreakRef.current = null;
|
|
45
81
|
page.assign(
|
|
46
82
|
canonicalSessionDeepLinkTarget(
|
|
47
83
|
resolution.workspaceId,
|
|
@@ -52,10 +88,31 @@ export function SessionUnavailableRoute(props: { workspaceId: string; sessionId:
|
|
|
52
88
|
);
|
|
53
89
|
return;
|
|
54
90
|
}
|
|
91
|
+
if (resolution.status === "error" && isTransientRequestError(resolution.error)) {
|
|
92
|
+
// A deploy or network blip: keep looking quietly, and show the problem
|
|
93
|
+
// only if it outlasts the quiet window. Keep retrying afterwards.
|
|
94
|
+
const now = Date.now();
|
|
95
|
+
const streak = (transientStreakRef.current ??= {
|
|
96
|
+
key,
|
|
97
|
+
since: now,
|
|
98
|
+
attempts: 0,
|
|
99
|
+
surfaced: false,
|
|
100
|
+
});
|
|
101
|
+
const step = transientReadRetryStep(streak, now, DEFAULT_TRANSIENT_READ_RETRY);
|
|
102
|
+
if (!step.quiet) setState("transient");
|
|
103
|
+
retryTimer = setTimeout(() => {
|
|
104
|
+
retryTimer = null;
|
|
105
|
+
if (pageLiveRef.current) setAttempt((value) => value + 1);
|
|
106
|
+
else deferredRetryRef.current = true;
|
|
107
|
+
}, step.delayMs);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
transientStreakRef.current = null;
|
|
55
111
|
setState(resolution.status === "error" ? "error" : "not-found");
|
|
56
112
|
});
|
|
57
113
|
return () => {
|
|
58
114
|
cancelled = true;
|
|
115
|
+
if (retryTimer !== null) clearTimeout(retryTimer);
|
|
59
116
|
};
|
|
60
117
|
}, [
|
|
61
118
|
page,
|
|
@@ -64,9 +121,23 @@ export function SessionUnavailableRoute(props: { workspaceId: string; sessionId:
|
|
|
64
121
|
sessionWorkspaceIds,
|
|
65
122
|
props.sessionId,
|
|
66
123
|
props.workspaceId,
|
|
124
|
+
attempt,
|
|
67
125
|
]);
|
|
68
126
|
|
|
69
127
|
if (state === "resolving") return <LoadingPanel label="Looking for this session" />;
|
|
128
|
+
if (state === "transient") {
|
|
129
|
+
return (
|
|
130
|
+
<ProblemPanel
|
|
131
|
+
title="Temporarily unavailable"
|
|
132
|
+
description="Retrying automatically."
|
|
133
|
+
action={
|
|
134
|
+
<Button type="button" variant="outline" onClick={() => setAttempt((value) => value + 1)}>
|
|
135
|
+
Try again
|
|
136
|
+
</Button>
|
|
137
|
+
}
|
|
138
|
+
/>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
70
141
|
const unavailable = (
|
|
71
142
|
<ProblemPanel
|
|
72
143
|
title={state === "error" ? "Session unavailable" : "Session not found"}
|
|
@@ -134,7 +134,8 @@ import {
|
|
|
134
134
|
} from "react";
|
|
135
135
|
import { toast } from "../lib/toast";
|
|
136
136
|
|
|
137
|
-
import {
|
|
137
|
+
import { useAppApi } from "../lib/app-api";
|
|
138
|
+
import { useSessionFailureToasts } from "../lib/session-failure-toasts";
|
|
138
139
|
import { apiErrorFacts, userErrorText } from "../../ui/api-error";
|
|
139
140
|
import { ConsoleComposer } from "../components/Composer";
|
|
140
141
|
import { CONSOLE_TIMELINE_ALLOWANCE_LABELS } from "../lib/allowance-labels";
|
|
@@ -858,18 +859,7 @@ export function SessionRoute({
|
|
|
858
859
|
},
|
|
859
860
|
[sessionId, sessionEventFeedStore, setContextConnectionState, setContextSession],
|
|
860
861
|
);
|
|
861
|
-
|
|
862
|
-
if (streamError && !isApiErrorStatus(streamError, 404)) {
|
|
863
|
-
toast.error("Event stream disconnected", {
|
|
864
|
-
description: streamError.message,
|
|
865
|
-
});
|
|
866
|
-
}
|
|
867
|
-
}, [streamError]);
|
|
868
|
-
useEffect(() => {
|
|
869
|
-
if (loadError && !isApiErrorStatus(loadError, 404)) {
|
|
870
|
-
toast.error("Failed to load session", { description: String(loadError) });
|
|
871
|
-
}
|
|
872
|
-
}, [loadError]);
|
|
862
|
+
useSessionFailureToasts(loadError, streamError);
|
|
873
863
|
// A reconnect OAuth round-trip lands back here (the reconnect card set
|
|
874
864
|
// returnPath to this session). The connection is refreshed server-side, but
|
|
875
865
|
// the original tool call was settled as an error and is never replayed. Strip
|
|
@@ -1277,6 +1267,7 @@ export function SessionRoute({
|
|
|
1277
1267
|
workspaceId={workspaceId}
|
|
1278
1268
|
sessionId={sessionId}
|
|
1279
1269
|
loadError={loadError}
|
|
1270
|
+
onRetry={() => void refreshSession()}
|
|
1280
1271
|
/>
|
|
1281
1272
|
</Suspense>
|
|
1282
1273
|
);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useAppApi } from "../lib/app-api";
|
|
2
|
+
import { useSessionUiFeature } from "../lib/session-ui-features";
|
|
2
3
|
import { initialWorkspaceMachineCompute } from "../lib/workspace-default-machine";
|
|
3
4
|
import { t } from "../lib/console-text";
|
|
4
5
|
import { ANALYTICS_COLLECTION_ENABLED_EVENT } from "../lib/analytics-consent";
|
|
@@ -259,6 +260,7 @@ function SessionsIndexRouteContent({
|
|
|
259
260
|
const context = useAppContext();
|
|
260
261
|
const api = useAppApi();
|
|
261
262
|
const page = usePage();
|
|
263
|
+
const starters = useSessionUiFeature("starters");
|
|
262
264
|
const connectionAccounts = useConnectionAccounts(
|
|
263
265
|
context.client,
|
|
264
266
|
{
|
|
@@ -2020,15 +2022,17 @@ function SessionsIndexRouteContent({
|
|
|
2020
2022
|
</div>
|
|
2021
2023
|
|
|
2022
2024
|
<RecentSessions workspaceId={workspaceId} />
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2025
|
+
{starters ? (
|
|
2026
|
+
<NewSessionStarters
|
|
2027
|
+
workspaceId={workspaceId}
|
|
2028
|
+
set={signupStarterSet(context.authSession?.user.email, workspace?.accountId)}
|
|
2029
|
+
disabled={busy || newSessionDraft.loading}
|
|
2030
|
+
onSelect={(prompt) => {
|
|
2031
|
+
setMessage(prompt);
|
|
2032
|
+
composerRegionRef.current?.querySelector("textarea")?.focus({ preventScroll: true });
|
|
2033
|
+
}}
|
|
2034
|
+
/>
|
|
2035
|
+
) : null}
|
|
2032
2036
|
</div>
|
|
2033
2037
|
<ChannelCreateDialog
|
|
2034
2038
|
open={projectDialogOpen}
|