@mattrobenolt/pi-acp
v0.1.0
Published
ACP adapter for pi coding agent
Maintainers
Readme
pi-acp
ACP (Agent Client Protocol) adapter for pi, maintained as a local Zed integration.
pi-acp speaks ACP JSON-RPC 2.0 over stdio to an ACP client and spawns pi --mode rpc behind it. Zed is the target client. Other ACP clients may work, but this repo does not optimize for generic compatibility when Zed needs specific behavior.
This repo started as a fork of svkozak/pi-acp, but it has diverged enough that it should be treated as its own adapter now. The MIT license attribution is preserved in LICENSE.
Status
Practical, Zed-focused, and intentionally not upstream-compatible ceremony. The adapter tracks pi's RPC mode instead of reimplementing pi, so the supported surface is the useful intersection of Zed, ACP, and pi --mode rpc.
Expect changes as pi, ACP, and Zed move. This is not the published ACP Registry adapter and should not be installed using upstream registry/npm instructions unless this fork is explicitly published there later.
Features
- Streams assistant output as ACP
agent_message_chunkand hidden thinking asagent_thought_chunk. - Maps pi tool execution to ACP
tool_call/tool_call_update.- File paths are resolved against the session cwd where appropriate.
- Read/write/edit tools surface file locations and structured diffs when possible.
- Search tools such as
grep,find, andwebsearchrender as search/fetch cards instead of fake file locations. - Bash renders as a Zed terminal-style execute card, including ANSI color output via Zed's
_meta.terminal_outputconvention. - Common pi tools get Zed-friendly titles/kinds:
read,write,edit,bash,term,find,grep,webfetch,websearch,todo,subagent,mcp, scratchpad, and memory tools.
- Session lifecycle support.
- pi stores its own sessions under the configured pi session directory.
pi-acpstores adapter metadata in~/.pi/pi-acp/session-map.json.session/loadreplays a previous pi session into Zed.session/resumereattaches to an existing pi session file without replaying prior messages.session/forkcopies a pi session file into a new independent session.session/closecancels/releases adapter state.
- Zed-focused metadata and diagnostics.
- Conservative capability negotiation with
_meta.piAcpdebug details. session_info_update._meta.piAcpincludes pi-acp version, model, context window, session file, additional directories, queue state, and startup info.- Best-effort ACP
usage_updatefrom pi stats when context window data is available. - Custom diagnostic extension methods under
pi-acp/*:pi-acp/session,pi-acp/state,pi-acp/commands, andpi-acp/reloadCommands.
- Conservative capability negotiation with
- Slash commands.
- Advertises pi RPC commands, file-based prompt commands, skill commands, and adapter built-ins.
- Expands file-based prompt commands before sending to pi.
- Handles some commands adapter-side when pi's interactive UI equivalent does not make sense in Zed.
- Extension UI bridge.
selectandconfirmmap to ACP permission prompts.- Single-line
inputuses ACP elicitation when available. notifyis surfaced as assistant text.- Fire-and-forget UI calls such as status/widget/title/editor text are ignored rather than wedging the turn.
- Startup info mirrors pi's terminal prelude: pi version, context, skills, prompts, extensions, and configured packages. Disable it with
quietStartup: truein pi settings.
Requirements
- Node.js 24+
- A working
piinstall available onPATH, or setPI_ACP_PI_COMMAND=/path/to/pi - pi configured separately for model providers/API keys
- Zed configured with this adapter as a custom ACP agent server
Install pi separately if needed:
npm install -g @earendil-works/pi-coding-agentInstall from this repo
Build the adapter:
npm install
npm run buildPoint Zed at the built file in settings.json:
{
"agent_servers": {
"pi": {
"type": "custom",
"command": "node",
"args": ["/Users/matt/code/scratch/pi-acp/dist/index.js"],
"env": {}
}
}
}For development, point Zed at tsx if you want live TypeScript execution instead of rebuilding:
{
"agent_servers": {
"pi": {
"type": "custom",
"command": "./node_modules/.bin/tsx",
"args": ["/Users/matt/code/scratch/pi-acp/src/index.ts"],
"env": {}
}
}
}Use the absolute path for command if Zed does not launch from this repo. The built dist/index.js path is the safer default.
Environment variables
PI_ACP_PI_COMMAND=/path/to/pioverrides thepiexecutable used by the adapter.PI_ACP_DIR=/path/to/stateoverrides adapter state storage. Default:~/.pi/pi-acp.PI_ACP_DEBUG_LOG=/tmp/pi-acp.jsonlwrites JSONL debug events for ACP/Zed diagnostics.PI_ACP_ENABLE_EMBEDDED_CONTEXT=trueadvertises ACPpromptCapabilities.embeddedContext. If a client sends embeddedresourceblocks anyway,pi-acpconverts them into plain-text prompt context.PI_ACP_ENABLE_EXTENSION_COMMANDS=falsehides extension-provided pi commands from the advertised slash command list. Defaults to true, matching pi settings unless overridden.PI_ACP_SKIP_PI_AUTH=1skips the startup auth preflight that turns “no configured models” into ACPAUTH_REQUIRED.
Example:
{
"agent_servers": {
"pi": {
"type": "custom",
"command": "node",
"args": ["/Users/matt/code/scratch/pi-acp/dist/index.js"],
"env": {
"PI_ACP_DEBUG_LOG": "/Users/matt/.pi/pi-acp/debug.log"
}
}
}
}Slash commands
pi-acp advertises several command sources to Zed.
File-based prompt commands are loaded from:
~/.pi/agent/prompts/**/*.md<cwd>/.pi/prompts/**/*.md
Adapter built-ins:
/compact [instructions...]— run pi compaction/autocompact on|off|toggle— toggle automatic compaction/export— export the current session to HTML in the session cwd/session— show session stats/name <name>— set session display name/steering [all|one-at-a-time]— get/set pi steering mode/follow-up [all|one-at-a-time]— get/set pi follow-up mode/changelog— print the installed pi changelog, best effort
Zed-native mappings:
/modelmaps to Zed's model selector/thinkingmaps to Zed's mode selector/clearis intentionally not implemented; start a new Zed thread instead
pi RPC commands and skill commands are also advertised from pi's command catalog. Extension commands are enabled by default, but their behavior depends on what extension UI APIs they use.
Authentication
pi-acp exposes ACP terminal-auth metadata so Zed can show an authenticate banner when pi reports missing auth/configuration. The terminal auth command runs:
pi-acp --terminal-loginIn source installs, Zed launches that through the configured adapter command. You can also just run pi directly in a terminal and configure providers there:
piDevelopment
npm install
npm run dev # run from src via tsx
npm run fmt
npm run check # tsgo --noEmit
npm run lint # oxlint --deny-warnings
npm run test
npm run build # tsdown -> dist/index.jsNormal validation after code edits:
npm run fmt && npm run check && npm run test && npm run smoke:evalSmoke / eval harness
scripts/smoke-eval.mjs is a self-contained ACP smoke harness that runs against the compiled adapter using a fake pi subprocess (scripts/fake-pi.mjs + scripts/fake-pi-bin.sh). No real pi installation is required.
npm run smoke:eval
SMOKE_VERBOSE=1 npm run smoke:evalCovered flows include initialize, session/new, command advertisement, prompt streaming, slash commands, cancel, close, load, resume, and fork.
Project layout:
src/acp/*— ACP server and translation layersrc/pi-rpc/*— pi subprocess wrapperscripts/*— smoke/eval helperstest/*— unit/component/ACP protocol tests
Limitations
- Zed editing of previous messages is not available for ACP agents yet. Zed currently wires that UI to its internal
AgentConnection::truncate()hook, not to an ACP method.pi-acpsupports ACP session fork, but Zed does not use ACP fork for this feature. - No ACP filesystem delegation (
fs/*) and no ACP terminal delegation (terminal/*). pi reads/writes and executes locally. Bash output is rendered with Zed terminal metadata, but Zed is not executing the command. - ACP
additionalDirectoriesare metadata only. They are stored, advertised, and included in startup context, but pi still operates from the sessioncwd; they do not enforce filesystem scope. - MCP servers passed by ACP are stored in session state but not wired through to pi by this adapter. Configure MCP through pi itself.
- Extension UI support is partial.
notify,select,confirm, and single-lineinputwork; richer TUI/editor/status/widget behavior is degraded. - pi commands are advertised from
get_commands, but not every pi or extension command has a perfect ACP/Zed equivalent. - Tool card metadata is adapter-maintained. pi's tool registry does not yet expose semantic ACP/Zed display metadata, so custom tool rendering may need adapter-side mapping.
- Queue/active-turn behavior is adapter-managed: normal concurrent prompts are sent to pi as steering messages.
License and attribution
MIT. See LICENSE.
This repository preserves the original MIT copyright notice from svkozak/pi-acp.
