Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 92 additions & 84 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,32 @@

Minimal operating guide for AI coding agents in this repo.

## Before Implementing
## First 60 Seconds
- Classify task type:
- Info-only (triage/review/questions/docs guidance): no code edits and no test runs unless explicitly requested.
- Code change: make minimal scoped edits and run only required checks from **Testing Matrix**.
- State assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them - don't pick silently.
- If a simpler approach exists, say so. Push back when warranted.

## Code Changes
- Minimum code that solves the problem. No speculative features.
- No abstractions for single-use code.
- Surgical edits: touch only what the task requires.
- Match existing style, even if you'd do it differently.
- Remove imports/variables YOUR changes made unused; don't touch pre-existing dead code.

## Verification
- Transform tasks into verifiable goals with clear success criteria.
- For multi-step tasks, state a brief plan with verification checkpoints.

## Docs & Skills
- For every behavior or CLI surface change, evaluate whether docs/skills updates are required.
- Update `README.md` and relevant `website/docs/**` pages when command behavior, flags, aliases, or workflows change.
- Update relevant `skills/**/SKILL.md` guidance when usage examples or workflow recommendations change.
- In final summaries, explicitly state whether docs/skills were updated; if not, state why no updates were needed.
- Read at most 3 files first:
- owning handler/module
- one shared helper used by that handler
- one downstream platform file if needed
- Define verifiable success criteria before editing.
- Decide docs/skills impact up front.

## Scope
- Solve issues with the smallest context read.
- Keep changes scoped to one command family or module group.
- Preserve daemon session semantics and platform behavior.
- Read at most 3 files first:
- the owning handler/module
- one shared helper used by that handler
- one downstream platform file if needed
- Expand only when contracts cross module boundaries.
- Do not read both iOS and Android paths unless the issue is explicitly cross-platform.
- Do not read both iOS and Android paths unless explicitly cross-platform.
- If requested fix expands beyond one command family/module group, stop and confirm before broadening scope.

## Code Changes
- Minimum code that solves the problem. No speculative features.
- No abstractions for single-use code.
- Surgical edits only.
- Match existing style.
- Remove imports/variables YOUR changes made unused; do not clean unrelated dead code.

## Routing
- Keep `src/daemon.ts` as a thin router.
Expand All @@ -45,28 +39,78 @@ Minimal operating guide for AI coding agents in this repo.
- record/trace: `src/daemon/handlers/record-trace.ts`
- Generic passthrough (press/scroll/type) is daemon fallback only after handlers return null.

## Hard Rules
## Command Family Lookup
- `logs`: `src/daemon/handlers/session.ts` -> `src/daemon/app-log.ts` -> `src/daemon/handlers/__tests__/session.test.ts`
- `open/close/replay/apps/appstate`: `src/daemon/handlers/session.ts` -> `src/daemon/session-store.ts` -> `src/daemon/handlers/__tests__/session.test.ts`
- `click/fill/get/is`: `src/daemon/handlers/interaction.ts` -> `src/daemon/selectors.ts` -> `src/daemon/handlers/__tests__/interaction.test.ts`
- `snapshot/wait/settings/alert`: `src/daemon/handlers/snapshot.ts` -> `src/daemon/snapshot-processing.ts` -> `src/daemon/handlers/__tests__/snapshot-handler.test.ts`
- `record/trace`: `src/daemon/handlers/record-trace.ts` -> `src/platforms/ios/runner-client.ts` -> `src/daemon/handlers/__tests__/record-trace.test.ts`

## Hard Rules
- Use `runCmd`/`runCmdSync` from `src/utils/exec.ts` for process execution.
- Use daemon session flow for interactions (`open` before interactions, `close` after).
- Do not remove shared snapshot/session model behavior without full migration.
- Command/device support must come from `src/core/capabilities.ts`.
- If Swift runner code changes, run `pnpm build:xcuitest`.
- Use `inferFillText` and `uniqueStrings` from `src/daemon/action-utils.ts`. Do not duplicate.
- Use `evaluateIsPredicate` from `src/daemon/is-predicates.ts` for assertion logic. Do not inline.
- Use `inferFillText` and `uniqueStrings` from `src/daemon/action-utils.ts`.
- Use `evaluateIsPredicate` from `src/daemon/is-predicates.ts` for assertion logic.

## Logs Contract
- Logs backend/source of truth is `src/daemon/app-log.ts`.
- `session.ts` should orchestrate only (start/stop/path/doctor/mark), not duplicate backend logic.
- Preserve external grep/tail workflow in docs/skills.

## Diagnostics & Errors
- Diagnostics source of truth: `src/utils/diagnostics.ts`
- `withDiagnosticsScope`, `emitDiagnostic`, `withDiagnosticTimer`, `flushDiagnosticsToSessionFile`
- Do not add ad-hoc stderr/file logging where diagnostics helpers apply.
- Normalize user-facing failures via `src/utils/errors.ts` (`normalizeError`).
- Failure payload contract: `code`, `message`, `hint`, `diagnosticId`, `logPath`, `details`.
- Preserve `hint`, `diagnosticId`, `logPath` when wrapping/rethrowing errors.
- `--debug` is canonical; `--verbose` is backward-compatible alias.
- Keep redaction centralized in diagnostics helpers.

## Selector System Rules
- Interaction commands (`click`, `fill`, `get`, `is`) and `wait` accept selectors and `@ref`.
- Pipeline: **parse -> resolve -> act -> record selectorChain -> heal on replay**.
- Keep selector parsing/matching in `src/daemon/selectors.ts`.
- Call `buildSelectorChainForNode` after resolving target nodes.
- New element-targeting interactions must support selector + `@ref`, record `selectorChain`, and hook replay healing (`healReplayAction` + `collectReplaySelectorCandidates` in `session.ts`).
- New selector keys remain centralized in `selectors.ts`.
- New `is` predicates belong in `evaluateIsPredicate`.

## Testing Matrix
- Docs/skills only: no tests required.
- Non-TS, no behavior impact: no tests unless requested.
- Any TS change: `pnpm typecheck`.
- Daemon handler/shared module change: `pnpm test:unit` and `pnpm test:smoke`.
- iOS runner/Swift change: `pnpm build:xcuitest`.
- Cross-platform behavior change: run `pnpm test:integration`.

## Token Guardrails
- Do not read unrelated files once owning module is identified.
- Do not run integration tests by default.
- Do not inspect both iOS and Android codepaths unless task requires both.
- Keep PR summaries short and scoped.

## Common Mistakes
- Adding command logic to `src/daemon.ts` instead of handlers.
- Adding capability checks outside `src/core/capabilities.ts`.
- Inlining `is` predicate logic in handlers.
- Returning non-normalized user-facing errors.
- Duplicating logs backend logic in handlers instead of `src/daemon/app-log.ts`.

## Docs & Skills
- For behavior/CLI surface changes, evaluate docs/skills updates.
- Update `README.md` and relevant `website/docs/**` pages for command behavior/flags/aliases/workflows.
- Update relevant `skills/**/SKILL.md` when usage examples/workflow recommendations change.
- In final summaries, state whether docs/skills were updated; if not, explain why.

- Use `src/utils/diagnostics.ts` as the diagnostics source of truth:
- `withDiagnosticsScope`
- `emitDiagnostic`
- `withDiagnosticTimer`
- `flushDiagnosticsToSessionFile`
- Do not add ad-hoc stderr/file logging in handlers/platform modules when diagnostics helpers can be used.
- Normalize user-facing failures through `src/utils/errors.ts` (`normalizeError`).
- Failure payload contract should include: `code`, `message`, `hint`, `diagnosticId`, `logPath`, `details`.
- When wrapping/rethrowing daemon errors (batch/replay/handler wrappers), preserve `hint`, `diagnosticId`, and `logPath` from inner errors.
- `--debug` is canonical; `--verbose` remains backward-compatible alias.
- Keep redaction centralized in `src/utils/diagnostics.ts`; do not duplicate redaction logic in handlers/CLI.
## When Blocked
- If blocked by network/device/auth/permissions, stop and report:
- blocker
- why it blocks completion
- exact next command/action needed to unblock

## Key Files
- CLI parse + formatting: `src/bin.ts`, `src/cli.ts`, `src/utils/args.ts`
Expand All @@ -77,53 +121,17 @@ Minimal operating guide for AI coding agents in this repo.
- Shared action helpers: `src/daemon/action-utils.ts`
- Snapshot shaping + labels: `src/daemon/snapshot-processing.ts`
- Handler context helpers: `src/daemon/context.ts`, `src/daemon/device-ready.ts`
- Dispatcher and capability source of truth: `src/core/dispatch.ts`, `src/core/capabilities.ts`
- Dispatcher + capability map: `src/core/dispatch.ts`, `src/core/capabilities.ts`
- Platform backends: `src/platforms/ios/*`, `ios-runner/*`, `src/platforms/android/*`

## Capability Source Of Truth

- Command/device support must come from `src/core/capabilities.ts`.
- Do not scatter new support checks across handlers.

## Selector System Rules

- Interaction commands (`click`, `fill`, `get`, `is`) and `wait` accept selectors and `@ref`.
- Pipeline is: **parse -> resolve -> act -> record selectorChain -> heal on replay**.
- Keep selector parsing/matching in `src/daemon/selectors.ts`.
- Call `buildSelectorChainForNode` after resolving an interaction target.
- New element-targeting interactions must support selector input and `@ref`, record `selectorChain`, and hook replay healing (`healReplayAction` + `collectReplaySelectorCandidates` in `session.ts`).
- New selector key updates stay centralized in `selectors.ts` (`SelectorKey`, key sets, matcher, token checks).
- New `is` predicates belong in `evaluateIsPredicate` (`src/daemon/is-predicates.ts`), not handler code.

## Testing
- Unit tests are colocated with source files under `src/**`.
- Use `__tests__` folders colocated with the related source folder.
- The `test/**` tree is integration-only (including smoke integration tests).
- Example: tests for `src/daemon/selectors.ts` go in `src/daemon/__tests__/selectors.test.ts`.
- Add/extend colocated unit tests in the same PR for touched module logic.
- Any TS change:
- `pnpm typecheck`
- Daemon handler/shared module change:
- `pnpm test:unit`
- `pnpm test:smoke`
- iOS runner/Swift change:
- `pnpm build:xcuitest`

Run integration tests when behavior crosses platform boundaries:
- `pnpm test:integration`

## Measurement
- Track files touched per fix, cycle time, and iOS/Android regressions.

## Local Commands

- Run CLI: `pnpm ad <command>`
- For verification commands, use the **Testing** section above.

## Pull Requests
- Before opening PR: ensure no conflict markers and no unmerged paths.
- Run required checks for touched scope (at minimum `pnpm typecheck`; plus test commands from **Testing** above).
- Before opening PR: ensure no conflict markers/unmerged paths.
- Run required checks for touched scope from **Testing Matrix**.
- PR body must be short and include:
- `## Summary` with key behavior changes
- `## Summary`
- `## Validation` with exact commands run
- Call out known gaps or follow-ups explicitly; do not hide failing checks.
- Call out known gaps/follow-ups explicitly.
- Include touched-file count and note if scope expanded beyond initial command family.

## Priority Order
- When guidance conflicts, apply in this order: **Hard Rules -> Scope -> Testing Matrix -> style/preferences**.