berthdocs

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:

PieceCLIBox API
Start work: a worktree with an agent in itberth task new BOX/LOC/NAME --agent claude --prompt …POST /v1/tasks
Prompt a running agentberth session send BOX/SESSION TEXTPOST /v1/sessions/{name}/send
Wait for its turn to endberth session wait BOX/SESSIONGET /v1/sessions/{name}/wait
Run a check where it worksberth exec BOX/LOC[/WT] -- COMMANDPOST /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 1h

It 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 --changed

Runs 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 5

It 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:

~/.berth/hooks.json
{
  "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.

On this page