# How SwarmForge Orchestrates AI Agents: A Deep Dive into Declarative Agent Coordination

> Learn how SwarmForge orchestrates AI agents using declarative configurations to manage tmux sessions, git work-trees, and shell commands for tools like Claude, Codex, and Grok.

- Repository: [Robert C. Martin/swarm-forge](https://github.com/unclebob/swarm-forge)
- Tags: deep-dive
- Published: 2026-09-02

---

**SwarmForge orchestrates AI agents by transforming a declarative configuration file into coordinated tmux sessions, isolated git work-trees, and specialized shell commands that launch agents like Claude, Codex, and Grok with role-specific prompts and environment settings.**

The [unclebob/swarm-forge](https://github.com/unclebob/swarm-forge) project provides a lightweight, Unix-native approach to **AI agent orchestration** using tmux as the process supervisor and git work-trees for filesystem isolation. Unlike container-heavy alternatives, SwarmForge keeps agents in the same repository context while giving each a distinct view of the codebase.

## The Three-Layer Orchestration Pipeline

SwarmForge's **agent orchestration** follows a clear pipeline from configuration to execution:

| Layer | Purpose | Core Functions |
|-------|---------|--------------|
| **Config → Context** | Parse and validate [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) | `parse-config`, `context` |
| **Workspace Setup** | Create state directories, work-trees, and helper scripts | `prepare-workspace!`, `prepare-worktrees!`, `check-helper-scripts!` |
| **Agent Launch** | Build and send commands to tmux panes | `launch-command`, `launch-role!`, `launch-roles!` |

## Layer 1: Parsing Configuration and Building Context

### Reading the Declarative Configuration

The **agent orchestration** begins in `parse-config` (lines 13-38 of [`swarmforge.bb`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarmforge.bb)), which processes [`swarmforge/swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/swarmforge.conf) line by line:

- Extracts directives: `window` or `window-invisible`
- Parses role name, agent name, work-tree, receive mode, propagation rule, and extra arguments
- Validates against constraints: no underscores in role names, unique work-trees per role
- Verifies the agent exists in `known-agents` (`#{"claude" "codex" "copilot" "grok"}`)
- Confirms the corresponding prompt file exists in `swarmforge/roles/`

### Constructing the Runtime Context

The `context` function (lines 59-73) builds a **context map** containing:

- Absolute paths for project root, scripts directory, and state directory (`.swarmforge`)
- **tmux socket name**: derived from CRC32 of the working directory for isolation
- **Terminal backend detection**: `iterm2`, `terminal-app`, `windows-terminal`, or `none`

This context map threads through all subsequent operations, ensuring consistent path resolution and session naming.

## Layer 2: Preparing the Workspace and Isolating Agents

### State Management and Script Distribution

The `prepare-workspace!` function (lines 39-49) creates the `.swarmforge` directory structure and writes two critical TSV files:

| File | Purpose |
|------|---------|
| `sessions.tsv` | Maps roles to tmux session names for dashboard consumption |
| `roles.tsv` | Records role-to-work-tree mappings for the hand-off daemon |

The `check-helper-scripts!` function (lines 84-92) ensures all scripts in `required-helpers` are executable and available in `.swarmforge/bin`.

### Git Work-Tree Isolation

For **agent orchestration** that prevents filesystem collisions, `prepare-worktrees!` (lines 21-27) creates lightweight git branches:

```bash
git worktree add -b swarmforge-<worktree> .swarmforge/worktrees/<role>

```

Each non-master role receives:
- A dedicated work-tree directory under `.swarmforge/worktrees/`
- A branch named `swarmforge-<worktree>` pointing at current `HEAD`
- Shared repository history with zero-copy overhead

## Layer 3: Launching Agents into Tmux Sessions

### Building Agent-Specific Commands

The `launch-command` function (lines 90-128) constructs the precise shell command injected into each tmux pane:

```clojure
;; Example: Building a command for the "refactorer" role
(str "export SWARMFORGE_ROLE=" role "; "
     "export PATH=" scripts-dir ":" state-dir "/bin:$PATH; "
     "cd " work-tree "; "
     (agent-binary agent) " " (yolo-flag agent) " "
     (alt-screen-env agent) " "
     extra-args " "
     prompt-file)

```

**Agent-specific adaptations** include:
- **yolo-flag**: `--yolo` for agents that support it (disables confirmation prompts)
- **alt-screen-env**: Terminal environment variables to suppress alternate screen modes
- **extra-args**: Role-specific flags from configuration

### Tmux Injection and Sequencing

The `launch-role!` function (lines 66-73) sends commands via `tmux send-keys`:

```bash
tmux -S <socket> send-keys -t <session>:<window>.<pane> "<command>" C-m

```

The `launch-roles!` orchestrator (lines 44-50) controls startup timing:

- Respects `SWARMFORGE_AGENT_START_DELAY_MS` (default: 1500ms)
- Starts agents sequentially to prevent resource contention
- Treats the first role specially as the "lieutenant"

## Supporting Services for Coordinated Operation

### Hand-Off Daemon

`start-handoff-daemon!` launches `handoffd.bb` to move files between agents based on propagation rules (`forward-only`, `back-one`, `broadcast`). Optional sleep inhibitors (`caffeinate` on macOS, `systemd-inhibit` on Linux) keep the daemon active.

### Web Dashboard

`start-pack-web!` runs [`pack_web.sh`](https://github.com/unclebob/swarm-forge/blob/main/pack_web.sh), serving the SwarmForge UI and writing its URL to `.swarmforge/dashboard-url` for quick access.

### Terminal Surfaces

`open-terminal-surfaces!` adapts to detected backends—opening separate iTerm2 windows, Terminal.app tabs, or Windows Terminal panes as appropriate.

## Practical Usage Examples

### Defining a Multi-Agent Configuration

```clojure

# swarmforge.conf

# role      agent    worktree   receive-mode   propagation   extra-args

coder       codex    master     task           forward-only  --yolo
refactorer  copilot  refactor   batch          back-one      --no-alt-screen
specifier   claude   spec       task           forward-only  bypassPermissions

```

### Starting a SwarmForge Session

```bash

# From repository root, targeting a project

bb swarmforge.bb /path/to/project

```

This invokes `run-main!` (lines 62-86), the top-level orchestrator that wires all layers together.

### Testing Launch Commands

```bash
bb swarmforge.bb --test-launch-command /path/to/project codex "--yolo"

```

Outputs the exact tmux command without executing it, useful for debugging **agent orchestration** logic.

## Summary

- **SwarmForge orchestrates AI agents** through a three-layer pipeline: configuration parsing, workspace preparation, and tmux-based launch
- **Git work-trees** provide lightweight filesystem isolation without container overhead
- **Context maps** carry path and session information through all operations
- **Agent-specific command builders** adapt flags and environment per AI backend
- **Supporting services** (hand-off daemon, dashboard, terminal adapters) enable multi-agent coordination

## Frequently Asked Questions

### What agents does SwarmForge support?

SwarmForge supports Claude, Codex, Copilot, and Grok as built-in agents, defined in `known-agents`. The architecture allows extending support by adding agent-specific helper functions like `yolo-flag` and `alt-screen-env` in the source.

### How does SwarmForge isolate agent filesystem access?

Each role receives a dedicated git work-tree via `prepare-worktrees!`, creating a `swarmforge-<worktree>` branch that shares repository history while presenting an independent file view. Roles configured with `master` or `none` work-trees skip this isolation.

### Can I control the startup timing between agents?

Yes. Set the `SWARMFORGE_AGENT_START_DELAY_MS` environment variable (default 1500ms) to adjust the sequential delay between agent launches in `launch-roles!`.

### Where does SwarmForge store runtime state?

All state lives in `.swarmforge/` at the project root: work-trees under `.swarmforge/worktrees/`, helper scripts in `.swarmforge/bin/`, and metadata files (`sessions.tsv`, `roles.tsv`, `dashboard-url`) for dashboard and daemon consumption.