pr-craft
Skill0 starsChanged 8 days agoMITView on GitHub
Create a pull request with a structured, concise description derived from the diff and conversation context. Use when the user asks to "create a PR", "open a PR", "PR to <branch>", "raise a pull request", or wants the full branch → commit → push → gh pr create flow. Also opens GitHub-native stacked PRs — an ordered series of dependent PRs, one per layer — when the user says "stack this", "stacked PR", or the change is too large/layered to review as one. Produces a body with Problem / Root cause / Fix / Test / Out of scope sections and references task/ticket IDs.
- Commits and pushes
In this repository31 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- ai-estimateSkill
- aso-craftSkill
- audit-reportSkill
- babysit-prsSkill
- blueprintSkill
- brag-docSkill
- business-briefSkill
- cagan-checkSkill
- code-craftSkill
- commit-reportSkill
- compassSkill
- cv-craftSkill
- dev-flowSkill
- grill-meSkill
- implementation-reviewSkill
- llm-wikiSkill
- parallel-worktreesSkill
- periscopeSkill
- portfolio-syncSkill
- problem-solvingSkill
- publish-skillSkill
- review-passSkill
- security-auditSkill
- semverSkill
- sentinelSkill
- seoSkill
- testing-philosophySkill
- to-prdSkill
- write-a-skillSkill
- wstg-security-testingSkill
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 37
Branch: If on the base branch (main/staging/master), create type/short-slug (e.g.
- Distinctive: line 46
Only include sections that carry signal — drop empty ones.
- Very specific: line 76
A stack is always a GitHub stack: Never stack by hand, opening each PR with gh pr create --base <lower-branch>.
- Very specific: line 86
Revise a lower layer: Commit on it, then gh stack sync to rebase + retarget the layers above (conflicts: gh stack rebase → resolve → gh …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
pr-craft
Drive a clean PR end to end: branch, stage only the relevant files, conventional-commit, push, open the PR with a structured body. Default to one focused PR; for a large change that splits into ordered dependent layers, open a stack instead (see Stacked PRs).
Flow
- Inspect.
git status+git diff(andgit diff --staged). Identify which changed files belong to this task. Pre-existing modified/untracked files unrelated to the work (lockfiles, config, scratch dirs) are NOT yours — leave them. Size the change. This gate is blocking: no
gh pr createuntil it has run and been printed. Measure what the PR will actually ask someone to read, before committing, so a split is still cheap. It applies just as much when the branch arrives already committed (a dev-flow run, a branch built over several sessions): measure it, and if it trips, split it before opening anything.# BASE = the branch the PR will target (the user's, or the repo CLAUDE.md's), NOT origin/HEAD: # a repo whose GitHub default is a release branch measures against the wrong tree. BASE=${BASE:-$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|origin/||')} git diff --numstat "origin/${BASE}...HEAD" -- . \ ':(exclude)*.lock' ':(exclude)*lock.json' ':(exclude)*.lockb' \ ':(exclude)dist/**' ':(exclude)build/**' ':(exclude)vendor/**' \ ':(exclude)**/*.min.*' ':(exclude)**/*.snap' ':(exclude)**/*.generated.*' \ | awk '{a+=$1; d+=$2; f++} END{printf "%d files, +%d -%d (%d lines)\n", f, a, d, a+d}'Work not committed yet? Same pipe over
git diff --numstat HEAD, but first mark this task's new files withgit add -N <file> …(intent-to-add, named individually like step 4, never-A).git diffdoes not see untracked files, so without it a feature made of brand-new files measures as zero lines and sails past the gate. The exclusions are deliberate: a regenerated lockfile or adist/rebuild is not review surface, and counting it splits PRs that never needed splitting.Reading Action < 400 lines and < 15 files One PR. Proceed. 400-800 lines, or 15-25 files One PR, but report the number and offer the split. > 800 lines, or > 25 files Stop. Propose a stack: print the reading and the layer cut (each layer's files and line count), and wait for the user. One PR ships only if the user says so for this change; a "Size" note in the PR body is not that. These are review-capacity heuristics, not laws: reviewer defect-detection drops off sharply past a few hundred lines in one sitting. Tune the numbers here if a repo consistently runs bigger.
The failure this guards against: two PRs of 6.5k and 2.1k lines were opened after the gate was measured, with the size explained in the body instead of split. Measuring is not passing; above 800 the user decides, before the PR exists.
- Branch. If on the base branch (
main/staging/master), createtype/short-slug(e.g.fix/marketing-consent-required-signup). Type matches the commit type. If already on a feature branch, stay. - Stage explicitly.
git add <file> <file> …— name each relevant file. Nevergit add ./-A. Re-rungit statusto confirm only intended files are staged. - Commit. Conventional Commits subject (
type(scope): summary, ≤72 chars). Body explains why + bullet the changes. End withRefs task <id>/Refs <ticket>when known. Obey the repo's CLAUDE.md (e.g. noCo-Authored-Bytrailer if it says so). - Push.
git push -u origin <branch>. - Open PR.
gh pr create --base <base> --head <branch> --title "<same as commit subject>" --body "$(cat <<'EOF' … EOF)". Base = the branch the user named, else the repo default (staginghere, oftenmainelsewhere — checkgit remote show originor repo CLAUDE.md if unsure). - Report the PR URL. Name which automated reviewers this repo runs, so the user knows what will (and won't) look at the diff — one discovery command, in review-pass/references/automated-reviewers.md. If the repo has none configured, or the one it has is paused, that's worth a sentence: a PR nobody and nothing reviews should be a deliberate choice, not a surprise. Then offer follow-ups (log time, comment the link on the task).
PR body structure
Only include sections that carry signal — drop empty ones. Concise, no filler.
## Problem
What's broken / needed and who reported it. The user-facing or compliance impact.
## Root cause
Why it happens, by layer/file. Cite `file:line` or function names.
## Fix
- Bullet each change, what it does and why.
- Note side effects / benefits.
## Test
1. Numbered manual steps a reviewer runs to confirm.
## Out of scope (flag to <owner>)
- Known gaps deliberately not handled (other locales, data backfill, etc.).
Refs task <id>Stacked PRs (large, layered changes)
Default to one focused PR. Reach for a stack when the size gate in step 2 trips and the change decomposes into ordered dependent layers (e.g. schema → API → UI). Each layer becomes its own small PR, reviewable in parallel, and lower layers can merge first. This is GitHub's native stacked pull requests (public preview, since July 2026): each PR targets the layer below and shows only its own diff, with a stack map at the top.
Size alone is not a reason to split. Some large changes have exactly one seam: a mechanical rename across 60 files, a regenerated API client, a dependency bump with wide call-site churn. Splitting those yields layers that are individually meaningless and harder to review than the whole. When the gate trips but no seam exists, keep the single PR and spend one line of the body saying why it is big and which parts are mechanical (point reviewers at ?w=1 for whitespace-heavy diffs). Aim each layer under ~400 lines, but let the seam pick the cut, never the line count.
Prereq (once per machine): gh extension install github/gh-stack.
A stack is always a GitHub stack. Never stack by hand, opening each PR with gh pr create --base <lower-branch>. GitHub then shows unrelated PRs with no stack map, and CI that only runs on PRs into the default branch skips every upper layer. Use gh stack for every stack:
- Building it now: steps 1-3 below.
- Layers already exist as branches or PRs (split after the fact, or opened by hand):
gh stack link <bottom> <next> …(branch names, PR numbers or URLs, bottom to top). It pushes the branches, opens any missing PRs with the right bases, and links them into one stack.
Confirm the stack exists before reporting: submit and link print Created stack with N PRs (stack #…). No stack number means it isn't stacked.
- Bottom layer. From the base branch:
gh stack init <layer-1-branch>. Do that layer's work with the same explicit-staging + conventional-commit rules as the single-PR flow above. - Stack up. For each next layer:
gh stack add <layer-n-branch>, then commit its work. Each layer depends on the one below it. - Submit.
gh stack submit— pushes every branch, opens one PR per layer, and links them as a stack (each PR based on the layer below). Give each PR the same structured body, scoped to its own layer. - Inspect.
gh stack viewprints the stack map / status. Move around withgh stack up/down/top/bottom, orgh stack switchto pick a layer interactively. - Revise a lower layer. Commit on it, then
gh stack syncto rebase + retarget the layers above (conflicts:gh stack rebase→ resolve →gh stack rebase --continue). - Merge.
gh stack merge <pr-number>does an atomic all-or-nothing merge of that PR and every layer below it. Always pass the PR number. With no argument in a non-interactive shell (which is what the Bash tool is) it merges the entire stack without prompting, using your last merge method. Branch protection and required checks still govern, and a merge-queue base queues the stack instead. Merging on GitHub works too: PRs above stay open and auto-rebase onto the new base. - Report the stack: each PR URL + the merge order.
Notes: split by reviewable seam, not commit count — a layer that can't be reviewed or reverted on its own isn't a layer. Reordering is CLI-only (gh stack modify) during the preview; merge-queue support is still rolling out.
Gotchas
- Bash tool is POSIX sh — for multi-line commit/PR text use a heredoc (
-F -for commit,$(cat <<'EOF' … EOF)for--body). Do NOT use PowerShell here-strings (@'…'@) in the Bash tool — the@leaks into the message. Quote the heredoc delimiter (<<'EOF') so backticks/$stay literal. - Don't sweep unrelated changes into the commit — the #1 mistake. Stage by name.
- Subject = PR title — keep them identical.
- Derive body content from the actual diff + what was discussed, not guesses. If root cause wasn't established, say "investigating" rather than inventing one.
See EXAMPLE.md for a full worked PR.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

