Agent Tile BlogRunning a fleet of AI coding agents, well.

Sending one command to many AI agent sessions at once

· workflow, terminal, parallelism

There's a specific moment where running several AI coding agents stops feeling like leverage. You've just merged something into main, and now six sessions are working against a stale base. Every one of them needs the same sentence. So you click a window, type it, click the next, type it again, and by the fourth you've lost track of which ones you've done.

The work didn't get harder. The addressing did. You have one instruction and six recipients, and no way to say it once.

The two shapes of fan-out

Terminals have solved this twice, in different ways.

tmux treats it as a scripted operation. send-keys writes into a pane's input as if you'd typed it:

# every pane in the current window
tmux list-panes -F '#{pane_id}' \
  | xargs -I{} tmux send-keys -t {} 'git pull --rebase origin main' Enter

Widen the scope to every pane in the session by swapping in list-panes -s, or every pane on the server with -a. Because it's just a command, you can put it in a shell function and give it a name:

fleet() {
  tmux list-panes -s -F '#{pane_id}' \
    | xargs -I{} tmux send-keys -t {} "$*" Enter
}
# fleet "run the test suite and report only failures"

Note the Enter as a separate argument — without it the text lands in the input but never submits, which looks exactly like nothing happening.

iTerm2 treats it as a mode. Shell → Broadcast Input → Send Input to All Panes in Current Tab (⌥⌘I) puts a blue border on the affected panes and mirrors your keystrokes into all of them until you turn it off. It's faster to reach for and much easier to forget you left on. The border is the only thing standing between you and typing rm -rf into eight places at once, so treat that border as a real signal, not decoration.

The tmux approach is precise and scriptable. The iTerm2 approach is immediate and dangerous. Most fleets end up wanting both: a mode for conversation, a script for routine.

What's actually safe to broadcast

The failure mode isn't technical, it's semantic. Broadcast assumes every recipient is in the same state. Agents are usually not.

Safe, because they're idempotent and state-independent:

  • git pull --rebase origin main — every worktree wants the new base
  • "run the full test suite, report only failures"
  • "stop what you're doing"
  • "summarize what you've changed so far, then wait"
  • dependency reinstalls after a lockfile change

Unsafe, because the right answer differs per session:

  • anything containing a branch name, file path, or ticket number
  • "commit and push" — one agent's work is finished, another's is half-written
  • "yes" or "continue" — you have no idea what each one is asking
  • destructive git operations: reset --hard, checkout ., clean -fd

That last group is the one that hurts. A blanket "yes" sent to six agents answers six different questions, and one of them was "should I delete the migration files?"

The rule that holds up: broadcast instructions, not answers. Instructions are about the future and can be evaluated independently by each session. Answers are about a specific question you can't see from the broadcast bar.

Prompts that survive fan-out

A prompt sent to one agent can be lazy about context. A broadcast prompt can't — it lands in six different conversations and has to make sense in all of them.

Two habits make the difference:

Make it self-scoping. "Update the imports" depends on what the agent was doing. "In files you have modified in this branch, update any imports of lib/auth to lib/auth/session" doesn't. The agent that touched no such file correctly does nothing.

Ask for a bounded report. Add "reply with one line: DONE or the error" and scanning six panes becomes reading six lines instead of six scrollbacks. This is the single highest-value phrase to keep in a snippet.

Put together:

Rebase onto the latest origin/main. If there are conflicts, stop and do not resolve them. Reply with exactly one line: REBASED, CONFLICT <file>, or ERROR <message>.

Six sessions, six lines, one glance.

Groups beat "all"

"All panes" is the wrong granularity almost immediately. Three agents on the frontend repo and three on the API don't want the same pull. What you want is a named subset — a group you can address on purpose.

tmux gives you this through structure: put each project in its own window or session, and target -t projectname instead of everything. It works, but the grouping lives in your head and in how you happened to arrange things at 9am.

The alternative is tooling that makes the group a first-class object — sessions labeled by project and folder, selected explicitly, addressed as a set, so you can see which sessions are about to receive the instruction before you send it. That preview is the part that turns broadcast from a risk into a routine. In Agent Tile, ⌘-clicking tiles builds exactly that selection: the chosen tiles are visibly marked, and the next thing you type goes to those and only those.

Start here

Add the fleet function above to your shell config today. Use it only for git pull --rebase, the test suite, and "stop". That's three commands that are always safe and that you currently type five times each.

Once that's habit, the useful question is no longer "how do I send to all" but "how do I choose the four that should hear this" — and that's a grouping problem, not a typing problem.

Agent Tile
Practical guides for running many Claude Code sessions in parallel on macOS — orchestration, review workflows, and staying sane with a fleet of AI coding agents.
Get Agent Tile — full source, $10 once →
Also from TechAthletes
  • IT-QA — Technical Q&A with AI-assisted answers and point bounties — for the questions that come up while you're running a fleet.