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
|
@@ -5,16 +5,20 @@ import { logError } from "./logging.js";
|
|
|
5
5
|
import { OpsRuntime } from "./ops/ops-runtime.js";
|
|
6
6
|
import { CanvasRuntime } from "./canvas/canvas-runtime.js";
|
|
7
7
|
import { formatDispatchSourceLabel, stripAnnotationPayloadScreenshots } from "./annotation-payload.js";
|
|
8
|
+
import { getRestrictionMessage } from "./services/url-restrictions.js";
|
|
8
9
|
const connection = new ConnectionManager();
|
|
9
|
-
|
|
10
|
-
send: (message) => connection.sendCanvasMessage(message)
|
|
11
|
-
});
|
|
10
|
+
let canvasRuntime;
|
|
12
11
|
const opsRuntime = new OpsRuntime({
|
|
13
12
|
send: (message) => connection.sendOpsMessage(message),
|
|
14
13
|
cdp: connection.getCdpRouter(),
|
|
15
14
|
getCanvasPageState: (targetId) => canvasRuntime.getPageStateByTargetId(targetId),
|
|
16
15
|
performCanvasPageAction: (targetId, action, selector) => canvasRuntime.performPageAction(targetId, action, selector)
|
|
17
16
|
});
|
|
17
|
+
canvasRuntime = new CanvasRuntime({
|
|
18
|
+
send: (message) => connection.sendCanvasMessage(message),
|
|
19
|
+
registerOpsCanvasTarget: (browserSessionId, targetId) => opsRuntime.registerCanvasTargetForSession(browserSessionId, targetId),
|
|
20
|
+
unregisterOpsCanvasTarget: (browserSessionId, targetId) => opsRuntime.unregisterCanvasTargetForSession(browserSessionId, targetId)
|
|
21
|
+
});
|
|
18
22
|
const nativePort = new NativePortManager({
|
|
19
23
|
onMessage: (payload) => {
|
|
20
24
|
handleNativePortMessage(payload).catch((error) => {
|
|
@@ -29,6 +33,7 @@ let autoConnectInFlight = false;
|
|
|
29
33
|
let statusNoteOverride = null;
|
|
30
34
|
let retryScheduled = false;
|
|
31
35
|
let retryDelayMs = 5000;
|
|
36
|
+
let autoConnectEnabled = DEFAULT_AUTO_CONNECT;
|
|
32
37
|
let nativeEnabled = DEFAULT_NATIVE_ENABLED;
|
|
33
38
|
const RETRY_ALARM_NAME = "opendevbrowser-auto-connect";
|
|
34
39
|
const RETRY_MAX_MS = 60_000;
|
|
@@ -36,15 +41,20 @@ const ANNOTATION_CONTENT_SCRIPT = "dist/annotate-content.js";
|
|
|
36
41
|
const ANNOTATION_CONTENT_STYLE = "dist/annotate-content.css";
|
|
37
42
|
const ANNOTATION_MAX_PAYLOAD_BYTES = 10 * 1024 * 1024;
|
|
38
43
|
const ANNOTATION_REQUEST_TIMEOUT_MS = 120_000;
|
|
44
|
+
const ANNOTATION_RECEIVER_UNAVAILABLE_MESSAGE = "Annotation UI did not load in the page. Reload the tab and retry.";
|
|
39
45
|
const LAST_ANNOTATION_META_KEY = "annotationLastMeta";
|
|
40
46
|
const LAST_ANNOTATION_PAYLOAD_KEY = "annotationLastPayloadSansScreenshots";
|
|
41
47
|
const LAST_AGENT_ANNOTATION_META_KEY = "annotationAgentMeta";
|
|
42
48
|
const LAST_AGENT_ANNOTATION_PAYLOAD_KEY = "annotationAgentPayloadSansScreenshots";
|
|
49
|
+
const LAST_ANNOTATABLE_TAB_ID_KEY = "annotationLastTabId";
|
|
50
|
+
const POPUP_ANNOTATION_TARGET_TTL_MS = 10_000;
|
|
43
51
|
const BADGE_CONNECTED_DOT_COLOR = "#16a34a";
|
|
44
52
|
const BADGE_DISCONNECTED_DOT_COLOR = "#dc2626";
|
|
45
53
|
const annotationSessions = new Map();
|
|
46
54
|
let lastAnnotationFull = null;
|
|
47
55
|
let lastAgentAnnotationFull = null;
|
|
56
|
+
let lastAnnotatableTabId = null;
|
|
57
|
+
let lastPopupAnnotationTarget = null;
|
|
48
58
|
connection.onAnnotationCommand((command) => {
|
|
49
59
|
handleRelayAnnotationCommand(command).catch((error) => {
|
|
50
60
|
logError("annotation.relay_command", error, { code: "annotation_command_failed" });
|
|
@@ -56,16 +66,6 @@ connection.onOpsMessage((message) => {
|
|
|
56
66
|
connection.onCanvasMessage((message) => {
|
|
57
67
|
canvasRuntime.handleMessage(message);
|
|
58
68
|
});
|
|
59
|
-
const RESTRICTED_PROTOCOLS = new Set([
|
|
60
|
-
"chrome:",
|
|
61
|
-
"chrome-extension:",
|
|
62
|
-
"chrome-search:",
|
|
63
|
-
"chrome-untrusted:",
|
|
64
|
-
"devtools:",
|
|
65
|
-
"chrome-devtools:",
|
|
66
|
-
"edge:",
|
|
67
|
-
"brave:"
|
|
68
|
-
]);
|
|
69
69
|
const updateBadge = (status) => {
|
|
70
70
|
const isConnected = status === "connected";
|
|
71
71
|
const dotColor = isConnected ? BADGE_CONNECTED_DOT_COLOR : BADGE_DISCONNECTED_DOT_COLOR;
|
|
@@ -152,6 +152,16 @@ const setStorage = (items) => {
|
|
|
152
152
|
const setStatusNoteOverride = (note) => {
|
|
153
153
|
statusNoteOverride = note;
|
|
154
154
|
};
|
|
155
|
+
const loadStoredAnnotatableTabId = async () => {
|
|
156
|
+
const data = await new Promise((resolve) => {
|
|
157
|
+
chrome.storage.local.get([LAST_ANNOTATABLE_TAB_ID_KEY], (items) => resolve(items));
|
|
158
|
+
});
|
|
159
|
+
const value = data[LAST_ANNOTATABLE_TAB_ID_KEY];
|
|
160
|
+
return typeof value === "number" && Number.isInteger(value) ? value : null;
|
|
161
|
+
};
|
|
162
|
+
const persistAnnotatableTabId = async (tabId) => {
|
|
163
|
+
await setStorage({ [LAST_ANNOTATABLE_TAB_ID_KEY]: tabId });
|
|
164
|
+
};
|
|
155
165
|
const buildRelayHealthNote = (health) => {
|
|
156
166
|
if (!health) {
|
|
157
167
|
return "Relay unreachable. Start the daemon and retry.";
|
|
@@ -162,7 +172,7 @@ const buildRelayHealthNote = (health) => {
|
|
|
162
172
|
case "pairing_required":
|
|
163
173
|
return "Pairing required. Enable auto-pair or set the token.";
|
|
164
174
|
case "handshake_incomplete":
|
|
165
|
-
return "Extension handshake
|
|
175
|
+
return "Extension websocket is up but the daemon-extension handshake is incomplete. Open the popup and click Connect again to re-establish a clean handshake, then confirm `status --daemon` shows ext=on and handshake=on.";
|
|
166
176
|
case "extension_disconnected":
|
|
167
177
|
return "Extension not connected to relay. Click Connect.";
|
|
168
178
|
case "annotation_disconnected":
|
|
@@ -258,23 +268,11 @@ const parseEpoch = (value) => {
|
|
|
258
268
|
}
|
|
259
269
|
return null;
|
|
260
270
|
};
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
return true;
|
|
267
|
-
}
|
|
268
|
-
return false;
|
|
269
|
-
};
|
|
270
|
-
const getRestrictionMessage = (url) => {
|
|
271
|
-
if (RESTRICTED_PROTOCOLS.has(url.protocol)) {
|
|
272
|
-
return "Active tab uses a restricted URL scheme. Open a normal http(s) page and retry.";
|
|
273
|
-
}
|
|
274
|
-
if (isWebStoreUrl(url)) {
|
|
275
|
-
return "Chrome Web Store tabs cannot be annotated. Open a normal tab and retry.";
|
|
276
|
-
}
|
|
277
|
-
return null;
|
|
271
|
+
const getAnnotationRestrictionMessage = (url) => {
|
|
272
|
+
return getRestrictionMessage(url, {
|
|
273
|
+
restrictedSchemeMessage: "Active tab uses a restricted URL scheme. Open a normal http(s) page and retry.",
|
|
274
|
+
webStoreMessage: "Chrome Web Store tabs cannot be annotated. Open a normal tab and retry."
|
|
275
|
+
});
|
|
278
276
|
};
|
|
279
277
|
const fetchRelayConfig = async (port) => {
|
|
280
278
|
try {
|
|
@@ -449,10 +447,166 @@ const waitForTabComplete = async (tabId, timeoutMs = 10000) => {
|
|
|
449
447
|
chrome.tabs.onUpdated.addListener(listener);
|
|
450
448
|
});
|
|
451
449
|
};
|
|
450
|
+
const waitForAnnotationTabReady = async (tabId) => {
|
|
451
|
+
const tab = await getTab(tabId);
|
|
452
|
+
if (!tab || tab.status === "complete") {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
try {
|
|
456
|
+
await waitForTabComplete(tabId);
|
|
457
|
+
}
|
|
458
|
+
catch (error) {
|
|
459
|
+
if (error instanceof Error && error.message === "Tab load timeout") {
|
|
460
|
+
throw new Error("Active tab is still loading. Wait for it to finish and retry.");
|
|
461
|
+
}
|
|
462
|
+
throw error;
|
|
463
|
+
}
|
|
464
|
+
};
|
|
452
465
|
const getActiveTab = async () => {
|
|
453
466
|
const tabs = await chrome.tabs.query({ active: true, lastFocusedWindow: true });
|
|
454
467
|
return tabs[0] ?? null;
|
|
455
468
|
};
|
|
469
|
+
const getTabRecency = (tab) => {
|
|
470
|
+
return typeof tab.lastAccessed === "number" ? tab.lastAccessed : -1;
|
|
471
|
+
};
|
|
472
|
+
const rememberAnnotatableTab = (tab) => {
|
|
473
|
+
if (!tab || typeof tab.id !== "number") {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
if (isRestrictedTab(tab) !== null) {
|
|
477
|
+
if (lastAnnotatableTabId === tab.id) {
|
|
478
|
+
lastAnnotatableTabId = null;
|
|
479
|
+
void persistAnnotatableTabId(null).catch((error) => {
|
|
480
|
+
logError("annotation.persist_tab", error, { code: "annotation_tab_persist_failed", extra: { tabId: null } });
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
lastAnnotatableTabId = tab.id;
|
|
486
|
+
void persistAnnotatableTabId(tab.id).catch((error) => {
|
|
487
|
+
logError("annotation.persist_tab", error, { code: "annotation_tab_persist_failed", extra: { tabId: tab.id } });
|
|
488
|
+
});
|
|
489
|
+
};
|
|
490
|
+
const getRememberedAnnotatableTab = async (excludeTabId) => {
|
|
491
|
+
if (typeof lastAnnotatableTabId !== "number") {
|
|
492
|
+
lastAnnotatableTabId = await loadStoredAnnotatableTabId();
|
|
493
|
+
}
|
|
494
|
+
if (typeof lastAnnotatableTabId !== "number") {
|
|
495
|
+
return null;
|
|
496
|
+
}
|
|
497
|
+
if (typeof excludeTabId === "number" && lastAnnotatableTabId === excludeTabId) {
|
|
498
|
+
return null;
|
|
499
|
+
}
|
|
500
|
+
const tabId = lastAnnotatableTabId;
|
|
501
|
+
const tab = await getTab(tabId);
|
|
502
|
+
if (!tab || isRestrictedTab(tab) !== null) {
|
|
503
|
+
if (lastAnnotatableTabId === tabId) {
|
|
504
|
+
lastAnnotatableTabId = null;
|
|
505
|
+
void persistAnnotatableTabId(null).catch((error) => {
|
|
506
|
+
logError("annotation.persist_tab", error, { code: "annotation_tab_persist_failed", extra: { tabId: null } });
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
return null;
|
|
510
|
+
}
|
|
511
|
+
return tab;
|
|
512
|
+
};
|
|
513
|
+
const clearPopupAnnotationTarget = (tabId) => {
|
|
514
|
+
if (!lastPopupAnnotationTarget) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
if (typeof tabId === "number" && lastPopupAnnotationTarget.tabId !== tabId) {
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
lastPopupAnnotationTarget = null;
|
|
521
|
+
};
|
|
522
|
+
const rememberPopupAnnotationTarget = (tabId, bootId) => {
|
|
523
|
+
const previousBootId = lastPopupAnnotationTarget?.tabId === tabId
|
|
524
|
+
? lastPopupAnnotationTarget.bootId
|
|
525
|
+
: null;
|
|
526
|
+
lastPopupAnnotationTarget = {
|
|
527
|
+
tabId,
|
|
528
|
+
bootId: typeof bootId === "string" ? bootId : previousBootId,
|
|
529
|
+
resolvedAt: Date.now()
|
|
530
|
+
};
|
|
531
|
+
};
|
|
532
|
+
const getCachedPopupAnnotationTab = async () => {
|
|
533
|
+
const cached = lastPopupAnnotationTarget;
|
|
534
|
+
if (!cached) {
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
if (Date.now() - cached.resolvedAt > POPUP_ANNOTATION_TARGET_TTL_MS) {
|
|
538
|
+
clearPopupAnnotationTarget(cached.tabId);
|
|
539
|
+
return null;
|
|
540
|
+
}
|
|
541
|
+
const tab = await getTab(cached.tabId);
|
|
542
|
+
if (!tab || isRestrictedTab(tab) !== null) {
|
|
543
|
+
clearPopupAnnotationTarget(cached.tabId);
|
|
544
|
+
return null;
|
|
545
|
+
}
|
|
546
|
+
return tab;
|
|
547
|
+
};
|
|
548
|
+
const getPopupAnnotationTab = async (tabIdHint) => {
|
|
549
|
+
const cached = await getCachedPopupAnnotationTab();
|
|
550
|
+
if (cached) {
|
|
551
|
+
rememberAnnotatableTab(cached);
|
|
552
|
+
return cached;
|
|
553
|
+
}
|
|
554
|
+
if (typeof tabIdHint === "number") {
|
|
555
|
+
const hinted = await getTab(tabIdHint);
|
|
556
|
+
if (hinted && isRestrictedTab(hinted) === null) {
|
|
557
|
+
rememberAnnotatableTab(hinted);
|
|
558
|
+
if (typeof hinted.id === "number") {
|
|
559
|
+
rememberPopupAnnotationTarget(hinted.id);
|
|
560
|
+
}
|
|
561
|
+
return hinted;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
const preferred = await getPreferredAnnotationTab();
|
|
565
|
+
if (preferred && typeof preferred.id === "number") {
|
|
566
|
+
rememberPopupAnnotationTarget(preferred.id);
|
|
567
|
+
}
|
|
568
|
+
return preferred;
|
|
569
|
+
};
|
|
570
|
+
const getMostRecentAnnotatableTab = async (excludeTabId) => {
|
|
571
|
+
const tabs = await chrome.tabs.query({});
|
|
572
|
+
const candidates = tabs
|
|
573
|
+
.filter((tab) => {
|
|
574
|
+
if (typeof tab.id !== "number") {
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
if (typeof excludeTabId === "number" && tab.id === excludeTabId) {
|
|
578
|
+
return false;
|
|
579
|
+
}
|
|
580
|
+
return isRestrictedTab(tab) === null;
|
|
581
|
+
})
|
|
582
|
+
.sort((left, right) => {
|
|
583
|
+
const recencyDelta = getTabRecency(right) - getTabRecency(left);
|
|
584
|
+
if (recencyDelta !== 0) {
|
|
585
|
+
return recencyDelta;
|
|
586
|
+
}
|
|
587
|
+
const activeDelta = Number(Boolean(right.active)) - Number(Boolean(left.active));
|
|
588
|
+
if (activeDelta !== 0) {
|
|
589
|
+
return activeDelta;
|
|
590
|
+
}
|
|
591
|
+
return (right.id ?? 0) - (left.id ?? 0);
|
|
592
|
+
});
|
|
593
|
+
return candidates[0] ?? null;
|
|
594
|
+
};
|
|
595
|
+
const getPreferredAnnotationTab = async () => {
|
|
596
|
+
const active = await getActiveTab();
|
|
597
|
+
if (active && isRestrictedTab(active) === null) {
|
|
598
|
+
rememberAnnotatableTab(active);
|
|
599
|
+
return active;
|
|
600
|
+
}
|
|
601
|
+
const excludeTabId = active && typeof active.id === "number" ? active.id : undefined;
|
|
602
|
+
const remembered = await getRememberedAnnotatableTab(excludeTabId);
|
|
603
|
+
if (remembered) {
|
|
604
|
+
return remembered;
|
|
605
|
+
}
|
|
606
|
+
const fallback = await getMostRecentAnnotatableTab(excludeTabId);
|
|
607
|
+
rememberAnnotatableTab(fallback);
|
|
608
|
+
return fallback ?? active;
|
|
609
|
+
};
|
|
456
610
|
const resolveAnnotationTab = async (command) => {
|
|
457
611
|
if (typeof command.tabId === "number") {
|
|
458
612
|
if (command.url) {
|
|
@@ -473,7 +627,7 @@ const resolveAnnotationTab = async (command) => {
|
|
|
473
627
|
}
|
|
474
628
|
return created;
|
|
475
629
|
}
|
|
476
|
-
const active = await
|
|
630
|
+
const active = await getPreferredAnnotationTab();
|
|
477
631
|
if (!active) {
|
|
478
632
|
throw new Error("No active tab available");
|
|
479
633
|
}
|
|
@@ -491,7 +645,7 @@ const isRestrictedTab = (tab) => {
|
|
|
491
645
|
logError("annotation.parse_tab_url", error, { code: "tab_url_parse_failed" });
|
|
492
646
|
return "Active tab URL is invalid.";
|
|
493
647
|
}
|
|
494
|
-
return
|
|
648
|
+
return getAnnotationRestrictionMessage(parsed);
|
|
495
649
|
};
|
|
496
650
|
const injectAnnotationAssets = async (tabId) => {
|
|
497
651
|
await new Promise((resolve, reject) => {
|
|
@@ -533,20 +687,56 @@ const isMissingAnnotationReceiverError = (error) => {
|
|
|
533
687
|
}
|
|
534
688
|
return error.message.includes("Receiving end does not exist");
|
|
535
689
|
};
|
|
690
|
+
const readAnnotationBridgeStatus = (response) => {
|
|
691
|
+
if (typeof response !== "object" || response === null) {
|
|
692
|
+
return null;
|
|
693
|
+
}
|
|
694
|
+
const candidate = response;
|
|
695
|
+
if (candidate.ok !== true || typeof candidate.bootId !== "string" || typeof candidate.active !== "boolean") {
|
|
696
|
+
return null;
|
|
697
|
+
}
|
|
698
|
+
return {
|
|
699
|
+
ok: true,
|
|
700
|
+
bootId: candidate.bootId,
|
|
701
|
+
active: candidate.active
|
|
702
|
+
};
|
|
703
|
+
};
|
|
704
|
+
const sendAnnotationMessageToTab = async (tabId, message) => {
|
|
705
|
+
try {
|
|
706
|
+
return await sendMessageToTab(tabId, message);
|
|
707
|
+
}
|
|
708
|
+
catch (error) {
|
|
709
|
+
if (!isMissingAnnotationReceiverError(error)) {
|
|
710
|
+
throw error;
|
|
711
|
+
}
|
|
712
|
+
await ensureAnnotationInjected(tabId);
|
|
713
|
+
try {
|
|
714
|
+
return await sendMessageToTab(tabId, message);
|
|
715
|
+
}
|
|
716
|
+
catch (retryError) {
|
|
717
|
+
if (isMissingAnnotationReceiverError(retryError)) {
|
|
718
|
+
throw new Error(ANNOTATION_RECEIVER_UNAVAILABLE_MESSAGE);
|
|
719
|
+
}
|
|
720
|
+
throw retryError;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
};
|
|
536
724
|
const sleep = async (ms) => {
|
|
537
725
|
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
538
726
|
};
|
|
539
727
|
const pingAnnotation = async (tabId) => {
|
|
540
728
|
const response = await sendMessageToTab(tabId, { type: "annotation:ping" });
|
|
541
|
-
const
|
|
542
|
-
if (!
|
|
729
|
+
const ready = readAnnotationBridgeStatus(response);
|
|
730
|
+
if (!ready) {
|
|
543
731
|
throw new Error("Annotation ping failed");
|
|
544
732
|
}
|
|
733
|
+
rememberPopupAnnotationTarget(tabId, ready.bootId);
|
|
734
|
+
return ready;
|
|
545
735
|
};
|
|
546
736
|
const ensureAnnotationInjected = async (tabId) => {
|
|
737
|
+
await waitForAnnotationTabReady(tabId);
|
|
547
738
|
try {
|
|
548
|
-
await pingAnnotation(tabId);
|
|
549
|
-
return;
|
|
739
|
+
return await pingAnnotation(tabId);
|
|
550
740
|
}
|
|
551
741
|
catch (error) {
|
|
552
742
|
// Initial ping can fail before content script injection; avoid noisy logs for missing receivers.
|
|
@@ -558,9 +748,9 @@ const ensureAnnotationInjected = async (tabId) => {
|
|
|
558
748
|
let lastError = null;
|
|
559
749
|
for (let attempt = 0; attempt <= backoff.length; attempt += 1) {
|
|
560
750
|
try {
|
|
751
|
+
await waitForAnnotationTabReady(tabId);
|
|
561
752
|
await injectAnnotationAssets(tabId);
|
|
562
|
-
await pingAnnotation(tabId);
|
|
563
|
-
return;
|
|
753
|
+
return await pingAnnotation(tabId);
|
|
564
754
|
}
|
|
565
755
|
catch (error) {
|
|
566
756
|
lastError = error;
|
|
@@ -571,13 +761,55 @@ const ensureAnnotationInjected = async (tabId) => {
|
|
|
571
761
|
}
|
|
572
762
|
}
|
|
573
763
|
}
|
|
764
|
+
if (isMissingAnnotationReceiverError(lastError)) {
|
|
765
|
+
throw new Error(ANNOTATION_RECEIVER_UNAVAILABLE_MESSAGE);
|
|
766
|
+
}
|
|
574
767
|
if (lastError instanceof Error) {
|
|
575
768
|
throw lastError;
|
|
576
769
|
}
|
|
577
770
|
throw new Error("Annotation injection failed");
|
|
578
771
|
};
|
|
579
|
-
const
|
|
580
|
-
|
|
772
|
+
const refreshAnnotationInjected = async (tabId) => {
|
|
773
|
+
await waitForAnnotationTabReady(tabId);
|
|
774
|
+
await injectAnnotationAssets(tabId);
|
|
775
|
+
return await pingAnnotation(tabId);
|
|
776
|
+
};
|
|
777
|
+
const startAnnotationUi = async (tabId, requestId, options, url) => {
|
|
778
|
+
let lastError = null;
|
|
779
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
780
|
+
try {
|
|
781
|
+
const response = await sendAnnotationMessageToTab(tabId, {
|
|
782
|
+
type: "annotation:start",
|
|
783
|
+
requestId,
|
|
784
|
+
options: options ?? {},
|
|
785
|
+
url
|
|
786
|
+
});
|
|
787
|
+
const ready = readAnnotationBridgeStatus(response);
|
|
788
|
+
if (ready?.active) {
|
|
789
|
+
rememberPopupAnnotationTarget(tabId, ready.bootId);
|
|
790
|
+
return ready;
|
|
791
|
+
}
|
|
792
|
+
throw new Error("Annotation start acknowledgement missing active bridge.");
|
|
793
|
+
}
|
|
794
|
+
catch (error) {
|
|
795
|
+
lastError = error;
|
|
796
|
+
if (attempt === 0) {
|
|
797
|
+
await refreshAnnotationInjected(tabId);
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
if (isMissingAnnotationReceiverError(lastError)
|
|
803
|
+
|| (lastError instanceof Error && lastError.message.includes("active bridge"))) {
|
|
804
|
+
throw new Error(ANNOTATION_RECEIVER_UNAVAILABLE_MESSAGE);
|
|
805
|
+
}
|
|
806
|
+
if (lastError instanceof Error) {
|
|
807
|
+
throw lastError;
|
|
808
|
+
}
|
|
809
|
+
throw new Error("Annotation start failed");
|
|
810
|
+
};
|
|
811
|
+
const probeAnnotationInjected = async (tabIdHint) => {
|
|
812
|
+
const active = await getPopupAnnotationTab(tabIdHint);
|
|
581
813
|
if (!active || typeof active.id !== "number") {
|
|
582
814
|
return { injected: false, detail: "No active tab available." };
|
|
583
815
|
}
|
|
@@ -585,8 +817,12 @@ const probeAnnotationInjected = async () => {
|
|
|
585
817
|
if (restricted) {
|
|
586
818
|
return { injected: false, detail: restricted };
|
|
587
819
|
}
|
|
820
|
+
if (active.status && active.status !== "complete") {
|
|
821
|
+
return { injected: false, detail: "Active tab is still loading." };
|
|
822
|
+
}
|
|
588
823
|
try {
|
|
589
|
-
await pingAnnotation(active.id);
|
|
824
|
+
const ready = await pingAnnotation(active.id);
|
|
825
|
+
rememberPopupAnnotationTarget(active.id, ready.bootId);
|
|
590
826
|
return { injected: true };
|
|
591
827
|
}
|
|
592
828
|
catch (error) {
|
|
@@ -595,7 +831,7 @@ const probeAnnotationInjected = async () => {
|
|
|
595
831
|
}
|
|
596
832
|
};
|
|
597
833
|
const toggleAnnotationUi = async () => {
|
|
598
|
-
const tab = await
|
|
834
|
+
const tab = await getPreferredAnnotationTab();
|
|
599
835
|
if (!tab || typeof tab.id !== "number") {
|
|
600
836
|
return;
|
|
601
837
|
}
|
|
@@ -604,7 +840,7 @@ const toggleAnnotationUi = async () => {
|
|
|
604
840
|
return;
|
|
605
841
|
}
|
|
606
842
|
await ensureAnnotationInjected(tab.id);
|
|
607
|
-
await
|
|
843
|
+
await sendAnnotationMessageToTab(tab.id, { type: "annotation:toggle" });
|
|
608
844
|
};
|
|
609
845
|
const startAnnotationSession = async (command, transport) => {
|
|
610
846
|
const requestId = command.requestId;
|
|
@@ -637,9 +873,11 @@ const startAnnotationSession = async (command, transport) => {
|
|
|
637
873
|
}, transport);
|
|
638
874
|
return;
|
|
639
875
|
}
|
|
876
|
+
rememberAnnotatableTab(tab);
|
|
640
877
|
let timeoutId = null;
|
|
641
878
|
try {
|
|
642
|
-
await ensureAnnotationInjected(tab.id);
|
|
879
|
+
const initialBridge = await ensureAnnotationInjected(tab.id);
|
|
880
|
+
rememberPopupAnnotationTarget(tab.id, initialBridge.bootId);
|
|
643
881
|
timeoutId = startAnnotationTimeout(requestId, transport);
|
|
644
882
|
annotationSessions.set(requestId, {
|
|
645
883
|
requestId,
|
|
@@ -649,18 +887,15 @@ const startAnnotationSession = async (command, transport) => {
|
|
|
649
887
|
timeoutId,
|
|
650
888
|
transport
|
|
651
889
|
});
|
|
652
|
-
await
|
|
653
|
-
|
|
654
|
-
requestId,
|
|
655
|
-
options: command.options ?? {},
|
|
656
|
-
url: command.url
|
|
657
|
-
});
|
|
890
|
+
const startedBridge = await startAnnotationUi(tab.id, requestId, command.options, command.url);
|
|
891
|
+
rememberPopupAnnotationTarget(tab.id, startedBridge.bootId);
|
|
658
892
|
}
|
|
659
893
|
catch (error) {
|
|
660
894
|
if (timeoutId !== null) {
|
|
661
895
|
clearTimeout(timeoutId);
|
|
662
896
|
}
|
|
663
897
|
annotationSessions.delete(requestId);
|
|
898
|
+
clearPopupAnnotationTarget(tab.id);
|
|
664
899
|
throw error instanceof Error ? error : new Error("Annotation injection failed");
|
|
665
900
|
}
|
|
666
901
|
};
|
|
@@ -677,7 +912,7 @@ const cancelAnnotationSession = async (requestId, transport) => {
|
|
|
677
912
|
}
|
|
678
913
|
clearTimeout(session.timeoutId);
|
|
679
914
|
annotationSessions.delete(requestId);
|
|
680
|
-
await
|
|
915
|
+
await sendAnnotationMessageToTab(session.tabId, { type: "annotation:cancel", requestId });
|
|
681
916
|
sendAnnotationResponse({
|
|
682
917
|
version: 1,
|
|
683
918
|
requestId,
|
|
@@ -700,6 +935,7 @@ const buildLastAnnotationMeta = (requestId, response, hasFullPayloadInMemory, ex
|
|
|
700
935
|
requestId,
|
|
701
936
|
status: response.status,
|
|
702
937
|
error: response.error,
|
|
938
|
+
receipt: extras.receipt ?? response.receipt,
|
|
703
939
|
source: extras.source,
|
|
704
940
|
label: extras.label,
|
|
705
941
|
url: payload?.url,
|
|
@@ -755,24 +991,55 @@ const isAnnotationPayload = (value) => {
|
|
|
755
991
|
&& typeof payload.screenshotMode === "string"
|
|
756
992
|
&& Array.isArray(payload.annotations);
|
|
757
993
|
};
|
|
758
|
-
const storeAgentAnnotationPayload = async (payload, source, label) => {
|
|
994
|
+
const storeAgentAnnotationPayload = async (payload, source, label, receipt) => {
|
|
759
995
|
if (!validatePayloadSize(payload)) {
|
|
760
996
|
throw new Error("Annotation payload exceeded size limits.");
|
|
761
997
|
}
|
|
762
998
|
const response = {
|
|
763
999
|
version: 1,
|
|
764
|
-
requestId: crypto.randomUUID(),
|
|
1000
|
+
requestId: receipt?.receiptId ?? crypto.randomUUID(),
|
|
765
1001
|
status: "ok",
|
|
766
|
-
payload
|
|
1002
|
+
payload,
|
|
1003
|
+
receipt
|
|
767
1004
|
};
|
|
768
1005
|
const meta = buildLastAnnotationMeta(response.requestId, response, true, {
|
|
769
1006
|
source,
|
|
770
|
-
label: label?.trim().length ? label.trim() : formatDispatchSourceLabel(source)
|
|
1007
|
+
label: label?.trim().length ? label.trim() : formatDispatchSourceLabel(source),
|
|
1008
|
+
receipt
|
|
771
1009
|
});
|
|
772
1010
|
lastAgentAnnotationFull = { meta, payload };
|
|
773
|
-
await persistAgentAnnotation(meta, stripAnnotationPayloadScreenshots(payload));
|
|
1011
|
+
await persistAgentAnnotation({ ...meta, hasFullPayloadInMemory: false }, stripAnnotationPayloadScreenshots(payload));
|
|
774
1012
|
return meta;
|
|
775
1013
|
};
|
|
1014
|
+
const buildStoredOnlyReceipt = (payload, source, label, reason) => {
|
|
1015
|
+
const sanitizedPayload = stripAnnotationPayloadScreenshots(payload);
|
|
1016
|
+
return {
|
|
1017
|
+
receiptId: crypto.randomUUID(),
|
|
1018
|
+
deliveryState: "stored_only",
|
|
1019
|
+
storedFallback: true,
|
|
1020
|
+
reason,
|
|
1021
|
+
chatScopeKey: null,
|
|
1022
|
+
createdAt: new Date().toISOString(),
|
|
1023
|
+
itemCount: sanitizedPayload.annotations.length,
|
|
1024
|
+
byteLength: new TextEncoder().encode(JSON.stringify(sanitizedPayload)).length,
|
|
1025
|
+
source,
|
|
1026
|
+
label: label?.trim().length ? label.trim() : formatDispatchSourceLabel(source)
|
|
1027
|
+
};
|
|
1028
|
+
};
|
|
1029
|
+
const enqueueAgentPayload = async (payload, source, label) => {
|
|
1030
|
+
const response = await connection.sendAnnotationCommand({
|
|
1031
|
+
version: 1,
|
|
1032
|
+
requestId: crypto.randomUUID(),
|
|
1033
|
+
command: "store_agent_payload",
|
|
1034
|
+
payload,
|
|
1035
|
+
source,
|
|
1036
|
+
label
|
|
1037
|
+
});
|
|
1038
|
+
if (response.status !== "ok" || !response.receipt) {
|
|
1039
|
+
throw new Error(response.error?.code ?? response.error?.message ?? "relay_unavailable");
|
|
1040
|
+
}
|
|
1041
|
+
return response.receipt;
|
|
1042
|
+
};
|
|
776
1043
|
const loadAgentAnnotationPayload = async (includeScreenshots) => {
|
|
777
1044
|
if (includeScreenshots && lastAgentAnnotationFull) {
|
|
778
1045
|
return {
|
|
@@ -1003,6 +1270,7 @@ const attemptAutoConnect = async () => {
|
|
|
1003
1270
|
});
|
|
1004
1271
|
});
|
|
1005
1272
|
const autoConnect = typeof data.autoConnect === "boolean" ? data.autoConnect : DEFAULT_AUTO_CONNECT;
|
|
1273
|
+
autoConnectEnabled = autoConnect;
|
|
1006
1274
|
if (!autoConnect || connection.getStatus() === "connected") {
|
|
1007
1275
|
clearRetry();
|
|
1008
1276
|
return;
|
|
@@ -1068,6 +1336,7 @@ const attemptAutoConnect = async () => {
|
|
|
1068
1336
|
if (config.instanceId && fetched.instanceId && config.instanceId !== fetched.instanceId) {
|
|
1069
1337
|
console.warn("[opendevbrowser] Relay instance mismatch during auto-pair. Retrying later.");
|
|
1070
1338
|
setStatusNoteOverride("Relay instance mismatch. Open the popup and click Connect.");
|
|
1339
|
+
scheduleRetry();
|
|
1071
1340
|
return;
|
|
1072
1341
|
}
|
|
1073
1342
|
const tokenEpoch = fetched.epoch ?? configEpoch;
|
|
@@ -1123,6 +1392,9 @@ connection.onStatus((status) => {
|
|
|
1123
1392
|
clearTimeout(session.timeoutId);
|
|
1124
1393
|
}
|
|
1125
1394
|
annotationSessions.clear();
|
|
1395
|
+
if (autoConnectEnabled) {
|
|
1396
|
+
scheduleRetry();
|
|
1397
|
+
}
|
|
1126
1398
|
}
|
|
1127
1399
|
});
|
|
1128
1400
|
updateBadge(getEffectiveStatus());
|
|
@@ -1158,6 +1430,37 @@ if (chrome.commands?.onCommand) {
|
|
|
1158
1430
|
autoConnect().catch((error) => {
|
|
1159
1431
|
logError("auto_connect.startup", error, { code: "auto_connect_failed" });
|
|
1160
1432
|
});
|
|
1433
|
+
void getActiveTab()
|
|
1434
|
+
.then((tab) => {
|
|
1435
|
+
rememberAnnotatableTab(tab);
|
|
1436
|
+
})
|
|
1437
|
+
.catch((error) => {
|
|
1438
|
+
logError("annotation.initial_tab", error, { code: "annotation_tab_resolution_failed" });
|
|
1439
|
+
});
|
|
1440
|
+
chrome.tabs.onActivated.addListener((activeInfo) => {
|
|
1441
|
+
void getTab(activeInfo.tabId)
|
|
1442
|
+
.then((tab) => {
|
|
1443
|
+
rememberAnnotatableTab(tab);
|
|
1444
|
+
})
|
|
1445
|
+
.catch((error) => {
|
|
1446
|
+
logError("annotation.tab_activated", error, { code: "annotation_tab_resolution_failed", extra: { tabId: activeInfo.tabId } });
|
|
1447
|
+
});
|
|
1448
|
+
});
|
|
1449
|
+
chrome.tabs.onUpdated.addListener((tabId, _changeInfo, tab) => {
|
|
1450
|
+
if (!tab.active && tabId !== lastAnnotatableTabId) {
|
|
1451
|
+
return;
|
|
1452
|
+
}
|
|
1453
|
+
rememberAnnotatableTab(tab);
|
|
1454
|
+
});
|
|
1455
|
+
chrome.tabs.onRemoved.addListener((tabId) => {
|
|
1456
|
+
if (lastAnnotatableTabId === tabId) {
|
|
1457
|
+
lastAnnotatableTabId = null;
|
|
1458
|
+
void persistAnnotatableTabId(null).catch((error) => {
|
|
1459
|
+
logError("annotation.persist_tab", error, { code: "annotation_tab_persist_failed", extra: { tabId: null } });
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
clearPopupAnnotationTarget(tabId);
|
|
1463
|
+
});
|
|
1161
1464
|
chrome.storage.onChanged.addListener((changes, area) => {
|
|
1162
1465
|
if (area !== "local") {
|
|
1163
1466
|
return;
|
|
@@ -1169,11 +1472,18 @@ chrome.storage.onChanged.addListener((changes, area) => {
|
|
|
1169
1472
|
}
|
|
1170
1473
|
updateBadge(getEffectiveStatus());
|
|
1171
1474
|
}
|
|
1475
|
+
if (changes.autoConnect) {
|
|
1476
|
+
autoConnectEnabled =
|
|
1477
|
+
typeof changes.autoConnect.newValue === "boolean" ? changes.autoConnect.newValue : DEFAULT_AUTO_CONNECT;
|
|
1478
|
+
}
|
|
1172
1479
|
if (changes.autoConnect?.newValue === true) {
|
|
1173
1480
|
autoConnect().catch((error) => {
|
|
1174
1481
|
logError("auto_connect.setting", error, { code: "auto_connect_failed" });
|
|
1175
1482
|
});
|
|
1176
1483
|
}
|
|
1484
|
+
else if (changes.autoConnect?.newValue === false) {
|
|
1485
|
+
clearRetry();
|
|
1486
|
+
}
|
|
1177
1487
|
if (changes.pairingToken) {
|
|
1178
1488
|
autoConnect().catch((error) => {
|
|
1179
1489
|
logError("auto_connect.pairing_token", error, { code: "auto_connect_failed" });
|
|
@@ -1244,7 +1554,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1244
1554
|
ok: false
|
|
1245
1555
|
};
|
|
1246
1556
|
try {
|
|
1247
|
-
const active = await
|
|
1557
|
+
const active = await getPopupAnnotationTab(message.tabId);
|
|
1248
1558
|
if (!active) {
|
|
1249
1559
|
response.error = { code: "invalid_request", message: "No active tab available." };
|
|
1250
1560
|
sendResponse(response);
|
|
@@ -1304,7 +1614,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1304
1614
|
}
|
|
1305
1615
|
if (message.type === "annotation:probe") {
|
|
1306
1616
|
(async () => {
|
|
1307
|
-
const result = await probeAnnotationInjected();
|
|
1617
|
+
const result = await probeAnnotationInjected(message.tabId);
|
|
1308
1618
|
sendResponse({ type: "annotation:probeResult", ...result });
|
|
1309
1619
|
})().catch((error) => {
|
|
1310
1620
|
logError("annotation.probe", error, { code: "annotation_probe_failed" });
|
|
@@ -1384,16 +1694,50 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1384
1694
|
type: "annotation:sendPayloadResult",
|
|
1385
1695
|
ok: false,
|
|
1386
1696
|
meta: null,
|
|
1697
|
+
receipt: null,
|
|
1387
1698
|
error: { code: "invalid_request", message: "Invalid annotation payload." }
|
|
1388
1699
|
};
|
|
1389
1700
|
sendResponse(response);
|
|
1390
1701
|
return;
|
|
1391
1702
|
}
|
|
1392
|
-
const
|
|
1703
|
+
const source = message.source ?? "popup_all";
|
|
1704
|
+
let receipt;
|
|
1705
|
+
try {
|
|
1706
|
+
receipt = await enqueueAgentPayload(message.payload, source, message.label);
|
|
1707
|
+
}
|
|
1708
|
+
catch (error) {
|
|
1709
|
+
const reason = error instanceof Error && error.message.trim().length > 0
|
|
1710
|
+
? error.message.trim()
|
|
1711
|
+
: "relay_unavailable";
|
|
1712
|
+
receipt = buildStoredOnlyReceipt(message.payload, source, message.label, reason);
|
|
1713
|
+
}
|
|
1714
|
+
let meta;
|
|
1715
|
+
try {
|
|
1716
|
+
meta = await storeAgentAnnotationPayload(message.payload, source, message.label, receipt);
|
|
1717
|
+
}
|
|
1718
|
+
catch (error) {
|
|
1719
|
+
if (receipt.deliveryState !== "delivered") {
|
|
1720
|
+
throw error;
|
|
1721
|
+
}
|
|
1722
|
+
const response = {
|
|
1723
|
+
version: 1,
|
|
1724
|
+
requestId: receipt.receiptId,
|
|
1725
|
+
status: "ok",
|
|
1726
|
+
payload: message.payload,
|
|
1727
|
+
receipt
|
|
1728
|
+
};
|
|
1729
|
+
meta = buildLastAnnotationMeta(receipt.receiptId, response, true, {
|
|
1730
|
+
source,
|
|
1731
|
+
label: message.label?.trim().length ? message.label.trim() : formatDispatchSourceLabel(source),
|
|
1732
|
+
receipt
|
|
1733
|
+
});
|
|
1734
|
+
logError("annotation.store_agent_payload_optional", error, { code: "annotation_persist_failed" });
|
|
1735
|
+
}
|
|
1393
1736
|
const response = {
|
|
1394
1737
|
type: "annotation:sendPayloadResult",
|
|
1395
1738
|
ok: true,
|
|
1396
|
-
meta: { ...meta, hasFullPayloadInMemory: true }
|
|
1739
|
+
meta: { ...meta, hasFullPayloadInMemory: true },
|
|
1740
|
+
receipt
|
|
1397
1741
|
};
|
|
1398
1742
|
sendResponse(response);
|
|
1399
1743
|
})().catch((error) => {
|
|
@@ -1401,6 +1745,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1401
1745
|
type: "annotation:sendPayloadResult",
|
|
1402
1746
|
ok: false,
|
|
1403
1747
|
meta: null,
|
|
1748
|
+
receipt: null,
|
|
1404
1749
|
error: {
|
|
1405
1750
|
code: "payload_too_large",
|
|
1406
1751
|
message: error instanceof Error ? error.message : "Annotation dispatch failed."
|