react-native-ai-debugger 1.10.16 → 1.10.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flowpoints.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/flowpoints.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=flowpointsQuery.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flowpointsQuery.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/unit/flowpointsQuery.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,91 @@
1
+ import { describe, expect, it } from "@jest/globals";
2
+ import { formatMeta, matchesPoint, resolveLastRuns, filterFlowpoints, formatFlowpoints, } from "../../pro/flowpoints.js";
3
+ function e(seq, overrides = {}) {
4
+ return { seq, t: 1000 + seq, name: "add-to-cart", step: `s${seq}`, run: "r1", level: "info", ...overrides };
5
+ }
6
+ describe("formatMeta", () => {
7
+ it("passes strings through and stringifies objects", () => {
8
+ expect(formatMeta("start")).toBe("start");
9
+ expect(formatMeta({ removed: 3 })).toBe('{"removed":3}');
10
+ expect(formatMeta(undefined)).toBe("");
11
+ });
12
+ });
13
+ describe("matchesPoint", () => {
14
+ it("matches on step equality, level, and case-insensitive metaIncludes", () => {
15
+ const entry = e(1, { step: "failed", level: "error", meta: { reason: "Timeout" } });
16
+ expect(matchesPoint(entry, { step: "failed" })).toBe(true);
17
+ expect(matchesPoint(entry, { step: "other" })).toBe(false);
18
+ expect(matchesPoint(entry, { level: "error" })).toBe(true);
19
+ expect(matchesPoint(entry, { metaIncludes: "timeout" })).toBe(true);
20
+ expect(matchesPoint(entry, { step: "failed", level: "info" })).toBe(false);
21
+ });
22
+ });
23
+ describe("resolveLastRuns", () => {
24
+ it("returns the run of the chronologically last entry per flow", () => {
25
+ const entries = [
26
+ e(1, { run: "aaaa" }),
27
+ e(2, { run: "aaaa" }),
28
+ e(3, { run: "bbbb" }),
29
+ e(4, { name: "other", run: "cccc" }),
30
+ ];
31
+ const last = resolveLastRuns(entries);
32
+ expect(last.get("add-to-cart")).toBe("bbbb");
33
+ expect(last.get("other")).toBe("cccc");
34
+ });
35
+ });
36
+ describe("filterFlowpoints", () => {
37
+ const entries = [
38
+ e(1, { run: "aaaa", step: "start" }),
39
+ e(2, { run: "aaaa", step: "failed", level: "error", meta: { reason: "timeout" } }),
40
+ e(3, { run: "bbbb", step: "start" }),
41
+ e(4, { run: "bbbb", step: "done" }),
42
+ e(5, { name: "checkout", run: "cccc", step: "start" }),
43
+ ];
44
+ it("filters by name, step, and level", () => {
45
+ expect(filterFlowpoints(entries, { name: "checkout" })).toHaveLength(1);
46
+ expect(filterFlowpoints(entries, { step: "start" })).toHaveLength(3);
47
+ expect(filterFlowpoints(entries, { level: "error" })).toHaveLength(1);
48
+ });
49
+ it("filters by metaIncludes and since", () => {
50
+ expect(filterFlowpoints(entries, { metaIncludes: "TIMEOUT" })).toHaveLength(1);
51
+ expect(filterFlowpoints(entries, { since: 1003 })).toHaveLength(2);
52
+ });
53
+ it("resolves run: 'last' per flow and explicit run ids", () => {
54
+ const last = filterFlowpoints(entries, { run: "last" });
55
+ expect(last.map((x) => x.seq)).toEqual([3, 4, 5]);
56
+ expect(filterFlowpoints(entries, { run: "aaaa" })).toHaveLength(2);
57
+ });
58
+ it("applies limit keeping the newest entries", () => {
59
+ expect(filterFlowpoints(entries, { limit: 2 }).map((x) => x.seq)).toEqual([4, 5]);
60
+ });
61
+ });
62
+ describe("formatFlowpoints", () => {
63
+ it("formats a single-run flow with deltas, span, level prefix, and meta", () => {
64
+ const out = formatFlowpoints([
65
+ e(1, { step: "start", t: 1000 }),
66
+ e(2, { step: "cleared", t: 1006, meta: { removed: 3 } }),
67
+ e(3, { step: "failed", t: 1312, level: "error", meta: { reason: "timeout" } }),
68
+ ]);
69
+ expect(out).toContain('Flow "add-to-cart" run r1 — 3 points (312ms span):');
70
+ expect(out).toContain("+0ms");
71
+ expect(out).toContain("+6ms");
72
+ expect(out).toContain('cleared {"removed":3}');
73
+ expect(out).toContain("[error] failed");
74
+ });
75
+ it("groups multiple runs and labels the latest", () => {
76
+ const out = formatFlowpoints([e(1, { run: "aaaa", t: 1000 }), e(2, { run: "bbbb", t: 2000 })]);
77
+ expect(out).toContain('Flow "add-to-cart" — 2 runs');
78
+ expect(out).toContain("run aaaa — 1 points");
79
+ expect(out).toContain("run bbbb (latest) — 1 points");
80
+ });
81
+ it("labels (latest) by last activity, not first appearance, under interleaved runs", () => {
82
+ const out = formatFlowpoints([
83
+ e(1, { run: "aaaa", t: 1000 }),
84
+ e(2, { run: "bbbb", t: 1500 }),
85
+ e(3, { run: "aaaa", t: 2000 }),
86
+ ]);
87
+ expect(out).toContain("run aaaa (latest)");
88
+ expect(out).not.toContain("bbbb (latest)");
89
+ });
90
+ });
91
+ //# sourceMappingURL=flowpointsQuery.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flowpointsQuery.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/flowpointsQuery.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=verifyFlow.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifyFlow.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/unit/verifyFlow.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,45 @@
1
+ import { describe, expect, it } from "@jest/globals";
2
+ import { verifyFlow } from "../../pro/flowpoints.js";
3
+ function e(seq, step, overrides = {}) {
4
+ return { seq, t: 1000 + seq * 10, name: "add-to-cart", step, run: "r1", level: "info", ...overrides };
5
+ }
6
+ const happy = [e(1, "start"), e(2, "cleared"), e(3, "item-added"), e(4, "done")];
7
+ describe("verifyFlow", () => {
8
+ it("passes when expected steps appear in order (subsequence: extras allowed)", () => {
9
+ const result = verifyFlow("add-to-cart", "r1", happy, ["start", "item-added", "done"], false);
10
+ expect(result.pass).toBe(true);
11
+ expect(result.text).toContain('PASS — flow "add-to-cart" run r1:');
12
+ expect(result.text).toContain("✓ start (+0ms)");
13
+ expect(result.text).toContain("✓ done (+30ms)");
14
+ });
15
+ it("fails and diffs a missing step", () => {
16
+ const result = verifyFlow("add-to-cart", "r1", [e(1, "start"), e(2, "cleared")], ["start", "item-added"], false);
17
+ expect(result.pass).toBe(false);
18
+ expect(result.text).toContain("✗ item-added — not seen");
19
+ });
20
+ it("fails on out-of-order steps", () => {
21
+ const result = verifyFlow("add-to-cart", "r1", happy, ["done", "start"], false);
22
+ expect(result.pass).toBe(false);
23
+ });
24
+ it("fails on an unexpected error point, with a ! line", () => {
25
+ const entries = [e(1, "start"), e(2, "failed", { level: "error", meta: { reason: "timeout" } })];
26
+ const result = verifyFlow("add-to-cart", "r1", entries, ["start"], false);
27
+ expect(result.pass).toBe(false);
28
+ expect(result.text).toContain('! failed [error] (+10ms) {"reason":"timeout"} — unexpected error point');
29
+ });
30
+ it("allowErrors tolerates unexpected error points", () => {
31
+ const entries = [e(1, "start"), e(2, "failed", { level: "error" })];
32
+ expect(verifyFlow("add-to-cart", "r1", entries, ["start"], true).pass).toBe(true);
33
+ });
34
+ it("an explicitly expected error step passes", () => {
35
+ const entries = [e(1, "start"), e(2, "failed", { level: "error" })];
36
+ const result = verifyFlow("add-to-cart", "r1", entries, ["start", { step: "failed", level: "error" }], false);
37
+ expect(result.pass).toBe(true);
38
+ });
39
+ it("object matchers can constrain meta", () => {
40
+ const entries = [e(1, "done", { meta: { count: 5 } })];
41
+ expect(verifyFlow("f", "r1", entries, [{ step: "done", metaIncludes: '"count":5' }], false).pass).toBe(true);
42
+ expect(verifyFlow("f", "r1", entries, [{ step: "done", metaIncludes: 'count":9' }], false).pass).toBe(false);
43
+ });
44
+ });
45
+ //# sourceMappingURL=verifyFlow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifyFlow.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/verifyFlow.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"guides.d.ts","sourceRoot":"","sources":["../../src/core/guides.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,KAAK;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACnB;AAiWD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,MAchB,CAAC;AAEb,wBAAgB,gBAAgB,IAAI,MAAM,CAWzC;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI5D;AAED,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAE7C"}
1
+ {"version":3,"file":"guides.d.ts","sourceRoot":"","sources":["../../src/core/guides.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,KAAK;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACnB;AA4YD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,MAehB,CAAC;AAEb,wBAAgB,gBAAgB,IAAI,MAAM,CAWzC;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI5D;AAED,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAE7C"}
@@ -202,7 +202,8 @@ tap(text=...) skips fiber for non-ASCII (Hermes limitation) and uses accessibili
202
202
  ## Tips
203
203
  - Always start with summary=true to avoid token overload
204
204
  - Use verbose=true with low maxLogs for full error details
205
- - Use startFromText to begin reading from a specific point`
205
+ - Use startFromText to begin reading from a specific point
206
+ - Instrumenting a flow to verify behavior? Prefer flowpoint() over console.log — see get_usage_guide(topic="flowpoints")`
206
207
  },
207
208
  {
208
209
  id: "network",
@@ -350,6 +351,48 @@ Suggested prompt the user can paste to trigger this:
350
351
  - Include workflow_context when possible — name the ExecBro tools/steps in play so the team can reproduce the tooling issue
351
352
  - The user can review and edit the issue body before submitting
352
353
  - No GitHub account setup or CLI tools needed — just a browser`
354
+ },
355
+ {
356
+ id: "flowpoints",
357
+ title: "Flowpoints — Flow Tracing & Verification",
358
+ summary: "Instrument app flows with flowpoint() breadcrumbs, then query, wait on, and assert them",
359
+ content: `# Flowpoints — Flow Tracing & Verification
360
+
361
+ Flowpoints are structured, timestamped breadcrumbs emitted by flowpoint() calls in app
362
+ code (execbro-sdk). They replace console.log spraying when you need to VERIFY what a
363
+ flow actually did — steps, order, timing, failures — with factual assertions.
364
+
365
+ ## Workflow (verify a flow)
366
+ 1. Instrument the flow (edit app code; execbro-sdk must be installed and init()-ed):
367
+ import { flowpoint } from 'execbro-sdk'
368
+ flowpoint({ name: 'add-to-cart', step: 'start', begin: true }) // flow entry
369
+ flowpoint({ name: 'add-to-cart', step: 'cleared', meta: { removed: 3 } })
370
+ flowpoint({ name: 'add-to-cart', step: 'done' })
371
+ flowpoint({ name: 'add-to-cart', step: 'failed', level: 'error' }) // error paths
372
+ 2. Reload the app so the instrumented code is live.
373
+ 3. Drive the flow (tap, swipe, input).
374
+ 4. wait_for_flowpoint({ name: 'add-to-cart', step: 'done' }) — blocks until the flow
375
+ finishes instead of sleeping and re-polling.
376
+ 5. verify_flow({ name: 'add-to-cart', expect: ['start', 'cleared', 'done'] }) —
377
+ factual PASS/FAIL diff against the expected sequence.
378
+ 6. get_flowpoints({ name: 'add-to-cart', run: 'last' }) — full trail with timing
379
+ deltas when diagnosing a failure.
380
+
381
+ ## Key Tools
382
+ - get_flowpoints: query the trail (filters: name, step, run, level, metaIncludes, since)
383
+ - wait_for_flowpoint: block until a matching point arrives (or timeout with partial trail)
384
+ - verify_flow: assert an expected step sequence against one run (any unexpected error-level point fails it unless allowErrors: true)
385
+ - clear_flowpoints: reset stored points (name-scoped clears touch only the server store; rarely needed — prefer run filters)
386
+
387
+ ## Tips
388
+ - Prefer flowpoint() over console.log when instrumenting a flow to verify behavior.
389
+ - Keep name and step low-cardinality and stable; dynamic payload goes in meta.
390
+ - begin: true on the flow's entry point separates retries into runs; run: 'last'
391
+ queries only the newest attempt.
392
+ - get_flowpoints({ level: 'error' }) answers "did anything fail?" across every flow.
393
+ - flowpoint() is a production no-op — instrumentation can stay in the code.
394
+ - Runtime TDD: write the verify_flow expectation FIRST, then implement until it passes.
395
+ - verify_flow FAILS on any unexpected error-level point in the run — pass allowErrors: true to tolerate them, or include the error step in expect.`
353
396
  }
354
397
  ];
355
398
  /**
@@ -363,15 +406,16 @@ export const DECISION_TREE = [
363
406
  "Platform-specific ios_* / android_* tools (ios_button, android_input_text, android_key_event, android_long_press, ios_open_url, etc.) are FALLBACKS for non-React or native-only flows — prefer the cross-platform primary tools above whenever possible.",
364
407
  "",
365
408
  "Call get_usage_guide(topic=...) for end-to-end workflows. Available topics:",
366
- " setup — session setup (scan_metro, connect_metro, ensure_connection)",
367
- " logs — console debugging (get_logs, search_logs)",
368
- " interact — device interaction (tap, swipe, screenshots, android_input_text, clear_focused_input, dismiss_keyboard)",
369
- " layout — on-screen layout check (get_screen_layout, get_pressable_elements)",
370
- " inspect — component inspection (find_components, inspect_component, get_inspector_selection)",
371
- " network — network request inspection (get_network_requests, search_network)",
372
- " state — app state & JS execution (execute_in_app, list_debug_globals)",
373
- " bundle — bundle / Metro error checks (get_bundle_status, get_bundle_errors)",
374
- " feedback — share feedback, feature requests, or bug reports (send_feedback)"
409
+ " setup — session setup (scan_metro, connect_metro, ensure_connection)",
410
+ " logs — console debugging (get_logs, search_logs)",
411
+ " interact — device interaction (tap, swipe, screenshots, android_input_text, clear_focused_input, dismiss_keyboard)",
412
+ " layout — on-screen layout check (get_screen_layout, get_pressable_elements)",
413
+ " inspect — component inspection (find_components, inspect_component, get_inspector_selection)",
414
+ " network — network request inspection (get_network_requests, search_network)",
415
+ " flowpoints — verify a flow's behavior (flowpoint() breadcrumbs, wait_for_flowpoint, verify_flow)",
416
+ " state — app state & JS execution (execute_in_app, list_debug_globals)",
417
+ " bundle — bundle / Metro error checks (get_bundle_status, get_bundle_errors)",
418
+ " feedback — share feedback, feature requests, or bug reports (send_feedback)"
375
419
  ].join("\n");
376
420
  export function getGuideOverview() {
377
421
  const guideList = guides.map((g) => ` ${g.id} — ${g.summary}`).join("\n");
@@ -1 +1 @@
1
- {"version":3,"file":"guides.js","sourceRoot":"","sources":["../../src/core/guides.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"guides.js","sourceRoot":"","sources":["../../src/core/guides.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAkBA,OAAO,EAAkC,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAiBlF,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAkBA,OAAO,EAAkC,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAkBlF,OAAO,EAAE,YAAY,EAAE,CAAC"}
package/build/index.js CHANGED
@@ -20,6 +20,7 @@ import { registerConnectionTools } from "./tools/connectionTools.js";
20
20
  import { registerScreenshotTools } from "./tools/screenshotTools.js";
21
21
  import { registerInteractionTools } from "./tools/interactionTools.js";
22
22
  import { registerComponentTools } from "./tools/componentTools.js";
23
+ import { registerFlowpointTools } from "./pro/flowpointTools.js";
23
24
  // Re-export so tests (src/__tests__/unit/toolDescriptions.test.ts) can enumerate
24
25
  // registered tools without booting the server.
25
26
  export { toolRegistry };
@@ -45,6 +46,7 @@ registerReduxTools(server);
45
46
  registerExecutionTools(server);
46
47
  registerLogTools(server);
47
48
  registerNetworkTools(server);
49
+ registerFlowpointTools(server);
48
50
  registerBundleTools(server);
49
51
  registerDeviceTools(server);
50
52
  registerConnectionTools(server);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EACH,aAAa,EACb,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,0BAA0B,GAC7B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,8BAA8B,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,iFAAiF;AACjF,+CAA+C;AAC/C,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB,MAAM,MAAM,GAAG,IAAI,SAAS,CACxB;IACI,IAAI,EAAE,2BAA2B;IACjC,OAAO,EAAE,OAAO;CACnB,EACD;IACI,YAAY,EAAE;QACV,oCAAoC;QACpC,EAAE;QACF,aAAa;QACb,EAAE;QACF,kGAAkG;KACrG,CAAC,IAAI,CAAC,IAAI,CAAC;CACf,CACJ,CAAC;AACF,8BAA8B,CAAC,MAAM,CAAC,CAAC;AAEvC,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,iBAAiB,CAAC,MAAM,EAAE;IACtB,OAAO,EAAE,SAAS,EAAE;IACpB,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;CAC5C,CAAC,CAAC;AACH,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAC3B,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAC/B,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACzB,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChC,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChC,wBAAwB,CAAC,MAAM,CAAC,CAAC;AACjC,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAE/B,KAAK,UAAU,IAAI;IACf,aAAa,EAAE,CAAC;IAChB,iBAAiB,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAEvC,6EAA6E;IAC7E,8EAA8E;IAC9E,2EAA2E;IAC3E,mEAAmE;IACnE,0EAA0E;IAC1E,8EAA8E;IAC9E,sEAAsE;IAEtE,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IAEnE,IAAI,OAAO,EAAE,CAAC;QACV,qDAAqD;QACrD,sFAAsF;QACtF,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;YAChD,kBAAkB,EAAE,SAAS;SAChC,CAAC,CAAC;QAEH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEhC,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YACnD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,oBAAoB,QAAQ,EAAE,CAAC,CAAC;YAEnE,IAAI,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;gBAC1B,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBACxC,OAAO;YACX,CAAC;YAED,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE;YAC7B,OAAO,CAAC,KAAK,CAAC,2DAA2D,QAAQ,MAAM,CAAC,CAAC;QAC7F,CAAC,CAAC,CAAC;IACP,CAAC;SAAM,CAAC;QACJ,gDAAgD;QAChD,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;AACL,CAAC;AAED,2EAA2E;AAC3E,wEAAwE;AACxE,iEAAiE;AACjE,iDAAiD;AACjD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;IACzG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACnB,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACP,CAAC;AAED,mFAAmF;AACnF,SAAS,gBAAgB;IACrB,oBAAoB,EAAE,CAAC;IACvB,2BAA2B,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/C,IAAI,CAAC;YACD,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACL,sCAAsC;QAC1C,CAAC;QACD,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IACD,0BAA0B,EAAE,CAAC;IAC7B,uBAAuB,EAAE,CAAC;IAC1B,uBAAuB,EAAE,CAAC;IAC1B,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,gBAAgB,EAAE,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,gBAAgB,EAAE,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function resolveTargetDeviceName(device?: string): string;
3
+ export declare function registerFlowpointTools(server: McpServer): void;
4
+ //# sourceMappingURL=flowpointTools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flowpointTools.d.ts","sourceRoot":"","sources":["../../src/pro/flowpointTools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0BzE,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAS/D;AAOD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkR9D"}
@@ -0,0 +1,266 @@
1
+ import { z } from "zod";
2
+ import { registerToolWithTelemetry } from "../core/register.js";
3
+ import { getConnectedAppByDevice, getFirstConnectedApp, executeInApp } from "../core/index.js";
4
+ import { UserInputError } from "../core/errors.js";
5
+ import { allStoredFlowpoints, clearFlowpointStores, drainFlowpoints, filterFlowpoints, formatFlowpoints, formatMeta, getFlowpointStore, matchesPoint, buildClearExpression, verifyFlow, resolveLastRuns, } from "./flowpoints.js";
6
+ const NO_FLOWPOINTS_HINT = "No flowpoints captured. Instrument the flow under test (execbro-sdk required):\n\n" +
7
+ " import { flowpoint } from 'execbro-sdk'\n" +
8
+ " flowpoint({ name: 'my-flow', step: 'start', begin: true })\n" +
9
+ " flowpoint({ name: 'my-flow', step: 'done', meta: { anything: true } })\n\n" +
10
+ "Then reload the app, drive the flow, and query again. " +
11
+ 'See get_usage_guide(topic="flowpoints").';
12
+ export function resolveTargetDeviceName(device) {
13
+ if (device) {
14
+ const app = getConnectedAppByDevice(device);
15
+ if (!app)
16
+ throw new UserInputError(`No connected device matches "${device}"`);
17
+ return app.deviceInfo.deviceName || app.deviceInfo.title || "unknown";
18
+ }
19
+ const first = getFirstConnectedApp();
20
+ if (!first)
21
+ throw new UserInputError("No connected app. Run scan_metro first.");
22
+ return first.deviceInfo.deviceName || first.deviceInfo.title || "unknown";
23
+ }
24
+ const deviceParam = z
25
+ .string()
26
+ .optional()
27
+ .describe("Target device name (substring match). Omit for all devices. Run get_apps to see connected devices.");
28
+ export function registerFlowpointTools(server) {
29
+ registerToolWithTelemetry(server, "get_flowpoints", {
30
+ description: "Read flowpoint breadcrumbs — structured, timestamped points emitted by flowpoint() calls " +
31
+ "(execbro-sdk) — grouped by flow and run, with inter-point timing deltas.\n" +
32
+ "PURPOSE: verify what actually happened inside a flow (steps, order, timing, failures) " +
33
+ "instead of inferring it from console logs.\n" +
34
+ "WHEN TO USE: after driving an instrumented flow; or with level: 'error' to ask " +
35
+ '"did any flow fail?" across all flows at once.\n' +
36
+ "WORKFLOW: instrument with flowpoint() -> reload -> drive the flow -> " +
37
+ "wait_for_flowpoint (sync) -> verify_flow (assert) -> get_flowpoints (inspect details).\n" +
38
+ "LIMITATIONS: requires execbro-sdk init() and flowpoint() instrumentation in app code.\n" +
39
+ "GOOD: get_flowpoints({ name: 'add-to-cart', run: 'last' }) after a retry.\n" +
40
+ "BAD: polling get_flowpoints in a loop — use wait_for_flowpoint instead.\n" +
41
+ 'SEE ALSO: call get_usage_guide(topic="flowpoints") for the full playbook.',
42
+ inputSchema: {
43
+ name: z.string().optional().describe("Filter to one flow name. Omit for all flows."),
44
+ step: z.string().optional().describe("Filter to one step label (exact match)."),
45
+ run: z
46
+ .string()
47
+ .optional()
48
+ .describe("Filter to one run id, or 'last' for the most recent run per flow."),
49
+ level: z.enum(["info", "warn", "error"]).optional().describe("Filter by severity."),
50
+ metaIncludes: z
51
+ .string()
52
+ .optional()
53
+ .describe("Case-insensitive substring match against the stringified meta payload."),
54
+ since: z.number().optional().describe("Epoch-ms lower bound on the point timestamp (exclusive)."),
55
+ limit: z.number().optional().default(200).describe("Max points returned, newest kept (default 200)."),
56
+ device: deviceParam,
57
+ },
58
+ }, async ({ name, step, run, level, metaIncludes, since, limit, device }) => {
59
+ const deviceName = resolveTargetDeviceName(device);
60
+ const drained = await drainFlowpoints(deviceName, device);
61
+ if (!drained.ok) {
62
+ return { isError: true, content: [{ type: "text", text: drained.error }] };
63
+ }
64
+ const sourceEntries = device ? getFlowpointStore(deviceName).entries : allStoredFlowpoints();
65
+ const entries = filterFlowpoints(sourceEntries, {
66
+ name,
67
+ step,
68
+ run,
69
+ level,
70
+ metaIncludes,
71
+ since,
72
+ limit,
73
+ });
74
+ if (entries.length === 0) {
75
+ if (sourceEntries.length === 0) {
76
+ return { content: [{ type: "text", text: NO_FLOWPOINTS_HINT }] };
77
+ }
78
+ return {
79
+ content: [
80
+ {
81
+ type: "text",
82
+ text: `${sourceEntries.length} flowpoints stored, but 0 matched your filters. ` +
83
+ "Loosen or drop filters (name/step/run/level/metaIncludes/since) to see them.",
84
+ },
85
+ ],
86
+ };
87
+ }
88
+ const flows = new Set(entries.map((e) => e.name)).size;
89
+ return {
90
+ content: [
91
+ {
92
+ type: "text",
93
+ text: `Flowpoints (${entries.length} points, ${flows} flow${flows === 1 ? "" : "s"}):\n\n${formatFlowpoints(entries)}`,
94
+ },
95
+ ],
96
+ };
97
+ }, (result) => !!result?.content?.[0]?.text?.startsWith("No flowpoints captured"));
98
+ registerToolWithTelemetry(server, "clear_flowpoints", {
99
+ description: "Clear stored flowpoints.\n" +
100
+ "PURPOSE: reset flowpoint history between test sessions.\n" +
101
+ "WHEN TO USE: rarely — prefer begin: true + run: 'last' filtering between attempts. " +
102
+ "With name: clears one flow from the server store only (cleared entries never re-drain). " +
103
+ "Without name: clears everything server-side AND the in-app buffer.",
104
+ inputSchema: {
105
+ name: z.string().optional().describe("Clear only this flow (server-side). Omit to clear all."),
106
+ device: z
107
+ .string()
108
+ .optional()
109
+ .describe("Target device (substring match). Scopes both the server-store clear and the in-app " +
110
+ "buffer clear. Omit for all devices."),
111
+ },
112
+ }, async ({ name, device }) => {
113
+ const deviceName = device ? resolveTargetDeviceName(device) : undefined;
114
+ let cleared = clearFlowpointStores(name, deviceName);
115
+ let caveat = "";
116
+ if (!name) {
117
+ const result = await executeInApp(buildClearExpression(), false, { timeoutMs: 3000, originatingToolName: "clear_flowpoints" }, device);
118
+ if (result.success) {
119
+ const inApp = parseInt(result.result || "0", 10);
120
+ if (!isNaN(inApp))
121
+ cleared = Math.max(cleared, inApp);
122
+ }
123
+ else {
124
+ caveat = " (in-app buffer clear failed — still-buffered points may re-drain after the next app event)";
125
+ }
126
+ }
127
+ const scope = name ? ` for flow "${name}"` : "";
128
+ return { content: [{ type: "text", text: `Cleared ${cleared} flowpoints${scope}.${caveat}` }] };
129
+ });
130
+ registerToolWithTelemetry(server, "wait_for_flowpoint", {
131
+ description: "Block until a flowpoint matching the criteria arrives, or timeout.\n" +
132
+ "PURPOSE: deterministic synchronization for drive-then-verify — act first, then block on the flow's " +
133
+ "terminal step instead of sleeping and re-polling.\n" +
134
+ "WHEN TO USE: after tapping/driving an instrumented flow, with the flow's terminal step.\n" +
135
+ "Points emitted after your action but before this call still match (only points already " +
136
+ "seen by a previous flowpoint tool call are excluded).\n" +
137
+ "On timeout, returns whatever points DID arrive for the flow — that partial trail is the " +
138
+ "diagnostic for what stalled.\n" +
139
+ 'SEE ALSO: get_usage_guide(topic="flowpoints").',
140
+ inputSchema: {
141
+ name: z.string().describe("Flow name to watch."),
142
+ step: z.string().optional().describe("Step label to wait for (exact match). Omit to match any step."),
143
+ level: z.enum(["info", "warn", "error"]).optional().describe("Only match this severity."),
144
+ metaIncludes: z
145
+ .string()
146
+ .optional()
147
+ .describe("Case-insensitive substring the stringified meta must contain."),
148
+ timeoutMs: z.number().optional().default(5000).describe("Max wait in ms (default 5000, cap 30000)."),
149
+ device: deviceParam,
150
+ },
151
+ }, async ({ name, step, level, metaIncludes, timeoutMs, device }) => {
152
+ const effectiveTimeout = Math.min(timeoutMs, 30000);
153
+ const deviceName = resolveTargetDeviceName(device);
154
+ const store = getFlowpointStore(deviceName);
155
+ const baselineEntry = store.entries.length > 0 ? store.entries[store.entries.length - 1] : null;
156
+ const start = Date.now();
157
+ const deadline = start + effectiveTimeout;
158
+ const freshEntries = () => {
159
+ const startIdx = baselineEntry ? store.entries.indexOf(baselineEntry) + 1 : 0;
160
+ return store.entries.slice(startIdx).filter((e) => e.name === name);
161
+ };
162
+ for (;;) {
163
+ const remaining = deadline - Date.now();
164
+ if (remaining > 0) {
165
+ const drained = await Promise.race([
166
+ drainFlowpoints(deviceName, device),
167
+ new Promise((resolve) => setTimeout(() => resolve(null), remaining)),
168
+ ]);
169
+ if (drained && !drained.ok) {
170
+ return { isError: true, content: [{ type: "text", text: drained.error }] };
171
+ }
172
+ }
173
+ const fresh = freshEntries();
174
+ const match = fresh.find((e) => matchesPoint(e, { step, level, metaIncludes }));
175
+ if (match) {
176
+ const meta = match.meta !== undefined ? `\nmeta: ${formatMeta(match.meta)}` : "";
177
+ return {
178
+ content: [
179
+ {
180
+ type: "text",
181
+ text: `Matched after ${Date.now() - start}ms: flow "${match.name}" ` +
182
+ `run ${match.run} step "${match.step}" [${match.level}]${meta}`,
183
+ },
184
+ ],
185
+ };
186
+ }
187
+ if (Date.now() >= deadline) {
188
+ const trail = fresh.length
189
+ ? `Points that DID arrive for "${name}" during the wait:\n\n${formatFlowpoints(fresh)}`
190
+ : `No new points arrived for flow "${name}" during the wait.`;
191
+ return {
192
+ content: [
193
+ {
194
+ type: "text",
195
+ text: `Timeout after ${effectiveTimeout}ms waiting for flow "${name}"${step ? ` step "${step}"` : ""}.\n${trail}`,
196
+ },
197
+ ],
198
+ };
199
+ }
200
+ await new Promise((resolve) => setTimeout(resolve, Math.min(250, Math.max(1, deadline - Date.now()))));
201
+ }
202
+ });
203
+ registerToolWithTelemetry(server, "verify_flow", {
204
+ description: "Assert a flow behaved as expected: compare the actual flowpoint trail of one run " +
205
+ "against an expected step sequence and get a factual PASS/FAIL diff.\n" +
206
+ "PURPOSE: factual PASS/FAIL assertion of a flow run against an expected step sequence.\n" +
207
+ "WHEN TO USE: after wait_for_flowpoint confirms the flow finished; or write the expectation first " +
208
+ "(runtime TDD) and iterate until PASS.\n" +
209
+ "Matching is subsequence: expected steps must appear in order; extra points in between " +
210
+ "are fine. Any unexpected error-level point fails the run unless allowErrors is true or " +
211
+ "that step is explicitly expected.\n" +
212
+ "WORKFLOW: write the expected sequence (even before implementing — runtime TDD), drive " +
213
+ "the flow, wait_for_flowpoint on the terminal step, then verify_flow.\n" +
214
+ 'SEE ALSO: get_usage_guide(topic="flowpoints").',
215
+ inputSchema: {
216
+ name: z.string().describe("Flow name to verify."),
217
+ expect: z
218
+ .array(z.union([
219
+ z.string(),
220
+ z.object({
221
+ step: z.string(),
222
+ level: z.enum(["info", "warn", "error"]).optional(),
223
+ metaIncludes: z.string().optional(),
224
+ }),
225
+ ]))
226
+ .describe("Expected step sequence, in order. Strings are shorthand for { step }."),
227
+ run: z.string().optional().default("last").describe("Run id to check, or 'last' (default)."),
228
+ allowErrors: z
229
+ .boolean()
230
+ .optional()
231
+ .default(false)
232
+ .describe("Tolerate unexpected error-level points (default false)."),
233
+ device: deviceParam,
234
+ },
235
+ }, async ({ name, expect: expected, run, allowErrors, device }) => {
236
+ const deviceName = resolveTargetDeviceName(device);
237
+ const drained = await drainFlowpoints(deviceName, device);
238
+ if (!drained.ok) {
239
+ return { isError: true, content: [{ type: "text", text: drained.error }] };
240
+ }
241
+ const sourceEntries = device ? getFlowpointStore(deviceName).entries : allStoredFlowpoints();
242
+ const flowEntries = sourceEntries.filter((e) => e.name === name);
243
+ if (flowEntries.length === 0) {
244
+ return {
245
+ content: [
246
+ {
247
+ type: "text",
248
+ text: `No flowpoints recorded for flow "${name}".\n\n${NO_FLOWPOINTS_HINT}`,
249
+ },
250
+ ],
251
+ };
252
+ }
253
+ const runId = run === "last" || run === undefined ? resolveLastRuns(flowEntries).get(name) : run;
254
+ const runEntries = flowEntries.filter((e) => e.run === runId);
255
+ if (runEntries.length === 0) {
256
+ return {
257
+ isError: true,
258
+ content: [{ type: "text", text: `No entries for flow "${name}" run "${runId}".` }],
259
+ };
260
+ }
261
+ const result = verifyFlow(name, runId, runEntries, expected, allowErrors ?? false);
262
+ // A FAIL verdict is a successful verification, not a tool error — never set isError for it.
263
+ return { content: [{ type: "text", text: result.text }] };
264
+ });
265
+ }
266
+ //# sourceMappingURL=flowpointTools.js.map