# Pr Describer

> Write a good pull request description from the actual diff — what changed, why, how, testing notes, and appropriate flags. Triggers on "write a PR description", "describe this PR", "help me open a PR", or when the user is preparing to push a branch and needs a description.

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

---


# pr-describer

Produce a pull request description that a reviewer will actually thank you
for. Reads the diff, not the commit messages — commit messages record how
you built the change, PR descriptions explain why and what it means for
the codebase and its users.

## When to use this

- "Write a PR description"
- "Describe this PR"
- "Help me open a PR"
- Just before `git push` / `gh pr create`, when the user needs the body

## Procedure

### 1. Determine the diff range

Priority order:

1. If the user specified a base/head, use it.
2. Try `git merge-base main HEAD` (or `master`, or the repo's default branch —
   check `git symbolic-ref refs/remotes/origin/HEAD` or fall back to `main`).
3. Otherwise use `HEAD~N` for a reasonable N if the branch is short.

Get the actual data:

```sh
git diff <base>...HEAD --stat
git diff <base>...HEAD
git log <base>..HEAD --no-merges --pretty=format:"%h %s%n%b%n---"
```

The `<base>...HEAD` form (three dots) shows the diff from the merge base,
which is what a reviewer sees. Do not use `<base>..HEAD` (two dots) for the
diff — that includes any unrelated changes on main.

### 2. Read the diff, not the commit history

The commit messages describe the *process* of making the change. The PR
description should describe the *outcome*. Read the actual diff:

- What files were touched, and what's the shape of the change (new file, big
  rewrite, small edit, config change)?
- What's the user-visible or API-visible impact?
- Are there any migration steps a consumer would need to take?
- Any generated files (lockfiles, snapshots, protobuf) that reviewers should skip?

### 3. Write the description

Use this structure (adjust for repo conventions if present in `.github/PULL_REQUEST_TEMPLATE.md`):

```markdown
## Summary

<1-3 sentences. What this PR does, in plain language. If the reader stops
reading after this section, they still know what merged.>

## Why

<Motivation. Optional if obvious from summary. Link to the issue if there is one.>

## What changed

- **<Area 1>** — what was actually done and why in that area
- **<Area 2>** — same
- <keep this bulleted and short; the diff is one click away>

## Testing

<How was this verified? "Ran the test suite" is fine when true. "Manually
walked through X flow" is fine when true. Be honest — reviewers can tell
when this section was skipped.>

## Screenshots

<Only if UI changes. Before / after. Skip section entirely if not applicable.>

## Breaking changes

<Only if there ARE breaking changes. Be very concrete: exactly what breaks,
exactly what a consumer has to do. Skip section entirely otherwise.>

## Notes for reviewer

<Anything that would save the reviewer time. "The change in `foo.rs` is
mechanical, only `bar.rs` matters." Or: "Ignore lockfile diff." Skip if
nothing to add.>
```

### 4. Detect and flag important situations

Scan the diff for these and add appropriate mentions:

- **Public API changes** (exported functions/types/routes) → mention in
  "What changed" and consider whether it's a breaking change
- **New dependencies added** → mention in "What changed"; consider whether
  the license and size are worth flagging
- **Migration files / schema changes** → mention explicitly with runbook
- **Deleted files / removed exports** → breaking change if public
- **Secrets, tokens, or `.env`-shaped strings in the diff** → HALT. Do not
  write the PR. Tell the user something looks like a secret leak and point
  at the specific lines.
- **Commented-out code left in** → mention as review note ("Leftover from
  debugging in X, safe to remove")
- **TODO/FIXME added** → mention, ask if intentional

### 5. Length calibration

The right length is proportional to the diff, not to how proud you are.

- ~10 lines changed → summary + testing, maybe one bullet in "What changed". That's it.
- ~100 lines changed → the full structure above, but keep each section tight.
- ~1000+ lines changed → the full structure plus a "How to review" section
  suggesting an order to look at files.

If the diff is over ~2000 lines and there's no clear reason (generated files,
mechanical refactor), *offer to the user* that this should probably be split
into multiple PRs. Then still write the description if they say to proceed.

## Anti-patterns

- Do not just paraphrase the commit messages. Read the diff.
- Do not include the diff itself in the description — reviewers see it below.
- Do not use marketing language ("major overhaul", "significant improvements").
  Boring is professional.
- Do not skip the "Testing" section. If nothing was tested, say so — that's
  useful information for the reviewer, not a shame to hide.
- Do not run `git push` or `gh pr create` yourself. Hand the description to
  the user; they push.

