@swmansion/argent 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/ax-service CHANGED
Binary file
@@ -9459,6 +9459,291 @@ var require_dist = __commonJS({
9459
9459
  }
9460
9460
  });
9461
9461
 
9462
+ // ../update-core/dist/config-parse.js
9463
+ var require_config_parse = __commonJS({
9464
+ "../update-core/dist/config-parse.js"(exports) {
9465
+ "use strict";
9466
+ Object.defineProperty(exports, "__esModule", { value: true });
9467
+ exports.DAY_MS = exports.MINUTE_MS = exports.SECOND_MS = void 0;
9468
+ exports.parseConfigValue = parseConfigValue;
9469
+ exports.parseBeforeAgeMs = parseBeforeAgeMs;
9470
+ exports.parseYarnAgeGateMs = parseYarnAgeGateMs;
9471
+ exports.SECOND_MS = 1e3;
9472
+ exports.MINUTE_MS = 60 * 1e3;
9473
+ exports.DAY_MS = 24 * 60 * 60 * 1e3;
9474
+ function trimConfigValue(stdout) {
9475
+ const trimmed = stdout.trim();
9476
+ if (!trimmed || trimmed === "undefined" || trimmed === "null")
9477
+ return null;
9478
+ if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
9479
+ return trimmed.slice(1, -1).trim();
9480
+ }
9481
+ return trimmed;
9482
+ }
9483
+ function parseConfigValue(stdout) {
9484
+ const value = trimConfigValue(stdout);
9485
+ if (!value)
9486
+ return 0;
9487
+ const n = Number(value);
9488
+ return Number.isFinite(n) && n > 0 ? n : 0;
9489
+ }
9490
+ function parseBeforeAgeMs(stdout, now = Date.now()) {
9491
+ const value = trimConfigValue(stdout);
9492
+ if (!value)
9493
+ return 0;
9494
+ const candidates = [value, value.replace(/\s+\([^)]*\)$/, "")];
9495
+ for (const candidate of candidates) {
9496
+ const ts = Date.parse(candidate);
9497
+ if (!Number.isNaN(ts)) {
9498
+ return ts < now ? now - ts : 0;
9499
+ }
9500
+ }
9501
+ return 0;
9502
+ }
9503
+ function parseYarnAgeGateMs(stdout) {
9504
+ const value = trimConfigValue(stdout);
9505
+ if (!value)
9506
+ return 0;
9507
+ const numeric = Number(value);
9508
+ if (Number.isFinite(numeric) && numeric > 0) {
9509
+ return numeric * exports.MINUTE_MS;
9510
+ }
9511
+ const match = value.match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d|w)$/i);
9512
+ if (!match)
9513
+ return 0;
9514
+ const amount = Number(match[1]);
9515
+ if (!Number.isFinite(amount) || amount <= 0)
9516
+ return 0;
9517
+ switch (match[2].toLowerCase()) {
9518
+ case "ms":
9519
+ return amount;
9520
+ case "s":
9521
+ return amount * exports.SECOND_MS;
9522
+ case "m":
9523
+ return amount * exports.MINUTE_MS;
9524
+ case "h":
9525
+ return amount * 60 * exports.MINUTE_MS;
9526
+ case "d":
9527
+ return amount * exports.DAY_MS;
9528
+ case "w":
9529
+ return amount * 7 * exports.DAY_MS;
9530
+ default:
9531
+ return 0;
9532
+ }
9533
+ }
9534
+ }
9535
+ });
9536
+
9537
+ // ../update-core/dist/min-release-age.js
9538
+ var require_min_release_age = __commonJS({
9539
+ "../update-core/dist/min-release-age.js"(exports) {
9540
+ "use strict";
9541
+ Object.defineProperty(exports, "__esModule", { value: true });
9542
+ exports.detectMinReleaseAgeMsForPm = detectMinReleaseAgeMsForPm2;
9543
+ exports.detectMinReleaseAgeMs = detectMinReleaseAgeMs;
9544
+ var node_child_process_1 = __require("node:child_process");
9545
+ var config_parse_1 = require_config_parse();
9546
+ var PROBE_TIMEOUT_MS2 = 3e3;
9547
+ var OVERRIDE_ENV = "ARGENT_MIN_RELEASE_AGE_DAYS";
9548
+ var PM_PROBES = {
9549
+ // npm flattens `min-release-age` to an effective `before` cutoff, and some
9550
+ // npm 11.x builds report `min-release-age=null` even while the policy is
9551
+ // active. Probe `before`, which is what the resolver actually uses.
9552
+ npm: { command: "npm config get before", parse: config_parse_1.parseBeforeAgeMs },
9553
+ pnpm: {
9554
+ command: "pnpm config get minimumReleaseAge",
9555
+ parse: (stdout) => (0, config_parse_1.parseConfigValue)(stdout) * config_parse_1.MINUTE_MS
9556
+ },
9557
+ yarn: { command: "yarn config get npmMinimalAgeGate", parse: config_parse_1.parseYarnAgeGateMs }
9558
+ };
9559
+ function overrideMs() {
9560
+ const override = process.env[OVERRIDE_ENV];
9561
+ if (override === void 0)
9562
+ return null;
9563
+ const days = Number(override);
9564
+ return Number.isFinite(days) && days > 0 ? days * config_parse_1.DAY_MS : 0;
9565
+ }
9566
+ function probe(p2) {
9567
+ return new Promise((resolve3) => {
9568
+ (0, node_child_process_1.exec)(p2.command, { timeout: PROBE_TIMEOUT_MS2, windowsHide: true }, (err, stdout) => {
9569
+ if (err) {
9570
+ resolve3(0);
9571
+ return;
9572
+ }
9573
+ resolve3(p2.parse(stdout));
9574
+ });
9575
+ });
9576
+ }
9577
+ async function detectMinReleaseAgeMsForPm2(pm) {
9578
+ const override = overrideMs();
9579
+ if (override !== null)
9580
+ return override;
9581
+ const p2 = PM_PROBES[pm];
9582
+ return p2 ? probe(p2) : 0;
9583
+ }
9584
+ async function detectMinReleaseAgeMs() {
9585
+ const override = overrideMs();
9586
+ if (override !== null)
9587
+ return override;
9588
+ const ages = await Promise.all(Object.values(PM_PROBES).map(probe));
9589
+ return ages.reduce((max, ms) => Math.max(max, ms), 0);
9590
+ }
9591
+ }
9592
+ });
9593
+
9594
+ // ../update-core/dist/registry.js
9595
+ var require_registry = __commonJS({
9596
+ "../update-core/dist/registry.js"(exports) {
9597
+ "use strict";
9598
+ var __importDefault = exports && exports.__importDefault || function(mod) {
9599
+ return mod && mod.__esModule ? mod : { "default": mod };
9600
+ };
9601
+ Object.defineProperty(exports, "__esModule", { value: true });
9602
+ exports.fetchRegistryInfo = fetchRegistryInfo2;
9603
+ var node_https_1 = __importDefault(__require("node:https"));
9604
+ var REQUEST_TIMEOUT_MS = 1e4;
9605
+ function fetchRegistryInfo2(url) {
9606
+ return new Promise((resolve3) => {
9607
+ let resolved = false;
9608
+ const safeResolve = (value) => {
9609
+ if (!resolved) {
9610
+ resolved = true;
9611
+ resolve3(value);
9612
+ }
9613
+ };
9614
+ const req = node_https_1.default.get(url, { timeout: REQUEST_TIMEOUT_MS }, (res) => {
9615
+ if (res.statusCode !== 200) {
9616
+ res.resume();
9617
+ safeResolve(null);
9618
+ return;
9619
+ }
9620
+ let body = "";
9621
+ res.setEncoding("utf8");
9622
+ res.on("data", (chunk) => {
9623
+ body += chunk;
9624
+ });
9625
+ res.on("end", () => {
9626
+ try {
9627
+ const json = JSON.parse(body);
9628
+ const latestVersion = json["dist-tags"]?.latest;
9629
+ if (!latestVersion) {
9630
+ safeResolve(null);
9631
+ return;
9632
+ }
9633
+ const times = json.time ?? {};
9634
+ safeResolve({
9635
+ latest: { version: latestVersion, publishedAt: times[latestVersion] ?? null },
9636
+ times
9637
+ });
9638
+ } catch {
9639
+ safeResolve(null);
9640
+ }
9641
+ });
9642
+ res.on("error", () => safeResolve(null));
9643
+ });
9644
+ req.on("error", () => safeResolve(null));
9645
+ req.on("timeout", () => {
9646
+ req.destroy();
9647
+ safeResolve(null);
9648
+ });
9649
+ });
9650
+ }
9651
+ }
9652
+ });
9653
+
9654
+ // ../update-core/dist/pick-target.js
9655
+ var require_pick_target = __commonJS({
9656
+ "../update-core/dist/pick-target.js"(exports) {
9657
+ "use strict";
9658
+ var __importDefault = exports && exports.__importDefault || function(mod) {
9659
+ return mod && mod.__esModule ? mod : { "default": mod };
9660
+ };
9661
+ Object.defineProperty(exports, "__esModule", { value: true });
9662
+ exports.pickInstallableTarget = pickInstallableTarget2;
9663
+ var semver_1 = __importDefault(require_semver2());
9664
+ function isStableUpgrade(version, current) {
9665
+ if (!semver_1.default.valid(version) || semver_1.default.prerelease(version))
9666
+ return false;
9667
+ if (current === null)
9668
+ return true;
9669
+ if (!semver_1.default.valid(current))
9670
+ return false;
9671
+ return semver_1.default.gt(version, current);
9672
+ }
9673
+ function isOldEnough(publishedAt, minReleaseAgeMs) {
9674
+ if (minReleaseAgeMs <= 0)
9675
+ return true;
9676
+ if (!publishedAt)
9677
+ return false;
9678
+ const published = Date.parse(publishedAt);
9679
+ if (Number.isNaN(published))
9680
+ return false;
9681
+ return Date.now() - published >= minReleaseAgeMs;
9682
+ }
9683
+ function pickInstallableTarget2(latest, times, current, minReleaseAgeMs) {
9684
+ if (minReleaseAgeMs <= 0) {
9685
+ return isStableUpgrade(latest.version, current) ? latest : null;
9686
+ }
9687
+ let best = null;
9688
+ for (const [version, publishedAt] of Object.entries(times)) {
9689
+ if (!semver_1.default.valid(version) || semver_1.default.prerelease(version))
9690
+ continue;
9691
+ if (current !== null && !semver_1.default.gt(version, current))
9692
+ continue;
9693
+ if (!isOldEnough(publishedAt, minReleaseAgeMs))
9694
+ continue;
9695
+ if (best === null || semver_1.default.gt(version, best.version)) {
9696
+ best = { version, publishedAt };
9697
+ }
9698
+ }
9699
+ return best;
9700
+ }
9701
+ }
9702
+ });
9703
+
9704
+ // ../update-core/dist/index.js
9705
+ var require_dist2 = __commonJS({
9706
+ "../update-core/dist/index.js"(exports) {
9707
+ "use strict";
9708
+ Object.defineProperty(exports, "__esModule", { value: true });
9709
+ exports.pickInstallableTarget = exports.fetchRegistryInfo = exports.detectMinReleaseAgeMsForPm = exports.detectMinReleaseAgeMs = exports.parseYarnAgeGateMs = exports.parseBeforeAgeMs = exports.parseConfigValue = exports.DAY_MS = exports.MINUTE_MS = exports.SECOND_MS = void 0;
9710
+ var config_parse_1 = require_config_parse();
9711
+ Object.defineProperty(exports, "SECOND_MS", { enumerable: true, get: function() {
9712
+ return config_parse_1.SECOND_MS;
9713
+ } });
9714
+ Object.defineProperty(exports, "MINUTE_MS", { enumerable: true, get: function() {
9715
+ return config_parse_1.MINUTE_MS;
9716
+ } });
9717
+ Object.defineProperty(exports, "DAY_MS", { enumerable: true, get: function() {
9718
+ return config_parse_1.DAY_MS;
9719
+ } });
9720
+ Object.defineProperty(exports, "parseConfigValue", { enumerable: true, get: function() {
9721
+ return config_parse_1.parseConfigValue;
9722
+ } });
9723
+ Object.defineProperty(exports, "parseBeforeAgeMs", { enumerable: true, get: function() {
9724
+ return config_parse_1.parseBeforeAgeMs;
9725
+ } });
9726
+ Object.defineProperty(exports, "parseYarnAgeGateMs", { enumerable: true, get: function() {
9727
+ return config_parse_1.parseYarnAgeGateMs;
9728
+ } });
9729
+ var min_release_age_1 = require_min_release_age();
9730
+ Object.defineProperty(exports, "detectMinReleaseAgeMs", { enumerable: true, get: function() {
9731
+ return min_release_age_1.detectMinReleaseAgeMs;
9732
+ } });
9733
+ Object.defineProperty(exports, "detectMinReleaseAgeMsForPm", { enumerable: true, get: function() {
9734
+ return min_release_age_1.detectMinReleaseAgeMsForPm;
9735
+ } });
9736
+ var registry_1 = require_registry();
9737
+ Object.defineProperty(exports, "fetchRegistryInfo", { enumerable: true, get: function() {
9738
+ return registry_1.fetchRegistryInfo;
9739
+ } });
9740
+ var pick_target_1 = require_pick_target();
9741
+ Object.defineProperty(exports, "pickInstallableTarget", { enumerable: true, get: function() {
9742
+ return pick_target_1.pickInstallableTarget;
9743
+ } });
9744
+ }
9745
+ });
9746
+
9462
9747
  // ../../node_modules/@clack/core/dist/index.mjs
9463
9748
  import { styleText as v } from "node:util";
9464
9749
  import { stdout as x, stdin as D } from "node:process";
@@ -14326,8 +14611,24 @@ function runNpxSkills(args, interactive, cwd) {
14326
14611
 
14327
14612
  // ../argent-installer/src/update.ts
14328
14613
  var import_picocolors3 = __toESM(require_picocolors(), 1);
14614
+ var import_semver2 = __toESM(require_semver2(), 1);
14329
14615
  import { execFileSync as execFileSync3 } from "node:child_process";
14330
14616
 
14617
+ // ../argent-installer/src/update-target.ts
14618
+ var import_update_core = __toESM(require_dist2(), 1);
14619
+ async function resolveInstallableUpdateTarget(pm, current) {
14620
+ const info = await (0, import_update_core.fetchRegistryInfo)(`${NPM_REGISTRY}/${PACKAGE_NAME}`);
14621
+ if (info === null) return null;
14622
+ const minReleaseAgeMs = await (0, import_update_core.detectMinReleaseAgeMsForPm)(pm);
14623
+ const target = (0, import_update_core.pickInstallableTarget)(info.latest, info.times, current, minReleaseAgeMs);
14624
+ return {
14625
+ latestVersion: info.latest.version,
14626
+ latestPublishedAt: info.latest.publishedAt,
14627
+ targetVersion: target?.version ?? null,
14628
+ minReleaseAgeMs
14629
+ };
14630
+ }
14631
+
14331
14632
  // ../argent-tools-client/src/launcher.ts
14332
14633
  import * as net from "node:net";
14333
14634
  import * as fs3 from "node:fs";
@@ -14364,8 +14665,21 @@ async function killToolServer() {
14364
14665
  }
14365
14666
 
14366
14667
  // ../argent-installer/src/update.ts
14668
+ function getRequestedVersion(args) {
14669
+ for (let i = 0; i < args.length; i += 1) {
14670
+ const arg = args[i];
14671
+ if (arg === "--version") {
14672
+ return args[i + 1] ?? null;
14673
+ }
14674
+ if (arg?.startsWith("--version=")) {
14675
+ return arg.slice("--version=".length) || null;
14676
+ }
14677
+ }
14678
+ return null;
14679
+ }
14367
14680
  async function update(args) {
14368
14681
  const nonInteractive = args.includes("--yes") || args.includes("-y");
14682
+ const requestedVersion = getRequestedVersion(args);
14369
14683
  ge(import_picocolors3.default.bgCyan(import_picocolors3.default.black(" argent update ")));
14370
14684
  const globallyInstalled = isGloballyInstalled();
14371
14685
  const installed = globallyInstalled ? getGloballyInstalledVersion() : null;
@@ -14375,13 +14689,34 @@ async function update(args) {
14375
14689
  }
14376
14690
  const spinner = ft();
14377
14691
  spinner.start("Checking for updates...");
14378
- let latest;
14379
- try {
14380
- latest = getLatestVersion();
14381
- } catch (err) {
14382
- spinner.stop(import_picocolors3.default.red("Could not reach registry."));
14383
- R2.error(`Failed to check registry: ${err}`);
14384
- process.exit(1);
14692
+ const pm = detectPackageManager();
14693
+ let latest = null;
14694
+ let target = null;
14695
+ let minReleaseAgeMs = 0;
14696
+ if (requestedVersion !== null) {
14697
+ if (!import_semver2.default.valid(requestedVersion) || import_semver2.default.prerelease(requestedVersion)) {
14698
+ spinner.stop(import_picocolors3.default.red("Invalid update target."));
14699
+ R2.error(`Requested version is not a stable semver: ${requestedVersion}`);
14700
+ process.exit(1);
14701
+ }
14702
+ target = requestedVersion;
14703
+ } else {
14704
+ let resolved;
14705
+ try {
14706
+ resolved = await resolveInstallableUpdateTarget(pm, installed);
14707
+ } catch (err) {
14708
+ spinner.stop(import_picocolors3.default.red("Could not reach registry."));
14709
+ R2.error(`Failed to check registry: ${err}`);
14710
+ process.exit(1);
14711
+ }
14712
+ if (resolved === null) {
14713
+ spinner.stop(import_picocolors3.default.red("Could not reach registry."));
14714
+ R2.error("Failed to determine the latest Argent release from the registry.");
14715
+ process.exit(1);
14716
+ }
14717
+ latest = resolved.latestVersion;
14718
+ target = resolved.targetVersion;
14719
+ minReleaseAgeMs = resolved.minReleaseAgeMs;
14385
14720
  }
14386
14721
  spinner.stop("Version check complete.");
14387
14722
  if (installed) {
@@ -14389,19 +14724,26 @@ async function update(args) {
14389
14724
  } else {
14390
14725
  R2.warn(`${PACKAGE_NAME} is not installed globally.`);
14391
14726
  }
14392
- R2.info(`Latest: ${import_picocolors3.default.cyan(`v${latest}`)}`);
14393
- const needsInstall = !installed || isNewerVersion(latest, installed);
14394
- if (needsInstall) {
14727
+ if (latest) {
14728
+ R2.info(`Latest: ${import_picocolors3.default.cyan(`v${latest}`)}`);
14729
+ }
14730
+ if (target) {
14731
+ const label = latest && latest !== target ? "Target: " : "Version: ";
14732
+ const suffix = latest && latest !== target ? import_picocolors3.default.dim(" (newest installable)") : "";
14733
+ R2.info(`${label}${import_picocolors3.default.cyan(`v${target}`)}${suffix}`);
14734
+ }
14735
+ const needsInstall = target !== null && (!installed || isNewerVersion(target, installed));
14736
+ const latestIsNewer = latest !== null && (!installed || isNewerVersion(latest, installed));
14737
+ if (needsInstall && target !== null) {
14395
14738
  if (installed) {
14396
- R2.warn(`Update available: ${import_picocolors3.default.yellow(`v${installed}`)} -> ${import_picocolors3.default.green(`v${latest}`)}`);
14739
+ R2.warn(`Update available: ${import_picocolors3.default.yellow(`v${installed}`)} -> ${import_picocolors3.default.green(`v${target}`)}`);
14397
14740
  }
14398
- const pm = detectPackageManager();
14399
- const cmd = globalInstallCommand(pm, `${PACKAGE_NAME}@${latest}`);
14741
+ const cmd = globalInstallCommand(pm, `${PACKAGE_NAME}@${target}`);
14400
14742
  const cmdStr = formatShellCommand(cmd);
14401
14743
  if (!nonInteractive) {
14402
14744
  R2.message(import_picocolors3.default.dim(" Press y for yes, n for no, enter to confirm."));
14403
14745
  const proceed = await ue({
14404
- message: installed ? `Update to v${latest}?` : `Install ${PACKAGE_NAME}@${latest} globally?`,
14746
+ message: installed ? `Update to v${target}?` : `Install ${PACKAGE_NAME}@${target} globally?`,
14405
14747
  initialValue: true
14406
14748
  });
14407
14749
  if (q(proceed) || !proceed) {
@@ -14421,7 +14763,16 @@ async function update(args) {
14421
14763
  process.exit(1);
14422
14764
  }
14423
14765
  } else {
14424
- R2.success("Already on the latest version.");
14766
+ if (latest && target === null && latestIsNewer && minReleaseAgeMs > 0) {
14767
+ R2.warn(
14768
+ `Latest version ${import_picocolors3.default.cyan(`v${latest}`)} is still held by your minimum-release-age policy.`
14769
+ );
14770
+ R2.info("No installable update is available yet.");
14771
+ } else if (latest && target && latest !== target) {
14772
+ R2.success("Already on the latest installable version.");
14773
+ } else {
14774
+ R2.success("Already on the latest version.");
14775
+ }
14425
14776
  }
14426
14777
  spinner.start("Refreshing workspace configuration...");
14427
14778
  const projectRoot = resolveProjectRoot(process.cwd());
@@ -15602,6 +15602,7 @@ async function ensureToolsServer(paths) {
15602
15602
  }
15603
15603
 
15604
15604
  // ../argent-mcp/src/content.ts
15605
+ import { readFile as readFile2 } from "node:fs/promises";
15605
15606
  var PNG_SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
15606
15607
  async function fetchPngBytes(url) {
15607
15608
  try {
@@ -15615,9 +15616,12 @@ async function fetchPngBytes(url) {
15615
15616
  return null;
15616
15617
  }
15617
15618
  }
15618
- async function toMcpContent(result, outputHint) {
15619
+ async function toMcpContent(result, outputHint, args) {
15619
15620
  if (outputHint === "image" && result && typeof result === "object" && "url" in result) {
15620
15621
  const r = result;
15622
+ if (isRecord(args) && args.includeImageInContext === false) {
15623
+ return [{ type: "text", text: `Saved: ${r.path}` }];
15624
+ }
15621
15625
  const buf = await fetchPngBytes(r.url);
15622
15626
  if (buf) {
15623
15627
  return [
@@ -15638,6 +15642,26 @@ async function toMcpContent(result, outputHint) {
15638
15642
  }
15639
15643
  return [{ type: "text", text: JSON.stringify(result, null, 2) }];
15640
15644
  }
15645
+ function isRecord(value) {
15646
+ return value !== null && typeof value === "object";
15647
+ }
15648
+ function isScreenshotDiffResult(value) {
15649
+ if (!isRecord(value)) return false;
15650
+ return typeof value.summary === "string";
15651
+ }
15652
+ async function screenshotDiffToMcpContent(result) {
15653
+ const blocks = [];
15654
+ if (typeof result.contextDiffPath === "string") {
15655
+ const buf = await readFile2(result.contextDiffPath);
15656
+ blocks.push({
15657
+ type: "image",
15658
+ data: buf.toString("base64"),
15659
+ mimeType: "image/png"
15660
+ });
15661
+ }
15662
+ blocks.push({ type: "text", text: result.summary });
15663
+ return blocks;
15664
+ }
15641
15665
  async function flowRunToMcpContent(result) {
15642
15666
  const blocks = [];
15643
15667
  if (result.executionPrerequisite) {
@@ -15662,7 +15686,7 @@ async function flowRunToMcpContent(result) {
15662
15686
  });
15663
15687
  } else {
15664
15688
  blocks.push({ type: "text", text: `[${num}] ${step.tool}` });
15665
- const stepContent = await toMcpContent(step.result, step.outputHint);
15689
+ const stepContent = await toMcpContent(step.result, step.outputHint, step.args);
15666
15690
  blocks.push(...stepContent);
15667
15691
  }
15668
15692
  }
@@ -15873,14 +15897,21 @@ async function startMcpServer(options) {
15873
15897
  isError: false,
15874
15898
  result
15875
15899
  });
15876
- let content = params.name === "flow-execute" && result && typeof result === "object" && "flow" in result && "steps" in result ? await flowRunToMcpContent(result) : await toMcpContent(result, outputHint);
15900
+ let content;
15901
+ if (params.name === "flow-execute" && result && typeof result === "object" && "flow" in result && "steps" in result) {
15902
+ content = await flowRunToMcpContent(result);
15903
+ } else if (params.name === "screenshot-diff" && isScreenshotDiffResult(result)) {
15904
+ content = await screenshotDiffToMcpContent(result);
15905
+ } else {
15906
+ content = await toMcpContent(result, outputHint, params.arguments);
15907
+ }
15877
15908
  const udid = getUdidFromArgs(params.arguments);
15878
15909
  if (autoScreenshotEnabled() && udid && shouldAutoScreenshot(params.name)) {
15879
15910
  const delayMs = getAutoScreenshotDelayMs(params.name);
15880
15911
  if (delayMs > 0) await new Promise((r) => setTimeout(r, delayMs));
15881
15912
  try {
15882
15913
  const screenshotResult = await callTool("screenshot", { udid });
15883
- const screenshotContent = await toMcpContent(screenshotResult.result, "image");
15914
+ const screenshotContent = await toMcpContent(screenshotResult.result, "image", { udid });
15884
15915
  const hasImage = screenshotContent.some((b) => b.type === "image");
15885
15916
  if (hasImage) {
15886
15917
  content = [