@swmansion/argent 0.32.1-next.0 → 0.32.1-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/cli-cmds.mjs +46 -6
  2. package/dist/client.js +12 -0
  3. package/dist/installer.mjs +19 -7
  4. package/dist/mcp-server.mjs +13 -1
  5. package/dist/tool-args.generated.d.ts +183 -178
  6. package/dist/tool-server.cjs +4572 -3776
  7. package/package.json +1 -1
  8. package/rules/argent.md +19 -183
  9. package/skills/argent-android-emulator-setup/SKILL.md +5 -13
  10. package/skills/argent-create-e2e/SKILL.md +1 -1
  11. package/skills/argent-create-e2e/references/e2e-yaml.md +16 -17
  12. package/skills/argent-create-e2e/references/live-authoring.md +26 -65
  13. package/skills/argent-create-e2e/references/reliability-and-recovery.md +8 -8
  14. package/skills/argent-device-interact/SKILL.md +65 -367
  15. package/skills/argent-device-interact/references/chromium.md +4 -19
  16. package/skills/argent-device-interact/references/foldables.md +8 -0
  17. package/skills/argent-device-interact/references/harmonyos.md +13 -50
  18. package/skills/argent-ios-device-interact/SKILL.md +0 -1
  19. package/skills/argent-ios-device-setup/SKILL.md +1 -1
  20. package/skills/argent-ios-simulator-setup/SKILL.md +3 -9
  21. package/skills/argent-lens/SKILL.md +20 -75
  22. package/skills/argent-metro-debugger/SKILL.md +35 -101
  23. package/skills/argent-native-profiler/SKILL.md +23 -92
  24. package/skills/argent-qa-e2e/SKILL.md +5 -5
  25. package/skills/argent-react-native-app-workflow/SKILL.md +34 -203
  26. package/skills/argent-react-native-optimization/SKILL.md +10 -26
  27. package/skills/argent-react-native-optimization/references/fix-reference.md +11 -11
  28. package/skills/argent-react-native-optimization/references/lint-rules.md +4 -5
  29. package/skills/argent-react-native-optimization/references/semantic-checklist.md +2 -2
  30. package/skills/argent-react-native-profiler/SKILL.md +46 -110
  31. package/skills/argent-screen-recording/SKILL.md +18 -37
  32. package/skills/argent-screenshot-diff/SKILL.md +8 -52
  33. package/skills/argent-settings-permissions/SKILL.md +15 -117
  34. package/skills/argent-test-ui-flow/SKILL.md +20 -90
  35. package/skills/argent-tv-interact/SKILL.md +12 -37
  36. package/skills/argent-tv-interact/references/vega.md +23 -0
  37. package/agents/argent-environment-inspector.md +0 -107
  38. package/agents/references/quality-control-checklist.md +0 -45
  39. package/skills/argent-device-interact/references/gesture-examples.md +0 -114
  40. package/skills/argent-device-interact/references/secrets.md +0 -23
  41. package/skills/argent-metro-debugger/references/failure-scenarios.md +0 -14
  42. package/skills/argent-metro-debugger/references/source-maps.md +0 -27
  43. package/skills/argent-react-native-profiler/references/diagnostic-tools.md +0 -101
@@ -10,11 +10,11 @@ export interface ArgentToolArgs {
10
10
  minStableMs?: number;
11
11
  };
12
12
  "await-ui-element": {
13
- /** Target device id from `list-devices` (iOS UDID, Android serial, HarmonyOS id, or Chromium id). */
13
+ /** Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, HarmonyOS id, or Chromium id). */
14
14
  udid: string;
15
- /** 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. */
15
+ /** What to wait for. `exists`: the selector matches an element anywhere in the tree. `visible`: it matches one with a non-zero on-screen frame. `hidden`: it matches nothing, or only a zero-area element (e.g. a spinner that went away). `text`: the first visible match in reading order (topmost, then leftmost; the first match overall if none is visible) contains expectedText, or equals it with textMatch `equals`. Only that match is checked, so if a loose selector hits several elements, narrow it to the one holding the text. */
16
16
  condition: "exists" | "visible" | "hidden" | "text";
17
- /** Element to match (text / identifier / role). */
17
+ /** Element to match. Give at least one field; every given field must match. */
18
18
  selector: {
19
19
  /** Case-insensitive substring of the element's visible label or value. */
20
20
  text?: string;
@@ -23,11 +23,11 @@ export interface ArgentToolArgs {
23
23
  /** Case-insensitive substring of the element's role (e.g. AXButton, button, TextView). */
24
24
  role?: string;
25
25
  };
26
- /** 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. */
26
+ /** Required for condition `text`: the string the checked match must contain or equal (see `textMatch`). */
27
27
  expectedText?: string;
28
28
  /** For condition `text`: how expectedText is compared. `contains` (default) is a case-insensitive substring; `equals` is a case-insensitive full-string match. */
29
29
  textMatch?: "contains" | "equals";
30
- /** Optional iOS app bundle id, passed to the describe fallback (see `describe`). Ignored on every other platform, including physical iOS. */
30
+ /** iOS app bundle id, passed to the describe fallback (see `describe`). Ignored on every other platform, including physical iOS. */
31
31
  bundleId?: string;
32
32
  /** Max time to wait for the condition before giving up (default 5000). */
33
33
  timeoutMs?: number;
@@ -39,25 +39,25 @@ export interface ArgentToolArgs {
39
39
  timeoutSeconds?: number;
40
40
  };
41
41
  "boot-device": {
42
- /** iOS: simulator UDID to boot (from `list-devices`). Provide exactly one of `udid`, `avdName`, `vvdImage`, `harmonyInstance`, or `electronAppPath`. */
42
+ /** iOS: simulator UDID to boot (from `list-devices`). */
43
43
  udid?: string;
44
- /** Android: AVD name to launch a new emulator from (from `list-devices` → `avds[].name`). Provide exactly one of `udid`, `avdName`, `vvdImage`, `harmonyInstance`, or `electronAppPath`. */
44
+ /** Android: AVD name to launch a new emulator from (from `list-devices` → `avds[].name`). */
45
45
  avdName?: string;
46
- /** 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`, `harmonyInstance`, or `electronAppPath`. */
46
+ /** Vega (Fire TV): VVD image to boot: the `vvdImage` of a Vega device from `list-devices` (e.g. `tv`). */
47
47
  vvdImage?: string;
48
- /** HarmonyOS: emulator instance to start: the `name` of a `kind: "emulator"` device from `list-devices` (e.g. `Phone_1`); the `harmony-emulator-<name>` id that entry reports as its `udid` is accepted too. Provide exactly one of `udid`, `avdName`, `vvdImage`, `harmonyInstance`, or `electronAppPath`. */
48
+ /** HarmonyOS: emulator instance to start: the `name` of a `kind: "emulator"` device from `list-devices` (e.g. `Phone_1`); the `harmony-emulator-<name>` id that entry reports as its `udid` is accepted too. */
49
49
  harmonyInstance?: string;
50
- /** Android/Vega/HarmonyOS: overall budget for the boot sequence. Default 480000 (8 min) on Android, 120000 (2 min) on Vega, 180000 (3 min) on HarmonyOS, where with `force` it spans the shutdown as well as the boot. Clamped to [30s, 15min]. Ignored on iOS. */
50
+ /** Android/Vega/HarmonyOS: overall budget for the boot sequence. Default 480000 (8 min) on Android, 120000 (2 min) on Vega, 180000 (3 min) on HarmonyOS, where with `force` it spans the shutdown as well as the boot. */
51
51
  bootTimeoutMs?: number;
52
- /** Shut down and re-boot the device even if already running. On HarmonyOS it is also what ties an already-running instance to the `hdc` connect key it registered under, since the emulator manager never reports one: without it the instance is left alone and the payload names the instance rather than a key (`list-devices` lists the keys, but not which instance each belongs to). Ignored for Electron, which always spawns a fresh process. */
52
+ /** Shut down and re-boot the device even if already running. On HarmonyOS it is also what ties an already-running instance to its `hdc` connect key: without it the instance is left alone and its key stays unresolved (`list-devices` lists the keys, but not which instance each belongs to). Ignored for Electron, which always spawns a fresh process. */
53
53
  force?: boolean;
54
- /** 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/HarmonyOS/Electron, which argent never mutes. */
54
+ /** Android only (argent never mutes other platforms): boot the emulator with audio output enabled. Defaults to false, so several agent-driven emulators don't all play sound on the host; 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`. The first boot after toggling is a slower cold boot (the snapshot was saved in the other audio mode). The `boot-sound` argent flag flips this default to true. */
55
55
  sound?: boolean;
56
56
  /** Android on a macOS host only: boot the emulator with guest Vulkan. Defaults to false: guest Vulkan crashes Chrome's GPU process, which breaks Chrome and Custom Tab sign-in flows. Without it apps find no Vulkan device, although the guest still lists the Vulkan features, so a Vulkan-only renderer such as WebGPU (react-native-wgpu) draws nothing; pass `true` to test one. Takes effect at boot: an emulator already running in the other mode is reused with a `note`, and `force: true` reboots it. A boot snapshot saved in the other mode can't be reused, so the first boot after toggling is a slower cold boot. The `ARGENT_EMULATOR_GUEST_VULKAN` env var flips this default to true. Ignored on other hosts and platforms. */
57
57
  guestVulkan?: boolean;
58
- /** 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/HarmonyOS/Electron, which have no equivalent GUI step. */
58
+ /** 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. The `ARGENT_SIMULATOR_NO_WINDOW` env var (1/true/yes) forces this host-wide. */
59
59
  headless?: boolean;
60
- /** Electron: path to the Electron app to launch. Either a packaged .app bundle / executable, or a project directory whose package.json points the Electron binary at the entry script. Provide exactly one of `udid`, `avdName`, `vvdImage`, `harmonyInstance`, or `electronAppPath`. */
60
+ /** Electron: path to the Electron app to launch. Either a packaged .app bundle / executable, or a project directory whose package.json points the Electron binary at the entry script. */
61
61
  electronAppPath?: string;
62
62
  /** Electron-only: CDP remote-debugging port to expose. Defaults to a free port; the resulting device id is `chromium-cdp-<port>`. */
63
63
  electronPort?: number;
@@ -73,15 +73,15 @@ export interface ArgentToolArgs {
73
73
  "chromium-cookies": {
74
74
  /** Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`). */
75
75
  udid: string;
76
- /** get: read cookies. set: create/update a cookie. delete: remove a named cookie. clear: remove all browser cookies. */
76
+ /** get: read cookies. set: create/update a cookie. delete: remove matching cookies. clear: remove ALL browser cookies. */
77
77
  action: "get" | "set" | "delete" | "clear";
78
- /** set/delete: cookie name. */
78
+ /** Cookie name. */
79
79
  name?: string;
80
- /** set: cookie value. */
80
+ /** Cookie value. */
81
81
  value?: string;
82
- /** get: restrict to these URLs (defaults to the active page). set/delete: scope the cookie by URL. */
82
+ /** get: restrict to this URL (defaults to the active page). set/delete: scope the cookie by URL. */
83
83
  url?: string;
84
- /** set/delete: scope the cookie by domain (alt to url). */
84
+ /** set/delete: scope the cookie by domain. */
85
85
  domain?: string;
86
86
  /** set/delete: cookie path (default /). */
87
87
  path?: string;
@@ -97,21 +97,21 @@ export interface ArgentToolArgs {
97
97
  "chromium-storage": {
98
98
  /** Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`). */
99
99
  udid: string;
100
- /** Which Web Storage area: `local` (localStorage) or `session` (sessionStorage). */
100
+ /** `local`: localStorage. `session`: sessionStorage. */
101
101
  store: "local" | "session";
102
102
  /** get: read one key (with `key`) or all entries. set: write `key`=`value`. remove: delete `key`. clear: empty the store. */
103
103
  action: "get" | "set" | "remove" | "clear";
104
- /** get (optional) / set / remove: the storage key. */
104
+ /** The storage key. */
105
105
  key?: string;
106
- /** set: the value to store. */
106
+ /** The value to store. */
107
107
  value?: string;
108
108
  };
109
109
  "chromium-tabs": {
110
110
  /** Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`). */
111
111
  udid: string;
112
- /** list: enumerate tabs/windows. select: make a tab active (every other tool then acts on it). new: open a tab. close: close a tab. */
112
+ /** list: enumerate tabs/windows. select: make a tab active. new: open a tab and activate it. close: close a tab; if it was active, another live tab becomes active. */
113
113
  action: "list" | "select" | "new" | "close";
114
- /** Target tab for `select` / `close`: a tabId like `t2` or a label. `close` defaults to the active tab. */
114
+ /** Target tab for `select` (required) / `close`: a tabId like `t2` or a label. `close` defaults to the active tab. */
115
115
  tab?: string;
116
116
  /** `new` only: URL to open (defaults to about:blank). */
117
117
  url?: string;
@@ -119,27 +119,27 @@ export interface ArgentToolArgs {
119
119
  label?: string;
120
120
  };
121
121
  "debugger-component-tree": {
122
- /** 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. */
122
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
123
123
  port?: number;
124
124
  /** Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial). */
125
125
  device_id: string;
126
126
  /** 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. */
127
127
  udid?: string;
128
- /** When true (default), only components visible on screen are returned. Set to false to include all mounted components including those scrolled off-screen. Useful when you need to understand the full page structure. */
128
+ /** When true, only components visible on screen are returned. Set to false to include all mounted components, including those scrolled off-screen, e.g. to understand the full page structure. */
129
129
  onScreenOnly?: boolean;
130
130
  /** Maximum total nodes to include. When exceeded, intermediate single-child wrapper chains are collapsed to preserve both root structure and leaf elements. Default: no limit. */
131
131
  maxNodes?: number;
132
- /** When true, appends a summary of all filtered components: total fiber count, JS-side skip counts by name, and TS-side filter pass removals. Useful for understanding what was pruned from the tree. */
132
+ /** When true, appends a summary of all filtered components: total fiber count and skip counts by component name and by filter. */
133
133
  includeSkipped?: boolean;
134
134
  };
135
135
  "debugger-connect": {
136
- /** 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. */
136
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
137
137
  port?: number;
138
138
  /** 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. */
139
139
  device_id: string;
140
140
  };
141
141
  "debugger-evaluate": {
142
- /** 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. */
142
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
143
143
  port?: number;
144
144
  /** 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. */
145
145
  device_id: string;
@@ -147,37 +147,37 @@ export interface ArgentToolArgs {
147
147
  expression: string;
148
148
  };
149
149
  "debugger-inspect-element": {
150
- /** 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. */
150
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
151
151
  port?: number;
152
152
  /** Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial). */
153
153
  device_id: string;
154
- /** Logical X coordinate on device screen */
154
+ /** X coordinate on device screen, in logical pixels (not normalized 0–1) */
155
155
  x: number;
156
- /** Logical Y coordinate on device screen */
156
+ /** Y coordinate on device screen, in logical pixels (not normalized 0–1) */
157
157
  y: number;
158
158
  /** Lines of source context to include around the component definition */
159
159
  contextLines?: number;
160
- /** 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. */
160
+ /** 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 a code fragment. */
161
161
  resolveSourceMaps?: boolean;
162
- /** 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. */
162
+ /** Maximum number of hierarchy items to return, most specific first. The default covers all app-specific code; increase to 70+ to also see the navigation/screen structure. */
163
163
  maxItems?: number;
164
- /** 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. */
164
+ /** When true, items that would normally be filtered are kept in the response with skipped=true and a skipReason. */
165
165
  includeSkipped?: boolean;
166
166
  };
167
167
  "debugger-log-registry": {
168
- /** 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. */
168
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
169
169
  port?: number;
170
170
  /** 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. */
171
171
  device_id: string;
172
172
  };
173
173
  "debugger-reload-metro": {
174
- /** 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. */
174
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
175
175
  port?: number;
176
176
  /** Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial). */
177
177
  device_id: string;
178
178
  };
179
179
  "debugger-status": {
180
- /** 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. */
180
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
181
181
  port?: number;
182
182
  /** 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. */
183
183
  device_id: string;
@@ -185,7 +185,7 @@ export interface ArgentToolArgs {
185
185
  describe: {
186
186
  /** Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, HarmonyOS id, or Chromium id). */
187
187
  udid: string;
188
- /** Optional app bundle ID. Used as a target hint on iOS when the AX-service returns no elements and the describe tool falls back to native-devtools inspection. If omitted, the fallback auto-detects the frontmost connected app. Ignored on every other platform, including a physical iOS device. */
188
+ /** App bundle ID, used as a target hint on iOS when the AX-service returns no elements and describe falls back to native-devtools inspection. If omitted, the fallback auto-detects the frontmost connected app. Ignored on every other platform, including a physical iOS device. */
189
189
  bundleId?: string;
190
190
  };
191
191
  "dismiss-update": {
@@ -195,9 +195,9 @@ export interface ArgentToolArgs {
195
195
  "e2e-add-echo": {
196
196
  /** Name of the e2e test being recorded: the one passed to e2e-start-recording. */
197
197
  name: string;
198
- /** Absolute path to the project root of the e2e test being recorded: the same value passed to e2e-start-recording. Together with `name` it identifies which recording this echo belongs to. */
198
+ /** Absolute path to the project root of the e2e test being recorded: the same value passed to e2e-start-recording. */
199
199
  project_root: string;
200
- /** Message to echo when the e2e test is replayed */
200
+ /** Text the echo step prints */
201
201
  message: string;
202
202
  };
203
203
  "e2e-add-script": {
@@ -207,13 +207,13 @@ export interface ArgentToolArgs {
207
207
  project_root: string;
208
208
  /** Path to the .mjs file, relative to the e2e test YAML. For example: "../../scripts/seed-order.mjs". */
209
209
  path: string;
210
- /** Optional time limit in milliseconds. The default is 30000 and the minimum is 100. */
210
+ /** Time limit in milliseconds. The default is 30000 and the minimum is 100. */
211
211
  timeout?: number;
212
212
  };
213
213
  "e2e-add-step": {
214
214
  /** Name of the e2e test being recorded: the one passed to e2e-start-recording. */
215
215
  name: string;
216
- /** Absolute path to the project root of the e2e test being recorded: the same value passed to e2e-start-recording. Together with `name` it identifies which recording this step belongs to. */
216
+ /** Absolute path to the project root of the e2e test being recorded: the same value passed to e2e-start-recording. */
217
217
  project_root: string;
218
218
  /** MCP tool to execute and record, for example "gesture-tap". Do not pass an e2e test directive or a recording tool. Call e2e-add-script directly for a requested script step. */
219
219
  command: string;
@@ -223,21 +223,21 @@ export interface ArgentToolArgs {
223
223
  delayMs?: number;
224
224
  };
225
225
  "e2e-execute": {
226
- /** Name of a saved e2e test to run from `.argent/e2e`, or `.argent/flows` when it is not there (e.g. "settings-explore"). Omit when e2e_test_path is set. */
226
+ /** Name of a saved e2e test to run from `<project_root>/.argent/e2e`, or `.argent/flows` when it is not there (e.g. "settings-explore"). */
227
227
  name?: string;
228
- /** Absolute path to the calling agent's project root: the cwd it is working in. With name, the saved e2e test is read from `.argent/e2e/<name>.yaml`, else `.argent/flows/<name>.yaml`, under this root; with e2e_test_path, the e2e test, 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. */
228
+ /** Absolute path to the calling agent's project root: the cwd it is working in, also with e2e_test_path, where the e2e test, its run: siblings, its script: paths and baselines resolve beside the YAML instead. A script still RUNS in this root. */
229
229
  project_root: string;
230
230
  /** Path to the e2e test .yaml as readable by the tool-server. Internal: the argent client derives it from project_root and name automatically; leave unset. */
231
231
  e2e_test_file?: string;
232
- /** Omit when name is set. Absolute path to an e2e test .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 e2e test 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 e2e test file. A tool: e2e-execute step that names an e2e test with name and an absolute project_root without a .. segment runs: the client also uploads that e2e test and its own files. Over a link, the uploaded e2e tests must not have: script: steps; tool: steps that run an e2e test another way or record an e2e test; 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. */
232
+ /** Absolute path to an e2e test .yaml on the client. */
233
233
  e2e_test_path?: string;
234
- /** 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. */
234
+ /** 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` and the e2e test's `requires:` block); with several booted the run fails and lists them, so pass this explicitly whenever more than one device is up. */
235
235
  device?: string;
236
- /** 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 a standalone e2e test - 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: … }` 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 a standalone e2e test's 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. */
236
+ /** Restrict auto-detection to this platform when several devices are booted. `ios` selects local simulators only; `ios-remote` selects a remote one. `chromium` with no `device` also makes the runner boot an Electron instance for a standalone e2e test from its `launch` step's chromium value and tear it down after the run, with no fallback to auto-detection (a single-key `launch: { chromium: … }` map, or a `requires:` block that allows only chromium, does this on its own; a fragment, or a launch map without a `chromium` key, is still auto-detected). That value must be an Electron app path on the tool-server host: the bare-string `launch:` the recorder writes holds a bundle id, which fails the run with `Electron boot: path does not exist`, so first edit it to `{ chromium: <app path> }`. */
237
237
  platform?: "ios" | "android" | "chromium" | "vega" | "ios-remote";
238
- /** Write/refresh screenshot baselines for `snapshot` steps instead of diffing against them, also in the e2e tests that tool: e2e-execute steps run, unless such a step sets updateBaselines itself. */
238
+ /** Write/refresh screenshot baselines for `snapshot` steps instead of diffing against them, also in the e2e tests that tool: e2e-execute steps run, unless such a step sets updateBaselines itself. Over a link, the client writes the new baselines when the run ends. */
239
239
  updateBaselines?: boolean;
240
- /** Set to true to confirm the execution prerequisite has been met. Required (LLM path) when a fragment defines an executionPrerequisite. */
240
+ /** Set to true to confirm the execution prerequisite has been met. Required when a fragment defines an executionPrerequisite. */
241
241
  prerequisiteAcknowledged?: boolean;
242
242
  /** @deprecated Renamed to `e2e_test_path`. */
243
243
  flow_path?: string;
@@ -247,17 +247,17 @@ export interface ArgentToolArgs {
247
247
  "e2e-finish-recording": {
248
248
  /** Name of the e2e test being recorded: the one passed to e2e-start-recording. */
249
249
  name: string;
250
- /** Absolute path to the project root of the e2e test being recorded: the same value passed to e2e-start-recording. Together with `name` it identifies which recording to finish. */
250
+ /** Absolute path to the project root of the e2e test being recorded: the same value passed to e2e-start-recording. */
251
251
  project_root: string;
252
252
  };
253
253
  "e2e-read-prerequisite": {
254
- /** Name of a saved e2e test to inspect from `.argent/e2e`, or `.argent/flows` when it is not there (e.g. "settings-explore"). Omit when e2e_test_path is set. */
254
+ /** Name of a saved e2e test to inspect from `<project_root>/.argent/e2e`, or `.argent/flows` when it is not there (e.g. "settings-explore"). */
255
255
  name?: string;
256
- /** Absolute path to the calling agent's project root: the cwd it is working in. With name, the saved e2e test is read from `.argent/e2e/<name>.yaml`, else `.argent/flows/<name>.yaml`, under this root; with e2e_test_path, the prerequisite is read from that YAML instead, so pass the agent's cwd. */
256
+ /** Absolute path to the calling agent's project root: the cwd it is working in. */
257
257
  project_root: string;
258
258
  /** Path to the e2e test .yaml as readable by the tool-server. Internal: the argent client derives it from project_root and name automatically; leave unset. */
259
259
  e2e_test_file?: string;
260
- /** Omit when name is set. Absolute path to an e2e test .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 e2e test source here as to e2e-execute, so the prerequisite you read belongs to the e2e test that will run. */
260
+ /** Absolute path to an e2e test .yaml on the client. */
261
261
  e2e_test_path?: string;
262
262
  /** @deprecated Renamed to `e2e_test_path`. */
263
263
  flow_path?: string;
@@ -267,10 +267,15 @@ export interface ArgentToolArgs {
267
267
  "e2e-start-recording": {
268
268
  /** Name for this e2e test (e.g. "settings-explore"): letters, digits, underscore and hyphen only. */
269
269
  name: string;
270
- /** Absolute path to the project root directory (the directory that contains or should contain `.argent/e2e/`). The e2e test file is created at `<project_root>/.argent/e2e/<name>.yaml`. */
270
+ /** Absolute path to the project root directory (the directory that contains or should contain `.argent/e2e/`). */
271
271
  project_root: string;
272
- /** Fragments only: the app/device state assumed on entry (e.g. "Settings app open on General page"). For a standalone e2e test, omit this and record a `restart-app` as the first step instead; it is captured as the e2e test's `launch` step. restart-app has no chromium support, so a chromium e2e test records as a fragment; add the `launch: { chromium: <app path> }` line to the YAML afterward, deleting the executionPrerequisite line if you passed one, since an e2e test that starts with a launch must not declare it. */
272
+ /** Fragments only: the app/device state assumed on entry (e.g. "Settings app open on General page"). Omit it for a standalone e2e test. restart-app has no chromium support, so a chromium e2e test records as a fragment; add the `launch: { chromium: <app path> }` line to the YAML afterward, deleting the executionPrerequisite line if you passed one, since an e2e test that starts with a launch must not declare it. */
273
273
  executionPrerequisite?: string;
274
+ /** The e2e test's `requires:` block: the targets it supports, ANDed. `platform` is one platform or a list (`ios` also covers a remote simulator); `runtimeKind` is `tv` or `mobile`. Omit it for a test that runs on any target. */
275
+ requires?: {
276
+ platform?: "ios" | "android" | "chromium" | "vega" | Array<"ios" | "android" | "chromium" | "vega">;
277
+ runtimeKind?: "mobile" | "tv";
278
+ };
274
279
  };
275
280
  fill: {
276
281
  /** Target device id from `list-devices`. */
@@ -281,9 +286,9 @@ export interface ArgentToolArgs {
281
286
  fold: {
282
287
  /** Target device id from `list-devices` (a foldable iOS simulator UDID or Android emulator serial). */
283
288
  udid: string;
284
- /** Where to move the hinge: `closed` (the cover panel), `half-open` or `open` (the inner panel). Exactly one of `posture` and `angle`. */
289
+ /** Where to move the hinge: `closed` shows the cover panel, `half-open` and `open` show the inner panel. */
285
290
  posture?: "closed" | "half-open" | "open";
286
- /** The hinge angle in degrees, 0 (closed) to 180 (open). Exactly one of `posture` and `angle`. */
291
+ /** The hinge angle in degrees: 0 = closed, 180 = open. */
287
292
  angle?: number;
288
293
  };
289
294
  "foreground-app": {
@@ -297,56 +302,56 @@ export interface ArgentToolArgs {
297
302
  "gesture-custom": {
298
303
  /** Target device id from `list-devices` (iOS UDID or Android serial). */
299
304
  udid: string;
300
- /** Sequence of touch events; x/y (and optional second touch) are normalized 0.0–1.0, not pixels */
305
+ /** Touch events, dispatched in order. */
301
306
  events: Array<{
302
307
  /** Touch event type */
303
308
  type: "Down" | "Move" | "Up";
304
- /** Normalized x 0.0–1.0 (not pixels; same as tap/swipe) */
309
+ /** Touch x. */
305
310
  x: number;
306
- /** Normalized y 0.0–1.0 (not pixels; same as tap/swipe) */
311
+ /** Touch y. */
307
312
  y: number;
308
- /** Second touch x for two-finger gestures: normalized 0.0–1.0 (not pixels) */
313
+ /** Second finger x, for two-finger gestures. */
309
314
  x2?: number;
310
- /** Second touch y for two-finger gestures: normalized 0.0–1.0 (not pixels) */
315
+ /** Second finger y, for two-finger gestures. */
311
316
  y2?: number;
312
317
  /** Delay before this event in milliseconds (default 16ms ≈ 60fps) */
313
318
  delayMs?: number;
314
319
  }>;
315
- /** Number of intermediate Move events to auto-insert between each pair of consecutive events. Smooths out gestures by linearly interpolating both primary (x,y) and secondary (x2,y2) coordinates. The delay is split evenly across interpolated frames. Default: no interpolation. */
320
+ /** Number of Move events to insert between each pair of consecutive events, linearly interpolating both x,y and x2,y2 and splitting the delay evenly, for a smooth gesture. Default: no interpolation. */
316
321
  interpolate?: number;
317
322
  };
318
323
  "gesture-drag": {
319
324
  /** Target Chromium device id from `list-devices` (chromium-cdp-<port>). */
320
325
  udid: string;
321
- /** Press x: normalized 0.0–1.0 (fraction of window width, not pixels). */
326
+ /** Press x. */
322
327
  fromX: number;
323
- /** Press y: normalized 0.0–1.0 (fraction of window height, not pixels). */
328
+ /** Press y. */
324
329
  fromY: number;
325
- /** Release x: normalized 0.0–1.0 (not pixels; same space as tap). */
330
+ /** Release x. */
326
331
  toX: number;
327
- /** Release y: normalized 0.0–1.0 (not pixels; same space as tap). */
332
+ /** Release y. */
328
333
  toY: number;
329
- /** Total drag duration in milliseconds (default 300, at most 10000 - the button stays down for exactly this long), interpolated at ~60fps. */
334
+ /** Total drag duration in milliseconds (default 300); the button stays down this long. */
330
335
  durationMs?: number;
331
- /** 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. */
336
+ /** Whether the drag releases with momentum; default true (a constant-speed drag). false decelerates into the release point, so an app that derives a fling from the release velocity (carousels, drag libraries) applies little to no momentum: use it when the drag must stop where it was aimed. Under ~100ms durationMs some fling survives; keep the default 300 when the fling must be fully suppressed. */
332
337
  momentum?: boolean;
333
338
  };
334
339
  "gesture-pinch": {
335
340
  /** Target device id from `list-devices` (iOS UDID, HarmonyOS id, or Android serial). */
336
341
  udid: string;
337
- /** Center of pinch, horizontal: normalized 0.0–1.0 (fraction of screen width, not pixels) */
342
+ /** Center of the pinch, horizontal. */
338
343
  centerX: number;
339
- /** Center of pinch, vertical: normalized 0.0–1.0 (fraction of screen height, not pixels) */
344
+ /** Center of the pinch, vertical. */
340
345
  centerY: number;
341
- /** Initial distance between the two fingers: normalized 0.0–1.0 (fraction of screen, not pixels). E.g. 0.2 = fingers 20% of screen apart. Use a larger startDistance than endDistance to pinch in (zoom out). */
346
+ /** Initial distance between the two fingers. */
342
347
  startDistance: number;
343
- /** Final distance between the two fingers: normalized 0.0–1.0 (fraction of screen, not pixels). E.g. 0.6 = fingers 60% of screen apart. Use a larger endDistance than startDistance to pinch out (zoom in). */
348
+ /** Final distance between the two fingers. */
344
349
  endDistance: number;
345
- /** Final horizontal center of the pinch: normalized 0.0–1.0. When set, the centroid drifts linearly from centerX to endCenterX over the gesture (e.g. to keep expanding fingers on-screen near an edge). Omit for a fixed center. */
350
+ /** Final horizontal center of the pinch. When set, the centroid drifts linearly from centerX to endCenterX over the gesture (e.g. to keep expanding fingers on-screen near an edge). Omit for a fixed center. */
346
351
  endCenterX?: number;
347
- /** Final vertical center of the pinch: normalized 0.0–1.0. When set, the centroid drifts linearly from centerY to endCenterY over the gesture. Omit for a fixed center. */
352
+ /** Final vertical center of the pinch; drifts from centerY like endCenterX. Omit for a fixed center. */
348
353
  endCenterY?: number;
349
- /** Axis angle in degrees along which the fingers are placed (default 0 = horizontal). */
354
+ /** Angle in degrees of the axis the fingers lie on: 0 = horizontal (default), 90 = vertical. */
350
355
  angle?: number;
351
356
  /** Total gesture duration in milliseconds (default 300). On HarmonyOS the device runs the whole move itself and takes this as wall-clock time, clamped to the 1–15000ms range `uinput` accepts. */
352
357
  durationMs?: number;
@@ -354,19 +359,19 @@ export interface ArgentToolArgs {
354
359
  "gesture-rotate": {
355
360
  /** Target device id from `list-devices` (iOS UDID or Android serial). */
356
361
  udid: string;
357
- /** Center of rotation, horizontal: normalized 0.0–1.0 (fraction of screen width, not pixels) */
362
+ /** Center of rotation, horizontal. */
358
363
  centerX: number;
359
- /** Center of rotation, vertical: normalized 0.0–1.0 (fraction of screen height, not pixels) */
364
+ /** Center of rotation, vertical. */
360
365
  centerY: number;
361
- /** Distance from center to each finger: normalized 0.0–1.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. */
366
+ /** Distance from the center to each finger. */
362
367
  radius?: number;
363
- /** Per-axis finger distance, horizontal: normalized 0.0–1.0 fraction of screen WIDTH. Give both radiusX and radiusY (they override radius) with radiusX·screenWidth = radiusY·screenHeight for a physically circular orbit: constant finger separation, no pinch coupled into the turn. */
368
+ /** Finger distance along the horizontal axis, as a fraction of screen WIDTH. */
364
369
  radiusX?: number;
365
- /** Per-axis finger distance, vertical: normalized 0.0–1.0 fraction of screen HEIGHT. Always paired with radiusX; see radiusX. */
370
+ /** Finger distance along the vertical axis, as a fraction of screen HEIGHT. */
366
371
  radiusY?: number;
367
372
  /** Starting angle in degrees (0 = right, 90 = down) */
368
373
  startAngle: number;
369
- /** Ending angle in degrees. endAngle > startAngle = clockwise. */
374
+ /** Ending angle in degrees. */
370
375
  endAngle: number;
371
376
  /** Total gesture duration in milliseconds (default 300) */
372
377
  durationMs?: number;
@@ -374,13 +379,13 @@ export interface ArgentToolArgs {
374
379
  "gesture-scroll": {
375
380
  /** Target Chromium device id from `list-devices` (chromium-cdp-<port>). */
376
381
  udid: string;
377
- /** Anchor x: normalized 0.0–1.0 (fraction of window width, not pixels). The wheel events land here; put it over the element you want to scroll. */
382
+ /** Anchor x. The wheel events land here; put it over the element you want to scroll. */
378
383
  x: number;
379
- /** Anchor y: normalized 0.0–1.0 (fraction of window height, not pixels). */
384
+ /** Anchor y. */
380
385
  y: number;
381
- /** Horizontal scroll distance as a fraction of the window width (e.g. 0.5 = half a window). Positive scrolls content right (reveals content to the right). */
386
+ /** Horizontal scroll distance as a fraction of the window width. Positive reveals content to the right; negative scrolls back left. */
382
387
  deltaX?: number;
383
- /** Vertical scroll distance as a fraction of the window height (e.g. 0.5 = half a window). Positive scrolls content down (reveals content below), like rolling a mouse wheel toward you. */
388
+ /** Vertical scroll distance as a fraction of the window height (0.5 = half a window). Positive scrolls down (reveals content below), like rolling a mouse wheel toward you; negative scrolls back up. */
384
389
  deltaY?: number;
385
390
  /** Spread the scroll over this many milliseconds in wheel-event steps (default 300) so scroll handlers fire progressively. */
386
391
  durationMs?: number;
@@ -388,47 +393,47 @@ export interface ArgentToolArgs {
388
393
  "gesture-swipe": {
389
394
  /** Target device id from `list-devices` (iOS UDID, HarmonyOS id, or Android serial). */
390
395
  udid: string;
391
- /** Start x: normalized 0.0–1.0 (not pixels; same as tap) */
396
+ /** Start x. */
392
397
  fromX: number;
393
- /** Start y: normalized 0.0–1.0 (not pixels; same as tap) */
398
+ /** Start y. */
394
399
  fromY: number;
395
- /** End x: normalized 0.0–1.0 (not pixels; same as tap) */
400
+ /** End x. */
396
401
  toX: number;
397
- /** End y: normalized 0.0–1.0 (not pixels; same as tap) */
402
+ /** End y. */
398
403
  toY: number;
399
- /** Total gesture duration in milliseconds (default 300, at most 10000 - the gesture holds a finger down for exactly this long) */
404
+ /** Total gesture duration in milliseconds (default 300); the finger stays down this long. Below ~32ms the whole travel lands in one or two frames, which the OS flings as hard as any flick. */
400
405
  durationMs?: number;
401
- /** Whether the swipe releases with momentum; default true (a natural flinging swipe). Pass false for a momentum-free swipe at the default durationMs: the finger decelerates into the end point (ease-out) so the OS reads ~0 release velocity and applies little to no fling. Use false for scroll-to-element loops. momentum: false needs durationMs >= 150 and is rejected below it: a shorter ease-out gives the OS velocity fit too little wall clock to read the deceleration as a stop, and it flings harder than a plain swipe instead (on Android, backwards). At 150 itself the swipe lands short of where the finger stopped, and 2 of 47 runs still flung backwards. */
406
+ /** Whether the swipe releases with momentum; default true (a natural flinging swipe). false eases the finger into the end point so the OS applies little to no fling and the content stops where the finger lifts: use it when you need a deterministic scroll distance, e.g. in scroll-to-element loops. false needs durationMs >= 150 and is rejected below that; near 150 it can still land short or fling, so keep the default 300. */
402
407
  momentum?: boolean;
403
408
  };
404
409
  "gesture-tap": {
405
410
  /** Target device id from `list-devices` (iOS UDID, Android serial, HarmonyOS id, or Chromium id). */
406
411
  udid: string;
407
- /** Normalized horizontal position 0.0–1.0 (left=0, right=1), not pixels */
412
+ /** Horizontal position: 0 = left edge, 1 = right edge. */
408
413
  x: number;
409
- /** Normalized vertical position 0.0–1.0 (top=0, bottom=1), not pixels */
414
+ /** Vertical position: 0 = top edge, 1 = bottom edge. */
410
415
  y: number;
411
- /** Number of taps/clicks dispatched as ONE multi-tap gesture (2 = double-tap / double-click). The taps land inside the OS double-tap window; on Chromium each click carries an escalating CDP clickCount so dblclick actually fires; on physical iOS 2 is the native double-tap and higher counts loop single taps, which a double-tap recognizer may pair. On HarmonyOS only 2 is one gesture; 3 or more are separate injections a device round trip apart, which the OS reads as single taps. Default 1. */
416
+ /** Number of taps/clicks dispatched as ONE gesture inside the OS double-tap window (2 = double-tap / double-click), which two separate tap calls cannot guarantee. On physical iOS, higher counts loop single taps, which a double-tap recognizer may pair. On HarmonyOS they land as separate taps. Default 1. */
412
417
  clickCount?: number;
413
418
  };
414
419
  keyboard: {
415
420
  /** Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, HarmonyOS id, or Chromium id). */
416
421
  udid: string;
417
- /** 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. Over a link with the `forward-secrets` flag on, the client's own sources are checked first. 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. */
422
+ /** Text to type character by character; handles uppercase, digits and common punctuation. Cannot be combined with `key`: to type and then press a key, send two `keyboard` steps in one `run-sequence` ({ text: "hello" } then { key: "enter" }). To type a credential without its plaintext ever entering your context, use a secret placeholder `{{secret:<NAME>}}`, e.g. "{{secret:APP_PASSWORD}}", alone or inside longer text. It 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. Over a link with the `forward-secrets` flag on, the client's own sources are checked first. The result echoes the placeholder, never the value, and the auto-screenshot after typing is skipped. To submit after a secret, put both steps in ONE `run-sequence`: that keeps the skip covering the Enter, which a second bare `keyboard` call would not. If the secret is not set, the failure lists the available names and the sources it checked; 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. */
418
423
  text?: string;
419
- /** 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`. HarmonyOS: only enter (return), backspace (delete), space, arrow-left and arrow-right; any other key fails with 400 KEYBOARD_KEY_UNSUPPORTED. */
424
+ /** Named key to press: enter, escape, backspace, tab, space, arrow-up, arrow-down, arrow-left, arrow-right, f1-f12. Cannot be combined with `text`; to do both, send two `keyboard` steps in one `run-sequence`. Not supported on Apple TV / Android TV; move focus with `tv-remote` (up/down/left/right) instead. Physical iOS: only `enter` and `backspace`. HarmonyOS: only enter (return), backspace (delete), space, arrow-left and arrow-right; any other key fails with 400 KEYBOARD_KEY_UNSUPPORTED. */
420
425
  key?: string;
421
- /** Delay in ms between key presses (default 50). Ignored on Android phones/tablets (typed via `adb input text`, which has no per-key cadence), on HarmonyOS (`uitest uiInput text` types the whole string in one shot), on Vega (text/keys injected in a single shot), on TV targets (Apple TV / Android TV type the whole string at the daemon's own cadence), and on physical iOS. */
426
+ /** Delay in ms between key presses (default 50). Ignored on Android phones/tablets, HarmonyOS, Vega, Apple TV / Android TV and physical iOS, which type the whole string in one shot or at their own cadence. */
422
427
  delayMs?: number;
423
428
  };
424
429
  "launch-app": {
425
430
  /** Target device id from `list-devices` (iOS UDID, Android serial, HarmonyOS id, or Chromium id). */
426
431
  udid: string;
427
- /** App identifier. iOS: bundle id (e.g. com.apple.MobileSMS). Android: package name from build.gradle `applicationId` (e.g. com.android.settings). HarmonyOS: bundle name as listed by `bm dump -a` (e.g. com.huawei.hmos.calculator). Chromium: any tag matching the same alphabet (letters, digits, '.', '_' and '-'); the call is a no-op since the renderer is already running. */
432
+ /** App identifier. iOS: bundle id. Android: package name from build.gradle `applicationId`. Vega (Fire TV): the interactive component app id from manifest.toml (e.g. com.example.app.main). HarmonyOS: bundle name as listed by `bm dump -a` (e.g. com.huawei.hmos.calculator). Chromium: any tag matching the pattern. */
428
433
  bundleId: string;
429
- /** Android-only: fully-qualified Activity name (e.g. `.MainActivity` or `com.example/com.example.MainActivity`). If omitted on Android, the app's default launcher activity is used. Ignored on iOS / Chromium / HarmonyOS (a HarmonyOS ability is resolved from the bundle's own `abilityInfos`). */
434
+ /** Android-only: fully-qualified Activity name (e.g. `.MainActivity` or `com.example/com.example.MainActivity`). If omitted, the app's default launcher activity is used. */
430
435
  activity?: string;
431
- /** Apple simulators and physical iPhones: arguments passed to the app process at launch, e.g. `["-FeatureFlag", "YES"]` to override UserDefaults. A running app is relaunched to apply them. Ignored on other targets. */
436
+ /** Apple simulators and physical iPhones: arguments passed to the app process at launch, e.g. `["-FeatureFlag", "YES"]` to override UserDefaults. A running app is relaunched to apply them. The call fails, launching nothing, if terminating it does not finish within 15s on a local iOS simulator, or fails for a reason other than the app not running on a remote one. */
432
437
  launchArgs?: Array<string>;
433
438
  };
434
439
  "list-devices": Record<string, never>;
@@ -481,7 +486,7 @@ export interface ArgentToolArgs {
481
486
  skipClasses?: Array<string>;
482
487
  /** 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. */
483
488
  skipClassPrefixes?: Array<string>;
484
- /** Maximum recursion depth (default 8). Increase for deeper inspection, decrease to reduce output size. */
489
+ /** Maximum recursion depth (default 8). Raise it to reach deeper views. */
485
490
  maxDepth?: number;
486
491
  };
487
492
  "native-network-logs": {
@@ -505,11 +510,11 @@ export interface ArgentToolArgs {
505
510
  "native-profiler-start": {
506
511
  /** Target device id from `list-devices` (iOS UDID or Android serial). */
507
512
  device_id: string;
508
- /** iOS: the CFBundleExecutable or display name of the app to profile. Android: the app's package name. If omitted, auto-detects the currently running foreground app. Only provide this if auto-detection picks the wrong app. */
513
+ /** iOS: the CFBundleExecutable or display name of the app to profile. Android: the app's package name. If omitted, auto-detects the foreground app; set it only if auto-detection picks the wrong app. */
509
514
  app_process?: string;
510
- /** iOS-only: path to an Instruments .tracetemplate file (defaults to bundled Argent template). Ignored on Android. */
515
+ /** iOS only. Path to an Instruments .tracetemplate file (defaults to the bundled Argent template). */
511
516
  template_path?: string;
512
- /** 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. */
517
+ /** 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 carry no backtrace (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, so leave it off for pure CPU/hang profiling. Rejected up front under the all-processes capture (used where Xcode's `--device` recording is broken, or forced with ARGENT_IOS_CAPTURE=all-processes), which cannot cold-launch and records no leaks. */
513
518
  malloc_stack_logging?: boolean;
514
519
  };
515
520
  "native-profiler-stop": {
@@ -523,7 +528,7 @@ export interface ArgentToolArgs {
523
528
  bundleId: string;
524
529
  /** Raw X coordinate in points, on the portrait axes of the screen (the axes of native-describe-screen frames). NOT normalized [0,1] tap space. */
525
530
  x: number;
526
- /** Raw Y coordinate in points, on the portrait axes of the screen (the axes of native-describe-screen frames). NOT normalized [0,1] tap space. */
531
+ /** Raw Y coordinate in points, on the same axes as x. NOT normalized [0,1] tap space. */
527
532
  y: number;
528
533
  /** Include ancestor chain for the matched view (default true) */
529
534
  includeAncestors?: boolean;
@@ -545,7 +550,7 @@ export interface ArgentToolArgs {
545
550
  bundleId: string;
546
551
  /** Raw X coordinate in points, on the portrait axes of the screen (the axes of native-describe-screen frames). NOT normalized [0,1] tap space. */
547
552
  x: number;
548
- /** Raw Y coordinate in points, on the portrait axes of the screen (the axes of native-describe-screen frames). NOT normalized [0,1] tap space. */
553
+ /** Raw Y coordinate in points, on the same axes as x. NOT normalized [0,1] tap space. */
549
554
  y: number;
550
555
  /** Include ancestor chain for the matched view (default true) */
551
556
  includeAncestors?: boolean;
@@ -563,93 +568,93 @@ export interface ArgentToolArgs {
563
568
  "open-url": {
564
569
  /** Target device id from `list-devices` (iOS UDID, Android serial, HarmonyOS id, or Chromium id). */
565
570
  udid: string;
566
- /** URL or scheme to open (e.g. https://example.com, messages://, tel:555, geo:37.0,-122.0). For Chromium this navigates the renderer. */
571
+ /** URL or scheme to open (e.g. https://example.com, messages://, tel:555, geo:37.0,-122.0). */
567
572
  url: string;
568
- /** Physical iOS only: the app that receives the URL. Defaults to Safari for http(s); required for any other scheme. Ignored elsewhere. */
573
+ /** Physical iOS only: the app that receives the URL. Defaults to Safari for http(s); required for any other scheme. */
569
574
  bundleId?: string;
570
575
  };
571
576
  paste: {
572
577
  /** Target device id from `list-devices` (iOS simulator UDID or Android emulator serial). */
573
578
  udid: string;
574
- /** 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`, the client's first over a link with the `forward-secrets` flag on), 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. */
579
+ /** 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 and is never echoed back. 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. */
575
580
  text: string;
576
581
  };
577
582
  "profiler-combined-report": {
578
- /** 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. */
583
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
579
584
  port?: number;
580
585
  /** iOS Simulator/device UDID or Android serial */
581
586
  device_id: string;
582
587
  };
583
588
  "profiler-commit-query": {
584
- /** 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. */
589
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
585
590
  port?: number;
586
591
  /** Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). */
587
592
  device_id: string;
588
- /** Query mode: by_component (commits for a component), by_time_range (commits in a window), by_index (full detail for one commit), cascade_tree (parent-child cascade for a commit) */
593
+ /** Query mode; see Modes in the tool description. */
589
594
  mode: "by_component" | "by_time_range" | "by_index" | "cascade_tree";
590
- /** Component name for by_component mode */
595
+ /** Component name */
591
596
  component_name?: string;
592
- /** Time range filter for by_time_range mode */
597
+ /** Time range in ms since profiling started, the clock this tool prints */
593
598
  time_range_ms?: {
594
- /** Start of range in ms since profiling started, the same clock profiler-commit-query prints */
599
+ /** Start of range in ms */
595
600
  start: number;
596
- /** End of range in ms since profiling started, the same clock profiler-commit-query prints */
601
+ /** End of range in ms */
597
602
  end: number;
598
603
  };
599
- /** Commit index for by_index and cascade_tree modes */
604
+ /** Commit index */
600
605
  commit_index?: number;
601
- /** 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. */
606
+ /** 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; a small cap there can show less than the analyze report it is meant to expand on. */
602
607
  top_n?: number;
603
608
  };
604
609
  "profiler-cpu-query": {
605
- /** 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. */
610
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
606
611
  port?: number;
607
612
  /** Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). */
608
613
  device_id: string;
609
- /** 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) */
614
+ /** Query mode; see Modes in the tool description. */
610
615
  mode: "top_functions" | "time_window" | "call_tree" | "component_cpu";
611
- /** Time window filter for time_window mode (ms since profiling started, the same clock profiler-commit-query prints) */
616
+ /** Time window in ms since profiling started, the same clock profiler-commit-query prints */
612
617
  time_window_ms?: {
613
- /** Start of window in ms since profiling started, the same clock profiler-commit-query prints */
618
+ /** Start of window in ms */
614
619
  start: number;
615
- /** End of window in ms since profiling started, the same clock profiler-commit-query prints */
620
+ /** End of window in ms */
616
621
  end: number;
617
622
  };
618
- /** Component name for component_cpu mode */
623
+ /** Component name */
619
624
  component_name?: string;
620
- /** Function name for call_tree mode */
625
+ /** Function name */
621
626
  function_name?: string;
622
- /** Number of results to return (default 15) */
627
+ /** Number of results to return */
623
628
  top_n?: number;
624
- /** For call_tree mode: also show callers of the function */
629
+ /** Also show callers of the function */
625
630
  include_callers?: boolean;
626
631
  };
627
632
  "profiler-load": {
628
- /** list: show available sessions on disk. load_react: load a React profiler session into memory for query tools. load_native: re-parse native profiler XML files (xctrace on iOS) into memory for query tools. */
633
+ /** What to do; see Modes in the tool description. */
629
634
  mode: "list" | "load_react" | "load_native";
630
- /** Timestamp-based session identifier (e.g. '20250313-143022') from the list output. Required for load_react and load_native modes. */
635
+ /** Timestamp-based session identifier (e.g. '20250313-143022') from the list output. */
631
636
  session_id?: string;
632
- /** 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. */
637
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
633
638
  port?: number;
634
639
  /** Target device id from `list-devices`. Used to cache the loaded React session under the correct port+device key, and required to resolve the native profiler session for load_native. */
635
640
  device_id: string;
636
- /** Android package name to use when restoring older load_native .pftrace sessions that do not have a metadata sidecar. */
641
+ /** Android package name to pass when restoring an older load_native .pftrace session that has no metadata sidecar. */
637
642
  app_process?: string;
638
643
  };
639
644
  "profiler-stack-query": {
640
645
  /** iOS Simulator UDID or Android serial. */
641
646
  device_id: string;
642
- /** Query mode: hang_stacks (full CPU context during a hang), function_callers (who calls a native function), thread_breakdown (CPU split by thread), leak_stacks (leak details by object type) */
647
+ /** Query mode; see Modes in the tool description. */
643
648
  mode: "hang_stacks" | "function_callers" | "thread_breakdown" | "leak_stacks";
644
- /** 0-based index into the hang list for hang_stacks mode */
649
+ /** 0-based index into the hang list */
645
650
  hang_index?: number;
646
- /** Function name for function_callers mode */
651
+ /** Native function name */
647
652
  function_name?: string;
648
653
  /** Thread filter. thread_breakdown: case-insensitive substring match. function_callers: exact raw thread name (e.g. ".blueskyweb.app"), or "main" for the UI thread; omit to search ALL threads (each result is tagged with its thread). Run thread_breakdown first to see the exact raw names. */
649
654
  thread?: string;
650
- /** Object type filter for leak_stacks mode */
655
+ /** Object type filter */
651
656
  object_type?: string;
652
- /** Max results to return (default 15) */
657
+ /** Max results to return */
653
658
  top_n?: number;
654
659
  };
655
660
  propose_variant: {
@@ -686,7 +691,7 @@ export interface ArgentToolArgs {
686
691
  };
687
692
  };
688
693
  "react-profiler-analyze": {
689
- /** 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. */
694
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
690
695
  port?: number;
691
696
  /** Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). */
692
697
  device_id: string;
@@ -696,9 +701,9 @@ export interface ArgentToolArgs {
696
701
  platform?: "ios" | "android";
697
702
  /** React Native version (e.g. "0.73.4") */
698
703
  rn_version?: string;
699
- /** Optional list of user actions with their time offset from profiling start. Compute offsetMs = tapTimestampMs - startedAtEpochMs, where tapTimestampMs comes from the tap/swipe tool return value and startedAtEpochMs comes from react-profiler-start return value. */
704
+ /** User actions to annotate the report's commits with: each commit shows the action that preceded it. */
700
705
  annotations?: Array<{
701
- /** Milliseconds since profiling started. Compute as: tapTimestampMs - startedAtEpochMs, using the timestampMs returned by tap/swipe and the startedAtEpochMs returned by react-profiler-start. */
706
+ /** Milliseconds since profiling started: tapTimestampMs - startedAtEpochMs, where tapTimestampMs is the timestampMs a tap/swipe tool returned and startedAtEpochMs is the value react-profiler-start returned. */
702
707
  offsetMs: number;
703
708
  /** Description of the action performed */
704
709
  label: string;
@@ -711,51 +716,51 @@ export interface ArgentToolArgs {
711
716
  project_root: string;
712
717
  };
713
718
  "react-profiler-cpu-summary": {
714
- /** 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. */
719
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
715
720
  port?: number;
716
721
  /** Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). */
717
722
  device_id: string;
718
- /** Number of top hotspot functions to return (default 20) */
723
+ /** Number of top hotspot functions to return */
719
724
  top_n?: number;
720
725
  /** If true, only show React component functions (PascalCase names) */
721
726
  react_only?: boolean;
722
727
  };
723
728
  "react-profiler-fiber-tree": {
724
- /** 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. */
729
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
725
730
  port?: number;
726
731
  /** Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). */
727
732
  device_id: string;
728
- /** Maximum tree depth to traverse (default 10) */
733
+ /** Maximum tree depth to traverse */
729
734
  max_depth?: number;
730
735
  /** Regex string to filter component names */
731
736
  filter?: string;
732
737
  };
733
738
  "react-profiler-renders": {
734
- /** 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. */
739
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
735
740
  port?: number;
736
741
  /** Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). */
737
742
  device_id: string;
738
- /** Number of top re-rendering components to return (default 20) */
743
+ /** Number of components to return */
739
744
  top_n?: number;
740
745
  };
741
746
  "react-profiler-start": {
742
- /** 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. */
747
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
743
748
  port?: number;
744
749
  /** Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial). */
745
750
  device_id: string;
746
- /** CPU sampling interval in microseconds (default 100) */
751
+ /** CPU sampling interval in microseconds */
747
752
  sample_interval_us?: number;
748
753
  /** Take over an active profiling session even when it is owned by another tool-server and still fresh. Set to true only when you know the prior owner is gone. */
749
754
  force?: boolean;
750
755
  };
751
756
  "react-profiler-status": {
752
- /** 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. */
757
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
753
758
  port?: number;
754
759
  /** Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). */
755
760
  device_id: string;
756
761
  };
757
762
  "react-profiler-stop": {
758
- /** 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. */
763
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
759
764
  port?: number;
760
765
  /** Device id from list-devices: the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial). */
761
766
  device_id: string;
@@ -763,7 +768,7 @@ export interface ArgentToolArgs {
763
768
  "reinstall-app": {
764
769
  /** Target device id from `list-devices` (iOS UDID, HarmonyOS id, or Android serial). */
765
770
  udid: string;
766
- /** App identifier that matches the bundle at `appPath`. iOS: bundle id (used to uninstall first). Android: package name (used to uninstall first; the install itself identifies the app from the APK). Vega: interactive component app id (e.g. com.example.app.main), used to uninstall first. HarmonyOS: bundle name, which must match `app.bundleName` in the `.hap`. */
771
+ /** App identifier, used to uninstall the previous installation. iOS: bundle id. Android: package name. Vega: interactive component app id (e.g. com.example.app.main). HarmonyOS: bundle name (`app.bundleName` in the `.hap`). */
767
772
  bundleId: string;
768
773
  /** Path to the app bundle. iOS: `.app` directory (e.g. ./build/.../MyApp.app). Android: `.apk` file (e.g. android/app/build/outputs/apk/debug/app-debug.apk). Vega: `.vpkg` file. HarmonyOS: `.hap` file. Relative paths are resolved from the current working directory. */
769
774
  appPath: string;
@@ -771,11 +776,11 @@ export interface ArgentToolArgs {
771
776
  "restart-app": {
772
777
  /** Target device id from `list-devices` (iOS UDID, HarmonyOS id, or Android serial). */
773
778
  udid: string;
774
- /** App identifier. iOS: bundle id. Android: package name. HarmonyOS: bundle name. */
779
+ /** App identifier. iOS: bundle id. Android: package name. Vega: interactive component app id. HarmonyOS: bundle name. */
775
780
  bundleId: string;
776
- /** Android-only: relaunch a non-launcher Activity (e.g. `.SettingsActivity` or `com.example/com.example.SettingsActivity`). If omitted, the app's default launcher activity is used. Ignored on iOS / HarmonyOS. */
781
+ /** Android-only: relaunch a non-launcher Activity (e.g. `.SettingsActivity` or `com.example/com.example.SettingsActivity`). If omitted, the app's default launcher activity is used. */
777
782
  activity?: string;
778
- /** Apple simulators and physical iPhones: arguments passed to the app process at launch, e.g. `["-FeatureFlag", "YES"]` to override UserDefaults. Ignored on other targets. */
783
+ /** Apple simulators and physical iPhones: arguments passed to the app process at launch, e.g. `["-FeatureFlag", "YES"]` to override UserDefaults. */
779
784
  launchArgs?: Array<string>;
780
785
  };
781
786
  rotate: {
@@ -789,7 +794,7 @@ export interface ArgentToolArgs {
789
794
  udid: string;
790
795
  /** Ordered list of interaction steps to execute sequentially */
791
796
  steps: Array<{
792
- /** 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). */
797
+ /** Tool name: one of the allowed tools listed in the description. */
793
798
  tool: string;
794
799
  /** Tool arguments (excluding udid, which is injected automatically) */
795
800
  args: {
@@ -802,11 +807,11 @@ export interface ArgentToolArgs {
802
807
  "screen-recording-start": {
803
808
  /** Target device id from `list-devices` (iOS Simulator UDID or Android serial). */
804
809
  udid: string;
805
- /** Auto-stop cap in seconds (default 180, max 600). Set it to slightly more than the interaction you plan to capture. */
810
+ /** Auto-stop cap in seconds (default 180). Set it to slightly more than the interaction you plan to capture. */
806
811
  timeLimitSeconds?: number;
807
- /** Default true. Collapse stretches where the screen does not change: the first second of each still stretch is kept, then unchanged frames are dropped until something moves again, so a long recording with brief activity comes back short instead of full of dead air (on a remote simulator the still stretches are removed whole). The returned durationMs is the trimmed length; wallClockMs/trimmedMs report what was removed. Set false to keep a faithful real-time recording. */
812
+ /** Default true. Collapse stretches where the screen does not change: the first second of each still stretch is kept, then unchanged frames are dropped until something moves again, so a long recording with brief activity comes back short instead of full of dead air. Set false to keep a faithful real-time recording. */
808
813
  trimStatic?: boolean;
809
- /** Default true. Draw simulator-server's touch visualizer into the recording: a pulse marks each tap, a comet trail follows swipes and drags, and paired markers show two-finger pinch/rotate, so the video makes clear where every interaction landed. On remote (`remote:`) simulators the overlay is drawn on the runner and is also visible in the live stream until the recording stops. Set false to record the raw screen with no overlay. */
814
+ /** Default true. Draw an on-screen marker for every tap, swipe, drag, pinch and rotate into the video, so it shows where each interaction landed. Set false to record the raw screen with no overlay. */
810
815
  showTouches?: boolean;
811
816
  };
812
817
  "screen-recording-stop": {
@@ -816,29 +821,29 @@ export interface ArgentToolArgs {
816
821
  screenshot: {
817
822
  /** Target device id from `list-devices` (iOS UDID, Android serial, Apple TV UDID, Vega serial, HarmonyOS id, or Chromium id). */
818
823
  udid: string;
819
- /** Orientation override for the screenshot (rotates the captured image after Page.captureScreenshot on Chromium). On Android the capture already follows the device's rotation. Rejected on HarmonyOS, which captures the display in its current orientation and has no override. Ignored on physical iPhones. */
824
+ /** Orientation override for the screenshot (on Chromium it rotates the captured image). On Android the capture already follows the device's rotation. Rejected on HarmonyOS, which captures the display in its current orientation and has no override. Ignored on physical iPhones. */
820
825
  rotation?: "Portrait" | "LandscapeLeft" | "LandscapeRight" | "PortraitUpsideDown";
821
- /** Scale factor (0.01-1.0). Defaults to ARGENT_SCREENSHOT_SCALE env var, or 0.25 if unset for iOS/Android/HarmonyOS. On a local Apple TV simulator, an Android TV or Vega, with neither set, the capture is downscaled to a 576 px long side (0.15 of a 4K capture); an Android TV whose form factor or display size cannot be read in time keeps 0.25. On Chromium the default is 1.0 (no downscale); pass <1 to opt in. Downscaling on Chromium requires the optional `sharp` dependency. */
826
+ /** Scale factor. Defaults to ARGENT_SCREENSHOT_SCALE env var, or 0.25 if unset for iOS/Android/HarmonyOS. On a local Apple TV simulator, an Android TV or Vega, with neither set, the capture is downscaled to a 576 px long side (0.15 of a 4K capture). On Chromium the default is 1.0 (no downscale); pass <1 to opt in. Downscaling on Chromium requires the optional `sharp` dependency. */
822
827
  scale?: number;
823
- /** 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. */
828
+ /** 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. */
824
829
  includeImageInContext?: boolean;
825
- /** Downscaling algorithm when scale<1 on Chromium. Defaults to lanczos3 (highest quality). Mirrors sim-server's wire enum. Ignored on physical iPhones. */
830
+ /** Downscaling algorithm when scale<1 on Chromium. Defaults to lanczos3 (highest quality). Ignored on every other platform. */
826
831
  downscaler?: "lanczos3" | "box" | "bilinear" | "nearest";
827
832
  };
828
833
  "screenshot-diff": {
829
- /** Path to the baseline PNG file. Required unless captureBaseline is true. */
834
+ /** Path to the saved baseline PNG file. Required unless captureBaseline is true; do not pass both. */
830
835
  baselinePath?: string;
831
- /** Path to the current PNG file. Required unless captureCurrent is true. */
836
+ /** Path to the saved current PNG file. Required unless captureCurrent is true; do not pass both. */
832
837
  currentPath?: string;
833
838
  /** Target device id from `list-devices` (iOS UDID, HarmonyOS id, or Android serial). */
834
839
  udid: string;
835
- /** Capture the baseline screenshot live at full resolution before diffing. Cannot be combined with captureCurrent. */
840
+ /** Capture the baseline screenshot live from the device, at full resolution, before diffing. Cannot be combined with captureCurrent. */
836
841
  captureBaseline?: boolean;
837
- /** Capture the current screenshot live at full resolution before diffing. Cannot be combined with captureBaseline. */
842
+ /** Capture the current screenshot live from the device, at full resolution, before diffing. Cannot be combined with captureBaseline. */
838
843
  captureCurrent?: boolean;
839
844
  /** Orientation override for live baseline/current captures. Rejected on HarmonyOS, which captures the display in its current orientation and has no override. Ignored on physical iPhones. */
840
845
  rotation?: "Portrait" | "LandscapeLeft" | "LandscapeRight" | "PortraitUpsideDown";
841
- /** Directory where diff artifacts should be written. Optional: defaults to a temp directory; the diff images are returned in the result either way. */
846
+ /** Directory where diff artifacts should be written (default: a temp directory). The diff images are returned in the result either way. */
842
847
  outputDir?: string;
843
848
  };
844
849
  "settings-permissions": {
@@ -846,23 +851,23 @@ export interface ArgentToolArgs {
846
851
  udid: string;
847
852
  /** `grant` pre-authorizes the permission, `deny` refuses it, `reset` returns it to the not-yet-asked state so the app prompts on next use. */
848
853
  action: "grant" | "deny" | "reset";
849
- /** 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). */
854
+ /** The permission to change. `notifications` is Android-only; `reminders` is iOS-only; `camera` works on Android, and on iOS only when the simulator's runtime models the service. */
850
855
  permission: "camera" | "microphone" | "photos" | "contacts" | "notifications" | "calendar" | "location" | "location-always" | "media-library" | "motion" | "reminders";
851
- /** 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. */
856
+ /** App to change the permission for; every action, `reset` included, applies to this app only. iOS: bundle id (e.g. com.example.app). Android: package name. */
852
857
  bundleId: string;
853
858
  };
854
859
  shake: {
855
860
  /** Target device id from `list-devices` (iOS simulator UDID or Android emulator serial). */
856
861
  udid: string;
857
- /** How many shake gestures to deliver back-to-back (default 1, max 10). Raise it for apps whose shake detector needs sustained motion before it fires. */
862
+ /** How many shake gestures to deliver back-to-back (default 1). Raise it for apps whose shake detector needs sustained motion before it fires. */
858
863
  count?: number;
859
864
  };
860
865
  "stop-all-simulator-servers": {
861
- /** 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. */
866
+ /** Ids of the devices THIS session used (iOS UDID / Android serial / Chromium id), to scope the teardown to. */
862
867
  devices?: Array<string>;
863
868
  };
864
869
  "stop-metro": {
865
- /** TCP port Metro is listening on (default 8081) */
870
+ /** TCP port Metro is listening on */
866
871
  port?: number;
867
872
  };
868
873
  "stop-simulator-server": {
@@ -878,7 +883,7 @@ export interface ArgentToolArgs {
878
883
  "tv-remote": {
879
884
  /** Target TV device id from `list-devices` (Apple TV, Android TV, or Vega). */
880
885
  udid: string;
881
- /** 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. */
886
+ /** A single TV-remote button, or a path of them run in one call. Move focus with up/down/left/right, confirm with select, go back with back/menu, exit with home; the media and volume buttons press the matching remote keys. 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. */
882
887
  button: "up" | "down" | "left" | "right" | "select" | "back" | "home" | "menu" | "playPause" | "rewind" | "fastForward" | "next" | "previous" | "volumeUp" | "volumeDown" | "mute" | Array<"up" | "down" | "left" | "right" | "select" | "back" | "home" | "menu" | "playPause" | "rewind" | "fastForward" | "next" | "previous" | "volumeUp" | "volumeDown" | "mute">;
883
888
  /** Repeat the whole `button` value this many times (default 1). Compact for long same-button runs, e.g. { button: "down", repeat: 12 }. */
884
889
  repeat?: number;
@@ -892,7 +897,7 @@ export interface ArgentToolArgs {
892
897
  target?: "auto" | "global" | "local" | "both";
893
898
  };
894
899
  "view-network-logs": {
895
- /** 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. */
900
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
896
901
  port?: number;
897
902
  /** Device id from list-devices (iOS simulator UDID or Android serial), the same id used with debugger-connect. */
898
903
  device_id: string;
@@ -900,13 +905,13 @@ export interface ArgentToolArgs {
900
905
  pageIndex?: number | "latest";
901
906
  };
902
907
  "view-network-request-details": {
903
- /** 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. */
908
+ /** Metro port. Omit it to use this device's port (8081 by default). Ignored for Chromium, whose CDP port is in device_id. */
904
909
  port?: number;
905
910
  /** Device id from list-devices (iOS simulator UDID or Android serial), the same id used with debugger-connect. An android- ID needs no debugger connection. */
906
911
  device_id: string;
907
- /** The requestId from view-network-logs, or an android- ID from native-network-logs */
912
+ /** The requestId from view-network-logs, or an android- ID from native-network-logs. */
908
913
  requestId: string;
909
- /** Whether to include the response body (if captured). Defaults to true. */
914
+ /** Whether to include the response body (if captured). */
910
915
  includeBody?: boolean;
911
916
  };
912
917
  /** @deprecated Renamed to `e2e-add-echo`. */