codex-acp is a practical fork of the Zed Codex ACP adapter. It connects Codex to ACP-compatible clients such as Zed through codex app-server.
This fork is focused on real daily use: better startup diagnostics, better session lifecycle behavior, more usable resume/archive/rename flows, and Linux-first stability improvements.
This project is usable, but still beta.
- Main real-world target today: Linux on
x86_64-unknown-linux-gnu - Fedora is the most tested environment today
- GitHub Releases are intended to ship:
- Linux
x86_64-unknown-linux-gnu - macOS Apple Silicon
aarch64-apple-darwin - Windows
x86_64-pc-windows-msvc
- Linux
- Behavior may still change between releases
Resume picker with workspace-scoped thread selection:
Context selector and session controls:
Context limits and usage view:
Plan mode and visible planning steps:
Archive flow:
Rename flow:
Unarchive flow:
Sub-agent and collaboration tool-call rendering:
Supported Now
8000 a>- ACP prompt capabilities: embedded context and image input
- Session lifecycle:
new_sessionload_sessionfork_sessionresume_sessionlist_sessions
- Session-scoped MCP passthrough for
stdioandhttp - History replay after
load_sessionandresume_session - Session commands:
/init/status/review/threads/resume/fork/archive/unarchive/rename/compact/undo/plan- hidden compatibility alias
/delete -> /archive
- Better thread title handling for resume/archive/rename/fork flows
- ACP
session/forksurfaced on top of nativethread/fork - Inline review flows for uncommitted changes, base branches, and specific commits, centered on one ACP picker behind
/review - In-place
/forkand standard ACPsession/forksupport - Tool call cards for command, MCP, web, image, file, and collab branches
- Clearer status surfacing through
/statusand the existingContextselector Contextselector summaries for session status, context usage, MCP, skills, plugins, limits, and compaction- Practical plan mode support
- Better default-mode fallback plan progress for long step lists: visible checkpoints now advance across the list instead of only snapping at the very end of work
- Better startup and reconnect diagnostics
- Shorter first-open loading pulse: skills/account/limits metadata now hydrate right after the initial session response instead of blocking
new_session/load_session/resume_session - Safer turn-start timeout and stale turn-tail cleanup around reconnects
- Safer history replay fencing for
/undoand auto-restored session history - Less UI freeze risk during
/resume --historyby replaying restored history outside the main session mutex - Less duplicate file-change I/O when one patch item touches the same path multiple times
- Less mutex hold time while waiting for file-change approval prompts
- Less chat stall while command approval prompts are pending
- Faster file-change start cards with ACP snapshot priming moved out of the main session mutex
- Less mutex hold time while final file-change diff and ACP writeback are published
- Safer transport drain: stale server requests are rejected during post-turn and pre-prompt cleanup instead of triggering late approvals
- Less reconnect spam: reconnect warnings now collapse into one normalized status line while reconnect-assisted stalled turns still abort cleanly
- Less brittle transport cleanup: background drain and thread-switch flush now wait for the queue to go quiet instead of assuming
64messages or one tiny timeout is enough - Less turn-completion lock contention: turn diff ACP writeback now runs outside the main session mutex and skips paths already reserved by file-change lifecycle
- Less transport serialization during quiet backend periods: app-server stdout now has a dedicated reader/inbox, so cancel, interrupt, post-turn drain, and thread-switch cleanup do not sit behind one long
next_message()mutex wait
Compared with upstream-oriented adapter work, this fork currently focuses more on:
- Better startup diagnostics when Zed or
codex app-serverfails early - Better session resume and thread switching behavior
- Better archive, unarchive, and rename handling
- More usable ACP rendering for collaboration and sub-agent flows
- Linux-first practical fixes
This project does not claim full upstream parity.
Current strengths of this fork:
- More robust startup behavior and clearer logging
- Less startup latency before Zed gets a ready ACP thread
- Better session lifecycle handling in ACP clients
- Less UI freeze risk during
/undohistory rebuilds - Less UI freeze risk during
/resume --historythread switches - Less repeated ACP snapshot and writeback churn on multi-hunk file edits
- Less chat stall while waiting for file edit approval
- Less chat stall while waiting for shell command approval
- Less lock contention while file-change start cards are published
- Less lock contention while file-change completion diff/writeback is published
- Less lock contention while final turn-diff cards and ACP buffer sync are published
- Less risk of ghost approvals from stale app-server requests during drain/flush cleanup
- Clearer reconnect UX with one normalized retry status and cleaner reconnect-assisted stall aborts
- More reliable pre-prompt and thread-switch cleanup under bursty app-server tails
- Better transport responsiveness while the backend is quiet: app-server message reads no longer monopolize the transport mutex for the full wait window
- Better thread titles in lists and resumed sessions
- Inline review flows backed by native
review/start - Practical thread switching with native
ZedNew Thread,/fork,/resume, and archive-triggered replacement - Standard ACP
session/forksurfaced separately from the in-place slash/forkflow - Practical plan mode support
- Canonical session status surfacing through
/statusplus theContextselector pluginsnow sit alongsidestatus,MCP,skills, and limits in the selector UX- More complete collab and sub-agent UI mapping
Current gaps:
- No full structured elicitation parity yet
- Manual
Plan modeis usable, but it is not an exact match for Codex CLIupdate_planautoplan rendering; think of it as a CLI-like collaboration flow rather than the same UI contract - Default-mode fallback checkpoint rendering is intentionally pragmatic ACP UI, not a pixel-for-pixel clone of Codex CLI autoplan visuals
DynamicToolCallis intentionally unsupported in runtime code for now; the old partial implementation was removed and summarized indocs/drafts/dynamic-tool-call-backup.md- Some upstream-style flows are still missing or incomplete, including
close_sessionand/logout - There is still no true delete path end-to-end:
codex app-serverdoes not give this fork a practical hard-delete flow, and the current ACP bridge inZedstill does not surfacesession/delete, so/deletestays only as a compatibility alias to/archive - Slash
/newis intentionally not surfaced anymore. Use nativeZedNew Threadfor a real new ACP session; in-place backend switching remains only for/forkand archive-triggered replacement flows. Standard ACPsession/forkis supported by the adapter, but currentZedstill has no dedicated UI entrypoint for it, so slash/forkremains the practical path unless you patch the client. The old soft-new behavior is summarized indocs/drafts/soft-new-backup.md - Some behavior still depends on Zed-side ACP support
- MCP passthrough supports
stdioandhttptoday - MCP
ssepassthrough is not supported yet item/tool/call/DynamicToolCallrequests are rejected as unsupported/undoitself works, and the adapter also exposes rollback via ACP ext methods, but the visual rewind/edit button and the pencil-style edit UX in currentZedstill depend on a client-side ACP fix: the external-agent ACP bridge does not wiretruncate()/ rollback ext-methods for this flow yet. In practice that means patching or rebuildingZedif you want the native button UX- The selected-agent /
New Threadtrigger in currentZedcan show a visibly odd pulsing state that appears only while the pointer is moving. In practice this looks like a client-side repaint/animation quirk, not an ACP startup stall in the adapter - While history replay is restoring after
load_sessionor replaying/undo, new prompts and session commands are intentionally fenced until replay finishes; this avoids overlapping turn/replay state in one ACP session - Linux is the most tested platform right now
- Multi-platform release artifacts can exist before all platforms are equally tested in real use
Download the artifact for your platform from the releases page.
Planned release artifacts:
.tar.gzfor Linux.tar.gzfor macOS Apple Silicon.zipfor Windows
Extract the archive, place codex-acp somewhere on your PATH, and point Zed at that binary.
Example:
mkdir -p "$HOME/.local/bin"
tar -xzf codex-acp-cas-<version>-x86_64-unknown-linux-gnu.tar.gz
mv codex-acp "$HOME/.local/bin/codex-acp"
chmod +x "$HOME/.local/bin/codex-acp"Then configure Zed to use the binary path:
{
"agent_servers": {
"codex-acp-cas": {
"type": "custom",
"command": "/home/your-user/.local/bin/codex-acp"
}
}
}- Install or build
codex-acpand make sure the binary path is stable. - Open your Zed settings JSON.
- Add a custom agent server entry pointing to the
codex-acpbinary. - Restart Zed if the new agent does not appear immediately.
If you run the adapter directly from a repository checkout during local development, prefer
pointing Zed at .build/codex-acp-current and rebuilding with:
bash script/build_local_release.shThat script rotates .build/codex-acp-current and .build/codex-acp-previous. Rebuilding only
target/release/codex-acp does not update the binary path if Zed is already configured to use
.build/codex-acp-current.
Example:
{
"agent_servers": {
"codex-acp-cas": {
"type": "custom",
"command": "/home/your-user/.local/bin/codex-acp"
}
}
}If codex is not already available in your environment, make sure it is installed and visible in PATH, because this adapter starts codex app-server under the hood.
Requirements:
- Rust toolchain
codexavailable in your environment
Build:
bash script/build_local_release.shRun:
./target/release/codex-acp --helpThe local release script also keeps two rollback-friendly copies in the repository:
.build/codex-acp-current.build/codex-acp-previous
Basic local checks:
cargo test
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warningsRelease-target check for Linux:
cargo test --release --target x86_64-unknown-linux-gnuUseful environment variables:
RUST_LOG=codex_acp=debugRUST_BACKTRACE=1ACP_DISABLE_AUTO_RESTORE=1CODEX_ACP_STARTUP_TIMEOUT_MS=<milliseconds>CODEX_ACP_STARTUP_METADATA_TIMEOUT_MS=<milliseconds>
CODEX_ACP_STARTUP_TIMEOUT_MS now also bounds the turn/start handshake, so an app-server that stops responding before it returns a turn_id does not leave the ACP UI spinning forever.
ACP_DISABLE_AUTO_RESTORE=1 suppresses only the earliest startup-driven backend restore right after the agent boots. Later explicit opens from Zed history continue to use the normal restore path. If you want a clean startup and still keep manual history opens working, this is the intended mode.
If Zed seems to hang or the adapter looks like it crashed, run Zed from a terminal:
RUST_LOG=codex_acp=debug RUST_BACKTRACE=1 zedImportant log lines:
Starting codex app-server processInitializing codex app-serverSending startup-sensitive app-server requestQueued app-server request while waiting for a responseTimed out waiting for app-server startup responsecodex app-server closed stdoutTurn appears stuck after repeated reconnect failures
What they usually mean:
- Timeout during
initialize,thread/start, orturn/start: app-server is stuck before the adapter can safely continue failed to start 'codex' app-server:codexis missing or not available inPATHTurn appears stuck after repeated reconnect failures: the adapter aborted a stalled turn and drained queued tail notifications so the next prompt starts from a clean state- Panic backtrace: the adapter or child process crashed directly
Recent hardening in this fork:
ItemStartedandItemCompletedfrom the wrongturn_idare ignored instead of creating stale tool cards after reconnect or thread switch- reconnect-stall watchdog abort now runs the same post-turn drain path as normal turn completion
User-facing documentation stays in this README. Deeper project notes are kept separately:
Current Zed-specific UI caveats are tracked in docs/upstream-feature-matrix.md, especially around approval-card layout and command/review/session UX that the adapter alone cannot fully control.
Near-term work:
- Keep refining the
Contextselector and/statusreport where it helps daily use - Decide the next surfaced preview flow after status, most likely
thread/reador/diff
Later candidates:
/diff/debug-configthread/read
Not a priority for this fork right now:
close_sessionas a user-visible focus area in current Zed/logoutfs/watch- app-server feature flags plumbing
codex_homesurfacing- remote auth through client
Apache-2.0. See LICENSE.