CLI reference
coderex is a thin JSON-RPC client over a local socket. Anything
the app can do — list tabs, read a screen, type into a shell, start an agent
— a script or another agent can do too.
Install
The CLI ships inside the desktop app — installing Coderex puts
coderex on your PATH. Grab the signed
.dmg, or use Homebrew:
On a server, or anywhere you want the daemon and CLI without the GUI, install the headless build instead. Same binary, no app:
Verify it's wired up:
Quick start
Start an agent, tell it what to do, and read what it said back:
agent start opens a new tab, launches the agent
in it, and prints that tab's surface id — which is why command substitution
works. Every later command takes that id via --surface.
How it works
The app (or the headless coderex serve daemon) listens on a unix
socket. The CLI sends one JSON-RPC request per invocation and prints the
result.
The socket path resolves in this order:
$CODEREX_SOCKET_PATH, if set.-
Otherwise a socket inside a per-uid private directory with mode
0700—$XDG_RUNTIME_DIRon Linux (systemd already makes it per-user and 0700), else<temp_dir>/coderex-<uid>/.
Every terminal Coderex opens gets $CODEREX_SOCKET_PATH and its
own ids injected into the environment. A script running inside a
tab can therefore call coderex with no flags at all — it
already knows which tab it is. See Environment.
Inspect
coderex ls
Prints the workspace → pane → tab → surface tree.
coderex status
Reports each tab as idle, running (a
foreground program is live in it), or attention — the tab
rang BEL, which is the signal coding agents emit when they're
blocked on you.
| Flag | Scope |
|---|---|
(none) | Every workspace across all windows, plus a totals line. |
--workspace <id> | One workspace's rollup, with a per-tab breakdown. |
--surface <id> | A single tab. Mutually exclusive with --workspace. |
On a terminal you get the readable view:
Pipe it anywhere and you get the raw JSON-RPC result instead — same for every command. See Output & exit codes.
coderex read
Prints a tab's current screen. --ansi keeps the
colour escapes; without it you get plain text.
coderex history
Prints a tab's scrollback. --lines <n> limits
it to the last n lines.
coderex screenshot
| Flag | Meaning |
|---|---|
--format | png (default), json, or ansi. |
--out <path> | Write the PNG to a file instead of stdout. |
Drive a tab
coderex send
Types text into a tab's shell and presses Enter. Pass
--no-enter to leave the line uncommitted.
Everything after the flags is passed through verbatim, so hyphens and quotes survive.
Agents
Supported tools: claude, codex,
gemini, opencode.
coderex agent start <tool>
Opens a new tab, launches the agent, prints the new surface id. Flags after the tool name are handed to the agent itself:
| Flag | Meaning |
|---|---|
--workspace <id> |
Where to open the tab. Defaults to $CODEREX_WORKSPACE_ID,
else the selected workspace. Must come before the tool name.
|
--no-check | Skip the pre-flight "is this agent installed?" check. Also goes before the tool name. |
coderex agent stop
Terminates the agent's foreground process; the tab stays open.
Defaults to $CODEREX_SURFACE_ID.
coderex agent update <tool>
Runs the agent's own self-update in a new tab and prints its surface id.
Workspaces & tabs
workspace delete and tab close do
not prompt — confirmation dialogs are GUI-only. Scripts get
exactly what they asked for.
Notifications
coderex notify raises a notification in the app, attributed to
the calling tab automatically. Put it at the end of a long job and your phone
lights up.
notifications accepts --workspace and
--surface to filter.
Resources & usage
coderex resources
System, GPU, and per-process usage. Narrow it with --workspace or
--surface.
coderex usage
AI-agent model and context usage. Claude reports per tab; Codex, Gemini, and
OpenCode report their newest session. --json gives the raw
payload instead of the formatted view; --surface limits Claude to
one tab.
coderex watch
Subscribes to the event stream and prints each event as it arrives. Useful as the input to a supervisor loop.
Daemon
Terminals are hosted by an engine. On macOS the desktop app runs it in-process by default; turning on Remote Control moves it into a background daemon so your sessions keep running with the window closed. On a server you run the daemon directly:
Manage a running daemon from anywhere:
daemon stop ends every agent the daemon owns. The
coderex binary is GUI-free and builds on any platform,
including a headless Linux box.
Output & exit codes
Commands print human-readable output when stdout is a terminal and the raw JSON-RPC result when it isn't. So this is for you:
…and this is for your script, with no flag to remember:
Exit status is 0 on success and 1 on failure.
| Error code | Meaning |
|---|---|
parse_error | The request wasn't valid JSON. |
invalid_request | Malformed request envelope. |
invalid_params | A parameter was missing or unparseable — e.g. a bad surface id. |
not_found | The workspace or surface doesn't exist. |
internal | The app failed to handle it. |
If the app isn't running you get
coderex: could not reach app at <path> on stderr and exit
1.
Environment
Coderex injects these into every terminal it opens, so scripts running inside a tab are self-locating.
| Variable | Meaning |
|---|---|
CODEREX_SOCKET_PATH | Overrides the socket location. Read by both the app and the CLI. |
CODEREX_SURFACE_ID |
The calling tab. Used when --surface is omitted by
send, read, history,
screenshot, tab close, and
agent stop.
|
CODEREX_WORKSPACE_ID |
The calling workspace. Used when --workspace is omitted by
tab new, workspace delete, and
agent start.
|
CODEREX_PANE_ID | The calling pane. |
CODEREX_WINDOW_ID | The calling window. |
coderex status deliberately ignores the
$CODEREX_* fallback, so the bare form is always the
every-workspace aggregate rather than "whichever tab I happen to be in".
Recipes
Which agents are blocked on me?
Nudge every idle agent
Ping me when the agent finishes
Run this inside the tab — no ids needed, the environment supplies them: