Setup
How I run multiple Claude Code sessions in parallel with tmux, plus dotfiles and phone access.
Terminal
.zshrc below auto-skips tmux inside VS Code terminals to prevent this.
My setup uses tmux in iTerm2. The shell auto-attaches on launch, and I spawn Claude Code panes with a one-line script.
tmux config highlights
- Mouse enabled (scroll, click, resize)
- Scrollback buffer: 50,000 lines
- True color support (
tmux-256color) - Pane border titles showing pane name
aggressive-resizeso multiple clients can have different window sizes- Plugins via tpm: tmux-claude-code (session management), resurrect + continuum (auto-save every 15 min, but auto-restore disabled — it caused pane explosions with grouped sessions. Manual restore via prefix+Ctrl-r)
tmux-claude-code plugin
A TPM plugin for managing Claude Code sessions. Searches past conversations by keyword, resumes them in the correct working directory, and shows active session count in the status bar.
- prefix+c — new Claude Code pane
- prefix+C — new named pane
- prefix+Ctrl-r — resume session by keyword search
- prefix+Ctrl-b — browse all sessions with fzf
cc list— list recent sessions with active/inactive statuscc detect— show which panes are running CC
The keyword search is the key feature: it greps the first few user messages of every session transcript (~/.claude/projects/*/*.jsonl), excludes active sessions, decodes the project directory, and opens claude --resume in the right place. Smart pane detection uses child process checks and content markers to reliably identify CC panes even when they report zsh as their command.
Auto-attach on shell start
This block in .zshrc ensures every terminal session lands inside tmux — but skips VS Code terminals (which have their own Claude Code panel). SSH connections create a grouped session so phone and laptop share windows but can view them independently.
# Skip auto-attach in VS Code terminals (use VS Code's Claude Code panel instead)
if [[ -z "$TMUX" && -z "$VSCODE_INJECTION" ]]; then
if [[ -n "$SSH_CONNECTION" ]]; then
# Skip during tmux-resurrect restore to prevent pane explosion
if [[ -z "$(tmux show-environment -g TMUX_RESTORING 2>/dev/null | grep -v '^-')" ]]; then
tmux new-session -A -t c -s "remote-$$" \; new-window -n remote 'claude; exec zsh' 2>/dev/null || tmux new -s c 'claude; exec zsh'
fi
else
tmux attach -t c 2>/dev/null || tmux new -s c 'claude; exec zsh'
fi
fi Navigation cheatsheet
| Action | Key |
|---|---|
| New Claude Code pane | prefix+c |
| New named CC pane | prefix+C |
| Resume CC session by keyword | prefix+Ctrl-r |
| Browse CC sessions (fzf) | prefix+Ctrl-b |
| Grid view (re-tile) | prefix+g |
| Zoom pane fullscreen | prefix+z |
| Return to grid | prefix+z again |
| Jump to pane by number | prefix+q then number |
| Next pane (stays zoomed) | prefix+n |
| Previous pane (stays zoomed) | prefix+p |
| Next pane (unzooms) | prefix+o |
| Move pane to own window | prefix+! |
| Kill pane | prefix+x then y |
Window organization
I group tmux windows by domain so prefix+0 through prefix+3 maps to a mental context switch, not a hunt through panes:
| Key | Window | What lives here |
|---|---|---|
| 0 | meta | Single pane running Claude Code as a "control plane" — reorganizes windows, kills dead panes, checks on other sessions |
| 1 | policyengine | All PolicyEngine work: microsimulation, emails, deployment, data pipelines |
| 2 | other | Rules Foundation, Cosilico, Eggnest, outreach, decks |
| 3 | personal | Side projects, personal errands, life stuff |
Each window has 5–8 panes in a tiled layout. I zoom into one pane with prefix+z to focus, then prefix+n/prefix+p to cycle through panes while staying zoomed. The meta pane at prefix+0 is a persistent Claude Code session that can inspect and reorganize everything else — moving panes between windows with join-pane, killing idle shells, or checking what a session was working on by reading its transcript.
Claude Code
Configuration lives in a dedicated repo: MaxGhenis/.claude
Key settings
- Remote Control: enabled for all sessions — every session is automatically accessible from claude.ai/code and the Claude mobile app. Start a standalone remote session with
claude remote-control, or type/rcinside an existing session. - teammateMode:
in-process - Bypass permissions: enabled for trusted repos
- Hooks:
enforce-package-managers— blocks wrong package managers per projectbounce-plan-gpt— automatically bounces implementation plans off GPT before exiting plan mode (max 2 rounds)auto-commit-wip— commits work-in-progress on session endwarn-uncommitted— alerts on large uncommitted diffssync-setup-page— reminds Claude to update this page after dotfiles/config commits
Skills
13 on-demand skills that load based on conversation context (not preloaded). Examples: Whoop health data, Xero UK accounting, App Store Connect, GCP billing, OpenCollective expenses, Modal/Vercel deployment, OpenMessage patterns, agent teams, Slack patterns, Cloudflare domains.
Commands
12 slash commands including /briefing (daily summary), /search-everything (cross-platform search), /expense (OpenCollective filing), /config-tidy (audit and reorganize config layers), and more.
Plugins
- max-productivity (local) — custom commands + all 13 skills
- policyengine-claude — PolicyEngine design system and patterns
- rules-foundation — tax/benefit rules engine conventions
- frontend-design — production-grade UI generation
- plugin-dev — Claude Code plugin development
Dotfiles
Tracked in a separate repo: MaxGhenis/dotfiles
Contains .tmux.conf and .zshrc. Kept separate from .claude because these files also include non-Claude config (conda, NVM, Julia, PATH, etc.).
Home directory files are symlinks to the repo, so edits are always in sync:
~/.zshrc → ~/dotfiles/.zshrc ~/.tmux.conf → ~/dotfiles/.tmux.conf ~/bin/cc → ~/tmux-claude-code/cc
Phone access
The simplest way: Remote Control. Every local session is automatically available at claude.ai/code and the Claude mobile app (iOS / Android) with no SSH or VPN.
For direct terminal access from a phone (e.g. to run shell commands), I also have:
- Grouped sessions: SSH creates a linked tmux session that shares windows but has its own independent view (cursor position, active pane)
- Tailscale: mesh VPN for networking between devices without port forwarding
- Termux on Android: full Linux environment for SSH access from a phone
aggressive-resize: set in.tmux.confso phone and laptop can have different window sizes simultaneously