
Code Reviewer
- 690 installs
- 65 repo stars
- Updated June 21, 2026
- charon-fan/agent-playbook
code-reviewer is a Claude Code skill that runs structured pull-request and diff reviews with security, quality, and test coverage feedback for developers preparing changes to merge.
About
code-reviewer is an agent-playbook skill for comprehensive review of pull requests and local diffs in Claude Code. The skill analyzes changes across correctness, security including OWASP Top 10 and injection prevention, performance, and test coverage, then returns structured feedback developers can act on before merge. Invoke it with prompts like Review this PR, Check my changes, or Review the code in src/auth/. The workflow follows five review steps from change analysis through categorized findings, making it a repeatable pre-merge gate for teams without a dedicated reviewer available.
- Seven review lenses: correctness, security, performance, code quality, testing, documentation, maintainability
- Four severity buckets: Critical, High, Medium, and Low for actionable merge decisions
- Security pass aligned with OWASP Top 10, secrets exposure, and injection risks
- Optional Python script `review_checklist.py` to generate a repeatable review checklist
- Natural-language triggers: review this PR, check my changes, or review a directory
Code Reviewer by the numbers
- 690 all-time installs (skills.sh)
- Ranked #186 of 1,382 Code Review & Quality skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/charon-fan/agent-playbook --skill code-reviewerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 690 |
|---|---|
| repo stars | ★ 65 |
| Security audit | 2 / 3 scanners passed |
| Last updated | June 21, 2026 |
| Repository | charon-fan/agent-playbook ↗ |
How do you review a pull request thoroughly?
Run a structured pull-request and diff review with security, quality, and test coverage feedback before you merge.
Who is it for?
Developers seeking a structured pre-merge review on auth modules, API changes, or feature branches before human review.
Skip if: Teams needing automated CI lint gates only or formal compliance audit reports with signed attestations.
When should I use this skill?
A developer asks to review a PR, check local changes, or audit code in a specific directory before merge.
What you get
Structured PR review feedback covering correctness, security, performance, and test coverage gaps.
- Structured review report
- Security and quality findings
- Test coverage assessment
By the numbers
- Five-step review workflow from analysis through structured feedback
- Covers OWASP Top 10 security checks
Files
Code Reviewer
A comprehensive code review skill that analyzes pull requests and code changes for quality, security, maintainability, and best practices.
When This Skill Activates
This skill activates when you:
- Ask for a code review
- Request a PR review
- Mention reviewing changes
- Say "review this" or "check this code"
Review Process
Phase 1: Context Gathering
1. Get changed files
git diff main...HEAD --name-only
git log main...HEAD --oneline2. Get the diff
git diff main...HEAD3. Understand project context
- Read relevant documentation
- Check existing patterns in similar files
- Identify project-specific conventions
Phase 2: Analysis Categories
1. Correctness
- [ ] Logic is sound and matches requirements
- [ ] Edge cases are handled
- [ ] Error handling is appropriate
- [ ] No obvious bugs or typos
2. Security
- [ ] No hardcoded secrets or credentials
- [ ] Input validation and sanitization
- [ ] SQL injection prevention
- [ ] XSS prevention (for frontend)
- [ ] Authentication/authorization checks
- [ ] Safe handling of user data
3. Performance
- [ ] No N+1 queries
- [ ] Appropriate caching
- [ ] Efficient algorithms
- [ ] No unnecessary computations
- [ ] Memory efficiency
4. Code Quality
- [ ] Follows DRY principle
- [ ] Follows KISS principle
- [ ] Appropriate abstractions
- [ ] Clear naming conventions
- [ ] Proper typing (if TypeScript)
- [ ] No commented-out code
5. Testing
- [ ] Tests cover new functionality
- [ ] Tests cover edge cases
- [ ] Test assertions are meaningful
- [ ] No brittle tests
6. Documentation
- [ ] Complex logic is explained
- [ ] Public APIs have documentation
- [ ] JSDoc/TSDoc for functions
- [ ] README updated if needed
7. Maintainability
- [ ] Code is readable
- [ ] Consistent style
- [ ] Modular design
- [ ] Separation of concerns
Phase 3: Output Format
Use this structured format for review feedback:
# Code Review
## Summary
Brief overview of the changes (2-3 sentences).
## Issues by Severity
### Critical
Must fix before merge.
- [ ] **Issue Title**: Description with file:line reference
### High
Should fix before merge unless there's a good reason.
- [ ] **Issue Title**: Description with file:line reference
### Medium
Consider fixing, can be done in follow-up.
- [ ] **Issue Title**: Description with file:line reference
### Low
Nice to have improvements.
- [ ] **Issue Title**: Description with file:line reference
## Positive Highlights
What was done well in this PR.
## Suggestions
Optional improvements that don't require immediate action.
## Approval Status
- [ ] Approved
- [ ] Approved with suggestions
- [ ] Request changesCommon Issues to Check
Security Issues
| Issue | Pattern | Recommendation |
|---|---|---|
| Hardcoded secrets | const API_KEY = "sk-" | Use environment variables |
| SQL injection | \"SELECT * FROM...\" + user_input | Use parameterized queries |
| XSS vulnerability | innerHTML = user_input | Sanitize or use textContent |
| Missing auth check | New endpoint without @RequireAuth | Add authentication middleware |
Performance Issues
| Issue | Pattern | Recommendation |
|---|---|---|
| N+1 query | Loop with database call | Use eager loading or batch queries |
| Unnecessary re-render | Missing dependencies in useEffect | Fix dependency array |
| Memory leak | Event listener not removed | Add cleanup in useEffect return |
| Inefficient loop | Nested loops O(n²) | Consider hash map or different algorithm |
Code Quality Issues
| Issue | Pattern | Recommendation |
|---|---|---|
| Duplicate code | Similar blocks repeated | Extract to function |
| Magic number | if (status === 5) | Use named constant |
| Long function | Function >50 lines | Split into smaller functions |
| Complex condition | `a && b |
Testing Issues
| Issue | Pattern | Recommendation |
|---|---|---|
| No tests | New feature without test file | Add unit tests |
| Untested edge case | Test only covers happy path | Add edge case tests |
| Brittle test | Test relies on implementation details | Test behavior, not implementation |
| Missing assertion | Test doesn't assert anything | Add proper assertions |
Language-Specific Guidelines
TypeScript
- Use
unknowninstead ofanyfor untyped values - Prefer
interfacefor public APIs,typefor unions - Use strict mode settings
- Avoid
asassertions when possible
React
- Follow Hooks rules
- Use
useCallback/useMemoappropriately (not prematurely) - Prefer function components
- Use proper key props in lists
- Avoid prop drilling with Context
Python
- Follow PEP 8 style guide
- Use type hints
- Use f-strings for formatting
- Prefer list comprehensions over map/filter
- Use context managers for resources
Go
- Handle errors explicitly
- Use named returns for clarity
- Keep goroutines simple
- Use channels for communication
- Avoid package-level state
Before Approving
Confirm the following:
- [ ] All critical issues are addressed
- [ ] Tests pass locally
- [ ] No merge conflicts
- [ ] Commit messages are clear
- [ ] Documentation is updated
- [ ] Breaking changes are documented
Scripts
Run the review checklist script:
python scripts/review_checklist.py <pr-number>References
references/checklist.md- Complete review checklistreferences/security.md- Security review guidelinesreferences/patterns.md- Common patterns and anti-patterns
Code Reviewer
A Claude Code skill for comprehensive code review of pull requests and code changes.
Installation
This skill is part of the agent-playbook collection.
Usage
When reviewing code, simply ask:
You: Review this PR
You: Check my changes
You: Review the code in src/auth/The skill will: 1. Analyze the changes 2. Check against security best practices 3. Evaluate code quality 4. Review test coverage 5. Provide structured feedback
Review Categories
| Category | Description |
|---|---|
| Correctness | Logic, edge cases, error handling |
| Security | OWASP Top 10, secrets, injection prevention |
| Performance | N+1 queries, caching, algorithms |
| Code Quality | DRY, KISS, naming, abstractions |
| Testing | Coverage, edge cases, meaningful assertions |
| Documentation | Comments, API docs, README |
| Maintainability | Modularity, separation of concerns |
Output Format
Reviews are structured with severity levels:
- Critical: Must fix before merge
- High: Should fix before merge
- Medium: Consider fixing
- Low: Nice to have improvements
Scripts
Generate a review checklist:
python scripts/review_checklist.pyReferences
Code Review Checklist
Use this checklist for systematic code reviews.
Pre-Review
- [ ] I understand what this PR is trying to achieve
- [ ] I have read the linked issues/tickets
- [ ] I have checked the base branch is correct
- [ ] I have verified the PR is not a draft
Code Review
Correctness
- [ ] Code implements the stated requirements
- [ ] Edge cases are handled
- [ ] Error handling is appropriate
- [ ] No obvious bugs
- [ ] Input validation is present
Security
- [ ] No hardcoded secrets/credentials
- [ ] User input is validated/sanitized
- [ ] SQL/NoSQL injection prevention
- [ ] XSS prevention (for web)
- [ ] CSRF protection (for state-changing operations)
- [ ] Authentication/authorization is correct
- [ ] Sensitive data is handled securely
Performance
- [ ] No N+1 queries
- [ ] Appropriate caching (if applicable)
- [ ] Efficient algorithm/data structure choice
- [ ] No unnecessary database/network calls
- [ ] Pagination for large datasets
- [ ] Indexes used where appropriate
Code Quality
- [ ] Code is readable and understandable
- [ ] Naming is clear and consistent
- [ ] No dead/commented-out code
- [ ] No duplicate code
- [ ] Appropriate abstractions
- [ ] Follows DRY, KISS, YAGNI
- [ ] Type definitions are accurate (if typed)
Testing
- [ ] Tests cover new functionality
- [ ] Tests cover edge cases
- [ ] Tests are meaningful (not tautologies)
- [ ] No hardcoded test data that makes tests brittle
- [ ] All tests pass
- [ ] Test coverage not decreased
Documentation
- [ ] Complex logic has comments
- [ ] Public APIs are documented
- [ ] Breaking changes are noted
- [ ] README/API docs updated if needed
- [ ] Migration guide provided for breaking changes
Maintainability
- [ ] Code is modular
- [ ] Separation of concerns
- [ ] Easy to modify
- [ ] Easy to test
- [ ] Follows project conventions
Style
- [ ] Consistent formatting
- [ ] Follows project style guide
- [ ] No lint errors
- [ ] No console.log/debugger left in
Post-Review
- [ ] Provided clear, actionable feedback
- [ ] Explained reasoning for suggestions
- [ ] Flagged blocking issues separately from nice-to-haves
- [ ] Recognized good work in the PR
Common Patterns and Anti-Patterns
Patterns to Encourage
Error Handling
Good:
async function getUser(id: string) {
const user = await db.users.findById(id);
if (!user) {
throw new NotFoundError(`User ${id} not found`);
}
return user;
}Bad:
async function getUser(id: string) {
return await db.users.findById(id); // Returns null, not handled
}Async/Await
Good:
const result = await fetch(url);
const data = await result.json();Bad:
fetch(url).then(r => r.json()).then(data => {
// Nested callbacks
});Early Returns
Good:
function process(user) {
if (!user) return null;
if (!user.active) return null;
return user.data;
}Bad:
function process(user) {
if (user) {
if (user.active) {
return user.data;
}
}
return null;
}Destructuring
Good:
const { name, email } = user;Bad:
const name = user.name;
const email = user.email;Anti-Patterns to Catch
Magic Numbers
Bad:
if (user.role === 5) { ... }Good:
const Role = { ADMIN: 5, USER: 1 };
if (user.role === Role.ADMIN) { ... }Neglected Promise Rejection
Bad:
fetch(url).then(data => processData(data));Good:
fetch(url)
.then(data => processData(data))
.catch(error => logError(error));Any Type
Bad:
function parse(data: any) { ... }Good:
function parse(data: unknown): Result { ... }Deep Nesting
Bad:
if (a) {
if (b) {
if (c) {
doSomething();
}
}
}Good:
if (!a) return;
if (!b) return;
if (!c) return;
doSomething();Large Functions
Bad: Functions > 50 lines
Good: Split into smaller, focused functions
God Objects
Bad: Classes/methods that do everything
Good: Single Responsibility Principle
Shotgun Surgery
Bad: Adding a feature requires changing many files
Good: Good separation of concerns
React Specific
Hooks Dependencies
Bad:
useEffect(() => {
fetchData(userId);
}, []); // Missing userId dependencyGood:
useEffect(() => {
fetchData(userId);
}, [userId]);State Updates
Bad:
setCount(count + 1);
setCount(count + 1);Good:
setCount(c => c + 2);Key Props
Bad:
items.map((item, i) => <Item key={i} />)Good:
items.map(item => <Item key={item.id} />)Backend Specific
N+1 Query
Bad:
for user in users:
posts = db.query("SELECT * FROM posts WHERE user_id = ?", user.id)Good:
user_ids = [u.id for u in users]
posts = db.query("SELECT * FROM posts WHERE user_id IN ?", user_ids)Transaction Handling
Bad:
db.transfer(a, b, amount) # No transactionGood:
with db.transaction():
db.transfer(a, b, amount)Security Review Guidelines
OWASP Top 10 Coverage
A01:2021 – Broken Access Control
- [ ] Users can only access their own data
- [ ] API endpoints have proper authentication
- [ ] Admin actions require admin role
- [ ] No IDOR (Insecure Direct Object References)
- [ ] Proper authorization checks on all endpoints
A02:2021 – Cryptographic Failures
- [ ] Passwords are hashed (bcrypt/argon2)
- [ ] HTTPS is enforced
- [ ] Sensitive data is encrypted at rest
- [ ] No weak cipher suites
- [ ] Proper key management
A03:2021 – Injection
- [ ] Parameterized queries for SQL
- [ ] Input validation and sanitization
- [ ] ORM used safely
- [ ] No command injection from user input
- [ ] No LDAP injection
A04:2021 – Insecure Design
- [ ] Rate limiting on auth endpoints
- [ ] Proper logout functionality
- [ ] Session timeout is reasonable
- [ ] No security through obscurity
A05:2021 – Security Misconfiguration
- [ ] Debug mode off in production
- [ ] Error messages don't leak information
- [ ] Default credentials changed
- [ ] Security headers configured
- [ ] CORS configured correctly
A06:2021 – Vulnerable Components
- [ ] Dependencies up to date
- [ ] No known vulnerabilities in deps
- [ ] Unused dependencies removed
A07:2021 – Auth Failures
- [ ] Strong password policy
- [ ] No brute force protection needed (rate limiting)
- [ ] MFA implemented for sensitive operations
- [ ] Session IDs are random
A08:2021 – Software/Data Integrity
- [ ] Dependencies from trusted sources
- [ ] CI/CD has integrity checks
- [ ] Verify data integrity
A09:2021 – Logging Failures
- [ ] Security events logged
- [ ] Logs don't contain sensitive data
- [ ] Log tampering protection
- [ ] Audit trail for critical operations
A10:2021 – SSRF
- [ ] No arbitrary URL fetching from user input
- [ ] Allowlist for external calls
- [ ] Network segmentation
Frontend Security
- [ ] XSS prevention
- [ ] CSRF tokens
- [ ] Content Security Policy
- [ ] Subresource Integrity
- [ ] No
dangerouslySetInnerHTMLwith user content
Backend Security
- [ ] Input validation on all endpoints
- [ ] Output encoding
- [ ] Prepared statements
- [ ] Principle of least privilege
- [ ] Secure file upload handling
Infrastructure Security
- [ ] Secrets in environment variables
- [ ] No secrets in code
- [ ] Proper RBAC
- [ ] Network security rules
- [ ] Regular security updates
#!/usr/bin/env python3
"""
Code Review Checklist Generator
Generates a structured review checklist for a given PR or diff.
"""
import argparse
import subprocess
import sys
from pathlib import Path
def run_git(args: list[str], base_branch: str) -> str:
"""Run a git command and fail with a useful error."""
try:
result = subprocess.run(
["git", *args],
capture_output=True,
text=True,
check=True
)
return result.stdout
except subprocess.CalledProcessError as exc:
detail = (exc.stderr or exc.stdout or "").strip()
message = f"git {' '.join(args)} failed for base '{base_branch}'"
if detail:
message += f": {detail}"
raise RuntimeError(message) from exc
def get_changed_files(base_branch: str = "main") -> list[str]:
"""Get list of changed files."""
output = run_git(["diff", f"{base_branch}...HEAD", "--name-only"], base_branch)
return [f.strip() for f in output.strip().split('\n') if f.strip()]
def get_commit_messages(base_branch: str = "main") -> list[str]:
"""Get commit messages in the PR."""
output = run_git(["log", f"{base_branch}...HEAD", "--oneline"], base_branch)
return [line.strip() for line in output.strip().split('\n') if line.strip()]
def get_diff(base_branch: str = "main") -> str:
"""Get the full diff."""
return run_git(["diff", f"{base_branch}...HEAD"], base_branch)
def categorize_file(filename: str) -> str:
"""Categorize file by extension for targeted checks."""
ext = Path(filename).suffix.lower()
if ext in {'.ts', '.tsx', '.js', '.jsx'}:
return 'javascript'
if ext in {'.py'}:
return 'python'
if ext in {'.go'}:
return 'go'
if ext in {'.rs'}:
return 'rust'
if ext in {'.java', '.kt'}:
return 'jvm'
if ext in {'.sql'}:
return 'sql'
if ext in {'.yml', '.yaml'}:
return 'yaml'
if ext in {'.md', '.rst'}:
return 'docs'
return 'general'
def generate_review_checklist(base_branch: str = "main") -> str:
"""Generate a structured review checklist."""
files = get_changed_files(base_branch)
commits = get_commit_messages(base_branch)
diff = get_diff(base_branch)
if not files:
return "# No changes found\n\nNo files changed compared to " + base_branch
lines = ["# Code Review Checklist\n"]
# Overview
lines.append("## Overview\n")
lines.append(f"- **Branch**: {base_branch} → HEAD")
lines.append(f"- **Files changed**: {len(files)}")
lines.append(f"- **Commits**: {len(commits)}\n")
# Commits
lines.append("### Commits\n")
for commit in commits:
lines.append(f"- {commit}")
lines.append("")
# Files by category
categories = {}
for f in files:
cat = categorize_file(f)
categories.setdefault(cat, []).append(f)
lines.append("## Files to Review\n")
for cat, cat_files in categories.items():
lines.append(f"\n### {cat.title()}\n")
for f in cat_files:
lines.append(f"- [{f}]")
# Diff snippet (first 100 lines)
lines.append("\n## Diff Preview\n")
lines.append("```diff")
for line in diff.split('\n')[:100]:
lines.append(line)
if len(diff.split('\n')) > 100:
lines.append("\n... (diff truncated)")
lines.append("```\n")
# Review sections
lines.append("## Review Sections\n")
# Security check
lines.append("### 🔒 Security\n")
if any('secret' in f.lower() or 'config' in f.lower() or 'env' in f.lower() for f in files):
lines.append("- [ ] **Secrets check**: No hardcoded credentials in config/env files\n")
lines.append("- [ ] **Input validation**: User input is validated and sanitized\n")
lines.append("- [ ] **Injection**: No SQL/command injection vulnerabilities\n")
lines.append("- [ ] **Auth**: Proper authentication/authorization on new endpoints\n")
# Code quality
lines.append("\n### 📝 Code Quality\n")
lines.append("- [ ] **Readability**: Code is clear and understandable\n")
lines.append("- [ ] **Naming**: Variables/functions are well named\n")
lines.append("- [ ] **DRY**: No duplicate code\n")
lines.append("- [ ] **Comments**: Complex logic is explained\n")
# Testing
test_files = [f for f in files if 'test' in f.lower() or 'spec' in f.lower()]
if test_files:
lines.append(f"\n### 🧪 Testing ({len(test_files)} test files)\n")
else:
lines.append("\n### 🧪 Testing\n")
lines.append("- [ ] **Tests added**: New functionality has tests\n")
lines.append("- [ ] **Coverage**: Test coverage not decreased\n")
lines.append("- [ ] **Edge cases**: Edge cases are tested\n")
# Performance
lines.append("\n### ⚡ Performance\n")
lines.append("- [ ] **N+1 queries**: No database queries in loops\n")
lines.append("- [ ] **Caching**: Appropriate caching where needed\n")
lines.append("- [ ] **Efficiency**: Efficient algorithms/data structures\n")
# Documentation
lines.append("\n### 📚 Documentation\n")
lines.append("- [ ] **API docs**: Public APIs are documented\n")
lines.append("- [ ] **README**: README updated if needed\n")
lines.append("- [ ] **Comments**: Complex logic has comments\n")
# Breaking changes
lines.append("\n### ⚠️ Breaking Changes\n")
lines.append("- [ ] **Documented**: Breaking changes are documented\n")
lines.append("- [ ] **Migration**: Migration guide provided if needed\n")
# Approval
lines.append("\n## Approval\n")
lines.append("- [ ] **Critical issues**: None\n")
lines.append("- [ ] **Tests pass**: All tests pass locally\n")
lines.append("- [ ] **Ready to merge**: No blocking issues\n")
return '\n'.join(lines)
def main():
parser = argparse.ArgumentParser(description="Generate code review checklist")
parser.add_argument("--base", default="main", help="Base branch to compare against")
parser.add_argument("--output", "-o", help="Output file (default: stdout)")
args = parser.parse_args()
try:
checklist = generate_review_checklist(args.base)
except RuntimeError as exc:
print(f"Error: {exc}", file=sys.stderr)
return 1
if args.output:
Path(args.output).write_text(checklist)
print(f"Checklist written to {args.output}")
else:
print(checklist)
return 0
if __name__ == "__main__":
raise SystemExit(main())
Related skills
How it compares
Use for interactive structured PR review rather than static linter configs that only catch syntax-level issues.
FAQ
What categories does code-reviewer check?
code-reviewer evaluates correctness, security including OWASP Top 10 and injection risks, performance, and test coverage. Findings are returned as structured feedback after analyzing the PR or diff.
How do you invoke code-reviewer in Claude Code?
code-reviewer activates on prompts like Review this PR, Check my changes, or Review the code in src/auth/. The skill runs a five-step analysis workflow and outputs categorized review feedback.
Is Code Reviewer safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.