I have a habit of working on more things at once than I probably should. That is manageable when the work is mine, because I can hold the context in my head. It stops being manageable when a coding agent is doing the work, because now there are several long-running sessions, each in the middle of something, and only one working copy to run them in.
So I would stash. Or I would start a second thing, forget the first was halfway through a refactor, and spend twenty minutes untangling a working tree that two different jobs had opinions about. Neither is a good use of an evening.
The four commands
What I actually wanted was simple enough to write down:
git worktree add ../myrepo-issue-123 -b fix/issue-123 origin/main
cd ../myrepo-issue-123
tmux new-session -s cc-myrepo-issue-123
claude
Every time. Same four commands, different slug. And then the reverse afterwards, which I would put off, which is how I ended up with eleven stale worktrees and a git branch listing I was afraid of.
Anything you type that often should be a script. So I wrote one.
claude-work
claude-work issue-123
That creates a worktree at ../myrepo-issue-123, branches fix/issue-123 off origin/main (fetched first), opens a tmux session named cc-myrepo-issue-123, and starts Claude Code in it. You can pass a different base branch as a second argument, and BRANCH_PREFIX=feat if fix/ is wrong for what you are doing.
The point is not that it saves typing, though it does. The point is that every job gets its own directory and its own branch. Whatever the agent does, it does over there. My main checkout stays exactly as I left it, and two sessions can run at once without ever meeting.
Running the same command again is safe. If the worktree, branch or tmux session already exists, it attaches to what is there instead of creating a second one. I lean on that more than I expected to — it means claude-work issue-123 is also just “take me back to issue 123”.
Detaching is not quitting
This is the distinction the whole thing is built around.
Detach from the session with Ctrl-b d and it keeps running. The script tells you how to get back and gets out of the way. Go make coffee, go to bed, whatever — the agent is still working.
Quit Claude Code, and the session ends. Now the work is done, so the script offers to remove the worktree and delete the branch.
Telling those two apart is most of what the script does that a shell alias could not.
It tries quite hard not to eat your work
Automating cleanup means automating deletion, which is where a convenience script turns into a bad afternoon. So the cleanup path is deliberately timid:
- The prompt defaults to no. Hitting enter keeps everything.
- Before removing anything it checks for uncommitted changes and for commits that are not on the branch’s upstream, and warns about both. Then it asks a second time.
- Branch deletion uses
git branch -d, never-D. If the branch is unmerged, git refuses, you get told why, and the branch survives. You can always run-Dyourself if you mean it. - If stdin is not a terminal, cleanup is skipped entirely. Nothing gets deleted by a script calling a script.
None of that is clever. It is just the set of things I would have wanted the first time I lost a commit.
Installing it
On macOS and Linux:
curl -fsSL https://raw.githubusercontent.com/bjornjohansen/claude-work/main/install.sh | bash
That fetches the latest release, checks it against the SHA256 published alongside it, and installs to /usr/local/bin if you can write there or ~/.local/bin if you cannot. It will not run sudo behind your back, and it tells you if the directory it picked is not on your PATH.
Now, you should not pipe a script from the internet into a shell because a blog told you to, and I am not going to pretend otherwise. It is one self-contained file, so read it first:
curl -fsSL https://raw.githubusercontent.com/bjornjohansen/claude-work/main/install.sh -o install.sh
less install.sh
sh install.sh # user install → ~/.local/bin
sudo sh install.sh # system-wide → /usr/local/bin
sh install.sh --uninstall removes it again, and --help lists the rest. Re-running upgrades in place.
You will need git, tmux and Claude Code on your PATH. The installer warns you about any that are missing rather than failing halfway through.
Where it lives
github.com/bjornjohansen/claude-work. MIT licensed, and it is about 240 lines of bash, so reading the whole thing before you trust it with git worktree remove takes five minutes and is time well spent.
It is a small tool that does one small thing. But it is the difference between running one agent session at a time and running four, and that turns out to matter more than the size of the script suggests.