@jshookmcp/jshook 0.2.2 → 0.2.3

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 (130) hide show
  1. package/LICENSE +661 -661
  2. package/README.md +4 -4
  3. package/README.zh.md +3 -3
  4. package/dist/native/scripts/linux/enum-windows.sh +12 -12
  5. package/dist/native/scripts/macos/enum-windows.applescript +22 -22
  6. package/dist/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
  7. package/dist/native/scripts/windows/enum-windows.ps1 +44 -44
  8. package/dist/native/scripts/windows/inject-dll.ps1 +21 -21
  9. package/dist/src/modules/analyzer/CodeAnalyzer.d.ts +1 -1
  10. package/dist/src/modules/analyzer/CodeAnalyzer.js +1 -1
  11. package/dist/src/modules/browser/BrowserDiscovery.d.ts +6 -5
  12. package/dist/src/modules/browser/BrowserDiscovery.js +1 -1
  13. package/dist/src/modules/browser/BrowserModeManager.d.ts +1 -1
  14. package/dist/src/modules/browser/BrowserModeManager.js +1 -1
  15. package/dist/src/modules/browser/UnifiedBrowserManager.js +1 -1
  16. package/dist/src/modules/captcha/AICaptchaDetector.d.ts +22 -22
  17. package/dist/src/modules/captcha/AICaptchaDetector.js +75 -75
  18. package/dist/src/modules/captcha/CaptchaDetector.d.ts +31 -17
  19. package/dist/src/modules/captcha/CaptchaDetector.js +1 -1
  20. package/dist/src/modules/collector/CodeCache.d.ts +2 -2
  21. package/dist/src/modules/collector/CodeCollector.d.ts +12 -9
  22. package/dist/src/modules/collector/CodeCollector.js +1 -1
  23. package/dist/src/modules/collector/DOMInspector.d.ts +3 -2
  24. package/dist/src/modules/collector/DOMInspector.js +1 -1
  25. package/dist/src/modules/crypto/CryptoDetector.d.ts +1 -1
  26. package/dist/src/modules/crypto/CryptoDetector.js +1 -1
  27. package/dist/src/modules/debugger/ScriptManager.impl.extract-function-tree.js +1 -1
  28. package/dist/src/modules/deobfuscator/Deobfuscator.d.ts +1 -1
  29. package/dist/src/modules/deobfuscator/Deobfuscator.js +1 -1
  30. package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.d.ts +1 -1
  31. package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.js +2 -2
  32. package/dist/src/modules/deobfuscator/PackerDeobfuscator.js +1 -1
  33. package/dist/src/modules/deobfuscator/VMDeobfuscator.d.ts +1 -1
  34. package/dist/src/modules/deobfuscator/VMDeobfuscator.js +82 -82
  35. package/dist/src/modules/emulator/AIEnvironmentAnalyzer.js +1 -1
  36. package/dist/src/modules/external/ExternalToolRunner.d.ts +1 -1
  37. package/dist/src/modules/external/ExternalToolRunner.js +1 -1
  38. package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.compose.js +5 -5
  39. package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.network.js +311 -311
  40. package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.runtime.js +410 -410
  41. package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.storage.js +122 -122
  42. package/dist/src/modules/monitor/ConsoleMonitor.impl.core.dynamic.js +194 -194
  43. package/dist/src/modules/monitor/PlaywrightNetworkMonitor.js +62 -62
  44. package/dist/src/modules/process/LinuxProcessManager.js +2 -2
  45. package/dist/src/modules/process/MacProcessManager.js +26 -26
  46. package/dist/src/modules/process/ProcessManager.impl.js +1 -1
  47. package/dist/src/modules/process/memory/availability.js +49 -49
  48. package/dist/src/modules/process/memory/injector.js +185 -185
  49. package/dist/src/modules/process/memory/reader.js +50 -50
  50. package/dist/src/modules/process/memory/regions.dump.js +51 -51
  51. package/dist/src/modules/process/memory/regions.enumerate.js +107 -107
  52. package/dist/src/modules/process/memory/regions.modules.js +80 -80
  53. package/dist/src/modules/process/memory/regions.protection.js +106 -106
  54. package/dist/src/modules/process/memory/scanner.darwin.js +41 -41
  55. package/dist/src/modules/process/memory/scanner.windows.js +124 -124
  56. package/dist/src/modules/process/memory/writer.js +54 -54
  57. package/dist/src/modules/security/ExecutionSandbox.js +44 -44
  58. package/dist/src/modules/stealth/StealthScripts.d.ts +3 -2
  59. package/dist/src/modules/stealth/StealthScripts.js +35 -1
  60. package/dist/src/modules/stealth/StealthVerifier.d.ts +1 -1
  61. package/dist/src/modules/stealth/StealthVerifier.js +1 -1
  62. package/dist/src/modules/trace/TraceDB.js +63 -63
  63. package/dist/src/native/CodeInjector.js +1 -1
  64. package/dist/src/native/HardwareBreakpoint.js +1 -1
  65. package/dist/src/server/MCPServer.js +1 -0
  66. package/dist/src/server/MCPServer.search.helpers.js +1 -1
  67. package/dist/src/server/MCPServer.tools.js +1 -1
  68. package/dist/src/server/ToolCallContextGuard.d.ts +5 -0
  69. package/dist/src/server/ToolCallContextGuard.js +77 -0
  70. package/dist/src/server/ToolRouter.d.ts +1 -1
  71. package/dist/src/server/ToolRouter.js +2 -2
  72. package/dist/src/server/domains/analysis/handlers.impl.d.ts +8 -8
  73. package/dist/src/server/domains/analysis/handlers.impl.js +8 -8
  74. package/dist/src/server/domains/analysis/handlers.web-tools.js +2 -2
  75. package/dist/src/server/domains/browser/definitions.tools.page-core.js +59 -59
  76. package/dist/src/server/domains/browser/definitions.tools.runtime.js +41 -41
  77. package/dist/src/server/domains/browser/definitions.tools.security.js +114 -114
  78. package/dist/src/server/domains/browser/handlers/facade-initializer.d.ts +3 -3
  79. package/dist/src/server/domains/browser/handlers/facade-initializer.js +3 -3
  80. package/dist/src/server/domains/browser/handlers/framework-state.js +210 -0
  81. package/dist/src/server/domains/browser/handlers/stealth-injection.js +8 -2
  82. package/dist/src/server/domains/browser/handlers.impl.d.ts +15 -11
  83. package/dist/src/server/domains/browser/handlers.impl.js +4 -4
  84. package/dist/src/server/domains/coordination/definitions.js +67 -0
  85. package/dist/src/server/domains/coordination/index.d.ts +18 -0
  86. package/dist/src/server/domains/coordination/index.js +132 -0
  87. package/dist/src/server/domains/coordination/manifest.js +15 -0
  88. package/dist/src/server/domains/graphql/handlers.impl.core.runtime.replay.js +2 -2
  89. package/dist/src/server/domains/graphql/handlers.impl.core.runtime.shared.js +77 -77
  90. package/dist/src/server/domains/hooks/ai-handlers.js +3 -3
  91. package/dist/src/server/domains/maintenance/handlers.d.ts +2 -2
  92. package/dist/src/server/domains/maintenance/handlers.js +2 -2
  93. package/dist/src/server/domains/platform/handlers/bridge-handlers.d.ts +1 -1
  94. package/dist/src/server/domains/platform/handlers/bridge-handlers.js +1 -1
  95. package/dist/src/server/domains/platform/handlers/miniapp-handlers.d.ts +1 -1
  96. package/dist/src/server/domains/platform/handlers/miniapp-handlers.js +1 -1
  97. package/dist/src/server/domains/process/handlers.impl.core.runtime.inject.js +1 -1
  98. package/dist/src/server/domains/trace/TraceSummarizer.d.ts +60 -0
  99. package/dist/src/server/domains/trace/TraceSummarizer.js +109 -0
  100. package/dist/src/server/domains/trace/definitions.tools.js +101 -71
  101. package/dist/src/server/domains/trace/handlers.d.ts +2 -1
  102. package/dist/src/server/domains/trace/handlers.js +59 -4
  103. package/dist/src/server/domains/trace/manifest.js +3 -1
  104. package/dist/src/server/domains/transform/handlers.impl.transform-base.js +103 -103
  105. package/dist/src/server/domains/wasm/handlers.js +2 -2
  106. package/dist/src/server/domains/workflow/handlers.impl.workflow-account-bundle.js +1 -1
  107. package/dist/src/server/domains/workflow/handlers.impl.workflow-api.js +51 -51
  108. package/dist/src/server/domains/workflow/handlers.impl.workflow-base.js +51 -51
  109. package/dist/src/server/extensions/ExtensionManager.roots.js +15 -5
  110. package/dist/src/server/http/HttpMiddleware.js +1 -1
  111. package/dist/src/server/registry/contracts.d.ts +6 -0
  112. package/dist/src/server/sandbox/MCPBridge.d.ts +9 -0
  113. package/dist/src/server/sandbox/MCPBridge.js +22 -0
  114. package/dist/src/server/sandbox/QuickJSSandbox.d.ts +4 -1
  115. package/dist/src/server/sandbox/QuickJSSandbox.js +149 -0
  116. package/dist/src/server/sandbox/SandboxHelpers.js +250 -250
  117. package/dist/src/server/sandbox/types.d.ts +13 -0
  118. package/dist/src/server/search/AffinityGraph.d.ts +7 -1
  119. package/dist/src/server/search/AffinityGraph.js +24 -3
  120. package/dist/src/services/LLMService.js +1 -1
  121. package/dist/src/utils/UnifiedCacheManager.d.ts +1 -1
  122. package/dist/src/utils/UnifiedCacheManager.js +2 -2
  123. package/dist/src/utils/cliFastPath.js +18 -4
  124. package/package.json +5 -3
  125. package/scripts/postinstall.cjs +37 -37
  126. package/src/native/scripts/linux/enum-windows.sh +12 -12
  127. package/src/native/scripts/macos/enum-windows.applescript +22 -22
  128. package/src/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
  129. package/src/native/scripts/windows/enum-windows.ps1 +44 -44
  130. package/src/native/scripts/windows/inject-dll.ps1 +21 -21
@@ -1,79 +1,79 @@
1
1
  export { GRAPHQL_MAX_PREVIEW_CHARS, GRAPHQL_MAX_SCHEMA_CHARS, GRAPHQL_MAX_QUERY_CHARS, GRAPHQL_MAX_GRAPH_NODES, GRAPHQL_MAX_GRAPH_EDGES, } from '../../../constants.js';
2
- export const INTROSPECTION_QUERY = `
3
- query IntrospectionQuery {
4
- __schema {
5
- queryType { name }
6
- mutationType { name }
7
- subscriptionType { name }
8
- types { ...FullType }
9
- directives {
10
- name
11
- description
12
- locations
13
- args(includeDeprecated: true) { ...InputValue }
14
- }
15
- }
16
- }
17
- fragment FullType on __Type {
18
- kind
19
- name
20
- description
21
- fields(includeDeprecated: true) {
22
- name
23
- description
24
- args(includeDeprecated: true) { ...InputValue }
25
- type { ...TypeRef }
26
- isDeprecated
27
- deprecationReason
28
- }
29
- inputFields(includeDeprecated: true) { ...InputValue }
30
- interfaces { ...TypeRef }
31
- enumValues(includeDeprecated: true) {
32
- name
33
- description
34
- isDeprecated
35
- deprecationReason
36
- }
37
- possibleTypes { ...TypeRef }
38
- }
39
- fragment InputValue on __InputValue {
40
- name
41
- description
42
- type { ...TypeRef }
43
- defaultValue
44
- isDeprecated
45
- deprecationReason
46
- }
47
- fragment TypeRef on __Type {
48
- kind
49
- name
50
- ofType {
51
- kind
52
- name
53
- ofType {
54
- kind
55
- name
56
- ofType {
57
- kind
58
- name
59
- ofType {
60
- kind
61
- name
62
- ofType {
63
- kind
64
- name
65
- ofType {
66
- kind
67
- name
68
- ofType {
69
- kind
70
- name
71
- }
72
- }
73
- }
74
- }
75
- }
76
- }
77
- }
78
- }
2
+ export const INTROSPECTION_QUERY = `
3
+ query IntrospectionQuery {
4
+ __schema {
5
+ queryType { name }
6
+ mutationType { name }
7
+ subscriptionType { name }
8
+ types { ...FullType }
9
+ directives {
10
+ name
11
+ description
12
+ locations
13
+ args(includeDeprecated: true) { ...InputValue }
14
+ }
15
+ }
16
+ }
17
+ fragment FullType on __Type {
18
+ kind
19
+ name
20
+ description
21
+ fields(includeDeprecated: true) {
22
+ name
23
+ description
24
+ args(includeDeprecated: true) { ...InputValue }
25
+ type { ...TypeRef }
26
+ isDeprecated
27
+ deprecationReason
28
+ }
29
+ inputFields(includeDeprecated: true) { ...InputValue }
30
+ interfaces { ...TypeRef }
31
+ enumValues(includeDeprecated: true) {
32
+ name
33
+ description
34
+ isDeprecated
35
+ deprecationReason
36
+ }
37
+ possibleTypes { ...TypeRef }
38
+ }
39
+ fragment InputValue on __InputValue {
40
+ name
41
+ description
42
+ type { ...TypeRef }
43
+ defaultValue
44
+ isDeprecated
45
+ deprecationReason
46
+ }
47
+ fragment TypeRef on __Type {
48
+ kind
49
+ name
50
+ ofType {
51
+ kind
52
+ name
53
+ ofType {
54
+ kind
55
+ name
56
+ ofType {
57
+ kind
58
+ name
59
+ ofType {
60
+ kind
61
+ name
62
+ ofType {
63
+ kind
64
+ name
65
+ ofType {
66
+ kind
67
+ name
68
+ ofType {
69
+ kind
70
+ name
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
79
  `.trim();
@@ -125,7 +125,7 @@ export class AIHookToolHandlers {
125
125
  const hookId = argStringRequired(args, 'hookId');
126
126
  const page = await this.pageController.getPage();
127
127
  const hookData = await evaluateWithTimeout(page, (id) => {
128
- if (!window.__aiHooks || !window.__aiHooks[id]) {
128
+ if (!window.__aiHooks?.[id]) {
129
129
  return null;
130
130
  }
131
131
  return {
@@ -222,7 +222,7 @@ export class AIHookToolHandlers {
222
222
  const page = await this.pageController.getPage();
223
223
  if (hookId) {
224
224
  await evaluateWithTimeout(page, (id) => {
225
- if (window.__aiHooks && window.__aiHooks[id]) {
225
+ if (window.__aiHooks?.[id]) {
226
226
  window.__aiHooks[id] = [];
227
227
  }
228
228
  }, hookId);
@@ -280,7 +280,7 @@ export class AIHookToolHandlers {
280
280
  const enabled = argBool(args, 'enabled');
281
281
  const page = await this.pageController.getPage();
282
282
  await evaluateWithTimeout(page, (id, enable) => {
283
- if (window.__aiHookMetadata && window.__aiHookMetadata[id]) {
283
+ if (window.__aiHookMetadata?.[id]) {
284
284
  window.__aiHookMetadata[id].enabled = enable;
285
285
  }
286
286
  }, hookId, enabled);
@@ -1,5 +1,5 @@
1
- import { TokenBudgetManager } from '../../../utils/TokenBudgetManager.js';
2
- import { UnifiedCacheManager } from '../../../utils/UnifiedCacheManager.js';
1
+ import { type TokenBudgetManager } from '../../../utils/TokenBudgetManager.js';
2
+ import { type UnifiedCacheManager } from '../../../utils/UnifiedCacheManager.js';
3
3
  import type { ToolResponse } from '../../types.js';
4
4
  import { cleanupArtifacts } from '../../../utils/artifactRetention.js';
5
5
  import { runEnvironmentDoctor } from '../../../utils/environmentDoctor.js';
@@ -1,6 +1,6 @@
1
1
  import { logger } from '../../../utils/logger.js';
2
- import { TokenBudgetManager } from '../../../utils/TokenBudgetManager.js';
3
- import { UnifiedCacheManager } from '../../../utils/UnifiedCacheManager.js';
2
+ import {} from '../../../utils/TokenBudgetManager.js';
3
+ import {} from '../../../utils/UnifiedCacheManager.js';
4
4
  import { asJsonResponse, serializeError } from '../../domains/shared/response.js';
5
5
  import { cleanupArtifacts } from '../../../utils/artifactRetention.js';
6
6
  import { runEnvironmentDoctor } from '../../../utils/environmentDoctor.js';
@@ -1,4 +1,4 @@
1
- import { ExternalToolRunner } from '../../../domains/shared/modules.js';
1
+ import { type ExternalToolRunner } from '../../../domains/shared/modules.js';
2
2
  export declare class BridgeHandlers {
3
3
  private runner;
4
4
  constructor(runner: ExternalToolRunner);
@@ -1,6 +1,6 @@
1
1
  import { basename, extname, resolve } from 'node:path';
2
2
  import { argStringArray } from '../../../domains/shared/parse-args.js';
3
- import { ExternalToolRunner } from '../../../domains/shared/modules.js';
3
+ import {} from '../../../domains/shared/modules.js';
4
4
  import { toTextResponse, toErrorResponse, parseStringArg, resolveOutputDirectory, checkExternalCommand, } from '../../../domains/platform/handlers/platform-utils.js';
5
5
  function generateFridaTemplate(hookType, functionName) {
6
6
  const templates = {
@@ -1,5 +1,5 @@
1
1
  import type { CodeCollector } from '../../../domains/shared/modules.js';
2
- import { ExternalToolRunner } from '../../../domains/shared/modules.js';
2
+ import { type ExternalToolRunner } from '../../../domains/shared/modules.js';
3
3
  export declare class MiniappHandlers {
4
4
  private runner;
5
5
  private collector;
@@ -1,6 +1,6 @@
1
1
  import { readFile, mkdir, writeFile, stat } from 'node:fs/promises';
2
2
  import { basename, dirname, extname, relative, resolve } from 'node:path';
3
- import { ExternalToolRunner } from '../../../domains/shared/modules.js';
3
+ import {} from '../../../domains/shared/modules.js';
4
4
  import { logger } from '../../../../utils/logger.js';
5
5
  import { toTextResponse, toErrorResponse, getCollectorState, parseStringArg, isRecord, toStringArray, toDisplayPath, getDefaultSearchPaths, walkDirectory, resolveOutputDirectory, resolveSafeOutputPath, readJsonFileSafe, extractAppIdFromPath, } from '../../../domains/platform/handlers/platform-utils.js';
6
6
  function parseMiniappPkgBuffer(buffer) {
@@ -297,7 +297,7 @@ export class ProcessToolHandlersRuntime extends ProcessHandlersBase {
297
297
  };
298
298
  }
299
299
  const target = filtered[0];
300
- if (!target || !target.webSocketDebuggerUrl) {
300
+ if (!target?.webSocketDebuggerUrl) {
301
301
  return {
302
302
  content: [
303
303
  {
@@ -0,0 +1,60 @@
1
+ export type SummaryDetail = 'compact' | 'balanced' | 'full';
2
+ export interface TraceEvent {
3
+ timestamp: number;
4
+ category: string;
5
+ eventType: string;
6
+ data?: unknown;
7
+ scriptId?: string;
8
+ lineNumber?: number;
9
+ }
10
+ export interface MemoryDelta {
11
+ timestamp: number;
12
+ address: string;
13
+ oldValue: string;
14
+ newValue: string;
15
+ size: number;
16
+ valueType: string;
17
+ }
18
+ export interface CategorySummary {
19
+ category: string;
20
+ count: number;
21
+ firstTimestamp: number;
22
+ lastTimestamp: number;
23
+ topEventTypes: Array<{
24
+ type: string;
25
+ count: number;
26
+ }>;
27
+ }
28
+ export interface KeyMoment {
29
+ timestamp: number;
30
+ type: 'breakpoint' | 'network_complete' | 'memory_anomaly' | 'exception' | 'navigation';
31
+ description: string;
32
+ data?: unknown;
33
+ }
34
+ export interface TraceSummary {
35
+ detail: SummaryDetail;
36
+ totalEvents: number;
37
+ timeRange: {
38
+ start: number;
39
+ end: number;
40
+ durationMs: number;
41
+ };
42
+ categories: CategorySummary[];
43
+ keyMoments?: KeyMoment[];
44
+ }
45
+ export interface MemorySummary {
46
+ totalDeltas: number;
47
+ uniqueAddresses: number;
48
+ anomalies: Array<{
49
+ address: string;
50
+ writeCount: number;
51
+ description: string;
52
+ }>;
53
+ topAddresses: Array<{
54
+ address: string;
55
+ writeCount: number;
56
+ }>;
57
+ }
58
+ export declare function summarizeEvents(events: TraceEvent[], detail?: SummaryDetail): TraceSummary;
59
+ export declare function extractKeyMoments(events: TraceEvent[]): KeyMoment[];
60
+ export declare function summarizeMemoryDeltas(deltas: MemoryDelta[]): MemorySummary;
@@ -0,0 +1,109 @@
1
+ export function summarizeEvents(events, detail = 'balanced') {
2
+ if (events.length === 0) {
3
+ return {
4
+ detail,
5
+ totalEvents: 0,
6
+ timeRange: { start: 0, end: 0, durationMs: 0 },
7
+ categories: [],
8
+ keyMoments: detail !== 'compact' ? [] : undefined,
9
+ };
10
+ }
11
+ const timestamps = events.map((e) => e.timestamp);
12
+ const start = Math.min(...timestamps);
13
+ const end = Math.max(...timestamps);
14
+ const catMap = new Map();
15
+ for (const event of events) {
16
+ let cat = catMap.get(event.category);
17
+ if (!cat) {
18
+ cat = { count: 0, first: event.timestamp, last: event.timestamp, types: new Map() };
19
+ catMap.set(event.category, cat);
20
+ }
21
+ cat.count++;
22
+ cat.first = Math.min(cat.first, event.timestamp);
23
+ cat.last = Math.max(cat.last, event.timestamp);
24
+ cat.types.set(event.eventType, (cat.types.get(event.eventType) ?? 0) + 1);
25
+ }
26
+ const categories = [...catMap.entries()]
27
+ .sort((a, b) => b[1].count - a[1].count)
28
+ .map(([category, info]) => ({
29
+ category,
30
+ count: info.count,
31
+ firstTimestamp: info.first,
32
+ lastTimestamp: info.last,
33
+ topEventTypes: [...info.types.entries()]
34
+ .sort((a, b) => b[1] - a[1])
35
+ .slice(0, 5)
36
+ .map(([type, count]) => ({ type, count })),
37
+ }));
38
+ const summary = {
39
+ detail,
40
+ totalEvents: events.length,
41
+ timeRange: { start, end, durationMs: end - start },
42
+ categories,
43
+ };
44
+ if (detail === 'balanced' || detail === 'full') {
45
+ summary.keyMoments = extractKeyMoments(events);
46
+ }
47
+ return summary;
48
+ }
49
+ export function extractKeyMoments(events) {
50
+ const moments = [];
51
+ for (const event of events) {
52
+ if (event.eventType === 'Debugger.paused') {
53
+ moments.push({
54
+ timestamp: event.timestamp,
55
+ type: 'breakpoint',
56
+ description: `Debugger paused${event.scriptId ? ` at script ${event.scriptId}` : ''}${event.lineNumber ? `:${event.lineNumber}` : ''}`,
57
+ data: event.data,
58
+ });
59
+ }
60
+ else if (event.eventType === 'Network.loadingFinished') {
61
+ moments.push({
62
+ timestamp: event.timestamp,
63
+ type: 'network_complete',
64
+ description: 'Network request completed',
65
+ data: event.data,
66
+ });
67
+ }
68
+ else if (event.eventType === 'Runtime.exceptionThrown') {
69
+ moments.push({
70
+ timestamp: event.timestamp,
71
+ type: 'exception',
72
+ description: 'Runtime exception thrown',
73
+ data: event.data,
74
+ });
75
+ }
76
+ else if (event.eventType === 'Page.frameNavigated' || event.eventType === 'Page.navigatedWithinDocument') {
77
+ moments.push({
78
+ timestamp: event.timestamp,
79
+ type: 'navigation',
80
+ description: 'Page navigation',
81
+ data: event.data,
82
+ });
83
+ }
84
+ }
85
+ return moments;
86
+ }
87
+ export function summarizeMemoryDeltas(deltas) {
88
+ if (deltas.length === 0) {
89
+ return { totalDeltas: 0, uniqueAddresses: 0, anomalies: [], topAddresses: [] };
90
+ }
91
+ const writeMap = new Map();
92
+ for (const delta of deltas) {
93
+ writeMap.set(delta.address, (writeMap.get(delta.address) ?? 0) + 1);
94
+ }
95
+ const uniqueAddresses = writeMap.size;
96
+ const totalWrites = deltas.length;
97
+ const meanWrites = totalWrites / uniqueAddresses;
98
+ const sorted = [...writeMap.entries()].sort((a, b) => b[1] - a[1]);
99
+ const topAddresses = sorted.slice(0, 10).map(([address, writeCount]) => ({ address, writeCount }));
100
+ const anomalyThreshold = meanWrites * 3;
101
+ const anomalies = sorted
102
+ .filter(([, count]) => count > anomalyThreshold)
103
+ .map(([address, writeCount]) => ({
104
+ address,
105
+ writeCount,
106
+ description: `${writeCount} writes (${(writeCount / meanWrites).toFixed(1)}× average)`,
107
+ }));
108
+ return { totalDeltas: totalWrites, uniqueAddresses, anomalies, topAddresses };
109
+ }
@@ -1,19 +1,19 @@
1
1
  export const TRACE_TOOLS = [
2
2
  {
3
3
  name: 'start_trace_recording',
4
- description: `Start recording CDP events, debugger state, and memory writes into a SQLite trace database.
5
-
6
- Recording captures events from:
7
- - Debugger: breakpoints, pauses, script parsing
8
- - Runtime: console calls, exceptions
9
- - Network: requests, responses
10
- - Page: navigation events
11
- - EventBus: tool calls, memory scans, browser events
12
-
13
- Call stop_trace_recording to end the recording session.
14
-
15
- Examples:
16
- start_trace_recording()
4
+ description: `Start recording CDP events, debugger state, and memory writes into a SQLite trace database.
5
+
6
+ Recording captures events from:
7
+ - Debugger: breakpoints, pauses, script parsing
8
+ - Runtime: console calls, exceptions
9
+ - Network: requests, responses
10
+ - Page: navigation events
11
+ - EventBus: tool calls, memory scans, browser events
12
+
13
+ Call stop_trace_recording to end the recording session.
14
+
15
+ Examples:
16
+ start_trace_recording()
17
17
  start_trace_recording(cdpDomains=["Debugger", "Network"])`,
18
18
  inputSchema: {
19
19
  type: 'object',
@@ -32,16 +32,16 @@ start_trace_recording(cdpDomains=["Debugger", "Network"])`,
32
32
  },
33
33
  {
34
34
  name: 'stop_trace_recording',
35
- description: `Stop the active trace recording and finalize the SQLite database.
36
-
37
- Returns session summary including:
38
- - Database file path
39
- - Total event count
40
- - Memory delta count
41
- - Heap snapshot count
42
- - Recording duration
43
-
44
- Examples:
35
+ description: `Stop the active trace recording and finalize the SQLite database.
36
+
37
+ Returns session summary including:
38
+ - Database file path
39
+ - Total event count
40
+ - Memory delta count
41
+ - Heap snapshot count
42
+ - Recording duration
43
+
44
+ Examples:
45
45
  stop_trace_recording()`,
46
46
  inputSchema: {
47
47
  type: 'object',
@@ -50,19 +50,19 @@ stop_trace_recording()`,
50
50
  },
51
51
  {
52
52
  name: 'query_trace_sql',
53
- description: `Execute a read-only SQL query against a trace database.
54
-
55
- Available tables:
56
- - events(id, timestamp, category, event_type, data, script_id, line_number)
57
- - memory_deltas(id, timestamp, address, old_value, new_value, size, value_type)
58
- - heap_snapshots(id, timestamp, snapshot_data, summary)
59
- - metadata(key, value)
60
-
61
- Returns columns, rows, and row count.
62
-
63
- Examples:
64
- query_trace_sql(sql="SELECT * FROM events WHERE category='debugger' ORDER BY timestamp")
65
- query_trace_sql(sql="SELECT address, COUNT(*) as writes FROM memory_deltas GROUP BY address ORDER BY writes DESC LIMIT 10")
53
+ description: `Execute a read-only SQL query against a trace database.
54
+
55
+ Available tables:
56
+ - events(id, timestamp, category, event_type, data, script_id, line_number)
57
+ - memory_deltas(id, timestamp, address, old_value, new_value, size, value_type)
58
+ - heap_snapshots(id, timestamp, snapshot_data, summary)
59
+ - metadata(key, value)
60
+
61
+ Returns columns, rows, and row count.
62
+
63
+ Examples:
64
+ query_trace_sql(sql="SELECT * FROM events WHERE category='debugger' ORDER BY timestamp")
65
+ query_trace_sql(sql="SELECT address, COUNT(*) as writes FROM memory_deltas GROUP BY address ORDER BY writes DESC LIMIT 10")
66
66
  query_trace_sql(sql="SELECT * FROM events WHERE timestamp BETWEEN 1000 AND 2000", dbPath="artifacts/traces/my-trace.db")`,
67
67
  inputSchema: {
68
68
  type: 'object',
@@ -81,18 +81,18 @@ query_trace_sql(sql="SELECT * FROM events WHERE timestamp BETWEEN 1000 AND 2000"
81
81
  },
82
82
  {
83
83
  name: 'seek_to_timestamp',
84
- description: `Reconstruct application state at a specific timestamp from a recorded trace.
85
-
86
- Returns a structured snapshot including:
87
- - Events near the timestamp
88
- - Debugger state (last pause, call stack)
89
- - Memory state (latest values per address)
90
- - Network state (completed requests)
91
- - Nearest heap snapshot
92
-
93
- Examples:
94
- seek_to_timestamp(timestamp=1711000000000)
95
- seek_to_timestamp(timestamp=1711000000000, windowMs=500)
84
+ description: `Reconstruct application state at a specific timestamp from a recorded trace.
85
+
86
+ Returns a structured snapshot including:
87
+ - Events near the timestamp
88
+ - Debugger state (last pause, call stack)
89
+ - Memory state (latest values per address)
90
+ - Network state (completed requests)
91
+ - Nearest heap snapshot
92
+
93
+ Examples:
94
+ seek_to_timestamp(timestamp=1711000000000)
95
+ seek_to_timestamp(timestamp=1711000000000, windowMs=500)
96
96
  seek_to_timestamp(timestamp=1711000000000, dbPath="artifacts/traces/my-trace.db")`,
97
97
  inputSchema: {
98
98
  type: 'object',
@@ -115,18 +115,18 @@ seek_to_timestamp(timestamp=1711000000000, dbPath="artifacts/traces/my-trace.db"
115
115
  },
116
116
  {
117
117
  name: 'diff_heap_snapshots',
118
- description: `Compare two heap snapshots from a trace and return the differences.
119
-
120
- Shows:
121
- - New object types (in snapshot 2 but not 1)
122
- - Deleted object types (in snapshot 1 but not 2)
123
- - Changed objects (count or size differs)
124
- - Total size delta
125
-
126
- Useful for identifying state changes in obfuscated code.
127
-
128
- Examples:
129
- diff_heap_snapshots(snapshotId1=1, snapshotId2=2)
118
+ description: `Compare two heap snapshots from a trace and return the differences.
119
+
120
+ Shows:
121
+ - New object types (in snapshot 2 but not 1)
122
+ - Deleted object types (in snapshot 1 but not 2)
123
+ - Changed objects (count or size differs)
124
+ - Total size delta
125
+
126
+ Useful for identifying state changes in obfuscated code.
127
+
128
+ Examples:
129
+ diff_heap_snapshots(snapshotId1=1, snapshotId2=2)
130
130
  diff_heap_snapshots(snapshotId1=1, snapshotId2=3, dbPath="artifacts/traces/my-trace.db")`,
131
131
  inputSchema: {
132
132
  type: 'object',
@@ -149,17 +149,17 @@ diff_heap_snapshots(snapshotId1=1, snapshotId2=3, dbPath="artifacts/traces/my-tr
149
149
  },
150
150
  {
151
151
  name: 'export_trace',
152
- description: `Export a trace database to Chrome Trace Event JSON format.
153
-
154
- The resulting file can be loaded in:
155
- - chrome://tracing
156
- - Perfetto UI (ui.perfetto.dev)
157
-
158
- Maps events to the standard trace event format with name, category, phase, timestamp.
159
-
160
- Examples:
161
- export_trace()
162
- export_trace(dbPath="artifacts/traces/my-trace.db")
152
+ description: `Export a trace database to Chrome Trace Event JSON format.
153
+
154
+ The resulting file can be loaded in:
155
+ - chrome://tracing
156
+ - Perfetto UI (ui.perfetto.dev)
157
+
158
+ Maps events to the standard trace event format with name, category, phase, timestamp.
159
+
160
+ Examples:
161
+ export_trace()
162
+ export_trace(dbPath="artifacts/traces/my-trace.db")
163
163
  export_trace(outputPath="my-export.json")`,
164
164
  inputSchema: {
165
165
  type: 'object',
@@ -175,4 +175,34 @@ export_trace(outputPath="my-export.json")`,
175
175
  },
176
176
  },
177
177
  },
178
+ {
179
+ name: 'summarize_trace',
180
+ description: `Generate a compact, LLM-friendly summary of a trace database.
181
+
182
+ Avoids sending raw trace data that may exceed context windows. Three detail levels:
183
+ - compact: category aggregation + timeline overview (~10% of raw size)
184
+ - balanced: compact + key moments (breakpoints, exceptions, network completions) [DEFAULT]
185
+ - full: passthrough — returns all events without compression
186
+
187
+ Also detects memory anomalies: addresses with significantly more writes than average.
188
+
189
+ Examples:
190
+ summarize_trace()
191
+ summarize_trace(detail="compact")
192
+ summarize_trace(detail="balanced", dbPath="artifacts/traces/my-trace.db")`,
193
+ inputSchema: {
194
+ type: 'object',
195
+ properties: {
196
+ detail: {
197
+ type: 'string',
198
+ enum: ['compact', 'balanced', 'full'],
199
+ description: 'Summary detail level (default: balanced)',
200
+ },
201
+ dbPath: {
202
+ type: 'string',
203
+ description: 'Path to trace DB file. Uses the active recording if omitted.',
204
+ },
205
+ },
206
+ },
207
+ },
178
208
  ];
@@ -1,5 +1,5 @@
1
1
  import type { MCPServerContext } from '../../MCPServer.context.js';
2
- import { TraceRecorder } from '../../../modules/trace/TraceRecorder.js';
2
+ import { type TraceRecorder } from '../../../modules/trace/TraceRecorder.js';
3
3
  export declare class TraceToolHandlers {
4
4
  private readonly recorder;
5
5
  private readonly ctx;
@@ -13,4 +13,5 @@ export declare class TraceToolHandlers {
13
13
  private getDbForReading;
14
14
  private rowToObject;
15
15
  private safeParseJSON;
16
+ handleSummarizeTrace(args: Record<string, unknown>): Promise<unknown>;
16
17
  }