@swmansion/argent 0.28.1-next.21 → 0.28.1-next.22

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 (31) hide show
  1. package/agents/argent-environment-inspector.md +7 -7
  2. package/agents/references/quality-control-checklist.md +14 -14
  3. package/dist/cli-cmds.mjs +1 -1
  4. package/dist/installer.mjs +1 -1
  5. package/dist/tool-args.generated.d.ts +76 -76
  6. package/dist/tool-server.cjs +174 -174
  7. package/package.json +1 -1
  8. package/rules/argent.md +16 -16
  9. package/skills/argent-android-emulator-setup/SKILL.md +9 -9
  10. package/skills/argent-create-flow/references/flow-yaml.md +11 -11
  11. package/skills/argent-create-flow/references/live-authoring.md +9 -9
  12. package/skills/argent-create-flow/references/reliability-and-recovery.md +13 -13
  13. package/skills/argent-device-interact/SKILL.md +47 -47
  14. package/skills/argent-device-interact/references/chromium.md +1 -1
  15. package/skills/argent-device-interact/references/gesture-examples.md +7 -7
  16. package/skills/argent-device-interact/references/secrets.md +6 -6
  17. package/skills/argent-lens/SKILL.md +21 -21
  18. package/skills/argent-metro-debugger/SKILL.md +22 -22
  19. package/skills/argent-metro-debugger/references/failure-scenarios.md +11 -11
  20. package/skills/argent-metro-debugger/references/source-maps.md +4 -4
  21. package/skills/argent-native-profiler/SKILL.md +13 -13
  22. package/skills/argent-qa-flows/SKILL.md +3 -3
  23. package/skills/argent-react-native-app-workflow/SKILL.md +18 -18
  24. package/skills/argent-react-native-optimization/SKILL.md +12 -12
  25. package/skills/argent-react-native-optimization/references/fix-reference.md +10 -10
  26. package/skills/argent-react-native-optimization/references/lint-rules.md +1 -1
  27. package/skills/argent-react-native-profiler/SKILL.md +25 -25
  28. package/skills/argent-react-native-profiler/references/diagnostic-tools.md +19 -19
  29. package/skills/argent-screen-recording/SKILL.md +14 -14
  30. package/skills/argent-test-ui-flow/SKILL.md +9 -9
  31. package/skills/argent-tv-interact/SKILL.md +19 -19
@@ -94920,7 +94920,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
94920
94920
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
94921
94921
  function readCliVersion() {
94922
94922
  if (true) {
94923
- return "0.28.1-next.21";
94923
+ return "0.28.1-next.22";
94924
94924
  }
94925
94925
  return "0.0.0";
94926
94926
  }
@@ -111341,13 +111341,13 @@ var listDevicesTool = {
111341
111341
  description: `List iOS simulators, Android emulators, connected physical Android devices, running Chromium apps, and Vega (Fire TV) devices in one place.
111342
111342
  Use at the start of a session to pick a target id ('udid' for iOS entries, 'serial' for Android/Vega entries, 'id' for Chromium) to pass to interaction tools, and to see which targets are already running.
111343
111343
  Returns { devices, avds } where each device carries a 'platform' discriminator ('ios', 'android', 'chromium', or 'vega'); 'avds' lists Android AVDs bootable via boot-device. A Vega VVD is listed under 'devices' whether running or stopped (state 'running'/'stopped'); start a stopped one with boot-device using its 'vvdImage'.
111344
- Android entries also carry a 'kind' ('emulator' for a local AVD, 'device' for a physical phone connected over USB / wireless adb) \u2014 physical phones are detected from \`adb devices\` (any serial that is not an \`emulator-*\` one) and are driven through the same interaction tools as emulators; they do not need boot-device (just connect the phone with USB debugging authorised).
111344
+ Android entries also carry a 'kind' ('emulator' for a local AVD, 'device' for a physical phone connected over USB / wireless adb). Physical phones are detected from \`adb devices\` (any serial that is not an \`emulator-*\` one) and are driven through the same interaction tools as emulators; they do not need boot-device (just connect the phone with USB debugging authorised).
111345
111345
  Physical iPhones appear as iOS entries with kind 'device' (no iPads); no boot-device. State 'connected' = cabled and usable; 'paired' = not reachable over USB, never auto-bound.
111346
- TV targets are tagged with runtimeKind 'tv' (Apple TV simulators on iOS, Android TV / leanback devices on Android) \u2014 these are focus-driven, not touch-driven: use \`describe\` to read focus, \`tv-remote\` for remote presses (up/down/left/right/select/back/menu/home), and \`keyboard\` to type, rather than the coordinate/gesture tools.
111347
- iOS simulators from an additional CoreSimulator device set (the 'ios.additionalDeviceSets' configuration \u2014 e.g. devices created by Radon IDE) are listed alongside default-set ones, tagged with their owning 'deviceSet' path; they are driven through the same tools by udid, but run headless (no Simulator.app window attaches to them).
111346
+ TV targets are tagged with runtimeKind 'tv' (Apple TV simulators on iOS, Android TV / leanback devices on Android). These are focus-driven, not touch-driven: use \`describe\` to read focus, \`tv-remote\` for remote presses (up/down/left/right/select/back/menu/home), and \`keyboard\` to type, rather than the coordinate/gesture tools.
111347
+ iOS simulators from an additional CoreSimulator device set (the 'ios.additionalDeviceSets' configuration, e.g. devices created by Radon IDE) are listed alongside default-set ones, tagged with their owning 'deviceSet' path; they are driven through the same tools by udid, but run headless (no Simulator.app window attaches to them).
111348
111348
  A foldable iOS simulator (the iPhone Duo) has 'foldable: true'. Use the \`fold\` tool to fold or unfold it.
111349
- Chromium apps are discovered by probing CDP debugging ports (default 9222; extend via the ARGENT_CHROMIUM_PORTS=<comma-separated-ports> env var). They must already be running with --remote-debugging-port=<port> \u2014 use boot-device with electronAppPath to launch one.
111350
- Booted/ready devices are listed first. Platforms whose CLI is unavailable are silently omitted \u2014 an empty result usually means xcode-select, Android platform-tools, or the Vega SDK is not installed.`,
111349
+ Chromium apps are discovered by probing CDP debugging ports (default 9222; extend via the ARGENT_CHROMIUM_PORTS=<comma-separated-ports> env var). They must already be running with --remote-debugging-port=<port>; use boot-device with electronAppPath to launch one.
111350
+ Booted/ready devices are listed first. Platforms whose CLI is unavailable are silently omitted; an empty result usually means xcode-select, Android platform-tools, or the Vega SDK is not installed.`,
111351
111351
  alwaysLoad: true,
111352
111352
  searchHint: "list devices simulators emulators avd serial udid ios android chromium vega app fire tv session start",
111353
111353
  zodSchema,
@@ -111921,7 +111921,7 @@ var NATIVE_DEVTOOLS_NAMESPACE = "NativeDevtools";
111921
111921
  function isInjectableBundleId(bundleId) {
111922
111922
  return !bundleId.toLowerCase().startsWith("com.apple.");
111923
111923
  }
111924
- var NON_INJECTABLE_NATIVE_WARNING = "Do not fall back to the native-devtools feature tools (native-describe-screen, native-find-views, native-full-hierarchy, native-network-logs, native-view-at-point, native-user-interactable-view-at-point) \u2014 they run the same injection precheck and fail with the same non-injectable error.";
111924
+ var NON_INJECTABLE_NATIVE_WARNING = "Do not fall back to the native-devtools feature tools (native-describe-screen, native-find-views, native-full-hierarchy, native-network-logs, native-view-at-point, native-user-interactable-view-at-point): they run the same injection precheck and fail with the same non-injectable error.";
111925
111925
  var NON_INJECTABLE_RECOVERY = "Use the standard `describe` tool (its accessibility path reads the screen without injection) or `screenshot` (then interact by coordinate). " + NON_INJECTABLE_NATIVE_WARNING;
111926
111926
  var MAX_NATIVE_DEVTOOLS_INIT_ATTEMPTS = 3;
111927
111927
  var NATIVE_DEVTOOLS_AGE_SLOP_MS = 3e3;
@@ -118909,19 +118909,19 @@ Returns { envSetup, appRunning, connected, requiresRestart, state, message, next
118909
118909
  - envSetup: DYLD_INSERT_LIBRARIES is configured in the simulator's launchd environment
118910
118910
  - appRunning: the target bundle currently has a running UIKit process on the simulator
118911
118911
  - connected: the dylib is active in the current running process for this bundleId
118912
- - requiresRestart: the app is already running and a fresh process would reach this simulator's devtools endpoint where the current one does not \u2014 it carries no argent injection, was pointed at an earlier tool-server's listener, or could not be inspected to tell. Always false for a non-injectable app, and false when state is unregistered or connecting, where a relaunch cannot help.
118913
- - state: why devtools are or aren't live, measured from the running process. "connected"; "not_running"; "stale_process" (the process cannot reach this simulator's devtools endpoint \u2014 launched either before argent's instrumentation was in place or against an earlier tool-server's listener \u2014 so restart-app fixes it); "unregistered" (the process IS injected and pointed at this simulator's devtools endpoint yet the service never registered it, so restarting the app cannot help); "connecting" (the process IS injected but launched moments ago and is still connecting, so waiting is what helps); "indeterminate" (the process could not be inspected). Omitted when injectable is false, which is terminal on its own.
118914
- - message: the remedy for that state, in full, including for a state not listed above. Omitted when connected or non-injectable. Prefer it over inferring one from the booleans \u2014 it is the only field that can tell you to stop restarting the app.
118912
+ - requiresRestart: the app is already running and a fresh process would reach this simulator's devtools endpoint where the current one does not: it carries no argent injection, was pointed at an earlier tool-server's listener, or could not be inspected to tell. Always false for a non-injectable app, and false when state is unregistered or connecting, where a relaunch cannot help.
118913
+ - state: why devtools are or aren't live, measured from the running process. "connected"; "not_running"; "stale_process" (the process cannot reach this simulator's devtools endpoint, launched either before argent's instrumentation was in place or against an earlier tool-server's listener, so restart-app fixes it); "unregistered" (the process IS injected and pointed at this simulator's devtools endpoint yet the service never registered it, so restarting the app cannot help); "connecting" (the process IS injected but launched moments ago and is still connecting, so waiting is what helps); "indeterminate" (the process could not be inspected). Omitted when injectable is false, which is terminal on its own.
118914
+ - message: the remedy for that state, in full, including for a state not listed above. Omitted when connected or non-injectable. Prefer it over inferring one from the booleans: it is the only field that can tell you to stop restarting the app.
118915
118915
  - nextLaunchWillBeInjected: if you launch this bundle now, native devtools env setup is already in place (always false for a non-injectable app)
118916
118916
  - injectable: whether this app is a supported target for Argent native devtools. Apple system apps (bundle ids under com.apple.) are not: they are never the app under test, so the native tools refuse to read one.
118917
118917
 
118918
118918
  Call this before using app-scoped native hierarchy tools or native-network-logs.
118919
- If injectable is false: treat this as TERMINAL \u2014 the app is not a supported native-devtools target, and no relaunch changes that. Do NOT restart/retry. Use the standard \`describe\` tool (its accessibility path reads the screen without injection) or \`screenshot\` (then interact by coordinate). Do not fall back to the native-devtools feature tools (native-describe-screen, native-find-views, native-full-hierarchy, native-network-logs, native-view-at-point, native-user-interactable-view-at-point) \u2014 they run the same injection precheck and fail with the same non-injectable error.
118919
+ If injectable is false: treat this as TERMINAL. The app is not a supported native-devtools target, and no relaunch changes that. Do NOT restart/retry. Use the standard \`describe\` tool (its accessibility path reads the screen without injection) or \`screenshot\` (then interact by coordinate). Do not fall back to the native-devtools feature tools (native-describe-screen, native-find-views, native-full-hierarchy, native-network-logs, native-view-at-point, native-user-interactable-view-at-point): they run the same injection precheck and fail with the same non-injectable error.
118920
118920
  If appRunning is false and nextLaunchWillBeInjected is true: use launch-app normally.
118921
- If requiresRestart is true: call restart-app once, then proceed with the native feature. Read state before acting on a second such reading \u2014 indeterminate reaches this rule too, and its line below bounds it at that one restart.
118922
- If state is unregistered: do NOT restart the app again \u2014 it already launched under the terms a restart would recreate. Restart the tool-server (\`argent server stop && argent server start --detach\`), then retry. If it reads unregistered again after that restart, stop: the process loads argent's dylib but never dials, and no further restart on either side changes it \u2014 treat native devtools as unavailable, then use \`describe\` or \`screenshot\` and drive by coordinate.
118923
- If state is connecting: do NOT restart the app \u2014 launching it is what starts the connection, so a relaunch discards the one in progress and returns this same state. Wait a few seconds and repeat this call.
118924
- If state is indeterminate: the process could not be inspected, so restart-app is worth one attempt. If this call still reports it after that restart, do NOT restart the app again \u2014 the service is stale rather than the app uninjected, so restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. Remote simulators can never inspect the process, so this is the only unconnected state a running app reaches there.
118921
+ If requiresRestart is true: call restart-app once, then proceed with the native feature. Read state before acting on a second such reading. Indeterminate reaches this rule too, and its line below bounds it at that one restart.
118922
+ If state is unregistered: do NOT restart the app again: it already launched under the terms a restart would recreate. Restart the tool-server (\`argent server stop && argent server start --detach\`), then retry. If it reads unregistered again after that restart, stop: the process loads argent's dylib but never dials, and no further restart on either side changes it. Treat native devtools as unavailable, then use \`describe\` or \`screenshot\` and drive by coordinate.
118923
+ If state is connecting: do NOT restart the app. Launching it is what starts the connection, so a relaunch discards the one in progress and returns this same state. Wait a few seconds and repeat this call.
118924
+ If state is indeterminate: the process could not be inspected, so restart-app is worth one attempt. If this call still reports it after that restart, do NOT restart the app again: the service is stale rather than the app uninjected, so restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. Remote simulators can never inspect the process, so this is the only unconnected state a running app reaches there.
118925
118925
  Returns { status: "init_failed", message, attempts } instead when the simulator's native-devtools environment failed to initialize.
118926
118926
  Fails if the simulator server is not running for the given UDID.`,
118927
118927
  zodSchema: zodSchema2,
@@ -119016,8 +119016,8 @@ var nativeNetworkLogsTool = {
119016
119016
  Unlike the JS-level network inspector (view-network-logs), this captures ALL network traffic from the app including native modules, Swift/Objective-C networking, and background transfers that bypass JS fetch.
119017
119017
  Use when you need to inspect native-level HTTP traffic that is invisible to JS fetch interception.
119018
119018
  Returns { status, count, events } where each event contains URL, method, status code, headers, and timing.
119019
- If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help \u2014 restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting \u2014 do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised \u2014 follow the message (re-boot the simulator) rather than retrying this tool.
119020
- A not-running app comes back as one of those statuses rather than a failure. An app that is not connected does too, except on a device whose devtools agent argent attached to rather than armed itself \u2014 there it fails with \`NATIVE_DEVTOOLS_NOT_CONNECTED\`, since no restart of ours can complete a handshake we do not own. Failures are separate: an Apple system app is rejected outright (terminal \u2014 never retry it), while a missing host dependency or a udid that is not an Apple device is not.`,
119019
+ If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
119020
+ A not-running app comes back as one of those statuses rather than a failure. An app that is not connected does too, except on a device whose devtools agent argent attached to rather than armed itself: there it fails with \`NATIVE_DEVTOOLS_NOT_CONNECTED\`, since no restart of ours can complete a handshake we do not own. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), while a missing host dependency or a udid that is not an Apple device is not.`,
119021
119021
  zodSchema: zodSchema3,
119022
119022
  services: (params) => ({
119023
119023
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -119079,8 +119079,8 @@ var nativeFindViewsTool = {
119079
119079
  Use when you need to locate a specific view by its properties without dumping the entire hierarchy.
119080
119080
  Returns { status: "ok", matches } with matching views including their frames, properties, optional ancestors, and optional children. Much more targeted than native-full-hierarchy.
119081
119081
  At least one of className, identifier, label, tag, or nativeID must be provided.
119082
- If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help \u2014 restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting \u2014 do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised \u2014 follow the message (re-boot the simulator) rather than retrying this tool.
119083
- A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal \u2014 never retry it), and the hierarchy query itself can error or time out.`,
119082
+ If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
119083
+ A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the hierarchy query itself can error or time out.`,
119084
119084
  zodSchema: zodSchema4,
119085
119085
  services: (params) => ({
119086
119086
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -119130,7 +119130,7 @@ var zodSchema5 = external_exports.object({
119130
119130
  'Exact UIView class names whose entire subtree should be pruned (e.g. ["UIImageView"] to drop image leaf nodes)'
119131
119131
  ),
119132
119132
  skipClassPrefixes: external_exports.array(external_exports.string()).optional().describe(
119133
- 'Class name prefixes to prune entire subtrees. For SwiftUI apps use ["_TtGC7SwiftUI"] to drop mangled SwiftUI generic type subtrees while keeping _UIHostingView and UIKit bridges. Avoid broad prefixes like "_UI" \u2014 they prune useful system views.'
119133
+ 'Class name prefixes to prune entire subtrees. For SwiftUI apps use ["_TtGC7SwiftUI"] to drop mangled SwiftUI generic type subtrees while keeping _UIHostingView and UIKit bridges. Avoid broad prefixes like "_UI": they prune useful system views.'
119134
119134
  ),
119135
119135
  maxDepth: external_exports.number().int().positive().optional().describe(
119136
119136
  "Maximum recursion depth (default 8). Increase for deeper inspection, decrease to reduce output size."
@@ -119149,8 +119149,8 @@ WARNING: Output can be extremely large (100KB\u2013500KB+) for complex apps, esp
119149
119149
  Use skipClasses / skipClassPrefixes to prune SwiftUI internal subtrees and reduce output size. Use the fields param to request only the properties you need.
119150
119150
  Use when you need deep layout debugging, finding views with no accessibility labels, or verifying view structure not exposed through the accessibility tree.
119151
119151
  Returns { status: "ok", windows, screen } with the full view hierarchy. screen gives the screen size in points on its portrait axes, and the interfaceOrientation of the UI (portrait, portraitUpsideDown, landscapeLeft, landscapeRight). Each screenFrame uses the portrait axes of the screen. Each windowFrame uses the axes of its window, which turn with the UI.
119152
- If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help \u2014 restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting \u2014 do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised \u2014 follow the message (re-boot the simulator) rather than retrying this tool.
119153
- A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal \u2014 never retry it), and the hierarchy query itself can error or time out.`,
119152
+ If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
119153
+ A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the hierarchy query itself can error or time out.`,
119154
119154
  zodSchema: zodSchema5,
119155
119155
  services: (params) => ({
119156
119156
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -119218,8 +119218,8 @@ Use when you are evaluating or debugging the lower-level native data behind the
119218
119218
  describe tool, or when you need its raw point-space geometry rather than describe's
119219
119219
  normalized contract.
119220
119220
 
119221
- If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help \u2014 restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting \u2014 do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised \u2014 follow the message (re-boot the simulator) rather than retrying this tool.
119222
- A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal \u2014 never retry it), and the screen query itself can error or time out.`,
119221
+ If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
119222
+ A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the screen query itself can error or time out.`,
119223
119223
  zodSchema: zodSchema6,
119224
119224
  services: (params) => ({
119225
119225
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -119287,8 +119287,8 @@ var nativeViewAtPointTool = {
119287
119287
  Unlike native-user-interactable-view-at-point, this ignores userInteractionEnabled,
119288
119288
  so it answers "what is visually here?" rather than "what would receive the touch?".
119289
119289
 
119290
- Use when a screenshot shows something the accessibility tree does not name \u2014 an
119291
- unlabeled icon, a decorative overlay, a custom-drawn cell \u2014 and you need the class,
119290
+ Use when a screenshot shows something the accessibility tree does not name (an
119291
+ unlabeled icon, a decorative overlay, a custom-drawn cell) and you need the class,
119292
119292
  identifier or nativeID of whatever draws it.
119293
119293
 
119294
119294
  Returns { status: "ok", view }: the matched view with its class name, frames,
@@ -119300,8 +119300,8 @@ normalized [0,1] simulator tap coordinates. To get them from a describe frame,
119300
119300
  multiply the normalized values by the screen size in points. Do this also when
119301
119301
  the UI is landscape.
119302
119302
 
119303
- If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help \u2014 restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting \u2014 do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised \u2014 follow the message (re-boot the simulator) rather than retrying this tool.
119304
- A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal \u2014 never retry it), and the point query itself can error or time out.`,
119303
+ If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
119304
+ A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the point query itself can error or time out.`,
119305
119305
  zodSchema: zodSchema7,
119306
119306
  services: (params) => ({
119307
119307
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -119376,7 +119376,7 @@ Unlike native-view-at-point, this respects userInteractionEnabled and is closer
119376
119376
  UIKit hit-testing semantics.
119377
119377
 
119378
119378
  Use when a tap lands somewhere unexpected or does nothing, to see which control
119379
- UIKit would hand the touch to \u2014 a transparent overlay swallowing it, a parent
119379
+ UIKit would hand the touch to: a transparent overlay swallowing it, a parent
119380
119380
  recognizer, a disabled button.
119381
119381
 
119382
119382
  Returns { status: "ok", view }: the hit-test winner with its class name, frames,
@@ -119388,8 +119388,8 @@ normalized [0,1] simulator tap coordinates. To get them from a describe frame,
119388
119388
  multiply the normalized values by the screen size in points. Do this also when
119389
119389
  the UI is landscape.
119390
119390
 
119391
- If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help \u2014 restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting \u2014 do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised \u2014 follow the message (re-boot the simulator) rather than retrying this tool.
119392
- A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal \u2014 never retry it), and the point query itself can error or time out.`,
119391
+ If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
119392
+ A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the point query itself can error or time out.`,
119393
119393
  zodSchema: zodSchema8,
119394
119394
  services: (params) => ({
119395
119395
  nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
@@ -119505,7 +119505,7 @@ init_zod();
119505
119505
  init_external_devices();
119506
119506
  var DEFAULT_METRO_PORT = 8081;
119507
119507
  var metroPortField = external_exports.coerce.number().int().min(1).max(65535).optional().describe(
119508
- "Metro server port. Optional \u2014 omit it to use this device's port, 8081 by default. Ignored for Chromium, whose CDP port is encoded in device_id."
119508
+ "Metro server port. Optional: omit it to use this device's port, 8081 by default. Ignored for Chromium, whose CDP port is encoded in device_id."
119509
119509
  );
119510
119510
  function metroPort(params) {
119511
119511
  if (params.port !== void 0) return params.port;
@@ -121560,14 +121560,14 @@ var zodSchema9 = external_exports.object({
121560
121560
  "Android: AVD name to launch a new emulator from (from `list-devices` \u2192 `avds[].name`). Provide exactly one of `udid`, `avdName`, `vvdImage`, or `electronAppPath`."
121561
121561
  ),
121562
121562
  vvdImage: external_exports.string().optional().describe(
121563
- "Vega (Fire TV): VVD image to boot \u2014 the `vvdImage` of a Vega device from `list-devices` (e.g. `tv`). Starts the single SDK-managed Vega Virtual Device. Provide exactly one of `udid`, `avdName`, `vvdImage`, or `electronAppPath`."
121563
+ "Vega (Fire TV): VVD image to boot: the `vvdImage` of a Vega device from `list-devices` (e.g. `tv`). Starts the single SDK-managed Vega Virtual Device. Provide exactly one of `udid`, `avdName`, `vvdImage`, or `electronAppPath`."
121564
121564
  ),
121565
121565
  bootTimeoutMs: external_exports.number().int().min(3e4).max(9e5).optional().describe(
121566
121566
  "Android/Vega: overall budget for the boot sequence. Default 480000 (8 min) on Android, 120000 (2 min) on Vega. Clamped to [30s, 15min]. Ignored on iOS."
121567
121567
  ),
121568
121568
  force: external_exports.boolean().optional().describe("Shut down and re-boot the device even if already running."),
121569
121569
  sound: external_exports.boolean().optional().describe(
121570
- "Android only: boot the emulator with audio output enabled. Defaults to false \u2014 argent boots emulators MUTED so several agent-driven devices don't all play sound on the host machine; pass `true` when the task involves playing, hearing, or testing audio. Takes effect at boot: if the emulator is already running muted, add `force: true` to reboot it with sound. A boot snapshot saved in the other audio mode can't be reused, so the first boot after toggling is a slower cold boot. The `boot-sound` argent flag flips this default to true. Ignored on iOS/Vega/Electron, which argent never mutes."
121570
+ "Android only: boot the emulator with audio output enabled. Defaults to false: argent boots emulators MUTED so several agent-driven devices don't all play sound on the host machine; pass `true` when the task involves playing, hearing, or testing audio. Takes effect at boot: if the emulator is already running muted, add `force: true` to reboot it with sound. A boot snapshot saved in the other audio mode can't be reused, so the first boot after toggling is a slower cold boot. The `boot-sound` argent flag flips this default to true. Ignored on iOS/Vega/Electron, which argent never mutes."
121571
121571
  ),
121572
121572
  headless: external_exports.boolean().optional().describe(
121573
121573
  "iOS only: boot the simulator core WITHOUT opening its GUI window (Simulator.app, or Device Hub on Xcode 27+). The device still streams via simulator-server; used by Argent Lens. Set the `ARGENT_SIMULATOR_NO_WINDOW` env var (1/true/yes) to force this host-wide without passing the flag per call (the iOS analog of `ARGENT_EMULATOR_NO_WINDOW`). Ignored on Android/Vega/Electron, which have no equivalent GUI step."
@@ -122801,7 +122801,7 @@ function createLaunchAppTool(registry2) {
122801
122801
  failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to launch ${params.bundleId}: ${failureSignal2.error_code}`
122802
122802
  },
122803
122803
  description: `Open an app by its bundle id (iOS) or package name (Android), or confirm the running renderer (Chromium).
122804
- Use when starting any app \u2014 prefer this over tapping home-screen / launcher icons. Also prepares the native-devtools injection before the app starts (the iOS slice on iOS, the tvOS slice on Apple TV); on tvOS, interaction is focus-driven \u2014 use the tv-* tools rather than coordinate taps.
122804
+ Use when starting any app; prefer this over tapping home-screen / launcher icons. Also prepares the native-devtools injection before the app starts (the iOS slice on iOS, the tvOS slice on Apple TV); on tvOS, interaction is focus-driven; use the tv-* tools rather than coordinate taps.
122805
122805
  Returns { launched, bundleId, note? }. Fails if the app is not installed on the target device (iOS / Android). On a physical iPhone this registers the app every other tool acts on; com.apple.springboard and com.apple.Spotlight register without launching. note warns when runner signing is not ready.
122806
122806
  For Chromium, the app is already running behind a CDP port; this call simply refreshes the cached viewport and acknowledges the bundleId tag. To change the visible route, use \`open-url\`.
122807
122807
  On Vega (Fire TV), pass the interactive component app id from manifest.toml (e.g. com.example.app.main) as bundleId.
@@ -123020,7 +123020,7 @@ function createRestartAppTool(registry2) {
123020
123020
  failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to restart ${params.bundleId}: ${failureSignal2.error_code}`
123021
123021
  },
123022
123022
  description: `Terminate then relaunch an app by bundle id / package name.
123023
- Use when you need a clean in-memory state without a full reinstall. Also refreshes the native-devtools injection before the relaunch (the iOS slice on iOS, the tvOS slice on Apple TV); on tvOS, interaction is focus-driven \u2014 use the tv-* tools rather than coordinate taps.
123023
+ Use when you need a clean in-memory state without a full reinstall. Also refreshes the native-devtools injection before the relaunch (the iOS slice on iOS, the tvOS slice on Apple TV); on tvOS, interaction is focus-driven; use the tv-* tools rather than coordinate taps.
123024
123024
  Returns { restarted, bundleId }. Fails if the app is not installed.`,
123025
123025
  alwaysLoad: true,
123026
123026
  searchHint: "terminate relaunch restart reset app bundle id package simulator emulator vega tvos fire tv",
@@ -123589,7 +123589,7 @@ var zodSchema14 = external_exports.object({
123589
123589
  "The permission to change. `notifications` is Android-only (iOS has no simctl service for it); `reminders` is iOS-only; `camera` works on Android and on iOS only when the target simulator's runtime models the service (varies by simruntime, not by the installed Xcode)."
123590
123590
  ),
123591
123591
  bundleId: external_exports.string().regex(BUNDLE_ID_PATTERN, BUNDLE_ID_MESSAGE).describe(
123592
- "App to change the permission for \u2014 required for every action. iOS: bundle id (e.g. com.example.app). Android: package name. `reset` is per-app too: simctl's device-wide reset (no bundleId) silently leaves existing per-app grants untouched on recent iOS, so the permission is always reset for this one app."
123592
+ "App to change the permission for, required for every action. iOS: bundle id (e.g. com.example.app). Android: package name. `reset` is per-app too: simctl's device-wide reset (no bundleId) silently leaves existing per-app grants untouched on recent iOS, so the permission is always reset for this one app."
123593
123593
  )
123594
123594
  });
123595
123595
  var permissionAction = {
@@ -123615,9 +123615,9 @@ var settingsPermissionsTool = {
123615
123615
  },
123616
123616
  description: `Grant, deny, or reset a runtime permission for an app without navigating the system Settings UI. Use during test setup to pre-authorize (or explicitly deny) a service before the app asks, or \`reset\` so the permission dialog appears again on next use. Always per-app: bundleId is required.
123617
123617
  Permissions: camera, microphone, photos, contacts, notifications, calendar, location, location-always, media-library, motion, reminders.
123618
- iOS simulator: edits the simulator's TCC store, always per-app. \`notifications\` is not supported (no iOS equivalent). \`reset\` is per-app \u2014 a device-wide reset is a no-op for existing grants on recent iOS, so it is not offered. \`grant location\`/\`location-always\` needs the app already installed (location auth isn't stored in TCC and isn't applied to a bundle id until the app exists) \u2014 enforced on local simulators; a remote simulator can't be probed for install state, so ensure the app is installed there first. Other services can be granted before install.
123618
+ iOS simulator: edits the simulator's TCC store, always per-app. \`notifications\` is not supported (no iOS equivalent). \`reset\` is per-app: a device-wide reset is a no-op for existing grants on recent iOS, so it is not offered. \`grant location\`/\`location-always\` needs the app already installed (location auth isn't stored in TCC and isn't applied to a bundle id until the app exists). This is enforced on local simulators; a remote simulator can't be probed for install state, so ensure the app is installed there first. Other services can be granted before install.
123619
123619
  Android: changes the mapped \`android.permission.*\` runtime permissions (reset also best-effort clears the user-set permission flags). The app must be installed and declare them in its manifest; \`reminders\` has no Android equivalent.
123620
- Some permission changes terminate the app if it is running (system behavior on both platforms) \u2014 set permissions before launching, or relaunch after.
123620
+ Some permission changes terminate the app if it is running (system behavior on both platforms), so set permissions before launching, or relaunch after.
123621
123621
  Returns { action, permission, bundleId, applied, skipped? }: \`applied\` lists the platform-level services/permissions actually changed; \`skipped\` (Android) lists mapped permissions the package manager rejected, e.g. ones the manifest doesn't declare. Fails if nothing could be applied.`,
123622
123622
  searchHint: "grant deny reset revoke app permissions privacy camera microphone location settings",
123623
123623
  zodSchema: zodSchema14,
@@ -123785,7 +123785,7 @@ var openUrlTool = {
123785
123785
  description: `Open a URL or URL scheme on the device.
123786
123786
  Use to navigate to a web page or deep-link into an app. On Chromium, this navigates the primary renderer to the given URL.
123787
123787
  Cross-platform schemes: https://, tel:, mailto:. iOS also: messages://, settings://, maps://. Android also: geo:, plus any app-specific deep link.
123788
- Deep-linking caveat: an https:// link opens the native app only when an installed app is verified for the link's domain (iOS Universal Links / Android App Links) \u2014 otherwise it opens in the browser, and on iOS simulators it may open in Safari even when the owning app is installed. To reliably open an installed app, use its custom scheme (scheme://path) or launch-app with its bundle id.
123788
+ Deep-linking caveat: an https:// link opens the native app only when an installed app is verified for the link's domain (iOS Universal Links / Android App Links); otherwise it opens in the browser, and on iOS simulators it may open in Safari even when the owning app is installed. To reliably open an installed app, use its custom scheme (scheme://path) or launch-app with its bundle id.
123789
123789
  On a physical iPhone, http(s) URLs default to Safari and any other scheme needs bundleId; the receiving app becomes the app under automation.
123790
123790
  Returns { opened, url, note? }. note carries the deep-linking caveat when a web URL was opened on a native device. Fails if no app is registered to handle the URI (iOS/Android) or the renderer rejects the navigation (Chromium).`,
123791
123791
  zodSchema: zodSchema15,
@@ -124394,7 +124394,7 @@ var zodSchema16 = external_exports.object({
124394
124394
  "Scale factor (0.01-1.0). Defaults to ARGENT_SCREENSHOT_SCALE env var, or 0.25 if unset for iOS/Android. On Chromium the default is 1.0 (no downscale); pass <1 to opt in. Downscaling on Chromium requires the optional `sharp` dependency."
124395
124395
  ),
124396
124396
  includeImageInContext: external_exports.boolean().optional().default(true).describe(
124397
- "Default true. Set false only when capturing a full-resolution PNG (scale: 1.0) to save as a baseline/current for screenshot-diff \u2014 the file is still written, but the image bytes are not attached to the agent context."
124397
+ "Default true. Set false only when capturing a full-resolution PNG (scale: 1.0) to save as a baseline/current for screenshot-diff. The file is still written, but the image bytes are not attached to the agent context."
124398
124398
  ),
124399
124399
  downscaler: external_exports.enum(["lanczos3", "box", "bilinear", "nearest"]).optional().describe(
124400
124400
  "Downscaling algorithm when scale<1 on Chromium. Defaults to lanczos3 (highest quality). Mirrors sim-server's wire enum. Ignored on physical iPhones."
@@ -124637,11 +124637,11 @@ var gestureTapTool = {
124637
124637
  },
124638
124638
  description: `Press the device screen (iOS simulator or physical device, Android emulator, or Chromium app) at normalized coordinates: x and y are fractions of screen width and height in 0.0\u20131.0 (not pixels).
124639
124639
  Sends a Down event followed by an Up event at the same point. For Chromium, this dispatches a CDP mouse-press/release on the renderer.
124640
- Set clickCount: 2 for a double-tap / double-click \u2014 the taps are dispatched as one gesture with proper click counting, which two separate tap calls cannot guarantee.
124640
+ Set clickCount: 2 for a double-tap / double-click: the taps are dispatched as one gesture with proper click counting, which two separate tap calls cannot guarantee.
124641
124641
  Use when you need to tap a button, link, or any tappable element on the screen.
124642
124642
  Returns { tapped: true, timestampMs }. On physical iOS, reactivated: true = app was re-fronted; re-describe. Fails if the simulator-server / emulator backend / Chromium CDP is not reachable for the given device.
124643
124643
  On a physical iPhone use \`describe\`; \`native-describe-screen\` is simulator-only.
124644
- Before tapping, determine the correct coordinates by using discovery tools \u2014 pick by platform: iOS / Android use \`describe\`, \`native-describe-screen\`, or \`debugger-component-tree\`; Chromium uses \`describe\` (the DOM walker), since the native and RN-specific discovery tools don't apply. More information in \`argent-device-interact\` skill`,
124644
+ Before tapping, determine the correct coordinates by using discovery tools. Pick by platform: iOS / Android use \`describe\`, \`native-describe-screen\`, or \`debugger-component-tree\`; Chromium uses \`describe\` (the DOM walker), since the native and RN-specific discovery tools don't apply. More information in \`argent-device-interact\` skill`,
124645
124645
  alwaysLoad: true,
124646
124646
  searchHint: "tap press button element device simulator emulator chromium touch down up click",
124647
124647
  zodSchema: zodSchema17,
@@ -124756,7 +124756,7 @@ var gestureSwipeTool = {
124756
124756
  description: `Execute a smooth swipe / drag touch gesture between two points on the device (iOS simulator or physical device, or Android emulator). All from/to positions are normalized 0.0\u20131.0 (fractions of screen width/height, not pixels), same as gesture-tap.
124757
124757
  Generates interpolated Move events for a natural feel (~60fps).
124758
124758
  Swipe up (fromY > toY) to scroll content down.
124759
- Use when you need to scroll a list, dismiss a modal, drag an element, or navigate between pages. Not supported on Chromium \u2014 use gesture-scroll there instead.
124759
+ Use when you need to scroll a list, dismiss a modal, drag an element, or navigate between pages. Not supported on Chromium; use gesture-scroll there instead.
124760
124760
  Physical iOS: an edge gesture (back-swipe) needs fromX 0 exactly; durationMs sets drag speed, not time; momentum:false only rests 300ms at the end and does not damp.
124761
124761
  Pass momentum:false for a momentum-free swipe that lands where the finger lifts (little to no fling at the 300 default), when you need a deterministic scroll distance; it needs durationMs >= 150 and is rejected below that, a shorter ease-out leaving the OS too little wall clock to read the deceleration as a stop. At 150 it lands short of the lift point instead, and 2 of 47 runs still flung backwards. A plain swipe takes any duration up to 10000ms and is delivered as close to the speed it was authored as a 16ms frame allows: below ~32ms the whole travel lands in one or two frames, which the OS flings as hard as it flings anything. Returns { swiped: true, timestampMs }. On physical iOS, reactivated: true = app was re-fronted; re-describe. Fails if the simulator-server / emulator backend is not reachable for the given device.`,
124762
124762
  alwaysLoad: true,
@@ -124859,7 +124859,7 @@ var sleep4 = (ms) => new Promise((r) => setTimeout(r, ms));
124859
124859
  var zodSchema19 = external_exports.object({
124860
124860
  udid: external_exports.string().describe("Target Chromium device id from `list-devices` (chromium-cdp-<port>)."),
124861
124861
  x: external_exports.number().describe(
124862
- "Anchor x: normalized 0.0\u20131.0 (fraction of window width, not pixels). The wheel events land here \u2014 put it over the element you want to scroll."
124862
+ "Anchor x: normalized 0.0\u20131.0 (fraction of window width, not pixels). The wheel events land here; put it over the element you want to scroll."
124863
124863
  ),
124864
124864
  y: external_exports.number().describe("Anchor y: normalized 0.0\u20131.0 (fraction of window height, not pixels)."),
124865
124865
  deltaX: external_exports.number().optional().describe(
@@ -124892,7 +124892,7 @@ var gestureScrollTool = {
124892
124892
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to scroll: ${failureSignal2.error_code}`
124893
124893
  },
124894
124894
  description: `Scroll content in a Chromium app by dispatching mouse-wheel events at a point. Anchor x/y are normalized 0.0\u20131.0 (fractions of the window, not pixels), same coordinate space as gesture-tap and describe. Deltas are fractions of the window too: deltaY 0.5 scrolls down half a window; negative scrolls back up.
124895
- Use when content is below/above the fold (describe shows off-screen elements with zero height) or a list needs scrolling. Chromium only \u2014 on iOS/Android use gesture-swipe.
124895
+ Use when content is below/above the fold (describe shows off-screen elements with zero height) or a list needs scrolling. Chromium only: on iOS/Android use gesture-swipe.
124896
124896
  Returns { scrolled: true, timestampMs }. Fails if the Chromium CDP session is not reachable for the given device.`,
124897
124897
  searchHint: "scroll wheel list page chromium mouse down up content fold",
124898
124898
  zodSchema: zodSchema19,
@@ -124937,7 +124937,7 @@ var zodSchema20 = external_exports.object({
124937
124937
  `Total drag duration in milliseconds (default 300, at most ${MAX_DURATION_MS2} - the button stays down for exactly this long), interpolated at ~60fps.`
124938
124938
  ),
124939
124939
  momentum: external_exports.boolean().optional().describe(
124940
- "Whether the drag releases with momentum; default true (a constant-speed drag). Pass false to decelerate into the release point (ease-out) so an app deriving fling from pointer release velocity (carousels, drag libraries) reads ~0 and applies little to no momentum \u2014 use it when the drag must stop where it was aimed rather than fling past. Deceleration needs wall clock: under ~100ms the whole drag fits inside the velocity window a page averages over (tens of ms), so some fling survives, and under ~70ms its extra frames cannot dispatch fast enough to fit durationMs. Keep durationMs at its default when the fling must be fully suppressed."
124940
+ "Whether the drag releases with momentum; default true (a constant-speed drag). Pass false to decelerate into the release point (ease-out) so an app deriving fling from pointer release velocity (carousels, drag libraries) reads ~0 and applies little to no momentum. Use it when the drag must stop where it was aimed rather than fling past. Deceleration needs wall clock: under ~100ms the whole drag fits inside the velocity window a page averages over (tens of ms), so some fling survives, and under ~70ms its extra frames cannot dispatch fast enough to fit durationMs. Keep durationMs at its default when the fling must be fully suppressed."
124941
124941
  ),
124942
124942
  // `momentum`'s earlier spelling, with the opposite polarity. Declared so this
124943
124943
  // non-strict object refuses it instead of stripping it and running the default.
@@ -124957,8 +124957,8 @@ var gestureDragTool = {
124957
124957
  completedMsg: ({ params }) => `Dragged from (${Math.round(params.fromX * 100)}%, ${Math.round(params.fromY * 100)}%) to (${Math.round(params.toX * 100)}%, ${Math.round(params.toY * 100)}%)`,
124958
124958
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to drag: ${failureSignal2.error_code}`
124959
124959
  },
124960
- description: `Press the left mouse button at a start point, move to an end point, and release \u2014 a desktop mouse drag in a Chromium app. All positions are normalized 0.0\u20131.0 (fractions of the window, not pixels), same coordinate space as gesture-tap and describe, except that a coordinate of exactly 1.0 lands one pixel inside the window edge (gesture-tap maps it to the edge itself). Interpolates mouse-move events at ~60fps over durationMs for a natural drag (a momentum-free drag samples more finely when durationMs is short, so its ease-out has a curve).
124961
- Use for slider thumbs, drag-and-drop, text selection, or draggable UI elements. Dragging never scrolls content on desktop \u2014 use gesture-scroll for lists/pages. Chromium only \u2014 on iOS/Android use gesture-swipe.
124960
+ description: `Press the left mouse button at a start point, move to an end point, and release: a desktop mouse drag in a Chromium app. All positions are normalized 0.0\u20131.0 (fractions of the window, not pixels), same coordinate space as gesture-tap and describe, except that a coordinate of exactly 1.0 lands one pixel inside the window edge (gesture-tap maps it to the edge itself). Interpolates mouse-move events at ~60fps over durationMs for a natural drag (a momentum-free drag samples more finely when durationMs is short, so its ease-out has a curve).
124961
+ Use for slider thumbs, drag-and-drop, text selection, or draggable UI elements. Dragging never scrolls content on desktop; use gesture-scroll for lists/pages. Chromium only: on iOS/Android use gesture-swipe.
124962
124962
  Pass momentum:false for a momentum-free drag that decelerates into the release, so apps that compute a fling from the pointer stream read ~0 velocity and the drag ends where it was aimed instead of flinging past it (a durationMs under ~100ms is too short for the deceleration to suppress the fling entirely). Returns { dragged: true, timestampMs }. Fails if the Chromium CDP session is not reachable for the given device.`,
124963
124963
  searchHint: "drag drop slider mouse press move release chromium select",
124964
124964
  zodSchema: zodSchema20,
@@ -125271,7 +125271,7 @@ var gesturePinchTool = {
125271
125271
  completedMsg: ({ params }) => `Pinched ${params.endDistance > params.startDistance ? "out" : "in"} at (${Math.round(params.centerX * 100)}%, ${Math.round(params.centerY * 100)}%)`,
125272
125272
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to pinch: ${failureSignal2.error_code}`
125273
125273
  },
125274
- description: `Execute a pinch-to-zoom gesture by moving two fingers toward or away from a center point to change the scale of on-screen content. All positions and distances are normalized 0.0\u20131.0 (fractions of screen width/height, not pixels)\u2014same coordinate space as gesture-tap and gesture-swipe.
125274
+ description: `Execute a pinch-to-zoom gesture by moving two fingers toward or away from a center point to change the scale of on-screen content. All positions and distances are normalized 0.0\u20131.0 (fractions of screen width/height, not pixels), same coordinate space as gesture-tap and gesture-swipe.
125275
125275
  startDistance > endDistance = pinch in (zoom out). startDistance < endDistance = pinch out (zoom in).
125276
125276
  Typical values: startDistance 0.2, endDistance 0.6 for a zoom-in pinch at screen center.
125277
125277
  Auto-generates interpolated frames at ~60fps. The angle parameter controls the axis (0 = horizontal, 90 = vertical). Optional endCenterX/endCenterY drift the centroid linearly over the gesture (omitted = fixed center).
@@ -125325,13 +125325,13 @@ var zodSchema23 = external_exports.object({
125325
125325
  "Center of rotation, vertical: normalized 0.0\u20131.0 (fraction of screen height, not pixels)"
125326
125326
  ),
125327
125327
  radius: external_exports.number().optional().describe(
125328
- "Distance from center to each finger: normalized 0.0\u20131.0 (fraction of screen, not pixels). E.g. 0.15 = fingers placed 15% of screen away from center. One value for both axes, so on a non-square screen the orbit is a physical ellipse \u2014 pass radiusX+radiusY instead for a true circle. Required unless radiusX and radiusY are given."
125328
+ "Distance from center to each finger: normalized 0.0\u20131.0 (fraction of screen, not pixels). E.g. 0.15 = fingers placed 15% of screen away from center. One value for both axes, so on a non-square screen the orbit is a physical ellipse; pass radiusX+radiusY instead for a true circle. Required unless radiusX and radiusY are given."
125329
125329
  ),
125330
125330
  radiusX: external_exports.number().optional().describe(
125331
- "Per-axis finger distance, horizontal: normalized 0.0\u20131.0 fraction of screen WIDTH. Give both radiusX and radiusY (they override radius) with radiusX\xB7screenWidth = radiusY\xB7screenHeight for a physically circular orbit \u2014 constant finger separation, no pinch coupled into the turn."
125331
+ "Per-axis finger distance, horizontal: normalized 0.0\u20131.0 fraction of screen WIDTH. Give both radiusX and radiusY (they override radius) with radiusX\xB7screenWidth = radiusY\xB7screenHeight for a physically circular orbit: constant finger separation, no pinch coupled into the turn."
125332
125332
  ),
125333
125333
  radiusY: external_exports.number().optional().describe(
125334
- "Per-axis finger distance, vertical: normalized 0.0\u20131.0 fraction of screen HEIGHT. Always paired with radiusX \u2014 see radiusX."
125334
+ "Per-axis finger distance, vertical: normalized 0.0\u20131.0 fraction of screen HEIGHT. Always paired with radiusX; see radiusX."
125335
125335
  ),
125336
125336
  startAngle: external_exports.number().describe("Starting angle in degrees (0 = right, 90 = down)"),
125337
125337
  endAngle: external_exports.number().describe("Ending angle in degrees. endAngle > startAngle = clockwise."),
@@ -125361,7 +125361,7 @@ var gestureRotateTool = {
125361
125361
  },
125362
125362
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to rotate gesture: ${failureSignal2.error_code}`
125363
125363
  },
125364
- description: `Send a two-finger circular arc gesture to rotate on-screen content by a specified angle. Two fingers are placed opposite each other at a fixed radius from the center, then swept from startAngle to endAngle degrees. All positions and radii are normalized 0.0\u20131.0 (fractions of screen width/height, not pixels)\u2014same coordinate space as gesture-tap and gesture-swipe.
125364
+ description: `Send a two-finger circular arc gesture to rotate on-screen content by a specified angle. Two fingers are placed opposite each other at a fixed radius from the center, then swept from startAngle to endAngle degrees. All positions and radii are normalized 0.0\u20131.0 (fractions of screen width/height, not pixels), same coordinate space as gesture-tap and gesture-swipe.
125365
125365
  endAngle > startAngle = clockwise rotation. Typical values: radius 0.15, startAngle 0, endAngle 90 for a 90\xB0 clockwise turn. A single radius applies to both axes, so on a non-square screen it traces a physical ellipse (finger separation varies through the turn); pass radiusX+radiusY (fractions of width/height with radiusX\xB7width = radiusY\xB7height) for a physically circular orbit instead.
125366
125366
  Auto-generates interpolated frames at ~60fps.
125367
125367
  Unlike gesture-pinch which moves fingers linearly to zoom, this orbits fingers in an arc to change orientation.
@@ -126162,7 +126162,7 @@ var zodSchema25 = external_exports.object({
126162
126162
  "Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, or Chromium id)."
126163
126163
  ),
126164
126164
  text: external_exports.string().optional().describe(
126165
- 'Text to type character by character. Cannot be combined with `key` in one call \u2014 one call per action; to type and then press a key, put two `keyboard` steps in one `run-sequence`. Handles uppercase and common punctuation. To type a credential without its plaintext ever entering your context, use a secret placeholder: `{{secret:<NAME>}}` \u2014 e.g. text: "{{secret:APP_PASSWORD}}". The value is resolved on the machine running the tool-server, from the first source that defines the name: the `ARGENT_SECRET_<NAME>` environment variable, `.argent/secrets.env` in the project, the project\'s `.env.local` / `.env` (only their `ARGENT_SECRET_`-prefixed keys), then `~/.argent/secrets.env`. Nothing else on the host is reachable. Placeholders can be embedded in longer text and are never echoed back resolved. If the secret you need is not set, the failure lists the available names and every source it looked in \u2014 ask the user to add it to one of them (a secrets file applies immediately; an env var needs a restart), NEVER ask the user to paste the secret value into the conversation.'
126165
+ 'Text to type character by character. Cannot be combined with `key` in one call (one call per action); to type and then press a key, put two `keyboard` steps in one `run-sequence`. Handles uppercase and common punctuation. To type a credential without its plaintext ever entering your context, use a secret placeholder: `{{secret:<NAME>}}`, e.g. text: "{{secret:APP_PASSWORD}}". The value is resolved on the machine running the tool-server, from the first source that defines the name: the `ARGENT_SECRET_<NAME>` environment variable, `.argent/secrets.env` in the project, the project\'s `.env.local` / `.env` (only their `ARGENT_SECRET_`-prefixed keys), then `~/.argent/secrets.env`. Nothing else on the host is reachable. Placeholders can be embedded in longer text and are never echoed back resolved. If the secret you need is not set, the failure lists the available names and every source it looked in; ask the user to add it to one of them (a secrets file applies immediately; an env var needs a restart), NEVER ask the user to paste the secret value into the conversation.'
126166
126166
  ),
126167
126167
  key: external_exports.string().optional().describe(
126168
126168
  "Named key to press: enter, escape, backspace, tab, space, arrow-up, arrow-down, arrow-left, arrow-right, f1-f12. Cannot be combined with `text` in one call: one call per action; to type and then press a key, put two `keyboard` steps in one `run-sequence`. Not supported on TV targets; move focus with `tv-remote` (up/down/left/right) instead. Physical iOS: only `enter` and `backspace`."
@@ -126210,11 +126210,11 @@ function createKeyboardTool(registry2) {
126210
126210
  description: `Type text or press special keys on the device (iOS simulator, Android emulator or device, Chromium app, Vega Virtual Device, or Apple TV / Android TV) using keyboard events.
126211
126211
  Use when you need to enter text or trigger a named key such as enter, escape, or arrow keys. On Vega and Apple TV / Android TV, prefer the remote tools for D-pad navigation; use keyboard to type into a focused text field (e.g. a search or login box).
126212
126212
  Returns { typed: string, keys: number }. On physical iOS, reactivated: true = app was re-fronted; re-describe. Fails if text and key are both given in one call (rejected before anything is typed), if an unsupported key name is provided, or if the device's input backend is not reachable.
126213
- A failure is not rolled back. An unsupported key name is always rejected before anything is sent. Un-typeable text is not: the iOS simulator and Chromium reject it mid-string and leave the characters before it in the field (Android, Vega and TV targets check the whole string up front). A transport failure partway also leaves the text already sent. On a retry, read the field's actual contents \u2014 do not assume it is unchanged.
126214
- - text: types a string (supports uppercase, digits, common punctuation). To type a credential, use \`{{secret:<NAME>}}\` \u2014 resolved server-side from the \`ARGENT_SECRET_<NAME>\` env var or an argent secrets file (\`.argent/secrets.env\` in the project, \`~/.argent/secrets.env\`, or an \`ARGENT_SECRET_\`-prefixed key in the project's \`.env\`/\`.env.local\`), so the plaintext never enters agent context; the result echoes the placeholder, not the value, and the after-typing auto-screenshot is skipped. To submit after typing a secret, put both steps in ONE \`run-sequence\` \u2014 that keeps the skip covering the Enter, which a second bare \`keyboard\` call would not.
126213
+ A failure is not rolled back. An unsupported key name is always rejected before anything is sent. Un-typeable text is not: the iOS simulator and Chromium reject it mid-string and leave the characters before it in the field (Android, Vega and TV targets check the whole string up front). A transport failure partway also leaves the text already sent. On a retry, read the field's actual contents; do not assume it is unchanged.
126214
+ - text: types a string (supports uppercase, digits, common punctuation). To type a credential, use \`{{secret:<NAME>}}\`, resolved server-side from the \`ARGENT_SECRET_<NAME>\` env var or an argent secrets file (\`.argent/secrets.env\` in the project, \`~/.argent/secrets.env\`, or an \`ARGENT_SECRET_\`-prefixed key in the project's \`.env\`/\`.env.local\`), so the plaintext never enters agent context; the result echoes the placeholder, not the value, and the after-typing auto-screenshot is skipped. To submit after typing a secret, put both steps in ONE \`run-sequence\`: that keeps the skip covering the Enter, which a second bare \`keyboard\` call would not.
126215
126215
  - key: presses a single named key (enter, escape, backspace, tab, arrow-up/down/left/right, f1-f12). NOT supported on TV targets; move focus with \`tv-remote\` instead. Physical iOS: only \`enter\` and \`backspace\`.
126216
- On a TV target (runtimeKind 'tv') only \`text\` applies \u2014 focus a text field first (with \`tv-remote\`), then type into it (injected HID keyboard on Apple TV, \`adb input text\` on Android TV).
126217
- One call does one action: pass text OR key, never both. To type and then press a key, send two \`keyboard\` steps in one \`run-sequence\` \u2014 { text: "hello" } then { key: "enter" } \u2014 which also keeps it to a single round-trip.`,
126216
+ On a TV target (runtimeKind 'tv') only \`text\` applies. Focus a text field first (with \`tv-remote\`), then type into it (injected HID keyboard on Apple TV, \`adb input text\` on Android TV).
126217
+ One call does one action: pass text OR key, never both. To type and then press a key, send two \`keyboard\` steps in one \`run-sequence\` ({ text: "hello" } then { key: "enter" }), which also keeps it to a single round-trip.`,
126218
126218
  zodSchema: zodSchema25,
126219
126219
  capability: capability17,
126220
126220
  alwaysLoad: true,
@@ -126279,7 +126279,7 @@ var pasteZodSchema = external_exports.object({
126279
126279
  "Target device id from `list-devices` (iOS simulator UDID or Android emulator serial)."
126280
126280
  ),
126281
126281
  text: external_exports.string().min(1).describe(
126282
- "Text to put on the device clipboard and paste into the focused field. Supports `{{secret:<NAME>}}` placeholders, resolved on the tool-server from the `ARGENT_SECRET_<NAME>` environment variable or an argent secrets file \u2014 the same sources as `keyboard` \u2014 so a credential never enters your context. If the secret is not set, the failure lists the available names and every source it looked in; ask the user to add it there, NEVER ask for the value in the conversation."
126282
+ "Text to put on the device clipboard and paste into the focused field. Supports `{{secret:<NAME>}}` placeholders, resolved on the tool-server from the `ARGENT_SECRET_<NAME>` environment variable or an argent secrets file (the same sources as `keyboard`), so a credential never enters your context. If the secret is not set, the failure lists the available names and every source it looked in; ask the user to add it there, NEVER ask for the value in the conversation."
126283
126283
  )
126284
126284
  });
126285
126285
 
@@ -126425,7 +126425,7 @@ function createPasteTool(registry2) {
126425
126425
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to paste text: ${failureSignal2.error_code}`
126426
126426
  },
126427
126427
  description: `Paste text into the focused field: puts \`text\` on the DEVICE clipboard, then triggers the platform's paste shortcut (iOS simulator, Android emulator).
126428
- Do NOT use this in place of \`keyboard\`. \`keyboard\` types as a user would and is the default for all text entry; use \`paste\` only where a real user would paste \u2014 a 2FA/OTP code copied from another app, a long link or token, or when testing the app's own paste handling.
126428
+ Do NOT use this in place of \`keyboard\`. \`keyboard\` types as a user would and is the default for all text entry; use \`paste\` only where a real user would paste: a 2FA/OTP code copied from another app, a long link or token, or when testing the app's own paste handling.
126429
126429
  Tap the field first so it has focus. Returns { pasted: true }, plus via: "keyboard" when a secret was typed instead of pasted. Fails on a TV target, when the device clipboard cannot be set, when a secret that has to be typed holds a character that cannot be typed, or when the simulator-server build lacks clipboard support.
126430
126430
  Supports \`{{secret:<NAME>}}\` placeholders like \`keyboard\`; the value is never echoed back.`,
126431
126431
  searchHint: "paste clipboard pasteboard otp 2fa code fill field",
@@ -126466,7 +126466,7 @@ var rotateTool = {
126466
126466
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to rotate device: ${failureSignal2.error_code}`
126467
126467
  },
126468
126468
  description: `Set the device orientation to Portrait, LandscapeLeft, LandscapeRight, or PortraitUpsideDown.
126469
- Use to test layout in a different orientation. Re-run \`describe\` afterwards \u2014 frame coordinates change with the orientation.
126469
+ Use to test layout in a different orientation. Re-run \`describe\` afterwards: frame coordinates change with the orientation.
126470
126470
  On an unfolded foldable iOS simulator (the iPhone Duo), the value sets the orientation of the device, not of the UI: \`Portrait\` gives a landscape UI and \`LandscapeLeft\` gives a portrait UI. To fold or unfold the device, use \`fold\`.
126471
126471
  Returns { orientation }. Fails if the target device is not booted.`,
126472
126472
  zodSchema: zodSchema26,
@@ -126931,7 +126931,7 @@ var shakeTool = {
126931
126931
  },
126932
126932
  description: `Shake the device (iOS simulator or Android emulator).
126933
126933
  Use to trigger anything bound to the shake gesture: iOS's "Undo Typing" / "Redo Typing" prompt in a text field, React Native's developer menu in a debug build, or an app's own shake-to-report handler.
126934
- iOS delivers one discrete shake per gesture (the same motion event a physical device raises). Android has no OS-level shake event \u2014 the accelerometer is driven through a burst of hard direction changes so app-side detectors fire, and the resting orientation is restored afterwards.
126934
+ iOS delivers one discrete shake per gesture (the same motion event a physical device raises). Android has no OS-level shake event: the accelerometer is driven through a burst of hard direction changes so app-side detectors fire, and the resting orientation is restored afterwards.
126935
126935
  Set \`count\` above 1 when a detector needs sustained motion before it triggers.
126936
126936
  Returns { shaken: true, count }.
126937
126937
  Works on local and remote (sim-remote) iOS simulators.
@@ -127189,7 +127189,7 @@ var buttonSchema = external_exports.preprocess(
127189
127189
  },
127190
127190
  external_exports.union([external_exports.enum(BUTTONS), external_exports.array(external_exports.enum(BUTTONS)).min(1).max(64)])
127191
127191
  ).describe(
127192
- 'A single TV-remote button, or a path of them run in one call. Buttons: up/down/left/right (D-pad), select (OK), back, home, menu, playPause, rewind, fastForward, next, previous, volumeUp, volumeDown, mute. The media-transport and volume keys work on Android TV and Vega; on the Apple TV simulator they are rejected (its HID stack ignores them) \u2014 the D-pad/select/back/menu/home/playPause core works on all three. For multi-step navigation pass an array, e.g. ["up","right","right","select"] \u2014 strongly prefer this over multiple `tv-remote` calls: the whole path runs in a single call.'
127192
+ 'A single TV-remote button, or a path of them run in one call. Buttons: up/down/left/right (D-pad), select (OK), back, home, menu, playPause, rewind, fastForward, next, previous, volumeUp, volumeDown, mute. The media-transport and volume keys work on Android TV and Vega; on the Apple TV simulator they are rejected (its HID stack ignores them). The D-pad/select/back/menu/home/playPause core works on all three. For multi-step navigation pass an array, e.g. ["up","right","right","select"]; strongly prefer this over multiple `tv-remote` calls: the whole path runs in a single call.'
127193
127193
  );
127194
127194
  var zodSchema28 = external_exports.object({
127195
127195
  udid: external_exports.string().describe("Target TV device id from `list-devices` (Apple TV, Android TV, or Vega)."),
@@ -127211,10 +127211,10 @@ function createTvRemoteTool(registry2) {
127211
127211
  completedMsg: ({ params }) => `Pressed ${params.button} on TV remote${(params.repeat ?? 1) > 1 ? ` ${params.repeat} times` : ""}`,
127212
127212
  failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to press ${params.button} on TV remote: ${failureSignal2.error_code}`
127213
127213
  },
127214
- description: `Press a TV remote / D-pad button (or a whole path of them) on a TV device \u2014 Apple TV (tvOS), Android TV (leanback), or Vega (Fire TV).
127215
- A TV is navigated with a directional remote, not touch \u2014 use this instead of gesture-tap/swipe (which do not apply on a TV). Move focus with up/down/left/right, confirm with select, go back with back/menu, exit with home, and use playPause/rewind/fastForward/next/previous/volumeUp/volumeDown/mute for the corresponding remote keys. (On the Apple TV simulator the media-transport and volume keys are rejected \u2014 its HID stack ignores them; they work on Android TV and Vega.)
127214
+ description: `Press a TV remote / D-pad button (or a whole path of them) on a TV device: Apple TV (tvOS), Android TV (leanback), or Vega (Fire TV).
127215
+ A TV is navigated with a directional remote, not touch. Use this instead of gesture-tap/swipe (which do not apply on a TV). Move focus with up/down/left/right, confirm with select, go back with back/menu, exit with home, and use playPause/rewind/fastForward/next/previous/volumeUp/volumeDown/mute for the corresponding remote keys. (On the Apple TV simulator the media-transport and volume keys are rejected (its HID stack ignores them); they work on Android TV and Vega.)
127216
127216
  Single press: { button: "down" }. Repeat the same button: { button: "down", repeat: 3 }.
127217
- Multi-step navigation: pass a path as { button: ["up","right","right","select"] } \u2014 it runs in one tool call, far cheaper than separate presses.
127217
+ Multi-step navigation: pass a path as { button: ["up","right","right","select"] }. It runs in one tool call, far cheaper than separate presses.
127218
127218
  Read the screen with \`describe\` before and after to see where focus landed.
127219
127219
  Returns { pressed, count }.`,
127220
127220
  // A path (≤64 buttons) × repeat (≤50) flattens to thousands of presses, sent
@@ -133566,11 +133566,11 @@ var DEFAULT_POLL_INTERVAL_MS = 400;
133566
133566
  var zodSchema29 = external_exports.object({
133567
133567
  udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id)."),
133568
133568
  condition: external_exports.enum(["exists", "visible", "hidden", "text"]).describe(
133569
- "What to wait for. `exists`: selector is anywhere in the tree. `visible`: selector is present with a non-zero on-screen frame. `hidden`: selector is absent or zero-area. `text`: the first visible match in reading order (topmost), falling back to the first match overall if none is visible, contains (or, with textMatch `equals`, exactly matches) expectedText \u2014 if a loose selector hits several elements, only that one is checked, so narrow it to target the intended element."
133569
+ "What to wait for. `exists`: selector is anywhere in the tree. `visible`: selector is present with a non-zero on-screen frame. `hidden`: selector is absent or zero-area. `text`: the first visible match in reading order (topmost), falling back to the first match overall if none is visible, contains (or, with textMatch `equals`, exactly matches) expectedText. If a loose selector hits several elements, only that one is checked, so narrow it to target the intended element."
133570
133570
  ),
133571
133571
  selector: selectorSchema.describe("Element to match (text / identifier / role)."),
133572
133572
  expectedText: external_exports.string().min(1).optional().describe(
133573
- "For condition `text`: the string the first visible matched element (topmost in reading order; the first match overall if none is visible) must contain (default) or equal \u2014 see `textMatch`. Case-insensitive."
133573
+ "For condition `text`: the string the first visible matched element (topmost in reading order; the first match overall if none is visible) must contain (default) or equal (see `textMatch`). Case-insensitive."
133574
133574
  ),
133575
133575
  textMatch: external_exports.enum(["contains", "equals"]).optional().describe(
133576
133576
  "For condition `text`: how expectedText is compared. `contains` (default) is a case-insensitive substring; `equals` is a case-insensitive full-string match."
@@ -133680,13 +133680,13 @@ function createAwaitUiElementTool(registry2) {
133680
133680
  description: `Block until a UI element reaches an expected state or a timeout elapses, so you don't have to poll screenshot/describe yourself.
133681
133681
 
133682
133682
  Conditions:
133683
- exists \u2014 the selector matches an element anywhere in the tree.
133684
- visible \u2014 the selector matches an element with a non-zero on-screen frame.
133685
- hidden \u2014 the selector matches nothing, or only a zero-area element (e.g. a spinner that disappeared).
133686
- text \u2014 the first VISIBLE match in reading order (topmost, then leftmost; falling back to the first match
133683
+ exists: the selector matches an element anywhere in the tree.
133684
+ visible: the selector matches an element with a non-zero on-screen frame.
133685
+ hidden: the selector matches nothing, or only a zero-area element (e.g. a spinner that disappeared).
133686
+ text: the first VISIBLE match in reading order (topmost, then leftmost; falling back to the first match
133687
133687
  overall if none is visible) contains expectedText (case-insensitive substring), or exactly matches
133688
133688
  it when textMatch is \`equals\`. A loose selector can match several elements; only that one is
133689
- inspected, so if a different match is the one holding the text the wait still reports failure \u2014
133689
+ inspected, so if a different match is the one holding the text the wait still reports failure;
133690
133690
  narrow the selector to target it.
133691
133691
 
133692
133692
  The selector is { text?, identifier?, role? }; every provided field must match. text and role match as
@@ -133697,10 +133697,10 @@ It polls the same accessibility / DOM tree as \`describe\`
133697
133697
  Vega automation toolkit) every pollIntervalMs
133698
133698
  (default ${DEFAULT_POLL_INTERVAL_MS}ms) until timeoutMs (default ${DEFAULT_TIMEOUT_MS3}ms).
133699
133699
 
133700
- Returns { success: boolean, elapsed: number, note?, cause? } \u2014 success=false means the wait ended without the
133701
- condition holding, which is not always a verdict on the condition: \`cause\` says which it was \u2014 \`unmet\` (the tree
133700
+ Returns { success: boolean, elapsed: number, note?, cause? }. success=false means the wait ended without the
133701
+ condition holding, which is not always a verdict on the condition: \`cause\` says which it was: \`unmet\` (the tree
133702
133702
  was read and the condition was false there), \`unreadable\` (no trustworthy read, so nothing was judged) or
133703
- \`cancelled\` \u2014 and \`note\` describes what was seen. Only \`unmet\` licenses rewriting the check. Use this after a
133703
+ \`cancelled\`. \`note\` describes what was seen. Only \`unmet\` licenses rewriting the check. Use this after a
133704
133704
  tap/navigation to wait for the next screen, or before tapping an element that appears asynchronously.`,
133705
133705
  alwaysLoad: true,
133706
133706
  searchHint: "wait await poll until visible hidden exists text appears disappears timeout element condition settle",
@@ -133796,12 +133796,12 @@ var ALLOWED_TOOLS = /* @__PURE__ */ new Set([
133796
133796
  ]);
133797
133797
  var zodSchema30 = external_exports.object({
133798
133798
  udid: external_exports.string().describe(
133799
- "Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, or Chromium id) \u2014 shared across all steps."
133799
+ "Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, or Chromium id), shared across all steps."
133800
133800
  ),
133801
133801
  steps: external_exports.array(
133802
133802
  external_exports.object({
133803
133803
  tool: external_exports.string().describe(
133804
- "Tool name \u2014 one of: gesture-tap, gesture-swipe, gesture-scroll, gesture-drag, gesture-custom, gesture-pinch, gesture-rotate, button, keyboard, paste, rotate, shake, fold, tv-remote, await-ui-element. On a TV target (Apple TV / Android TV / Vega) use tv-remote (remote presses) and keyboard (text)."
133804
+ "Tool name, one of: gesture-tap, gesture-swipe, gesture-scroll, gesture-drag, gesture-custom, gesture-pinch, gesture-rotate, button, keyboard, paste, rotate, shake, fold, tv-remote, await-ui-element. On a TV target (Apple TV / Android TV / Vega) use tv-remote (remote presses) and keyboard (text)."
133805
133805
  ),
133806
133806
  args: external_exports.record(external_exports.string(), external_exports.unknown()).describe("Tool arguments (excluding udid, which is injected automatically)"),
133807
133807
  delayMs: external_exports.number().optional().describe(
@@ -133834,7 +133834,7 @@ On a physical iOS device only gesture-tap, gesture-swipe, gesture-custom, button
133834
133834
  Use when you need sequential actions and do NOT need to observe the screen between them
133835
133835
  (e.g. scrolling multiple times, typing then pressing enter, rotating back and forth).
133836
133836
  Returns { completed, total, steps } with per-step results. Fails if an unrecognised tool name is used in a step (error returned at that step, execution stops).
133837
- One screenshot is captured automatically after the whole sequence (not per step) \u2014 call screenshot separately only for a baseline BEFORE it, or to observe an intermediate step.
133837
+ One screenshot is captured automatically after the whole sequence (not per step). Call screenshot separately only for a baseline BEFORE it, or to observe an intermediate step.
133838
133838
  That single capture is also why a secret belongs in this call rather than in two bare ones: the skip is decided from the whole request, so a \`{{secret:...}}\` in any step suppresses the capture that would otherwise follow the submit.
133839
133839
 
133840
133840
  ONLY use this when every step is known in advance. If any step depends on the
@@ -133852,41 +133852,41 @@ Allowed tools and their args (udid is auto-injected, do NOT include it in args):
133852
133852
  gesture-rotate: { centerX: number, centerY: number, radius?: number, radiusX?: number, radiusY?: number, startAngle: number, endAngle: number, durationMs?: number } [ios/android]
133853
133853
  button: { button: "home"|"back"|"power"|"volumeUp"|"volumeDown"|"appSwitch"|"actionButton" } [ios/android]
133854
133854
  keyboard: { text?: string, key?: string, delayMs?: number } (text OR key per step, never both; TV: text only) [ios/android/chromium/vega/tv]
133855
- text supports {{secret:<NAME>}} placeholders, resolved server-side from ARGENT_SECRET_<NAME> env vars or an argent secrets file \u2014 credentials never enter agent context
133856
- paste: { text: string } (device clipboard + paste shortcut; only where a user would paste, e.g. an OTP \u2014 keyboard otherwise) [ios sim/android emu]
133855
+ text supports {{secret:<NAME>}} placeholders, resolved server-side from ARGENT_SECRET_<NAME> env vars or an argent secrets file; credentials never enter agent context
133856
+ paste: { text: string } (device clipboard + paste shortcut; only where a user would paste, e.g. an OTP; keyboard otherwise) [ios sim/android emu]
133857
133857
  rotate: { orientation: "Portrait"|"LandscapeLeft"|"LandscapeRight"|"PortraitUpsideDown" } [ios/android]
133858
133858
  shake: { count?: number } [ios sim/android emu]
133859
133859
  fold: { posture?: "closed"|"half-open"|"open", angle?: 0-180 } (one of posture/angle; the next step lands on the new panel, whose coordinates are different) [foldable ios sim]
133860
133860
  tv-remote: { button: <remote button | array of them>, repeat?: number } [apple tv/android tv/vega]
133861
- buttons: up/down/left/right/select/back/home/menu/playPause (+ rewind/fastForward/next/previous/volumeUp/volumeDown/mute \u2014 work on Android TV and Vega; rejected on the Apple TV simulator)
133861
+ buttons: up/down/left/right/select/back/home/menu/playPause (+ rewind/fastForward/next/previous/volumeUp/volumeDown/mute work on Android TV and Vega; rejected on the Apple TV simulator)
133862
133862
  await-ui-element: { condition: "exists"|"visible"|"hidden"|"text", selector: {text?,identifier?,role?}, expectedText?, timeoutMs?, pollIntervalMs? } [ios/android/chromium]
133863
133863
 
133864
- Example \u2014 scroll down three times (use gesture-scroll with positive deltaY on Chromium):
133864
+ Example: scroll down three times (use gesture-scroll with positive deltaY on Chromium):
133865
133865
  { "udid": "<UDID>", "steps": [
133866
133866
  { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } },
133867
133867
  { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } },
133868
133868
  { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } }
133869
133869
  ]}
133870
133870
 
133871
- Example \u2014 type text and submit (two keyboard steps; one call cannot carry both):
133871
+ Example: type text and submit (two keyboard steps; one call cannot carry both):
133872
133872
  { "udid": "<UDID>", "steps": [
133873
133873
  { "tool": "keyboard", "args": { "text": "hello world" } },
133874
133874
  { "tool": "keyboard", "args": { "key": "enter" } }
133875
133875
  ]}
133876
133876
 
133877
- Example \u2014 TV: move focus right twice then activate (one tv-remote step with a path is cheaper):
133877
+ Example (TV): move focus right twice then activate (one tv-remote step with a path is cheaper):
133878
133878
  { "udid": "<TV-TARGET-ID>", "steps": [
133879
133879
  { "tool": "tv-remote", "args": { "button": ["right", "right", "select"] } }
133880
133880
  ]}
133881
133881
 
133882
- Example \u2014 tap, wait for the next screen's element, then tap it:
133882
+ Example: tap, wait for the next screen's element, then tap it:
133883
133883
  { "udid": "<UDID>", "steps": [
133884
133884
  { "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.9 } },
133885
133885
  { "tool": "await-ui-element", "args": { "condition": "visible", "selector": { "text": "Continue" } } },
133886
133886
  { "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.5 } }
133887
133887
  ]}
133888
133888
  If the await-ui-element condition is not met before its timeout, the sequence stops there and the
133889
- following steps do NOT run \u2014 so the tap above only fires once "Continue" is actually on screen.
133889
+ following steps do NOT run, so the tap above only fires once "Continue" is actually on screen.
133890
133890
 
133891
133891
  Stops on the first error (or unmet await-ui-element condition) and returns partial results.`,
133892
133892
  alwaysLoad: true,
@@ -133993,7 +133993,7 @@ function debuggerServiceRef(params) {
133993
133993
  var zodSchema31 = external_exports.object({
133994
133994
  port: metroPortField,
133995
133995
  device_id: external_exports.string().describe(
133996
- "Device id from list-devices: iOS simulator UDID, Android serial, Vega serial (amazon-...), or Chromium device id (chromium-cdp-<port>). Pass this SAME id as device_id to every subsequent debugger-* call to pin them to this device. The returned logicalDeviceId is informational (Metro's own per-connection handle, absent on Vega); you do not switch to it \u2014 forwarding it still resolves here, but the list-devices id is the stable one."
133996
+ "Device id from list-devices: iOS simulator UDID, Android serial, Vega serial (amazon-...), or Chromium device id (chromium-cdp-<port>). Pass this SAME id as device_id to every subsequent debugger-* call to pin them to this device. The returned logicalDeviceId is informational (Metro's own per-connection handle, absent on Vega); you do not switch to it. Forwarding it still resolves here, but the list-devices id is the stable one."
133997
133997
  )
133998
133998
  });
133999
133999
  var debuggerConnectTool = {
@@ -134004,7 +134004,7 @@ var debuggerConnectTool = {
134004
134004
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to connect JavaScript debugger: ${failureSignal2.error_code}`
134005
134005
  },
134006
134006
  description: `Connect to a JS runtime CDP debugger.
134007
- iOS / Android / Vega: connects to Metro's CDP endpoint on the given port. Chromium: re-uses the page CDP session opened by boot-device \u2014 port is ignored.
134007
+ iOS / Android / Vega: connects to Metro's CDP endpoint on the given port. Chromium: re-uses the page CDP session opened by boot-device; port is ignored.
134008
134008
  Returns connection info including port, projectRoot (empty on Chromium and on legacy Metro, e.g. Vega), deviceName, appName, logicalDeviceId (absent on Vega), and isNewDebugger, plus a note naming the kept log file when the previous session ended because the app crashed. If already connected, returns the existing connection.
134009
134009
  Use when starting a debug session or before calling other debugger-* tools. Fails if the runtime is unreachable (Metro down, or Chromium CDP terminated).`,
134010
134010
  zodSchema: zodSchema31,
@@ -134116,7 +134116,7 @@ function isDebuggerNotConnectedResult(toolId, result) {
134116
134116
  var zodSchema32 = external_exports.object({
134117
134117
  port: metroPortField,
134118
134118
  device_id: external_exports.string().describe(
134119
- "Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
134119
+ "Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
134120
134120
  )
134121
134121
  });
134122
134122
  function createDebuggerStatusTool(registry2) {
@@ -134128,9 +134128,9 @@ function createDebuggerStatusTool(registry2) {
134128
134128
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to check JavaScript debugger: ${failureSignal2.error_code}`
134129
134129
  },
134130
134130
  description: `Get JS runtime debugger connection status and diagnostic info.
134131
- Use when you need to verify connectivity before using other debugger tools. Never fails when the runtime is simply unreachable \u2014 it returns a discriminated result instead:
134132
- - { status: "connected", ... } with port, projectRoot (empty on Chromium and on legacy Metro, e.g. Vega), deviceName, appName, logicalDeviceId (absent on Vega), isNewDebugger (false on the legacy inspector), connected flag, loadedScripts count, and sourceMapReady (always true \u2014 waits for pending source maps before returning; no-op on Chromium).
134133
- - { status: "not_connected", connected: false, reason, detail, guidance } (port omitted on Chromium) when Metro is not running (reason "metro_not_running"), no app is attached ("no_app_connected"), the device_id matches no target ("device_mismatch"), the CDP endpoint is unreachable or answered malformed ("cdp_unreachable"), the runtime accepted the connection but never answered ("runtime_unresponsive"), the cached connection went stale ("stale_connection"), or a reconnect is in flight ("reconnecting"). Follow the guidance field \u2014 do not retry in a loop.`,
134131
+ Use when you need to verify connectivity before using other debugger tools. Never fails when the runtime is simply unreachable: it returns a discriminated result instead:
134132
+ - { status: "connected", ... } with port, projectRoot (empty on Chromium and on legacy Metro, e.g. Vega), deviceName, appName, logicalDeviceId (absent on Vega), isNewDebugger (false on the legacy inspector), connected flag, loadedScripts count, and sourceMapReady (always true: waits for pending source maps before returning; no-op on Chromium).
134133
+ - { status: "not_connected", connected: false, reason, detail, guidance } (port omitted on Chromium) when Metro is not running (reason "metro_not_running"), no app is attached ("no_app_connected"), the device_id matches no target ("device_mismatch"), the CDP endpoint is unreachable or answered malformed ("cdp_unreachable"), the runtime accepted the connection but never answered ("runtime_unresponsive"), the cached connection went stale ("stale_connection"), or a reconnect is in flight ("reconnecting"). Follow the guidance field; do not retry in a loop.`,
134134
134134
  zodSchema: zodSchema32,
134135
134135
  capability: DEBUGGER_TOOL_CAPABILITY,
134136
134136
  // Resolved manually in execute so a not-connected precondition becomes a
@@ -134191,7 +134191,7 @@ init_src2();
134191
134191
  var zodSchema33 = external_exports.object({
134192
134192
  port: metroPortField,
134193
134193
  device_id: external_exports.string().describe(
134194
- "Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
134194
+ "Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
134195
134195
  ),
134196
134196
  expression: external_exports.string().describe("JavaScript expression to evaluate in the app runtime")
134197
134197
  });
@@ -134202,8 +134202,8 @@ var debuggerEvaluateTool = {
134202
134202
  completedMsg: () => "Ran JavaScript in the app",
134203
134203
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to run JavaScript in the app: ${failureSignal2.error_code}`
134204
134204
  },
134205
- description: `Execute arbitrary JavaScript in the app's JS runtime via CDP \u2014 Hermes on iOS / Android / Vega, V8 on Chromium.
134206
- Returns the evaluation result as a JSON-serializable value, along with deviceName, appName, and logicalDeviceId for context. Use when you need to read app state, call app functions, or test logic at runtime. The result is serialized by value, so cyclic objects (many RN runtime values \u2014 fiber nodes, navigation refs, global \u2014 are cyclic) fail with a serialization error rather than returning silently. Fails if the expression throws or the runtime is not connected.`,
134205
+ description: `Execute arbitrary JavaScript in the app's JS runtime via CDP: Hermes on iOS / Android / Vega, V8 on Chromium.
134206
+ Returns the evaluation result as a JSON-serializable value, along with deviceName, appName, and logicalDeviceId for context. Use when you need to read app state, call app functions, or test logic at runtime. The result is serialized by value, so cyclic objects (many RN runtime values, such as fiber nodes, navigation refs and global, are cyclic) fail with a serialization error rather than returning silently. Fails if the expression throws or the runtime is not connected.`,
134207
134207
  zodSchema: zodSchema33,
134208
134208
  capability: DEBUGGER_TOOL_CAPABILITY,
134209
134209
  services: (params) => ({
@@ -134244,7 +134244,7 @@ init_src2();
134244
134244
  var zodSchema34 = external_exports.object({
134245
134245
  port: metroPortField,
134246
134246
  device_id: external_exports.string().describe(
134247
- "Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
134247
+ "Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
134248
134248
  )
134249
134249
  });
134250
134250
  var debuggerReloadMetroTool = {
@@ -135196,7 +135196,7 @@ async function readTapAxes(registry2, app) {
135196
135196
  var zodSchema35 = external_exports.object({
135197
135197
  port: metroPortField,
135198
135198
  device_id: external_exports.string().describe(
135199
- "Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
135199
+ "Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
135200
135200
  ),
135201
135201
  udid: external_exports.string().optional().describe(
135202
135202
  "iOS simulator UDID from list-devices. Pass it when device_id is a logicalDeviceId (two or more devices share one Metro), so that the tap coordinates of a landscape UI are on the screen's axes. Give the UDID of the simulator that shows the app."
@@ -135220,11 +135220,11 @@ function createDebuggerComponentTreeTool(registry2) {
135220
135220
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to read React component tree: ${failureSignal2.error_code}`
135221
135221
  },
135222
135222
  description: `Fetch the current screen of a running React Native app as a compact component text tree.
135223
- Only shows on-screen components with unique positions \u2014 off-screen (scrolled) content,
135223
+ Only shows on-screen components with unique positions. Off-screen (scrolled) content,
135224
135224
  full-screen transparent wrappers, and implementation-detail components are pruned.
135225
135225
 
135226
135226
  Each visible component is listed with its name, text content, and normalized
135227
- tap coordinates in [0,1] space (fractions of the screen, not pixels \u2014 same space as tap/swipe/gesture).
135227
+ tap coordinates in [0,1] space (fractions of the screen, not pixels; same space as tap/swipe/gesture).
135228
135228
  On an iOS simulator with a landscape UI (a rotated device, or an unfolded foldable), the tap
135229
135229
  coordinates are on the screen's axes, which the gesture tools use. When two or more devices share
135230
135230
  one Metro, pass the simulator's udid too. If the result says that the orientation could not be
@@ -135723,7 +135723,7 @@ function filterInspectItems(items, includeSkipped = false) {
135723
135723
  var zodSchema36 = external_exports.object({
135724
135724
  port: metroPortField,
135725
135725
  device_id: external_exports.string().describe(
135726
- "Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
135726
+ "Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
135727
135727
  ),
135728
135728
  x: external_exports.coerce.number().describe("Logical X coordinate on device screen"),
135729
135729
  y: external_exports.coerce.number().describe("Logical Y coordinate on device screen"),
@@ -135732,7 +135732,7 @@ var zodSchema36 = external_exports.object({
135732
135732
  "When true, resolves bundled frame locations to original source files via Metro symbolication and includes a code fragment. When false, returns the raw bundled frame info (file, line, column) without symbolication or source reading."
135733
135733
  ),
135734
135734
  maxItems: external_exports.coerce.number().default(35).describe(
135735
- "Maximum number of hierarchy items to return, counted from the bottom (most specific component first). The hierarchy walks from the tapped element up to the root \u2014 the first items are the most relevant for editing. Increase to 70+ if you need to understand the broader navigation/screen structure."
135735
+ "Maximum number of hierarchy items to return, counted from the bottom (most specific component first). The hierarchy walks from the tapped element up to the root, so the first items are the most relevant for editing. Increase to 70+ if you need to understand the broader navigation/screen structure."
135736
135736
  ),
135737
135737
  includeSkipped: external_exports.boolean().default(false).describe(
135738
135738
  "When true, items that would normally be filtered are kept in the response with skipped=true and a skipReason. Useful for understanding what was pruned."
@@ -135749,7 +135749,7 @@ var debuggerInspectElementTool = {
135749
135749
  Returns components from the tapped element upward through its parent hierarchy,
135750
135750
  each with its source file:line and a code fragment.
135751
135751
 
135752
- The first items (lowest indices) are the most specific \u2014 the exact component under
135752
+ The first items (lowest indices) are the most specific: the exact component under
135753
135753
  the tap point and its direct parents. Higher indices are broader context (page, navigator).
135754
135754
  Default shows 35 items which covers all app-specific code; use maxItems=70+ to also
135755
135755
  see the navigation/screen structure.
@@ -135860,7 +135860,7 @@ init_zod();
135860
135860
  var zodSchema37 = external_exports.object({
135861
135861
  port: metroPortField,
135862
135862
  device_id: external_exports.string().describe(
135863
- "Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
135863
+ "Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
135864
135864
  )
135865
135865
  });
135866
135866
  function createDebuggerLogRegistryTool(registry2) {
@@ -135873,8 +135873,8 @@ function createDebuggerLogRegistryTool(registry2) {
135873
135873
  },
135874
135874
  description: `Get a summary of all console logs captured from the app's JS runtime.
135875
135875
  Returns the log file path, entry counts by level, and message clusters (grouped by similarity). Works against Hermes (iOS / Android / Vega) and V8 (Chromium).
135876
- Use when investigating warnings, errors, or unexpected output \u2014 call this first for an overview, then read the returned file for details. Returns empty stats if no log data has been captured yet \u2014 but check { note }, which is present only when the stats are empty BECAUSE the previous debugger session ended: torn down (e.g. by stop-all-simulator-servers) with its log file deleted, or cut off by the app crashing with its log file kept at the path the note names. Absent that note, empty really does mean the app has logged nothing.
135877
- When the debugger cannot be reached, this tool does not fail: it returns { status: "not_connected", reason, detail, guidance } with NO log file \u2014 follow the guidance (do not retry in a loop). Read a log file in this state only when a { note } names one kept from before the app crashed. A "connected" result's stats may come from a session whose socket has since died \u2014 use debugger-status, not this tool, to judge debugger health.`,
135876
+ Use when investigating warnings, errors, or unexpected output. Call this first for an overview, then read the returned file for details. Returns empty stats if no log data has been captured yet, but check { note }, which is present only when the stats are empty BECAUSE the previous debugger session ended: torn down (e.g. by stop-all-simulator-servers) with its log file deleted, or cut off by the app crashing with its log file kept at the path the note names. Absent that note, empty really does mean the app has logged nothing.
135877
+ When the debugger cannot be reached, this tool does not fail: it returns { status: "not_connected", reason, detail, guidance } with NO log file. Follow the guidance (do not retry in a loop). Read a log file in this state only when a { note } names one kept from before the app crashed. A "connected" result's stats may come from a session whose socket has since died. Use debugger-status, not this tool, to judge debugger health.`,
135878
135878
  zodSchema: zodSchema37,
135879
135879
  capability: DEBUGGER_TOOL_CAPABILITY,
135880
135880
  // Resolved manually in execute so a not-connected precondition becomes a
@@ -135986,7 +135986,7 @@ ${lines.join("\n")}`;
135986
135986
  var zodSchema38 = external_exports.object({
135987
135987
  port: metroPortField,
135988
135988
  device_id: external_exports.string().describe(
135989
- "Device id from list-devices (iOS simulator UDID or Android serial) \u2014 the same id used with debugger-connect."
135989
+ "Device id from list-devices (iOS simulator UDID or Android serial), the same id used with debugger-connect."
135990
135990
  ),
135991
135991
  pageIndex: external_exports.union([external_exports.coerce.number().int().nonnegative(), external_exports.literal("latest")]).default("latest").describe(
135992
135992
  'Page index (0-based) or "latest" for the most recent page. Each page contains up to 50 entries.'
@@ -136002,7 +136002,7 @@ var networkLogsTool = {
136002
136002
  description: `Retrieve captured network (HTTP) requests from the running app.
136003
136003
  Returns a paginated list of requests with method, URL, status, resource type, size, and duration.
136004
136004
  Each entry includes a requestId that can be passed to view-network-request-details for full details.
136005
- On React Native (iOS / Android / Vega) interception is injected into the JS runtime \u2014 it captures fetch() calls. On Chromium it reads the browser's native CDP Network domain (the active tab; all request types).
136005
+ On React Native (iOS / Android / Vega) interception is injected into the JS runtime: it captures fetch() calls. On Chromium it reads the browser's native CDP Network domain (the active tab; all request types).
136006
136006
  Use when inspecting outbound HTTP traffic or debugging API calls in the running app.
136007
136007
  Fails if the app is not connected (RN) or the device is not reachable (Chromium).`,
136008
136008
  zodSchema: zodSchema38,
@@ -136080,7 +136080,7 @@ var MAX_BODY_SIZE = 1e3;
136080
136080
  var zodSchema39 = external_exports.object({
136081
136081
  port: metroPortField,
136082
136082
  device_id: external_exports.string().describe(
136083
- "Device id from list-devices (iOS simulator UDID or Android serial) \u2014 the same id used with debugger-connect."
136083
+ "Device id from list-devices (iOS simulator UDID or Android serial), the same id used with debugger-connect."
136084
136084
  ),
136085
136085
  requestId: external_exports.string().describe("The requestId from view-network-logs to get full details for"),
136086
136086
  includeBody: external_exports.coerce.boolean().default(true).describe("Whether to include the response body (if captured). Defaults to true.")
@@ -136095,7 +136095,7 @@ var networkRequestTool = {
136095
136095
  description: `Get full details of a specific network request by its requestId (from view-network-logs).
136096
136096
  Returns request/response headers (sensitive headers redacted), status, timing, and optionally the response body.
136097
136097
  Large response bodies are truncated. Use when you need headers, body, or timing for a specific request after listing logs.
136098
- Returns an error message string if the requestId is not found \u2014 use view-network-logs to get valid requestId values.`,
136098
+ Returns an error message string if the requestId is not found; use view-network-logs to get valid requestId values.`,
136099
136099
  zodSchema: zodSchema39,
136100
136100
  capability: DEBUGGER_TOOL_CAPABILITY,
136101
136101
  services: (params) => {
@@ -136484,10 +136484,10 @@ function createDescribeTool(registry2) {
136484
136484
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to read screen: ${failureSignal2.error_code}`
136485
136485
  },
136486
136486
  description: `Get the accessibility / DOM element tree for the current screen.
136487
- On iOS, uses the AXRuntime accessibility service to inspect whatever is currently visible \u2014 including
136487
+ On iOS, uses the AXRuntime accessibility service to inspect whatever is currently visible, including
136488
136488
  system dialogs, permission prompts, and any foreground app content. On a physical iOS device the tree
136489
136489
  covers only the app registered by launch-app. On Android, runs \`uiautomator dump\`.
136490
- On Chromium, walks the renderer's DOM via Chrome DevTools Protocol \u2014 every visible element with its ARIA
136490
+ On Chromium, walks the renderer's DOM via Chrome DevTools Protocol: every visible element with its ARIA
136491
136491
  role, accessible name, and bounding rect (normalized to 0\u20131).
136492
136492
  On Vega (Fire TV), reads the on-device automation toolkit (\`getPageSource\`); each element carries
136493
136493
  \`[focused]\`/\`[selected]\` so you can see where the D-pad cursor is, then move it with the \`tv-remote\` tool
@@ -136498,9 +136498,9 @@ When a system dialog is visible, describe returns the dialog's interactive eleme
136498
136498
  with tap coordinates. When no dialog is present, it returns the foreground app's accessible elements.
136499
136499
  On a physical iOS device, launch-app \`com.apple.springboard\` first to read system dialogs.
136500
136500
 
136501
- Returns \`{ description, source }\` where \`description\` is a text rendering of the UI tree \u2014 one
136501
+ Returns \`{ description, source }\` where \`description\` is a text rendering of the UI tree, one
136502
136502
  line per element with its role, label/value/id, interactivity flags, and frame. Frame coordinates
136503
- are normalized [0,1] fractions of the screen / window width/height (not pixels) \u2014 the same space as
136503
+ are normalized [0,1] fractions of the screen / window width/height (not pixels), the same space as
136504
136504
  gesture-tap / gesture-swipe / gesture-pinch.
136505
136505
 
136506
136506
  To tap an element use the centre of its frame: \`tap_x = frame.x + frame.width / 2\`,
@@ -136513,7 +136513,7 @@ For app-scoped inspection with full UIKit properties (accessibilityIdentifier, v
136513
136513
  use native-describe-screen with an explicit bundleId instead (iOS simulator only).
136514
136514
  For React Native apps, debugger-component-tree returns React component names with tap coordinates.
136515
136515
 
136516
- On a TV target (Apple TV / Android TV \u2014 a \`list-devices\` entry with runtimeKind 'tv') this returns
136516
+ On a TV target (Apple TV / Android TV: a \`list-devices\` entry with runtimeKind 'tv') this returns
136517
136517
  the focus-driven view instead: the currently FOCUSED element and the list of FOCUSABLE elements,
136518
136518
  since a TV UI has no tap coordinates. Move the highlight with \`tv-remote\` (up/down/left/right/select/
136519
136519
  back/menu/home), then call describe again to confirm where focus landed.`,
@@ -137175,7 +137175,7 @@ function createAwaitScreenIdleTool(registry2) {
137175
137175
 
137176
137176
  Polls the same accessibility / DOM tree as \`describe\` every pollIntervalMs (default ${DEFAULT_POLL_INTERVAL_MS2}ms) until it
137177
137177
  has content and that content holds identical for minStableMs (default ${DEFAULT_MIN_STABLE_MS}ms), or timeoutMs (default
137178
- ${DEFAULT_TIMEOUT_MS4}ms) is reached. Returns { settled, waitedMs, polls } \u2014 settled=false means the screen never went
137178
+ ${DEFAULT_TIMEOUT_MS4}ms) is reached. Returns { settled, waitedMs, polls }; settled=false means the screen never went
137179
137179
  still before the timeout. Use after a launch/navigation to wait for the UI to render before screenshotting or tapping.`,
137180
137180
  searchHint: "wait until screen settles idle stable stops changing animation transition rendered ready before screenshot",
137181
137181
  longRunning: true,
@@ -137280,7 +137280,7 @@ var NO_RENDERERS_ATTACHED_ERROR = "React DevTools hook is present but no React r
137280
137280
  var zodSchema44 = external_exports.object({
137281
137281
  port: metroPortField,
137282
137282
  device_id: external_exports.string().describe(
137283
- "Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
137283
+ "Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
137284
137284
  ),
137285
137285
  sample_interval_us: external_exports.coerce.number().int().positive().default(100).describe("CPU sampling interval in microseconds (default 100)"),
137286
137286
  force: external_exports.boolean().default(false).describe(
@@ -137305,7 +137305,7 @@ function createReactProfilerStartTool(registry2) {
137305
137305
  description: `Start CPU profiling + React commit capture on the connected Hermes runtime.
137306
137306
  Delegates React commit capture to the in-app React DevTools backend (ri.startProfiling).
137307
137307
  If another tool-server already owns the session, returns { already_running: true, owner, stale, how_to_reclaim } without clobbering their data. Pass { force: true } to reclaim a fresh owner's session, but BEFORE OVERTAKING - ask the user for approval first, see relevant skill for guidance.
137308
- Before calling this, ask the user if they also want native profiling (native-profiler-start) \u2014 recommend running both in parallel for a complete picture.
137308
+ Before calling this, ask the user if they also want native profiling (native-profiler-start), and recommend running both in parallel for a complete picture.
137309
137309
  After starting, ask the user to perform the interaction to profile, then call react-profiler-stop.
137310
137310
  Returns { started_at, startedAtEpochMs, hermes_version, detected_architecture } on success, or the already_running payload described above.
137311
137311
  Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot be established.`,
@@ -137583,7 +137583,7 @@ async function readCommitTree(path53) {
137583
137583
  var zodSchema45 = external_exports.object({
137584
137584
  port: metroPortField,
137585
137585
  device_id: external_exports.string().describe(
137586
- "Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
137586
+ "Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
137587
137587
  )
137588
137588
  });
137589
137589
  function normalizeChangeDescription(raw) {
@@ -137667,7 +137667,7 @@ Reads commit data from the in-app React DevTools backend.
137667
137667
  Stores results in the ReactProfilerSession for later use by react-profiler-analyze or react-profiler-cpu-summary.
137668
137668
  Call react-profiler-start first, then exercise the app, then call this.
137669
137669
  Returns { duration_ms, sample_count, fiber_renders_captured, total_react_commits, hot_commit_indices } summarizing the session.
137670
- When any commit had fibers whose display name could not be resolved at stop time (typically transient components like modals/tooltips/animations that unmounted before stop), the response also includes { unattributed_ms, unattributed_fiber_count, unattributed_commit_count } \u2014 these quantify how much work is not accounted for in the per-component breakdown (the per-commit duration itself remains correct).
137670
+ When any commit had fibers whose display name could not be resolved at stop time (typically transient components like modals/tooltips/animations that unmounted before stop), the response also includes { unattributed_ms, unattributed_fiber_count, unattributed_commit_count }. These quantify how much work is not accounted for in the per-component breakdown (the per-commit duration itself remains correct).
137671
137671
  Fails if no active profiling session exists or the CDP connection was lost during recording.`,
137672
137672
  zodSchema: zodSchema45,
137673
137673
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -137908,7 +137908,7 @@ function createReactProfilerStatusTool(registry2) {
137908
137908
  completedMsg: ({ result }) => result.is_running ? "React profiler is running" : "React profiler is stopped",
137909
137909
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to check React profiler: ${failureSignal2.error_code}`
137910
137910
  },
137911
- description: `Check the state of the React profiler session without side effects. Use after an interruption (debugger disconnect, unexpected error, agent pause) to decide whether to continue with react-profiler-stop, start a new session, or reconnect the debugger. Ownership is verified server-side against this tool-server's in-memory session \u2014 no token-threading is required. Returns { session_status, is_running, current_owner, \u2026 }. If this tool-server process restarted after react-profiler-start, status will report 'taken_over'; use react-profiler-start { force: true } to reclaim.`,
137911
+ description: `Check the state of the React profiler session without side effects. Use after an interruption (debugger disconnect, unexpected error, agent pause) to decide whether to continue with react-profiler-stop, start a new session, or reconnect the debugger. Ownership is verified server-side against this tool-server's in-memory session, so no token-threading is required. Returns { session_status, is_running, current_owner, \u2026 }. If this tool-server process restarted after react-profiler-start, status will report 'taken_over'; use react-profiler-start { force: true } to reclaim.`,
137912
137912
  zodSchema: zodSchema46,
137913
137913
  // RN-only: companion to react-profiler-start.
137914
137914
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -139710,7 +139710,7 @@ var reactProfilerComponentSourceTool = {
139710
139710
  description: `Find a React component's source via tree-sitter AST lookup: returns file path, line number, memoization status (isMemoized, hasUseCallback, hasUseMemo), and 50 lines of source for a named React component.
139711
139711
  Call this per-finding after react-profiler-analyze to inspect source before proposing a fix.
139712
139712
  Returns found: false if the component is not found in user-owned code (e.g. lives in node_modules).
139713
- When several files define a component with the same name (e.g. platform variants like List.tsx and List.web.tsx), returns the primary match and lists the rest under otherMatches[] (file/line/col) \u2014 check it before assuming the returned file is the one you meant.`,
139713
+ When several files define a component with the same name (e.g. platform variants like List.tsx and List.web.tsx), returns the primary match and lists the rest under otherMatches[] (file/line/col). Check it before assuming the returned file is the one you meant.`,
139714
139714
  zodSchema: zodSchema48,
139715
139715
  // Declared so the tool catalogue groups this with the other react-profiler-*
139716
139716
  // tools; the HTTP gate itself is a no-op here, as there is no device arg to
@@ -139843,7 +139843,7 @@ var reactProfilerCpuSummaryTool = {
139843
139843
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to summarize React CPU profile: ${failureSignal2.error_code}`
139844
139844
  },
139845
139845
  description: `Return a raw Hermes CPU flamegraph summary (top hotspot functions by self-time).
139846
- FOR DEDICATED CPU INVESTIGATION ONLY \u2014 do NOT call this as part of a normal profiling session.
139846
+ FOR DEDICATED CPU INVESTIGATION ONLY: do NOT call this as part of a normal profiling session.
139847
139847
  Use react-profiler-analyze instead; it covers all React rendering performance analysis.
139848
139848
  Use when you specifically need to investigate JS CPU hotspots that are NOT tied to React rendering (e.g. regex slowness, cryptography, heavy computations).
139849
139849
  Call react-profiler-stop first. Reads directly from the stored cpuProfile.
@@ -139960,7 +139960,7 @@ var reactProfilerRendersTool = {
139960
139960
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to read React render activity: ${failureSignal2.error_code}`
139961
139961
  },
139962
139962
  description: `Scan the live React fiber tree to collect component render counts and durations.
139963
- Returns a markdown table of the top re-rendering components. No profiling session required \u2014 works on a live connected app.
139963
+ Returns a markdown table of the top re-rendering components. No profiling session required; works on a live connected app.
139964
139964
  Use when you want a quick snapshot of render counts without a full profiling session.
139965
139965
  Fails if the React DevTools hook is not present in the runtime or the app is not connected.`,
139966
139966
  zodSchema: zodSchema50,
@@ -143948,7 +143948,7 @@ var zodSchema52 = external_exports.object({
143948
143948
  "iOS-only: path to an Instruments .tracetemplate file (defaults to bundled Argent template). Ignored on Android."
143949
143949
  ),
143950
143950
  malloc_stack_logging: external_exports.boolean().optional().describe(
143951
- "iOS-only. When true, cold-launches the app under the profiler with Malloc Stack Logging enabled so memory leaks carry an allocation backtrace (responsible frame + library). Without it, leaks are still detected but unattributable \u2014 Instruments reports '<Call stack limit reached>'. Trade-offs: this RESTARTS the app (current state is lost), adds memory/CPU overhead, and makes the app noticeably slow to launch (every startup allocation records a backtrace), so leave it off for pure CPU/hang profiling. Requires a non-degraded Xcode: on Xcode 26.4 and later the cold-launch path is broken, so the call is rejected up front (re-run without the flag, or set ARGENT_IOS_CAPTURE=device to override if the device path works on your host). ARGENT_IOS_CAPTURE=all-processes \u2014 e.g. exported globally for the normal capture path \u2014 also rejects this flag up front, since that fallback cannot cold-launch; unset it (or set it to device) first. Ignored on Android."
143951
+ "iOS-only. When true, cold-launches the app under the profiler with Malloc Stack Logging enabled so memory leaks carry an allocation backtrace (responsible frame + library). Without it, leaks are still detected but unattributable: Instruments reports '<Call stack limit reached>'. Trade-offs: this RESTARTS the app (current state is lost), adds memory/CPU overhead, and makes the app noticeably slow to launch (every startup allocation records a backtrace), so leave it off for pure CPU/hang profiling. Requires a non-degraded Xcode: on Xcode 26.4 and later the cold-launch path is broken, so the call is rejected up front (re-run without the flag, or set ARGENT_IOS_CAPTURE=device to override if the device path works on your host). ARGENT_IOS_CAPTURE=all-processes (e.g. exported globally for the normal capture path) also rejects this flag up front, since that fallback cannot cold-launch; unset it (or set it to device) first. Ignored on Android."
143952
143952
  )
143953
143953
  });
143954
143954
  var capability29 = {
@@ -145194,9 +145194,9 @@ function createScreenRecordingStartTool(registry2) {
145194
145194
  description: `Start recording the device screen to a video file (h264 mp4, 30fps at the device's native resolution).
145195
145195
  By default stretches where the screen does not change are trimmed out (see trimStatic), so a long session with only brief activity comes back as a short clip instead of minutes of dead air.
145196
145196
  By default every tap, swipe, drag, pinch and rotate is drawn into the video as an on-screen touch marker (see showTouches), so the recording shows where each interaction landed.
145197
- The recording keeps running across other tool calls (every result carries a reminder) until \`screen-recording-stop\` is called or timeLimitSeconds elapses \u2014 immediately after starting, set yourself a reminder/wakeup for the expected end of the recording so it is never left running.
145198
- Use when the user wants a video of an interaction, animation, or app behavior \u2014 for a single still frame use \`screenshot\` instead.
145199
- Returns { status: "recording", timeLimitSeconds, outputFile } \u2014 the video is retrieved later by \`screen-recording-stop\`, not by reading outputFile directly.
145197
+ The recording keeps running across other tool calls (every result carries a reminder) until \`screen-recording-stop\` is called or timeLimitSeconds elapses. Immediately after starting, set yourself a reminder/wakeup for the expected end of the recording so it is never left running.
145198
+ Use when the user wants a video of an interaction, animation, or app behavior; for a single still frame use \`screenshot\` instead.
145199
+ Returns { status: "recording", timeLimitSeconds, outputFile }. The video is retrieved later by \`screen-recording-stop\`, not by reading outputFile directly.
145200
145200
  Fails if a recording is already running on the device, the device is not booted, ffmpeg is not installed, or the platform cannot be recorded (tvOS, Chromium, Vega and remote simulators are unsupported).`,
145201
145201
  searchHint: "record video screen capture movie mp4 start filming screencast",
145202
145202
  zodSchema: zodSchema55,
@@ -145315,7 +145315,7 @@ var screenRecordingStopTool = {
145315
145315
  },
145316
145316
  capability: capability33,
145317
145317
  description: `Stop the screen recording started by \`screen-recording-start\` and retrieve the video: frame capture ends and ffmpeg finalizes the mp4.
145318
- Also retrieves the video when the recording already ended on its own (time limit reached, capture process died) \u2014 call it even after the cap fired.
145318
+ Also retrieves the video when the recording already ended on its own (time limit reached, capture process died); call it even after the cap fired.
145319
145319
  Use when the interaction being captured is finished, or a tool-result note reminds you a recording is still running.
145320
145320
  Returns { video, durationMs, wallClockMs?, trimmedMs?, panelSwitches?, warning? }; video is a downloadable artifact materialized to a local path. When static-frame trimming removed dead air, durationMs is the trimmed video length and wallClockMs/trimmedMs report the real duration and how much was cut. On a foldable simulator, the recording follows the panel that shows the UI. panelSwitches gives the number of panel changes. The video keeps the size of the first panel. warning is set when argent could not find that panel during the recording.
145321
145321
  Fails if no recording (running or finished-but-unretrieved) exists for the given udid.`,
@@ -145353,10 +145353,10 @@ init_src2();
145353
145353
  var import_fs18 = require("fs");
145354
145354
  var timeWindowSchema = external_exports.object({
145355
145355
  start: external_exports.coerce.number().describe(
145356
- "Start of window in ms since profiling started \u2014 the same clock profiler-commit-query prints"
145356
+ "Start of window in ms since profiling started, the same clock profiler-commit-query prints"
145357
145357
  ),
145358
145358
  end: external_exports.coerce.number().describe(
145359
- "End of window in ms since profiling started \u2014 the same clock profiler-commit-query prints"
145359
+ "End of window in ms since profiling started, the same clock profiler-commit-query prints"
145360
145360
  )
145361
145361
  });
145362
145362
  var zodSchema57 = external_exports.object({
@@ -145368,7 +145368,7 @@ var zodSchema57 = external_exports.object({
145368
145368
  "Query mode: top_functions (global hotspots), time_window (CPU in a time range), call_tree (callers/callees of a function), component_cpu (CPU during a component's commits)"
145369
145369
  ),
145370
145370
  time_window_ms: timeWindowSchema.optional().describe(
145371
- "Time window filter for time_window mode (ms since profiling started \u2014 the same clock profiler-commit-query prints)"
145371
+ "Time window filter for time_window mode (ms since profiling started, the same clock profiler-commit-query prints)"
145372
145372
  ),
145373
145373
  component_name: external_exports.string().optional().describe("Component name for component_cpu mode"),
145374
145374
  function_name: external_exports.string().optional().describe("Function name for call_tree mode"),
@@ -145647,7 +145647,7 @@ Every table states how many samples it covers and how much of that was idle.
145647
145647
  - component_cpu: For a given component_name, aggregate CPU activity across all its commits.
145648
145648
  Use when investigating JS CPU hotspots or correlating CPU cost with specific components.
145649
145649
  Returns a markdown table of CPU hotspots, call tree, or per-component CPU breakdown.
145650
- Fails if no CPU profile is stored \u2014 run react-profiler-stop first.`,
145650
+ Fails if no CPU profile is stored; run react-profiler-stop first.`,
145651
145651
  zodSchema: zodSchema57,
145652
145652
  // RN-only: reads Hermes-format CPU profiles; Chromium's V8 sample format differs.
145653
145653
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -145728,10 +145728,10 @@ init_zod();
145728
145728
  init_src2();
145729
145729
  var timeRangeSchema = external_exports.object({
145730
145730
  start: external_exports.coerce.number().describe(
145731
- "Start of range in ms since profiling started \u2014 the same clock profiler-commit-query prints"
145731
+ "Start of range in ms since profiling started, the same clock profiler-commit-query prints"
145732
145732
  ),
145733
145733
  end: external_exports.coerce.number().describe(
145734
- "End of range in ms since profiling started \u2014 the same clock profiler-commit-query prints"
145734
+ "End of range in ms since profiling started, the same clock profiler-commit-query prints"
145735
145735
  )
145736
145736
  });
145737
145737
  var zodSchema58 = external_exports.object({
@@ -145746,7 +145746,7 @@ var zodSchema58 = external_exports.object({
145746
145746
  time_range_ms: timeRangeSchema.optional().describe("Time range filter for by_time_range mode"),
145747
145747
  commit_index: external_exports.coerce.number().int().optional().describe("Commit index for by_index and cascade_tree modes"),
145748
145748
  top_n: external_exports.coerce.number().int().positive().optional().describe(
145749
- "Max results to return. Defaults to 20 for by_component / by_time_range, which count commits. by_index counts individual fibers and returns all of them unless this is set, because one commit's fibers collapse to far fewer distinct components \u2014 a small cap there can show less than the analyze report it is meant to expand on."
145749
+ "Max results to return. Defaults to 20 for by_component / by_time_range, which count commits. by_index counts individual fibers and returns all of them unless this is set, because one commit's fibers collapse to far fewer distinct components, and a small cap there can show less than the analyze report it is meant to expand on."
145750
145750
  )
145751
145751
  });
145752
145752
  async function getCommitTree(port, deviceId) {
@@ -147344,7 +147344,7 @@ init_src2();
147344
147344
  init_external_devices();
147345
147345
  var zodSchema63 = external_exports.object({
147346
147346
  devices: external_exports.array(external_exports.string()).optional().describe(
147347
- "Device ids (iOS UDID / Android serial / Chromium id) to scope the teardown to \u2014 pass the devices THIS session actually used. Omit only for a deliberate machine-wide cleanup: one tool-server serves every agent using this argent install, so an unscoped stop also kills devices another agent is mid-session on."
147347
+ "Device ids (iOS UDID / Android serial / Chromium id) to scope the teardown to. Pass the devices THIS session actually used. Omit only for a deliberate machine-wide cleanup: one tool-server serves every agent using this argent install, so an unscoped stop also kills devices another agent is mid-session on."
147348
147348
  )
147349
147349
  }).strict();
147350
147350
  function createStopAllSimulatorServersTool(registry2) {
@@ -147378,9 +147378,9 @@ function createStopAllSimulatorServersTool(registry2) {
147378
147378
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop simulator servers: ${failureSignal2.error_code}`
147379
147379
  },
147380
147380
  description: `Stop the services a device owns - simulator-server processes (iOS + Android), native devtools, the iOS accessibility service, TV-control daemons, Chromium CDP sessions, screen recordings, native profiler sessions, and JS-runtime debugger sessions along with the network inspectors and React profiler sessions that ride on them - freeing their spawned processes, sockets and ports. Call this when your session ends or the user says they are done.
147381
- PASS \`devices\` with the device ids this session used \u2014 one tool-server serves every agent, subagent and CLI call using this argent install, and an unscoped call tears down THEIR devices too (a mid-recording devtools teardown degrades another agent's flow to brittle coordinate taps; that agent is warned, but its recorded steps are already the worse kind). Omit \`devices\` only when a machine-wide cleanup is what you actually want. Passing an EMPTY array scopes to nothing and stops nothing - it is not a way to ask for the machine-wide sweep.
147381
+ PASS \`devices\` with the device ids this session used: one tool-server serves every agent, subagent and CLI call using this argent install, and an unscoped call tears down THEIR devices too (a mid-recording devtools teardown degrades another agent's flow to brittle coordinate taps; that agent is warned, but its recorded steps are already the worse kind). Omit \`devices\` only when a machine-wide cleanup is what you actually want. Passing an EMPTY array scopes to nothing and stops nothing - it is not a way to ask for the machine-wide sweep.
147382
147382
  A JS-runtime debugger session is keyed by the id you called \`debugger-connect\` with. On a Metro serving two or more devices that id is not a udid or serial - connect refuses those and tells you to re-target with the \`logicalDeviceId\` it returns - so a scope built from \`list-devices\` ids cannot reach that session. Pass any such \`logicalDeviceId\` in \`devices\` ALONGSIDE the device id; { left_running } names the ones you missed.
147383
- Returns { stopped } - the URNs of the services that were actually live and got shut down; an ERROR node is disposed too but never appears there, so an empty \`stopped\` only means nothing was still running. { unmatched } lists supplied ids that own no service here, so a mistyped id - or a device NAME passed where an id was expected - does not read as a clean machine. It is NOT proof the id is wrong: a Vega device is driven through CLI/adb shell-outs, so one you only booted and drove with the remote registers no service and always lands here \u2014 as does a real device of any platform this session never started anything on. Present ONLY when \`devices\` was supplied AND at least one id matched nothing - absent on an unscoped call and when every id matched. Stopping the same device twice does not report it unmatched: ownership counts regardless of service state. { left_running } lists the URNs of live debugger sessions (and the network inspectors / React profiler sessions riding on them) whose id no device scope can name - re-call with the id after each URN's \`<namespace>:<port>:\` prefix to reap them. { aborted: true } means the caller cancelled the request part-way, so the rest of the machine was left untouched and neither of the other two fields was computed. Past the schema - which rejects an unknown key outright, so the \`udids\` slip is an error rather than a silent machine-wide sweep - the call always succeeds; reaping nothing is a result, not a failure.`,
147383
+ Returns { stopped } - the URNs of the services that were actually live and got shut down; an ERROR node is disposed too but never appears there, so an empty \`stopped\` only means nothing was still running. { unmatched } lists supplied ids that own no service here, so a mistyped id - or a device NAME passed where an id was expected - does not read as a clean machine. It is NOT proof the id is wrong: a Vega device is driven through CLI/adb shell-outs, so one you only booted and drove with the remote registers no service and always lands here, as does a real device of any platform this session never started anything on. Present ONLY when \`devices\` was supplied AND at least one id matched nothing - absent on an unscoped call and when every id matched. Stopping the same device twice does not report it unmatched: ownership counts regardless of service state. { left_running } lists the URNs of live debugger sessions (and the network inspectors / React profiler sessions riding on them) whose id no device scope can name - re-call with the id after each URN's \`<namespace>:<port>:\` prefix to reap them. { aborted: true } means the caller cancelled the request part-way, so the rest of the machine was left untouched and neither of the other two fields was computed. Past the schema - which rejects an unknown key outright, so the \`udids\` slip is an error rather than a silent machine-wide sweep - the call always succeeds; reaping nothing is a result, not a failure.`,
147384
147384
  zodSchema: zodSchema63,
147385
147385
  services: () => ({}),
147386
147386
  async execute(_services, params, ctx) {
@@ -147471,7 +147471,7 @@ var stopMetroTool = {
147471
147471
  completedMsg: ({ params }) => `Stopped Metro on port ${params.port}`,
147472
147472
  failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to stop Metro on port ${params.port}: ${failureSignal2.error_code}`
147473
147473
  },
147474
- description: `Stop the Metro bundler process listening on a given port (default 8081). Use when ending a React Native session or when Metro must be restarted. Returns { stopped, port, pids }; stopped=false if no process is found on the port. Fails if the port lookup command times out or the process cannot be killed. This is DESTRUCTIVE \u2014 always ask the user for confirmation before calling this tool.`,
147474
+ description: `Stop the Metro bundler process listening on a given port (default 8081). Use when ending a React Native session or when Metro must be restarted. Returns { stopped, port, pids }; stopped=false if no process is found on the port. Fails if the port lookup command times out or the process cannot be killed. This is DESTRUCTIVE: always ask the user for confirmation before calling this tool.`,
147475
147475
  zodSchema: zodSchema64,
147476
147476
  services: () => ({}),
147477
147477
  async execute(_services, params) {
@@ -149818,13 +149818,13 @@ async function appendStepToFlow(session, step) {
149818
149818
  // ../tool-server/src/tools/flows/flow-start-recording.ts
149819
149819
  var zodSchema65 = external_exports.object({
149820
149820
  name: external_exports.string().describe(
149821
- 'Name for this flow (e.g. "settings-explore") \u2014 letters, digits, underscore and hyphen only.'
149821
+ 'Name for this flow (e.g. "settings-explore"): letters, digits, underscore and hyphen only.'
149822
149822
  ),
149823
149823
  project_root: external_exports.string().describe(
149824
149824
  "Absolute path to the project root directory (the directory that contains or should contain `.argent/flows/`). The flow file is created at `<project_root>/.argent/flows/<name>.yaml`."
149825
149825
  ),
149826
149826
  executionPrerequisite: external_exports.string().optional().describe(
149827
- 'Fragments only: the app/device state assumed on entry (e.g. "Settings app open on General page"). For a self-contained e2e flow, omit this and record a `restart-app` as the first step instead \u2014 it is captured as the flow\'s `launch` step. restart-app has no chromium support, so a chromium flow records as a fragment; add the `launch: { chromium: <app path> }` line to the YAML afterward, deleting the executionPrerequisite line if you passed one \u2014 a flow that starts with a launch must not declare it.'
149827
+ 'Fragments only: the app/device state assumed on entry (e.g. "Settings app open on General page"). For a self-contained e2e flow, omit this and record a `restart-app` as the first step instead; it is captured as the flow\'s `launch` step. restart-app has no chromium support, so a chromium flow records as a fragment; add the `launch: { chromium: <app path> }` line to the YAML afterward, deleting the executionPrerequisite line if you passed one, since a flow that starts with a launch must not declare it.'
149828
149828
  )
149829
149829
  });
149830
149830
  var fileInputs2 = [
@@ -149848,19 +149848,19 @@ Use when you want to capture a reusable sequence of device interactions for late
149848
149848
  Returns { message, flowFile, savedTo } and optionally { restarted, discardedSteps } if a live recording of the same flow was discarded.
149849
149849
  Without a link, it creates that file and fails if the .argent/flows/ directory cannot be created or the file cannot be written. Over a link (argent link or ARGENT_TOOLS_URL, also to 127.0.0.1), your client writes the file, and \`savedTo\` is its path on your computer, or null when that write failed.
149850
149850
 
149851
- Several flows can be recorded at once \u2014 each keyed by the \`name\` + \`project_root\`
149852
- that every subsequent recording tool repeats \u2014 and one recording's steps never
149851
+ Several flows can be recorded at once, each keyed by the \`name\` + \`project_root\`
149852
+ that every subsequent recording tool repeats, and one recording's steps never
149853
149853
  land in another's file. Steps still run LIVE, so give each concurrent recording
149854
149854
  its own device and pick a name unique to your task.
149855
149855
 
149856
- After starting, use flow-add-step to append tool calls \u2014 each step is executed
149856
+ After starting, use flow-add-step to append tool calls. Each step is executed
149857
149857
  LIVE so you can verify it works before it gets recorded. Read each step's
149858
149858
  \`message\`: an await-ui-element whose condition never held is still recorded (it
149859
149859
  returns success:false rather than failing), and a check that passes live can
149860
149860
  still fail once polished into an \`await:\`/\`assert:\` directive, which resolves
149861
149861
  against a different tree. flow-add-step warns about both when you record the
149862
149862
  wait DIRECTLY. A wait nested inside a recorded run-sequence gets neither warning
149863
- \u2014 that tool reports its own shape \u2014 so for those, read \`toolResult\`. For a self-contained
149863
+ (that tool reports its own shape), so for those, read \`toolResult\`. For a self-contained
149864
149864
  e2e flow, record a restart-app of the app under test as the FIRST step (captured
149865
149865
  as the flow's \`launch\` step); for a reusable fragment, skip that and pass
149866
149866
  executionPrerequisite instead. Use flow-add-echo to add labels, and
@@ -152374,9 +152374,9 @@ function stepAnchor(step) {
152374
152374
  // ../tool-server/src/tools/flows/flow-add-step.ts
152375
152375
  init_device_info();
152376
152376
  var zodSchema66 = external_exports.object({
152377
- name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
152377
+ name: external_exports.string().describe("Name of the flow being recorded: the one passed to flow-start-recording."),
152378
152378
  project_root: external_exports.string().describe(
152379
- "Absolute path to the project root of the flow being recorded \u2014 the same value passed to flow-start-recording. Together with `name` it identifies which recording this step belongs to."
152379
+ "Absolute path to the project root of the flow being recorded: the same value passed to flow-start-recording. Together with `name` it identifies which recording this step belongs to."
152380
152380
  ),
152381
152381
  command: external_exports.string().describe(
152382
152382
  'MCP tool to execute and record, for example "gesture-tap". Do not pass a flow directive or a recording tool. Call flow-add-script directly for a requested script step.'
@@ -153022,9 +153022,9 @@ Returns { message, stepCount, recorded, savedTo }; \`recorded\`, not the status,
153022
153022
  // ../tool-server/src/tools/flows/flow-insert-echo.ts
153023
153023
  init_zod();
153024
153024
  var zodSchema67 = external_exports.object({
153025
- name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
153025
+ name: external_exports.string().describe("Name of the flow being recorded: the one passed to flow-start-recording."),
153026
153026
  project_root: external_exports.string().describe(
153027
- "Absolute path to the project root of the flow being recorded \u2014 the same value passed to flow-start-recording. Together with `name` it identifies which recording this echo belongs to."
153027
+ "Absolute path to the project root of the flow being recorded: the same value passed to flow-start-recording. Together with `name` it identifies which recording this echo belongs to."
153028
153028
  ),
153029
153029
  message: external_exports.string().describe("Message to echo when the flow is replayed")
153030
153030
  });
@@ -153036,7 +153036,7 @@ var flowInsertEchoTool = {
153036
153036
  completedMsg: ({ params }) => `Added note to flow ${params.name}`,
153037
153037
  failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to add note to flow ${params.name}: ${failureSignal2.error_code}`
153038
153038
  },
153039
- description: `Record an echo step in the flow named by \`name\` + \`project_root\`. Echo steps print a message when the flow is replayed \u2014 useful as labels between tool calls.
153039
+ description: `Record an echo step in the flow named by \`name\` + \`project_root\`. Echo steps print a message when the flow is replayed, useful as labels between tool calls.
153040
153040
  Use when you want to annotate a recorded flow with a human-readable label or checkpoint message.
153041
153041
  Returns { message, stepCount, savedTo }. Fails if that flow has no recording in progress.`,
153042
153042
  zodSchema: zodSchema67,
@@ -154490,9 +154490,9 @@ var flowAddScriptTool = {
154490
154490
  init_zod();
154491
154491
  var fs60 = __toESM(require("node:fs/promises"));
154492
154492
  var zodSchema69 = external_exports.object({
154493
- name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
154493
+ name: external_exports.string().describe("Name of the flow being recorded: the one passed to flow-start-recording."),
154494
154494
  project_root: external_exports.string().describe(
154495
- "Absolute path to the project root of the flow being recorded \u2014 the same value passed to flow-start-recording. Together with `name` it identifies which recording to finish."
154495
+ "Absolute path to the project root of the flow being recorded: the same value passed to flow-start-recording. Together with `name` it identifies which recording to finish."
154496
154496
  )
154497
154497
  });
154498
154498
  function attachStepWarnings(summary, warnings) {
@@ -157031,19 +157031,19 @@ var zodSchema70 = external_exports.object({
157031
157031
  'Name of a saved flow to run from `.argent/flows` (e.g. "settings-explore"). Omit when flow_path is set.'
157032
157032
  ),
157033
157033
  project_root: external_exports.string().describe(
157034
- "Absolute path to the calling agent's project root \u2014 the cwd it is working in. With name, the saved flow is read from `.argent/flows/<name>.yaml` under this root; with flow_path, the flow, its run: siblings, its script: paths and baselines all resolve beside the YAML instead, so pass the agent's cwd. A script still RUNS in this root whichever source was used."
157034
+ "Absolute path to the calling agent's project root: the cwd it is working in. With name, the saved flow is read from `.argent/flows/<name>.yaml` under this root; with flow_path, the flow, its run: siblings, its script: paths and baselines all resolve beside the YAML instead, so pass the agent's cwd. A script still RUNS in this root whichever source was used."
157035
157035
  ),
157036
157036
  flow_file: external_exports.string().optional().describe(
157037
- "Path to the flow .yaml as readable by the tool-server. Internal \u2014 the argent client derives it from project_root and name automatically; leave unset."
157037
+ "Path to the flow .yaml as readable by the tool-server. Internal: the argent client derives it from project_root and name automatically; leave unset."
157038
157038
  ),
157039
157039
  flow_path: external_exports.string().optional().describe(
157040
157040
  "Omit when name is set. Absolute path to a flow .yaml on the client. Over a link (argent link or ARGENT_TOOLS_URL), the argent client uploads the file, its run: fragments and the snapshot baselines of each run, and the tool-server runs those copies. Keep run: fragments under project_root or beside the flow file. With updateBaselines, the client writes the new baselines when the run ends. The client also uploads each absolute .png or .yaml path that a tool: step takes as a file argument, when the file is under project_root or beside the flow file. A tool: flow-execute step that names a flow with name and an absolute project_root without a .. segment runs: the client also uploads that flow and its own files. Over a link, the uploaded flows must not have: script: steps; tool: steps that run a flow another way or record a flow; tool: steps that take a directory, an app or an output directory; tool: steps whose tool builds a file path from several arguments; tool: steps that name a relative path or a file other than .png or .yaml. Without a link, the tool-server reads the files in place and all step kinds run."
157041
157041
  ),
157042
157042
  device: external_exports.string().optional().describe(
157043
- "Device id to run against (iOS UDID, Android/Vega serial, Chromium id) \u2014 the id list-devices reports. Auto-detected when omitted, but only when exactly one booted device matches (optionally narrowed by `platform`); with several booted the run fails and lists them, so pass this explicitly whenever more than one device is up."
157043
+ "Device id to run against (iOS UDID, Android/Vega serial, Chromium id), as list-devices reports it. Auto-detected when omitted, but only when exactly one booted device matches (optionally narrowed by `platform`); with several booted the run fails and lists them, so pass this explicitly whenever more than one device is up."
157044
157044
  ),
157045
157045
  platform: external_exports.enum(SELECTABLE_PLATFORMS).optional().describe(
157046
- "Restrict auto-detection to this platform when several devices are booted. `ios` selects local simulators only \u2014 pass `ios-remote` to select a remote one. `chromium` does more than filter: with no `device` it SELECTS the self-boot branch for an e2e flow - the runner boots an Electron instance from the `launch` step's chromium value and tears it down after the run (a single-key `launch: { chromium: \u2026 }` map selects it on its own, without this parameter). When it selects that branch it never falls back to device auto-detection (a fragment, or an e2e launch map with no `chromium` key, still does), and the launch value must be a real Electron app path on the tool-server host: a bare-string `launch:` - what the recorder writes - holds an installed-app bundle id, so passing `chromium` for one fails the whole run with `Electron boot: path does not exist`. Edit the launch to `{ chromium: <app path> }` first."
157046
+ "Restrict auto-detection to this platform when several devices are booted. `ios` selects local simulators only; pass `ios-remote` to select a remote one. `chromium` does more than filter: with no `device` it SELECTS the self-boot branch for an e2e flow - the runner boots an Electron instance from the `launch` step's chromium value and tears it down after the run (a single-key `launch: { chromium: \u2026 }` map selects it on its own, without this parameter). When it selects that branch it never falls back to device auto-detection (a fragment, or an e2e launch map with no `chromium` key, still does), and the launch value must be a real Electron app path on the tool-server host: a bare-string `launch:` - what the recorder writes - holds an installed-app bundle id, so passing `chromium` for one fails the whole run with `Electron boot: path does not exist`. Edit the launch to `{ chromium: <app path> }` first."
157047
157047
  ),
157048
157048
  updateBaselines: external_exports.boolean().optional().describe(
157049
157049
  "Write/refresh screenshot baselines for `snapshot` steps instead of diffing against them, also in the flows that tool: flow-execute steps run, unless such a step sets updateBaselines itself."
@@ -158515,10 +158515,10 @@ var zodSchema71 = external_exports.object({
158515
158515
  'Name of a saved flow to inspect from `.argent/flows` (e.g. "settings-explore"). Omit when flow_path is set.'
158516
158516
  ),
158517
158517
  project_root: external_exports.string().describe(
158518
- "Absolute path to the calling agent's project root \u2014 the cwd it is working in. With name, the saved flow is read from `.argent/flows/<name>.yaml` under this root; with flow_path, the prerequisite is read from that YAML instead, so pass the agent's cwd."
158518
+ "Absolute path to the calling agent's project root: the cwd it is working in. With name, the saved flow is read from `.argent/flows/<name>.yaml` under this root; with flow_path, the prerequisite is read from that YAML instead, so pass the agent's cwd."
158519
158519
  ),
158520
158520
  flow_file: external_exports.string().optional().describe(
158521
- "Path to the flow .yaml as readable by the tool-server. Internal \u2014 the argent client derives it from project_root and name automatically; leave unset."
158521
+ "Path to the flow .yaml as readable by the tool-server. Internal: the argent client derives it from project_root and name automatically; leave unset."
158522
158522
  ),
158523
158523
  flow_path: external_exports.string().optional().describe(
158524
158524
  "Omit when name is set. Absolute path to a flow .yaml on the client. Over a link (argent link or ARGENT_TOOLS_URL), the argent client uploads the file and the tool-server reads the uploaded copy; without a link, the tool-server reads the file in place. Pass the path through the argent client; a raw path that the file-input boundary did not verify is rejected. Pass the same flow source here as to flow-execute, so the prerequisite you read belongs to the flow that will run."
@@ -158556,7 +158556,7 @@ var flowReadPrerequisiteTool = {
158556
158556
  completedMsg: () => "Read flow prerequisite",
158557
158557
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to read flow prerequisite: ${failureSignal2.error_code}`
158558
158558
  },
158559
- description: `Read the execution prerequisite of a flow without running it \u2014 a saved flow from the .argent/flows/ directory, or an explicit boundary-managed flow_path.
158559
+ description: `Read the execution prerequisite of a flow without running it: a saved flow from the .argent/flows/ directory, or an explicit boundary-managed flow_path.
158560
158560
  Returns { flow, executionPrerequisite }: the logical name, plus the precondition its author recorded
158561
158561
  verbatim. Empty when none was declared, which is always so for a self-contained scenario: one opening
158562
158562
  on a launch may declare no prerequisite, because it builds its own start state.
@@ -158989,7 +158989,7 @@ function targetFlagsFor(target) {
158989
158989
  }
158990
158990
  var zodSchema73 = external_exports.object({
158991
158991
  target: external_exports.enum(["auto", "global", "local", "both"]).optional().describe(
158992
- "Which install to update. 'auto' (default) updates the install serving this session \u2014 the global PATH install or this project's local devDependency, whichever this server runs from. Pass 'global' / 'local' to force one, or 'both' when the user has both and wants each updated."
158992
+ "Which install to update. 'auto' (default) updates the install serving this session: the global PATH install or this project's local devDependency, whichever this server runs from. Pass 'global' / 'local' to force one, or 'both' when the user has both and wants each updated."
158993
158993
  )
158994
158994
  });
158995
158995
  var updateScheduled = false;
@@ -159130,7 +159130,7 @@ var zodSchema75 = external_exports.object({
159130
159130
  "Orientation override for live baseline/current captures. Ignored on physical iPhones."
159131
159131
  ),
159132
159132
  outputDir: external_exports.string().min(1).optional().describe(
159133
- "Directory where diff artifacts should be written. Optional \u2014 defaults to a temp directory; the diff images are returned in the result either way."
159133
+ "Directory where diff artifacts should be written. Optional: defaults to a temp directory; the diff images are returned in the result either way."
159134
159134
  )
159135
159135
  }).strict();
159136
159136
  var capability34 = {
@@ -159477,7 +159477,7 @@ var zodSchema76 = external_exports.object({
159477
159477
  'Human name of the on-screen element this variant targets, e.g. "Foo button" or "profile header". Repeated calls with the same element accumulate multiple variants on it. Used as the default screen matcher when `match` is omitted.'
159478
159478
  ),
159479
159479
  udid: external_exports.string().min(1).max(200).optional().describe(
159480
- "Device id (iOS udid / Android serial) the variants were captured on. The preview window streams THIS device directly \u2014 pass the same udid you screenshotted/described with, so the human never has to pick a simulator. Set it on the first propose_variant of a round; later calls may omit it (the last non-empty value wins)."
159480
+ "Device id (iOS udid / Android serial) the variants were captured on. The preview window streams THIS device directly; pass the same udid you screenshotted/described with, so the human never has to pick a simulator. Set it on the first propose_variant of a round; later calls may omit it (the last non-empty value wins)."
159481
159481
  ),
159482
159482
  match: external_exports.object({
159483
159483
  by: external_exports.enum(["text", "label", "identifier", "role"]).describe(
@@ -159501,7 +159501,7 @@ var zodSchema76 = external_exports.object({
159501
159501
  width: external_exports.number(),
159502
159502
  height: external_exports.number()
159503
159503
  }).optional().describe(
159504
- "Normalized [0..1] bounds (fractions of screen width/height) of the target element AS IT APPEARS IN THIS VARIANT \u2014 read the matched node's `frame` from `describe` AFTER applying this variant. The preview window crops the screenshot to these bounds, so each variant shows its own re-laid-out element instead of every variant sharing one stale frame. The element moves/resizes between variants, so capture it per variant. Omit if unknown."
159504
+ "Normalized [0..1] bounds (fractions of screen width/height) of the target element AS IT APPEARS IN THIS VARIANT. Read the matched node's `frame` from `describe` AFTER applying this variant. The preview window crops the screenshot to these bounds, so each variant shows its own re-laid-out element instead of every variant sharing one stale frame. The element moves/resizes between variants, so capture it per variant. Omit if unknown."
159505
159505
  )
159506
159506
  }).describe("The variant being proposed for `element`.")
159507
159507
  });
@@ -159519,17 +159519,17 @@ function createProposeVariantTool(registry2) {
159519
159519
  Use when you have produced multiple alternative designs for an element and want the human to pick.
159520
159520
  Call this once per variant: e.g. propose_variant("Foo", v1), propose_variant("Foo", v2),
159521
159521
  propose_variant("Bar", v1)\u2026 Variants accumulate per element and across elements. The agent is NOT
159522
- blocked \u2014 keep proposing and keep working. Each element appears live in the Argent Lens window (a
159522
+ blocked: keep proposing and keep working. Each element appears live in the Argent Lens window (a
159523
159523
  native window that opens automatically) as a floating card beside the streamed simulator, with a thin
159524
159524
  line connecting it to the matched on-screen element; you don't open or display anything yourself. Pass
159525
159525
  variant.previewImage (e.g. a screenshot path) to show how each variant looks.
159526
159526
 
159527
- When you have proposed every variant for every element, you are done staging \u2014 the human reviews them
159527
+ When you have proposed every variant for every element, you are done staging. The human reviews them
159528
159528
  in the Argent Lens window and sends back their picks and comments. If an \`await_user_selection\` tool
159529
159529
  is available, call it once to block until they submit; otherwise just end your turn and their feedback
159530
159530
  arrives as a follow-up message (this is the case in an \`argent lens\` CLI session).
159531
159531
 
159532
- Returns { round, elementId, variantId, element, variantCount, totalElements } \u2014 confirmation only;
159532
+ Returns { round, elementId, variantId, element, variantCount, totalElements }: confirmation only;
159533
159533
  it does not wait for the user.`,
159534
159534
  searchHint: "propose design variant alternative option for element non-blocking ab choice",
159535
159535
  zodSchema: zodSchema76,
@@ -159558,7 +159558,7 @@ it does not wait for the user.`,
159558
159558
  init_zod();
159559
159559
  var zodSchema77 = external_exports.object({
159560
159560
  timeoutSeconds: external_exports.number().int().min(5).max(86400).optional().describe(
159561
- "Max seconds to block this call before returning a re-awaitable { status: 'pending' } result (default 1800). The user's proposals stay live across timeouts \u2014 on 'pending' just call await_user_selection again. Lower this if your MCP client enforces a short request timeout."
159561
+ "Max seconds to block this call before returning a re-awaitable { status: 'pending' } result (default 1800). The user's proposals stay live across timeouts; on 'pending' just call await_user_selection again. Lower this if your MCP client enforces a short request timeout."
159562
159562
  )
159563
159563
  });
159564
159564
  var awaitUserSelectionTool = {
@@ -159583,15 +159583,15 @@ that opens automatically on the user's screen), then returns their choices and a
159583
159583
  Returns one of:
159584
159584
  \u2022 { status: "completed", round, selections: [{ element, chosenVariant, comment? }], unselected,
159585
159585
  annotations: [{ target, match, comment }], globalComment, morePending? }
159586
- \u2014 the user finished this round; apply chosenVariant for each element (skip ones in
159586
+ The user finished this round; apply chosenVariant for each element (skip ones in
159587
159587
  \`unselected\`). \`annotations\` are free-form comments the user pinned to specific on-screen
159588
- elements via the inspector \u2014 treat each as a change request for that element.
159588
+ elements via the inspector; treat each as a change request for that element.
159589
159589
  If \`morePending\` is true, another already-decided round or a freshly-staged round is
159590
- still waiting \u2014 call await_user_selection AGAIN (repeat until you get a completed result
159590
+ still waiting. Call await_user_selection AGAIN (repeat until you get a completed result
159591
159591
  without \`morePending\`, a \`pending\`, or \`no_proposals\`); do not stop on this result alone.
159592
- \u2022 { status: "pending", message, proposedElements } \u2014 timeoutSeconds elapsed with no submission.
159592
+ \u2022 { status: "pending", message, proposedElements }: timeoutSeconds elapsed with no submission.
159593
159593
  Expected, not an error: the proposals are still live; call await_user_selection AGAIN.
159594
- \u2022 { status: "no_proposals" } \u2014 you called this before propose_variant.
159594
+ \u2022 { status: "no_proposals" }: you called this before propose_variant.
159595
159595
 
159596
159596
  This tool is long-running; it intentionally holds the request open. It honors client
159597
159597
  disconnects (aborts cleanly).`,