| name | review-pr |
| description | Review a PR with the pr-review-toolkit agents plus a security pass. No argument reviews your own draft PR and applies fixes. A PR number reviews the author's code via inline comments, no edits. |
Review — PR Review
Context-aware PR review. Auto-detects whether you're reviewing your own draft or someone else's PR and runs the right mode. Every review includes a security-focused pass (a checklist similar to /security-review, run as an in-process agent rather than invoking that skill) alongside the pr-review-toolkit agents.
Arguments
$ARGUMENTS — Optional PR number or URL, plus optional flags
- (none) — Auto-detect from current branch → your draft PR → self-review mode
#123 or URL — Your PR: self-review mode. Someone else's PR: review mode (no edits).
--no-mark-ready — Self-review mode only: run Steps 1–8 (post review, apply fixes, push, post improvements summary, update PR description) but skip Step 9 (the mark-ready prompt + gh pr ready). Used by hero-skills:one-shot so its DAG can render self-review (Step 5) and mark-ready (Step 6) as distinct nodes without double-prompting. Combine with a PR number/URL as needed (#42 --no-mark-ready).
Parse $ARGUMENTS for the flag once at the top of Step 0:
NO_MARK_READY=false
ARGS_FILTERED=""
for tok in $ARGUMENTS; do
case "$tok" in
--no-mark-ready) NO_MARK_READY=true ;;
*) ARGS_FILTERED="$ARGS_FILTERED $tok" ;;
esac
done
ARGS_FILTERED=$(printf '%s' "$ARGS_FILTERED" | sed 's/^ //')
Prerequisites
gh CLI installed and authenticated
- The
pr-review-toolkit plugin available
Instructions
Step 0: Load Configuration and Detect Mode
ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
cat "$ROOT/HERO.md" 2>/dev/null || echo "NO_HERO_CONFIG"
Read HERO.md for:
- Code Quality → pre-commit (re-run after fixes in self-review mode)
- Code Review Agent → bot username (to avoid duplicating its comments)
If HERO.md is missing, suggest hero-skills:init-hero but proceed with defaults.
Detect the PR and mode:
BRANCH=$(git branch --show-current)
ME=$(gh api user --jq '.login' 2>/dev/null)
if [ -n "$ARGUMENTS" ]; then
PR_ARG=$(printf '%s' "$ARGUMENTS" | awk '{print $1}')
PR_JSON=$(gh pr view "$PR_ARG" --json number,url,headRefName,baseRefName,state,isDraft,author)
else
PR_JSON=$(gh pr list --head "$BRANCH" --json number,url,headRefName,baseRefName,state,isDraft,author --jq '.[0]')
fi
if [ -z "$PR_JSON" ] || [ "$PR_JSON" = "null" ]; then
echo "No PR found for branch '$BRANCH'. Run hero-skills:push-pr first."
exit 1
fi
PR_NUMBER=$(echo "$PR_JSON" | jq -r '.number')
PR_AUTHOR=$(echo "$PR_JSON" | jq -r '.author.login')
IS_DRAFT=$(echo "$PR_JSON" | jq -r '.isDraft')
PR_BRANCH=$(echo "$PR_JSON" | jq -r '.headRefName')
PR_URL=$(echo "$PR_JSON" | jq -r '.url')
PR_STATE=$(echo "$PR_JSON" | jq -r '.state')
Mode selection:
| Condition | Mode |
|---|
| No PR found | STOP — "No PR for '$BRANCH'. Run hero-skills:push-pr first." |
| Closed/merged | STOP — Report status. |
| PR author is you AND draft | Self-review mode |
| PR author is you AND not draft | Warn "PR is already ready-for-review — continue self-review? [y/N]" |
| PR author is someone else | Review mode (no edits) |
Self-Review Mode
Step 1: Ensure on Correct Branch
CURRENT=$(git branch --show-current)
If CURRENT != PR_BRANCH, check for uncommitted changes:
git status --porcelain
If uncommitted changes exist, STOP — show what's uncommitted and tell the user to commit or cancel. Never silently stash.
When working tree is clean, switch:
git fetch origin "$PR_BRANCH"
git checkout "$PR_BRANCH"
git pull origin "$PR_BRANCH"
Step 2: Run All Review Agents in Parallel
Launch all six review agents simultaneously in a single message — the five pr-review-toolkit agents plus the security agent:
Agent(subagent_type="pr-review-toolkit:code-reviewer", ...)
Agent(subagent_type="pr-review-toolkit:silent-failure-hunter", ...)
Agent(subagent_type="pr-review-toolkit:pr-test-analyzer", ...)
Agent(subagent_type="pr-review-toolkit:comment-analyzer", ...)
Agent(subagent_type="pr-review-toolkit:type-design-analyzer", ...)
Agent(subagent_type="general-purpose", security review — prompt spec below)
Security agent prompt spec. Give the agent the PR diff scope (repo path, branch/PR number) and this brief: review ONLY for security vulnerabilities that are plausibly exploitable in the changed code — injection (SQL/command/template), XSS, authentication/authorization flaws, secrets or credentials in code or logs, SSRF, path traversal, unsafe deserialization/RCE, cryptographic misuse, and sensitive-data exposure. High signal only: every finding needs a concrete exploit scenario (who sends what, what happens). Explicitly EXCLUDE noise categories — denial-of-service/rate-limiting, memory safety in memory-safe languages, theoretical issues with no plausible attack path, and anything requiring an already-privileged attacker position. Return findings with file:line, severity (Critical = exploitable, Important = realistic hardening gap), and the exploit scenario; return "NO FINDINGS" when clean.
Wait for all agents to complete, then aggregate findings into: Critical (bugs, security, data loss), Important (quality, correctness), Suggestions (style, polish), Strengths. Security findings land in Critical/Important per the spec above — never bury an exploitable finding in Suggestions.
Step 3: Post Review Comment
gh pr comment $PR_NUMBER --body "$(cat <<'EOF'
## Self-Review
<!-- ai-hero:self-review -->
### Critical ({N})
- [agent] {file:line} — {finding}
### Important ({N})
- [agent] {file:line} — {finding}
### Suggestions ({N})
- [agent] {file:line} — {finding}
### Strengths
- {what's well-done}
---
_Generated using hero-skills._
EOF
)"
Omit empty sections.
Step 4: Ask Permission to Apply Fixes
Show the findings summary and ask:
Apply fixes? [Default: all]
1. All (critical + important + suggestions) ← default
2. Only critical + important
3. Only critical
4. Pick individually
5. Skip — leave the comment only
Wait for the user's choice. If "individually", walk through each finding yes/no.
Step 5: Apply Fixes
For each accepted finding:
- Read the file and surrounding context.
- Apply the minimal fix — don't refactor surrounding code.
- Track changed files.
- If a finding is ambiguous or conflicts with another, stop and ask.
After all fixes:
if command -v pre-commit > /dev/null 2>&1; then
pre-commit run --files "${CHANGED_FILES[@]}"
else
echo "NO_PRECOMMIT"
fi
Fix any pre-commit failures before continuing.
Step 6: Commit and Push Fixes
git add "${CHANGED_FILES[@]}"
git commit -m "$(cat <<'EOF'
fix: address self-review findings
- {summary of fix 1}
- {summary of fix 2}
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
EOF
)"
git push origin "$PR_BRANCH"
Commit logically distinct fixes separately if they touch unrelated areas.
Step 7: Post Improvements Summary
Always post this, even when no fixes were applied. This is the durable record that the review ran.
Render the template with real values — never post literal placeholders. Omit sections whose count is zero.
gh pr comment $PR_NUMBER --body "$(cat <<'EOF'
## Self-Review — Improvements
<!-- ai-hero:self-review -->
**Critical (A / X fixed):**
- FILE:LINE — FINDING — FIX_DESCRIPTION
**Important (B / Y fixed):**
- FILE:LINE — FINDING — FIX_DESCRIPTION
**Suggestions (C / Z fixed):**
- FILE:LINE — FINDING — FIX_DESCRIPTION
**Skipped:**
- FILE:LINE — FINDING — REASON
Commits: SHA1, SHA2
---
_Generated using hero-skills._
EOF
)"
If the post fails, surface the rendered body for manual paste — do NOT swallow the error.
Step 8: Update PR Description if Scope Changed
Update when:
- New files added by fixes weren't in the original description
- Critical fixes changed observable behavior (security, data-loss, correctness)
- Features were removed or defaults changed
Leave unchanged for: style/typo/comment fixes only. Default to update when uncertain.
gh pr view $PR_NUMBER --json title,body --jq '{title, body}'
Draft the full new body preserving structure (Summary, Changesets, Test Plan) and ending with _Generated using hero-skills._ as the final line, then apply:
gh pr edit $PR_NUMBER --title "NEW_TITLE_UNDER_70_CHARS" --body "$(cat <<'EOF'
DRAFTED_FULL_BODY_HERE
EOF
)"
Substitute DRAFTED_FULL_BODY_HERE with actual Markdown before running — the drafted body must end with _Generated using hero-skills._.
Step 9: Ask to Mark Ready
Skip this step entirely when $NO_MARK_READY is true (caller passed --no-mark-ready, typically hero-skills:one-shot whose own Step 6 owns the mark-ready gate). In that case, jump straight to Step 10 — the summary will show PR state: Draft (mark-ready deferred to caller).
Otherwise, ask the user:
Self-review complete.
Critical fixed: A/X | Important fixed: B/Y | Suggestions fixed: C/Z
Convert draft PR #{number} to ready-for-review? [y/N]
Wait for the user's confirmation. Never mark ready without it.
gh pr ready $PR_NUMBER
Step 10: Summary
Self-Review Summary
===================
PR: #{number} - {title}
Branch: {branch}
Findings:
Critical: X (Y fixed, Z skipped)
Important: A (B fixed, C skipped)
Suggestions: D (E fixed, F skipped)
Commits: N pushed
PR description: {updated | left as-is} ({reason})
PR state: {Draft / Ready for review}
URL: {pr-url}
Next step: (pick exactly one, based on what actually happened above)
$NO_MARK_READY is true (deferred to caller, e.g. one-shot): no next-step line — the caller owns what happens next (one-shot's own Step 7 mark-ready gate).
- Marked ready, agent configured: print
Waiting on {agent}'s first review — then run hero-skills:respond-to-comments. (no prompt, nothing to invoke yet).
- Marked ready,
agent: none: Next step: hero-skills:ship-pr — @auto-approve, merge, reset (offer to auto-run: ask "Run it now? [y/N]", invoke via Skill tool on yes).
- Declined mark-ready:
Next step: address the findings above, then re-run hero-skills:review-pr. (print only — re-invoking the same skill right after it finishes isn't auto-chained).
Review Mode (Someone Else's PR)
Step 1: Get PR Context
OWNER, REPO, PR_NUMBER, HEAD_SHA from Step 0 detection.
gh pr diff $PR_NUMBER
gh api "repos/$OWNER/$REPO/pulls/$PR_NUMBER/comments" \
--jq '.[] | {path: .path, line: .line, body: .body, user: .user.login}'
gh pr view $PR_NUMBER --json commits --jq '.commits[].messageHeadline'
Read the PR description carefully — it explains design decisions.
If diff exceeds 1500 lines or 50 files, warn and ask to focus on specific paths.
Step 2: Run All Review Agents in Parallel
Same as self-review Step 2: launch all six review agents (the five pr-review-toolkit agents plus the security agent, same prompt spec) simultaneously and aggregate findings.
Step 3: Post Inline Comments
Map severity to prefix:
| Category | Prefix |
|---|
| Critical | 🔴 |
| Important | 🟡 |
| Suggestion | 🔵 nit: |
| Question | ❓ |
| Strength | 👍 |
Comment guidelines: be specific, constructive, respectful. Skip findings already raised by others. Skip nits the linter catches.
OWNER=$(echo "$PR_URL" | awk -F/ '{print $4}')
REPO=$(echo "$PR_URL" | awk -F/ '{print $5}')
HEAD_SHA=$(gh pr view "$PR_NUMBER" --json commits --jq '.commits[-1].oid')
gh api "repos/$OWNER/$REPO/pulls/$PR_NUMBER/comments" \
-f body="$COMMENT_BODY" \
-f commit_id="$HEAD_SHA" \
-f path="$FILE_PATH" \
-F line=$LINE_NUMBER \
-f side="RIGHT"
For multi-line: also pass -F start_line=$START_LINE -f start_side="RIGHT".
Step 4: Submit Overall Review
| Has criticals? | Has importants? | Decision |
|---|
| Yes | — | --request-changes |
| No | Yes | --comment |
| No | No | --approve (unless questions remain) |
gh pr review $PR_NUMBER {DECISION_FLAG} --body "$(cat <<'EOF'
## Review Summary
**Findings:** {X} critical, {Y} important, {Z} suggestions
### Overall Assessment
{1-3 sentence summary}
### Key Findings
- {most important issue}
- {second most important}
### What's Good
- {positive observations}
---
_Generated using hero-skills._
EOF
)"
Step 5: Report
Review Summary
==============
PR: #{number} - {title}
Author: @{username}
Files: {N} changed (+A -D)
Findings:
🔴 Critical: {X}
🟡 Important: {Y}
🔵 Suggestions: {Z}
❓ Questions: {W}
Inline comments posted: {N}
Decision: {Comment / Approve / Request Changes}
URL: {pr-url}
Notes
- Never edit code in review mode — only post comments.
- Never mark a PR ready without explicit user confirmation.
- Do not auto-resolve other reviewers' comments.