workshell
v0.0.7
Published
Agent- and human-friendly Git multitasking, powered by worktrees
Maintainers
Readme
Install
$ npm i -g workshell # aliases to `wk`
$ wk --help
wk v0.0.6 - Open branches in ephemeral subshells
Usage: wk <command> [options]
# ...How workshell works
There have been many attempts to nail a DX for parallel work in the agentic coding era. Most are thin wrappers over git worktree. Instead wk introduces a new paradigm: the workshell.
A workshell is an ephemeral worktree whose lifecycle is bound to a subshell.
Here's how it works (key points in bold).
- You open a Git branch with
wk open <branch>or create a new one withwk new <branch>. - An ephemeral worktree is created for this branch (in
~/.workshell/worktrees) and opened in a fresh subshell. - You are now in an fresh checkout of your repo that is isolated on disk. Make changes with your agent/editor of choice and commit them.
- You close the subshell with
wk close. The associated worktree is auto-pruned. - Your changes still exist on the associated branch, as Git commits/branches are shared among all worktrees. The worktree is destroyed—but your commits aren't.
Features
This approach has some nice properties.
- 🖥️ Tab-local workspaces — Normally a
git checkout/git switchchanges your active branch for all terminals. With workshells, you can functionality open branches in the current tab only. - 🌳 Full isolation — Each workshell is isolated on disk, so the changes you make don't interfere anything else you're doing.
- 🙅♂️ Never stash again — You can
wk opena branch even with uncommitted changes. When you exit the subshell, things will be exactly the same as they were. ☕️ - Consistent with branch semantics — As with regular
git switch,wk closewon't let you close the subshell if you have unstaged/uncommitted changes. This is a feature, not a bug! Regular worktrees make it easy to lose your work in a forgotten corner of your file system. - 🤖 Agent-ready — Spin up parallel workshells so multiple agents can work simultaneously without conflicts.
Quickstart
This section is entirely linear and self-contained. Try running all these commands in order to get a feel for how wk works. First, install wk.
$ npm i -g workshellThis installs the workshell CLI. For convenience, it's also aliased to wk. We'll use wk throughout the quickstart.
$ wk status
branch: main (root)
worktree: /Users/colinmcd94/Documents/projects/pf
status: cleanClone a repo (any repo works):
$ git clone [email protected]:colinhacks/zod.git
$ cd zodAfter cloning, the main branch is checked out. Let's say we want to start work on a new feature:
$ wk new feat-1
✓ feat-1 (from main)
Opened branch in ephemeral subshell
Type 'wk close' to return.You're now in a workshell. Check where you are:
$ pwd
~/.workshell/worktrees/{repo-id}/zod@feat-1
$ git branch --show-current
feat-1Now let's make some changes. (You can also open the repo in an IDE, start an agent run, etc.)
$ touch a.txtNow let's try to close the workshell.
$ wk close
⚠ Uncommitted changes found. Commit, stash, or reset your changes first.
Or use --force/-f to discard changes
wk close -fWe aren't able to close because we have uncommitted changes. Let's commit them.
$ git add -A && git commit -am "Add a.txt"Now we can try closing again. Since our changes can be fast-forwarded from the base branch, wk offers to auto-merge the changes.
$ wk close
✓ Back in main
Pruned worktree. Your changes are still in the 'feat-1' branch.
To merge your changes:
git merge feat-1
Auto-merge? (y/n/never) y
✓ Merged 'feat-1' into 'main'CLI
wk v0.x.y - Human- and agent-friendly Git multitasking
Usage: wk <command> [options]
Commands:
new [branch] Create a branch and open it [--from <branch>]
open <branch> Open a branch in a workshell
close Exit current workshell
ls List orphaned worktrees
status Show current branch
rm <branch> Remove a branch's worktree
config Show or create config file
Options:
--help, -h Show help
--version, -v Show versionList orphaned worktrees
Normally the worktree will be auto-pruned when you close its associated workshell. If a worktree is left behind for some reason, you can list them with wk ls.
$ wk ls
┌────────┬───────────┬───────────────┐
│ branch │ status │ created │
├────────┼───────────┼───────────────┤
│ main * │ clean │ - │
│ feat-1 │ 1 changed │ 5 minutes ago │
└────────┴───────────┴───────────────┘Open a branch in a workshell
You can open any existing Git branch in a workshell.
$ wk open feat-1
✓ feat-1 (existing worktree)
Type 'wk close' to return.Show current branch status
$ wk status
branch: main (root)
worktree: /path/to/zod
status: cleanRemove a worktree
Remove the worktree for a branch (the branch itself is kept):
$ wk rm feat-1
✓ Pruned worktree for feat-1Closing a workshell
This closes the current workshell and auto-prunes the associated worktree. Your changes survive in your branch commits.
$ wk close
✓ Back in main
Pruned worktree. Your changes are still in the 'feat-1' branch.
To merge your changes:
git merge feat-1
Auto-merge? (y/n/never) y
✓ Merged 'feat-1' into 'main'If the branch hasn't been pushed to a remote, you'll be prompted to auto-merge:
y— merge into base branchn— skip (branch is kept, merge manually later)never— permanently disable auto-merge prompt
That command will fail if you have unstaged/uncommited changes. Use the --force/-f flag to force close the workshell; this will discard uncommitted changes.
$ wk close --forcePrint or create a workshell.toml
To print or create a config file:
$ wk config
✓ Config file: /path/to/repo/.git/workshell.toml
────────────────────────────────────────────────────────────
setup = "npm install"
────────────────────────────────────────────────────────────If no config exists, you'll be prompted to create one.
$ wk config
No config file found.
Where would you like to create one?
1. .git/workshell.toml (local only, not committed)
2. workshell.toml (project root, can be committed)
Choice (1/2): 1
✓ Created /path/to/repo/.git/workshell.tomlworkshell.toml
You can configure wk with a workshell.toml file. This is useful for running setup scripts when opening a workshell (e.g., npm install).
wk looks for config files in the following order:
| Path | Description |
|------|-------------|
| .git/workshell.toml | Local only, not committed (highest precedence) |
| workshell.toml | Project root, can be committed |
Currently only one setting is supported: setup.
# setup script executed in subshell after initialization
# the following variable substitutions are supported
# `{{ branch }}` — The name of the opened branch, e.g. `feature/auth`
# `{{ repo_path }}` — The absolute path to main repo, e.g. `/path/to/repo`
# `{{ worktree_path }}` — The absolute path to worktree, e.g. `~/.workshell/worktrees/.../repo@feat`
setup = "npm install && cp {{ repo_path }}/.env {{ worktree_path }}/.env"