@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.
- package/LICENSE +661 -661
- package/README.md +4 -4
- package/README.zh.md +3 -3
- package/dist/native/scripts/linux/enum-windows.sh +12 -12
- package/dist/native/scripts/macos/enum-windows.applescript +22 -22
- package/dist/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
- package/dist/native/scripts/windows/enum-windows.ps1 +44 -44
- package/dist/native/scripts/windows/inject-dll.ps1 +21 -21
- package/dist/src/modules/analyzer/CodeAnalyzer.d.ts +1 -1
- package/dist/src/modules/analyzer/CodeAnalyzer.js +1 -1
- package/dist/src/modules/browser/BrowserDiscovery.d.ts +6 -5
- package/dist/src/modules/browser/BrowserDiscovery.js +1 -1
- package/dist/src/modules/browser/BrowserModeManager.d.ts +1 -1
- package/dist/src/modules/browser/BrowserModeManager.js +1 -1
- package/dist/src/modules/browser/UnifiedBrowserManager.js +1 -1
- package/dist/src/modules/captcha/AICaptchaDetector.d.ts +22 -22
- package/dist/src/modules/captcha/AICaptchaDetector.js +75 -75
- package/dist/src/modules/captcha/CaptchaDetector.d.ts +31 -17
- package/dist/src/modules/captcha/CaptchaDetector.js +1 -1
- package/dist/src/modules/collector/CodeCache.d.ts +2 -2
- package/dist/src/modules/collector/CodeCollector.d.ts +12 -9
- package/dist/src/modules/collector/CodeCollector.js +1 -1
- package/dist/src/modules/collector/DOMInspector.d.ts +3 -2
- package/dist/src/modules/collector/DOMInspector.js +1 -1
- package/dist/src/modules/crypto/CryptoDetector.d.ts +1 -1
- package/dist/src/modules/crypto/CryptoDetector.js +1 -1
- package/dist/src/modules/debugger/ScriptManager.impl.extract-function-tree.js +1 -1
- package/dist/src/modules/deobfuscator/Deobfuscator.d.ts +1 -1
- package/dist/src/modules/deobfuscator/Deobfuscator.js +1 -1
- package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.d.ts +1 -1
- package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.js +2 -2
- package/dist/src/modules/deobfuscator/PackerDeobfuscator.js +1 -1
- package/dist/src/modules/deobfuscator/VMDeobfuscator.d.ts +1 -1
- package/dist/src/modules/deobfuscator/VMDeobfuscator.js +82 -82
- package/dist/src/modules/emulator/AIEnvironmentAnalyzer.js +1 -1
- package/dist/src/modules/external/ExternalToolRunner.d.ts +1 -1
- package/dist/src/modules/external/ExternalToolRunner.js +1 -1
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.compose.js +5 -5
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.network.js +311 -311
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.runtime.js +410 -410
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.storage.js +122 -122
- package/dist/src/modules/monitor/ConsoleMonitor.impl.core.dynamic.js +194 -194
- package/dist/src/modules/monitor/PlaywrightNetworkMonitor.js +62 -62
- package/dist/src/modules/process/LinuxProcessManager.js +2 -2
- package/dist/src/modules/process/MacProcessManager.js +26 -26
- package/dist/src/modules/process/ProcessManager.impl.js +1 -1
- package/dist/src/modules/process/memory/availability.js +49 -49
- package/dist/src/modules/process/memory/injector.js +185 -185
- package/dist/src/modules/process/memory/reader.js +50 -50
- package/dist/src/modules/process/memory/regions.dump.js +51 -51
- package/dist/src/modules/process/memory/regions.enumerate.js +107 -107
- package/dist/src/modules/process/memory/regions.modules.js +80 -80
- package/dist/src/modules/process/memory/regions.protection.js +106 -106
- package/dist/src/modules/process/memory/scanner.darwin.js +41 -41
- package/dist/src/modules/process/memory/scanner.windows.js +124 -124
- package/dist/src/modules/process/memory/writer.js +54 -54
- package/dist/src/modules/security/ExecutionSandbox.js +44 -44
- package/dist/src/modules/stealth/StealthScripts.d.ts +3 -2
- package/dist/src/modules/stealth/StealthScripts.js +35 -1
- package/dist/src/modules/stealth/StealthVerifier.d.ts +1 -1
- package/dist/src/modules/stealth/StealthVerifier.js +1 -1
- package/dist/src/modules/trace/TraceDB.js +63 -63
- package/dist/src/native/CodeInjector.js +1 -1
- package/dist/src/native/HardwareBreakpoint.js +1 -1
- package/dist/src/server/MCPServer.js +1 -0
- package/dist/src/server/MCPServer.search.helpers.js +1 -1
- package/dist/src/server/MCPServer.tools.js +1 -1
- package/dist/src/server/ToolCallContextGuard.d.ts +5 -0
- package/dist/src/server/ToolCallContextGuard.js +77 -0
- package/dist/src/server/ToolRouter.d.ts +1 -1
- package/dist/src/server/ToolRouter.js +2 -2
- package/dist/src/server/domains/analysis/handlers.impl.d.ts +8 -8
- package/dist/src/server/domains/analysis/handlers.impl.js +8 -8
- package/dist/src/server/domains/analysis/handlers.web-tools.js +2 -2
- package/dist/src/server/domains/browser/definitions.tools.page-core.js +59 -59
- package/dist/src/server/domains/browser/definitions.tools.runtime.js +41 -41
- package/dist/src/server/domains/browser/definitions.tools.security.js +114 -114
- package/dist/src/server/domains/browser/handlers/facade-initializer.d.ts +3 -3
- package/dist/src/server/domains/browser/handlers/facade-initializer.js +3 -3
- package/dist/src/server/domains/browser/handlers/framework-state.js +210 -0
- package/dist/src/server/domains/browser/handlers/stealth-injection.js +8 -2
- package/dist/src/server/domains/browser/handlers.impl.d.ts +15 -11
- package/dist/src/server/domains/browser/handlers.impl.js +4 -4
- package/dist/src/server/domains/coordination/definitions.js +67 -0
- package/dist/src/server/domains/coordination/index.d.ts +18 -0
- package/dist/src/server/domains/coordination/index.js +132 -0
- package/dist/src/server/domains/coordination/manifest.js +15 -0
- package/dist/src/server/domains/graphql/handlers.impl.core.runtime.replay.js +2 -2
- package/dist/src/server/domains/graphql/handlers.impl.core.runtime.shared.js +77 -77
- package/dist/src/server/domains/hooks/ai-handlers.js +3 -3
- package/dist/src/server/domains/maintenance/handlers.d.ts +2 -2
- package/dist/src/server/domains/maintenance/handlers.js +2 -2
- package/dist/src/server/domains/platform/handlers/bridge-handlers.d.ts +1 -1
- package/dist/src/server/domains/platform/handlers/bridge-handlers.js +1 -1
- package/dist/src/server/domains/platform/handlers/miniapp-handlers.d.ts +1 -1
- package/dist/src/server/domains/platform/handlers/miniapp-handlers.js +1 -1
- package/dist/src/server/domains/process/handlers.impl.core.runtime.inject.js +1 -1
- package/dist/src/server/domains/trace/TraceSummarizer.d.ts +60 -0
- package/dist/src/server/domains/trace/TraceSummarizer.js +109 -0
- package/dist/src/server/domains/trace/definitions.tools.js +101 -71
- package/dist/src/server/domains/trace/handlers.d.ts +2 -1
- package/dist/src/server/domains/trace/handlers.js +59 -4
- package/dist/src/server/domains/trace/manifest.js +3 -1
- package/dist/src/server/domains/transform/handlers.impl.transform-base.js +103 -103
- package/dist/src/server/domains/wasm/handlers.js +2 -2
- package/dist/src/server/domains/workflow/handlers.impl.workflow-account-bundle.js +1 -1
- package/dist/src/server/domains/workflow/handlers.impl.workflow-api.js +51 -51
- package/dist/src/server/domains/workflow/handlers.impl.workflow-base.js +51 -51
- package/dist/src/server/extensions/ExtensionManager.roots.js +15 -5
- package/dist/src/server/http/HttpMiddleware.js +1 -1
- package/dist/src/server/registry/contracts.d.ts +6 -0
- package/dist/src/server/sandbox/MCPBridge.d.ts +9 -0
- package/dist/src/server/sandbox/MCPBridge.js +22 -0
- package/dist/src/server/sandbox/QuickJSSandbox.d.ts +4 -1
- package/dist/src/server/sandbox/QuickJSSandbox.js +149 -0
- package/dist/src/server/sandbox/SandboxHelpers.js +250 -250
- package/dist/src/server/sandbox/types.d.ts +13 -0
- package/dist/src/server/search/AffinityGraph.d.ts +7 -1
- package/dist/src/server/search/AffinityGraph.js +24 -3
- package/dist/src/services/LLMService.js +1 -1
- package/dist/src/utils/UnifiedCacheManager.d.ts +1 -1
- package/dist/src/utils/UnifiedCacheManager.js +2 -2
- package/dist/src/utils/cliFastPath.js +18 -4
- package/package.json +5 -3
- package/scripts/postinstall.cjs +37 -37
- package/src/native/scripts/linux/enum-windows.sh +12 -12
- package/src/native/scripts/macos/enum-windows.applescript +22 -22
- package/src/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
- package/src/native/scripts/windows/enum-windows.ps1 +44 -44
- 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
|
|
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
|
|
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
|
|
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 {
|
|
3
|
-
import {
|
|
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,6 +1,6 @@
|
|
|
1
1
|
import { basename, extname, resolve } from 'node:path';
|
|
2
2
|
import { argStringArray } from '../../../domains/shared/parse-args.js';
|
|
3
|
-
import {
|
|
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 {
|
|
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) {
|
|
@@ -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
|
}
|