How SwarmForge Achieves tmux Session Isolation Per Project

SwarmForge isolates tmux sessions per project by generating a unique Unix socket file for each project instance and binding every tmux command to that specific socket via the -S flag.

The unclebob/swarm-forge repository orchestrates development environments using tmux for terminal management. To prevent conflicts between concurrent projects, the tool implements strict tmux session isolation per project through socket-based server separation. This architecture ensures that windows, panes, and sessions from one project never interfere with another, even when multiple SwarmForge instances run simultaneously on the same host.

Socket-Based Architecture for Complete Isolation

SwarmForge does not rely on session naming conventions alone; it spawns an entirely separate tmux server process for each project by controlling the socket path.

Per-Project Socket Directory

When SwarmForge initializes, it constructs a temporary directory path that incorporates the user's UID or username to avoid permission conflicts.

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

This directory definition in swarmforge.bb (lines 464–465) ensures that socket files reside in /tmp/swarmforge-<user>/, separating resources by operating system user.

Unique Socket File Generation

Inside this directory, SwarmForge creates a uniquely named socket file using a random identifier (socket-id) generated for each project run.

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

As implemented in swarmforge.bb (lines 465–466), this guarantees that concurrent project instances receive distinct socket files, preventing cross-contamination between tmux servers.

Persisting the Socket Path

To ensure child processes and terminal adapters can locate the correct server, SwarmForge writes the absolute socket path to a state file within the project directory.

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

This operation, found at lines 246–247 in swarmforge.bb, creates .swarmforge/tmux-socket, allowing external scripts to reference the isolated tmux instance without hardcoding paths.

Binding All Operations to the Project Socket

Isolation is enforced at the command level by appending the -S <socket> flag to every tmux invocation.

Command Invocation Pattern

Every tmux operation—from session creation to option queries—targets the specific socket path stored in the context. The tmux-agent-target helper (lines 297–304 in swarmforge.bb) constructs proper target strings for panes and windows, ensuring all references resolve against the private socket.

For example, creating a new session uses:

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

Detecting Base Indexes Independently

SwarmForge probes the isolated socket at startup to discover base-index and pane-base-index values (lines 88–97 in swarmforge.bb). By reading these options from the project-specific server rather than assuming defaults, the tool maintains consistent window and pane numbering that remains independent of any other tmux server running on the host.

Cleanup and Session Termination

When a project closes, SwarmForge terminates only the sessions associated with its specific socket, leaving other tmux servers untouched.

The kill-session! function explicitly references the socket path:

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

As shown in lines 520–525 of swarmforge.bb, this selective termination prevents accidental disruption of unrelated development sessions.

Summary

  • SwarmForge generates a unique Unix socket for each project under /tmp/swarmforge-<user>/<socket-id>.sock.
  • The socket path is persisted to .swarmforge/tmux-socket so child processes can locate the isolated server.
  • Every tmux command uses the -S flag to bind exclusively to the project-specific socket, creating a separate tmux server instance.
  • Base indexes are detected from the isolated socket to ensure consistent numbering across projects.
  • Cleanup operations target only the project's socket, preventing interference with other tmux sessions.

Frequently Asked Questions

Why does SwarmForge use socket files instead of session names for isolation?

Session names alone do not prevent conflicts between tmux servers; different projects could accidentally use identical session names. By generating a unique Unix socket file for each project run, SwarmForge creates an entirely separate tmux server process. This guarantees that commands like tmux new-session or tmux kill-session affect only the intended project, regardless of session naming conventions.

Where does SwarmForge store the tmux socket path for a project?

SwarmForge writes the absolute path to the socket file into .swarmforge/tmux-socket within the project root directory. This occurs at lines 246–247 in swarmforge.bb via the spit function. Terminal adapter scripts read this file to attach to the correct tmux server when opening new terminal windows.

Can multiple SwarmForge projects run simultaneously without conflicts?

Yes. Each project instance generates a unique socket-id and creates its own .sock file in the user's temporary directory. Because every tmux command specifies the socket via the -S flag, multiple isolated tmux servers can coexist on the same host. The cleanup logic at lines 520–525 ensures that terminating one project only kills sessions belonging to its specific socket.

How does SwarmForge handle tmux base-index configurations per project?

At startup, SwarmForge queries the isolated socket to read the base-index and pane-base-index options (lines 88–97 in swarmforge.bb). By inspecting these values directly from the project-specific server, the tool correctly calculates window and pane references without assuming global defaults or conflicting with other running tmux instances.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →