@swmansion/argent 0.28.1-next.24 → 0.28.1-next.26

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
@@ -30095,7 +30095,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
30095
30095
  var SESSION_ID2 = randomUUID5();
30096
30096
  function readCliVersion() {
30097
30097
  if (true) {
30098
- return "0.28.1-next.24";
30098
+ return "0.28.1-next.25";
30099
30099
  }
30100
30100
  return "0.0.0";
30101
30101
  }
@@ -16739,7 +16739,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
16739
16739
  var SESSION_ID = randomUUID4();
16740
16740
  function readCliVersion() {
16741
16741
  if (true) {
16742
- return "0.28.1-next.24";
16742
+ return "0.28.1-next.25";
16743
16743
  }
16744
16744
  return "0.0.0";
16745
16745
  }
@@ -802,7 +802,7 @@ export interface ArgentToolArgs {
802
802
  udid: string;
803
803
  /** Orientation override for the screenshot (rotates the captured image after Page.captureScreenshot on Chromium). On Android the capture already follows the device's rotation. Ignored on physical iPhones. */
804
804
  rotation?: "Portrait" | "LandscapeLeft" | "LandscapeRight" | "PortraitUpsideDown";
805
- /** Scale factor (0.01-1.0). Defaults to ARGENT_SCREENSHOT_SCALE env var, or 0.25 if unset for iOS/Android. On Chromium the default is 1.0 (no downscale); pass <1 to opt in. Downscaling on Chromium requires the optional `sharp` dependency. */
805
+ /** Scale factor (0.01-1.0). Defaults to ARGENT_SCREENSHOT_SCALE env var, or 0.25 if unset for iOS/Android. On a local Apple TV simulator, an Android TV or Vega, with neither set, the capture is downscaled to a 576 px long side (0.15 of a 4K capture); an Android TV whose form factor or display size cannot be read in time keeps 0.25. On Chromium the default is 1.0 (no downscale); pass <1 to opt in. Downscaling on Chromium requires the optional `sharp` dependency. */
806
806
  scale?: number;
807
807
  /** Default true. Set false only when capturing a full-resolution PNG (scale: 1.0) to save as a baseline/current for screenshot-diff. The file is still written, but the image bytes are not attached to the agent context. */
808
808
  includeImageInContext?: boolean;
@@ -94923,7 +94923,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
94923
94923
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
94924
94924
  function readCliVersion() {
94925
94925
  if (true) {
94926
- return "0.28.1-next.24";
94926
+ return "0.28.1-next.25";
94927
94927
  }
94928
94928
  return "0.0.0";
94929
94929
  }
@@ -107957,6 +107957,7 @@ var os5 = __toESM(require("node:os"));
107957
107957
  var import_node_crypto6 = require("node:crypto");
107958
107958
  var import_node_url = require("node:url");
107959
107959
  var DEFAULT_SCREENSHOT_SCALE = 0.25;
107960
+ var TV_DEFAULT_LONG_SIDE = 576;
107960
107961
  var NO_IMAGE_ERROR = /no image to export/i;
107961
107962
  var FIRST_FRAME_WAIT_MS = 6e3;
107962
107963
  var FIRST_FRAME_POLL_MS = 250;
@@ -108312,19 +108313,24 @@ async function simulatorPost(toolLabel, api, endpoint, reqBody, signal, fallback
108312
108313
  return { res, body };
108313
108314
  }
108314
108315
  var warnedScaleValue;
108315
- function getScreenshotScale() {
108316
+ function getScreenshotScaleOverride() {
108316
108317
  const v = process.env.ARGENT_SCREENSHOT_SCALE;
108317
- if (v) {
108318
- const n = parseFloat(v);
108319
- if (!Number.isNaN(n) && n >= 0.01 && n <= 1) return n;
108320
- if (v !== warnedScaleValue) {
108321
- warnedScaleValue = v;
108322
- console.warn(
108323
- `[screenshot] Ignoring ARGENT_SCREENSHOT_SCALE=${v}: expected a number between 0.01 and 1.0. Using ${DEFAULT_SCREENSHOT_SCALE}.`
108324
- );
108325
- }
108318
+ if (!v) return void 0;
108319
+ const n = parseFloat(v);
108320
+ if (!Number.isNaN(n) && n >= 0.01 && n <= 1) return n;
108321
+ if (v !== warnedScaleValue) {
108322
+ warnedScaleValue = v;
108323
+ console.warn(
108324
+ `[screenshot] Ignoring ARGENT_SCREENSHOT_SCALE=${v}: expected a number between 0.01 and 1.0. Using the default.`
108325
+ );
108326
108326
  }
108327
- return DEFAULT_SCREENSHOT_SCALE;
108327
+ return void 0;
108328
+ }
108329
+ function getScreenshotScale() {
108330
+ return getScreenshotScaleOverride() ?? DEFAULT_SCREENSHOT_SCALE;
108331
+ }
108332
+ function tvDefaultScale(width, height) {
108333
+ return Math.min(1, TV_DEFAULT_LONG_SIDE / Math.max(width, height));
108328
108334
  }
108329
108335
  async function httpScreenshot(api, rotation, signal, scale, screen) {
108330
108336
  if (api.transport) {
@@ -121532,9 +121538,10 @@ async function bootElectronApp(options) {
121532
121538
  }
121533
121539
  const onSpawnError = (err, reject) => {
121534
121540
  const codeSuffix = err.code ? ` (${err.code})` : "";
121541
+ const installHint = launcher.command === "electron" && err.code === "ENOENT" ? ` Make sure 'electron' is installed (npm i electron in the app dir, or globally) and on PATH.` : "";
121535
121542
  reject(
121536
121543
  new FailureError(
121537
- `Electron boot: failed to launch ${launcher.command}${codeSuffix}: ${err.message}. Make sure 'electron' is installed (npm i electron in the app dir, or globally) and on PATH.`,
121544
+ `Electron boot: failed to launch ${launcher.command}${codeSuffix}: ${err.message}.${installHint}`,
121538
121545
  {
121539
121546
  error_code: FAILURE_CODES.CHROMIUM_ELECTRON_SPAWN_FAILED,
121540
121547
  failure_stage: "electron_spawn_error",
@@ -121555,18 +121562,21 @@ async function bootElectronApp(options) {
121555
121562
  };
121556
121563
  child.once("error", spawnErrorListener);
121557
121564
  if (!child.pid) {
121558
- child.removeListener("error", spawnErrorListener);
121559
- spawnErrorReject = null;
121560
- throw new FailureError(
121561
- `Electron boot: spawn returned without a pid (binary: ${launcher.command}).`,
121562
- {
121563
- error_code: FAILURE_CODES.CHROMIUM_ELECTRON_SPAWN_FAILED,
121564
- failure_stage: "electron_spawn_no_pid",
121565
- failure_area: "tool_server",
121566
- error_kind: "subprocess",
121567
- failure_command: "electron"
121568
- }
121569
- );
121565
+ return Promise.race([
121566
+ spawnError,
121567
+ sleepUnref(1e3).then(() => {
121568
+ throw new FailureError(
121569
+ `Electron boot: spawn returned without a pid (binary: ${launcher.command}).`,
121570
+ {
121571
+ error_code: FAILURE_CODES.CHROMIUM_ELECTRON_SPAWN_FAILED,
121572
+ failure_stage: "electron_spawn_no_pid",
121573
+ failure_area: "tool_server",
121574
+ error_kind: "subprocess",
121575
+ failure_command: "electron"
121576
+ }
121577
+ );
121578
+ })
121579
+ ]);
121570
121580
  }
121571
121581
  child.stderr?.on("data", (chunk) => {
121572
121582
  process.stderr.write(`[chromium-cdp-${port}] ${chunk}`);
@@ -123892,6 +123902,7 @@ var os13 = __toESM(require("node:os"));
123892
123902
  var path29 = __toESM(require("node:path"));
123893
123903
  init_zod();
123894
123904
  init_device_info();
123905
+ init_adb();
123895
123906
 
123896
123907
  // ../tool-server/src/utils/device-orientation.ts
123897
123908
  var import_node_fs13 = require("node:fs");
@@ -124443,7 +124454,7 @@ async function captureViaEmulatorConsole(opts) {
124443
124454
  }
124444
124455
  }
124445
124456
  function scalePng(src, scale) {
124446
- const s = scale ?? getScreenshotScale();
124457
+ const s = scale ?? getScreenshotScaleOverride() ?? tvDefaultScale(src.width, src.height);
124447
124458
  if (s >= 1) return src;
124448
124459
  const outW = Math.max(1, Math.round(src.width * s));
124449
124460
  const outH = Math.max(1, Math.round(src.height * s));
@@ -124468,7 +124479,7 @@ var zodSchema16 = external_exports.object({
124468
124479
  "Orientation override for the screenshot (rotates the captured image after Page.captureScreenshot on Chromium). On Android the capture already follows the device's rotation. Ignored on physical iPhones."
124469
124480
  ),
124470
124481
  scale: external_exports.number().min(0.01).max(1).optional().describe(
124471
- "Scale factor (0.01-1.0). Defaults to ARGENT_SCREENSHOT_SCALE env var, or 0.25 if unset for iOS/Android. On Chromium the default is 1.0 (no downscale); pass <1 to opt in. Downscaling on Chromium requires the optional `sharp` dependency."
124482
+ "Scale factor (0.01-1.0). Defaults to ARGENT_SCREENSHOT_SCALE env var, or 0.25 if unset for iOS/Android. On a local Apple TV simulator, an Android TV or Vega, with neither set, the capture is downscaled to a 576 px long side (0.15 of a 4K capture); an Android TV whose form factor or display size cannot be read in time keeps 0.25. On Chromium the default is 1.0 (no downscale); pass <1 to opt in. Downscaling on Chromium requires the optional `sharp` dependency."
124472
124483
  ),
124473
124484
  includeImageInContext: external_exports.boolean().optional().default(true).describe(
124474
124485
  "Default true. Set false only when capturing a full-resolution PNG (scale: 1.0) to save as a baseline/current for screenshot-diff. The file is still written, but the image bytes are not attached to the agent context."
@@ -124503,7 +124514,7 @@ async function tvScreenshot(udid, scale, signal) {
124503
124514
  await execFileAsync25("xcrun", await simctlArgsForUdid(udid, ["io", udid, "screenshot", file2]), {
124504
124515
  signal
124505
124516
  });
124506
- if (scale < 1) {
124517
+ if (scale === void 0 || scale < 1) {
124507
124518
  await execFileAsync25("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
124508
124519
  signal
124509
124520
  }).catch(() => {
@@ -124522,7 +124533,28 @@ async function tvTargetLongSide(file2, scale) {
124522
124533
  }
124523
124534
  } catch {
124524
124535
  }
124525
- return Math.round(longSide * scale);
124536
+ return scale === void 0 ? Math.min(TV_DEFAULT_LONG_SIDE, longSide) : Math.round(longSide * scale);
124537
+ }
124538
+ var ANDROID_TV_PROBE_BUDGET_MS = 2e3;
124539
+ async function androidTvDefaultScale(serial, notBefore) {
124540
+ if (getScreenshotScaleOverride() !== void 0) return void 0;
124541
+ const probe3 = Promise.all([
124542
+ isAndroidTv(serial).catch(() => false),
124543
+ getAndroidScreenSize(serial).catch(() => void 0)
124544
+ ]).then(([isTv, size]) => isTv && size ? tvDefaultScale(size.width, size.height) : void 0);
124545
+ let timer;
124546
+ const budget = new Promise((resolve14) => {
124547
+ timer = setTimeout(resolve14, ANDROID_TV_PROBE_BUDGET_MS);
124548
+ });
124549
+ try {
124550
+ return await Promise.race([
124551
+ probe3,
124552
+ Promise.all([budget, notBefore.catch(() => {
124553
+ })]).then(() => void 0)
124554
+ ]);
124555
+ } finally {
124556
+ clearTimeout(timer);
124557
+ }
124526
124558
  }
124527
124559
  async function downscalePngInPlace(file2, scale, signal) {
124528
124560
  if (scale >= 1) {
@@ -124589,7 +124621,11 @@ Fails if the simulator-server / emulator backend / Chromium CDP is not reachable
124589
124621
  return { image: image2, ...note ? { [RESULT_NOTE_KEY]: note } : {} };
124590
124622
  }
124591
124623
  if (device.platform === "ios" && await isTvOsSimulator(params.udid)) {
124592
- const pngPath = await tvScreenshot(params.udid, scale, signal);
124624
+ const pngPath = await tvScreenshot(
124625
+ params.udid,
124626
+ params.scale ?? getScreenshotScaleOverride(),
124627
+ signal
124628
+ );
124593
124629
  const image2 = await requireArtifacts(ctx).register({
124594
124630
  hostPath: pngPath,
124595
124631
  kind: "screenshot",
@@ -124615,14 +124651,18 @@ Fails if the simulator-server / emulator backend / Chromium CDP is not reachable
124615
124651
  return { image: image2, ...note ? { [RESULT_NOTE_KEY]: note } : {} };
124616
124652
  }
124617
124653
  const ref = simulatorServerRef(device);
124618
- const api = await registry2.resolveService(ref.urn, ref.options);
124654
+ const apiReady = registry2.resolveService(ref.urn, ref.options);
124655
+ const [api, androidTvScale] = await Promise.all([
124656
+ apiReady,
124657
+ params.scale === void 0 && device.platform === "android" ? androidTvDefaultScale(device.id, apiReady) : void 0
124658
+ ]);
124619
124659
  const panel = await resolveCapturePanel(api);
124620
124660
  const { path: capturedPath } = await captureScreenshotUpright(
124621
124661
  api,
124622
124662
  device,
124623
124663
  params.rotation,
124624
124664
  signal,
124625
- params.scale,
124665
+ params.scale ?? androidTvScale,
124626
124666
  panel ? (a, r, s, sc) => httpScreenshot(a, r, s, sc, panel.screen) : void 0,
124627
124667
  androidDevtoolsRotationPeek(registry2, device)
124628
124668
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.28.1-next.24",
3
+ "version": "0.28.1-next.26",
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",