Fanout: orchestrate parallel agents

Updated August 4, 2026

Fanout turns one Claude session into a manager for a whole team of agents. Give it a list of tasks and it figures out which project each one belongs to, opens a worker (a Claude running in its own shard) for each, watches over them (handling their approvals and answering their questions), and folds their finished work back in when they’re done. Instead of babysitting five agents in five tabs, you talk to one manager that runs the other five.

Guild feature. Fanout spawns, merges, and approves on your behalf, so it relies on the control commands of the crystl CLI, which require a Guild membership.

Using it

/fanout is a slash command. crystl installs it automatically (to ~/.claude/commands/fanout.md) so it’s available in any Claude Code session, no setup. Type it with a freeform task list:

/fanout fix the login bug in webapp; add tests to the api; update the changelog in docs

The manager reads your list and runs the loop below on its own. You only hear from it when it needs you: a worker asked a question it can’t answer, or something risky needs your approval.

What it does

  1. Resolve each task to a project. It matches each task to an open gem by name (fuzzy is fine, so “webapp” finds “my-webapp”); if none is open it scans your projects directory and opens the best match; if it’s ambiguous it asks you.
  2. Spawn a worker per task. One shard per task, briefed with the task plus a protocol that tells the worker to report back over the quest channel.
  3. Attend the workers. It reads each worker’s reports (done / blocked / a question), approves their safe operations, answers their questions from your intent, and escalates to you anything it’s unsure about or anything risky.
  4. Merge finished work. When an isolated worker reports done, the manager merges its branch back into the project’s main branch. Conflicts are left for you to resolve.
  5. Report. When everyone’s finished it gives you a per-worker summary: what got done, what merged, what was blocked, and anything left for you.

Workers don’t all have to be on the frontier API. Any agent can run on an open model you configured, so the manager can hand mechanical tasks (lint fixes, running a suite and reporting back) to a self-hosted or managed open-model worker and keep the thinking with a stronger model. One self-hosted connection is one machine, so keep it to a worker or two there. A hosted open model doesn’t have that limit.

A big fan-out also has a memory cost, and the manager can see it: crystl status reports the app’s memory and system pressure plus each shard’s resident memory, so it can check before spawning and keep workers light with a --scrollback cap (or free a noisy worker’s buffer afterwards with crystl scrollback clear).

Isolation: separate live checkouts

Two or more tasks targeting the same project each run in their own isolated git worktree (a separate working copy on its own branch), so their live in-repo edits do not overwrite one another. crystl merges each one back when it finishes; if branches changed the same lines, the manager surfaces the integration conflict instead of shipping a broken file. A lone worker in a project just runs in place. You can override this in plain language: “all isolated” or “all shared.”

Non-git projects can’t be isolated, so the manager won’t run multiple workers concurrently in one. It’ll suggest git init or run them one at a time.

Approval and escalation

By default workers run in smart approval mode: crystl auto-approves safe, read-only operations, and anything destructive or risky comes to the manager, which escalates it to you. You can change the posture per run in plain language:

  • “full auto”: workers run with everything auto-approved (good for trusted, low-risk task lists).
  • “ask before anything destructive” / “check everything”: the manager escalates every approval to you.
  • “report only, don’t merge”: finished branches are reported as ready instead of being merged.

When a worker asks a question the manager can’t confidently answer from your task description, it escalates it to you and relays your answer back, so you stay in the loop on the decisions that matter without watching every step.

When the manager dispatches to a worker it uses crystl send … --wait, so it knows the instruction arrived instead of assuming it did. A worker mid-turn still counts as delivered (the message lands in the agent’s own input queue), and the exit code tells the three cases apart: 0 delivered, 3 queued behind the worker’s current turn, 1 no receipt from an idle shard. 3 is the one that matters for a manager, because re-sending on it hands the worker the same task twice.

A worker can also stall on the agent’s own in-terminal approval prompt (its “Do you want to proceed?” menu), which is separate from crystl’s approval flow. crystl flags these in crystl shards and crystl status as ⏸ awaiting input, so the manager spots a silently parked worker and clears it instead of mistaking it for one that is still working. A quiet worker is not necessarily finished, so the manager checks for this before treating a task as done.

How it’s built

Fanout is a prompt, not a separate app. The /fanout command drives the regular crystl CLI. The worker shards talk back through crystl’s quest message channel (quest_msg), the manager handles their approvals with crystl pending / crystl approve, and it integrates finished branches with crystl merge. Everything it does is something you could do by hand from the command line.