cd /news/ai-tools/show-hn-canopy-parallel-sandboxed-cl… · home topics ai-tools article
[ARTICLE · art-27728] src=github.com ↗ pub= topic=ai-tools verified=true sentiment=↑ positive

Show HN: Canopy – parallel, sandboxed Claude Code sessions on macOS

Developer Julien Simon released Canopy, a native macOS app that manages parallel, sandboxed Claude Code sessions using git worktrees. The tool addresses workflow friction when working on multiple tasks simultaneously by providing a unified interface for session management, automatic context resumption, and per-session sandboxing. Canopy is available via Homebrew or as a signed DMG for macOS 14+.

read13 min publishedJun 15, 2026

Parallel Claude Code sessions with git worktrees — a native macOS app.

One window. Parallel branches. Parallel Claudes. Zero context switching.

Universal binary · Apple Silicon + Intel · Notarized · macOS 14+

demo.mp4 #

I've been using Canopy every day for months on my own projects. I'm sharing it now because it has earned its place on my dock, and I think it might earn a place on yours too.

Here's the honest pitch: Claude Code is a superpower. Canopy feels like wearing all five Infinity Stones.

When you use Claude Code seriously — not just for experiments, but for real production work — you hit a wall the tool wasn't designed to push through. Claude is brilliant at focusing on one thing in one directory. But real engineering work doesn't come one thing at a time. A bug report lands while you're refactoring. A teammate asks you to review a change while you're writing tests. The roadmap demands you keep shipping while you investigate a flaky test. You need to work on three things at once, but Claude — and git

— want you to work on one.

You can hack around it: stash, checkout, maybe a second clone, maybe git worktree add

and a hand-written shell script to copy your .env

, maybe remember which of your six Terminal.app tabs was running which session. You end up with a tab graveyard, stale worktrees littering your disk, Claude sessions you can't find, and a quiet tax on every task you do.

Canopy removes that tax. Completely.

Every Canopy feature exists because I was tired of doing something manually. Each one saves a few seconds. Do the math over a day — over a week, over a month — and the compound is real.

You used to do this With Canopy
Stash your work, checkout another branch, lose Claude's conversation context Open a new worktree session — your old session keeps running in another tab
Hunt through ~/.claude/projects/<hash>/ for a session ID, then claude --resume abc123…
Click the tab. Canopy resumes the right session automatically.
Juggle six Terminal.app windows, cmd-tabbing to find the right one One window, one tab bar, Cmd+1Cmd+9 to jump anywhere
Copy-paste the working directory into Cursor/VS Code with cmd-c / cmd-shift-o / cmd-v Right-click → Open in IDE
Switch windows to run git log while Claude is working
Cmd+Shift+D — shell pane drops in below Claude, no interruption
Re-run npm install , copy .env , symlink node_modules every time you make a worktree
Configure once per project. Canopy does it on every new worktree.
Wonder which of your branches are merged and safe to delete Project view lists every worktree with status and a one-click Merge & Finish
git checkout main && git pull && git merge feat/… && git worktree remove … && git branch -d …
Right-click → Merge & Finish — two panels, one button
Squint at ls ~/.claude/projects/ trying to guess how many tokens you've burned this week
Open Activity — token counts, session history, 12-week heatmap
Type out the same "write tests", "review security", "update docs" prompt for the tenth time Save it once in the Prompt Library — one right-click to fire it at any session
Scroll a flickering terminal trying to re-read what Claude said ten minutes ago Right-click → Show Transcript — the conversation as clean markdown, live-updating
Worry about what an autonomous agent might touch outside the repo Pick a sandbox — per session, per project, or globally — and Claude runs in a VM with just your worktree mounted

None of these are big problems on their own. All of them are papercuts. Canopy is a tool for people who notice papercuts.

brew install --cask juliensimon/canopy/canopy

Grab the latest signed and notarized .dmg

from ** Releases**. Open, drag to Applications, launch.

Requirements: macOS 14 Sonoma or later. Apple Silicon or Intel. Claude Code installed (claude

available in your $PATH

).

Add a project(Cmd+Shift+P

) — point at any git repository. Configure files to copy (.env

), symlink paths (node_modules

), and setup commands (npm install

).Create a worktree session(Cmd+Shift+T

) — pick a base branch, name your feature branch.- Canopy creates the worktree, copies config, runs your setup, and launches Claude Code. Start prompting.

  • Need a parallel task? Cmd+Shift+T

again. Each session is completely isolated. - When you're done with a session, right-click → Merge & Finish. Canopy merges your branch and cleans up the worktree.

That's the whole loop. Repeat forever.

Each tab is a separate worktree running its own Claude Code instance. Switch between them with Cmd+1

Cmd+9

. Drag tabs to reorder. Sort by name, project, creation date, or directory with Cmd+Shift+S

. Activity dots show which sessions have output streaming, so you know at a glance which Claude is still thinking.

When you close and reopen Canopy, every session comes back — with its Claude conversation resumed automatically. No session IDs to remember, no --resume

flags to type. Canopy finds the right session by scanning ~/.claude/projects/

and passes it to claude

for you.

Token usage is the one thing Claude Code doesn't surface well. Canopy fixes that.

The Activity view parses your ~/.claude/projects/

JSONL files and gives you a full picture of how you've been using Claude:

All-time token totals— input and output, across every session you've ever run** Last 12 weeks**— same breakdown, so you can see recent trends** Session count**— how many conversations you've had in the window** Busiest day**— when were you deep in Claude?** Model breakdown**— percentage split across Opus, Sonnet, and Haiku** Hour-by-hour heatmap**— 12 weeks of your actual working hours, visualized

This is the view I use to answer "am I on track for my API budget this month" and "when am I most productive." No third-party tools, no scraping, no estimation — it's reading the same JSONL files Claude Code writes.

Cmd+K

opens a fuzzy-match palette over every session, project, branch, and action Canopy knows about. Type three letters of a branch name, hit return, you're there. Type the name of a project, hit return, the project view opens. Type "merge", hit return, the merge flow fires on the current session.

If you have more than four or five sessions open, this is the fastest way to navigate. Faster than clicking. Faster than Mission Control. Fast enough to feel instant.

Cmd+F

inside any session opens an incremental search over the terminal output. Matches highlight as you type. Return jumps to the next match. Shift-return jumps to the previous one. Escape closes the search.

This is a small feature that turns out to matter a lot: when Claude produces a 400-line plan and you need to jump to the part about "database migration," you used to scroll. Now you don't.

Right-click any session → Show Transcript… for a clean, scrollable, read-only view of the whole conversation. When Claude Code is running, Canopy reads its structured JSONL session log and renders user/assistant turns with markdown formatting — tool calls compacted to one-line summaries instead of walls of raw output. It live-updates as Claude streams, with an auto-tail toggle so you can read history without being yanked back down. The Copy button (Cmd+Shift+C

) puts the formatted markdown on your clipboard — handy for PR descriptions and notes.

Cmd+Shift+D

toggles a secondary shell pane below Claude's terminal. Need to run git status

while Claude is mid-thought? Peek at the test output from another tool? Tail a log? You don't need to interrupt Claude or open a new window. The split pane is a full interactive shell, scoped to the same worktree, and you can hide it the same way you showed it.

This is the feature I was most skeptical I'd use, and now I can't imagine working without it.

Pick a sandbox backend in Settings (globally, per project, or per session in the New Worktree Session sheet) to launch Claude inside a VM. Your working directory is bind-mounted into the sandbox, so file edits work normally, but everything that isn't explicitly mounted — SSH keys, documents, the Keychain, other repos, the rest of your home directory — is out of reach. A shield icon marks sandboxed sessions in the sidebar, and the split terminal still opens a host shell for inspecting the real filesystem. Canopy validates the required tools before enabling a backend. The user guide spells out exactly what is and isn't protected (the mounted project and outbound network are deliberate trade-offs).

Docker Sandbox (sbx) — a Docker Sandbox microVM via sbx run

. Session resume is disabled (session files live inside the ephemeral microVM). Requirements: Docker Desktop and sbx

(brew install docker/tap/sbx

).

Apple container — a lightweight VM via Apple's open-source container runtime, no Docker Desktop needed. Canopy mounts the worktree, the project's main repo, and your ~/.claude

state at their host paths — so git works inside the sandbox and session resume works, unlike sbx. The default canopy-claude

image is built in one click (Settings → Build Image); a one-time /login

inside the first sandboxed session sets up credentials. Requirements: macOS 26+ on Apple silicon, brew install container

, container system start

once per boot. Full setup steps in the user guide.

The last step of every feature used to be a four-command dance:

git checkout main
git pull
git merge feat/whatever
git worktree remove ../canopy-worktrees/myproject/feat-whatever
git branch -d feat/whatever

…except you never actually did all of it, and now you have 11 stale worktrees and 40 merged branches on your laptop. Canopy replaces the whole thing with a two-phase confirmation sheet. Phase 1: pick the target branch, confirm the commit count, see any conflicts before they happen. Phase 2: pick what to clean up — worktree directory, feature branch, both, or neither. One click. Done. No debt.

Click any project in the sidebar to see every worktree, its branch, its status, and a one-click button to open, merge, or delete it. "Open All" resumes every inactive worktree at once with their prior Claude sessions — the fastest way to get back into a multi-branch project after a weekend away.

The project view also lists every open pull request for the repository, pulled via gh pr list

— so you can see at a glance which of your worktrees already have a PR in flight and which are still local.

Canopy polls git

and gh

every 10 seconds so you never have to drop into a shell to check the state of the current worktree. You see:

Status bar at the bottom of the window, for the active session: modified files with+

/

line counts, commits ahead of the upstream, and open pull request count (with draft split). Hover any pill for a full tooltip — file list, push status, PR titles.Sidebar session rows show a compact+N / −N

diffstat and an up-arrow count for commits-ahead, so you can scan all your worktrees at once.Project detail view lists every open PR with title, number, author, and draft status.

Requires gh

to be installed for the PR data (brew install gh

). Path is auto-detected; override in Settings if needed.

Build a library of prompts you use repeatedly — "write tests for this", "check for security issues", "update the README" — and fire them at any session without retyping.

Sending a prompt: Right-click any session → Send Prompt. Starred prompts appear inline in the submenu for instant access. Click Browse All… to search the full library.

Managing the library: Open Settings → Prompt Library. Add, edit, reorder (drag-and-drop), star, and delete prompts. All changes save immediately.

Template variables are substituted at send time:

Variable Resolves to
{{branch}}
Current git branch of the session
{{project}}
Project name
{{dir}}
Working directory name (last path component)

A prompt like "Review {{branch}} for correctness and add tests"

becomes "Review feat/auth for correctness and add tests"

when sent to that session.

Shortcut Action
Cmd+T
New plain session (directory picker)
Cmd+Shift+T
New worktree session
Cmd+Shift+P
Add project
Cmd+K
Command palette
Cmd+F
Find in terminal
Cmd+Shift+D
Toggle split terminal
Cmd+Shift+A
Activity dashboard
Cmd+Shift+S
Cycle tab sort mode
Cmd+1Cmd+9
Jump to tab N
Cmd+,
Settings
Cmd+?
Help

Canopy builds on two ideas that play well together:

let you check out multiple branches of the same repo simultaneously, each in its own directory, sharing oneGit worktrees.git

store. Creating one is cheap and fast.Claude Code sessions are directory-scoped and resumable. Canopy finds the last session ID for each worktree and passes it via--resume

, so conversations survive restarts.

Everything else — the tabs, the project view, the Activity dashboard, the palette, the split pane — is a native SwiftUI app wrapped around SwiftTerm for terminal emulation. No Electron, no webviews, no bundled Node. It launches fast, idles quiet, and behaves like a Mac app.

For a deeper walkthrough, read the ** User Guide**.

Every project can be configured independently from the Add Project sheet:

Setting Example Why
Files to copy .env , .env.local
Untracked config files Claude needs at runtime
Symlink paths node_modules , .venv , vendor
Heavy directories; symlinks save disk and install time
Setup commands npm install , bundle install , make setup
Run once in each fresh worktree
Worktree base directory ~/worktrees/myproject
Where new worktrees live (default: ../canopy-worktrees/<project> )
Auto-start Claude on/off Per-project override of the global default
Claude flags --permission-mode auto
Per-project override of the global flags
Sandbox backend Off / Docker Sandbox / Apple container Run Claude inside a

--memory 8g

sbx run

canopy-claude

/ --memory 8g

All configuration lives in ~/.config/canopy/

:

settings.json

— global preferencesprojects.json

— project list and per-project configprojects.backup.json

— automatic backup created on every launchsessions.json

— persisted sessions, restored on app restartsessions.backup.json

— automatic backup created on every launchprompts.json

— saved prompt library

Found a bug, have a feature request, or want to send a patch? ** Open an issue** or a PR.

Because Canopy is dual-licensed (see below), contributors are asked to sign the ** Contributor License Agreement** by submitting a pull request. This is a lightweight CLA that grants the project maintainer the right to relicense contributions. It's what makes dual licensing possible while keeping the open source version free under AGPL.

Built by Julien Simonjulien@julien.org.

I've been writing software for a long time. I built Canopy because I use Claude Code every day and the rough edges were getting in the way of the work. It started as a weekend experiment and turned into the tool I now reach for first every morning.

If Canopy saves you time, the best thank-you is to tell someone else who might also find it useful — post it on social, drop it in a Slack, submit a PR. A star on the repo never hurts either.

Copyright © 2026 Julien Simon.

Canopy is licensed under the ** GNU Affero General Public License v3.0** (AGPL-3.0). You can use it, modify it, and redistribute it under the terms of that license.

Commercial licensing: If you need to use Canopy under terms other than AGPL-3.0 — for example, embedding it in a proprietary product or redistributing without source disclosure — commercial licenses are available. Contact julien@julien.org.

── more in #ai-tools 4 stories · sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-canopy-paral…] indexed:0 read:13min 2026-06-15 ·