opendevbrowser 0.0.17 → 0.0.18
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 +171 -73
- package/dist/annotate/agent-inbox-store.d.ts +58 -0
- package/dist/annotate/agent-inbox-store.d.ts.map +1 -0
- package/dist/annotate/agent-inbox.d.ts +25 -0
- package/dist/annotate/agent-inbox.d.ts.map +1 -0
- package/dist/annotate/direct-annotator.d.ts.map +1 -1
- package/dist/annotate/timeout-messages.d.ts +4 -0
- package/dist/annotate/timeout-messages.d.ts.map +1 -0
- package/dist/automation/coordinator.d.ts +55 -0
- package/dist/automation/coordinator.d.ts.map +1 -0
- package/dist/browser/annotation-manager.d.ts +4 -1
- package/dist/browser/annotation-manager.d.ts.map +1 -1
- package/dist/browser/browser-manager.d.ts +147 -47
- package/dist/browser/browser-manager.d.ts.map +1 -1
- package/dist/browser/canvas-client.d.ts +1 -0
- package/dist/browser/canvas-client.d.ts.map +1 -1
- package/dist/browser/canvas-code-sync-manager.d.ts +9 -1
- package/dist/browser/canvas-code-sync-manager.d.ts.map +1 -1
- package/dist/browser/canvas-manager.d.ts +29 -1
- package/dist/browser/canvas-manager.d.ts.map +1 -1
- package/dist/browser/global-challenge-coordinator.d.ts +27 -0
- package/dist/browser/global-challenge-coordinator.d.ts.map +1 -0
- package/dist/browser/manager-types.d.ts +167 -1
- package/dist/browser/manager-types.d.ts.map +1 -1
- package/dist/browser/ops-browser-manager.d.ts +103 -3
- package/dist/browser/ops-browser-manager.d.ts.map +1 -1
- package/dist/browser/ops-client.d.ts +17 -1
- package/dist/browser/ops-client.d.ts.map +1 -1
- package/dist/browser/playwright-runtime.d.ts +4 -0
- package/dist/browser/playwright-runtime.d.ts.map +1 -0
- package/dist/browser/review-surface.d.ts +9 -0
- package/dist/browser/review-surface.d.ts.map +1 -0
- package/dist/browser/screencast-recorder.d.ts +57 -0
- package/dist/browser/screencast-recorder.d.ts.map +1 -0
- package/dist/browser/session-inspector.d.ts +71 -0
- package/dist/browser/session-inspector.d.ts.map +1 -0
- package/dist/browser/session-store.d.ts +5 -1
- package/dist/browser/session-store.d.ts.map +1 -1
- package/dist/browser/system-chrome-cookies.d.ts +46 -0
- package/dist/browser/system-chrome-cookies.d.ts.map +1 -0
- package/dist/browser/target-manager.d.ts +1 -0
- package/dist/browser/target-manager.d.ts.map +1 -1
- package/dist/cache/chrome-locator.d.ts.map +1 -1
- package/dist/cache/chrome-user-data.d.ts +17 -0
- package/dist/cache/chrome-user-data.d.ts.map +1 -0
- package/dist/canvas/adapter-plugins/loader.d.ts +13 -0
- package/dist/canvas/adapter-plugins/loader.d.ts.map +1 -0
- package/dist/canvas/adapter-plugins/manifest.d.ts +146 -0
- package/dist/canvas/adapter-plugins/manifest.d.ts.map +1 -0
- package/dist/canvas/adapter-plugins/types.d.ts +83 -0
- package/dist/canvas/adapter-plugins/types.d.ts.map +1 -0
- package/dist/canvas/adapter-plugins/validator.d.ts +10 -0
- package/dist/canvas/adapter-plugins/validator.d.ts.map +1 -0
- package/dist/canvas/code-sync/apply-tsx.d.ts +3 -1
- package/dist/canvas/code-sync/apply-tsx.d.ts.map +1 -1
- package/dist/canvas/code-sync/import.d.ts +1 -0
- package/dist/canvas/code-sync/import.d.ts.map +1 -1
- package/dist/canvas/code-sync/manifest.d.ts +2 -1
- package/dist/canvas/code-sync/manifest.d.ts.map +1 -1
- package/dist/canvas/code-sync/tsx-adapter.d.ts.map +1 -1
- package/dist/canvas/code-sync/types.d.ts +102 -10
- package/dist/canvas/code-sync/types.d.ts.map +1 -1
- package/dist/canvas/document-store.d.ts +11 -1
- package/dist/canvas/document-store.d.ts.map +1 -1
- package/dist/canvas/export.d.ts.map +1 -1
- package/dist/canvas/framework-adapters/custom-elements-v1.d.ts +3 -0
- package/dist/canvas/framework-adapters/custom-elements-v1.d.ts.map +1 -0
- package/dist/canvas/framework-adapters/html-static-v1.d.ts +3 -0
- package/dist/canvas/framework-adapters/html-static-v1.d.ts.map +1 -0
- package/dist/canvas/framework-adapters/markup.d.ts +9 -0
- package/dist/canvas/framework-adapters/markup.d.ts.map +1 -0
- package/dist/canvas/framework-adapters/react-tsx-v2.d.ts +3 -0
- package/dist/canvas/framework-adapters/react-tsx-v2.d.ts.map +1 -0
- package/dist/canvas/framework-adapters/registry.d.ts +12 -0
- package/dist/canvas/framework-adapters/registry.d.ts.map +1 -0
- package/dist/canvas/framework-adapters/svelte-sfc-v1.d.ts +3 -0
- package/dist/canvas/framework-adapters/svelte-sfc-v1.d.ts.map +1 -0
- package/dist/canvas/framework-adapters/types.d.ts +57 -0
- package/dist/canvas/framework-adapters/types.d.ts.map +1 -0
- package/dist/canvas/framework-adapters/vue-sfc-v1.d.ts +3 -0
- package/dist/canvas/framework-adapters/vue-sfc-v1.d.ts.map +1 -0
- package/dist/canvas/kits/catalog.d.ts +5 -0
- package/dist/canvas/kits/catalog.d.ts.map +1 -0
- package/dist/canvas/library-adapters/react/index.d.ts +3 -0
- package/dist/canvas/library-adapters/react/index.d.ts.map +1 -0
- package/dist/canvas/library-adapters/registry.d.ts +11 -0
- package/dist/canvas/library-adapters/registry.d.ts.map +1 -0
- package/dist/canvas/library-adapters/types.d.ts +43 -0
- package/dist/canvas/library-adapters/types.d.ts.map +1 -0
- package/dist/canvas/repo-store.d.ts +2 -0
- package/dist/canvas/repo-store.d.ts.map +1 -1
- package/dist/canvas/starters/catalog.d.ts +34 -0
- package/dist/canvas/starters/catalog.d.ts.map +1 -0
- package/dist/canvas/token-references.d.ts +22 -0
- package/dist/canvas/token-references.d.ts.map +1 -0
- package/dist/canvas/types.d.ts +345 -6
- package/dist/canvas/types.d.ts.map +1 -1
- package/dist/challenges/action-loop.d.ts +13 -0
- package/dist/challenges/action-loop.d.ts.map +1 -0
- package/dist/challenges/capability-matrix.d.ts +3 -0
- package/dist/challenges/capability-matrix.d.ts.map +1 -0
- package/dist/challenges/evidence-bundle.d.ts +48 -0
- package/dist/challenges/evidence-bundle.d.ts.map +1 -0
- package/dist/challenges/governed-adapter-gateway.d.ts +4 -0
- package/dist/challenges/governed-adapter-gateway.d.ts.map +1 -0
- package/dist/challenges/human-yield-gate.d.ts +20 -0
- package/dist/challenges/human-yield-gate.d.ts.map +1 -0
- package/dist/challenges/index.d.ts +15 -0
- package/dist/challenges/index.d.ts.map +1 -0
- package/dist/challenges/interpreter.d.ts +3 -0
- package/dist/challenges/interpreter.d.ts.map +1 -0
- package/dist/challenges/optional-computer-use-bridge.d.ts +9 -0
- package/dist/challenges/optional-computer-use-bridge.d.ts.map +1 -0
- package/dist/challenges/orchestrator.d.ts +32 -0
- package/dist/challenges/orchestrator.d.ts.map +1 -0
- package/dist/challenges/outcome-recorder.d.ts +8 -0
- package/dist/challenges/outcome-recorder.d.ts.map +1 -0
- package/dist/challenges/owned-environment-lane.d.ts +3 -0
- package/dist/challenges/owned-environment-lane.d.ts.map +1 -0
- package/dist/challenges/policy-gate.d.ts +9 -0
- package/dist/challenges/policy-gate.d.ts.map +1 -0
- package/dist/challenges/sanctioned-identity-lane.d.ts +3 -0
- package/dist/challenges/sanctioned-identity-lane.d.ts.map +1 -0
- package/dist/challenges/service-adapter-lane.d.ts +3 -0
- package/dist/challenges/service-adapter-lane.d.ts.map +1 -0
- package/dist/challenges/strategy-selector.d.ts +10 -0
- package/dist/challenges/strategy-selector.d.ts.map +1 -0
- package/dist/challenges/types.d.ts +277 -0
- package/dist/challenges/types.d.ts.map +1 -0
- package/dist/challenges/verification-gate.d.ts +15 -0
- package/dist/challenges/verification-gate.d.ts.map +1 -0
- package/dist/chunk-5FZQJRBQ.js +15256 -0
- package/dist/chunk-5FZQJRBQ.js.map +1 -0
- package/dist/chunk-L57D35TB.js +33513 -0
- package/dist/chunk-L57D35TB.js.map +1 -0
- package/dist/chunk-YBQECXZX.js +409 -0
- package/dist/chunk-YBQECXZX.js.map +1 -0
- package/dist/cli/args.d.ts +4 -4
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/commands/artifacts.d.ts.map +1 -1
- package/dist/cli/commands/canvas.d.ts +7 -7
- package/dist/cli/commands/canvas.d.ts.map +1 -1
- package/dist/cli/commands/daemon.d.ts +7 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -1
- package/dist/cli/commands/desktop/accessibility-snapshot.d.ts +3 -0
- package/dist/cli/commands/desktop/accessibility-snapshot.d.ts.map +1 -0
- package/dist/cli/commands/desktop/active-window.d.ts +3 -0
- package/dist/cli/commands/desktop/active-window.d.ts.map +1 -0
- package/dist/cli/commands/desktop/capture-desktop.d.ts +3 -0
- package/dist/cli/commands/desktop/capture-desktop.d.ts.map +1 -0
- package/dist/cli/commands/desktop/capture-window.d.ts +3 -0
- package/dist/cli/commands/desktop/capture-window.d.ts.map +1 -0
- package/dist/cli/commands/desktop/shared.d.ts +19 -0
- package/dist/cli/commands/desktop/shared.d.ts.map +1 -0
- package/dist/cli/commands/desktop/status.d.ts +3 -0
- package/dist/cli/commands/desktop/status.d.ts.map +1 -0
- package/dist/cli/commands/desktop/windows.d.ts +3 -0
- package/dist/cli/commands/desktop/windows.d.ts.map +1 -0
- package/dist/cli/commands/devtools/dialog.d.ts +19 -0
- package/dist/cli/commands/devtools/dialog.d.ts.map +1 -0
- package/dist/cli/commands/devtools/screencast-start.d.ts +20 -0
- package/dist/cli/commands/devtools/screencast-start.d.ts.map +1 -0
- package/dist/cli/commands/devtools/screencast-stop.d.ts +17 -0
- package/dist/cli/commands/devtools/screencast-stop.d.ts.map +1 -0
- package/dist/cli/commands/devtools/screenshot.d.ts +2 -0
- package/dist/cli/commands/devtools/screenshot.d.ts.map +1 -1
- package/dist/cli/commands/interact/click.d.ts.map +1 -1
- package/dist/cli/commands/interact/pointer-down.d.ts +7 -0
- package/dist/cli/commands/interact/pointer-down.d.ts.map +1 -0
- package/dist/cli/commands/interact/pointer-drag.d.ts +7 -0
- package/dist/cli/commands/interact/pointer-drag.d.ts.map +1 -0
- package/dist/cli/commands/interact/pointer-move.d.ts +7 -0
- package/dist/cli/commands/interact/pointer-move.d.ts.map +1 -0
- package/dist/cli/commands/interact/pointer-shared.d.ts +6 -0
- package/dist/cli/commands/interact/pointer-shared.d.ts.map +1 -0
- package/dist/cli/commands/interact/pointer-up.d.ts +7 -0
- package/dist/cli/commands/interact/pointer-up.d.ts.map +1 -0
- package/dist/cli/commands/interact/upload.d.ts +18 -0
- package/dist/cli/commands/interact/upload.d.ts.map +1 -0
- package/dist/cli/commands/macro-resolve.d.ts +2 -0
- package/dist/cli/commands/macro-resolve.d.ts.map +1 -1
- package/dist/cli/commands/native.d.ts +10 -7
- package/dist/cli/commands/native.d.ts.map +1 -1
- package/dist/cli/commands/nav/review.d.ts +7 -0
- package/dist/cli/commands/nav/review.d.ts.map +1 -0
- package/dist/cli/commands/nav/snapshot.d.ts.map +1 -1
- package/dist/cli/commands/pages/open.d.ts.map +1 -1
- package/dist/cli/commands/product-video.d.ts +2 -0
- package/dist/cli/commands/product-video.d.ts.map +1 -1
- package/dist/cli/commands/research.d.ts +3 -0
- package/dist/cli/commands/research.d.ts.map +1 -1
- package/dist/cli/commands/run.d.ts +14 -0
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/serve.d.ts +1 -26
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/commands/session/connect.d.ts.map +1 -1
- package/dist/cli/commands/session/disconnect.d.ts.map +1 -1
- package/dist/cli/commands/session/inspector.d.ts +21 -0
- package/dist/cli/commands/session/inspector.d.ts.map +1 -0
- package/dist/cli/commands/session/launch.d.ts.map +1 -1
- package/dist/cli/commands/shopping.d.ts +5 -0
- package/dist/cli/commands/shopping.d.ts.map +1 -1
- package/dist/cli/commands/status.d.ts +2 -14
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/targets/new.d.ts.map +1 -1
- package/dist/cli/daemon-autostart.d.ts +11 -0
- package/dist/cli/daemon-autostart.d.ts.map +1 -1
- package/dist/cli/daemon-client.d.ts +3 -0
- package/dist/cli/daemon-client.d.ts.map +1 -1
- package/dist/cli/daemon-commands.d.ts.map +1 -1
- package/dist/cli/daemon-state.d.ts +16 -0
- package/dist/cli/daemon-state.d.ts.map +1 -1
- package/dist/cli/daemon-status.d.ts +7 -2
- package/dist/cli/daemon-status.d.ts.map +1 -1
- package/dist/cli/daemon.d.ts +1 -0
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/help.d.ts +15 -4
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/index.js +2467 -1033
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/install-autostart-output.d.ts +6 -0
- package/dist/cli/install-autostart-output.d.ts.map +1 -0
- package/dist/cli/install-autostart-reconciliation.d.ts +23 -0
- package/dist/cli/install-autostart-reconciliation.d.ts.map +1 -0
- package/dist/cli/installers/skills.d.ts +42 -6
- package/dist/cli/installers/skills.d.ts.map +1 -1
- package/dist/cli/output.d.ts +3 -0
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/remote-desktop-runtime.d.ts +15 -0
- package/dist/cli/remote-desktop-runtime.d.ts.map +1 -0
- package/dist/cli/remote-manager.d.ts +24 -2
- package/dist/cli/remote-manager.d.ts.map +1 -1
- package/dist/cli/transport-timeouts.d.ts +8 -0
- package/dist/cli/transport-timeouts.d.ts.map +1 -0
- package/dist/cli/utils/http.d.ts +9 -0
- package/dist/cli/utils/http.d.ts.map +1 -1
- package/dist/cli/utils/parse.d.ts +2 -0
- package/dist/cli/utils/parse.d.ts.map +1 -1
- package/dist/cli/utils/skills.d.ts +1 -2
- package/dist/cli/utils/skills.d.ts.map +1 -1
- package/dist/cli/utils/workflow-message.d.ts +2 -0
- package/dist/cli/utils/workflow-message.d.ts.map +1 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/core/bootstrap.d.ts.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/logging.d.ts +3 -1
- package/dist/core/logging.d.ts.map +1 -1
- package/dist/core/runtime-assemblies.d.ts +22 -0
- package/dist/core/runtime-assemblies.d.ts.map +1 -0
- package/dist/core/types.d.ts +15 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/desktop/audit.d.ts +37 -0
- package/dist/desktop/audit.d.ts.map +1 -0
- package/dist/desktop/errors.d.ts +7 -0
- package/dist/desktop/errors.d.ts.map +1 -0
- package/dist/desktop/index.d.ts +6 -0
- package/dist/desktop/index.d.ts.map +1 -0
- package/dist/desktop/runtime.d.ts +26 -0
- package/dist/desktop/runtime.d.ts.map +1 -0
- package/dist/desktop/types.d.ts +76 -0
- package/dist/desktop/types.d.ts.map +1 -0
- package/dist/extension-extractor.d.ts +6 -0
- package/dist/extension-extractor.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1103 -467
- package/dist/index.js.map +1 -1
- package/dist/integrations/figma/assets.d.ts +13 -0
- package/dist/integrations/figma/assets.d.ts.map +1 -0
- package/dist/integrations/figma/auth.d.ts +3 -0
- package/dist/integrations/figma/auth.d.ts.map +1 -0
- package/dist/integrations/figma/client.d.ts +42 -0
- package/dist/integrations/figma/client.d.ts.map +1 -0
- package/dist/integrations/figma/mappers.d.ts +23 -0
- package/dist/integrations/figma/mappers.d.ts.map +1 -0
- package/dist/integrations/figma/normalize.d.ts +99 -0
- package/dist/integrations/figma/normalize.d.ts.map +1 -0
- package/dist/integrations/figma/url.d.ts +17 -0
- package/dist/integrations/figma/url.d.ts.map +1 -0
- package/dist/integrations/figma/variables.d.ts +21 -0
- package/dist/integrations/figma/variables.d.ts.map +1 -0
- package/dist/macros/execute-runtime.d.ts +19 -0
- package/dist/macros/execute-runtime.d.ts.map +1 -0
- package/dist/macros/execute.d.ts +3 -1
- package/dist/macros/execute.d.ts.map +1 -1
- package/dist/opendevbrowser.d.ts.map +1 -1
- package/dist/opendevbrowser.js +1103 -467
- package/dist/opendevbrowser.js.map +1 -1
- package/dist/providers/blocker.d.ts.map +1 -1
- package/dist/providers/browser-fallback.d.ts +30 -0
- package/dist/providers/browser-fallback.d.ts.map +1 -0
- package/dist/providers/constraint.d.ts +45 -0
- package/dist/providers/constraint.d.ts.map +1 -0
- package/dist/providers/index.d.ts +11 -2
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/policy.d.ts.map +1 -1
- package/dist/providers/product-video-compiler.d.ts +92 -0
- package/dist/providers/product-video-compiler.d.ts.map +1 -0
- package/dist/providers/registry.d.ts +37 -1
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/renderer.d.ts.map +1 -1
- package/dist/providers/research-compiler.d.ts +64 -0
- package/dist/providers/research-compiler.d.ts.map +1 -0
- package/dist/providers/research-executor.d.ts +27 -0
- package/dist/providers/research-executor.d.ts.map +1 -0
- package/dist/providers/runtime-bundle.d.ts +26 -0
- package/dist/providers/runtime-bundle.d.ts.map +1 -0
- package/dist/providers/runtime-factory.d.ts +6 -1
- package/dist/providers/runtime-factory.d.ts.map +1 -1
- package/dist/providers/runtime-policy.d.ts +24 -0
- package/dist/providers/runtime-policy.d.ts.map +1 -0
- package/dist/providers/shared/anti-bot-policy.d.ts +3 -2
- package/dist/providers/shared/anti-bot-policy.d.ts.map +1 -1
- package/dist/providers/shopping/index.d.ts +11 -1
- package/dist/providers/shopping/index.d.ts.map +1 -1
- package/dist/providers/shopping-compiler.d.ts +51 -0
- package/dist/providers/shopping-compiler.d.ts.map +1 -0
- package/dist/providers/shopping-executor.d.ts +18 -0
- package/dist/providers/shopping-executor.d.ts.map +1 -0
- package/dist/providers/shopping-postprocess.d.ts +46 -0
- package/dist/providers/shopping-postprocess.d.ts.map +1 -0
- package/dist/providers/shopping-workflow.d.ts +33 -0
- package/dist/providers/shopping-workflow.d.ts.map +1 -0
- package/dist/providers/social/platform.d.ts +2 -1
- package/dist/providers/social/platform.d.ts.map +1 -1
- package/dist/providers/social/search-quality.d.ts +16 -0
- package/dist/providers/social/search-quality.d.ts.map +1 -0
- package/dist/providers/social/youtube-resolver.d.ts +2 -1
- package/dist/providers/social/youtube-resolver.d.ts.map +1 -1
- package/dist/providers/social/youtube.d.ts.map +1 -1
- package/dist/providers/types.d.ts +116 -4
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/web/crawl-worker.d.ts.map +1 -1
- package/dist/providers/web/extract.d.ts +16 -0
- package/dist/providers/web/extract.d.ts.map +1 -1
- package/dist/providers/web/index.d.ts.map +1 -1
- package/dist/providers/workflow-contracts.d.ts +53 -0
- package/dist/providers/workflow-contracts.d.ts.map +1 -0
- package/dist/providers/workflows.d.ts +30 -6
- package/dist/providers/workflows.d.ts.map +1 -1
- package/dist/{providers-G3LRHQXX.js → providers-G36AM3Z2.js} +2 -2
- package/dist/public-surface/generated-manifest.d.ts +1168 -0
- package/dist/public-surface/generated-manifest.d.ts.map +1 -0
- package/dist/public-surface/source.d.ts +437 -0
- package/dist/public-surface/source.d.ts.map +1 -0
- package/dist/relay/protocol.d.ts +25 -3
- package/dist/relay/protocol.d.ts.map +1 -1
- package/dist/relay/relay-endpoints.d.ts +21 -0
- package/dist/relay/relay-endpoints.d.ts.map +1 -1
- package/dist/relay/relay-server.d.ts +18 -0
- package/dist/relay/relay-server.d.ts.map +1 -1
- package/dist/skills/bundled-skill-directories.d.ts +8 -0
- package/dist/skills/bundled-skill-directories.d.ts.map +1 -0
- package/dist/skills/skill-loader.d.ts +9 -1
- package/dist/skills/skill-loader.d.ts.map +1 -1
- package/dist/skills/skill-loader.js +7 -0
- package/dist/skills/skill-nudge.d.ts.map +1 -1
- package/dist/skills/types.d.ts +31 -0
- package/dist/skills/types.d.ts.map +1 -1
- package/dist/snapshot/ops-snapshot.d.ts +1 -1
- package/dist/snapshot/ops-snapshot.d.ts.map +1 -1
- package/dist/snapshot/refs.d.ts +6 -1
- package/dist/snapshot/refs.d.ts.map +1 -1
- package/dist/snapshot/snapshotter.d.ts.map +1 -1
- package/dist/tools/connect.d.ts.map +1 -1
- package/dist/tools/deps.d.ts +4 -0
- package/dist/tools/deps.d.ts.map +1 -1
- package/dist/tools/desktop-shared.d.ts +6 -0
- package/dist/tools/desktop-shared.d.ts.map +1 -0
- package/dist/tools/desktop_accessibility_snapshot.d.ts +4 -0
- package/dist/tools/desktop_accessibility_snapshot.d.ts.map +1 -0
- package/dist/tools/desktop_active_window.d.ts +4 -0
- package/dist/tools/desktop_active_window.d.ts.map +1 -0
- package/dist/tools/desktop_capture_desktop.d.ts +4 -0
- package/dist/tools/desktop_capture_desktop.d.ts.map +1 -0
- package/dist/tools/desktop_capture_window.d.ts +4 -0
- package/dist/tools/desktop_capture_window.d.ts.map +1 -0
- package/dist/tools/desktop_status.d.ts +4 -0
- package/dist/tools/desktop_status.d.ts.map +1 -0
- package/dist/tools/desktop_windows.d.ts +4 -0
- package/dist/tools/desktop_windows.d.ts.map +1 -0
- package/dist/tools/dialog.d.ts +4 -0
- package/dist/tools/dialog.d.ts.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/launch.d.ts.map +1 -1
- package/dist/tools/macro_resolve.d.ts.map +1 -1
- package/dist/tools/pointer_down.d.ts +4 -0
- package/dist/tools/pointer_down.d.ts.map +1 -0
- package/dist/tools/pointer_drag.d.ts +4 -0
- package/dist/tools/pointer_drag.d.ts.map +1 -0
- package/dist/tools/pointer_move.d.ts +4 -0
- package/dist/tools/pointer_move.d.ts.map +1 -0
- package/dist/tools/pointer_up.d.ts +4 -0
- package/dist/tools/pointer_up.d.ts.map +1 -0
- package/dist/tools/product_video_run.d.ts.map +1 -1
- package/dist/tools/prompting_guide.d.ts.map +1 -1
- package/dist/tools/research_run.d.ts.map +1 -1
- package/dist/tools/review.d.ts +4 -0
- package/dist/tools/review.d.ts.map +1 -0
- package/dist/tools/screencast_start.d.ts +4 -0
- package/dist/tools/screencast_start.d.ts.map +1 -0
- package/dist/tools/screencast_stop.d.ts +4 -0
- package/dist/tools/screencast_stop.d.ts.map +1 -0
- package/dist/tools/screenshot.d.ts.map +1 -1
- package/dist/tools/session_inspector.d.ts +4 -0
- package/dist/tools/session_inspector.d.ts.map +1 -0
- package/dist/tools/shopping_run.d.ts.map +1 -1
- package/dist/tools/skill_list.d.ts.map +1 -1
- package/dist/tools/skill_load.d.ts.map +1 -1
- package/dist/tools/upload.d.ts +4 -0
- package/dist/tools/upload.d.ts.map +1 -0
- package/dist/tools/workflow-runtime.d.ts +4 -1
- package/dist/tools/workflow-runtime.d.ts.map +1 -1
- package/dist/utils/package-assets.d.ts +4 -0
- package/dist/utils/package-assets.d.ts.map +1 -0
- package/extension/canvas.html +379 -9
- package/extension/dist/annotate-content.js +62 -32
- package/extension/dist/annotation-payload.js +57 -21
- package/extension/dist/background.js +406 -61
- package/extension/dist/canvas/canvas-runtime.js +481 -52
- package/extension/dist/canvas/model.js +129 -1
- package/extension/dist/canvas-page.js +1882 -74
- package/extension/dist/ops/dom-bridge.js +139 -0
- package/extension/dist/ops/ops-runtime.js +2854 -295
- package/extension/dist/ops/ops-session-store.js +83 -5
- package/extension/dist/ops/snapshot-builder.js +2 -2
- package/extension/dist/ops/snapshot-shared.js +2 -2
- package/extension/dist/ops/target-session-coordinator.js +5 -3
- package/extension/dist/popup.js +50 -15
- package/extension/dist/services/CDPRouter.js +1567 -63
- package/extension/dist/services/ConnectionManager.js +436 -78
- package/extension/dist/services/RelayClient.js +70 -30
- package/extension/dist/services/TabManager.js +83 -10
- package/extension/dist/services/TargetSessionMap.js +127 -3
- package/extension/dist/services/attach-errors.js +20 -0
- package/extension/dist/services/cdp-router-commands.js +135 -8
- package/extension/dist/services/url-restrictions.js +9 -13
- package/extension/manifest.json +2 -2
- package/extension/popup.html +7 -6
- package/package.json +15 -7
- package/skills/AGENTS.md +9 -8
- package/skills/opendevbrowser-best-practices/SKILL.md +118 -9
- package/skills/opendevbrowser-best-practices/artifacts/browser-agent-known-issues-matrix.md +1 -0
- package/skills/opendevbrowser-best-practices/artifacts/command-channel-reference.md +26 -12
- package/skills/opendevbrowser-best-practices/artifacts/parity-gates.md +9 -2
- package/skills/opendevbrowser-best-practices/artifacts/provider-workflows.md +6 -0
- package/skills/opendevbrowser-best-practices/artifacts/skill-runtime-surface-matrix.md +58 -0
- package/skills/opendevbrowser-best-practices/assets/templates/skill-runtime-pack-matrix.json +674 -0
- package/skills/opendevbrowser-best-practices/assets/templates/surface-audit-checklist.json +9 -4
- package/skills/opendevbrowser-best-practices/scripts/odb-workflow.sh +89 -20
- package/skills/opendevbrowser-best-practices/scripts/resolve-odb-cli.sh +100 -0
- package/skills/opendevbrowser-best-practices/scripts/run-robustness-audit.sh +1 -0
- package/skills/opendevbrowser-best-practices/scripts/validate-skill-assets.sh +256 -116
- package/skills/opendevbrowser-best-practices/scripts/validator-fixture-cli.sh +208 -0
- package/skills/opendevbrowser-continuity-ledger/SKILL.md +14 -1
- package/skills/opendevbrowser-continuity-ledger/scripts/validate-skill-assets.sh +61 -0
- package/skills/opendevbrowser-data-extraction/SKILL.md +6 -0
- package/skills/opendevbrowser-data-extraction/scripts/validate-skill-assets.sh +112 -0
- package/skills/opendevbrowser-design-agent/SKILL.md +275 -0
- package/skills/opendevbrowser-design-agent/artifacts/app-shell-and-state-wiring.md +84 -0
- package/skills/opendevbrowser-design-agent/artifacts/async-search-state-ownership.md +58 -0
- package/skills/opendevbrowser-design-agent/artifacts/component-pattern-index.md +130 -0
- package/skills/opendevbrowser-design-agent/artifacts/design-contract-playbook.md +157 -0
- package/skills/opendevbrowser-design-agent/artifacts/design-release-gate.md +40 -0
- package/skills/opendevbrowser-design-agent/artifacts/design-workflows.md +153 -0
- package/skills/opendevbrowser-design-agent/artifacts/existing-surface-adaptation.md +56 -0
- package/skills/opendevbrowser-design-agent/artifacts/external-pattern-synthesis.md +103 -0
- package/skills/opendevbrowser-design-agent/artifacts/frontend-evaluation-rubric.md +61 -0
- package/skills/opendevbrowser-design-agent/artifacts/implementation-anti-patterns.md +163 -0
- package/skills/opendevbrowser-design-agent/artifacts/isolated-preview-validation.md +68 -0
- package/skills/opendevbrowser-design-agent/artifacts/loading-and-feedback-surfaces.md +56 -0
- package/skills/opendevbrowser-design-agent/artifacts/opendevbrowser-ui-example-map.md +44 -0
- package/skills/opendevbrowser-design-agent/artifacts/performance-audit-playbook.md +70 -0
- package/skills/opendevbrowser-design-agent/artifacts/research-harvest-workflow.md +81 -0
- package/skills/opendevbrowser-design-agent/artifacts/scroll-reveal-surface-planning.md +64 -0
- package/skills/opendevbrowser-design-agent/artifacts/state-ownership-matrix.md +36 -0
- package/skills/opendevbrowser-design-agent/artifacts/theming-and-token-ownership.md +43 -0
- package/skills/opendevbrowser-design-agent/assets/templates/canvas-generation-plan.design.v1.json +58 -0
- package/skills/opendevbrowser-design-agent/assets/templates/design-audit-report.v1.md +34 -0
- package/skills/opendevbrowser-design-agent/assets/templates/design-brief.v1.md +40 -0
- package/skills/opendevbrowser-design-agent/assets/templates/design-contract.v1.json +226 -0
- package/skills/opendevbrowser-design-agent/assets/templates/design-release-gate.v1.json +35 -0
- package/skills/opendevbrowser-design-agent/assets/templates/design-review-checklist.json +57 -0
- package/skills/opendevbrowser-design-agent/assets/templates/real-surface-design-matrix.json +32 -0
- package/skills/opendevbrowser-design-agent/assets/templates/reference-pattern-board.v1.json +31 -0
- package/skills/opendevbrowser-design-agent/scripts/design-workflow.sh +171 -0
- package/skills/opendevbrowser-design-agent/scripts/extract-canvas-plan.sh +56 -0
- package/skills/opendevbrowser-design-agent/scripts/validate-skill-assets.sh +223 -0
- package/skills/opendevbrowser-form-testing/SKILL.md +19 -3
- package/skills/opendevbrowser-form-testing/artifacts/form-workflows.md +5 -4
- package/skills/opendevbrowser-form-testing/assets/templates/challenge-decision-tree.json +2 -0
- package/skills/opendevbrowser-form-testing/scripts/validate-skill-assets.sh +109 -0
- package/skills/opendevbrowser-login-automation/SKILL.md +21 -3
- package/skills/opendevbrowser-login-automation/artifacts/login-workflows.md +5 -4
- package/skills/opendevbrowser-login-automation/assets/templates/auth-signals.json +5 -0
- package/skills/opendevbrowser-login-automation/assets/templates/login-scenario-matrix.json +3 -2
- package/skills/opendevbrowser-login-automation/scripts/run-login-workflow.sh +17 -1
- package/skills/opendevbrowser-login-automation/scripts/validate-skill-assets.sh +133 -0
- package/skills/opendevbrowser-product-presentation-asset/SKILL.md +23 -11
- package/skills/opendevbrowser-product-presentation-asset/artifacts/asset-pack-assembly.md +5 -3
- package/skills/opendevbrowser-product-presentation-asset/assets/templates/shot-list.md +2 -0
- package/skills/opendevbrowser-product-presentation-asset/assets/templates/video-assembly.md +3 -2
- package/skills/opendevbrowser-product-presentation-asset/scripts/capture-screenshots.sh +5 -1
- package/skills/opendevbrowser-product-presentation-asset/scripts/collect-product.sh +6 -2
- package/skills/opendevbrowser-product-presentation-asset/scripts/download-images.sh +5 -1
- package/skills/opendevbrowser-product-presentation-asset/scripts/render-video-brief.sh +20 -7
- package/skills/opendevbrowser-product-presentation-asset/scripts/validate-skill-assets.sh +39 -0
- package/skills/opendevbrowser-product-presentation-asset/scripts/write-manifest.sh +5 -1
- package/skills/opendevbrowser-research/SKILL.md +14 -6
- package/skills/opendevbrowser-research/scripts/render-output.sh +5 -1
- package/skills/opendevbrowser-research/scripts/run-research.sh +5 -1
- package/skills/opendevbrowser-research/scripts/validate-skill-assets.sh +45 -0
- package/skills/opendevbrowser-research/scripts/write-artifacts.sh +5 -1
- package/skills/opendevbrowser-shopping/SKILL.md +20 -1
- package/skills/opendevbrowser-shopping/scripts/normalize-offers.sh +6 -2
- package/skills/opendevbrowser-shopping/scripts/run-deal-hunt.sh +5 -1
- package/skills/opendevbrowser-shopping/scripts/run-shopping.sh +5 -1
- package/skills/opendevbrowser-shopping/scripts/validate-skill-assets.sh +54 -0
- package/dist/chunk-5J3IFL3X.js +0 -16706
- package/dist/chunk-5J3IFL3X.js.map +0 -1
- package/dist/chunk-D633UO34.js +0 -8149
- package/dist/chunk-D633UO34.js.map +0 -1
- package/dist/chunk-V7KUDHDG.js +0 -276
- package/dist/chunk-V7KUDHDG.js.map +0 -1
- package/dist/runtime-factory-BICHDPE7.js +0 -13
- /package/dist/{providers-G3LRHQXX.js.map → providers-G36AM3Z2.js.map} +0 -0
- /package/dist/{runtime-factory-BICHDPE7.js.map → skills/skill-loader.js.map} +0 -0
|
@@ -29,6 +29,20 @@ const logInfo = (message) => {
|
|
|
29
29
|
const logWarn = (message) => {
|
|
30
30
|
console.warn(`[opendevbrowser] ${message}`);
|
|
31
31
|
};
|
|
32
|
+
const getTrackedTabUrl = (tab) => {
|
|
33
|
+
if (!tab) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const pendingUrl = typeof tab.pendingUrl === "string" && tab.pendingUrl.length > 0 ? tab.pendingUrl : undefined;
|
|
37
|
+
const currentUrl = typeof tab.url === "string" && tab.url.length > 0 ? tab.url : undefined;
|
|
38
|
+
return pendingUrl ?? currentUrl;
|
|
39
|
+
};
|
|
40
|
+
const getTrackedTabTitle = (tab) => {
|
|
41
|
+
if (!tab || tab.status === "loading") {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
return typeof tab.title === "string" && tab.title.length > 0 ? tab.title : undefined;
|
|
45
|
+
};
|
|
32
46
|
const RECONNECT_INITIAL_DELAY_MS = 12_000;
|
|
33
47
|
const RECONNECT_MAX_DELAY_MS = 30_000;
|
|
34
48
|
export class ConnectionManager {
|
|
@@ -58,6 +72,8 @@ export class ConnectionManager {
|
|
|
58
72
|
canvasHandler = null;
|
|
59
73
|
heartbeatTimer = null;
|
|
60
74
|
heartbeatInFlight = false;
|
|
75
|
+
handshakeRefreshQueued = false;
|
|
76
|
+
handshakeRefreshPromise = null;
|
|
61
77
|
heartbeatIntervalMs = 25_000;
|
|
62
78
|
heartbeatTimeoutMs = 2_000;
|
|
63
79
|
constructor() {
|
|
@@ -143,13 +159,82 @@ export class ConnectionManager {
|
|
|
143
159
|
return null;
|
|
144
160
|
}
|
|
145
161
|
try {
|
|
146
|
-
|
|
162
|
+
const health = await this.relay.sendHealthCheck();
|
|
163
|
+
if (health.extensionConnected && !health.extensionHandshakeComplete) {
|
|
164
|
+
this.relayNotice = "Extension websocket is connected but the daemon-extension handshake is unhealthy. Re-establishing a clean handshake.";
|
|
165
|
+
this.refreshHandshake();
|
|
166
|
+
}
|
|
167
|
+
return health;
|
|
147
168
|
}
|
|
148
169
|
catch (error) {
|
|
149
170
|
logError("relay.health_check", error, { code: "relay_health_failed" });
|
|
150
171
|
return null;
|
|
151
172
|
}
|
|
152
173
|
}
|
|
174
|
+
async sendAnnotationCommand(command, timeoutMs = 5000) {
|
|
175
|
+
const socket = new WebSocket(this.buildAnnotationUrl());
|
|
176
|
+
let settled = false;
|
|
177
|
+
return await new Promise((resolve, reject) => {
|
|
178
|
+
const timeoutId = setTimeout(() => {
|
|
179
|
+
finish(() => reject(new Error("Annotation relay request timed out")));
|
|
180
|
+
}, timeoutMs);
|
|
181
|
+
const finish = (callback) => {
|
|
182
|
+
if (settled) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
settled = true;
|
|
186
|
+
clearTimeout(timeoutId);
|
|
187
|
+
try {
|
|
188
|
+
if (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING) {
|
|
189
|
+
socket.close(1000, "annotation-command-complete");
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
// Ignore socket close failures during cleanup.
|
|
194
|
+
}
|
|
195
|
+
callback();
|
|
196
|
+
};
|
|
197
|
+
socket.addEventListener("open", () => {
|
|
198
|
+
try {
|
|
199
|
+
socket.send(JSON.stringify({
|
|
200
|
+
type: "annotationCommand",
|
|
201
|
+
payload: command
|
|
202
|
+
}));
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
finish(() => reject(error instanceof Error ? error : new Error("Annotation relay send failed")));
|
|
206
|
+
}
|
|
207
|
+
}, { once: true });
|
|
208
|
+
socket.addEventListener("message", (event) => {
|
|
209
|
+
if (typeof event.data !== "string") {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
const message = JSON.parse(event.data);
|
|
214
|
+
if (message.type !== "annotationResponse") {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const payload = message.payload;
|
|
218
|
+
if (!isAnnotationResponse(payload) || payload.requestId !== command.requestId) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
finish(() => resolve(payload));
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// Ignore malformed one-off annotation responses.
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
socket.addEventListener("error", () => {
|
|
228
|
+
finish(() => reject(new Error("Annotation relay unavailable")));
|
|
229
|
+
}, { once: true });
|
|
230
|
+
socket.addEventListener("close", () => {
|
|
231
|
+
if (settled) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
finish(() => reject(new Error("Annotation relay closed")));
|
|
235
|
+
}, { once: true });
|
|
236
|
+
});
|
|
237
|
+
}
|
|
153
238
|
async connect() {
|
|
154
239
|
if (this.connectPromise) {
|
|
155
240
|
return await this.connectPromise;
|
|
@@ -193,6 +278,7 @@ export class ConnectionManager {
|
|
|
193
278
|
this.shouldReconnect = false;
|
|
194
279
|
this.clearReconnectTimer();
|
|
195
280
|
this.stopHeartbeat();
|
|
281
|
+
this.handshakeRefreshQueued = false;
|
|
196
282
|
try {
|
|
197
283
|
if (this.relay) {
|
|
198
284
|
this.relay.disconnect();
|
|
@@ -228,6 +314,38 @@ export class ConnectionManager {
|
|
|
228
314
|
logError(context, error, { code: "relay_send_failed" });
|
|
229
315
|
}
|
|
230
316
|
}
|
|
317
|
+
async getFirstHttpFallbackTab(currentTabId) {
|
|
318
|
+
const fallbackTab = await this.tabs.getFirstAttachableTab(currentTabId);
|
|
319
|
+
if (!fallbackTab || typeof fallbackTab.id !== "number" || !fallbackTab.url) {
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
logInfo("Falling back to first http(s) tab.");
|
|
323
|
+
return fallbackTab;
|
|
324
|
+
}
|
|
325
|
+
async bootstrapRelayAttachTab() {
|
|
326
|
+
try {
|
|
327
|
+
const fallbackTab = await this.tabs.createTab("about:blank", true);
|
|
328
|
+
if (fallbackTab && typeof fallbackTab.id === "number") {
|
|
329
|
+
logInfo("Bootstrapping a fresh browser tab for relay attach.");
|
|
330
|
+
return fallbackTab;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
// Ignore tab creation failures and let the caller surface the original error.
|
|
335
|
+
}
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
async resolveRelayAttachFallback(currentTabId) {
|
|
339
|
+
const httpTab = await this.getFirstHttpFallbackTab(currentTabId);
|
|
340
|
+
if (httpTab) {
|
|
341
|
+
return { tab: httpTab, allowBlankRelayFallback: false };
|
|
342
|
+
}
|
|
343
|
+
const blankTab = await this.bootstrapRelayAttachTab();
|
|
344
|
+
if (blankTab) {
|
|
345
|
+
return { tab: blankTab, allowBlankRelayFallback: true };
|
|
346
|
+
}
|
|
347
|
+
return { tab: null, allowBlankRelayFallback: false };
|
|
348
|
+
}
|
|
231
349
|
startHeartbeat() {
|
|
232
350
|
if (this.heartbeatTimer !== null) {
|
|
233
351
|
return;
|
|
@@ -254,7 +372,15 @@ export class ConnectionManager {
|
|
|
254
372
|
}
|
|
255
373
|
this.heartbeatInFlight = true;
|
|
256
374
|
try {
|
|
257
|
-
await this.relay.sendPing(this.heartbeatTimeoutMs);
|
|
375
|
+
const health = await this.relay.sendPing(this.heartbeatTimeoutMs);
|
|
376
|
+
if (health.extensionConnected && !health.extensionHandshakeComplete) {
|
|
377
|
+
this.relayNotice = "Extension websocket is connected but the daemon-extension handshake is incomplete. Re-establishing a clean handshake.";
|
|
378
|
+
this.refreshHandshake();
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
if (health.ok) {
|
|
382
|
+
this.relayNotice = null;
|
|
383
|
+
}
|
|
258
384
|
}
|
|
259
385
|
catch (error) {
|
|
260
386
|
logError("relay.heartbeat", error, { code: "relay_heartbeat_failed" });
|
|
@@ -268,29 +394,35 @@ export class ConnectionManager {
|
|
|
268
394
|
}
|
|
269
395
|
async attachToActiveTab() {
|
|
270
396
|
let tab = await this.tabs.getActiveTab();
|
|
397
|
+
let allowBlankRelayFallback = false;
|
|
398
|
+
let tabUrl = getTrackedTabUrl(tab);
|
|
271
399
|
if (!tab || typeof tab.id !== "number") {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
400
|
+
const fallback = await this.resolveRelayAttachFallback();
|
|
401
|
+
tab = fallback.tab;
|
|
402
|
+
allowBlankRelayFallback = fallback.allowBlankRelayFallback;
|
|
403
|
+
tabUrl = getTrackedTabUrl(tab);
|
|
404
|
+
if (!tab || typeof tab.id !== "number") {
|
|
405
|
+
this.trackedTab = null;
|
|
406
|
+
this.setStatus("disconnected");
|
|
407
|
+
logWarn("Active tab not found.");
|
|
408
|
+
throw new ConnectionError("no_active_tab", "No active browser page found. Focus the site tab or popup window you want to automate, not the extension popup, and retry.");
|
|
409
|
+
}
|
|
276
410
|
}
|
|
277
|
-
if (!
|
|
411
|
+
if (!tabUrl) {
|
|
278
412
|
logWarn("Active tab URL missing.");
|
|
279
|
-
const
|
|
280
|
-
if (
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
tab = fallbackTab;
|
|
285
|
-
}
|
|
413
|
+
const fallback = await this.resolveRelayAttachFallback(tab.id);
|
|
414
|
+
if (fallback.tab) {
|
|
415
|
+
tab = fallback.tab;
|
|
416
|
+
allowBlankRelayFallback ||= fallback.allowBlankRelayFallback;
|
|
417
|
+
tabUrl = getTrackedTabUrl(tab);
|
|
286
418
|
}
|
|
287
|
-
if (!
|
|
419
|
+
if (!tabUrl) {
|
|
288
420
|
throw new ConnectionError("tab_url_missing", "Active tab URL is unavailable. Reload the tab and retry.");
|
|
289
421
|
}
|
|
290
422
|
}
|
|
291
423
|
let parsedUrl = null;
|
|
292
424
|
try {
|
|
293
|
-
parsedUrl = new URL(
|
|
425
|
+
parsedUrl = tabUrl ? new URL(tabUrl) : null;
|
|
294
426
|
}
|
|
295
427
|
catch (error) {
|
|
296
428
|
logError("connection.parse_tab_url", error, { code: "tab_url_parse_failed" });
|
|
@@ -298,54 +430,48 @@ export class ConnectionManager {
|
|
|
298
430
|
}
|
|
299
431
|
if (!parsedUrl) {
|
|
300
432
|
logWarn("Active tab URL is invalid.");
|
|
301
|
-
const
|
|
302
|
-
if (
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
parsedUrl = null;
|
|
312
|
-
}
|
|
433
|
+
const fallback = await this.resolveRelayAttachFallback(tab.id);
|
|
434
|
+
if (fallback.tab) {
|
|
435
|
+
tab = fallback.tab;
|
|
436
|
+
allowBlankRelayFallback ||= fallback.allowBlankRelayFallback;
|
|
437
|
+
tabUrl = getTrackedTabUrl(tab);
|
|
438
|
+
try {
|
|
439
|
+
parsedUrl = tabUrl ? new URL(tabUrl) : null;
|
|
440
|
+
}
|
|
441
|
+
catch {
|
|
442
|
+
parsedUrl = null;
|
|
313
443
|
}
|
|
314
444
|
}
|
|
315
445
|
if (!parsedUrl) {
|
|
316
|
-
throw new ConnectionError("tab_url_restricted", "Active
|
|
446
|
+
throw new ConnectionError("tab_url_restricted", "Active browser page URL is unsupported. Focus an http(s) page or site popup window, not the extension popup, and retry.");
|
|
317
447
|
}
|
|
318
448
|
}
|
|
319
449
|
const restrictionMessage = getRestrictionMessage(parsedUrl);
|
|
320
450
|
if (restrictionMessage) {
|
|
321
|
-
logWarn(`Active tab blocked: ${summarizeProtocol(
|
|
322
|
-
const
|
|
323
|
-
if (
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
parsedUrl = fallbackUrl;
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
catch {
|
|
336
|
-
// Ignore invalid fallback URL.
|
|
337
|
-
}
|
|
451
|
+
logWarn(`Active tab blocked: ${summarizeProtocol(tabUrl)} scheme.`);
|
|
452
|
+
const fallback = await this.resolveRelayAttachFallback(tab.id);
|
|
453
|
+
if (fallback.tab) {
|
|
454
|
+
tab = fallback.tab;
|
|
455
|
+
allowBlankRelayFallback ||= fallback.allowBlankRelayFallback;
|
|
456
|
+
tabUrl = getTrackedTabUrl(tab);
|
|
457
|
+
try {
|
|
458
|
+
parsedUrl = tabUrl ? new URL(tabUrl) : null;
|
|
459
|
+
}
|
|
460
|
+
catch {
|
|
461
|
+
parsedUrl = null;
|
|
338
462
|
}
|
|
339
463
|
}
|
|
340
|
-
if (restrictionMessage && getRestrictionMessage(parsedUrl)) {
|
|
341
|
-
|
|
464
|
+
if (restrictionMessage && (!parsedUrl || getRestrictionMessage(parsedUrl))) {
|
|
465
|
+
if (!allowBlankRelayFallback) {
|
|
466
|
+
throw new ConnectionError("tab_url_restricted", restrictionMessage);
|
|
467
|
+
}
|
|
342
468
|
}
|
|
343
469
|
}
|
|
344
470
|
const tabId = tab.id;
|
|
345
471
|
if (typeof tabId !== "number") {
|
|
346
472
|
this.trackedTab = null;
|
|
347
473
|
this.setStatus("disconnected");
|
|
348
|
-
throw new ConnectionError("no_active_tab", "No active browser
|
|
474
|
+
throw new ConnectionError("no_active_tab", "No active browser page found. Focus the site tab or popup window you want to automate, not the extension popup, and retry.");
|
|
349
475
|
}
|
|
350
476
|
logInfo("Active tab resolved.");
|
|
351
477
|
try {
|
|
@@ -360,12 +486,7 @@ export class ConnectionManager {
|
|
|
360
486
|
: "Debugger attach failed. Close DevTools for the tab and retry.";
|
|
361
487
|
throw new ConnectionError("debugger_attach_failed", message);
|
|
362
488
|
}
|
|
363
|
-
this.trackedTab =
|
|
364
|
-
id: tabId,
|
|
365
|
-
url: tab.url ?? undefined,
|
|
366
|
-
title: tab.title ?? undefined,
|
|
367
|
-
groupId: typeof tab.groupId === "number" ? tab.groupId : undefined
|
|
368
|
-
};
|
|
489
|
+
this.trackedTab = this.toTrackedTab(tab, null);
|
|
369
490
|
}
|
|
370
491
|
async connectRelay() {
|
|
371
492
|
if (!this.trackedTab) {
|
|
@@ -378,6 +499,9 @@ export class ConnectionManager {
|
|
|
378
499
|
this.handleCdpDetach({ reason: "cdp_command_failed" });
|
|
379
500
|
});
|
|
380
501
|
},
|
|
502
|
+
onCdpControl: (message) => {
|
|
503
|
+
this.handleCdpControl(message);
|
|
504
|
+
},
|
|
381
505
|
onAnnotationCommand: (command) => {
|
|
382
506
|
this.annotationHandler?.(command);
|
|
383
507
|
},
|
|
@@ -420,6 +544,10 @@ export class ConnectionManager {
|
|
|
420
544
|
if (!mismatch) {
|
|
421
545
|
this.persistRelayIdentity(ack.payload.relayPort, this.relayInstanceId, this.relayEpoch);
|
|
422
546
|
}
|
|
547
|
+
const handshakeHealthy = await this.verifyHandshakeHealth(relay, "connect");
|
|
548
|
+
if (!handshakeHealthy) {
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
423
551
|
logInfo("Relay WebSocket connected.");
|
|
424
552
|
this.setStatus("connected");
|
|
425
553
|
this.startHeartbeat();
|
|
@@ -438,6 +566,7 @@ export class ConnectionManager {
|
|
|
438
566
|
handleRelayClose(detail) {
|
|
439
567
|
this.stopHeartbeat();
|
|
440
568
|
this.relay = null;
|
|
569
|
+
this.cdp.markClientClosed();
|
|
441
570
|
if (detail && (detail.code === 1008 || detail.reason?.includes("Invalid pairing token"))) {
|
|
442
571
|
this.clearStoredPairingToken();
|
|
443
572
|
}
|
|
@@ -465,6 +594,10 @@ export class ConnectionManager {
|
|
|
465
594
|
if (this.cdp.getAttachedTabIds().length > 0) {
|
|
466
595
|
return;
|
|
467
596
|
}
|
|
597
|
+
if (detail?.reason === "manual_disconnect") {
|
|
598
|
+
void this.recoverFromManualDetach(detail);
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
468
601
|
this.setStatus("disconnected");
|
|
469
602
|
if (this.relay?.isConnected()) {
|
|
470
603
|
this.relay.disconnect();
|
|
@@ -472,12 +605,49 @@ export class ConnectionManager {
|
|
|
472
605
|
}
|
|
473
606
|
this.scheduleReconnect();
|
|
474
607
|
}
|
|
608
|
+
async recoverFromManualDetach(detail) {
|
|
609
|
+
try {
|
|
610
|
+
const preferredTabId = typeof detail?.tabId === "number" ? detail.tabId : this.trackedTab?.id ?? null;
|
|
611
|
+
if (typeof preferredTabId === "number") {
|
|
612
|
+
await this.cdp.attach(preferredTabId);
|
|
613
|
+
const recoveredTabId = this.cdp.getPrimaryTabId() ?? preferredTabId;
|
|
614
|
+
await this.refreshTrackedTab(recoveredTabId, { preserveCurrentOnRestricted: true });
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
await this.attachToActiveTab();
|
|
618
|
+
}
|
|
619
|
+
if (!this.relay?.isConnected()) {
|
|
620
|
+
this.scheduleReconnect();
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
this.setStatus("connected");
|
|
624
|
+
this.refreshHandshake();
|
|
625
|
+
}
|
|
626
|
+
catch (error) {
|
|
627
|
+
logError("connection.manual_detach_recover", error, { code: "tracked_tab_refresh_failed" });
|
|
628
|
+
this.setStatus("disconnected");
|
|
629
|
+
if (this.relay?.isConnected()) {
|
|
630
|
+
this.relay.disconnect();
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
this.scheduleReconnect();
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
handleCdpControl(message) {
|
|
637
|
+
if (message.action !== "client_closed") {
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
this.cdp.markClientClosed();
|
|
641
|
+
}
|
|
475
642
|
scheduleReconnect() {
|
|
476
643
|
if (this.reconnectTimer !== null) {
|
|
477
644
|
return;
|
|
478
645
|
}
|
|
479
646
|
this.reconnectTimer = setTimeout(() => {
|
|
480
647
|
this.reconnectTimer = null;
|
|
648
|
+
if (!this.shouldReconnect || this.status === "connected" || this.relay?.isConnected()) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
481
651
|
this.reconnectAttempts += 1;
|
|
482
652
|
this.reconnectDelayMs = Math.min(this.reconnectDelayMs * 2, this.maxReconnectDelayMs);
|
|
483
653
|
this.reconnectRelay().catch((error) => {
|
|
@@ -487,7 +657,7 @@ export class ConnectionManager {
|
|
|
487
657
|
}, this.reconnectDelayMs);
|
|
488
658
|
}
|
|
489
659
|
async reconnectRelay() {
|
|
490
|
-
if (!this.shouldReconnect) {
|
|
660
|
+
if (!this.shouldReconnect || this.status === "connected" || this.relay?.isConnected()) {
|
|
491
661
|
return;
|
|
492
662
|
}
|
|
493
663
|
const primaryId = this.cdp.getPrimaryTabId();
|
|
@@ -544,24 +714,59 @@ export class ConnectionManager {
|
|
|
544
714
|
if (!this.trackedTab || this.trackedTab.id !== tabId) {
|
|
545
715
|
return;
|
|
546
716
|
}
|
|
547
|
-
|
|
717
|
+
const attachedTabIds = this.cdp.getAttachedTabIds().filter((attachedId) => attachedId !== tabId);
|
|
718
|
+
if (attachedTabIds.length === 0) {
|
|
548
719
|
this.disconnect().catch((error) => {
|
|
549
720
|
logError("connection.tab_removed_disconnect", error, { code: "disconnect_failed" });
|
|
550
721
|
});
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
const primaryTabId = this.cdp.getPrimaryTabId();
|
|
725
|
+
const nextTrackedTabId = primaryTabId && primaryTabId !== tabId
|
|
726
|
+
? primaryTabId
|
|
727
|
+
: attachedTabIds[0] ?? null;
|
|
728
|
+
if (!nextTrackedTabId) {
|
|
729
|
+
this.disconnect().catch((error) => {
|
|
730
|
+
logError("connection.tab_removed_disconnect", error, { code: "disconnect_failed" });
|
|
731
|
+
});
|
|
732
|
+
return;
|
|
551
733
|
}
|
|
734
|
+
this.refreshTrackedTab(nextTrackedTabId, { preserveCurrentOnRestricted: true })
|
|
735
|
+
.then(() => {
|
|
736
|
+
this.refreshHandshake();
|
|
737
|
+
})
|
|
738
|
+
.catch((error) => {
|
|
739
|
+
logError("connection.tab_removed_refresh", error, { code: "tracked_tab_refresh_failed" });
|
|
740
|
+
});
|
|
552
741
|
};
|
|
553
742
|
handleTabUpdated = (_tabId, _changeInfo, tab) => {
|
|
554
|
-
|
|
743
|
+
const updatedTabId = typeof tab.id === "number" ? tab.id : null;
|
|
744
|
+
if (updatedTabId === null) {
|
|
555
745
|
return;
|
|
556
746
|
}
|
|
557
|
-
this.trackedTab
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
747
|
+
const trackedTabId = this.trackedTab?.id ?? null;
|
|
748
|
+
const primaryTabId = this.cdp.getPrimaryTabId();
|
|
749
|
+
if (trackedTabId !== updatedTabId && primaryTabId !== updatedTabId) {
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
if (trackedTabId !== updatedTabId) {
|
|
753
|
+
if (!this.isRestrictedTab(tab)) {
|
|
754
|
+
this.setTrackedTab(tab);
|
|
755
|
+
this.refreshHandshake();
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
this.refreshTrackedTab(updatedTabId, { preserveCurrentOnRestricted: true })
|
|
759
|
+
.then(() => {
|
|
760
|
+
this.refreshHandshake();
|
|
761
|
+
})
|
|
762
|
+
.catch((error) => {
|
|
763
|
+
logError("connection.tab_updated_refresh", error, { code: "tracked_tab_refresh_failed" });
|
|
764
|
+
});
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
this.setTrackedTab(tab);
|
|
563
768
|
if (this.relay?.isConnected()) {
|
|
564
|
-
this.
|
|
769
|
+
this.refreshHandshake();
|
|
565
770
|
}
|
|
566
771
|
};
|
|
567
772
|
async loadSettings() {
|
|
@@ -584,7 +789,7 @@ export class ConnectionManager {
|
|
|
584
789
|
}
|
|
585
790
|
return {
|
|
586
791
|
code: "unknown",
|
|
587
|
-
message: "Connection failed. Focus
|
|
792
|
+
message: "Connection failed. Focus the site tab or popup window you want to automate, not the extension popup, and retry."
|
|
588
793
|
};
|
|
589
794
|
}
|
|
590
795
|
updatePairingToken(value) {
|
|
@@ -666,9 +871,9 @@ export class ConnectionManager {
|
|
|
666
871
|
this.clearStoredRelayIdentity();
|
|
667
872
|
this.clearStoredPairingToken(false);
|
|
668
873
|
this.relayNotice = instanceMismatch
|
|
669
|
-
? "Relay instance changed. Re-
|
|
670
|
-
: "Relay restarted. Re-
|
|
671
|
-
this.
|
|
874
|
+
? "Relay instance changed. Re-establishing a clean daemon-extension handshake."
|
|
875
|
+
: "Relay restarted. Re-establishing a clean daemon-extension handshake.";
|
|
876
|
+
this.refreshHandshake();
|
|
672
877
|
return true;
|
|
673
878
|
}
|
|
674
879
|
this.relayNotice = null;
|
|
@@ -682,6 +887,13 @@ export class ConnectionManager {
|
|
|
682
887
|
buildRelayUrl() {
|
|
683
888
|
return `ws://127.0.0.1:${this.relayPort}/extension`;
|
|
684
889
|
}
|
|
890
|
+
buildAnnotationUrl() {
|
|
891
|
+
const port = this.relayConfirmedPort ?? this.relayPort;
|
|
892
|
+
const query = this.pairingEnabled && this.pairingToken
|
|
893
|
+
? `?token=${encodeURIComponent(this.pairingToken)}`
|
|
894
|
+
: "";
|
|
895
|
+
return `ws://127.0.0.1:${port}/annotation${query}`;
|
|
896
|
+
}
|
|
685
897
|
async refreshRelay() {
|
|
686
898
|
if (this.status !== "connected")
|
|
687
899
|
return;
|
|
@@ -690,26 +902,101 @@ export class ConnectionManager {
|
|
|
690
902
|
}
|
|
691
903
|
async handlePrimaryTabChange(tabId) {
|
|
692
904
|
if (!tabId) {
|
|
905
|
+
const trackedTabId = this.trackedTab?.id;
|
|
906
|
+
if (this.shouldReconnect && !this.disconnecting && typeof trackedTabId === "number") {
|
|
907
|
+
const trackedTab = await this.tabs.getTab(trackedTabId);
|
|
908
|
+
if (trackedTab && typeof trackedTab.id === "number") {
|
|
909
|
+
await this.refreshTrackedTab(trackedTab.id, { preserveCurrentOnRestricted: true });
|
|
910
|
+
this.refreshHandshake();
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
693
914
|
this.trackedTab = null;
|
|
694
915
|
if (this.relay?.isConnected()) {
|
|
695
916
|
this.relay.disconnect();
|
|
696
917
|
}
|
|
697
918
|
return;
|
|
698
919
|
}
|
|
699
|
-
await this.refreshTrackedTab(tabId);
|
|
920
|
+
await this.refreshTrackedTab(tabId, { preserveCurrentOnRestricted: true });
|
|
700
921
|
this.refreshHandshake();
|
|
701
922
|
}
|
|
702
|
-
|
|
703
|
-
const
|
|
923
|
+
isRestrictedTab(tab) {
|
|
924
|
+
const rawUrl = getTrackedTabUrl(tab);
|
|
925
|
+
if (!rawUrl) {
|
|
926
|
+
return true;
|
|
927
|
+
}
|
|
928
|
+
try {
|
|
929
|
+
return Boolean(getRestrictionMessage(new URL(rawUrl)));
|
|
930
|
+
}
|
|
931
|
+
catch {
|
|
932
|
+
return true;
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
async refreshTrackedTab(tabId, options) {
|
|
936
|
+
const previous = this.trackedTab;
|
|
937
|
+
let tab = await this.tabs.getTab(tabId);
|
|
938
|
+
if ((!tab || typeof tab.id !== "number") && options?.preserveCurrentOnRestricted && previous) {
|
|
939
|
+
this.trackedTab = previous;
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
704
942
|
if (!tab || typeof tab.id !== "number") {
|
|
705
943
|
this.trackedTab = null;
|
|
706
944
|
return;
|
|
707
945
|
}
|
|
708
|
-
this.
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
946
|
+
if (this.isRestrictedTab(tab)) {
|
|
947
|
+
const httpFallback = await this.getFirstHttpFallbackTab(tab.id);
|
|
948
|
+
if (httpFallback) {
|
|
949
|
+
tab = httpFallback;
|
|
950
|
+
}
|
|
951
|
+
else if (options?.preserveCurrentOnRestricted && previous) {
|
|
952
|
+
this.trackedTab = previous;
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
else {
|
|
956
|
+
const blankFallback = await this.bootstrapRelayAttachTab();
|
|
957
|
+
if (blankFallback) {
|
|
958
|
+
tab = blankFallback;
|
|
959
|
+
}
|
|
960
|
+
else {
|
|
961
|
+
this.trackedTab = null;
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
const nextTrackedTabId = tab.id;
|
|
967
|
+
if (typeof nextTrackedTabId !== "number") {
|
|
968
|
+
if (options?.preserveCurrentOnRestricted && previous) {
|
|
969
|
+
this.trackedTab = previous;
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
this.trackedTab = null;
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
this.setTrackedTab(tab);
|
|
976
|
+
}
|
|
977
|
+
setTrackedTab(tab) {
|
|
978
|
+
const tabId = typeof tab.id === "number" ? tab.id : null;
|
|
979
|
+
if (tabId === null) {
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
this.trackedTab = this.toTrackedTab(tab, this.trackedTab);
|
|
983
|
+
}
|
|
984
|
+
toTrackedTab(tab, previous) {
|
|
985
|
+
const tabId = typeof tab.id === "number" ? tab.id : null;
|
|
986
|
+
if (tabId === null) {
|
|
987
|
+
throw new Error("Tracked tab id is missing");
|
|
988
|
+
}
|
|
989
|
+
const sameTab = previous?.id === tabId;
|
|
990
|
+
const url = getTrackedTabUrl(tab) ?? (sameTab ? previous?.url : undefined);
|
|
991
|
+
const title = getTrackedTabTitle(tab) ?? (sameTab ? previous?.title : undefined);
|
|
992
|
+
const groupId = typeof tab.groupId === "number"
|
|
993
|
+
? tab.groupId
|
|
994
|
+
: (sameTab ? previous?.groupId : undefined);
|
|
995
|
+
return {
|
|
996
|
+
id: tabId,
|
|
997
|
+
...(url ? { url } : {}),
|
|
998
|
+
...(title ? { title } : {}),
|
|
999
|
+
...(typeof groupId === "number" ? { groupId } : {})
|
|
713
1000
|
};
|
|
714
1001
|
}
|
|
715
1002
|
clearReconnectTimer() {
|
|
@@ -718,10 +1005,81 @@ export class ConnectionManager {
|
|
|
718
1005
|
this.reconnectTimer = null;
|
|
719
1006
|
}
|
|
720
1007
|
}
|
|
1008
|
+
async verifyHandshakeHealth(relay, source) {
|
|
1009
|
+
try {
|
|
1010
|
+
const health = await relay.sendPing(this.heartbeatTimeoutMs);
|
|
1011
|
+
if (health.extensionConnected && health.extensionHandshakeComplete) {
|
|
1012
|
+
if (this.relay === relay) {
|
|
1013
|
+
this.relayNotice = null;
|
|
1014
|
+
}
|
|
1015
|
+
return true;
|
|
1016
|
+
}
|
|
1017
|
+
if (this.relay === relay) {
|
|
1018
|
+
this.relayNotice = "Extension websocket is connected but the daemon-extension handshake is still incomplete. Retrying a clean handshake.";
|
|
1019
|
+
if (this.shouldReconnect && !this.disconnecting) {
|
|
1020
|
+
relay.disconnect();
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
catch (error) {
|
|
1025
|
+
logError(`relay.${source}_handshake_health`, error, { code: "relay_handshake_health_failed" });
|
|
1026
|
+
if (this.relay === relay) {
|
|
1027
|
+
this.relayNotice = "Failed to verify a clean daemon-extension handshake. Retrying the relay connection.";
|
|
1028
|
+
if (this.shouldReconnect && !this.disconnecting) {
|
|
1029
|
+
relay.disconnect();
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
return false;
|
|
1034
|
+
}
|
|
721
1035
|
refreshHandshake() {
|
|
722
1036
|
if (!this.trackedTab || !this.relay?.isConnected()) {
|
|
723
1037
|
return;
|
|
724
1038
|
}
|
|
725
|
-
this.
|
|
1039
|
+
this.handshakeRefreshQueued = true;
|
|
1040
|
+
if (this.handshakeRefreshPromise) {
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
const run = (async () => {
|
|
1044
|
+
while (this.handshakeRefreshQueued) {
|
|
1045
|
+
this.handshakeRefreshQueued = false;
|
|
1046
|
+
const relay = this.relay;
|
|
1047
|
+
if (!this.trackedTab || !relay || !relay.isConnected()) {
|
|
1048
|
+
return;
|
|
1049
|
+
}
|
|
1050
|
+
try {
|
|
1051
|
+
await relay.sendHandshake(this.buildHandshake());
|
|
1052
|
+
const handshakeHealthy = await this.verifyHandshakeHealth(relay, "refresh");
|
|
1053
|
+
if (!handshakeHealthy) {
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
catch (error) {
|
|
1058
|
+
logError("relay.refresh_handshake", error, { code: "relay_handshake_refresh_failed" });
|
|
1059
|
+
if (this.relay === relay) {
|
|
1060
|
+
this.relayNotice = "Failed to re-establish a clean daemon-extension handshake. Open the extension popup, click Connect again, confirm `status --daemon` shows ext=on and handshake=on, then retry.";
|
|
1061
|
+
if (this.shouldReconnect && !this.disconnecting) {
|
|
1062
|
+
relay.disconnect();
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
return;
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
})();
|
|
1069
|
+
const refreshPromise = run.finally(() => {
|
|
1070
|
+
if (this.handshakeRefreshPromise === refreshPromise) {
|
|
1071
|
+
this.handshakeRefreshPromise = null;
|
|
1072
|
+
}
|
|
1073
|
+
});
|
|
1074
|
+
this.handshakeRefreshPromise = refreshPromise;
|
|
726
1075
|
}
|
|
727
1076
|
}
|
|
1077
|
+
const isAnnotationResponse = (value) => {
|
|
1078
|
+
if (!value || typeof value !== "object") {
|
|
1079
|
+
return false;
|
|
1080
|
+
}
|
|
1081
|
+
const record = value;
|
|
1082
|
+
return record.version === 1
|
|
1083
|
+
&& typeof record.requestId === "string"
|
|
1084
|
+
&& (record.status === "ok" || record.status === "cancelled" || record.status === "error");
|
|
1085
|
+
};
|