codereview-cli
cr is the Open CLI Collective code-review CLI. It runs automated pull-request
reviews, records review state locally, posts review output back to GitHub, and
keeps enough durable metadata to resume, repair, inspect, and prune runs.
Not GitHub Code Review
This project is not affiliated with GitHub and is not a replacement for human
review. It is a CLI for orchestrating LLM-backed review agents against GitHub
pull requests.
Use cr when you want to:
- preview review actions before posting anything;
- run a live PR review with idempotent posting and resume behavior;
- reuse named LLM sessions across related live reviews;
- inspect trusted reviewer agents available to a repository;
- manage local review run data and credentials from the terminal.
Installation
Package-manager installs are available for versions after their
package-channel release jobs publish successfully.
Homebrew
brew install --cask open-cli-collective/tap/codereview-cli
Windows Package Managers
winget install OpenCLICollective.codereview-cli
choco install codereview-cli
Linux Packages
cr release builds include .deb and .rpm packages for the
open-cli-collective/linux-packages
repository.
Binary Download
Download a release archive from the
Releases page.
From Source
go install github.com/open-cli-collective/codereview-cli/cmd/cr@latest
Manual Build
git clone https://github.com/open-cli-collective/codereview-cli.git
cd codereview-cli
make build
Platform Support
cr stores secrets in the OS credential store through the shared
cli-common/credstore library.
| Platform | Default credential backend |
|---|
| macOS | Keychain |
| Windows | Credential Manager |
| Linux | Secret Service |
Supported backend names are keychain, wincred, secret-service, file,
pass, and memory. Backend selection precedence is:
--backend
CODEREVIEW_KEYRING_BACKEND=
keyring.backend in config.yml
- OS default
Secrets are never written to config.yml. Non-secret config lives in the
codereview config directory resolved by the operating system, and durable
review data lives under the OS data directory for the cr binary.
Authentication And Setup
cr v1 supports GitHub personal access token authentication for Git-host
operations. The credential key for GitHub PATs is git_token.
Quick setup with adapter-managed LLM credentials:
cr init --non-interactive \
--git-token-from-env GITHUB_TOKEN
Setup with Pi's local RPC runtime. Install Pi's coding agent and make sure the
pi binary is available on PATH before running cr review. New installs
should use the current npm package (@earendil-works/pi-coding-agent); existing
installs from the previous npm scope can also work if their pi binary supports
the required --mode rpc and --system-prompt flags.
cr init --non-interactive \
--llm-provider pi \
--llm-auth subscription \
--llm-adapter pi_rpc \
--git-token-from-env GITHUB_TOKEN
Setup with Codex CLI subscription auth. Install Codex CLI, log in with your
subscription, and make sure the codex binary is available on PATH before
running cr review. This path is supported for review, but remains
best-effort/beta until Codex exposes an explicit all-tools-disabled flag.
cr init --non-interactive \
--llm-provider openai \
--llm-auth subscription \
--llm-adapter codex_cli \
--git-token-from-env GITHUB_TOKEN
Setup with a direct LLM API key:
cr init --non-interactive \
--llm-auth api_key \
--llm-adapter anthropic_api \
--llm-api-key-from-env ANTHROPIC_API_KEY \
--git-token-from-env GITHUB_TOKEN
Setup a named profile:
cr --profile work init --non-interactive \
--git-token-from-env GITHUB_TOKEN \
--agent-source ~/.config/codereview/agents
Repo-aware profile routing can select a profile from the PR repository when
--profile is omitted. Use this when org, personal, or repo-specific reviewer
credentials should differ without changing commands:
For scripted installs, use cr init --non-interactive for the core profile and
then layer narrow config mutations with the dedicated config commands. A typical
sequence looks like:
cr --profile work init --non-interactive \
--set-default \
--git-host github.com \
--git-auth-mode pat \
--llm-provider anthropic \
--llm-auth subscription \
--llm-adapter claude_cli \
--llm-reviewer-model-tier medium \
--keyring-backend file
cr --profile work config route set \
--host github.com \
--namespace open-cli-collective \
--repo codereview-cli
cr --profile work config agent-source add ~/.config/codereview/agents
cr --profile work config llm models set medium claude-sonnet-4-6
cr config retention set --max-age-days 30 --enforcement manual_only
printf '%s' "$GITHUB_TOKEN" | cr set-credential \
--ref codereview/work \
--key git_token \
--stdin \
--overwrite
Use cr config route for repository routing, cr config agent-source for
trusted source paths, cr config llm models for llm.model_map, and
cr config retention for durable run-data policy. Use cr init --non-interactive --keyring-backend to persist a keyring backend,
--reset-keyring-backend to clear it, --disable-reviewer to remove separate
reviewer credentials, --llm-reviewer-model-tier or
--clear-llm-reviewer-model-tier for the durable reviewer baseline, and
--set-default to make the target profile the default during init. For
backward compatibility, init may still persist a runtime --backend when the
command writes credentials or configures API-key LLM auth, but the explicit
--keyring-backend / --reset-keyring-backend flags are the readable
scripted surface to prefer.
default_profile: personal
repository_profiles:
- profile: personal-reviewer-a
match:
host: github.com
namespace: rianjs
repos: [bar, baz]
- profile: personal-reviewer-b
match:
host: github.com
namespace: rianjs
repos: [qux]
- profile: work
match:
host: github.com
namespace: open-cli-collective
- profile: personal
match:
host: github.com
namespace: rianjs
profiles:
personal: ...
personal-reviewer-a: ...
personal-reviewer-b: ...
work: ...
Route matching is deterministic: host + namespace + repo routes beat
host + namespace routes, omitted repos means all repos in that namespace,
and no match falls back to default_profile. Host matching is case-insensitive
after normalization, while namespace and repo matching are case-sensitive after
trimming whitespace. An explicit --profile bypasses repository routing. Route
targets still use the profile's configured auth mode. Passing --profile ""
also counts as explicit and resolves default_profile without route lookup.
For GitHub App auth, cr review can use the PR owner/repo to look up the app
installation when github_app_installation_id is not staged.
Add or replace one credential later:
printf '%s' "$GITHUB_TOKEN" | cr set-credential \
--ref codereview/default \
--key git_token \
--stdin \
--overwrite
Credential refs use the codereview/ service/profile form. cr
accepts secrets by --stdin or --from-env during setup and credential writes;
it does not read runtime tokens directly from arbitrary environment variables.
Reviewer credentials use a separate credential ref that also stores key
git_token; keep it distinct from the user Git ref.
Org Deployment / MDM
For managed rollouts, ship non-secret config and pre-stage secrets in the
target user's credential store. The staging commands must run as the target OS
user who will run cr, not as root, SYSTEM, or an administrator account whose
keyring is different from the target user's keyring.
reviewer_credentials may use a PAT or GitHub App auth. A shared reviewer PAT
is an access secret even when distributed org-wide. A GitHub App private key is
also a deployment secret; cr signs short-lived JWTs locally, mints
installation tokens as needed, and never stores those minted tokens in
config.yml. Pre-stage reviewer credentials into each target user's credential
store, rotate or revoke them with the same set-credential --overwrite flow,
and do not store them in config files, agent sources, installers, logs, or
shell profiles.
For GitHub App reviewer credentials, grant the app only the repository
permissions needed by the enabled review workflow:
| GitHub App permission | Access | Used for |
|---|
| Metadata | Read | Required by GitHub for repository access and installation lookup. |
| Contents | Read | Reading diffs, files, and tree entries during review. |
| Pull requests | Read and write | Reading PR metadata/reviews/threads and posting PR reviews or inline comments. |
| Issues | Read and write | Reading and posting issue comments on PR conversations. |
Thread resolution uses the pull request review-thread GraphQL surface, so keep
Pull requests write access when review_policy.resolve_threads is enabled.
Either omit keyring.backend to use the platform default, or set it
per-platform and run set-credential with the same backend selection.
Example non-secret config template:
default_profile: work
profiles:
work:
git:
host: github.com
auth_mode: pat
credential_ref: codereview/work
reviewer_credentials:
auth_mode: github_app
credential_ref: codereview/work-reviewer-app
llm:
provider: anthropic
auth: api_key
adapter: anthropic_api
credential_ref: codereview/work-llm
model_map:
medium: claude-sonnet-4-6
agent_sources:
- ~/.config/codereview/agents
review_policy:
major_event: comment
For adapter-managed LLM credentials, use auth: subscription and omit
llm.credential_ref. Codex-backed profiles must set provider: openai,
auth: subscription, and adapter: codex_cli together. Pi-backed profiles
must set provider: pi, auth: subscription, and adapter: pi_rpc together:
llm:
provider: openai
auth: subscription
adapter: codex_cli
llm:
provider: pi
auth: subscription
adapter: pi_rpc
Agent definitions are non-secret deployment material, not credentials. Ship
them separately from keyring pre-staging and point agent_sources at the
managed directory. Recommended managed paths:
| Platform | Example managed agent source |
|---|
| macOS | /Library/Application Support/codereview/agents |
| Windows | C:\ProgramData\codereview\agents |
| Linux | /etc/codereview/agents |
Use the standard agent layout under that directory:
agents/
security/
index.yaml
secrets/
index.yaml
prompt.md
Agent index.yaml files must declare exactly one model selector and an
explicit effort:
name: secrets
description: Reviews credential and secret-handling changes.
model_tier: medium
effort: medium
file_globs:
- "**/*.go"
applies_when:
- Go files changed
needs_full_file_content: false
Use model_tier: small|medium|large for portable shared catalogs. It means the
minimum acceptable reviewer tier for that agent, not a direct model pick. Use
model_id: only when an agent intentionally requires one
provider-specific model. effort is independent and must be one of
low, medium, or high.
applies_when is the selector's routing contract. Keep it focused on when the
agent should be chosen for a change. Reviewer execution instructions belong in
prompt.md and are not sent to the selector.
Legacy agent files that use model: sonnet or another provider-specific
model value must be updated. Replace portable intent with model_tier
and move provider-specific defaults into profile llm.model_map; use
model_id only for intentionally non-portable agents.
cr config show --json reports each configured source by path, presence,
status, canonical path, warnings, and SHA-256 fingerprint prefix without
inlining index.yaml or prompt.md. Missing or unreadable sources are shown as
deployment status in config show; commands that actually load agents, such as
cr agents and cr review, fail fast until the source is fixed.
Avoid profile sources under temp directories, relative paths, or Git worktrees.
Those locations are warned because they are easy for local scripts or PR authors
to mutate. Symlinked sources are accepted, but cr records the canonical path
and fingerprints the resolved files.
When deploying a profile without the interactive wizard, run
cr init --non-interactive first to write the core non-secret profile shape,
then use set-credential only for secrets that you are intentionally staging
outside init. Example:
github_app_installation_id is optional for cr review, which can discover
the installation from the PR repository. Stage it when you want cr me and
other commands without repository context to work.
cr --profile work init --non-interactive \
--git-host github.com \
--git-credential-ref codereview/work \
--reviewer-auth-mode github_app \
--reviewer-credential-ref codereview/work-reviewer-app \
--llm-provider anthropic \
--llm-auth api_key \
--llm-adapter anthropic_api \
--llm-credential-ref codereview/work-llm
printf '%s' "$USER_GITHUB_TOKEN" | cr set-credential \
--ref codereview/work \
--key git_token \
--stdin \
--overwrite
printf '%s' "$GITHUB_APP_ID" | cr set-credential \
--ref codereview/work-reviewer-app \
--key github_app_id \
--stdin \
--overwrite
printf '%s' "$GITHUB_APP_PRIVATE_KEY" | cr set-credential \
--ref codereview/work-reviewer-app \
--key github_app_private_key \
--stdin \
--overwrite
# Optional: needed for cr me and other commands without repository context.
printf '%s' "$GITHUB_APP_INSTALLATION_ID" | cr set-credential \
--ref codereview/work-reviewer-app \
--key github_app_installation_id \
--stdin \
--overwrite
printf '%s' "$ANTHROPIC_API_KEY" | cr set-credential \
--ref codereview/work-llm \
--key anthropic_api_key \
--stdin \
--overwrite
Then apply any config that intentionally lives outside init flags:
cr --profile work config route set \
--host github.com \
--namespace open-cli-collective \
--repo codereview-cli
cr --profile work config agent-source add ~/.config/codereview/agents
cr --profile work config llm models set medium claude-sonnet-4-6
cr config retention set --max-age-days 30 --enforcement manual_only
Then verify the deployed profile:
cr config show --json
cr me --all --json
Use set-credential only for deferred or multi-key credential bundles that are
clearer to manage outside init.
Environment variables in the examples above are setup ingress only. Runtime
commands resolve service credentials from config.yml and the configured
credential backend.
Configuration
Run cr config show to inspect the active profile and credential status.
default_profile: default
keyring:
backend: keychain
profiles:
default:
git:
host: github.com
auth_mode: pat
credential_ref: codereview/default
llm:
provider: anthropic
auth: subscription
adapter: claude_cli
reviewer_model_tier: small
agent_sources:
- ~/.config/codereview/agents
review_policy:
major_event: comment
allow_self_approve: false
resolve_threads: auto
resolve_after: 24h
data:
retention:
max_age_days: 90
enforcement: at_write
Supported values:
| Field | Values |
|---|
git.auth_mode | pat and github_app are implemented for GitHub. oauth_device is reserved; config recognizes the mode but validation rejects it in v1. |
llm.provider | anthropic, openai, pi |
llm.auth | subscription, api_key |
llm.adapter | claude_cli, anthropic_api, openai_api, pi_rpc, and codex_cli are usable for review. codex_cli requires provider: openai and auth: subscription, and is currently best-effort/beta because Codex does not yet expose an explicit all-tools-disabled flag. |
llm.model_map keys | small, medium, large |
llm.reviewer_model_tier | small, medium, large |
review_policy.major_event | comment, request_changes |
review_policy.resolve_threads | auto, never |
data.retention.enforcement | at_write applies review-time pruning before each cr review; manual_only disables review-time pruning and leaves cr data prune as the explicit maintenance path. |
subscription LLM auth means the adapter owns its own credentials, such as a
logged-in CLI or local runtime. api_key LLM auth requires
llm.credential_ref and stores a provider-specific API key in the credential
backend.
Reviewer agents use provider-neutral model_tier values as minimum floors. At
runtime, cr combines the profile's llm.reviewer_model_tier baseline with
the agent floor and resolves the higher tier through the active profile's
llm.model_map plus provider+adapter built-ins. User llm.model_map entries
override built-ins, and model IDs are opaque strings so future provider models
can be configured without a CLI update.
Effective reviewer tier is:
max(llm.reviewer_model_tier, agent.model_tier)
When llm.reviewer_model_tier is omitted, cr defaults it to small.
model_id stays an exact provider-specific selection and does not participate
in the tier-floor calculation.
Migration note: older releases treated reviewer model_tier as a direct map
lookup. Current releases treat it as a minimum acceptable tier, so profiles can
raise the reviewer baseline without editing shared agent catalogs.
Dry-run and no-post runs also record selected reviewer runtime resolution in
agent-sources.json for auditability. Each selected agent may include
reviewer_runtime with:
| Field | Meaning |
|---|
mode | tier_floor for portable tier resolution, exact_model for agent model_id passthrough |
floor_tier | Declared agent model_tier floor when mode=tier_floor |
baseline_tier | Effective operator baseline tier used for this run |
effective_tier | Higher of baseline and agent floor |
resolved_model | Resolved provider model, from the active model map for tier_floor or from agent model_id for exact_model |
model_map_source | built_in or config for the resolved tier mapping |
Built-in model maps:
| Provider | Adapter | small | medium | large |
|---|
openai | codex_cli | gpt-5.4-mini | gpt-5.4 | gpt-5.5 |
openai | openai_api | gpt-5.4-mini | gpt-5.4 | gpt-5.5 |
anthropic | claude_cli | unset | claude-sonnet-4-6 | claude-opus-4-8 |
anthropic | anthropic_api | unset | unset | unset |
pi | pi_rpc | unset | unset | unset |
anthropic_api, pi_rpc, and claude_cli small-tier usage require explicit
llm.model_map entries.
For Anthropic subscription profiles, adapter: claude_cli runs Claude Code
background jobs, writes the full review task to cr-prompt.txt in an
adapter-owned scratch directory, and starts claude --bg with a compact
positional prompt that allows only Read,Write. The adapter reads the review
result from cr-result.json in that scratch directory and records the Claude
provider session returned by the job state. Background jobs run from a stable
cache workdir so Claude Code can resolve resumed sessions consistently; set
CR_CLAUDE_BG_WORK_DIR to override that workdir.
For OpenAI subscription profiles, adapter: codex_cli runs codex exec in an
adapter-owned scratch directory with --json, --ephemeral,
--skip-git-repo-check, --ignore-user-config, --ignore-rules, a read-only
sandbox, and a scratch --cd. The adapter rejects unsafe flags and fails the
review if Codex emits tool-use events. This remains best-effort/beta because
Codex CLI does not yet expose a first-class all-tools-disabled flag.
Credential key matrix:
| Profile field | Purpose | Auth/provider | Required keys | Optional keys | v1 behavior |
|---|
git.credential_ref | User Git host auth | pat | git_token | None | Supported |
reviewer_credentials.credential_ref | Reviewer Git host auth | pat | git_token | None | Supported; must use a distinct ref from git.credential_ref in the same profile |
git.credential_ref / reviewer_credentials.credential_ref | Git host auth | github_app | github_app_id, github_app_private_key | github_app_installation_id | Supported for GitHub. cr review can discover the installation from the PR repository when the optional installation ID is omitted; commands without repository context require it |
git.credential_ref / reviewer_credentials.credential_ref | Git host auth | oauth_device | None | None | Reserved; config recognizes the mode but v1 rejects it and does not accept future keys such as git_oauth_access_token or git_oauth_refresh_token |
llm.credential_ref | Anthropic direct API auth | api_key + anthropic | anthropic_api_key | None | Supported |
llm.credential_ref | OpenAI direct API auth | api_key + openai | openai_api_key | None | Supported |
Omitted llm.credential_ref | Adapter-managed LLM auth | subscription + anthropic/openai/pi | None | None | Supported; credentials are owned by the selected adapter. openai + codex_cli is best-effort/beta until Codex exposes an explicit all-tools-disabled flag |
llm.credential_ref |
Upgrade note: pre-matrix versions used the generic llm_api_key key for direct
LLM API credentials. Re-provision API-key LLM refs with anthropic_api_key or
openai_api_key; llm_api_key is not accepted by v1 set-credential.
Common Workflows
Preview a review without posting:
cr review --dry-run https://github.com/OWNER/REPO/pull/123
Run a live review:
cr review https://github.com/OWNER/REPO/pull/123
Run a live review and fail the command when a major or blocking finding exists:
cr review --fail-on major https://github.com/OWNER/REPO/pull/123
Force a fresh live review instead of using existing approval, override,
resume, or marker gates:
cr review --rerun https://github.com/OWNER/REPO/pull/123
Retry missing or failed required posts without rerunning the LLM review:
cr review --retry-posts https://github.com/OWNER/REPO/pull/123
Approve after a prior agentic pass when the PR author explicitly asks to skip a
low-value rerun:
# Comment on the PR after the latest codereview marker, for example:
# "These findings are low-value; please approve the pull request."
cr review https://github.com/OWNER/REPO/pull/123
Reuse a named LLM session for a series of related live reviews:
cr review --session release-train https://github.com/OWNER/REPO/pull/123
cr sessions show release-train
Inspect trusted agents for a PR:
cr agents list https://github.com/OWNER/REPO/pull/123
cr agents show harness:reviewer https://github.com/OWNER/REPO/pull/123
Inspect and clean local data:
cr data show
cr data prune --dry-run
cr data prune --keep-last 10
cr data purge --dry-run
Validate and run a benchmark suite:
cr benchmark validate .codereview/benchmarks/reviewer.yml
cr benchmark doctor .codereview/benchmarks/reviewer.yml --json
cr benchmark select .codereview/benchmarks/reviewer.yml \
--candidate claude-sonnet-medium \
--case merged-security-pr
cr benchmark run .codereview/benchmarks/reviewer.yml \
--candidate claude-sonnet-medium \
--case merged-security-pr
See BENCHMARKING.md for suite schema, terminology, artifact
layout, privacy guidance, and metric caveats.
Command Reference
All commands accept the global flags:
| Flag | Semantics |
|---|
--profile | Select a configured profile and bypass repo-aware routing. When omitted, PR-aware commands may use repository_profiles, then fall back to default_profile; during init, empty means default. |
--backend | Select the credential backend for this invocation. One of keychain, wincred, secret-service, file, pass, memory. |
cr
cr [flags]
cr [command]
With no subcommand, cr prints help. cr --version prints the same version
line as cr version. Unknown commands and malformed flags return usage errors.
cr version
cr version
Prints the build version as cr . It takes no arguments.
cr init
cr init [flags]
Creates or updates non-secret config. In v1, --non-interactive is required.
If the selected profile already exists, pass --replace-profile to replace the
profile config.
Flags:
| Flag | Semantics |
|---|
--non-interactive | Required in v1. Run without prompts. |
--git-host | Git host, default github.com. The PR host must match this value. |
--git-credential-ref | Credential ref for Git auth. Defaults to codereview/. |
--git-token-stdin | Read the Git token from stdin and write key git_token. |
--git-token-from-env | Read the Git token from an environment variable and write key git_token. |
--reviewer-credential-ref | Credential ref for reviewer Git auth. Defaults to codereview/-reviewer when reviewer credentials are requested. |
--reviewer-auth-mode | Reviewer Git auth mode, default pat. github_app writes config and prints follow-up credential commands. |
--reviewer-token-stdin | Read the reviewer Git token from stdin and write key git_token; PAT reviewer auth only. |
--reviewer-token-from-env | Read the reviewer Git token from an environment variable and write key git_token; PAT reviewer auth only. |
--llm-provider | LLM provider, default anthropic; also selects whether API-key ingress writes anthropic_api_key or openai_api_key. pi is adapter-managed and does not accept API-key ingress. |
--llm-auth | LLM auth mode, default subscription. Use api_key for keyring-managed direct API keys. |
--llm-adapter | LLM adapter, default claude_cli. |
--llm-credential-ref | Credential ref for LLM API-key auth. Defaults to codereview/-llm when --llm-auth api_key. |
--llm-api-key-stdin | Read the LLM API key from stdin and write anthropic_api_key or openai_api_key according to --llm-provider. |
Only one stdin secret ingress flag may be used at a time. PAT reviewer
credentials use key git_token under their own credential ref, so
--reviewer-credential-ref must differ from --git-credential-ref. GitHub App
reviewer credentials use github_app_id and github_app_private_key, plus
optional github_app_installation_id; init does not accept reviewer token
ingress for --reviewer-auth-mode github_app. LLM API-key ingress requires
--llm-auth api_key. --overwrite with API-key auth requires an LLM key
ingress flag. --allow-self-review is intentionally runtime-only on
cr review; init only stores the profile-level self-approval policy.
cr set-credential
cr set-credential --ref --key (--stdin | --from-env ) [flags]
Writes one secret value to the credential store. Globally allowed keys are
git_token, github_app_id, github_app_private_key,
github_app_installation_id, anthropic_api_key, and openai_api_key. When
config.yml declares the target ref, set-credential narrows that global
allowlist to the exact key set expected for that ref. PAT user Git refs and PAT
reviewer refs use git_token; GitHub App refs use github_app_id,
github_app_private_key, and optional github_app_installation_id; Anthropic
LLM API-key refs use anthropic_api_key; OpenAI LLM API-key refs use
openai_api_key.
Flags:
| Flag | Semantics |
|---|
--ref | Required credential ref, such as codereview/default. |
--key | Required key name. Git refs accept the keys described in the credential key matrix; LLM API-key refs accept anthropic_api_key or openai_api_key. |
--stdin | Read the secret from stdin. |
--from-env | Read the secret from an environment variable. |
--overwrite | Replace an existing key. Without it, existing keys are not overwritten. |
--json | Emit a JSON result. |
Exactly one of --stdin or --from-env is required.
cr config show
cr config show [--json]
Shows the resolved active profile, selected credential backend and source,
credential refs, non-secret profile config, review policy, and data retention.
For each declared credential ref, it reports whether expected keys are present
and labels optional keys as optional.
For each configured agent source, it reports deployment-material status,
canonical path, warnings, and SHA-256 fingerprint prefix without inlining agent
definition contents.
--json emits the same information as structured JSON.
cr config route
cr config route list [--json]
cr config route set --host --namespace [--repo ...]
cr config route unset --host --namespace [--repo ...]
Inspects and updates repository_profiles routing rules. set and unset
apply to the active profile when --profile is supplied; omit --repo to make
the route namespace-wide, or repeat --repo for repo-specific routes.
Use this command for scripted route parity instead of trying to encode routing
inside cr init --non-interactive.
cr config agent-source
cr config agent-source list [--json]
cr config agent-source add
cr config agent-source remove
Inspects and updates the active profile's agent_sources. add normalizes the
path, skips duplicates, and preserves unrelated sources. remove removes only
matching normalized paths from the active profile.
cr config retention
cr config retention get [--json]
cr config retention set [--max-age-days ] [--enforcement ]
cr config retention reset
Inspects and updates global data.retention. set accepts a non-negative
--max-age-days value where 0 means keep forever, and an --enforcement
value of at_write or manual_only. reset restores the default 90 day
at_write policy.
cr config llm models
cr config llm models list [--json]
cr config llm models resolve [--json]
cr config llm models set
cr config llm models unset
cr config llm models reset [--provider ]
Inspects and updates the active profile's llm.model_map. list shows the
effective small/medium/large map, including whether each value came from
profile config, built-in defaults, or is unset. resolve prints the concrete
provider model ID for one tier under the active profile.
set, unset, and reset mutate only the active profile. reset clears the
configured map so built-ins apply again; --provider is a safety guard and
must match the active profile provider.
cr config clear
cr config clear [--all] [--dry-run] [--json]
Deletes stored credentials declared by the active profile.
Flags:
| Flag | Semantics |
|---|
--all | Also remove the active profile from config.yml and clear the disposable cache root. Inactive profiles and durable data are not touched. |
--dry-run | Report the credential refs, config profile reset, and cache cleanup that would happen without deleting credentials, config, cache, or data. |
--json | Emit a JSON result. |
Without --all, this removes secret keyring entries only and leaves
config.yml intact. With --all, --profile selects the profile to
reset; otherwise the default profile is reset. If other profiles remain after a
profile reset, the default profile is updated deterministically to the first
remaining profile name when needed. If the last profile is reset, config.yml
is removed.
config clear never touches durable review data. Use cr data purge for the
data pillar.
cr me
cr me [--all] [--json]
Resolves the active git-host identity using configured posting credentials and
caches the identity in config. With --all, refreshes every configured profile
and verifies both user Git and reviewer identity credentials when a profile
declares both. --json emits structured output. --all cannot be combined
with --profile.
cr agents list
cr agents list [PR] [--agents-dir ...] [--json]
Lists trusted review agents. If a PR URL is supplied, repo-local agents are
loaded from the PR base branch under .codereview/agents, not from the PR head.
This keeps unreviewed agent changes from affecting their own review.
Filesystem profile and flag sources include structured provenance with
configured path, canonical path, warnings, and SHA-256 fingerprint prefix so an
operator can verify which org-shipped agent version was used.
Agent source precedence is profile sources, repo-local base-branch agents, then
--agents-dir sources. Later sources override earlier agents with the same ID.
Flags:
| Flag | Semantics |
|---|
--agents-dir | Additional trusted agents directory. Repeatable. |
--json | Emit JSON. |
cr agents show
cr agents show [PR] [--agents-dir ...] [--json]
Shows one agent, including category metadata, model_tier or model_id,
effort, file globs, applies_when, needs_full_file_content, prompt,
provenance, and trust note when repo-local agents are considered.
cr review
cr review [flags]
Runs the automated review pipeline for a GitHub pull request URL. The PR host
must match the active profile's git.host.
Modes:
| Flag | Semantics |
|---|
--dry-run | Plan review actions, write local artifacts, and print the plan without posting. |
--no-post | Alias for --dry-run. |
--rerun | Bypass existing approval, approval-override, resume, and marker gates and start a fresh live review. Mutually exclusive with --retry-posts. |
--retry-posts | Retry missing or failed required posts for an existing run without rerunning LLM planning or checking approval overrides. Mutually exclusive with --rerun and incompatible with --session. |
Review selection and execution flags:
| Flag | Semantics |
|---|
--agents-dir | Additional trusted agents directory. Repeatable. |
--max-agents | Limit selected reviewer agents. Omit the flag or pass 0 for the default limit of 5. Negative values are rejected. |
--max-concurrency | Limit concurrent reviewer agents. Omit the flag or pass 0 for the default limit of 5. Negative values are rejected. |
--selection-model | Exact provider model ID passthrough for the selection stage only. Bypasses the default medium-tier selection model resolution. Requires --dry-run or --no-post. |
--selection-effort | Override selection-stage effort only with low, medium, or high. Requires --dry-run or --no-post. |
--selection-prompt | Load selection-stage instruction text from a file while preserving the structured JSON selection protocol. Requires --dry-run or --no-post. |
--reviewer-model | Exact provider model ID passthrough for reviewer stages only. Bypasses reviewer agent model_tier, model_id, and profile model-map resolution. Requires --dry-run or --no-post. |
--reviewer-model-tier | Override the reviewer baseline tier only with small, medium, or large. This still respects higher agent model_tier floors. Requires --dry-run or --no-post. |
--reviewer-effort | Override reviewer-stage effort only with low, medium, or high. Requires --dry-run or --no-post. |
--review-base-sha | Review this base commit SHA instead of the PR's current base SHA. Requires --review-head-sha and --dry-run or --no-post. |
--review-head-sha | Review this head commit SHA instead of the PR's current head SHA. Requires and or . |
Policy and output flags:
| Flag | Semantics |
|---|
--fail-on | Exit 1 if any finding is at or above blocking, major, minor, or nits. |
--allow-self-review | Allow reviewer credentials that resolve to the PR author. |
--allow-self-approve | Allow approval when the posting identity is the PR author. |
--no-resolve-threads | Do not plan thread-resolution actions. Also implied by profile resolve_threads: never. |
--json | Emit JSON. |
Live review uses a gate before planning or posting. If the posting identity has
already approved the PR, cr review exits immediately in Go code before any
LLM classifier or reviewer loop runs; this is true even if newer commits made
the approval stale. Use --rerun to force a fresh review anyway.
If there is no existing approval, cr review looks for an explicit PR-author
approval override request newer than the latest codereview marker from the
posting identity. This check only runs after at least one prior codereview marker
exists. Candidate comments are filtered in Go to PR-author issue comments,
review bodies, and inline-thread comments newer than that marker; a small-tier
LLM classifier only decides whether those comments ask for approval override. A
positive classification skips the reviewer loop and posts an approving review
through the normal ledger/outbox path. Only ordering relative to the latest
codereview marker is enforced; the tool intentionally does not require the
request to be newer than a later head update.
If matching complete markers already exist for the current
head/base/profile/posting identity, cr review exits early. If a prior
compatible partial run exists, it resumes or repairs posting from durable local
state. If the PR base moved, live review aborts with an upstream exit. --rerun
starts fresh and bypasses the approval/override fast paths. --retry-posts
replays required posts that are missing or failed without rerunning the LLM
review or checking approval overrides.
Dry-run output contains planned actions and artifact paths. Dry-run action
markers are reported as omitted because nothing is posted.
Live text output includes run ID, gate status, decision, outcome, PR, artifacts,
and post counts. JSON output includes run, status, decision, message,
outbox, artifacts, and fail_on_triggered.
cr benchmark
cr benchmark
Validates, inspects, runs, and compares benchmark suites. See
BENCHMARKING.md for the full benchmark guide.
cr benchmark validate
cr benchmark validate
Validates benchmark suite schema and configured profile compatibility without
running reviews. For the current full-pipeline commands, this includes
stage-recipe validation and selection prompt file readiness checks.
cr benchmark doctor
cr benchmark doctor [--candidate ...] [--case ...] [--results-dir ] [--cr-bin ] [--json]
Inspects benchmark readiness without running reviews. It reports the selected
candidates and cases, resolved results directory, selected cr binary, profile
availability, selection/reviewer/synthesis stage recipes, reviewer agent
directories, and warnings.
cr benchmark run
cr benchmark run [--candidate ...] [--case ...] [--results-dir ] [--cr-bin ] [--json]
Runs the selected candidate x case matrix by invoking cr review --dry-run --json for each run. It always uses dry-run review mode, captures stdout and
stderr separately, records each child exit code, and writes generated artifacts
under .cr-bench/results/// unless --results-dir is set.
Use --candidate and --case for benchmark selection. Candidate YAML fields
such as stages.selection, stages.reviewers, max_agents, and
max_concurrency control review runtime overrides. stages.selection.model
and stages.selection.effort map to --selection-model and
--selection-effort; optional stages.selection.prompt maps to
--selection-prompt. stages.reviewers.model remains the exact-model bypass,
while stages.reviewers.model_tier maps to --reviewer-model-tier.
stages.reviewers.effort and stages.reviewers.agent_dirs[] map to
--reviewer-effort and repeated --agents-dir flags. Case YAML fields
review_base_sha and review_head_sha pin the exact base/head commit pair
reviewed by the dry-run child command. Optional stages.synthesis metadata is
reserved for future benchmark support and does not change benchmark run
execution yet.
cr benchmark select
cr benchmark select [--candidate ...] [--case ...] [--results-dir ] [--json]
Runs the selected candidate x case matrix through the extracted in-process
selection phase only. It reuses the same profile, provider, adapter, and agent
catalog loading semantics as cr review, but stops after selector execution.
It does not spawn a child cr review, does not run reviewer agents, and does
not run synthesis.
Candidate stages.selection.model and stages.selection.effort map to
selection overrides directly. Optional stages.selection.prompt is loaded from
disk into selection instructions, and optional
stages.reviewers.agent_dirs[] are passed into the selector catalog so
candidate reviewer packs still influence routing. Case YAML
review_base_sha and review_head_sha still pin the exact base/head commit
pair used to build the selector diff view.
Optional stages.synthesis metadata is preserved in summaries and selector
recipe.json artifacts, but selector-only benchmarking still stops after
selection. Dedicated synthesis benchmarking is future work.
Selector benchmarks write selector-specific per-run artifacts such as
selection.json, recipe.json, metrics.json, and selection log metadata.
When one selector run fails after partial execution, benchmark select records
that run as failed and continues the remaining matrix when it can still write
trustworthy suite artifacts.
cr benchmark compare
cr benchmark compare [--json]
Reads an existing benchmark results directory and writes deterministic
comparison.json and comparison.md artifacts. Comparison is local-only: it
does not invoke models, read live PR state, mutate Git provider state, or
require provider credentials. cr benchmark run and cr benchmark select
write the same comparison artifacts automatically.
cr sessions list
cr sessions list [--json]
Lists named LLM sessions in name order. Text output shows name, profile,
provider, adapter, model, host, and last-used time. JSON output includes the
provider session ID plus created and last-used timestamps.
cr sessions show
cr sessions show [--json]
Shows one named LLM session. Missing sessions return an error. Text output
includes the provider session ID.
cr sessions delete
cr sessions delete [--json]
Deletes one named LLM session row. It does not delete provider-side session
state. Missing sessions return an error.
cr data show
cr data show [--json]
Shows local durable data usage: data root, ledger path, runs root, run counts,
live/dry-run counts, outcome counts in JSON, oldest/newest run timestamps,
artifact bytes, and orphan artifact counts/bytes.
cr data prune
cr data prune [--older-than | --keep-last ] [--dry-run] [--json]
Prunes selected ledger runs and their artifacts, then removes orphan artifact
directories. The default with no selector applies built-in manual retention:
live runs older than 90 days and dry-run runs older than 7 days. This manual
default is independent from data.retention.* review-time pruning config.
Flags:
| Flag | Semantics |
|---|
--older-than | Prune runs older than the given positive duration. Mutually exclusive with --keep-last. |
--keep-last | Keep the newest non-negative n runs per post mode and prune the rest. Mutually exclusive with --older-than. |
--dry-run | Report selected runs and orphans without deleting. |
--json | Emit JSON including selected/deleted runs, orphan removals, and warnings. |
Prune deletes the ledger row first, then removes artifact directories best
effort. Unsafe artifact paths and remove failures are reported as warnings after
the ledger row is deleted.
cr data purge
cr data purge --yes [--json]
cr data purge --dry-run [--json]
Purges the whole local data root. --yes is required unless --dry-run is set.
Purge does not open the ledger database, so it can remove a corrupt local data
root. --json emits the data root, dry-run status, and removed status.
Flags:
| Flag | Semantics |
|---|
--yes | Confirm permanent deletion. Required unless --dry-run is set. |
--dry-run | Report the data root without deleting. |
--json | Emit JSON. |
Operational Semantics
Local State
cr keeps non-secret config in the OS config directory for service
codereview. Durable review data lives under the OS data directory for
the cr binary and includes:
ledger.db: runs, sessions, findings, planned actions, and named sessions;
runs/...: per-run artifacts such as diff.patch, findings.json,
rollup.md, diff slices, and agent JSONL logs;
locks/...: live-review advisory locks.
The HTTP cache is under the OS cache directory for the cr binary.
Releases before this state-layout alignment wrote data/cache below a nested
codereview child inside the cr root. Commands that write review state
migrate those legacy entries into the cr root without changing config or
credential refs.
Posting, Markers, And Idempotency
Live posting records hidden codereview markers on comments/reviews created by
the posting identity. Markers let later invocations classify the PR as complete,
partial, stale-base, or fresh for the current head/base context. The outbox
reconciles markers only from the posting identity, so unrelated comments from
other users do not satisfy cr's idempotency checks.
Planned actions can include inline comments, file-level or rollup comments,
review submission, thread summary replies, and thread resolution. Thread
summary content uses separate summary markers. Model-generated marker-looking
text is escaped before posting.
Session Reuse
--session stores and reuses the provider session for live orchestrator
turns. A named session is scoped by name, profile, provider, adapter, model, and
host. Profile/provider/adapter/model mismatches are errors. Host mismatches warn
and continue. If the active adapter does not support resume, cr starts fresh
and records the new provider session when available. claude_cli supports
resume by launching a new Claude Code background job with the stored provider
session.
Retention
cr review applies retention before fetching the PR or allocating the next run
when data.retention.enforcement is at_write. data.retention.max_age_days
controls live-run retention and defaults to 90 days. A value of 0 keeps live
runs forever. Dry-run runs remain throwaway data and use a fixed 7-day
review-time retention cap.
Set data.retention.enforcement: manual_only to disable review-time pruning for
both live and dry-run invocations. The explicit cr data prune --dry-run
command remains the safe preview path for manual maintenance, and no-selector
cr data prune uses its built-in live 90-day and dry-run 7-day windows
independent from profile config.
Development
make tidy
make lint
make test
make build
make snapshot
make check
The main binary lives in cmd/cr. Command wiring is in internal/cmd, provider
boundaries are under internal/gitprovider, and review orchestration is split
between internal/pipeline, internal/reviewrun, internal/reviewplan, and
internal/outbox.
See docs/development.md for local development notes.