@swmansion/argent 0.31.2-next.1 → 0.31.2-next.11

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 (32) hide show
  1. package/bin/argent-android-devtools-0.3.0.apk +0 -0
  2. package/bin/darwin/ax-service +0 -0
  3. package/bin/darwin/tvos-ax-service +0 -0
  4. package/bin/darwin/tvos-hid-daemon +0 -0
  5. package/bin/network-inspector/arm64-v8a/libjvmti_network_inspector.so +0 -0
  6. package/bin/network-inspector/network-inspector.jar +0 -0
  7. package/bin/network-inspector/x86_64/libjvmti_network_inspector.so +0 -0
  8. package/bin/tcp/ax-service +0 -0
  9. package/dist/cli-cmds.mjs +106 -24
  10. package/dist/client.js +83 -14
  11. package/dist/installer.mjs +25 -1
  12. package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentExceptionGuard.h +3 -0
  13. package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentExceptionGuard.m +11 -3
  14. package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentRunnerSession+Gestures.swift +27 -19
  15. package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentRunnerSession+Quiescence.swift +95 -0
  16. package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentRunnerSession+TextEntry.swift +2 -2
  17. package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/RunnerProtocol.swift +5 -5
  18. package/dist/mcp-server.mjs +87 -17
  19. package/dist/tool-args.generated.d.ts +26 -14
  20. package/dist/tool-server.cjs +4604 -1860
  21. package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
  22. package/dylibs/libKeyboardPatch.dylib +0 -0
  23. package/dylibs/libNativeDevtoolsIos.dylib +0 -0
  24. package/dylibs/tcp/libArgentInjectionBootstrap.dylib +0 -0
  25. package/dylibs/tcp/libKeyboardPatch.dylib +0 -0
  26. package/dylibs/tcp/libNativeDevtoolsIos.dylib +0 -0
  27. package/dylibs/tvos/libArgentInjectionBootstrap.dylib +0 -0
  28. package/dylibs/tvos/libKeyboardPatch.dylib +0 -0
  29. package/dylibs/tvos/libNativeDevtoolsIos.dylib +0 -0
  30. package/package.json +1 -1
  31. package/skills/argent-create-e2e/references/live-authoring.md +3 -3
  32. package/skills/argent-ios-device-setup/SKILL.md +1 -1
Binary file
Binary file
Binary file
Binary file
package/dist/cli-cmds.mjs CHANGED
@@ -10310,6 +10310,36 @@ var TOOL_ID_ALIASES = Object.freeze({
10310
10310
  function canonicalToolId(id) {
10311
10311
  return Object.hasOwn(TOOL_ID_ALIASES, id) ? TOOL_ID_ALIASES[id] : id;
10312
10312
  }
10313
+ var TOOL_PARAM_ALIASES = Object.freeze({
10314
+ "e2e-execute": Object.freeze({ flow_path: "e2e_test_path", flow_file: "e2e_test_file" }),
10315
+ "e2e-read-prerequisite": Object.freeze({
10316
+ flow_path: "e2e_test_path",
10317
+ flow_file: "e2e_test_file"
10318
+ })
10319
+ });
10320
+ var ToolParamAliasError = class extends Error {
10321
+ constructor(former, current) {
10322
+ super(`Pass ${current} or its former name ${former}, not both.`);
10323
+ this.name = "ToolParamAliasError";
10324
+ }
10325
+ };
10326
+ function toolParamAliases(tool) {
10327
+ const id = canonicalToolId(tool);
10328
+ return Object.hasOwn(TOOL_PARAM_ALIASES, id) ? TOOL_PARAM_ALIASES[id] : {};
10329
+ }
10330
+ function canonicalToolArgs(tool, args) {
10331
+ if (typeof args !== "object" || args === null || Array.isArray(args)) return args;
10332
+ const record2 = args;
10333
+ let out;
10334
+ for (const [former, current] of Object.entries(toolParamAliases(tool))) {
10335
+ if (record2[former] === void 0) continue;
10336
+ if (record2[current] !== void 0) throw new ToolParamAliasError(former, current);
10337
+ out ??= { ...record2 };
10338
+ out[current] = out[former];
10339
+ delete out[former];
10340
+ }
10341
+ return out ?? args;
10342
+ }
10313
10343
 
10314
10344
  // ../registry/src/flow-file-refs.ts
10315
10345
  async function canonicalFlowPath(p) {
@@ -10379,7 +10409,13 @@ async function classifyOnDiskSpelling(dir, base, addressable = FLOW_FILE_NAME_PA
10379
10409
  }
10380
10410
  function nestedFlowTarget(args) {
10381
10411
  if (typeof args !== "object" || args === null || Array.isArray(args)) return void 0;
10382
- const { name, project_root: projectRoot, flow_path: flowPath } = args;
10412
+ let canonical;
10413
+ try {
10414
+ canonical = canonicalToolArgs("e2e-execute", args);
10415
+ } catch {
10416
+ return void 0;
10417
+ }
10418
+ const { name, project_root: projectRoot, e2e_test_path: flowPath } = canonical;
10383
10419
  if (flowPath === void 0) {
10384
10420
  if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name)) return void 0;
10385
10421
  if (!isResolvedAbsolute(projectRoot)) return void 0;
@@ -10388,7 +10424,7 @@ function nestedFlowTarget(args) {
10388
10424
  }
10389
10425
  if (name !== void 0 || !isResolvedAbsolute(flowPath)) return void 0;
10390
10426
  if (!FLOW_FILE_NAME_PATTERN.test(path8.basename(flowPath))) return void 0;
10391
- return { kind: "flow_path", path: flowPath };
10427
+ return { kind: "e2e_test_path", path: flowPath };
10392
10428
  }
10393
10429
  function isResolvedAbsolute(value) {
10394
10430
  return typeof value === "string" && path8.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
@@ -10420,6 +10456,8 @@ var FAILURE_CODES = {
10420
10456
  TOOL_CAPABILITY_UNSUPPORTED_OPERATION: "TOOL_CAPABILITY_UNSUPPORTED_OPERATION",
10421
10457
  TOOL_PLATFORM_NOT_IMPLEMENTED: "TOOL_PLATFORM_NOT_IMPLEMENTED",
10422
10458
  TOOL_DEPENDENCY_MISSING: "TOOL_DEPENDENCY_MISSING",
10459
+ // Xcode's simctl or devicectl wrapper would start its component install and wait for a password.
10460
+ TOOL_XCODE_FIRST_LAUNCH_PENDING: "TOOL_XCODE_FIRST_LAUNCH_PENDING",
10423
10461
  TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
10424
10462
  TOOLSERVER_UNHANDLED_REJECTION: "TOOLSERVER_UNHANDLED_REJECTION",
10425
10463
  TOOLSERVER_UNCAUGHT_EXCEPTION: "TOOLSERVER_UNCAUGHT_EXCEPTION",
@@ -10592,6 +10630,16 @@ var FAILURE_CODES = {
10592
10630
  JS_RUNTIME_CDP_DISCONNECTED: "JS_RUNTIME_CDP_DISCONNECTED",
10593
10631
  JS_RUNTIME_PAUSED: "JS_RUNTIME_PAUSED",
10594
10632
  NETWORK_INSPECTOR_CDP_DISCONNECTED: "NETWORK_INSPECTOR_CDP_DISCONNECTED",
10633
+ ANDROID_NETWORK_INSPECTOR_FACTORY_OPTIONS_INVALID: "ANDROID_NETWORK_INSPECTOR_FACTORY_OPTIONS_INVALID",
10634
+ ANDROID_NETWORK_INSPECTOR_WRONG_PLATFORM: "ANDROID_NETWORK_INSPECTOR_WRONG_PLATFORM",
10635
+ ANDROID_NETWORK_INSPECTOR_UNKNOWN_PACKAGE: "ANDROID_NETWORK_INSPECTOR_UNKNOWN_PACKAGE",
10636
+ ANDROID_NETWORK_INSPECTOR_RUN_AS_FAILED: "ANDROID_NETWORK_INSPECTOR_RUN_AS_FAILED",
10637
+ ANDROID_NETWORK_INSPECTOR_DEVICE_IN_USE: "ANDROID_NETWORK_INSPECTOR_DEVICE_IN_USE",
10638
+ ANDROID_NETWORK_INSPECTOR_NO_DEVICE_PORT: "ANDROID_NETWORK_INSPECTOR_NO_DEVICE_PORT",
10639
+ NATIVE_NETWORK_LOGS_STOP_UNSUPPORTED: "NATIVE_NETWORK_LOGS_STOP_UNSUPPORTED",
10640
+ NDJSON_CDP_REQUEST_TIMEOUT: "NDJSON_CDP_REQUEST_TIMEOUT",
10641
+ NDJSON_CDP_REQUEST_FAILED: "NDJSON_CDP_REQUEST_FAILED",
10642
+ NDJSON_CDP_CONNECTION_CLOSED: "NDJSON_CDP_CONNECTION_CLOSED",
10595
10643
  REACT_PROFILER_NO_ACTIVE_SESSION: "REACT_PROFILER_NO_ACTIVE_SESSION",
10596
10644
  REACT_PROFILER_CDP_CONNECTION_LOST: "REACT_PROFILER_CDP_CONNECTION_LOST",
10597
10645
  REACT_PROFILER_NO_CPU_PROFILE: "REACT_PROFILER_NO_CPU_PROFILE",
@@ -31111,12 +31159,18 @@ function isResolvedAbsolute2(value) {
31111
31159
  return typeof value === "string" && path11.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
31112
31160
  }
31113
31161
  function namesValidFlow(args) {
31114
- const { project_root, flow_path, name } = args;
31162
+ let canonical;
31163
+ try {
31164
+ canonical = canonicalToolArgs("e2e-execute", args);
31165
+ } catch {
31166
+ return false;
31167
+ }
31168
+ const { project_root, e2e_test_path: testPath, name } = canonical;
31115
31169
  if (!isResolvedAbsolute2(project_root)) return false;
31116
31170
  if (name === void 0) {
31117
- return isResolvedAbsolute2(flow_path) && FLOW_FILE_NAME_PATTERN.test(path11.basename(flow_path));
31171
+ return isResolvedAbsolute2(testPath) && FLOW_FILE_NAME_PATTERN.test(path11.basename(testPath));
31118
31172
  }
31119
- return flow_path === void 0 && typeof name === "string" && FLOW_NAME_PATTERN.test(name);
31173
+ return testPath === void 0 && typeof name === "string" && FLOW_NAME_PATTERN.test(name);
31120
31174
  }
31121
31175
  function savedFlowProject(file2) {
31122
31176
  if (!path11.isAbsolute(file2)) return null;
@@ -31290,8 +31344,8 @@ function memberCollector(roots, opts) {
31290
31344
  `));
31291
31345
  const emit = (member, sent) => {
31292
31346
  members2.push(member);
31293
- const subject = member.role === "flow" ? member.canonical : member.key;
31294
- if (logging) log2(printable(`[flow-files] ${member.role} ${subject}: ${sent}`));
31347
+ const [label, subject] = member.role === "flow" ? ["e2e test", member.canonical] : [member.role, member.key];
31348
+ if (logging) log2(printable(`[e2e-files] ${label} ${subject}: ${sent}`));
31295
31349
  };
31296
31350
  async function flow(anchorDir, target, onlyPresent) {
31297
31351
  const key = flowMemberKey(anchorDir, target);
@@ -31457,7 +31511,7 @@ function recordedStep(args) {
31457
31511
  if (typeof text2 !== "string") return void 0;
31458
31512
  let parsed;
31459
31513
  try {
31460
- parsed = JSON.parse(text2);
31514
+ parsed = canonicalToolArgs(command, JSON.parse(text2));
31461
31515
  } catch {
31462
31516
  return void 0;
31463
31517
  }
@@ -31480,7 +31534,7 @@ async function collectStepMembers(args, opts, recordingDirFor = e2eDirFor) {
31480
31534
  const self2 = await collector.flow(path11.dirname(recording), path11.basename(recording));
31481
31535
  let runArgs = step.args;
31482
31536
  const named = nestedFlowTarget(runArgs);
31483
- if (named?.kind === "flow_path") {
31537
+ if (named?.kind === "e2e_test_path") {
31484
31538
  const stem = path11.basename(named.path, ".yaml");
31485
31539
  const base = path11.basename(named.path);
31486
31540
  const dir = path11.resolve(path11.dirname(named.path));
@@ -31489,7 +31543,7 @@ async function collectStepMembers(args, opts, recordingDirFor = e2eDirFor) {
31489
31543
  if (dirs.some((d) => path11.resolve(d) === dir)) {
31490
31544
  await collector.flow(path11.dirname(named.path), base);
31491
31545
  runArgs = { ...runArgs, name: stem };
31492
- delete runArgs.flow_path;
31546
+ delete runArgs.e2e_test_path;
31493
31547
  }
31494
31548
  }
31495
31549
  const target = nestedFlowTarget(runArgs);
@@ -31517,7 +31571,21 @@ async function nameToE2ePathForOlderServer(tool, fileInputs, args) {
31517
31571
  const picked = await pickE2eFile(target.paths);
31518
31572
  if (!picked.exists || picked.legacy) return args;
31519
31573
  const { name: _name, ...rest } = args;
31520
- return { ...rest, flow_path: picked.path };
31574
+ return { ...rest, e2e_test_path: picked.path };
31575
+ }
31576
+ function formerParamsForOlderServer(meta3, args) {
31577
+ const listed = meta3.inputSchema.properties;
31578
+ if (typeof args !== "object" || args === null || Array.isArray(args)) return args;
31579
+ if (typeof listed !== "object" || listed === null) return args;
31580
+ const record2 = args;
31581
+ let out;
31582
+ for (const [former, current] of Object.entries(toolParamAliases(meta3.name))) {
31583
+ if (record2[current] === void 0 || current in listed || !(former in listed)) continue;
31584
+ out ??= { ...record2 };
31585
+ out[former] = out[current];
31586
+ delete out[current];
31587
+ }
31588
+ return out ?? args;
31521
31589
  }
31522
31590
  async function stepForOlderServer(args, listedId) {
31523
31591
  if (typeof args !== "object" || args === null || Array.isArray(args)) return args;
@@ -31775,12 +31843,13 @@ function createToolsClient(options = {}) {
31775
31843
  async function callTool(name, args, opts) {
31776
31844
  opts?.signal?.throwIfAborted();
31777
31845
  const { url: url2, token, remote } = await route();
31778
- let finalArgs = args;
31846
+ let finalArgs = canonicalToolArgs(name, args);
31779
31847
  const tools2 = await fetchTools({ signal: opts?.signal });
31780
31848
  const meta3 = findTool(tools2, name);
31781
31849
  const olderServer = meta3 !== null && !tools2.some((t2) => t2.name === canonicalToolId(meta3.name));
31782
31850
  if (meta3) {
31783
- finalArgs = await nameToE2ePathForOlderServer(meta3.name, meta3.fileInputs, args);
31851
+ finalArgs = await nameToE2ePathForOlderServer(meta3.name, meta3.fileInputs, finalArgs);
31852
+ finalArgs = formerParamsForOlderServer(meta3, finalArgs);
31784
31853
  }
31785
31854
  if (olderServer && canonicalToolId(meta3.name) === "e2e-add-step") {
31786
31855
  finalArgs = await stepForOlderServer(finalArgs, (tool) => findTool(tools2, tool)?.name);
@@ -31808,7 +31877,7 @@ function createToolsClient(options = {}) {
31808
31877
  if (filesLogEnabled()) {
31809
31878
  for (const file2 of applied.written) {
31810
31879
  if (baselineDirs.includes(path12.dirname(file2))) {
31811
- diagnose(`[flow-files] baseline ${file2}: written`);
31880
+ diagnose(`[e2e-files] baseline ${file2}: written`);
31812
31881
  }
31813
31882
  }
31814
31883
  }
@@ -35740,7 +35809,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
35740
35809
  var SESSION_ID2 = randomUUID5();
35741
35810
  function readCliVersion() {
35742
35811
  if (true) {
35743
- return "0.31.2-next.0";
35812
+ return "0.31.2-next.10";
35744
35813
  }
35745
35814
  return "0.0.0";
35746
35815
  }
@@ -37203,8 +37272,12 @@ function renderEchoLine(s) {
37203
37272
  }
37204
37273
  return ` ${indent}\u203A ${s.message}`;
37205
37274
  }
37275
+ function e2eTestOf(r2) {
37276
+ return r2.e2eTest ?? r2.flow;
37277
+ }
37206
37278
  function stepLabel(s, topFlow) {
37207
- const where = s.flow && s.flow !== topFlow ? ` [${s.flow}]` : "";
37279
+ const owner = e2eTestOf(s);
37280
+ const where = owner && owner !== topFlow ? ` [${owner}]` : "";
37208
37281
  const what = s.tool ?? s.target;
37209
37282
  return `${what ? `${s.kind} ${what}` : s.kind}${where}`;
37210
37283
  }
@@ -37261,7 +37334,7 @@ function renderFailedSteps(report) {
37261
37334
  if (s.status !== "fail" && s.status !== "error" && !s.warning && !scriptNote && scriptLog.length === 0) {
37262
37335
  continue;
37263
37336
  }
37264
- lines.push(renderStepLine(s, n3, report.flow));
37337
+ lines.push(renderStepLine(s, n3, e2eTestOf(report)));
37265
37338
  if (s.warning) lines.push(renderUnderStepLine(s, n3, `\u26A0 ${s.warning}`));
37266
37339
  lines.push(...scriptLog);
37267
37340
  if (s.artifacts && typeof s.artifacts === "object") {
@@ -37282,7 +37355,7 @@ function summarizeFailure(report) {
37282
37355
  n3++;
37283
37356
  if (s.status === "fail" || s.status === "error") {
37284
37357
  const detail = s.reason ? String(s.reason) : void 0;
37285
- return { headline: `step ${n3} ${stepLabel(s, report.flow)}`, detail };
37358
+ return { headline: `step ${n3} ${stepLabel(s, e2eTestOf(report))}`, detail };
37286
37359
  }
37287
37360
  }
37288
37361
  return { headline: "failed with no failing step" };
@@ -37322,11 +37395,15 @@ function rerunCommand(flowPath, rel, projectRoot, args) {
37322
37395
  if (args.output) parts.push("--output", pathArg(path18.join(args.output, path18.dirname(rel))));
37323
37396
  return parts.join(" ");
37324
37397
  }
37325
- var EXPORT_SOURCE_MARKER = ".argent-flow-source";
37398
+ var EXPORT_SOURCE_MARKER = ".argent-e2e-source";
37399
+ var LEGACY_EXPORT_SOURCE_MARKER = ".argent-flow-source";
37326
37400
  var MARKER_READ_RETRIES = 4;
37327
37401
  var MARKER_READ_DELAY_MS = 5;
37328
37402
  async function readExportMarker(dir) {
37329
- const marker = path18.join(dir, EXPORT_SOURCE_MARKER);
37403
+ const owner = await readMarkerFile(path18.join(dir, EXPORT_SOURCE_MARKER));
37404
+ return owner !== void 0 ? owner : await readMarkerFile(path18.join(dir, LEGACY_EXPORT_SOURCE_MARKER));
37405
+ }
37406
+ async function readMarkerFile(marker) {
37330
37407
  for (let attempt = 0; ; attempt++) {
37331
37408
  let owner;
37332
37409
  try {
@@ -37469,7 +37546,7 @@ function exitAfterFlush(code, streams = [process.stdout, process.stderr]) {
37469
37546
  }
37470
37547
  function renderReport(report) {
37471
37548
  const lines = [];
37472
- lines.push(`E2E test "${report.flow}"${report.device ? ` on ${report.device}` : ""}`);
37549
+ lines.push(`E2E test "${e2eTestOf(report)}"${report.device ? ` on ${report.device}` : ""}`);
37473
37550
  if (report.executionPrerequisite) {
37474
37551
  lines.push(` assumes: ${report.executionPrerequisite}`);
37475
37552
  }
@@ -37481,7 +37558,7 @@ function renderReport(report) {
37481
37558
  continue;
37482
37559
  }
37483
37560
  n3++;
37484
- lines.push(renderStepLine(s, n3, report.flow));
37561
+ lines.push(renderStepLine(s, n3, e2eTestOf(report)));
37485
37562
  if (s.warning) lines.push(renderUnderStepLine(s, n3, `\u26A0 ${s.warning}`));
37486
37563
  lines.push(...renderScriptLogLines(s, n3));
37487
37564
  if (s.artifacts && typeof s.artifacts === "object") {
@@ -37575,7 +37652,7 @@ async function collectFlowFiles(dir, recursive2) {
37575
37652
  var RUN_TOOL_ID = "e2e-execute";
37576
37653
  function buildRunPayload(flowPath, projectRoot, args) {
37577
37654
  const payload = {
37578
- flow_path: flowPath,
37655
+ e2e_test_path: flowPath,
37579
37656
  project_root: projectRoot,
37580
37657
  // Headless runs never block on the LLM prerequisite handshake.
37581
37658
  prerequisiteAcknowledged: true
@@ -37785,7 +37862,12 @@ async function runFlowDirectory(dir, args, projectRoot, options) {
37785
37862
  const durationMs = Date.now() - batchStartedAt;
37786
37863
  if (args.json) {
37787
37864
  console.log(
37788
- JSON.stringify({ ok: counts.failed === 0, ...counts, durationMs, flows: results }, null, 2)
37865
+ JSON.stringify(
37866
+ // `flows` is the deprecated spelling of `e2eTests`.
37867
+ { ok: counts.failed === 0, ...counts, durationMs, e2eTests: results, flows: results },
37868
+ null,
37869
+ 2
37870
+ )
37789
37871
  );
37790
37872
  } else {
37791
37873
  for (const line of renderFailedFlows(failures)) console.log(line);
package/dist/client.js CHANGED
@@ -8883,6 +8883,36 @@ var TOOL_ID_ALIASES = Object.freeze({
8883
8883
  function canonicalToolId(id) {
8884
8884
  return Object.hasOwn(TOOL_ID_ALIASES, id) ? TOOL_ID_ALIASES[id] : id;
8885
8885
  }
8886
+ var TOOL_PARAM_ALIASES = Object.freeze({
8887
+ "e2e-execute": Object.freeze({ flow_path: "e2e_test_path", flow_file: "e2e_test_file" }),
8888
+ "e2e-read-prerequisite": Object.freeze({
8889
+ flow_path: "e2e_test_path",
8890
+ flow_file: "e2e_test_file"
8891
+ })
8892
+ });
8893
+ var ToolParamAliasError = class extends Error {
8894
+ constructor(former, current) {
8895
+ super(`Pass ${current} or its former name ${former}, not both.`);
8896
+ this.name = "ToolParamAliasError";
8897
+ }
8898
+ };
8899
+ function toolParamAliases(tool) {
8900
+ const id = canonicalToolId(tool);
8901
+ return Object.hasOwn(TOOL_PARAM_ALIASES, id) ? TOOL_PARAM_ALIASES[id] : {};
8902
+ }
8903
+ function canonicalToolArgs(tool, args) {
8904
+ if (typeof args !== "object" || args === null || Array.isArray(args)) return args;
8905
+ const record = args;
8906
+ let out;
8907
+ for (const [former, current] of Object.entries(toolParamAliases(tool))) {
8908
+ if (record[former] === void 0) continue;
8909
+ if (record[current] !== void 0) throw new ToolParamAliasError(former, current);
8910
+ out ??= { ...record };
8911
+ out[current] = out[former];
8912
+ delete out[former];
8913
+ }
8914
+ return out ?? args;
8915
+ }
8886
8916
 
8887
8917
  // ../registry/src/flow-file-refs.ts
8888
8918
  async function canonicalFlowPath(p) {
@@ -8952,7 +8982,13 @@ async function classifyOnDiskSpelling(dir, base, addressable = FLOW_FILE_NAME_PA
8952
8982
  }
8953
8983
  function nestedFlowTarget(args) {
8954
8984
  if (typeof args !== "object" || args === null || Array.isArray(args)) return void 0;
8955
- const { name, project_root: projectRoot, flow_path: flowPath } = args;
8985
+ let canonical;
8986
+ try {
8987
+ canonical = canonicalToolArgs("e2e-execute", args);
8988
+ } catch {
8989
+ return void 0;
8990
+ }
8991
+ const { name, project_root: projectRoot, e2e_test_path: flowPath } = canonical;
8956
8992
  if (flowPath === void 0) {
8957
8993
  if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name)) return void 0;
8958
8994
  if (!isResolvedAbsolute(projectRoot)) return void 0;
@@ -8961,7 +8997,7 @@ function nestedFlowTarget(args) {
8961
8997
  }
8962
8998
  if (name !== void 0 || !isResolvedAbsolute(flowPath)) return void 0;
8963
8999
  if (!FLOW_FILE_NAME_PATTERN.test(path8.basename(flowPath))) return void 0;
8964
- return { kind: "flow_path", path: flowPath };
9000
+ return { kind: "e2e_test_path", path: flowPath };
8965
9001
  }
8966
9002
  function isResolvedAbsolute(value) {
8967
9003
  return typeof value === "string" && path8.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
@@ -8993,6 +9029,8 @@ var FAILURE_CODES = {
8993
9029
  TOOL_CAPABILITY_UNSUPPORTED_OPERATION: "TOOL_CAPABILITY_UNSUPPORTED_OPERATION",
8994
9030
  TOOL_PLATFORM_NOT_IMPLEMENTED: "TOOL_PLATFORM_NOT_IMPLEMENTED",
8995
9031
  TOOL_DEPENDENCY_MISSING: "TOOL_DEPENDENCY_MISSING",
9032
+ // Xcode's simctl or devicectl wrapper would start its component install and wait for a password.
9033
+ TOOL_XCODE_FIRST_LAUNCH_PENDING: "TOOL_XCODE_FIRST_LAUNCH_PENDING",
8996
9034
  TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
8997
9035
  TOOLSERVER_UNHANDLED_REJECTION: "TOOLSERVER_UNHANDLED_REJECTION",
8998
9036
  TOOLSERVER_UNCAUGHT_EXCEPTION: "TOOLSERVER_UNCAUGHT_EXCEPTION",
@@ -9165,6 +9203,16 @@ var FAILURE_CODES = {
9165
9203
  JS_RUNTIME_CDP_DISCONNECTED: "JS_RUNTIME_CDP_DISCONNECTED",
9166
9204
  JS_RUNTIME_PAUSED: "JS_RUNTIME_PAUSED",
9167
9205
  NETWORK_INSPECTOR_CDP_DISCONNECTED: "NETWORK_INSPECTOR_CDP_DISCONNECTED",
9206
+ ANDROID_NETWORK_INSPECTOR_FACTORY_OPTIONS_INVALID: "ANDROID_NETWORK_INSPECTOR_FACTORY_OPTIONS_INVALID",
9207
+ ANDROID_NETWORK_INSPECTOR_WRONG_PLATFORM: "ANDROID_NETWORK_INSPECTOR_WRONG_PLATFORM",
9208
+ ANDROID_NETWORK_INSPECTOR_UNKNOWN_PACKAGE: "ANDROID_NETWORK_INSPECTOR_UNKNOWN_PACKAGE",
9209
+ ANDROID_NETWORK_INSPECTOR_RUN_AS_FAILED: "ANDROID_NETWORK_INSPECTOR_RUN_AS_FAILED",
9210
+ ANDROID_NETWORK_INSPECTOR_DEVICE_IN_USE: "ANDROID_NETWORK_INSPECTOR_DEVICE_IN_USE",
9211
+ ANDROID_NETWORK_INSPECTOR_NO_DEVICE_PORT: "ANDROID_NETWORK_INSPECTOR_NO_DEVICE_PORT",
9212
+ NATIVE_NETWORK_LOGS_STOP_UNSUPPORTED: "NATIVE_NETWORK_LOGS_STOP_UNSUPPORTED",
9213
+ NDJSON_CDP_REQUEST_TIMEOUT: "NDJSON_CDP_REQUEST_TIMEOUT",
9214
+ NDJSON_CDP_REQUEST_FAILED: "NDJSON_CDP_REQUEST_FAILED",
9215
+ NDJSON_CDP_CONNECTION_CLOSED: "NDJSON_CDP_CONNECTION_CLOSED",
9168
9216
  REACT_PROFILER_NO_ACTIVE_SESSION: "REACT_PROFILER_NO_ACTIVE_SESSION",
9169
9217
  REACT_PROFILER_CDP_CONNECTION_LOST: "REACT_PROFILER_CDP_CONNECTION_LOST",
9170
9218
  REACT_PROFILER_NO_CPU_PROFILE: "REACT_PROFILER_NO_CPU_PROFILE",
@@ -9857,12 +9905,18 @@ function isResolvedAbsolute2(value) {
9857
9905
  return typeof value === "string" && path11.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
9858
9906
  }
9859
9907
  function namesValidFlow(args) {
9860
- const { project_root, flow_path, name } = args;
9908
+ let canonical;
9909
+ try {
9910
+ canonical = canonicalToolArgs("e2e-execute", args);
9911
+ } catch {
9912
+ return false;
9913
+ }
9914
+ const { project_root, e2e_test_path: testPath, name } = canonical;
9861
9915
  if (!isResolvedAbsolute2(project_root)) return false;
9862
9916
  if (name === void 0) {
9863
- return isResolvedAbsolute2(flow_path) && FLOW_FILE_NAME_PATTERN.test(path11.basename(flow_path));
9917
+ return isResolvedAbsolute2(testPath) && FLOW_FILE_NAME_PATTERN.test(path11.basename(testPath));
9864
9918
  }
9865
- return flow_path === void 0 && typeof name === "string" && FLOW_NAME_PATTERN.test(name);
9919
+ return testPath === void 0 && typeof name === "string" && FLOW_NAME_PATTERN.test(name);
9866
9920
  }
9867
9921
  function savedFlowProject(file) {
9868
9922
  if (!path11.isAbsolute(file)) return null;
@@ -10036,8 +10090,8 @@ function memberCollector(roots, opts) {
10036
10090
  `));
10037
10091
  const emit = (member, sent) => {
10038
10092
  members.push(member);
10039
- const subject = member.role === "flow" ? member.canonical : member.key;
10040
- if (logging) log(printable(`[flow-files] ${member.role} ${subject}: ${sent}`));
10093
+ const [label, subject] = member.role === "flow" ? ["e2e test", member.canonical] : [member.role, member.key];
10094
+ if (logging) log(printable(`[e2e-files] ${label} ${subject}: ${sent}`));
10041
10095
  };
10042
10096
  async function flow(anchorDir, target, onlyPresent) {
10043
10097
  const key = flowMemberKey(anchorDir, target);
@@ -10203,7 +10257,7 @@ function recordedStep(args) {
10203
10257
  if (typeof text !== "string") return void 0;
10204
10258
  let parsed;
10205
10259
  try {
10206
- parsed = JSON.parse(text);
10260
+ parsed = canonicalToolArgs(command, JSON.parse(text));
10207
10261
  } catch {
10208
10262
  return void 0;
10209
10263
  }
@@ -10226,7 +10280,7 @@ async function collectStepMembers(args, opts, recordingDirFor = e2eDirFor) {
10226
10280
  const self = await collector.flow(path11.dirname(recording), path11.basename(recording));
10227
10281
  let runArgs = step.args;
10228
10282
  const named = nestedFlowTarget(runArgs);
10229
- if (named?.kind === "flow_path") {
10283
+ if (named?.kind === "e2e_test_path") {
10230
10284
  const stem = path11.basename(named.path, ".yaml");
10231
10285
  const base = path11.basename(named.path);
10232
10286
  const dir = path11.resolve(path11.dirname(named.path));
@@ -10235,7 +10289,7 @@ async function collectStepMembers(args, opts, recordingDirFor = e2eDirFor) {
10235
10289
  if (dirs.some((d) => path11.resolve(d) === dir)) {
10236
10290
  await collector.flow(path11.dirname(named.path), base);
10237
10291
  runArgs = { ...runArgs, name: stem };
10238
- delete runArgs.flow_path;
10292
+ delete runArgs.e2e_test_path;
10239
10293
  }
10240
10294
  }
10241
10295
  const target = nestedFlowTarget(runArgs);
@@ -10263,7 +10317,21 @@ async function nameToE2ePathForOlderServer(tool, fileInputs, args) {
10263
10317
  const picked = await pickE2eFile(target.paths);
10264
10318
  if (!picked.exists || picked.legacy) return args;
10265
10319
  const { name: _name, ...rest } = args;
10266
- return { ...rest, flow_path: picked.path };
10320
+ return { ...rest, e2e_test_path: picked.path };
10321
+ }
10322
+ function formerParamsForOlderServer(meta, args) {
10323
+ const listed = meta.inputSchema.properties;
10324
+ if (typeof args !== "object" || args === null || Array.isArray(args)) return args;
10325
+ if (typeof listed !== "object" || listed === null) return args;
10326
+ const record = args;
10327
+ let out;
10328
+ for (const [former, current] of Object.entries(toolParamAliases(meta.name))) {
10329
+ if (record[current] === void 0 || current in listed || !(former in listed)) continue;
10330
+ out ??= { ...record };
10331
+ out[former] = out[current];
10332
+ delete out[current];
10333
+ }
10334
+ return out ?? args;
10267
10335
  }
10268
10336
  async function stepForOlderServer(args, listedId) {
10269
10337
  if (typeof args !== "object" || args === null || Array.isArray(args)) return args;
@@ -10521,12 +10589,13 @@ function createToolsClient(options = {}) {
10521
10589
  async function callTool(name, args, opts) {
10522
10590
  opts?.signal?.throwIfAborted();
10523
10591
  const { url, token, remote } = await route();
10524
- let finalArgs = args;
10592
+ let finalArgs = canonicalToolArgs(name, args);
10525
10593
  const tools = await fetchTools({ signal: opts?.signal });
10526
10594
  const meta = findTool(tools, name);
10527
10595
  const olderServer = meta !== null && !tools.some((t) => t.name === canonicalToolId(meta.name));
10528
10596
  if (meta) {
10529
- finalArgs = await nameToE2ePathForOlderServer(meta.name, meta.fileInputs, args);
10597
+ finalArgs = await nameToE2ePathForOlderServer(meta.name, meta.fileInputs, finalArgs);
10598
+ finalArgs = formerParamsForOlderServer(meta, finalArgs);
10530
10599
  }
10531
10600
  if (olderServer && canonicalToolId(meta.name) === "e2e-add-step") {
10532
10601
  finalArgs = await stepForOlderServer(finalArgs, (tool) => findTool(tools, tool)?.name);
@@ -10554,7 +10623,7 @@ function createToolsClient(options = {}) {
10554
10623
  if (filesLogEnabled()) {
10555
10624
  for (const file of applied.written) {
10556
10625
  if (baselineDirs.includes(path12.dirname(file))) {
10557
- diagnose(`[flow-files] baseline ${file}: written`);
10626
+ diagnose(`[e2e-files] baseline ${file}: written`);
10558
10627
  }
10559
10628
  }
10560
10629
  }
@@ -15759,6 +15759,13 @@ var TOOL_ID_ALIASES = Object.freeze({
15759
15759
  "flow-read-prerequisite": "e2e-read-prerequisite",
15760
15760
  "flow-execute": "e2e-execute"
15761
15761
  });
15762
+ var TOOL_PARAM_ALIASES = Object.freeze({
15763
+ "e2e-execute": Object.freeze({ flow_path: "e2e_test_path", flow_file: "e2e_test_file" }),
15764
+ "e2e-read-prerequisite": Object.freeze({
15765
+ flow_path: "e2e_test_path",
15766
+ flow_file: "e2e_test_file"
15767
+ })
15768
+ });
15762
15769
 
15763
15770
  // ../registry/src/failure-codes.ts
15764
15771
  var FAILURE_CODES = {
@@ -15786,6 +15793,8 @@ var FAILURE_CODES = {
15786
15793
  TOOL_CAPABILITY_UNSUPPORTED_OPERATION: "TOOL_CAPABILITY_UNSUPPORTED_OPERATION",
15787
15794
  TOOL_PLATFORM_NOT_IMPLEMENTED: "TOOL_PLATFORM_NOT_IMPLEMENTED",
15788
15795
  TOOL_DEPENDENCY_MISSING: "TOOL_DEPENDENCY_MISSING",
15796
+ // Xcode's simctl or devicectl wrapper would start its component install and wait for a password.
15797
+ TOOL_XCODE_FIRST_LAUNCH_PENDING: "TOOL_XCODE_FIRST_LAUNCH_PENDING",
15789
15798
  TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
15790
15799
  TOOLSERVER_UNHANDLED_REJECTION: "TOOLSERVER_UNHANDLED_REJECTION",
15791
15800
  TOOLSERVER_UNCAUGHT_EXCEPTION: "TOOLSERVER_UNCAUGHT_EXCEPTION",
@@ -15958,6 +15967,16 @@ var FAILURE_CODES = {
15958
15967
  JS_RUNTIME_CDP_DISCONNECTED: "JS_RUNTIME_CDP_DISCONNECTED",
15959
15968
  JS_RUNTIME_PAUSED: "JS_RUNTIME_PAUSED",
15960
15969
  NETWORK_INSPECTOR_CDP_DISCONNECTED: "NETWORK_INSPECTOR_CDP_DISCONNECTED",
15970
+ ANDROID_NETWORK_INSPECTOR_FACTORY_OPTIONS_INVALID: "ANDROID_NETWORK_INSPECTOR_FACTORY_OPTIONS_INVALID",
15971
+ ANDROID_NETWORK_INSPECTOR_WRONG_PLATFORM: "ANDROID_NETWORK_INSPECTOR_WRONG_PLATFORM",
15972
+ ANDROID_NETWORK_INSPECTOR_UNKNOWN_PACKAGE: "ANDROID_NETWORK_INSPECTOR_UNKNOWN_PACKAGE",
15973
+ ANDROID_NETWORK_INSPECTOR_RUN_AS_FAILED: "ANDROID_NETWORK_INSPECTOR_RUN_AS_FAILED",
15974
+ ANDROID_NETWORK_INSPECTOR_DEVICE_IN_USE: "ANDROID_NETWORK_INSPECTOR_DEVICE_IN_USE",
15975
+ ANDROID_NETWORK_INSPECTOR_NO_DEVICE_PORT: "ANDROID_NETWORK_INSPECTOR_NO_DEVICE_PORT",
15976
+ NATIVE_NETWORK_LOGS_STOP_UNSUPPORTED: "NATIVE_NETWORK_LOGS_STOP_UNSUPPORTED",
15977
+ NDJSON_CDP_REQUEST_TIMEOUT: "NDJSON_CDP_REQUEST_TIMEOUT",
15978
+ NDJSON_CDP_REQUEST_FAILED: "NDJSON_CDP_REQUEST_FAILED",
15979
+ NDJSON_CDP_CONNECTION_CLOSED: "NDJSON_CDP_CONNECTION_CLOSED",
15961
15980
  REACT_PROFILER_NO_ACTIVE_SESSION: "REACT_PROFILER_NO_ACTIVE_SESSION",
15962
15981
  REACT_PROFILER_CDP_CONNECTION_LOST: "REACT_PROFILER_CDP_CONNECTION_LOST",
15963
15982
  REACT_PROFILER_NO_CPU_PROFILE: "REACT_PROFILER_NO_CPU_PROFILE",
@@ -16915,7 +16934,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
16915
16934
  var SESSION_ID = randomUUID4();
16916
16935
  function readCliVersion() {
16917
16936
  if (true) {
16918
- return "0.31.2-next.0";
16937
+ return "0.31.2-next.10";
16919
16938
  }
16920
16939
  return "0.0.0";
16921
16940
  }
@@ -22711,6 +22730,11 @@ async function runGlobal(opts) {
22711
22730
  try {
22712
22731
  await runShellCommand(cmd);
22713
22732
  spinner3.stop(import_picocolors4.default.green("Installed globally."));
22733
+ if (!isGloballyInstalled()) {
22734
+ log.warn(
22735
+ `${import_picocolors4.default.cyan("argent")} is not on PATH, so editors can't start it. Add your package manager's global bin directory to PATH.`
22736
+ );
22737
+ }
22714
22738
  version = getGloballyInstalledVersion() ?? getInstalledVersion() ?? version;
22715
22739
  await tel.trackPackageAction("fresh_install", packageActionStartedAt2, true);
22716
22740
  } catch (err) {
@@ -11,6 +11,9 @@ NS_ASSUME_NONNULL_BEGIN
11
11
  /// Returns nil when the block completed, otherwise "Name: reason".
12
12
  + (NSString *_Nullable)runCatching:(NS_NOESCAPE dispatch_block_t)block;
13
13
 
14
+ /// Returns nil when the block completed, otherwise the exception it raised.
15
+ + (NSException *_Nullable)exceptionFrom:(NS_NOESCAPE dispatch_block_t)block;
16
+
14
17
  @end
15
18
 
16
19
  NS_ASSUME_NONNULL_END
@@ -3,13 +3,21 @@
3
3
  @implementation ArgentExceptionGuard
4
4
 
5
5
  + (NSString *_Nullable)runCatching:(NS_NOESCAPE dispatch_block_t)block {
6
+ NSException *exception = [self exceptionFrom:block];
7
+ if (exception == nil) {
8
+ return nil;
9
+ }
10
+ NSString *name = exception.name ?: @"NSException";
11
+ NSString *reason = exception.reason ?: @"unhandled Objective-C exception";
12
+ return [NSString stringWithFormat:@"%@: %@", name, reason];
13
+ }
14
+
15
+ + (NSException *_Nullable)exceptionFrom:(NS_NOESCAPE dispatch_block_t)block {
6
16
  @try {
7
17
  block();
8
18
  return nil;
9
19
  } @catch (NSException *exception) {
10
- NSString *name = exception.name ?: @"NSException";
11
- NSString *reason = exception.reason ?: @"unhandled Objective-C exception";
12
- return [NSString stringWithFormat:@"%@: %@", name, reason];
20
+ return exception;
13
21
  }
14
22
  }
15
23