# CLI reference
Supercov has one command for measuring a suite and a small set of commands for
reading the result. Text output is designed for people and coding agents. Add
`--json` only when an integration needs a stable machine-readable response.
```sh supercov
npx supercov --help
```
## Quick reference
| Measure a suite | `npx supercov -- <test command>` |
| List recent runs | `npx supercov runs` |
| Read the newest run | `npx supercov runs latest` |
| Find useful gaps | `npx supercov runs latest gaps` |
| Inspect one file | `npx supercov runs latest file <path>` |
| List assertions and their status | `npx supercov runs latest assertions` |
| Inspect one assertion and its flows | `npx supercov runs latest assertion <id>` |
| Read matching current source code | `npx supercov runs latest source <path>` |
| Compare two runs | `npx supercov diff <older> <newer>` |
| Combine shards | `npx supercov merge <id> <id> [...]` |
| Remove local data | `npx supercov clean` |
| Read bundled guides | `npx supercov docs` |
## Measure a test command
```sh supercov
npx supercov -- <test command>
```
Everything after `--` is passed to the test command:
```sh supercov
npx supercov -- npm test
npx supercov -- npx playwright test --project=chromium
npx supercov -- cargo test
npx supercov -- cargo nextest run
```
Use the complete command you rely on before merging or deploying. A coverage run
preserves the wrapped command's exit status, so it can remain a CI gate.
## List and select runs
```sh supercov
npx supercov runs
npx supercov runs --limit 5
npx supercov runs latest
npx supercov runs <run-id>
```
Runs are listed newest first. `latest` is convenient during an interactive
loop. Use the immutable run id in automation, review notes, and work that spans
sessions.
## Query a run
```sh supercov
npx supercov runs <run-id> [query] [options]
```
| no query | Read the overall result, test outcome, completeness, and timings |
| `gaps` | See only files with uncovered behavior or measurement limits |
| `files` | See every included file, including fully covered files |
| `file <path>` | Inspect the open obligations in one file |
| `decision <id \| path:line>` | Understand missing boolean outcomes and MC/DC witnesses |
| `line <path:line>` | See one line's state, obligations, and covering tests |
| `test <id \| name>` | See the coverage attributed to one test |
| `kinds` | Group coverage by test level, such as unit or E2E |
| `runners` | Group coverage by test runner |
| `scope` | Review included, excluded, and ambiguous source files |
| `assertions` | List assertions, including sites without flows, with freshness and execution status |
| `assertion <id>` | Inspect one assertion and its authored flows |
| `source <path>` | Read matching current project source with line numbers |
| `minimize` | Find a small test subset that preserves a coverage target |
Common examples:
```sh supercov
npx supercov runs latest gaps --limit 10
npx supercov runs latest file app/routes/checkout.ts
npx supercov runs latest decision app/routes/checkout.ts:42
npx supercov runs latest line app/routes/checkout.ts:57
npx supercov runs latest test "checkout retry"
```
Run any query with `--help` to see only the options valid for that query:
```sh supercov
npx supercov runs latest --help
npx supercov runs latest file --help
npx supercov runs latest assertions --help
```
Assertion queries read the run-owned map. `source <path>` reads the matching current
file directly. It prints source code with line numbers, preserving indentation;
add `--json` only when you want structured `{line, text}` items. `--offset` is
zero-based and `--limit` controls the number of source lines. Source and assertion
investigation require current files that match the run. Rerun the suite after
source changes to inherit the map into a new run.
### Assertion coverage
The regular run summary includes assertion coverage when a map has been
assessed. JSON reports expose it under `data.assertionCoverage`. Start with
[Understanding assertion coverage](assertions.md), or use these commands to
inspect and check a map:
```sh supercov-example
npx supercov runs <run-id> assertions --needs-attention
npx supercov runs <run-id> assertion <assertion-id>
npx supercov runs <run-id> assertions report --view statements --file src/shipping.js
npx supercov runs <run-id> assertions report --view excludedStatements
npx supercov runs <run-id> assertions validate --json
npx supercov runs <run-id> assertions check --require-mappings
```
Edit the file shown by `assertions`. Validation returns `expectedBasis` tokens;
after examining a flow, save its token in the map before running `check`.
`--require-mappings` requires explanations for recognized assertions observed
passing. Add `--require-observed` when every mapped site and selector should have
passing evidence, or `--min <percentage>` for a chosen target.
To inspect one large flow, add `--flow <flow-id> --view nodes` or `--view edges`
to the assertion detail command. `--compact` omits repeated source text from the
report. Follow the printed next-page command or JSON `pagination.nextOffset`.
Validation supports `--view flows`, `--view changes` and `--view errors` for large
maps. The [map reference](assertion-maps.md) describes all fields and gates.
## Fail CI below a coverage floor
```sh supercov-example
supercov runs check --min-lines 90 --min-branches 80 --min-mcdc 80
supercov runs check --min-lines 100 --per-file --json
```
`check` reads a recorded run; it never runs tests again. Give a floor per metric
with `--min-lines`, `--min-statements`, `--min-functions`, `--min-branches` or
`--min-mcdc`. `--per-file` applies the same floors to every file that has
eligible obligations, in addition to the whole run. Both report the counts
behind the percentage and, for lines, where the gaps are.
Floors are compared against the counts, never a rounded percentage: 9,999
covered lines out of 10,000 displays as 99.99% and fails a 100% floor, and a
run that displayed `100.00%` could never pass one while something is uncovered.
A check answers only when the run can answer. These end the command with `2`
rather than a pass or a failure:
- the wrapped test command did not pass, so a gate over it would turn a red CI
run green
- the run no longer matches the current checkout
- a requested metric has nothing eligible, which is not the same as complete
- a requested metric left obligations unmeasured, so no exact judgement exists
- a requested metric is not recorded by the language adapter
Assertion coverage keeps its own check. Whether a test *examines* what it
executes is a different question from whether a line ran, and
`runs <id> assertions check` carries the freshness and acknowledgement rules
that answer needs.
## Check the lines a change touches
```sh supercov-example
supercov runs patch --base origin/main --min-lines 100
supercov runs patch --base origin/main --annotate github
```
`patch` answers whether the lines this change added or modified are tested. It
compares against the **merge base** with `--base`, not that branch's tip, so
commits other people landed after you branched are not counted as your
obligation. A shallow checkout has no merge base; fetch with full history
(`actions/checkout` takes `fetch-depth: 0`).
The denominator is the changed lines the run measured. Comments, blank lines and
declarations fall out because the language adapter already decided they are not
executable, not because `patch` guesses at syntax. Deleted lines are excluded:
there is nothing left to cover. Untracked new source counts as entirely added.
A change with nothing executable in it reports **No executable changes** and
passes, rather than claiming 100% for a patch that changed only comments. A
changed file that looks like product source but is absent from the run is named
separately, because treating it as zero uncovered lines would report success for
code nothing ran.
`--annotate github` prints workflow-command annotations on stdout, combining
adjacent misses into one range and capping the total (`--max-annotations`). It
needs no token and posts no comment.
## Export for other tools
```sh supercov-example
supercov runs report --format lcov --output coverage/lcov.info
supercov runs report --format cobertura --output coverage/cobertura.xml
supercov runs report --format html --output coverage/report
```
Both are written from the same view `check` and `patch` read, so a viewer,
hosted service or CI integration sees the totals Supercov enforced. Paths are
repository-relative with forward slashes, ordering is stable, and the file is
written atomically; an existing file is kept unless you pass `--force`. Without
`--output` the report goes to stdout and diagnostics to stderr, so a redirect
captures only the report.
Supercov records that a line ran, not how many times, so `DA:` and `hits` state
`1` or `0`. They are not execution frequencies, and Supercov will not invent
one to fill a field.
MC/DC conditions are not exported as ordinary branches. A consumer would then
show condition obligations as branch coverage, which is a different
measurement; that evidence stays in the JSON view and the HTML report. A report
from a failed or stale run is still written, with a warning on stderr — only
`check` refuses to pass on one.
### The HTML report
`--format html` writes one self-contained document. It opens from a copied CI
artifact with no server, no network and no login, and nothing is fetched from a
CDN. Because a source path is never used as an output path, a filename cannot
write outside the directory you named, and no directory is ever cleared to
regenerate a report.
It has three levels: the run's metric counts, a filterable and sortable file
table, and a source view marking each line covered or not covered in words and
a glyph as well as colour. Every line links as `#<file>:<line>`, so a CI summary
can point someone at the obligation rather than at the report.
Four states stay distinct, because collapsing them into one score is how a
report starts to mislead: **uncovered** (measured, nothing reached it), **not
applicable** (nothing eligible), **partly measured** (Supercov declined some
obligations, which are excluded from every count) and **stale** (the run no
longer matches the checkout). A failed suite says so beside its numbers.
Source text is embedded only when the run still matches the checkout; otherwise
the report shows line numbers and explains why. Embedding makes a report
portable and also means it contains your code — worth knowing before uploading
one as a public artifact.
## Narrow a view
| `--filter all \| passed \| failed` | Recalculate the view from all, successful, or failed attempts |
| `--kind <kind>` | Restrict to a test level such as `unit`, `integration`, or `e2e` |
| `--runner <runner>` | Restrict to one runner |
| `--metric all \| lines \| statements \| functions \| branches \| mcdc` | Choose a metric for `files`, `gaps`, `diff`, or `minimize` |
| `--limit N`, `--offset N` | Page through a collection |
| `--json` | Return the machine-readable form |
Collection output includes a copyable command for the next page.
For a large file, group and rank its decisions:
```sh supercov
npx supercov runs latest file app/routes/checkout.ts \
--group decision --sort missing
```
## Compare runs
```sh supercov
npx supercov diff <older-run> <newer-run>
```
`diff` reports gains and losses. Use it after adding a test to prove that the
expected behavior became covered without an unexplained regression elsewhere.
Neither input run is changed.
The same filters can focus a comparison:
```sh supercov
npx supercov diff <older-run> <newer-run> --kind e2e
```
## Find a smaller test set
```sh supercov
npx supercov runs latest minimize
npx supercov runs latest minimize --metric branches --target 90
```
`minimize` finds a small set of tests that preserves the selected coverage
target. It does not edit, delete, or skip tests for you. Treat the result as an
analysis aid, not permission to remove tests that protect behavior outside the
selected metric.
## Combine shards
```sh supercov
npx supercov merge <shard-a> <shard-b> <shard-c>
```
Merge creates a new run. The inputs must describe the same source,
configuration, toolchain, schema, and coverage denominator. Supercov rejects an
incompatible merge rather than publishing a misleading aggregate.
## Clean local data
```sh supercov
npx supercov clean --dry-run
npx supercov clean --keep 20
npx supercov clean
```
By default, `clean` removes all stored runs and the isolated build cache.
`--keep N` keeps the newest N runs. Cleanup removes only marker-owned Supercov
storage.
## Read bundled documentation
```sh supercov
npx supercov docs
npx supercov docs getting-started
npx supercov docs troubleshooting
```
The guides are installed with the package, so they remain available in a
terminal or offline environment after the package has been downloaded.
## Environment variables
| `SUPERCOV_SOURCE_ROOTS` | Set comma-separated first-party source roots when automatic discovery is ambiguous |
| `SUPERCOV_TEST_KIND` | Label the wrapped command as a test level such as `unit` or `e2e` |
Examples:
```sh supercov
SUPERCOV_SOURCE_ROOTS=src,app npx supercov -- npm test
SUPERCOV_TEST_KIND=e2e npx supercov -- npx playwright test
```
## Exit codes
| `0` | The command or query succeeded |
| Wrapped command's code | The test command failed and Supercov preserved its status |
| `1` | A valid measurement failed a policy you set, such as a coverage floor |
| `2` | Supercov could not complete the request, or the evidence cannot answer it |