This guide walks through installing, authenticating, and using the Compair CLI.
Repository note: the binary and product name are compair / "Compair CLI". In this workspace, the repository directory is compair-cli.
Looking for the fastest first run? Start with compair demo --offline to see the output shape without Docker, a model key, or a Cloud account. Use this guide when you want the full command reference and workflow details.
| Platform | Recommended command | Notes |
|---|---|---|
| macOS | brew tap RocketResearch-Inc/tapbrew install --cask compair |
Fastest macOS path today. |
| Debian / Ubuntu | curl -fsSL https://rocketresearch-inc.github.io/compair-packages/install/debian.sh | bash |
Installs from the Compair APT repo. |
| Fedora / RHEL | curl -fsSL https://rocketresearch-inc.github.io/compair-packages/install/compair.repo | sudo tee /etc/yum.repos.d/compair.repo >/dev/nullsudo dnf install -y compair |
Omit sudo if you are already root. |
| Windows | Download the latest zip from GitHub Releases, unzip it, then run .\compair.exe version. |
WinGet is pending upstream approval. |
| Any | go build -o compair .mv compair /usr/local/bin/ |
Best for contributors and local hacking. |
Release archives are published for macOS, Linux, and Windows on the GitHub Releases page.
If you want the fastest end-to-end check, run:
compair demo --offlineThat creates the disposable demo repos, seeds the same client/API drift as the live demo, and renders a prebaked report. It does not start Docker, call OpenAI, or require a Compair Cloud account.
When you want Compair to run a real review, use:
compair demo --mode local
compair demo --mode cloudOn an interactive terminal, Compair will ask whether to run:
- an offline sample with a prebaked report
- a local Core demo using the managed Docker runtime
- or a Cloud demo against the current hosted API/profile
The live demo creates a disposable workspace with two small repos, tracks them in a dedicated demo group, and runs a real Compair review.
If you want the recommended multi-repo product workflow instead of the disposable demo, follow cross_repo_workflow.md.
Compair CLI is ready for early developer testing.
Feedback is especially useful from developers maintaining:
- backend + frontend repos
- API + SDK repos
- CLI + cloud service repos
- docs + implementation repos
- multi-repo internal tools
Please open an issue with what worked, what broke, and where the output was confusing. If you can include your repo shape, operating system, install path, and whether you tested --offline, local Core, or Cloud, that makes the feedback much easier to act on.
Use this mental model to stay out of the weeds:
compair review: the normal interactive command for reviewing the repo you changedcompair review --detach: submit the review work now and come back latercompair review --pairwise: slower advanced review that runs one pass per target/peer repo paircompair wait: reattach to saved pending repo tasks and fetch the finished reportcompair wait --timeout 20m: keep waiting longer when a large baseline needs more timecompair push/compair pull: lower-level async split when you want upload and fetch as separate stepscompair sync: advanced/CI command surface for JSON output, gates, automation, and power-user control
If you are not sure which command to use, start with compair review.
The CLI uses --api-base or COMPAIR_API_BASE:
export COMPAIR_API_BASE="https://app.compair.sh/api"Create an account if needed:
compair signup --email you@example.com --name "Your Name" --referral ABC123Creates a new account by calling /sign-up. The password prompt hides your input, and --referral is optional.
Interactive login chooses the best method for the target server:
compair loginBehavior by server capabilities:
- Cloud with Google enabled: offers browser-based sign-in and waits for completion
- Password-based auth: prompts for email/password unless you pass them explicitly
- Single-user Core: auto-establishes a local session
Force browser-based sign-in explicitly:
compair login browserUse email/password directly:
compair login --email you@example.com --password 'your-password'Successful login stores a token at ~/.compair/credentials.json and sends it in the Authorization: Bearer header (and auth-token for compatibility).
If you already have a valid token from web/device auth (or CI secret storage), you can save it directly:
compair login --token "$COMPAIR_AUTH_TOKEN" --user-id "<optional-user-id>" --username "<optional-username>"If the server advertises single-user mode (auth.required=false), compair login skips credential prompts, establishes a session automatically, and lets you work without creating an account.
Profiles let you switch between Compair Cloud and self-hosted Core overlays without rebuilding the CLI.
compair profile ls
compair profile set staging --api-base https://staging.compair.local/api
compair profile use cloudCloud setup is:
compair profile use cloud
compair signup --email you@example.com --name "Your Name"
compair loginSkip compair signup if you already have an account.
Resolution order for the API base: --api-base flag → COMPAIR_API_BASE → selected profile (or COMPAIR_PROFILE) → default profile (cloud). Switching profiles clears cached capability info so commands adapt immediately.
When you use the managed local Core runtime, compair core up automatically rewrites the local profile to match the configured localhost port.
compair status # current auth, active group, repo binding, and snapshot defaults
compair doctor # validate auth, group bindings, and current repo document health
compair doctor --json
compair version # CLI + target server version/capability identity
compair telemetry status
compair telemetry on
compair telemetry off
compair feedback-length detailed
compair whoami # prints username (and user_id)
compair logout # removes stored credentialsThe CLI now supports a small opt-in usage heartbeat:
compair telemetry status
compair telemetry on
compair telemetry offWhen enabled, the CLI sends at most one anonymous heartbeat per day to https://app.compair.sh/api by default. The payload includes:
- a random local install ID
- CLI version
- OS and architecture
- the last command path that ran
It does not include repo contents, document text, auth tokens, usernames, or local file paths.
Override the collection endpoint when needed:
export COMPAIR_TELEMETRY_BASE="https://app.compair.sh/api"Compair Cloud admins can inspect a summary with:
curl -H "admin-key: $ADMIN_API_KEY" \
"https://app.compair.sh/api/admin/client_metrics_summary?days=30"Use this when you want to run compair_core locally without editing container environment variables by hand.
# Inspect the saved runtime config and Docker/container state
compair core status
compair core doctor
# Start the default single-user Core container with local providers
compair core up
compair profile use local
compair login
# Switch the local runtime to OpenAI generation with local embeddings
export OPENAI_API_KEY="sk-..."
compair core config set --generation-provider openai --embedding-provider local --openai-model gpt-5.4-mini --openai-api-key "$OPENAI_API_KEY"
compair core up
# Quality-first option: use OpenAI for both generation and embeddings
compair core config set --provider openai --openai-model gpt-5.4 --openai-api-key "$OPENAI_API_KEY"
compair core up
# Run Core with local auth-enabled accounts instead of single-user mode
compair core config set --auth accounts
compair core up
# Return to the default free local path
compair core config set --provider local --auth single-user
compair core up
# Inspect or follow logs
compair core logs --tail 200
compair core logs --follow
# Recreate the container after changing saved config
compair core restart
# Shut the runtime down later
compair core down
compair core down --purgeNotes:
compair core upruns the publishedcompairsteven/compair-corecontainer on the configured localhost port and updates thelocalCLI profile automatically.--generation-provider openai --embedding-provider localis the recommended bring-your-own-key starting point.--provider openaisets both generation and embeddings to OpenAI for the quality-first path.--openai-code-modeland--openai-notif-modellet you tune local Core review generation and notification scoring separately.--openai-base-urllets local Core talk to an OpenAI-compatible endpoint instead of the default OpenAI base URL.--provider fallbackkeeps local embeddings but disables model-generated feedback in favor of reference-only fallback behavior.- If you prefer not to save the key in
~/.compair/core_runtime.yaml, setCOMPAIR_OPENAI_API_KEYorOPENAI_API_KEYand omit--openai-api-key. compair core doctorvalidates Docker, the local profile, container state, the Core/healthendpoint, and auth-mode alignment.
--api-base,--profile,--group,--verbose,--debug-http,--no-color- Active group resolution:
COMPAIR_ACTIVE_GROUP→--group→~/.compair/active_group; if none is set, the CLI auto-selects a default (your{username}group if present, else the first group you belong to) and persists it.
compair group ls # list groups (id + name); marks (active)
compair group use <group> # set active group (id or name)
compair group current # print active group
compair open # open the active/auto-resolved group in the web UIcompair open infers the UI origin from your API base by stripping a trailing /api. Override with COMPAIR_UI_BASE when needed.
Enable HTTP request logging (useful for support tickets):
compair --debug-http syncCreate and inspect groups:
compair group create "Platform Services"
compair group ls
compair group list-users [group]
compair group join <group>
compair group rm <group> # delete a group (admin only; prompts for confirmation)With an active group set, you can omit the group (id or name) for many commands:
# Set the active group once
compair group use <group-id|group-name>
# Then you can:
compair group list-users # uses active group if none provided
compair track # uses active group by defaultGroup resolution:
- Commands that accept a group allow either the group ID (e.g.,
grp_123) or the exact group name. - If multiple groups have the same name, the CLI will list matching IDs and ask you to specify the ID.
group join <name>also searches discoverable groups, not just groups you already belong to.- Repo documents are published by default so other repos can reference them during cross-repo review. Use
--unpublishedto opt out.
Run inside a git repository:
compair track # simplest repo-first path; uses active group
compair track ./path/to/repo # track another local repo
compair track --group <group> # explicit group id or name
compair track --initial-sync # register + send the first sync immediately
compair track --initial-sync --no-feedback # register + upload a baseline without feedback
compair track --unpublished # keep this repo private- Creates a document representing the repo via
/create_doc - Saves
.compair/config.yamlwithdocument_idand repo metadata - Existing repo bindings are auto-published on
compair syncunless the repo config explicitly opts out withunpublished: true compair trackis the repo-registration entry point--no-feedbackonly applies when paired with--initial-sync; it is the recommended way to baseline a repo into a shared group before a later warm review pass
For single-user cross-repo review, enable your own published repo documents as reference candidates:
compair self-feedback on
compair self-feedback offControl how much generated feedback is returned for your account:
compair feedback-length brief
compair feedback-length detailed
compair feedback-length verbose# Run a full review (default uploads + fetches, waits for processing,
# writes .compair/latest_feedback_sync.md, then renders it)
compair review --commits 10 --ext-detail
compair review --all --snapshot-mode snapshot --reanalyze-existing
compair review --detach # submit now, then follow with `compair wait`
compair review --all --pairwise
compair review --all --pairwise --cross-repo-only
compair review --all --snapshot-mode snapshot --reanalyze-existing --now --yes
compair review --all --snapshot-mode snapshot --reanalyze-existing --now --skip-index --yes
compair wait
compair wait --timeout 20m
compair wait --timeout 0
# Simpler task-oriented aliases
compair push
compair pull
compair reports
# Advanced / CI path: use sync when you want lower-level control
compair sync --push-only
compair sync --fetch-only
# If your backend queues take longer, extend the wait window (seconds)
compair sync --feedback-wait 90
# If backend processing itself is the long pole, reattach with a larger wait budget
compair wait --timeout 20m
compair wait --timeout 0
# Sync selected paths (resolved to repo roots)
compair sync ./projA ./projB
# Sync all tracked repos in the active group
compair sync --all --commits 10
# Preview payload without sending it
compair sync --dry-run
# CI-friendly summary output and gating
compair sync --json
compair sync --json --gate api-contract
compair sync --gate help
compair sync --json --fail-on-feedback 1 # count-based fallback when detailed notification gating is unavailable- Collects recent commits + a summary of diffs since the last sync
- On the first sync of a repo (no
last_synced_commityet), sends a baseline snapshot with the file tree and full tracked text contents by default - Sends text to
/process_docwithgenerate_feedback=true --reanalyze-existingis the warm-pass switch: when paired with--snapshot-mode snapshot, Compair can generate feedback from already-indexed repo chunks that do not yet have feedbackcompair review --detachsubmits the review work and returns immediately; usecompair waitto reattach latercompair review --pairwiseis the heavier coverage mode: it replays the target repo against one peer repo at a time instead of relying on the shared peer poolcompair review --pairwise --cross-repo-onlyskips same-repo pairs and focuses only on other tracked repos in the active group--pairwisecurrently runs attached only; use it when you intentionally want a slower, more exhaustive repo-pair sweepcompair review --nowruns a one-shot whole-bundle LLM review over the current tracked repo content instead of the normal per-chunk retrieval pipeline, with a token/cost quote before the model call. On Cloud, this path uses prepaid credits when enabled.compair review --now --skip-indexkeeps that one-shot review fast by skipping chunk/embedding refresh for the uploaded snapshot, but the normal indexed retrieval state stays stale until a later full sync/review- If the repo was bootstrapped with
track --initial-sync --no-feedback, a later feedback-generating review may first finish that unfinished baseline indexing before it can submit new review work. This also applies toreview --detach. compair waitresumes saved pending repo tasks, then fetches and renders the resulting reportcompair wait --timeoutis the friendly way to extend how long you stay attached to a large review; use0to wait indefinitelycompair sync --feedback-waitremains the lower-level knob when you want to cap only the post-processing feedback wait budgetcompair syncis mainly for automation, CI, JSON output, gating, or troubleshooting; most interactive use should stay onreview- Large first baselines can also hit the default 10-minute processing wait budget; rerun the same command or use
compair wait --timeout 20mto continue waiting without resubmitting, or usecompair review --detach/compair pushand come back later - Caches feedback IDs locally so repeated syncs only append newly seen items
- Updates
last_synced_commitboth in repo-local.compair/config.yamland the workspace DB --gate <preset>provides the simplest path for common CI/review use cases without needing to remember low-level notification flags- Built-in presets:
api-contract,cross-product,review,strict(use--gate helpto print details) --fail-on-severityand--fail-on-typeuse new notification events as the primary CI gate (severity + notification intent/type)--fail-on-feedbackremains the simpler fallback gate when detailed notification data is unavailable or unsupported- Saved reports are ordered using ranked notification events when they are available, so higher-severity/higher-certainty items appear first with notification rationale attached on both Cloud and Core
- Core still differs from Cloud on delivery/integration layers such as Google OAuth, billing, and hosted notification delivery
- Long-running review commands now print periodic progress lines while waiting for server-side processing and while waiting for newly generated feedback; the ETA is approximate
Baseline snapshots now default to full-repo indexing. Add caps only when you want a lighter or faster run:
compair sync --snapshot-max-files 80 --snapshot-max-total-bytes 500000
compair push --snapshot-max-total-bytes 300000 --snapshot-max-files 60Before you reach for blunt caps, prefer trimming obviously low-signal tracked
files with a repo-local .compairignore. This keeps the review surface closer
to the product-surface scale that Compair handles best.
Ask the CLI for a conservative starter list:
compair ignore suggest
compair ignore suggest --all
compair ignore suggest --writeExample .compairignore:
package-lock.json
scripts/*
docs/third-party-notices*
generated-sdk/docs/
Use .compairignore for things like:
- generated model or reranker artifacts
- evaluation or training scripts that are not part of the shipped product
- giant lockfiles
- third-party notice bundles
Keep the patterns simple. .compairignore is not full .gitignore syntax; it
does straightforward basename and repo-relative glob matching. A trailing slash
acts as a directory-prefix rule, so generated-sdk/docs/ ignores everything
under that repo-relative directory.
What tends to produce the strongest cross-repo signal:
- focused edits beat large mixed rewrites
- one concrete route/field/config change is easier to ground than several unrelated changes in the same chunk
- docs, API maps, and config tables are easiest to compare when the changed rows stay close to the implementation or companion docs they affect
What tends to be harder:
- tiny structured renames buried inside a much larger rewritten chunk
- many unrelated edits in the same file during snapshot review
- broad prose rewrites where the old and new behavior are both only implied
This is one reason smaller, more coherent diffs usually work better with Compair, in addition to being good general git hygiene.
For a shared group of repos you own, the recommended pattern is:
# 1. Put every repo in the same active group and upload a baseline with no feedback
compair group use <group-id|group-name>
compair self-feedback on
compair track ~/code/compair_core --initial-sync --no-feedback
compair track ~/code/compair_cloud --initial-sync --no-feedback
compair track ~/code/compair-cli --initial-sync --no-feedback
# Optional but recommended on larger suites:
# add repo-local .compairignore files before the warm pass to exclude
# generated artifacts and other low-signal tracked files
# 2. Once all repo baselines exist in that group, run one warm snapshot pass
compair review --all --snapshot-mode snapshot --reanalyze-existing --detach
compair wait --allThis keeps the onboarding path aligned with the normal Compair model:
- each repo is still just a document in a group
- the baseline pass creates the searchable snapshot without prematurely generating feedback
- the warm pass generates feedback after the whole group is available for cross-repo reference selection
Persist those caps in a profile when you want them every time:
compair profile set cloud --snapshot-max-files 80 --snapshot-max-total-bytes 500000Force snapshot or diff mode (default: auto):
compair sync --snapshot-mode snapshot
compair sync --snapshot-mode diffInclude/exclude files in snapshots:
compair sync --snapshot-include "src/*.py" --snapshot-exclude "vendor/*"Preview a baseline snapshot (no upload):
compair snapshot preview --output .compair/snapshot.mdSee the exact payload that would be sent:
compair diff --snapshot-mode autoSummarize language mix and snapshot coverage:
compair statsThat makes compair stats a good first sanity check after adding a
.compairignore: confirm that the included snapshot surface shrank in the way
you expected before running the full review.
When OCR uploads are disabled on the server, the CLI continues syncing but warns that OCR-based extraction is unavailable. Configure COMPAIR_OCR_ENDPOINT to point at your own OCR service or upgrade to Compair Cloud for full OCR support.
# Show the latest report using the built-in renderer
compair reports
# Step through every saved report
compair reports --all
# Open the latest report using your OS default markdown viewer
compair reports --system
# Render a specific file
compair reports --file .compair/latest_feedback_sync.md- Reports saved under
.compair/*.mdare discoverable viacompair reports - Rendering happens in-terminal via a lightweight Markdown renderer with a plain-text fallback
- When iterating (
--all), press Enter to move forward,oto open the file externally, orqto exit - On Cloud, report sections are ordered using notification-event ranking when those events exist for the feedback chunks
# See recent activity across your groups (Cloud only)
compair activity
compair activity --include-own=false --page 1 --page-size 20# List ranked notification events
compair notifications
compair notifications --include-ack --include-dismiss --all-groups
# Act on a notification event
compair notifications ack <event_id>
compair notifications dismiss <event_id>
compair notifications share <event_id> --note "Please review"
# Show or update hosted delivery preferences
compair notifications prefs
compair notifications prefs --digest on --frequency daily
compair notifications prefs --push on --max-push 1
compair notifications prefs --all-buckets --clear-quiet-hours
compair notifications prefs --delivery-email alerts@example.com
compair notifications prefs --clear-delivery-emailNotes:
- Ranked notification events work on both Cloud and Core when the server advertises
features.notification_events=true. - Hosted email delivery remains a Cloud capability. The
prefssubcommand controls Cloud digests and instant email alerts; on pure Core those settings are mostly informational. - Hosted delivery now defaults to explicit opt-in. Digests are off until enabled, and the default cadence when enabled is
daily. - Alternate delivery emails must be verified before Compair will route push/digest mail there. Until verification completes, the current verified address stays active.
compair feedback rate <feedback_id> --value positive
compair feedback rate <feedback_id> --value negative
compair feedback rate <feedback_id> --value clear
compair feedback hide <feedback_id>
compair feedback hide <feedback_id> --unhidecompair notes list <document_id>
compair notes add <document_id> --content "Review notes here"
compair notes add <document_id> --file ./notes.txt
compair notes get <note_id># List documents for the active group
compair docs list
# Filters
compair docs list --filter recently_updated
compair docs list --filter recently_compaired
compair docs list --filter unpublished --own-only# Watch current repo
compair watch --interval 90s --notify --on-change 'open .compair/last-sync.md'
# Watch specific repos by path
compair watch ~/code/repo1 ~/code/repo2
# Watch all tracked repos for the active group
compair watch --all- Repeats sync on an interval
- Watches your local checkout state; it does not subscribe to remote collaborator pushes by itself
- Remote collaborator changes surface after they land in your local repo or when another client/server process syncs them into Compair
- Best-effort notifications on macOS/Linux/Windows
- Hook (
--on-change) runs a shell command on changes
Hook environment:
COMPAIR_COMMITS– number of commits detected in last cycleCOMPAIR_FEEDBACK_COUNT– number of feedback itemsCOMPAIR_SYNC_JSON– path to a JSON file with the full result (if available)
See Hook Recipes for ideas.
The CLI maintains a canonical index at ~/.compair/workspace.db to map local paths ↔ groups ↔ documents.
# Add items to the active group
compair add ./src ./README.md
# Remove items from tracking
compair rm ./README.md
# Show tracked items under the current directory
compair statusAdd a helper function to your shell profile to switch the active group quickly:
compair_use() {
export COMPAIR_ACTIVE_GROUP="$1"
echo "Active group: $COMPAIR_ACTIVE_GROUP"
}(Fish or PowerShell users can adapt the snippet above to their shell syntax.)
Notes:
review,sync, andwatchdefault to repo-local.compair/config.yaml, and automation can override that path withCOMPAIR_PROJECT_CONFIG_PATH.- The workspace DB is the source of truth for
add,rm, andstatus. - Command names use a single style:
group ...subcommands (colon forms are deprecated).
