oysterun 1.6.0-beta.21 → 1.6.0-beta.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -7
- package/bin/oysterun.mjs +25 -22
- package/dev/client/connectivity/host-connection-feedback.mjs +3 -1
- package/dev/client/connectivity/logical-host-connection.mjs +4 -0
- package/dev/client/connectivity/managed-host-browser.mjs +36 -6
- package/dev/client/web/index.html +821 -869
- package/dev/client/web-chat/dist/assets/{ReactPrism-C6YiTZTC.js → ReactPrism-J2mp0sGV.js} +1 -1
- package/dev/client/web-chat/dist/assets/{ReactPrism-C6YiTZTC.js.map → ReactPrism-J2mp0sGV.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/SessionsSetupApp-CkENGhE-.css +1 -0
- package/dev/client/web-chat/dist/assets/SessionsSetupApp-DMSLgqp_.js +6348 -0
- package/dev/client/web-chat/dist/assets/{SessionsSetupApp-CKJOSPFP.js.map → SessionsSetupApp-DMSLgqp_.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/{index-CN_FoTB1.js → index-BfrZKoYM.js} +2 -2
- package/dev/client/web-chat/dist/assets/{index-CN_FoTB1.js.map → index-BfrZKoYM.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/{index-DCQFwgGf.js → index-C0U6oqMv.js} +1 -1
- package/dev/client/web-chat/dist/assets/{index-DCQFwgGf.js.map → index-C0U6oqMv.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/{index-Ae5I4LHp.js → index-CG0A3OzI.js} +2 -2
- package/dev/client/web-chat/dist/assets/{index-Ae5I4LHp.js.map → index-CG0A3OzI.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/{matrix-entry-abAy3aOo.js → matrix-entry-4XhjfS2j.js} +165 -165
- package/dev/client/web-chat/dist/assets/matrix-entry-4XhjfS2j.js.map +1 -0
- package/dev/client/web-chat/dist/assets/{pdf-DN7oVvM6.js → pdf-DjW36tod.js} +3 -3
- package/dev/client/web-chat/dist/assets/{pdf-DN7oVvM6.js.map → pdf-DjW36tod.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/{web-Dabw6cJi.js → web-B-85Q5Fj.js} +1 -1
- package/dev/client/web-chat/dist/assets/{web-Dabw6cJi.js.map → web-B-85Q5Fj.js.map} +1 -1
- package/dev/client/web-chat/dist/assets/{web-BlYuDlOV.js → web-T-l_F_RW.js} +1 -1
- package/dev/client/web-chat/dist/assets/{web-BlYuDlOV.js.map → web-T-l_F_RW.js.map} +1 -1
- package/dev/client/web-chat/dist/index.html +1 -1
- package/docs/routec/config_hierachy.md +28 -22
- package/docs/routec/dev/host_update_runtime_identity.md +42 -1
- package/docs/routec/dev/npmjs_publish.md +46 -16
- package/docs/routec/form_UI_fields.md +1 -2
- package/docs/routec/host_cloud_app_auth.md +4 -4
- package/docs/routec/host_setup.md +28 -37
- package/docs/routec/oysterun_operation_interface_spec.md +6 -5
- package/docs/routec/skill_installation.md +0 -1
- package/host-service/README.md +18 -25
- package/host-service/adapters/claude-code-adapter.mjs +123 -19
- package/host-service/agent-config-migration.mjs +3 -2
- package/host-service/agent-config.mjs +26 -4
- package/host-service/apns-complete-message-dispatcher.mjs +6 -7
- package/host-service/apns-config.mjs +2 -1
- package/host-service/apns-device-store.mjs +7 -3
- package/host-service/assets/product-skills/Oysterun/SKILL.md +0 -1
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-session-chat/SKILL.md +11 -10
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-sessions/SKILL.md +24 -10
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-website/SKILL.md +2 -2
- package/host-service/assets/product-skills/oysterun-session-chat/SKILL.md +11 -10
- package/host-service/assets/product-skills/oysterun-sessions/SKILL.md +24 -10
- package/host-service/assets/product-skills/oysterun-website/SKILL.md +2 -2
- package/host-service/atomic-file.mjs +184 -14
- package/host-service/claude-acp-model-discovery.mjs +106 -22
- package/host-service/claude-acp-model-error-classification.mjs +97 -0
- package/host-service/cli/prepare-storage-layout.mjs +41 -0
- package/host-service/cli/product-cli.mjs +136 -46
- package/host-service/cli/recover-installer-lifecycle.mjs +2 -1
- package/host-service/cli-profile-storage.mjs +69 -0
- package/host-service/cloud-identity-envelope.mjs +93 -0
- package/host-service/complete-cli-uninstall.mjs +8 -3
- package/host-service/config-storage-shape.mjs +48 -0
- package/host-service/config.mjs +167 -179
- package/host-service/connectivity/managed-tunnel-runtime-status.mjs +5 -5
- package/host-service/connectivity/transport-usage-circuit-store.mjs +2 -6
- package/host-service/desired-open-session-state.mjs +5 -3
- package/host-service/frp-agent.mjs +14 -10
- package/host-service/host-lifecycle-recovery.mjs +29 -15
- package/host-service/host-login-bootstrap-tokens.mjs +21 -34
- package/host-service/host-restart-login-gate.mjs +4 -7
- package/host-service/host-runtime-diagnostics.mjs +10 -17
- package/host-service/host-telemetry.mjs +4 -5
- package/host-service/initial-preflight-recovery.mjs +2 -1
- package/host-service/installer-recovery-guidance.mjs +4 -3
- package/host-service/installer-reinstall-bindings.mjs +2 -1
- package/host-service/installer-reinstall-target.mjs +2 -1
- package/host-service/large-tool-call-store.mjs +4 -2
- package/host-service/lifecycle-compat-preload.mjs +1 -1
- package/host-service/lifecycle-compatibility.mjs +5 -4
- package/host-service/lifecycle-continuity-assets.mjs +24 -10
- package/host-service/lifecycle-continuity-probe.mjs +9 -3
- package/host-service/lifecycle-continuity-projection.mjs +2 -0
- package/host-service/lifecycle-continuity-runner.mjs +5 -12
- package/host-service/lifecycle-continuity.mjs +99 -46
- package/host-service/lifecycle-diagnostics.mjs +54 -8
- package/host-service/lifecycle-service-render-bundle.mjs +3 -2
- package/host-service/lifecycle-user-path.mjs +4 -0
- package/host-service/log-retention.mjs +199 -0
- package/host-service/mail-notification-dispatcher.mjs +6 -7
- package/host-service/mail-store.mjs +2 -1
- package/host-service/managed-identity-lifecycle.mjs +3 -31
- package/host-service/matrix-room-binding.mjs +8 -7
- package/host-service/node-npm-runtime-identity.mjs +2 -1
- package/host-service/onboard.mjs +9 -17
- package/host-service/package.json +1 -1
- package/host-service/product-runtime-host-origin.mjs +10 -13
- package/host-service/provider-model-params.mjs +34 -13
- package/host-service/provider-model-refresh-runner.mjs +16 -3
- package/host-service/registered-update-authority.mjs +0 -13
- package/host-service/replay-claude-acp-raw-events.mjs +6 -3
- package/host-service/restart-restore-state.mjs +4 -7
- package/host-service/routec-artifacts.mjs +6 -4
- package/host-service/routec-matrix-media-store.mjs +8 -12
- package/host-service/routec-matrix-sqlite-store.mjs +43 -71
- package/host-service/routec-matrix-storage-adapter.mjs +5 -2
- package/host-service/routec-matrix-storage-paths.mjs +16 -2
- package/host-service/routec-matrix-stream-seq-repair.mjs +5 -6
- package/host-service/routec-viewport-geometry-diagnostics.mjs +2 -1
- package/host-service/scheduler-setup-snapshot-contract.mjs +12 -0
- package/host-service/scheduler-store.mjs +2 -1
- package/host-service/server.mjs +276 -243
- package/host-service/service-control-token.mjs +7 -13
- package/host-service/service-definition-migration.mjs +70 -13
- package/host-service/session-assets.mjs +3 -2
- package/host-service/session-collection-service.mjs +13 -0
- package/host-service/session-history.mjs +15 -34
- package/host-service/session-loop-definitions.mjs +4 -21
- package/host-service/session-manager.mjs +156 -57
- package/host-service/session-name-counter-store.mjs +2 -1
- package/host-service/session-notification-settings-store.mjs +3 -2
- package/host-service/session-tags.mjs +11 -34
- package/host-service/session-transcript-target.mjs +4 -7
- package/host-service/setup-input-file.mjs +6 -4
- package/host-service/setup-provider-model-defaults.mjs +6 -1
- package/host-service/setup.mjs +58 -576
- package/host-service/stopped-user-host-package.mjs +2 -1
- package/host-service/storage-continuity.mjs +112 -0
- package/host-service/storage-database.mjs +115 -0
- package/host-service/storage-layout-cli.mjs +15 -0
- package/host-service/storage-layout.mjs +377 -0
- package/host-service/storage-lifecycle.mjs +306 -0
- package/host-service/storage-lock.mjs +178 -0
- package/host-service/storage-migration.mjs +678 -0
- package/host-service/storage-references.mjs +72 -0
- package/host-service/storage-service-binding.mjs +255 -0
- package/host-service/storage-snapshot.mjs +101 -0
- package/host-service/telegram-adapter.mjs +7 -1
- package/host-service/telegram-bridge.mjs +195 -0
- package/host-service/telegram-media.mjs +11 -14
- package/host-service/test-fixtures/p316/rca-run1-chunks.json +71 -0
- package/host-service/test-fixtures/p316/rca-run2-chunks.json +213 -0
- package/host-service/tool-event-detail-store.mjs +8 -11
- package/host-service/transcript-store.mjs +16 -14
- package/host-service/update-reminder-state.mjs +7 -8
- package/host-service/upload-manager.mjs +3 -2
- package/host-service/voice-input-service.mjs +5 -13
- package/host-service/voice-input-usage-store.mjs +2 -1
- package/package.json +2 -1
- 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-screenshots.json +22 -12
- package/static/site/docs/choose-and-recover-a-provider/en/index.html +2 -2
- package/static/site/docs/choose-and-recover-a-provider/en/index.md +2 -2
- package/static/site/docs/choose-and-recover-a-provider/zh/index.html +2 -2
- package/static/site/docs/choose-and-recover-a-provider/zh/index.md +2 -2
- 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 +18 -18
- package/static/site/docs/configure-session-files-and-settings/en/index.html +4 -4
- package/static/site/docs/configure-session-files-and-settings/en/index.md +3 -3
- package/static/site/docs/configure-session-files-and-settings/zh/index.html +4 -4
- package/static/site/docs/configure-session-files-and-settings/zh/index.md +3 -3
- package/static/site/docs/generated_manifest.json +82 -82
- package/static/site/docs/host-authentication-and-connection/assets/publication/sessions-connected-managed.png +0 -0
- package/static/site/docs/host-authentication-and-connection/assets/publication-screenshots.json +13 -13
- package/static/site/docs/host-authentication-and-connection/en/index.html +7 -7
- package/static/site/docs/host-authentication-and-connection/en/index.md +9 -9
- package/static/site/docs/host-authentication-and-connection/zh/index.html +7 -7
- package/static/site/docs/host-authentication-and-connection/zh/index.md +9 -9
- package/static/site/docs/install-and-use-a-skill/en/index.html +0 -1
- package/static/site/docs/install-and-use-a-skill/en/index.md +0 -4
- package/static/site/docs/install-and-use-a-skill/zh/index.html +0 -1
- package/static/site/docs/install-and-use-a-skill/zh/index.md +0 -4
- 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-screenshots.json +7 -7
- package/static/site/docs/restore-work-after-a-host-restart/en/index.html +2 -2
- package/static/site/docs/restore-work-after-a-host-restart/en/index.md +2 -2
- package/static/site/docs/restore-work-after-a-host-restart/zh/index.html +2 -2
- package/static/site/docs/restore-work-after-a-host-restart/zh/index.md +2 -2
- 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 +63 -51
- package/static/site/docs/set-up-and-understand-a-host/en/index.html +17 -17
- package/static/site/docs/set-up-and-understand-a-host/en/index.md +16 -48
- package/static/site/docs/set-up-and-understand-a-host/zh/index.html +17 -17
- package/static/site/docs/set-up-and-understand-a-host/zh/index.md +16 -48
- package/static/site/install.sh +83 -21
- package/static/site_source/content/AGENTS.md +5 -12
- 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-screenshots.json +22 -12
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/en/article.html +2 -2
- package/static/site_source/content/tutorials/published/choose-and-recover-a-provider/zh/article.html +2 -2
- 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 +18 -18
- package/static/site_source/content/tutorials/published/configure-session-files-and-settings/en/article.html +3 -3
- package/static/site_source/content/tutorials/published/configure-session-files-and-settings/zh/article.html +3 -3
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/assets/publication/sessions-connected-managed.png +0 -0
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/assets/publication-screenshots.json +13 -13
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/en/article.html +6 -6
- package/static/site_source/content/tutorials/published/host-authentication-and-connection/zh/article.html +6 -6
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/en/article.html +0 -1
- package/static/site_source/content/tutorials/published/install-and-use-a-skill/zh/article.html +0 -1
- 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-screenshots.json +7 -7
- package/static/site_source/content/tutorials/published/restore-work-after-a-host-restart/en/article.html +2 -2
- package/static/site_source/content/tutorials/published/restore-work-after-a-host-restart/zh/article.html +2 -2
- 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 +63 -51
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/en/article.html +16 -16
- package/static/site_source/content/tutorials/published/set-up-and-understand-a-host/zh/article.html +16 -16
- package/static/site_source/downloads/install.sh +83 -21
- package/tool_scripts/install_oysterun_update.mjs +18 -33
- package/tool_scripts/oysterun_continuity_transaction.mjs +97 -93
- package/tool_scripts/oysterun_npm_package_manifest.mjs +15 -1
- package/tool_scripts/oysterun_service_common.sh +72 -15
- package/tool_scripts/oysterun_setup_input.sh +77 -16
- package/tool_scripts/oysterun_update_restart_runner.mjs +3 -5
- package/tool_scripts/p233_legacy_bootstrap.mjs +1 -1
- package/tool_scripts/run_oysterun_host.sh +1 -0
- package/tool_scripts/stack_dashboard_credentials.mjs +28 -12
- package/tool_scripts/start_oysterun.sh +2 -0
- package/tool_scripts/sync_host_stack_config.mjs +23 -13
- package/tool_scripts/test_environment_remote_cloud_deprovision.mjs +13 -10
- package/dev/client/web-chat/dist/assets/SessionsSetupApp-CKJOSPFP.js +0 -6442
- package/dev/client/web-chat/dist/assets/SessionsSetupApp-Dx09Uz-6.css +0 -1
- package/dev/client/web-chat/dist/assets/matrix-entry-abAy3aOo.js.map +0 -1
- package/host-service/agent-store-demo.mjs +0 -369
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-find-context/SKILL.md +0 -114
- package/host-service/assets/product-skills/Oysterun/modules/oysterun-find-context/scripts/oysterun_find_context.mjs +0 -49
- package/host-service/assets/product-skills/oysterun-find-context/SKILL.md +0 -114
- package/host-service/assets/product-skills/oysterun-find-context/scripts/oysterun_find_context.mjs +0 -49
- package/host-service/legacy-continuity-observation.mjs +0 -33
- package/static/site/docs/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/sessions-connected-direct-host.png +0 -0
|
@@ -1258,48 +1258,6 @@
|
|
|
1258
1258
|
justify-content: center;
|
|
1259
1259
|
}
|
|
1260
1260
|
|
|
1261
|
-
.agent-store-demo-backdrop {
|
|
1262
|
-
z-index: 10020;
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
.agent-store-demo-status {
|
|
1266
|
-
min-height: 42px;
|
|
1267
|
-
margin-top: 14px;
|
|
1268
|
-
display: flex;
|
|
1269
|
-
align-items: center;
|
|
1270
|
-
gap: 10px;
|
|
1271
|
-
color: var(--ink-soft);
|
|
1272
|
-
font-size: 14px;
|
|
1273
|
-
line-height: 1.45;
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
.agent-store-demo-spinner {
|
|
1277
|
-
width: 16px;
|
|
1278
|
-
height: 16px;
|
|
1279
|
-
flex: 0 0 16px;
|
|
1280
|
-
border: 2px solid rgba(151, 89, 49, 0.22);
|
|
1281
|
-
border-top-color: var(--accent);
|
|
1282
|
-
border-radius: 50%;
|
|
1283
|
-
animation: oysterun-auth-spin 800ms linear infinite;
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
.browse-create-folder-modal .agent-store-demo-actions {
|
|
1287
|
-
display: grid;
|
|
1288
|
-
grid-template-columns: minmax(0, 1fr);
|
|
1289
|
-
gap: 10px;
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
.agent-store-demo-actions > button {
|
|
1293
|
-
min-width: 0;
|
|
1294
|
-
justify-content: center;
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
|
-
#agent-store-demo-submit-btn {
|
|
1298
|
-
display: inline-flex;
|
|
1299
|
-
align-items: center;
|
|
1300
|
-
gap: 9px;
|
|
1301
|
-
}
|
|
1302
|
-
|
|
1303
1261
|
#app {
|
|
1304
1262
|
display: none;
|
|
1305
1263
|
height: 100vh;
|
|
@@ -4749,6 +4707,57 @@
|
|
|
4749
4707
|
grid-template-columns: minmax(0, 1fr);
|
|
4750
4708
|
}
|
|
4751
4709
|
|
|
4710
|
+
/* Folder Session page: History rows with inline Resume / Duplicate Setup. */
|
|
4711
|
+
.session-list-row-history.session-list-row-inline-actions {
|
|
4712
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
4713
|
+
align-items: center;
|
|
4714
|
+
}
|
|
4715
|
+
|
|
4716
|
+
.session-row-inline-actions {
|
|
4717
|
+
display: flex;
|
|
4718
|
+
align-items: center;
|
|
4719
|
+
padding-right: 8px;
|
|
4720
|
+
}
|
|
4721
|
+
|
|
4722
|
+
.session-row-inline-action {
|
|
4723
|
+
width: var(--oysterun-session-action-trigger-target-size);
|
|
4724
|
+
height: var(--oysterun-session-action-trigger-target-size);
|
|
4725
|
+
display: grid;
|
|
4726
|
+
place-items: center;
|
|
4727
|
+
padding: 0;
|
|
4728
|
+
border: 0;
|
|
4729
|
+
border-radius: 50%;
|
|
4730
|
+
background: transparent;
|
|
4731
|
+
cursor: pointer;
|
|
4732
|
+
}
|
|
4733
|
+
|
|
4734
|
+
.session-row-inline-action:hover:not(:disabled),
|
|
4735
|
+
.session-row-inline-action:focus-visible {
|
|
4736
|
+
background: var(--oysterun-session-action-hover);
|
|
4737
|
+
outline: none;
|
|
4738
|
+
}
|
|
4739
|
+
|
|
4740
|
+
.session-row-inline-action:focus-visible {
|
|
4741
|
+
outline: 2px solid var(--oysterun-session-action-focus);
|
|
4742
|
+
outline-offset: -2px;
|
|
4743
|
+
}
|
|
4744
|
+
|
|
4745
|
+
.session-row-inline-action:disabled {
|
|
4746
|
+
cursor: default;
|
|
4747
|
+
opacity: 0.45;
|
|
4748
|
+
}
|
|
4749
|
+
|
|
4750
|
+
.folder-sessions-intro {
|
|
4751
|
+
display: grid;
|
|
4752
|
+
gap: 14px;
|
|
4753
|
+
padding: 16px 22px 8px;
|
|
4754
|
+
}
|
|
4755
|
+
|
|
4756
|
+
.folder-sessions-label {
|
|
4757
|
+
font-size: 13px;
|
|
4758
|
+
font-weight: 600;
|
|
4759
|
+
}
|
|
4760
|
+
|
|
4752
4761
|
.session-list-row-desired-open {
|
|
4753
4762
|
grid-template-columns: minmax(0, 1fr) 58px;
|
|
4754
4763
|
}
|
|
@@ -7796,6 +7805,15 @@
|
|
|
7796
7805
|
grid-template-columns: minmax(0, 1fr);
|
|
7797
7806
|
}
|
|
7798
7807
|
|
|
7808
|
+
.sessions-collection-list
|
|
7809
|
+
.session-list-row-history.session-list-row-inline-actions {
|
|
7810
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
7811
|
+
}
|
|
7812
|
+
|
|
7813
|
+
.folder-sessions-intro {
|
|
7814
|
+
padding: 14px 14px 6px;
|
|
7815
|
+
}
|
|
7816
|
+
|
|
7799
7817
|
.web-collection-list .web-site-row {
|
|
7800
7818
|
grid-template-columns: minmax(0, 1fr) 86px;
|
|
7801
7819
|
}
|
|
@@ -8488,26 +8506,6 @@
|
|
|
8488
8506
|
>
|
|
8489
8507
|
</div>
|
|
8490
8508
|
<div class="topbar-right">
|
|
8491
|
-
<button
|
|
8492
|
-
class="sessions-compose-button topbar-agent-store hidden"
|
|
8493
|
-
id="entry-agent-store-btn"
|
|
8494
|
-
type="button"
|
|
8495
|
-
aria-label="Agent Store"
|
|
8496
|
-
title="Agent Store"
|
|
8497
|
-
data-testid="oysterun-agent-store-demo"
|
|
8498
|
-
onClick=${call("openAgentStoreDemo")}
|
|
8499
|
-
>
|
|
8500
|
-
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
8501
|
-
<path
|
|
8502
|
-
d="M4 9.25h16v10.5H4V9.25Zm2-5h12l2 5H4l2-5Zm4 5v10.5m4-10.5v10.5"
|
|
8503
|
-
fill="none"
|
|
8504
|
-
stroke="currentColor"
|
|
8505
|
-
stroke-width="1.7"
|
|
8506
|
-
stroke-linecap="round"
|
|
8507
|
-
stroke-linejoin="round"
|
|
8508
|
-
></path>
|
|
8509
|
-
</svg>
|
|
8510
|
-
</button>
|
|
8511
8509
|
<button
|
|
8512
8510
|
class="sessions-compose-button topbar-sessions-compose hidden"
|
|
8513
8511
|
id="entry-start-session-btn"
|
|
@@ -9715,36 +9713,9 @@
|
|
|
9715
9713
|
</div>
|
|
9716
9714
|
</div>
|
|
9717
9715
|
<div class="kv-table">
|
|
9718
|
-
<div class="kv-label">
|
|
9719
|
-
|
|
9720
|
-
<div class="value-stack">
|
|
9721
|
-
<div class="settings-copy-url-control">
|
|
9722
|
-
<input
|
|
9723
|
-
id="host-public-base-url"
|
|
9724
|
-
type="url"
|
|
9725
|
-
placeholder="Host URL from setup"
|
|
9726
|
-
data-oysterun-p75-copyable-url-control="direct-host-url"
|
|
9727
|
-
/>
|
|
9728
|
-
<button
|
|
9729
|
-
class="btn-primary btn-compact settings-copy-url-btn"
|
|
9730
|
-
id="host-public-base-url-copy-btn"
|
|
9731
|
-
type="button"
|
|
9732
|
-
onClick=${call(
|
|
9733
|
-
"copyHostPreferencesDirectHostUrl"
|
|
9734
|
-
)}
|
|
9735
|
-
>
|
|
9736
|
-
Copy
|
|
9737
|
-
</button>
|
|
9738
|
-
</div>
|
|
9739
|
-
<div
|
|
9740
|
-
class="field-hint"
|
|
9741
|
-
id="host-public-base-url-hint"
|
|
9742
|
-
>
|
|
9743
|
-
Optional. Use this URL for manual connection.
|
|
9744
|
-
</div>
|
|
9745
|
-
</div>
|
|
9716
|
+
<div class="kv-label">
|
|
9717
|
+
Local address (this computer)
|
|
9746
9718
|
</div>
|
|
9747
|
-
<div class="kv-label">Local URL</div>
|
|
9748
9719
|
<div class="kv-value">
|
|
9749
9720
|
<div class="settings-copy-url-control">
|
|
9750
9721
|
<input
|
|
@@ -10288,13 +10259,23 @@
|
|
|
10288
10259
|
class="field-hint host-update-phase"
|
|
10289
10260
|
id="host-update-phase"
|
|
10290
10261
|
></div>
|
|
10262
|
+
<button
|
|
10263
|
+
class="btn-ghost btn-compact hidden"
|
|
10264
|
+
type="button"
|
|
10265
|
+
id="host-update-card-diagnostics-btn"
|
|
10266
|
+
onClick=${call(
|
|
10267
|
+
"downloadHostLifecycleDiagnosticSummary"
|
|
10268
|
+
)}
|
|
10269
|
+
>
|
|
10270
|
+
Download diagnostic summary
|
|
10271
|
+
</button>
|
|
10291
10272
|
<button
|
|
10292
10273
|
class="btn-ghost btn-compact hidden"
|
|
10293
10274
|
type="button"
|
|
10294
10275
|
id="host-update-recovery-btn"
|
|
10295
10276
|
onClick=${call("runOysterunRecoveryAction")}
|
|
10296
10277
|
>
|
|
10297
|
-
|
|
10278
|
+
Restore and restart
|
|
10298
10279
|
</button>
|
|
10299
10280
|
<div
|
|
10300
10281
|
class="field-hint host-update-recovery-status hidden"
|
|
@@ -10388,6 +10369,16 @@
|
|
|
10388
10369
|
>
|
|
10389
10370
|
Cancel
|
|
10390
10371
|
</button>
|
|
10372
|
+
<button
|
|
10373
|
+
class="btn-ghost hidden"
|
|
10374
|
+
type="button"
|
|
10375
|
+
id="host-update-confirm-diagnostics-btn"
|
|
10376
|
+
onClick=${call(
|
|
10377
|
+
"downloadHostLifecycleDiagnosticSummary"
|
|
10378
|
+
)}
|
|
10379
|
+
>
|
|
10380
|
+
Download diagnostic summary
|
|
10381
|
+
</button>
|
|
10391
10382
|
<button
|
|
10392
10383
|
class="btn-primary"
|
|
10393
10384
|
type="button"
|
|
@@ -11743,9 +11734,30 @@ Terminal output will appear here.</pre
|
|
|
11743
11734
|
</div>
|
|
11744
11735
|
</div>
|
|
11745
11736
|
</div>
|
|
11737
|
+
</section>
|
|
11738
|
+
</div>
|
|
11739
|
+
</div>
|
|
11740
|
+
</section>
|
|
11741
|
+
`;
|
|
11742
|
+
}
|
|
11743
|
+
|
|
11744
|
+
// Resume Session reuses the Sessions history list primitives for one
|
|
11745
|
+
// folder. Its rows and menus come from the same History renderers.
|
|
11746
|
+
function FolderSessionsView() {
|
|
11747
|
+
return html`
|
|
11748
|
+
<section
|
|
11749
|
+
id="folder-sessions-view"
|
|
11750
|
+
class="view view-page-scroll"
|
|
11751
|
+
data-oysterun-folder-sessions-page="true"
|
|
11752
|
+
>
|
|
11753
|
+
<div class="collection-layout sessions-collection-layout">
|
|
11754
|
+
<div class="collection-shell sessions-collection-shell">
|
|
11755
|
+
<section
|
|
11756
|
+
class="panel collection-panel sessions-collection-panel"
|
|
11757
|
+
>
|
|
11746
11758
|
<div
|
|
11747
|
-
class="
|
|
11748
|
-
id="
|
|
11759
|
+
class="collection-list sessions-collection-list"
|
|
11760
|
+
id="folder-sessions-list"
|
|
11749
11761
|
></div>
|
|
11750
11762
|
</section>
|
|
11751
11763
|
</div>
|
|
@@ -12508,126 +12520,6 @@ Terminal output will appear here.</pre
|
|
|
12508
12520
|
`;
|
|
12509
12521
|
}
|
|
12510
12522
|
|
|
12511
|
-
function AgentStoreDemoModal() {
|
|
12512
|
-
return html`
|
|
12513
|
-
<div
|
|
12514
|
-
id="agent-store-demo-backdrop"
|
|
12515
|
-
class="modal-backdrop sheet browse-create-folder-backdrop agent-store-demo-backdrop hidden"
|
|
12516
|
-
onClick=${closeBackdrop("closeAgentStoreDemo")}
|
|
12517
|
-
>
|
|
12518
|
-
<div
|
|
12519
|
-
class="modal sheet narrow browse-create-folder-modal agent-store-demo-modal"
|
|
12520
|
-
role="dialog"
|
|
12521
|
-
aria-modal="true"
|
|
12522
|
-
aria-labelledby="agent-store-demo-title"
|
|
12523
|
-
data-oysterun-agent-store-demo="true"
|
|
12524
|
-
>
|
|
12525
|
-
<button
|
|
12526
|
-
class="modal-close-btn browse-create-folder-close-btn"
|
|
12527
|
-
id="agent-store-demo-close-btn"
|
|
12528
|
-
type="button"
|
|
12529
|
-
aria-label="Close"
|
|
12530
|
-
title="Close"
|
|
12531
|
-
onClick=${call("closeAgentStoreDemo")}
|
|
12532
|
-
>
|
|
12533
|
-
x
|
|
12534
|
-
</button>
|
|
12535
|
-
<div class="modal-scroll">
|
|
12536
|
-
<span class="eyebrow">Agent Store Demo</span>
|
|
12537
|
-
<h2 id="agent-store-demo-title">Clone GitHub Agent</h2>
|
|
12538
|
-
<div class="field" style="margin-top:14px">
|
|
12539
|
-
<label for="agent-store-demo-repository-select"
|
|
12540
|
-
>Demo Repository</label
|
|
12541
|
-
>
|
|
12542
|
-
<select
|
|
12543
|
-
id="agent-store-demo-repository-select"
|
|
12544
|
-
onChange=${(event) =>
|
|
12545
|
-
window.handleAgentStoreDemoRepositorySelect?.(event)}
|
|
12546
|
-
>
|
|
12547
|
-
<option value="">Choose a demo repository</option>
|
|
12548
|
-
<option
|
|
12549
|
-
value="https://github.com/GoatWang/oysterun-ccstock-workenv"
|
|
12550
|
-
>
|
|
12551
|
-
CCStock WorkEnv
|
|
12552
|
-
</option>
|
|
12553
|
-
<option
|
|
12554
|
-
value="https://github.com/GoatWang/oysterun-ccstock-workenv-en"
|
|
12555
|
-
>
|
|
12556
|
-
CCStock WorkEnv (English)
|
|
12557
|
-
</option>
|
|
12558
|
-
<option
|
|
12559
|
-
value="https://github.com/GoatWang/oysterun-github-tracker"
|
|
12560
|
-
>
|
|
12561
|
-
GitHub Tracker
|
|
12562
|
-
</option>
|
|
12563
|
-
</select>
|
|
12564
|
-
</div>
|
|
12565
|
-
<div class="field" style="margin-top:14px">
|
|
12566
|
-
<label for="agent-store-demo-url-input"
|
|
12567
|
-
>GitHub Repository URL</label
|
|
12568
|
-
>
|
|
12569
|
-
<input
|
|
12570
|
-
id="agent-store-demo-url-input"
|
|
12571
|
-
type="url"
|
|
12572
|
-
inputmode="url"
|
|
12573
|
-
autocomplete="url"
|
|
12574
|
-
autocapitalize="none"
|
|
12575
|
-
spellcheck="false"
|
|
12576
|
-
placeholder="https://github.com/owner/repository"
|
|
12577
|
-
onInput=${(event) =>
|
|
12578
|
-
window.handleAgentStoreDemoUrlInput?.(event)}
|
|
12579
|
-
onKeyDown=${(event) =>
|
|
12580
|
-
window.handleAgentStoreDemoUrlKeyDown?.(event)}
|
|
12581
|
-
/>
|
|
12582
|
-
</div>
|
|
12583
|
-
<div
|
|
12584
|
-
id="agent-store-demo-status"
|
|
12585
|
-
class="agent-store-demo-status hidden"
|
|
12586
|
-
role="status"
|
|
12587
|
-
aria-live="polite"
|
|
12588
|
-
aria-atomic="true"
|
|
12589
|
-
>
|
|
12590
|
-
<span
|
|
12591
|
-
id="agent-store-demo-status-spinner"
|
|
12592
|
-
class="agent-store-demo-spinner"
|
|
12593
|
-
aria-hidden="true"
|
|
12594
|
-
></span>
|
|
12595
|
-
<span id="agent-store-demo-status-text"></span>
|
|
12596
|
-
</div>
|
|
12597
|
-
<div
|
|
12598
|
-
id="agent-store-demo-error"
|
|
12599
|
-
class="error-box hidden"
|
|
12600
|
-
style="margin-top:12px"
|
|
12601
|
-
></div>
|
|
12602
|
-
</div>
|
|
12603
|
-
<div class="modal-actions agent-store-demo-actions">
|
|
12604
|
-
<button
|
|
12605
|
-
class="btn-primary"
|
|
12606
|
-
id="agent-store-demo-submit-btn"
|
|
12607
|
-
type="button"
|
|
12608
|
-
onClick=${call("submitAgentStoreDemo")}
|
|
12609
|
-
>
|
|
12610
|
-
<span
|
|
12611
|
-
id="agent-store-demo-submit-spinner"
|
|
12612
|
-
class="agent-store-demo-spinner hidden"
|
|
12613
|
-
aria-hidden="true"
|
|
12614
|
-
></span>
|
|
12615
|
-
<span id="agent-store-demo-submit-label">OK</span>
|
|
12616
|
-
</button>
|
|
12617
|
-
<button
|
|
12618
|
-
class="btn-secondary hidden"
|
|
12619
|
-
id="agent-store-demo-session-setup-btn"
|
|
12620
|
-
type="button"
|
|
12621
|
-
onClick=${call("openAgentStoreDemoSessionSetup")}
|
|
12622
|
-
>
|
|
12623
|
-
Open Session Setup
|
|
12624
|
-
</button>
|
|
12625
|
-
</div>
|
|
12626
|
-
</div>
|
|
12627
|
-
</div>
|
|
12628
|
-
`;
|
|
12629
|
-
}
|
|
12630
|
-
|
|
12631
12523
|
function ProviderAuthModal() {
|
|
12632
12524
|
return html`
|
|
12633
12525
|
<div
|
|
@@ -12811,6 +12703,7 @@ Waiting for Claude login output…</pre
|
|
|
12811
12703
|
<div class="app-body">
|
|
12812
12704
|
<main class="workspace" id="dashboard-workspace">
|
|
12813
12705
|
<${EntryView} />
|
|
12706
|
+
<${FolderSessionsView} />
|
|
12814
12707
|
<${WebView} />
|
|
12815
12708
|
<${MailView} />
|
|
12816
12709
|
<${SchedulerView} />
|
|
@@ -12826,6 +12719,10 @@ Waiting for Claude login output…</pre
|
|
|
12826
12719
|
<${BrowserSurfaceView} />
|
|
12827
12720
|
<${AgentProfileView} />
|
|
12828
12721
|
<${ExplorerView} />
|
|
12722
|
+
<div
|
|
12723
|
+
class="session-action-menu-layer hidden"
|
|
12724
|
+
id="session-action-menu-layer"
|
|
12725
|
+
></div>
|
|
12829
12726
|
</main>
|
|
12830
12727
|
</div>
|
|
12831
12728
|
<nav class="bottom-nav" id="bottom-nav">
|
|
@@ -12981,7 +12878,6 @@ Waiting for Claude login output…</pre
|
|
|
12981
12878
|
<div id="browse-context-menu" class="browse-context-menu hidden" role="menu" aria-hidden="true" tabindex="-1"></div>
|
|
12982
12879
|
<div id="app-toast" class="app-toast oysterun-notice hidden" role="status" aria-live="polite" aria-atomic="true"></div>
|
|
12983
12880
|
<${BrowseCreateFolderModal} />
|
|
12984
|
-
<${AgentStoreDemoModal} />
|
|
12985
12881
|
<${ProviderAuthModal} />
|
|
12986
12882
|
<${ChatImagePreviewModal} />
|
|
12987
12883
|
<${HiddenCache} />
|
|
@@ -14454,7 +14350,6 @@ Waiting for Claude login output…</pre
|
|
|
14454
14350
|
const OYSTERUN_PROVIDER_SKILL_MODULE_HELPERS = Object.freeze([
|
|
14455
14351
|
["oysterun_sessions_skill", "oysterun-sessions"],
|
|
14456
14352
|
["oysterun_session_chat_skill", "oysterun-session-chat"],
|
|
14457
|
-
["oysterun_find_context_skill", "oysterun-find-context"],
|
|
14458
14353
|
["oysterun_scheduler_skill", "oysterun-scheduler"],
|
|
14459
14354
|
["oysterun_mail_skill", "oysterun-mail"],
|
|
14460
14355
|
["oysterun_notification_skill", "oysterun-notifications"],
|
|
@@ -14689,6 +14584,7 @@ Waiting for Claude login output…</pre
|
|
|
14689
14584
|
for (const field of [
|
|
14690
14585
|
"restore_failed_reason",
|
|
14691
14586
|
"manual_start_setup_reason",
|
|
14587
|
+
"agent_folder_real_path",
|
|
14692
14588
|
]) {
|
|
14693
14589
|
if (field in row) nullableString(row[field], field);
|
|
14694
14590
|
}
|
|
@@ -14735,6 +14631,16 @@ Waiting for Claude login output…</pre
|
|
|
14735
14631
|
"Session History cannot claim active provider lifecycle."
|
|
14736
14632
|
);
|
|
14737
14633
|
}
|
|
14634
|
+
if (
|
|
14635
|
+
row.telegram_listener_alert != null &&
|
|
14636
|
+
(typeof row.telegram_listener_alert !== "object" ||
|
|
14637
|
+
typeof row.telegram_listener_alert.outage_id !== "string" ||
|
|
14638
|
+
row.kind !== "running")
|
|
14639
|
+
) {
|
|
14640
|
+
throw new Error(
|
|
14641
|
+
"Session data Telegram listener reminder must belong to a live Session."
|
|
14642
|
+
);
|
|
14643
|
+
}
|
|
14738
14644
|
if (
|
|
14739
14645
|
"restore_failed" in row &&
|
|
14740
14646
|
typeof row.restore_failed !== "boolean"
|
|
@@ -16673,17 +16579,6 @@ Waiting for Claude login output…</pre
|
|
|
16673
16579
|
};
|
|
16674
16580
|
}
|
|
16675
16581
|
|
|
16676
|
-
function createAgentStoreDemoState() {
|
|
16677
|
-
return {
|
|
16678
|
-
visible: false,
|
|
16679
|
-
phase: "idle",
|
|
16680
|
-
repositoryUrl: "",
|
|
16681
|
-
status: "",
|
|
16682
|
-
error: "",
|
|
16683
|
-
clone: null,
|
|
16684
|
-
requestId: 0,
|
|
16685
|
-
};
|
|
16686
|
-
}
|
|
16687
16582
|
function createTerminalViewState() {
|
|
16688
16583
|
return {
|
|
16689
16584
|
terminal: null,
|
|
@@ -16750,18 +16645,6 @@ Waiting for Claude login output…</pre
|
|
|
16750
16645
|
payload.display_name = String(value || "").trim() || null;
|
|
16751
16646
|
},
|
|
16752
16647
|
}),
|
|
16753
|
-
hostPreferenceField("publicBaseUrl", "", {
|
|
16754
|
-
controlIds: ["host-public-base-url"],
|
|
16755
|
-
read: hostPreferenceTextControl(
|
|
16756
|
-
"host-public-base-url",
|
|
16757
|
-
"publicBaseUrl"
|
|
16758
|
-
),
|
|
16759
|
-
serialize: (value, { payload }) => {
|
|
16760
|
-
const normalized = String(value || "").trim() || null;
|
|
16761
|
-
payload.direct_host_url = normalized;
|
|
16762
|
-
payload.public_base_url = normalized;
|
|
16763
|
-
},
|
|
16764
|
-
}),
|
|
16765
16648
|
hostPreferenceField("defaultBrowsePath", "", {
|
|
16766
16649
|
controlIds: ["host-default-browse-path"],
|
|
16767
16650
|
read: hostPreferenceTextControl(
|
|
@@ -16993,9 +16876,6 @@ Waiting for Claude login output…</pre
|
|
|
16993
16876
|
loaded: false,
|
|
16994
16877
|
loading: false,
|
|
16995
16878
|
saving: false,
|
|
16996
|
-
// Internal cloud/mamarun plumbing is retained but not product-facing
|
|
16997
|
-
// in the short term; Host Preferences intentionally hides this.
|
|
16998
|
-
connectionMode: "direct",
|
|
16999
16879
|
displayName: "",
|
|
17000
16880
|
notificationSoundWebEnabled: true,
|
|
17001
16881
|
notificationSoundAppEnabled: true,
|
|
@@ -17045,8 +16925,6 @@ Waiting for Claude login output…</pre
|
|
|
17045
16925
|
allowedPathDisabled: true,
|
|
17046
16926
|
allowedPathDebugUiEnabled: false,
|
|
17047
16927
|
providerPermissionDebugModeDropdownEnabled: false,
|
|
17048
|
-
publicBaseUrl: "",
|
|
17049
|
-
activeDirectHostUrl: "",
|
|
17050
16928
|
managedTunnelEnabled: false,
|
|
17051
16929
|
managedTunnelStatus: "disabled",
|
|
17052
16930
|
managedTunnelStatusReason: "managed_tunnel_disabled",
|
|
@@ -17060,7 +16938,6 @@ Waiting for Claude login output…</pre
|
|
|
17060
16938
|
notificationDiagnosticsUiEnabled: false,
|
|
17061
16939
|
notificationServiceWorkerState: "unknown",
|
|
17062
16940
|
notificationLastError: "",
|
|
17063
|
-
directHostUrlRestartRequired: false,
|
|
17064
16941
|
hostRestartSupported: false,
|
|
17065
16942
|
loginQr: null,
|
|
17066
16943
|
loginQrLoading: false,
|
|
@@ -17148,7 +17025,6 @@ Waiting for Claude login output…</pre
|
|
|
17148
17025
|
},
|
|
17149
17026
|
};
|
|
17150
17027
|
let providerAuthModalState = createProviderAuthModalState();
|
|
17151
|
-
let agentStoreDemoState = createAgentStoreDemoState();
|
|
17152
17028
|
let chatImagePreviewState = {
|
|
17153
17029
|
visible: false,
|
|
17154
17030
|
requestKey: "",
|
|
@@ -17624,16 +17500,6 @@ Waiting for Claude login output…</pre
|
|
|
17624
17500
|
typeof fallbackValue === "string" ? fallbackValue.trim() : "";
|
|
17625
17501
|
return fallback || defaultValue;
|
|
17626
17502
|
}
|
|
17627
|
-
function requiresProviderPermissionPolicyConfirmation(providerId, value) {
|
|
17628
|
-
const selected = typeof value === "string" ? value.trim() : "";
|
|
17629
|
-
const defaultValue = getDefaultProviderPermissionPolicy(providerId);
|
|
17630
|
-
return (
|
|
17631
|
-
isProviderPermissionDebugModeDropdownEnabled() &&
|
|
17632
|
-
Boolean(selected) &&
|
|
17633
|
-
Boolean(defaultValue) &&
|
|
17634
|
-
selected !== defaultValue
|
|
17635
|
-
);
|
|
17636
|
-
}
|
|
17637
17503
|
function syncSessionSetupInterfaceStyleVisibility() {
|
|
17638
17504
|
const visible = isSessionSetupInterfaceStyleVisible();
|
|
17639
17505
|
for (const element of document.querySelectorAll(
|
|
@@ -22374,6 +22240,7 @@ Waiting for Claude login output…</pre
|
|
|
22374
22240
|
syncOwnerId = null,
|
|
22375
22241
|
timeoutMs = void 0,
|
|
22376
22242
|
onUploadProgress = null,
|
|
22243
|
+
onDispatch = null,
|
|
22377
22244
|
} = {}
|
|
22378
22245
|
) {
|
|
22379
22246
|
if (this.closed)
|
|
@@ -22390,6 +22257,7 @@ Waiting for Claude login output…</pre
|
|
|
22390
22257
|
const isMatrixSync = MATRIX_SYNC_PATH.test(request.path);
|
|
22391
22258
|
const startedAt = Date.now();
|
|
22392
22259
|
const releaseTransport = this.acquireTransportLease(transport);
|
|
22260
|
+
onDispatch?.({ pathKind });
|
|
22393
22261
|
this.emitDiagnostic({
|
|
22394
22262
|
event_type: isMatrixSync
|
|
22395
22263
|
? "matrix_sync_request_started"
|
|
@@ -24715,6 +24583,17 @@ Waiting for Claude login output…</pre
|
|
|
24715
24583
|
headers: response.headers || {},
|
|
24716
24584
|
});
|
|
24717
24585
|
}
|
|
24586
|
+
function responseFromDispatchedLogicalResult(
|
|
24587
|
+
result,
|
|
24588
|
+
dispatchedPathKind
|
|
24589
|
+
) {
|
|
24590
|
+
return dispatchedPathKind === "webrtc"
|
|
24591
|
+
? responseFromLogicalResult(result)
|
|
24592
|
+
: responseFromBootstrapLogicalResult(result);
|
|
24593
|
+
}
|
|
24594
|
+
function transportAccountingKind(pathKind) {
|
|
24595
|
+
return pathKind === "webrtc" ? "datachannel" : "bootstrap";
|
|
24596
|
+
}
|
|
24718
24597
|
function logicalResultBodyByteLength(result) {
|
|
24719
24598
|
if (result?.response?.body instanceof Uint8Array) {
|
|
24720
24599
|
return result.response.body.byteLength;
|
|
@@ -26415,7 +26294,7 @@ Waiting for Claude login output…</pre
|
|
|
26415
26294
|
}
|
|
26416
26295
|
: {}),
|
|
26417
26296
|
};
|
|
26418
|
-
|
|
26297
|
+
let dispatchedPathKind2 = "bootstrap";
|
|
26419
26298
|
let result2;
|
|
26420
26299
|
try {
|
|
26421
26300
|
result2 = await this.logicalConnection.request(
|
|
@@ -26425,6 +26304,14 @@ Waiting for Claude login output…</pre
|
|
|
26425
26304
|
syncOwnerId: MATRIX_SYNC_PATH2.test(path)
|
|
26426
26305
|
? this.ensureSyncOwner()
|
|
26427
26306
|
: null,
|
|
26307
|
+
onDispatch: ({ pathKind }) => {
|
|
26308
|
+
dispatchedPathKind2 = pathKind;
|
|
26309
|
+
recordTransportRequest(
|
|
26310
|
+
this.accounting,
|
|
26311
|
+
transportAccountingKind(pathKind),
|
|
26312
|
+
path
|
|
26313
|
+
);
|
|
26314
|
+
},
|
|
26428
26315
|
}
|
|
26429
26316
|
);
|
|
26430
26317
|
} catch (error) {
|
|
@@ -26465,10 +26352,13 @@ Waiting for Claude login output…</pre
|
|
|
26465
26352
|
}
|
|
26466
26353
|
throw error;
|
|
26467
26354
|
}
|
|
26468
|
-
const response =
|
|
26355
|
+
const response = responseFromDispatchedLogicalResult(
|
|
26356
|
+
result2,
|
|
26357
|
+
dispatchedPathKind2
|
|
26358
|
+
);
|
|
26469
26359
|
recordTransportResponseBytes(
|
|
26470
26360
|
this.accounting,
|
|
26471
|
-
|
|
26361
|
+
transportAccountingKind(dispatchedPathKind2),
|
|
26472
26362
|
logicalResultBodyByteLength(result2),
|
|
26473
26363
|
path
|
|
26474
26364
|
);
|
|
@@ -26492,6 +26382,7 @@ Waiting for Claude login output…</pre
|
|
|
26492
26382
|
signal: request.signal,
|
|
26493
26383
|
...(body ? { body } : {}),
|
|
26494
26384
|
};
|
|
26385
|
+
let dispatchedPathKind = "webrtc";
|
|
26495
26386
|
const result = await this.logicalConnection.request(
|
|
26496
26387
|
requestPayload,
|
|
26497
26388
|
{
|
|
@@ -26505,16 +26396,23 @@ Waiting for Claude login output…</pre
|
|
|
26505
26396
|
? BULK_REQUEST_TIMEOUT_MS
|
|
26506
26397
|
: void 0,
|
|
26507
26398
|
onUploadProgress: recovery.onUploadProgress || null,
|
|
26399
|
+
onDispatch: ({ pathKind }) => {
|
|
26400
|
+
dispatchedPathKind = pathKind;
|
|
26401
|
+
},
|
|
26508
26402
|
}
|
|
26509
26403
|
);
|
|
26510
|
-
|
|
26404
|
+
const accountingKind = transportAccountingKind(dispatchedPathKind);
|
|
26405
|
+
recordTransportRequest(this.accounting, accountingKind, path);
|
|
26511
26406
|
recordTransportResponseBytes(
|
|
26512
26407
|
this.accounting,
|
|
26513
|
-
|
|
26408
|
+
accountingKind,
|
|
26514
26409
|
logicalResultBodyByteLength(result),
|
|
26515
26410
|
path
|
|
26516
26411
|
);
|
|
26517
|
-
return
|
|
26412
|
+
return responseFromDispatchedLogicalResult(
|
|
26413
|
+
result,
|
|
26414
|
+
dispatchedPathKind
|
|
26415
|
+
);
|
|
26518
26416
|
}
|
|
26519
26417
|
status() {
|
|
26520
26418
|
const logicalStatus = this.logicalConnection.status();
|
|
@@ -26770,7 +26668,7 @@ Waiting for Claude login output…</pre
|
|
|
26770
26668
|
["closed", "disconnected", "recovering", "unavailable"].includes(
|
|
26771
26669
|
status.connection_state
|
|
26772
26670
|
);
|
|
26773
|
-
let qualifier = "
|
|
26671
|
+
let qualifier = "Local address";
|
|
26774
26672
|
if (originKind === "managed_endpoint") {
|
|
26775
26673
|
qualifier =
|
|
26776
26674
|
activePathKind === "webrtc"
|
|
@@ -27682,376 +27580,6 @@ Waiting for Claude login output…</pre
|
|
|
27682
27580
|
window.openExplorerFromSessionsEmptyState =
|
|
27683
27581
|
openExplorerFromSessionsEmptyState;
|
|
27684
27582
|
|
|
27685
|
-
const AGENT_STORE_DEMO_PENDING_PHASES = new Set([
|
|
27686
|
-
"validating",
|
|
27687
|
-
"cloning",
|
|
27688
|
-
"loading_config",
|
|
27689
|
-
"starting_session",
|
|
27690
|
-
]);
|
|
27691
|
-
|
|
27692
|
-
const AGENT_STORE_DEMO_REPOSITORY_URLS = new Set([
|
|
27693
|
-
"https://github.com/GoatWang/oysterun-ccstock-workenv",
|
|
27694
|
-
"https://github.com/GoatWang/oysterun-ccstock-workenv-en",
|
|
27695
|
-
"https://github.com/GoatWang/oysterun-github-tracker",
|
|
27696
|
-
]);
|
|
27697
|
-
|
|
27698
|
-
function isAgentStoreDemoPending() {
|
|
27699
|
-
return AGENT_STORE_DEMO_PENDING_PHASES.has(agentStoreDemoState.phase);
|
|
27700
|
-
}
|
|
27701
|
-
|
|
27702
|
-
function getAgentStoreDemoPendingLabel() {
|
|
27703
|
-
if (agentStoreDemoState.phase === "validating") return "Validating...";
|
|
27704
|
-
if (agentStoreDemoState.phase === "cloning") return "Cloning...";
|
|
27705
|
-
if (agentStoreDemoState.phase === "loading_config")
|
|
27706
|
-
return "Loading config...";
|
|
27707
|
-
if (agentStoreDemoState.phase === "starting_session")
|
|
27708
|
-
return "Starting session...";
|
|
27709
|
-
return "OK";
|
|
27710
|
-
}
|
|
27711
|
-
|
|
27712
|
-
function renderAgentStoreDemo() {
|
|
27713
|
-
const backdrop = $("agent-store-demo-backdrop");
|
|
27714
|
-
if (!backdrop) return;
|
|
27715
|
-
const pending = isAgentStoreDemoPending();
|
|
27716
|
-
const cloneComplete = Boolean(agentStoreDemoState.clone?.agent_folder);
|
|
27717
|
-
const input = $("agent-store-demo-url-input");
|
|
27718
|
-
const repositorySelect = $("agent-store-demo-repository-select");
|
|
27719
|
-
const closeButton = $("agent-store-demo-close-btn");
|
|
27720
|
-
const submitButton = $("agent-store-demo-submit-btn");
|
|
27721
|
-
const submitLabel = $("agent-store-demo-submit-label");
|
|
27722
|
-
|
|
27723
|
-
backdrop.classList.toggle(
|
|
27724
|
-
"hidden",
|
|
27725
|
-
agentStoreDemoState.visible !== true
|
|
27726
|
-
);
|
|
27727
|
-
backdrop.dataset.phase = agentStoreDemoState.phase;
|
|
27728
|
-
if (input) {
|
|
27729
|
-
if (input.value !== agentStoreDemoState.repositoryUrl) {
|
|
27730
|
-
input.value = agentStoreDemoState.repositoryUrl;
|
|
27731
|
-
}
|
|
27732
|
-
input.disabled = pending || cloneComplete;
|
|
27733
|
-
}
|
|
27734
|
-
if (repositorySelect) {
|
|
27735
|
-
repositorySelect.value = AGENT_STORE_DEMO_REPOSITORY_URLS.has(
|
|
27736
|
-
agentStoreDemoState.repositoryUrl
|
|
27737
|
-
)
|
|
27738
|
-
? agentStoreDemoState.repositoryUrl
|
|
27739
|
-
: "";
|
|
27740
|
-
repositorySelect.disabled = pending || cloneComplete;
|
|
27741
|
-
}
|
|
27742
|
-
if (closeButton) closeButton.disabled = pending;
|
|
27743
|
-
if (submitButton) {
|
|
27744
|
-
submitButton.disabled =
|
|
27745
|
-
pending ||
|
|
27746
|
-
cloneComplete ||
|
|
27747
|
-
!agentStoreDemoState.repositoryUrl.trim();
|
|
27748
|
-
submitButton.classList.toggle(
|
|
27749
|
-
"hidden",
|
|
27750
|
-
agentStoreDemoState.phase === "failed_after_clone"
|
|
27751
|
-
);
|
|
27752
|
-
}
|
|
27753
|
-
if (submitLabel)
|
|
27754
|
-
submitLabel.textContent = getAgentStoreDemoPendingLabel();
|
|
27755
|
-
setVisible("agent-store-demo-submit-spinner", pending);
|
|
27756
|
-
setVisible("agent-store-demo-status", pending);
|
|
27757
|
-
setText(
|
|
27758
|
-
"agent-store-demo-status-text",
|
|
27759
|
-
agentStoreDemoState.status || ""
|
|
27760
|
-
);
|
|
27761
|
-
showError("agent-store-demo-error", agentStoreDemoState.error || "");
|
|
27762
|
-
setVisible(
|
|
27763
|
-
"agent-store-demo-session-setup-btn",
|
|
27764
|
-
agentStoreDemoState.phase === "failed_after_clone" && cloneComplete
|
|
27765
|
-
);
|
|
27766
|
-
}
|
|
27767
|
-
|
|
27768
|
-
function openAgentStoreDemo() {
|
|
27769
|
-
if (isAgentStoreDemoPending()) return;
|
|
27770
|
-
agentStoreDemoState = {
|
|
27771
|
-
...createAgentStoreDemoState(),
|
|
27772
|
-
visible: true,
|
|
27773
|
-
requestId: agentStoreDemoState.requestId + 1,
|
|
27774
|
-
};
|
|
27775
|
-
renderAgentStoreDemo();
|
|
27776
|
-
requestAnimationFrame(() => {
|
|
27777
|
-
$("agent-store-demo-url-input")?.focus({ preventScroll: true });
|
|
27778
|
-
});
|
|
27779
|
-
}
|
|
27780
|
-
|
|
27781
|
-
function closeAgentStoreDemo(opts = {}) {
|
|
27782
|
-
if (isAgentStoreDemoPending() && opts.force !== true) return;
|
|
27783
|
-
agentStoreDemoState = {
|
|
27784
|
-
...createAgentStoreDemoState(),
|
|
27785
|
-
requestId: agentStoreDemoState.requestId + 1,
|
|
27786
|
-
};
|
|
27787
|
-
renderAgentStoreDemo();
|
|
27788
|
-
}
|
|
27789
|
-
|
|
27790
|
-
function handleAgentStoreDemoUrlInput(event) {
|
|
27791
|
-
if (isAgentStoreDemoPending() || agentStoreDemoState.clone) return;
|
|
27792
|
-
agentStoreDemoState = {
|
|
27793
|
-
...agentStoreDemoState,
|
|
27794
|
-
phase: "idle",
|
|
27795
|
-
repositoryUrl: event?.target?.value || "",
|
|
27796
|
-
status: "",
|
|
27797
|
-
error: "",
|
|
27798
|
-
};
|
|
27799
|
-
renderAgentStoreDemo();
|
|
27800
|
-
}
|
|
27801
|
-
|
|
27802
|
-
function handleAgentStoreDemoRepositorySelect(event) {
|
|
27803
|
-
if (isAgentStoreDemoPending() || agentStoreDemoState.clone) return;
|
|
27804
|
-
const repositoryUrl = String(event?.target?.value || "").trim();
|
|
27805
|
-
if (!repositoryUrl) return;
|
|
27806
|
-
agentStoreDemoState = {
|
|
27807
|
-
...agentStoreDemoState,
|
|
27808
|
-
phase: "idle",
|
|
27809
|
-
repositoryUrl,
|
|
27810
|
-
status: "",
|
|
27811
|
-
error: "",
|
|
27812
|
-
};
|
|
27813
|
-
renderAgentStoreDemo();
|
|
27814
|
-
requestAnimationFrame(() => {
|
|
27815
|
-
$("agent-store-demo-url-input")?.focus({ preventScroll: true });
|
|
27816
|
-
});
|
|
27817
|
-
}
|
|
27818
|
-
|
|
27819
|
-
function handleAgentStoreDemoUrlKeyDown(event) {
|
|
27820
|
-
if (event?.key !== "Enter" || event.isComposing) return;
|
|
27821
|
-
event.preventDefault();
|
|
27822
|
-
if (!isAgentStoreDemoPending()) void submitAgentStoreDemo();
|
|
27823
|
-
}
|
|
27824
|
-
|
|
27825
|
-
function validateAgentStoreDemoUrl(value) {
|
|
27826
|
-
let parsed;
|
|
27827
|
-
try {
|
|
27828
|
-
parsed = new URL(String(value || "").trim());
|
|
27829
|
-
} catch {
|
|
27830
|
-
throw new Error("Enter a valid public GitHub HTTPS repository URL.");
|
|
27831
|
-
}
|
|
27832
|
-
if (
|
|
27833
|
-
parsed.protocol !== "https:" ||
|
|
27834
|
-
parsed.hostname.toLowerCase() !== "github.com" ||
|
|
27835
|
-
parsed.username ||
|
|
27836
|
-
parsed.password ||
|
|
27837
|
-
parsed.port ||
|
|
27838
|
-
parsed.search ||
|
|
27839
|
-
parsed.hash ||
|
|
27840
|
-
!/^\/[^/]+\/[^/]+\/?$/.test(parsed.pathname)
|
|
27841
|
-
) {
|
|
27842
|
-
throw new Error(
|
|
27843
|
-
"Only public https://github.com/<owner>/<repo> URLs are supported."
|
|
27844
|
-
);
|
|
27845
|
-
}
|
|
27846
|
-
return parsed.toString();
|
|
27847
|
-
}
|
|
27848
|
-
|
|
27849
|
-
async function getAgentStoreDemoProviderSkillInstallDecision({
|
|
27850
|
-
agentId,
|
|
27851
|
-
agentFolder,
|
|
27852
|
-
provider,
|
|
27853
|
-
}) {
|
|
27854
|
-
const params = new URLSearchParams({
|
|
27855
|
-
agent_id: agentId,
|
|
27856
|
-
agent_folder: agentFolder,
|
|
27857
|
-
provider,
|
|
27858
|
-
});
|
|
27859
|
-
try {
|
|
27860
|
-
const status = await apiWithAuthRetry(
|
|
27861
|
-
"GET",
|
|
27862
|
-
`/agent/provider-skill-status?${params.toString()}`
|
|
27863
|
-
);
|
|
27864
|
-
return (
|
|
27865
|
-
status?.default_checked === true &&
|
|
27866
|
-
status?.can_install === true &&
|
|
27867
|
-
status?.disabled !== true
|
|
27868
|
-
);
|
|
27869
|
-
} catch {
|
|
27870
|
-
return false;
|
|
27871
|
-
}
|
|
27872
|
-
}
|
|
27873
|
-
|
|
27874
|
-
function buildAgentStoreDemoSessionStartPayload({
|
|
27875
|
-
clone,
|
|
27876
|
-
folderConfig,
|
|
27877
|
-
installOysterunSkills,
|
|
27878
|
-
}) {
|
|
27879
|
-
const provider = String(folderConfig?.provider || "").trim();
|
|
27880
|
-
const model = String(folderConfig?.model || "").trim();
|
|
27881
|
-
if (!provider || !model) {
|
|
27882
|
-
throw new Error(
|
|
27883
|
-
"The cloned folder did not resolve a provider and model."
|
|
27884
|
-
);
|
|
27885
|
-
}
|
|
27886
|
-
const payload = {
|
|
27887
|
-
agent_id: clone.agent_id,
|
|
27888
|
-
agent_folder: clone.agent_folder,
|
|
27889
|
-
provider,
|
|
27890
|
-
model,
|
|
27891
|
-
interface_type: normalizeFirstPartyInterfaceType(
|
|
27892
|
-
folderConfig.interfaceType || "coding"
|
|
27893
|
-
),
|
|
27894
|
-
reasoning_effort: folderConfig.reasoningEffort || undefined,
|
|
27895
|
-
dangerous_mode: folderConfig.dangerousMode === true,
|
|
27896
|
-
allow_dangerously_skip_permissions:
|
|
27897
|
-
folderConfig.allowDangerouslySkipPermissions === true,
|
|
27898
|
-
install_oysterun_skills: installOysterunSkills === true,
|
|
27899
|
-
};
|
|
27900
|
-
if (provider === "claude") {
|
|
27901
|
-
payload.permission_mode = folderConfig.permissionMode;
|
|
27902
|
-
} else if (provider === "codex") {
|
|
27903
|
-
payload.approval_policy = folderConfig.approvalPolicy;
|
|
27904
|
-
}
|
|
27905
|
-
const proof = {
|
|
27906
|
-
...buildCreateSessionSetupProviderModelPermissionProof(payload),
|
|
27907
|
-
proof_surface: "visible_agent_store_clone_modal_state",
|
|
27908
|
-
};
|
|
27909
|
-
payload.session_setup_provider_model_permission_proof = proof;
|
|
27910
|
-
return { payload, proof };
|
|
27911
|
-
}
|
|
27912
|
-
|
|
27913
|
-
function finalizeAgentStoreDemoStartedSession(data, expectedProof) {
|
|
27914
|
-
const proofValidation =
|
|
27915
|
-
validateSessionSetupProviderModelPermissionProofResponse(
|
|
27916
|
-
data,
|
|
27917
|
-
expectedProof,
|
|
27918
|
-
{ requireCountableStartResponseProof: true }
|
|
27919
|
-
);
|
|
27920
|
-
if (!proofValidation.ok) {
|
|
27921
|
-
throw new Error(
|
|
27922
|
-
`Session Setup proof validation failed: ${proofValidation.errors.join(
|
|
27923
|
-
" "
|
|
27924
|
-
)}`
|
|
27925
|
-
);
|
|
27926
|
-
}
|
|
27927
|
-
const normalizedData = {
|
|
27928
|
-
...data,
|
|
27929
|
-
session_setup_provider_model_permission_proof: proofValidation.proof,
|
|
27930
|
-
};
|
|
27931
|
-
clearPendingAttachments();
|
|
27932
|
-
primeSelectedAgentFromStart(normalizedData);
|
|
27933
|
-
const startedLiveSession =
|
|
27934
|
-
upsertStartedSessionIntoLiveCatalog(normalizedData);
|
|
27935
|
-
invalidateDashboardDataCaches({
|
|
27936
|
-
catalog: true,
|
|
27937
|
-
sessions: true,
|
|
27938
|
-
history: true,
|
|
27939
|
-
transcripts: true,
|
|
27940
|
-
});
|
|
27941
|
-
if (
|
|
27942
|
-
!startedLiveSession ||
|
|
27943
|
-
startedLiveSession.sessionId !== normalizedData.session_id
|
|
27944
|
-
) {
|
|
27945
|
-
throw new Error(
|
|
27946
|
-
"Agent Store could not materialize the started Host session before opening chat."
|
|
27947
|
-
);
|
|
27948
|
-
}
|
|
27949
|
-
return normalizedData.session_id;
|
|
27950
|
-
}
|
|
27951
|
-
|
|
27952
|
-
async function submitAgentStoreDemo() {
|
|
27953
|
-
if (isAgentStoreDemoPending() || agentStoreDemoState.clone) return;
|
|
27954
|
-
const requestId = agentStoreDemoState.requestId + 1;
|
|
27955
|
-
agentStoreDemoState = {
|
|
27956
|
-
...agentStoreDemoState,
|
|
27957
|
-
phase: "validating",
|
|
27958
|
-
status: "Validating GitHub repository...",
|
|
27959
|
-
error: "",
|
|
27960
|
-
requestId,
|
|
27961
|
-
};
|
|
27962
|
-
renderAgentStoreDemo();
|
|
27963
|
-
|
|
27964
|
-
try {
|
|
27965
|
-
const repositoryUrl = validateAgentStoreDemoUrl(
|
|
27966
|
-
agentStoreDemoState.repositoryUrl
|
|
27967
|
-
);
|
|
27968
|
-
agentStoreDemoState = {
|
|
27969
|
-
...agentStoreDemoState,
|
|
27970
|
-
phase: "cloning",
|
|
27971
|
-
status: "Cloning the repository into Default Browse Root...",
|
|
27972
|
-
};
|
|
27973
|
-
renderAgentStoreDemo();
|
|
27974
|
-
const clone = await apiWithAuthRetry(
|
|
27975
|
-
"POST",
|
|
27976
|
-
"/agent-store/demo/clone",
|
|
27977
|
-
{ repository_url: repositoryUrl }
|
|
27978
|
-
);
|
|
27979
|
-
if (agentStoreDemoState.requestId !== requestId) return;
|
|
27980
|
-
|
|
27981
|
-
agentStoreDemoState = {
|
|
27982
|
-
...agentStoreDemoState,
|
|
27983
|
-
phase: "loading_config",
|
|
27984
|
-
status: "Loading the cloned agent configuration...",
|
|
27985
|
-
clone,
|
|
27986
|
-
};
|
|
27987
|
-
renderAgentStoreDemo();
|
|
27988
|
-
const folderConfig = await apiWithAuthRetry(
|
|
27989
|
-
"GET",
|
|
27990
|
-
`/dev/folder-config?path=${encodeURIComponent(clone.agent_folder)}`
|
|
27991
|
-
);
|
|
27992
|
-
if (agentStoreDemoState.requestId !== requestId) return;
|
|
27993
|
-
const installOysterunSkills =
|
|
27994
|
-
await getAgentStoreDemoProviderSkillInstallDecision({
|
|
27995
|
-
agentId: clone.agent_id,
|
|
27996
|
-
agentFolder: clone.agent_folder,
|
|
27997
|
-
provider: folderConfig.provider,
|
|
27998
|
-
});
|
|
27999
|
-
const { payload, proof } = buildAgentStoreDemoSessionStartPayload({
|
|
28000
|
-
clone,
|
|
28001
|
-
folderConfig,
|
|
28002
|
-
installOysterunSkills,
|
|
28003
|
-
});
|
|
28004
|
-
|
|
28005
|
-
agentStoreDemoState = {
|
|
28006
|
-
...agentStoreDemoState,
|
|
28007
|
-
phase: "starting_session",
|
|
28008
|
-
status: "Starting a session with the resolved agent settings...",
|
|
28009
|
-
};
|
|
28010
|
-
renderAgentStoreDemo();
|
|
28011
|
-
const data = await apiWithAuthRetry(
|
|
28012
|
-
"POST",
|
|
28013
|
-
"/session/start",
|
|
28014
|
-
payload
|
|
28015
|
-
);
|
|
28016
|
-
if (agentStoreDemoState.requestId !== requestId) return;
|
|
28017
|
-
const sessionId = finalizeAgentStoreDemoStartedSession(data, proof);
|
|
28018
|
-
closeAgentStoreDemo({ force: true });
|
|
28019
|
-
openRouteCForStartedSession(sessionId);
|
|
28020
|
-
} catch (err) {
|
|
28021
|
-
if (agentStoreDemoState.requestId !== requestId) return;
|
|
28022
|
-
const cloneComplete = Boolean(
|
|
28023
|
-
agentStoreDemoState.clone?.agent_folder
|
|
28024
|
-
);
|
|
28025
|
-
const detail = String(err?.data?.detail || "").trim();
|
|
28026
|
-
const message = cloneComplete
|
|
28027
|
-
? formatCreateStepError("Could not start session", err)
|
|
28028
|
-
: err?.message || "Could not clone the GitHub repository.";
|
|
28029
|
-
agentStoreDemoState = {
|
|
28030
|
-
...agentStoreDemoState,
|
|
28031
|
-
phase: cloneComplete ? "failed_after_clone" : "failed_before_clone",
|
|
28032
|
-
status: "",
|
|
28033
|
-
error: detail ? `${message}\n${detail}` : message,
|
|
28034
|
-
};
|
|
28035
|
-
renderAgentStoreDemo();
|
|
28036
|
-
}
|
|
28037
|
-
}
|
|
28038
|
-
|
|
28039
|
-
function openAgentStoreDemoSessionSetup() {
|
|
28040
|
-
const folder = agentStoreDemoState.clone?.agent_folder || "";
|
|
28041
|
-
if (!folder || isAgentStoreDemoPending()) return;
|
|
28042
|
-
closeAgentStoreDemo({ force: true });
|
|
28043
|
-
openCreateModal(folder);
|
|
28044
|
-
}
|
|
28045
|
-
|
|
28046
|
-
window.openAgentStoreDemo = openAgentStoreDemo;
|
|
28047
|
-
window.closeAgentStoreDemo = closeAgentStoreDemo;
|
|
28048
|
-
window.handleAgentStoreDemoUrlInput = handleAgentStoreDemoUrlInput;
|
|
28049
|
-
window.handleAgentStoreDemoRepositorySelect =
|
|
28050
|
-
handleAgentStoreDemoRepositorySelect;
|
|
28051
|
-
window.handleAgentStoreDemoUrlKeyDown = handleAgentStoreDemoUrlKeyDown;
|
|
28052
|
-
window.submitAgentStoreDemo = submitAgentStoreDemo;
|
|
28053
|
-
window.openAgentStoreDemoSessionSetup = openAgentStoreDemoSessionSetup;
|
|
28054
|
-
|
|
28055
27583
|
function getHostDefaultRuntime() {
|
|
28056
27584
|
return (
|
|
28057
27585
|
hostPreferencesState.effectiveDefaultProvider ||
|
|
@@ -30099,10 +29627,6 @@ Waiting for Claude login output…</pre
|
|
|
30099
29627
|
);
|
|
30100
29628
|
}
|
|
30101
29629
|
|
|
30102
|
-
function getConnectionModeLabel(mode) {
|
|
30103
|
-
return mode === "cloud" ? "Cloud" : "Direct";
|
|
30104
|
-
}
|
|
30105
|
-
|
|
30106
29630
|
function getCreateDefaultInterfaceType() {
|
|
30107
29631
|
return normalizeFirstPartyInterfaceType(
|
|
30108
29632
|
hostPreferencesState.interfaceType ||
|
|
@@ -31044,6 +30568,36 @@ Waiting for Claude login output…</pre
|
|
|
31044
30568
|
});
|
|
31045
30569
|
}
|
|
31046
30570
|
|
|
30571
|
+
function buildFolderSessionsRoute({ folder = "", returnPath = "" } = {}) {
|
|
30572
|
+
return normalizeClientRoute({
|
|
30573
|
+
screen: "folder-sessions",
|
|
30574
|
+
folder,
|
|
30575
|
+
returnPath,
|
|
30576
|
+
});
|
|
30577
|
+
}
|
|
30578
|
+
|
|
30579
|
+
// Resume Session returns only to the standalone Explorer location that
|
|
30580
|
+
// opened it, like File Preview and the folder picker's return_path.
|
|
30581
|
+
function normalizeFolderSessionsReturnPath(value) {
|
|
30582
|
+
const rawPath = sanitizeRouteText(value);
|
|
30583
|
+
if (!rawPath) return "";
|
|
30584
|
+
let resolvedPath;
|
|
30585
|
+
try {
|
|
30586
|
+
resolvedPath = new URL(rawPath, BASE);
|
|
30587
|
+
} catch {
|
|
30588
|
+
return "";
|
|
30589
|
+
}
|
|
30590
|
+
if (resolvedPath.origin !== BASE) return "";
|
|
30591
|
+
const pathname = resolvedPath.pathname.replace(/\/+$/, "") || "/";
|
|
30592
|
+
if (pathname !== "/app/explorer") return "";
|
|
30593
|
+
return `${pathname}${resolvedPath.search}`;
|
|
30594
|
+
}
|
|
30595
|
+
|
|
30596
|
+
function getFolderSessionsReturnTarget(route = getCurrentRoute()) {
|
|
30597
|
+
// Same fallback as File Preview: the standalone Explorer.
|
|
30598
|
+
return normalizeClientRoute(route).returnPath || "/app/explorer";
|
|
30599
|
+
}
|
|
30600
|
+
|
|
31047
30601
|
function buildSettingsRoute() {
|
|
31048
30602
|
return normalizeClientRoute({ screen: "host-preferences" });
|
|
31049
30603
|
}
|
|
@@ -31319,6 +30873,22 @@ Waiting for Claude login output…</pre
|
|
|
31319
30873
|
warning,
|
|
31320
30874
|
};
|
|
31321
30875
|
}
|
|
30876
|
+
if (screen === "folder-sessions") {
|
|
30877
|
+
const folder = sanitizeRouteText(route?.folder);
|
|
30878
|
+
if (!folder) {
|
|
30879
|
+
return buildSessionsRoute({
|
|
30880
|
+
warning:
|
|
30881
|
+
warning ||
|
|
30882
|
+
"Requested Resume Session page is missing a folder. Opening Sessions.",
|
|
30883
|
+
});
|
|
30884
|
+
}
|
|
30885
|
+
return {
|
|
30886
|
+
screen: "folder-sessions",
|
|
30887
|
+
folder,
|
|
30888
|
+
returnPath: normalizeFolderSessionsReturnPath(route?.returnPath),
|
|
30889
|
+
warning,
|
|
30890
|
+
};
|
|
30891
|
+
}
|
|
31322
30892
|
if (screen === "host-preferences") {
|
|
31323
30893
|
return { screen: "host-preferences", warning };
|
|
31324
30894
|
}
|
|
@@ -31554,6 +31124,12 @@ Waiting for Claude login output…</pre
|
|
|
31554
31124
|
url.searchParams.get("mode") === "branch" ? "branch" : "",
|
|
31555
31125
|
});
|
|
31556
31126
|
}
|
|
31127
|
+
if (pathname === "/app/folder-sessions") {
|
|
31128
|
+
return buildFolderSessionsRoute({
|
|
31129
|
+
folder: url.searchParams.get("folder") || "",
|
|
31130
|
+
returnPath: url.searchParams.get("return_path") || "",
|
|
31131
|
+
});
|
|
31132
|
+
}
|
|
31557
31133
|
if (pathname === "/app/settings") {
|
|
31558
31134
|
return buildSettingsRoute();
|
|
31559
31135
|
}
|
|
@@ -31687,6 +31263,12 @@ Waiting for Claude login output…</pre
|
|
|
31687
31263
|
}
|
|
31688
31264
|
}
|
|
31689
31265
|
}
|
|
31266
|
+
} else if (normalized.screen === "folder-sessions") {
|
|
31267
|
+
url.pathname = "/app/folder-sessions";
|
|
31268
|
+
url.searchParams.set("folder", normalized.folder);
|
|
31269
|
+
if (normalized.returnPath) {
|
|
31270
|
+
url.searchParams.set("return_path", normalized.returnPath);
|
|
31271
|
+
}
|
|
31690
31272
|
} else if (normalized.screen === "host-preferences") {
|
|
31691
31273
|
url.pathname = "/app/settings";
|
|
31692
31274
|
} else if (normalized.screen === "voice-input-usage") {
|
|
@@ -31978,6 +31560,11 @@ Waiting for Claude login output…</pre
|
|
|
31978
31560
|
} else if (normalized.screen === "voice-input-usage") {
|
|
31979
31561
|
renderHostVoiceInputUsageDetail();
|
|
31980
31562
|
await loadHostVoiceInputUsage();
|
|
31563
|
+
} else if (normalized.screen === "folder-sessions") {
|
|
31564
|
+
// Each page opening re-reads Resume eligibility, like a menu opening.
|
|
31565
|
+
folderSessionsResumeStates = new Map();
|
|
31566
|
+
renderFolderSessionsView();
|
|
31567
|
+
void hydrateSessionListPreviews();
|
|
31981
31568
|
} else if (normalized.screen === "change-password") {
|
|
31982
31569
|
renderChangePasswordView();
|
|
31983
31570
|
} else if (normalized.screen === "terminal") {
|
|
@@ -35307,9 +34894,34 @@ Waiting for Claude login output…</pre
|
|
|
35307
34894
|
const rollbackText = operation.rollback_result?.safe_message || "";
|
|
35308
34895
|
const recoveryText = operation.recovery_result?.safe_message || "";
|
|
35309
34896
|
const cleanupText = operation.cleanup_result?.safe_message || "";
|
|
35310
|
-
|
|
35311
|
-
|
|
35312
|
-
|
|
34897
|
+
// A repeated recovery attempt reports its own (latest) failure first;
|
|
34898
|
+
// the first failure stays visible as the root cause.
|
|
34899
|
+
const latestFailure = operation.latest_failure;
|
|
34900
|
+
const latestIsLater =
|
|
34901
|
+
latestFailure?.check &&
|
|
34902
|
+
latestFailure?.safe_message &&
|
|
34903
|
+
Date.parse(latestFailure.observed_at || "") >
|
|
34904
|
+
Date.parse(rootFailure.observed_at || "");
|
|
34905
|
+
const failureText = latestIsLater
|
|
34906
|
+
? `Latest attempt failed${(() => {
|
|
34907
|
+
const at = new Date(latestFailure.observed_at);
|
|
34908
|
+
return Number.isNaN(at.getTime())
|
|
34909
|
+
? ""
|
|
34910
|
+
: ` at ${at.toLocaleTimeString([], {
|
|
34911
|
+
hour: "numeric",
|
|
34912
|
+
minute: "2-digit",
|
|
34913
|
+
})}`;
|
|
34914
|
+
})()}: ${latestFailure.check} (stage: ${
|
|
34915
|
+
latestFailure.stage || "lifecycle"
|
|
34916
|
+
}). ${String(latestFailure.safe_message)
|
|
34917
|
+
.trim()
|
|
34918
|
+
.replace(/([^.!?])$/, "$1.")} First failure: ${
|
|
34919
|
+
rootFailure.check
|
|
34920
|
+
} (stage: ${rootFailure.stage || "lifecycle"}).`
|
|
34921
|
+
: `Failed check: ${rootFailure.check} (stage: ${
|
|
34922
|
+
rootFailure.stage || "lifecycle"
|
|
34923
|
+
}). ${rootFailure.safe_message}`;
|
|
34924
|
+
return `${failureText} ${restartText}${
|
|
35313
34925
|
rollbackText ? ` ${rollbackText}` : ""
|
|
35314
34926
|
}${recoveryText ? ` ${recoveryText}` : ""}${
|
|
35315
34927
|
cleanupText ? ` ${cleanupText}` : ""
|
|
@@ -36767,28 +36379,6 @@ Waiting for Claude login output…</pre
|
|
|
36767
36379
|
}
|
|
36768
36380
|
}
|
|
36769
36381
|
|
|
36770
|
-
async function copyHostPreferencesDirectHostUrl() {
|
|
36771
|
-
const value = String(
|
|
36772
|
-
$("host-public-base-url")?.value ||
|
|
36773
|
-
hostPreferencesState.publicBaseUrl ||
|
|
36774
|
-
""
|
|
36775
|
-
).trim();
|
|
36776
|
-
if (!value) {
|
|
36777
|
-
showToast("Direct Host URL is unavailable.", true, 3200);
|
|
36778
|
-
return;
|
|
36779
|
-
}
|
|
36780
|
-
try {
|
|
36781
|
-
await writeTextToClipboard(value);
|
|
36782
|
-
showToast("Copied Direct Host URL");
|
|
36783
|
-
} catch (err) {
|
|
36784
|
-
showToast(
|
|
36785
|
-
err.message || "Could not copy Direct Host URL.",
|
|
36786
|
-
true,
|
|
36787
|
-
4200
|
|
36788
|
-
);
|
|
36789
|
-
}
|
|
36790
|
-
}
|
|
36791
|
-
|
|
36792
36382
|
async function copyHostPreferencesManagedEndpoint() {
|
|
36793
36383
|
const value = String(
|
|
36794
36384
|
$("host-managed-endpoint")?.value ||
|
|
@@ -40803,6 +40393,12 @@ Waiting for Claude login output…</pre
|
|
|
40803
40393
|
subtitle: "",
|
|
40804
40394
|
};
|
|
40805
40395
|
}
|
|
40396
|
+
if (screen === "folder-sessions") {
|
|
40397
|
+
return {
|
|
40398
|
+
title: getPathLastComponent(normalized.folder) || normalized.folder,
|
|
40399
|
+
subtitle: "",
|
|
40400
|
+
};
|
|
40401
|
+
}
|
|
40806
40402
|
if (screen === "change-password") {
|
|
40807
40403
|
return {
|
|
40808
40404
|
title: "Change Password",
|
|
@@ -40896,7 +40492,6 @@ Waiting for Claude login output…</pre
|
|
|
40896
40492
|
setVisible("browser-site-next-btn", isBrowser);
|
|
40897
40493
|
setVisible("browser-site-share-btn", isBrowser);
|
|
40898
40494
|
setVisible("browser-site-exit-btn", isBrowser);
|
|
40899
|
-
setVisible("entry-agent-store-btn", screen === "sessions");
|
|
40900
40495
|
setVisible("entry-start-session-btn", screen === "sessions");
|
|
40901
40496
|
setVisible("topbar-scheduler-new-btn", isSchedulerList);
|
|
40902
40497
|
setVisible("topbar-scheduler-refresh-btn", isSchedulerList);
|
|
@@ -41148,7 +40743,12 @@ Waiting for Claude login output…</pre
|
|
|
41148
40743
|
|
|
41149
40744
|
function applyNavigationState() {
|
|
41150
40745
|
const screen = getCurrentScreen();
|
|
41151
|
-
const collectionSurface = [
|
|
40746
|
+
const collectionSurface = [
|
|
40747
|
+
"sessions",
|
|
40748
|
+
"folder-sessions",
|
|
40749
|
+
"web",
|
|
40750
|
+
"mail",
|
|
40751
|
+
].includes(screen)
|
|
41152
40752
|
? screen
|
|
41153
40753
|
: "";
|
|
41154
40754
|
recordHostTelemetryFeatureView(getCurrentRoute());
|
|
@@ -41156,6 +40756,10 @@ Waiting for Claude login output…</pre
|
|
|
41156
40756
|
closeSessionLoopActionMenu();
|
|
41157
40757
|
closeHostSchedulerActionMenu();
|
|
41158
40758
|
$("entry-view").classList.toggle("active", screen === "sessions");
|
|
40759
|
+
$("folder-sessions-view").classList.toggle(
|
|
40760
|
+
"active",
|
|
40761
|
+
screen === "folder-sessions"
|
|
40762
|
+
);
|
|
41159
40763
|
$("web-view").classList.toggle("active", screen === "web");
|
|
41160
40764
|
$("mail-view").classList.toggle("active", screen === "mail");
|
|
41161
40765
|
$("dashboard-workspace")?.classList.toggle(
|
|
@@ -41207,6 +40811,14 @@ Waiting for Claude login output…</pre
|
|
|
41207
40811
|
screen === "tool-detail"
|
|
41208
40812
|
);
|
|
41209
40813
|
$("browser-view").classList.toggle("active", screen === "browser");
|
|
40814
|
+
// The shared row menu layer is outside every page; close it when its
|
|
40815
|
+
// row is no longer on the visible page.
|
|
40816
|
+
if (
|
|
40817
|
+
sessionActionMenuState &&
|
|
40818
|
+
!sessionActionMenuState.anchorButton?.closest?.(".view.active")
|
|
40819
|
+
) {
|
|
40820
|
+
closeSessionActionMenu();
|
|
40821
|
+
}
|
|
41210
40822
|
if (screen === "explorer") {
|
|
41211
40823
|
renderExplorerContextChrome();
|
|
41212
40824
|
}
|
|
@@ -41395,6 +41007,14 @@ Waiting for Claude login output…</pre
|
|
|
41395
41007
|
|
|
41396
41008
|
function handleTopbarBack() {
|
|
41397
41009
|
const currentBackRoute = getCurrentRoute();
|
|
41010
|
+
if (currentBackRoute.screen === "folder-sessions") {
|
|
41011
|
+
// Explorer is a separate document; return to the exact page that
|
|
41012
|
+
// opened Resume Session, as the folder picker does.
|
|
41013
|
+
window.location.assign(
|
|
41014
|
+
getFolderSessionsReturnTarget(currentBackRoute)
|
|
41015
|
+
);
|
|
41016
|
+
return;
|
|
41017
|
+
}
|
|
41398
41018
|
if (navigatePreviousPageRouteMapFallback(currentBackRoute)) {
|
|
41399
41019
|
return;
|
|
41400
41020
|
}
|
|
@@ -41437,7 +41057,6 @@ Waiting for Claude login output…</pre
|
|
|
41437
41057
|
"browse-context-menu",
|
|
41438
41058
|
"picker-modal-backdrop",
|
|
41439
41059
|
"browse-create-folder-backdrop",
|
|
41440
|
-
"agent-store-demo-backdrop",
|
|
41441
41060
|
"provider-auth-backdrop",
|
|
41442
41061
|
"chat-image-preview-backdrop",
|
|
41443
41062
|
"command-palette",
|
|
@@ -42079,7 +41698,7 @@ Waiting for Claude login output…</pre
|
|
|
42079
41698
|
$("model-hint").textContent =
|
|
42080
41699
|
"Spillover Fake deterministic count model for P82 verification.";
|
|
42081
41700
|
$("runtime-hint").textContent =
|
|
42082
|
-
"Uses the hidden P82 Spillover Fake provider. It is available only when Host config
|
|
41701
|
+
"Uses the hidden P82 Spillover Fake provider. It is available only when Host config/debug.json enables large tool spillover verification.";
|
|
42083
41702
|
} else if (createRuntime === "debug-p135-codex-replay") {
|
|
42084
41703
|
modelSelect.disabled = modelSelection.options.length === 0;
|
|
42085
41704
|
if (claudeReasoningEffortSelect) {
|
|
@@ -42091,7 +41710,7 @@ Waiting for Claude login output…</pre
|
|
|
42091
41710
|
$("model-hint").textContent =
|
|
42092
41711
|
"P135 Codex Replay deterministic fixture model.";
|
|
42093
41712
|
$("runtime-hint").textContent =
|
|
42094
|
-
"Uses the hidden P135 Codex Replay provider. It is available only when Host config
|
|
41713
|
+
"Uses the hidden P135 Codex Replay provider. It is available only when Host config/debug.json enables replay verification.";
|
|
42095
41714
|
}
|
|
42096
41715
|
|
|
42097
41716
|
if (opts.applyDefaults !== false) {
|
|
@@ -42183,6 +41802,8 @@ Waiting for Claude login output…</pre
|
|
|
42183
41802
|
showError("login-error", "");
|
|
42184
41803
|
showLoginNotice("Opening Oysterun...");
|
|
42185
41804
|
setLoginBusy(true, "Opening…");
|
|
41805
|
+
// Fixed internal account name, never a user input: a P296 Host ignores
|
|
41806
|
+
// it, while an older Host (e.g. after a rolled-back update) requires it.
|
|
42186
41807
|
const username = "admin";
|
|
42187
41808
|
const password = $("login-pass").value;
|
|
42188
41809
|
try {
|
|
@@ -43397,6 +43018,7 @@ Waiting for Claude login output…</pre
|
|
|
43397
43018
|
session_tags_error: entry.session_tags_error ?? null,
|
|
43398
43019
|
session_tag_labels_error: entry.session_tag_labels_error ?? null,
|
|
43399
43020
|
agent_folder: entry.agent_folder,
|
|
43021
|
+
agent_folder_real_path: entry.agent_folder_real_path,
|
|
43400
43022
|
runtime: entry.runtime,
|
|
43401
43023
|
model: entry.model,
|
|
43402
43024
|
created_at: entry.started_at,
|
|
@@ -43646,6 +43268,15 @@ Waiting for Claude login output…</pre
|
|
|
43646
43268
|
return menuItems.find((item) => item.disabled !== true)?.action || "";
|
|
43647
43269
|
}
|
|
43648
43270
|
|
|
43271
|
+
// Sessions and Resume Session can both hold a History row for the same
|
|
43272
|
+
// Session; prefer the copy in the visible page.
|
|
43273
|
+
function querySessionRowElement(selector) {
|
|
43274
|
+
return (
|
|
43275
|
+
document.querySelector(`.view.active ${selector}`) ||
|
|
43276
|
+
document.querySelector(selector)
|
|
43277
|
+
);
|
|
43278
|
+
}
|
|
43279
|
+
|
|
43649
43280
|
function closeSessionActionMenu(opts = {}) {
|
|
43650
43281
|
const layer = $("session-action-menu-layer");
|
|
43651
43282
|
if (layer) {
|
|
@@ -43655,7 +43286,7 @@ Waiting for Claude login output…</pre
|
|
|
43655
43286
|
const closingState = sessionActionMenuState;
|
|
43656
43287
|
closingState?.expandedButton?.setAttribute?.("aria-expanded", "false");
|
|
43657
43288
|
const currentExpandedButton = closingState?.sessionId
|
|
43658
|
-
?
|
|
43289
|
+
? querySessionRowElement(
|
|
43659
43290
|
`[data-session-action-menu-session-id="${CSS.escape(
|
|
43660
43291
|
closingState.sessionId
|
|
43661
43292
|
)}"]`
|
|
@@ -43674,7 +43305,7 @@ Waiting for Claude login output…</pre
|
|
|
43674
43305
|
closingState.kind === "history"
|
|
43675
43306
|
? "data-history-session-id"
|
|
43676
43307
|
: "data-live-session-id";
|
|
43677
|
-
const currentRow =
|
|
43308
|
+
const currentRow = querySessionRowElement(
|
|
43678
43309
|
`[${rowAttribute}="${CSS.escape(closingState.sessionId)}"]`
|
|
43679
43310
|
);
|
|
43680
43311
|
focusTarget =
|
|
@@ -43875,6 +43506,8 @@ Waiting for Claude login output…</pre
|
|
|
43875
43506
|
liveSession.agentFolder ||
|
|
43876
43507
|
liveSession.agent_folder ||
|
|
43877
43508
|
"",
|
|
43509
|
+
// A running Session has no Host-resolved History folder location.
|
|
43510
|
+
agent_folder_real_path: null,
|
|
43878
43511
|
runtime: liveSession.provider || liveSession.runtime || null,
|
|
43879
43512
|
model: liveSession.model || null,
|
|
43880
43513
|
// Only editable setup values cross this boundary. Native/thread,
|
|
@@ -44065,6 +43698,53 @@ Waiting for Claude login output…</pre
|
|
|
44065
43698
|
});
|
|
44066
43699
|
}
|
|
44067
43700
|
|
|
43701
|
+
// Shared History Resume eligibility. The Sessions row menu and the
|
|
43702
|
+
// folder Session page buttons use the same pre-check and settle rules.
|
|
43703
|
+
function getHistoryResumePreCheckState(sessionId) {
|
|
43704
|
+
const historyRecord = getHistorySessionRecord(sessionId);
|
|
43705
|
+
const desiredRestore = getDesiredOpenRestoreSession(sessionId);
|
|
43706
|
+
if (historyRecord?.restore_failed !== true) {
|
|
43707
|
+
failedResumeAvailabilityBySession.delete(sessionId);
|
|
43708
|
+
}
|
|
43709
|
+
return desiredRestore &&
|
|
43710
|
+
desiredRestore.state !== "failed" &&
|
|
43711
|
+
desiredRestore.state !== "ready"
|
|
43712
|
+
? "restoring"
|
|
43713
|
+
: "";
|
|
43714
|
+
}
|
|
43715
|
+
|
|
43716
|
+
function settleHistoryResumeState(sessionId, resumeCheckFailed) {
|
|
43717
|
+
const historyRecord = getHistorySessionRecord(sessionId);
|
|
43718
|
+
let resumeState = resumeCheckFailed
|
|
43719
|
+
? "retry"
|
|
43720
|
+
: historySessionCanResume(sessionId)
|
|
43721
|
+
? "supported"
|
|
43722
|
+
: "unavailable";
|
|
43723
|
+
if (historyRecord?.restore_failed === true && !resumeCheckFailed) {
|
|
43724
|
+
const signature = historyResumeAvailabilitySignature(sessionId);
|
|
43725
|
+
const previous = failedResumeAvailabilityBySession.get(sessionId);
|
|
43726
|
+
const availabilityChanged =
|
|
43727
|
+
previous && previous.signature !== signature;
|
|
43728
|
+
const unlocked = Boolean(previous?.unlocked || availabilityChanged);
|
|
43729
|
+
failedResumeAvailabilityBySession.set(sessionId, {
|
|
43730
|
+
signature,
|
|
43731
|
+
unlocked,
|
|
43732
|
+
});
|
|
43733
|
+
// A failed provider Resume stays disabled on this check. A later
|
|
43734
|
+
// check may offer Resume Chat only after availability changes and
|
|
43735
|
+
// the full transcript/provider eligibility check passes.
|
|
43736
|
+
if (
|
|
43737
|
+
!unlocked &&
|
|
43738
|
+
!isDeterministicRestoreUnavailableReason(
|
|
43739
|
+
historyRecord.restore_failed_reason
|
|
43740
|
+
)
|
|
43741
|
+
) {
|
|
43742
|
+
resumeState = "unavailable";
|
|
43743
|
+
}
|
|
43744
|
+
}
|
|
43745
|
+
return resumeState;
|
|
43746
|
+
}
|
|
43747
|
+
|
|
44068
43748
|
function canSettleSessionActionMenu(openedState, currentState, signal) {
|
|
44069
43749
|
return currentState === openedState && signal?.aborted !== true;
|
|
44070
43750
|
}
|
|
@@ -44275,15 +43955,8 @@ Waiting for Claude login output…</pre
|
|
|
44275
43955
|
installSessionActionMenuEnvironmentalDismissHandlers();
|
|
44276
43956
|
if (normalizedKind === "history") {
|
|
44277
43957
|
const historyRecord = getHistorySessionRecord(normalizedSessionId);
|
|
44278
|
-
const desiredRestore =
|
|
44279
|
-
getDesiredOpenRestoreSession(normalizedSessionId);
|
|
44280
|
-
if (historyRecord?.restore_failed !== true) {
|
|
44281
|
-
failedResumeAvailabilityBySession.delete(normalizedSessionId);
|
|
44282
|
-
}
|
|
44283
43958
|
if (
|
|
44284
|
-
|
|
44285
|
-
desiredRestore.state !== "failed" &&
|
|
44286
|
-
desiredRestore.state !== "ready"
|
|
43959
|
+
getHistoryResumePreCheckState(normalizedSessionId) === "restoring"
|
|
44287
43960
|
) {
|
|
44288
43961
|
renderOpenSessionActionMenu(
|
|
44289
43962
|
anchorButton,
|
|
@@ -44361,35 +44034,10 @@ Waiting for Claude login output…</pre
|
|
|
44361
44034
|
) {
|
|
44362
44035
|
return;
|
|
44363
44036
|
}
|
|
44364
|
-
|
|
44365
|
-
|
|
44366
|
-
|
|
44367
|
-
|
|
44368
|
-
: "unavailable";
|
|
44369
|
-
if (historyRecord?.restore_failed === true && !resumeCheckFailed) {
|
|
44370
|
-
const signature =
|
|
44371
|
-
historyResumeAvailabilitySignature(normalizedSessionId);
|
|
44372
|
-
const previous =
|
|
44373
|
-
failedResumeAvailabilityBySession.get(normalizedSessionId);
|
|
44374
|
-
const availabilityChanged =
|
|
44375
|
-
previous && previous.signature !== signature;
|
|
44376
|
-
const unlocked = Boolean(previous?.unlocked || availabilityChanged);
|
|
44377
|
-
failedResumeAvailabilityBySession.set(normalizedSessionId, {
|
|
44378
|
-
signature,
|
|
44379
|
-
unlocked,
|
|
44380
|
-
});
|
|
44381
|
-
// A failed provider Resume stays disabled on this menu opening.
|
|
44382
|
-
// A later opening may offer Resume Chat only after availability
|
|
44383
|
-
// changes and the full transcript/provider eligibility check passes.
|
|
44384
|
-
if (
|
|
44385
|
-
!unlocked &&
|
|
44386
|
-
!isDeterministicRestoreUnavailableReason(
|
|
44387
|
-
historyRecord.restore_failed_reason
|
|
44388
|
-
)
|
|
44389
|
-
) {
|
|
44390
|
-
resumeState = "unavailable";
|
|
44391
|
-
}
|
|
44392
|
-
}
|
|
44037
|
+
const resumeState = settleHistoryResumeState(
|
|
44038
|
+
normalizedSessionId,
|
|
44039
|
+
resumeCheckFailed
|
|
44040
|
+
);
|
|
44393
44041
|
openedMenuState.resumeState = resumeState;
|
|
44394
44042
|
renderOpenSessionActionMenu(
|
|
44395
44043
|
anchorButton,
|
|
@@ -44662,7 +44310,11 @@ Waiting for Claude login output…</pre
|
|
|
44662
44310
|
`;
|
|
44663
44311
|
}
|
|
44664
44312
|
|
|
44665
|
-
|
|
44313
|
+
// `inlineActions` (folder Session page) replaces the row-menu trigger
|
|
44314
|
+
// with a non-interactive row body plus the given inline action buttons.
|
|
44315
|
+
function renderHistorySessionRow(record, opts = {}) {
|
|
44316
|
+
const inlineActions =
|
|
44317
|
+
typeof opts.inlineActions === "string" ? opts.inlineActions : null;
|
|
44666
44318
|
const runtime = record.runtime || "claude";
|
|
44667
44319
|
const model = record.model || "default model";
|
|
44668
44320
|
const displayName = getHistorySessionDisplayName(record);
|
|
@@ -44681,30 +44333,7 @@ Waiting for Claude login output…</pre
|
|
|
44681
44333
|
const expanded =
|
|
44682
44334
|
sessionActionMenuState?.sessionId === record.session_id &&
|
|
44683
44335
|
sessionActionMenuState?.kind === "history";
|
|
44684
|
-
|
|
44685
|
-
<article
|
|
44686
|
-
class="collection-row session-list-row session-list-row-history"
|
|
44687
|
-
data-history-session-id="${esc(record.session_id)}"
|
|
44688
|
-
data-agent-id="${esc(record.agent_id)}"
|
|
44689
|
-
data-session-preview-status="${esc(
|
|
44690
|
-
previewState?.status || "loading"
|
|
44691
|
-
)}"
|
|
44692
|
-
data-completed-session-unread="${unread ? "true" : "false"}"
|
|
44693
|
-
>
|
|
44694
|
-
<button
|
|
44695
|
-
class="collection-row-main session-row-main"
|
|
44696
|
-
type="button"
|
|
44697
|
-
data-session-action-menu-session-id="${esc(record.session_id)}"
|
|
44698
|
-
data-session-action-menu-kind="history"
|
|
44699
|
-
aria-haspopup="menu"
|
|
44700
|
-
aria-expanded="${String(expanded)}"
|
|
44701
|
-
aria-label="Session actions for ${esc(displayName)}${
|
|
44702
|
-
unread ? ", unread completed message" : ""
|
|
44703
|
-
}"
|
|
44704
|
-
data-session-base-aria-label="Session actions for ${esc(
|
|
44705
|
-
displayName
|
|
44706
|
-
)}"
|
|
44707
|
-
>
|
|
44336
|
+
const rowBody = `
|
|
44708
44337
|
${renderSessionUnreadSlot(unread)}
|
|
44709
44338
|
${renderSessionAvatar(runtime, false)}
|
|
44710
44339
|
<span class="collection-row-copy session-row-copy">
|
|
@@ -44728,7 +44357,38 @@ Waiting for Claude login output…</pre
|
|
|
44728
44357
|
</span>
|
|
44729
44358
|
${renderSessionTagDiagnostic(record)}
|
|
44730
44359
|
</span>
|
|
44731
|
-
|
|
44360
|
+
`;
|
|
44361
|
+
return `
|
|
44362
|
+
<article
|
|
44363
|
+
class="collection-row session-list-row session-list-row-history${
|
|
44364
|
+
inlineActions === null ? "" : " session-list-row-inline-actions"
|
|
44365
|
+
}"
|
|
44366
|
+
data-history-session-id="${esc(record.session_id)}"
|
|
44367
|
+
data-agent-id="${esc(record.agent_id)}"
|
|
44368
|
+
data-session-preview-status="${esc(
|
|
44369
|
+
previewState?.status || "loading"
|
|
44370
|
+
)}"
|
|
44371
|
+
data-completed-session-unread="${unread ? "true" : "false"}"
|
|
44372
|
+
>
|
|
44373
|
+
${
|
|
44374
|
+
inlineActions === null
|
|
44375
|
+
? `<button
|
|
44376
|
+
class="collection-row-main session-row-main"
|
|
44377
|
+
type="button"
|
|
44378
|
+
data-session-action-menu-session-id="${esc(record.session_id)}"
|
|
44379
|
+
data-session-action-menu-kind="history"
|
|
44380
|
+
aria-haspopup="menu"
|
|
44381
|
+
aria-expanded="${String(expanded)}"
|
|
44382
|
+
aria-label="Session actions for ${esc(displayName)}${
|
|
44383
|
+
unread ? ", unread completed message" : ""
|
|
44384
|
+
}"
|
|
44385
|
+
data-session-base-aria-label="Session actions for ${esc(
|
|
44386
|
+
displayName
|
|
44387
|
+
)}"
|
|
44388
|
+
>${rowBody}</button>`
|
|
44389
|
+
: `<div class="collection-row-main session-row-main">${rowBody}</div>
|
|
44390
|
+
<div class="session-row-inline-actions">${inlineActions}</div>`
|
|
44391
|
+
}
|
|
44732
44392
|
</article>
|
|
44733
44393
|
`;
|
|
44734
44394
|
}
|
|
@@ -44797,7 +44457,262 @@ Waiting for Claude login output…</pre
|
|
|
44797
44457
|
</section>`;
|
|
44798
44458
|
}
|
|
44799
44459
|
|
|
44460
|
+
// Resume Session compares real filesystem locations: the chosen folder
|
|
44461
|
+
// is resolved by the Host and each History row carries the Host-resolved
|
|
44462
|
+
// agent_folder_real_path, so path spelling, aliases and symlinks match.
|
|
44463
|
+
let folderSessionsFolderResolution = {
|
|
44464
|
+
folder: "",
|
|
44465
|
+
realPath: "",
|
|
44466
|
+
error: "",
|
|
44467
|
+
};
|
|
44468
|
+
|
|
44469
|
+
function resolveFolderSessionsFolder(folder) {
|
|
44470
|
+
if (folderSessionsFolderResolution.folder === folder) {
|
|
44471
|
+
return folderSessionsFolderResolution;
|
|
44472
|
+
}
|
|
44473
|
+
const resolution = { folder, realPath: "", error: "" };
|
|
44474
|
+
folderSessionsFolderResolution = resolution;
|
|
44475
|
+
apiWithAuthRetry("POST", "/dev/folders/validate", { path: folder })
|
|
44476
|
+
.then((result) => {
|
|
44477
|
+
const realPath = sanitizeRouteText(result?.path);
|
|
44478
|
+
if (!realPath) {
|
|
44479
|
+
throw new Error("Folder validation did not return a real path.");
|
|
44480
|
+
}
|
|
44481
|
+
resolution.realPath = realPath;
|
|
44482
|
+
})
|
|
44483
|
+
.catch((err) => {
|
|
44484
|
+
resolution.error = err?.message || String(err);
|
|
44485
|
+
showBanner(
|
|
44486
|
+
`Could not resolve this folder: ${resolution.error}`,
|
|
44487
|
+
true
|
|
44488
|
+
);
|
|
44489
|
+
})
|
|
44490
|
+
.finally(() => {
|
|
44491
|
+
if (folderSessionsFolderResolution === resolution) {
|
|
44492
|
+
renderFolderSessionsView();
|
|
44493
|
+
}
|
|
44494
|
+
});
|
|
44495
|
+
return resolution;
|
|
44496
|
+
}
|
|
44497
|
+
|
|
44498
|
+
function getFolderSessionsHistoryRecords(folderRealPath) {
|
|
44499
|
+
const liveSessionIds = new Set(
|
|
44500
|
+
liveSessions.map((entry) => entry.sessionId)
|
|
44501
|
+
);
|
|
44502
|
+
return sessionHistory.filter((record) => {
|
|
44503
|
+
if (liveSessionIds.has(record.session_id)) return false;
|
|
44504
|
+
if (record.agent_folder_real_path === undefined) {
|
|
44505
|
+
throw new Error(
|
|
44506
|
+
`History Session ${record.session_id} is missing agent_folder_real_path.`
|
|
44507
|
+
);
|
|
44508
|
+
}
|
|
44509
|
+
return record.agent_folder_real_path === folderRealPath;
|
|
44510
|
+
});
|
|
44511
|
+
}
|
|
44512
|
+
|
|
44513
|
+
// Resume button state per Session on the folder Session page: one forced
|
|
44514
|
+
// eligibility read per agent, settled with the shared History rules.
|
|
44515
|
+
let folderSessionsResumeStates = new Map();
|
|
44516
|
+
|
|
44517
|
+
function checkFolderSessionsResume(records, opts = {}) {
|
|
44518
|
+
const pending = records.filter(
|
|
44519
|
+
(record) =>
|
|
44520
|
+
opts.force === true ||
|
|
44521
|
+
!folderSessionsResumeStates.has(record.session_id)
|
|
44522
|
+
);
|
|
44523
|
+
const checksByAgent = new Map();
|
|
44524
|
+
for (const record of pending) {
|
|
44525
|
+
if (
|
|
44526
|
+
getHistoryResumePreCheckState(record.session_id) === "restoring"
|
|
44527
|
+
) {
|
|
44528
|
+
folderSessionsResumeStates.set(record.session_id, {
|
|
44529
|
+
resumeState: "restoring",
|
|
44530
|
+
});
|
|
44531
|
+
continue;
|
|
44532
|
+
}
|
|
44533
|
+
folderSessionsResumeStates.set(record.session_id, {
|
|
44534
|
+
resumeState: "checking",
|
|
44535
|
+
});
|
|
44536
|
+
const group = checksByAgent.get(record.agent_id) || [];
|
|
44537
|
+
group.push(record.session_id);
|
|
44538
|
+
checksByAgent.set(record.agent_id, group);
|
|
44539
|
+
}
|
|
44540
|
+
for (const sessionIds of checksByAgent.values()) {
|
|
44541
|
+
const checkingPresentation =
|
|
44542
|
+
waitForHistoryResumeCheckingPresentation();
|
|
44543
|
+
void validateHistorySessionResumeMembership(sessionIds[0], {
|
|
44544
|
+
force: true,
|
|
44545
|
+
})
|
|
44546
|
+
.then(
|
|
44547
|
+
() => ({ failed: false, timedOut: false }),
|
|
44548
|
+
(err) => {
|
|
44549
|
+
console.warn(
|
|
44550
|
+
"[oysterun-ui] Could not check folder Session Resume",
|
|
44551
|
+
err
|
|
44552
|
+
);
|
|
44553
|
+
return {
|
|
44554
|
+
failed: true,
|
|
44555
|
+
timedOut: err?.code === "history_resume_check_timeout",
|
|
44556
|
+
};
|
|
44557
|
+
}
|
|
44558
|
+
)
|
|
44559
|
+
.then(async (result) => {
|
|
44560
|
+
await checkingPresentation;
|
|
44561
|
+
for (const sessionId of sessionIds) {
|
|
44562
|
+
if (
|
|
44563
|
+
folderSessionsResumeStates.get(sessionId)?.resumeState !==
|
|
44564
|
+
"checking"
|
|
44565
|
+
)
|
|
44566
|
+
continue;
|
|
44567
|
+
const resumeState = settleHistoryResumeState(
|
|
44568
|
+
sessionId,
|
|
44569
|
+
result.failed
|
|
44570
|
+
);
|
|
44571
|
+
folderSessionsResumeStates.set(sessionId, {
|
|
44572
|
+
resumeState,
|
|
44573
|
+
resumeCheckTimedOut: result.timedOut,
|
|
44574
|
+
resumeUnavailableReason:
|
|
44575
|
+
resumeState === "unavailable"
|
|
44576
|
+
? historySessionResumeMenuUnavailableReason(sessionId)
|
|
44577
|
+
: "",
|
|
44578
|
+
});
|
|
44579
|
+
}
|
|
44580
|
+
renderFolderSessionsView();
|
|
44581
|
+
});
|
|
44582
|
+
}
|
|
44583
|
+
}
|
|
44584
|
+
|
|
44585
|
+
function renderFolderSessionsActionButton(item) {
|
|
44586
|
+
const accessibleLabel = [item.label, item.reason]
|
|
44587
|
+
.filter(Boolean)
|
|
44588
|
+
.join(". ");
|
|
44589
|
+
const disabled = item.disabled === true;
|
|
44590
|
+
return `
|
|
44591
|
+
<button
|
|
44592
|
+
class="session-row-inline-action"
|
|
44593
|
+
type="button"
|
|
44594
|
+
data-folder-sessions-action="${esc(item.action)}"
|
|
44595
|
+
${
|
|
44596
|
+
item.resumeState
|
|
44597
|
+
? `data-history-resume-state="${esc(item.resumeState)}"`
|
|
44598
|
+
: ""
|
|
44599
|
+
}
|
|
44600
|
+
aria-label="${esc(accessibleLabel)}"
|
|
44601
|
+
title="${esc(accessibleLabel)}"
|
|
44602
|
+
aria-disabled="${String(disabled)}"
|
|
44603
|
+
${disabled ? "disabled" : ""}
|
|
44604
|
+
>
|
|
44605
|
+
<span class="session-row-menu-action-icon">${renderSessionActionIcon(
|
|
44606
|
+
item.icon
|
|
44607
|
+
)}</span>
|
|
44608
|
+
</button>
|
|
44609
|
+
`;
|
|
44610
|
+
}
|
|
44611
|
+
|
|
44612
|
+
// Inline Resume and Duplicate Setup use the History menu items, so labels,
|
|
44613
|
+
// enablement and unavailable reasons match the Sessions row menu.
|
|
44614
|
+
function renderFolderSessionsRowActions(record) {
|
|
44615
|
+
const state = folderSessionsResumeStates.get(record.session_id) || {
|
|
44616
|
+
resumeState: "checking",
|
|
44617
|
+
};
|
|
44618
|
+
const items = getSessionActionMenuItems("history", record.session_id, {
|
|
44619
|
+
resumeState: state.resumeState,
|
|
44620
|
+
resumeCheckTimedOut: state.resumeCheckTimedOut === true,
|
|
44621
|
+
resumeUnavailableReason: state.resumeUnavailableReason || "",
|
|
44622
|
+
});
|
|
44623
|
+
const resumeItem = items.find((item) => item.resumeState);
|
|
44624
|
+
const duplicateItem = items.find((item) => item.action === "duplicate");
|
|
44625
|
+
if (!resumeItem || !duplicateItem) {
|
|
44626
|
+
throw new Error(
|
|
44627
|
+
"History actions must include Resume and Duplicate Setup."
|
|
44628
|
+
);
|
|
44629
|
+
}
|
|
44630
|
+
return [resumeItem, duplicateItem]
|
|
44631
|
+
.map(renderFolderSessionsActionButton)
|
|
44632
|
+
.join("");
|
|
44633
|
+
}
|
|
44634
|
+
|
|
44635
|
+
function wireFolderSessionsView(container, folder) {
|
|
44636
|
+
container
|
|
44637
|
+
.querySelector("[data-folder-sessions-new-session]")
|
|
44638
|
+
?.addEventListener("click", () => {
|
|
44639
|
+
void navigateToRoute(buildSessionSetupRoute({ folder }));
|
|
44640
|
+
});
|
|
44641
|
+
for (const button of container.querySelectorAll(
|
|
44642
|
+
"[data-folder-sessions-action]"
|
|
44643
|
+
)) {
|
|
44644
|
+
button.addEventListener("click", () => {
|
|
44645
|
+
const sessionId =
|
|
44646
|
+
button.closest("[data-history-session-id]")?.dataset
|
|
44647
|
+
.historySessionId || "";
|
|
44648
|
+
const action = button.dataset.folderSessionsAction;
|
|
44649
|
+
if (!sessionId) return;
|
|
44650
|
+
if (action === "resume") {
|
|
44651
|
+
void openHistorySession(sessionId, { resume: true });
|
|
44652
|
+
} else if (action === "duplicate") {
|
|
44653
|
+
void openHistorySession(sessionId, { resume: false });
|
|
44654
|
+
} else if (action === "retry_resume_check") {
|
|
44655
|
+
// Retries only the availability read, never provider Resume.
|
|
44656
|
+
const record = getHistorySessionRecord(sessionId);
|
|
44657
|
+
if (record) checkFolderSessionsResume([record], { force: true });
|
|
44658
|
+
renderFolderSessionsView();
|
|
44659
|
+
}
|
|
44660
|
+
});
|
|
44661
|
+
}
|
|
44662
|
+
}
|
|
44663
|
+
|
|
44664
|
+
function renderFolderSessionsView() {
|
|
44665
|
+
const route = normalizeClientRoute(getCurrentRoute());
|
|
44666
|
+
const container = $("folder-sessions-list");
|
|
44667
|
+
if (route.screen !== "folder-sessions" || !container) return;
|
|
44668
|
+
const resolution = resolveFolderSessionsFolder(route.folder);
|
|
44669
|
+
const historyLoaded = Boolean(dashboardAppliedCollectionIdentity);
|
|
44670
|
+
const ready = historyLoaded && Boolean(resolution.realPath);
|
|
44671
|
+
const records = ready
|
|
44672
|
+
? getFolderSessionsHistoryRecords(resolution.realPath)
|
|
44673
|
+
: [];
|
|
44674
|
+
if (records.length) checkFolderSessionsResume(records);
|
|
44675
|
+
const historyRows = records
|
|
44676
|
+
.map((record) =>
|
|
44677
|
+
renderHistorySessionRow(record, {
|
|
44678
|
+
inlineActions: renderFolderSessionsRowActions(record),
|
|
44679
|
+
})
|
|
44680
|
+
)
|
|
44681
|
+
.join("");
|
|
44682
|
+
container.dataset.folderSessionsFolder = route.folder;
|
|
44683
|
+
container.dataset.folderSessionsFolderRealPath = resolution.realPath;
|
|
44684
|
+
container.innerHTML = `
|
|
44685
|
+
<div class="folder-sessions-intro">
|
|
44686
|
+
<div class="surface-action-row">
|
|
44687
|
+
<button
|
|
44688
|
+
class="btn-primary"
|
|
44689
|
+
type="button"
|
|
44690
|
+
data-folder-sessions-new-session="true"
|
|
44691
|
+
data-oysterun-normal-session-start-action="true"
|
|
44692
|
+
>+ New Session</button>
|
|
44693
|
+
</div>
|
|
44694
|
+
${
|
|
44695
|
+
historyRows
|
|
44696
|
+
? '<div class="meta-text folder-sessions-label">Previous Sessions</div>'
|
|
44697
|
+
: ""
|
|
44698
|
+
}
|
|
44699
|
+
</div>
|
|
44700
|
+
${
|
|
44701
|
+
historyRows
|
|
44702
|
+
? `<div class="session-section-rows">${historyRows}</div>`
|
|
44703
|
+
: ready
|
|
44704
|
+
? `<div class="empty-state sessions-empty-state">
|
|
44705
|
+
<div class="sessions-empty-icon" aria-hidden="true"></div>
|
|
44706
|
+
<strong>No previous Sessions in this folder.</strong>
|
|
44707
|
+
</div>`
|
|
44708
|
+
: ""
|
|
44709
|
+
}
|
|
44710
|
+
`;
|
|
44711
|
+
wireFolderSessionsView(container, route.folder);
|
|
44712
|
+
}
|
|
44713
|
+
|
|
44800
44714
|
function renderCatalog() {
|
|
44715
|
+
renderFolderSessionsView();
|
|
44801
44716
|
const entryContainer = $("entry-agent-list");
|
|
44802
44717
|
const focusedSessionTagGroupIdentity =
|
|
44803
44718
|
document.activeElement?.dataset?.sessionTagGroupToggle || "";
|
|
@@ -46367,8 +46282,7 @@ Waiting for Claude login output…</pre
|
|
|
46367
46282
|
}
|
|
46368
46283
|
}
|
|
46369
46284
|
|
|
46370
|
-
function wireEntryCardEvents() {
|
|
46371
|
-
const entryContainer = $("entry-agent-list");
|
|
46285
|
+
function wireEntryCardEvents(entryContainer = $("entry-agent-list")) {
|
|
46372
46286
|
if (!entryContainer) return;
|
|
46373
46287
|
|
|
46374
46288
|
for (const toggle of entryContainer.querySelectorAll(
|
|
@@ -47046,7 +46960,6 @@ Waiting for Claude login output…</pre
|
|
|
47046
46960
|
: HOST_DEFAULT_SESSION_DEFAULTS.xai.approvalPolicy;
|
|
47047
46961
|
const savedDraft = buildHostPreferencesDraft({
|
|
47048
46962
|
displayName: data.display_name || "",
|
|
47049
|
-
publicBaseUrl: data.direct_host_url || data.public_base_url || "",
|
|
47050
46963
|
defaultBrowsePath: data.default_browse_path || "",
|
|
47051
46964
|
notificationSoundWebEnabled,
|
|
47052
46965
|
notificationSoundAppEnabled,
|
|
@@ -47091,7 +47004,6 @@ Waiting for Claude login output…</pre
|
|
|
47091
47004
|
loaded: true,
|
|
47092
47005
|
loading: false,
|
|
47093
47006
|
saving: false,
|
|
47094
|
-
connectionMode: data.connection_mode === "cloud" ? "cloud" : "direct",
|
|
47095
47007
|
platform: typeof data.platform === "string" ? data.platform : "",
|
|
47096
47008
|
folderAccessSettingsSupported:
|
|
47097
47009
|
data.folder_access_settings_supported === true,
|
|
@@ -47165,8 +47077,6 @@ Waiting for Claude login output…</pre
|
|
|
47165
47077
|
allowedPathDisabled,
|
|
47166
47078
|
allowedPathDebugUiEnabled,
|
|
47167
47079
|
providerPermissionDebugModeDropdownEnabled,
|
|
47168
|
-
publicBaseUrl: data.direct_host_url || data.public_base_url || "",
|
|
47169
|
-
activeDirectHostUrl: data.active_direct_host_url || "",
|
|
47170
47080
|
managedTunnelEnabled: data.managed_tunnel_enabled === true,
|
|
47171
47081
|
managedTunnelStatus:
|
|
47172
47082
|
data.managed_tunnel_status === "ready" ||
|
|
@@ -47202,8 +47112,6 @@ Waiting for Claude login output…</pre
|
|
|
47202
47112
|
hostPreferencesState.notificationServiceWorkerState || "unknown",
|
|
47203
47113
|
notificationLastError:
|
|
47204
47114
|
hostPreferencesState.notificationLastError || "",
|
|
47205
|
-
directHostUrlRestartRequired:
|
|
47206
|
-
data.direct_host_url_restart_required === true,
|
|
47207
47115
|
hostRestartSupported: data.host_restart_supported === true,
|
|
47208
47116
|
loginQr: hostPreferencesState.loginQr,
|
|
47209
47117
|
loginQrLoading: false,
|
|
@@ -49844,10 +49752,6 @@ Waiting for Claude login output…</pre
|
|
|
49844
49752
|
if (displayNameInput && document.activeElement !== displayNameInput) {
|
|
49845
49753
|
displayNameInput.value = hostPreferencesState.displayName || "";
|
|
49846
49754
|
}
|
|
49847
|
-
const publicUrlInput = $("host-public-base-url");
|
|
49848
|
-
if (publicUrlInput && document.activeElement !== publicUrlInput) {
|
|
49849
|
-
publicUrlInput.value = hostPreferencesState.publicBaseUrl || "";
|
|
49850
|
-
}
|
|
49851
49755
|
if ($("host-default-provider")) {
|
|
49852
49756
|
renderHostDefaultProviderOptions();
|
|
49853
49757
|
}
|
|
@@ -49958,11 +49862,6 @@ Waiting for Claude login output…</pre
|
|
|
49958
49862
|
"disabled",
|
|
49959
49863
|
providerCatalogState.loading
|
|
49960
49864
|
);
|
|
49961
|
-
const loginQrUsesManagedEndpoint =
|
|
49962
|
-
hostPreferencesState.connectionMode === "cloud";
|
|
49963
|
-
const directAccessHint = loginQrUsesManagedEndpoint
|
|
49964
|
-
? "Managed login QR uses the healthy Oysterun Managed Endpoint. Direct Host URL remains available for manual Direct access."
|
|
49965
|
-
: "Used by app login QR and manual iPhone connection. Save changes before generating QR.";
|
|
49966
49865
|
const localUrlInput = $("host-preferences-local-url");
|
|
49967
49866
|
if (localUrlInput) {
|
|
49968
49867
|
localUrlInput.value = hostPreferencesState.localUrl || "";
|
|
@@ -49999,10 +49898,10 @@ Waiting for Claude login output…</pre
|
|
|
49999
49898
|
"host-managed-tunnel-status-hint",
|
|
50000
49899
|
managedTunnelStatus === "denied"
|
|
50001
49900
|
? hostPreferencesState.managedTunnelStatusDetail ||
|
|
50002
|
-
"Managed registration was denied.
|
|
49901
|
+
"Managed registration was denied. This Host's Tunnel URL is not reachable until registration succeeds."
|
|
50003
49902
|
: managedTunnelStatus === "pending"
|
|
50004
49903
|
? hostPreferencesState.managedTunnelStatusDetail ||
|
|
50005
|
-
"Managed Connector is still retrying.
|
|
49904
|
+
"Managed Connector is still retrying. The Host service runs locally, but its Tunnel URL is not reachable yet."
|
|
50006
49905
|
: ""
|
|
50007
49906
|
);
|
|
50008
49907
|
const managedQuota = hostPreferencesState.managedTunnelQuota;
|
|
@@ -50177,49 +50076,21 @@ Waiting for Claude login output…</pre
|
|
|
50177
50076
|
"disabled",
|
|
50178
50077
|
!managedDiagnostics
|
|
50179
50078
|
);
|
|
50180
|
-
|
|
50181
|
-
const directUrlCopyButton = $("host-public-base-url-copy-btn");
|
|
50182
|
-
if (directUrlCopyButton) {
|
|
50183
|
-
directUrlCopyButton.disabled = !String(
|
|
50184
|
-
publicUrlInput?.value || hostPreferencesState.publicBaseUrl || ""
|
|
50185
|
-
).trim();
|
|
50186
|
-
}
|
|
50187
|
-
const hasDirectAccessDraftChanges = hasUnsavedHostPreferencesChanges();
|
|
50188
|
-
const savedDirectHostUrl = hostPreferencesState.publicBaseUrl || "";
|
|
50189
|
-
const activeDirectHostUrl =
|
|
50190
|
-
hostPreferencesState.activeDirectHostUrl || savedDirectHostUrl;
|
|
50079
|
+
// Every login QR carries this Host's formal URL: its registered Tunnel URL.
|
|
50191
50080
|
const managedLoginQrReady =
|
|
50192
50081
|
hostPreferencesState.managedTunnelEnabled &&
|
|
50193
50082
|
managedTunnelStatus === "ready" &&
|
|
50194
50083
|
Boolean(hostPreferencesState.managedEndpoint);
|
|
50195
|
-
const
|
|
50196
|
-
|
|
50197
|
-
const loginQrTargetReady = loginQrUsesManagedEndpoint
|
|
50198
|
-
? managedLoginQrReady
|
|
50199
|
-
: Boolean(savedDirectHostUrl);
|
|
50084
|
+
const hasDirectAccessDraftChanges = hasUnsavedHostPreferencesChanges();
|
|
50085
|
+
const loginQrTargetReady = managedLoginQrReady;
|
|
50200
50086
|
let directAccessStatus = "";
|
|
50201
50087
|
if (hostPreferencesState.loginQrError) {
|
|
50202
50088
|
directAccessStatus = hostPreferencesState.loginQrError;
|
|
50203
|
-
} else
|
|
50089
|
+
} else {
|
|
50204
50090
|
directAccessStatus = managedLoginQrReady
|
|
50205
50091
|
? `QR will use Oysterun Managed Endpoint ${hostPreferencesState.managedEndpoint}.`
|
|
50206
50092
|
: hostPreferencesState.managedTunnelStatusDetail ||
|
|
50207
50093
|
"Managed Endpoint must be Ready before generating a login QR.";
|
|
50208
|
-
} else if (hostPreferencesState.directHostUrlRestartRequired) {
|
|
50209
|
-
directAccessStatus =
|
|
50210
|
-
"Saved URL differs from the running Host URL. Restart Host before using the new app connection URL.";
|
|
50211
|
-
} else if (savedDirectHostUrl) {
|
|
50212
|
-
directAccessStatus = `QR will use ${savedDirectHostUrl}.`;
|
|
50213
|
-
} else {
|
|
50214
|
-
directAccessStatus =
|
|
50215
|
-
"Set a Direct Host URL before generating a login QR.";
|
|
50216
|
-
}
|
|
50217
|
-
if (
|
|
50218
|
-
activeDirectHostUrl &&
|
|
50219
|
-
savedDirectHostUrl &&
|
|
50220
|
-
activeDirectHostUrl !== savedDirectHostUrl
|
|
50221
|
-
) {
|
|
50222
|
-
directAccessStatus += ` Running URL: ${activeDirectHostUrl}.`;
|
|
50223
50094
|
}
|
|
50224
50095
|
setText("host-direct-access-status", directAccessStatus);
|
|
50225
50096
|
const restartHandoff = hostPreferencesState.restartHandoff;
|
|
@@ -50247,7 +50118,6 @@ Waiting for Claude login output…</pre
|
|
|
50247
50118
|
qrButton.disabled =
|
|
50248
50119
|
disabled ||
|
|
50249
50120
|
hostPreferencesState.loginQrLoading ||
|
|
50250
|
-
loginQrBlockedByDraftChanges ||
|
|
50251
50121
|
!loginQrTargetReady;
|
|
50252
50122
|
qrButton.textContent = hostPreferencesState.loginQrLoading
|
|
50253
50123
|
? "Generating..."
|
|
@@ -50255,9 +50125,11 @@ Waiting for Claude login output…</pre
|
|
|
50255
50125
|
}
|
|
50256
50126
|
const restartButton = $("host-restart-btn");
|
|
50257
50127
|
if (restartButton) {
|
|
50258
|
-
|
|
50259
|
-
|
|
50260
|
-
|
|
50128
|
+
// An unfinished restart continues through Restart Host itself.
|
|
50129
|
+
const restartBlockedByUpdate =
|
|
50130
|
+
isOysterunUpdateOperationBlocking(hostPreferencesState.update) &&
|
|
50131
|
+
getHostLifecycleRecoveryUserAction(hostPreferencesState.update)
|
|
50132
|
+
?.kind !== "restart_only";
|
|
50261
50133
|
restartButton.disabled =
|
|
50262
50134
|
disabled ||
|
|
50263
50135
|
hostPreferencesState.restartLoading ||
|
|
@@ -50336,10 +50208,18 @@ Waiting for Claude login output…</pre
|
|
|
50336
50208
|
betaUpdateVisible && hostPreferencesState.betaUpdateRefreshing
|
|
50337
50209
|
);
|
|
50338
50210
|
const updatePhase = getOysterunUpdatePhase(update);
|
|
50211
|
+
const restartRecoveryDescription =
|
|
50212
|
+
getHostLifecycleRecoveryUserAction(update)?.kind === "restart_only"
|
|
50213
|
+
? getHostLifecycleRecoveryUserAction(update).description || ""
|
|
50214
|
+
: "";
|
|
50339
50215
|
setText(
|
|
50340
50216
|
"host-restart-status",
|
|
50341
50217
|
hostPreferencesState.restartStatus ||
|
|
50342
|
-
(restartOperation
|
|
50218
|
+
(restartOperation
|
|
50219
|
+
? [updatePhase, restartRecoveryDescription]
|
|
50220
|
+
.filter(Boolean)
|
|
50221
|
+
.join(" ")
|
|
50222
|
+
: "")
|
|
50343
50223
|
);
|
|
50344
50224
|
setText("host-update-phase", restartOperation ? "" : updatePhase);
|
|
50345
50225
|
setText(
|
|
@@ -50358,7 +50238,16 @@ Waiting for Claude login output…</pre
|
|
|
50358
50238
|
typeof recoveryPlan.user_action === "object"
|
|
50359
50239
|
? recoveryPlan.user_action
|
|
50360
50240
|
: null;
|
|
50361
|
-
|
|
50241
|
+
// Restart and update continuations use Restart Host / Update & Restart;
|
|
50242
|
+
// only Restore and the unverifiable-data diagnostics keep this entry.
|
|
50243
|
+
const updateEntryRecovery = [
|
|
50244
|
+
"complete_update_and_restart",
|
|
50245
|
+
"repair_and_restart",
|
|
50246
|
+
].includes(recoveryAction?.kind);
|
|
50247
|
+
const updateRecoveryRequired = [
|
|
50248
|
+
"restore_and_restart",
|
|
50249
|
+
"export_diagnostics",
|
|
50250
|
+
].includes(recoveryAction?.kind);
|
|
50362
50251
|
const recoveryButton = $("host-update-recovery-btn");
|
|
50363
50252
|
if (recoveryButton) {
|
|
50364
50253
|
recoveryButton.classList.toggle("hidden", !updateRecoveryRequired);
|
|
@@ -50371,17 +50260,35 @@ Waiting for Claude login output…</pre
|
|
|
50371
50260
|
? "Working..."
|
|
50372
50261
|
: recoveryAction?.label || "Download diagnostic summary";
|
|
50373
50262
|
}
|
|
50263
|
+
// P298 (Owner decision A): a recovery whose card button opens a
|
|
50264
|
+
// confirmation also offers the redacted summary on the card, before it.
|
|
50265
|
+
const cardDiagnosticsButton = $("host-update-card-diagnostics-btn");
|
|
50266
|
+
if (cardDiagnosticsButton) {
|
|
50267
|
+
cardDiagnosticsButton.classList.toggle(
|
|
50268
|
+
"hidden",
|
|
50269
|
+
recoveryAction?.kind !== "restore_and_restart" ||
|
|
50270
|
+
updateOperationRunning
|
|
50271
|
+
);
|
|
50272
|
+
cardDiagnosticsButton.disabled =
|
|
50273
|
+
disabled || hostPreferencesState.updateRecoveryChecking;
|
|
50274
|
+
cardDiagnosticsButton.textContent =
|
|
50275
|
+
hostPreferencesState.updateRecoveryChecking
|
|
50276
|
+
? "Preparing summary..."
|
|
50277
|
+
: "Download diagnostic summary";
|
|
50278
|
+
}
|
|
50279
|
+
const updateRecoveryDescription =
|
|
50280
|
+
recoveryAction?.kind === "restart_only"
|
|
50281
|
+
? ""
|
|
50282
|
+
: recoveryAction?.description || "";
|
|
50374
50283
|
setText(
|
|
50375
50284
|
"host-update-recovery-status",
|
|
50376
|
-
hostPreferencesState.updateRecoveryStatus ||
|
|
50377
|
-
recoveryAction?.description ||
|
|
50378
|
-
""
|
|
50285
|
+
hostPreferencesState.updateRecoveryStatus || updateRecoveryDescription
|
|
50379
50286
|
);
|
|
50380
50287
|
setVisible(
|
|
50381
50288
|
"host-update-recovery-status",
|
|
50382
50289
|
Boolean(
|
|
50383
50290
|
hostPreferencesState.updateRecoveryStatus ||
|
|
50384
|
-
|
|
50291
|
+
updateRecoveryDescription
|
|
50385
50292
|
)
|
|
50386
50293
|
);
|
|
50387
50294
|
const updateCanRun =
|
|
@@ -50485,13 +50392,16 @@ Waiting for Claude login output…</pre
|
|
|
50485
50392
|
}
|
|
50486
50393
|
const updateRunButton = $("host-update-run-btn");
|
|
50487
50394
|
if (updateRunButton) {
|
|
50395
|
+
// A prepared or unfinished install continues its original operation
|
|
50396
|
+
// through Update & Restart; otherwise this starts a new update.
|
|
50488
50397
|
updateRunButton.disabled =
|
|
50489
50398
|
disabled ||
|
|
50490
50399
|
hostPreferencesState.updateChecking ||
|
|
50491
50400
|
hostPreferencesState.updateRunning ||
|
|
50492
|
-
updateOperationBlocking ||
|
|
50493
50401
|
updateConfirmationVisible ||
|
|
50494
|
-
|
|
50402
|
+
(updateEntryRecovery
|
|
50403
|
+
? updateOperationRunning
|
|
50404
|
+
: updateOperationBlocking || !updateCanRun);
|
|
50495
50405
|
updateRunButton.textContent = hostPreferencesState.updateRunning
|
|
50496
50406
|
? "Installing..."
|
|
50497
50407
|
: "Update & Restart";
|
|
@@ -50537,6 +50447,12 @@ Waiting for Claude login output…</pre
|
|
|
50537
50447
|
? "Confirm beta install and restart"
|
|
50538
50448
|
: "Confirm update and restart"
|
|
50539
50449
|
);
|
|
50450
|
+
setText(
|
|
50451
|
+
"host-update-confirmation-warning",
|
|
50452
|
+
recoveryConfirmation
|
|
50453
|
+
? "Oysterun continues this operation with its retained Session restore state; a new one is prepared only if the operation stopped before its first restart. Loops remain off. Active provider replies, terminal commands, loop turns, and scheduler work may be marked interrupted and will not be replayed."
|
|
50454
|
+
: "Oysterun will prepare restore state for existing Sessions before restarting Host. Loops remain off. Active provider replies, terminal commands, loop turns, and scheduler work may be marked interrupted and will not be replayed."
|
|
50455
|
+
);
|
|
50540
50456
|
setText("host-update-confirmation-current", updateCurrentVersion);
|
|
50541
50457
|
setText("host-update-confirmation-target", updateTargetVersion);
|
|
50542
50458
|
setText(
|
|
@@ -50582,12 +50498,32 @@ Waiting for Claude login output…</pre
|
|
|
50582
50498
|
updateConfirmRunButton.disabled =
|
|
50583
50499
|
disabled || !updateConfirmationVisible;
|
|
50584
50500
|
updateConfirmRunButton.textContent = recoveryConfirmation
|
|
50585
|
-
?
|
|
50501
|
+
? getHostLifecycleRecoveryPrimaryLabel(updateConfirmationMode)
|
|
50586
50502
|
: updateConfirmationMode === "beta"
|
|
50587
50503
|
? "Confirm Beta Install & Restart"
|
|
50588
50504
|
: "Confirm Update & Restart";
|
|
50589
50505
|
setVisible("host-update-confirm-run-btn", updateConfirmationVisible);
|
|
50590
50506
|
}
|
|
50507
|
+
// Failure/recovery confirmations offer the redacted summary as a
|
|
50508
|
+
// secondary action next to Cancel and the primary operation. Restore
|
|
50509
|
+
// offers it on the card instead (P298, Owner decision X).
|
|
50510
|
+
const updateConfirmDiagnosticsButton = $(
|
|
50511
|
+
"host-update-confirm-diagnostics-btn"
|
|
50512
|
+
);
|
|
50513
|
+
if (updateConfirmDiagnosticsButton) {
|
|
50514
|
+
updateConfirmDiagnosticsButton.disabled =
|
|
50515
|
+
disabled || hostPreferencesState.updateRecoveryChecking;
|
|
50516
|
+
updateConfirmDiagnosticsButton.textContent =
|
|
50517
|
+
hostPreferencesState.updateRecoveryChecking
|
|
50518
|
+
? "Preparing summary..."
|
|
50519
|
+
: "Download diagnostic summary";
|
|
50520
|
+
setVisible(
|
|
50521
|
+
"host-update-confirm-diagnostics-btn",
|
|
50522
|
+
updateConfirmationVisible &&
|
|
50523
|
+
recoveryConfirmation &&
|
|
50524
|
+
updateConfirmationMode !== "restore_and_restart"
|
|
50525
|
+
);
|
|
50526
|
+
}
|
|
50591
50527
|
const updateConfirmCancelButton = $("host-update-confirm-cancel-btn");
|
|
50592
50528
|
if (updateConfirmCancelButton) {
|
|
50593
50529
|
updateConfirmCancelButton.disabled = disabled;
|
|
@@ -50643,7 +50579,6 @@ Waiting for Claude login output…</pre
|
|
|
50643
50579
|
showError("host-preferences-error", hostPreferencesState.error);
|
|
50644
50580
|
const defaultProviderDisabled =
|
|
50645
50581
|
providerControlsDisabled || getAvailableProviderIds().length === 0;
|
|
50646
|
-
const publicUrlDisabled = disabled;
|
|
50647
50582
|
const folderAccessVisible =
|
|
50648
50583
|
hostPreferencesState.platform === "darwin" &&
|
|
50649
50584
|
hostPreferencesState.folderAccessSettingsSupported === true &&
|
|
@@ -50698,10 +50633,6 @@ Waiting for Claude login output…</pre
|
|
|
50698
50633
|
renderHostNotificationPreferences({ disabled });
|
|
50699
50634
|
renderHostVoiceInputPreferences({ disabled });
|
|
50700
50635
|
setVisible("host-folder-access-card", folderAccessVisible);
|
|
50701
|
-
$("host-public-base-url")?.toggleAttribute(
|
|
50702
|
-
"disabled",
|
|
50703
|
-
publicUrlDisabled
|
|
50704
|
-
);
|
|
50705
50636
|
$("host-display-name")?.toggleAttribute("disabled", disabled);
|
|
50706
50637
|
$("host-default-browse-path")?.toggleAttribute("disabled", disabled);
|
|
50707
50638
|
$("host-default-browse-path-picker")?.toggleAttribute(
|
|
@@ -50829,18 +50760,6 @@ Waiting for Claude login output…</pre
|
|
|
50829
50760
|
|
|
50830
50761
|
async function generateDirectHostLoginQr() {
|
|
50831
50762
|
if (hostPreferencesState.loginQrLoading) return;
|
|
50832
|
-
if (
|
|
50833
|
-
hostPreferencesState.connectionMode !== "cloud" &&
|
|
50834
|
-
hasUnsavedHostPreferencesChanges()
|
|
50835
|
-
) {
|
|
50836
|
-
hostPreferencesState = {
|
|
50837
|
-
...hostPreferencesState,
|
|
50838
|
-
loginQrError:
|
|
50839
|
-
"Save Direct Host URL changes before generating a login QR.",
|
|
50840
|
-
};
|
|
50841
|
-
renderHostPreferences();
|
|
50842
|
-
return;
|
|
50843
|
-
}
|
|
50844
50763
|
hostPreferencesState = {
|
|
50845
50764
|
...hostPreferencesState,
|
|
50846
50765
|
loginQrLoading: true,
|
|
@@ -50876,6 +50795,19 @@ Waiting for Claude login output…</pre
|
|
|
50876
50795
|
|
|
50877
50796
|
async function restartHostFromPreferences() {
|
|
50878
50797
|
if (hostPreferencesState.restartLoading) return;
|
|
50798
|
+
// An unfinished restart continues with its original Session snapshot
|
|
50799
|
+
// after the existing recovery confirmation.
|
|
50800
|
+
const retained = getHostLifecycleRecoveryUserAction(
|
|
50801
|
+
hostPreferencesState.update
|
|
50802
|
+
);
|
|
50803
|
+
if (
|
|
50804
|
+
retained?.kind === "restart_only" &&
|
|
50805
|
+
!hostPreferencesState.loading &&
|
|
50806
|
+
!hostPreferencesState.saving
|
|
50807
|
+
) {
|
|
50808
|
+
openHostLifecycleRecoveryConfirmation(retained);
|
|
50809
|
+
return;
|
|
50810
|
+
}
|
|
50879
50811
|
if (
|
|
50880
50812
|
hostPreferencesState.loading ||
|
|
50881
50813
|
hostPreferencesState.saving ||
|
|
@@ -51081,32 +51013,46 @@ Waiting for Claude login output…</pre
|
|
|
51081
51013
|
}
|
|
51082
51014
|
}
|
|
51083
51015
|
|
|
51084
|
-
|
|
51085
|
-
|
|
51016
|
+
function getHostLifecycleRecoveryUserAction(update) {
|
|
51017
|
+
const action = update?.recovery_plan?.user_action;
|
|
51018
|
+
return action && typeof action === "object" && action.kind
|
|
51019
|
+
? action
|
|
51020
|
+
: null;
|
|
51021
|
+
}
|
|
51022
|
+
|
|
51023
|
+
function getHostLifecycleRecoveryPrimaryLabel(kind) {
|
|
51024
|
+
// The confirmation keeps the real operation name of its entry.
|
|
51025
|
+
if (kind === "restart_only") return "Restart Host";
|
|
51026
|
+
if (kind === "restore_and_restart") return "Restore and restart";
|
|
51027
|
+
return "Update & Restart";
|
|
51028
|
+
}
|
|
51029
|
+
|
|
51030
|
+
function openHostLifecycleRecoveryConfirmation(action) {
|
|
51086
51031
|
const update = hostPreferencesState.update || {};
|
|
51087
|
-
|
|
51088
|
-
|
|
51089
|
-
|
|
51090
|
-
|
|
51091
|
-
|
|
51092
|
-
|
|
51093
|
-
|
|
51094
|
-
|
|
51095
|
-
|
|
51096
|
-
|
|
51097
|
-
|
|
51098
|
-
|
|
51099
|
-
|
|
51100
|
-
|
|
51101
|
-
|
|
51102
|
-
|
|
51103
|
-
|
|
51104
|
-
|
|
51105
|
-
|
|
51106
|
-
|
|
51107
|
-
|
|
51108
|
-
|
|
51109
|
-
|
|
51032
|
+
hostPreferencesState = {
|
|
51033
|
+
...hostPreferencesState,
|
|
51034
|
+
updateConfirmationVisible: true,
|
|
51035
|
+
updateConfirmationMode: action.kind,
|
|
51036
|
+
updateConfirmationCurrentVersion:
|
|
51037
|
+
update.current_version || "the current version",
|
|
51038
|
+
updateConfirmationTargetVersion:
|
|
51039
|
+
action.target_version ||
|
|
51040
|
+
update.update_operation?.target_version ||
|
|
51041
|
+
update.update_operation?.last_working_version ||
|
|
51042
|
+
"the retained version",
|
|
51043
|
+
updateRecoveryStatus: "",
|
|
51044
|
+
updateError: "",
|
|
51045
|
+
};
|
|
51046
|
+
renderHostPreferences();
|
|
51047
|
+
window.setTimeout(() => {
|
|
51048
|
+
$("host-update-confirm-run-btn")?.focus();
|
|
51049
|
+
}, 0);
|
|
51050
|
+
}
|
|
51051
|
+
|
|
51052
|
+
// Fetches only the redacted summary; never runs install, restore or
|
|
51053
|
+
// restart and leaves any open confirmation as it is.
|
|
51054
|
+
async function downloadHostLifecycleDiagnosticSummary() {
|
|
51055
|
+
if (hostPreferencesState.updateRecoveryChecking) return;
|
|
51110
51056
|
hostPreferencesState = {
|
|
51111
51057
|
...hostPreferencesState,
|
|
51112
51058
|
updateRecoveryChecking: true,
|
|
@@ -51135,6 +51081,7 @@ Waiting for Claude login output…</pre
|
|
|
51135
51081
|
"Redacted diagnostic summary downloaded. The current Host was not changed.",
|
|
51136
51082
|
};
|
|
51137
51083
|
} catch (error) {
|
|
51084
|
+
if (await handleHostPreferencesAuthFailure(error)) return;
|
|
51138
51085
|
hostPreferencesState = {
|
|
51139
51086
|
...hostPreferencesState,
|
|
51140
51087
|
updateRecoveryChecking: false,
|
|
@@ -51144,12 +51091,42 @@ Waiting for Claude login output…</pre
|
|
|
51144
51091
|
renderHostPreferences();
|
|
51145
51092
|
}
|
|
51146
51093
|
|
|
51094
|
+
async function runOysterunRecoveryAction() {
|
|
51095
|
+
if (hostPreferencesState.updateRecoveryChecking) return;
|
|
51096
|
+
const action = getHostLifecycleRecoveryUserAction(
|
|
51097
|
+
hostPreferencesState.update
|
|
51098
|
+
);
|
|
51099
|
+
if (!action) return;
|
|
51100
|
+
if (action.kind === "export_diagnostics") {
|
|
51101
|
+
await downloadHostLifecycleDiagnosticSummary();
|
|
51102
|
+
return;
|
|
51103
|
+
}
|
|
51104
|
+
if (action.kind !== "restore_and_restart") return;
|
|
51105
|
+
openHostLifecycleRecoveryConfirmation(action);
|
|
51106
|
+
}
|
|
51107
|
+
|
|
51147
51108
|
async function runOysterunUpdate() {
|
|
51148
51109
|
if (
|
|
51149
51110
|
hostPreferencesState.updateRunning ||
|
|
51150
|
-
hostPreferencesState.updateChecking
|
|
51151
|
-
|
|
51111
|
+
hostPreferencesState.updateChecking
|
|
51112
|
+
) {
|
|
51113
|
+
return;
|
|
51114
|
+
}
|
|
51115
|
+
// A prepared update or unfinished install continues its original
|
|
51116
|
+
// operation and exact version instead of selecting a new release.
|
|
51117
|
+
const retained = getHostLifecycleRecoveryUserAction(
|
|
51118
|
+
hostPreferencesState.update
|
|
51119
|
+
);
|
|
51120
|
+
if (
|
|
51121
|
+
retained &&
|
|
51122
|
+
["complete_update_and_restart", "repair_and_restart"].includes(
|
|
51123
|
+
retained.kind
|
|
51124
|
+
)
|
|
51152
51125
|
) {
|
|
51126
|
+
openHostLifecycleRecoveryConfirmation(retained);
|
|
51127
|
+
return;
|
|
51128
|
+
}
|
|
51129
|
+
if (isOysterunUpdateOperationBlocking(hostPreferencesState.update)) {
|
|
51153
51130
|
return;
|
|
51154
51131
|
}
|
|
51155
51132
|
const update = hostPreferencesState.update || {};
|
|
@@ -51233,10 +51210,11 @@ Waiting for Claude login output…</pre
|
|
|
51233
51210
|
};
|
|
51234
51211
|
renderHostPreferences();
|
|
51235
51212
|
window.setTimeout(() => {
|
|
51236
|
-
|
|
51237
|
-
HOST_LIFECYCLE_RECOVERY_MODES.includes(confirmationMode);
|
|
51213
|
+
// Return focus to the entry that opened the confirmation.
|
|
51238
51214
|
$(
|
|
51239
|
-
|
|
51215
|
+
confirmationMode === "restart_only"
|
|
51216
|
+
? "host-restart-btn"
|
|
51217
|
+
: confirmationMode === "restore_and_restart"
|
|
51240
51218
|
? "host-update-recovery-btn"
|
|
51241
51219
|
: confirmationMode === "beta"
|
|
51242
51220
|
? "host-update-beta-run-btn"
|
|
@@ -51588,19 +51566,6 @@ Waiting for Claude login output…</pre
|
|
|
51588
51566
|
renderHostPreferences();
|
|
51589
51567
|
return;
|
|
51590
51568
|
}
|
|
51591
|
-
const confirmProviderPermissionMode =
|
|
51592
|
-
requiresProviderPermissionPolicyConfirmation(
|
|
51593
|
-
"claude",
|
|
51594
|
-
currentDraft.claudePermissionMode
|
|
51595
|
-
) ||
|
|
51596
|
-
requiresProviderPermissionPolicyConfirmation(
|
|
51597
|
-
"codex",
|
|
51598
|
-
currentDraft.codexApprovalPolicy
|
|
51599
|
-
) ||
|
|
51600
|
-
requiresProviderPermissionPolicyConfirmation(
|
|
51601
|
-
"xai",
|
|
51602
|
-
currentDraft.xaiApprovalPolicy
|
|
51603
|
-
);
|
|
51604
51569
|
const preferencesPayload = serializeHostPreferencesDraft(currentDraft);
|
|
51605
51570
|
hostPreferencesState = {
|
|
51606
51571
|
...hostPreferencesState,
|
|
@@ -51609,9 +51574,6 @@ Waiting for Claude login output…</pre
|
|
|
51609
51574
|
};
|
|
51610
51575
|
renderHostPreferences();
|
|
51611
51576
|
try {
|
|
51612
|
-
if (confirmProviderPermissionMode) {
|
|
51613
|
-
preferencesPayload.confirm_beta_provider_permission_mode = true;
|
|
51614
|
-
}
|
|
51615
51577
|
const data = await apiWithAuthRetry(
|
|
51616
51578
|
"PUT",
|
|
51617
51579
|
"/dev/preferences",
|
|
@@ -63731,14 +63693,6 @@ Waiting for Claude login output…</pre
|
|
|
63731
63693
|
if (isAllowedPathDebugUiVisible()) {
|
|
63732
63694
|
payload.allowed_paths = allowedPaths;
|
|
63733
63695
|
}
|
|
63734
|
-
if (
|
|
63735
|
-
requiresProviderPermissionPolicyConfirmation(
|
|
63736
|
-
createRuntime,
|
|
63737
|
-
permissionMode || codexApproval || xaiApproval
|
|
63738
|
-
)
|
|
63739
|
-
) {
|
|
63740
|
-
payload.confirm_beta_provider_permission_mode = true;
|
|
63741
|
-
}
|
|
63742
63696
|
validateTelegramEnabledPayloadOrThrow(
|
|
63743
63697
|
payload,
|
|
63744
63698
|
getCreateTelegramConfiguredState()
|
|
@@ -66143,8 +66097,6 @@ Waiting for Claude login output…</pre
|
|
|
66143
66097
|
window.removeHostVoiceInputSavedToken = removeHostVoiceInputSavedToken;
|
|
66144
66098
|
window.testHostVoiceInput = testHostVoiceInput;
|
|
66145
66099
|
window.generateDirectHostLoginQr = generateDirectHostLoginQr;
|
|
66146
|
-
window.copyHostPreferencesDirectHostUrl =
|
|
66147
|
-
copyHostPreferencesDirectHostUrl;
|
|
66148
66100
|
window.copyHostPreferencesLocalUrl = copyHostPreferencesLocalUrl;
|
|
66149
66101
|
window.restartHostFromPreferences = restartHostFromPreferences;
|
|
66150
66102
|
window.restorePreviousSessions = restorePreviousSessions;
|