Installation
This page covers:
- The one-line install command for Linux / macOS / Windows.
- Direct binary download and the escape-hatch alternative.
- Where the binary lands.
- Two sanity checks —
novetest --versionandnovetest --help. - Environment overrides, re-install, and uninstall.
Nove Test ships as a single self-contained binary — a PyApp bundle that embeds CPython 3.11 plus the novetest wheel — so the binary path needs no Python toolchain on your machine. The install script always resolves the latest release unless you pin one; the current version is listed on the GitHub Releases page.
1. The install command
The install scripts are hosted at ailovestesting.com/products/novetest/ — a byte-identical mirror of scripts/install.sh / scripts/install.ps1 in the public repo. Use the branded URL (shorter, canonical to share); the GitHub Raw URL shown under each is the same script straight from source. Either URL works.
Linux + macOS
curl -fsSL https://ailovestesting.com/products/novetest/install.sh | shDirect from source (identical bytes):
curl -fsSL https://raw.githubusercontent.com/Nove-Lab/Nove-Test/main/scripts/install.sh | shWindows (PowerShell)
irm https://ailovestesting.com/products/novetest/install.ps1 | iexDirect from source (identical bytes):
irm https://raw.githubusercontent.com/Nove-Lab/Nove-Test/main/scripts/install.ps1 | iexBoth scripts are idempotent (re-running upgrades in place via atomic rename), sudo-free (write to ~/.local/bin/), and abort loudly on a SHA-256 mismatch rather than write a partial binary.
Inspect-first (recommended for first-time users)
# Linux / macOS
curl -fsSL -o install.sh \
https://raw.githubusercontent.com/Nove-Lab/Nove-Test/main/scripts/install.sh
less install.sh # read it
sh install.sh# Windows
irm https://raw.githubusercontent.com/Nove-Lab/Nove-Test/main/scripts/install.ps1 -OutFile install.ps1
Get-Content install.ps1 # read it
.\install.ps1What the install script does, step by step
- Detects OS + arch.
Resolves the GitHub Release asset name:
- Linux × x86_64 ->
novetest-linux-x86_64 - Linux × aarch64 ->
novetest-linux-aarch64 - macOS (any arch) ->
novetest-macos-universal2(one fat binary covering Intel + Apple Silicon) - Windows × x86_64 ->
novetest-windows-x86_64.exe
- Linux × x86_64 ->
- Downloads the binary and its
.sha256sidecar. - Computes SHA-256 locally (
sha256sum/shasum/openssl/Get-FileHash). - Compares to the sidecar. Mismatch -> loud abort; nothing is written under the install prefix.
- Atomically renames the verified binary into
~/.local/bin/novetest. - Tests whether the install prefix is on
PATH; if not, prints a one-line hint.
The script needs a downloader (curl or wget) and a SHA-256 tool.
Supported platforms
| OS | Arch | Asset |
|---|---|---|
| Linux | x86_64 | novetest-linux-x86_64 |
| Linux | aarch64 | novetest-linux-aarch64 |
| macOS | universal2 (Intel + Apple Silicon) | novetest-macos-universal2 |
| Windows | x86_64 | novetest-windows-x86_64.exe |
Linux i686 / armv7l and Windows arm64 are not built.
Linux hosts have a glibc floor. The binaries bundle a CPython built against a specific glibc, and each release states its minimum in its release notes. For every release up to and including 0.2.1 that minimum is glibc 2.39, so on an older host (Debian 12 "bookworm" 2.36, Ubuntu 22.04 LTS 2.35 — including the official node image family, which is bookworm-based) the install succeeds but the binary refuses to start with version 'GLIBC_2.39' not found. From v0.3.0 the floor drops to glibc 2.31 — most hosts the earlier floor excluded, including both of the ones just named, now work; see the Troubleshooting glibc entry for the full host table. Check yours with ldd --version; below the floor, use the Python-tooling install in §2, which runs on your own Python and is not subject to it. Full recovery steps: Troubleshooting -> Install issues.
Where the binary lives
| OS | Default path |
|---|---|
| Linux | ~/.local/bin/novetest |
| macOS | ~/.local/bin/novetest |
| Windows | %USERPROFILE%\.local\bin\novetest.exe |
Override with NOVETEST_INSTALL_PREFIX=... if you need elsewhere.
If ~/.local/bin is not on your PATH
# Linux / macOS (~/.bashrc, ~/.zshrc)
export PATH="$HOME/.local/bin:$PATH"# Windows (PowerShell profile)
$env:PATH = "$HOME\.local\bin;$env:PATH"Then source the profile (or open a new shell) and re-check.
Pinning a specific version
NOVETEST_INSTALL_VERSION=v0.1.2 \
curl -fsSL https://raw.githubusercontent.com/Nove-Lab/Nove-Test/main/scripts/install.sh | shThe default (latest) resolves the most recent GitHub Release at install time. Pinning a tag gives deterministic, reproducible installs — recommended for CI pipelines and agent-managed hosts.
2. Other ways to install
Direct binary download (no script)
base=https://github.com/Nove-Lab/Nove-Test/releases/latest/download
target=novetest-linux-x86_64 # or linux-aarch64 / macos-universal2 / windows-x86_64
curl -fsSLO "$base/$target"
curl -fsSLO "$base/$target.sha256"
sha256sum -c "$target.sha256" # must say: OK
chmod +x "$target" && mv "$target" ~/.local/bin/novetestThe install scripts above are the only recommended install path; the direct binary download covers environments where piping to a shell is forbidden by policy. Escape hatch beyond both (no prebuilt binary for your platform, a Linux host below the binaries' glibc floor, or a PyPI-mirror-only network): a Python-tooling install — uv tool install novetest / pipx install novetest (Python >= 3.11). There is no Homebrew, Docker, npm, or cargo distribution.
3. Sanity check #1 — novetest --version
The shortest round-trip to confirm the binary works. It reports the CLI identity envelope; on a TTY the same values render as text.
novetest --versionThe reported identity (JSON shown for clarity):
{
"command": "version",
"data": {
"commandName": "novetest",
"installLocation": "~/.local/share/pyapp/novetest/7904589091198436804/0.3.1/bin/python3",
"installedVersion": "0.3.1",
"platform": "linux-x86_64",
"pythonVersion": "3.11.9",
"verifiedAt": "2026-08-05T01:44:37.415596Z"
},
"errors": [],
"ok": true,
"schema": "novetest/v1",
"warnings": []
}| Field | Meaning |
|---|---|
installedVersion | CLI version — the latest release unless you pinned one at install time (this capture was taken on 0.3.1). |
commandName | Always novetest. |
installLocation | Path on disk of the interpreter your novetest runs as. On a curl-pipe-sh binary install it lives inside PyApp's per-install cache under your home directory (shown here with ~; the long numeric install-id segment differs on every machine). You did not create or manage it. |
pythonVersion | The bundled CPython 3.11.x — you did not install it. |
platform | {system}-{machine}, lowercased. |
verifiedAt | ISO-8601 UTC timestamp of when this identity envelope was generated (i.e. when you ran --version) — not a build time; it changes every invocation. |
Exit code: 0. If you see a stack trace or nothing at all, see Troubleshooting.
NOVETEST_OUTPUT=json novetest --versionCaptured envelope from a clean binary install of 0.3.1 (the per-machine installLocation home is shown as ~; every other field is verbatim):
{
"command": "version",
"data": {
"commandName": "novetest",
"installLocation": "~/.local/share/pyapp/novetest/7904589091198436804/0.3.1/bin/python3",
"installedVersion": "0.3.1",
"platform": "linux-x86_64",
"pythonVersion": "3.11.9",
"verifiedAt": "2026-08-05T01:44:37.415596Z"
},
"errors": [],
"ok": true,
"schema": "novetest/v1",
"warnings": []
}Top-level keys are exactly {schema, command, ok, data, errors, warnings} (emitted sorted) — there is no top-level version, verb, or exit_code. Gate version-dependent behavior on data.installedVersion; confirm identity with data.commandName == "novetest". Route platform assumptions on data.platform.
Exit code: 0. There is no other expected exit code for --version.
4. Sanity check #2 — novetest --help
The list of every verb the CLI exposes. novetest --help and bare novetest (no args) are equivalent — bare novetest prints help, it does not run tests.
novetest --helpReal output, grouped into two sections:
novetest — AI-first testing orchestration
Onboarding:
novetest --version Print CLI identity envelope.
novetest --help Print command surface envelope.
novetest init Initialize a Project Store under .novetest/ in the current workspace.
novetest reset Wipe the active Project Store and re-initialize (requires --confirm).
Operating:
novetest test Run tests with integrated orchestration and synthesize a recommendation.
novetest run Execute a Test Target via the native engine and persist a Run Record.
novetest memory list List Memory Entries in Run History.
novetest memory show Show a Memory Entry by Run Reference.
novetest memory delete Tombstone a Memory Entry; Run Reference remains resolvable.
novetest inspect Aggregate run view across Memory and derived facts.
novetest status Latest run plus per-sub-report availability summary.
novetest coverage show Show Coverage Facts for a run.
novetest coverage diff Diff Coverage Facts between two runs.
novetest regression compare Compare two runs into a Regression Fact set.
novetest regression latest Compute Regression Facts versus the latest baseline.
novetest compare Composed Regression and Coverage delta between two runs.
novetest localization Ranked suspicious code locations for a run.
novetest localization latest Ranked suspicious code locations for the latest analyzable run.
novetest replay Re-execute a stored run and classify reproducibility.
novetest licenses List third-party components Nove Test redistributes or links to.- Onboarding — verbs you run once to come online:
--version,--help,init, andreset. - Operating — the verbs you use during normal work.
novetest testis the headline; everything else is either a deeper view (inspect,status) or a power-user surface (coverage,regression,localization,replay,memory).
Exit code: 0.
NOVETEST_OUTPUT=json novetest --helpEmits the command surface envelope — the canonical way for an agent to discover verbs without grepping docs. Real output (data.operating truncated; elided items are real, not invented):
{
"command": "help",
"data": {
"onboarding": [
{ "availableInPhase": 0, "group": "onboarding", "name": "novetest --version", "summary": "Print CLI identity envelope." },
{ "availableInPhase": 0, "group": "onboarding", "name": "novetest --help", "summary": "Print command surface envelope." },
{ "availableInPhase": 1, "group": "onboarding", "name": "novetest init", "summary": "Initialize a Project Store under .novetest/ in the current workspace." },
{ "availableInPhase": 7, "group": "onboarding", "name": "novetest reset", "summary": "Wipe the active Project Store and re-initialize (requires --confirm)." }
],
"operating": [
{ "availableInPhase": 6, "group": "orchestration", "name": "novetest test", "summary": "Run tests with integrated orchestration and synthesize a recommendation." },
{ "availableInPhase": 1, "group": "run", "name": "novetest run", "summary": "Execute a Test Target via the native engine and persist a Run Record." }
/* ... also: memory list/show/delete, inspect, status, coverage show/diff,
regression compare/latest, compare, localization, localization latest,
replay, licenses */
],
"schemaVersion": 1
},
"errors": [],
"ok": true,
"schema": "novetest/v1",
"warnings": []
}Two arrays under data: onboarding[] (--version, --help, init, reset) and operating[] (the 16 work verbs). Each item carries name, summary, group, and availableInPhase; the pair (group, name) is stable — rely on it for dispatch. Discover verbs from data.operating[*].name instead of hard-coding them; do not gate on availableInPhase (informational, not a capability flag).
Exit code: 0.
5. Environment overrides
Install-script variables (script-only; they do not affect the CLI at runtime):
| Variable | Default | What it does |
|---|---|---|
NOVETEST_INSTALL_PREFIX | ~/.local/bin | Where the binary is placed during install. |
NOVETEST_INSTALL_VERSION | latest | A tag like v0.1.2 to pin to during install. |
NOVETEST_INSTALL_REPO | Nove-Lab/Nove-Test | GitHub owner/repo for URL composition. |
NOVETEST_INSTALL_BASE_URL | (GitHub Releases) | Override the download base URL. |
Runtime output mode:
| Variable | Default | What it does |
|---|---|---|
NOVETEST_OUTPUT | auto (text on TTY, json when piped) | Force text / json / ndjson output. |
Precedence rule:
explicit --output flag > NOVETEST_OUTPUT env > TTY auto-detect6. Verifying a clean install
The two sanity checks above are enough. If novetest --version and novetest --help both print clean output and exit 0, move on to the Quick Start. If something looks off, jump to Troubleshooting -> Install issues.
A minimal pre-flight probe — copy into your agent's startup:
# 1) Binary on PATH
command -v novetest || { echo "novetest missing"; exit 1; }
# 2) Version envelope round-trips
NOVETEST_OUTPUT=json novetest --version \
| jq -e '.ok == true and .schema == "novetest/v1"' \
|| { echo "version envelope malformed"; exit 1; }
# (gate on .data.installedVersion only if you pinned a version at install time)
# 3) Help envelope enumerates the operating surface
NOVETEST_OUTPUT=json novetest --help | jq -e '.data.operating | length >= 15' \
|| { echo "help envelope shrunk unexpectedly"; exit 1; }If all three pass, you can drive novetest.
7. Re-install and uninstall
- Re-install / upgrade: re-run the same install command. The script always overwrites with the verified binary via atomic rename.
- Uninstall:
rm ~/.local/bin/novetest(Linux/macOS) orRemove-Item $HOME\.local\bin\novetest.exe(Windows). The CLI keeps no state outside per-project.novetest/directories, so removing the binary removes the CLI entirely.
To delete a specific project's history (without touching its source or tests):
cd /path/to/project
novetest reset --confirm # wipe + re-initialize the Project Store
# or remove it outright:
rm -rf .novetest/Caveats pinned by the MVP
- First-run cold start is on the order of 5–15 seconds (PyApp unpacks its embedded Python once per binary version). Subsequent invocations are warm and fast.
- The SHA-256 check is a real integrity gate: a mismatch aborts and writes nothing.
- The binary bundles CPython 3.11; a Python
>= 3.11requirement applies only to theuv/pipxescape hatch (see §2).
What to read next
- Quick Start — the 4-step canonical happy path:
init->test-> read the recommendation -> (optional)inspect. - Supported Languages — if your project is not Python, the one-line toolchain difference your engine needs before you
novetest init. - Troubleshooting — if a sanity check didn't return clean output.