Skip to content
Back to skills

Pr Update

ASecurity

Update a PR description to account for commits made since it was last written

  • 5 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 27, 2026
data-aigobashgit

Security analysis

A100/100

Scanned October 2, 2026

npx -y skills add JasonWarrenUK/goblin-mode --skill pr-update --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Pr Update?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Pr Update
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jasonwarrenuk-pr-update/badge)](https://www.skillsdirectory.com/skills/jasonwarrenuk-pr-update)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: "PR: Update"
description: "Update a PR description to account for commits made since it was last written"
when_to_use: "When commits have been pushed to a branch after its PR was opened or last described; offer it whenever new work lands on a branch with an open PR rather than leaving the description stale."
model: sonnet
effort: medium
metadata:
  glyph: ᛊ
  family: pr
disable-model-invocation: false # invocable by Claude so it can offer a refresh when new commits leave the description stale; its approval step still gates the write
allowed-tools: ["Bash(git:*)", "Bash(gh:*)", "Bash(~/.claude/library/scripts/pr-facts.sh:*)", "Bash(~/.claude/library/scripts/slop-scan.py:*)", "Bash(~/.claude/library/scripts/md-lint.py:*)", "Read", "Glob", "Grep"]
arguments: ["pr"]
argument-hint: "[PR number | URL]"
---

# Update an Existing PR

Update the description of the PR named by `$ARGUMENTS`, or of the current branch's PR when no argument is given.

## Steps

### 0. Resolve the identifier

Pick `{pr}` out of `$ARGUMENTS`: the one token that is a PR number or a `github.com/.../pull/<n>` URL. With no argument at all, `{pr}` is empty and both commands below resolve the current branch's PR on their own. Any other bare token is an error, never passed through: `pr-facts.sh` reads only its first argument, and `gh` treats an unknown word as a branch name and reports "no pull requests found" with exit 0, so a stray token would fail quietly at the wrong step.

### 1. Gather the facts in one call

```bash
"$HOME"/.claude/library/scripts/pr-facts.sh {pr}
```

It prints the PR metadata, the current body, the watermark (`<!-- pr-update-watermark: <sha> -->`, or "none" when the whole branch is new), every commit since it with per-commit stats, and the SHA to use as the next watermark. Analyse that dump rather than running exploratory `gh`/`git` calls. Exit **3** means no new commits; tell me the description is already up to date and stop. Exit **2**: report the script's message.

### 2. Analyse the new commits

From the dump, understand what changed and why. Group related commits into coherent change categories. Run `git show <sha>` on a specific commit only where the stat alone can't tell you what a change is.

### 3. Produce the updated PR body

Take the existing body (in the dump) and update it:

- **Do not rewrite from scratch.** Preserve existing content unless it is now inaccurate.
- The body structure follows `~/.claude/library/templates/pr-description.md` (the same template `pr-create` fills); keep updates within that structure rather than adding new top-level sections.
- **Integrate, never append.** Fold the new work into the existing sections: `## Changes` gains or amends entries, summaries absorb the new scope, stale statements get corrected in place. Bolting an "updates since" block onto the end of the description is the failure mode this step exists to prevent: the reader must see one coherent current description, not a base version plus a changelog of patches.
- **Provenance lives in its own trail, not in the body content.** Maintain a single collapsible block immediately above the watermark:

  ```markdown
  <details><summary>Update history</summary>

  - 2026-08-13: folded in <one-line summary> (`<first-sha>..<last-sha>`)

  </details>
  ```

  It sits under the template's closing `---`, with a blank line between; add no rule of its own. The blank line above `</details>` is load-bearing: without it the closing tag joins the list and anything after it renders raw.

  Append one dated line per update run. This block records *that* and *when* the description changed; the substantive content itself always lands in the sections above.
- The Overview follows the template's current rule: what and why for a non-dev, 2-4 sentences or a lead-in plus at most 5 bullets, with no code identifiers, file paths, figures or test results. New work that is its own unit becomes its own sentence or bullet rather than a clause bolted onto an existing one.
- **Layout is not content**, so the "do not rewrite" rule above does not shield a body written to an older template. Reshape it while folding the new work in, changing no facts:
  - a long or dense Overview gets cut down, with its mechanics moved into the matching Changes block;
  - verification runs and "not checked" notes move into the Verification section;
  - breaking-change notes move into the WARNING alert under the TIP;
  - Changes blocks gain their intro, a reason per bullet and a **Review:** line where they lack them.

  Verification and WARNING are template sections, so adding them is not a new top-level section.
- Keep every blank line the template has: before and after each `---` and `</details>`, before each `<details>` and after each `<summary>`, with `<summary>` directly under its `<details>`.
- If the description references behaviour that has changed, correct it.
- Insert or replace the watermark comment at the very end of the body, using the `next watermark sha` from the dump:

```text
<!-- pr-update-watermark: <latest-sha> -->
```

### 4. Scan the updated body

Before showing it:

```bash
~/.claude/library/scripts/slop-scan.py --strict - <<'SLOP_EOF'
<updated body>
SLOP_EOF
```

Then lint the typography:

```bash
~/.claude/library/scripts/md-lint.py - <<'MD_EOF'
<updated body>
MD_EOF
```

Fix every md-lint hit before showing the body (almost always a missing blank line, or backticks inside `<summary>`); a PreToolUse hook blocks `gh pr edit` on the same rules. For slop-scan, a non-zero exit means rewrite to clear every `L<n> <rule>: <excerpt>` line and rescan, at most twice. Hits in text you did not write (the existing body) count too; this is the moment they get fixed. If hits remain, carry them to step 5 listed under the body so I decide.

### 5. Show me the diff

Display the updated body in full and a brief summary of what changed vs the previous description. **Wait for my approval.**

### 6. Apply the update

Once approved, pass the body on stdin so quoting never mangles it:

```bash
gh pr edit {pr} --body-file - <<'PR_EOF'
<updated body>
PR_EOF
```

Confirm success.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…