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 extensioncursor:cursor/ask_questionis a question’s card,cursor/create_planthe card « Plan à approuver » (its tasks in the plan too),cursor/update_todosthe task list; a subagent (task,subagent_spawned) speaks under its own session, shown under itsTask; a tool of an MCP server israwInput.providerIdentifierandtoolName; Auto isdefault[]; a turn Cursor refuses ends on its words (« Upgrade your plan to continue »). - gemini
- Gemini CLI’s ways beside ACP (the extension
geminiof 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 intests/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 addandgit commitof 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:executeisBash,editEdit(orWritefor a file added),deleteDelete,readRead,searchGrep(orGlob),fetchWebFetch; another is shown by its title. A write’s diff (contentof typediff) is its result. - vibe
- Mistral Vibe’s ways beside ACP (the extension
vibeof a manifest, INT-10.6), as the core’s own client of Vibe 3.0.3 drove it (ESC-265 to 268, its streams intests/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 (
paramsofsession/request_permission) names a path offence(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
pathis in the folderdir(or is it), whatever its slashes and case. - mcp_
servers - What
session/newandsession/loadare 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) namespathor 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) ofkind(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/loadkeeps 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.