Gen PR
Produce one PR draft per invocation. An independent --create token in the current invocation enables create mode; without it, use draft mode. Remove the token first, then parse the remaining input for the source and target branches.
Guardrails
- Keep the repository and working tree read-only during analysis. Do not change their state with
fetch,pull,push, orcheckout. - The only writes are one
gh pr createauthorized by--createor by selectingcreate-prafter the draft, and onegh pr editseparately authorized for an existing PR. - Ground every claim in the title and body in the diff, commits, or project PR template.
- Pass branch names and generated text as separate, correctly shell-escaped arguments. Do not compose generated text into shell syntax.
Workflow
1. Resolve the branches
When the request omits the source, use the current branch:
git branch --show-current
An empty result means detached HEAD. Ask for the source branch.
When the request omits the target, discover the remote default branch:
git symbolic-ref --short refs/remotes/origin/HEAD
For example, when the result is origin/main, use main as the PR target and origin/main as the comparison ref. Ask for the target only when the default branch cannot be discovered. When the user supplies a target, first use that name as the comparison ref; if it does not exist, try origin/<target>.
Verify that the source and comparison ref each resolve to a commit:
git rev-parse --verify --end-of-options "<ref>^{commit}"
On failure, identify the invalid ref and ask only for that branch again. This step is complete when both refs resolve and the PR target and comparison ref are identified separately.
2. Resolve the PR template
Use read to check these files in order and use the first one that exists:
.github/pull_request_template.md.github/pull_request_template.txt.github/PULL_REQUEST_TEMPLATE.md.github/PULL_REQUEST_TEMPLATE.txt.github/PULL_REQUEST_TEMPLATE/pull_request_template.mddocs/pull_request_template.md
If none exists, search file paths once for pull_request_template. Use the sole candidate when exactly one exists. When multiple distinct candidates exist and their names do not identify the applicable one, ask the user to choose. When no candidate exists, use the default template in the PR Writing Contract.
This step is complete when one project template or the default template is selected.
3. Describe the change snapshot
Collect these four results:
git log "<comparison>..<source>" --format='%h %s' --no-merges
git diff "<comparison>...<source>" --stat
git diff "<comparison>...<source>" --name-status
git diff "<comparison>...<source>"
If a command fails, return its error and do not produce a draft. If name-status is empty, output No changes with the two compared refs and stop.
If the full diff is truncated, read every missing path from name-status with the following command. Escape each path exactly.
git diff "<comparison>...<source>" -- "<path>"
Classify every changed path as added, modified, deleted, renamed, binary, or submodule. Record significant function, class, component, configuration, and documentation changes. Commit messages may help interpret the diff but cannot support a claim that conflicts with it.
This step is complete when every changed path and significant hunk is represented in the description or explicitly classified as insignificant, and the complete diff is retained as the analysis snapshot.
4. Write the title and body
Read and apply the complete PR Writing Contract.
When using a project template, preserve its structure, fixed text, instructions, and checklists. Fill only placeholders supported by evidence, and leave unverified checkboxes unchecked. When using the default template, omit unnecessary sections according to the contract.
Produce one final title and one concise, complete body. Select the title internally and expose only that selection; candidate lists and alternative titles are invalid output. Completion criteria:
- Every concrete claim in the title and body is verified by the analysis snapshot.
- Every significant change is covered with the fewest non-duplicative sentences or bullets.
- No speculation, duplication, empty placeholder, or optional section without reviewer value remains.
- The required structure of the project template remains intact.
- Every title, style, and length rule in the contract is satisfied.
5. Deliver the draft or write the PR
Draft mode
Present the draft in this format:
PR title:
```
[Title]
```
PR body:
```
[Body]
```
Next action:
- `edit-draft`: Request changes to the title or body
- `create-pr`: Create the PR from this draft
- `stop`: Finish without creating a PR
For edit-draft, apply the requested changes, recheck the Step 4 completion criteria, and show the full title and body. For create-pr, continue to the creation procedure below. For stop, end without writing a PR.
Creation procedure
Rerun the complete diff from Step 3 and compare it with the analysis snapshot. If it changed, repeat Steps 3 and 4 with the new snapshot.
List open PRs with the same source and target:
gh pr list --head "<source>" --base "<target>" --state open --json url,title,body,baseRefName,headRefName
If the lookup fails, return the error instead of guessing whether a PR exists. If it returns an empty array, create the PR and retain the returned URL:
gh pr create --base "<target>" --head "<source>" --title "<title>" --body "<body>"
If one PR exists, show its URL and the new draft, then ask for approval to update it. If multiple PRs exist, ask the user to select one. After approval, edit the selected PR explicitly:
gh pr edit "<PR URL>" --title "<title>" --body "<body>"
After creating or editing, run gh pr view with the retained URL. Success requires a present URL and title, body, baseRefName, and headRefName values that exactly match the resolved values. On success, output only the URL and title.
If a command fails or verification differs, do not claim success. Return the error, generated title and body, and the correctly escaped command for manual execution.
Allowed Commands
git branch --show-currentgit symbolic-ref --short refs/remotes/origin/HEADgit rev-parse --verify --end-of-options "<ref>^{commit}"git log "<comparison>..<source>" --format='%h %s' --no-mergesgit diff "<comparison>...<source>" --statgit diff "<comparison>...<source>" --name-statusgit diff "<comparison>...<source>"git diff "<comparison>...<source>" -- "<path>"gh pr list --head "<source>" --base "<target>" --state open --json url,title,body,baseRefName,headRefNamegh pr create --base "<target>" --head "<source>" --title "<title>" --body "<body>"gh pr edit "<PR URL>" --title "<title>" --body "<body>"gh pr view "<PR URL>" --json url,title,body,baseRefName,headRefName