@jshookmcp/jshook 0.2.8 → 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 (162) hide show
  1. package/README.md +36 -5
  2. package/README.zh.md +36 -5
  3. package/dist/{AntiCheatDetector-S8VRj-dD.mjs → AntiCheatDetector-CqGDXmfc.mjs} +160 -54
  4. package/dist/{CodeInjector-4Z3ngPoX.mjs → CodeInjector-BdjRfNx7.mjs} +5 -5
  5. package/dist/ConsoleMonitor-DykL3IAw.mjs +2269 -0
  6. package/dist/{DarwinAPI-B8hg_yhz.mjs → DarwinAPI-ETyy0xyo.mjs} +1 -1
  7. package/dist/DetailedDataManager-HT49OrvF.mjs +217 -0
  8. package/dist/EventBus-DFKvADm3.mjs +141 -0
  9. package/dist/EvidenceGraphBridge-318Oi0Lf.mjs +153 -0
  10. package/dist/{ExtensionManager-D5-bO9D8.mjs → ExtensionManager-BDMsY2Dz.mjs} +27 -13
  11. package/dist/{FingerprintManager-BVxFJL2-.mjs → FingerprintManager-BN4UQWnX.mjs} +1 -1
  12. package/dist/{HardwareBreakpoint-DK1yjWkV.mjs → HardwareBreakpoint-Cc2AFq1Y.mjs} +3 -3
  13. package/dist/{HeapAnalyzer-CEbo10xU.mjs → HeapAnalyzer-DruMgsgj.mjs} +21 -21
  14. package/dist/HookGeneratorBuilders.core.generators.storage-CTbB4Lcx.mjs +566 -0
  15. package/dist/InstrumentationSession-DLH0vd-z.mjs +244 -0
  16. package/dist/{MemoryController-DdtnBdD4.mjs → MemoryController-CMtviNW_.mjs} +3 -3
  17. package/dist/{MemoryScanSession-RMixN3bX.mjs → MemoryScanSession-ITgb_NMi.mjs} +81 -78
  18. package/dist/{MemoryScanner-QjK4ld0B.mjs → MemoryScanner-CiL7Z3ey.mjs} +50 -21
  19. package/dist/{NativeMemoryManager.impl-CB6gJ0NM.mjs → NativeMemoryManager.impl-D9Lkovvn.mjs} +20 -56
  20. package/dist/{NativeMemoryManager.utils-BML4q1ry.mjs → NativeMemoryManager.utils-BBlAixF5.mjs} +1 -1
  21. package/dist/{PEAnalyzer-CK0xe0Fs.mjs → PEAnalyzer-DMQ44gen.mjs} +16 -16
  22. package/dist/PageController-BPJNqqBN.mjs +431 -0
  23. package/dist/{PointerChainEngine-Cd73qu5b.mjs → PointerChainEngine-K7wN8Z-w.mjs} +10 -7
  24. package/dist/PrerequisiteError-TuyZIs6n.mjs +20 -0
  25. package/dist/ProcessRegistry-zGg12QbE.mjs +74 -0
  26. package/dist/ResponseBuilder-CJXWmWNw.mjs +143 -0
  27. package/dist/ReverseEvidenceGraph-C02-gXOh.mjs +269 -0
  28. package/dist/ScriptManager-ZuWD-0Jg.mjs +3003 -0
  29. package/dist/{Speedhack-CeF0XmEz.mjs → Speedhack-D-z0umeT.mjs} +2 -2
  30. package/dist/{StructureAnalyzer-D4GkMduU.mjs → StructureAnalyzer-Cav5AVSL.mjs} +9 -6
  31. package/dist/ToolCatalog-5OJdMiF0.mjs +582 -0
  32. package/dist/ToolError-jh9whhMd.mjs +15 -0
  33. package/dist/ToolProbe-DbCFGyrg.mjs +45 -0
  34. package/dist/ToolRegistry-B9krbTtI.mjs +180 -0
  35. package/dist/ToolRouter.policy-BGDAGyeH.mjs +344 -0
  36. package/dist/TraceRecorder-B41Z5XBj.mjs +1286 -0
  37. package/dist/{Win32API-Bc0QnQsN.mjs → Win32API-C2kjj0ze.mjs} +19 -13
  38. package/dist/{Win32Debug-DUHt9XUn.mjs → Win32Debug-CKrGOTpo.mjs} +3 -3
  39. package/dist/WorkflowEngine-DJ6M4opp.mjs +569 -0
  40. package/dist/analysis-BHeJW2Nb.mjs +1234 -0
  41. package/dist/antidebug-BRKeyt27.mjs +1081 -0
  42. package/dist/artifactRetention-CPXkUJXp.mjs +598 -0
  43. package/dist/artifacts-DkfosXH3.mjs +59 -0
  44. package/dist/authorization-schema-DRqyJMSk.mjs +31 -0
  45. package/dist/betterSqlite3-DLSBZodi.mjs +74 -0
  46. package/dist/binary-instrument--V3MAhJ4.mjs +971 -0
  47. package/dist/bind-helpers-ClV34xdn.mjs +42 -0
  48. package/dist/boringssl-inspector-Bo_LOLaS.mjs +180 -0
  49. package/dist/browser-Dx3_S2cG.mjs +4369 -0
  50. package/dist/capabilities-CcHlvWgK.mjs +33 -0
  51. package/dist/concurrency-Drev_Vz9.mjs +41 -0
  52. package/dist/{constants-CCvsN80K.mjs → constants-CDZLOoVv.mjs} +105 -48
  53. package/dist/coordination-DgItD9DL.mjs +259 -0
  54. package/dist/debugger-RS3RSAqs.mjs +1288 -0
  55. package/dist/definitions-BEoYofW5.mjs +47 -0
  56. package/dist/definitions-BRaefg3u.mjs +365 -0
  57. package/dist/definitions-BbkvZkiv.mjs +96 -0
  58. package/dist/definitions-BtWSHJ3o.mjs +17 -0
  59. package/dist/definitions-C1gCHO0i.mjs +43 -0
  60. package/dist/definitions-CDOg_b-l.mjs +138 -0
  61. package/dist/definitions-CVPD9hzZ.mjs +54 -0
  62. package/dist/definitions-Cea8Lgl7.mjs +94 -0
  63. package/dist/definitions-DAgIyjxM.mjs +10 -0
  64. package/dist/definitions-DJA27nsL.mjs +66 -0
  65. package/dist/definitions-DKPFU3LW.mjs +25 -0
  66. package/dist/definitions-DPRpZQ96.mjs +47 -0
  67. package/dist/definitions-DUE5gmdn.mjs +18 -0
  68. package/dist/definitions-DYVjOtxa.mjs +26 -0
  69. package/dist/definitions-DcYLVLCo.mjs +37 -0
  70. package/dist/definitions-Pp5LI2H4.mjs +27 -0
  71. package/dist/definitions-j9KdHVNR.mjs +14 -0
  72. package/dist/definitions-uzkjBwa7.mjs +258 -0
  73. package/dist/definitions-va-AnLuQ.mjs +28 -0
  74. package/dist/encoding-DJeqHmpd.mjs +1079 -0
  75. package/dist/evidence-graph-bridge-DcYizFk2.mjs +136 -0
  76. package/dist/{factory-CibqTNC8.mjs → factory-C90tBff6.mjs} +41 -56
  77. package/dist/flat-target-session-Dgax2Cy3.mjs +29 -0
  78. package/dist/graphql-CoHrhweh.mjs +1197 -0
  79. package/dist/handlers-4jmR0nMs.mjs +898 -0
  80. package/dist/handlers-BAHPxcch.mjs +789 -0
  81. package/dist/handlers-BOs9b907.mjs +2600 -0
  82. package/dist/handlers-BWXEy6ef.mjs +917 -0
  83. package/dist/handlers-Bndn6QvE.mjs +111 -0
  84. package/dist/handlers-BqC4bD4s.mjs +681 -0
  85. package/dist/handlers-BtYq60bM2.mjs +276 -0
  86. package/dist/handlers-BzgcB4iv.mjs +799 -0
  87. package/dist/handlers-CRyRWj2b.mjs +859 -0
  88. package/dist/handlers-CVv2H1uq.mjs +592 -0
  89. package/dist/handlers-Dl5a7JS4.mjs +572 -0
  90. package/dist/handlers-Dx2d7jt7.mjs +2537 -0
  91. package/dist/handlers-Dz9PYsCa.mjs +2805 -0
  92. package/dist/handlers-HujRKC3b.mjs +661 -0
  93. package/dist/handlers.impl-XWXkQfyi.mjs +807 -0
  94. package/dist/hooks-B1B8NRHL.mjs +898 -0
  95. package/dist/index.mjs +491 -259
  96. package/dist/{logger-BmWzC2lM.mjs → logger-Dh_xb7_2.mjs} +14 -6
  97. package/dist/maintenance-PRMkLVRW.mjs +835 -0
  98. package/dist/manifest-67Bok-Si.mjs +58 -0
  99. package/dist/manifest-6lNTMZAB2.mjs +87 -0
  100. package/dist/manifest-B2duEHiH.mjs +90 -0
  101. package/dist/manifest-B6EY9Vm8.mjs +57 -0
  102. package/dist/manifest-B6nKSbyY.mjs +95 -0
  103. package/dist/manifest-BL8AQNPF.mjs +106 -0
  104. package/dist/manifest-BSZvJJmV.mjs +47 -0
  105. package/dist/manifest-BU7qzUyX.mjs +418 -0
  106. package/dist/manifest-Bl62e8WK.mjs +49 -0
  107. package/dist/manifest-Bo5cXjdt.mjs +82 -0
  108. package/dist/manifest-BpS4gtUK.mjs +1347 -0
  109. package/dist/manifest-Bv65_e2W.mjs +101 -0
  110. package/dist/manifest-BytNIF4Z.mjs +117 -0
  111. package/dist/manifest-C-xtsjS3.mjs +81 -0
  112. package/dist/manifest-CDYl7OhA.mjs +66 -0
  113. package/dist/manifest-CRZ3xmkD.mjs +61 -0
  114. package/dist/manifest-CoW6u4Tp.mjs +132 -0
  115. package/dist/manifest-Cq5zN_8A.mjs +50 -0
  116. package/dist/manifest-D7YZM_2e.mjs +194 -0
  117. package/dist/manifest-DE_VrAeQ.mjs +314 -0
  118. package/dist/manifest-DGsXSCpT.mjs +39 -0
  119. package/dist/manifest-DJ2vfEuW.mjs +156 -0
  120. package/dist/manifest-DPXDYhEu.mjs +80 -0
  121. package/dist/manifest-Dd4fQb0a.mjs +322 -0
  122. package/dist/manifest-Deq6opGg.mjs +223 -0
  123. package/dist/manifest-DfJTafJK.mjs +37 -0
  124. package/dist/manifest-DgOdgN_j.mjs +50 -0
  125. package/dist/manifest-DlbMW4v4.mjs +47 -0
  126. package/dist/manifest-DmVfbH0w.mjs +374 -0
  127. package/dist/manifest-Dog6Ddjr.mjs +109 -0
  128. package/dist/manifest-DvgU5FWb.mjs +58 -0
  129. package/dist/manifest-HsfDBs7j.mjs +50 -0
  130. package/dist/manifest-I8oQHvCG.mjs +186 -0
  131. package/dist/manifest-NvH_a-av.mjs +786 -0
  132. package/dist/manifest-cEJU1v0Z.mjs +129 -0
  133. package/dist/manifest-wOl5XLB12.mjs +112 -0
  134. package/dist/modules-tZozf0LQ.mjs +10635 -0
  135. package/dist/mojo-ipc-DXNEXEqb.mjs +640 -0
  136. package/dist/network-CPVvwvFg.mjs +3852 -0
  137. package/dist/{artifacts-BbdOMET5.mjs → outputPaths-um7lCRY3.mjs} +219 -216
  138. package/dist/parse-args-B4cY5Vx5.mjs +39 -0
  139. package/dist/platform-CYeFoTWp.mjs +2161 -0
  140. package/dist/process-BTbgcVc6.mjs +1306 -0
  141. package/dist/proxy-r8YN6nP1.mjs +192 -0
  142. package/dist/registry-Bl8ZQW61.mjs +34 -0
  143. package/dist/response-CWhh2aLo.mjs +34 -0
  144. package/dist/server/plugin-api.mjs +2 -2
  145. package/dist/shared-state-board-BoZnSoj-.mjs +586 -0
  146. package/dist/sourcemap-BIDHUVXy.mjs +934 -0
  147. package/dist/ssrf-policy-Dsqd-DTX.mjs +166 -0
  148. package/dist/streaming-Dal6utPp.mjs +725 -0
  149. package/dist/tool-builder-BHJp32mV.mjs +186 -0
  150. package/dist/transform-DRVgGG90.mjs +1011 -0
  151. package/dist/types-Bx92KJfT.mjs +4 -0
  152. package/dist/wasm-BYx5UOeG.mjs +1044 -0
  153. package/dist/webcrack-Be0_FccV.mjs +747 -0
  154. package/dist/workflow-BpuKEtvn.mjs +725 -0
  155. package/package.json +82 -49
  156. package/dist/ExtensionManager-CPTJhHFg.mjs +0 -2
  157. package/dist/ToolCatalog-Bq4V2sbJ.mjs +0 -67201
  158. package/dist/{CacheAdapters-CzFNpD9a.mjs → CacheAdapters-jJFy20G-.mjs} +0 -0
  159. package/dist/{StealthVerifier-BzBCFiwx.mjs → StealthVerifier-BWmPgQsv.mjs} +0 -0
  160. package/dist/{VersionDetector-CNXcvD46.mjs → VersionDetector-K3V4vGsw.mjs} +0 -0
  161. package/dist/{formatAddress-ChCSIRWT.mjs → formatAddress-nnMvEohD.mjs} +0 -0
  162. package/dist/{types-BBjOqye-.mjs → types-DDBWs9UP.mjs} +1 -1
@@ -1,7 +1,7 @@
1
- import { Dt as POINTER_CHAIN_SCAN_CHUNK_SIZE, Et as POINTER_CHAIN_MAX_RESULTS, Tt as POINTER_CHAIN_MAX_OFFSET, wt as POINTER_CHAIN_MAX_DEPTH } from "./constants-CCvsN80K.mjs";
2
- import { t as nativeMemoryManager } from "./NativeMemoryManager.impl-CB6gJ0NM.mjs";
3
- import { t as createPlatformProvider } from "./factory-CibqTNC8.mjs";
4
- import { n as parseAddress, t as formatAddress } from "./formatAddress-ChCSIRWT.mjs";
1
+ import { Qt as POINTER_CHAIN_SCAN_CHUNK_SIZE, Xt as POINTER_CHAIN_MAX_OFFSET, Yt as POINTER_CHAIN_MAX_DEPTH, Zt as POINTER_CHAIN_MAX_RESULTS } from "./constants-CDZLOoVv.mjs";
2
+ import { t as createPlatformProvider } from "./factory-C90tBff6.mjs";
3
+ import { t as nativeMemoryManager } from "./NativeMemoryManager.impl-D9Lkovvn.mjs";
4
+ import { n as parseAddress, t as formatAddress } from "./formatAddress-nnMvEohD.mjs";
5
5
  import { randomUUID } from "node:crypto";
6
6
  //#region src/native/PointerChainEngine.ts
7
7
  /**
@@ -15,10 +15,13 @@ import { randomUUID } from "node:crypto";
15
15
  * @module PointerChainEngine
16
16
  */
17
17
  var PointerChainEngine = class {
18
- _provider = null;
18
+ providerCache = null;
19
19
  get provider() {
20
- if (!this._provider) this._provider = createPlatformProvider();
21
- return this._provider;
20
+ if (!this.providerCache) this.providerCache = createPlatformProvider();
21
+ return this.providerCache;
22
+ }
23
+ set provider(value) {
24
+ this.providerCache = value;
22
25
  }
23
26
  /**
24
27
  * Multi-level BFS pointer scan.
@@ -0,0 +1,20 @@
1
+ import { t as ToolError } from "./ToolError-jh9whhMd.mjs";
2
+ //#region src/errors/PrerequisiteError.ts
3
+ /**
4
+ * Thrown when a tool's prerequisite is not met (e.g. debugger not enabled,
5
+ * browser not connected, profiling not started).
6
+ *
7
+ * The MCP server catches this and returns a graceful
8
+ * `{ success: false, message }` response instead of `isError: true`.
9
+ *
10
+ * Extends ToolError with code 'PREREQUISITE' for unified error classification.
11
+ * Constructor signature unchanged — backward-compatible with all existing callers.
12
+ */
13
+ var PrerequisiteError = class extends ToolError {
14
+ constructor(message) {
15
+ super("PREREQUISITE", message);
16
+ this.name = "PrerequisiteError";
17
+ }
18
+ };
19
+ //#endregion
20
+ export { PrerequisiteError as t };
@@ -0,0 +1,74 @@
1
+ import { t as logger } from "./logger-Dh_xb7_2.mjs";
2
+ import { G as EXTERNAL_TOOL_FORCE_KILL_GRACE_MS } from "./constants-CDZLOoVv.mjs";
3
+ //#region src/utils/ProcessRegistry.ts
4
+ /**
5
+ * Global singleton registry to track and safely terminate orphaned child
6
+ * processes and worker threads upon server shutdown.
7
+ */
8
+ var ProcessRegistrySingleton = class {
9
+ processes = /* @__PURE__ */ new Set();
10
+ /**
11
+ * Register a ChildProcess or Worker for automatic cleanup on shutdown.
12
+ */
13
+ register(proc) {
14
+ if (!proc) return;
15
+ this.processes.add(proc);
16
+ if ("kill" in proc) proc.once("close", () => this.unregister(proc));
17
+ else if ("terminate" in proc) {
18
+ if (typeof proc.once === "function") proc.once("exit", () => this.unregister(proc));
19
+ else if (typeof proc.on === "function") proc.on("exit", () => this.unregister(proc));
20
+ }
21
+ }
22
+ /**
23
+ * Unregister a process/worker.
24
+ */
25
+ unregister(proc) {
26
+ if (!proc) return;
27
+ this.processes.delete(proc);
28
+ }
29
+ /**
30
+ * Terminate all tracked processes and workers.
31
+ * Sends SIGTERM, then after a grace period sends SIGKILL.
32
+ */
33
+ async terminateAll() {
34
+ if (this.processes.size === 0) return;
35
+ logger.debug(`[ProcessRegistry] Attempting to terminate ${this.processes.size} active processes/workers...`);
36
+ const terminationPromises = [];
37
+ for (const proc of this.processes) if ("terminate" in proc) terminationPromises.push(proc.terminate().then(() => {
38
+ this.processes.delete(proc);
39
+ }).catch((err) => {
40
+ logger.warn(`[ProcessRegistry] Error terminating worker: ${err.message}`);
41
+ }));
42
+ else if ("kill" in proc) terminationPromises.push(new Promise((resolve) => {
43
+ if (proc.killed || proc.exitCode !== null || proc.signalCode !== null) {
44
+ this.processes.delete(proc);
45
+ return resolve();
46
+ }
47
+ proc.kill("SIGTERM");
48
+ let settled = false;
49
+ const handleExit = () => {
50
+ if (settled) return;
51
+ settled = true;
52
+ this.processes.delete(proc);
53
+ resolve();
54
+ };
55
+ proc.once("exit", handleExit);
56
+ proc.once("close", handleExit);
57
+ setTimeout(() => {
58
+ if (!settled && !proc.killed && proc.exitCode === null) {
59
+ logger.debug(`[ProcessRegistry] Force killing child process PID ${proc.pid}`);
60
+ try {
61
+ proc.kill("SIGKILL");
62
+ } catch {}
63
+ handleExit();
64
+ }
65
+ }, EXTERNAL_TOOL_FORCE_KILL_GRACE_MS).unref();
66
+ }));
67
+ await Promise.race([Promise.all(terminationPromises), new Promise((resolve) => setTimeout(resolve, EXTERNAL_TOOL_FORCE_KILL_GRACE_MS + 1e3).unref())]);
68
+ this.processes.clear();
69
+ logger.debug(`[ProcessRegistry] Termination sweep complete.`);
70
+ }
71
+ };
72
+ const ProcessRegistry = new ProcessRegistrySingleton();
73
+ //#endregion
74
+ export { ProcessRegistry as t };
@@ -0,0 +1,143 @@
1
+ //#region src/server/domains/shared/ResponseBuilder.ts
2
+ /**
3
+ * Fluent builder for MCP tool responses.
4
+ *
5
+ * Replaces the verbose 14-line deep-nesting pattern:
6
+ * ```
7
+ * return { content: [{ type: 'text', text: JSON.stringify({...}, null, 2) }] };
8
+ * ```
9
+ *
10
+ * With a chainable API:
11
+ * ```
12
+ * return R.ok().set('driver', 'chrome').json();
13
+ * ```
14
+ */
15
+ var ResponseBuilder = class {
16
+ payload = {};
17
+ hasMcpError = false;
18
+ additionalContent = [];
19
+ useStructuredContent = false;
20
+ /** Mark as success (sets `success: true`). */
21
+ ok() {
22
+ this.payload.success = true;
23
+ return this;
24
+ }
25
+ /** Mark as failure (sets `success: false, error: <message>, message: <message>`). */
26
+ fail(error) {
27
+ this.payload.success = false;
28
+ const msg = error instanceof Error ? error.message : String(error);
29
+ this.payload.error = msg;
30
+ this.payload.message = msg;
31
+ return this;
32
+ }
33
+ /** Set a single key-value pair. */
34
+ set(key, value) {
35
+ this.payload[key] = value;
36
+ return this;
37
+ }
38
+ /** Merge multiple fields at once. */
39
+ merge(fields) {
40
+ Object.assign(this.payload, fields);
41
+ return this;
42
+ }
43
+ /** Set MCP-level `isError: true` on the response envelope. */
44
+ mcpError() {
45
+ this.hasMcpError = true;
46
+ return this;
47
+ }
48
+ /** Push an image block to the final response. */
49
+ image(base64, mimeType) {
50
+ this.additionalContent.push({
51
+ type: "image",
52
+ data: base64,
53
+ mimeType
54
+ });
55
+ return this;
56
+ }
57
+ /** Push an embedded resource block to the final response. */
58
+ embeddedResource(uri, text, mimeType = "text/plain") {
59
+ this.additionalContent.push({
60
+ type: "resource",
61
+ resource: {
62
+ uri,
63
+ text,
64
+ mimeType
65
+ }
66
+ });
67
+ return this;
68
+ }
69
+ /** Send output payload natively as `structuredContent` in the MCP envelope instead of stringifying inside text block. */
70
+ structured() {
71
+ this.useStructuredContent = true;
72
+ return this;
73
+ }
74
+ /**
75
+ * Build the ToolResponse. Handles text vs structured plus extra blocks.
76
+ * Optionally merges extra fields before building.
77
+ */
78
+ json(fields) {
79
+ if (fields) this.merge(fields);
80
+ return {
81
+ content: [{
82
+ type: "text",
83
+ text: JSON.stringify(this.payload, null, 2)
84
+ }, ...this.additionalContent],
85
+ ...this.hasMcpError ? { isError: true } : {},
86
+ ...this.useStructuredContent ? { structuredContent: this.payload } : {}
87
+ };
88
+ }
89
+ /** Alias for json(). */
90
+ build(fields) {
91
+ return this.json(fields);
92
+ }
93
+ /** Build a ToolResponse from an arbitrary value (no success/error wrapper). */
94
+ static raw(data) {
95
+ return { content: [{
96
+ type: "text",
97
+ text: JSON.stringify(data, null, 2)
98
+ }] };
99
+ }
100
+ /**
101
+ * Build a ToolResponse from a plain text string.
102
+ * Setting `isError = true` returns a soft error for macro compatibility
103
+ * without triggering a JSON-RPC ErrorCode.
104
+ */
105
+ static text(text, isError = false) {
106
+ return {
107
+ content: [{
108
+ type: "text",
109
+ text
110
+ }],
111
+ ...isError ? { isError: true } : {}
112
+ };
113
+ }
114
+ /**
115
+ * Safely extract and parse JSON from an MCP ToolResponse.
116
+ * Useful for consuming tool results in workflow/orchestration logic.
117
+ */
118
+ static parse(response) {
119
+ if (!response.content || response.content.length === 0) throw new Error("ToolResponse has no content");
120
+ const textBlock = response.content.find((c) => c.type === "text");
121
+ if (!textBlock || !("text" in textBlock)) throw new Error("ToolResponse has no text content block");
122
+ try {
123
+ return JSON.parse(textBlock.text);
124
+ } catch (e) {
125
+ throw new Error(`Failed to parse tool result as JSON: ${String(e)}\nRaw text: ${textBlock.text.substring(0, 500)}`, { cause: e });
126
+ }
127
+ }
128
+ };
129
+ /** Shorthand factory — the primary entry point for building responses. */
130
+ const R = {
131
+ /** Start a success response (`{ success: true, ... }`). */
132
+ ok: () => new ResponseBuilder().ok(),
133
+ /** Start a failure response (`{ success: false, error: "..." }`). */
134
+ fail: (error) => new ResponseBuilder().fail(error),
135
+ /** Wrap an existing object as-is (no success/error wrapper). */
136
+ raw: (data) => ResponseBuilder.raw(data),
137
+ /** Wrap a plain text string. */
138
+ text: (text, isError = false) => ResponseBuilder.text(text, isError),
139
+ /** Parse a response back into an object. */
140
+ parse: (response) => ResponseBuilder.parse(response)
141
+ };
142
+ //#endregion
143
+ export { R as t };
@@ -0,0 +1,269 @@
1
+ import { t as __exportAll } from "./chunk-CjcI7cDX.mjs";
2
+ //#region src/server/evidence/ReverseEvidenceGraph.ts
3
+ var ReverseEvidenceGraph_exports = /* @__PURE__ */ __exportAll({ ReverseEvidenceGraph: () => ReverseEvidenceGraph });
4
+ let nextId = 1;
5
+ function generateId(prefix) {
6
+ return `${prefix}-${nextId++}`;
7
+ }
8
+ var ReverseEvidenceGraph = class {
9
+ nodes = /* @__PURE__ */ new Map();
10
+ edges = /* @__PURE__ */ new Map();
11
+ eventBus;
12
+ isDirty = false;
13
+ mutationSeq = 0;
14
+ lastPersistedSeq = 0;
15
+ persistNotifier;
16
+ setEventBus(eventBus) {
17
+ this.eventBus = eventBus;
18
+ }
19
+ setPersistNotifier(notify) {
20
+ this.persistNotifier = notify;
21
+ }
22
+ markDirty() {
23
+ this.isDirty = true;
24
+ this.mutationSeq++;
25
+ this.persistNotifier?.();
26
+ }
27
+ commit() {
28
+ if (this.isDirty && this.eventBus) {
29
+ this.isDirty = false;
30
+ this.eventBus.emit("evidence:updated", {
31
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
32
+ reason: "Tool execution committed changes"
33
+ });
34
+ }
35
+ }
36
+ /** Add a node to the graph. */
37
+ addNode(type, label, metadata = {}) {
38
+ const node = {
39
+ id: generateId(type),
40
+ type,
41
+ label,
42
+ metadata,
43
+ createdAt: Date.now()
44
+ };
45
+ this.nodes.set(node.id, node);
46
+ this.markDirty();
47
+ return node;
48
+ }
49
+ /** Add a directed edge between two nodes. */
50
+ addEdge(sourceId, targetId, type, metadata) {
51
+ if (!this.nodes.has(sourceId)) throw new Error(`Source node "${sourceId}" not found`);
52
+ if (!this.nodes.has(targetId)) throw new Error(`Target node "${targetId}" not found`);
53
+ const edge = {
54
+ id: generateId("edge"),
55
+ source: sourceId,
56
+ target: targetId,
57
+ type,
58
+ metadata
59
+ };
60
+ this.edges.set(edge.id, edge);
61
+ this.markDirty();
62
+ return edge;
63
+ }
64
+ /** Get a node by ID. */
65
+ getNode(id) {
66
+ return this.nodes.get(id);
67
+ }
68
+ /** Remove a node and all connected edges. */
69
+ removeNode(id) {
70
+ if (!this.nodes.has(id)) return false;
71
+ this.nodes.delete(id);
72
+ for (const [edgeId, edge] of this.edges) if (edge.source === id || edge.target === id) this.edges.delete(edgeId);
73
+ this.markDirty();
74
+ return true;
75
+ }
76
+ /** Get all edges originating from a node. */
77
+ getEdgesFrom(nodeId) {
78
+ return [...this.edges.values()].filter((e) => e.source === nodeId);
79
+ }
80
+ /** Get all edges pointing to a node. */
81
+ getEdgesTo(nodeId) {
82
+ return [...this.edges.values()].filter((e) => e.target === nodeId);
83
+ }
84
+ /** Get total node count. */
85
+ get nodeCount() {
86
+ return this.nodes.size;
87
+ }
88
+ /** Get total edge count. */
89
+ get edgeCount() {
90
+ return this.edges.size;
91
+ }
92
+ /**
93
+ * BFS traversal from a node, following edges in the given direction.
94
+ * Returns all reachable nodes (including the start node).
95
+ */
96
+ getEvidenceChain(nodeId, direction = "forward") {
97
+ if (!this.nodes.get(nodeId)) return [];
98
+ const visited = /* @__PURE__ */ new Set();
99
+ const queue = [nodeId];
100
+ const result = [];
101
+ while (queue.length > 0) {
102
+ const current = queue.shift();
103
+ if (visited.has(current)) continue;
104
+ visited.add(current);
105
+ const node = this.nodes.get(current);
106
+ if (node) result.push(node);
107
+ const connectedEdges = direction === "forward" ? this.getEdgesFrom(current) : this.getEdgesTo(current);
108
+ for (const edge of connectedEdges) {
109
+ const nextNodeId = direction === "forward" ? edge.target : edge.source;
110
+ if (!visited.has(nextNodeId)) queue.push(nextNodeId);
111
+ }
112
+ }
113
+ return result;
114
+ }
115
+ /**
116
+ * Find all nodes associated with a URL.
117
+ * Searches request nodes by URL metadata, then returns connected subgraph.
118
+ */
119
+ queryByUrl(url) {
120
+ const matchingNodes = [...this.nodes.values()].filter((n) => {
121
+ if (n.type === "request" && typeof n.metadata.url === "string") return n.metadata.url.includes(url);
122
+ if (typeof n.metadata.url === "string") return n.metadata.url.includes(url);
123
+ return false;
124
+ });
125
+ const allNodes = /* @__PURE__ */ new Set();
126
+ for (const node of matchingNodes) {
127
+ for (const n of this.getEvidenceChain(node.id, "forward")) allNodes.add(n.id);
128
+ for (const n of this.getEvidenceChain(node.id, "backward")) allNodes.add(n.id);
129
+ }
130
+ return [...allNodes].map((id) => this.nodes.get(id)).filter(Boolean);
131
+ }
132
+ /**
133
+ * Find all nodes associated with a function name.
134
+ * Searches function nodes, then returns connected subgraph.
135
+ */
136
+ queryByFunction(name) {
137
+ const matchingNodes = [...this.nodes.values()].filter((n) => {
138
+ if (n.type === "function" && typeof n.metadata.functionName === "string") return n.metadata.functionName.includes(name);
139
+ if (n.label.includes(name) && (n.type === "function" || n.type === "breakpoint-hook")) return true;
140
+ return false;
141
+ });
142
+ const allNodes = /* @__PURE__ */ new Set();
143
+ for (const node of matchingNodes) {
144
+ for (const n of this.getEvidenceChain(node.id, "forward")) allNodes.add(n.id);
145
+ for (const n of this.getEvidenceChain(node.id, "backward")) allNodes.add(n.id);
146
+ }
147
+ return [...allNodes].map((id) => this.nodes.get(id)).filter(Boolean);
148
+ }
149
+ /**
150
+ * Find all nodes associated with a script ID.
151
+ * Searches script nodes by scriptId metadata, then returns connected subgraph.
152
+ */
153
+ queryByScriptId(scriptId) {
154
+ const matchingNodes = [...this.nodes.values()].filter((n) => {
155
+ if (n.type === "script" && n.metadata.scriptId === scriptId) return true;
156
+ return false;
157
+ });
158
+ const allNodes = /* @__PURE__ */ new Set();
159
+ for (const node of matchingNodes) {
160
+ for (const n of this.getEvidenceChain(node.id, "forward")) allNodes.add(n.id);
161
+ for (const n of this.getEvidenceChain(node.id, "backward")) allNodes.add(n.id);
162
+ }
163
+ return [...allNodes].map((id) => this.nodes.get(id)).filter(Boolean);
164
+ }
165
+ /** Export the full graph as a JSON snapshot. */
166
+ exportJson() {
167
+ return {
168
+ version: 1,
169
+ nodes: [...this.nodes.values()],
170
+ edges: [...this.edges.values()],
171
+ exportedAt: (/* @__PURE__ */ new Date()).toISOString()
172
+ };
173
+ }
174
+ /** Export the graph as a readable Markdown report. */
175
+ exportMarkdown() {
176
+ const lines = [];
177
+ lines.push("# Reverse Evidence Graph Report");
178
+ lines.push("");
179
+ lines.push(`**Exported:** ${(/* @__PURE__ */ new Date()).toISOString()}`);
180
+ lines.push(`**Nodes:** ${this.nodes.size} | **Edges:** ${this.edges.size}`);
181
+ lines.push("");
182
+ const byType = /* @__PURE__ */ new Map();
183
+ for (const node of this.nodes.values()) {
184
+ const list = byType.get(node.type) ?? [];
185
+ list.push(node);
186
+ byType.set(node.type, list);
187
+ }
188
+ for (const type of [
189
+ "request",
190
+ "initiator-stack",
191
+ "script",
192
+ "function",
193
+ "breakpoint-hook",
194
+ "captured-data",
195
+ "replay-artifact",
196
+ "v8-heap-object",
197
+ "v8-hidden-class",
198
+ "network-request",
199
+ "network-response",
200
+ "canvas-scene-node",
201
+ "canvas-render-node",
202
+ "skia-draw-call",
203
+ "syscall-event",
204
+ "mojo-message",
205
+ "mojo-interface",
206
+ "binary-symbol",
207
+ "binary-function",
208
+ "binary-module",
209
+ "proto-message",
210
+ "proto-state"
211
+ ]) {
212
+ const nodes = byType.get(type);
213
+ if (!nodes || nodes.length === 0) continue;
214
+ lines.push(`## ${type} (${nodes.length})`);
215
+ lines.push("");
216
+ for (const node of nodes) {
217
+ lines.push(`### ${node.label}`);
218
+ lines.push(`- **ID:** \`${node.id}\``);
219
+ lines.push(`- **Created:** ${new Date(node.createdAt).toISOString()}`);
220
+ const metaKeys = Object.keys(node.metadata);
221
+ if (metaKeys.length > 0) for (const key of metaKeys) {
222
+ const val = node.metadata[key];
223
+ const display = typeof val === "string" ? val : JSON.stringify(val);
224
+ lines.push(`- **${key}:** ${display}`);
225
+ }
226
+ const outEdges = this.getEdgesFrom(node.id);
227
+ const inEdges = this.getEdgesTo(node.id);
228
+ if (outEdges.length > 0) lines.push(`- **→ Out:** ${outEdges.map((e) => `${e.type} → \`${e.target}\``).join(", ")}`);
229
+ if (inEdges.length > 0) lines.push(`- **← In:** ${inEdges.map((e) => `\`${e.source}\` ${e.type} →`).join(", ")}`);
230
+ lines.push("");
231
+ }
232
+ }
233
+ return lines.join("\n");
234
+ }
235
+ getSnapshotSeq() {
236
+ return this.mutationSeq;
237
+ }
238
+ getLastPersistedSeq() {
239
+ return this.lastPersistedSeq;
240
+ }
241
+ markPersisted() {
242
+ this.lastPersistedSeq = this.mutationSeq;
243
+ }
244
+ isPersistDirty() {
245
+ return this.mutationSeq !== this.lastPersistedSeq;
246
+ }
247
+ exportSnapshot() {
248
+ return {
249
+ schemaVersion: 1,
250
+ savedAt: (/* @__PURE__ */ new Date()).toISOString(),
251
+ graph: this.exportJson()
252
+ };
253
+ }
254
+ restoreSnapshot(data) {
255
+ if (!data || typeof data !== "object") return;
256
+ const snapshot = data;
257
+ if (snapshot.schemaVersion !== 1 || !snapshot.graph) return;
258
+ const { nodes, edges } = snapshot.graph;
259
+ this.nodes.clear();
260
+ this.edges.clear();
261
+ for (const node of nodes) this.nodes.set(node.id, node);
262
+ for (const edge of edges) this.edges.set(edge.id, edge);
263
+ this.mutationSeq = nodes.length + edges.length;
264
+ this.lastPersistedSeq = this.mutationSeq;
265
+ this.isDirty = false;
266
+ }
267
+ };
268
+ //#endregion
269
+ export { ReverseEvidenceGraph_exports as t };