Skip to main content

Crate escouade_acp

Crate escouade_acp 

Source
Expand description

§escouade-acp

The ACP (Agent Client Protocol, version 1) client of Escouade: a state machine that reads an agent’s lines and answers the items of the conversation and the lines to write back to it, with no process or runtime of its own. It compiles for wasm32-wasip1 too.

use escouade_acp::Agent;
use escouade_plugin_protocol::engine::{Attach, HarnessDecl};
use serde_json::json;

let harness: HarnessDecl = serde_json::from_value(json!({ "id": "example", "name": "Example", "acp": {} })).unwrap();
let mut agent = Agent::new(&Attach::default(), &harness, "2.2.0");

// What the program wrote, line by line: the items of the conversation, and those that say what to write back.
let items = agent.frames(&[json!({ "jsonrpc": "2.0", "method": "session/update", "params": {} }).to_string()]);
assert!(items.len() <= 1);

The reference of the plugins: https://escouade.dev/en/docs/plugins/api. The code is in Escouade’s repository. This crate is under the MIT licence; the app is under GPL-3.0-or-later.

§Internals

The ACP client of Escouade (Agent Client Protocol v1: JSON-RPC 2.0, one message a line on the agent’s input and output), drawn from the one Cursor CLI was driven with (engine/cursor/, agent/cursor.rs of the app), with what is Cursor’s own (cursor/*) kept apart in cursor (docs/PLUGINS.md §1.1, PLG-6).

It holds no process: Agent is a state machine that reads what the agent wrote (Agent::frames) and answers the normalized items of the conversation (escouade_plugin_protocol::engine::Item) and the lines to write back to it (Item::Write, or the writes of an answer), as the contract of the harnesses in process wants it (INT-9). The plugin dev.escouade.acp (escouade-plugins acp) runs one for each agent of a harness a manifest describes (contributes.harnesses[].acp).

The helpers at the top are those of the ACP harnesses, and of Antigravity CLI, whose client puts its stream in the form of this one (plugins/antigravity, INT-10.8).

Re-exports§

pub use agent::Agent;
pub use tools::call_id;
pub use tools::content_text;
pub use tools::diff_of;
pub use tools::line_hunks;
pub use tools::tool_of;

Modules§

agent
One agent on an ACP harness, as the client sees it: what it asked of the agent and waits for, what the agent asks and waits for (a permission, a question), the session, the turn under way, the calls and their diffs.
cursor
What is Cursor CLI’s own beside ACP (its extensions cursor/*, read on 2026.10.22: ESC-24, tests/fixtures/engines/cursor-2026.10.22-27dcf5f.acp.json), for a harness whose manifest names the extension cursor: cursor/ask_question is a question’s card, cursor/create_plan the card « Plan à approuver » (its tasks in the plan too), cursor/update_todos the task list; a subagent (task, subagent_spawned) speaks under its own session, shown under its Task; a tool of an MCP server is rawInput.providerIdentifier and toolName; Auto is default[]; a turn Cursor refuses ends on its words (« Upgrade your plan to continue »).
gemini
Gemini CLI’s ways beside ACP (the extension gemini of a manifest, INT-10.7), as the core’s own client of Gemini CLI 0.66.0 drove it (ESC-273 to 275, its streams in tests/fixtures/gemini/):
git
The git commands Escouade accepts for an agent of Codex without asking, in « Édits auto » and « Auto » (docs/PROTOCOL.md, « Codex app-server », « Les modes »): git add and git commit of its own worktree, which Codex’s sandbox never lets write in .git. Such a command runs out of the sandbox, with the network: anything that is not plainly one of them is asked.
limits
The usage limits Google’s harnesses tell in their words (Antigravity CLI’s, read in its program, ESC-269, and Gemini CLI’s, which says the same of its model’s capacity).
paths
The fence of private projects on the files an agent reads and writes through the client (fs/read_text_file, fs/write_text_file): the barrier that holds, so compared by the paths’ components, never by their text. A path must be absolute (ACP asks it); its . and .. are taken out without the disk, then the longest part of it that exists is canonicalized (links and junctions followed, without the \\?\ prefix of Windows) and the rest put back; under Windows, the case is ignored. The file is then opened at that very path (resolve), never at the text the agent sent: under Unix the kernel follows a link before it takes a .. (link/../secret), so the text could open another file than the one checked.
questions
The questions of an agent that has no tool to ask in ACP (Gemini CLI, Goose): the first message tells it to end its turn on a block <escouade_question>{"questions": […]}</escouade_question>, which the client takes out of the text and shows as a question’s card; the answers go back as the next message. Shared with the core’s Gemini CLI and Antigravity CLI.
tools
The calls of an ACP agent under the names Claude Code gives its tools, by their kind: execute is Bash, edit Edit (or Write for a file added), delete Delete, read Read, search Grep (or Glob), fetch WebFetch; another is shown by its title. A write’s diff (content of type diff) is its result.
vibe
Mistral Vibe’s ways beside ACP (the extension vibe of a manifest, INT-10.6), as the core’s own client of Vibe 3.0.3 drove it (ESC-265 to 268, its streams in tests/fixtures/vibe/):

Constants§

PROTOCOL
The version of ACP Escouade speaks.
SERVER
The name of Escouade’s MCP server, as its agents know it.

Functions§

fenced
« Projet privé » (ESC-140): whether the permission an agent asks (params of session/request_permission) names a path of fence (as its program names them): its command, its title, the files it writes or reads. A command can reach a path it does not name: a guard, not a barrier; what holds is the files read and written through the client (Agent, fs/*).
inside
Whether path is in the folder dir (or is it), whatever its slashes and case.
mcp_servers
What session/new and session/load are given of MCP servers: Escouade’s (its address and token; the token in a header, on the process’s input, never its command line), or none. An entry of the user’s of that name is replaced by it (tried with Cursor CLI).
names
Whether text (a path, a command) names path or a path under it, whatever its separators and, under Windows, its case. A guard: a longer name that starts alike counts too.
option_of
The option of a permission (session/request_permission) of kind (allow_once, allow_always, reject_once), by the id the agent gave it.
preamble
The instructions added to an agent (a ticket’s protocol), as they go before its first message: ACP has no system message, and session/load keeps them (tried with Cursor CLI).
relayed
What was said in the agent’s own interface (« Vue Cursor », the core’s relay), as it goes before its next message.