From e30084ea24c3d2430867cdcdcba4cc9a7cca81eb Mon Sep 17 00:00:00 2001 From: Miguel Palhas Date: Sun, 6 Sep 2026 18:48:24 +0100 Subject: [PATCH] docs(maestro): document Codex structured installation --- crates/maestro-acp/Cargo.toml | 2 +- crates/maestro-acp/src/lib.rs | 16 ++++++++-------- crates/maestro-protocol/src/lib.rs | 2 +- docs/INSTALL.md | 21 ++++++++++++--------- web/src/types.ts | 2 +- 5 files changed, 23 insertions(+), 20 deletions(-) diff --git a/crates/maestro-acp/Cargo.toml b/crates/maestro-acp/Cargo.toml index cab090d..0456094 100644 --- a/crates/maestro-acp/Cargo.toml +++ b/crates/maestro-acp/Cargo.toml @@ -5,7 +5,7 @@ edition.workspace = true license.workspace = true repository.workspace = true publish.workspace = true -description = "ACP client role: one claude-code-acp child per structured session" +description = "ACP client role: one provider adapter child per structured session" [dependencies] agent-client-protocol.workspace = true diff --git a/crates/maestro-acp/src/lib.rs b/crates/maestro-acp/src/lib.rs index e001fda..f5316a5 100644 --- a/crates/maestro-acp/src/lib.rs +++ b/crates/maestro-acp/src/lib.rs @@ -1,5 +1,5 @@ -//! ACP client role for the daemon (#134): one `claude-code-acp` child per -//! structured session. +//! ACP client role for the daemon: one provider adapter child per structured +//! session. //! //! The daemon is the client; the adapter is the agent. [`spawn`] starts the //! adapter as a child process with stdio pipes, in the session's `cwd` with @@ -9,10 +9,10 @@ //! //! **The handshake declares almost nothing.** `initialize` reports //! `fs.readTextFile`, `fs.writeTextFile` and `terminal` as `false`, so the -//! adapter uses Claude Code's own Read / Write / Bash instead of asking the -//! daemon to act on its behalf — exactly what already happens in the -//! terminal view. `session/request_permission` is the one client method that -//! gets a real implementation, in #139; here it is a stub that declines. +//! adapter uses the provider's own file and command tools instead of asking +//! the daemon to act on its behalf — exactly what already happens in the +//! terminal view. `session/request_permission` is the one client method with +//! a real implementation. //! //! Every `session/update` notification the adapter sends lands on an //! unbounded channel the session owns ([`AcpSession::take_updates`]). Nothing @@ -96,8 +96,8 @@ pub const INSTALL_COMMAND: &str = "npm install -g --prefix ~/.local @zed-industries/claude-code-acp"; /// How long `initialize` + `session/new` may take before the spawn is -/// declared failed. The real adapter boots a node process and the Claude -/// Code SDK behind it; a slow machine takes seconds, never a minute. +/// declared failed. The real adapters boot a node process and their provider +/// client behind it; a slow machine takes seconds, never a minute. pub const HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(60); /// How long [`AcpSession::terminate`] waits after `session/cancel` before diff --git a/crates/maestro-protocol/src/lib.rs b/crates/maestro-protocol/src/lib.rs index b707af0..03cd125 100644 --- a/crates/maestro-protocol/src/lib.rs +++ b/crates/maestro-protocol/src/lib.rs @@ -123,7 +123,7 @@ pub struct Session { /// daemon that predates the field keeps working untouched. #[serde(default)] pub view: SessionView, - /// The ACP session id the `claude-code-acp` adapter handed back from + /// The ACP session id the selected provider adapter handed back from /// `session/new` (#134). Only a [`SessionView::Structured`] session has /// one, and only once its handshake succeeded; a later respawn passes it /// to `session/load` so the conversation continues (#135). Distinct from diff --git a/docs/INSTALL.md b/docs/INSTALL.md index d17f8a5..a515efe 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -195,25 +195,28 @@ An unknown name is rejected as an `[tui].theme` configuration error. The full action vocabulary is the `Action` enum in `crates/maestro-tui/src/action.rs`. -## Structured sessions: `claude-code-acp` +## Structured sessions: ACP adapters -A session spawned with `view: Structured` (#134) runs Claude Code as a child +A session spawned with `view: Structured` runs Claude Code or Codex as a child of the daemon over the Agent Client Protocol instead of in a tmux pane. The -daemon resolves the adapter binary, `claude-code-acp`, on its `PATH` at spawn -time. Install it once per host: +resolved session command selects the adapter binary, which must be on the +session's `PATH` when the spawn request sets one, or the daemon's `PATH` +otherwise. Install the adapter for each provider you use: ```sh npm install -g --prefix ~/.local @zed-industries/claude-code-acp +npm install -g --prefix ~/.local @agentclientprotocol/codex-acp ``` -That puts `claude-code-acp` in `~/.local/bin`, which must be on the daemon's -`PATH` (a systemd user unit does not read your shell profile; set +That puts `claude-code-acp` and `codex-acp` in `~/.local/bin`, which must be on +the applicable `PATH` (a systemd user unit does not read your shell profile; set `Environment=PATH=…` in the unit or install somewhere already on it). The -adapter needs a logged-in Claude Code (`claude /login`). +Claude adapter needs a logged-in Claude Code (`claude /login`); Codex uses the +Codex CLI's or adapter's configured authentication. When the adapter is missing the spawn still creates the session, marked dead -with the install command above as its activity detail, so the sidebar says -what to run. The adapter is a child of the daemon: it ends with a `DELETE +with the provider-specific install command as its activity detail, so clients +say what to run. The adapter is a child of the daemon: it ends with a `DELETE /api/sessions/:id` (`session/cancel`, then `SIGTERM`) and with the daemon itself. A daemon restart ends an in-flight structured turn, but preserves its worktree, session record, and event-log transcript. The replacement daemon diff --git a/web/src/types.ts b/web/src/types.ts index e135ce0..5238b4e 100644 --- a/web/src/types.ts +++ b/web/src/types.ts @@ -56,7 +56,7 @@ export interface Session { * how the command bar's empty query sorts a never-focused session after every * session that has one (`docs/COMMAND-BAR.md`). */ last_focused_at?: IsoTimestamp | null; - /** The ACP session id the `claude-code-acp` adapter returned from + /** The ACP session id the selected provider adapter returned from * `session/new` (#134). Only a `Structured` session whose handshake * succeeded has one; a respawn passes it to `session/load` (#135). */ acp_session_id?: string | null;