PR
Dispatch on the first argument:
create → see Create below
draft → same as Create but create a draft PR instead of a regular PR
update → see Update below
preview → see Preview below
- No argument or unknown → check if a PR exists for the current branch. If yes, run Update. If no, run Create.
An optional base=<branch> argument (any position) sets the target branch. If omitted, default to the repo's default branch. Pass via --base <branch> to gh pr create. Ignored for update and preview.
Before drafting any PR body (create/draft/update/preview): Read references/content-guidelines.md AND references/blocks.md in full. Do not draft from memory.
Classify
Run this first, before selecting blocks. Classify the change on two axes:
- TYPE (fix vs feature) — infer from Conventional Commit prefixes on the branch commits plus diff shape.
fix:/revert: lean fix; feat: leans feature.
- COMPLEXITY (simple vs complex) — infer from files touched, diff size, and whether new architecture or a changed control/data flow is introduced.
Then:
- State the result in one line, e.g.
Detected: feature + complex.
- Ask the user ONLY when signals conflict: mixed
fix/feat commits, or a diff on the simple/complex borderline. Otherwise proceed.
Template
The body is assembled from the block library, not a single fixed template.
- Take the classification's quadrant and pick the matching profile in references/blocks.md.
- Add or drop the profile's
○ blocks using the include-when rules there.
- Emit blocks in the order listed in the block library.
Do not add sections outside the block library. Keep all language succinct and concise.
Pre-Apply Check
Before gh pr create, gh pr edit, or printing a Preview body, verify the drafted body:
- Every
## heading appears in the block library in references/blocks.md (no ## Test plan, ## Testing, ## Test coverage, ## Summary, or other ad-hoc headings).
- No line numbers referenced.
- No banned wording from references/content-guidelines.md (AI vocab, hedging, filler, chatbot artifacts).
- Sentence structure (per references/content-guidelines.md): scan all prose. Flag any sentence that chains what changed + mechanism + consequence with
which/so/and, or leads with mechanism instead of the change. Split flagged sentences into what-then-why. Additionally, Key Changes sub-bullets over ~2 sentences / ~25 words (the cap in references/blocks.md) split into two bullets.
- Jargon (per references/content-guidelines.md "Glossing Jargon"): every term of art carries a one-clause appositive gloss at first use. Flag any glossed term expanded into a worked example (cut to the gloss) or re-taught on a later mention.
- No em dashes (
—) anywhere in the body, including link/label separators. Grep the drafted body for —; if any appear, replace with a colon, comma, parentheses, or separate sentence before applying.
If any check fails, revise before applying. Do not ship a body you haven't checked.
Applying the Body
For gh pr create and gh pr edit, always use --body-file with mktemp. Never --body (its subshell mangles backticks and $). No exceptions — inconsistency invites the next agent to rationalize their way back to --body.
tmp=$(mktemp -t pr-body.XXXXXX) && trap 'rm -f "$tmp"' EXIT && cat > "$tmp" <<'EOF' && gh pr create --body-file "$tmp" [flags]
[body]
EOF
Run in a single Bash call — the trap only protects the shell it's set in.
Create / Draft
- Inspect branch state and commit history (including
git log --oneline -- <changed-files> for convention patterns).
- Generate title
- Conventional Commits:
<type>(<scope>)?<!>?: <title>. Title starts lowercase. No trailing period. Omit scope when no single area dominates.
- Synthesize from branch commits
- ≤72 chars
- Should describe the change, not the symptom or task. Focus on what an affected user would interpret, not the exact code change.
- Run Classify above, then write the PR body per Template (profile + include-when rules).
- Create the PR per Applying the Body above (add
--draft for draft PRs).
- Say "PR Created: [title] [PR URL]".
Update
Steps:
- Find the existing PR for the current branch. If none exists, tell the user to run
/pr create instead.
- Run the HARD-GATE check above. Resolve before continuing.
- Inspect current branch state and any new design/plan docs since the PR was opened.
- Run Classify above, then regenerate the PR body per Template (profile + include-when rules). Preserve existing intent where still accurate; revise drifted sections.
- Apply the new body via
gh pr edit per Applying the Body above.
- Show a diff of the old vs new body, highlighting changes.
- Say "PR Updated: [PR URL]".
Scope: body only. Do not change title or draft state unless the user asks.
Red flags (rationalizations to reject)
| Thought |
Reality |
| "The body update is the main action, push is incidental" |
Push is a precondition. The body is meaningless if the commits aren't visible to reviewers. |
"User said /pr update, not /pr update and push" |
The skill defines update as inclusive of the push question. Asking is in scope. |
| "I can mention pushing in my closing summary" |
Too late. The PR is already updated against stale remote state. |
Preview
Generate the PR body and print it inline without creating, updating, or pushing anything.
Inspect branch state (same as Create).
Print a preview summary first, then the body. The summary is a fixed set of key/value lines so it's scannable, not prose:
**Title:** <generated title>
**Detected:** <type> + <complexity>
**Blocks:** <comma-separated blocks included, in emit order>
**Dropped:** <comma-separated ○ blocks omitted + one-word reason each, or "none">
**Status:** Preview only: nothing created or pushed
After the summary, output the PR body.
Close with a one-line next step, e.g. "Run /pr create to open it."
Do NOT write to any file.
Do NOT run gh pr create, gh pr edit, git push, or any remote-mutating command.
1---2name: pr3description: Use when the user wants to create a new pull request, update an existing PR's body, open a draft PR, or preview a PR body locally before pushing.4---56# PR78Dispatch on the first argument:910- `create` → see Create below11- `draft` → same as Create but create a draft PR instead of a regular PR12- `update` → see Update below13- `preview` → see Preview below14- No argument or unknown → check if a PR exists for the current branch. If yes, run Update. If no, run Create.1516An optional `base=<branch>` argument (any position) sets the target branch. If omitted, default to the repo's default branch. Pass via `--base <branch>` to `gh pr create`. Ignored for `update` and `preview`.1718**Before drafting any PR body (create/draft/update/preview): Read [references/content-guidelines.md](references/content-guidelines.md) AND [references/blocks.md](references/blocks.md) in full.** Do not draft from memory.1920## Classify2122Run this first, before selecting blocks. Classify the change on two axes:2324- **TYPE (fix vs feature)** — infer from Conventional Commit prefixes on the branch commits plus diff shape. `fix:`/`revert:` lean fix; `feat:` leans feature.25- **COMPLEXITY (simple vs complex)** — infer from files touched, diff size, and whether new architecture or a changed control/data flow is introduced.2627Then:28291. State the result in one line, e.g. `Detected: feature + complex`.302. Ask the user ONLY when signals conflict: mixed `fix`/`feat` commits, or a diff on the simple/complex borderline. Otherwise proceed.3132## Template3334The body is assembled from the block library, not a single fixed template.35361. Take the classification's quadrant and pick the matching **profile** in [references/blocks.md](references/blocks.md).372. Add or drop the profile's `○` blocks using the **include-when rules** there.383. Emit blocks in the order listed in the block library.3940Do not add sections outside the block library. Keep all language succinct and concise.4142## Pre-Apply Check4344Before `gh pr create`, `gh pr edit`, or printing a Preview body, verify the drafted body:4546- Every `##` heading appears in the block library in [references/blocks.md](references/blocks.md) (no `## Test plan`, `## Testing`, `## Test coverage`, `## Summary`, or other ad-hoc headings).47- No line numbers referenced.48- No banned wording from [references/content-guidelines.md](references/content-guidelines.md) (AI vocab, hedging, filler, chatbot artifacts).49- Sentence structure (per [references/content-guidelines.md](references/content-guidelines.md)): scan all prose. Flag any sentence that chains *what changed* + *mechanism* + *consequence* with `which`/`so`/`and`, or leads with mechanism instead of the change. Split flagged sentences into what-then-why. Additionally, Key Changes sub-bullets over ~2 sentences / ~25 words (the cap in [references/blocks.md](references/blocks.md)) split into two bullets.50- Jargon (per [references/content-guidelines.md](references/content-guidelines.md) "Glossing Jargon"): every term of art carries a one-clause appositive gloss at first use. Flag any glossed term expanded into a worked example (cut to the gloss) or re-taught on a later mention.51- No em dashes (`—`) anywhere in the body, including link/label separators. Grep the drafted body for `—`; if any appear, replace with a colon, comma, parentheses, or separate sentence before applying.5253If any check fails, revise before applying. Do not ship a body you haven't checked.5455## Applying the Body5657For `gh pr create` and `gh pr edit`, always use `--body-file` with `mktemp`. Never `--body` (its subshell mangles backticks and `$`). No exceptions — inconsistency invites the next agent to rationalize their way back to `--body`.5859```bash60tmp=$(mktemp -t pr-body.XXXXXX) && trap 'rm -f "$tmp"' EXIT && cat > "$tmp" <<'EOF' && gh pr create --body-file "$tmp" [flags]61[body]62EOF63```6465Run in a single Bash call — the `trap` only protects the shell it's set in.6667## Create / Draft6869- Inspect branch state and commit history (including `git log --oneline -- <changed-files>` for convention patterns).70- Generate title71 - Conventional Commits: `<type>(<scope>)?<!>?: <title>`. Title starts lowercase. No trailing period. Omit scope when no single area dominates.72 - Synthesize from branch commits73 - ≤72 chars74 - Should describe the change, not the symptom or task. Focus on what an affected user would interpret, not the exact code change.75- Run **Classify** above, then write the PR body per **Template** (profile + include-when rules).76- Create the PR per **Applying the Body** above (add `--draft` for draft PRs).77- Say "PR Created: [title] [PR URL]".7879## Update8081<HARD-GATE>82STOP before any `gh pr edit` call.83Run `git status -b --porcelain=v2` (or check ahead/behind from `git status`).84If the branch is ahead of origin by ≥1 commit, you MUST call AskUserQuestion:85 "Branch is N commits ahead of origin. Push before updating the PR body?"86 - Yes, push then update body87 - No, update body only (description may reference commits not yet on remote)88This is a correctness gate, not etiquette: if you skip it, the body will describe commits the reviewer can't see. Skipping is a violation even if the user previously approved unrelated unpushed commits.89</HARD-GATE>9091Steps:92931. Find the existing PR for the current branch. If none exists, tell the user to run `/pr create` instead.942. Run the HARD-GATE check above. Resolve before continuing.953. Inspect current branch state and any new design/plan docs since the PR was opened.964. Run **Classify** above, then regenerate the PR body per **Template** (profile + include-when rules). Preserve existing intent where still accurate; revise drifted sections.975. Apply the new body via `gh pr edit` per **Applying the Body** above.986. Show a diff of the old vs new body, highlighting changes.997. Say "PR Updated: [PR URL]".100101Scope: body only. Do not change title or draft state unless the user asks.102103### Red flags (rationalizations to reject)104105| Thought | Reality |106|---------|---------|107| "The body update is the main action, push is incidental" | Push is a precondition. The body is meaningless if the commits aren't visible to reviewers. |108| "User said `/pr update`, not `/pr update and push`" | The skill defines update as inclusive of the push question. Asking is in scope. |109| "I can mention pushing in my closing summary" | Too late. The PR is already updated against stale remote state. |110111## Preview112113Generate the PR body and print it inline without creating, updating, or pushing anything.114115- Inspect branch state (same as Create).116- Print a **preview summary** first, then the body. The summary is a fixed set of key/value lines so it's scannable, not prose:117118 ```119 **Title:** <generated title>120 **Detected:** <type> + <complexity>121 **Blocks:** <comma-separated blocks included, in emit order>122 **Dropped:** <comma-separated ○ blocks omitted + one-word reason each, or "none">123 **Status:** Preview only: nothing created or pushed124 ```125126- After the summary, output the PR body.127- Close with a one-line next step, e.g. "Run `/pr create` to open it."128- Do NOT write to any file.129- Do NOT run `gh pr create`, `gh pr edit`, `git push`, or any remote-mutating command.