opendevbrowser 0.0.28 → 0.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/accessibility-snapshot-PA6NWNS7.js +39 -0
- package/dist/accessibility-snapshot-PA6NWNS7.js.map +1 -0
- package/dist/active-window-YNYTIPZN.js +37 -0
- package/dist/active-window-YNYTIPZN.js.map +1 -0
- package/dist/annotate-STYHXZYJ.js +205 -0
- package/dist/annotate-STYHXZYJ.js.map +1 -0
- package/dist/artifacts-KJ6RNDO2.js +120 -0
- package/dist/artifacts-KJ6RNDO2.js.map +1 -0
- package/dist/attr-GHFZZ4SA.js +84 -0
- package/dist/attr-GHFZZ4SA.js.map +1 -0
- package/dist/browser/ops-client.d.ts +1 -0
- package/dist/browser/ops-client.d.ts.map +1 -1
- package/dist/canvas-54FBOEGP.js +309 -0
- package/dist/canvas-54FBOEGP.js.map +1 -0
- package/dist/capture-desktop-SNABC24E.js +38 -0
- package/dist/capture-desktop-SNABC24E.js.map +1 -0
- package/dist/capture-window-UJSB5AMP.js +40 -0
- package/dist/capture-window-UJSB5AMP.js.map +1 -0
- package/dist/check-ST5UQ2F5.js +71 -0
- package/dist/check-ST5UQ2F5.js.map +1 -0
- package/dist/checked-IEMWI5CU.js +71 -0
- package/dist/checked-IEMWI5CU.js.map +1 -0
- package/dist/chunk-2CG4SW3E.js +64 -0
- package/dist/chunk-2CG4SW3E.js.map +1 -0
- package/dist/chunk-2SIMIPLY.js +67 -0
- package/dist/chunk-2SIMIPLY.js.map +1 -0
- package/dist/chunk-37VSRUW4.js +141 -0
- package/dist/chunk-37VSRUW4.js.map +1 -0
- package/dist/chunk-5SWZDVOW.js +144 -0
- package/dist/chunk-5SWZDVOW.js.map +1 -0
- package/dist/chunk-6PVZ2ABC.js +429 -0
- package/dist/chunk-6PVZ2ABC.js.map +1 -0
- package/dist/chunk-7GVOUZMQ.js +64 -0
- package/dist/chunk-7GVOUZMQ.js.map +1 -0
- package/dist/chunk-7THCPS52.js +84 -0
- package/dist/chunk-7THCPS52.js.map +1 -0
- package/dist/chunk-ASMHEEKY.js +10 -0
- package/dist/chunk-ASMHEEKY.js.map +1 -0
- package/dist/chunk-DBF5OKH3.js +111 -0
- package/dist/chunk-DBF5OKH3.js.map +1 -0
- package/dist/chunk-DW4TX7MU.js +54 -0
- package/dist/chunk-DW4TX7MU.js.map +1 -0
- package/dist/chunk-IPE7TF2P.js +54 -0
- package/dist/chunk-IPE7TF2P.js.map +1 -0
- package/dist/chunk-IQTJHXZJ.js +126 -0
- package/dist/chunk-IQTJHXZJ.js.map +1 -0
- package/dist/chunk-J47N77VG.js +2969 -0
- package/dist/chunk-J47N77VG.js.map +1 -0
- package/dist/chunk-JZXD6FWR.js +25 -0
- package/dist/chunk-JZXD6FWR.js.map +1 -0
- package/dist/{chunk-QVWOPIZJ.js → chunk-KDSNXS6N.js} +75 -149
- package/dist/chunk-KDSNXS6N.js.map +1 -0
- package/dist/chunk-KZ2IXVQT.js +219 -0
- package/dist/chunk-KZ2IXVQT.js.map +1 -0
- package/dist/chunk-LBPELU7L.js +3649 -0
- package/dist/chunk-LBPELU7L.js.map +1 -0
- package/dist/chunk-MX3NFLCE.js +940 -0
- package/dist/chunk-MX3NFLCE.js.map +1 -0
- package/dist/chunk-N44UXKIB.js +26 -0
- package/dist/chunk-N44UXKIB.js.map +1 -0
- package/dist/chunk-OW5HMYMI.js +19 -0
- package/dist/chunk-OW5HMYMI.js.map +1 -0
- package/dist/chunk-OYNLAZQU.js +838 -0
- package/dist/chunk-OYNLAZQU.js.map +1 -0
- package/dist/chunk-PDPJN2OP.js +17 -0
- package/dist/chunk-PDPJN2OP.js.map +1 -0
- package/dist/chunk-RCZZGGJS.js +226 -0
- package/dist/chunk-RCZZGGJS.js.map +1 -0
- package/dist/chunk-RJNI3BHT.js +1 -0
- package/dist/chunk-RPXWUCQQ.js +112 -0
- package/dist/chunk-RPXWUCQQ.js.map +1 -0
- package/dist/chunk-S5KZQJJI.js +107 -0
- package/dist/chunk-S5KZQJJI.js.map +1 -0
- package/dist/{chunk-T3VVHJTK.js → chunk-S6S2UP6U.js} +1074 -1459
- package/dist/chunk-S6S2UP6U.js.map +1 -0
- package/dist/{chunk-I5ZCOZZV.js → chunk-SXAGSEKZ.js} +1202 -9561
- package/dist/chunk-SXAGSEKZ.js.map +1 -0
- package/dist/chunk-T4GMCW6Z.js +46 -0
- package/dist/chunk-T4GMCW6Z.js.map +1 -0
- package/dist/chunk-WHQZBUNY.js +982 -0
- package/dist/chunk-WHQZBUNY.js.map +1 -0
- package/dist/chunk-WOXBLP7V.js +610 -0
- package/dist/chunk-WOXBLP7V.js.map +1 -0
- package/dist/cli/commands/inspiredesign.d.ts.map +1 -1
- package/dist/cli/commands/macro-resolve.d.ts +4 -1
- package/dist/cli/commands/macro-resolve.d.ts.map +1 -1
- package/dist/cli/commands/product-video.d.ts.map +1 -1
- package/dist/cli/commands/research.d.ts.map +1 -1
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/commands/shopping.d.ts.map +1 -1
- package/dist/cli/commands/workflow-output.d.ts +2 -0
- package/dist/cli/commands/workflow-output.d.ts.map +1 -0
- package/dist/cli/daemon-commands.d.ts.map +1 -1
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/index.js +204 -8123
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/installers/postinstall-skill-sync.js +2 -1
- package/dist/cli/installers/postinstall-skill-sync.js.map +1 -1
- package/dist/cli/remote-relay.d.ts.map +1 -1
- package/dist/click-TENZA3Y6.js +81 -0
- package/dist/click-TENZA3Y6.js.map +1 -0
- package/dist/clone-component-STH5AR6M.js +82 -0
- package/dist/clone-component-STH5AR6M.js.map +1 -0
- package/dist/clone-page-BSTWAPAJ.js +69 -0
- package/dist/clone-page-BSTWAPAJ.js.map +1 -0
- package/dist/close-CEMMAAM7.js +63 -0
- package/dist/close-CEMMAAM7.js.map +1 -0
- package/dist/close-QCWUNRAI.js +63 -0
- package/dist/close-QCWUNRAI.js.map +1 -0
- package/dist/connect-J3RVSEZF.js +107 -0
- package/dist/connect-J3RVSEZF.js.map +1 -0
- package/dist/console-poll-HL7BVIVX.js +76 -0
- package/dist/console-poll-HL7BVIVX.js.map +1 -0
- package/dist/cookie-import-WMUCIIHN.js +177 -0
- package/dist/cookie-import-WMUCIIHN.js.map +1 -0
- package/dist/cookie-list-PB2N4RPH.js +117 -0
- package/dist/cookie-list-PB2N4RPH.js.map +1 -0
- package/dist/daemon-5KSVMGN4.js +194 -0
- package/dist/daemon-5KSVMGN4.js.map +1 -0
- package/dist/daemon-fingerprint.json +1 -1
- package/dist/debug-trace-snapshot-RK7KDXA5.js +136 -0
- package/dist/debug-trace-snapshot-RK7KDXA5.js.map +1 -0
- package/dist/dialog-P6P4U7XE.js +75 -0
- package/dist/dialog-P6P4U7XE.js.map +1 -0
- package/dist/disconnect-32F7IDIP.js +58 -0
- package/dist/disconnect-32F7IDIP.js.map +1 -0
- package/dist/enabled-A6C6ZM2O.js +71 -0
- package/dist/enabled-A6C6ZM2O.js.map +1 -0
- package/dist/extension-extractor-GKWSFHPN.js +11 -0
- package/dist/extension-extractor-GKWSFHPN.js.map +1 -0
- package/dist/global-D6WLWBXA.js +56 -0
- package/dist/global-D6WLWBXA.js.map +1 -0
- package/dist/goto-ULTSABDM.js +98 -0
- package/dist/goto-ULTSABDM.js.map +1 -0
- package/dist/help-EKKKEDL5.js +491 -0
- package/dist/help-EKKKEDL5.js.map +1 -0
- package/dist/hover-UF2ZUMTQ.js +71 -0
- package/dist/hover-UF2ZUMTQ.js.map +1 -0
- package/dist/html-B6TX7GK7.js +84 -0
- package/dist/html-B6TX7GK7.js.map +1 -0
- package/dist/index.js +68 -34
- package/dist/index.js.map +1 -1
- package/dist/inspector-6S5FKUZQ.js +62 -0
- package/dist/inspector-6S5FKUZQ.js.map +1 -0
- package/dist/inspector-audit-ARGEGOS7.js +84 -0
- package/dist/inspector-audit-ARGEGOS7.js.map +1 -0
- package/dist/inspector-plan-CSG5HZOC.js +69 -0
- package/dist/inspector-plan-CSG5HZOC.js.map +1 -0
- package/dist/inspiredesign-7VRMMZN4.js +234 -0
- package/dist/inspiredesign-7VRMMZN4.js.map +1 -0
- package/dist/install-autostart-output-5DOMKCQL.js +41 -0
- package/dist/install-autostart-output-5DOMKCQL.js.map +1 -0
- package/dist/install-autostart-reconciliation-NHKOFYTD.js +73 -0
- package/dist/install-autostart-reconciliation-NHKOFYTD.js.map +1 -0
- package/dist/launch-REYCIR3Z.js +225 -0
- package/dist/launch-REYCIR3Z.js.map +1 -0
- package/dist/list-NPRXRQY2.js +51 -0
- package/dist/list-NPRXRQY2.js.map +1 -0
- package/dist/list-STYD2ZWA.js +54 -0
- package/dist/list-STYD2ZWA.js.map +1 -0
- package/dist/local-HXJLUUNT.js +54 -0
- package/dist/local-HXJLUUNT.js.map +1 -0
- package/dist/macro-resolve-ZIJZ65QI.js +253 -0
- package/dist/macro-resolve-ZIJZ65QI.js.map +1 -0
- package/dist/macros/execute-runtime.d.ts +3 -1
- package/dist/macros/execute-runtime.d.ts.map +1 -1
- package/dist/macros/execute.d.ts +2 -0
- package/dist/macros/execute.d.ts.map +1 -1
- package/dist/native-UPLVQ2SG.js +22 -0
- package/dist/native-UPLVQ2SG.js.map +1 -0
- package/dist/network-poll-HLDOSC72.js +76 -0
- package/dist/network-poll-HLDOSC72.js.map +1 -0
- package/dist/new-HXLLN6UT.js +69 -0
- package/dist/new-HXLLN6UT.js.map +1 -0
- package/dist/onboarding-metadata-7E3KLYSZ.js +27 -0
- package/dist/onboarding-metadata-7E3KLYSZ.js.map +1 -0
- package/dist/open-KDR25LQZ.js +81 -0
- package/dist/open-KDR25LQZ.js.map +1 -0
- package/dist/opendevbrowser.js +68 -34
- package/dist/opendevbrowser.js.map +1 -1
- package/dist/perf-EM6SWFJ6.js +58 -0
- package/dist/perf-EM6SWFJ6.js.map +1 -0
- package/dist/pointer-down-ZYWRZNCH.js +55 -0
- package/dist/pointer-down-ZYWRZNCH.js.map +1 -0
- package/dist/pointer-drag-LVEAVJO4.js +54 -0
- package/dist/pointer-drag-LVEAVJO4.js.map +1 -0
- package/dist/pointer-move-7SRKUS66.js +52 -0
- package/dist/pointer-move-7SRKUS66.js.map +1 -0
- package/dist/pointer-up-KLDBSK37.js +55 -0
- package/dist/pointer-up-KLDBSK37.js.map +1 -0
- package/dist/press-UIIXFTD7.js +83 -0
- package/dist/press-UIIXFTD7.js.map +1 -0
- package/dist/product-video-PYOXJVAI.js +235 -0
- package/dist/product-video-PYOXJVAI.js.map +1 -0
- package/dist/providers/artifacts.d.ts +0 -2
- package/dist/providers/artifacts.d.ts.map +1 -1
- package/dist/providers/blocker.d.ts.map +1 -1
- package/dist/providers/bounded-map.d.ts +2 -0
- package/dist/providers/bounded-map.d.ts.map +1 -0
- package/dist/providers/community/index.d.ts.map +1 -1
- package/dist/providers/constraint.d.ts.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/renderer.d.ts.map +1 -1
- package/dist/providers/research-compiler.d.ts +1 -1
- package/dist/providers/research-compiler.d.ts.map +1 -1
- package/dist/providers/research-executor.d.ts.map +1 -1
- package/dist/providers/runtime-factory.d.ts.map +1 -1
- package/dist/providers/shared/traversal-url.d.ts +3 -0
- package/dist/providers/shared/traversal-url.d.ts.map +1 -1
- package/dist/providers/shopping/index.d.ts.map +1 -1
- package/dist/providers/social/search-quality.d.ts.map +1 -1
- package/dist/providers/workflow-handoff.d.ts +4 -0
- package/dist/providers/workflow-handoff.d.ts.map +1 -1
- package/dist/providers/workflows.d.ts.map +1 -1
- package/dist/{providers-QF2RFB4J.js → providers-4YY2BLXG.js} +19 -14
- package/dist/providers-4YY2BLXG.js.map +1 -0
- package/dist/public-surface/generated-manifest.d.ts +2 -2
- package/dist/public-surface/generated-manifest.d.ts.map +1 -1
- package/dist/public-surface/source.d.ts +2 -2
- package/dist/public-surface/source.d.ts.map +1 -1
- package/dist/relay/protocol.d.ts +3 -1
- package/dist/relay/protocol.d.ts.map +1 -1
- package/dist/relay/relay-server.d.ts +6 -0
- package/dist/relay/relay-server.d.ts.map +1 -1
- package/dist/research-CKXMJ2DK.js +295 -0
- package/dist/research-CKXMJ2DK.js.map +1 -0
- package/dist/review-7HWJPZOD.js +48 -0
- package/dist/review-7HWJPZOD.js.map +1 -0
- package/dist/review-desktop-2IBJHFB5.js +54 -0
- package/dist/review-desktop-2IBJHFB5.js.map +1 -0
- package/dist/rpc-3HGIEJUO.js +159 -0
- package/dist/rpc-3HGIEJUO.js.map +1 -0
- package/dist/run-ADRYI3MS.js +180 -0
- package/dist/run-ADRYI3MS.js.map +1 -0
- package/dist/screencast-start-DTLUHD5H.js +67 -0
- package/dist/screencast-start-DTLUHD5H.js.map +1 -0
- package/dist/screencast-stop-54C5LRSS.js +59 -0
- package/dist/screencast-stop-54C5LRSS.js.map +1 -0
- package/dist/screenshot-HOAKR7P7.js +68 -0
- package/dist/screenshot-HOAKR7P7.js.map +1 -0
- package/dist/scroll-IAOO5COY.js +84 -0
- package/dist/scroll-IAOO5COY.js.map +1 -0
- package/dist/scroll-into-view-RKWSLAPH.js +71 -0
- package/dist/scroll-into-view-RKWSLAPH.js.map +1 -0
- package/dist/select-IGD3T6X4.js +86 -0
- package/dist/select-IGD3T6X4.js.map +1 -0
- package/dist/serve-7X4INUCU.js +498 -0
- package/dist/serve-7X4INUCU.js.map +1 -0
- package/dist/shopping-FC6DRW76.js +273 -0
- package/dist/shopping-FC6DRW76.js.map +1 -0
- package/dist/skill-lifecycle-5UAZGKSN.js +89 -0
- package/dist/skill-lifecycle-5UAZGKSN.js.map +1 -0
- package/dist/skills-NSXDX6YM.js +26 -0
- package/dist/skills-NSXDX6YM.js.map +1 -0
- package/dist/snapshot-X22GG324.js +113 -0
- package/dist/snapshot-X22GG324.js.map +1 -0
- package/dist/status-SP55LMNW.js +132 -0
- package/dist/status-SP55LMNW.js.map +1 -0
- package/dist/status-VH2WXIDG.js +35 -0
- package/dist/status-VH2WXIDG.js.map +1 -0
- package/dist/status-capabilities-YBERLRRA.js +57 -0
- package/dist/status-capabilities-YBERLRRA.js.map +1 -0
- package/dist/text-6TB5WNLI.js +84 -0
- package/dist/text-6TB5WNLI.js.map +1 -0
- package/dist/tools/macro_resolve.d.ts.map +1 -1
- package/dist/type-3UI3TQH3.js +94 -0
- package/dist/type-3UI3TQH3.js.map +1 -0
- package/dist/uncheck-5L3D2D4U.js +71 -0
- package/dist/uncheck-5L3D2D4U.js.map +1 -0
- package/dist/uninstall-KYKGJAX7.js +91 -0
- package/dist/uninstall-KYKGJAX7.js.map +1 -0
- package/dist/update-SMXPYGXS.js +305 -0
- package/dist/update-SMXPYGXS.js.map +1 -0
- package/dist/update-skill-modes-BVX7IVMW.js +38 -0
- package/dist/update-skill-modes-BVX7IVMW.js.map +1 -0
- package/dist/upload-YG4J2EMI.js +56 -0
- package/dist/upload-YG4J2EMI.js.map +1 -0
- package/dist/use-V3LGFP3K.js +63 -0
- package/dist/use-V3LGFP3K.js.map +1 -0
- package/dist/value-3247D57X.js +71 -0
- package/dist/value-3247D57X.js.map +1 -0
- package/dist/visible-A7HEV36U.js +71 -0
- package/dist/visible-A7HEV36U.js.map +1 -0
- package/dist/wait-UZPP4Y4R.js +109 -0
- package/dist/wait-UZPP4Y4R.js.map +1 -0
- package/dist/windows-76TR3AIP.js +37 -0
- package/dist/windows-76TR3AIP.js.map +1 -0
- package/extension/dist/background.js +99 -22
- package/extension/dist/ops/ops-runtime.js +85 -7
- package/extension/dist/ops/ops-session-store.js +3 -0
- package/extension/dist/ops/target-session-coordinator.js +3 -0
- package/extension/dist/services/CDPRouter.js +9 -0
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
- package/skills/opendevbrowser-best-practices/SKILL.md +8 -6
- package/skills/opendevbrowser-best-practices/artifacts/skill-runtime-surface-matrix.md +1 -1
- package/skills/opendevbrowser-best-practices/scripts/odb-workflow.sh +3 -2
- package/skills/opendevbrowser-best-practices/scripts/validator-fixture-cli.sh +39 -2
- package/skills/opendevbrowser-research/SKILL.md +64 -12
- package/skills/opendevbrowser-research/artifacts/research-workflows.md +56 -19
- package/skills/opendevbrowser-research/assets/templates/compact.md +31 -5
- package/skills/opendevbrowser-research/assets/templates/context.json +52 -1
- package/skills/opendevbrowser-research/assets/templates/report.md +57 -4
- package/skills/opendevbrowser-research/examples/sample-input.json +1 -1
- package/skills/opendevbrowser-research/examples/sample-output.md +27 -2
- package/skills/opendevbrowser-research/scripts/run-research.sh +2 -6
- package/skills/opendevbrowser-research/scripts/validate-skill-assets.sh +115 -1
- package/dist/chunk-I5ZCOZZV.js.map +0 -1
- package/dist/chunk-QVWOPIZJ.js.map +0 -1
- package/dist/chunk-T3VVHJTK.js.map +0 -1
- /package/dist/{providers-QF2RFB4J.js.map → chunk-RJNI3BHT.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/dom/visible.ts"],"sourcesContent":["import type { ParsedArgs } from \"../../args\";\nimport { callDaemon } from \"../../client\";\nimport { createUsageError } from \"../../errors\";\nimport { parseOptionalStringFlag } from \"../../utils/parse\";\n\nfunction parseDomVisibleArgs(rawArgs: string[]): { sessionId?: string; ref?: string } {\n const parsed: { sessionId?: string; ref?: string } = {};\n for (let i = 0; i < rawArgs.length; i += 1) {\n const arg = rawArgs[i];\n if (arg === \"--session-id\") {\n const value = rawArgs[i + 1];\n if (!value) throw createUsageError(\"Missing value for --session-id\");\n parsed.sessionId = value;\n i += 1;\n continue;\n }\n if (arg?.startsWith(\"--session-id=\")) {\n parsed.sessionId = arg.split(\"=\", 2)[1];\n continue;\n }\n if (arg === \"--ref\") {\n const value = rawArgs[i + 1];\n if (!value) throw createUsageError(\"Missing value for --ref\");\n parsed.ref = value;\n i += 1;\n continue;\n }\n if (arg?.startsWith(\"--ref=\")) {\n parsed.ref = arg.split(\"=\", 2)[1];\n continue;\n }\n }\n return parsed;\n}\n\nexport async function runDomVisible(args: ParsedArgs) {\n const { sessionId, ref } = parseDomVisibleArgs(args.rawArgs);\n const targetId = parseOptionalStringFlag(args.rawArgs, \"--target-id\");\n if (!sessionId) throw createUsageError(\"Missing --session-id\");\n if (!ref) throw createUsageError(\"Missing --ref\");\n const result = await callDaemon(\"dom.isVisible\", {\n sessionId,\n ref,\n ...(typeof targetId === \"string\" ? { targetId } : {})\n });\n return { success: true, message: \"Visibility checked.\", data: result };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,SAAS,oBAAoB,SAAyD;AACpF,QAAM,SAA+C,CAAC;AACtD,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,GAAG;AAC1C,UAAM,MAAM,QAAQ,CAAC;AACrB,QAAI,QAAQ,gBAAgB;AAC1B,YAAM,QAAQ,QAAQ,IAAI,CAAC;AAC3B,UAAI,CAAC,MAAO,OAAM,iBAAiB,gCAAgC;AACnE,aAAO,YAAY;AACnB,WAAK;AACL;AAAA,IACF;AACA,QAAI,KAAK,WAAW,eAAe,GAAG;AACpC,aAAO,YAAY,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;AACtC;AAAA,IACF;AACA,QAAI,QAAQ,SAAS;AACnB,YAAM,QAAQ,QAAQ,IAAI,CAAC;AAC3B,UAAI,CAAC,MAAO,OAAM,iBAAiB,yBAAyB;AAC5D,aAAO,MAAM;AACb,WAAK;AACL;AAAA,IACF;AACA,QAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,aAAO,MAAM,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;AAChC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,cAAc,MAAkB;AACpD,QAAM,EAAE,WAAW,IAAI,IAAI,oBAAoB,KAAK,OAAO;AAC3D,QAAM,WAAW,wBAAwB,KAAK,SAAS,aAAa;AACpE,MAAI,CAAC,UAAW,OAAM,iBAAiB,sBAAsB;AAC7D,MAAI,CAAC,IAAK,OAAM,iBAAiB,eAAe;AAChD,QAAM,SAAS,MAAM,WAAW,iBAAiB;AAAA,IAC/C;AAAA,IACA;AAAA,IACA,GAAI,OAAO,aAAa,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,EACrD,CAAC;AACD,SAAO,EAAE,SAAS,MAAM,SAAS,uBAAuB,MAAM,OAAO;AACvE;","names":[]}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import "./chunk-RJNI3BHT.js";
|
|
2
|
+
import {
|
|
3
|
+
parseNumberFlag,
|
|
4
|
+
parseOptionalStringFlag
|
|
5
|
+
} from "./chunk-RPXWUCQQ.js";
|
|
6
|
+
import {
|
|
7
|
+
callDaemon
|
|
8
|
+
} from "./chunk-OYNLAZQU.js";
|
|
9
|
+
import "./chunk-LBPELU7L.js";
|
|
10
|
+
import "./chunk-SXAGSEKZ.js";
|
|
11
|
+
import "./chunk-MX3NFLCE.js";
|
|
12
|
+
import "./chunk-ASMHEEKY.js";
|
|
13
|
+
import {
|
|
14
|
+
createUsageError
|
|
15
|
+
} from "./chunk-IPE7TF2P.js";
|
|
16
|
+
import "./chunk-STGGGVYT.js";
|
|
17
|
+
import "./chunk-3ILXPKSJ.js";
|
|
18
|
+
import "./chunk-TBUCZX4A.js";
|
|
19
|
+
import "./chunk-Y2KL55OG.js";
|
|
20
|
+
import "./chunk-5SWZDVOW.js";
|
|
21
|
+
import "./chunk-S6S2UP6U.js";
|
|
22
|
+
import "./chunk-S5KZQJJI.js";
|
|
23
|
+
import "./chunk-KZ2IXVQT.js";
|
|
24
|
+
import "./chunk-WHQZBUNY.js";
|
|
25
|
+
import "./chunk-FUSXMW3G.js";
|
|
26
|
+
|
|
27
|
+
// src/cli/commands/nav/wait.ts
|
|
28
|
+
function parseWaitArgs(rawArgs) {
|
|
29
|
+
const parsed = {};
|
|
30
|
+
for (let i = 0; i < rawArgs.length; i += 1) {
|
|
31
|
+
const arg = rawArgs[i];
|
|
32
|
+
if (arg === "--session-id") {
|
|
33
|
+
const value = rawArgs[i + 1];
|
|
34
|
+
if (!value) throw createUsageError("Missing value for --session-id");
|
|
35
|
+
parsed.sessionId = value;
|
|
36
|
+
i += 1;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (arg?.startsWith("--session-id=")) {
|
|
40
|
+
parsed.sessionId = arg.split("=", 2)[1];
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (arg === "--ref") {
|
|
44
|
+
const value = rawArgs[i + 1];
|
|
45
|
+
if (!value) throw createUsageError("Missing value for --ref");
|
|
46
|
+
parsed.ref = value;
|
|
47
|
+
i += 1;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (arg?.startsWith("--ref=")) {
|
|
51
|
+
parsed.ref = arg.split("=", 2)[1];
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (arg === "--state") {
|
|
55
|
+
const value = rawArgs[i + 1];
|
|
56
|
+
if (!value) throw createUsageError("Missing value for --state");
|
|
57
|
+
parsed.state = value;
|
|
58
|
+
i += 1;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (arg?.startsWith("--state=")) {
|
|
62
|
+
parsed.state = arg.split("=", 2)[1];
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (arg === "--until") {
|
|
66
|
+
const value = rawArgs[i + 1];
|
|
67
|
+
if (!value) throw createUsageError("Missing value for --until");
|
|
68
|
+
parsed.until = value;
|
|
69
|
+
i += 1;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (arg?.startsWith("--until=")) {
|
|
73
|
+
parsed.until = arg.split("=", 2)[1];
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (arg === "--timeout-ms") {
|
|
77
|
+
const value = rawArgs[i + 1];
|
|
78
|
+
if (!value) throw createUsageError("Missing value for --timeout-ms");
|
|
79
|
+
parsed.timeoutMs = parseNumberFlag(value, "--timeout-ms", { min: 1 });
|
|
80
|
+
i += 1;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (arg?.startsWith("--timeout-ms=")) {
|
|
84
|
+
const value = arg.split("=", 2)[1];
|
|
85
|
+
if (!value) throw createUsageError("Missing value for --timeout-ms");
|
|
86
|
+
parsed.timeoutMs = parseNumberFlag(value, "--timeout-ms", { min: 1 });
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return parsed;
|
|
91
|
+
}
|
|
92
|
+
async function runWait(args) {
|
|
93
|
+
const { sessionId, ref, state, until, timeoutMs } = parseWaitArgs(args.rawArgs);
|
|
94
|
+
const targetId = parseOptionalStringFlag(args.rawArgs, "--target-id");
|
|
95
|
+
if (!sessionId) throw createUsageError("Missing --session-id");
|
|
96
|
+
const result = await callDaemon("nav.wait", {
|
|
97
|
+
sessionId,
|
|
98
|
+
ref,
|
|
99
|
+
state,
|
|
100
|
+
until,
|
|
101
|
+
timeoutMs,
|
|
102
|
+
...typeof targetId === "string" ? { targetId } : {}
|
|
103
|
+
});
|
|
104
|
+
return { success: true, message: "Wait complete.", data: result };
|
|
105
|
+
}
|
|
106
|
+
export {
|
|
107
|
+
runWait
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=wait-UZPP4Y4R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/nav/wait.ts"],"sourcesContent":["import type { ParsedArgs } from \"../../args\";\nimport { callDaemon } from \"../../client\";\nimport { createUsageError } from \"../../errors\";\nimport { parseNumberFlag, parseOptionalStringFlag } from \"../../utils/parse\";\n\nfunction parseWaitArgs(rawArgs: string[]): { sessionId?: string; ref?: string; state?: string; until?: string; timeoutMs?: number } {\n const parsed: { sessionId?: string; ref?: string; state?: string; until?: string; timeoutMs?: number } = {};\n for (let i = 0; i < rawArgs.length; i += 1) {\n const arg = rawArgs[i];\n if (arg === \"--session-id\") {\n const value = rawArgs[i + 1];\n if (!value) throw createUsageError(\"Missing value for --session-id\");\n parsed.sessionId = value;\n i += 1;\n continue;\n }\n if (arg?.startsWith(\"--session-id=\")) {\n parsed.sessionId = arg.split(\"=\", 2)[1];\n continue;\n }\n if (arg === \"--ref\") {\n const value = rawArgs[i + 1];\n if (!value) throw createUsageError(\"Missing value for --ref\");\n parsed.ref = value;\n i += 1;\n continue;\n }\n if (arg?.startsWith(\"--ref=\")) {\n parsed.ref = arg.split(\"=\", 2)[1];\n continue;\n }\n if (arg === \"--state\") {\n const value = rawArgs[i + 1];\n if (!value) throw createUsageError(\"Missing value for --state\");\n parsed.state = value;\n i += 1;\n continue;\n }\n if (arg?.startsWith(\"--state=\")) {\n parsed.state = arg.split(\"=\", 2)[1];\n continue;\n }\n if (arg === \"--until\") {\n const value = rawArgs[i + 1];\n if (!value) throw createUsageError(\"Missing value for --until\");\n parsed.until = value;\n i += 1;\n continue;\n }\n if (arg?.startsWith(\"--until=\")) {\n parsed.until = arg.split(\"=\", 2)[1];\n continue;\n }\n if (arg === \"--timeout-ms\") {\n const value = rawArgs[i + 1];\n if (!value) throw createUsageError(\"Missing value for --timeout-ms\");\n parsed.timeoutMs = parseNumberFlag(value, \"--timeout-ms\", { min: 1 });\n i += 1;\n continue;\n }\n if (arg?.startsWith(\"--timeout-ms=\")) {\n const value = arg.split(\"=\", 2)[1];\n if (!value) throw createUsageError(\"Missing value for --timeout-ms\");\n parsed.timeoutMs = parseNumberFlag(value, \"--timeout-ms\", { min: 1 });\n continue;\n }\n }\n return parsed;\n}\n\nexport async function runWait(args: ParsedArgs) {\n const { sessionId, ref, state, until, timeoutMs } = parseWaitArgs(args.rawArgs);\n const targetId = parseOptionalStringFlag(args.rawArgs, \"--target-id\");\n if (!sessionId) throw createUsageError(\"Missing --session-id\");\n const result = await callDaemon(\"nav.wait\", {\n sessionId,\n ref,\n state,\n until,\n timeoutMs,\n ...(typeof targetId === \"string\" ? { targetId } : {})\n });\n return { success: true, message: \"Wait complete.\", data: result };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,SAAS,cAAc,SAA6G;AAClI,QAAM,SAAmG,CAAC;AAC1G,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,GAAG;AAC1C,UAAM,MAAM,QAAQ,CAAC;AACrB,QAAI,QAAQ,gBAAgB;AAC1B,YAAM,QAAQ,QAAQ,IAAI,CAAC;AAC3B,UAAI,CAAC,MAAO,OAAM,iBAAiB,gCAAgC;AACnE,aAAO,YAAY;AACnB,WAAK;AACL;AAAA,IACF;AACA,QAAI,KAAK,WAAW,eAAe,GAAG;AACpC,aAAO,YAAY,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;AACtC;AAAA,IACF;AACA,QAAI,QAAQ,SAAS;AACnB,YAAM,QAAQ,QAAQ,IAAI,CAAC;AAC3B,UAAI,CAAC,MAAO,OAAM,iBAAiB,yBAAyB;AAC5D,aAAO,MAAM;AACb,WAAK;AACL;AAAA,IACF;AACA,QAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,aAAO,MAAM,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;AAChC;AAAA,IACF;AACA,QAAI,QAAQ,WAAW;AACrB,YAAM,QAAQ,QAAQ,IAAI,CAAC;AAC3B,UAAI,CAAC,MAAO,OAAM,iBAAiB,2BAA2B;AAC9D,aAAO,QAAQ;AACf,WAAK;AACL;AAAA,IACF;AACA,QAAI,KAAK,WAAW,UAAU,GAAG;AAC/B,aAAO,QAAQ,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;AAClC;AAAA,IACF;AACA,QAAI,QAAQ,WAAW;AACrB,YAAM,QAAQ,QAAQ,IAAI,CAAC;AAC3B,UAAI,CAAC,MAAO,OAAM,iBAAiB,2BAA2B;AAC9D,aAAO,QAAQ;AACf,WAAK;AACL;AAAA,IACF;AACA,QAAI,KAAK,WAAW,UAAU,GAAG;AAC/B,aAAO,QAAQ,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;AAClC;AAAA,IACF;AACA,QAAI,QAAQ,gBAAgB;AAC1B,YAAM,QAAQ,QAAQ,IAAI,CAAC;AAC3B,UAAI,CAAC,MAAO,OAAM,iBAAiB,gCAAgC;AACnE,aAAO,YAAY,gBAAgB,OAAO,gBAAgB,EAAE,KAAK,EAAE,CAAC;AACpE,WAAK;AACL;AAAA,IACF;AACA,QAAI,KAAK,WAAW,eAAe,GAAG;AACpC,YAAM,QAAQ,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;AACjC,UAAI,CAAC,MAAO,OAAM,iBAAiB,gCAAgC;AACnE,aAAO,YAAY,gBAAgB,OAAO,gBAAgB,EAAE,KAAK,EAAE,CAAC;AACpE;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,QAAQ,MAAkB;AAC9C,QAAM,EAAE,WAAW,KAAK,OAAO,OAAO,UAAU,IAAI,cAAc,KAAK,OAAO;AAC9E,QAAM,WAAW,wBAAwB,KAAK,SAAS,aAAa;AACpE,MAAI,CAAC,UAAW,OAAM,iBAAiB,sBAAsB;AAC7D,QAAM,SAAS,MAAM,WAAW,YAAY;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,OAAO,aAAa,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,EACrD,CAAC;AACD,SAAO,EAAE,SAAS,MAAM,SAAS,kBAAkB,MAAM,OAAO;AAClE;","names":[]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
callDesktopCommand,
|
|
3
|
+
desktopCommandResult,
|
|
4
|
+
parseDesktopReasonArgs
|
|
5
|
+
} from "./chunk-2CG4SW3E.js";
|
|
6
|
+
import "./chunk-RJNI3BHT.js";
|
|
7
|
+
import "./chunk-RPXWUCQQ.js";
|
|
8
|
+
import "./chunk-OW5HMYMI.js";
|
|
9
|
+
import "./chunk-OYNLAZQU.js";
|
|
10
|
+
import "./chunk-LBPELU7L.js";
|
|
11
|
+
import "./chunk-SXAGSEKZ.js";
|
|
12
|
+
import "./chunk-MX3NFLCE.js";
|
|
13
|
+
import "./chunk-ASMHEEKY.js";
|
|
14
|
+
import "./chunk-IPE7TF2P.js";
|
|
15
|
+
import "./chunk-STGGGVYT.js";
|
|
16
|
+
import "./chunk-3ILXPKSJ.js";
|
|
17
|
+
import "./chunk-TBUCZX4A.js";
|
|
18
|
+
import "./chunk-Y2KL55OG.js";
|
|
19
|
+
import "./chunk-5SWZDVOW.js";
|
|
20
|
+
import "./chunk-S6S2UP6U.js";
|
|
21
|
+
import "./chunk-S5KZQJJI.js";
|
|
22
|
+
import "./chunk-KZ2IXVQT.js";
|
|
23
|
+
import "./chunk-WHQZBUNY.js";
|
|
24
|
+
import "./chunk-FUSXMW3G.js";
|
|
25
|
+
|
|
26
|
+
// src/cli/commands/desktop/windows.ts
|
|
27
|
+
async function runDesktopWindows(args) {
|
|
28
|
+
const { reason, timeoutMs } = parseDesktopReasonArgs(args.rawArgs);
|
|
29
|
+
const result = await callDesktopCommand("desktop.windows.list", {
|
|
30
|
+
...typeof reason === "string" ? { reason } : {}
|
|
31
|
+
}, timeoutMs);
|
|
32
|
+
return desktopCommandResult("Desktop windows listed.", result);
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
runDesktopWindows
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=windows-76TR3AIP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/desktop/windows.ts"],"sourcesContent":["import type { ParsedArgs } from \"../../args\";\nimport { callDesktopCommand, desktopCommandResult, parseDesktopReasonArgs } from \"./shared\";\n\nexport async function runDesktopWindows(args: ParsedArgs) {\n const { reason, timeoutMs } = parseDesktopReasonArgs(args.rawArgs);\n const result = await callDesktopCommand(\"desktop.windows.list\", {\n ...(typeof reason === \"string\" ? { reason } : {})\n }, timeoutMs);\n return desktopCommandResult(\"Desktop windows listed.\", result);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,eAAsB,kBAAkB,MAAkB;AACxD,QAAM,EAAE,QAAQ,UAAU,IAAI,uBAAuB,KAAK,OAAO;AACjE,QAAM,SAAS,MAAM,mBAAmB,wBAAwB;AAAA,IAC9D,GAAI,OAAO,WAAW,WAAW,EAAE,OAAO,IAAI,CAAC;AAAA,EACjD,GAAG,SAAS;AACZ,SAAO,qBAAqB,2BAA2B,MAAM;AAC/D;","names":[]}
|
|
@@ -36,8 +36,11 @@ let retryScheduled = false;
|
|
|
36
36
|
let retryDelayMs = 5000;
|
|
37
37
|
let autoConnectEnabled = DEFAULT_AUTO_CONNECT;
|
|
38
38
|
let nativeEnabled = DEFAULT_NATIVE_ENABLED;
|
|
39
|
+
let lastRelayCleanupStatus = null;
|
|
39
40
|
const RETRY_ALARM_NAME = "opendevbrowser-auto-connect";
|
|
41
|
+
const WATCHDOG_ALARM_NAME = "opendevbrowser-auto-connect-watchdog";
|
|
40
42
|
const RETRY_MAX_MS = 60_000;
|
|
43
|
+
const WATCHDOG_PERIOD_MINUTES = 1;
|
|
41
44
|
const ANNOTATION_CONTENT_SCRIPT = "dist/annotate-content.js";
|
|
42
45
|
const ANNOTATION_CONTENT_STYLE = "dist/annotate-content.css";
|
|
43
46
|
const ANNOTATION_MAX_PAYLOAD_BYTES = 10 * 1024 * 1024;
|
|
@@ -92,21 +95,27 @@ const getEffectiveStatus = () => {
|
|
|
92
95
|
return "disconnected";
|
|
93
96
|
};
|
|
94
97
|
const hasReadyRelayHandshake = (health) => {
|
|
95
|
-
return health?.extensionConnected === true && health.extensionHandshakeComplete === true;
|
|
98
|
+
return health?.ok !== false && health?.extensionConnected === true && health.extensionHandshakeComplete === true;
|
|
96
99
|
};
|
|
97
100
|
const deriveBackgroundStatus = (relayStatus, nativeHealth, relayHealth, reconnectSuppressed) => {
|
|
98
101
|
if (relayStatus === "connected") {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
+
if (relayHealth?.ok === false) {
|
|
103
|
+
return "disconnected";
|
|
104
|
+
}
|
|
102
105
|
return "connected";
|
|
103
106
|
}
|
|
104
107
|
if (reconnectSuppressed) {
|
|
105
108
|
return "disconnected";
|
|
106
109
|
}
|
|
110
|
+
if (nativeHealth?.status === "connected") {
|
|
111
|
+
return "connected";
|
|
112
|
+
}
|
|
107
113
|
return hasReadyRelayHandshake(relayHealth) ? "connected" : "disconnected";
|
|
108
114
|
};
|
|
109
115
|
const deriveBadgeTone = (status, relayHealth) => {
|
|
116
|
+
if (relayHealth?.ok === false) {
|
|
117
|
+
return status === "connected" ? "warning" : "disconnected";
|
|
118
|
+
}
|
|
110
119
|
if (status === "connected") {
|
|
111
120
|
return "connected";
|
|
112
121
|
}
|
|
@@ -139,9 +148,9 @@ const buildStatusMessage = async () => {
|
|
|
139
148
|
note = `Connected to 127.0.0.1:${identity.relayPort}`;
|
|
140
149
|
}
|
|
141
150
|
relayHealth = await connection.relayHealthCheck();
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
151
|
+
if (relayHealth?.ok === false) {
|
|
152
|
+
note = statusNoteOverride ?? buildRelayHealthNote(relayHealth);
|
|
153
|
+
}
|
|
145
154
|
}
|
|
146
155
|
else {
|
|
147
156
|
const stored = await new Promise((resolve) => {
|
|
@@ -149,9 +158,16 @@ const buildStatusMessage = async () => {
|
|
|
149
158
|
});
|
|
150
159
|
const port = parsePort(stored.relayPort) ?? DEFAULT_RELAY_PORT;
|
|
151
160
|
relayHealth = await fetchRelayHealth(port);
|
|
152
|
-
if (
|
|
161
|
+
if (reconnectSuppressed) {
|
|
162
|
+
note = statusNoteOverride
|
|
163
|
+
?? "Another extension client took over the relay connection. This client will stay disconnected until you reconnect it explicitly.";
|
|
164
|
+
}
|
|
165
|
+
else if (hasReadyRelayHandshake(relayHealth)) {
|
|
153
166
|
note = `Connected to 127.0.0.1:${port}`;
|
|
154
167
|
}
|
|
168
|
+
else if (nativeHealth?.status === "connected") {
|
|
169
|
+
note = "Connected via native host.";
|
|
170
|
+
}
|
|
155
171
|
else {
|
|
156
172
|
note = statusNoteOverride ?? buildRelayHealthNote(relayHealth);
|
|
157
173
|
}
|
|
@@ -230,6 +246,8 @@ const buildRelayHealthNote = (health) => {
|
|
|
230
246
|
return "Canvas channel disconnected. Reopen the design canvas command and retry.";
|
|
231
247
|
case "cdp_disconnected":
|
|
232
248
|
return "No CDP clients connected. Start a session and retry.";
|
|
249
|
+
case "relay_dirty":
|
|
250
|
+
return "Relay has active CDP, annotation, canvas clients, or ops-owned targets. Disconnect the current run and retry.";
|
|
233
251
|
case "relay_down":
|
|
234
252
|
return "Relay down. Start the daemon and retry.";
|
|
235
253
|
default:
|
|
@@ -262,6 +280,16 @@ const clearRetry = () => {
|
|
|
262
280
|
chrome.alarms.clear(RETRY_ALARM_NAME);
|
|
263
281
|
}
|
|
264
282
|
};
|
|
283
|
+
const scheduleWatchdog = () => {
|
|
284
|
+
if (chrome.alarms?.create) {
|
|
285
|
+
chrome.alarms.create(WATCHDOG_ALARM_NAME, { periodInMinutes: WATCHDOG_PERIOD_MINUTES });
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
const clearWatchdog = () => {
|
|
289
|
+
if (chrome.alarms?.clear) {
|
|
290
|
+
chrome.alarms.clear(WATCHDOG_ALARM_NAME);
|
|
291
|
+
}
|
|
292
|
+
};
|
|
265
293
|
const scheduleRetry = () => {
|
|
266
294
|
if (retryScheduled) {
|
|
267
295
|
return;
|
|
@@ -357,24 +385,37 @@ const fetchRelayHealth = async (port) => {
|
|
|
357
385
|
}
|
|
358
386
|
const data = await response.json();
|
|
359
387
|
if (data.health && typeof data.health === "object") {
|
|
360
|
-
|
|
388
|
+
const health = data.health;
|
|
389
|
+
return typeof health.opsOwnedTargetCount === "number" && Number.isFinite(health.opsOwnedTargetCount)
|
|
390
|
+
? health
|
|
391
|
+
: null;
|
|
361
392
|
}
|
|
362
393
|
const extensionConnected = data.extensionConnected === true;
|
|
363
394
|
const handshake = data.extensionHandshakeComplete === true;
|
|
364
395
|
const cdpConnected = data.cdpConnected === true;
|
|
365
396
|
const annotationConnected = data.annotationConnected === true;
|
|
366
397
|
const opsConnected = data.opsConnected === true;
|
|
398
|
+
const opsOwnedTargetCount = typeof data.opsOwnedTargetCount === "number" && Number.isFinite(data.opsOwnedTargetCount)
|
|
399
|
+
? data.opsOwnedTargetCount
|
|
400
|
+
: null;
|
|
401
|
+
if (opsOwnedTargetCount === null || opsOwnedTargetCount < 0) {
|
|
402
|
+
return null;
|
|
403
|
+
}
|
|
367
404
|
const canvasConnected = data.canvasConnected === true;
|
|
368
405
|
const pairingRequired = data.pairingRequired === true;
|
|
369
|
-
const
|
|
406
|
+
const dirty = cdpConnected || annotationConnected || canvasConnected || opsOwnedTargetCount > 0;
|
|
407
|
+
const ok = extensionConnected && handshake && !dirty;
|
|
370
408
|
return {
|
|
371
409
|
ok,
|
|
372
|
-
reason: ok
|
|
410
|
+
reason: ok
|
|
411
|
+
? "ok"
|
|
412
|
+
: (dirty ? "relay_dirty" : (extensionConnected ? "handshake_incomplete" : "extension_disconnected")),
|
|
373
413
|
extensionConnected,
|
|
374
414
|
extensionHandshakeComplete: handshake,
|
|
375
415
|
cdpConnected,
|
|
376
416
|
annotationConnected,
|
|
377
417
|
opsConnected,
|
|
418
|
+
opsOwnedTargetCount,
|
|
378
419
|
canvasConnected,
|
|
379
420
|
pairingRequired
|
|
380
421
|
};
|
|
@@ -384,6 +425,10 @@ const fetchRelayHealth = async (port) => {
|
|
|
384
425
|
return null;
|
|
385
426
|
}
|
|
386
427
|
};
|
|
428
|
+
const relayHasActiveExtensionClient = async (storedRelayPort) => {
|
|
429
|
+
const storedHealth = await fetchRelayHealth(storedRelayPort);
|
|
430
|
+
return hasReadyRelayHandshake(storedHealth);
|
|
431
|
+
};
|
|
387
432
|
const sendAnnotationResponse = (payload, transport = "relay") => {
|
|
388
433
|
if (transport === "popup") {
|
|
389
434
|
return;
|
|
@@ -1292,11 +1337,8 @@ const fetchTokenFromPlugin = async (port) => {
|
|
|
1292
1337
|
return null;
|
|
1293
1338
|
}
|
|
1294
1339
|
};
|
|
1295
|
-
const
|
|
1340
|
+
const clearStoredRelayCredentials = async () => {
|
|
1296
1341
|
await setStorage({
|
|
1297
|
-
relayPort: null,
|
|
1298
|
-
relayInstanceId: null,
|
|
1299
|
-
relayEpoch: null,
|
|
1300
1342
|
pairingToken: null,
|
|
1301
1343
|
tokenEpoch: null
|
|
1302
1344
|
});
|
|
@@ -1319,10 +1361,17 @@ const attemptAutoConnect = async () => {
|
|
|
1319
1361
|
});
|
|
1320
1362
|
const autoConnect = typeof data.autoConnect === "boolean" ? data.autoConnect : DEFAULT_AUTO_CONNECT;
|
|
1321
1363
|
autoConnectEnabled = autoConnect;
|
|
1322
|
-
if (!autoConnect || connection.getStatus() === "connected"
|
|
1364
|
+
if (!autoConnect || connection.getStatus() === "connected") {
|
|
1323
1365
|
clearRetry();
|
|
1366
|
+
if (!autoConnect) {
|
|
1367
|
+
clearWatchdog();
|
|
1368
|
+
}
|
|
1369
|
+
else {
|
|
1370
|
+
scheduleWatchdog();
|
|
1371
|
+
}
|
|
1324
1372
|
return;
|
|
1325
1373
|
}
|
|
1374
|
+
scheduleWatchdog();
|
|
1326
1375
|
const autoPair = typeof data.autoPair === "boolean" ? data.autoPair : DEFAULT_AUTO_PAIR;
|
|
1327
1376
|
const pairingEnabled = typeof data.pairingEnabled === "boolean" ? data.pairingEnabled : DEFAULT_PAIRING_ENABLED;
|
|
1328
1377
|
const storedRelayPort = parsePort(data.relayPort) ?? DEFAULT_RELAY_PORT;
|
|
@@ -1331,6 +1380,15 @@ const attemptAutoConnect = async () => {
|
|
|
1331
1380
|
if (typeof data.nativeEnabled !== "boolean") {
|
|
1332
1381
|
await setStorage({ nativeEnabled });
|
|
1333
1382
|
}
|
|
1383
|
+
if (connection.isReconnectSuppressed()) {
|
|
1384
|
+
const activeExtensionClient = await relayHasActiveExtensionClient(storedRelayPort);
|
|
1385
|
+
if (activeExtensionClient) {
|
|
1386
|
+
setStatusNoteOverride("Another extension client is connected. Retrying when the relay is free.");
|
|
1387
|
+
scheduleRetry();
|
|
1388
|
+
return;
|
|
1389
|
+
}
|
|
1390
|
+
setStatusNoteOverride("Relay no longer has an active extension client. Reconnecting.");
|
|
1391
|
+
}
|
|
1334
1392
|
if (autoPair && pairingEnabled) {
|
|
1335
1393
|
let config = await fetchRelayConfig(DEFAULT_DISCOVERY_PORT);
|
|
1336
1394
|
if (!config && storedRelayPort !== DEFAULT_DISCOVERY_PORT) {
|
|
@@ -1355,12 +1413,12 @@ const attemptAutoConnect = async () => {
|
|
|
1355
1413
|
});
|
|
1356
1414
|
}
|
|
1357
1415
|
if (hasEpoch && storedRelayEpoch !== null && storedRelayEpoch !== configEpoch) {
|
|
1358
|
-
await
|
|
1416
|
+
await clearStoredRelayCredentials();
|
|
1359
1417
|
storedPairingToken = null;
|
|
1360
1418
|
setStatusNoteOverride("Relay restarted. Refresh the connection.");
|
|
1361
1419
|
}
|
|
1362
1420
|
if (config.instanceId && storedRelayInstanceId && config.instanceId !== storedRelayInstanceId) {
|
|
1363
|
-
await
|
|
1421
|
+
await clearStoredRelayCredentials();
|
|
1364
1422
|
storedPairingToken = null;
|
|
1365
1423
|
setStatusNoteOverride("Relay instance mismatch. Open the popup and click Connect.");
|
|
1366
1424
|
}
|
|
@@ -1428,6 +1486,8 @@ const autoConnect = async () => {
|
|
|
1428
1486
|
}
|
|
1429
1487
|
};
|
|
1430
1488
|
connection.onStatus((status) => {
|
|
1489
|
+
const shouldCleanupRelayDisconnect = status === "disconnected" && lastRelayCleanupStatus !== "disconnected";
|
|
1490
|
+
lastRelayCleanupStatus = status;
|
|
1431
1491
|
const effectiveStatus = status === "connected" ? "connected" : (nativeEnabled && nativePort.isConnected()) ? "connected" : "disconnected";
|
|
1432
1492
|
updateBadge(effectiveStatus);
|
|
1433
1493
|
void refreshBadgeFromBackgroundStatus();
|
|
@@ -1436,11 +1496,21 @@ connection.onStatus((status) => {
|
|
|
1436
1496
|
setStatusNoteOverride(null);
|
|
1437
1497
|
clearRetry();
|
|
1438
1498
|
}
|
|
1439
|
-
if (status === "disconnected"
|
|
1440
|
-
|
|
1441
|
-
|
|
1499
|
+
if (status === "disconnected") {
|
|
1500
|
+
if (shouldCleanupRelayDisconnect) {
|
|
1501
|
+
for (const session of annotationSessions.values()) {
|
|
1502
|
+
clearTimeout(session.timeoutId);
|
|
1503
|
+
}
|
|
1504
|
+
annotationSessions.clear();
|
|
1505
|
+
opsRuntime.handleRelayDisconnected();
|
|
1506
|
+
}
|
|
1507
|
+
if (nativePort.isConnected()) {
|
|
1508
|
+
return;
|
|
1509
|
+
}
|
|
1510
|
+
if (connection.isReconnectSuppressed() && autoConnectEnabled) {
|
|
1511
|
+
scheduleRetry();
|
|
1512
|
+
return;
|
|
1442
1513
|
}
|
|
1443
|
-
annotationSessions.clear();
|
|
1444
1514
|
if (connection.isReconnectSuppressed()) {
|
|
1445
1515
|
clearRetry();
|
|
1446
1516
|
return;
|
|
@@ -1469,6 +1539,11 @@ if (chrome.alarms?.onAlarm) {
|
|
|
1469
1539
|
logError("auto_connect.alarm", error, { code: "auto_connect_failed" });
|
|
1470
1540
|
});
|
|
1471
1541
|
}
|
|
1542
|
+
if (alarm.name === WATCHDOG_ALARM_NAME) {
|
|
1543
|
+
autoConnect().catch((error) => {
|
|
1544
|
+
logError("auto_connect.watchdog", error, { code: "auto_connect_failed" });
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1472
1547
|
});
|
|
1473
1548
|
}
|
|
1474
1549
|
if (chrome.commands?.onCommand) {
|
|
@@ -1531,12 +1606,14 @@ chrome.storage.onChanged.addListener((changes, area) => {
|
|
|
1531
1606
|
typeof changes.autoConnect.newValue === "boolean" ? changes.autoConnect.newValue : DEFAULT_AUTO_CONNECT;
|
|
1532
1607
|
}
|
|
1533
1608
|
if (changes.autoConnect?.newValue === true) {
|
|
1609
|
+
scheduleWatchdog();
|
|
1534
1610
|
autoConnect().catch((error) => {
|
|
1535
1611
|
logError("auto_connect.setting", error, { code: "auto_connect_failed" });
|
|
1536
1612
|
});
|
|
1537
1613
|
}
|
|
1538
1614
|
else if (changes.autoConnect?.newValue === false) {
|
|
1539
1615
|
clearRetry();
|
|
1616
|
+
clearWatchdog();
|
|
1540
1617
|
}
|
|
1541
1618
|
if (changes.pairingToken) {
|
|
1542
1619
|
autoConnect().catch((error) => {
|
|
@@ -13,7 +13,10 @@ const MAX_NETWORK_EVENTS = 300;
|
|
|
13
13
|
const SESSION_TTL_MS = 20_000;
|
|
14
14
|
const SCREENSHOT_TIMEOUT_MS = 8000;
|
|
15
15
|
const TAB_CLOSE_TIMEOUT_MS = 5000;
|
|
16
|
+
const OPS_SESSION_DETACH_TIMEOUT_MS = 3000;
|
|
16
17
|
const POPUP_ATTACH_RETRY_DELAY_MS = 100;
|
|
18
|
+
const ROOT_DETACH_VERIFY_DELAY_MS = 250;
|
|
19
|
+
const ROOT_DETACH_VERIFY_ATTEMPTS = 4;
|
|
17
20
|
const STALE_REF_ERROR_SUFFIX = "Take a new snapshot first.";
|
|
18
21
|
const DOM_OUTER_HTML_DECLARATION = `
|
|
19
22
|
function() {
|
|
@@ -305,6 +308,12 @@ export class OpsRuntime {
|
|
|
305
308
|
});
|
|
306
309
|
}
|
|
307
310
|
}
|
|
311
|
+
handleRelayDisconnected() {
|
|
312
|
+
this.cdp.markClientClosed();
|
|
313
|
+
for (const session of this.sessions.list()) {
|
|
314
|
+
void this.cleanupSession(session, "ops_session_expired");
|
|
315
|
+
}
|
|
316
|
+
}
|
|
308
317
|
handleHello(message) {
|
|
309
318
|
if (message.version !== OPS_PROTOCOL_VERSION) {
|
|
310
319
|
const error = {
|
|
@@ -2576,10 +2585,19 @@ export class OpsRuntime {
|
|
|
2576
2585
|
await this.cdp.setDiscoverTargetsEnabled?.(true);
|
|
2577
2586
|
}
|
|
2578
2587
|
catch (error) {
|
|
2588
|
+
if (isAttachBlockedError(error)) {
|
|
2589
|
+
return;
|
|
2590
|
+
}
|
|
2579
2591
|
logError("ops.discover_targets", error, {
|
|
2580
2592
|
code: "discover_targets_enable_failed",
|
|
2581
2593
|
extra: baseDetails
|
|
2582
2594
|
});
|
|
2595
|
+
if (baseDetails.strict) {
|
|
2596
|
+
throw this.decorateCdpFailure(error, {
|
|
2597
|
+
...baseDetails,
|
|
2598
|
+
enablementStage: "set_discover_targets"
|
|
2599
|
+
});
|
|
2600
|
+
}
|
|
2583
2601
|
}
|
|
2584
2602
|
}
|
|
2585
2603
|
async enableTargetDomainsOnDebuggee(debuggee, baseDetails) {
|
|
@@ -4006,7 +4024,7 @@ export class OpsRuntime {
|
|
|
4006
4024
|
}
|
|
4007
4025
|
throw new Error("Wait for selector timed out");
|
|
4008
4026
|
}
|
|
4009
|
-
cleanupSession(session, event) {
|
|
4027
|
+
async cleanupSession(session, event) {
|
|
4010
4028
|
this.clearClosingTimer(session.id);
|
|
4011
4029
|
const waiters = this.parallelWaiters.get(session.id);
|
|
4012
4030
|
if (waiters) {
|
|
@@ -4020,8 +4038,25 @@ export class OpsRuntime {
|
|
|
4020
4038
|
this.parallelWaiters.delete(session.id);
|
|
4021
4039
|
}
|
|
4022
4040
|
this.sessions.delete(session.id);
|
|
4023
|
-
|
|
4024
|
-
|
|
4041
|
+
const targets = Array.from(session.targets.values());
|
|
4042
|
+
try {
|
|
4043
|
+
const results = await withTimeout(Promise.allSettled(targets.map(async (target) => this.cdp.detachTab(target.tabId))), OPS_SESSION_DETACH_TIMEOUT_MS, "Ops session detach timed out");
|
|
4044
|
+
const failedTabIds = results.flatMap((result, index) => {
|
|
4045
|
+
const target = targets[index];
|
|
4046
|
+
return result.status === "rejected" && target ? [target.tabId] : [];
|
|
4047
|
+
});
|
|
4048
|
+
if (failedTabIds.length > 0) {
|
|
4049
|
+
logError("ops.session_detach", new Error("One or more ops session targets failed to detach"), {
|
|
4050
|
+
code: "session_detach_failed",
|
|
4051
|
+
extra: { sessionId: session.id, event, failedTabIds }
|
|
4052
|
+
});
|
|
4053
|
+
}
|
|
4054
|
+
}
|
|
4055
|
+
catch (error) {
|
|
4056
|
+
logError("ops.session_detach", error, {
|
|
4057
|
+
code: "session_detach_failed",
|
|
4058
|
+
extra: { sessionId: session.id, event }
|
|
4059
|
+
});
|
|
4025
4060
|
}
|
|
4026
4061
|
this.emitSessionEvent(session, event);
|
|
4027
4062
|
}
|
|
@@ -4036,7 +4071,7 @@ export class OpsRuntime {
|
|
|
4036
4071
|
if (!removedTarget)
|
|
4037
4072
|
return;
|
|
4038
4073
|
if (targetId === session.targetId || session.targets.size === 0) {
|
|
4039
|
-
this.cleanupSession(session, event);
|
|
4074
|
+
void this.cleanupSession(session, event);
|
|
4040
4075
|
}
|
|
4041
4076
|
}
|
|
4042
4077
|
async handleDebuggerDetachForTab(tabId) {
|
|
@@ -4044,7 +4079,8 @@ export class OpsRuntime {
|
|
|
4044
4079
|
if (!session)
|
|
4045
4080
|
return;
|
|
4046
4081
|
if (tabId === session.tabId) {
|
|
4047
|
-
// Root tab detach can be transient during child-target shutdown
|
|
4082
|
+
// Root tab detach can be transient during child-target shutdown, but it must not retain ownership forever.
|
|
4083
|
+
this.scheduleRootDebuggerDetachVerification(session.id, tabId);
|
|
4048
4084
|
return;
|
|
4049
4085
|
}
|
|
4050
4086
|
const targetId = this.sessions.getTargetIdByTabId(session.id, tabId);
|
|
@@ -4064,6 +4100,48 @@ export class OpsRuntime {
|
|
|
4064
4100
|
}
|
|
4065
4101
|
this.handleClosedTarget(tabId, "ops_session_closed");
|
|
4066
4102
|
}
|
|
4103
|
+
scheduleRootDebuggerDetachVerification(sessionId, tabId) {
|
|
4104
|
+
if (typeof this.cdp.getTabDebuggee !== "function") {
|
|
4105
|
+
return;
|
|
4106
|
+
}
|
|
4107
|
+
setTimeout(() => {
|
|
4108
|
+
void this.verifyRootDebuggerDetach(sessionId, tabId, ROOT_DETACH_VERIFY_ATTEMPTS);
|
|
4109
|
+
}, ROOT_DETACH_VERIFY_DELAY_MS);
|
|
4110
|
+
}
|
|
4111
|
+
async verifyRootDebuggerDetach(sessionId, tabId, attemptsRemaining) {
|
|
4112
|
+
const session = this.sessions.get(sessionId);
|
|
4113
|
+
if (!session || session.tabId !== tabId) {
|
|
4114
|
+
return;
|
|
4115
|
+
}
|
|
4116
|
+
if (this.isConcreteDebuggee(this.cdp.getTabDebuggee?.(tabId))) {
|
|
4117
|
+
return;
|
|
4118
|
+
}
|
|
4119
|
+
let liveTab = null;
|
|
4120
|
+
try {
|
|
4121
|
+
liveTab = await this.tabs.getTab(tabId);
|
|
4122
|
+
}
|
|
4123
|
+
catch {
|
|
4124
|
+
liveTab = null;
|
|
4125
|
+
}
|
|
4126
|
+
const current = this.sessions.get(sessionId);
|
|
4127
|
+
if (!current || current.tabId !== tabId) {
|
|
4128
|
+
return;
|
|
4129
|
+
}
|
|
4130
|
+
if (!liveTab) {
|
|
4131
|
+
void this.cleanupSession(current, "ops_session_closed");
|
|
4132
|
+
return;
|
|
4133
|
+
}
|
|
4134
|
+
if (this.isConcreteDebuggee(this.cdp.getTabDebuggee?.(tabId))) {
|
|
4135
|
+
return;
|
|
4136
|
+
}
|
|
4137
|
+
if (attemptsRemaining > 1) {
|
|
4138
|
+
setTimeout(() => {
|
|
4139
|
+
void this.verifyRootDebuggerDetach(sessionId, tabId, attemptsRemaining - 1);
|
|
4140
|
+
}, ROOT_DETACH_VERIFY_DELAY_MS);
|
|
4141
|
+
return;
|
|
4142
|
+
}
|
|
4143
|
+
void this.cleanupSession(current, "ops_session_closed");
|
|
4144
|
+
}
|
|
4067
4145
|
async closeTabBestEffort(tabId) {
|
|
4068
4146
|
try {
|
|
4069
4147
|
await withTimeout(this.tabs.closeTab(tabId), TAB_CLOSE_TIMEOUT_MS, "Ops tab close timed out");
|
|
@@ -4081,7 +4159,7 @@ export class OpsRuntime {
|
|
|
4081
4159
|
if (!session) {
|
|
4082
4160
|
return;
|
|
4083
4161
|
}
|
|
4084
|
-
this.cleanupSession(session, event);
|
|
4162
|
+
void this.cleanupSession(session, event);
|
|
4085
4163
|
}, 0);
|
|
4086
4164
|
}
|
|
4087
4165
|
sendResponse(message, payload) {
|
|
@@ -4159,7 +4237,7 @@ export class OpsRuntime {
|
|
|
4159
4237
|
this.closingTimers.delete(session.id);
|
|
4160
4238
|
const current = this.sessions.get(session.id);
|
|
4161
4239
|
if (current && current.state === "closing") {
|
|
4162
|
-
this.cleanupSession(current, "ops_session_expired");
|
|
4240
|
+
void this.cleanupSession(current, "ops_session_expired");
|
|
4163
4241
|
}
|
|
4164
4242
|
}, SESSION_TTL_MS);
|
|
4165
4243
|
this.closingTimers.set(session.id, timeoutId);
|
|
@@ -44,6 +44,9 @@ export class TargetSessionCoordinator {
|
|
|
44
44
|
listOwnedBy(clientId) {
|
|
45
45
|
return Array.from(this.sessions.values()).filter((session) => session.ownerClientId === clientId);
|
|
46
46
|
}
|
|
47
|
+
list() {
|
|
48
|
+
return Array.from(this.sessions.values());
|
|
49
|
+
}
|
|
47
50
|
delete(sessionId) {
|
|
48
51
|
const session = this.sessions.get(sessionId) ?? null;
|
|
49
52
|
if (!session) {
|
|
@@ -912,6 +912,9 @@ export class CDPRouter {
|
|
|
912
912
|
return;
|
|
913
913
|
}
|
|
914
914
|
catch (error) {
|
|
915
|
+
if (this.isExpectedDebuggerCleanupError(error)) {
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
915
918
|
logError("cdp.restore_root_attach", error, {
|
|
916
919
|
code: "restore_root_attach_failed",
|
|
917
920
|
extra: { tabId }
|
|
@@ -2021,6 +2024,9 @@ export class CDPRouter {
|
|
|
2021
2024
|
const message = error instanceof Error ? error.message : String(error);
|
|
2022
2025
|
return STALE_TAB_ERROR_MARKERS.some((marker) => message.includes(marker));
|
|
2023
2026
|
}
|
|
2027
|
+
isExpectedDebuggerCleanupError(error) {
|
|
2028
|
+
return this.isStaleTabError(error);
|
|
2029
|
+
}
|
|
2024
2030
|
markExpectedRootDetach(tabId) {
|
|
2025
2031
|
this.expectedRootDetachDeadlines.set(tabId, Date.now() + 1000);
|
|
2026
2032
|
}
|
|
@@ -2074,6 +2080,9 @@ export class CDPRouter {
|
|
|
2074
2080
|
});
|
|
2075
2081
|
}
|
|
2076
2082
|
catch (error) {
|
|
2083
|
+
if (this.isExpectedDebuggerCleanupError(error)) {
|
|
2084
|
+
return;
|
|
2085
|
+
}
|
|
2077
2086
|
logError("cdp.safe_detach", error, { code: "detach_failed" });
|
|
2078
2087
|
}
|
|
2079
2088
|
}
|
package/extension/manifest.json
CHANGED