Skip to content
Docs · CLI

Reference

CLI reference

Every Stableship CLI command, from the CLI's own help, with the environment variables and exit codes.

The CLI is Stableship from your terminal and CI. stableship help <command> prints the same text as each section below.

Install

npm install -g @stableship/cli

Or run any command once with npx --yes @stableship/cli@latest <command>. It needs Node 22 or newer. This page describes 1.14.1.

Commands

Most commands take --json. Commands about one app take --project <id> or --repo <owner/name>; without them, the app comes from the repository's git remote get-url origin.

stableship login

stableship login [--paste]

Sign in from the terminal: opens app.stableship.ai/app/connect with a code to approve (sign up there if you're new), then saves the token to ~/.config/stableship/config.json (mode 0600). Uses STABLESHIP_TOKEN when it is set. --paste asks for a token you made in Settings → Connections.

stableship connect

stableship connect claude|cursor|codex|windsurf|gemini|copilot

Connect a coding agent. Claude Code gets the Stableship plugin (its MCP server, /stableship:gate, the skill and the hooks, which use your saved login), replacing a separate stableship server if there was one. Cursor, Codex, Windsurf, Gemini CLI and GitHub Copilot get the MCP server with your saved token in ~/.cursor/mcp.json, ~/.codex/config.toml, Windsurf's (Devin Desktop's) mcp_config.json, ~/.gemini/settings.json or ~/.copilot/mcp-config.json (Copilot CLI and VS Code). Start a new session of the agent afterwards.

stableship init

stableship init [--agent claude|cursor|codex|windsurf|gemini|copilot] [--project <id> | --repo <owner/name>]

Everything to get going, one step at a time: sign in (as login), connect your coding agent (as connect; when you don't name one, the agent you run it from, else Claude Code when the claude command is installed), then say what this repository still needs in Stableship, with the link for the next step.

stableship logout

stableship logout

Delete the saved token. STABLESHIP_TOKEN, if set, still applies.

stableship status

stableship status [--json]

Each project with its latest release verdict and open and blocking finding counts.

stableship findings

stableship findings [--blocking] [--project <id> | --repo <owner/name>] [--status open|fixed|dismissed|all][--limit <n>] [--since <time>] [--json]stableship findings --sarif [--project <id> | --repo <owner/name>] [--run <runId>] > stableship.sarif

List findings (default: open ones). Only findings marked BLOCKS hold a release. --since keeps findings first seen at or after a date or time. --sarif prints SARIF 2.1.0 for GitHub code scanning (github/codeql-action/upload-sarif).

stableship brief

stableship brief <findingId> [--prompt] [--json]

Print the fix brief for a finding. --prompt prints only the copy-paste prompt for a coding agent, e.g. stableship brief <id> --prompt | pbcopy

stableship check

stableship check [--ref <sha|branch>] [--branch <name>] [--project <id> | --repo <owner/name>][--scope auto|quick|security|qa|full|skip] [--flow <key>] [--as <role>][--endpoint <path>] [--reason <text>] [--finding <id>]...[--wait] [--timeout <seconds>] [--json]

Start a check. A ref of 7-40 hex characters is a commit (add --branch to say which branch it is on), anything else a branch. Without --ref, in the app's repository, the commit you are on is checked once it is pushed (if not, the branch as pushed, and it says so). Without --project or --repo the repo is read from git remote get-url origin. --scope defaults to auto (the change decides). Asking for less than the project's minimum for the change runs at the minimum and says so. --flow, --as (or --role) and --endpoint narrow the check. Each check started here (narrowed or not, unless skipped) counts as one of the app's deep checks this month; with none left it replays saved flows only. --finding re-checks those findings only, as a fix verification, which is not counted (nor are the checks every push gets). --wait polls until the check is done and sets the exit code from the verdict. --timeout defaults to 900 seconds.

stableship skip

stableship skip "<reason>" [--ref <sha|branch>] [--branch <name>] [--project <id> | --repo <owner/name>] [--json]

Record that nothing in this commit needs checking (docs, copy). A change Stableship's path rules cover (sign-in, data, money) runs its minimum check instead, and says so.

stableship audit

stableship audit [--project <id> | --repo <owner/name>] [--wait] [--timeout <seconds>] [--json]

Start a full audit of the default branch: every role, every critical flow, on a private copy. Uses one of the app's full audits this month (Essentials and Protect), then a purchased one. When they are used, it offers to open the purchase page and waits for the payment: the audit starts by itself once it goes through. If an audit is already running, --wait follows it. Audits take up to 60 minutes; --timeout defaults to 5400 seconds. Needs a token with the run scope.

stableship verify

stableship verify <findingId>... [--project <id> | --repo <owner/name>] [--ref <sha|branch>] [--wait] [--timeout <seconds>] [--json]

Re-run just the check that found this finding, to confirm a fix. Pass every finding one fix closes (up to 20) to re-check them in one run. Without --ref, it re-checks the commit you are on once it is pushed (if not, the branch as pushed).

stableship rerun

stableship rerun <runId> [--wait] [--timeout <seconds>] [--json]

Run a check again with the same scope, narrowing, commit and branch (or the same findings, for a verification). Use it after a run ends in failed_infra or timed_out.

stableship why

stableship why <findingId|runId> [--json]

Why a finding blocks (or does not): confidence, the policy reason, the rule it breaks, repro, the verifier's notes, how often it was seen, known-issue status and evidence links. For a run: the scope it ran at, what was narrowed, each blocker and what was not covered.

stableship rules

stableship rules [--project <id> | --repo <owner/name>] [--area access|data|money|auth|flow|other] [--path <file>] [--json]

The project's rules as sentences, and the flows Stableship tests. --path shows only the rules that concern one file.

stableship context

stableship context [--project <id> | --repo <owner/name>] [--json]

Rules, kinds of user (role keys), the founder's product notes and what the last test copy could not test.

stableship note

stableship note "<fact>" [--remove] [--project <id> | --repo <owner/name>] [--json]

Save one lasting product fact (under 600 characters, no secrets) to the product notes. --remove takes a note out instead: its words, or the whole line. Needs a token with the run scope.

stableship propose

stableship propose --resource <thing> --action see|create|change|delete--allowed <role,role> --reason <text> [--area access|data|money][--text <sentence>] [--project <id> | --repo <owner/name>] [--json]

Propose who may do what, instead of changing access in code. The founder accepts it under Access; a rule that only adds a check may apply at once. Needs the run scope.

stableship flow

stableship flow --title <what people do> --reason <text> [--start </path>][--roles <role,role>] [--steps <text>] [--success <text>] [--critical][--project <id> | --repo <owner/name>] [--json]

Add something people do that every check clicks through. It only adds a check, so it may apply at once; otherwise the founder accepts it under Flows. Needs the run scope.

stableship known-issues

stableship known-issues [--project <id> | --repo <owner/name>] [--json]

Accepted risks, false positives, won't-fix and in-progress items, and dismissed findings.

stableship fix-plan

stableship fix-plan [--project <id> | --repo <owner/name>] [--run <auditRunId>] [--out STABLESHIP_FIXES.md] [--json]

Every open finding as ordered tasks (blocking first), as markdown. --out writes a file.

stableship report

stableship report [--project <id> | --repo <owner/name>] [--run <auditRunId>] [--json]

The plain-English audit report: verdict, steps, problems and what was not tested. Without --run, the project's latest finished audit.

stableship setup

stableship setup [--write CLAUDE.md] [--json]

The Stableship block for CLAUDE.md, AGENTS.md or Cursor rules. --write adds it to the file (or replaces the Stableship section already there), keeping everything else.

stableship wait

stableship wait [--sha <commit>] [--project <id> | --repo <owner/name>] [--timeout <seconds>] [--no-run-timeout <seconds>] [--json]

For CI before a deploy (Railway, Fly, anything deployed from GitHub Actions): waits until Stableship has decided whether this commit may deploy. Exit 0: it may (passed, shipped anyway, nothing risky changed, or Stableship could not finish a low-risk change). Exit 1: held (a blocking problem, or Stableship could not finish a change to sign-in, data or payments). --sha defaults to GITHUB_SHA, CI_COMMIT_SHA or HEAD; --timeout to 6600 seconds. When no check starts for the commit within --no-run-timeout (1200 seconds) the deploy goes ahead.

stableship hook

stableship hook install [--strict] [--force]stableship hook uninstall

A git pre-push hook for this repository. Pushing to the default branch while Stableship has open blocking findings prints them; with --strict the push is refused unless the commit has a Gate: <scope> trailer. It lets the push through when Stableship is slow or unreachable. git push --no-verify skips it. Checks still run on GitHub.

stableship whoami

stableship whoami [--json]

The workspace, the projects this token can see, its scopes (read, run, manage) and the role of the person who made it.

stableship next

stableship next [--project <id> | --repo <owner/name>] [--json]

The latest audit as a plan: how it went, what was covered, what to fix first (grouped by cause, ranked) and the one next step. Start here after an audit.

stableship activity

stableship activity [--project <id> | --repo <owner/name>] [--limit <n>] [--json]

What changed recently and who did it: findings dismissed, rules changed, fixes verified, settings.

stableship map

stableship map [--project <id> | --repo <owner/name>] [--run <runId>] [--json]

The map of the app from the latest audit: the pages each kind of user reached and how each went, the endpoints the API checks called, and what changed since the last map.

stableship approval

stableship approval <approvalId> [--json]

Whether a person approved an action you asked for, and whether Stableship carried it out.

stableship do

stableship do <action> [--key value]... [--json]

Run Stableship from your terminal or coding agent. Needs a token with the manage scope. Actions:

triage_finding --finding-id <id> --status false_positive|accepted|fixed|open --reason <text>reanalyzeresume_held_audit --run-id <id>          ship_anyway --run-id <id> --reason <text>decide_rule_suggestion --suggestion-id <id> --accept true|falseset_policy --type blocking|fail_open|schedule|notifications --settings '<json>'set_autonomy --level hands_on|guided|autopilotset_role --key <key> --name <name>       set_role_reach --key <key> --reach all|relatedremove_role --key <key>                  remove_rule --rule-id <id> --reason <text>share_report --run-id <id>               unshare_report --run-id <id>set_notifications --events block|approval_needed|audit_complete|digest [--events …] --email true|falsecreate_app --repos <owner/name> [--repos <owner/name>]... [--name <name>]   (the first repository is the main one)link_repo --add <owner/name>             set_service --service-id <id> [--kind <kind>] [--start <cmd>] [--port <n>] [--ignored true|false] [--reset]

Project actions take --project-id or --repo (default: the git remote). Anything that lowers protection (letting a blocking problem through, shipping anyway, loosening a policy) asks you here when you run it in a terminal; run by an agent without a terminal, it asks a person in Stableship instead (email, Slack, the app) and prints how to follow the approval.

Environment

STABLESHIP_TOKEN    API token. Takes precedence over the saved login (use this in CI).STABLESHIP_API_URL  API base URL (default https://api.stableship.ai).XDG_CONFIG_HOME     Where the config directory lives (default ~/.config).

Exit codes

0  Success. For check, verify and rerun: the release passed, passed with warnings, was   skipped or shipped anyway. Also 0 when Stableship itself failed (failed_infra,   timed_out, cancelled): Stableship never blocks a release on its own infrastructure   failure, so it prints a warning and lets you through.1  Blocked. The verdict is "block": at least one finding blocks this release (for verify:   the finding was found again; for the strict pre-push hook: the push was refused). A verify   that could not reach the finding prints "Could not check" and exits 0.2  Could not run. Usage error, not logged in, token rejected or missing a scope, API   error, or --wait ran past --timeout.

For your coding agent: this page as Markdown