You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Drive iOS and Android devices for the Expensify App - testing, debugging, performance profiling, bug reproduction, and feature verification. Use when the developer needs to interact with the mobile app on a device.
If the resolved bundle ID is missing from the list, **STOP** and instruct the developer to run the matching build script from the table. HybridApp mobile builds **must** be initiated from `Mobile-Expensify/` (per project CLAUDE.md).
43
+
44
+
### 4. Metro
45
+
46
+
```bash
47
+
agent-device metro prepare --public-base-url http://localhost:8081 --port 8081 --kind react-native
48
+
```
49
+
50
+
If `metro prepare` fails, **STOP** and surface the error verbatim.
51
+
52
+
### 5. Pick a target device
53
+
54
+
```bash
55
+
agent-device devices --platform <p> --json
56
+
```
57
+
58
+
- Prefer the first device with `booted=true`.
59
+
- If none are booted, choose the default target device (usually the first listed), then continue to step 6 to detect and clear any stale session bound to that device before opening.
60
+
- If multiple are booted, ask the user which.
61
+
62
+
Capture the device name and (for iOS) the simulator UDID, or (for Android) the serial.
63
+
64
+
### 6. Session reuse vs reset
65
+
66
+
```bash
67
+
agent-device session list --json
68
+
```
69
+
70
+
For each entry whose `device_udid` (iOS) or `serial` (Android) matches the chosen device:
71
+
72
+
- If the session was created earlier in the **current** Claude invocation, reuse it silently.
73
+
- Otherwise prompt: `reuse` (continue with the existing session) or `reset` (force-close it).
74
+
- To reset: `agent-device close --shutdown --session <name>`. `--shutdown` also frees the simulator.
75
+
76
+
### 7. Open
77
+
78
+
```bash
79
+
agent-device open <bundle-id> --platform <p> --device "<name>"
80
+
```
81
+
82
+
If `open` errors with "app not installed", revisit step 3.
83
+
84
+
### 8. Sanity
85
+
86
+
```bash
87
+
agent-device snapshot -i
88
+
```
89
+
90
+
Confirm the app rendered. From here, follow the [Agent decision loop](flows/README.md) for repeatable flows or drive interactively.
91
+
92
+
### Canonical skill references
93
+
94
+
Read these files directly for device automation guidance (bootstrap, exploration, verification, debugging): !`echo "$(npm root -g)/agent-device/skills/agent-device"`
27
95
28
96
## Flows
29
97
30
-
Repeatable steps (sign-in, onboarding, etc.) are captured as composable `.ad` snippets under [`flows/`](flows/README.md). Before manually tapping through a screen, follow the **Agent decision loop** in [`flows/README.md`](flows/README.md) - it covers discovery, `@pre` filtering, replay, and `@post` verification.
98
+
Repeatable steps (sign-in, onboarding, etc.) are captured as composable `.ad` snippets under [`flows/`](flows/README.md). For interactive usage, propose and run only `flows/macros/` helpers. `flows/tests/` belongs to a separate QA workflow and must not be proposed by this skill; QA/perf runs execute them via `agent-device test <path>`.
Composable `.ad` snippets - bounded units of work. A flow may span one or multiple screens as long as it represents a coherent, reusable action with clear start (`@pre`) and completion (`@post`) checkpoints. Each flow advertises machine-matchable metadata (`@pre`, `@post`, `@tag`) via `# @`-prefixed comment headers, so an agent can pick the right one from a snapshot.
3
+
## Directory layout
4
4
5
-
## Agent decision loop
5
+
-`macros/` - reusable helpers for common setup/navigation actions that stop in a navigable state for further interactive work.
6
+
-`tests/` - critical-scenario scripts for QA/perf verification that assert explicit outcomes (for example Sentry spans) and then stop.
7
+
8
+
Composable `.ad` snippets - bounded units of work. A flow may span one or multiple screens as long as it represents a coherent, reusable action with clear start (`@pre`) and completion (`@post`) checkpoints. Each flow advertises machine-matchable metadata (`@pre`, `@post`, `@tag`, `@param`) via `# @`-prefixed comment headers, while flow type is derived from location (`flows/macros/` or `flows/tests/`).
9
+
10
+
## Agent decision loop (interactive)
6
11
7
12
Before manually navigating, use this human-in-the-loop loop:
8
13
9
14
1.`agent-device snapshot -i` - see current state.
10
-
2.`grep -H '^# @' .claude/skills/agent-device/flows/*.ad` - full catalog in one read.
3. For each candidate flow, run `agent-device is exists "<selector>"` per `@pre`. Keep flows where every `@pre` passes.
12
-
4. Rank survivors by goal closeness (`@post` overlap with the requested destination when present) and present top candidates to the user with a short "why this flow" note.
17
+
4. Rank survivors by goal closeness and present top macro candidates to the user with a short "why this flow" note:
18
+
- Prefer flows whose `@post` selectors literally match destination language from the user request (same `text`, `label`, or selector phrase).
13
19
5. Wait for user selection before replaying. **Auto-run is allowed only when there is exactly one survivor and it is an unambiguous match for an explicit user request.**
14
-
6.`agent-device replay <path>`.
15
-
7. If the flow declares `@post`, verify each `@post` with `is exists`. On success, re-enter the loop only if the user's stated goal is not complete; otherwise stop and report completion. On failure, propose peer flow/manual fallback options and ask before continuing. If no `@post` is declared (utility flow), rely on explicit user confirmation or the next snapshot before continuing.
20
+
- Only propose flows from `flows/macros/` in interactive usage.
21
+
6. Scan selected flow `# @param` headers. Ask the user for any missing parameter values, then build explicit CLI args (`-e KEY=VALUE`) for replay.
22
+
7.`agent-device replay <path> -e KEY=VALUE ...`.
23
+
8. If the flow declares `@post`, verify each `@post` with `is exists`. On success, re-enter the loop only if the user's stated goal is not complete; otherwise stop and report completion. On failure, propose peer flow/manual fallback options and ask before continuing. If no `@post` is declared (utility flow), rely on explicit user confirmation or the next snapshot before continuing.
24
+
25
+
## QA workflow (separate)
26
+
27
+
`flows/tests/` is reserved for dedicated QA automation and should not be offered to users as part of the interactive helper loop above. Run these flows with the dedicated test runner:
28
+
29
+
```bash
30
+
agent-device test .claude/skills/agent-device/flows/tests/<name>.ad -e KEY=VALUE ...
31
+
```
16
32
17
33
## Metadata header spec
18
34
@@ -24,21 +40,22 @@ Each flow starts with `# @key value` comment lines. The `.ad` parser treats `#`
24
40
|`@pre`| 1..N | Selector that must resolve in the current snapshot. Multiple lines are ANDed. |
25
41
|`@post`| 0..N | Selector expected after replay. Multiple lines are ANDed. Used for chaining + success. |
|`@param`| 0..N | Runtime input contract: `@param KEY description.` Use with `${KEY}` in flow body. |
27
44
28
45
Selector syntax matches the body: `id="..."`, `role="..." label="..."`, `text="..."`, `||` for fallbacks.
29
46
30
47
## Parametrization (`agent-device` v0.13.0+)
31
48
32
-
Lift body literals to named variables via `env` + `${VAR}` interpolation so values can be overridden at runtime without editing the file.
49
+
Declare runtime inputs via metadata (`@param`) and reference them in the body with `${VAR}` interpolation. Values are supplied by caller arguments (`-e`) or shell imports (`AD_VAR_*`) - never by in-file`env` directives.
-**No fixed `wait` calls.**`fill`/`press` resolve selectors with retry. Only add `wait <selector>` for real post-action blocks.
53
70
-**Durable selectors.** Prefer `id=...` first, then `role=... label=...`, with `||` fallbacks. Avoid `@eN` refs.
54
71
-**Every flow declares `@desc` and `@pre`.** Add `@post` for outcome-bearing flows; utility flows (for example `go-back`) may omit it. Add `@tag` when applicable.
72
+
-**Choose directory intentionally.** Put reusable setup/navigation steps in `flows/macros/`; put outcome verification scenarios in `flows/tests/`.
55
73
-**Keep scope coherent, not artificially tiny.** Flows can span multiple screens when that sequence is the reusable intent (for example "create and submit manual expense").
56
74
-**Peers share `@pre` and differ on `@post`.** One flow per narrow outcome is better than a mega-flow with conditional branches.
57
-
-**Use `env` for substituted values.** If a literal is interpolated into the body, declare a matching `env` default and reference it as `${VAR}`.
75
+
-**Use `@param` for substituted values.** If a literal is interpolated into the body, declare `# @param KEY description.` and reference it as `${KEY}`.
76
+
-**Do not use `env` directives in repo flows.** Runtime values must come from `-e KEY=VALUE` (preferred) or `AD_VAR_KEY=...`.
77
+
-**Use inline defaults sparingly.** Optional tuning values can use `${KEY:-fallback}` in the body; required values should have no fallback and must be provided by caller input.
58
78
59
79
## Recording a new flow
60
80
61
81
1. Drive the target screen manually.
62
82
2. Start a session with `--save-script`:
63
83
```bash
64
-
agent-device open <app> --save-script .claude/skills/agent-device/flows/<name>.ad
84
+
agent-device open <app> --save-script .claude/skills/agent-device/flows/<kind>/<name>.ad
65
85
```
66
86
3. Perform the steps.
67
87
4.`agent-device close` - flushes the `.ad`.
68
88
5. Edit the generated file:
69
89
- Delete the `context` line, leading `open ... --relaunch`, trailing `close`, and eyeballing `wait`s.
Re-verify `@pre`/`@post` still hold, then commit. Note: `replay -u`is rejected when the script declares `env` directives (rewrite would drop them); strip the `env` block manually before healing, then re-add it.
101
+
Re-verify `@pre`/`@post` still hold, then commit. Note: `replay -u`can rewrite interpolated lines to concrete selectors/values; review diffs and restore `${KEY}` placeholders where needed. Keep runtime inputs in `@param` + `-e`/`AD_VAR_*`; do not reintroduce in-file `env` directives.
# @desc Send a chat message from inside an already-open chat. Reusable helper for setting up state in other flows. Does not navigate or open a chat - assumes the composer is visible. For the QA scenario that exercises the ManualSendMessage Sentry span, see flows/tests/send-message.ad.
2
+
# @pre label="Write something..." editable=true
3
+
# @post label="Write something..." editable=true
4
+
# @tag chat
5
+
# @param MESSAGE Message text to send in the currently open chat.
6
+
7
+
is exists "label=\"Write something...\" editable=true"
8
+
fill "label=\"Write something...\" editable=true" "${MESSAGE}"
# @desc Sign in with the shared agent-device test account. Supports both new-account and returning-account outcomes. Caller MUST randomize EMAIL via `-e EMAIL=agent-device-testing+<9digits>@gmail.com` to avoid account flagging.
# @desc From the Inbox tab, open a chat/report matching TARGET_CHAT in the LHN, with fallback to the first available chat row. Triggers the ManualOpenReport Sentry span (LHN row press -> report screen mounted with composer visible). Assumes the user is signed in with at least one chat in the Inbox.
0 commit comments