@flowlaps/scrutineer
v0.9.0
Published
Multi-agent PR review orchestrator CLI
Downloads
2,227
Maintainers
Readme
scrutineer
Scrutineer is an autonomous, sandboxed CLI that reviews the TypeScript files in your pull request before you merge — so you get a real code-review and security-audit pass, plus a sandboxed smoke test, without waiting on a human reviewer or shipping your diff to some black-box SaaS.
Key Features
- AST-grounded context, not just a raw diff.
ts-morphparses the target file and extracts exported function signatures, imports, and interfaces into a compact summary, so the model reviews structured facts about the file instead of guessing from text. - Layered agent personas. Each file goes through a
code-reviewerpass and then asecurity-auditorpass, using pinned, hash-verified persona prompts sourced from Addy Osmani'sagent-skillsrepository — seedocs/adr/0003-pin-and-hash-verify-persona-prompts.mdfor why they're pinned. - Air-gapped local model support.
--provider ollamaruns the entire pipeline against a local Ollama model, so nothing leaves your machine. Scrutineer warns on stderr ifOLLAMA_HOSTresolves off loopback, since that means review content is going somewhere other than your own box. isolated-vmsecure sandbox. The model also generates a small smoke test for the file, which runs inside an ephemeral V8 isolate with a bounded memory limit, an execution timeout, and zero filesystem, network, or Node built-in access. On--provider anthropic/openai/geminiit runs in parallel with the review passes; on--provider ollamait runs after them instead, to avoid contending with a single local model. A script that blows past its budget gets its failure captured, not left to crash the process.- Diffs get scrubbed before they leave your machine. Anything that looks like an API key, token, or private key block is redacted out of the diff before it's included in a prompt.
See docs/ARCHITECTURE.md for the full data flow.
Quick Start
# install
npm install -g @flowlaps/scrutineer
# set your API key for this shell session
export ANTHROPIC_API_KEY=sk-ant-...
# review a file
scrutineer review ./src/index.tsOr skip the install and run it straight from the registry:
npx @flowlaps/scrutineer review ./src/index.tsPrefer a fully offline setup? Install Ollama, pull a model, then point scrutineer at it — no API key needed:
ollama pull phi4
scrutineer review ./src/index.ts --provider ollamaOther useful flags:
scrutineer review ./src/index.ts --output review.md # write the report to a file
scrutineer review ./src/index.ts --pr 42 # post the report as a PR comment
scrutineer parse ./src/index.ts --json # just the AST extraction, no model callPick a specific model instead of the provider's default, e.g. to trade cost for reasoning quality:
scrutineer review ./src/index.ts --provider anthropic --model claude-opus-4-8--model (-m) takes precedence over SCRUTINEER_MODEL_* when both are set; omit it to keep today's per-provider default (or, for --provider ollama, its auto-detection of a locally running model).
Review every changed file against a git ref in one batch, instead of naming a file — useful in a pre-push hook or CI:
scrutineer review --diff origin/mainThis resolves git diff --name-only origin/main...HEAD internally, filters it to .ts/.tsx files, and sends all of them to the review swarm as a single batch call so findings can reference across files. --diff and a file argument are mutually exclusive — pass one or the other.
Any --pr run automatically fetches the PR's already-resolved review threads and won't re-flag a finding you've already addressed (unless the same file/line changed again). When --pr is combined with --diff, it also refuses a batch touching more than 10 files — split a larger PR into smaller ones for reliable review results.
Configuration
Scrutineer reads all credentials and overrides from environment variables in whatever shell or CI job it's running in. There's no config file — set what you need before invoking the CLI.
| Variable | Required | Description |
|---|---|---|
| ANTHROPIC_API_KEY | Yes, for --provider anthropic (the default) | API key used to call Claude. Not needed with --provider ollama, --provider openai, or --provider gemini. |
| OPENAI_API_KEY | Yes, for --provider openai | API key used to call OpenAI. |
| GOOGLE_GENERATIVE_AI_API_KEY | Yes, for --provider gemini | API key used to call Gemini. |
| GITHUB_TOKEN | Only for scrutineer review --pr <number> | Personal access token with permission to comment on the repo's PRs. |
| OLLAMA_HOST | No | Overrides the Ollama server address (defaults to http://127.0.0.1:11434). Scrutineer warns on stderr if this isn't a loopback address, since review content is sent to whatever host it points at. |
| SCRUTINEER_MODEL_ANTHROPIC | No | Overrides the default Anthropic model (claude-sonnet-5). |
| SCRUTINEER_MODEL_OLLAMA | No | Overrides the default Ollama model (auto-detected from what's running locally, falling back to phi4). |
| SCRUTINEER_MODEL_OPENAI | No | Overrides the default OpenAI model (gpt-4o-mini). |
| SCRUTINEER_MODEL_GEMINI | No | Overrides the default Gemini model (gemini-flash-lite-latest). |
Local shell — export vars directly, or drop them in a .env file (copy .env.example to .env and fill it in):
export ANTHROPIC_API_KEY=sk-ant-...
export GITHUB_TOKEN=ghp_...GitHub Actions — set them in the job's env block, backed by repo/org secrets:
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx @flowlaps/scrutineer review ./src/index.ts --pr ${{ github.event.pull_request.number }}
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Troubleshooting
pnpm (v10+): Scrutineer depends on isolated-vm, which compiles a native C++ addon during install. Modern pnpm blocks native build scripts by default for security reasons, so after pnpm install you'll need to explicitly approve it:
pnpm approve-buildsand allow isolated-vm to compile. Without this step, the sandbox will fail to load.
Development
To work on the CLI itself, build from source:
git clone https://github.com/Flowlaps/scrutineer.git
cd scrutineer
npm install
npm run build| Command | Description |
|---------|-------------|
| npm run dev | Run the CLI from source with tsx (no build step) |
| npm run build | Compile TypeScript to dist/ |
| npm start | Run the compiled CLI from dist/ |
| npm run typecheck | Type-check without emitting |
| npm test | Run the test suite (node --test) |
