CLI

Install the v12 command, sign in, run the common commands, and use it in CI.

The v12 command reads and triages findings, starts and follows runs, and manages context documents from your terminal. It calls the REST API, so the same scopes, permissions and errors apply.

Install

npm install -g @v12sh/cli
v12 --version

Or run it without installing: npx @v12sh/cli. Version 1.0 needs Node.js 20.19 or later.

Sign in

v12 auth login
v12 auth status

v12 auth login opens V12's consent page for V12 CLI in your browser, and saves the credentials when you select Authorize V12 CLI. The login acts on the workspace active in V12 at that moment; see Which organization a token reads. The CLI refreshes its access token and finds the workspace's slug for REST paths itself, so no command takes one.

  • --no-browser doesn't open the browser; open the URL the CLI prints. The login waits up to five minutes.

  • --scopes chooses a comma-separated scope list, such as --scopes user:read,findings:read. Without it, the CLI requests every scope except the opt-in runs:share (guest links) and steers:write (Steer management). Include either explicitly when needed, together with the other scopes your workflow uses. API keys expose them as Share runs and Manage Steers.

  • --with-token reads an API key from standard input instead of signing in with OAuth:

    printf '%s\n' "$V12_API_TOKEN" | v12 auth login --with-token
CommandWhat it does
v12 auth statusShows your user, workspace with its slug, and token scopes
v12 auth tokenPrints a valid access token, refreshing it if needed. Treat the output as a secret.
v12 auth logoutRevokes the OAuth tokens and deletes the saved credentials. For an API key, it only deletes the key from this machine; revoke the key in Settings → Developer.

Repository and position

Commands that work on one repository take --repo: the repository's full name, owner/name, or its slug. Without it, the CLI reads the repository from git remote get-url origin when that is a GitHub URL ([email protected]:owner/name.git, https://github.com/owner/name or ssh://[email protected]/owner/name.git). v12 findings list shows the organization inbox when it finds no repository, and always with --org.

--at takes a position, or HEAD, which the CLI turns into your checkout's current commit.

Commands

CommandWhat it does
v12 me, v12 membersYour user and workspace; the workspace's members
v12 steers list|show|create|edit|archive|restoreSteer documents; list --archived shows only archived ones. Writes require steers:write.
v12 repos list|show|refsRepositories, their state, and their branches, pull requests and tags
v12 repos addAdd a repository to the workspace by owner/name, GitHub link or clone URL; without one, the origin repository. Adding a repository that is already there changes nothing.
v12 repos create|pushCreate a repository V12 hosts, v12/<name>, and push a commit to one of its branches; see Push code to a hosted repository. Admins only; available in CLI 1.2.
v12 findings list|showThe organization or repository inbox; one finding with its reports, evidence and activity
v12 findings status|severity|assign|commentTriage findings by key, such as F-42, or number. assign takes me, none, or a member's email or username.
v12 runs list|show|findings|watch|cancelRuns, their stages, the findings they added to the inbox, following a run, and cancelling it. A run is named by its number in the workspace, such as 12.
v12 runs estimate|startPrice a run, or approve and start it
v12 runs links list|create|update|revokeGuest links that open a run to people outside the organization. Each takes the run's number; update and revoke also take the link's number in the run, such as v12 runs links revoke 12 2. create prints the URL once; update --clear-label removes a link's label. Needs runs:share; create and update also need findings:read, and findings:write for a comment or triage link.
v12 docs list|show|archive|upload|noteContext documents for runs; list --archived adds archived documents to the active ones.
v12 findings list --status open --severity critical,high
v12 findings status fixed F-12 F-15
v12 findings assign me F-12
v12 repos add https://github.com/acme/sdk

A status change takes no reason; explain a decision with v12 findings comment. CLI 1.1 and older still require --reason, which V12 now refuses, so update with npm install -g @v12sh/cli.

v12 <command> --help, for example v12 findings list --help, lists every flag.

Members can add public repositories. Only an Admin can add a private repository, and the workspace's GitHub App must be able to read it. Adding a repository doesn't start a run. A run on a repository that isn't in the workspace fails with repository_not_added until you add it.

Manage Steers

Steer writes are available in CLI 1.1 and need the opt-in steers:write scope. Use v12 auth login --scopes repos:read,steers:write, adding any other scopes your workflow needs, or select Manage Steers on an API key.

v12 steers create --title 'Accounting' --emoji '🧮' --file accounting.md
v12 steers edit accounting --file updated-accounting.md
v12 steers archive accounting
v12 steers list --archived
v12 steers restore accounting

--instructions 'text' supplies instructions directly, and --file - reads stdin. Edits keep omitted fields and the original slug; --instructions '' clears the document. Repeating create makes another document. Archive and restore are safe to repeat. Archiving detaches Autopilot rules but preserves finding tags and run history; restoring does not reattach rules. See Steers.

Start runs from the CLI

v12 runs start --repo acme/api --at branch:main --scope src/ --max-price 25

v12 runs start estimates the run and prints the price and what it covers. In a terminal, it asks you to confirm, then starts the run with that quote. v12 runs estimate takes the same flags and only prices the run.

  • What to review: --at reviews the code at a position. --pr <number> (GitHub repositories only), or --branch <name> with an optional --since <commit>, reviews a change; see Review a change. --since takes a full 40-character SHA, or a revision this checkout names, such as HEAD~1 or an abbreviated SHA, which the CLI resolves with Git. --also, --steering and --doc add other repositories, instructions and context documents. --steer <slug>, repeatable up to 5 times, attaches Steers to either kind of review.
  • What it reads: a review of the code reads only what --scope names, with no default: pass each folder (ending in /) or file, repeating the flag. --scope owner/name:path names what an --also repository reads, and each one needs at least one. A path that names nothing V12 reviews is refused.
  • Price limit: --max-price (dollars) or --max-price-cents sets the most the run may cost. Without either, the quoted price is the limit. A run that would cost more doesn't start.
  • Confirmation: --yes skips the prompt. Outside a terminal, --yes is required; without it, the command exits with code 2.
  • Follow it: --watch follows the run until it ends, then prints its findings.

v12 runs findings <run> lists findings at each repository's analyzed commit, including findings only on a branch or pull request. status and codeState are evaluated at those commits, so a later fix on the default branch leaves the run's finding open. If the finding is present at current defaults, read it without a position for its current state.

With --json:

  • Each repository's position.at is commit:<sha>, and each finding's webUrl opens its detail in the repository workspace at that commit.
  • For later positioned reads, send that position.at with its repositories[i].repository. It keeps working if the branch moves or disappears.
  • Without repository, V12 infers it, and answers repository_required when more than one registered repository holds the finding at that position.

For the same flow over REST or MCP, see Start a run within a price limit.

Use in CI

Create an API key with only the scopes the job needs, and store it as a CI secret. Reading findings needs findings:read. Starting runs needs runs:write; --watch adds runs:read and findings:read.

- name: List open critical findings
  env:
    V12_API_TOKEN: ${{ secrets.V12_API_TOKEN }}
  run: npx @v12sh/cli findings list --repo ${{ github.repository }} --status open --severity critical --json

V12_API_TOKEN takes precedence over saved credentials, so the job needs no login. The CLI takes the API URL from --api-url, then V12_API_URL, then the saved setting, then https://v12.sh.

Output

The CLI prints readable results by default. --json prints the API response as JSON on standard output. Prices, progress, prompts and errors go to standard error, so the JSON stays parseable.

Exit codes

CodeMeaning
0Success
1Any other error, or a watched run that failed or was cancelled
2Usage error, including runs start outside a terminal without --yes, or a declined confirmation
3unauthenticated, insufficient_scope or forbidden
4not_found, repository_not_added or repository_not_visible
5price_exceeds_max, insufficient_credits, spend_cap_reached or quote_stale
6rate_limited, or any HTTP 429 or 503

Configuration

The CLI saves credentials in ~/.config/v12/config.json, one entry per API URL, with the slug of the workspace they read. Only your user can read the file.

Upgrading from 0.3

Version 0.3 used /api/v1, which now answers 410. Install version 1.0 or later; v12 repos create and v12 repos push need 1.2. Each keeps an API key that 0.3 saved.

Upgrading from 1.0

The API now refuses a review of the code without a scope. Version 1.1 checks for --scope before it sends the request, and adds --scope owner/name:path for --also repositories, which 1.0 can't scope.

On this page