feat(acp): endpoint registry + RemoteState per-agent keying (agent-consoles slice 1) - #66
Merged
Merged
Conversation
…nsoles slice 1) ADR agent-consoles Part B: generalize the single `remote.toml` connection into a registry of named `/acp` endpoints and rekey the live-connection state per agent, so Studio can reach N agents instead of one. - crates/acp-tunnel/config.rs: add `AgentEndpoint` (name + url/token/cwd + `management` flag) and `AgentRegistry` (`[[agent]]` in agents.toml). Explicit fields + a `conn()` accessor reuse `RemoteConfig` validation as one source of truth (no serde-flatten, which is order-fragile under toml). `from_legacy` adopts a `remote.toml` as one `management = true` entry. Structural `validate` (unique non-empty names, ≤1 management). Unit-tested. - src-tauri/remote.rs: `Remote` is now `HashMap<name, RemoteState>` — each agent console has its own task/status/reconnect. `oab` reverse-MCP tools are declared only when the endpoint is `management` (least privilege, Part A); an ordinary agent console runs chat-only. `remote-status` / `agent-update` events carry an `agent` field so the UI can route per console. `agents.toml` preferred, legacy `remote.toml` adopted when absent. `disconnect_all` on app teardown. - src-tauri/lib.rs: remote_connect/disconnect + agent_prompt/cancel take an optional `agent` (None ⇒ management, so the current single-console UI is unchanged); new `remote_agents` command lists the registry + live status for the slice-2 selector. Backend-only; the frontend still drives the management endpoint. Desktop crate is built by the bundle-macos CI job (GTK libs absent locally). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
brettchien
added a commit
that referenced
this pull request
Aug 17, 2026
…s slice 2) (#67) * feat(acp): per-agent endpoint registry + RemoteState keying (agent-consoles slice 1) (#66) ADR agent-consoles Part B: generalize the single `remote.toml` connection into a registry of named `/acp` endpoints and rekey the live-connection state per agent, so Studio can reach N agents instead of one. - crates/acp-tunnel/config.rs: add `AgentEndpoint` (name + url/token/cwd + `management` flag) and `AgentRegistry` (`[[agent]]` in agents.toml). Explicit fields + a `conn()` accessor reuse `RemoteConfig` validation as one source of truth (no serde-flatten, which is order-fragile under toml). `from_legacy` adopts a `remote.toml` as one `management = true` entry. Structural `validate` (unique non-empty names, ≤1 management). Unit-tested. - src-tauri/remote.rs: `Remote` is now `HashMap<name, RemoteState>` — each agent console has its own task/status/reconnect. `oab` reverse-MCP tools are declared only when the endpoint is `management` (least privilege, Part A); an ordinary agent console runs chat-only. `remote-status` / `agent-update` events carry an `agent` field so the UI can route per console. `agents.toml` preferred, legacy `remote.toml` adopted when absent. `disconnect_all` on app teardown. - src-tauri/lib.rs: remote_connect/disconnect + agent_prompt/cancel take an optional `agent` (None ⇒ management, so the current single-console UI is unchanged); new `remote_agents` command lists the registry + live status for the slice-2 selector. Backend-only; the frontend still drives the management endpoint. Desktop crate is built by the bundle-macos CI job (GTK libs absent locally). Co-authored-by: Orca <orca@openab.dev> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * feat(console): reusable chat panel + agent-console shell (agent-consoles slice 2 · pt2) Turns the chat panel into the per-endpoint primitive the ADR calls for and adds the agent-console shell on top of it (ADR agent-consoles Parts A/C): - chatPanel.ts: extract the management chat wiring (transcript, one-turn queue, streaming spinner, stop/copy) into `createChatPanel({agent, source, mock})`. Each panel owns its own state + DOM listeners (AbortController-scoped) and is keyed by endpoint name; `onChunk`/`onTurnEnd`/`setConnected` feed it events. - main.ts: the management console now mounts this primitive. One `agent-update` /`remote-status` subscription routes each event to the owning panel by name (`chatPanels` map); the management endpoint's name is learned from the registry. - agentConsole.ts: selector over `remote_agents` + a per-agent console that dials on open (`remote_connect(agent)`), tears down on close, shows read-only config, and mounts a chat panel bound to that agent. One console open at a time. - render.ts: pure `agentListHtml` + `agentConsoleHeaderHtml`. - index.html: the agents section (selector + console with its own chat region). Read-only per ADR §6 — the file editor's write path waits on the openab `fs/*` wire (slices 3–4). Reverse-MCP `oab` stays gated to the management binding. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(console): agent selector/header render tests + agent-console styles - render.test.ts: cover `agentListHtml` (openable vs management vs unconfigured rows, open-marking, escaping) and `agentConsoleHeaderHtml` (identity/target/ status, no token leak, read-only note). 75 tests green. - styles.css: the agents selector + open-console layout, reusing the chat-wrap and identity `id-field` primitives so the surfaces read as one system. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Orca <orca@openab.dev> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Aug 17, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Slice 1 of 4 for the agent-consoles ADR (#49). Generalizes Studio's single
/acpconnection into a registry of named endpoints and rekeys the live-connection state per agent — the foundation N agent consoles need. Backend-only; the current single management console is unchanged.Changes
crates/acp-tunnel/config.rs—AgentEndpoint(name+url/token/cwd+managementflag) andAgentRegistry([[agent]]inagents.toml). Explicit fields + aconn()accessor reuseRemoteConfig's validation as one source of truth (noserde(flatten)— it's order-fragile undertomlserialization).from_legacyadopts aremote.tomlas onemanagement = trueentry. Structuralvalidate(unique non-empty names, ≤1 management). Fully unit-tested.src-tauri/remote.rs—Remoteis nowHashMap<name, RemoteState>; each agent console owns its task/status/reconnect. Reverse-MCPoabtools are declared only for themanagementendpoint (least privilege, ADR Part A) — an ordinary agent console runs chat-only.remote-status/agent-updateevents now carry anagentfield for per-console routing.agents.tomlpreferred; legacyremote.tomladopted when absent.disconnect_allon teardown.src-tauri/lib.rs—remote_connect/remote_disconnect+agent_prompt/agent_canceltake an optionalagent(None⇒ management, so the existing UI's arg-less calls keep working). Newremote_agentscommand lists the registry + live status for the slice-2 selector.Back-compat
No
agents.tomlyet? The registry adopts the existingremote.tomlas the sole management entry, and every command defaults to it. The frontend is untouched in this slice, so behaviour is identical until slice 2 adds the selector.Testing
cargo test -p acp-tunnelgreen (registry parse / legacy shim / validate / round-trip). The desktop crate (src-tauri) needs GTK/glib and is compiled by the bundle-macos CI job.Stacked slices to follow: 2 (agent console shell + per-endpoint chat), 3 (file-editor read path), 4 (write/apply behind the upstream
fs/*wire).🤖 Generated with Claude Code