Learn how to use Spec Kitty with Jujutsu (jj) for better multi-agent parallel development. This tutorial walks you through a complete workflow from project initialization to feature completion.
Time: 30-45 minutes
What You’ll Learn:
Before starting this tutorial, ensure you have:
jj --version
# Expected: jj 0.20.0 or higher
If not installed, see the jj installation guide.
spec-kitty --version
# Expected: 0.12.0 or higher
If not installed, see Install Spec Kitty.
This tutorial uses Claude Code, but any supported agent works.
You will need a terminal such as macOS Terminal, Windows PowerShell, or a Linux shell.
Create a new Spec Kitty project. When jj is available, Spec Kitty automatically uses it.
spec-kitty init my-jj-project --ai claude
You’ll see output like:
Spec Kitty Project Initializer
✓ Detected jj (0.24.0) - using jujutsu for version control
✓ Created .jj/ repository in colocated mode
✓ Created .git/ for compatibility
✓ Initialized .kittify/ configuration
✓ Installed Claude Code slash commands
Your project is ready at: my-jj-project/
When both jj and git are available, Spec Kitty uses colocated mode:
my-jj-project/
├── .jj/ # Jujutsu repository (primary)
├── .git/ # Git repository (for compatibility)
├── .kittify/ # Spec Kitty configuration
└── .claude/ # Claude Code commands
This means:
git push to GitHubTo explicitly choose git instead of jj:
spec-kitty init my-git-project --ai claude --vcs git
Now let’s create a feature and implement it using jj workspaces.
Jujutsu uses native workspaces (not git worktrees). Spec Kitty still places them under .worktrees/ for consistency across VCS choices.
Change into your project and create a specification:
cd my-jj-project
Use the /spec-kitty.specify slash command in Claude Code to describe your feature:
/spec-kitty.specify Add a user profile page with avatar upload
Follow the prompts to create spec.md with requirements.
Create your implementation plan:
/spec-kitty.plan
Generate work packages:
/spec-kitty.tasks
This creates tasks like:
WP01 - Setup database modelsWP02 - Create API endpointsWP03 - Build frontend componentsCreate a workspace for WP01:
spec-kitty implement WP01
Output:
Implement WP01
├── ● Detect feature context (Feature: 001-user-profile)
├── ● Validate dependencies (none)
└── ● Create workspace
✓ Created workspace at .worktrees/001-user-profile-WP01/
✓ Created jj workspace 'WP01' with change ID: xyz123abc
Next steps:
cd .worktrees/001-user-profile-WP01/
Run /spec-kitty.implement to start coding
Navigate to your workspace and implement the feature:
cd .worktrees/001-user-profile-WP01/
The workspace is isolated - you can make changes without affecting main.
This is where jj shines! When upstream changes occur, jj automatically rebases your work.
Imagine this parallel development scenario:
main ─────────────────────────────────────────→
↓
WP01 ─── (you're working here)
↓
WP02 ─── (another agent is working here)
When WP01 completes and merges, WP02 needs to incorporate those changes.
From your workspace, run:
spec-kitty sync
With jj, you’ll see:
Sync Workspace
├── ● Fetch upstream changes
├── ● Auto-rebase local changes
└── ● Update workspace state
✓ Synced successfully
Rebased 3 commits onto new upstream
No conflicts detected
Key difference from git: With jj, sync always succeeds. If there are conflicts, they’re stored in the files for later resolution - work continues uninterrupted.
With git, the same sync might produce:
error: Your local changes would be overwritten by merge
hint: Please commit or stash them
You’d have to stop, resolve conflicts, then continue. With jj, you keep working.
When sync detects conflicts, jj stores them in your files rather than blocking you.
After a sync with conflicts:
spec-kitty sync
Sync Workspace
├── ● Fetch upstream changes
├── ● Auto-rebase local changes
└── ● Update workspace state
✓ Synced successfully
Rebased 2 commits onto new upstream
⚠ 1 file has conflicts (resolve when ready)
Your work continues! The conflicts are marked in the file:
# src/models/user.py
class User:
<<<<<<< Working copy
avatar_url: str
avatar_size: int
=======
avatar_url: Optional[str]
>>>>>>> Parent commit
# Edit the file to resolve conflicts
# Then let jj know it's resolved
jj resolve
View current conflicts:
spec-kitty ops log --verbose
Operation Log
─────────────────────────────────────────────────
abc123 rebase 2 minutes ago ⚠ conflicts in src/models/user.py
def456 edit 5 minutes ago Clean
ghi789 fetch 7 minutes ago Clean
See Also: Handle Conflicts (jj) for detailed resolution strategies.
When your work is ready, complete the review cycle and merge.
From your workspace:
/spec-kitty.review
This:
for_review laneAfter review approval:
/spec-kitty.accept
This:
done laneFinally, merge your completed work:
spec-kitty merge --push
Merge Feature
├── ● Validate all WPs complete
├── ● Merge 001-user-profile-WP01 → main
├── ● Clean up workspace
└── ● Push to origin
✓ Feature 001-user-profile merged successfully
Throughout this process, jj maintains stable Change IDs. Even after multiple rebases, your changes have the same identity:
Change ID: xyz123abc
↳ Commit abc001 (initial)
↳ Commit def002 (after rebase 1)
↳ Commit ghi003 (after rebase 2) ← Same Change ID!
This makes tracking work across multiple agents and rebases much easier.
One of jj’s most powerful features is its operation log with full undo capability.
See what operations have been performed:
spec-kitty ops log
Operation Log (last 20)
─────────────────────────────────────────────────
ID Type When Status
─────────────────────────────────────────────────
abc123 rebase 2 minutes ago Clean
def456 commit 5 minutes ago Clean
ghi789 fetch 10 minutes ago Clean
jkl012 commit 15 minutes ago Clean
Made a mistake? Undo the last operation:
spec-kitty ops undo
Undo Operation
├── ● Identify last operation (abc123: rebase)
└── ● Restore previous state
✓ Undone operation abc123
Repository restored to state before rebase
Jump back to any previous operation:
spec-kitty ops restore def456
Restore Operation
├── ● Load operation def456
└── ● Restore repository state
✓ Restored to operation def456
State from: 5 minutes ago
Important: The
ops undoandops restorecommands are jj only. Git users see the operation log (via reflog) but cannot undo operations through Spec Kitty.
See Also: Use Operation History for advanced recovery scenarios.
You’ve completed your first feature using Spec Kitty with jujutsu. You’ve learned:
Continue learning with these resources:
Ensure jj is installed and in your PATH:
which jj
# Should show: /usr/local/bin/jj or similar
If a feature was started with git, it continues using git. Create a new feature to use jj:
spec-kitty init new-project --vcs jj
This is expected with jj! Conflicts are non-blocking. See Handle Conflicts (jj) for resolution.
The ops undo command requires jj. Git projects use git reflog for history but cannot undo through Spec Kitty.