psmux_psmux/docs/claude-code.md
Josh 1cde3d15c7 docs: add PowerShell 7+ prerequisites to Claude Code guide
Adds a Prerequisites section documenting the PowerShell 7+ requirement for
Claude Code agent teams. The env shim and teammate mode injection rely on
PowerShell 7+ features not available in legacy Windows PowerShell 5.1.

Credit to @LiamKarlMitchell for contributing this documentation via PR #184
after discovering the version requirement while troubleshooting #173.
2026-04-06 14:56:00 +05:30

9.7 KiB

Claude Code Agent Teams

psmux has first-class support for Claude Code agent teams. When Claude Code runs inside a psmux session, it automatically spawns teammate agents in separate tmux panes instead of running them in-process — giving you full visibility into what each agent is doing.

Prerequisites

PowerShell 7+

Install PowerShell 7 on Windows

To work with Claude Code, psmux requires PowerShell 7 or later. The env shim and teammate mode injection rely on PowerShell 7+ features that are not available in the legacy Windows PowerShell 5.1.

Check your current version:

$PSVersionTable.PSVersion

If you are on an older version, install PowerShell 7+ via winget:

winget install --id Microsoft.PowerShell --source winget

After installation, restart your terminal and verify the version again.

  • pwsh will run the new version
  • powershell will still run the older legacy version as a fallback

You may need to restart VS Code for changes to the default terminal to take effect.

Credit: This prerequisite documentation was contributed by @LiamKarlMitchell in #184 after discovering the PowerShell version requirement while troubleshooting #173.

Quick Start

  1. Install psmux (see README)

  2. Start a psmux session:

    psmux new-session -s work
    
  3. Run Claude Code inside the psmux pane:

    claude
    
  4. Ask Claude to create a team. Claude Code will automatically split panes for each teammate agent.

That's it. No extra configuration needed — psmux handles everything automatically.

How It Works

When a pane spawns inside psmux, several environment variables are set automatically:

Variable Value Purpose
TMUX /tmp/psmux-{pid}/... Tells Claude Code it's inside tmux
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS 1 Enables the agent teams feature gate
PSMUX_CLAUDE_TEAMMATE_MODE tmux Triggers the --teammate-mode tmux CLI injection

Claude Code detects the TMUX environment variable, recognizes it's inside a tmux-compatible multiplexer, and uses the TmuxBackend to spawn teammate agents via split-window and send-keys — the same mechanism it uses on Linux/macOS tmux.

The Two Things psmux Fixes

Claude Code's standalone binary (the Bun SFE claude.exe) has two issues on Windows that psmux works around:

  1. Agent teams feature gate: The entire teammate tool-set (spawnTeam, spawnTeammate) is gated behind CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1. Without this env var, Claude only has the in-process "Agent" tool and never creates separate panes. psmux sets this automatically.

  2. teammateMode config ignored: The standalone binary ignores teammateMode: "tmux" from ~/.claude/settings.json. psmux injects --teammate-mode tmux via a PowerShell wrapper function that's loaded in every pane.

Configuration Options

These options can be set in ~/.psmux.conf or at runtime:

# Auto-inject --teammate-mode tmux for Claude Code (default: on)
set -g claude-code-fix-tty on

# Disable the Claude Code teammate-mode workaround
set -g claude-code-fix-tty off

What each option controls

Option Default Description
claude-code-fix-tty on Sets PSMUX_CLAUDE_TEAMMATE_MODE=tmux and defines a claude wrapper function that injects --teammate-mode tmux into every claude invocation

The CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 env var is always set (not gated by any option) since it's required for the feature to work at all.

Two Agent Systems in Claude Code

Claude Code has two completely separate agent systems. Understanding both is critical because psmux can only control one of them.

1. Teammate Agents (tmux panes) ✅

The teammate system spawns agents in visible tmux panes. This is the system psmux fully supports.

  • Triggered when the model passes team_name + name to the subagent tool
  • Gated by CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 (psmux sets this)
  • Controlled by --teammate-mode tmux (psmux injects this)
  • Each agent gets its own pane with full terminal visibility
  • Lower-tier models (Haiku, Sonnet) tend to prefer this path

2. Worktree Agents (in-process, invisible) ⚠️

The worktree system creates isolated git worktrees and runs agents in-process — invisible to the user.

  • Triggered when the model passes isolation: "worktree" to the subagent tool
  • Creates git worktrees at .claude/worktrees/agent-<id>/ via git worktree add
  • Each agent works on a separate branch in an isolated repo copy
  • Runs entirely in-process (no pane, no terminal output visible)
  • Higher-tier models (Opus) tend to prefer this path for git-level isolation
  • On Windows, worktree tmux integration is hardcoded disabled ("--tmux may not have effect on Windows when model chooses worktrees. Opus tends to always choose that.")
  • There is no env var or setting to force worktree agents into tmux panes

Why Opus says "Let me launch agents in worktrees"

Both systems are exposed through the same subagent tool. The model chooses which to use:

Parameter System Visibility Model preference
team_name + name Teammate Visible tmux pane Haiku, Sonnet
isolation: "worktree" Worktree Invisible in-process Opus

Opus prefers worktree agents because they provide git-level isolation — each agent works on its own branch and can't cause merge conflicts with other agents. The tradeoff is zero visibility.

Workaround: Project Instructions

Since the model decides which system to use, you can influence its choice via CLAUDE.md project instructions:

# Agent Configuration
When spawning subagents, always use the teammate system (team_name + name parameters)
instead of worktree isolation. This ensures agents are visible in tmux panes.
Do NOT use isolation: "worktree" — use teammates instead.

Place this in your project's CLAUDE.md or ~/.claude/CLAUDE.md for global effect. This is a best-effort approach — the model may still choose worktree isolation for complex parallel tasks.

Important: Interactive Mode Required

Agent teams spawn in separate tmux panes only when Claude Code is running interactively (the default when you type claude in a pane). When using -p (pipe/print mode), Claude intentionally runs agents in-process since there's no interactive terminal to split.

# ✅ Interactive — agents spawn in tmux panes
claude

# ❌ Pipe mode — agents run in-process (by design)
claude -p "do something"

Verifying the Setup

To confirm everything is configured correctly inside a psmux pane:

# Check environment variables
Write-Host "TMUX: $env:TMUX"
Write-Host "AGENT_TEAMS: $env:CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS"
Write-Host "TEAMMATE_MODE: $env:PSMUX_CLAUDE_TEAMMATE_MODE"

Expected output:

TMUX: /tmp/psmux-{pid}/default,{port},0
AGENT_TEAMS: 1
TEAMMATE_MODE: tmux

You can also verify the claude wrapper is active:

Get-Command claude | Format-List

If the wrapper is active, this shows a Function (not an Application). The wrapper auto-injects --teammate-mode tmux when calling claude.exe.

Troubleshooting

Agents still running in-process

  1. Check you're in interactive mode — not using -p or --print
  2. Verify env vars — run the verification commands above
  3. Check debug log — start Claude with --debug-file $env:TEMP\claude_debug.log and look for:
    • [TeammateModeSnapshot] Captured from CLI override: tmux — teammate mode is set
    • [BackendRegistry] isInProcessEnabled: false — tmux panes will be used
    • [BackendRegistry] isInProcessEnabled: true (non-interactive session) — you're in pipe mode

Opus using "worktree agents" instead of tmux panes

This is expected behavior. Opus prefers isolation: "worktree" over the teammate system. These are two completely different agent systems — see Two Agent Systems above.

What you'll see: Claude says "Let me launch 3 implementation agents in worktrees" — agents run invisibly, no panes appear.

Workaround: Add a CLAUDE.md instruction telling the model to prefer teammates over worktree isolation. This is best-effort — the model ultimately decides.

Claude command not found

Make sure claude.exe is on your PATH. Install via:

npm install -g @anthropic-ai/claude-code

Wrapper not injecting --teammate-mode

The wrapper is only defined when claude-code-fix-tty is on (default). Check:

tmux show-options -g claude-code-fix-tty

Technical Details

For the curious — here's what happens under the hood when Claude Code spawns a teammate:

  1. Claude calls spawnTeammate tool (available because T8() gate passes due to CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1)
  2. BackendRegistry.detectAndGetBackend() checks isInProcessEnabled:
    • If non-interactive → true → in-process (by design)
    • If interactive → checks teammateMode → "tmux" → false → uses TmuxBackend
  3. TmuxBackend runs tmux split-window via psmux's tmux compatibility
  4. Sends cd <workdir> && claude.exe --agent-id <id> --agent-name <name> ... via tmux send-keys
  5. The teammate agent starts in its own pane with full terminal access