Guides
Orchestration
Agents driving agents. Prompt, wait, check, loop, hand off and broadcast, from the app, the CLI, the API or another agent.
Agents in Berth can drive each other, and so can you, a hook, a flow or a plugin. Four pieces on every box do it, the same from the app, the CLI and the API:
| Piece | CLI | Box API |
|---|---|---|
| Start work: a worktree with an agent in it | berth task new BOX/LOC/NAME --agent claude --prompt … | POST /v1/tasks |
| Prompt a running agent | berth session send BOX/SESSION TEXT | POST /v1/sessions/{name}/send |
| Wait for its turn to end | berth session wait BOX/SESSION | GET /v1/sessions/{name}/wait |
| Run a check where it works | berth exec BOX/LOC[/WT] -- COMMAND | POST /v1/exec |
On a box, berthd takes the same commands without the BOX/ prefix, which
is what agents there use.
Send
berth session send devl/cal-billing-claude "Rebase on main and fix any conflicts"The text is pasted as one block (so a multi-line prompt is one prompt), then
Enter is pressed (--no-enter leaves it typed). Prompts never appear in
events or logs; only session.sent with the session's name.
before:session.send hooks can refuse a prompt.
With --wait, it then waits for the turn the prompt starts to end (up to
--timeout, 30 minutes by default). With --queue, a prompt for a box that
cannot be reached waits on the laptop instead of failing; see
the offline queue.
Wait
berth session wait devl/cal-billing-claude # finished or waiting
berth session wait devl/cal-billing-claude --for finished --timeout 1hIt returns when the agent is finished or waiting (or the states you ask
for), or when its program exits. berth session wait counts the state the
agent is in now; berth session send … --wait counts only what comes after
the prompt, so the previous turn's finished does not end it. Over the API,
only states reported after after count.
Exec
berth exec devl/cal/billing -- pnpm test --changedRuns a command to completion through a login shell in the location or
worktree, with its environment, and returns its exit code and the last 64 KB
of output (--timeout, 10 minutes by default). before:exec hooks can
refuse it.
Patterns
Loop until a check passes
berth loop devl/cal-billing-claude --check "pnpm test" --prompt "Make the tests pass" --max 5It prompts, waits, runs the check in the session's worktree, and sends the
failure back ("The check … failed: …output… Fix it.") until the check
passes or --max rounds (default 5) run out. It stops if the agent is
waiting for a human; --turn-timeout bounds each turn. In the app, Loop until… in a session's
menu does the same, and running loops show in a panel in the corner.
Hand off
A new worktree and agent picking up where another left off:
berth task new devl/cal/billing-tests --agent codex \
--prompt "Continue from cal-billing-claude in ~/work/cal-billing: write the missing tests."The app's Hand off to… does the same and records from_session on the
task.
Review
A second agent in the same worktree:
berth session new devl/cal/billing --agent codex --prompt "Review the uncommitted changes. Do not edit."Broadcast
The app can send one prompt to several agents at once: Send a prompt to
several agents… in ⌘K, Send to N agents… on the Agent Dashboard,
Prompt agents… on a selection in Worktrees, or Send to several… in the
prompt library. The prompt's {{variables}} are filled in for each agent
(its branch, worktree, project, box), sends go one after another, and you
can wait for every turn to end and read what each said. Agents on offline
boxes can be queued for when they're back.
Chain with hooks and flows
A hook on the box can start the next step when an agent finishes. Here a
Codex session named reviewer looks at whatever Claude Code just did; the
case keeps the reviewer's own finished turns from prompting it again:
{
"hooks": [
{ "on": "agent.finished", "run": "case \"$BERTH_AGENT\" in claude) berthd session send reviewer \"Review what changed in $BERTH_PATH\";; esac" }
]
}For anything with more than one step (run the tests, send failures back, notify you), use a flow.
From an agent
The skills Berth installs (berthd integrations install claude) teach
agents these commands, so an agent can split work across worktrees, ask
another agent for a review, or loop on a check by itself. The
berth-orchestrate skill also tells them never to answer another agent's
question on the user's behalf. See agent integrations.
From a plugin
Plugins get the same operations as berth.orchestrate: send, wait,
exec, handoff, review and loop; see
the plugin SDK.
Agent state
All of this relies on agents reporting their state through their own hooks,
so it works fully for Claude Code, and for Codex and Cursor as far as they
report (finished only). See
sessions and agents.