mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
ee3a2d1105
apps.ts was extracted into app-resolution/app-launch/app-device-io/app-settings modules; it is now a 15-line barrel, so the extract-before-adding warning no longer applies. session.ts remains over budget and keeps its entry.
150 lines
8.9 KiB
Markdown
150 lines
8.9 KiB
Markdown
# AGENTS.md
|
|
|
|
`agent-device` is a CLI and daemon for automating Apple, Android, HarmonyOS, Vega, Linux, and web
|
|
targets. A long-lived daemon owns sessions; registry-derived commands route to platform runtimes.
|
|
|
|
This file contains repository-specific traps and invariants that are expensive to rediscover. Load
|
|
task procedures only when needed:
|
|
|
|
| When the task involves | Read |
|
|
| --- | --- |
|
|
| Domain vocabulary | `CONTEXT.md`, `docs/agents/domain.md` |
|
|
| Architecture decisions | `docs/adr/README.md` |
|
|
| Tests or gate selection | `docs/agents/testing.md` |
|
|
| Selector capture, polling, or interaction fast paths | `docs/agents/selector-capture.md` |
|
|
| Adding or changing a CLI flag | `docs/agents/cli-flags.md` |
|
|
| Opening or reviewing a PR | `docs/agents/pull-requests.md` |
|
|
| Migrating an ADR 0019 command | `docs/agents/adr-0019-unit.md` |
|
|
| Running against a real device | `docs/agents/device-verification.md` |
|
|
| Issues, PRDs, and triage labels | `docs/agents/issue-tracker.md`, `docs/agents/triage-labels.md` |
|
|
| Web backend setup or diagnostics | `docs/agents/web-backend.md` |
|
|
|
|
Versioned CLI help is the source of truth for command behavior. Start workflow planning with
|
|
`agent-device help workflow`, then use the relevant topic help.
|
|
|
|
## Incident-derived principles
|
|
|
|
- Guarantees erode at path boundaries. Classify every interaction dispatch path in
|
|
`packages/contracts/src/interaction-guarantees.ts`; a registry claim is not proof that the native
|
|
implementation satisfies the guarantee's definition.
|
|
- Delegation on error proves no success-path parity. A fast path may succeed on a candidate the
|
|
shared rules would refuse.
|
|
- Prove that a code path can fire before measuring it. An A/B test with an unreachable arm is two
|
|
green runs without evidence.
|
|
- A green regression test counts only after it has been observed red against the pre-fix code. Plant
|
|
a violation for new structural gates and verify the gate names the invariant.
|
|
- Repair recurring failures at their owning interface with types, a registry, or one construction
|
|
path. A custom guard that reconstructs another source of truth needs redesign, not another
|
|
exception.
|
|
- Key behavior on typed reasons and details, never error text. Existing message sniffs are owned debt
|
|
and must not be copied.
|
|
- Snapshot output is the token budget: do not add per-node metadata when response-level metadata can
|
|
be emitted once. Append warnings through the shared response builder; never replace prior warnings.
|
|
- Before preserving a compatibility shape, run `git tag --contains <commit>`. Unreleased API has no
|
|
external compatibility obligation.
|
|
|
|
## Declaration sites and enforcement
|
|
|
|
Read the declaration rather than maintaining a prose copy:
|
|
|
|
- commands and their surface, capability, batch, and timeout traits:
|
|
`src/core/command-descriptor/registry.ts`
|
|
- daemon route ownership and request-policy traits: `src/daemon/daemon-command-registry.ts`
|
|
- interaction paths and guarantees: `packages/contracts/src/interaction-guarantees.ts`
|
|
- canonical command names: `src/command-catalog.ts`
|
|
- device capability admission: `src/core/capabilities.ts`
|
|
|
|
Shared selector parsing and matching belongs in `@agent-device/selectors`; request cancellation and
|
|
progress in `src/request`; cross-layer contracts in `src/contracts`; CLI flags in
|
|
`src/commands/cli-grammar`; cross-surface schema composition in `src/cli-schema`.
|
|
|
|
The enforced registries are self-declaring. A failing completeness, parity, coverage, timeout,
|
|
layering, or construction gate means the new cell or path is unclassified; do not suppress or
|
|
allowlist it. Interaction responses are built only through `buildInteractionResponseData`, and
|
|
cross-language rules change through golden tables under `contracts/fixtures/`.
|
|
|
|
## Hard repository rules
|
|
|
|
- Plain `.mjs` packaging fixtures that cannot import TypeScript execution helpers keep child-process
|
|
use local and prefer `execFile`.
|
|
- Apple target changes keep the kernel device model, capability admission, dispatch resolution,
|
|
Apple discovery, and xctestrun preparation in sync.
|
|
- iOS simulator-set scoping must never hide the host macOS desktop target.
|
|
- Skills may carry a minimal start/routing card; command semantics belong in versioned CLI help.
|
|
- Do not add compatibility or fallback behavior without explicit approval. Complete migrations and
|
|
remove superseded paths.
|
|
- Keep changes within one command family or module group unless the task explicitly crosses a
|
|
boundary. Platform-neutral work does not license inspecting every platform implementation.
|
|
|
|
## Module and test topology
|
|
|
|
- Name modules for the domain question they answer and colocate machine-readable claims with their
|
|
enforcement. Internal barrels are legacy; add barrels only at package boundaries.
|
|
- Implementation files target at most 300 lines. Extract before adding behavior past 500 lines;
|
|
files past 1,000 lines are architecture debt unless generated or fixture data.
|
|
- Tests mirror source topology one-to-one. Split a source module and its test together; do not add to
|
|
the legacy `interaction.test.ts` or platform `index.test.ts` aggregations.
|
|
- Shared fixtures are named exports in a sibling fixture module, not repeated inline literals.
|
|
- `src/daemon/handlers/session.ts` is already over budget; extract the relevant platform-specific
|
|
concept before adding behavior.
|
|
|
|
## Toolchain and worktree traps
|
|
|
|
- Use `pnpm`; never add `package-lock.json`. OXC owns lint and format. Run `pnpm format` for the
|
|
repository, not a path-scoped formatter invocation.
|
|
- A fresh worktree requires `pnpm install --frozen-lockfile && pnpm build`. Until then package and
|
|
optional-peer resolution may point at another checkout and produce false failures.
|
|
- Source-checkout daemon state is worktree-scoped, but devices are not. Use `pnpm daemon:state-dir`
|
|
to inspect it and different devices for concurrent worktrees.
|
|
- Run one full gate per host at a time. Subprocess-backed tests under concurrent worktrees produce
|
|
timeout-shaped contention failures.
|
|
- Before pushing, run `pnpm check:affected --run && git push`. Use `pnpm check` for broad refactors.
|
|
GitHub remains authoritative for native, device, provider, and full-coverage lanes.
|
|
- The layering scan reads tracked files only. Stage a new module before trusting its result.
|
|
- Fallow baselines are path-keyed. Move the matching baseline entry when renaming a file; never bulk
|
|
regenerate baselines to accept unrelated findings.
|
|
- The first Node process after a newly signed Apple runner launches may block during Gatekeeper
|
|
verification. Warm it with a throwaway `node -e 0` before measuring.
|
|
- `DEVICE_IN_USE` normally means another session still owns the device. Follow the error's targeted
|
|
`close --session` hint instead of debugging the daemon.
|
|
- A changing timeout failure set that passes in isolation is host contention. Reproduce the same
|
|
test on `origin/main` under the same load before treating it as a regression.
|
|
|
|
## Runtime and diagnostics seams
|
|
|
|
The OS-neutral Apple runner lives under `src/platforms/apple/core/runner/`. For connection errors,
|
|
retry policy, or command typing, start at `runner-contract.ts`; transport stays below session/client
|
|
behavior, and xctestrun build/cache logic stays outside request execution.
|
|
|
|
Diagnostics use `src/utils/diagnostics.ts`. Request diagnostics belong in the session request log;
|
|
session artifact paths come from `src/daemon/session-store.ts`. App/device logs remain in `app.log`;
|
|
Apple runner and xcodebuild output remains in `runner.log`.
|
|
|
|
Normalize failures with `normalizeError` and preserve `hint`, `diagnosticId`, `logPath`, and typed
|
|
`details`. An interaction taking five seconds or more is a daemon-log question: inspect runner
|
|
restart, stale-session recovery, accessibility failure, transport retry, and timeout evidence.
|
|
|
|
Optional probes and caches are best-effort only when the feature contract says so. Their budgets
|
|
must be shorter than the required operation they precede.
|
|
|
|
## Selector and replay invariants
|
|
|
|
Element interactions support selector and `@ref`, then record a selector chain after resolution.
|
|
Replay failures may re-resolve that chain only to produce a ranked divergence suggestion; ADR 0012
|
|
retired silent script rewriting.
|
|
|
|
Selector keys stay centralized in `@agent-device/selectors`; `is` predicates use
|
|
`evaluateIsPredicate`. On macOS, snapshot rectangles are absolute in window space and point actions
|
|
translate through the interaction root frame. Prefer selector or ref tests over raw coordinates.
|
|
|
|
## Documentation ownership
|
|
|
|
Before adding guidance, decide whether the command surface, CLI grammar/help, MCP projection, daemon
|
|
runtime, ADR, or task procedure owns it. Link to executable registries instead of copying their
|
|
contents. Keep a sentence in this file only when no gate, lint rule, versioned help, ADR, or
|
|
decision-site comment can own it. `CONTEXT.md` is glossary-only: no implementation paths,
|
|
architecture decisions, migration state, or workflows.
|
|
|
|
Behavior changes update their owning help/metadata and user docs when relevant. In the final summary,
|
|
state whether docs or skills changed and why.
|