@swmansion/argent 0.25.2-next.1 → 0.25.2-next.10

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
@@ -21872,7 +21872,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
21872
21872
  var SESSION_ID2 = randomUUID5();
21873
21873
  function readCliVersion() {
21874
21874
  if (true) {
21875
- return "0.25.2-next.1";
21875
+ return "0.25.2-next.10";
21876
21876
  }
21877
21877
  return "0.0.0";
21878
21878
  }
@@ -23182,6 +23182,13 @@ function stepIndent(depth) {
23182
23182
  if (typeof depth !== "number" || !Number.isInteger(depth) || depth <= 0) return "";
23183
23183
  return " ".repeat(Math.min(depth, MAX_RENDER_DEPTH));
23184
23184
  }
23185
+ function durationSuffix(ms) {
23186
+ if (typeof ms !== "number" || !Number.isFinite(ms) || ms < 0) return "";
23187
+ const tenths = Math.round(ms / 100);
23188
+ if (tenths < 600) return ` (${(tenths / 10).toFixed(1)}s)`;
23189
+ const seconds = Math.round(ms / 1e3);
23190
+ return ` (${Math.floor(seconds / 60)}m ${seconds % 60}s)`;
23191
+ }
23185
23192
  function printHelp(toStderr = false) {
23186
23193
  const print = toStderr ? console.error : console.log;
23187
23194
  print(`Usage: argent flow <subcommand> [options]
@@ -23305,7 +23312,7 @@ function renderStepLine(s, n2, topFlow) {
23305
23312
  const label = what ? `${s.kind} ${what}` : s.kind;
23306
23313
  const reason = s.reason ? ` \u2014 ${s.reason}` : "";
23307
23314
  const glyph = s.status === "pass" && s.warning ? "\u26A0" : STATUS_GLYPH[s.status];
23308
- return ` ${glyph} ${String(n2).padStart(2)} ${stepIndent(s.depth)}${label}${where}${reason}`;
23315
+ return ` ${glyph} ${String(n2).padStart(2)} ${stepIndent(s.depth)}${label}${where}${durationSuffix(s.durationMs)}${reason}`;
23309
23316
  }
23310
23317
  function renderUnderStepLine(s, n2, text2) {
23311
23318
  return `${" ".repeat(5 + Math.max(2, String(n2).length))}${stepIndent(s.depth)}${text2}`;
@@ -23328,7 +23335,7 @@ function renderSummary(report, opts = {}) {
23328
23335
  const where = opts.withDevice && report.device ? ` (started on ${report.device})` : "";
23329
23336
  const nothingCounted = report.ok && report.passed + report.failed + report.errored + report.skipped === 0;
23330
23337
  const note = nothingCounted ? " (no test steps)" : "";
23331
- return `${report.ok ? "PASS" : "FAIL"}${where} \u2014 ${report.passed} passed, ${report.failed} failed, ${report.errored} errored, ${report.skipped} skipped${warningsNote}${note}`;
23338
+ return `${report.ok ? "PASS" : "FAIL"}${where} \u2014 ${report.passed} passed, ${report.failed} failed, ${report.errored} errored, ${report.skipped} skipped${warningsNote}${note}${durationSuffix(report.durationMs)}`;
23332
23339
  }
23333
23340
  function renderArtifactLines(report) {
23334
23341
  const lines = [];
@@ -23366,8 +23373,8 @@ function renderFailedSteps(report) {
23366
23373
  }
23367
23374
  return lines;
23368
23375
  }
23369
- function renderBatchSummary(counts) {
23370
- return `${counts.failed === 0 ? "PASS" : "FAIL"} \u2014 ${counts.total} flow${counts.total === 1 ? "" : "s"}: ${counts.passed} passed, ${counts.failed} failed, ${counts.skipped} skipped`;
23376
+ function renderBatchSummary(counts, durationMs) {
23377
+ return `${counts.failed === 0 ? "PASS" : "FAIL"} \u2014 ${counts.total} flow${counts.total === 1 ? "" : "s"}: ${counts.passed} passed, ${counts.failed} failed, ${counts.skipped} skipped${durationSuffix(durationMs)}`;
23371
23378
  }
23372
23379
  var SAFE_ARTIFACT_NAME = FLOW_NAME_PATTERN;
23373
23380
  var SAFE_FLOW_NAME = FLOW_NAME_PATTERN;
@@ -23682,6 +23689,7 @@ async function runFlowDirectory(dir, args, projectRoot, options) {
23682
23689
  const { callTool, baseUrl } = createToolsClient({ paths: options.paths });
23683
23690
  const outputBase = args.output ? path14.resolve(args.output) : void 0;
23684
23691
  const results = [];
23692
+ const batchStartedAt = Date.now();
23685
23693
  let stopped = false;
23686
23694
  for (const [i2, rel] of flows.entries()) {
23687
23695
  if (!args.json) console.log(`[${i2 + 1}/${flows.length}] ${rel}`);
@@ -23737,11 +23745,14 @@ async function runFlowDirectory(dir, args, projectRoot, options) {
23737
23745
  failed: results.filter((r2) => r2.status === "fail").length,
23738
23746
  skipped: results.filter((r2) => r2.status === "skip").length
23739
23747
  };
23748
+ const durationMs = Date.now() - batchStartedAt;
23740
23749
  if (args.json) {
23741
- console.log(JSON.stringify({ ok: counts.failed === 0, ...counts, flows: results }, null, 2));
23750
+ console.log(
23751
+ JSON.stringify({ ok: counts.failed === 0, ...counts, durationMs, flows: results }, null, 2)
23752
+ );
23742
23753
  } else {
23743
23754
  console.log(`
23744
- ${renderBatchSummary(counts)}`);
23755
+ ${renderBatchSummary(counts, durationMs)}`);
23745
23756
  }
23746
23757
  return exitAfterFlush(counts.failed === 0 ? 0 : 1);
23747
23758
  }
@@ -25795,12 +25806,25 @@ function reportError(err, suggest) {
25795
25806
  }
25796
25807
  process.exit(2);
25797
25808
  }
25809
+ function wrapText(text2, indent, width = 80) {
25810
+ const lines = [];
25811
+ let line = "";
25812
+ for (const word of text2.split(/\s+/).filter(Boolean)) {
25813
+ if (line && indent.length + line.length + 1 + word.length > width) {
25814
+ lines.push(indent + line);
25815
+ line = word;
25816
+ } else {
25817
+ line = line ? `${line} ${word}` : word;
25818
+ }
25819
+ }
25820
+ if (line) lines.push(indent + line);
25821
+ return lines;
25822
+ }
25798
25823
  function printUsage() {
25799
- const keys = CONFIG_SCHEMA.map((d) => d.key);
25800
- const maxKey = keys.reduce((m, k) => Math.max(m, k.length), 0);
25801
25824
  const keyLines = CONFIG_SCHEMA.map((d) => {
25802
- const managed = d.manageCommand ? import_picocolors2.default.dim(` [managed by \`${d.manageCommand}\`]`) : "";
25803
- return ` ${d.key.padEnd(maxKey)} ${d.description}${managed}`;
25825
+ const lines = [` ${d.key}`, ...wrapText(d.description, " ")];
25826
+ if (d.manageCommand) lines.push(import_picocolors2.default.dim(` [managed by \`${d.manageCommand}\`]`));
25827
+ return lines.join("\n");
25804
25828
  });
25805
25829
  console.log(`Usage: argent config <command> [options]
25806
25830
 
@@ -25816,7 +25840,7 @@ Commands:
25816
25840
  unset <key> Remove a value at a scope (default global)
25817
25841
 
25818
25842
  Recognized keys:
25819
- ${keyLines.join("\n")}
25843
+ ${keyLines.join("\n\n")}
25820
25844
 
25821
25845
  Run \`argent config <command> --help\` for command-specific help.`);
25822
25846
  }
@@ -16725,7 +16725,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
16725
16725
  var SESSION_ID = randomUUID4();
16726
16726
  function readCliVersion() {
16727
16727
  if (true) {
16728
- return "0.25.2-next.1";
16728
+ return "0.25.2-next.10";
16729
16729
  }
16730
16730
  return "0.0.0";
16731
16731
  }
@@ -18542,6 +18542,13 @@ function stepIndent(depth) {
18542
18542
  if (typeof depth !== "number" || !Number.isInteger(depth) || depth <= 0) return "";
18543
18543
  return " ".repeat(Math.min(depth, MAX_RENDER_DEPTH));
18544
18544
  }
18545
+ function durationSuffix(ms) {
18546
+ if (typeof ms !== "number" || !Number.isFinite(ms) || ms < 0) return "";
18547
+ const tenths = Math.round(ms / 100);
18548
+ if (tenths < 600) return ` (${(tenths / 10).toFixed(1)}s)`;
18549
+ const seconds = Math.round(ms / 1e3);
18550
+ return ` (${Math.floor(seconds / 60)}m ${seconds % 60}s)`;
18551
+ }
18545
18552
  function stepLabel(step) {
18546
18553
  if (step.kind === "echo") return step.message ?? "";
18547
18554
  if (step.tool) return step.tool;
@@ -18565,9 +18572,10 @@ async function flowRunToMcpContent(result, ctx) {
18565
18572
  const reason = step.reason ?? step.error;
18566
18573
  const suffix = reason ? ` \u2014 ${reason}` : "";
18567
18574
  const warning = step.warning ? ` \u26A0 ${step.warning}` : "";
18575
+ const timing = step.kind === "echo" ? "" : durationSuffix(step.durationMs);
18568
18576
  blocks.push({
18569
18577
  type: "text",
18570
- text: `[${num}] ${glyph}${stepIndent(step.depth)}${stepLabel(step)}${suffix}${warning}`
18578
+ text: `[${num}] ${glyph}${stepIndent(step.depth)}${stepLabel(step)}${timing}${suffix}${warning}`
18571
18579
  });
18572
18580
  const scriptLog = typeof step.scriptLog === "string" ? step.scriptLog : "";
18573
18581
  const scriptLogTruncated = step.scriptLogTruncated === true;
@@ -18589,7 +18597,7 @@ async function flowRunToMcpContent(result, ctx) {
18589
18597
  const note = result.ok && counted === 0 ? " (no test steps)" : "";
18590
18598
  blocks.push({
18591
18599
  type: "text",
18592
- text: `${result.ok ? "PASS" : "FAIL"} \u2014 ${result.passed ?? 0} passed, ${result.failed ?? 0} failed, ${result.errored ?? 0} errored, ${result.skipped ?? 0} skipped${note}`
18600
+ text: `${result.ok ? "PASS" : "FAIL"} \u2014 ${result.passed ?? 0} passed, ${result.failed ?? 0} failed, ${result.errored ?? 0} errored, ${result.skipped ?? 0} skipped${note}${durationSuffix(result.durationMs)}`
18593
18601
  });
18594
18602
  } else {
18595
18603
  blocks.push({ type: "text", text: `Flow "${result.flow}" complete.` });
@@ -7599,51 +7599,51 @@ var init_he = __esm({
7599
7599
  }
7600
7600
  case "too_big": {
7601
7601
  const sizing = getSizing(issue2.origin);
7602
- const subject = withDefinite(issue2.origin ?? "value");
7602
+ const subject2 = withDefinite(issue2.origin ?? "value");
7603
7603
  if (issue2.origin === "string") {
7604
- return `${sizing?.longLabel ?? "\u05D0\u05E8\u05D5\u05DA"} \u05DE\u05D3\u05D9: ${subject} \u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05DB\u05D9\u05DC ${issue2.maximum.toString()} ${sizing?.unit ?? ""} ${issue2.inclusive ? "\u05D0\u05D5 \u05E4\u05D7\u05D5\u05EA" : "\u05DC\u05DB\u05DC \u05D4\u05D9\u05D5\u05EA\u05E8"}`.trim();
7604
+ return `${sizing?.longLabel ?? "\u05D0\u05E8\u05D5\u05DA"} \u05DE\u05D3\u05D9: ${subject2} \u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05DB\u05D9\u05DC ${issue2.maximum.toString()} ${sizing?.unit ?? ""} ${issue2.inclusive ? "\u05D0\u05D5 \u05E4\u05D7\u05D5\u05EA" : "\u05DC\u05DB\u05DC \u05D4\u05D9\u05D5\u05EA\u05E8"}`.trim();
7605
7605
  }
7606
7606
  if (issue2.origin === "number") {
7607
7607
  const comparison = issue2.inclusive ? `\u05E7\u05D8\u05DF \u05D0\u05D5 \u05E9\u05D5\u05D5\u05D4 \u05DC-${issue2.maximum}` : `\u05E7\u05D8\u05DF \u05DE-${issue2.maximum}`;
7608
- return `\u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9: ${subject} \u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA ${comparison}`;
7608
+ return `\u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9: ${subject2} \u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA ${comparison}`;
7609
7609
  }
7610
7610
  if (issue2.origin === "array" || issue2.origin === "set") {
7611
7611
  const verb = issue2.origin === "set" ? "\u05E6\u05E8\u05D9\u05DB\u05D4" : "\u05E6\u05E8\u05D9\u05DA";
7612
7612
  const comparison = issue2.inclusive ? `${issue2.maximum} ${sizing?.unit ?? ""} \u05D0\u05D5 \u05E4\u05D7\u05D5\u05EA` : `\u05E4\u05D7\u05D5\u05EA \u05DE-${issue2.maximum} ${sizing?.unit ?? ""}`;
7613
- return `\u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9: ${subject} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${comparison}`.trim();
7613
+ return `\u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9: ${subject2} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${comparison}`.trim();
7614
7614
  }
7615
7615
  const adj = issue2.inclusive ? "<=" : "<";
7616
7616
  const be = verbFor(issue2.origin ?? "value");
7617
7617
  if (sizing?.unit) {
7618
- return `${sizing.longLabel} \u05DE\u05D3\u05D9: ${subject} ${be} ${adj}${issue2.maximum.toString()} ${sizing.unit}`;
7618
+ return `${sizing.longLabel} \u05DE\u05D3\u05D9: ${subject2} ${be} ${adj}${issue2.maximum.toString()} ${sizing.unit}`;
7619
7619
  }
7620
- return `${sizing?.longLabel ?? "\u05D2\u05D3\u05D5\u05DC"} \u05DE\u05D3\u05D9: ${subject} ${be} ${adj}${issue2.maximum.toString()}`;
7620
+ return `${sizing?.longLabel ?? "\u05D2\u05D3\u05D5\u05DC"} \u05DE\u05D3\u05D9: ${subject2} ${be} ${adj}${issue2.maximum.toString()}`;
7621
7621
  }
7622
7622
  case "too_small": {
7623
7623
  const sizing = getSizing(issue2.origin);
7624
- const subject = withDefinite(issue2.origin ?? "value");
7624
+ const subject2 = withDefinite(issue2.origin ?? "value");
7625
7625
  if (issue2.origin === "string") {
7626
- return `${sizing?.shortLabel ?? "\u05E7\u05E6\u05E8"} \u05DE\u05D3\u05D9: ${subject} \u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05DB\u05D9\u05DC ${issue2.minimum.toString()} ${sizing?.unit ?? ""} ${issue2.inclusive ? "\u05D0\u05D5 \u05D9\u05D5\u05EA\u05E8" : "\u05DC\u05E4\u05D7\u05D5\u05EA"}`.trim();
7626
+ return `${sizing?.shortLabel ?? "\u05E7\u05E6\u05E8"} \u05DE\u05D3\u05D9: ${subject2} \u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05DB\u05D9\u05DC ${issue2.minimum.toString()} ${sizing?.unit ?? ""} ${issue2.inclusive ? "\u05D0\u05D5 \u05D9\u05D5\u05EA\u05E8" : "\u05DC\u05E4\u05D7\u05D5\u05EA"}`.trim();
7627
7627
  }
7628
7628
  if (issue2.origin === "number") {
7629
7629
  const comparison = issue2.inclusive ? `\u05D2\u05D3\u05D5\u05DC \u05D0\u05D5 \u05E9\u05D5\u05D5\u05D4 \u05DC-${issue2.minimum}` : `\u05D2\u05D3\u05D5\u05DC \u05DE-${issue2.minimum}`;
7630
- return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject} \u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA ${comparison}`;
7630
+ return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject2} \u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA ${comparison}`;
7631
7631
  }
7632
7632
  if (issue2.origin === "array" || issue2.origin === "set") {
7633
7633
  const verb = issue2.origin === "set" ? "\u05E6\u05E8\u05D9\u05DB\u05D4" : "\u05E6\u05E8\u05D9\u05DA";
7634
7634
  if (issue2.minimum === 1 && issue2.inclusive) {
7635
7635
  const singularPhrase = issue2.origin === "set" ? "\u05DC\u05E4\u05D7\u05D5\u05EA \u05E4\u05E8\u05D9\u05D8 \u05D0\u05D7\u05D3" : "\u05DC\u05E4\u05D7\u05D5\u05EA \u05E4\u05E8\u05D9\u05D8 \u05D0\u05D7\u05D3";
7636
- return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${singularPhrase}`;
7636
+ return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject2} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${singularPhrase}`;
7637
7637
  }
7638
7638
  const comparison = issue2.inclusive ? `${issue2.minimum} ${sizing?.unit ?? ""} \u05D0\u05D5 \u05D9\u05D5\u05EA\u05E8` : `\u05D9\u05D5\u05EA\u05E8 \u05DE-${issue2.minimum} ${sizing?.unit ?? ""}`;
7639
- return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${comparison}`.trim();
7639
+ return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject2} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${comparison}`.trim();
7640
7640
  }
7641
7641
  const adj = issue2.inclusive ? ">=" : ">";
7642
7642
  const be = verbFor(issue2.origin ?? "value");
7643
7643
  if (sizing?.unit) {
7644
- return `${sizing.shortLabel} \u05DE\u05D3\u05D9: ${subject} ${be} ${adj}${issue2.minimum.toString()} ${sizing.unit}`;
7644
+ return `${sizing.shortLabel} \u05DE\u05D3\u05D9: ${subject2} ${be} ${adj}${issue2.minimum.toString()} ${sizing.unit}`;
7645
7645
  }
7646
- return `${sizing?.shortLabel ?? "\u05E7\u05D8\u05DF"} \u05DE\u05D3\u05D9: ${subject} ${be} ${adj}${issue2.minimum.toString()}`;
7646
+ return `${sizing?.shortLabel ?? "\u05E7\u05D8\u05DF"} \u05DE\u05D3\u05D9: ${subject2} ${be} ${adj}${issue2.minimum.toString()}`;
7647
7647
  }
7648
7648
  case "invalid_format": {
7649
7649
  const _issue = issue2;
@@ -70657,8 +70657,13 @@ function defaultAndroidRoots() {
70657
70657
  "/opt/android-sdk",
70658
70658
  "/usr/lib/android-sdk",
70659
70659
  // Debian/Ubuntu `android-sdk` apt package
70660
- "/usr/local/share/android-sdk"
70661
- // Homebrew cask
70660
+ "/usr/local/share/android-sdk",
70661
+ // Homebrew cask (Intel prefix)
70662
+ // Where `brew install --cask android-commandlinetools` roots the SDK, so an
70663
+ // `sdkmanager`-installed platform-tools is found without setting ANDROID_HOME
70664
+ // — otherwise following the missing-adb hint still leaves the tool failing.
70665
+ "/opt/homebrew/share/android-commandlinetools",
70666
+ "/usr/local/share/android-commandlinetools"
70662
70667
  ];
70663
70668
  if (process.platform === "win32") {
70664
70669
  const localAppData = process.env.LOCALAPPDATA?.trim();
@@ -94799,7 +94804,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
94799
94804
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
94800
94805
  function readCliVersion() {
94801
94806
  if (true) {
94802
- return "0.25.2-next.1";
94807
+ return "0.25.2-next.10";
94803
94808
  }
94804
94809
  return "0.0.0";
94805
94810
  }
@@ -96058,8 +96063,8 @@ var DependencyMissingError = class extends Error {
96058
96063
  var CACHE_TTL_MS2 = 6e4;
96059
96064
  var cache3 = /* @__PURE__ */ new Map();
96060
96065
  var INSTALL_HINTS = {
96061
- "xcrun": "Xcode command-line tools are not installed. Run `xcode-select --install` (or install Xcode from the App Store) and retry. Only required for iOS simulators.",
96062
- "adb": "Android SDK Platform Tools not found. Install with `brew install --cask android-platform-tools` or via Android Studio \u2192 SDK Manager. If installed, ensure `adb` is on PATH or point `$ANDROID_HOME` (or the `android.sdkRoot` config key) at the SDK root (the resolver checks `<root>/platform-tools/adb`). Only required for Android devices and emulators.",
96066
+ "xcrun": "Xcode command-line tools not found \u2014 iOS/tvOS simulators need a macOS host with them installed. On macOS, run `xcode-select --install` (or install Xcode from the App Store) and retry.",
96067
+ "adb": "Android SDK Platform Tools not found. Install `platform-tools` via Android Studio \u2192 SDK Manager or `sdkmanager 'platform-tools'` (`brew install --cask android-platform-tools` on macOS). If installed, ensure `adb` is on PATH or point `$ANDROID_HOME` (or the `android.sdkRoot` config key) at the SDK root (the resolver checks `<root>/platform-tools/adb`). Only required for Android devices and emulators.",
96063
96068
  "emulator": "Android Emulator not found. Install via Android Studio \u2192 SDK Manager \u2192 Emulator, or `sdkmanager 'emulator'`. If installed, ensure `emulator` is on PATH or point `$ANDROID_HOME` (or the `android.sdkRoot` config key) at the SDK root (the resolver checks `<root>/emulator/emulator`). Only required to launch new Android emulators via `boot-device`.",
96064
96069
  "sim-remote": "`sim-remote` CLI not found on PATH. Install via the radon-cloud project (see its README) and run `sim-remote login` before invoking any ios-remote tool. Only required for remote iOS simulators.",
96065
96070
  "vega": "Vega SDK CLI not found. Install the Amazon Vega SDK and run `source ~/vega/env` so `vega` (or its `kepler` alias) is on PATH; the resolver also checks `~/vega/bin/vega`. Only required for Vega (Fire TV) devices."
@@ -96335,8 +96340,8 @@ async function listCertificatePem(commonName) {
96335
96340
  }
96336
96341
  }
96337
96342
  var PEM_BLOCK_RE = /-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g;
96338
- function subjectValue(subject, key2) {
96339
- for (const line of subject.split("\n")) {
96343
+ function subjectValue(subject2, key2) {
96344
+ for (const line of subject2.split("\n")) {
96340
96345
  if (line.startsWith(`${key2}=`)) {
96341
96346
  return line.slice(key2.length + 1).trim() || null;
96342
96347
  }
@@ -109688,23 +109693,34 @@ async function captureScreenshot(ctx, opts = {}) {
109688
109693
  let bytes = Buffer.from(cdpResult.data, "base64");
109689
109694
  const rotation = opts.rotation && opts.rotation !== "Portrait" ? opts.rotation : null;
109690
109695
  const scale = opts.scale != null && opts.scale > 0 && opts.scale < 1 ? opts.scale : null;
109696
+ const dropped = [];
109697
+ let dropReason;
109691
109698
  if (rotation || scale) {
109692
109699
  const sharp = tryLoadSharp();
109693
109700
  if (!sharp) {
109694
109701
  const features = [rotation && "rotation", scale && "scale"].filter(Boolean).join(" + ");
109695
109702
  warnSharpMissingOnce(features);
109703
+ if (rotation) dropped.push("rotation");
109704
+ if (scale) dropped.push("scale");
109705
+ dropReason = "sharp-missing";
109696
109706
  } else {
109697
109707
  let pipeline = sharp(bytes);
109698
109708
  if (rotation) pipeline = pipeline.rotate(ROTATION_DEGREES2[rotation]);
109699
109709
  if (scale) {
109700
109710
  const dims = readPngSize(bytes);
109701
109711
  if (dims) {
109702
- const targetW = Math.max(1, Math.round(dims.width * scale));
109703
- const targetH = Math.max(1, Math.round(dims.height * scale));
109712
+ const quarterTurn = rotation === "LandscapeLeft" || rotation === "LandscapeRight";
109713
+ const rotatedW = quarterTurn ? dims.height : dims.width;
109714
+ const rotatedH = quarterTurn ? dims.width : dims.height;
109715
+ const targetW = Math.max(1, Math.round(rotatedW * scale));
109716
+ const targetH = Math.max(1, Math.round(rotatedH * scale));
109704
109717
  pipeline = pipeline.resize(targetW, targetH, {
109705
109718
  kernel: DOWNSCALER_TO_KERNEL[opts.downscaler ?? "lanczos3"],
109706
109719
  fit: "fill"
109707
109720
  });
109721
+ } else {
109722
+ dropped.push("scale");
109723
+ dropReason = "png-header-unreadable";
109708
109724
  }
109709
109725
  }
109710
109726
  bytes = Buffer.from(await pipeline.png({ compressionLevel: 6 }).toBuffer());
@@ -109714,7 +109730,11 @@ async function captureScreenshot(ctx, opts = {}) {
109714
109730
  const safeDeviceId = ctx.deviceId.replace(/[^A-Za-z0-9_-]/g, "_");
109715
109731
  const filePath = path16.join(mediaDir(), `argent-screenshot-${safeDeviceId}-${stem}.png`);
109716
109732
  fs18.writeFileSync(filePath, bytes);
109717
- return { url: `file://${filePath}`, path: filePath };
109733
+ return {
109734
+ url: `file://${filePath}`,
109735
+ path: filePath,
109736
+ ...dropped.length > 0 ? { droppedFeatures: dropped, dropReason } : {}
109737
+ };
109718
109738
  }
109719
109739
  function readPngSize(buf) {
109720
109740
  const signature = [137, 80, 78, 71, 13, 10, 26, 10];
@@ -114635,6 +114655,31 @@ async function handleWsCommand(msg, server) {
114635
114655
 
114636
114656
  // ../tool-server/src/http.ts
114637
114657
  init_device_info();
114658
+
114659
+ // ../tool-server/src/tools/screenshot/dropped-geometry.ts
114660
+ var RESULT_NOTE_KEY = "__argentNote";
114661
+ function requestedGeometry(params) {
114662
+ const requested = [];
114663
+ if (params.rotation !== void 0 && params.rotation !== "Portrait") requested.push("rotation");
114664
+ if (params.scale !== void 0 && params.scale > 0 && params.scale < 1) requested.push("scale");
114665
+ return requested;
114666
+ }
114667
+ function subject(dropped) {
114668
+ return dropped.length === 2 ? "scale and rotation were" : `${dropped[0]} was`;
114669
+ }
114670
+ function chromiumDropNote(dropped, reason = "sharp-missing") {
114671
+ if (dropped.length === 0) return void 0;
114672
+ if (reason === "png-header-unreadable") {
114673
+ return `${subject(dropped)} not applied: the PNG header could not be read. Any rotation was applied.`;
114674
+ }
114675
+ return `${subject(dropped)} not applied: install the optional \`sharp\` package in the tool-server environment.`;
114676
+ }
114677
+ function unsupportedDropNote(dropped, target) {
114678
+ if (dropped.length === 0) return void 0;
114679
+ return `${subject(dropped)} not applied: ${target} screenshots cannot be rotated.`;
114680
+ }
114681
+
114682
+ // ../tool-server/src/http.ts
114638
114683
  var AUTO_SUPPRESS_MS = 30 * 60 * 1e3;
114639
114684
  var AUTH_TOKEN_ENV = "ARGENT_AUTH_TOKEN";
114640
114685
  var BEARER_PREFIX = "Bearer ";
@@ -114796,6 +114841,14 @@ function isWebsocketUpgradeAllowed(headers, policy) {
114796
114841
  var UPLOAD_TTL_MS = 15 * 60 * 1e3;
114797
114842
  var MAX_UPLOAD_STREAM_BYTES = 2 * 1024 * 1024 * 1024;
114798
114843
  var MAX_PENDING_UPLOAD_BYTES = 8 * 1024 * 1024 * 1024;
114844
+ function takeToolNote(data) {
114845
+ if (typeof data !== "object" || data === null) return void 0;
114846
+ const bag = data;
114847
+ if (!(RESULT_NOTE_KEY in bag)) return void 0;
114848
+ const note = bag[RESULT_NOTE_KEY];
114849
+ delete bag[RESULT_NOTE_KEY];
114850
+ return typeof note === "string" && note.length > 0 ? note : void 0;
114851
+ }
114799
114852
  function createHttpApp(registry2, options) {
114800
114853
  const app = (0, import_express3.default)();
114801
114854
  app.use(import_express3.default.json({ limit: "48mb" }));
@@ -115206,6 +115259,8 @@ function createHttpApp(registry2, options) {
115206
115259
  if (signingNote) {
115207
115260
  notes.push(signingNote);
115208
115261
  }
115262
+ const toolNote = takeToolNote(data);
115263
+ if (toolNote) notes.push(toolNote);
115209
115264
  const notePayload = notes.length > 0 ? { note: notes.join("\n\n") } : {};
115210
115265
  if (wantsStream) {
115211
115266
  writeLine({ event: "result", data, ...notePayload });
@@ -120038,11 +120093,11 @@ function clearCachedProfilerPaths(port, deviceId) {
120038
120093
  }
120039
120094
 
120040
120095
  // ../tool-server/src/tools/devices/boot-device.ts
120041
- var import_node_child_process25 = require("node:child_process");
120096
+ var import_node_child_process24 = require("node:child_process");
120042
120097
  var import_node_fs12 = require("node:fs");
120043
120098
  var import_node_os11 = require("node:os");
120044
120099
  var import_node_path15 = require("node:path");
120045
- var import_node_util18 = require("node:util");
120100
+ var import_node_util17 = require("node:util");
120046
120101
  init_zod();
120047
120102
  init_src();
120048
120103
  init_src2();
@@ -120128,39 +120183,6 @@ function androidHeadlessFromEnv() {
120128
120183
  init_device_info();
120129
120184
  init_external_devices();
120130
120185
 
120131
- // ../tool-server/src/utils/hid-suppression.ts
120132
- var import_node_child_process23 = require("node:child_process");
120133
- var import_node_util17 = require("node:util");
120134
- var execFileAsync17 = (0, import_node_util17.promisify)(import_node_child_process23.execFile);
120135
- var WARMUP_TIMEOUT_MS = 4e4;
120136
- var errText = (err) => err instanceof Error ? err.message : String(err);
120137
- function startHidWarmUp(udid, deviceSet) {
120138
- let binary;
120139
- try {
120140
- binary = simulatorServerBinaryPath();
120141
- } catch (err) {
120142
- process.stderr.write(
120143
- `[hid-warmup ${udid.slice(0, 8)}] simulator-server binary not found (${errText(err)}); HID suppression protection is not active for this boot.
120144
- `
120145
- );
120146
- return Promise.resolve();
120147
- }
120148
- const args = ["hid_warmup", "--id", udid];
120149
- if (deviceSet) args.push("--device-set", deviceSet);
120150
- return execFileAsync17(binary, args, {
120151
- timeout: WARMUP_TIMEOUT_MS,
120152
- // It prints CoreSimulator noise on every failed attach attempt — ~80KB
120153
- // against a device that never comes up. Well under Node's 1MB default, but
120154
- // the default is the only headroom there is, so name one.
120155
- maxBuffer: 4 * 1024 * 1024
120156
- }).then(() => void 0).catch((err) => {
120157
- process.stderr.write(
120158
- `[hid-warmup ${udid.slice(0, 8)}] warm-up did not run (${errText(err)}); input may be silently dropped on this simulator.
120159
- `
120160
- );
120161
- });
120162
- }
120163
-
120164
120186
  // ../tool-server/src/utils/vega-vvd.ts
120165
120187
  init_src2();
120166
120188
  init_adb();
@@ -120291,7 +120313,7 @@ async function waitForVvdRunning(timeoutMs) {
120291
120313
  }
120292
120314
 
120293
120315
  // ../tool-server/src/tools/devices/boot-electron.ts
120294
- var import_node_child_process24 = require("node:child_process");
120316
+ var import_node_child_process23 = require("node:child_process");
120295
120317
  var fs31 = __toESM(require("node:fs"));
120296
120318
  var path26 = __toESM(require("node:path"));
120297
120319
  init_src2();
@@ -120487,7 +120509,7 @@ async function bootElectronApp(options) {
120487
120509
  ];
120488
120510
  let child;
120489
120511
  try {
120490
- child = (0, import_node_child_process24.spawn)(launcher.command, args, {
120512
+ child = (0, import_node_child_process23.spawn)(launcher.command, args, {
120491
120513
  detached: true,
120492
120514
  // stdout is discarded, not piped: nothing reads it, and an unread pipe
120493
120515
  // blocks the child's writes once the OS buffer fills. The
@@ -120609,7 +120631,7 @@ async function bootElectronApp(options) {
120609
120631
  }
120610
120632
 
120611
120633
  // ../tool-server/src/tools/devices/boot-device.ts
120612
- var execFileAsync18 = (0, import_node_util18.promisify)(import_node_child_process25.execFile);
120634
+ var execFileAsync17 = (0, import_node_util17.promisify)(import_node_child_process24.execFile);
120613
120635
  var zodSchema9 = external_exports.object({
120614
120636
  udid: external_exports.string().optional().describe(
120615
120637
  "iOS: simulator UDID to boot (from `list-devices`). Provide exactly one of `udid`, `avdName`, `vvdImage`, or `electronAppPath`."
@@ -120813,7 +120835,7 @@ async function bootIos(udid, registry2, force, headless) {
120813
120835
  const deviceSet = await deviceSetForUdid(udid);
120814
120836
  const prefix = simctlPrefix(deviceSet);
120815
120837
  if (force && simState === "Booted") {
120816
- await execFileAsync18("xcrun", [...prefix, "shutdown", udid]);
120838
+ await execFileAsync17("xcrun", [...prefix, "shutdown", udid]);
120817
120839
  }
120818
120840
  const needsPreBoot = simState === "Shutdown" || force && simState === "Booted";
120819
120841
  if (needsPreBoot) {
@@ -120824,15 +120846,13 @@ async function bootIos(udid, registry2, force, headless) {
120824
120846
  );
120825
120847
  });
120826
120848
  }
120827
- const alreadyUp = simState === "Booted" && !force;
120828
- const hidWarmUp = alreadyUp || isTvOs ? Promise.resolve() : startHidWarmUp(udid, deviceSet);
120829
- await execFileAsync18("xcrun", [...prefix, "boot", udid]).catch((err) => {
120849
+ await execFileAsync17("xcrun", [...prefix, "boot", udid]).catch((err) => {
120830
120850
  const message = err instanceof Error ? err.message : String(err);
120831
120851
  if (!message.includes("Unable to boot device in current state: Booted")) {
120832
120852
  throw err;
120833
120853
  }
120834
120854
  });
120835
- await execFileAsync18("xcrun", [...prefix, "bootstatus", udid, "-b"]);
120855
+ await execFileAsync17("xcrun", [...prefix, "bootstatus", udid, "-b"]);
120836
120856
  if (isTvOs && needsPreBoot) {
120837
120857
  await registry2.disposeService(`${TV_CONTROL_NAMESPACE}:${udid}`).catch((err) => {
120838
120858
  if (err instanceof ServiceNotFoundError) return;
@@ -120851,7 +120871,6 @@ async function bootIos(udid, registry2, force, headless) {
120851
120871
  });
120852
120872
  }
120853
120873
  await ensureAutomationEnabled(udid).catch(() => void 0);
120854
- await hidWarmUp;
120855
120874
  const ndRef = nativeDevtoolsRef({ id: udid, platform: "ios", kind: "simulator" });
120856
120875
  const ndApi = await registry2.resolveService(ndRef.urn, ndRef.options);
120857
120876
  await ndApi.reverifyEnv().catch(() => {
@@ -120861,7 +120880,7 @@ async function bootIos(udid, registry2, force, headless) {
120861
120880
  return buildInitFailedResult(udid, initFailure);
120862
120881
  }
120863
120882
  if (!deviceSet) {
120864
- await execFileAsync18("defaults", [
120883
+ await execFileAsync17("defaults", [
120865
120884
  "write",
120866
120885
  "com.apple.iphonesimulator",
120867
120886
  "CurrentDeviceUDID",
@@ -120870,7 +120889,7 @@ async function bootIos(udid, registry2, force, headless) {
120870
120889
  });
120871
120890
  }
120872
120891
  if (!headless && !iosHeadlessFromEnv() && !deviceSet) {
120873
- await execFileAsync18("open", ["-a", "Simulator.app"]).catch(() => execFileAsync18("open", ["-b", "com.apple.dt.Devices"])).catch(() => {
120892
+ await execFileAsync17("open", ["-a", "Simulator.app"]).catch(() => execFileAsync17("open", ["-b", "com.apple.dt.Devices"])).catch(() => {
120874
120893
  });
120875
120894
  }
120876
120895
  return { platform: "ios", udid, booted: true };
@@ -120917,7 +120936,7 @@ async function attemptBoot(params) {
120917
120936
  emulatorLogFd = (0, import_node_fs12.openSync)(logPath, "w");
120918
120937
  stdio = ["ignore", emulatorLogFd, emulatorLogFd];
120919
120938
  }
120920
- const child = (0, import_node_child_process25.spawn)(params.emulatorBinary, params.emulatorArgs, {
120939
+ const child = (0, import_node_child_process24.spawn)(params.emulatorBinary, params.emulatorArgs, {
120921
120940
  detached: true,
120922
120941
  stdio
120923
120942
  });
@@ -121542,11 +121561,11 @@ var BUNDLE_ID_PATTERN = /^[A-Za-z0-9_][A-Za-z0-9._-]*$/;
121542
121561
  var BUNDLE_ID_MESSAGE = "bundleId may only contain letters, digits, '.', '_' and '-', and may not start with '-' or '.'";
121543
121562
 
121544
121563
  // ../tool-server/src/tools/launch-app/platforms/ios.ts
121545
- var import_node_child_process26 = require("node:child_process");
121546
- var import_node_util19 = require("node:util");
121564
+ var import_node_child_process25 = require("node:child_process");
121565
+ var import_node_util18 = require("node:util");
121547
121566
  init_src2();
121548
121567
  init_external_devices();
121549
- var execFileAsync19 = (0, import_node_util19.promisify)(import_node_child_process26.execFile);
121568
+ var execFileAsync18 = (0, import_node_util18.promisify)(import_node_child_process25.execFile);
121550
121569
  function makeIosImpl(registry2) {
121551
121570
  return {
121552
121571
  requires: ["xcrun"],
@@ -121561,7 +121580,7 @@ function makeIosImpl(registry2) {
121561
121580
  if (blocked) return blocked;
121562
121581
  }
121563
121582
  try {
121564
- await execFileAsync19(
121583
+ await execFileAsync18(
121565
121584
  "xcrun",
121566
121585
  await simctlArgsForUdid(params.udid, ["launch", params.udid, params.bundleId])
121567
121586
  );
@@ -121853,11 +121872,11 @@ init_zod();
121853
121872
  init_device_info();
121854
121873
 
121855
121874
  // ../tool-server/src/tools/restart-app/platforms/ios.ts
121856
- var import_node_child_process27 = require("node:child_process");
121857
- var import_node_util20 = require("node:util");
121875
+ var import_node_child_process26 = require("node:child_process");
121876
+ var import_node_util19 = require("node:util");
121858
121877
  init_src2();
121859
121878
  init_external_devices();
121860
- var execFileAsync20 = (0, import_node_util20.promisify)(import_node_child_process27.execFile);
121879
+ var execFileAsync19 = (0, import_node_util19.promisify)(import_node_child_process26.execFile);
121861
121880
  function makeIosImpl2(registry2) {
121862
121881
  return {
121863
121882
  requires: ["xcrun"],
@@ -121873,11 +121892,11 @@ function makeIosImpl2(registry2) {
121873
121892
  if (blocked) return blocked;
121874
121893
  }
121875
121894
  try {
121876
- await execFileAsync20("xcrun", await simctlArgsForUdid(udid, ["terminate", udid, bundleId]));
121895
+ await execFileAsync19("xcrun", await simctlArgsForUdid(udid, ["terminate", udid, bundleId]));
121877
121896
  } catch {
121878
121897
  }
121879
121898
  try {
121880
- await execFileAsync20("xcrun", await simctlArgsForUdid(udid, ["launch", udid, bundleId]));
121899
+ await execFileAsync19("xcrun", await simctlArgsForUdid(udid, ["launch", udid, bundleId]));
121881
121900
  } catch (err) {
121882
121901
  throw new FailureError(
121883
121902
  `Failed to restart iOS app ${bundleId} on ${udid}.`,
@@ -122055,11 +122074,11 @@ Returns { restarted, bundleId }. Fails if the app is not installed.`,
122055
122074
  init_zod();
122056
122075
 
122057
122076
  // ../tool-server/src/tools/reinstall-app/platforms/ios.ts
122058
- var import_node_child_process28 = require("node:child_process");
122059
- var import_node_util21 = require("node:util");
122077
+ var import_node_child_process27 = require("node:child_process");
122078
+ var import_node_util20 = require("node:util");
122060
122079
  var import_node_path16 = require("node:path");
122061
122080
  init_src2();
122062
- var execFileAsync21 = (0, import_node_util21.promisify)(import_node_child_process28.execFile);
122081
+ var execFileAsync20 = (0, import_node_util20.promisify)(import_node_child_process27.execFile);
122063
122082
  var iosImpl = {
122064
122083
  requires: ["xcrun"],
122065
122084
  handler: async (_services, params) => {
@@ -122067,11 +122086,11 @@ var iosImpl = {
122067
122086
  const absolute = (0, import_node_path16.resolve)(appPath);
122068
122087
  const { nativeId, prefix } = await simctlTargetForUdid(udid);
122069
122088
  try {
122070
- await execFileAsync21("xcrun", [...prefix, "uninstall", nativeId, bundleId]);
122089
+ await execFileAsync20("xcrun", [...prefix, "uninstall", nativeId, bundleId]);
122071
122090
  } catch {
122072
122091
  }
122073
122092
  try {
122074
- await execFileAsync21("xcrun", [...prefix, "install", nativeId, absolute]);
122093
+ await execFileAsync20("xcrun", [...prefix, "install", nativeId, absolute]);
122075
122094
  } catch (err) {
122076
122095
  throw new FailureError(
122077
122096
  `Failed to install iOS app bundle on ${udid}.`,
@@ -122248,10 +122267,10 @@ var PERMISSION_NAMES = [
122248
122267
  ];
122249
122268
 
122250
122269
  // ../tool-server/src/tools/settings-permissions/platforms/ios.ts
122251
- var import_node_child_process29 = require("node:child_process");
122252
- var import_node_util22 = require("node:util");
122270
+ var import_node_child_process28 = require("node:child_process");
122271
+ var import_node_util21 = require("node:util");
122253
122272
  init_src2();
122254
- var execFileAsync22 = (0, import_node_util22.promisify)(import_node_child_process29.execFile);
122273
+ var execFileAsync21 = (0, import_node_util21.promisify)(import_node_child_process28.execFile);
122255
122274
  var SIMCTL_ACTION = {
122256
122275
  grant: "grant",
122257
122276
  deny: "revoke",
@@ -122276,7 +122295,7 @@ var NON_TCC_GRANT_NEEDS_INSTALL = /* @__PURE__ */ new Set([
122276
122295
  ]);
122277
122296
  var localBackend = {
122278
122297
  async run(udid, simctlAction, service, bundleId) {
122279
- await execFileAsync22(
122298
+ await execFileAsync21(
122280
122299
  "xcrun",
122281
122300
  await simctlArgsForUdid(udid, ["privacy", udid, simctlAction, service, bundleId]),
122282
122301
  { timeout: 3e4 }
@@ -122284,7 +122303,7 @@ var localBackend = {
122284
122303
  },
122285
122304
  async isInstalled(udid, bundleId) {
122286
122305
  try {
122287
- await execFileAsync22(
122306
+ await execFileAsync21(
122288
122307
  "xcrun",
122289
122308
  await simctlArgsForUdid(udid, ["get_app_container", udid, bundleId]),
122290
122309
  { timeout: 15e3 }
@@ -122567,8 +122586,8 @@ init_zod();
122567
122586
  init_device_info();
122568
122587
 
122569
122588
  // ../tool-server/src/tools/open-url/platforms/ios.ts
122570
- var import_node_child_process30 = require("node:child_process");
122571
- var import_node_util23 = require("node:util");
122589
+ var import_node_child_process29 = require("node:child_process");
122590
+ var import_node_util22 = require("node:util");
122572
122591
  init_src2();
122573
122592
 
122574
122593
  // ../tool-server/src/tools/open-url/deep-link-note.ts
@@ -122578,12 +122597,12 @@ function httpDeepLinkNote(url2) {
122578
122597
  }
122579
122598
 
122580
122599
  // ../tool-server/src/tools/open-url/platforms/ios.ts
122581
- var execFileAsync23 = (0, import_node_util23.promisify)(import_node_child_process30.execFile);
122600
+ var execFileAsync22 = (0, import_node_util22.promisify)(import_node_child_process29.execFile);
122582
122601
  var iosImpl3 = {
122583
122602
  requires: ["xcrun"],
122584
122603
  handler: async (_services, params) => {
122585
122604
  try {
122586
- await execFileAsync23(
122605
+ await execFileAsync22(
122587
122606
  "xcrun",
122588
122607
  await simctlArgsForUdid(params.udid, ["openurl", params.udid, params.url])
122589
122608
  );
@@ -122739,8 +122758,8 @@ Returns { opened, url, note? }. note carries the deep-linking caveat when a web
122739
122758
  };
122740
122759
 
122741
122760
  // ../tool-server/src/tools/screenshot/index.ts
122742
- var import_node_child_process31 = require("node:child_process");
122743
- var import_node_util24 = require("node:util");
122761
+ var import_node_child_process30 = require("node:child_process");
122762
+ var import_node_util23 = require("node:util");
122744
122763
  var os13 = __toESM(require("node:os"));
122745
122764
  var path27 = __toESM(require("node:path"));
122746
122765
  init_zod();
@@ -123312,7 +123331,7 @@ function scalePng(src, scale) {
123312
123331
 
123313
123332
  // ../tool-server/src/tools/screenshot/index.ts
123314
123333
  var fs33 = __toESM(require("node:fs/promises"));
123315
- var execFileAsync24 = (0, import_node_util24.promisify)(import_node_child_process31.execFile);
123334
+ var execFileAsync23 = (0, import_node_util23.promisify)(import_node_child_process30.execFile);
123316
123335
  var zodSchema15 = external_exports.object({
123317
123336
  udid: external_exports.string().describe(
123318
123337
  "Target device id from `list-devices` (iOS UDID, Android serial, Apple TV UDID, Vega serial, or Chromium id)."
@@ -123353,11 +123372,11 @@ async function tvScreenshot(udid, scale, signal) {
123353
123372
  os13.tmpdir(),
123354
123373
  `argent-tv-screenshot-${udid.slice(0, 8)}-${process.hrtime.bigint()}.png`
123355
123374
  );
123356
- await execFileAsync24("xcrun", await simctlArgsForUdid(udid, ["io", udid, "screenshot", file2]), {
123375
+ await execFileAsync23("xcrun", await simctlArgsForUdid(udid, ["io", udid, "screenshot", file2]), {
123357
123376
  signal
123358
123377
  });
123359
123378
  if (scale < 1) {
123360
- await execFileAsync24("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
123379
+ await execFileAsync23("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
123361
123380
  signal
123362
123381
  }).catch(() => {
123363
123382
  });
@@ -123367,7 +123386,7 @@ async function tvScreenshot(udid, scale, signal) {
123367
123386
  async function tvTargetLongSide(file2, scale) {
123368
123387
  let longSide = 3840;
123369
123388
  try {
123370
- const { stdout } = await execFileAsync24("sips", ["-g", "pixelWidth", "-g", "pixelHeight", file2]);
123389
+ const { stdout } = await execFileAsync23("sips", ["-g", "pixelWidth", "-g", "pixelHeight", file2]);
123371
123390
  const width = Number(/pixelWidth:\s*(\d+)/.exec(stdout)?.[1]);
123372
123391
  const height = Number(/pixelHeight:\s*(\d+)/.exec(stdout)?.[1]);
123373
123392
  if (Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0) {
@@ -123381,7 +123400,7 @@ async function downscalePngInPlace(file2, scale, signal) {
123381
123400
  if (scale >= 1) {
123382
123401
  return;
123383
123402
  }
123384
- await execFileAsync24("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
123403
+ await execFileAsync23("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
123385
123404
  signal
123386
123405
  }).catch(() => {
123387
123406
  });
@@ -123413,17 +123432,20 @@ Fails if the simulator-server / emulator backend / Chromium CDP is not reachable
123413
123432
  if (device.platform === "chromium") {
123414
123433
  const ref2 = chromiumCdpRef(device);
123415
123434
  const chromium = await registry2.resolveService(ref2.urn, ref2.options);
123416
- const { path: capturedPath2 } = await chromium.captureScreenshot({
123435
+ const captured = await chromium.captureScreenshot({
123417
123436
  rotation: params.rotation,
123418
123437
  scale: params.scale,
123419
123438
  downscaler: params.downscaler
123420
123439
  });
123421
123440
  const image2 = await requireArtifacts(ctx).register({
123422
- hostPath: capturedPath2,
123441
+ hostPath: captured.path,
123423
123442
  kind: "screenshot",
123424
123443
  mimeType: "image/png"
123425
123444
  });
123426
- return { image: image2 };
123445
+ const requested = requestedGeometry(params);
123446
+ const dropped = (captured.droppedFeatures ?? []).filter((f) => requested.includes(f));
123447
+ const note = chromiumDropNote(dropped, captured.dropReason);
123448
+ return { image: image2, ...note ? { [RESULT_NOTE_KEY]: note } : {} };
123427
123449
  }
123428
123450
  if (isIosPhysicalDevice(device)) {
123429
123451
  const pngPath = await iosPhysicalScreenshot(registry2, device, scale);
@@ -123432,7 +123454,11 @@ Fails if the simulator-server / emulator backend / Chromium CDP is not reachable
123432
123454
  kind: "screenshot",
123433
123455
  mimeType: "image/png"
123434
123456
  });
123435
- return { image: image2 };
123457
+ const note = unsupportedDropNote(
123458
+ requestedGeometry(params).filter((f) => f === "rotation"),
123459
+ "physical iPhone"
123460
+ );
123461
+ return { image: image2, ...note ? { [RESULT_NOTE_KEY]: note } : {} };
123436
123462
  }
123437
123463
  if (device.platform === "ios" && await isTvOsSimulator(params.udid)) {
123438
123464
  const pngPath = await tvScreenshot(params.udid, scale, signal);
@@ -123441,7 +123467,11 @@ Fails if the simulator-server / emulator backend / Chromium CDP is not reachable
123441
123467
  kind: "screenshot",
123442
123468
  mimeType: "image/png"
123443
123469
  });
123444
- return { image: image2 };
123470
+ const note = unsupportedDropNote(
123471
+ requestedGeometry(params).filter((f) => f === "rotation"),
123472
+ "Apple TV"
123473
+ );
123474
+ return { image: image2, ...note ? { [RESULT_NOTE_KEY]: note } : {} };
123445
123475
  }
123446
123476
  if (device.platform === "vega") {
123447
123477
  const pngPath = await captureVegaScreenshotPng({ scale: params.scale });
@@ -123450,7 +123480,11 @@ Fails if the simulator-server / emulator backend / Chromium CDP is not reachable
123450
123480
  kind: "screenshot",
123451
123481
  mimeType: "image/png"
123452
123482
  });
123453
- return { image: image2 };
123483
+ const note = unsupportedDropNote(
123484
+ requestedGeometry(params).filter((f) => f === "rotation"),
123485
+ "Vega (Fire TV)"
123486
+ );
123487
+ return { image: image2, ...note ? { [RESULT_NOTE_KEY]: note } : {} };
123454
123488
  }
123455
123489
  const ref = simulatorServerRef(device);
123456
123490
  const api = await registry2.resolveService(ref.urn, ref.options);
@@ -125373,12 +125407,12 @@ var shakeZodSchema = external_exports.object({
125373
125407
  });
125374
125408
 
125375
125409
  // ../tool-server/src/tools/shake/platforms/ios.ts
125376
- var import_node_child_process33 = require("node:child_process");
125377
- var import_node_util25 = require("node:util");
125410
+ var import_node_child_process32 = require("node:child_process");
125411
+ var import_node_util24 = require("node:util");
125378
125412
  init_src2();
125379
125413
 
125380
125414
  // ../tool-server/src/utils/window-shake.ts
125381
- var import_node_child_process32 = require("node:child_process");
125415
+ var import_node_child_process31 = require("node:child_process");
125382
125416
  init_src();
125383
125417
  var MICROINTERACTIONS_FLAG = "microinteractions";
125384
125418
  var AMPLITUDE = 22;
@@ -125485,7 +125519,7 @@ end run
125485
125519
  }
125486
125520
  function runOsascript(script) {
125487
125521
  return new Promise((resolve14, reject) => {
125488
- const child = (0, import_node_child_process32.execFile)(
125522
+ const child = (0, import_node_child_process31.execFile)(
125489
125523
  "/usr/bin/osascript",
125490
125524
  ["-"],
125491
125525
  { timeout: OSASCRIPT_TIMEOUT_MS },
@@ -125578,7 +125612,7 @@ async function prepareHostWindowShake(target) {
125578
125612
  }
125579
125613
 
125580
125614
  // ../tool-server/src/tools/shake/platforms/ios.ts
125581
- var execFileAsync25 = (0, import_node_util25.promisify)(import_node_child_process33.execFile);
125615
+ var execFileAsync24 = (0, import_node_util24.promisify)(import_node_child_process32.execFile);
125582
125616
  var SHAKE_NOTIFICATION = "com.apple.UIKit.SimulatorShake";
125583
125617
  var SHAKE_INTERVAL_MS = 400;
125584
125618
  var sleep11 = (ms) => new Promise((r) => setTimeout(r, ms));
@@ -125618,7 +125652,7 @@ var iosImpl4 = {
125618
125652
  if (i > 0) await sleep11(SHAKE_INTERVAL_MS);
125619
125653
  shaker.begin();
125620
125654
  try {
125621
- await execFileAsync25("xcrun", args, { timeout: 15e3 });
125655
+ await execFileAsync24("xcrun", args, { timeout: 15e3 });
125622
125656
  } catch (err) {
125623
125657
  const error52 = err instanceof Error ? err : new Error(String(err));
125624
125658
  throw shakeFailure(udid, error52.message, error52);
@@ -138460,8 +138494,8 @@ var import_util8 = require("util");
138460
138494
  var DEFAULT_EXEC_TIMEOUT_MS = 6e4;
138461
138495
  var DEFAULT_EXEC_MAX_BUFFER = 256 * 1024 * 1024;
138462
138496
  async function execFileAsyncWithTimeout(file2, args, options = {}) {
138463
- const execFileAsync30 = (0, import_util8.promisify)(import_child_process2.execFile);
138464
- const { stdout, stderr } = await execFileAsync30(file2, args, {
138497
+ const execFileAsync29 = (0, import_util8.promisify)(import_child_process2.execFile);
138498
+ const { stdout, stderr } = await execFileAsync29(file2, args, {
138465
138499
  encoding: "utf-8",
138466
138500
  ...options,
138467
138501
  // Applied after ...options so a caller cannot weaken the guards; maxBuffer
@@ -142487,7 +142521,7 @@ var WATERMARK_PNG_HEIGHT = 277;
142487
142521
  var WATERMARK_PNG_BASE64 = "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";
142488
142522
 
142489
142523
  // ../tool-server/src/tools/screen-recording/watermark.ts
142490
- var execFileAsync26 = (0, import_util9.promisify)(import_child_process6.execFile);
142524
+ var execFileAsync25 = (0, import_util9.promisify)(import_child_process6.execFile);
142491
142525
  var OUTPUT_FPS = 30;
142492
142526
  var FFMPEG_FALLBACK_PATHS = [
142493
142527
  "/opt/homebrew/bin/ffmpeg",
@@ -142504,7 +142538,7 @@ var MASK_DARK_MAX_LUMA = 90;
142504
142538
  var MASK_LIGHT_MIN_LUMA = 165;
142505
142539
  async function resolveBinary(name, fallbacks) {
142506
142540
  try {
142507
- await execFileAsync26("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
142541
+ await execFileAsync25("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
142508
142542
  return name;
142509
142543
  } catch {
142510
142544
  }
@@ -142703,7 +142737,7 @@ async function startCaptureLocked(api, params) {
142703
142737
  const ffmpeg = await resolveFfmpeg();
142704
142738
  if (!ffmpeg) {
142705
142739
  throw new FailureError(
142706
- "`ffmpeg` was not found on PATH. Install it (e.g. `brew install ffmpeg`) to record the screen.",
142740
+ "`ffmpeg` was not found on PATH. Install a build with libx264 (`brew install ffmpeg` on macOS, `apt install ffmpeg` on Debian/Ubuntu) and retry.",
142707
142741
  {
142708
142742
  error_code: FAILURE_CODES.SCREEN_RECORDING_FFMPEG_NOT_FOUND,
142709
142743
  failure_stage: "screen_recording_resolve_ffmpeg",
@@ -145204,7 +145238,7 @@ Returns { stopped } - the URNs of the services that were actually live and got s
145204
145238
 
145205
145239
  // ../tool-server/src/tools/simulator/stop-metro.ts
145206
145240
  init_zod();
145207
- var import_node_child_process34 = require("node:child_process");
145241
+ var import_node_child_process33 = require("node:child_process");
145208
145242
  function parseNetstatListeningPids(netstatOutput, port) {
145209
145243
  const pids = /* @__PURE__ */ new Set();
145210
145244
  for (const line of netstatOutput.split(/\r?\n/)) {
@@ -145220,7 +145254,7 @@ function parseNetstatListeningPids(netstatOutput, port) {
145220
145254
  }
145221
145255
  function listeningPids(port) {
145222
145256
  if (process.platform === "win32") {
145223
- const output2 = (0, import_node_child_process34.execFileSync)("netstat", ["-ano"], {
145257
+ const output2 = (0, import_node_child_process33.execFileSync)("netstat", ["-ano"], {
145224
145258
  encoding: "utf-8",
145225
145259
  timeout: 5e3,
145226
145260
  // `netstat -ano` dumps every socket on the host; overflowing Node's
@@ -145229,7 +145263,7 @@ function listeningPids(port) {
145229
145263
  });
145230
145264
  return parseNetstatListeningPids(output2, port);
145231
145265
  }
145232
- const output = (0, import_node_child_process34.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
145266
+ const output = (0, import_node_child_process33.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
145233
145267
  encoding: "utf-8",
145234
145268
  timeout: 5e3
145235
145269
  }).trim();
@@ -150346,7 +150380,7 @@ var import_node_url4 = require("node:url");
150346
150380
  init_src2();
150347
150381
 
150348
150382
  // ../tool-server/src/tools/flows/script/flow-script-executor.ts
150349
- var import_node_child_process35 = require("node:child_process");
150383
+ var import_node_child_process34 = require("node:child_process");
150350
150384
  var fs56 = __toESM(require("node:fs"));
150351
150385
  var os17 = __toESM(require("node:os"));
150352
150386
  var path41 = __toESM(require("node:path"));
@@ -150731,7 +150765,7 @@ var FlowScriptExecutor = class {
150731
150765
  detached: process.platform !== "win32",
150732
150766
  windowsHide: process.platform === "win32"
150733
150767
  };
150734
- child = (0, import_node_child_process35.fork)(scriptPath, [], forkOptions);
150768
+ child = (0, import_node_child_process34.fork)(scriptPath, [], forkOptions);
150735
150769
  } catch (err) {
150736
150770
  return emptyResult(
150737
150771
  { kind: "spawn", message: `Could not start the script process: ${errorMessage(err)}` },
@@ -151172,7 +151206,7 @@ async function stopProcessTree(child, graceMs) {
151172
151206
  if (process.platform === "win32") {
151173
151207
  if (hasExited(child)) return;
151174
151208
  tryKill(() => {
151175
- const killer = (0, import_node_child_process35.spawn)("taskkill", ["/pid", String(pid), "/t", "/f"], {
151209
+ const killer = (0, import_node_child_process34.spawn)("taskkill", ["/pid", String(pid), "/t", "/f"], {
151176
151210
  windowsHide: true,
151177
151211
  stdio: "ignore"
151178
151212
  });
@@ -151966,7 +152000,7 @@ init_src2();
151966
152000
  // ../tool-server/src/tools/screenshot-diff/screenshot-diff-ocr.ts
151967
152001
  var import_child_process8 = require("child_process");
151968
152002
  var import_util10 = require("util");
151969
- var execFileAsync27 = (0, import_util10.promisify)(import_child_process8.execFile);
152003
+ var execFileAsync26 = (0, import_util10.promisify)(import_child_process8.execFile);
151970
152004
  var OCR_TIMEOUT_MS = 1e4;
151971
152005
  var OCR_MAX_BUFFER_BYTES = 32 * 1024 * 1024;
151972
152006
  var TESSERACT_BINARY = "tesseract";
@@ -152011,7 +152045,7 @@ async function extractOcrTextBlocks(imagePath) {
152011
152045
  }
152012
152046
  }
152013
152047
  async function recognizeTsv(imagePath) {
152014
- const { stdout } = await execFileAsync27(
152048
+ const { stdout } = await execFileAsync26(
152015
152049
  TESSERACT_BINARY,
152016
152050
  [
152017
152051
  imagePath,
@@ -154236,11 +154270,11 @@ async function runSnapshot(env, opts) {
154236
154270
  }
154237
154271
 
154238
154272
  // ../tool-server/src/utils/status-bar.ts
154239
- var import_node_child_process36 = require("node:child_process");
154240
- var import_node_util26 = require("node:util");
154273
+ var import_node_child_process35 = require("node:child_process");
154274
+ var import_node_util25 = require("node:util");
154241
154275
  init_adb();
154242
154276
  init_device_info();
154243
- var execFileAsync28 = (0, import_node_util26.promisify)(import_node_child_process36.execFile);
154277
+ var execFileAsync27 = (0, import_node_util25.promisify)(import_node_child_process35.execFile);
154244
154278
  var DEMO_BROADCAST = "am broadcast -a com.android.systemui.demo";
154245
154279
  var IOS_STATUS_BAR_OVERRIDE = [
154246
154280
  "override",
@@ -154264,7 +154298,7 @@ async function pinStatusBar(device, signal) {
154264
154298
  if (isIosPhysicalDevice(device)) return false;
154265
154299
  try {
154266
154300
  if (device.platform === "ios") {
154267
- await execFileAsync28(
154301
+ await execFileAsync27(
154268
154302
  "xcrun",
154269
154303
  await simctlArgsForUdid(device.id, ["status_bar", device.id, ...IOS_STATUS_BAR_OVERRIDE])
154270
154304
  );
@@ -154300,7 +154334,7 @@ async function pinStatusBar(device, signal) {
154300
154334
  async function restoreStatusBar(device) {
154301
154335
  try {
154302
154336
  if (device.platform === "ios") {
154303
- await execFileAsync28(
154337
+ await execFileAsync27(
154304
154338
  "xcrun",
154305
154339
  await simctlArgsForUdid(device.id, ["status_bar", device.id, "clear"])
154306
154340
  );
@@ -154764,6 +154798,7 @@ Returns a per-step report: the first failure stops the run and the rest report a
154764
154798
  fileInputs: fileInputs3,
154765
154799
  services: () => ({}),
154766
154800
  async execute(_services, params, ctx) {
154801
+ const runStartedAt = Date.now();
154767
154802
  const signal = ctx?.signal;
154768
154803
  const { filePath, flowName, viaUpload } = await resolveFlowSource(
154769
154804
  params,
@@ -154806,6 +154841,7 @@ Returns a per-step report: the first failure stops the run and the rest report a
154806
154841
  executionPrerequisite: flow.executionPrerequisite
154807
154842
  };
154808
154843
  }
154844
+ const resolveStartedAt = Date.now();
154809
154845
  const resolved = await resolveRunDevice(
154810
154846
  registry2,
154811
154847
  ctx,
@@ -154838,6 +154874,7 @@ Returns a per-step report: the first failure stops the run and the rest report a
154838
154874
  stopped: false,
154839
154875
  pinned: statusBarPinned,
154840
154876
  owned: resolved.booted ? [resolved.booted] : [],
154877
+ ...resolved.booted ? { hoistedBootMs: Date.now() - resolveStartedAt } : {},
154841
154878
  chromiumLaunched: false,
154842
154879
  snapshotApps: /* @__PURE__ */ new Map(),
154843
154880
  projectRoot: params.project_root,
@@ -154863,7 +154900,8 @@ Returns a per-step report: the first failure stops the run and the rest report a
154863
154900
  device?.id ?? "",
154864
154901
  flow.executionPrerequisite,
154865
154902
  state3.reports,
154866
- aborted2
154903
+ aborted2,
154904
+ { startedAt: runStartedAt, durationMs: Date.now() - runStartedAt }
154867
154905
  );
154868
154906
  }
154869
154907
  };
@@ -155004,7 +155042,7 @@ async function frontChromiumPage(registry2, device) {
155004
155042
  } catch {
155005
155043
  }
155006
155044
  }
155007
- function summarize(flowName, deviceId, executionPrerequisite, steps, aborted2) {
155045
+ function summarize(flowName, deviceId, executionPrerequisite, steps, aborted2, timing) {
155008
155046
  let passed = 0;
155009
155047
  let failed2 = 0;
155010
155048
  let skipped = 0;
@@ -155030,7 +155068,8 @@ function summarize(flowName, deviceId, executionPrerequisite, steps, aborted2) {
155030
155068
  failed: failed2,
155031
155069
  skipped,
155032
155070
  errored,
155033
- steps
155071
+ steps,
155072
+ ...timing
155034
155073
  };
155035
155074
  }
155036
155075
  function pushReport(state3, report) {
@@ -155121,7 +155160,13 @@ async function execSteps(state3, steps, scope) {
155121
155160
  await execBlockStep(state3, step, scope);
155122
155161
  continue;
155123
155162
  }
155163
+ let startedAt = Date.now();
155164
+ if (step.kind === "launch" && state3.hoistedBootMs !== void 0) {
155165
+ startedAt -= state3.hoistedBootMs;
155166
+ state3.hoistedBootMs = void 0;
155167
+ }
155124
155168
  const report = await execLeafStep(state3, step, index, scope);
155169
+ if (report.status !== "skip") report.durationMs = Date.now() - startedAt;
155125
155170
  pushReport(state3, report);
155126
155171
  if (report.status === "fail" || report.status === "error") state3.stopped = true;
155127
155172
  }
@@ -155164,6 +155209,7 @@ async function execWhenStep(state3, step, scope) {
155164
155209
  ...depthOf(scope)
155165
155210
  };
155166
155211
  const inner = childScope(scope);
155212
+ const guardStartedAt = Date.now();
155167
155213
  let met;
155168
155214
  if (step.condition.kind === "platform") {
155169
155215
  const guardEnv = deviceEnv(state3);
@@ -155180,7 +155226,8 @@ async function execWhenStep(state3, step, scope) {
155180
155226
  pushReport(state3, {
155181
155227
  ...marker,
155182
155228
  status: "error",
155183
- reason: `could not evaluate when guard (${label}): ${probe3.reason}`
155229
+ reason: `could not evaluate when guard (${label}): ${probe3.reason}`,
155230
+ durationMs: Date.now() - guardStartedAt
155184
155231
  });
155185
155232
  state3.stopped = true;
155186
155233
  reportBlockSkipped(state3, step.steps, inner, "when guard errored");
@@ -155193,12 +155240,18 @@ async function execWhenStep(state3, step, scope) {
155193
155240
  pushReport(state3, {
155194
155241
  ...marker,
155195
155242
  status: "skip",
155196
- reason: `condition not met (${label}) \u2014 block skipped (${n} step${n === 1 ? "" : "s"})`
155243
+ reason: `condition not met (${label}) \u2014 block skipped (${n} step${n === 1 ? "" : "s"})`,
155244
+ durationMs: Date.now() - guardStartedAt
155197
155245
  });
155198
155246
  reportBlockSkipped(state3, step.steps, inner, "when block skipped");
155199
155247
  return;
155200
155248
  }
155201
- pushReport(state3, { ...marker, status: "pass", reason: `condition met (${label})` });
155249
+ pushReport(state3, {
155250
+ ...marker,
155251
+ status: "pass",
155252
+ reason: `condition met (${label})`,
155253
+ durationMs: Date.now() - guardStartedAt
155254
+ });
155202
155255
  await execSteps(state3, step.steps, inner);
155203
155256
  }
155204
155257
  function baselineKeyFor(canonicalPath, flowName) {
@@ -155209,6 +155262,7 @@ async function execRunStep(state3, step, scope) {
155209
155262
  const index = state3.reports.length;
155210
155263
  const target = step.flow;
155211
155264
  const display = runDisplayName(target, scope);
155265
+ const startedAt = Date.now();
155212
155266
  const fail = (reason) => {
155213
155267
  pushReport(state3, {
155214
155268
  index,
@@ -155217,7 +155271,8 @@ async function execRunStep(state3, step, scope) {
155217
155271
  flow: display,
155218
155272
  target,
155219
155273
  reason,
155220
- ...depthOf(scope)
155274
+ ...depthOf(scope),
155275
+ durationMs: Date.now() - startedAt
155221
155276
  });
155222
155277
  state3.stopped = true;
155223
155278
  };
@@ -155255,7 +155310,8 @@ async function execRunStep(state3, step, scope) {
155255
155310
  status: "pass",
155256
155311
  flow: display,
155257
155312
  target,
155258
- ...depthOf(scope)
155313
+ ...depthOf(scope),
155314
+ durationMs: Date.now() - startedAt
155259
155315
  });
155260
155316
  await execSteps(
155261
155317
  state3,
@@ -155645,7 +155701,7 @@ init_zod();
155645
155701
  // ../tool-server/src/utils/workspace-reader.ts
155646
155702
  var import_promises12 = require("node:fs/promises");
155647
155703
  var import_node_path23 = require("node:path");
155648
- var import_node_child_process37 = require("node:child_process");
155704
+ var import_node_child_process36 = require("node:child_process");
155649
155705
  var import_dotenv2 = __toESM(require_main());
155650
155706
  async function exists(path50) {
155651
155707
  try {
@@ -155689,7 +155745,7 @@ async function listDir(path50) {
155689
155745
  var COMMAND_TIMEOUT_MS = 3e3;
155690
155746
  function runVersionCommand(cmd, args, cwd) {
155691
155747
  return new Promise((resolve14) => {
155692
- const child = (0, import_node_child_process37.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
155748
+ const child = (0, import_node_child_process36.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
155693
155749
  if (err) {
155694
155750
  resolve14(null);
155695
155751
  return;
@@ -155978,7 +156034,7 @@ Fails if the workspacePath is not an absolute path or the directory cannot be ac
155978
156034
  };
155979
156035
 
155980
156036
  // ../tool-server/src/tools/system/update-argent.ts
155981
- var import_node_child_process38 = require("node:child_process");
156037
+ var import_node_child_process37 = require("node:child_process");
155982
156038
  var fs63 = __toESM(require("node:fs"));
155983
156039
  var path46 = __toESM(require("node:path"));
155984
156040
  init_zod();
@@ -156113,7 +156169,7 @@ var updateArgentTool = {
156113
156169
  if (spawnRoot) updateArgs.push("--project-root", spawnRoot);
156114
156170
  const cmd = cliEntry ? process.execPath : "argent";
156115
156171
  const args = cliEntry ? [cliEntry, ...updateArgs] : updateArgs;
156116
- const child = (0, import_node_child_process38.spawn)(cmd, args, {
156172
+ const child = (0, import_node_child_process37.spawn)(cmd, args, {
156117
156173
  detached: true,
156118
156174
  stdio: "ignore",
156119
156175
  env: { ...process.env, ARGENT_UPDATE_TRIGGER: "mcp_update" }
@@ -157115,13 +157171,13 @@ function probeArgentToolServer(host, port, timeoutMs = 500) {
157115
157171
 
157116
157172
  // ../tool-server/src/utils/simulator-watcher.ts
157117
157173
  var fs65 = __toESM(require("node:fs"));
157118
- var import_node_child_process39 = require("node:child_process");
157119
- var import_node_util27 = require("node:util");
157174
+ var import_node_child_process38 = require("node:child_process");
157175
+ var import_node_util26 = require("node:util");
157120
157176
  init_external_devices();
157121
- var execFileAsync29 = (0, import_node_util27.promisify)(import_node_child_process39.execFile);
157177
+ var execFileAsync28 = (0, import_node_util26.promisify)(import_node_child_process38.execFile);
157122
157178
  var POLL_INTERVAL_MS2 = 1e4;
157123
157179
  async function getBootedUdidsInSet(deviceSet) {
157124
- const { stdout } = await execFileAsync29("xcrun", [
157180
+ const { stdout } = await execFileAsync28("xcrun", [
157125
157181
  ...simctlPrefix(deviceSet),
157126
157182
  "list",
157127
157183
  "devices",
@@ -157240,7 +157296,7 @@ function startSimulatorWatcher(registry2) {
157240
157296
  }
157241
157297
 
157242
157298
  // ../tool-server/src/utils/preview-window.ts
157243
- var import_node_child_process40 = require("node:child_process");
157299
+ var import_node_child_process39 = require("node:child_process");
157244
157300
  var fs66 = __toESM(require("node:fs"));
157245
157301
  var os20 = __toESM(require("node:os"));
157246
157302
  var path48 = __toESM(require("node:path"));
@@ -157272,10 +157328,10 @@ function ensureLensAppBundle(electronBin) {
157272
157328
  fs66.copyFileSync(path48.join(realContents, "Info.plist"), plist);
157273
157329
  const setPlist = (entry, value) => {
157274
157330
  try {
157275
- (0, import_node_child_process40.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
157331
+ (0, import_node_child_process39.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
157276
157332
  } catch {
157277
157333
  try {
157278
- (0, import_node_child_process40.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
157334
+ (0, import_node_child_process39.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
157279
157335
  } catch {
157280
157336
  }
157281
157337
  }
@@ -157334,7 +157390,7 @@ function createPreviewWindowManager(opts = {}) {
157334
157390
  const wrapperBin = ensureLensAppBundle(electronBin);
157335
157391
  const launchBin = wrapperBin ?? electronBin;
157336
157392
  const launchArgs = wrapperBin ? ["--no-sandbox", mainScript] : [mainScript];
157337
- const next = (0, import_node_child_process40.spawn)(launchBin, launchArgs, {
157393
+ const next = (0, import_node_child_process39.spawn)(launchBin, launchArgs, {
157338
157394
  // Strips ELECTRON_RUN_AS_NODE, which an Electron-based MCP host leaves in
157339
157395
  // our env, so the child boots as a GUI app instead of bare Node.
157340
157396
  env: electronGuiChildEnv({ ARGENT_PREVIEW_URL: url2 }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.25.2-next.1",
3
+ "version": "0.25.2-next.10",
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",
@@ -44,5 +44,5 @@ A recording does not stop itself before its `timeLimitSeconds` cap, so a forgott
44
44
  - **The timeline is paced to a steady 30 fps**: a device only emits a frame when its screen changes, so captured frames are re-paced onto a fixed timeline rather than bunching up. With static-frame trimming off (`trimStatic: false`) that timeline is wall-clock accurate — a completely still screen still comes back as a full-length video (compressing to almost nothing) and `durationMs` matches the time you actually recorded. With trimming on (the default, see §3) still stretches past the grace window are collapsed, so `durationMs` is the trimmed video length and `wallClockMs` carries the real elapsed time.
45
45
  - **Android**: records at the device's native resolution; secure screens (DRM, some password fields) come out black.
46
46
  - **Unsupported**: tvOS simulators, physical iPhones, Chromium apps, Vega/Fire TV, and remote (`remote:`-prefixed) simulators — none of them expose a readable frame stream. For a single still frame use `screenshot`; for a replayable interaction script use `argent-create-flow` instead of a video.
47
- - **ffmpeg is required**: it is the encoder, so `screen-recording-start` fails up front with an install hint if it is missing (`brew install ffmpeg`). It is resolved from `PATH` plus the usual Homebrew prefixes.
47
+ - **ffmpeg is required**: it is the encoder, so `screen-recording-start` fails up front with an install hint if it is missing (`brew install ffmpeg` on macOS). It is resolved from `PATH` plus the usual Homebrew prefixes.
48
48
  - **Watermark**: the Argent logo + "By @swmansion" is stamped bottom-left while encoding, faint (20% opacity) and per-pixel contrast-matched to the background (light logo over dark UI, dark logo over light UI). On by default — turn it off with `argent disable video-watermark` (re-enable with `argent enable video-watermark`). The flag is read when the recording starts.