Automated Pull Request Review

VerifiedCaution

Review a pull request and emit a validated JSON payload with comments anchored to diff line positions.

Sby Skills Guide Bot
DevelopmentAdvanced
10/30/2026
Claude Code
#code-review#pull-request#github#git-diff#review-automation

Recommended for

Automated summary

Writes a JSON review payload for a GitHub pull request by gathering PR metadata, an annotated diff, existing review threads, and repository style rules without posting anything.

Strengths

  • Runs the metadata, diff, and existing-thread reads in parallel to reduce round trips.
  • Uses `annotate-diff` to expose old/new line numbers and comment sides for precise inline anchoring.
  • Avoids repeating prior feedback by fetching up to 100 review threads.
  • Pins commands to `$base_dir` and `$pr_checkout` so it does not analyze the wrong working tree.

Limitations

  • The skill text is cut off mid-step 3 and includes no payload schema or validation command, so the final JSON shape is underspecified.
  • Requires authenticated `gh`, `uv`, the `skills` CLI, and a shallow checkout of `refs/pull/<n>/merge`; missing any of these blocks execution.
  • It only writes the payload and deliberately posts nothing, so a separate process must submit the review.
When to use it

Use it when you need a structured, line-anchored review of a GitHub PR as JSON rather than posted comments, especially in a repository that uses the `skills` CLI.

When not to use it

Do not use it without GitHub CLI access, `uv`, or a merge-ref checkout, or when you simply want review comments posted directly.

Security analysis

Caution
Quality score86/100

The skill is a well-scoped PR-review workflow that gathers context via `gh`/`git`, analyzes the diff, and writes a JSON payload without posting anything; there is no exfiltration, obfuscated payload, credential access, or safety-disabling behavior, and it even hardens against prompt injection by pinning `--directory $base_dir` so the reviewed repo's rules/package are not used. The residual risk is that it deliberately builds and boots untrusted PR code and wields an authenticated `gh` session plus network/browser tooling, so it lands at caution rather than safe. No instruction-injection attempts were found in the content.

Findings
  • •Step 3 instructs the agent to build and boot the UI/backend of the pull request under review (`cd $pr_checkout && ...` for anything that builds or runs repository code). This executes untrusted contributor code on the reviewer's machine, which is inherent to deep PR review but is real execution surface worth flagging.
  • •The skill grants the agent broad local and network capability: `gh` (authenticated API access to the repo), `git`, `uv run`, `jq`, `agent-browser`, and web fetch/search. All uses are legitimate and scoped to reviewing, but they are powerful tools operating against a live GitHub token.
  • •Reads and writes caller-supplied paths (`$payload_path`, `$media_dir`, `$pr_checkout`) with no validation; a mis-supplied path could overwrite unintended files (e.g. jq redirect patterns in the examples). Low risk but unguarded.
  • •Ambiguity around media upload: the prose says a later workflow step uploads media and the agent must not upload, yet the `embed-media` example is passed `--repository-id`, leaving it unclear whether that path uploads artifacts. Not malicious, but the data-handling behavior is under-specified.
  • •Instructs broad shell/network use: `gh` API calls, `git` operations, web fetch/search, and `uv run` which executes the repository's own package code — all legitimate for a PR-review workflow but powerful and undeclared (no allowed-tools specified).
  • •Writes to caller-supplied absolute paths ($payload_path, $media_dir) and embeds referenced media, which could be abused to place files at arbitrary locations; mitigated by schema validation but not constrained to a sandbox.
  • •Does not post to the PR or exfiltrate data; explicitly forbids gh pr review and other posting skills, and contains no destructive, obfuscated, or secret-transmitting instructions.
How this analysis is made

Examples

Review a GitHub PR to JSON
Use the pr-review skill to review https://github.com/acme/api/pull/123 with PR checkout /tmp/pr-123, payload path /tmp/review.json, media dir /tmp/media, and base dir /workspace.
Anchor findings on changed lines
Run pr-review for https://github.com/acme/web/pull/456 using /tmp/pr-456 as the checkout, /tmp/web-review.json as the payload, /tmp/media as the media dir, and /workspace as the base dir; anchor every finding to the correct side and line from the annotated diff.
Skip duplicate review feedback
Review https://github.com/acme/service/pull/789 with pr-review, writing to /tmp/service-review.json from checkout /tmp/pr-789, media dir /tmp/media, base dir /workspace, and omit issues already covered in existing review threads.

name: pr-review description: Review a pull request and emit a validated review payload. disable-model-invocation: true argument-hint: "<pr_url> <pr_checkout> <payload_path> <media_dir> <base_dir>" arguments: [pr_url, pr_checkout, payload_path, media_dir, base_dir]

Review Pull Request

Review $pr_url and write a JSON review payload to $payload_path. Do not post anything: writing that payload is the whole job.

The reviewed tree

The PR is checked out at $pr_checkout, not in the working directory:

$base_dir             # the working directory: this skill and the `skills`
                      # CLI come from here, and nothing you review does
$pr_checkout          # the reviewed tree: the PR merged into its base

The working directory holds a checkout of the same repository, so it looks like the code under review and is not guaranteed to match it. Everything aimed at the PR needs the prefix: git -C $pr_checkout ..., $pr_checkout/<path> to open or grep a file, and cd $pr_checkout && ... for anything that builds or runs repository code. The uv run commands below are the exception: --directory $base_dir pins each one to this checkout, so it keeps using this tree's skills package and rules even when the working directory has moved into $pr_checkout. uv resolves its workspace from the working directory, and so does the rule loader, so dropping the flag silently hands both to the code under review.

Instructions

The commands below take <pr_url> from the PR URL above, and <owner>, <repo>, and <pr_number> from its parts.

1. Gather context (run in parallel)

These reads are independent. Issue them as parallel tool calls in a single turn, not sequentially.

PR title and description

gh pr view <pr_url> --json title,body

PR diff hunks. $pr_checkout holds the merge ref (see step 3), so HEAD^1 HEAD is exactly the PR diff:

git -C $pr_checkout diff HEAD^1 HEAD | uv run --directory $base_dir --package skills skills annotate-diff

Each line comes back as old_line new_line | <marker> content, which gives you the line and side to anchor each comment on: - is side=LEFT at old_line, + is side=RIGHT at new_line, and an unmarked context line is side=RIGHT at new_line. Pass --help for the rest.

Existing review threads, so you can avoid duplicating prior feedback. Up to 100 threads (open, resolved, and outdated) with up to 20 comments each:

gh api graphql -F owner=<owner> -F repo=<repo> -F pr=<pr_number> \
  --jq '.data.repository.pullRequest.reviewThreads.nodes | map(.comments = .comments.nodes)' \
  -f query='
  query($owner: String!, $repo: String!, $pr: Int!) {
    repository(owner: $owner, name: $repo) {
      pullRequest(number: $pr) {
        reviewThreads(first: 100) {
          nodes {
            isResolved
            isOutdated
            path
            line
            comments(first: 20) {
              nodes { author { login } body }
            }
          }
        }
      }
    }
  }'

2. Load repository style rules

Load the repository style rules applicable to the changed files:

git -C $pr_checkout diff --name-only HEAD^1 | uv run --directory $base_dir --package skills skills load-rules

3. Analyze the change

$pr_checkout holds the PR merged into the base (refs/pull/<pr_number>/merge), so its file contents reflect the post-merge state. Explore it for context beyond the diff (existing patterns, call sites of changed symbols, file conventions), scoping every search to that directory.

The merge ref's base parent is reachable as HEAD^1. When the diff doesn't show enough (verifying a refactor preserved behavior, reading a masked deleted file, or seeing the pre-change version of a heavily modified one), use git -C $pr_checkout show HEAD^1:<path> rather than re-fetching the file over the API. The checkout is shallow, so nothing older than HEAD^1 exists: git log and git blame stop at the shallow boundary rather than reaching the commit that actually introduced a line. Neither errors, so don't trust them for pre-change history.

Verify rather than infer. A grep through the installed package, a uv run python -c '...', a web fetch, or a web search ($base_dir/.claude/skills/pr-review/search-web.sh "<query>") will settle most questions in seconds, and an unverified finding should be dropped rather than hedged. When the cheap checks don't settle it, escalate to the expensive ones: build the docs site, build and boot the UI, start the backend.

Node and agent-browser are on PATH for docs and UI changes. Capture to an absolute path named for what it shows: agent-browser screenshot --full $media_dir/example.png, and cite that same path in a finding.

Evaluate the changed code across these dimensions:

  • Correctness: logic errors, off-by-one, incorrect API usage, broken invariants, regressions in behavior
  • Security: injection, unsafe deserialization, secret leakage, missing authz/authn, unsafe defaults
  • Edge cases: None/empty/zero inputs, concurrency, error paths, retries, large/unicode inputs
  • Efficiency: needless N+1 queries, redundant work in hot paths, allocations in tight loops
  • Readability & maintainability: unclear names, dead code, premature abstractions, comments that restate the code
  • Test coverage: new behavior lacks tests, tests assert on the wrong thing, mocks hide real failures
  • Style guide: violations of the rules loaded in step 2

Don't comment on

  • Pre-existing code. You may read unchanged/context lines to understand the change, but only file findings against the changed lines (added, modified, or deleted), even if surrounding code looks suboptimal.
  • Anything a formatter or linter already catches: unused imports, formatting, line length, simple typos.
  • Unfamiliar names and values. Model names, runner types, library versions, and dates that postdate your training data are new, not wrong.
  • Hypothetical edge cases. If the finding needs "while unlikely", "could potentially", or "edge case where" to stand up, skip it. Only flag what realistically happens.
  • Naming preferences. Flag a name only when it is actively misleading.
  • One-off literals. Don't ask for a constant to be extracted for a single use site.

Severity

Classify each finding that survives those exclusions:

  • CRITICAL: bugs, logic errors, security issues, data loss risk, broken public API.
  • MODERATE: non-blocking quality concerns where the code works but could be clearer or safer.
  • NIT: pure style/preference the author can ignore.

4. Write and validate the review payload

Read review-payload.schema.json, then write $payload_path matching it. It defines the severity prefix each comment body carries and derives event from those prefixes.

Authoring rules not captured by the schema:

  • One comment per distinct finding, anchored to the most relevant changed line. For repeated identical issues, leave a single representative comment rather than flagging every instance.
  • For findings about out-of-diff code, anchor to any changed line (prefer the same file when it has hunks) and name the actual path:line in the body.
  • Keep comments short: state the problem, why it matters, and a concrete fix in roughly three sentences plus an optional suggestion block. Cut the investigation trail (commands you ran, alternatives you weighed, evidence for a claim the reader can check in one look) and anything the suggestion block already shows.
  • Use suggestion blocks for simple fixes: fence with ```suggestion and preserve original indentation.
  • To attach an image or video (a diagram, a chart, a captured repro), write the file into $media_dir and cite it by the absolute path you wrote it to: ![desc]($media_dir/name.png) to embed, or [desc]($media_dir/name.png) to link. A later workflow step uploads it and rewrites the reference to a URL. Do not upload anything yourself. Skip this unless a visual genuinely beats prose; most reviews need none.
  • Put a video reference (.mp4, .mov, .webm) on a line of its own. GitHub renders a player only for a bare URL in its own paragraph, so a video cited mid-sentence falls back to a plain link.

Validate before finishing, then fix any errors and re-emit until both of these pass:

uv run --directory $base_dir --only-group lint check-jsonschema \
  --schemafile .claude/skills/pr-review/review-payload.schema.json "$payload_path"
# only when you wrote a file into $media_dir
set -o pipefail
jq -j '[.body, .comments[]?.body] | map(select(type == "string")) | join("\n")' "$payload_path" |
  uv run --directory $base_dir --package skills skills embed-media --check --dir "$media_dir"

When embedding a single field, extract and update it with jq rather than passing the whole JSON payload to embed-media. Use -j to avoid adding a newline to the body:

jq -j '.body' review.json | skills embed-media --check --dir "$media_dir"
jq -j '.body' review.json | skills embed-media --dir "$media_dir" --repository-id "$repo_id" > embedded-body.txt
jq --rawfile body embedded-body.txt '.body = $body' review.json > updated-review.json

Do not post the review: no gh pr review, no review/comment APIs, no other skills. Stop after writing and validating $payload_path.

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/automated-pull-request-review-mveraoc3/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

mkdir -p '.skill-downloads/automated-pull-request-review-mveraoc3' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/automated-pull-request-review-mveraoc3/download' --output '.skill-downloads/automated-pull-request-review-mveraoc3/SKILL.md.part' && mv '.skill-downloads/automated-pull-request-review-mveraoc3/SKILL.md.part' '.skill-downloads/automated-pull-request-review-mveraoc3/SKILL.md'

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.

The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.

Claude Code
test -f '.skill-downloads/automated-pull-request-review-mveraoc3/SKILL.md' && test -s '.skill-downloads/automated-pull-request-review-mveraoc3/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/pr-review' && cp -R '.skill-downloads/automated-pull-request-review-mveraoc3' '.claude/skills/pr-review'

OpenSkills

OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.

Official OpenSkills installation
openskills install './.skill-downloads/automated-pull-request-review-mveraoc3'

openskills read 'automated-pull-request-review-mveraoc3'

Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.

For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.

openskills sync

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/automated-pull-request-review-mveraoc3/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills