execbro 1.10.22 → 1.10.24

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 (87) hide show
  1. package/README.md +2 -1
  2. package/build/__tests__/unit/componentSource.test.d.ts +2 -0
  3. package/build/__tests__/unit/componentSource.test.d.ts.map +1 -0
  4. package/build/__tests__/unit/componentSource.test.js +67 -0
  5. package/build/__tests__/unit/componentSource.test.js.map +1 -0
  6. package/build/__tests__/unit/componentSourceResolve.test.d.ts +2 -0
  7. package/build/__tests__/unit/componentSourceResolve.test.d.ts.map +1 -0
  8. package/build/__tests__/unit/componentSourceResolve.test.js +91 -0
  9. package/build/__tests__/unit/componentSourceResolve.test.js.map +1 -0
  10. package/build/__tests__/unit/inspectorHarvest.test.d.ts +2 -0
  11. package/build/__tests__/unit/inspectorHarvest.test.d.ts.map +1 -0
  12. package/build/__tests__/unit/inspectorHarvest.test.js +61 -0
  13. package/build/__tests__/unit/inspectorHarvest.test.js.map +1 -0
  14. package/build/__tests__/unit/inspectorSource.test.d.ts +2 -0
  15. package/build/__tests__/unit/inspectorSource.test.d.ts.map +1 -0
  16. package/build/__tests__/unit/inspectorSource.test.js +74 -0
  17. package/build/__tests__/unit/inspectorSource.test.js.map +1 -0
  18. package/build/__tests__/unit/selectionBuffer.test.d.ts +2 -0
  19. package/build/__tests__/unit/selectionBuffer.test.d.ts.map +1 -0
  20. package/build/__tests__/unit/selectionBuffer.test.js +86 -0
  21. package/build/__tests__/unit/selectionBuffer.test.js.map +1 -0
  22. package/build/__tests__/unit/selectionPoller.test.d.ts +2 -0
  23. package/build/__tests__/unit/selectionPoller.test.d.ts.map +1 -0
  24. package/build/__tests__/unit/selectionPoller.test.js +109 -0
  25. package/build/__tests__/unit/selectionPoller.test.js.map +1 -0
  26. package/build/__tests__/unit/symbolicate.test.d.ts +2 -0
  27. package/build/__tests__/unit/symbolicate.test.d.ts.map +1 -0
  28. package/build/__tests__/unit/symbolicate.test.js +154 -0
  29. package/build/__tests__/unit/symbolicate.test.js.map +1 -0
  30. package/build/__tests__/unit/toolsJson.test.d.ts +2 -0
  31. package/build/__tests__/unit/toolsJson.test.d.ts.map +1 -0
  32. package/build/__tests__/unit/toolsJson.test.js +24 -0
  33. package/build/__tests__/unit/toolsJson.test.js.map +1 -0
  34. package/build/core/componentSource.d.ts +62 -0
  35. package/build/core/componentSource.d.ts.map +1 -0
  36. package/build/core/componentSource.js +268 -0
  37. package/build/core/componentSource.js.map +1 -0
  38. package/build/core/connection.d.ts.map +1 -1
  39. package/build/core/connection.js +4 -0
  40. package/build/core/connection.js.map +1 -1
  41. package/build/core/debugGlobals.d.ts.map +1 -1
  42. package/build/core/debugGlobals.js +3 -1
  43. package/build/core/debugGlobals.js.map +1 -1
  44. package/build/core/guides.js +1 -1
  45. package/build/core/index.d.ts +4 -1
  46. package/build/core/index.d.ts.map +1 -1
  47. package/build/core/index.js +4 -1
  48. package/build/core/index.js.map +1 -1
  49. package/build/core/inspector.d.ts +24 -0
  50. package/build/core/inspector.d.ts.map +1 -1
  51. package/build/core/inspector.js +58 -0
  52. package/build/core/inspector.js.map +1 -1
  53. package/build/core/sdkBridge.d.ts +8 -8
  54. package/build/core/sdkBridge.d.ts.map +1 -1
  55. package/build/core/sdkBridge.js +20 -20
  56. package/build/core/sdkBridge.js.map +1 -1
  57. package/build/core/selectionBuffer.d.ts +42 -0
  58. package/build/core/selectionBuffer.d.ts.map +1 -0
  59. package/build/core/selectionBuffer.js +51 -0
  60. package/build/core/selectionBuffer.js.map +1 -0
  61. package/build/core/selectionPoller.d.ts +13 -0
  62. package/build/core/selectionPoller.d.ts.map +1 -0
  63. package/build/core/selectionPoller.js +102 -0
  64. package/build/core/selectionPoller.js.map +1 -0
  65. package/build/core/symbolicate.d.ts +18 -0
  66. package/build/core/symbolicate.d.ts.map +1 -0
  67. package/build/core/symbolicate.js +119 -0
  68. package/build/core/symbolicate.js.map +1 -0
  69. package/build/tools/componentTools.d.ts.map +1 -1
  70. package/build/tools/componentTools.js +78 -9
  71. package/build/tools/componentTools.js.map +1 -1
  72. package/build/tools/connectionTools.d.ts.map +1 -1
  73. package/build/tools/connectionTools.js +3 -1
  74. package/build/tools/connectionTools.js.map +1 -1
  75. package/build/tools/interactionTools.d.ts.map +1 -1
  76. package/build/tools/interactionTools.js +1 -0
  77. package/build/tools/interactionTools.js.map +1 -1
  78. package/build/tools/logTools.d.ts.map +1 -1
  79. package/build/tools/logTools.js +26 -17
  80. package/build/tools/logTools.js.map +1 -1
  81. package/build/tools/networkTools.d.ts.map +1 -1
  82. package/build/tools/networkTools.js +15 -20
  83. package/build/tools/networkTools.js.map +1 -1
  84. package/build/tools/screenshotTools.d.ts.map +1 -1
  85. package/build/tools/screenshotTools.js +3 -0
  86. package/build/tools/screenshotTools.js.map +1 -1
  87. package/package.json +65 -64
@@ -0,0 +1,154 @@
1
+ import { describe, it, expect, beforeEach, jest } from "@jest/globals";
2
+ import { parseStackString, symbolicateFrames, firstUserFrame, clearSymbolicateCache, } from "../../core/symbolicate.js";
3
+ const BUNDLE = "http://192.168.0.102:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true&transform.engine=hermes";
4
+ const REAL_STACK = [
5
+ "Error: react-stack-top-frame",
6
+ ` at anonymous (${BUNDLE}:19648:90)`,
7
+ ` at HomeScreen (${BUNDLE}:342013:64)`,
8
+ ` at react_stack_bottom_frame (${BUNDLE}:31478:29)`,
9
+ ].join("\n");
10
+ describe("parseStackString", () => {
11
+ it("parses named frames with URL, line and column", () => {
12
+ const frames = parseStackString(REAL_STACK);
13
+ expect(frames[0]).toEqual({
14
+ file: BUNDLE,
15
+ lineNumber: 19648,
16
+ column: 90,
17
+ methodName: "anonymous",
18
+ });
19
+ expect(frames[1].methodName).toBe("HomeScreen");
20
+ expect(frames[1].lineNumber).toBe(342013);
21
+ });
22
+ it("does not split on the colon inside http://", () => {
23
+ const frames = parseStackString(REAL_STACK);
24
+ expect(frames[0].file).toBe(BUNDLE);
25
+ expect(frames[0].file.startsWith("http://")).toBe(true);
26
+ });
27
+ it("skips the leading Error: line", () => {
28
+ const frames = parseStackString(REAL_STACK);
29
+ expect(frames.every((f) => f.methodName !== null)).toBe(true);
30
+ expect(frames.length).toBe(3);
31
+ });
32
+ it("parses anonymous frames with no method name", () => {
33
+ const frames = parseStackString(` at ${BUNDLE}:100:5`);
34
+ expect(frames[0]).toEqual({
35
+ file: BUNDLE,
36
+ lineNumber: 100,
37
+ column: 5,
38
+ methodName: null,
39
+ });
40
+ });
41
+ it("honours the limit argument", () => {
42
+ expect(parseStackString(REAL_STACK, 2).length).toBe(2);
43
+ });
44
+ it("returns an empty array for junk input", () => {
45
+ expect(parseStackString("")).toEqual([]);
46
+ expect(parseStackString("not a stack at all")).toEqual([]);
47
+ });
48
+ });
49
+ describe("firstUserFrame", () => {
50
+ it("returns the first frame not marked collapse", () => {
51
+ const frame = firstUserFrame([
52
+ { file: "/x/node_modules/react/a.js", lineNumber: 1, column: 1, methodName: "jsx", collapse: true },
53
+ { file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
54
+ ]);
55
+ expect(frame.file).toBe("/x/src/Home.tsx");
56
+ expect(frame.lineNumber).toBe(105);
57
+ });
58
+ it("returns null when every frame is collapsed", () => {
59
+ const frame = firstUserFrame([
60
+ { file: "/x/node_modules/react/a.js", lineNumber: 1, column: 1, methodName: "jsx", collapse: true },
61
+ ]);
62
+ expect(frame).toBeNull();
63
+ });
64
+ it("returns null for an empty list", () => {
65
+ expect(firstUserFrame([])).toBeNull();
66
+ });
67
+ });
68
+ describe("symbolicateFrames", () => {
69
+ beforeEach(() => {
70
+ clearSymbolicateCache();
71
+ globalThis.fetch = jest.fn();
72
+ });
73
+ it("POSTs to localhost on the port taken from the frame URL", async () => {
74
+ globalThis.fetch.mockResolvedValue({
75
+ ok: true,
76
+ json: async () => ({
77
+ stack: [
78
+ { file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
79
+ ],
80
+ }),
81
+ });
82
+ await symbolicateFrames([
83
+ { file: BUNDLE, lineNumber: 342013, column: 64, methodName: "HomeScreen" },
84
+ ]);
85
+ const [url, init] = globalThis.fetch.mock.calls[0];
86
+ expect(url).toBe("http://127.0.0.1:8081/symbolicate");
87
+ expect(init.method).toBe("POST");
88
+ // The file field must be sent verbatim — Metro matches it against its bundle registry.
89
+ expect(JSON.parse(init.body).stack[0].file).toBe(BUNDLE);
90
+ });
91
+ it("returns symbolicated frames with the collapse flag", async () => {
92
+ globalThis.fetch.mockResolvedValue({
93
+ ok: true,
94
+ json: async () => ({
95
+ stack: [
96
+ { file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
97
+ ],
98
+ }),
99
+ });
100
+ const out = await symbolicateFrames([
101
+ { file: BUNDLE, lineNumber: 342013, column: 64, methodName: "HomeScreen" },
102
+ ]);
103
+ expect(out).toEqual([
104
+ { file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
105
+ ]);
106
+ });
107
+ it("defaults collapse to false when Metro omits it", async () => {
108
+ globalThis.fetch.mockResolvedValue({
109
+ ok: true,
110
+ json: async () => ({ stack: [{ file: "/x/a.tsx", lineNumber: 1, column: 2, methodName: "A" }] }),
111
+ });
112
+ const out = await symbolicateFrames([{ file: BUNDLE, lineNumber: 1, column: 2, methodName: "A" }]);
113
+ expect(out[0].collapse).toBe(false);
114
+ });
115
+ it("serves a repeated frame from cache without a second fetch", async () => {
116
+ globalThis.fetch.mockResolvedValue({
117
+ ok: true,
118
+ json: async () => ({
119
+ stack: [{ file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false }],
120
+ }),
121
+ });
122
+ const frame = { file: BUNDLE, lineNumber: 342013, column: 64, methodName: "HomeScreen" };
123
+ await symbolicateFrames([frame]);
124
+ const second = await symbolicateFrames([frame]);
125
+ expect(globalThis.fetch.mock.calls.length).toBe(1);
126
+ expect(second[0].file).toBe("/x/src/Home.tsx");
127
+ });
128
+ it("returns null when Metro is unreachable", async () => {
129
+ globalThis.fetch.mockRejectedValue(new Error("ECONNREFUSED"));
130
+ const out = await symbolicateFrames([{ file: BUNDLE, lineNumber: 1, column: 1, methodName: "A" }]);
131
+ expect(out).toBeNull();
132
+ });
133
+ it("returns null on a non-ok response", async () => {
134
+ globalThis.fetch.mockResolvedValue({ ok: false, status: 500, json: async () => ({}) });
135
+ const out = await symbolicateFrames([{ file: BUNDLE, lineNumber: 1, column: 1, methodName: "A" }]);
136
+ expect(out).toBeNull();
137
+ });
138
+ it("returns an empty array without fetching when given no frames", async () => {
139
+ const out = await symbolicateFrames([]);
140
+ expect(out).toEqual([]);
141
+ expect(globalThis.fetch.mock.calls.length).toBe(0);
142
+ });
143
+ it("falls back to the frame origin when the URL has no port", async () => {
144
+ globalThis.fetch.mockResolvedValue({
145
+ ok: true,
146
+ json: async () => ({ stack: [{ file: "/a.tsx", lineNumber: 1, column: 1, methodName: "A", collapse: false }] }),
147
+ });
148
+ await symbolicateFrames([
149
+ { file: "http://example.com/bundle.js", lineNumber: 1, column: 1, methodName: "A" },
150
+ ]);
151
+ expect(globalThis.fetch.mock.calls[0][0]).toBe("http://example.com/symbolicate");
152
+ });
153
+ });
154
+ //# sourceMappingURL=symbolicate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbolicate.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/symbolicate.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=toolsJson.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolsJson.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/unit/toolsJson.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ // Fails when tools.json drifts from the live registry — i.e. someone added or
2
+ // removed a tool without re-running `npm run tools:json`. The website vendors
3
+ // this file to validate its /readme/tools reference, so stale output silently
4
+ // ships a wrong tool list to users.
5
+ // IMPORTANT: set test mode BEFORE importing src/index.ts so main() is skipped
6
+ // (no license check, no transport, no HTTP listener, no CDP sockets).
7
+ process.env.RN_AI_DEVTOOLS_TEST_MODE = "1";
8
+ import { describe, it, expect } from "@jest/globals";
9
+ import { readFileSync } from "node:fs";
10
+ import { join } from "node:path";
11
+ import { toolRegistry } from "../../index.js";
12
+ describe("tools.json", () => {
13
+ const payload = JSON.parse(readFileSync(join(process.cwd(), "tools.json"), "utf8"));
14
+ it("lists exactly the registered tools", () => {
15
+ expect(payload.tools).toEqual([...toolRegistry.keys()].sort());
16
+ });
17
+ it("records a count matching its own list", () => {
18
+ expect(payload.count).toBe(payload.tools.length);
19
+ });
20
+ it("is not empty", () => {
21
+ expect(payload.tools.length).toBeGreaterThan(0);
22
+ });
23
+ });
24
+ //# sourceMappingURL=toolsJson.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolsJson.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/toolsJson.test.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAC9E,oCAAoC;AAEpC,8EAA8E;AAC9E,sEAAsE;AACtE,OAAO,CAAC,GAAG,CAAC,wBAAwB,GAAG,GAAG,CAAC;AAE3C,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IACxB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAGjF,CAAC;IAEF,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;QACpB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,62 @@
1
+ import type { ComponentStack, SelectionFrame } from "./selectionBuffer.js";
2
+ export interface ProbeResult {
3
+ active: boolean;
4
+ selected: boolean;
5
+ changed: boolean;
6
+ element?: string;
7
+ path?: string;
8
+ hierarchy?: string[];
9
+ frame?: SelectionFrame | null;
10
+ style?: Record<string, unknown> | null;
11
+ }
12
+ export interface HarvestResult {
13
+ stacks: ComponentStack[];
14
+ error?: string;
15
+ }
16
+ /**
17
+ * Cheap per-tick probe. Deliberately does NO measurement — it runs every
18
+ * 500-2000ms and must stay inexpensive. Reports whether RN's inspector is
19
+ * mounted and whether its selection changed since the previous tick.
20
+ */
21
+ export declare function buildSelectionProbeExpression(): string;
22
+ /**
23
+ * Hit-tests at (x, y) and harvests raw _debugStack strings up the return chain.
24
+ * Measures host fibers, so this runs only when the probe reports a change -
25
+ * once per tap, never per tick.
26
+ *
27
+ * Prefers _debugSource when present (React < 19, already source coordinates);
28
+ * otherwise emits the raw _debugStack string for host-side symbolication.
29
+ *
30
+ * The cap is deliberately generous. Real trees bury the nearest user component
31
+ * deep behind library wrappers - measured on a production app, a tapped SearchBar
32
+ * sat 12 ancestors above the hit fiber (SVG icon, Pressable and View wrappers in
33
+ * between) and HomeScreen sat at 22. Collapsed library frames are dropped
34
+ * host-side, so a larger walk improves recall without bloating the output; the
35
+ * extra frames cost nothing beyond one batched, cached symbolicate request.
36
+ */
37
+ export declare function buildDebugStackHarvestExpression(x: number, y: number, maxAncestors?: number): string;
38
+ export interface RawComponentStack {
39
+ component: string;
40
+ stack: string;
41
+ /** Present only on React < 19, where _debugSource still exists. */
42
+ file?: string;
43
+ lineNumber?: number;
44
+ column?: number;
45
+ }
46
+ export interface SourceLocation {
47
+ file: string;
48
+ line: number;
49
+ column: number;
50
+ }
51
+ export interface ResolvedAncestor {
52
+ component: string;
53
+ file: string;
54
+ line: number;
55
+ }
56
+ export interface ResolvedSource {
57
+ source: SourceLocation | null;
58
+ ancestors: ResolvedAncestor[];
59
+ sourceUnavailable?: string;
60
+ }
61
+ export declare function resolveStacksToSource(stacks: RawComponentStack[]): Promise<ResolvedSource>;
62
+ //# sourceMappingURL=componentSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentSource.d.ts","sourceRoot":"","sources":["../../src/core/componentSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3E,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAkBD;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,CAmEtD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gCAAgC,CAC5C,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,YAAY,GAAE,MAAW,GAC1B,MAAM,CAwGR;AAED,MAAM,WAAW,iBAAiB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AASD,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CA2DhG"}
@@ -0,0 +1,268 @@
1
+ import { parseStackString, symbolicateFrames } from "./symbolicate.js";
2
+ /** Shared fiber-root lookup. Hermes-safe: var + function only. */
3
+ const ROOTS_SNIPPET = `
4
+ var hook = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
5
+ var roots = [];
6
+ if (hook && hook.getFiberRoots) {
7
+ if (hook.renderers) {
8
+ for (var entry of hook.renderers) {
9
+ try { roots = roots.concat(Array.from(hook.getFiberRoots(entry[0]) || [])); } catch (e) {}
10
+ }
11
+ }
12
+ if (roots.length === 0) {
13
+ try { roots = Array.from(hook.getFiberRoots(1) || []); } catch (e) {}
14
+ }
15
+ }
16
+ `;
17
+ /**
18
+ * Cheap per-tick probe. Deliberately does NO measurement — it runs every
19
+ * 500-2000ms and must stay inexpensive. Reports whether RN's inspector is
20
+ * mounted and whether its selection changed since the previous tick.
21
+ */
22
+ export function buildSelectionProbeExpression() {
23
+ return `
24
+ (function() {
25
+ ${ROOTS_SNIPPET}
26
+ if (roots.length === 0) return { active: false, selected: false, changed: false };
27
+
28
+ var panels = [];
29
+ function walk(fiber, depth) {
30
+ if (!fiber || depth > 3000) return;
31
+ if (fiber.type && typeof fiber.type !== 'string' &&
32
+ (fiber.type.displayName || fiber.type.name) === 'InspectorPanel') {
33
+ panels.push(fiber);
34
+ }
35
+ var child = fiber.child;
36
+ while (child) { walk(child, depth + 1); child = child.sibling; }
37
+ }
38
+ for (var r = 0; r < roots.length; r++) { walk(roots[r].current, 0); }
39
+
40
+ if (panels.length === 0) {
41
+ globalThis.__execbro_lastInspected = undefined;
42
+ return { active: false, selected: false, changed: false };
43
+ }
44
+
45
+ var panel = null;
46
+ for (var p = 0; p < panels.length; p++) {
47
+ var h = panels[p].memoizedProps && panels[p].memoizedProps.hierarchy;
48
+ if (h && h.length > 0) { panel = panels[p]; break; }
49
+ }
50
+ if (!panel) return { active: true, selected: false, changed: false };
51
+
52
+ var props = panel.memoizedProps;
53
+ var inspected = props.inspected;
54
+
55
+ // RN allocates a fresh object per tap, so identity - not value -
56
+ // distinguishes two consecutive taps on the same element.
57
+ if (inspected === globalThis.__execbro_lastInspected) {
58
+ return { active: true, selected: true, changed: false };
59
+ }
60
+ globalThis.__execbro_lastInspected = inspected;
61
+
62
+ var names = [];
63
+ for (var i = 0; i < props.hierarchy.length; i++) {
64
+ names.push(props.hierarchy[i].name);
65
+ }
66
+
67
+ var style = {};
68
+ if (inspected && inspected.style) {
69
+ var list = Array.isArray(inspected.style) ? inspected.style : [inspected.style];
70
+ for (var s = 0; s < list.length; s++) {
71
+ if (list[s] && typeof list[s] === 'object') {
72
+ for (var k in list[s]) { style[k] = list[s][k]; }
73
+ }
74
+ }
75
+ }
76
+
77
+ return {
78
+ active: true,
79
+ selected: true,
80
+ changed: true,
81
+ element: names.length > 0 ? names[names.length - 1] : 'Unknown',
82
+ path: names.join(' > '),
83
+ hierarchy: names,
84
+ frame: inspected && inspected.frame ? inspected.frame : null,
85
+ style: Object.keys(style).length > 0 ? style : null
86
+ };
87
+ })()
88
+ `;
89
+ }
90
+ /**
91
+ * Hit-tests at (x, y) and harvests raw _debugStack strings up the return chain.
92
+ * Measures host fibers, so this runs only when the probe reports a change -
93
+ * once per tap, never per tick.
94
+ *
95
+ * Prefers _debugSource when present (React < 19, already source coordinates);
96
+ * otherwise emits the raw _debugStack string for host-side symbolication.
97
+ *
98
+ * The cap is deliberately generous. Real trees bury the nearest user component
99
+ * deep behind library wrappers - measured on a production app, a tapped SearchBar
100
+ * sat 12 ancestors above the hit fiber (SVG icon, Pressable and View wrappers in
101
+ * between) and HomeScreen sat at 22. Collapsed library frames are dropped
102
+ * host-side, so a larger walk improves recall without bloating the output; the
103
+ * extra frames cost nothing beyond one batched, cached symbolicate request.
104
+ */
105
+ export function buildDebugStackHarvestExpression(x, y, maxAncestors = 30) {
106
+ return `
107
+ new Promise(function(resolve) {
108
+ var maxAncestors = ${maxAncestors};
109
+ ${ROOTS_SNIPPET}
110
+ if (roots.length === 0) return resolve({ stacks: [], error: 'no-fiber-roots' });
111
+
112
+ function getMeasurable(fiber) {
113
+ var sn = fiber.stateNode;
114
+ if (!sn) return null;
115
+ if (typeof sn.measureInWindow === 'function') return sn;
116
+ if (sn.canonical && sn.canonical.publicInstance &&
117
+ typeof sn.canonical.publicInstance.measureInWindow === 'function') {
118
+ return sn.canonical.publicInstance;
119
+ }
120
+ if (sn.node && globalThis.nativeFabricUIManager &&
121
+ typeof globalThis.nativeFabricUIManager.measureInWindow === 'function') {
122
+ var node = sn.node;
123
+ return {
124
+ measureInWindow: function(cb) {
125
+ try { globalThis.nativeFabricUIManager.measureInWindow(node, cb); } catch (e) {}
126
+ }
127
+ };
128
+ }
129
+ return null;
130
+ }
131
+
132
+ var hostFibers = [];
133
+ function walkFibers(fiber, depth) {
134
+ var cur = fiber;
135
+ while (cur) {
136
+ if (hostFibers.length >= 500) return;
137
+ if (typeof cur.type === 'string' && getMeasurable(cur)) hostFibers.push(cur);
138
+ if (cur.child && depth < 250) walkFibers(cur.child, depth + 1);
139
+ cur = cur.sibling;
140
+ }
141
+ }
142
+ for (var r = 0; r < roots.length; r++) { walkFibers(roots[r].current, 0); }
143
+ if (hostFibers.length === 0) return resolve({ stacks: [], error: 'no-host-fibers' });
144
+
145
+ var measurements = new Array(hostFibers.length).fill(null);
146
+ var pending = hostFibers.length;
147
+ var settled = false;
148
+
149
+ function collect() {
150
+ if (settled) return;
151
+ settled = true;
152
+
153
+ var targetX = ${x};
154
+ var targetY = ${y};
155
+ var hits = [];
156
+ for (var i = 0; i < measurements.length; i++) {
157
+ var m = measurements[i];
158
+ if (m && m.width > 0 && m.height > 0 &&
159
+ targetX >= m.x && targetX <= m.x + m.width &&
160
+ targetY >= m.y && targetY <= m.y + m.height) {
161
+ hits.push({ fiber: hostFibers[i], area: m.width * m.height });
162
+ }
163
+ }
164
+ if (hits.length === 0) return resolve({ stacks: [], error: 'no-hit' });
165
+ hits.sort(function(a, b) { return a.area - b.area; });
166
+
167
+ var stacks = [];
168
+ var node = hits[0].fiber;
169
+ while (node && stacks.length < maxAncestors) {
170
+ var name = null;
171
+ if (node.type) {
172
+ name = typeof node.type === 'string'
173
+ ? node.type
174
+ : (node.type.displayName || node.type.name);
175
+ }
176
+ if (name) {
177
+ var src = node._debugSource;
178
+ if (src && src.fileName) {
179
+ stacks.push({
180
+ component: name,
181
+ stack: '',
182
+ file: src.fileName,
183
+ lineNumber: src.lineNumber,
184
+ column: src.columnNumber
185
+ });
186
+ } else if (node._debugStack && node._debugStack.stack) {
187
+ stacks.push({ component: name, stack: String(node._debugStack.stack) });
188
+ }
189
+ }
190
+ node = node.return;
191
+ }
192
+ resolve({ stacks: stacks });
193
+ }
194
+
195
+ hostFibers.forEach(function(fiber, i) {
196
+ try {
197
+ getMeasurable(fiber).measureInWindow(function(fx, fy, fw, fh) {
198
+ measurements[i] = { x: fx, y: fy, width: fw, height: fh };
199
+ if (--pending === 0) collect();
200
+ });
201
+ } catch (e) {
202
+ if (--pending === 0) collect();
203
+ }
204
+ });
205
+
206
+ setTimeout(collect, 300);
207
+ })
208
+ `;
209
+ }
210
+ /**
211
+ * Frame index 1 of a parsed _debugStack is the component's render site - the
212
+ * JSX call site in its parent, which is the line a developer edits. Index 0 is
213
+ * the Error construction inside React's jsx runtime.
214
+ */
215
+ const RENDER_SITE_FRAME_INDEX = 1;
216
+ export async function resolveStacksToSource(stacks) {
217
+ if (stacks.length === 0) {
218
+ return { source: null, ancestors: [], sourceUnavailable: "no-debug-stack" };
219
+ }
220
+ // React < 19 path: _debugSource already carries source coordinates.
221
+ const direct = [];
222
+ const needsSymbolication = [];
223
+ for (const entry of stacks) {
224
+ if (entry.file && entry.lineNumber !== undefined) {
225
+ direct.push({ component: entry.component, file: entry.file, line: entry.lineNumber });
226
+ continue;
227
+ }
228
+ const frames = parseStackString(entry.stack, RENDER_SITE_FRAME_INDEX + 1);
229
+ const renderSite = frames[RENDER_SITE_FRAME_INDEX];
230
+ if (renderSite) {
231
+ needsSymbolication.push({ component: entry.component, frame: renderSite });
232
+ }
233
+ }
234
+ if (needsSymbolication.length === 0) {
235
+ if (direct.length === 0) {
236
+ return { source: null, ancestors: [], sourceUnavailable: "no-debug-stack" };
237
+ }
238
+ const first = direct[0];
239
+ const firstEntry = stacks.find((s) => s.component === first.component);
240
+ return {
241
+ source: { file: first.file, line: first.line, column: firstEntry?.column ?? 0 },
242
+ ancestors: direct,
243
+ };
244
+ }
245
+ const resolved = await symbolicateFrames(needsSymbolication.map((n) => n.frame));
246
+ if (resolved === null) {
247
+ return { source: null, ancestors: [], sourceUnavailable: "symbolicate-unreachable" };
248
+ }
249
+ const ancestors = [...direct];
250
+ let best = null;
251
+ resolved.forEach((frame, i) => {
252
+ const component = needsSymbolication[i]?.component;
253
+ if (!component || frame.collapse)
254
+ return;
255
+ ancestors.push({ component, file: frame.file, line: frame.lineNumber });
256
+ if (!best) {
257
+ best = { file: frame.file, line: frame.lineNumber, column: frame.column };
258
+ }
259
+ });
260
+ if (!best && direct.length > 0) {
261
+ best = { file: direct[0].file, line: direct[0].line, column: 0 };
262
+ }
263
+ if (!best) {
264
+ return { source: null, ancestors: [], sourceUnavailable: "library-only" };
265
+ }
266
+ return { source: best, ancestors };
267
+ }
268
+ //# sourceMappingURL=componentSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentSource.js","sourceRoot":"","sources":["../../src/core/componentSource.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/core/connection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/core/connection.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ import { probeCdpAlive } from "./probe.js";
9
9
  import { UserInputError } from "./errors.js";
10
10
  import { scheduleAppDetection } from "./appDetection.js";
11
11
  import { markConnectionEstablished } from "./jsExecute.js";
12
+ import { startSelectionPoller } from "./selectionPoller.js";
12
13
  import { DEFAULT_RECONNECTION_CONFIG, MIN_STABLE_CONNECTION_MS, initConnectionState, updateConnectionState, getConnectionState, recordConnectionGap, closeConnectionGap, saveConnectionMetadata, clearConnectionMetadata, getConnectionMetadata, saveReconnectionTimer, cancelReconnectionTimer, calculateBackoffDelay, initContextHealth, markContextHealthy, markContextStale, getContextHealth, updateContextHealth, formatDuration, recordConnectionEvent, } from "./connectionState.js";
13
14
  // Connection locks to prevent concurrent connection attempts to the same device
14
15
  const connectionLocks = new Set();
@@ -954,6 +955,9 @@ export async function connectToDevice(device, port, options = {}) {
954
955
  connectionLocks.delete(appKey);
955
956
  connectedApps.set(appKey, { ws, deviceInfo: device, port, platform: "android" });
956
957
  markConnectionEstablished();
958
+ // Watch RN's Element Inspector for selections made outside an agent
959
+ // request. Idempotent, and a no-op when EXECBRO_DISABLE_SELECTION_POLL=1.
960
+ startSelectionPoller(device.deviceName);
957
961
  // Initialize or update connection state
958
962
  // Note: We do NOT reset reconnectionAttempts here - that happens
959
963
  // only when connection has been stable for MIN_STABLE_CONNECTION_MS