@jshookmcp/jshook 0.2.9 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -50
- package/README.zh.md +25 -48
- package/dist/AntiCheatDetector-CGVGNfy5.mjs +1 -0
- package/dist/CacheAdapters-CdAxBmVW.mjs +1 -0
- package/dist/CodeInjector-BlgyqTOk.mjs +1 -0
- package/dist/ConsoleMonitor-Dkqc0HNi.mjs +490 -0
- package/dist/DOMInspector-BYY_EJ0C.mjs +95 -0
- package/dist/DarwinAPI-DC4HGGLl.mjs +1 -0
- package/dist/DetailedDataManager-BniBJlVv.mjs +1 -0
- package/dist/EventBus-DgciURGg.mjs +1 -0
- package/dist/EvidenceGraphBridge-BIfgB7HP.mjs +1 -0
- package/dist/ExtensionManager-erMpqcLk.mjs +1 -0
- package/dist/FingerprintManager-N7BZqjxP.mjs +1 -0
- package/dist/HardwareBreakpoint-OcJqNFVc.mjs +1 -0
- package/dist/HeapAnalyzer-CqAxZzeS.mjs +1 -0
- package/dist/{HookGeneratorBuilders.core.generators.storage-CtcdK78Q.mjs → HookGeneratorBuilders.core.generators.storage-Bf1fbrNK.mjs} +66 -174
- package/dist/InstrumentationSession-DxXs0sCp.mjs +1 -0
- package/dist/MCPServer.search.handlers.domain-DVbWL1bT.mjs +1 -0
- package/dist/MemoryController-BaqstM5w.mjs +2 -0
- package/dist/MemoryScanSession-CaxAjZJf.mjs +1 -0
- package/dist/MemoryScanner-BLYnMJy6.mjs +1 -0
- package/dist/NativeMemoryManager.impl-CI554XbY.mjs +1 -0
- package/dist/NativeMemoryManager.utils-DM4NC3FE.mjs +1 -0
- package/dist/PEAnalyzer-DJyaJTQJ.mjs +1 -0
- package/dist/PageController-D9jVkH0i.mjs +1 -0
- package/dist/PointerChainEngine-5nF9eNlu.mjs +1 -0
- package/dist/PrerequisiteError-Bl3dK8XA.mjs +1 -0
- package/dist/ProcessRegistry-Hf12LlR9.mjs +1 -0
- package/dist/ResponseBuilder-B2lu4KEl.mjs +1 -0
- package/dist/ReverseEvidenceGraph-B931HeoW.mjs +2 -0
- package/dist/ScriptManager-fgqiALgj.mjs +7 -0
- package/dist/Speedhack-l6s8L2Qw.mjs +1 -0
- package/dist/StealthVerifier-Dhbj4B4P.mjs +1 -0
- package/dist/StructureAnalyzer-A-WamfYE.mjs +2 -0
- package/dist/ToolCatalog-D_IKl1Hu.mjs +1 -0
- package/dist/ToolError-DWU_z7gp.mjs +1 -0
- package/dist/ToolProbe-xsfALmN3.mjs +1 -0
- package/dist/ToolRegistry-B0Zs-phN.mjs +1 -0
- package/dist/ToolRouter.policy-CFHoN_Lw.mjs +4 -0
- package/dist/TraceRecorder-Dd8jLXpi.mjs +272 -0
- package/dist/VersionDetector-DMoUWyNm.mjs +9 -0
- package/dist/Win32API-Bhi5xFBe.mjs +1 -0
- package/dist/Win32Debug-CQteFL4F.mjs +1 -0
- package/dist/WorkflowEngine-CxEp2WXH.mjs +1 -0
- package/dist/analysis-BuR-NgX8.mjs +5 -0
- package/dist/{antidebug-CqDTB_uk.mjs → antidebug-BOTZH6-0.mjs} +8 -259
- package/dist/artifactRetention-NBdncOEW.mjs +1 -0
- package/dist/artifacts-B5xQuEa_.mjs +1 -0
- package/dist/authorization-schema-B40obG1A.mjs +1 -0
- package/dist/betterSqlite3-CGaxz4AX.mjs +1 -0
- package/dist/binary-instrument-Cf9qqLlM.mjs +7 -0
- package/dist/bind-helpers-BlAOQrFQ.mjs +1 -0
- package/dist/boringssl-inspector-BST5vtKx.mjs +2 -0
- package/dist/browser-C4Le3xqA.mjs +11 -0
- package/dist/capabilities-DbYCv-HF.mjs +1 -0
- package/dist/chunk-C_pMuVsO.mjs +1 -0
- package/dist/collector-CKO8RPK8.mjs +1 -0
- package/dist/concurrency-CcK46d0h.mjs +1 -0
- package/dist/constants-Cp6hBrrx.mjs +1 -0
- package/dist/coordination-BbijHEHH.mjs +1 -0
- package/dist/debugger-CRJq_krh.mjs +1 -0
- package/dist/definitions-BGobEDQa.mjs +1 -0
- package/dist/definitions-BGwNSkVm.mjs +1 -0
- package/dist/definitions-BbxOUiP-.mjs +1 -0
- package/dist/definitions-CCP9gphV.mjs +1 -0
- package/dist/definitions-CIO9O-Sw.mjs +1 -0
- package/dist/definitions-CYFbewnd.mjs +1 -0
- package/dist/definitions-CdWEuIkI.mjs +1 -0
- package/dist/definitions-CoQFbggH.mjs +1 -0
- package/dist/definitions-CuJRsJ6N.mjs +1 -0
- package/dist/definitions-DI9YXsJk.mjs +1 -0
- package/dist/definitions-DJklW2sS.mjs +1 -0
- package/dist/definitions-DZ8uKusP.mjs +1 -0
- package/dist/definitions-Dds_zrWx.mjs +1 -0
- package/dist/definitions-Dgrg7f3D.mjs +1 -0
- package/dist/definitions-DtE0XLrT.mjs +1 -0
- package/dist/definitions-LaYTuwQd.mjs +26 -0
- package/dist/definitions-NoVp_9Pm.mjs +1 -0
- package/dist/definitions-OvGsfxdt.mjs +1 -0
- package/dist/definitions-jXPaVy4P.mjs +1 -0
- package/dist/encoding-DGcr6Aj_.mjs +2 -0
- package/dist/ensure-browser-core-Buls24LQ.mjs +1 -0
- package/dist/evidence-graph-bridge-B0yhGPcs.mjs +1 -0
- package/dist/factory-Cx_1LorX.mjs +1 -0
- package/dist/flat-target-session-CO5g78k3.mjs +1 -0
- package/dist/formatAddress-C7j2fDlM.mjs +1 -0
- package/dist/graphql-HLf3MS8H.mjs +62 -0
- package/dist/handlers-BLMa4X7l.mjs +54 -0
- package/dist/handlers-BP12ZsWc.mjs +4 -0
- package/dist/handlers-BZoPla6E.mjs +1 -0
- package/dist/handlers-BggKiVx9.mjs +2 -0
- package/dist/handlers-D3iev8g1.mjs +1 -0
- package/dist/handlers-D49r1-1P.mjs +1 -0
- package/dist/handlers-DCE45Ww8.mjs +2 -0
- package/dist/handlers-DW5AbYs5.mjs +5 -0
- package/dist/handlers-De5u62Ga2.mjs +1 -0
- package/dist/handlers-DmQzIc44.mjs +31 -0
- package/dist/handlers-DnJRGp7t.mjs +302 -0
- package/dist/handlers-Dv_runVv.mjs +2 -0
- package/dist/handlers-S9Ws0IGy.mjs +2 -0
- package/dist/{handlers-Bl8zkwz1.mjs → handlers-pVNpaw4A.mjs} +144 -841
- package/dist/handlers.impl-CD2_kOcC.mjs +1 -0
- package/dist/hooks-DDKppogd.mjs +600 -0
- package/dist/index.mjs +12 -5225
- package/dist/logger-sBC6IdRT.mjs +1 -0
- package/dist/maintenance-CutEO84j.mjs +1 -0
- package/dist/manifest-BFGxlDRh.mjs +123 -0
- package/dist/manifest-BPuE6oH2.mjs +1 -0
- package/dist/manifest-BXry5N09.mjs +1 -0
- package/dist/manifest-BeP_zJGb2.mjs +1 -0
- package/dist/manifest-C0g67k6U.mjs +1 -0
- package/dist/manifest-C1nZkTkO.mjs +1 -0
- package/dist/manifest-C7qV1z7F.mjs +1 -0
- package/dist/manifest-CDeUZGUZ.mjs +1 -0
- package/dist/manifest-CDiCtaQT.mjs +1 -0
- package/dist/manifest-CFn0359q2.mjs +1 -0
- package/dist/manifest-CGq4NpqH2.mjs +1 -0
- package/dist/manifest-CJMGt7Qy.mjs +1 -0
- package/dist/manifest-CRIJq4Hs.mjs +1 -0
- package/dist/manifest-C_hEIjSx.mjs +1 -0
- package/dist/manifest-CeQmtQOY.mjs +1 -0
- package/dist/manifest-Cq0j7GZt.mjs +1 -0
- package/dist/manifest-CtPmHAdn.mjs +1 -0
- package/dist/manifest-Cx2IVMUY.mjs +1 -0
- package/dist/manifest-D16xPXro.mjs +1 -0
- package/dist/manifest-D44TaRJU.mjs +1 -0
- package/dist/manifest-D610kxZr.mjs +2 -0
- package/dist/manifest-DC-SMF6b.mjs +1 -0
- package/dist/manifest-DD3rtxvV.mjs +1 -0
- package/dist/manifest-DKUorv5M.mjs +1 -0
- package/dist/manifest-DMJlcsTR.mjs +1 -0
- package/dist/manifest-DWUUWBz0.mjs +1 -0
- package/dist/manifest-De-6Wf2R.mjs +1 -0
- package/dist/manifest-Dgh0uDW-.mjs +1 -0
- package/dist/manifest-Dm0o3i2U.mjs +1 -0
- package/dist/manifest-DsVh7Y4U.mjs +1 -0
- package/dist/manifest-DtEFSRaq.mjs +1 -0
- package/dist/manifest-H-EpAyZQ.mjs +1 -0
- package/dist/manifest-ais9Afrw.mjs +1 -0
- package/dist/manifest-tmb54wmA.mjs +1 -0
- package/dist/manifest-yu2xiQqe.mjs +1 -0
- package/dist/manifest-zrbrpKCC.mjs +1 -0
- package/dist/matchesWildcardPattern-BGqLSmEs.mjs +1 -0
- package/dist/modules-p-PUNv9r.mjs +332 -0
- package/dist/mojo-ipc-VGlv3Qyp.mjs +9 -0
- package/dist/network-BjZ1Y-GB.mjs +7 -0
- package/dist/outputPaths-BonGThuc.mjs +2 -0
- package/dist/parse-args-Cuk7-xUt.mjs +1 -0
- package/dist/platform-C446Lf97.mjs +93 -0
- package/dist/playwright-cdp-fallback-BwVR-_T3.mjs +1 -0
- package/dist/process-C9f2A5zk.mjs +962 -0
- package/dist/proxy-CvRepxgV.mjs +1 -0
- package/dist/registry-DUHIPE-v.mjs +1 -0
- package/dist/response-C7rKQst4.mjs +1 -0
- package/dist/search-defaults-D2bY-rzH.mjs +1 -0
- package/dist/server/plugin-api.mjs +1 -293
- package/dist/shared-state-board-Cyg-xh_k.mjs +1 -0
- package/dist/sourcemap-D6Q1UuAp.mjs +1 -0
- package/dist/ssrf-policy-T96MR3r6.mjs +1 -0
- package/dist/streaming-CTX58tbb.mjs +1 -0
- package/dist/tool-builder-CI9914Tf.mjs +1 -0
- package/dist/transform-Cv9P2vVD.mjs +103 -0
- package/dist/types-CuyefmGT.mjs +1 -0
- package/dist/types-DtThH00r.mjs +1 -0
- package/dist/wasm-DaJa8J0V.mjs +174 -0
- package/dist/webcrack-CsLLJIs9.mjs +46 -0
- package/dist/workflow-CYIXtrWD.mjs +101 -0
- package/package.json +12 -7
- package/dist/AntiCheatDetector-BNk-EoBt.mjs +0 -244
- package/dist/CacheAdapters-CDe5WPSV.mjs +0 -80
- package/dist/CodeInjector-Cq8q01kp.mjs +0 -150
- package/dist/ConsoleMonitor-CPVQW1Y-.mjs +0 -2201
- package/dist/DarwinAPI-BNPxu0RH.mjs +0 -363
- package/dist/DetailedDataManager-BQQcxh64.mjs +0 -217
- package/dist/EventBus-DgPmwpeu.mjs +0 -141
- package/dist/EvidenceGraphBridge-SFesNera.mjs +0 -153
- package/dist/ExtensionManager-CWYgw0YW.mjs +0 -714
- package/dist/FingerprintManager-gzWtkKuf.mjs +0 -96
- package/dist/HardwareBreakpoint-B9gZCdFP.mjs +0 -239
- package/dist/HeapAnalyzer-BLDH0dCv.mjs +0 -284
- package/dist/InstrumentationSession-CvPC7Jwy.mjs +0 -244
- package/dist/MemoryController-CbVdCIJF.mjs +0 -167
- package/dist/MemoryScanSession-BsDZbLYm.mjs +0 -278
- package/dist/MemoryScanner-Bcpml6II.mjs +0 -425
- package/dist/NativeMemoryManager.impl-dZtA1ZGn.mjs +0 -482
- package/dist/NativeMemoryManager.utils-B-FjA2mJ.mjs +0 -165
- package/dist/PEAnalyzer-D1lzJ_VG.mjs +0 -385
- package/dist/PageController-Bqm2kZ_X.mjs +0 -417
- package/dist/PointerChainEngine-BOhyVsjx.mjs +0 -322
- package/dist/PrerequisiteError-Dl33Svkz.mjs +0 -20
- package/dist/ResponseBuilder-D3iFYx2N.mjs +0 -143
- package/dist/ReverseEvidenceGraph-Dlsk94LC.mjs +0 -269
- package/dist/ScriptManager-aHHq0X7U.mjs +0 -3000
- package/dist/Speedhack-CqdIFlQl.mjs +0 -156
- package/dist/StealthVerifier-Bo4T3bz8.mjs +0 -135
- package/dist/StructureAnalyzer-DhFaPvRO.mjs +0 -426
- package/dist/ToolCatalog-C0JGZoOm.mjs +0 -582
- package/dist/ToolError-jh9whhMd.mjs +0 -15
- package/dist/ToolProbe-oC7aPrkv.mjs +0 -45
- package/dist/ToolRegistry-BjaF4oNz.mjs +0 -131
- package/dist/ToolRouter.policy-BWV67ZK-.mjs +0 -304
- package/dist/TraceRecorder-DgxyVbdQ.mjs +0 -519
- package/dist/VersionDetector-CwVLVdDM.mjs +0 -104
- package/dist/Win32API-CePkipZY.mjs +0 -340
- package/dist/Win32Debug-BvKs-gxc.mjs +0 -274
- package/dist/WorkflowEngine-CuvkZtWu.mjs +0 -598
- package/dist/analysis-CL9uACt9.mjs +0 -463
- package/dist/artifactRetention-CFEprwPw.mjs +0 -591
- package/dist/artifacts-Bk2-_uPq.mjs +0 -59
- package/dist/betterSqlite3-0pqusHHH.mjs +0 -74
- package/dist/binary-instrument-CXfpx6fT.mjs +0 -979
- package/dist/bind-helpers-xFfRF-qm.mjs +0 -22
- package/dist/boringssl-inspector-BH2D3VKc.mjs +0 -180
- package/dist/browser-BpOr5PEx.mjs +0 -4082
- package/dist/chunk-CjcI7cDX.mjs +0 -15
- package/dist/concurrency-Bt0yv1kJ.mjs +0 -41
- package/dist/constants-B0OANIBL.mjs +0 -519
- package/dist/coordination-qUbyF8KU.mjs +0 -259
- package/dist/debugger-gnKxRSN0.mjs +0 -1271
- package/dist/definitions-6M-eejaT.mjs +0 -53
- package/dist/definitions-B18eyf0B.mjs +0 -18
- package/dist/definitions-B3QdlrHv.mjs +0 -34
- package/dist/definitions-B4rAvHNZ.mjs +0 -63
- package/dist/definitions-BB_4jnmy.mjs +0 -37
- package/dist/definitions-BMfYXoNC.mjs +0 -43
- package/dist/definitions-Beid2EB3.mjs +0 -27
- package/dist/definitions-C1UvM5Iy.mjs +0 -126
- package/dist/definitions-CXEI7QC72.mjs +0 -216
- package/dist/definitions-C_4r7Fo-2.mjs +0 -14
- package/dist/definitions-CkFDALoa.mjs +0 -26
- package/dist/definitions-Cke7zEb8.mjs +0 -94
- package/dist/definitions-ClJLzsJQ.mjs +0 -25
- package/dist/definitions-Cq-zroAU.mjs +0 -28
- package/dist/definitions-Cy3Sl6gV.mjs +0 -34
- package/dist/definitions-D3VsGcvz.mjs +0 -47
- package/dist/definitions-DVGfrn7y.mjs +0 -96
- package/dist/definitions-LKpC3-nL.mjs +0 -9
- package/dist/definitions-bAhHQJq9.mjs +0 -359
- package/dist/encoding-Bvz5jLRv.mjs +0 -1065
- package/dist/evidence-graph-bridge-C_fv9PuC.mjs +0 -135
- package/dist/factory-DxlGh9Xf.mjs +0 -575
- package/dist/formatAddress-DVkj9kpI.mjs +0 -17
- package/dist/graphql-DYWzJ29s.mjs +0 -1026
- package/dist/handlers-9sAbfIg-.mjs +0 -2552
- package/dist/handlers-C67ktuRN.mjs +0 -710
- package/dist/handlers-C87g8oCe.mjs +0 -276
- package/dist/handlers-CTsDAO6p.mjs +0 -681
- package/dist/handlers-Cgyg6c0U.mjs +0 -645
- package/dist/handlers-D6j6yka7.mjs +0 -2124
- package/dist/handlers-DdFzXLvF.mjs +0 -446
- package/dist/handlers-DeLOCd5m.mjs +0 -799
- package/dist/handlers-DlCJN4Td.mjs +0 -757
- package/dist/handlers-DxGIq15_2.mjs +0 -917
- package/dist/handlers-U6L4xhuF.mjs +0 -585
- package/dist/handlers-tB9Mp9ZK.mjs +0 -84
- package/dist/handlers-tiy7EIBp.mjs +0 -572
- package/dist/handlers.impl-DS0d9fUw.mjs +0 -761
- package/dist/hooks-CzCWByww.mjs +0 -898
- package/dist/logger-Dh_xb7_2.mjs +0 -93
- package/dist/maintenance-P7ePRXQC.mjs +0 -830
- package/dist/manifest-2ToTpjv8.mjs +0 -106
- package/dist/manifest-3g71z6Bg.mjs +0 -79
- package/dist/manifest-82baTv4U.mjs +0 -45
- package/dist/manifest-B3QVVeBS.mjs +0 -82
- package/dist/manifest-BB2J8IMJ.mjs +0 -149
- package/dist/manifest-BKbgbSiY.mjs +0 -60
- package/dist/manifest-Bcf-TJzH.mjs +0 -848
- package/dist/manifest-BmtZzQiQ2.mjs +0 -45
- package/dist/manifest-Bnd7kqEY.mjs +0 -55
- package/dist/manifest-BqQX6OQC2.mjs +0 -65
- package/dist/manifest-BqrQ4Tpj.mjs +0 -81
- package/dist/manifest-Br4RPFt5.mjs +0 -370
- package/dist/manifest-C5qDjysN.mjs +0 -107
- package/dist/manifest-C9RT5nk32.mjs +0 -34
- package/dist/manifest-CAhOuvSl.mjs +0 -204
- package/dist/manifest-CBYWCUBJ.mjs +0 -51
- package/dist/manifest-CFADCRa1.mjs +0 -37
- package/dist/manifest-CQVhavRF.mjs +0 -114
- package/dist/manifest-CT7zZBV1.mjs +0 -48
- package/dist/manifest-CV12bcrF.mjs +0 -121
- package/dist/manifest-CXsRWjjI.mjs +0 -224
- package/dist/manifest-CZLUCfG02.mjs +0 -95
- package/dist/manifest-D6phHKFd.mjs +0 -131
- package/dist/manifest-DCyjf4n2.mjs +0 -294
- package/dist/manifest-DHsnKgP6.mjs +0 -60
- package/dist/manifest-Df_dliIe.mjs +0 -55
- package/dist/manifest-Dh8WBmEW.mjs +0 -129
- package/dist/manifest-DhKRAT8_.mjs +0 -92
- package/dist/manifest-DlpTj4ic2.mjs +0 -193
- package/dist/manifest-DrbmZcFl2.mjs +0 -253
- package/dist/manifest-DuwHjUa5.mjs +0 -70
- package/dist/manifest-DzwvxPJX.mjs +0 -38
- package/dist/manifest-NXctwWQq.mjs +0 -68
- package/dist/manifest-Sc_0JQ13.mjs +0 -418
- package/dist/manifest-gZ4s_UtG.mjs +0 -96
- package/dist/manifest-qSleDqdO.mjs +0 -1023
- package/dist/modules-C184v-S9.mjs +0 -11365
- package/dist/mojo-ipc-B_H61Afw.mjs +0 -525
- package/dist/network-671Cw6hV.mjs +0 -3346
- package/dist/outputPaths-B1uGmrWZ.mjs +0 -1145
- package/dist/parse-args-BlRjqlkL.mjs +0 -39
- package/dist/platform-WmNn8Sxb.mjs +0 -2070
- package/dist/process-QcbIy5Zq.mjs +0 -1401
- package/dist/proxy-DqNs0bAd.mjs +0 -170
- package/dist/registry-D-6e18lB.mjs +0 -34
- package/dist/response-BQVP-xUn.mjs +0 -28
- package/dist/shared-state-board-DV-dpHFJ.mjs +0 -586
- package/dist/sourcemap-Dq8ez8vS.mjs +0 -650
- package/dist/ssrf-policy-ZaUfvhq7.mjs +0 -166
- package/dist/streaming-BUQ0VJsg.mjs +0 -725
- package/dist/tool-builder-DCbIC5Eo.mjs +0 -186
- package/dist/transform-CiYJfNX0.mjs +0 -1007
- package/dist/types-Bx92KJfT.mjs +0 -4
- package/dist/types-CPhOReNX.mjs +0 -37
- package/dist/wasm-DQTnHDs4.mjs +0 -531
- package/dist/workflow-f3xJOcjx.mjs +0 -725
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{n as e}from"./chunk-C_pMuVsO.mjs";import{Ut as t}from"./constants-Cp6hBrrx.mjs";import{a as n,r}from"./parse-args-Cuk7-xUt.mjs";import{n as i,t as a}from"./capabilities-DbYCv-HF.mjs";import"./manifest-CGq4NpqH2.mjs";import{execFile as o,spawn as s}from"node:child_process";function c(){return[{name:`blink.mojom.WidgetHost`,version:1,pendingMessages:0},{name:`content.mojom.FrameHost`,version:2,pendingMessages:0},{name:`network.mojom.URLLoaderFactory`,version:3,pendingMessages:0}]}function l(){try{return e.resolve(`frida`),!0}catch{return!1}}async function u(){return new Promise(e=>{let n=s(`frida`,[`--version`],{timeout:t,windowsHide:!0}),r=``;n.stdout?.on(`data`,e=>{r+=e.toString()}),n.on(`close`,t=>{if(t===0&&r.trim().length>0){e(`frida`);return}e(null)}),n.on(`error`,()=>{e(null)})})}async function d(){let e=process.env.JSHOOK_ENABLE_MOJO_IPC,t=l(),n=await u(),r=t||n!==null;return e===`0`||e===`false`?{available:!1,fridaAvailable:r,fridaCliAvailable:n!==null,reason:`Mojo IPC disabled by JSHOOK_ENABLE_MOJO_IPC=0.`}:{available:r,fridaAvailable:r,fridaCliAvailable:n!==null,reason:r?void 0:`Mojo IPC backend is not connected. Install Frida for real IPC monitoring: https://frida.re/docs/installation/`}}function f(e,t){return!(t.interfaceName&&e.interfaceName!==t.interfaceName||t.messageType&&e.messageType!==t.messageType||typeof t.pid==`number`&&e.sourcePid!==t.pid&&e.targetPid!==t.pid)}function p(){return`
|
|
2
|
+
const messages = [];
|
|
3
|
+
recv('message', () => {});
|
|
4
|
+
rpc.exports = {
|
|
5
|
+
flush() {
|
|
6
|
+
return messages;
|
|
7
|
+
},
|
|
8
|
+
};
|
|
9
|
+
`}var m=class{active=!1;simulationMode=!1;fridaProbeSucceeded=!1;deviceId;messages=[];interfaces=new Map;observedInterfaceNames=new Set;availability={available:!1,fridaAvailable:!1,fridaCliAvailable:!1,reason:`Not yet initialized. Call start() to probe availability.`};constructor(){this.resetInterfaces()}isAvailable(){return this.availability.available}getUnavailableReason(){return this.availability.reason}getAvailabilitySnapshot(){return{...this.availability}}async probeAvailability(){return this.availability=await d(),this.getAvailabilitySnapshot()}isSimulationMode(){return this.simulationMode}didFridaProbeSucceed(){return this.fridaProbeSucceeded}setSimulationMode(e){this.simulationMode=e}isActive(){return this.active}getDeviceId(){return this.deviceId}async start(e){if(this.deviceId=e,this.availability=await d(),this.resetInterfaces(),this.simulationMode=!1,this.fridaProbeSucceeded=!1,!this.availability.available){this.active=!1;return}this.active=!0,this.availability.fridaCliAvailable?await this.captureWithFrida(e):this.simulationMode=!0}async stop(){this.active=!1,this.deviceId=void 0,this.fridaProbeSucceeded=!1,this.resetInterfaces()}async captureMessages(e={}){if(!this.active)return[];let t=[],n=[];for(let r of this.messages)f(r,e)?t.push({...r}):n.push(r);return this.messages.length=0,this.messages.push(...n),this.recomputePendingCounts(),t}async listInterfaces(){return[...this.interfaces.values()].map(e=>({name:e.name,version:e.version,pendingMessages:e.pendingMessages})).toSorted((e,t)=>e.name.localeCompare(t.name))}hasObservedInterfaces(){return this.observedInterfaceNames.size>0}getObservedInterfaceCount(){return this.observedInterfaceNames.size}getInterfaceCatalogSource(){return this.observedInterfaceNames.size===0?`seeded-defaults`:this.observedInterfaceNames.size>=this.interfaces.size?`observed`:`mixed`}async getMessages(e){if(!this.active)return{messages:[],totalAvailable:0,filtered:!1,simulation:this.simulationMode};let t={};e?.interfaceName&&(t.interfaceName=e.interfaceName);let n=await this.captureMessages(t),r=e?.limit??100;return{messages:n.slice(0,r),totalAvailable:n.length,filtered:!!e?.interfaceName,simulation:this.simulationMode}}recordMessage(e,t=1){if(!this.active)return;this.messages.push({...e}),this.observedInterfaceNames.add(e.interfaceName);let n=this.interfaces.get(e.interfaceName);if(n){n.pendingMessages+=1;return}this.interfaces.set(e.interfaceName,{name:e.interfaceName,version:t,pendingMessages:1})}async captureWithFrida(e){let n=e??`chrome`,r=p();await new Promise((e,i)=>{o(`frida`,[`-q`,`-n`,n,`-l`,`-`,`--runtime=v8`],{timeout:t,windowsHide:!0},t=>{if(t){i(t);return}e()}).stdin?.end(r)}).then(()=>{this.fridaProbeSucceeded=!0}).catch(()=>{this.fridaProbeSucceeded=!1}),this.simulationMode=!0}recomputePendingCounts(){this.resetPendingCounts();for(let e of this.messages){this.observedInterfaceNames.add(e.interfaceName);let t=this.interfaces.get(e.interfaceName);t?t.pendingMessages+=1:this.interfaces.set(e.interfaceName,{name:e.interfaceName,version:1,pendingMessages:1})}}resetPendingCounts(){for(let e of this.interfaces.values())e.pendingMessages=0}resetInterfaces(){this.messages.length=0,this.interfaces.clear(),this.observedInterfaceNames.clear();for(let e of c())this.interfaces.set(e.name,{...e})}};function h(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function g(e){return h(e)?typeof e.handle==`number`:!1}function _(e){let t=e.replace(/\s+/g,``);return t.length%2==0?t.toLowerCase():`0${t.toLowerCase()}`}var v=class{decodePayload(e,t){let n=this.cleanHex(e),r=Buffer.from(n,`hex`),i=this.readUInt8(r,0),a=this.readUInt8(r,1),o=this.readUInt8(r,2),s=this.readUInt8(r,3),c=this.readUInt16LE(r,4),l={},u=[],d=6,f=0;for(let e=0;e<s;e+=1){if(d>=r.length){u.push(`payload ended before all fields were decoded`);break}let t=this.readUInt8(r,d);d+=1;let n=`field${e}`;if(t===1){if(!this.hasBytes(r,d,1)){u.push(`${n} truncated`);break}l[n]=this.readUInt8(r,d)!==0,d+=1;continue}if(t===6){if(!this.hasBytes(r,d,4)){u.push(`${n} truncated`);break}l[n]=r.readInt32LE(d),d+=4;continue}if(t===8){if(!this.hasBytes(r,d,4)){u.push(`${n} truncated`);break}l[n]=r.readUInt32LE(d),d+=4;continue}if(t===12){if(!this.hasBytes(r,d,2)){u.push(`${n} length prefix truncated`);break}let e=this.readUInt16LE(r,d);if(d+=2,!this.hasBytes(r,d,e)){u.push(`${n} string data truncated`);break}l[n]=r.subarray(d,d+e).toString(`utf8`),d+=e;continue}if(t===16){if(!this.hasBytes(r,d,4)){u.push(`${n} handle truncated`);break}l[n]={handle:r.readUInt32LE(d)},f+=1,d+=4;continue}u.push(`unknown field type 0x${t.toString(16).padStart(2,`0`)}`);break}let p=u.length>0?u.join(`; `):this.buildSummary(t,Object.keys(l).length,s,f);return{header:{version:i,flags:a,messageType:o,numFields:s,handles:c},fields:l,handles:f,raw:n,_raw_summary:p}}encodeMessage(e,t,n){let r=[],i=0;for(let e of n){if(typeof e==`boolean`){r.push(Buffer.from([1,+!!e]));continue}if(typeof e==`number`&&Number.isInteger(e)&&e>=0){let t=Buffer.alloc(5);t.writeUInt8(8,0),t.writeUInt32LE(e,1),r.push(t);continue}if(typeof e==`number`&&Number.isInteger(e)){let t=Buffer.alloc(5);t.writeUInt8(6,0),t.writeInt32LE(e,1),r.push(t);continue}if(g(e)){let t=Buffer.alloc(5);t.writeUInt8(16,0),t.writeUInt32LE(e.handle,1),r.push(t),i+=1;continue}let t=typeof e==`string`?e:JSON.stringify(e),n=Buffer.from(t,`utf8`),a=Buffer.alloc(3);a.writeUInt8(12,0),a.writeUInt16LE(n.length,1),r.push(a,n)}let a=this.resolveMessageType(e,t),o=Math.min(n.length,255),s=Buffer.alloc(6);return s.writeUInt8(1,0),s.writeUInt8(0,1),s.writeUInt8(a,2),s.writeUInt8(o,3),s.writeUInt16LE(i,4),Buffer.concat([s,...r]).toString(`hex`)}cleanHex(e){return _(e)}resolveMessageType(e,t){if(/^[0-9]+$/.test(t))return Number.parseInt(t,10)&255;if(/^0x[0-9a-f]+$/i.test(t))return Number.parseInt(t.slice(2),16)&255;let n=0,r=`${e}:${t}`;for(let e of r)n=n*31+e.charCodeAt(0)&255;return n}buildSummary(e,t,n,r){return`${e?`${e}: `:``}decoded ${t}/${n} fields, ${r} handle(s)`}readUInt8(e,t){return this.hasBytes(e,t,1)?e.readUInt8(t):0}readUInt16LE(e,t){return this.hasBytes(e,t,2)?e.readUInt16LE(t):0}hasBytes(e,t,n){return t>=0&&n>=0&&t+n<=e.length}};function y(e){return e.includes(`JSHOOK_ENABLE_MOJO_IPC`)?`Unset JSHOOK_ENABLE_MOJO_IPC or set it to 1, then retry.`:`Install Frida and ensure the Chromium target is running.`}function b(e,t){return{...a(t,`mojo_ipc_monitoring`,e,y(e)),error:e}}function x(e){let t=e;return typeof t.didFridaProbeSucceed==`function`?t.didFridaProbeSucceed():!1}var S=class{monitor;decoder;eventBus;constructor(e,t,n){this.monitor=e,this.decoder=t,this.eventBus=n}async handleMojoMonitorDispatch(e){return String(e.action??``)===`stop`?this.handleMojoMonitorStop():this.handleMojoMonitorStart(e)}async handleMojoIpcCapabilities(){let e=this.getMonitor(),t=x(e),n=typeof e.probeAvailability==`function`?await e.probeAvailability():{available:e.isAvailable(),reason:e.getUnavailableReason(),fridaAvailable:e.isAvailable(),fridaCliAvailable:!1};return i(`mojo_ipc_capabilities`,[{capability:`mojo_ipc_monitoring`,status:n.available?`available`:`unavailable`,reason:n.reason,fix:n.available?void 0:y(n.reason??``),details:{tools:[`mojo_monitor`,`mojo_list_interfaces`,`mojo_messages_get`],fridaAvailable:n.fridaAvailable,fridaCliAvailable:n.fridaCliAvailable,fridaProbeSucceeded:t,active:e.isActive(),simulationMode:e.isSimulationMode(),interfaceCatalogSource:e.getInterfaceCatalogSource(),observedInterfaceCount:e.getObservedInterfaceCount(),liveCaptureImplemented:!1}},{capability:`mojo_live_capture`,status:`unavailable`,reason:`Current Mojo IPC backend only exposes a seeded interface catalog and simulated capture. Live Chromium Mojo hooks are not implemented in this build.`,fix:`No user-side fix is available in this build. Treat mojo_monitor/mojo_list_interfaces/mojo_messages_get as simulation-only until real Frida hooks are implemented.`,details:{tools:[`mojo_monitor`,`mojo_list_interfaces`,`mojo_messages_get`],fridaAvailable:n.fridaAvailable,fridaCliAvailable:n.fridaCliAvailable,fridaProbeSucceeded:t,active:e.isActive(),simulationMode:e.isSimulationMode(),interfaceCatalogSource:e.getInterfaceCatalogSource(),observedInterfaceCount:e.getObservedInterfaceCount(),fallbackMode:n.available?`simulation`:`none`,liveCaptureImplemented:!1}},{capability:`mojo_payload_decode`,status:`available`,details:{tools:[`mojo_decode_message`]}}])}async handleMojoMonitorStart(e){let t=this.getMonitor(),r=n(e,`deviceId`);if(await t.start(r),!t.isAvailable())return b(t.getUnavailableReason()??`Mojo IPC monitoring is not available`,`mojo_monitor`);let i={success:!0,available:!0,started:t.isActive(),deviceId:t.getDeviceId()??null,simulation:t.isSimulationMode(),interfaceCatalogSource:t.getInterfaceCatalogSource(),observedInterfaceCount:t.getObservedInterfaceCount()};return t.isSimulationMode()&&(i.warningMessage=`Mojo IPC monitor is running in simulation mode. Real Frida-backed message capture is not active.`),i}async handleMojoMonitorStop(){let e=this.getMonitor();return e.isAvailable()?(await e.stop(),{success:!0,available:!0,started:!1,simulation:e.isSimulationMode()}):b(e.getUnavailableReason()??`Mojo IPC monitoring is not available`,`mojo_monitor`)}async handleMojoDecodeMessage(e){let t=n(e,`hexPayload`,``);return t.length===0?{success:!1,error:`hexPayload is required`}:{success:!0,decoded:this.getDecoder().decodePayload(t)}}async handleMojoListInterfaces(){let e=this.getMonitor();if(!e.isAvailable())return{...b(e.getUnavailableReason()??`Mojo IPC monitoring is not available`,`mojo_list_interfaces`),interfaces:[]};let t={success:!0,available:!0,active:e.isActive(),interfaces:await e.listInterfaces(),simulation:e.isSimulationMode(),interfaceCatalogSource:e.getInterfaceCatalogSource(),observedInterfaceCount:e.getObservedInterfaceCount()};return e.getInterfaceCatalogSource()===`seeded-defaults`?t.warningMessage=`Interface list currently comes from the seeded default catalog; no live observed Mojo interfaces have been captured yet.`:e.isSimulationMode()&&(t.warningMessage=`Mojo IPC monitor is running in simulation mode. Interface counts may not reflect live traffic.`),t}async handleMojoMessagesGet(e){let t=this.getMonitor();if(!t.isAvailable())return{...b(t.getUnavailableReason()??`Mojo IPC monitoring is not available`,`mojo_messages_get`),messages:[],totalAvailable:0,filtered:!1,simulation:!0};let i=r(e,`limit`),a=n(e,`interface`),o=await t.getMessages({limit:i===void 0?100:Math.min(i,1e4),interfaceName:a}),s={success:!0,available:!0,active:t.isActive(),messages:o.messages,totalAvailable:o.totalAvailable,filtered:o.filtered,simulation:o.simulation,interfaceCatalogSource:t.getInterfaceCatalogSource(),observedInterfaceCount:t.getObservedInterfaceCount()};return o.messages&&Array.isArray(o.messages)&&o.messages.length>0&&this.eventBus?.emit(`mojo:message_captured`,{messageCount:o.messages.length,timestamp:new Date().toISOString()}),t.isSimulationMode()&&(s.warningMessage=`Mojo IPC is operating in simulation mode. Messages are not captured from real Frida hooks. Install Frida for live IPC monitoring.`),s}getMonitor(){return this.monitor||=new m,this.monitor}getDecoder(){return this.decoder||=new v,this.decoder}};export{S as MojoIPCHandlers};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{t as e}from"./logger-sBC6IdRT.mjs";import{Gt as t,Kt as n,ft as r,g as i,mt as a,pt as o}from"./constants-Cp6hBrrx.mjs";import{t as s}from"./DetailedDataManager-BniBJlVv.mjs";import{r as c}from"./modules-p-PUNv9r.mjs";import{n as l,t as u}from"./parse-args-Cuk7-xUt.mjs";import{a as d,c as f,i as p,l as m,n as h,o as g,r as _,s as v,t as y}from"./ssrf-policy-T96MR3r6.mjs";import{t as b}from"./ResponseBuilder-B2lu4KEl.mjs";import"./definitions-Dgrg7f3D.mjs";import*as x from"node:http";import{createHash as S}from"node:crypto";import{promises as C}from"node:fs";import w from"koffi";import*as T from"node:net";import*as E from"node:dns/promises";import*as ee from"node:tls";import*as te from"node:http2";import*as ne from"node:https";const re=new Set([`Image`,`Font`,`Stylesheet`,`Media`,`Manifest`,`Ping`]),ie={XHR:0,Fetch:1,Document:2,Script:3,WebSocket:4,EventSource:5},D=e=>typeof e==`object`&&!!e,ae=e=>D(e)?typeof e.url==`string`&&typeof e.method==`string`:!1,oe=e=>D(e)?typeof e.status==`number`:!1,se=e=>typeof e==`number`&&Number.isFinite(e),O=e=>typeof e==`string`?e:void 0,ce=e=>typeof e==`boolean`?e:void 0,k=e=>typeof e==`number`&&Number.isFinite(e)?e:void 0,le=e=>{if(Array.isArray(e))return e.every(e=>typeof e==`string`)?e:void 0},ue=e=>!(!D(e)||e.hitCount!==void 0&&typeof e.hitCount!=`number`||e.callFrame!==void 0&&!D(e.callFrame)||D(e.callFrame)&&(e.callFrame.functionName!==void 0&&typeof e.callFrame.functionName!=`string`||e.callFrame.url!==void 0&&typeof e.callFrame.url!=`string`||e.callFrame.lineNumber!==void 0&&typeof e.callFrame.lineNumber!=`number`)),de=e=>!D(e)||!Array.isArray(e.nodes)||typeof e.startTime!=`number`||typeof e.endTime!=`number`||!e.nodes.every(e=>ue(e))?null:{nodes:e.nodes,samples:Array.isArray(e.samples)?e.samples:void 0,startTime:e.startTime,endTime:e.endTime};function fe(){return s.getInstance()}function A(e,t,n){e?.emit(t,n)}function j(e,t){if(typeof e==`boolean`)return e;if(typeof e==`number`)return e===1?!0:e===0?!1:t;if(typeof e==`string`){let t=e.trim().toLowerCase();if([`true`,`1`,`yes`,`on`].includes(t))return!0;if([`false`,`0`,`no`,`off`].includes(t))return!1}return t}function M(e,t){let n;if(typeof e==`number`&&Number.isFinite(e))n=e;else if(typeof e==`string`){let t=e.trim();if(t.length>0){let e=Number(t);Number.isFinite(e)&&(n=e)}}return n===void 0&&(n=t.defaultValue),t.integer&&(n=Math.trunc(n)),typeof t.min==`number`&&(n=Math.max(t.min,n)),typeof t.max==`number`&&(n=Math.min(t.max,n)),n}function pe(e,t,n){if(!D(t))return null;let r=O(t.url),i=O(t.method);if(!r||!i)return null;let a=k(t.timestamp),o=O(t.requestId)??`${e.toLowerCase()}-injected-${a??0}-${n}`;return{...t,requestId:o,url:r,method:i,type:O(t.type)??e,timestamp:a,injected:!0,captureSource:`inpage`}}function me(e){let t=(e.type??``).toString().toLowerCase();return t.includes(`xhr`)?`xhr`:t.includes(`fetch`)?`fetch`:t||`unknown`}function he(e){return`${e.method.toUpperCase()}|${e.url}|${me(e)}`}function ge(e){return`${e.method.toUpperCase()}|${e.url}`}function _e(e,t){let n=k(e.timestamp),r=k(t.timestamp);return n===void 0||r===void 0?!1:Math.abs(n-r)<=1500}function ve(e,t){let n=me(e),r=me(t);return n===r||n===`unknown`||r===`unknown`}function ye(e,t,n,r,i){if(!e)return null;for(let a=0;a<e.length;a+=1){let o=e[a];if(o===void 0||n.has(o))continue;let s=t[o];if(!(!s||!_e(s,r))&&!(i&&!ve(s,r)))return e.splice(a,1),o}return null}async function be(e){let t=e.getNetworkRequests().filter(e=>ae(e)).map(e=>({...e,captureSource:`cdp`})),[n,r]=await Promise.all([typeof e.getXHRRequests==`function`?e.getXHRRequests().catch(()=>[]):Promise.resolve([]),typeof e.getFetchRequests==`function`?e.getFetchRequests().catch(()=>[]):Promise.resolve([])]),i=n.map((e,t)=>pe(`XHR`,e,t)).filter(e=>e!==null),a=r.map((e,t)=>pe(`Fetch`,e,t)).filter(e=>e!==null),o=[...i,...a],s=new Set,c=new Map,l=new Map;t.forEach((e,t)=>{let n=he(e),r=ge(e);c.set(n,[...c.get(n)??[],t]),l.set(r,[...l.get(r)??[],t])});for(let e of o){let n=e.requestId?t.findIndex((t,n)=>!s.has(n)&&t.requestId===e.requestId):-1,r=he(e),i=ge(e),a=n>=0?n:ye(c.get(r),t,s,e,!1)??ye(l.get(i),t,s,e,!0);if(a===null||a===-1){t.push(e);continue}s.add(a);let o=t[a];t[a]={...e,...o,injected:!!(o.injected||e.injected),captureSource:e.captureSource??o.captureSource}}return t}const xe=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i,Se=/\/[0-9a-f]{16,}(?=[/?#]|$)/gi,Ce=/\/\d{2,}(?=[/?#]|$)/g;function we(e){try{let t=new URL(e),n=t.pathname;return n=n.replace(xe,`{id}`),n=n.replace(Se,`/{id}`),n=n.replace(Ce,`/{id}`),`${t.origin}${n}`}catch{return e}}var Te=class{deps;detailedDataManager=fe();constructor(e){this.deps=e}async handleNetworkMonitor(e){let t=String(e.action??``);switch(t){case`enable`:return this.handleNetworkEnable(e);case`disable`:return this.handleNetworkDisable(e);case`status`:return this.handleNetworkGetStatus(e);default:return b.fail(`Invalid generic action parameter: ${t}. Expected enable, disable, status.`).json()}}async handleNetworkEnable(e){try{let t=j(e.enableExceptions,!0);await this.deps.consoleMonitor.enable({enableNetwork:!0,enableExceptions:t});let n=this.deps.consoleMonitor.getNetworkStatus();return b.ok().merge({message:` Network monitoring enabled successfully`,enabled:n.enabled,cdpSessionActive:n.cdpSessionActive,listenerCount:n.listenerCount,usage:{step1:`Network monitoring is now active`,step2:`Navigate to a page using page_navigate tool`,step3:`Use network_get_requests to retrieve captured requests`,step4:`Use network_get_response_body to get response content`},important:`Network monitoring must be enabled BEFORE navigating to capture requests`}).json()}catch(e){return b.fail(e).json()}}async handleNetworkDisable(e){try{return await this.deps.consoleMonitor.disable(),b.ok().set(`message`,`Network monitoring disabled`).json()}catch(e){return b.fail(e).json()}}async handleNetworkGetStatus(e){try{let e=this.deps.consoleMonitor.getNetworkStatus();return e.enabled?b.ok().merge({enabled:!0,message:` Network monitoring is active. Captured ${e.requestCount} requests and ${e.responseCount} responses.`,requestCount:e.requestCount,responseCount:e.responseCount,listenerCount:e.listenerCount,cdpSessionActive:e.cdpSessionActive,nextSteps:e.requestCount===0?{hint:`No requests captured yet`,action:`Navigate to a page using page_navigate to capture network traffic`}:{hint:`${e.requestCount} requests captured`,action:`Use network_get_requests to retrieve them`}}).json():b.fail(` Network monitoring is NOT enabled`).merge({enabled:!1,nextSteps:{step1:`Call network_enable tool to start monitoring`,step2:`Then navigate to a page using page_navigate`,step3:`Finally use network_get_requests to see captured requests`},example:`network_enable -> page_navigate -> network_get_requests`}).json()}catch(e){return b.fail(e).json()}}async getMergedNetworkRequests(){return await be(this.deps.consoleMonitor)}async handleNetworkGetRequests(e){try{let t=j(e.autoEnable,!0),n=j(e.enableExceptions,!0),r=await this.ensureNetworkEnabled({autoEnable:t,enableExceptions:n});if(!r.enabled)return this.buildNotEnabledResponse(t,r.error);let i=O(e.url),a=O(e.urlRegex),o=O(e.method),s=se(e.sinceTimestamp)?e.sinceTimestamp:void 0,c=O(e.sinceRequestId),l=se(e.tail)&&e.tail>0?Math.floor(e.tail):void 0,u=j(e.deduplicateUrls,!1),d=e.fields,f=Array.isArray(d)&&d.length>0?d.filter(e=>typeof e==`string`):void 0,p=M(e.limit,{defaultValue:100,min:1,max:1e3,integer:!0}),m=M(e.offset,{defaultValue:0,min:0,integer:!0}),h=await this.getMergedNetworkRequests();if(h.length===0)return this.buildEmptyRequestsResponse(r.autoEnabled);let g=this.applyRequestFilters(h,{url:i,urlRegex:a,method:o,sinceTimestamp:s,sinceRequestId:c,tail:l,limit:p,offset:m,autoEnabled:r.autoEnabled,fields:f,deduplicateUrls:u}),_=this.detailedDataManager.smartHandle(g.finalPayload,25600);return b.ok().merge(_).json()}catch(e){return b.fail(e).json()}}async handleNetworkGetResponseBody(e){try{let t=O(e.requestId)||``,n=M(e.maxSize,{defaultValue:1e5,min:1024,max:20*1024*1024,integer:!0}),r=j(e.returnSummary,!1),i=M(e.retries,{defaultValue:3,min:0,max:10,integer:!0}),a=M(e.retryIntervalMs,{defaultValue:500,min:50,max:5e3,integer:!0}),o=j(e.autoEnable,!1),s=j(e.enableExceptions,!0);if(!t)return b.fail(`requestId parameter is required`).set(`hint`,`Get requestId from network_get_requests tool`).json();let c=await this.ensureNetworkEnabled({autoEnable:o,enableExceptions:s});if(!c.enabled)return b.fail(`Network monitoring is not enabled`).merge({hint:o?`Auto-enable failed. Check active page and call network_enable manually.`:`Use network_enable tool first, or set autoEnable=true`,detail:c.error}).json();let l=null,u=0;for(let e=0;e<=i&&(u=e+1,l=await this.deps.consoleMonitor.getResponseBody(t),!l);e+=1)e<i&&await new Promise(e=>setTimeout(e,a));return l?this.buildResponseBodyResult(t,l,u,n,r):b.fail(`No response body found for requestId: ${t}`).merge({hint:`The request may not have completed yet, or the requestId is invalid`,attempts:u,waitedMs:i*a,retryConfig:{retries:i,retryIntervalMs:a}}).json()}catch(e){return b.fail(e).json()}}async handleNetworkGetStats(e){try{if(!this.deps.consoleMonitor.isNetworkEnabled())return b.fail(`Network monitoring is not enabled`).set(`hint`,`Use network_enable tool first`).json();let e=this.deps.consoleMonitor.getNetworkRequests().filter(e=>ae(e)),t=this.deps.consoleMonitor.getNetworkResponses().filter(oe),n={};e.forEach(e=>{n[e.method]=(n[e.method]||0)+1});let r={};t.forEach(e=>{r[e.status]=(r[e.status]||0)+1});let i={};e.forEach(e=>{let t=e.type||`unknown`;i[t]=(i[t]||0)+1});let a=e.map(e=>e.timestamp).filter(e=>se(e)),o=a.length>0?{earliest:Math.min(...a),latest:Math.max(...a),duration:Math.max(...a)-Math.min(...a)}:null;return b.ok().set(`stats`,{totalRequests:e.length,totalResponses:t.length,byMethod:n,byStatus:r,byType:i,timeStats:o,monitoringEnabled:!0}).json()}catch(e){return b.fail(e).json()}}async ensureNetworkEnabled(e){if(this.deps.consoleMonitor.isNetworkEnabled())return{enabled:!0,autoEnabled:!1};if(!e.autoEnable)return{enabled:!1,autoEnabled:!1};try{return await this.deps.consoleMonitor.enable({enableNetwork:!0,enableExceptions:e.enableExceptions}),{enabled:this.deps.consoleMonitor.isNetworkEnabled(),autoEnabled:!0}}catch(e){return{enabled:!1,autoEnabled:!1,error:e instanceof Error?e.message:String(e)}}}buildNotEnabledResponse(e,t){return e&&t?b.fail(`Failed to auto-enable network monitoring`).merge({detail:t,solution:{step1:`Ensure browser page is active and reachable`,step2:`Call network_enable manually`,step3:`Navigate to target page: page_navigate(url)`,step4:`Get requests: network_get_requests`}}).json():b.fail(` Network monitoring is not enabled`).merge({requests:[],total:0,solution:{step1:`Enable network monitoring: network_enable`,step2:`Navigate to target page: page_navigate(url)`,step3:`Get requests: network_get_requests`},tip:`Set autoEnable=true to auto-enable monitoring in this call`}).json()}buildEmptyRequestsResponse(e){return b.ok().merge({message:`No network requests captured yet`,requests:[],total:0,hint:`Network monitoring is enabled, but no requests have been captured`,possibleReasons:[`1. You haven't navigated to any page yet (use page_navigate)`,`2. The page has already loaded before network monitoring was enabled`,`3. The page doesn't make any network requests`,`4. The page uses frontend-wrapped fetch/XHR not captured by CDP`],recommended_actions:[`console_inject_fetch_interceptor() — capture frontend-wrapped fetch calls (SPAs, React, Vue)`,`console_inject_xhr_interceptor() — capture XMLHttpRequest calls`,`page_navigate(url, enableNetworkMonitoring=true) — re-navigate with monitoring enabled`],nextAction:`Call console_inject_fetch_interceptor(), then re-navigate or trigger the target action`,monitoring:{autoEnabled:e}}).json()}applyRequestFilters(e,t){let{url:n,urlRegex:r,method:i,sinceTimestamp:a,sinceRequestId:o,tail:s,limit:c,offset:l,autoEnabled:u,fields:d,deduplicateUrls:f}=t,p=e.length,m=e.map(e=>e.url),h=!!(n||r||i&&i.toUpperCase()!==`ALL`||a||o||s),g=0;if(!h){let t=e.length;e=e.filter(e=>!e.type||!re.has(e.type)),g=t-e.length}if(o){let t=e.findIndex(e=>e.requestId===o);t>=0&&(e=e.slice(t+1))}if(a!==void 0&&(e=e.filter(e=>(e.timestamp??0)>a)),r){if(r.length>500)throw Error(`urlRegex too long (max 500 characters)`);let t=new RegExp(r,`i`);if(e.length>0){let n=performance.now();t.test(e[0].url);let r=performance.now()-n;if(r>100)throw Error(`urlRegex pattern is too expensive (${r.toFixed(0)}ms on first URL). Use a simpler pattern.`)}e=e.filter(e=>t.test(e.url))}else if(n){let t=n.toLowerCase();e=e.filter(e=>e.url.toLowerCase().includes(t))}i&&i.toUpperCase()!==`ALL`&&(e=e.filter(e=>e.method.toUpperCase()===i.toUpperCase())),s!==void 0&&e.length>s&&(e=e.slice(-s)),e.sort((e,t)=>(ie[e.type??``]??6)-(ie[t.type??``]??6));let _=e.length;e=e.slice(l,l+c);let v=l+e.length<_,y=_===0&&p>0&&!!(n||i&&i.toUpperCase()!==`ALL`),b=y?m.slice(0,10).map(e=>e.substring(0,120)):void 0;if(f){let t=new Map;for(let n of e){let e=we(n.url),r=`${n.method.toUpperCase()} ${e}`,i=t.get(r);i?i.count++:t.set(r,{pattern:e,method:n.method.toUpperCase(),count:1,example:n.url})}let n=[...t.values()].toSorted((e,t)=>t.count-e.count);return{finalPayload:{message:` Deduplicated ${e.length} requests into ${n.length} unique endpoint(s)`,endpoints:n,totalRequests:e.length,uniqueEndpoints:n.length,stats:{totalCaptured:p,afterFilter:_},filtered:h,monitoring:{autoEnabled:u}}}}let x=d?e.map(e=>{let t={};for(let n of d)n in e&&(t[n]=e[n]);return t}):e;return{finalPayload:{message:` Retrieved ${e.length} network request(s)`,requests:x,total:e.length,page:{offset:l,limit:c,returned:e.length,totalAfterFilter:_,hasMore:v,nextOffset:v?l+e.length:null},stats:{totalCaptured:p,afterFilter:_,returned:e.length,truncated:_>l+c},filtered:h,filters:{url:n,urlRegex:r,method:i,sinceTimestamp:a,sinceRequestId:o,tail:s,limit:c,offset:l},monitoring:{autoEnabled:u},...y&&{filterMiss:!0,hint:`URL filter "${n}" matched 0 of ${p} captured requests. Check urlSamples to verify the correct filter substring.`,urlSamples:b},tip:e.length>0?`Use network_get_response_body(requestId) to get response content`:void 0,...g>0&&{staticResourcesExcluded:g,staticFilterNote:`${g} static resources (Image/Font/Stylesheet/Media) excluded by default. Set any filter to include all types.`},...p>100&&!h&&{optimizationHint:`${p} requests captured. Use url/method filters to reduce payload size.`}}}}buildResponseBodyResult(e,t,n,r,i){let a=t.body.length,o=a>r;if(i||o){let i=t.body.substring(0,500);return b.ok().merge({requestId:e,attempts:n,summary:{size:a,sizeKB:(a/1024).toFixed(2),base64Encoded:t.base64Encoded,preview:i+(a>500?`...`:``),truncated:o,reason:o?`Response too large (${(a/1024).toFixed(2)} KB > ${(r/1024).toFixed(2)} KB)`:`Summary mode enabled`},tip:o?`Use collect_code tool to collect and compress this script, or increase maxSize parameter`:`Set returnSummary=false to get full body`}).json()}return b.ok().merge({requestId:e,attempts:n,body:t.body,base64Encoded:t.base64Encoded,size:a,sizeKB:(a/1024).toFixed(2)}).json()}},Ee=class{deps;constructor(e){this.deps=e}async handlePerformanceGetMetrics(e){try{let t=e.includeTimeline===!0,n=this.deps.getPerformanceMonitor(),r=await n.getPerformanceMetrics(),i=b.ok().set(`metrics`,r);return t&&i.set(`timeline`,await n.getPerformanceTimeline()),i.json()}catch(e){return b.fail(e).json()}}async handlePerformanceCoverage(e){return l(e,`action`,new Set([`start`,`stop`]))===`stop`?this.handlePerformanceStopCoverage(e):this.handlePerformanceStartCoverage(e)}async handlePerformanceStartCoverage(e){try{return await this.deps.getPerformanceMonitor().startCoverage(),b.ok().set(`message`,`Code coverage collection started`).json()}catch(e){return b.fail(e).json()}}async handlePerformanceStopCoverage(e){try{let e=await this.deps.getPerformanceMonitor().stopCoverage(),t=e.length>0?e.reduce((e,t)=>e+t.coveragePercentage,0)/e.length:0;return b.ok().merge({coverage:e,totalScripts:e.length,avgCoverage:t}).json()}catch(e){return b.fail(e).json()}}async handlePerformanceTakeHeapSnapshot(e){try{let e=this.deps.getTraceRecorder?.()??null;if(e?.getState()===`recording`)try{let t=await e.captureActiveHeapSnapshot();return b.ok().merge({snapshotSize:t,persistedToTrace:!0,message:`Heap snapshot taken and persisted to the active trace recording (data too large to return)`}).json()}catch(e){let t=await this.deps.getPerformanceMonitor().takeHeapSnapshot();return b.ok().merge({snapshotSize:t,persistedToTrace:!1,tracePersistenceError:e instanceof Error?e.message:String(e),message:`Heap snapshot taken, but the active trace recording could not persist it (data too large to return)`}).json()}let t=await this.deps.getPerformanceMonitor().takeHeapSnapshot();return b.ok().merge({snapshotSize:t,persistedToTrace:!1,message:`Heap snapshot taken (data too large to return, saved internally)`}).json()}catch(e){return b.fail(e).json()}}async handlePerformanceTraceStart(e){try{let t=this.deps.getPerformanceMonitor(),n=le(e.categories),r=ce(e.screenshots);return await t.startTracing({categories:n,screenshots:r}),b.ok().set(`message`,`Performance tracing started. Call performance_trace with action="stop" to save the trace.`).json()}catch(e){return b.fail(e).json()}}async handlePerformanceTraceStop(e){try{let t=this.deps.getPerformanceMonitor(),n=O(e.artifactPath),r=await t.stopTracing({artifactPath:n});return b.ok().merge({artifactPath:r.artifactPath,eventCount:r.eventCount,sizeBytes:r.sizeBytes,sizeKB:(r.sizeBytes/1024).toFixed(1),hint:`Open the trace file in Chrome DevTools -> Performance tab -> Load profile`}).json()}catch(e){return b.fail(e).json()}}async handleProfilerCpuStart(e){try{return await this.deps.getPerformanceMonitor().startCPUProfiling(),b.ok().set(`message`,`CPU profiling started. Call profiler_cpu with action="stop" to save the profile.`).json()}catch(e){return b.fail(e).json()}}async handleProfilerCpuStop(e){try{let t=await this.deps.getPerformanceMonitor().stopCPUProfiling(),n=de(t)||t,{writeFile:r}=await import(`node:fs/promises`),{resolveArtifactPath:i}=await import(`./artifacts-B5xQuEa_.mjs`).then(e=>e.t),a=O(e.artifactPath),o=JSON.stringify(n,null,2),s;if(a)await r(a,o,`utf-8`),s=a;else{let{absolutePath:e,displayPath:t}=await i({category:`profiles`,toolName:`cpu-profile`,ext:`cpuprofile`});await r(e,o,`utf-8`),s=t}let c=n.nodes.filter(e=>(e.hitCount||0)>0).toSorted((e,t)=>(t.hitCount||0)-(e.hitCount||0)).slice(0,20).map(e=>({functionName:e.callFrame?.functionName||`(anonymous)`,url:e.callFrame?.url,line:e.callFrame?.lineNumber,hitCount:e.hitCount}));return b.ok().merge({artifactPath:s,totalNodes:n.nodes.length,totalSamples:n.samples?.length||0,durationMs:n.endTime-n.startTime,hotFunctions:c,hint:`Open the .cpuprofile file in Chrome DevTools -> Performance tab`}).json()}catch(e){return b.fail(e).json()}}async handleProfilerHeapSamplingStart(e){try{let t=this.deps.getPerformanceMonitor(),n=k(e.samplingInterval);return await t.startHeapSampling({samplingInterval:n}),b.ok().set(`message`,`Heap sampling started. Call profiler_heap_sampling with action="stop" to save the report.`).json()}catch(e){return b.fail(e).json()}}async handleProfilerHeapSamplingStop(e){try{let t=this.deps.getPerformanceMonitor(),n=O(e.artifactPath),r=k(e.topN),i=await t.stopHeapSampling({artifactPath:n,topN:r});return b.ok().merge({artifactPath:i.artifactPath,sampleCount:i.sampleCount,topAllocations:i.topAllocations}).json()}catch(e){return b.fail(e).json()}}},De=class{deps;constructor(e){this.deps=e}async handleConsoleGetExceptions(e){try{let t=O(e.url),n=M(e.limit,{defaultValue:50,min:1,max:1e3,integer:!0}),r=this.deps.consoleMonitor.getExceptions();return t&&(r=r.filter(e=>e.url?.includes(t))),r=r.slice(0,n),b.ok().merge({exceptions:r,total:r.length}).json()}catch(e){return b.fail(e).json()}}async handleConsoleInjectScriptMonitor(e){try{let t=u(e,`persistent`,!1);return await this.deps.consoleMonitor.enableDynamicScriptMonitoring({persistent:t}),b.ok().set(`message`,t?`Dynamic script monitoring enabled (persistent — survives navigations)`:`Dynamic script monitoring enabled`).json()}catch(e){return b.fail(e).json()}}async handleConsoleInjectXhrInterceptor(e){try{let t=u(e,`persistent`,!1);return await this.deps.consoleMonitor.injectXHRInterceptor({persistent:t}),b.ok().set(`message`,t?`XHR interceptor injected (persistent)`:`XHR interceptor injected`).json()}catch(e){return b.fail(e).json()}}async handleConsoleInjectFetchInterceptor(e){try{let t=u(e,`persistent`,!1);return await this.deps.consoleMonitor.injectFetchInterceptor({persistent:t}),b.ok().set(`message`,t?`Fetch interceptor injected (persistent)`:`Fetch interceptor injected`).json()}catch(e){return b.fail(e).json()}}async handleConsoleClearInjectedBuffers(e){try{let e=await this.deps.consoleMonitor.clearInjectedBuffers();return b.ok().merge({message:`Injected buffers cleared`,...e}).json()}catch(e){return b.fail(e).json()}}async handleConsoleResetInjectedInterceptors(e){try{let e=await this.deps.consoleMonitor.resetInjectedInterceptors();return b.ok().merge({message:`Injected interceptors/monitors reset`,...e}).json()}catch(e){return b.fail(e).json()}}async handleConsoleInjectFunctionTracer(e){try{let t=O(e.functionName)||``;if(!t)return b.fail(`functionName is required`).json();let n=u(e,`persistent`,!1);return await this.deps.consoleMonitor.injectFunctionTracer(t,{persistent:n}),b.ok().set(`message`,n?`Function tracer injected for: ${t} (persistent — survives navigations)`:`Function tracer injected for: ${t}`).json()}catch(e){return b.fail(e).json()}}};const Oe=[`authorization`,`cookie`,`x-token`,`x-auth-token`,`x-access-token`,`x-api-key`,`x-signature`,`x-sign`,`x-csrf-token`],ke=/^(token|access_token|refresh_token|sign|signature|auth|jwt|api_key|apikey|key|secret)$/i,Ae=/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/,je=/^Bearer\s+\S+/i;function N(e){let t=e.trim();return t.length<=12?`***`:`${t.slice(0,6)}***${t.slice(-4)}`}function P(e){let t=e.trim();return je.test(t)?.95:Ae.test(t)?.9:t.length>20&&/^[A-Za-z0-9+/=_-]+$/.test(t)?.7:t.length>10?.5:.3}function Me(e){let t=[],n=new Set;for(let r of e){let e=r.headers??{};for(let[i,a]of Object.entries(e)){let e=i.toLowerCase();if(!Oe.includes(e)||!a||a.length<4)continue;if(e===`cookie`){for(let e of a.split(`;`)){let i=e.indexOf(`=`);if(i===-1)continue;let a=e.slice(0,i).trim(),o=e.slice(i+1).trim();if(!o||o.length<8)continue;let s=`cookie:${a}:${o.slice(0,8)}`;n.has(s)||(n.add(s),t.push({header:`cookie[${a}]`,value_masked:N(o),request_url:r.url,confidence:P(o),source:`cookie`}))}continue}let o=`header:${e}:${a.slice(0,8)}`;n.has(o)||(n.add(o),t.push({header:i,value_masked:N(a),request_url:r.url,confidence:P(a),source:`header`}))}try{let e=new URL(r.url);for(let[i,a]of e.searchParams.entries()){if(!ke.test(i)||!a||a.length<8)continue;let e=`query:${i}:${a.slice(0,8)}`;n.has(e)||(n.add(e),t.push({header:i,value_masked:N(a),request_url:r.url,confidence:P(a)*.9,source:`query`}))}}catch{}if(r.postData)try{let e=JSON.parse(r.postData);if(e&&typeof e==`object`)for(let[i,a]of Object.entries(e)){if(!ke.test(i)||typeof a!=`string`||a.length<8)continue;let e=`body:${i}:${a.slice(0,8)}`;n.has(e)||(n.add(e),t.push({header:i,value_masked:N(a),request_url:r.url,confidence:P(a)*.85,source:`body`}))}}catch{}}return t.toSorted((e,t)=>t.confidence-e.confidence)}function Ne(e={}){return Object.entries(e).map(([e,t])=>({name:e,value:t}))}function Pe(e){return e.split(`;`).map(e=>{let t=e.indexOf(`=`);return t===-1?{name:e.trim(),value:``}:{name:e.slice(0,t).trim(),value:e.slice(t+1).trim()}})}function Fe(e){try{let t=new URL(e);return Array.from(t.searchParams.entries()).map(([e,t])=>({name:e,value:t}))}catch{return[]}}async function Ie(e){let{requests:n,getResponse:r,getResponseBody:i,includeBodies:a,creatorVersion:o=`unknown`}=e,s=[],c=new Map;if(a){let e=t;for(let t=0;t<n.length;t+=e){let r=n.slice(t,t+e),a=await Promise.allSettled(r.map(async e=>{try{let t=await i(e.requestId);return t?{requestId:e.requestId,text:t.body}:{requestId:e.requestId,_bodyUnavailable:!0}}catch{return{requestId:e.requestId,_bodyUnavailable:!0}}}));for(let e of a)if(e.status===`fulfilled`){let t=e.value;c.set(t.requestId,`_bodyUnavailable`in t?{_bodyUnavailable:!0}:{text:t.text})}}}for(let e of n){let t=r(e.requestId),n=e.timestamp?new Date(e.timestamp*1e3).toISOString():new Date().toISOString(),i=a?c.get(e.requestId)??{_bodyUnavailable:!0}:{},o=e.postData?{mimeType:e.headers?.[`content-type`]??`application/octet-stream`,text:e.postData}:void 0,l=e.headers?.cookie??``,u=t?.headers?.[`set-cookie`]??``,d={startedDateTime:n,time:t?.timing?.receiveHeadersEnd??0,request:{method:e.method,url:e.url,httpVersion:`HTTP/1.1`,headers:Ne(e.headers),queryString:Fe(e.url),cookies:l?Pe(l):[],headersSize:-1,bodySize:e.postData?e.postData.length:0,...o?{postData:o}:{}},response:{status:t?.status??0,statusText:t?.statusText??``,httpVersion:`HTTP/1.1`,headers:Ne(t?.headers),cookies:u?Pe(u):[],content:{size:i.text?i.text.length:-1,mimeType:t?.mimeType??`application/octet-stream`,...i},redirectURL:t?.headers?.location??``,headersSize:-1,bodySize:i.text?i.text.length:-1},cache:{},timings:{send:0,wait:t?.timing?.receiveHeadersEnd??0,receive:0},_requestId:e.requestId};s.push(d)}return{log:{version:`1.2`,creator:{name:`jshookmcp`,version:o},entries:s}}}const Le=new Set([`host`,`content-length`,`transfer-encoding`,`connection`,`keep-alive`,`proxy-authenticate`,`proxy-authorization`,`te`,`trailers`,`upgrade`]),Re=new Set([`__proto__`,`constructor`,`prototype`]);function ze(e){let t=[];for(let n of e.cookies)n.name&&t.push(`${n.name}=${n.value}`);return t.length>0?t.join(`; `):void 0}function Be(e){let t=Object.create(null);for(let[n,r]of Object.entries(e))!Le.has(n.toLowerCase())&&!Re.has(n)&&(t[n]=r);return t}async function Ve(e,t,r=512e3){let i=t.urlOverride??e.url,a=(t.methodOverride??e.method).toUpperCase(),o=Be({...e.headers,...t.headerPatch}),s=t.sessionProfile?ze(t.sessionProfile):void 0;s&&(o.Cookie=s),t.sessionProfile?.userAgent&&!o[`User-Agent`]&&!o[`user-agent`]&&(o[`User-Agent`]=t.sessionProfile.userAgent),t.sessionProfile?.acceptLanguage&&!o[`Accept-Language`]&&!o[`accept-language`]&&(o[`Accept-Language`]=t.sessionProfile.acceptLanguage),t.sessionProfile?.referer&&!o.Referer&&!o.referer&&(o.Referer=t.sessionProfile.referer);let c=t.bodyPatch===void 0?e.postData:t.bodyPatch,l=y(t.authorization),u=!l&&p();if(l&&(l.allowPrivateNetwork||l.allowInsecureHttp)&&!h(l))throw Error(`Replay authorization must include at least one allowed host or CIDR when enabling private network or insecure HTTP access.`);if(g(l))throw Error(`Replay authorization expired before the request was executed.`);let b=e=>u?!0:l?.allowPrivateNetwork===!0&&_(l,e),x=e=>e.parsedUrl.protocol!==`http:`||u||d(e.hostname)?!0:l?.allowInsecureHttp===!0&&_(l,e),S=async e=>{let t;try{t=await m(e)}catch{throw Error(`Replay blocked: DNS resolution failed for "${e}"`)}if(!x(t))throw Error(`Replay blocked: insecure HTTP is only allowed for loopback or explicitly authorized targets, got "${e}"`);let n=v(t.hostname),r=v(t.resolvedAddress??``);if((n||r)&&!b(t))throw!n&&r&&t.resolvedAddress?Error(`Replay blocked: "${e}" resolved to private IP ${t.resolvedAddress}`):Error(`Replay blocked: target URL "${e}" resolves to a private/reserved address.`);if(t.parsedUrl.protocol===`https:`||t.isIpLiteral)return{pinnedUrl:e,originalHost:t.parsedUrl.host,target:t};let i=t.parsedUrl.host;return t.parsedUrl.hostname=t.resolvedAddress&&t.resolvedAddress.includes(`:`)?`[${t.resolvedAddress}]`:t.resolvedAddress??t.hostname,{pinnedUrl:t.parsedUrl.toString(),originalHost:i,target:t}};if(t.dryRun!==!1){if(await f(i,t.authorization))throw Error(`Replay blocked: target URL "${i}" resolves to a private/reserved address.`);let e=await m(i).catch(()=>null);if(e&&!x(e))throw Error(`Replay blocked: insecure HTTP is only allowed for loopback or explicitly authorized targets, got "${i}"`);return{dryRun:!0,preview:{url:i,method:a,headers:o,body:c}}}let C=new AbortController,w=setTimeout(()=>C.abort(),t.timeoutMs??3e4),T=n;try{let e=i,n=a,s=c,l;for(let t=0;t<T;t++){let{pinnedUrl:t,originalHost:r,target:i}=await S(e),a={...o};if(i.parsedUrl.protocol===`http:`&&i.resolvedAddress&&!i.isIpLiteral&&(a.Host=r),l=await fetch(t,{method:n,headers:a,body:n!==`GET`&&n!==`HEAD`?s:void 0,signal:C.signal,redirect:`manual`}),l.status>=300&&l.status<400){let t=l.headers.get(`location`);if(!t)break;e=new URL(t,e).toString(),(l.status===301||l.status===302||l.status===303)&&(n=`GET`,s=void 0),delete o.Host,delete o.host;continue}break}if(l.status>=300&&l.status<400)throw Error(`Replay blocked: too many redirects (>${T})`);let u={};l.headers.forEach((e,t)=>{u[t]=e});let d=await l.text(),f=d.length>r,p=f?d.slice(0,r):d;return{dryRun:!1,status:l.status,statusText:l.statusText,headers:u,body:p,bodyTruncated:f,requestId:t.requestId}}finally{clearTimeout(w)}}const He=e=>{if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.requestId==`string`&&typeof t.url==`string`&&typeof t.method==`string`},Ue=(e,t)=>{if(e===void 0)return[];if(!Array.isArray(e)||e.some(e=>typeof e!=`string`))throw Error(`${t} must be an array of strings`);return e.map(e=>e.trim()).filter(e=>e.length>0)},We=(e,t)=>{if(e===void 0)return;if(typeof e!=`string`)throw Error(`${t} must be a string`);let n=e.trim();return n.length>0?n:void 0},Ge=(e,t)=>{if(e!==void 0){if(typeof e!=`boolean`)throw Error(`${t} must be a boolean`);return e}},Ke=(e,t)=>{if(typeof e!=`string`||e.trim().length===0)throw Error(`authorizationCapability must be a non-empty base64url string`);let n;try{n=JSON.parse(Buffer.from(e,`base64url`).toString(`utf8`))}catch{throw Error(`authorizationCapability must be valid base64url-encoded JSON`)}if(typeof n!=`object`||!n||Array.isArray(n))throw Error(`authorizationCapability payload must be an object`);let r=n;if(r.version!==void 0&&r.version!==1)throw Error(`authorizationCapability version ${String(r.version)} is not supported`);if(r.requestId!==t)throw Error(`authorizationCapability requestId does not match the replay requestId`);return r},qe=(e,t)=>{let n=e.authorization,r=e.authorizationCapability;if(n!==void 0&&r!==void 0)throw Error(`Provide either authorization or authorizationCapability, not both`);let i;if(n!==void 0){if(typeof n!=`object`||!n||Array.isArray(n))throw Error(`authorization must be an object`);i=n}else if(r!==void 0)i=Ke(r,t);else return;let a=Ue(i.allowedHosts,`authorization.allowedHosts`),o=Ue(i.allowedCidrs,`authorization.allowedCidrs`),s=Ge(i.allowPrivateNetwork,`authorization.allowPrivateNetwork`),c=Ge(i.allowInsecureHttp,`authorization.allowInsecureHttp`),l=We(i.expiresAt,`authorization.expiresAt`),u=We(i.reason,`authorization.reason`),d={};return a.length>0&&(d.allowedHosts=a),o.length>0&&(d.allowedCidrs=o),s!==void 0&&(d.allowPrivateNetwork=s),c!==void 0&&(d.allowInsecureHttp=c),l!==void 0&&(d.expiresAt=l),u!==void 0&&(d.reason=u),d};var Je=class{deps;detailedDataManager=fe();constructor(e){this.deps=e}async handleNetworkExtractAuth(e){try{let t=M(e.minConfidence,{defaultValue:.4}),n=this.deps.consoleMonitor.getNetworkRequests();if(n.length===0)return b.fail(`No captured requests found. Call network_enable then page_navigate first.`).json();let r=Me(n).filter(e=>e.confidence>=t);return b.ok().merge({scannedRequests:n.length,found:r.length,findings:r,note:`Values are masked (first 6 + last 4 chars). Use network_replay_request to test with actual values.`}).json()}catch(e){return b.fail(e).json()}}async handleNetworkExportHar(e){try{let t=e.outputPath,n=j(e.includeBodies,!1),r;if(t){let e=await import(`node:path`),n=await import(`node:fs/promises`),i=e.resolve(t),a=await n.realpath(process.cwd()),o=await n.realpath((await import(`node:os`)).tmpdir()),s=e.dirname(i),c;try{c=await n.realpath(s)}catch{c=s}let l=e.join(c,e.basename(i)),u=l===a||l.startsWith(a+e.sep),d=l===o||l.startsWith(o+e.sep);if(!u&&!d)return b.fail(`outputPath must be within the current working directory or system temp dir.`).json();r=l}let i=this.deps.consoleMonitor.getNetworkRequests();if(i.length===0)return b.fail(`No captured requests to export. Call network_enable then page_navigate first.`).json();let a=await Ie({requests:i,getResponse:e=>this.deps.consoleMonitor.getNetworkActivity(e)?.response,getResponseBody:async e=>{try{return await this.deps.consoleMonitor.getResponseBody(e)}catch{return null}},includeBodies:n,creatorVersion:`1.0.0`});if(r){try{if((await C.lstat(r)).isSymbolicLink())return b.fail(`outputPath must not be a symbolic link.`).json()}catch{}return await C.writeFile(r,JSON.stringify(a,null,2),`utf-8`),b.ok().merge({message:`HAR exported to ${r}`,entryCount:a.log.entries.length,outputPath:r}).json()}let o=this.detailedDataManager.smartHandle({entryCount:a.log.entries.length,har:a},51200);return b.ok().merge(o).json()}catch(e){return b.fail(e).json()}}async handleNetworkReplayRequest(e){try{let t=e.requestId;if(!t)return b.fail(`requestId is required`).json();let n=this.deps.consoleMonitor.getNetworkRequests().find(e=>He(e)&&e.requestId===t);if(!n)return b.fail(`Request ${t} not found in captured requests`).merge({hint:`Use network_get_requests to list available requestIds`}).json();let r=qe(e,t),i=await Ve(n,{requestId:t,headerPatch:e.headerPatch,sessionProfile:e.sessionProfile,bodyPatch:e.bodyPatch,methodOverride:e.methodOverride,urlOverride:e.urlOverride,timeoutMs:e.timeoutMs,dryRun:e.dryRun!==!1,authorization:r});return b.ok().merge(i).json()}catch(e){return b.fail(e).json()}}};const Ye=e=>typeof e==`object`&&!!e;var Xe=class{deps;constructor(e){this.deps=e}async handleNetworkInterceptResponse(e){try{let t=this.parseInterceptRules(e);if(t.length===0)return b.fail(`No valid rules provided. Provide either "urlPattern" (single) or "rules" array (batch).`).merge({usage:{single:{urlPattern:`*api/status*`,responseCode:200,responseBody:`{"status":"active"}`},batch:{rules:[{urlPattern:`*api/status*`,responseBody:`{"status":"active"}`}]}}}).json();let n=await this.deps.consoleMonitor.enableFetchIntercept(t),r=this.deps.consoleMonitor.getFetchInterceptStatus();return A(this.deps.eventBus,`network:intercept_started`,{interceptType:`fetch`,timestamp:new Date().toISOString()}),b.ok().merge({message:`Added ${n.length} interception rule(s)`,createdRules:n.map(e=>({id:e.id,urlPattern:e.urlPattern,interceptAction:e.interceptAction,stage:e.stage,responseCode:e.responseCode})),totalActiveRules:r.rules.length,hint:`Use network_intercept(action: "list") to see all rules and hit counts. Use network_intercept(action: "disable") to remove rules.`}).json()}catch(e){return b.fail(e instanceof Error?e.message:String(e)).merge({hint:`Ensure browser is launched and a page is active before enabling interception.`}).json()}}async handleNetworkInterceptList(e){let t=this.deps.consoleMonitor.getFetchInterceptStatus();return b.ok().merge(t).merge({hint:t.rules.length>0?`Use network_intercept(action: "disable", ruleId) to remove a specific rule, or network_intercept(action: "disable", all: true) to remove all.`:`No active interception rules. Use network_intercept(action: "add") to add rules.`}).json()}async handleNetworkInterceptDisable(e){let t=typeof e.ruleId==`string`?e.ruleId:void 0,n=e.all===!0;if(!t&&!n)return b.fail(`Provide either "ruleId" to remove a specific rule, or "all": true to disable all.`).json();try{if(n){let e=await this.deps.consoleMonitor.disableFetchIntercept();return b.ok().merge({message:`Disabled all interception. Removed ${e.removedRules} rule(s).`,removedRules:e.removedRules}).json()}let e=await this.deps.consoleMonitor.removeFetchInterceptRule(t),r=this.deps.consoleMonitor.getFetchInterceptStatus();return b.ok().merge({success:e,message:e?`Rule ${t} removed.`:`Rule ${t} not found.`,remainingRules:r.rules.length}).json()}catch(e){return b.fail(e instanceof Error?e.message:String(e)).json()}}parseInterceptRules(e){let t=[];if(Array.isArray(e.rules))for(let n of e.rules)Ye(n)&&typeof n.urlPattern==`string`&&t.push(this.toInterceptRule(n));else typeof e.urlPattern==`string`&&t.push(this.toInterceptRule(e));return t}toInterceptRule(e){return{urlPattern:e.urlPattern,urlPatternType:e.urlPatternType===`regex`?`regex`:`glob`,stage:e.stage===`Request`?`Request`:`Response`,interceptAction:this.toInterceptAction(e.interceptAction),responseCode:typeof e.responseCode==`number`?e.responseCode:200,responseHeaders:Ye(e.responseHeaders)?e.responseHeaders:void 0,responseBody:typeof e.responseBody==`string`?e.responseBody:typeof e.responseBody==`object`?JSON.stringify(e.responseBody):void 0}}toInterceptAction(e){return e===`continue`||e===`abort`?e:`fulfill`}},Ze=class{chunks=[];totalLength=0;get length(){return this.totalLength}append(e){e.length!==0&&(this.chunks.push(e),this.totalLength+=e.length)}toBuffer(){if(this.chunks.length===0)return Buffer.alloc(0);if(this.chunks.length===1)return this.chunks[0];let e=Buffer.concat(this.chunks,this.totalLength);return this.chunks=[e],e}reset(){this.chunks=[],this.totalLength=0}get isEmpty(){return this.totalLength===0}};const Qe=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,$e=/^(?:text\/|application\/(?:json|ld\+json|xml|xhtml\+xml|javascript|x-javascript|problem\+json|problem\+xml|graphql-response\+json|x-www-form-urlencoded)|image\/svg\+xml)/i;function et(e,t){if(e.includes(`\r`)||e.includes(`
|
|
2
|
+
`))throw Error(`${t} must not contain CR or LF characters`)}function F(e,t){return Object.keys(e).some(e=>e.toLowerCase()===t.toLowerCase())}function tt(e,t){return e.find(e=>e.name.toLowerCase()===t.toLowerCase())?.value??null}function nt(e,t){return t?.toUpperCase()===`HEAD`||e>=100&&e<200||e===204||e===304}function rt(e){let t=e.indexOf(`\r
|
|
3
|
+
\r
|
|
4
|
+
`);if(t>=0)return t+4;let n=e.indexOf(`
|
|
5
|
+
|
|
6
|
+
`);return n>=0?n+2:null}function it(e,t){let n=e.indexOf(10,t);return n<0?null:{lineEnd:n>t&&e[n-1]===13?n-1:n,nextOffset:n+1}}function at(e){let t=[],n=0;for(;n<e.length;){let r=it(e,n);if(!r)return{complete:!1,consumedBytes:n,body:Buffer.concat(t)};let i=e.subarray(n,r.lineEnd).toString(`latin1`).trim().split(`;`,1)[0]?.trim()??``,a=Number.parseInt(i,16);if(!Number.isFinite(a)||a<0)return{complete:!1,consumedBytes:n,body:Buffer.concat(t)};if(a===0){let i=e.subarray(r.nextOffset),a=rt(i);return a===null?i.length>=2&&i[0]===13&&i[1]===10?{complete:!0,consumedBytes:r.nextOffset+2,body:Buffer.concat(t)}:i.length>=1&&i[0]===10?{complete:!0,consumedBytes:r.nextOffset+1,body:Buffer.concat(t)}:{complete:!1,consumedBytes:n,body:Buffer.concat(t)}:{complete:!0,consumedBytes:r.nextOffset+a,body:Buffer.concat(t)}}let o=r.nextOffset,s=o+a;if(s>e.length)return{complete:!1,consumedBytes:n,body:Buffer.concat(t)};t.push(e.subarray(o,s));let c=it(e,s);if(!c||c.lineEnd!==s)return{complete:!1,consumedBytes:n,body:Buffer.concat(t)};n=c.nextOffset}return{complete:!1,consumedBytes:n,body:Buffer.concat(t)}}function ot(e){let t=Object.entries(e);return t.length===0?``:`${t.map(([e,t])=>`${e}: ${t}`).join(`\r
|
|
7
|
+
`)}\r\n`}function st(e){let t=e.method.trim().toUpperCase(),n=e.target.trim(),r=e.httpVersion??`1.1`;if(!Qe.test(t))throw Error(`method must be a valid HTTP token`);if(n.length===0)throw Error(`target is required`);if(et(n,`target`),r!==`1.0`&&r!==`1.1`)throw Error(`httpVersion must be either "1.0" or "1.1"`);let i={};for(let[t,n]of Object.entries(e.headers??{})){if(!Qe.test(t))throw Error(`Invalid HTTP header name: ${t}`);if(typeof n!=`string`)throw Error(`HTTP header "${t}" must be a string`);et(n,`headers.${t}`),i[t]=n}e.addHostHeader!==!1&&e.host&&!F(i,`Host`)&&(et(e.host,`host`),i.Host=e.host);let a=e.body??``;e.body!==void 0&&e.addContentLength!==!1&&!F(i,`Content-Length`)&&(F(i,`Transfer-Encoding`)||(i[`Content-Length`]=String(Buffer.byteLength(a,`utf8`)))),e.addConnectionClose!==!1&&!F(i,`Connection`)&&(i.Connection=`close`);let o=`${t} ${n} HTTP/${r}`,s=`${o}\r\n${ot(i)}\r\n${a}`,c=Buffer.from(s,`utf8`);return{requestText:s,requestHex:c.toString(`hex`),requestBytes:c.length,startLine:o,headers:i,bodyBytes:Buffer.byteLength(a,`utf8`),httpVersion:r}}function ct(e,t){let n=rt(e);if(n===null)return null;let r=e.subarray(0,n).toString(`latin1`).replace(/\r?\n\r?\n$/,``).split(/\r?\n/).filter(e=>e.length>0);if(r.length===0)throw Error(`HTTP response did not contain a status line`);let i=r[0],a=/^HTTP\/(\d+\.\d+)\s+(\d{3})(?:\s+(.*))?$/.exec(i);if(!a)throw Error(`Invalid HTTP status line: ${i}`);let o=[],s={};for(let e of r.slice(1)){let t=e.indexOf(`:`);if(t<=0)continue;let n=e.slice(0,t).trim(),r=e.slice(t+1).trim();o.push({name:n,value:r}),n in s?(n.toLowerCase(),s[n]=`${s[n]}, ${r}`):s[n]=r}let c=Number.parseInt(a[2],10),l=e.subarray(n);if(nt(c,t))return{statusLine:i,httpVersion:a[1],statusCode:c,statusText:a[3]??``,headers:s,rawHeaders:o,headerBytes:n,bodyBytes:0,bodyBuffer:Buffer.alloc(0),bodyMode:`none`,complete:!0,expectedRawBytes:n,chunkedDecoded:!1};if(tt(o,`transfer-encoding`)?.toLowerCase().includes(`chunked`)){let e=at(l);return{statusLine:i,httpVersion:a[1],statusCode:c,statusText:a[3]??``,headers:s,rawHeaders:o,headerBytes:n,bodyBytes:e.body.length,bodyBuffer:e.complete?e.body:l,bodyMode:`chunked`,complete:e.complete,expectedRawBytes:e.complete?n+e.consumedBytes:null,chunkedDecoded:e.complete}}let u=tt(o,`content-length`);if(u!==null){let e=Number.parseInt(u,10);if(Number.isFinite(e)&&e>=0){let t=l.subarray(0,Math.min(l.length,e));return{statusLine:i,httpVersion:a[1],statusCode:c,statusText:a[3]??``,headers:s,rawHeaders:o,headerBytes:n,bodyBytes:t.length,bodyBuffer:t,bodyMode:`content-length`,complete:l.length>=e,expectedRawBytes:n+e,chunkedDecoded:!1}}}return{statusLine:i,httpVersion:a[1],statusCode:c,statusText:a[3]??``,headers:s,rawHeaders:o,headerBytes:n,bodyBytes:l.length,bodyBuffer:l,bodyMode:`until-close`,complete:!1,expectedRawBytes:null,chunkedDecoded:!1}}function lt(e,t){if(t.length===0||e&&$e.test(e))return!0;let n=t.subarray(0,Math.min(t.length,64));for(let e of n)if(e===0)return!1;return!0}const I=2147483647,ut=4294967295,L={DATA:0,RST_STREAM:3,SETTINGS:4,PING:6,GOAWAY:7,WINDOW_UPDATE:8};function R(e,t,n,r){if(!Number.isInteger(e)||e<n||e>r)throw Error(`${t} must be an integer between ${String(n)} and ${String(r)}`)}function dt(e,t){let n=e.replace(/\s+/g,``).trim();if(n.length===0)return Buffer.alloc(0);if(n.length%2!=0||!/^[0-9a-fA-F]+$/.test(n))throw Error(`${t} must be an even-length hexadecimal string`);return Buffer.from(n,`hex`)}function ft(e,t){return Buffer.from(e,t)}function pt(e,t,n){if(e!==void 0&&t!==void 0)throw Error(`payloadHex and payloadText are mutually exclusive`);return e===void 0?t===void 0?Buffer.alloc(0):ft(t,n):dt(e,`payloadHex`)}function mt(e){let t=Buffer.alloc(e.length*6);return e.forEach((e,n)=>{R(e.id,`settings[${String(n)}].id`,0,65535),R(e.value,`settings[${String(n)}].value`,0,ut),t.writeUInt16BE(e.id,n*6),t.writeUInt32BE(e.value>>>0,n*6+2)}),t}function ht(e,t){R(e,t,0,I);let n=Buffer.alloc(4);return n.writeUInt32BE(e>>>0,0),n[0]&=127,n}function gt(e){let t=e.frameType,n=e.flags??0;switch(R(n,`flags`,0,255),t){case`DATA`:return{payload:pt(e.payloadHex,e.payloadText,e.payloadEncoding??`utf8`),typeCode:L.DATA,flags:n};case`SETTINGS`:if(e.ack===!0&&(e.settings?.length??0)>0)throw Error(`SETTINGS ack frames must not include settings payload`);return{payload:mt(e.settings??[]),typeCode:L.SETTINGS,flags:e.ack?n|1:n};case`PING`:{let t=e.pingOpaqueDataHex?dt(e.pingOpaqueDataHex,`pingOpaqueDataHex`):Buffer.alloc(8);if(t.length!==8)throw Error(`PING frames require exactly 8 bytes of opaque data`);return{payload:t,typeCode:L.PING,flags:e.ack?n|1:n}}case`WINDOW_UPDATE`:{let t=e.windowSizeIncrement;if(t===void 0)throw Error(`windowSizeIncrement is required for WINDOW_UPDATE frames`);return R(t,`windowSizeIncrement`,1,I),{payload:ht(t,`windowSizeIncrement`),typeCode:L.WINDOW_UPDATE,flags:n}}case`RST_STREAM`:{let t=e.errorCode??0;R(t,`errorCode`,0,ut);let r=Buffer.alloc(4);return r.writeUInt32BE(t>>>0,0),{payload:r,typeCode:L.RST_STREAM,flags:n}}case`GOAWAY`:{let t=e.lastStreamId??0,r=e.errorCode??0;R(t,`lastStreamId`,0,I),R(r,`errorCode`,0,ut);let i=e.debugDataText===void 0?Buffer.alloc(0):ft(e.debugDataText,e.debugDataEncoding??`utf8`);return{payload:Buffer.concat([ht(t,`lastStreamId`),Buffer.from([r>>>24&255,r>>>16&255,r>>>8&255,r&255]),i]),typeCode:L.GOAWAY,flags:n}}case`RAW`:{let t=e.frameTypeCode;if(t===void 0)throw Error(`frameTypeCode is required when frameType is RAW`);return R(t,`frameTypeCode`,0,255),{payload:pt(e.payloadHex,e.payloadText,e.payloadEncoding??`utf8`),typeCode:t,flags:n}}}}function _t(e,t){if((e===`SETTINGS`||e===`PING`||e===`GOAWAY`)&&t!==0)throw Error(`${e} frames must use streamId 0`);if((e===`DATA`||e===`RST_STREAM`)&&t===0)throw Error(`${e} frames must use a non-zero streamId`)}function vt(e){let t=e.streamId??0;R(t,`streamId`,0,I),_t(e.frameType,t);let{payload:n,typeCode:r,flags:i}=gt(e);if(n.length>16777215)throw Error(`payload exceeds the HTTP/2 maximum frame size of 16777215 bytes`);let a=Buffer.alloc(9);a[0]=n.length>>>16&255,a[1]=n.length>>>8&255,a[2]=n.length&255,a[3]=r&255,a[4]=i&255,a.writeUInt32BE(t>>>0,5),a[5]&=127;let o=Buffer.concat([a,n]);return{frameType:e.frameType,typeCode:r,streamId:t,flags:i,payloadBytes:n.length,payloadHex:n.toString(`hex`),frameHeaderHex:a.toString(`hex`),frameHex:o.toString(`hex`)}}const yt=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;function z(e,t){if(e===void 0)return;if(typeof e!=`string`)throw Error(`${t} must be a string`);let n=e.trim();return n.length>0?n:void 0}function B(e,t,n={}){if(e!==void 0){if(typeof e!=`string`)throw Error(`${t} must be a string`);if(!(e.length===0&&!n.allowEmpty))return e}}function bt(e,t){if(e!==void 0){if(typeof e!=`boolean`)throw Error(`${t} must be a boolean`);return e}}function V(e,t){if(e===void 0)return[];if(!Array.isArray(e)||e.some(e=>typeof e!=`string`))throw Error(`${t} must be an array of strings`);return e.map(e=>e.trim()).filter(e=>e.length>0)}function xt(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`${t} must be an object`);let n={};for(let[r,i]of Object.entries(e)){if(!yt.test(r))throw Error(`${t} contains an invalid HTTP header name: ${r}`);if(typeof i!=`string`)throw Error(`${t}.${r} must be a string`);n[r]=i}return n}function H(e,t=`authorization`){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`${t} must be an object`);let n=e,r=V(n.allowedHosts,`${t}.allowedHosts`),i=V(n.allowedCidrs,`${t}.allowedCidrs`),a=bt(n.allowPrivateNetwork,`${t}.allowPrivateNetwork`),o=bt(n.allowInsecureHttp,`${t}.allowInsecureHttp`),s=z(n.expiresAt,`${t}.expiresAt`),c=z(n.reason,`${t}.reason`),l={};return r.length>0&&(l.allowedHosts=r),i.length>0&&(l.allowedCidrs=i),a!==void 0&&(l.allowPrivateNetwork=a),o!==void 0&&(l.allowInsecureHttp=o),s!==void 0&&(l.expiresAt=s),c!==void 0&&(l.reason=c),l}function U(e,t,n){return Math.min(Math.max(e,t),n)}function W(e){return Math.round(e*100)/100}function St(e){let t=[...e].toSorted((e,t)=>e-t);return t.length===0?null:{count:t.length,minMs:t[0],maxMs:t[t.length-1],avgMs:W(t.reduce((e,t)=>e+t,0)/t.length),p50Ms:t[Math.floor(t.length*.5)],p90Ms:t[Math.floor(t.length*.9)],p95Ms:t[Math.floor(t.length*.95)],p99Ms:t[Math.floor(t.length*.99)]}}async function G(e,t,n){let r;try{r=new URL(e)}catch{throw Error(`url must be an absolute http:// or https:// URL`)}if(r.protocol!==`http:`&&r.protocol!==`https:`)throw Error(`url must use the http:// or https:// scheme`);let i=y(t),a=!i&&p();if(i&&(i.allowPrivateNetwork||i.allowInsecureHttp)&&!h(i))throw Error(`authorization must include at least one allowed host or CIDR when enabling private network or insecure HTTP access.`);if(g(i))throw Error(`authorization expired before the request was executed.`);let o;try{o=await m(r.toString())}catch{throw Error(`${n} blocked: DNS resolution failed for "${r.toString()}"`)}let s=e=>a?!0:i?.allowPrivateNetwork===!0&&_(i,e),c=e=>a||d(e.hostname)?!0:i?.allowInsecureHttp===!0&&_(i,e),l=Number.parseInt(r.port||(r.protocol===`https:`?`443`:`80`),10);if(r.protocol===`http:`&&!c(o))throw Error(`${n} blocked: insecure HTTP is only allowed for loopback or explicitly authorized targets, got "${o.hostname}:${String(l)}"`);let u=v(o.hostname),f=v(o.resolvedAddress??``),b=d(o.hostname)||d(o.resolvedAddress??``);if((u||f)&&!b&&!s(o))throw!u&&f&&o.resolvedAddress?Error(`${n} blocked: "${o.hostname}:${String(l)}" resolved to private IP ${o.resolvedAddress}`):Error(`${n} blocked: target "${o.hostname}:${String(l)}" resolves to a private or reserved address.`);return{url:r,target:o,authorizationPolicy:i,allowLegacyLocalSsrf:a}}function Ct(e){let t=e.trim();return t.startsWith(`[`)&&t.endsWith(`]`)?t.slice(1,-1):t}function wt(e){return e.includes(`:`)&&!e.startsWith(`[`)?`[${e}]`:e}function Tt(e){let t=(e.split(/\r?\n/,1)[0]?.trim()??``).split(/\s+/,1)[0]?.trim().toUpperCase()??``;if(!yt.test(t))throw Error(`requestText must start with a valid HTTP request line`);return t}async function Et(e,t,n,r,i,a){return await new Promise((o,s)=>{let c=T.createConnection({host:e,port:t}),l=!1,u=!1,d=new Ze,f=()=>{c.removeAllListeners(),c.destroy()},p=e=>{l||(l=!0,f(),o({rawResponse:d.toBuffer(),endedBy:e}))},m=e=>{l||(l=!0,f(),s(e))};c.setTimeout(i),c.once(`connect`,()=>{c.end(n)}),c.on(`data`,e=>{if(u=!0,d.append(e),d.length>a){p(`max-bytes`);return}let t=ct(d.toBuffer(),r);if(!(!t||!t.complete)){if(t.bodyMode===`none`){p(`no-body`);return}if(t.bodyMode===`content-length`){p(`content-length`);return}t.bodyMode===`chunked`&&p(`chunked`)}}),c.once(`timeout`,()=>{if(!u){m(Error(`Timed out waiting for HTTP response from ${e}:${String(t)}`));return}p(`timeout`)}),c.once(`end`,()=>{p(`socket-close`)}),c.once(`error`,e=>{m(e)})})}function Dt(e){return e===void 0?null:Array.isArray(e)?e.map(e=>String(e)):String(e)}function Ot(e){let t={};for(let[n,r]of Object.entries(e)){let e=Dt(r);e!==null&&(t[n]=e)}return t}function kt(e){if(!e)return null;let t=e.trim();return t.length>0?t:null}function At(e){let t={};for(let[n,r]of Object.entries(e??{}))t[n.toLowerCase()]=r;return t}function jt(e){let{url:t,target:n,method:r,requestHeaders:i,bodyBuffer:a,timeoutMs:o,maxBodyBytes:s,effectivePort:c,requestedAlpnProtocols:l,connectTimeoutMs:u=1e4}=e,d=null;return new Promise((e,f)=>{let p=!1,m,h=new Ze,g=!1,_=null,v=null,y=te.connect(t.origin,{createConnection:()=>{if(t.protocol===`https:`){let e=ee.connect({host:n.resolvedAddress??n.hostname,port:c,servername:n.hostname,ALPNProtocols:l,rejectUnauthorized:!0}),r=setTimeout(()=>{e.destroy(Error(`Timed out connecting to ${t.toString()} (${u}ms)`))},u);return e.once(`secureConnect`,()=>{clearTimeout(r),d=kt(e.alpnProtocol)}),e.once(`error`,()=>clearTimeout(r)),e.setTimeout(o,()=>{e.destroy(Error(`Timed out probing HTTP/2 endpoint ${t.toString()}`))}),v=e,e}let e=T.connect({host:n.resolvedAddress??n.hostname,port:c});return e.setTimeout(o,()=>{e.destroy(Error(`Timed out probing HTTP/2 endpoint ${t.toString()}`))}),v=e,e}}),b=()=>{_?.removeAllListeners(),y.removeAllListeners()},x=()=>{p||(p=!0,b(),y.close(),e({responseHeaders:m??{},bodyBuffer:h.toBuffer(),truncated:g,alpnProtocol:d}))},S=e=>{p||(p=!0,b(),y.destroy(e),f(e))};y.once(`error`,e=>{v instanceof ee.TLSSocket&&(d=kt(v.alpnProtocol)),S(e instanceof Error?e:Error(String(e)))}),y.once(`connect`,()=>{v instanceof ee.TLSSocket&&(d=kt(v.alpnProtocol)),_=y.request({":method":r,":path":`${t.pathname}${t.search}`,":scheme":t.protocol.slice(0,-1),":authority":t.host,...i}),_.once(`response`,e=>{m=e}),_.on(`data`,e=>{let t=Buffer.isBuffer(e)?e:Buffer.from(e,`utf8`),n=s-h.length;n>0&&h.append(t.subarray(0,n)),t.length>n&&!g&&(g=!0,_?.close(te.constants.NGHTTP2_CANCEL))}),_.once(`end`,x),_.once(`close`,()=>{g&&x()}),_.once(`error`,e=>{S(e instanceof Error?e:Error(String(e)))}),a.length>0?_.end(a):_.end()})})}const K=[`A`,`AAAA`,`MX`,`TXT`,`NS`,`CNAME`,`SOA`,`PTR`,`SRV`,`ANY`];function Mt(e){return e?e===`ENOTFOUND`?`NXDOMAIN`:e===`ENODATA`?`NODATA`:e===`ESERVFAIL`?`SERVFAIL`:e===`ETIMEOUT`?`TIMEOUT`:e===`ECONNREFUSED`?`CONNREFUSED`:e===`EREFUSED`?`REFUSED`:`ERROR`:`ERROR`}function q(e){return Math.round((performance.now()-e)*100)/100}var Nt=class{eventBus;constructor(e){this.eventBus=e}async handleDnsResolve(e){try{let t=z(e.hostname,`hostname`);if(!t)return b.text(`hostname is required`,!0);let n=z(e.rrType,`rrType`)??`A`;if(!K.includes(n))return b.text(`Invalid rrType: "${n}". Expected one of: ${K.join(`, `)}`,!0);let r=performance.now(),i=await E.resolve(t,n),a=q(r);return b.ok().json({hostname:t,rrType:n,records:i,timing:a})}catch(e){let t=e instanceof Error?e.message:String(e);return b.fail(`DNS resolve failed: ${t}`).json()}}async handleDnsReverse(e){try{let t=z(e.ip,`ip`);if(!t)return b.text(`ip is required`,!0);let n=performance.now(),r=await E.reverse(t),i=q(n);return b.ok().json({ip:t,hostnames:r,timing:i})}catch(e){let t=e instanceof Error?e.message:String(e);return b.fail(`DNS reverse lookup failed: ${t}`).json()}}async handleDnsProbe(e){try{let t=z(e.hostname,`hostname`);if(!t)return b.text(`hostname is required`,!0);let n=z(e.rrType,`rrType`)??`A`;if(!K.includes(n))return b.text(`Invalid rrType: "${n}". Expected one of: ${K.join(`, `)}`,!0);let r=performance.now();try{let e=await E.resolve(t,n),i=q(r);return b.ok().json({hostname:t,rrType:n,status:`NOERROR`,records:e,timing:i})}catch(e){let i=q(r),a=e instanceof Error&&`code`in e?e.code:void 0,o=Mt(a);return b.ok().json({hostname:t,rrType:n,status:o,records:[],timing:i,errorCode:a??null})}}catch(e){let t=e instanceof Error?e.message:String(e);return b.fail(`DNS probe failed: ${t}`).json()}}async handleDnsCnameChain(e){try{let t=z(e.hostname,`hostname`);if(!t)return b.text(`hostname is required`,!0);let n=M(e.maxDepth,{defaultValue:10,min:1,max:30,integer:!0}),r=[],i=t;for(let e=0;e<n;e++){let t=performance.now();try{let n=await E.resolve(i,`CNAME`),a=q(t),o=n[0]??null;if(r.push({host:i,target:o,status:`CNAME`,depth:e,timing:a}),o)i=o;else break}catch(n){let a=q(t),o=n instanceof Error&&`code`in n?n.code:void 0,s=o===`ENOTFOUND`||o===`ENODATA`?`TERMINAL`:Mt(o);r.push({host:i,target:null,status:s,depth:e,timing:a});break}}return b.ok().json({hostname:t,chain:r,depth:r.length})}catch(e){let t=e instanceof Error?e.message:String(e);return b.fail(`CNAME chain trace failed: ${t}`).json()}}async handleDnsBulkResolve(e){try{let t=V(e.hostnames,`hostnames`);if(t.length===0)return b.text(`hostnames must be a non-empty array`,!0);if(t.length>1e3)return b.text(`hostnames array too large (max 1000)`,!0);let n=z(e.rrType,`rrType`)??`A`;if(!K.includes(n))return b.text(`Invalid rrType: "${n}". Expected one of: ${K.join(`, `)}`,!0);let r=M(e.concurrency,{defaultValue:10,min:1,max:50,integer:!0}),i=[];for(let e=0;e<t.length;e+=r){let a=t.slice(e,e+r),o=await Promise.all(a.map(async e=>{let t=performance.now();try{return{hostname:e,status:`NOERROR`,records:await E.resolve(e,n),timing:q(t)}}catch(n){let r=q(t);return{hostname:e,status:Mt(n instanceof Error&&`code`in n?n.code:void 0),records:[],timing:r}}}));i.push(...o)}let a=i.filter(e=>e.status!==`NOERROR`).length;return b.ok().json({results:i,total:i.length,errors:a,rrType:n})}catch(e){let t=e instanceof Error?e.message:String(e);return b.fail(`Bulk DNS resolve failed: ${t}`).json()}}async handleHttpRequestBuild(e){try{let t=z(e.method,`method`),n=z(e.target,`target`);if(!t)throw Error(`method is required`);if(!n)throw Error(`target is required`);let r=st({method:t,target:n,host:z(e.host,`host`),headers:xt(e.headers,`headers`),body:B(e.body,`body`,{allowEmpty:!0}),httpVersion:z(e.httpVersion,`httpVersion`)??`1.1`,addHostHeader:j(e.addHostHeader,!0),addContentLength:j(e.addContentLength,!0),addConnectionClose:j(e.addConnectionClose,!0)});return A(this.eventBus,`network:http_request_built`,{method:r.startLine.split(` `,1)[0]??`UNKNOWN`,target:n,byteLength:r.requestBytes,timestamp:new Date().toISOString()}),b.ok().merge(r).json()}catch(e){return b.fail(e instanceof Error?e.message:String(e)).json()}}async handleHttpPlainRequest(e){try{let t=z(e.host,`host`),n=B(e.requestText,`requestText`);if(!t)throw Error(`host is required`);if(!n)throw Error(`requestText is required`);let r=Ct(t),i=M(e.port,{defaultValue:80,min:1,max:65535,integer:!0}),a=M(e.timeoutMs,{defaultValue:3e4,min:1,max:12e4,integer:!0}),o=M(e.maxResponseBytes,{defaultValue:512e3,min:256,max:5242880,integer:!0}),s=Tt(n),c=H(e.authorization),{target:l}=await G(`http://${wt(r)}:${String(i)}/`,c,`HTTP request`);if(c){let e=(n.split(/\r?\n/,1)[0]??``).split(/\s+/)[1]??``;if(e.includes(`://`))try{let t=Ct(new URL(e).hostname);if(t!==r&&t!==(l.resolvedAddress??``))throw Error(`HTTP request blocked: request-line target host "${t}" does not match authorized host "${r}"`)}catch(e){if(e instanceof Error&&e.message.startsWith(`HTTP request blocked:`))throw e}let t=n.match(/^Host:\s*(\S+)/im)?.[1];if(t){let e=Ct(t.replace(/:\d+$/,``));if(e!==r&&e!==(l.resolvedAddress??``))throw Error(`HTTP request blocked: Host header "${t}" does not match authorized host "${r}"`)}}let u=await Et(l.resolvedAddress??l.hostname,i,Buffer.from(n,`utf8`),s,a,o),d=ct(u.rawResponse,s);if(!d)throw Error(`Received data but could not parse complete HTTP response headers.`);let f=lt(d.rawHeaders.find(e=>e.name.toLowerCase()===`content-type`)?.value??null,d.bodyBuffer),p=d.complete||d.bodyMode===`until-close`&&u.endedBy===`socket-close`;return A(this.eventBus,`network:http_plain_request_completed`,{host:r,port:i,statusCode:d.statusCode,byteLength:u.rawResponse.length,timestamp:new Date().toISOString()}),b.ok().merge({host:r,port:i,resolvedAddress:l.resolvedAddress??l.hostname,requestBytes:Buffer.byteLength(n,`utf8`),response:{statusLine:d.statusLine,httpVersion:d.httpVersion,statusCode:d.statusCode,statusText:d.statusText,headers:d.headers,rawHeaders:d.rawHeaders,headerBytes:d.headerBytes,bodyBytes:d.bodyBytes,bodyMode:d.bodyMode,chunkedDecoded:d.chunkedDecoded,complete:p,truncated:u.endedBy===`max-bytes`,endedBy:u.endedBy,bodyText:f?d.bodyBuffer.toString(`utf8`):void 0,bodyBase64:f?void 0:d.bodyBuffer.toString(`base64`)}}).json()}catch(e){return b.fail(e instanceof Error?e.message:String(e)).json()}}},Pt=class{eventBus;constructor(e){this.eventBus=e}async handleHttp2Probe(e){let t=z(e.url,`url`),n=t??``,r=null,i=null,a=!1;try{if(!t)throw Error(`url is required`);let o=(z(e.method,`method`)??`GET`).toUpperCase();if(!yt.test(o))throw Error(`method must be a valid HTTP token`);let s=M(e.timeoutMs,{defaultValue:3e4,min:1,max:12e4,integer:!0}),c=M(e.maxBodyBytes,{defaultValue:32768,min:128,max:1048576,integer:!0}),l=e.body,u=l!=null&&typeof l!=`string`,d=typeof l==`string`?l:u?JSON.stringify(l):``,f=Buffer.from(d,`utf8`),p=V(e.alpnProtocols,`alpnProtocols`),m=At(xt(e.headers,`headers`));u&&f.length>0&&!(`content-type`in m)&&(m[`content-type`]=`application/json`);let{url:h,target:g}=await G(t,H(e.authorization),`HTTP/2 probe`);n=h.toString(),!(`content-length`in m)&&f.length>0&&(m[`content-length`]=String(f.length));let{responseHeaders:_,bodyBuffer:v,truncated:y,alpnProtocol:x}=await jt({url:h,target:g,method:o,requestHeaders:m,bodyBuffer:f,timeoutMs:s,maxBodyBytes:c,effectivePort:Number.parseInt(h.port||(h.protocol===`https:`?`443`:`80`),10),requestedAlpnProtocols:p.length>0?p:[`h2`,`http/1.1`]}),S=Ot(_),C=_[`:status`],w=typeof C==`number`?C:typeof C==`string`?Number.parseInt(C,10):null,T=lt(typeof S[`content-type`]==`string`?S[`content-type`]:Array.isArray(S[`content-type`])?S[`content-type`][0]??null:null,v);return r=Number.isFinite(w??NaN)?w:null,i=x,a=!0,b.ok().merge({url:n,statusCode:r,alpnProtocol:i,headers:S,bodyBytes:v.length,truncated:y,bodyText:T?v.toString(`utf8`):void 0,bodyBase64:T?void 0:v.toString(`base64`)}).json()}catch(e){return b.fail(e instanceof Error?e.message:String(e)).json()}finally{A(this.eventBus,`network:http2_probed`,{url:n,success:a,statusCode:r,alpnProtocol:i,timestamp:new Date().toISOString()})}}async handleHttp2FrameBuild(e){let t=z(e.frameType,`frameType`);if(!t)throw Error(`frameType is required`);let n=[`DATA`,`SETTINGS`,`PING`,`WINDOW_UPDATE`,`RST_STREAM`,`GOAWAY`,`RAW`],r=t.toUpperCase();if(!n.includes(r))throw Error(`frameType must be one of: ${n.join(`, `)}`);let i=e.streamId===void 0?void 0:M(e.streamId,{defaultValue:0,min:0,integer:!0}),a=e.flags===void 0?void 0:M(e.flags,{defaultValue:0,min:0,max:255,integer:!0}),o=e.frameTypeCode===void 0?void 0:M(e.frameTypeCode,{defaultValue:0,min:0,max:255,integer:!0}),s=e.windowSizeIncrement===void 0?void 0:M(e.windowSizeIncrement,{defaultValue:1,min:1,integer:!0}),c=e.errorCode===void 0?void 0:M(e.errorCode,{defaultValue:0,min:0,integer:!0}),l=e.lastStreamId===void 0?void 0:M(e.lastStreamId,{defaultValue:0,min:0,integer:!0}),u=z(e.payloadHex,`payloadHex`),d=B(e.payloadText,`payloadText`,{allowEmpty:!0}),f=z(e.payloadEncoding,`payloadEncoding`),p=bt(e.ack,`ack`),m=z(e.pingOpaqueDataHex,`pingOpaqueDataHex`),h=B(e.debugDataText,`debugDataText`,{allowEmpty:!0}),g=z(e.debugDataEncoding,`debugDataEncoding`),_;if(e.settings!==void 0){if(!Array.isArray(e.settings))throw Error(`settings must be an array`);_=e.settings.map((e,t)=>{if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`settings[${String(t)}] must be an object with id and value`);return{id:typeof e.id==`number`?e.id:(()=>{throw Error(`settings[${String(t)}].id must be a number`)})(),value:typeof e.value==`number`?e.value:(()=>{throw Error(`settings[${String(t)}].value must be a number`)})()}})}let v=vt({frameType:r,...i!==void 0&&{streamId:i},...a!==void 0&&{flags:a},...o!==void 0&&{frameTypeCode:o},...u!==void 0&&{payloadHex:u},...d!==void 0&&{payloadText:d},...f!==void 0&&{payloadEncoding:f},..._!==void 0&&{settings:_},...p!==void 0&&{ack:p},...m!==void 0&&{pingOpaqueDataHex:m},...s!==void 0&&{windowSizeIncrement:s},...c!==void 0&&{errorCode:c},...l!==void 0&&{lastStreamId:l},...h!==void 0&&{debugDataText:h},...g!==void 0&&{debugDataEncoding:g}});return A(this.eventBus,`network:http2_frame_build_completed`,{frameType:v.frameType,typeCode:v.typeCode,streamId:v.streamId,flags:v.flags,payloadBytes:v.payloadBytes,timestamp:new Date().toISOString()}),b.ok().merge(v).json()}};function J(e){return`${e&255}.${e>>>8&255}.${e>>>16&255}.${e>>>24&255}`}function Ft(e){let t=e.split(`.`);return t.length===4?t.every(e=>{let t=parseInt(e,10);return!isNaN(t)&&t>=0&&t<=255&&e===String(t)}):!1}let Y=null;const It={0:`SUCCESS`,11001:`BUF_TOO_SMALL`,11002:`DEST_NET_UNREACHABLE`,11003:`DEST_HOST_UNREACHABLE`,11004:`DEST_PROT_UNREACHABLE`,11005:`DEST_PORT_UNREACHABLE`,11009:`PACKET_TOO_BIG`,11010:`REQ_TIMED_OUT`,11013:`TTL_EXPIRED_TRANSIT`,11014:`TTL_EXPIRED_REASSEM`,11015:`PARAM_PROBLEM`,11016:`SOURCE_QUENCH`,11050:`GENERAL_FAILURE`};function Lt(e){return It[e]??`UNKNOWN_${e}`}function Rt(e){return e===0?`success`:e===11010?`timeout`:e===11013||e===11014?`time_exceeded`:e>=11002&&e<=11005?`destination_unreachable`:e===11016?`source_quench`:e===11009?`packet_too_big`:e===11015?`parameter_problem`:`error`}let zt=null,Bt=null;function Vt(){return zt||(zt=w.load(`iphlpapi.dll`),e.debug(`Loaded iphlpapi.dll via koffi`)),zt}function Ht(){return Bt||(Bt=w.load(`ws2_32.dll`),e.debug(`Loaded ws2_32.dll via koffi`)),Bt}function Ut(e){return Math.max(256,e+64)}function Wt(e){let t=Buffer.alloc(16,0);return t.writeUInt8(e,0),t}function Gt(e){return{address:e.readUInt32LE(0),status:e.readUInt32LE(4),rtt:e.readUInt32LE(8)}}function Kt(e){return Ht().func(`uint32 inet_addr(char *)`)(e)}function qt(){return Vt().func(`void * IcmpCreateFile()`)()}function Jt(e){return Vt().func(`int IcmpCloseHandle(void *)`)(e)!==0}function Yt(e,t,n,r,i){let a=Vt().func(`uint32 IcmpSendEcho(void *, uint32, void *, uint16, void *, void *, uint32, uint32)`),o=Buffer.alloc(Ut(n.length)),s=a(e,t,n,n.length,r,o,o.length,i);return{numReplies:Number(s),replyBuf:o}}function Xt(e){let{target:t,ttl:n=128,packetSize:i=r,timeout:a=o}=e,s=Kt(t);if(s===4294967295)return{target:t,ip:``,alive:!1,rtt:null,ttl:n,icmpStatus:`INVALID_ADDRESS`,errorClass:`error`,packetSize:i};let c=qt();try{let{numReplies:e,replyBuf:r}=Yt(c,s,Buffer.alloc(i,170),Wt(n),a);if(e===0)return{target:t,ip:J(s),alive:!1,rtt:null,ttl:n,icmpStatus:`REQ_TIMED_OUT`,errorClass:`timeout`,packetSize:i};let o=Gt(r);return{target:t,ip:J(o.address),alive:o.status===0,rtt:o.status===0?o.rtt:null,ttl:n,icmpStatus:Lt(o.status),errorClass:Rt(o.status),packetSize:i}}finally{Jt(c)}}function Zt(e){let{target:t,maxHops:n=a,timeout:i=o,packetSize:s=r}=e,c=Kt(t);if(c===4294967295)return{target:t,ip:``,hops:[],reached:!1,totalHops:0,totalTime:0};let l=qt(),u=[],d=performance.now();try{for(let e=1;e<=n;e++){let{numReplies:t,replyBuf:n}=Yt(l,c,Buffer.alloc(s,170),Wt(e),i);if(t===0){u.push({hop:e,ip:null,rtt:null,status:`REQ_TIMED_OUT`,errorClass:`timeout`});continue}let r=Gt(n),a=J(r.address);if(u.push({hop:e,ip:a,rtt:r.rtt,status:Lt(r.status),errorClass:Rt(r.status)}),r.status===0)break}}finally{Jt(l)}let f=u[u.length-1];return{target:t,ip:J(c),hops:u,reached:f?.status===`SUCCESS`,totalHops:u.length,totalTime:Math.round((performance.now()-d)*100)/100}}const Qt=process.platform===`darwin`?4102:20,$t=process.platform===`darwin`?`/usr/lib/libSystem.B.dylib`:`libc.so.6`;let en=null;function X(){return en||(en=w.load($t),e.debug(`Loaded ${$t} via koffi for ICMP`)),en}function tn(e,t,n){return X().func(`int socket(int, int, int)`)(e,t,n)}function nn(e,t,n,r,i){return X().func(`int setsockopt(int, int, int, void *, int)`)(e,t,n,r,i)}function rn(e,t,n){return X().func(`int sendto(int, void *, int, int, void *, int)`)(e,t,t.length,0,n,16)}function an(e,t){return X().func(`int recv(int, void *, int, int)`)(e,t,t.length,0)}function on(e){return X().func(`int close(int)`)(e)}function sn(e){let t=0;for(let n=0;n<e.length-1;n+=2)t+=e.readUInt16BE(n);for(e.length&1&&(t+=(e[e.length-1]??0)<<8);t>65535;)t=(t&65535)+(t>>>16);return~t&65535}function cn(e,t,n){let r=Buffer.alloc(8+n);r[0]=8,r[1]=0,r.writeUInt16BE(e&65535,4),r.writeUInt16BE(t&65535,6);for(let e=8;e<r.length;e++)r[e]=170;return r.writeUInt16BE(sn(r),2),r}function ln(e){let t=Buffer.alloc(16,0);t.writeUInt16LE(2,0);let n=e.split(`.`).map(Number);return t[4]=n[0]??0,t[5]=n[1]??0,t[6]=n[2]??0,t[7]=n[3]??0,t}function un(e,t,n){if(t<20)return null;let r=((e[0]??0)&15)*4;if(t<r+8)return null;let i=e[r]??0,a=e[r+1]??0,o=e.readUInt32LE(12);if(i===0)return e.readUInt16BE(r+4)===n?{type:i,code:a,fromIp:o}:null;if(i===11||i===3){let s=r+8;if(t<s+28)return null;let c=((e[s]??0)&15)*4;return t<s+c+8||e.readUInt16BE(s+c+4)!==n?null:{type:i,code:a,fromIp:o}}return null}function dn(e,t,n){return e===0?`SUCCESS`:n?`REQ_TIMED_OUT`:e===11&&t===0?`TTL_EXPIRED_TRANSIT`:e===11&&t===1?`TTL_EXPIRED_REASSEM`:e===3&&t===0?`DEST_NET_UNREACHABLE`:e===3&&t===1?`DEST_HOST_UNREACHABLE`:e===3&&t===2?`DEST_PROT_UNREACHABLE`:e===3&&t===3?`DEST_PORT_UNREACHABLE`:`UNKNOWN_${e}_${t}`}function fn(e,t,n){return e===0?`success`:n?`timeout`:e===11?`time_exceeded`:e===3?`destination_unreachable`:`error`}function pn(e,t){let n=Buffer.alloc(4);n.writeInt32LE(t),nn(e,0,2,n,4)}function mn(e,t){let n=Buffer.alloc(16,0);n.writeInt32LE(Math.floor(t/1e3),0),n.writeInt32LE(t%1e3*1e3,8),nn(e,1,Qt,n,16)}function hn(e){let{target:t,ttl:n=128,packetSize:i=r,timeout:a=o}=e;if(!Ft(t))return{target:t,ip:``,alive:!1,rtt:null,ttl:n,icmpStatus:`INVALID_ADDRESS`,errorClass:`error`,packetSize:i};let s=tn(2,3,1);if(s<0)return{target:t,ip:``,alive:!1,rtt:null,ttl:n,icmpStatus:`SOCKET_ERROR`,errorClass:`error`,packetSize:i};try{pn(s,n),mn(s,a);let e=process.pid&65535,r=cn(e,1,i),o=ln(t),c=performance.now();if(rn(s,r,o)<0)return{target:t,ip:t,alive:!1,rtt:null,ttl:n,icmpStatus:`SEND_ERROR`,errorClass:`error`,packetSize:i};let l=Buffer.alloc(512),u=an(s,l),d=Math.round(performance.now()-c);if(u<=0)return{target:t,ip:t,alive:!1,rtt:null,ttl:n,icmpStatus:`REQ_TIMED_OUT`,errorClass:`timeout`,packetSize:i};let f=un(l,u,e);if(!f)return{target:t,ip:t,alive:!1,rtt:null,ttl:n,icmpStatus:`UNEXPECTED_REPLY`,errorClass:`error`,packetSize:i};let p=f.type===0;return{target:t,ip:J(f.fromIp),alive:p,rtt:p?d:null,ttl:n,icmpStatus:dn(f.type,f.code,!1),errorClass:fn(f.type,f.code,!1),packetSize:i}}finally{on(s)}}function gn(e){let{target:t,maxHops:n=a,timeout:i=o,packetSize:s=r}=e;if(!Ft(t))return{target:t,ip:``,hops:[],reached:!1,totalHops:0,totalTime:0};let c=tn(2,3,1);if(c<0)return{target:t,ip:``,hops:[],reached:!1,totalHops:0,totalTime:0};let l=[],u=process.pid&65535,d=ln(t),f=performance.now(),p=0;try{mn(c,i);for(let e=1;e<=n;e++){pn(c,e);let t=cn(u,e,s),n=performance.now();if(rn(c,t,d)<0){if(p++,l.push({hop:e,ip:null,rtt:null,status:`SEND_ERROR`,errorClass:`error`}),p>=5)break;continue}p=0;let r=Buffer.alloc(512),i=an(c,r),a=Math.round(performance.now()-n);if(i<=0){l.push({hop:e,ip:null,rtt:null,status:`REQ_TIMED_OUT`,errorClass:`timeout`});continue}let o=un(r,i,u);if(!o){l.push({hop:e,ip:null,rtt:null,status:`UNEXPECTED_REPLY`,errorClass:`error`});continue}let f=dn(o.type,o.code,!1),m=fn(o.type,o.code,!1);if(l.push({hop:e,ip:J(o.fromIp),rtt:a,status:f,errorClass:m}),o.type===0)break}}finally{on(c)}return{target:t,ip:t,hops:l,reached:l[l.length-1]?.status===`SUCCESS`,totalHops:l.length,totalTime:Math.round((performance.now()-f)*100)/100}}const _n=process.platform===`linux`||process.platform===`darwin`;function vn(){if(Y!==null)return Y;if(process.platform===`win32`)try{return w.load(`iphlpapi.dll`).unload(),Y=!0,!0}catch{return Y=!1,!1}if(_n){try{let e=tn(2,3,1);e>=0?(on(e),Y=!0):Y=!1}catch{Y=!1}return Y}return Y=!1,!1}function yn(e){let{target:t,ttl:n=128,packetSize:i=r,timeout:a=o}=e;return vn()?process.platform===`win32`?Xt({target:t,ttl:n,packetSize:i,timeout:a}):hn({target:t,ttl:n,packetSize:i,timeout:a}):{target:t,ip:``,alive:!1,rtt:null,ttl:n,icmpStatus:`PLATFORM_NOT_SUPPORTED`,errorClass:`error`,packetSize:i}}function bn(e){let{target:t,maxHops:n=a,timeout:i=o,packetSize:s=r}=e;return vn()?process.platform===`win32`?Zt({target:t,maxHops:n,timeout:i,packetSize:s}):gn({target:t,maxHops:n,timeout:i,packetSize:s}):{target:t,ip:``,hops:[],reached:!1,totalHops:0,totalTime:0}}var xn=class{eventBus;constructor(e){this.eventBus=e}async handleNetworkRttMeasure(e){let t=z(e.url,`url`);if(!t)throw Error(`url is required`);let n=z(e.probeType,`probeType`)??`tcp`;if(![`tcp`,`tls`,`http`].includes(n))throw Error(`probeType must be one of: tcp, tls, http`);let r=U(e.iterations===void 0?5:M(e.iterations,{defaultValue:5,min:1,integer:!0}),1,50),i=U(e.timeoutMs===void 0?5e3:M(e.timeoutMs,{defaultValue:5e3,min:100,integer:!0}),100,3e4),{url:a,target:o}=await G(t,H(e.authorization),`RTT measurement`),s=o.hostname,c=Number(a.port)||(a.protocol===`https:`?443:80),l=o.resolvedAddress??s,u=a.protocol===`https:`,d=[],f=[];for(let e=0;e<r;e+=1)try{let e=await this.measureSingleRtt(s,l,c,n,i,u);d.push(e)}catch(e){f.push(e instanceof Error?e.message:String(e))}let p=St(d);return A(this.eventBus,`network:rtt_measured`,{url:t,probeType:n,iterations:r,successCount:d.length,errorCount:f.length,stats:p,timestamp:new Date().toISOString()}),b.ok().merge({target:{hostname:s,port:c,resolvedIp:l,probeType:n},stats:p,samples:d,errors:f.length>0?f:void 0,timestamp:new Date().toISOString()}).json()}async handleNetworkTraceroute(e){try{if(!vn())return b.text(`ICMP traceroute not available on this platform (Windows: native API, Linux/macOS: requires root/CAP_NET_RAW)`,!0);let t=z(e.target,`target`);if(!t)return b.text(`target is required`,!0);let n=await Sn(t);if(!n)return b.fail(`Could not resolve hostname: ${t}`).json();let r=bn({target:n,maxHops:U(e.maxHops===void 0?30:Number(e.maxHops),1,64),timeout:U(e.timeout===void 0?5e3:Number(e.timeout),100,3e4),packetSize:U(e.packetSize===void 0?32:Number(e.packetSize),8,65500)});return b.ok().merge({resolvedFrom:t}).json(r)}catch(e){let t=e instanceof Error?e.message:String(e);return b.fail(`Traceroute failed: ${t}`).json()}}async handleNetworkLatencyStats(e){let t=z(e.url,`url`);if(!t)return b.text(`url is required`,!0);let n=z(e.probeType,`probeType`)??`http`;if(![`tcp`,`tls`,`http`].includes(n))return b.text(`Invalid probeType: "${n}". Expected one of: tcp, tls, http`,!0);let r=U(e.iterations===void 0?20:M(e.iterations,{defaultValue:20,min:5,integer:!0}),5,100),i=U(e.concurrency===void 0?5:M(e.concurrency,{defaultValue:5,min:1,integer:!0}),1,20),a=U(e.timeoutMs===void 0?5e3:M(e.timeoutMs,{defaultValue:5e3,min:100,integer:!0}),100,3e4),{url:o,target:s}=await G(t,H(e.authorization),`Latency stats`),c=s.hostname,l=Number(o.port)||(o.protocol===`https:`?443:80),u=s.resolvedAddress??c,d=o.protocol===`https:`,f=[],p=[];for(let e=0;e<r;e+=i){let t=Array.from({length:Math.min(i,r-e)},(t,n)=>n+e),o=await Promise.allSettled(t.map(()=>this.measureSingleRtt(c,u,l,n,a,d)));for(let e of o)e.status===`fulfilled`?f.push(e.value):p.push(e.reason instanceof Error?e.reason.message:String(e.reason))}let m=St(f);return b.ok().json({url:t,target:{hostname:c,port:l,resolvedIp:u,probeType:n},iterations:r,concurrency:i,stats:m,errors:p.length>0?p:void 0})}async handleNetworkIcmpProbe(e){try{if(!vn())return b.text(`ICMP probe not available on this platform (Windows: native API, Linux/macOS: requires root/CAP_NET_RAW)`,!0);let t=z(e.target,`target`);if(!t)return b.text(`target is required`,!0);let n=await Sn(t);if(!n)return b.fail(`Could not resolve hostname: ${t}`).json();let r=U(e.ttl===void 0?128:Number(e.ttl),1,255),i=U(e.timeout===void 0?5e3:Number(e.timeout),100,3e4),a=yn({target:n,ttl:r,packetSize:U(e.packetSize===void 0?32:Number(e.packetSize),8,65500),timeout:i});return b.ok().merge({resolvedFrom:t}).json(a)}catch(e){let t=e instanceof Error?e.message:String(e);return b.fail(`ICMP probe failed: ${t}`).json()}}measureSingleRtt(e,t,n,r,i,a){switch(r){case`tcp`:return this.probeTcp(t,n,i);case`tls`:return this.probeTls(e,t,n,i);case`http`:return this.probeHttp(e,t,n,i,a)}}createPinnedLookup(e){let t=T.isIP(e)===6?6:4;return(n,r,i)=>{(typeof r==`function`?r:i)?.(null,e,t)}}probeTcp(e,t,n){return new Promise((r,i)=>{let a=performance.now(),o=setTimeout(()=>i(Error(`TCP probe timed out after ${n}ms`)),n),s=T.createConnection({host:e,port:t},()=>{clearTimeout(o),s.destroy(),r(W(performance.now()-a))});s.on(`error`,e=>{clearTimeout(o),s.destroy(),i(e)})})}probeTls(e,t,n,r){return new Promise((i,a)=>{let o=performance.now(),s=!1,c=null,l=e=>{s||(s=!0,clearTimeout(u),c?.destroy(),e())},u=setTimeout(()=>{l(()=>a(Error(`TLS probe timed out after ${r}ms`)))},r);c=ee.connect({host:e,port:n,lookup:this.createPinnedLookup(t),...T.isIP(e)===0?{servername:e}:{}},()=>{l(()=>i(W(performance.now()-o)))}),c.on(`error`,e=>{l(()=>a(e))})})}probeHttp(e,t,n,r,i){return new Promise((a,o)=>{let s=performance.now(),c=!1,l=null,u=e=>{c||(c=!0,clearTimeout(d),l?.destroy(),e())},d=setTimeout(()=>{u(()=>o(Error(`HTTP probe timed out after ${r}ms`)))},r);l=(i?ne.request:x.request)({host:e,port:n,path:`/`,method:`HEAD`,lookup:this.createPinnedLookup(t),...i&&T.isIP(e)===0?{servername:e}:{}},e=>{e.resume(),u(()=>a(W(performance.now()-s)))}),l.on(`error`,e=>{u(()=>o(e))}),l.end()})}};async function Sn(e){if(T.isIPv4(e))return e;try{return(await E.resolve(e,`A`))[0]??null}catch{return null}}var Cn=class extends xn{dnsHttp;http2;constructor(e){super(e),this.dnsHttp=new Nt(e),this.http2=new Pt(e)}handleDnsResolve(e){return this.dnsHttp.handleDnsResolve(e)}handleDnsReverse(e){return this.dnsHttp.handleDnsReverse(e)}handleDnsProbe(e){return this.dnsHttp.handleDnsProbe(e)}handleDnsCnameChain(e){return this.dnsHttp.handleDnsCnameChain(e)}handleDnsBulkResolve(e){return this.dnsHttp.handleDnsBulkResolve(e)}handleHttpRequestBuild(e){return this.dnsHttp.handleHttpRequestBuild(e)}handleHttpPlainRequest(e){return this.dnsHttp.handleHttpPlainRequest(e)}handleHttp2Probe(e){return this.http2.handleHttp2Probe(e)}handleHttp2FrameBuild(e){return this.http2.handleHttp2FrameBuild(e)}};const wn=new Set([`0a0a`,`1a1a`,`2a2a`,`3a3a`,`4a4a`,`5a5a`,`6a6a`,`7a7a`,`8a8a`,`9a9a`,`aaaa`,`baba`,`caca`,`dada`,`eaea`,`fafa`]);function Z(e){return wn.has(e.replace(`0x`,``).toLowerCase().padStart(4,`0`))}function Q(e){return S(`sha256`).update(e).digest(`hex`).substring(0,12)}function $(e){return e.replace(`0x`,``).toLowerCase().padStart(4,`0`)}const Tn={"0304":`13`,"0303":`12`,"0302":`11`,"0301":`10`,"0300":`s3`,"0002":`s2`,feff:`d1`,fefd:`d2`,fefc:`d3`};function En(e){return Tn[e.toLowerCase()]??`00`}function Dn(e){if(!e||e.length===0)return`00`;let t=e[0],n=e[e.length-1],r=/[0-9a-zA-Z]/.test(t),i=/[0-9a-zA-Z]/.test(n);if(r&&i)return`${t}${n}`;let a=Buffer.from(e,`utf8`).toString(`hex`);return`${a[0]??`0`}${a[a.length-1]??`0`}`}function On(e){let{protocol:t,tlsVersion:n,hasSni:r,ciphers:i,extensions:a,signatureAlgorithms:o,alpn:s}=e,c=t===`quic`?`q`:t===`dtls`?`d`:`t`,l=[n].map($).filter(e=>!Z(e)&&e!==`0303`),u=(n.length>0?l:[`0303`]).toSorted(),d=En(u.length>0?u[u.length-1]:`0303`),f=r?`d`:`i`,p=i.map($).filter(e=>!Z(e)),m=a.map($).filter(e=>!Z(e)),h=`${c}${d}${f}${String(Math.min(p.length,99)).padStart(2,`0`)}${String(Math.min(m.length,99)).padStart(2,`0`)}${Dn(s)}`,g=p.toSorted().join(`,`),_=p.length>0?Q(g):`000000000000`,v=m.filter(e=>e!==`0000`&&e!==`0010`).toSorted(),y=o.map($),b;return b=y.length>0?`${v.join(`,`)}_${y.join(`,`)}`:v.join(`,`),{tls:`${h}_${_}_${v.length>0||y.length>0?Q(b):`000000000000`}`,tls_raw:`${h}_${p.join(`,`)}_${m.join(`,`)}_${y.join(`,`)}`}}function kn(e,t,n,r,i){let a=e.toUpperCase(),o={GET:`ge`,POST:`po`,PUT:`pu`,DELETE:`de`,HEAD:`he`,PATCH:`pa`,OPTIONS:`ot`}[a]??a.toLowerCase().substring(0,2).padEnd(2,a.charAt(0).toLowerCase()),s=typeof n==`string`?n.trim().toLowerCase():``,c=s===`2`||s===`2.0`||s===`h2`||s===`http/2`?`20`:s===`3`||s===`3.0`||s===`h3`||s===`http/3`?`30`:s===`1.0`||s===`http/1.0`?`10`:s===`1.1`||s===`http/1.1`?`11`:`00`,l=t.map(e=>e.toLowerCase()),u=l.includes(`cookie`)?`c`:`n`,d=l.includes(`referer`)?`r`:`n`,f=l.filter(e=>e!==`cookie`&&e!==`referer`),p=String(Math.min(f.length,99)).padStart(2,`0`),m=`0000`;i&&i.length>0&&(m=(i.split(`,`)[0]??``).replace(/[-;]/g,``).toLowerCase().trim().padEnd(4,`0`).substring(0,4));let h=`${o}${c}${u}${d}${p}${m}`,g=f.filter(e=>!e.startsWith(`:`)).toSorted(),_=g.length>0?Q(g.join(`,`)):`000000000000`,v=`000000000000`,y=`000000000000`;if(u===`c`&&r){let e=r.split(`;`).map(e=>e.trim()).filter(Boolean),t=e.map(e=>e.split(`=`)[0]?.trim()??``).filter(Boolean).toSorted();v=t.length>0?Q(t.join(`,`)):`000000000000`;let n=e.map(e=>{let t=e.indexOf(`=`);return{name:t>=0?e.substring(0,t).trim():e.trim(),pair:e}}).toSorted((e,t)=>e.name.localeCompare(t.name)).map(e=>e.pair);y=n.length>0?Q(n.join(`,`)):`000000000000`}return{http:`${h}_${_}_${v}_${y}`}}function An(e){if(typeof e!=`string`)return;let t=e.trim().toLowerCase();if(t===`1.0`||t===`http/1.0`)return`1.0`;if(t===`1.1`||t===`http/1.1`)return`1.1`;if(t===`2`||t===`2.0`||t===`http/2`||t===`h2`)return`h2`;if(t===`3`||t===`3.0`||t===`http/3`||t===`h3`)return`h3`}function jn(e,t,n){let r=[],i=0;!e||e.length===0?(r.push(`missing-user-agent`),i+=.3):(/bot|crawler|spider|headless|selenium|puppeteer|playwright|phantom|curl|wget|python|java|go-http|httpclient|okhttp|requests\/|aiohttp|axios|node-fetch|undici/i.test(e)&&(r.push(`bot-ua: ${e.substring(0,40)}`),i+=.5),/headless/i.test(e)&&(r.push(`headless-browser`),i+=.4),e.length<30&&!/bot|curl|wget|python/i.test(e)&&(r.push(`suspiciously-short-ua`),i+=.2));let a=t.map(e=>e.toLowerCase());a.includes(`accept`)||(r.push(`missing-accept-header`),i+=.15),a.includes(`accept-language`)||(r.push(`missing-accept-language`),i+=.1),a.includes(`accept-encoding`)||(r.push(`missing-accept-encoding`),i+=.1);let o=t.length;o<4&&(r.push(`suspicious-few-headers: ${o}`),i+=.2),n&&(n.cipherCount<=2&&(r.push(`anomalous-cipher-count: ${n.cipherCount} (real browsers typically 5-15)`),i+=.3),n.extensionCount<5&&(r.push(`few-tls-extensions: ${n.extensionCount} (real browsers 10-25+)`),i+=.2),/\bTLS\s*1\.[01]\b|\b1\.0\b|\b1\.1\b|\bSSL/i.test(n.tlsVersion)&&(r.push(`outdated-tls-version: ${n.tlsVersion}`),i+=.25));let s=[`host`,`connection`,`cache-control`,`sec-ch-ua`,`sec-ch-ua-mobile`,`sec-ch-ua-platform`,`upgrade-insecure-requests`,`user-agent`,`accept`,`sec-fetch-site`,`sec-fetch-mode`,`sec-fetch-user`,`sec-fetch-dest`,`referer`,`accept-encoding`,`accept-language`];return a.length>=5&&a.slice(0,5).filter((e,t)=>e===s[t]).length===0&&(r.push(`header-order-does-not-match-known-browser`),i+=.1),{score:Math.min(i,1),signals:r}}var Mn=class{consoleMonitor;constructor(e){this.consoleMonitor=e.consoleMonitor}async handleNetworkTlsFingerprint(e){let t=e.mode,n=e.includeAnalysis!==!1,r=[`compute_tls`,`compute_http`,`analyze_request`];if(!t||!r.includes(t))return b.fail(`Invalid mode: "${t}". Expected one of: ${r.join(`, `)}`).json();try{if(t===`compute_tls`){let t=e.tlsVersions||[],r=e.ciphers||[],i=e.extensions||[],a=e.signatureAlgorithms||[],o=e.protocol===`quic`?`quic`:e.protocol===`dtls`?`dtls`:`tls`,s=e.sni!==!1,c=e.alpn||``;if(r.length===0)return b.fail(`ciphers array is required for compute_tls mode`).json();let l=t.map($).filter(e=>!Z(e)).toSorted(),u=l.length>0?l[l.length-1]:`0303`,{tls:d,tls_raw:f}=On({protocol:o,tlsVersion:u,hasSni:s,ciphers:r,extensions:i,signatureAlgorithms:a,alpn:c}),p={success:!0,mode:`tls`,tls:d,tls_raw:f};if(n){let e=r.map($).filter(e=>!Z(e)),t=i.map($).filter(e=>!Z(e));p.analysis={protocol:o.toUpperCase(),tlsVersion:u,sni:s,cipherCount:e.length,extensionCount:t.length,signatureAlgorithmCount:a.length,alpn:c||`(none)`,sortedCiphers:e.toSorted(),sortedExtensions:t.filter(e=>e!==`0000`&&e!==`0010`).toSorted()}}return b.ok().merge(p).json()}if(t===`compute_http`){let t=e.httpHeaders||[],r=e.userAgent||``,i=e.httpMethod||`GET`,a=e.httpVersion||`1.1`,o=e.cookieHeader||``,s=e.acceptLanguage||``;if(t.length===0)return b.fail(`httpHeaders array is required for compute_http mode`).json();let{http:c}=kn(i,t,a,o,s),l={success:!0,mode:`http`,http:c};if(n){let e=t.map(e=>e.toLowerCase());l.analysis={method:i,httpVersion:a,headerCount:t.length,nonCookieRefererHeaders:e.filter(e=>e!==`cookie`&&e!==`referer`).length,hasCookie:e.includes(`cookie`),hasAcceptLanguage:e.includes(`accept-language`),sortedHeaders:e.filter(e=>e!==`cookie`&&e!==`referer`&&!e.startsWith(`:`)).toSorted(),userAgentLength:r.length}}return b.ok().merge(l).json()}let r=e.requestId;if(!r)return b.fail(`requestId is required for analyze_request mode`).json();let i=this.consoleMonitor.getNetworkRequests().find(e=>e.requestId===r);if(!i)return b.fail(`Request ${r} not found`).json();let a=i.headers||{},o=Object.keys(a),s=a[`user-agent`]||a[`User-Agent`]||``,c=i.method||`GET`,l=a.cookie||a.Cookie||``,u=a[`accept-language`]||a[`Accept-Language`]||``,d=An(i.httpVersion),{http:f}=kn(c,o,d,l,u),p=i.securityDetails,m=p&&typeof p==`object`?{cipherCount:typeof p.cipherCount==`number`?p.cipherCount:5,extensionCount:typeof p.extensionCount==`number`?p.extensionCount:10,tlsVersion:typeof p.protocol==`string`?p.protocol:``}:void 0,h={success:!0,mode:`analyze_request`,requestId:r,url:i.url,method:c,httpVersion:d??`unknown`,http:f},g={requestId:r,url:i.url,method:c,httpVersion:d??`unknown`,http:f,headerCount:o.length,headerOrder:o.join(`, `),userAgent:s.length>80?s.substring(0,80)+`...`:s,securityHeaders:{hasCSP:void 0,hasHSTS:void 0,hasCORS:void 0},botSignals:jn(s,o,m)};return n&&(h.analysis=g),b.ok().merge(h).json()}catch(e){return b.fail(e instanceof Error?e.message:String(e)).json()}}async handleNetworkBotDetectAnalyze(e){let t=typeof e.limit==`number`?e.limit:i,n=e.includeDetails===!0,r=this.consoleMonitor.getNetworkRequests(),a=r.slice(0,t);if(a.length===0)return b.ok().merge({analyzed:0,summary:`No captured requests to analyze. Enable network monitoring first.`}).json();let o=[],s=[],c=0,l=new Map,u=0,d=0,f=new Map,p=null;for(let e of a){let t=e.headers||{},r=Object.keys(t),i=t[`user-agent`]||t[`User-Agent`]||``,a=e.url||``,m=e.method||`GET`,h=t.cookie||t.Cookie||``,g=t[`accept-language`]||t[`Accept-Language`]||``,_=An(e.httpVersion),v=e.securityDetails,y=jn(i,r,v&&typeof v==`object`?{cipherCount:typeof v.cipherCount==`number`?v.cipherCount:5,extensionCount:typeof v.extensionCount==`number`?v.extensionCount:10,tlsVersion:typeof v.protocol==`string`?v.protocol:``}:void 0),b=/\/api\/|\/v\d+\/|\/graphql/i.test(a),{http:x}=kn(m,r,_,h,g);l.set(x,(l.get(x)??0)+1),f.has(x)?f.get(x)!==i&&u++:f.set(x,i),p===null?p=r.join(`,`):r.join(`,`)!==p&&d++;let S={requestId:e.requestId,url:a.length>100?a.substring(0,100)+`...`:a,method:m,http:x,botScore:y.score,signals:y.signals};c+=y.score,y.score>.5&&o.push(`Request ${e.requestId}: ${y.signals.join(`, `)}`),b&&(S.apiPattern=!0),n&&s.push(S)}let m=a.length>0?c/a.length:0,h=l.size,g=h/a.length,_=[];g>.8&&_.push(`High fingerprint diversity (${h} unique HTTP fingerprints in ${a.length} requests) — may indicate multiple clients or rotation`),g===1&&a.length>5&&_.push(`Every request has a unique HTTP fingerprint — likely automated tool rotating headers`);let v=[];u>0&&v.push(`${u} request(s) with different UA for same HTTP fingerprint — UA drift detected`),d>0&&v.push(`${d} request(s) with different header order — header rotation detected`);let y=a.length>1?Math.max(0,1-(u+d)/(a.length*2)):1;return b.ok().merge({analyzed:a.length,totalRequests:r.length,averageBotScore:Math.round(m*100)/100,suspiciousRequests:o.length,httpFingerprintSummary:{uniqueFingerprints:h,diversity:Math.round(g*100)/100,topFingerprints:[...l.entries()].toSorted((e,t)=>t[1]-e[1]).slice(0,5).map(([e,t])=>({http_fingerprint:e,count:t}))},signals:o.slice(0,20),..._.length>0?{diversitySignals:_}:{},interRequestConsistency:{consistencyScore:Math.round(y*100)/100,uaDriftCount:u,headerOrderDriftCount:d,...v.length>0?{signals:v}:{}},details:n?s:void 0,recommendations:m>.5?[`High bot-like signal detected. Consider TLS fingerprint rotation.`,`Review User-Agent consistency across requests.`,`Check header ordering matches real browser behavior.`,`HTTP fingerprint diversity can distinguish botnets from real users.`]:g>.8?[`Traffic appears human but fingerprint diversity is high — investigate further.`]:[`Traffic appears to follow normal browser patterns.`]}).json()}},Nn=class{collector;consoleMonitor;eventBus;performanceMonitor=null;detailedDataManager=s.getInstance();core;perf;consoleHandlers;replay;intercept;raw;tlsBot;constructor(e,t,n,r){this.collector=e,this.consoleMonitor=t,this.eventBus=n,this.core=new Te({collector:e,consoleMonitor:t,eventBus:n}),this.perf=new Ee({collector:e,getPerformanceMonitor:()=>this.getPerformanceMonitor(),getTraceRecorder:r}),this.consoleHandlers=new De({consoleMonitor:t}),this.replay=new Je({consoleMonitor:t}),this.intercept=new Xe({consoleMonitor:t,eventBus:n}),this.raw=new Cn(n),this.tlsBot=new Mn({consoleMonitor:t})}getPerformanceMonitor(){return this.performanceMonitor||=new c(this.collector),this.performanceMonitor}handleNetworkEnable=e=>this.core.handleNetworkEnable(e);handleNetworkDisable=e=>this.core.handleNetworkDisable(e);handleNetworkGetStatus=e=>this.core.handleNetworkGetStatus(e);handleNetworkMonitor=e=>this.core.handleNetworkMonitor(e);handleNetworkGetRequests=e=>this.core.handleNetworkGetRequests(e);handleNetworkGetResponseBody=e=>this.core.handleNetworkGetResponseBody(e);handleNetworkGetStats=e=>this.core.handleNetworkGetStats(e);handlePerformanceGetMetrics=e=>this.perf.handlePerformanceGetMetrics(e);handlePerformanceCoverage=e=>this.perf.handlePerformanceCoverage(e);handlePerformanceStartCoverage=e=>this.perf.handlePerformanceStartCoverage(e);handlePerformanceStopCoverage=e=>this.perf.handlePerformanceStopCoverage(e);handlePerformanceTakeHeapSnapshot=e=>this.perf.handlePerformanceTakeHeapSnapshot(e);handlePerformanceTraceStart=e=>this.perf.handlePerformanceTraceStart(e);handlePerformanceTraceStop=e=>this.perf.handlePerformanceTraceStop(e);handlePerformanceTraceDispatch=e=>String(e.action??``)===`stop`?this.perf.handlePerformanceTraceStop(e):this.perf.handlePerformanceTraceStart(e);handleProfilerCpuStart=e=>this.perf.handleProfilerCpuStart(e);handleProfilerCpuStop=e=>this.perf.handleProfilerCpuStop(e);handleProfilerCpuDispatch=e=>String(e.action??``)===`stop`?this.perf.handleProfilerCpuStop(e):this.perf.handleProfilerCpuStart(e);handleProfilerHeapSamplingStart=e=>this.perf.handleProfilerHeapSamplingStart(e);handleProfilerHeapSamplingStop=e=>this.perf.handleProfilerHeapSamplingStop(e);handleProfilerHeapSamplingDispatch=e=>String(e.action??``)===`stop`?this.perf.handleProfilerHeapSamplingStop(e):this.perf.handleProfilerHeapSamplingStart(e);handleConsoleGetExceptions=e=>this.consoleHandlers.handleConsoleGetExceptions(e);handleConsoleInjectDispatch=e=>{switch(String(e.type??``)){case`xhr`:return this.consoleHandlers.handleConsoleInjectXhrInterceptor(e);case`fetch`:return this.consoleHandlers.handleConsoleInjectFetchInterceptor(e);case`function`:return this.consoleHandlers.handleConsoleInjectFunctionTracer(e);default:return this.consoleHandlers.handleConsoleInjectScriptMonitor(e)}};handleConsoleBuffersDispatch=e=>String(e.action??``)===`reset`?this.consoleHandlers.handleConsoleResetInjectedInterceptors(e):this.consoleHandlers.handleConsoleClearInjectedBuffers(e);handleConsoleInjectScriptMonitor=e=>this.consoleHandlers.handleConsoleInjectScriptMonitor(e);handleConsoleInjectXhrInterceptor=e=>this.consoleHandlers.handleConsoleInjectXhrInterceptor(e);handleConsoleInjectFetchInterceptor=e=>this.consoleHandlers.handleConsoleInjectFetchInterceptor(e);handleConsoleClearInjectedBuffers=e=>this.consoleHandlers.handleConsoleClearInjectedBuffers(e);handleConsoleResetInjectedInterceptors=e=>this.consoleHandlers.handleConsoleResetInjectedInterceptors(e);handleConsoleInjectFunctionTracer=e=>this.consoleHandlers.handleConsoleInjectFunctionTracer(e);handleNetworkExtractAuth=e=>this.replay.handleNetworkExtractAuth(e);handleNetworkExportHar=e=>this.replay.handleNetworkExportHar(e);handleNetworkReplayRequest=e=>this.replay.handleNetworkReplayRequest(e);handleNetworkInterceptResponse=e=>this.intercept.handleNetworkInterceptResponse(e);handleNetworkInterceptList=e=>this.intercept.handleNetworkInterceptList(e);handleNetworkInterceptDisable=e=>this.intercept.handleNetworkInterceptDisable(e);handleNetworkInterceptDispatch=e=>{let t=String(e.action??``);switch(t){case`add`:return this.intercept.handleNetworkInterceptResponse(e);case`list`:return this.intercept.handleNetworkInterceptList(e);case`disable`:return this.intercept.handleNetworkInterceptDisable(e);default:return Promise.resolve({content:[{type:`text`,text:`Invalid action: "${t}". Expected one of: add, list, disable`}],isError:!0})}};handleNetworkTraceroute=e=>this.raw.handleNetworkTraceroute(e);handleNetworkIcmpProbe=e=>this.raw.handleNetworkIcmpProbe(e);handleDnsResolve=e=>this.raw.handleDnsResolve(e);handleDnsReverse=e=>this.raw.handleDnsReverse(e);handleDnsProbe=e=>this.raw.handleDnsProbe(e);handleDnsCnameChain=e=>this.raw.handleDnsCnameChain(e);handleDnsBulkResolve=e=>this.raw.handleDnsBulkResolve(e);handleHttpRequestBuild=e=>this.raw.handleHttpRequestBuild(e);handleHttpPlainRequest=e=>this.raw.handleHttpPlainRequest(e);handleHttp2Probe=e=>this.raw.handleHttp2Probe(e);handleHttp2FrameBuild=e=>this.raw.handleHttp2FrameBuild(e);handleNetworkRttMeasure=e=>this.raw.handleNetworkRttMeasure(e);handleNetworkLatencyStats=e=>this.raw.handleNetworkLatencyStats(e);handleNetworkTlsFingerprint=e=>this.tlsBot.handleNetworkTlsFingerprint(e);handleNetworkBotDetectAnalyze=e=>this.tlsBot.handleNetworkBotDetectAnalyze(e)};export{Nn as AdvancedToolHandlers};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./search-defaults-D2bY-rzH.mjs";import{homedir as t}from"node:os";import{z as n}from"zod";import{basename as r,dirname as i,extname as a,isAbsolute as o,join as s,normalize as c,relative as l,resolve as u,sep as d}from"node:path";import{fileURLToPath as f}from"node:url";import{mkdir as p}from"node:fs/promises";import{config as m}from"dotenv";const h=f(new URL(`../..`,import.meta.url)),g=f(new URL(`../../.env`,import.meta.url));let _=!1;const v={puppeteer:{headless:!1,timeout:3e4},mcp:{name:`jshookmcp`,version:`0.1.8`},cache:{enabled:!1,dir:`.cache`,ttl:3600},paths:{screenshotDir:`screenshots`,captchaScreenshotDir:`screenshots/captcha`,debuggerSessionsDir:`debugger-sessions`,extensionRegistryDir:`artifacts/extension-registry`,tlsKeyLogDir:`artifacts/tmp`,registryCacheDir:`.jshookmcp/cache`},performance:{maxConcurrentAnalysis:3,maxCodeSizeMB:10}};function y(){if(_)return;_=!0;let e=m({path:g,quiet:!0}),t=e.error?.code;e.error&&t!==`ENOENT`?(console.error(`[Config] Warning: Failed to load .env file from configured path`),console.error(`[Config] Error: ${e.error.message}`),console.error(`[Config] Will use environment variables or defaults`)):!e.error&&process.env.DEBUG===`true`&&console.info(`[Config] .env file loaded (debug mode)`)}const b=e=>n.string().optional().transform(t=>t?parseInt(t,10):e).pipe(n.number().int().finite()),x=e=>n.string().optional().transform(t=>t===void 0?e:t===`true`);function S(e,t){return c(o(e)?e:u(t,e))}const C=n.object({PUPPETEER_HEADLESS:x(v.puppeteer.headless),PUPPETEER_TIMEOUT:b(v.puppeteer.timeout).pipe(n.number().min(1e3).max(3e5)),PUPPETEER_EXECUTABLE_PATH:n.string().optional(),CHROME_PATH:n.string().optional(),BROWSER_EXECUTABLE_PATH:n.string().optional(),MCP_SERVER_NAME:n.string().optional().default(v.mcp.name),MCP_SERVER_VERSION:n.string().optional().default(v.mcp.version),ENABLE_CACHE:x(v.cache.enabled),CACHE_DIR:n.string().optional().default(v.cache.dir),CACHE_TTL:b(v.cache.ttl).pipe(n.number().min(0)),MCP_SCREENSHOT_DIR:n.string().optional().default(v.paths.screenshotDir),CAPTCHA_SCREENSHOT_DIR:n.string().optional().default(v.paths.captchaScreenshotDir),MCP_DEBUGGER_SESSIONS_DIR:n.string().optional().default(v.paths.debuggerSessionsDir),MCP_EXTENSION_REGISTRY_DIR:n.string().optional().default(v.paths.extensionRegistryDir),MCP_TLS_KEYLOG_DIR:n.string().optional().default(v.paths.tlsKeyLogDir),MCP_REGISTRY_CACHE_DIR:n.string().optional().default(v.paths.registryCacheDir),MAX_CONCURRENT_ANALYSIS:b(v.performance.maxConcurrentAnalysis).pipe(n.number().min(1).max(32)),MAX_CODE_SIZE_MB:b(v.performance.maxCodeSizeMB).pipe(n.number().min(1).max(500))});function w(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function T(e){let t=process.env[e];if(t)try{let e=JSON.parse(t);return Array.isArray(e)?e:void 0}catch{return}}function E(){let e=T(`SEARCH_QUERY_CATEGORY_PROFILES_JSON`);if(e!==void 0)return e.flatMap(e=>{if(!w(e)||typeof e.pattern!=`string`||!Array.isArray(e.domainBoosts))return[];let t=e.domainBoosts.flatMap(e=>!w(e)||typeof e.domain!=`string`||typeof e.weight!=`number`?[]:[{domain:e.domain,weight:e.weight}]);return[{pattern:e.pattern,flags:typeof e.flags==`string`?e.flags:void 0,domainBoosts:t}]})}function D(){let e=T(`SEARCH_CJK_QUERY_ALIASES_JSON`);if(e!==void 0)return e.flatMap(e=>{if(!w(e)||typeof e.pattern!=`string`||!Array.isArray(e.tokens))return[];let t=e.tokens.filter(e=>typeof e==`string`);return[{pattern:e.pattern,flags:typeof e.flags==`string`?e.flags:void 0,tokens:t}]})}function O(){let e=T(`SEARCH_INTENT_TOOL_BOOST_RULES_JSON`);if(e!==void 0)return e.flatMap(e=>{if(!w(e)||typeof e.pattern!=`string`||!Array.isArray(e.boosts))return[];let t=e.boosts.flatMap(e=>!w(e)||typeof e.tool!=`string`||typeof e.bonus!=`number`?[]:[{tool:e.tool,bonus:e.bonus}]);return[{pattern:e.pattern,flags:typeof e.flags==`string`?e.flags:void 0,boosts:t}]})}function k(e){return{queryCategoryProfiles:e.queryCategoryProfiles.map(e=>({pattern:e.pattern,flags:e.flags,domainBoosts:e.domainBoosts.map(e=>({domain:e.domain,weight:e.weight}))})),cjkQueryAliases:e.cjkQueryAliases.map(e=>({pattern:e.pattern,flags:e.flags,tokens:[...e.tokens]})),intentToolBoostRules:e.intentToolBoostRules.map(e=>({pattern:e.pattern,flags:e.flags,boosts:e.boosts.map(e=>({tool:e.tool,bonus:e.bonus}))}))}}function A(){let t=k(e);return{queryCategoryProfiles:E()??t.queryCategoryProfiles,cjkQueryAliases:D()??t.cjkQueryAliases,intentToolBoostRules:O()??t.intentToolBoostRules}}function j(e,t){return typeof e==`boolean`?e:typeof e==`string`?e===`true`:t}function M(e,t){if(typeof e==`number`&&Number.isFinite(e))return e;if(typeof e==`string`){let t=Number.parseInt(e,10);if(Number.isFinite(t))return t}return t}function N(){y();let e=C.safeParse(process.env);if(!e.success){let t=e.error.issues.map(e=>` ${e.path.join(`.`)}: ${e.message}`);console.error(`[Config] Validation errors:\n${t.join(`
|
|
2
|
+
`)}`),console.error(`[Config] Falling back to safe defaults for invalid fields`)}let n=e.success?e.data:process.env,r=n.CACHE_DIR||v.cache.dir,i=n.PUPPETEER_EXECUTABLE_PATH||n.CHROME_PATH||n.BROWSER_EXECUTABLE_PATH,a=r.startsWith(`/`)||r.match(/^[A-Za-z]:/)?r:s(h,r),o=A(),c={screenshotDir:S(n.MCP_SCREENSHOT_DIR||v.paths.screenshotDir,h),captchaScreenshotDir:S(n.CAPTCHA_SCREENSHOT_DIR||v.paths.captchaScreenshotDir,h),debuggerSessionsDir:S(n.MCP_DEBUGGER_SESSIONS_DIR||v.paths.debuggerSessionsDir,process.cwd()),extensionRegistryDir:S(n.MCP_EXTENSION_REGISTRY_DIR||v.paths.extensionRegistryDir,h),tlsKeyLogDir:S(n.MCP_TLS_KEYLOG_DIR||v.paths.tlsKeyLogDir,h),registryCacheDir:S(n.MCP_REGISTRY_CACHE_DIR||v.paths.registryCacheDir,t())};return{puppeteer:{headless:j(n.PUPPETEER_HEADLESS,v.puppeteer.headless),timeout:M(n.PUPPETEER_TIMEOUT,v.puppeteer.timeout),executablePath:i?.trim()||void 0},mcp:{name:n.MCP_SERVER_NAME||v.mcp.name,version:n.MCP_SERVER_VERSION||v.mcp.version},cache:{enabled:j(n.ENABLE_CACHE,v.cache.enabled),dir:a,ttl:M(n.CACHE_TTL,v.cache.ttl)},paths:c,performance:{maxConcurrentAnalysis:M(n.MAX_CONCURRENT_ANALYSIS,v.performance.maxConcurrentAnalysis),maxCodeSizeMB:M(n.MAX_CODE_SIZE_MB,v.performance.maxCodeSizeMB)},search:o}}function P(e){let t=[];e.performance.maxConcurrentAnalysis<1&&t.push(`maxConcurrentAnalysis must be at least 1`),e.performance.maxCodeSizeMB<1&&t.push(`maxCodeSizeMB must be at least 1`),e.puppeteer.timeout<1e3&&t.push(`puppeteer.timeout must be at least 1000ms`),e.cache.ttl<0&&t.push(`cache.ttl must be non-negative`);for(let n of e.search.queryCategoryProfiles)try{new RegExp(n.pattern,n.flags)}catch{t.push(`search.queryCategoryProfiles contains invalid regex: ${n.pattern}`)}for(let n of e.search.cjkQueryAliases)try{new RegExp(n.pattern,n.flags)}catch{t.push(`search.cjkQueryAliases contains invalid regex: ${n.pattern}`)}for(let n of e.search.intentToolBoostRules)try{new RegExp(n.pattern,n.flags)}catch{t.push(`search.intentToolBoostRules contains invalid regex: ${n.pattern}`)}return{valid:t.length===0,errors:t}}const F=f(import.meta.url),I=F.includes(`/src/utils/`)||F.includes(`\\src\\utils\\`)?f(new URL(`../..`,import.meta.url)):f(new URL(`..`,import.meta.url));function L(e=process.env){let t=e.MCP_PROJECT_ROOT?.trim();return t?c(R(t)?t:u(I,t)):I}function R(e){return o(e)||/^[A-Za-z]:[\\/]/.test(e)||e.startsWith(`\\\\`)}function z(e,t){let n=l(e,t);return!(!n||n===`..`||n.startsWith(`..${d}`)||o(n))}function B(e,t=H()){let n=R(e)?c(e):u(t,e);return z(t,n)?n:u(t,`screenshots`,`external`,c(e).split(/[\\/]/).pop()||`output.bin`)}function V(e,t){return a(e)?e:`${e}.${t.replace(/^\./,``)}`}function H(){return L()}function U(e){let t=H(),n=e.trim();if(!n)throw Error(`path must be a non-empty relative path within the project root`);if(R(n))throw Error(`path must be relative to the project root`);let r=c(u(t,n));if(!z(t,r))throw Error(`path must stay within the project root`);return r}function W(e,t=`screenshots`){let n=H(),r=e?.trim();if(!r)return u(n,t);let i=B(r,n);return z(n,i)?i:u(n,t)}function G(){return N().paths.debuggerSessionsDir}function K(){return N().paths.extensionRegistryDir}function q(){return u(N().cache.dir,`code`)}function J(){return N().paths.tlsKeyLogDir}async function Y(e){let t=H(),n=e.type===`jpeg`?`jpg`:`png`,a=e.fallbackDir||`screenshots/manual`,o=e.fallbackName||`page`,s=W(N().paths.screenshotDir,a),c=e.requestedPath?.trim(),d,f=!1;if(!c)d=u(s,`${o}-${Date.now()}.${n}`),f=!0;else{let e=V(c,n);R(e)?(d=u(s,r(e)),f=!0):(d=u(t,e),z(t,d)||(d=u(s,r(d)),f=!0))}await p(i(d),{recursive:!0});let m=z(t,d)?l(t,d).replace(/\\/g,`/`):d.replace(/\\/g,`/`);return{absolutePath:d,displayPath:m,pathRewritten:f}}export{J as a,Y as c,P as d,H as i,N as l,G as n,W as o,K as r,U as s,q as t,h as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t,n){let r=e[t];return typeof r==`string`?r:n}function t(e,t,n){let r=e[t];return typeof r==`number`?r:n}function n(e,t,n){let r=e[t];return typeof r==`boolean`?r:n}function r(e,t,n,r){let i=e[t];if(i==null||typeof i!=`string`)return r;if(!n.has(i))throw Error(`Invalid ${t}: "${i}". Expected one of: ${[...n].join(`, `)}`);return i}function i(e,t){let n=e[t];if(typeof n!=`string`)throw Error(`Missing required string argument: "${t}"`);return n}function a(e,t){let n=e[t];return Array.isArray(n)?n.filter(e=>typeof e==`string`):[]}function o(e,t){let n=e[t];if(typeof n==`object`&&n&&!Array.isArray(n))return n}export{e as a,o as i,r as n,a as o,t as r,i as s,n as t};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import{t as e}from"./logger-sBC6IdRT.mjs";import{Mr as t}from"./constants-Cp6hBrrx.mjs";import{i as n}from"./modules-p-PUNv9r.mjs";import{i as r}from"./artifacts-B5xQuEa_.mjs";import{n as i}from"./capabilities-DbYCv-HF.mjs";import{t as a}from"./ToolRegistry-B0Zs-phN.mjs";import"./definitions-DJklW2sS.mjs";import{homedir as o}from"node:os";import{basename as s,dirname as c,extname as l,join as u,normalize as d,relative as f,resolve as p,sep as m}from"node:path";import{copyFile as h,mkdir as g,readFile as _,readdir as v,stat as y,writeFile as b}from"node:fs/promises";import{execFile as x,spawn as S}from"node:child_process";import{promisify as C}from"node:util";function w(e){return{content:[{type:`text`,text:JSON.stringify(e,null,2)}]}}function T(e,t,n={}){return w({success:!1,tool:e,error:t instanceof Error?t.message:String(t),...n})}function E(e){return`attached`}function D(e,t,n=!1){let r=e[t];if(typeof r==`string`){let e=r.trim();if(e.length>0)return e}if(n)throw Error(`${t} must be a non-empty string`)}function O(e,t,n){let r=e[t];if(typeof r==`boolean`)return r;if(typeof r==`number`){if(r===1)return!0;if(r===0)return!1}if(typeof r==`string`){let e=r.trim().toLowerCase();if([`true`,`1`,`yes`,`on`].includes(e))return!0;if([`false`,`0`,`no`,`off`].includes(e))return!1}return n}function k(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function A(e){if(!Array.isArray(e))return[];let t=[];for(let n of e)if(typeof n==`string`){let e=n.trim();e.length>0&&t.push(e)}return t}function j(e){let t=f(process.cwd(),e).replace(/\\/g,`/`);return t.length===0?`.`:t.startsWith(`..`)?e.replace(/\\/g,`/`):t}async function M(e){try{return await y(e),!0}catch{return!1}}function N(){let e=process.env.USERPROFILE??o(),t=process.env.APPDATA??u(e,`AppData`,`Roaming`),n=[u(e,`Documents`),u(t)],r=[`Applet`,`XPlugin`,`MiniApp`],i=[];for(let e of n)for(let t of r)i.push(p(e,t));return Array.from(new Set(i))}async function P(t,n){let r=[p(t)];for(;r.length>0;){let t=r.pop();if(!t)continue;let i;try{i=await v(t,{withFileTypes:!0})}catch(n){e.debug(`walkDirectory skip unreadable directory`,{currentDir:t,error:n instanceof Error?n.message:String(n)});continue}for(let a of i){let i=u(t,String(a.name));if(a.isDirectory()){r.push(i);continue}if(a.isFile())try{await n(i,await y(i))}catch(t){e.warn(`walkDirectory skip unreadable file`,{absolutePath:i,error:t instanceof Error?t.message:String(t)})}}}}async function F(e,t,n){if(n){let e=p(n);return await g(e,{recursive:!0}),{absolutePath:e,displayPath:j(e)}}let{absolutePath:i,displayPath:a}=await r({category:`tmp`,toolName:e,target:t,ext:`tmpdir`}),o=i.replace(/\.tmpdir$/i,``);return await g(o,{recursive:!0}),{absolutePath:o,displayPath:a.replace(/\.tmpdir$/i,``)}}function I(e){return d(e.replace(/\\/g,`/`)).replace(/\\/g,`/`).split(`/`).filter(e=>e.length>0&&e!==`.`&&e!==`..`).join(`/`)}function L(e,t){let n=I(t),r=s(t)||`unnamed.bin`,i=p(e,n.length>0?n:r),a=p(e);if(i!==a&&!i.startsWith(`${a}${m}`))throw Error(`Path traversal blocked: ${t}`);return i}async function R(e){try{let t=await _(e,`utf-8`),n=JSON.parse(t);return k(n)?n:null}catch{return null}}function z(e){let t=e.replace(/\\/g,`/`);for(let e of[/\/([a-zA-Z]{2,4}[a-zA-Z0-9]{6,})\//,/\/Applet\/([^/]+)\//i]){let n=t.match(e);if(n?.[1])return n[1]}let n=s(e,l(e)).match(/([a-zA-Z]{2,4}[a-zA-Z0-9]{6,})/);return n?.[1]?n[1]:null}function ee(e){if(e.length<18)throw Error(`Invalid miniapp package: file too small`);let t=e.readUInt8(0);if(t!==190)throw Error(`Invalid miniapp package magic: expected 0xBE, got 0x${t.toString(16)}`);let n=e.readUInt32BE(1),r=e.readUInt32BE(5),i=e.readUInt32BE(9),a=e.readUInt8(13),o=14+r;if(o>e.length)throw Error(`Invalid miniapp package: index section out of range`);let s=14;if(s+4>o)throw Error(`Invalid miniapp package: missing file count in index`);let c=e.readUInt32BE(s);s+=4;let l=[];for(let t=0;t<c;t+=1){if(s+4>o)throw Error(`Invalid miniapp package index at entry ${t}: missing nameLen`);let n=e.readUInt32BE(s);if(s+=4,n<=0||s+n>o)throw Error(`Invalid miniapp package index at entry ${t}: invalid nameLen`);let r=e.subarray(s,s+n).toString(`utf-8`);if(s+=n,s+8>o)throw Error(`Invalid miniapp package index at entry ${t}: missing offset/size`);let i=e.readUInt32BE(s);s+=4;let a=e.readUInt32BE(s);s+=4,l.push({name:r,offset:i,size:a})}return{magic:t,info:n,indexInfoLength:r,dataLength:i,lastIdent:a,dataOffset:o,entries:l}}async function te(e,t,n){let r=(await e.probeAll())[`miniapp.unpacker`];if(!r?.available)return{used:!1,stderr:r?.reason??`外部解包工具 is unavailable`};let i=[[`unpack`,t,`-o`,n],[`unpack`,`-o`,n,t],[`-o`,n,t],[t,n]],a=`外部解包工具 failed for all argument patterns`;for(let n of i){let r=await e.run({tool:`miniapp.unpacker`,args:n,timeoutMs:18e4,cwd:c(t)});if(r.ok)return{used:!0,command:`unveilr ${n.join(` `)}`};a=r.stderr?.trim()||`exitCode=${String(r.exitCode)}`}return{used:!1,stderr:a}}var ne=class{runner;collector;constructor(e,t){this.runner=e,this.collector=t}async handleMiniappPkgScan(e){try{let t=D(e,`searchPath`),n=t?[p(t)]:N(),r=[],i=[];for(let e of n)try{(await y(e)).isDirectory()?r.push(e):i.push(e)}catch{i.push(e)}let a=[];for(let e of r)await P(e,async(e,t)=>{if(l(e).toLowerCase()===`.pkg`){try{let t=await import(`node:fs/promises`).then(t=>t.open(e,`r`));try{let e=Buffer.alloc(1);if(await t.read(e,0,1,0),e[0]!==190)return}finally{await t.close()}}catch{return}a.push({path:e.replace(/\\/g,`/`),size:Number(t.size),appId:z(e),lastModified:t.mtime.toISOString()})}});return a.sort((e,t)=>new Date(t.lastModified).getTime()-new Date(e.lastModified).getTime()),w({success:!0,searchedRoots:r.map(e=>e.replace(/\\/g,`/`)),skippedRoots:i.map(e=>e.replace(/\\/g,`/`)),count:a.length,files:a,collectorState:E(this.collector)})}catch(e){return T(`miniapp_pkg_scan`,e)}}async handleMiniappPkgUnpack(t){try{let n=D(t,`inputPath`,!0),r=D(t,`outputDir`);if(!n)throw Error(`inputPath is required`);let i=p(n);if(!(await y(i)).isFile())throw Error(`inputPath must be a file`);let a=await F(`miniapp-unpack`,z(i)??s(i,l(i)),r);await g(a.absolutePath,{recursive:!0});let o=await te(this.runner,i,a.absolutePath);if(o.used){let t=0;if(await P(a.absolutePath,async(e,n)=>{t+=1}),t>0)return w({success:!0,usedExternalCli:!0,cliCommand:o.command??null,outputDir:a.displayPath,extractedFiles:t,appId:z(i),collectorState:E(this.collector)});e.warn(`External unpack tool reported success but produced no output; falling back to parser`,{inputPath:i,outputDir:a.absolutePath})}let u=await _(i),d=ee(u),f=[],m=0,h=0;for(let[e,t]of d.entries.entries()){let n=t.name.trim().length>0?t.name:`file-${e}.bin`;try{let e=t.offset,r=e+t.size;if(e<0||r>u.length){let n=d.dataOffset+t.offset,i=n+t.size;if(n>=0&&i<=u.length)e=n,r=i;else throw Error(`entry offset out of range`)}let i=u.subarray(e,r),o=L(a.absolutePath,n);await g(c(o),{recursive:!0}),await b(o,i),m+=1,h+=i.length}catch(e){f.push({path:n,reason:e instanceof Error?e.message:String(e)})}}return w({success:m>0,usedExternalCli:!1,cliError:o.stderr??null,outputDir:a.displayPath,appId:z(i),header:{magic:d.magic,info:d.info,indexInfoLength:d.indexInfoLength,dataLength:d.dataLength,lastIdent:d.lastIdent},fileCount:d.entries.length,extractedFiles:m,totalBytesExtracted:h,failedFiles:f,collectorState:E(this.collector)})}catch(e){return T(`miniapp_pkg_unpack`,e)}}async handleMiniappPkgAnalyze(e){try{let t=D(e,`unpackedDir`,!0);if(!t)throw Error(`unpackedDir is required`);let n=p(t);if(!(await y(n)).isDirectory())throw Error(`unpackedDir must be a directory`);let r=new Set,i=new Set,a=[],o=0,c,u,d;await P(n,async(e,t)=>{o+=Number(t.size);let r=f(n,e).replace(/\\/g,`/`),p=s(e).toLowerCase(),m=l(e).toLowerCase();p===`app.json`&&!c?c=e:p===`app-config.json`&&!u?u=e:p===`page-frame.html`&&!d&&(d=e),m===`.js`&&a.push(r),r.includes(`/components/`)&&[`.js`,`.wxml`,`.json`,`.wxss`].includes(m)&&i.add(r)});let m=[],h=null;if(c){let e=await R(c);if(e){for(let t of A(e.pages))r.add(t);let t=e.subPackages??e.subpackages;if(Array.isArray(t))for(let e of t){if(!k(e))continue;let t=typeof e.root==`string`?e.root.trim():``,n=A(e.pages);m.push({root:t,pages:n});for(let e of n)t.length>0?r.add(`${t}/${e}`):r.add(e)}let n=e.usingComponents;if(k(n))for(let e of Object.values(n))typeof e==`string`&&e.trim()&&i.add(e.trim());let a=typeof e.appId==`string`?e.appId:typeof e.appid==`string`?e.appid:null;a&&a.trim().length>0&&(h=a.trim())}}if(u){let e=await R(u);if(e){let t=typeof e.appId==`string`?e.appId:typeof e.appid==`string`?e.appid:null;t&&t.trim().length>0&&!h&&(h=t.trim());for(let t of A(e.pages))r.add(t)}}return h||=z(n),w({success:!0,unpackedDir:n.replace(/\\/g,`/`),pages:Array.from(r).toSorted(),subPackages:m,components:Array.from(i).toSorted(),jsFiles:a.toSorted(),totalSize:o,appId:h,discovered:{appJsonPath:c?j(c):null,appConfigPath:u?j(u):null,pageFramePath:d?j(d):null},collectorState:E(this.collector)})}catch(e){return T(`miniapp_pkg_analyze`,e)}}};function re(e){let t=e.length;for(;t>0&&e.charCodeAt(t-1)===0;)--t;return t===e.length?e:e.slice(0,t)}function ie(e){if(!k(e.files))return[];let t=[],n=(e,r)=>{for(let[i,a]of Object.entries(e)){if(!k(a))continue;let e=r.length>0?`${r}/${i}`:i;if(k(a.files)){n(a.files,e);continue}let o=a.size,s=a.offset,c=a.unpacked===!0,l=typeof o==`number`&&Number.isFinite(o)&&o>=0?o:0,u=0;if(typeof s==`number`||typeof s==`string`){let e=Number(s);Number.isFinite(e)&&e>=0&&(u=e)}t.push({path:I(e),size:l,offset:u,unpacked:c})}};return n(e.files,``),t}function ae(e,t,n){let r=e.filter(e=>!e.unpacked).slice(0,32);for(let e of r){let r=t+e.offset,i=r+e.size;if(r<0||i<r||i>n)return!1}return!0}function B(e){if(e.length<16)throw Error(`Invalid ASAR: file too small`);let t=e.readUInt32LE(0),n=e.readUInt32LE(4),r=e.readUInt32LE(8),i=e.readUInt32LE(12),a=Array.from(new Set([r,n,t-8,t])).filter(t=>t>0&&16+t<=e.length),o=null,s=0;for(let t of a){let n=re(e.subarray(16,16+t).toString(`utf-8`)).trim();if(n.length!==0)try{let e=JSON.parse(n);if(k(e)){o=e,s=t;break}}catch{let e=n.lastIndexOf(`}`);if(e>0)try{let r=n.substring(0,e+1),i=JSON.parse(r);if(k(i)){o=i,s=t;break}}catch{}}}if(!o)throw Error(`Invalid ASAR: cannot parse header JSON`);let c=ie(k(o.files)?o:{files:o}),l=Array.from(new Set([16+s+i,8+t,16+r+i,16+n+i])).filter(t=>t>=0&&t<=e.length),u=l[0]??16+s;for(let t of l)if(ae(c,t,e.length)){u=t;break}return{files:c,dataOffset:u,headerSize:t,headerStringSize:n,headerContentSize:r,padding:i}}function oe(e,t,n){let r=I(n);if(r.length===0)return;let i=t.files.find(e=>e.path===r)??t.files.find(e=>e.path.endsWith(`/${r}`));if(!i||i.unpacked)return;let a=t.dataOffset+i.offset,o=a+i.size;if(!(a<0||o>e.length||o<a))return e.subarray(a,o)}function V(e,t,n){let r=oe(e,t,n);return r?r.toString(`utf-8`):void 0}function se(e){let t=new Set,n=/preload\s*:\s*(?:path\.(?:join|resolve)\([^)]*?['"`]([^'"`]+)['"`][^)]*\)|['"`]([^'"`]+)['"`])/g,r=n.exec(e);for(;r;){let i=r[1]??r[2];i&&t.add(i.trim()),r=n.exec(e)}let i=e.match(/devTools\s*:\s*(true|false)/),a=null;return i?.[1]&&(a=i[1]===`true`),/\.openDevTools\s*\(/.test(e)&&(a=!0),{preloadScripts:Array.from(t),devToolsEnabled:a}}async function ce(e){let t=new Set;return await P(e,async(e,n)=>{let r=s(e).toLowerCase();l(e).toLowerCase()===`.js`&&r.includes(`preload`)&&t.add(j(e))}),Array.from(t).toSorted().slice(0,100)}var le=class{collector;constructor(e){this.collector=e}async handleAsarExtract(e){try{let t=D(e,`inputPath`,!0),n=D(e,`outputDir`),r=O(e,`listOnly`,!1);if(!t)throw Error(`inputPath is required`);let i=p(t);if(!(await y(i)).isFile())throw Error(`inputPath must be a file`);let a=await _(i),o=B(a),u=o.files.map(e=>({path:e.path,size:e.size,offset:e.offset})),d=u.reduce((e,t)=>e+t.size,0);if(r)return w({success:!0,files:u,totalFiles:u.length,totalSize:d,dataOffset:o.dataOffset,header:{headerSize:o.headerSize,headerStringSize:o.headerStringSize,headerContentSize:o.headerContentSize,padding:o.padding},collectorState:E(this.collector)});let f=await F(`asar-extract`,s(i,l(i)),n),m=0,h=[];for(let e of o.files){if(e.unpacked){h.push({path:e.path,reason:`Entry is marked as unpacked and not stored inside app.asar`});continue}let t=o.dataOffset+e.offset,n=t+e.size;if(t<0||n>a.length||n<t){h.push({path:e.path,reason:`Entry data range is out of bounds`});continue}try{let r=a.subarray(t,n),i=L(f.absolutePath,e.path);await g(c(i),{recursive:!0}),await b(i,r),m+=1}catch(t){h.push({path:e.path,reason:t instanceof Error?t.message:String(t)})}}return w({success:m>0,files:u,totalFiles:u.length,totalSize:d,extractedFiles:m,failedFiles:h,outputDir:f.displayPath,dataOffset:o.dataOffset,header:{headerSize:o.headerSize,headerStringSize:o.headerStringSize,headerContentSize:o.headerContentSize,padding:o.padding},collectorState:E(this.collector)})}catch(e){return T(`asar_extract`,e)}}async handleElectronInspectApp(t){try{let n=D(t,`appPath`,!0);if(!n)throw Error(`appPath is required`);let r=p(n),i=(await y(r)).isDirectory()?r:c(r),a=[u(i,`resources`,`app.asar`),u(i,`Contents`,`Resources`,`app.asar`),u(i,`app.asar`)],o=null;for(let e of a)if(await M(e)&&(await y(e)).isFile()){o=e;break}let d=null,f=null;if(o)try{d=await _(o),f=B(d)}catch(t){e.warn(`electron_inspect_app failed to parse asar`,{asarPath:o,error:t instanceof Error?t.message:String(t)}),d=null,f=null}let m=null,h=``,g=`none`;if(f&&d){let t=f.files.find(e=>e.path===`package.json`||e.path.endsWith(`/package.json`));if(t){let n=V(d,f,t.path);if(n)try{let e=JSON.parse(n);k(e)&&(m=e,h=t.path,g=`asar`)}catch(n){e.warn(`electron_inspect_app invalid package.json in asar`,{packagePath:t.path,error:n instanceof Error?n.message:String(n)})}}}if(!m){let e=[u(i,`package.json`),u(i,`app`,`package.json`),u(i,`resources`,`app`,`package.json`),u(i,`Contents`,`Resources`,`app`,`package.json`)];for(let t of e){let e=await R(t);if(e){m=e,h=t,g=`filesystem`;break}}}if(!m)return w({success:!1,tool:`electron_inspect_app`,error:`Cannot locate package.json in app directory or app.asar`,appPath:r.replace(/\\/g,`/`),scanRoot:i.replace(/\\/g,`/`),asarPath:o?o.replace(/\\/g,`/`):null,collectorState:E(this.collector)});let v=typeof m.main==`string`&&m.main.trim().length>0?m.main.trim():`index.js`,b=typeof m.version==`string`?m.version:null,x=m.dependencies,S=k(x)?Object.keys(x).toSorted():[],C=``,T=``;if(g===`asar`&&f&&d){let e=h.length>0?c(h):``,t=Array.from(new Set([I(u(e,v)),I(v),I(s(v))])).filter(e=>e.length>0);for(let e of t){let t=V(d,f,e);if(typeof t==`string`){C=t,T=e;break}}if(C.length===0){let e=f.files.find(e=>s(e.path)===s(v));if(e){let t=V(d,f,e.path);typeof t==`string`&&(C=t,T=e.path)}}}else if(g===`filesystem`){let t=p(c(h),v);if(await M(t)&&(await y(t)).isFile())try{C=await _(t,`utf-8`),T=t}catch(n){e.warn(`electron_inspect_app failed to read main script`,{absoluteMainPath:t,error:n instanceof Error?n.message:String(n)})}}let O=C.length>0?se(C):{preloadScripts:[],devToolsEnabled:null},A=new Set(O.preloadScripts);if(A.size===0&&f)for(let e of f.files){let t=e.path.toLowerCase();t.includes(`preload`)&&l(t)===`.js`&&A.add(e.path)}if(A.size===0){let e=await ce(i);for(let t of e)A.add(t)}let N=O.devToolsEnabled===null?!0:O.devToolsEnabled;return w({success:!0,appPath:r.replace(/\\/g,`/`),scanRoot:i.replace(/\\/g,`/`),mainEntry:v,version:b,preloadScripts:Array.from(A).toSorted(),dependencies:S,devToolsEnabled:N,packageSource:g,packagePath:g===`filesystem`?j(h):h,mainScriptPath:T.length>0?g===`filesystem`?j(T):T:null,asarPath:o?j(o):null,browserWindowDetected:C.length>0?C.includes(`BrowserWindow`):!1,collectorState:E(this.collector)})}catch(e){return T(`electron_inspect_app`,e)}}async handleAsarSearch(e){try{let t=D(e,`inputPath`,!0),n=D(e,`pattern`,!0);if(!t)throw Error(`inputPath is required`);if(!n)throw Error(`pattern is required`);let r=D(e,`fileGlob`)||`*.js`,i=typeof e.maxResults==`number`&&e.maxResults>0?e.maxResults:100,a=p(t);if(!await M(a))return w({success:!1,tool:`asar_search`,error:`File does not exist: ${t}`});let o=await _(a),s=B(o),c=r.startsWith(`*.`)?r.slice(1):null,u=s.files.filter(e=>e.unpacked||e.size<=0?!1:c?l(e.path).toLowerCase()===c.toLowerCase():!0),d;try{d=new RegExp(n,`gi`)}catch{return w({success:!1,tool:`asar_search`,error:`Invalid regex pattern: ${n}`})}let f=[],m=0,h=0;for(let e of u){if(m>=i)break;let t=s.dataOffset+e.offset,n=t+e.size;if(t<0||n>o.length||n<t||e.size>512e3)continue;let r=o.subarray(t,n).toString(`utf-8`);h++,d.lastIndex=0;let a=r.split(`
|
|
2
|
+
`),c=[];for(let e=0;e<a.length&&!(m>=i);e++){let t=a[e];t&&(d.lastIndex=0,d.test(t)&&(c.push({lineNumber:e+1,text:t.slice(0,200)}),m++))}c.length>0&&f.push({filePath:e.path,matchCount:c.length,matchLines:c})}return w({success:!0,tool:`asar_search`,matches:f,totalMatches:m,filesScanned:h,pattern:n})}catch(e){return T(`asar_search`,e)}}};async function ue(e){try{let t=D(e,`dirPath`,!0);if(!t)throw Error(`dirPath is required`);let n=typeof e.maxFiles==`number`&&e.maxFiles>0?e.maxFiles:20,r=(typeof e.maxFileSizeKB==`number`&&e.maxFileSizeKB>0?e.maxFileSizeKB:1024)*1024;if(!await M(t))return w({success:!1,tool:`electron_scan_userdata`,error:`Directory does not exist: ${t}`});if(!(await y(t)).isDirectory())return w({success:!1,tool:`electron_scan_userdata`,error:`Path is not a directory: ${t}`});let i;try{i=await v(t)}catch{return w({success:!1,tool:`electron_scan_userdata`,error:`Cannot read directory: ${t}`})}let a=i.filter(e=>e.endsWith(`.json`)).slice(0,n),o=[],s=[];for(let e of a){let n=u(t,e);try{let t=await y(n);if(!t.isFile()){s.push({name:e,reason:`not a file`});continue}if(t.size>r){s.push({name:e,reason:`exceeds maxFileSizeKB`});continue}let i=await _(n,`utf-8`),a=JSON.parse(i);o.push({name:e,sizeBytes:t.size,content:a})}catch{s.push({name:e,reason:`read or parse error`})}}return w({success:!0,tool:`electron_scan_userdata`,files:o,skipped:s,totalScanned:a.length,directory:t})}catch(e){return T(`electron_scan_userdata`,e)}}const H=`dL7pKGdnNz796PbbjQWNKmHXBZIA`,U=[`RunAsNode`,`EnableCookieEncryption`,`EnableNodeOptionsEnvironmentVariable`,`EnableNodeCliInspectArguments`,`EnableEmbeddedAsarIntegrityValidation`,`OnlyLoadAppFromAsar`,`LoadBrowserProcessSpecificV8Snapshot`,`GrantFileProtocolExtraPrivileges`],W={48:`DISABLE`,49:`ENABLE`,114:`REMOVED`},de={RunAsNode:`ENABLE`,EnableNodeOptionsEnvironmentVariable:`ENABLE`,EnableNodeCliInspectArguments:`ENABLE`,OnlyLoadAppFromAsar:`DISABLE`};function G(e,t){let n=t+Buffer.from(H,`ascii`).length,r={};for(let t=0;t<U.length;t++){let i=U[t];if(!i)continue;let a=n+t;if(a>=e.length){r[i]=`UNKNOWN`;continue}let o=e[a];if(o===void 0){r[i]=`UNKNOWN`;continue}r[i]=W[o]??`UNKNOWN`}return r}async function fe(e){try{let t=D(e,`exePath`,!0);if(!t)throw Error(`exePath is required`);if(!await M(t))return w({success:!1,tool:`electron_check_fuses`,error:`File does not exist: ${t}`});let n=await _(t),r=Buffer.from(H,`ascii`),i=n.indexOf(r);return w(i===-1?{success:!0,tool:`electron_check_fuses`,exePath:t,fuseWireFound:!1,fuses:{},note:`No fuse sentinel found. This may not be an Electron binary, or fuses are not configured.`}:{success:!0,tool:`electron_check_fuses`,exePath:t,fuseWireFound:!0,fuses:G(n,i)})}catch(e){return T(`electron_check_fuses`,e)}}async function pe(e){try{let t=D(e,`exePath`,!0);if(!t)throw Error(`exePath is required`);if(!await M(t))return w({success:!1,tool:`electron_patch_fuses`,error:`File does not exist: ${t}`});let n=D(e,`profile`)??`debug`,r=e.createBackup!==!1,i;if(n===`debug`)i={...de};else if(n===`custom`){let t=e.fuses;if(!t||Object.keys(t).length===0)throw Error('profile="custom" requires a `fuses` object mapping fuse names to ENABLE/DISABLE');i={};for(let[e,n]of Object.entries(t)){if(!U.includes(e))throw Error(`Unknown fuse: ${e}. Valid: ${U.join(`, `)}`);if(n!==`ENABLE`&&n!==`DISABLE`)throw Error(`Invalid fuse value for ${e}: ${n}. Must be ENABLE or DISABLE`);i[e]=n}}else throw Error(`Unknown profile: ${n}. Use "debug" or "custom"`);let a=await _(t),o=Buffer.from(H,`ascii`),s=a.indexOf(o);if(s===-1)return w({success:!1,tool:`electron_patch_fuses`,error:`No fuse sentinel found. This may not be an Electron binary.`,exePath:t});let c=G(a,s),l=s+o.length,u=[];for(let[e,t]of Object.entries(i)){let n=U.indexOf(e);if(n===-1)continue;let r=l+n;if(r>=a.length)continue;let i=a[r];if(i===114){u.push({fuse:e,before:`REMOVED`,after:`REMOVED (cannot patch)`});continue}let o=t===`ENABLE`?49:48,s=W[i??0]??`UNKNOWN`;i!==o&&(a[r]=o,u.push({fuse:e,before:s,after:t}))}if(u.length===0)return w({success:!0,tool:`electron_patch_fuses`,exePath:t,message:`All target fuses are already in the desired state. No changes needed.`,fuses:c});let d=null;r&&(d=`${t}.bak`,await h(t,d)),await b(t,a);let f=G(a,s);return w({success:!0,tool:`electron_patch_fuses`,exePath:t,backupPath:d,profile:n,changes:u,fusesBefore:c,fusesAfter:f,note:d?`Backup created at ${d}. Restore with: copy "${d}" "${t}"`:`No backup created (createBackup=false).`})}catch(e){return T(`electron_patch_fuses`,e)}}const K=C(x),me=Buffer.from([192,222]),he=Buffer.from(`BYTN`),ge=new Set([`.jsc`,`.bin`]);function _e(e,t){let n=l(t).toLowerCase();if(e.length>=4&&e.subarray(0,4).equals(he))return`bytenode`;if(e.length>=2&&e.subarray(0,2).equals(me))return`v8-raw`;if(ge.has(n))return`jsc-extension`;let r=[Buffer.from(`Ldar`),Buffer.from(`Star`),Buffer.from(`LdaSmi`),Buffer.from(`CallRuntime`)];for(let t of r)if(e.indexOf(t)!==-1)return`v8-heuristic`;return null}async function ve(e){try{let{stdout:n,stderr:r}=await K(`python`,[`-m`,`view8`,e],{timeout:t,maxBuffer:10*1024*1024});return n&&n.trim().length>0?{ok:!0,output:n}:{ok:!1,error:r||`Empty output from view8`}}catch{try{let{stdout:n}=await K(`python3`,[`-m`,`view8`,e],{timeout:t,maxBuffer:10*1024*1024});return n&&n.trim().length>0?{ok:!0,output:n}:{ok:!1,error:`Empty output from view8`}}catch{return{ok:!1,error:`view8 not available. Install with: pip install view8`}}}}async function q(e){try{return await K(e,[`-c`,`import view8; print(getattr(view8, "__file__", "view8"))`],{timeout:t,maxBuffer:1024*1024}),{available:!0,interpreter:e}}catch(t){return{available:!1,interpreter:e,reason:t instanceof Error?t.message:String(t)}}}async function ye(){let e=await q(`python`);if(e.available)return e;let t=await q(`python3`);return t.available?t:{available:!1,reason:e.reason&&t.reason?`${e.reason}; ${t.reason}`:e.reason??t.reason??`view8 is not available`}}function be(e){let t=[],n=[],r=new Set,i=2e3,a=``;for(let n=0;n<e.length;n++){let o=e[n];o>=32&&o<=126?a+=String.fromCharCode(o):(a.length>=4&&a.length<=i&&J(a)&&!r.has(a)&&(r.add(a),t.push(a)),a=``)}for(let n=0;n<e.length-3;n++)if(e[n+1]===0&&e[n]>=32&&e[n]<=126){let a=``,o=n;for(;o<e.length-1&&e[o]>=32&&e[o]<=126&&e[o+1]===0;)a+=String.fromCharCode(e[o]),o+=2;a.length>=4&&a.length<=i&&J(a)&&!r.has(a)&&(r.add(a),t.push(a))}return{strings:t,numbers:n}}function J(e){return new Set(e).size<=2||(e.match(/[^a-zA-Z0-9_\-.\s/\\:;=+*&|!?,'"(){}[\]<>@#$%^~`]/g)??[]).length/e.length>.3?!1:[/[a-zA-Z_$][a-zA-Z0-9_$]*/,/function\s/,/return\s/,/const\s/,/let\s/,/var\s/,/require\(/,/module\.exports/,/import\s/,/\.prototype\./,/\.call\(/,/\.apply\(/,/async\s/,/await\s/,/Promise/,/https?:\/\//,/[a-zA-Z]+Error/].some(t=>t.test(e))}async function xe(e){try{let t=D(e,`filePath`,!0);if(!t)throw Error(`filePath is required — path to a .jsc or V8 bytecode file`);if(!await M(t))return w({success:!1,tool:`v8_bytecode_decompile`,error:`File does not exist: ${t}`});let n=await y(t);if(n.size>50*1024*1024)return w({success:!1,tool:`v8_bytecode_decompile`,error:`File too large (${(n.size/1024/1024).toFixed(1)}MB). Maximum: 50MB.`});let r=await _(t),i=_e(r,t);if(!i)return w({success:!1,tool:`v8_bytecode_decompile`,filePath:t,fileSize:n.size,error:`Not a recognized V8 bytecode format. Expected .jsc, bytenode, or V8 serialized bytecode.`,hint:`Ensure the file is a V8 compiled bytecode file (created by bytenode or v8.serialize).`});let a={success:!1,tool:`v8_bytecode_decompile`,filePath:t,fileSize:n.size,detectedFormat:i,strategy:`pending`},o=await ve(t);if(o.ok&&o.output)return a.success=!0,a.strategy=`view8`,a.pseudocode=o.output.length>5e4?o.output.slice(0,5e4)+`
|
|
3
|
+
|
|
4
|
+
... [truncated, total `+o.output.length+` chars]`:o.output,w(a);let{strings:s}=be(r);return s.length>0?(a.success=!0,a.strategy=`constant-pool-extraction`,a.strings=s.slice(0,500),a.note=[`view8 unavailable (${o.error}). Used built-in constant pool extraction.`,`Found ${s.length} code-relevant strings. These include function names, identifiers, URLs, and string literals from the original source.`,`For full decompilation, install view8: pip install view8`].join(` `)):(a.success=!1,a.strategy=`none`,a.error=`Could not decompile. view8: ${o.error}. Built-in extraction found no code strings.`,a.note=`The bytecode may be heavily optimized or use an unsupported V8 version.`),w(a)}catch(e){return T(`v8_bytecode_decompile`,e)}}const Y=new Map;async function Se(e){try{let t=await _(e),n=Buffer.from(`dL7pKGdnNz796PbbjQWNKmHXBZIA`,`ascii`),r=t.indexOf(n);if(r===-1)return{fuseFound:!1,runAsNode:!1,inspectArgs:!1,nodeOptions:!1};let i=r+n.length;return{fuseFound:!0,runAsNode:t[i]===49,nodeOptions:t[i+2]===49,inspectArgs:t[i+3]===49}}catch{return{fuseFound:!1,runAsNode:!1,inspectArgs:!1,nodeOptions:!1}}}async function X(e,t=1e4){let n=Date.now();for(;Date.now()-n<t;){try{let t=await fetch(`http://127.0.0.1:${e}/json/version`,{signal:AbortSignal.timeout(2e3)});if(t.ok)return{ok:!0,info:await t.text()}}catch{}await new Promise(e=>setTimeout(e,500))}return{ok:!1,error:`CDP port ${e} did not respond within ${t}ms`}}async function Ce(e){try{let t=D(e,`exePath`,!0);if(!t)throw Error(`exePath is required — path to the Electron .exe`);if(!await M(t))return w({success:!1,tool:`electron_launch_debug`,error:`File does not exist: ${t}`});let n=t.split(/[\\/]/).pop()?.toLowerCase()??``;if(![/^electron/i,/\.app$/i,/chrome/i,/chromium/i].some(e=>e.test(n)))return w({success:!1,tool:`electron_launch_debug`,error:`exePath does not appear to be an Electron binary: ${n}. Only Electron/Chromium executables are allowed.`});let r=e.mainPort??9229,i=e.rendererPort??9222,a=e.args??[],o=[`--require`,`--loader`,`--import`,`-e`,`--eval`,`-p`,`--print`],s=a.filter(e=>!o.some(t=>e===t||e.startsWith(`${t}=`))),c=e.skipFuseCheck===!0,l=e.waitMs??8e3,u=[];if(!c){let e=await Se(t);e.fuseFound&&(e.inspectArgs||u.push(`EnableNodeCliInspectArguments is DISABLED — main process --inspect may be blocked. Use electron_patch_fuses first.`),e.nodeOptions||u.push(`EnableNodeOptionsEnvironmentVariable is DISABLED — NODE_OPTIONS injection blocked.`),e.runAsNode||u.push(`RunAsNode is DISABLED — ELECTRON_RUN_AS_NODE=1 will not work.`))}let d=S(t,[`--inspect=${r}`,`--remote-debugging-port=${i}`,...s],{stdio:`ignore`,detached:!0,env:{...process.env}});if(d.unref(),!d.pid)return w({success:!1,tool:`electron_launch_debug`,error:`Failed to spawn process — no PID returned.`});let f=`electron-${d.pid}`;Y.set(f,{child:d,pid:d.pid,ports:{main:r,renderer:i}});let[p,m]=await Promise.all([X(r,l),X(i,l)]);return w({success:!0,tool:`electron_launch_debug`,sessionId:f,pid:d.pid,ports:{main:{port:r,available:p.ok,info:p.ok?`Ready`:p.error},renderer:{port:i,available:m.ok,info:m.ok?`Ready`:m.error}},fuseWarnings:u.length>0?u:void 0,usage:{main:`Use electron_attach(port=${r}) to debug the main process (Node.js)`,renderer:`Use electron_attach(port=${i}) to debug the renderer (Chromium)`,combined:`Both sessions can be used simultaneously for cross-process analysis`}})}catch(e){return T(`electron_launch_debug`,e)}}async function we(e){try{let t=D(e,`sessionId`);if(t){let e=Y.get(t);if(!e)return w({success:!1,tool:`electron_debug_status`,error:`No session found: ${t}`,activeSessions:Array.from(Y.keys())});let[n,r]=await Promise.all([X(e.ports.main,2e3),X(e.ports.renderer,2e3)]);return w({success:!0,tool:`electron_debug_status`,sessionId:t,pid:e.pid,main:{port:e.ports.main,alive:n.ok},renderer:{port:e.ports.renderer,alive:r.ok}})}return w({success:!0,tool:`electron_debug_status`,sessions:Array.from(Y.entries()).map(([e,t])=>({sessionId:e,pid:t.pid,ports:t.ports}))})}catch(e){return T(`electron_debug_status`,e)}}const Z=new Map;function Q(){return typeof globalThis.WebSocket==`function`?{available:!0}:{available:!1,reason:`Global WebSocket is not available in this Node runtime.`,fix:`Use Node.js 21+ or provide a WebSocket-compatible runtime.`}}async function $(e,t){let n=e.match(/ws:\/\/([\d.]+:\d+)\//);if(!n?.[1])return{ok:!1,error:`Invalid wsDebuggerUrl: ${e}`};let r=n[1];try{let e=(await(await fetch(`http://${r}/json`,{signal:AbortSignal.timeout(5e3)})).json()).find(e=>e.type===`page`);if(!e)return{ok:!1,error:`No page target found`};let n=e.webSocketDebuggerUrl;return n?await Te(n,t):{ok:!1,error:`Page target has no WebSocket debugger URL`}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}function Te(e,t){return new Promise(n=>{try{let r=Q();if(!r.available){n({ok:!1,error:`${r.reason} ${r.fix??``}`.trim()});return}let i=globalThis.WebSocket,a=new i(e),o=setTimeout(()=>{try{a.close()}catch{}n({ok:!1,error:`CDP WebSocket timeout (10s)`})},1e4);a.addEventListener(`open`,()=>{a.send(JSON.stringify({id:1,method:`Runtime.evaluate`,params:{expression:t,returnByValue:!0,awaitPromise:!1}}))}),a.addEventListener(`message`,e=>{clearTimeout(o);try{let t=JSON.parse(String(e.data));t.result?.exceptionDetails?n({ok:!1,error:t.result.exceptionDetails.text}):n({ok:!0,result:String(t.result?.result?.value??``)})}catch(e){n({ok:!1,error:`Parse error: ${e}`})}try{a.close()}catch{}}),a.addEventListener(`error`,e=>{clearTimeout(o),n({ok:!1,error:`WebSocket error: ${e}`})})}catch(e){n({ok:!1,error:e instanceof Error?e.message:String(e)})}})}async function Ee(e){try{let t=D(e,`action`)??`guide`;if(t===`start`){let t=e.port??9222,n=`ipc-sniff-${t}-${Date.now()}`,r;try{r=(await(await fetch(`http://127.0.0.1:${t}/json/version`,{signal:AbortSignal.timeout(5e3)})).json()).webSocketDebuggerUrl??`ws://127.0.0.1:${t}/devtools/browser`}catch{return w({success:!1,tool:`electron_ipc_sniff`,error:`Cannot connect to CDP at port ${t}. Ensure Electron is launched with --remote-debugging-port=${t}.`,hint:`Use electron_launch_debug to start the app with CDP enabled.`})}let i=await $(r,`
|
|
5
|
+
(function() {
|
|
6
|
+
if (window.__ipcSnifferInstalled) return 'already_installed';
|
|
7
|
+
|
|
8
|
+
const captured = [];
|
|
9
|
+
window.__ipcSnifferCaptured = captured;
|
|
10
|
+
window.__ipcSnifferInstalled = true;
|
|
11
|
+
|
|
12
|
+
// Try to access ipcRenderer from contextBridge-exposed API or require
|
|
13
|
+
let ipcRenderer = null;
|
|
14
|
+
|
|
15
|
+
// Method 1: Direct require (works if nodeIntegration is enabled)
|
|
16
|
+
try {
|
|
17
|
+
ipcRenderer = require('electron').ipcRenderer;
|
|
18
|
+
} catch(e) {}
|
|
19
|
+
|
|
20
|
+
// Method 2: window.electron (common contextBridge pattern)
|
|
21
|
+
if (!ipcRenderer && window.electron && window.electron.ipcRenderer) {
|
|
22
|
+
ipcRenderer = window.electron.ipcRenderer;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!ipcRenderer) {
|
|
26
|
+
return 'ipcRenderer_not_accessible';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Hook invoke
|
|
30
|
+
const origInvoke = ipcRenderer.invoke.bind(ipcRenderer);
|
|
31
|
+
ipcRenderer.invoke = function(channel, ...args) {
|
|
32
|
+
captured.push({
|
|
33
|
+
timestamp: Date.now(),
|
|
34
|
+
method: 'invoke',
|
|
35
|
+
channel: channel,
|
|
36
|
+
args: args.map(a => {
|
|
37
|
+
try { return JSON.parse(JSON.stringify(a)); }
|
|
38
|
+
catch { return String(a); }
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
return origInvoke(channel, ...args);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// Hook send
|
|
45
|
+
const origSend = ipcRenderer.send.bind(ipcRenderer);
|
|
46
|
+
ipcRenderer.send = function(channel, ...args) {
|
|
47
|
+
captured.push({
|
|
48
|
+
timestamp: Date.now(),
|
|
49
|
+
method: 'send',
|
|
50
|
+
channel: channel,
|
|
51
|
+
args: args.map(a => {
|
|
52
|
+
try { return JSON.parse(JSON.stringify(a)); }
|
|
53
|
+
catch { return String(a); }
|
|
54
|
+
})
|
|
55
|
+
});
|
|
56
|
+
return origSend(channel, ...args);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Hook sendSync
|
|
60
|
+
if (ipcRenderer.sendSync) {
|
|
61
|
+
const origSendSync = ipcRenderer.sendSync.bind(ipcRenderer);
|
|
62
|
+
ipcRenderer.sendSync = function(channel, ...args) {
|
|
63
|
+
captured.push({
|
|
64
|
+
timestamp: Date.now(),
|
|
65
|
+
method: 'sendSync',
|
|
66
|
+
channel: channel,
|
|
67
|
+
args: args.map(a => {
|
|
68
|
+
try { return JSON.parse(JSON.stringify(a)); }
|
|
69
|
+
catch { return String(a); }
|
|
70
|
+
})
|
|
71
|
+
});
|
|
72
|
+
return origSendSync(channel, ...args);
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return 'hooks_installed';
|
|
77
|
+
})();
|
|
78
|
+
`);if(!i.ok)return w({success:!1,tool:`electron_ipc_sniff`,error:`Failed to inject IPC hooks: ${i.error}`,hint:`The renderer may have contextIsolation enabled. Try injecting via main process CDP instead.`});let a={id:n,port:t,wsUrl:r,messages:[],startedAt:Date.now(),active:!0};return Z.set(n,a),w({success:!0,tool:`electron_ipc_sniff`,action:`start`,sessionId:n,port:t,hookStatus:i.result,usage:{dump:`electron_ipc_sniff(action="dump", sessionId="${n}")`,stop:`electron_ipc_sniff(action="stop", sessionId="${n}")`},note:i.result===`ipcRenderer_not_accessible`?`ipcRenderer not accessible — contextIsolation may be enabled. IPC hooking requires nodeIntegration or a custom preload.`:`IPC hooks installed. Interact with the app, then use dump to retrieve captured messages.`})}if(t===`dump`){let t=D(e,`sessionId`),n=e.port,r=e.clear!==!1,i;if(t)i=Z.get(t);else if(n)i=Array.from(Z.values()).find(e=>e.port===n);else{let e=Array.from(Z.values());i=e[e.length-1]}if(!i)return w({success:!1,tool:`electron_ipc_sniff`,error:`No active IPC sniff session found.`,activeSessions:Array.from(Z.keys()),hint:`Start a session first: electron_ipc_sniff(action="start", port=9222)`});let a=await $(i.wsUrl,`
|
|
79
|
+
(function() {
|
|
80
|
+
const captured = window.__ipcSnifferCaptured || [];
|
|
81
|
+
const result = JSON.stringify(captured);
|
|
82
|
+
return result;
|
|
83
|
+
})();
|
|
84
|
+
`);if(!a.ok)return w({success:!1,tool:`electron_ipc_sniff`,error:`Failed to dump IPC messages: ${a.error}`});let o=[];try{o=JSON.parse(a.result??`[]`)}catch{o=[]}r&&o.length>0&&await $(i.wsUrl,`
|
|
85
|
+
(function() {
|
|
86
|
+
if (window.__ipcSnifferCaptured) {
|
|
87
|
+
const count = window.__ipcSnifferCaptured.length;
|
|
88
|
+
window.__ipcSnifferCaptured.length = 0;
|
|
89
|
+
return String(count);
|
|
90
|
+
}
|
|
91
|
+
return '0';
|
|
92
|
+
})();
|
|
93
|
+
`);let s={};for(let e of o)s[e.channel]=(s[e.channel]??0)+1;return w({success:!0,tool:`electron_ipc_sniff`,action:`dump`,sessionId:i.id,messageCount:o.length,channelSummary:s,messages:o.slice(0,200),cleared:r,note:o.length>200?`Showing first 200 of ${o.length} messages. Use dump repeatedly for ongoing capture.`:void 0})}if(t===`stop`){let t=D(e,`sessionId`);if(!t)return w({success:!1,tool:`electron_ipc_sniff`,error:`sessionId is required for stop.`,activeSessions:Array.from(Z.keys())});let n=Z.get(t);return n?(n.active=!1,Z.delete(t),w({success:!0,tool:`electron_ipc_sniff`,action:`stop`,sessionId:t,message:`IPC sniff session stopped.`,uptime:Math.round((Date.now()-n.startedAt)/1e3)})):w({success:!1,tool:`electron_ipc_sniff`,error:`Session not found: ${t}`})}if(t===`list`){let e=Array.from(Z.entries()).map(([e,t])=>({sessionId:e,port:t.port,active:t.active,uptime:Math.round((Date.now()-t.startedAt)/1e3)}));return w({success:!0,tool:`electron_ipc_sniff`,action:`list`,sessions:e,count:e.length})}return w({success:!0,guide:{what:`Electron IPC sniffer — intercepts ipcRenderer.invoke/send/sendSync messages via CDP injection.`,workflow:[`1. Launch Electron with: electron_launch_debug(exePath="...")`,`2. Start sniffing: electron_ipc_sniff(action="start", port=9222)`,`3. Interact with the app to trigger IPC messages`,`4. Dump captured: electron_ipc_sniff(action="dump", sessionId="...")`,`5. Stop when done: electron_ipc_sniff(action="stop", sessionId="...")`],actions:[`start`,`dump`,`stop`,`list`,`guide`],limitations:[`Requires renderer CDP port (--remote-debugging-port)`,`contextIsolation=true may block direct ipcRenderer access`,`Main process IPC (ipcMain) is captured indirectly through renderer-side hooks`]}})}catch(e){return T(`electron_ipc_sniff`,e)}}async function De(e){let t=(await e.probeAll())[`miniapp.unpacker`],n=await ye()??{available:!1,reason:`view8 probe returned no result`},r=Q()??{available:!1,reason:`IPC runtime probe returned no result`};return w(i(`platform_capabilities`,[{capability:`miniapp_unpacker`,status:t?.available?`available`:`unavailable`,reason:t?.reason,fix:t?.available?void 0:`Install unveilr to enable the fast external unpack path.`,details:{tools:[`miniapp_pkg_unpack`],fallback:`Built-in Node.js parser remains available.`,...t?.path?{path:t.path}:{},...t?.version?{version:t.version}:{}}},{capability:`view8`,status:n.available?`available`:`unavailable`,reason:n.reason,fix:n.available?void 0:`Install view8 with pip install view8 to enable full bytecode decompilation.`,details:{tools:[`v8_bytecode_decompile`],fallback:`Built-in constant-pool extraction remains available.`,...n.interpreter?{interpreter:n.interpreter}:{}}},{capability:`electron_ipc_sniff_runtime`,status:r.available?`available`:`unavailable`,reason:r.reason,fix:r.fix,details:{tools:[`electron_ipc_sniff`],note:`A renderer CDP port is still required at call time.`}}]))}var Oe=class{miniapp;electron;runner;constructor(e){let t=new a;this.runner=new n(t),this.miniapp=new ne(this.runner,e),this.electron=new le(e)}handlePlatformCapabilities(){return De(this.runner)}handleMiniappPkgScan(e){return this.miniapp.handleMiniappPkgScan(e)}handleMiniappPkgUnpack(e){return this.miniapp.handleMiniappPkgUnpack(e)}handleMiniappPkgAnalyze(e){return this.miniapp.handleMiniappPkgAnalyze(e)}handleAsarExtract(e){return this.electron.handleAsarExtract(e)}handleElectronInspectApp(e){return this.electron.handleElectronInspectApp(e)}handleElectronScanUserdata(e){return ue(e)}handleAsarSearch(e){return this.electron.handleAsarSearch(e)}handleElectronCheckFuses(e){return fe(e)}handleElectronPatchFuses(e){return pe(e)}handleV8BytecodeDecompile(e){return xe(e)}handleElectronLaunchDebug(e){return Ce(e)}handleElectronDebugStatus(e){return we(e)}handleElectronIPCSniff(e){return Ee(e)}};export{Oe as PlatformToolHandlers};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./logger-sBC6IdRT.mjs";import{createRequire as t}from"node:module";import{dirname as n,join as r}from"node:path";let i=!1;function a(){let e=n(t(import.meta.url).resolve(`playwright-core/package.json`));return{playwrightServerPath:r(e,`lib/server/playwright.js`),crBrowserPath:r(e,`lib/server/chromium/crBrowser.js`)}}function o(){if(i)return;let n=t(import.meta.url),{playwrightServerPath:r,crBrowserPath:o}=a(),{createPlaywright:s}=n(r);s({sdkLanguage:`javascript`,isInternalPlaywright:!0});let{CRBrowserContext:c}=n(o);if(c.prototype.__jshookElectronCompatPatched){i=!0;return}let l=c.prototype.initialize;c.prototype.initialize=async function(...t){try{return await l.apply(this,t)}catch(t){let n=t instanceof Error?t.message:String(t);if(n.includes(`Browser.setDownloadBehavior`)&&n.includes(`Browser context management is not supported`)){e.warn(`[playwright-cdp-fallback] Swallowed Browser.setDownloadBehavior for legacy Electron CDP endpoint.`);return}throw t}},Object.defineProperty(c.prototype,`__jshookElectronCompatPatched`,{value:!0,configurable:!1,enumerable:!1,writable:!1}),i=!0}function s(e){return e}function c(e){return e===`networkidle0`||e===`networkidle2`?`networkidle`:e}function l(e){let t=e.contexts()[0];if(!t)throw Error(`Connected Playwright CDP browser exposes no default context. Cannot create or resolve pages.`);return t}function u(t,n){let r=n.get(t);if(r)return r;let i=new Proxy({async goto(e,n){return await t.goto(e,{...n,waitUntil:c(n?.waitUntil)})},async reload(e){return await t.reload({...e,waitUntil:c(e?.waitUntil)})},async waitForNavigation(e){let n=c(e?.waitUntil);return typeof t.waitForNavigation==`function`?await t.waitForNavigation({...e,waitUntil:n}):await t.waitForLoadState(n??`load`,{timeout:e?.timeout})},async select(e,...n){return await t.selectOption(e,n)},async evaluateOnNewDocument(e,...n){return await t.addInitScript(e,...n)},async createCDPSession(){let e=t.context();if(typeof e.newCDPSession!=`function`)throw Error(`Playwright BrowserContext does not expose newCDPSession() for the attached page.`);return await e.newCDPSession(t)},async setUserAgent(n){let r=t.context();if(typeof r.newCDPSession!=`function`){e.debug(`[playwright-cdp-fallback] Cannot apply UA override: newCDPSession unavailable.`);return}await(await r.newCDPSession(t)).send(`Network.setUserAgentOverride`,{userAgent:n}),e.debug(`[playwright-cdp-fallback] Applied user agent override via CDP session.`)}},{get(e,n,r){if(Reflect.has(e,n)){let t=Reflect.get(e,n,r);return typeof t==`function`?t.bind(e):t}let i=Reflect.get(t,n);return typeof i==`function`?i.bind(t):i}});return n.set(t,i),i}function d(e,t){return{type:()=>`page`,url:()=>e.url(),page:async()=>u(e,t)}}function f(e){let t=new WeakMap;return new Proxy({targets(){return e.contexts().flatMap(e=>e.pages()).map(e=>d(e,t))},async pages(){return e.contexts().flatMap(e=>e.pages()).map(e=>u(e,t))},async newPage(){return u(await l(e).newPage(),t)},async disconnect(){await e.close()},async close(){await e.close()}},{get(t,n,r){if(Reflect.has(t,n)){let e=Reflect.get(t,n,r);return typeof e==`function`?e.bind(t):e}let i=Reflect.get(e,n);return typeof i==`function`?i.bind(e):i}})}async function p(e,t){o();let{chromium:n}=await import(`playwright-core`);return f(await n.connectOverCDP(s(e),{timeout:t}))}export{p as t};
|