Skip to content

Instantly share code, notes, and snippets.

@teradyne
Last active March 28, 2026 03:34
Show Gist options
  • Select an option

  • Save teradyne/b0560fa5f65f74774bea98323e7c360c to your computer and use it in GitHub Desktop.

Select an option

Save teradyne/b0560fa5f65f74774bea98323e7c360c to your computer and use it in GitHub Desktop.
Claude CLI + tmux on WSL2 — Complete Setup Guide (HTML blog post with dark terminal theme, .tmux.conf, keybindings, multi-agent workflows, and launcher scripts)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Claude CLI + tmux on WSL2 — The Complete Setup Guide</title>
<style>
:root {
--bg: #F7F6F2;
--surface: #FFFFFF;
--text: #28251D;
--text-muted: #7A7974;
--teal: #01696F;
--teal-light: #E8F5F6;
--border: #D4D1CA;
--code-bg: #1C1B19;
--code-fg: #CDCCCA;
--comment: #6A9955;
--keyword: #9CDCFE;
--rust: #A84B2F;
--gold: #D19900;
--warn-bg: #FFF3E0;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #171614;
--surface: #1C1B19;
--text: #CDCCCA;
--text-muted: #797876;
--teal: #4F98A3;
--teal-light: #0A3A3E;
--border: #393836;
--rust: #D4734E;
--gold: #E8AF34;
--warn-bg: #2A2012;
}
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.7;
font-size: 16px;
}
.container {
max-width: 780px;
margin: 0 auto;
padding: 0 24px;
}
/* ── Hero ──────────────────────────────────── */
.hero {
background: var(--code-bg);
padding: 80px 0 60px;
margin-bottom: 48px;
}
.hero .container { position: relative; }
.hero h1 {
font-family: 'DM Sans', 'Inter', sans-serif;
font-size: 2.6rem;
font-weight: 700;
color: #FFFFFF;
line-height: 1.2;
margin-bottom: 8px;
}
.hero .subtitle {
font-size: 1.2rem;
color: #A0D8DD;
margin-bottom: 12px;
}
.hero .meta {
font-size: 0.85rem;
color: #5A5957;
}
.terminal-preview {
background: #141312;
border-radius: 8px;
padding: 16px 20px;
margin-bottom: 32px;
font-family: 'JetBrains Mono', 'Fira Code', monospace;
font-size: 0.85rem;
line-height: 1.6;
overflow-x: auto;
}
.terminal-preview .dots {
display: flex;
gap: 8px;
margin-bottom: 12px;
}
.terminal-preview .dots span {
width: 10px; height: 10px;
border-radius: 50%;
display: inline-block;
}
.terminal-preview .dot-red { background: #FF5F56; }
.terminal-preview .dot-yellow { background: #FFBD2E; }
.terminal-preview .dot-green { background: #27C93F; }
/* ── Typography ────────────────────────────── */
h2 {
font-family: 'DM Sans', 'Inter', sans-serif;
font-size: 1.7rem;
color: var(--teal);
margin: 56px 0 16px;
padding-top: 24px;
border-top: 1px solid var(--border);
}
h2:first-of-type { border-top: none; margin-top: 0; }
h3 {
font-family: 'DM Sans', 'Inter', sans-serif;
font-size: 1.15rem;
color: var(--text);
margin: 32px 0 10px;
}
p { margin-bottom: 14px; }
ul, ol {
margin: 0 0 16px 24px;
}
li { margin-bottom: 6px; }
strong { font-weight: 600; }
a { color: var(--teal); text-decoration: none; }
a:hover { text-decoration: underline; }
/* ── Code blocks ───────────────────────────── */
pre {
background: var(--code-bg);
color: var(--code-fg);
border-radius: 8px;
padding: 20px;
margin: 16px 0 20px;
overflow-x: auto;
font-family: 'JetBrains Mono', 'Fira Code', monospace;
font-size: 0.82rem;
line-height: 1.65;
}
pre .title-bar {
display: block;
background: #2A2927;
margin: -20px -20px 14px;
padding: 8px 16px;
border-radius: 8px 8px 0 0;
color: #8A8985;
font-size: 0.78rem;
}
code {
font-family: 'JetBrains Mono', 'Fira Code', monospace;
font-size: 0.88em;
}
p code, li code {
background: var(--teal-light);
padding: 2px 6px;
border-radius: 4px;
font-size: 0.84em;
}
.cm { color: #6A9955; } /* comment */
.kw { color: #9CDCFE; } /* keyword/command */
.st { color: #CE9178; } /* string */
.tl { color: #4F98A3; } /* teal highlight */
/* ── Tables ─────────────────────────────────── */
table {
width: 100%;
border-collapse: collapse;
margin: 16px 0 24px;
font-size: 0.92rem;
}
th {
background: var(--teal);
color: #FFFFFF;
text-align: left;
padding: 10px 14px;
font-weight: 600;
}
th:first-child { border-radius: 6px 0 0 0; }
th:last-child { border-radius: 0 6px 0 0; }
td {
padding: 10px 14px;
border-bottom: 1px solid var(--border);
}
tr:nth-child(even) td { background: var(--surface); }
td code {
color: var(--teal);
background: none;
padding: 0;
font-weight: 500;
}
/* ── Callout boxes ──────────────────────────── */
.tip, .warn {
border-left: 3px solid var(--teal);
background: var(--teal-light);
padding: 14px 18px;
border-radius: 0 6px 6px 0;
margin: 16px 0 20px;
font-size: 0.92rem;
}
.tip strong { color: var(--teal); }
.warn {
border-left-color: var(--gold);
background: var(--warn-bg);
}
.warn strong { color: var(--gold); }
/* ── Layout diagrams ────────────────────────── */
.layout {
background: var(--code-bg);
color: var(--code-fg);
border-radius: 8px;
padding: 20px;
margin: 16px 0 20px;
font-family: 'JetBrains Mono', 'Fira Code', monospace;
font-size: 0.82rem;
line-height: 1.5;
white-space: pre;
overflow-x: auto;
}
/* ── TOC ─────────────────────────────────────── */
.toc {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 24px 28px;
margin-bottom: 40px;
}
.toc h2 {
font-size: 1.1rem;
margin: 0 0 12px;
padding: 0;
border: none;
color: var(--text);
}
.toc ol {
margin: 0;
padding-left: 20px;
}
.toc li {
margin-bottom: 4px;
font-size: 0.95rem;
}
/* ── Footer ──────────────────────────────────── */
footer {
margin-top: 64px;
padding: 32px 0;
border-top: 1px solid var(--border);
color: var(--text-muted);
font-size: 0.85rem;
text-align: center;
}
/* ── Issue titles ─────────────────────────────── */
.issue-title {
color: var(--rust);
font-weight: 600;
margin: 20px 0 4px;
}
</style>
</head>
<body>
<!-- ════════════════ HERO ════════════════ -->
<header class="hero">
<div class="container">
<div class="terminal-preview">
<div class="dots">
<span class="dot-red"></span>
<span class="dot-yellow"></span>
<span class="dot-green"></span>
</div>
<span class="kw">$</span> tmux new -s claude-project<br>
<span class="tl">$</span> claude<br>
<span class="cm">Claude CLI v1.x connected</span><br><br>
<span class="cm"># Split panes: Ctrl-a | and Ctrl-a -</span><br>
<span class="cm"># Navigate: Alt+Arrow keys</span><br>
<span class="kw">$</span> claude --resume
</div>
<h1>Claude CLI + tmux on WSL2</h1>
<p class="subtitle">The complete setup guide</p>
<p class="meta">March 2026 &middot; Installation, configuration, keybindings, and multi-agent workflows</p>
</div>
</header>
<main class="container">
<!-- ════════════════ TOC ════════════════ -->
<nav class="toc">
<h2>Contents</h2>
<ol>
<li><a href="#prerequisites">Prerequisites and Environment Setup</a></li>
<li><a href="#install-claude">Installing Claude CLI on WSL2</a></li>
<li><a href="#tmux-setup">tmux Installation and Configuration</a></li>
<li><a href="#tmux-conf">Complete .tmux.conf Reference</a></li>
<li><a href="#keybindings">Keybinding Quick Reference</a></li>
<li><a href="#workflows">Multi-Claude Workflows</a></li>
<li><a href="#scripts">Launcher Scripts</a></li>
<li><a href="#windows-terminal">Windows Terminal Integration</a></li>
<li><a href="#troubleshooting">Tips and Troubleshooting</a></li>
</ol>
</nav>
<!-- ═══════ 1. Prerequisites ═══════ -->
<h2 id="prerequisites">1. Prerequisites and Environment Setup</h2>
<p>Before configuring Claude CLI with tmux, ensure your WSL2 environment is properly set up. This guide assumes Windows 11 with WSL2 (Ubuntu 22.04+) and Windows Terminal.</p>
<h3>System requirements</h3>
<ul>
<li>Windows 11 (build 22000+) with WSL2 enabled</li>
<li>Ubuntu 22.04 or 24.04 LTS on WSL2</li>
<li>Windows Terminal (recommended frontend)</li>
<li>Node.js 18+ (for Claude CLI)</li>
<li>A valid Anthropic API key or Claude Max subscription</li>
</ul>
<h3>Verify WSL2</h3>
<pre><span class="title-bar">PowerShell</span><span class="cm"># From PowerShell — confirm WSL version</span>
<span class="kw">wsl</span> --list --verbose
<span class="cm"># Expected output:</span>
<span class="cm"># NAME STATE VERSION</span>
<span class="cm"># Ubuntu Running 2</span></pre>
<h3>Update your Ubuntu packages</h3>
<pre><span class="title-bar">bash</span><span class="kw">sudo</span> apt update && <span class="kw">sudo</span> apt upgrade -y
<span class="kw">sudo</span> apt install -y build-essential git curl wget</pre>
<h3>Install Node.js via nvm</h3>
<p>nvm gives you flexible Node.js version management. Claude CLI requires Node.js 18 or later.</p>
<pre><span class="title-bar">bash</span><span class="cm"># Install nvm</span>
<span class="kw">curl</span> -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
<span class="cm"># Reload shell, then install Node</span>
<span class="kw">source</span> ~/.bashrc
nvm install --lts
nvm use --lts
node --version <span class="cm"># should show v20.x or v22.x</span></pre>
<div class="tip">
<strong>Tip:</strong> Keep all project files on the WSL filesystem (<code>~/projects/</code>), not on <code>/mnt/c/</code>. The Linux filesystem is dramatically faster for I/O-heavy tools like Claude CLI and git.
</div>
<!-- ═══════ 2. Installing Claude CLI ═══════ -->
<h2 id="install-claude">2. Installing Claude CLI on WSL2</h2>
<p>Claude CLI (also known as Claude Code) is Anthropic's terminal-based AI coding assistant. It runs natively in your shell and integrates with your project context.</p>
<h3>Install globally via npm</h3>
<pre><span class="title-bar">bash</span><span class="kw">npm</span> install -g @anthropic-ai/claude-code
<span class="cm"># Verify installation</span>
claude --version</pre>
<h3>Authenticate</h3>
<pre><span class="title-bar">bash</span><span class="cm"># Launch Claude — it will prompt for authentication</span>
claude
<span class="cm"># Or set your API key directly</span>
<span class="kw">export</span> ANTHROPIC_API_KEY=sk-ant-xxxxx
<span class="cm"># Add to ~/.bashrc for persistence</span>
<span class="kw">echo</span> <span class="st">'export ANTHROPIC_API_KEY=sk-ant-xxxxx'</span> >> ~/.bashrc</pre>
<h3>Key CLI flags</h3>
<table>
<thead>
<tr><th>Flag</th><th>Description</th></tr>
</thead>
<tbody>
<tr><td><code>claude</code></td><td>Start interactive REPL in current directory</td></tr>
<tr><td><code>claude "prompt"</code></td><td>Run a one-shot command and exit</td></tr>
<tr><td><code>claude --resume</code></td><td>Resume the most recent conversation</td></tr>
<tr><td><code>claude --continue</code></td><td>Continue the last conversation in the current directory</td></tr>
<tr><td><code>claude -p "prompt"</code></td><td>Print-mode: output to stdout (great for piping)</td></tr>
<tr><td><code>claude config</code></td><td>Open configuration settings</td></tr>
</tbody>
</table>
<div class="warn">
<strong>Note:</strong> Claude CLI reads project context from your working directory. Always <code>cd</code> into your project root before launching. It respects <code>.gitignore</code> and reads <code>CLAUDE.md</code> for project instructions.
</div>
<!-- ═══════ 3. tmux Installation ═══════ -->
<h2 id="tmux-setup">3. tmux Installation and Configuration</h2>
<p>tmux is a terminal multiplexer that lets you manage multiple shell sessions from a single window. It is the backbone of an efficient Claude CLI workflow, enabling you to run multiple Claude instances, keep sessions alive across disconnects, and organize your workspace.</p>
<h3>Core concepts</h3>
<ul>
<li><strong>Session</strong> — A named group of work (e.g., <code>claude-api</code>). Persists even if your terminal closes.</li>
<li><strong>Window</strong> — A tab inside a session. Switch between windows like browser tabs.</li>
<li><strong>Pane</strong> — A split inside a window. Run Claude in one pane, your shell in another.</li>
</ul>
<h3>Install tmux</h3>
<pre><span class="title-bar">bash</span><span class="kw">sudo</span> apt install -y tmux
tmux -V <span class="cm"># should show tmux 3.x</span></pre>
<h3>Basic tmux session management</h3>
<pre><span class="title-bar">bash</span><span class="cm"># Start a named session</span>
tmux new -s myproject
<span class="cm"># Detach from session (keeps it running)</span>
<span class="cm"># Press: Ctrl-a d</span>
<span class="cm"># List sessions</span>
tmux ls
<span class="cm"># Reattach to session</span>
tmux attach -t myproject
<span class="cm"># Kill a session</span>
tmux kill-session -t myproject</pre>
<div class="tip">
<strong>Tip:</strong> Add <code>tmux attach || tmux</code> to the end of your <code>~/.bashrc</code> to automatically rejoin your last session whenever you open a WSL terminal. Sessions survive window closes.
</div>
<!-- ═══════ 4. .tmux.conf ═══════ -->
<h2 id="tmux-conf">4. Complete .tmux.conf Reference</h2>
<p>Save this configuration to <code>~/.tmux.conf</code>. It is tuned for WSL2 + Windows Terminal with mouse support, intuitive splits, and a clean status bar.</p>
<pre><span class="title-bar">~/.tmux.conf</span><span class="cm"># ─────────────────────────────────────────────</span>
<span class="cm"># Prefix: Ctrl-a (easier than default Ctrl-b)</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="kw">unbind</span> C-b
<span class="kw">set</span> -g prefix C-a
<span class="kw">bind</span> C-a send-prefix
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="cm"># General Settings</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="kw">set</span> -g base-index 1 <span class="cm"># windows start at 1</span>
<span class="kw">setw</span> -g pane-base-index 1 <span class="cm"># panes start at 1</span>
<span class="kw">set</span> -g mouse on <span class="cm"># full mouse support</span>
<span class="kw">set</span> -g history-limit 50000 <span class="cm"># generous scrollback</span>
<span class="kw">set</span> -g escape-time 0 <span class="cm"># no delay after Esc</span>
<span class="kw">set</span> -g focus-events on <span class="cm"># for vim/editor focus</span>
<span class="kw">set</span> -g default-terminal <span class="st">"tmux-256color"</span>
<span class="kw">set</span> -ag terminal-overrides <span class="st">",xterm-256color:RGB"</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="cm"># Splits — intuitive keys</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="kw">unbind</span> '"'
<span class="kw">unbind</span> %
<span class="kw">bind</span> | split-window -h -c <span class="st">"#{pane_current_path}"</span>
<span class="kw">bind</span> - split-window -v -c <span class="st">"#{pane_current_path}"</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="cm"># Pane Navigation — Alt+Arrow (no prefix)</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="kw">bind</span> -n M-Left select-pane -L
<span class="kw">bind</span> -n M-Right select-pane -R
<span class="kw">bind</span> -n M-Up select-pane -U
<span class="kw">bind</span> -n M-Down select-pane -D
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="cm"># Pane Resizing — Ctrl+Arrow (no prefix)</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="kw">bind</span> -n C-Left resize-pane -L 3
<span class="kw">bind</span> -n C-Right resize-pane -R 3
<span class="kw">bind</span> -n C-Up resize-pane -U 2
<span class="kw">bind</span> -n C-Down resize-pane -D 2
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="cm"># Close panes and windows</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="kw">bind</span> x kill-pane <span class="cm"># close current pane</span>
<span class="kw">bind</span> X kill-window <span class="cm"># close current window</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="cm"># Copy mode (vi style)</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="kw">setw</span> -g mode-keys vi
<span class="kw">bind</span> -T copy-mode-vi v send -X begin-selection
<span class="kw">bind</span> -T copy-mode-vi y send -X copy-pipe-and-cancel \
<span class="st">"clip.exe"</span> <span class="cm"># copies to Windows clipboard</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="cm"># Status Bar</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="kw">set</span> -g status-position bottom
<span class="kw">set</span> -g status-style bg=#1C1B19,fg=#8A8985
<span class="kw">set</span> -g status-left-length 40
<span class="kw">set</span> -g status-right-length 80
<span class="kw">set</span> -g status-left \
<span class="st">'#[fg=#01696F,bold] #S #[default]| '</span>
<span class="kw">set</span> -g status-right \
<span class="st">'#[fg=#6A9955]%Y-%m-%d #[fg=#D19900]%H:%M '</span>
<span class="kw">setw</span> -g window-status-format \
<span class="st">' #I:#W '</span>
<span class="kw">setw</span> -g window-status-current-format \
<span class="st">'#[fg=#01696F,bold][#I:#W]#[default]'</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="cm"># Reload config with Ctrl-a r</span>
<span class="cm"># ─────────────────────────────────────────────</span>
<span class="kw">bind</span> r source-file ~/.tmux.conf \; display <span class="st">"Reloaded"</span></pre>
<h3>Apply the configuration</h3>
<pre><span class="title-bar">bash</span><span class="cm"># If tmux is already running, reload from inside tmux:</span>
<span class="cm"># Press Ctrl-a r</span>
<span class="cm"># Or from any shell:</span>
tmux source-file ~/.tmux.conf
<span class="cm"># Or kill and restart fresh:</span>
tmux kill-server && tmux</pre>
<!-- ═══════ 5. Keybindings ═══════ -->
<h2 id="keybindings">5. Keybinding Quick Reference</h2>
<p>All bindings use <code>Ctrl-a</code> as the prefix (configured in Section 4). Bindings marked "no prefix" work without pressing Ctrl-a first.</p>
<h3>Session management</h3>
<table>
<thead><tr><th>Keybinding</th><th>Action</th></tr></thead>
<tbody>
<tr><td><code>Ctrl-a d</code></td><td>Detach from session (session stays alive)</td></tr>
<tr><td><code>Ctrl-a s</code></td><td>List and switch sessions</td></tr>
<tr><td><code>Ctrl-a $</code></td><td>Rename current session</td></tr>
</tbody>
</table>
<h3>Windows (tabs)</h3>
<table>
<thead><tr><th>Keybinding</th><th>Action</th></tr></thead>
<tbody>
<tr><td><code>Ctrl-a c</code></td><td>Create new window</td></tr>
<tr><td><code>Ctrl-a ,</code></td><td>Rename current window</td></tr>
<tr><td><code>Ctrl-a n / p</code></td><td>Next / previous window</td></tr>
<tr><td><code>Ctrl-a [0-9]</code></td><td>Jump to window by number</td></tr>
<tr><td><code>Ctrl-a X</code></td><td>Kill current window</td></tr>
</tbody>
</table>
<h3>Panes (splits)</h3>
<table>
<thead><tr><th>Keybinding</th><th>Action</th></tr></thead>
<tbody>
<tr><td><code>Ctrl-a |</code></td><td>Split vertically (left / right)</td></tr>
<tr><td><code>Ctrl-a -</code></td><td>Split horizontally (top / bottom)</td></tr>
<tr><td><code>Alt + Arrow</code></td><td>Navigate panes (no prefix needed)</td></tr>
<tr><td><code>Ctrl + Arrow</code></td><td>Resize panes (no prefix needed)</td></tr>
<tr><td><code>Ctrl-a x</code></td><td>Kill current pane</td></tr>
<tr><td><code>Ctrl-a z</code></td><td>Toggle pane zoom (fullscreen)</td></tr>
<tr><td><code>Ctrl-a Space</code></td><td>Cycle through pane layouts</td></tr>
</tbody>
</table>
<h3>Copy mode and scrollback</h3>
<table>
<thead><tr><th>Keybinding</th><th>Action</th></tr></thead>
<tbody>
<tr><td><code>Ctrl-a [</code></td><td>Enter copy mode (scroll with arrows/PgUp)</td></tr>
<tr><td><code>v</code> (in copy mode)</td><td>Start selection</td></tr>
<tr><td><code>y</code> (in copy mode)</td><td>Copy to Windows clipboard</td></tr>
<tr><td><code>q</code></td><td>Exit copy mode</td></tr>
<tr><td><code>Ctrl-a r</code></td><td>Reload tmux.conf</td></tr>
</tbody>
</table>
<div class="tip">
<strong>Tip:</strong> Mouse scroll automatically enters copy mode. You can also click to select panes and drag pane borders to resize — the mouse config handles all of this.
</div>
<!-- ═══════ 6. Multi-Claude Workflows ═══════ -->
<h2 id="workflows">6. Multi-Claude Workflows</h2>
<p>The real power of tmux with Claude CLI is running multiple Claude instances simultaneously. Below are battle-tested workflow patterns.</p>
<h3>Pattern 1: Side-by-side (Claude + Shell)</h3>
<p>The most common layout. Claude on the left, your shell on the right for running tests, checking git status, or reviewing files.</p>
<div class="layout"><span class="cm"># Create session and split</span>
tmux new -s myproject
<span class="cm"># Press Ctrl-a | to split vertically</span>
<span class="cm"># Left pane: run claude</span>
<span class="cm"># Right pane: run tests, git, etc.</span>
┌──────────────┬──────────────┐
│ Claude CLI │ Shell │
│ │ (tests, │
│ (interactive │ git, │
│ session) │ files) │
└──────────────┴──────────────┘</div>
<h3>Pattern 2: Director + Workers</h3>
<p>Use one Claude instance as a coordinator that delegates tasks to other Claude instances. The director pane plans and reviews; worker panes execute focused subtasks.</p>
<div class="layout">┌──────────────┬──────────────┐
│ │ Worker A │
│ Director │ (claude) │
│ (claude) ├──────────────┤
│ │ Worker B │
│ │ (claude) │
└──────────────┴──────────────┘
<span class="cm"># Director plans → you paste tasks into Worker panes</span>
<span class="cm"># Workers execute independently on specific files</span></div>
<h3>Pattern 3: Multi-project sessions</h3>
<p>One tmux session per project. Each session has its own Claude instance with full project context. Switch between projects instantly.</p>
<pre><span class="title-bar">bash</span><span class="cm"># Start sessions for each project</span>
tmux new -d -s api -c ~/projects/api
tmux new -d -s frontend -c ~/projects/frontend
tmux new -d -s etl -c ~/projects/etl
<span class="cm"># Attach to one, then switch:</span>
tmux attach -t api
<span class="cm"># Ctrl-a s → session picker</span>
<span class="cm"># or Ctrl-a ( / ) → prev/next session</span></pre>
<h3>Pattern 4: Review workflow</h3>
<p>Run Claude in one pane to generate code, and a second Claude instance to review what the first produced. This catches bugs and improves quality through adversarial review.</p>
<div class="layout">┌──────────────┬──────────────┐
│ Claude A │ Claude B │
│ (author) │ (reviewer) │
├──────────────┴──────────────┤
│ Shell (bottom) │
│ git diff, tests, etc. │
└─────────────────────────────┘
<span class="cm"># Pane A: claude → writes code</span>
<span class="cm"># Pane B: claude → reviews A's output</span>
<span class="cm"># Bottom: run tests, git diff, verify</span></div>
<div class="warn">
<strong>Performance Note:</strong> Each Claude CLI instance holds its own conversation context. On WSL2 with 16 GB RAM, 2–3 concurrent Claude instances run comfortably. Close idle instances with <code>/exit</code> to free resources.
</div>
<!-- ═══════ 7. Launcher Scripts ═══════ -->
<h2 id="scripts">7. Launcher Scripts</h2>
<p>Automate your Claude + tmux layouts with shell scripts. Save these in <code>~/bin/</code> and make them executable.</p>
<h3>claude-dev: Project launcher</h3>
<p>Launches a named tmux session for the current directory with Claude on the left and a shell on the right.</p>
<pre><span class="title-bar">~/bin/claude-dev</span><span class="cm">#!/usr/bin/env bash</span>
<span class="cm"># ~/bin/claude-dev — launch a Claude+shell layout</span>
SESSION=<span class="st">"claude-$(basename "$PWD")"</span>
if ! tmux has-session -t <span class="st">"$SESSION"</span> 2>/dev/null; then
tmux new-session -d -s <span class="st">"$SESSION"</span> -c <span class="st">"$PWD"</span>
<span class="cm"># Left pane: Claude CLI</span>
tmux send-keys -t <span class="st">"$SESSION"</span> <span class="st">"claude"</span> Enter
<span class="cm"># Right pane: shell</span>
tmux split-window -h -t <span class="st">"$SESSION"</span> -c <span class="st">"$PWD"</span>
<span class="cm"># Focus left pane (Claude)</span>
tmux select-pane -t <span class="st">"$SESSION"</span>:.1
fi
tmux attach -t <span class="st">"$SESSION"</span></pre>
<h3>claude-multi: Multi-agent launcher</h3>
<p>Launches the Director + Workers layout from Pattern 2 with three Claude panes.</p>
<pre><span class="title-bar">~/bin/claude-multi</span><span class="cm">#!/usr/bin/env bash</span>
<span class="cm"># ~/bin/claude-multi — director + 2 worker panes</span>
SESSION=<span class="st">"multi-$(basename "$PWD")"</span>
if ! tmux has-session -t <span class="st">"$SESSION"</span> 2>/dev/null; then
tmux new-session -d -s <span class="st">"$SESSION"</span> -c <span class="st">"$PWD"</span>
<span class="cm"># Left pane (60%): Director Claude</span>
tmux send-keys -t <span class="st">"$SESSION"</span> <span class="st">"claude"</span> Enter
<span class="cm"># Right-top pane: Worker A</span>
tmux split-window -h -p 40 -t <span class="st">"$SESSION"</span> -c <span class="st">"$PWD"</span>
tmux send-keys <span class="st">"claude"</span> Enter
<span class="cm"># Right-bottom pane: Worker B</span>
tmux split-window -v -t <span class="st">"$SESSION"</span> -c <span class="st">"$PWD"</span>
tmux send-keys <span class="st">"claude"</span> Enter
<span class="cm"># Focus director pane</span>
tmux select-pane -t <span class="st">"$SESSION"</span>:.1
fi
tmux attach -t <span class="st">"$SESSION"</span></pre>
<h3>Make scripts executable</h3>
<pre><span class="title-bar">bash</span><span class="kw">mkdir</span> -p ~/bin
<span class="kw">chmod</span> +x ~/bin/claude-dev ~/bin/claude-multi
<span class="cm"># Add ~/bin to PATH (add to ~/.bashrc)</span>
<span class="kw">export</span> PATH=<span class="st">"$HOME/bin:$PATH"</span>
<span class="cm"># Now from any project directory:</span>
cd ~/projects/my-api
claude-dev <span class="cm"># launches Claude + shell layout</span>
claude-multi <span class="cm"># launches director + workers</span></pre>
<!-- ═══════ 8. Windows Terminal ═══════ -->
<h2 id="windows-terminal">8. Windows Terminal Integration</h2>
<p>Configure Windows Terminal to launch directly into your tmux sessions for a seamless experience.</p>
<h3>WSL profile with auto-tmux</h3>
<p>Add this profile to your Windows Terminal <code>settings.json</code>. It launches WSL and auto-attaches to an existing tmux session (or starts a new one).</p>
<pre><span class="title-bar">settings.json (Windows Terminal profile)</span>{
<span class="kw">"name"</span>: <span class="st">"WSL2 + tmux"</span>,
<span class="kw">"source"</span>: <span class="st">"Windows.Terminal.Wsl"</span>,
<span class="kw">"commandline"</span>: <span class="st">"wsl.exe ~ -e bash -lc \"tmux attach || tmux\""</span>,
<span class="kw">"startingDirectory"</span>: <span class="st">"//wsl$/Ubuntu/home/YOUR_USER"</span>,
<span class="kw">"colorScheme"</span>: <span class="st">"One Half Dark"</span>,
<span class="kw">"font"</span>: {
<span class="kw">"face"</span>: <span class="st">"JetBrains Mono"</span>,
<span class="kw">"size"</span>: 11
},
<span class="kw">"padding"</span>: <span class="st">"8"</span>,
<span class="kw">"antialiasingMode"</span>: <span class="st">"cleartype"</span>
}</pre>
<h3>Dedicated Claude launcher profile</h3>
<pre><span class="title-bar">settings.json (Claude launcher profile)</span>{
<span class="kw">"name"</span>: <span class="st">"Claude Dev"</span>,
<span class="kw">"commandline"</span>: <span class="st">"wsl.exe ~ -e bash -lc \"cd ~/projects && claude-dev\""</span>,
<span class="kw">"colorScheme"</span>: <span class="st">"One Half Dark"</span>,
<span class="kw">"font"</span>: {
<span class="kw">"face"</span>: <span class="st">"JetBrains Mono"</span>,
<span class="kw">"size"</span>: 11
}
}</pre>
<div class="tip">
<strong>Tip:</strong> Install JetBrains Mono or your preferred coding font on Windows (not just WSL). Windows Terminal renders fonts from the Windows font directory, even when running WSL sessions.
</div>
<!-- ═══════ 9. Troubleshooting ═══════ -->
<h2 id="troubleshooting">9. Tips and Troubleshooting</h2>
<h3>Essential tips</h3>
<ul>
<li><strong>Use --resume liberally.</strong> If Claude CLI crashes or you accidentally close a pane, <code>claude --resume</code> picks up where you left off.</li>
<li><strong>CLAUDE.md for project context.</strong> Drop a <code>CLAUDE.md</code> in your project root with architecture notes, conventions, and file layout. Claude reads it automatically on startup.</li>
<li><strong>Zoom a pane.</strong> Press <code>Ctrl-a z</code> to fullscreen any pane. Press again to restore. Great for focused Claude work, then zoom out to see your shell.</li>
<li><strong>Session persistence.</strong> tmux sessions survive terminal closes. Close Windows Terminal, reopen it, and <code>tmux attach</code> reconnects you to all running sessions.</li>
<li><strong>Scrollback search.</strong> In copy mode (<code>Ctrl-a [</code>), press <code>/</code> to search backwards through output. Use <code>n</code>/<code>N</code> to jump between matches.</li>
</ul>
<h3>Common issues</h3>
<p class="issue-title">&gt; Alt+Arrow not working in Windows Terminal</p>
<p>Go to Settings &rarr; Actions and remove or rebind any Alt+Arrow keybindings that Windows Terminal claims. tmux needs these to pass through to WSL.</p>
<p class="issue-title">&gt; Mouse scroll not working</p>
<p>Ensure <code>set -g mouse on</code> is in your <code>.tmux.conf</code> and reload with <code>Ctrl-a r</code>. Also check that Windows Terminal isn't intercepting scroll events.</p>
<p class="issue-title">&gt; Copy/paste between tmux and Windows</p>
<p>The <code>y</code> binding in the <code>.tmux.conf</code> pipes selections to <code>clip.exe</code>, which writes to the Windows clipboard. Paste with <code>Ctrl+V</code> in Windows Terminal, or right-click. For pasting into tmux, use <code>Ctrl+Shift+V</code>.</p>
<p class="issue-title">&gt; Claude CLI not found after install</p>
<p>Run <code>source ~/.bashrc</code> or open a new terminal. Verify with <code>which claude</code>. If using nvm, ensure nvm is loaded in your shell profile.</p>
<p class="issue-title">&gt; Slow filesystem on /mnt/c/</p>
<p>WSL2 I/O through <code>/mnt/c/</code> is significantly slower than the native Linux filesystem. Move projects to <code>~/projects/</code> for 5–10x faster git and file operations.</p>
<p class="issue-title">&gt; tmux colors look wrong</p>
<p>Add <code>set -g default-terminal "tmux-256color"</code> to your <code>.tmux.conf</code> and ensure Windows Terminal is using a color scheme that supports 256 colors.</p>
<h3>Quick Command Cheat Sheet</h3>
<pre><span class="title-bar">Cheat Sheet</span><span class="cm"># Daily workflow</span>
cd ~/projects/my-api <span class="cm"># go to project</span>
claude-dev <span class="cm"># launch Claude + shell layout</span>
<span class="cm"># Session management</span>
tmux ls <span class="cm"># list all sessions</span>
tmux attach -t NAME <span class="cm"># reattach to session</span>
tmux kill-session -t X <span class="cm"># clean up old sessions</span>
<span class="cm"># Inside tmux</span>
Ctrl-a | <span class="cm"># split vertical</span>
Ctrl-a - <span class="cm"># split horizontal</span>
Alt+Arrow <span class="cm"># switch panes</span>
Ctrl-a z <span class="cm"># zoom/unzoom pane</span>
Ctrl-a d <span class="cm"># detach (session stays alive)</span>
Ctrl-a r <span class="cm"># reload config</span>
<span class="cm"># Claude CLI</span>
claude <span class="cm"># start interactive session</span>
claude --resume <span class="cm"># resume last conversation</span>
claude --continue <span class="cm"># continue in current dir</span>
claude -p <span class="st">"question"</span> <span class="cm"># one-shot, print to stdout</span></pre>
</main>
<footer>
<div class="container">
March 2026 &middot; Generated with Perplexity Computer
</div>
</footer>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment