Reusable jj + Claude Code workflow template — per-session snapshot management for concurrent AI agents
| .claude/commands | ||
| scripts | ||
| INTEGRATION.md | ||
| README.md | ||
jj-template
Reusable jj + Claude Code workflow template. Provides automatic per-session snapshot management so every Claude Code session's work is committed and isolated — even with concurrent agents.
What It Does
- Session start: snapshots any pre-existing uncommitted work before the agent starts editing
- Post-edit: tracks every file Claude edits (via Edit/Write/NotebookEdit tools) per-session
- Session end: commits tracked files with a descriptive
wip(claude:<session>):message, then commits any untracked leftovers - Concurrent safety: multiple agent sessions on the same repo get isolated, file-scoped commits
- Orphan reaping: dead sessions (crashed CLI) are cleaned up automatically via PID liveness checks and 2h timeout
- Squash:
squash-wipconsolidates accumulated wip commits into one for cleaner history - Repo cleanup:
/repo-cleanupClaude command organizes wip commits into themed conventional commits
Prerequisites
- jj (Jujutsu VCS)
- jq (JSON processor)
- Claude Code CLI
Quick Start
See INTEGRATION.md for step-by-step instructions to add this to an existing or new project.
Files
scripts/
_lib.sh # Shared utilities (REPO_ROOT resolution)
jj-hook.sh # Main hook script (all 6 actions)
test-jj-hooks.sh # 26-test integration suite
.claude/
settings.local.json # Hook configuration for Claude Code
commands/
repo-cleanup.md # /repo-cleanup slash command
Manual Commands
# Check active sessions for this repo
./scripts/jj-hook.sh status
# Squash all wip commits between main and @ into one
./scripts/jj-hook.sh squash-wip
# Force-reap all non-alive sessions
./scripts/jj-hook.sh reap
How It Works
Tracking Files
Each active session gets a tracking file at /tmp/jj-claude-{REPO_ID}-{SESSION_ID}-files. The REPO_ID is a cksum of the repo root path, preventing cross-repo contamination. A companion -pid file records the parent process for liveness checking.
Commit Flow
session-start (startup) → snapshot pre-existing work
→ initialize empty tracking file
→ reap stale/orphaned sessions
post-edit (per file) → append relative path to tracking file (dedup)
session-end → commit tracked files (file-scoped)
→ commit untracked leftovers (if sole session)
→ clean up tracking + PID files
Concurrency
When multiple Claude sessions edit the same repo simultaneously:
- Each session tracks its own files independently
- Session A ending only commits files A touched
- Untracked changes (Bash-created files) are only committed when the last session ends
- If both sessions touch the same file, the first to end commits it; the second skips it (no diff remaining)
Tests
scripts/test-jj-hooks.sh
Runs 26 integration tests in temporary jj repos. Requires jj and jq. Portable across macOS and Linux.