Pr
One skill for committing work and opening PRs, built around stacked PRs. Bare /pr (or $pr in Codex) checkpoints the current diff as the next branch in a stack; subcommands publish the stack (submit), rebase it onto trunk (sync), walk every PR as annotatable Markdown plus exact patches (walk), and land it bottom-up (merge). Update covers the single-branch case — commit and refresh the current branch's PR. Any PR can be opened as a draft with --draft (-d), or make drafts the default with setup. Also ships an optional diff-size nudge hook when the uncommitted diff grows large; enable it explicitly with setup nudge. Agent-callable — an agent working through a task should invoke this to ship a finished slice — `checkpoint`/`commit` at each logical seam to land a stacked PR and continue on a fresh branch, or `update` to commit and refresh the current branch's single PR. Reach for it when a unit of work is complete or the user asks to commit, push, checkpoint, open a PR, or review/walk a PR stack. Do not autonomously run `merge` (it lands PRs into trunk) unless the user asks. Runs under Claude Code, Codex, Delta, and Gemini CLI. Uses GitHub's first-party gh-stack extension for git repositories. Optional Jujutsu (jj) backend for colocated repos. Invoke via /pr [subcommand] [args] in Claude Code and Gemini CLI, or $pr [subcommand] [args] in Codex and Delta.From its SKILL.md
npx -y skills add zcaceres/skills --skill prAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 7 stars7 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
16.1 KB, as published. Nobody here has run it
PR — One Skill
Commit your work and ship it as stacked PRs with /pr. Each bare /pr
slices the current diff onto a new branch stacked on the last one;
subcommands push the whole stack (submit), rebase it onto trunk
(sync), review it as annotatable Markdown with colorized git-delta
rendering (walk), and merge it bottom-up (merge). /pr update covers
the single-branch case — commit and refresh the current branch's PR.
Any PR this skill creates can be a draft: pass --draft (or
-d) on the invocation, or make drafts the default everywhere with
/pr setup (writes git config pr.draft true).
Draft is orthogonal to everything else — it works on every subcommand
that creates a PR.
Usage: /pr [subcommand] [args] in Claude Code and Gemini CLI;
$pr [subcommand] [args] in Codex and Delta.
$ARGUMENTS is parsed by the dispatcher below. Read the matched
subcommand's reference file and follow it exactly.
If the host does not substitute a literal $ARGUMENTS variable (including
Codex and Delta), treat the text following the skill invocation as $ARGUMENTS.
Determine the backend first
Before anything else, resolve which VCS backend drives the workflow:
git config pr.backend 2>/dev/null # resolves local, then global; empty = unset
- Output
jj→ jj backend. - Empty AND
.jj/exists at the repo root ([ -d "$(git rev-parse --show-toplevel)/.jj" ]) → jj backend (the user colocated by hand). - Anything else — including an explicit
git— → git backend (the default).
The backend only changes which workflow reference is read. The git backend uses GitHub's first-party gh stack extension and
reads references/git/<keyword>.md; the jj backend uses the matching command
section in references/jj.md. setup, walk, and
recovery.md are shared; title-convention.md is Jujutsu-only. Draft semantics are
identical in both backends. The jj backend is colocated-only (jj working
alongside .git in the same checkout) — /pr setup
wires it with /pr setup jj.
Determine draft intent
Resolve, once, whether a PR you create this run should be a draft. Per-invocation flags always win over the configured default:
-
The dispatcher strips draft flags from
$ARGUMENTSbefore matching a subcommand (see below). If--ready/--no-draftwas present → ready. Else if--draft/-dwas present → draft. If both appear, the last one on the line wins. -
No per-invocation flag → read the default:
git config pr.draft 2>/dev/null # resolves local, then globalOutput
true→ draft. Anything else (including empty) → ready.
Carry the resolved answer (draft or ready) into the matched
subcommand. It only affects PR creation — a single-PR gh pr create gets
--draft for draft intent; gh stack submit uses --auto for draft or
--auto --open for ready. An explicit per-invocation flag may also flip an
already-open single PR (gh pr ready / gh pr ready --undo); the configured
default never does — see the matched backend's update workflow.
Subcommands
| Subcommand | Reference | What it does |
|---|---|---|
commit [message] | (alias) | Alias for the default action — checkpoint, with the message as the slice description. The everyday "ship my work" verb; identical to bare /pr. |
setup | references/setup.md | Show and change the persistent settings: the draft default (pr.draft) and the backend (pr.backend, git ↔ jj). Global by default (the backend is always local-scope). The optional nudge hook is enabled only with an explicit /pr setup nudge. |
update [base-branch] | git · jj | Commit + push + update the current branch's PR (or open one if missing). The single-branch flow; doesn't change an existing PR's base. |
log | git · jj | Read-only. Print the stack tree with each branch's PR status (a branch that isn't stacked renders as a one-branch stack). |
walk [PR-number-or-URL] | references/walk.md | Build numbered Markdown + exact-patch review artifacts with one notes area per open PR, render each complete PR in conversational mode with colorized git-delta diffs and structured controls, collect notes bottom-to-top, then apply the approved stack-wide plan and sync it to GitHub. Use --resume <session-dir> to continue a packet. |
merge [--merge|--rebase|--squash] [--all] [--dry-run] | git · jj | Land the stack through GitHub's stack-aware merge command on the git backend (a lone branch is just a one-branch stack). |
checkpoint [slice description] | git · jj | Cut the current uncommitted diff as the next local branch in a stack. Build repeated layers, then submit them together. This is the default action. |
submit [--draft] | git · jj | Publish point. Push the whole stack and create/update one PR per branch, linked in GitHub's native stack UI. --draft opens newly created PRs as drafts. Requires GitHub's gh stack extension on the git backend; the jj backend needs no extra binary. |
sync [--no-push] | git · jj | Synchronize the stack with GitHub; --no-push performs the cascade rebase locally for review first. |
Native GitHub stack representation
On the git backend, gh stack submit links the pull requests into GitHub's
native stacked-pull-request object. GitHub displays their order and navigation,
so /pr must not encode layer numbers in PR titles or maintain a parallel stack
representation.
Git stack invariants
Treat a stack as one linear history. Only its bottom branch is based on trunk;
every higher branch and PR is based on the branch directly below it. Create
layers from bottom to top with gh stack add—never create each branch
independently from trunk.
Put a change on the lowest layer where it logically belongs. After changing a
layer that has descendants, immediately run gh stack rebase --upstack, then
publish the rewritten branches with gh stack push. A top-layer-only change
needs only gh stack push. Prefer a new review-fix commit over repeatedly
amending or squashing a lower commit, because rewriting lower commits changes
every descendant.
Use stack-aware operations throughout:
- Synchronize with trunk using
gh stack sync. Do not merge trunk into a stack branch, run an unqualifiedgit pullthere, or rebase every branch independently onto trunk. - Resolve a stopped cascade, stage the resolved files, then use
gh stack rebase --continue; abandon it withgh stack rebase --abort. - Push rewritten branches with
gh stack push, which applies force-with-lease safety. Never usegit push --force. - Merge with
gh stack merge, nevergh pr merge. After merging, usegh stack sync --prunefor a fully landed stack orgh stack syncafter a partial merge. - Never manually retarget stacked PRs or maintain stack metadata outside
gh stack.
Optional bundled hook
A diff-size nudge hook is shipped with this skill. It fires after every
file-modifying tool call and nudges toward /pr when the uncommitted
diff crosses size/file thresholds — so you land a focused PR (a stacked
checkpoint) before the diff grows unwieldy. The same hook binary runs
under Claude Code (PostToolUse;
Edit/Write/MultiEdit/NotebookEdit), Codex (PostToolUse;
apply_patch), and Gemini CLI (AfterTool; replace/write_file).
It identifies the host from the hook payload and adapts. Only the config
wiring differs, and install.sh --agent handles that. Delta does not load
Claude/Codex hook configuration, so its /pr workflow is supported but the
optional nudge hook is unavailable there.
The hook is opt-in. Installing the skill does not register it, and
ordinary /pr setup operations for drafts or backends must not register
or provision it. Enable it explicitly with /pr setup nudge, or run the
installer directly after installing the skill:
npx skills add zcaceres/skills -s pr
~/.claude/skills/pr/scripts/install.sh # Claude Code (default)
# or, for Codex:
~/.codex/skills/pr/scripts/install.sh --agent codex
# or, for Gemini CLI:
~/.gemini/skills/pr/scripts/install.sh --agent gemini
The second step wires the hook into the host's hook config so it fires on
every matching tool call, not just when the skill is active in context.
install.sh auto-detects the host (override with
--agent claude|codex|gemini) and writes the right event name, tool
matcher, and config path (settings.json for Claude/Gemini; hooks.json
for Codex). The script self-locates, so the same command works whether
the skill was installed at user scope or project scope. Codex users must
review and trust the new command hook with /hooks. Flags: --agent,
--project, --target PATH. Requires jq. See
references/nudge.md for thresholds, env-var
overrides, and manual wiring as an alternative.
install.sh also provisions the compiled binary the hook execs (a
file-copy install ships the source but not the ~60 MB binary) by
running scripts/fetch-binary.sh — which downloads the prebuilt binary
for your platform from the skill's GitHub release, or builds it with
bun. /pr setup nudge runs install.sh for you, inferring --agent
from the host it's running in. See
references/nudge.md.
Dispatcher
First read the backend (see "Determine the backend first" above). For a
workflow command, read references/git/<keyword>.md on the git backend or
the matching command section in references/jj.md on the jj backend.
setup and walk are always shared.
setup is exempt from the next step. If the first non-flag token of
$ARGUMENTS is setup, skip draft-flag stripping and dispatch straight
to setup.md with the raw $ARGUMENTS — there,
draft/--draft/no-draft/ready mean "which default to write", not
per-run intent.
Otherwise, extract draft flags from $ARGUMENTS wherever they appear
and remove them from the token stream, recording the draft intent (see
"Determine draft intent" above):
--draft/-d→ draft.--ready/--no-draft→ ready (overrides apr.draft truedefault).
These are not subcommands and never consume the subcommand slot —
/pr --draft, /pr update --draft, and /pr -d "fix bug" all dispatch
to the default/named action with draft intent set. After stripping them,
parse the first remaining whitespace-separated token of $ARGUMENTS:
-
First token is
setup→ read references/setup.md and follow it. This is how the user changes the persistent settings. -
First token is
walk→ read references/walk.md and follow it with the remaining$ARGUMENTS. This workflow is shared across backends because it operates on published GitHub PRs. -
First token is
update,log,merge,checkpoint,submit, orsync→ read the matched backend workflow described above, then follow it with the remaining$ARGUMENTSas that subcommand's arguments. -
First remaining token starts with
-(e.g.--help,-h) → print this subcommand list and stop. (Draft flags were already stripped in the pre-parse step, so they never land here.) -
First token is
commit, anything else, OR$ARGUMENTSis empty → the default action: read the matched backend'scheckpointworkflow and follow it, using the message as the slice description.When the first token is literally
commit, strip it and pass the remaining$ARGUMENTSas the slice description. For any other non-keyword first token, the full$ARGUMENTSstring seeds the slice description.So
/pr≡/pr commit≡/pr checkpoint— no need to type the keyword for the everyday action.
If the agent is unsure what the user wants — e.g. the first token is ambiguous between a subcommand and a description — ask the user before acting. Don't guess at workflow-changing inputs.
Important — applies to every subcommand
- NEVER commit files you didn't modify in this conversation.
- NEVER use
git add .orgit add -A. Stage explicitly. - Prefer small, coherent PRs even when
/pris invoked on a large body of completed work. Before committing or publishing, partition the diff by reviewer-meaningful concern, not just by line or file count. Mechanical renames/refactors, documentation, and behavior/business-logic changes are separate slices unless one is required to understand or validate another. Keep directly coupled tests with the behavior they verify. If the diff mixes concerns, do not put all of it in one PR: propose an ordered stack, confirm it with the user, then checkpoint each concern independently. Size is only a signal—a large coherent change may stay together, while tiny unrelated changes should be split. - Order the stack to orient the reviewer early. Prefer an initial tracer-bullet slice that demonstrates the high-level direction, or a small foundation such as interface definitions, initial types, or a README/design document that makes later implementation slices easier to understand. Then order the remaining slices by dependency while keeping each independently reviewable; do not move incidental cleanup earlier merely because it was authored first.
- Keep each PR note concise and proportional to its small slice: explain its purpose, important choices, and validation without repeating the diff. Give the bottom PR a slightly fuller stack overview that previews the intended direction and the layers that follow; later PR notes should focus on their own incremental concern and mention dependencies only when useful.
- Report the PR URL when done.
- When an agent invokes this itself (not a direct
/prfrom the user):checkpoint,commit,update, andsubmitare fair game at a logical seam — that's the point of being agent-callable. Butmergelands PRs into trunk and is irreversible; run it only when the user explicitly asks. Never invokesetup(it flips the user's persistent settings) on your own. - (git backend) Require GitHub's first-party
gh stackextension; do not fall back to hand-rolled branch metadata orgh prloops for a stack. - (jj backend) No extra binary is needed — jj itself is the stack primitive (ancestry replaces Git metadata; one rebase restacks everything).