From pr-review
Deep code-centric review of pull requests for the moving-frontend monorepo. Use when the user mentions reviewing a PR, triaging GitHub Copilot or CodeRabbit comments, doing a code review, or wants feedback on a team member's code. Also trigger for "리뷰", "PR 리뷰", "코드 리뷰", "review PR", "review this PR", "Copilot review", "GitHub Copilot review", or when a PR doc path or GitHub PR URL is provided. Performs independent deep code analysis with git-truth validation, provider-aware AI review triage, and educational Korean-language feedback. AI review triage is secondary — the review stands alone even with 0 Copilot/CodeRabbit comments.
How this skill is triggered — by the user, by Claude, or both
Slash command
/pr-review:pr-reviewThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Help Eddie (team leader) efficiently review PRs through independent deep code analysis. Produce structured review documents with git-truth validation, scope-aware findings, educational feedback, and developer growth tracking.
evals/evals.jsonevals/phase-0-evals.jsonreferences/coderabbit-triage-guide.mdreferences/copilot-triage-guide.mdreferences/feedback-templates.mdreferences/fix-forward-template.mdreferences/output-template.mdreferences/review-criteria.mdscripts/fetch-pr.shscripts/generate-decisions-json.shscripts/post-ai-review-comments.shscripts/post-review-comments.shscripts/prepare-pr-worktree.shscripts/resolve-ai-review-threads.shscripts/resolve-threads.shscripts/update-review-round-doc.shHelp Eddie (team leader) efficiently review PRs through independent deep code analysis. Produce structured review documents with git-truth validation, scope-aware findings, educational feedback, and developer growth tracking.
On startup, check for a settings file at .claude/pr-review.local.md (relative to the project root). If it exists, read the YAML frontmatter to configure behavior:
output_language — review feedback language (default: ko)default_review_source — default --review-source value (default: all)default_repo_path — default --repo-path for auto mode (avoids passing it every time)full_review_dimensions / quick_review_dimensions — which of the 9 dimensions to check per modefix_forward_exclusions — file patterns that fix-forward should never auto-modifytrack_developer_profiles — whether to create/update developer profilesIf the settings file doesn't exist, use the defaults defined in this skill. Settings from the file override the defaults. CLI flags (e.g., --review-source copilot) override settings.
Output language: Determined by output_language setting. Default: Korean with English technical terms (component names, TypeScript types, React concepts).
--quick) — Skip AI review triage + developer history. Focused git-truth validation and streamlined code review. Use for fast turnaround when provider output is unavailable or irrelevant. The output document must completely omit the AI review triage section (not include it with a "skipped" note — omit it entirely). Quick mode also reduces review depth: focus on the top 5 dimensions (Bugs & Correctness, Architecture/FSD, React & TypeScript, Error Handling, Performance) and skip Sibling Consistency, DRY/Duplication, UI/Design System, and Accessibility unless an obvious issue is spotted. This produces a meaningfully shorter and faster review, not just the same review minus the triage section.--triage-only) — Only process GitHub Copilot and/or CodeRabbit comments without deep code review--history <github-id>) — Show a developer's accumulated review patterns--auto <PR#>) — Worktree-aware end-to-end pipeline: fetch PR data, run the full review, prepare a managed Round N record, generate provider-neutral artifacts, preview mutations safely, and only perform live commit/push/reply/resolve when --live is explicitly present. Auto mode executes the workflow; it does not invent autonomous review judgment. See Step 11.When invoked, extract these from the user's message:
docs/pr-for-review/[TICKET-ID] ...mdACME-595/split-place-card# [TICKET] Title by <github-id>) or ask the userACME-595). Used for scope determination.--review-source <all|coderabbit|copilot|none>. Default is all for Full Review / Triage Only / Auto Review and none for Quick Review.--repo-path <abs-path>. Explicit target product repo path for auto mode. If omitted, check default_repo_path from .claude/pr-review.local.md settings. If neither is set, resolve from the current working directory only; never guess across repos.--review-doc <path>. Optional explicit Round N review record path. Resolution precedence is: explicit --review-doc, then docs/reviews/<TICKET>-review.md derived from the PR head branch basename, else fail fast.--worktree auto|<abs-path>. auto creates or reuses a deterministic clean worktree for the current PR round. An explicit path reuses or creates that worktree path. If the target repo has staged changes and no worktree option is supplied, auto mode must stop safely. Unstaged modifications are not considered dirty.--dry-run. Preview GitHub reply / thread-resolution mutations without posting them.--live. Required before commit, push, reply, or resolve actions happen. Without --live, /pr-review --auto stops after artifacts and previews are generated.--quick, --triage-only, --history <github-id>, --auto <PR#>, --review-source <...>, --repo-path <abs-path>, --review-doc <path>, --worktree auto|<abs-path>, --dry-run, --liveIf the user provides a GitHub PR URL instead of a local path, use gh pr view <number> --json body to fetch the content. Fall back to asking for a local doc path if gh is unavailable.
When --auto is used, the PR number replaces the need for a PR doc path — the skill fetches it automatically via scripts/fetch-pr.sh. Branch name, GitHub ID, provider latest-round metadata, and head-repo metadata are extracted from the fetched PR data.
When AI review triage is requested, prefer a PR URL/number or a fetched PR doc that has a sibling *.review-data.json file generated by scripts/fetch-pr.sh. Local markdown alone may include CodeRabbit text but usually will not include GitHub Copilot inline comments unless that sidecar JSON exists.
Auto mode hard rules:
--repo-path or the current working directory only. If neither resolves the correct repo, fail fast.--repo-path is absent and the current working directory is not the PR target repo, stop immediately. Do not scan sibling directories, prior worktrees, or unrelated clones as a fallback.[A-Z][A-Z0-9]+-\d+ match. If zero or multiple matches exist, require --review-doc..pr-review/pr-<PR_NUMBER>/round-<N>/ inside the target repo as the canonical artifact directory for that round..pr-review/ as local operational state only. Add it to the active worktree exclude file instead of editing the tracked product .gitignore.--live is present. --live must fail if any selected latest-round decision remains pending.Read the PR doc and extract structured data:
ACME-595), title, author GitHub ID## ✨ Features): what the PR claims to do → build a claim list## 🔄 Changes): component table, file tree → build a claimed file list*.review-data.json sidecar file exists (structured provider data)<!-- auto-generated comment: release notes -->)## Summary by GitHub Copilot)The claim list is used in Step 2 for git-truth validation. Provider guides are loaded in Step 5:
references/coderabbit-triage-guide.mdreferences/copilot-triage-guide.mdVerify PR document claims against the actual git diff. Load references/review-criteria.md Section J.
Repo access requirement: Steps 2-4 require access to the actual git repository. Resolution order:
--repo-path if provided
default_repo_path from .claude/pr-review.local.md settings
Current working directory if it matches the PR's target repo
If the PR is from a GitHub URL and no local repo is available, use gh pr diff <PR#> --repo <owner/repo> to fetch the diff via GitHub API — this provides file-level changes without a full clone
If none of the above work, degrade gracefully and clearly disclose the limitation in the review output:
gh pr diff output if available — but clearly label all findings as "based on PR doc / GitHub API diff, not verified against full source code"Run git diff dev..HEAD --name-only to get the authoritative list of changed files
Cross-reference with the PR doc's file tree:
Build scope map from commit messages:
git log dev..HEAD --oneline[TICKET-ID] prefix → changed files are IN_SCOPEProduce a verification table (see Section J format)
If OUT_OF_SCOPE files exist, note this for the scope section in the output
The actual source code is the primary review source — the PR doc provides context only.
git diff dev..HEAD -- <filepath>index.ts) for proper re-export organizationPrioritize: new files first, then modified files, then renamed/deleted files.
This is the core of the review and runs unconditionally — regardless of whether GitHub Copilot or CodeRabbit produced comments or not. Load references/review-criteria.md and perform a thorough, adversarial review of every IN_SCOPE file.
CRITICAL execution order: Complete this entire step BEFORE reading any AI provider comments (Step 5). Do not read the *.review-data.json sidecar, CodeRabbit sections, or Copilot summaries until Step 4 is fully complete. This ensures findings are genuinely independent. If you read provider comments first, your "independent" findings will be contaminated by confirmation bias.
Review Dimensions (9 categories):
| Dimension | Criteria Section | Focus |
|---|---|---|
| Bugs & Correctness | — | Runtime errors, logic bugs, null dereferences |
| Architecture / FSD | A | Layer compliance, import direction, API location |
| React & TypeScript | B | useWatch, useEffect deps, type safety |
| Sibling Consistency | I, K | Parallel patterns across related components |
| DRY / Duplication | I | Repeated logic, extractable utilities |
| UI / Design System | C | Semantic tokens, layout patterns, hover states |
| Error Handling | D | safeResponseJson, mutation error UX |
| Accessibility | F | aria-labels, semantic HTML, keyboard |
| Performance | H | useCallback, useMemo, N+1 patterns |
Adversarial Review Process (go beyond checklist-walking):
expect(true).toBe(true) or empty test bodies. Check that tests actually exercise the changed logic, not just import the module. Missing tests for new utility functions or complex logic = a finding.Severity count validation: After classifying all findings, count the severity labels in each individual finding's detail block and verify they match the summary line (총 X건: 🔴 HIGH A건 / 🟡 MEDIUM B건 / 🟢 LOW C건). If a finding is labeled MEDIUM in the summary but LOW in its detail, fix the inconsistency before finalizing. The detail block's severity is the source of truth.
This step should produce the bulk of the review findings. If it produces fewer than 3 findings for a non-trivial PR, proceed to Step 6 for re-examination.
This step is provider-aware and secondary to the independent code review.
--review-source all → triage every available provider--review-source coderabbit → only CodeRabbit--review-source copilot → only GitHub Copilot--review-source none or --quick → skip this step entirelyreferences/coderabbit-triage-guide.mdreferences/copilot-triage-guide.md*.review-data.json when available. Fall back to markdown parsing only if sidecar data is absent.# Comment | by CodeRabbit bot | <timestamp> sectionpull_request_review_id belongs to that latest Copilot reviewImportant: Every comment must appear as an individual row in the triage tables (Fix-Self, Pass-to-Creator, or Dismissed). Do NOT bulk-dismiss comments without per-comment entries. The consolidated footer (for 5+ scope dismissals) is an additional summary footnote — it does not replace individual rows in the Dismissed table.
Is this comment from the latest review round for its provider?
├── No → DISMISSED: "이전 리뷰 라운드 기준이라 현재 검토 대상 아님"
└── Yes
├── Is the issue still present in current code?
│ ├── No → DISMISSED: "이후 커밋에서 이미 수정됨"
│ └── Yes
│ ├── Is the file OUT_OF_SCOPE?
│ │ └── Yes → DISMISSED: "스코프 외 ([TICKET] 커밋 소속)"
│ │ Exception: obvious bugs still flagged
│ ├── Does this contradict a project convention in CLAUDE.md or provider instructions?
│ │ └── Yes → DISMISSED: "프로젝트 컨벤션과 상충"
│ └── Is the fix mechanical?
│ ├── Yes → FIX-SELF + severity (HIGH/MEDIUM/LOW)
│ └── No → Would the developer learn something?
│ ├── Yes → PASS-TO-CREATOR + severity (HIGH/MEDIUM/LOW)
│ └── No → FIX-SELF + severity (HIGH/MEDIUM/LOW)
If a selected provider has 0 comments:
references/coderabbit-triage-guide.mdreferences/copilot-triage-guide.mdState this clearly in the review and move on — the review's substance comes from Step 4.
If the PR is non-trivial (3+ IN_SCOPE files with meaningful logic) and Steps 4-5 combined produced fewer than 3 HIGH+MEDIUM findings:
references/review-criteria.md Section Kdocs/reviews/developers/<github-id>.md if it existsLoad references/output-template.md for the review structure and references/feedback-templates.md for Korean phrasing. Save to:
docs/reviews/[TICKET-ID]-review.md
When using --quick mode, add -quick suffix to avoid overwriting a full review: docs/reviews/[TICKET-ID]-review-quick.md.
Present a summary to Eddie in the conversation after saving.
Create or update docs/reviews/developers/<github-id>.md:
This step activates when the reviewer decides to fix issues directly instead of waiting for the PR creator. Common triggers include: "직접 수정", "내가 고칠게", "시간이 없어서 내가 수정", "fix it myself", "fix-forward".
fix_forward_exclusions from .claude/pr-review.local.md settings (defaults below). Instead, output "Manual fix recommended" with an explanation:
**/migrations/**, **/*.sql in migration directories (immutable after application in Supabase, Prisma, etc.)Dockerfile, docker-compose*.yml.github/workflows/** (CI/CD pipelines)*.lock (lockfiles).env* (environment files)pnpm typecheck to verify all fixes pass
a. Commit convention: Before creating any commit, run git log --oneline -10 in the target repo to detect the existing commit message convention (e.g., conventional commits, gitmoji, ticket prefixes). Match that convention exactly.
b. Specific git add only: Only git add the specific files you modified during fix-forward. Never use git add ., git add -A, or any broad staging command. This prevents accidentally staging the user's unrelated changes.
c. No attribution metadata: Never include Co-Authored-By, Signed-off-by, or any similar attribution trailer in generated commits.references/fix-forward-template.md for the appendable section formatdocs/reviews/[TICKET-ID]-review.md)Round 1 for the first fix pass; increment to Round 2, Round 3 etc. if new issues arise after pushing fixes (e.g., new GitHub Copilot or CodeRabbit comments){reviewer_github_id}'s Comment section is mandatory — it serves as the copy-pasteable PR comment for the author. The 피드백 subsection within it is also mandatory to preserve educational value even when the reviewer fixes things directly--auto mode only)When invoked with --auto <PR#>, execute the managed pipeline below. Use the canonical scripts under skills/pr-review/scripts/.
scripts/fetch-pr.sh <PR#> --review-source <source> [--repo-path <abs-path>] to fetch PR metadata, provider latest-round metadata, and the sibling *.review-data.json sidecar.--repo-path or the current working directory. If neither resolves the correct repo, fail fast instead of guessing.--review-doc <path>docs/reviews/<TICKET>-review.md derived from the PR head branch basename[A-Z][A-Z0-9]+-\d+ match, require --review-doc.scripts/prepare-pr-worktree.sh <review-data.json> [--repo-path <abs-path>] [--review-doc <path>] [--worktree auto|<abs-path>].
status: needs-repo-path, stop immediately and tell Eddie to rerun with --repo-path <abs-path>.git diff --cached is non-empty) and no worktree override is supplied, stop safely and tell Eddie to rerun with --worktree auto or --worktree <abs-path>. Unstaged modifications (e.g. local .gitignore changes) are not considered dirty — they won't leak into commits as long as fix-forward only git adds specific files.--worktree auto is used, create or reuse the deterministic clean worktree for the current PR round.review_doc_path plus a Round 1 context so the first review document can be created during Phase B.review_doc_path from that output for subsequent round updates.review_doc_path does not exist yet, create the initial review document at that exact returned path inside the prepared worktree or resolved repo before Phase C begins.--review-doc <path> points to a non-standard location inside the repo, honor that exact path for the first save instead of drifting back to the default docs/reviews/[TICKET]-review.md.pnpm typecheck (and any focused tests) inside the prepared worktree before continuing.scripts/update-review-round-doc.sh init <review-data.json> --repo-path <repo> [--review-doc <path>] [--review-source <source>] [--worktree-json <path>].round_metaround_decisionsround_meta is the source of truth for:
round_decisions is the canonical machine-readable source for verdicts and reasons. A new managed round starts with one pending row for every latest selected provider comment.round_decisions row to accepted or declined during triage. Do not rely on free-form prose for verdicts.scripts/generate-decisions-json.sh <review-doc> <review-data.json> --repo-path <repo>
.pr-review/pr-<PR_NUMBER>/round-<N>/decisions.jsonscripts/post-ai-review-comments.sh <PR#> <decisions.json> --repo <owner/repo> --dry-run --output <reply-output.json>
scripts/resolve-ai-review-threads.sh <PR#> <decisions.json> --repo <owner/repo> --dry-run --output <resolve-output.json>
scripts/update-review-round-doc.sh status <review-doc> --round <N> --status dry-run-verified \
--artifact decisions_json=<path> \
--artifact reply_output=<path> \
--artifact resolve_output=<path>
--live is present. /pr-review --auto without --live is a supervised artifact-and-preview flow, not autonomous mutation.--live required)scripts/generate-decisions-json.sh <review-doc> <review-data.json> --repo-path <repo> --require-live-ready --output <decisions.json>
pendingscripts/post-ai-review-comments.sh <PR#> <decisions.json> --repo <owner/repo> --output <reply-output.json>
scripts/resolve-ai-review-threads.sh <PR#> <decisions.json> --repo <owner/repo> --output <resolve-output.json>
live-posted on full successmutation-partial if code changes committed/pushed but GitHub mutation was incompleteblocked if the flow cannot continue safelymutation-partial -> live-posted is resumable automatically. Any other rerun scenario requires explicit operator judgment./pr-review --auto <PR#> --review-source <source> [--repo-path ...] [--review-doc ...] [--worktree ...]pending row in round_decisions--livelive-postedfetch-pr.sh fails (e.g. PR not found): abort with a clear error.pnpm typecheck fails after fixes: do not commit or push.mutation-partial or blocked instead of pretending the round finished cleanly.Every finding is classified on two orthogonal axes:
The guiding principle: "Would fixing this myself teach the developer nothing, or would explaining it teach them something valuable?"
Fix-Self (reviewer fixes directly) — mechanical, no learning opportunity lost:
aria-label to icon-only buttons{memo && <p>...</p>})IS_EDIT_MODE = false that's never truly toggled)Pass-to-Creator (developer should fix to learn) — the developer gains something:
useEffect with incorrect dependency array — understanding React's reactivity model| Severity | Criteria | Merge Impact |
|---|---|---|
| 🔴 HIGH | Runtime crash, data loss, security vulnerability, broken feature, wrong behavior | Blocks merge — must fix before approval |
| 🟡 MEDIUM | Missing error handling, incorrect types, FSD violation, silent failures, incomplete implementation | Should fix — strongly recommended before merge |
| 🟢 LOW | Style improvement, minor accessibility gap, extractable utility, naming inconsistency | Nice to fix — can merge with follow-up |
| Finding | Who | Severity | Why |
|---|---|---|---|
| Null dereference when API returns empty | Fix-Self | 🔴 HIGH | Crash risk, mechanical one-line fix |
useEffect missing placeData in deps | Pass-to-Creator | 🔴 HIGH | Stale data bug, developer needs to learn reactivity |
safeResponseJson not used in catch block | Fix-Self | 🟡 MEDIUM | Silent failure on empty body, easy to fix |
Silent ?? 'bus' fallback for unknown enum | Pass-to-Creator | 🟡 MEDIUM | Hides backend changes, teaches defensive strategy |
Missing aria-label on icon button | Fix-Self | 🟢 LOW | Accessibility gap, mechanical addition |
Utility function could move to lib/ | Pass-to-Creator | 🟢 LOW | FSD organization, learning opportunity |
Load references/output-template.md for the exact review document structure. Follow it precisely — the template defines all section headings, table formats, and conditional rendering rules (e.g., omit AI triage section in quick mode).
Two modes, mixed as appropriate:
교육적 (Educational) — for architecture, patterns, and "why" explanations:
간결 (Concise) — for small, obvious fixes:
aria-label 추가 권장"Tone rules:
For detailed phrase templates, read references/feedback-templates.md.
docs/reviews/developers/<github-id>.md
# Developer Profile: @github-id
## 통계 (Statistics)
- 총 리뷰 횟수: N
- 마지막 리뷰: YYYY/MM/DD
- 주요 강점: [comma-separated areas]
- 주의 영역: [comma-separated areas]
## 리뷰 이력 (Review History)
### YYYY/MM/DD - [TICKET-ID] Title
**전체 평가**: [1-2 sentence summary]
**발견 건수**: Fix-Self N건, Pass-to-Creator N건, Dismissed N건
## 카테고리별 이력 (History by Category)
### Code Style & Formatting
- [YYYY/MM/DD] [TICKET] description (file:line) [Fix-Self/Pass-to-Creator]
### Type Safety & TypeScript
### React Patterns
### Accessibility
### Architecture / FSD Compliance
### Error Handling
### Performance
### DRY / Code Duplication
Load these on demand during the workflow:
| Reference | When to Load | Purpose |
|---|---|---|
references/review-criteria.md | Steps 2, 4, 6 | Git-truth validation (J), code review checklist (A-I), re-examination (K) |
references/output-template.md | Step 8 | Exact review document structure with all section headings and table formats |
references/feedback-templates.md | Step 8 | Korean phrase templates for writing feedback |
references/coderabbit-triage-guide.md | Step 5 | How to parse, classify, and scope-triage CodeRabbit comments |
references/copilot-triage-guide.md | Step 5 | How to parse, classify, and scope-triage GitHub Copilot comments |
references/fix-forward-template.md | Step 10 | Appendable fix log template with 수정/미수정 tables and PR comment format |
scripts/fetch-pr.sh | Step 11, Phase A | Fetches PR data from GitHub API and creates *.review-data.json sidecars |
scripts/prepare-pr-worktree.sh | Step 11, Phase A | Validates repo identity, handles dirty repos safely, and prepares deterministic worktrees |
scripts/update-review-round-doc.sh | Step 11, Phase C | Appends or resumes managed Round N sections and owns round status / artifact metadata |
scripts/generate-decisions-json.sh | Step 11, Phase D | Reads round_meta + round_decisions and emits the normalized decisions artifact |
scripts/post-ai-review-comments.sh | Step 11, Phases D-E | Previews or posts accept/decline replies to GitHub Copilot or CodeRabbit comments |
scripts/resolve-ai-review-threads.sh | Step 11, Phases D-E | Previews or resolves accepted GitHub Copilot or CodeRabbit threads via GraphQL |
These files contain detailed content that should not be loaded upfront. Read them only at the step indicated.
Also always reference:
CLAUDE.md (already in context) — the authoritative source for project coding conventions.coderabbit.yaml — CodeRabbit configuration for understanding its review profile and path-specific rules.github/copilot-instructions.md and .github/instructions/**/*.instructions.md — GitHub Copilot review guidance and path-specific review instructionsnpx claudepluginhub junyoung2015/pr-review-skill --plugin pr-reviewLoads GitHub PR review comments into the AI session for analysis, triage, and fix planning. Default is analysis-only; use --mode fix to enable auto-fixes.
Interactively responds to PR review feedback: fetches comments, verifies findings, asks for user approval, makes changes, and posts replies. Use when addressing GitHub pull request reviews.