| |
┌──────────────────────────────────┬──────────────────────────────────┐ │ │ │ │ Claude Code (worktree A) │ Claude Code (worktree B) │ │ feature/new-validation │ chore/translations │ │ │ │ │ │ │ ├──────────────────────────────────┴──────────────────────────────────┤ │ │ │ Main repo — tests, builds, git log │ │ │ └─────────────────────────────────────────────────────────────────────┘
Two *splits* on top, each one running an agent in its own *worktree*. One *split* on the bottom running `main`, where I run tests, view diffs, and handle merges once the agents are done.
The *Quick Terminal* (`Ctrl+``) is for tasks that take three seconds: checking the backlog in Linear, viewing deploy status, or running a quick `make validate`.
## How to set this up step by step
### 1. Configure Ghostty for development
Here’s the essentials from my `~/.config/ghostty/config`:
Shell
command = /opt/homebrew/bin/fish shell-integration = fish
Readable font for long sessions
font-family = JetBrainsMono Nerd Font font-size = 15 font-thicken = true
Quick Terminal (dropdown Quake-style)
keybind = global:ctrl+grave_accent=toggle_quick_terminal quick-terminal-position = bottom quick-terminal-animation-duration = 0.15
Splits
keybind = cmd+d=new_split:right keybind = cmd+shift+d=new_split:down keybind = cmd+alt+left=goto_split:left keybind = cmd+alt+right=goto_split:right keybind = cmd+alt+up=goto_split:top keybind = cmd+alt+down=goto_split:down
Zoom split (toggle fullscreen for a panel)
keybind = cmd+shift+enter=toggle_split_zoom
Jump between Claude Code prompts (game changer)
keybind = cmd+up=jump_to_prompt:-1 keybind = cmd+down=jump_to_prompt:1
Functional transparency
background-opacity = 0.92 background-blur = 20
Generous scrollback (Claude outputs a lot)
scrollback-limit = 50000
Eliminate unnecessary blinking
cursor-style-blink = false
Most of the settings are sensible defaults, but two are especially noteworthy.
`jump_to_prompt` lets you navigate between Claude Code responses using `Cmd+Up` and `Cmd+Down`. When a session is 40 minutes long and you want to revisit something, instead of *scrolling* endlessly, you can jump right to the previous prompt. It’s really cool.
`toggle_split_zoom` lets you expand a particular *split* to fullscreen without closing the others. If you’re reviewing a long diff in the left split, press `Cmd+Shift+Enter` to expand it to fill the whole window. Review the diff, press it again, and everything snaps back into place.
### 2. Create worktrees
I’ve already written about [what worktrees are](/en/git-worktrees-coding-agents-parallel/) and [how Claude Code uses them](/en/claude-code-worktrees-parallelism-agents/). Here’s the TL;DR of what I do every morning:
```bash
# From the main repo
cd ~/code/my-project
# Create worktrees for the day’s tasks
git worktree add ../my-project-feature-a -b feature/validation
git worktree add ../my-project-translations -b chore/translations
Naming convention: the original repo is main. Each worktree is the repo’s name plus a descriptive suffix. A quick ls ~/code/my-project* gives me an overview.
3. Open splits and launch agents
| |
In under a minute, my window is set up with three splits and two agents working.
4. Monitor and merge
The main split is the command center. From there:
| |
No need to switch splits to view diffs. All worktrees share the same git database, so I can see all branches and their changes from main.
What I’ve learned after two months with this setup
Split zoom is a lifesaver
When an agent generates a 200-line diff and I want to review it carefully, the split gets too small. Cmd+Shift+Enter expands it into a fullscreen view. After reviewing, I either approve or request changes, then return to the three-split layout. No sessions are lost.
Quick Terminal is for tasks that don’t deserve a split
I used to cram everything into splits. Mistake. I’d end up with five tiny panels where nothing was readable. Now the rule is simple: if a task takes more than a minute, it deserves a split. If not, use the Quick Terminal.
Ctrl+` → git log --oneline -5 → Ctrl+`
It pops up, executes, and disappears. No clutter.
No more than three splits at a time
I’ve tried four and five splits. It doesn’t work. On a 27-inch screen, three is the max before each panel gets too narrow and Claude’s output becomes illegible. On a 14-inch laptop, two is the practical limit.
If I need more than three parallel tasks, I open a new tab with Cmd+T and recreate the layout there. Ghostty retains the state of all tabs, so everything is exactly as I left it when the lid is reopened (window-save-state = always).
Worktrees need their own .env
Each worktree is an independent working directory. This means your .env.local, .claude/settings.json, or any file not in git doesn’t exist in a new worktree.
Here’s my little hack: a Fish script that copies what’s needed when creating a worktree:
| |
It’s not elegant, but it works. I could use symlinks, but I prefer independent copies: if an agent changes something in .env.local (which they shouldn’t, but you never know), I don’t want it affecting the others.
Ghostty + Claude Code has a hidden trick
Ghostty’s shell integration (shell-integration = fish) lets the terminal know where each prompt begins and ends. This is what powers jump_to_prompt. But the side effect is that you can select the output of an entire command with a single click in the left margin.
When Claude Code spits out a block of code and you want to copy it, instead of selecting manually (and accidentally including the prompt or missing a line), just click the margin to select all the output. Cmd+C and done.
It’s not documented anywhere, but once you discover it, you can’t live without it.
When I DON’T use this setup
On battery. This is the cost of Ghostty, and there’s no way around it: GPU rendering uses what it uses. I covered this in-depth in Your terminal is burning through battery like it’s mining Bitcoin, and the numbers are obscene. If I’m at a coffee shop, I close Ghostty and open Terminal.app. The workflow is clunkier, but the battery lasts three times as long.
For sequential tasks. If task B depends on task A, there’s no benefit to running in worktrees. A single split with a single agent is enough. Worktrees shine for true parallelism, not for pretending to be productive.
When I don’t fully understand the problem. If I don’t know exactly what I want each agent to do, launching three in parallel is asking for chaos. First, I explore in a single split, understand the problem, and only once I have clear, independent tasks, I set up the three-split layout.
The big picture
flowchart LR
subgraph Ghostty[" Ghostty "]
direction TB
subgraph Splits[" Splits Cmd+D / Cmd+Shift+D "]
direction LR
S1[" Split 1 \nClaude Code\nworktree A"]
S2[" Split 2 \nClaude Code\nworktree B"]
S3[" Split 3 \nmain\ntests + merges"]
end
QT[" Quick Terminal Ctrl+` \ngit status, linear, make validate"]
end
subgraph Git[" Git "]
direction TB
G1[".git/\n(shared)"]
W1["worktree A\nfeature/x"]
W2["worktree B\nchore/y"]
W3["main"]
end
S1 --> W1
S2 --> W2
S3 --> W3
W1 --> G1
W2 --> G1
W3 --> G1
style Ghostty fill:#1a1a2e,stroke:#4a9eed,color:#fff
style Git fill:#1a2e1a,stroke:#4aed5c,color:#fff
style Splits fill:#2d3748,stroke:#4a9eed,color:#fff
Ghostty as a visual multiplexer. Worktrees as a git multiplexer. Claude Code as the workhorse. Each part does one thing and does it well.
I don’t need tmux because Ghostty handles multiplexing. I don’t need cloned repos because worktrees share the same state. I don’t need to switch branches because each split is a separate directory.
It’s the first time in years that I feel like my terminal isn’t getting in the way. That my train of thought—“I want to advance three things at once”—translates directly into actions without ceremony, boilerplate, or friction.
Is it perfect? No. The battery issue is still a problem. Five splits are too much. Occasionally, an orphaned worktree will need cleaning up with git worktree prune.
But life doesn’t run on perfection. It runs on what works. And this works damn well.
TL;DR: Ghostty for splits and Quick Terminal (no tmux). Git worktrees for multiple parallel checkouts (no cloning). Claude Code in each split, each in its own worktree. Cmd+D to split, Cmd+Alt+Arrows to navigate, Cmd+Shift+Enter for zoom, `Ctrl+`` for quick terminal. Three splits is the practical max on a 27-inch screen. On battery, use Terminal.app and forget the GPU.