Create PR
Creates a GitHub Pull Request using gh pr create. Generates the PR title and body
from git diff, writes it to PR_DESCRIPTION.md, then submits.
Usage
The user may specify a target branch. If omitted, default is main.
Examples:
- "Create a PR" → targets
main - "Create a PR for staging" → targets
staging - "Create a PR against release-v2" → targets
release-v2
PR Description Format
When generating the PR description:
- Run
git diff <base>...HEAD(where<base>is the target branch) to see all changes on this branch. - Create or overwrite
PR_DESCRIPTION.mdin the repository root. - Write the PR description into
PR_DESCRIPTION.mdfollowing the format below. - Final response must mention the file path and briefly summarize what was written.
Output requirements:
- MUST use the write tool to create or update
PR_DESCRIPTION.md. - MUST NOT only print the PR description in chat unless the user explicitly asks for chat-only output.
- If
PR_DESCRIPTION.mdwas not written, the task is incomplete.
Template
The file has two distinct sections - the title block and the body. The title is the first non-empty line after ## Title suggestion. The body is everything from ## What onwards.
## Title suggestion
<short descriptive title here>
## What
One sentence explaining what this PR does.
## Why
Brief context on why this change is needed.
## Changes
- Bullet points of specific changes made
- Group related changes together
- Mention any files deleted or renamed
Workflow
Generate the PR description following the format above - run
git diff <target-branch>...HEAD, then createPR_DESCRIPTION.mdwith the title and body.Determine target branch: if user specified a branch, use that; otherwise
main.Read
PR_DESCRIPTION.mdto extract title and body:- Title: the first non-empty line after
## Title suggestion. Do not include the header itself. - Body: everything from
## Whatonwards (inclusive). This excludes the## Title suggestionblock entirely.
Extraction example:
# Title: first non-empty line after "## Title suggestion" TITLE=$(sed -n '/^## Title suggestion/,/^##/{/^##/d;/^$/d;p;}' PR_DESCRIPTION.md | head -1) # Body: everything from "## What" to end of file BODY=$(sed -n '/^## What/,$p' PR_DESCRIPTION.md)- Title: the first non-empty line after
Create PR via
gh pr create:gh pr create \ --base <target-branch> \ --title "$TITLE" \ --body "$BODY"- If on a fork, add
--repo <owner>/<repo>inferred fromgit remote get-url origin. - If the branch has no remote, prompt to push first with
git push -u origin HEAD. - If
ghis not authenticated, report error and stop.
- If on a fork, add
Verify the rendered body. GitHub renders every newline as a hard line break - fetch the rendered HTML and confirm there are zero
<br>tags outside code blocks:gh pr view <pr-number> --json body --jq '.body' # sanity check raw body gh api graphql -f query='query { repository(owner:"<owner>", name:"<repo>") { pullRequest(number:<pr-number>) { bodyHTML } } }' \ --jq '.data.repository.pullRequest.bodyHTML' | grep -c "<br"Expect
0. If it's nonzero, the body was wrapped somewhere before submission - fix and re-edit withgh pr edit <pr-number> --body "...", then re-verify.Clean up. Once the PR is created and the body verified, delete
PR_DESCRIPTION.md- it was a drafting scratch file, not something to leave in the repo where a later broadgit addcould sweep it into a commit.Report result: output the PR URL and a summary.
Edge Cases
| Scenario | Action |
|---|---|
| No commits on branch vs base | Warn user: no diff to create PR from |
| Branch already has open PR | Detect with gh pr list --head "$BRANCH"; reuse or abort |
| Unpushed branch | Offer to push before creating PR |
gh not installed |
Report error, suggest brew install gh |
gh not authenticated |
Report error, suggest gh auth login |
Parameter Detection
Parse the user's request for a target branch:
| Phrase | Branch |
|---|---|
| "for X" | X |
| "against X" | X |
| "into X" | X |
| "to X" | X |
| "base X" | X |
| No branch mention | main |