Open-source, self-hosted PR review tool. Like Greptile or CodeRabbit, but runs on your machine.
Watches your GitHub repositories for pull requests, spawns a local AI coding CLI to review them, and posts structured comments back to GitHub automatically.
No API keys required -- pr-reviewer uses your existing CLI subscriptions (Claude Code, OpenCode, Codex) instead of calling AI APIs directly.
- You configure which repos to watch and which CLI harness to use
- The daemon polls GitHub for new or updated pull requests
- For each PR, it assembles context (diff, changed files, optional GitNexus impact analysis)
- It spawns your chosen CLI tool with a review prompt
- The response is parsed into structured comments and posted as a GitHub PR review
- If someone replies to a review comment, the daemon responds in-thread
- Multi-harness support -- Claude Code, OpenCode, Codex, or any CLI that accepts a prompt
- No API keys -- uses your existing Pro/Max subscription through the CLI
- Multi-repo -- watch as many repos as you want, each with its own harness and model
- GitNexus integration -- optional codebase indexing for impact analysis and call chain context
- Safety first -- fork policy enforcement, path traversal protection, environment scrubbing, sandboxed execution
- Idempotent -- deduplicated reviews with atomic claim locks, no double-posting on restarts
- Adaptive polling -- ETag caching, backoff, jitter, and rate budget tracking
- CLI-first -- every setting is controllable via CLI commands, designed for agent management
- Signet compatible -- runs with
SIGNET_NO_HOOKS=1to avoid memory pollution and statistical bias - Dry-run mode -- log reviews without posting to GitHub
- Rust toolchain -- install via rustup
- GitHub Personal Access Token -- fine-grained PAT with
pull_requests:read+writeandcontents:readscopes, or a classic PAT withreposcope - At least one AI CLI tool installed and authenticated:
- Claude Code (
claude) -- requires a Pro/Max subscription - OpenCode (
opencode) - Codex (
codex)
- Claude Code (
- GitNexus (optional) --
npm install -g gitnexusor usenpx gitnexus. Enriches reviews with codebase impact analysis
# one-liner (review the script first, or use the clone method below)
curl -sSf https://raw.githubusercontent.com/NicholaiVogel/pr-reviewer/main/install.sh -o install.sh
less install.sh # inspect before running
bash install.shOr from a clone:
git clone https://github.com/NicholaiVogel/pr-reviewer.git
cd pr-reviewer
./install.shThe install script checks prerequisites, builds from source, runs pr-reviewer init, and audits your runtime dependencies. Run ./install.sh --help for options.
If you upgraded from an older install location and your current shell still says pr-reviewer is missing, run hash -r once to clear Bash's cached command path.
pr-reviewer initThis creates ~/.config/pr-reviewer/config.toml and the SQLite state database.
# encrypt and store (prompted for token + optional passphrase)
pr-reviewer config set-token --passphrase
# or pipe from stdin
echo "ghp_..." | pr-reviewer config set-token --stdin
# or store in Signet (if installed)
pr-reviewer config set-token --signet
# check what's configured
pr-reviewer config token-status# auto-clones to ~/.config/pr-reviewer/repos/ (recommended)
pr-reviewer add owner/repo \
--harness claude-code \
--model claude-sonnet-4-6
# or point to an existing local clone
pr-reviewer add owner/repo --path /path/to/local/cloneIf GitNexus is installed, this automatically runs gitnexus analyze to index the repo.
pr-reviewer review owner/repo#42 --dry-run
pr-reviewer review owner/repo#42 --dry-run --harness codex --model gpt-5.4 --reasoning-effort lowThis runs the full review pipeline but logs the output instead of posting to GitHub.
pr-reviewer review owner/repo#42# foreground (see logs in terminal)
pr-reviewer start
# background (writes PID file, stop with `pr-reviewer stop`)
pr-reviewer start --daemon
# check status
pr-reviewer statusThe daemon polls GitHub for new/updated PRs and automatically reviews them. It uses ETag caching and adaptive backoff to stay well within GitHub's rate limits.
Config lives at ~/.config/pr-reviewer/config.toml. All settings can be managed via CLI:
pr-reviewer config list # show all config
pr-reviewer config set harness.default codex # change default harness
pr-reviewer config set harness.model gpt-5.4
pr-reviewer config set harness.reasoning_effort low
pr-reviewer config get daemon.poll_interval_secsSee config.example.toml for the full configuration reference.
Each repo can override the global harness, model, fork policy, and review instructions:
[[repos]]
owner = "nicholai"
name = "openmarketui"
# local_path is optional — omit to use auto-managed clone at ~/.config/pr-reviewer/repos/
# local_path = "/mnt/work/dev/openmarketui"
harness = "codex"
model = "gpt-5.4"
reasoning_effort = "low"
fork_policy = "ignore"
ignore_paths = ["*.lock", "dist/**"]
custom_instructions = "This project uses a custom ORM. Watch for SQL injection."
gitnexus = true- Troubleshooting — diagnosing common errors
- Deployment — systemd, log management, production setup
- Configuration reference — all config options explained
pr-reviewer <COMMAND> [OPTIONS]
pr-reviewer --help
pr-reviewer <command> --helppr-reviewer initCreates config and SQLite state in ~/.config/pr-reviewer/.
# auto-clones to managed directory
pr-reviewer add <owner/repo> \
[--harness claude-code|opencode|codex] \
[--model <model>] \
[--fork-policy ignore|limited|full]
# or use an existing local clone
pr-reviewer add <owner/repo> --path <local_path> [...]
pr-reviewer add --scan <directory>
pr-reviewer add --org <org> # currently not implementedpr-reviewer remove <owner/repo>
pr-reviewer remove <owner/repo> --purge # also deletes managed clonepr-reviewer cleanup # removes orphaned managed clonespr-reviewer listpr-reviewer index <owner/repo>
pr-reviewer index --allRuns gitnexus analyze for the target repo(s).
pr-reviewer review <owner/repo>#<pr_number> \
[--dry-run] \
[--harness claude-code|opencode|codex] \
[--model <model>] \
[--reasoning-effort none|low|medium|high|xhigh] \
[--force] \
[--rerun-completed]--force clears stale or failed local claims for the exact review mode. --rerun-completed is the operator escape hatch for dogfooding: it clears a completed local claim for the exact PR/SHA/harness/dry-run mode and bypasses the GitHub already-posted guard.
pr-reviewer start
pr-reviewer start --daemonStarts polling loop in foreground or background.
pr-reviewer stoppr-reviewer statusShows daemon/process state and recent polling metadata.
pr-reviewer queue list [--repo <owner/repo>] [--status pending|claimed|failed|completed|canceled] [--limit <n>] [--json]
pr-reviewer queue show <id> [--json]
pr-reviewer queue retry <id>
pr-reviewer queue cancel <id>Inspects and operates the persistent maintainer work queue. New PR heads, maintainer commands, and repair markers land here before the daemon invokes the configured agent.
Maintainers can also operate the queue from PR issue comments with @pr-reviewer fix, @pr-reviewer retry [id], and @pr-reviewer cancel [id]. status, explain, and queue-control acknowledgements are posted through the configured agent response path.
pr-reviewer logs \
[--repo <owner/repo>] \
[--since <datetime>] \
[--model <model>] \
[--harness <harness>] \
[--limit <n>]pr-reviewer stats [--repo <owner/repo>] [--since <datetime>]pr-reviewer config list
pr-reviewer config get <key>
pr-reviewer config set <key> <value>
# Token management
pr-reviewer config set-token [--passphrase] [--signet] [--stdin] [TOKEN]
pr-reviewer config remove-token
pr-reviewer config token-statusExamples:
pr-reviewer config set harness.default codex
pr-reviewer config set daemon.poll_interval_secs 60
pr-reviewer config set-token --passphrase
pr-reviewer config token-status| Harness | CLI command | Model flag |
|---|---|---|
| claude-code | claude --model <m> --dangerously-skip-permissions -p "..." |
--model |
| opencode | opencode run --model <m> --format json "..." |
--model |
| codex | codex exec --model <m> --skip-git-repo-check --json "..." |
--model |
Model resolution: per-repo config > global harness.model > harness default.
pr-reviewer runs AI tools against potentially untrusted code. The safety model includes:
- Sandboxed execution: harnesses run in a temporary directory, not the repo root
- Managed repo clones: repos are auto-cloned to
~/.config/pr-reviewer/repos/, keeping your working repos isolated from review agents - Encrypted token storage: GitHub tokens encrypted at rest with double-layer AES-256-GCM (machine-bound keyfile + passphrase/machine-derived key)
- Environment scrubbing:
HOME,SSH_AUTH_SOCK,GH_TOKEN,AWS_*,ANTHROPIC_API_KEY, and other sensitive variables are stripped from the harness environment - Fork policy: configurable per-repo (
ignore,limited,full) with trusted author allowlists - Path validation: canonicalization and containment checks reject traversal attacks and symlink escapes
- Signet bypass:
SIGNET_NO_HOOKS=1prevents hook invocation in spawned processes - Optional Signet secrets: tokens can be stored in Signet's encrypted secret store for unified credential management
GitHub tokens are never stored in plain text by default. The set-token command encrypts tokens with two independent AES-256-GCM layers:
- Machine-bound key: a random 32-byte key stored at
~/.config/pr-reviewer/keyfile(permissions0600) -- this is the primary protection layer; anyone who can read this file can decrypt the token - Passphrase or machine identity: if
--passphraseis used, the inner layer is derived via Argon2id from your passphrase, providing strong protection even if the keyfile is compromised. Without--passphrase, the inner layer uses/etc/machine-id+ username (world-readable inputs, so the keyfile is your real security boundary)
Token resolution order:
- Signet secret store (if Signet is installed and has the secret)
- Encrypted config (
github.encrypted_token) - Plain-text config (
github.token) -- legacy, emits a warning GITHUB_TOKENenvironment variable
For daemon mode with passphrase-protected tokens, set PR_REVIEWER_PASSPHRASE as an environment variable.
Run pr-reviewer config token-status to see which source is active.
If GitNexus is installed and a repo has been indexed (.gitnexus/ directory exists), pr-reviewer enriches review context with:
- Impact analysis (blast radius of changed symbols)
- Call chain tracing (upstream/downstream dependencies)
- Community context (which functional area of the codebase is affected)
To index a repo: pr-reviewer index owner/repo or gitnexus analyze /path/to/repo.
