How the SwarmForge Launcher Works: Orchestrating AI Agents with Babashka and TMUX
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 script located at 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 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
# 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 with role definitions:
# 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:
cat .swarmforge/sessions.tsv # Session index → role → tmux session name
cat .swarmforge/roles.tsv # Full role metadata (worktree, agent, etc.)
Manual Session Attachment
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:
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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →