memorydetective 1.8.1 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -1
- package/README.md +75 -9
- package/USAGE.md +27 -4
- package/dist/cli.js +106 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.js +42 -22
- package/dist/index.js.map +1 -1
- package/dist/parsers/referenceTree.d.ts +73 -0
- package/dist/parsers/referenceTree.js +145 -0
- package/dist/parsers/referenceTree.js.map +1 -0
- package/dist/runtime/axe.js +6 -1
- package/dist/runtime/axe.js.map +1 -1
- package/dist/runtime/exec.d.ts +30 -0
- package/dist/runtime/exec.js +30 -3
- package/dist/runtime/exec.js.map +1 -1
- package/dist/runtime/fixTemplates.js +67 -0
- package/dist/runtime/fixTemplates.js.map +1 -1
- package/dist/runtime/leakReport.d.ts +62 -0
- package/dist/runtime/leakReport.js +138 -0
- package/dist/runtime/leakReport.js.map +1 -0
- package/dist/runtime/platformCheck.d.ts +54 -0
- package/dist/runtime/platformCheck.js +94 -0
- package/dist/runtime/platformCheck.js.map +1 -0
- package/dist/runtime/redact.d.ts +66 -0
- package/dist/runtime/redact.js +146 -0
- package/dist/runtime/redact.js.map +1 -0
- package/dist/runtime/responseFormatter.d.ts +55 -0
- package/dist/runtime/responseFormatter.js +200 -0
- package/dist/runtime/responseFormatter.js.map +1 -0
- package/dist/runtime/securityFlags.d.ts +74 -0
- package/dist/runtime/securityFlags.js +90 -0
- package/dist/runtime/securityFlags.js.map +1 -0
- package/dist/runtime/staticAnalysisHints.js +14 -1
- package/dist/runtime/staticAnalysisHints.js.map +1 -1
- package/dist/templates/leak-report.html +39 -0
- package/dist/templates/templates/leak-report.html +39 -0
- package/dist/tools/analyzeAbandonedMemory.d.ts +140 -0
- package/dist/tools/analyzeAbandonedMemory.js +287 -0
- package/dist/tools/analyzeAbandonedMemory.js.map +1 -0
- package/dist/tools/analyzeAllocations.d.ts +11 -2
- package/dist/tools/analyzeAllocations.js +4 -0
- package/dist/tools/analyzeAllocations.js.map +1 -1
- package/dist/tools/analyzeAnimationHitches.d.ts +32 -2
- package/dist/tools/analyzeAnimationHitches.js +25 -4
- package/dist/tools/analyzeAnimationHitches.js.map +1 -1
- package/dist/tools/analyzeAppLaunch.d.ts +3 -0
- package/dist/tools/analyzeAppLaunch.js +2 -0
- package/dist/tools/analyzeAppLaunch.js.map +1 -1
- package/dist/tools/analyzeHangs.d.ts +78 -2
- package/dist/tools/analyzeHangs.js +117 -4
- package/dist/tools/analyzeHangs.js.map +1 -1
- package/dist/tools/analyzeMemgraph.d.ts +21 -1
- package/dist/tools/analyzeMemgraph.js +52 -2
- package/dist/tools/analyzeMemgraph.js.map +1 -1
- package/dist/tools/analyzeTimeProfile.d.ts +11 -1
- package/dist/tools/analyzeTimeProfile.js +5 -0
- package/dist/tools/analyzeTimeProfile.js.map +1 -1
- package/dist/tools/bootAndLaunchForLeakInvestigation.d.ts +18 -9
- package/dist/tools/bootAndLaunchForLeakInvestigation.js +27 -0
- package/dist/tools/bootAndLaunchForLeakInvestigation.js.map +1 -1
- package/dist/tools/captureMemgraph.d.ts +22 -4
- package/dist/tools/captureMemgraph.js +42 -9
- package/dist/tools/captureMemgraph.js.map +1 -1
- package/dist/tools/captureScenarioState.d.ts +12 -4
- package/dist/tools/captureScenarioState.js +4 -0
- package/dist/tools/captureScenarioState.js.map +1 -1
- package/dist/tools/classifyCycle.js +77 -0
- package/dist/tools/classifyCycle.js.map +1 -1
- package/dist/tools/cleanupTraces.d.ts +87 -0
- package/dist/tools/cleanupTraces.js +232 -0
- package/dist/tools/cleanupTraces.js.map +1 -0
- package/dist/tools/compareTracesByPattern.d.ts +2 -2
- package/dist/tools/detectLeaksInXCTest.d.ts +116 -0
- package/dist/tools/detectLeaksInXCTest.js +311 -0
- package/dist/tools/detectLeaksInXCTest.js.map +1 -0
- package/dist/tools/detectLeaksInXCUITest.d.ts +8 -3
- package/dist/tools/detectLeaksInXCUITest.js +30 -4
- package/dist/tools/detectLeaksInXCUITest.js.map +1 -1
- package/dist/tools/diffMemgraphs.d.ts +5 -2
- package/dist/tools/diffMemgraphs.js +2 -0
- package/dist/tools/diffMemgraphs.js.map +1 -1
- package/dist/tools/findCycles.d.ts +1 -1
- package/dist/tools/recordTimeProfile.d.ts +29 -9
- package/dist/tools/recordTimeProfile.js +70 -7
- package/dist/tools/recordTimeProfile.js.map +1 -1
- package/dist/tools/renderCycleGraph.d.ts +1 -1
- package/dist/tools/verifyFix.d.ts +2 -2
- package/dist/types.d.ts +24 -1
- package/package.json +3 -3
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
3
|
-
import { resolve as resolvePath, dirname } from "node:path";
|
|
2
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { resolve as resolvePath, dirname, isAbsolute as isAbsolutePath, join as joinPath, } from "node:path";
|
|
4
4
|
import { runCommand } from "../runtime/exec.js";
|
|
5
|
+
import { getSecurityFlags, maxRecordingExceededMessage, } from "../runtime/securityFlags.js";
|
|
5
6
|
/**
|
|
6
|
-
* Base shape
|
|
7
|
+
* Base shape, exposed so the MCP layer can read `.shape` (ZodEffects from
|
|
7
8
|
* `.superRefine()` doesn't expose shape).
|
|
8
9
|
*/
|
|
9
10
|
export const recordTimeProfileShape = {
|
|
@@ -70,6 +71,26 @@ export const recordTimeProfileSchema = z
|
|
|
70
71
|
});
|
|
71
72
|
}
|
|
72
73
|
});
|
|
74
|
+
const XCTRACE_TIMEOUT_MESSAGE = "xctrace did not exit when `--time-limit` elapsed (a known regression on some macOS 26.x simulators). memorydetective sent SIGINT after a grace window and waited up to 10s for xctrace to flush the trace cleanly. The `.trace` bundle at `output` may still be readable; if `analyzeTimeProfile` later reports a missing-template export error, the SIGKILL escalation fired before the flush completed and the trace is partial.";
|
|
75
|
+
const XCTRACE_TIMEOUT_FALLBACKS = [
|
|
76
|
+
"Try recording on an iOS 18 simulator runtime, which does not exhibit the `--time-limit` ignore bug.",
|
|
77
|
+
"Shorten `durationSec` to 30s or less; the ignore behavior is more common on long recordings.",
|
|
78
|
+
"If `analyzeTimeProfile` fails on the partial `.trace`, re-record after restarting the simulator (`xcrun simctl shutdown <udid> && xcrun simctl boot <udid>`).",
|
|
79
|
+
];
|
|
80
|
+
/**
|
|
81
|
+
* Grace window beyond `--time-limit` before the wrapper SIGINTs xctrace.
|
|
82
|
+
* 30s matches the budget used by `analyzeTimeProfile` for export overhead
|
|
83
|
+
* and keeps the loop responsive when xctrace IS respecting the time limit.
|
|
84
|
+
*/
|
|
85
|
+
const XCTRACE_TIMEOUT_GRACE_SEC = 30;
|
|
86
|
+
/**
|
|
87
|
+
* Time to wait for xctrace to flush the trace after SIGINT before escalating
|
|
88
|
+
* to SIGKILL. 10s is generous: xctrace's normal post-`--time-limit` shutdown
|
|
89
|
+
* takes 2-5 seconds in practice. SIGKILL leaves the trace partial (missing
|
|
90
|
+
* template metadata), but is the only way to guarantee the wrapper unblocks
|
|
91
|
+
* when xctrace is wedged.
|
|
92
|
+
*/
|
|
93
|
+
const XCTRACE_GRACEFUL_KILL_MS = 10_000;
|
|
73
94
|
/** Pure: build the xctrace argv for the given input. Exposed for testing. */
|
|
74
95
|
export function buildXctraceArgs(input) {
|
|
75
96
|
const args = ["xctrace", "record", "--template", input.template];
|
|
@@ -89,16 +110,58 @@ export function buildXctraceArgs(input) {
|
|
|
89
110
|
return args;
|
|
90
111
|
}
|
|
91
112
|
export async function recordTimeProfile(input) {
|
|
92
|
-
const
|
|
113
|
+
const security = getSecurityFlags();
|
|
114
|
+
// Cap the recording duration so an unattended agent does not pile up
|
|
115
|
+
// multi-GB traces. Default cap is 300s (5 min); override via
|
|
116
|
+
// MEMORYDETECTIVE_MAX_RECORDING_SECONDS, capped at 3600s.
|
|
117
|
+
if (input.durationSec > security.maxRecordingSeconds) {
|
|
118
|
+
throw new Error(maxRecordingExceededMessage(input.durationSec, security.maxRecordingSeconds));
|
|
119
|
+
}
|
|
120
|
+
// Resolve the output path against TRACE_ROOT when relative, so the
|
|
121
|
+
// default behavior places traces in a predictable location that
|
|
122
|
+
// cleanup_traces can manage. Absolute paths are preserved verbatim
|
|
123
|
+
// for backwards compat with v1.8 callers that always passed absolute.
|
|
124
|
+
const output = isAbsolutePath(input.output)
|
|
125
|
+
? resolvePath(input.output)
|
|
126
|
+
: joinPath(security.traceRoot, input.output);
|
|
93
127
|
const outDir = dirname(output);
|
|
94
128
|
if (!existsSync(outDir)) {
|
|
95
|
-
|
|
129
|
+
// Auto-create the directory for the TRACE_ROOT case so first-time
|
|
130
|
+
// users do not have to mkdir manually. Same behavior whether the
|
|
131
|
+
// path came from TRACE_ROOT or was an absolute path to a missing
|
|
132
|
+
// parent.
|
|
133
|
+
mkdirSync(outDir, { recursive: true });
|
|
96
134
|
}
|
|
97
135
|
const args = buildXctraceArgs({ ...input, output });
|
|
136
|
+
// External timeout wrapper. xctrace itself receives `--time-limit Ns`, so
|
|
137
|
+
// the normal exit path is xctrace finishing on its own at N seconds. The
|
|
138
|
+
// wrapper here is a safety net for the macOS 26.x sim regression where
|
|
139
|
+
// xctrace ignores `--time-limit` and runs indefinitely. We give it a
|
|
140
|
+
// 30s grace beyond its own deadline, then SIGINT (so it flushes the
|
|
141
|
+
// trace), then escalate to SIGKILL after 10s if it is still wedged.
|
|
142
|
+
// SIGTERM specifically corrupts xctrace's output, so we never use it
|
|
143
|
+
// here.
|
|
98
144
|
const result = await runCommand("xcrun", args, {
|
|
99
|
-
|
|
100
|
-
|
|
145
|
+
timeoutMs: (input.durationSec + XCTRACE_TIMEOUT_GRACE_SEC) * 1_000,
|
|
146
|
+
timeoutSignal: "SIGINT",
|
|
147
|
+
gracefulKillAfterMs: XCTRACE_GRACEFUL_KILL_MS,
|
|
101
148
|
});
|
|
149
|
+
if (result.timedOut) {
|
|
150
|
+
return {
|
|
151
|
+
ok: false,
|
|
152
|
+
command: `xcrun ${args.join(" ")}`,
|
|
153
|
+
output,
|
|
154
|
+
durationSec: input.durationSec,
|
|
155
|
+
template: input.template,
|
|
156
|
+
stderr: result.stderr || undefined,
|
|
157
|
+
recordingTimedOut: true,
|
|
158
|
+
workaroundNotice: {
|
|
159
|
+
issue: "xctrace-time-limit-ignored",
|
|
160
|
+
message: XCTRACE_TIMEOUT_MESSAGE,
|
|
161
|
+
fallbacks: XCTRACE_TIMEOUT_FALLBACKS,
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
|
102
165
|
if (result.code !== 0) {
|
|
103
166
|
throw new Error(`xctrace record failed (code ${result.code}): ${result.stderr || result.stdout}`);
|
|
104
167
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recordTimeProfile.js","sourceRoot":"","sources":["../../src/tools/recordTimeProfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"recordTimeProfile.js","sourceRoot":"","sources":["../../src/tools/recordTimeProfile.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,8 +7,8 @@ export declare const renderCycleGraphSchema: z.ZodObject<{
|
|
|
7
7
|
maxDepth: z.ZodDefault<z.ZodNumber>;
|
|
8
8
|
truncateClassName: z.ZodDefault<z.ZodNumber>;
|
|
9
9
|
}, "strip", z.ZodTypeAny, {
|
|
10
|
-
maxDepth: number;
|
|
11
10
|
path: string;
|
|
11
|
+
maxDepth: number;
|
|
12
12
|
cycleIndex: number;
|
|
13
13
|
format: "mermaid" | "dot";
|
|
14
14
|
truncateClassName: number;
|
|
@@ -20,12 +20,12 @@ export declare const verifyFixSchema: z.ZodObject<{
|
|
|
20
20
|
verbosity: z.ZodDefault<z.ZodEnum<["compact", "normal", "full"]>>;
|
|
21
21
|
}, "strip", z.ZodTypeAny, {
|
|
22
22
|
verbosity: "compact" | "normal" | "full";
|
|
23
|
-
before: string;
|
|
24
23
|
after: string;
|
|
24
|
+
before: string;
|
|
25
25
|
expectedPatternId?: string | undefined;
|
|
26
26
|
}, {
|
|
27
|
-
before: string;
|
|
28
27
|
after: string;
|
|
28
|
+
before: string;
|
|
29
29
|
verbosity?: "compact" | "normal" | "full" | undefined;
|
|
30
30
|
expectedPatternId?: string | undefined;
|
|
31
31
|
}>;
|
package/dist/types.d.ts
CHANGED
|
@@ -52,11 +52,34 @@ export interface LeaksReport {
|
|
|
52
52
|
/** True if the report contains zero ROOT CYCLE entries (independent of leakCount, since plain leaks may exist). */
|
|
53
53
|
hasNoCycles: boolean;
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Disambiguation of why a data section is empty or missing on a tool
|
|
57
|
+
* response. Replaces the older convention of "empty = no data found" which
|
|
58
|
+
* collapses three very different cases together.
|
|
59
|
+
*
|
|
60
|
+
* - `available`: data was exported and parsed. Empty arrays under this status
|
|
61
|
+
* mean the trace genuinely had no rows for the section (e.g. no hang
|
|
62
|
+
* events during the recording window).
|
|
63
|
+
* - `partial`: export started but did not finish. Typical cause is the Phase
|
|
64
|
+
* 1.4 xctrace timeout wrapper firing on a wedged recording. The data in
|
|
65
|
+
* the response is a partial snapshot of what was flushed.
|
|
66
|
+
* - `not_exportable`: a GUI track exists in Instruments.app but `xcrun
|
|
67
|
+
* xctrace export` has no exportable table schema for it on this OS. This
|
|
68
|
+
* is an Apple-side limitation; the only recovery is to use Instruments.app
|
|
69
|
+
* directly for that data family. Surfaced specifically so the agent does
|
|
70
|
+
* not branch on "empty" as "no problem".
|
|
71
|
+
* - `not_present`: the requested table schema is simply not in the trace
|
|
72
|
+
* bundle. Either the recording did not include that instrument template,
|
|
73
|
+
* or the section is genuinely empty at the trace-bundle level. Different
|
|
74
|
+
* from `not_exportable` because the data does not exist in the trace at
|
|
75
|
+
* all, not just "exists but cannot be read".
|
|
76
|
+
*/
|
|
77
|
+
export type DataStatus = "available" | "partial" | "not_exportable" | "not_present";
|
|
55
78
|
/**
|
|
56
79
|
* HATEOAS-style hint that an LLM agent can chain after the current tool's
|
|
57
80
|
* result. We pre-populate `args` from the current response so the agent can
|
|
58
81
|
* call the next tool with one fewer inference step. The agent is free to
|
|
59
|
-
* adapt or ignore
|
|
82
|
+
* adapt or ignore. These are suggestions, not commands.
|
|
60
83
|
*/
|
|
61
84
|
export interface NextCallSuggestion {
|
|
62
85
|
/** Name of the tool to call next. */
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memorydetective",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"mcpName": "io.github.carloshpdoc/memorydetective",
|
|
5
|
-
"description": "MCP server for iOS leak hunting and performance investigation.
|
|
5
|
+
"description": "MCP server for iOS leak hunting and performance investigation. 34 tools across .memgraph and .trace files, 36-pattern retain-cycle classifier with Swift fixTemplate snippets, abandoned-memory diff for KVO/NotificationCenter/cache shapes that escape leaks(1), per-test CI gate (detectLeaksInXCTest + detectLeaksInXCUITest with self-contained HTML reports), main-thread violation classifier on analyzeHangs, single-call build+boot+launch for the macOS 26.x leaks --outputGraph regression, replayScenario + captureScenarioState verify-fix loop, compareTracesByPattern CI gate on hangs/hitches/launch regressions, SourceKit-LSP source bridging. macOS only (depends on leaks(1) and xctrace).",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
8
|
"memorydetective": "dist/index.js"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"USAGE.md"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
-
"build": "tsc && chmod +x dist/index.js",
|
|
20
|
+
"build": "tsc && cp -R src/templates dist/templates && chmod +x dist/index.js",
|
|
21
21
|
"dev": "tsx src/index.ts",
|
|
22
22
|
"test": "vitest run",
|
|
23
23
|
"test:watch": "vitest",
|