| name | review |
| description | Review a pull request or pending changes. Performs a focused code review against the current branch's diff (or staged diff if invoked pre-commit), surfacing correctness bugs, missing tests, style violations, and unclear naming. Use when the user asks to "review this", "review the PR", "code review", or before commits/PRs. |
Code Review Skill
You are conducting a focused code review. Your goal is to surface real issues a reviewer should catch — not produce a generic summary.
Step 1 — Determine review scope
Pick the diff source in this order:
- If the user names a PR (e.g. "review PR 42"), fetch it with
gh pr view <n> --json ... + gh pr diff <n>.
- If staged changes exist (
git diff --cached --name-only is non-empty), review the staged diff. Announce: "Reviewing staged changes."
- Otherwise, review the current branch vs
main:
base=$(git merge-base HEAD main)
git diff "$base"...HEAD
State the scope in one sentence before going deeper.
Step 2 — Gather context
- List changed files (
git diff --name-only <range>).
- Read each changed file (the whole file, not just the hunks) so you understand the context surrounding each change.
- Read any CLAUDE.md files in the repo to learn project conventions.
- If tests exist for changed modules, scan them so you know what's already covered.
Step 3 — Review
For each changed file, look for:
Correctness
- Off-by-one errors, wrong operator, swapped arguments
- Unhandled error paths, swallowed exceptions, missing
raise
- Resource leaks (open files/connections not closed, missing context managers)
- Race conditions, mutation of shared state
- Wrong return type or shape vs. what callers expect
Tests
- New behaviour without a corresponding test
- Tests that assert on incidental output rather than behaviour
- Mocks that mask real integration risk
Security (lightweight — defer deep work to /security-review)
- Obvious injection sinks (SQL string concatenation,
shell=True, eval)
- Secrets in code or logs
- Missing input validation at trust boundaries
Style & clarity
- Names that don't match what the thing does
- Comments that say WHAT (delete) vs WHY (keep if non-obvious)
- Dead code, unused imports, commented-out blocks
- Over-engineering: speculative abstractions, premature config knobs, error handling for impossible cases
- Violations of project conventions (line length, formatter, import order — check CLAUDE.md)
Scope
- Changes outside the stated purpose of the PR (unrelated refactors mixed in)
- Half-finished work, TODOs added without tickets
Step 4 — Report
Output format — be terse:
## Review: <one-line scope>
### Blocking
- `path/to/file.py:42` — <issue>. <one-line fix suggestion>
### Should fix
- `path/to/file.py:88` — <issue>.
### Nits
- `path/to/file.py:12` — <issue>.
### Looks good
<1-2 sentences on what's solid — only if there's something genuinely worth calling out>
Rules:
- Use
file:line references so the user can jump to the source.
- "Blocking" = correctness or security bug; do not block on style.
- If there's nothing in a category, omit the heading entirely.
- If the diff is clean, say so in one sentence. Don't pad.
- Do NOT summarise what the PR does — the user wrote it and can read the diff.
Step 5 — If invoked from /commit or /implement
When the caller is another slash command (not the user directly), it may auto-apply your suggestions. In that case:
- Be explicit about which findings are mechanical fixes (formatter, rename, delete dead code) vs. judgement calls that need user input.
- Tag judgement calls with
[needs-decision] so the caller knows to surface them rather than silently auto-apply.