# How SwarmForge Uses tmux: Session Management, Transcript Capture, and Role Isolation

> Discover how SwarmForge leverages tmux for isolated sessions, transcript capture, and role management. Optimize your swarm operations with powerful terminal orchestration.

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

---

**SwarmForge uses tmux as the core infrastructure for orchestrating isolated terminal sessions per role, capturing interactive output to scrollback, and enabling clean teardown when swarms complete.**

In the `unclebob/swarm-forge` repository, tmux is not merely a convenience tool—it is the deliberate architectural choice for managing the lifecycle of multi-role swarms. The codebase demonstrates precise control over tmux socket creation, per-role session spawning, output persistence, and server shutdown. This article examines the implementation details found in the test suite and supporting files.

## Tmux Socket Creation and Portability

Every swarm begins with a **dedicated tmux socket**. This socket file enables multiple processes to coordinate against the same tmux server without relying on default system paths.

The socket path is written to `.swarmforge/tmux-socket` for discoverability:

```clojure
(let [sock (str (fs/path root "tmux.sock"))]
  (write-file (fs/path root ".swarmforge/tmux-socket") (str sock "\n"))
  ;; Subsequent tmux commands use -S sock
  ...)

```

This pattern appears in `test/swarmforge/script_test.clj` at lines 110 and 893, where the test suite verifies socket file existence and persistence. The socket-based approach ensures that:

- SwarmForge can run multiple swarms concurrently without socket collisions
- Any subprocess can locate and communicate with the correct tmux server
- The entire tmux state is scoped to the swarm's working directory

## Per-Role Session Spawning

Each role in a swarm receives its own **isolated tmux window**. The helper `start-tmux!` in `test/swarmforge/pack_ui_test.clj` (line 195) encapsulates this logic:

```clojure
;; From pack_ui_test.clj - starts tmux session for each role
(doseq [role roles]
  (run {:dir root}
       "tmux" "-S" sock "new-session" "-d" 
       "-s" (str "swarmforge-" role) 
       "sleep" "120"))

```

The session naming convention `swarmforge-{role}` creates predictable targets for subsequent commands. The `-d` flag ensures sessions detach immediately, running in the background while SwarmForge continues orchestration.

Commands are dispatched to specific windows using the `-t` target flag:

```clojure
(run {:dir root}
     "tmux" "-S" sock "send-keys"
     "-t" "swarmforge-specifier:Specifier.0"
     "-l" "your command here" "C-m")

```

This direct addressing enables SwarmForge to route tasks to the appropriate role without complex process management.

## Transcript Capture in Scrollback

A critical requirement for swarm observability is **retaining complete output history**. SwarmForge leverages tmux's native scrollback buffer for this purpose.

The test `launch-command puts transcript in scrollback` at line 447 of `test/swarmforge/script_test.clj` explicitly validates this behavior. After a command executes, its full output remains accessible through tmux's history—enabling:

- Post-hoc debugging of failed role executions
- Replay of interactive sessions
- Audit trails without separate log file management

This design choice avoids the complexity of external log aggregation while ensuring no output is lost during role execution.

## Graceful Shutdown and Cleanup

When a swarm terminates, SwarmForge ensures **complete tmux server teardown**. The `close-swarm` logic at line 886 of `test/swarmforge/script_test.clj` demonstrates the pattern:

```clojure
;; Kill the tmux server and all associated sessions
(run {:dir "." :ok? false} "tmux" "-S" sock "kill-server")

```

The `:ok? false` parameter acknowledges that the command may fail if the server already exited—an acceptable condition that prevents error propagation during cleanup. This approach guarantees:

- No orphaned tmux processes persist after swarm completion
- The socket file becomes invalid, preventing accidental reconnection
- System resources are promptly released

## Summary

- **Socket-based coordination**: Each swarm creates a dedicated tmux socket stored at `.swarmforge/tmux-socket`, enabling portable multi-process access
- **Per-role isolation**: Every role runs in a named tmux session (`swarmforge-{role}`), with commands targeted via explicit window addresses
- **Built-in output persistence**: Tmux scrollback buffers capture complete transcripts without additional logging infrastructure
- **Clean resource management**: `kill-server` ensures deterministic teardown of all sessions and the socket on swarm completion

## Frequently Asked Questions

### Why does SwarmForge use tmux instead of Docker or raw subprocesses?

Tmux provides lightweight terminal multiplexing without containerization overhead. As implemented in `unclebob/swarm-forge`, it offers interactive session persistence, scrollback capture, and clean signal propagation—capabilities that raw subprocess management would require significant custom code to replicate.

### Where is the tmux socket path stored in a swarm project?

The socket path is written to `.swarmforge/tmux-socket` in the swarm root directory. This convention appears in `test/swarmforge/script_test.clj` (lines 110, 893) and enables any component to locate the active tmux server for that swarm.

### How does SwarmForge prevent tmux session name collisions?

Session names follow the pattern `swarmforge-{role}` combined with a unique socket path per swarm. Since each swarm operates on its own socket, identical role names across different swarms do not conflict—demonstrated in `test/swarmforge/pack_ui_test.clj` (line 195).

### Can I inspect a running swarm's tmux sessions manually?

Yes. With the socket path from `.swarmforge/tmux-socket`, run `tmux -S /path/to/socket list-sessions` to view active role windows. The test suite at `test/swarmforge/script_test.clj` shows this pattern used for verification during automated testing.