@swmansion/argent 0.20.1-next.5 → 0.20.1-next.7

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.
package/dist/cli-cmds.mjs CHANGED
@@ -1285,6 +1285,8 @@ var FAILURE_CODES = {
1285
1285
  IOS_REINSTALL_INSTALL_FAILED: "IOS_REINSTALL_INSTALL_FAILED",
1286
1286
  IOS_RESTART_LAUNCH_FAILED: "IOS_RESTART_LAUNCH_FAILED",
1287
1287
  IOS_SETTINGS_PERMISSION_FAILED: "IOS_SETTINGS_PERMISSION_FAILED",
1288
+ IOS_SHAKE_FAILED: "IOS_SHAKE_FAILED",
1289
+ ANDROID_SHAKE_FAILED: "ANDROID_SHAKE_FAILED",
1288
1290
  SETTINGS_PERMISSION_UNSUPPORTED: "SETTINGS_PERMISSION_UNSUPPORTED",
1289
1291
  NATIVE_DEVTOOLS_DESCRIBE_ERROR: "NATIVE_DEVTOOLS_DESCRIBE_ERROR",
1290
1292
  NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR: "NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR",
@@ -16434,6 +16434,8 @@ var FAILURE_CODES = {
16434
16434
  IOS_REINSTALL_INSTALL_FAILED: "IOS_REINSTALL_INSTALL_FAILED",
16435
16435
  IOS_RESTART_LAUNCH_FAILED: "IOS_RESTART_LAUNCH_FAILED",
16436
16436
  IOS_SETTINGS_PERMISSION_FAILED: "IOS_SETTINGS_PERMISSION_FAILED",
16437
+ IOS_SHAKE_FAILED: "IOS_SHAKE_FAILED",
16438
+ ANDROID_SHAKE_FAILED: "ANDROID_SHAKE_FAILED",
16437
16439
  SETTINGS_PERMISSION_UNSUPPORTED: "SETTINGS_PERMISSION_UNSUPPORTED",
16438
16440
  NATIVE_DEVTOOLS_DESCRIBE_ERROR: "NATIVE_DEVTOOLS_DESCRIBE_ERROR",
16439
16441
  NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR: "NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR",
@@ -16491,6 +16491,8 @@ var FAILURE_CODES = {
16491
16491
  IOS_REINSTALL_INSTALL_FAILED: "IOS_REINSTALL_INSTALL_FAILED",
16492
16492
  IOS_RESTART_LAUNCH_FAILED: "IOS_RESTART_LAUNCH_FAILED",
16493
16493
  IOS_SETTINGS_PERMISSION_FAILED: "IOS_SETTINGS_PERMISSION_FAILED",
16494
+ IOS_SHAKE_FAILED: "IOS_SHAKE_FAILED",
16495
+ ANDROID_SHAKE_FAILED: "ANDROID_SHAKE_FAILED",
16494
16496
  SETTINGS_PERMISSION_UNSUPPORTED: "SETTINGS_PERMISSION_UNSUPPORTED",
16495
16497
  NATIVE_DEVTOOLS_DESCRIBE_ERROR: "NATIVE_DEVTOOLS_DESCRIBE_ERROR",
16496
16498
  NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR: "NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR",
@@ -608,6 +608,8 @@ var init_failure_codes = __esm({
608
608
  IOS_REINSTALL_INSTALL_FAILED: "IOS_REINSTALL_INSTALL_FAILED",
609
609
  IOS_RESTART_LAUNCH_FAILED: "IOS_RESTART_LAUNCH_FAILED",
610
610
  IOS_SETTINGS_PERMISSION_FAILED: "IOS_SETTINGS_PERMISSION_FAILED",
611
+ IOS_SHAKE_FAILED: "IOS_SHAKE_FAILED",
612
+ ANDROID_SHAKE_FAILED: "ANDROID_SHAKE_FAILED",
611
613
  SETTINGS_PERMISSION_UNSUPPORTED: "SETTINGS_PERMISSION_UNSUPPORTED",
612
614
  NATIVE_DEVTOOLS_DESCRIBE_ERROR: "NATIVE_DEVTOOLS_DESCRIBE_ERROR",
613
615
  NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR: "NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR",
@@ -98632,6 +98634,23 @@ async function simctlListDevices() {
98632
98634
  );
98633
98635
  }
98634
98636
  }
98637
+ var remoteRuntimeKindCache = /* @__PURE__ */ new Map();
98638
+ async function isRemoteTvOsSimulator(udid) {
98639
+ const id = stripRemotePrefix(udid);
98640
+ const cached3 = remoteRuntimeKindCache.get(id);
98641
+ if (cached3) return cached3 === "tv";
98642
+ try {
98643
+ const { devices } = await simctlListDevices();
98644
+ for (const [runtime, entries] of Object.entries(devices)) {
98645
+ if (!entries.some((d) => d.udid === id)) continue;
98646
+ const kind = runtime.includes("tvOS") ? "tv" : "mobile";
98647
+ remoteRuntimeKindCache.set(id, kind);
98648
+ return kind === "tv";
98649
+ }
98650
+ } catch {
98651
+ }
98652
+ return false;
98653
+ }
98635
98654
  async function simctlBoot(udid) {
98636
98655
  await run(["simctl", "boot", stripRemotePrefix(udid)]);
98637
98656
  }
@@ -99364,23 +99383,23 @@ var InvalidToolInputError = class extends Error {
99364
99383
  });
99365
99384
  }
99366
99385
  };
99367
- function platformMatrix(platform, capability32) {
99386
+ function platformMatrix(platform, capability33) {
99368
99387
  switch (platform) {
99369
99388
  case "ios":
99370
- return capability32.apple;
99389
+ return capability33.apple;
99371
99390
  case "ios-remote":
99372
- return capability32.appleRemote;
99391
+ return capability33.appleRemote;
99373
99392
  case "android":
99374
- return capability32.android;
99393
+ return capability33.android;
99375
99394
  case "chromium":
99376
- return capability32.chromium;
99395
+ return capability33.chromium;
99377
99396
  case "vega":
99378
- return capability32.vega;
99397
+ return capability33.vega;
99379
99398
  }
99380
99399
  }
99381
- function assertSupported(toolId, capability32, device) {
99382
- if (!capability32) return;
99383
- const matrix = platformMatrix(device.platform, capability32);
99400
+ function assertSupported(toolId, capability33, device) {
99401
+ if (!capability33) return;
99402
+ const matrix = platformMatrix(device.platform, capability33);
99384
99403
  if (!matrix) {
99385
99404
  throw new UnsupportedOperationError(toolId, device, `no ${device.platform} support declared`);
99386
99405
  }
@@ -99388,7 +99407,7 @@ function assertSupported(toolId, capability32, device) {
99388
99407
  if (!supported) {
99389
99408
  throw new UnsupportedOperationError(toolId, device, `kind '${device.kind}' not supported`);
99390
99409
  }
99391
- if (capability32.supports && !capability32.supports(device)) {
99410
+ if (capability33.supports && !capability33.supports(device)) {
99392
99411
  throw new UnsupportedOperationError(toolId, device, "supports() refiner rejected device");
99393
99412
  }
99394
99413
  }
@@ -123264,6 +123283,274 @@ Returns { orientation }. Fails if the target device is not booted.`,
123264
123283
  }
123265
123284
  };
123266
123285
 
123286
+ // ../tool-server/src/tools/shake/schema.ts
123287
+ init_zod();
123288
+ var MAX_SHAKE_COUNT = 10;
123289
+ var shakeZodSchema = external_exports.object({
123290
+ udid: external_exports.string().min(1).describe(
123291
+ "Target device id from `list-devices` (iOS simulator UDID or Android emulator serial)."
123292
+ ),
123293
+ count: external_exports.number().int().min(1).max(MAX_SHAKE_COUNT).optional().describe(
123294
+ `How many shake gestures to deliver back-to-back (default 1, max ${MAX_SHAKE_COUNT}). Raise it for apps whose shake detector needs sustained motion before it fires.`
123295
+ )
123296
+ });
123297
+
123298
+ // ../tool-server/src/tools/shake/platforms/ios.ts
123299
+ var import_node_child_process26 = require("node:child_process");
123300
+ var import_node_util20 = require("node:util");
123301
+ init_src();
123302
+ var execFileAsync20 = (0, import_node_util20.promisify)(import_node_child_process26.execFile);
123303
+ var SHAKE_NOTIFICATION = "com.apple.UIKit.SimulatorShake";
123304
+ var SHAKE_INTERVAL_MS = 400;
123305
+ var sleep10 = (ms) => new Promise((r) => setTimeout(r, ms));
123306
+ var NOTIFYUTIL_ARGV = ["notifyutil", "-p", SHAKE_NOTIFICATION];
123307
+ function rejectTv(toolId, device) {
123308
+ throw new UnsupportedOperationError(
123309
+ toolId,
123310
+ device,
123311
+ "tvOS has no shake gesture \u2014 a TV is focus-driven, use tv-remote"
123312
+ );
123313
+ }
123314
+ function shakeFailure(udid, detail, cause) {
123315
+ const shutdownHint = /current state:\s*shutdown|unable to lookup/i.test(detail) ? " The simulator must be booted first \u2014 use boot-device." : "";
123316
+ return new FailureError(
123317
+ `Failed to shake ${udid}: ${detail.trim()}${shutdownHint}`,
123318
+ {
123319
+ error_code: FAILURE_CODES.IOS_SHAKE_FAILED,
123320
+ failure_stage: "ios_shake_notifyutil",
123321
+ failure_area: "tool_server",
123322
+ error_kind: "subprocess",
123323
+ // Only a thrown subprocess error carries the syscall/exit metadata. The
123324
+ // remote backend reports a non-zero child in its JSON payload instead of
123325
+ // throwing, so there is no error object to mine there.
123326
+ ...cause ? subprocessFailureMetadata(cause, "xcrun_simctl") : {}
123327
+ },
123328
+ cause ? { cause } : void 0
123329
+ );
123330
+ }
123331
+ var iosImpl4 = {
123332
+ requires: ["xcrun"],
123333
+ async handler(_services, params, device) {
123334
+ const { udid } = params;
123335
+ const count2 = params.count ?? 1;
123336
+ if (await isTvOsSimulator(udid)) rejectTv("shake", device);
123337
+ const args = await simctlArgsForUdid(udid, ["spawn", udid, ...NOTIFYUTIL_ARGV]);
123338
+ for (let i = 0; i < count2; i++) {
123339
+ if (i > 0) await sleep10(SHAKE_INTERVAL_MS);
123340
+ try {
123341
+ await execFileAsync20("xcrun", args, { timeout: 15e3 });
123342
+ } catch (err) {
123343
+ const error52 = err instanceof Error ? err : new Error(String(err));
123344
+ throw shakeFailure(udid, error52.message, error52);
123345
+ }
123346
+ }
123347
+ return { shaken: true, count: count2 };
123348
+ }
123349
+ };
123350
+ var iosRemoteImpl6 = {
123351
+ requires: ["sim-remote"],
123352
+ async handler(_services, params, device) {
123353
+ const { udid } = params;
123354
+ const count2 = params.count ?? 1;
123355
+ if (await isRemoteTvOsSimulator(udid)) rejectTv("shake", device);
123356
+ for (let i = 0; i < count2; i++) {
123357
+ if (i > 0) await sleep10(SHAKE_INTERVAL_MS);
123358
+ let result;
123359
+ try {
123360
+ result = await simctlSpawn(udid, { args: NOTIFYUTIL_ARGV });
123361
+ } catch (err) {
123362
+ const error52 = err instanceof Error ? err : new Error(String(err));
123363
+ throw shakeFailure(udid, error52.message, error52);
123364
+ }
123365
+ if (result.exitCode !== 0) {
123366
+ throw shakeFailure(
123367
+ udid,
123368
+ `notifyutil exited ${result.exitCode ?? "unknown"}${result.stderr ? `: ${result.stderr}` : ""}`
123369
+ );
123370
+ }
123371
+ }
123372
+ return { shaken: true, count: count2 };
123373
+ }
123374
+ };
123375
+
123376
+ // ../tool-server/src/tools/shake/platforms/android.ts
123377
+ init_src();
123378
+ init_adb();
123379
+ var SHAKE_AMPLITUDE = 30;
123380
+ var SWINGS_PER_SHAKE = 8;
123381
+ var SWING_INTERVAL_MS = 50;
123382
+ var DEFAULT_REST = { x: 0, y: 9.81, z: 0 };
123383
+ var MIN_REST_MAGNITUDE = 5;
123384
+ var MAX_REST_MAGNITUDE = 15;
123385
+ var DECIMAL = String.raw`[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?`;
123386
+ var ACCELERATION_RE = new RegExp(
123387
+ String.raw`acceleration\s*=\s*(${DECIMAL}):(${DECIMAL}):(${DECIMAL})`
123388
+ );
123389
+ function parseAcceleration(stdout) {
123390
+ const match = ACCELERATION_RE.exec(stdout);
123391
+ if (!match) return null;
123392
+ const [x, y, z2] = [match[1], match[2], match[3]].map(Number);
123393
+ if (![x, y, z2].every((n) => Number.isFinite(n))) return null;
123394
+ return { x, y, z: z2 };
123395
+ }
123396
+ function restingVectorFrom(stdout) {
123397
+ const read = parseAcceleration(stdout);
123398
+ if (!read) return DEFAULT_REST;
123399
+ const magnitude = Math.hypot(read.x, read.y, read.z);
123400
+ if (magnitude < MIN_REST_MAGNITUDE || magnitude > MAX_REST_MAGNITUDE) return DEFAULT_REST;
123401
+ return read;
123402
+ }
123403
+ var fmt = (v) => `${v.x.toFixed(4)}:${v.y.toFixed(4)}:${v.z.toFixed(4)}`;
123404
+ var sleep11 = (ms) => new Promise((r) => setTimeout(r, ms));
123405
+ async function emuConsole(serial, args) {
123406
+ const { stdout } = await runAdb(["-s", serial, "emu", ...args], { timeoutMs: 1e4 });
123407
+ const lines = stdout.split("\n").map((line) => line.trim()).filter(Boolean);
123408
+ const verdict = lines[lines.length - 1];
123409
+ if (verdict?.startsWith("KO:")) {
123410
+ throw new Error(`emulator console rejected \`${args.join(" ")}\` \u2014 ${verdict}`);
123411
+ }
123412
+ return stdout;
123413
+ }
123414
+ var inFlightByDevice = /* @__PURE__ */ new Map();
123415
+ function withDeviceLock(serial, fn) {
123416
+ const previous = inFlightByDevice.get(serial) ?? Promise.resolve();
123417
+ const run2 = previous.then(fn, fn);
123418
+ const settled = run2.catch(() => {
123419
+ });
123420
+ inFlightByDevice.set(serial, settled);
123421
+ void settled.then(() => {
123422
+ if (inFlightByDevice.get(serial) === settled) inFlightByDevice.delete(serial);
123423
+ });
123424
+ return run2;
123425
+ }
123426
+ var androidImpl6 = {
123427
+ requires: ["adb"],
123428
+ async handler(_services, params, device) {
123429
+ const serial = params.udid;
123430
+ const count2 = params.count ?? 1;
123431
+ if (await isAndroidTv(serial)) {
123432
+ throw new UnsupportedOperationError(
123433
+ "shake",
123434
+ device,
123435
+ "Android TV has no shake gesture \u2014 a TV is focus-driven, use tv-remote"
123436
+ );
123437
+ }
123438
+ if (consolePortFromAdbSerial(serial) === null) {
123439
+ throw new FailureError(
123440
+ `Cannot shake ${serial}: sensor injection needs an Android emulator.`,
123441
+ {
123442
+ error_code: FAILURE_CODES.ANDROID_SHAKE_FAILED,
123443
+ failure_stage: "android_shake_not_emulator",
123444
+ failure_area: "tool_server",
123445
+ error_kind: "validation"
123446
+ }
123447
+ );
123448
+ }
123449
+ const setAcceleration = async (v) => {
123450
+ await emuConsole(serial, ["sensor", "set", "acceleration", fmt(v)]);
123451
+ };
123452
+ return withDeviceLock(serial, async () => {
123453
+ let rest;
123454
+ try {
123455
+ rest = restingVectorFrom(await emuConsole(serial, ["sensor", "get", "acceleration"]));
123456
+ } catch (err) {
123457
+ const detail = err instanceof Error ? err.message : String(err);
123458
+ throw new FailureError(
123459
+ `Failed to read the accelerometer on ${serial}: ${detail.trim()}`,
123460
+ {
123461
+ error_code: FAILURE_CODES.ANDROID_SHAKE_FAILED,
123462
+ failure_stage: "android_shake_sensor_get",
123463
+ failure_area: "tool_server",
123464
+ error_kind: "subprocess"
123465
+ },
123466
+ { cause: err instanceof Error ? err : new Error(String(err)) }
123467
+ );
123468
+ }
123469
+ try {
123470
+ for (let gesture = 0; gesture < count2; gesture++) {
123471
+ for (let swing = 0; swing < SWINGS_PER_SHAKE; swing++) {
123472
+ const direction = swing % 2 === 0 ? 1 : -1;
123473
+ await setAcceleration({
123474
+ x: rest.x + direction * SHAKE_AMPLITUDE,
123475
+ y: rest.y,
123476
+ z: rest.z
123477
+ });
123478
+ await sleep11(SWING_INTERVAL_MS);
123479
+ }
123480
+ }
123481
+ } catch (err) {
123482
+ const detail = err instanceof Error ? err.message : String(err);
123483
+ throw new FailureError(
123484
+ `Failed to shake ${serial}: ${detail.trim()}`,
123485
+ {
123486
+ error_code: FAILURE_CODES.ANDROID_SHAKE_FAILED,
123487
+ failure_stage: "android_shake_sensor_set",
123488
+ failure_area: "tool_server",
123489
+ error_kind: "subprocess"
123490
+ },
123491
+ { cause: err instanceof Error ? err : new Error(String(err)) }
123492
+ );
123493
+ } finally {
123494
+ await setAcceleration(rest).catch(() => {
123495
+ });
123496
+ }
123497
+ return { shaken: true, count: count2 };
123498
+ });
123499
+ }
123500
+ };
123501
+
123502
+ // ../tool-server/src/tools/shake/index.ts
123503
+ var capability18 = {
123504
+ // Simulator only. A physical iPhone's motion comes from real hardware; there
123505
+ // is no host-side hook to fake it, so `device` stays false and a paired phone
123506
+ // gets a clean 400 instead of a silent no-op.
123507
+ apple: { simulator: true },
123508
+ // A remote simulator is still a simulator: `sim-remote spawn` runs the same
123509
+ // in-simulator `notifyutil` argv the local path does.
123510
+ appleRemote: { simulator: true },
123511
+ // Android emulators only, for the same reason as iOS: a physical phone's
123512
+ // accelerometer can't be driven from the host. `unknown` is allowed through
123513
+ // because a serial that didn't resolve may still be an emulator; the handler
123514
+ // re-checks and rejects a non-emulator serial explicitly.
123515
+ android: { emulator: true, unknown: true }
123516
+ // No `vega`: a Fire TV is rejected here, by the absent block.
123517
+ //
123518
+ // TV targets that are NOT separate platforms cannot be excluded here. An
123519
+ // Apple TV simulator is `ios`/`simulator` and an Android TV emulator is
123520
+ // `android`/`emulator` — identical to a phone by id shape and device kind, so
123521
+ // the matrix admits them and each platform handler probes the runtime and
123522
+ // rejects a TV. `supports` can't do it: it is synchronous, while the runtime
123523
+ // kind is an async `simctl list` / `adb` probe.
123524
+ };
123525
+ var shakeTool = {
123526
+ id: "shake",
123527
+ interaction: {
123528
+ startedMsg: ({ params }) => params.count && params.count > 1 ? `Shaking device ${params.count}x` : "Shaking device",
123529
+ completedMsg: ({ params }) => params.count && params.count > 1 ? `Shook device ${params.count}x` : "Shook device",
123530
+ failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to shake device: ${failureSignal2.error_code}`
123531
+ },
123532
+ description: `Shake the device (iOS simulator or Android emulator).
123533
+ Use to trigger anything bound to the shake gesture: iOS's "Undo Typing" / "Redo Typing" prompt in a text field, React Native's developer menu in a debug build, or an app's own shake-to-report handler.
123534
+ iOS delivers one discrete shake per gesture (the same motion event a physical device raises). Android has no OS-level shake event \u2014 the accelerometer is driven through a burst of hard direction changes so app-side detectors fire, and the resting orientation is restored afterwards.
123535
+ Set \`count\` above 1 when a detector needs sustained motion before it triggers.
123536
+ Returns { shaken: true, count }.
123537
+ Works on local and remote (sim-remote) iOS simulators.
123538
+ Only phone/tablet simulators and emulators are supported.`,
123539
+ searchHint: "shake motion accelerometer undo typing dev menu gesture",
123540
+ zodSchema: shakeZodSchema,
123541
+ capability: capability18,
123542
+ // Talks to `simctl` / `adb` directly, so no simulator-server is resolved —
123543
+ // avoids spawning one (and its ready-wait) for a tool that never uses it.
123544
+ services: () => ({}),
123545
+ execute: dispatchByPlatform({
123546
+ toolId: "shake",
123547
+ capability: capability18,
123548
+ ios: iosImpl4,
123549
+ iosRemote: iosRemoteImpl6,
123550
+ android: androidImpl6
123551
+ })
123552
+ };
123553
+
123267
123554
  // ../tool-server/src/tools/tv-remote/index.ts
123268
123555
  init_zod();
123269
123556
 
@@ -123360,7 +123647,7 @@ var zodSchema26 = external_exports.object({
123360
123647
  'Repeat the whole `button` value this many times (default 1). Compact for long same-button runs, e.g. { button: "down", repeat: 12 }.'
123361
123648
  )
123362
123649
  });
123363
- var capability18 = {
123650
+ var capability19 = {
123364
123651
  apple: { simulator: true, device: true },
123365
123652
  android: { emulator: true, device: true, unknown: true },
123366
123653
  vega: { vvd: true }
@@ -123387,11 +123674,11 @@ Returns { pressed, count }.`,
123387
123674
  longRunning: true,
123388
123675
  searchHint: "tv remote dpad d-pad navigate focus up down left right select ok back home menu play pause rewind fast forward sequence path apple tv tvos android tv leanback vega fire tv",
123389
123676
  zodSchema: zodSchema26,
123390
- capability: capability18,
123677
+ capability: capability19,
123391
123678
  services: () => ({}),
123392
123679
  execute: dispatchByPlatform({
123393
123680
  toolId: "tv-remote",
123394
- capability: capability18,
123681
+ capability: capability19,
123395
123682
  ios: makeIosImpl4(registry2),
123396
123683
  android: makeAndroidImpl2(registry2),
123397
123684
  vega: vegaImpl5
@@ -129565,7 +129852,7 @@ var conditionCompleted = {
129565
129852
  hidden: "UI element became hidden",
129566
129853
  text: "UI element matched expected text"
129567
129854
  };
129568
- var capability19 = {
129855
+ var capability20 = {
129569
129856
  apple: { simulator: true, device: true },
129570
129857
  android: { emulator: true, device: true, unknown: true },
129571
129858
  chromium: { app: true },
@@ -129657,7 +129944,7 @@ or before tapping an element that appears asynchronously.`,
129657
129944
  searchHint: "wait await poll until visible hidden exists text appears disappears timeout element condition settle",
129658
129945
  longRunning: true,
129659
129946
  zodSchema: zodSchema27,
129660
- capability: capability19,
129947
+ capability: capability20,
129661
129948
  services: (params) => {
129662
129949
  const device = resolveDevice(params.udid);
129663
129950
  if (device.platform === "chromium") {
@@ -129668,7 +129955,7 @@ or before tapping an element that appears asynchronously.`,
129668
129955
  async execute(services, params, ctx) {
129669
129956
  const signal = ctx?.signal;
129670
129957
  const device = resolveDevice(params.udid);
129671
- assertSupported(AWAIT_UI_ELEMENT_TOOL_ID, capability19, device);
129958
+ assertSupported(AWAIT_UI_ELEMENT_TOOL_ID, capability20, device);
129672
129959
  if (device.platform === "ios") await ensureDeps(iosRequires);
129673
129960
  else if (device.platform === "android") await ensureDeps(androidRequires);
129674
129961
  else if (device.platform === "vega") await ensureDeps(vegaRequires);
@@ -129726,6 +130013,10 @@ var ALLOWED_TOOLS = /* @__PURE__ */ new Set([
129726
130013
  "button",
129727
130014
  "keyboard",
129728
130015
  "rotate",
130016
+ // Sequencing matters for shake: the interesting cases are races (shake while
130017
+ // a sheet is dismissing, shake right after typing), which need the steps
130018
+ // dispatched back-to-back rather than across separate round-trips.
130019
+ "shake",
129729
130020
  // `tv-remote` drives the D-pad on a TV target (Apple TV / Android TV / Vega);
129730
130021
  // `keyboard` types into the focused field there.
129731
130022
  "tv-remote",
@@ -129738,7 +130029,7 @@ var zodSchema28 = external_exports.object({
129738
130029
  steps: external_exports.array(
129739
130030
  external_exports.object({
129740
130031
  tool: external_exports.string().describe(
129741
- "Tool name \u2014 one of: gesture-tap, gesture-swipe, gesture-scroll, gesture-drag, gesture-custom, gesture-pinch, gesture-rotate, button, keyboard, rotate, tv-remote, await-ui-element. On a TV target (Apple TV / Android TV / Vega) use tv-remote (remote presses) and keyboard (text)."
130032
+ "Tool name \u2014 one of: gesture-tap, gesture-swipe, gesture-scroll, gesture-drag, gesture-custom, gesture-pinch, gesture-rotate, button, keyboard, rotate, shake, tv-remote, await-ui-element. On a TV target (Apple TV / Android TV / Vega) use tv-remote (remote presses) and keyboard (text)."
129742
130033
  ),
129743
130034
  args: external_exports.record(external_exports.string(), external_exports.unknown()).describe("Tool arguments (excluding udid, which is injected automatically)"),
129744
130035
  delayMs: external_exports.number().optional().describe(
@@ -129747,7 +130038,7 @@ var zodSchema28 = external_exports.object({
129747
130038
  })
129748
130039
  ).min(1).describe("Ordered list of interaction steps to execute sequentially")
129749
130040
  });
129750
- var capability20 = {
130041
+ var capability21 = {
129751
130042
  apple: { simulator: true, device: true },
129752
130043
  appleRemote: { simulator: true },
129753
130044
  android: { emulator: true, device: true, unknown: true },
@@ -129789,6 +130080,7 @@ Allowed tools and their args (udid is auto-injected, do NOT include it in args):
129789
130080
  keyboard: { text?: string, key?: string, delayMs?: number } (key pressed after text; TV: text only) [ios/android/chromium/vega/tv]
129790
130081
  text supports {{secret:<NAME>}} placeholders, resolved server-side from ARGENT_SECRET_<NAME> env vars or an argent secrets file \u2014 credentials never enter agent context
129791
130082
  rotate: { orientation: "Portrait"|"LandscapeLeft"|"LandscapeRight"|"PortraitUpsideDown" } [ios/android]
130083
+ shake: { count?: number } [ios sim/android emu]
129792
130084
  tv-remote: { button: <remote button | array of them>, repeat?: number } [apple tv/android tv/vega]
129793
130085
  buttons: up/down/left/right/select/back/home/menu/playPause (+ rewind/fastForward/next/previous/volumeUp/volumeDown/mute \u2014 work on Android TV and Vega; rejected on the Apple TV simulator)
129794
130086
  await-ui-element: { condition: "exists"|"visible"|"hidden"|"text", selector: {text?,identifier?,role?}, expectedText?, timeoutMs?, pollIntervalMs? } [ios/android/chromium]
@@ -129824,7 +130116,7 @@ Stops on the first error (or unmet await-ui-element condition) and returns parti
129824
130116
  longRunning: true,
129825
130117
  searchHint: "batch sequence multiple gesture steps sequentially",
129826
130118
  zodSchema: zodSchema28,
129827
- capability: capability20,
130119
+ capability: capability21,
129828
130120
  // No eagerly-declared service: each step resolves its own services through
129829
130121
  // `invokeSubTool` below (simulator-server for iOS/Android, CDP for
129830
130122
  // Chromium), so run-sequence itself needs none. An eager resolver can't be
@@ -132102,7 +132394,7 @@ function formatDescribeTree(root, opts) {
132102
132394
  }
132103
132395
 
132104
132396
  // ../tool-server/src/tools/describe/platforms/tv.ts
132105
- var sleep10 = (ms) => new Promise((r) => setTimeout(r, ms));
132397
+ var sleep12 = (ms) => new Promise((r) => setTimeout(r, ms));
132106
132398
  var EMPTY_RETRY_ATTEMPTS = 3;
132107
132399
  var EMPTY_RETRY_DELAY_MS = 600;
132108
132400
  var EMPTY_HINT = "No focusable elements after retrying and recycling the read path. The app is most likely still launching (splash / loading screen) or mid-transition \u2014 this is normal right after launch-app / restart-app. Wait ~2-3s and call describe again; a React Native app only exposes focus once its JS bundle has loaded. If it stays empty, take a screenshot to confirm what's actually on screen.";
@@ -132143,7 +132435,7 @@ async function describeTv(registry2, device) {
132143
132435
  let res = await api.describe();
132144
132436
  if (device.platform !== "android") {
132145
132437
  for (let attempt = 1; attempt < EMPTY_RETRY_ATTEMPTS && isEmpty(res); attempt++) {
132146
- await sleep10(EMPTY_RETRY_DELAY_MS);
132438
+ await sleep12(EMPTY_RETRY_DELAY_MS);
132147
132439
  res = await api.describe();
132148
132440
  }
132149
132441
  }
@@ -132193,7 +132485,7 @@ var zodSchema38 = external_exports.object({
132193
132485
  "Optional app bundle ID. Used as a target hint on iOS when the AX-service returns no elements and the describe tool falls back to native-devtools inspection. If omitted, the fallback auto-detects the frontmost connected app. Ignored on Android / Chromium."
132194
132486
  )
132195
132487
  });
132196
- var capability21 = {
132488
+ var capability22 = {
132197
132489
  apple: { simulator: true, device: true },
132198
132490
  appleRemote: { simulator: true },
132199
132491
  android: { emulator: true, device: true, unknown: true },
@@ -132203,7 +132495,7 @@ var capability21 = {
132203
132495
  function makeDescribeExecute(registry2) {
132204
132496
  return dispatchByPlatform({
132205
132497
  toolId: "describe",
132206
- capability: capability21,
132498
+ capability: capability22,
132207
132499
  ios: {
132208
132500
  requires: iosRequires,
132209
132501
  handler: async (_services, params, device) => (
@@ -132278,7 +132570,7 @@ back/menu/home), then call describe again to confirm where focus landed.`,
132278
132570
  alwaysLoad: true,
132279
132571
  searchHint: "accessibility element tree ui hierarchy tap coordinates ios android chromium vega dom tv tvos apple tv android tv fire tv focus focusable remote dpad",
132280
132572
  zodSchema: zodSchema38,
132281
- capability: capability21,
132573
+ capability: capability22,
132282
132574
  services: (params) => {
132283
132575
  const device = resolveDevice(params.udid);
132284
132576
  if (device.platform === "chromium") {
@@ -132307,7 +132599,7 @@ var zodSchema39 = external_exports.object({
132307
132599
  `The screen must hold the same content for at least this long to count as settled (default ${DEFAULT_MIN_STABLE_MS}).`
132308
132600
  )
132309
132601
  });
132310
- var capability22 = {
132602
+ var capability23 = {
132311
132603
  apple: { simulator: true, device: true },
132312
132604
  android: { emulator: true, device: true, unknown: true },
132313
132605
  chromium: { app: true }
@@ -132351,7 +132643,7 @@ still before the timeout. Use after a launch/navigation to wait for the UI to re
132351
132643
  searchHint: "wait until screen settles idle stable stops changing animation transition rendered ready before screenshot",
132352
132644
  longRunning: true,
132353
132645
  zodSchema: zodSchema39,
132354
- capability: capability22,
132646
+ capability: capability23,
132355
132647
  services: (params) => {
132356
132648
  const device = resolveDevice(params.udid);
132357
132649
  if (device.platform === "chromium") {
@@ -132361,7 +132653,7 @@ still before the timeout. Use after a launch/navigation to wait for the UI to re
132361
132653
  },
132362
132654
  async execute(services, params, ctx) {
132363
132655
  const device = resolveDevice(params.udid);
132364
- assertSupported(AWAIT_SCREEN_IDLE_TOOL_ID, capability22, device);
132656
+ assertSupported(AWAIT_SCREEN_IDLE_TOOL_ID, capability23, device);
132365
132657
  if (device.platform === "ios") await ensureDeps(iosRequires);
132366
132658
  else if (device.platform === "android") await ensureDeps(androidRequires);
132367
132659
  const isTvOs = device.platform === "ios" && await isTvOsSimulator(device.id);
@@ -135688,8 +135980,8 @@ var import_util6 = require("util");
135688
135980
  var DEFAULT_EXEC_TIMEOUT_MS = 6e4;
135689
135981
  var DEFAULT_EXEC_MAX_BUFFER = 256 * 1024 * 1024;
135690
135982
  async function execFileAsyncWithTimeout(file2, args, options = {}) {
135691
- const execFileAsync24 = (0, import_util6.promisify)(import_child_process2.execFile);
135692
- const { stdout, stderr } = await execFileAsync24(file2, args, {
135983
+ const execFileAsync25 = (0, import_util6.promisify)(import_child_process2.execFile);
135984
+ const { stdout, stderr } = await execFileAsync25(file2, args, {
135693
135985
  encoding: "utf-8",
135694
135986
  ...options,
135695
135987
  // The timeout and maxBuffer are this wrapper's whole purpose (the
@@ -139049,7 +139341,7 @@ var zodSchema48 = external_exports.object({
139049
139341
  "iOS-only. When true, cold-launches the app under the profiler with Malloc Stack Logging enabled so memory leaks carry an allocation backtrace (responsible frame + library). Without it, leaks are still detected but unattributable \u2014 Instruments reports '<Call stack limit reached>'. Trade-offs: this RESTARTS the app (current state is lost), adds memory/CPU overhead, and makes the app noticeably slow to launch (every startup allocation records a backtrace), so leave it off for pure CPU/hang profiling. Requires a non-degraded Xcode: on Xcode 26.4 and later the cold-launch path is broken, so the call is rejected up front (re-run without the flag, or set ARGENT_IOS_CAPTURE=device to override if the device path works on your host). ARGENT_IOS_CAPTURE=all-processes \u2014 e.g. exported globally for the normal capture path \u2014 also rejects this flag up front, since that fallback cannot cold-launch; unset it (or set it to device) first. Ignored on Android."
139050
139342
  )
139051
139343
  });
139052
- var capability23 = {
139344
+ var capability24 = {
139053
139345
  apple: { simulator: true, device: true },
139054
139346
  android: { emulator: true, device: true, unknown: true }
139055
139347
  };
@@ -139060,7 +139352,7 @@ var nativeProfilerStartTool = {
139060
139352
  completedMsg: () => "Started native profiler",
139061
139353
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to start native profiler: ${failureSignal2.error_code}`
139062
139354
  },
139063
- capability: capability23,
139355
+ capability: capability24,
139064
139356
  description: `Start native profiling on a booted device. iOS: Instruments via xctrace (CPU, hangs, memory). Android: Perfetto (CPU, jank, RSS-growth weak signal).
139065
139357
  Auto-detects the running app process unless app_process is explicitly provided.
139066
139358
  After starting, let the user interact with the app, then call native-profiler-stop.
@@ -139074,7 +139366,7 @@ Fails if no app is running on the device, or the profiler cannot attach to the p
139074
139366
  async execute(services, params) {
139075
139367
  const api = services.session;
139076
139368
  const device = resolveDevice(params.device_id);
139077
- assertSupported("native-profiler-start", capability23, device);
139369
+ assertSupported("native-profiler-start", capability24, device);
139078
139370
  if (api.platform === "ios") {
139079
139371
  await ensureDeps(["xcrun"]);
139080
139372
  return startNativeProfilerIos(api, params);
@@ -139091,7 +139383,7 @@ var zodSchema49 = external_exports.object({
139091
139383
  "Target device id from `list-devices` (iOS UDID or Android serial)."
139092
139384
  )
139093
139385
  });
139094
- var capability24 = {
139386
+ var capability25 = {
139095
139387
  apple: { simulator: true, device: true },
139096
139388
  android: { emulator: true, device: true, unknown: true }
139097
139389
  };
@@ -139112,7 +139404,7 @@ var nativeProfilerStopTool = {
139112
139404
  completedMsg: ({ result }) => `Saved native profile ${result.traceFile.filename}`,
139113
139405
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop native profiler: ${failureSignal2.error_code}`
139114
139406
  },
139115
- capability: capability24,
139407
+ capability: capability25,
139116
139408
  // Packaging plus the export passes routinely exceed the 30s fetch timeout.
139117
139409
  longRunning: true,
139118
139410
  description: `Stop native profiling and export trace data.
@@ -139129,7 +139421,7 @@ Fails if no active native-profiler-start session exists for the given device_id.
139129
139421
  async execute(services, params, ctx) {
139130
139422
  const api = services.session;
139131
139423
  const device = resolveDevice(params.device_id);
139132
- assertSupported("native-profiler-stop", capability24, device);
139424
+ assertSupported("native-profiler-stop", capability25, device);
139133
139425
  if (api.platform === "ios") {
139134
139426
  await ensureDeps(["xcrun"]);
139135
139427
  const ios = await stopNativeProfilerIos(api);
@@ -139161,7 +139453,7 @@ var zodSchema50 = external_exports.object({
139161
139453
  "Target device id from `list-devices` (iOS UDID or Android serial)."
139162
139454
  )
139163
139455
  });
139164
- var capability25 = {
139456
+ var capability26 = {
139165
139457
  apple: { simulator: true, device: true },
139166
139458
  android: { emulator: true, device: true, unknown: true }
139167
139459
  };
@@ -139172,7 +139464,7 @@ var nativeProfilerAnalyzeTool = {
139172
139464
  completedMsg: () => "Analyzed native profile",
139173
139465
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to analyze native profile: ${failureSignal2.error_code}`
139174
139466
  },
139175
- capability: capability25,
139467
+ capability: capability26,
139176
139468
  description: `Analyze exported native trace data and return an LLM-optimized markdown report.
139177
139469
  iOS: parses CPU time profile, UI hangs, and memory leaks from the exported XML files.
139178
139470
  Android: queries the Perfetto .pftrace via the in-process Perfetto trace-processor engine for CPU hotspots, UI hangs with jank reason + main-thread state breakdown, GC annotation, and an RSS-growth weak signal.
@@ -139189,7 +139481,7 @@ Fails if native-profiler-stop has not been called first to export trace data.`,
139189
139481
  async execute(services, params, ctx) {
139190
139482
  const api = services.session;
139191
139483
  const device = resolveDevice(params.device_id);
139192
- assertSupported("native-profiler-analyze", capability25, device);
139484
+ assertSupported("native-profiler-analyze", capability26, device);
139193
139485
  let result;
139194
139486
  if (api.platform === "ios") {
139195
139487
  await ensureDeps(["xcrun"]);
@@ -139673,7 +139965,7 @@ var WATERMARK_PNG_HEIGHT = 277;
139673
139965
  var WATERMARK_PNG_BASE64 = "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";
139674
139966
 
139675
139967
  // ../tool-server/src/tools/screen-recording/watermark.ts
139676
- var execFileAsync20 = (0, import_util7.promisify)(import_child_process6.execFile);
139968
+ var execFileAsync21 = (0, import_util7.promisify)(import_child_process6.execFile);
139677
139969
  var OUTPUT_FPS = 30;
139678
139970
  var FFMPEG_FALLBACK_PATHS = [
139679
139971
  "/opt/homebrew/bin/ffmpeg",
@@ -139690,7 +139982,7 @@ var MASK_DARK_MAX_LUMA = 90;
139690
139982
  var MASK_LIGHT_MIN_LUMA = 165;
139691
139983
  async function resolveBinary(name, fallbacks) {
139692
139984
  try {
139693
- await execFileAsync20("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
139985
+ await execFileAsync21("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
139694
139986
  return name;
139695
139987
  } catch {
139696
139988
  }
@@ -140168,7 +140460,7 @@ var zodSchema51 = external_exports.object({
140168
140460
  "Default true. Draw simulator-server's touch visualizer into the recording: a pulse marks each tap, a comet trail follows swipes and drags, and paired markers show two-finger pinch/rotate, so the video makes clear where every interaction landed. Set false to record the raw screen with no overlay."
140169
140461
  )
140170
140462
  });
140171
- var capability26 = {
140463
+ var capability27 = {
140172
140464
  apple: { simulator: true },
140173
140465
  android: { emulator: true, device: true, unknown: true }
140174
140466
  };
@@ -140180,7 +140472,7 @@ function createScreenRecordingStartTool(registry2) {
140180
140472
  completedMsg: () => "Started screen recording",
140181
140473
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to start screen recording: ${failureSignal2.error_code}`
140182
140474
  },
140183
- capability: capability26,
140475
+ capability: capability27,
140184
140476
  description: `Start recording the device screen to a video file (h264 mp4, 30fps at the device's native resolution).
140185
140477
  By default stretches where the screen does not change are trimmed out (see trimStatic), so a long session with only brief activity comes back as a short clip instead of minutes of dead air.
140186
140478
  By default every tap, swipe, drag, pinch and rotate is drawn into the video as an on-screen touch marker (see showTouches), so the recording shows where each interaction landed.
@@ -140200,7 +140492,7 @@ Fails if a recording is already running on the device, the device is not booted,
140200
140492
  async execute(services, params) {
140201
140493
  const api = services.session;
140202
140494
  const device = resolveDevice(params.udid);
140203
- assertSupported("screen-recording-start", capability26, device);
140495
+ assertSupported("screen-recording-start", capability27, device);
140204
140496
  if (device.platform === "ios" && await isTvOsSimulator(params.udid)) {
140205
140497
  throw new FailureError(
140206
140498
  `Screen recording is not supported on tvOS simulators (device ${params.udid}).`,
@@ -140275,7 +140567,7 @@ var zodSchema52 = external_exports.object({
140275
140567
  udid: external_exports.string().describe("Target device id from `list-devices` (iOS Simulator UDID or Android serial).")
140276
140568
  });
140277
140569
  var RECORDINGS_DIR = ".argent/recordings";
140278
- var capability27 = {
140570
+ var capability28 = {
140279
140571
  apple: { simulator: true },
140280
140572
  android: { emulator: true, device: true, unknown: true }
140281
140573
  };
@@ -140286,7 +140578,7 @@ var screenRecordingStopTool = {
140286
140578
  completedMsg: ({ result }) => `Saved screen recording ${result.video.filename}`,
140287
140579
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop screen recording: ${failureSignal2.error_code}`
140288
140580
  },
140289
- capability: capability27,
140581
+ capability: capability28,
140290
140582
  description: `Stop the screen recording started by \`screen-recording-start\` and retrieve the video: frame capture ends and ffmpeg finalizes the mp4.
140291
140583
  Also retrieves the video when the recording already ended on its own (time limit reached, capture process died) \u2014 call it even after the cap fired.
140292
140584
  Use when the interaction being captured is finished, or a tool-result note reminds you a recording is still running.
@@ -140300,7 +140592,7 @@ Fails if no recording (running or finished-but-unretrieved) exists for the given
140300
140592
  async execute(services, params, ctx) {
140301
140593
  const api = services.session;
140302
140594
  const device = resolveDevice(params.udid);
140303
- assertSupported("screen-recording-stop", capability27, device);
140595
+ assertSupported("screen-recording-stop", capability28, device);
140304
140596
  const stopped = await stopCapture(api);
140305
140597
  const artifacts = requireArtifacts(ctx);
140306
140598
  const video = await artifacts.register(stopped.outputFile, {
@@ -142347,7 +142639,7 @@ Returns { stopped } - the URNs of the services that were actually live and got s
142347
142639
 
142348
142640
  // ../tool-server/src/tools/simulator/stop-metro.ts
142349
142641
  init_zod();
142350
- var import_node_child_process26 = require("node:child_process");
142642
+ var import_node_child_process27 = require("node:child_process");
142351
142643
  function parseNetstatListeningPids(netstatOutput, port) {
142352
142644
  const pids = /* @__PURE__ */ new Set();
142353
142645
  for (const line of netstatOutput.split(/\r?\n/)) {
@@ -142363,7 +142655,7 @@ function parseNetstatListeningPids(netstatOutput, port) {
142363
142655
  }
142364
142656
  function listeningPids(port) {
142365
142657
  if (process.platform === "win32") {
142366
- const output2 = (0, import_node_child_process26.execFileSync)("netstat", ["-ano"], {
142658
+ const output2 = (0, import_node_child_process27.execFileSync)("netstat", ["-ano"], {
142367
142659
  encoding: "utf-8",
142368
142660
  timeout: 5e3,
142369
142661
  // `netstat -ano` dumps every socket on the host; a busy box easily
@@ -142373,7 +142665,7 @@ function listeningPids(port) {
142373
142665
  });
142374
142666
  return parseNetstatListeningPids(output2, port);
142375
142667
  }
142376
- const output = (0, import_node_child_process26.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
142668
+ const output = (0, import_node_child_process27.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
142377
142669
  encoding: "utf-8",
142378
142670
  timeout: 5e3
142379
142671
  }).trim();
@@ -142717,6 +143009,12 @@ function selectorTree(sel) {
142717
143009
  walk(sel);
142718
143010
  return out;
142719
143011
  }
143012
+ function blockSteps(step) {
143013
+ return isBlockStep(step) ? step.steps : void 0;
143014
+ }
143015
+ function isBlockStep(step) {
143016
+ return isBlockDirectiveKey(step.kind);
143017
+ }
142720
143018
  function isE2eFlow(flow) {
142721
143019
  const first = flow.steps.find((s) => s.kind !== "echo");
142722
143020
  return first?.kind === "launch";
@@ -143381,6 +143679,10 @@ var STEP_DIRECTIVE_KEYS = [
143381
143679
  "rotate",
143382
143680
  "snapshot"
143383
143681
  ];
143682
+ var BLOCK_DIRECTIVE_KEYS = ["when"];
143683
+ function isBlockDirectiveKey(key2) {
143684
+ return BLOCK_DIRECTIVE_KEYS.includes(key2);
143685
+ }
143384
143686
  function parseTapTimes(raw, entry) {
143385
143687
  if (raw === void 0) return void 0;
143386
143688
  if (typeof raw !== "number" || !Number.isInteger(raw) || raw < 1 || raw > 10) {
@@ -143573,14 +143875,26 @@ function parseWhenCondition(raw) {
143573
143875
  }
143574
143876
  return { kind: "ui", ...cond };
143575
143877
  }
143576
- var MAX_WHEN_DEPTH = 20;
143577
- function parseWhenStep(raw, depth) {
143578
- if (depth >= MAX_WHEN_DEPTH) {
143878
+ var MAX_BLOCK_DEPTH = 20;
143879
+ function assertBlockDepth(raw, depth) {
143880
+ if (depth >= MAX_BLOCK_DEPTH) {
143881
+ const directives = BLOCK_DIRECTIVE_KEYS.map((key2) => `\`${key2}:\``).join("/");
143579
143882
  badEntry(
143580
143883
  raw,
143581
- `when blocks nest deeper than ${MAX_WHEN_DEPTH} levels \u2014 check for a cyclic YAML alias (\`steps: &s \u2026 steps: *s\`)`
143884
+ `${directives} blocks nest deeper than ${MAX_BLOCK_DEPTH} levels \u2014 check for a cyclic YAML alias (\`steps: &s \u2026 steps: *s\`)`
143582
143885
  );
143583
143886
  }
143887
+ }
143888
+ function parseBlockSteps(raw, depth, emptyDetail) {
143889
+ assertBlockDepth(raw, depth);
143890
+ if (!Array.isArray(raw.steps) || raw.steps.length === 0) badEntry(raw, emptyDetail);
143891
+ return raw.steps.map((s) => {
143892
+ if (s !== null && typeof s === "object") return fromYamlStep(s, depth + 1);
143893
+ return badEntry(s, "step must be an object");
143894
+ });
143895
+ }
143896
+ function parseWhenStep(raw, depth) {
143897
+ assertBlockDepth(raw, depth);
143584
143898
  if ("else" in raw) {
143585
143899
  badEntry(
143586
143900
  raw,
@@ -143591,13 +143905,7 @@ function parseWhenStep(raw, depth) {
143591
143905
  badEntry(raw, "a when step takes exactly { when: <condition>, steps: [...] }");
143592
143906
  }
143593
143907
  const condition = parseWhenCondition(raw.when);
143594
- if (!Array.isArray(raw.steps) || raw.steps.length === 0) {
143595
- badEntry(raw, "when needs a non-empty steps list to guard");
143596
- }
143597
- const steps = raw.steps.map((s) => {
143598
- if (s !== null && typeof s === "object") return fromYamlStep(s, depth + 1);
143599
- return badEntry(s, "step must be an object");
143600
- });
143908
+ const steps = parseBlockSteps(raw, depth, "when needs a non-empty steps list to guard");
143601
143909
  return { kind: "when", condition, steps };
143602
143910
  }
143603
143911
  function runTargetName(target) {
@@ -143636,7 +143944,7 @@ function completeRunExtension(value) {
143636
143944
  const candidate = `${value}.yaml`;
143637
143945
  return FLOW_FILE_NAME_PATTERN.test(path31.posix.basename(candidate)) ? candidate : value;
143638
143946
  }
143639
- function fromYamlStep(raw, whenDepth = 0) {
143947
+ function fromYamlStep(raw, blockDepth = 0) {
143640
143948
  const entry = raw;
143641
143949
  if ("optional" in raw) {
143642
143950
  badEntry(
@@ -143659,7 +143967,7 @@ function fromYamlStep(raw, whenDepth = 0) {
143659
143967
  );
143660
143968
  }
143661
143969
  const kind = kinds[0];
143662
- if (kind !== "when") {
143970
+ if (!isBlockDirectiveKey(kind)) {
143663
143971
  const siblings = kind === "tool" ? ["tool", "args", "delayMs"] : [kind];
143664
143972
  const extras = Object.keys(entry).filter((k) => !siblings.includes(k));
143665
143973
  if (extras.length > 0) {
@@ -143672,7 +143980,7 @@ function fromYamlStep(raw, whenDepth = 0) {
143672
143980
  if ("echo" in raw) return { kind: "echo", message: String(raw.echo) };
143673
143981
  if ("launch" in raw) return { kind: "launch", app: parseLaunch(raw.launch) };
143674
143982
  if ("run" in raw) return { kind: "run", flow: parseRunTarget(raw, raw.run) };
143675
- if ("when" in raw) return parseWhenStep(entry, whenDepth);
143983
+ if ("when" in raw) return parseWhenStep(entry, blockDepth);
143676
143984
  if ("tap" in raw) return parseTap(raw.tap, raw);
143677
143985
  if ("long-press" in raw) {
143678
143986
  return parseLongPress(raw["long-press"], raw);
@@ -144388,11 +144696,13 @@ function stepRequiresDevice(registry2, step) {
144388
144696
  }
144389
144697
  }
144390
144698
  function flowRequiresDevice(registry2, steps) {
144391
- return steps.some((step) => stepRequiresDevice(registry2, step));
144699
+ return steps.some(
144700
+ (step) => stepRequiresDevice(registry2, step) || flowRequiresDevice(registry2, blockSteps(step) ?? [])
144701
+ );
144392
144702
  }
144393
144703
  function flowScopesDevice(registry2, steps) {
144394
144704
  return steps.some(
144395
- (step) => step.kind === "tool" && declaresAny(registry2, step.name, DEVICE_BIND_LIST_KEYS)
144705
+ (step) => step.kind === "tool" && declaresAny(registry2, step.name, DEVICE_BIND_LIST_KEYS) || flowScopesDevice(registry2, blockSteps(step) ?? [])
144396
144706
  );
144397
144707
  }
144398
144708
  function toolRequiresDevice(registry2, toolName) {
@@ -146064,7 +146374,7 @@ var import_pngjs3 = __toESM(require_png());
146064
146374
  // ../tool-server/src/tools/screenshot-diff/screenshot-diff-ocr.ts
146065
146375
  var import_child_process8 = require("child_process");
146066
146376
  var import_util8 = require("util");
146067
- var execFileAsync21 = (0, import_util8.promisify)(import_child_process8.execFile);
146377
+ var execFileAsync22 = (0, import_util8.promisify)(import_child_process8.execFile);
146068
146378
  var OCR_TIMEOUT_MS = 1e4;
146069
146379
  var OCR_MAX_BUFFER_BYTES = 32 * 1024 * 1024;
146070
146380
  var TESSERACT_BINARY = "tesseract";
@@ -146109,7 +146419,7 @@ async function extractOcrTextBlocks(imagePath) {
146109
146419
  }
146110
146420
  }
146111
146421
  async function recognizeTsv(imagePath) {
146112
- const { stdout } = await execFileAsync21(
146422
+ const { stdout } = await execFileAsync22(
146113
146423
  TESSERACT_BINARY,
146114
146424
  [
146115
146425
  imagePath,
@@ -148306,15 +148616,15 @@ async function runSnapshot(env, opts) {
148306
148616
  }
148307
148617
 
148308
148618
  // ../tool-server/src/utils/status-bar.ts
148309
- var import_node_child_process27 = require("node:child_process");
148310
- var import_node_util20 = require("node:util");
148619
+ var import_node_child_process28 = require("node:child_process");
148620
+ var import_node_util21 = require("node:util");
148311
148621
  init_adb();
148312
- var execFileAsync22 = (0, import_node_util20.promisify)(import_node_child_process27.execFile);
148622
+ var execFileAsync23 = (0, import_node_util21.promisify)(import_node_child_process28.execFile);
148313
148623
  var DEMO_BROADCAST = "am broadcast -a com.android.systemui.demo";
148314
148624
  async function pinStatusBar(device) {
148315
148625
  try {
148316
148626
  if (device.platform === "ios") {
148317
- await execFileAsync22(
148627
+ await execFileAsync23(
148318
148628
  "xcrun",
148319
148629
  await simctlArgsForUdid(device.id, [
148320
148630
  "status_bar",
@@ -148357,7 +148667,7 @@ async function pinStatusBar(device) {
148357
148667
  async function restoreStatusBar(device) {
148358
148668
  try {
148359
148669
  if (device.platform === "ios") {
148360
- await execFileAsync22(
148670
+ await execFileAsync23(
148361
148671
  "xcrun",
148362
148672
  await simctlArgsForUdid(device.id, ["status_bar", device.id, "clear"])
148363
148673
  );
@@ -148662,7 +148972,8 @@ function displayFlowName(params) {
148662
148972
  function* walkSteps(steps) {
148663
148973
  for (const step of steps) {
148664
148974
  yield step;
148665
- if (step.kind === "when") yield* walkSteps(step.steps);
148975
+ const inner = blockSteps(step);
148976
+ if (inner) yield* walkSteps(inner);
148666
148977
  }
148667
148978
  }
148668
148979
  function assertUploadSelfContained(flow) {
@@ -149063,8 +149374,18 @@ function stepTarget(step) {
149063
149374
  return step.cropOn ? `"${step.name}" cropOn ${selectorLabel2(step.cropOn)}` : `"${step.name}"`;
149064
149375
  case "run":
149065
149376
  return step.flow;
149066
- default:
149377
+ case "echo":
149378
+ case "tool":
149379
+ return void 0;
149380
+ case "launch":
149067
149381
  return void 0;
149382
+ case "wait":
149383
+ return void 0;
149384
+ default: {
149385
+ const unclassified = step;
149386
+ void unclassified;
149387
+ return void 0;
149388
+ }
149068
149389
  }
149069
149390
  }
149070
149391
  function scopeFlow(scope) {
@@ -149106,7 +149427,8 @@ async function execSteps(state3, steps, scope) {
149106
149427
  // line rather than vanishing — matching reportBlockSkipped.
149107
149428
  ...step.kind === "echo" ? { message: step.message } : {}
149108
149429
  });
149109
- if (step.kind === "when") reportBlockSkipped(state3, step.steps, childScope(scope));
149430
+ const inner = blockSteps(step);
149431
+ if (inner) reportBlockSkipped(state3, inner, childScope(scope));
149110
149432
  continue;
149111
149433
  }
149112
149434
  if (!state3.device && stepRequiresDevice(state3.registry, step)) {
@@ -149120,7 +149442,8 @@ async function execSteps(state3, steps, scope) {
149120
149442
  ...depthOf(scope),
149121
149443
  reason: `step needs a device but the flow was resolved as device-free \u2014 pass an explicit device`
149122
149444
  });
149123
- if (step.kind === "when") reportBlockSkipped(state3, step.steps, childScope(scope));
149445
+ const inner = blockSteps(step);
149446
+ if (inner) reportBlockSkipped(state3, inner, childScope(scope));
149124
149447
  continue;
149125
149448
  }
149126
149449
  if (state3.signal?.aborted) {
@@ -149135,17 +149458,16 @@ async function execSteps(state3, steps, scope) {
149135
149458
  ...depthOf(scope),
149136
149459
  ...step.kind === "echo" ? { message: step.message } : {}
149137
149460
  });
149138
- if (step.kind === "when") {
149139
- reportBlockSkipped(state3, step.steps, childScope(scope), "run aborted");
149140
- }
149461
+ const inner = blockSteps(step);
149462
+ if (inner) reportBlockSkipped(state3, inner, childScope(scope), "run aborted");
149141
149463
  continue;
149142
149464
  }
149143
149465
  if (step.kind === "run") {
149144
149466
  await execRunStep(state3, step, scope);
149145
149467
  continue;
149146
149468
  }
149147
- if (step.kind === "when") {
149148
- await execWhenStep(state3, step, scope);
149469
+ if (isBlockStep(step)) {
149470
+ await execBlockStep(state3, step, scope);
149149
149471
  continue;
149150
149472
  }
149151
149473
  const report = await execLeafStep(state3, step, index, scope);
@@ -149169,7 +149491,18 @@ function reportBlockSkipped(state3, steps, scope, reason) {
149169
149491
  ...depthOf(scope),
149170
149492
  ...step.kind === "echo" ? { message: step.message } : {}
149171
149493
  });
149172
- if (step.kind === "when") reportBlockSkipped(state3, step.steps, childScope(scope), reason);
149494
+ const inner = blockSteps(step);
149495
+ if (inner) reportBlockSkipped(state3, inner, childScope(scope), reason);
149496
+ }
149497
+ }
149498
+ async function execBlockStep(state3, step, scope) {
149499
+ switch (step.kind) {
149500
+ case "when":
149501
+ return execWhenStep(state3, step, scope);
149502
+ default: {
149503
+ const unhandled = step.kind;
149504
+ void unhandled;
149505
+ }
149173
149506
  }
149174
149507
  }
149175
149508
  async function execWhenStep(state3, step, scope) {
@@ -149619,7 +149952,7 @@ init_zod();
149619
149952
  // ../tool-server/src/utils/workspace-reader.ts
149620
149953
  var import_promises12 = require("node:fs/promises");
149621
149954
  var import_node_path21 = require("node:path");
149622
- var import_node_child_process28 = require("node:child_process");
149955
+ var import_node_child_process29 = require("node:child_process");
149623
149956
  var import_dotenv2 = __toESM(require_main());
149624
149957
  async function exists(path40) {
149625
149958
  try {
@@ -149663,7 +149996,7 @@ async function listDir(path40) {
149663
149996
  var COMMAND_TIMEOUT_MS = 3e3;
149664
149997
  function runVersionCommand(cmd, args, cwd) {
149665
149998
  return new Promise((resolve11) => {
149666
- const child = (0, import_node_child_process28.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
149999
+ const child = (0, import_node_child_process29.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
149667
150000
  if (err) {
149668
150001
  resolve11(null);
149669
150002
  return;
@@ -149952,7 +150285,7 @@ Fails if the workspacePath is not an absolute path or the directory cannot be ac
149952
150285
  };
149953
150286
 
149954
150287
  // ../tool-server/src/tools/system/update-argent.ts
149955
- var import_node_child_process29 = require("node:child_process");
150288
+ var import_node_child_process30 = require("node:child_process");
149956
150289
  var fs51 = __toESM(require("node:fs"));
149957
150290
  var path36 = __toESM(require("node:path"));
149958
150291
  init_zod();
@@ -150087,7 +150420,7 @@ var updateArgentTool = {
150087
150420
  if (spawnRoot) updateArgs.push("--project-root", spawnRoot);
150088
150421
  const cmd = cliEntry ? process.execPath : "argent";
150089
150422
  const args = cliEntry ? [cliEntry, ...updateArgs] : updateArgs;
150090
- const child = (0, import_node_child_process29.spawn)(cmd, args, {
150423
+ const child = (0, import_node_child_process30.spawn)(cmd, args, {
150091
150424
  detached: true,
150092
150425
  stdio: "ignore",
150093
150426
  env: { ...process.env, ARGENT_UPDATE_TRIGGER: "mcp_update" }
@@ -150160,7 +150493,7 @@ var zodSchema70 = external_exports.object({
150160
150493
  "Directory where diff artifacts should be written. Optional \u2014 defaults to a temp directory; the diff images are returned in the result either way."
150161
150494
  )
150162
150495
  }).strict();
150163
- var capability28 = {
150496
+ var capability29 = {
150164
150497
  apple: { simulator: true, device: true },
150165
150498
  android: { emulator: true, device: true, unknown: true }
150166
150499
  };
@@ -150185,7 +150518,7 @@ Ignores the fixed top status-bar band for both pixel and OCR text comparisons.
150185
150518
  Fails if the input sources are invalid, PNG files cannot be read, outputDir cannot be written, or the simulator-server / emulator backend is not reachable.`,
150186
150519
  searchHint: "compare screenshots png diff visual UI changes UI regression visual regression screenshot diff changed regions text ocr live capture",
150187
150520
  zodSchema: zodSchema70,
150188
- capability: capability28,
150521
+ capability: capability29,
150189
150522
  fileInputs: fileInputs6,
150190
150523
  services: (params) => {
150191
150524
  if (params.captureBaseline || params.captureCurrent) {
@@ -150576,7 +150909,7 @@ var tabAction = {
150576
150909
  failure: "close"
150577
150910
  }
150578
150911
  };
150579
- var capability29 = {
150912
+ var capability30 = {
150580
150913
  chromium: { app: true }
150581
150914
  };
150582
150915
  var chromiumTabsTool = {
@@ -150595,7 +150928,7 @@ Use when an app exposes multiple windows or tabs and you need to inspect or driv
150595
150928
  Returns { tabs: [{ tabId, targetId, title, url, active, label? }] }. Fails if the device is not a Chromium (CDP) device, or the requested tabId/label no longer matches a live tab. Chromium-only.`,
150596
150929
  searchHint: "tab tabs window windows switch select close new open multi-tab chromium electron",
150597
150930
  zodSchema: zodSchema73,
150598
- capability: capability29,
150931
+ capability: capability30,
150599
150932
  services: (params) => {
150600
150933
  const device = resolveDevice(params.udid);
150601
150934
  if (device.platform === "chromium") {
@@ -150718,7 +151051,7 @@ var cookieAction = {
150718
151051
  delete: { started: "Deleting", completed: "Deleted", failure: "delete" },
150719
151052
  clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
150720
151053
  };
150721
- var capability30 = {
151054
+ var capability31 = {
150722
151055
  chromium: { app: true }
150723
151056
  };
150724
151057
  var chromiumCookiesTool = {
@@ -150737,7 +151070,7 @@ Use when seeding an authenticated session before a flow (set the session cookie,
150737
151070
  Returns { cookies, count } for get, or a small status object ({ set } / { deleted } / { cleared }) otherwise. Fails if the device is not a Chromium (CDP) device, or set is missing name/value. Chromium-only.`,
150738
151071
  searchHint: "cookies cookie get set delete clear httponly samesite session auth chromium",
150739
151072
  zodSchema: zodSchema74,
150740
- capability: capability30,
151073
+ capability: capability31,
150741
151074
  services: (params) => {
150742
151075
  const device = resolveDevice(params.udid);
150743
151076
  if (device.platform === "chromium") {
@@ -150816,7 +151149,7 @@ var storageAction = {
150816
151149
  remove: { started: "Removing from", completed: "Removed from", failure: "remove from" },
150817
151150
  clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
150818
151151
  };
150819
- var capability31 = {
151152
+ var capability32 = {
150820
151153
  chromium: { app: true }
150821
151154
  };
150822
151155
  var chromiumStorageTool = {
@@ -150836,7 +151169,7 @@ Use when seeding feature flags / auth tokens before a flow or asserting persiste
150836
151169
  Returns { value } for a single key, { entries, count } for all, or a status object ({ set } / { removed } / { cleared }) otherwise. Fails if the device is not a Chromium (CDP) device, or set is missing key/value. Chromium-only.`,
150837
151170
  searchHint: "storage localstorage sessionstorage local session get set remove clear key value chromium",
150838
151171
  zodSchema: zodSchema75,
150839
- capability: capability31,
151172
+ capability: capability32,
150840
151173
  services: (params) => {
150841
151174
  const device = resolveDevice(params.udid);
150842
151175
  if (device.platform === "chromium") {
@@ -150925,6 +151258,7 @@ function createRegistry() {
150925
151258
  registry2.registerTool(buttonTool);
150926
151259
  registry2.registerTool(createKeyboardTool(registry2));
150927
151260
  registry2.registerTool(rotateTool);
151261
+ registry2.registerTool(shakeTool);
150928
151262
  registry2.registerTool(createTvRemoteTool(registry2));
150929
151263
  registry2.registerTool(createRunSequenceTool(registry2));
150930
151264
  registry2.registerTool(debuggerConnectTool);
@@ -151004,12 +151338,12 @@ function probeArgentToolServer(host, port, timeoutMs = 500) {
151004
151338
 
151005
151339
  // ../tool-server/src/utils/simulator-watcher.ts
151006
151340
  var fs53 = __toESM(require("node:fs"));
151007
- var import_node_child_process30 = require("node:child_process");
151008
- var import_node_util21 = require("node:util");
151009
- var execFileAsync23 = (0, import_node_util21.promisify)(import_node_child_process30.execFile);
151341
+ var import_node_child_process31 = require("node:child_process");
151342
+ var import_node_util22 = require("node:util");
151343
+ var execFileAsync24 = (0, import_node_util22.promisify)(import_node_child_process31.execFile);
151010
151344
  var POLL_INTERVAL_MS2 = 1e4;
151011
151345
  async function getBootedUdidsInSet(deviceSet) {
151012
- const { stdout } = await execFileAsync23("xcrun", [
151346
+ const { stdout } = await execFileAsync24("xcrun", [
151013
151347
  ...simctlPrefix(deviceSet),
151014
151348
  "list",
151015
151349
  "devices",
@@ -151082,7 +151416,7 @@ function startSimulatorWatcher(registry2) {
151082
151416
  }
151083
151417
 
151084
151418
  // ../tool-server/src/utils/preview-window.ts
151085
- var import_node_child_process31 = require("node:child_process");
151419
+ var import_node_child_process32 = require("node:child_process");
151086
151420
  var fs54 = __toESM(require("node:fs"));
151087
151421
  var os14 = __toESM(require("node:os"));
151088
151422
  var path38 = __toESM(require("node:path"));
@@ -151114,10 +151448,10 @@ function ensureLensAppBundle(electronBin) {
151114
151448
  fs54.copyFileSync(path38.join(realContents, "Info.plist"), plist);
151115
151449
  const setPlist = (entry, value) => {
151116
151450
  try {
151117
- (0, import_node_child_process31.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
151451
+ (0, import_node_child_process32.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
151118
151452
  } catch {
151119
151453
  try {
151120
- (0, import_node_child_process31.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
151454
+ (0, import_node_child_process32.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
151121
151455
  } catch {
151122
151456
  }
151123
151457
  }
@@ -151176,7 +151510,7 @@ function createPreviewWindowManager(opts = {}) {
151176
151510
  const wrapperBin = ensureLensAppBundle(electronBin);
151177
151511
  const launchBin = wrapperBin ?? electronBin;
151178
151512
  const launchArgs = wrapperBin ? ["--no-sandbox", mainScript] : [mainScript];
151179
- const next = (0, import_node_child_process31.spawn)(launchBin, launchArgs, {
151513
+ const next = (0, import_node_child_process32.spawn)(launchBin, launchArgs, {
151180
151514
  // Strip ELECTRON_RUN_AS_NODE so the child boots as a GUI Electron app, not
151181
151515
  // a bare Node runtime (see electronGuiChildEnv). An Electron-based MCP
151182
151516
  // host puts it in our env, and inheriting it makes main.cjs crash at
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.20.1-next.5",
3
+ "version": "0.20.1-next.7",
4
4
  "mcpName": "io.github.software-mansion/argent",
5
5
  "description": "MCP server for iOS Simulator and Android Emulator control",
6
6
  "license": "Apache-2.0",
@@ -74,6 +74,7 @@ Common schemes: `messages://`, `settings://`, `maps://?q=<query>`, `tel://<numbe
74
74
  | Hardware key | `button` | Home, back, power, volume, appSwitch, actionButton |
75
75
  | Type text | `keyboard` | Every platform. Supports Enter, Escape, arrows (not on TV) |
76
76
  | Rotate device | `rotate` | Orientation changes |
77
+ | Shake device | `shake` | Shake handlers (sim/emu only), Undo-typing prompt, RN dev menu |
77
78
  | Wait for UI | `await-ui-element` | Block until an element is visible/hidden/exists/contains text |
78
79
  | Wait for idle | `await-screen-idle` | Block until a non-empty screen tree stops changing |
79
80