One terminal · every branch · every Claude session

Parallel development,
actually manageable.

Work is a cross-platform CLI that turns git worktrees into a development cockpit. Spin up isolated workspaces per branch across one repo or many, auto-launch Claude Code, and orchestrate PRs, Jira issues, and tasks from a single keyboard-driven dashboard.

MIT licensed Node 18+ · macOS · Linux · Windows Single-repo & multi-repo groups
work tree api feature/login
$ work tree api feature/login --prompt "Implement the login page"
 resolved target          → repo "api" at ~/repos/api
 branch resolved          → creating from main (no local, no remote)
 worktree created         → ~/worktrees/api/feature-login
 copied dev settings      → 3 files matched copyFiles globs
 session recorded         → ~/.work/history.json
 launching Claude Code    → --prompt "Implement the login page"

claude-code (api · feature/login)
 Reading src/auth/AuthContext.tsx
 Writing src/pages/login.tsx
 build passed             0 warnings · 0 errors
Plays well with
Claude CodeGitHub CLIAtlassian CLI VS CodePowerShellbashzsh Windows TerminaliTerm2
01 The problem

Three branches, three terminals, three lost contexts.

Working on multiple branches in parallel is a productivity superpower — until the cognitive overhead eats the gain. Hand-rolled `git worktree add` invocations, dev settings copied by hand, Claude Code sessions that don't survive a terminal restart, and "which directory was that branch in again?" looped through every context switch.

Without Work

Manual worktree juggling

cd ../path && git worktree add && cp .env.local . every time. Three terminals open. Three Claude sessions you can't tell apart.

The drift tax

Stale context, stale worktrees

Merged branches pile up on disk. Jira tickets get re-typed into branch names. PRs get checked from a separate browser tab.

With Work

One command, one cockpit

work tree creates the worktree, copies dev settings, launches Claude. work dash shows every session with its PR, Jira, and tasks attached.

Foundations

Built on git's best primitive — with everything around it that git doesn't ship.

Work doesn't replace git. It layers session tracking, multi-repo orchestration, and AI-assistant integration on top of git worktrees so the workflow scales past two parallel branches.

F.01

Isolated checkouts

Every branch gets its own working directory. No stash gymnastics. No rebuilt build cache.

F.02

Atomic operations

Worktree creation, file copying, session recording, AI launch — all-or-nothing with rollback.

F.03

Multi-repo aware

Group repos that ship together. Combined CLAUDE.md generated by Claude itself.

F.04

Session-tracked

History keyed by target+branch. Recent sessions, resume, status, prune — all derived from one source.

F.05

Cross-platform

macOS, Linux, and Windows. PowerShell shims and tab completion auto-installed.

02 How it works

Four moves. Every branch, every day.

The whole tool collapses to four verbs — create, switch, observe, retire — applied to the entire lifecycle of a branch from "I have an idea" to "this is merged."

01

Create

work tree api feature/login resolves the target, picks branch from local → remote → new, creates the worktree, copies dev-settings globs, and launches Claude Code with an optional prompt.

work tree --base --prompt --open
02

Switch

work resume picks a recent session and re-enters it — the embedded Claude session continues with --continue, so the conversation history isn't lost. Or jump straight from the dashboard.

work recent work resume work dash
03

Observe

work status joins history with live git status — merge state, dirty trees, unpushed commits, last-access timestamps. The dashboard adds open PRs, assigned Jira issues, and pending tasks.

work status work list work dash
04

Retire

work prune removes worktrees whose branches landed on main — interactive picker, or --force for sweep mode. work remove blocks on uncommitted or unpushed work unless you really mean it.

work prune work remove --force
03 Why teams use Work

Built for engineers running more than one branch at a time.

Twelve capabilities that separate Work from a shell alias around git worktree add.

Auto-launch Claude Code

Every work tree creates the worktree and starts a Claude Code session in it. Optional --prompt seeds the conversation. work resume keeps the thread alive across restarts.

Multi-repo groups

One name, many repos. work tree fullstack feature/x creates synchronized worktrees across every repo in the group, plus a Claude-merged combined CLAUDE.md.

Atomic worktree ops

setupWorktree() and teardownWorktree() are all-or-nothing with rollback on partial failure. No half-created worktrees, no orphan history rows.

GitHub PR integration

Open PRs across every configured repo via gh. Status decorated with check state, conflicts, your review state, draft dimming, and ownership marks. Selecting a PR creates or resumes its worktree.

Jira → branch → Claude

Pick an assigned Jira issue, choose target project, Work generates a branch slug via Claude Haiku, creates the worktree, and pipes a structured planning prompt into Claude.

Local task tracking

A native work todo command and a Tasks pane in the dashboard. Press w on a task to spin up a todo/<slug> worktree and start working on it.

Session-aware everything

Every work tree upserts to history.json. recent, resume, status, and the dashboard's session pane all derive from one source — fs.watch means external changes appear immediately.

Dev-settings autopilot

Glob patterns in copyFiles get copied into every new worktree. *.Local.json, .env.local, .claude/settings.local.json — the gitignored-but-required trio, handled.

Cross-platform completion

Tab completion auto-installed for PowerShell 7/5.1, bash, and zsh during work init. Idempotent, marker-guarded, manual fallback documented.

Fleet commands

One action, every worktree. work run --all npm test fans a shell command across the fleet (parallel, prefixed output, Ctrl-C kills all). work broadcast --all "rebase onto main" queues a prompt to every live AI session for its next turn.

Browser dashboard

work web brings every session — diff, review comments, and a live terminal — into one browser tab. A singleton process; every wd review registers as a scope on it instead of spawning its own port.

Idle notifications & hooks

Opt in to a desktop ping when a session finishes its turn or needs input, or wire a statusHooks shell command for sounds, Slack, anything. Plus work sync — fetch every repo and prune merged worktrees in one non-interactive sweep.

04 The difference

The same workflow, before and after.

Same engineering tasks. Different ergonomics.

Step Plain git worktrees With Work
Start a feature git worktree add ../api-feat-x feature/x && cp .env.local ../api-feat-x/ && cd ../api-feat-x && claude work tree api feature/x
Multi-repo feature Repeat the above for every repo. Hand-merge each CLAUDE.md. work tree fullstack feature/x — combined CLAUDE.md auto-generated.
Resume a session Remember which directory it was in. cd. claude --continue. work resume — picker sorted by last access.
See open PRs Open gh pr list per repo, then a browser tab to check status. PR pane shows checks, conflicts, draft, your review state, ownership.
Take a Jira ticket Read the ticket, type a branch name, paste the description into Claude. Select issue → branch slug generated → worktree created → planning prompt sent.
Clean up merged branches git worktree list, check each, git worktree remove one by one. work prune — interactive multi-select, or --force sweep.
See everything at once N terminals, N editors, N tabs. work dash — sessions, PRs, Jira, tasks, embedded terminal.
05 The dashboard

Five panes. One focus model. Zero context switching.

work dash is an Ink-based terminal UI with an embedded node-pty Claude Code session per worktree. Sessions, pull requests, Jira, and tasks on the left — your live AI conversation on the right.

Reactive sessions

fs.watch on history.json — running a work tree in another terminal pops up in the dashboard immediately. No refresh needed.

Auto-sync on startup

All repo remotes fetched in parallel. PRs and Jira issues loaded immediately. g syncs the focused pane. G syncs everything.

Hook-aware activity

A local HTTP server receives Claude Code lifecycle events (Stop, Notification, UserPromptSubmit) so session indicators reflect real-time activity.

PR decorations

★ yours ✔ approved ✎ reviewed ✓ checks ✗ failing — at a glance.

Mouse + keyboard

Scroll wheel navigates panes. Left-click switches focus. Shift+drag selects text. j/k for keyboard purists.

Context-sensitive status bar

Keybinding hints change based on the focused pane. No memorising — the cheat sheet is always on screen.

06 Multi-repo groups

One feature.
Many repositories.

When a feature spans an API repo, a frontend, and a shared library, Work treats them as a single unit. One command creates synchronized worktrees across all of them, plus a Claude-merged combined CLAUDE.md so the AI session understands every codebase it can see.

Definework config group add fullstack api web shared-lib
Creatework tree fullstack feature/checkout
Tear downwork remove fullstack feature/checkout
Regenerate CLAUDE.mdwork config group regen fullstack
~/worktrees/fullstack/feature-checkout
fullstack/
└── feature-checkout/
    ├── api/             # worktree for api repo
    ├── web/             # worktree for web repo
    ├── shared-lib/      # worktree for shared-lib repo
    └── CLAUDE.md       # auto-merged from each repo's CLAUDE.md

$ work tree fullstack feature/checkout
 resolved group           → 3 repos: api, web, shared-lib
 created 3 worktrees      → in lockstep, with rollback on failure
 merged CLAUDE.md         → via Claude CLI
 launching Claude         → workspace-aware session
07 Diff & review

Every branch, reviewed before you push.

wd opens a GitHub-style diff for the current worktree in your browser. wd -c turns it into a live review session — click any line to leave a comment, Claude reads them inline and replies in-thread. Every wd invocation registers as a scope on a single work web server, so a dozen reviews share one port and one set of browser tabs.

Live reload

The server watches the working tree. Save a file, refresh the browser — the diff updates. No re-running anything.

Two-way conversation with Claude

Comments stream to wd -c's stdout as markers. The wd-review skill picks them up, replies inline via the API, and the thread renders right under the original — Claude's voice shaded in accent.

One server, every scope

Run work web once. Every wd and wd -c invocation registers as a scope on that same server — addressable at /diff/<hash> or /review/<hash>. No port-per-tab sprawl.

Multi-repo tabs

In a group worktree, every sub-repo's diff renders as a tab. Sticky at the top while you scroll — switch repos without losing your place.

Uncommitted vs Since branch

Toggle between just-the-working-tree-delta and a full PR-style diff against the branch's parent. The parent is detected automatically (main, master, dev, develop) or honoured from work tree --base.

Auto-collapsed migrations

Files over 500 changed lines render a placeholder with a Load diff button. EF Core migrations and lockfile churn no longer freeze the browser.

Hooks bridge to live Claude

work web installs UserPromptSubmit and Stop hooks in ~/.claude/settings.json. Drop a comment on a line and any Claude running in that worktree picks it up on the next turn — no copy-paste, no "hey can you look at line 42".

Singleton

work web is one process per user — ~/.work/web.pid + ~/.work/web.url. Second invocation reuses the running one. work web --stop for a clean shutdown.

08 Architecture

Small core. Strict boundaries.

A yargs router on top of a shared core layer, with two consumers: the CLI commands and the Ink-based TUI. Same atomic operations, two interfaces.

Core operations
core/worktree.tsAtomic setupWorktree() / teardownWorktree() — used by both CLI and TUI.
core/git.tsGit wrapper — branch resolution, remote fetch, worktree add/remove.
core/resolve.tsGroup vs single-repo dispatch — one name, two behaviours.
core/copy-files.tsGlob-driven dev-settings copy — including dot-prefixed dirs.
core/history.tsSession tracking keyed by target+branch — backs recent, status, resume.
core/tasks.tsLocal task persistence (~/.work/tasks.json) — file-watched.
core/pr.tsGitHub PR fetching via gh pr list — checks, conflicts, review state.
core/jira.tsJira issue fetching via acli — assigned-to-me, grouped by status.
TUI & PTY layer
tui-ink/App.tsxInk layout, keyboard handling, session lifecycle, focus model.
tui-ink/Sidebar.tsxFive-pane sidebar — sessions, PRs, Jira, tasks; bordered components.
tui-ink/TerminalPane.tsxRenders the xterm headless buffer to the Ink terminal pane.
tui/session.tsnode-pty + @xterm/headless — embedded Claude per worktree.
tui/hooks.tsLocal HTTP server receiving Claude Code lifecycle events for activity tracking.
Build & runtime
tsup → ESM Node ≥18 deps external vitest npm link
09 Get started

Install in three commands.

Node 18+ and Git are the only requirements. Claude Code, GitHub CLI, and Atlassian CLI are optional — Work degrades gracefully when they're not present.

1 · Clone & build node ≥ 18
$ git clone https://github.com/moberghr/cli-work-tree-manager work
$ cd work && npm install && npm run build && npm link
2 · Initial setup interactive · one-time
$ work init
  → worktrees root · repo aliases · tab completion
3 · Daily driving every branch
$ work tree api feature/login         # create worktree, launch Claude
$ work dash                            # open the cockpit (or `work web` in the browser)
$ wd -c                                # review the diff, comments flow to Claude
$ work run --all npm test              # fan a command across every worktree
$ work resume                          # jump back into a recent session
$ work sync                            # fetch all repos + prune merged worktrees
View on GitHub Read the README

Stop juggling terminals.
Start running every branch in parallel.

Work is the missing layer between git worktree and your AI assistant. One command creates the workspace. One dashboard runs them all.

Get Work About Moberg
10 FAQ

Common questions.

Why git worktrees instead of branches in one checkout?

Branches share a working directory. Worktrees give every branch its own isolated checkout — separate node_modules, separate bin/obj, separate dev-server processes, separate Claude Code sessions. You can run all of them concurrently without stash gymnastics or losing your build cache.

Do I need Claude Code to use Work?

No. work tree, work list, work status, work prune, and the dashboard's session pane all work without Claude Code installed. You just lose auto-launch, group CLAUDE.md generation, and the embedded terminal in the dashboard. The CLI degrades gracefully when claude isn't on PATH.

Does the dashboard work on Windows?

Yes. Ink and node-pty support Windows; PowerShell completions are installed automatically during work init. Mouse and keyboard handling work in Windows Terminal, ConEmu, and the VS Code integrated terminal.

What happens when a worktree's branch is merged?

work prune lists every worktree whose branch is merged into main / master and offers to remove them interactively. --force skips the prompt. For groups, every sub-repo's branch must be merged before the group is offered.

Can I customise which files get copied into new worktrees?

Yes — edit copyFiles in ~/.work/config.json (or run work config edit). Any glob pattern works. The default set covers *.Development.json, *.Local.json, and .claude/settings.local.json — the typical "gitignored but required to run" trio.

How does the Jira → branch flow work?

Pick a Jira issue in the dashboard, choose the target project, and Work invokes Claude Haiku with the issue title to generate a branch slug. It then runs work tree <project> <slug> in a PTY and pipes a structured planning prompt to Claude via --prompt-file. End result: a fresh worktree with Claude already thinking about your ticket.

Is it open source?

Yes — MIT licensed. Fork it, extend it, send a PR on GitHub.