* fix(agent): enforce --max-tokens-budget inside a running group The budget was only checked when the next group was dispatched, so a review with fewer groups than --concurrency could never hit it. Check it before every LLM round, give the over-budget group one final round to submit findings, and report it as failed(budget). * fix(agent): record the budget when the round gate skips a round The round gate in executeGroupSubtask breaks out of the round loop when the aggregate budget is already spent, but it was the only budget stop that did not set budgetExceeded. A group whose round finished normally — task_done, findings submitted — and only then tripped the gate left the run reporting the budget as intact, because no other gate ever looked again. It now records the stop the same way the in-conversation check does, with a warning naming the skipped round, the group, and the usage against the cap. The grace round stays on StopTokenBudget, in answer to the review on this PR. It is one bounded call whose whole job is to let the model submit findings it already has; skipping it spends the tokens the run has already paid for and throws the findings away. What was missing was not the skip but the record, plus docs that say the cap is checked before every round rather than only at dispatch — the cli-reference and CI input tables in all five locales now say so. Test covers the gate specifically: a group whose round 1 ends in task_done already over budget must not start round 2, must not get a grace round (it has nothing unreported), must stay classified completed, and must still report BudgetExceeded.
28 KiB
title, sidebar
| title | sidebar | ||
|---|---|---|---|
| CLI Reference |
|
The complete reference for every ocr subcommand, flag, and exit
behaviour.
Global usage
OpenCodeReview - AI-Powered Code Review CLI
Usage:
ocr [command]
Commands:
review, r Start a code review
rules Inspect and debug review rules
config Manage configuration settings
llm LLM utility commands
viewer Start the WebUI session viewer
session, sessions List and inspect saved review sessions
version Show version information
Examples:
ocr review --from master --to dev Review diff range
ocr review --commit abc123 Review a single commit
ocr review --background "Focus on auth" Review with inline context
ocr review -B ./docs/requirements.md Review with context file
ocr config provider Interactive provider setup
ocr config model Interactive model selection
ocr config set llm.model opus-4-6 Set a config value
ocr llm test Test LLM connectivity
ocr llm providers List built-in providers
ocr session list List saved review sessions
ocr version Show version info
Use "ocr review -h" for more information about review.
Use "ocr rules -h" for more information about rules.
Use "ocr config" for more information about config.
Use "ocr llm" for more information about LLM utilities.
Use "ocr session -h" for more information about session inspection.
GitHub: https://github.com/alibaba/open-code-review
Global flags
Available on every command, and accepted either before or after the subcommand
(ocr --color=never review and ocr review --color=never are equivalent).
| Flag | Default | What it does |
|---|---|---|
--color <auto|always|never> |
auto |
When to emit ANSI color. auto colorizes only when stdout is a terminal, so piping or redirecting yields plain text. always keeps color through a pipe (useful for | less -R). |
Text output is plain whenever stdout is not a terminal, so it can be piped safely:
ocr review --commit HEAD | gh issue comment 123 --body-file -
TERM=dumb also disables color.
Command summary
| Command | Alias | What it does |
|---|---|---|
ocr review |
ocr r |
Run a code review and emit comments. |
ocr scan |
ocr s |
Scan complete files without requiring a Git diff. |
ocr rules check <file> |
— | Show which rule applies to a given file path and where it came from. |
ocr config set <key> <value> |
— | Persist a config value to ~/.opencodereview/config.json. |
ocr config unset custom_providers.<name> |
— | Delete a custom provider (clears active provider/model if it was active). |
ocr config provider |
— | Interactive provider-setup TUI. |
ocr config model |
— | Interactive model-selection TUI. |
ocr llm test |
— | Send a small chat request to verify the configured endpoint. |
ocr llm providers |
— | List all built-in LLM providers. |
ocr session list |
ocr sessions list, ocr session ls |
List saved review sessions. |
ocr session show <id> |
ocr sessions show <id> |
Inspect one session and its per-file checkpoints. |
ocr session comments <id> |
ocr sessions comments <id> |
Print the review comments recorded in one session. |
ocr session compare <before> <after> |
ocr session diff <before> <after> |
Compare two sessions' findings: new, persisting, resolved, not reviewed. |
ocr viewer |
— | Launch the local web UI for past review sessions (localhost:5483). |
ocr version |
— | Print version, commit, platform, build date, and GitHub URL. |
ocr and ocr -h print top-level usage. Each subcommand also accepts
-h / --help.
ocr review
The main command. Resolves a Git diff, groups the changed files semantically, dispatches one sub-agent per group, collects review comments, and prints them.
Synopsis
ocr review [flags]
ocr r [flags] (alias)
If no flags are passed, OCR runs in workspace mode — review of all staged + unstaged + untracked changes in the current directory's repo.
Flags
| Flag | Short | Default | Description |
|---|---|---|---|
--repo <path> |
— | current dir | Git repository root. |
--from <ref> |
— | — | Source ref to start the diff from (e.g., main). |
--to <ref> |
— | — | Target ref to end the diff at (e.g., feature-branch). When set, OCR computes merge-base(from, to)..to. |
--commit <sha> |
-c |
— | Single commit to review (vs its parent). |
--preview |
-p |
false |
Run the filter pipeline but skip the LLM. Prints the file list and exclusion reasons. Honors --format json; --format sarif is not supported (a preview has no completed findings to emit). |
--no-filter |
— | false |
Keep all review comments and skip the per-subtask REVIEW_FILTER_TASK LLM post-processing call. A subtask reviews a single file or a bundle of related files. |
--resume <session-id> |
— | — | Resume from a previous compatible range or commit review session. |
--format <fmt> |
-f |
text |
text (human-readable), json (machine-readable comment array), or sarif (SARIF 2.1.0 report for GitHub Code Scanning). |
--output <path> |
-o |
stdout | Write review results to a UTF-8 file (- means stdout). Lazily created on first write so failed runs leave existing files untouched. Text format automatically strips ANSI color codes. |
--audience <who> |
— | human |
human streams progress lines (to stderr when --format is json/sarif, so stdout stays a single parseable document); agent suppresses progress entirely and prints only the final summary / JSON. |
--background <text> |
-b |
— | Optional requirement / business context injected into the plan + main prompts. |
--background-file <path> |
-B |
— | Path to a Markdown file used as review background. Takes precedence over --background when both are set. |
--exclude <patterns> |
— | — | Comma-separated gitignore-style patterns to exclude; merged with the excludes section of rule.json |
--concurrency <n> |
— | 8 |
Maximum number of subtasks reviewed in parallel. |
--timeout <minutes> |
— | 15 |
Per-subtask deadline. 0 disables the timeout. Scaled linearly by the number of effort review rounds (e.g. 15/30/45 min for low/medium/high). |
--effort <level> |
— | medium |
Review effort preset: low (1 review round), medium (2 rounds), high (3 rounds). More rounds improve recall at proportionally higher cost. Overrides the saved effort setting for this run. |
--rule <path> |
— | — | Path to a custom JSON review rule file. Overrides the project-level and global rule.json. |
--max-tools <n> |
— | template default | Max tool-call rounds per subtask. 0 uses the template default (100); values 1–49 are clamped up to 50. The flag only ever raises the cap — a value below the template default is ignored. |
--max-tokens <n> |
— | config or template default | Prompt (input) token ceiling per subtask; the template default is 200000. Overrides the saved max_tokens setting for this run. Does not change the output cap — see MAX_COMPLETION_TOKENS. |
--max-tokens-budget <n> |
— | 0 (unlimited) |
Cap total input + output token usage for the review. Checked before every LLM round: a subtask already over budget gets one final round to submit findings and is reported as failed(budget), no further subtasks are dispatched, and partial results are still published. |
--provider <name> |
— | — | Select a configured provider for this run. Names under both providers and custom_providers are accepted. |
--model <name> |
— | — | Override the resolved LLM model for this run (e.g., claude-opus-4-6). |
--max-git-procs <n> |
— | 16 |
Maximum number of concurrent git subprocesses. |
--tools <path> |
— | embedded | Path to a custom JSON tool-config file. Overrides the embedded tool definitions. |
Mode flags are mutually exclusive: pass either
--from/--to, or--commit, or neither (workspace mode). Mixing them is a hard error.--resumesupports only range or commit reviews and cannot be combined with--preview.
Per-run LLM selection
Both review and scan accept --provider and --model. The overrides
apply only to the current invocation and do not modify saved configuration:
ocr review --provider anthropic --model claude-opus-4-6 --format json
ocr scan --provider openai --model gpt-5.4 --format json
An explicit --provider selects a saved entry from providers or
custom_providers before normal source resolution. Without --provider, OCR
preserves the legacy source order: saved configuration, complete OCR_LLM_*
environment configuration, complete Claude Code environment configuration, then
shell rc files. --model overrides the model within whichever source wins; it
does not change that source order. Incomplete strategies fall through without
being mixed. A selected built-in provider's credentials may still come from its
supported environment variable.
Modes
Workspace mode (default)
ocr review
OCR assembles the working-tree changes from two git commands:
- tracked changes via
git diff HEAD(staged + unstaged combined againstHEAD; if that comes back empty, OCR falls back togit diff --staged) - untracked files via
git ls-files --others --exclude-standard, read from disk and treated as full-file additions
This is what you usually want pre-commit. Stage selectively if you want narrower scope.
Range mode
ocr review --from main --to feature-branch
OCR computes merge-base(main, feature-branch)..feature-branch so you only
see the diff introduced by the feature branch — not unrelated changes
that landed on main since branching.
Commit mode
ocr review --commit abc123
ocr review -c abc123
Reviews the diff produced by git show abc123 (i.e., the changes that
single commit introduced).
Resuming interrupted reviews
Every ocr review run persists a local session log under
~/.opencodereview/sessions/. Successful text output stays focused on review
results and does not print the session ID; use ocr session list/show to find
saved sessions, or --format json to include session_id in machine-readable
output. If a range or commit review is interrupted, list saved sessions and
resume from one that matches the same review target:
ocr session list
ocr session show <session-id>
ocr session comments <session-id>
ocr review --from main --to feature-branch --resume <session-id>
ocr review --commit abc123 --resume <session-id>
Resume is strict by design. Checkpoints are only reused when the resumed run would review the same thing the parent did:
- workspace reviews cannot be resumed
- the review mode must match: a range session cannot be resumed as a commit one
- the resolved input must match. Ref spellings are not compared —
abc1234andabc1234defname the same commit — but if the same refs now resolve to a different diff, or the rules or filters changed the selected file set, the whole resume is rejected rather than partially reused - a provider or model change must be asked for explicitly with
--provider/--model. A change that arrived through config or the environment is rejected - the parent must carry a run manifest, which is what its input is verified against. After file dispatch begins, Ctrl-C cancels the review gracefully and records one, so completed checkpoints remain resumable. A process killed before graceful shutdown and sessions older than run manifests do not have one
- only files the parent's manifest settled are reused. A checkpoint the manifest does not account for, or one that is unreadable, costs that file its checkpoint and nothing more — it is simply reviewed again
--previewand--resumecannot be used together
A rejected resume writes nothing: no session, no manifest, no LLM call.
Output
Text (default, --audience human)
Progress lines stream as the review runs, followed by one block per
comment (a dim Unicode-rule header with path:start-end, the comment
body wrapped to 100 columns, and — when present — a colored inline diff
of the suggested replacement). A run summary lands on stdout at the end:
[ocr] 17 file(s) changed, reviewing 9 in /path/to/repo
[ocr] Skipping image.png — filtered by path/extension rules
[ocr] ▶ file_read "src/foo.go"
[ocr] ✔ file_read (12ms)
[ocr] Plan completed for src/foo.go
…
─── src/foo.go:42-47 ───
Concurrent map access without a lock — wrap with sync.RWMutex.
- m[k] = v
+ mu.Lock(); defer mu.Unlock(); m[k] = v
…
[ocr] Summary: 9 file(s) reviewed, 14 comment(s), ~21344 token(s) used (input: ~18012, output: ~3332), 1m12s elapsed
Text (agent, --audience agent)
Identical comment output, but progress lines are suppressed via an internal
quiet-able stdout writer (internal/stdout).
Use this in CI / when piping into another agent.
JSON
ocr review --format json --audience agent
The document is always written to stdout on its own. With the default
--audience human the [ocr] progress lines stream to stderr as the review
runs, so you can watch a long run and still pipe stdout straight into a parser:
ocr review --format json > result.json # progress still visible on the terminal
ocr review --format json | jq .summary # stdout is a single JSON document
Pass --audience agent to drop the progress lines altogether, or 2>/dev/null
to discard them at the shell.
{
"status": "success",
"llm": {
"provider": "anthropic",
"model": "claude-opus-4-6"
},
"summary": {
"files_reviewed": 9,
"comments": 1,
"total_tokens": 21344,
"input_tokens": 18012,
"output_tokens": 3332,
"elapsed": "1m12s"
},
"comments": [
{
"path": "src/foo.go",
"content": "Concurrent map access without a lock — wrap with sync.RWMutex.",
"start_line": 42,
"end_line": 47,
"existing_code": "m[k] = v",
"suggestion_code": "mu.Lock(); defer mu.Unlock(); m[k] = v",
"thinking": "Looking at line 42, the map …"
}
]
}
Top-level fields:
| Field | Notes |
|---|---|
status |
success, completed_with_warnings, completed_with_errors, or skipped. |
llm |
Resolved LLM identity. The normalized model is always present; provider is present only for a named configured provider. |
message |
Optional. Human-readable summary, e.g. "No comments generated. Looks good to me.". |
summary |
Optional. Run aggregates: files_reviewed, comments, total_tokens, input_tokens, output_tokens, cache_read_tokens (omitempty), cache_write_tokens (omitempty), elapsed. Omitted for skipped runs. |
comments |
Always present, possibly empty. Per-comment fields are the ones in the example above. |
warnings |
Optional. Present when one or more sub-agents failed; each entry describes the affected file and the error. |
session_id |
Optional. Present on persisted review runs; pass this to ocr review --resume <session-id> when retrying compatible range or commit reviews. |
resume |
Optional. Present on resumed runs with resumed_from, reused_files, rerun_files, previous_model, and current_model. |
When no files were eligible for review, JSON mode emits a skipped
envelope instead so callers can distinguish "no changes" from "no findings":
{
"status": "skipped",
"message": "No supported files changed.",
"llm": {
"provider": "anthropic",
"model": "claude-opus-4-6"
},
"comments": []
}
Exit codes
| Code | Meaning |
|---|---|
0 |
Review completed (possibly with zero comments, possibly with non-fatal warnings). |
1 |
Fatal error — bad flags, can't resolve LLM endpoint, all per-group sub-agents failed, etc. The error text is printed to stderr. |
Non-fatal warnings (a single sub-agent failed, a file exceeded the token
threshold, etc.) are printed inline; in JSON mode they're added to the
warnings array.
ocr scan
Full-file review without a Git diff. Each file's current content is read from the working tree and sent to the LLM — useful for auditing an unfamiliar codebase or a directory with no meaningful diff.
ocr scan [flags]
ocr s [flags] (alias)
With no --path, the whole repository is scanned.
Flags
| Flag | Short | Default | Description |
|---|---|---|---|
--path <list> |
- | whole repo | Comma-separated repo-relative directories or files to scan (e.g., internal/agent, internal/llm/client.go). |
--exclude <patterns> |
- | - | Comma-separated gitignore-style patterns to skip (e.g., **/generated/*,*.pb.go); merged with rule.json excludes. |
--output <path> |
-o |
stdout | Write scan results to a UTF-8 file (- means stdout). Lazily created on first write so failed runs leave existing files untouched. Text format automatically strips ANSI color codes. |
--preview |
-p |
false |
Enumerate and filter files without calling the LLM. Prints the file list, reviewable/excluded counts, total lines, and per-file exclusion reasons. Honors --format json; --format sarif is not supported. |
ocr scan --preview # see what would be scanned
ocr scan --path internal/agent # scan one directory
ocr scan --path internal/agent,internal/llm/client.go
ocr scan --exclude '**/generated/*,*.pb.go'
See ocr scan -h for the full flag list.
ocr session
Lists and inspects local review session logs saved under
~/.opencodereview/sessions/. Use it to find a session ID, inspect
per-file checkpoint status, and resume interrupted range or commit reviews.
ocr session <sub-command>
ocr sessions <sub-command> (alias)
Sub-commands:
list, ls List recent review sessions for the current repo
show <id> Show one session's metadata and per-file items
comments <id> Show the review comments recorded in one session
ocr session list
ocr session list
ocr session list --limit 50
ocr session list --json
| Flag | Default | Description |
|---|---|---|
--repo <path> |
current dir | Repository whose sessions should be listed. |
--json |
false |
Emit session summaries as JSON. |
--limit <n> |
20 |
Cap the number of listed sessions. Use 0 for unlimited. |
ocr session show
A resumed run also prints the run it continued, and the provider/model transition when the resume crossed one.
ocr session show <session-id>
ocr session show --json <session-id>
ocr session show --repo /path/to/repo <session-id>
| Flag | Default | Description |
|---|---|---|
--repo <path> |
current dir | Repository whose session should be inspected. |
--json |
false |
Emit session metadata and per-file items as JSON. |
ocr session comments
Prints every review comment persisted in a session, rendered in the same
style as ocr review terminal output (path, line range, severity badge,
suggestion diff).
ocr session comments <session-id>
ocr session comments --json <session-id>
ocr session comments --severity high <session-id>
ocr session comments --severity critical,high --category bug,security <session-id>
| Flag | Default | Description |
|---|---|---|
--repo <path> |
current dir | Repository whose session should be inspected. |
--json |
false |
Emit the comments as a JSON array. |
--severity <list> |
all | Comma-separated severities to include (critical, high, medium, low). |
--category <list> |
all | Comma-separated categories to include (e.g. bug, security). |
ocr session compare
Groups the findings of two sessions into four buckets: new (only in the after session), persisting (in both), resolved (only in the before session) and not reviewed (in the before session, in files the after session never looked at, so they are not counted as resolved).
Findings are matched on path, category and the offending snippet, not on line numbers, so a finding that only moved down the file still counts as persisting.
ocr session compare <before-session-id> <after-session-id>
ocr session diff <before-session-id> <after-session-id>
ocr session compare --json <before-session-id> <after-session-id>
Both sessions must belong to the same repository; otherwise the command
fails. Different review modes only print a warning on stderr, so --json
output stays pipeable.
| Flag | Default | Description |
|---|---|---|
--repo <path> |
current dir | Repository whose sessions should be compared. |
--json |
false |
Emit the comparison as JSON (new, persisting, resolved, not_reviewed). |
ocr rules
Rule introspection. There is exactly one subcommand:
ocr rules check [flags] <file-path>
Flags:
--repo <path> Git repository root (default: current dir)
--rule <path> Path to a custom rule JSON file
For the given file path, OCR:
- Walks the four-layer rule chain (custom → project → global → system).
- Picks the first match.
- Prints the source layer, the glob pattern that matched, and the resolved rule text.
$ ocr rules check src/main/java/com/example/Foo.java
File: src/main/java/com/example/Foo.java
Source: System built-in
Pattern: **/*.java
Rule:
────────────────────────────────────────
<contents of internal/config/rules/rule_docs/java.md>
────────────────────────────────────────
Useful for debugging "why isn't my custom rule firing?" — see Review Rules for the full priority story.
ocr config
Persists keys to ~/.opencodereview/config.json and offers interactive
setup TUIs. Four subcommands:
ocr config set <key> <value>
ocr config unset <key> Clear a saved key
ocr config provider Interactive provider setup
ocr config model Interactive model selection
set— write a single config value non-interactively.effortacceptslow/medium/highand sets the default review effort for every run;--effortoverrides it per invocation.unset— clear a saved key.provider,max_tokens,effort,custom_providers.<name>, andmcp_servers.<name>are supported. Clearingeffortrestores the defaultmediumpreset. If a deleted provider was the active one,providerandmodelare cleared (runocr config providerto pick a new one).provider— launch the interactive provider-setup TUI (no extra arguments; useocr config set provider <name>for non-interactive setup).model— launch the interactive model-selection TUI (no extra arguments; useocr config set model <name>for non-interactive setup).
See Configuration for the full key reference, schemas, and examples.
ocr llm
LLM utility commands. Two subcommands:
ocr llm <sub-command>
Sub-commands:
test Send a test conversation to the configured LLM model
providers List all built-in LLM providers
ocr llm test
ocr llm test
Resolves the LLM endpoint exactly the way ocr review does, sends a single
canned chat request from
internal/config/testconnection/task.json,
and prints:
Source: <which strategy was used>
URL: <endpoint URL>
Model: <effective model>
<the model's reply>
✓ Connection test successful
A non-zero exit means either the endpoint isn't fully configured or the request failed (network / auth / model error). The error message tells you which.
ocr llm providers
ocr llm providers
Lists every built-in LLM provider in a three-column table:
Built-in providers:
NAME PROTOCOL BASE URL
---- -------- --------
anthropic anthropic https://api.anthropic.com
…
Followed by a hint to configure one interactively with ocr config provider or non-interactively with ocr config set provider <name>.
ocr viewer
ocr viewer [flags]
Flags:
--addr <address> listen address (default: localhost:5483)
--open <mode> when to open the browser: auto, always, never (default: auto)
Examples:
ocr viewer # start and open the browser
ocr viewer --addr :3000 # bind to all interfaces on port 3000
ocr viewer --open=never # just print the URL
ocr viewer --open=always # force it when auto declines (piped output, WSL)
Starts an embedded HTTP server that reads
~/.opencodereview/sessions/... and renders past review sessions in a
browser-friendly UI. See Session Viewer.
--open=auto skips the browser when stdout is not a terminal, when
SSH_CONNECTION is set with no display forwarded, or when Linux has neither
DISPLAY nor WAYLAND_DISPLAY; the reason is printed alongside the URL. Use
--open=always where auto declines but a browser is in fact reachable.
ocr version
ocr version
ocr --version
ocr -V
Prints the version stamped at build time, the short Git commit (when
present), the platform (<GOOS>/<GOARCH>), the build date (when present),
and the GitHub URL (https://github.com/alibaba/open-code-review).
ocr completion
Generate shell completion scripts for ocr, so command names, flags,
and arguments can be tab-completed in your shell.
Bash
One-shot, current session only:
source <(ocr completion bash)
Persistent (Linux):
ocr completion bash > /etc/bash_completion.d/ocr
Persistent (macOS):
ocr completion bash > $(brew --prefix)/etc/bash_completion.d/ocr
Zsh
If shell completion isn't already enabled in your environment, enable it once:
echo "autoload -U compinit; compinit" >> ~/.zshrc
Then load completions persistently:
ocr completion zsh > "${fpath[1]}/_ocr"
Start a new shell for this to take effect.
Fish
One-shot, current session only:
ocr completion fish | source
Persistent:
ocr completion fish > ~/.config/fish/completions/ocr.fish
PowerShell
One-shot, current session only:
ocr completion powershell | Out-String | Invoke-Expression
Persistent — generate the script once, then source it from your profile:
ocr completion powershell > ocr.ps1
Add a line to your PowerShell profile that dot-sources ocr.ps1.
Tips & gotchas
--audience agentdoes not imply--format json, and--format jsondoes not imply a quiet terminal. They control different things — quiet UI vs structured payload.--format jsonalone keeps progress visible on stderr; add--audience agentwhen you want it gone.--backgroundis one of the highest-leverage flags for review quality — always pass the requirement / PR description when invoking from another agent.- A file whose diff alone exceeds 80 % of
MAX_TOKENS(200000by default) is dropped before the LLM is called. This is logged but does not fail the run. MAX_TOKENScaps the prompt only. The model's output is capped separately byMAX_COMPLETION_TOKENS(16384), so raising--max-tokensfor a large-context model does not inflate output cost.- The plan phase is automatically skipped when changed lines fall below
both
PLAN_MODE_LINE_THRESHOLD(50, applied to the largest single file in the group) andPLAN_MODE_GROUP_LINE_THRESHOLD(100, applied to the combined churn of a group with 2+ files). - Files are bundled into semantic groups by one cheap metadata-only LLM call before review, so related changes (handler + service + test) are reviewed in a single conversation. Grouping failures fall back silently to one-file-per-group.
--effort highis the cheapest quality lever when a review feels shallow;--effort lowroughly halves cost versus the default when you just want a fast sanity pass.
See Also
- QuickStart — install and run your first review.
- Configuration — env vars and config keys behind the flags.
- Review Rules — the
--ruleflag and rule resolution. - Integrations — calling
ocr reviewfrom agents and CI.