packages/jut/skill/SKILL.md
Jujutsu version control through jut, a human and agentic framework around jj. Use for: check status, view changes, commit work, create branches, push, pull, create PRs, squash commits, reword messages, absorb changes, undo operations, view history. Complements jj — use jut for opinionated workflows, drop into raw jj for everything else.
npx skillsauth add edmundmiller/dotfiles jutInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use jut as the primary interface for jj version control. jut is a thin opinionated layer — not a replacement. Drop into raw jj for anything jut doesn't cover.
jut status --json to get workspace state, stack structure, and change IDs.--json --status-after.jut status --json output (short_id field) to reference revisions.--status-after, do not run redundant jut status.jj for interactive commands (split, resolve, diffedit, edit, rebase) — jut intentionally does not wrap these.jut status, jut log, or jut show output first.add/stage commands.jut branch <name> --stack to chain them.jut commit (or jj new) to start the next one. This is NOT git's "stage → commit" model.# 1. Understand workspace state
jut status --json
# 2. Perform mutations with structured feedback
jut <command> --json --status-after
# 3. For complex operations, drop into jj
jj split -r <rev>
jj rebase -r <rev> -d <dest>
jut status # Workspace state: stacks, bookmarks, files
jut status -f # Include file-level details
jut status -v # Verbose: author + timestamps
jut log # Revision history (default: 20)
jut log -n 50 # More revisions
jut log --all # All revisions
jut diff # Working copy diff
jut diff <rev> # Diff of specific revision
jut show <rev> # Revision details
jut show <rev> -v # With inline diff
jut commit -m "message" # Describe @ + create new empty change
jut commit # Opens editor for message
jj's model: the working copy is always a commit. jut commit describes it and creates a new empty change on top — like jj commit.
jut branch <name> # Create branch from trunk + new change
jut branch <name> --stack # Stack: branch from @ (dependent work)
jut branch <name> --from <rev> # Branch from specific revision
jut branch -l # List branches (same as status)
jut branch -d <name> # Delete branch
jut branch --rename <old> <new> # Rename branch
rub is the universal "combine two things" verb (from GitButler). It replaces several jj commands based on what SOURCE and TARGET are:
jut rub <source> <target> # Or: jut <source> <target>
| SOURCE → TARGET | Action | jj equivalent |
| ------------------- | ---------------------- | ------------------------------------- |
| file → revision | Amend file into commit | jj squash --into <rev> <file> |
| file → zz | Discard file changes | jj restore <file> |
| revision → revision | Squash into target | jj squash --from <src> --into <tgt> |
| revision → zz | Abandon revision | jj abandon <rev> |
zz is the discard target — the trash can.
jut squash # Squash @ into parent
jut squash <rev> # Squash <rev> into its parent
jut squash <from> <into> # Squash <from> into <into>
jut squash <from> <into> -m "x" # With new message
jut reword <rev> -m "new msg" # Edit commit message
jut reword <rev> # Opens editor
jut discard <file> # Restore file (discard changes)
jut discard <rev> # Abandon revision
Auto-detects whether target is a file path or revision ID.
jut absorb # Auto-amend changes into the right commits
jut absorb --dry-run # Show plan without applying
jut push # Push all bookmarks
jut push <bookmark> # Push specific bookmark
jut pull # Fetch + rebase onto trunk
jut pull --clean # Also delete merged bookmarks
jut pull --no-rebase # Fetch only
jut pull --dry-run # Show plan
jut pr # Create PR for current bookmark (via gh)
jut pr <bookmark> # Create PR for specific bookmark
jut pr -m "title\nbody" # With message
jut undo # Undo last operation
jut oplog # View operation history
jut oplog -n 20 # More operations
jut oplog restore <op-id> # Restore to previous state
All commands support --json (or -j). Key shapes:
jut status --json{
"trunk": { "change_id": "...", "short_id": "...", "bookmarks": ["main"], ... },
"stacks": [
{
"bookmarks": ["feature-x"],
"revisions": [
{
"change_id": "abc123...",
"commit_id": "def456...",
"short_id": "abc",
"description": "add feature x",
"bookmarks": ["feature-x"],
"is_empty": false,
"is_working_copy": true,
"is_conflicted": false,
"is_immutable": false,
"parent_change_ids": ["..."],
"author": "[email protected]",
"timestamp": "2026-02-10 13:00",
"files": [{ "status": "M", "path": "src/main.rs" }]
}
]
}
],
"working_copy": null,
"uncommitted_files": [],
"shared_base": []
}
jut log --json{
"revisions": [
{ "change_id": "...", "short_id": "...", "description": "...", "bookmarks": [...], ... }
]
}
jut pull --json{
"fetched": true,
"rebased": true,
"merged_bookmarks": ["old-feature"],
"cleaned_bookmarks": [],
"conflicts": []
}
jut pr --json{
"created": true,
"bookmark": "feature-x",
"pr_url": "https://github.com/user/repo/pull/42"
}
jut pull --clean --json --status-after
jut branch my-feature --json --status-after
# ... make changes ...
jut commit -m "implement feature" --json --status-after
jut branch part-2 --stack --json --status-after
# ... make changes ...
jut commit -m "part 2" --json --status-after
DO THIS — three stacked commits, each reviewable independently:
jut branch auth --json --status-after
# ... write auth code ...
jut commit -m "add authentication" --json --status-after
jut branch profile --stack --json --status-after
# ... write profile code ...
jut commit -m "add user profiles" --json --status-after
jut branch settings --stack --json --status-after
# ... write settings code ...
jut commit -m "add settings page" --json --status-after
NOT THIS — one giant commit (git muscle memory):
# WRONG: dumping everything into one commit
# ... write all files ...
jj describe -m "add auth, profiles, and settings"
Each logical unit of work should be its own commit in a stack. This enables independent review, selective rollback, and clean history.
jut push --json --status-after
jut pr --json
jut status --json # Find the file and target revision short_id
jut rub <file> <rev> --json --status-after # Amend file into that commit
jut rub <file> zz --json --status-after
# or equivalently:
jut discard <file> --json --status-after
jut rub <rev> zz --json --status-after
# or equivalently:
jut discard <rev> --json --status-after
jut pull --clean --json --status-after
jut undo --json --status-after
# If you need to go further back:
jut oplog --json # Find the operation
jut oplog restore <op-id> --json --status-after
jut status --json # Get the revision ID
jj split -r <rev> # Interactive split in jj
jut status --json # Refresh state
jj rebase -r <rev> -d <dest>
jut status --json # Refresh state
jut status --json # See conflicted revisions (is_conflicted: true)
jj resolve -r <rev> # Interactive merge tool
jut status --json # Verify resolution
jut intentionally skips these — use raw jj:
| Command | Why |
| ------------------------ | ------------------------------------------------ |
| jj split | Interactive editor — can't improve on it |
| jj edit <rev> | Trivial one-liner |
| jj rebase | Complex revset args — wrapping loses flexibility |
| jj resolve | Interactive merge tool |
| jj diffedit | Interactive editor |
| jj next / jj prev | Trivial navigation |
| jj new | Covered by jut commit and jut branch |
| jj describe | Covered by jut reword |
| jj abandon | Covered by jut discard |
| jj bookmark (advanced) | jut branch covers common cases |
| jj config | Config management, not a repo operation |
Read-only jj commands are always fine alongside jut (jj log, jj evolog, jj show, jj diff).
@) is always a revision. jut commit describes it and creates a new one.short_id from JSON output is the shortest unique prefix — use these for brevity.rub is positional: jut <source> <target> works without the rub subcommand.zz is the universal discard target for rub.--status-after returns the full workspace state after mutation — eliminates a round-trip.jut skill check as routine preflight.jut skill check when command behavior diverges from this skill.jut skill check --update.references/reference.md.references/concepts.md.references/examples.md.development
Read-only Linear issue access via the Linear GraphQL API.
data-ai
## <!-- Purpose: Teach agents fast day-to-day memory browse/search/read/sync workflows in pi-context-repo. --> name: searching-memory description: > Search, browse, and inspect memory quickly in pi-context-repo. Use when asked to find prior notes, inspect memory files, locate preferences, or sync recent memory updates. Trigger phrases: "search memory", "list memory files", "find in memory", "read memory file", "memory status", "sync memory". --- # Searching Memory Use this workflow for fast
development
Comprehensive guide for initializing or reorganizing agent memory into a deeply hierarchical file structure. Use when running /init, when user asks to set up memory, or when memory needs a major reorganization. Trigger phrases: "initialize memory", "set up memory", "populate memory", "build my memory", "memory init".
data-ai
Decomposes and reorganizes agent memory files into focused, single-purpose components. Use when memory has large multi-topic blocks, redundancy, or poor organization. Trigger phrases: "defrag memory", "reorganize memory", "clean up memory files", "split memory blocks".