Reusable jj + Claude Code workflow template — per-session snapshot management for concurrent AI agents
Find a file
2026-03-21 11:30:08 -06:00
.claude/commands chore: initial jj + claude code workflow template 2026-03-21 11:30:08 -06:00
scripts chore: initial jj + claude code workflow template 2026-03-21 11:30:08 -06:00
INTEGRATION.md chore: initial jj + claude code workflow template 2026-03-21 11:30:08 -06:00
README.md chore: initial jj + claude code workflow template 2026-03-21 11:30:08 -06:00

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-wip consolidates accumulated wip commits into one for cleaner history
  • Repo cleanup: /repo-cleanup Claude command organizes wip commits into themed conventional commits

Prerequisites

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.