# How SwarmForge Manages Local tmux Sessions for Project Isolation

> Learn how SwarmForge isolates local tmux sessions using unique Unix sockets. Discover its project isolation techniques for efficient development workflows.

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

---

**SwarmForge creates completely isolated tmux environments by generating unique Unix socket files per project and binding every tmux command to that specific socket using the `-S` flag.**

SwarmForge, an open-source project orchestration tool maintained in `unclebob/swarm-forge`, ensures robust terminal session isolation by managing local tmux sessions through private socket files rather than the default tmux server. This architecture prevents cross-project interference by spawning separate tmux server instances for each SwarmForge run, allowing developers to work on multiple projects simultaneously without window or session collisions.

## Per-Project Socket Architecture

SwarmForge establishes isolation at the filesystem level by creating dedicated socket directories and files that are unique to each user and project instance.

### Temporary Socket Directory Creation

When a SwarmForge run initializes, it constructs a temporary directory under `/tmp` that incorporates the current user identifier to prevent permission conflicts between different system users. According to the source code in `swarmforge/scripts/swarmforge.bb`, the implementation defines the socket directory as follows:

```clojure
(def tmux-socket-dir (fs/path "/tmp"
                      (str "swarmforge-" (or (System/getenv "UID")
                                             (System/getProperty "user.name")))))

```

This definition appears at lines 464-465, ensuring that socket files are namespaced by username or UID before any project-specific identifiers are applied.

### Unique Socket File Generation

Inside the temporary directory, SwarmForge generates a socket file with a random identifier to distinguish between different instances of the same project. Lines 465-466 in `swarmforge.bb` construct the absolute socket path:

```clojure
(def tmux-socket (str (fs/path tmux-socket-dir (str socket-id ".sock"))))

```

The `socket-id` variable ensures that even if multiple SwarmForge processes run concurrently for the same project, each maintains its own distinct communication endpoint with the tmux server.

### Persisting Socket Paths for Child Processes

To maintain isolation across process boundaries, SwarmForge writes the socket path to a state file within the project directory. At lines 246-247, the application persists the configuration:

```clojure
(spit (str (:tmux-socket-file ctx)) (str (:tmux-socket ctx) "\n"))

```

This writes to `.swarmforge/tmux-socket`, allowing child processes and terminal adapters to locate the correct socket without inheriting environment variables directly.

## Enforcing Isolation Through Socket Binding

Every tmux operation executed by SwarmForge explicitly targets the project-specific socket, bypassing the default tmux server socket entirely.

### The -S Flag Implementation

All tmux commands invoked by SwarmForge use the `-S` flag to specify the custom socket path. Lines 297-304 in `swarmforge.bb` demonstrate this pattern across session creation and management operations. For example, creating a new detached session requires:

```bash
tmux -S $TMUX_SOCKET new-session -d -s swarmforge-coder

```

The Clojure implementation wraps this in the `start-agent-session` function:

```clojure
(defn start-agent-session [ctx session-name]
  (sh "tmux" "-S" (:tmux-socket ctx)
      "new-session" "-d" "-s" session-name "sleep" "120"))

```

This ensures that windows, panes, and sessions exist only within the isolated server instance.

### Window and Pane Index Management

To maintain consistent numbering independent of other tmux servers, SwarmForge probes the isolated socket for index configuration immediately after creation. Lines 88-97 query the `base-index` and `pane-base-index` values:

```clojure
;; Context initialization queries the isolated server
(let [base-idx (tmux-get-option tmux-socket "base-index")
      pane-base-idx (tmux-get-option tmux-socket "pane-base-index")]
  ...)

```

This discovery step prevents indexing conflicts when multiple SwarmForge instances run simultaneously on the same host.

## Session Lifecycle and Cleanup

SwarmForge implements targeted cleanup that affects only the resources associated with the current project's socket.

### Targeted Session Termination

When shutting down, SwarmForge kills only sessions belonging to its specific socket rather than terminating all tmux processes system-wide. Lines 520-525 implement this selective cleanup:

```clojure
(defn kill-session! [tmux-socket session]
  (process/sh {:continue true}
               "tmux" "-S" tmux-socket "kill-session" "-t" session))

```

This approach ensures that developers running personal tmux sessions or other SwarmForge projects remain unaffected by a single project's termination.

## Working with Isolated Sessions

Developers can interact with SwarmForge's isolated tmux environment manually by referencing the socket file written to the project state.

To attach to a running SwarmForge session from an external terminal:

```bash

# Retrieve the socket path from the project state

$ TMUX_SOCKET=$(cat .swarmforge/tmux-socket)

# Attach to the specific isolated session

$ tmux -S "$TMUX_SOCKET" attach-session -t swarmforge-coder

```

The socket path follows the pattern `/tmp/swarmforge-<username>/<socket-id>.sock`, allowing direct tmux interaction while maintaining complete separation from other projects.

## Summary

- **SwarmForge creates unique socket directories** under `/tmp` namespaced by user ID to prevent cross-user conflicts.
- **Random socket identifiers** ensure that concurrent instances of the same project operate on separate tmux servers.
- **All tmux commands use the `-S` flag** to bind operations to the project-specific socket defined in `swarmforge/scripts/swarmforge.bb`.
- **Socket paths are persisted** to `.swarmforge/tmux-socket` for child process discovery and manual attachment.
- **Cleanup targets specific sockets only**, leaving other tmux servers and SwarmForge instances unaffected.

## Frequently Asked Questions

### How does SwarmForge prevent tmux session collisions between different projects?

SwarmForge prevents collisions by generating a unique Unix socket file for every project instance and executing all tmux commands with the `-S` flag pointing to that specific socket. This creates separate tmux server processes rather than using the default system socket, ensuring that session names, window indexes, and pane configurations remain isolated per project.

### Where does SwarmForge store the tmux socket file path?

SwarmForge writes the absolute socket path to `.swarmforge/tmux-socket` within the project root directory at lines 246-247 of `swarmforge/scripts/swarmforge.bb`. This state file allows both the orchestration logic and terminal adapter scripts to locate the correct socket for session attachment without relying on environment variables.

### Can I manually attach to a SwarmForge tmux session while it is running?

Yes, you can manually attach by reading the socket path from the project state file and using the `-S` flag. Execute `TMUX_SOCKET=$(cat .swarmforge/tmux-socket)` followed by `tmux -S "$TMUX_SOCKET" attach-session -t <session-name>` to connect to the isolated environment without disrupting the orchestration.

### Does stopping one SwarmForge project affect tmux sessions in other projects?

No, SwarmForge implements targeted cleanup that only kills sessions belonging to the specific socket associated with that project instance. The `kill-session!` function in `swarmforge.bb` (lines 520-525) explicitly passes the socket path to the tmux command, ensuring that other SwarmForge instances and standalone tmux servers remain operational.