mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
34e8cbb7a2
* docs+ux: make device ownership discoverable end to end Complete the #1320 agent experience so 'busy? -> inspect -> choose or release' is discoverable from every surface an agent actually reads: - devices now projects the blocking claim owner per row (claimedBy with session and workspace, observe-policy projection; provably dead owners are excluded because the next open replaces them automatically), so an agent told a device is busy can pick a free one from the same listing. - help debugging gains a 'Device busy and ownership' section separating the two DEVICE_IN_USE flavors and their exact recoveries. - AGENTS.md documents both flavors; docs/agents/device-verification.md retires the last ps/kill recovery guidance in favor of device status, daemon stop --state-dir, and device release --stale (Stage 5 of #1320). - ADR-0010 no longer calls DEVICE_IN_USE 'the only retriable code' without naming the claim path's non-retriable override. - The rendered cross-worktree claim error gains a help-conformance quiz case binding (sample-output-device-claim-inspects-owner). - README points at device status / device release --stale. Part of #1320. * fix: key ownership projection by canonical device identity end to end Review findings on #2165: - blockingClaimOwnersByDevice keyed claims and inventory rows by bare device.id, so a live Android claim could project claimedBy onto an unrelated same-id Apple/Harmony/Vega row, with scan order picking the displayed owner. Both sides now use the canonical local device key (claim.deviceKey against canonicalLocalDeviceKey of the row's claim identity). The cross-family same-id regression was observed red against the bare-id keying. - The projection is now asserted across every hop the PR promises: client normalization preserves well-formed claimedBy and drops malformed ones, and the devices CLI formatter carries it through JSON data and renders the text line (MCP shares the same serialization).
3.2 KiB
3.2 KiB
Manual Device Verification
Read this before running agent-device by hand against a simulator, emulator, or physical device.
Before the run: defeat staleness
Dev-loop staleness has three layers, and each produces a convincing false negative.
- After changing runtime code reached through
bin/agent-device.mjsor the daemon:pnpm build, thenpnpm clean:daemon— the daemon does not self-reload. - Before any Android verification from source:
pnpm build,pnpm build:android,pnpm clean:daemon.build:androidrefreshes and verifies both bundled Android helper artifacts for the current package version. shutdowndeliberately HANDS OFF a healthy simulator runner. The adopted runner keeps serving the old Swift binary until you kill its process or the source fingerprint changes, so "my change did nothing" measured against an adopted runner is a classic false negative. If Swift runner code changed, runpnpm build:xcuitest.
Prove the path under test was actually active
- Android: capture
snapshot -i --jsonand requireandroidSnapshot.backendto beandroid-helperwithhelperVersionequal topackage.json's version. A stock UIAutomator fallback is not valid verification unless the fallback itself is the behavior under test. - For repo-owned
Agent Device Testerwork,examples/test-app/README.mdis the source of truth for simulator, physical-device, Metro/dev-client, and app-surface steps. An already-installedcom.callstack.agentdevicelabis not sufficient — the README's Metro/dev-build andsnapshot -ichecks must prove the expected app surface is running. - For Android RN/Expo/dev-client apps on any local Metro port,
adb reverse tcp:<port> tcp:<port>is harmless and should be run before opening the app or URL.
Session hygiene
Every manually opened session is a resource that must be closed — including exploratory sessions and failed verification attempts.
- Every
agent-device openneeds a matchingclosewith the same--session,--platform,--udid, and--state-dirbefore the agent finishes. - Use a purpose-specific session name for experiments, and an isolated
--state-dirunder/private/tmpwhen you need cleanup isolation beyond the current worktree's default daemon. - Track opened sessions in working notes; close each one before the final response.
- If
closeis blocked or ownership looks stuck, inspect it withagent-device device status --stale(daemonless), stop the owning daemon withagent-device daemon stop --state-dir <dir>(add--cleanto remove retained runners), and release provably dead owners withagent-device device release --stale. Do not hunt PIDs withps/kill. - If cleanup cannot be completed, report the remaining session name, state dir, and the
device status --staleoutput as a blocker.
Sandboxed environments
Start the daemon outside the sandbox with escalation. The daemon binds localhost, and sandboxed runs
fail before any product code executes, with listen EPERM: operation not permitted 127.0.0.1 or
repeated Failed to start daemon/metadata cleanup messages. Those are not agent-device regressions —
rerun with escalation. Unit tests, typecheck, lint, and build can stay sandboxed unless they need
devices or listener access.