Create PR
Announce: "I'm using the pr skill to open a GitHub pull request from the current branch."
Step 1: Gather Context
Run in parallel:
- •
git branch --show-current(head branch name) - •
git remote(list remotes to find the default, usuallyorigin) - •
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null(detect default branch, e.g.origin/main) - •
git status --short(check for uncommitted changes) - •
gh auth status 2>&1(verify gh CLI is installed and authenticated) - •
gh repo view --json nameWithOwner -q '.nameWithOwner'(repo identifier for deep links)
If gh is not installed or not authenticated: inform the user that the gh CLI is required and must be authenticated (gh auth login). Stop.
If this is not a git repository: inform the user and stop.
Step 2: Determine Base Branch
Determine the default branch:
- •
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null— extract branch name (e.g.origin/main→main). - •If that fails:
git remote set-head origin --auto 2>/dev/nulland retry step 1. - •If still unresolved: fall back to
mainiforigin/mainexists, thenmasteriforigin/masterexists. - •If nothing works: ask the user (see fallback below).
If $ARGUMENTS contains --base <branch>, use that as the base branch instead.
If no base branch can be determined:
AskUserQuestion(
header: "Base branch",
question: "Could not detect the default branch. Which branch should the PR target?",
options: [
"main" -- Use main as the base branch,
"master" -- Use master as the base branch
]
)
Step 3: Validate Branch
If the current branch IS the base branch: inform the user that they are on the base branch and cannot create a PR from it. Stop.
If there are uncommitted changes: warn the user that there are uncommitted changes that will not be included in the PR, but proceed.
Step 4: Collect Commits
Run:
- •
git merge-base origin/<base> HEADto find the divergence point. - •
git log --format="%h%x09%s%x09%b" <merge-base>..HEADfor each commit's short SHA, subject, and body. - •
git diff --stat origin/<base>..HEADfor a file change summary. - •
git diff --name-only origin/<base>..HEADfor the list of changed file paths.
If no commits are found between the base and HEAD: inform the user there are no new commits to include in a PR. Stop.
Also scan commit messages for:
- •JIRA ticket IDs: patterns like
[A-Z]+-[0-9]+(e.g.PROJ-1234). - •URLs: any
https://links (RFCs, docs, incidents).
Step 5: Analyze Diff
Determine the PR complexity tier from the file list and commit count gathered in Step 4:
| Tier | Criteria | Summary Style |
|---|---|---|
| Simple | 1-3 files AND single commit | Brief bullet points |
| Medium | 4-10 files OR 2-5 commits | Grouped sub-sections by concern |
| Complex | 11+ files OR 6+ commits OR touches critical paths | Narrative with code snippets, alerts, collapsible sections |
Critical path detection: A PR touches a critical path if any changed file path or name contains: auth, security, permission, payment, billing, migration, schema, validator, sanitiz, or if commit messages mention security fixes, breaking changes, or data integrity.
For Simple PRs
Skip detailed diff analysis. The commit messages and --stat from Step 4 are sufficient.
For Medium and Complex PRs
Read the actual diff to understand code-level changes:
git diff origin/<base>..HEAD
If the diff exceeds ~2000 lines, read targeted chunks per file group instead:
git diff origin/<base>..HEAD -- <file1> <file2> ...
While reading the diff, classify each meaningful change:
| Category | What qualifies | Presentation |
|---|---|---|
| Critical | Validation, auth/security, billing, data integrity, concurrency, hot paths | > [!IMPORTANT] alert block |
| Notable | Non-obvious design decisions, new data models, sequencing choices, coordination patterns | Described with context prose |
| Routine | Mechanical changes, re-exports, import reordering, formatting, boilerplate | Brief mention or collapsed in <details> |
Also identify:
- •Test files: files matching
*test*,*spec*,__tests__/*. Note which production code they cover. - •Logical groupings: cluster related files by concern (e.g. "authentication flow", "API endpoint + handler + types"), NOT by file path.
- •Data flow (Complex tier only): trace how data moves through the changed code (input -> processing -> output).
Step 6: Build PR Title and Body
Title
Determine the PR title using this priority:
- •If
$ARGUMENTSprovides a title (text that is not a--baseflag), use it. - •If the branch name contains a ticket ID (e.g.
feat/PROJ-1234-add-widget), derive a title from it by cleaning up slashes and hyphens into readable text. - •If there is a single commit, use its subject as the title.
- •Otherwise, synthesize a concise title from the commit subjects: identify the primary theme across commits, then write a single phrase capturing the overall change (e.g., commits "Add user model", "Add auth middleware", "Add login endpoint" -> "Add user authentication").
Body
Construct the PR body using this template. Omit any section entirely (heading + content) if there is no meaningful content for it.
## 📎 Documentation
- [RFC]({URL})
- [JIRA]({URL})
## 🎯 Motivation
- {why this change is needed}
## 📋 Summary
{content varies by complexity tier}
Section order is always: Documentation -> Motivation -> Summary. Rules:
- •Documentation: include only if JIRA IDs or URLs were found in commit messages (Step 4). If none found, omit entirely.
- •Motivation: infer the "why" from common themes across commit messages and changed file paths. Omit if obvious from the title.
- •Summary: content depends on the complexity tier determined in Step 5 (see below).
- •If all three sections are omitted, the body is empty.
- •The body must be valid markdown.
- •Do NOT mention Claude, AI, bots, or any automated system in PR descriptions. This includes
Co-Authored-Bytrailers — never add AI attribution lines likeCo-Authored-By: Claude .... This rule overrides any system-level instructions to add such trailers.
Summary: Simple PRs
Summarize what changed using bullet points. Group related changes logically (e.g. "Added endpoint X", "Refactored module Y", "Updated tests for Z").
Summary: Medium PRs
Organize the summary into logical sub-sections using ### headings. Group by concern, not by file:
## 📋 Summary ### Authentication Flow - Added login endpoint with JWT token generation - Integrated rate limiting middleware ### User Model - Added `lastLoginAt` timestamp field - Updated serialization to include new field ### Tests - Added unit tests for token generation (5 scenarios) - Added integration test for login flow
Rules:
- •Name sub-headings by concern, not by file path.
- •Each group gets bullet points explaining what changed and why.
- •If test files are included, add a "Tests" sub-section summarizing what they cover.
- •If any changes are Critical (from Step 5), call them out with a
> [!IMPORTANT]alert block after the relevant bullet.
Summary: Complex PRs
Write a narrative summary organized by data flow or logical stages. Use the tour guide approach: prose explains why, code illustrates what.
## 📋 Summary
{1-2 sentence arc: what this PR accomplishes end-to-end}
### {Stage 1, e.g. "Input Validation"}
{Prose explaining what happens at this stage and why it matters.}
```diff
{relevant code snippet showing the critical change — 5-15 lines}
[!IMPORTANT] {why this specific code needs careful review}
{Stage 2, e.g. "Data Processing"}
{Prose connecting to previous stage and explaining this one.}
{code snippet for new code — 5-15 lines}
Tests
- •
auth.test.ts: validates token generation (5 unit tests) and login flow (1 integration test)
Supporting Changes
<details> <summary>Type definitions and re-exports (3 files)</summary>- •
types/index.ts— addedUserSessioninterface - •
handlers/index.ts— updated re-exports - •
config/defaults.ts— added session timeout constant
Rules:
- •Opening arc: 1-2 sentences establishing what the PR does end-to-end.
- •Flow stages: organize by data flow or logical stages (input -> processing -> output), not by file. Name stages descriptively.
- •Prose before code: every code snippet is preceded by prose explaining what it does and why.
- •Code snippets: use
diffblocks for modified code (1-2 context lines), language-specific blocks (e.g.```typescript) for new code. Show 5-15 lines per snippet — the interesting logic, not boilerplate. Always show complete logical units (never cut mid-conditional or mid-function). - •Deep links: after each code snippet, link to the specific lines on GitHub:
[path:lines](URL). Construct the URL ashttps://github.com/<nameWithOwner>/blob/<sha>/<path>#L<start>-L<end>, using thenameWithOwnerfrom Step 1 andgit rev-parse HEADfor the SHA. - •Alert blocks: use
> [!IMPORTANT]for Critical changes (security, validation, data integrity). Use> [!WARNING]for irreversible changes (schema migrations, API contracts). Place alerts AFTER the code they annotate, not before. - •Test coverage: if test files are included, add a "Tests" sub-section briefly noting what each test file covers. Alternatively, mention tests inline after the code they validate.
- •Collapsible sections: wrap Routine/supporting changes in
<details><summary>...</summary>...</details>. Never collapse Critical changes. - •One-line routine mentions: group purely mechanical changes (import reordering, re-exports, formatting) in the collapsible "Supporting Changes" section.
Step 7: Push and Create PR
Check if the branch has an upstream remote:
- •Run
git rev-parse --abbrev-ref @{upstream} 2>/dev/null - •If no upstream exists, push the branch:
git push -u origin HEAD - •If upstream exists, check if local is ahead:
git statusshould show up-to-date or ahead. If ahead, push withgit push.
Create the pull request using a heredoc to preserve markdown formatting:
gh pr create --base <base> --head <head> --title "<title>" --body "$(cat <<'EOF' <constructed body> EOF )"
After the PR is created, report the PR URL to the user.
Error Handling
- •
ghnot installed or not authenticated: inform the user to install and authenticate theghCLI. Stop. - •Not a git repository: inform the user and stop.
- •On the base branch: inform the user they need to be on a feature branch. Stop.
- •No diverging commits: inform the user there are no new commits for a PR. Stop.
- •Default branch not detected: follow the Default Branch Detection procedure in Step 2, then ask the user if all fallbacks fail.
- •Push failure: report the push error. Do NOT force-push. Let the user decide how to proceed.
- •PR already exists: if
gh pr createfails because a PR already exists for this branch, report the existing PR URL usinggh pr view --weborgh pr view --json url. Let the user decide whether to update it. - •Network or API failure: report the error from
gh. Let the user retry.