@jshookmcp/jshook 0.2.7 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -5
- package/README.zh.md +36 -5
- package/dist/{AntiCheatDetector-S8VRj-dD.mjs → AntiCheatDetector-BNk-EoBt.mjs} +3 -3
- package/dist/{CodeInjector-4Z3ngPoX.mjs → CodeInjector-Cq8q01kp.mjs} +5 -5
- package/dist/ConsoleMonitor-CPVQW1Y-.mjs +2201 -0
- package/dist/{DarwinAPI-B8hg_yhz.mjs → DarwinAPI-BNPxu0RH.mjs} +1 -1
- package/dist/DetailedDataManager-BQQcxh64.mjs +217 -0
- package/dist/EventBus-DgPmwpeu.mjs +141 -0
- package/dist/EvidenceGraphBridge-SFesNera.mjs +153 -0
- package/dist/{ExtensionManager-CZ6IveoV.mjs → ExtensionManager-CWYgw0YW.mjs} +13 -6
- package/dist/{FingerprintManager-BVxFJL2-.mjs → FingerprintManager-gzWtkKuf.mjs} +1 -1
- package/dist/{HardwareBreakpoint-DK1yjWkV.mjs → HardwareBreakpoint-B9gZCdFP.mjs} +3 -3
- package/dist/{HeapAnalyzer-CEbo10xU.mjs → HeapAnalyzer-BLDH0dCv.mjs} +4 -4
- package/dist/HookGeneratorBuilders.core.generators.storage-CtcdK78Q.mjs +639 -0
- package/dist/InstrumentationSession-CvPC7Jwy.mjs +244 -0
- package/dist/{MemoryController-DdtnBdD4.mjs → MemoryController-CbVdCIJF.mjs} +3 -3
- package/dist/{MemoryScanSession-RMixN3bX.mjs → MemoryScanSession-BsDZbLYm.mjs} +81 -78
- package/dist/{MemoryScanner-QjK4ld0B.mjs → MemoryScanner-Bcpml6II.mjs} +44 -18
- package/dist/{NativeMemoryManager.impl-CB6gJ0NM.mjs → NativeMemoryManager.impl-dZtA1ZGn.mjs} +14 -53
- package/dist/{NativeMemoryManager.utils-BML4q1ry.mjs → NativeMemoryManager.utils-B-FjA2mJ.mjs} +1 -1
- package/dist/{PEAnalyzer-CK0xe0Fs.mjs → PEAnalyzer-D1lzJ_VG.mjs} +2 -2
- package/dist/PageController-Bqm2kZ_X.mjs +417 -0
- package/dist/{PointerChainEngine-Cd73qu5b.mjs → PointerChainEngine-BOhyVsjx.mjs} +4 -4
- package/dist/PrerequisiteError-Dl33Svkz.mjs +20 -0
- package/dist/ResponseBuilder-D3iFYx2N.mjs +143 -0
- package/dist/ReverseEvidenceGraph-Dlsk94LC.mjs +269 -0
- package/dist/ScriptManager-aHHq0X7U.mjs +3000 -0
- package/dist/{Speedhack-CeF0XmEz.mjs → Speedhack-CqdIFlQl.mjs} +2 -2
- package/dist/{StructureAnalyzer-D4GkMduU.mjs → StructureAnalyzer-DhFaPvRO.mjs} +3 -3
- package/dist/ToolCatalog-C0JGZoOm.mjs +582 -0
- package/dist/ToolError-jh9whhMd.mjs +15 -0
- package/dist/ToolProbe-oC7aPrkv.mjs +45 -0
- package/dist/ToolRegistry-BjaF4oNz.mjs +131 -0
- package/dist/ToolRouter.policy-BWV67ZK-.mjs +304 -0
- package/dist/TraceRecorder-DgxyVbdQ.mjs +519 -0
- package/dist/{Win32API-Bc0QnQsN.mjs → Win32API-CePkipZY.mjs} +1 -1
- package/dist/{Win32Debug-DUHt9XUn.mjs → Win32Debug-BvKs-gxc.mjs} +2 -2
- package/dist/WorkflowEngine-CuvkZtWu.mjs +598 -0
- package/dist/analysis-CL9uACt9.mjs +463 -0
- package/dist/antidebug-CqDTB_uk.mjs +1081 -0
- package/dist/artifactRetention-CFEprwPw.mjs +591 -0
- package/dist/artifacts-Bk2-_uPq.mjs +59 -0
- package/dist/betterSqlite3-0pqusHHH.mjs +74 -0
- package/dist/binary-instrument-CXfpx6fT.mjs +979 -0
- package/dist/bind-helpers-xFfRF-qm.mjs +22 -0
- package/dist/boringssl-inspector-BH2D3VKc.mjs +180 -0
- package/dist/browser-BpOr5PEx.mjs +4082 -0
- package/dist/concurrency-Bt0yv1kJ.mjs +41 -0
- package/dist/{constants-CCvsN80K.mjs → constants-B0OANIBL.mjs} +88 -46
- package/dist/coordination-qUbyF8KU.mjs +259 -0
- package/dist/debugger-gnKxRSN0.mjs +1271 -0
- package/dist/definitions-6M-eejaT.mjs +53 -0
- package/dist/definitions-B18eyf0B.mjs +18 -0
- package/dist/definitions-B3QdlrHv.mjs +34 -0
- package/dist/definitions-B4rAvHNZ.mjs +63 -0
- package/dist/definitions-BB_4jnmy.mjs +37 -0
- package/dist/definitions-BMfYXoNC.mjs +43 -0
- package/dist/definitions-Beid2EB3.mjs +27 -0
- package/dist/definitions-C1UvM5Iy.mjs +126 -0
- package/dist/definitions-CXEI7QC72.mjs +216 -0
- package/dist/definitions-C_4r7Fo-2.mjs +14 -0
- package/dist/definitions-CkFDALoa.mjs +26 -0
- package/dist/definitions-Cke7zEb8.mjs +94 -0
- package/dist/definitions-ClJLzsJQ.mjs +25 -0
- package/dist/definitions-Cq-zroAU.mjs +28 -0
- package/dist/definitions-Cy3Sl6gV.mjs +34 -0
- package/dist/definitions-D3VsGcvz.mjs +47 -0
- package/dist/definitions-DVGfrn7y.mjs +96 -0
- package/dist/definitions-LKpC3-nL.mjs +9 -0
- package/dist/definitions-bAhHQJq9.mjs +359 -0
- package/dist/encoding-Bvz5jLRv.mjs +1065 -0
- package/dist/evidence-graph-bridge-C_fv9PuC.mjs +135 -0
- package/dist/{factory-CibqTNC8.mjs → factory-DxlGh9Xf.mjs} +37 -52
- package/dist/graphql-DYWzJ29s.mjs +1026 -0
- package/dist/handlers-9sAbfIg-.mjs +2552 -0
- package/dist/handlers-Bl8zkwz1.mjs +2716 -0
- package/dist/handlers-C67ktuRN.mjs +710 -0
- package/dist/handlers-C87g8oCe.mjs +276 -0
- package/dist/handlers-CTsDAO6p.mjs +681 -0
- package/dist/handlers-Cgyg6c0U.mjs +645 -0
- package/dist/handlers-D6j6yka7.mjs +2124 -0
- package/dist/handlers-DdFzXLvF.mjs +446 -0
- package/dist/handlers-DeLOCd5m.mjs +799 -0
- package/dist/handlers-DlCJN4Td.mjs +757 -0
- package/dist/handlers-DxGIq15_2.mjs +917 -0
- package/dist/handlers-U6L4xhuF.mjs +585 -0
- package/dist/handlers-tB9Mp9ZK.mjs +84 -0
- package/dist/handlers-tiy7EIBp.mjs +572 -0
- package/dist/handlers.impl-DS0d9fUw.mjs +761 -0
- package/dist/hooks-CzCWByww.mjs +898 -0
- package/dist/index.mjs +384 -155
- package/dist/{logger-BmWzC2lM.mjs → logger-Dh_xb7_2.mjs} +14 -6
- package/dist/maintenance-P7ePRXQC.mjs +830 -0
- package/dist/manifest-2ToTpjv8.mjs +106 -0
- package/dist/manifest-3g71z6Bg.mjs +79 -0
- package/dist/manifest-82baTv4U.mjs +45 -0
- package/dist/manifest-B3QVVeBS.mjs +82 -0
- package/dist/manifest-BB2J8IMJ.mjs +149 -0
- package/dist/manifest-BKbgbSiY.mjs +60 -0
- package/dist/manifest-Bcf-TJzH.mjs +848 -0
- package/dist/manifest-BmtZzQiQ2.mjs +45 -0
- package/dist/manifest-Bnd7kqEY.mjs +55 -0
- package/dist/manifest-BqQX6OQC2.mjs +65 -0
- package/dist/manifest-BqrQ4Tpj.mjs +81 -0
- package/dist/manifest-Br4RPFt5.mjs +370 -0
- package/dist/manifest-C5qDjysN.mjs +107 -0
- package/dist/manifest-C9RT5nk32.mjs +34 -0
- package/dist/manifest-CAhOuvSl.mjs +204 -0
- package/dist/manifest-CBYWCUBJ.mjs +51 -0
- package/dist/manifest-CFADCRa1.mjs +37 -0
- package/dist/manifest-CQVhavRF.mjs +114 -0
- package/dist/manifest-CT7zZBV1.mjs +48 -0
- package/dist/manifest-CV12bcrF.mjs +121 -0
- package/dist/manifest-CXsRWjjI.mjs +224 -0
- package/dist/manifest-CZLUCfG02.mjs +95 -0
- package/dist/manifest-D6phHKFd.mjs +131 -0
- package/dist/manifest-DCyjf4n2.mjs +294 -0
- package/dist/manifest-DHsnKgP6.mjs +60 -0
- package/dist/manifest-Df_dliIe.mjs +55 -0
- package/dist/manifest-Dh8WBmEW.mjs +129 -0
- package/dist/manifest-DhKRAT8_.mjs +92 -0
- package/dist/manifest-DlpTj4ic2.mjs +193 -0
- package/dist/manifest-DrbmZcFl2.mjs +253 -0
- package/dist/manifest-DuwHjUa5.mjs +70 -0
- package/dist/manifest-DzwvxPJX.mjs +38 -0
- package/dist/manifest-NXctwWQq.mjs +68 -0
- package/dist/manifest-Sc_0JQ13.mjs +418 -0
- package/dist/manifest-gZ4s_UtG.mjs +96 -0
- package/dist/manifest-qSleDqdO.mjs +1023 -0
- package/dist/modules-C184v-S9.mjs +11365 -0
- package/dist/mojo-ipc-B_H61Afw.mjs +525 -0
- package/dist/network-671Cw6hV.mjs +3346 -0
- package/dist/{artifacts-BbdOMET5.mjs → outputPaths-B1uGmrWZ.mjs} +219 -212
- package/dist/parse-args-BlRjqlkL.mjs +39 -0
- package/dist/platform-WmNn8Sxb.mjs +2070 -0
- package/dist/process-QcbIy5Zq.mjs +1401 -0
- package/dist/proxy-DqNs0bAd.mjs +170 -0
- package/dist/registry-D-6e18lB.mjs +34 -0
- package/dist/response-BQVP-xUn.mjs +28 -0
- package/dist/server/plugin-api.mjs +2 -2
- package/dist/shared-state-board-DV-dpHFJ.mjs +586 -0
- package/dist/sourcemap-Dq8ez8vS.mjs +650 -0
- package/dist/ssrf-policy-ZaUfvhq7.mjs +166 -0
- package/dist/streaming-BUQ0VJsg.mjs +725 -0
- package/dist/tool-builder-DCbIC5Eo.mjs +186 -0
- package/dist/transform-CiYJfNX0.mjs +1007 -0
- package/dist/types-Bx92KJfT.mjs +4 -0
- package/dist/wasm-DQTnHDs4.mjs +531 -0
- package/dist/workflow-f3xJOcjx.mjs +725 -0
- package/package.json +48 -78
- package/dist/ExtensionManager-DqUSOamB.mjs +0 -2
- package/dist/ToolCatalog-CnwmMIw3.mjs +0 -61483
- package/dist/{CacheAdapters-CzFNpD9a.mjs → CacheAdapters-CDe5WPSV.mjs} +0 -0
- package/dist/{StealthVerifier-BzBCFiwx.mjs → StealthVerifier-Bo4T3bz8.mjs} +0 -0
- package/dist/{VersionDetector-CNXcvD46.mjs → VersionDetector-CwVLVdDM.mjs} +0 -0
- package/dist/{formatAddress-ChCSIRWT.mjs → formatAddress-DVkj9kpI.mjs} +0 -0
- package/dist/{types-BBjOqye-.mjs → types-CPhOReNX.mjs} +1 -1
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { t as logger } from "./logger-Dh_xb7_2.mjs";
|
|
2
|
+
import { t as createProgressDebouncer } from "./EventBus-DgPmwpeu.mjs";
|
|
3
|
+
import { n as toolLookup, t as ensureBrowserCore } from "./registry-D-6e18lB.mjs";
|
|
4
|
+
import { t as coreTools } from "./definitions-C1UvM5Iy.mjs";
|
|
5
|
+
//#region src/modules/deobfuscator/LLMDeobfuscator.ts
|
|
6
|
+
/** Maximum code snippet size sent to the LLM (chars) to avoid token overflow */
|
|
7
|
+
const MAX_CODE_SNIPPET = 2e3;
|
|
8
|
+
/** Maximum number of identifiers to send in one request */
|
|
9
|
+
const MAX_IDENTIFIERS = 20;
|
|
10
|
+
var LLMDeobfuscator = class {
|
|
11
|
+
constructor(bridge) {
|
|
12
|
+
this.bridge = bridge;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Check if the underlying sampling bridge supports LLM delegation.
|
|
16
|
+
*/
|
|
17
|
+
isAvailable() {
|
|
18
|
+
return this.bridge.isSamplingSupported();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Use the client's LLM to suggest meaningful names for obfuscated identifiers.
|
|
22
|
+
*
|
|
23
|
+
* @param code - The obfuscated code snippet (truncated to MAX_CODE_SNIPPET)
|
|
24
|
+
* @param identifiers - Array of obfuscated identifier names to rename
|
|
25
|
+
* @returns Map of old → new names, or `null` if sampling unavailable/failed
|
|
26
|
+
*/
|
|
27
|
+
async suggestVariableNames(code, identifiers) {
|
|
28
|
+
if (!this.bridge.isSamplingSupported()) {
|
|
29
|
+
logger.debug("LLMDeobfuscator: sampling not available, skipping name suggestion");
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const trimmedIds = identifiers.slice(0, MAX_IDENTIFIERS);
|
|
33
|
+
const trimmedCode = code.slice(0, MAX_CODE_SNIPPET);
|
|
34
|
+
const userMessage = [
|
|
35
|
+
"Given this obfuscated JavaScript code, suggest meaningful variable/function names",
|
|
36
|
+
`for these identifiers: ${trimmedIds.join(", ")}`,
|
|
37
|
+
"",
|
|
38
|
+
"```javascript",
|
|
39
|
+
trimmedCode,
|
|
40
|
+
"```",
|
|
41
|
+
"",
|
|
42
|
+
"Respond ONLY with a valid JSON array of objects with fields:",
|
|
43
|
+
" { \"original\": \"<old_name>\", \"suggested\": \"<new_name>\", \"confidence\": \"high\"|\"medium\"|\"low\" }",
|
|
44
|
+
"",
|
|
45
|
+
"Rules:",
|
|
46
|
+
"- Use camelCase for variables/functions, PascalCase for classes",
|
|
47
|
+
"- If uncertain, use confidence \"low\"",
|
|
48
|
+
"- If the name is already meaningful, keep it and mark confidence \"high\""
|
|
49
|
+
].join("\n");
|
|
50
|
+
const result = await this.bridge.sampleText({
|
|
51
|
+
systemPrompt: "You are an expert JavaScript reverse engineer. You specialize in deobfuscation and renaming obfuscated identifiers to semantically meaningful names. Output only valid JSON.",
|
|
52
|
+
userMessage,
|
|
53
|
+
maxTokens: 256,
|
|
54
|
+
temperature: .3,
|
|
55
|
+
modelHint: "haiku"
|
|
56
|
+
});
|
|
57
|
+
if (!result) return null;
|
|
58
|
+
return this.parseNameSuggestions(result, trimmedIds);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Use the client's LLM to infer the purpose of a function from its code.
|
|
62
|
+
*
|
|
63
|
+
* @param code - The function's code snippet
|
|
64
|
+
* @returns A brief description of the function's purpose, or null
|
|
65
|
+
*/
|
|
66
|
+
async inferFunctionPurpose(code) {
|
|
67
|
+
if (!this.bridge.isSamplingSupported()) return null;
|
|
68
|
+
const trimmedCode = code.slice(0, MAX_CODE_SNIPPET);
|
|
69
|
+
return (await this.bridge.sampleText({
|
|
70
|
+
systemPrompt: "You are a JavaScript reverse engineer. Analyze code and describe its purpose in one concise sentence.",
|
|
71
|
+
userMessage: `What does this function do?\n\n\`\`\`javascript\n${trimmedCode}\n\`\`\`\n\nRespond with a single sentence.`,
|
|
72
|
+
maxTokens: 100,
|
|
73
|
+
temperature: .2,
|
|
74
|
+
modelHint: "haiku"
|
|
75
|
+
}))?.trim() ?? null;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Parse the LLM's JSON response into structured name suggestions.
|
|
79
|
+
* Robust against malformed output.
|
|
80
|
+
*/
|
|
81
|
+
parseNameSuggestions(rawResponse, expectedIds) {
|
|
82
|
+
try {
|
|
83
|
+
const jsonMatch = rawResponse.match(/\[[\s\S]*\]/);
|
|
84
|
+
if (!jsonMatch) {
|
|
85
|
+
logger.warn("LLMDeobfuscator: no JSON array found in LLM response");
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
89
|
+
if (!Array.isArray(parsed)) return [];
|
|
90
|
+
const expectedSet = new Set(expectedIds);
|
|
91
|
+
return parsed.filter((item) => typeof item === "object" && item !== null && typeof item.original === "string" && typeof item.suggested === "string").filter((item) => expectedSet.has(item.original)).map((item) => ({
|
|
92
|
+
original: item.original,
|
|
93
|
+
suggested: item.suggested,
|
|
94
|
+
confidence: [
|
|
95
|
+
"high",
|
|
96
|
+
"medium",
|
|
97
|
+
"low"
|
|
98
|
+
].includes(item.confidence) ? item.confidence : "low"
|
|
99
|
+
}));
|
|
100
|
+
} catch (error) {
|
|
101
|
+
logger.warn("LLMDeobfuscator: failed to parse LLM response:", error);
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
//#endregion
|
|
107
|
+
//#region src/server/domains/analysis/manifest.ts
|
|
108
|
+
const DOMAIN = "core";
|
|
109
|
+
const DEP_KEY = "coreAnalysisHandlers";
|
|
110
|
+
const t = toolLookup(coreTools);
|
|
111
|
+
let globalContext = null;
|
|
112
|
+
/**
|
|
113
|
+
* Analysis-domain bind helper that threads `_meta.progressToken` into
|
|
114
|
+
* a throttled `onProgress` callback — same pattern as memory/manifest.ts.
|
|
115
|
+
*/
|
|
116
|
+
function bindWithProgress(invoke) {
|
|
117
|
+
return (deps) => {
|
|
118
|
+
const handler = deps[DEP_KEY];
|
|
119
|
+
return (args) => {
|
|
120
|
+
const _meta = args._meta;
|
|
121
|
+
let onProgress;
|
|
122
|
+
if (_meta?.progressToken !== void 0 && globalContext) onProgress = createProgressDebouncer(globalContext.eventBus, _meta.progressToken);
|
|
123
|
+
return invoke(handler, {
|
|
124
|
+
...args,
|
|
125
|
+
onProgress
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const b = bindWithProgress;
|
|
131
|
+
async function ensure(ctx) {
|
|
132
|
+
const { Deobfuscator, AdvancedDeobfuscator, ObfuscationDetector, CodeAnalyzer, CryptoDetector, HookManager } = await import("./modules-C184v-S9.mjs").then((n) => n.t);
|
|
133
|
+
const { CoreAnalysisHandlers } = await import("./analysis-CL9uACt9.mjs");
|
|
134
|
+
globalContext = ctx;
|
|
135
|
+
await ensureBrowserCore(ctx);
|
|
136
|
+
if (!ctx.deobfuscator || !ctx.advancedDeobfuscator || !ctx.obfuscationDetector || !ctx.analyzer || !ctx.cryptoDetector || !ctx.hookManager || !ctx.coreAnalysisHandlers) {
|
|
137
|
+
if (!ctx.deobfuscator) ctx.deobfuscator = new Deobfuscator();
|
|
138
|
+
if (!ctx.advancedDeobfuscator) ctx.advancedDeobfuscator = new AdvancedDeobfuscator();
|
|
139
|
+
if (!ctx.obfuscationDetector) ctx.obfuscationDetector = new ObfuscationDetector();
|
|
140
|
+
if (!ctx.analyzer) ctx.analyzer = new CodeAnalyzer();
|
|
141
|
+
if (!ctx.cryptoDetector) ctx.cryptoDetector = new CryptoDetector();
|
|
142
|
+
if (!ctx.hookManager) ctx.hookManager = new HookManager();
|
|
143
|
+
if (!ctx.coreAnalysisHandlers) ctx.coreAnalysisHandlers = new CoreAnalysisHandlers({
|
|
144
|
+
collector: ctx.collector,
|
|
145
|
+
scriptManager: ctx.scriptManager,
|
|
146
|
+
deobfuscator: ctx.deobfuscator,
|
|
147
|
+
advancedDeobfuscator: ctx.advancedDeobfuscator,
|
|
148
|
+
obfuscationDetector: ctx.obfuscationDetector,
|
|
149
|
+
analyzer: ctx.analyzer,
|
|
150
|
+
cryptoDetector: ctx.cryptoDetector,
|
|
151
|
+
hookManager: ctx.hookManager
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return ctx.coreAnalysisHandlers;
|
|
155
|
+
}
|
|
156
|
+
const manifest = {
|
|
157
|
+
kind: "domain-manifest",
|
|
158
|
+
version: 1,
|
|
159
|
+
domain: DOMAIN,
|
|
160
|
+
depKey: DEP_KEY,
|
|
161
|
+
profiles: ["workflow", "full"],
|
|
162
|
+
ensure,
|
|
163
|
+
workflowRule: {
|
|
164
|
+
patterns: [/(deobfuscate|deobfusc|beautify|analyze).*(javascript|js|script|code)/i, /(反混淆|美化|分析).*(javascript|js|脚本|代码)/i],
|
|
165
|
+
priority: 85,
|
|
166
|
+
tools: [
|
|
167
|
+
"deobfuscate",
|
|
168
|
+
"extract_function_tree",
|
|
169
|
+
"llm_suggest_names"
|
|
170
|
+
],
|
|
171
|
+
hint: "JavaScript analysis workflow: collect -> deobfuscate -> inspect function tree | LLM-powered naming"
|
|
172
|
+
},
|
|
173
|
+
prerequisites: { collect_code: [{
|
|
174
|
+
condition: "Browser must be launched",
|
|
175
|
+
fix: "Call browser_launch or browser_attach first"
|
|
176
|
+
}] },
|
|
177
|
+
registrations: [
|
|
178
|
+
{
|
|
179
|
+
tool: t("collect_code"),
|
|
180
|
+
domain: DOMAIN,
|
|
181
|
+
bind: b((h, a) => h.handleCollectCode(a))
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
tool: t("search_in_scripts"),
|
|
185
|
+
domain: DOMAIN,
|
|
186
|
+
profiles: [
|
|
187
|
+
"search",
|
|
188
|
+
"workflow",
|
|
189
|
+
"full"
|
|
190
|
+
],
|
|
191
|
+
bind: b((h, a) => h.handleSearchInScripts(a))
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
tool: t("extract_function_tree"),
|
|
195
|
+
domain: DOMAIN,
|
|
196
|
+
bind: b((h, a) => h.handleExtractFunctionTree(a))
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
tool: t("deobfuscate"),
|
|
200
|
+
domain: DOMAIN,
|
|
201
|
+
bind: b((h, a) => h.handleDeobfuscate(a))
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
tool: t("understand_code"),
|
|
205
|
+
domain: DOMAIN,
|
|
206
|
+
profiles: [
|
|
207
|
+
"search",
|
|
208
|
+
"workflow",
|
|
209
|
+
"full"
|
|
210
|
+
],
|
|
211
|
+
bind: b((h, a) => h.handleUnderstandCode(a))
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
tool: t("detect_crypto"),
|
|
215
|
+
domain: DOMAIN,
|
|
216
|
+
profiles: [
|
|
217
|
+
"search",
|
|
218
|
+
"workflow",
|
|
219
|
+
"full"
|
|
220
|
+
],
|
|
221
|
+
bind: b((h, a) => h.handleDetectCrypto(a))
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
tool: t("manage_hooks"),
|
|
225
|
+
domain: DOMAIN,
|
|
226
|
+
bind: b((h, a) => h.handleManageHooks(a))
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
tool: t("detect_obfuscation"),
|
|
230
|
+
domain: DOMAIN,
|
|
231
|
+
profiles: [
|
|
232
|
+
"search",
|
|
233
|
+
"workflow",
|
|
234
|
+
"full"
|
|
235
|
+
],
|
|
236
|
+
bind: b((h, a) => h.handleDetectObfuscation(a))
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
tool: t("webcrack_unpack"),
|
|
240
|
+
domain: DOMAIN,
|
|
241
|
+
bind: b((h, a) => h.handleWebcrackUnpack(a))
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
tool: t("clear_collected_data"),
|
|
245
|
+
domain: DOMAIN,
|
|
246
|
+
bind: b((h) => h.handleClearCollectedData())
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
tool: t("get_collection_stats"),
|
|
250
|
+
domain: DOMAIN,
|
|
251
|
+
bind: b((h) => h.handleGetCollectionStats())
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
tool: t("webpack_enumerate"),
|
|
255
|
+
domain: DOMAIN,
|
|
256
|
+
bind: b((h, a) => h.handleWebpackEnumerate(a))
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
tool: t("llm_suggest_names"),
|
|
260
|
+
domain: DOMAIN,
|
|
261
|
+
bind: bindWithProgress(async (_h, args) => {
|
|
262
|
+
if (!globalContext) return { content: [{
|
|
263
|
+
type: "text",
|
|
264
|
+
text: JSON.stringify({
|
|
265
|
+
success: false,
|
|
266
|
+
error: "Server context not initialized"
|
|
267
|
+
})
|
|
268
|
+
}] };
|
|
269
|
+
const deob = new LLMDeobfuscator(globalContext.samplingBridge);
|
|
270
|
+
if (!deob.isAvailable()) return { content: [{
|
|
271
|
+
type: "text",
|
|
272
|
+
text: JSON.stringify({
|
|
273
|
+
success: false,
|
|
274
|
+
error: "Sampling not supported by this client",
|
|
275
|
+
hint: "The connected MCP client does not declare sampling capabilities. Try using Claude Desktop or another sampling-capable client."
|
|
276
|
+
})
|
|
277
|
+
}] };
|
|
278
|
+
const code = typeof args.code === "string" ? args.code : "";
|
|
279
|
+
const identifiers = Array.isArray(args.identifiers) ? args.identifiers.filter((id) => typeof id === "string") : [];
|
|
280
|
+
const suggestions = await deob.suggestVariableNames(code, identifiers);
|
|
281
|
+
return { content: [{
|
|
282
|
+
type: "text",
|
|
283
|
+
text: JSON.stringify({
|
|
284
|
+
success: true,
|
|
285
|
+
suggestions: suggestions ?? [],
|
|
286
|
+
samplingUsed: true
|
|
287
|
+
})
|
|
288
|
+
}] };
|
|
289
|
+
})
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
};
|
|
293
|
+
//#endregion
|
|
294
|
+
export { manifest as default };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { n as toolLookup } from "./registry-D-6e18lB.mjs";
|
|
2
|
+
import { t as bindByDepKey } from "./bind-helpers-xFfRF-qm.mjs";
|
|
3
|
+
import { t as transformTools } from "./definitions-Cq-zroAU.mjs";
|
|
4
|
+
//#region src/server/domains/transform/manifest.ts
|
|
5
|
+
const DOMAIN = "transform";
|
|
6
|
+
const DEP_KEY = "transformHandlers";
|
|
7
|
+
const t = toolLookup(transformTools);
|
|
8
|
+
const b = (invoke) => bindByDepKey(DEP_KEY, invoke);
|
|
9
|
+
async function ensure(ctx) {
|
|
10
|
+
const { CodeCollector } = await import("./modules-C184v-S9.mjs").then((n) => n.t);
|
|
11
|
+
const { TransformToolHandlers } = await import("./transform-CiYJfNX0.mjs");
|
|
12
|
+
if (!ctx.collector) {
|
|
13
|
+
ctx.collector = new CodeCollector(ctx.config.puppeteer);
|
|
14
|
+
ctx.registerCaches();
|
|
15
|
+
}
|
|
16
|
+
if (!ctx.transformHandlers) ctx.transformHandlers = new TransformToolHandlers(ctx.collector);
|
|
17
|
+
return ctx.transformHandlers;
|
|
18
|
+
}
|
|
19
|
+
const manifest = {
|
|
20
|
+
kind: "domain-manifest",
|
|
21
|
+
version: 1,
|
|
22
|
+
domain: DOMAIN,
|
|
23
|
+
depKey: DEP_KEY,
|
|
24
|
+
profiles: ["full"],
|
|
25
|
+
ensure,
|
|
26
|
+
registrations: [
|
|
27
|
+
{
|
|
28
|
+
tool: t("ast_transform_preview"),
|
|
29
|
+
domain: DOMAIN,
|
|
30
|
+
bind: b((h, a) => h.handleAstTransformPreview(a))
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
tool: t("ast_transform_chain"),
|
|
34
|
+
domain: DOMAIN,
|
|
35
|
+
bind: b((h, a) => h.handleAstTransformChain(a))
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
tool: t("ast_transform_apply"),
|
|
39
|
+
domain: DOMAIN,
|
|
40
|
+
bind: b((h, a) => h.handleAstTransformApply(a))
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
tool: t("crypto_extract_standalone"),
|
|
44
|
+
domain: DOMAIN,
|
|
45
|
+
bind: b((h, a) => h.handleCryptoExtractStandalone(a))
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
tool: t("crypto_test_harness"),
|
|
49
|
+
domain: DOMAIN,
|
|
50
|
+
bind: b((h, a) => h.handleCryptoTestHarness(a))
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
tool: t("crypto_compare"),
|
|
54
|
+
domain: DOMAIN,
|
|
55
|
+
bind: b((h, a) => h.handleCryptoCompare(a))
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
export { manifest as default };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { n as toolLookup } from "./registry-D-6e18lB.mjs";
|
|
2
|
+
import { t as bindByDepKey } from "./bind-helpers-xFfRF-qm.mjs";
|
|
3
|
+
import { t as encodingTools } from "./definitions-D3VsGcvz.mjs";
|
|
4
|
+
//#region src/server/domains/encoding/manifest.ts
|
|
5
|
+
const DOMAIN = "encoding";
|
|
6
|
+
const DEP_KEY = "encodingHandlers";
|
|
7
|
+
const t = toolLookup(encodingTools);
|
|
8
|
+
const b = (invoke) => bindByDepKey(DEP_KEY, invoke);
|
|
9
|
+
async function ensure(ctx) {
|
|
10
|
+
const { CodeCollector } = await import("./modules-C184v-S9.mjs").then((n) => n.t);
|
|
11
|
+
const { EncodingToolHandlers } = await import("./encoding-Bvz5jLRv.mjs");
|
|
12
|
+
if (!ctx.collector) {
|
|
13
|
+
ctx.collector = new CodeCollector(ctx.config.puppeteer);
|
|
14
|
+
ctx.registerCaches();
|
|
15
|
+
}
|
|
16
|
+
if (!ctx.encodingHandlers) ctx.encodingHandlers = new EncodingToolHandlers(ctx.collector);
|
|
17
|
+
return ctx.encodingHandlers;
|
|
18
|
+
}
|
|
19
|
+
const manifest = {
|
|
20
|
+
kind: "domain-manifest",
|
|
21
|
+
version: 1,
|
|
22
|
+
domain: DOMAIN,
|
|
23
|
+
depKey: DEP_KEY,
|
|
24
|
+
profiles: ["workflow", "full"],
|
|
25
|
+
ensure,
|
|
26
|
+
registrations: [
|
|
27
|
+
{
|
|
28
|
+
tool: t("binary_detect_format"),
|
|
29
|
+
domain: DOMAIN,
|
|
30
|
+
bind: b((h, a) => h.handleBinaryDetectFormat(a))
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
tool: t("binary_decode"),
|
|
34
|
+
domain: DOMAIN,
|
|
35
|
+
bind: b((h, a) => h.handleBinaryDecode(a))
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
tool: t("binary_encode"),
|
|
39
|
+
domain: DOMAIN,
|
|
40
|
+
bind: b((h, a) => h.handleBinaryEncode(a))
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
tool: t("binary_entropy_analysis"),
|
|
44
|
+
domain: DOMAIN,
|
|
45
|
+
bind: b((h, a) => h.handleBinaryEntropyAnalysis(a))
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
tool: t("protobuf_decode_raw"),
|
|
49
|
+
domain: DOMAIN,
|
|
50
|
+
bind: b((h, a) => h.handleProtobufDecodeRaw(a))
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
};
|
|
54
|
+
//#endregion
|
|
55
|
+
export { manifest as default };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { n as asJsonResponse } from "./response-BQVP-xUn.mjs";
|
|
2
|
+
import { n as toolLookup } from "./registry-D-6e18lB.mjs";
|
|
3
|
+
import { t as bindByDepKey } from "./bind-helpers-xFfRF-qm.mjs";
|
|
4
|
+
const skiaTools = [
|
|
5
|
+
{
|
|
6
|
+
name: "skia_detect_renderer",
|
|
7
|
+
description: "Detect the active Skia renderer backend from the current page context.",
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {},
|
|
11
|
+
required: []
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: "skia_extract_scene",
|
|
16
|
+
description: "Extract a lightweight Skia scene tree from the selected canvas.",
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: { canvasId: { type: "string" } },
|
|
20
|
+
required: []
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: "skia_correlate_objects",
|
|
25
|
+
description: "Correlate requested Skia node identifiers with the extracted scene tree.",
|
|
26
|
+
inputSchema: {
|
|
27
|
+
type: "object",
|
|
28
|
+
properties: {
|
|
29
|
+
canvasId: {
|
|
30
|
+
type: "string",
|
|
31
|
+
description: "Optional canvas element ID to target for correlation."
|
|
32
|
+
},
|
|
33
|
+
skiaNodeIds: {
|
|
34
|
+
type: "array",
|
|
35
|
+
items: { type: "string" },
|
|
36
|
+
description: "Optional list of Skia node identifiers to correlate."
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
required: []
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/server/domains/skia-capture/manifest.ts
|
|
45
|
+
const DOMAIN = "skia-capture";
|
|
46
|
+
const DEP_KEY = "skiaCaptureHandlers";
|
|
47
|
+
const PROFILES = ["workflow", "full"];
|
|
48
|
+
const lookup = toolLookup(skiaTools);
|
|
49
|
+
const bind = (invoke) => bindByDepKey(DEP_KEY, async (handler, args) => {
|
|
50
|
+
return asJsonResponse(await invoke(handler, args));
|
|
51
|
+
});
|
|
52
|
+
async function ensure(ctx) {
|
|
53
|
+
const { SkiaCaptureHandlers } = await import("./handlers-CTsDAO6p.mjs");
|
|
54
|
+
const existing = ctx.getDomainInstance(DEP_KEY);
|
|
55
|
+
if (existing) return existing;
|
|
56
|
+
const handlers = new SkiaCaptureHandlers({
|
|
57
|
+
pageController: ctx.pageController ?? null,
|
|
58
|
+
eventBus: ctx.eventBus
|
|
59
|
+
});
|
|
60
|
+
ctx.setDomainInstance(DEP_KEY, handlers);
|
|
61
|
+
return handlers;
|
|
62
|
+
}
|
|
63
|
+
const manifest = {
|
|
64
|
+
kind: "domain-manifest",
|
|
65
|
+
version: 1,
|
|
66
|
+
domain: DOMAIN,
|
|
67
|
+
depKey: DEP_KEY,
|
|
68
|
+
profiles: PROFILES,
|
|
69
|
+
registrations: [
|
|
70
|
+
{
|
|
71
|
+
tool: lookup("skia_detect_renderer"),
|
|
72
|
+
domain: DOMAIN,
|
|
73
|
+
bind: bind((handler, args) => handler.handleSkiaDetectRenderer(args))
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
tool: lookup("skia_extract_scene"),
|
|
77
|
+
domain: DOMAIN,
|
|
78
|
+
bind: bind((handler, args) => handler.handleSkiaExtractScene(args))
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
tool: lookup("skia_correlate_objects"),
|
|
82
|
+
domain: DOMAIN,
|
|
83
|
+
bind: bind((handler, args) => handler.handleSkiaCorrelateObjects(args))
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
ensure,
|
|
87
|
+
workflowRule: {
|
|
88
|
+
patterns: [
|
|
89
|
+
/\b(skia|gpu|render(er)?|scene\s?(tree|graph)|draw\s?call|raster|paint|layer)\b/i,
|
|
90
|
+
/skia.*(render|detect|scene)/i,
|
|
91
|
+
/canvas.*skia/i,
|
|
92
|
+
/gpu.*backend/i
|
|
93
|
+
],
|
|
94
|
+
priority: 78,
|
|
95
|
+
tools: [
|
|
96
|
+
"skia_detect_renderer",
|
|
97
|
+
"skia_extract_scene",
|
|
98
|
+
"skia_correlate_objects"
|
|
99
|
+
],
|
|
100
|
+
hint: "Skia pipeline analysis: detect GPU backend → dump scene tree → correlate with JS objects."
|
|
101
|
+
},
|
|
102
|
+
prerequisites: {
|
|
103
|
+
skia_detect_renderer: [{
|
|
104
|
+
condition: "Browser must be running with CDP attached",
|
|
105
|
+
fix: "Call browser_launch or browser_attach first"
|
|
106
|
+
}],
|
|
107
|
+
skia_extract_scene: [{
|
|
108
|
+
condition: "Browser must be running with CDP attached",
|
|
109
|
+
fix: "Call browser_launch or browser_attach first"
|
|
110
|
+
}],
|
|
111
|
+
skia_correlate_objects: [{
|
|
112
|
+
condition: "V8 heap snapshot should be available for robust matching",
|
|
113
|
+
fix: "Run v8_heap_snapshot_capture before correlation"
|
|
114
|
+
}]
|
|
115
|
+
},
|
|
116
|
+
toolDependencies: [{
|
|
117
|
+
from: "canvas",
|
|
118
|
+
to: "skia-capture",
|
|
119
|
+
relation: "uses",
|
|
120
|
+
weight: .9
|
|
121
|
+
}, {
|
|
122
|
+
from: "skia_correlate_objects",
|
|
123
|
+
to: "v8_heap_snapshot_capture",
|
|
124
|
+
relation: "precedes",
|
|
125
|
+
weight: .6
|
|
126
|
+
}]
|
|
127
|
+
};
|
|
128
|
+
//#endregion
|
|
129
|
+
export { manifest as default };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { n as toolLookup } from "./registry-D-6e18lB.mjs";
|
|
2
|
+
import { t as bindByDepKey } from "./bind-helpers-xFfRF-qm.mjs";
|
|
3
|
+
import { t as tool } from "./tool-builder-DCbIC5Eo.mjs";
|
|
4
|
+
//#region src/server/domains/trace/definitions.tools.ts
|
|
5
|
+
const TRACE_TOOLS = [
|
|
6
|
+
tool("trace_recording", (t) => t.desc("Start or stop time-travel trace recording into a SQLite database.\n\nRecording captures events from Debugger, Runtime, Network, Page, and EventBus.\nUse action=\"stop\" to finalize and get a session summary.").enum("action", ["start", "stop"], "Recording action").array("cdpDomains", { type: "string" }, "CDP domains to record (action=start, default: Debugger, Runtime, Network, Page)").boolean("recordMemoryDeltas", "Record memory write deltas (action=start)", { default: true }).required("action").idempotent()),
|
|
7
|
+
tool("query_trace_sql", (t) => t.desc("Execute a read-only SQL query against a trace database.\n\nAvailable tables:\n- events(id, timestamp, category, event_type, data, script_id, line_number)\n- memory_deltas(id, timestamp, address, old_value, new_value, size, value_type)\n- heap_snapshots(id, timestamp, snapshot_data, summary)\n- metadata(key, value)\n\nReturns columns, rows, and row count.\n\nExamples:\nquery_trace_sql(sql=\"SELECT * FROM events WHERE category='debugger' ORDER BY timestamp\")\nquery_trace_sql(sql=\"SELECT address, COUNT(*) as writes FROM memory_deltas GROUP BY address ORDER BY writes DESC LIMIT 10\")\nquery_trace_sql(sql=\"SELECT * FROM events WHERE timestamp BETWEEN 1000 AND 2000\", dbPath=\"artifacts/traces/my-trace.db\")").string("sql", "SQL query to execute (SELECT only — write operations are rejected)").string("dbPath", "Path to trace DB file. Uses the active recording if omitted.").required("sql").query()),
|
|
8
|
+
tool("seek_to_timestamp", (t) => t.desc("Reconstruct application state at a specific timestamp from a recorded trace.\n\nReturns a structured snapshot including:\n- Events near the timestamp\n- Debugger state (last pause, call stack)\n- Memory state (latest values per address)\n- Network state (completed requests)\n- Nearest heap snapshot\n\nExamples:\nseek_to_timestamp(timestamp=1711000000000)\nseek_to_timestamp(timestamp=1711000000000, windowMs=500)\nseek_to_timestamp(timestamp=1711000000000, dbPath=\"artifacts/traces/my-trace.db\")").number("timestamp", "Target timestamp in milliseconds since epoch").string("dbPath", "Path to trace DB file. Uses the active recording if omitted.").number("windowMs", "Time window around timestamp to include in ms", { default: 100 }).required("timestamp").query()),
|
|
9
|
+
tool("diff_heap_snapshots", (t) => t.desc("Compare two heap snapshots from a trace and return the differences.\n\nShows:\n- New object types (in snapshot 2 but not 1)\n- Deleted object types (in snapshot 1 but not 2)\n- Changed objects (count or size differs)\n- Total size delta\n\nUseful for identifying state changes in obfuscated code.\n\nExamples:\ndiff_heap_snapshots(snapshotId1=1, snapshotId2=2)\ndiff_heap_snapshots(snapshotId1=1, snapshotId2=3, dbPath=\"artifacts/traces/my-trace.db\")").number("snapshotId1", "First snapshot ID (earlier)").number("snapshotId2", "Second snapshot ID (later)").string("dbPath", "Path to trace DB file. Uses the active recording if omitted.").required("snapshotId1", "snapshotId2").query()),
|
|
10
|
+
tool("export_trace", (t) => t.desc("Export a trace database to Chrome Trace Event JSON format.\n\nThe resulting file can be loaded in:\n- chrome://tracing\n- Perfetto UI (ui.perfetto.dev)\n\nMaps events to the standard trace event format with name, category, phase, timestamp.\n\nExamples:\nexport_trace()\nexport_trace(dbPath=\"artifacts/traces/my-trace.db\")\nexport_trace(outputPath=\"my-export.json\")").string("dbPath", "Path to trace DB file. Uses the active recording if omitted.").string("outputPath", "Output JSON file path. Auto-generated if omitted.").idempotent()),
|
|
11
|
+
tool("summarize_trace", (t) => t.desc("Generate a compact, LLM-friendly summary of a trace database.\n\nAvoids sending raw trace data that may exceed context windows. Three detail levels:\n- compact: category aggregation + timeline overview (~10% of raw size)\n- balanced: compact + key moments (breakpoints, exceptions, network completions) [DEFAULT]\n- full: passthrough — returns all events without compression\n\nAlso detects memory anomalies: addresses with significantly more writes than average.\n\nExamples:\nsummarize_trace()\nsummarize_trace(detail=\"compact\")\nsummarize_trace(detail=\"balanced\", dbPath=\"artifacts/traces/my-trace.db\")").enum("detail", [
|
|
12
|
+
"compact",
|
|
13
|
+
"balanced",
|
|
14
|
+
"full"
|
|
15
|
+
], "Summary detail level", { default: "balanced" }).string("dbPath", "Path to trace DB file. Uses the active recording if omitted.").query())
|
|
16
|
+
];
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/server/domains/trace/manifest.ts
|
|
19
|
+
const DOMAIN = "trace";
|
|
20
|
+
const DEP_KEY = "traceHandlers";
|
|
21
|
+
const t = toolLookup(TRACE_TOOLS);
|
|
22
|
+
const b = (invoke) => bindByDepKey(DEP_KEY, invoke);
|
|
23
|
+
async function ensure(ctx) {
|
|
24
|
+
const { TraceRecorder } = await import("./TraceRecorder-DgxyVbdQ.mjs");
|
|
25
|
+
const { TraceToolHandlers } = await import("./handlers-DdFzXLvF.mjs");
|
|
26
|
+
if (!ctx.traceRecorder || !ctx.traceHandlers) {
|
|
27
|
+
if (!ctx.traceRecorder) ctx.traceRecorder = new TraceRecorder();
|
|
28
|
+
if (!ctx.traceHandlers) ctx.traceHandlers = new TraceToolHandlers(ctx.traceRecorder, ctx);
|
|
29
|
+
}
|
|
30
|
+
return ctx.traceHandlers;
|
|
31
|
+
}
|
|
32
|
+
const manifest = {
|
|
33
|
+
kind: "domain-manifest",
|
|
34
|
+
version: 1,
|
|
35
|
+
domain: DOMAIN,
|
|
36
|
+
depKey: DEP_KEY,
|
|
37
|
+
profiles: ["full"],
|
|
38
|
+
ensure,
|
|
39
|
+
prerequisites: {},
|
|
40
|
+
workflowRule: {
|
|
41
|
+
patterns: [
|
|
42
|
+
/trace/i,
|
|
43
|
+
/time.?travel/i,
|
|
44
|
+
/replay/i,
|
|
45
|
+
/recorded?\s+events?/i
|
|
46
|
+
],
|
|
47
|
+
priority: 70,
|
|
48
|
+
tools: [
|
|
49
|
+
"trace_recording",
|
|
50
|
+
"query_trace_sql",
|
|
51
|
+
"seek_to_timestamp",
|
|
52
|
+
"diff_heap_snapshots",
|
|
53
|
+
"export_trace",
|
|
54
|
+
"summarize_trace"
|
|
55
|
+
],
|
|
56
|
+
hint: "Start recording → perform actions → stop recording → summarize/query/seek/diff/export"
|
|
57
|
+
},
|
|
58
|
+
registrations: [
|
|
59
|
+
{
|
|
60
|
+
tool: t("trace_recording"),
|
|
61
|
+
domain: DOMAIN,
|
|
62
|
+
bind: b((h, a) => h.handleTraceRecording(a))
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
tool: t("query_trace_sql"),
|
|
66
|
+
domain: DOMAIN,
|
|
67
|
+
bind: b((h, a) => h.handleQueryTraceSql(a))
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
tool: t("seek_to_timestamp"),
|
|
71
|
+
domain: DOMAIN,
|
|
72
|
+
bind: b((h, a) => h.handleSeekToTimestamp(a))
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
tool: t("diff_heap_snapshots"),
|
|
76
|
+
domain: DOMAIN,
|
|
77
|
+
bind: b((h, a) => h.handleDiffHeapSnapshots(a))
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
tool: t("export_trace"),
|
|
81
|
+
domain: DOMAIN,
|
|
82
|
+
bind: b((h, a) => h.handleExportTrace(a))
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
tool: t("summarize_trace"),
|
|
86
|
+
domain: DOMAIN,
|
|
87
|
+
bind: b((h, a) => h.handleSummarizeTrace(a))
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
};
|
|
91
|
+
//#endregion
|
|
92
|
+
export { manifest as default };
|