> your AI agent picks dependencies from memory; give it dated facts — try starlog.dev ↗ vet your agent's deps ↗ vibe-coding is fine. vibe-importing isn’t. — try starlog.dev ↗ vibe-importing isn’t fine ↗ your agent has never seen your private packages — try starlog.dev ↗ facts for private packages ↗ a linter for the dependencies your AI agent picks — try starlog.dev ↗ a linter for agent deps ↗

Back to Articles

Claude Squad: Git Worktrees Meet AI Agent Orchestration

[ View on GitHub ]

Claude Squad: Git Worktrees Meet AI Agent Orchestration

Hook

Most AI agent tools force you to run one assistant at a time or risk chaotic merge conflicts. Claude Squad treats git worktrees as the missing primitive for true parallelism, letting you run Claude, Aider, and Codex simultaneously on isolated branches of the same repository.

Context

The explosion of AI coding assistants—Claude Code, Aider, Codex, OpenCode—created a new workflow problem that traditional developer tools weren't designed to solve. Developers want to parallelize feature work by delegating separate tasks to different agents, but AI assistants expect exclusive control of a working directory. Run two agents pointed at the same codebase and you'll immediately hit file conflicts as both try to modify files simultaneously. The naive solution is cloning your repository multiple times, but that wastes disk space, creates git history divergence headaches, and makes it unclear which clone has the canonical state.

The more fundamental issue is that terminal multiplexers like tmux and screen were built for managing human interactive sessions, not supervising long-running AI processes that need workspace isolation. You could manually create git worktrees for each agent and spawn tmux sessions with careful naming conventions, but that's tedious busywork that breaks flow when you're trying to context-switch between what Claude is doing on the authentication refactor versus what Aider is handling for the database migration. Claude Squad emerged as purpose-built orchestration layer that binds these primitives—tmux for session management, git worktrees for filesystem isolation, and a TUI for unified status visibility—into a cohesive workflow for developers running multiple AI assistants in parallel.

Technical Insight

Per-Session Isolation

spawn session

poll status

attach/detach

create worktree

read diffs

start in worktree dir

encode metadata in name

isolated workspace

modify files

Bubble Tea TUI

Session Manager

tmux Server

Process Orchestration

Git Worktrees

Branch Isolation

AI Agent CLI

claude/aider/codex

System architecture — auto-generated

Claude Squad's core architectural insight is that it shouldn't reinvent what tmux and git already do well. Rather than implementing process supervision, terminal emulation, or workspace isolation from scratch, it's a 1,500-line Go program that orchestrates existing tools through shell-outs and tmux commands. When you create a new session, the workflow looks like this:

// Simplified from the actual implementation
func createSession(profile Profile, task string) error {
    // Create isolated git worktree on new branch
    branchName := fmt.Sprintf("squad/%s/%d", sanitize(task), time.Now().Unix())
    worktreePath := filepath.Join(".worktrees", branchName)
    exec.Command("git", "worktree", "add", "-b", branchName, worktreePath).Run()
    
    // Build command with auto-accept flag if enabled
    cmd := profile.Command
    if autoYes {
        cmd = fmt.Sprintf("%s %s", cmd, profile.AutoYesFlag)
    }
    
    // Spawn tmux session in the worktree directory
    sessionName := encodeMetadata(task, branchName)
    tmuxCmd := fmt.Sprintf("tmux new-session -d -s '%s' -c '%s' '%s'", 
        sessionName, worktreePath, cmd)
    return exec.Command("sh", "-c", tmuxCmd).Run()
}

The git worktree is the killer feature that makes this architecture work. Unlike separate clones, worktrees share the .git directory and object database but have independent working directories and checked-out branches. This means each AI agent gets true filesystem isolation—Claude can modify auth.go on its branch while Aider refactors database.go on a different branch—without duplicating repository data or creating merge conflicts during active work. The worktree lives in .worktrees/squad-feature-name-timestamp/, keeping everything contained and making cleanup straightforward.

Session metadata encoding is where things get clever and Unix-philosophy fragile. Rather than maintaining a database or state file, Claude Squad encodes task descriptions and branch names directly into tmux session names:

func encodeMetadata(task, branch string) string {
    // Session name format: cs__<base64-task>__<branch>
    encoded := base64.URLEncoding.EncodeToString([]byte(task))
    return fmt.Sprintf("cs__%s__%s", encoded, branch)
}

This makes the Go binary completely stateless from a persistence perspective. When you restart the TUI, it polls tmux list-sessions, parses session names back into task descriptions, and reconstructs state. The trade-off is that session names have length limits (tmux caps at around 200 characters), you can't store complex metadata like timestamps or agent performance metrics, and the parsing is fragile to special characters in task descriptions.

The profile system lives in ~/.config/claude-squad/profiles.json and defines how to spawn different agents:

{
  "profiles": [
    {
      "name": "Claude",
      "command": "claude-code",
      "auto_yes_flag": "--auto-yes"
    },
    {
      "name": "Aider-Sonnet",
      "command": "aider --model claude-3-5-sonnet-20241022",
      "auto_yes_flag": "--yes-always"
    },
    {
      "name": "Local-Ollama",
      "command": "aider --model ollama_chat/qwen2.5-coder:32b",
      "auto_yes_flag": "--yes-always"
    }
  ]
}

This is genuinely agent-agnostic—you're not limited to Claude despite the project name. You can run any CLI tool that supports interactive terminal sessions, which makes this useful beyond just AI coding assistants. I've seen developers use it to manage multiple SSH sessions to different servers or parallel test runs in different environments.

The auto-accept implementation reveals the pragmatic-but-brittle design philosophy. Instead of wrapping stdin/stdout to intercept confirmation prompts, Claude Squad just appends the auto-yes flag to the command string and hopes the underlying tool supports it. There's no verification that --auto-yes actually exists for that CLI tool, no parsing of help text to confirm flag names, no fallback behavior if the flag is ignored. This works reliably for Aider and Claude Code because they have consistent flag interfaces, but breaks silently if you typo the flag name or use a tool that prompts differently.

The TUI is built with Bubble Tea and polls tmux/git on a 500ms interval rather than using filesystem watches or tmux hooks. Every refresh cycle, it shells out to tmux list-sessions for session state, git status --porcelain for file changes in each worktree, and git diff for the diff preview. This polling approach is simple and avoids inotify descriptor limits, but means the UI lags behind actual state by up to half a second and generates unnecessary git subprocess overhead on large repositories.

Gotcha

The hard tmux dependency is non-negotiable and immediately disqualifies this tool for certain environments. Windows developers using WSL need tmux installed and running. Containerized CI environments where you'd want to run multiple test suites in parallel via different agents won't work because tmux sessions don't persist across container restarts. SSH sessions to remote servers require a persistent tmux server process—if the SSH connection drops and kills the tmux server, all session state vanishes. There's no fallback to native process management or session persistence layer beyond what tmux provides.

Git worktree cleanup is manual and error-prone. When you delete a session through the TUI, Claude Squad removes the tmux session and attempts to clean up the worktree, but if the process crashes or you kill sessions directly via tmux kill-session, you're left with orphaned worktrees and branches cluttering .worktrees/ and your branch list. Running git worktree list after a few weeks of use reveals dozens of stale worktrees pointing to directories that no longer exist or branches that were never merged. The tool has a reset command, but it's destructive—it kills all sessions and prunes all worktrees, even ones with uncommitted work you might want to salvage. There's no incremental garbage collection or detection of abandoned sessions that haven't had activity in days.

Verdict

Use if: You already live in tmux, regularly context-switch between multiple features or experiments on the same repository, and find yourself manually creating branches and running AI assistants in separate terminal tabs. The git worktree integration alone saves enough friction to justify the setup, and the unified TUI makes it trivial to see what each agent is working on. Also use if you want to run the same AI coding task with different models in parallel to compare output quality—spinning up Claude, GPT-4, and a local Ollama model on isolated branches of the same test case is genuinely useful for evaluation workflows. Skip if: You don't use tmux daily (the dependency is absolute), work in massive monorepos where git worktrees perform poorly due to checkout times, or need robust session recovery across system reboots. Also skip if you're looking for multi-agent collaboration on a single task—this tool provides parallel isolation, not coordination. Agents don't share context or collaborate; they work on completely separate branches that you manually merge later.