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/cliOr 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|copilotConnect 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 logoutDelete 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.sarifList 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 uninstallA 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