Project-agnostic code review for Claude Code. One slash command runs deterministic gates, ten parallel review agents, and an adversarial verification pass.
> /plugin marketplace add ncoevoet/claude-review-all> /plugin install review-all@ncoevoet-review-all
Repo: ncoevoet/claude-review-all
What's inside
Project-agnostic code review for Claude Code. One slash command runs deterministic gates, ten parallel review agents, and an adversarial verification pass. Every finding cites file:line and is independently re-checked before the report — false positives stay out.

One verdict line up top, automated gate results, then findings by severity — Critical/Important carry full anatomy (impact · suggested fix · evidence), Debt/Suggested collapse to one line each. Every finding cites file:line and is independently re-verified before it reaches the report.
Inside Claude Code, add the marketplace and install the plugin:
/plugin marketplace add ncoevoet/claude-review-all
/plugin install review-all@ncoevoet-review-all
/review-all is available right away. Update later with /plugin update review-all@ncoevoet-review-all, remove with /plugin uninstall review-all@ncoevoet-review-all. CLI equivalents work too: claude plugin marketplace add ncoevoet/claude-review-all then claude plugin install review-all@ncoevoet-review-all. The plugin bundles the skill's scripts/ and resolves them relative to the skill, so it works wherever Claude Code installs it.
make install)For hacking on the skill itself, copy it straight into ~/.claude/skills/:
git clone https://github.com/ncoevoet/claude-review-all.git
cd claude-review-all
make install # copies skills/review-all/ → ~/.claude/skills/review-all/
make uninstall removes it. make review-self installs then reminds you to run /review-all in this repo. The skill works in Claude Code only — it depends on filesystem access and bash.
Inside Claude Code, run /review-all with any of these targets:
| Argument | Reviews |
|---|---|
| (empty) | Uncommitted changes if any, else current branch vs default branch, else last commit |
--staged | Only staged changes |
--unstaged | Only unstaged changes |
last commit | HEAD~1..HEAD |
last N commits | HEAD~N..HEAD |
vs <branch> | Current branch vs merge-base with <branch> |
<sha1>..<sha2> | A specific commit range |
PR #N or #N | A GitHub PR (requires gh) |
| file paths | Restrict review to those files |
--paths a/b,c/d | Filter resolved diff to these path prefixes |
--exclude x,y | Drop these path prefixes from the resolved diff |
gate / --ci | Headless gate mode — full review, then a machine verdict (gate-verdict.json + exit code) with no Phase 4 menu; composes with any target (gate --staged, gate PR #N) |
Examples:
/review-all
/review-all --staged
/review-all PR #123
/review-all last 3 commits
/review-all vs main
/review-all src/auth/login.ts src/auth/session.ts
/review-all PR #42 --exclude apps/legacy
/review-all gate --severity critical
| Step | What it does | Why |
|---|---|---|
| 0.0 Discovery (one call) | Runs scripts/discover.sh — composes the preflight tool probe (git/timeout/lsof/ss/gh/jq/curl/rsync/python3), toolchain detection, test-pattern detection, .codegraph/ check, and the rules-cache verdict in a SINGLE script call | Phase 0 costs one round trip regardless of cache state; later phases degrade instead of crashing on a missing tool |
| 0.1 Resolve target | Parses $ARGUMENTS against the table above | Single source of truth for "what diff is being reviewed" |
| 0.2 Load config + rules cache | Reads .claude/review-all.json; on cache HIT reuses the LLM-extracted global rules from .claude/cache/review-all-profile.json | Only the expensive LLM work (rules extraction) is cached — toolchain commands are re-probed fresh every run, so a package.json/pom.xml change can never be served stale |
| 0.3 + 0.4 Toolchain | Folded into 0.0 — detect-toolchain.sh emits {ecosystem, framework, test, lint, typecheck, build} | Project-agnostic gate commands; never assumes Angular vs Spring vs Rust |
| 0.5 Project rules | Reads root + nested CLAUDE.md files; the global half is skipped on cache HIT, module-level CLAUDE.md (changed dirs) always read fresh. Also reads repo-root REVIEW.md when present (never cached) | "NEVER do X / ALWAYS do Y" steer the agents; REVIEW.md overrides what gets flagged and at what severity |
| 0.6 Test patterns | Folded into 0.0 — test-pattern-probe.sh infers location, suffix, framework | Spec Existence Check uses this; no hardcoded __tests__ assumption |
| 0.7 CodeGraph + MCP | Probes the live MCP tool registry (skipped entirely when 0.0 found no .codegraph/); records toolchain.codegraphTools keyed by capability | Tool names are not hardcoded — survives MCP-server renames |
| 0.8 Gather diff + select | Computes diff + per-file slice, applies --paths/--exclude, then runs scripts/select-files.py — a pure function that drops binary files, secret paths, generated/vendor/lock output and any single file over maxFileDiffBytes, and tags every survivor with its file classes | Filtering is enforced before any agent sees the diff, and it is a computation rather than a judgment — a dry run and the real run consume one answer |
| 0.9 Output dirs + cache write | Creates .claude/cache, .claude/reports, .claude/review-all; on cache MISS writes the v2 rules profile | First run on a fresh repo never crashes on a missing dir |
The rules cache is keyed on a manifest of per-file content hashes over every repo CLAUDE.md (+ root CLAUDE.local.md), carries a schema version, and expires after 7 days — a branch switch, a CLAUDE.md edit, or a legacy cache file all force a fresh extraction. The report's gate table shows Profile cache: HIT / MISS(reason) so cache behavior is always visible (and eval-gradeable).
| Gate | Command | Why |
|---|---|---|
| Typecheck | timeout 120 <discovered> | Compilers find what review can't |
| Lint | timeout 120 <discovered> | Style + simple bugs at zero token cost |
| Tests | timeout 180 <scoped> | Smart scoping: tests that import changed files first, fallback to package, fallback to suite |
| Dev-server probe | scripts/dev-server-probe.sh | If dev server is up, skip the build gate — it's already running |
| Spec existence | per new file vs toolchain.testPattern | New public code without tests is automatically 🔴 |
| Dependency check | per manifest diff | New deps / major bumps / removed deps surface explicitly |
Gate-confirmed findings are tagged VERIFIED and skip the verification phase. They are real, by definition.
When a gate fails, its output is also handed to every agent and to the verifier as a <gate_results> block (failures only, truncated) — a compiler or test runner is ground truth no amount of reading matches, which is why hybrid static-analysis + LLM review outperforms either alone. Agents treat it as a lead to the underlying defect, never as a finding to restate: the failure is already on the report.
If a UI file changed AND a dev-server port is open AND curl exists:
Catches dead routes and visual regressions that static review cannot.
Up to ten specialized agents review the (filtered) diff slice in parallel, each on its own concern:
standards · bugs+security · DRY · consistency · simplification · security-deep-dive · performance · test-quality · API-contract · a11y/i18n
Agents share _shared.md (severity tiers, 3-question gate, quotas, auto-drop rules, codegraph-tool resolution).
Only the agents the diff needs are spawned. scripts/select-agents.py turns Step 0.8's file classes into the spawn set: six axes always run, and security-deep-dive, test-quality, API-contract and a11y/i18n run only when the diff actually holds a file of class security, test, contract, or ui/i18n. A backend-only Go diff spawns six agents, not ten. Each conditional axis also receives only its own files as its slice. The report names every skipped axis with the reason it was skipped, so an absent agent never reads as a failed one.
This used to be prose inside the personas (Only spawn this agent if …), which can only take effect after the agent is running — a measured 73 545-character floor of persona text paid to be told there was nothing to review. The persona lines survive as a fallback for a hand-spawned agent; the gate is the script.
Per-language rule packs. Each agent also receives a <language_rules> block: a short checklist of the defects — and the false positives — that the languages in its slice specifically invite (rules/<lang>.md). It is injected once per language present, never once per file, so a Java-only diff never pays for the TypeScript pack. Set languageRules: false to turn it off. Every pack ends with a mandatory #### Do not report section; that negative half is the point, and tests/check-rule-packs.sh enforces it.
Every spawn names its model, per axis. The axes whose findings are claims about behavior — bugs+security, security-deep-dive, performance, API-contract — run on opus; the axes that match code against a known shape — standards, DRY, consistency, simplification, test-quality, a11y/i18n — run on sonnet. The tier is declared in each persona's frontmatter (model:), so it travels with the persona; an omitted model would silently inherit the session's tier and put mechanical axes on the expensive one. Precision does not depend on the tier: every finding still faces the hostile verifier, so a weaker axis over-flagging costs a verifier call, not a false positive. The rule is not limited to the axes — the Phase 4 follow-up agents name a tier too (Deep-dive opus, Ask-a-question and the test generator sonnet), so no spawn in the skill inherits a tier by accident.
Completed axes are checkpointed to .claude/review-all/checkpoints/<axis>.json and resumed on a re-run, so an interrupted review (session cut, cancelled CI job) does not re-pay for the agents that already returned. The key is deliberately all-or-nothing — sha256 over the reviewed HEAD, the exact diff bytes, SKILL.md + every persona, and REVIEW.md + .claude/review-all.json — so any change to the code, the scope, or the reviewer definitions discards every checkpoint. Only complete returns are saved (a timed-out axis re-runs), findings are stored pre-verification, and the report names each resumed axis. Delete the directory to force a full re-run.
FAQ
review-all is a Claude Code plugin with 1 hand-picked skill for development work, indexed on Flowy. Install it with the command on its page. It includes review-all. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it