# Pr

> Generate a gold-standard pull request description from branch diff

- Skill: `tony/pr` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tony/pr`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tony/pr/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tony (https://skillmd.com/u/tony)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tony/pr

---


# Generate PR Description

Create a gold-standard pull request description from the current branch's diff.

User hint: $ARGUMENTS

## Context

Current branch — run this command and read the output:

```bash
git branch --show-current
```

Base branch detection — run this command and read the output:

```bash
git rev-parse --verify origin/main >/dev/null 2>&1 && echo main || echo master
```

Commits on this branch — run this command and read the output:

```bash
BASE=$(git rev-parse --verify origin/main >/dev/null 2>&1 && echo main || echo master); git log "origin/$BASE..HEAD" --oneline 2>/dev/null || echo "(no commits ahead of base)"
```

Files changed (stat) — run this command and read the output:

```bash
BASE=$(git rev-parse --verify origin/main >/dev/null 2>&1 && echo main || echo master); git diff "origin/$BASE...HEAD" --stat 2>/dev/null || echo "(no diff)"
```

Full diff — run this command and read the output:

```bash
BASE=$(git rev-parse --verify origin/main >/dev/null 2>&1 && echo main || echo master); git diff "origin/$BASE...HEAD" 2>/dev/null || echo "(no diff)"
```

---

## Procedure

### 1. Analyze Changes

- Review the full diff and **all commits** on the branch — not just the latest
- Determine the nature of the change: new feature, bug fix, refactor, CI/infra, docs, etc.
- Identify which modules, files, and areas are affected
- Note the scope: is this a small targeted fix or a large multi-module change?

### 2. Read Project Conventions

- Read AGENTS.md and/or CLAUDE.md for any PR description conventions
- Resolve the `ticket` plugin's content contract when it is installed — it owns the past/present/future tense rules this description follows. Read `references/contract.md`. An installed plugin caches under a version directory, so that sibling sits one level further out than the path suggests: glob the version segment rather than hard-coding it, and run the glob through `sh`, since zsh treats an unmatched glob as a fatal error and would abort before reaching the flat-layout fallback. Continue without it when nothing resolves
- Resolve the PR template per `references/template-resolution.md`: a template mentioned in the user's message wins; otherwise the repository's PR template; otherwise the gold-standard patterns below. When multiple candidate templates are in play, ask — never guess between them
- If a template applies, its structure is the starting point; fill it in with the gold-standard patterns below

### 3. Draft PR Description

#### Title

- Short — under 70 characters
- Descriptive of the impact, not the implementation
- Details belong in the body, not the title
- Match the project's commit/PR title style if one exists

#### Body

Use the sections that are **relevant** to the change — not every PR needs every section. A small bug fix needs fewer sections than a large feature.

**`## Summary`** — 3-7 bullet points:
- Each bullet opens with a **bold impact label** (e.g., **Fix**, **Add**, **Remove**, **Replace**, **Migrate**)
- Concise but complete — a reviewer should understand the full scope from just the summary
- For non-trivial changes, include the motivation (why this change is needed)

**`## Changes`** or **`## Changes by area`** — for multi-module changes:
- Group by area with `###` sub-headings
- Use **bold file/module names** with inline descriptions
- Example: **`src/server.py`**: Wrap post-deletion code in `try/finally` for safe env restoration

**`## Design decisions`** — when trade-offs were made:
- Explain rationale with **bold-label** entries
- Include "why not" for alternatives considered
- Example: **Errors as values, not exceptions**: `SyncResult` follows the structured result pattern because...

**`## Verification`** — copyable commands proving completeness:
- Each `rg` or `grep` command on its own line in its own code block
- Commands should return zero matches for removed patterns or expected matches for added patterns
- Example: verify no f-strings remain in log calls

**`## Test plan`** — a `- [x]` checklist:
- Each item describes **what is validated**, not just the command
- Include project test/lint/typecheck commands as discovered from AGENTS.md
- Include specific test names when they exist
- Example: `- [x] test_new_session_empty_stdout — verifies error on empty stdout`

**`## Setup Required`** — pre-merge steps (only when applicable):
- Numbered external URLs
- Specific configuration steps

**`## Companion PR`** — cross-repo links (only when applicable):
- Link to related PRs in other repositories

#### Tables

Use tables when they improve scannability:

| Use case | Format |
|---|---|
| Parameter/flag mappings | `Parameter \| Flag \| Description` |
| Old-to-new renames | `Method \| Old \| New` |
| File inventories | `Path \| Description` |
| Environment matrices | `Environment \| Result` |
| Sync/async API pairs | `Sync \| Async` |
| Before/after comparisons | `Before \| After` |

#### Line wrapping

**Do NOT hard-wrap PR body text.** Unlike commit messages, PR descriptions
are rendered as Markdown on GitHub — long lines reflow into paragraphs.
Hard-wrapping at 72 characters creates jarring mid-sentence line breaks
in the rendered view. Write prose and bullet text as single long lines;
let the editor/renderer handle display wrapping.

#### Code blocks

- One command per code block
- Explanatory text goes outside the block as regular markdown
- Never put `#` comments inside code blocks

#### Before/After

For behavioral or UX changes, show both states in separate labeled code blocks.

#### Negative assertions in test plan

For removal or migration PRs, include "verify zero matches for X" items proving unwanted patterns are fully removed.

#### What NOT to include

- Test counts or passing numbers ("875 tests pass", "42 tests added")
- Git SHAs or commit hashes
- File-level line numbers
- Number of files or lines changed ("updated 12 files", "adds 340 lines")
- Details the reviewer can see in the diff
- Redundant context already visible in `git log`
- `Fixes #N` hardcoded in the body — use `gh pr create` flags or let GitHub auto-link
- **Within-branch tactical narrative** — renames of unshipped symbols, "no longer X" / "previously Y" phrasing, diff paraphrases, or `### Fixes` framing for behavior that never shipped. Belongs in the commit messages of the commits that did the work. See `AGENTS.md` § *AI Slop Prevention*; apply the Published-Release Test before including.

#### Whole-branch perspective

Describe the branch's **net shipped result**, not its internal evolution. Ignore
fixup commits, reverts-then-re-adds, and intermediate WIP states — the PR
description is a product changelog for reviewers, not a commit-by-commit diary.

### 4. Present and Create

- **Show the proposed title and body** to the user in full
- Ask whether to:
  1. Create the PR via `gh pr create`
  2. Just output the description (user will create manually)
- **If creating the PR:**
  - Check if the branch has been pushed; if not, push it with `git push -u origin <branch>`
  - Never push to `main` or `master`
  - Use heredoc for the body to preserve formatting:
    ```
    gh pr create --title "the title" --body "$(cat <<'EOF'
    ## Summary
    ...
    EOF
    )"
    ```
  - If the user provided `$ARGUMENTS` containing a hint about a linked issue, add `--body` content accordingly
- Return the PR URL when done

---

## Rules

- **Never** force-push or run destructive git commands
- **Never** push to `main` or `master`
- **Always** present the full description before creating the PR
- **Always** use heredoc for `gh pr create --body` to preserve formatting
- **Language-agnostic**: discover test/lint commands from AGENTS.md/CLAUDE.md — never hardcode specific tool commands
- **Proportional**: match the description's detail level to the diff size — a one-file fix doesn't need 20 bullets; a 30-file feature shouldn't be one sentence
- **No brittle details**: no test counts, no SHAs, no line numbers, no file/line-changed counts
- **Whole-branch perspective**: describe the net shipped result, not the branch's internal commit history


## Portability notes

- `$ARGUMENTS` — the text the user passed when invoking this skill. If your host does not substitute it, read it as the user's request in the current turn, and ask when there is none.
- Bundled files — every relative path in this skill points at a file shipped inside this skill directory. Read them from here, not from the host's plugin tree.

