CLI & npm Package
In addition to the webhook-based GitHub App, ai-review-bot ships as an npm package with a CLI tool for running full-repository audits on demand — no PR, no webhook, no Vercel required.
Local review (ai-review review)
Run the full multi-agent review against your local working copy and write a durable Markdown report into docs/code-reviews/ — no GitHub PR, and it can bill your existing Codex / Claude subscription instead of API credits.
ai-review review [--full | --commit <sha>] [--slug <slug>] [--title <t>] [--out <dir>] [--extra <text>] [--json]| Flag | Description |
|---|---|
| (default) | Review local changes (committed + working-tree, vs the merge-base with the default branch). |
--full | Review the entire tracked tree. |
--commit <sha> | Review exactly the files touched by <sha>, read at that commit. |
--slug <slug> | Override the filename slug (default: branch / commit subject / full-audit). |
--title <t> | Override the report H1 / front-matter title. |
--out <dir> | Output directory (default docs/code-reviews). |
--extra <text> | Extra instructions passed to every review agent. |
--json | Print { path, durationSeconds, costUsd, filesReviewed, providers } to stdout. |
Reports are named <YYYY-MM-DD>-<slug>-<NN>.md with a per-day, per-slug round number, and carry YAML front-matter (status, scope, remote, duration_seconds, cost_usd, providers, models, skills, findings). Flip status: reviewed → implemented once findings are addressed.
Auth resolution (local, personal use only)
Per provider, the CLI tries in order: API key (OPENAI_API_KEY / ANTHROPIC_API_KEY, or an explicit ANTHROPIC_AUTH_TOKEN / CLAUDE_CODE_OAUTH_TOKEN) → subscription OAuth from your logged-in codex (~/.codex/auth.json) and Claude Code (macOS Keychain). A provider that can't authenticate is skipped.
⚠️ The OAuth fallback is for your own machine only. Anthropic's ToS (eff. 2026-02-20) prohibits using Claude subscription OAuth tokens in third-party tools outside Claude Code / Claude.ai, and refresh tokens are shared with the real CLIs. See docs/code-reviews/README.md. The hosted webhook bot is unaffected — it uses API keys only.
Fix workflow
The /code-review slash command (in .claude/commands/) wraps this CLI with three modes: doc-only (default), --fix (auto-apply findings + run gates + flip status), and --propose (propose fixes, get sign-off, then apply).
What the audit does
The audit mode fetches every code file in a repository at a given ref, batches them into 150 KB chunks, and runs all five review agents on each batch. Findings are merged, deduplicated, and posted as a GitHub issue in the target repo. It runs against the entire codebase, not just a diff.
Supported file extensions: .ts, .tsx, .js, .jsx, .mjs, .cjs, .py, .go, .rs, .rb, .java, .cs, .cpp, .c, .h, .swift, .kt.
Installation
npm install -g ai-review-bot # global install
npx ai-review-bot@latest owner/repo # one-off, no installUsage
ai-review OWNER/REPO [--ref <branch-or-sha>] [--dry-run] [--extra <instructions>] [--provider <anthropic|openai>]Arguments
| Argument | Description |
|---|---|
OWNER/REPO | Repository to audit (required) |
--ref <ref> | Branch, tag, or SHA to audit. Defaults to the repo's default branch. |
--dry-run | Print the audit report to stdout instead of creating a GitHub issue. |
--extra <text> | Additional instructions passed to every review agent. |
--provider <name> | AI provider: anthropic (default) or openai. |
Environment variables
| Variable | Required | Description |
|---|---|---|
GITHUB_APP_ID | ✓ | Numeric GitHub App ID |
GITHUB_APP_PRIVATE_KEY | ✓ | PKCS#8 private key PEM (\n for newlines) |
ANTHROPIC_API_KEY | ✓ (anthropic) | Anthropic API key (required when using --provider anthropic) |
OPENAI_API_KEY | ✓ (openai) | OpenAI API key (required when using --provider openai) |
Examples
# Audit the default branch, post findings as a GitHub issue
GITHUB_APP_ID=12345 \
GITHUB_APP_PRIVATE_KEY="$(cat key.pem | awk 'NF {printf "%s\\n", $0}')" \
ANTHROPIC_API_KEY=sk-ant-... \
ai-review joeblackwaslike/my-project
# Audit a specific branch without posting (dry run)
ai-review joeblackwaslike/my-project --ref feature/new-api --dry-run
# Audit with extra instructions
ai-review joeblackwaslike/my-project --extra "focus on database query safety"Output
On success the CLI prints progress as it runs:
Found 142 code files in joeblackwaslike/my-project@main
Fetched 142 files
Running agents over 3 batch(es)...
Batch 1/3: 20 files
Batch 2/3: 20 files
Batch 3/3: 20 files
Audit issue created: https://github.com/joeblackwaslike/my-project/issues/47With --dry-run, the report is printed to stdout instead of posted as an issue.
GitHub Action
Use the published action to run a full-repo audit inside any CI workflow:
- uses: joeblackwaslike/ai-review-bot@v0.1.0
with:
github-app-id: ${{ secrets.GITHUB_APP_ID }}
github-app-private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}Action inputs
| Input | Required | Default | Description |
|---|---|---|---|
github-app-id | ✓ | — | GitHub App ID |
github-app-private-key | ✓ | — | PKCS#8 private key PEM (newlines as \n) |
anthropic-api-key | — | — | Anthropic API key (required when provider is anthropic) |
openai-api-key | — | — | OpenAI API key (required when provider is openai) |
provider | — | anthropic | AI provider: anthropic or openai |
repo | — | current repository | Repository to audit (owner/repo) |
ref | — | repo default branch | Branch, tag, or SHA to audit |
dry-run | — | false | Set to true to print the report without creating an issue |
extra | — | — | Additional instructions for the review agents |
version | — | latest | npm version of ai-review-bot to use (e.g. 0.1.0) |
Scheduled audit example
Run a full codebase audit every Monday morning and post findings as a GitHub issue:
name: Weekly audit
on:
schedule:
- cron: '0 8 * * 1' # every Monday at 08:00 UTC
workflow_dispatch:
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: joeblackwaslike/ai-review-bot@v0.1.0
with:
github-app-id: ${{ secrets.GITHUB_APP_ID }}
github-app-private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}Audit a different repo
- uses: joeblackwaslike/ai-review-bot@v0.1.0
with:
github-app-id: ${{ secrets.GITHUB_APP_ID }}
github-app-private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
repo: myorg/other-repo
ref: main
extra: "This codebase uses strict null checks. Flag any unsafe casts."Difference from PR reviews
| PR Review (webhook bot) | Full Audit (CLI / Action) | |
|---|---|---|
| Trigger | PR opened, pushed, or /ai-review command | Manual, scheduled, or CI step |
| Input | Unified diff of changed lines | All code files in the repo |
| Output | GitHub Pull Request Review with inline comments | GitHub Issue with a structured report |
| Providers | Claude + Codex in parallel | Claude (default) or Codex (--provider openai) |
| Inline comments | Yes — anchored to diff lines | No — whole-file findings only |
Private key formatting
Both the CLI and the Action require the private key as a single-line string with \n for newlines:
awk 'NF {printf "%s\\n", $0}' your-private-key.pemStore the output as a GitHub Actions secret or shell environment variable. The CLI normalizes \n back to real newlines at runtime.
Credentials for ai-review watch outside this repo
The globally npm-linked ai-review binary has no autoload for this repo's .env — if you run ai-review watch from a different repo's directory with no matching environment already exported, it fails with GITHUB_APP_ID environment variable is required. ai-review creds fixes this by storing the credentials in the macOS Keychain, which the CLI checks automatically at startup before falling back to ~/.config/ai-review/.env as a last resort.
Which vars ai-review watch needs
Only the 4 identity vars used to post through the two GitHub App bots:
GITHUB_APP_ID,GITHUB_APP_PRIVATE_KEY— the Claude bot's identityOPENAI_APP_ID,OPENAI_APP_PRIVATE_KEY— the Codex bot's identity
(Webhook secrets, DATABASE_URL, QSTASH_*, and KV_REST_API_* are server/webhook-only and not needed by the CLI.)
Setting them — primary source: this repo's own .env
The correct values already live in this repo's .env file. creds set <VAR> accepts the value on stdin — it never touches our own argv or shell history:
grep '^GITHUB_APP_ID=' .env | cut -d= -f2- | ai-review creds set GITHUB_APP_ID
grep '^GITHUB_APP_PRIVATE_KEY=' .env | cut -d= -f2- | ai-review creds set GITHUB_APP_PRIVATE_KEY
grep '^OPENAI_APP_ID=' .env | cut -d= -f2- | ai-review creds set OPENAI_APP_ID
grep '^OPENAI_APP_PRIVATE_KEY=' .env | cut -d= -f2- | ai-review creds set OPENAI_APP_PRIVATE_KEYWith no pipe attached, creds set <VAR> prompts interactively (input hidden, not echoed) instead. The private key values in .env are already single-line \n-escaped — no reformatting needed.
creds set <VAR> <value> (value as a third argument) still works for scripted callers that have already accepted the trade-off, but avoid it for anything sensitive: the value additionally lands in your shell history. <VAR> must be one of the 4 vars above — an unrecognized name is rejected rather than silently creating an orphaned Keychain entry.
For the two _PRIVATE_KEY vars specifically, creds set also checks the resolved value looks like a complete PEM (starts with -----BEGIN, contains a matching -----END) before writing it — this catches the one real failure mode of interactive entry: pasting a raw, un-escaped multi-line PEM into the hidden prompt, which reads only one line and would otherwise silently store a truncated key. Pasting the documented single-line \n-escaped form (the only form this CLI ever produces or expects) works fine either way, piped or interactive.
Residual exposure, either way: the stdin/prompt form keeps the value out of ai-review's own argv and your shell history, but the Keychain write itself shells out to macOS's security add-generic-password ... -w <value>, which briefly holds the value in that subprocess's argv (visible via ps//proc for its short lifetime) regardless of how ai-review obtained it. This is a security-CLI limitation, not something this feature can route around: its only non-argv input mode is an interactive double-entry prompt (type it twice, no echo) that reads from the controlling terminal, not stdin — incompatible with the piped/non-interactive flow above, which is the primary intended use. src/auth.ts's existing Keychain writer (the Claude Code OAuth token storage this feature mirrors) has the identical -w <value> pattern for the same reason.
Check what's currently stored (names only, never values) with ai-review creds list, and remove an entry with ai-review creds unset <VAR>.
Recovery path if .env is ever lost
Go to
github.com/settings/appsand open the existing app (the Claude bot app forGITHUB_APP_ID, the Codex bot app forOPENAI_APP_ID).Read the App ID at the top of the settings page.
Under Private keys, click Generate a private key to get a new PEM — the original can't be re-downloaded.
Convert it to the
\n-escaped one-liner the CLI expects (same command as Private key formatting above):bashawk 'NF {printf "%s\\n", $0}' new-private-key.pemPipe the result to
ai-review creds set GITHUB_APP_PRIVATE_KEY(orOPENAI_APP_PRIVATE_KEY):bashawk 'NF {printf "%s\\n", $0}' new-private-key.pem | ai-review creds set GITHUB_APP_PRIVATE_KEY
~/.config/ai-review/.env fallback
If the Keychain isn't usable (e.g. a headless/non-interactive context), the CLI falls back to a plain KEY=VALUE file at ~/.config/ai-review/.env — the same format as this repo's own .env.example, so it's literally copyable from there. This file is plaintext on disk; the Keychain is preferred whenever it's available. If you use this fallback, chmod 600 ~/.config/ai-review/.env.