oysterun 1.5.7-beta.8 → 1.5.7
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/bin/oysterun.mjs +25 -1
- package/dev/client/connectivity/internal-connectivity-status.d.mts +10 -2
- package/dev/client/connectivity/internal-connectivity-status.mjs +17 -6
- package/dev/client/connectivity/managed-host-browser.d.mts +19 -3
- package/dev/client/connectivity/managed-host-browser.mjs +323 -24
- package/dev/client/web/index.html +1490 -393
- package/dev/client/web-chat/dist/assets/{ReactPrism-BVwTeJ2J.js → ReactPrism-C_qvQuWU.js} +1 -1
- package/dev/client/web-chat/dist/assets/{ReactPrism-BVwTeJ2J.js.map → ReactPrism-C_qvQuWU.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/{index-DyTV0z1z.css → index-1o8_vyRd.css} +1 -1
- package/dev/client/web-chat/dist/assets/{index-BIJqUapL.js → index-B44MyL7f.js} +2 -2
- package/dev/client/web-chat/dist/assets/index-B44MyL7f.js.map +1 -0
- package/dev/client/web-chat/dist/assets/{index-B0-fm02U.js → index-BgxQAT-U.js} +90 -90
- package/dev/client/web-chat/dist/assets/index-BgxQAT-U.js.map +1 -0
- package/dev/client/web-chat/dist/assets/{index-Bcsmmpmp.js → index-DdoJ_noi.js} +1 -1
- package/dev/client/web-chat/dist/assets/{index-Bcsmmpmp.js.map → index-DdoJ_noi.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/{pdf-Dx9dlfRj.js → pdf-DgSk769O.js} +3 -3
- package/dev/client/web-chat/dist/assets/pdf-DgSk769O.js.map +1 -0
- package/dev/client/web-chat/dist/assets/{web-Ql5RPS3a.js → web-CIst0rFB.js} +1 -1
- package/dev/client/web-chat/dist/assets/{web-Ql5RPS3a.js.map → web-CIst0rFB.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/{web-CNSm9WCL.js → web-D3DR1arO.js} +1 -1
- package/dev/client/web-chat/dist/assets/{web-CNSm9WCL.js.map → web-D3DR1arO.js.map} +1 -1
- package/dev/client/web-chat/dist/index.html +2 -2
- package/docs/routec/config_hierachy.md +132 -950
- package/docs/routec/dev/chat_local_link_annotation_pipeline.md +4 -0
- package/docs/routec/dev/cloud_deplyments.md +8 -0
- package/docs/routec/dev/host_update_runtime_identity.md +31 -0
- package/docs/routec/dev/node_runtime_startup.md +14 -3
- package/docs/routec/dev/npmjs_publish.md +36 -24
- package/docs/routec/dev/provider_command_resolution.md +11 -0
- package/docs/routec/form_UI_fields.md +287 -427
- package/docs/routec/host2_turn_started_idempotency_diagnostics.md +91 -105
- package/docs/routec/host_cloud_app_auth.md +102 -203
- package/docs/routec/host_owner_message_navigation.md +126 -93
- package/docs/routec/host_runtime_error_boundary.md +75 -60
- package/docs/routec/host_setup.md +155 -304
- package/docs/routec/hyperlink.md +91 -77
- package/docs/routec/hyperlink_rendering_mechanism.md +57 -315
- package/docs/routec/hyperlink_rendering_rule.md +89 -245
- package/docs/routec/large_tool_event_spillover.md +87 -38
- package/docs/routec/media_upload_image_compression.md +74 -65
- package/docs/routec/oysterun_operation_interface_spec.md +173 -650
- package/docs/routec/prev_page_map.md +101 -85
- package/docs/routec/provider_contract.md +153 -355
- package/docs/routec/skill_installation.md +128 -158
- package/docs/routec/tool_message_transfer_compression.md +43 -69
- package/host-service/adapters/claude-code-adapter.mjs +145 -5
- package/host-service/adapters/codex-app-server-adapter.mjs +34 -0
- package/host-service/agent-config.mjs +90 -22
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-find-context/SKILL.md +15 -2
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-scheduler/SKILL.md +5 -0
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-session-chat/SKILL.md +134 -1
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-sessions/SKILL.md +98 -2
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-telegram/SKILL.md +18 -4
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-website/SKILL.md +184 -21
- package/host-service/assets/product-skills/oysterun-find-context/SKILL.md +15 -2
- package/host-service/assets/product-skills/oysterun-scheduler/SKILL.md +5 -0
- package/host-service/assets/product-skills/oysterun-session-chat/SKILL.md +134 -1
- package/host-service/assets/product-skills/oysterun-sessions/SKILL.md +98 -2
- package/host-service/assets/product-skills/oysterun-telegram/SKILL.md +18 -4
- package/host-service/assets/product-skills/oysterun-website/SKILL.md +184 -21
- package/host-service/claude-acp-model-discovery.mjs +247 -6
- package/host-service/cli/assert-lifecycle-operation-available.mjs +117 -0
- package/host-service/cli/product-cli.mjs +140 -264
- package/host-service/cli/run-host-lifecycle.mjs +133 -0
- package/host-service/config.mjs +116 -26
- package/host-service/connectivity/cloud-retry-decision.mjs +57 -0
- package/host-service/connectivity/managed-tunnel-runtime-status.mjs +11 -0
- package/host-service/connectivity/retry-policy.json +9 -0
- package/host-service/connectivity/transport-usage-circuit-store.mjs +161 -0
- package/host-service/connectivity/webrtc-signaling-service.mjs +172 -33
- package/host-service/frp-agent.mjs +58 -0
- package/host-service/host-lifecycle-recovery.mjs +196 -0
- package/host-service/host-runtime-diagnostics.mjs +32 -0
- package/host-service/managed-identity-lifecycle.mjs +165 -0
- package/host-service/matrix-transcript-read-adapter.mjs +176 -0
- package/host-service/node-npm-runtime-identity.mjs +349 -7
- package/host-service/package.json +11 -2
- package/host-service/provider-registry.mjs +47 -0
- package/host-service/registered-update-authority.mjs +368 -0
- package/host-service/routec-matrix-storage-adapter.mjs +68 -4
- package/host-service/scheduler-setup-snapshot-contract.mjs +16 -2
- package/host-service/server.mjs +2761 -329
- package/host-service/session-history.mjs +3 -0
- package/host-service/session-manager.mjs +41 -4
- package/host-service/session-profile-runtime.mjs +54 -0
- package/host-service/setup.mjs +155 -82
- package/host-service/telegram-adapter.mjs +33 -0
- package/host-service/telegram-bridge.mjs +673 -190
- package/host-service/templates/agent-site/index.html +17 -1
- package/host-service/update-reminder-state.mjs +353 -0
- package/host-service/website-canonical-url.mjs +220 -0
- package/package.json +6 -1
- package/static/site/404/en/index.html +75 -0
- package/static/site/404/zh/index.html +75 -0
- package/static/site/assets/site.css +489 -0
- package/static/site/blog/en/index.html +92 -0
- package/static/site/blog/en/index.md +9 -0
- package/static/site/blog/generated_manifest.json +22 -10
- package/static/site/blog/index.html +18 -55
- package/static/site/blog/voice-input-model-experiment/en/index.html +55 -18
- package/static/site/blog/voice-input-model-experiment/en/index.md +1211 -0
- package/static/site/blog/voice-input-model-experiment/zh/index.html +59 -92
- package/static/site/blog/voice-input-model-experiment/zh/index.md +1220 -0
- package/static/site/blog/zh/index.html +92 -0
- package/static/site/blog/zh/index.md +9 -0
- package/static/site/docs/choose-and-recover-a-provider/assets/article.css +104 -0
- package/static/site/docs/choose-and-recover-a-provider/assets/codex-login-required.png +0 -0
- package/static/site/docs/choose-and-recover-a-provider/assets/codex-recovered.png +0 -0
- package/static/site/docs/choose-and-recover-a-provider/assets/publication/provider-command-unavailable.png +0 -0
- package/static/site/docs/choose-and-recover-a-provider/assets/publication/provider-login-required.png +0 -0
- package/static/site/docs/choose-and-recover-a-provider/assets/publication/provider-ready-after-restart.png +0 -0
- package/static/site/docs/choose-and-recover-a-provider/assets/publication/provider-refresh-ready.png +0 -0
- package/static/site/docs/choose-and-recover-a-provider/assets/publication/provider-restart-menu.png +0 -0
- package/static/site/docs/choose-and-recover-a-provider/assets/publication-screenshots.json +150 -0
- package/static/site/docs/choose-and-recover-a-provider/en/index.html +474 -0
- package/static/site/docs/choose-and-recover-a-provider/en/index.md +174 -0
- package/static/site/docs/choose-and-recover-a-provider/zh/index.html +474 -0
- package/static/site/docs/choose-and-recover-a-provider/zh/index.md +174 -0
- package/static/site/docs/configure-session-files-and-settings/assets/article.css +92 -0
- package/static/site/docs/configure-session-files-and-settings/assets/publication/folder-picker-focused.png +0 -0
- package/static/site/docs/configure-session-files-and-settings/assets/publication/session-profile-root.png +0 -0
- package/static/site/docs/configure-session-files-and-settings/assets/publication/session-setup-confirmed.png +0 -0
- package/static/site/docs/configure-session-files-and-settings/assets/publication-screenshots.json +100 -0
- package/static/site/docs/configure-session-files-and-settings/en/index.html +456 -0
- package/static/site/docs/configure-session-files-and-settings/en/index.md +130 -0
- package/static/site/docs/configure-session-files-and-settings/zh/index.html +456 -0
- package/static/site/docs/configure-session-files-and-settings/zh/index.md +132 -0
- package/static/site/docs/en/index.html +174 -0
- package/static/site/docs/en/index.md +31 -0
- package/static/site/docs/generated_manifest.json +720 -0
- package/static/site/docs/host-authentication-and-connection/assets/article.css +80 -0
- package/static/site/docs/host-authentication-and-connection/assets/publication/invalid-credentials-empty-password.png +0 -0
- package/static/site/docs/host-authentication-and-connection/assets/publication/password-sign-in.png +0 -0
- package/static/site/docs/host-authentication-and-connection/assets/publication/sessions-connected-direct-host.png +0 -0
- package/static/site/docs/host-authentication-and-connection/assets/publication-screenshots.json +100 -0
- package/static/site/docs/host-authentication-and-connection/en/index.html +429 -0
- package/static/site/docs/host-authentication-and-connection/en/index.md +108 -0
- package/static/site/docs/host-authentication-and-connection/zh/index.html +429 -0
- package/static/site/docs/host-authentication-and-connection/zh/index.md +110 -0
- package/static/site/docs/index.html +28 -0
- package/static/site/docs/install-and-use-a-skill/assets/article.css +141 -0
- package/static/site/docs/install-and-use-a-skill/assets/publication/skill-helper-draft.jpg +0 -0
- package/static/site/docs/install-and-use-a-skill/assets/publication/skill-read-only-result.jpg +0 -0
- package/static/site/docs/install-and-use-a-skill/assets/publication/skill-state-menu.jpg +0 -0
- package/static/site/docs/install-and-use-a-skill/assets/publication/skill-update-result.jpg +0 -0
- package/static/site/docs/install-and-use-a-skill/assets/publication/update-result.png +0 -0
- package/static/site/docs/install-and-use-a-skill/assets/publication-screenshots.json +122 -0
- package/static/site/docs/install-and-use-a-skill/en/index.html +484 -0
- package/static/site/docs/install-and-use-a-skill/en/index.md +233 -0
- package/static/site/docs/install-and-use-a-skill/zh/index.html +484 -0
- package/static/site/docs/install-and-use-a-skill/zh/index.md +233 -0
- package/static/site/docs/llms.txt +40 -0
- package/static/site/docs/read-large-tool-results/assets/article.css +132 -0
- package/static/site/docs/read-large-tool-results/assets/publication/oversized-result.jpg +0 -0
- package/static/site/docs/read-large-tool-results/assets/publication/tool-detail-page-two.jpg +0 -0
- package/static/site/docs/read-large-tool-results/assets/publication/tool-row-after-close.jpg +0 -0
- package/static/site/docs/read-large-tool-results/assets/publication/tool-row-view-details.jpg +0 -0
- package/static/site/docs/read-large-tool-results/assets/publication-screenshots.json +130 -0
- package/static/site/docs/read-large-tool-results/en/index.html +443 -0
- package/static/site/docs/read-large-tool-results/en/index.md +176 -0
- package/static/site/docs/read-large-tool-results/zh/index.html +443 -0
- package/static/site/docs/read-large-tool-results/zh/index.md +176 -0
- package/static/site/docs/recover-from-a-host-runtime-error/assets/article.css +104 -0
- package/static/site/docs/recover-from-a-host-runtime-error/assets/publication/recovered-chat.png +0 -0
- package/static/site/docs/recover-from-a-host-runtime-error/assets/publication/runtime-error.png +0 -0
- package/static/site/docs/recover-from-a-host-runtime-error/assets/publication-screenshots.json +70 -0
- package/static/site/docs/recover-from-a-host-runtime-error/en/index.html +453 -0
- package/static/site/docs/recover-from-a-host-runtime-error/en/index.md +142 -0
- package/static/site/docs/recover-from-a-host-runtime-error/zh/index.html +453 -0
- package/static/site/docs/recover-from-a-host-runtime-error/zh/index.md +142 -0
- package/static/site/docs/restore-work-after-a-host-restart/assets/article.css +63 -0
- package/static/site/docs/restore-work-after-a-host-restart/assets/publication/loop-disabled-after-restart.png +0 -0
- package/static/site/docs/restore-work-after-a-host-restart/assets/publication/restart-control.png +0 -0
- package/static/site/docs/restore-work-after-a-host-restart/assets/publication/restart-ready-sign-in.png +0 -0
- package/static/site/docs/restore-work-after-a-host-restart/assets/publication/restored-checkpoint.png +0 -0
- package/static/site/docs/restore-work-after-a-host-restart/assets/publication-screenshots.json +130 -0
- package/static/site/docs/restore-work-after-a-host-restart/en/index.html +444 -0
- package/static/site/docs/restore-work-after-a-host-restart/en/index.md +110 -0
- package/static/site/docs/restore-work-after-a-host-restart/zh/index.html +444 -0
- package/static/site/docs/restore-work-after-a-host-restart/zh/index.md +110 -0
- package/static/site/docs/search-index.json +273 -0
- package/static/site/docs/send-images-and-media/assets/article.css +132 -0
- package/static/site/docs/send-images-and-media/assets/publication/safe-image-viewer.jpg +0 -0
- package/static/site/docs/send-images-and-media/assets/publication/sent-ordered-group.jpg +0 -0
- package/static/site/docs/send-images-and-media/assets/publication/staged-ordered-group.jpg +0 -0
- package/static/site/docs/send-images-and-media/assets/publication-screenshots.json +100 -0
- package/static/site/docs/send-images-and-media/en/index.html +468 -0
- package/static/site/docs/send-images-and-media/en/index.md +152 -0
- package/static/site/docs/send-images-and-media/zh/index.html +468 -0
- package/static/site/docs/send-images-and-media/zh/index.md +152 -0
- package/static/site/docs/set-up-and-understand-a-host/assets/article.css +104 -0
- package/static/site/docs/set-up-and-understand-a-host/assets/publication/host-identity-browse-root.png +0 -0
- package/static/site/docs/set-up-and-understand-a-host/assets/publication/host-setup-managed-ready.png +0 -0
- package/static/site/docs/set-up-and-understand-a-host/assets/publication/host-setup-seven-steps.png +0 -0
- package/static/site/docs/set-up-and-understand-a-host/assets/publication/session-profile-identity.png +0 -0
- package/static/site/docs/set-up-and-understand-a-host/assets/publication/session-setup-identity.png +0 -0
- package/static/site/docs/set-up-and-understand-a-host/assets/publication/website-link.png +0 -0
- package/static/site/docs/set-up-and-understand-a-host/assets/publication-screenshots.json +178 -0
- package/static/site/docs/set-up-and-understand-a-host/en/index.html +519 -0
- package/static/site/docs/set-up-and-understand-a-host/en/index.md +211 -0
- package/static/site/docs/set-up-and-understand-a-host/zh/index.html +519 -0
- package/static/site/docs/set-up-and-understand-a-host/zh/index.md +211 -0
- package/static/site/docs/understand-agent-activity/assets/article.css +154 -0
- package/static/site/docs/understand-agent-activity/assets/publication/session-available.png +0 -0
- package/static/site/docs/understand-agent-activity/assets/publication/turn-occupied.png +0 -0
- package/static/site/docs/understand-agent-activity/assets/publication/turn-terminal.png +0 -0
- package/static/site/docs/understand-agent-activity/assets/publication-screenshots.json +100 -0
- package/static/site/docs/understand-agent-activity/en/index.html +441 -0
- package/static/site/docs/understand-agent-activity/en/index.md +146 -0
- package/static/site/docs/understand-agent-activity/zh/index.html +441 -0
- package/static/site/docs/understand-agent-activity/zh/index.md +146 -0
- package/static/site/docs/use-the-oysterun-cli-safely/assets/article.css +138 -0
- package/static/site/docs/use-the-oysterun-cli-safely/assets/publication/cli-post-status.jpg +0 -0
- package/static/site/docs/use-the-oysterun-cli-safely/assets/publication/cli-protected-dry-run.jpg +0 -0
- package/static/site/docs/use-the-oysterun-cli-safely/assets/publication/cli-supported-modules.jpg +0 -0
- package/static/site/docs/use-the-oysterun-cli-safely/assets/publication/cli-target-read.jpg +0 -0
- package/static/site/docs/use-the-oysterun-cli-safely/assets/publication-screenshots.json +122 -0
- package/static/site/docs/use-the-oysterun-cli-safely/en/index.html +499 -0
- package/static/site/docs/use-the-oysterun-cli-safely/en/index.md +548 -0
- package/static/site/docs/use-the-oysterun-cli-safely/zh/index.html +499 -0
- package/static/site/docs/use-the-oysterun-cli-safely/zh/index.md +548 -0
- package/static/site/docs/zh/index.html +174 -0
- package/static/site/docs/zh/index.md +31 -0
- package/static/site/en/index.html +227 -0
- package/static/site/en/index.md +33 -0
- package/static/site/faq/en/index.html +116 -0
- package/static/site/faq/en/index.md +33 -0
- package/static/site/faq/index.html +28 -0
- package/static/site/faq/zh/index.html +116 -0
- package/static/site/faq/zh/index.md +33 -0
- package/static/site/getting-started/en/index.html +131 -0
- package/static/site/getting-started/en/index.md +18 -0
- package/static/site/getting-started/index.html +28 -0
- package/static/site/getting-started/zh/index.html +131 -0
- package/static/site/getting-started/zh/index.md +18 -0
- package/static/site/index.html +14 -1187
- package/static/site/llms.txt +25 -0
- package/static/site/overview/en/index.html +87 -0
- package/static/site/overview/en/index.md +36 -0
- package/static/site/overview/index.html +28 -0
- package/static/site/overview/zh/index.html +87 -0
- package/static/site/overview/zh/index.md +36 -0
- package/static/site/privacy/en/index.html +124 -0
- package/static/site/privacy/en/index.md +45 -0
- package/static/site/privacy/index.html +18 -171
- package/static/site/privacy/zh/index.html +124 -0
- package/static/site/privacy/zh/index.md +45 -0
- package/static/site/robots.txt +3 -0
- package/static/site/sitemap.xml +193 -0
- package/static/site/zh/index.html +227 -0
- package/static/site/zh/index.md +33 -0
- package/static/site_source/content/AGENTS.md +9 -2
- package/static/site_source/content/blog/published/voice-input-model-experiment/zh/article.html +0 -70
- package/static/site_source/content/tutorials/drafts/build-a-website-with-natural-language/assets/article.css +92 -0
- package/static/site_source/content/tutorials/drafts/build-a-website-with-natural-language/assets/build-complete.png +0 -0
- package/static/site_source/content/tutorials/drafts/build-a-website-with-natural-language/assets/cover.svg +39 -0
- package/static/site_source/content/tutorials/drafts/build-a-website-with-natural-language/assets/empty-project.png +0 -0
- package/static/site_source/content/tutorials/drafts/build-a-website-with-natural-language/assets/natural-language-prompt.png +0 -0
- package/static/site_source/content/tutorials/drafts/build-a-website-with-natural-language/assets/web-catalog-owner-only.png +0 -0
- package/static/site_source/content/tutorials/drafts/build-a-website-with-natural-language/assets/website-result.png +0 -0
- package/static/site_source/content/tutorials/drafts/build-a-website-with-natural-language/content.json +33 -0
- package/static/site_source/content/tutorials/drafts/build-a-website-with-natural-language/en/article.html +116 -0
- package/static/site_source/content/tutorials/drafts/build-a-website-with-natural-language/zh/article.html +116 -0
- package/static/site_source/content/tutorials/drafts/find-and-return-to-a-message/assets/article.css +87 -0
- package/static/site_source/content/tutorials/drafts/find-and-return-to-a-message/assets/cover.svg +41 -0
- package/static/site_source/content/tutorials/drafts/find-and-return-to-a-message/assets/publication/previous-result.png +0 -0
- package/static/site_source/content/tutorials/drafts/find-and-return-to-a-message/assets/publication/returned-source.png +0 -0
- package/static/site_source/content/tutorials/drafts/find-and-return-to-a-message/assets/publication/source-message.png +0 -0
- package/static/site_source/content/tutorials/drafts/find-and-return-to-a-message/assets/publication-screenshots.json +100 -0
- package/static/site_source/content/tutorials/drafts/find-and-return-to-a-message/content.json +34 -0
- package/static/site_source/content/tutorials/drafts/find-and-return-to-a-message/en/article.html +91 -0
- package/static/site_source/content/tutorials/drafts/find-and-return-to-a-message/zh/article.html +91 -0
- package/static/site_source/content/tutorials/drafts/follow-live-chat-output/assets/article.css +87 -0
- package/static/site_source/content/tutorials/drafts/follow-live-chat-output/assets/cover.svg +55 -0
- package/static/site_source/content/tutorials/drafts/follow-live-chat-output/assets/publication/jump-to-latest.png +0 -0
- package/static/site_source/content/tutorials/drafts/follow-live-chat-output/assets/publication/live-output-arriving.png +0 -0
- package/static/site_source/content/tutorials/drafts/follow-live-chat-output/assets/publication/older-position-stable.png +0 -0
- package/static/site_source/content/tutorials/drafts/follow-live-chat-output/assets/publication-screenshots.json +100 -0
- package/static/site_source/content/tutorials/drafts/follow-live-chat-output/content.json +34 -0
- package/static/site_source/content/tutorials/drafts/follow-live-chat-output/en/article.html +91 -0
- package/static/site_source/content/tutorials/drafts/follow-live-chat-output/zh/article.html +91 -0
- package/static/site_source/content/tutorials/drafts/getting-started/assets/article.css +50 -0
- package/static/site_source/content/tutorials/drafts/getting-started/content.json +10 -4
- package/static/site_source/content/tutorials/drafts/getting-started/en/article.html +109 -132
- package/static/site_source/content/tutorials/drafts/getting-started/zh/article.html +120 -0
- package/static/site_source/content/tutorials/drafts/open-links-safely/assets/article.css +91 -0
- package/static/site_source/content/tutorials/drafts/open-links-safely/assets/cover.svg +48 -0
- package/static/site_source/content/tutorials/drafts/open-links-safely/assets/publication/file-preview-safe.png +0 -0
- package/static/site_source/content/tutorials/drafts/open-links-safely/assets/publication/local-link-confirmed.png +0 -0
- package/static/site_source/content/tutorials/drafts/open-links-safely/assets/publication/returned-source-session.png +0 -0
- package/static/site_source/content/tutorials/drafts/open-links-safely/assets/publication/source-links.png +0 -0
- package/static/site_source/content/tutorials/drafts/open-links-safely/assets/publication-screenshots.json +130 -0
- package/static/site_source/content/tutorials/drafts/open-links-safely/content.json +34 -0
- package/static/site_source/content/tutorials/drafts/open-links-safely/en/article.html +111 -0
- package/static/site_source/content/tutorials/drafts/open-links-safely/zh/article.html +111 -0
- package/static/site_source/content/tutorials/drafts/pin-and-return-to-messages/assets/article.css +87 -0
- package/static/site_source/content/tutorials/drafts/pin-and-return-to-messages/assets/cover.svg +53 -0
- package/static/site_source/content/tutorials/drafts/pin-and-return-to-messages/assets/publication/pin-menu.png +0 -0
- package/static/site_source/content/tutorials/drafts/pin-and-return-to-messages/assets/publication/pinned-focus.png +0 -0
- package/static/site_source/content/tutorials/drafts/pin-and-return-to-messages/assets/publication/pinned-list.png +0 -0
- package/static/site_source/content/tutorials/drafts/pin-and-return-to-messages/assets/publication/previous-page.png +0 -0
- package/static/site_source/content/tutorials/drafts/pin-and-return-to-messages/assets/publication-screenshots.json +130 -0
- package/static/site_source/content/tutorials/drafts/pin-and-return-to-messages/content.json +34 -0
- package/static/site_source/content/tutorials/drafts/pin-and-return-to-messages/en/article.html +123 -0
- package/static/site_source/content/tutorials/drafts/pin-and-return-to-messages/zh/article.html +123 -0
- package/static/site_source/content/tutorials/drafts/recover-delayed-chat-sync/assets/article.css +87 -0
- package/static/site_source/content/tutorials/drafts/recover-delayed-chat-sync/assets/cover.svg +50 -0
- package/static/site_source/content/tutorials/drafts/recover-delayed-chat-sync/assets/publication/connection-lost.png +0 -0
- package/static/site_source/content/tutorials/drafts/recover-delayed-chat-sync/assets/publication/reconnecting.png +0 -0
- package/static/site_source/content/tutorials/drafts/recover-delayed-chat-sync/assets/publication/recovered.png +0 -0
- package/static/site_source/content/tutorials/drafts/recover-delayed-chat-sync/assets/publication-screenshots.json +94 -0
- package/static/site_source/content/tutorials/drafts/recover-delayed-chat-sync/content.json +34 -0
- package/static/site_source/content/tutorials/drafts/recover-delayed-chat-sync/en/article.html +102 -0
- package/static/site_source/content/tutorials/drafts/recover-delayed-chat-sync/zh/article.html +102 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/assets/article.css +92 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/assets/cover.svg +39 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/assets/empty-project.png +0 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/assets/latest-report.png +0 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/assets/natural-language-prompt.png +0 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/assets/no-runs.png +0 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/assets/run-history-pass.png +0 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/assets/run-log.png +0 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/assets/test-run-prompt.png +0 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/content.json +33 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/en/article.html +124 -0
- package/static/site_source/content/tutorials/drafts/schedule-agent-work-with-natural-language/zh/article.html +124 -0
- package/static/site_source/content/tutorials/drafts/write-markdown-in-chat/assets/article.css +105 -0
- package/static/site_source/content/tutorials/drafts/write-markdown-in-chat/assets/cover.svg +44 -0
- package/static/site_source/content/tutorials/drafts/write-markdown-in-chat/assets/publication/markdown-correction.png +0 -0
- package/static/site_source/content/tutorials/drafts/write-markdown-in-chat/assets/publication/markdown-rendered.png +0 -0
- package/static/site_source/content/tutorials/drafts/write-markdown-in-chat/assets/publication/markdown-source.png +0 -0
- package/static/site_source/content/tutorials/drafts/write-markdown-in-chat/assets/publication-screenshots.json +100 -0
- package/static/site_source/content/tutorials/drafts/write-markdown-in-chat/content.json +34 -0
- package/static/site_source/content/tutorials/drafts/write-markdown-in-chat/en/article.html +104 -0
- package/static/site_source/content/tutorials/drafts/write-markdown-in-chat/zh/article.html +104 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/assets/article.css +104 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/assets/codex-login-required.png +0 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/assets/codex-recovered.png +0 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/assets/publication/provider-command-unavailable.png +0 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/assets/publication/provider-login-required.png +0 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/assets/publication/provider-ready-after-restart.png +0 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/assets/publication/provider-refresh-ready.png +0 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/assets/publication/provider-restart-menu.png +0 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/assets/publication-screenshots.json +150 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/content.json +23 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/en/article.html +141 -0
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/zh/article.html +141 -0
- package/static/site_source/content/tutorials/published/configure-session-files-and-settings/assets/article.css +92 -0
- package/static/site_source/content/tutorials/published/configure-session-files-and-settings/assets/publication/folder-picker-focused.png +0 -0
- package/static/site_source/content/tutorials/published/configure-session-files-and-settings/assets/publication/session-profile-root.png +0 -0
- package/static/site_source/content/tutorials/published/configure-session-files-and-settings/assets/publication/session-setup-confirmed.png +0 -0
- package/static/site_source/content/tutorials/published/configure-session-files-and-settings/assets/publication-screenshots.json +100 -0
- package/static/site_source/content/tutorials/published/configure-session-files-and-settings/content.json +23 -0
- package/static/site_source/content/tutorials/published/configure-session-files-and-settings/en/article.html +126 -0
- package/static/site_source/content/tutorials/published/configure-session-files-and-settings/zh/article.html +126 -0
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/assets/article.css +80 -0
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/assets/publication/invalid-credentials-empty-password.png +0 -0
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/assets/publication/password-sign-in.png +0 -0
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/assets/publication/sessions-connected-direct-host.png +0 -0
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/assets/publication-screenshots.json +100 -0
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/content.json +23 -0
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/en/article.html +101 -0
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/zh/article.html +101 -0
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/assets/article.css +141 -0
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/assets/cover.svg +59 -0
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/assets/publication/skill-helper-draft.jpg +0 -0
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/assets/publication/skill-read-only-result.jpg +0 -0
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/assets/publication/skill-state-menu.jpg +0 -0
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/assets/publication/skill-update-result.jpg +0 -0
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/assets/publication/update-result.png +0 -0
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/assets/publication-screenshots.json +122 -0
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/content.json +34 -0
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/en/article.html +155 -0
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/zh/article.html +155 -0
- package/static/site_source/content/tutorials/published/read-large-tool-results/assets/article.css +132 -0
- package/static/site_source/content/tutorials/published/read-large-tool-results/assets/publication/oversized-result.jpg +0 -0
- package/static/site_source/content/tutorials/published/read-large-tool-results/assets/publication/tool-detail-page-two.jpg +0 -0
- package/static/site_source/content/tutorials/published/read-large-tool-results/assets/publication/tool-row-after-close.jpg +0 -0
- package/static/site_source/content/tutorials/published/read-large-tool-results/assets/publication/tool-row-view-details.jpg +0 -0
- package/static/site_source/content/tutorials/published/read-large-tool-results/assets/publication-screenshots.json +130 -0
- package/static/site_source/content/tutorials/published/read-large-tool-results/content.json +23 -0
- package/static/site_source/content/tutorials/published/read-large-tool-results/en/article.html +116 -0
- package/static/site_source/content/tutorials/published/read-large-tool-results/zh/article.html +116 -0
- package/static/site_source/content/tutorials/published/recover-from-a-host-runtime-error/assets/article.css +104 -0
- package/static/site_source/content/tutorials/published/recover-from-a-host-runtime-error/assets/publication/recovered-chat.png +0 -0
- package/static/site_source/content/tutorials/published/recover-from-a-host-runtime-error/assets/publication/runtime-error.png +0 -0
- package/static/site_source/content/tutorials/published/recover-from-a-host-runtime-error/assets/publication-screenshots.json +70 -0
- package/static/site_source/content/tutorials/published/recover-from-a-host-runtime-error/content.json +23 -0
- package/static/site_source/content/tutorials/published/recover-from-a-host-runtime-error/en/article.html +122 -0
- package/static/site_source/content/tutorials/published/recover-from-a-host-runtime-error/zh/article.html +122 -0
- package/static/site_source/content/tutorials/published/restore-work-after-a-host-restart/assets/article.css +63 -0
- package/static/site_source/content/tutorials/published/restore-work-after-a-host-restart/assets/publication/loop-disabled-after-restart.png +0 -0
- package/static/site_source/content/tutorials/published/restore-work-after-a-host-restart/assets/publication/restart-control.png +0 -0
- package/static/site_source/content/tutorials/published/restore-work-after-a-host-restart/assets/publication/restart-ready-sign-in.png +0 -0
- package/static/site_source/content/tutorials/published/restore-work-after-a-host-restart/assets/publication/restored-checkpoint.png +0 -0
- package/static/site_source/content/tutorials/published/restore-work-after-a-host-restart/assets/publication-screenshots.json +130 -0
- package/static/site_source/content/tutorials/published/restore-work-after-a-host-restart/content.json +23 -0
- package/static/site_source/content/tutorials/published/restore-work-after-a-host-restart/en/article.html +117 -0
- package/static/site_source/content/tutorials/published/restore-work-after-a-host-restart/zh/article.html +117 -0
- package/static/site_source/content/tutorials/published/send-images-and-media/assets/article.css +132 -0
- package/static/site_source/content/tutorials/published/send-images-and-media/assets/publication/safe-image-viewer.jpg +0 -0
- package/static/site_source/content/tutorials/published/send-images-and-media/assets/publication/sent-ordered-group.jpg +0 -0
- package/static/site_source/content/tutorials/published/send-images-and-media/assets/publication/staged-ordered-group.jpg +0 -0
- package/static/site_source/content/tutorials/published/send-images-and-media/assets/publication-screenshots.json +100 -0
- package/static/site_source/content/tutorials/published/send-images-and-media/content.json +23 -0
- package/static/site_source/content/tutorials/published/send-images-and-media/en/article.html +141 -0
- package/static/site_source/content/tutorials/published/send-images-and-media/zh/article.html +141 -0
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/assets/article.css +104 -0
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/assets/publication/host-identity-browse-root.png +0 -0
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/assets/publication/host-setup-managed-ready.png +0 -0
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/assets/publication/host-setup-seven-steps.png +0 -0
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/assets/publication/session-profile-identity.png +0 -0
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/assets/publication/session-setup-identity.png +0 -0
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/assets/publication/website-link.png +0 -0
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/assets/publication-screenshots.json +178 -0
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/content.json +23 -0
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/en/article.html +177 -0
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/zh/article.html +177 -0
- package/static/site_source/content/tutorials/published/understand-agent-activity/assets/article.css +154 -0
- package/static/site_source/content/tutorials/published/understand-agent-activity/assets/publication/session-available.png +0 -0
- package/static/site_source/content/tutorials/published/understand-agent-activity/assets/publication/turn-occupied.png +0 -0
- package/static/site_source/content/tutorials/published/understand-agent-activity/assets/publication/turn-terminal.png +0 -0
- package/static/site_source/content/tutorials/published/understand-agent-activity/assets/publication-screenshots.json +100 -0
- package/static/site_source/content/tutorials/published/understand-agent-activity/content.json +23 -0
- package/static/site_source/content/tutorials/published/understand-agent-activity/en/article.html +114 -0
- package/static/site_source/content/tutorials/published/understand-agent-activity/zh/article.html +114 -0
- package/static/site_source/content/tutorials/published/use-the-oysterun-cli-safely/assets/article.css +138 -0
- package/static/site_source/content/tutorials/published/use-the-oysterun-cli-safely/assets/publication/cli-post-status.jpg +0 -0
- package/static/site_source/content/tutorials/published/use-the-oysterun-cli-safely/assets/publication/cli-protected-dry-run.jpg +0 -0
- package/static/site_source/content/tutorials/published/use-the-oysterun-cli-safely/assets/publication/cli-supported-modules.jpg +0 -0
- package/static/site_source/content/tutorials/published/use-the-oysterun-cli-safely/assets/publication/cli-target-read.jpg +0 -0
- package/static/site_source/content/tutorials/published/use-the-oysterun-cli-safely/assets/publication-screenshots.json +122 -0
- package/static/site_source/content/tutorials/published/use-the-oysterun-cli-safely/content.json +23 -0
- package/static/site_source/content/tutorials/published/use-the-oysterun-cli-safely/en/article.html +170 -0
- package/static/site_source/content/tutorials/published/use-the-oysterun-cli-safely/zh/article.html +170 -0
- package/static/site_source/manifests/docs_taxonomy.json +126 -0
- package/static/site_source/manifests/public_site.json +230 -0
- package/static/site_source/pages/blog/en.html +1 -0
- package/static/site_source/pages/blog/zh.html +1 -0
- package/static/site_source/pages/docs/en.html +1 -0
- package/static/site_source/pages/docs/zh.html +1 -0
- package/static/site_source/pages/faq/en.html +35 -0
- package/static/site_source/pages/faq/zh.html +35 -0
- package/static/site_source/pages/getting-started/en.html +50 -0
- package/static/site_source/pages/getting-started/zh.html +50 -0
- package/static/site_source/pages/home/en.html +19 -0
- package/static/site_source/pages/home/zh.html +19 -0
- package/static/site_source/pages/overview/en.html +6 -0
- package/static/site_source/pages/overview/zh.html +6 -0
- package/static/site_source/pages/privacy/en.html +43 -0
- package/static/site_source/pages/privacy/zh.html +43 -0
- package/static/site_source/shared/home_analytics.html +127 -0
- package/tool_scripts/install_oysterun_launch_agents.sh +57 -0
- package/tool_scripts/install_oysterun_update.mjs +76 -13
- package/tool_scripts/oysterun_npm_package_manifest.mjs +5 -0
- package/tool_scripts/oysterun_release_service.sh +119 -24
- package/tool_scripts/oysterun_service_common.sh +556 -23
- package/tool_scripts/oysterun_update_restart_runner.mjs +440 -17
- package/tool_scripts/preflight_oysterun_restart.sh +45 -0
- package/tool_scripts/restart_oysterun.sh +43 -2
- package/tool_scripts/run_oysterun_host.sh +15 -5
- package/tool_scripts/start_oysterun.sh +15 -5
- package/dev/client/web-chat/dist/assets/index-B0-fm02U.js.map +0 -1
- package/dev/client/web-chat/dist/assets/index-BIJqUapL.js.map +0 -1
- package/dev/client/web-chat/dist/assets/pdf-Dx9dlfRj.js.map +0 -1
- package/static/site/content/blog/drafts/20260718-24hr-agent-team/assets/article.css +0 -31
- package/static/site/content/blog/drafts/20260718-24hr-agent-team/assets/cover.svg +0 -24
- package/static/site/content/blog/drafts/20260718-24hr-agent-team/zh/index.html +0 -224
- package/static/site/content/blog/drafts/generated_manifest.json +0 -37
- package/static/site/content/tutorials/drafts/generated_manifest.json +0 -49
- package/static/site/content/tutorials/drafts/getting-started/assets/AppStore.png +0 -0
- package/static/site/content/tutorials/drafts/getting-started/assets/article.css +0 -31
- package/static/site/content/tutorials/drafts/getting-started/assets/chat.png +0 -0
- package/static/site/content/tutorials/drafts/getting-started/assets/cover.svg +0 -24
- package/static/site/content/tutorials/drafts/getting-started/en/index.html +0 -360
- package/static/site/tutorial/generated_manifest.json +0 -13
- package/static/site/tutorial/index.html +0 -54
package/bin/oysterun.mjs
CHANGED
|
@@ -29,6 +29,11 @@ const serviceCommands = new Map([
|
|
|
29
29
|
["service:start", "start"],
|
|
30
30
|
["service:stop", "stop"],
|
|
31
31
|
["service:restart", "restart"],
|
|
32
|
+
["service:update", "update"],
|
|
33
|
+
["service:complete-update", "complete-update"],
|
|
34
|
+
["service:repair", "repair"],
|
|
35
|
+
["service:restore", "restore"],
|
|
36
|
+
["service:lifecycle-status", "lifecycle-status"],
|
|
32
37
|
["service:status", "status"],
|
|
33
38
|
["service:logs", "logs"],
|
|
34
39
|
["service:uninstall", "uninstall"],
|
|
@@ -55,7 +60,21 @@ function runSetup(args = []) {
|
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
function runService(command, args = []) {
|
|
58
|
-
|
|
63
|
+
const result = spawnSync(releaseServiceScript, [command, ...args], {
|
|
64
|
+
cwd: repoRoot,
|
|
65
|
+
env: {
|
|
66
|
+
...process.env,
|
|
67
|
+
OYSTERUN_BOOTSTRAP_NODE_BIN: process.execPath,
|
|
68
|
+
},
|
|
69
|
+
stdio: "inherit",
|
|
70
|
+
});
|
|
71
|
+
if (result.error) {
|
|
72
|
+
console.error(
|
|
73
|
+
`oysterun: failed to run ${releaseServiceScript}: ${result.error.message}`
|
|
74
|
+
);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
process.exit(result.status ?? 0);
|
|
59
78
|
}
|
|
60
79
|
|
|
61
80
|
function parseUninstallArgs(args = []) {
|
|
@@ -181,6 +200,11 @@ Usage:
|
|
|
181
200
|
oysterun service:start
|
|
182
201
|
oysterun service:stop
|
|
183
202
|
oysterun service:restart [--restore-sessions]
|
|
203
|
+
oysterun service:update --channel latest|beta
|
|
204
|
+
oysterun service:complete-update
|
|
205
|
+
oysterun service:repair
|
|
206
|
+
oysterun service:restore
|
|
207
|
+
oysterun service:lifecycle-status
|
|
184
208
|
oysterun service:status
|
|
185
209
|
oysterun service:logs [--follow]
|
|
186
210
|
oysterun service:uninstall [--stack production|staging|all]
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
export type InternalConnectivityStatus = {
|
|
2
2
|
matrix: "Connected" | "Reconnecting" | "Error" | "Offline";
|
|
3
|
-
activePath:
|
|
3
|
+
activePath:
|
|
4
|
+
| "WebRTC"
|
|
5
|
+
| "WebRTC (LAN)"
|
|
6
|
+
| "WebRTC (STUN Direct)"
|
|
7
|
+
| "WebRTC (TURN)"
|
|
8
|
+
| "WebRTC (IPv6 Direct)"
|
|
9
|
+
| "Bootstrap"
|
|
10
|
+
| "Direct"
|
|
11
|
+
| "None";
|
|
4
12
|
promotion: "Idle" | `Attempt ${number}/4` | "Quiesced" | "Not applicable";
|
|
5
13
|
};
|
|
6
14
|
|
|
@@ -10,5 +18,5 @@ export function deriveInternalConnectivityStatus(input?: {
|
|
|
10
18
|
transportStatus?: Record<string, unknown>;
|
|
11
19
|
}): InternalConnectivityStatus;
|
|
12
20
|
export function internalConnectivityStatusText(
|
|
13
|
-
status: InternalConnectivityStatus
|
|
21
|
+
status: InternalConnectivityStatus
|
|
14
22
|
): string;
|
|
@@ -13,6 +13,14 @@ const ACTIVE_PATH_STATUS = Object.freeze({
|
|
|
13
13
|
direct_host: "Direct",
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
+
const WEBRTC_SELECTED_PATH_STATUS = Object.freeze({
|
|
17
|
+
lan: "WebRTC (LAN)",
|
|
18
|
+
stun_direct: "WebRTC (STUN Direct)",
|
|
19
|
+
turn_udp: "WebRTC (TURN)",
|
|
20
|
+
turn_tcp_tls: "WebRTC (TURN)",
|
|
21
|
+
ipv6: "WebRTC (IPv6 Direct)",
|
|
22
|
+
});
|
|
23
|
+
|
|
16
24
|
export const INTERNAL_CONNECTIVITY_PROMOTION_ATTEMPT_LIMIT = 4;
|
|
17
25
|
|
|
18
26
|
function finiteNonNegativeInteger(value) {
|
|
@@ -32,23 +40,26 @@ export function deriveInternalConnectivityStatus({
|
|
|
32
40
|
transportConnectionState === "disconnected"
|
|
33
41
|
? "Reconnecting"
|
|
34
42
|
: transportConnectionState === "connected"
|
|
35
|
-
|
|
36
|
-
|
|
43
|
+
? "Connected"
|
|
44
|
+
: "Offline");
|
|
37
45
|
const activePath =
|
|
38
|
-
|
|
46
|
+
transportStatus.active_path_kind === "webrtc"
|
|
47
|
+
? WEBRTC_SELECTED_PATH_STATUS[transportStatus.webrtc_selected_path] ||
|
|
48
|
+
ACTIVE_PATH_STATUS.webrtc
|
|
49
|
+
: ACTIVE_PATH_STATUS[transportStatus.active_path_kind] || "None";
|
|
39
50
|
|
|
40
51
|
let promotion = "Not applicable";
|
|
41
52
|
if (transportStatus.managed_transport_enabled === true) {
|
|
42
53
|
const attempt = Math.min(
|
|
43
54
|
finiteNonNegativeInteger(transportStatus.promotion_attempt_count),
|
|
44
|
-
INTERNAL_CONNECTIVITY_PROMOTION_ATTEMPT_LIMIT
|
|
55
|
+
INTERNAL_CONNECTIVITY_PROMOTION_ATTEMPT_LIMIT
|
|
45
56
|
);
|
|
46
57
|
promotion =
|
|
47
58
|
transportStatus.retry_quiesced === true
|
|
48
59
|
? "Quiesced"
|
|
49
60
|
: attempt > 0
|
|
50
|
-
|
|
51
|
-
|
|
61
|
+
? `Attempt ${attempt}/${INTERNAL_CONNECTIVITY_PROMOTION_ATTEMPT_LIMIT}`
|
|
62
|
+
: "Idle";
|
|
52
63
|
}
|
|
53
64
|
|
|
54
65
|
return Object.freeze({ matrix, activePath, promotion });
|
|
@@ -5,7 +5,8 @@ export class ManagedHostBrowserConnection {
|
|
|
5
5
|
close(): Promise<void>;
|
|
6
6
|
setTicketProvider(ticketProvider: ManagedHostTicketProvider | null): void;
|
|
7
7
|
subscribeStatus(
|
|
8
|
-
listener: (status: Record<string, unknown>) => void
|
|
8
|
+
listener: (status: Record<string, unknown>) => void,
|
|
9
|
+
options?: { includeSelectedWebRtcPath?: boolean }
|
|
9
10
|
): () => void;
|
|
10
11
|
}
|
|
11
12
|
|
|
@@ -15,7 +16,8 @@ export class DirectHostBrowserConnection {
|
|
|
15
16
|
status(): Record<string, unknown>;
|
|
16
17
|
close(): Promise<void>;
|
|
17
18
|
subscribeStatus(
|
|
18
|
-
listener: (status: Record<string, unknown>) => void
|
|
19
|
+
listener: (status: Record<string, unknown>) => void,
|
|
20
|
+
options?: { includeSelectedWebRtcPath?: boolean }
|
|
19
21
|
): () => void;
|
|
20
22
|
}
|
|
21
23
|
|
|
@@ -32,6 +34,19 @@ export function classifyManagedHostBrowserOrigin(value?: string | URL): {
|
|
|
32
34
|
kind: "managed_endpoint" | "direct_host";
|
|
33
35
|
managed_transport_enabled: boolean;
|
|
34
36
|
};
|
|
37
|
+
export type ManagedWebRtcSelectedPath =
|
|
38
|
+
| "lan"
|
|
39
|
+
| "stun_direct"
|
|
40
|
+
| "turn_udp"
|
|
41
|
+
| "turn_tcp_tls"
|
|
42
|
+
| "ipv6";
|
|
43
|
+
export function normalizeManagedWebRtcSelectedPath(
|
|
44
|
+
value: unknown
|
|
45
|
+
): ManagedWebRtcSelectedPath | null;
|
|
46
|
+
export function readManagedWebRtcSelectedPath(
|
|
47
|
+
hostStatus: unknown,
|
|
48
|
+
connectionId: string
|
|
49
|
+
): ManagedWebRtcSelectedPath | null;
|
|
35
50
|
export function getManagedHostBrowserConnection():
|
|
36
51
|
| ManagedHostBrowserConnection
|
|
37
52
|
| DirectHostBrowserConnection;
|
|
@@ -66,5 +81,6 @@ export function managedMediaObjectUrl(
|
|
|
66
81
|
export function waitForManagedHostAvailability(): Promise<boolean>;
|
|
67
82
|
export function getManagedHostConnectionStatus(): Record<string, unknown>;
|
|
68
83
|
export function subscribeManagedHostConnectionStatus(
|
|
69
|
-
listener: (status: Record<string, unknown>) => void
|
|
84
|
+
listener: (status: Record<string, unknown>) => void,
|
|
85
|
+
options?: { includeSelectedWebRtcPath?: boolean }
|
|
70
86
|
): () => void;
|
|
@@ -11,6 +11,7 @@ const REQUIRED_CHANNELS = Object.freeze(["control", "events", "bulk"]);
|
|
|
11
11
|
const SUPPORTED_TRANSPORT_PROTOCOL_VERSIONS = Object.freeze([1]);
|
|
12
12
|
const MANAGED_TRANSPORT_CONTRACT = "oysterun.managed_webrtc.v1";
|
|
13
13
|
const SIGNALING_TIMEOUT_MS = 20_000;
|
|
14
|
+
const MANAGED_ICE_CANDIDATE_SETTLE_MS = 100;
|
|
14
15
|
const BOOTSTRAP_SAFE_REQUEST_TIMEOUT_MS = 12_000;
|
|
15
16
|
const BOOTSTRAP_MATRIX_SYNC_TIMEOUT_MS = 45_000;
|
|
16
17
|
const PRESENCE_WAIT_SECONDS = 55;
|
|
@@ -30,6 +31,13 @@ const HOST_UNAVAILABLE_RESPONSE_ERROR =
|
|
|
30
31
|
const BULK_REQUEST_TIMEOUT_MS = 120_000;
|
|
31
32
|
const MATRIX_SYNC_PATH = /^\/_matrix\/client\/[^/]+\/sync(?:\?|$)/;
|
|
32
33
|
const SIGNALING_PATH_PREFIX = "/connectivity/webrtc/";
|
|
34
|
+
const MANAGED_WEBRTC_SELECTED_PATHS = new Set([
|
|
35
|
+
"lan",
|
|
36
|
+
"stun_direct",
|
|
37
|
+
"turn_udp",
|
|
38
|
+
"turn_tcp_tls",
|
|
39
|
+
"ipv6",
|
|
40
|
+
]);
|
|
33
41
|
const MANAGED_ENDPOINT_HOSTNAME = /^h-([a-z2-7]{16})\.tunnel\.oysterun\.com$/i;
|
|
34
42
|
const SESSION_SNAPSHOT_PATH = /^\/session\/snapshot(?:\?|$)/;
|
|
35
43
|
const TRANSPORT_PATH_KINDS = Object.freeze([
|
|
@@ -354,6 +362,7 @@ function browserConnectionStatusKey(status) {
|
|
|
354
362
|
status.last_request_failed,
|
|
355
363
|
status.browser_online,
|
|
356
364
|
status.active_path_kind,
|
|
365
|
+
status.webrtc_selected_path,
|
|
357
366
|
status.transition_state,
|
|
358
367
|
status.transition_generation,
|
|
359
368
|
status.browser_peer_state,
|
|
@@ -368,6 +377,30 @@ function browserConnectionStatusKey(status) {
|
|
|
368
377
|
]);
|
|
369
378
|
}
|
|
370
379
|
|
|
380
|
+
export function normalizeManagedWebRtcSelectedPath(value) {
|
|
381
|
+
return MANAGED_WEBRTC_SELECTED_PATHS.has(value) ? value : null;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
export function readManagedWebRtcSelectedPath(hostStatus, connectionId) {
|
|
385
|
+
if (
|
|
386
|
+
!hostStatus ||
|
|
387
|
+
typeof hostStatus !== "object" ||
|
|
388
|
+
!Array.isArray(hostStatus.peers) ||
|
|
389
|
+
typeof connectionId !== "string" ||
|
|
390
|
+
!connectionId
|
|
391
|
+
) {
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
const matchingPeers = hostStatus.peers.filter(
|
|
395
|
+
(peer) =>
|
|
396
|
+
peer &&
|
|
397
|
+
typeof peer === "object" &&
|
|
398
|
+
peer.connection_id === connectionId
|
|
399
|
+
);
|
|
400
|
+
if (matchingPeers.length !== 1) return null;
|
|
401
|
+
return normalizeManagedWebRtcSelectedPath(matchingPeers[0].selected_path);
|
|
402
|
+
}
|
|
403
|
+
|
|
371
404
|
function managedHostUnavailableError() {
|
|
372
405
|
const error = new Error(
|
|
373
406
|
"Managed Oysterun Host is unavailable; the request was not sent"
|
|
@@ -521,20 +554,161 @@ function fingerprintFromSdp(sdp) {
|
|
|
521
554
|
return compact;
|
|
522
555
|
}
|
|
523
556
|
|
|
524
|
-
function
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
557
|
+
function managedWebRtcAttemptError(code, message) {
|
|
558
|
+
const error = new Error(message);
|
|
559
|
+
error.code = code;
|
|
560
|
+
return error;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
function signalingCandidateToJson(candidate) {
|
|
564
|
+
if (
|
|
565
|
+
!candidate ||
|
|
566
|
+
typeof candidate.candidate !== "string" ||
|
|
567
|
+
!candidate.candidate.trim()
|
|
568
|
+
) {
|
|
569
|
+
return null;
|
|
570
|
+
}
|
|
571
|
+
return candidateToJson(candidate);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
function createManagedIceCandidateReadiness(
|
|
575
|
+
peer,
|
|
576
|
+
{
|
|
577
|
+
assertCurrentAttempt,
|
|
578
|
+
settleMs = MANAGED_ICE_CANDIDATE_SETTLE_MS,
|
|
579
|
+
timeoutMs = SIGNALING_TIMEOUT_MS,
|
|
580
|
+
} = {}
|
|
581
|
+
) {
|
|
582
|
+
if (typeof assertCurrentAttempt !== "function") {
|
|
583
|
+
throw new Error("Managed ICE readiness requires an attempt owner");
|
|
584
|
+
}
|
|
585
|
+
const candidates = [];
|
|
586
|
+
const readiness = deferred();
|
|
587
|
+
let waitStarted = false;
|
|
588
|
+
let settled = false;
|
|
589
|
+
let settleTimer = null;
|
|
590
|
+
let timeoutTimer = null;
|
|
591
|
+
|
|
592
|
+
// A candidate or peer-close callback can reject between setLocalDescription
|
|
593
|
+
// and wait(). Keep that attempt-owned rejection observed until the caller
|
|
594
|
+
// reaches the browser_ice_gathering stage.
|
|
595
|
+
void readiness.promise.catch(() => {});
|
|
596
|
+
|
|
597
|
+
const cleanup = () => {
|
|
598
|
+
if (settleTimer !== null) {
|
|
599
|
+
clearTimeout(settleTimer);
|
|
600
|
+
settleTimer = null;
|
|
601
|
+
}
|
|
602
|
+
if (timeoutTimer !== null) {
|
|
603
|
+
clearTimeout(timeoutTimer);
|
|
604
|
+
timeoutTimer = null;
|
|
605
|
+
}
|
|
606
|
+
peer.removeEventListener("icecandidate", handleCandidate);
|
|
607
|
+
peer.removeEventListener("icegatheringstatechange", handleGatheringChange);
|
|
608
|
+
peer.removeEventListener("connectionstatechange", handleConnectionChange);
|
|
609
|
+
};
|
|
610
|
+
const reject = (error) => {
|
|
611
|
+
if (settled) return false;
|
|
612
|
+
settled = true;
|
|
613
|
+
cleanup();
|
|
614
|
+
readiness.reject(error);
|
|
615
|
+
return true;
|
|
616
|
+
};
|
|
617
|
+
const resolve = () => {
|
|
618
|
+
if (settled) return false;
|
|
619
|
+
try {
|
|
620
|
+
assertCurrentAttempt(peer);
|
|
621
|
+
} catch (error) {
|
|
622
|
+
return reject(error);
|
|
623
|
+
}
|
|
624
|
+
if (candidates.length === 0) return false;
|
|
625
|
+
settled = true;
|
|
626
|
+
cleanup();
|
|
627
|
+
readiness.resolve(candidates);
|
|
628
|
+
return true;
|
|
629
|
+
};
|
|
630
|
+
const startSettle = () => {
|
|
631
|
+
if (settled || settleTimer !== null) return;
|
|
632
|
+
settleTimer = setTimeout(resolve, settleMs);
|
|
633
|
+
};
|
|
634
|
+
function handleCandidate(event) {
|
|
635
|
+
if (settled) return;
|
|
636
|
+
try {
|
|
637
|
+
assertCurrentAttempt(peer);
|
|
638
|
+
} catch (error) {
|
|
639
|
+
reject(error);
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
const candidate = signalingCandidateToJson(event.candidate);
|
|
643
|
+
if (!candidate) return;
|
|
644
|
+
candidates.push(candidate);
|
|
645
|
+
if (peer.iceGatheringState === "complete") {
|
|
646
|
+
resolve();
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
startSettle();
|
|
650
|
+
}
|
|
651
|
+
function handleGatheringChange() {
|
|
652
|
+
if (settled || peer.iceGatheringState !== "complete") return;
|
|
653
|
+
resolve();
|
|
654
|
+
}
|
|
655
|
+
function handleConnectionChange() {
|
|
656
|
+
if (settled || peer.connectionState !== "closed") return;
|
|
657
|
+
reject(
|
|
658
|
+
managedWebRtcAttemptError(
|
|
659
|
+
"managed_webrtc_attempt_cancelled",
|
|
660
|
+
"Managed WebRTC connect attempt was cancelled"
|
|
661
|
+
)
|
|
662
|
+
);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
peer.addEventListener("icecandidate", handleCandidate);
|
|
666
|
+
peer.addEventListener("icegatheringstatechange", handleGatheringChange);
|
|
667
|
+
peer.addEventListener("connectionstatechange", handleConnectionChange);
|
|
668
|
+
|
|
669
|
+
return {
|
|
670
|
+
peer,
|
|
671
|
+
candidates,
|
|
672
|
+
wait() {
|
|
673
|
+
if (!waitStarted) {
|
|
674
|
+
waitStarted = true;
|
|
675
|
+
try {
|
|
676
|
+
assertCurrentAttempt(peer);
|
|
677
|
+
} catch (error) {
|
|
678
|
+
reject(error);
|
|
679
|
+
return readiness.promise;
|
|
680
|
+
}
|
|
681
|
+
if (peer.iceGatheringState === "complete" && candidates.length > 0) {
|
|
682
|
+
resolve();
|
|
683
|
+
} else if (!settled) {
|
|
684
|
+
timeoutTimer = setTimeout(
|
|
685
|
+
() =>
|
|
686
|
+
reject(
|
|
687
|
+
new Error("Browser ICE candidate gathering timed out")
|
|
688
|
+
),
|
|
689
|
+
timeoutMs
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return readiness.promise;
|
|
694
|
+
},
|
|
695
|
+
cancel(error) {
|
|
696
|
+
reject(
|
|
697
|
+
error ||
|
|
698
|
+
managedWebRtcAttemptError(
|
|
699
|
+
"managed_webrtc_attempt_cancelled",
|
|
700
|
+
"Managed WebRTC connect attempt was cancelled"
|
|
701
|
+
)
|
|
702
|
+
);
|
|
703
|
+
},
|
|
704
|
+
dispose() {
|
|
705
|
+
if (!settled) {
|
|
706
|
+
this.cancel();
|
|
707
|
+
} else {
|
|
708
|
+
cleanup();
|
|
709
|
+
}
|
|
710
|
+
},
|
|
711
|
+
};
|
|
538
712
|
}
|
|
539
713
|
|
|
540
714
|
function waitForPeerReady(peer, channels) {
|
|
@@ -939,6 +1113,7 @@ export class ManagedHostBrowserConnection {
|
|
|
939
1113
|
});
|
|
940
1114
|
this.peer = null;
|
|
941
1115
|
this.connectingPeer = null;
|
|
1116
|
+
this.pendingIceCandidateReadiness = null;
|
|
942
1117
|
this.webRtcTransport = null;
|
|
943
1118
|
this.activeConnection = null;
|
|
944
1119
|
this.iceTransportPolicy = "all";
|
|
@@ -962,7 +1137,12 @@ export class ManagedHostBrowserConnection {
|
|
|
962
1137
|
this.immediateRecoveryPromise = null;
|
|
963
1138
|
this.presenceAbortControllers = new Set();
|
|
964
1139
|
this.statusListeners = new Set();
|
|
1140
|
+
this.selectedPathStatusListeners = new Set();
|
|
965
1141
|
this.lastNotifiedStatusKey = "";
|
|
1142
|
+
this.webrtcSelectedPath = null;
|
|
1143
|
+
this.webrtcSelectedPathConnectionId = null;
|
|
1144
|
+
this.selectedPathStatusReadConnectionId = null;
|
|
1145
|
+
this.selectedPathStatusReadPromise = null;
|
|
966
1146
|
this.lastRequestFailed = false;
|
|
967
1147
|
this.accounting = createTransportAccounting();
|
|
968
1148
|
this.reconciliationOwner = new EpochBoundTransportReconciliationOwner({
|
|
@@ -994,16 +1174,29 @@ export class ManagedHostBrowserConnection {
|
|
|
994
1174
|
this.ticketProvider = ticketProvider;
|
|
995
1175
|
}
|
|
996
1176
|
|
|
997
|
-
subscribeStatus(listener) {
|
|
1177
|
+
subscribeStatus(listener, { includeSelectedWebRtcPath = false } = {}) {
|
|
998
1178
|
if (typeof listener !== "function") {
|
|
999
1179
|
throw new Error("Managed Host status listener must be a function");
|
|
1000
1180
|
}
|
|
1001
1181
|
this.statusListeners.add(listener);
|
|
1182
|
+
if (includeSelectedWebRtcPath === true) {
|
|
1183
|
+
this.selectedPathStatusListeners.add(listener);
|
|
1184
|
+
}
|
|
1002
1185
|
const status = this.status();
|
|
1003
1186
|
this.lastNotifiedStatusKey = browserConnectionStatusKey(status);
|
|
1004
1187
|
listener(status);
|
|
1188
|
+
if (
|
|
1189
|
+
includeSelectedWebRtcPath === true &&
|
|
1190
|
+
status.active_path_kind === "webrtc" &&
|
|
1191
|
+
this.activeConnection?.connectionId
|
|
1192
|
+
) {
|
|
1193
|
+
void this.refreshSelectedWebRtcPath(
|
|
1194
|
+
this.activeConnection.connectionId
|
|
1195
|
+
);
|
|
1196
|
+
}
|
|
1005
1197
|
return () => {
|
|
1006
1198
|
this.statusListeners.delete(listener);
|
|
1199
|
+
this.selectedPathStatusListeners.delete(listener);
|
|
1007
1200
|
};
|
|
1008
1201
|
}
|
|
1009
1202
|
|
|
@@ -1109,6 +1302,70 @@ export class ManagedHostBrowserConnection {
|
|
|
1109
1302
|
return data;
|
|
1110
1303
|
}
|
|
1111
1304
|
|
|
1305
|
+
refreshSelectedWebRtcPath(connectionId) {
|
|
1306
|
+
if (
|
|
1307
|
+
this.selectedPathStatusListeners.size === 0 ||
|
|
1308
|
+
typeof connectionId !== "string" ||
|
|
1309
|
+
!connectionId ||
|
|
1310
|
+
this.activeConnection?.connectionId !== connectionId ||
|
|
1311
|
+
this.logicalConnection.status().active_path_kind !== "webrtc"
|
|
1312
|
+
) {
|
|
1313
|
+
return Promise.resolve(null);
|
|
1314
|
+
}
|
|
1315
|
+
if (this.selectedPathStatusReadConnectionId === connectionId) {
|
|
1316
|
+
return (
|
|
1317
|
+
this.selectedPathStatusReadPromise ||
|
|
1318
|
+
Promise.resolve(this.webrtcSelectedPath)
|
|
1319
|
+
);
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
this.selectedPathStatusReadConnectionId = connectionId;
|
|
1323
|
+
this.webrtcSelectedPath = null;
|
|
1324
|
+
this.webrtcSelectedPathConnectionId = connectionId;
|
|
1325
|
+
const readPromise = this.nativeJson(SIGNALING_PATH_PREFIX + "status", {})
|
|
1326
|
+
.then((hostStatus) => {
|
|
1327
|
+
const selectedPath = readManagedWebRtcSelectedPath(
|
|
1328
|
+
hostStatus,
|
|
1329
|
+
connectionId
|
|
1330
|
+
);
|
|
1331
|
+
if (
|
|
1332
|
+
this.selectedPathStatusListeners.size === 0 ||
|
|
1333
|
+
this.activeConnection?.connectionId !== connectionId ||
|
|
1334
|
+
this.logicalConnection.status().active_path_kind !== "webrtc"
|
|
1335
|
+
) {
|
|
1336
|
+
return null;
|
|
1337
|
+
}
|
|
1338
|
+
this.webrtcSelectedPath = selectedPath;
|
|
1339
|
+
this.webrtcSelectedPathConnectionId = connectionId;
|
|
1340
|
+
this.emitDiagnostic({
|
|
1341
|
+
event_type: "managed_webrtc_selected_path_resolved",
|
|
1342
|
+
selected_path: selectedPath || "unknown",
|
|
1343
|
+
});
|
|
1344
|
+
this.notifyStatusListeners();
|
|
1345
|
+
return selectedPath;
|
|
1346
|
+
})
|
|
1347
|
+
.catch((error) => {
|
|
1348
|
+
if (
|
|
1349
|
+
this.activeConnection?.connectionId === connectionId &&
|
|
1350
|
+
this.logicalConnection.status().active_path_kind === "webrtc"
|
|
1351
|
+
) {
|
|
1352
|
+
this.emitDiagnostic({
|
|
1353
|
+
event_type: "managed_webrtc_selected_path_status_failed",
|
|
1354
|
+
error_code:
|
|
1355
|
+
error?.code || "managed_webrtc_selected_path_status_failed",
|
|
1356
|
+
});
|
|
1357
|
+
}
|
|
1358
|
+
return null;
|
|
1359
|
+
})
|
|
1360
|
+
.finally(() => {
|
|
1361
|
+
if (this.selectedPathStatusReadPromise === readPromise) {
|
|
1362
|
+
this.selectedPathStatusReadPromise = null;
|
|
1363
|
+
}
|
|
1364
|
+
});
|
|
1365
|
+
this.selectedPathStatusReadPromise = readPromise;
|
|
1366
|
+
return readPromise;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1112
1369
|
ensureSyncOwner() {
|
|
1113
1370
|
if (this.syncOwnerId) return this.syncOwnerId;
|
|
1114
1371
|
this.syncOwnerId = "routec-matrix-client";
|
|
@@ -1196,6 +1453,15 @@ export class ManagedHostBrowserConnection {
|
|
|
1196
1453
|
reconciliationEpoch = this.reconciliationOwner.status().epoch,
|
|
1197
1454
|
lifecycleReason = "initial_start",
|
|
1198
1455
|
} = {}) {
|
|
1456
|
+
if (this.pendingIceCandidateReadiness) {
|
|
1457
|
+
this.pendingIceCandidateReadiness.cancel(
|
|
1458
|
+
managedWebRtcAttemptError(
|
|
1459
|
+
"managed_webrtc_stale_connect_attempt",
|
|
1460
|
+
"Managed WebRTC connect attempt was replaced"
|
|
1461
|
+
)
|
|
1462
|
+
);
|
|
1463
|
+
this.pendingIceCandidateReadiness = null;
|
|
1464
|
+
}
|
|
1199
1465
|
const connectionGeneration = ++this.connectionGeneration;
|
|
1200
1466
|
const connectionAttemptId = createConnectivityRandomId();
|
|
1201
1467
|
const attempt = {
|
|
@@ -1250,6 +1516,7 @@ export class ManagedHostBrowserConnection {
|
|
|
1250
1516
|
iceTransportPolicy,
|
|
1251
1517
|
});
|
|
1252
1518
|
this.connectingPeer = peer;
|
|
1519
|
+
let iceCandidateReadiness = null;
|
|
1253
1520
|
try {
|
|
1254
1521
|
const channels = Object.fromEntries(
|
|
1255
1522
|
REQUIRED_CHANNELS.map((name) => [
|
|
@@ -1260,19 +1527,20 @@ export class ManagedHostBrowserConnection {
|
|
|
1260
1527
|
for (const channel of Object.values(channels)) {
|
|
1261
1528
|
channel.binaryType = "arraybuffer";
|
|
1262
1529
|
}
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
if (event.candidate) {
|
|
1266
|
-
localCandidates.push(candidateToJson(event.candidate));
|
|
1267
|
-
}
|
|
1530
|
+
iceCandidateReadiness = createManagedIceCandidateReadiness(peer, {
|
|
1531
|
+
assertCurrentAttempt,
|
|
1268
1532
|
});
|
|
1533
|
+
this.pendingIceCandidateReadiness = iceCandidateReadiness;
|
|
1269
1534
|
await this.runConnectionStage("browser_offer", attempt, async () => {
|
|
1270
1535
|
const offer = await peer.createOffer();
|
|
1271
1536
|
await peer.setLocalDescription(offer);
|
|
1272
1537
|
});
|
|
1273
1538
|
await this.runConnectionStage("browser_ice_gathering", attempt, () =>
|
|
1274
|
-
|
|
1539
|
+
iceCandidateReadiness.wait()
|
|
1275
1540
|
);
|
|
1541
|
+
if (this.pendingIceCandidateReadiness === iceCandidateReadiness) {
|
|
1542
|
+
this.pendingIceCandidateReadiness = null;
|
|
1543
|
+
}
|
|
1276
1544
|
assertCurrentAttempt(peer);
|
|
1277
1545
|
const localDescription = peer.localDescription;
|
|
1278
1546
|
if (!localDescription) {
|
|
@@ -1301,6 +1569,7 @@ export class ManagedHostBrowserConnection {
|
|
|
1301
1569
|
client_authority_kind: "host_owner_browser",
|
|
1302
1570
|
}
|
|
1303
1571
|
);
|
|
1572
|
+
assertCurrentAttempt(peer);
|
|
1304
1573
|
if (
|
|
1305
1574
|
!ticket ||
|
|
1306
1575
|
typeof ticket.credential !== "string" ||
|
|
@@ -1325,7 +1594,7 @@ export class ManagedHostBrowserConnection {
|
|
|
1325
1594
|
type: localDescription.type,
|
|
1326
1595
|
sdp: localDescription.sdp,
|
|
1327
1596
|
},
|
|
1328
|
-
candidates:
|
|
1597
|
+
candidates: iceCandidateReadiness.candidates,
|
|
1329
1598
|
})
|
|
1330
1599
|
);
|
|
1331
1600
|
assertCurrentAttempt(peer);
|
|
@@ -1385,6 +1654,12 @@ export class ManagedHostBrowserConnection {
|
|
|
1385
1654
|
);
|
|
1386
1655
|
assertCurrentAttempt(peer);
|
|
1387
1656
|
this.lastRequestFailed = false;
|
|
1657
|
+
this.webrtcSelectedPath = null;
|
|
1658
|
+
this.webrtcSelectedPathConnectionId = answer.connection_id;
|
|
1659
|
+
this.notifyStatusListeners();
|
|
1660
|
+
if (this.selectedPathStatusListeners.size > 0) {
|
|
1661
|
+
void this.refreshSelectedWebRtcPath(answer.connection_id);
|
|
1662
|
+
}
|
|
1388
1663
|
this.emitDiagnostic({
|
|
1389
1664
|
event_type: "managed_webrtc_connected",
|
|
1390
1665
|
connection_id: answer.connection_id,
|
|
@@ -1397,6 +1672,11 @@ export class ManagedHostBrowserConnection {
|
|
|
1397
1672
|
if (this.connectingPeer === peer) this.connectingPeer = null;
|
|
1398
1673
|
peer.close();
|
|
1399
1674
|
throw error;
|
|
1675
|
+
} finally {
|
|
1676
|
+
if (this.pendingIceCandidateReadiness === iceCandidateReadiness) {
|
|
1677
|
+
this.pendingIceCandidateReadiness = null;
|
|
1678
|
+
}
|
|
1679
|
+
iceCandidateReadiness?.dispose();
|
|
1400
1680
|
}
|
|
1401
1681
|
}
|
|
1402
1682
|
|
|
@@ -1530,6 +1810,15 @@ export class ManagedHostBrowserConnection {
|
|
|
1530
1810
|
this.connectionGeneration += 1;
|
|
1531
1811
|
const connectingPeer = this.connectingPeer;
|
|
1532
1812
|
this.connectingPeer = null;
|
|
1813
|
+
if (this.pendingIceCandidateReadiness?.peer === connectingPeer) {
|
|
1814
|
+
this.pendingIceCandidateReadiness.cancel(
|
|
1815
|
+
managedWebRtcAttemptError(
|
|
1816
|
+
"managed_webrtc_stale_connect_attempt",
|
|
1817
|
+
"Managed WebRTC connect attempt was replaced"
|
|
1818
|
+
)
|
|
1819
|
+
);
|
|
1820
|
+
this.pendingIceCandidateReadiness = null;
|
|
1821
|
+
}
|
|
1533
1822
|
connectingPeer?.close();
|
|
1534
1823
|
const peer = this.peer;
|
|
1535
1824
|
const connection = this.activeConnection;
|
|
@@ -1537,6 +1826,9 @@ export class ManagedHostBrowserConnection {
|
|
|
1537
1826
|
this.peer = null;
|
|
1538
1827
|
this.webRtcTransport = null;
|
|
1539
1828
|
this.activeConnection = null;
|
|
1829
|
+
this.webrtcSelectedPath = null;
|
|
1830
|
+
this.webrtcSelectedPathConnectionId = null;
|
|
1831
|
+
this.selectedPathStatusReadConnectionId = null;
|
|
1540
1832
|
if (this.logicalConnection.status().active_path_kind === "webrtc") {
|
|
1541
1833
|
await this.logicalConnection.activateBootstrap({ reason });
|
|
1542
1834
|
this.emitDiagnostic({
|
|
@@ -2191,6 +2483,12 @@ export class ManagedHostBrowserConnection {
|
|
|
2191
2483
|
relay_only_debug_enabled: this.iceTransportPolicy === "relay",
|
|
2192
2484
|
connection_id: this.activeConnection?.connectionId || null,
|
|
2193
2485
|
connection_attempt_id: this.activeConnection?.connectionAttemptId || null,
|
|
2486
|
+
webrtc_selected_path:
|
|
2487
|
+
logicalStatus.active_path_kind === "webrtc" &&
|
|
2488
|
+
this.webrtcSelectedPathConnectionId ===
|
|
2489
|
+
this.activeConnection?.connectionId
|
|
2490
|
+
? this.webrtcSelectedPath
|
|
2491
|
+
: null,
|
|
2194
2492
|
page_visibility_state: document.visibilityState,
|
|
2195
2493
|
browser_online: browserOnline,
|
|
2196
2494
|
retry_count: this.retryCount,
|
|
@@ -2234,6 +2532,7 @@ export class ManagedHostBrowserConnection {
|
|
|
2234
2532
|
await this.closePeer("browser_connection_closed");
|
|
2235
2533
|
this.routeUnavailable = false;
|
|
2236
2534
|
this.statusListeners.clear();
|
|
2535
|
+
this.selectedPathStatusListeners.clear();
|
|
2237
2536
|
this.abortPresenceRequests();
|
|
2238
2537
|
this.presenceRecovery?.resolve();
|
|
2239
2538
|
this.presenceRecovery = null;
|
|
@@ -2345,10 +2644,10 @@ export function getManagedHostConnectionStatus() {
|
|
|
2345
2644
|
return getManagedHostBrowserConnection().status();
|
|
2346
2645
|
}
|
|
2347
2646
|
|
|
2348
|
-
export function subscribeManagedHostConnectionStatus(listener) {
|
|
2647
|
+
export function subscribeManagedHostConnectionStatus(listener, options = {}) {
|
|
2349
2648
|
const connection = getManagedHostBrowserConnection();
|
|
2350
2649
|
if (typeof connection.subscribeStatus === "function") {
|
|
2351
|
-
return connection.subscribeStatus(listener);
|
|
2650
|
+
return connection.subscribeStatus(listener, options);
|
|
2352
2651
|
}
|
|
2353
2652
|
listener(connection.status());
|
|
2354
2653
|
return () => {};
|