← back to posts

Open PR skill

2026-09-03

It reads the diff, writes a conventional-commit title, and splits the body in two: a plain summary first, then the technical details pointing at real files. Sections like ## Demo or ## Risks & rollout only appear when the change needs them.

---
name: open-pr
description: Write a pull request description and open or update the PR. Use when asked to open a PR, raise a PR, create a pull request, write or rewrite a PR description or PR title, or update the body of an existing PR. Produces a conventional-commit title and a two-part body (plain-language summary, then technical detail).
---

# Open PR

Read the actual diff, write a title and body from it, then open or update the PR with `gh`.

Never describe changes you have not read. Never claim a check passed unless you ran it in this session.

## 1. Gather context

```bash
git rev-parse --abbrev-ref HEAD                                  # current branch
gh repo view --json defaultBranchRef -q .defaultBranchRef.name   # base branch
git log --oneline <base>..HEAD                                   # commits
git diff <base>...HEAD --stat                                    # shape of the change
git diff <base>...HEAD                                           # the change itself
gh pr list --head <branch> --json number,url,title               # existing PR?
```

Stop and ask if: the branch is the default branch, there are uncommitted changes, or the branch has no commits ahead of base.

## 2. Title — conventional commits

`type(scope): summary` per the Conventional Commits spec — lowercase, imperative, no trailing period, ≤ 72 chars, `!` before the colon for a breaking change.

Scope = the dominant package, app, or directory (`auth`, `editor`, `api`); omit it if the change is repo-wide. If the branch holds one commit whose subject is already conventional and accurate, reuse it.

## 3. Body

Two required sections. First is prose, second is bullets.

```markdown
## What & why

<2-4 plain sentences: the problem a user or teammate had, and what the change
does about it. No file names, no class names, no jargon. A PM should follow it.>

## Implementation

- `path/to/file.ts:88` — what changed here and why this approach
- <key decision, tradeoff, or alternative rejected>
- <migration, new dependency, config, or flag introduced>
- Refs: <ticket / RFC / related PR, only if it exists in the branch or commits>
```

Budget: body under ~40 lines. 3–8 implementation bullets, each anchored to a real path (add `:line` when it points at one spot). Cut restating-the-diff bullets — say why, not what.

## 4. Conditional sections

Append these below `## Implementation`, in this order, only when the row's condition holds.

| Section | Include when | Skip when |
| --- | --- | --- |
| `## Demo` | the diff touches a user-visible surface (component, page, style, CLI output, email template) | no rendered surface changed |
| `## How to test` | a reviewer needs manual steps, seed data, a flag flipped, or a specific route to verify | automated tests in the diff already cover it |
| `## Risks & rollout` | migration, backfill, breaking API, feature flag, auth/permissions, or a hot path | isolated, reversible, internal-only change |

`## Demo` — never fabricate an image link. Emit a marker plus the exact states worth capturing:

```markdown
## Demo

<!-- drop screenshot / GIF here -->

Worth capturing: <e.g. empty state, populated list, validation error, mobile width>
```

`## How to test` — numbered steps a reviewer can paste. State separately which checks you actually ran and their result.

`## Risks & rollout` — what breaks, who notices, how to roll back. Three bullets max.

## 5. Open or update

```bash
# new PR
git push -u origin <branch>
gh pr create --base <base> --title "<title>" --body-file <tmp>.md

# existing PR
gh pr edit <number> --title "<title>" --body-file <tmp>.md
```

Write the body to a temp file rather than passing it inline. Show the user the title and body and get an explicit go-ahead before the push or the `gh` call — this is outward-facing. Use `gh pr create --draft` for a new PR when the user asks or the branch has obvious TODOs; an existing PR converts with `gh pr ready <number> --undo` (`gh pr edit` has no `--draft` flag). Return the PR URL when done.