Skip to content

Commit a8701a3

Browse files
committed
docs: document acp as first-class interface
1 parent 6d9460d commit a8701a3

10 files changed

Lines changed: 61 additions & 31 deletions

CONTEXT.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
best-effort signaling. It must not own domain cleanup policy such as browser ownership markers,
4444
runner lease reclamation, daemon takeover checks, or app-log PID metadata verification.
4545
- Command surface: catalog of public command identity, interface exposure, adapter policy, and shared command metadata across CLI, Node.js, MCP, ACP, and batch entrypoints.
46+
- MCP/ACP adapters: MCP is the structured-tool projection of the command surface; ACP is the deterministic prompt-line projection for ACP clients. Both reuse command metadata and `AgentDeviceClient` execution, and neither owns daemon route policy.
4647
- Daemon command registry: daemon-side source of truth for command route ownership and request-policy traits, including admission exemptions, session locking, selector validation, replay-scoped actions, recording invalidation, Android dialog guards, and request provider device resolution.
4748
- Runner command traits: per-command-type classification for iOS/macOS runner lifecycle behavior, distinct from the public command surface and daemon command registry. The Swift runner traits classify interaction, read-only, and runner-lifecycle axes for XCTest execution; Swift resolves the alert command as read-only only for its `get` action. The TypeScript runner command traits classify daemon-side runner send/recovery policy such as read-only retry routing, readiness probes, and recent-healthy-mutation preflight skips; the TypeScript table is command-type keyed and currently classifies alert as read-only for daemon retry policy. Each side keeps one source of truth keyed by runner command type.
4849
- Coordinate-first resolved element activation: iOS/macOS runner interaction pattern where a selector or text query resolves the semantic `XCUIElement`, then activation uses the element's resolved center coordinate when a frame is available. This keeps target selection semantic while avoiding `XCUIElement.tap()` post-action element re-resolution after normal navigation. tvOS remains focus/remote-driven.
@@ -69,8 +70,8 @@ The perfect-shape refactor is complete and merged. Its end-state:
6970

7071
- Two derivation registries. One `CommandDescriptor` per command
7172
(`src/core/command-descriptor/registry.ts`) is the single declaration site from which the public
72-
catalog, capability matrix, daemon command registry, batch allowlist, MCP tools, CLI schema, and
73-
the Node client surface are *derived* by parity-tested projection; the dispatch `switch` became a
73+
catalog, capability matrix, daemon command registry, batch allowlist, MCP tools, ACP available
74+
commands, CLI schema, and the Node client surface are *derived* by parity-tested projection; the dispatch `switch` became a
7475
total map keyed on the command-name union (a missing handler is a compile error). One
7576
`PlatformPlugin` per platform family (`src/core/platform-plugin/`) stops core/daemon from branching
7677
on platform, with the Apple plugin the first instance. See

docs/adr/0003-daemon-command-registry.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ registry instead of recreating command string sets. Handler modules own executio
2727
not export duplicate coverage tables to prove route membership.
2828

2929
The daemon registry is internal-only. It must not define CLI grammar, Node.js client options, MCP
30-
schemas, user-facing help, or platform capability support. Those remain owned by the command
31-
contract, projection, help, and capability modules.
30+
schemas, ACP slash/prompt-line behavior, user-facing help, or platform capability support. Those
31+
remain owned by the command contract, projection, help, and capability modules.
3232

3333
## Alternatives Considered
3434

@@ -57,9 +57,9 @@ owns the rationale so future changes do not need to infer it from agent instruct
5757
## Update (2026-06): single-declaration / derivation model
5858

5959
A later proposal (the `CommandDescriptor` direction, now [ADR 0008](0008-command-descriptor-registry.md)) unifies a command's
60-
declarations so the public catalog, capability matrix, CLI/MCP projections, batch allowlist, and this
61-
daemon registry are *derived* from one registration site, to remove the cross-table drift that several
62-
of these surfaces are kept aligned against by convention.
60+
declarations so the public catalog, capability matrix, CLI/MCP/ACP projections, batch allowlist, and
61+
this daemon registry are *derived* from one registration site, to remove the cross-table drift that
62+
several of these surfaces are kept aligned against by convention.
6363

6464
**This ADR's decision stands.** Its boundary is about *ownership* and the *predicate interface*, not
6565
about the physical file a trait is typed in. "Separate source of truth" means separately owned and
@@ -75,9 +75,10 @@ derived daemon registry is therefore permitted **only if** it preserves all of t
7575
predicates (`getDaemonCommandRoute`, `isLeaseAdmissionExempt`, `shouldLockSessionExecution`, …). The
7676
daemon registry remains their sole exposer; derivation changes how the backing table is *built*, not
7777
how it is *read*.
78-
3. **No leakage into public projections.** The catalog/CLI/MCP/help/capability projections must be
79-
type-prevented from reading daemon-only traits, and the daemon registry must still not define CLI
80-
grammar, Node.js options, MCP schemas, user-facing help, or capability support.
78+
3. **No leakage into public projections.** The catalog/CLI/MCP/ACP/help/capability projections must
79+
be type-prevented from reading daemon-only traits, and the daemon registry must still not define
80+
CLI grammar, Node.js options, MCP schemas, ACP prompt-line behavior, user-facing help, or
81+
capability support.
8182
4. **One declaration per concern, enforced by types.** The single registration site must make a missing
8283
or duplicated daemon trait a *compile error* — replacing today's "aligned by convention". This is the
8384
structural improvement that justifies derivation over a separately hand-authored table.

docs/adr/0008-command-descriptor-registry.md

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@ A command's identity is restated, by hand, across roughly ten tables that must s
1010
convention: `PUBLIC_COMMANDS` (`src/command-catalog.ts`), the per-command metadata and family facets
1111
(`src/commands/**`), the capability matrix (`src/core/capabilities.ts`), the daemon command registry
1212
(`src/daemon/daemon-command-registry.ts`, ADR 0003), the structured-batch allowlist
13-
(`src/batch-policy.ts`), the MCP exposure sets, the Node client interface and impl (`src/client-types.ts`,
14-
`src/client.ts`), and the generic-dispatch `switch` (`src/core/dispatch.ts`, whose `default: throw` makes a
15-
missing or renamed command a runtime error, not a compile error). Adding one command touches ~24 files, the
16-
argument shape is (de)serialized ~4 times, and the gesture set is retyped in three places.
13+
(`src/batch-policy.ts`), the MCP exposure sets, ACP available-command projection, the Node client
14+
interface and impl (`src/client-types.ts`, `src/client.ts`), and the generic-dispatch `switch`
15+
(`src/core/dispatch.ts`, whose `default: throw` makes a missing or renamed command a runtime error,
16+
not a compile error). Adding one command touches ~24 files, the argument shape is (de)serialized
17+
~4 times, and the gesture set is retyped in three places.
1718

1819
The codebase already proves the cure works for part of this: the `CommandFamilyFacet`
19-
(`src/commands/family/`) derives the MCP tools, the CLI schema, and the batch writer from a single array.
20-
It simply stops at the command-surface boundary; everything past it is hand-maintained.
20+
(`src/commands/family/`) derives the MCP tools, ACP runnable command list, CLI schema, and the batch
21+
writer from a single array. It simply stops at the command-surface boundary; everything past it is
22+
hand-maintained.
2123

2224
ADR 0003 deliberately separated daemon route/policy into its own internally-owned registry with a small
2325
predicate interface, and its 2026-06 update set four invariants that any single-declaration/derivation
@@ -28,16 +30,23 @@ model must preserve. This ADR is that model.
2830
Introduce one `CommandDescriptor` per command that **composes facets owned by their domains** and from which
2931
every consumer table is **derived** by pure, parity-tested projection:
3032

31-
- The descriptor composes a `surface` facet (owned by `src/commands/**`: identity, CLI schema/reader, MCP),
32-
a `capability` facet (owned by `src/core/capabilities`), and a `daemon` facet (route + request-policy
33-
traits, **owned under `src/daemon/`** per ADR 0003), plus a typed result.
34-
- The public catalog, capability matrix, daemon command registry, batch allowlist, MCP tool list, CLI
35-
schema, and the Node client surface become pure projections of the descriptor set. The
33+
- The descriptor composes a `surface` facet (owned by `src/commands/**`: identity, CLI schema/reader,
34+
MCP, and ACP prompt-line exposure), a `capability` facet (owned by `src/core/capabilities`), and a
35+
`daemon` facet (route + request-policy traits, **owned under `src/daemon/`** per ADR 0003), plus a
36+
typed result.
37+
- The public catalog, capability matrix, daemon command registry, batch allowlist, MCP tool list, ACP
38+
available-command list, CLI schema, and the Node client surface become pure projections of the
39+
descriptor set. The
3640
`src/core/dispatch.ts` `switch` is replaced by a total map keyed on the command-name union, so a missing
3741
handler is a compile error.
3842
- The cross-process `invoke` (client) and in-daemon `execute` seams stay distinct; the process boundary is
3943
never collapsed.
4044

45+
ACP is a consumer of the command surface, not a new command registry. It advertises the same runnable
46+
commands through `available_commands_update` and parses prompt text into CLI-shaped command lines
47+
before executing through the existing command contracts and `AgentDeviceClient` path. Its slash-command
48+
syntax is an ACP transport affordance, not a separate command identity.
49+
4150
This **composes with**, and is bound by, ADR 0003's four invariants: daemon-owned declaration (never inlined
4251
into the public surface), the predicate interface unchanged, no leakage of daemon-only traits into public
4352
projections, and one declaration per concern enforced by the type system.

docs/adr/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
| [0005 iOS Runner Interaction Lifecycle](0005-ios-runner-interaction-lifecycle.md) | XCTest runner sessions, leases, adoption, idle-stop |
1010
| [0006 Daemon RPC Protocol Version](0006-daemon-rpc-protocol-version.md) | remote daemon HTTP/JSON-RPC compatibility |
1111
| [0007 Remote Device Leases](0007-remote-device-leases.md) | leases, tenancy, provider-owned devices |
12-
| [0008 Command Descriptor Registry](0008-command-descriptor-registry.md) | adding/changing a command, any surface projection (CLI/MCP/client/batch), timeout policy |
12+
| [0008 Command Descriptor Registry](0008-command-descriptor-registry.md) | adding/changing a command, any surface projection (CLI/MCP/ACP/client/batch), timeout policy |
1313
| [0009 Apple Platform Consolidation](0009-apple-platform-consolidation.md) | Apple platform family, apple/appleOs axes, the apple-leak guard |
1414
| [0010 Error system conventions](0010-error-system.md) | error codes, hints, normalizeError, typed error signals |
1515
| [0011 Interaction Guarantee Contract](0011-interaction-guarantee-contract.md) | interaction dispatch paths, fast paths, guards, the guarantee matrix, parity tables |

src/utils/cli-command-overrides.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ type SchemaOnlyCliCommandName = Exclude<LocalCliCommandName, CommandName>;
1111

1212
const SCHEMA_ONLY_CLI_COMMAND_SCHEMAS = {
1313
acp: {
14-
helpDescription:
15-
'Start the stdio ACP (Agent Client Protocol) agent. Prompts are interpreted as agent-device command lines, one per line, executed through the agent-device client.',
14+
helpDescription: `Start the stdio ACP (Agent Client Protocol) agent.
15+
16+
ACP is a deterministic agent interface for ACP-capable editors and agent clients. It does not add LLM behavior: each text prompt line is parsed as one agent-device command line, with optional ACP slash-command syntax such as /devices or /snapshot -i. Commands execute through the same command contracts and AgentDeviceClient path as CLI/MCP commands, while stdout remains newline-delimited JSON-RPC only.`,
1617
summary: 'Start ACP agent',
1718
},
1819
cdp: {

website/docs/docs/agent-setup.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ description: Configure Cursor, Codex, Claude Code, Windsurf, Cline, Goose, Zed,
77

88
`agent-device` is built for AI agents, but humans usually install it, grant device permissions, and decide which agent client should use it.
99

10-
Use this page to wire Cursor, Codex, Claude Code, Windsurf, Cline, Goose, or another coding agent into mobile, TV, desktop, and web app verification. It covers skills, project rules, and MCP setup for React Native QA, Expo app verification, iOS Simulator automation, Android Emulator automation, tvOS checks, Android TV checks, web browser sessions, debugging, profiling, and exploratory QA.
10+
Use this page to wire Cursor, Codex, Claude Code, Windsurf, Cline, Goose, Zed, ACP clients, or another coding agent into mobile, TV, desktop, and web app verification. It covers skills, project rules, MCP setup, and ACP setup for React Native QA, Expo app verification, iOS Simulator automation, Android Emulator automation, tvOS checks, Android TV checks, web browser sessions, debugging, profiling, and exploratory QA.
1111

12-
The short version: install the CLI, make the agent read version-matched help, and let the agent use either MCP tools or CLI commands. MCP tools use command contracts backed by the same `AgentDeviceClient` execution path as the CLI adapters.
12+
The short version: install the CLI, make the agent read version-matched help, and let the agent use CLI commands, MCP tools, or the ACP agent depending on what its client supports. MCP tools and ACP command turns use command contracts backed by the same `AgentDeviceClient` execution path as the CLI adapters.
1313

1414
## Prerequisite: install the CLI
1515

@@ -295,7 +295,7 @@ If the client has project rules or custom instructions, add the recommended agen
295295

296296
## Why this setup works
297297

298-
The CLI stays the auditable automation surface, installed help stays version-matched with the commands, skills and rules route agents toward the right help topics, and MCP gives compatible clients direct structured tools backed by the same daemon/client implementation.
298+
The CLI stays the auditable automation surface, installed help stays version-matched with the commands, skills and rules route agents toward the right help topics, MCP gives compatible clients direct structured tools, and ACP gives compatible clients a deterministic prompt-line agent backed by the same daemon/client implementation.
299299

300300
For the broader positioning, supported targets, observability features, and how `agent-device` differs from scripted test frameworks, see [Introduction](/docs/introduction). For exact command groups and platform behavior, see [Commands](/docs/commands).
301301

website/docs/docs/commands.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ agent-device mcp
3232

3333
The MCP server exposes direct structured tools for installed commands. Tools use structured input contracts through `AgentDeviceClient`; local-only workflows stay CLI-only rather than subprocess fallbacks. It does not expose generic shell execution over MCP. MCP tools can target `platform: "web"` after `agent-device web setup`, but setup and doctor stay CLI-only.
3434

35+
For ACP-aware clients that support Agent Client Protocol agents, run:
36+
37+
```bash
38+
agent-device acp
39+
```
40+
41+
The ACP agent exposes installed commands as a deterministic prompt-line interface. ACP clients send prompt text such as `/devices` or `snapshot -i`; `agent-device` parses one command per line, executes through the same command contracts and `AgentDeviceClient` path, streams ACP tool-call updates, and refuses natural-language prompts instead of guessing.
42+
3543
## Navigation
3644

3745
```bash

website/docs/docs/installation.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ agent-device help cdp
2626

2727
Some agent clients run commands in an environment that differs from the user's normal install shell. If `agent-device` is missing in the agent terminal but was installed globally elsewhere, resolve the command the same way the user would from a normal terminal session, then use the absolute binary path for agent commands. This may require inspecting shell startup behavior or package-manager/global bin locations; do not assume the agent process `PATH` is the user's `PATH`.
2828

29-
For Cursor, Codex, Claude Code, Windsurf, Cline, Goose, skills, and project rules, see [AI Agent Setup](/docs/agent-setup). For the first app automation commands, see [Quick Start](/docs/quick-start).
29+
For Cursor, Codex, Claude Code, Windsurf, Cline, Goose, skills, MCP, ACP, and project rules, see [AI Agent Setup](/docs/agent-setup). For the first app automation commands, see [Quick Start](/docs/quick-start).
3030

3131
Interactive CLI runs periodically check for a newer published `agent-device` package in the background. When an upgrade is available, the CLI suggests reinstalling the package globally:
3232

@@ -37,15 +37,21 @@ agent-device --version
3737

3838
Set `AGENT_DEVICE_NO_UPDATE_NOTIFIER=1` to disable the notice.
3939

40-
## Agent clients and MCP
40+
## Agent clients, MCP, and ACP
4141

4242
The official MCP server exposes direct structured tools for installed `agent-device` commands. Tools use command contracts through `AgentDeviceClient`, so app and device automation still uses the same daemon implementation.
4343

4444
```bash
4545
agent-device mcp
4646
```
4747

48-
Use [AI Agent Setup](/docs/agent-setup#mcp-server) for copy-paste MCP client configuration.
48+
The ACP agent exposes the same command surface to ACP-capable editors and agent clients as explicit prompt lines. It is deterministic: prompt text such as `/devices` or `snapshot -i` is parsed as command lines and executed through `AgentDeviceClient`; natural-language instructions are refused instead of guessed.
49+
50+
```bash
51+
agent-device acp
52+
```
53+
54+
Use [AI Agent Setup](/docs/agent-setup) for copy-paste MCP and ACP client configuration.
4955

5056
## Without installing
5157

website/docs/docs/introduction.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ agent-device help cdp
5353
agent-device help dogfood
5454
```
5555

56-
Use [AI Agent Setup](/docs/agent-setup) for Cursor, Codex, Claude Code, Windsurf, Cline, Goose, skills, and MCP setup. Use [Commands](/docs/commands) for detailed command groups and platform behavior.
56+
Use [AI Agent Setup](/docs/agent-setup) for Cursor, Codex, Claude Code, Windsurf, Cline, Goose, skills, MCP setup, and ACP setup. Use [Commands](/docs/commands) for detailed command groups and platform behavior.
5757

5858
## Where it fits
5959

@@ -63,6 +63,8 @@ It complements scripted test frameworks such as Appium, Maestro, Detox, XCTest,
6363

6464
MCP support exposes direct structured tools for installed `agent-device` commands. Tools use structured input contracts through `AgentDeviceClient`, so MCP clients can call device workflows directly while the daemon remains the execution source of truth.
6565

66+
ACP support exposes a deterministic stdio agent for ACP-capable editors and agent clients. The ACP agent interprets prompt text as explicit `agent-device` command lines, including advertised slash commands such as `/devices`, and executes them through the same command contracts and `AgentDeviceClient` path. It is not an LLM and does not guess natural-language actions.
67+
6668
## Next steps
6769

6870
- Install the CLI: [Installation](/docs/installation)

website/docs/docs/security-trust.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ description: Security and trust guidance for agent-device local app automation,
1111

1212
- Device automation runs through the installed CLI and platform tooling such as Xcode, ADB, macOS accessibility APIs, and Linux AT-SPI.
1313
- The MCP server exposes direct structured tools for `agent-device` commands. Tools use command contracts through `AgentDeviceClient`; local-only workflows stay CLI-only rather than subprocess fallbacks. It does not expose generic shell execution over MCP.
14+
- The ACP agent exposes a deterministic prompt-line interface for ACP clients. It accepts explicit command lines and advertised slash commands, executes them through `AgentDeviceClient`, and refuses prompts that do not contain runnable commands. It is not a generic shell or an LLM.
15+
- MCP and ACP stdio stdout are protocol channels. Do not wrap these commands with logging or banner output on stdout; use stderr or client-side logs for diagnostics.
1416
- Mutating commands should run serially against one session. Use separate sessions/devices for parallel work.
1517

1618
## Daemon trust model

0 commit comments

Comments
 (0)