# How the SwarmForge Launcher Works: Orchestrating AI Agents with Babashka and TMUX

> Discover how the SwarmForge launcher orchestrates AI agents using Babashka and TMUX. Learn about context setup, dependency validation, and agent spawning.

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

---

**The SwarmForge launcher is a Babashka script (`swarmforge.bb`) that orchestrates AI agents by constructing a runtime context, validating dependencies, preparing Git work-trees and TMUX sessions, and spawning configured agents in isolated terminal environments.**

The `unclebob/swarm-forge` repository implements a novel approach to multi-agent AI workflows using a lightweight Clojure-based launcher. Unlike containerized orchestrators, the **SwarmForge launcher** leverages TMUX sessions and Git work-trees to create isolated execution contexts for each AI role, all managed through a single portable Babashka script located at `swarmforge/scripts/swarmforge.bb`.

## Entry Point and Dependency Validation

The launch sequence begins with a thin shell wrapper. The [`swarmforge.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.sh) script located at [`swarmforge/scripts/swarmforge.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarmforge.sh) simply execs the Babashka launcher, passing all arguments unchanged to `swarmforge.bb`.

Once invoked, the `run-main!` function performs strict dependency verification. It asserts that `tmux`, `git`, and `bb` (Babashka) are available on the host system before proceeding. This validation occurs in `swarmforge/scripts/swarmforge.bb` at lines 106-108, ensuring the environment can support the subsequent TMUX and Git operations.

## Building the Runtime Context

Before spawning agents, the launcher constructs a comprehensive context map. The `context` function (lines 55-66) creates a map containing absolute paths for the working directory, script directory, and a unique TMUX socket. The socket name is derived using a CRC32 hash of the working directory path, preventing collisions when running multiple SwarmForge instances.

The launcher then detects host-specific TMUX configurations using `detect-tmux-base-indexes` (lines 87-97). This function probes a temporary TMUX session to discover the `window-base-index` and `pane-base-index` values, ensuring the launcher respects local TMUX conventions.

Simultaneously, `detect-terminal-backend` (lines 52-60) selects an appropriate terminal adapter. It checks the `SWARMFORGE_TERMINAL` environment variable or probes for OS-specific commands to determine whether to use `iterm2`, `terminal-app`, `windows-terminal`, or fall back to `none`.

## Configuration Parsing and Validation

The launcher reads the swarm configuration from [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) using `parse-config` (lines 29-90). This function validates each line of the configuration and builds a **row** for every role, capturing the role name, agent type (e.g., `claude`, `codex`, `copilot`, `grok`), work-tree specification, and receive mode. These rows are stored in the `:roles` key of the context map.

Following parsing, `check-backend-dependencies!` (lines 92-95) verifies that each agent binary referenced in the configuration is actually installed on the host, failing fast if dependencies are missing.

## Workspace and Git Infrastructure

If the working directory is not already a Git repository, `initialize-git-repo!` (lines 121-127) initializes one and commits the initial SwarmForge files. This ensures Git work-trees can be created for individual roles.

The `prepare-workspace!` function (lines 42-50) creates the internal directory structure, including `.swarmforge` and `.worktrees`, writes the `sessions.tsv` and `roles.tsv` metadata files, and ensures helper scripts are executable. For roles requiring separate work-trees, `prepare-worktrees!` (lines 51-60) creates Git work-trees linked to the main repository.

The launcher then prepares inter-agent communication infrastructure. `prepare-handoff-dirs!` (lines 61-64) creates inbox/outbox folder structures under each role’s `.swarmforge/handoffs` directory. Any stale coordination processes are terminated via `stop-handoff-daemon!` (lines 61-65), and existing TMUX sessions with matching names are killed to prevent clashes.

## TMUX Session Orchestration

For each configured role, `create-role-session!` (lines 96-99) creates a dedicated TMUX session with a window named "swarm", disabling window-renaming to maintain consistent references. Helper scripts are synchronized to each work-tree via `sync-worktree-scripts!` (lines 70-86), ensuring agents can invoke local utilities.

The background coordination process starts via `start-handoff-daemon!` (lines 88-99), which launches `handoffd.bb` to watch hand-off directories. This daemon optionally uses OS-specific sleep-inhibition tools to prevent the host from suspending during long-running agent tasks.

## Agent Deployment and Terminal Surfaces

Agent execution begins with `launch-role!` (lines 50-59). For each role, this function constructs a command that sets environment variables (`SWARMFORGE_ROLE`, `PATH`), changes to the role’s work-tree directory, and invokes the specified agent binary with the role-specific prompt file. The first role (index 0) receives special cleanup logic that runs when the agent exits.

If a terminal backend was detected, `open-terminal-surfaces!` (lines 20-28) creates separate OS windows for each TMUX session and starts a watchdog process to keep windows synchronized. If no backend is available, the launcher attaches the current shell to the first session.

Finally, the launcher prints a "SwarmForge is ready" banner displaying the working directory and a list of session names for manual re-attachment.

## Practical Usage Examples

### Running the Launcher

```bash

# From the repository root using the shell wrapper

./swarmforge/scripts/swarmforge.sh .

# Direct Babashka invocation

bb swarmforge/scripts/swarmforge.bb .

```

The dot (`.`) specifies the current directory as the SwarmForge root.

### Minimal Configuration File

Create [`swarmforge/swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/swarmforge.conf) with role definitions:

```text

# role   agent   worktree   receive-mode   [extra-args]

window   claude   master     task

```

This creates a TMUX session named `swarmforge-window` running the Claude agent.

### Inspecting Generated Metadata

After launch, examine the generated tracking files:

```bash
cat .swarmforge/sessions.tsv   # Session index → role → tmux session name

cat .swarmforge/roles.tsv      # Full role metadata (worktree, agent, etc.)

```

### Manual Session Attachment

```bash
tmux -S /tmp/swarmforge-$(id -u)/<socket-id>.sock attach-session -t swarmforge-window

```

The socket path is printed in the launcher output during initialization.

### Testing Launch Commands

To preview the command that would be sent to TMUX for a specific role:

```bash
bb swarmforge/scripts/swarmforge.bb --test-launch-command /path/to/repo claude "--yolo"

```

## Summary

- The **SwarmForge launcher** is implemented as a Babashka script (`swarmforge.bb`) that orchestrates AI agents through TMUX sessions and Git work-trees.
- The launch pipeline executes 19 distinct steps ranging from dependency validation (`run-main!`) to agent deployment (`launch-role!`).
- **Context construction** involves creating a CRC32-derived TMUX socket, detecting base indexes, and selecting terminal backends.
- The **handoff daemon** (`handoffd.bb`) coordinates file-based communication between agents using inbox/outbox directories.
- Agent isolation is achieved through Git work-trees and dedicated TMUX sessions, with optional native terminal window management for supported emulators.

## Frequently Asked Questions

### What is Babashka and why does SwarmForge use it?

**Babashka is a native Clojure interpreter designed for scripting.** SwarmForge uses it because Babashka provides the expressiveness of Clojure with fast startup times and no JVM overhead, making the launcher portable and efficient for shell-script-like tasks while maintaining access to the Clojure standard library.

### How does SwarmForge prevent conflicts between multiple AI agents?

**SwarmForge isolates agents using Git work-trees and dedicated TMUX sessions.** Each role receives its own filesystem context (via `prepare-worktrees!`) and terminal session (via `create-role-session!`), while the handoff daemon (`handoffd.bb`) mediates file-based communication through structured inbox/outbox directories to prevent race conditions.

### Can I use SwarmForge with terminal emulators other than iTerm2?

**Yes, SwarmForge supports multiple terminal backends.** The `detect-terminal-backend` function checks for `iterm2`, `terminal-app` (macOS), `windows-terminal`, or falls back to direct TMUX attachment. You can also force a specific backend by setting the `SWARMFORGE_TERMINAL` environment variable.

### How do I manually reconnect to a running SwarmForge session?

**Use the TMUX socket path printed during launch.** The launcher outputs the specific socket path (typically under `/tmp/swarmforge-$(id -u)/`), which you can use with `tmux -S <socket> attach-session -t <session-name>`. Alternatively, run the launcher again from the same directory, which will detect existing sessions and print the attachment commands.