Local-first license compliance scanner. Find AGPL / GPL / SSPL contamination in your codebase — including the bits Copilot, Cursor, and friends quietly pasted in — before your acquirer does.
# Scan the current directory locally — no signup, no upload
npx licenseleak scan .
# Scan a remote GitHub repo via the hosted API (requires an API key)
npx licenseleak login
npx licenseleak scan https://github.com/your-org/your-reposcan exits with code 1 if any critical finding is present (override
with --fail-on high|medium|low|none), so you can drop it into a pre-commit
hook or any CI without copy-pasting YAML.
| Command | Description |
|---|---|
licenseleak scan <path-or-url> |
Scan a local path (default) or a https://github.com/... URL. |
licenseleak login |
Save an API key to ~/.licenseleak/config.json (mode 0600). |
licenseleak logout |
Remove the saved API key. |
licenseleak whoami |
Print the account, plan, and credit balance for the saved key. |
licenseleak --help |
Full flag reference. |
--remote— force a remote scan even when given a local-looking path.--branch <name>— branch to scan (remote only).--format <text|json>— emit a structured JSON report for piping into other tooling. Same shape as the hosted API's findings response.--fail-on <critical|high|medium|low|none>— exit-code threshold. Defaultcritical.--no-hints— suppress the one-line "scanned offline" hint printed after a successful local scan in text mode. Useful for CI logs and power users.
Remote uploads (licenseleak scan <path>, with auto-remote on, or
--remote) walk your working directory and apply two ignore files:
.gitignore— read from the repo root, matchinggit check-ignoresemantics (anchoring,dir/directory-only,!negation)..licenseleakignore— same syntax as.gitignore, additive on top. Use it to exclude paths you want git to track but don't want LicenseLeak to scan (e.g. vendored fixtures, generated test snapshots, one specific package in a monorepo). A!patternline can re-include a path that.gitignorewould have excluded.
The CLI prints a one-line summary to stderr after packing:
excluded 142 file(s) by .gitignore, 7 by .licenseleakignore
The active .licenseleakignore patterns and per-source counts are sent
with the upload, persisted on the scan record, embedded in the signed
manifest, and shown under "Exclusions" in the public HTML / PDF report
so anyone reviewing the report can see exactly what scope you scanned.
The CLI reads its API key from, in order:
LICENSELEAK_API_KEYenvironment variable.~/.licenseleak/config.json(created bylicenseleak login, file mode0600).
Generate a key from the
Settings → API keys page.
The key is sent as Authorization: Bearer ll_live_….
The default licenseleak scan <path> command is fully offline: it reads
manifests and lockfiles from disk, classifies them locally, and prints the
result. No source code, dependency list, telemetry, or update check is sent
anywhere.
Outbound HTTP requests are made only by the following commands and flags:
| Trigger | Endpoint | What is sent |
|---|---|---|
licenseleak scan https://github.com/... |
Hosted API (POST /api/scans) |
The repo URL and optional branch name. |
licenseleak scan <path> --remote |
Hosted API (POST /api/scans/upload) |
A gzipped tarball of your working directory, plus the active .licenseleakignore patterns and per-source excluded-file counts (sent as X-Licenseleak-Ignore-Patterns / X-Licenseleak-Excluded-Counts headers and embedded in the signed manifest). |
licenseleak whoami |
Hosted API (GET /api/me) |
Your API key, to look up account / plan / credits. |
licenseleak login and licenseleak logout make no network calls — they
only read/write ~/.licenseleak/config.json (mode 0600). The saved key
is then used by the commands above.
That is the complete list. No other command, flag, or code path in this CLI opens a network connection. There is no telemetry, no auto-update check, no crash reporter, no analytics beacon.
- Local (default for paths): walks the directory's manifests and lockfiles for npm, pip, go, cargo, ruby, and php; classifies each dependency by SPDX license family; reports any non-permissive match. No source code or telemetry is uploaded anywhere. Best for a fast pre-commit sniff test.
- Remote (default for
https://URLs, or--remote): submits the repo URL to the hosted scanner, which performs deep AST fingerprinting against a copyleft corpus and produces a signed PDF. Polls until terminal and prints the same colorized table.
| Code | Meaning |
|---|---|
0 |
Scan completed and no finding met the --fail-on threshold. |
1 |
Scan completed and at least one finding met the threshold. |
2 |
Scanner error, auth failure, invalid arguments. |
Apache-2.0 — see LICENSE.
This repository (licenseleak/cli) is a one-way release mirror of
packages/cli/ from the LicenseLeak monorepo. Each tagged release on
npm lands here as a single
commit (with a back-reference to the upstream commit SHA), and a matching
vX.Y.Z git tag.
- Issues and discussions: open them on this repo — https://github.com/licenseleak/cli/issues
- Pull requests: also welcome on this repo. Accepted PRs are replayed upstream by the maintainers and shipped in the next release.
- The hosted scanner, similarity engine, benchmark corpus, and signed- report pipeline live in the private monorepo and are not part of this package — the CLI is a thin client that calls the LicenseLeak API for remote scans and runs a deterministic SPDX classifier locally.