@swmansion/argent 0.10.0 → 0.12.0

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 (63) hide show
  1. package/README.md +4 -1
  2. package/assets/argent.tracecfg.pbtxt +133 -0
  3. package/assets/queries/README.md +93 -0
  4. package/assets/queries/cpu-hotspots.sql +106 -0
  5. package/assets/queries/function-callers.sql +62 -0
  6. package/assets/queries/hang-folds-batched.sql +88 -0
  7. package/assets/queries/hang-main-thread-samples.sql +32 -0
  8. package/assets/queries/hang-state-breakdown.sql +44 -0
  9. package/assets/queries/memory-rss.sql +25 -0
  10. package/assets/queries/thread-breakdown.sql +34 -0
  11. package/assets/queries/trace-bounds.sql +6 -0
  12. package/assets/queries/ui-hangs.sql +59 -0
  13. package/assets/trace-processor/LICENSE +235 -0
  14. package/assets/trace-processor/SHA256SUMS +4 -0
  15. package/assets/trace-processor/engine.mjs +42423 -0
  16. package/assets/trace-processor/engine_bundle.node.js +11130 -0
  17. package/assets/trace-processor/trace_processor.wasm +0 -0
  18. package/{dist → bin}/argent-android-devtools-0.1.0.apk +0 -0
  19. package/bin/argent-simulator-server.cjs +11 -3
  20. package/bin/darwin/ax-service +0 -0
  21. package/bin/darwin/resources/android/LICENSE.txt +186 -0
  22. package/bin/darwin/resources/android/README.md +11 -0
  23. package/bin/darwin/resources/android/arm64-v8a/libscreen-sharing-agent.so +0 -0
  24. package/bin/darwin/resources/android/armeabi-v7a/libscreen-sharing-agent.so +0 -0
  25. package/bin/darwin/resources/android/screen-sharing-agent.jar +0 -0
  26. package/bin/darwin/resources/android/x86_64/libscreen-sharing-agent.so +0 -0
  27. package/bin/darwin/simulator-server +0 -0
  28. package/bin/linux/resources/android/LICENSE.txt +186 -0
  29. package/bin/linux/resources/android/README.md +11 -0
  30. package/bin/linux/resources/android/arm64-v8a/libscreen-sharing-agent.so +0 -0
  31. package/bin/linux/resources/android/armeabi-v7a/libscreen-sharing-agent.so +0 -0
  32. package/bin/linux/resources/android/screen-sharing-agent.jar +0 -0
  33. package/bin/linux/resources/android/x86_64/libscreen-sharing-agent.so +0 -0
  34. package/bin/linux/simulator-server +0 -0
  35. package/bin/linux-arm64/resources/android/LICENSE.txt +186 -0
  36. package/bin/linux-arm64/resources/android/README.md +11 -0
  37. package/bin/linux-arm64/resources/android/arm64-v8a/libscreen-sharing-agent.so +0 -0
  38. package/bin/linux-arm64/resources/android/armeabi-v7a/libscreen-sharing-agent.so +0 -0
  39. package/bin/linux-arm64/resources/android/screen-sharing-agent.jar +0 -0
  40. package/bin/linux-arm64/resources/android/x86_64/libscreen-sharing-agent.so +0 -0
  41. package/bin/linux-arm64/simulator-server +0 -0
  42. package/dist/cli-cmds.mjs +1858 -1578
  43. package/dist/cli.js +0 -3
  44. package/dist/cli.js.map +1 -1
  45. package/dist/installer.mjs +119 -96
  46. package/dist/mcp-server.mjs +452 -92
  47. package/dist/preview-ui/index.html +4500 -645
  48. package/dist/preview-ui/theme.css +231 -0
  49. package/dist/preview-window/main.cjs +182 -0
  50. package/dist/tool-server.cjs +11265 -5220
  51. package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
  52. package/dylibs/libKeyboardPatch.dylib +0 -0
  53. package/dylibs/libNativeDevtoolsIos.dylib +0 -0
  54. package/package.json +5 -2
  55. package/rules/argent.md +8 -2
  56. package/scripts/postinstall.cjs +6 -2
  57. package/skills/argent-device-interact/SKILL.md +36 -28
  58. package/skills/argent-lens/SKILL.md +101 -0
  59. package/skills/argent-metro-debugger/SKILL.md +18 -16
  60. package/skills/argent-native-profiler/SKILL.md +5 -5
  61. package/skills/argent-react-native-app-workflow/SKILL.md +8 -8
  62. /package/{dist → assets}/Argent.tracetemplate +0 -0
  63. /package/{manifest.json → assets/manifest.json} +0 -0
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "MCP server for iOS Simulator and Android Emulator control",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -37,12 +37,15 @@
37
37
  "skills/",
38
38
  "agents/",
39
39
  "rules/",
40
- "manifest.json",
40
+ "assets/",
41
41
  "scripts/postinstall.cjs"
42
42
  ],
43
43
  "dependencies": {
44
44
  "@modelcontextprotocol/sdk": "^1.20.0"
45
45
  },
46
+ "optionalDependencies": {
47
+ "electron": "^42.4.1"
48
+ },
46
49
  "devDependencies": {
47
50
  "@argent/cli": "file:../argent-cli",
48
51
  "@argent/installer": "file:../argent-installer",
package/rules/argent.md CHANGED
@@ -4,7 +4,7 @@ alwaysApply: true
4
4
  ---
5
5
 
6
6
  <description>
7
- Argent MCP tools are available in this project for iOS simulator and Android emulator control. Argent MCP tools are the preferred form of interaction with the application.
7
+ Argent MCP tools are available in this project for iOS simulator, Android emulator, and Chromium (CDP) app control. Argent MCP tools are the preferred form of interaction with the application. A "Chromium (CDP) app" is any Chromium runtime exposing a Chrome DevTools Protocol endpoint — an Electron app, or any Chromium-family browser (Chrome/Brave/Edge) launched with `--remote-debugging-port`; all are driven through the same tool surface and tagged `platform: "chromium"`.
8
8
  Running MCP server and managing the Argent toolkit utilises `argent` command - if asked use `argent --help` for reference.
9
9
  To check current version of MCP server run `argent --version` command.
10
10
 
@@ -17,6 +17,7 @@ Use cases:
17
17
  - Any request to execute manual QA, UI QA, or visual behavior validation for a mobile app
18
18
  - Running, debugging, or testing a React Native app (iOS or Android)
19
19
  - Profiling performance or diagnosing re-renders in a React Native app (iOS or Android)
20
+ - Running, debugging, or testing a Chromium (CDP) app — an Electron app (boot with `boot-device` + `electronAppPath`) or a Chromium browser exposing CDP (auto-discovered on port `9222` / `ARGENT_CHROMIUM_PORTS`); on Chromium scroll with `gesture-scroll` and drag with `gesture-drag` — `gesture-swipe` is touch-only
20
21
  </description>
21
22
 
22
23
  <tapping_rule>
@@ -44,7 +45,7 @@ Before booting, running, or interacting with any app, call `list-devices` first
44
45
  Decision order:
45
46
 
46
47
  1. **Explicit user intent** - choose the user named platform or device. Look for words "simulator" and "emulator".
47
- 2. **Prefer a running device.** iOS simulators - state `Booted` and Android devices - `state: "device"` come first in `list-devices`.
48
+ 2. **Prefer a running device.** iOS simulators - state `Booted` and Android devices - `state: "device"` come first in `list-devices`; Chromium (CDP) apps appear as `platform: "chromium"`, `state: "Running"`.
48
49
  3. **Single-platform project:** (per `argent-environment-inspector` flags `is_native_ios`/`is_native_android`, or RN with only one platform configured) → boot that platform.
49
50
  </device_selection_rule>
50
51
 
@@ -128,6 +129,11 @@ RECORDING & REPLAYING FLOWS
128
129
  Use skill: `argent-create-flow`
129
130
  When: A multi-step interaction sequence needs to be repeated — re-profiling after a fix, A/B comparisons, regression checks, user says "again" / "run that flow", or you worked through a complex path worth saving. Also use proactively: if you are about to repeat steps you already performed, record first, then replay.
130
131
  Prompt keywords: flow, repeat, test X times
132
+
133
+ PROPOSING DESIGN VARIANTS FOR HUMAN SELECTION
134
+ Use skill: `argent-lens`
135
+ When: The user asks for design alternatives / options / A-B choices for a screen or component, or you have produced more than one candidate look for an element and want a human to pick before committing. Covers the build → navigate → screenshot → propose_variant loop and the single blocking await_user_selection call. (Gated behind the `argent-lens` flag, off by default — run `argent enable argent-lens` first.)
136
+ Prompt keywords: variant, design option, alternative, A/B, "let me pick", "show me options"
131
137
  </skill_routing>
132
138
 
133
139
  <subagents>
@@ -15,10 +15,14 @@ try {
15
15
  if (state && state.pid) {
16
16
  try {
17
17
  process.kill(state.pid, "SIGTERM");
18
- } catch {}
18
+ } catch {
19
+ /* process already gone — nothing to kill */
20
+ }
19
21
  }
20
22
  fs.unlinkSync(stateFile);
21
- } catch {}
23
+ } catch {
24
+ /* no state file or unreadable — nothing to clean up */
25
+ }
22
26
 
23
27
  if (process.env.ARGENT_SKIP_POSTINSTALL === "1") {
24
28
  process.exit(0);
@@ -1,11 +1,17 @@
1
1
  ---
2
2
  name: argent-device-interact
3
- description: Interact with an iOS simulator or Android emulator using argent MCP tools. Use when tapping UI elements, performing gestures, scrolling/swiping, typing text, pressing hardware buttons, launching apps, opening URLs, taking screenshots, or checking visible app state after interactions.
3
+ description: Interact with an iOS simulator, Android emulator, or Chromium (CDP) app using argent MCP tools. Use when tapping UI elements, performing gestures, scrolling/swiping, typing text, pressing hardware buttons, launching apps, opening URLs, taking screenshots, or checking visible app state after interactions.
4
4
  ---
5
5
 
6
6
  ## Unified tool surface
7
7
 
8
- All interaction tools below accept a `udid` parameter and auto-dispatch iOS vs Android based on its shape (UUID → iOS simulator, anything else → Android adb serial). You use the same tool names on both platforms.
8
+ All interaction tools below accept a `udid` parameter and auto-dispatch iOS vs Android based on its shape (UUID → iOS simulator, `chromium-cdp-<port>` → Chromium (CDP) app, anything else → Android adb serial). You use the same tool names on every platform.
9
+
10
+ **Chromium (CDP) app** = any Chromium runtime exposing a Chrome DevTools Protocol endpoint: an Electron app (boot it with `boot-device` + `electronAppPath`), or any Chromium-family browser (Chrome/Brave/Edge) launched with `--remote-debugging-port`. The latter is auto-discovered by `list-devices` on port `9222` plus anything in `ARGENT_CHROMIUM_PORTS`. The same describe/tap/swipe/keyboard/screenshot surface drives all of them.
11
+
12
+ **Multi-tab / windows (Chromium only):** a Chromium device may have several tabs / BrowserWindows. Use `chromium-tabs` to `list` them (stable ids `t1`, `t2`, …, optional labels), open a `new` one, `select` which is active, or `close` one. Every other tool (`describe`, `gesture-tap`, `screenshot`, `debugger-evaluate`, `open-url`, …) acts on the **active** tab, so `chromium-tabs action=select` before driving a different tab. Note: a cross-process navigation (some redirects) can swap a tab's underlying CDP target — re-run `chromium-tabs action=list` to pick it up under a fresh id.
13
+
14
+ **Cookies & storage (Chromium only):** `chromium-cookies` reads/writes cookies via the Network domain (so HttpOnly cookies are visible): `action=get` (optionally scoped by `url`), `set` (`name`, `value`, + `url`/`domain`, optional `secure`/`httpOnly`/`sameSite`/`expires`), `delete` (`name`), `clear` (all). `chromium-storage` reads/writes Web Storage for the active page: `store=local|session`, `action=get` (one `key` or all entries), `set`, `remove`, `clear`. Both are per-origin / active-tab. Handy for seeding auth before a flow or asserting app state after one.
9
15
 
10
16
  For platform-specific caveats (Metro `adb reverse`, locked-screen describe errors, etc.), see § 9 Platform-specific notes at the bottom.
11
17
 
@@ -13,7 +19,7 @@ For platform-specific caveats (Metro `adb reverse`, locked-screen describe error
13
19
 
14
20
  If you delegate simulator tasks to sub-agents, make sure they have MCP permissions.
15
21
 
16
- Use `list-devices` to get a target id. Results are tagged with `platform` (`ios` or `android`); booted/ready devices come first. Pick the first entry that matches the platform you need — if none are ready, call `boot-device` with `udid` (iOS) or `avdName` (Android). See `argent-ios-simulator-setup` / `argent-android-emulator-setup` for full setup flow.
22
+ Use `list-devices` to get a target id. Results are tagged with `platform` (`ios`, `android`, or `chromium`); booted/ready devices come first. Pick the first entry that matches the platform you need — if none are ready, call `boot-device` with `udid` (iOS), `avdName` (Android), or `electronAppPath` (boots an Electron app as a `chromium` device). A Chromium browser already running with a CDP port shows up directly — no `boot-device` needed. See `argent-ios-simulator-setup` / `argent-android-emulator-setup` for full setup flow.
17
23
 
18
24
  **Load tool schemas before first use.** Gesture tools (`gesture-tap`, `gesture-swipe`, `gesture-pinch`, `gesture-rotate`, `gesture-custom`) may be deferred — their parameter schemas are not loaded until fetched. Always use ToolSearch to load the schemas of all gesture tools you plan to use **before** calling any of them. If you skip this step, parameters may be coerced to strings instead of numbers, causing validation errors.
19
25
 
@@ -21,7 +27,7 @@ Use `list-devices` to get a target id. Results are tagged with `platform` (`ios`
21
27
 
22
28
  1. **Always refer to tapping_rule** from your argent.md rule before tapping.
23
29
  2. Before performing interactions, consider whether they can be **dispatched sequentially** - more on that in `run-sequence`.
24
- 3. **Use `gesture-swipe` for lists/scrolling**, not `gesture-custom`, unless you need non-linear movement. Consider whether you need multiple swipes, if yes - use `run-sequence`.
30
+ 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`.
25
31
  4. **Tap a text field before typing** — on iOS try `paste` first then fall back to `keyboard`; on Android use `keyboard` directly (`paste` is iOS-only).
26
32
  5. **Coordinates are normalized** — always 0.0–1.0, not pixels.
27
33
  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.
@@ -48,35 +54,37 @@ Common schemes: `messages://`, `settings://`, `maps://?q=<query>`, `tel://<numbe
48
54
 
49
55
  ## 4. Choosing the Right Tool
50
56
 
51
- | Action | Tool | Notes |
52
- | ---------------- | ---------------- | ---------------------------------------------------------------------- |
53
- | Multiple actions | `run-sequence` | Batch steps in one call (no intermediate screenshots) |
54
- | Open an app | `launch-app` | **Always — never tap home-screen icons** |
55
- | Restart an app | `restart-app` | Terminate and relaunch by bundle ID |
56
- | Open URL/scheme | `open-url` | Web pages, deep links, URL schemes |
57
- | Single tap | `gesture-tap` | Buttons, links, checkboxes |
58
- | Scroll/swipe | `gesture-swipe` | Straight-line scroll or swipe |
59
- | Long press | `gesture-custom` | Context menus, drag start |
60
- | Drag & drop | `gesture-custom` | Complex drag interactions |
61
- | Pinch/zoom | `gesture-pinch` | Two-finger pinch with auto-interpolation |
62
- | Rotation | `gesture-rotate` | Two-finger rotation with auto-interpolation |
63
- | Custom gesture | `gesture-custom` | Arbitrary touch sequences, optional interpolation |
64
- | Hardware key | `button` | Home, back, power, volume, appSwitch, actionButton |
65
- | Type text (fast) | `paste` | iOS only. Form fields — uses clipboard |
66
- | Type text | `keyboard` | iOS+Android. Fallback when paste fails; supports Enter, Escape, arrows |
67
- | Rotate device | `rotate` | Orientation changes |
57
+ | Action | Tool | Notes |
58
+ | ----------------- | ---------------- | ---------------------------------------------------------------------- |
59
+ | Multiple actions | `run-sequence` | Batch steps in one call (no intermediate screenshots) |
60
+ | Open an app | `launch-app` | **Always — never tap home-screen icons** |
61
+ | Restart an app | `restart-app` | Terminate and relaunch by bundle ID |
62
+ | Open URL/scheme | `open-url` | Web pages, deep links, URL schemes |
63
+ | Single tap | `gesture-tap` | Buttons, links, checkboxes |
64
+ | Scroll/swipe | `gesture-swipe` | Straight-line scroll or swipe |
65
+ | Scroll (Chromium) | `gesture-scroll` | Wheel-based; deltas are window fractions, positive deltaY = down |
66
+ | Drag (Chromium) | `gesture-drag` | Sliders, drag-and-drop, text selection |
67
+ | Long press | `gesture-custom` | Context menus, drag start |
68
+ | Drag & drop | `gesture-custom` | Complex drag interactions |
69
+ | Pinch/zoom | `gesture-pinch` | Two-finger pinch with auto-interpolation |
70
+ | Rotation | `gesture-rotate` | Two-finger rotation with auto-interpolation |
71
+ | Custom gesture | `gesture-custom` | Arbitrary touch sequences, optional interpolation |
72
+ | Hardware key | `button` | Home, back, power, volume, appSwitch, actionButton |
73
+ | Type text (fast) | `paste` | iOS only. Form fields — uses clipboard |
74
+ | Type text | `keyboard` | iOS+Android. Fallback when paste fails; supports Enter, Escape, arrows |
75
+ | Rotate device | `rotate` | Orientation changes |
68
76
 
69
77
  ## 5. Finding Tap Targets
70
78
 
71
79
  IMPORTANT. When moved to a different screen after an action or do not know the coordinates of component, **always** perform proper discovery first.
72
80
 
73
- | App type | Discovery tool | What it returns |
74
- | --------------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
75
- | Target app discovery | `describe` | Accessibility element tree for the current device screen (iOS AX-service or Android uiautomator) with normalized frame coordinates. Works on any app, system dialogs, and Home screen — no app restart or `bundleId` required |
76
- | React Native | `debugger-component-tree` | React component tree with names, text, testID, and (tap: x,y) |
77
- | App-scoped native | `native-describe-screen` | Low-level app-scoped accessibility elements with normalized and raw coordinates; requires `bundleId` |
78
- | Permission / system modal overlay | `describe` | `describe` detects system dialogs automatically and returns dialog buttons with tap coordinates. Fall back to `screenshot` only if `describe` does not expose the controls |
79
- | Final visual fallback | `screenshot` | Use only when discovery tools cannot inspect the current UI reliably. Do not derive routine in-app navigation targets from screenshots |
81
+ | App type | Discovery tool | What it returns |
82
+ | --------------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
83
+ | Target app discovery | `describe` | Accessibility element tree for the current device screen (iOS AX-service, Android uiautomator, or Chromium DOM walker) with normalized frame coordinates. Works on any app, system dialogs, and Home screen — no app restart or `bundleId` required |
84
+ | React Native | `debugger-component-tree` | React component tree with names, text, testID, and (tap: x,y) |
85
+ | App-scoped native | `native-describe-screen` | Low-level app-scoped accessibility elements with normalized and raw coordinates; requires `bundleId` |
86
+ | Permission / system modal overlay | `describe` | `describe` detects system dialogs automatically and returns dialog buttons with tap coordinates. Fall back to `screenshot` only if `describe` does not expose the controls |
87
+ | Final visual fallback | `screenshot` | Use only when discovery tools cannot inspect the current UI reliably. Do not derive routine in-app navigation targets from screenshots |
80
88
 
81
89
  Point follow-up native diagnostics after you already have a candidate point:
82
90
 
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: argent-lens
3
+ description: Propose multiple visual design variants for on-screen elements and let the human pick in the Argent Lens window. Use when the user asks for design alternatives / options / A-B choices for a screen or component, or any time you have produced more than one candidate look for an element and want a human decision before committing.
4
+ ---
5
+
6
+ > **Prerequisite — feature flag.** This workflow is gated behind the `argent-lens` flag (off by default). Run `argent enable argent-lens` once before using it. If `propose_variant` / `await_user_selection` come back not-found, the flag is off — enable it and retry.
7
+
8
+ ## 1. Overview
9
+
10
+ You implement several candidate designs, capture each one running on the device, and stage them with `propose_variant`. Each proposed element shows up as a floating card next to the live simulator stream in the Argent Lens window (a native window that opens automatically), connected by a thin line to the real element. The human picks per element, optionally pins free-form comments to elements, and presses **Complete selection**. `await_user_selection` is the single blocking call that returns their decision.
11
+
12
+ **The golden rule: one variant = one real, _distinct_ screenshot.** A proposal is only useful if its `previewImage` shows the variant actually rendered on the device, captured AFTER that specific variant was applied. Never propose a variant you have not built and seen on screen, and never point two variants at the same file path — if two captures end up byte-identical you have not actually changed anything and the Argent Lens degenerates to identical thumbnails. Plan → build → navigate → screenshot → propose, repeated for every variant of every element, then await once.
13
+
14
+ ## 2. Tools
15
+
16
+ | Tool | Blocking? | Purpose |
17
+ | ---------------------- | --------- | ----------------------------------------------------------------------- |
18
+ | `propose_variant` | No | Stage ONE variant for ONE element. Call once per variant. Keep working. |
19
+ | `await_user_selection` | Yes | Call ONCE after every variant is staged. Parks until the human is done. |
20
+
21
+ `propose_variant` params: `element` (human name), optional `match` (`{ by: "text"|"label"|"identifier"|"role", value }`), optional `udid` (the device id you captured the variants on), and `variant` (`{ name, summary, code?, filePath?, previewImage?, frame? }`). Repeated calls with the same `element` accumulate variants on that element; different `element` values create separate cards.
22
+
23
+ **Always pass `udid`** (the same simulator/emulator id you screenshotted and described with). The preview window then streams _that_ device directly — the human never has to pick a simulator. Set it on the first `propose_variant` of a round; later calls may omit it (the last value wins).
24
+
25
+ ## 3. Workflow
26
+
27
+ Resolve a simulator/emulator first (`argent-ios-simulator-setup` / `argent-android-emulator-setup`) and, for React Native, `argent-react-native-app-workflow` to run the app and reload the bundle. Argent shows the staged variants in a native preview window that opens automatically on the user's screen; you don't open or display anything yourself. Just stage variants and call `await_user_selection`, and the window appears on its own.
28
+
29
+ ### Step 0 — Plan the variants
30
+
31
+ Decide, before touching code, exactly which elements you are redesigning and the distinct variants for each. Write them down (e.g. "Search field: Filled / Outlined / Pill" — "Primary CTA: Solid / Gradient"). Each variant must be a single, self-contained change you can apply, screenshot, and revert independently. Vague or overlapping variants produce useless proposals.
32
+
33
+ ### Step 1 — Get a precise matcher
34
+
35
+ For each element, run `describe` (or `debugger-component-tree` for RN) on the screen where it lives and read its exact `label` / `identifier` / `role`. Pass that as `match` so the floating card's connector anchors to the right element:
36
+
37
+ - Stable testID / accessibilityIdentifier → `{ by: "identifier", value: "search-input" }` (most reliable)
38
+ - Exact a11y label → `{ by: "label", value: "Search" }`
39
+ - Otherwise → `{ by: "text", value: "Search" }` (fuzzy contains; the default if `match` is omitted)
40
+
41
+ Omitting `match` defaults to `{ by: "text", value: element }`, which is fine only when the element's visible text is unique.
42
+
43
+ ### Step 2 — For each variant: build → navigate → screenshot → propose
44
+
45
+ Loop over every variant of every element:
46
+
47
+ 1. **Build the variant.** Implement that one variant in code.
48
+ 2. **Apply it on the device.** Reload the RN bundle (`debugger-reload-metro`) or rebuild as needed so the running app shows this variant.
49
+ 3. **Navigate to it.** Drive the app (`argent-device-interact`) to the screen where the element is visible — a screenshot is only meaningful if the element is actually on screen.
50
+ 4. **Screenshot.** Call `screenshot` and pass the returned file path **straight through** as `variant.previewImage`. **NEVER hand-crop, resize, re-encode, or copy the screenshot to another folder** (e.g. a `crop.py` into `/tmp/variants/`): that double-crops against the preview window's own cropping and writes the image somewhere the server won't serve it ("No preview"). Capture the whole screen — the preview window crops it for you using `variant.frame` (step 5). The path you got back must be a NEW file; if you suspect the device froze or the variant didn't apply (you see no visible change vs. the previous capture), diff with the previous path (`shasum -a 256`) before proposing — byte-identical captures mean the variant is not on screen yet. Fix that before proposing, never propose anyway.
51
+ 5. **Propose.** Call `propose_variant` with `element`, `match`, `udid` (the device you captured on), and `variant.previewImage` set to that screenshot path. The tool **auto-captures the crop frame**: it describes the device at propose time and matches the element, so each thumbnail crops to its own current layout — **as long as the variant is still on screen when you call `propose_variant`** (propose right after the screenshot, before reverting). You may pass `variant.frame` (the matched node's normalized `{x, y, width, height}` in 0..1 from a `describe` on THIS variant) to override the auto-capture — useful when the element can't stay on screen at propose time. Add `summary` (what changed and why) and `code`/`filePath` when useful.
52
+ 6. **Revert.** Roll the variant change back before building the next one — only one variant can be on screen at a time. Keep going; `propose_variant` does not block.
53
+
54
+ `previewImage` accepts a local screenshot path (served from the OS temp dir / cwd), an `http(s)` URL, or a `data:` URI. A local screenshot of the real running variant is strongly preferred.
55
+
56
+ ### Step 3 — Await the human's decision (once)
57
+
58
+ After every variant for every element is staged, call `await_user_selection` exactly once. It returns:
59
+
60
+ - `{ status: "completed", selections: [{ element, chosenVariant, comment? }], unselected, annotations: [{ target, match, comment }], globalComment }` — apply `chosenVariant` for each element; skip elements in `unselected`. Treat each `annotations` entry (inspector comments the human pinned to elements) and `globalComment` as a change request.
61
+ - `{ status: "pending", proposedElements }` — `timeoutSeconds` elapsed, not an error. Proposals are still live; call `await_user_selection` again.
62
+ - `{ status: "no_proposals" }` — you called it before any `propose_variant`. Stage variants first.
63
+
64
+ ### Step 4 — Apply the outcome
65
+
66
+ Implement the chosen variant for every selected element, address every annotation/comment, and report what you applied and what was skipped. If the human commented but skipped a variant, the comment still matters — act on it.
67
+
68
+ ## 4. Rules
69
+
70
+ - **At least two variants per element.** A choice needs alternatives — every element you propose must have ≥2 distinct variants (call `propose_variant` at least twice for it). If you only have one look for an element, either produce a real alternative or don't propose that element at all; a lone variant isn't a choice.
71
+ - **Build before you propose.** Every `previewImage` must be a screenshot of that variant actually running on the device. No mockups, no guesses, no proposing un-built ideas.
72
+ - **Distinct screenshot per variant.** Reusing a `previewImage` path across two variants — or capturing two paths whose bytes turn out identical — defeats the whole point of the Argent Lens. If you can't produce visibly different captures (e.g. the app is read-only, accessibility is broken so you can't navigate, the bundle won't hot-reload), STOP and tell the user instead of staging duplicates.
73
+ - **One blocking call.** `propose_variant` never blocks — stage freely. `await_user_selection` is the only call that waits, and you call it once, last.
74
+ - **Anchor accurately.** Pull matchers from `describe`; a wrong `match` makes the card point at the wrong element or float unanchored.
75
+ - **One variant on screen at a time.** Apply → screenshot → revert before the next variant so screenshots never bleed together.
76
+ - **`pending` is normal.** On `pending`, just await again — proposals persist across timeouts.
77
+ - **Re-proposing starts a fresh round.** Calling `propose_variant` after a round was consumed begins round N+1 and clears the previous round's elements; stage a full set each round.
78
+
79
+ ## 5. Example
80
+
81
+ ```
82
+ describe { udid } # read exact label/identifier
83
+ propose_variant { element: "Search field",
84
+ match: { by: "identifier", value: "search-input" },
85
+ variant: { name: "Outlined", summary: "1pt border, transparent fill",
86
+ previewImage: "/var/folders/.../search-outlined.png" } }
87
+ propose_variant { element: "Search field",
88
+ match: { by: "identifier", value: "search-input" },
89
+ variant: { name: "Pill", summary: "Fully rounded, filled grey",
90
+ previewImage: "/var/folders/.../search-pill.png" } }
91
+ propose_variant { element: "Primary CTA",
92
+ match: { by: "label", value: "Get started" },
93
+ variant: { name: "Gradient", summary: "Accent gradient fill",
94
+ previewImage: "/var/folders/.../cta-gradient.png" } }
95
+ await_user_selection {} # ONE blocking call → human picks
96
+ → { status: "completed",
97
+ selections: [ { element: "Search field", chosenVariant: { name: "Pill" } },
98
+ { element: "Primary CTA", chosenVariant: { name: "Gradient" } } ],
99
+ annotations: [ { target: "Tab bar", comment: "raise contrast" } ] }
100
+ # → apply Pill + Gradient, and raise tab-bar contrast.
101
+ ```
@@ -1,11 +1,13 @@
1
1
  ---
2
2
  name: argent-metro-debugger
3
- description: Debug a React Native app via Metro CDP using argent debugger tools. Use when connecting to Metro, inspecting React components, reading console logs, or evaluating JavaScript in the app runtime.
3
+ description: Debug a JS runtime via CDP using argent debugger tools. Primary path is React Native via Metro (iOS / Android); a subset of the tools (debugger-connect, debugger-status, debugger-evaluate, debugger-log-registry) also drive a Chromium (CDP) app's renderer (an Electron app, or any Chromium browser exposing CDP) through the same surface. Use when connecting to the runtime, inspecting React components, reading console logs, or evaluating JavaScript.
4
4
  ---
5
5
 
6
6
  ## 1. Prerequisites
7
7
 
8
- The debugger requires **Metro dev server running** (default `localhost:8081`) and **a React Native app connected to Metro** (at least one CDP target). Verify via `debugger-status`.
8
+ For **React Native (iOS / Android)**: requires **Metro dev server running** (default `localhost:8081`) and **a React Native app connected to Metro** (at least one CDP target). Verify via `debugger-status`.
9
+
10
+ For **Chromium (CDP)**: requires a Chromium/CDP app already available — an Electron app booted via `boot-device` with `electronAppPath`, or any Chromium browser exposing a CDP port (auto-discovered by `list-devices` on `9222` / `ARGENT_CHROMIUM_PORTS`). The debugger re-uses the page CDP session — `port` is ignored, `device_id` is the `chromium-cdp-<port>` value from `list-devices` / `boot-device`. Only `debugger-connect`, `debugger-status`, `debugger-evaluate`, `debugger-log-registry`, `view-network-logs`, and `view-network-request-details` work on Chromium (the latter two read the browser's native CDP Network recording for the active tab instead of the Metro-injected `fetch` interceptor); `debugger-component-tree`, `debugger-reload-metro`, `debugger-inspect-element`, and the `react-profiler-*` / `profiler-*` tools are RN-only and reject Chromium at the capability gate with `Tool 'X' is not supported on chromium app`.
9
11
 
10
12
  ### Android: reverse port for Metro
11
13
 
@@ -25,10 +27,10 @@ One Metro port can serve multiple connected devices (e.g. two simulators on `loc
25
27
 
26
28
  ### Connect & diagnostics
27
29
 
28
- | Tool | Purpose |
29
- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
30
- | `debugger-connect` | Connect to Metro CDP. Returns port, projectRoot, deviceName, appName, `logicalDeviceId`, isNewDebugger, connected. The returned `logicalDeviceId` is the `device_id` for every subsequent debugger/network/profiler call. |
31
- | `debugger-status` | Like connect + loadedScripts, enabledDomains, sourceMapReady. **Use to diagnose.** |
30
+ | Tool | Purpose |
31
+ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
32
+ | `debugger-connect` | Connect to the JS runtime's CDP (Metro on iOS / Android; the page CDP session on Chromium). Returns port, projectRoot (empty on Chromium), deviceName, appName, `logicalDeviceId`, isNewDebugger, connected. The returned `logicalDeviceId` is the `device_id` for every subsequent debugger call. |
33
+ | `debugger-status` | Like connect + loadedScripts, enabledDomains, sourceMapReady (no-op on Chromium). **Use to diagnose.** |
32
34
 
33
35
  ### Reload & recovery
34
36
 
@@ -115,13 +117,13 @@ When reading from the log file:
115
117
 
116
118
  ## Quick Reference
117
119
 
118
- | Action | Tool |
119
- | ----------------------------- | ------------------------------------------------------------------- |
120
- | Diagnose / check connection | `debugger-status` |
121
- | Connect to Metro CDP | `debugger-connect` |
122
- | Reload JS (already connected) | `debugger-reload-metro` |
123
- | Relaunch app on device | `restart-app` |
124
- | Inspect component at point | `debugger-inspect-element` |
125
- | Full component tree | `debugger-component-tree` |
126
- | Console log overview | `debugger-log-registry` (summary + log file path for `Grep`/`Read`) |
127
- | Evaluate JS | `debugger-evaluate` |
120
+ | Action | Tool |
121
+ | --------------------------------- | ------------------------------------------------------------------- |
122
+ | Diagnose / check connection | `debugger-status` |
123
+ | Connect to CDP (Metro / Chromium) | `debugger-connect` |
124
+ | Reload JS (already connected) | `debugger-reload-metro` |
125
+ | Relaunch app on device | `restart-app` |
126
+ | Inspect component at point | `debugger-inspect-element` |
127
+ | Full component tree | `debugger-component-tree` |
128
+ | Console log overview | `debugger-log-registry` (summary + log file path for `Grep`/`Read`) |
129
+ | Evaluate JS | `debugger-evaluate` |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: argent-native-profiler
3
- description: Native profiling for CPU hotspots, UI hangs, and memory leaks. Currently iOS-only (xctrace-backed); Android support (Perfetto/simpleperf) is on the roadmap. Use when diagnosing native-level performance issues.
3
+ description: Native profiling for CPU hotspots, UI hangs, memory issues. iOS via xctrace; Android via Perfetto. Use when diagnosing native-level performance issues.
4
4
  ---
5
5
 
6
6
  ## 1. Tools
@@ -15,8 +15,8 @@ description: Native profiling for CPU hotspots, UI hangs, and memory leaks. Curr
15
15
 
16
16
  ## 2. Platform Support
17
17
 
18
- - **iOS**: Fully supported. Backend: Xcode Instruments via `xctrace` on a booted simulator or connected device. Requires Xcode command-line tools on PATH.
19
- - **Android**: Not yet implemented. An Android backend (Perfetto or simpleperf via `adb`) is planned; today `native-profiler-start` rejects Android serials with a clear "iOS-only for now" error.
18
+ - **iOS**: Backend: Xcode Instruments via `xctrace` on a booted simulator or connected device. Requires Xcode command-line tools on PATH. Surfaces CPU hotspots, UI hangs, and memory leaks (instruments `Leaks` table).
19
+ - **Android**: Backend: Perfetto via `adb shell perfetto` + an in-process WASM trace-processor engine. Surfaces CPU hotspots and UI hangs, with per-hang jank reason codes, a main-thread state breakdown with `blocked_function` attribution, and a GC overlap annotation. Also reports an RSS-growth signal for memory pressure; treat it as a hint to confirm manually, not a confirmed leak. The target app must be debuggable or include `<profileable android:shell="true"/>` in its manifest for `perf_sample` callstacks to be captured.
20
20
 
21
21
  ---
22
22
 
@@ -53,12 +53,12 @@ You do not need to derive `app_process` manually — just make sure the app is l
53
53
 
54
54
  ### Step 1: Start recording
55
55
 
56
- Call `native-profiler-start` with `device_id` (iOS UDID; Android not yet supported). The tool auto-detects the running app and saves the trace to `/tmp/argent-profiler-cwd/` with a timestamped filename.
56
+ Call `native-profiler-start` with `device_id` (iOS UDID or Android serial). The tool auto-detects the running app and saves the trace to `/tmp/argent-profiler-cwd/` with a timestamped filename.
57
57
  Let the user interact with the app or drive interaction via simulator tools (see `argent-device-interact` skill).
58
58
 
59
59
  ### Step 2: Stop and export
60
60
 
61
- Call `native-profiler-stop` with `device_id`. On iOS this sends SIGINT to xctrace, waits for trace packaging, and exports CPU, hangs, and leaks data to XML. Check `exportDiagnostics` in the response for any export warnings.
61
+ Call `native-profiler-stop` with `device_id`. iOS sends SIGINT to xctrace, waits for trace packaging, and exports CPU, hangs, and leaks data to XML check `exportDiagnostics` for any export warnings. Android sends SIGTERM to the on-device perfetto daemon, polls `/proc/<pid>` until it exits, then `adb pull`s the `.pftrace` to the host.
62
62
 
63
63
  ### Step 3: Analyze
64
64
 
@@ -235,13 +235,13 @@ If the user's intent is ambiguous (run existing tests, write new tests, or find
235
235
 
236
236
  ## Related Skills
237
237
 
238
- | Skill | When to use |
239
- | ------------------------------- | ------------------------------------------------------------------------------- |
240
- | `argent-ios-simulator-setup` | Initial iOS simulator boot and connection setup |
241
- | `argent-android-emulator-setup` | Initial Android emulator boot and connection setup |
242
- | `argent-device-interact` | Tapping, swiping, typing, hardware buttons, gestures on the simulator/emulator |
243
- | `argent-metro-debugger` | Full Metro CDP debugging: component inspection, console logs, JS evaluation |
244
- | `argent-react-native-profiler` | Profiling performance, finding re-render issues, CPU hotspots |
245
- | `argent-test-ui-flow` | Interactive UI testing with automatic screenshot verification after each action |
238
+ | Skill | When to use |
239
+ | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
240
+ | `argent-ios-simulator-setup` | Initial iOS simulator boot and connection setup |
241
+ | `argent-android-emulator-setup` | Initial Android emulator boot and connection setup |
242
+ | `argent-device-interact` | Tapping, swiping, typing, hardware buttons, gestures on the simulator/emulator |
243
+ | `argent-metro-debugger` | JS-runtime CDP debugging (Metro on iOS / Android; the four ported tools also drive Chromium/CDP apps): component inspection, console logs, JS evaluation |
244
+ | `argent-react-native-profiler` | Profiling performance, finding re-render issues, CPU hotspots |
245
+ | `argent-test-ui-flow` | Interactive UI testing with automatic screenshot verification after each action |
246
246
 
247
247
  Ask the user before running tests: confirm which test suite (unit, E2E, or both), whether to use existing CI commands, and whether they want you to run existing tests, write new ones, or explore test cases yourself.
File without changes
File without changes