Claude
Skills
Sign in
โ† Back

pr-create

Included with Lifetime
$97 forever

Use this skill whenever the user wants to create, open, or raise a new GitHub pull request from the current branch โ€” including phrasings like "open a PR", "raise a PR", "make a PR", "ship this". Drafts a Conventional Commits title and a Summary body that explains *why* and *what*, respects `.github/pull_request_template.md` when present, auto-links referenced issues, waits for approval, then pushes and opens the PR. Assumes commits already exist. Requires `gh` CLI.

General

What this skill does


# PR Create

## Hard rules

These override anything else. No exceptions without an explicit user instruction.

- **Never append Claude attribution trailers.** No `๐Ÿค– Generated with Claude Code`, no `Co-Authored-By: Claude โ€ฆ`, no "Generated by" footers. The PR title and body contain nothing that identifies the author as an AI.
- **Never force-push unless the user explicitly asks this turn** โ€” and only `--force-with-lease`, never plain `--force`. Confirm the head branch is not `main` / `master` before the push.
- **Never open a PR from `main` / `master`.** Stop and surface to the user.
- **Never auto-rebase or auto-merge the base branch.** If the branch is behind, surface it and ask.
- **Never fill a checklist item you haven't verified.** Leave `[ ]` unchecked; don't tick boxes on the user's behalf.
- **Never open a PR that contains secrets.** If the diff touches `.env*`, `*credentials*`, `*.pem`, `*.key`, or `id_rsa*`, stop and surface to the user โ€” even if the user asked you to proceed. Public PRs cache forever.

---

## Workflow

1. **Preflight** โ€” validate branch state, remote state, and `gh` auth.
2. **Gather context** โ€” commits, diff, branch name, referenced issues, existing PR template.
3. **Draft title and body** โ€” Conventional Commits title + Summary covering *why* and *what*.
4. **Propose for approval** โ€” show the draft; wait for edits or OK.
5. **Push and create** โ€” push the branch, open the PR, return the URL.

---

## Step 1 โ€” Preflight

Run these in parallel and stop if any check fails:

```bash
gh auth status
git rev-parse --abbrev-ref HEAD
git status --porcelain
BRANCH=$(git rev-parse --abbrev-ref HEAD)
gh pr list --head "$BRANCH" --state open --json url,number
```

Fail-stop conditions:

| Check | Condition | Action |
|---|---|---|
| Current branch | `main` or `master` | Stop. Tell the user to switch to a feature branch. |
| `gh auth status` | not authenticated | Stop. Tell the user to run `gh auth login`. |
| Existing PR | a PR already exists for this branch | Stop. Return the existing URL โ€” don't open a duplicate. |
| Uncommitted changes | `git status --porcelain` is non-empty | Surface to the user. This skill is PR-only; don't auto-commit. |

Determine the base branch (usually `main`, sometimes `master` or `develop`):

```bash
gh repo view --json defaultBranchRef --jq .defaultBranchRef.name
```

Check the branch is up to date with the base. Fetch first so the comparison is accurate:

```bash
git fetch origin
BASE=$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)
BEHIND=$(git rev-list --count HEAD..origin/$BASE)
```

If `BEHIND > 0`, surface it: *"Your branch is N commits behind `origin/$BASE`. Rebase or merge before opening the PR?"* โ€” **do not auto-rebase**.

---

## Step 2 โ€” Gather context

Collect the material needed to write the title and body:

```bash
BASE=$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)
git log --reverse --pretty=format:'%h %s%n%b%n---' origin/$BASE..HEAD
git diff --stat origin/$BASE...HEAD
git rev-parse --abbrev-ref HEAD
```

**Sensitive-file scan.** Check the file list from `git diff --stat` for paths matching `.env*`, `*credentials*`, `*.pem`, `*.key`, or `id_rsa*`. Any match โ†’ stop and surface to the user per the hard rule. Do not proceed even if the user tells you to; require a direct re-confirmation that the file is intentional.

**Issue references.** Scan commit subjects, commit bodies, and the branch name for `#NNN` patterns. Only promote to `Closes #NNN` when the signal is unambiguous:

- A commit *subject* matches `^(fix|close|resolve)(\(.+\))?:` **and** contains `#NNN` on the same line.
- The branch name starts with `fix/NNN-โ€ฆ` or `issue-NNN-โ€ฆ`.

Every other reference (`#NNN` in a body, a `refactor` commit mentioning an issue, a `feat` that relates to but doesn't close an issue) is `Refs #NNN`. Default to `Refs` when in doubt and flag for the user in Step 4 โ€” a wrong `Closes` silently closes an issue on merge, a wrong `Refs` is harmless.

**PR template.** Check for a template and use it as the body scaffold if it exists. GitHub looks in several locations โ€” check all of them:

```bash
ls .github/pull_request_template.md \
   .github/PULL_REQUEST_TEMPLATE.md \
   pull_request_template.md \
   PULL_REQUEST_TEMPLATE.md \
   docs/pull_request_template.md \
   docs/PULL_REQUEST_TEMPLATE.md \
   2>/dev/null
ls -d .github/PULL_REQUEST_TEMPLATE/ 2>/dev/null
```

If `.github/PULL_REQUEST_TEMPLATE/` is a directory (multi-template repo), list its contents and ask the user which template applies before filling.

If a template is found, fill its sections from the gathered context. If it has a checklist, leave items unchecked unless you've verified them.

---

## Step 3 โ€” Draft title and body

### Title

Conventional Commits: `type(scope): subject`

- **type** โ€” `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `perf`, `build`, `ci`.
- **scope** โ€” optional; the primary package/module/area touched. Derive from paths in `git diff --stat`.
- **subject** โ€” imperative mood, lowercase, no trailing period, under ~70 chars total.

If the branch has a single commit, reuse its subject when it already follows Conventional Commits. Otherwise, synthesize a new subject that covers the dominant change.

### Body โ€” default structure (when no repo template exists)

```markdown
## Summary

<2โ€“4 sentences. Lead with *why* โ€” the problem, the user need, the constraint that forced this. Then *what* โ€” the concrete change. Avoid restating the diff.>

Closes #NNN
```

**Summary rules:**

- Start with the motivation (*why*), not the implementation (*what*).
- One paragraph, not a wall of text. If you need headings inside Summary, the change is probably two PRs.
- Never write "This PR โ€ฆ" โ€” write the change directly.
- No hedging ("attempts to", "should hopefully"). State what it does.

### Body โ€” when a repo template exists

Fill the template's sections verbatim (don't rename or reorder). Map:

- Template "Summary" / "Description" / "What" โ†’ the Summary content above.
- Template "Why" / "Motivation" โ†’ the *why* from the Summary (split it if the template separates them).
- Template "Testing" / "Test Plan" โ†’ describe what was tested **if verified**, otherwise leave blank with a note for the user to fill in. **Do not fabricate test steps.**
- Template "Checklist" โ†’ unchecked `[ ]` unless verified.
- Template "Issue" / "Related" โ†’ `Closes #NNN` / `Refs #NNN`.

---

## Step 4 โ€” Propose for approval

Print the full draft โ€” exactly as it will be submitted โ€” and wait. Format:

```
Title:  feat(tracer): stream spans to disk without blocking the agent loop
Base:   main โ† <current-branch>
Draft:  no

---
## Summary
โ€ฆ

Closes #42
---
```

If there's any ambiguity (close vs refs, unclear scope, behind base), list it under the draft as numbered clarifications. The user edits by number or gives a free-form correction. Re-render the draft after edits and re-confirm before proceeding.

**Do not proceed without explicit approval.** A silent response is not approval.

---

## Step 5 โ€” Push and create

Push the branch (set upstream if missing). **No `--force` variants.**

```bash
git push -u origin HEAD
```

Create the PR with a HEREDOC so the body formats correctly:

```bash
gh pr create \
  --base "$BASE" \
  --title "feat(tracer): stream spans to disk without blocking the agent loop" \
  --body "$(cat <<'EOF'
## Summary

Span export was blocking the agent loop under load because the exporter flushed synchronously on every span. This moves writes to a background task with a bounded channel so the hot path stays non-blocking.

Closes #42
EOF
)"
```

Return the PR URL to the user. Done.

---

## Edge cases

Fail-stop conditions are already covered in Step 1 (main/master, uncommitted changes, existing PR, no auth). The cases below are the genuinely ambiguous ones.

| Situation | Handling |
|---|---|
| No upstream set | Use `git push -u origin HEAD` โ€” don't prompt. |
| Branch behind base | Surface to user; do not auto-r
Files: 1
Size: 9.1 KB
Complexity: 16/100
Category: General

Related in General