Docs
Reference for the leanest CLI.
Install
Requires Bun. The CLI runs the TypeScript source directly; there is no build step.
bun add -D leanest
Configuration
leanest loads .env from the current directory. Environment variables:
| Variable | Description | Default |
|---|---|---|
| LEANEST_PROVIDER | Judge provider to use: classifier-dev, jev, or laya. | classifier-dev |
| TYPESAFE_API_KEY | API key for the jev provider. Unused by classifier-dev and laya. | (none) |
| TYPESAFE_API_BASE | Base URL for the jev provider. | https://api.typesafe.ai/v1 |
| TYPESAFE_MODEL | Model name for the jev provider. | jev-latest |
Commands
| leanest playwright | Select, then actually run Playwright on the selection. |
| leanest vitest | Select, then actually run Vitest on the selection. |
| leanest select playwright | Show the selection only, run nothing. |
| leanest inspect playwright | Rank every test by relevance, for debugging. |
Flags
| --base <ref> | Base branch to diff against. Default main. |
| --dir <path> | Target directory. Default the current one. |
| --changed | Diff the working tree instead of a branch. |
| --json | Machine-readable output. |
| --shadow | Run the full suite, but log what would have been skipped. |
| --full | Skip selection, run everything. |
Judge providers
Set with LEANEST_PROVIDER.
| Name | Description | Key required |
|---|---|---|
| classifier-dev (default) | classifier.dev, a free zero-shot classifier | none |
| jev | TypeSafe's Jev, over HTTP | TYPESAFE_API_KEY |
| laya | Laya, self-hosted, runs in-process via ONNX Runtime | none |
LEANEST_PROVIDER=jev npx leanest playwright
CI integration
GitHub Actions:
.github/workflows/test.yml
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: baronunread/leanest@v1
with:
framework: playwright
# defaults to classifier-dev: free, no key needed typesafe-api-key is only needed when
provider is set to jev.
Any other CI system: install and run the CLI directly.
bun add -g leanest leanest playwright --base origin/main
Behavior
- Fail open. A missing or invalid provider key, an API timeout, or a malformed response runs the full suite and prints why, instead of silently skipping coverage.
- Deterministic overrides. A test always runs,
regardless of the judge's answer, if: its own file changed, it statically imports a
changed file, or it navigates a route a changed file's path names (e.g.
page.goto("/admin/users")against a changedroutes/admin/users.tsx). - No changes detected. When the diff is empty (e.g. a pure CI or config change with no application code), every test is evaluated conservatively rather than skipped outright.
- No server. The CLI calls the selected provider directly with your credentials, if any. Nothing routes through leanest's own infrastructure, because there isn't any.