@swmansion/argent 0.11.0 → 0.12.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.
Files changed (43) hide show
  1. package/bin/argent-android-devtools-0.1.0.apk +0 -0
  2. package/bin/argent-simulator-server.cjs +11 -3
  3. package/bin/darwin/ax-service +0 -0
  4. package/bin/darwin/resources/android/LICENSE.txt +186 -0
  5. package/bin/darwin/resources/android/README.md +11 -0
  6. package/bin/darwin/resources/android/arm64-v8a/libscreen-sharing-agent.so +0 -0
  7. package/bin/darwin/resources/android/armeabi-v7a/libscreen-sharing-agent.so +0 -0
  8. package/bin/darwin/resources/android/screen-sharing-agent.jar +0 -0
  9. package/bin/darwin/resources/android/x86_64/libscreen-sharing-agent.so +0 -0
  10. package/bin/darwin/simulator-server +0 -0
  11. package/bin/linux/resources/android/LICENSE.txt +186 -0
  12. package/bin/linux/resources/android/README.md +11 -0
  13. package/bin/linux/resources/android/arm64-v8a/libscreen-sharing-agent.so +0 -0
  14. package/bin/linux/resources/android/armeabi-v7a/libscreen-sharing-agent.so +0 -0
  15. package/bin/linux/resources/android/screen-sharing-agent.jar +0 -0
  16. package/bin/linux/resources/android/x86_64/libscreen-sharing-agent.so +0 -0
  17. package/bin/linux/simulator-server +0 -0
  18. package/bin/linux-arm64/resources/android/LICENSE.txt +186 -0
  19. package/bin/linux-arm64/resources/android/README.md +11 -0
  20. package/bin/linux-arm64/resources/android/arm64-v8a/libscreen-sharing-agent.so +0 -0
  21. package/bin/linux-arm64/resources/android/armeabi-v7a/libscreen-sharing-agent.so +0 -0
  22. package/bin/linux-arm64/resources/android/screen-sharing-agent.jar +0 -0
  23. package/bin/linux-arm64/resources/android/x86_64/libscreen-sharing-agent.so +0 -0
  24. package/bin/linux-arm64/simulator-server +0 -0
  25. package/dist/cli-cmds.mjs +139 -26
  26. package/dist/cli.js +0 -3
  27. package/dist/cli.js.map +1 -1
  28. package/dist/installer.mjs +111 -97
  29. package/dist/mcp-server.mjs +204 -62
  30. package/dist/preview-ui/index.html +4500 -645
  31. package/dist/preview-ui/theme.css +231 -0
  32. package/dist/preview-window/main.cjs +182 -0
  33. package/dist/tool-server.cjs +7719 -3531
  34. package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
  35. package/dylibs/libKeyboardPatch.dylib +0 -0
  36. package/dylibs/libNativeDevtoolsIos.dylib +0 -0
  37. package/package.json +4 -1
  38. package/rules/argent.md +8 -2
  39. package/scripts/postinstall.cjs +6 -2
  40. package/skills/argent-device-interact/SKILL.md +36 -28
  41. package/skills/argent-lens/SKILL.md +101 -0
  42. package/skills/argent-metro-debugger/SKILL.md +18 -16
  43. package/skills/argent-react-native-app-workflow/SKILL.md +8 -8
@@ -6,7 +6,11 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
8
  var __commonJS = (cb, mod) => function __require() {
9
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
+ try {
10
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
+ } catch (e) {
12
+ throw mod = 0, e;
13
+ }
10
14
  };
11
15
  var __export = (target, all) => {
12
16
  for (var name in all)
@@ -2980,7 +2984,7 @@ var require_compile = __commonJS({
2980
2984
  const schOrFunc = root.refs[ref];
2981
2985
  if (schOrFunc)
2982
2986
  return schOrFunc;
2983
- let _sch = resolve2.call(this, root, ref);
2987
+ let _sch = resolve3.call(this, root, ref);
2984
2988
  if (_sch === void 0) {
2985
2989
  const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
2986
2990
  const { schemaId } = this.opts;
@@ -3007,7 +3011,7 @@ var require_compile = __commonJS({
3007
3011
  function sameSchemaEnv(s1, s2) {
3008
3012
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3009
3013
  }
3010
- function resolve2(root, ref) {
3014
+ function resolve3(root, ref) {
3011
3015
  let sch;
3012
3016
  while (typeof (sch = this.refs[ref]) == "string")
3013
3017
  ref = sch;
@@ -3225,8 +3229,8 @@ var require_utils = __commonJS({
3225
3229
  }
3226
3230
  return ind;
3227
3231
  }
3228
- function removeDotSegments(path4) {
3229
- let input = path4;
3232
+ function removeDotSegments(path6) {
3233
+ let input = path6;
3230
3234
  const output = [];
3231
3235
  let nextSlash = -1;
3232
3236
  let len = 0;
@@ -3478,8 +3482,8 @@ var require_schemes = __commonJS({
3478
3482
  wsComponent.secure = void 0;
3479
3483
  }
3480
3484
  if (wsComponent.resourceName) {
3481
- const [path4, query] = wsComponent.resourceName.split("?");
3482
- wsComponent.path = path4 && path4 !== "/" ? path4 : void 0;
3485
+ const [path6, query] = wsComponent.resourceName.split("?");
3486
+ wsComponent.path = path6 && path6 !== "/" ? path6 : void 0;
3483
3487
  wsComponent.query = query;
3484
3488
  wsComponent.resourceName = void 0;
3485
3489
  }
@@ -3638,7 +3642,7 @@ var require_fast_uri = __commonJS({
3638
3642
  }
3639
3643
  return uri;
3640
3644
  }
3641
- function resolve2(baseURI, relativeURI, options) {
3645
+ function resolve3(baseURI, relativeURI, options) {
3642
3646
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3643
3647
  const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
3644
3648
  schemelessOptions.skipEscape = true;
@@ -3896,7 +3900,7 @@ var require_fast_uri = __commonJS({
3896
3900
  var fastUri = {
3897
3901
  SCHEMES,
3898
3902
  normalize,
3899
- resolve: resolve2,
3903
+ resolve: resolve3,
3900
3904
  resolveComponent,
3901
3905
  equal,
3902
3906
  serialize,
@@ -6872,12 +6876,12 @@ var require_dist = __commonJS({
6872
6876
  throw new Error(`Unknown format "${name}"`);
6873
6877
  return f;
6874
6878
  };
6875
- function addFormats(ajv, list, fs3, exportName) {
6879
+ function addFormats(ajv, list, fs4, exportName) {
6876
6880
  var _a3;
6877
6881
  var _b;
6878
6882
  (_a3 = (_b = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
6879
6883
  for (const f of list)
6880
- ajv.addFormat(f, fs3[f]);
6884
+ ajv.addFormat(f, fs4[f]);
6881
6885
  }
6882
6886
  module.exports = exports = formatsPlugin;
6883
6887
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -6886,8 +6890,8 @@ var require_dist = __commonJS({
6886
6890
  });
6887
6891
 
6888
6892
  // ../argent-mcp/src/mcp-server.ts
6889
- import { appendFile, mkdir as mkdir4 } from "node:fs/promises";
6890
- import { dirname as dirname2 } from "node:path";
6893
+ import { appendFile, mkdir as mkdir5 } from "node:fs/promises";
6894
+ import { dirname as dirname3 } from "node:path";
6891
6895
  import { homedir as homedir4 } from "node:os";
6892
6896
 
6893
6897
  // ../../node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
@@ -7133,10 +7137,10 @@ function mergeDefs(...defs) {
7133
7137
  function cloneDef(schema) {
7134
7138
  return mergeDefs(schema._zod.def);
7135
7139
  }
7136
- function getElementAtPath(obj, path4) {
7137
- if (!path4)
7140
+ function getElementAtPath(obj, path6) {
7141
+ if (!path6)
7138
7142
  return obj;
7139
- return path4.reduce((acc, key) => acc?.[key], obj);
7143
+ return path6.reduce((acc, key) => acc?.[key], obj);
7140
7144
  }
7141
7145
  function promiseAllObject(promisesObj) {
7142
7146
  const keys = Object.keys(promisesObj);
@@ -7545,11 +7549,11 @@ function explicitlyAborted(x, startIndex = 0) {
7545
7549
  }
7546
7550
  return false;
7547
7551
  }
7548
- function prefixIssues(path4, issues) {
7552
+ function prefixIssues(path6, issues) {
7549
7553
  return issues.map((iss) => {
7550
7554
  var _a3;
7551
7555
  (_a3 = iss).path ?? (_a3.path = []);
7552
- iss.path.unshift(path4);
7556
+ iss.path.unshift(path6);
7553
7557
  return iss;
7554
7558
  });
7555
7559
  }
@@ -7696,16 +7700,16 @@ function flattenError(error2, mapper = (issue2) => issue2.message) {
7696
7700
  }
7697
7701
  function formatError(error2, mapper = (issue2) => issue2.message) {
7698
7702
  const fieldErrors = { _errors: [] };
7699
- const processError = (error3, path4 = []) => {
7703
+ const processError = (error3, path6 = []) => {
7700
7704
  for (const issue2 of error3.issues) {
7701
7705
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7702
- issue2.errors.map((issues) => processError({ issues }, [...path4, ...issue2.path]));
7706
+ issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
7703
7707
  } else if (issue2.code === "invalid_key") {
7704
- processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
7708
+ processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
7705
7709
  } else if (issue2.code === "invalid_element") {
7706
- processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
7710
+ processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
7707
7711
  } else {
7708
- const fullpath = [...path4, ...issue2.path];
7712
+ const fullpath = [...path6, ...issue2.path];
7709
7713
  if (fullpath.length === 0) {
7710
7714
  fieldErrors._errors.push(mapper(issue2));
7711
7715
  } else {
@@ -13697,12 +13701,12 @@ var StdioServerTransport = class {
13697
13701
  this.onclose?.();
13698
13702
  }
13699
13703
  send(message) {
13700
- return new Promise((resolve2) => {
13704
+ return new Promise((resolve3) => {
13701
13705
  const json = serializeMessage(message);
13702
13706
  if (this._stdout.write(json)) {
13703
- resolve2();
13707
+ resolve3();
13704
13708
  } else {
13705
- this._stdout.once("drain", resolve2);
13709
+ this._stdout.once("drain", resolve3);
13706
13710
  }
13707
13711
  });
13708
13712
  }
@@ -14300,7 +14304,7 @@ var Protocol = class {
14300
14304
  return;
14301
14305
  }
14302
14306
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
14303
- await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
14307
+ await new Promise((resolve3) => setTimeout(resolve3, pollInterval));
14304
14308
  options?.signal?.throwIfAborted();
14305
14309
  }
14306
14310
  } catch (error2) {
@@ -14317,7 +14321,7 @@ var Protocol = class {
14317
14321
  */
14318
14322
  request(request, resultSchema, options) {
14319
14323
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
14320
- return new Promise((resolve2, reject) => {
14324
+ return new Promise((resolve3, reject) => {
14321
14325
  const earlyReject = (error2) => {
14322
14326
  reject(error2);
14323
14327
  };
@@ -14395,7 +14399,7 @@ var Protocol = class {
14395
14399
  if (!parseResult.success) {
14396
14400
  reject(parseResult.error);
14397
14401
  } else {
14398
- resolve2(parseResult.data);
14402
+ resolve3(parseResult.data);
14399
14403
  }
14400
14404
  } catch (error2) {
14401
14405
  reject(error2);
@@ -14656,12 +14660,12 @@ var Protocol = class {
14656
14660
  }
14657
14661
  } catch {
14658
14662
  }
14659
- return new Promise((resolve2, reject) => {
14663
+ return new Promise((resolve3, reject) => {
14660
14664
  if (signal.aborted) {
14661
14665
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
14662
14666
  return;
14663
14667
  }
14664
- const timeoutId = setTimeout(resolve2, interval);
14668
+ const timeoutId = setTimeout(resolve3, interval);
14665
14669
  signal.addEventListener("abort", () => {
14666
14670
  clearTimeout(timeoutId);
14667
14671
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -15483,7 +15487,7 @@ function generateToken() {
15483
15487
  return randomBytes(AUTH_TOKEN_BYTES).toString("hex");
15484
15488
  }
15485
15489
  function findFreePort() {
15486
- return new Promise((resolve2, reject) => {
15490
+ return new Promise((resolve3, reject) => {
15487
15491
  const srv = net.createServer();
15488
15492
  srv.listen(0, "127.0.0.1", () => {
15489
15493
  const addr = srv.address();
@@ -15494,7 +15498,7 @@ function findFreePort() {
15494
15498
  const port = addr.port;
15495
15499
  srv.close((err) => {
15496
15500
  if (err) reject(err);
15497
- else resolve2(port);
15501
+ else resolve3(port);
15498
15502
  });
15499
15503
  });
15500
15504
  srv.on("error", reject);
@@ -15536,7 +15540,7 @@ async function isToolsServerHealthy(port, host = "127.0.0.1", timeoutMs = 2e3, t
15536
15540
  }
15537
15541
  }
15538
15542
  function spawnToolsServer(paths, port, options = {}) {
15539
- return new Promise((resolve2, reject) => {
15543
+ return new Promise((resolve3, reject) => {
15540
15544
  let logFd;
15541
15545
  try {
15542
15546
  fs.mkdirSync(STATE_DIR, { recursive: true });
@@ -15568,7 +15572,7 @@ function spawnToolsServer(paths, port, options = {}) {
15568
15572
  const actualPort = parseInt(match[1], 10);
15569
15573
  rl.close();
15570
15574
  child.stdout?.resume();
15571
- settle(() => resolve2({ port: actualPort, pid }));
15575
+ settle(() => resolve3({ port: actualPort, pid }));
15572
15576
  }
15573
15577
  });
15574
15578
  child.on("error", (err) => {
@@ -15699,8 +15703,100 @@ async function isRemoteRouted() {
15699
15703
  return url !== null;
15700
15704
  }
15701
15705
 
15706
+ // ../argent-tools-client/src/file-inputs.ts
15707
+ import { mkdir as mkdir3, stat, writeFile as writeFile3 } from "node:fs/promises";
15708
+ import { readFile as readFile3 } from "node:fs/promises";
15709
+ import * as path3 from "node:path";
15710
+ var FILE_INPUT_MARKER = "__argentFileInput";
15711
+ var CLIENT_FILE_MARKER = "__argentClientFile";
15712
+ var MAX_CONTENT_BYTES = 32 * 1024 * 1024;
15713
+ function interpolatePath(template, args) {
15714
+ let missing = false;
15715
+ const out = template.replace(/\$\{([A-Za-z0-9_]+)\}/g, (_m, name) => {
15716
+ const v = args[name];
15717
+ if (typeof v !== "string" || v.length === 0) {
15718
+ missing = true;
15719
+ return "";
15720
+ }
15721
+ return v;
15722
+ });
15723
+ return missing ? null : out;
15724
+ }
15725
+ async function prepareFileInputs(specs, args, opts) {
15726
+ if (!specs || specs.length === 0 || typeof args !== "object" || args === null) {
15727
+ return args;
15728
+ }
15729
+ const record2 = args;
15730
+ let out = null;
15731
+ for (const spec of specs) {
15732
+ if (spec.target in record2 && typeof record2[spec.target] !== "string") continue;
15733
+ const filePath = interpolatePath(spec.path, record2);
15734
+ if (filePath === null) continue;
15735
+ if (spec.target in record2 && record2[spec.target] !== filePath) continue;
15736
+ const wire = { [FILE_INPUT_MARKER]: true, path: filePath };
15737
+ if (spec.kind === "file") {
15738
+ try {
15739
+ const st = await stat(filePath);
15740
+ if (st.isFile()) {
15741
+ wire.size = st.size;
15742
+ wire.mtimeMs = st.mtimeMs;
15743
+ if (opts.includeContent && st.size <= MAX_CONTENT_BYTES) {
15744
+ wire.content = (await readFile3(filePath)).toString("base64");
15745
+ } else if (opts.includeContent) {
15746
+ wire.contentOmitted = "size-limit";
15747
+ }
15748
+ }
15749
+ } catch {
15750
+ }
15751
+ }
15752
+ out = out ?? { ...record2 };
15753
+ out[spec.target] = wire;
15754
+ }
15755
+ return out ?? args;
15756
+ }
15757
+ function isAllowedClientFilePath(p) {
15758
+ if (!path3.isAbsolute(p)) return false;
15759
+ const segments = p.split(/[\\/]+/);
15760
+ if (segments.includes("..")) return false;
15761
+ const file = segments[segments.length - 1] ?? "";
15762
+ if (!/^[A-Za-z0-9_-]+\.yaml$/.test(file)) return false;
15763
+ return segments[segments.length - 3] === ".argent" && segments[segments.length - 2] === "flows";
15764
+ }
15765
+ function isClientFileDirective(value) {
15766
+ return !!value && typeof value === "object" && value[CLIENT_FILE_MARKER] === true && typeof value.path === "string" && typeof value.content === "string";
15767
+ }
15768
+ async function applyClientFileDirectives(result) {
15769
+ const written = [];
15770
+ async function walk(value) {
15771
+ if (isClientFileDirective(value)) {
15772
+ if (!isAllowedClientFilePath(value.path)) return null;
15773
+ try {
15774
+ await mkdir3(path3.dirname(value.path), { recursive: true });
15775
+ await writeFile3(value.path, value.content, "utf8");
15776
+ written.push(value.path);
15777
+ return value.path;
15778
+ } catch {
15779
+ return null;
15780
+ }
15781
+ }
15782
+ if (Array.isArray(value)) {
15783
+ return Promise.all(value.map(walk));
15784
+ }
15785
+ if (value && typeof value === "object") {
15786
+ const out = {};
15787
+ for (const [k, v] of Object.entries(value)) {
15788
+ out[k] = await walk(v);
15789
+ }
15790
+ return out;
15791
+ }
15792
+ return value;
15793
+ }
15794
+ const rewritten = await walk(result);
15795
+ return { result: rewritten, written };
15796
+ }
15797
+
15702
15798
  // ../argent-tools-client/src/artifacts.ts
15703
- import { mkdir as mkdir3, readFile as readFile3, rm, stat, writeFile as writeFile3 } from "node:fs/promises";
15799
+ import { mkdir as mkdir4, readFile as readFile4, rm, stat as stat2, writeFile as writeFile4 } from "node:fs/promises";
15704
15800
  import { tmpdir } from "node:os";
15705
15801
  import { basename, join as join3 } from "node:path";
15706
15802
  import { createHash } from "node:crypto";
@@ -15739,7 +15835,7 @@ function artifactDir(deviceId) {
15739
15835
  async function resolveLocalFile(handle) {
15740
15836
  if (!handle.hostPath) return null;
15741
15837
  try {
15742
- const st = await stat(handle.hostPath);
15838
+ const st = await stat2(handle.hostPath);
15743
15839
  if (handle.archive) {
15744
15840
  return st.isDirectory() ? handle.hostPath : null;
15745
15841
  }
@@ -15756,7 +15852,7 @@ async function resolveLocalFile(handle) {
15756
15852
  async function downloadAndExtractArchive(handle, data, dir) {
15757
15853
  const tarball = join3(dir, `${sanitizeSegment(handle.filename)}.tar.gz`);
15758
15854
  try {
15759
- await writeFile3(tarball, data);
15855
+ await writeFile4(tarball, data);
15760
15856
  await execFileAsync("tar", ["-xzf", tarball, "-C", dir]);
15761
15857
  return join3(dir, handle.filename);
15762
15858
  } catch {
@@ -15774,7 +15870,7 @@ async function materializeArtifacts(result, ctx) {
15774
15870
  let dirReady = false;
15775
15871
  async function ensureDir() {
15776
15872
  if (!dirReady) {
15777
- await mkdir3(dir, { recursive: true });
15873
+ await mkdir4(dir, { recursive: true });
15778
15874
  dirReady = true;
15779
15875
  }
15780
15876
  }
@@ -15783,7 +15879,7 @@ async function materializeArtifacts(result, ctx) {
15783
15879
  const localPath = await resolveLocalFile(value);
15784
15880
  if (localPath) {
15785
15881
  if (value.mimeType.startsWith("image/")) {
15786
- images.push({ localPath, data: await readFile3(localPath), mimeType: value.mimeType });
15882
+ images.push({ localPath, data: await readFile4(localPath), mimeType: value.mimeType });
15787
15883
  }
15788
15884
  return localPath;
15789
15885
  }
@@ -15799,7 +15895,7 @@ async function materializeArtifacts(result, ctx) {
15799
15895
  }
15800
15896
  if (value.size > 0 && data.length !== value.size) return null;
15801
15897
  const downloadedPath = join3(dir, sanitizeSegment(value.filename));
15802
- await writeFile3(downloadedPath, data);
15898
+ await writeFile4(downloadedPath, data);
15803
15899
  if (value.mimeType.startsWith("image/")) {
15804
15900
  images.push({ localPath: downloadedPath, data, mimeType: value.mimeType });
15805
15901
  }
@@ -15832,7 +15928,7 @@ function getDeviceIdFromArgs(args) {
15832
15928
  }
15833
15929
 
15834
15930
  // ../argent-mcp/src/content.ts
15835
- import { readFile as readFile4 } from "node:fs/promises";
15931
+ import { readFile as readFile5 } from "node:fs/promises";
15836
15932
  var PNG_SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
15837
15933
  function imageBlock(data, mimeType) {
15838
15934
  return { type: "image", data: data.toString("base64"), mimeType };
@@ -15898,15 +15994,34 @@ function isScreenshotDiffResult(value) {
15898
15994
  if (!isRecord(value)) return false;
15899
15995
  return typeof value.summary === "string";
15900
15996
  }
15901
- async function screenshotDiffToMcpContent(result) {
15997
+ async function screenshotDiffToMcpContent(result, ctx) {
15902
15998
  const blocks = [];
15903
- if (typeof result.contextDiffPath === "string") {
15904
- const buf = await readFile4(result.contextDiffPath);
15905
- blocks.push({
15906
- type: "image",
15907
- data: buf.toString("base64"),
15908
- mimeType: "image/png"
15909
- });
15999
+ let contextDiffPath = result.contextDiffPath;
16000
+ let materializedImages = [];
16001
+ if (ctx) {
16002
+ const { result: rewritten, images } = await materializeArtifacts(result, ctx);
16003
+ contextDiffPath = rewritten.contextDiffPath;
16004
+ materializedImages = images;
16005
+ }
16006
+ if (typeof contextDiffPath === "string") {
16007
+ const fromMaterializer = materializedImages.find((img) => img.localPath === contextDiffPath);
16008
+ if (fromMaterializer) {
16009
+ blocks.push({
16010
+ type: "image",
16011
+ data: fromMaterializer.data.toString("base64"),
16012
+ mimeType: fromMaterializer.mimeType
16013
+ });
16014
+ } else {
16015
+ try {
16016
+ const buf = await readFile5(contextDiffPath);
16017
+ blocks.push({
16018
+ type: "image",
16019
+ data: buf.toString("base64"),
16020
+ mimeType: "image/png"
16021
+ });
16022
+ } catch {
16023
+ }
16024
+ }
15910
16025
  }
15911
16026
  blocks.push({ type: "text", text: result.summary });
15912
16027
  return blocks;
@@ -15945,17 +16060,17 @@ async function flowRunToMcpContent(result, ctx) {
15945
16060
 
15946
16061
  // ../configuration-core/src/flags.ts
15947
16062
  import * as fs2 from "node:fs";
15948
- import * as path3 from "node:path";
16063
+ import * as path4 from "node:path";
15949
16064
  import { homedir as homedir3 } from "node:os";
15950
16065
  var PROJECT_MARKERS = [".argent", ".git", "package.json"];
15951
16066
  function resolveProjectRoot(startDir) {
15952
- const initial = path3.resolve(startDir);
16067
+ const initial = path4.resolve(startDir);
15953
16068
  let current = initial;
15954
16069
  while (true) {
15955
16070
  for (const marker of PROJECT_MARKERS) {
15956
- if (fs2.existsSync(path3.join(current, marker))) return current;
16071
+ if (fs2.existsSync(path4.join(current, marker))) return current;
15957
16072
  }
15958
- const parent = path3.dirname(current);
16073
+ const parent = path4.dirname(current);
15959
16074
  if (parent === current) return initial;
15960
16075
  current = parent;
15961
16076
  }
@@ -15963,10 +16078,10 @@ function resolveProjectRoot(startDir) {
15963
16078
  function getFlagsPath(scope, options = {}) {
15964
16079
  const home = options.homeDir ?? homedir3();
15965
16080
  if (scope === "global") {
15966
- return path3.join(home, ".argent", "flags.json");
16081
+ return path4.join(home, ".argent", "flags.json");
15967
16082
  }
15968
16083
  const cwd = options.cwd ?? process.cwd();
15969
- return path3.join(resolveProjectRoot(cwd), ".argent", "flags.json");
16084
+ return path4.join(resolveProjectRoot(cwd), ".argent", "flags.json");
15970
16085
  }
15971
16086
  function readFlagsFile(filePath) {
15972
16087
  let raw;
@@ -16005,6 +16120,8 @@ function isFlagEnabled(name, options = {}) {
16005
16120
  var AUTO_SCREENSHOT_TOOLS = /* @__PURE__ */ new Set([
16006
16121
  "gesture-tap",
16007
16122
  "gesture-swipe",
16123
+ "gesture-scroll",
16124
+ "gesture-drag",
16008
16125
  "gesture-custom",
16009
16126
  "gesture-pinch",
16010
16127
  "gesture-rotate",
@@ -16022,6 +16139,8 @@ var AUTO_SCREENSHOT_DELAY_MS_BY_TOOL = {
16022
16139
  "restart-app": 3e3,
16023
16140
  "open-url": 2e3,
16024
16141
  "gesture-swipe": 1500,
16142
+ "gesture-scroll": 1500,
16143
+ "gesture-drag": 1500,
16025
16144
  "gesture-custom": 1500,
16026
16145
  "gesture-tap": 1500,
16027
16146
  "gesture-pinch": 1500,
@@ -16074,6 +16193,19 @@ function toMcpTool(t) {
16074
16193
  };
16075
16194
  }
16076
16195
 
16196
+ // ../argent-mcp/src/installed-version.ts
16197
+ import * as fs3 from "node:fs";
16198
+ import * as path5 from "node:path";
16199
+ function getInstalledVersion() {
16200
+ try {
16201
+ const pkgPath = path5.resolve(import.meta.dirname, "..", "package.json");
16202
+ const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf8"));
16203
+ return pkg.version ?? "unknown";
16204
+ } catch {
16205
+ return "unknown";
16206
+ }
16207
+ }
16208
+
16077
16209
  // ../argent-mcp/src/mcp-server.ts
16078
16210
  var MAX_RETRIES = 4;
16079
16211
  var EXP_BACKOFF_BASE = 250;
@@ -16144,7 +16276,7 @@ async function startMcpServer(options) {
16144
16276
  async function spyLog(entry) {
16145
16277
  try {
16146
16278
  if (!logDirReady) {
16147
- await mkdir4(dirname2(LOG_FILE2), { recursive: true });
16279
+ await mkdir5(dirname3(LOG_FILE2), { recursive: true });
16148
16280
  logDirReady = true;
16149
16281
  }
16150
16282
  await appendFile(LOG_FILE2, JSON.stringify(entry) + "\n");
@@ -16161,23 +16293,33 @@ async function startMcpServer(options) {
16161
16293
  async function callTool(name, args) {
16162
16294
  const tools = await fetchTools();
16163
16295
  const meta2 = tools.find((t) => t.name === name);
16296
+ let finalArgs = args;
16297
+ if (meta2?.fileInputs?.length) {
16298
+ finalArgs = await prepareFileInputs(meta2.fileInputs, args ?? {}, {
16299
+ // `resolved` is the startup routing decision that picked TOOLS_URL —
16300
+ // an external target means this process may not share the server's
16301
+ // filesystem, so file bytes must ride along.
16302
+ includeContent: resolved.url !== null
16303
+ });
16304
+ }
16164
16305
  const res = await fetchWithReconnect(() => `${TOOLS_URL}/tools/${name}`, reconnect, {
16165
16306
  init: {
16166
16307
  method: "POST",
16167
16308
  headers: { "Content-Type": "application/json", ...authHeader() },
16168
- body: JSON.stringify(args ?? {})
16309
+ body: JSON.stringify(finalArgs ?? {})
16169
16310
  },
16170
16311
  fetchTimeoutMs: meta2?.longRunning ? null : FETCH_TIMEOUT_MS
16171
16312
  });
16172
16313
  const json = await res.json();
16173
16314
  if (!res.ok) throw new Error(json.error ?? json.message ?? res.statusText);
16174
- return { result: json.data, outputHint: meta2?.outputHint, note: json.note };
16315
+ const { result: data } = await applyClientFileDirectives(json.data);
16316
+ return { result: data, outputHint: meta2?.outputHint, note: json.note };
16175
16317
  }
16176
16318
  const server = new Server(
16177
- { name: "argent", version: "0.5.3" },
16319
+ { name: "argent", version: getInstalledVersion() },
16178
16320
  {
16179
16321
  capabilities: { tools: {} },
16180
- instructions: "Argent \u2014 iOS Simulator and Android Emulator control for interacting, testing, profiling and debugging mobile applications. Always use discovery tools (describe / debugger-component-tree / screenshot) before tapping \u2014 never guess coordinates. On session end: call stop-all-simulator-servers and perform any necessary cleanup. Full guidance is in the argent rule loaded from .claude/rules/argent.md."
16322
+ instructions: "Argent \u2014 iOS Simulator, Android Emulator, and Chromium app control for interacting, testing, profiling and debugging mobile and Chromium applications. Always use discovery tools (describe / debugger-component-tree / screenshot) before tapping \u2014 never guess coordinates. On session end: call stop-all-simulator-servers and perform any necessary cleanup. Full guidance is in the argent rule loaded from .claude/rules/argent.md."
16181
16323
  }
16182
16324
  );
16183
16325
  server.setRequestHandler(ListToolsRequestSchema, async () => {
@@ -16224,7 +16366,7 @@ async function startMcpServer(options) {
16224
16366
  if (params.name === "flow-execute" && result && typeof result === "object" && "flow" in result && "steps" in result) {
16225
16367
  content = await flowRunToMcpContent(result, ctx);
16226
16368
  } else if (params.name === "screenshot-diff" && isScreenshotDiffResult(result)) {
16227
- content = await screenshotDiffToMcpContent(result);
16369
+ content = await screenshotDiffToMcpContent(result, ctx);
16228
16370
  } else {
16229
16371
  content = await toMcpContent(result, outputHint, ctx, params.arguments);
16230
16372
  }