Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Update an existing GitHub pull request's title and description to reflect the current state of the branch. Use when the user asks to "update the PR", "update PR description", "update PR title", "refresh PR description", or "sync PR with changes".
.claude/skills/tobihagemann-update-pr/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-10 | ✗→✓ | ▲ Improved | 36% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 0% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 105% | 0% |
| case-17 | ✗→✓ | ▲ Improved | 11% | 0% |
| case-23 | ✗→✓ | ▲ Improved | 0% | 0% |
Read the current PR title and body, analyze what changed in the session, and draft an updated title and description that preserves the original writing style.
Fetch the current PR details:
bashgh pr view [PR_NUMBER] --json number,title,body,baseRefName,headRefName,updatedAt,commits
Omit PR_NUMBER to auto-detect from current branch.
Before drafting, study the current title and body to identify:
feat:, fix:), capitalizationUse the PR's updatedAt field and commit timestamps to determine whether new commits were added since the body was last edited.
If commits_since_body_change is empty, the description is already up to date — say so and stop.
Run git fetch origin <base> so the remote ref is current before any diff below. A local branch of the same name can sit behind the remote, which puts the merge base before an already-merged pull request and pulls merged work into the description.
If there are commits since the last body change, check the incremental diff to assess significance:
bashgit diff origin/<base>...HEAD --diff-filter=d --stat -- $(git log --since="<body_last_changed>" --name-only --pretty=format: origin/<base>..HEAD | sort -u)
Skip the update if the incremental changes are trivial (formatting, typos, config-only). Proceed if they add, remove, or modify meaningful behavior.
Derive the PR description from the full diff, not from individual commits. The description should reflect the net change — what the code looks like now vs. the base — not the development journey. Intermediate bug fixes, reverted approaches, and implementation pivots that happened during development are not relevant to the reader.
git diff origin/<base>...HEAD for the full scope of changes — this is the primary source of truth$github-voice SkillRun the $github-voice skill to load writing style rules.
Write an updated title and body that:
Output the drafted title and description as text, alongside the original for comparison. Then use request_user_input for confirmation.
After confirmation, write the drafted title to .turbo/pr/<PR_NUMBER>-title.txt and the drafted body to .turbo/pr/<PR_NUMBER>-body.md with apply_patch, then update the PR. The title goes through a file because it carries text fetched from the PR, where backticks and $ would run inside a quoted argument:
bashgh api --method PATCH "/repos/<owner>/<repo>/pulls/<PR_NUMBER>" \ -F title=@.turbo/pr/<PR_NUMBER>-title.txt \ -F body=@.turbo/pr/<PR_NUMBER>-body.md
GitHub renders Mermaid natively in PR descriptions via mermaid code blocks. Include diagrams only when they add clarity a text description can't.
Include when the changes introduce or modify a clear runtime flow: API endpoints, event handlers, pipelines, multi-service interactions, webhook flows.
`markdown
sequenceDiagram Client->>API: POST /payments API->>PaymentService: processPayment() PaymentService->>StripeClient: charge() StripeClient-->>PaymentService: confirmation PaymentService->>DB: save()
Include when the changes add or modify entity states, status enums, workflow transitions, or lifecycle hooks.
`markdown
stateDiagram-v2 ] --> Draft Draft --> Pending: submit() Pending --> Approved: approve() Pending --> Rejected: reject() Approved --> []
## Flow or ## State Machine heading.turbo/ content (filenames, acceptance criteria, step numbers, headings) in the title or body. .turbo/ is gitignored, so these references would be opaque to anyone reading without local copies.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-10 | fail→pass | 8,960 | 3,324 | -63% | 1 | 1 | 0% | 1,242 | 1,689 | +36% | 0 | 0 | — |
case-01 | fail→fail | 3,530 | 44,509 | +1161% | 1 | 1 | 0% | 522 | 1,551 | +197% | 0 | 0 | — |
case-02 | fail→fail | 4,881 | 4,915 | +1% | 1 | 1 | 0% | 820 | 1,606 | +96% | 0 | 0 | — |
case-03 | fail→fail | 13,503 | 5,032 | -63% | 1 | 1 | 0% | 932 | 1,538 | +65% | 0 | 0 | — |
case-04 | pass→fail | 11,958 | 8,811 | -26% | 1 | 1 | 0% | 675 | 1,647 | +144% | 0 | 0 | — |
case-09 | pass→fail | 19,253 | 6,299 | -67% | 1 | 1 | 0% | 1,238 | 1,609 | +30% | 0 | 0 | — |
case-05 | pass→fail | 4,278 | 9,158 | +114% | 1 | 1 | 0% | 738 | 1,985 | +169% | 0 | 0 | — |
case-06 | fail→fail | 4,140 | 12,600 | +204% | 1 | 1 | 0% | 464 | 2,414 | +420% | 0 | 0 | — |
case-07 | pass→pass | 7,756 | 2,810 | -64% | 1 | 1 | 0% | 1,279 | 1,721 | +35% | 0 | 0 | — |
case-08 | fail→pass | 12,093 | 6,537 | -46% | 1 | 1 | 0% | 2,350 | 2,340 | -0% | 0 | 0 | — |
case-11 | fail→pass | 4,694 | 13,079 | +179% | 1 | 1 | 0% | 749 | 1,537 | +105% | 0 | 0 | — |
case-12 | pass→pass | 7,526 | 3,361 | -55% | 1 | 1 | 0% | 1,032 | 1,771 | +72% | 0 | 0 | — |
case-13 | pass→fail | 5,319 | 2,773 | -48% | 1 | 1 | 0% | 841 | 1,718 | +104% | 0 | 0 | — |
case-14 | pass→pass | 10,774 | 2,566 | -76% | 1 | 1 | 0% | 1,667 | 1,675 | +0% | 0 | 0 | — |
case-15 | fail→fail | 16,753 | 2,298 | -86% | 1 | 1 | 0% | 1,660 | 1,658 | -0% | 0 | 0 | — |
case-16 | fail→fail | 9,594 | 1,828 | -81% | 1 | 1 | 0% | 1,344 | 1,544 | +15% | 0 | 0 | — |
case-17 | fail→pass | 11,473 | 2,652 | -77% | 1 | 1 | 0% | 1,514 | 1,686 | +11% | 0 | 0 | — |
case-18 | fail→fail | 14,119 | 18,891 | +34% | 1 | 1 | 0% | 2,171 | 1,680 | -23% | 0 | 0 | — |
case-19 | pass→pass | 15,522 | 3,941 | -75% | 1 | 1 | 0% | 2,222 | 2,083 | -6% | 0 | 0 | — |
case-20 | fail→fail | 8,586 | 3,074 | -64% | 1 | 1 | 0% | 1,140 | 1,819 | +60% | 0 | 0 | — |
case-21 | pass→pass | 7,784 | 2,261 | -71% | 1 | 1 | 0% | 1,073 | 1,645 | +53% | 0 | 0 | — |
case-22 | fail→fail | 10,289 | 1,992 | -81% | 1 | 1 | 0% | 1,534 | 1,565 | +2% | 0 | 0 | — |
case-23 | fail→pass | 13,425 | 4,420 | -67% | 1 | 1 | 0% | 1,792 | 1,792 | 0% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted, and 16 counted toward the lift figure. The other 7 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +4 percentage points is the difference between those two pass rates over the 16 comparable cases. 4 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/21/2026 | +27% |
Other measured skills in the registry, with their headline benchmark lift.