@swmansion/argent 0.30.2-next.9 → 0.31.1-next.0

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",
@@ -83678,6 +83679,7 @@ __export(adb_exports, {
83678
83679
  listAndroidDevices: () => listAndroidDevices,
83679
83680
  listAvds: () => listAvds,
83680
83681
  parseAdbDevices: () => parseAdbDevices,
83682
+ readEmulatorConsoleAvdName: () => readEmulatorConsoleAvdName,
83681
83683
  resolveAvdPath: () => resolveAvdPath,
83682
83684
  resolveEmulatorOrThrow: () => resolveEmulatorOrThrow,
83683
83685
  runAdb: () => runAdb,
@@ -83845,6 +83847,21 @@ async function readAvdName(serial) {
83845
83847
  ]);
83846
83848
  return modern.trim() || legacy.trim() || null;
83847
83849
  }
83850
+ async function readEmulatorConsoleAvdName(serial, options = {}) {
83851
+ try {
83852
+ const { stdout } = await runAdb(["-s", serial, "emu", "avd", "name"], {
83853
+ timeoutMs: options.timeoutMs ?? 2e3
83854
+ });
83855
+ const lines = stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
83856
+ const name = lines.find((line) => line !== "OK" && !line.startsWith("KO"));
83857
+ if (name && lines.includes("OK")) return { status: "ok", avdName: name };
83858
+ return { status: "unknown" };
83859
+ } catch (err) {
83860
+ const message = err instanceof Error ? err.message : String(err);
83861
+ if (/Connection refused/i.test(message)) return { status: "unreachable" };
83862
+ return { status: "unknown" };
83863
+ }
83864
+ }
83848
83865
  async function readRuntimeKind(serial) {
83849
83866
  const features = await adbShell(serial, "pm list features", {
83850
83867
  timeoutMs: ENRICH_TIMEOUT_MS
@@ -100944,7 +100961,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
100944
100961
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
100945
100962
  function readCliVersion() {
100946
100963
  if (true) {
100947
- return "0.30.2-next.9";
100964
+ return "0.31.1-next.0";
100948
100965
  }
100949
100966
  return "0.0.0";
100950
100967
  }
@@ -102555,7 +102572,7 @@ var import_node_path8 = __toESM(require("node:path"));
102555
102572
  var import_semver2 = __toESM(require_semver2());
102556
102573
 
102557
102574
  // ../tool-server/package.json
102558
- var version2 = "0.30.1";
102575
+ var version2 = "0.31.0";
102559
102576
 
102560
102577
  // ../tool-server/src/utils/update-checker.ts
102561
102578
  var import_update_core = __toESM(require_dist7());
@@ -122147,19 +122164,23 @@ async function openMoqClient(udid) {
122147
122164
  async function openMoqClientFromInfo(info) {
122148
122165
  await installNodeWebTransport();
122149
122166
  const session = new MoqDeviceSession(await connectMoq(info), { publishPath: PUBLISH_PATH });
122150
- disposeWhenTransportDies(session);
122167
+ let closed = false;
122168
+ disposeWhenTransportDies(session, () => closed = true);
122151
122169
  return {
122152
- sendControl: (payload) => session.sendControl(payload),
122170
+ // The SDK resolves sends on a closed session, reporting undelivered input as sent.
122171
+ sendControl: (payload) => closed ? Promise.reject(new Error("MoQ session is closed")) : session.sendControl(payload),
122153
122172
  async screenshot(opts) {
122154
122173
  return Buffer.from(await session.screenshot({ scale: opts?.scale }));
122155
122174
  },
122156
122175
  async close() {
122176
+ closed = true;
122157
122177
  session.close();
122158
122178
  }
122159
122179
  };
122160
122180
  }
122161
- function disposeWhenTransportDies(session) {
122181
+ function disposeWhenTransportDies(session, onDispose) {
122162
122182
  const dispose = () => {
122183
+ onDispose();
122163
122184
  try {
122164
122185
  session.close();
122165
122186
  } catch {
@@ -122219,6 +122240,52 @@ function settleWithin(p, ms, signal) {
122219
122240
  // ../tool-server/src/utils/simulator-client.ts
122220
122241
  init_external_devices();
122221
122242
 
122243
+ // ../tool-server/src/utils/profiling-devices.ts
122244
+ var runs = /* @__PURE__ */ new Map();
122245
+ var servers = /* @__PURE__ */ new Map();
122246
+ function trackProfilingRun(deviceId, run2) {
122247
+ let set2 = runs.get(deviceId);
122248
+ if (!set2) {
122249
+ set2 = /* @__PURE__ */ new Set();
122250
+ runs.set(deviceId, set2);
122251
+ }
122252
+ set2.add(run2);
122253
+ syncCaptureOnDemand();
122254
+ }
122255
+ function isProfiling(deviceId) {
122256
+ syncCaptureOnDemand();
122257
+ return runs.has(deviceId);
122258
+ }
122259
+ function syncCaptureOnDemand() {
122260
+ for (const [deviceId, set2] of runs) {
122261
+ for (const run2 of set2) {
122262
+ if (!run2.profilingActive) set2.delete(run2);
122263
+ }
122264
+ if (set2.size === 0) runs.delete(deviceId);
122265
+ }
122266
+ for (const [deviceId, server] of servers) {
122267
+ const profiling = runs.has(deviceId);
122268
+ if (server.onDemand !== profiling) {
122269
+ server.onDemand = profiling;
122270
+ server.send(profiling);
122271
+ }
122272
+ }
122273
+ }
122274
+ function registerCaptureOnDemandSender(deviceId, endpoint, send) {
122275
+ const entry = { endpoint, send, onDemand: false };
122276
+ servers.set(deviceId, entry);
122277
+ syncCaptureOnDemand();
122278
+ return () => {
122279
+ if (servers.get(deviceId) !== entry) return;
122280
+ servers.delete(deviceId);
122281
+ if (entry.onDemand) entry.send(false);
122282
+ };
122283
+ }
122284
+ function captureOnDemandDropped(deviceId, endpoint) {
122285
+ const server = servers.get(deviceId);
122286
+ if (server?.endpoint === endpoint) server.onDemand = false;
122287
+ }
122288
+
122222
122289
  // ../tool-server/src/utils/foldable.ts
122223
122290
  var import_node_child_process13 = require("node:child_process");
122224
122291
  var fs17 = __toESM(require("node:fs"));
@@ -122461,6 +122528,14 @@ var FIRST_FRAME_POLL_MS = 250;
122461
122528
  var COMMAND_ACK_TIMEOUT_MS = 5e3;
122462
122529
  var connections = /* @__PURE__ */ new Map();
122463
122530
  var cmdId = 0;
122531
+ function pendingIdNamedBy(conn, message) {
122532
+ const named = message?.match(/unknown variant `([^`]+)`/)?.[1];
122533
+ if (named === void 0) return void 0;
122534
+ for (const [id, entry] of conn.pending) {
122535
+ if (entry.cmd === named) return id;
122536
+ }
122537
+ return void 0;
122538
+ }
122464
122539
  function failAllPending(conn, makeError) {
122465
122540
  const entries = [...conn.pending.values()];
122466
122541
  conn.pending.clear();
@@ -122507,7 +122582,7 @@ function getOrCreateConnection(api) {
122507
122582
  }
122508
122583
  if (ack.status !== "ok" && ack.status !== "error") return;
122509
122584
  if (ack.id != null && !conn.pending.has(ack.id)) return;
122510
- const id = ack.id ?? conn.pending.keys().next().value;
122585
+ const id = ack.id ?? pendingIdNamedBy(conn, ack.message) ?? conn.pending.keys().next().value;
122511
122586
  if (id == null) return;
122512
122587
  const entry = conn.pending.get(id);
122513
122588
  if (entry == null) return;
@@ -122536,6 +122611,7 @@ function getOrCreateConnection(api) {
122536
122611
  ws.on("close", () => {
122537
122612
  connections.delete(key2);
122538
122613
  failAllPending(conn, (cmd) => transportError(cmd, key2, "the connection closed"));
122614
+ if (api.deviceId) captureOnDemandDropped(api.deviceId, key2);
122539
122615
  });
122540
122616
  connections.set(key2, conn);
122541
122617
  return conn;
@@ -123211,6 +123287,19 @@ async function spawnSimulatorServerProcess(udid, subcommand) {
123211
123287
  }, READY_TIMEOUT_MS);
123212
123288
  });
123213
123289
  }
123290
+ function withCaptureOnDemand(deviceId, instance) {
123291
+ const unregister = registerCaptureOnDemandSender(deviceId, instance.api.apiUrl, (enabled) => {
123292
+ sendCommand(instance.api, { cmd: "capture_on_demand", enabled }).catch(() => {
123293
+ });
123294
+ });
123295
+ return {
123296
+ ...instance,
123297
+ dispose: async () => {
123298
+ unregister();
123299
+ await instance.dispose();
123300
+ }
123301
+ };
123302
+ }
123214
123303
  var simulatorServerBlueprint = {
123215
123304
  namespace: SIMULATOR_SERVER_NAMESPACE,
123216
123305
  getURN(device) {
@@ -123255,7 +123344,7 @@ var simulatorServerBlueprint = {
123255
123344
  }
123256
123345
  const claim2 = externalClaimForAnyId(device.id);
123257
123346
  if (claim2) {
123258
- return buildAttachedInstance(device, claim2);
123347
+ return withCaptureOnDemand(device.id, await buildAttachedInstance(device, claim2));
123259
123348
  }
123260
123349
  if (device.platform === "ios-remote") {
123261
123350
  return buildRemoteInstance(device);
@@ -123313,7 +123402,7 @@ var simulatorServerBlueprint = {
123313
123402
  events
123314
123403
  };
123315
123404
  await attachFoldableDisplay(instance.api, device);
123316
- return instance;
123405
+ return withCaptureOnDemand(device.id, instance);
123317
123406
  }
123318
123407
  };
123319
123408
 
@@ -125977,6 +126066,7 @@ Chromium apps are discovered by probing CDP debugging ports (default 9222; exten
125977
126066
  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
126067
  alwaysLoad: true,
125979
126068
  searchHint: "list devices simulators emulators avd serial udid ios android chromium vega <flag:harmonyos>harmony harmonyos </flag:harmonyos>app fire tv session start",
126069
+ readOnly: true,
125980
126070
  zodSchema,
125981
126071
  services: () => ({}),
125982
126072
  async execute(_services, _params) {
@@ -130727,6 +130817,7 @@ function createHttpApp(registry2, options) {
130727
130817
  if (def.searchHint) entry.searchHint = renderFlagGated(def.searchHint, isFlagEnabled);
130728
130818
  if (def.longRunning) entry.longRunning = true;
130729
130819
  if (def.hideFromMcp) entry.hideFromMcp = true;
130820
+ if (def.readOnly) entry.readOnly = true;
130730
130821
  const aliases = (def.aliases ?? []).map((alias) => ({
130731
130822
  ...entry,
130732
130823
  name: alias,
@@ -130974,11 +131065,12 @@ function createHttpApp(registry2, options) {
130974
131065
  const toolNote = takeToolNote(data);
130975
131066
  if (toolNote) notes.push(toolNote);
130976
131067
  const notePayload = notes.length > 0 ? { note: notes.join("\n\n") } : {};
131068
+ const profilingPayload = deviceArg && isProfiling(canonicalDeviceId(deviceArg) ?? deviceArg) ? { profiling: true } : {};
130977
131069
  if (wantsStream) {
130978
- writeLine({ event: "result", data, ...notePayload });
131070
+ writeLine({ event: "result", data, ...notePayload, ...profilingPayload });
130979
131071
  res.end();
130980
131072
  } else {
130981
- res.json({ data, ...notePayload });
131073
+ res.json({ data, ...notePayload, ...profilingPayload });
130982
131074
  }
130983
131075
  } catch (err) {
130984
131076
  const attribute = (message) => {
@@ -133830,6 +133922,7 @@ If state is connecting: do NOT restart the app. Launching it is what starts the
133830
133922
  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
133923
  Returns { status: "init_failed", message, attempts } instead when the simulator's native-devtools environment failed to initialize.
133832
133924
  Fails if the simulator server is not running for the given UDID.`,
133925
+ readOnly: true,
133833
133926
  zodSchema: zodSchema2,
133834
133927
  services: (params) => ({
133835
133928
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -133987,6 +134080,7 @@ Returns { status: "ok", matches } with matching views including their frames, pr
133987
134080
  At least one of className, identifier, label, tag, or nativeID must be provided.
133988
134081
  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
134082
  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.`,
134083
+ readOnly: true,
133990
134084
  zodSchema: zodSchema4,
133991
134085
  services: (params) => ({
133992
134086
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -134057,6 +134151,7 @@ Use when you need deep layout debugging, finding views with no accessibility lab
134057
134151
  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
134152
  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
134153
  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.`,
134154
+ readOnly: true,
134060
134155
  zodSchema: zodSchema5,
134061
134156
  services: (params) => ({
134062
134157
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -134126,6 +134221,7 @@ normalized contract.
134126
134221
 
134127
134222
  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
134223
  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.`,
134224
+ readOnly: true,
134129
134225
  zodSchema: zodSchema6,
134130
134226
  services: (params) => ({
134131
134227
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -134208,6 +134304,7 @@ the UI is landscape.
134208
134304
 
134209
134305
  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
134306
  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.`,
134307
+ readOnly: true,
134211
134308
  zodSchema: zodSchema7,
134212
134309
  services: (params) => ({
134213
134310
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -134296,6 +134393,7 @@ the UI is landscape.
134296
134393
 
134297
134394
  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
134395
  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.`,
134396
+ readOnly: true,
134299
134397
  zodSchema: zodSchema8,
134300
134398
  services: (params) => ({
134301
134399
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -136753,6 +136851,7 @@ var reactProfilerSessionBlueprint = {
136753
136851
  profileStartWallMs: null,
136754
136852
  sessionId: null,
136755
136853
  ownerToolServerPid: null,
136854
+ disposed: false,
136756
136855
  disposeSession: () => events.emit("terminated")
136757
136856
  };
136758
136857
  await cdp.send("Profiler.enable").catch(warnOnError("Profiler.enable"));
@@ -136815,11 +136914,25 @@ var reactProfilerSessionBlueprint = {
136815
136914
  );
136816
136915
  };
136817
136916
  cdp.events.on("disconnected", onDisconnected);
136917
+ const onCdpEvent = (method) => {
136918
+ if (method !== "Runtime.executionContextDestroyed" && method !== "Runtime.executionContextsCleared") {
136919
+ return;
136920
+ }
136921
+ if (state3.profilingActive) {
136922
+ state3.profilingActive = false;
136923
+ clearCachedProfilerPaths(state3.port, state3.deviceId);
136924
+ stopSamplerInNextRuntime(cdp);
136925
+ }
136926
+ events.emit("terminated");
136927
+ };
136928
+ cdp.events.on("event", onCdpEvent);
136818
136929
  return {
136819
136930
  api: state3,
136820
136931
  dispose: async () => {
136932
+ state3.disposed = true;
136821
136933
  cdp.events.off("scriptParsed", onScriptParsed);
136822
136934
  cdp.events.off("disconnected", onDisconnected);
136935
+ cdp.events.off("event", onCdpEvent);
136823
136936
  if (state3.profilingActive) {
136824
136937
  state3.profilingActive = false;
136825
136938
  await cdp.send("Runtime.evaluate", {
@@ -136834,6 +136947,20 @@ var reactProfilerSessionBlueprint = {
136834
136947
  };
136835
136948
  }
136836
136949
  };
136950
+ function stopSamplerInNextRuntime(cdp) {
136951
+ const onEvent = (method) => {
136952
+ if (method !== "Runtime.executionContextCreated") return;
136953
+ disarm();
136954
+ void cdp.send("Profiler.stop").catch(() => {
136955
+ });
136956
+ };
136957
+ const disarm = () => {
136958
+ cdp.events.off("event", onEvent);
136959
+ cdp.events.off("disconnected", disarm);
136960
+ };
136961
+ cdp.events.on("event", onEvent);
136962
+ cdp.events.on("disconnected", disarm);
136963
+ }
136837
136964
  var profilerPathsCache = /* @__PURE__ */ new Map();
136838
136965
  function cacheKey(port, deviceId) {
136839
136966
  return `${port}:${deviceId}`;
@@ -136849,17 +136976,54 @@ function clearCachedProfilerPaths(port, deviceId) {
136849
136976
  }
136850
136977
 
136851
136978
  // ../tool-server/src/tools/devices/boot-device.ts
136852
- var import_node_child_process27 = require("node:child_process");
136979
+ var import_node_child_process28 = require("node:child_process");
136853
136980
  var import_node_fs12 = require("node:fs");
136854
136981
  var import_promises12 = require("node:fs/promises");
136855
136982
  var import_node_os11 = require("node:os");
136856
136983
  var import_node_path17 = require("node:path");
136857
- var import_node_util20 = require("node:util");
136984
+ var import_node_util21 = require("node:util");
136858
136985
  init_zod();
136859
136986
  init_src();
136860
136987
  init_src2();
136861
136988
  init_adb();
136862
136989
 
136990
+ // ../tool-server/src/utils/emulator-process.ts
136991
+ var import_node_child_process26 = require("node:child_process");
136992
+ var import_node_util20 = require("node:util");
136993
+ var execFileAsync20 = (0, import_node_util20.promisify)(import_node_child_process26.execFile);
136994
+ var EMULATOR_PROCESS_RE = /(?:^|\/)(?:qemu-system-[\w-]+|emulator|emulator64-[\w-]+)\s/;
136995
+ function escapeRegExp(value) {
136996
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
136997
+ }
136998
+ function parseEmulatorPidsForAvd(psOutput, avdName) {
136999
+ const avdArg = new RegExp(`(?:^|\\s)-avd\\s+${escapeRegExp(avdName)}(?:\\s|$)`);
137000
+ const pids = [];
137001
+ for (const line of psOutput.split("\n")) {
137002
+ const m = line.match(/^\s*(\d+)\s+(.*)$/);
137003
+ if (!m) continue;
137004
+ const argv = m[2];
137005
+ if (!EMULATOR_PROCESS_RE.test(argv) || !avdArg.test(argv)) continue;
137006
+ pids.push(parseInt(m[1], 10));
137007
+ }
137008
+ return pids;
137009
+ }
137010
+ async function listEmulatorPidsForAvd(avdName) {
137011
+ if (process.platform === "win32") return [];
137012
+ try {
137013
+ const { stdout } = await execFileAsync20(PS_BIN, [...PS_ARGS_WITH_PID], {
137014
+ timeout: 5e3,
137015
+ maxBuffer: 16 * 1024 * 1024
137016
+ });
137017
+ return parseEmulatorPidsForAvd(stdout, avdName);
137018
+ } catch (err) {
137019
+ process.stderr.write(
137020
+ `[emulator-process] ps probe failed; assuming no emulator runs "${avdName}": ${String(err)}
137021
+ `
137022
+ );
137023
+ return [];
137024
+ }
137025
+ }
137026
+
136863
137027
  // ../tool-server/src/utils/linux-preflight.ts
136864
137028
  var fs33 = __toESM(require("node:fs"));
136865
137029
  var import_node_os10 = require("node:os");
@@ -136935,6 +137099,9 @@ function iosHeadlessFromEnv() {
136935
137099
  function androidHeadlessFromEnv() {
136936
137100
  return truthyEnv("ARGENT_EMULATOR_NO_WINDOW");
136937
137101
  }
137102
+ function androidGuestVulkanFromEnv() {
137103
+ return truthyEnv("ARGENT_EMULATOR_GUEST_VULKAN");
137104
+ }
136938
137105
 
136939
137106
  // ../tool-server/src/tools/devices/boot-device.ts
136940
137107
  init_device_info();
@@ -137342,7 +137509,7 @@ async function harmonyDumpLayout(connectKey, localPath, timeoutMs = UITEST_TIMEO
137342
137509
  }
137343
137510
 
137344
137511
  // ../tool-server/src/tools/devices/boot-electron.ts
137345
- var import_node_child_process26 = require("node:child_process");
137512
+ var import_node_child_process27 = require("node:child_process");
137346
137513
  var fs34 = __toESM(require("node:fs"));
137347
137514
  var path29 = __toESM(require("node:path"));
137348
137515
  init_src2();
@@ -137538,7 +137705,7 @@ async function bootElectronApp(options) {
137538
137705
  ];
137539
137706
  let child;
137540
137707
  try {
137541
- child = (0, import_node_child_process26.spawn)(launcher.command, args, {
137708
+ child = (0, import_node_child_process27.spawn)(launcher.command, args, {
137542
137709
  detached: true,
137543
137710
  // stdout is discarded, not piped: nothing reads it, and an unread pipe
137544
137711
  // blocks the child's writes once the OS buffer fills. The
@@ -137664,7 +137831,7 @@ async function bootElectronApp(options) {
137664
137831
  }
137665
137832
 
137666
137833
  // ../tool-server/src/tools/devices/boot-device.ts
137667
- var execFileAsync20 = (0, import_node_util20.promisify)(import_node_child_process27.execFile);
137834
+ var execFileAsync21 = (0, import_node_util21.promisify)(import_node_child_process28.execFile);
137668
137835
  var zodSchema9 = external_exports.object({
137669
137836
  udid: external_exports.string().optional().describe(
137670
137837
  "iOS: simulator UDID to boot (from `list-devices`). Provide exactly one of `udid`, `avdName`, `vvdImage`, <flag:harmonyos>`harmonyInstance`, </flag:harmonyos>or `electronAppPath`."
@@ -137687,6 +137854,9 @@ var zodSchema9 = external_exports.object({
137687
137854
  sound: external_exports.boolean().optional().describe(
137688
137855
  "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
137856
  ),
137857
+ guestVulkan: external_exports.boolean().optional().describe(
137858
+ "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."
137859
+ ),
137690
137860
  headless: external_exports.boolean().optional().describe(
137691
137861
  "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
137862
  ),
@@ -137754,14 +137924,27 @@ function selectGpuMode() {
137754
137924
  }
137755
137925
  return process.platform === "linux" ? "swiftshader" : "auto";
137756
137926
  }
137927
+ function guestVulkanArgs(guestVulkan) {
137928
+ if (process.platform !== "darwin") return [];
137929
+ return ["-feature", guestVulkan ? "Vulkan" : "-Vulkan"];
137930
+ }
137931
+ async function runningGuestVulkanNote(serial, guestVulkan) {
137932
+ if (process.platform !== "darwin") return void 0;
137933
+ const prop = await adbShell(serial, "getprop ro.boot.hardware.vulkan", { timeoutMs: 5e3 }).then((out) => out.trim()).catch(() => null);
137934
+ if (prop === null || prop !== "" === guestVulkan) return void 0;
137935
+ 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.";
137936
+ }
137757
137937
  var BOOT_POLL_INTERVALS_MS = {
137758
137938
  serialByAvd: 1500,
137759
137939
  // findSerialByAvdName: re-scan when >1 new emulator appeared
137760
137940
  adbRegister: 1e3,
137761
137941
  // attemptBoot stage 2: re-scan adb devices for the new serial
137762
- earlyExit: 500
137942
+ earlyExit: 500,
137763
137943
  // createEarlyExitRacer: re-check the crash latch during a blocking adb call
137944
+ serialGone: 500
137945
+ // awaitEmulatorsGone, awaitOwnEmulatorSettled: re-check for a dying emulator
137764
137946
  };
137947
+ var EMULATOR_GONE_BUDGET_MS = 3e4;
137765
137948
  var FRAME_PROBE = "screencap -p 2>/dev/null | wc -c | awk '$1>20000{print 1;exit} {print 0}'";
137766
137949
  async function killEmulatorQuietly(serial, child) {
137767
137950
  if (serial) {
@@ -137841,18 +138024,70 @@ async function findSerialByAvdName(avdName, deadline) {
137841
138024
  }
137842
138025
  return null;
137843
138026
  }
137844
- async function listNewEmulatorSerials(before) {
138027
+ async function listEmulatorSerials() {
137845
138028
  const { stdout } = await runAdb(["devices"], { timeoutMs: 3e3 }).catch(() => ({
137846
138029
  stdout: "",
137847
138030
  stderr: ""
137848
138031
  }));
137849
- const lines = stdout.split("\n");
137850
138032
  const now = [];
137851
- for (const line of lines) {
138033
+ for (const line of stdout.split("\n")) {
137852
138034
  const m = line.match(/^(emulator-\d+)\s+/);
137853
138035
  if (m) now.push(m[1]);
137854
138036
  }
137855
- return now.filter((s) => !before.has(s));
138037
+ return now;
138038
+ }
138039
+ async function listNewEmulatorSerials(before) {
138040
+ return (await listEmulatorSerials()).filter((s) => !before.has(s));
138041
+ }
138042
+ async function awaitEmulatorsGone(serials) {
138043
+ const deadline = Date.now() + EMULATOR_GONE_BUDGET_MS;
138044
+ while (serials.length > 0 && Date.now() < deadline) {
138045
+ const listed = await listEmulatorSerials();
138046
+ if (!serials.some((s) => listed.includes(s))) return;
138047
+ await new Promise((r) => setTimeout(r, BOOT_POLL_INTERVALS_MS.serialGone));
138048
+ }
138049
+ }
138050
+ function isRunningAvd(device, avdName) {
138051
+ return device.isEmulator && device.avdName === avdName && device.state === "device";
138052
+ }
138053
+ async function awaitOwnEmulatorSettled(avdName, deadline) {
138054
+ let healthy = null;
138055
+ let listing = null;
138056
+ while (Date.now() < deadline) {
138057
+ if (healthy) return healthy;
138058
+ if ((await listEmulatorPidsForAvd(avdName)).length === 0) return null;
138059
+ listing ??= listAndroidDevices().then((devices) => {
138060
+ if (devices.some((d) => isRunningAvd(d, avdName))) healthy = devices;
138061
+ }).catch(() => {
138062
+ }).finally(() => {
138063
+ listing = null;
138064
+ });
138065
+ await new Promise(
138066
+ (r) => setTimeout(r, Math.min(BOOT_POLL_INTERVALS_MS.serialGone, deadline - Date.now()))
138067
+ );
138068
+ }
138069
+ return healthy;
138070
+ }
138071
+ async function dropUnreachableSerials(devices, serialsBefore) {
138072
+ await Promise.all(
138073
+ devices.filter((d) => d.isEmulator && !(d.state === "device" && d.avdName !== null)).map(async (d) => {
138074
+ if ((await readEmulatorConsoleAvdName(d.serial)).status === "unreachable") {
138075
+ serialsBefore.delete(d.serial);
138076
+ }
138077
+ })
138078
+ );
138079
+ }
138080
+ async function pickOwnSerial(avdName, newSerials) {
138081
+ const names = await Promise.all(newSerials.map((s) => readEmulatorConsoleAvdName(s)));
138082
+ const own2 = newSerials.find((_, i) => {
138083
+ const answer = names[i];
138084
+ return answer.status === "ok" && answer.avdName === avdName;
138085
+ });
138086
+ if (own2) return own2;
138087
+ const unnamed = newSerials.filter((_, i) => names[i].status !== "ok");
138088
+ if (unnamed.length === 0) return null;
138089
+ if (unnamed.length === 1) return unnamed[0];
138090
+ return findSerialByAvdName(avdName, Date.now() + 3e3);
137856
138091
  }
137857
138092
  async function bootIos(udid, registry2, force, headless) {
137858
138093
  if (process.platform !== "darwin") {
@@ -137873,7 +138108,7 @@ async function bootIos(udid, registry2, force, headless) {
137873
138108
  const deviceSet = await deviceSetForUdid(udid);
137874
138109
  const prefix = simctlPrefix(deviceSet);
137875
138110
  if (force && simState === "Booted") {
137876
- await execFileAsync20("xcrun", [...prefix, "shutdown", udid]);
138111
+ await execFileAsync21("xcrun", [...prefix, "shutdown", udid]);
137877
138112
  }
137878
138113
  const needsPreBoot = simState === "Shutdown" || force && simState === "Booted";
137879
138114
  if (needsPreBoot) {
@@ -137884,13 +138119,13 @@ async function bootIos(udid, registry2, force, headless) {
137884
138119
  );
137885
138120
  });
137886
138121
  }
137887
- await execFileAsync20("xcrun", [...prefix, "boot", udid]).catch((err) => {
138122
+ await execFileAsync21("xcrun", [...prefix, "boot", udid]).catch((err) => {
137888
138123
  const message = err instanceof Error ? err.message : String(err);
137889
138124
  if (!message.includes("Unable to boot device in current state: Booted")) {
137890
138125
  throw err;
137891
138126
  }
137892
138127
  });
137893
- await execFileAsync20("xcrun", [...prefix, "bootstatus", udid, "-b"]);
138128
+ await execFileAsync21("xcrun", [...prefix, "bootstatus", udid, "-b"]);
137894
138129
  if (isTvOs && needsPreBoot) {
137895
138130
  await registry2.disposeService(`${TV_CONTROL_NAMESPACE}:${udid}`).catch((err) => {
137896
138131
  if (err instanceof ServiceNotFoundError) return;
@@ -137918,7 +138153,7 @@ async function bootIos(udid, registry2, force, headless) {
137918
138153
  return buildInitFailedResult(udid, initFailure);
137919
138154
  }
137920
138155
  if (!deviceSet) {
137921
- await execFileAsync20("defaults", [
138156
+ await execFileAsync21("defaults", [
137922
138157
  "write",
137923
138158
  "com.apple.iphonesimulator",
137924
138159
  "CurrentDeviceUDID",
@@ -137934,17 +138169,17 @@ async function bootIos(udid, registry2, force, headless) {
137934
138169
  }
137935
138170
  async function openSimulatorWindow(udid) {
137936
138171
  const timeout = 5e3;
137937
- const { stdout } = await execFileAsync20("xcode-select", ["-p"], { timeout });
138172
+ const { stdout } = await execFileAsync21("xcode-select", ["-p"], { timeout });
137938
138173
  const developerDir2 = (0, import_node_fs12.realpathSync)(stdout.trim());
137939
138174
  const simulatorApp = (0, import_node_path17.join)(developerDir2, "Applications", "Simulator.app");
137940
138175
  if ((0, import_node_fs12.existsSync)(simulatorApp)) {
137941
- await execFileAsync20("open", ["-a", simulatorApp], { timeout });
138176
+ await execFileAsync21("open", ["-a", simulatorApp], { timeout });
137942
138177
  return;
137943
138178
  }
137944
138179
  const deviceHubApp = (0, import_node_path17.join)(developerDir2, "..", "Applications", "DeviceHub.app");
137945
138180
  if ((0, import_node_fs12.existsSync)(deviceHubApp)) {
137946
138181
  const url2 = `devices://device/open?id=${encodeURIComponent(udid)}`;
137947
- await execFileAsync20("open", ["-a", deviceHubApp, url2], { timeout });
138182
+ await execFileAsync21("open", ["-a", deviceHubApp, url2], { timeout });
137948
138183
  }
137949
138184
  }
137950
138185
  async function bootIosRemote(id, registry2, force) {
@@ -137989,7 +138224,7 @@ async function attemptBoot(params) {
137989
138224
  emulatorLogFd = (0, import_node_fs12.openSync)(logPath, "w");
137990
138225
  stdio = ["ignore", emulatorLogFd, emulatorLogFd];
137991
138226
  }
137992
- const child = (0, import_node_child_process27.spawn)(params.emulatorBinary, params.emulatorArgs, {
138227
+ const child = (0, import_node_child_process28.spawn)(params.emulatorBinary, params.emulatorArgs, {
137993
138228
  detached: true,
137994
138229
  stdio
137995
138230
  });
@@ -138028,13 +138263,9 @@ async function attemptBoot(params) {
138028
138263
  if (launchError) throw launchError;
138029
138264
  const newSerials = await listNewEmulatorSerials(params.serialsBefore);
138030
138265
  if (newSerials.length >= 1) {
138031
- if (newSerials.length === 1) {
138032
- serial = newSerials[0];
138033
- break;
138034
- }
138035
- const byAvd = await findSerialByAvdName(params.avdName, Date.now() + 3e3);
138036
- if (byAvd) {
138037
- serial = byAvd;
138266
+ const own2 = await pickOwnSerial(params.avdName, newSerials);
138267
+ if (own2) {
138268
+ serial = own2;
138038
138269
  break;
138039
138270
  }
138040
138271
  }
@@ -138152,7 +138383,10 @@ async function bootAndroidImpl(params) {
138152
138383
  await ensureDep("adb");
138153
138384
  await ensureDep("emulator");
138154
138385
  const gpuMode = selectGpuMode();
138155
- const extraEmulatorArgs = androidHeadlessFromEnv() ? ["-no-window"] : [];
138386
+ const extraEmulatorArgs = [
138387
+ ...androidHeadlessFromEnv() ? ["-no-window"] : [],
138388
+ ...guestVulkanArgs(params.guestVulkan)
138389
+ ];
138156
138390
  const hardeningArgs = launchHardeningArgs(params.sound);
138157
138391
  for (const msg of linuxBootDiagnostics(params.avdName) ?? []) {
138158
138392
  console.warn(`[boot-device:linux] ${msg}`);
@@ -138200,31 +138434,42 @@ async function bootAndroidImpl(params) {
138200
138434
  await runAdb(["start-server"], { timeoutMs: 1e4 }).catch(() => {
138201
138435
  });
138202
138436
  const existingDevices = await listAndroidDevices().catch(() => []);
138437
+ if (!existingDevices.some((d) => isRunningAvd(d, params.avdName))) {
138438
+ const settled = await awaitOwnEmulatorSettled(
138439
+ params.avdName,
138440
+ Math.min(overallDeadline, Date.now() + EMULATOR_GONE_BUDGET_MS)
138441
+ );
138442
+ if (settled) existingDevices.splice(0, existingDevices.length, ...settled);
138443
+ }
138203
138444
  let hotBootFailureReason;
138204
- const alreadyRunning = existingDevices.find(
138205
- (d) => d.isEmulator && d.avdName === params.avdName && d.state === "device"
138206
- );
138445
+ const dropKilledEmulator = async (serial) => {
138446
+ await awaitEmulatorsGone([serial]);
138447
+ const refreshed = await listAndroidDevices().catch(() => existingDevices);
138448
+ existingDevices.splice(0, existingDevices.length, ...refreshed);
138449
+ };
138450
+ const alreadyRunning = existingDevices.find((d) => isRunningAvd(d, params.avdName));
138207
138451
  if (alreadyRunning) {
138208
138452
  if (params.force) {
138209
138453
  await killEmulatorQuietly(alreadyRunning.serial);
138210
- const refreshed = await listAndroidDevices().catch(() => existingDevices);
138211
- existingDevices.splice(0, existingDevices.length, ...refreshed);
138454
+ await dropKilledEmulator(alreadyRunning.serial);
138212
138455
  } else {
138213
138456
  try {
138214
138457
  await assertScreencapAlive(alreadyRunning.serial);
138458
+ const note = await runningGuestVulkanNote(alreadyRunning.serial, params.guestVulkan);
138215
138459
  return {
138216
138460
  platform: "android",
138217
138461
  serial: alreadyRunning.serial,
138218
138462
  avdName: params.avdName,
138219
- booted: true
138463
+ booted: true,
138464
+ ...note ? { note } : {}
138220
138465
  };
138221
138466
  } catch (_err) {
138222
- const refreshed = await listAndroidDevices().catch(() => existingDevices);
138223
- existingDevices.splice(0, existingDevices.length, ...refreshed);
138467
+ await dropKilledEmulator(alreadyRunning.serial);
138224
138468
  }
138225
138469
  }
138226
138470
  }
138227
138471
  const serialsBefore = new Set(existingDevices.map((d) => d.serial));
138472
+ await dropUnreachableSerials(existingDevices, serialsBefore);
138228
138473
  const crashReportArgs = await emulatorSupportsFlag("-crash-report-mode") ? ["-crash-report-mode", "never"] : [];
138229
138474
  const hasSnapshot = await hasDefaultBootSnapshot(params.avdName);
138230
138475
  if (!hasSnapshot) {
@@ -138273,6 +138518,7 @@ async function bootAndroidImpl(params) {
138273
138518
  };
138274
138519
  } catch (err) {
138275
138520
  hotBootFailureReason = err instanceof Error ? err.message : String(err);
138521
+ await awaitEmulatorsGone(await listNewEmulatorSerials(serialsBefore));
138276
138522
  const refreshed = new Set(
138277
138523
  (await listAndroidDevices().catch(() => [])).map((d) => d.serial)
138278
138524
  );
@@ -138522,7 +138768,7 @@ async function startHarmonyEmulator(instanceName) {
138522
138768
  } catch {
138523
138769
  logFd = null;
138524
138770
  }
138525
- const child = (0, import_node_child_process27.spawn)(bin, ["-start", instanceName], {
138771
+ const child = (0, import_node_child_process28.spawn)(bin, ["-start", instanceName], {
138526
138772
  detached: true,
138527
138773
  stdio: logFd === null ? "ignore" : ["ignore", logFd, logFd]
138528
138774
  });
@@ -138838,7 +139084,7 @@ function createBootDeviceTool(registry2) {
138838
139084
  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
139085
  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
139086
  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).
139087
+ 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
139088
  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
139089
  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
139090
  alwaysLoad: true,
@@ -138901,7 +139147,8 @@ HarmonyOS hands the instance to DevEco Studio's Emulator manager, then waits for
138901
139147
  // An explicit argument always wins; the `boot-sound` flag only moves
138902
139148
  // the default when the caller left `sound` unset. Read live per call
138903
139149
  // so `argent enable/disable boot-sound` applies without a restart.
138904
- sound: params.sound ?? isFlagEnabled("boot-sound")
139150
+ sound: params.sound ?? isFlagEnabled("boot-sound"),
139151
+ guestVulkan: params.guestVulkan ?? androidGuestVulkanFromEnv()
138905
139152
  });
138906
139153
  }
138907
139154
  if (hasVega) {
@@ -139037,11 +139284,11 @@ var BUNDLE_ID_PATTERN = /^[A-Za-z0-9_][A-Za-z0-9._-]*$/;
139037
139284
  var BUNDLE_ID_MESSAGE = "bundleId may only contain letters, digits, '.', '_' and '-', and may not start with '-' or '.'";
139038
139285
 
139039
139286
  // ../tool-server/src/tools/launch-app/platforms/ios.ts
139040
- var import_node_child_process28 = require("node:child_process");
139041
- var import_node_util21 = require("node:util");
139287
+ var import_node_child_process29 = require("node:child_process");
139288
+ var import_node_util22 = require("node:util");
139042
139289
  init_src2();
139043
139290
  init_external_devices();
139044
- var execFileAsync21 = (0, import_node_util21.promisify)(import_node_child_process28.execFile);
139291
+ var execFileAsync22 = (0, import_node_util22.promisify)(import_node_child_process29.execFile);
139045
139292
  function makeIosImpl(registry2) {
139046
139293
  return {
139047
139294
  requires: ["xcrun"],
@@ -139057,7 +139304,7 @@ function makeIosImpl(registry2) {
139057
139304
  }
139058
139305
  if (params.launchArgs?.length) {
139059
139306
  try {
139060
- await execFileAsync21(
139307
+ await execFileAsync22(
139061
139308
  "xcrun",
139062
139309
  await simctlArgsForUdid(params.udid, ["terminate", params.udid, params.bundleId])
139063
139310
  );
@@ -139065,7 +139312,7 @@ function makeIosImpl(registry2) {
139065
139312
  }
139066
139313
  }
139067
139314
  try {
139068
- await execFileAsync21(
139315
+ await execFileAsync22(
139069
139316
  "xcrun",
139070
139317
  await simctlArgsForUdid(params.udid, [
139071
139318
  "launch",
@@ -139534,11 +139781,11 @@ init_zod();
139534
139781
  init_device_info();
139535
139782
 
139536
139783
  // ../tool-server/src/tools/restart-app/platforms/ios.ts
139537
- var import_node_child_process29 = require("node:child_process");
139538
- var import_node_util22 = require("node:util");
139784
+ var import_node_child_process30 = require("node:child_process");
139785
+ var import_node_util23 = require("node:util");
139539
139786
  init_src2();
139540
139787
  init_external_devices();
139541
- var execFileAsync22 = (0, import_node_util22.promisify)(import_node_child_process29.execFile);
139788
+ var execFileAsync23 = (0, import_node_util23.promisify)(import_node_child_process30.execFile);
139542
139789
  function makeIosImpl2(registry2) {
139543
139790
  return {
139544
139791
  requires: ["xcrun"],
@@ -139554,11 +139801,11 @@ function makeIosImpl2(registry2) {
139554
139801
  if (blocked) return blocked;
139555
139802
  }
139556
139803
  try {
139557
- await execFileAsync22("xcrun", await simctlArgsForUdid(udid, ["terminate", udid, bundleId]));
139804
+ await execFileAsync23("xcrun", await simctlArgsForUdid(udid, ["terminate", udid, bundleId]));
139558
139805
  } catch {
139559
139806
  }
139560
139807
  try {
139561
- await execFileAsync22(
139808
+ await execFileAsync23(
139562
139809
  "xcrun",
139563
139810
  await simctlArgsForUdid(udid, ["launch", udid, bundleId, ...params.launchArgs ?? []])
139564
139811
  );
@@ -139761,11 +140008,11 @@ Returns { restarted, bundleId }. Fails if the app is not installed.`,
139761
140008
  }
139762
140009
 
139763
140010
  // ../tool-server/src/tools/terminate-app/index.ts
139764
- var import_node_child_process30 = require("node:child_process");
139765
- var import_node_util23 = require("node:util");
140011
+ var import_node_child_process31 = require("node:child_process");
140012
+ var import_node_util24 = require("node:util");
139766
140013
  init_zod();
139767
140014
  init_adb();
139768
- var execFileAsync23 = (0, import_node_util23.promisify)(import_node_child_process30.execFile);
140015
+ var execFileAsync24 = (0, import_node_util24.promisify)(import_node_child_process31.execFile);
139769
140016
  var zodSchema12 = external_exports.object({
139770
140017
  udid: external_exports.string().min(1).describe("Target device id from `list-devices`."),
139771
140018
  bundleId: external_exports.string().min(1).regex(BUNDLE_ID_PATTERN, BUNDLE_ID_MESSAGE).describe("App identifier. iOS: bundle id. Android: package name.")
@@ -139808,7 +140055,7 @@ Succeeds when the app is not running or not installed.`,
139808
140055
  requires: ["xcrun"],
139809
140056
  handler: async (_services, { udid, bundleId }) => {
139810
140057
  const args = await simctlArgsForUdid(udid, ["terminate", udid, bundleId]);
139811
- const terminated = await tolerateNotRunning(execFileAsync23("xcrun", args));
140058
+ const terminated = await tolerateNotRunning(execFileAsync24("xcrun", args));
139812
140059
  return { terminated, bundleId };
139813
140060
  }
139814
140061
  },
@@ -139840,16 +140087,16 @@ Succeeds when the app is not running or not installed.`,
139840
140087
  init_zod();
139841
140088
 
139842
140089
  // ../tool-server/src/tools/reinstall-app/platforms/ios.ts
139843
- var import_node_child_process32 = require("node:child_process");
139844
- var import_node_util25 = require("node:util");
140090
+ var import_node_child_process33 = require("node:child_process");
140091
+ var import_node_util26 = require("node:util");
139845
140092
  var import_node_path19 = require("node:path");
139846
140093
  init_src2();
139847
140094
 
139848
140095
  // ../tool-server/src/tools/reinstall-app/validate-app.ts
139849
- var import_node_child_process31 = require("node:child_process");
140096
+ var import_node_child_process32 = require("node:child_process");
139850
140097
  var import_promises14 = require("node:fs/promises");
139851
140098
  var import_node_path18 = require("node:path");
139852
- var import_node_util24 = require("node:util");
140099
+ var import_node_util25 = require("node:util");
139853
140100
  init_capability();
139854
140101
 
139855
140102
  // ../tool-server/src/utils/apk-package.ts
@@ -139948,7 +140195,7 @@ function readStringPool(xml, chunk) {
139948
140195
  }
139949
140196
 
139950
140197
  // ../tool-server/src/tools/reinstall-app/validate-app.ts
139951
- var execFileAsync24 = (0, import_node_util24.promisify)(import_node_child_process31.execFile);
140198
+ var execFileAsync25 = (0, import_node_util25.promisify)(import_node_child_process32.execFile);
139952
140199
  async function requirePath(absolute, kind, what) {
139953
140200
  const info = await (0, import_promises14.stat)(absolute).catch(() => null);
139954
140201
  if (!info) {
@@ -139972,7 +140219,7 @@ async function assertIosAppBundle(absolute, bundleId, { readBundleId = true } =
139972
140219
  );
139973
140220
  }
139974
140221
  if (!readBundleId) return;
139975
- const actual = await execFileAsync24("plutil", [
140222
+ const actual = await execFileAsync25("plutil", [
139976
140223
  "-extract",
139977
140224
  "CFBundleIdentifier",
139978
140225
  "raw",
@@ -140025,7 +140272,7 @@ async function assertHap(absolute, bundleName) {
140025
140272
  }
140026
140273
 
140027
140274
  // ../tool-server/src/tools/reinstall-app/platforms/ios.ts
140028
- var execFileAsync25 = (0, import_node_util25.promisify)(import_node_child_process32.execFile);
140275
+ var execFileAsync26 = (0, import_node_util26.promisify)(import_node_child_process33.execFile);
140029
140276
  var iosImpl = {
140030
140277
  requires: ["xcrun"],
140031
140278
  handler: async (_services, params) => {
@@ -140034,11 +140281,11 @@ var iosImpl = {
140034
140281
  await assertIosAppBundle(absolute, bundleId);
140035
140282
  const { nativeId, prefix } = await simctlTargetForUdid(udid);
140036
140283
  try {
140037
- await execFileAsync25("xcrun", [...prefix, "uninstall", nativeId, bundleId]);
140284
+ await execFileAsync26("xcrun", [...prefix, "uninstall", nativeId, bundleId]);
140038
140285
  } catch {
140039
140286
  }
140040
140287
  try {
140041
- await execFileAsync25("xcrun", [...prefix, "install", nativeId, absolute]);
140288
+ await execFileAsync26("xcrun", [...prefix, "install", nativeId, absolute]);
140042
140289
  } catch (err) {
140043
140290
  throw new FailureError(
140044
140291
  `Failed to install iOS app bundle on ${udid}.`,
@@ -140265,11 +140512,11 @@ var PERMISSION_NAMES = [
140265
140512
  ];
140266
140513
 
140267
140514
  // ../tool-server/src/tools/settings-permissions/platforms/ios.ts
140268
- var import_node_child_process33 = require("node:child_process");
140269
- var import_node_util26 = require("node:util");
140515
+ var import_node_child_process34 = require("node:child_process");
140516
+ var import_node_util27 = require("node:util");
140270
140517
  init_src2();
140271
140518
  init_capability();
140272
- var execFileAsync26 = (0, import_node_util26.promisify)(import_node_child_process33.execFile);
140519
+ var execFileAsync27 = (0, import_node_util27.promisify)(import_node_child_process34.execFile);
140273
140520
  var SIMCTL_ACTION = {
140274
140521
  grant: "grant",
140275
140522
  deny: "revoke",
@@ -140294,7 +140541,7 @@ var NON_TCC_GRANT_NEEDS_INSTALL = /* @__PURE__ */ new Set([
140294
140541
  ]);
140295
140542
  var localBackend = {
140296
140543
  async run(udid, simctlAction, service, bundleId) {
140297
- await execFileAsync26(
140544
+ await execFileAsync27(
140298
140545
  "xcrun",
140299
140546
  await simctlArgsForUdid(udid, ["privacy", udid, simctlAction, service, bundleId]),
140300
140547
  { timeout: 3e4 }
@@ -140302,7 +140549,7 @@ var localBackend = {
140302
140549
  },
140303
140550
  async isInstalled(udid, bundleId) {
140304
140551
  try {
140305
- await execFileAsync26(
140552
+ await execFileAsync27(
140306
140553
  "xcrun",
140307
140554
  await simctlArgsForUdid(udid, ["get_app_container", udid, bundleId]),
140308
140555
  { timeout: 15e3 }
@@ -140586,8 +140833,8 @@ init_zod();
140586
140833
  init_device_info();
140587
140834
 
140588
140835
  // ../tool-server/src/tools/open-url/platforms/ios.ts
140589
- var import_node_child_process34 = require("node:child_process");
140590
- var import_node_util27 = require("node:util");
140836
+ var import_node_child_process35 = require("node:child_process");
140837
+ var import_node_util28 = require("node:util");
140591
140838
  init_src2();
140592
140839
 
140593
140840
  // ../tool-server/src/tools/open-url/deep-link-note.ts
@@ -140597,12 +140844,12 @@ function httpDeepLinkNote(url2) {
140597
140844
  }
140598
140845
 
140599
140846
  // ../tool-server/src/tools/open-url/platforms/ios.ts
140600
- var execFileAsync27 = (0, import_node_util27.promisify)(import_node_child_process34.execFile);
140847
+ var execFileAsync28 = (0, import_node_util28.promisify)(import_node_child_process35.execFile);
140601
140848
  var iosImpl3 = {
140602
140849
  requires: ["xcrun"],
140603
140850
  handler: async (_services, params) => {
140604
140851
  try {
140605
- await execFileAsync27(
140852
+ await execFileAsync28(
140606
140853
  "xcrun",
140607
140854
  await simctlArgsForUdid(params.udid, ["openurl", params.udid, params.url])
140608
140855
  );
@@ -140779,8 +141026,8 @@ Returns { opened, url, note? }. note carries the deep-linking caveat when a web
140779
141026
  };
140780
141027
 
140781
141028
  // ../tool-server/src/tools/screenshot/index.ts
140782
- var import_node_child_process35 = require("node:child_process");
140783
- var import_node_util28 = require("node:util");
141029
+ var import_node_child_process36 = require("node:child_process");
141030
+ var import_node_util29 = require("node:util");
140784
141031
  var os13 = __toESM(require("node:os"));
140785
141032
  var path30 = __toESM(require("node:path"));
140786
141033
  init_zod();
@@ -141405,7 +141652,7 @@ async function captureHarmonyScreenshotPng(opts) {
141405
141652
  // ../tool-server/src/tools/screenshot/index.ts
141406
141653
  init_capability();
141407
141654
  var fs36 = __toESM(require("node:fs/promises"));
141408
- var execFileAsync28 = (0, import_node_util28.promisify)(import_node_child_process35.execFile);
141655
+ var execFileAsync29 = (0, import_node_util29.promisify)(import_node_child_process36.execFile);
141409
141656
  var zodSchema16 = external_exports.object({
141410
141657
  udid: external_exports.string().describe(
141411
141658
  "Target device id from `list-devices` (iOS UDID, Android serial, Apple TV UDID, Vega serial, <flag:harmonyos>HarmonyOS id, </flag:harmonyos>or Chromium id)."
@@ -141447,11 +141694,11 @@ async function tvScreenshot(udid, scale, signal) {
141447
141694
  os13.tmpdir(),
141448
141695
  `argent-tv-screenshot-${udid.slice(0, 8)}-${process.hrtime.bigint()}.png`
141449
141696
  );
141450
- await execFileAsync28("xcrun", await simctlArgsForUdid(udid, ["io", udid, "screenshot", file2]), {
141697
+ await execFileAsync29("xcrun", await simctlArgsForUdid(udid, ["io", udid, "screenshot", file2]), {
141451
141698
  signal
141452
141699
  });
141453
141700
  if (scale === void 0 || scale < 1) {
141454
- await execFileAsync28("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
141701
+ await execFileAsync29("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
141455
141702
  signal
141456
141703
  }).catch(() => {
141457
141704
  });
@@ -141461,7 +141708,7 @@ async function tvScreenshot(udid, scale, signal) {
141461
141708
  async function tvTargetLongSide(file2, scale) {
141462
141709
  let longSide = 3840;
141463
141710
  try {
141464
- const { stdout } = await execFileAsync28("sips", ["-g", "pixelWidth", "-g", "pixelHeight", file2]);
141711
+ const { stdout } = await execFileAsync29("sips", ["-g", "pixelWidth", "-g", "pixelHeight", file2]);
141465
141712
  const width = Number(/pixelWidth:\s*(\d+)/.exec(stdout)?.[1]);
141466
141713
  const height = Number(/pixelHeight:\s*(\d+)/.exec(stdout)?.[1]);
141467
141714
  if (Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0) {
@@ -141496,7 +141743,7 @@ async function downscalePngInPlace(file2, scale, signal) {
141496
141743
  if (scale >= 1) {
141497
141744
  return;
141498
141745
  }
141499
- await execFileAsync28("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
141746
+ await execFileAsync29("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
141500
141747
  signal
141501
141748
  }).catch(() => {
141502
141749
  });
@@ -141514,6 +141761,7 @@ Use when you need a baseline image before an interaction or to inspect the curre
141514
141761
  Fails if the simulator-server / emulator backend / Chromium CDP <flag:harmonyos>/ \`hdc\` </flag:harmonyos>is not reachable for the given device.`,
141515
141762
  alwaysLoad: true,
141516
141763
  searchHint: "device simulator emulator chromium screen image capture baseline tvos apple tv",
141764
+ readOnly: true,
141517
141765
  zodSchema: zodSchema16,
141518
141766
  outputHint: "image",
141519
141767
  capability: capability8,
@@ -143840,13 +144088,13 @@ var shakeZodSchema = external_exports.object({
143840
144088
  });
143841
144089
 
143842
144090
  // ../tool-server/src/tools/shake/platforms/ios.ts
143843
- var import_node_child_process37 = require("node:child_process");
143844
- var import_node_util29 = require("node:util");
144091
+ var import_node_child_process38 = require("node:child_process");
144092
+ var import_node_util30 = require("node:util");
143845
144093
  init_src2();
143846
144094
  init_capability();
143847
144095
 
143848
144096
  // ../tool-server/src/utils/window-shake.ts
143849
- var import_node_child_process36 = require("node:child_process");
144097
+ var import_node_child_process37 = require("node:child_process");
143850
144098
  init_src();
143851
144099
  var MICROINTERACTIONS_FLAG = "microinteractions";
143852
144100
  var AMPLITUDE = 22;
@@ -143953,7 +144201,7 @@ end run
143953
144201
  }
143954
144202
  function runOsascript(script) {
143955
144203
  return new Promise((resolve16, reject) => {
143956
- const child = (0, import_node_child_process36.execFile)(
144204
+ const child = (0, import_node_child_process37.execFile)(
143957
144205
  "/usr/bin/osascript",
143958
144206
  ["-"],
143959
144207
  { timeout: OSASCRIPT_TIMEOUT_MS },
@@ -144046,7 +144294,7 @@ async function prepareHostWindowShake(target) {
144046
144294
  }
144047
144295
 
144048
144296
  // ../tool-server/src/tools/shake/platforms/ios.ts
144049
- var execFileAsync29 = (0, import_node_util29.promisify)(import_node_child_process37.execFile);
144297
+ var execFileAsync30 = (0, import_node_util30.promisify)(import_node_child_process38.execFile);
144050
144298
  var SHAKE_NOTIFICATION = "com.apple.UIKit.SimulatorShake";
144051
144299
  var SHAKE_INTERVAL_MS = 400;
144052
144300
  var sleep11 = (ms) => new Promise((r) => setTimeout(r, ms));
@@ -144088,7 +144336,7 @@ var iosImpl4 = {
144088
144336
  if (i > 0) await sleep11(SHAKE_INTERVAL_MS);
144089
144337
  shaker.begin();
144090
144338
  try {
144091
- await execFileAsync29("xcrun", args, { timeout: 15e3 });
144339
+ await execFileAsync30("xcrun", args, { timeout: 15e3 });
144092
144340
  } catch (err) {
144093
144341
  const error63 = err instanceof Error ? err : new Error(String(err));
144094
144342
  throw shakeFailure(udid, error63.message, error63);
@@ -150783,6 +151031,7 @@ after a tap/navigation to wait for the next screen, or before tapping an element
150783
151031
  alwaysLoad: true,
150784
151032
  searchHint: "wait await poll until visible hidden exists text appears disappears timeout element condition settle",
150785
151033
  longRunning: true,
151034
+ readOnly: true,
150786
151035
  zodSchema: zodSchema29,
150787
151036
  capability: capability23,
150788
151037
  services: (params) => {
@@ -151214,6 +151463,7 @@ function createDebuggerStatusTool(registry2) {
151214
151463
  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
151464
  - { 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
151465
  - { 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.`,
151466
+ readOnly: true,
151217
151467
  zodSchema: zodSchema32,
151218
151468
  capability: DEBUGGER_TOOL_CAPABILITY,
151219
151469
  // Resolved manually in execute so a not-connected precondition becomes a
@@ -152325,6 +152575,7 @@ Set includeSkipped=true to see a summary of all filtered components.
152325
152575
  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
152576
  alwaysLoad: true,
152327
152577
  searchHint: "react native component tree discovery tap coordinates",
152578
+ readOnly: true,
152328
152579
  zodSchema: zodSchema35,
152329
152580
  // RN-only: needs the React DevTools backend from the dev JS bundle. Chromium has
152330
152581
  // no equivalent — use `describe` there.
@@ -152841,6 +153092,7 @@ Uses getInspectorDataForViewAtPoint + _debugStack + Metro /symbolicate.
152841
153092
  Set resolveSourceMaps to false to skip symbolication and get raw bundled locations instead.
152842
153093
  Set includeSkipped=true to see filtered items annotated with skip reasons.
152843
153094
  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.`,
153095
+ readOnly: true,
152844
153096
  zodSchema: zodSchema36,
152845
153097
  // RN-only: needs React Native's internal getInspectorDataForViewAtPoint and
152846
153098
  // Metro's /symbolicate; the Chromium session has no source resolver.
@@ -152958,6 +153210,7 @@ function createDebuggerLogRegistryTool(registry2) {
152958
153210
  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
153211
  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
153212
  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.`,
153213
+ readOnly: true,
152961
153214
  zodSchema: zodSchema37,
152962
153215
  capability: DEBUGGER_TOOL_CAPABILITY,
152963
153216
  // Resolved manually in execute so a not-connected precondition becomes a
@@ -153137,6 +153390,7 @@ Each entry includes a requestId that can be passed to view-network-request-detai
153137
153390
  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
153391
  Use when inspecting outbound HTTP traffic or debugging API calls in the running app.
153139
153392
  Fails if the app is not connected (RN) or the device is not reachable (Chromium).`,
153393
+ readOnly: true,
153140
153394
  zodSchema: zodSchema38,
153141
153395
  capability: DEBUGGER_TOOL_CAPABILITY,
153142
153396
  services: (params) => {
@@ -153254,6 +153508,7 @@ var networkRequestTool = {
153254
153508
  Returns request/response headers (sensitive headers redacted), status, timing, the request body, and optionally the response body.
153255
153509
  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
153510
  Returns an error message string if the requestId is not found: use view-network-logs to get valid requestId values.`,
153511
+ readOnly: true,
153257
153512
  zodSchema: zodSchema39,
153258
153513
  capability: DEBUGGER_TOOL_CAPABILITY,
153259
153514
  services: (params) => {
@@ -153700,6 +153955,7 @@ since a TV UI has no tap coordinates. Move the highlight with \`tv-remote\` (up/
153700
153955
  back/menu/home), then call describe again to confirm where focus landed.`,
153701
153956
  alwaysLoad: true,
153702
153957
  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",
153958
+ readOnly: true,
153703
153959
  zodSchema: zodSchema40,
153704
153960
  capability: capability25,
153705
153961
  services: (params) => {
@@ -154200,6 +154456,7 @@ Use when a program needs element ancestry, such as an e2e engine's scoped select
154200
154456
  Returns { schemaVersion, roots, truncated, alertVisible, keyboardVisible, foregroundApp, unsupportedFields }.
154201
154457
  Fails if the iOS ax-service predates the tree command; update argent.`,
154202
154458
  hideFromMcp: true,
154459
+ readOnly: true,
154203
154460
  zodSchema: zodSchema41,
154204
154461
  capability: capability26,
154205
154462
  services: () => ({}),
@@ -154270,6 +154527,7 @@ function createForegroundAppTool(registry2) {
154270
154527
  Returns { bundleId, name, alertVisible }; under a system alert, bundleId is the app it covers.
154271
154528
  A field is unset when it is unknown.`,
154272
154529
  hideFromMcp: true,
154530
+ readOnly: true,
154273
154531
  zodSchema: zodSchema42,
154274
154532
  capability: capability27,
154275
154533
  services: () => ({}),
@@ -154756,6 +155014,7 @@ panel settles instantly on its last frame, and taps land nowhere until it is wok
154756
155014
  </flag:harmonyos>Use after a launch/navigation to wait for the UI to render before screenshotting or tapping.`,
154757
155015
  searchHint: "wait until screen settles idle stable stops changing animation transition rendered ready before screenshot",
154758
155016
  longRunning: true,
155017
+ readOnly: true,
154759
155018
  zodSchema: zodSchema44,
154760
155019
  capability: capability29,
154761
155020
  services: (params) => {
@@ -154839,6 +155098,96 @@ function classifyStaleness({
154839
155098
  };
154840
155099
  }
154841
155100
 
155101
+ // ../tool-server/src/utils/debugger/runtime-device.ts
155102
+ var import_node_crypto12 = require("node:crypto");
155103
+ var import_node_child_process39 = require("node:child_process");
155104
+ var import_node_util31 = require("node:util");
155105
+ init_adb();
155106
+ var execFileAsync31 = (0, import_node_util31.promisify)(import_node_child_process39.execFile);
155107
+ var LOG_READ_TIMEOUT_MS = 5e3;
155108
+ var RETRY_DELAY_MS = 300;
155109
+ async function findRuntimeDevice(cdp) {
155110
+ const marker = `argent-device-probe:${(0, import_node_crypto12.randomUUID)()}`;
155111
+ const logged = await cdp.evaluate(
155112
+ `(function () {
155113
+ if (typeof nativeLoggingHook !== "function") return false;
155114
+ nativeLoggingHook(${JSON.stringify(marker)}, 1);
155115
+ return true;
155116
+ })()`
155117
+ ).catch(() => false);
155118
+ if (logged !== true) return void 0;
155119
+ const checks = [
155120
+ async () => firstFound((await androidSerials()).map((serial) => () => logcatHolds(serial, marker))),
155121
+ async () => firstFound((await bootedSimulators()).map((udid) => () => simulatorLogHolds(udid, marker)))
155122
+ ];
155123
+ for (let attempt = 0; attempt < 2; attempt++) {
155124
+ if (attempt > 0) await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));
155125
+ const found = await firstFound(checks);
155126
+ if (found !== void 0) return found;
155127
+ }
155128
+ return void 0;
155129
+ }
155130
+ function firstFound(checks) {
155131
+ return new Promise((resolve16) => {
155132
+ let left = checks.length;
155133
+ if (left === 0) resolve16(void 0);
155134
+ for (const check3 of checks) {
155135
+ void check3().then((id) => {
155136
+ if (id !== void 0) resolve16(id);
155137
+ else if (--left === 0) resolve16(void 0);
155138
+ });
155139
+ }
155140
+ });
155141
+ }
155142
+ async function androidSerials() {
155143
+ try {
155144
+ const { stdout } = await runAdb(["devices"], { timeoutMs: ADB_DEVICES_TIMEOUT_MS });
155145
+ return parseAdbDevices(stdout).filter((d) => d.state === "device").map((d) => d.serial);
155146
+ } catch {
155147
+ return [];
155148
+ }
155149
+ }
155150
+ async function bootedSimulators() {
155151
+ const simulators = await listIosSimulators();
155152
+ return simulators.filter((s) => s.state === "Booted").map((s) => s.udid);
155153
+ }
155154
+ async function logcatHolds(serial, marker) {
155155
+ try {
155156
+ const { stdout } = await runAdb(
155157
+ ["-s", serial, "logcat", "-d", "-s", "ReactNativeJS", "-e", marker],
155158
+ { timeoutMs: LOG_READ_TIMEOUT_MS }
155159
+ );
155160
+ return stdout.includes(marker) ? serial : void 0;
155161
+ } catch {
155162
+ return void 0;
155163
+ }
155164
+ }
155165
+ async function simulatorLogHolds(udid, marker) {
155166
+ try {
155167
+ const args = await simctlArgsForUdid(udid, [
155168
+ "spawn",
155169
+ udid,
155170
+ "log",
155171
+ "show",
155172
+ "--info",
155173
+ "--last",
155174
+ "1m",
155175
+ "--style",
155176
+ "compact",
155177
+ "--predicate",
155178
+ `eventMessage CONTAINS ${JSON.stringify(marker)} AND process != "log"`
155179
+ ]);
155180
+ const { stdout } = await execFileAsync31("xcrun", args, {
155181
+ timeout: LOG_READ_TIMEOUT_MS,
155182
+ killSignal: SIMCTL_KILL_SIGNAL,
155183
+ encoding: "utf-8"
155184
+ });
155185
+ return stdout.includes(marker) ? udid : void 0;
155186
+ } catch {
155187
+ return void 0;
155188
+ }
155189
+ }
155190
+
154842
155191
  // ../tool-server/src/utils/react-profiler/devtools-bootstrap.ts
154843
155192
  function bootstrapFailureMessage(bootstrap) {
154844
155193
  switch (bootstrap.reason) {
@@ -154861,6 +155210,7 @@ function bootstrapFailureMessage(bootstrap) {
154861
155210
  // ../tool-server/src/tools/profiler/react/react-profiler-start.ts
154862
155211
  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
155212
  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.";
155213
+ 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
155214
  var zodSchema45 = external_exports.object({
154865
155215
  port: metroPortField,
154866
155216
  device_id: external_exports.string().describe(
@@ -155036,6 +155386,7 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
155036
155386
  await cdp.send("Profiler.stop").catch(ignore);
155037
155387
  api.profilingActive = false;
155038
155388
  }
155389
+ const runtimeDevice = isLogicalKeyedDevice(api.deviceId) ? await findRuntimeDevice(cdp) : void 0;
155039
155390
  const sessionId = crypto6.randomUUID();
155040
155391
  const ownerPayload = {
155041
155392
  sessionId,
@@ -155080,6 +155431,19 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
155080
155431
  }
155081
155432
  );
155082
155433
  }
155434
+ if (api.disposed) {
155435
+ await cdp.evaluate(STOP_FOR_TAKEOVER_SCRIPT).catch(ignore);
155436
+ await cdp.send("Profiler.stop").catch(ignore);
155437
+ throw new FailureError(
155438
+ `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.`,
155439
+ {
155440
+ error_code: FAILURE_CODES.REACT_PROFILER_SESSION_TORN_DOWN,
155441
+ failure_stage: "react_profiler_start_session_torn_down",
155442
+ failure_area: "tool_server",
155443
+ error_kind: "not_found"
155444
+ }
155445
+ );
155446
+ }
155083
155447
  const startedAtEpochMs = startResult.startedAtEpochMs ?? Date.now();
155084
155448
  clearCachedProfilerPaths(api.port, api.deviceId);
155085
155449
  api.sessionPaths = null;
@@ -155090,11 +155454,14 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
155090
155454
  api.profileStartWallMs = startedAtEpochMs;
155091
155455
  api.sessionId = sessionId;
155092
155456
  api.ownerToolServerPid = process.pid;
155457
+ trackProfilingRun(api.deviceId, api);
155458
+ if (runtimeDevice) trackProfilingRun(runtimeDevice, api);
155093
155459
  return {
155094
155460
  started_at: new Date(startedAtEpochMs).toISOString(),
155095
155461
  startedAtEpochMs,
155096
155462
  hermes_version: api.hermesVersion,
155097
- detected_architecture: api.detectedArchitecture
155463
+ detected_architecture: api.detectedArchitecture,
155464
+ ...isLogicalKeyedDevice(api.deviceId) && !runtimeDevice ? { [RESULT_NOTE_KEY]: UNKNOWN_DEVICE_NOTE } : {}
155098
155465
  };
155099
155466
  }
155100
155467
  };
@@ -155287,7 +155654,7 @@ Fails if no active profiling session exists or the CDP connection was lost durin
155287
155654
  }
155288
155655
  if (!api.profilingActive) {
155289
155656
  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.",
155657
+ "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
155658
  {
155292
155659
  error_code: FAILURE_CODES.REACT_PROFILER_NO_ACTIVE_SESSION,
155293
155660
  failure_stage: "react_profiler_stop_inactive",
@@ -155493,6 +155860,7 @@ function createReactProfilerStatusTool(registry2) {
155493
155860
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to check React profiler: ${failureSignal2.error_code}`
155494
155861
  },
155495
155862
  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.`,
155863
+ readOnly: true,
155496
155864
  zodSchema: zodSchema47,
155497
155865
  // RN-only: companion to react-profiler-start.
155498
155866
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -157295,6 +157663,7 @@ var reactProfilerComponentSourceTool = {
157295
157663
  Call this per-finding after react-profiler-analyze to inspect source before proposing a fix.
157296
157664
  Returns found: false if the component is not found in user-owned code (e.g. lives in node_modules).
157297
157665
  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.`,
157666
+ readOnly: true,
157298
157667
  zodSchema: zodSchema49,
157299
157668
  // Declared so the tool catalogue groups this with the other react-profiler-*
157300
157669
  // tools; the HTTP gate itself is a no-op here, as there is no device arg to
@@ -157433,6 +157802,7 @@ Use when you specifically need to investigate JS CPU hotspots that are NOT tied
157433
157802
  Call react-profiler-stop first. Reads directly from the stored cpuProfile.
157434
157803
  Returns a markdown table of the top hotspot functions with self-time, total-time, and location.
157435
157804
  Fails if react-profiler-stop has not been called or no CPU profile is stored.`,
157805
+ readOnly: true,
157436
157806
  zodSchema: zodSchema50,
157437
157807
  // RN-only: reads a Hermes CPU profile; Chromium's V8 sample format differs.
157438
157808
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -157547,6 +157917,7 @@ var reactProfilerRendersTool = {
157547
157917
  Returns a markdown table of the top re-rendering components. No profiling session required; works on a live connected app.
157548
157918
  Use when you want a quick snapshot of render counts without a full profiling session.
157549
157919
  Fails if the React DevTools hook is not present in the runtime or the app is not connected.`,
157920
+ readOnly: true,
157550
157921
  zodSchema: zodSchema51,
157551
157922
  // RN-only: queries the React DevTools backend hook on the live runtime.
157552
157923
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -157723,6 +158094,7 @@ var reactProfilerFiberTreeTool = {
157723
158094
  Use when tracing ancestry of a library component or checking for useMemoCache hook (confirms React Compiler is active on a component).
157724
158095
  Returns a nested JSON tree of fiber nodes with name, tag, actualDuration, selfBaseDuration, and children.
157725
158096
  Fails if the React DevTools hook is not present or no fiber roots have been committed yet.`,
158097
+ readOnly: true,
157726
158098
  zodSchema: zodSchema52,
157727
158099
  // RN-only: walks the fiber tree via the React DevTools backend hook.
157728
158100
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -158146,8 +158518,8 @@ var import_util14 = require("util");
158146
158518
  var DEFAULT_EXEC_TIMEOUT_MS = 6e4;
158147
158519
  var DEFAULT_EXEC_MAX_BUFFER = 256 * 1024 * 1024;
158148
158520
  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, {
158521
+ const execFileAsync36 = (0, import_util14.promisify)(import_child_process2.execFile);
158522
+ const { stdout, stderr } = await execFileAsync36(file2, args, {
158151
158523
  encoding: "utf-8",
158152
158524
  ...options,
158153
158525
  // Applied after ...options so a caller cannot weaken the guards; maxBuffer
@@ -159679,7 +160051,7 @@ var STARTUP_TIMEOUT_MS = 1e4;
159679
160051
  var DETECT_RUNNING_APP_TIMEOUT_MS = 1e4;
159680
160052
  var NOTIFY_REGISTER_TIMEOUT_MS = 2e3;
159681
160053
  var MAX_START_ATTEMPTS = 2;
159682
- var RETRY_DELAY_MS = 1200;
160054
+ var RETRY_DELAY_MS2 = 1200;
159683
160055
  var COLD_START_SIGNATURE = "Cannot find process matching name:";
159684
160056
  var STOP_GRACE_MS = 3e5;
159685
160057
  var STOP_TERM_MS = 5e3;
@@ -160103,10 +160475,10 @@ async function startNativeProfilerIos(api, params) {
160103
160475
  if (!isColdStart) throw err;
160104
160476
  if (attempt >= MAX_START_ATTEMPTS) break;
160105
160477
  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.
160478
+ `[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
160479
  `
160108
160480
  );
160109
- await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));
160481
+ await new Promise((r) => setTimeout(r, RETRY_DELAY_MS2));
160110
160482
  }
160111
160483
  }
160112
160484
  const totalMs = Date.now() - startMs;
@@ -161564,12 +161936,16 @@ Fails if no app is running on the device, or the profiler cannot attach to the p
161564
161936
  const api = services.session;
161565
161937
  const device = resolveDevice(params.device_id);
161566
161938
  assertSupported("native-profiler-start", capability30, device);
161939
+ let started;
161567
161940
  if (api.platform === "ios") {
161568
161941
  await ensureDeps(["xcrun"]);
161569
- return startNativeProfilerIos(api, params);
161942
+ started = await startNativeProfilerIos(api, params);
161943
+ } else {
161944
+ await ensureDeps(["adb"]);
161945
+ started = await startNativeProfilerAndroid(api, params);
161570
161946
  }
161571
- await ensureDeps(["adb"]);
161572
- return startNativeProfilerAndroid(api, params);
161947
+ trackProfilingRun(device.id, api);
161948
+ return started;
161573
161949
  }
161574
161950
  };
161575
161951
 
@@ -162196,7 +162572,7 @@ var WATERMARK_PNG_HEIGHT = 277;
162196
162572
  var WATERMARK_PNG_BASE64 = "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";
162197
162573
 
162198
162574
  // ../tool-server/src/tools/screen-recording/watermark.ts
162199
- var execFileAsync30 = (0, import_util15.promisify)(import_child_process6.execFile);
162575
+ var execFileAsync32 = (0, import_util15.promisify)(import_child_process6.execFile);
162200
162576
  var OUTPUT_FPS = 30;
162201
162577
  var FFMPEG_FALLBACK_PATHS = [
162202
162578
  "/opt/homebrew/bin/ffmpeg",
@@ -162213,7 +162589,7 @@ var MASK_DARK_MAX_LUMA = 90;
162213
162589
  var MASK_LIGHT_MIN_LUMA = 165;
162214
162590
  async function resolveBinary(name, fallbacks) {
162215
162591
  try {
162216
- await execFileAsync30("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
162592
+ await execFileAsync32("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
162217
162593
  return name;
162218
162594
  } catch {
162219
162595
  }
@@ -163239,6 +163615,7 @@ Every table states how many samples it covers and how much of that was idle.
163239
163615
  Use when investigating JS CPU hotspots or correlating CPU cost with specific components.
163240
163616
  Returns a markdown table of CPU hotspots, call tree, or per-component CPU breakdown.
163241
163617
  Fails if no CPU profile is stored; run react-profiler-stop first.`,
163618
+ readOnly: true,
163242
163619
  zodSchema: zodSchema58,
163243
163620
  // RN-only: reads Hermes-format CPU profiles; Chromium's V8 sample format differs.
163244
163621
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -163598,6 +163975,7 @@ Modes:
163598
163975
  Use when drilling into specific components or time windows after react-profiler-analyze.
163599
163976
  Returns a markdown table or tree of commit data matching the requested mode.
163600
163977
  Fails if react-profiler-stop has not been called or no commit data is stored.`,
163978
+ readOnly: true,
163601
163979
  zodSchema: zodSchema59,
163602
163980
  // Reads React commit data captured via the React DevTools backend.
163603
163981
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -163987,6 +164365,7 @@ Modes:
163987
164365
  Use when drilling into native hang stacks, thread CPU breakdown, or memory leaks after native-profiler-analyze.
163988
164366
  Returns a markdown report with native call stacks, thread weights, or leak details for the selected mode.
163989
164367
  Fails if native-profiler-analyze has not been run or no parsed trace data is in memory.`,
164368
+ readOnly: true,
163990
164369
  zodSchema: zodSchema60,
163991
164370
  // No chromium entry: it has no native trace capture.
163992
164371
  capability: {
@@ -164074,6 +164453,7 @@ Requires both react-profiler-analyze and native-profiler-analyze to have been ca
164074
164453
  Call this tool when both profilers were run in parallel on the same session.
164075
164454
  Returns a markdown report correlating hangs with React commits, memory leaks, and investigation hints.
164076
164455
  Fails if either react-profiler-analyze or native-profiler-analyze has not been called first.`,
164456
+ readOnly: true,
164077
164457
  zodSchema: zodSchema61,
164078
164458
  // iOS reads xctrace output; Android re-queries the Perfetto .pftrace via
164079
164459
  // loadAndroidCombinedData. Chromium has no native trace capture.
@@ -165020,7 +165400,7 @@ Returns { stopped } - the URNs of the services that were actually live and got s
165020
165400
 
165021
165401
  // ../tool-server/src/tools/simulator/stop-metro.ts
165022
165402
  init_zod();
165023
- var import_node_child_process38 = require("node:child_process");
165403
+ var import_node_child_process40 = require("node:child_process");
165024
165404
  function parseNetstatListeningPids(netstatOutput, port) {
165025
165405
  const pids = /* @__PURE__ */ new Set();
165026
165406
  for (const line of netstatOutput.split(/\r?\n/)) {
@@ -165036,7 +165416,7 @@ function parseNetstatListeningPids(netstatOutput, port) {
165036
165416
  }
165037
165417
  function listeningPids(port) {
165038
165418
  if (process.platform === "win32") {
165039
- const output3 = (0, import_node_child_process38.execFileSync)("netstat", ["-ano"], {
165419
+ const output3 = (0, import_node_child_process40.execFileSync)("netstat", ["-ano"], {
165040
165420
  encoding: "utf-8",
165041
165421
  timeout: 5e3,
165042
165422
  // `netstat -ano` dumps every socket on the host; overflowing Node's
@@ -165045,7 +165425,7 @@ function listeningPids(port) {
165045
165425
  });
165046
165426
  return parseNetstatListeningPids(output3, port);
165047
165427
  }
165048
- const output2 = (0, import_node_child_process38.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
165428
+ const output2 = (0, import_node_child_process40.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
165049
165429
  encoding: "utf-8",
165050
165430
  timeout: 5e3
165051
165431
  }).trim();
@@ -170802,7 +171182,7 @@ var import_node_url4 = require("node:url");
170802
171182
  init_src2();
170803
171183
 
170804
171184
  // ../tool-server/src/tools/flows/script/flow-script-executor.ts
170805
- var import_node_child_process39 = require("node:child_process");
171185
+ var import_node_child_process41 = require("node:child_process");
170806
171186
  var fs59 = __toESM(require("node:fs"));
170807
171187
  var os17 = __toESM(require("node:os"));
170808
171188
  var path45 = __toESM(require("node:path"));
@@ -171187,7 +171567,7 @@ var FlowScriptExecutor = class {
171187
171567
  detached: process.platform !== "win32",
171188
171568
  windowsHide: process.platform === "win32"
171189
171569
  };
171190
- child = (0, import_node_child_process39.fork)(scriptPath, [], forkOptions);
171570
+ child = (0, import_node_child_process41.fork)(scriptPath, [], forkOptions);
171191
171571
  } catch (err) {
171192
171572
  return emptyResult(
171193
171573
  { kind: "spawn", message: `Could not start the script process: ${errorMessage(err)}` },
@@ -171631,7 +172011,7 @@ async function stopProcessTree(child, graceMs) {
171631
172011
  if (process.platform === "win32") {
171632
172012
  if (hasExited(child)) return;
171633
172013
  tryKill(() => {
171634
- const killer = (0, import_node_child_process39.spawn)("taskkill", ["/pid", String(pid), "/t", "/f"], {
172014
+ const killer = (0, import_node_child_process41.spawn)("taskkill", ["/pid", String(pid), "/t", "/f"], {
171635
172015
  windowsHide: true,
171636
172016
  stdio: "ignore"
171637
172017
  });
@@ -172337,7 +172717,7 @@ init_src2();
172337
172717
  init_device_info();
172338
172718
 
172339
172719
  // ../tool-server/src/tools/flows/flow-visual.ts
172340
- var import_node_crypto12 = require("node:crypto");
172720
+ var import_node_crypto13 = require("node:crypto");
172341
172721
  var fs63 = __toESM(require("node:fs/promises"));
172342
172722
  var os18 = __toESM(require("node:os"));
172343
172723
  var path48 = __toESM(require("node:path"));
@@ -172353,7 +172733,7 @@ init_src2();
172353
172733
  // ../tool-server/src/tools/screenshot-diff/screenshot-diff-ocr.ts
172354
172734
  var import_child_process8 = require("child_process");
172355
172735
  var import_util16 = require("util");
172356
- var execFileAsync31 = (0, import_util16.promisify)(import_child_process8.execFile);
172736
+ var execFileAsync33 = (0, import_util16.promisify)(import_child_process8.execFile);
172357
172737
  var OCR_TIMEOUT_MS = 1e4;
172358
172738
  var OCR_MAX_BUFFER_BYTES = 32 * 1024 * 1024;
172359
172739
  var TESSERACT_BINARY = "tesseract";
@@ -172398,7 +172778,7 @@ async function extractOcrTextBlocks(imagePath) {
172398
172778
  }
172399
172779
  }
172400
172780
  async function recognizeTsv(imagePath) {
172401
- const { stdout } = await execFileAsync31(
172781
+ const { stdout } = await execFileAsync33(
172402
172782
  TESSERACT_BINARY,
172403
172783
  [
172404
172784
  imagePath,
@@ -174508,7 +174888,7 @@ async function runSnapshot(env, opts) {
174508
174888
  });
174509
174889
  const captureWarned = shot.warning !== void 0 ? { warning: shot.warning } : {};
174510
174890
  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)}`;
174891
+ const cropSuffix = opts.cropOn === void 0 ? "" : `-crop-${(0, import_node_crypto13.createHash)("sha256").update(cropIdentity(opts.cropOn)).digest("hex").slice(0, 8)}`;
174512
174892
  const snapshotKey = `${opts.name}__${authoringPlatform(env.device.platform)}-${w}x${h}${cropSuffix}`;
174513
174893
  const key2 = `${snapshotKey}.png`;
174514
174894
  const baselinePath = opts.clientFlowPath === void 0 ? path48.join(baselineDir(opts.flowsDir, opts.flowName), key2) : clientBaselinePath(opts.clientFlowPath, opts.flowName, key2);
@@ -174644,7 +175024,7 @@ async function runSnapshot(env, opts) {
174644
175024
  }
174645
175025
  };
174646
175026
  }
174647
- const within = result.mismatchPercentage <= opts.maxMismatch;
175027
+ const within = result.mismatchPercentage <= opts.maxMismatch * (1 + 1e-14);
174648
175028
  const reason2 = `diff ${result.mismatchPercentage.toFixed(2)}% ${within ? "\u2264" : ">"} ${opts.maxMismatch}% (${key2})`;
174649
175029
  if (within) {
174650
175030
  return { status: "pass", reason: reason2, ...captureWarned };
@@ -174680,11 +175060,11 @@ async function runSnapshot(env, opts) {
174680
175060
  }
174681
175061
 
174682
175062
  // ../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");
175063
+ var import_node_child_process42 = require("node:child_process");
175064
+ var import_node_util32 = require("node:util");
174685
175065
  init_adb();
174686
175066
  init_device_info();
174687
- var execFileAsync32 = (0, import_node_util30.promisify)(import_node_child_process40.execFile);
175067
+ var execFileAsync34 = (0, import_node_util32.promisify)(import_node_child_process42.execFile);
174688
175068
  var DEMO_BROADCAST = "am broadcast -a com.android.systemui.demo";
174689
175069
  var IOS_STATUS_BAR_OVERRIDE = [
174690
175070
  "override",
@@ -174708,7 +175088,7 @@ async function pinStatusBar(device, signal) {
174708
175088
  if (isIosPhysicalDevice(device)) return false;
174709
175089
  try {
174710
175090
  if (device.platform === "ios") {
174711
- await execFileAsync32(
175091
+ await execFileAsync34(
174712
175092
  "xcrun",
174713
175093
  await simctlArgsForUdid(device.id, ["status_bar", device.id, ...IOS_STATUS_BAR_OVERRIDE])
174714
175094
  );
@@ -174744,7 +175124,7 @@ async function pinStatusBar(device, signal) {
174744
175124
  async function restoreStatusBar(device) {
174745
175125
  try {
174746
175126
  if (device.platform === "ios") {
174747
- await execFileAsync32(
175127
+ await execFileAsync34(
174748
175128
  "xcrun",
174749
175129
  await simctlArgsForUdid(device.id, ["status_bar", device.id, "clear"])
174750
175130
  );
@@ -176328,6 +176708,7 @@ Touches no device: nothing is launched, tapped, dispatched or torn down, and no
176328
176708
  needs booting, so calling this costs nothing but a file read.
176329
176709
  Fails if the e2e test file does not exist.
176330
176710
  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.`,
176711
+ readOnly: true,
176331
176712
  zodSchema: zodSchema72,
176332
176713
  fileInputs: fileInputs5,
176333
176714
  services: () => ({}),
@@ -176352,7 +176733,7 @@ init_zod();
176352
176733
  // ../tool-server/src/utils/workspace-reader.ts
176353
176734
  var import_promises19 = require("node:fs/promises");
176354
176735
  var import_node_path29 = require("node:path");
176355
- var import_node_child_process41 = require("node:child_process");
176736
+ var import_node_child_process43 = require("node:child_process");
176356
176737
  var import_dotenv2 = __toESM(require_dist());
176357
176738
  async function exists2(path54) {
176358
176739
  try {
@@ -176396,7 +176777,7 @@ async function listDir(path54) {
176396
176777
  var COMMAND_TIMEOUT_MS = 3e3;
176397
176778
  function runVersionCommand(cmd, args, cwd) {
176398
176779
  return new Promise((resolve16) => {
176399
- const child = (0, import_node_child_process41.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
176780
+ const child = (0, import_node_child_process43.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
176400
176781
  if (err) {
176401
176782
  resolve16(null);
176402
176783
  return;
@@ -176676,6 +177057,7 @@ exploration of anything the snapshot surfaces.
176676
177057
  Use when you need to inspect project configuration without manually reading multiple files.
176677
177058
  Returns partial data if workspacePath does not exist or is not readable; missing items are represented as null or empty collections.
176678
177059
  Fails if the workspacePath is not an absolute path or the directory cannot be accessed.`,
177060
+ readOnly: true,
176679
177061
  zodSchema: zodSchema73,
176680
177062
  fileInputs: fileInputs6,
176681
177063
  services: () => ({}),
@@ -176685,7 +177067,7 @@ Fails if the workspacePath is not an absolute path or the directory cannot be ac
176685
177067
  };
176686
177068
 
176687
177069
  // ../tool-server/src/tools/system/update-argent.ts
176688
- var import_node_child_process42 = require("node:child_process");
177070
+ var import_node_child_process44 = require("node:child_process");
176689
177071
  var fs66 = __toESM(require("node:fs"));
176690
177072
  var path50 = __toESM(require("node:path"));
176691
177073
  init_zod();
@@ -176820,7 +177202,7 @@ var updateArgentTool = {
176820
177202
  if (spawnRoot) updateArgs.push("--project-root", spawnRoot);
176821
177203
  const cmd = cliEntry ? process.execPath : "argent";
176822
177204
  const args = cliEntry ? [cliEntry, ...updateArgs] : updateArgs;
176823
- const child = (0, import_node_child_process42.spawn)(cmd, args, {
177205
+ const child = (0, import_node_child_process44.spawn)(cmd, args, {
176824
177206
  detached: true,
176825
177207
  stdio: "ignore",
176826
177208
  env: { ...process.env, ARGENT_UPDATE_TRIGGER: "mcp_update" }
@@ -176872,7 +177254,7 @@ var dismissUpdateTool = {
176872
177254
  };
176873
177255
 
176874
177256
  // ../tool-server/src/tools/screenshot-diff/index.ts
176875
- var import_node_crypto13 = __toESM(require("node:crypto"));
177257
+ var import_node_crypto14 = __toESM(require("node:crypto"));
176876
177258
  var import_promises20 = __toESM(require("fs/promises"));
176877
177259
  var import_node_os15 = __toESM(require("node:os"));
176878
177260
  var import_path8 = __toESM(require("path"));
@@ -176886,10 +177268,10 @@ var zodSchema76 = external_exports.object({
176886
177268
  udid: external_exports.string().min(1).describe(
176887
177269
  "Target device id from `list-devices` (iOS UDID<flag:harmonyos>, HarmonyOS id,</flag:harmonyos> or Android serial)."
176888
177270
  ),
176889
- captureBaseline: external_exports.coerce.boolean().optional().describe(
177271
+ captureBaseline: external_exports.boolean().optional().describe(
176890
177272
  "Capture the baseline screenshot live at full resolution before diffing. Cannot be combined with captureCurrent."
176891
177273
  ),
176892
- captureCurrent: external_exports.coerce.boolean().optional().describe(
177274
+ captureCurrent: external_exports.boolean().optional().describe(
176893
177275
  "Capture the current screenshot live at full resolution before diffing. Cannot be combined with captureBaseline."
176894
177276
  ),
176895
177277
  rotation: external_exports.enum(["Portrait", "LandscapeLeft", "LandscapeRight", "PortraitUpsideDown"]).optional().describe(
@@ -177019,7 +177401,7 @@ async function resolveOutputDir(params, options) {
177019
177401
  const dir = import_path8.default.join(
177020
177402
  import_node_os15.default.tmpdir(),
177021
177403
  "argent-screenshot-diff",
177022
- import_node_crypto13.default.randomBytes(6).toString("hex")
177404
+ import_node_crypto14.default.randomBytes(6).toString("hex")
177023
177405
  );
177024
177406
  await import_promises20.default.mkdir(dir, { recursive: true });
177025
177407
  return dir;
@@ -177117,7 +177499,7 @@ function requireIosDeviceRunner(services) {
177117
177499
  }
177118
177500
  async function captureIosDeviceLiveInput(params) {
177119
177501
  const png = await captureRunnerScreenshotPng(params.runner, RUNNER_COMMAND_TIMEOUT_MS);
177120
- const suffix = import_node_crypto13.default.randomBytes(4).toString("hex");
177502
+ const suffix = import_node_crypto14.default.randomBytes(4).toString("hex");
177121
177503
  const destination = import_path8.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
177122
177504
  await import_promises20.default.mkdir(params.outputDir, { recursive: true });
177123
177505
  await import_promises20.default.writeFile(destination, png);
@@ -177135,7 +177517,7 @@ async function captureHarmonyLiveInput(params) {
177135
177517
  }
177136
177518
  await ensureDep("hdc");
177137
177519
  const captured = await captureHarmonyScreenshotPng({ connectKey: params.connectKey, scale: 1 });
177138
- const suffix = import_node_crypto13.default.randomBytes(4).toString("hex");
177520
+ const suffix = import_node_crypto14.default.randomBytes(4).toString("hex");
177139
177521
  const destination = import_path8.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
177140
177522
  try {
177141
177523
  await import_promises20.default.mkdir(params.outputDir, { recursive: true });
@@ -177171,7 +177553,7 @@ async function captureLiveInput(params) {
177171
177553
  params.peekFor?.(params.device)
177172
177554
  );
177173
177555
  }
177174
- const suffix = import_node_crypto13.default.randomBytes(4).toString("hex");
177556
+ const suffix = import_node_crypto14.default.randomBytes(4).toString("hex");
177175
177557
  const destination = import_path8.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
177176
177558
  await import_promises20.default.mkdir(params.outputDir, { recursive: true });
177177
177559
  await import_promises20.default.copyFile(capture.path, destination);
@@ -177890,13 +178272,13 @@ function probeArgentToolServer(host, port, timeoutMs = 500) {
177890
178272
 
177891
178273
  // ../tool-server/src/utils/simulator-watcher.ts
177892
178274
  var fs68 = __toESM(require("node:fs"));
177893
- var import_node_child_process43 = require("node:child_process");
177894
- var import_node_util31 = require("node:util");
178275
+ var import_node_child_process45 = require("node:child_process");
178276
+ var import_node_util33 = require("node:util");
177895
178277
  init_external_devices();
177896
- var execFileAsync33 = (0, import_node_util31.promisify)(import_node_child_process43.execFile);
178278
+ var execFileAsync35 = (0, import_node_util33.promisify)(import_node_child_process45.execFile);
177897
178279
  var POLL_INTERVAL_MS2 = 1e4;
177898
178280
  async function getBootedUdidsInSet(deviceSet) {
177899
- const { stdout } = await execFileAsync33("xcrun", [
178281
+ const { stdout } = await execFileAsync35("xcrun", [
177900
178282
  ...simctlPrefix(deviceSet),
177901
178283
  "list",
177902
178284
  "devices",
@@ -178015,7 +178397,7 @@ function startSimulatorWatcher(registry2) {
178015
178397
  }
178016
178398
 
178017
178399
  // ../tool-server/src/utils/preview-window.ts
178018
- var import_node_child_process44 = require("node:child_process");
178400
+ var import_node_child_process46 = require("node:child_process");
178019
178401
  var fs69 = __toESM(require("node:fs"));
178020
178402
  var os20 = __toESM(require("node:os"));
178021
178403
  var path52 = __toESM(require("node:path"));
@@ -178047,10 +178429,10 @@ function ensureLensAppBundle(electronBin) {
178047
178429
  fs69.copyFileSync(path52.join(realContents, "Info.plist"), plist);
178048
178430
  const setPlist = (entry, value) => {
178049
178431
  try {
178050
- (0, import_node_child_process44.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
178432
+ (0, import_node_child_process46.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
178051
178433
  } catch {
178052
178434
  try {
178053
- (0, import_node_child_process44.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
178435
+ (0, import_node_child_process46.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
178054
178436
  } catch {
178055
178437
  }
178056
178438
  }
@@ -178109,7 +178491,7 @@ function createPreviewWindowManager(opts = {}) {
178109
178491
  const wrapperBin = ensureLensAppBundle(electronBin);
178110
178492
  const launchBin = wrapperBin ?? electronBin;
178111
178493
  const launchArgs = wrapperBin ? ["--no-sandbox", mainScript] : [mainScript];
178112
- const next = (0, import_node_child_process44.spawn)(launchBin, launchArgs, {
178494
+ const next = (0, import_node_child_process46.spawn)(launchBin, launchArgs, {
178113
178495
  // Strips ELECTRON_RUN_AS_NODE, which an Electron-based MCP host leaves in
178114
178496
  // our env, so the child boots as a GUI app instead of bare Node.
178115
178497
  env: electronGuiChildEnv({ ARGENT_PREVIEW_URL: url2 }),