From jj-workspaces
Use when starting feature work that needs isolation, before executing implementation plans, or before dispatching sub-agents in a jj (jujutsu) repository. ALSO INTERCEPTS any request for git worktrees (including references to the `using-git-worktrees` skill, brainstorming Phase 4, subagent-driven-development, executing-plans, or any "create a worktree" phrasing) whenever the current repo is jj-managed — creates isolated jj workspaces as sibling directories with verified clean baselines so parallel work (including multiple AI agents) proceeds without stepping on each other.
How this skill is triggered — by the user, by Claude, or both
Slash command
/jj-workspaces:using-jj-workspacesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
jj workspaces are independent working copies backed by the same underlying repository. Unlike git worktrees, they're not tied to a branch — they're tied to a *revision*, which jj can move freely. Every workspace sees the others in `jj log` (each marked with its own `@` pointer), and any command auto-snapshots the working copy, so context-switching never requires stashing.
jj workspaces are independent working copies backed by the same underlying repository. Unlike git worktrees, they're not tied to a branch — they're tied to a revision, which jj can move freely. Every workspace sees the others in jj log (each marked with its own @ pointer), and any command auto-snapshots the working copy, so context-switching never requires stashing.
This makes workspaces an ideal unit of isolation for sub-agent driven development: spin up one workspace per parallel task, let each agent iterate in its own directory, and merge back through jj's usual revision graph instead of branch-and-merge ceremony.
Core principle: Sibling-directory workspaces + clean shared base + verified green starting point = reliable parallel isolation.
Announce at start: "I'm using the using-jj-workspaces skill to set up an isolated workspace."
Several skills in this toolkit (notably using-git-worktrees, and the skills that call it — brainstorming Phase 4, subagent-driven-development, executing-plans, finishing-a-development-branch) assume the repo is plain git. In a jj-managed repo those instructions produce the wrong kind of isolation: a git worktree locks a branch, misses jj's revision semantics, and won't appear in jj log, which breaks the multi-workspace coordination the rest of the workflow depends on.
Interception rule: If any skill, plan, or user request asks you to "create a git worktree", invoke the using-git-worktrees skill, or otherwise set up isolated parallel work, run the detection step below first. When jj is in use, this skill takes precedence and you should follow it instead of using-git-worktrees.
jj workspace root 2>/dev/null
.git directory or git rev-parse --is-inside-work-tree succeeds → plain git repo. Defer to using-git-worktrees unchanged.When intercepting a git-worktree request, say so explicitly so the caller (human or agent) understands the substitution:
"This repo is jj-managed, so I'm using the
using-jj-workspacesskill instead ofusing-git-worktrees. Mapping:git worktree add→jj workspace add,.worktrees/<name>→../<repo>-<name>,git worktree remove→jj workspace forget+rm -rf."
Use this table to translate any git-worktree instructions you receive into their jj equivalents before executing:
| git-worktree operation | jj-workspace equivalent |
|---|---|
git worktree add <path> -b <branch> | jj new && jj workspace add <path> (create bookmark later with jj bookmark create <name> if/when needed) |
git worktree add <path> <existing-branch> | jj workspace add -r <bookmark-or-revision> <path> |
Place worktree under .worktrees/<name> | Place workspace at sibling ../<repo>-<name> (workspaces cannot nest inside the main tree) |
Verify .worktrees/ is gitignored | Skip — workspaces live outside the repo tree; no gitignore concern |
git worktree list | jj workspace list |
git worktree remove <path> | jj workspace forget <name> + rm -rf <path> |
| Branch name per worktree | Workspace name (defaults to final path component); bookmarks are optional and created when work is ready to ship |
Once translated, continue with the creation steps below as normal.
jj log shows which workspace is editing which change (@ for current workspace, <name>@ for others). Agents can observe each other's progress.jj workspace root
jj git init --colocate (adopts the existing git repo in place) or fall back to the using-git-worktrees skill.jj workspaces must live outside the main repo's working tree. Nesting a workspace inside the repo it's linked to confuses jj's tracking and many tools. Sibling paths are the idiomatic choice.
Follow this priority order:
repo_root=$(jj workspace root)
repo_name=$(basename "$repo_root")
parent=$(dirname "$repo_root")
# Preferred patterns, in order
ls -d "$parent/.${repo_name}-workspaces" 2>/dev/null # hidden grouped folder
ls -d "$parent/${repo_name}-workspaces" 2>/dev/null # visible grouped folder
jj workspace list # any already-registered workspaces hint at the convention
If any of these already exist, honor the existing layout.
grep -iE "jj workspace|workspace.*director" CLAUDE.md 2>/dev/null
Use the documented preference without asking.
If nothing is configured, ask:
No jj workspace layout found. Where should I create the workspace?
1. Sibling: ../<repo>-<feature>/ (jj-idiomatic, one-off)
2. Grouped: ../<repo>-workspaces/<feature>/ (when several are in flight)
3. Global: ~/.config/superpowers/jj-workspaces/<repo>/<feature>/
Because workspaces sit outside the main tree, there is no .gitignore concern — unlike git worktrees placed at .worktrees/.
Create a fresh empty commit before adding the workspace, so it branches from a stable revision rather than inheriting in-flight edits from the current working copy:
jj new
Skip this if you deliberately want the workspace to start from a specific revision — pass -r <rev> to jj workspace add below instead.
# Default: branch off current @ (what `jj new` just created)
jj workspace add "<destination-path>"
# Or: start from a specific revision / bookmark
jj workspace add -r <revision-or-bookmark> "<destination-path>"
The destination path is the directory that will be created. The workspace name defaults to the final path component — e.g. ../myproject-auth → workspace named myproject-auth. If you want a different name shown in jj log, rename afterwards with jj workspace rename <old> <new>.
cd "<destination-path>"
jj workspace root # sanity-check: should print the new path
[ -f package.json ] && npm install
[ -f Cargo.toml ] && cargo build
[ -f requirements.txt ] && pip install -r requirements.txt
[ -f pyproject.toml ] && poetry install
[ -f go.mod ] && go mod download
Only run what matches; skip silently otherwise.
Run the project's suite once to confirm the workspace starts green. Use whichever command the project uses — npm test, cargo test, pytest, go test ./..., etc.
Workspace ready at <full-path> (name: <workspace-name>)
Tests passing (<N> tests, 0 failures)
Ready to implement <feature>
When the parent session will dispatch N sub-agents in parallel, create one workspace per agent:
jj new # shared base
jj workspace add ../myproject-agent-1
jj workspace add ../myproject-agent-2
jj workspace add ../myproject-agent-3
Each sub-agent receives its own workspace path and operates independently. Because all workspaces share the same backing repo:
jj log from any workspace shows every agent's in-progress revision.jj rebase -s <agent-rev> -d <target> or jj new <rev1> <rev2> … for a combined merge change — no pushing/pulling required.jj abandon <rev> followed by jj workspace forget <name> and rm -rf <path>.If another workspace rewrote the revision your workspace was editing, the next jj command will report the working copy as stale. Resolve with:
jj workspace update-stale
This resyncs files to the current operation's working-copy commit. If prior state would otherwise be lost, jj preserves it as an automatic recovery commit — don't force-reset.
When the workspace's work is integrated or abandoned:
# From anywhere in the repo
jj workspace forget <workspace-name>
rm -rf <workspace-path>
jj workspace forget unregisters the workspace from the repo; removing the directory is a separate manual step. Running them in either order is fine, but both must happen or jj workspace list will keep showing a ghost entry.
| Situation | Action |
|---|---|
| Not a jj repo | jj git init --colocate or use using-git-worktrees |
Existing <repo>-workspaces/ sibling | Use it |
| No layout, no CLAUDE.md | Ask user |
| About to add workspace | jj new first for clean base |
| Different starting revision needed | jj workspace add -r <rev> <path> |
| Want a different workspace name than dir | jj workspace rename <old> <new> after add |
| "Working copy is stale" error | jj workspace update-stale |
| Done with workspace | jj workspace forget <name> + rm -rf <path> |
| Lost track of workspaces | jj workspace list |
jj log.../<name> or an absolute path outside the repo tree.jj workspace forgetjj log and jj workspace list show a phantom.jj workspace forget <name> when tearing down.jj workspace update-stale resolves it safely; jj preserves prior state in a recovery commit when needed.jj new firstjj new before jj workspace add, unless deliberately branching from a specific revision with -r.You: I'm using the using-jj-workspaces skill to set up an isolated workspace.
[jj workspace root → /Users/jesse/myproject]
[Parent: /Users/jesse, repo_name: myproject]
[No existing *-workspaces directory; no CLAUDE.md preference]
[Ask user → chose "sibling" pattern]
[jj new] # clean shared base
[jj workspace add ../myproject-auth] # adds workspace, name "myproject-auth"
[cd ../myproject-auth]
[jj workspace root → /Users/jesse/myproject-auth]
[npm install]
[npm test → 47 passing]
Workspace ready at /Users/jesse/myproject-auth (name: myproject-auth)
Tests passing (47 tests, 0 failures)
Ready to implement auth feature
Never:
jj workspace forget.Always:
jj new before jj workspace add (unless -r <rev> is specified deliberately).jj workspace update-stale when jj reports staleness.Called by (natively):
Intercepts (in jj repos):
jj workspace root succeeds, use this skill instead. Translate worktree vocabulary to workspace vocabulary via the mapping table.Pairs with:
jj workspace forget <name> + rm -rf <path>.jj workspace root fails and you're not going to colocate with jj git init --colocate.Provides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub antstanley/skills --plugin jj-workspaces