@swmansion/argent 0.30.2-next.2 → 0.30.2-next.20

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.
@@ -1584,6 +1584,7 @@ var init_failure_codes = __esm({
1584
1584
  REACT_PROFILER_DEVTOOLS_RENDERER_MISSING: "REACT_PROFILER_DEVTOOLS_RENDERER_MISSING",
1585
1585
  REACT_PROFILER_START_FAILED: "REACT_PROFILER_START_FAILED",
1586
1586
  REACT_PROFILER_START_VERIFY_FAILED: "REACT_PROFILER_START_VERIFY_FAILED",
1587
+ REACT_PROFILER_SESSION_TORN_DOWN: "REACT_PROFILER_SESSION_TORN_DOWN",
1587
1588
  REACT_PROFILER_HOOK_ERROR: "REACT_PROFILER_HOOK_ERROR",
1588
1589
  REACT_PROFILER_ANALYZE_NO_DATA: "REACT_PROFILER_ANALYZE_NO_DATA",
1589
1590
  NATIVE_PROFILER_FACTORY_OPTIONS_MISSING: "NATIVE_PROFILER_FACTORY_OPTIONS_MISSING",
@@ -100944,7 +100945,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
100944
100945
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
100945
100946
  function readCliVersion() {
100946
100947
  if (true) {
100947
- return "0.30.2-next.2";
100948
+ return "0.30.2-next.20";
100948
100949
  }
100949
100950
  return "0.0.0";
100950
100951
  }
@@ -122147,19 +122148,23 @@ async function openMoqClient(udid) {
122147
122148
  async function openMoqClientFromInfo(info) {
122148
122149
  await installNodeWebTransport();
122149
122150
  const session = new MoqDeviceSession(await connectMoq(info), { publishPath: PUBLISH_PATH });
122150
- disposeWhenTransportDies(session);
122151
+ let closed = false;
122152
+ disposeWhenTransportDies(session, () => closed = true);
122151
122153
  return {
122152
- sendControl: (payload) => session.sendControl(payload),
122154
+ // The SDK resolves sends on a closed session, reporting undelivered input as sent.
122155
+ sendControl: (payload) => closed ? Promise.reject(new Error("MoQ session is closed")) : session.sendControl(payload),
122153
122156
  async screenshot(opts) {
122154
122157
  return Buffer.from(await session.screenshot({ scale: opts?.scale }));
122155
122158
  },
122156
122159
  async close() {
122160
+ closed = true;
122157
122161
  session.close();
122158
122162
  }
122159
122163
  };
122160
122164
  }
122161
- function disposeWhenTransportDies(session) {
122165
+ function disposeWhenTransportDies(session, onDispose) {
122162
122166
  const dispose = () => {
122167
+ onDispose();
122163
122168
  try {
122164
122169
  session.close();
122165
122170
  } catch {
@@ -122219,6 +122224,52 @@ function settleWithin(p, ms, signal) {
122219
122224
  // ../tool-server/src/utils/simulator-client.ts
122220
122225
  init_external_devices();
122221
122226
 
122227
+ // ../tool-server/src/utils/profiling-devices.ts
122228
+ var runs = /* @__PURE__ */ new Map();
122229
+ var servers = /* @__PURE__ */ new Map();
122230
+ function trackProfilingRun(deviceId, run2) {
122231
+ let set2 = runs.get(deviceId);
122232
+ if (!set2) {
122233
+ set2 = /* @__PURE__ */ new Set();
122234
+ runs.set(deviceId, set2);
122235
+ }
122236
+ set2.add(run2);
122237
+ syncCaptureOnDemand();
122238
+ }
122239
+ function isProfiling(deviceId) {
122240
+ syncCaptureOnDemand();
122241
+ return runs.has(deviceId);
122242
+ }
122243
+ function syncCaptureOnDemand() {
122244
+ for (const [deviceId, set2] of runs) {
122245
+ for (const run2 of set2) {
122246
+ if (!run2.profilingActive) set2.delete(run2);
122247
+ }
122248
+ if (set2.size === 0) runs.delete(deviceId);
122249
+ }
122250
+ for (const [deviceId, server] of servers) {
122251
+ const profiling = runs.has(deviceId);
122252
+ if (server.onDemand !== profiling) {
122253
+ server.onDemand = profiling;
122254
+ server.send(profiling);
122255
+ }
122256
+ }
122257
+ }
122258
+ function registerCaptureOnDemandSender(deviceId, endpoint, send) {
122259
+ const entry = { endpoint, send, onDemand: false };
122260
+ servers.set(deviceId, entry);
122261
+ syncCaptureOnDemand();
122262
+ return () => {
122263
+ if (servers.get(deviceId) !== entry) return;
122264
+ servers.delete(deviceId);
122265
+ if (entry.onDemand) entry.send(false);
122266
+ };
122267
+ }
122268
+ function captureOnDemandDropped(deviceId, endpoint) {
122269
+ const server = servers.get(deviceId);
122270
+ if (server?.endpoint === endpoint) server.onDemand = false;
122271
+ }
122272
+
122222
122273
  // ../tool-server/src/utils/foldable.ts
122223
122274
  var import_node_child_process13 = require("node:child_process");
122224
122275
  var fs17 = __toESM(require("node:fs"));
@@ -122461,6 +122512,14 @@ var FIRST_FRAME_POLL_MS = 250;
122461
122512
  var COMMAND_ACK_TIMEOUT_MS = 5e3;
122462
122513
  var connections = /* @__PURE__ */ new Map();
122463
122514
  var cmdId = 0;
122515
+ function pendingIdNamedBy(conn, message) {
122516
+ const named = message?.match(/unknown variant `([^`]+)`/)?.[1];
122517
+ if (named === void 0) return void 0;
122518
+ for (const [id, entry] of conn.pending) {
122519
+ if (entry.cmd === named) return id;
122520
+ }
122521
+ return void 0;
122522
+ }
122464
122523
  function failAllPending(conn, makeError) {
122465
122524
  const entries = [...conn.pending.values()];
122466
122525
  conn.pending.clear();
@@ -122507,7 +122566,7 @@ function getOrCreateConnection(api) {
122507
122566
  }
122508
122567
  if (ack.status !== "ok" && ack.status !== "error") return;
122509
122568
  if (ack.id != null && !conn.pending.has(ack.id)) return;
122510
- const id = ack.id ?? conn.pending.keys().next().value;
122569
+ const id = ack.id ?? pendingIdNamedBy(conn, ack.message) ?? conn.pending.keys().next().value;
122511
122570
  if (id == null) return;
122512
122571
  const entry = conn.pending.get(id);
122513
122572
  if (entry == null) return;
@@ -122536,6 +122595,7 @@ function getOrCreateConnection(api) {
122536
122595
  ws.on("close", () => {
122537
122596
  connections.delete(key2);
122538
122597
  failAllPending(conn, (cmd) => transportError(cmd, key2, "the connection closed"));
122598
+ if (api.deviceId) captureOnDemandDropped(api.deviceId, key2);
122539
122599
  });
122540
122600
  connections.set(key2, conn);
122541
122601
  return conn;
@@ -123211,6 +123271,19 @@ async function spawnSimulatorServerProcess(udid, subcommand) {
123211
123271
  }, READY_TIMEOUT_MS);
123212
123272
  });
123213
123273
  }
123274
+ function withCaptureOnDemand(deviceId, instance) {
123275
+ const unregister = registerCaptureOnDemandSender(deviceId, instance.api.apiUrl, (enabled) => {
123276
+ sendCommand(instance.api, { cmd: "capture_on_demand", enabled }).catch(() => {
123277
+ });
123278
+ });
123279
+ return {
123280
+ ...instance,
123281
+ dispose: async () => {
123282
+ unregister();
123283
+ await instance.dispose();
123284
+ }
123285
+ };
123286
+ }
123214
123287
  var simulatorServerBlueprint = {
123215
123288
  namespace: SIMULATOR_SERVER_NAMESPACE,
123216
123289
  getURN(device) {
@@ -123255,7 +123328,7 @@ var simulatorServerBlueprint = {
123255
123328
  }
123256
123329
  const claim2 = externalClaimForAnyId(device.id);
123257
123330
  if (claim2) {
123258
- return buildAttachedInstance(device, claim2);
123331
+ return withCaptureOnDemand(device.id, await buildAttachedInstance(device, claim2));
123259
123332
  }
123260
123333
  if (device.platform === "ios-remote") {
123261
123334
  return buildRemoteInstance(device);
@@ -123313,7 +123386,7 @@ var simulatorServerBlueprint = {
123313
123386
  events
123314
123387
  };
123315
123388
  await attachFoldableDisplay(instance.api, device);
123316
- return instance;
123389
+ return withCaptureOnDemand(device.id, instance);
123317
123390
  }
123318
123391
  };
123319
123392
 
@@ -125977,6 +126050,7 @@ Chromium apps are discovered by probing CDP debugging ports (default 9222; exten
125977
126050
  Booted/ready devices are listed first. Platforms whose CLI is unavailable are silently omitted; an empty result usually means xcode-select, Android platform-tools, <flag:harmonyos>DevEco Studio, </flag:harmonyos>or the Vega SDK is not installed.`,
125978
126051
  alwaysLoad: true,
125979
126052
  searchHint: "list devices simulators emulators avd serial udid ios android chromium vega <flag:harmonyos>harmony harmonyos </flag:harmonyos>app fire tv session start",
126053
+ readOnly: true,
125980
126054
  zodSchema,
125981
126055
  services: () => ({}),
125982
126056
  async execute(_services, _params) {
@@ -130727,6 +130801,7 @@ function createHttpApp(registry2, options) {
130727
130801
  if (def.searchHint) entry.searchHint = renderFlagGated(def.searchHint, isFlagEnabled);
130728
130802
  if (def.longRunning) entry.longRunning = true;
130729
130803
  if (def.hideFromMcp) entry.hideFromMcp = true;
130804
+ if (def.readOnly) entry.readOnly = true;
130730
130805
  const aliases = (def.aliases ?? []).map((alias) => ({
130731
130806
  ...entry,
130732
130807
  name: alias,
@@ -130974,11 +131049,12 @@ function createHttpApp(registry2, options) {
130974
131049
  const toolNote = takeToolNote(data);
130975
131050
  if (toolNote) notes.push(toolNote);
130976
131051
  const notePayload = notes.length > 0 ? { note: notes.join("\n\n") } : {};
131052
+ const profilingPayload = deviceArg && isProfiling(canonicalDeviceId(deviceArg) ?? deviceArg) ? { profiling: true } : {};
130977
131053
  if (wantsStream) {
130978
- writeLine({ event: "result", data, ...notePayload });
131054
+ writeLine({ event: "result", data, ...notePayload, ...profilingPayload });
130979
131055
  res.end();
130980
131056
  } else {
130981
- res.json({ data, ...notePayload });
131057
+ res.json({ data, ...notePayload, ...profilingPayload });
130982
131058
  }
130983
131059
  } catch (err) {
130984
131060
  const attribute = (message) => {
@@ -133830,6 +133906,7 @@ If state is connecting: do NOT restart the app. Launching it is what starts the
133830
133906
  If state is indeterminate: the process could not be inspected, so restart-app is worth one attempt. If this call still reports it after that restart, do NOT restart the app again: the service is stale rather than the app uninjected, so restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. Remote simulators can never inspect the process, so this is the only unconnected state a running app reaches there.
133831
133907
  Returns { status: "init_failed", message, attempts } instead when the simulator's native-devtools environment failed to initialize.
133832
133908
  Fails if the simulator server is not running for the given UDID.`,
133909
+ readOnly: true,
133833
133910
  zodSchema: zodSchema2,
133834
133911
  services: (params) => ({
133835
133912
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -133987,6 +134064,7 @@ Returns { status: "ok", matches } with matching views including their frames, pr
133987
134064
  At least one of className, identifier, label, tag, or nativeID must be provided.
133988
134065
  If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
133989
134066
  A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the hierarchy query itself can error or time out.`,
134067
+ readOnly: true,
133990
134068
  zodSchema: zodSchema4,
133991
134069
  services: (params) => ({
133992
134070
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -134057,6 +134135,7 @@ Use when you need deep layout debugging, finding views with no accessibility lab
134057
134135
  Returns { status: "ok", windows, screen } with the full view hierarchy. screen gives the screen size in points on its portrait axes, and the interfaceOrientation of the UI (portrait, portraitUpsideDown, landscapeLeft, landscapeRight). Each screenFrame uses the portrait axes of the screen. Each windowFrame uses the axes of its window, which turn with the UI.
134058
134136
  If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
134059
134137
  A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the hierarchy query itself can error or time out.`,
134138
+ readOnly: true,
134060
134139
  zodSchema: zodSchema5,
134061
134140
  services: (params) => ({
134062
134141
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -134126,6 +134205,7 @@ normalized contract.
134126
134205
 
134127
134206
  If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
134128
134207
  A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the screen query itself can error or time out.`,
134208
+ readOnly: true,
134129
134209
  zodSchema: zodSchema6,
134130
134210
  services: (params) => ({
134131
134211
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -134208,6 +134288,7 @@ the UI is landscape.
134208
134288
 
134209
134289
  If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
134210
134290
  A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the point query itself can error or time out.`,
134291
+ readOnly: true,
134211
134292
  zodSchema: zodSchema7,
134212
134293
  services: (params) => ({
134213
134294
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -134296,6 +134377,7 @@ the UI is landscape.
134296
134377
 
134297
134378
  If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
134298
134379
  A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the point query itself can error or time out.`,
134380
+ readOnly: true,
134299
134381
  zodSchema: zodSchema8,
134300
134382
  services: (params) => ({
134301
134383
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -136753,6 +136835,7 @@ var reactProfilerSessionBlueprint = {
136753
136835
  profileStartWallMs: null,
136754
136836
  sessionId: null,
136755
136837
  ownerToolServerPid: null,
136838
+ disposed: false,
136756
136839
  disposeSession: () => events.emit("terminated")
136757
136840
  };
136758
136841
  await cdp.send("Profiler.enable").catch(warnOnError("Profiler.enable"));
@@ -136815,11 +136898,25 @@ var reactProfilerSessionBlueprint = {
136815
136898
  );
136816
136899
  };
136817
136900
  cdp.events.on("disconnected", onDisconnected);
136901
+ const onCdpEvent = (method) => {
136902
+ if (method !== "Runtime.executionContextDestroyed" && method !== "Runtime.executionContextsCleared") {
136903
+ return;
136904
+ }
136905
+ if (state3.profilingActive) {
136906
+ state3.profilingActive = false;
136907
+ clearCachedProfilerPaths(state3.port, state3.deviceId);
136908
+ stopSamplerInNextRuntime(cdp);
136909
+ }
136910
+ events.emit("terminated");
136911
+ };
136912
+ cdp.events.on("event", onCdpEvent);
136818
136913
  return {
136819
136914
  api: state3,
136820
136915
  dispose: async () => {
136916
+ state3.disposed = true;
136821
136917
  cdp.events.off("scriptParsed", onScriptParsed);
136822
136918
  cdp.events.off("disconnected", onDisconnected);
136919
+ cdp.events.off("event", onCdpEvent);
136823
136920
  if (state3.profilingActive) {
136824
136921
  state3.profilingActive = false;
136825
136922
  await cdp.send("Runtime.evaluate", {
@@ -136834,6 +136931,20 @@ var reactProfilerSessionBlueprint = {
136834
136931
  };
136835
136932
  }
136836
136933
  };
136934
+ function stopSamplerInNextRuntime(cdp) {
136935
+ const onEvent = (method) => {
136936
+ if (method !== "Runtime.executionContextCreated") return;
136937
+ disarm();
136938
+ void cdp.send("Profiler.stop").catch(() => {
136939
+ });
136940
+ };
136941
+ const disarm = () => {
136942
+ cdp.events.off("event", onEvent);
136943
+ cdp.events.off("disconnected", disarm);
136944
+ };
136945
+ cdp.events.on("event", onEvent);
136946
+ cdp.events.on("disconnected", disarm);
136947
+ }
136837
136948
  var profilerPathsCache = /* @__PURE__ */ new Map();
136838
136949
  function cacheKey(port, deviceId) {
136839
136950
  return `${port}:${deviceId}`;
@@ -136935,6 +137046,9 @@ function iosHeadlessFromEnv() {
136935
137046
  function androidHeadlessFromEnv() {
136936
137047
  return truthyEnv("ARGENT_EMULATOR_NO_WINDOW");
136937
137048
  }
137049
+ function androidGuestVulkanFromEnv() {
137050
+ return truthyEnv("ARGENT_EMULATOR_GUEST_VULKAN");
137051
+ }
136938
137052
 
136939
137053
  // ../tool-server/src/tools/devices/boot-device.ts
136940
137054
  init_device_info();
@@ -137687,6 +137801,9 @@ var zodSchema9 = external_exports.object({
137687
137801
  sound: external_exports.boolean().optional().describe(
137688
137802
  "Android only: boot the emulator with audio output enabled. Defaults to false: argent boots emulators MUTED so several agent-driven devices don't all play sound on the host machine; pass `true` when the task involves playing, hearing, or testing audio. Takes effect at boot: if the emulator is already running muted, add `force: true` to reboot it with sound. A boot snapshot saved in the other audio mode can't be reused, so the first boot after toggling is a slower cold boot. The `boot-sound` argent flag flips this default to true. Ignored on iOS/Vega<flag:harmonyos>/HarmonyOS</flag:harmonyos>/Electron, which argent never mutes."
137689
137803
  ),
137804
+ guestVulkan: external_exports.boolean().optional().describe(
137805
+ "Android on a macOS host only: boot the emulator with guest Vulkan. Defaults to false: guest Vulkan crashes Chrome's GPU process, which breaks Chrome and Custom Tab sign-in flows. Without it apps find no Vulkan device, although the guest still lists the Vulkan features, so a Vulkan-only renderer such as WebGPU (react-native-wgpu) draws nothing; pass `true` to test one. Takes effect at boot: an emulator already running in the other mode is reused with a `note`, and `force: true` reboots it. A boot snapshot saved in the other mode can't be reused, so the first boot after toggling is a slower cold boot. The `ARGENT_EMULATOR_GUEST_VULKAN` env var flips this default to true. Ignored on other hosts and platforms."
137806
+ ),
137690
137807
  headless: external_exports.boolean().optional().describe(
137691
137808
  "iOS only: boot the simulator core WITHOUT opening its GUI window (Simulator.app, or Device Hub on Xcode 27+). The device still streams via simulator-server; used by Argent Lens. Set the `ARGENT_SIMULATOR_NO_WINDOW` env var (1/true/yes) to force this host-wide without passing the flag per call (the iOS analog of `ARGENT_EMULATOR_NO_WINDOW`). Ignored on Android/Vega<flag:harmonyos>/HarmonyOS</flag:harmonyos>/Electron, which have no equivalent GUI step."
137692
137809
  ),
@@ -137754,14 +137871,27 @@ function selectGpuMode() {
137754
137871
  }
137755
137872
  return process.platform === "linux" ? "swiftshader" : "auto";
137756
137873
  }
137874
+ function guestVulkanArgs(guestVulkan) {
137875
+ if (process.platform !== "darwin") return [];
137876
+ return ["-feature", guestVulkan ? "Vulkan" : "-Vulkan"];
137877
+ }
137878
+ async function runningGuestVulkanNote(serial, guestVulkan) {
137879
+ if (process.platform !== "darwin") return void 0;
137880
+ const prop = await adbShell(serial, "getprop ro.boot.hardware.vulkan", { timeoutMs: 5e3 }).then((out) => out.trim()).catch(() => null);
137881
+ if (prop === null || prop !== "" === guestVulkan) return void 0;
137882
+ return guestVulkan ? "This emulator was already running without guest Vulkan, so apps find no Vulkan device. Pass `force: true` to reboot it with guest Vulkan." : "This emulator was already running with guest Vulkan, which can crash Chrome's GPU process. Pass `force: true` to reboot it without guest Vulkan.";
137883
+ }
137757
137884
  var BOOT_POLL_INTERVALS_MS = {
137758
137885
  serialByAvd: 1500,
137759
137886
  // findSerialByAvdName: re-scan when >1 new emulator appeared
137760
137887
  adbRegister: 1e3,
137761
137888
  // attemptBoot stage 2: re-scan adb devices for the new serial
137762
- earlyExit: 500
137889
+ earlyExit: 500,
137763
137890
  // createEarlyExitRacer: re-check the crash latch during a blocking adb call
137891
+ serialGone: 500
137892
+ // awaitEmulatorsGone: re-scan adb devices for a killed emulator
137764
137893
  };
137894
+ var EMULATOR_GONE_BUDGET_MS = 3e4;
137765
137895
  var FRAME_PROBE = "screencap -p 2>/dev/null | wc -c | awk '$1>20000{print 1;exit} {print 0}'";
137766
137896
  async function killEmulatorQuietly(serial, child) {
137767
137897
  if (serial) {
@@ -137841,18 +137971,28 @@ async function findSerialByAvdName(avdName, deadline) {
137841
137971
  }
137842
137972
  return null;
137843
137973
  }
137844
- async function listNewEmulatorSerials(before) {
137974
+ async function listEmulatorSerials() {
137845
137975
  const { stdout } = await runAdb(["devices"], { timeoutMs: 3e3 }).catch(() => ({
137846
137976
  stdout: "",
137847
137977
  stderr: ""
137848
137978
  }));
137849
- const lines = stdout.split("\n");
137850
137979
  const now = [];
137851
- for (const line of lines) {
137980
+ for (const line of stdout.split("\n")) {
137852
137981
  const m = line.match(/^(emulator-\d+)\s+/);
137853
137982
  if (m) now.push(m[1]);
137854
137983
  }
137855
- return now.filter((s) => !before.has(s));
137984
+ return now;
137985
+ }
137986
+ async function listNewEmulatorSerials(before) {
137987
+ return (await listEmulatorSerials()).filter((s) => !before.has(s));
137988
+ }
137989
+ async function awaitEmulatorsGone(serials) {
137990
+ const deadline = Date.now() + EMULATOR_GONE_BUDGET_MS;
137991
+ while (serials.length > 0 && Date.now() < deadline) {
137992
+ const listed = await listEmulatorSerials();
137993
+ if (!serials.some((s) => listed.includes(s))) return;
137994
+ await new Promise((r) => setTimeout(r, BOOT_POLL_INTERVALS_MS.serialGone));
137995
+ }
137856
137996
  }
137857
137997
  async function bootIos(udid, registry2, force, headless) {
137858
137998
  if (process.platform !== "darwin") {
@@ -138152,7 +138292,10 @@ async function bootAndroidImpl(params) {
138152
138292
  await ensureDep("adb");
138153
138293
  await ensureDep("emulator");
138154
138294
  const gpuMode = selectGpuMode();
138155
- const extraEmulatorArgs = androidHeadlessFromEnv() ? ["-no-window"] : [];
138295
+ const extraEmulatorArgs = [
138296
+ ...androidHeadlessFromEnv() ? ["-no-window"] : [],
138297
+ ...guestVulkanArgs(params.guestVulkan)
138298
+ ];
138156
138299
  const hardeningArgs = launchHardeningArgs(params.sound);
138157
138300
  for (const msg of linuxBootDiagnostics(params.avdName) ?? []) {
138158
138301
  console.warn(`[boot-device:linux] ${msg}`);
@@ -138201,26 +138344,31 @@ async function bootAndroidImpl(params) {
138201
138344
  });
138202
138345
  const existingDevices = await listAndroidDevices().catch(() => []);
138203
138346
  let hotBootFailureReason;
138347
+ const dropKilledEmulator = async (serial) => {
138348
+ await awaitEmulatorsGone([serial]);
138349
+ const refreshed = await listAndroidDevices().catch(() => existingDevices);
138350
+ existingDevices.splice(0, existingDevices.length, ...refreshed);
138351
+ };
138204
138352
  const alreadyRunning = existingDevices.find(
138205
138353
  (d) => d.isEmulator && d.avdName === params.avdName && d.state === "device"
138206
138354
  );
138207
138355
  if (alreadyRunning) {
138208
138356
  if (params.force) {
138209
138357
  await killEmulatorQuietly(alreadyRunning.serial);
138210
- const refreshed = await listAndroidDevices().catch(() => existingDevices);
138211
- existingDevices.splice(0, existingDevices.length, ...refreshed);
138358
+ await dropKilledEmulator(alreadyRunning.serial);
138212
138359
  } else {
138213
138360
  try {
138214
138361
  await assertScreencapAlive(alreadyRunning.serial);
138362
+ const note = await runningGuestVulkanNote(alreadyRunning.serial, params.guestVulkan);
138215
138363
  return {
138216
138364
  platform: "android",
138217
138365
  serial: alreadyRunning.serial,
138218
138366
  avdName: params.avdName,
138219
- booted: true
138367
+ booted: true,
138368
+ ...note ? { note } : {}
138220
138369
  };
138221
138370
  } catch (_err) {
138222
- const refreshed = await listAndroidDevices().catch(() => existingDevices);
138223
- existingDevices.splice(0, existingDevices.length, ...refreshed);
138371
+ await dropKilledEmulator(alreadyRunning.serial);
138224
138372
  }
138225
138373
  }
138226
138374
  }
@@ -138273,6 +138421,7 @@ async function bootAndroidImpl(params) {
138273
138421
  };
138274
138422
  } catch (err) {
138275
138423
  hotBootFailureReason = err instanceof Error ? err.message : String(err);
138424
+ await awaitEmulatorsGone(await listNewEmulatorSerials(serialsBefore));
138276
138425
  const refreshed = new Set(
138277
138426
  (await listAndroidDevices().catch(() => [])).map((d) => d.serial)
138278
138427
  );
@@ -138838,7 +138987,7 @@ function createBootDeviceTool(registry2) {
138838
138987
  description: `Start an iOS simulator, launch an Android emulator, start a Vega (Fire TV) Virtual Device, <flag:harmonyos>start a HarmonyOS emulator, </flag:harmonyos>or spawn an Electron app and wait until it is ready to accept interactions.
138839
138988
  Pick the platform by which argument you pass: 'udid' for an iOS simulator from list-devices, 'avdName' for an Android AVD (a serial is assigned automatically), 'vvdImage' for a Vega VVD (the 'vvdImage' of a vega device from list-devices, e.g. 'tv'), <flag:harmonyos>'harmonyInstance' for a HarmonyOS emulator instance (the 'name' of a harmony device from list-devices), </flag:harmonyos>or 'electronAppPath' for an Electron app (a CDP remote-debugging port is picked automatically, or pass 'electronPort' to fix one).
138840
138989
  Use at the start of a session once you have picked a target.
138841
- Returns a tagged payload: { platform: 'ios', udid, booted } or { platform: 'android', serial, avdName, booted } or { platform: 'vega', serial, vvdImage, booted } or <flag:harmonyos>{ platform: 'harmony', udid, instanceName, booted, note? } or </flag:harmonyos>{ platform: 'chromium', id, port, pid, booted } (an Electron app boots as a Chromium/CDP device).
138990
+ Returns a tagged payload: { platform: 'ios', udid, booted } or { platform: 'android', serial, avdName, booted, note? } or { platform: 'vega', serial, vvdImage, booted } or <flag:harmonyos>{ platform: 'harmony', udid, instanceName, booted, note? } or </flag:harmonyos>{ platform: 'chromium', id, port, pid, booted } (an Electron app boots as a Chromium/CDP device).
138842
138991
  Android boots take 2\u201310 minutes depending on machine and cold/warm state; the tool transparently hot-boots from the AVD's default_boot snapshot when usable and falls back to cold boot otherwise. Vega starts the single SDK-managed VVD via the vega CLI (~10s) and returns once it reports running. If an Android/Electron boot stage fails, the tool terminates the device it spawned so the next retry starts clean.<flag:harmonyos>
138843
138992
  HarmonyOS hands the instance to DevEco Studio's Emulator manager, then waits for it to register with 'hdc' and returns its connect key as 'udid', the id the interaction tools drive. The manager itself reports no readiness signal and never names a port, so an instance that is already running is left alone unless you pass 'force: true'; when the key could not be resolved the payload names the instance instead, and a 'note' is present whenever the boot left something unproven: no key and why, or a key that is not yet answering or could not be checked against the instance. Huawei serves the emulator images only within mainland China, so a host outside it usually has no instance to start; one that already has an image is started like any other.</flag:harmonyos>`,
138844
138993
  alwaysLoad: true,
@@ -138901,7 +139050,8 @@ HarmonyOS hands the instance to DevEco Studio's Emulator manager, then waits for
138901
139050
  // An explicit argument always wins; the `boot-sound` flag only moves
138902
139051
  // the default when the caller left `sound` unset. Read live per call
138903
139052
  // so `argent enable/disable boot-sound` applies without a restart.
138904
- sound: params.sound ?? isFlagEnabled("boot-sound")
139053
+ sound: params.sound ?? isFlagEnabled("boot-sound"),
139054
+ guestVulkan: params.guestVulkan ?? androidGuestVulkanFromEnv()
138905
139055
  });
138906
139056
  }
138907
139057
  if (hasVega) {
@@ -139501,7 +139651,7 @@ Returns { launched, bundleId, note? }. Fails if the app is not installed on the
139501
139651
  For Chromium, the app is already running behind a CDP port; this call simply refreshes the cached viewport and acknowledges the bundleId tag. To change the visible route, use \`open-url\`.
139502
139652
  On Vega (Fire TV), pass the interactive component app id from manifest.toml (e.g. com.example.app.main) as bundleId.
139503
139653
 
139504
- Common iOS bundle ids: com.apple.MobileSMS, com.apple.mobilesafari, com.apple.Preferences, com.apple.Maps, com.apple.camera, com.apple.Photos, com.apple.mobilemail, com.apple.mobilenotes, com.apple.MobileAddressBook
139654
+ Common iOS bundle ids: com.apple.MobileSMS, com.apple.mobilesafari, com.apple.Preferences, com.apple.Maps, com.apple.mobileslideshow (Photos), com.apple.MobileAddressBook
139505
139655
  Common Android packages: com.android.settings, com.android.chrome, com.google.android.apps.maps, com.google.android.gm, com.android.vending, com.google.android.dialer, com.google.android.apps.messaging`,
139506
139656
  alwaysLoad: true,
139507
139657
  searchHint: "open start app bundle id package simulator emulator chromium vega launch tvos apple tv fire tv",
@@ -141514,6 +141664,7 @@ Use when you need a baseline image before an interaction or to inspect the curre
141514
141664
  Fails if the simulator-server / emulator backend / Chromium CDP <flag:harmonyos>/ \`hdc\` </flag:harmonyos>is not reachable for the given device.`,
141515
141665
  alwaysLoad: true,
141516
141666
  searchHint: "device simulator emulator chromium screen image capture baseline tvos apple tv",
141667
+ readOnly: true,
141517
141668
  zodSchema: zodSchema16,
141518
141669
  outputHint: "image",
141519
141670
  capability: capability8,
@@ -150783,6 +150934,7 @@ after a tap/navigation to wait for the next screen, or before tapping an element
150783
150934
  alwaysLoad: true,
150784
150935
  searchHint: "wait await poll until visible hidden exists text appears disappears timeout element condition settle",
150785
150936
  longRunning: true,
150937
+ readOnly: true,
150786
150938
  zodSchema: zodSchema29,
150787
150939
  capability: capability23,
150788
150940
  services: (params) => {
@@ -151214,6 +151366,7 @@ function createDebuggerStatusTool(registry2) {
151214
151366
  Use when you need to verify connectivity before using other debugger tools. Never fails when the runtime is simply unreachable: it returns a discriminated result instead:
151215
151367
  - { status: "connected", ... } with port, projectRoot (empty on Chromium and on legacy Metro, e.g. Vega), deviceName, appName, logicalDeviceId (absent on Vega), isNewDebugger (false on the legacy inspector), connected flag, loadedScripts count, and sourceMapReady (always true: waits for pending source maps before returning; no-op on Chromium).
151216
151368
  - { status: "not_connected", connected: false, reason, detail, guidance } (port omitted on Chromium) when Metro is not running (reason "metro_not_running"), no app is attached ("no_app_connected"), the device_id matches no target ("device_mismatch"), the CDP endpoint is unreachable or answered malformed ("cdp_unreachable"), the runtime accepted the connection but never answered ("runtime_unresponsive"), the cached connection went stale ("stale_connection"), or a reconnect is in flight ("reconnecting"). Follow the guidance field; do not retry in a loop.`,
151369
+ readOnly: true,
151217
151370
  zodSchema: zodSchema32,
151218
151371
  capability: DEBUGGER_TOOL_CAPABILITY,
151219
151372
  // Resolved manually in execute so a not-connected precondition becomes a
@@ -152325,6 +152478,7 @@ Set includeSkipped=true to see a summary of all filtered components.
152325
152478
  Use when you need tap coordinates for a React Native UI element. Returns a compact text tree with (tap: x,y) coords. Fails if Metro debugger is not connected.`,
152326
152479
  alwaysLoad: true,
152327
152480
  searchHint: "react native component tree discovery tap coordinates",
152481
+ readOnly: true,
152328
152482
  zodSchema: zodSchema35,
152329
152483
  // RN-only: needs the React DevTools backend from the dev JS bundle. Chromium has
152330
152484
  // no equivalent — use `describe` there.
@@ -152841,6 +152995,7 @@ Uses getInspectorDataForViewAtPoint + _debugStack + Metro /symbolicate.
152841
152995
  Set resolveSourceMaps to false to skip symbolication and get raw bundled locations instead.
152842
152996
  Set includeSkipped=true to see filtered items annotated with skip reasons.
152843
152997
  Use when you need the source file and line for a component at a tap coordinate. Fails if the app is not connected or the coordinate is outside the screen.`,
152998
+ readOnly: true,
152844
152999
  zodSchema: zodSchema36,
152845
153000
  // RN-only: needs React Native's internal getInspectorDataForViewAtPoint and
152846
153001
  // Metro's /symbolicate; the Chromium session has no source resolver.
@@ -152958,6 +153113,7 @@ function createDebuggerLogRegistryTool(registry2) {
152958
153113
  Returns the log file path, entry counts by level, and message clusters (grouped by similarity). Works against Hermes (iOS / Android / Vega) and V8 (Chromium).
152959
153114
  Use when investigating warnings, errors, or unexpected output. Call this first for an overview, then read the returned file for details. Returns empty stats if no log data has been captured yet, but check { note }, which is present only when the stats are empty BECAUSE the previous debugger session ended: torn down (e.g. by stop-all-simulator-servers) with its log file deleted, or cut off by the app crashing with its log file kept at the path the note names. Absent that note, empty really does mean the app has logged nothing.
152960
153115
  When the debugger cannot be reached, this tool does not fail: it returns { status: "not_connected", reason, detail, guidance } with NO log file. Follow the guidance (do not retry in a loop). Read a log file in this state only when a { note } names one kept from before the app crashed. A "connected" result's stats may come from a session whose socket has since died. Use debugger-status, not this tool, to judge debugger health.`,
153116
+ readOnly: true,
152961
153117
  zodSchema: zodSchema37,
152962
153118
  capability: DEBUGGER_TOOL_CAPABILITY,
152963
153119
  // Resolved manually in execute so a not-connected precondition becomes a
@@ -153137,6 +153293,7 @@ Each entry includes a requestId that can be passed to view-network-request-detai
153137
153293
  On React Native (iOS / Android / Vega) interception is injected into the JS runtime: it records each request once: XMLHttpRequest (axios included), React Native's fetch, Expo's fetch, and a fetch library that sends through React Native's network module itself, such as react-native-fetch-api (found in a Metro development build). Capture starts at the first network-tool call; a reload clears it. On Chromium it reads the browser's native CDP Network domain (the active tab; all request types).
153138
153294
  Use when inspecting outbound HTTP traffic or debugging API calls in the running app.
153139
153295
  Fails if the app is not connected (RN) or the device is not reachable (Chromium).`,
153296
+ readOnly: true,
153140
153297
  zodSchema: zodSchema38,
153141
153298
  capability: DEBUGGER_TOOL_CAPABILITY,
153142
153299
  services: (params) => {
@@ -153254,6 +153411,7 @@ var networkRequestTool = {
153254
153411
  Returns request/response headers (sensitive headers redacted), status, timing, the request body, and optionally the response body.
153255
153412
  Request and response bodies over 1000 chars are cut to 1000 under a "[TRUNCATED: ...]" line that gives the full size; a binary response body is replaced by "[body omitted: binary <mime>, N bytes]". Use when you need headers, body, or timing for a specific request after listing logs.
153256
153413
  Returns an error message string if the requestId is not found: use view-network-logs to get valid requestId values.`,
153414
+ readOnly: true,
153257
153415
  zodSchema: zodSchema39,
153258
153416
  capability: DEBUGGER_TOOL_CAPABILITY,
153259
153417
  services: (params) => {
@@ -153700,6 +153858,7 @@ since a TV UI has no tap coordinates. Move the highlight with \`tv-remote\` (up/
153700
153858
  back/menu/home), then call describe again to confirm where focus landed.`,
153701
153859
  alwaysLoad: true,
153702
153860
  searchHint: "accessibility element tree ui hierarchy tap coordinates ios android chromium vega <flag:harmonyos>harmony harmonyos </flag:harmonyos>dom tv tvos apple tv android tv fire tv focus focusable remote dpad",
153861
+ readOnly: true,
153703
153862
  zodSchema: zodSchema40,
153704
153863
  capability: capability25,
153705
153864
  services: (params) => {
@@ -154200,6 +154359,7 @@ Use when a program needs element ancestry, such as an e2e engine's scoped select
154200
154359
  Returns { schemaVersion, roots, truncated, alertVisible, keyboardVisible, foregroundApp, unsupportedFields }.
154201
154360
  Fails if the iOS ax-service predates the tree command; update argent.`,
154202
154361
  hideFromMcp: true,
154362
+ readOnly: true,
154203
154363
  zodSchema: zodSchema41,
154204
154364
  capability: capability26,
154205
154365
  services: () => ({}),
@@ -154270,6 +154430,7 @@ function createForegroundAppTool(registry2) {
154270
154430
  Returns { bundleId, name, alertVisible }; under a system alert, bundleId is the app it covers.
154271
154431
  A field is unset when it is unknown.`,
154272
154432
  hideFromMcp: true,
154433
+ readOnly: true,
154273
154434
  zodSchema: zodSchema42,
154274
154435
  capability: capability27,
154275
154436
  services: () => ({}),
@@ -154756,6 +154917,7 @@ panel settles instantly on its last frame, and taps land nowhere until it is wok
154756
154917
  </flag:harmonyos>Use after a launch/navigation to wait for the UI to render before screenshotting or tapping.`,
154757
154918
  searchHint: "wait until screen settles idle stable stops changing animation transition rendered ready before screenshot",
154758
154919
  longRunning: true,
154920
+ readOnly: true,
154759
154921
  zodSchema: zodSchema44,
154760
154922
  capability: capability29,
154761
154923
  services: (params) => {
@@ -154839,6 +155001,96 @@ function classifyStaleness({
154839
155001
  };
154840
155002
  }
154841
155003
 
155004
+ // ../tool-server/src/utils/debugger/runtime-device.ts
155005
+ var import_node_crypto12 = require("node:crypto");
155006
+ var import_node_child_process38 = require("node:child_process");
155007
+ var import_node_util30 = require("node:util");
155008
+ init_adb();
155009
+ var execFileAsync30 = (0, import_node_util30.promisify)(import_node_child_process38.execFile);
155010
+ var LOG_READ_TIMEOUT_MS = 5e3;
155011
+ var RETRY_DELAY_MS = 300;
155012
+ async function findRuntimeDevice(cdp) {
155013
+ const marker = `argent-device-probe:${(0, import_node_crypto12.randomUUID)()}`;
155014
+ const logged = await cdp.evaluate(
155015
+ `(function () {
155016
+ if (typeof nativeLoggingHook !== "function") return false;
155017
+ nativeLoggingHook(${JSON.stringify(marker)}, 1);
155018
+ return true;
155019
+ })()`
155020
+ ).catch(() => false);
155021
+ if (logged !== true) return void 0;
155022
+ const checks = [
155023
+ async () => firstFound((await androidSerials()).map((serial) => () => logcatHolds(serial, marker))),
155024
+ async () => firstFound((await bootedSimulators()).map((udid) => () => simulatorLogHolds(udid, marker)))
155025
+ ];
155026
+ for (let attempt = 0; attempt < 2; attempt++) {
155027
+ if (attempt > 0) await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));
155028
+ const found = await firstFound(checks);
155029
+ if (found !== void 0) return found;
155030
+ }
155031
+ return void 0;
155032
+ }
155033
+ function firstFound(checks) {
155034
+ return new Promise((resolve16) => {
155035
+ let left = checks.length;
155036
+ if (left === 0) resolve16(void 0);
155037
+ for (const check3 of checks) {
155038
+ void check3().then((id) => {
155039
+ if (id !== void 0) resolve16(id);
155040
+ else if (--left === 0) resolve16(void 0);
155041
+ });
155042
+ }
155043
+ });
155044
+ }
155045
+ async function androidSerials() {
155046
+ try {
155047
+ const { stdout } = await runAdb(["devices"], { timeoutMs: ADB_DEVICES_TIMEOUT_MS });
155048
+ return parseAdbDevices(stdout).filter((d) => d.state === "device").map((d) => d.serial);
155049
+ } catch {
155050
+ return [];
155051
+ }
155052
+ }
155053
+ async function bootedSimulators() {
155054
+ const simulators = await listIosSimulators();
155055
+ return simulators.filter((s) => s.state === "Booted").map((s) => s.udid);
155056
+ }
155057
+ async function logcatHolds(serial, marker) {
155058
+ try {
155059
+ const { stdout } = await runAdb(
155060
+ ["-s", serial, "logcat", "-d", "-s", "ReactNativeJS", "-e", marker],
155061
+ { timeoutMs: LOG_READ_TIMEOUT_MS }
155062
+ );
155063
+ return stdout.includes(marker) ? serial : void 0;
155064
+ } catch {
155065
+ return void 0;
155066
+ }
155067
+ }
155068
+ async function simulatorLogHolds(udid, marker) {
155069
+ try {
155070
+ const args = await simctlArgsForUdid(udid, [
155071
+ "spawn",
155072
+ udid,
155073
+ "log",
155074
+ "show",
155075
+ "--info",
155076
+ "--last",
155077
+ "1m",
155078
+ "--style",
155079
+ "compact",
155080
+ "--predicate",
155081
+ `eventMessage CONTAINS ${JSON.stringify(marker)} AND process != "log"`
155082
+ ]);
155083
+ const { stdout } = await execFileAsync30("xcrun", args, {
155084
+ timeout: LOG_READ_TIMEOUT_MS,
155085
+ killSignal: SIMCTL_KILL_SIGNAL,
155086
+ encoding: "utf-8"
155087
+ });
155088
+ return stdout.includes(marker) ? udid : void 0;
155089
+ } catch {
155090
+ return void 0;
155091
+ }
155092
+ }
155093
+
154842
155094
  // ../tool-server/src/utils/react-profiler/devtools-bootstrap.ts
154843
155095
  function bootstrapFailureMessage(bootstrap) {
154844
155096
  switch (bootstrap.reason) {
@@ -154861,6 +155113,7 @@ function bootstrapFailureMessage(bootstrap) {
154861
155113
  // ../tool-server/src/tools/profiler/react/react-profiler-start.ts
154862
155114
  var NO_DEVTOOLS_HOOK_ERROR = "React DevTools hook (__REACT_DEVTOOLS_GLOBAL_HOOK__) is not present in this app's JavaScript runtime. React profiling requires a development build with React DevTools enabled. Likely causes: (1) the app is a release/production build \u2014 DevTools is stripped to reduce bundle size; (2) you connected to the wrong JS runtime; (3) this isn't a React (Native) app. Fix: rebuild in debug/dev mode (e.g. `npx react-native run-ios` without --configuration Release; for Expo, run a dev client). Once the app is running with DevTools attached, call react-profiler-start again.";
154863
155115
  var NO_RENDERERS_ATTACHED_ERROR = "React DevTools hook is present but no React renderer has registered yet. The hook is loaded but no fiber renderer has attached \u2014 typically because the app has not committed its first render, or the DevTools backend has not been bootstrapped on a bridgeless React Native dev build. Fix: ensure the app has rendered (interact with it once, then retry); if it stays empty, call react-profiler-start first \u2014 it will attempt to attach the DevTools backend automatically.";
155116
+ var UNKNOWN_DEVICE_NOTE = "Two or more devices share this Metro, and Argent could not tell which of them runs this app. So taps and swipes on that device still return a screenshot and an element tree, and the capture loads the app while the profiler records. To avoid this, run the app on its own Metro port.";
154864
155117
  var zodSchema45 = external_exports.object({
154865
155118
  port: metroPortField,
154866
155119
  device_id: external_exports.string().describe(
@@ -155036,6 +155289,7 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
155036
155289
  await cdp.send("Profiler.stop").catch(ignore);
155037
155290
  api.profilingActive = false;
155038
155291
  }
155292
+ const runtimeDevice = isLogicalKeyedDevice(api.deviceId) ? await findRuntimeDevice(cdp) : void 0;
155039
155293
  const sessionId = crypto6.randomUUID();
155040
155294
  const ownerPayload = {
155041
155295
  sessionId,
@@ -155080,6 +155334,19 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
155080
155334
  }
155081
155335
  );
155082
155336
  }
155337
+ if (api.disposed) {
155338
+ await cdp.evaluate(STOP_FOR_TAKEOVER_SCRIPT).catch(ignore);
155339
+ await cdp.send("Profiler.stop").catch(ignore);
155340
+ throw new FailureError(
155341
+ `The React profiler session for ${api.deviceId} was torn down while the profiler was starting, so nothing is recorded. One tool-server serves every agent using this argent install, so another agent may have run stop-all-simulator-servers. Call react-profiler-start again.`,
155342
+ {
155343
+ error_code: FAILURE_CODES.REACT_PROFILER_SESSION_TORN_DOWN,
155344
+ failure_stage: "react_profiler_start_session_torn_down",
155345
+ failure_area: "tool_server",
155346
+ error_kind: "not_found"
155347
+ }
155348
+ );
155349
+ }
155083
155350
  const startedAtEpochMs = startResult.startedAtEpochMs ?? Date.now();
155084
155351
  clearCachedProfilerPaths(api.port, api.deviceId);
155085
155352
  api.sessionPaths = null;
@@ -155090,11 +155357,14 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
155090
155357
  api.profileStartWallMs = startedAtEpochMs;
155091
155358
  api.sessionId = sessionId;
155092
155359
  api.ownerToolServerPid = process.pid;
155360
+ trackProfilingRun(api.deviceId, api);
155361
+ if (runtimeDevice) trackProfilingRun(runtimeDevice, api);
155093
155362
  return {
155094
155363
  started_at: new Date(startedAtEpochMs).toISOString(),
155095
155364
  startedAtEpochMs,
155096
155365
  hermes_version: api.hermesVersion,
155097
- detected_architecture: api.detectedArchitecture
155366
+ detected_architecture: api.detectedArchitecture,
155367
+ ...isLogicalKeyedDevice(api.deviceId) && !runtimeDevice ? { [RESULT_NOTE_KEY]: UNKNOWN_DEVICE_NOTE } : {}
155098
155368
  };
155099
155369
  }
155100
155370
  };
@@ -155287,7 +155557,7 @@ Fails if no active profiling session exists or the CDP connection was lost durin
155287
155557
  }
155288
155558
  if (!api.profilingActive) {
155289
155559
  throw new FailureError(
155290
- "No active profiling run to stop. The session exists but Hermes CPU sampling was never started \u2014 typically because react-profiler-start failed before reaching the sampler (often on release builds without React DevTools). Check the error react-profiler-start returned, address the underlying cause (rebuild in dev mode, reconnect the debugger, etc.), then call react-profiler-start again.",
155560
+ "No active profiling run to stop. Either the run ended without its data (a JS reload ends it: Metro's `r`, a red-box Reload, debugger-reload-metro), or Hermes CPU sampling was never started \u2014 typically because react-profiler-start failed before reaching the sampler (often on release builds without React DevTools). After a reload, call react-profiler-start again. Otherwise check the error react-profiler-start returned, address the underlying cause (rebuild in dev mode, reconnect the debugger, etc.), then call react-profiler-start again.",
155291
155561
  {
155292
155562
  error_code: FAILURE_CODES.REACT_PROFILER_NO_ACTIVE_SESSION,
155293
155563
  failure_stage: "react_profiler_stop_inactive",
@@ -155493,6 +155763,7 @@ function createReactProfilerStatusTool(registry2) {
155493
155763
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to check React profiler: ${failureSignal2.error_code}`
155494
155764
  },
155495
155765
  description: `Check the state of the React profiler session without side effects. Use after an interruption (debugger disconnect, unexpected error, agent pause) to decide whether to continue with react-profiler-stop, start a new session, or reconnect the debugger. Ownership is verified server-side against this tool-server's in-memory session, so no token-threading is required. Returns { session_status, is_running, current_owner, \u2026 }. If this tool-server process restarted after react-profiler-start, status will report 'taken_over'; use react-profiler-start { force: true } to reclaim.`,
155766
+ readOnly: true,
155496
155767
  zodSchema: zodSchema47,
155497
155768
  // RN-only: companion to react-profiler-start.
155498
155769
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -157295,6 +157566,7 @@ var reactProfilerComponentSourceTool = {
157295
157566
  Call this per-finding after react-profiler-analyze to inspect source before proposing a fix.
157296
157567
  Returns found: false if the component is not found in user-owned code (e.g. lives in node_modules).
157297
157568
  When several files define a component with the same name (e.g. platform variants like List.tsx and List.web.tsx), returns the primary match and lists the rest under otherMatches[] (file/line/col). Check it before assuming the returned file is the one you meant.`,
157569
+ readOnly: true,
157298
157570
  zodSchema: zodSchema49,
157299
157571
  // Declared so the tool catalogue groups this with the other react-profiler-*
157300
157572
  // tools; the HTTP gate itself is a no-op here, as there is no device arg to
@@ -157433,6 +157705,7 @@ Use when you specifically need to investigate JS CPU hotspots that are NOT tied
157433
157705
  Call react-profiler-stop first. Reads directly from the stored cpuProfile.
157434
157706
  Returns a markdown table of the top hotspot functions with self-time, total-time, and location.
157435
157707
  Fails if react-profiler-stop has not been called or no CPU profile is stored.`,
157708
+ readOnly: true,
157436
157709
  zodSchema: zodSchema50,
157437
157710
  // RN-only: reads a Hermes CPU profile; Chromium's V8 sample format differs.
157438
157711
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -157547,6 +157820,7 @@ var reactProfilerRendersTool = {
157547
157820
  Returns a markdown table of the top re-rendering components. No profiling session required; works on a live connected app.
157548
157821
  Use when you want a quick snapshot of render counts without a full profiling session.
157549
157822
  Fails if the React DevTools hook is not present in the runtime or the app is not connected.`,
157823
+ readOnly: true,
157550
157824
  zodSchema: zodSchema51,
157551
157825
  // RN-only: queries the React DevTools backend hook on the live runtime.
157552
157826
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -157723,6 +157997,7 @@ var reactProfilerFiberTreeTool = {
157723
157997
  Use when tracing ancestry of a library component or checking for useMemoCache hook (confirms React Compiler is active on a component).
157724
157998
  Returns a nested JSON tree of fiber nodes with name, tag, actualDuration, selfBaseDuration, and children.
157725
157999
  Fails if the React DevTools hook is not present or no fiber roots have been committed yet.`,
158000
+ readOnly: true,
157726
158001
  zodSchema: zodSchema52,
157727
158002
  // RN-only: walks the fiber tree via the React DevTools backend hook.
157728
158003
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -158146,8 +158421,8 @@ var import_util14 = require("util");
158146
158421
  var DEFAULT_EXEC_TIMEOUT_MS = 6e4;
158147
158422
  var DEFAULT_EXEC_MAX_BUFFER = 256 * 1024 * 1024;
158148
158423
  async function execFileAsyncWithTimeout(file2, args, options = {}) {
158149
- const execFileAsync34 = (0, import_util14.promisify)(import_child_process2.execFile);
158150
- const { stdout, stderr } = await execFileAsync34(file2, args, {
158424
+ const execFileAsync35 = (0, import_util14.promisify)(import_child_process2.execFile);
158425
+ const { stdout, stderr } = await execFileAsync35(file2, args, {
158151
158426
  encoding: "utf-8",
158152
158427
  ...options,
158153
158428
  // Applied after ...options so a caller cannot weaken the guards; maxBuffer
@@ -159679,7 +159954,7 @@ var STARTUP_TIMEOUT_MS = 1e4;
159679
159954
  var DETECT_RUNNING_APP_TIMEOUT_MS = 1e4;
159680
159955
  var NOTIFY_REGISTER_TIMEOUT_MS = 2e3;
159681
159956
  var MAX_START_ATTEMPTS = 2;
159682
- var RETRY_DELAY_MS = 1200;
159957
+ var RETRY_DELAY_MS2 = 1200;
159683
159958
  var COLD_START_SIGNATURE = "Cannot find process matching name:";
159684
159959
  var STOP_GRACE_MS = 3e5;
159685
159960
  var STOP_TERM_MS = 5e3;
@@ -160103,10 +160378,10 @@ async function startNativeProfilerIos(api, params) {
160103
160378
  if (!isColdStart) throw err;
160104
160379
  if (attempt >= MAX_START_ATTEMPTS) break;
160105
160380
  process.stderr.write(
160106
- `[native-profiler] xctrace could not find "${appProcess}" on attempt ${attempt}/${MAX_START_ATTEMPTS}; waiting ${RETRY_DELAY_MS} ms for cold-start to settle, then retrying.
160381
+ `[native-profiler] xctrace could not find "${appProcess}" on attempt ${attempt}/${MAX_START_ATTEMPTS}; waiting ${RETRY_DELAY_MS2} ms for cold-start to settle, then retrying.
160107
160382
  `
160108
160383
  );
160109
- await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));
160384
+ await new Promise((r) => setTimeout(r, RETRY_DELAY_MS2));
160110
160385
  }
160111
160386
  }
160112
160387
  const totalMs = Date.now() - startMs;
@@ -161564,12 +161839,16 @@ Fails if no app is running on the device, or the profiler cannot attach to the p
161564
161839
  const api = services.session;
161565
161840
  const device = resolveDevice(params.device_id);
161566
161841
  assertSupported("native-profiler-start", capability30, device);
161842
+ let started;
161567
161843
  if (api.platform === "ios") {
161568
161844
  await ensureDeps(["xcrun"]);
161569
- return startNativeProfilerIos(api, params);
161845
+ started = await startNativeProfilerIos(api, params);
161846
+ } else {
161847
+ await ensureDeps(["adb"]);
161848
+ started = await startNativeProfilerAndroid(api, params);
161570
161849
  }
161571
- await ensureDeps(["adb"]);
161572
- return startNativeProfilerAndroid(api, params);
161850
+ trackProfilingRun(device.id, api);
161851
+ return started;
161573
161852
  }
161574
161853
  };
161575
161854
 
@@ -162196,7 +162475,7 @@ var WATERMARK_PNG_HEIGHT = 277;
162196
162475
  var WATERMARK_PNG_BASE64 = "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";
162197
162476
 
162198
162477
  // ../tool-server/src/tools/screen-recording/watermark.ts
162199
- var execFileAsync30 = (0, import_util15.promisify)(import_child_process6.execFile);
162478
+ var execFileAsync31 = (0, import_util15.promisify)(import_child_process6.execFile);
162200
162479
  var OUTPUT_FPS = 30;
162201
162480
  var FFMPEG_FALLBACK_PATHS = [
162202
162481
  "/opt/homebrew/bin/ffmpeg",
@@ -162213,7 +162492,7 @@ var MASK_DARK_MAX_LUMA = 90;
162213
162492
  var MASK_LIGHT_MIN_LUMA = 165;
162214
162493
  async function resolveBinary(name, fallbacks) {
162215
162494
  try {
162216
- await execFileAsync30("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
162495
+ await execFileAsync31("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
162217
162496
  return name;
162218
162497
  } catch {
162219
162498
  }
@@ -163239,6 +163518,7 @@ Every table states how many samples it covers and how much of that was idle.
163239
163518
  Use when investigating JS CPU hotspots or correlating CPU cost with specific components.
163240
163519
  Returns a markdown table of CPU hotspots, call tree, or per-component CPU breakdown.
163241
163520
  Fails if no CPU profile is stored; run react-profiler-stop first.`,
163521
+ readOnly: true,
163242
163522
  zodSchema: zodSchema58,
163243
163523
  // RN-only: reads Hermes-format CPU profiles; Chromium's V8 sample format differs.
163244
163524
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -163598,6 +163878,7 @@ Modes:
163598
163878
  Use when drilling into specific components or time windows after react-profiler-analyze.
163599
163879
  Returns a markdown table or tree of commit data matching the requested mode.
163600
163880
  Fails if react-profiler-stop has not been called or no commit data is stored.`,
163881
+ readOnly: true,
163601
163882
  zodSchema: zodSchema59,
163602
163883
  // Reads React commit data captured via the React DevTools backend.
163603
163884
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -163987,6 +164268,7 @@ Modes:
163987
164268
  Use when drilling into native hang stacks, thread CPU breakdown, or memory leaks after native-profiler-analyze.
163988
164269
  Returns a markdown report with native call stacks, thread weights, or leak details for the selected mode.
163989
164270
  Fails if native-profiler-analyze has not been run or no parsed trace data is in memory.`,
164271
+ readOnly: true,
163990
164272
  zodSchema: zodSchema60,
163991
164273
  // No chromium entry: it has no native trace capture.
163992
164274
  capability: {
@@ -164074,6 +164356,7 @@ Requires both react-profiler-analyze and native-profiler-analyze to have been ca
164074
164356
  Call this tool when both profilers were run in parallel on the same session.
164075
164357
  Returns a markdown report correlating hangs with React commits, memory leaks, and investigation hints.
164076
164358
  Fails if either react-profiler-analyze or native-profiler-analyze has not been called first.`,
164359
+ readOnly: true,
164077
164360
  zodSchema: zodSchema61,
164078
164361
  // iOS reads xctrace output; Android re-queries the Perfetto .pftrace via
164079
164362
  // loadAndroidCombinedData. Chromium has no native trace capture.
@@ -164901,7 +165184,7 @@ function createStopSimulatorServerTool(registry2) {
164901
165184
  completedMsg: ({ params }) => `Stopped simulator server for ${params.udid}`,
164902
165185
  failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to stop simulator server for ${params.udid}: ${failureSignal2.error_code}`
164903
165186
  },
164904
- description: `Stop the transport session for a specific device (iOS simulator / Android: simulator-server process; physical iOS: the on-device runner; Chromium: CDP WebSocket) and free its resources; on a TV target it also reaps that device's TV-control daemons. Use when you are done interacting with one device but want to keep others running, or to restart a wedged transport. On iOS / Android / TV it deliberately leaves this device's native-devtools, accessibility, profiler and debugger services running - to drain those as well, use stop-all-simulator-servers with \`devices\`. On CHROMIUM that does not hold: the JS-runtime debugger declares the CDP session as a dependency, so stopping the transport cascades to it and its captured console history goes with it - reconnect with debugger-connect afterwards. Returns { stopped, udid }. Fails silently if no session is open for the given id.`,
165187
+ description: `Stop the transport session for a specific device (iOS simulator / Android: simulator-server process; physical iOS: the on-device runner; Chromium: CDP WebSocket) and free its resources; on a TV target it also reaps that device's TV-control daemons. Use to restart a wedged transport, or when the user is done with one device but wants to keep others running - not just because a task on it finished, since the next task on that device would start cold again. On iOS / Android / TV it deliberately leaves this device's native-devtools, accessibility, profiler and debugger services running - to drain those as well, use stop-all-simulator-servers with \`devices\`. On CHROMIUM that does not hold: the JS-runtime debugger declares the CDP session as a dependency, so stopping the transport cascades to it and its captured console history goes with it - reconnect with debugger-connect afterwards. Returns { stopped, udid }. Fails silently if no session is open for the given id.`,
164905
165188
  zodSchema: zodSchema63,
164906
165189
  services: () => ({}),
164907
165190
  async execute(_services, params) {
@@ -164968,7 +165251,7 @@ function createStopAllSimulatorServersTool(registry2) {
164968
165251
  },
164969
165252
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop simulator servers: ${failureSignal2.error_code}`
164970
165253
  },
164971
- description: `Stop the services a device owns - simulator-server processes (iOS + Android), native devtools, the iOS accessibility service, TV-control daemons, Chromium CDP sessions, screen recordings, native profiler sessions, and JS-runtime debugger sessions along with the network inspectors and React profiler sessions that ride on them - freeing their spawned processes, sockets and ports. Call this when your session ends or the user says they are done.
165254
+ description: `Stop the services a device owns - simulator-server processes (iOS + Android), native devtools, the iOS accessibility service, TV-control daemons, Chromium CDP sessions, screen recordings, native profiler sessions, and JS-runtime debugger sessions along with the network inspectors and React profiler sessions that ride on them - freeing their spawned processes, sockets and ports. Call this when the user asks to clean up or ends the session, or when a skill tells you to recycle a device's services mid-flow - not just because a task finished, since the next task reuses these services and would start cold again.
164972
165255
  PASS \`devices\` with the device ids this session used: one tool-server serves every agent, subagent and CLI call using this argent install, and an unscoped call tears down THEIR devices too (a mid-recording devtools teardown degrades another agent's e2e test to brittle coordinate taps; that agent is warned, but its recorded steps are already the worse kind). Omit \`devices\` only when a machine-wide cleanup is what you actually want. Passing an EMPTY array scopes to nothing and stops nothing - it is not a way to ask for the machine-wide sweep.
164973
165256
  A JS-runtime debugger session is keyed by the id you called \`debugger-connect\` with. On a Metro serving two or more devices that id is not a udid or serial - connect refuses those and tells you to re-target with the \`logicalDeviceId\` it returns - so a scope built from \`list-devices\` ids cannot reach that session. Pass any such \`logicalDeviceId\` in \`devices\` ALONGSIDE the device id; { left_running } names the ones you missed.
164974
165257
  Returns { stopped } - the URNs of the services that were actually live and got shut down; an ERROR node is disposed too but never appears there, so an empty \`stopped\` only means nothing was still running. { unmatched } lists supplied ids that own no service here, so a mistyped id - or a device NAME passed where an id was expected - does not read as a clean machine. It is NOT proof the id is wrong: a Vega device is driven through CLI/adb shell-outs, so one you only booted and drove with the remote registers no service and always lands here, as does a real device of any platform this session never started anything on. Present ONLY when \`devices\` was supplied AND at least one id matched nothing - absent on an unscoped call and when every id matched. Stopping the same device twice does not report it unmatched: ownership counts regardless of service state. { left_running } lists the URNs of live debugger sessions (and the network inspectors / React profiler sessions riding on them) whose id no device scope can name - re-call with the id after each URN's \`<namespace>:<port>:\` prefix to reap them. { aborted: true } means the caller cancelled the request part-way, so the rest of the machine was left untouched and neither of the other two fields was computed. Past the schema - which rejects an unknown key outright, so the \`udids\` slip is an error rather than a silent machine-wide sweep - the call always succeeds; reaping nothing is a result, not a failure.`,
@@ -165020,7 +165303,7 @@ Returns { stopped } - the URNs of the services that were actually live and got s
165020
165303
 
165021
165304
  // ../tool-server/src/tools/simulator/stop-metro.ts
165022
165305
  init_zod();
165023
- var import_node_child_process38 = require("node:child_process");
165306
+ var import_node_child_process39 = require("node:child_process");
165024
165307
  function parseNetstatListeningPids(netstatOutput, port) {
165025
165308
  const pids = /* @__PURE__ */ new Set();
165026
165309
  for (const line of netstatOutput.split(/\r?\n/)) {
@@ -165036,7 +165319,7 @@ function parseNetstatListeningPids(netstatOutput, port) {
165036
165319
  }
165037
165320
  function listeningPids(port) {
165038
165321
  if (process.platform === "win32") {
165039
- const output3 = (0, import_node_child_process38.execFileSync)("netstat", ["-ano"], {
165322
+ const output3 = (0, import_node_child_process39.execFileSync)("netstat", ["-ano"], {
165040
165323
  encoding: "utf-8",
165041
165324
  timeout: 5e3,
165042
165325
  // `netstat -ano` dumps every socket on the host; overflowing Node's
@@ -165045,7 +165328,7 @@ function listeningPids(port) {
165045
165328
  });
165046
165329
  return parseNetstatListeningPids(output3, port);
165047
165330
  }
165048
- const output2 = (0, import_node_child_process38.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
165331
+ const output2 = (0, import_node_child_process39.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
165049
165332
  encoding: "utf-8",
165050
165333
  timeout: 5e3
165051
165334
  }).trim();
@@ -165062,7 +165345,7 @@ var stopMetroTool = {
165062
165345
  completedMsg: ({ params }) => `Stopped Metro on port ${params.port}`,
165063
165346
  failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to stop Metro on port ${params.port}: ${failureSignal2.error_code}`
165064
165347
  },
165065
- description: `Stop the Metro bundler process listening on a given port (default 8081). Use when ending a React Native session or when Metro must be restarted. Returns { stopped, port, pids }; stopped=false if no process is found on the port. Fails if the port lookup command times out or the process cannot be killed. This is DESTRUCTIVE: always ask the user for confirmation before calling this tool.`,
165348
+ description: `Stop the Metro bundler process listening on a given port (default 8081). Use when the user asks to stop Metro or when Metro must be restarted - do not offer it when a task wraps up, since the next task would wait on a cold Metro start. Returns { stopped, port, pids }; stopped=false if no process is found on the port. Fails if the port lookup command times out or the process cannot be killed. This is DESTRUCTIVE: always ask the user for confirmation before calling this tool.`,
165066
165349
  zodSchema: zodSchema65,
165067
165350
  services: () => ({}),
165068
165351
  async execute(_services, params) {
@@ -170802,7 +171085,7 @@ var import_node_url4 = require("node:url");
170802
171085
  init_src2();
170803
171086
 
170804
171087
  // ../tool-server/src/tools/flows/script/flow-script-executor.ts
170805
- var import_node_child_process39 = require("node:child_process");
171088
+ var import_node_child_process40 = require("node:child_process");
170806
171089
  var fs59 = __toESM(require("node:fs"));
170807
171090
  var os17 = __toESM(require("node:os"));
170808
171091
  var path45 = __toESM(require("node:path"));
@@ -171187,7 +171470,7 @@ var FlowScriptExecutor = class {
171187
171470
  detached: process.platform !== "win32",
171188
171471
  windowsHide: process.platform === "win32"
171189
171472
  };
171190
- child = (0, import_node_child_process39.fork)(scriptPath, [], forkOptions);
171473
+ child = (0, import_node_child_process40.fork)(scriptPath, [], forkOptions);
171191
171474
  } catch (err) {
171192
171475
  return emptyResult(
171193
171476
  { kind: "spawn", message: `Could not start the script process: ${errorMessage(err)}` },
@@ -171631,7 +171914,7 @@ async function stopProcessTree(child, graceMs) {
171631
171914
  if (process.platform === "win32") {
171632
171915
  if (hasExited(child)) return;
171633
171916
  tryKill(() => {
171634
- const killer = (0, import_node_child_process39.spawn)("taskkill", ["/pid", String(pid), "/t", "/f"], {
171917
+ const killer = (0, import_node_child_process40.spawn)("taskkill", ["/pid", String(pid), "/t", "/f"], {
171635
171918
  windowsHide: true,
171636
171919
  stdio: "ignore"
171637
171920
  });
@@ -172337,7 +172620,7 @@ init_src2();
172337
172620
  init_device_info();
172338
172621
 
172339
172622
  // ../tool-server/src/tools/flows/flow-visual.ts
172340
- var import_node_crypto12 = require("node:crypto");
172623
+ var import_node_crypto13 = require("node:crypto");
172341
172624
  var fs63 = __toESM(require("node:fs/promises"));
172342
172625
  var os18 = __toESM(require("node:os"));
172343
172626
  var path48 = __toESM(require("node:path"));
@@ -172353,7 +172636,7 @@ init_src2();
172353
172636
  // ../tool-server/src/tools/screenshot-diff/screenshot-diff-ocr.ts
172354
172637
  var import_child_process8 = require("child_process");
172355
172638
  var import_util16 = require("util");
172356
- var execFileAsync31 = (0, import_util16.promisify)(import_child_process8.execFile);
172639
+ var execFileAsync32 = (0, import_util16.promisify)(import_child_process8.execFile);
172357
172640
  var OCR_TIMEOUT_MS = 1e4;
172358
172641
  var OCR_MAX_BUFFER_BYTES = 32 * 1024 * 1024;
172359
172642
  var TESSERACT_BINARY = "tesseract";
@@ -172398,7 +172681,7 @@ async function extractOcrTextBlocks(imagePath) {
172398
172681
  }
172399
172682
  }
172400
172683
  async function recognizeTsv(imagePath) {
172401
- const { stdout } = await execFileAsync31(
172684
+ const { stdout } = await execFileAsync32(
172402
172685
  TESSERACT_BINARY,
172403
172686
  [
172404
172687
  imagePath,
@@ -174508,7 +174791,7 @@ async function runSnapshot(env, opts) {
174508
174791
  });
174509
174792
  const captureWarned = shot.warning !== void 0 ? { warning: shot.warning } : {};
174510
174793
  const { w, h } = await pngDimensions(shot.image.hostPath);
174511
- const cropSuffix = opts.cropOn === void 0 ? "" : `-crop-${(0, import_node_crypto12.createHash)("sha256").update(cropIdentity(opts.cropOn)).digest("hex").slice(0, 8)}`;
174794
+ const cropSuffix = opts.cropOn === void 0 ? "" : `-crop-${(0, import_node_crypto13.createHash)("sha256").update(cropIdentity(opts.cropOn)).digest("hex").slice(0, 8)}`;
174512
174795
  const snapshotKey = `${opts.name}__${authoringPlatform(env.device.platform)}-${w}x${h}${cropSuffix}`;
174513
174796
  const key2 = `${snapshotKey}.png`;
174514
174797
  const baselinePath = opts.clientFlowPath === void 0 ? path48.join(baselineDir(opts.flowsDir, opts.flowName), key2) : clientBaselinePath(opts.clientFlowPath, opts.flowName, key2);
@@ -174644,7 +174927,7 @@ async function runSnapshot(env, opts) {
174644
174927
  }
174645
174928
  };
174646
174929
  }
174647
- const within = result.mismatchPercentage <= opts.maxMismatch;
174930
+ const within = result.mismatchPercentage <= opts.maxMismatch * (1 + 1e-14);
174648
174931
  const reason2 = `diff ${result.mismatchPercentage.toFixed(2)}% ${within ? "\u2264" : ">"} ${opts.maxMismatch}% (${key2})`;
174649
174932
  if (within) {
174650
174933
  return { status: "pass", reason: reason2, ...captureWarned };
@@ -174680,11 +174963,11 @@ async function runSnapshot(env, opts) {
174680
174963
  }
174681
174964
 
174682
174965
  // ../tool-server/src/utils/status-bar.ts
174683
- var import_node_child_process40 = require("node:child_process");
174684
- var import_node_util30 = require("node:util");
174966
+ var import_node_child_process41 = require("node:child_process");
174967
+ var import_node_util31 = require("node:util");
174685
174968
  init_adb();
174686
174969
  init_device_info();
174687
- var execFileAsync32 = (0, import_node_util30.promisify)(import_node_child_process40.execFile);
174970
+ var execFileAsync33 = (0, import_node_util31.promisify)(import_node_child_process41.execFile);
174688
174971
  var DEMO_BROADCAST = "am broadcast -a com.android.systemui.demo";
174689
174972
  var IOS_STATUS_BAR_OVERRIDE = [
174690
174973
  "override",
@@ -174708,7 +174991,7 @@ async function pinStatusBar(device, signal) {
174708
174991
  if (isIosPhysicalDevice(device)) return false;
174709
174992
  try {
174710
174993
  if (device.platform === "ios") {
174711
- await execFileAsync32(
174994
+ await execFileAsync33(
174712
174995
  "xcrun",
174713
174996
  await simctlArgsForUdid(device.id, ["status_bar", device.id, ...IOS_STATUS_BAR_OVERRIDE])
174714
174997
  );
@@ -174744,7 +175027,7 @@ async function pinStatusBar(device, signal) {
174744
175027
  async function restoreStatusBar(device) {
174745
175028
  try {
174746
175029
  if (device.platform === "ios") {
174747
- await execFileAsync32(
175030
+ await execFileAsync33(
174748
175031
  "xcrun",
174749
175032
  await simctlArgsForUdid(device.id, ["status_bar", device.id, "clear"])
174750
175033
  );
@@ -176328,6 +176611,7 @@ Touches no device: nothing is launched, tapped, dispatched or torn down, and no
176328
176611
  needs booting, so calling this costs nothing but a file read.
176329
176612
  Fails if the e2e test file does not exist.
176330
176613
  Address the e2e test exactly as you will address it in e2e-execute: name or flow_path, one and only one; supplying both or neither is rejected. The name goes in \`name\`, which resolves <project_root>/.argent/e2e/<name>.yaml, else .argent/flows/<name>.yaml.`,
176614
+ readOnly: true,
176331
176615
  zodSchema: zodSchema72,
176332
176616
  fileInputs: fileInputs5,
176333
176617
  services: () => ({}),
@@ -176352,7 +176636,7 @@ init_zod();
176352
176636
  // ../tool-server/src/utils/workspace-reader.ts
176353
176637
  var import_promises19 = require("node:fs/promises");
176354
176638
  var import_node_path29 = require("node:path");
176355
- var import_node_child_process41 = require("node:child_process");
176639
+ var import_node_child_process42 = require("node:child_process");
176356
176640
  var import_dotenv2 = __toESM(require_dist());
176357
176641
  async function exists2(path54) {
176358
176642
  try {
@@ -176396,7 +176680,7 @@ async function listDir(path54) {
176396
176680
  var COMMAND_TIMEOUT_MS = 3e3;
176397
176681
  function runVersionCommand(cmd, args, cwd) {
176398
176682
  return new Promise((resolve16) => {
176399
- const child = (0, import_node_child_process41.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
176683
+ const child = (0, import_node_child_process42.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
176400
176684
  if (err) {
176401
176685
  resolve16(null);
176402
176686
  return;
@@ -176676,6 +176960,7 @@ exploration of anything the snapshot surfaces.
176676
176960
  Use when you need to inspect project configuration without manually reading multiple files.
176677
176961
  Returns partial data if workspacePath does not exist or is not readable; missing items are represented as null or empty collections.
176678
176962
  Fails if the workspacePath is not an absolute path or the directory cannot be accessed.`,
176963
+ readOnly: true,
176679
176964
  zodSchema: zodSchema73,
176680
176965
  fileInputs: fileInputs6,
176681
176966
  services: () => ({}),
@@ -176685,7 +176970,7 @@ Fails if the workspacePath is not an absolute path or the directory cannot be ac
176685
176970
  };
176686
176971
 
176687
176972
  // ../tool-server/src/tools/system/update-argent.ts
176688
- var import_node_child_process42 = require("node:child_process");
176973
+ var import_node_child_process43 = require("node:child_process");
176689
176974
  var fs66 = __toESM(require("node:fs"));
176690
176975
  var path50 = __toESM(require("node:path"));
176691
176976
  init_zod();
@@ -176820,7 +177105,7 @@ var updateArgentTool = {
176820
177105
  if (spawnRoot) updateArgs.push("--project-root", spawnRoot);
176821
177106
  const cmd = cliEntry ? process.execPath : "argent";
176822
177107
  const args = cliEntry ? [cliEntry, ...updateArgs] : updateArgs;
176823
- const child = (0, import_node_child_process42.spawn)(cmd, args, {
177108
+ const child = (0, import_node_child_process43.spawn)(cmd, args, {
176824
177109
  detached: true,
176825
177110
  stdio: "ignore",
176826
177111
  env: { ...process.env, ARGENT_UPDATE_TRIGGER: "mcp_update" }
@@ -176872,7 +177157,7 @@ var dismissUpdateTool = {
176872
177157
  };
176873
177158
 
176874
177159
  // ../tool-server/src/tools/screenshot-diff/index.ts
176875
- var import_node_crypto13 = __toESM(require("node:crypto"));
177160
+ var import_node_crypto14 = __toESM(require("node:crypto"));
176876
177161
  var import_promises20 = __toESM(require("fs/promises"));
176877
177162
  var import_node_os15 = __toESM(require("node:os"));
176878
177163
  var import_path8 = __toESM(require("path"));
@@ -176886,10 +177171,10 @@ var zodSchema76 = external_exports.object({
176886
177171
  udid: external_exports.string().min(1).describe(
176887
177172
  "Target device id from `list-devices` (iOS UDID<flag:harmonyos>, HarmonyOS id,</flag:harmonyos> or Android serial)."
176888
177173
  ),
176889
- captureBaseline: external_exports.coerce.boolean().optional().describe(
177174
+ captureBaseline: external_exports.boolean().optional().describe(
176890
177175
  "Capture the baseline screenshot live at full resolution before diffing. Cannot be combined with captureCurrent."
176891
177176
  ),
176892
- captureCurrent: external_exports.coerce.boolean().optional().describe(
177177
+ captureCurrent: external_exports.boolean().optional().describe(
176893
177178
  "Capture the current screenshot live at full resolution before diffing. Cannot be combined with captureBaseline."
176894
177179
  ),
176895
177180
  rotation: external_exports.enum(["Portrait", "LandscapeLeft", "LandscapeRight", "PortraitUpsideDown"]).optional().describe(
@@ -177019,7 +177304,7 @@ async function resolveOutputDir(params, options) {
177019
177304
  const dir = import_path8.default.join(
177020
177305
  import_node_os15.default.tmpdir(),
177021
177306
  "argent-screenshot-diff",
177022
- import_node_crypto13.default.randomBytes(6).toString("hex")
177307
+ import_node_crypto14.default.randomBytes(6).toString("hex")
177023
177308
  );
177024
177309
  await import_promises20.default.mkdir(dir, { recursive: true });
177025
177310
  return dir;
@@ -177117,7 +177402,7 @@ function requireIosDeviceRunner(services) {
177117
177402
  }
177118
177403
  async function captureIosDeviceLiveInput(params) {
177119
177404
  const png = await captureRunnerScreenshotPng(params.runner, RUNNER_COMMAND_TIMEOUT_MS);
177120
- const suffix = import_node_crypto13.default.randomBytes(4).toString("hex");
177405
+ const suffix = import_node_crypto14.default.randomBytes(4).toString("hex");
177121
177406
  const destination = import_path8.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
177122
177407
  await import_promises20.default.mkdir(params.outputDir, { recursive: true });
177123
177408
  await import_promises20.default.writeFile(destination, png);
@@ -177135,7 +177420,7 @@ async function captureHarmonyLiveInput(params) {
177135
177420
  }
177136
177421
  await ensureDep("hdc");
177137
177422
  const captured = await captureHarmonyScreenshotPng({ connectKey: params.connectKey, scale: 1 });
177138
- const suffix = import_node_crypto13.default.randomBytes(4).toString("hex");
177423
+ const suffix = import_node_crypto14.default.randomBytes(4).toString("hex");
177139
177424
  const destination = import_path8.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
177140
177425
  try {
177141
177426
  await import_promises20.default.mkdir(params.outputDir, { recursive: true });
@@ -177171,7 +177456,7 @@ async function captureLiveInput(params) {
177171
177456
  params.peekFor?.(params.device)
177172
177457
  );
177173
177458
  }
177174
- const suffix = import_node_crypto13.default.randomBytes(4).toString("hex");
177459
+ const suffix = import_node_crypto14.default.randomBytes(4).toString("hex");
177175
177460
  const destination = import_path8.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
177176
177461
  await import_promises20.default.mkdir(params.outputDir, { recursive: true });
177177
177462
  await import_promises20.default.copyFile(capture.path, destination);
@@ -177890,13 +178175,13 @@ function probeArgentToolServer(host, port, timeoutMs = 500) {
177890
178175
 
177891
178176
  // ../tool-server/src/utils/simulator-watcher.ts
177892
178177
  var fs68 = __toESM(require("node:fs"));
177893
- var import_node_child_process43 = require("node:child_process");
177894
- var import_node_util31 = require("node:util");
178178
+ var import_node_child_process44 = require("node:child_process");
178179
+ var import_node_util32 = require("node:util");
177895
178180
  init_external_devices();
177896
- var execFileAsync33 = (0, import_node_util31.promisify)(import_node_child_process43.execFile);
178181
+ var execFileAsync34 = (0, import_node_util32.promisify)(import_node_child_process44.execFile);
177897
178182
  var POLL_INTERVAL_MS2 = 1e4;
177898
178183
  async function getBootedUdidsInSet(deviceSet) {
177899
- const { stdout } = await execFileAsync33("xcrun", [
178184
+ const { stdout } = await execFileAsync34("xcrun", [
177900
178185
  ...simctlPrefix(deviceSet),
177901
178186
  "list",
177902
178187
  "devices",
@@ -178015,7 +178300,7 @@ function startSimulatorWatcher(registry2) {
178015
178300
  }
178016
178301
 
178017
178302
  // ../tool-server/src/utils/preview-window.ts
178018
- var import_node_child_process44 = require("node:child_process");
178303
+ var import_node_child_process45 = require("node:child_process");
178019
178304
  var fs69 = __toESM(require("node:fs"));
178020
178305
  var os20 = __toESM(require("node:os"));
178021
178306
  var path52 = __toESM(require("node:path"));
@@ -178047,10 +178332,10 @@ function ensureLensAppBundle(electronBin) {
178047
178332
  fs69.copyFileSync(path52.join(realContents, "Info.plist"), plist);
178048
178333
  const setPlist = (entry, value) => {
178049
178334
  try {
178050
- (0, import_node_child_process44.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
178335
+ (0, import_node_child_process45.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
178051
178336
  } catch {
178052
178337
  try {
178053
- (0, import_node_child_process44.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
178338
+ (0, import_node_child_process45.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
178054
178339
  } catch {
178055
178340
  }
178056
178341
  }
@@ -178109,7 +178394,7 @@ function createPreviewWindowManager(opts = {}) {
178109
178394
  const wrapperBin = ensureLensAppBundle(electronBin);
178110
178395
  const launchBin = wrapperBin ?? electronBin;
178111
178396
  const launchArgs = wrapperBin ? ["--no-sandbox", mainScript] : [mainScript];
178112
- const next = (0, import_node_child_process44.spawn)(launchBin, launchArgs, {
178397
+ const next = (0, import_node_child_process45.spawn)(launchBin, launchArgs, {
178113
178398
  // Strips ELECTRON_RUN_AS_NODE, which an Electron-based MCP host leaves in
178114
178399
  // our env, so the child boots as a GUI app instead of bare Node.
178115
178400
  env: electronGuiChildEnv({ ARGENT_PREVIEW_URL: url2 }),