Skip to content

Commit 5be506e

Browse files
MelvinBotmonzacarcaresuneox
committed
Merge main and add auto-match for receipt requirement CSV columns
Resolves merge conflict in ImportedCategoriesPage.tsx (kept dataIndex variable with .trim() from main). Adds findColumnName cases so CSV headers like "Receipts Required" and "Itemised Receipt Requirement" are automatically mapped to MAX_AMOUNT_NO_RECEIPT and MAX_AMOUNT_NO_ITEMIZED_RECEIPT. Co-authored-by: suneox <26096760+suneox@users.noreply.github.com> Co-authored-by: Cong Pham <suneox@users.noreply.github.com>
2 parents d101b53 + 31a5b2e commit 5be506e

1,049 files changed

Lines changed: 593134 additions & 373929 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/commands/review-code-pr.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
allowed-tools: Bash(gh pr diff:*),Bash(gh pr view:*),Bash(check-compiler.sh:*)
3-
description: Review a code contribution pull request
3+
description: Run the coding-standards rule linter on a PR diff. Use when user wants to review their changes against our custom rules.
44
---
55

66
Perform a comprehensive PR review using a specialized subagent:

.claude/skills/agent-device/SKILL.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,23 @@ allowed-tools: Bash(agent-device *) Bash(npm root *)
88

99
## Pre-flight
1010

11-
`agent-device` CLI version: !`agent-device --version 2>&1 || echo "NOT_INSTALLED"`
11+
<!-- The line below compares the installed `agent-device --version` to the required minimum 0.13.0 -->
12+
13+
`agent-device` version check: !`R=0.13.0; V=$(agent-device --version 2>/dev/null); [ -n "$V" ] && [ "$(printf '%s\n%s\n' "$R" "$V" | sort -V | head -1)" = "$R" ] && echo "OK ($V)" || echo "FAIL (need v$R+, got: ${V:-not installed})"`
14+
15+
> If the version check above shows `FAIL`, **STOP** and instruct the developer: `npm install -g agent-device@latest`.
1216
1317
Canonical skill reference path (read these files directly for device automation guidance - bootstrap, exploration, verification, debugging): !`echo "$(npm root -g)/agent-device/skills/agent-device"`
1418

15-
> If the version line above shows `NOT_INSTALLED` or a command-not-found error, **STOP** and instruct the developer to install it: `npm install -g agent-device`. All device interaction depends on it.
19+
## Dev prerequisites
20+
21+
Default assumption: dev build from this repo. Before `open <app>`, both must be true:
22+
23+
1. **Metro dev server** running: `npm run start` (background).
24+
2. **Dev build installed** on target: `npm run ios` or `npm run android` from the repo root.
25+
26+
Skip these only when the developer explicitly targets a non-dev build (e.g., standalone/prod artifact, or a pre-installed release build).
27+
28+
## Flows
29+
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.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Flows
2+
3+
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.
4+
5+
## Agent decision loop
6+
7+
Before manually navigating, use this human-in-the-loop loop:
8+
9+
1. `agent-device snapshot -i` - see current state.
10+
2. `grep -H '^# @' .claude/skills/agent-device/flows/*.ad` - full catalog in one read.
11+
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.
13+
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.
16+
17+
## Metadata header spec
18+
19+
Each flow starts with `# @key value` comment lines. The `.ad` parser treats `#` lines as no-ops, so headers cost nothing at replay time.
20+
21+
| Field | Cardinality | Value |
22+
| -------- | ----------- | ------------------------------------------------------------------------------------------------ |
23+
| `@desc` | 1 | One-line human summary. |
24+
| `@pre` | 1..N | Selector that must resolve in the current snapshot. Multiple lines are ANDed. |
25+
| `@post` | 0..N | Selector expected after replay. Multiple lines are ANDed. Used for chaining + success. |
26+
| `@tag` | 0..N | Free-form category (`auth`, `onboarding`, ...) or scoped (`sentry-<spanName>`). |
27+
28+
Selector syntax matches the body: `id="..."`, `role="..." label="..."`, `text="..."`, `||` for fallbacks.
29+
30+
## Parametrization (`agent-device` v0.13.0+)
31+
32+
Lift body literals to named variables via `env` + `${VAR}` interpolation so values can be overridden at runtime without editing the file.
33+
34+
| Construct | Where | Purpose |
35+
| ------------------ | -------------------- | -------------------------------------------------------------------------------- |
36+
| `env KEY=VALUE` | Header (after `# @`) | File-level default. Quote values with spaces or `||` chains: `env KEY="a || b"`. |
37+
| `${KEY}` | Body | Interpolation point. Resolves at replay time. |
38+
| `${KEY:-fallback}` | Body | Use `fallback` if `KEY` is unset. |
39+
| `\${KEY}` | Body | Literal `${KEY}` (escape). |
40+
41+
Resolution precedence (high to low): CLI `-e KEY=VALUE` (repeatable) > shell `AD_KEY=...` (auto-imported, prefix stripped) > file `env` > built-ins (`AD_PLATFORM`, `AD_SESSION`, `AD_FILENAME`, `AD_DEVICE`, `AD_ARTIFACTS`). Unresolved `${X}` errors with `file:line`.
42+
43+
Override at runtime without editing the file:
44+
45+
```bash
46+
agent-device replay <flow>.ad -e EMAIL=other@example.com
47+
```
48+
49+
## Authoring rules
50+
51+
- **No `open`, no `close`, no `context` header.** Caller owns lifecycle.
52+
- **No fixed `wait` calls.** `fill`/`press` resolve selectors with retry. Only add `wait <selector>` for real post-action blocks.
53+
- **Durable selectors.** Prefer `id=...` first, then `role=... label=...`, with `||` fallbacks. Avoid `@eN` refs.
54+
- **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.
55+
- **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+
- **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}`.
58+
59+
## Recording a new flow
60+
61+
1. Drive the target screen manually.
62+
2. Start a session with `--save-script`:
63+
```bash
64+
agent-device open <app> --save-script .claude/skills/agent-device/flows/<name>.ad
65+
```
66+
3. Perform the steps.
67+
4. `agent-device close` - flushes the `.ad`.
68+
5. Edit the generated file:
69+
- Delete the `context` line, leading `open ... --relaunch`, trailing `close`, and eyeballing `wait`s.
70+
- Add `@desc`, `@pre`, optional `@post`, and `@tag` headers.
71+
6. Verify: pre-check from a matching state, replay, post-check.
72+
73+
## Maintenance
74+
75+
Heal selector drift in place:
76+
77+
```bash
78+
agent-device replay -u .claude/skills/agent-device/flows/<name>.ad
79+
```
80+
81+
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.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# @desc Complete onboarding with minimal choices (skip work email, pick "Something else" purpose, enter generic name). Lands on Home.
2+
# @pre text="What’s your work email?"
3+
# @post text="Home"
4+
# @post role="button" label="Search"
5+
# @tag onboarding
6+
env FIRST_NAME=Agent
7+
env LAST_NAME=Device
8+
9+
press "id=\"onboardingPrivateEmailSkipButton\" || role=\"button\" label=\"Skip\" || label=\"Skip\""
10+
press "role=\"button\" label=\"Something else\" || label=\"Something else\""
11+
fill "role=\"textfield\" label=\"First name\" editable=true || label=\"First name\" editable=true" "${FIRST_NAME}"
12+
fill "role=\"textfield\" label=\"Last name\" editable=true || label=\"Last name\" editable=true" "${LAST_NAME}"
13+
press "role=\"button\" label=\"Continue\" || label=\"Continue\""
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# @desc Open Create Expense from the FAB, enter an amount on the Manual tab, fill the Merchant field, and submit. Supports configurable currency-aware submit button matching. Exercises the full submit-chain Sentry spans end-to-end. Assumes a workspace where Category is not required.
2+
# @pre role="button" label="Open actions menu"
3+
# @post text="Reports"
4+
# @post role="button" label="Expenses"
5+
# @tag iou
6+
# @tag navigation
7+
# @tag perf
8+
# @tag sentry-ManualCreateExpenseSubmit
9+
# @tag sentry-ManualSubmitToDestinationVisible
10+
# @tag sentry-ManualCreateExpenseServerResponse
11+
# @tag sentry-ManualConfirmationMount
12+
# @tag sentry-ManualConfirmationListReady
13+
# @tag sentry-ManualConfirmationReceiptLoad
14+
# @tag sentry-ManualGeolocationWait
15+
env AMOUNT=22
16+
env CURRENCY=PLN
17+
env MERCHANT="Test Coffee"
18+
19+
press "role=\"button\" label=\"Open actions menu\""
20+
press "role=\"button\" label=\"Create expense\" || label=\"Create expense\""
21+
press "label=\"Manual\""
22+
is exists "role=\"button\" label=\"Flip\""
23+
fill "editable=true" "${AMOUNT}"
24+
press "role=\"button\" label=\"Next\" || label=\"Next\""
25+
press "role=\"button\" label=\"Merchant\" || label=\"Merchant\""
26+
fill "role=\"text-field\" label=\"Merchant,\" editable=true || label=\"Merchant,\" editable=true" "${MERCHANT}"
27+
press "role=\"button\" label=\"Save\" || label=\"Save\""
28+
press "label=\"Create ${CURRENCY} ${AMOUNT}.00 expense\" || label=\"Create expense\""
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# @desc Generic back navigation via the HeaderWithBackButton chevron. Works on any screen that mounts HeaderWithBackButton (Create Expense, Search, Report details, settings pages, etc.).
2+
# @pre role="button" label="Back"
3+
# @tag navigation
4+
press "role=\"button\" label=\"Back\""
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# @desc From the Inbox tab, open the FAB actions menu and tap "Create expense". Triggers the ManualOpenCreateExpense Sentry span (startMoneyRequest -> IOURequestStart/Participants/Confirmation page). Assumes the user is signed in and the Inbox bottom nav with the floating action button is visible.
2+
# @pre text="Inbox"
3+
# @pre role="button" label="Open actions menu"
4+
# @post text="Manual"
5+
# @tag iou
6+
# @tag navigation
7+
# @tag perf
8+
# @tag sentry-ManualOpenCreateExpense
9+
find "Inbox" "click"
10+
press "role=\"button\" label=\"Open actions menu\""
11+
press "role=\"button\" label=\"Create expense\" || label=\"Create expense\""
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# @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.
2+
# @pre text="Inbox"
3+
# @pre text="Navigates to a chat"
4+
# @post role="textview" label="Write something..."
5+
# @tag chat
6+
# @tag navigation
7+
# @tag perf
8+
# @tag sentry-ManualOpenReport
9+
env TARGET_CHAT="Navigates to a chat"
10+
11+
find "Inbox" "click"
12+
find "${TARGET_CHAT}" "click"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# @desc Open the SearchRouter from the Inbox tab. Triggers the ManualOpenSearchRouter Sentry span (Search button tap -> SearchRouterPage visible). Assumes the user is signed in.
2+
# @pre text="Inbox"
3+
# @pre role="button" label="Search"
4+
# @post label="Search for something..." editable=true
5+
# @tag navigation
6+
# @tag perf
7+
# @tag search
8+
# @tag sentry-ManualOpenSearchRouter
9+
press "label=\"Inbox\" || label=\"Inbox. Your review is required\""
10+
press "role=\"button\" label=\"Search\""
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# @desc From the Inbox tab, open the FAB -> Create expense -> switch to Scan tab. Triggers the ManualCameraInit Sentry span (Scan tab mount -> camera session ready). Assumes the user is signed in and camera permission is granted.
2+
# @pre text="Inbox"
3+
# @pre role="button" label="Open actions menu"
4+
# @post text="Take a photo"
5+
# @tag iou
6+
# @tag scan
7+
# @tag perf
8+
# @tag sentry-ManualCameraInit
9+
find "Inbox" "click"
10+
press "role=\"button\" label=\"Open actions menu\""
11+
press "role=\"button\" label=\"Create expense\" || label=\"Create expense\""
12+
press "label=\"Scan\""

0 commit comments

Comments
 (0)