Skip to content

Commit 921d470

Browse files
authored
Merge pull request #445 from Mng-dev-ai/feat/acp-transport
Add ACP transport with multi-agent Claude/Codex support
2 parents e94b855 + 3b22e67 commit 921d470

186 files changed

Lines changed: 4193 additions & 9630 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ REDIS_PORT=6379
88
DOCKER_IMAGE=ghcr.io/mng-dev-ai/agentrove-sandbox:latest
99

1010
BACKEND_PORT=8080
11-
VNC_PORT=5900
12-
VNC_WS_PORT=6080
13-
OPENVSCODE_PORT=8765
1411

1512
DATABASE_URL=postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
1613
REDIS_URL=redis://redis:6379/0

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,7 @@ backend/*beat-schedule*
8585
.bashrc
8686
.claude.json
8787
.codex/
88-
.ide_connection_token
8988
.npm/
90-
.openvscode-server/
9189
.git-askpass.sh
9290
.gitconfig
9391
Library/

CLAUDE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@
6868
- When a function receives an optional targeting parameter (e.g., `cwd`, `workspace_id`) and the value is provided but invalid, raise an error — do not silently fall back to a default target, as this causes the operation to succeed against the wrong resource
6969
- When adding new operations in a domain where existing operations already accept a context/targeting parameter (e.g., `cwd` for worktree paths), propagate that parameter through all new operations in the same chain — backend endpoint, frontend service, React Query hook, and UI component
7070
- When multiple endpoints share the same parameter validation (e.g., token presence check), extract it into a FastAPI dependency that raises on failure and returns the validated value — do not duplicate the check inline in each endpoint
71+
- Do not extract a shared React hook when callers must add `useCallback`/`useMemo` wrappers that the inline version did not need — the per-call-site ceremony can exceed the duplication it removes
72+
- When closing, cleaning up, or tearing down multiple independent resources in a loop, use `asyncio.gather(*[...], return_exceptions=True)` instead of sequential awaits — serializing I/O across independent resources wastes time, especially during shutdown or idle cleanup
73+
- When catching a `ServiceException` subclass at the API boundary to produce an `HTTPException`, use `exc.status_code` from the exception — do not hardcode a status code constant (e.g., `HTTP_500`) that shadows the exception's own classification
7174

7275
## Naming Conventions
7376

README.md

Lines changed: 89 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Agentrove
22

3-
Self-hosted Claude Code workspace with multi-provider routing, sandboxed execution, and a full web IDE.
3+
Self-hosted AI coding workspace with Claude and Codex agents, isolated sandboxes, and a full web IDE.
44

55
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
66
[![Python 3.13](https://img.shields.io/badge/python-3.13-blue.svg)](https://www.python.org/)
@@ -21,84 +21,106 @@ Join the [Discord server](https://discord.gg/HvkJU8dcBA).
2121

2222
## Why Agentrove
2323

24-
- Claude Code as the execution harness, exposed through a self-hosted web UI
25-
- One workflow across Anthropic, OpenAI, GitHub Copilot, OpenRouter, and custom Anthropic-compatible endpoints
26-
- Anthropic Bridge routing for non-Anthropic providers while preserving Claude Code behavior
27-
- Isolated sandbox backends (Docker, host)
28-
- Extension surface: MCP servers, skills, agents, slash commands, prompts, and marketplace plugins
29-
- Provider switching with shared working context
24+
- Run Claude Code and Codex from one self-hosted interface
25+
- Keep each project in its own Docker or host sandbox
26+
- Work in chat, editor, terminal, diff, secrets, and PR review views side by side
27+
- Reuse the same workspace context across chats and sub-threads
28+
- Manage MCP servers, agents, skills, commands, personas, env vars, and marketplace plugins from the app
3029

3130
## Core Architecture
3231

3332
```text
3433
React/Vite Frontend
3534
-> FastAPI Backend
36-
-> PostgreSQL + Redis (web/docker mode)
35+
-> PostgreSQL + Redis (web mode)
3736
-> SQLite + in-memory cache/pubsub (desktop mode)
38-
-> Sandbox runtime (Docker/Host)
39-
-> Claude Code CLI + claude-agent-sdk
37+
-> Workspace sandbox (Docker or Host)
38+
-> Claude Code ACP / Codex ACP
39+
-> Claude Code CLI / Codex CLI
4040
```
4141

42-
### Claude Code harness
42+
The app can launch either:
4343

44-
Agentrove runs chats through `claude-agent-sdk`, which drives the Claude Code CLI in the selected sandbox. This keeps Claude Code-native behavior for tools, session flow, permission modes, and MCP orchestration.
45-
46-
### Anthropic Bridge for non-Anthropic providers
47-
48-
For OpenAI, OpenRouter, and Copilot providers, Agentrove starts `anthropic-bridge` inside the sandbox and routes Claude Code requests through:
49-
50-
- `ANTHROPIC_BASE_URL=http://127.0.0.1:3456`
51-
- provider-specific auth secrets such as `OPENROUTER_API_KEY` and `GITHUB_COPILOT_TOKEN`
52-
- provider-scoped model IDs like `openai/gpt-5.2-codex`, `openrouter/moonshotai/kimi-k2.5`, `copilot/gpt-5.2-codex`
53-
54-
```text
55-
Agentrove UI
56-
-> Claude Agent SDK + Claude Code CLI
57-
-> Anthropic-compatible request shape
58-
-> Anthropic Bridge (OpenAI/OpenRouter/Copilot)
59-
-> Target provider model
60-
```
61-
62-
For Anthropic providers, Agentrove uses your Claude auth token directly. For custom providers, Agentrove calls your configured Anthropic-compatible `base_url`.
44+
- **Claude** via `claude-agent-acp` + Claude Code
45+
- **Codex** via `codex-acp` + Codex CLI
6346

6447
## Key Features
6548

66-
- Claude Code-native chat execution through `claude-agent-sdk`
67-
- Anthropic Bridge provider routing with provider-scoped models (`openai/*`, `openrouter/*`, `copilot/*`)
49+
- Claude and Codex model selection in the same UI
50+
- Agent-specific permission modes and reasoning/thinking modes
6851
- Workspace-based project organization with per-workspace sandboxes
69-
- Multi-sandbox runtime (Docker/Host)
70-
- MCP + custom skills/agents/commands + plugin marketplace
71-
- Streaming architecture with resumable SSE events and explicit cancellation
72-
- Built-in recurring task scheduler (in-process async, no worker service)
52+
- Docker and host sandbox providers
53+
- Built-in editor, terminal, diff, secrets, and PR review panels
54+
- Git helpers for branches, commits, push/pull, and PR creation
55+
- Streaming chat sessions with resumable SSE events and explicit cancellation
56+
- Sub-threads for branching work from an existing chat
57+
- Extension management for MCP servers, custom agents, skills, slash commands, personas, env vars, and marketplace plugins
58+
- Web app and macOS desktop app
7359

7460
## Workspaces
7561

76-
Workspaces are the top-level organizational unit. Each workspace owns a dedicated sandbox and groups all related chats under one project context.
62+
Workspaces are the top-level project unit. Each workspace owns a sandbox and groups related chats under one project context.
7763

7864
### Source types
7965

80-
- **Empty** — creates a new empty directory in the sandbox
81-
- **Git clone** — clones a repository (HTTPS or SSH) into a fresh sandbox
82-
- **Local folder** — mounts an existing directory from the host filesystem (host sandbox only)
66+
- **Empty**: create a new empty directory
67+
- **Git clone**: clone a repository into a fresh sandbox
68+
- **Local folder**: mount an existing host directory when using the host sandbox
8369

8470
### Sandbox isolation
8571

86-
Each workspace gets its own sandbox instance (Docker container or host process). Chats within a workspace share the same filesystem, installed tools, and `.claude` configuration. Switching between workspaces switches the entire execution environment.
72+
Each workspace gets its own sandbox instance. Chats in the same workspace share the same filesystem, installed tools, auth files, and `.claude` / `.codex` resources.
8773

8874
### Per-workspace sandbox provider
8975

90-
When creating a workspace you can override the default sandbox provider (Docker or Host). The provider is locked at creation time — all chats in that workspace use the same provider.
76+
You can choose a sandbox provider per workspace:
77+
78+
- **Docker**: isolated local container
79+
- **Host**: runs directly on the host machine
80+
81+
## Models And Agents
82+
83+
The app currently exposes two agent families:
84+
85+
- **Claude**: `default`, `opus`, `haiku`
86+
- **Codex**: `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.3-codex`, `gpt-5.2-codex`, `gpt-5.2`, `gpt-5.1-codex-max`, `gpt-5.1-codex-mini`
87+
88+
Agent-specific controls:
89+
90+
- **Claude permission modes**: `default`, `acceptEdits`, `plan`, `bypassPermissions`
91+
- **Codex permission modes**: `default`, `read-only`, `full-access`
92+
- **Claude thinking modes**: `low`, `medium`, `high`, `max`
93+
- **Codex reasoning modes**: `low`, `medium`, `high`, `xhigh`
94+
95+
## Settings Surface
9196

92-
### Workspace lifecycle
97+
Current settings are organized around:
9398

94-
- Creating a workspace provisions the sandbox and initializes it with your settings (GitHub token, env vars, skills, agents, slash commands)
95-
- Deleting a workspace soft-deletes all its chats and destroys the sandbox container
99+
- General account settings
100+
- Marketplace plugins
101+
- MCP servers
102+
- Custom agents
103+
- Skills
104+
- Slash commands
105+
- Personas
106+
- Environment variables
107+
- Custom instructions
108+
109+
General settings also include:
110+
111+
- GitHub personal access token
112+
- Default sandbox provider
113+
- Timezone
114+
- Notification preferences
115+
- Auto-compact toggle
116+
- Attribution toggle
96117

97118
## Quick Start (Web)
98119

99120
### Requirements
100121

101-
- Docker + Docker Compose
122+
- Docker
123+
- Docker Compose
102124

103125
### Start
104126

@@ -108,14 +130,13 @@ cd agentrove
108130
cp .env.example .env
109131
```
110132

111-
Set a `SECRET_KEY` in your `.env` file (used for JWT signing):
133+
Set a `SECRET_KEY` in `.env`:
112134

113135
```bash
114-
# Generate a random key and paste it as the SECRET_KEY value in .env
115136
openssl rand -hex 32
116137
```
117138

118-
Then start all services:
139+
Start the stack:
119140

120141
```bash
121142
docker compose -p agentrove-web -f docker-compose.yml up -d
@@ -132,25 +153,20 @@ docker compose -p agentrove-web -f docker-compose.yml logs -f
132153

133154
## Desktop (macOS)
134155

135-
Desktop mode uses Tauri with a bundled Python backend sidecar on `localhost:8081`, with local SQLite storage.
156+
Desktop mode uses Tauri with a bundled Python backend sidecar on `localhost:8081` and local SQLite storage.
136157

137158
### Download prebuilt app
138159

139160
- Apple Silicon DMG: [Latest Release](https://github.com/Mng-dev-ai/agentrove/releases/latest)
140161

141162
### How it works
142163

143-
When running in desktop mode:
144-
145-
- Tauri hosts the frontend in a native macOS window
146-
- the sidecar backend process serves the API on `8081`
147-
- desktop uses local SQLite plus in-memory cache/pubsub (no Postgres/Redis dependency required for desktop mode)
148-
149164
```text
150165
Tauri Desktop App
151-
-> React frontend (.env.desktop)
166+
-> React frontend
152167
-> bundled backend sidecar (localhost:8081)
153168
-> local SQLite database
169+
-> local workspace sandbox access
154170
```
155171

156172
### Build and run from source
@@ -168,7 +184,7 @@ npm install
168184
npm run desktop:dev
169185
```
170186

171-
Build (unsigned dev):
187+
Build:
172188

173189
```bash
174190
cd frontend
@@ -179,48 +195,25 @@ App bundle output:
179195

180196
- `frontend/src-tauri/target/release/bundle/macos/Agentrove.app`
181197

182-
Desktop troubleshooting:
183-
184-
- Backend unavailable: wait for sidecar startup to finish
185-
- Database errors: verify local app data directory permissions
186-
- Port conflict: free port `8081` if already in use
187-
188-
## Provider Setup
189-
190-
Configure providers in `Settings -> Providers`.
198+
## Included Tooling
191199

192-
- `anthropic`: paste token from `claude setup-token`
193-
- `openai`: authenticate with OpenAI device flow in UI
194-
- `copilot`: authenticate with GitHub device flow in UI
195-
- `openrouter`: add OpenRouter API key and model IDs
196-
- `custom`: set Anthropic-compatible `base_url`, token, and model IDs
200+
The backend and sandbox images install the tooling Agentrove needs to run coding agents locally, including:
197201

198-
### Model examples
202+
- Claude Code
203+
- Codex CLI
204+
- `claude-agent-acp`
205+
- `codex-acp`
206+
- GitHub CLI
207+
- Playwright MCP
199208

200-
- OpenAI/Codex: `gpt-5.2-codex`, `gpt-5.2`, `gpt-5.3-codex`
201-
- OpenRouter catalog examples: `moonshotai/kimi-k2.5`, `minimax/minimax-m2.1`, `google/gemini-3-pro-preview`
202-
- Custom gateways: models like `GLM-5`, `M2.5`, or private org-specific endpoints (depends on your backend compatibility)
203-
204-
## Shared Working Context
205-
206-
Switching providers within a workspace does not require a new workflow:
207-
208-
- Same sandbox filesystem/workdir
209-
- Same `.claude` resources (skills, agents, commands)
210-
- Same MCP configuration in Agentrove
211-
- Same workspace and chat history
212-
213-
This is the main value of using Claude Code as the harness while changing inference providers behind Anthropic Bridge.
209+
Agentrove also syncs local Claude and Codex auth/config files into sandboxes when available.
214210

215211
## Services and Ports (Web)
216212

217213
- Frontend: `3000`
218214
- Backend API: `8080`
219215
- PostgreSQL: `5432`
220216
- Redis: `6379`
221-
- VNC: `5900`
222-
- VNC Web: `6080`
223-
- OpenVSCode server: `8765`
224217

225218
## API and Admin
226219

@@ -231,32 +224,24 @@ This is the main value of using Claude Code as the harness while changing infere
231224

232225
- Liveness endpoint: `GET /health`
233226
- Readiness endpoint: `GET /api/v1/readyz`
234-
- web mode checks database + Redis
235-
- desktop mode checks database (SQLite) only
227+
- web mode checks database and Redis
228+
- desktop mode checks database only
236229

237230
## Deployment
238231

239232
- VPS/Coolify guide: [docs/coolify-installation-guide.md](docs/coolify-installation-guide.md)
240-
- Production setup uses frontend at `/` and API under `/api/*`
233+
- Production setup serves frontend at `/` and API under `/api/*`
241234

242235
## Tech Stack
243236

244-
- Frontend: React 19, TypeScript, Vite, TailwindCSS, Zustand, React Query
237+
- Frontend: React 19, TypeScript, Vite, TailwindCSS, Zustand, React Query, Monaco, xterm.js
245238
- Backend: FastAPI, SQLAlchemy, Redis, PostgreSQL/SQLite
246-
- Runtime: Claude Code CLI, claude-agent-sdk, anthropic-bridge, uvicorn
239+
- Runtime: Claude Code, Codex CLI, ACP, Docker, Tauri
247240

248241
## License
249242

250243
Apache 2.0. See [LICENSE](LICENSE).
251244

252245
## Contributing
253246

254-
Contributions are welcome. Please open an issue first to discuss what you would like to change, then submit a pull request.
255-
256-
## References
257-
258-
- Anthropic Claude Code SDK: [docs.anthropic.com/s/claude-code-sdk](https://docs.anthropic.com/s/claude-code-sdk)
259-
- Anthropic Bridge package: [pypi.org/project/anthropic-bridge](https://pypi.org/project/anthropic-bridge/)
260-
- OpenAI Codex CLI sign-in: [help.openai.com/en/articles/11381614](https://help.openai.com/en/articles/11381614)
261-
- OpenRouter API keys: [openrouter.ai/docs/api-keys](https://openrouter.ai/docs/api-keys)
262-
- GitHub Copilot plans: [github.com/features/copilot/plans](https://github.com/features/copilot/plans)
247+
Contributions are welcome. Open an issue first to discuss the change, then submit a pull request.

0 commit comments

Comments
 (0)