@jshookmcp/jshook 0.2.9 → 0.3.0

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.
Files changed (187) hide show
  1. package/README.md +2 -2
  2. package/README.zh.md +2 -2
  3. package/dist/{AntiCheatDetector-BNk-EoBt.mjs → AntiCheatDetector-CqGDXmfc.mjs} +159 -53
  4. package/dist/{CodeInjector-Cq8q01kp.mjs → CodeInjector-BdjRfNx7.mjs} +5 -5
  5. package/dist/{ConsoleMonitor-CPVQW1Y-.mjs → ConsoleMonitor-DykL3IAw.mjs} +85 -17
  6. package/dist/{DetailedDataManager-BQQcxh64.mjs → DetailedDataManager-HT49OrvF.mjs} +1 -1
  7. package/dist/{ExtensionManager-CWYgw0YW.mjs → ExtensionManager-BDMsY2Dz.mjs} +15 -8
  8. package/dist/{HardwareBreakpoint-B9gZCdFP.mjs → HardwareBreakpoint-Cc2AFq1Y.mjs} +3 -3
  9. package/dist/{HeapAnalyzer-BLDH0dCv.mjs → HeapAnalyzer-DruMgsgj.mjs} +20 -20
  10. package/dist/{HookGeneratorBuilders.core.generators.storage-CtcdK78Q.mjs → HookGeneratorBuilders.core.generators.storage-CTbB4Lcx.mjs} +1 -74
  11. package/dist/{InstrumentationSession-CvPC7Jwy.mjs → InstrumentationSession-DLH0vd-z.mjs} +2 -2
  12. package/dist/{MemoryController-CbVdCIJF.mjs → MemoryController-CMtviNW_.mjs} +3 -3
  13. package/dist/{MemoryScanSession-BsDZbLYm.mjs → MemoryScanSession-ITgb_NMi.mjs} +2 -2
  14. package/dist/{MemoryScanner-Bcpml6II.mjs → MemoryScanner-CiL7Z3ey.mjs} +12 -9
  15. package/dist/{NativeMemoryManager.impl-dZtA1ZGn.mjs → NativeMemoryManager.impl-D9Lkovvn.mjs} +13 -10
  16. package/dist/{NativeMemoryManager.utils-B-FjA2mJ.mjs → NativeMemoryManager.utils-BBlAixF5.mjs} +1 -1
  17. package/dist/{PEAnalyzer-D1lzJ_VG.mjs → PEAnalyzer-DMQ44gen.mjs} +15 -15
  18. package/dist/{PageController-Bqm2kZ_X.mjs → PageController-BPJNqqBN.mjs} +18 -4
  19. package/dist/{PointerChainEngine-BOhyVsjx.mjs → PointerChainEngine-K7wN8Z-w.mjs} +10 -7
  20. package/dist/ProcessRegistry-zGg12QbE.mjs +74 -0
  21. package/dist/{ResponseBuilder-D3iFYx2N.mjs → ResponseBuilder-CJXWmWNw.mjs} +10 -10
  22. package/dist/{ScriptManager-aHHq0X7U.mjs → ScriptManager-ZuWD-0Jg.mjs} +195 -192
  23. package/dist/{Speedhack-CqdIFlQl.mjs → Speedhack-D-z0umeT.mjs} +2 -2
  24. package/dist/{StructureAnalyzer-DhFaPvRO.mjs → StructureAnalyzer-Cav5AVSL.mjs} +9 -6
  25. package/dist/{ToolCatalog-C0JGZoOm.mjs → ToolCatalog-5OJdMiF0.mjs} +81 -81
  26. package/dist/{ToolProbe-oC7aPrkv.mjs → ToolProbe-DbCFGyrg.mjs} +1 -1
  27. package/dist/{ToolRegistry-BjaF4oNz.mjs → ToolRegistry-B9krbTtI.mjs} +51 -2
  28. package/dist/{ToolRouter.policy-BWV67ZK-.mjs → ToolRouter.policy-BGDAGyeH.mjs} +60 -20
  29. package/dist/TraceRecorder-B41Z5XBj.mjs +1286 -0
  30. package/dist/{Win32API-CePkipZY.mjs → Win32API-C2kjj0ze.mjs} +18 -12
  31. package/dist/{Win32Debug-BvKs-gxc.mjs → Win32Debug-CKrGOTpo.mjs} +2 -2
  32. package/dist/{WorkflowEngine-CuvkZtWu.mjs → WorkflowEngine-DJ6M4opp.mjs} +226 -255
  33. package/dist/analysis-BHeJW2Nb.mjs +1234 -0
  34. package/dist/{antidebug-CqDTB_uk.mjs → antidebug-BRKeyt27.mjs} +3 -3
  35. package/dist/{artifactRetention-CFEprwPw.mjs → artifactRetention-CPXkUJXp.mjs} +13 -6
  36. package/dist/{artifacts-Bk2-_uPq.mjs → artifacts-DkfosXH3.mjs} +1 -1
  37. package/dist/authorization-schema-DRqyJMSk.mjs +31 -0
  38. package/dist/{binary-instrument-CXfpx6fT.mjs → binary-instrument--V3MAhJ4.mjs} +19 -27
  39. package/dist/bind-helpers-ClV34xdn.mjs +42 -0
  40. package/dist/{boringssl-inspector-BH2D3VKc.mjs → boringssl-inspector-Bo_LOLaS.mjs} +1 -1
  41. package/dist/{browser-BpOr5PEx.mjs → browser-Dx3_S2cG.mjs} +324 -37
  42. package/dist/capabilities-CcHlvWgK.mjs +33 -0
  43. package/dist/{constants-B0OANIBL.mjs → constants-CDZLOoVv.mjs} +18 -3
  44. package/dist/{coordination-qUbyF8KU.mjs → coordination-DgItD9DL.mjs} +2 -2
  45. package/dist/{debugger-gnKxRSN0.mjs → debugger-RS3RSAqs.mjs} +30 -13
  46. package/dist/definitions-BEoYofW5.mjs +47 -0
  47. package/dist/{definitions-bAhHQJq9.mjs → definitions-BRaefg3u.mjs} +11 -5
  48. package/dist/{definitions-DVGfrn7y.mjs → definitions-BbkvZkiv.mjs} +2 -2
  49. package/dist/definitions-BtWSHJ3o.mjs +17 -0
  50. package/dist/{definitions-BMfYXoNC.mjs → definitions-C1gCHO0i.mjs} +1 -1
  51. package/dist/{definitions-C1UvM5Iy.mjs → definitions-CDOg_b-l.mjs} +14 -2
  52. package/dist/definitions-CVPD9hzZ.mjs +54 -0
  53. package/dist/{definitions-Cke7zEb8.mjs → definitions-Cea8Lgl7.mjs} +1 -1
  54. package/dist/definitions-DAgIyjxM.mjs +10 -0
  55. package/dist/{definitions-B4rAvHNZ.mjs → definitions-DJA27nsL.mjs} +12 -9
  56. package/dist/{definitions-ClJLzsJQ.mjs → definitions-DKPFU3LW.mjs} +1 -1
  57. package/dist/{definitions-D3VsGcvz.mjs → definitions-DPRpZQ96.mjs} +7 -7
  58. package/dist/{definitions-B18eyf0B.mjs → definitions-DUE5gmdn.mjs} +1 -1
  59. package/dist/definitions-DYVjOtxa.mjs +26 -0
  60. package/dist/{definitions-BB_4jnmy.mjs → definitions-DcYLVLCo.mjs} +1 -1
  61. package/dist/{definitions-Beid2EB3.mjs → definitions-Pp5LI2H4.mjs} +1 -1
  62. package/dist/definitions-j9KdHVNR.mjs +14 -0
  63. package/dist/definitions-uzkjBwa7.mjs +258 -0
  64. package/dist/{definitions-Cq-zroAU.mjs → definitions-va-AnLuQ.mjs} +4 -4
  65. package/dist/{encoding-Bvz5jLRv.mjs → encoding-DJeqHmpd.mjs} +18 -4
  66. package/dist/{evidence-graph-bridge-C_fv9PuC.mjs → evidence-graph-bridge-DcYizFk2.mjs} +1 -0
  67. package/dist/{factory-DxlGh9Xf.mjs → factory-C90tBff6.mjs} +6 -6
  68. package/dist/flat-target-session-Dgax2Cy3.mjs +29 -0
  69. package/dist/{graphql-DYWzJ29s.mjs → graphql-CoHrhweh.mjs} +205 -34
  70. package/dist/{handlers-C67ktuRN.mjs → handlers-4jmR0nMs.mjs} +220 -32
  71. package/dist/{handlers-DlCJN4Td.mjs → handlers-BAHPxcch.mjs} +122 -90
  72. package/dist/{handlers-9sAbfIg-.mjs → handlers-BOs9b907.mjs} +849 -801
  73. package/dist/{handlers-DxGIq15_2.mjs → handlers-BWXEy6ef.mjs} +16 -16
  74. package/dist/{handlers-tB9Mp9ZK.mjs → handlers-Bndn6QvE.mjs} +31 -4
  75. package/dist/{handlers-CTsDAO6p.mjs → handlers-BqC4bD4s.mjs} +1 -1
  76. package/dist/{handlers-C87g8oCe.mjs → handlers-BtYq60bM2.mjs} +1 -1
  77. package/dist/{handlers-DeLOCd5m.mjs → handlers-BzgcB4iv.mjs} +17 -17
  78. package/dist/{handlers-Cgyg6c0U.mjs → handlers-CRyRWj2b.mjs} +237 -23
  79. package/dist/{handlers-U6L4xhuF.mjs → handlers-CVv2H1uq.mjs} +24 -17
  80. package/dist/{handlers-tiy7EIBp.mjs → handlers-Dl5a7JS4.mjs} +3 -3
  81. package/dist/{handlers-D6j6yka7.mjs → handlers-Dx2d7jt7.mjs} +1893 -1480
  82. package/dist/{handlers-Bl8zkwz1.mjs → handlers-Dz9PYsCa.mjs} +95 -6
  83. package/dist/handlers-HujRKC3b.mjs +661 -0
  84. package/dist/{handlers.impl-DS0d9fUw.mjs → handlers.impl-XWXkQfyi.mjs} +70 -24
  85. package/dist/{hooks-CzCWByww.mjs → hooks-B1B8NRHL.mjs} +3 -3
  86. package/dist/index.mjs +154 -144
  87. package/dist/{maintenance-P7ePRXQC.mjs → maintenance-PRMkLVRW.mjs} +35 -30
  88. package/dist/manifest-67Bok-Si.mjs +58 -0
  89. package/dist/{manifest-B3QVVeBS.mjs → manifest-6lNTMZAB2.mjs} +33 -28
  90. package/dist/manifest-B2duEHiH.mjs +90 -0
  91. package/dist/manifest-B6EY9Vm8.mjs +57 -0
  92. package/dist/{manifest-gZ4s_UtG.mjs → manifest-B6nKSbyY.mjs} +32 -33
  93. package/dist/{manifest-2ToTpjv8.mjs → manifest-BL8AQNPF.mjs} +31 -31
  94. package/dist/{manifest-DzwvxPJX.mjs → manifest-BSZvJJmV.mjs} +23 -14
  95. package/dist/{manifest-Sc_0JQ13.mjs → manifest-BU7qzUyX.mjs} +23 -23
  96. package/dist/{manifest-CT7zZBV1.mjs → manifest-Bl62e8WK.mjs} +24 -23
  97. package/dist/manifest-Bo5cXjdt.mjs +82 -0
  98. package/dist/manifest-BpS4gtUK.mjs +1347 -0
  99. package/dist/manifest-Bv65_e2W.mjs +101 -0
  100. package/dist/manifest-BytNIF4Z.mjs +117 -0
  101. package/dist/{manifest-BqrQ4Tpj.mjs → manifest-C-xtsjS3.mjs} +23 -23
  102. package/dist/{manifest-NXctwWQq.mjs → manifest-CDYl7OhA.mjs} +36 -38
  103. package/dist/manifest-CRZ3xmkD.mjs +61 -0
  104. package/dist/manifest-CoW6u4Tp.mjs +132 -0
  105. package/dist/manifest-Cq5zN_8A.mjs +50 -0
  106. package/dist/{manifest-CAhOuvSl.mjs → manifest-D7YZM_2e.mjs} +75 -85
  107. package/dist/{manifest-DCyjf4n2.mjs → manifest-DE_VrAeQ.mjs} +27 -7
  108. package/dist/manifest-DGsXSCpT.mjs +39 -0
  109. package/dist/{manifest-BB2J8IMJ.mjs → manifest-DJ2vfEuW.mjs} +48 -41
  110. package/dist/{manifest-3g71z6Bg.mjs → manifest-DPXDYhEu.mjs} +26 -25
  111. package/dist/manifest-Dd4fQb0a.mjs +322 -0
  112. package/dist/{manifest-CXsRWjjI.mjs → manifest-Deq6opGg.mjs} +95 -96
  113. package/dist/{manifest-C9RT5nk32.mjs → manifest-DfJTafJK.mjs} +14 -11
  114. package/dist/manifest-DgOdgN_j.mjs +50 -0
  115. package/dist/{manifest-BmtZzQiQ2.mjs → manifest-DlbMW4v4.mjs} +17 -15
  116. package/dist/{manifest-DrbmZcFl2.mjs → manifest-DmVfbH0w.mjs} +212 -91
  117. package/dist/manifest-Dog6Ddjr.mjs +109 -0
  118. package/dist/manifest-DvgU5FWb.mjs +58 -0
  119. package/dist/manifest-HsfDBs7j.mjs +50 -0
  120. package/dist/manifest-I8oQHvCG.mjs +186 -0
  121. package/dist/manifest-NvH_a-av.mjs +786 -0
  122. package/dist/{manifest-Dh8WBmEW.mjs → manifest-cEJU1v0Z.mjs} +24 -24
  123. package/dist/manifest-wOl5XLB12.mjs +112 -0
  124. package/dist/{modules-C184v-S9.mjs → modules-tZozf0LQ.mjs} +130 -860
  125. package/dist/{mojo-ipc-B_H61Afw.mjs → mojo-ipc-DXNEXEqb.mjs} +141 -26
  126. package/dist/{network-671Cw6hV.mjs → network-CPVvwvFg.mjs} +1329 -823
  127. package/dist/{outputPaths-B1uGmrWZ.mjs → outputPaths-um7lCRY3.mjs} +4 -8
  128. package/dist/{platform-WmNn8Sxb.mjs → platform-CYeFoTWp.mjs} +101 -10
  129. package/dist/{process-QcbIy5Zq.mjs → process-BTbgcVc6.mjs} +251 -346
  130. package/dist/{proxy-DqNs0bAd.mjs → proxy-r8YN6nP1.mjs} +30 -8
  131. package/dist/{registry-D-6e18lB.mjs → registry-Bl8ZQW61.mjs} +3 -3
  132. package/dist/{response-BQVP-xUn.mjs → response-CWhh2aLo.mjs} +7 -1
  133. package/dist/{shared-state-board-DV-dpHFJ.mjs → shared-state-board-BoZnSoj-.mjs} +2 -2
  134. package/dist/{sourcemap-Dq8ez8vS.mjs → sourcemap-BIDHUVXy.mjs} +350 -66
  135. package/dist/{streaming-BUQ0VJsg.mjs → streaming-Dal6utPp.mjs} +13 -13
  136. package/dist/{tool-builder-DCbIC5Eo.mjs → tool-builder-BHJp32mV.mjs} +1 -1
  137. package/dist/{transform-CiYJfNX0.mjs → transform-DRVgGG90.mjs} +18 -14
  138. package/dist/wasm-BYx5UOeG.mjs +1044 -0
  139. package/dist/webcrack-Be0_FccV.mjs +747 -0
  140. package/dist/{workflow-f3xJOcjx.mjs → workflow-BpuKEtvn.mjs} +8 -8
  141. package/package.json +76 -43
  142. package/dist/TraceRecorder-DgxyVbdQ.mjs +0 -519
  143. package/dist/analysis-CL9uACt9.mjs +0 -463
  144. package/dist/bind-helpers-xFfRF-qm.mjs +0 -22
  145. package/dist/definitions-6M-eejaT.mjs +0 -53
  146. package/dist/definitions-B3QdlrHv.mjs +0 -34
  147. package/dist/definitions-CXEI7QC72.mjs +0 -216
  148. package/dist/definitions-C_4r7Fo-2.mjs +0 -14
  149. package/dist/definitions-CkFDALoa.mjs +0 -26
  150. package/dist/definitions-Cy3Sl6gV.mjs +0 -34
  151. package/dist/definitions-LKpC3-nL.mjs +0 -9
  152. package/dist/handlers-DdFzXLvF.mjs +0 -446
  153. package/dist/manifest-82baTv4U.mjs +0 -45
  154. package/dist/manifest-BKbgbSiY.mjs +0 -60
  155. package/dist/manifest-Bcf-TJzH.mjs +0 -848
  156. package/dist/manifest-Bnd7kqEY.mjs +0 -55
  157. package/dist/manifest-BqQX6OQC2.mjs +0 -65
  158. package/dist/manifest-Br4RPFt5.mjs +0 -370
  159. package/dist/manifest-C5qDjysN.mjs +0 -107
  160. package/dist/manifest-CBYWCUBJ.mjs +0 -51
  161. package/dist/manifest-CFADCRa1.mjs +0 -37
  162. package/dist/manifest-CQVhavRF.mjs +0 -114
  163. package/dist/manifest-CV12bcrF.mjs +0 -121
  164. package/dist/manifest-CZLUCfG02.mjs +0 -95
  165. package/dist/manifest-D6phHKFd.mjs +0 -131
  166. package/dist/manifest-DHsnKgP6.mjs +0 -60
  167. package/dist/manifest-Df_dliIe.mjs +0 -55
  168. package/dist/manifest-DhKRAT8_.mjs +0 -92
  169. package/dist/manifest-DlpTj4ic2.mjs +0 -193
  170. package/dist/manifest-DuwHjUa5.mjs +0 -70
  171. package/dist/manifest-qSleDqdO.mjs +0 -1023
  172. package/dist/wasm-DQTnHDs4.mjs +0 -531
  173. /package/dist/{CacheAdapters-CDe5WPSV.mjs → CacheAdapters-jJFy20G-.mjs} +0 -0
  174. /package/dist/{DarwinAPI-BNPxu0RH.mjs → DarwinAPI-ETyy0xyo.mjs} +0 -0
  175. /package/dist/{EventBus-DgPmwpeu.mjs → EventBus-DFKvADm3.mjs} +0 -0
  176. /package/dist/{EvidenceGraphBridge-SFesNera.mjs → EvidenceGraphBridge-318Oi0Lf.mjs} +0 -0
  177. /package/dist/{FingerprintManager-gzWtkKuf.mjs → FingerprintManager-BN4UQWnX.mjs} +0 -0
  178. /package/dist/{PrerequisiteError-Dl33Svkz.mjs → PrerequisiteError-TuyZIs6n.mjs} +0 -0
  179. /package/dist/{ReverseEvidenceGraph-Dlsk94LC.mjs → ReverseEvidenceGraph-C02-gXOh.mjs} +0 -0
  180. /package/dist/{StealthVerifier-Bo4T3bz8.mjs → StealthVerifier-BWmPgQsv.mjs} +0 -0
  181. /package/dist/{VersionDetector-CwVLVdDM.mjs → VersionDetector-K3V4vGsw.mjs} +0 -0
  182. /package/dist/{betterSqlite3-0pqusHHH.mjs → betterSqlite3-DLSBZodi.mjs} +0 -0
  183. /package/dist/{concurrency-Bt0yv1kJ.mjs → concurrency-Drev_Vz9.mjs} +0 -0
  184. /package/dist/{formatAddress-DVkj9kpI.mjs → formatAddress-nnMvEohD.mjs} +0 -0
  185. /package/dist/{parse-args-BlRjqlkL.mjs → parse-args-B4cY5Vx5.mjs} +0 -0
  186. /package/dist/{ssrf-policy-ZaUfvhq7.mjs → ssrf-policy-Dsqd-DTX.mjs} +0 -0
  187. /package/dist/{types-CPhOReNX.mjs → types-DDBWs9UP.mjs} +0 -0
@@ -0,0 +1,1347 @@
1
+ import { t as VersionDetector } from "./VersionDetector-K3V4vGsw.mjs";
2
+ import { a as argString, r as argNumber, t as argBool } from "./parse-args-B4cY5Vx5.mjs";
3
+ import { t as bindByDepKey } from "./bind-helpers-ClV34xdn.mjs";
4
+ import { t as tool } from "./tool-builder-BHJp32mV.mjs";
5
+ import { spawn } from "node:child_process";
6
+ //#region src/modules/v8-inspector/V8InspectorClient.ts
7
+ function isRecord$3(value) {
8
+ return typeof value === "object" && value !== null;
9
+ }
10
+ function toNumber$1(value) {
11
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
12
+ }
13
+ function unwrapRuntimeValue$2(value) {
14
+ if (!isRecord$3(value)) return value;
15
+ if ("value" in value) return unwrapRuntimeValue$2(value["value"]);
16
+ if ("result" in value) return unwrapRuntimeValue$2(value["result"]);
17
+ return value;
18
+ }
19
+ function parseHeapUsage(value) {
20
+ const unwrapped = unwrapRuntimeValue$2(value);
21
+ const normalized = typeof unwrapped === "string" ? (() => {
22
+ try {
23
+ return JSON.parse(unwrapped);
24
+ } catch {
25
+ return null;
26
+ }
27
+ })() : unwrapped;
28
+ if (!isRecord$3(normalized)) return null;
29
+ const jsHeapSizeUsed = toNumber$1(normalized["jsHeapSizeUsed"]) ?? toNumber$1(normalized["usedSize"]);
30
+ const jsHeapSizeTotal = toNumber$1(normalized["jsHeapSizeTotal"]) ?? toNumber$1(normalized["totalSize"]);
31
+ const jsHeapSizeLimit = toNumber$1(normalized["jsHeapSizeLimit"]) ?? 0;
32
+ if (jsHeapSizeUsed === null && jsHeapSizeTotal === null && jsHeapSizeLimit === 0) return null;
33
+ const patch = {};
34
+ if (jsHeapSizeUsed !== null) patch.jsHeapSizeUsed = jsHeapSizeUsed;
35
+ if (jsHeapSizeTotal !== null) patch.jsHeapSizeTotal = jsHeapSizeTotal;
36
+ if (jsHeapSizeLimit > 0) patch.jsHeapSizeLimit = jsHeapSizeLimit;
37
+ return patch;
38
+ }
39
+ function hasMeaningfulHeapUsage(stats) {
40
+ return stats.jsHeapSizeUsed > 0 || stats.jsHeapSizeTotal > 0 || stats.jsHeapSizeLimit > 0;
41
+ }
42
+ function mergeHeapUsage(base, patch) {
43
+ if (!base && !patch) return null;
44
+ const merged = {
45
+ jsHeapSizeUsed: patch?.jsHeapSizeUsed ?? base?.jsHeapSizeUsed ?? 0,
46
+ jsHeapSizeTotal: patch?.jsHeapSizeTotal ?? base?.jsHeapSizeTotal ?? 0,
47
+ jsHeapSizeLimit: patch?.jsHeapSizeLimit ?? base?.jsHeapSizeLimit ?? 0
48
+ };
49
+ return hasMeaningfulHeapUsage(merged) ? merged : null;
50
+ }
51
+ function parsePerformanceMetrics(value) {
52
+ const unwrapped = unwrapRuntimeValue$2(value);
53
+ if (!isRecord$3(unwrapped) || !Array.isArray(unwrapped["metrics"])) return null;
54
+ const metrics = /* @__PURE__ */ new Map();
55
+ for (const metric of unwrapped["metrics"]) {
56
+ if (!isRecord$3(metric)) continue;
57
+ const name = typeof metric["name"] === "string" ? metric["name"] : null;
58
+ const metricValue = toNumber$1(metric["value"]);
59
+ if (!name || metricValue === null) continue;
60
+ metrics.set(name, metricValue);
61
+ }
62
+ const jsHeapSizeUsed = metrics.get("JSHeapUsedSize") ?? 0;
63
+ const jsHeapSizeTotal = metrics.get("JSHeapTotalSize") ?? 0;
64
+ if (jsHeapSizeUsed === 0 && jsHeapSizeTotal === 0) return null;
65
+ return {
66
+ jsHeapSizeUsed,
67
+ jsHeapSizeTotal
68
+ };
69
+ }
70
+ function isCDPPageLike$3(value) {
71
+ return isRecord$3(value) && typeof value["createCDPSession"] === "function";
72
+ }
73
+ function isCDPSessionLike(value) {
74
+ return isRecord$3(value) && typeof value["send"] === "function" && typeof value["detach"] === "function";
75
+ }
76
+ /**
77
+ * CDP wrapper for V8 HeapProfiler operations.
78
+ *
79
+ * Provides heap snapshot capture, object inspection, and usage stats
80
+ * via the Chrome DevTools Protocol HeapProfiler domain.
81
+ */
82
+ var V8InspectorClient = class {
83
+ session = null;
84
+ constructor(getPage) {
85
+ this.getPage = getPage;
86
+ }
87
+ /**
88
+ * Enable the HeapProfiler domain via CDP.
89
+ * Must be called before any heap profiling operations.
90
+ */
91
+ async enableHeapProfiler() {
92
+ const session = await this.createSession();
93
+ if (!session) throw new Error("V8InspectorClient: cannot create CDP session");
94
+ await session.send("HeapProfiler.enable");
95
+ this.session = session;
96
+ }
97
+ /**
98
+ * Take a heap snapshot and collect all chunks via the HeapProfiler.addHeapSnapshotChunk event.
99
+ *
100
+ * @param onChunk - Callback invoked for each snapshot chunk received.
101
+ * @returns Total size of the snapshot in bytes.
102
+ */
103
+ async takeHeapSnapshot(onChunk) {
104
+ if (!this.session) await this.enableHeapProfiler();
105
+ const session = this.session;
106
+ if (!session) throw new Error("V8InspectorClient: session not available for heap snapshot");
107
+ return new Promise((resolve, reject) => {
108
+ const chunks = [];
109
+ let totalSize = 0;
110
+ const chunkHandler = (data) => {
111
+ const chunk = data?.chunk;
112
+ if (typeof chunk === "string") {
113
+ chunks.push(chunk);
114
+ totalSize += Buffer.byteLength(chunk, "utf8");
115
+ onChunk?.(chunk);
116
+ }
117
+ };
118
+ session.on("HeapProfiler.addHeapSnapshotChunk", chunkHandler);
119
+ session.send("HeapProfiler.takeHeapSnapshot", { reportProgress: false }).then(() => {
120
+ session.off("HeapProfiler.addHeapSnapshotChunk", chunkHandler);
121
+ resolve(totalSize);
122
+ }).catch((error) => {
123
+ session.off("HeapProfiler.addHeapSnapshotChunk", chunkHandler);
124
+ reject(error);
125
+ });
126
+ });
127
+ }
128
+ /**
129
+ * Retrieve a heap object by its object ID.
130
+ *
131
+ * @param objectId - Heap snapshot object identifier (e.g. "1:1234").
132
+ * @returns The object's properties and metadata.
133
+ */
134
+ async getObjectByObjectId(_objectId) {
135
+ const session = await this.createSession();
136
+ if (!session) return null;
137
+ try {
138
+ const response = await session.send("Runtime.getProperties", {
139
+ objectId: _objectId,
140
+ ownProperties: true,
141
+ accessorPropertiesOnly: false,
142
+ generatePreview: true
143
+ });
144
+ if (Array.isArray(response.result)) return {
145
+ kind: "runtime-object",
146
+ properties: response.result,
147
+ internalProperties: Array.isArray(response.internalProperties) ? response.internalProperties : [],
148
+ privateProperties: Array.isArray(response.privateProperties) ? response.privateProperties : [],
149
+ ...response.exceptionDetails ? { exceptionDetails: response.exceptionDetails } : {}
150
+ };
151
+ } catch {}
152
+ try {
153
+ return await session.send("HeapProfiler.getObjectByHeapObjectId", { objectId: _objectId });
154
+ } catch {
155
+ return null;
156
+ }
157
+ }
158
+ /**
159
+ * Get current V8 heap usage statistics.
160
+ *
161
+ * @returns Object with jsHeapSizeUsed, jsHeapSizeTotal, jsHeapSizeLimit.
162
+ */
163
+ async getHeapUsage() {
164
+ if (!this.session) await this.enableHeapProfiler();
165
+ const session = this.session;
166
+ if (!session) throw new Error("V8InspectorClient: session not available for heap usage");
167
+ let heapUsage = null;
168
+ try {
169
+ const runtimeUsage = await session.send("Runtime.getHeapUsage");
170
+ heapUsage = mergeHeapUsage(heapUsage, parseHeapUsage(runtimeUsage));
171
+ } catch {}
172
+ try {
173
+ const profilerUsage = await session.send("HeapProfiler.getHeapUsage");
174
+ heapUsage = mergeHeapUsage(heapUsage, parseHeapUsage(profilerUsage));
175
+ } catch {}
176
+ try {
177
+ const metrics = await session.send("Performance.getMetrics");
178
+ heapUsage = mergeHeapUsage(heapUsage, parsePerformanceMetrics(metrics));
179
+ } catch {}
180
+ try {
181
+ const response = await session.send("Runtime.evaluate", {
182
+ expression: `
183
+ (() => {
184
+ const m = performance.memory;
185
+ return m
186
+ ? {
187
+ jsHeapSizeUsed: m.usedJSHeapSize,
188
+ jsHeapSizeTotal: m.totalJSHeapSize,
189
+ jsHeapSizeLimit: m.jsHeapSizeLimit
190
+ }
191
+ : null;
192
+ })()
193
+ `,
194
+ returnByValue: true
195
+ });
196
+ heapUsage = mergeHeapUsage(heapUsage, parseHeapUsage(response));
197
+ } catch {}
198
+ if (!heapUsage) throw new Error("V8InspectorClient: heap usage metrics unavailable");
199
+ return heapUsage;
200
+ }
201
+ /**
202
+ * Detach the underlying CDP session and release resources.
203
+ */
204
+ async dispose() {
205
+ if (this.session) {
206
+ await this.session.detach().catch(() => void 0);
207
+ this.session = null;
208
+ }
209
+ }
210
+ async createSession() {
211
+ if (this.session) return this.session;
212
+ if (!this.getPage) return null;
213
+ try {
214
+ const page = await this.getPage();
215
+ if (!isCDPPageLike$3(page)) return null;
216
+ const session = await page.createCDPSession();
217
+ if (!isCDPSessionLike(session)) return null;
218
+ this.session = session;
219
+ return session;
220
+ } catch {
221
+ return null;
222
+ }
223
+ }
224
+ };
225
+ //#endregion
226
+ //#region src/server/domains/v8-inspector/definitions.ts
227
+ const v8InspectorTools = [
228
+ tool("v8_heap_snapshot_capture", (t) => t.desc("Capture a V8 heap snapshot").query()),
229
+ tool("v8_heap_snapshot_analyze", (t) => t.desc("Analyze a captured V8 heap snapshot").string("snapshotId", "Snapshot ID").required("snapshotId").query()),
230
+ tool("v8_heap_diff", (t) => t.desc("Diff two V8 heap snapshots").string("beforeSnapshotId", "Baseline snapshot ID").string("afterSnapshotId", "Updated snapshot ID").required("beforeSnapshotId", "afterSnapshotId").query()),
231
+ tool("v8_object_inspect", (t) => t.desc("Inspect a live JS object by object identifier").string("address", "Runtime objectId or compatible heap object id").required("address").query()),
232
+ tool("v8_heap_stats", (t) => t.desc("Read V8 heap usage").query()),
233
+ tool("v8_bytecode_extract", (t) => t.desc("Attempt V8 bytecode extraction for a script").string("scriptId", "CDP scriptId").number("functionOffset", "Optional function byte offset").boolean("includeSourceFallback", "Include source-derived fallback output").required("scriptId").query()),
234
+ tool("v8_version_detect", (t) => t.desc("Detect V8 version and capabilities").query()),
235
+ tool("v8_jit_inspect", (t) => t.desc("Inspect JIT status for a V8 script").string("scriptId", "CDP scriptId").required("scriptId").query())
236
+ ];
237
+ //#endregion
238
+ //#region src/server/domains/v8-inspector/handlers/heap-snapshot.ts
239
+ const snapshotCache = /* @__PURE__ */ new Map();
240
+ function getSnapshotCache() {
241
+ return snapshotCache;
242
+ }
243
+ function storeSnapshot(snapshot) {
244
+ snapshotCache.set(snapshot.id, snapshot);
245
+ return snapshot;
246
+ }
247
+ function getSnapshot(snapshotId) {
248
+ return snapshotCache.get(snapshotId);
249
+ }
250
+ function isRecord$2(v) {
251
+ return typeof v === "object" && v !== null;
252
+ }
253
+ function isCDPPageLike$2(v) {
254
+ return isRecord$2(v) && typeof v["createCDPSession"] === "function";
255
+ }
256
+ function unwrapRuntimeValue$1(value) {
257
+ if (!isRecord$2(value)) return value;
258
+ if ("value" in value) return unwrapRuntimeValue$1(value["value"]);
259
+ if ("result" in value) return unwrapRuntimeValue$1(value["result"]);
260
+ return value;
261
+ }
262
+ async function handleHeapSnapshotCapture(_args, options) {
263
+ const snapshotId = `snapshot_${Date.now().toString(36)}`;
264
+ const capturedAt = (/* @__PURE__ */ new Date()).toISOString();
265
+ const chunks = [];
266
+ if (options.client) try {
267
+ const stored = storeSnapshot({
268
+ id: snapshotId,
269
+ chunks,
270
+ capturedAt,
271
+ sizeBytes: await options.client.takeHeapSnapshot((chunk) => {
272
+ chunks.push(chunk);
273
+ })
274
+ });
275
+ options.setSnapshot(snapshotId);
276
+ return {
277
+ success: true,
278
+ snapshotId: stored.id,
279
+ capturedAt: stored.capturedAt,
280
+ sizeBytes: stored.sizeBytes,
281
+ chunks: [],
282
+ simulated: false
283
+ };
284
+ } catch {}
285
+ try {
286
+ const page = await options.getPage();
287
+ if (isCDPPageLike$2(page)) {
288
+ const session = await page.createCDPSession();
289
+ const sessionSend = (method, params) => session.send(method, params);
290
+ const sessionDetach = () => session.detach();
291
+ await sessionSend("HeapProfiler.enable");
292
+ const response = await sessionSend("Runtime.evaluate", {
293
+ expression: `
294
+ (() => {
295
+ const m = performance.memory;
296
+ return m
297
+ ? {
298
+ jsHeapSizeUsed: m.usedJSHeapSize,
299
+ jsHeapSizeTotal: m.totalJSHeapSize,
300
+ jsHeapSizeLimit: m.jsHeapSizeLimit
301
+ }
302
+ : null;
303
+ })()
304
+ `,
305
+ returnByValue: true
306
+ });
307
+ await sessionDetach().catch(() => void 0);
308
+ const result = unwrapRuntimeValue$1(response);
309
+ const parsedResult = typeof result === "string" ? (() => {
310
+ try {
311
+ return JSON.parse(result);
312
+ } catch {
313
+ return null;
314
+ }
315
+ })() : result;
316
+ let sizeBytes = 0;
317
+ if (isRecord$2(parsedResult) && typeof parsedResult["jsHeapSizeUsed"] === "number") sizeBytes = parsedResult["jsHeapSizeUsed"];
318
+ const stored = storeSnapshot({
319
+ id: snapshotId,
320
+ chunks: [`{"simulated":true,"sizeBytes":${sizeBytes}}`],
321
+ capturedAt,
322
+ sizeBytes
323
+ });
324
+ options.setSnapshot(snapshotId);
325
+ return {
326
+ success: true,
327
+ snapshotId: stored.id,
328
+ capturedAt: stored.capturedAt,
329
+ sizeBytes: stored.sizeBytes,
330
+ chunks: [],
331
+ simulated: true
332
+ };
333
+ }
334
+ } catch {}
335
+ const stored = storeSnapshot({
336
+ id: snapshotId,
337
+ chunks: ["{}"],
338
+ capturedAt,
339
+ sizeBytes: 0
340
+ });
341
+ options.setSnapshot(snapshotId);
342
+ return {
343
+ success: true,
344
+ snapshotId: stored.id,
345
+ capturedAt: stored.capturedAt,
346
+ sizeBytes: stored.sizeBytes,
347
+ chunks: [],
348
+ simulated: true
349
+ };
350
+ }
351
+ //#endregion
352
+ //#region src/modules/v8-inspector/NativeBytecodePrinter.ts
353
+ const STATUS_PREFIX = "__JSHOOK_BYTECODE_STATUS__:";
354
+ const TARGET_NAME = "__jshookBytecodeTarget__";
355
+ const DEFAULT_TIMEOUT_MS = 15e3;
356
+ function isValidFunctionName(value) {
357
+ return /^[A-Za-z_$][\w$]*$/u.test(value);
358
+ }
359
+ function normalizeFunctionName(value) {
360
+ const trimmed = value.trim();
361
+ if (trimmed.length === 0 || trimmed === "anonymous") return TARGET_NAME;
362
+ return isValidFunctionName(trimmed) ? trimmed : TARGET_NAME;
363
+ }
364
+ function shouldWrapAsObjectMember(source) {
365
+ const trimmed = source.trim();
366
+ if (trimmed.startsWith("function") || trimmed.startsWith("async function") || trimmed.startsWith("class ") || trimmed.startsWith("(") || trimmed.includes("=>")) return false;
367
+ return /^(?:async\s+)?(?:get\s+|set\s+)?\*?\s*[A-Za-z_$][\w$]*\s*\(/u.test(trimmed);
368
+ }
369
+ function buildBootstrapScript(context) {
370
+ const source = context.sourceSlice.trim();
371
+ const requestedName = context.functionName.trim();
372
+ return `
373
+ let ${TARGET_NAME};
374
+ ${shouldWrapAsObjectMember(source) ? `
375
+ try {
376
+ const __jshookHolder = { ${source} };
377
+ const __jshookCandidate = __jshookHolder[${JSON.stringify(requestedName)}];
378
+ if (typeof __jshookCandidate === 'function') {
379
+ ${TARGET_NAME} = __jshookCandidate;
380
+ }
381
+ } catch {}
382
+ ` : `
383
+ try {
384
+ ${TARGET_NAME} = (${source});
385
+ } catch {}
386
+ `}
387
+
388
+ if (typeof ${TARGET_NAME} !== 'function') {
389
+ console.log(${JSON.stringify(`${STATUS_PREFIX}resolve-failed`)});
390
+ } else {
391
+ try {
392
+ const __jshookArity =
393
+ typeof ${TARGET_NAME}.length === 'number' && ${TARGET_NAME}.length > 0
394
+ ? ${TARGET_NAME}.length
395
+ : 0;
396
+ Reflect.apply(${TARGET_NAME}, globalThis, Array.from({ length: __jshookArity }, () => undefined));
397
+ } catch (error) {
398
+ console.log(${JSON.stringify(`${STATUS_PREFIX}invoke-error:`)} + String(error));
399
+ }
400
+ console.log(${JSON.stringify(`${STATUS_PREFIX}done`)});
401
+ }
402
+ `;
403
+ }
404
+ function parsePrintedBytecode(output, candidateNames) {
405
+ const lines = output.split(/\r?\n/u);
406
+ const filters = new Set(candidateNames.filter((entry) => entry.length > 0));
407
+ let matchedFunctionName = null;
408
+ let capturing = false;
409
+ const captured = [];
410
+ for (const line of lines) {
411
+ const headerMatch = /^\[generated bytecode for function: (.+?) \(/u.exec(line);
412
+ if (headerMatch?.[1]) {
413
+ if (capturing && captured.length > 0) break;
414
+ matchedFunctionName = filters.has(headerMatch[1]) ? headerMatch[1] : null;
415
+ capturing = matchedFunctionName !== null;
416
+ if (capturing) {
417
+ captured.length = 0;
418
+ captured.push(line);
419
+ }
420
+ continue;
421
+ }
422
+ if (!capturing) continue;
423
+ if (line.startsWith(STATUS_PREFIX)) break;
424
+ captured.push(line);
425
+ }
426
+ if (captured.length === 0) return {
427
+ bytecode: null,
428
+ matchedFunctionName: null
429
+ };
430
+ return {
431
+ bytecode: captured.join("\n").trim(),
432
+ matchedFunctionName
433
+ };
434
+ }
435
+ function parseStatus(output) {
436
+ const line = output.split(/\r?\n/u).find((entry) => entry.startsWith(STATUS_PREFIX) && entry.length > 27);
437
+ return line ? line.slice(27) : null;
438
+ }
439
+ function formatIsolatedFailure(output, stderr, fallback) {
440
+ const status = parseStatus(output);
441
+ if (status === "resolve-failed") return "Unable to reconstruct an executable function from the captured source slice";
442
+ if (typeof status === "string" && status.startsWith("invoke-error:")) return `Function compiled but raised during isolated invocation: ${status.slice(13)}`;
443
+ const stderrText = stderr.trim();
444
+ if (stderrText.length > 0) return stderrText;
445
+ return fallback;
446
+ }
447
+ async function runBytecodePrinter(bootstrapScript, filterName, timeoutMs) {
448
+ return await new Promise((resolve) => {
449
+ const child = spawn(process.execPath, [
450
+ "--print-bytecode",
451
+ `--print-bytecode-filter=${filterName}`,
452
+ "-"
453
+ ], { stdio: [
454
+ "pipe",
455
+ "pipe",
456
+ "pipe"
457
+ ] });
458
+ let stdout = "";
459
+ let stderr = "";
460
+ let settled = false;
461
+ const finish = (error) => {
462
+ if (settled) return;
463
+ settled = true;
464
+ clearTimeout(timer);
465
+ resolve({
466
+ stdout,
467
+ stderr,
468
+ error
469
+ });
470
+ };
471
+ const timer = setTimeout(() => {
472
+ child.kill();
473
+ finish(`Timed out after ${timeoutMs}ms while waiting for isolated bytecode output`);
474
+ }, timeoutMs);
475
+ child.stdout.setEncoding("utf8");
476
+ child.stderr.setEncoding("utf8");
477
+ child.stdout.on("data", (chunk) => {
478
+ stdout += chunk;
479
+ });
480
+ child.stderr.on("data", (chunk) => {
481
+ stderr += chunk;
482
+ });
483
+ child.on("error", (error) => {
484
+ finish(error instanceof Error ? error.message : String(error));
485
+ });
486
+ child.on("close", (code) => {
487
+ finish(code === 0 ? null : `Bytecode printer exited with code ${code}`);
488
+ });
489
+ child.stdin.end(bootstrapScript);
490
+ });
491
+ }
492
+ async function printNativeIgnitionBytecode(context, timeoutMs = DEFAULT_TIMEOUT_MS) {
493
+ const requestedName = normalizeFunctionName(context.functionName);
494
+ const candidateNames = Array.from(new Set([requestedName, TARGET_NAME]));
495
+ const bootstrapScript = buildBootstrapScript(context);
496
+ for (const filterName of candidateNames) {
497
+ const { stdout, stderr, error } = await runBytecodePrinter(bootstrapScript, filterName, timeoutMs);
498
+ const extracted = parsePrintedBytecode(stdout, candidateNames);
499
+ if (extracted.bytecode) {
500
+ const resolvedFunctionName = extracted.matchedFunctionName === TARGET_NAME ? requestedName : extracted.matchedFunctionName;
501
+ return {
502
+ available: true,
503
+ bytecode: extracted.bytecode,
504
+ format: "ignition-bytecode",
505
+ functionName: resolvedFunctionName ?? requestedName,
506
+ reason: "Ignition bytecode emitted by an isolated V8 process via --print-bytecode from the extracted source slice",
507
+ rawIgnitionBytecodeAvailable: true
508
+ };
509
+ }
510
+ if (error && filterName === candidateNames.at(-1)) return {
511
+ available: false,
512
+ bytecode: null,
513
+ format: null,
514
+ functionName: requestedName,
515
+ reason: formatIsolatedFailure(stdout, stderr, error),
516
+ rawIgnitionBytecodeAvailable: false
517
+ };
518
+ }
519
+ return {
520
+ available: false,
521
+ bytecode: null,
522
+ format: null,
523
+ functionName: requestedName,
524
+ reason: "Isolated V8 bytecode printer did not emit a matching function block",
525
+ rawIgnitionBytecodeAvailable: false
526
+ };
527
+ }
528
+ //#endregion
529
+ //#region src/modules/v8-inspector/BytecodeExtractor.ts
530
+ function isRecord$1(value) {
531
+ return typeof value === "object" && value !== null;
532
+ }
533
+ function isCDPPageLike$1(value) {
534
+ return isRecord$1(value) && typeof value["createCDPSession"] === "function";
535
+ }
536
+ function toNumber(value) {
537
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
538
+ }
539
+ function toStringValue(value) {
540
+ return typeof value === "string" ? value : null;
541
+ }
542
+ function toRecordArray(value) {
543
+ if (!Array.isArray(value)) return [];
544
+ return value.filter(isRecord$1);
545
+ }
546
+ function splitOperands(raw) {
547
+ return raw.split(",").map((part) => part.trim()).filter((part) => part.length > 0);
548
+ }
549
+ function inferOpcode(line) {
550
+ const trimmed = line.trim();
551
+ if (trimmed.startsWith("function ")) return {
552
+ opcode: "FunctionDeclaration",
553
+ operands: []
554
+ };
555
+ if (trimmed.startsWith("return ")) return {
556
+ opcode: "Return",
557
+ operands: [trimmed.slice(7)]
558
+ };
559
+ if (trimmed.includes("=>")) return {
560
+ opcode: "CreateClosure",
561
+ operands: []
562
+ };
563
+ if (trimmed.includes("(") && trimmed.includes(")")) {
564
+ const nameMatch = /^([A-Za-z_$][\w$]*)\(/u.exec(trimmed);
565
+ if (nameMatch?.[1]) return {
566
+ opcode: "Call",
567
+ operands: [nameMatch[1]]
568
+ };
569
+ }
570
+ if (trimmed.includes("=")) {
571
+ const parts = trimmed.split("=", 2);
572
+ const left = parts[0];
573
+ const right = parts[1];
574
+ if (left && right) return {
575
+ opcode: "Store",
576
+ operands: [left.trim(), right.trim()]
577
+ };
578
+ }
579
+ if (trimmed.startsWith("if ")) return {
580
+ opcode: "JumpIfTrue",
581
+ operands: [trimmed]
582
+ };
583
+ if (trimmed.startsWith("for ") || trimmed.startsWith("while ")) return {
584
+ opcode: "Loop",
585
+ operands: [trimmed]
586
+ };
587
+ if (trimmed.startsWith("{") || trimmed.startsWith("const ") || trimmed.startsWith("let ")) return {
588
+ opcode: "LoadLiteral",
589
+ operands: [trimmed]
590
+ };
591
+ return {
592
+ opcode: "Evaluate",
593
+ operands: [trimmed]
594
+ };
595
+ }
596
+ function buildPseudoBytecode(source) {
597
+ const instructions = ["; pseudo-bytecode synthesized from script source"];
598
+ let offset = 0;
599
+ for (const line of source.split(/\r?\n/u)) {
600
+ const trimmed = line.trim();
601
+ if (trimmed.length === 0) continue;
602
+ const { opcode, operands } = inferOpcode(trimmed);
603
+ const operandText = operands.join(", ");
604
+ instructions.push(`${offset} ${opcode}${operandText.length > 0 ? ` ${operandText}` : ""}`);
605
+ offset += 1;
606
+ }
607
+ return instructions.join("\n");
608
+ }
609
+ function inferFunctionName(source, functionOffset) {
610
+ if (typeof functionOffset === "number" && functionOffset >= 0 && functionOffset < source.length) {
611
+ const start = Math.max(0, functionOffset - 120);
612
+ const end = Math.min(source.length, functionOffset + 120);
613
+ const nearby = source.slice(start, end);
614
+ const namedFunction = /function\s+([A-Za-z_$][\w$]*)/u.exec(nearby);
615
+ if (namedFunction?.[1]) return namedFunction[1];
616
+ const assignedFunction = /([A-Za-z_$][\w$]*)\s*=\s*(?:async\s*)?\(/u.exec(nearby);
617
+ if (assignedFunction?.[1]) return assignedFunction[1];
618
+ }
619
+ return /function\s+([A-Za-z_$][\w$]*)/u.exec(source)?.[1] ?? "anonymous";
620
+ }
621
+ function findObjectLiteralProperties(source) {
622
+ const matches = source.matchAll(/\{([^{}]+:[^{}]+)\}/gu);
623
+ const results = [];
624
+ let index = 0;
625
+ for (const match of matches) {
626
+ const body = match[1];
627
+ if (!body) continue;
628
+ const properties = body.split(",").map((entry) => entry.trim()).map((entry) => {
629
+ const [key] = entry.split(":", 1);
630
+ return key?.trim() ?? "";
631
+ }).filter((entry) => entry.length > 0).filter((entry, position, list) => list.indexOf(entry) === position);
632
+ if (properties.length === 0) continue;
633
+ results.push({
634
+ address: `hidden-class-${index}`,
635
+ properties,
636
+ transitionMap: properties.length > 1 ? properties.join(" -> ") : void 0
637
+ });
638
+ index += 1;
639
+ }
640
+ return results;
641
+ }
642
+ function unwrapRuntimeValue(response) {
643
+ const result = response["result"];
644
+ if (isRecord$1(result) && result["value"] !== void 0) return result["value"];
645
+ return result;
646
+ }
647
+ function formatUnavailableReason(result) {
648
+ const explicitReason = toStringValue(result["reason"]);
649
+ if (explicitReason) return explicitReason;
650
+ const disassemblyError = toStringValue(result["disassemblyError"]);
651
+ if (disassemblyError) return disassemblyError;
652
+ const disassemblyType = toStringValue(result["disassemblyType"]);
653
+ if (disassemblyType) return `Native disassembly returned ${disassemblyType} instead of text`;
654
+ return "Runtime disassembly output is not exposed through the current browser/CDP path";
655
+ }
656
+ var BytecodeExtractor = class {
657
+ versionDetector;
658
+ constructor(getPage) {
659
+ this.getPage = getPage;
660
+ this.versionDetector = new VersionDetector(getPage);
661
+ }
662
+ async extractBytecode(scriptId, functionOffset) {
663
+ const context = await this.resolveScriptFunctionContext(scriptId, functionOffset);
664
+ if (!context) return null;
665
+ return {
666
+ functionName: context.functionName,
667
+ bytecode: buildPseudoBytecode(context.sourceSlice),
668
+ sourcePosition: context.sourcePosition
669
+ };
670
+ }
671
+ async attemptNativeBytecodeExtraction(scriptId, functionOffset) {
672
+ const context = await this.resolveScriptFunctionContext(scriptId, functionOffset);
673
+ if (!context) return null;
674
+ if (!await this.versionDetector.supportsNativesSyntax()) return {
675
+ available: false,
676
+ bytecode: null,
677
+ format: null,
678
+ functionName: context.functionName,
679
+ rawIgnitionBytecodeAvailable: false,
680
+ reason: "V8 natives syntax is unavailable in the current browser target",
681
+ sourcePosition: context.sourcePosition,
682
+ supportsNativesSyntax: false
683
+ };
684
+ const session = await this.createSession();
685
+ if (!session) return {
686
+ available: false,
687
+ bytecode: null,
688
+ format: null,
689
+ functionName: context.functionName,
690
+ rawIgnitionBytecodeAvailable: false,
691
+ reason: "Browser/page CDP session is unavailable for native bytecode inspection",
692
+ sourcePosition: context.sourcePosition,
693
+ supportsNativesSyntax: true
694
+ };
695
+ try {
696
+ const response = await session.send("Runtime.evaluate", {
697
+ expression: this.buildNativeExtractionExpression(context.functionName),
698
+ returnByValue: true,
699
+ awaitPromise: false
700
+ });
701
+ if (!isRecord$1(response)) return {
702
+ available: false,
703
+ bytecode: null,
704
+ format: null,
705
+ functionName: context.functionName,
706
+ rawIgnitionBytecodeAvailable: false,
707
+ reason: "Runtime.evaluate did not return structured data",
708
+ sourcePosition: context.sourcePosition,
709
+ supportsNativesSyntax: true
710
+ };
711
+ if (response["exceptionDetails"]) return {
712
+ available: false,
713
+ bytecode: null,
714
+ format: null,
715
+ functionName: context.functionName,
716
+ rawIgnitionBytecodeAvailable: false,
717
+ reason: "Runtime.evaluate raised an exception while probing native bytecode",
718
+ sourcePosition: context.sourcePosition,
719
+ supportsNativesSyntax: true
720
+ };
721
+ const value = unwrapRuntimeValue(response);
722
+ const result = isRecord$1(value) ? value : {};
723
+ const bytecode = toStringValue(result["disassembly"]);
724
+ const nativeSourcePosition = toNumber(result["nativeSourcePosition"]);
725
+ if (bytecode && bytecode.length > 0) return {
726
+ available: true,
727
+ bytecode,
728
+ format: "v8-disassembly",
729
+ functionName: context.functionName,
730
+ rawIgnitionBytecodeAvailable: false,
731
+ reason: "Native V8 disassembly text returned via %DisassembleFunction",
732
+ sourcePosition: nativeSourcePosition ?? context.sourcePosition,
733
+ supportsNativesSyntax: true
734
+ };
735
+ const isolatedAttempt = await printNativeIgnitionBytecode(context);
736
+ if (isolatedAttempt.available && isolatedAttempt.bytecode) return {
737
+ available: true,
738
+ bytecode: isolatedAttempt.bytecode,
739
+ format: isolatedAttempt.format,
740
+ functionName: isolatedAttempt.functionName,
741
+ rawIgnitionBytecodeAvailable: isolatedAttempt.rawIgnitionBytecodeAvailable,
742
+ reason: isolatedAttempt.reason,
743
+ sourcePosition: nativeSourcePosition ?? context.sourcePosition,
744
+ supportsNativesSyntax: true
745
+ };
746
+ return {
747
+ available: false,
748
+ bytecode: null,
749
+ format: null,
750
+ functionName: context.functionName,
751
+ rawIgnitionBytecodeAvailable: false,
752
+ reason: `${formatUnavailableReason(result)}; isolated printer: ${isolatedAttempt.reason}`,
753
+ sourcePosition: nativeSourcePosition ?? context.sourcePosition,
754
+ supportsNativesSyntax: true
755
+ };
756
+ } catch (error) {
757
+ return {
758
+ available: false,
759
+ bytecode: null,
760
+ format: null,
761
+ functionName: context.functionName,
762
+ rawIgnitionBytecodeAvailable: false,
763
+ reason: error instanceof Error ? error.message : String(error),
764
+ sourcePosition: context.sourcePosition,
765
+ supportsNativesSyntax: true
766
+ };
767
+ } finally {
768
+ await session.detach().catch(() => void 0);
769
+ }
770
+ }
771
+ disassembleBytecode(bytecode) {
772
+ const instructions = [];
773
+ for (const line of bytecode.split(/\r?\n/u)) {
774
+ const trimmed = line.trim();
775
+ if (trimmed.length === 0 || trimmed.startsWith(";")) continue;
776
+ const match = /^\d+\s+\w+>\s+[0-9A-Fa-f]+\s+@\s*(\d+)\s*:\s*(?:[0-9A-Fa-f]{2}(?:\s+[0-9A-Fa-f]{2})*\s+)?([A-Za-z_][\w.]*)\s*(.*)$/u.exec(trimmed) ?? /^(\d+)\s*@\s*([A-Za-z_][\w.]*)\s*(.*)$/u.exec(trimmed) ?? /^(?:0x[0-9a-fA-F]+\s+@)?\s*(\d+)\s*[: ]\s*([A-Za-z_][\w.]*)\s*(.*)$/u.exec(trimmed) ?? /^(\d+)\s+([A-Za-z_][\w.]*)\s*(.*)$/u.exec(trimmed);
777
+ if (!match) continue;
778
+ const offset = Number(match[1]);
779
+ if (!Number.isFinite(offset)) continue;
780
+ instructions.push({
781
+ offset,
782
+ opcode: match[2] ?? "Unknown",
783
+ operands: splitOperands(match[3] ?? "")
784
+ });
785
+ }
786
+ return instructions;
787
+ }
788
+ async findHiddenClasses(scriptId) {
789
+ const scriptSource = await this.getScriptSource(scriptId);
790
+ if (!scriptSource) return [];
791
+ return findObjectLiteralProperties(scriptSource);
792
+ }
793
+ buildNativeExtractionExpression(functionName) {
794
+ return `
795
+ (() => {
796
+ const functionName = ${JSON.stringify(functionName)};
797
+ try {
798
+ const candidate = globalThis[functionName];
799
+ if (typeof candidate !== 'function') {
800
+ return {
801
+ functionName,
802
+ reason: 'Resolved function is not reachable via globalThis in the current target',
803
+ };
804
+ }
805
+
806
+ const nativeSourcePosition = (() => {
807
+ try {
808
+ return %FunctionGetScriptSourcePosition(candidate);
809
+ } catch (error) {
810
+ return null;
811
+ }
812
+ })();
813
+
814
+ try {
815
+ const disassembly = %DisassembleFunction(candidate);
816
+ return {
817
+ functionName,
818
+ disassembly: typeof disassembly === 'string' ? disassembly : null,
819
+ disassemblyType: typeof disassembly,
820
+ nativeSourcePosition:
821
+ typeof nativeSourcePosition === 'number' ? nativeSourcePosition : null,
822
+ };
823
+ } catch (error) {
824
+ return {
825
+ functionName,
826
+ disassemblyError: String(error),
827
+ nativeSourcePosition:
828
+ typeof nativeSourcePosition === 'number' ? nativeSourcePosition : null,
829
+ };
830
+ }
831
+ } catch (error) {
832
+ return {
833
+ functionName,
834
+ reason: String(error),
835
+ };
836
+ }
837
+ })()
838
+ `;
839
+ }
840
+ async resolveScriptFunctionContext(scriptId, functionOffset) {
841
+ const scriptSource = await this.getScriptSource(scriptId);
842
+ if (!scriptSource) return null;
843
+ const functions = await this.getCoverageFunctions(scriptId);
844
+ const defaultFunction = (typeof functionOffset === "number" ? functions.find((candidate) => functionOffset >= candidate.startOffset && functionOffset <= candidate.endOffset) : void 0) ?? functions.find((candidate) => candidate.functionName.length > 0 && candidate.functionName !== "anonymous") ?? functions[0];
845
+ const functionName = defaultFunction?.functionName && defaultFunction.functionName.length > 0 && defaultFunction.functionName !== "anonymous" ? defaultFunction.functionName : inferFunctionName(scriptSource, functionOffset);
846
+ const sourceSlice = defaultFunction && defaultFunction.endOffset > defaultFunction.startOffset ? scriptSource.slice(defaultFunction.startOffset, defaultFunction.endOffset) : scriptSource;
847
+ return {
848
+ functionName,
849
+ sourcePosition: typeof functionOffset === "number" ? functionOffset : defaultFunction ? defaultFunction.startOffset : void 0,
850
+ sourceSlice
851
+ };
852
+ }
853
+ async getCoverageFunctions(scriptId) {
854
+ const session = await this.createSession();
855
+ if (!session) return [];
856
+ try {
857
+ await session.send("Profiler.enable");
858
+ await session.send("Profiler.startPreciseCoverage", {
859
+ callCount: true,
860
+ detailed: true
861
+ });
862
+ const response = await session.send("Profiler.takePreciseCoverage");
863
+ const targetScript = (isRecord$1(response) ? toRecordArray(response["result"]) : []).find((entry) => typeof entry["scriptId"] === "string" && entry["scriptId"] === scriptId);
864
+ if (!targetScript) return [];
865
+ const functions = toRecordArray(targetScript["functions"]);
866
+ const extracted = [];
867
+ for (const fn of functions) {
868
+ const primaryRange = toRecordArray(fn["ranges"])[0];
869
+ if (!primaryRange) continue;
870
+ const startOffset = toNumber(primaryRange["startOffset"]);
871
+ const endOffset = toNumber(primaryRange["endOffset"]);
872
+ if (startOffset === null || endOffset === null) continue;
873
+ extracted.push({
874
+ functionName: toStringValue(fn["functionName"]) ?? "anonymous",
875
+ startOffset,
876
+ endOffset
877
+ });
878
+ }
879
+ return extracted;
880
+ } catch {
881
+ return [];
882
+ } finally {
883
+ await session.send("Profiler.stopPreciseCoverage").catch(() => void 0);
884
+ await session.send("Profiler.disable").catch(() => void 0);
885
+ await session.detach().catch(() => void 0);
886
+ }
887
+ }
888
+ async getScriptSource(scriptId) {
889
+ const session = await this.createSession();
890
+ if (!session) return null;
891
+ try {
892
+ await session.send("Debugger.enable");
893
+ const response = await session.send("Debugger.getScriptSource", { scriptId });
894
+ if (!isRecord$1(response)) return null;
895
+ const scriptSource = response["scriptSource"];
896
+ return typeof scriptSource === "string" ? scriptSource : null;
897
+ } catch {
898
+ return null;
899
+ } finally {
900
+ await session.send("Debugger.disable").catch(() => void 0);
901
+ await session.detach().catch(() => void 0);
902
+ }
903
+ }
904
+ async createSession() {
905
+ if (!this.getPage) return null;
906
+ try {
907
+ const page = await this.getPage();
908
+ if (!isCDPPageLike$1(page)) return null;
909
+ return await page.createCDPSession();
910
+ } catch {
911
+ return null;
912
+ }
913
+ }
914
+ };
915
+ //#endregion
916
+ //#region src/modules/v8-inspector/JITInspector.ts
917
+ function isRecord(value) {
918
+ return typeof value === "object" && value !== null;
919
+ }
920
+ function isCDPPageLike(value) {
921
+ return isRecord(value) && typeof value["createCDPSession"] === "function";
922
+ }
923
+ function readNumber(value) {
924
+ if (typeof value === "number" && Number.isFinite(value)) return value;
925
+ if (isRecord(value) && typeof value["value"] === "number") {
926
+ const nested = value["value"];
927
+ return typeof nested === "number" && Number.isFinite(nested) ? nested : null;
928
+ }
929
+ return null;
930
+ }
931
+ function mapOptimizationTier(status) {
932
+ if (status === null) return {
933
+ optimized: false,
934
+ tier: "unknown"
935
+ };
936
+ if ((status & 128) !== 0) return {
937
+ optimized: true,
938
+ tier: "maglev"
939
+ };
940
+ if ((status & 64) !== 0) return {
941
+ optimized: true,
942
+ tier: "turbofan"
943
+ };
944
+ if ((status & 16) !== 0 || (status & 32) !== 0) return {
945
+ optimized: true,
946
+ tier: "optimized"
947
+ };
948
+ return {
949
+ optimized: false,
950
+ tier: "interpreted"
951
+ };
952
+ }
953
+ var JITInspector = class {
954
+ bytecodeExtractor;
955
+ versionDetector;
956
+ optimizedFunctionsCache = [];
957
+ constructor(getPage) {
958
+ this.getPage = getPage;
959
+ this.bytecodeExtractor = new BytecodeExtractor(getPage);
960
+ this.versionDetector = new VersionDetector(getPage);
961
+ }
962
+ async inspectJIT(scriptId) {
963
+ const hiddenClasses = await this.bytecodeExtractor.findHiddenClasses(scriptId);
964
+ const extraction = await this.bytecodeExtractor.extractBytecode(scriptId);
965
+ const functionNames = /* @__PURE__ */ new Set();
966
+ if (extraction) functionNames.add(extraction.functionName);
967
+ for (const hiddenClass of hiddenClasses) {
968
+ const candidate = hiddenClass.properties[0];
969
+ if (candidate) functionNames.add(candidate);
970
+ }
971
+ if (functionNames.size === 0) functionNames.add("anonymous");
972
+ const supportsNativesSyntax = await this.versionDetector.supportsNativesSyntax();
973
+ const results = [];
974
+ for (const functionName of functionNames) {
975
+ const { optimized, tier } = mapOptimizationTier(supportsNativesSyntax ? await this.getOptimizationStatus(functionName) : null);
976
+ results.push({
977
+ functionName,
978
+ optimized,
979
+ tier
980
+ });
981
+ }
982
+ this.optimizedFunctionsCache = results;
983
+ return {
984
+ functions: results,
985
+ supportsNativesSyntax,
986
+ inspectionMode: supportsNativesSyntax ? "native-status" : "heuristic"
987
+ };
988
+ }
989
+ async forceDeoptimization(functionRef) {
990
+ if (!await this.versionDetector.supportsNativesSyntax()) return;
991
+ const session = await this.createSession();
992
+ if (!session) return;
993
+ try {
994
+ await session.send("Runtime.evaluate", {
995
+ expression: `
996
+ (() => {
997
+ try {
998
+ const candidate = eval(${JSON.stringify(functionRef)});
999
+ if (typeof candidate === 'function') {
1000
+ %DeoptimizeFunction(candidate);
1001
+ }
1002
+ } catch (error) {
1003
+ return undefined;
1004
+ }
1005
+ return undefined;
1006
+ })()
1007
+ `,
1008
+ returnByValue: true,
1009
+ awaitPromise: false
1010
+ });
1011
+ } finally {
1012
+ await session.detach().catch(() => void 0);
1013
+ }
1014
+ }
1015
+ async getOptimizedFunctions() {
1016
+ return [...this.optimizedFunctionsCache];
1017
+ }
1018
+ async getOptimizationStatus(functionName) {
1019
+ const session = await this.createSession();
1020
+ if (!session) return null;
1021
+ try {
1022
+ const response = await session.send("Runtime.evaluate", {
1023
+ expression: `
1024
+ (() => {
1025
+ try {
1026
+ const candidate = globalThis[${JSON.stringify(functionName)}];
1027
+ if (typeof candidate !== 'function') {
1028
+ return null;
1029
+ }
1030
+ return %GetOptimizationStatus(candidate);
1031
+ } catch (error) {
1032
+ return null;
1033
+ }
1034
+ })()
1035
+ `,
1036
+ returnByValue: true,
1037
+ awaitPromise: false
1038
+ });
1039
+ if (!isRecord(response)) return null;
1040
+ return readNumber(response["result"]);
1041
+ } catch {
1042
+ return null;
1043
+ } finally {
1044
+ await session.detach().catch(() => void 0);
1045
+ }
1046
+ }
1047
+ async createSession() {
1048
+ if (!this.getPage) return null;
1049
+ try {
1050
+ const page = await this.getPage();
1051
+ if (!isCDPPageLike(page)) return null;
1052
+ return await page.createCDPSession();
1053
+ } catch {
1054
+ return null;
1055
+ }
1056
+ }
1057
+ };
1058
+ //#endregion
1059
+ //#region src/server/domains/v8-inspector/handlers/bytecode-extract.ts
1060
+ async function handleBytecodeExtract(args, runtime) {
1061
+ const scriptId = argString(args, "scriptId", "").trim();
1062
+ const functionOffset = argNumber(args, "functionOffset");
1063
+ const includeSourceFallback = argBool(args, "includeSourceFallback", false);
1064
+ if (scriptId.length === 0) return {
1065
+ success: false,
1066
+ error: "scriptId is required"
1067
+ };
1068
+ const extractor = new BytecodeExtractor(runtime?.getPage);
1069
+ const nativeAttempt = await extractor.attemptNativeBytecodeExtraction(scriptId, functionOffset ?? void 0);
1070
+ if (!nativeAttempt) return {
1071
+ success: false,
1072
+ error: `Unable to inspect bytecode for scriptId "${scriptId}"`
1073
+ };
1074
+ const hiddenClasses = await extractor.findHiddenClasses(scriptId);
1075
+ if (nativeAttempt.available && nativeAttempt.bytecode) {
1076
+ const extraction = {
1077
+ functionName: nativeAttempt.functionName,
1078
+ bytecode: nativeAttempt.bytecode,
1079
+ sourcePosition: nativeAttempt.sourcePosition
1080
+ };
1081
+ return {
1082
+ success: true,
1083
+ scriptId,
1084
+ functionOffset: functionOffset ?? null,
1085
+ mode: "native",
1086
+ bytecodeAvailable: true,
1087
+ format: nativeAttempt.format,
1088
+ rawIgnitionBytecodeAvailable: nativeAttempt.rawIgnitionBytecodeAvailable,
1089
+ supportsNativesSyntax: nativeAttempt.supportsNativesSyntax,
1090
+ reason: nativeAttempt.reason,
1091
+ extraction,
1092
+ disassembly: extractor.disassembleBytecode(nativeAttempt.bytecode),
1093
+ hiddenClasses,
1094
+ sourceFallback: null
1095
+ };
1096
+ }
1097
+ const sourceFallback = includeSourceFallback ? await extractor.extractBytecode(scriptId, functionOffset ?? void 0) : null;
1098
+ return {
1099
+ success: true,
1100
+ scriptId,
1101
+ functionOffset: functionOffset ?? null,
1102
+ mode: sourceFallback ? "source-fallback" : "unavailable",
1103
+ bytecodeAvailable: false,
1104
+ format: null,
1105
+ rawIgnitionBytecodeAvailable: nativeAttempt.rawIgnitionBytecodeAvailable,
1106
+ supportsNativesSyntax: nativeAttempt.supportsNativesSyntax,
1107
+ reason: nativeAttempt.reason,
1108
+ extraction: null,
1109
+ disassembly: [],
1110
+ hiddenClasses,
1111
+ sourceFallback: sourceFallback ? {
1112
+ format: "pseudo-bytecode",
1113
+ extraction: sourceFallback,
1114
+ disassembly: extractor.disassembleBytecode(sourceFallback.bytecode)
1115
+ } : null
1116
+ };
1117
+ }
1118
+ //#endregion
1119
+ //#region src/server/domains/v8-inspector/handlers/jit-inspect.ts
1120
+ async function handleJitInspect(args, runtime) {
1121
+ const scriptId = argString(args, "scriptId", "").trim();
1122
+ if (scriptId.length === 0) return {
1123
+ success: false,
1124
+ error: "scriptId is required"
1125
+ };
1126
+ const inspection = await new JITInspector(runtime?.getPage).inspectJIT(scriptId);
1127
+ return {
1128
+ success: true,
1129
+ scriptId,
1130
+ inspectionMode: inspection.inspectionMode,
1131
+ supportsNativesSyntax: inspection.supportsNativesSyntax,
1132
+ functions: inspection.functions
1133
+ };
1134
+ }
1135
+ //#endregion
1136
+ //#region src/server/domains/v8-inspector/handlers/impl.ts
1137
+ function createDebuggerObjectData(properties) {
1138
+ return {
1139
+ kind: "runtime-object",
1140
+ source: "debugger-session",
1141
+ propertyCount: properties.length,
1142
+ properties
1143
+ };
1144
+ }
1145
+ function requireStringArg(args, key) {
1146
+ const value = args[key];
1147
+ if (typeof value !== "string" || value.length === 0) throw new Error(`${key} is required`);
1148
+ return value;
1149
+ }
1150
+ function requirePageController(ctx) {
1151
+ const pageController = ctx.pageController;
1152
+ if (!pageController) throw new Error("PageController not available");
1153
+ return pageController;
1154
+ }
1155
+ function createV8InspectorClient(ctx) {
1156
+ return new V8InspectorClient(createPageGetter(ctx));
1157
+ }
1158
+ function createPageGetter(ctx) {
1159
+ const pageController = requirePageController(ctx);
1160
+ return async () => await pageController.getPage();
1161
+ }
1162
+ var V8InspectorHandlers = class {
1163
+ currentSnapshotId = null;
1164
+ constructor(deps) {
1165
+ this.deps = deps;
1166
+ }
1167
+ async handle(toolName, args) {
1168
+ const handler = {
1169
+ v8_heap_snapshot_capture: (toolArgs) => this.v8_heap_snapshot_capture(toolArgs),
1170
+ v8_heap_snapshot_analyze: (toolArgs) => this.v8_heap_snapshot_analyze(toolArgs),
1171
+ v8_heap_diff: (toolArgs) => this.v8_heap_diff(toolArgs),
1172
+ v8_object_inspect: (toolArgs) => this.v8_object_inspect(toolArgs),
1173
+ v8_heap_stats: (toolArgs) => this.v8_heap_stats(toolArgs),
1174
+ v8_bytecode_extract: (toolArgs) => this.v8_bytecode_extract(toolArgs),
1175
+ v8_version_detect: (toolArgs) => this.v8_version_detect(toolArgs),
1176
+ v8_jit_inspect: (toolArgs) => this.v8_jit_inspect(toolArgs)
1177
+ }[toolName];
1178
+ if (!handler) throw new Error(`Unknown v8-inspector tool: ${toolName}`);
1179
+ return handler(args);
1180
+ }
1181
+ async v8_heap_snapshot_capture(args) {
1182
+ requirePageController(this.deps.ctx);
1183
+ const result = await handleHeapSnapshotCapture(args, {
1184
+ getPage: createPageGetter(this.deps.ctx),
1185
+ getSnapshot: () => this.currentSnapshotId,
1186
+ setSnapshot: (id) => {
1187
+ this.currentSnapshotId = id;
1188
+ },
1189
+ client: this.deps.client
1190
+ });
1191
+ if (result.success && result.snapshotId) this.deps.ctx.eventBus.emit("v8:heap_captured", {
1192
+ snapshotId: result.snapshotId,
1193
+ sizeBytes: result.sizeBytes,
1194
+ timestamp: result.capturedAt
1195
+ });
1196
+ return result;
1197
+ }
1198
+ async v8_heap_snapshot_analyze(args) {
1199
+ const snapshotId = requireStringArg(args, "snapshotId");
1200
+ const snapshot = getSnapshot(snapshotId);
1201
+ if (!snapshot) throw new Error(`Snapshot ${snapshotId} not found`);
1202
+ return {
1203
+ success: true,
1204
+ snapshotId,
1205
+ summary: {
1206
+ chunkCount: snapshot.chunks.length,
1207
+ sizeBytes: snapshot.sizeBytes
1208
+ },
1209
+ objectAddress: `0x${snapshot.sizeBytes.toString(16)}`
1210
+ };
1211
+ }
1212
+ async v8_heap_diff(args) {
1213
+ const beforeSnapshotId = typeof args.beforeSnapshotId === "string" ? args.beforeSnapshotId : void 0;
1214
+ const afterSnapshotId = typeof args.afterSnapshotId === "string" ? args.afterSnapshotId : void 0;
1215
+ if (!beforeSnapshotId || !afterSnapshotId) throw new Error("Both beforeSnapshotId and afterSnapshotId are required");
1216
+ const beforeSnapshot = getSnapshot(beforeSnapshotId);
1217
+ if (!beforeSnapshot) throw new Error(`Snapshot ${beforeSnapshotId} not found`);
1218
+ const afterSnapshot = getSnapshot(afterSnapshotId);
1219
+ if (!afterSnapshot) throw new Error(`Snapshot ${afterSnapshotId} not found`);
1220
+ return {
1221
+ success: true,
1222
+ beforeSnapshotId,
1223
+ afterSnapshotId,
1224
+ sizeDeltaBytes: afterSnapshot.sizeBytes - beforeSnapshot.sizeBytes
1225
+ };
1226
+ }
1227
+ async v8_object_inspect(args) {
1228
+ const address = requireStringArg(args, "address");
1229
+ let objectData = await this.inspectObjectViaDebugger(address);
1230
+ if (!objectData) try {
1231
+ objectData = await this.deps.client.getObjectByObjectId(address) ?? void 0;
1232
+ } catch {}
1233
+ return {
1234
+ success: true,
1235
+ address,
1236
+ ...objectData ? { objectData } : {}
1237
+ };
1238
+ }
1239
+ async v8_heap_stats(_args) {
1240
+ requirePageController(this.deps.ctx);
1241
+ let heapUsage;
1242
+ try {
1243
+ heapUsage = await this.deps.client.getHeapUsage();
1244
+ } catch {}
1245
+ return {
1246
+ success: true,
1247
+ snapshotCount: getSnapshotCache().size,
1248
+ ...heapUsage ? { heapUsage } : {}
1249
+ };
1250
+ }
1251
+ async v8_bytecode_extract(args) {
1252
+ return handleBytecodeExtract(args, { getPage: this.deps.ctx.pageController ? createPageGetter(this.deps.ctx) : void 0 });
1253
+ }
1254
+ async v8_version_detect(_args) {
1255
+ if (!this.deps.ctx.pageController) return {
1256
+ success: false,
1257
+ error: "PageController not available"
1258
+ };
1259
+ const { VersionDetector } = await import("./VersionDetector-K3V4vGsw.mjs").then((n) => n.n);
1260
+ const detector = new VersionDetector(createPageGetter(this.deps.ctx));
1261
+ return {
1262
+ success: true,
1263
+ version: await detector.detectV8Version(),
1264
+ features: { nativesSyntax: await detector.supportsNativesSyntax() }
1265
+ };
1266
+ }
1267
+ async v8_jit_inspect(args) {
1268
+ return handleJitInspect(args, { getPage: this.deps.ctx.pageController ? createPageGetter(this.deps.ctx) : void 0 });
1269
+ }
1270
+ async inspectObjectViaDebugger(address) {
1271
+ const debuggerManager = this.deps.ctx.debuggerManager;
1272
+ if (!debuggerManager || typeof debuggerManager.getObjectPropertiesById !== "function") return;
1273
+ try {
1274
+ const properties = await debuggerManager.getObjectPropertiesById(address);
1275
+ if (!Array.isArray(properties)) return;
1276
+ return createDebuggerObjectData(properties);
1277
+ } catch {
1278
+ return;
1279
+ }
1280
+ }
1281
+ };
1282
+ const registrations = v8InspectorTools.map((toolDef) => ({
1283
+ tool: toolDef,
1284
+ domain: "v8-inspector",
1285
+ bind: bindByDepKey("v8InspectorHandlers", (handlers, args) => handlers.handle(toolDef.name, args))
1286
+ }));
1287
+ async function ensure(ctx) {
1288
+ if (!ctx.pageController) throw new Error("v8-inspector: PageController not available");
1289
+ const handlers = new V8InspectorHandlers({
1290
+ ctx,
1291
+ client: createV8InspectorClient(ctx)
1292
+ });
1293
+ ctx.v8InspectorHandlers = handlers;
1294
+ return handlers;
1295
+ }
1296
+ const manifest = {
1297
+ kind: "domain-manifest",
1298
+ version: 1,
1299
+ domain: "v8-inspector",
1300
+ depKey: "v8InspectorHandlers",
1301
+ profiles: ["workflow", "full"],
1302
+ registrations,
1303
+ ensure,
1304
+ prerequisites: {
1305
+ v8_heap_snapshot_capture: [{
1306
+ condition: "Browser must be connected",
1307
+ fix: "Call browser_launch or browser_attach first"
1308
+ }],
1309
+ v8_heap_snapshot_analyze: [{
1310
+ condition: "A snapshotId must be provided",
1311
+ fix: "Capture a heap snapshot before analysis"
1312
+ }],
1313
+ v8_heap_diff: [{
1314
+ condition: "Both snapshot identifiers are required",
1315
+ fix: "Capture before/after snapshots before diffing"
1316
+ }]
1317
+ },
1318
+ toolDependencies: [{
1319
+ from: "v8_heap_snapshot_capture",
1320
+ to: "browser_attach",
1321
+ relation: "requires",
1322
+ weight: .8
1323
+ }, {
1324
+ from: "v8_object_inspect",
1325
+ to: "v8_heap_snapshot_analyze",
1326
+ relation: "precedes",
1327
+ weight: .6
1328
+ }],
1329
+ workflowRule: {
1330
+ patterns: [
1331
+ /v8.*heap/i,
1332
+ /heap.*snapshot/i,
1333
+ /jit/i,
1334
+ /object.*address/i
1335
+ ],
1336
+ priority: 80,
1337
+ tools: [
1338
+ "v8_heap_snapshot_capture",
1339
+ "v8_heap_snapshot_analyze",
1340
+ "v8_object_inspect",
1341
+ "v8_heap_stats"
1342
+ ],
1343
+ hint: "Capture a heap snapshot, analyze it, then inspect interesting objects by address."
1344
+ }
1345
+ };
1346
+ //#endregion
1347
+ export { V8InspectorHandlers, manifest as default };