Skip to content

CLI Reference

pr-review reads a unified diff, runs one Vizzini mode against your LiteLLM proxy, and prints the validated result.

Terminal window
git diff main...HEAD | pr-review --mode review
pr-review --patch-file change.patch --mode describe --format json
git diff main...HEAD | pr-review --mode risk # no model or proxy needed
Flag Default Meaning
--patch-file - Unified diff to read. - reads stdin
--mode review describe, review, improve, command, plan or risk (the deterministic score alone; needs no proxy or model)
--issue Plan mode: JSON issue file {title, body, labels}. See Pre-Code Planning
--tree Plan mode: repository paths, one per line (git ls-files > tree.txt)
--okf-index Plan mode: the knowledge base’s root index.md
--command Command mode: a slash command, e.g. "/explain a.go:44-45 why?"
--thread Command mode: JSON file with the thread history, [{"author": "...", "body": "..."}]
--litellm-url $VIZZINI_LITELLM_URL OpenAI-compatible API root, e.g. http://litellm:4000/v1
--model $VIZZINI_MODEL Model name as configured in LiteLLM
--format markdown markdown (for humans and mrman) or json
--max-chunk-tokens 6000 Token budget per LLM request
--concurrency 4 Parallel LLM requests
--timeout 10m Overall deadline
--skip-oversized false Review mode: skip hunks larger than the token budget
--knowledge Review mode: OKF bundle directory (e.g. .okfw) whose relevant documents the model may cite. See Knowledge-Grounded Reviews
--repo Review mode: the repository checkout at the change’s head (e.g. .). The definitions of symbols the change uses and the callers of symbols it changes are given to the model as read-only context. See Repository Context
--run-id generated UUIDv7 Attribution: this run’s ID. Every request carries it, as metadata and as the W3C trace ID (VIZZINI_RUN_ID). See Cost Attribution
--pr — Attribution: the pull request, e.g. ado:dev.azure.com/org/project/repo#42 (VIZZINI_PR)
--iteration — Attribution: the head commit reviewed (VIZZINI_ITERATION)
--requester — Attribution: the human the run is for, sent as the proxy’s end user (VIZZINI_REQUESTER)
--agent pr-review Attribution: the tool asking (VIZZINI_AGENT)
--risk-policy JSON risk policy (#RiskPolicy): path weights, threshold, sensitivity. See Risk & Auto-Approve
--lint-json Review mode, repeatable: a linter report, either golangci-lint JSON or SARIF, whose diagnostics on changed lines the model should explain. See Lint-Aware Reviews
--fail-on Critical,Major Review mode: comma-separated severities that make pr-review exit 2, or none
--all-findings off Review mode: report every finding. By default the noise floor moves Trivial findings, and Minor Performance findings, to the JSON report’s filtered list. See The noise floor
Variable Used for
VIZZINI_LITELLM_URL, VIZZINI_MODEL Defaults for the flags above
VIZZINI_API_KEY Bearer token for the proxy (falls back to LITELLM_API_KEY). There is deliberately no flag, so the key never appears in ps
TIKTOKEN_CACHE_DIR Pre-seeded tokenizer cache. See Running Offline
Mode JSON output
review {summary, risk_score, base_risk_score, model_risk_score, risk_files[], auto_approve, findings[], knowledge_docs[], excluded[], skipped[], chunks, diagnostics, merged_findings, context_snippets, run_id, pr_key, iteration, requester, agent, usage} with findings sorted most severe first; merged_findings counts same-span duplicates folded into one (knowledge guide); context_snippets counts the repository-context snippets given
describe {title, type, summary, changes[]}
improve {suggestions: [{file, start_line, end_line, category, summary, existing_code, improved_code}]}
plan {summary, affected_files[], phases[], verification[], risks[], references[]} (no patch is read)
command {command, answer} for /explain; {command, suggestions[]} for /refactor and /docstrings
risk {score, band, files[]}: the deterministic risk score, with no model call

Every model answer is validated against the schema and anchored to the diff before it is printed. JSON output is a report: it starts with "apiVersion": "vizzini.infrashift.io/v1" and a "kind" and is itself schema-checked, ready for garmr.

Code Meaning
0 Success
1 Any error: bad flags, unreadable patch, proxy failure, or an answer the model could not repair
2 Review mode: at least one finding has a severity listed in --fail-on

The gate’s default comes from #PolicyGate in schema/review.cue, which blocks on Critical and Major. The review is always printed in full, and the gate only decides the exit code, so a CI job can post the review and then fail:

Terminal window
git diff origin/main...HEAD | pr-review --mode review > review.md
status=$? # 0 pass, 2 blocked by policy, 1 error
Terminal window
pr-review --fail-on Critical # block only on Critical
pr-review --fail-on Critical,Major,Minor
pr-review --fail-on none # report, never block

An unknown severity such as --fail-on High is rejected before any request is made.

Some kinds of finding are rarely worth a reviewer’s time. In Vizzini’s benchmark, 6% of Trivial findings and about a fifth of Minor Performance findings were real problems, against 81% of Major ones. By default, pr-review leaves these out. Minor Maintainability findings were as noisy, but models sometimes file a real bug under Maintainability, so the default keeps them:

  • Where they go: they are not shown in Markdown or text output. The JSON report keeps them in a filtered list, so nothing is lost.
  • What still sees them: the floor decides what is shown, never what blocks. --fail-on still applies to filtered findings, and so does auto-approval. When a filtered finding fails the gate, pr-review says so.
  • The bot: vizzini-bot does not post filtered findings. A thread it posted earlier for such a finding is left open, not resolved as fixed.

The rules live in #NoiseFloor in schema/review.cue. --all-findings turns the floor off for one run. Embedders set Config.NoiseFloor, where {"rules": []} turns it off, or use ReviewOptions.AllFindings.

Interrupting with Ctrl-C or SIGTERM cancels in-flight requests.