@swmansion/argent 0.22.2-next.4 → 0.22.2-next.5

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.
package/dist/cli-cmds.mjs CHANGED
@@ -2815,6 +2815,10 @@ var FLAG_REGISTRY = [
2815
2815
  name: "disable-auto-screenshot",
2816
2816
  description: "Disable the automatic screenshot captured after interaction tools."
2817
2817
  },
2818
+ {
2819
+ name: "disable-auto-describe",
2820
+ description: "Disable the accessibility element tree appended after interaction tools."
2821
+ },
2818
2822
  {
2819
2823
  name: "argent-lens",
2820
2824
  description: "Argent Lens \u2014 the propose_variant / await_user_selection tools and the Electron preview window for staging UI design variants and letting a human pick among them. Off by default while the feature is in development."
@@ -7210,7 +7214,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
7210
7214
  var SESSION_ID2 = randomUUID5();
7211
7215
  function readCliVersion() {
7212
7216
  if (true) {
7213
- return "0.22.2-next.4";
7217
+ return "0.22.2-next.5";
7214
7218
  }
7215
7219
  return "0.0.0";
7216
7220
  }
@@ -16428,7 +16428,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
16428
16428
  var SESSION_ID = randomUUID4();
16429
16429
  function readCliVersion() {
16430
16430
  if (true) {
16431
- return "0.22.2-next.4";
16431
+ return "0.22.2-next.5";
16432
16432
  }
16433
16433
  return "0.0.0";
16434
16434
  }
@@ -18491,7 +18491,7 @@ async function stepArtifactBlocks(artifacts, status, ctx, depth) {
18491
18491
  return blocks;
18492
18492
  }
18493
18493
 
18494
- // ../argent-mcp/src/auto-screenshot.ts
18494
+ // ../argent-mcp/src/auto-capture.ts
18495
18495
  var AUTO_SCREENSHOT_TOOLS = /* @__PURE__ */ new Set([
18496
18496
  "gesture-tap",
18497
18497
  "gesture-swipe",
@@ -18532,6 +18532,30 @@ var DEFAULT_DELAY_MS = 1400;
18532
18532
  function autoScreenshotEnabled(options) {
18533
18533
  return !isFlagEnabled("disable-auto-screenshot", options);
18534
18534
  }
18535
+ var AUTO_DESCRIBE_TOOLS = /* @__PURE__ */ new Set([
18536
+ "gesture-tap",
18537
+ "gesture-swipe",
18538
+ "gesture-scroll",
18539
+ "gesture-drag",
18540
+ "gesture-custom",
18541
+ "gesture-pinch",
18542
+ "gesture-rotate",
18543
+ "button",
18544
+ "keyboard",
18545
+ "paste",
18546
+ "rotate",
18547
+ "launch-app",
18548
+ "restart-app",
18549
+ "open-url",
18550
+ "run-sequence"
18551
+ ]);
18552
+ function autoDescribeEnabled(options) {
18553
+ return !isFlagEnabled("disable-auto-describe", options);
18554
+ }
18555
+ var AUTO_DESCRIBE_HEADER = "--- Elements after action (describe) ---";
18556
+ function shouldAutoDescribe(toolName) {
18557
+ return AUTO_DESCRIBE_TOOLS.has(normalizeToolName(toolName));
18558
+ }
18535
18559
  var SECRET_PLACEHOLDER_MARKER = "{{secret:";
18536
18560
  function containsSecretPlaceholder(args) {
18537
18561
  try {
@@ -18628,6 +18652,7 @@ async function startMcpServer(options) {
18628
18652
  markFirstRunNoticeShown();
18629
18653
  }
18630
18654
  const autoScreenshotOn = autoScreenshotEnabled();
18655
+ const autoDescribeOn = autoDescribeEnabled();
18631
18656
  let TOOLS_URL;
18632
18657
  let AUTH_TOKEN;
18633
18658
  const resolved = await getResolvedToolsUrl();
@@ -18715,7 +18740,7 @@ async function startMcpServer(options) {
18715
18740
  { name: "argent", version: getInstalledVersion() },
18716
18741
  {
18717
18742
  capabilities: { tools: {} },
18718
- instructions: "Argent \u2014 iOS Simulator, Android Emulator, and Chromium app control for interacting, testing, profiling and debugging mobile and Chromium applications. Always use discovery tools (describe / debugger-component-tree / screenshot) before tapping \u2014 never guess coordinates. On session end: call stop-all-simulator-servers with devices: [...] naming the devices this session used, and perform any necessary cleanup. One tool-server is shared by every agent using this argent install, so an unscoped call tears down their devices too \u2014 reserve it for a deliberate machine-wide cleanup. Full guidance is in the argent rule loaded from .claude/rules/argent.md."
18743
+ instructions: "Argent \u2014 iOS Simulator, Android Emulator, and Chromium app control for interacting, testing, profiling and debugging mobile and Chromium applications. Interaction tools return the screen after the action: a screenshot plus the accessibility element tree with normalized tap frames. Take coordinates from that tree; call describe (or debugger-component-tree) only when no fresh tree is available \u2014 never guess coordinates from pixels. On session end: call stop-all-simulator-servers with devices: [...] naming the devices this session used, and perform any necessary cleanup. One tool-server is shared by every agent using this argent install, so an unscoped call tears down their devices too \u2014 reserve it for a deliberate machine-wide cleanup. Full guidance is in the argent rule loaded from .claude/rules/argent.md."
18719
18744
  }
18720
18745
  );
18721
18746
  server.setRequestHandler(ListToolsRequestSchema, async () => {
@@ -18767,15 +18792,17 @@ async function startMcpServer(options) {
18767
18792
  content = await toMcpContent(result, outputHint, ctx, params.arguments);
18768
18793
  }
18769
18794
  const udid = getUdidFromArgs(params.arguments);
18770
- if (autoScreenshotOn && udid && shouldAutoScreenshot(params.name) && containsSecretPlaceholder(params.arguments)) {
18795
+ const wantScreenshot = autoScreenshotOn && shouldAutoScreenshot(params.name);
18796
+ const wantTree = autoDescribeOn && shouldAutoDescribe(params.name);
18797
+ if (udid && (wantScreenshot || wantTree) && containsSecretPlaceholder(params.arguments)) {
18771
18798
  content = [
18772
18799
  ...content,
18773
18800
  {
18774
18801
  type: "text",
18775
- text: "Auto-screenshot skipped: the input contains a {{secret:\u2026}} placeholder, and a screenshot of this screen could reveal the typed secret. The secret is already typed \u2014 do not send the typing step again, or the field will hold two copies of it. Submit or navigate away, then verify the resulting screen as usual. Only this call is covered: the next call is screenshotted normally, and captures the secret if the field is still on screen. To cover the submit as well, put the typing and the submit in ONE `run-sequence` the next time you type a secret."
18802
+ text: "Auto-screenshot and element tree skipped: the input contains a {{secret:\u2026}} placeholder, and a capture of this screen could reveal the typed secret. The secret is already typed \u2014 do not send the typing step again, or the field will hold two copies of it. Submit or navigate away, then verify the resulting screen as usual. Only this call is covered: the next call is captured normally, and shows the secret if the field is still on screen. To cover the submit as well, put the typing and the submit in ONE `run-sequence` the next time you type a secret."
18776
18803
  }
18777
18804
  ];
18778
- } else if (autoScreenshotOn && udid && shouldAutoScreenshot(params.name)) {
18805
+ } else if (udid && (wantScreenshot || wantTree)) {
18779
18806
  const maxWaitMs = getAutoScreenshotDelayMs(params.name);
18780
18807
  if (maxWaitMs > 0) {
18781
18808
  try {
@@ -18791,25 +18818,56 @@ async function startMcpServer(options) {
18791
18818
  await new Promise((r) => setTimeout(r, maxWaitMs));
18792
18819
  }
18793
18820
  }
18794
- try {
18795
- const screenshotResult = await callTool("screenshot", { udid });
18796
- const screenshotContent = await toMcpContent(screenshotResult.result, "image", {
18797
- toolsUrl: TOOLS_URL,
18798
- authToken: AUTH_TOKEN,
18799
- deviceId: udid
18800
- });
18801
- const hasImage = screenshotContent.some((b) => b.type === "image");
18802
- if (hasImage) {
18803
- content = [
18804
- ...content,
18805
- {
18806
- type: "text",
18807
- text: "--- Screen after action ---"
18808
- },
18809
- ...screenshotContent
18810
- ];
18821
+ if (wantScreenshot) {
18822
+ try {
18823
+ const screenshotResult = await callTool("screenshot", { udid });
18824
+ const screenshotContent = await toMcpContent(screenshotResult.result, "image", {
18825
+ toolsUrl: TOOLS_URL,
18826
+ authToken: AUTH_TOKEN,
18827
+ deviceId: udid
18828
+ });
18829
+ const hasImage = screenshotContent.some((b) => b.type === "image");
18830
+ if (hasImage) {
18831
+ content = [
18832
+ ...content,
18833
+ {
18834
+ type: "text",
18835
+ text: "--- Screen after action ---"
18836
+ },
18837
+ ...screenshotContent
18838
+ ];
18839
+ }
18840
+ } catch {
18841
+ }
18842
+ }
18843
+ if (wantTree) {
18844
+ const t1 = Date.now();
18845
+ try {
18846
+ const d = await callTool("describe", { udid });
18847
+ const desc = d.result?.description;
18848
+ if (typeof desc === "string" && desc.length > 0) {
18849
+ content = [
18850
+ ...content,
18851
+ { type: "text", text: `${AUTO_DESCRIBE_HEADER}
18852
+ ${desc}` }
18853
+ ];
18854
+ }
18855
+ await spyLog({
18856
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
18857
+ event: "auto_describe",
18858
+ name: params.name,
18859
+ durationMs: Date.now() - t1,
18860
+ chars: typeof desc === "string" ? desc.length : 0
18861
+ });
18862
+ } catch (e) {
18863
+ await spyLog({
18864
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
18865
+ event: "auto_describe",
18866
+ name: params.name,
18867
+ durationMs: Date.now() - t1,
18868
+ error: String(e instanceof Error ? e.message : e)
18869
+ });
18811
18870
  }
18812
- } catch {
18813
18871
  }
18814
18872
  }
18815
18873
  if (note) {
@@ -89995,6 +89995,10 @@ var FLAG_REGISTRY = [
89995
89995
  name: "disable-auto-screenshot",
89996
89996
  description: "Disable the automatic screenshot captured after interaction tools."
89997
89997
  },
89998
+ {
89999
+ name: "disable-auto-describe",
90000
+ description: "Disable the accessibility element tree appended after interaction tools."
90001
+ },
89998
90002
  {
89999
90003
  name: "argent-lens",
90000
90004
  description: "Argent Lens \u2014 the propose_variant / await_user_selection tools and the Electron preview window for staging UI design variants and letting a human pick among them. Off by default while the feature is in development."
@@ -93886,7 +93890,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
93886
93890
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
93887
93891
  function readCliVersion() {
93888
93892
  if (true) {
93889
- return "0.22.2-next.4";
93893
+ return "0.22.2-next.5";
93890
93894
  }
93891
93895
  return "0.0.0";
93892
93896
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.22.2-next.4",
3
+ "version": "0.22.2-next.5",
4
4
  "mcpName": "io.github.software-mansion/argent",
5
5
  "description": "MCP server for iOS Simulator and Android Emulator control",
6
6
  "license": "Apache-2.0",
package/rules/argent.md CHANGED
@@ -36,8 +36,10 @@ If argent is ABSENT, treat it as an expected state, not an error to retry. Do no
36
36
  > </availability_check>
37
37
 
38
38
  <tapping_rule>
39
- <important>**Never** derive tap coordinates from a screenshot</important>
40
- Before **every** tap, you MUST call a discovery tool and extract coordinates from the result. This is not optional. Preferred tools are, in order:
39
+ <important>**Never** derive tap coordinates from screenshot pixels</important>
40
+ Interaction tools (`gesture-tap`, `gesture-swipe`, `keyboard`, `button`, `launch-app`, `open-url`, `run-sequence`, …) return the screen **after** the action: a screenshot AND the accessibility element tree (`--- Elements after action (describe) ---`, the same format `describe` prints, with normalized 0–1 frames). Take tap coordinates from that tree — the centre of the element's frame (`x + width/2`, `y + height/2`). You do not need a separate discovery call before a tap when the last result already lists the target.
41
+
42
+ Call a discovery tool yourself only when you have no fresh tree for the current screen — before the first action on a screen you have not touched yet, after waiting for something to load, or when the last tree did not list your target. Preferred tools are, in order:
41
43
 
42
44
  - `describe` - native app-level components and safely targetable foreground apps (iOS and Android).
43
45
  - `native-describe-screen` - accessibility screen description via injected native devtools (iOS only)
@@ -45,9 +47,7 @@ Before **every** tap, you MUST call a discovery tool and extract coordinates fro
45
47
 
46
48
  `native-user-interactable-view-at-point` / `native-view-at-point` are follow-up diagnostics once you already have a candidate point (iOS only).
47
49
 
48
- Whenever something changed YOU MUST first call `describe`, or another appropriate discovery tool so you do not hallucinate element positions. Do not guess coordinates if you can use discovery tool. Do not tap if you have not called a discovery tool in the current step. Screenshots alone are never sufficient for coordinates.
49
-
50
- If a **tap fails twice** at the same coordinates, **stop retrying**. Re-run the discovery tool.
50
+ If a **tap fails twice** at the same coordinates, **stop retrying** and re-run a discovery tool.
51
51
 
52
52
  If `describe` fails, **read the exact error before reacting**, follow the recovery guidance in `argent-device-interact` to choose the correct next action.
53
53
 
@@ -73,8 +73,8 @@ Decision order:
73
73
  - All simulator/emulator interactions go through argent MCP tools — never use `xcrun simctl`,
74
74
  raw `curl` to simulator ports, or the simulator-server binary directly.
75
75
  - Before calling any gesture tool for the first time, use ToolSearch to load its schema.
76
- - Interaction tools (`gesture-tap`, `gesture-swipe`, `gesture-pinch`, `gesture-rotate`, `gesture-custom`, `launch-app`, etc.) return a screenshot automatically.
77
- Call `screenshot` separately only for a baseline before any action or after a delay.
76
+ - Interaction tools (`gesture-tap`, `gesture-swipe`, `gesture-pinch`, `gesture-rotate`, `gesture-custom`, `launch-app`, etc.) return a screenshot and the element tree automatically.
77
+ Call `screenshot` or `describe` separately only for a baseline before any action or after a delay.
78
78
  - Always open apps with `launch-app` or `open-url` — never tap home screen icons.
79
79
  - If a task can require a saved flow, choose `argent-create-flow` or `argent-qa-flows` before the first launch or in-app action. Start the recorder before walking the path; recording is not retroactive.
80
80
  - Always use `run-sequence` when performing multiple sequential device actions where you don't need to observe the screen between steps. More in `argent-device-interact` skill.
@@ -32,7 +32,7 @@ Use `list-devices` to get a target id. Results are tagged with `platform` (`ios`
32
32
  3. **Use `gesture-swipe` for lists/scrolling**, not `gesture-custom`, unless you need non-linear movement. On Chromium use `gesture-scroll` instead — `gesture-swipe` is touch-only. Consider whether you need multiple swipes, if yes - use `run-sequence`. Pass `momentum: false` when the swipe should decelerate before ending for a precise movement.
33
33
  4. **Tap a text field before typing**, then use `keyboard` to enter text.
34
34
  5. **Coordinates are normalized** — always 0.0–1.0, not pixels.
35
- 6. **For app navigation, prefer `describe` first.** It works on any screen without app restart. Do not navigate from screenshots on regular in-app screens unless `describe` failed to expose a reliable target. Use `native-describe-screen` only when you need app-scoped UIKit properties.
35
+ 6. **For app navigation, use the element tree returned after each action** (`--- Elements after action (describe) ---`); call `describe` only when no fresh tree is available for the current screen. It works on any screen without app restart. Do not navigate from screenshot pixels on regular in-app screens unless the tree failed to expose a reliable target. Use `native-describe-screen` only when you need app-scoped UIKit properties.
36
36
 
37
37
  ## 3. Opening Apps
38
38