execbro 1.10.25 → 1.11.1
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 +1 -1
- package/build/__tests__/integration/native-logs.test.d.ts +2 -0
- package/build/__tests__/integration/native-logs.test.d.ts.map +1 -0
- package/build/__tests__/integration/native-logs.test.js +39 -0
- package/build/__tests__/integration/native-logs.test.js.map +1 -0
- package/build/__tests__/unit/clearLogsNative.test.d.ts +2 -0
- package/build/__tests__/unit/clearLogsNative.test.d.ts.map +1 -0
- package/build/__tests__/unit/clearLogsNative.test.js +43 -0
- package/build/__tests__/unit/clearLogsNative.test.js.map +1 -0
- package/build/__tests__/unit/componentFormatNaming.test.d.ts +2 -0
- package/build/__tests__/unit/componentFormatNaming.test.d.ts.map +1 -0
- package/build/__tests__/unit/componentFormatNaming.test.js +32 -0
- package/build/__tests__/unit/componentFormatNaming.test.js.map +1 -0
- package/build/__tests__/unit/getLogsEmptyContract.test.js +20 -7
- package/build/__tests__/unit/getLogsEmptyContract.test.js.map +1 -1
- package/build/__tests__/unit/getLogsNativeSource.test.d.ts +2 -0
- package/build/__tests__/unit/getLogsNativeSource.test.d.ts.map +1 -0
- package/build/__tests__/unit/getLogsNativeSource.test.js +138 -0
- package/build/__tests__/unit/getLogsNativeSource.test.js.map +1 -0
- package/build/__tests__/unit/jsLogEvents.test.d.ts +2 -0
- package/build/__tests__/unit/jsLogEvents.test.d.ts.map +1 -0
- package/build/__tests__/unit/jsLogEvents.test.js +58 -0
- package/build/__tests__/unit/jsLogEvents.test.js.map +1 -0
- package/build/__tests__/unit/logEventFormat.test.d.ts +2 -0
- package/build/__tests__/unit/logEventFormat.test.d.ts.map +1 -0
- package/build/__tests__/unit/logEventFormat.test.js +210 -0
- package/build/__tests__/unit/logEventFormat.test.js.map +1 -0
- package/build/__tests__/unit/logEvents.test.d.ts +2 -0
- package/build/__tests__/unit/logEvents.test.d.ts.map +1 -0
- package/build/__tests__/unit/logEvents.test.js +118 -0
- package/build/__tests__/unit/logEvents.test.js.map +1 -0
- package/build/__tests__/unit/logGrouping.test.d.ts +2 -0
- package/build/__tests__/unit/logGrouping.test.d.ts.map +1 -0
- package/build/__tests__/unit/logGrouping.test.js +104 -0
- package/build/__tests__/unit/logGrouping.test.js.map +1 -0
- package/build/__tests__/unit/logOwnership.test.d.ts +2 -0
- package/build/__tests__/unit/logOwnership.test.d.ts.map +1 -0
- package/build/__tests__/unit/logOwnership.test.js +118 -0
- package/build/__tests__/unit/logOwnership.test.js.map +1 -0
- package/build/__tests__/unit/logRelevance.test.d.ts +2 -0
- package/build/__tests__/unit/logRelevance.test.d.ts.map +1 -0
- package/build/__tests__/unit/logRelevance.test.js +30 -0
- package/build/__tests__/unit/logRelevance.test.js.map +1 -0
- package/build/__tests__/unit/logSourceAndroid.test.d.ts +2 -0
- package/build/__tests__/unit/logSourceAndroid.test.d.ts.map +1 -0
- package/build/__tests__/unit/logSourceAndroid.test.js +61 -0
- package/build/__tests__/unit/logSourceAndroid.test.js.map +1 -0
- package/build/__tests__/unit/logSourceIos.test.d.ts +2 -0
- package/build/__tests__/unit/logSourceIos.test.d.ts.map +1 -0
- package/build/__tests__/unit/logSourceIos.test.js +64 -0
- package/build/__tests__/unit/logSourceIos.test.js.map +1 -0
- package/build/__tests__/unit/logs.test.js +23 -0
- package/build/__tests__/unit/logs.test.js.map +1 -1
- package/build/__tests__/unit/nativeLogs.test.d.ts +2 -0
- package/build/__tests__/unit/nativeLogs.test.d.ts.map +1 -0
- package/build/__tests__/unit/nativeLogs.test.js +230 -0
- package/build/__tests__/unit/nativeLogs.test.js.map +1 -0
- package/build/__tests__/unit/toolsJson.test.js +11 -0
- package/build/__tests__/unit/toolsJson.test.js.map +1 -1
- package/build/core/componentSearch.d.ts +1 -1
- package/build/core/componentSearch.d.ts.map +1 -1
- package/build/core/componentSearch.js +8 -8
- package/build/core/componentSearch.js.map +1 -1
- package/build/core/componentTree.d.ts +1 -1
- package/build/core/componentTree.d.ts.map +1 -1
- package/build/core/componentTree.js +8 -8
- package/build/core/componentTree.js.map +1 -1
- package/build/core/guides.d.ts.map +1 -1
- package/build/core/guides.js +25 -0
- package/build/core/guides.js.map +1 -1
- package/build/core/index.d.ts +0 -2
- package/build/core/index.d.ts.map +1 -1
- package/build/core/index.js +0 -2
- package/build/core/index.js.map +1 -1
- package/build/core/jsLogEvents.d.ts +13 -0
- package/build/core/jsLogEvents.d.ts.map +1 -0
- package/build/core/jsLogEvents.js +65 -0
- package/build/core/jsLogEvents.js.map +1 -0
- package/build/core/logEventFormat.d.ts +14 -0
- package/build/core/logEventFormat.d.ts.map +1 -0
- package/build/core/logEventFormat.js +85 -0
- package/build/core/logEventFormat.js.map +1 -0
- package/build/core/logEvents.d.ts +115 -0
- package/build/core/logEvents.d.ts.map +1 -0
- package/build/core/logEvents.js +146 -0
- package/build/core/logEvents.js.map +1 -0
- package/build/core/logGrouping.d.ts +17 -0
- package/build/core/logGrouping.d.ts.map +1 -0
- package/build/core/logGrouping.js +134 -0
- package/build/core/logGrouping.js.map +1 -0
- package/build/core/logOwnership.d.ts +29 -0
- package/build/core/logOwnership.d.ts.map +1 -0
- package/build/core/logOwnership.js +83 -0
- package/build/core/logOwnership.js.map +1 -0
- package/build/core/logRelevance.d.ts +13 -0
- package/build/core/logRelevance.d.ts.map +1 -0
- package/build/core/logRelevance.js +23 -0
- package/build/core/logRelevance.js.map +1 -0
- package/build/core/logSourceAndroid.d.ts +27 -0
- package/build/core/logSourceAndroid.d.ts.map +1 -0
- package/build/core/logSourceAndroid.js +89 -0
- package/build/core/logSourceAndroid.js.map +1 -0
- package/build/core/logSourceIos.d.ts +26 -0
- package/build/core/logSourceIos.d.ts.map +1 -0
- package/build/core/logSourceIos.js +119 -0
- package/build/core/logSourceIos.js.map +1 -0
- package/build/core/logs.d.ts +5 -1
- package/build/core/logs.d.ts.map +1 -1
- package/build/core/logs.js +8 -1
- package/build/core/logs.js.map +1 -1
- package/build/core/nativeLogs.d.ts +75 -0
- package/build/core/nativeLogs.d.ts.map +1 -0
- package/build/core/nativeLogs.js +260 -0
- package/build/core/nativeLogs.js.map +1 -0
- package/build/core/screenLayout.d.ts +1 -1
- package/build/core/screenLayout.d.ts.map +1 -1
- package/build/core/screenLayout.js +3 -3
- package/build/core/screenLayout.js.map +1 -1
- package/build/core/types.d.ts +3 -2
- package/build/core/types.d.ts.map +1 -1
- package/build/tools/componentTools.js +6 -6
- package/build/tools/componentTools.js.map +1 -1
- package/build/tools/logTools.d.ts +25 -0
- package/build/tools/logTools.d.ts.map +1 -1
- package/build/tools/logTools.js +246 -70
- package/build/tools/logTools.js.map +1 -1
- package/build/tools/networkTools.d.ts.map +1 -1
- package/build/tools/networkTools.js +5 -44
- package/build/tools/networkTools.js.map +1 -1
- package/package.json +6 -4
- package/tools.json +447 -0
- package/build/core/format.d.ts +0 -8
- package/build/core/format.d.ts.map +0 -1
- package/build/core/format.js +0 -34
- package/build/core/format.js.map +0 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { execAsync, withCancelableTimeout } from "./exec.js";
|
|
2
|
+
const MAX_BUFFER = 32 * 1024 * 1024;
|
|
3
|
+
const FETCH_TIMEOUT_MS = 8000;
|
|
4
|
+
const MESSAGE_TYPE = {
|
|
5
|
+
Fault: "fatal",
|
|
6
|
+
Error: "error",
|
|
7
|
+
Default: "log",
|
|
8
|
+
Info: "info",
|
|
9
|
+
Debug: "debug",
|
|
10
|
+
};
|
|
11
|
+
const IOS_SUBJECT_RE = /\b([a-z0-9]+(?:\.[A-Za-z0-9-]+){2,})\b/;
|
|
12
|
+
/**
|
|
13
|
+
* `log show --start` parses a bare timestamp as DEVICE-LOCAL time, and rejects
|
|
14
|
+
* an explicit UTC offset (verified against a live simulator). Emitting UTC
|
|
15
|
+
* would therefore shift the window by the host's offset: over-fetching hours
|
|
16
|
+
* of logs east of UTC, and silently MISSING events — crashes included — west
|
|
17
|
+
* of it. The simulator shares the host clock, so local components are correct.
|
|
18
|
+
*/
|
|
19
|
+
function localStamp(d) {
|
|
20
|
+
const p = (n) => String(n).padStart(2, "0");
|
|
21
|
+
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ` +
|
|
22
|
+
`${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Build the `log show` invocation.
|
|
26
|
+
*
|
|
27
|
+
* The predicate does the filtering inside the OS: a 30-minute app-scoped read
|
|
28
|
+
* is 42 KB, where an unscoped one is orders of magnitude larger.
|
|
29
|
+
*/
|
|
30
|
+
export function buildLogShowCommand(opts) {
|
|
31
|
+
const predicates = [];
|
|
32
|
+
if (opts.processName)
|
|
33
|
+
predicates.push(`process == "${opts.processName}"`);
|
|
34
|
+
// Enumerated explicitly — the predicate language has no ordering over
|
|
35
|
+
// messageType, so a ">=" comparison silently matches nothing.
|
|
36
|
+
if (opts.minMessageType === "fault") {
|
|
37
|
+
predicates.push("messageType == fault");
|
|
38
|
+
}
|
|
39
|
+
else if (opts.minMessageType === "error") {
|
|
40
|
+
predicates.push("(messageType == error OR messageType == fault)");
|
|
41
|
+
}
|
|
42
|
+
const parts = [`xcrun simctl spawn ${opts.udid} log show --style ndjson`];
|
|
43
|
+
if (opts.sinceTs) {
|
|
44
|
+
parts.push(`--start '${localStamp(opts.sinceTs)}'`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
parts.push("--last 30m");
|
|
48
|
+
}
|
|
49
|
+
if (predicates.length > 0) {
|
|
50
|
+
parts.push(`--predicate '${predicates.join(" AND ")}'`);
|
|
51
|
+
}
|
|
52
|
+
return parts.join(" ");
|
|
53
|
+
}
|
|
54
|
+
export function parseLogShowNdjson(stdout) {
|
|
55
|
+
const out = [];
|
|
56
|
+
for (const raw of stdout.split("\n")) {
|
|
57
|
+
const trimmed = raw.trim();
|
|
58
|
+
if (!trimmed)
|
|
59
|
+
continue;
|
|
60
|
+
let rec;
|
|
61
|
+
try {
|
|
62
|
+
rec = JSON.parse(trimmed);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
continue; // banner or partial line
|
|
66
|
+
}
|
|
67
|
+
// The stream ends with a {count, finished} summary object.
|
|
68
|
+
if (typeof rec.eventMessage !== "string")
|
|
69
|
+
continue;
|
|
70
|
+
const subsystem = typeof rec.subsystem === "string" ? rec.subsystem : "";
|
|
71
|
+
const category = typeof rec.category === "string" ? rec.category : "";
|
|
72
|
+
const message = rec.eventMessage;
|
|
73
|
+
const messageType = typeof rec.messageType === "string" ? rec.messageType : "Default";
|
|
74
|
+
out.push({
|
|
75
|
+
ts: new Date(String(rec.timestamp).replace(" ", "T").replace(/([+-]\d{2})(\d{2})$/, "$1:$2")),
|
|
76
|
+
level: MESSAGE_TYPE[messageType] ?? "log",
|
|
77
|
+
pid: Number(rec.processID ?? 0),
|
|
78
|
+
tid: rec.threadID === undefined ? undefined : Number(rec.threadID),
|
|
79
|
+
tag: subsystem || category ? `${subsystem}:${category}` : "default",
|
|
80
|
+
message,
|
|
81
|
+
subject: message.match(IOS_SUBJECT_RE)?.[1],
|
|
82
|
+
raw: trimmed,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
export async function fetchIosLines(opts) {
|
|
88
|
+
const cmd = buildLogShowCommand(opts);
|
|
89
|
+
const { stdout } = await withCancelableTimeout((signal) => execAsync(cmd, { signal, maxBuffer: MAX_BUFFER }), FETCH_TIMEOUT_MS, `log show (${opts.udid})`);
|
|
90
|
+
return parseLogShowNdjson(stdout);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Map a bundle id to the `process ==` value the predicate needs.
|
|
94
|
+
*
|
|
95
|
+
* The predicate matches the executable name, not the bundle id — verified:
|
|
96
|
+
* org.reactjs.native.example.RnDebuggerTestApp -> RnDebuggerTestApp.
|
|
97
|
+
*/
|
|
98
|
+
const processNameCache = new Map();
|
|
99
|
+
export async function resolveIosProcessName(udid, bundleId, signal) {
|
|
100
|
+
const key = `${udid}:${bundleId}`;
|
|
101
|
+
const cached = processNameCache.get(key);
|
|
102
|
+
if (cached)
|
|
103
|
+
return cached;
|
|
104
|
+
try {
|
|
105
|
+
const { stdout } = await execAsync(`xcrun simctl get_app_container ${udid} ${bundleId} app`, { signal });
|
|
106
|
+
const name = stdout.trim().split("/").pop()?.replace(/\.app$/, "");
|
|
107
|
+
if (name)
|
|
108
|
+
processNameCache.set(key, name);
|
|
109
|
+
return name || undefined;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/** Test-only. */
|
|
116
|
+
export function __resetIosProcessNameCache() {
|
|
117
|
+
processNameCache.clear();
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=logSourceIos.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logSourceIos.js","sourceRoot":"","sources":["../../src/core/logSourceIos.ts"],"names":[],"mappings":"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"}
|
package/build/core/logs.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { LogEntry, LogLevel } from "./types.js";
|
|
2
|
+
/** Test-only: reset the sequence so assertions are not order-dependent. */
|
|
3
|
+
export declare function __resetLogSeq(): void;
|
|
2
4
|
export declare class LogBuffer {
|
|
3
5
|
private logs;
|
|
4
6
|
private maxSize;
|
|
5
7
|
constructor(maxSize?: number);
|
|
6
|
-
add(entry: LogEntry
|
|
8
|
+
add(entry: Omit<LogEntry, "seq"> & {
|
|
9
|
+
seq?: number;
|
|
10
|
+
}): void;
|
|
7
11
|
get(count?: number, level?: string, startFromText?: string): LogEntry[];
|
|
8
12
|
search(text: string, maxResults?: number): LogEntry[];
|
|
9
13
|
clear(): number;
|
package/build/core/logs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/core/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/core/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKhD,2EAA2E;AAC3E,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAGD,qBAAa,SAAS;IAClB,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,MAAa;IAIlC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAQ1D,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE;IA4BvE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE;IAUrD,KAAK,IAAI,MAAM;IAMf,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAMlC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,MAAM,IAAI,QAAQ,EAAE;CAGvB;AAGD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAc9D;AAGD,MAAM,WAAW,iBAAiB;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAGD,wBAAgB,UAAU,CACtB,IAAI,EAAE,QAAQ,EAAE,EAChB,OAAO,GAAE,iBAAsB,GAChC,MAAM,CAqBR;AAGD,wBAAgB,OAAO,CACnB,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE;IACL,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CAChB,GACP;IAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAQxD;AAGD,wBAAgB,UAAU,CACtB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IACL,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CAChB,GACP;IAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAQxD;AAGD,wBAAgB,aAAa,CACzB,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE;IACL,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACxB,GACP,MAAM,CAoCR"}
|
package/build/core/logs.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
// Process-global so ids never collide across per-device buffers.
|
|
2
|
+
let nextSeq = 1;
|
|
3
|
+
/** Test-only: reset the sequence so assertions are not order-dependent. */
|
|
4
|
+
export function __resetLogSeq() {
|
|
5
|
+
nextSeq = 1;
|
|
6
|
+
}
|
|
1
7
|
// Circular buffer for storing logs
|
|
2
8
|
export class LogBuffer {
|
|
3
9
|
logs = [];
|
|
@@ -6,7 +12,8 @@ export class LogBuffer {
|
|
|
6
12
|
this.maxSize = maxSize;
|
|
7
13
|
}
|
|
8
14
|
add(entry) {
|
|
9
|
-
|
|
15
|
+
const stamped = { ...entry, seq: entry.seq ?? nextSeq++ };
|
|
16
|
+
this.logs.push(stamped);
|
|
10
17
|
if (this.logs.length > this.maxSize) {
|
|
11
18
|
this.logs.shift();
|
|
12
19
|
}
|
package/build/core/logs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/core/logs.ts"],"names":[],"mappings":"AAEA,mCAAmC;AACnC,MAAM,OAAO,SAAS;IACV,IAAI,GAAe,EAAE,CAAC;IACtB,OAAO,CAAS;IAExB,YAAY,UAAkB,IAAI;QAC9B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/core/logs.ts"],"names":[],"mappings":"AAEA,iEAAiE;AACjE,IAAI,OAAO,GAAG,CAAC,CAAC;AAEhB,2EAA2E;AAC3E,MAAM,UAAU,aAAa;IACzB,OAAO,GAAG,CAAC,CAAC;AAChB,CAAC;AAED,mCAAmC;AACnC,MAAM,OAAO,SAAS;IACV,IAAI,GAAe,EAAE,CAAC;IACtB,OAAO,CAAS;IAExB,YAAY,UAAkB,IAAI;QAC9B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,GAAG,CAAC,KAA+C;QAC/C,MAAM,OAAO,GAAa,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,OAAO,EAAE,EAAE,CAAC;QACpE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC;IACL,CAAC;IAED,GAAG,CAAC,KAAc,EAAE,KAAc,EAAE,aAAsB;QACtD,IAAI,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;QAEzB,iFAAiF;QACjF,IAAI,aAAa,EAAE,CAAC;YAChB,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC;YACpB,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5C,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;oBAC9C,UAAU,GAAG,CAAC,CAAC;oBACf,MAAM;gBACV,CAAC;YACL,CAAC;YACD,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;gBACpB,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC1C,CAAC;QACL,CAAC;QAED,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;YAC3B,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QAC7D,CAAC;QAED,IAAI,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACrB,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,UAAmB;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CACrC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CACzD,CAAC;QACF,IAAI,UAAU,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,KAAK;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,YAAY,CAAC,IAAY;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,OAAO,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IACrC,CAAC;IAED,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,MAAM;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACJ;AAED,gCAAgC;AAChC,MAAM,UAAU,cAAc,CAAC,IAAY;IACvC,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,OAAO;YACR,OAAO,OAAO,CAAC;QACnB,KAAK,SAAS,CAAC;QACf,KAAK,MAAM;YACP,OAAO,MAAM,CAAC;QAClB,KAAK,MAAM;YACP,OAAO,MAAM,CAAC;QAClB,KAAK,OAAO;YACR,OAAO,OAAO,CAAC;QACnB;YACI,OAAO,KAAK,CAAC;IACrB,CAAC;AACL,CAAC;AAQD,8BAA8B;AAC9B,MAAM,UAAU,UAAU,CACtB,IAAgB,EAChB,UAA6B,EAAE;IAE/B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,4EAA4E,CAAC;IACxF,CAAC;IAED,MAAM,EAAE,gBAAgB,GAAG,GAAG,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAE5D,OAAO,IAAI;SACN,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACT,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC;QAChD,IAAI,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAE1B,+CAA+C;QAC/C,IAAI,CAAC,OAAO,IAAI,gBAAgB,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;YACxE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,GAAG,mBAAmB,GAAG,CAAC,OAAO,CAAC,MAAM,SAAS,CAAC;QAClG,CAAC;QAED,OAAO,GAAG,IAAI,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC;IAC5C,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AAED,2BAA2B;AAC3B,MAAM,UAAU,OAAO,CACnB,SAAoB,EACpB,UAMI,EAAE;IAEN,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE,KAAK,GAAG,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC1F,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;IAC1D,OAAO;QACH,IAAI;QACJ,KAAK,EAAE,IAAI,CAAC,MAAM;QAClB,SAAS,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;KAC7D,CAAC;AACN,CAAC;AAED,8BAA8B;AAC9B,MAAM,UAAU,UAAU,CACtB,SAAoB,EACpB,IAAY,EACZ,UAII,EAAE;IAEN,MAAM,EAAE,UAAU,GAAG,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC/D,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAChD,OAAO;QACH,IAAI;QACJ,KAAK,EAAE,IAAI,CAAC,MAAM;QAClB,SAAS,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;KAC7D,CAAC;AACN,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,aAAa,CACzB,SAAoB,EACpB,UAGI,EAAE;IAEN,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,gBAAgB,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC;IACtD,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;IAEnC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,uBAAuB,CAAC;IACnC,CAAC;IAED,iBAAiB;IACjB,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACxB,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,kBAAkB;IAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC;QAChD,IAAI,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC1B,IAAI,gBAAgB,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAC5D,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC;QACzD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type AppIdentity, type LogEvent, type EventLevel, type RawLogLine } from "./logEvents.js";
|
|
2
|
+
import type { ConnectedApp } from "./types.js";
|
|
3
|
+
/** simulatorUdid ?? adbSerial. Never deviceName — two sims can share a name. */
|
|
4
|
+
export declare function deviceKeyOf(app: ConnectedApp): string | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* Build identity for a connected app. iOS bundle ids and Android package names
|
|
7
|
+
* differ for the same product, so this is always per-device and never global.
|
|
8
|
+
*
|
|
9
|
+
* `deviceKeyOverride` covers apps found via `matchAndroidAppBySerial`: their
|
|
10
|
+
* OWN `adbSerial` is exactly the null value that made the direct lookup miss
|
|
11
|
+
* in the first place, so `deviceKeyOf(app)` would still fail here — the
|
|
12
|
+
* caller passes the discovered device's serial instead, which is what the
|
|
13
|
+
* native buffer is actually keyed by.
|
|
14
|
+
*/
|
|
15
|
+
export declare function identityFromApp(app: ConnectedApp, deviceKeyOverride?: string): AppIdentity | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Last-known identity for a device that is no longer connected — the crash
|
|
18
|
+
* case, where there is no ConnectedApp to read appId from.
|
|
19
|
+
*
|
|
20
|
+
* Residual limitation: this can only find an appId that was previously
|
|
21
|
+
* recorded under `deviceKey` or `deviceName`. `resolveLogTargets` writes the
|
|
22
|
+
* live identity under `deviceKey` (the udid / adb serial) via `recordDevice`
|
|
23
|
+
* while the app is connected, which is what makes this succeed after a
|
|
24
|
+
* crash — but if the app has never been connected on this device in this
|
|
25
|
+
* project, there is nothing to find. That is a designed degradation, not a
|
|
26
|
+
* bug: the device still runs in crash-buffer-only mode, and crashes still
|
|
27
|
+
* surface with their declared owner.
|
|
28
|
+
*/
|
|
29
|
+
export declare function identityFromMemory(deviceKey: string, platform: "ios" | "android", deviceName?: string): AppIdentity | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* ownership -> grouping -> relevance -> ingest.
|
|
32
|
+
*
|
|
33
|
+
* Relevance runs after grouping because it tests `kind`, which the grouper
|
|
34
|
+
* assigns; a floor applied to raw lines would shred backtrace continuations.
|
|
35
|
+
*/
|
|
36
|
+
export declare function runNativePipeline(lines: RawLogLine[], identity: AppIdentity, deviceName: string, opts: {
|
|
37
|
+
minLevel: EventLevel;
|
|
38
|
+
}): {
|
|
39
|
+
events: LogEvent[];
|
|
40
|
+
};
|
|
41
|
+
export interface LogTarget {
|
|
42
|
+
/** simulatorUdid (iOS) | adb serial (Android). The buffer key. */
|
|
43
|
+
deviceKey: string;
|
|
44
|
+
deviceName: string;
|
|
45
|
+
platform: "ios" | "android";
|
|
46
|
+
/** Android only — what `adb -s` accepts. */
|
|
47
|
+
adbSerial?: string;
|
|
48
|
+
/** Absent when the app has never connected on this device. */
|
|
49
|
+
identity?: AppIdentity;
|
|
50
|
+
/** Where `identity` came from — memory-sourced ids can be stale. */
|
|
51
|
+
identitySource?: "live" | "memory";
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Every device we could read logs from — NOT just connected ones.
|
|
55
|
+
*
|
|
56
|
+
* A crashed app has no CDP connection, so connectedApps is empty exactly when
|
|
57
|
+
* this feature is most needed. Discovery is the source of truth for "which
|
|
58
|
+
* devices exist"; connectedApps and projectMemory only enrich them with
|
|
59
|
+
* identity. Shutdown simulators and stopped emulators are excluded — there is
|
|
60
|
+
* no log stream to read.
|
|
61
|
+
*/
|
|
62
|
+
export declare function resolveLogTargets(device?: string): Promise<LogTarget[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Fan out across every device in parallel. A device that fails degrades to a
|
|
65
|
+
* note; the others still answer.
|
|
66
|
+
*/
|
|
67
|
+
export declare function collectNativeEvents(opts: {
|
|
68
|
+
device?: string;
|
|
69
|
+
minLevel: EventLevel;
|
|
70
|
+
since?: Date;
|
|
71
|
+
}): Promise<{
|
|
72
|
+
events: LogEvent[];
|
|
73
|
+
notes: string[];
|
|
74
|
+
}>;
|
|
75
|
+
//# sourceMappingURL=nativeLogs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeLogs.d.ts","sourceRoot":"","sources":["../../src/core/nativeLogs.ts"],"names":[],"mappings":"AAIA,OAAO,EAEH,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,UAAU,EAClB,MAAM,gBAAgB,CAAC;AAMxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAEjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC3B,GAAG,EAAE,YAAY,EACjB,iBAAiB,CAAC,EAAE,MAAM,GAC3B,WAAW,GAAG,SAAS,CAIzB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAC9B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,KAAK,GAAG,SAAS,EAC3B,UAAU,CAAC,EAAE,MAAM,GACpB,WAAW,GAAG,SAAS,CAYzB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC7B,KAAK,EAAE,UAAU,EAAE,EACnB,QAAQ,EAAE,WAAW,EACrB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE;IAAE,QAAQ,EAAE,UAAU,CAAA;CAAE,GAC/B;IAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;CAAE,CASxB;AAED,MAAM,WAAW,SAAS;IACtB,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CACtC;AAiCD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CA2E7E;AAoDD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,UAAU,CAAC;IACrB,KAAK,CAAC,EAAE,IAAI,CAAC;CAChB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAsBnD"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { connectedApps } from "./state.js";
|
|
2
|
+
import { listDevices, recordDevice } from "./projectMemory.js";
|
|
3
|
+
import { listAllDevices } from "./deviceDiscovery.js";
|
|
4
|
+
import { execAsync } from "./exec.js";
|
|
5
|
+
import { getNativeLogBuffer, } from "./logEvents.js";
|
|
6
|
+
import { isOwned } from "./logOwnership.js";
|
|
7
|
+
import { groupIntoEvents } from "./logGrouping.js";
|
|
8
|
+
import { isRelevant } from "./logRelevance.js";
|
|
9
|
+
import { fetchAndroidLines, resolveAndroidPid } from "./logSourceAndroid.js";
|
|
10
|
+
import { fetchIosLines, resolveIosProcessName } from "./logSourceIos.js";
|
|
11
|
+
/** simulatorUdid ?? adbSerial. Never deviceName — two sims can share a name. */
|
|
12
|
+
export function deviceKeyOf(app) {
|
|
13
|
+
return app.simulatorUdid ?? app.adbSerial;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Build identity for a connected app. iOS bundle ids and Android package names
|
|
17
|
+
* differ for the same product, so this is always per-device and never global.
|
|
18
|
+
*
|
|
19
|
+
* `deviceKeyOverride` covers apps found via `matchAndroidAppBySerial`: their
|
|
20
|
+
* OWN `adbSerial` is exactly the null value that made the direct lookup miss
|
|
21
|
+
* in the first place, so `deviceKeyOf(app)` would still fail here — the
|
|
22
|
+
* caller passes the discovered device's serial instead, which is what the
|
|
23
|
+
* native buffer is actually keyed by.
|
|
24
|
+
*/
|
|
25
|
+
export function identityFromApp(app, deviceKeyOverride) {
|
|
26
|
+
const deviceKey = deviceKeyOverride ?? deviceKeyOf(app);
|
|
27
|
+
if (!deviceKey || !app.deviceInfo.appId)
|
|
28
|
+
return undefined;
|
|
29
|
+
return { deviceKey, platform: app.platform, appId: app.deviceInfo.appId };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Last-known identity for a device that is no longer connected — the crash
|
|
33
|
+
* case, where there is no ConnectedApp to read appId from.
|
|
34
|
+
*
|
|
35
|
+
* Residual limitation: this can only find an appId that was previously
|
|
36
|
+
* recorded under `deviceKey` or `deviceName`. `resolveLogTargets` writes the
|
|
37
|
+
* live identity under `deviceKey` (the udid / adb serial) via `recordDevice`
|
|
38
|
+
* while the app is connected, which is what makes this succeed after a
|
|
39
|
+
* crash — but if the app has never been connected on this device in this
|
|
40
|
+
* project, there is nothing to find. That is a designed degradation, not a
|
|
41
|
+
* bug: the device still runs in crash-buffer-only mode, and crashes still
|
|
42
|
+
* surface with their declared owner.
|
|
43
|
+
*/
|
|
44
|
+
export function identityFromMemory(deviceKey, platform, deviceName) {
|
|
45
|
+
const devices = listDevices();
|
|
46
|
+
// projectMemory records a device under whichever identifier the resolving
|
|
47
|
+
// caller used — the adb serial on some paths, the RN deviceName on others —
|
|
48
|
+
// so one physical device can hold two entries with only one carrying the
|
|
49
|
+
// appId. Both keys must be tried, and a matching row with no appId must not
|
|
50
|
+
// shadow one that has it, or this fallback never fires on Android.
|
|
51
|
+
const remembered = devices.find((d) => d.identifier === deviceKey && d.appId) ??
|
|
52
|
+
(deviceName ? devices.find((d) => d.identifier === deviceName && d.appId) : undefined);
|
|
53
|
+
if (!remembered?.appId)
|
|
54
|
+
return undefined;
|
|
55
|
+
return { deviceKey, platform, appId: remembered.appId };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* ownership -> grouping -> relevance -> ingest.
|
|
59
|
+
*
|
|
60
|
+
* Relevance runs after grouping because it tests `kind`, which the grouper
|
|
61
|
+
* assigns; a floor applied to raw lines would shred backtrace continuations.
|
|
62
|
+
*/
|
|
63
|
+
export function runNativePipeline(lines, identity, deviceName, opts) {
|
|
64
|
+
const owned = lines.filter((l) => isOwned(l, identity).owned);
|
|
65
|
+
const drafts = groupIntoEvents(owned, {
|
|
66
|
+
deviceKey: identity.deviceKey,
|
|
67
|
+
deviceName,
|
|
68
|
+
source: "native",
|
|
69
|
+
});
|
|
70
|
+
const relevant = drafts.filter((d) => isRelevant(d, { minLevel: opts.minLevel }));
|
|
71
|
+
return { events: getNativeLogBuffer(identity.deviceKey).ingest(relevant) };
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Find the ConnectedApp for a discovered Android device.
|
|
75
|
+
*
|
|
76
|
+
* ConnectedApp.adbSerial is frequently null — types.ts documents it as only
|
|
77
|
+
* populated when getAdbIdForAvd happens to match at connect time — so keying
|
|
78
|
+
* on it alone means Android never gets live identity, and every Android read
|
|
79
|
+
* silently degrades to crash-buffer-only. The three Android names (adb serial,
|
|
80
|
+
* AVD name, RN/Metro deviceName) do not join, and resolveDeviceTarget cannot
|
|
81
|
+
* bridge them either.
|
|
82
|
+
*
|
|
83
|
+
* Metro labels Android targets `${MODEL} - ${RELEASE} - API ${SDK}`, so
|
|
84
|
+
* ro.product.model is a deterministic prefix of the RN deviceName. Verified
|
|
85
|
+
* live: model "sdk_gphone16k_arm64" vs "sdk_gphone16k_arm64 - 16 - API 36".
|
|
86
|
+
*/
|
|
87
|
+
async function matchAndroidAppBySerial(serial, apps) {
|
|
88
|
+
const candidates = apps.filter((a) => a.platform === "android");
|
|
89
|
+
if (candidates.length === 0)
|
|
90
|
+
return undefined;
|
|
91
|
+
try {
|
|
92
|
+
const { stdout } = await execAsync(`adb -s ${serial} shell getprop ro.product.model`);
|
|
93
|
+
const model = stdout.trim();
|
|
94
|
+
if (!model)
|
|
95
|
+
return undefined;
|
|
96
|
+
return candidates.find((a) => (a.deviceInfo.deviceName ?? "").startsWith(model));
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Best-effort: fall through to memory / crash-only as before.
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Every device we could read logs from — NOT just connected ones.
|
|
105
|
+
*
|
|
106
|
+
* A crashed app has no CDP connection, so connectedApps is empty exactly when
|
|
107
|
+
* this feature is most needed. Discovery is the source of truth for "which
|
|
108
|
+
* devices exist"; connectedApps and projectMemory only enrich them with
|
|
109
|
+
* identity. Shutdown simulators and stopped emulators are excluded — there is
|
|
110
|
+
* no log stream to read.
|
|
111
|
+
*/
|
|
112
|
+
export async function resolveLogTargets(device) {
|
|
113
|
+
const connected = new Map();
|
|
114
|
+
for (const app of connectedApps.values()) {
|
|
115
|
+
const key = deviceKeyOf(app);
|
|
116
|
+
if (key)
|
|
117
|
+
connected.set(key, app);
|
|
118
|
+
}
|
|
119
|
+
const discovered = await listAllDevices();
|
|
120
|
+
const rows = [];
|
|
121
|
+
for (const sim of discovered.ios.simulators) {
|
|
122
|
+
if (sim.state !== "booted")
|
|
123
|
+
continue;
|
|
124
|
+
rows.push({ deviceKey: sim.udid, name: sim.name, platform: "ios" });
|
|
125
|
+
}
|
|
126
|
+
for (const emu of discovered.android.emulators) {
|
|
127
|
+
if (emu.state !== "running" || !emu.serial)
|
|
128
|
+
continue;
|
|
129
|
+
rows.push({ deviceKey: emu.serial, name: emu.name, platform: "android", adbSerial: emu.serial });
|
|
130
|
+
}
|
|
131
|
+
for (const phys of discovered.android.physical) {
|
|
132
|
+
if (phys.state !== "device")
|
|
133
|
+
continue;
|
|
134
|
+
rows.push({ deviceKey: phys.serial, name: phys.model, platform: "android", adbSerial: phys.serial });
|
|
135
|
+
}
|
|
136
|
+
const targets = [];
|
|
137
|
+
for (const row of rows) {
|
|
138
|
+
let app = connected.get(row.deviceKey);
|
|
139
|
+
// adbSerial is frequently null (see matchAndroidAppBySerial), so the
|
|
140
|
+
// serial-keyed lookup above routinely misses even a live app. Fall
|
|
141
|
+
// back to the deterministic model-prefix match before giving up —
|
|
142
|
+
// note the matched app's OWN adbSerial is still null, so its identity
|
|
143
|
+
// must be keyed by row.deviceKey, not recomputed from the app itself.
|
|
144
|
+
let matchedByModel = false;
|
|
145
|
+
if (!app && row.platform === "android") {
|
|
146
|
+
app = await matchAndroidAppBySerial(row.deviceKey, [...connectedApps.values()]);
|
|
147
|
+
matchedByModel = app !== undefined;
|
|
148
|
+
}
|
|
149
|
+
const deviceName = app?.deviceInfo.deviceName || row.name || row.deviceKey;
|
|
150
|
+
if (device) {
|
|
151
|
+
const hay = `${deviceName} ${row.deviceKey}`.toLowerCase();
|
|
152
|
+
if (!hay.includes(device.toLowerCase()))
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
// Chain: live connection -> remembered -> none (crash-buffer-only).
|
|
156
|
+
const live = app
|
|
157
|
+
? identityFromApp(app, matchedByModel ? row.deviceKey : undefined)
|
|
158
|
+
: undefined;
|
|
159
|
+
if (live) {
|
|
160
|
+
// Persist identity under the SAME key the native buffer uses (udid /
|
|
161
|
+
// adb serial). projectMemory is otherwise keyed by whatever
|
|
162
|
+
// identifier the resolving caller happened to use — on Android the
|
|
163
|
+
// appId-bearing row is keyed by the RN deviceName, which nothing
|
|
164
|
+
// links back to the serial. Recording it here while the app is alive
|
|
165
|
+
// is what lets identity survive the crash we later want to explain.
|
|
166
|
+
recordDevice({
|
|
167
|
+
identifier: row.deviceKey,
|
|
168
|
+
name: deviceName,
|
|
169
|
+
platform: row.platform,
|
|
170
|
+
appId: live.appId,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
const remembered = live
|
|
174
|
+
? undefined
|
|
175
|
+
: identityFromMemory(row.deviceKey, row.platform, row.name);
|
|
176
|
+
targets.push({
|
|
177
|
+
deviceKey: row.deviceKey,
|
|
178
|
+
deviceName,
|
|
179
|
+
platform: row.platform,
|
|
180
|
+
adbSerial: row.adbSerial ?? app?.adbSerial,
|
|
181
|
+
identity: live ?? remembered,
|
|
182
|
+
identitySource: live ? "live" : remembered ? "memory" : undefined,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return targets;
|
|
186
|
+
}
|
|
187
|
+
async function fetchForTarget(target, opts) {
|
|
188
|
+
const buffer = getNativeLogBuffer(target.deviceKey);
|
|
189
|
+
const sinceTs = opts.since ?? buffer.watermark;
|
|
190
|
+
try {
|
|
191
|
+
if (!target.identity) {
|
|
192
|
+
// Crash-buffer-only: no identity, so no ownership filtering is
|
|
193
|
+
// possible. That buffer is tiny and near-100% signal, and each
|
|
194
|
+
// event names its own owner, so this stays useful.
|
|
195
|
+
const lines = target.platform === "android"
|
|
196
|
+
? await fetchAndroidLines({ serial: target.adbSerial, sinceTs, crashOnly: true })
|
|
197
|
+
: await fetchIosLines({ udid: target.deviceKey, sinceTs, minMessageType: "fault" });
|
|
198
|
+
const drafts = groupIntoEvents(lines, {
|
|
199
|
+
deviceKey: target.deviceKey,
|
|
200
|
+
deviceName: target.deviceName,
|
|
201
|
+
source: "native",
|
|
202
|
+
}).filter((d) => d.kind === "crash" || d.kind === "anr");
|
|
203
|
+
return {
|
|
204
|
+
events: buffer.ingest(drafts),
|
|
205
|
+
note: `${target.deviceName}: no app identity known — showing crashes only`,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
const identity = { ...target.identity };
|
|
209
|
+
let lines;
|
|
210
|
+
if (target.platform === "android") {
|
|
211
|
+
// Re-resolved every call: the pid changes on every app restart,
|
|
212
|
+
// and is absent entirely after a crash.
|
|
213
|
+
identity.pid = await resolveAndroidPid(identity.appId, target.adbSerial);
|
|
214
|
+
lines = await fetchAndroidLines({ serial: target.adbSerial, sinceTs });
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
const processName = await resolveIosProcessName(target.deviceKey, identity.appId);
|
|
218
|
+
lines = await fetchIosLines({ udid: target.deviceKey, processName, sinceTs });
|
|
219
|
+
}
|
|
220
|
+
const result = runNativePipeline(lines, identity, target.deviceName, { minLevel: opts.minLevel });
|
|
221
|
+
return target.identitySource === "memory"
|
|
222
|
+
? {
|
|
223
|
+
...result,
|
|
224
|
+
note: `${target.deviceName}: app identity "${identity.appId}" came from project memory (app not currently connected) — if this is stale, events will be filtered out`,
|
|
225
|
+
}
|
|
226
|
+
: result;
|
|
227
|
+
}
|
|
228
|
+
catch (err) {
|
|
229
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
230
|
+
return { events: [], note: `${target.deviceName}: unavailable (${reason})` };
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Fan out across every device in parallel. A device that fails degrades to a
|
|
235
|
+
* note; the others still answer.
|
|
236
|
+
*/
|
|
237
|
+
export async function collectNativeEvents(opts) {
|
|
238
|
+
const targets = await resolveLogTargets(opts.device);
|
|
239
|
+
if (targets.length === 0) {
|
|
240
|
+
return { events: [], notes: ["No iOS simulators or Android devices found."] };
|
|
241
|
+
}
|
|
242
|
+
const settled = await Promise.allSettled(targets.map((t) => fetchForTarget(t, opts)));
|
|
243
|
+
const events = [];
|
|
244
|
+
const notes = [];
|
|
245
|
+
for (const result of settled) {
|
|
246
|
+
if (result.status === "fulfilled") {
|
|
247
|
+
events.push(...result.value.events);
|
|
248
|
+
if (result.value.note)
|
|
249
|
+
notes.push(result.value.note);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
notes.push(`device unavailable: ${String(result.reason)}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Exact within a device, approximate across devices — emulator clocks
|
|
256
|
+
// measured 4s of skew from the host, which we cannot correct for.
|
|
257
|
+
events.sort((a, b) => a.ts.getTime() - b.ts.getTime());
|
|
258
|
+
return { events, notes };
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=nativeLogs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeLogs.js","sourceRoot":"","sources":["../../src/core/nativeLogs.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ export interface ComponentSummary {
|
|
|
3
3
|
component: string;
|
|
4
4
|
count: number;
|
|
5
5
|
}
|
|
6
|
-
export declare function
|
|
6
|
+
export declare function formatSummaryCompact(components: ComponentSummary[], total: number): string;
|
|
7
7
|
export interface ScreenElement {
|
|
8
8
|
component: string;
|
|
9
9
|
path: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenLayout.d.ts","sourceRoot":"","sources":["../../src/core/screenLayout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,
|
|
1
|
+
{"version":3,"file":"screenLayout.d.ts","sourceRoot":"","sources":["../../src/core/screenLayout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,gBAAgB,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAM1F;AAMD,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAyND,wBAAgB,sBAAsB,CAClC,QAAQ,EAAE,aAAa,EAAE,EACzB,QAAQ,GAAE,OAAe,EACzB,SAAS,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GACrE,MAAM,CAuCR;AAYD,wBAAsB,eAAe,CACjC,OAAO,GAAE;IACL,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACjB,GACP,OAAO,CAAC,eAAe,GAAG;IACzB,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC,CA2hBD;AA0CD;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAC5C,UAAU,EAAE,MAAM,EAClB,qBAAqB,EAAE,MAAM,EAC7B,MAAM,CAAC,EAAE,MAAM,EACf,iBAAiB,GAAE,MAAU,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAmDxB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { executeInApp, delay } from "./jsExecute.js";
|
|
2
2
|
import { VISIBILITY_HELPERS_JS } from "./injected/visibility.js";
|
|
3
|
-
export function
|
|
3
|
+
export function formatSummaryCompact(components, total) {
|
|
4
4
|
const lines = [`#summary total=${total}`];
|
|
5
5
|
for (const c of components) {
|
|
6
6
|
lines.push(`${c.component}:${c.count}`);
|
|
@@ -763,8 +763,8 @@ export async function getScreenLayout(options = {}) {
|
|
|
763
763
|
const parsed = JSON.parse(result.result);
|
|
764
764
|
if (parsed.components) {
|
|
765
765
|
// Summary mode
|
|
766
|
-
const
|
|
767
|
-
return { success: true, result:
|
|
766
|
+
const compact = formatSummaryCompact(parsed.components, parsed.totalElements);
|
|
767
|
+
return { success: true, result: compact };
|
|
768
768
|
}
|
|
769
769
|
else if (parsed.elements) {
|
|
770
770
|
if (raw) {
|