Using conch
Agents working together
An agent in a conch pane can start another agent, prompt it, wait for it and read its answer — a reviewer for its change, a tester, a second opinion — without you passing messages between them. Each helper runs in a pane of its own, on its own branch, and shows in the tree like any other agent, so you can watch it, answer it or close it at any time.
Setting it up
The agents learn how from a skill conch carries. Install it once on each machine:
conch agent skill # says where it would write, and writes nothing
conch agent skill -apply # writes it
Or without leaving the TUI. i on a project, branch or pane says under conch whether the agent whose tab is open has the skill on that machine, and S installs it or takes it away. For every agent at once: , → Agents → conch's own skill… lists every machine and how it stands there — every agent has it, 1 have it · 1 not, or the reason it could not be asked — and opening a machine names each agent and what would happen to it. Install it for every agent… and Take conch's copy away… name every path in a question before anything is written, the way the command plans before -apply. A machine at a time, through that machine's own server.
It goes where each agent reads your skills — ~/.claude/skills/conch for Claude Code, ~/.agents/skills/conch for Codex, Gemini CLI and OpenCode, and ~/.config/devin/skills/conch for Devin — beside your own skills, replacing none of them. -agent claude,codex installs it for some agents only, -remove -apply takes it away again, and conch -m MACHINE agent skill -apply installs it on another machine. Claude Code picks it up at once, even mid-session; restart the others if they don't list it.
Asking an agent for a second opinion
In a project, start an agent (c) and ask in plain words:
Get a second opinion on the change on this branch from another agent, and tell me what it found.
What happens, as it did in a real run with Claude Code:
- The agent sees it is in conch and loads the skill.
- It starts a helper as a task —
conch task -name login-reviewer "…"— which appears under the project in the tree, on a branch and worktree of its own. - Its change wasn't committed, so rather than commit your work to hand it over, it put the diff in the helper's prompt.
- It waits for the helper, then reads the
REVIEW.mdthe helper wrote in its worktree. - It tells you what the reviewer found, and closes the reviewer's pane. The reviewer's branch and worktree stay for you to keep or clean up.
If the helper stops to ask something — a permission, a question — the agent doesn't answer for it: it tells you which pane is waiting. Open that pane and answer it yourself.
Other things to ask for the same way: "have Codex write tests for this and run them", "ask another agent to try the migration on a copy of the branch", "get Claude and Gemini to each review it and compare".
Who started what
A pane an agent started carries the pane it came from, so the tree reads as a chain of work rather than a list of strangers. It is listed under the agent that started it:
Agents
▾ claude ⑂2
↳ reviewer
↳ tester
codex
Fold the agent and its helpers go with it. The agent that started them carries ⑂2, which turns amber as ⑂2! when one of them is waiting on a question. A helper that cannot sit under its agent — it is in another section, on another machine, or a search has narrowed the agent away — says ↳ for claude on its own row instead. The review queue (Q), the jump to whoever needs you (!) and desktop notifications all name the same thing — waiting for an answer for claude — so the three read as one.
A pane nobody started says nothing either way, and a creator that has gone leaves its helpers unclaimed rather than naming a pane that is not there.
Claude's own subagents
Claude Code can also hand work to subagents of its own — its Agent tool, background tasks — which run inside the same claude process and have no terminal. conch lists them under the agent too, from the hooks Claude reports when one starts and stops, each with the task it was given and its kind:
Agents
▾ claude
⠋ Writing gateway e2e tests general-purpose
⠋ Running race tests Explore
A subagent is listed only while it runs, and goes when it finishes or the session ends. It has no screen of its own, so selecting it shows the agent running it, and enter opens that agent — where Claude itself shows what its subagents are doing. There is nothing to type into, close or rename. Agents other than Claude Code report no subagents, and a remote machine lists them once its conch is updated.
From the tree
m on an agent's pane — or a right-click — has Prompt…: type the message, and it goes in as that agent's next one. conch then watches the work it started and says when it ends: finished what you asked, is waiting for you, or ended before it answered, in the status bar, or as a desktop notification when that pane is not the one you are looking at. You are told once.
An agent that is already waiting on a question of its own is not sent anything — the menu says so before you open it, and the server refuses it in its own words if it starts waiting in between. A machine whose server predates agent.prompt.v1 says that instead of offering it.
A long-running job
A build that takes most of an hour needs a little more care than a review, because an agent's shell tool isn't made for it: Claude Code's stops a command after 2 minutes by default, and an agent that moves a long command into the background ends its turn early — so "done" would come long before the build is. The way round it is to run the build in a terminal pane of its own, which has no time limit and outlives the agent's turns, and to have it leave a file saying it finished.
Start an agent in the project and ask:
Hand the full build of this project to a helper agent and tell me how it went.
Start the helper with
conch task -name builder. Tell it to:
- build the entire package with
make all, in its own worktree;- the build takes about 40 minutes — too long for its shell tool — so run it in a conch terminal pane:
conch new -name build-run -cwd <its worktree> -- sh -c 'make all > build.log 2>&1; echo $? > build.exit'- then check every couple of minutes whether
build.exitexists, running each check in the foreground, never in the background;- if the build fails, fix the cause, run it again the same way, and repeat — at most 3 attempts;
- at the end write
BUILD.md: pass or fail, the exit code, how long it took, the first error if any, and what it changed;- close
build-runwhen done. Don't commit, push or merge anything.Then wait for the helper with
conch agent prompt -wait -timeout 2horconch wait, and when it stops, readBUILD.mdfrom its worktree. IfBUILD.mdisn't there yet, it's still going — wait again rather than report.If the helper, or anything it runs, asks for a permission or a decision, stop and tell me which pane is waiting — don't answer for it.
Put your own build command and time in place of make all and 40 minutes. Three panes appear under the project — the agent you asked, builder on a branch of its own, and build-run, the terminal the build scrolls in — and you can open any of them while it runs:
you ──▶ your agent (p1)
│ conch task -name builder "…"
▼
builder (p2, its own branch and worktree)
│ conch new -name build-run -- sh -c 'make all > build.log …'
▼
build-run (p3, a terminal) ── writes build.log and build.exit
▲
└─ builder checks build.exit, fixes, runs again, writes BUILD.md
your agent ◀── reads BUILD.md and tells you
Why each instruction is there:
| Instruction | Why |
|---|---|
| the build in a terminal pane | no time limit, and it outlives the helper's turns |
echo $? > build.exit | a file that says it finished, and how — surer than reading a scrolling screen |
| checks in the foreground | keeps the helper's turn open while it waits, so its end means the job's end |
BUILD.md | the result is read from a file, not guessed from a screen |
| at most 3 attempts | a build it can't fix doesn't spend your usage for ever |
| no commit, push or merge | that is yours to decide; the branch stays for you |
| stop when it asks | a question is yours to answer; conch agent prompt won't type onto it anyway |
Without an agent in between, start the builder from a terminal pane and wait for it yourself:
conch task -name builder "Build the entire package with make all … (the instructions above)"
conch wait -state done,waiting -timeout 2h builder
cat "$(conch status | awk '$2 == "builder" { print $7 }')/BUILD.md"
Giving helpers files that aren't committed
A helper works in a fresh worktree, which holds what is committed on its branch — so a design plan you keep out of git, a spec you haven't committed, or notes in .gitignore aren't there. Two ways to hand them over:
-
Let conch copy them in. When it makes a worktree, conch copies files from the project's main checkout that git ignores and that match the project's local files —
.envand a few others by default. Add a pattern for yours, keeping the defaults, since the list replaces them:conch project ls # the project's ID conch project files ID .env '.env.*' .envrc .claude/settings.local.json CLAUDE.local.md \ .mcp.json AGENTS.override.md .gemini/.env 'docs/plans/*.md'Every task from then on starts with those files in its worktree — copied, never committed, so never pushed. The files must be in the main checkout, and git must ignore them there (
.gitignore, or.git/info/excludeto keep even the names private). -
Or give the path. Name the file's absolute path in the helper's prompt — "build against
~/src/app/docs/plans/api.md" — and it reads it from there. Every worktree is on the same disk.
Don't commit a private file, or force-add an ignored one, just to hand it over: it would then be in the branch's history for anyone who fetches it. The skill tells agents the same, and to ask you to add a pattern rather than change the project's local files themselves.
Doing it yourself
The commands the agents use are plain conch commands, so a script — or you, in a terminal pane — can drive agents the same way:
# A reviewer on its own branch, starting from yours (commit first: it sees only commits).
conch task -name reviewer -agent codex -base "$(git branch --show-current)" \
"Review this branch against main. Run commands in the foreground. Write findings to REVIEW.md."
# Wait for its first answer.
conch wait -state done,waiting -timeout 30m reviewer
# A follow-up: typed in, submitted, and waited for in one step.
conch agent prompt -wait -timeout 30m reviewer "Now check the error handling in login.py too."
case $? in
0) echo "finished" ;;
3) echo "it is asking something:"; conch read reviewer ;;
124) echo "still working after 30 minutes" ;;
esac
conch read reviewer # its screen
conch close reviewer # its branch and worktree stay
conch agent prompt is the safe way to message an agent. It types only into an agent, never into one waiting for an answer — a permission prompt, a trust question or a menu, where its Enter would answer something nobody read — and with -wait it waits for the work that message starts, not for the state the agent was in before it. It exits:
| Exit | Meaning |
|---|---|
0 | the agent's turn ended |
3 | the agent is waiting for an answer; nothing was typed |
124 | -timeout ran out; it may still be working |
1 | anything else: the pane ended, another program took it over, a name two panes share |
conch send still types anything anywhere — for your terminals, not for agents.
conch wait sees an agent done only while nobody is looking at it: finished in front of you, it goes straight to idle. Wait for -state done,waiting in scripts that run unwatched.
Names
-name reviewer on conch task, or conch rename ID NAME on any pane, lets every pane command address it by name: send, read, close, redraw, wait, agent prompt, agent explain. An ID (p and a number) always means the ID, so names of that shape are refused, and a name two running panes share is refused rather than guessed. See pane names.
Through MCP instead of the command line
An agent that would rather call a tool than run a command can reach the same work through conch mcp, an MCP server over stdin and stdout:
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…. Restart an agent afterwards for its client to list the tools.
The library writes it into each agent's own configuration, so this is one action rather than five formats. Its tools are list, read, start, prompt, wait, task and rename — the same server calls the commands above make, so neither door tells the agent something the other wouldn't. A tool call comes back as a typed result and a refusal written for the agent to act on: a prompt onto an open question says to read the screen and answer it, and a wait that runs out says it timed out rather than failing.
list says which subagents are running inside each agent too (the ones above), so an agent waiting on a helper can see it is busy without reading its screen.
The skill above teaches the commands. An agent that has both should use whichever its client makes easier; nothing goes wrong if it mixes them, since both reach one server.
Three reviewers at once
Where the tools earn their keep is a job with several helpers in it. One agent reviewing auth.py, another billing.py, a third the tests — three agents, three branches, three worktrees — driven by a lead agent that never runs a shell command:
task {"prompt":"review auth.py", "branch":"review-auth", "agent":"claude", "name":"auth"}
→ p2: claude started on branch review-auth in /src/api.worktrees/review-auth.
Wait for it (the wait tool) before prompting it: conch has to see the agent start
task {"prompt":"review billing.py", "branch":"review-billing", "agent":"codex", "name":"billing"}
task {"prompt":"review the tests", "branch":"review-tests", "agent":"gemini", "name":"tests"}
wait {"pane":"auth", "state":["idle","waiting"], "timeout_seconds":1800}
→ p2: claude is idle
prompt {"pane":"auth", "text":"Write what you found to FINDINGS.md, worst first."}
read {"pane":"auth", "tail":20}
→ …what it said
Four things that are harder from a shell, and why each matters:
- Nothing is parsed.
listanswers with data —{"pane":"p3","name":"billing","agent":"codex","agent_state":"idle","branch":"review-billing"}— whereconch statusanswers with a table whose columns move when a name gets longer. With three helpers to keep track of, a mis-split prompts the wrong agent. - Three kinds of agent, one interface.
agentis just a name; how each is launched, resumed and detected is conch's business. Reviewers that disagree usefully are the point of fanning out. - The order comes from the tool. Each
tasksays to wait before prompting, because conch has to see an agent start before it can be messaged. Without that, a prompt sent in the same breath is refused — and an agent that then reaches forconch sendtypes into whatever is on screen, which may be a trust question nobody read. - It stops at the boundary. Every pane above is the lead's own. Reach outside and the answer is
out_of_scope: … it did not start it, and it is in another project, which an agent can repeat to you instead of working around.
For one helper and one question, conch task and conch wait in a terminal are two lines and need none of this. The tools pay off when there are several helpers, several kinds of agent, or a client where every shell command needs your approval and a tool can be allowed once.
What an agent may do
An agent calling conch from inside its pane may start panes and tasks and read anything. What it may change is kept to its own work:
| It may change | It may not |
|---|---|
| panes it started, and the panes those started | other panes in other projects: typing, keys, closing, renaming, marking as seen |
| any pane in its own project | another project's branches and worktrees |
| its own project's branches and worktrees: commit, push, discard | conch server stop or reload |
| your own setup: the skill, the library, syncing one agent's setup to the others, and which local files a project copies into its worktrees — even in its own project |
The rest is refused, and the agent is told why:
conch: out_of_scope: the claude agent in p1 may not close p4: it did not start it, and it is in another project; do it from the TUI or a terminal pane
You are never held to this: the TUI, your terminal panes and scripts run outside conch act as you. conch tells who is asking from the operating system — the process at the other end of its socket and that process's parents, up to a pane — so an agent can't get round it by changing its environment. It is a guard against an agent closing the wrong session, not a sandbox: a program set on escaping can leave its pane's process tree.
On another machine
conch -m MACHINE from an agent's pane carries the agent's scope along: on the other machine it reaches only the panes it started there, and the projects it started them in.
conch: out_of_scope: the claude agent in p1 on laptop.local may not close p1: it did not start it; do it from the TUI or a terminal pane
A machine whose conch predates this isn't driven from an agent's pane at all — conch machine upgrade it. Like the rest, this holds for agents going through conch: one that runs ssh itself isn't held by it.
Good to know
- A helper sees only committed work. It starts on a branch of its own. With your work committed, pass your branch as
-base; if it isn't, the skill has the agent put the diff in the helper's prompt instead of committing for you. - Files a helper needs that aren't committed — a spec, a plan, notes kept out of git — don't reach its worktree on their own. See giving helpers files that aren't committed.
- Exit 0 is the end of a turn, not always of the work. A helper that puts a long command in the background ends its turn and takes the work up again later; a request that failed (an expired API key, say) ends a turn too. Ask helpers to run commands in the foreground, and check the result — the file you asked for — before relying on it.
- Codex and Devin are read from their screen. conch can't see a failed request there: it ends like a finished one. Claude Code, Gemini CLI and OpenCode report it through their hooks.
- Every helper spends usage. The skill tells agents to start only as many as the job needs.