@swmansion/argent 0.32.1-next.2 → 0.32.1-next.21

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 (46) hide show
  1. package/README.md +1 -1
  2. package/assets/manifest.json +2 -2
  3. package/bin/argent-android-devtools-0.4.0.apk +0 -0
  4. package/bin/darwin/argent-macos-helper +0 -0
  5. package/bin/darwin/ax-service +0 -0
  6. package/bin/darwin/tvos-ax-service +0 -0
  7. package/bin/darwin/tvos-hid-daemon +0 -0
  8. package/bin/network-inspector/network-inspector.jar +0 -0
  9. package/bin/tcp/ax-service +0 -0
  10. package/dist/cli-cmds.mjs +552 -440
  11. package/dist/client.d.ts +5 -0
  12. package/dist/client.js +71 -9
  13. package/dist/installer.mjs +384 -202
  14. package/dist/mcp-server.mjs +167 -20
  15. package/dist/tool-args.generated.d.ts +91 -50
  16. package/dist/tool-server.cjs +34748 -29334
  17. package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
  18. package/dylibs/libKeyboardPatch.dylib +0 -0
  19. package/dylibs/libNativeDevtoolsIos.dylib +0 -0
  20. package/dylibs/macos/libArgentInjectionBootstrap.dylib +0 -0
  21. package/dylibs/macos/libNativeDevtoolsMacos.dylib +0 -0
  22. package/dylibs/tcp/libArgentInjectionBootstrap.dylib +0 -0
  23. package/dylibs/tcp/libKeyboardPatch.dylib +0 -0
  24. package/dylibs/tcp/libNativeDevtoolsIos.dylib +0 -0
  25. package/dylibs/tvos/libArgentInjectionBootstrap.dylib +0 -0
  26. package/dylibs/tvos/libKeyboardPatch.dylib +0 -0
  27. package/dylibs/tvos/libNativeDevtoolsIos.dylib +0 -0
  28. package/package.json +2 -2
  29. package/rules/argent.md +1 -1
  30. package/skills/argent-create-e2e/references/e2e-yaml.md +8 -4
  31. package/skills/argent-create-e2e/references/live-authoring.md +1 -0
  32. package/skills/argent-create-e2e/references/reliability-and-recovery.md +3 -3
  33. package/skills/argent-device-interact/SKILL.md +3 -2
  34. package/skills/argent-device-interact/references/chromium.md +1 -1
  35. package/skills/argent-device-interact/references/harmonyos.md +1 -1
  36. package/skills/argent-ios-simulator-setup/SKILL.md +1 -1
  37. package/skills/argent-macos-app-interact/SKILL.md +44 -0
  38. package/skills/argent-macos-app-interact/references/e2e.md +6 -0
  39. package/skills/argent-qa-e2e/SKILL.md +1 -1
  40. package/skills/argent-react-native-app-workflow/SKILL.md +2 -0
  41. package/skills/argent-react-native-optimization/SKILL.md +2 -3
  42. package/skills/argent-react-native-profiler/SKILL.md +8 -8
  43. package/skills/argent-screenshot-diff/SKILL.md +1 -1
  44. package/skills/argent-test-ui-flow/SKILL.md +1 -1
  45. package/skills/argent-tv-interact/SKILL.md +4 -4
  46. package/bin/argent-android-devtools-0.3.0.apk +0 -0
@@ -24943,6 +24943,10 @@ var FLAG_REGISTRY = [
24943
24943
  name: "video-watermark",
24944
24944
  description: "Overlay the argent corner watermark on recorded screen videos. On by default; turn it off with `argent disable video-watermark`.",
24945
24945
  defaultEnabled: true
24946
+ },
24947
+ {
24948
+ name: "macos-apps",
24949
+ description: "Drive native Mac apps (AppKit, SwiftUI, react-native-macos) from inside the app. Adds the macos platform to list-devices and boot-device, and the file-panel and menu-bar tools. Off by default."
24946
24950
  }
24947
24951
  ];
24948
24952
  function getFlagDefinition(name, registry2 = FLAG_REGISTRY) {
@@ -25735,6 +25739,8 @@ var FAILURE_CODES = {
25735
25739
  CLI_RUN_ARGS_JSON_INVALID: "CLI_RUN_ARGS_JSON_INVALID",
25736
25740
  CLI_RUN_INPUT_VALIDATION_FAILED: "CLI_RUN_INPUT_VALIDATION_FAILED",
25737
25741
  CLI_RUN_TOOL_CALL_FAILED: "CLI_RUN_TOOL_CALL_FAILED",
25742
+ // The result carried the tool-server's `failure` field.
25743
+ CLI_RUN_TOOL_RESULT_FAILED: "CLI_RUN_TOOL_RESULT_FAILED",
25738
25744
  CLI_RUN_SAVE_IMAGE_FAILED: "CLI_RUN_SAVE_IMAGE_FAILED",
25739
25745
  TOOL_CAPABILITY_UNSUPPORTED_OPERATION: "TOOL_CAPABILITY_UNSUPPORTED_OPERATION",
25740
25746
  TOOL_PLATFORM_NOT_IMPLEMENTED: "TOOL_PLATFORM_NOT_IMPLEMENTED",
@@ -25750,6 +25756,7 @@ var FAILURE_CODES = {
25750
25756
  INSTALL_MODE_FLAG_CONFLICT: "INSTALL_MODE_FLAG_CONFLICT",
25751
25757
  INSTALL_FROM_TAR_PACKAGE_FAILED: "INSTALL_FROM_TAR_PACKAGE_FAILED",
25752
25758
  INSTALL_INIT_TRIGGERED_UPDATE_FAILED: "INSTALL_INIT_TRIGGERED_UPDATE_FAILED",
25759
+ INSTALL_SKILLS_FAILED: "INSTALL_SKILLS_FAILED",
25753
25760
  INSTALL_SKILLS_REFRESH_FAILED: "INSTALL_SKILLS_REFRESH_FAILED",
25754
25761
  INSTALL_UNCLASSIFIED_FAILED: "INSTALL_UNCLASSIFIED_FAILED",
25755
25762
  UPDATE_INSTALLED_VERSION_DETECT_FAILED: "UPDATE_INSTALLED_VERSION_DETECT_FAILED",
@@ -25833,15 +25840,21 @@ var FAILURE_CODES = {
25833
25840
  ANDROID_LAUNCH_AM_START_FAILED: "ANDROID_LAUNCH_AM_START_FAILED",
25834
25841
  ANDROID_OPEN_URL_FAILED: "ANDROID_OPEN_URL_FAILED",
25835
25842
  ANDROID_REINSTALL_INSTALL_FAILED: "ANDROID_REINSTALL_INSTALL_FAILED",
25843
+ ANDROID_REINSTALL_UNINSTALL_FAILED: "ANDROID_REINSTALL_UNINSTALL_FAILED",
25836
25844
  ANDROID_RESTART_FAILED: "ANDROID_RESTART_FAILED",
25837
25845
  ANDROID_SETTINGS_PERMISSION_FAILED: "ANDROID_SETTINGS_PERMISSION_FAILED",
25838
25846
  IOS_LAUNCH_SIMCTL_FAILED: "IOS_LAUNCH_SIMCTL_FAILED",
25839
25847
  IOS_OPEN_URL_FAILED: "IOS_OPEN_URL_FAILED",
25840
25848
  IOS_REINSTALL_INSTALL_FAILED: "IOS_REINSTALL_INSTALL_FAILED",
25849
+ IOS_REINSTALL_UNINSTALL_FAILED: "IOS_REINSTALL_UNINSTALL_FAILED",
25841
25850
  IOS_RESTART_LAUNCH_FAILED: "IOS_RESTART_LAUNCH_FAILED",
25851
+ IOS_RESTART_TERMINATE_FAILED: "IOS_RESTART_TERMINATE_FAILED",
25852
+ IOS_TERMINATE_APP_FAILED: "IOS_TERMINATE_APP_FAILED",
25842
25853
  IOS_SETTINGS_PERMISSION_FAILED: "IOS_SETTINGS_PERMISSION_FAILED",
25843
25854
  IOS_SHAKE_FAILED: "IOS_SHAKE_FAILED",
25844
25855
  ANDROID_SHAKE_FAILED: "ANDROID_SHAKE_FAILED",
25856
+ STOP_METRO_PORT_PROBE_FAILED: "STOP_METRO_PORT_PROBE_FAILED",
25857
+ STOP_METRO_SIGNAL_FAILED: "STOP_METRO_SIGNAL_FAILED",
25845
25858
  // The hinge of a foldable iOS simulator: the server refused the request on a
25846
25859
  // foldable (a bad angle, a hinge that would not move) vs. nothing to fold —
25847
25860
  // a device that is not foldable, no hinge route, a remote simulator.
@@ -25940,6 +25953,8 @@ var FAILURE_CODES = {
25940
25953
  REACT_PROFILER_START_FAILED: "REACT_PROFILER_START_FAILED",
25941
25954
  REACT_PROFILER_START_VERIFY_FAILED: "REACT_PROFILER_START_VERIFY_FAILED",
25942
25955
  REACT_PROFILER_SESSION_TORN_DOWN: "REACT_PROFILER_SESSION_TORN_DOWN",
25956
+ REACT_PROFILER_SESSION_TAKEN_OVER: "REACT_PROFILER_SESSION_TAKEN_OVER",
25957
+ REACT_PROFILER_STOP_IN_PROGRESS: "REACT_PROFILER_STOP_IN_PROGRESS",
25943
25958
  REACT_PROFILER_HOOK_ERROR: "REACT_PROFILER_HOOK_ERROR",
25944
25959
  REACT_PROFILER_ANALYZE_NO_DATA: "REACT_PROFILER_ANALYZE_NO_DATA",
25945
25960
  NATIVE_PROFILER_FACTORY_OPTIONS_MISSING: "NATIVE_PROFILER_FACTORY_OPTIONS_MISSING",
@@ -25987,10 +26002,13 @@ var FAILURE_CODES = {
25987
26002
  FLOW_NAME_INVALID: "FLOW_NAME_INVALID",
25988
26003
  FLOW_NO_ACTIVE_RECORDING: "FLOW_NO_ACTIVE_RECORDING",
25989
26004
  FLOW_FILE_INVALID: "FLOW_FILE_INVALID",
26005
+ FLOW_FILE_NEWER_VERSION: "FLOW_FILE_NEWER_VERSION",
25990
26006
  FLOW_FILE_WRITE_FAILED: "FLOW_FILE_WRITE_FAILED",
25991
26007
  FLOW_ENTRY_UNRECOGNIZED: "FLOW_ENTRY_UNRECOGNIZED",
25992
26008
  FLOW_E2E_HAS_PREREQUISITE: "FLOW_E2E_HAS_PREREQUISITE",
25993
26009
  FLOW_DEVICE_RESOLUTION: "FLOW_DEVICE_RESOLUTION",
26010
+ // The target does not satisfy the test's `requires:` block; a directory run skips it.
26011
+ FLOW_REQUIREMENTS_UNMET: "FLOW_REQUIREMENTS_UNMET",
25994
26012
  PROFILER_QUERY_MODE_INVALID: "PROFILER_QUERY_MODE_INVALID",
25995
26013
  PROFILER_QUERY_REQUIRED_PARAM_MISSING: "PROFILER_QUERY_REQUIRED_PARAM_MISSING",
25996
26014
  PROFILER_DATA_NOT_LOADED: "PROFILER_DATA_NOT_LOADED",
@@ -26009,11 +26027,38 @@ var FAILURE_CODES = {
26009
26027
  CHROMIUM_STORAGE_EVAL_FAILED: "CHROMIUM_STORAGE_EVAL_FAILED",
26010
26028
  CHROMIUM_TAB_NOT_FOUND: "CHROMIUM_TAB_NOT_FOUND",
26011
26029
  CHROMIUM_TAB_OPEN_FAILED: "CHROMIUM_TAB_OPEN_FAILED",
26030
+ CHROMIUM_NAVIGATE_FAILED: "CHROMIUM_NAVIGATE_FAILED",
26012
26031
  CHROMIUM_DESCRIBE_FAILED: "CHROMIUM_DESCRIBE_FAILED",
26013
26032
  CHROMIUM_ELECTRON_APP_PATH_INVALID: "CHROMIUM_ELECTRON_APP_PATH_INVALID",
26014
26033
  CHROMIUM_ELECTRON_SPAWN_FAILED: "CHROMIUM_ELECTRON_SPAWN_FAILED",
26015
26034
  CHROMIUM_ELECTRON_CDP_TIMEOUT: "CHROMIUM_ELECTRON_CDP_TIMEOUT",
26016
26035
  CHROMIUM_ELECTRON_EXITED_BEFORE_READY: "CHROMIUM_ELECTRON_EXITED_BEFORE_READY",
26036
+ /**
26037
+ * Native Mac apps (the `macos-apps` flag)
26038
+ * @see [macos-app.ts](../../tool-server/src/blueprints/macos-app.ts)
26039
+ */
26040
+ MACOS_APP_UNSUPPORTED_HOST: "MACOS_APP_UNSUPPORTED_HOST",
26041
+ MACOS_APP_PATH_INVALID: "MACOS_APP_PATH_INVALID",
26042
+ MACOS_APP_BUNDLE_INVALID: "MACOS_APP_BUNDLE_INVALID",
26043
+ MACOS_APP_NOT_FOUND: "MACOS_APP_NOT_FOUND",
26044
+ MACOS_APP_HARDENED_RUNTIME: "MACOS_APP_HARDENED_RUNTIME",
26045
+ MACOS_APP_LIBRARY_MISSING: "MACOS_APP_LIBRARY_MISSING",
26046
+ MACOS_APP_LIBRARY_STAGE_FAILED: "MACOS_APP_LIBRARY_STAGE_FAILED",
26047
+ MACOS_APP_ALREADY_RUNNING: "MACOS_APP_ALREADY_RUNNING",
26048
+ MACOS_APP_SPAWN_FAILED: "MACOS_APP_SPAWN_FAILED",
26049
+ MACOS_APP_EXITED_BEFORE_READY: "MACOS_APP_EXITED_BEFORE_READY",
26050
+ MACOS_APP_HANDSHAKE_TIMEOUT: "MACOS_APP_HANDSHAKE_TIMEOUT",
26051
+ MACOS_APP_HANDSHAKE_INVALID: "MACOS_APP_HANDSHAKE_INVALID",
26052
+ MACOS_APP_NOT_RUNNING: "MACOS_APP_NOT_RUNNING",
26053
+ MACOS_APP_NOT_CONNECTED: "MACOS_APP_NOT_CONNECTED",
26054
+ MACOS_APP_CONNECTION_LOST: "MACOS_APP_CONNECTION_LOST",
26055
+ MACOS_APP_CONNECTION_CLOSED: "MACOS_APP_CONNECTION_CLOSED",
26056
+ MACOS_APP_RPC_TIMEOUT: "MACOS_APP_RPC_TIMEOUT",
26057
+ MACOS_APP_RPC_ERROR: "MACOS_APP_RPC_ERROR",
26058
+ MACOS_APP_TERMINATE_FAILED: "MACOS_APP_TERMINATE_FAILED",
26059
+ MACOS_APP_BUNDLE_ID_MISMATCH: "MACOS_APP_BUNDLE_ID_MISMATCH",
26060
+ MACOS_APP_OPEN_URL_FAILED: "MACOS_APP_OPEN_URL_FAILED",
26061
+ MACOS_APP_FILE_ACCESS_FAILED: "MACOS_APP_FILE_ACCESS_FAILED",
26017
26062
  KEYBOARD_KEY_UNSUPPORTED: "KEYBOARD_KEY_UNSUPPORTED",
26018
26063
  KEYBOARD_CHARACTER_UNSUPPORTED: "KEYBOARD_CHARACTER_UNSUPPORTED",
26019
26064
  KEYBOARD_TEXT_AND_KEY_COMBINED: "KEYBOARD_TEXT_AND_KEY_COMBINED",
@@ -26025,6 +26070,8 @@ var FAILURE_CODES = {
26025
26070
  SCREENSHOT_DIFF_INPUT_INVALID: "SCREENSHOT_DIFF_INPUT_INVALID",
26026
26071
  BOOT_DEVICE_TARGET_SELECTION_INVALID: "BOOT_DEVICE_TARGET_SELECTION_INVALID",
26027
26072
  BOOT_IOS_UNSUPPORTED_HOST: "BOOT_IOS_UNSUPPORTED_HOST",
26073
+ BOOT_IOS_SIMCTL_LIST_TIMEOUT: "BOOT_IOS_SIMCTL_LIST_TIMEOUT",
26074
+ BOOT_IOS_SIMCTL_TIMEOUT: "BOOT_IOS_SIMCTL_TIMEOUT",
26028
26075
  BOOT_ANDROID_NO_AVDS: "BOOT_ANDROID_NO_AVDS",
26029
26076
  BOOT_ANDROID_AVD_NOT_FOUND: "BOOT_ANDROID_AVD_NOT_FOUND",
26030
26077
  BOOT_ANDROID_ADB_UNAVAILABLE: "BOOT_ANDROID_ADB_UNAVAILABLE",
@@ -27139,7 +27186,8 @@ async function consumeToolStream(name, body, onProgress, signal) {
27139
27186
  final = {
27140
27187
  data: msg.data,
27141
27188
  note: msg.note,
27142
- ...msg.profiling === true ? { profiling: true } : {}
27189
+ ...msg.profiling === true ? { profiling: true } : {},
27190
+ ...typeof msg.failure === "string" ? { failure: msg.failure } : {}
27143
27191
  };
27144
27192
  } else if (msg.event === "error") {
27145
27193
  throw new ToolInvocationError(msg.error ?? "tool invocation failed", {
@@ -27191,7 +27239,8 @@ async function consumeToolStream(name, body, onProgress, signal) {
27191
27239
  return {
27192
27240
  data: final.data,
27193
27241
  note: final.note,
27194
- ...final.profiling ? { profiling: true } : {}
27242
+ ...final.profiling ? { profiling: true } : {},
27243
+ ...final.failure !== void 0 ? { failure: final.failure } : {}
27195
27244
  };
27196
27245
  }
27197
27246
  function errorBodyMessage(body) {
@@ -27356,6 +27405,7 @@ function createToolsClient(options = {}) {
27356
27405
  }
27357
27406
  const shadowWarning = await e2eShadowWarningFor(name, args);
27358
27407
  const baselineDirs = [];
27408
+ let unwrittenBaselines = [];
27359
27409
  if (meta2?.fileInputs?.length) {
27360
27410
  if (remote) assertRequiredPresent(meta2, finalArgs);
27361
27411
  finalArgs = await prepareFileInputs(meta2.fileInputs, finalArgs ?? {}, {
@@ -27369,8 +27419,9 @@ function createToolsClient(options = {}) {
27369
27419
  signal: opts?.signal
27370
27420
  });
27371
27421
  }
27372
- const settle2 = async (data) => {
27373
- const applied = await applyClientFileDirectives(data, { allowedDirs: baselineDirs });
27422
+ const settle2 = async (data2) => {
27423
+ const applied = await applyClientFileDirectives(data2, { allowedDirs: baselineDirs });
27424
+ unwrittenBaselines = applied.failed.map((f) => f.path);
27374
27425
  for (const { path: file, error: error2 } of applied.failed) {
27375
27426
  diagnose(`The baseline ${file} was not written on this client: ${error2}`);
27376
27427
  }
@@ -27387,6 +27438,7 @@ function createToolsClient(options = {}) {
27387
27438
  }
27388
27439
  return { ...result, warning: shadowWarning };
27389
27440
  };
27441
+ const unwrittenFailure = () => unwrittenBaselines.length > 0 ? `Baselines not written on this client: ${unwrittenBaselines.join(", ")}` : void 0;
27390
27442
  const stream = opts?.onProgress !== void 0 || carriesMembers(finalArgs);
27391
27443
  const sentOnce = carriesUpload(finalArgs);
27392
27444
  const forwarded = remote ? await forwardedSecrets(finalArgs) : void 0;
@@ -27450,11 +27502,14 @@ function createToolsClient(options = {}) {
27450
27502
  }),
27451
27503
  opts?.signal
27452
27504
  );
27505
+ const data2 = await settle2(streamed.data);
27506
+ const failure3 = streamed.failure ?? unwrittenFailure();
27453
27507
  return {
27454
- data: await settle2(streamed.data),
27508
+ data: data2,
27455
27509
  note: streamed.note,
27456
27510
  outputHint: meta2?.outputHint,
27457
- ...streamed.profiling ? { profiling: true } : {}
27511
+ ...streamed.profiling ? { profiling: true } : {},
27512
+ ...failure3 !== void 0 ? { failure: failure3 } : {}
27458
27513
  };
27459
27514
  }
27460
27515
  let json;
@@ -27490,11 +27545,14 @@ function createToolsClient(options = {}) {
27490
27545
  });
27491
27546
  }
27492
27547
  opts?.signal?.throwIfAborted();
27548
+ const data = await settle2(json.data);
27549
+ const failure2 = (typeof json.failure === "string" ? json.failure : void 0) ?? unwrittenFailure();
27493
27550
  return {
27494
- data: await settle2(json.data),
27551
+ data,
27495
27552
  note: json.note,
27496
27553
  outputHint: meta2?.outputHint,
27497
- ...json.profiling === true ? { profiling: true } : {}
27554
+ ...json.profiling === true ? { profiling: true } : {},
27555
+ ...failure2 !== void 0 ? { failure: failure2 } : {}
27498
27556
  };
27499
27557
  }
27500
27558
  return { fetchTools, fetchTool, callTool, baseUrl };
@@ -27786,7 +27844,8 @@ var PLATFORMS = [
27786
27844
  "vega",
27787
27845
  "harmony",
27788
27846
  "tvos",
27789
- "android-tv"
27847
+ "android-tv",
27848
+ "macos"
27790
27849
  ];
27791
27850
  var DEVICE_KINDS = [
27792
27851
  "simulator",
@@ -27960,6 +28019,9 @@ var ALLOWED = {
27960
28019
  warned_count: COUNT
27961
28020
  },
27962
28021
  "installation:skill_install": {
28022
+ source: oneOf(["pinned", "bundled"]),
28023
+ used_fallback: bool,
28024
+ fallback_reason: oneOf(["ref_missing", "unclassified"]),
27963
28025
  method: oneOf(["default", "interactive", "manual"]),
27964
28026
  is_online: bool,
27965
28027
  has_offline_cache: bool,
@@ -28844,7 +28906,9 @@ var AUTO_SCREENSHOT_TOOLS = /* @__PURE__ */ new Set([
28844
28906
  "describe",
28845
28907
  "run-sequence",
28846
28908
  // A wait is almost always followed by a look at the screen it waited for.
28847
- "await-ui-element"
28909
+ "await-ui-element",
28910
+ "file-panel",
28911
+ "menu-bar"
28848
28912
  ]);
28849
28913
  var AUTO_SCREENSHOT_DELAY_MS_BY_TOOL = {
28850
28914
  "launch-app": 3e3,
@@ -28892,15 +28956,18 @@ var AUTO_DESCRIBE_TOOLS = /* @__PURE__ */ new Set([
28892
28956
  "restart-app",
28893
28957
  "open-url",
28894
28958
  "run-sequence",
28895
- "await-ui-element"
28959
+ "await-ui-element",
28960
+ "file-panel",
28961
+ "menu-bar"
28896
28962
  ]);
28897
28963
  function autoDescribeEnabled(options) {
28898
28964
  return !isFlagEnabled("disable-auto-describe", options);
28899
28965
  }
28900
28966
  var PROFILING_CAPTURE_SKIPPED_NOTE = "Auto-screenshot and element tree skipped while a profiler is recording on this device. Call screenshot or describe if you need to see the screen.";
28901
28967
  var AUTO_DESCRIBE_HEADER = "--- Elements after action (describe) ---";
28902
- function shouldAutoDescribe(toolName) {
28903
- return AUTO_DESCRIBE_TOOLS.has(normalizeToolName(toolName));
28968
+ function shouldAutoDescribe(toolName, args) {
28969
+ const canonical = normalizeToolName(toolName);
28970
+ return AUTO_DESCRIBE_TOOLS.has(canonical) && !isListCall(canonical, args);
28904
28971
  }
28905
28972
  var SECRET_PLACEHOLDER_MARKER = "{{secret:";
28906
28973
  function containsSecretPlaceholder(args) {
@@ -28920,9 +28987,12 @@ function normalizeToolName(name) {
28920
28987
  const idx = name.lastIndexOf("__");
28921
28988
  return idx === -1 ? name : name.slice(idx + 2);
28922
28989
  }
28923
- function shouldAutoScreenshot(toolName) {
28990
+ function shouldAutoScreenshot(toolName, args) {
28924
28991
  const canonical = normalizeToolName(toolName);
28925
- return canonical !== "screenshot" && AUTO_SCREENSHOT_TOOLS.has(canonical);
28992
+ return canonical !== "screenshot" && AUTO_SCREENSHOT_TOOLS.has(canonical) && !isListCall(canonical, args);
28993
+ }
28994
+ function isListCall(canonical, args) {
28995
+ return (canonical === "menu-bar" || canonical === "file-panel") && args?.action === "list";
28926
28996
  }
28927
28997
  function getAutoScreenshotDelayMs(toolName) {
28928
28998
  const canonical = normalizeToolName(toolName);
@@ -29100,6 +29170,78 @@ function toMcpToolList(tools, options = {}) {
29100
29170
  return tools.filter((t) => !t.hideFromMcp).map((t) => toMcpTool(t, options));
29101
29171
  }
29102
29172
 
29173
+ // ../argent-mcp/src/list-devices-text.ts
29174
+ var RUNTIME_PREFIX = "com.apple.CoreSimulator.SimRuntime.";
29175
+ var STOPPED_SIMULATORS_HEADER = "iOS simulators that are shut down, one per line (platform, udid, name, runtime, state, tags); start one with boot-device:";
29176
+ function isRecord3(value) {
29177
+ return value !== null && typeof value === "object" && !Array.isArray(value);
29178
+ }
29179
+ function shortRuntime(runtime) {
29180
+ if (!runtime.startsWith(RUNTIME_PREFIX)) return runtime;
29181
+ const rest = runtime.slice(RUNTIME_PREFIX.length);
29182
+ const match = /^([A-Za-z]+)-(\d+(?:-\d+)*)$/.exec(rest);
29183
+ return match ? `${match[1]} ${match[2].replace(/-/g, ".")}` : rest;
29184
+ }
29185
+ function cleanEntry(device) {
29186
+ const out = {};
29187
+ for (const [key, value] of Object.entries(device)) {
29188
+ if (value === null || value === void 0) continue;
29189
+ if (key === "isEmulator") continue;
29190
+ if (key === "runtimeKind" && value === "mobile") continue;
29191
+ out[key] = key === "runtime" && typeof value === "string" ? shortRuntime(value) : value;
29192
+ }
29193
+ return out;
29194
+ }
29195
+ function isStoppedSimulator(device) {
29196
+ if (device.platform !== "ios" && device.platform !== "ios-remote") return false;
29197
+ if ("kind" in device || "external" in device) return false;
29198
+ return typeof device.udid === "string" && device.state === "Shutdown";
29199
+ }
29200
+ var ONE_LINE_FIELDS = /* @__PURE__ */ new Set(["platform", "udid", "name", "runtime", "state"]);
29201
+ function quoteIfNeeded(value) {
29202
+ return value === "" || /[\s"\\]/.test(value) ? JSON.stringify(value) : value;
29203
+ }
29204
+ function stoppedSimulatorLine(device) {
29205
+ const d = cleanEntry(device);
29206
+ const name = typeof d.name === "string" ? d.name : "";
29207
+ const parts = [String(d.platform), String(d.udid), JSON.stringify(name)];
29208
+ if (typeof d.runtime === "string") parts.push(d.runtime);
29209
+ if (typeof d.state === "string") parts.push(quoteIfNeeded(d.state));
29210
+ for (const [key, value] of Object.entries(d)) {
29211
+ if (ONE_LINE_FIELDS.has(key)) continue;
29212
+ if (value === true) parts.push(key);
29213
+ else if (typeof value === "string" || typeof value === "number")
29214
+ parts.push(`${key}=${quoteIfNeeded(String(value))}`);
29215
+ else parts.push(`${key}=${JSON.stringify(value)}`);
29216
+ }
29217
+ return parts.join(" ");
29218
+ }
29219
+ function listDevicesText(result) {
29220
+ if (!isRecord3(result) || !Array.isArray(result.devices)) return void 0;
29221
+ if (!result.devices.every(isRecord3)) return void 0;
29222
+ const devices = result.devices;
29223
+ const listed = [];
29224
+ const stopped = [];
29225
+ for (const device of devices) {
29226
+ if (isStoppedSimulator(device)) stopped.push(stoppedSimulatorLine(device));
29227
+ else listed.push(JSON.stringify(cleanEntry(device)));
29228
+ }
29229
+ const rest = [];
29230
+ for (const [key, value] of Object.entries(result)) {
29231
+ if (key === "devices") continue;
29232
+ rest.push(`${JSON.stringify(key)}:${JSON.stringify(value)}`);
29233
+ }
29234
+ const devicesPart = listed.length > 0 ? `[
29235
+ ${listed.join(",\n")}
29236
+ ]` : "[]";
29237
+ const object3 = `{"devices":${devicesPart}${rest.map((r) => `,
29238
+ ${r}`).join("")}}`;
29239
+ if (stopped.length === 0) return object3;
29240
+ return `${object3}
29241
+ ${STOPPED_SIMULATORS_HEADER}
29242
+ ${stopped.join("\n")}`;
29243
+ }
29244
+
29103
29245
  // ../argent-mcp/src/instructions.ts
29104
29246
  var SERVER_INSTRUCTIONS = "Argent \u2014 iOS Simulator, Android Emulator, and Chromium app control for interacting, testing, profiling and debugging mobile and Chromium applications. Interaction tools return the screen after the action: a screenshot plus the accessibility element tree with normalized tap frames. Take coordinates from that tree; call describe only when no fresh tree is available \u2014 never guess coordinates from pixels. Do not stop simulator servers when a task finishes: the next task reuses them. Call stop-all-simulator-servers when the user asks to clean up or ends the session, or when a skill tells you to recycle a device's services, always with devices: [...] naming the devices this session used. Never stop a Metro the user started unless they ask. One tool-server is shared by every agent using this argent install, so an unscoped call tears down their devices too \u2014 reserve it for a deliberate machine-wide cleanup.";
29105
29247
 
@@ -29337,7 +29479,7 @@ async function startMcpServer(options) {
29337
29479
  const t1 = Date.now();
29338
29480
  try {
29339
29481
  const d = await callTool("describe", { udid }, { signal });
29340
- const desc = d.result?.description;
29482
+ const { description: desc, hint } = d.result ?? {};
29341
29483
  await spyLog({
29342
29484
  ts: (/* @__PURE__ */ new Date()).toISOString(),
29343
29485
  event: "auto_describe",
@@ -29346,8 +29488,10 @@ async function startMcpServer(options) {
29346
29488
  chars: typeof desc === "string" ? desc.length : 0
29347
29489
  });
29348
29490
  if (typeof desc !== "string" || desc.length === 0) return [];
29491
+ const hintLine = typeof hint === "string" && hint && !desc.includes(hint) ? `Hint: ${hint}
29492
+ ` : "";
29349
29493
  return [{ type: "text", text: `${AUTO_DESCRIBE_HEADER}
29350
- ${desc}` }];
29494
+ ${hintLine}${desc}` }];
29351
29495
  } catch (e) {
29352
29496
  await spyLog({
29353
29497
  ts: (/* @__PURE__ */ new Date()).toISOString(),
@@ -29408,8 +29552,11 @@ ${desc}` }];
29408
29552
  authToken: AUTH_TOKEN,
29409
29553
  deviceId: getDeviceIdFromArgs(params.arguments)
29410
29554
  };
29555
+ const devicesText = canonicalToolId(params.name) === "list-devices" ? listDevicesText(result) : void 0;
29411
29556
  let content;
29412
- if (canonicalToolId(params.name) === "e2e-execute" && result && typeof result === "object" && ("e2eTest" in result || "flow" in result) && "steps" in result) {
29557
+ if (devicesText !== void 0) {
29558
+ content = [{ type: "text", text: devicesText }];
29559
+ } else if (canonicalToolId(params.name) === "e2e-execute" && result && typeof result === "object" && ("e2eTest" in result || "flow" in result) && "steps" in result) {
29413
29560
  content = await flowRunToMcpContent(result, ctx);
29414
29561
  } else if (params.name === "screenshot-diff" && isScreenshotDiffResult(result)) {
29415
29562
  content = await screenshotDiffToMcpContent(result, ctx);
@@ -29417,8 +29564,8 @@ ${desc}` }];
29417
29564
  content = await toMcpContent(result, outputHint, ctx, params.arguments);
29418
29565
  }
29419
29566
  const udid = getUdidFromArgs(params.arguments);
29420
- const wantScreenshot = autoScreenshotOn && shouldAutoScreenshot(params.name);
29421
- const wantTree = autoDescribeOn && shouldAutoDescribe(params.name);
29567
+ const wantScreenshot = autoScreenshotOn && shouldAutoScreenshot(params.name, params.arguments);
29568
+ const wantTree = autoDescribeOn && shouldAutoDescribe(params.name, params.arguments);
29422
29569
  if (udid && (wantScreenshot || wantTree) && containsSecretPlaceholder(params.arguments)) {
29423
29570
  content = [
29424
29571
  ...content,