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

You can also run it without installing, with 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 that is active in V12 at that moment; see Which organization a token reads. The CLI refreshes its access token on its own.

  • --no-browser does not open the browser; open the URL the CLI prints. The login waits up to five minutes.

  • --scopes asks for fewer scopes, as a comma-separated list such as --scopes user:read,findings:read. Without it, the CLI gets all seven scopes.

  • --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 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 owner/name. If you leave it out, 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 focuses list|showFocuses and their instructions
v12 repos list|show|refsRepositories, their state, and their branches, pull requests and tags
v12 findings list|showThe organization or repository inbox; one finding with its reports, evidence and activity
v12 findings status|severity|assign|dismiss|restore|commentTriage findings by id or key, such as F-42. Status changes and dismissals need --reason.
v12 runs list|show|findings|watch|cancelRuns, their stages, the findings they added to the inbox, following a run, and cancelling it
v12 runs estimate|startPrice a run, or approve and start it
v12 docs list|show|archive|upload|noteContext documents for runs
v12 findings list --status open --severity critical,high
v12 findings status fixed F-12 F-15 --reason "Fixed in #482"
v12 findings assign me F-12

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

Start runs from the CLI

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

v12 runs start estimates the run first 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>, or --branch <name> with an optional --since <sha>, reviews a change. --scope, --also, --steering and --doc add paths, other repositories, instructions and context documents. --focus <slug>, repeatable up to 5 times, attaches focuses to either kind of review.
  • Price limit: --max-price (in 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 does not 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.

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, and --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 calls the API URL from --api-url, then V12_API_URL, then the saved setting, then https://v12.sh.

Output

The CLI prints results in a readable form. --json prints the API response as JSON on standard output instead. 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
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. 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; it keeps an API key that 0.3 saved.

On this page