Skip to content

Instantly share code, notes, and snippets.

@paulsmith
Created March 10, 2026 18:08
Show Gist options
  • Select an option

  • Save paulsmith/78ecc108b5ba325e4867839cd3ec2359 to your computer and use it in GitHub Desktop.

Select an option

Save paulsmith/78ecc108b5ba325e4867839cd3ec2359 to your computer and use it in GitHub Desktop.
Claude Code skill for maintaining my jjify patchset on superpowers
name description
superpowers-fork
Use when syncing Paul's jj fork of obra/superpowers with upstream, rebasing the jjify patchset, or reviewing upstream for new git references that need converting to jj equivalents. Use when Paul says to update superpowers, sync the fork, or rebase jjify.

Maintaining the Superpowers jj Fork

Sync Paul's jj-adapted fork of obra/superpowers with upstream and maintain parity. The fork replaces all Git-specific commands and workflows with jj equivalents.

REQUIRED: Use the jj-workflow skill for all VCS operations.

Fork Structure

Component Value
Upstream remote upstream (https://github.com/obra/superpowers.git)
Fork remote origin (git@github.com:paulsmith/superpowers.git)
Upstream tracking bookmark main (tracks main@upstream)
Patch series bookmark jjify (tip of the jj conversion patches)
Repo location ~/projects/superpowers

The jjify bookmark points to the tip of a linear patch series that sits on top of main. These patches convert Git concepts throughout the superpowers skills to jj equivalents.

Sync Workflow

0. Pre-flight

Verify a clean working copy before starting. If @ has uncommitted work, create a new empty change or finish the current work first.

jj st
jj log --limit 5

Note where main currently points — you'll need this for the parity review later.

1. Fetch upstream

jj git fetch --remote upstream

2. Check what's new

jj log -r 'main..main@upstream'

If main already equals main@upstream, there's nothing to sync.

3. Rebase the jjify patches

Identify the bottom of the patch series (first Paul-authored commit above main) and rebase the whole range:

# Find the base patch
jj log -r 'main::jjify'

# Rebase from the bottom patch onto the new upstream
jj rebase -s <bottom-patch-change-id> -d 'main@upstream'

4. Resolve conflicts

After rebase, check for conflicts:

jj log -r 'main@upstream::jjify'  # × marks conflicted commits

If no conflicts, skip to step 5.

For each conflicted commit, starting from the earliest:

jj new <conflicted-change-id> -m "resolve conflicts"
# Edit files to remove conflict markers
jj squash --into <conflicted-change-id> -u

Resolution principle: preserve the jj-ified intent of each patch. If a patch removed "to git" from a phrase and upstream rewrote that phrase, apply the same spirit to the new text.

.claude-plugin/plugin.json version field — this conflicts on every upstream release. Resolution: use upstream version with jj suffix (e.g., 6.0.06.0.0jj).

5. Advance the main bookmark

jj bookmark set main -r 'main@upstream' --allow-backwards

After this, main::jjify shows the clean patch series on top of the new upstream.

6. Clean up

Abandon any orphaned commits (old upstream commits no longer in the ancestry of jjify), divergent empty working-copy copies, and leftover resolution commits:

jj log  # Look for orphaned/divergent commits outside the main::jjify chain
jj abandon <orphaned-change-ids>

Parity Review

After rebasing, review upstream changes to ensure the fork still covers everything. The goal is overall parity with upstream — Git concepts translated to jj, nothing silently diverged.

Review what upstream changed

Use the old main position noted in step 0:

jj diff --from <old-main-commit> --to main --stat

For each new or heavily modified skill file, read it and check whether it contains git-specific workflows that need a corresponding jjify patch. Also review each patch in the series (jj log -r 'main::jjify' -p) to verify they still make sense — a patch modifying a line upstream deleted is a sign it needs updating or dropping.

Scan for unconverted git references

Search skill files for git references that should be jj equivalents:

# Search for git commands in skill files (exclude .git directory)
rg -i '\bgit (commit|add|push|pull|branch|worktree|stash|checkout|switch|merge|cherry-pick|rebase|reset|log|diff)\b' skills/
rg -i '\b(commit|committed) to git\b' skills/
rg -i '\bgit branches?\b' skills/

Flag these patterns (they likely need conversion):

Pattern Conversion
git commit, git add, git push, git pull jj equivalents per jj-workflow skill
git branch / "branches" (as VCS concept) jj bookmark / "bookmarks"
git worktree / "worktrees" jj workspace / "workspaces"
git stash jj new @- pattern
git log, git diff jj log, jj diff
"commit to git", "commit with git" "commit" (remove git reference)
git checkout, git switch jj edit or jj new
git merge jj new A B
git cherry-pick jj duplicate
git rebase jj rebase
git reset jj restore or jj abandon

Ignore these (not conversions):

Pattern Reason
.gitignore jj uses gitignore natively
jj git push, jj git fetch jj's git interop layer
GitHub / github.com references The service, not the tool
git in example debugging case studies Illustrative, not instructional
Red-flag lists warning against using git Already correct
git rm --cached .jj-* in troubleshooting Legitimate git index fixup

Adding a New Conversion Patch

When the parity review finds git references that need converting:

# Work on top of jjify
jj new jjify -m "feat: convert <skill-name> to jj"

# Make the conversions
# ...

# Move jjify bookmark forward
jj bookmark set jjify -r @

Keep each patch focused: one skill or one logical group of related changes per commit.

Pushing

After sync and review are complete:

jj git push --remote origin -b main
jj git push --remote origin -b jjify

--allow-backwards may be needed for main if this is the first push after moving the bookmark.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment