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 --versionYou 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 statusv12 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-browserdoes not open the browser; open the URL the CLI prints. The login waits up to five minutes. -
--scopesasks for fewer scopes, as a comma-separated list such as--scopes user:read,findings:read. Without it, the CLI gets all seven scopes. -
--with-tokenreads an API key from standard input instead of signing in with OAuth:printf '%s\n' "$V12_API_TOKEN" | v12 auth login --with-token
| Command | What it does |
|---|---|
v12 auth status | Shows your user, workspace and token scopes |
v12 auth token | Prints a valid access token, refreshing it if needed. Treat the output as a secret. |
v12 auth logout | Revokes 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
| Command | What it does |
|---|---|
v12 me, v12 members | Your user and workspace; the workspace's members |
v12 focuses list|show | Focuses and their instructions |
v12 repos list|show|refs | Repositories, their state, and their branches, pull requests and tags |
v12 findings list|show | The organization or repository inbox; one finding with its reports, evidence and activity |
v12 findings status|severity|assign|dismiss|restore|comment | Triage findings by id or key, such as F-42. Status changes and dismissals need --reason. |
v12 runs list|show|findings|watch|cancel | Runs, their stages, the findings they added to the inbox, following a run, and cancelling it |
v12 runs estimate|start | Price a run, or approve and start it |
v12 docs list|show|archive|upload|note | Context 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-12Run 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 25v12 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:
--atreviews the code at a position.--pr <number>, or--branch <name>with an optional--since <sha>, reviews a change.--scope,--also,--steeringand--docadd 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-centssets the most the run may cost. Without either, the quoted price is the limit. A run that would cost more does not start. - Confirmation:
--yesskips the prompt. Outside a terminal,--yesis required; without it, the command exits with code 2. - Follow it:
--watchfollows 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 --jsonV12_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
| Code | Meaning |
|---|---|
0 | Success |
1 | Any other error, or a watched run that failed or was cancelled |
2 | Usage error, including runs start outside a terminal without --yes, or a declined confirmation |
3 | unauthenticated, insufficient_scope or forbidden |
4 | not_found |
5 | price_exceeds_max, insufficient_credits, spend_cap_reached or quote_stale |
6 | rate_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.