opendevbrowser 0.0.16 → 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 +201 -79
- 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 +7 -1
- package/dist/browser/annotation-manager.d.ts.map +1 -1
- package/dist/browser/browser-manager.d.ts +153 -48
- package/dist/browser/browser-manager.d.ts.map +1 -1
- package/dist/browser/canvas-client.d.ts +54 -0
- package/dist/browser/canvas-client.d.ts.map +1 -0
- package/dist/browser/canvas-code-sync-manager.d.ts +87 -0
- package/dist/browser/canvas-code-sync-manager.d.ts.map +1 -0
- package/dist/browser/canvas-manager.d.ts +122 -0
- package/dist/browser/canvas-manager.d.ts.map +1 -0
- package/dist/browser/canvas-runtime-preview-bridge.d.ts +20 -0
- package/dist/browser/canvas-runtime-preview-bridge.d.ts.map +1 -0
- package/dist/browser/canvas-session-sync-manager.d.ts +21 -0
- package/dist/browser/canvas-session-sync-manager.d.ts.map +1 -0
- 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 +179 -1
- package/dist/browser/manager-types.d.ts.map +1 -1
- package/dist/browser/ops-browser-manager.d.ts +114 -4
- 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 +25 -0
- package/dist/canvas/code-sync/apply-tsx.d.ts.map +1 -0
- package/dist/canvas/code-sync/graph.d.ts +5 -0
- package/dist/canvas/code-sync/graph.d.ts.map +1 -0
- package/dist/canvas/code-sync/hash.d.ts +3 -0
- package/dist/canvas/code-sync/hash.d.ts.map +1 -0
- package/dist/canvas/code-sync/import.d.ts +19 -0
- package/dist/canvas/code-sync/import.d.ts.map +1 -0
- package/dist/canvas/code-sync/manifest.d.ts +6 -0
- package/dist/canvas/code-sync/manifest.d.ts.map +1 -0
- package/dist/canvas/code-sync/tsx-adapter.d.ts +8 -0
- package/dist/canvas/code-sync/tsx-adapter.d.ts.map +1 -0
- package/dist/canvas/code-sync/types.d.ts +244 -0
- package/dist/canvas/code-sync/types.d.ts.map +1 -0
- package/dist/canvas/code-sync/write.d.ts +9 -0
- package/dist/canvas/code-sync/write.d.ts.map +1 -0
- package/dist/canvas/document-store.d.ts +91 -0
- package/dist/canvas/document-store.d.ts.map +1 -0
- package/dist/canvas/export.d.ts +12 -0
- package/dist/canvas/export.d.ts.map +1 -0
- 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 +12 -0
- package/dist/canvas/repo-store.d.ts.map +1 -0
- package/dist/canvas/starters/catalog.d.ts +34 -0
- package/dist/canvas/starters/catalog.d.ts.map +1 -0
- package/dist/canvas/surface-palette.d.ts +15 -0
- package/dist/canvas/surface-palette.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 +594 -0
- package/dist/canvas/types.d.ts.map +1 -0
- package/dist/canvas-runtime-preview-bridge-HBEHXM4T.js +7 -0
- package/dist/canvas-runtime-preview-bridge-HBEHXM4T.js.map +1 -0
- 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-7W3SPXIB.js → chunk-FUSXMW3G.js} +4 -1
- package/dist/chunk-L57D35TB.js +33513 -0
- package/dist/chunk-L57D35TB.js.map +1 -0
- package/dist/chunk-TBUCZX4A.js +34 -0
- package/dist/chunk-TBUCZX4A.js.map +1 -0
- package/dist/chunk-Y2KL55OG.js +59 -0
- package/dist/chunk-Y2KL55OG.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/annotate.d.ts +11 -0
- package/dist/cli/commands/annotate.d.ts.map +1 -1
- package/dist/cli/commands/artifacts.d.ts.map +1 -1
- package/dist/cli/commands/canvas.d.ts +45 -0
- package/dist/cli/commands/canvas.d.ts.map +1 -0
- 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/perf.d.ts.map +1 -1
- 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 +3 -0
- package/dist/cli/commands/devtools/screenshot.d.ts.map +1 -1
- package/dist/cli/commands/dom/attr.d.ts.map +1 -1
- package/dist/cli/commands/dom/checked.d.ts.map +1 -1
- package/dist/cli/commands/dom/enabled.d.ts.map +1 -1
- package/dist/cli/commands/dom/html.d.ts.map +1 -1
- package/dist/cli/commands/dom/text.d.ts.map +1 -1
- package/dist/cli/commands/dom/value.d.ts.map +1 -1
- package/dist/cli/commands/dom/visible.d.ts.map +1 -1
- package/dist/cli/commands/export/clone-component.d.ts +9 -0
- package/dist/cli/commands/export/clone-component.d.ts.map +1 -1
- package/dist/cli/commands/export/clone-page.d.ts +8 -0
- package/dist/cli/commands/export/clone-page.d.ts.map +1 -1
- package/dist/cli/commands/interact/check.d.ts.map +1 -1
- package/dist/cli/commands/interact/click.d.ts.map +1 -1
- package/dist/cli/commands/interact/hover.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/press.d.ts.map +1 -1
- package/dist/cli/commands/interact/scroll-into-view.d.ts.map +1 -1
- package/dist/cli/commands/interact/scroll.d.ts.map +1 -1
- package/dist/cli/commands/interact/select.d.ts.map +1 -1
- package/dist/cli/commands/interact/type.d.ts.map +1 -1
- package/dist/cli/commands/interact/uncheck.d.ts.map +1 -1
- 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 +22 -8
- package/dist/cli/commands/native.d.ts.map +1 -1
- package/dist/cli/commands/nav/goto.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/nav/wait.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 -21
- 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 -9
- 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 +19 -3
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/index.js +2927 -932
- 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-canvas-manager.d.ts +8 -0
- package/dist/cli/remote-canvas-manager.d.ts.map +1 -0
- 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 +27 -3
- package/dist/cli/remote-manager.d.ts.map +1 -1
- package/dist/cli/remote-relay.d.ts +2 -0
- package/dist/cli/remote-relay.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 +3 -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 +17 -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/fs-UMRKOBNN.js +7 -0
- package/dist/fs-UMRKOBNN.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1221 -460
- 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/{macros-NUBRM44Y.js → macros-ND2M7LWU.js} +2 -2
- package/dist/opendevbrowser.d.ts.map +1 -1
- package/dist/opendevbrowser.js +1221 -460
- 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-G36AM3Z2.js +121 -0
- package/dist/providers-G36AM3Z2.js.map +1 -0
- 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 +108 -4
- 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 +32 -1
- package/dist/relay/relay-server.d.ts.map +1 -1
- package/dist/relay/relay-types.d.ts +3 -0
- package/dist/relay/relay-types.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-loader.js.map +1 -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/annotate.d.ts.map +1 -1
- package/dist/tools/canvas.d.ts +4 -0
- package/dist/tools/canvas.d.ts.map +1 -0
- package/dist/tools/check.d.ts.map +1 -1
- package/dist/tools/click.d.ts.map +1 -1
- package/dist/tools/clone_component.d.ts.map +1 -1
- package/dist/tools/clone_page.d.ts.map +1 -1
- package/dist/tools/connect.d.ts.map +1 -1
- package/dist/tools/deps.d.ts +6 -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/dom_get_html.d.ts.map +1 -1
- package/dist/tools/dom_get_text.d.ts.map +1 -1
- package/dist/tools/get_attr.d.ts.map +1 -1
- package/dist/tools/get_value.d.ts.map +1 -1
- package/dist/tools/goto.d.ts.map +1 -1
- package/dist/tools/hover.d.ts.map +1 -1
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/is_checked.d.ts.map +1 -1
- package/dist/tools/is_enabled.d.ts.map +1 -1
- package/dist/tools/is_visible.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/perf.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/press.d.ts.map +1 -1
- 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/response.d.ts +4 -1
- package/dist/tools/response.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/scroll.d.ts.map +1 -1
- package/dist/tools/scroll_into_view.d.ts.map +1 -1
- package/dist/tools/select.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/snapshot.d.ts.map +1 -1
- package/dist/tools/type.d.ts.map +1 -1
- package/dist/tools/uncheck.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/wait.d.ts.map +1 -1
- package/dist/tools/workflow-runtime.d.ts +4 -2
- 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 +1006 -0
- package/extension/dist/annotate-content.css +15 -6
- package/extension/dist/annotate-content.js +175 -35
- package/extension/dist/annotation-payload.js +199 -0
- package/extension/dist/background.js +544 -69
- package/extension/dist/canvas/canvas-runtime.js +1490 -0
- package/extension/dist/canvas/model.js +341 -0
- package/extension/dist/canvas/viewport-fit.js +67 -0
- package/extension/dist/canvas-page.js +3609 -0
- package/extension/dist/ops/dom-bridge.js +255 -3
- package/extension/dist/ops/ops-runtime.js +3324 -301
- package/extension/dist/ops/ops-session-store.js +97 -112
- 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 +159 -0
- package/extension/dist/popup.js +201 -42
- package/extension/dist/services/CDPRouter.js +1567 -63
- package/extension/dist/services/ConnectionManager.js +453 -78
- package/extension/dist/services/RelayClient.js +79 -30
- package/extension/dist/services/TabManager.js +118 -22
- 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/dist/types.js +2 -0
- package/extension/manifest.json +2 -2
- package/extension/popup.html +59 -6
- package/package.json +19 -9
- package/skills/AGENTS.md +8 -4
- package/skills/opendevbrowser-best-practices/SKILL.md +183 -6
- package/skills/opendevbrowser-best-practices/artifacts/browser-agent-known-issues-matrix.md +1 -0
- package/skills/opendevbrowser-best-practices/artifacts/canvas-governance-playbook.md +141 -0
- package/skills/opendevbrowser-best-practices/artifacts/command-channel-reference.md +129 -19
- 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/canvas-blocker-checklist.json +70 -0
- package/skills/opendevbrowser-best-practices/assets/templates/canvas-feedback-eval.json +73 -0
- package/skills/opendevbrowser-best-practices/assets/templates/canvas-generation-plan.v1.json +67 -0
- package/skills/opendevbrowser-best-practices/assets/templates/canvas-handshake-example.json +126 -0
- package/skills/opendevbrowser-best-practices/assets/templates/robustness-checklist.json +57 -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 +12 -3
- package/skills/opendevbrowser-best-practices/scripts/odb-workflow.sh +107 -12
- package/skills/opendevbrowser-best-practices/scripts/resolve-odb-cli.sh +100 -0
- package/skills/opendevbrowser-best-practices/scripts/run-robustness-audit.sh +83 -1
- package/skills/opendevbrowser-best-practices/scripts/validate-skill-assets.sh +365 -84
- 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-ST7CO5FA.js +0 -18668
- package/dist/chunk-ST7CO5FA.js.map +0 -1
- /package/dist/{chunk-7W3SPXIB.js.map → chunk-FUSXMW3G.js.map} +0 -0
- /package/dist/{macros-NUBRM44Y.js.map → macros-ND2M7LWU.js.map} +0 -0
|
@@ -3,10 +3,21 @@ import { NativePortManager } from "./services/NativePortManager.js";
|
|
|
3
3
|
import { DEFAULT_AUTO_CONNECT, DEFAULT_AUTO_PAIR, DEFAULT_DISCOVERY_PORT, DEFAULT_NATIVE_ENABLED, DEFAULT_PAIRING_ENABLED, DEFAULT_RELAY_PORT } from "./relay-settings.js";
|
|
4
4
|
import { logError } from "./logging.js";
|
|
5
5
|
import { OpsRuntime } from "./ops/ops-runtime.js";
|
|
6
|
+
import { CanvasRuntime } from "./canvas/canvas-runtime.js";
|
|
7
|
+
import { formatDispatchSourceLabel, stripAnnotationPayloadScreenshots } from "./annotation-payload.js";
|
|
8
|
+
import { getRestrictionMessage } from "./services/url-restrictions.js";
|
|
6
9
|
const connection = new ConnectionManager();
|
|
10
|
+
let canvasRuntime;
|
|
7
11
|
const opsRuntime = new OpsRuntime({
|
|
8
12
|
send: (message) => connection.sendOpsMessage(message),
|
|
9
|
-
cdp: connection.getCdpRouter()
|
|
13
|
+
cdp: connection.getCdpRouter(),
|
|
14
|
+
getCanvasPageState: (targetId) => canvasRuntime.getPageStateByTargetId(targetId),
|
|
15
|
+
performCanvasPageAction: (targetId, action, selector) => canvasRuntime.performPageAction(targetId, action, selector)
|
|
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)
|
|
10
21
|
});
|
|
11
22
|
const nativePort = new NativePortManager({
|
|
12
23
|
onMessage: (payload) => {
|
|
@@ -22,6 +33,7 @@ let autoConnectInFlight = false;
|
|
|
22
33
|
let statusNoteOverride = null;
|
|
23
34
|
let retryScheduled = false;
|
|
24
35
|
let retryDelayMs = 5000;
|
|
36
|
+
let autoConnectEnabled = DEFAULT_AUTO_CONNECT;
|
|
25
37
|
let nativeEnabled = DEFAULT_NATIVE_ENABLED;
|
|
26
38
|
const RETRY_ALARM_NAME = "opendevbrowser-auto-connect";
|
|
27
39
|
const RETRY_MAX_MS = 60_000;
|
|
@@ -29,12 +41,20 @@ const ANNOTATION_CONTENT_SCRIPT = "dist/annotate-content.js";
|
|
|
29
41
|
const ANNOTATION_CONTENT_STYLE = "dist/annotate-content.css";
|
|
30
42
|
const ANNOTATION_MAX_PAYLOAD_BYTES = 10 * 1024 * 1024;
|
|
31
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.";
|
|
32
45
|
const LAST_ANNOTATION_META_KEY = "annotationLastMeta";
|
|
33
46
|
const LAST_ANNOTATION_PAYLOAD_KEY = "annotationLastPayloadSansScreenshots";
|
|
47
|
+
const LAST_AGENT_ANNOTATION_META_KEY = "annotationAgentMeta";
|
|
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;
|
|
34
51
|
const BADGE_CONNECTED_DOT_COLOR = "#16a34a";
|
|
35
52
|
const BADGE_DISCONNECTED_DOT_COLOR = "#dc2626";
|
|
36
53
|
const annotationSessions = new Map();
|
|
37
54
|
let lastAnnotationFull = null;
|
|
55
|
+
let lastAgentAnnotationFull = null;
|
|
56
|
+
let lastAnnotatableTabId = null;
|
|
57
|
+
let lastPopupAnnotationTarget = null;
|
|
38
58
|
connection.onAnnotationCommand((command) => {
|
|
39
59
|
handleRelayAnnotationCommand(command).catch((error) => {
|
|
40
60
|
logError("annotation.relay_command", error, { code: "annotation_command_failed" });
|
|
@@ -43,16 +63,9 @@ connection.onAnnotationCommand((command) => {
|
|
|
43
63
|
connection.onOpsMessage((message) => {
|
|
44
64
|
opsRuntime.handleMessage(message);
|
|
45
65
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"chrome-search:",
|
|
50
|
-
"chrome-untrusted:",
|
|
51
|
-
"devtools:",
|
|
52
|
-
"chrome-devtools:",
|
|
53
|
-
"edge:",
|
|
54
|
-
"brave:"
|
|
55
|
-
]);
|
|
66
|
+
connection.onCanvasMessage((message) => {
|
|
67
|
+
canvasRuntime.handleMessage(message);
|
|
68
|
+
});
|
|
56
69
|
const updateBadge = (status) => {
|
|
57
70
|
const isConnected = status === "connected";
|
|
58
71
|
const dotColor = isConnected ? BADGE_CONNECTED_DOT_COLOR : BADGE_DISCONNECTED_DOT_COLOR;
|
|
@@ -139,6 +152,16 @@ const setStorage = (items) => {
|
|
|
139
152
|
const setStatusNoteOverride = (note) => {
|
|
140
153
|
statusNoteOverride = note;
|
|
141
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
|
+
};
|
|
142
165
|
const buildRelayHealthNote = (health) => {
|
|
143
166
|
if (!health) {
|
|
144
167
|
return "Relay unreachable. Start the daemon and retry.";
|
|
@@ -149,13 +172,15 @@ const buildRelayHealthNote = (health) => {
|
|
|
149
172
|
case "pairing_required":
|
|
150
173
|
return "Pairing required. Enable auto-pair or set the token.";
|
|
151
174
|
case "handshake_incomplete":
|
|
152
|
-
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.";
|
|
153
176
|
case "extension_disconnected":
|
|
154
177
|
return "Extension not connected to relay. Click Connect.";
|
|
155
178
|
case "annotation_disconnected":
|
|
156
179
|
return "Annotation channel disconnected. Keep the extension open and retry.";
|
|
157
180
|
case "ops_disconnected":
|
|
158
181
|
return "Ops channel disconnected. Start a new session and retry.";
|
|
182
|
+
case "canvas_disconnected":
|
|
183
|
+
return "Canvas channel disconnected. Reopen the design canvas command and retry.";
|
|
159
184
|
case "cdp_disconnected":
|
|
160
185
|
return "No CDP clients connected. Start a session and retry.";
|
|
161
186
|
case "relay_down":
|
|
@@ -243,23 +268,11 @@ const parseEpoch = (value) => {
|
|
|
243
268
|
}
|
|
244
269
|
return null;
|
|
245
270
|
};
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
return true;
|
|
252
|
-
}
|
|
253
|
-
return false;
|
|
254
|
-
};
|
|
255
|
-
const getRestrictionMessage = (url) => {
|
|
256
|
-
if (RESTRICTED_PROTOCOLS.has(url.protocol)) {
|
|
257
|
-
return "Active tab uses a restricted URL scheme. Open a normal http(s) page and retry.";
|
|
258
|
-
}
|
|
259
|
-
if (isWebStoreUrl(url)) {
|
|
260
|
-
return "Chrome Web Store tabs cannot be annotated. Open a normal tab and retry.";
|
|
261
|
-
}
|
|
262
|
-
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
|
+
});
|
|
263
276
|
};
|
|
264
277
|
const fetchRelayConfig = async (port) => {
|
|
265
278
|
try {
|
|
@@ -303,6 +316,7 @@ const fetchRelayHealth = async (port) => {
|
|
|
303
316
|
const cdpConnected = data.cdpConnected === true;
|
|
304
317
|
const annotationConnected = data.annotationConnected === true;
|
|
305
318
|
const opsConnected = data.opsConnected === true;
|
|
319
|
+
const canvasConnected = data.canvasConnected === true;
|
|
306
320
|
const pairingRequired = data.pairingRequired === true;
|
|
307
321
|
const ok = extensionConnected && handshake;
|
|
308
322
|
return {
|
|
@@ -313,6 +327,7 @@ const fetchRelayHealth = async (port) => {
|
|
|
313
327
|
cdpConnected,
|
|
314
328
|
annotationConnected,
|
|
315
329
|
opsConnected,
|
|
330
|
+
canvasConnected,
|
|
316
331
|
pairingRequired
|
|
317
332
|
};
|
|
318
333
|
}
|
|
@@ -432,10 +447,166 @@ const waitForTabComplete = async (tabId, timeoutMs = 10000) => {
|
|
|
432
447
|
chrome.tabs.onUpdated.addListener(listener);
|
|
433
448
|
});
|
|
434
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
|
+
};
|
|
435
465
|
const getActiveTab = async () => {
|
|
436
466
|
const tabs = await chrome.tabs.query({ active: true, lastFocusedWindow: true });
|
|
437
467
|
return tabs[0] ?? null;
|
|
438
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
|
+
};
|
|
439
610
|
const resolveAnnotationTab = async (command) => {
|
|
440
611
|
if (typeof command.tabId === "number") {
|
|
441
612
|
if (command.url) {
|
|
@@ -456,7 +627,7 @@ const resolveAnnotationTab = async (command) => {
|
|
|
456
627
|
}
|
|
457
628
|
return created;
|
|
458
629
|
}
|
|
459
|
-
const active = await
|
|
630
|
+
const active = await getPreferredAnnotationTab();
|
|
460
631
|
if (!active) {
|
|
461
632
|
throw new Error("No active tab available");
|
|
462
633
|
}
|
|
@@ -474,7 +645,7 @@ const isRestrictedTab = (tab) => {
|
|
|
474
645
|
logError("annotation.parse_tab_url", error, { code: "tab_url_parse_failed" });
|
|
475
646
|
return "Active tab URL is invalid.";
|
|
476
647
|
}
|
|
477
|
-
return
|
|
648
|
+
return getAnnotationRestrictionMessage(parsed);
|
|
478
649
|
};
|
|
479
650
|
const injectAnnotationAssets = async (tabId) => {
|
|
480
651
|
await new Promise((resolve, reject) => {
|
|
@@ -516,20 +687,56 @@ const isMissingAnnotationReceiverError = (error) => {
|
|
|
516
687
|
}
|
|
517
688
|
return error.message.includes("Receiving end does not exist");
|
|
518
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
|
+
};
|
|
519
724
|
const sleep = async (ms) => {
|
|
520
725
|
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
521
726
|
};
|
|
522
727
|
const pingAnnotation = async (tabId) => {
|
|
523
728
|
const response = await sendMessageToTab(tabId, { type: "annotation:ping" });
|
|
524
|
-
const
|
|
525
|
-
if (!
|
|
729
|
+
const ready = readAnnotationBridgeStatus(response);
|
|
730
|
+
if (!ready) {
|
|
526
731
|
throw new Error("Annotation ping failed");
|
|
527
732
|
}
|
|
733
|
+
rememberPopupAnnotationTarget(tabId, ready.bootId);
|
|
734
|
+
return ready;
|
|
528
735
|
};
|
|
529
736
|
const ensureAnnotationInjected = async (tabId) => {
|
|
737
|
+
await waitForAnnotationTabReady(tabId);
|
|
530
738
|
try {
|
|
531
|
-
await pingAnnotation(tabId);
|
|
532
|
-
return;
|
|
739
|
+
return await pingAnnotation(tabId);
|
|
533
740
|
}
|
|
534
741
|
catch (error) {
|
|
535
742
|
// Initial ping can fail before content script injection; avoid noisy logs for missing receivers.
|
|
@@ -541,9 +748,9 @@ const ensureAnnotationInjected = async (tabId) => {
|
|
|
541
748
|
let lastError = null;
|
|
542
749
|
for (let attempt = 0; attempt <= backoff.length; attempt += 1) {
|
|
543
750
|
try {
|
|
751
|
+
await waitForAnnotationTabReady(tabId);
|
|
544
752
|
await injectAnnotationAssets(tabId);
|
|
545
|
-
await pingAnnotation(tabId);
|
|
546
|
-
return;
|
|
753
|
+
return await pingAnnotation(tabId);
|
|
547
754
|
}
|
|
548
755
|
catch (error) {
|
|
549
756
|
lastError = error;
|
|
@@ -554,13 +761,55 @@ const ensureAnnotationInjected = async (tabId) => {
|
|
|
554
761
|
}
|
|
555
762
|
}
|
|
556
763
|
}
|
|
764
|
+
if (isMissingAnnotationReceiverError(lastError)) {
|
|
765
|
+
throw new Error(ANNOTATION_RECEIVER_UNAVAILABLE_MESSAGE);
|
|
766
|
+
}
|
|
557
767
|
if (lastError instanceof Error) {
|
|
558
768
|
throw lastError;
|
|
559
769
|
}
|
|
560
770
|
throw new Error("Annotation injection failed");
|
|
561
771
|
};
|
|
562
|
-
const
|
|
563
|
-
|
|
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);
|
|
564
813
|
if (!active || typeof active.id !== "number") {
|
|
565
814
|
return { injected: false, detail: "No active tab available." };
|
|
566
815
|
}
|
|
@@ -568,8 +817,12 @@ const probeAnnotationInjected = async () => {
|
|
|
568
817
|
if (restricted) {
|
|
569
818
|
return { injected: false, detail: restricted };
|
|
570
819
|
}
|
|
820
|
+
if (active.status && active.status !== "complete") {
|
|
821
|
+
return { injected: false, detail: "Active tab is still loading." };
|
|
822
|
+
}
|
|
571
823
|
try {
|
|
572
|
-
await pingAnnotation(active.id);
|
|
824
|
+
const ready = await pingAnnotation(active.id);
|
|
825
|
+
rememberPopupAnnotationTarget(active.id, ready.bootId);
|
|
573
826
|
return { injected: true };
|
|
574
827
|
}
|
|
575
828
|
catch (error) {
|
|
@@ -578,7 +831,7 @@ const probeAnnotationInjected = async () => {
|
|
|
578
831
|
}
|
|
579
832
|
};
|
|
580
833
|
const toggleAnnotationUi = async () => {
|
|
581
|
-
const tab = await
|
|
834
|
+
const tab = await getPreferredAnnotationTab();
|
|
582
835
|
if (!tab || typeof tab.id !== "number") {
|
|
583
836
|
return;
|
|
584
837
|
}
|
|
@@ -587,7 +840,7 @@ const toggleAnnotationUi = async () => {
|
|
|
587
840
|
return;
|
|
588
841
|
}
|
|
589
842
|
await ensureAnnotationInjected(tab.id);
|
|
590
|
-
await
|
|
843
|
+
await sendAnnotationMessageToTab(tab.id, { type: "annotation:toggle" });
|
|
591
844
|
};
|
|
592
845
|
const startAnnotationSession = async (command, transport) => {
|
|
593
846
|
const requestId = command.requestId;
|
|
@@ -620,9 +873,11 @@ const startAnnotationSession = async (command, transport) => {
|
|
|
620
873
|
}, transport);
|
|
621
874
|
return;
|
|
622
875
|
}
|
|
876
|
+
rememberAnnotatableTab(tab);
|
|
623
877
|
let timeoutId = null;
|
|
624
878
|
try {
|
|
625
|
-
await ensureAnnotationInjected(tab.id);
|
|
879
|
+
const initialBridge = await ensureAnnotationInjected(tab.id);
|
|
880
|
+
rememberPopupAnnotationTarget(tab.id, initialBridge.bootId);
|
|
626
881
|
timeoutId = startAnnotationTimeout(requestId, transport);
|
|
627
882
|
annotationSessions.set(requestId, {
|
|
628
883
|
requestId,
|
|
@@ -632,18 +887,15 @@ const startAnnotationSession = async (command, transport) => {
|
|
|
632
887
|
timeoutId,
|
|
633
888
|
transport
|
|
634
889
|
});
|
|
635
|
-
await
|
|
636
|
-
|
|
637
|
-
requestId,
|
|
638
|
-
options: command.options ?? {},
|
|
639
|
-
url: command.url
|
|
640
|
-
});
|
|
890
|
+
const startedBridge = await startAnnotationUi(tab.id, requestId, command.options, command.url);
|
|
891
|
+
rememberPopupAnnotationTarget(tab.id, startedBridge.bootId);
|
|
641
892
|
}
|
|
642
893
|
catch (error) {
|
|
643
894
|
if (timeoutId !== null) {
|
|
644
895
|
clearTimeout(timeoutId);
|
|
645
896
|
}
|
|
646
897
|
annotationSessions.delete(requestId);
|
|
898
|
+
clearPopupAnnotationTarget(tab.id);
|
|
647
899
|
throw error instanceof Error ? error : new Error("Annotation injection failed");
|
|
648
900
|
}
|
|
649
901
|
};
|
|
@@ -660,7 +912,7 @@ const cancelAnnotationSession = async (requestId, transport) => {
|
|
|
660
912
|
}
|
|
661
913
|
clearTimeout(session.timeoutId);
|
|
662
914
|
annotationSessions.delete(requestId);
|
|
663
|
-
await
|
|
915
|
+
await sendAnnotationMessageToTab(session.tabId, { type: "annotation:cancel", requestId });
|
|
664
916
|
sendAnnotationResponse({
|
|
665
917
|
version: 1,
|
|
666
918
|
requestId,
|
|
@@ -675,19 +927,7 @@ const validatePayloadSize = (payload) => {
|
|
|
675
927
|
const generateAnnotationRequestId = () => {
|
|
676
928
|
return crypto.randomUUID();
|
|
677
929
|
};
|
|
678
|
-
const
|
|
679
|
-
const { screenshots, annotations, ...rest } = payload;
|
|
680
|
-
void screenshots;
|
|
681
|
-
return {
|
|
682
|
-
...rest,
|
|
683
|
-
annotations: annotations.map((item) => {
|
|
684
|
-
const { screenshotId, ...restItem } = item;
|
|
685
|
-
void screenshotId;
|
|
686
|
-
return restItem;
|
|
687
|
-
})
|
|
688
|
-
};
|
|
689
|
-
};
|
|
690
|
-
const buildLastAnnotationMeta = (requestId, response, hasFullPayloadInMemory) => {
|
|
930
|
+
const buildLastAnnotationMeta = (requestId, response, hasFullPayloadInMemory, extras = {}) => {
|
|
691
931
|
const payload = response.payload;
|
|
692
932
|
const annotationCount = payload ? payload.annotations.length : undefined;
|
|
693
933
|
const screenshotCount = payload?.screenshots?.length ?? 0;
|
|
@@ -695,6 +935,9 @@ const buildLastAnnotationMeta = (requestId, response, hasFullPayloadInMemory) =>
|
|
|
695
935
|
requestId,
|
|
696
936
|
status: response.status,
|
|
697
937
|
error: response.error,
|
|
938
|
+
receipt: extras.receipt ?? response.receipt,
|
|
939
|
+
source: extras.source,
|
|
940
|
+
label: extras.label,
|
|
698
941
|
url: payload?.url,
|
|
699
942
|
title: payload?.title,
|
|
700
943
|
timestamp: payload?.timestamp,
|
|
@@ -712,6 +955,12 @@ const persistLastAnnotation = async (meta, payload) => {
|
|
|
712
955
|
[LAST_ANNOTATION_PAYLOAD_KEY]: payload
|
|
713
956
|
});
|
|
714
957
|
};
|
|
958
|
+
const persistAgentAnnotation = async (meta, payload) => {
|
|
959
|
+
await setStorage({
|
|
960
|
+
[LAST_AGENT_ANNOTATION_META_KEY]: meta,
|
|
961
|
+
[LAST_AGENT_ANNOTATION_PAYLOAD_KEY]: payload
|
|
962
|
+
});
|
|
963
|
+
};
|
|
715
964
|
const loadPersistedLastAnnotation = async () => {
|
|
716
965
|
const data = await new Promise((resolve) => {
|
|
717
966
|
chrome.storage.local.get([LAST_ANNOTATION_META_KEY, LAST_ANNOTATION_PAYLOAD_KEY], (items) => resolve(items));
|
|
@@ -722,6 +971,108 @@ const loadPersistedLastAnnotation = async () => {
|
|
|
722
971
|
const payload = payloadRecord && typeof payloadRecord === "object" ? payloadRecord : null;
|
|
723
972
|
return { meta, payload };
|
|
724
973
|
};
|
|
974
|
+
const loadPersistedAgentAnnotation = async () => {
|
|
975
|
+
const data = await new Promise((resolve) => {
|
|
976
|
+
chrome.storage.local.get([LAST_AGENT_ANNOTATION_META_KEY, LAST_AGENT_ANNOTATION_PAYLOAD_KEY], (items) => resolve(items));
|
|
977
|
+
});
|
|
978
|
+
const metaRecord = data[LAST_AGENT_ANNOTATION_META_KEY];
|
|
979
|
+
const payloadRecord = data[LAST_AGENT_ANNOTATION_PAYLOAD_KEY];
|
|
980
|
+
const meta = metaRecord && typeof metaRecord === "object" ? metaRecord : null;
|
|
981
|
+
const payload = payloadRecord && typeof payloadRecord === "object" ? payloadRecord : null;
|
|
982
|
+
return { meta, payload };
|
|
983
|
+
};
|
|
984
|
+
const isAnnotationPayload = (value) => {
|
|
985
|
+
if (!value || typeof value !== "object") {
|
|
986
|
+
return false;
|
|
987
|
+
}
|
|
988
|
+
const payload = value;
|
|
989
|
+
return typeof payload.url === "string"
|
|
990
|
+
&& typeof payload.timestamp === "string"
|
|
991
|
+
&& typeof payload.screenshotMode === "string"
|
|
992
|
+
&& Array.isArray(payload.annotations);
|
|
993
|
+
};
|
|
994
|
+
const storeAgentAnnotationPayload = async (payload, source, label, receipt) => {
|
|
995
|
+
if (!validatePayloadSize(payload)) {
|
|
996
|
+
throw new Error("Annotation payload exceeded size limits.");
|
|
997
|
+
}
|
|
998
|
+
const response = {
|
|
999
|
+
version: 1,
|
|
1000
|
+
requestId: receipt?.receiptId ?? crypto.randomUUID(),
|
|
1001
|
+
status: "ok",
|
|
1002
|
+
payload,
|
|
1003
|
+
receipt
|
|
1004
|
+
};
|
|
1005
|
+
const meta = buildLastAnnotationMeta(response.requestId, response, true, {
|
|
1006
|
+
source,
|
|
1007
|
+
label: label?.trim().length ? label.trim() : formatDispatchSourceLabel(source),
|
|
1008
|
+
receipt
|
|
1009
|
+
});
|
|
1010
|
+
lastAgentAnnotationFull = { meta, payload };
|
|
1011
|
+
await persistAgentAnnotation({ ...meta, hasFullPayloadInMemory: false }, stripAnnotationPayloadScreenshots(payload));
|
|
1012
|
+
return meta;
|
|
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
|
+
};
|
|
1043
|
+
const loadAgentAnnotationPayload = async (includeScreenshots) => {
|
|
1044
|
+
if (includeScreenshots && lastAgentAnnotationFull) {
|
|
1045
|
+
return {
|
|
1046
|
+
version: 1,
|
|
1047
|
+
requestId: crypto.randomUUID(),
|
|
1048
|
+
status: "ok",
|
|
1049
|
+
payload: lastAgentAnnotationFull.payload
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
if (lastAgentAnnotationFull) {
|
|
1053
|
+
return {
|
|
1054
|
+
version: 1,
|
|
1055
|
+
requestId: crypto.randomUUID(),
|
|
1056
|
+
status: "ok",
|
|
1057
|
+
payload: stripAnnotationPayloadScreenshots(lastAgentAnnotationFull.payload)
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
const stored = await loadPersistedAgentAnnotation();
|
|
1061
|
+
if (stored.payload) {
|
|
1062
|
+
return {
|
|
1063
|
+
version: 1,
|
|
1064
|
+
requestId: crypto.randomUUID(),
|
|
1065
|
+
status: "ok",
|
|
1066
|
+
payload: stored.payload
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
return {
|
|
1070
|
+
version: 1,
|
|
1071
|
+
requestId: crypto.randomUUID(),
|
|
1072
|
+
status: "error",
|
|
1073
|
+
error: { code: "payload_unavailable", message: "No agent-dispatched annotation payload available." }
|
|
1074
|
+
};
|
|
1075
|
+
};
|
|
725
1076
|
async function handleNativePortMessage(payload) {
|
|
726
1077
|
if (!payload || typeof payload !== "object") {
|
|
727
1078
|
return;
|
|
@@ -746,6 +1097,14 @@ const handleRelayAnnotationCommand = async (command, transport = "relay") => {
|
|
|
746
1097
|
await cancelAnnotationSession(payload.requestId, transport);
|
|
747
1098
|
return;
|
|
748
1099
|
}
|
|
1100
|
+
if (payload.command === "fetch_stored") {
|
|
1101
|
+
const stored = await loadAgentAnnotationPayload(payload.options?.includeScreenshots === true);
|
|
1102
|
+
sendAnnotationResponse({
|
|
1103
|
+
...stored,
|
|
1104
|
+
requestId: payload.requestId
|
|
1105
|
+
}, transport);
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
749
1108
|
try {
|
|
750
1109
|
await startAnnotationSession(payload, transport);
|
|
751
1110
|
sendAnnotationEvent({
|
|
@@ -805,7 +1164,7 @@ const handleAnnotationComplete = (requestId, payload) => {
|
|
|
805
1164
|
const meta = buildLastAnnotationMeta(requestId, response, true);
|
|
806
1165
|
lastAnnotationFull = { meta, payload };
|
|
807
1166
|
const storageMeta = { ...meta, hasFullPayloadInMemory: false };
|
|
808
|
-
const sanitizedPayload =
|
|
1167
|
+
const sanitizedPayload = stripAnnotationPayloadScreenshots(payload);
|
|
809
1168
|
persistLastAnnotation(storageMeta, sanitizedPayload).catch((error) => {
|
|
810
1169
|
logError("annotation.persist_sanitized_payload", error, { code: "annotation_persist_failed" });
|
|
811
1170
|
});
|
|
@@ -911,6 +1270,7 @@ const attemptAutoConnect = async () => {
|
|
|
911
1270
|
});
|
|
912
1271
|
});
|
|
913
1272
|
const autoConnect = typeof data.autoConnect === "boolean" ? data.autoConnect : DEFAULT_AUTO_CONNECT;
|
|
1273
|
+
autoConnectEnabled = autoConnect;
|
|
914
1274
|
if (!autoConnect || connection.getStatus() === "connected") {
|
|
915
1275
|
clearRetry();
|
|
916
1276
|
return;
|
|
@@ -976,6 +1336,7 @@ const attemptAutoConnect = async () => {
|
|
|
976
1336
|
if (config.instanceId && fetched.instanceId && config.instanceId !== fetched.instanceId) {
|
|
977
1337
|
console.warn("[opendevbrowser] Relay instance mismatch during auto-pair. Retrying later.");
|
|
978
1338
|
setStatusNoteOverride("Relay instance mismatch. Open the popup and click Connect.");
|
|
1339
|
+
scheduleRetry();
|
|
979
1340
|
return;
|
|
980
1341
|
}
|
|
981
1342
|
const tokenEpoch = fetched.epoch ?? configEpoch;
|
|
@@ -1031,6 +1392,9 @@ connection.onStatus((status) => {
|
|
|
1031
1392
|
clearTimeout(session.timeoutId);
|
|
1032
1393
|
}
|
|
1033
1394
|
annotationSessions.clear();
|
|
1395
|
+
if (autoConnectEnabled) {
|
|
1396
|
+
scheduleRetry();
|
|
1397
|
+
}
|
|
1034
1398
|
}
|
|
1035
1399
|
});
|
|
1036
1400
|
updateBadge(getEffectiveStatus());
|
|
@@ -1066,6 +1430,37 @@ if (chrome.commands?.onCommand) {
|
|
|
1066
1430
|
autoConnect().catch((error) => {
|
|
1067
1431
|
logError("auto_connect.startup", error, { code: "auto_connect_failed" });
|
|
1068
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
|
+
});
|
|
1069
1464
|
chrome.storage.onChanged.addListener((changes, area) => {
|
|
1070
1465
|
if (area !== "local") {
|
|
1071
1466
|
return;
|
|
@@ -1077,11 +1472,18 @@ chrome.storage.onChanged.addListener((changes, area) => {
|
|
|
1077
1472
|
}
|
|
1078
1473
|
updateBadge(getEffectiveStatus());
|
|
1079
1474
|
}
|
|
1475
|
+
if (changes.autoConnect) {
|
|
1476
|
+
autoConnectEnabled =
|
|
1477
|
+
typeof changes.autoConnect.newValue === "boolean" ? changes.autoConnect.newValue : DEFAULT_AUTO_CONNECT;
|
|
1478
|
+
}
|
|
1080
1479
|
if (changes.autoConnect?.newValue === true) {
|
|
1081
1480
|
autoConnect().catch((error) => {
|
|
1082
1481
|
logError("auto_connect.setting", error, { code: "auto_connect_failed" });
|
|
1083
1482
|
});
|
|
1084
1483
|
}
|
|
1484
|
+
else if (changes.autoConnect?.newValue === false) {
|
|
1485
|
+
clearRetry();
|
|
1486
|
+
}
|
|
1085
1487
|
if (changes.pairingToken) {
|
|
1086
1488
|
autoConnect().catch((error) => {
|
|
1087
1489
|
logError("auto_connect.pairing_token", error, { code: "auto_connect_failed" });
|
|
@@ -1152,7 +1554,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1152
1554
|
ok: false
|
|
1153
1555
|
};
|
|
1154
1556
|
try {
|
|
1155
|
-
const active = await
|
|
1557
|
+
const active = await getPopupAnnotationTab(message.tabId);
|
|
1156
1558
|
if (!active) {
|
|
1157
1559
|
response.error = { code: "invalid_request", message: "No active tab available." };
|
|
1158
1560
|
sendResponse(response);
|
|
@@ -1212,7 +1614,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1212
1614
|
}
|
|
1213
1615
|
if (message.type === "annotation:probe") {
|
|
1214
1616
|
(async () => {
|
|
1215
|
-
const result = await probeAnnotationInjected();
|
|
1617
|
+
const result = await probeAnnotationInjected(message.tabId);
|
|
1216
1618
|
sendResponse({ type: "annotation:probeResult", ...result });
|
|
1217
1619
|
})().catch((error) => {
|
|
1218
1620
|
logError("annotation.probe", error, { code: "annotation_probe_failed" });
|
|
@@ -1237,9 +1639,9 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1237
1639
|
if (message.includeScreenshots) {
|
|
1238
1640
|
const response = {
|
|
1239
1641
|
type: "annotation:payloadResult",
|
|
1240
|
-
payload:
|
|
1642
|
+
payload: stored.payload,
|
|
1241
1643
|
meta: storedMeta,
|
|
1242
|
-
source: "none",
|
|
1644
|
+
source: stored.payload ? "storage" : "none",
|
|
1243
1645
|
warning: "Full payload not available; screenshots may have been dropped."
|
|
1244
1646
|
};
|
|
1245
1647
|
sendResponse(response);
|
|
@@ -1248,7 +1650,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1248
1650
|
if (lastAnnotationFull) {
|
|
1249
1651
|
const response = {
|
|
1250
1652
|
type: "annotation:payloadResult",
|
|
1251
|
-
payload:
|
|
1653
|
+
payload: stripAnnotationPayloadScreenshots(lastAnnotationFull.payload),
|
|
1252
1654
|
meta: { ...lastAnnotationFull.meta, hasFullPayloadInMemory: true },
|
|
1253
1655
|
source: "memory"
|
|
1254
1656
|
};
|
|
@@ -1285,6 +1687,74 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1285
1687
|
});
|
|
1286
1688
|
return true;
|
|
1287
1689
|
}
|
|
1690
|
+
if (message.type === "annotation:sendPayload") {
|
|
1691
|
+
(async () => {
|
|
1692
|
+
if (!isAnnotationPayload(message.payload)) {
|
|
1693
|
+
const response = {
|
|
1694
|
+
type: "annotation:sendPayloadResult",
|
|
1695
|
+
ok: false,
|
|
1696
|
+
meta: null,
|
|
1697
|
+
receipt: null,
|
|
1698
|
+
error: { code: "invalid_request", message: "Invalid annotation payload." }
|
|
1699
|
+
};
|
|
1700
|
+
sendResponse(response);
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
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
|
+
}
|
|
1736
|
+
const response = {
|
|
1737
|
+
type: "annotation:sendPayloadResult",
|
|
1738
|
+
ok: true,
|
|
1739
|
+
meta: { ...meta, hasFullPayloadInMemory: true },
|
|
1740
|
+
receipt
|
|
1741
|
+
};
|
|
1742
|
+
sendResponse(response);
|
|
1743
|
+
})().catch((error) => {
|
|
1744
|
+
const response = {
|
|
1745
|
+
type: "annotation:sendPayloadResult",
|
|
1746
|
+
ok: false,
|
|
1747
|
+
meta: null,
|
|
1748
|
+
receipt: null,
|
|
1749
|
+
error: {
|
|
1750
|
+
code: "payload_too_large",
|
|
1751
|
+
message: error instanceof Error ? error.message : "Annotation dispatch failed."
|
|
1752
|
+
}
|
|
1753
|
+
};
|
|
1754
|
+
sendResponse(response);
|
|
1755
|
+
});
|
|
1756
|
+
return true;
|
|
1757
|
+
}
|
|
1288
1758
|
if (message.type === "annotation:capture") {
|
|
1289
1759
|
(async () => {
|
|
1290
1760
|
const tab = sender.tab;
|
|
@@ -1319,3 +1789,8 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1319
1789
|
}
|
|
1320
1790
|
return false;
|
|
1321
1791
|
});
|
|
1792
|
+
chrome.runtime.onConnect.addListener((port) => {
|
|
1793
|
+
if (port.name === "canvas-page") {
|
|
1794
|
+
canvasRuntime.attachPort(port);
|
|
1795
|
+
}
|
|
1796
|
+
});
|