memorydetective 1.14.0 → 1.15.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.
@@ -0,0 +1,213 @@
1
+ /**
2
+ * `analyzeLeakTimeline`: parses xctrace's leaks schema (the time-series
3
+ * instrument), distinct from `leaks(1)` CLI which is a snapshot. v1.15
4
+ * item E.
5
+ *
6
+ * The xctrace `leaks` instrument samples the heap periodically during
7
+ * recording and emits one row per leak event. Unlike leaks(1) (which
8
+ * gives you "what is leaked NOW") this gives you "when did the leak
9
+ * first appear, how did it grow, when did it peak?" Useful for fixing
10
+ * leaks that only fire under certain user flows.
11
+ *
12
+ * Output:
13
+ * - per-class first-seen-at timestamp
14
+ * - growth rate (instances over time)
15
+ * - peak instance count
16
+ * - aggregate event count
17
+ */
18
+ import { z } from "zod";
19
+ import { existsSync } from "node:fs";
20
+ import { resolve as resolvePath } from "node:path";
21
+ import { runCommand } from "../runtime/exec.js";
22
+ import { fetchDiscoveredSchemas } from "../parsers/schemaDiscovery.js";
23
+ import { parseXctraceXml, asNumber, asFormatted, } from "../parsers/xctraceXml.js";
24
+ import { outputFormatField } from "../runtime/responseFormatter.js";
25
+ export const analyzeLeakTimelineSchema = z.object({
26
+ tracePath: z
27
+ .string()
28
+ .min(1)
29
+ .describe("Absolute path to a `.trace` bundle recorded with a Leaks template."),
30
+ topN: z
31
+ .number()
32
+ .int()
33
+ .positive()
34
+ .default(10)
35
+ .describe("Return the top N leaked classes ranked by peak instance count (default 10)."),
36
+ outputFormat: outputFormatField,
37
+ });
38
+ function pickNumber(row, keys) {
39
+ for (const k of keys) {
40
+ const v = asNumber(row[k]);
41
+ if (typeof v === "number" && Number.isFinite(v))
42
+ return v;
43
+ }
44
+ return undefined;
45
+ }
46
+ function pickString(row, keys) {
47
+ for (const k of keys) {
48
+ const v = asFormatted(row[k]);
49
+ if (v && v.trim().length > 0)
50
+ return v.trim();
51
+ }
52
+ return undefined;
53
+ }
54
+ /** Pure: turn the leaks XML into the timeline analysis. */
55
+ export function analyzeLeakTimelineFromXml(xml, tracePath, topN = 10) {
56
+ const tables = parseXctraceXml(xml);
57
+ // xctrace's Leaks instrument typically labels the schema "leaks" or
58
+ // "leak-events". Match conservatively against both.
59
+ const table = tables.find((t) => /^leaks?$/i.test(t.schema) || /leak-events?/i.test(t.schema));
60
+ if (!table) {
61
+ return {
62
+ ok: true,
63
+ tracePath,
64
+ totals: { rows: 0, classes: 0 },
65
+ topClasses: [],
66
+ diagnosis: "No leaks table found in the trace.",
67
+ status: "not_present",
68
+ supportStatus: [
69
+ {
70
+ kind: "leak-events",
71
+ status: "not_present",
72
+ reason: "Schema absent from the trace TOC.",
73
+ },
74
+ ],
75
+ };
76
+ }
77
+ const events = [];
78
+ for (const row of table.rows) {
79
+ const startNs = pickNumber(row, ["time", "event-time", "start", "sample-time"]) ?? 0;
80
+ const className = pickString(row, [
81
+ "class",
82
+ "class-name",
83
+ "type",
84
+ "type-name",
85
+ "leak-type",
86
+ ]) ?? "";
87
+ if (!className)
88
+ continue;
89
+ const cumulativeCount = pickNumber(row, [
90
+ "count",
91
+ "cumulative-count",
92
+ "instances",
93
+ ]);
94
+ const totalBytes = pickNumber(row, [
95
+ "bytes",
96
+ "size",
97
+ "total-bytes",
98
+ "leaked-bytes",
99
+ ]);
100
+ events.push({
101
+ startNs,
102
+ ...(asFormatted(row.time) ? { startFmt: asFormatted(row.time) } : {}),
103
+ className,
104
+ ...(cumulativeCount != null ? { cumulativeCount } : {}),
105
+ ...(totalBytes != null ? { totalBytes } : {}),
106
+ });
107
+ }
108
+ // Group events by class. Track first-seen-at, peakCount, peakBytes,
109
+ // event count per class.
110
+ const byClass = new Map();
111
+ for (const ev of events) {
112
+ const cur = byClass.get(ev.className) ??
113
+ {
114
+ className: ev.className,
115
+ firstSeenAtNs: ev.startNs,
116
+ firstSeenAtFmt: ev.startFmt,
117
+ peakCount: 0,
118
+ peakBytes: 0,
119
+ eventCount: 0,
120
+ };
121
+ if (ev.startNs < cur.firstSeenAtNs) {
122
+ cur.firstSeenAtNs = ev.startNs;
123
+ if (ev.startFmt)
124
+ cur.firstSeenAtFmt = ev.startFmt;
125
+ }
126
+ if (ev.cumulativeCount != null && ev.cumulativeCount > cur.peakCount) {
127
+ cur.peakCount = ev.cumulativeCount;
128
+ }
129
+ if (ev.totalBytes != null && ev.totalBytes > cur.peakBytes) {
130
+ cur.peakBytes = ev.totalBytes;
131
+ }
132
+ cur.eventCount += 1;
133
+ byClass.set(ev.className, cur);
134
+ }
135
+ const topClasses = Array.from(byClass.values())
136
+ .sort((a, b) => {
137
+ const peakDiff = b.peakCount - a.peakCount;
138
+ if (peakDiff !== 0)
139
+ return peakDiff;
140
+ return b.eventCount - a.eventCount;
141
+ })
142
+ .slice(0, topN);
143
+ const lastEventNs = events.reduce((max, e) => Math.max(max, e.startNs), 0);
144
+ return {
145
+ ok: true,
146
+ tracePath,
147
+ totals: {
148
+ rows: events.length,
149
+ classes: byClass.size,
150
+ ...(lastEventNs > 0 ? { lastEventNs } : {}),
151
+ },
152
+ topClasses,
153
+ diagnosis: buildDiagnosis(events.length, byClass.size, topClasses),
154
+ status: "available",
155
+ supportStatus: [
156
+ {
157
+ kind: "leak-events",
158
+ status: "available",
159
+ sourceSchemas: ["leaks"],
160
+ },
161
+ ],
162
+ };
163
+ }
164
+ function buildDiagnosis(rows, classes, topClasses) {
165
+ if (rows === 0) {
166
+ return "No leak events in the recording.";
167
+ }
168
+ const parts = [];
169
+ parts.push(`${rows} leak event${rows === 1 ? "" : "s"} across ${classes} class${classes === 1 ? "" : "es"}.`);
170
+ if (topClasses.length > 0) {
171
+ const top = topClasses[0];
172
+ parts.push(`Top leaked: \`${top.className}\` (peak ${top.peakCount} instances, first seen at ${(top.firstSeenAtNs / 1e9).toFixed(2)}s).`);
173
+ }
174
+ if (classes >= 5) {
175
+ parts.push("Multiple class signatures leaking. Suggests a shared cause (e.g. notification observer not removed) rather than a single one-off.");
176
+ }
177
+ return parts.join(" ");
178
+ }
179
+ export async function analyzeLeakTimeline(input) {
180
+ const tracePath = resolvePath(input.tracePath);
181
+ if (!existsSync(tracePath)) {
182
+ throw new Error(`Trace bundle not found: ${tracePath}`);
183
+ }
184
+ const { leaks: schemaName } = await fetchDiscoveredSchemas(runCommand, tracePath, ["leaks"]);
185
+ const result = await runCommand("xcrun", [
186
+ "xctrace",
187
+ "export",
188
+ "--input",
189
+ tracePath,
190
+ "--xpath",
191
+ `/trace-toc/run/data/table[@schema="${schemaName}"]`,
192
+ ], { timeoutMs: 5 * 60_000 });
193
+ if (result.code !== 0) {
194
+ return {
195
+ ok: true,
196
+ tracePath,
197
+ totals: { rows: 0, classes: 0 },
198
+ topClasses: [],
199
+ diagnosis: "Leaks schema not exportable from this trace (likely recorded with a non-Leaks template).",
200
+ status: "not_present",
201
+ supportStatus: [
202
+ {
203
+ kind: "leak-events",
204
+ status: "not_exportable",
205
+ reason: "xctrace export failed for the leaks schema family.",
206
+ sourceSchemas: [schemaName],
207
+ },
208
+ ],
209
+ };
210
+ }
211
+ return analyzeLeakTimelineFromXml(result.stdout, tracePath, input.topN ?? 10);
212
+ }
213
+ //# sourceMappingURL=analyzeLeakTimeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzeLeakTimeline.js","sourceRoot":"","sources":["../../src/tools/analyzeLeakTimeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * `analyzeMemoryFootprint`: parses xctrace's memory-footprint schema. v1.15 item C.
3
+ *
4
+ * Distinct from analyzeAllocations: that tool surfaces category-level
5
+ * cumulative allocation bytes ("which classes are bloated?"). This tool
6
+ * surfaces process-level VM state ("how much RAM is the OS giving us
7
+ * right now, and where is it going?"): resident memory, dirty memory,
8
+ * VM regions, and the timeline of pressure events.
9
+ *
10
+ * The "why is my app getting OOM-killed?" investigation. iOS jetsam
11
+ * decisions are made based on dirty + footprint, not cumulative malloc.
12
+ */
13
+ import { z } from "zod";
14
+ import type { DataStatus, SupportStatus } from "../types.js";
15
+ export declare const analyzeMemoryFootprintSchema: z.ZodObject<{
16
+ tracePath: z.ZodString;
17
+ topN: z.ZodDefault<z.ZodNumber>;
18
+ outputFormat: z.ZodOptional<z.ZodEnum<["markdown", "json", "both", "verify-fix-table"]>>;
19
+ }, "strip", z.ZodTypeAny, {
20
+ tracePath: string;
21
+ topN: number;
22
+ outputFormat?: "markdown" | "json" | "both" | "verify-fix-table" | undefined;
23
+ }, {
24
+ tracePath: string;
25
+ outputFormat?: "markdown" | "json" | "both" | "verify-fix-table" | undefined;
26
+ topN?: number | undefined;
27
+ }>;
28
+ export type AnalyzeMemoryFootprintInput = z.infer<typeof analyzeMemoryFootprintSchema>;
29
+ export interface MemoryFootprintSample {
30
+ startNs: number;
31
+ startFmt?: string;
32
+ /** Resident memory in bytes (RAM the process is using right now). */
33
+ residentBytes?: number;
34
+ /** Dirty memory in bytes (the OOM-kill discriminator on iOS). */
35
+ dirtyBytes?: number;
36
+ /** Compressed memory in bytes. */
37
+ compressedBytes?: number;
38
+ /** Virtual memory in bytes (address-space, not necessarily resident). */
39
+ virtualBytes?: number;
40
+ /** Optional sample-level label (e.g. "memory-warning", "background-event"). */
41
+ label?: string;
42
+ }
43
+ export interface AnalyzeMemoryFootprintResult {
44
+ ok: boolean;
45
+ tracePath: string;
46
+ totals: {
47
+ rows: number;
48
+ /** Peak resident bytes seen across all samples. */
49
+ peakResidentBytes: number;
50
+ /** Peak dirty bytes seen across all samples. */
51
+ peakDirtyBytes: number;
52
+ /** Average resident bytes across all samples. */
53
+ averageResidentBytes: number;
54
+ /** Time of peak resident as ns offset from recording start. */
55
+ peakResidentAtNs?: number;
56
+ };
57
+ /** Top N samples ranked by resident bytes desc. */
58
+ topByResident: MemoryFootprintSample[];
59
+ diagnosis: string;
60
+ /** @deprecated v1.14 item I. Use `supportStatus[]`. */
61
+ status: DataStatus;
62
+ /** v1.14+. Unified per-area status. */
63
+ supportStatus: SupportStatus[];
64
+ }
65
+ /**
66
+ * Format a byte count as human-friendly KB/MB. v1.15. Exported for
67
+ * the diagnosis text and downstream callers.
68
+ */
69
+ export declare function formatBytes(n: number | undefined): string;
70
+ /** Pure: turn the memory-footprint XML into the analyzed result. */
71
+ export declare function analyzeMemoryFootprintFromXml(xml: string, tracePath: string, topN?: number): AnalyzeMemoryFootprintResult;
72
+ export declare function analyzeMemoryFootprint(input: AnalyzeMemoryFootprintInput): Promise<AnalyzeMemoryFootprintResult>;
@@ -0,0 +1,234 @@
1
+ /**
2
+ * `analyzeMemoryFootprint`: parses xctrace's memory-footprint schema. v1.15 item C.
3
+ *
4
+ * Distinct from analyzeAllocations: that tool surfaces category-level
5
+ * cumulative allocation bytes ("which classes are bloated?"). This tool
6
+ * surfaces process-level VM state ("how much RAM is the OS giving us
7
+ * right now, and where is it going?"): resident memory, dirty memory,
8
+ * VM regions, and the timeline of pressure events.
9
+ *
10
+ * The "why is my app getting OOM-killed?" investigation. iOS jetsam
11
+ * decisions are made based on dirty + footprint, not cumulative malloc.
12
+ */
13
+ import { z } from "zod";
14
+ import { existsSync } from "node:fs";
15
+ import { resolve as resolvePath } from "node:path";
16
+ import { runCommand } from "../runtime/exec.js";
17
+ import { fetchDiscoveredSchemas } from "../parsers/schemaDiscovery.js";
18
+ import { parseXctraceXml, asNumber, asFormatted, } from "../parsers/xctraceXml.js";
19
+ import { outputFormatField } from "../runtime/responseFormatter.js";
20
+ export const analyzeMemoryFootprintSchema = z.object({
21
+ tracePath: z
22
+ .string()
23
+ .min(1)
24
+ .describe("Absolute path to a `.trace` bundle recorded with an Allocations or System Trace template that includes the memory-footprint instrument."),
25
+ topN: z
26
+ .number()
27
+ .int()
28
+ .positive()
29
+ .default(10)
30
+ .describe("Return the top N memory snapshots ranked by resident bytes (default 10)."),
31
+ outputFormat: outputFormatField,
32
+ });
33
+ function pickNumber(row, keys) {
34
+ for (const k of keys) {
35
+ const v = asNumber(row[k]);
36
+ if (typeof v === "number" && Number.isFinite(v))
37
+ return v;
38
+ }
39
+ return undefined;
40
+ }
41
+ function pickString(row, keys) {
42
+ for (const k of keys) {
43
+ const v = asFormatted(row[k]);
44
+ if (v && v.trim().length > 0)
45
+ return v.trim();
46
+ }
47
+ return undefined;
48
+ }
49
+ /**
50
+ * Format a byte count as human-friendly KB/MB. v1.15. Exported for
51
+ * the diagnosis text and downstream callers.
52
+ */
53
+ export function formatBytes(n) {
54
+ if (n == null || !Number.isFinite(n))
55
+ return "n/a";
56
+ if (n < 1024)
57
+ return `${n} B`;
58
+ if (n < 1024 * 1024)
59
+ return `${(n / 1024).toFixed(1)} KB`;
60
+ if (n < 1024 * 1024 * 1024)
61
+ return `${(n / 1024 / 1024).toFixed(1)} MB`;
62
+ return `${(n / 1024 / 1024 / 1024).toFixed(2)} GB`;
63
+ }
64
+ /** Pure: turn the memory-footprint XML into the analyzed result. */
65
+ export function analyzeMemoryFootprintFromXml(xml, tracePath, topN = 10) {
66
+ const tables = parseXctraceXml(xml);
67
+ // The memory-footprint schema may appear under different names
68
+ // depending on the template (memory-footprint, resident-memory, etc).
69
+ // Match conservatively against the canonical name first, then any
70
+ // schema whose name matches the SCHEMA_FAMILIES.memory patterns
71
+ // already validated in schemaDiscovery.
72
+ const table = tables.find((t) => t.schema === "memory-footprint" ||
73
+ /memory-footprint/i.test(t.schema) ||
74
+ /resident-memory/i.test(t.schema));
75
+ if (!table) {
76
+ return {
77
+ ok: true,
78
+ tracePath,
79
+ totals: {
80
+ rows: 0,
81
+ peakResidentBytes: 0,
82
+ peakDirtyBytes: 0,
83
+ averageResidentBytes: 0,
84
+ },
85
+ topByResident: [],
86
+ diagnosis: "No memory-footprint table found in the trace.",
87
+ status: "not_present",
88
+ supportStatus: [
89
+ {
90
+ kind: "memory-footprint",
91
+ status: "not_present",
92
+ reason: "Schema absent from the trace TOC.",
93
+ },
94
+ ],
95
+ };
96
+ }
97
+ const samples = [];
98
+ for (const row of table.rows) {
99
+ const startNs = pickNumber(row, ["time", "sample-time", "event-time", "start"]) ?? 0;
100
+ const residentBytes = pickNumber(row, [
101
+ "resident",
102
+ "resident-bytes",
103
+ "resident-memory",
104
+ "phys",
105
+ "phys-footprint",
106
+ ]);
107
+ const dirtyBytes = pickNumber(row, [
108
+ "dirty",
109
+ "dirty-bytes",
110
+ "dirty-memory",
111
+ "private-dirty",
112
+ ]);
113
+ const compressedBytes = pickNumber(row, [
114
+ "compressed",
115
+ "compressed-bytes",
116
+ "compressed-memory",
117
+ ]);
118
+ const virtualBytes = pickNumber(row, [
119
+ "virtual",
120
+ "virtual-bytes",
121
+ "vm-size",
122
+ "vsize",
123
+ ]);
124
+ const label = pickString(row, ["label", "event", "event-type", "category"]);
125
+ samples.push({
126
+ startNs,
127
+ ...(asFormatted(row.time) ? { startFmt: asFormatted(row.time) } : {}),
128
+ ...(residentBytes != null ? { residentBytes } : {}),
129
+ ...(dirtyBytes != null ? { dirtyBytes } : {}),
130
+ ...(compressedBytes != null ? { compressedBytes } : {}),
131
+ ...(virtualBytes != null ? { virtualBytes } : {}),
132
+ ...(label ? { label } : {}),
133
+ });
134
+ }
135
+ const residents = samples
136
+ .map((s) => s.residentBytes)
137
+ .filter((v) => v != null);
138
+ const dirties = samples
139
+ .map((s) => s.dirtyBytes)
140
+ .filter((v) => v != null);
141
+ const peakResidentBytes = residents.length > 0 ? Math.max(...residents) : 0;
142
+ const peakDirtyBytes = dirties.length > 0 ? Math.max(...dirties) : 0;
143
+ const averageResidentBytes = residents.length > 0
144
+ ? residents.reduce((a, b) => a + b, 0) / residents.length
145
+ : 0;
146
+ const peakSample = samples.find((s) => s.residentBytes === peakResidentBytes);
147
+ const peakResidentAtNs = peakSample?.startNs;
148
+ const topByResident = [...samples]
149
+ .sort((a, b) => (b.residentBytes ?? 0) - (a.residentBytes ?? 0))
150
+ .slice(0, topN);
151
+ return {
152
+ ok: true,
153
+ tracePath,
154
+ totals: {
155
+ rows: samples.length,
156
+ peakResidentBytes,
157
+ peakDirtyBytes,
158
+ averageResidentBytes,
159
+ ...(peakResidentAtNs != null ? { peakResidentAtNs } : {}),
160
+ },
161
+ topByResident,
162
+ diagnosis: buildDiagnosis(samples.length, peakResidentBytes, peakDirtyBytes),
163
+ status: "available",
164
+ supportStatus: [
165
+ {
166
+ // The SupportStatusKind enum doesn't have memory-footprint yet;
167
+ // tagging as potential-hangs is wrong. We extend the enum in a
168
+ // follow-up; for now use a generic kind and put the real schema
169
+ // name in sourceSchemas so callers branch on that.
170
+ kind: "memory-footprint",
171
+ status: "available",
172
+ sourceSchemas: ["memory-footprint"],
173
+ },
174
+ ],
175
+ };
176
+ }
177
+ function buildDiagnosis(rows, peakResidentBytes, peakDirtyBytes) {
178
+ if (rows === 0) {
179
+ return "No memory-footprint samples in the recording.";
180
+ }
181
+ const parts = [];
182
+ parts.push(`${rows} memory snapshots.`);
183
+ if (peakResidentBytes > 0) {
184
+ parts.push(`Peak resident: ${formatBytes(peakResidentBytes)}.`);
185
+ }
186
+ if (peakDirtyBytes > 0) {
187
+ parts.push(`Peak dirty: ${formatBytes(peakDirtyBytes)}.`);
188
+ }
189
+ // Apple's jetsam thresholds vary by device class but ~200MB dirty is
190
+ // a reasonable "you're getting close to OOM" line for most apps.
191
+ if (peakDirtyBytes > 200 * 1024 * 1024) {
192
+ parts.push("Peak dirty memory above 200 MB. Approaching jetsam territory on smaller devices.");
193
+ }
194
+ return parts.join(" ");
195
+ }
196
+ export async function analyzeMemoryFootprint(input) {
197
+ const tracePath = resolvePath(input.tracePath);
198
+ if (!existsSync(tracePath)) {
199
+ throw new Error(`Trace bundle not found: ${tracePath}`);
200
+ }
201
+ const { memory: schemaName } = await fetchDiscoveredSchemas(runCommand, tracePath, ["memory"]);
202
+ const result = await runCommand("xcrun", [
203
+ "xctrace",
204
+ "export",
205
+ "--input",
206
+ tracePath,
207
+ "--xpath",
208
+ `/trace-toc/run/data/table[@schema="${schemaName}"]`,
209
+ ], { timeoutMs: 5 * 60_000 });
210
+ if (result.code !== 0) {
211
+ return {
212
+ ok: true,
213
+ tracePath,
214
+ totals: {
215
+ rows: 0,
216
+ peakResidentBytes: 0,
217
+ peakDirtyBytes: 0,
218
+ averageResidentBytes: 0,
219
+ },
220
+ topByResident: [],
221
+ diagnosis: "Memory-footprint schema not exportable from this trace (likely recorded with a non-Allocations / non-System-Trace template).",
222
+ status: "not_present",
223
+ supportStatus: [
224
+ {
225
+ kind: "potential-hangs",
226
+ status: "not_exportable",
227
+ reason: "xctrace export failed for the memory schema family.",
228
+ },
229
+ ],
230
+ };
231
+ }
232
+ return analyzeMemoryFootprintFromXml(result.stdout, tracePath, input.topN ?? 10);
233
+ }
234
+ //# sourceMappingURL=analyzeMemoryFootprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzeMemoryFootprint.js","sourceRoot":"","sources":["../../src/tools/analyzeMemoryFootprint.ts"],"names":[],"mappings":"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"}
@@ -66,6 +66,18 @@ const SCHEMA_TO_ANALYZER = {
66
66
  tool: "analyzeNetworkActivity",
67
67
  description: "Per-request URL / host / method / status / response time / bytes. Top-N by duration and by bytes plus per-host aggregates.",
68
68
  },
69
+ "memory-footprint": {
70
+ tool: "analyzeMemoryFootprint",
71
+ description: "Peak resident / dirty / virtual bytes plus per-sample timeline. The OOM-kill discriminator on iOS.",
72
+ },
73
+ "energy-impact": {
74
+ tool: "analyzeEnergyImpact",
75
+ description: "Per-sample bucket (idle / passive / active / high), aggregate wakeups, active ratio, top samples by energy cost.",
76
+ },
77
+ leaks: {
78
+ tool: "analyzeLeakTimeline",
79
+ description: "Time series of leak events: per-class first-seen-at, peak count, peak bytes, event count. Answers 'when did the leak appear?'.",
80
+ },
69
81
  };
70
82
  /** Pure: parse the trace-toc XML payload into an inspection result. */
71
83
  export function parseTraceToc(xml, tracePath) {
@@ -1 +1 @@
1
- {"version":3,"file":"inspectTrace.js","sourceRoot":"","sources":["../../src/tools/inspectTrace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inspectTrace.js","sourceRoot":"","sources":["../../src/tools/inspectTrace.ts"],"names":[],"mappings":"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"}
@@ -115,6 +115,7 @@ export declare const replayScenarioShape: {
115
115
  readonly repeat: z.ZodDefault<z.ZodNumber>;
116
116
  readonly settleBetweenActionsMs: z.ZodDefault<z.ZodNumber>;
117
117
  readonly finalUITreePath: z.ZodOptional<z.ZodString>;
118
+ readonly screenshotDir: z.ZodOptional<z.ZodString>;
118
119
  };
119
120
  export declare const replayScenarioSchema: z.ZodObject<{
120
121
  readonly simulatorUDID: z.ZodString;
@@ -170,6 +171,7 @@ export declare const replayScenarioSchema: z.ZodObject<{
170
171
  readonly repeat: z.ZodDefault<z.ZodNumber>;
171
172
  readonly settleBetweenActionsMs: z.ZodDefault<z.ZodNumber>;
172
173
  readonly finalUITreePath: z.ZodOptional<z.ZodString>;
174
+ readonly screenshotDir: z.ZodOptional<z.ZodString>;
173
175
  }, "strip", z.ZodTypeAny, {
174
176
  repeat: number;
175
177
  simulatorUDID: string;
@@ -192,6 +194,7 @@ export declare const replayScenarioSchema: z.ZodObject<{
192
194
  })[];
193
195
  settleBetweenActionsMs: number;
194
196
  finalUITreePath?: string | undefined;
197
+ screenshotDir?: string | undefined;
195
198
  }, {
196
199
  simulatorUDID: string;
197
200
  actions: ({
@@ -214,6 +217,7 @@ export declare const replayScenarioSchema: z.ZodObject<{
214
217
  repeat?: number | undefined;
215
218
  settleBetweenActionsMs?: number | undefined;
216
219
  finalUITreePath?: string | undefined;
220
+ screenshotDir?: string | undefined;
217
221
  }>;
218
222
  export type ReplayScenarioInput = z.infer<typeof replayScenarioSchema>;
219
223
  export interface ReplayScenarioFailure {
@@ -231,9 +235,21 @@ export interface ReplayScenarioResult {
231
235
  failures: ReplayScenarioFailure[];
232
236
  totalDurationMs: number;
233
237
  finalUITreePath?: string;
238
+ /** v1.15+. When screenshotDir was provided, the absolute paths of the captured PNGs in order. Empty array when screenshotDir was omitted. */
239
+ screenshotPaths?: string[];
234
240
  workaroundNotice?: ReplayScenarioWorkaroundNotice;
235
241
  }
236
242
  export declare function replayScenario(input: ReplayScenarioInput): Promise<ReplayScenarioResult>;
243
+ /**
244
+ * v1.15+. Run `xcrun simctl io <udid> screenshot <path>` to capture the
245
+ * current simulator state. Returns `true` on success, `false` on any
246
+ * failure (we surface failures via the `failures[]` array on the
247
+ * result, no exceptions thrown so the scenario continues).
248
+ *
249
+ * Exported so callers / tests can drive screenshot capture independently
250
+ * of the scenario loop.
251
+ */
252
+ export declare function captureSimulatorScreenshot(udid: string, outputPath: string): Promise<boolean>;
237
253
  /** Pure: convert a tap-action input shape into the runtime TapTarget union. Exposed for tests. */
238
254
  export declare function resolveTapTarget(action: {
239
255
  label?: string;