CLI Reference
tools/cli.mjs is a dependency-free Node script that runs the same engine as the browser, for
batch analysis and CI.
node tools/cli.mjs <command> <file.spdx.json> [options]
| Command | Purpose |
|---|---|
analyze | Analyse an SBOM; output JSON, Markdown or CSV |
report | Per-ECU compliance report with verdict and obligation checklist |
notice | NOTICE attribution file |
inquiry | Supplier inquiry letter with numbered items and response blanks |
diff | Compare a baseline and a current SBOM |
gate | Release gate — exits non-zero on policy violation |
analyze
node tools/cli.mjs analyze samples/sample-ivisystem.spdx.json --format json
node tools/cli.mjs analyze samples/sample-ivisystem.spdx.json --format csv --out inventory.csv
node tools/cli.mjs analyze samples/sample-ivisystem.spdx.json --format md
--format accepts json, md or csv. Without --out, output goes to stdout, so it pipes
straight into other tooling.
report
node tools/cli.mjs report samples/sample-ivisystem.spdx.json \
--ecu "Cockpit ECU" --milestone C-Sample --supplier "Tier-1 GmbH" --out report.md
Produces the artefact for the internal review board: verdict, findings, obligation checklist, source-offer list and relinking list.
notice
node tools/cli.mjs notice samples/sample-ivisystem.spdx.json --out NOTICE
Emits per-component attribution blocks with license, source and copyright text.
inquiry
node tools/cli.mjs inquiry samples/sample-ivisystem.spdx.json --supplier "Tier-1 GmbH" --out inquiry.md
Drafts the letter to the supplier: numbered items, each with a blank for the response. This is the single most useful output for closing blockers, because it turns a finding into a question someone can answer.
diff
node tools/cli.mjs diff samples/sample-ivisystem-4.1.0.spdx.json samples/sample-ivisystem.spdx.json
--format accepts md or json. See milestone comparison
for what it detects.
gate — the CI contract
node tools/cli.mjs gate samples/sample-ivisystem.spdx.json \
--max-critical 0 --max-high 5 --min-quality 70
The exit code is the interface. A CI system needs nothing else: it does not parse output, does not read a report file, and does not need to know what a finding is.
| Outcome | stdout | stderr | Exit |
|---|---|---|---|
| All thresholds satisfied | GATE PASSED + score | — | 0 |
| Any threshold violated | — | GATE FAILED + reasons | 1 |
The gate fails on:
- CRITICAL findings above
--max-critical - HIGH findings above
--max-high - SBOM quality below
--min-quality - Any unresolved license, unless
--allow-unresolvedis passed
Defaults are --max-critical 0, --max-high 0, --min-quality 0 — the strictest sensible
posture. Out of the box the gate blocks on any critical or high finding. A programme that wants
a looser posture must state it explicitly in the pipeline command, and that statement then lives
in version control, which is exactly where a compliance policy should be recorded.
:::info Why unresolved licenses fail by default
An unresolved license is not a risk judgement — it is missing data, and missing data should
never pass silently. --allow-unresolved exists because some programmes legitimately accept
known-proprietary components, but requiring the operator to say so explicitly keeps the default
safe.
:::
All four checks are evaluated before any decision is taken, so the gate collects all reasons rather than short-circuiting on the first. An engineer reading a CI log gets the complete list of what must be fixed, not one item per run.
Wire it into the supplier-delivery pipeline so a non-conforming SBOM is rejected at intake rather than at the milestone review:
- run: node tools/cli.mjs gate sbom.json --max-critical 0 --max-high 5 --min-quality 70
What cannot run headlessly
Nothing is missing — the CLI, the MCP server and the browser all call identical pure functions. The engine contains no I/O, which is precisely why the three surfaces cannot disagree.