conchv0.1.8

Reference

Command line

Everything the TUI does to panes, projects and machines is also a conch subcommand, so you can script agents from a shell. conch help prints the commands to start with, and conch help all every one.

Scripting

conch task -cwd ~/src/api "Add a health check endpoint"   # pane, worktree, branch
conch new -agent claude -cwd ~/src/api                   # Claude in the repo
conch send p1 "fix the failing tests" && conch send -keys p1 enter
conch read p1                          # visible screen as text
conch status                           # panes with agent state
conch project ls                       # projects, base, worktrees
conch branch commit -m "Fix the flaky test" && conch branch pr   # finish a task
conch worktree clean -y                # remove finished worktrees and their branches
conch wait p1 && conch send p2 "review what p1 just changed"   # chain tasks
conch agent prompt -wait p2 "check finding 3 again" && conch read p2   # one agent driving another
conch close p1
conch server reload                    # run a new build; panes keep running
conch server stop                      # stops the server and all panes

conch server stop stops the server and every pane it owns. To move onto a new build, use conch server reload.

On macOS the server runs with GODEBUG=asyncpreemptoff=1, restarting itself once at start-up to get there: a reload re-execs the server process, and macOS makes that wait for scheduling signals a busy server never takes, which would leave it serving nothing. If a reload ever leaves the socket in place with nothing serving it, conch status says the server is not answering rather than that it is gone, and simply running conch again clears that socket and starts a fresh server. The panes of the old one are lost; nothing else needs cleaning up by hand.

Global flag

-m MACHINE (or --machine MACHINE) before the subcommand runs it against a remote machine instead of this one; local means this machine.

conch -m gpu-box status

Subcommands

conch

conch with no subcommand opens the TUI, starting the server if needed.

Inside one of its own panes it refuses, the way tmux refuses a nested session: the inner TUI would take the keys and the mouse, and closing the pane would kill it. Detach with ctrl+b d first, or run CONCH_PANE_ID= conch to open one inside the pane anyway (conch -m MACHINE for another machine's TUI always works).

server

CommandDescription
conch serverrun the server in the foreground
conch server stopstop the server and every pane it owns
conch server reload [-binary PATH]run a new conch build without stopping panes; -binary picks the program to reload into (default: the server's own executable path)

Panes

CommandDescription
conch viewwhat the terminal is showing: its tabs, what each holds, and which pane has the keyboard. The server keeps no layout of its own — a TUI publishes this and conch carries it
conch show [-name NAME] ID...ask the terminal to put those panes in front of the person: one is brought up, several are gathered side by side in one tab. A request, not an order
conch status (or conch ls)show server and pane status: ID, name, state, agent, ssh host, size, folder and command of each pane. The ssh column is the host a terminal is logged in to with plain ssh right now — the one -ssh on upload and download reaches — and - for the rest. Its first line gives the server's uptime, which counts from the first server of a chain of reloads — its panes have been alive that whole time — and then (reloaded N ago) for when the running binary was loaded, which is the one that says whether your last build got there
conch new [-cwd DIR] [-name N] -- CMD [ARGS...]start a pane (default command: your shell; default folder: the current one, or with -m that machine's home) and print its ID
conch new -agent claude [-cwd DIR] [-- CLAUDE ARGS...]start Claude Code with state tracking
conch send [-keys] ID TEXT...type text into a pane; with -keys, the arguments are key names (e.g. enter, ctrl+c)
conch read IDprint a pane's visible screen
conch close IDclose a pane
conch rename ID [NAME]name a pane; without NAME it gets its own back. Refused when a running pane already has the name
conch redraw IDdraw a pane's screen again, for stale text a program left behind
conch wait ID [-state done] [-timeout 30m]block until the pane's agent is done (or waiting, working, idle — several, comma separated, stop on the first to happen). Prints ID AGENT STATE. Exits 124 if the time runs out, so a script can tell that from a failure; without -timeout it waits as long as it takes
conch [-m MACHINE] upload [-to DIR [-p]] [-f] PATH...copy files or folders to the machine and print where each landed there: into DIR there (~ is its home), else its uploads folder (~/.config/conch/uploads), as dropping them on its pane does. A DIR that is missing is refused unless -p, which makes it and the folders above it first, as mkdir -p does. A name already taken is numbered (ca 2.pem) unless -f
conch [-m MACHINE] download [-to DIR] [-f] PATH...copy files or folders from the machine into DIR here (default: the current folder) and print where each landed; -f as for upload
conch [-m MACHINE] upload|download -ssh PANE ...the same with the host the terminal PANE (its ID or name) is logged in to with plain ssh — nothing of conch's needed there, as in its Files view. upload goes to that host's home unless -to says otherwise. It needs a key or an ssh agent for the host, since nobody is there to type a password

Pane names

Every command that takes a pane's ID — send, read, close, redraw, wait, rename, agent explain, agent prompt — takes its name as well: the one in conch status's name column, set with conch rename or conch task -name. That is how one agent addresses another it started, without keeping track of IDs:

conch task -name reviewer -agent codex "Review the diff on this branch"
conch agent prompt -wait reviewer "Check finding 3 again" && conch read reviewer
  • An ID is always an ID: p and a number is never looked up as a name, so names of that shape are refused.
  • A name is looked up once, when the command starts; a wait then stays with that pane.
  • Names are exact and case sensitive. A name two running panes share is refused rather than guessed — say which with its ID. A pane that has ended still answers to its name until another running pane takes it.
  • Names belong to one machine's server, so -m looks them up there.

When an agent runs these commands

An agent in a conch pane can drive conch with the same commands — start a reviewer, prompt it, read its answer. conch agent skill -apply teaches it how, and when to stop and ask you; Agents working together walks through it with examples. What it may change is kept to its own work:

  • panes it started, and the panes those started, in any project;
  • panes in its own project, whoever started them;
  • its own project's branches and worktrees.

Anything else — typing into, closing, renaming or marking as seen another project's pane, sending it keys or a broadcast, removing another project, committing, pushing or discarding there — is refused with out_of_scope, and so is conch server stop or reload, and changing your own setup: the agents' skill, the library, a sync, or which local files a project copies into its worktrees:

conch: out_of_scope: the claude agent in p4 may not close p1: it did not start it, and it is in another project; do it from the TUI or a terminal pane

Reading is never refused (read, status, wait, sessions), and neither is starting panes and tasks: what an agent starts is its own, and each pane in the server's pane list carries who started it (created_by).

conch tells who is asking from the operating system — the process at the other end of the socket, and its parents up to a pane — not from CONCH_PANE_ID, so unsetting that changes nothing. Only a pane with an agent running in it is held to this: a terminal pane, the TUI and scripts outside conch act as you. It is a guard against a confused agent closing the wrong session, not a sandbox: a program set on escaping can leave the pane's process tree.

On other machines. -m from an agent's pane carries its scope along: conch asks this machine's server who is running the command and, for an agent, has the other machine's server hold the connection to what that agent started there — its panes (and theirs), and the projects it started them in. It has no project there otherwise, so another project's panes stay out of reach even when they share a name with its own. A machine whose conch predates this isn't driven from an agent's pane at all; conch machine upgrade it. A terminal pane's -m is you, as before. Like the rest, this asks conch: an agent that runs ssh itself, or points CONCH_SOCKET elsewhere so this machine's server can't be asked, is not held by it.

agent

CommandDescription
conch agent explain IDshow how a pane's agent state was decided, as JSON
conch agent statuslist each supported agent: installed (with version and path) or not
conch agent install NAMErun an agent's installer in a pane and wait for it
conch agent prompt [-wait] [-until done,idle,waiting] [-timeout 30m] [-at TIME] ID TEXT...send the pane's agent its next message and submit it. Unlike conch send it only types into an agent, and never into one waiting on a question — a permission prompt, a menu — where its Enter could answer something nobody read: it exits 3 and types nothing (a question that comes up in the moment before Enter leaves the message typed but unsent). With -wait it blocks until the work the message starts has ended — not on the done or idle still showing from before it — and prints ID AGENT STATE; a question the agent asks ends it too, unless -until leaves waiting out. An agent already working gets the message when that work ends, so that work is the one waited for. Exits 124 if -timeout runs out, and fails if the pane ends or another program takes it over. With -at (14:05, +30m, 2026-10-15 09:00) the server keeps the message and sends it then, once the agent is free — see Later, and on a schedule
conch agent skill [-agent NAMES] [-remove] [-apply]install conch's skill — how an agent in a conch pane starts, prompts and reads another — where each agent reads your skills: ~/.claude/skills/conch for Claude, ~/.agents/skills/conch for Codex, Gemini and OpenCode, ~/.config/devin/skills/conch for Devin. Without -apply it only says what it would do; -remove takes it away again. A conch skill there that conch didn't write is left alone. With -m it installs on that machine. Not from an agent's pane: it is your setup
conch skillprint that skill to stdout instead of installing it, for an agent whose skills folder conch does not manage, a system prompt you assemble yourself, or a sandbox where it goes inline. The same bytes the installer writes
conch agent setup [-agent NAME] [-copy] [-json] [DIR]show what each agent loads in a folder; -agent limits it to one agent, -copy copies missing local files from the main checkout first, -json prints JSON
conch agent sync [-user] [-from NAME] [-to NAMES] [-apply] [-undo [-stamp S]] [DIR]give the other agents one agent's setup — instructions, skills, MCP servers — in a checkout, or with -user the setup in your home. Without -apply it only says what it would do; -undo puts a sync back. See One setup, every agent
conch agent library [list | add | mcp | skill | on | off | rm | import AGENT | plan | apply | undo]MCP servers and skills kept in conch, each given to the agents you choose. add NAME URL or add NAME -- COMMAND ARGS with -to NAMES, -env K=${VAR}, -header K=V, -sse; skill NAME FOLDER; on/off NAME AGENTS; plan says what apply would write. See Shared MCP servers and skills

project

CommandDescription
conch project add PATHadd a project to the sidebar
conch project create [-no-git] PATHcreate a folder with a git repository and an initial commit (-no-git: a plain folder)
conch project lslist projects, their base branch and worktrees
conch project rm IDremove a project from the sidebar
conch project files ID [-reset | -none | PATTERN...]set the local file patterns copied into new worktrees; -reset restores the defaults, -none copies nothing
conch project setup ID [-none | COMMAND]show or set the setup command run in each new worktree; -none runs nothing

task

conch task [-cwd DIR] [-branch B] [-base B] [-agent NAME] [-n N] [-name N] [-at TIME] [-every SPAN] [-queue [-wip N]] [-after REF] PROMPT creates a branch and worktree and starts an agent with the prompt (-at later, -every again and again, -queue when the project has room, -after once other work has finished, on top of it: see Later, and on a schedule; conch schedule lists and removes what is scheduled); in a folder that isn't a git repository — or, with -m and no -cwd, the machine's home — the agent works there with no branch. See Tasks.

FlagDefault
-cwd DIRa directory in the project; default: the current one. With -m it is required, as an absolute path on that machine
-branch Bbranch name; default: derived from the prompt
-base Bbranch to start from; default: the project's base
-agent NAMEclaude, codex, gemini or opencode, or several separated by commas; default: [agents] default
-n Nattempts at the same prompt, each on its own branch (default: one per agent, at most 10)
-name Nname the task's pane, to address it by in place of its ID (see Pane names). Refused while a running pane has that name, and with more than one attempt

branch

Finishing a task from a script, the same steps as the changes view. Every command takes -cwd DIR (a directory in the project; default: the current one) and -branch B; without -branch conch uses the branch checked out in that directory. With -m MACHINE, -cwd is required and must be an absolute path on that machine.

CommandDescription
conch branch commit -m MESSAGE [-file PATH]...commit every change on the branch, or only the -file paths (repeat the flag; a rename needs both its paths). Prints the new commit
conch branch pushpush the branch, setting its upstream on origin (or the only remote) the first time; a remote that has moved on refuses it, and -rebase takes its commits, puts the branch's own on top and pushes
conch branch pr [-title T] [-body B] [-draft]push, then open a pull request into the base with gh, and print its URL. Without -title, gh fills the title and body from the commits
conch branch merge [-no-squash] [-m MESSAGE]merge the branch into the base where the base is checked out, squashed unless -no-squash. A merge that conflicts is undone and the command fails
conch branch discard [-n] [-force]remove the branch's worktree and delete the branch. It refuses when that would lose uncommitted files or unpushed commits, unless -force; -n only prints what would go
conch branch commit -m "Add the health check" && conch branch pr -title "Health check"
conch branch merge && conch branch discard      # land it and clean up

review

The changes view's comments from a shell: the same ones, kept by the server, so a comment written here shows on a's hunk marks and the phone's agent card, and the other way round. Like branch, every command takes -cwd DIR and -branch B, and without -branch uses the branch checked out in that directory.

CommandDescription
conch reviewlist the comments waiting for the branch's agent, oldest first, each with its ID, where it is and who wrote it when an agent did. The unresolved comments on the branch's pull request follow, with the reviewer (alice on GitHub), their replies and their link
conch review add FILE[:LINE] NOTEcomment on a file, or one line of it (a.go:12). Every word after the file is the note. Run from an agent's pane, the comment says which agent wrote it
conch review rm IDtake a comment away. A pull request's comment is refused: answer or resolve it on GitHub
conch review send [-agent A]hand every comment to the agent working on the branch as one message, numbered, and clear them. The pull request's comments stay on GitHub but aren't sent again until somebody replies to them. Refused while that agent waits on a question. With no agent on the branch it is refused too, unless -agent names one to start in the branch's worktree with them
conch review add api/login.py:42 "This swallows the timeout; let it raise."
conch review send

An agent kept to its own work may comment on and send for its own project's branches, and no others — which is what lets a reviewer you started leave its findings as comments instead of a file.

worktree

CommandDescription
conch worktree lslist the project's worktrees besides the main checkout, with why each looks finished and what removing it would lose
conch worktree clean [-y] [-force] [PATH|BRANCH...]remove the worktrees that look finished and lose nothing, or the ones named, deleting their branches (never the base). Without -y it only prints what it would remove; -force allows losing work

Committing single hunks is a TUI-only step: see Finishing a task.

machine

CommandDescription
conch machine add [-label NAME] [-yes] SSH_TARGETadd a remote machine, installing conch there; -label sets the name shown in the sidebar (default: the host), -yes installs without asking
conch machine lslist machines (also plain conch machine)
conch machine rm IDremove a machine
conch machine rename ID LABELchange the name a machine is shown by; its ID and ssh target stay
conch machine upgrade IDinstall this build on a machine and reload its server
conch machine hostslist the host aliases in ~/.ssh/config, for suggesting machines to add

sandbox

CommandDescription
conch sandbox stats [-provider P]every provider's sandboxes in one table, and a line per provider: how many, in which states, what is running; no provider needed
conch sandbox -provider daytona|boat|devin …whose sandboxes the command means, in front of any subcommand below. Required for all of them — there is no default, and a sandbox named under another provider is refused
conch sandbox -provider P create [-label L] [-snapshot S] [-cpu N] [-memory GiB] [-disk GiB] [-env NAME]... [-yes]make a sandbox (key in $DAYTONA_API_KEY, $BOAT_API_KEY or $DEVIN_API_KEY; Devin Cloud also needs the devin CLI signed in), install conch there and add it as a machine; it runs until stopped. -env passes a variable from your environment; -yes deletes the sandbox without asking if setting it up fails
conch sandbox -provider P add [-label L] IDmake a sandbox ls shows with no machine — one whose machine was removed, or on boat.dev one made in its own interface — one of conch's machines: started if stopped, conch installed, and added. Never deleted if that fails
conch sandbox -provider P lsconch's sandboxes, their state and size, including ones no longer added as machines (also plain conch sandbox -provider P)
conch sandbox -provider P ssh [-t] ID [COMMAND...]a shell in a running sandbox, or COMMAND run there (-t gives it a terminal); exits with its status
conch sandbox -provider P start IDstart a stopped sandbox
conch sandbox -provider P stop [-y] IDstop it: its agents and terminals end, its files stay
conch sandbox -provider P rm [-y] IDdelete it for good and remove the machine; lists work that isn't pushed first
conch sandbox -provider P url [-expires 1h] [-open] ID PORTa link to a port inside the sandbox
conch sandbox -provider P usage [-since 720h] IDwhat it has cost, period by period
conch sandbox -provider P snapshot [-name N] IDkeep it, to make others from
conch sandbox -provider P snapshots [-rm NAME]list what is kept, or forget one

ID is the machine's ID or label, the provider's own sandbox ID, or PROVIDER:ID; it must belong to the provider -provider names. See Sandboxes.

web

conch web [-listen ADDR] [-port N] [-url URL] [-cert FILE -key FILE]   # the gateway a phone reaches
conch web pair [-permission view|reply|full] [-machine NAME]  # a QR code and one-time code, good for 5
                                                            # minutes; it reaches this computer unless
                                                            # -machine names a machine
conch web devices                                           # the paired phones
conch web revoke ID                                         # cut one off at once
conch web permission ID view|reply|full [-machine NAME]...  # change what one may do, and which
                                                            # machines it reaches (this computer only
                                                            # until you name one; 'local' clears them)
conch web stop                                              # end one running in the background

conch web serves your phone on this machine's Tailscale address and nowhere else, unless -listen names another address. -url is the address phones open — the https://…ts.net one tailscale serve gives — which the QR code points at. pair draws the QR code only when it prints to a terminal. It takes no -m: it shows the agents of the machine it runs on. pair and revoke are refused from an agent's pane.

mcp

conch mcp                                                   # an MCP server on stdin and stdout

An agent that would rather call a tool than a command talks to conch through conch mcp: a Model Context Protocol server over stdio, in front of the same socket the CLI uses. A tool call comes back as a typed result and a refusal it can act on, where shelling out hands it a screenful of text to parse.

ToolWhat it does
listthe panes you may see, each with what its agent is doing and the subagents running inside it
reada pane's screen now (tail for its last lines — leave it out for an agent, whose last lines are its prompt box)
startan agent in a pane of its own, in a folder that exists
promptan agent's next message; wait holds until the work it starts has ended
waitblock until a pane's agent is done, idle, waiting or working
taska branch, a worktree and an agent on a prompt
renamename a pane, to address it by that instead of its id
viewwhat the person is looking at: the tabs, what is in each, and which pane has the keyboard
showask the terminal to put panes in front of them — one is revealed, several open side by side in a tab of their own

view and show are the two that reach past the server to the screen. The server owns panes and the terminal owns the arrangement of them, so conch carries both ways: a TUI publishes what it is showing, and a show is passed back to it as a request. A request, not an order — the panes asked for are gathered side by side in one tab and nothing else is touched. They move rather than being copied, since a pane is shown in exactly one place, which is the same rule that governs ctrl+b ! and dragging a pane between tabs. An agent may only show panes it could already type into, by the same scope that governs prompt.

The tools are the same work as conch agent prompt, conch wait, conch task and the rest — the same server methods with the same payloads — so the two doors cannot drift. Scope comes for free: conch finds the caller from the socket's peer pid walked up to a pane's program, so an MCP server an agent starts inside its own pane reaches only what that pane may reach, and nothing in a tool call can widen it.

Installing it is one action, because the entry is the same for every agent — the library writes it in each one's own format:

conch agent library mcp          # conch's own tools, as a server in the library
conch agent library apply        # write it into each agent's configuration

Or in the TUI: , → Agents → Shared MCP servers & skills… → Add conch's own tools…, then Apply…. It is conch mcp on stdio with nothing in its environment — it finds its socket the way every other command does — and the command is the bare name, so an update that moves the binary doesn't strand it. Adding it twice is adding it once. Restart an agent afterwards for its client to list the tools.

Three reviewers at once is what this is for: several helpers, several kinds of agent, no shell.

Stdin and stdout are the protocol: notes go to stderr, one request per line (this revision of MCP has no batches), answered one at a time in order, and a wait tool holds the session until it ends, as conch wait holds a shell. A tool that names a pane refuses a name shaped like a pane id or one another running pane holds, as conch rename does — ids win, so such a name would pick out nothing. timeout_seconds defaults to 1800, 0 waits with no limit, and anything over a day is capped.

doctor

conch doctor          # check what conch needs, and say how to fix what is wrong
conch doctor -json    # the same checks, for a script

The first thing to run when something does not work. Each line is one thing conch relies on, and anything wrong comes with the command that puts it right:

✓ conch     0.1.9 · darwin/arm64
✓ config    /Users/you/.config/conch/config.toml
✓ socket    /Users/you/.config/conch/conch.sock
! server    pid 28356, up 6d, on another build (0.1.8) than this conch (0.1.9)
            → conch server reload -binary /Users/you/.local/bin/conch  (panes and agents keep running)
✓ agents    claude 2.1.3 · codex 0.46.0  (not installed: gemini, opencode, devin)
✓ git       2.49.0, committing as You
! gh        2.62.0 not signed in
            → gh auth login
✓ terminal  ghostty, xterm-256color, 24-bit colour
✓ machines  1 machine saved (not dialled; conch -m NAME status reaches one)

conch works; 2 things worth a look.
Check✗ (must be fixed)! (worth a look)
configconfig.toml does not parse, so none of it is in forcean [[actions]] entry with no name, no command or an unknown place
socketthe socket path is longer than the system allows (103 bytes on macOS, 107 on Linux), so no server can listen
serverthe socket is there but nothing answers — stuck, or somebody else's (starting conch would clear it, and every pane)not running; on another build than this conch (the fix reloads it onto this binary, or says to run the newer one when the server is ahead); missing features this conch uses
agentsthe server finds none installednot checked, because no server is running
gitnot foundno name or email to commit as, in git's config or its environment variables; older than 2.38, which telling which branches would conflict needs
ghnot found, or not signed in — pull requests, CI results and issues come through it
terminalTERM is empty or dumbinside tmux with the same prefix as tmux (asked of tmux itself), and a key free in both to use instead
machinesmachines.json cannot be read; machines are saved but there is no ssh

It exits 1 when anything is marked ✗, and 0 otherwise. The checks run side by side, so one slow thing costs only its own wait. It changes nothing and starts nothing — not even the server — and it does not dial your machines, so a machine that is asleep cannot make it hang. Whether gh is signed in is asked without reaching GitHub, so an offline laptop is not called signed out (a gh too old for that is asked the usual way), and the token gh hands back is thrown away. It checks this computer: on another machine, run it there.

bug

conch bug                                                   # the facts about this conch
conch bug -open "the tree lost a terminal"                  # …in a GitHub issue, already filled in
conch bug -log                                              # where the server's log is

What to hand over when conch itself is the problem, without writing anything down:

conch 0.1.7-dev (build 29945acfb71a, darwin/arm64)
server: 0.1.7-dev (build 01096cd11ad4, darwin/arm64), pid 28356, up 6d
  reloaded 5h06m ago
panes: 25 · claude×16
machines: 2, 1 reachable
terminal: iTerm.app, xterm-256color, 247×48, icons=nerd
last error: out_of_scope: the claude agent in p1 may not reload the server

It is facts, not contents: versions, counts, sizes, the capabilities a server is missing, and conch's own last error. Never a path, a project, a branch, a pane's title or anything off a screen — which is what makes it safe to send without reading it through first. The two builds above being different is the sort of thing it is for.

-open opens a GitHub issue with the block already in it; nothing is sent until you press submit there. Over ssh, or anywhere with no desktop, it prints the link instead. -log says where the server's log is and what is in it — paths, branch names and pane titles — and leaves attaching it to you.

Run conch doctor first: what it finds usually has a fix you can make yourself.

In the TUI the same thing is , → Report a problem…, which shows the report and offers to open the issue, copy it, or copy the log's path.

ask

conch ask [-y | -n] REQUEST asks the brain; it proposes actions and runs them once you confirm. -y runs the plan without asking; -n only shows it.

update

conch update [VERSION | latest | list | rollback] replaces this binary with a release and reloads the local server onto it, keeping panes.

CommandWhat it does
conch updateinstall the latest release, or say it is already running
conch update VERSIONinstall that release; an older one moves conch back
conch update listlist the releases published upstream, newest first, marking the running, latest and locally kept ones
conch update rollbackgo back to the version before the last update, from the copy it kept

See Auto-update and Going back to an older version.

version

conch version [--json] prints the version, build and platform (also --version, -v).

Internal commands

These are run by conch itself, not by you:

CommandUsed by
conch bridgea remote client over ssh: connects stdio to this machine's server, starting it if needed
conch reportagent hooks and plugins, to report state to the server