All notable changes to @testsprite/testsprite-cli are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
test cancel <run-id...>— user-initiated cancel of in-flight runs (the real stop button; Ctrl-C only detaches). A single id renders the run card with statuscancelled(plus an advisory when it was already cancelled); multiple ids print a{cancelled, alreadyCancelled, conflicts, notFound}summary. Exit codes: 4 when any id is not found, else 6 on conflicts, else 0.--dry-runsupported.- Graceful Ctrl-C during
--wait— SIGINT/SIGTERM now detaches cleanly instead of killing the process mid-poll: the in-flight request aborts immediately, stdout gets the same partial{runId, status: "running"}envelope as the request-timeout path, and stderr states the truth — the server-side run keeps executing (and billing) — with a re-attach hint and atest cancelpointer. Exit 130/143/129 per the documented signal contract; a second signal forces a hard exit. Interrupting never cancels the server-side run — that's whattest cancelis for. project delete <project-id> --confirm— permanently delete a project and everything under it (its frontend/backend sub-projects, all their tests, and backend fixtures), mirroring the Portal's cascade delete. Requires--confirm(the CLI never prompts);--dry-runpreviews the response shape without a network call. Standard exit codes: 0 success, 3 auth, 4 not-found (or already-deleted), 5 validation (e.g. missing--confirm).- Backend stdout and traceback in results —
test resultand the failure bundle now surface the backend test's captured stdout and Python traceback: full content in--output json(and inresult.json/failure.jsonbundle files), and a bounded 20-line tail with a byte count in text mode. No change for frontend tests, passing runs, or older backends. - Backend dependency declarations are now readable and editable —
test getsurfacesproduces/consumes/category, andtest updateaccepts--produces/--needs/--category(previously create-only). - Version-compatibility handshake — the CLI reads the backend's advertised minimum-supported-version on every response and prints a one-line upgrade advisory on stderr when the running version is below the floor (honors the same opt-outs as the update notice; never alters exit status). A
CLIENT_TOO_OLDrejection (HTTP 426) is now a first-class error: exit 14, non-retriable, rendered with upgrade guidance and the version gap. - V3 routing visibility —
auth statusanddoctorrender arouting: v2|v3line when the backend reports the account's routing, and V3-routed accounts get one consolidated advisory listing the known V3-path behavior gaps. Text mode only — JSON consumers readv3Enabledfrom the/mepayload; absent-safe against older backends.
- The
testsprite-verifyagent skill routes local-only changes to the TestSprite MCP — the skill now states the reachability gate explicitly: the CLI verifies reachable deployed URLs only; when the change is only running locally, the skill hands off to the TestSprite MCP when available (an explicitly named tool always wins), instead of failing against localhost.
project create --descriptionnow fails fast with a clear validation error — projects have no description field, so the flag's value was previously dropped silently; the error points at test-level descriptions (test create --description) instead.- Standalone backend run cards no longer show a misleading step summary —
test run/test wait/test reruncards for backend tests rendersteps: n/a (backend)instead of0/0 (passed=0, failed=0)(backend tests have no per-step storage).
0.3.0 - 2026-07-08
testsprite doctor— one-command environment diagnostic that checks your Node version, credentials, endpoint reachability, and installed agent skills, and reports what's misconfigured.test scaffold— emit a schema-correct starter plan (frontend) or a backend test skeleton to bootstrap a new test without hand-writing the JSON.test lint— offline validator for plan / steps files; catches malformed test definitions before they are sent to the server.test diff <run-a> <run-b>— compare two runs of the same test to isolate what changed between a passing and a failing run.test flaky <test-id>— repeat-run flaky-test detector. Replays a test N times (--runs, default 5), aggregates the outcomes, and reports a stability verdict (stable/flaky/failing) plus therunIdandfailureKindof every attempt that did not pass. Replays run with auto-heal off (strict verbatim) so a nondeterministic pass/fail can't be masked. Exit code is 0 only when every attempt passed, so CI can gate a merge on flakiness. Flags:--runs(1–10),--until-fail,--timeout,--output json.- JUnit XML report export for batch runs.
test run --alland batchtest rerunaccept--report junit --report-file <path>to write a CI-friendly XML sidecar after--waitpolling completes. The report is written even when the batch exits non-zero;--output jsonis unchanged;--dry-runwrites a canned sample without network calls. test waitis now variadic — pass several run ids to attach to and poll multiple runs in a single invocation.agent status— report which TestSprite skills are installed for each agent target and whether they are current; installed skills are now stamped with a version/hash marker.- New
agent installtargets: GitHub Copilot, Windsurf, and Kiro (experimental), alongside the existing Claude / Cursor / Cline / Codex / Antigravity targets. project credential/project auto-auth— configure a project's backend credentials (static credential, free) or a recurring auto-auth token (Pro) from the CLI, with surfaced auth warnings and managed-credential guidance.- Proxy support — the CLI now honors
HTTPS_PROXY/HTTP_PROXY/NO_PROXYfor use behind corporate and CI proxies. NO_COLORsupport — colored output is suppressed whenNO_COLORis set, per no-color.org.- "New version available" notice — a non-blocking, 24h-cached npm version check prints an upgrade hint on stderr. Opt out with the documented env var; automatically silenced in CI and under
--output json.
- Node.js 20.19+, 22.13+, or 24+ is now the minimum supported runtime. The CLI checks the running Node version at startup and exits with a clear message on an unsupported version; builds and CI run against Node 20 and 22.
- Graceful shutdown — the CLI handles termination signals cleanly and guards against broken-pipe (
EPIPE) errors when its output is piped to a closing consumer (e.g.| head). - Interactive prompts and preamble now go to stderr, keeping stdout pure for machine consumers even in interactive mode.
- Empty environment variables are treated as unset when resolving config, so
TESTSPRITE_API_URL=no longer overrides the built-in default with an empty string. agent installdefaults--targettoclaudein non-interactive / CI contexts (matchingsetup).- The
usagecommand no longer implies backend test runs are free. setup's "Next steps" guidance no longer suggeststest listbefore any project exists.
- Timeouts & polling:
RequestTimeoutErroris now classified as a timeout in the--all --waitfan-out; per-attempt timeout timers are cleared so they can't fire late;run --all --waitno longer polls still-queued runs past the shared deadline; a partial result is emitted on stdout whenrun --wait/test waittimes out (so a redirected file is never zero-byte). - Batch rerun: the exit code is preserved and auth errors escalate correctly; explicit ids combined with
--all— or--status/--skip-terminalwithout--all— are rejected with a clear validation error; auto-minted idempotency keys are surfaced under--output json. - HTTP: non-JSON
200responses map to a typed error envelope instead of crashing the parser. - Failure bundles / artifacts: artifact downloads retry on transient errors and guard the default run-id path; the
--outdirectory no longer sweeps unrelated pre-existing files (data-loss fix); run-scoped per-step error text and step type are surfaced. - Input validation (fail fast, before any network call): malformed API keys, invalid
--request-timeout, directory--code-file/--outpaths, blank or whitespace-only--name(test and project create/update), blank inline project passwords, fractional pagination flags / page sizes, and--sinceoverflow are all rejected up front withVALIDATION_ERRORrather than crashing or failing late server-side.--outputis validated uniformly across all command groups. - Setup / auth: the endpoint is validated before the key check; the typed API-error envelope is preserved when key verification fails; the per-request timeout is honored during
configure. - Misc: cursor pagination no longer drops empty pages; trailing-dot hostnames are treated as loopback by the local-target guard; buffered input is preserved between interactive prompts; the Codex managed-section skill check requires a complete section;
code getstrips a leading BOM and rejects an empty--out.
- INI injection: CR/LF characters are stripped from credential values before they are written to
~/.testsprite/credentials. - Symlink fail-close: the own-file
agent installpath applies its symlink containment guard under--dry-runas well, so a planted symlink cannot place or clobber files outside--dir.
0.2.0 - 2026-06-29
- Seed-suite onboarding skill.
agent installnow installs a second skill by default —testsprite-onboard— which guides your coding agent to create a first test suite in a repository that doesn't have one yet (alongside the existingtestsprite-verifyskill). Useagent install --skill <name>to install only a specific subset.
test resultnow reports the test verdict and execution status as separate fields. The latest-result output gains averdictfield (the run's pass / fail / blocked judgement) and anexecutionStatusfield (how the run terminated);summaryis now a human-readable string.- Breaking change to
--output json:summarywas previously an object ({ passed, failed, skipped }). Scripts that readsummary.passed/.failed/.skippedmust move to the newverdict/executionStatusfields. The legacystatusfield is unchanged.
- Breaking change to
project create,project update, andtest run --allnow print the[dry-run] sample response — not from the serverbanner under--dry-run, consistent with every other command.- The CLI no longer suggests TypeScript/JavaScript test code is supported — TestSprite runs all test code as Python.
- Security (failure-bundle writer):
test failure getandtest artifact getnow validate the response's step index and evidence kind before composing file paths, so a malformed or hostile API response can no longer write files outside the chosen--outdirectory. test create --type backendandtest code putnow reject a non-Python--code-fileimmediately with a clear validation error, instead of failing late server-side.test failure get --outis validated before the network call;test code get --outnow writes atomically (no truncation if the fetch fails); artifact downloads retry on transient transport errors.- Clearer validation messages for malformed
--endpoint-urlvalues and profile names; argument-parse errors now emit a structured JSON envelope under--output json. - Batch rerun dispatch is de-duplicated and serialized.
0.1.2 - 2026-06-19
testsprite setup— the onboarding command is now namedsetup(formerlyinit): configure your API key, verify it, and install the verification-loop skill for your coding agent in one shot. The oldinitname keeps working as a hidden, deprecated alias.
- Onboarding consolidation —
setupis now the single credential-writing command. The former granular commands are kept as hidden, deprecated aliases:auth configure→setup,auth whoami→auth status,auth logout→auth remove. - The CLI now reports its version in the
User-Agentheader on each request.
0.1.1 - 2026-06-12
- README: point the launch video at the updated public asset. Docs-only release — no code changes.
0.1.0 - 2026-06-10
-
testsprite init— one-shot onboarding command that chainsauth configure→auth whoami→agent installin a single interactive invocation. Accepts--from-env,--yes, and--agent <target>for non-interactive and CI use. -
agent install/agent list— write a ready-made TestSprite verification-loop skill file into your project so your coding agent knows the commands, the exit codes, and the failure-bundle layout. Pure-local command: no network, no credentials. Supported targets:claude(GA),codex,cursor,cline,antigravity(experimental). Thecodextarget uses managed-section mode that writes a sentinel-delimited block insideAGENTS.mdwithout clobbering surrounding content.--forcebacks up existing own-file targets before overwriting. -
auth configure/auth whoami/auth logout— API-key management.--from-envreadsTESTSPRITE_API_KEYfor non-interactive setup. Credentials stored at~/.testsprite/credentials(INI, mode0600). -
project list/project get— cursor-paginated project listing and single-project lookup. -
test list/test get— cursor-paginated test listing under a project (with--status,--type,--created-fromfilters) and single-test lookup. -
test create— create a frontend or backend test. Backend tests supply a code file directly (--code-file); frontend tests use--code-fileor generate from a plan-steps document (--plan-from). The--run --waitflags chain create → trigger → poll in one invocation. Dependency metadata flags for backend tests:--produces <var>(repeatable),--needs <var>(repeatable),--category <str>. -
test create-batch— bulk-create frontend tests from a JSONL plan file (--plans) or a directory of plan files (--plan-from-dir). Optional--run --max-concurrency <N>fans out triggers. -
test update <test-id>/test delete <test-id>/test delete-batch— metadata update (name, description) and permanent hard-delete of one or many tests.--confirmis required for destructive operations.test delete-batchsupports--all --project <id>and--status <list>for bulk targeted deletes. -
test code get <test-id>/test code put <test-id>— read the generated test source and replace it with etag-guarded optimistic concurrency (--expected-version, or--forceto skip the guard). -
test plan put <test-id>— replace a frontend test's plan-steps with a refined plan. Optional--expected-step-countdrift guard. -
project create/project update— manage projects from the CLI. Both commands pre-flight--target-urlagainst local addresses for fast feedback. -
test steps <test-id>— list a test's run steps with screenshot and DOM-snapshot pointers.--run-id <id>filters to the steps of one specific run. Without the flag, returns the cumulative step log across all runs with an advisory when steps span multiple runs. -
test result <test-id>— latest result: status, started/finished timestamps, video URL, step summary counts (passed / failed / skipped), and correlation fields (snapshotId,runId,codeVersion).--include-analysisadds an inline root-cause hypothesis, recommended fix target, and failure kind. -
test result <test-id> --history— list a test's prior runs (newest-first). Filters:--source cli|portal|mcp|schedule|github_action,--since 24h|7d|ISO,--page-size,--cursor. Each row carriesrunId,status,source,isRerun, timestamps,codeVersion, andfailureKind. A note is shown in place of a blank table for tests created before run-history tracking began. -
test failure get <test-id>— the agent entry point. Returns one self-consistent failure bundle: the failing step and its immediate neighbors with screenshots and DOM snapshots, the test source, the video pointer, a root-cause hypothesis, a recommended fix target, and correlation metadata. Every artifact in the bundle shares a singlesnapshotId; the CLI refuses to stitch data from different runs or code versions.--out <dir>writes the bundle atomically to disk.--failed-onlykeeps only the failing step and its neighbors. -
test failure summary <test-id>— one-screen triage card (status, failure kind, root-cause hypothesis, recommended fix target) without downloading media. -
test run <test-id>— trigger a fresh run. Without--wait, prints{ runId, status: "queued", … }and exits 0. With--wait, polls until terminal; exit 0 onpassed, exit 1 onfailed | blocked | cancelled, exit 7 on timeout with anextActionpointing attest wait <runId>. Accepts--target-url,--timeout,--idempotency-key. -
test run --all --project <id>— wave-ordered fresh batch run for all (or filtered) backend tests in a project. Routes to a batch endpoint; response enumeratesaccepted[],conflicts[],deferred[],skippedFrontend[], andskippedIntegration[]so a machine consumer readingacceptedalone can't silently undercount.--waitpolls all dispatched run IDs concurrently. -
test rerun [test-id…]— cheap replay of one or more tests. Frontend reruns replay the saved script verbatim (AI heal-on-drift is on by default, opt out with--no-auto-heal). Backend reruns expand the producer/teardown dependency closure; use--skip-dependenciesfor just the named test.--all --project <id>reruns every test in a project. Returnsaccepted[]plusdeferred[]for any tests shed by the per-key run-rate limit; under--wait, a non-emptydeferred[]exits 7 with a retry hint. -
test wait <run-id>— block until a run reaches a terminal status. Resumes polling after a timed-outtest run --wait, or when an agent already has arunId. Uses server-driven long-poll where supported; exponential backoff withRetry-Afterotherwise. -
test artifact get <run-id>— download the failure bundle for a specific run, addressed byrunIdinstead oftestId. Enforcesmeta.runId === <run-id>as an integrity check; exits 5 on mismatch. Default output directory:./.testsprite/runs/<run-id>/. -
--dry-run(global) — every command runs end-to-end without touching the network, credentials, or the local filesystem; emits canned data matching the API contract. -
Global flags:
--profile,--output json|text,--endpoint-url,--request-timeout <seconds>,--verbose,--debug. -
Pagination flags on every list:
--page-size,--starting-token,--max-items. -
--debugHTTP tracing to stderr (method, URL, request-id, latency, retry decisions). The API key is never included. -
Dashboard URL in outputs — commands that know both
projectIdandtestIdinclude adashboardUrldeep-link to the TestSprite web portal in JSON output. Text mode: create paths print aDashboard:line on stderr; run-completion output (test run --wait,test wait,test rerun --wait,test run --all) ends the run card with adashboardline on stdout. The portal domain is resolved from the configured API endpoint per environment. -
TTY-gated progress ticker — single-line in-place
\x1b[2K\rupdates during polling on TTY; completely silent on non-TTY (CI) and when--output jsonis set. -
AWS-CLI-style exit-code taxonomy — see Exit codes in README.
-
blockedis a distinct top-level status alongsidefailed(was collapsed intofailedin earlier previews). Triage routes:blocked→ infra (stale seed, login failure, unreachable target), not bug. -
test failure get/test stepsnow synthesize a terminalassertionstep row when no individual step is in error but the test failed at the assertion or overall-outcome layer. Previously the bundle shippedsteps: []for these tests. Synthetic rows have no screenshot or DOM snapshot. -
outcomeContributesToFailureboolean on every step row (nullwhen unclassified). The text renderer prefixes contributing rows with*so a 50-step list highlights which rows the failure landed on. -
failureKindenum widened: addsassertion_blocked,routing_404, andnetwork_timeout(previously these collapsed intounknown). The CLI accepts unrecognized values from the wire asunknownso new enum values are non-breaking. -
recommendedFixTargetreturnsnull(not anunknownwrapper) when the analysis pipeline produced no fill. Applied uniformly to/result?includeAnalysis,/failure, and/failure summary. -
Test.detailsdebug block ships a structuredprocessingStatus/testStatuspair alongside the previousrawStatusstring (deprecated but preserved for the transition window). -
test create --run/--wait/--timeout/--target-urlfully wired: chainsPOST /tests→POST /tests/{testId}/runs→GET /runs/{runId}in one invocation.--target-urlpre-flighted against local addresses on the client (exit 5) before the request is sent. -
Auto-minted idempotency keys and request IDs are suppressed by default; exposed under
--verbosefor retry and support use. -
Per-request wall-clock timeout (
--request-timeout, default 120 s) applied to every outgoing fetch. Under--wait, the per-request timeout is auto-raised to cover--timeout+ 5 s so a large batch under load is never cut at the default. -
test run --waitauto-resumes on 409run_in_flightby polling the existing run instead of exiting 6. An advisory is printed to stderr. Other conflict reasons and body-mismatch conflicts still propagate as exit 6. -
Backend test
test run --wait/test rerun --waitinclude a fallback path that readsGET /tests/{id}/resultwhen the run row is not yet finalized server-side, so the verdict is reachable without waiting for a timeout. -
test rerunbatch--waitsummary enumeratesdeferredandconflictscounts alongsidetotal(dispatched) so machine readers can't silently undercount.
-
parseEnvelopeBodynow recognizes NestJS raw 404 shape, surfacing the originalCannot POST /api/cli/v1/…message so the user sees which endpoint isn't deployed on the current backend rather than a generic "Server error." message. -
test run --waitCONFLICT auto-resume is gated ondetails.reason === 'run_in_flight'only. When--target-urlis supplied and the in-flight run's URL differs, the CLI fetches the existing run's URL and reports a descriptive conflict (exit 6) withnextAction: testsprite test wait <runId>. -
test stepsnow surfaces the synthetic terminalassertionstep row for assertion-only failures (previously this row was wired only fortest failure getandtest failure summary). -
test create-batch --plan-from-dir: theMAX_BATCH_SPECS(50) cap is enforced on valid specs after non-plan JSON files are skipped, not on the raw directory entry count. The duplicate-name advisory lookup uses a bounded 5-second deadline so a stalled listing endpoint delaystest createby at most 5 s. -
localValidationErrorandApiError.getDetail<T>()are shared library helpers; redundant inline cast patterns removed from call sites. -
engine-strict=truein.npmrcsonpm installhard-fails on Node < 20 instead of warning and proceeding. -
Commander
help [command]exits 0 (previously exited 5 ontest help/project help).