Using jj
The best skills for AI coding agents. I'm only creating AI agent skills here because the existing skills I could find weren't good enough. So, as far as I can tell the skills I'm adding here are the best.
npx -y skills add WebDevBooster/best-skills --skill using-jjAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Workspace-first Jujutsu workflow for coding agents. Use when working in a jj repo, coordinating parallel agent work, moving changes between workspaces, landing selected work onto trunk, publishing bookmarks, or recovering from rewrites and stale workspaces.
SKILL.md
9.2 KB, as published. Nobody here has run it
Using jj for parallel coding agents
Use this skill when the repository is using Jujutsu (jj) as the primary mutating VCS interface.
This skill is opinionated. It is written for coding agents, not for humans exploring jj casually.
Default assumptions:
- trunk bookmark is
main - default remote is
origin - one agent = one
jj workspace - use
jjfor mutations, notgit - prefer non-interactive commands
If the repo clearly uses a different trunk bookmark, use that instead of main.
Quick start
# 1) Sync remote state
jj git fetch
# 2) Create a dedicated workspace for this agent
jj workspace add ../repo-agent-<name> --name agent-<name> -r main@origin -m "agent-<name>: start from main"
# 3) Enter the workspace and inspect state
cd ../repo-agent-<name>
jj status
jj log -r 'main@origin | main | @ | @- | bookmarks()'
# 4) Start the change by describing it
jj describe -m "feat: implement <task>"
# 5) Edit files, then commit non-interactively
jj commit -m "feat: implement <task>"
# 6) Publish quickly if asked
jj git push --change @-
Non-negotiable rules
- Treat
jj workspaceas the unit of parallel agent work. - Use
jjfor mutations. Do not mix mutatinggitcommands into a jj workflow unless the user explicitly asks for that. - Never assume there is a current bookmark. jj does not have one.
- Use descriptions first. In normal agent work, start by naming the change with
jj describe -m .... - Prefer non-interactive commands. Add
-mwhen supported. - After
jj commit -m ..., the finished change is usually@-, not@. - When taking work from another workspace and you want to keep the source intact, use
jj duplicate. - Use
jj squash --from ... --into ...only when you intentionally want to adopt or consume that source change. - If a workspace becomes stale, repair it with
jj workspace update-stale. - If a rewrite goes wrong, recover with
jj undo. If needed, inspectjj op logand usejj op restore.
The mental model you must use
Think in changes, not branches
jj is not centered around “the current branch”. It is centered around changes and a working-copy commit.
@= current workspace’s working-copy commit@-= parent of the current working-copy commit<workspace>@= another workspace’s working-copy commit<workspace>@-= that workspace’s most recently committed change in the common case
Think describe-first
In this skill, treat jj as a describe-first workflow:
- first name the change with
jj describe -m "..." - then edit files
- then seal that state with
jj commit -m "..." - after commit, continue from the fresh working-copy commit at
@
The practical shortcut is that jj commit without path arguments or --interactive is effectively jj describe followed by jj new, so change description comes first in the normal flow.
Bookmarks are explicit public names
Bookmarks are for naming work that needs to be pushed, reviewed, or followed later.
Do not expect bookmarks to move automatically like Git branches. Move them explicitly with:
jj bookmark set ... -r ...jj bookmark move ... --to ...jj bookmark advance ... --to ...
Conflicts are state, not emergencies
jj can record conflicts directly in commits. That means a rebase can succeed while leaving a conflicted commit behind for later resolution.
Do not panic when conflicts appear. Inspect, resolve, continue.
Standard flow for agent work
1) Inspect first
Run these before mutating anything important:
jj status
jj log -r 'main@origin | main | @ | @- | bookmarks()'
jj workspace list
2) Start the task in a dedicated workspace
Preferred:
jj git fetch
jj workspace add ../repo-agent-<name> --name agent-<name> -r main@origin -m "agent-<name>: start from main"
Then:
cd ../repo-agent-<name>
jj status
jj describe -m "feat: <task>"
3) Implement the work
# edit files
jj diff
jj commit -m "feat: <task>"
After that, the completed change is typically @-.
4) Reshape the work if needed
Use the least destructive command that fits the job.
Fixups across a stack
# edit files in the current workspace
jj absorb
Use this when you changed files that logically belong in earlier commits.
Move one whole change into another
jj squash --from <source> --into <destination> --use-destination-message
Use this when you intentionally want the destination to absorb the source.
Split a mixed change by files
jj split path/to/file1 path/to/file2 -m "extract <part>"
Use this only when the split can be described by filesets and done non-interactively.
Rebase onto fresh trunk
jj git fetch
jj rebase -r @- -o main@origin
Use this when your change should be replayed onto current trunk.
5) Take work from another workspace
Safe copy mode
Use when you want another agent’s work without rewriting their source change.
jj duplicate agent-a@- -A @
Or duplicate after trunk:
jj duplicate agent-a@- -A main@origin
Adopt mode
Use when you are intentionally taking ownership of the source change.
jj squash --from agent-a@- --into @ --use-destination-message
Warning: this can leave the source workspace stale.
6) Publish
Fast route:
jj git push --change @-
Named bookmark route:
jj bookmark set agent/<task> -r @-
jj git push --bookmark agent/<task>
7) Land selected work onto main
Use a dedicated integration workspace.
jj git fetch
jj workspace add ../repo-integrate --name integrate -r main@origin -m "integrate selected agent work"
cd ../repo-integrate
jj squash --from agent-a@- --into @ --use-destination-message
jj squash --from agent-b@- --into @ --use-destination-message
jj commit -m "integrate selected agent work"
jj bookmark set main -r @-
Push main only if explicitly requested:
jj git push --bookmark main
Commands by job
Inspect and understand
jj status
jj log -r 'main@origin | main | @ | @- | bookmarks()'
jj show @-
jj diff
jj evolog -r @-
jj workspace list
jj workspace root --name agent-a
Start and name work
jj describe -m "feat: <task>"
jj new -m "next: <task>"
jj commit -m "feat: <task>"
Move and reshape work
jj absorb
jj squash --from <source> --into <destination> --use-destination-message
jj split <filesets> -m "extract <part>"
jj duplicate <rev> -A @
jj rebase -r <rev> -o main@origin
Workspaces
jj workspace add ../repo-agent-a --name agent-a -r main@origin -m "agent-a: start from main"
jj workspace list
jj workspace root --name agent-a
jj workspace update-stale
jj workspace forget agent-a
Bookmarks and publishing
jj bookmark set agent/<task> -r @-
jj bookmark move main --to @-
jj bookmark advance main --to @-
jj git push --change @-
jj git push --bookmark agent/<task>
Recovery
jj undo
jj redo
jj op log
jj op restore <operation-id>
jj resolve
Decision rules
Prefer jj describe when
- you are starting or renaming the current change
- you need to update the description without opening an editor
Prefer jj commit when
- you want to finalize the current working-copy change and continue from a fresh working-copy commit
Prefer jj duplicate when
- another workspace’s change should stay intact
- you want a safe local copy before integration
Prefer jj squash when
- you want one change to be absorbed into another
- you are intentionally consuming the source change into the destination
Prefer jj absorb when
- you made follow-up edits that logically belong to older commits
Prefer jj bookmark set when
- you need to create or point a bookmark by name
Prefer jj bookmark advance when
- a bookmark should follow rewritten work forward to a new target
Hard “do not do this” rules
- Do not default to Git worktrees. Use jj workspaces.
- Do not assume
mainmoved just because you committed. It did not. - Do not point bookmarks at
@afterjj commitunless you really want the fresh empty working-copy commit. - Do not mix
git commit,git rebase,git branch -f, orgit worktreeinto a normal jj workflow. - Do not use
jj splitfor a non-file-based split unless the user explicitly wants an interactive/editor flow. - Do not run
jj git push --allas a lazy default. Push the intended bookmark or change. - Do not rewrite another agent’s work unless the workflow explicitly allows adopt mode.
Specific tasks
- Mental model and describe-first:
references/mental-model.md - Workspace setup and agent coordination:
references/workspaces.md - Landing work onto trunk:
references/landing-on-main.md - Recovery, stale workspaces and conflicts:
references/recovery.md - Compatibility and mixed Git/JJ warnings:
references/compatibility-notes.md - Copy-paste recipes:
references/recipes.md