acpx
When to use this skill
Use this skill when you need to run coding agents through
acpx
, manage persistent ACP sessions, queue prompts, or consume structured agent output from scripts.
What acpx is
acpx
is a headless, scriptable CLI client for the Agent Client Protocol (ACP). It is built for agent-to-agent communication over the command line and avoids PTY scraping.
Core capabilities:
- Persistent multi-turn sessions per repo/cwd
- One-shot execution mode (
exec
)
- Named parallel sessions (
-s/--session
)
- Queue-aware prompt submission with optional fire-and-forget (
--no-wait
)
- Cooperative cancel command (
cancel
) for in-flight turns
- Graceful cancellation via ACP
session/cancel
on interrupt
- Session control methods (
set-mode
, set <key> <value>
)
- Agent reconnect/resume after dead subprocess detection
- Prompt input via stdin or
--file
- Config files with global+project merge and
config show|init
- Session metadata/history inspection (
sessions show
, sessions history
)
- Local agent process checks via
status
- Stable ACP client methods for filesystem and terminal requests
- Stable ACP
authenticate
handshake via env/config credentials
- Structured streaming output (
text
, json
, quiet
)
- Built-in agent registry plus raw
--agent
escape hatch
Install
npm i -g acpx
For normal session reuse, prefer a global install over
npx
.
Command model
prompt
is the default verb.
acpx [global_options] [prompt_text...]
acpx [global_options] prompt [prompt_options] [prompt_text...]
acpx [global_options] exec [prompt_options] [prompt_text...]
acpx [global_options] cancel [-s <name>]
acpx [global_options] set-mode <mode> [-s <name>]
acpx [global_options] set <key> <value> [-s <name>]
acpx [global_options] status [-s <name>]
acpx [global_options] sessions [list | new [--name <name>] | close [name] | show [name] | history [name] [--limit <count>]]
acpx [global_options] config [show | init]
acpx [global_options] <agent> [prompt_options] [prompt_text...]
acpx [global_options] <agent> prompt [prompt_options] [prompt_text...]
acpx [global_options] <agent> exec [prompt_options] [prompt_text...]
acpx [global_options] <agent> cancel [-s <name>]
acpx [global_options] <agent> set-mode <mode> [-s <name>]
acpx [global_options] <agent> set <key> <value> [-s <name>]
acpx [global_options] <agent> status [-s <name>]
acpx [global_options] <agent> sessions [list | new [--name <name>] | close [name] | show [name] | history [name] [--limit <count>]]
If prompt text is omitted and stdin is piped,
acpx
reads prompt text from stdin.
Built-in agent registry
Friendly agent names resolve to commands:
codex
-> npx @zed-industries/codex-acp
claude
-> npx @zed-industries/claude-agent-acp
gemini
-> gemini
opencode
-> npx opencode-ai
pi
-> npx pi-acp
Rules:
- Default agent is
codex
for top-level prompt
, exec
, and sessions
.
- Unknown positional agent tokens are treated as raw agent commands.
--agent <command>
explicitly sets a raw ACP adapter command.
- Do not combine a positional agent and
--agent
in the same command.
Commands
Prompt (default, persistent session)
Implicit:
acpx codex 'fix flaky tests'
Explicit:
acpx codex prompt 'fix flaky tests'
acpx prompt 'fix flaky tests' # defaults to codex
Behavior:
- Uses a saved session for the session scope key
- Auto-resumes prior session when one exists for that scope
- If no session exists for the scope, exits with
NO_SESSION
and prompts for sessions new
- Is queue-aware when another prompt is already running for the same session
- On interrupt during an active turn, sends ACP
session/cancel
before force-kill fallback
Prompt options:
-s, --session <name>
: use a named session within the same cwd
--no-wait
: enqueue and return immediately when session is already busy
-f, --file <path>
: read prompt text from file (-
means stdin)
Exec (one-shot)
acpx exec 'summarize this repo'
acpx codex exec 'summarize this repo'
Behavior:
- Runs a single prompt in a temporary ACP session
- Does not reuse or save persistent session state
Cancel / Mode / Config
acpx codex cancel
acpx codex set-mode plan
acpx codex set approval_policy conservative
Behavior:
cancel
: sends cooperative session/cancel
through queue-owner IPC.
set-mode
: calls ACP session/set_mode
.
set
: calls ACP session/set_config_option
.
set-mode
/set
route through queue-owner IPC when active, otherwise reconnect directly.
Sessions
acpx sessions
acpx sessions list
acpx sessions new
acpx sessions new --name backend
acpx sessions close
acpx sessions close backend
acpx sessions show
acpx sessions history --limit 20
acpx status
acpx codex sessions
acpx codex sessions new --name backend
acpx codex sessions close backend
acpx codex sessions show backend
acpx codex sessions history backend --limit 20
acpx codex status
Behavior:
sessions
and sessions list
are equivalent
new
creates a fresh session for the current (agentCommand, cwd, optional name)
scope
new --name <name>
targets a named session scope
- when
new
replaces an existing open session in that scope, the old one is soft-closed
close
targets current cwd default session
close <name>
targets current cwd named session
show [name]
prints stored metadata for that scoped session
history [name]
prints stored turn history previews (default 20, use --limit
)
Global options
--agent <command>
: raw ACP agent command (escape hatch)
--cwd <dir>
: working directory for session scope (default: current directory)
--approve-all
: auto-approve all permission requests
--approve-reads
: auto-approve reads/searches, prompt for writes (default mode)
--deny-all
: deny all permission requests
--format <fmt>
: output format (text
, json
, quiet
)
--timeout <seconds>
: max wait time (positive number)
--ttl <seconds>
: queue owner idle TTL before shutdown (default 300
, 0
disables TTL)
--verbose
: verbose ACP/debug logs to stderr
Permission flags are mutually exclusive.
Config files
Config files are merged in this order (later wins):
- global:
~/.acpx/config.json
- project:
<cwd>/.acpxrc.json
Supported keys:
defaultAgent
defaultPermissions
(approve-all
, approve-reads
, deny-all
)
ttl
(seconds)
timeout
(seconds or null
)
format
(text
, json
, quiet
)
agents
map (name -> { command }
)
auth
map (authMethodId -> credential
)
Use
acpx config show
to inspect the resolved config and
acpx config init
to create the global template.
Session behavior
Persistent prompt sessions are scoped by:
agentCommand
- absolute
cwd
- optional session
name
Persistence:
- Session records are stored in
~/.acpx/sessions/*.json
.
-s/--session
creates parallel named conversations in the same repo.
- Changing
--cwd
changes scope and therefore session lookup.
- closed sessions are retained on disk with
closed: true
and closedAt
.
- auto-resume by scope skips closed sessions.
Resume behavior:
- Prompt mode attempts to reconnect to saved session.
- If adapter-side session is invalid/not found,
acpx
creates a fresh session and updates the saved record.
- explicitly selected session records can still be resumed via
loadSession
even if previously closed.
- dead saved PIDs are detected and reconnected on the next prompt.
- each completed prompt stores lightweight turn history previews in the session record.
Prompt queueing and --no-wait
Queueing is per persistent session.
- The active
acpx
process for a running prompt becomes the queue owner.
- Other invocations submit prompts over local IPC.
- On Unix-like systems, queue IPC uses a Unix socket under
~/.acpx/queues/<hash>.sock
.
- Ownership is coordinated with a lock file under
~/.acpx/queues/<hash>.lock
.
- On Windows, named pipes are used instead of Unix sockets.
- after the queue drains, owner shutdown is governed by TTL (default 300s, configurable with
--ttl
).
Submission behavior:
- Default: enqueue and wait for queued prompt completion, streaming updates back.
--no-wait
: enqueue and return after queue acknowledgement.
Ctrl+C
during an active turn sends ACP session/cancel
, waits briefly, then force-kills only if cancellation does not finish in time.
cancel
sends the same cooperative cancellation without requiring terminal signals.
Output formats
Use
--format <fmt>
:
text
(default): human-readable stream with updates/tool status and done line
json
: NDJSON event stream (good for automation)
quiet
: final assistant text only
Example automation:
acpx --format json codex exec 'review changed files' \
| jq -r 'select(.type=="tool_call") | [.status, .title] | @tsv'
Permission modes
--approve-all
: no interactive permission prompts
--approve-reads
(default): approve reads/searches, prompt for writes
--deny-all
: deny all permission requests
If every permission request is denied/cancelled and none approved,
acpx
exits with permission-denied status.
Practical workflows
Persistent repo assistant:
acpx codex 'inspect failing tests and propose a fix plan'
acpx codex 'apply the smallest safe fix and run tests'
Parallel named streams:
acpx codex -s backend 'fix API pagination bug'
acpx codex -s docs 'draft changelog entry for release'
Queue follow-up without waiting:
acpx codex 'run full test suite and investigate failures'
acpx codex --no-wait 'after tests, summarize root causes and next steps'
One-shot script step:
acpx --format quiet exec 'summarize repo purpose in 3 lines'
Machine-readable output for orchestration:
acpx --format json codex 'review current branch changes' > events.ndjson
Raw custom adapter command:
acpx --agent './bin/custom-acp-server --profile ci' 'run validation checks'
Repo-scoped review with permissive mode:
acpx --cwd ~/repos/shop --approve-all codex -s pr-842 \
'review PR #842 for regressions and propose minimal patch'