@introspection-ai/recipes 0.26.0 → 0.27.2
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/dist/api/mcp.d.ts +3 -3
- package/dist/api/mcp.d.ts.map +1 -1
- package/dist/api/mcp.js +1 -1
- package/dist/api/mcp.js.map +1 -1
- package/dist/{child-agent-completions.d.ts → child/agent-completions.d.ts} +2 -2
- package/dist/child/agent-completions.d.ts.map +1 -0
- package/dist/{child-agent-completions.js → child/agent-completions.js} +1 -1
- package/dist/child/agent-completions.js.map +1 -0
- package/dist/{child-agent-store.d.ts → child/agent-store.d.ts} +1 -1
- package/dist/child/agent-store.d.ts.map +1 -0
- package/dist/{child-agent-store.js → child/agent-store.js} +1 -1
- package/dist/child/agent-store.js.map +1 -0
- package/dist/{child-agent.d.ts → child/agent.d.ts} +2 -2
- package/dist/child/agent.d.ts.map +1 -0
- package/dist/{child-agent.js → child/agent.js} +5 -5
- package/dist/child/agent.js.map +1 -0
- package/dist/{child-session.d.ts → child/session.d.ts} +4 -4
- package/dist/child/session.d.ts.map +1 -0
- package/dist/{child-session.js → child/session.js} +2 -2
- package/dist/child/session.js.map +1 -0
- package/dist/connector-tools.d.ts +1 -1
- package/dist/connector-tools.js +2 -2
- package/dist/inspect.d.ts +1 -1
- package/dist/inspect.js +1 -1
- package/dist/{mcp-catalog.d.ts → mcp/catalog.d.ts} +3 -3
- package/dist/mcp/catalog.d.ts.map +1 -0
- package/dist/{mcp-catalog.js → mcp/catalog.js} +2 -2
- package/dist/mcp/catalog.js.map +1 -0
- package/dist/{mcp-command-context.d.ts → mcp/cli/command-context.d.ts} +1 -1
- package/dist/mcp/cli/command-context.d.ts.map +1 -0
- package/dist/{mcp-command-context.js → mcp/cli/command-context.js} +1 -1
- package/dist/mcp/cli/command-context.js.map +1 -0
- package/dist/{mcp-cli-core.d.ts → mcp/cli/core.d.ts} +14 -8
- package/dist/mcp/cli/core.d.ts.map +1 -0
- package/dist/{mcp-cli-core.js → mcp/cli/core.js} +105 -146
- package/dist/mcp/cli/core.js.map +1 -0
- package/dist/mcp/cli/help.d.ts +6 -0
- package/dist/mcp/cli/help.d.ts.map +1 -0
- package/dist/mcp/cli/help.js +116 -0
- package/dist/mcp/cli/help.js.map +1 -0
- package/dist/mcp/cli/index.d.ts +3 -0
- package/dist/mcp/cli/index.d.ts.map +1 -0
- package/dist/{mcp-cli.js → mcp/cli/index.js} +4 -4
- package/dist/mcp/cli/index.js.map +1 -0
- package/dist/{mcp-cli-policy.d.ts → mcp/cli/policy.d.ts} +2 -2
- package/dist/mcp/cli/policy.d.ts.map +1 -0
- package/dist/{mcp-cli-policy.js → mcp/cli/policy.js} +2 -2
- package/dist/mcp/cli/policy.js.map +1 -0
- package/dist/mcp/cli/run-worker.d.ts +2 -0
- package/dist/mcp/cli/run-worker.d.ts.map +1 -0
- package/dist/mcp/cli/run-worker.js +54 -0
- package/dist/mcp/cli/run-worker.js.map +1 -0
- package/dist/mcp/client-entry.d.ts +3 -0
- package/dist/mcp/client-entry.d.ts.map +1 -0
- package/dist/{mcp-client.js → mcp/client-entry.js} +3 -3
- package/dist/mcp/client-entry.js.map +1 -0
- package/dist/{mcp-contract.d.ts → mcp/contract.d.ts} +2 -2
- package/dist/mcp/contract.d.ts.map +1 -0
- package/dist/{mcp-contract.js → mcp/contract.js} +1 -1
- package/dist/mcp/contract.js.map +1 -0
- package/dist/{mcp-daemon-client.d.ts → mcp/daemon/client.d.ts} +3 -2
- package/dist/mcp/daemon/client.d.ts.map +1 -0
- package/dist/{mcp-daemon-client.js → mcp/daemon/client.js} +12 -8
- package/dist/mcp/daemon/client.js.map +1 -0
- package/dist/mcp/daemon/index.d.ts +3 -0
- package/dist/mcp/daemon/index.d.ts.map +1 -0
- package/dist/mcp/daemon/index.js +453 -0
- package/dist/{mcp-daemon.js.map → mcp/daemon/index.js.map} +1 -1
- package/dist/{mcp-daemon-protocol.d.ts → mcp/daemon/protocol.d.ts} +2 -2
- package/dist/mcp/daemon/protocol.d.ts.map +1 -0
- package/dist/{mcp-daemon-protocol.js → mcp/daemon/protocol.js} +1 -1
- package/dist/mcp/daemon/protocol.js.map +1 -0
- package/dist/{mcp.d.ts → mcp/index.d.ts} +5 -5
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/{mcp.js → mcp/index.js} +16 -10
- package/dist/mcp/index.js.map +1 -0
- package/dist/{mcp-policy.d.ts → mcp/policy.d.ts} +3 -3
- package/dist/mcp/policy.d.ts.map +1 -0
- package/dist/{mcp-policy.js → mcp/policy.js} +1 -1
- package/dist/mcp/policy.js.map +1 -0
- package/dist/{mcp-tools.d.ts → mcp/tools.d.ts} +4 -4
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/{mcp-tools.js → mcp/tools.js} +4 -4
- package/dist/mcp/tools.js.map +1 -0
- package/dist/{mcp-trace-context.d.ts → mcp/trace-context.d.ts} +2 -2
- package/dist/mcp/trace-context.d.ts.map +1 -0
- package/dist/{mcp-trace-context.js → mcp/trace-context.js} +1 -1
- package/dist/mcp/trace-context.js.map +1 -0
- package/dist/mcp-chunks/{auth-command-JBYNHHMV.js → auth-command-GQFV6QYP.js} +22 -21
- package/dist/mcp-chunks/call-arguments-VT7JLNJY.js +16 -0
- package/dist/mcp-chunks/{call-command-467BVXTE.js → call-command-LMAREWKD.js} +45 -44
- package/dist/mcp-chunks/{chunk-I7JR2GIC.js → chunk-2HOMVWSA.js} +2 -2
- package/dist/mcp-chunks/{chunk-CZ43ZITK.js → chunk-2P2HVZ3G.js} +1 -1
- package/dist/mcp-chunks/{chunk-SUNOYTQJ.js → chunk-34QXE62Y.js} +175 -147
- package/dist/mcp-chunks/{chunk-TFU4NKFJ.js → chunk-5B7GRMUK.js} +1 -1
- package/dist/mcp-chunks/{chunk-LG3GLOSA.js → chunk-5BMCVE2J.js} +14 -11
- package/dist/mcp-chunks/{chunk-MJHMXYMO.js → chunk-6QZQZXDJ.js} +3 -3
- package/dist/mcp-chunks/{chunk-DMBE47LM.js → chunk-6RG6AD5X.js} +6 -6
- package/dist/mcp-chunks/{chunk-UCJ7YDFN.js → chunk-77BZYP72.js} +1 -1
- package/dist/mcp-chunks/{chunk-NTABJCUL.js → chunk-7PFJCLXL.js} +10 -10
- package/dist/mcp-chunks/{chunk-66P5FXP3.js → chunk-7WL4TMON.js} +4 -4
- package/dist/mcp-chunks/{chunk-HKZZGSDV.js → chunk-C2VLY7ED.js} +4 -4
- package/dist/mcp-chunks/{chunk-XCNWICLD.js → chunk-CLR6DJV3.js} +1 -1
- package/dist/mcp-chunks/{chunk-REEFOL44.js → chunk-D6B2M5V7.js} +1 -1
- package/dist/mcp-chunks/{chunk-EP22XMWK.js → chunk-D6SVCPN6.js} +1 -1
- package/dist/mcp-chunks/{chunk-BTU34BUG.js → chunk-FBVRU4Y3.js} +43 -30
- package/dist/mcp-chunks/{chunk-TGPIW6F6.js → chunk-FONFU4G5.js} +1 -1
- package/dist/mcp-chunks/chunk-H4KL74PV.js +2073 -0
- package/dist/mcp-chunks/{chunk-QIBGY4IX.js → chunk-H7ARMBV7.js} +4 -9
- package/dist/mcp-chunks/{chunk-OABFKFSL.js → chunk-HZ2SX5U6.js} +39 -34
- package/dist/mcp-chunks/{chunk-HTXQPQPB.js → chunk-I6UMKX5E.js} +4 -4
- package/dist/mcp-chunks/{chunk-Z6QEOUMK.js → chunk-IF6LRV3J.js} +8 -14
- package/dist/mcp-chunks/{chunk-HBN3ESMH.js → chunk-JVYCENPP.js} +4 -4
- package/dist/mcp-chunks/{chunk-IO2IMWYS.js → chunk-KOWNVUL2.js} +34 -7
- package/dist/mcp-chunks/{chunk-AS27BTCS.js → chunk-KQCLM7R7.js} +4 -4
- package/dist/mcp-chunks/{chunk-AP5VHS73.js → chunk-L6OOGZVA.js} +2 -2
- package/dist/mcp-chunks/{chunk-BC2HDCYV.js → chunk-LCBDVFVA.js} +1 -1
- package/dist/mcp-chunks/{chunk-EUDC3ICZ.js → chunk-LIEFPSSB.js} +5 -5
- package/dist/mcp-chunks/{chunk-YPTN46JQ.js → chunk-LQIE4PKL.js} +2 -2
- package/dist/mcp-chunks/{chunk-GK4LA4E6.js → chunk-LXHPDKEF.js} +1 -1
- package/dist/mcp-chunks/{chunk-XFQSUC7T.js → chunk-MJFZM5EV.js} +5 -5
- package/dist/mcp-chunks/{chunk-WUEDIOR5.js → chunk-NQW3ES2G.js} +2 -8
- package/dist/mcp-chunks/{chunk-3Q2Q7SBU.js → chunk-O2VOMKAS.js} +13 -13
- package/dist/mcp-chunks/{chunk-GL4AA5QV.js → chunk-O4JIUOWF.js} +2 -2
- package/dist/mcp-chunks/{chunk-GEVQ2GJW.js → chunk-P3UVILEW.js} +2 -2
- package/dist/mcp-chunks/{chunk-N7ZWX3WW.js → chunk-P463YBJM.js} +1 -1
- package/dist/mcp-chunks/{chunk-Y3L5LWBY.js → chunk-PJCMJ65D.js} +277 -2110
- package/dist/mcp-chunks/{chunk-LTR626QF.js → chunk-QALB3DRW.js} +1 -1
- package/dist/mcp-chunks/{chunk-D2P2IV4H.js → chunk-QJNF3A3F.js} +1 -1
- package/dist/mcp-chunks/{chunk-KJNNO5Z6.js → chunk-RIHPVCGI.js} +1 -1
- package/dist/mcp-chunks/{chunk-J2WP6ERZ.js → chunk-RZIJUJGL.js} +44 -1055
- package/dist/mcp-chunks/{chunk-L2LGMX5P.js → chunk-S2YF442K.js} +2 -2
- package/dist/mcp-chunks/{chunk-CN5YF3IQ.js → chunk-S5F3HEZZ.js} +1848 -1046
- package/dist/mcp-chunks/{chunk-6DVS7RBO.js → chunk-S6GJ42I2.js} +1 -1
- package/dist/mcp-chunks/chunk-T4MQCFIK.js +982 -0
- package/dist/mcp-chunks/{chunk-OB256NMD.js → chunk-TUQGOYK6.js} +1 -1
- package/dist/mcp-chunks/{chunk-M62ESEOY.js → chunk-TYYSBILI.js} +10 -22
- package/dist/mcp-chunks/{chunk-LYWEATXZ.js → chunk-UHO6KIUJ.js} +2 -2
- package/dist/mcp-chunks/{chunk-BSCNF4NY.js → chunk-UIPG6W7N.js} +2 -2
- package/dist/mcp-chunks/{chunk-AK5ZEDEF.js → chunk-UKM35J67.js} +2 -2
- package/dist/mcp-chunks/{chunk-G4H535MI.js → chunk-UYJZJXC2.js} +21 -3
- package/dist/mcp-chunks/{chunk-GA4ZYSRX.js → chunk-VJIAHZZG.js} +4 -4
- package/dist/mcp-chunks/{chunk-OZQTZWW4.js → chunk-WHJUDBPR.js} +1 -1
- package/dist/mcp-chunks/{chunk-YI5SMRFH.js → chunk-XNHGMWN2.js} +7 -7
- package/dist/mcp-chunks/{cli-TN6JTLTS.js → cli-JI7MEAAX.js} +70 -69
- package/dist/mcp-chunks/client-QU7ABSNB.js +30 -0
- package/dist/mcp-chunks/{config-command-LICU56ZH.js → config-command-GRZLKD3R.js} +36 -28
- package/dist/mcp-chunks/daemon-command-3266CYHO.js +30 -0
- package/dist/mcp-chunks/{dist-MFAWSKGH.js → dist-USMCQ22V.js} +71 -47
- package/dist/mcp-chunks/{emit-ts-command-FVX3JMSN.js → emit-ts-command-7VLESP7H.js} +18 -17
- package/dist/mcp-chunks/{generate-cli-runner-L2L7VMCA.js → generate-cli-runner-SSW2B72K.js} +43 -42
- package/dist/mcp-chunks/generated-daemon-runtime-7CFVWLC7.js +30 -0
- package/dist/mcp-chunks/{inspect-cli-command-Y5D3GRE2.js → inspect-cli-command-NCGCMOIS.js} +9 -9
- package/dist/mcp-chunks/{launch-ZFY6CM2A.js → launch-NBONSPNK.js} +1 -1
- package/dist/mcp-chunks/{lifecycle-H7DIW5DM.js → lifecycle-CXAKUCN4.js} +1 -1
- package/dist/mcp-chunks/{list-command-55LCLW4S.js → list-command-5T4UF4PF.js} +56 -69
- package/dist/mcp-chunks/{output-utils-YYHI637S.js → output-utils-YFTWQZ5V.js} +3 -3
- package/dist/mcp-chunks/{prompt-CH6TK0bC-DZLFAAPK.js → prompt-CH6TK0bC-6DI4RA4E.js} +1 -1
- package/dist/mcp-chunks/{record-command-PWIBYC5J.js → record-command-TE5O7WBL.js} +5 -5
- package/dist/mcp-chunks/{replay-command-QHZZZMXF.js → replay-command-QCUL5ASR.js} +6 -6
- package/dist/mcp-chunks/{resource-command-HMR2KXWK.js → resource-command-XMGF7EAK.js} +9 -9
- package/dist/mcp-chunks/{result-utils-UGCQSRJ4.js → result-utils-HKB42M7Y.js} +3 -3
- package/dist/mcp-chunks/runtime-3X2XVS6X.js +37 -0
- package/dist/mcp-chunks/{runtime-wrapper-I4B3OROR.js → runtime-wrapper-MI3HF45J.js} +3 -3
- package/dist/mcp-chunks/{serve-command-NTDI3YPN.js → serve-command-5HV3ZE25.js} +25 -24
- package/dist/mcp-chunks/{timeouts-35UDWFA7.js → timeouts-YBFBTLV2.js} +8 -5
- package/dist/mcp-chunks/{vault-command-D5QZL4FI.js → vault-command-FC2PD5U6.js} +4 -4
- package/dist/mcp-chunks/webapi-IFUPO72B.js +2481 -0
- package/dist/mcp-daemon.js +35 -28
- package/dist/mcp-run-worker.js +28 -27
- package/dist/pi-extension.d.ts +1 -1
- package/dist/pi-extension.d.ts.map +1 -1
- package/dist/pi-extension.js +10 -9
- package/dist/pi-extension.js.map +1 -1
- package/dist/{recipe-agent.d.ts → recipe/agent.d.ts} +3 -3
- package/dist/recipe/agent.d.ts.map +1 -0
- package/dist/{recipe-agent.js → recipe/agent.js} +5 -5
- package/dist/recipe/agent.js.map +1 -0
- package/dist/{recipe-extensions.d.ts → recipe/extensions.d.ts} +1 -1
- package/dist/recipe/extensions.d.ts.map +1 -0
- package/dist/{recipe-extensions.js → recipe/extensions.js} +1 -1
- package/dist/recipe/extensions.js.map +1 -0
- package/dist/{recipe-mcp-config.d.ts → recipe/mcp-config.d.ts} +2 -2
- package/dist/recipe/mcp-config.d.ts.map +1 -0
- package/dist/{recipe-mcp-config.js → recipe/mcp-config.js} +1 -1
- package/dist/recipe/mcp-config.js.map +1 -0
- package/dist/{recipe-model.d.ts → recipe/model.d.ts} +1 -1
- package/dist/recipe/model.d.ts.map +1 -0
- package/dist/{recipe-model.js → recipe/model.js} +1 -1
- package/dist/recipe/model.js.map +1 -0
- package/dist/{recipe-package.d.ts → recipe/package.d.ts} +1 -1
- package/dist/recipe/package.d.ts.map +1 -0
- package/dist/{recipe-package.js → recipe/package.js} +1 -1
- package/dist/recipe/package.js.map +1 -0
- package/dist/recipe/resolve.d.ts +6 -6
- package/dist/recipe/resolve.d.ts.map +1 -1
- package/dist/recipe/resolve.js +4 -4
- package/dist/recipe/resolve.js.map +1 -1
- package/dist/{recipe-session.d.ts → recipe/session.d.ts} +1 -1
- package/dist/recipe/session.d.ts.map +1 -0
- package/dist/{recipe-session.js → recipe/session.js} +1 -1
- package/dist/recipe/session.js.map +1 -0
- package/dist/recipe/skills-prompt.d.ts +30 -0
- package/dist/recipe/skills-prompt.d.ts.map +1 -0
- package/dist/recipe/skills-prompt.js +28 -0
- package/dist/recipe/skills-prompt.js.map +1 -0
- package/dist/{recipe-skills.d.ts → recipe/skills.d.ts} +1 -1
- package/dist/recipe/skills.d.ts.map +1 -0
- package/dist/{recipe-skills.js → recipe/skills.js} +2 -2
- package/dist/recipe/skills.js.map +1 -0
- package/dist/run-controller.js +2 -2
- package/dist/session.d.ts +1 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +5 -5
- package/dist/session.js.map +1 -1
- package/docs/agent-composition.md +4 -1
- package/docs/channels.md +1 -1
- package/docs/recipe-format.md +4 -2
- package/docs/slack.md +1 -1
- package/package.json +6 -6
- package/dist/child-agent-completions.d.ts.map +0 -1
- package/dist/child-agent-completions.js.map +0 -1
- package/dist/child-agent-store.d.ts.map +0 -1
- package/dist/child-agent-store.js.map +0 -1
- package/dist/child-agent.d.ts.map +0 -1
- package/dist/child-agent.js.map +0 -1
- package/dist/child-session.d.ts.map +0 -1
- package/dist/child-session.js.map +0 -1
- package/dist/mcp-catalog.d.ts.map +0 -1
- package/dist/mcp-catalog.js.map +0 -1
- package/dist/mcp-chunks/call-arguments-S4EGFKUQ.js +0 -15
- package/dist/mcp-chunks/chunk-YVH36MGQ.js +0 -92
- package/dist/mcp-chunks/client-G33HPQAC.js +0 -29
- package/dist/mcp-chunks/daemon-command-JLVHGWHB.js +0 -29
- package/dist/mcp-chunks/generated-daemon-runtime-DC6IL7E7.js +0 -29
- package/dist/mcp-chunks/runtime-ZNFPZXKE.js +0 -36
- package/dist/mcp-chunks/webapi-4GWO2UBA.js +0 -3508
- package/dist/mcp-cli-core.d.ts.map +0 -1
- package/dist/mcp-cli-core.js.map +0 -1
- package/dist/mcp-cli-help.d.ts +0 -2
- package/dist/mcp-cli-help.d.ts.map +0 -1
- package/dist/mcp-cli-help.js +0 -36
- package/dist/mcp-cli-help.js.map +0 -1
- package/dist/mcp-cli-policy.d.ts.map +0 -1
- package/dist/mcp-cli-policy.js.map +0 -1
- package/dist/mcp-cli.d.ts +0 -3
- package/dist/mcp-cli.d.ts.map +0 -1
- package/dist/mcp-cli.js.map +0 -1
- package/dist/mcp-client.d.ts +0 -3
- package/dist/mcp-client.d.ts.map +0 -1
- package/dist/mcp-client.js.map +0 -1
- package/dist/mcp-command-context.d.ts.map +0 -1
- package/dist/mcp-command-context.js.map +0 -1
- package/dist/mcp-contract.d.ts.map +0 -1
- package/dist/mcp-contract.js.map +0 -1
- package/dist/mcp-daemon-client.d.ts.map +0 -1
- package/dist/mcp-daemon-client.js.map +0 -1
- package/dist/mcp-daemon-protocol.d.ts.map +0 -1
- package/dist/mcp-daemon-protocol.js.map +0 -1
- package/dist/mcp-daemon.d.ts +0 -3
- package/dist/mcp-daemon.d.ts.map +0 -1
- package/dist/mcp-policy.d.ts.map +0 -1
- package/dist/mcp-policy.js.map +0 -1
- package/dist/mcp-run-worker.d.ts +0 -2
- package/dist/mcp-run-worker.d.ts.map +0 -1
- package/dist/mcp-run-worker.js.map +0 -1
- package/dist/mcp-tools.d.ts.map +0 -1
- package/dist/mcp-tools.js.map +0 -1
- package/dist/mcp-trace-context.d.ts.map +0 -1
- package/dist/mcp-trace-context.js.map +0 -1
- package/dist/mcp.d.ts.map +0 -1
- package/dist/mcp.js.map +0 -1
- package/dist/recipe-agent.d.ts.map +0 -1
- package/dist/recipe-agent.js.map +0 -1
- package/dist/recipe-extensions.d.ts.map +0 -1
- package/dist/recipe-extensions.js.map +0 -1
- package/dist/recipe-mcp-config.d.ts.map +0 -1
- package/dist/recipe-mcp-config.js.map +0 -1
- package/dist/recipe-model.d.ts.map +0 -1
- package/dist/recipe-model.js.map +0 -1
- package/dist/recipe-package.d.ts.map +0 -1
- package/dist/recipe-package.js.map +0 -1
- package/dist/recipe-session.d.ts.map +0 -1
- package/dist/recipe-session.js.map +0 -1
- package/dist/recipe-skills.d.ts.map +0 -1
- package/dist/recipe-skills.js.map +0 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
stableJsonStringify
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KQCLM7R7.js";
|
|
5
5
|
import {
|
|
6
6
|
NON_INTERACTIVE_ELICITATION_HINT,
|
|
7
7
|
createNonInteractiveElicitationResponder,
|
|
8
8
|
registerElicitationHandler
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-D6B2M5V7.js";
|
|
10
10
|
import {
|
|
11
11
|
RecordTransport,
|
|
12
12
|
resolveRecordingPath
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-L6OOGZVA.js";
|
|
14
14
|
import {
|
|
15
15
|
OAuthTimeoutError,
|
|
16
16
|
connectWithAuth,
|
|
@@ -20,50 +20,60 @@ import {
|
|
|
20
20
|
isUnauthorizedError,
|
|
21
21
|
maybeEnableOAuth,
|
|
22
22
|
resolveOAuthTimeoutFromEnv
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-TYYSBILI.js";
|
|
24
24
|
import {
|
|
25
25
|
readCachedAccessToken
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-IF6LRV3J.js";
|
|
27
27
|
import {
|
|
28
28
|
withRuntimeEnvironment
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-XNHGMWN2.js";
|
|
30
30
|
import {
|
|
31
31
|
createPrefixedConsoleLogger,
|
|
32
32
|
resolveLogLevelFromEnv
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-P463YBJM.js";
|
|
34
34
|
import {
|
|
35
35
|
STDIO_TRACE_ENABLED,
|
|
36
36
|
flushStdioLogs,
|
|
37
37
|
ignoreStdioEmitterError
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-FONFU4G5.js";
|
|
39
39
|
import {
|
|
40
40
|
MCPORTER_VERSION
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-7PFJCLXL.js";
|
|
42
42
|
import {
|
|
43
|
+
ChromeDevtoolsRelayDiscoveryError,
|
|
44
|
+
ChromeDevtoolsRelayRequiredError,
|
|
45
|
+
chromeDevtoolsRelayEnvironmentKeys,
|
|
46
|
+
formatChromeDevtoolsRelayDecision,
|
|
47
|
+
isExistingChromeDevtoolsCommand,
|
|
43
48
|
normalizeTimeout,
|
|
44
49
|
raceWithTimeout,
|
|
50
|
+
recordChromeDevtoolsRelayDecision,
|
|
51
|
+
resolveChromeDevtoolsAutoConnectCommand,
|
|
52
|
+
resolveChromeDevtoolsRelayEnvironment,
|
|
53
|
+
resolveChromeDevtoolsRelayPolicy,
|
|
54
|
+
resolveChromeDevtoolsRelayProbeTimeoutMs,
|
|
55
|
+
resolveChromeDevtoolsRelayRuntimeIdentity,
|
|
45
56
|
resolveCommandArgument,
|
|
46
|
-
resolveCommandArguments
|
|
47
|
-
|
|
57
|
+
resolveCommandArguments,
|
|
58
|
+
rewriteChromeDevtoolsArgsForRelay
|
|
59
|
+
} from "./chunk-H4KL74PV.js";
|
|
48
60
|
import {
|
|
49
61
|
loadServerDefinitions,
|
|
50
62
|
normalizeServerEntry,
|
|
51
|
-
parseTree,
|
|
52
63
|
readConfigFile
|
|
53
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-RZIJUJGL.js";
|
|
54
65
|
import {
|
|
55
66
|
pathExists
|
|
56
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-UYJZJXC2.js";
|
|
57
68
|
import {
|
|
58
69
|
mcporterConfigCandidates
|
|
59
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-UHO6KIUJ.js";
|
|
60
71
|
import {
|
|
61
|
-
resolveEnvPlaceholders
|
|
62
|
-
|
|
63
|
-
} from "./chunk-EP22XMWK.js";
|
|
72
|
+
resolveEnvPlaceholders
|
|
73
|
+
} from "./chunk-D6SVCPN6.js";
|
|
64
74
|
import {
|
|
65
75
|
analyzeConnectionError
|
|
66
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-O4JIUOWF.js";
|
|
67
77
|
import {
|
|
68
78
|
Client,
|
|
69
79
|
DEFAULT_REQUEST_TIMEOUT_MSEC,
|
|
@@ -76,7 +86,7 @@ import {
|
|
|
76
86
|
StreamableHTTPClientTransport,
|
|
77
87
|
serializeMessage,
|
|
78
88
|
specTypeSchemas
|
|
79
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-S5F3HEZZ.js";
|
|
80
90
|
import {
|
|
81
91
|
__commonJS,
|
|
82
92
|
__require,
|
|
@@ -88,8 +98,8 @@ var require_windows = __commonJS({
|
|
|
88
98
|
"node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module) {
|
|
89
99
|
module.exports = isexe;
|
|
90
100
|
isexe.sync = sync;
|
|
91
|
-
var
|
|
92
|
-
function checkPathExt(
|
|
101
|
+
var fs7 = __require("fs");
|
|
102
|
+
function checkPathExt(path7, options) {
|
|
93
103
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
94
104
|
if (!pathext) {
|
|
95
105
|
return true;
|
|
@@ -100,25 +110,25 @@ var require_windows = __commonJS({
|
|
|
100
110
|
}
|
|
101
111
|
for (var i = 0; i < pathext.length; i++) {
|
|
102
112
|
var p = pathext[i].toLowerCase();
|
|
103
|
-
if (p &&
|
|
113
|
+
if (p && path7.substr(-p.length).toLowerCase() === p) {
|
|
104
114
|
return true;
|
|
105
115
|
}
|
|
106
116
|
}
|
|
107
117
|
return false;
|
|
108
118
|
}
|
|
109
|
-
function checkStat(stat,
|
|
119
|
+
function checkStat(stat, path7, options) {
|
|
110
120
|
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
111
121
|
return false;
|
|
112
122
|
}
|
|
113
|
-
return checkPathExt(
|
|
123
|
+
return checkPathExt(path7, options);
|
|
114
124
|
}
|
|
115
|
-
function isexe(
|
|
116
|
-
|
|
117
|
-
cb(er, er ? false : checkStat(stat,
|
|
125
|
+
function isexe(path7, options, cb) {
|
|
126
|
+
fs7.stat(path7, function(er, stat) {
|
|
127
|
+
cb(er, er ? false : checkStat(stat, path7, options));
|
|
118
128
|
});
|
|
119
129
|
}
|
|
120
|
-
function sync(
|
|
121
|
-
return checkStat(
|
|
130
|
+
function sync(path7, options) {
|
|
131
|
+
return checkStat(fs7.statSync(path7), path7, options);
|
|
122
132
|
}
|
|
123
133
|
}
|
|
124
134
|
});
|
|
@@ -128,14 +138,14 @@ var require_mode = __commonJS({
|
|
|
128
138
|
"node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports, module) {
|
|
129
139
|
module.exports = isexe;
|
|
130
140
|
isexe.sync = sync;
|
|
131
|
-
var
|
|
132
|
-
function isexe(
|
|
133
|
-
|
|
141
|
+
var fs7 = __require("fs");
|
|
142
|
+
function isexe(path7, options, cb) {
|
|
143
|
+
fs7.stat(path7, function(er, stat) {
|
|
134
144
|
cb(er, er ? false : checkStat(stat, options));
|
|
135
145
|
});
|
|
136
146
|
}
|
|
137
|
-
function sync(
|
|
138
|
-
return checkStat(
|
|
147
|
+
function sync(path7, options) {
|
|
148
|
+
return checkStat(fs7.statSync(path7), options);
|
|
139
149
|
}
|
|
140
150
|
function checkStat(stat, options) {
|
|
141
151
|
return stat.isFile() && checkMode(stat, options);
|
|
@@ -159,7 +169,7 @@ var require_mode = __commonJS({
|
|
|
159
169
|
// node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
|
|
160
170
|
var require_isexe = __commonJS({
|
|
161
171
|
"node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module) {
|
|
162
|
-
var
|
|
172
|
+
var fs7 = __require("fs");
|
|
163
173
|
var core;
|
|
164
174
|
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
165
175
|
core = require_windows();
|
|
@@ -168,7 +178,7 @@ var require_isexe = __commonJS({
|
|
|
168
178
|
}
|
|
169
179
|
module.exports = isexe;
|
|
170
180
|
isexe.sync = sync;
|
|
171
|
-
function isexe(
|
|
181
|
+
function isexe(path7, options, cb) {
|
|
172
182
|
if (typeof options === "function") {
|
|
173
183
|
cb = options;
|
|
174
184
|
options = {};
|
|
@@ -178,7 +188,7 @@ var require_isexe = __commonJS({
|
|
|
178
188
|
throw new TypeError("callback not provided");
|
|
179
189
|
}
|
|
180
190
|
return new Promise(function(resolve, reject) {
|
|
181
|
-
isexe(
|
|
191
|
+
isexe(path7, options || {}, function(er, is) {
|
|
182
192
|
if (er) {
|
|
183
193
|
reject(er);
|
|
184
194
|
} else {
|
|
@@ -187,7 +197,7 @@ var require_isexe = __commonJS({
|
|
|
187
197
|
});
|
|
188
198
|
});
|
|
189
199
|
}
|
|
190
|
-
core(
|
|
200
|
+
core(path7, options || {}, function(er, is) {
|
|
191
201
|
if (er) {
|
|
192
202
|
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
193
203
|
er = null;
|
|
@@ -197,9 +207,9 @@ var require_isexe = __commonJS({
|
|
|
197
207
|
cb(er, is);
|
|
198
208
|
});
|
|
199
209
|
}
|
|
200
|
-
function sync(
|
|
210
|
+
function sync(path7, options) {
|
|
201
211
|
try {
|
|
202
|
-
return core.sync(
|
|
212
|
+
return core.sync(path7, options || {});
|
|
203
213
|
} catch (er) {
|
|
204
214
|
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
205
215
|
return false;
|
|
@@ -215,7 +225,7 @@ var require_isexe = __commonJS({
|
|
|
215
225
|
var require_which = __commonJS({
|
|
216
226
|
"node_modules/.pnpm/which@2.0.2/node_modules/which/which.js"(exports, module) {
|
|
217
227
|
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
218
|
-
var
|
|
228
|
+
var path7 = __require("path");
|
|
219
229
|
var COLON = isWindows ? ";" : ":";
|
|
220
230
|
var isexe = require_isexe();
|
|
221
231
|
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
@@ -253,7 +263,7 @@ var require_which = __commonJS({
|
|
|
253
263
|
return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
|
|
254
264
|
const ppRaw = pathEnv[i];
|
|
255
265
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
256
|
-
const pCmd =
|
|
266
|
+
const pCmd = path7.join(pathPart, cmd);
|
|
257
267
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
258
268
|
resolve(subStep(p, i, 0));
|
|
259
269
|
});
|
|
@@ -280,7 +290,7 @@ var require_which = __commonJS({
|
|
|
280
290
|
for (let i = 0; i < pathEnv.length; i++) {
|
|
281
291
|
const ppRaw = pathEnv[i];
|
|
282
292
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
283
|
-
const pCmd =
|
|
293
|
+
const pCmd = path7.join(pathPart, cmd);
|
|
284
294
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
285
295
|
for (let j = 0; j < pathExt.length; j++) {
|
|
286
296
|
const cur = p + pathExt[j];
|
|
@@ -328,7 +338,7 @@ var require_path_key = __commonJS({
|
|
|
328
338
|
var require_resolveCommand = __commonJS({
|
|
329
339
|
"node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module) {
|
|
330
340
|
"use strict";
|
|
331
|
-
var
|
|
341
|
+
var path7 = __require("path");
|
|
332
342
|
var which = require_which();
|
|
333
343
|
var getPathKey = require_path_key();
|
|
334
344
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
@@ -346,7 +356,7 @@ var require_resolveCommand = __commonJS({
|
|
|
346
356
|
try {
|
|
347
357
|
resolved = which.sync(parsed.command, {
|
|
348
358
|
path: env[getPathKey({ env })],
|
|
349
|
-
pathExt: withoutPathExt ?
|
|
359
|
+
pathExt: withoutPathExt ? path7.delimiter : void 0
|
|
350
360
|
});
|
|
351
361
|
} catch (e) {
|
|
352
362
|
} finally {
|
|
@@ -355,7 +365,7 @@ var require_resolveCommand = __commonJS({
|
|
|
355
365
|
}
|
|
356
366
|
}
|
|
357
367
|
if (resolved) {
|
|
358
|
-
resolved =
|
|
368
|
+
resolved = path7.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
359
369
|
}
|
|
360
370
|
return resolved;
|
|
361
371
|
}
|
|
@@ -409,8 +419,8 @@ var require_shebang_command = __commonJS({
|
|
|
409
419
|
if (!match) {
|
|
410
420
|
return null;
|
|
411
421
|
}
|
|
412
|
-
const [
|
|
413
|
-
const binary =
|
|
422
|
+
const [path7, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
423
|
+
const binary = path7.split("/").pop();
|
|
414
424
|
if (binary === "env") {
|
|
415
425
|
return argument;
|
|
416
426
|
}
|
|
@@ -423,16 +433,16 @@ var require_shebang_command = __commonJS({
|
|
|
423
433
|
var require_readShebang = __commonJS({
|
|
424
434
|
"node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module) {
|
|
425
435
|
"use strict";
|
|
426
|
-
var
|
|
436
|
+
var fs7 = __require("fs");
|
|
427
437
|
var shebangCommand = require_shebang_command();
|
|
428
438
|
function readShebang(command) {
|
|
429
439
|
const size = 150;
|
|
430
440
|
const buffer = Buffer.alloc(size);
|
|
431
441
|
let fd;
|
|
432
442
|
try {
|
|
433
|
-
fd =
|
|
434
|
-
|
|
435
|
-
|
|
443
|
+
fd = fs7.openSync(command, "r");
|
|
444
|
+
fs7.readSync(fd, buffer, 0, size, 0);
|
|
445
|
+
fs7.closeSync(fd);
|
|
436
446
|
} catch (e) {
|
|
437
447
|
}
|
|
438
448
|
return shebangCommand(buffer.toString());
|
|
@@ -445,7 +455,7 @@ var require_readShebang = __commonJS({
|
|
|
445
455
|
var require_parse = __commonJS({
|
|
446
456
|
"node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js"(exports, module) {
|
|
447
457
|
"use strict";
|
|
448
|
-
var
|
|
458
|
+
var path7 = __require("path");
|
|
449
459
|
var resolveCommand = require_resolveCommand();
|
|
450
460
|
var escape = require_escape();
|
|
451
461
|
var readShebang = require_readShebang();
|
|
@@ -470,7 +480,7 @@ var require_parse = __commonJS({
|
|
|
470
480
|
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
471
481
|
if (parsed.options.forceShell || needsShell) {
|
|
472
482
|
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
473
|
-
parsed.command =
|
|
483
|
+
parsed.command = path7.normalize(parsed.command);
|
|
474
484
|
parsed.command = escape.command(parsed.command);
|
|
475
485
|
parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
|
|
476
486
|
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
@@ -560,7 +570,7 @@ var require_cross_spawn = __commonJS({
|
|
|
560
570
|
var cp = __require("child_process");
|
|
561
571
|
var parse = require_parse();
|
|
562
572
|
var enoent = require_enoent();
|
|
563
|
-
function
|
|
573
|
+
function spawn2(command, args, options) {
|
|
564
574
|
const parsed = parse(command, args, options);
|
|
565
575
|
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
566
576
|
enoent.hookChildProcess(spawned, parsed);
|
|
@@ -572,1943 +582,18 @@ var require_cross_spawn = __commonJS({
|
|
|
572
582
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
573
583
|
return result;
|
|
574
584
|
}
|
|
575
|
-
module.exports =
|
|
576
|
-
module.exports.spawn =
|
|
585
|
+
module.exports = spawn2;
|
|
586
|
+
module.exports.spawn = spawn2;
|
|
577
587
|
module.exports.sync = spawnSync2;
|
|
578
588
|
module.exports._parse = parse;
|
|
579
589
|
module.exports._enoent = enoent;
|
|
580
590
|
}
|
|
581
591
|
});
|
|
582
592
|
|
|
583
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
584
|
-
import { createHash
|
|
585
|
-
import
|
|
586
|
-
import path3 from "node:path";
|
|
587
|
-
|
|
588
|
-
// node_modules/.pnpm/mcporter@0.13.10/node_modules/mcporter/dist/chrome-devtools-relay.js
|
|
589
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
590
|
-
import fs from "node:fs";
|
|
591
|
-
import os from "node:os";
|
|
592
|
-
import path2 from "node:path";
|
|
593
|
-
|
|
594
|
-
// node_modules/.pnpm/mcporter@0.13.10/node_modules/mcporter/dist/chrome-devtools-command.js
|
|
595
|
-
var AUTO_CONNECT_FLAGS = /* @__PURE__ */ new Set(["--autoConnect", "--auto-connect"]);
|
|
596
|
-
var NEGATED_AUTO_CONNECT_FLAGS = /* @__PURE__ */ new Set(["--no-autoConnect", "--no-auto-connect"]);
|
|
597
|
-
var CONNECTION_VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
598
|
-
"--browserUrl",
|
|
599
|
-
"--browser-url",
|
|
600
|
-
"--channel",
|
|
601
|
-
"--executablePath",
|
|
602
|
-
"--executable-path",
|
|
603
|
-
"--userDataDir",
|
|
604
|
-
"--user-data-dir",
|
|
605
|
-
"--wsEndpoint",
|
|
606
|
-
"--ws-endpoint",
|
|
607
|
-
"--wsHeaders",
|
|
608
|
-
"--ws-headers",
|
|
609
|
-
"-e",
|
|
610
|
-
"-u",
|
|
611
|
-
"-w"
|
|
612
|
-
]);
|
|
613
|
-
var NPX_VALUE_OPTIONS = /* @__PURE__ */ new Set([
|
|
614
|
-
"--cache",
|
|
615
|
-
"--package",
|
|
616
|
-
"--prefix",
|
|
617
|
-
"--registry",
|
|
618
|
-
"--userconfig",
|
|
619
|
-
"--workspace",
|
|
620
|
-
"-p",
|
|
621
|
-
"-w"
|
|
622
|
-
]);
|
|
623
|
-
var NPX_COMMAND_STRING_OPTIONS = /* @__PURE__ */ new Set(["--call", "-c"]);
|
|
624
|
-
var NPX_NO_VALUE_OPTIONS = /* @__PURE__ */ new Set(["--ignore-existing", "--no-install", "--quiet", "--silent", "--yes", "-y"]);
|
|
625
|
-
var COMMON_WRAPPERS = /* @__PURE__ */ new Set([
|
|
626
|
-
"ash",
|
|
627
|
-
"bash",
|
|
628
|
-
"csh",
|
|
629
|
-
"dash",
|
|
630
|
-
"cmd",
|
|
631
|
-
"doas",
|
|
632
|
-
"env",
|
|
633
|
-
"fish",
|
|
634
|
-
"ksh",
|
|
635
|
-
"mksh",
|
|
636
|
-
"node",
|
|
637
|
-
"npm",
|
|
638
|
-
"npx",
|
|
639
|
-
"bunx",
|
|
640
|
-
"pnpm",
|
|
641
|
-
"powershell",
|
|
642
|
-
"pwsh",
|
|
643
|
-
"sh",
|
|
644
|
-
"sudo",
|
|
645
|
-
"tcsh",
|
|
646
|
-
"yarn",
|
|
647
|
-
"zsh"
|
|
648
|
-
]);
|
|
649
|
-
function isChromeDevtoolsToken(token) {
|
|
650
|
-
const normalized = token.replaceAll("\\", "/").toLowerCase();
|
|
651
|
-
const basename = normalized.slice(normalized.lastIndexOf("/") + 1);
|
|
652
|
-
return /^chrome-devtools-mcp(?:@[^/]+)?(?:\.(?:bat|cjs|cmd|exe|js|mjs))?$/u.test(basename) || normalized.includes("/chrome-devtools-mcp/") && /\.(?:bat|cjs|cmd|exe|js|mjs)$/u.test(basename);
|
|
653
|
-
}
|
|
654
|
-
function isAmbiguousChromeDevtoolsAutoConnectCommand(command, args) {
|
|
655
|
-
if (isChromeDevtoolsToken(command))
|
|
656
|
-
return false;
|
|
657
|
-
if (isSupportedPackageLauncher(command)) {
|
|
658
|
-
const target = findPackageLauncherTarget(args);
|
|
659
|
-
if (!target)
|
|
660
|
-
return false;
|
|
661
|
-
if (target.ambiguous)
|
|
662
|
-
return true;
|
|
663
|
-
const nestedTarget = commandBasename(args[target.index] ?? "");
|
|
664
|
-
return COMMON_WRAPPERS.has(nestedTarget) && containsChromeAutoConnectInvocation(args.slice(target.index + 1));
|
|
665
|
-
}
|
|
666
|
-
const launcher = commandBasename(command);
|
|
667
|
-
if (COMMON_WRAPPERS.has(launcher))
|
|
668
|
-
return containsChromeAutoConnectInvocation(args);
|
|
669
|
-
const scopedArgs = args.slice(0, optionTerminator(args));
|
|
670
|
-
const tokenIndex = scopedArgs.findIndex(isChromeDevtoolsToken);
|
|
671
|
-
return tokenIndex >= 0 && parseChromeDevtoolsAutoConnectArgs(scopedArgs.slice(tokenIndex + 1)).enabled;
|
|
672
|
-
}
|
|
673
|
-
function resolveChromeDevtoolsAutoConnectCommand(command, args) {
|
|
674
|
-
const target = resolveChromeDevtoolsTarget(command, args);
|
|
675
|
-
if (!target)
|
|
676
|
-
return { enabled: false, withoutAutoConnect: args };
|
|
677
|
-
const parsed = parseChromeDevtoolsAutoConnectArgs(target.args);
|
|
678
|
-
return {
|
|
679
|
-
enabled: parsed.enabled,
|
|
680
|
-
withoutAutoConnect: [...target.prefix, ...parsed.withoutAutoConnect]
|
|
681
|
-
};
|
|
682
|
-
}
|
|
683
|
-
function replaceChromeDevtoolsAutoConnectArgs(command, args, replacement) {
|
|
684
|
-
const target = resolveChromeDevtoolsTarget(command, args);
|
|
685
|
-
if (!target)
|
|
686
|
-
return args;
|
|
687
|
-
const parsed = parseChromeDevtoolsAutoConnectArgs(target.args);
|
|
688
|
-
const stripped = stripConnectionSelectionArgs(parsed.withoutAutoConnect);
|
|
689
|
-
const targetArgs = [...stripped.args];
|
|
690
|
-
targetArgs.splice(stripped.insertionIndex, 0, ...replacement);
|
|
691
|
-
return [...target.prefix, ...targetArgs];
|
|
692
|
-
}
|
|
693
|
-
function resolveChromeDevtoolsTarget(command, args) {
|
|
694
|
-
if (isChromeDevtoolsToken(command))
|
|
695
|
-
return { prefix: [], args };
|
|
696
|
-
if (!isSupportedPackageLauncher(command))
|
|
697
|
-
return void 0;
|
|
698
|
-
const target = findPackageLauncherTarget(args);
|
|
699
|
-
if (!target || target.ambiguous || !isChromeDevtoolsToken(args[target.index] ?? ""))
|
|
700
|
-
return void 0;
|
|
701
|
-
const separatorIndex = target.index + 1;
|
|
702
|
-
const consumesSeparator = target.consumePostTargetSeparator && args[separatorIndex] === "--";
|
|
703
|
-
const targetStart = consumesSeparator ? separatorIndex + 1 : separatorIndex;
|
|
704
|
-
return { prefix: args.slice(0, targetStart), args: args.slice(targetStart) };
|
|
705
|
-
}
|
|
706
|
-
function findPackageLauncherTarget(args) {
|
|
707
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
708
|
-
const arg = args[index];
|
|
709
|
-
if (arg === void 0)
|
|
710
|
-
continue;
|
|
711
|
-
if (arg === "--") {
|
|
712
|
-
return index + 1 < args.length ? { index: index + 1, ambiguous: false, consumePostTargetSeparator: false } : void 0;
|
|
713
|
-
}
|
|
714
|
-
if (arg.startsWith("--call=")) {
|
|
715
|
-
const value = arg.slice("--call=".length);
|
|
716
|
-
return containsInlineChromeAutoConnect([value]) ? { index, ambiguous: true, consumePostTargetSeparator: false } : void 0;
|
|
717
|
-
}
|
|
718
|
-
if (NPX_COMMAND_STRING_OPTIONS.has(arg)) {
|
|
719
|
-
const value = args[index + 1] ?? "";
|
|
720
|
-
return containsInlineChromeAutoConnect([value]) ? { index: index + 1, ambiguous: true, consumePostTargetSeparator: false } : void 0;
|
|
721
|
-
}
|
|
722
|
-
if (NPX_VALUE_OPTIONS.has(arg)) {
|
|
723
|
-
index += 1;
|
|
724
|
-
continue;
|
|
725
|
-
}
|
|
726
|
-
if (NPX_NO_VALUE_OPTIONS.has(arg) || /^--[^=]+=.+/u.test(arg))
|
|
727
|
-
continue;
|
|
728
|
-
if (arg.startsWith("-")) {
|
|
729
|
-
return {
|
|
730
|
-
index,
|
|
731
|
-
ambiguous: containsChromeAutoConnectInvocation(args.slice(index)),
|
|
732
|
-
consumePostTargetSeparator: false
|
|
733
|
-
};
|
|
734
|
-
}
|
|
735
|
-
return { index, ambiguous: false, consumePostTargetSeparator: true };
|
|
736
|
-
}
|
|
737
|
-
return void 0;
|
|
738
|
-
}
|
|
739
|
-
function isSupportedPackageLauncher(command) {
|
|
740
|
-
const launcher = commandBasename(command);
|
|
741
|
-
return launcher === "npx" || launcher === "bunx";
|
|
742
|
-
}
|
|
743
|
-
function containsChromeAutoConnectInvocation(args) {
|
|
744
|
-
const tokenIndex = args.findIndex(isChromeDevtoolsToken);
|
|
745
|
-
if (tokenIndex >= 0)
|
|
746
|
-
return parseChromeDevtoolsAutoConnectArgs(args.slice(tokenIndex + 1)).enabled;
|
|
747
|
-
return containsInlineChromeAutoConnect(args);
|
|
748
|
-
}
|
|
749
|
-
function containsInlineChromeAutoConnect(args) {
|
|
750
|
-
const rendered = args.join(" ").toLowerCase();
|
|
751
|
-
return rendered.includes("chrome-devtools-mcp") && /--(?:auto-connect|autoconnect)(?:=true)?(?:[;'"&|)\]}]|\s|$)/u.test(rendered);
|
|
752
|
-
}
|
|
753
|
-
function commandBasename(command) {
|
|
754
|
-
const normalized = command.replaceAll("\\", "/").toLowerCase();
|
|
755
|
-
return normalized.slice(normalized.lastIndexOf("/") + 1).replace(/\.(?:cmd|exe)$/u, "");
|
|
756
|
-
}
|
|
757
|
-
function optionTerminator(args) {
|
|
758
|
-
const index = args.indexOf("--");
|
|
759
|
-
return index >= 0 ? index : args.length;
|
|
760
|
-
}
|
|
761
|
-
function stripConnectionSelectionArgs(args) {
|
|
762
|
-
const result = [];
|
|
763
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
764
|
-
const arg = args[index];
|
|
765
|
-
if (arg === void 0)
|
|
766
|
-
continue;
|
|
767
|
-
if (arg === "--") {
|
|
768
|
-
result.push(...args.slice(index));
|
|
769
|
-
break;
|
|
770
|
-
}
|
|
771
|
-
if (CONNECTION_VALUE_FLAGS.has(arg)) {
|
|
772
|
-
index += 1;
|
|
773
|
-
continue;
|
|
774
|
-
}
|
|
775
|
-
if ([...CONNECTION_VALUE_FLAGS].some((flag) => arg.startsWith(`${flag}=`)))
|
|
776
|
-
continue;
|
|
777
|
-
result.push(arg);
|
|
778
|
-
}
|
|
779
|
-
const terminatorIndex = result.indexOf("--");
|
|
780
|
-
return { args: result, insertionIndex: terminatorIndex >= 0 ? terminatorIndex : result.length };
|
|
781
|
-
}
|
|
782
|
-
function parseChromeDevtoolsAutoConnectArgs(args) {
|
|
783
|
-
const consumed = /* @__PURE__ */ new Set();
|
|
784
|
-
let enabled = false;
|
|
785
|
-
let sawOption = false;
|
|
786
|
-
let terminatorIndex = args.length;
|
|
787
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
788
|
-
const arg = args[index];
|
|
789
|
-
if (arg === void 0)
|
|
790
|
-
continue;
|
|
791
|
-
if (arg === "--") {
|
|
792
|
-
terminatorIndex = index;
|
|
793
|
-
break;
|
|
794
|
-
}
|
|
795
|
-
if (NEGATED_AUTO_CONNECT_FLAGS.has(arg)) {
|
|
796
|
-
sawOption = true;
|
|
797
|
-
enabled = false;
|
|
798
|
-
consumed.add(index);
|
|
799
|
-
continue;
|
|
800
|
-
}
|
|
801
|
-
let matchedNegatedInline = false;
|
|
802
|
-
for (const flag of NEGATED_AUTO_CONNECT_FLAGS) {
|
|
803
|
-
if (!arg.startsWith(`${flag}=`))
|
|
804
|
-
continue;
|
|
805
|
-
sawOption = true;
|
|
806
|
-
enabled = false;
|
|
807
|
-
consumed.add(index);
|
|
808
|
-
matchedNegatedInline = true;
|
|
809
|
-
break;
|
|
810
|
-
}
|
|
811
|
-
if (matchedNegatedInline)
|
|
812
|
-
continue;
|
|
813
|
-
if (AUTO_CONNECT_FLAGS.has(arg)) {
|
|
814
|
-
sawOption = true;
|
|
815
|
-
consumed.add(index);
|
|
816
|
-
const pairedValue = booleanLiteral(args[index + 1]);
|
|
817
|
-
if (pairedValue !== void 0) {
|
|
818
|
-
enabled = pairedValue;
|
|
819
|
-
consumed.add(index + 1);
|
|
820
|
-
index += 1;
|
|
821
|
-
} else {
|
|
822
|
-
enabled = true;
|
|
823
|
-
}
|
|
824
|
-
continue;
|
|
825
|
-
}
|
|
826
|
-
for (const flag of AUTO_CONNECT_FLAGS) {
|
|
827
|
-
if (!arg.startsWith(`${flag}=`))
|
|
828
|
-
continue;
|
|
829
|
-
sawOption = true;
|
|
830
|
-
enabled = arg.slice(flag.length + 1) === "true";
|
|
831
|
-
consumed.add(index);
|
|
832
|
-
break;
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
const withoutAutoConnect = args.filter((_arg, index) => !consumed.has(index));
|
|
836
|
-
let insertionIndex = 0;
|
|
837
|
-
for (let index = 0; index < terminatorIndex; index += 1) {
|
|
838
|
-
if (!consumed.has(index))
|
|
839
|
-
insertionIndex += 1;
|
|
840
|
-
}
|
|
841
|
-
return { enabled: sawOption && enabled, withoutAutoConnect, insertionIndex };
|
|
842
|
-
}
|
|
843
|
-
function booleanLiteral(value) {
|
|
844
|
-
if (value === "true")
|
|
845
|
-
return true;
|
|
846
|
-
if (value === "false")
|
|
847
|
-
return false;
|
|
848
|
-
return void 0;
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
// node_modules/.pnpm/mcporter@0.13.10/node_modules/mcporter/dist/chrome-devtools-relay-proxy.js
|
|
852
|
-
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
853
|
-
import http, {} from "node:http";
|
|
854
|
-
var WEBSOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
855
|
-
async function startChromeDevtoolsRelayProxy(options) {
|
|
856
|
-
const sockets = /* @__PURE__ */ new Set();
|
|
857
|
-
const clientAuthorization = `Bearer ${randomBytes(32).toString("base64url")}`;
|
|
858
|
-
let downstreamAccepted = false;
|
|
859
|
-
let closed = false;
|
|
860
|
-
const server = http.createServer((_request, response) => {
|
|
861
|
-
response.writeHead(404, { Connection: "close", "Content-Length": "0" }).end();
|
|
862
|
-
});
|
|
863
|
-
server.on("connection", (socket) => trackSocket(sockets, socket));
|
|
864
|
-
server.on("upgrade", (request, downstream, head) => {
|
|
865
|
-
if (closed || downstreamAccepted || !isValidDownstreamUpgrade(request, clientAuthorization) || options.upstream.socket.destroyed) {
|
|
866
|
-
downstream.end("HTTP/1.1 404 Not Found\r\nConnection: close\r\nContent-Length: 0\r\n\r\n");
|
|
867
|
-
return;
|
|
868
|
-
}
|
|
869
|
-
downstreamAccepted = true;
|
|
870
|
-
const key = request.headers["sec-websocket-key"];
|
|
871
|
-
if (typeof key !== "string") {
|
|
872
|
-
downstream.destroy();
|
|
873
|
-
return;
|
|
874
|
-
}
|
|
875
|
-
const accept = createHash("sha1").update(`${key}${WEBSOCKET_GUID}`).digest("base64");
|
|
876
|
-
downstream.write([
|
|
877
|
-
"HTTP/1.1 101 Switching Protocols",
|
|
878
|
-
"Connection: Upgrade",
|
|
879
|
-
"Upgrade: websocket",
|
|
880
|
-
`Sec-WebSocket-Accept: ${accept}`,
|
|
881
|
-
"",
|
|
882
|
-
""
|
|
883
|
-
].join("\r\n"));
|
|
884
|
-
if (options.upstream.head.length > 0)
|
|
885
|
-
downstream.write(options.upstream.head);
|
|
886
|
-
if (head.length > 0)
|
|
887
|
-
options.upstream.socket.write(head);
|
|
888
|
-
options.upstream.socket.once("error", () => downstream.destroy());
|
|
889
|
-
options.upstream.socket.once("close", () => downstream.destroy());
|
|
890
|
-
downstream.once("error", () => options.upstream.socket.destroy());
|
|
891
|
-
downstream.once("close", () => options.upstream.socket.destroy());
|
|
892
|
-
downstream.pipe(options.upstream.socket).pipe(downstream);
|
|
893
|
-
server.close();
|
|
894
|
-
});
|
|
895
|
-
const onUpstreamClose = () => {
|
|
896
|
-
void closeServer(server, sockets);
|
|
897
|
-
};
|
|
898
|
-
options.upstream.socket.once("close", onUpstreamClose);
|
|
899
|
-
try {
|
|
900
|
-
await new Promise((resolve, reject) => {
|
|
901
|
-
const onError = (error) => reject(error);
|
|
902
|
-
server.once("error", onError);
|
|
903
|
-
server.listen(0, "127.0.0.1", () => {
|
|
904
|
-
server.off("error", onError);
|
|
905
|
-
resolve();
|
|
906
|
-
});
|
|
907
|
-
});
|
|
908
|
-
} catch (error) {
|
|
909
|
-
closeUpstream(options.upstream.socket);
|
|
910
|
-
throw error;
|
|
911
|
-
}
|
|
912
|
-
const address = server.address();
|
|
913
|
-
if (!address || address.address !== "127.0.0.1") {
|
|
914
|
-
closeUpstream(options.upstream.socket);
|
|
915
|
-
server.close();
|
|
916
|
-
throw new Error("Chrome relay proxy failed to bind to IPv4 loopback.");
|
|
917
|
-
}
|
|
918
|
-
let authorizationAvailable = true;
|
|
919
|
-
return {
|
|
920
|
-
endpoint: `ws://127.0.0.1:${address.port}/cdp`,
|
|
921
|
-
consumeClientAuthorization() {
|
|
922
|
-
if (!authorizationAvailable)
|
|
923
|
-
throw new Error("Chrome relay authorization handoff already consumed.");
|
|
924
|
-
authorizationAvailable = false;
|
|
925
|
-
return clientAuthorization;
|
|
926
|
-
},
|
|
927
|
-
async close() {
|
|
928
|
-
if (closed)
|
|
929
|
-
return;
|
|
930
|
-
closed = true;
|
|
931
|
-
options.upstream.socket.off("close", onUpstreamClose);
|
|
932
|
-
closeUpstream(options.upstream.socket);
|
|
933
|
-
await closeServer(server, sockets);
|
|
934
|
-
}
|
|
935
|
-
};
|
|
936
|
-
}
|
|
937
|
-
function isValidDownstreamUpgrade(request, expectedAuthorization) {
|
|
938
|
-
if (request.url !== "/cdp" || request.method !== "GET" || request.headers.upgrade?.toLowerCase() !== "websocket" || !hasToken(request.headers.connection, "upgrade") || request.headers["sec-websocket-version"] !== "13" || countRawHeader(request, "authorization") !== 1 || countRawHeader(request, "sec-websocket-key") !== 1 || !safeHeaderEqual(request.headers.authorization, expectedAuthorization)) {
|
|
939
|
-
return false;
|
|
940
|
-
}
|
|
941
|
-
const key = request.headers["sec-websocket-key"];
|
|
942
|
-
if (typeof key !== "string" || !/^[A-Za-z0-9+/]{22}==$/u.test(key))
|
|
943
|
-
return false;
|
|
944
|
-
const decoded = Buffer.from(key, "base64");
|
|
945
|
-
return decoded.byteLength === 16 && decoded.toString("base64") === key;
|
|
946
|
-
}
|
|
947
|
-
function countRawHeader(request, expectedName) {
|
|
948
|
-
let count = 0;
|
|
949
|
-
for (let index = 0; index < request.rawHeaders.length; index += 2) {
|
|
950
|
-
if (request.rawHeaders[index]?.toLowerCase() === expectedName)
|
|
951
|
-
count += 1;
|
|
952
|
-
}
|
|
953
|
-
return count;
|
|
954
|
-
}
|
|
955
|
-
function safeHeaderEqual(actual, expected) {
|
|
956
|
-
if (!actual)
|
|
957
|
-
return false;
|
|
958
|
-
const actualBytes = Buffer.from(actual);
|
|
959
|
-
const expectedBytes = Buffer.from(expected);
|
|
960
|
-
return actualBytes.length === expectedBytes.length && timingSafeEqual(actualBytes, expectedBytes);
|
|
961
|
-
}
|
|
962
|
-
function hasToken(value, expected) {
|
|
963
|
-
return Boolean(value?.split(",").some((token) => token.trim().toLowerCase() === expected));
|
|
964
|
-
}
|
|
965
|
-
function trackSocket(sockets, socket) {
|
|
966
|
-
if (sockets.has(socket))
|
|
967
|
-
return;
|
|
968
|
-
sockets.add(socket);
|
|
969
|
-
socket.once("close", () => sockets.delete(socket));
|
|
970
|
-
}
|
|
971
|
-
function closeUpstream(socket) {
|
|
972
|
-
if (socket.destroyed)
|
|
973
|
-
return;
|
|
974
|
-
if (!socket.remoteAddress) {
|
|
975
|
-
socket.destroy();
|
|
976
|
-
return;
|
|
977
|
-
}
|
|
978
|
-
try {
|
|
979
|
-
socket.resetAndDestroy();
|
|
980
|
-
} catch {
|
|
981
|
-
socket.destroy();
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
async function closeServer(server, sockets) {
|
|
985
|
-
for (const socket of sockets)
|
|
986
|
-
socket.destroy();
|
|
987
|
-
if (!server.listening)
|
|
988
|
-
return;
|
|
989
|
-
await new Promise((resolve) => server.close(() => resolve()));
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
// node_modules/.pnpm/mcporter@0.13.10/node_modules/mcporter/dist/browser-relay-auth-v2.js
|
|
993
|
-
import { createHmac, hash, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
994
|
-
var BROWSER_RELAY_AUTH_LABEL = "openclaw.browser-relay.auth";
|
|
995
|
-
var BROWSER_RELAY_AUTH_VERSION = 2;
|
|
996
|
-
var BROWSER_RELAY_CHALLENGE_MAX_LIFETIME_MS = 1e4;
|
|
997
|
-
var BROWSER_RELAY_CLOCK_SKEW_MS = 3e4;
|
|
998
|
-
var BROWSER_RELAY_AUTH_CHALLENGE_PATH = "/_openclaw/relay/auth/v2/challenge";
|
|
999
|
-
var BROWSER_RELAY_AUTH_COMPLETE_PATH = "/_openclaw/relay/auth/v2/complete";
|
|
1000
|
-
var BROWSER_RELAY_CDP_PATH = "/cdp";
|
|
1001
|
-
var BROWSER_RELAY_CDP_ROLE = "cdp";
|
|
1002
|
-
var BROWSER_RELAY_CDP_TRANSPORT = "connection";
|
|
1003
|
-
var BROWSER_RELAY_CDP_METHOD = "SEQUENCE";
|
|
1004
|
-
var BROWSER_RELAY_CDP_RESOURCE = "/json/version -> /cdp";
|
|
1005
|
-
var BROWSER_RELAY_CDP_FLOW = "cdp";
|
|
1006
|
-
var BROWSER_RELAY_VERSION_PATH = "/json/version";
|
|
1007
|
-
function deriveBrowserRelayKeyId(key) {
|
|
1008
|
-
assertRelayKey(key);
|
|
1009
|
-
return hash("sha256", key, "base64url").slice(0, 22);
|
|
1010
|
-
}
|
|
1011
|
-
function canonicalizeBrowserRelayProof(proofKind, fields, clientProof) {
|
|
1012
|
-
const canonical = [
|
|
1013
|
-
BROWSER_RELAY_AUTH_LABEL,
|
|
1014
|
-
BROWSER_RELAY_AUTH_VERSION,
|
|
1015
|
-
proofKind,
|
|
1016
|
-
fields.keyId,
|
|
1017
|
-
fields.instanceId,
|
|
1018
|
-
fields.sessionId,
|
|
1019
|
-
fields.clientNonce,
|
|
1020
|
-
fields.serverNonce,
|
|
1021
|
-
fields.issuedAtMs,
|
|
1022
|
-
fields.expiresAtMs,
|
|
1023
|
-
fields.role,
|
|
1024
|
-
fields.transport,
|
|
1025
|
-
fields.method,
|
|
1026
|
-
fields.resource,
|
|
1027
|
-
fields.flow
|
|
1028
|
-
];
|
|
1029
|
-
if (proofKind === "accept") {
|
|
1030
|
-
if (!clientProof || !isCanonicalBase64Url(clientProof, 32)) {
|
|
1031
|
-
throw new Error("Browser relay accept proof requires a 32-byte client proof.");
|
|
1032
|
-
}
|
|
1033
|
-
canonical.push(clientProof);
|
|
1034
|
-
} else if (clientProof !== void 0) {
|
|
1035
|
-
throw new Error("Browser relay client proof is only valid for an accept proof.");
|
|
1036
|
-
}
|
|
1037
|
-
return Buffer.from(JSON.stringify(canonical), "utf8");
|
|
1038
|
-
}
|
|
1039
|
-
function createBrowserRelayProof(key, proofKind, fields, clientProof) {
|
|
1040
|
-
assertRelayKey(key);
|
|
1041
|
-
return createHmac("sha256", key).update(canonicalizeBrowserRelayProof(proofKind, fields, clientProof)).digest("base64url");
|
|
1042
|
-
}
|
|
1043
|
-
function verifyBrowserRelayProof(key, proofKind, fields, proof, clientProof) {
|
|
1044
|
-
if (!isCanonicalBase64Url(proof, 32))
|
|
1045
|
-
return false;
|
|
1046
|
-
const actual = Buffer.from(proof, "base64url");
|
|
1047
|
-
const expected = Buffer.from(createBrowserRelayProof(key, proofKind, fields, clientProof), "base64url");
|
|
1048
|
-
return actual.byteLength === expected.byteLength && timingSafeEqual2(actual, expected);
|
|
1049
|
-
}
|
|
1050
|
-
function assertRelayKey(key) {
|
|
1051
|
-
if (key.byteLength !== 32)
|
|
1052
|
-
throw new Error("Browser relay key must contain 32 bytes.");
|
|
1053
|
-
}
|
|
1054
|
-
function isCanonicalBase64Url(value, bytes) {
|
|
1055
|
-
if (!/^[A-Za-z0-9_-]+$/u.test(value))
|
|
1056
|
-
return false;
|
|
1057
|
-
const decoded = Buffer.from(value, "base64url");
|
|
1058
|
-
return decoded.byteLength === bytes && decoded.toString("base64url") === value;
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
// node_modules/.pnpm/mcporter@0.13.10/node_modules/mcporter/dist/chrome-devtools-relay-client.js
|
|
1062
|
-
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
1063
|
-
import { lookup } from "node:dns/promises";
|
|
1064
|
-
import net from "node:net";
|
|
1065
|
-
import { TextDecoder } from "node:util";
|
|
1066
|
-
var MAX_HEADER_BYTES = 16 * 1024;
|
|
1067
|
-
var MAX_JSON_BYTES = 64 * 1024;
|
|
1068
|
-
var WEBSOCKET_GUID2 = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
1069
|
-
var RelayV2Error = class extends Error {
|
|
1070
|
-
reason;
|
|
1071
|
-
status;
|
|
1072
|
-
constructor(reason, status) {
|
|
1073
|
-
super(`Chrome relay authentication failed (${reason}).`);
|
|
1074
|
-
this.reason = reason;
|
|
1075
|
-
this.status = status;
|
|
1076
|
-
this.name = "RelayV2Error";
|
|
1077
|
-
}
|
|
1078
|
-
};
|
|
1079
|
-
async function connectChromeDevtoolsRelayV2(options) {
|
|
1080
|
-
const startedAt = performance.now();
|
|
1081
|
-
const durationMs = () => Math.max(0, Math.round(performance.now() - startedAt));
|
|
1082
|
-
let socket;
|
|
1083
|
-
let timer;
|
|
1084
|
-
try {
|
|
1085
|
-
let timedOut = false;
|
|
1086
|
-
const timeout = new Promise((_resolve, reject) => {
|
|
1087
|
-
timer = setTimeout(() => {
|
|
1088
|
-
timedOut = true;
|
|
1089
|
-
const error = new RelayV2Error("timeout");
|
|
1090
|
-
socket?.destroy(error);
|
|
1091
|
-
reject(error);
|
|
1092
|
-
}, options.timeoutMs);
|
|
1093
|
-
});
|
|
1094
|
-
timer?.unref();
|
|
1095
|
-
const addresses = await Promise.race([
|
|
1096
|
-
resolveLoopbackAddresses(options.baseUrl.hostname, options.resolve ?? lookup),
|
|
1097
|
-
timeout
|
|
1098
|
-
]);
|
|
1099
|
-
const port = resolvePort(options.baseUrl);
|
|
1100
|
-
let lastConnectionError;
|
|
1101
|
-
for (const address of addresses) {
|
|
1102
|
-
socket = net.createConnection({ host: address.address, family: address.family, port });
|
|
1103
|
-
try {
|
|
1104
|
-
await waitForConnect(socket);
|
|
1105
|
-
lastConnectionError = void 0;
|
|
1106
|
-
break;
|
|
1107
|
-
} catch (error) {
|
|
1108
|
-
socket.destroy();
|
|
1109
|
-
if (timedOut || isTimeoutError(error))
|
|
1110
|
-
throw new RelayV2Error("timeout");
|
|
1111
|
-
lastConnectionError = error;
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
if (lastConnectionError)
|
|
1115
|
-
throw lastConnectionError;
|
|
1116
|
-
if (!socket || socket.destroyed)
|
|
1117
|
-
throw new RelayV2Error(timedOut ? "timeout" : "network-error");
|
|
1118
|
-
if (!socket.remoteAddress || !isNumericLoopback(socket.remoteAddress))
|
|
1119
|
-
throw new RelayV2Error("protocol");
|
|
1120
|
-
const reader = new SocketReader(socket);
|
|
1121
|
-
const flow = options.flow ?? "cdp";
|
|
1122
|
-
const clientNonce = randomBytes2(32).toString("base64url");
|
|
1123
|
-
const hello = {
|
|
1124
|
-
v: BROWSER_RELAY_AUTH_VERSION,
|
|
1125
|
-
keyId: options.credential.keyId,
|
|
1126
|
-
clientNonce,
|
|
1127
|
-
role: BROWSER_RELAY_CDP_ROLE,
|
|
1128
|
-
transport: BROWSER_RELAY_CDP_TRANSPORT,
|
|
1129
|
-
method: flow === BROWSER_RELAY_CDP_FLOW ? BROWSER_RELAY_CDP_METHOD : "GET",
|
|
1130
|
-
resource: flow === BROWSER_RELAY_CDP_FLOW ? BROWSER_RELAY_CDP_RESOURCE : "/json/list",
|
|
1131
|
-
flow
|
|
1132
|
-
};
|
|
1133
|
-
await writeJsonRequest(socket, options.baseUrl.host, BROWSER_RELAY_AUTH_CHALLENGE_PATH, hello);
|
|
1134
|
-
const challengeResponse = await reader.readHttpResponse(MAX_JSON_BYTES);
|
|
1135
|
-
ensureAuthStatus(challengeResponse, "challenge");
|
|
1136
|
-
const challenge = parseStrictJsonObject(challengeResponse.body);
|
|
1137
|
-
const fields = validateChallenge(challenge, hello, options.now?.() ?? Date.now());
|
|
1138
|
-
const serverProof = requireString(challenge, "serverProof");
|
|
1139
|
-
if (!verifyBrowserRelayProof(options.credential.key, "server", fields, serverProof)) {
|
|
1140
|
-
throw new RelayV2Error("bad-server-proof");
|
|
1141
|
-
}
|
|
1142
|
-
const clientProof = createBrowserRelayProof(options.credential.key, "client", fields);
|
|
1143
|
-
await writeJsonRequest(socket, options.baseUrl.host, BROWSER_RELAY_AUTH_COMPLETE_PATH, {
|
|
1144
|
-
v: BROWSER_RELAY_AUTH_VERSION,
|
|
1145
|
-
sessionId: fields.sessionId,
|
|
1146
|
-
clientProof
|
|
1147
|
-
});
|
|
1148
|
-
const completeResponse = await reader.readHttpResponse(MAX_JSON_BYTES);
|
|
1149
|
-
ensureAuthStatus(completeResponse, "complete");
|
|
1150
|
-
const accepted = parseStrictJsonObject(completeResponse.body);
|
|
1151
|
-
validateAccept(accepted, fields.sessionId);
|
|
1152
|
-
if (!verifyBrowserRelayProof(options.credential.key, "accept", fields, requireString(accepted, "acceptProof"), clientProof)) {
|
|
1153
|
-
throw new RelayV2Error("bad-server-proof");
|
|
1154
|
-
}
|
|
1155
|
-
if (flow === "json-list") {
|
|
1156
|
-
await writeRequest(socket, options.baseUrl.host, "GET", "/json/list", []);
|
|
1157
|
-
const listResponse = await reader.readHttpResponse(MAX_JSON_BYTES, true);
|
|
1158
|
-
if (listResponse.status !== 200)
|
|
1159
|
-
throw classifyStatus(listResponse.status, true);
|
|
1160
|
-
const json = parseStrictJson(listResponse.body);
|
|
1161
|
-
if (!Array.isArray(json))
|
|
1162
|
-
throw new RelayV2Error("protocol", 200);
|
|
1163
|
-
socket.destroy();
|
|
1164
|
-
return { reason: "success", durationMs: durationMs(), status: 200, json };
|
|
1165
|
-
}
|
|
1166
|
-
await writeRequest(socket, options.baseUrl.host, "GET", BROWSER_RELAY_VERSION_PATH, []);
|
|
1167
|
-
const versionResponse = await reader.readHttpResponse(MAX_JSON_BYTES);
|
|
1168
|
-
if (versionResponse.status === 503) {
|
|
1169
|
-
socket.destroy();
|
|
1170
|
-
return { reason: "extension-disconnected", durationMs: durationMs(), status: 503 };
|
|
1171
|
-
}
|
|
1172
|
-
if (versionResponse.status !== 200)
|
|
1173
|
-
throw classifyStatus(versionResponse.status, true);
|
|
1174
|
-
parseStrictJsonObject(versionResponse.body);
|
|
1175
|
-
const websocketKey = randomBytes2(16).toString("base64");
|
|
1176
|
-
await writeRequest(socket, options.baseUrl.host, "GET", BROWSER_RELAY_CDP_PATH, [
|
|
1177
|
-
["Connection", "Upgrade"],
|
|
1178
|
-
["Upgrade", "websocket"],
|
|
1179
|
-
["Sec-WebSocket-Key", websocketKey],
|
|
1180
|
-
["Sec-WebSocket-Version", "13"]
|
|
1181
|
-
]);
|
|
1182
|
-
const upgrade = await reader.readHttpUpgrade();
|
|
1183
|
-
if (upgrade.status !== 101)
|
|
1184
|
-
throw classifyStatus(upgrade.status, true);
|
|
1185
|
-
const expectedAccept = createHash2("sha1").update(`${websocketKey}${WEBSOCKET_GUID2}`).digest("base64");
|
|
1186
|
-
if (upgrade.headers.get("upgrade")?.toLowerCase() !== "websocket" || !hasToken2(upgrade.headers.get("connection"), "upgrade") || upgrade.headers.get("sec-websocket-accept") !== expectedAccept) {
|
|
1187
|
-
throw new RelayV2Error("sequence", 101);
|
|
1188
|
-
}
|
|
1189
|
-
const head = reader.release();
|
|
1190
|
-
if (timer)
|
|
1191
|
-
clearTimeout(timer);
|
|
1192
|
-
return { reason: "success", durationMs: durationMs(), status: 200, upstream: { socket, head } };
|
|
1193
|
-
} catch (error) {
|
|
1194
|
-
socket?.destroy();
|
|
1195
|
-
if (error instanceof RelayV2Error) {
|
|
1196
|
-
return { reason: error.reason, durationMs: durationMs(), status: error.status };
|
|
1197
|
-
}
|
|
1198
|
-
return { reason: isTimeoutError(error) ? "timeout" : "network-error", durationMs: durationMs() };
|
|
1199
|
-
} finally {
|
|
1200
|
-
if (timer)
|
|
1201
|
-
clearTimeout(timer);
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
async function resolveLoopbackAddresses(hostname, resolver) {
|
|
1205
|
-
const normalized = hostname.replace(/^\[(.*)\]$/u, "$1");
|
|
1206
|
-
const addresses = await resolver(normalized, { all: true, verbatim: true });
|
|
1207
|
-
if (addresses.length === 0 || addresses.some((address) => !isNumericLoopback(address.address))) {
|
|
1208
|
-
throw new RelayV2Error("protocol");
|
|
1209
|
-
}
|
|
1210
|
-
return addresses;
|
|
1211
|
-
}
|
|
1212
|
-
function resolvePort(url) {
|
|
1213
|
-
const port = url.port === "" ? 80 : Number(url.port);
|
|
1214
|
-
if (!Number.isSafeInteger(port) || port < 1 || port > 65535)
|
|
1215
|
-
throw new RelayV2Error("protocol");
|
|
1216
|
-
return port;
|
|
1217
|
-
}
|
|
1218
|
-
function isNumericLoopback(address) {
|
|
1219
|
-
if (net.isIPv4(address))
|
|
1220
|
-
return address.startsWith("127.");
|
|
1221
|
-
if (!net.isIPv6(address))
|
|
1222
|
-
return false;
|
|
1223
|
-
const normalized = address.toLowerCase();
|
|
1224
|
-
return normalized === "::1" || normalized.startsWith("::ffff:127.");
|
|
1225
|
-
}
|
|
1226
|
-
async function waitForConnect(socket) {
|
|
1227
|
-
await new Promise((resolve, reject) => {
|
|
1228
|
-
const onConnect = () => {
|
|
1229
|
-
cleanup();
|
|
1230
|
-
resolve();
|
|
1231
|
-
};
|
|
1232
|
-
const onError = (error) => {
|
|
1233
|
-
cleanup();
|
|
1234
|
-
reject(error);
|
|
1235
|
-
};
|
|
1236
|
-
const cleanup = () => {
|
|
1237
|
-
socket.off("connect", onConnect);
|
|
1238
|
-
socket.off("error", onError);
|
|
1239
|
-
};
|
|
1240
|
-
socket.once("connect", onConnect);
|
|
1241
|
-
socket.once("error", onError);
|
|
1242
|
-
});
|
|
1243
|
-
}
|
|
1244
|
-
var SocketReader = class {
|
|
1245
|
-
socket;
|
|
1246
|
-
buffered = Buffer.alloc(0);
|
|
1247
|
-
failure;
|
|
1248
|
-
ended = false;
|
|
1249
|
-
onData = (chunk) => {
|
|
1250
|
-
this.buffered = Buffer.concat([this.buffered, chunk]);
|
|
1251
|
-
};
|
|
1252
|
-
onError = (error) => {
|
|
1253
|
-
this.failure = error;
|
|
1254
|
-
};
|
|
1255
|
-
onClose = () => {
|
|
1256
|
-
this.ended = true;
|
|
1257
|
-
};
|
|
1258
|
-
constructor(socket) {
|
|
1259
|
-
this.socket = socket;
|
|
1260
|
-
socket.on("data", this.onData);
|
|
1261
|
-
socket.on("error", this.onError);
|
|
1262
|
-
socket.on("close", this.onClose);
|
|
1263
|
-
}
|
|
1264
|
-
async readHttpResponse(maxBodyBytes, allowConnectionClose = false) {
|
|
1265
|
-
const parsed = await this.readHeaders();
|
|
1266
|
-
if (parsed.status === 101)
|
|
1267
|
-
throw new RelayV2Error("protocol", 101);
|
|
1268
|
-
if (parsed.headers.has("transfer-encoding"))
|
|
1269
|
-
throw new RelayV2Error("protocol", parsed.status);
|
|
1270
|
-
if (!allowConnectionClose && parsed.status === 200 && hasToken2(parsed.headers.get("connection"), "close")) {
|
|
1271
|
-
throw new RelayV2Error("protocol", parsed.status);
|
|
1272
|
-
}
|
|
1273
|
-
const rawLength = parsed.headers.get("content-length");
|
|
1274
|
-
if (!rawLength || !/^\d+$/u.test(rawLength))
|
|
1275
|
-
throw new RelayV2Error("protocol", parsed.status);
|
|
1276
|
-
const length = Number(rawLength);
|
|
1277
|
-
if (!Number.isSafeInteger(length) || length > maxBodyBytes)
|
|
1278
|
-
throw new RelayV2Error("protocol", parsed.status);
|
|
1279
|
-
await this.waitForBytes(length);
|
|
1280
|
-
const body = this.buffered.subarray(0, length);
|
|
1281
|
-
this.buffered = this.buffered.subarray(length);
|
|
1282
|
-
if (this.buffered.length > 0)
|
|
1283
|
-
throw new RelayV2Error("protocol", parsed.status);
|
|
1284
|
-
return { ...parsed, body };
|
|
1285
|
-
}
|
|
1286
|
-
async readHttpUpgrade() {
|
|
1287
|
-
const parsed = await this.readHeaders();
|
|
1288
|
-
if (parsed.headers.has("transfer-encoding"))
|
|
1289
|
-
throw new RelayV2Error("protocol", parsed.status);
|
|
1290
|
-
if (parsed.status === 101) {
|
|
1291
|
-
if (parsed.headers.has("content-length"))
|
|
1292
|
-
throw new RelayV2Error("protocol", parsed.status);
|
|
1293
|
-
return { ...parsed, body: Buffer.alloc(0) };
|
|
1294
|
-
}
|
|
1295
|
-
const rawLength = parsed.headers.get("content-length");
|
|
1296
|
-
if (!rawLength || !/^\d+$/u.test(rawLength))
|
|
1297
|
-
throw new RelayV2Error("protocol", parsed.status);
|
|
1298
|
-
const length = Number(rawLength);
|
|
1299
|
-
if (!Number.isSafeInteger(length) || length > MAX_JSON_BYTES)
|
|
1300
|
-
throw new RelayV2Error("protocol", parsed.status);
|
|
1301
|
-
await this.waitForBytes(length);
|
|
1302
|
-
const body = this.buffered.subarray(0, length);
|
|
1303
|
-
this.buffered = this.buffered.subarray(length);
|
|
1304
|
-
if (this.buffered.length > 0)
|
|
1305
|
-
throw new RelayV2Error("protocol", parsed.status);
|
|
1306
|
-
return { ...parsed, body };
|
|
1307
|
-
}
|
|
1308
|
-
release() {
|
|
1309
|
-
this.socket.off("data", this.onData);
|
|
1310
|
-
this.socket.off("error", this.onError);
|
|
1311
|
-
this.socket.off("close", this.onClose);
|
|
1312
|
-
const head = this.buffered;
|
|
1313
|
-
this.buffered = Buffer.alloc(0);
|
|
1314
|
-
return head;
|
|
1315
|
-
}
|
|
1316
|
-
async readHeaders() {
|
|
1317
|
-
let boundary = this.buffered.indexOf("\r\n\r\n");
|
|
1318
|
-
while (boundary < 0) {
|
|
1319
|
-
if (this.buffered.length > MAX_HEADER_BYTES)
|
|
1320
|
-
throw new RelayV2Error("protocol");
|
|
1321
|
-
await this.waitForData();
|
|
1322
|
-
boundary = this.buffered.indexOf("\r\n\r\n");
|
|
1323
|
-
}
|
|
1324
|
-
if (boundary > MAX_HEADER_BYTES)
|
|
1325
|
-
throw new RelayV2Error("protocol");
|
|
1326
|
-
const raw = this.buffered.subarray(0, boundary).toString("latin1");
|
|
1327
|
-
this.buffered = this.buffered.subarray(boundary + 4);
|
|
1328
|
-
const lines = raw.split("\r\n");
|
|
1329
|
-
const statusLine = lines.shift();
|
|
1330
|
-
const match = /^HTTP\/1\.1 ([1-5]\d\d)(?: [\x20-\x7e]*)?$/u.exec(statusLine ?? "");
|
|
1331
|
-
if (!match)
|
|
1332
|
-
throw new RelayV2Error("protocol");
|
|
1333
|
-
const status = Number(match[1]);
|
|
1334
|
-
const headers = /* @__PURE__ */ new Map();
|
|
1335
|
-
for (const line of lines) {
|
|
1336
|
-
if (/^[ \t]/u.test(line))
|
|
1337
|
-
throw new RelayV2Error("protocol", status);
|
|
1338
|
-
const separator = line.indexOf(":");
|
|
1339
|
-
if (separator <= 0)
|
|
1340
|
-
throw new RelayV2Error("protocol", status);
|
|
1341
|
-
const name = line.slice(0, separator).toLowerCase();
|
|
1342
|
-
const value = line.slice(separator + 1).trim();
|
|
1343
|
-
if (!/^[!#$%&'*+.^_`|~0-9a-z-]+$/u.test(name) || value.includes("\0") || value.includes("\r") || value.includes("\n") || value.includes("\x7F")) {
|
|
1344
|
-
throw new RelayV2Error("protocol", status);
|
|
1345
|
-
}
|
|
1346
|
-
if (headers.has(name))
|
|
1347
|
-
throw new RelayV2Error("protocol", status);
|
|
1348
|
-
headers.set(name, value);
|
|
1349
|
-
}
|
|
1350
|
-
return { status, headers };
|
|
1351
|
-
}
|
|
1352
|
-
async waitForBytes(length) {
|
|
1353
|
-
while (this.buffered.length < length)
|
|
1354
|
-
await this.waitForData();
|
|
1355
|
-
}
|
|
1356
|
-
async waitForData() {
|
|
1357
|
-
if (this.failure)
|
|
1358
|
-
throw this.failure;
|
|
1359
|
-
if (this.ended)
|
|
1360
|
-
throw new RelayV2Error("network-error");
|
|
1361
|
-
await new Promise((resolve, reject) => {
|
|
1362
|
-
const onData = () => {
|
|
1363
|
-
cleanup();
|
|
1364
|
-
resolve();
|
|
1365
|
-
};
|
|
1366
|
-
const onError = (error) => {
|
|
1367
|
-
cleanup();
|
|
1368
|
-
reject(error);
|
|
1369
|
-
};
|
|
1370
|
-
const onClose = () => {
|
|
1371
|
-
cleanup();
|
|
1372
|
-
reject(new RelayV2Error("network-error"));
|
|
1373
|
-
};
|
|
1374
|
-
const cleanup = () => {
|
|
1375
|
-
this.socket.off("data", onData);
|
|
1376
|
-
this.socket.off("error", onError);
|
|
1377
|
-
this.socket.off("close", onClose);
|
|
1378
|
-
};
|
|
1379
|
-
this.socket.once("data", onData);
|
|
1380
|
-
this.socket.once("error", onError);
|
|
1381
|
-
this.socket.once("close", onClose);
|
|
1382
|
-
});
|
|
1383
|
-
}
|
|
1384
|
-
};
|
|
1385
|
-
async function writeJsonRequest(socket, host, pathname, body) {
|
|
1386
|
-
const encoded = Buffer.from(JSON.stringify(body), "utf8");
|
|
1387
|
-
await writeRequest(socket, host, "POST", pathname, [
|
|
1388
|
-
["Content-Type", "application/json"],
|
|
1389
|
-
["Content-Length", String(encoded.byteLength)]
|
|
1390
|
-
], encoded);
|
|
1391
|
-
}
|
|
1392
|
-
async function writeRequest(socket, host, method, pathname, headers, body) {
|
|
1393
|
-
const lines = [`${method} ${pathname} HTTP/1.1`, `Host: ${host}`, "Connection: keep-alive"];
|
|
1394
|
-
for (const [name, value] of headers) {
|
|
1395
|
-
if (name.toLowerCase() === "connection")
|
|
1396
|
-
lines[2] = `${name}: ${value}`;
|
|
1397
|
-
else
|
|
1398
|
-
lines.push(`${name}: ${value}`);
|
|
1399
|
-
}
|
|
1400
|
-
const head = Buffer.from(`${lines.join("\r\n")}\r
|
|
1401
|
-
\r
|
|
1402
|
-
`, "ascii");
|
|
1403
|
-
const output = body ? Buffer.concat([head, body]) : head;
|
|
1404
|
-
await new Promise((resolve, reject) => {
|
|
1405
|
-
socket.write(output, (error) => error ? reject(error) : resolve());
|
|
1406
|
-
});
|
|
1407
|
-
}
|
|
1408
|
-
function ensureAuthStatus(response, phase) {
|
|
1409
|
-
if (response.status === 200)
|
|
1410
|
-
return;
|
|
1411
|
-
if (phase === "challenge" && response.status === 401 && responseError(response) === "Relay auth challenge rejected") {
|
|
1412
|
-
throw new RelayV2Error("replay", response.status);
|
|
1413
|
-
}
|
|
1414
|
-
if (response.status === 409)
|
|
1415
|
-
throw new RelayV2Error("sequence", response.status);
|
|
1416
|
-
throw classifyStatus(response.status, false);
|
|
1417
|
-
}
|
|
1418
|
-
function classifyStatus(status, authenticated) {
|
|
1419
|
-
if (!authenticated && (status === 401 || status === 404 || status === 426)) {
|
|
1420
|
-
return new RelayV2Error("unsupported-auth", status);
|
|
1421
|
-
}
|
|
1422
|
-
if (!authenticated && status === 503)
|
|
1423
|
-
return new RelayV2Error("server-auth-failed", status);
|
|
1424
|
-
if (status === 408 || status === 410)
|
|
1425
|
-
return new RelayV2Error("freshness", status);
|
|
1426
|
-
if (status === 409)
|
|
1427
|
-
return new RelayV2Error("sequence", status);
|
|
1428
|
-
if (status === 412)
|
|
1429
|
-
return new RelayV2Error("sequence", status);
|
|
1430
|
-
return new RelayV2Error("protocol", status);
|
|
1431
|
-
}
|
|
1432
|
-
function responseError(response) {
|
|
1433
|
-
try {
|
|
1434
|
-
const value = parseStrictJsonObject(response.body);
|
|
1435
|
-
return typeof value.error === "string" ? value.error : void 0;
|
|
1436
|
-
} catch {
|
|
1437
|
-
return void 0;
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
function validateChallenge(value, hello, nowMs) {
|
|
1441
|
-
assertExactKeys(value, [
|
|
1442
|
-
"type",
|
|
1443
|
-
"v",
|
|
1444
|
-
"keyId",
|
|
1445
|
-
"instanceId",
|
|
1446
|
-
"sessionId",
|
|
1447
|
-
"clientNonce",
|
|
1448
|
-
"serverNonce",
|
|
1449
|
-
"issuedAtMs",
|
|
1450
|
-
"expiresAtMs",
|
|
1451
|
-
"role",
|
|
1452
|
-
"transport",
|
|
1453
|
-
"method",
|
|
1454
|
-
"resource",
|
|
1455
|
-
"flow",
|
|
1456
|
-
"serverProof"
|
|
1457
|
-
]);
|
|
1458
|
-
if (value.type !== "auth.challenge")
|
|
1459
|
-
throw new RelayV2Error("protocol");
|
|
1460
|
-
if (value.v !== BROWSER_RELAY_AUTH_VERSION)
|
|
1461
|
-
throw new RelayV2Error("protocol");
|
|
1462
|
-
for (const key of ["keyId", "clientNonce", "role", "transport", "method", "resource", "flow"]) {
|
|
1463
|
-
if (value[key] !== hello[key])
|
|
1464
|
-
throw new RelayV2Error("protocol");
|
|
1465
|
-
}
|
|
1466
|
-
const fields = {
|
|
1467
|
-
keyId: requireToken(value, "keyId", 22),
|
|
1468
|
-
instanceId: requireEncoded(value, "instanceId", 22),
|
|
1469
|
-
sessionId: requireEncoded(value, "sessionId", 22),
|
|
1470
|
-
clientNonce: requireEncoded(value, "clientNonce", 43),
|
|
1471
|
-
serverNonce: requireEncoded(value, "serverNonce", 43),
|
|
1472
|
-
issuedAtMs: requireInteger(value, "issuedAtMs"),
|
|
1473
|
-
expiresAtMs: requireInteger(value, "expiresAtMs"),
|
|
1474
|
-
role: requireString(value, "role"),
|
|
1475
|
-
transport: requireString(value, "transport"),
|
|
1476
|
-
method: requireString(value, "method"),
|
|
1477
|
-
resource: requireString(value, "resource"),
|
|
1478
|
-
flow: requireString(value, "flow")
|
|
1479
|
-
};
|
|
1480
|
-
requireEncoded(value, "serverProof", 43);
|
|
1481
|
-
const lifetime = fields.expiresAtMs - fields.issuedAtMs;
|
|
1482
|
-
if (lifetime <= 0 || lifetime > BROWSER_RELAY_CHALLENGE_MAX_LIFETIME_MS || fields.issuedAtMs - nowMs > BROWSER_RELAY_CLOCK_SKEW_MS || nowMs > fields.expiresAtMs) {
|
|
1483
|
-
throw new RelayV2Error("freshness");
|
|
1484
|
-
}
|
|
1485
|
-
return fields;
|
|
1486
|
-
}
|
|
1487
|
-
function validateAccept(value, sessionId) {
|
|
1488
|
-
assertExactKeys(value, ["type", "v", "sessionId", "acceptProof"]);
|
|
1489
|
-
if (value.type !== "auth.ok")
|
|
1490
|
-
throw new RelayV2Error("protocol");
|
|
1491
|
-
if (value.v !== BROWSER_RELAY_AUTH_VERSION || value.sessionId !== sessionId)
|
|
1492
|
-
throw new RelayV2Error("protocol");
|
|
1493
|
-
requireEncoded(value, "acceptProof", 43);
|
|
1494
|
-
}
|
|
1495
|
-
function parseStrictJsonObject(body) {
|
|
1496
|
-
const value = parseStrictJson(body);
|
|
1497
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
1498
|
-
throw new RelayV2Error("protocol");
|
|
1499
|
-
return value;
|
|
1500
|
-
}
|
|
1501
|
-
function parseStrictJson(body) {
|
|
1502
|
-
let source;
|
|
1503
|
-
try {
|
|
1504
|
-
source = new TextDecoder("utf-8", { fatal: true }).decode(body);
|
|
1505
|
-
} catch {
|
|
1506
|
-
throw new RelayV2Error("protocol");
|
|
1507
|
-
}
|
|
1508
|
-
const errors = [];
|
|
1509
|
-
const tree = parseTree(source, errors, { allowTrailingComma: false, disallowComments: true });
|
|
1510
|
-
if (!tree || errors.length > 0)
|
|
1511
|
-
throw new RelayV2Error("protocol");
|
|
1512
|
-
rejectDuplicateJsonKeys(tree);
|
|
1513
|
-
try {
|
|
1514
|
-
return JSON.parse(source);
|
|
1515
|
-
} catch {
|
|
1516
|
-
throw new RelayV2Error("protocol");
|
|
1517
|
-
}
|
|
1518
|
-
}
|
|
1519
|
-
function rejectDuplicateJsonKeys(node) {
|
|
1520
|
-
if (node.type === "object") {
|
|
1521
|
-
const keys = /* @__PURE__ */ new Set();
|
|
1522
|
-
for (const property of node.children ?? []) {
|
|
1523
|
-
const key = property.children?.[0]?.value;
|
|
1524
|
-
if (typeof key !== "string" || keys.has(key))
|
|
1525
|
-
throw new RelayV2Error("protocol");
|
|
1526
|
-
keys.add(key);
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
for (const child of node.children ?? [])
|
|
1530
|
-
rejectDuplicateJsonKeys(child);
|
|
1531
|
-
}
|
|
1532
|
-
function assertExactKeys(value, required) {
|
|
1533
|
-
const actual = Object.keys(value);
|
|
1534
|
-
if (actual.length !== required.length || required.some((key) => !Object.hasOwn(value, key))) {
|
|
1535
|
-
throw new RelayV2Error("protocol");
|
|
1536
|
-
}
|
|
1537
|
-
}
|
|
1538
|
-
function requireString(value, key) {
|
|
1539
|
-
const field = value[key];
|
|
1540
|
-
if (typeof field !== "string")
|
|
1541
|
-
throw new RelayV2Error("protocol");
|
|
1542
|
-
return field;
|
|
1543
|
-
}
|
|
1544
|
-
function requireEncoded(value, key, length) {
|
|
1545
|
-
const field = requireString(value, key);
|
|
1546
|
-
const bytes = length === 22 ? 16 : length === 43 ? 32 : 0;
|
|
1547
|
-
const decoded = Buffer.from(field, "base64url");
|
|
1548
|
-
if (bytes === 0 || field.length !== length || !/^[A-Za-z0-9_-]+$/u.test(field) || decoded.byteLength !== bytes || decoded.toString("base64url") !== field) {
|
|
1549
|
-
throw new RelayV2Error("protocol");
|
|
1550
|
-
}
|
|
1551
|
-
return field;
|
|
1552
|
-
}
|
|
1553
|
-
function requireToken(value, key, length) {
|
|
1554
|
-
const field = requireString(value, key);
|
|
1555
|
-
if (field.length !== length || !/^[A-Za-z0-9_-]+$/u.test(field))
|
|
1556
|
-
throw new RelayV2Error("protocol");
|
|
1557
|
-
return field;
|
|
1558
|
-
}
|
|
1559
|
-
function requireInteger(value, key) {
|
|
1560
|
-
const field = value[key];
|
|
1561
|
-
if (typeof field !== "number" || !Number.isSafeInteger(field))
|
|
1562
|
-
throw new RelayV2Error("protocol");
|
|
1563
|
-
return field;
|
|
1564
|
-
}
|
|
1565
|
-
function hasToken2(value, expected) {
|
|
1566
|
-
return Boolean(value?.split(",").some((token) => token.trim().toLowerCase() === expected));
|
|
1567
|
-
}
|
|
1568
|
-
function isTimeoutError(error) {
|
|
1569
|
-
return Boolean(error && typeof error === "object" && error.reason === "timeout");
|
|
1570
|
-
}
|
|
1571
|
-
|
|
1572
|
-
// node_modules/.pnpm/mcporter@0.13.10/node_modules/mcporter/dist/chrome-devtools-relay-discovery.js
|
|
1573
|
-
import { spawn } from "node:child_process";
|
|
1574
|
-
import { statSync } from "node:fs";
|
|
1575
|
-
import net2 from "node:net";
|
|
593
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/daemon/connection-identity.js
|
|
594
|
+
import { createHash } from "node:crypto";
|
|
595
|
+
import fs from "node:fs/promises";
|
|
1576
596
|
import path from "node:path";
|
|
1577
|
-
var OPENCLAW_CDP_ARGS = ["browser", "extension", "cdp", "--json"];
|
|
1578
|
-
var OPENCLAW_WINDOWS_COMMAND_SUFFIX = "browser extension cdp --json";
|
|
1579
|
-
var OPENCLAW_WINDOWS_DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD";
|
|
1580
|
-
var OPENCLAW_WINDOWS_TREE_KILL_TIMEOUT_MS = 1e3;
|
|
1581
|
-
var OPENCLAW_PROFILE_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
|
|
1582
|
-
var OPENCLAW_RELAY_DISCOVERY_MAX_OUTPUT_BYTES = 64 * 1024;
|
|
1583
|
-
var OPENCLAW_RELAY_DISCOVERY_ENV_KEYS = [
|
|
1584
|
-
"APPDATA",
|
|
1585
|
-
"COMSPEC",
|
|
1586
|
-
"ComSpec",
|
|
1587
|
-
"HOME",
|
|
1588
|
-
"HOMEDRIVE",
|
|
1589
|
-
"HOMEPATH",
|
|
1590
|
-
"LANG",
|
|
1591
|
-
"LC_ALL",
|
|
1592
|
-
"LOCALAPPDATA",
|
|
1593
|
-
"OPENCLAW_CONFIG_PATH",
|
|
1594
|
-
"OPENCLAW_GATEWAY_PORT",
|
|
1595
|
-
"OPENCLAW_HOME",
|
|
1596
|
-
"OPENCLAW_OAUTH_DIR",
|
|
1597
|
-
"OPENCLAW_PROFILE",
|
|
1598
|
-
"OPENCLAW_STATE_DIR",
|
|
1599
|
-
"PATH",
|
|
1600
|
-
"Path",
|
|
1601
|
-
"PATHEXT",
|
|
1602
|
-
"SYSTEMROOT",
|
|
1603
|
-
"SystemRoot",
|
|
1604
|
-
"TEMP",
|
|
1605
|
-
"TMP",
|
|
1606
|
-
"TMPDIR",
|
|
1607
|
-
"USERPROFILE",
|
|
1608
|
-
"WINDIR",
|
|
1609
|
-
"XDG_CONFIG_HOME",
|
|
1610
|
-
"XDG_STATE_HOME"
|
|
1611
|
-
];
|
|
1612
|
-
function normalizeOpenClawProfile(raw) {
|
|
1613
|
-
const profile = raw?.trim();
|
|
1614
|
-
if (!profile || profile.toLowerCase() === "default" || !OPENCLAW_PROFILE_PATTERN.test(profile)) {
|
|
1615
|
-
return void 0;
|
|
1616
|
-
}
|
|
1617
|
-
return profile;
|
|
1618
|
-
}
|
|
1619
|
-
async function discoverOpenClawRelayUrl(options) {
|
|
1620
|
-
const platform = options.platform ?? process.platform;
|
|
1621
|
-
const cwd = options.cwd ?? process.cwd();
|
|
1622
|
-
const filteredEnv = openClawDiscoveryEnvironment(options.env);
|
|
1623
|
-
const command = resolveOpenClawRelayDiscoveryCommandPlan(filteredEnv, platform, options.isFile, cwd);
|
|
1624
|
-
if (!command)
|
|
1625
|
-
return { reason: "unavailable" };
|
|
1626
|
-
const env = sanitizeOpenClawDiscoveryCommandEnvironment(filteredEnv, command, platform, cwd);
|
|
1627
|
-
const result = await (options.run ?? runOpenClawRelayDiscovery)({
|
|
1628
|
-
...command,
|
|
1629
|
-
env,
|
|
1630
|
-
timeoutMs: options.timeoutMs,
|
|
1631
|
-
maxOutputBytes: OPENCLAW_RELAY_DISCOVERY_MAX_OUTPUT_BYTES,
|
|
1632
|
-
shell: false
|
|
1633
|
-
});
|
|
1634
|
-
return validateDiscoveryCommandResult(result, options.keyId);
|
|
1635
|
-
}
|
|
1636
|
-
function runOpenClawRelayDiscovery(options, runtime = {}) {
|
|
1637
|
-
return new Promise((resolve) => {
|
|
1638
|
-
const child = (runtime.spawn ?? spawn)(options.executable, [...options.args], {
|
|
1639
|
-
cwd: options.cwd,
|
|
1640
|
-
env: options.env,
|
|
1641
|
-
shell: options.shell,
|
|
1642
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1643
|
-
windowsVerbatimArguments: options.platform === "win32",
|
|
1644
|
-
windowsHide: true
|
|
1645
|
-
});
|
|
1646
|
-
const stdout = [];
|
|
1647
|
-
let outputBytes = 0;
|
|
1648
|
-
let settled = false;
|
|
1649
|
-
let terminating = false;
|
|
1650
|
-
let timer;
|
|
1651
|
-
const finish = (result) => {
|
|
1652
|
-
if (settled)
|
|
1653
|
-
return;
|
|
1654
|
-
settled = true;
|
|
1655
|
-
if (timer)
|
|
1656
|
-
clearTimeout(timer);
|
|
1657
|
-
resolve(result);
|
|
1658
|
-
};
|
|
1659
|
-
const terminate = (kind) => {
|
|
1660
|
-
if (settled || terminating)
|
|
1661
|
-
return;
|
|
1662
|
-
terminating = true;
|
|
1663
|
-
child.stdout.destroy();
|
|
1664
|
-
child.stderr.destroy();
|
|
1665
|
-
const plan = createOpenClawRelayDiscoveryTerminationPlan(options, child.pid);
|
|
1666
|
-
const terminateProcessTree = runtime.terminateProcessTree ?? terminateOpenClawRelayDiscoveryProcessTree;
|
|
1667
|
-
let termination = Promise.resolve();
|
|
1668
|
-
if (plan) {
|
|
1669
|
-
try {
|
|
1670
|
-
termination = terminateProcessTree(plan, child);
|
|
1671
|
-
} catch {
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
void boundedTreeTermination(termination).finally(() => {
|
|
1675
|
-
child.unref();
|
|
1676
|
-
finish({ kind });
|
|
1677
|
-
});
|
|
1678
|
-
};
|
|
1679
|
-
const collect = (chunk, keep) => {
|
|
1680
|
-
if (settled || terminating)
|
|
1681
|
-
return;
|
|
1682
|
-
outputBytes += chunk.byteLength;
|
|
1683
|
-
if (outputBytes > options.maxOutputBytes) {
|
|
1684
|
-
terminate("overflow");
|
|
1685
|
-
return;
|
|
1686
|
-
}
|
|
1687
|
-
if (keep)
|
|
1688
|
-
stdout.push(chunk);
|
|
1689
|
-
};
|
|
1690
|
-
child.stdout.on("data", (chunk) => collect(chunk, true));
|
|
1691
|
-
child.stderr.on("data", (chunk) => collect(chunk, false));
|
|
1692
|
-
child.once("error", (error) => {
|
|
1693
|
-
if (!terminating)
|
|
1694
|
-
finish({ kind: classifyCommandError(error) });
|
|
1695
|
-
});
|
|
1696
|
-
child.once("close", (code) => {
|
|
1697
|
-
if (!terminating) {
|
|
1698
|
-
finish(code === 0 ? { kind: "success", stdout: Buffer.concat(stdout) } : { kind: "nonzero" });
|
|
1699
|
-
}
|
|
1700
|
-
});
|
|
1701
|
-
timer = setTimeout(() => terminate("timeout"), options.timeoutMs);
|
|
1702
|
-
timer.unref();
|
|
1703
|
-
});
|
|
1704
|
-
}
|
|
1705
|
-
function resolveOpenClawRelayDiscoveryCommandPlan(env, platform = process.platform, isFile = isRegularFile, cwd = process.cwd()) {
|
|
1706
|
-
if (platform !== "win32")
|
|
1707
|
-
return { executable: "openclaw", args: OPENCLAW_CDP_ARGS, platform };
|
|
1708
|
-
const executable = resolveWindowsCommandInterpreter(env);
|
|
1709
|
-
const openClawShim = resolveWindowsOpenClawShim(env, isFile, cwd);
|
|
1710
|
-
if (!executable || !openClawShim)
|
|
1711
|
-
return void 0;
|
|
1712
|
-
const taskkillExecutable = path.win32.join(path.win32.dirname(executable), "taskkill.exe");
|
|
1713
|
-
if (!isSafeWindowsSystemToolPath(taskkillExecutable, "taskkill.exe"))
|
|
1714
|
-
return void 0;
|
|
1715
|
-
return {
|
|
1716
|
-
executable,
|
|
1717
|
-
// The only variable bytes are the validated absolute shim path. No config,
|
|
1718
|
-
// profile, URL, metadata, or unresolved command name reaches cmd.exe.
|
|
1719
|
-
args: ["/d", "/s", "/c", `""${openClawShim}" ${OPENCLAW_WINDOWS_COMMAND_SUFFIX}"`],
|
|
1720
|
-
cwd: path.win32.dirname(openClawShim),
|
|
1721
|
-
platform,
|
|
1722
|
-
taskkillExecutable
|
|
1723
|
-
};
|
|
1724
|
-
}
|
|
1725
|
-
function resolveWindowsCommandInterpreter(env) {
|
|
1726
|
-
const systemRoot = env.SYSTEMROOT?.trim() || env.SystemRoot?.trim();
|
|
1727
|
-
const systemCmd = systemRoot && isSafeWindowsSystemRoot(systemRoot) ? path.win32.join(systemRoot, "System32", "cmd.exe") : void 0;
|
|
1728
|
-
const comSpec = env.COMSPEC?.trim() || env.ComSpec?.trim();
|
|
1729
|
-
if (comSpec && isSafeWindowsCmdPath(comSpec)) {
|
|
1730
|
-
const normalizedComSpec = path.win32.normalize(comSpec);
|
|
1731
|
-
if (systemCmd && normalizedComSpec.toLowerCase() === systemCmd.toLowerCase() || !systemCmd && isConventionalWindowsSystemCmd(normalizedComSpec)) {
|
|
1732
|
-
return normalizedComSpec;
|
|
1733
|
-
}
|
|
1734
|
-
}
|
|
1735
|
-
return systemCmd;
|
|
1736
|
-
}
|
|
1737
|
-
function resolveWindowsOpenClawShim(env, isFile, cwd) {
|
|
1738
|
-
const pathEntries = safeWindowsPathEntries(env.PATH ?? env.Path, cwd);
|
|
1739
|
-
const extensions = windowsPathExtensions(env.PATHEXT);
|
|
1740
|
-
for (const directory of pathEntries) {
|
|
1741
|
-
for (const extension of extensions) {
|
|
1742
|
-
if (extension.toLowerCase() !== ".cmd")
|
|
1743
|
-
continue;
|
|
1744
|
-
const candidate = path.win32.join(directory, `openclaw${extension}`);
|
|
1745
|
-
if (isSafeWindowsCommandPath(candidate) && isFile(candidate))
|
|
1746
|
-
return path.win32.normalize(candidate);
|
|
1747
|
-
}
|
|
1748
|
-
}
|
|
1749
|
-
return void 0;
|
|
1750
|
-
}
|
|
1751
|
-
function isSafeWindowsCmdPath(value) {
|
|
1752
|
-
return isSafeWindowsSystemToolPath(value, "cmd.exe");
|
|
1753
|
-
}
|
|
1754
|
-
function isSafeWindowsSystemToolPath(value, basename) {
|
|
1755
|
-
const parent = path.win32.dirname(value);
|
|
1756
|
-
const root = path.win32.dirname(parent);
|
|
1757
|
-
return isSafeWindowsCommandPath(value) && path.win32.basename(value).toLowerCase() === basename && path.win32.basename(parent).toLowerCase() === "system32" && ["windows", "winnt"].includes(path.win32.basename(root).toLowerCase());
|
|
1758
|
-
}
|
|
1759
|
-
function isSafeWindowsSystemRoot(value) {
|
|
1760
|
-
const basename = path.win32.basename(value).toLowerCase();
|
|
1761
|
-
return isSafeWindowsAbsolutePath(value) && basename !== "cmd.exe" && basename !== "system32";
|
|
1762
|
-
}
|
|
1763
|
-
function isConventionalWindowsSystemCmd(value) {
|
|
1764
|
-
const parent = path.win32.dirname(value);
|
|
1765
|
-
const root = path.win32.dirname(parent);
|
|
1766
|
-
return path.win32.basename(parent).toLowerCase() === "system32" && ["windows", "winnt"].includes(path.win32.basename(root).toLowerCase());
|
|
1767
|
-
}
|
|
1768
|
-
function isSafeWindowsAbsolutePath(value) {
|
|
1769
|
-
if (!/^[a-z]:[\\/]/i.test(value) || /["<>|?*]/u.test(value) || hasControlCharacter(value) || value.slice(2).includes(":")) {
|
|
1770
|
-
return false;
|
|
1771
|
-
}
|
|
1772
|
-
const segments = value.replaceAll("/", "\\").split("\\");
|
|
1773
|
-
return !segments.some((segment) => segment === "." || segment === "..");
|
|
1774
|
-
}
|
|
1775
|
-
function isSafeWindowsCommandPath(value) {
|
|
1776
|
-
return isSafeWindowsAbsolutePath(value) && !/["%&|<>^!]/u.test(value) && !hasControlCharacter(value);
|
|
1777
|
-
}
|
|
1778
|
-
function hasControlCharacter(value) {
|
|
1779
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
1780
|
-
if (value.charCodeAt(index) < 32)
|
|
1781
|
-
return true;
|
|
1782
|
-
}
|
|
1783
|
-
return false;
|
|
1784
|
-
}
|
|
1785
|
-
function safeWindowsPathEntries(value, excludedDirectory) {
|
|
1786
|
-
if (!value)
|
|
1787
|
-
return [];
|
|
1788
|
-
const excluded = excludedDirectory && isSafeWindowsCommandPath(excludedDirectory) ? path.win32.resolve(excludedDirectory).toLowerCase() : void 0;
|
|
1789
|
-
return value.split(";").map((entry) => entry.trim()).filter((entry) => entry !== "" && path.win32.isAbsolute(entry) && isSafeWindowsCommandPath(entry)).map((entry) => path.win32.resolve(entry)).filter((entry) => entry.toLowerCase() !== excluded);
|
|
1790
|
-
}
|
|
1791
|
-
function windowsPathExtensions(value) {
|
|
1792
|
-
const raw = value?.trim() || OPENCLAW_WINDOWS_DEFAULT_PATHEXT;
|
|
1793
|
-
return raw.split(";").map((extension) => extension.trim()).filter((extension) => /^\.[a-z0-9]+$/iu.test(extension));
|
|
1794
|
-
}
|
|
1795
|
-
function isRegularFile(candidate) {
|
|
1796
|
-
try {
|
|
1797
|
-
return statSync(candidate).isFile();
|
|
1798
|
-
} catch {
|
|
1799
|
-
return false;
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
function sanitizeOpenClawDiscoveryCommandEnvironment(env, command, platform, sourceCwd) {
|
|
1803
|
-
if (platform !== "win32")
|
|
1804
|
-
return env;
|
|
1805
|
-
const sanitized = { ...env };
|
|
1806
|
-
delete sanitized.ComSpec;
|
|
1807
|
-
delete sanitized.COMSPEC;
|
|
1808
|
-
sanitized.ComSpec = command.executable;
|
|
1809
|
-
const safePath = safeWindowsPathEntries(sanitized.PATH ?? sanitized.Path, sourceCwd).join(";");
|
|
1810
|
-
delete sanitized.Path;
|
|
1811
|
-
delete sanitized.PATH;
|
|
1812
|
-
if (safePath)
|
|
1813
|
-
sanitized.Path = safePath;
|
|
1814
|
-
const systemRoot = sanitized.SYSTEMROOT?.trim() || sanitized.SystemRoot?.trim();
|
|
1815
|
-
if (systemRoot && !isSafeWindowsSystemRoot(systemRoot)) {
|
|
1816
|
-
delete sanitized.SystemRoot;
|
|
1817
|
-
delete sanitized.SYSTEMROOT;
|
|
1818
|
-
}
|
|
1819
|
-
return sanitized;
|
|
1820
|
-
}
|
|
1821
|
-
function createOpenClawRelayDiscoveryTerminationPlan(options, pid) {
|
|
1822
|
-
if (!Number.isSafeInteger(pid) || !pid || pid <= 0)
|
|
1823
|
-
return void 0;
|
|
1824
|
-
if (options.platform !== "win32")
|
|
1825
|
-
return { kind: "posix-sigkill", pid, signal: "SIGKILL" };
|
|
1826
|
-
if (!options.taskkillExecutable || !isSafeWindowsSystemToolPath(options.taskkillExecutable, "taskkill.exe")) {
|
|
1827
|
-
return void 0;
|
|
1828
|
-
}
|
|
1829
|
-
return {
|
|
1830
|
-
kind: "windows-taskkill",
|
|
1831
|
-
pid,
|
|
1832
|
-
executable: options.taskkillExecutable,
|
|
1833
|
-
args: ["/PID", String(pid), "/T", "/F"],
|
|
1834
|
-
shell: false,
|
|
1835
|
-
windowsHide: true
|
|
1836
|
-
};
|
|
1837
|
-
}
|
|
1838
|
-
async function terminateOpenClawRelayDiscoveryProcessTree(plan, child) {
|
|
1839
|
-
if (plan.kind === "posix-sigkill") {
|
|
1840
|
-
try {
|
|
1841
|
-
child.kill(plan.signal);
|
|
1842
|
-
} catch {
|
|
1843
|
-
}
|
|
1844
|
-
return;
|
|
1845
|
-
}
|
|
1846
|
-
await new Promise((resolve) => {
|
|
1847
|
-
let killer;
|
|
1848
|
-
try {
|
|
1849
|
-
killer = spawn(plan.executable, [...plan.args], {
|
|
1850
|
-
shell: plan.shell,
|
|
1851
|
-
stdio: "ignore",
|
|
1852
|
-
windowsHide: plan.windowsHide
|
|
1853
|
-
});
|
|
1854
|
-
} catch {
|
|
1855
|
-
resolve();
|
|
1856
|
-
return;
|
|
1857
|
-
}
|
|
1858
|
-
let done = false;
|
|
1859
|
-
const finish = () => {
|
|
1860
|
-
if (done)
|
|
1861
|
-
return;
|
|
1862
|
-
done = true;
|
|
1863
|
-
clearTimeout(timer);
|
|
1864
|
-
resolve();
|
|
1865
|
-
};
|
|
1866
|
-
killer.once("error", finish);
|
|
1867
|
-
killer.once("close", finish);
|
|
1868
|
-
const timer = setTimeout(() => {
|
|
1869
|
-
try {
|
|
1870
|
-
killer.kill("SIGKILL");
|
|
1871
|
-
} catch {
|
|
1872
|
-
}
|
|
1873
|
-
finish();
|
|
1874
|
-
}, OPENCLAW_WINDOWS_TREE_KILL_TIMEOUT_MS);
|
|
1875
|
-
timer.unref();
|
|
1876
|
-
});
|
|
1877
|
-
}
|
|
1878
|
-
async function boundedTreeTermination(termination) {
|
|
1879
|
-
let timer;
|
|
1880
|
-
try {
|
|
1881
|
-
await Promise.race([
|
|
1882
|
-
termination.catch(() => void 0),
|
|
1883
|
-
new Promise((resolve) => {
|
|
1884
|
-
timer = setTimeout(resolve, OPENCLAW_WINDOWS_TREE_KILL_TIMEOUT_MS + 250);
|
|
1885
|
-
timer.unref();
|
|
1886
|
-
})
|
|
1887
|
-
]);
|
|
1888
|
-
} finally {
|
|
1889
|
-
if (timer)
|
|
1890
|
-
clearTimeout(timer);
|
|
1891
|
-
}
|
|
1892
|
-
}
|
|
1893
|
-
function classifyCommandError(error) {
|
|
1894
|
-
const details = error;
|
|
1895
|
-
if (details.code === "ENOENT")
|
|
1896
|
-
return "unavailable";
|
|
1897
|
-
if (details.code === "ETIMEDOUT" || details.killed === true)
|
|
1898
|
-
return "timeout";
|
|
1899
|
-
if (details.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER" || details.code === "ENOBUFS")
|
|
1900
|
-
return "overflow";
|
|
1901
|
-
return "nonzero";
|
|
1902
|
-
}
|
|
1903
|
-
function validateDiscoveryCommandResult(result, expectedKeyId) {
|
|
1904
|
-
if (result.kind !== "success")
|
|
1905
|
-
return { reason: result.kind };
|
|
1906
|
-
if (result.stdout.byteLength > OPENCLAW_RELAY_DISCOVERY_MAX_OUTPUT_BYTES)
|
|
1907
|
-
return { reason: "overflow" };
|
|
1908
|
-
const encoded = result.stdout.toString("utf8").trim();
|
|
1909
|
-
const parseErrors = [];
|
|
1910
|
-
const tree = parseTree(encoded, parseErrors, { allowTrailingComma: false, disallowComments: true });
|
|
1911
|
-
if (!tree || parseErrors.length > 0 || hasDuplicateObjectKeys(tree))
|
|
1912
|
-
return { reason: "malformed" };
|
|
1913
|
-
let metadata;
|
|
1914
|
-
try {
|
|
1915
|
-
metadata = JSON.parse(encoded);
|
|
1916
|
-
} catch {
|
|
1917
|
-
return { reason: "malformed" };
|
|
1918
|
-
}
|
|
1919
|
-
if (!isPlainObject(metadata) || !hasExactKeys(metadata, ["auth", "browserUrl", "wsEndpoint"])) {
|
|
1920
|
-
return { reason: "incompatible" };
|
|
1921
|
-
}
|
|
1922
|
-
if (!isPlainObject(metadata.auth) || !hasExactKeys(metadata.auth, [
|
|
1923
|
-
"challengeUrl",
|
|
1924
|
-
"completeUrl",
|
|
1925
|
-
"flow",
|
|
1926
|
-
"keyId",
|
|
1927
|
-
"label",
|
|
1928
|
-
"method",
|
|
1929
|
-
"resource",
|
|
1930
|
-
"role",
|
|
1931
|
-
"transport",
|
|
1932
|
-
"version"
|
|
1933
|
-
])) {
|
|
1934
|
-
return { reason: "incompatible" };
|
|
1935
|
-
}
|
|
1936
|
-
const browserUrl = parseBrowserUrl(metadata.browserUrl);
|
|
1937
|
-
if (!browserUrl)
|
|
1938
|
-
return { reason: "unsafe" };
|
|
1939
|
-
const wsEndpoint = parseWebSocketUrl(metadata.wsEndpoint);
|
|
1940
|
-
if (!wsEndpoint || wsEndpoint.host !== browserUrl.host)
|
|
1941
|
-
return { reason: "unsafe" };
|
|
1942
|
-
const auth = metadata.auth;
|
|
1943
|
-
if (auth.label !== BROWSER_RELAY_AUTH_LABEL || auth.version !== BROWSER_RELAY_AUTH_VERSION || auth.role !== BROWSER_RELAY_CDP_ROLE || auth.transport !== BROWSER_RELAY_CDP_TRANSPORT || auth.method !== BROWSER_RELAY_CDP_METHOD || auth.resource !== BROWSER_RELAY_CDP_RESOURCE || auth.flow !== BROWSER_RELAY_CDP_FLOW || auth.challengeUrl !== new URL(BROWSER_RELAY_AUTH_CHALLENGE_PATH, browserUrl).toString() || auth.completeUrl !== new URL(BROWSER_RELAY_AUTH_COMPLETE_PATH, browserUrl).toString()) {
|
|
1944
|
-
return { reason: "incompatible" };
|
|
1945
|
-
}
|
|
1946
|
-
if (auth.keyId !== expectedKeyId)
|
|
1947
|
-
return { reason: "key-id-mismatch" };
|
|
1948
|
-
return { reason: "success", url: browserUrl };
|
|
1949
|
-
}
|
|
1950
|
-
function parseBrowserUrl(value) {
|
|
1951
|
-
if (typeof value !== "string")
|
|
1952
|
-
return void 0;
|
|
1953
|
-
let url;
|
|
1954
|
-
try {
|
|
1955
|
-
url = new URL(value);
|
|
1956
|
-
} catch {
|
|
1957
|
-
return void 0;
|
|
1958
|
-
}
|
|
1959
|
-
if (url.protocol !== "http:" || !isLoopbackHostname(url.hostname) || url.username !== "" || url.password !== "" || !hasValidPort(url) || url.pathname !== "/" || url.search !== "" || url.hash !== "") {
|
|
1960
|
-
return void 0;
|
|
1961
|
-
}
|
|
1962
|
-
return new URL(url.origin);
|
|
1963
|
-
}
|
|
1964
|
-
function parseWebSocketUrl(value) {
|
|
1965
|
-
if (typeof value !== "string")
|
|
1966
|
-
return void 0;
|
|
1967
|
-
let url;
|
|
1968
|
-
try {
|
|
1969
|
-
url = new URL(value);
|
|
1970
|
-
} catch {
|
|
1971
|
-
return void 0;
|
|
1972
|
-
}
|
|
1973
|
-
if (url.protocol !== "ws:" || !isLoopbackHostname(url.hostname) || url.username !== "" || url.password !== "" || !hasValidPort(url) || url.pathname !== BROWSER_RELAY_CDP_PATH || url.search !== "" || url.hash !== "") {
|
|
1974
|
-
return void 0;
|
|
1975
|
-
}
|
|
1976
|
-
return url;
|
|
1977
|
-
}
|
|
1978
|
-
function isLoopbackHostname(hostname) {
|
|
1979
|
-
const normalized = hostname.replace(/^\[(.*)\]$/u, "$1").toLowerCase();
|
|
1980
|
-
if (normalized === "localhost" || normalized === "::1")
|
|
1981
|
-
return true;
|
|
1982
|
-
if (net2.isIPv4(normalized))
|
|
1983
|
-
return normalized.startsWith("127.");
|
|
1984
|
-
if (!net2.isIPv6(normalized))
|
|
1985
|
-
return false;
|
|
1986
|
-
return normalized.startsWith("::ffff:127.") || /^::ffff:7f[0-9a-f]{2}:[0-9a-f]{1,4}$/u.test(normalized);
|
|
1987
|
-
}
|
|
1988
|
-
function hasValidPort(url) {
|
|
1989
|
-
if (url.port === "")
|
|
1990
|
-
return true;
|
|
1991
|
-
const port = Number(url.port);
|
|
1992
|
-
return Number.isSafeInteger(port) && port >= 1 && port <= 65535;
|
|
1993
|
-
}
|
|
1994
|
-
function isPlainObject(value) {
|
|
1995
|
-
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
1996
|
-
}
|
|
1997
|
-
function hasExactKeys(value, expected) {
|
|
1998
|
-
const actual = Object.keys(value).toSorted();
|
|
1999
|
-
return actual.length === expected.length && actual.every((key, index) => key === expected[index]);
|
|
2000
|
-
}
|
|
2001
|
-
function hasDuplicateObjectKeys(node) {
|
|
2002
|
-
if (node.type === "object") {
|
|
2003
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2004
|
-
for (const property of node.children ?? []) {
|
|
2005
|
-
const key = property.children?.[0]?.value;
|
|
2006
|
-
if (typeof key !== "string" || seen.has(key))
|
|
2007
|
-
return true;
|
|
2008
|
-
seen.add(key);
|
|
2009
|
-
}
|
|
2010
|
-
}
|
|
2011
|
-
return (node.children ?? []).some(hasDuplicateObjectKeys);
|
|
2012
|
-
}
|
|
2013
|
-
function openClawDiscoveryEnvironment(env) {
|
|
2014
|
-
const filtered = Object.fromEntries(OPENCLAW_RELAY_DISCOVERY_ENV_KEYS.flatMap((key) => {
|
|
2015
|
-
const value = env[key];
|
|
2016
|
-
return value === void 0 ? [] : [[key, value]];
|
|
2017
|
-
}));
|
|
2018
|
-
const profile = normalizeOpenClawProfile(filtered.OPENCLAW_PROFILE);
|
|
2019
|
-
if (profile)
|
|
2020
|
-
filtered.OPENCLAW_PROFILE = profile;
|
|
2021
|
-
else
|
|
2022
|
-
delete filtered.OPENCLAW_PROFILE;
|
|
2023
|
-
return filtered;
|
|
2024
|
-
}
|
|
2025
|
-
|
|
2026
|
-
// node_modules/.pnpm/mcporter@0.13.10/node_modules/mcporter/dist/chrome-devtools-relay.js
|
|
2027
|
-
var DEFAULT_RELAY_PROBE_TIMEOUT_MS = 5e3;
|
|
2028
|
-
var MIN_RELAY_PROBE_TIMEOUT_MS = 100;
|
|
2029
|
-
var MAX_RELAY_PROBE_TIMEOUT_MS = 3e4;
|
|
2030
|
-
var DEFAULT_RELAY_URL = "http://127.0.0.1:18799";
|
|
2031
|
-
var DEFAULT_RELAY_IDENTITY_URL = new URL(DEFAULT_RELAY_URL).toString();
|
|
2032
|
-
var RELAY_DEPENDENCY_SENTINEL = "$MCPORTER_CHROME_RELAY_DEPENDENCY:";
|
|
2033
|
-
var RELAY_DISCOVERY_SENTINEL = "$MCPORTER_CHROME_RELAY_DISCOVERY:";
|
|
2034
|
-
var CHROME_DEVTOOLS_RELAY_RUNTIME_ENV_KEYS = [
|
|
2035
|
-
"MCPORTER_CHROME_DEVTOOLS_RELAY_POLICY",
|
|
2036
|
-
"MCPORTER_DISABLE_CHROME_DEVTOOLS_RELAY",
|
|
2037
|
-
"MCPORTER_CHROME_DEVTOOLS_RELAY_URL",
|
|
2038
|
-
"MCPORTER_CHROME_DEVTOOLS_RELAY_TIMEOUT_MS",
|
|
2039
|
-
...OPENCLAW_RELAY_DISCOVERY_ENV_KEYS
|
|
2040
|
-
];
|
|
2041
|
-
var ChromeDevtoolsRelayRequiredError = class extends Error {
|
|
2042
|
-
decision;
|
|
2043
|
-
constructor(decision) {
|
|
2044
|
-
super(`Chrome DevTools relay policy 'require' could not use the OpenClaw extension relay (${decision.reason}). No chrome-devtools-mcp process was launched.`);
|
|
2045
|
-
this.decision = decision;
|
|
2046
|
-
this.name = "ChromeDevtoolsRelayRequiredError";
|
|
2047
|
-
}
|
|
2048
|
-
};
|
|
2049
|
-
var lastDecisions = /* @__PURE__ */ new Map();
|
|
2050
|
-
function recordChromeDevtoolsRelayDecision(server, decision) {
|
|
2051
|
-
lastDecisions.set(server, decision);
|
|
2052
|
-
}
|
|
2053
|
-
function getChromeDevtoolsRelayDecision(server) {
|
|
2054
|
-
return lastDecisions.get(server);
|
|
2055
|
-
}
|
|
2056
|
-
function formatChromeDevtoolsRelayDecision(decision) {
|
|
2057
|
-
return JSON.stringify(decision);
|
|
2058
|
-
}
|
|
2059
|
-
function resolveChromeDevtoolsRelayProbeTimeoutMs(env = process.env) {
|
|
2060
|
-
const raw = env.MCPORTER_CHROME_DEVTOOLS_RELAY_TIMEOUT_MS?.trim();
|
|
2061
|
-
if (!raw || !/^\d+$/.test(raw))
|
|
2062
|
-
return DEFAULT_RELAY_PROBE_TIMEOUT_MS;
|
|
2063
|
-
const parsed = Number(raw);
|
|
2064
|
-
if (!Number.isSafeInteger(parsed) || parsed <= 0)
|
|
2065
|
-
return DEFAULT_RELAY_PROBE_TIMEOUT_MS;
|
|
2066
|
-
return Math.min(MAX_RELAY_PROBE_TIMEOUT_MS, Math.max(MIN_RELAY_PROBE_TIMEOUT_MS, parsed));
|
|
2067
|
-
}
|
|
2068
|
-
function resolveChromeDevtoolsRelayPolicy(configured, env = process.env) {
|
|
2069
|
-
if (env.MCPORTER_DISABLE_CHROME_DEVTOOLS_RELAY === "1")
|
|
2070
|
-
return "off";
|
|
2071
|
-
const raw = env.MCPORTER_CHROME_DEVTOOLS_RELAY_POLICY?.trim().toLowerCase();
|
|
2072
|
-
if (!raw)
|
|
2073
|
-
return configured ?? "prefer";
|
|
2074
|
-
if (raw === "off" || raw === "prefer" || raw === "require")
|
|
2075
|
-
return raw;
|
|
2076
|
-
throw new Error(`Invalid MCPORTER_CHROME_DEVTOOLS_RELAY_POLICY '${raw}'. Expected off, prefer, or require.`);
|
|
2077
|
-
}
|
|
2078
|
-
function isChromeDevtoolsAutoConnectCommand(command, args) {
|
|
2079
|
-
return resolveChromeDevtoolsAutoConnectCommand(command, args).enabled;
|
|
2080
|
-
}
|
|
2081
|
-
function explicitRelayBaseUrl(env) {
|
|
2082
|
-
const raw = env.MCPORTER_CHROME_DEVTOOLS_RELAY_URL?.trim();
|
|
2083
|
-
if (!raw)
|
|
2084
|
-
return { explicit: false };
|
|
2085
|
-
let url;
|
|
2086
|
-
try {
|
|
2087
|
-
url = new URL(raw);
|
|
2088
|
-
} catch {
|
|
2089
|
-
return { explicit: true };
|
|
2090
|
-
}
|
|
2091
|
-
if (url.protocol !== "http:" || !["127.0.0.1", "localhost", "[::1]", "::1"].includes(url.hostname) || url.username !== "" || url.password !== "" || url.search !== "" || url.hash !== "") {
|
|
2092
|
-
return { explicit: true };
|
|
2093
|
-
}
|
|
2094
|
-
return { explicit: true, url };
|
|
2095
|
-
}
|
|
2096
|
-
function resolveOpenClawCredentialDir(env) {
|
|
2097
|
-
const oauthOverride = env.OPENCLAW_OAUTH_DIR?.trim();
|
|
2098
|
-
if (oauthOverride)
|
|
2099
|
-
return resolveOpenClawPath(oauthOverride, env);
|
|
2100
|
-
const stateOverride = env.OPENCLAW_STATE_DIR?.trim();
|
|
2101
|
-
const profile = normalizeOpenClawProfile(env.OPENCLAW_PROFILE);
|
|
2102
|
-
const stateDir = stateOverride ? resolveOpenClawPath(stateOverride, env) : path2.join(resolveOpenClawHome(env), profile ? `.openclaw-${profile}` : ".openclaw");
|
|
2103
|
-
return path2.join(stateDir, "credentials");
|
|
2104
|
-
}
|
|
2105
|
-
function resolveOpenClawHome(env) {
|
|
2106
|
-
const override = env.OPENCLAW_HOME?.trim();
|
|
2107
|
-
const osHome = resolveOpenClawOsHome(env);
|
|
2108
|
-
if (!override)
|
|
2109
|
-
return osHome;
|
|
2110
|
-
if (override === "~")
|
|
2111
|
-
return osHome;
|
|
2112
|
-
if (override.startsWith("~/") || override.startsWith("~\\")) {
|
|
2113
|
-
return path2.resolve(osHome, override.slice(2));
|
|
2114
|
-
}
|
|
2115
|
-
return path2.resolve(override);
|
|
2116
|
-
}
|
|
2117
|
-
function resolveOpenClawOsHome(env) {
|
|
2118
|
-
for (const value of [env.HOME, env.USERPROFILE]) {
|
|
2119
|
-
const normalized = value?.trim();
|
|
2120
|
-
if (normalized && normalized !== "undefined" && normalized !== "null")
|
|
2121
|
-
return path2.resolve(normalized);
|
|
2122
|
-
}
|
|
2123
|
-
return os.homedir();
|
|
2124
|
-
}
|
|
2125
|
-
function resolveOpenClawPath(value, env) {
|
|
2126
|
-
if (value === "~")
|
|
2127
|
-
return resolveOpenClawHome(env);
|
|
2128
|
-
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
2129
|
-
return path2.resolve(resolveOpenClawHome(env), value.slice(2));
|
|
2130
|
-
}
|
|
2131
|
-
return path2.resolve(value);
|
|
2132
|
-
}
|
|
2133
|
-
function defaultReadCredential(env) {
|
|
2134
|
-
const secretPath = path2.join(resolveOpenClawCredentialDir(env), "browser-extension-relay.secret");
|
|
2135
|
-
return readCredentialPath(secretPath);
|
|
2136
|
-
}
|
|
2137
|
-
function readCredentialPath(secretPath) {
|
|
2138
|
-
let descriptor;
|
|
2139
|
-
try {
|
|
2140
|
-
descriptor = fs.openSync(secretPath, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
|
|
2141
|
-
} catch (error) {
|
|
2142
|
-
return { reason: isErrno(error, "ENOENT") ? "missing-credential" : "invalid-credential" };
|
|
2143
|
-
}
|
|
2144
|
-
try {
|
|
2145
|
-
const stat = fs.fstatSync(descriptor);
|
|
2146
|
-
if (!stat.isFile())
|
|
2147
|
-
return { reason: "invalid-credential" };
|
|
2148
|
-
if (process.platform !== "win32") {
|
|
2149
|
-
if ((stat.mode & 63) !== 0)
|
|
2150
|
-
return { reason: "invalid-credential" };
|
|
2151
|
-
if (typeof process.getuid === "function" && stat.uid !== process.getuid())
|
|
2152
|
-
return { reason: "invalid-credential" };
|
|
2153
|
-
}
|
|
2154
|
-
const encoded = fs.readFileSync(descriptor, "utf8").trim();
|
|
2155
|
-
if (!/^[0-9a-f]{64}$/.test(encoded))
|
|
2156
|
-
return { reason: "invalid-credential" };
|
|
2157
|
-
const key = Buffer.from(encoded, "hex");
|
|
2158
|
-
return { credential: { key, keyId: deriveBrowserRelayKeyId(key) } };
|
|
2159
|
-
} catch {
|
|
2160
|
-
return { reason: "invalid-credential" };
|
|
2161
|
-
} finally {
|
|
2162
|
-
fs.closeSync(descriptor);
|
|
2163
|
-
}
|
|
2164
|
-
}
|
|
2165
|
-
async function defaultConnect(baseUrl, credential, timeoutMs) {
|
|
2166
|
-
return await connectChromeDevtoolsRelayV2({ baseUrl, credential, timeoutMs });
|
|
2167
|
-
}
|
|
2168
|
-
async function rewriteChromeDevtoolsArgsForRelay(command, args, env = process.env, options = {}, configuredPolicy) {
|
|
2169
|
-
const relayEnv = selectChromeDevtoolsRelayRuntimeEnvironment(env);
|
|
2170
|
-
const eligible = isChromeDevtoolsAutoConnectCommand(command, args);
|
|
2171
|
-
if (!eligible) {
|
|
2172
|
-
const ambiguous = isAmbiguousChromeDevtoolsAutoConnectCommand(command, args);
|
|
2173
|
-
if (!ambiguous) {
|
|
2174
|
-
return decide({
|
|
2175
|
-
args,
|
|
2176
|
-
applied: false,
|
|
2177
|
-
decision: { route: "legacy", reason: "not-eligible", policy: configuredPolicy ?? "prefer" }
|
|
2178
|
-
}, options);
|
|
2179
|
-
}
|
|
2180
|
-
const ambiguousPolicy = resolveChromeDevtoolsRelayPolicy(configuredPolicy, relayEnv);
|
|
2181
|
-
if (ambiguousPolicy === "require") {
|
|
2182
|
-
return unavailableOrLegacy(args, ambiguousPolicy, "unsupported-command", void 0, options);
|
|
2183
|
-
}
|
|
2184
|
-
return decide({
|
|
2185
|
-
args,
|
|
2186
|
-
applied: false,
|
|
2187
|
-
decision: { route: "legacy", reason: "not-eligible", policy: ambiguousPolicy }
|
|
2188
|
-
}, options);
|
|
2189
|
-
}
|
|
2190
|
-
const policy = resolveChromeDevtoolsRelayPolicy(configuredPolicy, relayEnv);
|
|
2191
|
-
if (policy === "off") {
|
|
2192
|
-
return decide({ args, applied: false, decision: { route: "legacy", reason: "disabled", policy } }, options);
|
|
2193
|
-
}
|
|
2194
|
-
const explicitBase = explicitRelayBaseUrl(relayEnv);
|
|
2195
|
-
if (explicitBase.explicit && !explicitBase.url) {
|
|
2196
|
-
return unavailableOrLegacy(args, policy, "invalid-endpoint", void 0, options);
|
|
2197
|
-
}
|
|
2198
|
-
const loaded = options.readToken ? (() => {
|
|
2199
|
-
const encoded = options.readToken?.();
|
|
2200
|
-
if (!encoded)
|
|
2201
|
-
return { reason: "missing-credential" };
|
|
2202
|
-
if (!/^[0-9a-f]{64}$/u.test(encoded))
|
|
2203
|
-
return { reason: "invalid-credential" };
|
|
2204
|
-
const key = Buffer.from(encoded, "hex");
|
|
2205
|
-
return { credential: { key, keyId: deriveBrowserRelayKeyId(key) } };
|
|
2206
|
-
})() : defaultReadCredential(relayEnv);
|
|
2207
|
-
if (!loaded.credential) {
|
|
2208
|
-
const base = explicitBase.url ?? new URL(DEFAULT_RELAY_URL);
|
|
2209
|
-
const upstreamEndpoint = new URL("/cdp", base);
|
|
2210
|
-
upstreamEndpoint.protocol = "ws:";
|
|
2211
|
-
return unavailableOrLegacy(args, policy, loaded.reason ?? "invalid-credential", upstreamEndpoint.toString(), options);
|
|
2212
|
-
}
|
|
2213
|
-
const timeoutMs = resolveChromeDevtoolsRelayProbeTimeoutMs(relayEnv);
|
|
2214
|
-
try {
|
|
2215
|
-
const base = explicitBase.url ?? (await discoverOpenClawRelayUrl({
|
|
2216
|
-
env: relayEnv,
|
|
2217
|
-
keyId: loaded.credential.keyId,
|
|
2218
|
-
timeoutMs,
|
|
2219
|
-
run: options.discover,
|
|
2220
|
-
platform: options.discovery?.platform,
|
|
2221
|
-
isFile: options.discovery?.isFile,
|
|
2222
|
-
cwd: options.discovery?.cwd
|
|
2223
|
-
})).url ?? new URL(DEFAULT_RELAY_URL);
|
|
2224
|
-
const upstreamEndpoint = new URL("/cdp", base);
|
|
2225
|
-
upstreamEndpoint.protocol = "ws:";
|
|
2226
|
-
const endpoint = upstreamEndpoint.toString();
|
|
2227
|
-
let probe;
|
|
2228
|
-
try {
|
|
2229
|
-
probe = await (options.connect ?? defaultConnect)(base, loaded.credential, timeoutMs);
|
|
2230
|
-
} catch {
|
|
2231
|
-
return unavailableOrLegacy(args, policy, "network-error", endpoint, options);
|
|
2232
|
-
}
|
|
2233
|
-
const probeDetails = { probeDurationMs: probe.durationMs, probeStatus: probe.status };
|
|
2234
|
-
if (probe.reason !== "success" || !probe.upstream) {
|
|
2235
|
-
probe.upstream?.socket.destroy();
|
|
2236
|
-
const reason = probe.reason === "success" ? "protocol" : probe.reason;
|
|
2237
|
-
return unavailableOrLegacy(args, policy, reason, endpoint, options, probeDetails);
|
|
2238
|
-
}
|
|
2239
|
-
let proxy;
|
|
2240
|
-
try {
|
|
2241
|
-
proxy = await (options.startProxy ?? startChromeDevtoolsRelayProxy)({ upstream: probe.upstream });
|
|
2242
|
-
} catch {
|
|
2243
|
-
probe.upstream.socket.destroy();
|
|
2244
|
-
return unavailableOrLegacy(args, policy, "network-error", endpoint, options, probeDetails);
|
|
2245
|
-
}
|
|
2246
|
-
const rewritten = replaceChromeDevtoolsAutoConnectArgs(command, args, ["--wsEndpoint", proxy.endpoint]);
|
|
2247
|
-
try {
|
|
2248
|
-
return decide({
|
|
2249
|
-
args: rewritten,
|
|
2250
|
-
applied: true,
|
|
2251
|
-
endpoint: proxy.endpoint,
|
|
2252
|
-
proxy,
|
|
2253
|
-
decision: { route: "relay", reason: "success", policy, endpoint, ...probeDetails }
|
|
2254
|
-
}, options);
|
|
2255
|
-
} catch (error) {
|
|
2256
|
-
await proxy.close().catch(() => {
|
|
2257
|
-
});
|
|
2258
|
-
throw error;
|
|
2259
|
-
}
|
|
2260
|
-
} finally {
|
|
2261
|
-
loaded.credential.key.fill(0);
|
|
2262
|
-
}
|
|
2263
|
-
}
|
|
2264
|
-
function unavailableOrLegacy(args, policy, reason, endpoint, options, probe = {}) {
|
|
2265
|
-
const decision = {
|
|
2266
|
-
route: policy === "require" ? "unavailable" : "legacy",
|
|
2267
|
-
reason,
|
|
2268
|
-
policy,
|
|
2269
|
-
endpoint,
|
|
2270
|
-
...probe
|
|
2271
|
-
};
|
|
2272
|
-
options.onDecision?.(decision);
|
|
2273
|
-
if (policy === "require")
|
|
2274
|
-
throw new ChromeDevtoolsRelayRequiredError(decision);
|
|
2275
|
-
return { args, applied: false, decision };
|
|
2276
|
-
}
|
|
2277
|
-
function decide(result, options) {
|
|
2278
|
-
options.onDecision?.(result.decision);
|
|
2279
|
-
return result;
|
|
2280
|
-
}
|
|
2281
|
-
function resolveChromeDevtoolsRelayEnvironment(overrides, env = process.env) {
|
|
2282
|
-
return { ...env, ...resolveRelayDefinitionEnvOverrides(overrides, env) };
|
|
2283
|
-
}
|
|
2284
|
-
function selectChromeDevtoolsRelayRuntimeEnvironment(env) {
|
|
2285
|
-
return Object.fromEntries(CHROME_DEVTOOLS_RELAY_RUNTIME_ENV_KEYS.flatMap((key) => {
|
|
2286
|
-
const value = env[key];
|
|
2287
|
-
return value === void 0 ? [] : [[key, value]];
|
|
2288
|
-
}));
|
|
2289
|
-
}
|
|
2290
|
-
function sanitizeRelayIdentityEnvironment(env) {
|
|
2291
|
-
const selected = selectChromeDevtoolsRelayRuntimeEnvironment(env);
|
|
2292
|
-
if (selected.MCPORTER_CHROME_DEVTOOLS_RELAY_URL !== void 0) {
|
|
2293
|
-
const explicit = explicitRelayBaseUrl(selected);
|
|
2294
|
-
selected.MCPORTER_CHROME_DEVTOOLS_RELAY_URL = explicit.explicit ? explicit.url?.toString() ?? "invalid-endpoint" : "";
|
|
2295
|
-
}
|
|
2296
|
-
return selected;
|
|
2297
|
-
}
|
|
2298
|
-
function chromeDevtoolsRelayEnvironmentKeys(definitions, env = process.env) {
|
|
2299
|
-
const keys = /* @__PURE__ */ new Set();
|
|
2300
|
-
for (const definition of definitions) {
|
|
2301
|
-
if (definition.command.kind !== "stdio")
|
|
2302
|
-
continue;
|
|
2303
|
-
const commandValues = [definition.command.command, ...definition.command.args];
|
|
2304
|
-
const commandEnvironmentKeys = new Set(commandValues.flatMap(referencedEnvironmentVariables));
|
|
2305
|
-
const relevant = commandEnvironmentKeys.size > 0 || isChromeDevtoolsAutoConnectCommand(definition.command.command, definition.command.args) || isAmbiguousChromeDevtoolsAutoConnectCommand(definition.command.command, definition.command.args);
|
|
2306
|
-
if (!relevant) {
|
|
2307
|
-
continue;
|
|
2308
|
-
}
|
|
2309
|
-
for (const key of commandEnvironmentKeys)
|
|
2310
|
-
keys.add(`${RELAY_DEPENDENCY_SENTINEL}${key}`);
|
|
2311
|
-
const resolvedDefinitionEnv = resolveRelayIdentityEnvOverrides(definition.env, env);
|
|
2312
|
-
for (const key of CHROME_DEVTOOLS_RELAY_RUNTIME_ENV_KEYS) {
|
|
2313
|
-
const override = definition.env?.[key];
|
|
2314
|
-
if (!override)
|
|
2315
|
-
continue;
|
|
2316
|
-
for (const referenced of referencedEnvironmentVariables(override))
|
|
2317
|
-
keys.add(`${RELAY_DEPENDENCY_SENTINEL}${referenced}`);
|
|
2318
|
-
}
|
|
2319
|
-
const resolvedCommand = resolveCommandArgument(definition.command.command, env);
|
|
2320
|
-
const resolvedArgs = resolveCommandArguments(definition.command.args, env);
|
|
2321
|
-
const eligible = isChromeDevtoolsAutoConnectCommand(resolvedCommand, resolvedArgs);
|
|
2322
|
-
if (!eligible && !isAmbiguousChromeDevtoolsAutoConnectCommand(resolvedCommand, resolvedArgs))
|
|
2323
|
-
continue;
|
|
2324
|
-
const environment = sanitizeRelayIdentityEnvironment(resolvedDefinitionEnv);
|
|
2325
|
-
keys.add(`${RELAY_DISCOVERY_SENTINEL}${Buffer.from(JSON.stringify({
|
|
2326
|
-
server: definition.name,
|
|
2327
|
-
eligible,
|
|
2328
|
-
environment,
|
|
2329
|
-
configuredPolicy: definition.chromeDevtoolsRelay
|
|
2330
|
-
}), "utf8").toString("base64url")}`);
|
|
2331
|
-
}
|
|
2332
|
-
return [...keys].toSorted();
|
|
2333
|
-
}
|
|
2334
|
-
async function resolveChromeDevtoolsRelayRuntimeIdentity(keys, env = process.env, options = {}) {
|
|
2335
|
-
const { values, relays } = relayEnvironmentIdentityValues(keys, env);
|
|
2336
|
-
for (const relay of relays) {
|
|
2337
|
-
let endpoint = relay.endpoint;
|
|
2338
|
-
if (relay.discover && relay.keyId !== "missing-credential" && relay.keyId !== "invalid-credential") {
|
|
2339
|
-
try {
|
|
2340
|
-
const discovered = await discoverOpenClawRelayUrl({
|
|
2341
|
-
env: relay.env,
|
|
2342
|
-
keyId: relay.keyId,
|
|
2343
|
-
timeoutMs: relay.timeoutMs,
|
|
2344
|
-
run: options.discover,
|
|
2345
|
-
platform: options.discovery?.platform,
|
|
2346
|
-
isFile: options.discovery?.isFile,
|
|
2347
|
-
cwd: options.discovery?.cwd
|
|
2348
|
-
});
|
|
2349
|
-
endpoint = discovered.url?.toString() ?? DEFAULT_RELAY_IDENTITY_URL;
|
|
2350
|
-
} catch {
|
|
2351
|
-
endpoint = DEFAULT_RELAY_IDENTITY_URL;
|
|
2352
|
-
}
|
|
2353
|
-
}
|
|
2354
|
-
values.push([relay.server, endpoint]);
|
|
2355
|
-
}
|
|
2356
|
-
return hashRelayIdentityValues(values);
|
|
2357
|
-
}
|
|
2358
|
-
function createRelayCredentialIdResolver() {
|
|
2359
|
-
const credentialIds = /* @__PURE__ */ new Map();
|
|
2360
|
-
return (credentialPath) => {
|
|
2361
|
-
const cached = credentialIds.get(credentialPath);
|
|
2362
|
-
if (cached)
|
|
2363
|
-
return cached;
|
|
2364
|
-
const loaded = readCredentialPath(credentialPath);
|
|
2365
|
-
const value = loaded.credential?.keyId ?? loaded.reason ?? "missing-credential";
|
|
2366
|
-
loaded.credential?.key.fill(0);
|
|
2367
|
-
credentialIds.set(credentialPath, value);
|
|
2368
|
-
return value;
|
|
2369
|
-
};
|
|
2370
|
-
}
|
|
2371
|
-
function relayEnvironmentIdentityValues(keys, env) {
|
|
2372
|
-
const credentialId = createRelayCredentialIdResolver();
|
|
2373
|
-
const values = [];
|
|
2374
|
-
const relays = [];
|
|
2375
|
-
for (const key of keys) {
|
|
2376
|
-
if (key.startsWith(RELAY_DEPENDENCY_SENTINEL)) {
|
|
2377
|
-
values.push([key, env[key.slice(RELAY_DEPENDENCY_SENTINEL.length)] ?? null]);
|
|
2378
|
-
continue;
|
|
2379
|
-
}
|
|
2380
|
-
if (!key.startsWith(RELAY_DISCOVERY_SENTINEL)) {
|
|
2381
|
-
values.push([key, relayEnvironmentIdentityValue(key, env)]);
|
|
2382
|
-
continue;
|
|
2383
|
-
}
|
|
2384
|
-
const payload = parseRelayDiscoveryIdentity(key.slice(RELAY_DISCOVERY_SENTINEL.length));
|
|
2385
|
-
if (!payload)
|
|
2386
|
-
throw new Error("Invalid Chrome DevTools relay identity metadata");
|
|
2387
|
-
const effectiveEnv = { ...selectChromeDevtoolsRelayRuntimeEnvironment(env), ...payload.environment };
|
|
2388
|
-
const policy = resolveChromeDevtoolsRelayPolicy(payload.configuredPolicy, effectiveEnv);
|
|
2389
|
-
const timeoutMs = resolveChromeDevtoolsRelayProbeTimeoutMs(effectiveEnv);
|
|
2390
|
-
const explicit = explicitRelayBaseUrl(effectiveEnv);
|
|
2391
|
-
const credentialDir = resolveOpenClawCredentialDir(effectiveEnv);
|
|
2392
|
-
const keyId = payload.eligible ? credentialId(path2.join(credentialDir, "browser-extension-relay.secret")) : "not-eligible";
|
|
2393
|
-
const server = `$relay:${payload.server}`;
|
|
2394
|
-
values.push([
|
|
2395
|
-
server,
|
|
2396
|
-
JSON.stringify({
|
|
2397
|
-
policy,
|
|
2398
|
-
timeoutMs,
|
|
2399
|
-
eligible: payload.eligible,
|
|
2400
|
-
credentialDir,
|
|
2401
|
-
keyId,
|
|
2402
|
-
// These values also reach the discovery subprocess; retain inputs whose equivalence it does not guarantee.
|
|
2403
|
-
discovery: OPENCLAW_RELAY_DISCOVERY_ENV_KEYS.map((name) => [
|
|
2404
|
-
name,
|
|
2405
|
-
relayEnvironmentIdentityValue(name, effectiveEnv)
|
|
2406
|
-
]),
|
|
2407
|
-
cwd: relayIdentityDependsOnCwd(effectiveEnv) ? process.cwd() : null
|
|
2408
|
-
})
|
|
2409
|
-
]);
|
|
2410
|
-
relays.push({
|
|
2411
|
-
server,
|
|
2412
|
-
env: effectiveEnv,
|
|
2413
|
-
timeoutMs,
|
|
2414
|
-
keyId,
|
|
2415
|
-
endpoint: policy === "off" ? "disabled" : explicit.explicit ? explicit.url?.toString() ?? "invalid-endpoint" : DEFAULT_RELAY_IDENTITY_URL,
|
|
2416
|
-
discover: payload.eligible && policy !== "off" && !explicit.explicit
|
|
2417
|
-
});
|
|
2418
|
-
}
|
|
2419
|
-
if (keys.length > 0)
|
|
2420
|
-
values.push(["$relayAuth", "v2-effective-metadata-discovery"]);
|
|
2421
|
-
return { values, relays };
|
|
2422
|
-
}
|
|
2423
|
-
function relayEnvironmentIdentityValue(key, env) {
|
|
2424
|
-
switch (key) {
|
|
2425
|
-
case "MCPORTER_CHROME_DEVTOOLS_RELAY_POLICY":
|
|
2426
|
-
case "MCPORTER_DISABLE_CHROME_DEVTOOLS_RELAY":
|
|
2427
|
-
return resolveChromeDevtoolsRelayPolicy(void 0, env);
|
|
2428
|
-
case "MCPORTER_CHROME_DEVTOOLS_RELAY_TIMEOUT_MS":
|
|
2429
|
-
return resolveChromeDevtoolsRelayProbeTimeoutMs(env);
|
|
2430
|
-
case "MCPORTER_CHROME_DEVTOOLS_RELAY_URL": {
|
|
2431
|
-
const explicit = explicitRelayBaseUrl(env);
|
|
2432
|
-
return explicit.explicit ? explicit.url?.toString() ?? "invalid-endpoint" : DEFAULT_RELAY_IDENTITY_URL;
|
|
2433
|
-
}
|
|
2434
|
-
case "OPENCLAW_PROFILE":
|
|
2435
|
-
return normalizeOpenClawProfile(env.OPENCLAW_PROFILE) ?? null;
|
|
2436
|
-
default:
|
|
2437
|
-
return env[key] ?? null;
|
|
2438
|
-
}
|
|
2439
|
-
}
|
|
2440
|
-
function relayIdentityDependsOnCwd(env) {
|
|
2441
|
-
const paths = [
|
|
2442
|
-
env.HOME,
|
|
2443
|
-
env.USERPROFILE,
|
|
2444
|
-
env.OPENCLAW_HOME,
|
|
2445
|
-
env.OPENCLAW_STATE_DIR,
|
|
2446
|
-
env.OPENCLAW_OAUTH_DIR,
|
|
2447
|
-
env.OPENCLAW_CONFIG_PATH,
|
|
2448
|
-
...(env.PATH ?? env.Path)?.split(path2.delimiter) ?? []
|
|
2449
|
-
];
|
|
2450
|
-
return paths.some((value) => value !== void 0 && !path2.isAbsolute(value) && !value.startsWith("~"));
|
|
2451
|
-
}
|
|
2452
|
-
function hashRelayIdentityValues(values) {
|
|
2453
|
-
return createHash3("sha256").update(JSON.stringify(values.toSorted((a, b) => a[0].localeCompare(b[0]) || JSON.stringify(a[1]).localeCompare(JSON.stringify(b[1]))))).digest("hex").slice(0, 16);
|
|
2454
|
-
}
|
|
2455
|
-
function parseRelayDiscoveryIdentity(encoded) {
|
|
2456
|
-
try {
|
|
2457
|
-
const value = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
2458
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
2459
|
-
return void 0;
|
|
2460
|
-
const candidate = value;
|
|
2461
|
-
if (typeof candidate.server !== "string" || typeof candidate.eligible !== "boolean" || !candidate.environment || typeof candidate.environment !== "object")
|
|
2462
|
-
return void 0;
|
|
2463
|
-
if (candidate.configuredPolicy !== void 0 && !["off", "prefer", "require"].includes(candidate.configuredPolicy))
|
|
2464
|
-
return void 0;
|
|
2465
|
-
const environment = {};
|
|
2466
|
-
for (const [key, raw] of Object.entries(candidate.environment)) {
|
|
2467
|
-
if (!CHROME_DEVTOOLS_RELAY_RUNTIME_ENV_KEYS.includes(key) || typeof raw !== "string")
|
|
2468
|
-
return void 0;
|
|
2469
|
-
environment[key] = raw;
|
|
2470
|
-
}
|
|
2471
|
-
return {
|
|
2472
|
-
server: candidate.server,
|
|
2473
|
-
eligible: candidate.eligible,
|
|
2474
|
-
environment,
|
|
2475
|
-
configuredPolicy: candidate.configuredPolicy
|
|
2476
|
-
};
|
|
2477
|
-
} catch {
|
|
2478
|
-
return void 0;
|
|
2479
|
-
}
|
|
2480
|
-
}
|
|
2481
|
-
function referencedEnvironmentVariables(value) {
|
|
2482
|
-
const names = /* @__PURE__ */ new Set();
|
|
2483
|
-
if (value.startsWith("$env:"))
|
|
2484
|
-
names.add(value.slice("$env:".length));
|
|
2485
|
-
for (const match of value.matchAll(/\$\{([A-Za-z_][A-Za-z0-9_]*)/gu)) {
|
|
2486
|
-
if (match[1])
|
|
2487
|
-
names.add(match[1]);
|
|
2488
|
-
}
|
|
2489
|
-
return [...names];
|
|
2490
|
-
}
|
|
2491
|
-
function resolveRelayDefinitionEnvOverrides(overrides, env) {
|
|
2492
|
-
const resolved = {};
|
|
2493
|
-
for (const [key, raw] of Object.entries(overrides ?? {})) {
|
|
2494
|
-
const value = resolveEnvValue(raw, env);
|
|
2495
|
-
if (value !== "")
|
|
2496
|
-
resolved[key] = value;
|
|
2497
|
-
}
|
|
2498
|
-
return resolved;
|
|
2499
|
-
}
|
|
2500
|
-
function resolveRelayIdentityEnvOverrides(overrides, env) {
|
|
2501
|
-
const relevant = Object.fromEntries(CHROME_DEVTOOLS_RELAY_RUNTIME_ENV_KEYS.flatMap((key) => {
|
|
2502
|
-
const value = overrides?.[key];
|
|
2503
|
-
return value === void 0 ? [] : [[key, value]];
|
|
2504
|
-
}));
|
|
2505
|
-
return resolveRelayDefinitionEnvOverrides(relevant, env);
|
|
2506
|
-
}
|
|
2507
|
-
function isErrno(error, code) {
|
|
2508
|
-
return Boolean(error && typeof error === "object" && error.code === code);
|
|
2509
|
-
}
|
|
2510
|
-
|
|
2511
|
-
// node_modules/.pnpm/mcporter@0.13.10/node_modules/mcporter/dist/daemon/connection-identity.js
|
|
2512
597
|
var BROKER_ENV = /* @__PURE__ */ new Set([
|
|
2513
598
|
"MCPORTER_DAEMON_DIR",
|
|
2514
599
|
"MCPORTER_DAEMON_CHILD",
|
|
@@ -2525,13 +610,13 @@ async function effectiveDefinition(definition, inherited = process.env, purpose
|
|
|
2525
610
|
const env = Object.fromEntries(Object.entries(resolveChromeDevtoolsRelayEnvironment(definition.env, inherited)).filter(([key, value]) => value !== void 0 && !BROKER_ENV.has(key)));
|
|
2526
611
|
const configuredEnv = Object.fromEntries(Object.keys(definition.env ?? {}).filter((key) => !BROKER_ENV.has(key)).map((key) => [key, env[key] ?? ""]));
|
|
2527
612
|
normalizeChromeEnvironment(definition, env);
|
|
2528
|
-
const chrome =
|
|
613
|
+
const chrome = isExistingChromeDefinition(definition, env);
|
|
2529
614
|
const launchCommand = definition.command.kind === "stdio" ? resolveCommandArgument(definition.command.command, env) : void 0;
|
|
2530
615
|
const command = definition.command.kind === "stdio" ? {
|
|
2531
616
|
...definition.command,
|
|
2532
617
|
command: chrome && purpose === "view" ? launchCommand : await resolveExecutable(launchCommand, env, definition.command.cwd),
|
|
2533
618
|
args: resolveCommandArguments(definition.command.args, env),
|
|
2534
|
-
cwd: await
|
|
619
|
+
cwd: await fs.realpath(definition.command.cwd)
|
|
2535
620
|
} : { ...definition.command, url: new URL(definition.command.url) };
|
|
2536
621
|
if (command.kind === "stdio") {
|
|
2537
622
|
if (!Object.hasOwn(configuredEnv, "PWD"))
|
|
@@ -2542,7 +627,7 @@ async function effectiveDefinition(definition, inherited = process.env, purpose
|
|
|
2542
627
|
return { ...definition, command, env, configuredEnv, ...chrome ? { launchCommand } : {} };
|
|
2543
628
|
}
|
|
2544
629
|
function normalizeChromeEnvironment(definition, env) {
|
|
2545
|
-
if (
|
|
630
|
+
if (isExistingChromeDefinition(definition, env)) {
|
|
2546
631
|
env.MCPORTER_CHROME_DEVTOOLS_RELAY_POLICY = resolveChromeDevtoolsRelayPolicy(definition.chromeDevtoolsRelay, env);
|
|
2547
632
|
env.MCPORTER_CHROME_DEVTOOLS_RELAY_TIMEOUT_MS = String(resolveChromeDevtoolsRelayProbeTimeoutMs(env));
|
|
2548
633
|
delete env.MCPORTER_DISABLE_CHROME_DEVTOOLS_RELAY;
|
|
@@ -2555,13 +640,13 @@ function normalizeChromeEnvironment(definition, env) {
|
|
|
2555
640
|
}
|
|
2556
641
|
}
|
|
2557
642
|
async function resolveExecutable(command, env, cwd) {
|
|
2558
|
-
const roots = /[/\\]/.test(command) ? [
|
|
2559
|
-
const extensions = process.platform === "win32" && !
|
|
643
|
+
const roots = /[/\\]/.test(command) ? [path.resolve(cwd, command)] : (env.PATH ?? env.Path ?? "").split(path.delimiter).map((dir) => path.resolve(cwd, dir, command));
|
|
644
|
+
const extensions = process.platform === "win32" && !path.extname(command) ? ["", ...(env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";")] : [""];
|
|
2560
645
|
const candidates = roots.flatMap((root) => extensions.map((extension) => root + extension));
|
|
2561
646
|
for (const candidate of candidates) {
|
|
2562
647
|
try {
|
|
2563
|
-
await
|
|
2564
|
-
return
|
|
648
|
+
await fs.access(candidate, fs.constants.X_OK);
|
|
649
|
+
return path.join(await fs.realpath(path.dirname(candidate)), path.basename(candidate));
|
|
2565
650
|
} catch {
|
|
2566
651
|
}
|
|
2567
652
|
}
|
|
@@ -2571,13 +656,13 @@ function connectionIdentity(definition) {
|
|
|
2571
656
|
const { name, description: _description, source: _source, sources: _sources, allowedTools: _allowed, blockedTools: _blocked, lifecycle: _lifecycle, configuredEnv: _configuredEnv, launchCommand: _launchCommand, logging: _logging, ...connection } = definition;
|
|
2572
657
|
const credentialOwner = definition.auth || definition.command.kind === "http" ? name : void 0;
|
|
2573
658
|
const env = { ...definition.env };
|
|
2574
|
-
const chrome =
|
|
659
|
+
const chrome = isExistingChromeDefinition(definition);
|
|
2575
660
|
if (chrome) {
|
|
2576
661
|
env.MCPORTER_CHROME_DEVTOOLS_RELAY_POLICY = resolveChromeDevtoolsRelayPolicy(definition.chromeDevtoolsRelay, env);
|
|
2577
662
|
delete env.MCPORTER_DISABLE_CHROME_DEVTOOLS_RELAY;
|
|
2578
663
|
env.MCPORTER_CHROME_DEVTOOLS_RELAY_TIMEOUT_MS = String(resolveChromeDevtoolsRelayProbeTimeoutMs(env));
|
|
2579
664
|
}
|
|
2580
|
-
return
|
|
665
|
+
return createHash("sha256").update(stableJsonStringify({
|
|
2581
666
|
...connection,
|
|
2582
667
|
env,
|
|
2583
668
|
credentialOwner,
|
|
@@ -2587,25 +672,30 @@ function connectionIdentity(definition) {
|
|
|
2587
672
|
chromeDevtoolsRelay: chrome ? env.MCPORTER_CHROME_DEVTOOLS_RELAY_POLICY : void 0
|
|
2588
673
|
})).digest("hex");
|
|
2589
674
|
}
|
|
2590
|
-
function
|
|
2591
|
-
|
|
675
|
+
function isExistingChromeDefinition(definition, env) {
|
|
676
|
+
if (definition.command.kind !== "stdio")
|
|
677
|
+
return false;
|
|
678
|
+
const effectiveEnv = env ?? resolveChromeDevtoolsRelayEnvironment(definition.env);
|
|
679
|
+
const command = resolveCommandArgument(definition.command.command, effectiveEnv);
|
|
680
|
+
const args = resolveCommandArguments(definition.command.args, effectiveEnv);
|
|
681
|
+
return [definition.name, command, ...args].some((value) => /chrome[-_]devtools(?:[-_]mcp)?/i.test(value)) && isExistingChromeDevtoolsCommand(command, args);
|
|
2592
682
|
}
|
|
2593
683
|
|
|
2594
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2595
|
-
import
|
|
2596
|
-
import
|
|
684
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/daemon/browser-owner.js
|
|
685
|
+
import os3 from "node:os";
|
|
686
|
+
import path4 from "node:path";
|
|
2597
687
|
|
|
2598
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2599
|
-
import
|
|
688
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/daemon/paths.js
|
|
689
|
+
import fs3 from "node:fs/promises";
|
|
2600
690
|
import { constants } from "node:fs";
|
|
2601
|
-
import { createHash as
|
|
691
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
2602
692
|
|
|
2603
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
693
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/chrome-devtools-relay-handoff.js
|
|
2604
694
|
import { spawnSync } from "node:child_process";
|
|
2605
|
-
import { randomBytes
|
|
2606
|
-
import
|
|
2607
|
-
import
|
|
2608
|
-
import
|
|
695
|
+
import { randomBytes } from "node:crypto";
|
|
696
|
+
import fs2 from "node:fs";
|
|
697
|
+
import os from "node:os";
|
|
698
|
+
import path2 from "node:path";
|
|
2609
699
|
import { pathToFileURL } from "node:url";
|
|
2610
700
|
var CHROME_RELAY_HANDOFF_ENV = "MCPORTER_CHROME_RELAY_HANDOFF_PATH";
|
|
2611
701
|
var HANDOFF_DIR_PREFIX = "mcporter-chrome-relay-";
|
|
@@ -2618,12 +708,12 @@ function createChromeDevtoolsRelayHandoff(env, clientAuthorization) {
|
|
|
2618
708
|
if (process.platform === "win32")
|
|
2619
709
|
directory = createWindowsHandoffDirectory();
|
|
2620
710
|
else {
|
|
2621
|
-
directory =
|
|
2622
|
-
|
|
711
|
+
directory = fs2.mkdtempSync(path2.join(os.tmpdir(), HANDOFF_DIR_PREFIX));
|
|
712
|
+
fs2.chmodSync(directory, 448);
|
|
2623
713
|
}
|
|
2624
714
|
assertSecurePath(directory, "directory");
|
|
2625
|
-
const handoffPath =
|
|
2626
|
-
const preloadPath =
|
|
715
|
+
const handoffPath = path2.join(directory, HANDOFF_FILENAME);
|
|
716
|
+
const preloadPath = path2.join(directory, PRELOAD_FILENAME);
|
|
2627
717
|
writeExclusiveFile(preloadPath, renderChromeDevtoolsRelayPreloadSource());
|
|
2628
718
|
writeExclusiveFile(handoffPath, JSON.stringify({ Authorization: clientAuthorization }));
|
|
2629
719
|
const importFlag = `--import=${pathToFileURL(preloadPath).href}`;
|
|
@@ -2646,13 +736,13 @@ function createChromeDevtoolsRelayHandoff(env, clientAuthorization) {
|
|
|
2646
736
|
};
|
|
2647
737
|
} catch (error) {
|
|
2648
738
|
if (directory)
|
|
2649
|
-
cleanupHandoff(directory,
|
|
739
|
+
cleanupHandoff(directory, path2.join(directory, HANDOFF_FILENAME), path2.join(directory, PRELOAD_FILENAME));
|
|
2650
740
|
const diagnostic = error instanceof Error && error.message.startsWith("Windows ACL setup failed:") ? ` ${error.message}` : "";
|
|
2651
741
|
throw new Error(`Unable to install secure Chrome relay authorization handoff.${diagnostic}`, { cause: error });
|
|
2652
742
|
}
|
|
2653
743
|
}
|
|
2654
744
|
function createWindowsHandoffDirectory() {
|
|
2655
|
-
const directory =
|
|
745
|
+
const directory = path2.join(os.tmpdir(), `${HANDOFF_DIR_PREFIX}${randomBytes(16).toString("hex")}`);
|
|
2656
746
|
ensureWindowsPrivateDirectory(directory);
|
|
2657
747
|
return directory;
|
|
2658
748
|
}
|
|
@@ -2697,7 +787,7 @@ if ($ruleSid -ne $sid.Value -or $rules[0].IsInherited -or -not $hasFullControl -
|
|
|
2697
787
|
if (result.status !== 0) {
|
|
2698
788
|
try {
|
|
2699
789
|
if (!allowExisting)
|
|
2700
|
-
|
|
790
|
+
fs2.rmdirSync(directory);
|
|
2701
791
|
} catch {
|
|
2702
792
|
}
|
|
2703
793
|
const stderr = typeof result.stderr === "string" ? result.stderr.trim() : "";
|
|
@@ -2707,27 +797,27 @@ if ($ruleSid -ne $sid.Value -or $rules[0].IsInherited -or -not $hasFullControl -
|
|
|
2707
797
|
}
|
|
2708
798
|
function resolveSystemPowerShellPath() {
|
|
2709
799
|
const systemRoot = process.env.SystemRoot?.trim() || process.env.WINDIR?.trim();
|
|
2710
|
-
if (!systemRoot || !
|
|
800
|
+
if (!systemRoot || !path2.win32.isAbsolute(systemRoot))
|
|
2711
801
|
throw new Error("unsafe Windows system root");
|
|
2712
|
-
const executable =
|
|
2713
|
-
const stat =
|
|
802
|
+
const executable = path2.win32.join(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
803
|
+
const stat = fs2.lstatSync(executable);
|
|
2714
804
|
if (!stat.isFile() || stat.isSymbolicLink())
|
|
2715
805
|
throw new Error("unsafe Windows PowerShell path");
|
|
2716
806
|
return executable;
|
|
2717
807
|
}
|
|
2718
808
|
function writeExclusiveFile(filePath, contents) {
|
|
2719
|
-
const descriptor =
|
|
809
|
+
const descriptor = fs2.openSync(filePath, fs2.constants.O_WRONLY | fs2.constants.O_CREAT | fs2.constants.O_EXCL | (fs2.constants.O_NOFOLLOW ?? 0), 384);
|
|
2720
810
|
try {
|
|
2721
811
|
if (process.platform !== "win32")
|
|
2722
|
-
|
|
2723
|
-
|
|
812
|
+
fs2.fchmodSync(descriptor, 384);
|
|
813
|
+
fs2.writeFileSync(descriptor, contents, "utf8");
|
|
2724
814
|
} finally {
|
|
2725
|
-
|
|
815
|
+
fs2.closeSync(descriptor);
|
|
2726
816
|
}
|
|
2727
817
|
assertSecurePath(filePath, "file");
|
|
2728
818
|
}
|
|
2729
819
|
function assertSecurePath(filePath, kind) {
|
|
2730
|
-
const stat =
|
|
820
|
+
const stat = fs2.lstatSync(filePath);
|
|
2731
821
|
if ((kind === "directory" ? !stat.isDirectory() : !stat.isFile()) || stat.isSymbolicLink())
|
|
2732
822
|
throw new Error("unsafe");
|
|
2733
823
|
if (process.platform === "win32")
|
|
@@ -2740,12 +830,12 @@ function assertSecurePath(filePath, kind) {
|
|
|
2740
830
|
function cleanupHandoff(directory, handoffPath, preloadPath) {
|
|
2741
831
|
for (const filePath of [handoffPath, preloadPath]) {
|
|
2742
832
|
try {
|
|
2743
|
-
|
|
833
|
+
fs2.unlinkSync(filePath);
|
|
2744
834
|
} catch {
|
|
2745
835
|
}
|
|
2746
836
|
}
|
|
2747
837
|
try {
|
|
2748
|
-
|
|
838
|
+
fs2.rmdirSync(directory);
|
|
2749
839
|
} catch {
|
|
2750
840
|
}
|
|
2751
841
|
}
|
|
@@ -2830,23 +920,23 @@ if (targetPath?.includes('chrome-devtools-mcp')) {
|
|
|
2830
920
|
`;
|
|
2831
921
|
}
|
|
2832
922
|
|
|
2833
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2834
|
-
import
|
|
2835
|
-
import
|
|
923
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/daemon/paths.js
|
|
924
|
+
import os2 from "node:os";
|
|
925
|
+
import path3 from "node:path";
|
|
2836
926
|
function daemonBaseDir() {
|
|
2837
927
|
const override = process.env.MCPORTER_DAEMON_DIR?.trim();
|
|
2838
928
|
if (override)
|
|
2839
|
-
return
|
|
2840
|
-
return
|
|
929
|
+
return path3.resolve(override);
|
|
930
|
+
return path3.join(os2.userInfo().homedir, ".mcporter");
|
|
2841
931
|
}
|
|
2842
932
|
function daemonRunDir() {
|
|
2843
|
-
return
|
|
933
|
+
return path3.join(daemonBaseDir(), "daemon");
|
|
2844
934
|
}
|
|
2845
935
|
var verifiedWindowsDirectory;
|
|
2846
936
|
async function secureDaemonDirectory() {
|
|
2847
937
|
if (process.platform === "win32") {
|
|
2848
938
|
const directory = daemonRunDir();
|
|
2849
|
-
const previous = await
|
|
939
|
+
const previous = await fs3.lstat(directory).catch((error) => {
|
|
2850
940
|
if (error.code !== "ENOENT")
|
|
2851
941
|
throw error;
|
|
2852
942
|
return void 0;
|
|
@@ -2854,15 +944,15 @@ async function secureDaemonDirectory() {
|
|
|
2854
944
|
await verifyWindowsDaemonDirectory(directory, previous);
|
|
2855
945
|
return;
|
|
2856
946
|
}
|
|
2857
|
-
await
|
|
2858
|
-
assertPosixDaemonDirectory(await
|
|
947
|
+
await fs3.mkdir(daemonRunDir(), { recursive: true, mode: 448 });
|
|
948
|
+
assertPosixDaemonDirectory(await fs3.lstat(daemonRunDir()), false);
|
|
2859
949
|
}
|
|
2860
950
|
async function verifyWindowsDaemonDirectory(directory, previous) {
|
|
2861
951
|
if (previous && (!previous.isDirectory() || previous.isSymbolicLink()))
|
|
2862
952
|
throw new Error("Unsafe daemon directory.");
|
|
2863
953
|
if (verifiedWindowsDirectory?.path !== directory || !previous || previous.dev !== verifiedWindowsDirectory.dev || previous.ino !== verifiedWindowsDirectory.ino || previous.birthtimeMs !== verifiedWindowsDirectory.birthtimeMs) {
|
|
2864
954
|
ensureWindowsPrivateDirectory(directory, true);
|
|
2865
|
-
const info = await
|
|
955
|
+
const info = await fs3.lstat(directory);
|
|
2866
956
|
if (!info.isDirectory() || info.isSymbolicLink())
|
|
2867
957
|
throw new Error("Unsafe daemon directory.");
|
|
2868
958
|
verifiedWindowsDirectory = { path: directory, dev: info.dev, ino: info.ino, birthtimeMs: info.birthtimeMs };
|
|
@@ -2879,7 +969,7 @@ function assertPosixDaemonDirectory(info, allowLegacy) {
|
|
|
2879
969
|
throw new Error("Daemon directory must be a current-user-owned directory (mode 0700), without symlinks.");
|
|
2880
970
|
}
|
|
2881
971
|
async function inspectLegacyDaemonDirectory(directory) {
|
|
2882
|
-
const info = await
|
|
972
|
+
const info = await fs3.lstat(directory).catch((error) => {
|
|
2883
973
|
if (error.code !== "ENOENT")
|
|
2884
974
|
throw error;
|
|
2885
975
|
return void 0;
|
|
@@ -2895,9 +985,9 @@ async function inspectLegacyDaemonDirectory(directory) {
|
|
|
2895
985
|
async function upgradeLegacyDaemonDirectory(directory) {
|
|
2896
986
|
if (!await inspectLegacyDaemonDirectory(directory) || process.platform === "win32")
|
|
2897
987
|
return;
|
|
2898
|
-
const before = await
|
|
988
|
+
const before = await fs3.lstat(directory);
|
|
2899
989
|
assertPosixDaemonDirectory(before, true);
|
|
2900
|
-
const handle = await
|
|
990
|
+
const handle = await fs3.open(directory, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
2901
991
|
const assertIdentity = (info) => {
|
|
2902
992
|
assertPosixDaemonDirectory(info, true);
|
|
2903
993
|
if (info.dev !== before.dev || info.ino !== before.ino)
|
|
@@ -2906,11 +996,11 @@ async function upgradeLegacyDaemonDirectory(directory) {
|
|
|
2906
996
|
try {
|
|
2907
997
|
const opened = await handle.stat();
|
|
2908
998
|
assertIdentity(opened);
|
|
2909
|
-
assertIdentity(await
|
|
999
|
+
assertIdentity(await fs3.lstat(directory));
|
|
2910
1000
|
if ((opened.mode & 4095) === 493)
|
|
2911
1001
|
await handle.chmod(448);
|
|
2912
1002
|
assertPosixDaemonDirectory(await handle.stat(), false);
|
|
2913
|
-
const after = await
|
|
1003
|
+
const after = await fs3.lstat(directory);
|
|
2914
1004
|
assertIdentity(after);
|
|
2915
1005
|
assertPosixDaemonDirectory(after, false);
|
|
2916
1006
|
} finally {
|
|
@@ -2918,31 +1008,31 @@ async function upgradeLegacyDaemonDirectory(directory) {
|
|
|
2918
1008
|
}
|
|
2919
1009
|
}
|
|
2920
1010
|
function getDaemonMetadataPath(_configKey) {
|
|
2921
|
-
return
|
|
1011
|
+
return path3.join(daemonRunDir(), "user.json");
|
|
2922
1012
|
}
|
|
2923
1013
|
function getDaemonSocketPath(_configKey) {
|
|
2924
1014
|
if (process.platform === "win32")
|
|
2925
|
-
return `\\\\.\\pipe\\mcporter-user-${
|
|
2926
|
-
return
|
|
1015
|
+
return `\\\\.\\pipe\\mcporter-user-${createHash2("sha256").update(daemonRunDir().toLowerCase()).digest("hex").slice(0, 24)}`;
|
|
1016
|
+
return path3.join(daemonRunDir(), "user.sock");
|
|
2927
1017
|
}
|
|
2928
1018
|
function getDaemonLogPath(_configKey) {
|
|
2929
|
-
return
|
|
1019
|
+
return path3.join(daemonRunDir(), "user.log");
|
|
2930
1020
|
}
|
|
2931
1021
|
|
|
2932
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1022
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/daemon/browser-owner.js
|
|
2933
1023
|
var BrowserOwnerConflict = class extends Error {
|
|
2934
1024
|
code = "browser_owner_conflict";
|
|
2935
1025
|
constructor(reason) {
|
|
2936
|
-
super(`Existing Chrome
|
|
1026
|
+
super(`Existing Chrome request refused: ${reason}. Use the canonical Chrome definition; if changing an existing owner, drain and stop the daemon first. This request was not retried.`);
|
|
2937
1027
|
}
|
|
2938
1028
|
};
|
|
2939
1029
|
function isCanonicalChromeNamespace() {
|
|
2940
|
-
return
|
|
1030
|
+
return path4.resolve(daemonBaseDir()) === path4.join(os3.userInfo().homedir, ".mcporter");
|
|
2941
1031
|
}
|
|
2942
1032
|
async function canonicalUserConfiguration() {
|
|
2943
1033
|
if (!isCanonicalChromeNamespace())
|
|
2944
1034
|
return { definitions: [] };
|
|
2945
|
-
const home =
|
|
1035
|
+
const home = os3.userInfo().homedir;
|
|
2946
1036
|
const file = mcporterConfigCandidates({ home }).find(pathExists);
|
|
2947
1037
|
if (!file)
|
|
2948
1038
|
return { definitions: [] };
|
|
@@ -2962,7 +1052,7 @@ async function canonicalUserConfiguration() {
|
|
|
2962
1052
|
];
|
|
2963
1053
|
if (!launchTokens.some((token) => /chrome[-_]devtools(?:[-_]mcp)?/i.test(token)))
|
|
2964
1054
|
continue;
|
|
2965
|
-
const definition = normalizeServerEntry(name, entry,
|
|
1055
|
+
const definition = normalizeServerEntry(name, entry, path4.dirname(file), { kind: "local", path: file }, [], {
|
|
2966
1056
|
env: canonicalEnv,
|
|
2967
1057
|
home
|
|
2968
1058
|
});
|
|
@@ -2972,11 +1062,15 @@ async function canonicalUserConfiguration() {
|
|
|
2972
1062
|
return { definitions, idleTimeoutMs: raw.daemonIdleTimeoutMs ?? raw.daemon_idle_timeout_ms };
|
|
2973
1063
|
}
|
|
2974
1064
|
function supportedOwner(definition) {
|
|
2975
|
-
return
|
|
1065
|
+
return isExistingChromeDefinition(definition) && definition.command.kind === "stdio" && resolveChromeDevtoolsAutoConnectCommand(definition.command.command, definition.command.args).enabled;
|
|
2976
1066
|
}
|
|
2977
1067
|
var BrowserOwner = class {
|
|
2978
1068
|
identity;
|
|
2979
1069
|
logicalIdentity;
|
|
1070
|
+
discoveryFailure;
|
|
1071
|
+
get discoveryDecision() {
|
|
1072
|
+
return this.discoveryFailure;
|
|
1073
|
+
}
|
|
2980
1074
|
canonicalKeys;
|
|
2981
1075
|
canonical;
|
|
2982
1076
|
get reserved() {
|
|
@@ -2987,14 +1081,14 @@ var BrowserOwner = class {
|
|
|
2987
1081
|
this.canonicalKeys = new Set(this.canonical.map(connectionIdentity));
|
|
2988
1082
|
}
|
|
2989
1083
|
reserve(definition) {
|
|
2990
|
-
if (!
|
|
1084
|
+
if (!isExistingChromeDefinition(definition))
|
|
2991
1085
|
return definition;
|
|
2992
1086
|
if (!isCanonicalChromeNamespace())
|
|
2993
1087
|
throw new BrowserOwnerConflict("existing local Chrome is forbidden in an isolated daemon directory");
|
|
2994
1088
|
if (definition.command.kind !== "stdio")
|
|
2995
1089
|
return definition;
|
|
2996
1090
|
if (!resolveChromeDevtoolsAutoConnectCommand(definition.command.command, definition.command.args).enabled)
|
|
2997
|
-
throw new BrowserOwnerConflict("
|
|
1091
|
+
throw new BrowserOwnerConflict("connection or browser-selection flags and ambiguous wrappers may reach an existing browser; only canonical auto-connect is supported");
|
|
2998
1092
|
const configured = this.canonical[0];
|
|
2999
1093
|
if (this.canonicalKeys.size !== 1 || !configured)
|
|
3000
1094
|
throw new BrowserOwnerConflict("canonical global Chrome definitions are missing or conflicting");
|
|
@@ -3018,17 +1112,31 @@ var BrowserOwner = class {
|
|
|
3018
1112
|
}
|
|
3019
1113
|
async resolveIdentity(definition) {
|
|
3020
1114
|
const resolve = () => resolveChromeDevtoolsRelayRuntimeIdentity(chromeDevtoolsRelayEnvironmentKeys([definition], definition.env), definition.env);
|
|
3021
|
-
if (!this.logicalIdentity)
|
|
3022
|
-
this.logicalIdentity = resolve()
|
|
3023
|
-
|
|
3024
|
-
|
|
1115
|
+
if (!this.logicalIdentity) {
|
|
1116
|
+
this.logicalIdentity = resolve().catch((error) => {
|
|
1117
|
+
this.logicalIdentity = void 0;
|
|
1118
|
+
throw error;
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
let retained;
|
|
1122
|
+
let current;
|
|
1123
|
+
try {
|
|
1124
|
+
retained = await this.logicalIdentity;
|
|
1125
|
+
current = await resolve();
|
|
1126
|
+
} catch (error) {
|
|
1127
|
+
if (error instanceof ChromeDevtoolsRelayDiscoveryError) {
|
|
1128
|
+
this.discoveryFailure = error.decision;
|
|
1129
|
+
}
|
|
1130
|
+
throw error;
|
|
1131
|
+
}
|
|
3025
1132
|
if (retained !== current)
|
|
3026
1133
|
throw new BrowserOwnerConflict("relay endpoint, credential generation or security context changed; explicit retirement is required");
|
|
1134
|
+
this.discoveryFailure = void 0;
|
|
3027
1135
|
return retained;
|
|
3028
1136
|
}
|
|
3029
1137
|
};
|
|
3030
1138
|
|
|
3031
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1139
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/daemon/transport-authority.js
|
|
3032
1140
|
var authority = /* @__PURE__ */ Symbol("broker transport authority");
|
|
3033
1141
|
function authorizeBrokerDefinition(definition, validateRequest) {
|
|
3034
1142
|
Object.defineProperty(definition, authority, { value: { validateRequest }, enumerable: true });
|
|
@@ -3040,16 +1148,22 @@ function isBrokerDefinition(definition) {
|
|
|
3040
1148
|
return Boolean(definition?.[authority]);
|
|
3041
1149
|
}
|
|
3042
1150
|
function assertChromeBrokerAuthority(definition) {
|
|
3043
|
-
if (
|
|
1151
|
+
if (isExistingChromeDefinition(definition) && !isBrokerDefinition(definition)) {
|
|
3044
1152
|
throw new BrowserOwnerConflict("programmatic or ephemeral Chrome attachment must use the daemon-backed runtime");
|
|
3045
1153
|
}
|
|
3046
1154
|
}
|
|
3047
1155
|
|
|
3048
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1156
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/runtime-process-utils.js
|
|
3049
1157
|
import { execFile } from "node:child_process";
|
|
1158
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
1159
|
+
async function captureTransportProcessTree(transport) {
|
|
1160
|
+
const pid = getTransportPid(transport);
|
|
1161
|
+
return { pid, targets: pid ? await collectProcessTreePids(pid) : [] };
|
|
1162
|
+
}
|
|
3050
1163
|
async function closeTransportAndWait(logger, transport, options = {}) {
|
|
3051
|
-
const
|
|
3052
|
-
const
|
|
1164
|
+
const processTree = options.processTree ?? await captureTransportProcessTree(transport);
|
|
1165
|
+
const pidBeforeClose = processTree.pid;
|
|
1166
|
+
const targetsBeforeClose = processTree.targets;
|
|
3053
1167
|
let closeError;
|
|
3054
1168
|
let closeSettled = false;
|
|
3055
1169
|
const closePromise = (options.close ?? (() => transport.close()))().catch((error) => {
|
|
@@ -3256,11 +1370,8 @@ async function waitForTreeExit(pids, durationMs) {
|
|
|
3256
1370
|
await delay(remaining);
|
|
3257
1371
|
}
|
|
3258
1372
|
}
|
|
3259
|
-
function delay(ms) {
|
|
3260
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3261
|
-
}
|
|
3262
1373
|
|
|
3263
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1374
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/runtime/errors.js
|
|
3264
1375
|
var NON_FATAL_MCP_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
3265
1376
|
ProtocolErrorCode.InvalidRequest,
|
|
3266
1377
|
ProtocolErrorCode.MethodNotFound,
|
|
@@ -3282,8 +1393,8 @@ function protocolErrorCode(error) {
|
|
|
3282
1393
|
return typeof error.code === "number" ? error.code : void 0;
|
|
3283
1394
|
}
|
|
3284
1395
|
|
|
3285
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
3286
|
-
import
|
|
1396
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/runtime/replay-transport.js
|
|
1397
|
+
import fs4 from "node:fs";
|
|
3287
1398
|
import { isDeepStrictEqual } from "node:util";
|
|
3288
1399
|
var CLIENT_IDENTITY_META_KEYS = [
|
|
3289
1400
|
"io.modelcontextprotocol/clientInfo",
|
|
@@ -3338,7 +1449,7 @@ var ReplayTransport = class {
|
|
|
3338
1449
|
};
|
|
3339
1450
|
function readRecordedMessages(recordPath) {
|
|
3340
1451
|
try {
|
|
3341
|
-
const contents =
|
|
1452
|
+
const contents = fs4.readFileSync(recordPath, "utf8");
|
|
3342
1453
|
return contents.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).map((line, index) => {
|
|
3343
1454
|
try {
|
|
3344
1455
|
return JSON.parse(line);
|
|
@@ -3710,15 +1821,15 @@ var StdioClientTransport = class {
|
|
|
3710
1821
|
}
|
|
3711
1822
|
};
|
|
3712
1823
|
|
|
3713
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
3714
|
-
import
|
|
3715
|
-
import
|
|
3716
|
-
import
|
|
1824
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/chrome-devtools-compat.js
|
|
1825
|
+
import fs6 from "node:fs";
|
|
1826
|
+
import os4 from "node:os";
|
|
1827
|
+
import path6 from "node:path";
|
|
3717
1828
|
import { fileURLToPath, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
3718
1829
|
|
|
3719
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
3720
|
-
import
|
|
3721
|
-
import
|
|
1830
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/chrome-devtools-auto-connect-patch.js
|
|
1831
|
+
import fs5 from "node:fs";
|
|
1832
|
+
import path5 from "node:path";
|
|
3722
1833
|
var MARKER = "MCPORTER_DEVTOOLS_TIMEOUT_PATCH";
|
|
3723
1834
|
var HELPER = `// ${MARKER}
|
|
3724
1835
|
const MCPORTER_DEVTOOLS_DETECTION_TIMEOUT = 1_000;
|
|
@@ -3748,7 +1859,7 @@ var PATCHED_DETECTION_BLOCK = `if (await mcporterWithTimeout(page.hasDevTools(),
|
|
|
3748
1859
|
}`;
|
|
3749
1860
|
patchChromeDevtoolsMcp();
|
|
3750
1861
|
function patchChromeDevtoolsMcp(mainPath = process.argv[1]) {
|
|
3751
|
-
patchChromeDevtoolsMcpWithDependencies(mainPath,
|
|
1862
|
+
patchChromeDevtoolsMcpWithDependencies(mainPath, fs5, path5, MARKER, HELPER, DETECTION_BLOCK, PATCHED_DETECTION_BLOCK);
|
|
3752
1863
|
}
|
|
3753
1864
|
function renderChromeDevtoolsAutoConnectPatchSource() {
|
|
3754
1865
|
return `import fs from 'node:fs';
|
|
@@ -3803,7 +1914,7 @@ ${helper}`);
|
|
|
3803
1914
|
}
|
|
3804
1915
|
}
|
|
3805
1916
|
|
|
3806
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1917
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/chrome-devtools-compat.js
|
|
3807
1918
|
var FALLBACK_PATCH_FILENAME = "mcporter-chrome-devtools-auto-connect-patch.js";
|
|
3808
1919
|
function applyChromeDevtoolsCompat(env, command, args) {
|
|
3809
1920
|
if (!shouldApplyChromeDevtoolsCompat(command, args, env)) {
|
|
@@ -3833,31 +1944,31 @@ function shouldApplyChromeDevtoolsCompat(command, args, env = process.env) {
|
|
|
3833
1944
|
}
|
|
3834
1945
|
return resolveChromeDevtoolsAutoConnectCommand(command, args).enabled;
|
|
3835
1946
|
}
|
|
3836
|
-
function resolveChromeDevtoolsCompatPatchPath(candidates = defaultChromeDevtoolsPatchCandidates(), fallbackDir =
|
|
3837
|
-
const existing = candidates.find((candidate) =>
|
|
1947
|
+
function resolveChromeDevtoolsCompatPatchPath(candidates = defaultChromeDevtoolsPatchCandidates(), fallbackDir = os4.tmpdir()) {
|
|
1948
|
+
const existing = candidates.find((candidate) => fs6.existsSync(candidate));
|
|
3838
1949
|
if (existing) {
|
|
3839
1950
|
return existing;
|
|
3840
1951
|
}
|
|
3841
1952
|
return writeFallbackPatch(fallbackDir);
|
|
3842
1953
|
}
|
|
3843
1954
|
function defaultChromeDevtoolsPatchCandidates() {
|
|
3844
|
-
const here =
|
|
1955
|
+
const here = path6.dirname(fileURLToPath(import.meta.url));
|
|
3845
1956
|
return [
|
|
3846
|
-
|
|
3847
|
-
|
|
1957
|
+
path6.join(here, "chrome-devtools-auto-connect-patch.js"),
|
|
1958
|
+
path6.resolve(here, "..", "dist", "chrome-devtools-auto-connect-patch.js")
|
|
3848
1959
|
];
|
|
3849
1960
|
}
|
|
3850
1961
|
function writeFallbackPatch(fallbackDir) {
|
|
3851
|
-
const patchPath =
|
|
1962
|
+
const patchPath = path6.join(fallbackDir, FALLBACK_PATCH_FILENAME);
|
|
3852
1963
|
try {
|
|
3853
|
-
|
|
1964
|
+
fs6.writeFileSync(patchPath, renderChromeDevtoolsAutoConnectPatchSource(), { mode: 384 });
|
|
3854
1965
|
return patchPath;
|
|
3855
1966
|
} catch {
|
|
3856
1967
|
return void 0;
|
|
3857
1968
|
}
|
|
3858
1969
|
}
|
|
3859
1970
|
|
|
3860
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1971
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/runtime/cached-auth.js
|
|
3861
1972
|
function hasAuthorizationHeader(headers) {
|
|
3862
1973
|
return Boolean(headers && Object.keys(headers).some((key) => key.toLowerCase() === "authorization"));
|
|
3863
1974
|
}
|
|
@@ -3920,7 +2031,7 @@ async function applyCachedAuthIfAvailable(definition, logger, allowCachedAuth) {
|
|
|
3920
2031
|
}
|
|
3921
2032
|
}
|
|
3922
2033
|
|
|
3923
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2034
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/runtime-header-utils.js
|
|
3924
2035
|
function materializeHeaders(headers, serverName, env = process.env) {
|
|
3925
2036
|
if (!headers) {
|
|
3926
2037
|
return void 0;
|
|
@@ -3937,8 +2048,8 @@ function materializeHeaders(headers, serverName, env = process.env) {
|
|
|
3937
2048
|
return resolved;
|
|
3938
2049
|
}
|
|
3939
2050
|
|
|
3940
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
3941
|
-
import
|
|
2051
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/runtime/node-http-fetch.js
|
|
2052
|
+
import http from "node:http";
|
|
3942
2053
|
import https from "node:https";
|
|
3943
2054
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
3944
2055
|
import { Readable } from "node:stream";
|
|
@@ -3976,7 +2087,7 @@ async function nodeHttp1FetchWithRedirects(input, init, redirectCount) {
|
|
|
3976
2087
|
headers["content-length"] = String(Buffer2.byteLength(body));
|
|
3977
2088
|
}
|
|
3978
2089
|
return new Promise((resolve, reject) => {
|
|
3979
|
-
const client = url.protocol === "https:" ? https :
|
|
2090
|
+
const client = url.protocol === "https:" ? https : http;
|
|
3980
2091
|
const request = client.request(url, {
|
|
3981
2092
|
method: init.method ?? "GET",
|
|
3982
2093
|
headers
|
|
@@ -4096,7 +2207,7 @@ async function materializeRequestBody(body) {
|
|
|
4096
2207
|
throw new TypeError("node-http1 fetch does not support streaming request bodies.");
|
|
4097
2208
|
}
|
|
4098
2209
|
|
|
4099
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2210
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/runtime/http-transport.js
|
|
4100
2211
|
function extractTransportStatusCode(error) {
|
|
4101
2212
|
if (!error || typeof error !== "object")
|
|
4102
2213
|
return void 0;
|
|
@@ -4158,10 +2269,7 @@ function createHttpTransportOptions(definition, oauthSession, shouldEstablishOAu
|
|
|
4158
2269
|
};
|
|
4159
2270
|
}
|
|
4160
2271
|
function trackStandaloneSseFetch(fetchOverride) {
|
|
4161
|
-
|
|
4162
|
-
const started = new Promise((resolve) => {
|
|
4163
|
-
markStarted = resolve;
|
|
4164
|
-
});
|
|
2272
|
+
const { promise: started, resolve: markStarted } = Promise.withResolvers();
|
|
4165
2273
|
const baseFetch = fetchOverride ?? ((input, init) => fetch(input, init));
|
|
4166
2274
|
return {
|
|
4167
2275
|
started,
|
|
@@ -4319,20 +2427,24 @@ async function connectSseFallbackTransport(client, definition, command, transpor
|
|
|
4319
2427
|
}
|
|
4320
2428
|
}
|
|
4321
2429
|
|
|
4322
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2430
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/runtime/stdio-transport.js
|
|
4323
2431
|
var McporterStdioTransport = class extends StdioClientTransport {
|
|
4324
2432
|
parameters;
|
|
4325
2433
|
meta;
|
|
4326
2434
|
closing = false;
|
|
2435
|
+
closePromise;
|
|
2436
|
+
closeNotified = false;
|
|
4327
2437
|
closeDelegate;
|
|
4328
2438
|
messageDelegate;
|
|
4329
2439
|
closeInterceptor = () => {
|
|
4330
2440
|
this.meta.code = this.closing ? 0 : 1;
|
|
4331
2441
|
flushStdioLogs(this.meta);
|
|
4332
2442
|
void this.cleanup();
|
|
4333
|
-
this.
|
|
2443
|
+
this.notifyClosed();
|
|
4334
2444
|
};
|
|
4335
2445
|
messageInterceptor = (message) => {
|
|
2446
|
+
if (this.parameters.lifetime?.aborted)
|
|
2447
|
+
return;
|
|
4336
2448
|
if (STDIO_TRACE_ENABLED && !this.parameters.redactDiagnostics)
|
|
4337
2449
|
this.meta.stdoutChunks?.push(JSON.stringify(message));
|
|
4338
2450
|
this.messageDelegate?.(message);
|
|
@@ -4362,24 +2474,34 @@ var McporterStdioTransport = class extends StdioClientTransport {
|
|
|
4362
2474
|
}
|
|
4363
2475
|
}
|
|
4364
2476
|
async start() {
|
|
2477
|
+
this.assertOpen();
|
|
4365
2478
|
if (STDIO_TRACE_ENABLED && !this.parameters.redactDiagnostics)
|
|
4366
2479
|
console.log("[mcporter] STDIO trace: start() invoked for stdio transport.");
|
|
4367
2480
|
this.installInterceptors();
|
|
4368
2481
|
await super.start();
|
|
2482
|
+
this.assertOpen();
|
|
4369
2483
|
if (STDIO_TRACE_ENABLED && !this.parameters.redactDiagnostics) {
|
|
4370
2484
|
console.log(`[mcporter] STDIO trace: spawned ${this.meta.command ?? "stdio server"} (pid=${this.pid ?? "unknown"}).`);
|
|
4371
2485
|
}
|
|
4372
2486
|
}
|
|
4373
2487
|
async send(message) {
|
|
2488
|
+
this.assertOpen();
|
|
4374
2489
|
this.installInterceptors();
|
|
4375
2490
|
if (STDIO_TRACE_ENABLED && !this.parameters.redactDiagnostics)
|
|
4376
2491
|
this.meta.stdinChunks?.push(JSON.stringify(message));
|
|
4377
2492
|
await super.send(message);
|
|
4378
2493
|
}
|
|
4379
|
-
|
|
2494
|
+
close() {
|
|
2495
|
+
if (this.closePromise)
|
|
2496
|
+
return this.closePromise;
|
|
4380
2497
|
this.closing = true;
|
|
4381
2498
|
this.installInterceptors();
|
|
2499
|
+
this.closePromise = this.closeOnce();
|
|
2500
|
+
return this.closePromise;
|
|
2501
|
+
}
|
|
2502
|
+
async closeOnce() {
|
|
4382
2503
|
try {
|
|
2504
|
+
await this.parameters.prepareClose?.();
|
|
4383
2505
|
await super.close();
|
|
4384
2506
|
} finally {
|
|
4385
2507
|
this.meta.code ??= 0;
|
|
@@ -4387,6 +2509,20 @@ var McporterStdioTransport = class extends StdioClientTransport {
|
|
|
4387
2509
|
await this.cleanup();
|
|
4388
2510
|
}
|
|
4389
2511
|
}
|
|
2512
|
+
assertOpen() {
|
|
2513
|
+
if (this.closing || this.parameters.lifetime?.aborted)
|
|
2514
|
+
throw new SdkError(SdkErrorCode.ConnectionClosed, "Transport connection closed.");
|
|
2515
|
+
}
|
|
2516
|
+
notifyClosed() {
|
|
2517
|
+
if (this.closeNotified)
|
|
2518
|
+
return;
|
|
2519
|
+
this.closeNotified = true;
|
|
2520
|
+
this.closeDelegate?.();
|
|
2521
|
+
}
|
|
2522
|
+
notifyConnectionClosed() {
|
|
2523
|
+
this.installInterceptors();
|
|
2524
|
+
this.notifyClosed();
|
|
2525
|
+
}
|
|
4390
2526
|
cleanup() {
|
|
4391
2527
|
this.cleanupPromise ??= Promise.resolve(this.parameters.cleanup?.()).catch(() => {
|
|
4392
2528
|
});
|
|
@@ -4404,7 +2540,7 @@ var McporterStdioTransport = class extends StdioClientTransport {
|
|
|
4404
2540
|
}
|
|
4405
2541
|
};
|
|
4406
2542
|
|
|
4407
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2543
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/runtime/transport.js
|
|
4408
2544
|
function shouldUseModeForServer(definition, serverFilter) {
|
|
4409
2545
|
return !serverFilter || serverFilter === definition.name;
|
|
4410
2546
|
}
|
|
@@ -4469,7 +2605,7 @@ async function createStdioClientContext(client, definition, logger, options) {
|
|
|
4469
2605
|
...Object.fromEntries(DEFAULT_INHERITED_ENV_VARS.map((key) => [key, void 0])),
|
|
4470
2606
|
...definition.env
|
|
4471
2607
|
};
|
|
4472
|
-
if (isBrokerDefinition(definition) &&
|
|
2608
|
+
if (isBrokerDefinition(definition) && isExistingChromeDefinition(definition) && resolveChromeDevtoolsRelayPolicy(definition.chromeDevtoolsRelay, definition.env) !== "off") {
|
|
4473
2609
|
mergedEnv.MCPORTER_CHROME_DEVTOOLS_RELAY_POLICY = "require";
|
|
4474
2610
|
delete mergedEnv.MCPORTER_DISABLE_CHROME_DEVTOOLS_RELAY;
|
|
4475
2611
|
}
|
|
@@ -4484,7 +2620,7 @@ async function createStdioClientContext(client, definition, logger, options) {
|
|
|
4484
2620
|
let relayDecision;
|
|
4485
2621
|
let relay;
|
|
4486
2622
|
try {
|
|
4487
|
-
relay = await rewriteChromeDevtoolsArgsForRelay(command, resolvedArgs, mergedEnv, { onDecision: (decision) => relayDecision = decision }, isBrokerDefinition(definition) &&
|
|
2623
|
+
relay = await rewriteChromeDevtoolsArgsForRelay(command, resolvedArgs, mergedEnv, { onDecision: (decision) => relayDecision = decision }, isBrokerDefinition(definition) && isExistingChromeDefinition(definition) && resolveChromeDevtoolsRelayPolicy(definition.chromeDevtoolsRelay, definition.env) !== "off" ? "require" : definition.chromeDevtoolsRelay);
|
|
4488
2624
|
} catch (error) {
|
|
4489
2625
|
if (relayDecision)
|
|
4490
2626
|
publishRelayDecision(relayDecision);
|
|
@@ -4494,6 +2630,9 @@ async function createStdioClientContext(client, definition, logger, options) {
|
|
|
4494
2630
|
let activeProxy = relay.proxy;
|
|
4495
2631
|
let handoff;
|
|
4496
2632
|
let rawTransport;
|
|
2633
|
+
let processTree;
|
|
2634
|
+
const captureProcesses = () => processTree ??= captureTransportProcessTree(rawTransport);
|
|
2635
|
+
let onProxyClosed;
|
|
4497
2636
|
try {
|
|
4498
2637
|
if (activeProxy) {
|
|
4499
2638
|
try {
|
|
@@ -4527,7 +2666,11 @@ async function createStdioClientContext(client, definition, logger, options) {
|
|
|
4527
2666
|
cwd: definition.command.cwd,
|
|
4528
2667
|
env: compat.env,
|
|
4529
2668
|
redactDiagnostics: isBrokerDefinition(definition),
|
|
2669
|
+
lifetime: activeProxy?.signal,
|
|
2670
|
+
prepareClose: activeProxy ? async () => void await captureProcesses() : void 0,
|
|
4530
2671
|
cleanup: activeProxy ? async () => {
|
|
2672
|
+
if (onProxyClosed)
|
|
2673
|
+
activeProxy?.signal.removeEventListener("abort", onProxyClosed);
|
|
4531
2674
|
await handoff?.close();
|
|
4532
2675
|
await activeProxy?.close();
|
|
4533
2676
|
} : void 0
|
|
@@ -4546,10 +2689,37 @@ async function createStdioClientContext(client, definition, logger, options) {
|
|
|
4546
2689
|
await closeTransportAndWait(logger, rawTransport, { throwOnCloseError: true, requireRetirement: true });
|
|
4547
2690
|
throw error;
|
|
4548
2691
|
}
|
|
2692
|
+
let connected = false;
|
|
2693
|
+
let setupRetirement;
|
|
2694
|
+
const retireSetup = () => setupRetirement ??= (async () => {
|
|
2695
|
+
const captured = await captureProcesses();
|
|
2696
|
+
await closeTransportAndWait(logger, transport, {
|
|
2697
|
+
throwOnCloseError: true,
|
|
2698
|
+
requireRetirement: true,
|
|
2699
|
+
processTree: captured
|
|
2700
|
+
});
|
|
2701
|
+
})();
|
|
2702
|
+
onProxyClosed = () => {
|
|
2703
|
+
if (connected) {
|
|
2704
|
+
rawTransport.notifyConnectionClosed();
|
|
2705
|
+
} else {
|
|
2706
|
+
void retireSetup().catch(() => {
|
|
2707
|
+
});
|
|
2708
|
+
}
|
|
2709
|
+
};
|
|
2710
|
+
activeProxy?.signal.addEventListener("abort", onProxyClosed, { once: true });
|
|
2711
|
+
if (activeProxy?.signal.aborted)
|
|
2712
|
+
onProxyClosed();
|
|
4549
2713
|
try {
|
|
4550
2714
|
await client.connect(transport, { signal: options.signal });
|
|
2715
|
+
if (activeProxy?.signal.aborted)
|
|
2716
|
+
throw new SdkError(SdkErrorCode.ConnectionClosed, "Chrome relay connection closed during setup.");
|
|
2717
|
+
connected = true;
|
|
4551
2718
|
} catch (error) {
|
|
4552
|
-
|
|
2719
|
+
const upstreamLost = activeProxy?.signal.aborted && activeProxy.signal.reason === "upstream";
|
|
2720
|
+
await retireSetup();
|
|
2721
|
+
if (upstreamLost)
|
|
2722
|
+
throw new SdkError(SdkErrorCode.ConnectionClosed, "Chrome relay connection closed during setup.");
|
|
4553
2723
|
throw error;
|
|
4554
2724
|
}
|
|
4555
2725
|
return { client, transport, definition, oauthSession: void 0 };
|
|
@@ -4588,7 +2758,7 @@ async function createClientContext(definition, logger, clientInfo, options = {})
|
|
|
4588
2758
|
});
|
|
4589
2759
|
}
|
|
4590
2760
|
|
|
4591
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2761
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/runtime/connection-cache.js
|
|
4592
2762
|
var RuntimeConnectionCache = class {
|
|
4593
2763
|
definitions;
|
|
4594
2764
|
options;
|
|
@@ -5107,10 +3277,7 @@ var RuntimeConnectionCache = class {
|
|
|
5107
3277
|
}
|
|
5108
3278
|
async enterConnectionSetup(server) {
|
|
5109
3279
|
const previous = this.connectionSetupTails.get(server) ?? Promise.resolve();
|
|
5110
|
-
|
|
5111
|
-
const current = new Promise((resolve) => {
|
|
5112
|
-
releaseCurrent = resolve;
|
|
5113
|
-
});
|
|
3280
|
+
const { promise: current, resolve: releaseCurrent } = Promise.withResolvers();
|
|
5114
3281
|
const tail = previous.catch(() => {
|
|
5115
3282
|
}).then(() => current);
|
|
5116
3283
|
this.connectionSetupTails.set(server, tail);
|
|
@@ -5142,7 +3309,7 @@ function connectionInfoFromClient(client) {
|
|
|
5142
3309
|
};
|
|
5143
3310
|
}
|
|
5144
3311
|
|
|
5145
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
3312
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/tool-filters.js
|
|
5146
3313
|
function validateToolFilters(name, filter) {
|
|
5147
3314
|
if (filter.allowedTools !== void 0 && filter.blockedTools !== void 0) {
|
|
5148
3315
|
throw new Error(`Server '${name}' cannot specify both allowedTools and blockedTools.`);
|
|
@@ -5164,7 +3331,7 @@ function filterTools(tools, filter) {
|
|
|
5164
3331
|
return tools.filter((tool) => isToolAllowed(tool.name, filter));
|
|
5165
3332
|
}
|
|
5166
3333
|
|
|
5167
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
3334
|
+
// node_modules/.pnpm/mcporter@0.13.13/node_modules/mcporter/dist/runtime.js
|
|
5168
3335
|
var PACKAGE_NAME = "mcporter";
|
|
5169
3336
|
var OAUTH_CODE_TIMEOUT_MS = resolveOAuthTimeoutFromEnv();
|
|
5170
3337
|
var MAX_RESOURCE_LIST_PAGES = 100;
|
|
@@ -5417,10 +3584,9 @@ function createConsoleLogger(level = resolveLogLevelFromEnv()) {
|
|
|
5417
3584
|
}
|
|
5418
3585
|
|
|
5419
3586
|
export {
|
|
5420
|
-
getChromeDevtoolsRelayDecision,
|
|
5421
3587
|
effectiveDefinition,
|
|
5422
3588
|
connectionIdentity,
|
|
5423
|
-
|
|
3589
|
+
isExistingChromeDefinition,
|
|
5424
3590
|
resolveSystemPowerShellPath,
|
|
5425
3591
|
daemonRunDir,
|
|
5426
3592
|
secureDaemonDirectory,
|
|
@@ -5429,6 +3595,7 @@ export {
|
|
|
5429
3595
|
getDaemonMetadataPath,
|
|
5430
3596
|
getDaemonSocketPath,
|
|
5431
3597
|
getDaemonLogPath,
|
|
3598
|
+
BrowserOwnerConflict,
|
|
5432
3599
|
canonicalUserConfiguration,
|
|
5433
3600
|
BrowserOwner,
|
|
5434
3601
|
authorizeBrokerDefinition,
|