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.
Files changed (135) hide show
  1. package/README.md +1 -1
  2. package/build/__tests__/integration/native-logs.test.d.ts +2 -0
  3. package/build/__tests__/integration/native-logs.test.d.ts.map +1 -0
  4. package/build/__tests__/integration/native-logs.test.js +39 -0
  5. package/build/__tests__/integration/native-logs.test.js.map +1 -0
  6. package/build/__tests__/unit/clearLogsNative.test.d.ts +2 -0
  7. package/build/__tests__/unit/clearLogsNative.test.d.ts.map +1 -0
  8. package/build/__tests__/unit/clearLogsNative.test.js +43 -0
  9. package/build/__tests__/unit/clearLogsNative.test.js.map +1 -0
  10. package/build/__tests__/unit/componentFormatNaming.test.d.ts +2 -0
  11. package/build/__tests__/unit/componentFormatNaming.test.d.ts.map +1 -0
  12. package/build/__tests__/unit/componentFormatNaming.test.js +32 -0
  13. package/build/__tests__/unit/componentFormatNaming.test.js.map +1 -0
  14. package/build/__tests__/unit/getLogsEmptyContract.test.js +20 -7
  15. package/build/__tests__/unit/getLogsEmptyContract.test.js.map +1 -1
  16. package/build/__tests__/unit/getLogsNativeSource.test.d.ts +2 -0
  17. package/build/__tests__/unit/getLogsNativeSource.test.d.ts.map +1 -0
  18. package/build/__tests__/unit/getLogsNativeSource.test.js +138 -0
  19. package/build/__tests__/unit/getLogsNativeSource.test.js.map +1 -0
  20. package/build/__tests__/unit/jsLogEvents.test.d.ts +2 -0
  21. package/build/__tests__/unit/jsLogEvents.test.d.ts.map +1 -0
  22. package/build/__tests__/unit/jsLogEvents.test.js +58 -0
  23. package/build/__tests__/unit/jsLogEvents.test.js.map +1 -0
  24. package/build/__tests__/unit/logEventFormat.test.d.ts +2 -0
  25. package/build/__tests__/unit/logEventFormat.test.d.ts.map +1 -0
  26. package/build/__tests__/unit/logEventFormat.test.js +210 -0
  27. package/build/__tests__/unit/logEventFormat.test.js.map +1 -0
  28. package/build/__tests__/unit/logEvents.test.d.ts +2 -0
  29. package/build/__tests__/unit/logEvents.test.d.ts.map +1 -0
  30. package/build/__tests__/unit/logEvents.test.js +118 -0
  31. package/build/__tests__/unit/logEvents.test.js.map +1 -0
  32. package/build/__tests__/unit/logGrouping.test.d.ts +2 -0
  33. package/build/__tests__/unit/logGrouping.test.d.ts.map +1 -0
  34. package/build/__tests__/unit/logGrouping.test.js +104 -0
  35. package/build/__tests__/unit/logGrouping.test.js.map +1 -0
  36. package/build/__tests__/unit/logOwnership.test.d.ts +2 -0
  37. package/build/__tests__/unit/logOwnership.test.d.ts.map +1 -0
  38. package/build/__tests__/unit/logOwnership.test.js +118 -0
  39. package/build/__tests__/unit/logOwnership.test.js.map +1 -0
  40. package/build/__tests__/unit/logRelevance.test.d.ts +2 -0
  41. package/build/__tests__/unit/logRelevance.test.d.ts.map +1 -0
  42. package/build/__tests__/unit/logRelevance.test.js +30 -0
  43. package/build/__tests__/unit/logRelevance.test.js.map +1 -0
  44. package/build/__tests__/unit/logSourceAndroid.test.d.ts +2 -0
  45. package/build/__tests__/unit/logSourceAndroid.test.d.ts.map +1 -0
  46. package/build/__tests__/unit/logSourceAndroid.test.js +61 -0
  47. package/build/__tests__/unit/logSourceAndroid.test.js.map +1 -0
  48. package/build/__tests__/unit/logSourceIos.test.d.ts +2 -0
  49. package/build/__tests__/unit/logSourceIos.test.d.ts.map +1 -0
  50. package/build/__tests__/unit/logSourceIos.test.js +64 -0
  51. package/build/__tests__/unit/logSourceIos.test.js.map +1 -0
  52. package/build/__tests__/unit/logs.test.js +23 -0
  53. package/build/__tests__/unit/logs.test.js.map +1 -1
  54. package/build/__tests__/unit/nativeLogs.test.d.ts +2 -0
  55. package/build/__tests__/unit/nativeLogs.test.d.ts.map +1 -0
  56. package/build/__tests__/unit/nativeLogs.test.js +230 -0
  57. package/build/__tests__/unit/nativeLogs.test.js.map +1 -0
  58. package/build/__tests__/unit/toolsJson.test.js +11 -0
  59. package/build/__tests__/unit/toolsJson.test.js.map +1 -1
  60. package/build/core/componentSearch.d.ts +1 -1
  61. package/build/core/componentSearch.d.ts.map +1 -1
  62. package/build/core/componentSearch.js +8 -8
  63. package/build/core/componentSearch.js.map +1 -1
  64. package/build/core/componentTree.d.ts +1 -1
  65. package/build/core/componentTree.d.ts.map +1 -1
  66. package/build/core/componentTree.js +8 -8
  67. package/build/core/componentTree.js.map +1 -1
  68. package/build/core/guides.d.ts.map +1 -1
  69. package/build/core/guides.js +25 -0
  70. package/build/core/guides.js.map +1 -1
  71. package/build/core/index.d.ts +0 -2
  72. package/build/core/index.d.ts.map +1 -1
  73. package/build/core/index.js +0 -2
  74. package/build/core/index.js.map +1 -1
  75. package/build/core/jsLogEvents.d.ts +13 -0
  76. package/build/core/jsLogEvents.d.ts.map +1 -0
  77. package/build/core/jsLogEvents.js +65 -0
  78. package/build/core/jsLogEvents.js.map +1 -0
  79. package/build/core/logEventFormat.d.ts +14 -0
  80. package/build/core/logEventFormat.d.ts.map +1 -0
  81. package/build/core/logEventFormat.js +85 -0
  82. package/build/core/logEventFormat.js.map +1 -0
  83. package/build/core/logEvents.d.ts +115 -0
  84. package/build/core/logEvents.d.ts.map +1 -0
  85. package/build/core/logEvents.js +146 -0
  86. package/build/core/logEvents.js.map +1 -0
  87. package/build/core/logGrouping.d.ts +17 -0
  88. package/build/core/logGrouping.d.ts.map +1 -0
  89. package/build/core/logGrouping.js +134 -0
  90. package/build/core/logGrouping.js.map +1 -0
  91. package/build/core/logOwnership.d.ts +29 -0
  92. package/build/core/logOwnership.d.ts.map +1 -0
  93. package/build/core/logOwnership.js +83 -0
  94. package/build/core/logOwnership.js.map +1 -0
  95. package/build/core/logRelevance.d.ts +13 -0
  96. package/build/core/logRelevance.d.ts.map +1 -0
  97. package/build/core/logRelevance.js +23 -0
  98. package/build/core/logRelevance.js.map +1 -0
  99. package/build/core/logSourceAndroid.d.ts +27 -0
  100. package/build/core/logSourceAndroid.d.ts.map +1 -0
  101. package/build/core/logSourceAndroid.js +89 -0
  102. package/build/core/logSourceAndroid.js.map +1 -0
  103. package/build/core/logSourceIos.d.ts +26 -0
  104. package/build/core/logSourceIos.d.ts.map +1 -0
  105. package/build/core/logSourceIos.js +119 -0
  106. package/build/core/logSourceIos.js.map +1 -0
  107. package/build/core/logs.d.ts +5 -1
  108. package/build/core/logs.d.ts.map +1 -1
  109. package/build/core/logs.js +8 -1
  110. package/build/core/logs.js.map +1 -1
  111. package/build/core/nativeLogs.d.ts +75 -0
  112. package/build/core/nativeLogs.d.ts.map +1 -0
  113. package/build/core/nativeLogs.js +260 -0
  114. package/build/core/nativeLogs.js.map +1 -0
  115. package/build/core/screenLayout.d.ts +1 -1
  116. package/build/core/screenLayout.d.ts.map +1 -1
  117. package/build/core/screenLayout.js +3 -3
  118. package/build/core/screenLayout.js.map +1 -1
  119. package/build/core/types.d.ts +3 -2
  120. package/build/core/types.d.ts.map +1 -1
  121. package/build/tools/componentTools.js +6 -6
  122. package/build/tools/componentTools.js.map +1 -1
  123. package/build/tools/logTools.d.ts +25 -0
  124. package/build/tools/logTools.d.ts.map +1 -1
  125. package/build/tools/logTools.js +246 -70
  126. package/build/tools/logTools.js.map +1 -1
  127. package/build/tools/networkTools.d.ts.map +1 -1
  128. package/build/tools/networkTools.js +5 -44
  129. package/build/tools/networkTools.js.map +1 -1
  130. package/package.json +6 -4
  131. package/tools.json +447 -0
  132. package/build/core/format.d.ts +0 -8
  133. package/build/core/format.d.ts.map +0 -1
  134. package/build/core/format.js +0 -34
  135. package/build/core/format.js.map +0 -1
@@ -0,0 +1,146 @@
1
+ import { createHash } from "node:crypto";
2
+ export const LEVEL_RANK = {
3
+ debug: 0,
4
+ log: 1,
5
+ info: 2,
6
+ warn: 3,
7
+ error: 4,
8
+ fatal: 5,
9
+ };
10
+ /**
11
+ * Identity of an event, derived from its FIRST line only.
12
+ *
13
+ * `logcat -T <ts>` is inclusive of the boundary, so the last event seen always
14
+ * comes back on the next fetch — and it may come back truncated if the window
15
+ * cut mid-backtrace. Hashing only the header line keeps the two reads equal.
16
+ * The device timestamp is used, never the host clock: emulators measured 4s
17
+ * of skew, which would make host-derived hashes unstable.
18
+ */
19
+ export function fingerprintEvent(lines, deviceKey) {
20
+ const head = lines[0];
21
+ if (!head)
22
+ return createHash("sha1").update(`${deviceKey}|empty`).digest("hex");
23
+ const parts = [
24
+ deviceKey,
25
+ head.ts.toISOString(),
26
+ String(head.pid),
27
+ head.tag,
28
+ head.message,
29
+ ];
30
+ // JSON.stringify, not join("|"): log messages and tags are free-form and
31
+ // routinely contain the separator, which would let two different field
32
+ // splits hash identically and silently collapse two distinct events into
33
+ // one during dedupe.
34
+ return createHash("sha1").update(JSON.stringify(parts)).digest("hex");
35
+ }
36
+ // Process-global so an id identifies exactly one event across every device,
37
+ // and get_log_details needs no device argument. Deliberately NOT the
38
+ // per-device numbering that resolveNetworkBuffer had to retrofit with a
39
+ // "@deviceName" suffix after ids collided.
40
+ let nextNativeId = 1;
41
+ export class NativeLogBuffer {
42
+ events = [];
43
+ seen = new Set();
44
+ lastTs;
45
+ maxSize;
46
+ /**
47
+ * How many fingerprints to retain relative to stored events.
48
+ *
49
+ * `seen` does NOT need to cover all history: the watermark already stops
50
+ * `logcat -T` from returning anything older than the last fetch, so the
51
+ * only thing `seen` must absorb is the inclusive-boundary overlap — a
52
+ * handful of events. Retaining several times maxSize is far more than
53
+ * that window needs while keeping memory bounded in a long-lived server.
54
+ */
55
+ static SEEN_RETENTION_MULTIPLE = 4;
56
+ constructor(maxSize = 200) {
57
+ this.maxSize = maxSize;
58
+ }
59
+ /** Append unseen drafts, assigning ids. Returns only what was new. */
60
+ ingest(drafts) {
61
+ const added = [];
62
+ for (const d of drafts) {
63
+ if (this.seen.has(d.fingerprint))
64
+ continue;
65
+ this.seen.add(d.fingerprint);
66
+ const event = { ...d, id: `n${nextNativeId++}` };
67
+ this.events.push(event);
68
+ added.push(event);
69
+ if (!this.lastTs || d.ts > this.lastTs)
70
+ this.lastTs = d.ts;
71
+ }
72
+ while (this.events.length > this.maxSize)
73
+ this.events.shift();
74
+ // Set iteration is insertion-ordered, so this drops the oldest
75
+ // fingerprints first.
76
+ const seenCap = this.maxSize * NativeLogBuffer.SEEN_RETENTION_MULTIPLE;
77
+ while (this.seen.size > seenCap) {
78
+ const oldest = this.seen.values().next().value;
79
+ if (oldest === undefined)
80
+ break;
81
+ this.seen.delete(oldest);
82
+ }
83
+ return added;
84
+ }
85
+ list() {
86
+ return [...this.events];
87
+ }
88
+ get(id) {
89
+ return this.events.find((e) => e.id === id);
90
+ }
91
+ /** Retained fingerprint count. Exposed for tests that assert bounded growth. */
92
+ get seenSize() {
93
+ return this.seen.size;
94
+ }
95
+ /**
96
+ * Clears stored events but NOT the seen-set or watermark — otherwise the
97
+ * next fetch re-ingests everything the caller just cleared.
98
+ */
99
+ clear() {
100
+ const count = this.events.length;
101
+ this.events = [];
102
+ return count;
103
+ }
104
+ /** Newest ingested device timestamp. Drives `logcat -T` / `log show --start`. */
105
+ get watermark() {
106
+ return this.lastTs;
107
+ }
108
+ get size() {
109
+ return this.events.length;
110
+ }
111
+ }
112
+ export const nativeLogBuffers = new Map();
113
+ export function getNativeLogBuffer(deviceKey) {
114
+ let buffer = nativeLogBuffers.get(deviceKey);
115
+ if (!buffer) {
116
+ buffer = new NativeLogBuffer(200);
117
+ nativeLogBuffers.set(deviceKey, buffer);
118
+ }
119
+ return buffer;
120
+ }
121
+ /** Resolve an event id across every device buffer. */
122
+ export function findNativeEvent(id) {
123
+ for (const buffer of nativeLogBuffers.values()) {
124
+ const hit = buffer.get(id);
125
+ if (hit)
126
+ return hit;
127
+ }
128
+ return undefined;
129
+ }
130
+ /** Test-only. */
131
+ export function __resetNativeLogBuffers() {
132
+ nativeLogBuffers.clear();
133
+ nextNativeId = 1;
134
+ }
135
+ let jsResolver;
136
+ export function registerJsEventResolver(fn) {
137
+ jsResolver = fn;
138
+ }
139
+ export function findLogEvent(id) {
140
+ if (id.startsWith("n"))
141
+ return findNativeEvent(id);
142
+ if (id.startsWith("j"))
143
+ return jsResolver?.(id);
144
+ return undefined;
145
+ }
146
+ //# sourceMappingURL=logEvents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logEvents.js","sourceRoot":"","sources":["../../src/core/logEvents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type DraftEvent, type RawLogLine } from "./logEvents.js";
2
+ export interface GroupContext {
3
+ deviceKey: string;
4
+ deviceName: string;
5
+ source: "native" | "js";
6
+ }
7
+ /**
8
+ * Correlate lines into events.
9
+ *
10
+ * Continuation is keyed on (pid, tid, tag) rather than adjacency because
11
+ * logcat interleaves processes: a foreign line can land in the middle of a
12
+ * backtrace without ending it. Unmatched lines become single-line `message`
13
+ * events rather than being dropped, so an unrecognized crash format still
14
+ * surfaces — worse formatting, never silence.
15
+ */
16
+ export declare function groupIntoEvents(lines: RawLogLine[], ctx: GroupContext): DraftEvent[];
17
+ //# sourceMappingURL=logGrouping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logGrouping.d.ts","sourceRoot":"","sources":["../../src/core/logGrouping.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,KAAK,UAAU,EAGf,KAAK,UAAU,EAClB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC3B;AA+FD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,YAAY,GAAG,UAAU,EAAE,CAiCpF"}
@@ -0,0 +1,134 @@
1
+ import { fingerprintEvent, LEVEL_RANK, } from "./logEvents.js";
2
+ const CRASH_OPENERS = [/^\*{3}\s/, /^Cmdline:/, /^pid:\s+\d+.*>>>/];
3
+ const JAVA_CRASH_OPENER = /^FATAL EXCEPTION/;
4
+ const ANR_OPENER = /^ANR in /;
5
+ const JAVA_CONTINUATION = /^\s*(at\s|Caused by:|\.\.\.\s|[\w.$]+(Exception|Error)([:\s]|$))/;
6
+ /** `pid:tid:tag` — logcat interleaves processes, so adjacency cannot group. */
7
+ function streamKey(line) {
8
+ return `${line.pid}:${line.tid ?? line.pid}:${line.tag}`;
9
+ }
10
+ function openerKind(line) {
11
+ if (CRASH_OPENERS.some((re) => re.test(line.message)))
12
+ return "crash";
13
+ if (JAVA_CRASH_OPENER.test(line.message))
14
+ return "crash";
15
+ if (ANR_OPENER.test(line.message))
16
+ return "anr";
17
+ return null;
18
+ }
19
+ function continues(kind, open, line) {
20
+ if (streamKey(open) !== streamKey(line))
21
+ return false;
22
+ if (kind === "crash" && line.tag === "DEBUG")
23
+ return true;
24
+ if (kind === "crash" && line.tag === "AndroidRuntime") {
25
+ return JAVA_CONTINUATION.test(line.message) || /^Process:/.test(line.message);
26
+ }
27
+ if (kind === "anr")
28
+ return line.message.trim().length > 0;
29
+ return false;
30
+ }
31
+ /**
32
+ * Frame #00 of every abort is libc.so (abort+…) — the mechanism, not the
33
+ * cause — with the ART/libbase abort helpers stacked above it. Naming those
34
+ * gives every SIGABRT on every device an identical, useless title, so skip
35
+ * them and report the first frame belonging to real code. Falls back to the
36
+ * first library seen if the whole backtrace is runtime machinery.
37
+ */
38
+ const ABORT_MACHINERY = /^(libc|libc\+\+|libart|libbase|liblog|libutils|libcutils|libbacktrace|libunwindstack)\.so$/;
39
+ function culpritLibrary(lines) {
40
+ let fallback;
41
+ for (const line of lines) {
42
+ const m = line.message.match(/\/([\w.\-+]+\.so)\s*\(/);
43
+ if (!m)
44
+ continue;
45
+ if (!fallback)
46
+ fallback = m[1];
47
+ if (!ABORT_MACHINERY.test(m[1]))
48
+ return m[1];
49
+ }
50
+ return fallback;
51
+ }
52
+ function titleFor(kind, lines) {
53
+ const text = lines.map((l) => l.message).join("\n");
54
+ if (kind === "crash") {
55
+ const signal = text.match(/signal\s+\d+\s+\(([A-Z]+)\)/);
56
+ if (signal) {
57
+ const frames = lines.filter((l) => /^\s*#\d+\s+pc\s/.test(l.message)).length;
58
+ const so = culpritLibrary(lines);
59
+ const where = so ? ` in ${so}` : "";
60
+ return `${signal[1]}${where}${frames ? ` (${frames} frames)` : ""}`;
61
+ }
62
+ const java = text.match(/^([\w.$]+(?:Exception|Error))(?::\s*(.*))?$/m);
63
+ if (java) {
64
+ const frames = lines.filter((l) => /^\s*at\s/.test(l.message)).length;
65
+ const detail = java[2] ? `: ${java[2]}` : "";
66
+ return `${java[1]}${detail}${frames ? ` (${frames} frames)` : ""}`;
67
+ }
68
+ }
69
+ if (kind === "anr")
70
+ return lines[0].message;
71
+ const first = lines[0].message;
72
+ return first.length > 160 ? `${first.slice(0, 160)}…` : first;
73
+ }
74
+ function maxLevel(lines) {
75
+ return lines.reduce((acc, l) => (LEVEL_RANK[l.level] > LEVEL_RANK[acc] ? l.level : acc), "debug");
76
+ }
77
+ function toDraft(kind, lines, ctx) {
78
+ return {
79
+ source: ctx.source,
80
+ deviceKey: ctx.deviceKey,
81
+ deviceName: ctx.deviceName,
82
+ ts: lines[0].ts,
83
+ level: maxLevel(lines),
84
+ kind,
85
+ title: titleFor(kind, lines),
86
+ owner: lines.find((l) => l.subject)?.subject,
87
+ lineCount: lines.length,
88
+ byteSize: lines.reduce((n, l) => n + l.raw.length, 0),
89
+ fingerprint: fingerprintEvent(lines, ctx.deviceKey),
90
+ lines,
91
+ };
92
+ }
93
+ /**
94
+ * Correlate lines into events.
95
+ *
96
+ * Continuation is keyed on (pid, tid, tag) rather than adjacency because
97
+ * logcat interleaves processes: a foreign line can land in the middle of a
98
+ * backtrace without ending it. Unmatched lines become single-line `message`
99
+ * events rather than being dropped, so an unrecognized crash format still
100
+ * surfaces — worse formatting, never silence.
101
+ */
102
+ export function groupIntoEvents(lines, ctx) {
103
+ const events = [];
104
+ const open = new Map();
105
+ const flush = (key) => {
106
+ const group = open.get(key);
107
+ if (group) {
108
+ events.push(toDraft(group.kind, group.lines, ctx));
109
+ open.delete(key);
110
+ }
111
+ };
112
+ for (const line of lines) {
113
+ const key = streamKey(line);
114
+ const existing = open.get(key);
115
+ if (existing && continues(existing.kind, existing.lines[0], line)) {
116
+ existing.lines.push(line);
117
+ continue;
118
+ }
119
+ if (existing)
120
+ flush(key);
121
+ const kind = openerKind(line);
122
+ if (kind) {
123
+ open.set(key, { kind, lines: [line] });
124
+ }
125
+ else {
126
+ events.push(toDraft("message", [line], ctx));
127
+ }
128
+ }
129
+ for (const key of [...open.keys()])
130
+ flush(key);
131
+ events.sort((a, b) => a.ts.getTime() - b.ts.getTime());
132
+ return events;
133
+ }
134
+ //# sourceMappingURL=logGrouping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logGrouping.js","sourceRoot":"","sources":["../../src/core/logGrouping.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { AppIdentity, RawLogLine } from "./logEvents.js";
2
+ export type OwnReason = "declared" | "pid" | "verdict";
3
+ export type OwnershipVerdict = {
4
+ owned: true;
5
+ reason: OwnReason;
6
+ } | {
7
+ owned: false;
8
+ };
9
+ /**
10
+ * Tags whose lines are VERDICTS ABOUT an app rather than output FROM it.
11
+ *
12
+ * This allowlist is a hard gate, not a hint. Two measured traps make a bare
13
+ * "message contains the package name" rule wrong:
14
+ * - MMKV / nativeloader embed the package as a filesystem path
15
+ * - ActivityThread announces package changes from OTHER apps' pids
16
+ * Neither tag is listed, so the name check never runs for them.
17
+ */
18
+ export declare const ANDROID_VERDICT_TAGS: ReadonlySet<string>;
19
+ /** iOS equivalents: process termination and launch failure reporters. */
20
+ export declare const IOS_VERDICT_SUBSYSTEMS: ReadonlySet<string>;
21
+ /**
22
+ * Decide whether a line belongs to the app under test. First match wins.
23
+ *
24
+ * Rule order matters: `declared` precedes `pid` because a tombstone is written
25
+ * by tombstoned's pid while naming the dead app as its subject, so pid
26
+ * matching would miss every crash — the exact case this feature exists for.
27
+ */
28
+ export declare function isOwned(line: RawLogLine, identity: AppIdentity): OwnershipVerdict;
29
+ //# sourceMappingURL=logOwnership.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logOwnership.d.ts","sourceRoot":"","sources":["../../src/core/logOwnership.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE9D,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;AACvD,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAErF;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAQnD,CAAC;AAEH,yEAAyE;AACzE,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAGrD,CAAC;AAwCH;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,GAAG,gBAAgB,CAYjF"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Tags whose lines are VERDICTS ABOUT an app rather than output FROM it.
3
+ *
4
+ * This allowlist is a hard gate, not a hint. Two measured traps make a bare
5
+ * "message contains the package name" rule wrong:
6
+ * - MMKV / nativeloader embed the package as a filesystem path
7
+ * - ActivityThread announces package changes from OTHER apps' pids
8
+ * Neither tag is listed, so the name check never runs for them.
9
+ */
10
+ export const ANDROID_VERDICT_TAGS = new Set([
11
+ "ActivityManager",
12
+ "ActivityTaskManager",
13
+ "AndroidRuntime",
14
+ "DEBUG",
15
+ "lowmemorykiller",
16
+ "PackageManager",
17
+ "InputDispatcher",
18
+ ]);
19
+ /** iOS equivalents: process termination and launch failure reporters. */
20
+ export const IOS_VERDICT_SUBSYSTEMS = new Set([
21
+ "com.apple.runningboard",
22
+ "com.apple.FrontBoard",
23
+ ]);
24
+ /**
25
+ * Tags whose output is already carried by another source.
26
+ *
27
+ * React Native mirrors console.* into logcat under `ReactNativeJS`. Those lines
28
+ * are in the CDP console buffer too, so owning them here would double-report
29
+ * under source:"all" and bury crashes under ordinary app logging in
30
+ * source:"native". Keeping the two sources disjoint is what makes merging safe.
31
+ */
32
+ const MIRRORED_TAGS = new Set(["ReactNativeJS"]);
33
+ function isVerdictSource(line, platform) {
34
+ if (platform === "android")
35
+ return ANDROID_VERDICT_TAGS.has(line.tag);
36
+ // iOS tags are "subsystem:category" — match on the subsystem half.
37
+ const subsystem = line.tag.split(":")[0];
38
+ return IOS_VERDICT_SUBSYSTEMS.has(subsystem);
39
+ }
40
+ /**
41
+ * Does the message name this package as a whole identifier?
42
+ *
43
+ * A bare `includes` would attribute `ANR in com.acme.app.dev` to
44
+ * `com.acme.app`. Debug and release variants differing only by a Gradle
45
+ * applicationIdSuffix are routinely installed side by side, so the shorter
46
+ * id being a prefix of the longer one is the normal case, not an edge case.
47
+ */
48
+ function namesPackage(message, appId) {
49
+ const boundary = /[A-Za-z0-9_.]/;
50
+ let from = 0;
51
+ for (;;) {
52
+ const at = message.indexOf(appId, from);
53
+ if (at === -1)
54
+ return false;
55
+ const before = at === 0 ? "" : message[at - 1];
56
+ const after = message[at + appId.length] ?? "";
57
+ if (!boundary.test(before) && !boundary.test(after))
58
+ return true;
59
+ from = at + 1;
60
+ }
61
+ }
62
+ /**
63
+ * Decide whether a line belongs to the app under test. First match wins.
64
+ *
65
+ * Rule order matters: `declared` precedes `pid` because a tombstone is written
66
+ * by tombstoned's pid while naming the dead app as its subject, so pid
67
+ * matching would miss every crash — the exact case this feature exists for.
68
+ */
69
+ export function isOwned(line, identity) {
70
+ if (MIRRORED_TAGS.has(line.tag))
71
+ return { owned: false };
72
+ if (line.subject && line.subject === identity.appId) {
73
+ return { owned: true, reason: "declared" };
74
+ }
75
+ if (identity.pid !== undefined && line.pid === identity.pid) {
76
+ return { owned: true, reason: "pid" };
77
+ }
78
+ if (isVerdictSource(line, identity.platform) && namesPackage(line.message, identity.appId)) {
79
+ return { owned: true, reason: "verdict" };
80
+ }
81
+ return { owned: false };
82
+ }
83
+ //# sourceMappingURL=logOwnership.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logOwnership.js","sourceRoot":"","sources":["../../src/core/logOwnership.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAwB,IAAI,GAAG,CAAC;IAC7D,iBAAiB;IACjB,qBAAqB;IACrB,gBAAgB;IAChB,OAAO;IACP,iBAAiB;IACjB,gBAAgB;IAChB,iBAAiB;CACpB,CAAC,CAAC;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,sBAAsB,GAAwB,IAAI,GAAG,CAAC;IAC/D,wBAAwB;IACxB,sBAAsB;CACzB,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;AAEtE,SAAS,eAAe,CAAC,IAAgB,EAAE,QAAiC;IACxE,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtE,mEAAmE;IACnE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,OAAe,EAAE,KAAa;IAChD,MAAM,QAAQ,GAAG,eAAe,CAAC;IACjC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,SAAS,CAAC;QACN,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACxC,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAC5B,MAAM,MAAM,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACjE,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;IAClB,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,IAAgB,EAAE,QAAqB;IAC3D,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACzD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC/C,CAAC;IACD,IAAI,QAAQ,CAAC,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,EAAE,CAAC;QAC1D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC1C,CAAC;IACD,IAAI,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC9C,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type DraftEvent, type EventLevel } from "./logEvents.js";
2
+ /**
3
+ * Gate 2: is this event worth a row?
4
+ *
5
+ * Runs AFTER grouping, because it tests `kind` and only the grouper assigns
6
+ * that. The exemption matters: a backtrace's continuation lines carry no
7
+ * marker identifying them as part of a crash, so a floor applied to lines
8
+ * would shred exactly the events this feature exists to surface.
9
+ */
10
+ export declare function isRelevant(event: Pick<DraftEvent, "level" | "kind">, opts: {
11
+ minLevel: EventLevel;
12
+ }): boolean;
13
+ //# sourceMappingURL=logRelevance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logRelevance.d.ts","sourceRoot":"","sources":["../../src/core/logRelevance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,UAAU,EAAkB,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAW9F;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACtB,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,CAAC,EACzC,IAAI,EAAE;IAAE,QAAQ,EAAE,UAAU,CAAA;CAAE,GAC/B,OAAO,CAGT"}
@@ -0,0 +1,23 @@
1
+ import { LEVEL_RANK } from "./logEvents.js";
2
+ /**
3
+ * Kinds that are always worth a row, whatever their level.
4
+ *
5
+ * Typed by EventKind, not string: a typo here would silently disable the
6
+ * exemption that guarantees a severity floor can never filter out a crash,
7
+ * so it must fail the build rather than fail quietly.
8
+ */
9
+ const ALWAYS = new Set(["crash", "anr"]);
10
+ /**
11
+ * Gate 2: is this event worth a row?
12
+ *
13
+ * Runs AFTER grouping, because it tests `kind` and only the grouper assigns
14
+ * that. The exemption matters: a backtrace's continuation lines carry no
15
+ * marker identifying them as part of a crash, so a floor applied to lines
16
+ * would shred exactly the events this feature exists to surface.
17
+ */
18
+ export function isRelevant(event, opts) {
19
+ if (ALWAYS.has(event.kind))
20
+ return true;
21
+ return LEVEL_RANK[event.level] >= LEVEL_RANK[opts.minLevel];
22
+ }
23
+ //# sourceMappingURL=logRelevance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logRelevance.js","sourceRoot":"","sources":["../../src/core/logRelevance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAoD,MAAM,gBAAgB,CAAC;AAE9F;;;;;;GAMG;AACH,MAAM,MAAM,GAA2B,IAAI,GAAG,CAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AAE5E;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CACtB,KAAyC,EACzC,IAA8B;IAE9B,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { RawLogLine } from "./logEvents.js";
2
+ /**
3
+ * Build the logcat invocation.
4
+ *
5
+ * Filtering is pushed into adb rather than done in node: a full dump is
6
+ * 13.8 MB, and node's exec buffer is 1 MiB by default.
7
+ */
8
+ export declare function buildLogcatArgs(opts: {
9
+ serial?: string;
10
+ sinceTs?: Date;
11
+ pid?: number;
12
+ minPriority?: string;
13
+ /** Read ONLY the crash buffer — used when app identity is unknown. */
14
+ crashOnly?: boolean;
15
+ }): string;
16
+ export declare function parseLogcatEpoch(stdout: string): RawLogLine[];
17
+ export declare function fetchAndroidLines(opts: {
18
+ serial?: string;
19
+ sinceTs?: Date;
20
+ pid?: number;
21
+ minPriority?: string;
22
+ crashOnly?: boolean;
23
+ signal?: AbortSignal;
24
+ }): Promise<RawLogLine[]>;
25
+ /** Resolve the app's live pid, or undefined when it is not running. */
26
+ export declare function resolveAndroidPid(packageName: string, serial?: string, signal?: AbortSignal): Promise<number | undefined>;
27
+ //# sourceMappingURL=logSourceAndroid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logSourceAndroid.d.ts","sourceRoot":"","sources":["../../src/core/logSourceAndroid.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAgC7D;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,MAAM,CAWT;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CAmB7D;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACxB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAQxB;AAED,uEAAuE;AACvE,wBAAsB,iBAAiB,CACnC,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAU7B"}
@@ -0,0 +1,89 @@
1
+ import { execAsync, withCancelableTimeout } from "./exec.js";
2
+ /** A full dump is 13.8 MB; node's exec default is 1 MiB. */
3
+ const MAX_BUFFER = 32 * 1024 * 1024;
4
+ const FETCH_TIMEOUT_MS = 5000;
5
+ const PRIORITY = {
6
+ V: "debug",
7
+ D: "debug",
8
+ I: "info",
9
+ W: "warn",
10
+ E: "error",
11
+ F: "fatal",
12
+ };
13
+ // " 1785352265.203 1210 13886 I NearbyMediums: Wifi changed"
14
+ const LINE_RE = /^\s*(\d+\.\d+)\s+(\d+)\s+(\d+)\s+([VDIWEF])\s+([^:]*?)\s*:\s?(.*)$/;
15
+ const SUBJECT_PATTERNS = [
16
+ /^Cmdline:\s*(\S+)/,
17
+ />>>\s*(\S+)\s*<<</,
18
+ /^Process:\s*([\w.]+)/,
19
+ ];
20
+ function declaredSubject(message) {
21
+ for (const re of SUBJECT_PATTERNS) {
22
+ const m = message.match(re);
23
+ if (m)
24
+ return m[1];
25
+ }
26
+ return undefined;
27
+ }
28
+ /**
29
+ * Build the logcat invocation.
30
+ *
31
+ * Filtering is pushed into adb rather than done in node: a full dump is
32
+ * 13.8 MB, and node's exec buffer is 1 MiB by default.
33
+ */
34
+ export function buildLogcatArgs(opts) {
35
+ const parts = ["adb"];
36
+ if (opts.serial)
37
+ parts.push("-s", opts.serial);
38
+ // crash first: it is small, and it is where tombstones land.
39
+ parts.push("logcat", "-d", "-b", opts.crashOnly ? "crash" : "crash,main", "-v", "epoch");
40
+ if (opts.sinceTs) {
41
+ parts.push("-T", `'${(opts.sinceTs.getTime() / 1000).toFixed(3)}'`);
42
+ }
43
+ if (opts.pid !== undefined)
44
+ parts.push(`--pid=${opts.pid}`);
45
+ if (opts.minPriority)
46
+ parts.push(`'*:${opts.minPriority}'`);
47
+ return parts.join(" ");
48
+ }
49
+ export function parseLogcatEpoch(stdout) {
50
+ const out = [];
51
+ for (const raw of stdout.split("\n")) {
52
+ if (!raw.trim() || raw.startsWith("---------"))
53
+ continue;
54
+ const m = raw.match(LINE_RE);
55
+ if (!m)
56
+ continue;
57
+ const [, epoch, pid, tid, priority, tag, message] = m;
58
+ out.push({
59
+ ts: new Date(Math.round(parseFloat(epoch) * 1000)),
60
+ level: PRIORITY[priority] ?? "log",
61
+ pid: Number(pid),
62
+ tid: Number(tid),
63
+ tag: tag.trim(),
64
+ message,
65
+ subject: declaredSubject(message),
66
+ raw,
67
+ });
68
+ }
69
+ return out;
70
+ }
71
+ export async function fetchAndroidLines(opts) {
72
+ const cmd = buildLogcatArgs(opts);
73
+ const { stdout } = await withCancelableTimeout((signal) => execAsync(cmd, { signal, maxBuffer: MAX_BUFFER }), FETCH_TIMEOUT_MS, `logcat (${opts.serial ?? "default device"})`);
74
+ return parseLogcatEpoch(stdout);
75
+ }
76
+ /** Resolve the app's live pid, or undefined when it is not running. */
77
+ export async function resolveAndroidPid(packageName, serial, signal) {
78
+ const target = serial ? `-s ${serial}` : "";
79
+ try {
80
+ const { stdout } = await execAsync(`adb ${target} shell pidof -s ${packageName}`, { signal });
81
+ const pid = Number(stdout.trim());
82
+ return Number.isFinite(pid) && pid > 0 ? pid : undefined;
83
+ }
84
+ catch {
85
+ // Not running — expected after a crash, which is the main case.
86
+ return undefined;
87
+ }
88
+ }
89
+ //# sourceMappingURL=logSourceAndroid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logSourceAndroid.js","sourceRoot":"","sources":["../../src/core/logSourceAndroid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { RawLogLine } from "./logEvents.js";
2
+ /**
3
+ * Build the `log show` invocation.
4
+ *
5
+ * The predicate does the filtering inside the OS: a 30-minute app-scoped read
6
+ * is 42 KB, where an unscoped one is orders of magnitude larger.
7
+ */
8
+ export declare function buildLogShowCommand(opts: {
9
+ udid: string;
10
+ processName?: string;
11
+ sinceTs?: Date;
12
+ /** "error" keeps error+fault; "fault" keeps fault only. */
13
+ minMessageType?: "error" | "fault";
14
+ }): string;
15
+ export declare function parseLogShowNdjson(stdout: string): RawLogLine[];
16
+ export declare function fetchIosLines(opts: {
17
+ udid: string;
18
+ processName?: string;
19
+ sinceTs?: Date;
20
+ minMessageType?: "error" | "fault";
21
+ signal?: AbortSignal;
22
+ }): Promise<RawLogLine[]>;
23
+ export declare function resolveIosProcessName(udid: string, bundleId: string, signal?: AbortSignal): Promise<string | undefined>;
24
+ /** Test-only. */
25
+ export declare function __resetIosProcessNameCache(): void;
26
+ //# sourceMappingURL=logSourceIos.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logSourceIos.d.ts","sourceRoot":"","sources":["../../src/core/logSourceIos.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,gBAAgB,CAAC;AA4B7D;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,2DAA2D;IAC3D,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CACtC,GAAG,MAAM,CAqBT;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CA+B/D;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACnC,MAAM,CAAC,EAAE,WAAW,CAAC;CACxB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAQxB;AAUD,wBAAsB,qBAAqB,CACvC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAe7B;AAED,iBAAiB;AACjB,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}