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
Copy file name to clipboardExpand all lines: .claude/skills/agent-device/flows/README.md
+14-1Lines changed: 14 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,17 +3,29 @@
3
3
## Directory layout
4
4
5
5
-`macros/` - reusable helpers for common setup/navigation actions that stop in a navigable state for further interactive work.
6
+
-`macros/<platform>/` - platform-specific overrides of a `macros/` flow, for flows whose selectors differ per platform. See [Platform scoping](#platform-scoping).
6
7
-`tests/` - critical-scenario scripts for QA/perf verification that assert explicit outcomes (for example Sentry spans) and then stop.
7
8
-`lib/` - bash drive libraries for flows that need conditional steering the linear `.ad` format cannot express (snapshot classification, state-dependent branching). Each file documents its own contract; the caller always owns the session lifecycle (`open`/`close`/`record`). Source them from an orchestrator or run them standalone against an already-open session (for example `lib/sign-in-drive.sh --platform web --session <name> --email <email>`).
8
9
9
10
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/`).
10
11
12
+
## Platform scoping
13
+
14
+
Most flows are platform-neutral and live directly in `macros/`. A flow whose selectors genuinely differ per platform gets a copy per platform under `macros/<platform>/`, where `<platform>` is the value passed to `--platform`.
15
+
16
+
A caller driving platform `P` resolves a macro by name:
17
+
18
+
1.`macros/<P>/<name>.ad` when that file exists.
19
+
2.`macros/<name>.ad` otherwise.
20
+
21
+
Split flows today: `sign-in.ad`, `send-message.ad`, `complete-onboarding.ad`. All three fill text inputs, whose accessibility shape differs between web and native. The unscoped copy of a split flow stays in `macros/` as the fallback for platforms that have no folder yet; it is not the contract for any platform that does have one. Everything else stays shared - split a flow only after confirming the divergence per platform with `agent-device is visible "<selector>"`.
22
+
11
23
## Agent decision loop (interactive)
12
24
13
25
Before manually navigating, use this human-in-the-loop loop:
2.`grep -H '^# @' .claude/skills/agent-device/flows/macros/*.ad .claude/skills/agent-device/flows/macros/<platform>/*.ad` - interactive catalog. Where both list the same name, the platform copy wins.
17
29
3. For each candidate flow, run `agent-device is exists "<selector>"` per `@pre`. Keep flows where every `@pre` passes.
18
30
4. Rank survivors by goal closeness and present top macro candidates to the user with a short "why this flow" note:
19
31
- Prefer flows whose `@post` selectors literally match destination language from the user request (same `text`, `label`, or selector phrase).
-**No `open`, no `close`, no `context` header.** Caller owns lifecycle.
70
82
-**No fixed `wait` calls.**`fill`/`press` resolve selectors with retry. Only add `wait <selector>` for real post-action blocks.
71
83
-**Durable selectors.** Prefer `id=...` first, then `role=... label=...`, with `||` fallbacks. Avoid `@eN` refs.
84
+
-**Confirm every selector on the platform it is written for.**`snapshot -i` prints display tags, which are not selector values - a node printed as `[text-field]` may only match `role="textbox"`. Check the exit code of `agent-device is visible "<selector>"` before committing a selector, and never carry one across platforms unchecked.
72
85
-**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.
73
86
-**Choose directory intentionally.** Put reusable setup/navigation steps in `flows/macros/`; put outcome verification scenarios in `flows/tests/`.
74
87
-**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").
Copy file name to clipboardExpand all lines: .claude/skills/agent-device/flows/lib/sign-in-drive.sh
+31-9Lines changed: 31 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -35,6 +35,8 @@ fi
35
35
36
36
# --- selector constants (one source of truth for .ad fallback, classifiers, waits) ---
37
37
readonly SEL_LOGIN_FIELD='id="username" || role="textfield" label="Phone or email" || label="Phone or email"'
38
+
# Mirrors the fill selector in sign-in.ad. Waiting on SEL_LOGIN_FIELD only proves the field exists, and the macro fills it requiring editable=true, so the replay could start against a field that had rendered but was not yet interactive.
39
+
readonly SEL_LOGIN_FIELD_EDITABLE='id="username" editable=true || role="textfield" label="Phone or email" editable=true || label="Phone or email" editable=true'
# @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.
3
+
# @pre label="Write something..." editable=true
4
+
# @post label="Write something..." editable=true
5
+
# @tag chat
6
+
# @param MESSAGE Message text to send in the currently open chat.
7
+
8
+
is exists "label=\"Write something...\" editable=true"
9
+
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 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.
3
+
# @pre role="textbox" label="Write something..."
4
+
# @post role="textbox" label="Write something..."
5
+
# @tag chat
6
+
# @param MESSAGE Message text to send in the currently open chat.
7
+
8
+
is exists "role=\"textbox\" label=\"Write something...\""
9
+
fill "role=\"textbox\" label=\"Write something...\"" "${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.
## [CONSISTENCY-17] No AI-generated jargon in code or comments
7
+
8
+
### Reasoning
9
+
10
+
Certain phrases appear constantly in AI-generated code but rarely in code written by engineers. They make the codebase sound like it was written by a chatbot and should be replaced with plain, direct language.
11
+
12
+
### Banned phrases
13
+
14
+
| Phrase | Plain substitute |
15
+
|--------|-----------------|
16
+
| sentinel | placeholder, marker, guard entry |
17
+
| fan out | send, make, dispatch, distribute |
18
+
| carve out | set aside, exclude, separate |
19
+
| defense in depth | extra guard, additional check |
20
+
| belt and suspenders / belt-and-suspenders | extra safety check, redundant guard |
21
+
| fresh evidence | new data, updated result |
22
+
23
+
### Incorrect
24
+
25
+
```ts
26
+
// Fan out the request to every matching snapshot.
27
+
function getSentinelValue() { ... }
28
+
const fanOutRequests = () => { ... }
29
+
30
+
// Defense in depth: reject the value if it arrived stale.
31
+
// Belt-and-suspenders check before writing.
32
+
// Uses a sentinel to signal end-of-stream.
33
+
```
34
+
35
+
### Correct
36
+
37
+
```ts
38
+
// Send the request to every matching snapshot.
39
+
function getPlaceholderValue() { ... }
40
+
const sendDuplicateRequests = () => { ... }
41
+
42
+
// Additional guard: reject the value if it arrived stale.
43
+
// Extra safety check before writing.
44
+
// Uses a placeholder to signal end-of-stream.
45
+
```
46
+
47
+
---
48
+
49
+
### Review Metadata
50
+
51
+
Flag when any added or modified code — including comments, function names, variable names, type names, or string literals — contains one of the banned phrases above.
52
+
53
+
**DO NOT flag if:**
54
+
55
+
- The phrase appears inside a quoted external API name, a third-party library identifier, or a value the codebase does not control (e.g. a server response field name)
56
+
- The phrase is in a test description string that is directly testing behavior described by an external spec or API that uses the term
0 commit comments