@vertaaux/cli 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/MIGRATION.md +239 -0
  3. package/README.md +62 -17
  4. package/dist/app/interactive-app.d.ts +103 -0
  5. package/dist/app/interactive-app.d.ts.map +1 -0
  6. package/dist/app/interactive-app.js +328 -0
  7. package/dist/app/layout/canvas.d.ts +23 -0
  8. package/dist/app/layout/canvas.d.ts.map +1 -0
  9. package/dist/app/layout/canvas.js +36 -0
  10. package/dist/app/layout/footer.d.ts +31 -0
  11. package/dist/app/layout/footer.d.ts.map +1 -0
  12. package/dist/app/layout/footer.js +41 -0
  13. package/dist/app/layout/header.d.ts +20 -0
  14. package/dist/app/layout/header.d.ts.map +1 -0
  15. package/dist/app/layout/header.js +27 -0
  16. package/dist/app/menu/categories.d.ts +20 -0
  17. package/dist/app/menu/categories.d.ts.map +1 -0
  18. package/dist/app/menu/categories.js +166 -0
  19. package/dist/app/menu/filter.d.ts +17 -0
  20. package/dist/app/menu/filter.d.ts.map +1 -0
  21. package/dist/app/menu/filter.js +33 -0
  22. package/dist/app/menu/menu-view.d.ts +35 -0
  23. package/dist/app/menu/menu-view.d.ts.map +1 -0
  24. package/dist/app/menu/menu-view.js +230 -0
  25. package/dist/app/menu/recent.d.ts +24 -0
  26. package/dist/app/menu/recent.d.ts.map +1 -0
  27. package/dist/app/menu/recent.js +49 -0
  28. package/dist/app/types.d.ts +43 -0
  29. package/dist/app/types.d.ts.map +1 -0
  30. package/dist/app/types.js +7 -0
  31. package/dist/app/views/command-runner.d.ts +36 -0
  32. package/dist/app/views/command-runner.d.ts.map +1 -0
  33. package/dist/app/views/command-runner.js +415 -0
  34. package/dist/app/views/help-overlay.d.ts +21 -0
  35. package/dist/app/views/help-overlay.d.ts.map +1 -0
  36. package/dist/app/views/help-overlay.js +46 -0
  37. package/dist/auth/ci-token.d.ts +8 -2
  38. package/dist/auth/ci-token.d.ts.map +1 -1
  39. package/dist/auth/ci-token.js +15 -30
  40. package/dist/auth/device-flow.d.ts +2 -1
  41. package/dist/auth/device-flow.d.ts.map +1 -1
  42. package/dist/auth/device-flow.js +13 -10
  43. package/dist/auth/token-store.d.ts.map +1 -1
  44. package/dist/auth/token-store.js +12 -2
  45. package/dist/baseline/diff.d.ts +2 -2
  46. package/dist/baseline/diff.d.ts.map +1 -1
  47. package/dist/baseline/diff.js +15 -34
  48. package/dist/commands/a11y.d.ts +11 -0
  49. package/dist/commands/a11y.d.ts.map +1 -0
  50. package/dist/commands/a11y.js +149 -0
  51. package/dist/commands/audit/artifacts.d.ts +27 -0
  52. package/dist/commands/audit/artifacts.d.ts.map +1 -0
  53. package/dist/commands/audit/artifacts.js +158 -0
  54. package/dist/commands/audit/ci-detection.d.ts +18 -0
  55. package/dist/commands/audit/ci-detection.d.ts.map +1 -0
  56. package/dist/commands/audit/ci-detection.js +71 -0
  57. package/dist/commands/audit/explain.d.ts +11 -0
  58. package/dist/commands/audit/explain.d.ts.map +1 -0
  59. package/dist/commands/audit/explain.js +45 -0
  60. package/dist/commands/audit/filters.d.ts +17 -0
  61. package/dist/commands/audit/filters.d.ts.map +1 -0
  62. package/dist/commands/audit/filters.js +40 -0
  63. package/dist/commands/audit/index.d.ts +18 -0
  64. package/dist/commands/audit/index.d.ts.map +1 -0
  65. package/dist/commands/audit/index.js +589 -0
  66. package/dist/commands/audit/output.d.ts +32 -0
  67. package/dist/commands/audit/output.d.ts.map +1 -0
  68. package/dist/commands/audit/output.js +129 -0
  69. package/dist/commands/audit/policy.d.ts +27 -0
  70. package/dist/commands/audit/policy.d.ts.map +1 -0
  71. package/dist/commands/audit/policy.js +147 -0
  72. package/dist/commands/audit/scoring.d.ts +23 -0
  73. package/dist/commands/audit/scoring.d.ts.map +1 -0
  74. package/dist/commands/audit/scoring.js +70 -0
  75. package/dist/commands/audit/types.d.ts +89 -0
  76. package/dist/commands/audit/types.d.ts.map +1 -0
  77. package/dist/commands/audit/types.js +8 -0
  78. package/dist/commands/audit.d.ts +2 -60
  79. package/dist/commands/audit.d.ts.map +1 -1
  80. package/dist/commands/audit.js +2 -1097
  81. package/dist/commands/baseline.d.ts +2 -0
  82. package/dist/commands/baseline.d.ts.map +1 -1
  83. package/dist/commands/baseline.js +221 -123
  84. package/dist/commands/comment.d.ts +22 -0
  85. package/dist/commands/comment.d.ts.map +1 -1
  86. package/dist/commands/comment.js +127 -62
  87. package/dist/commands/compare.d.ts +17 -0
  88. package/dist/commands/compare.d.ts.map +1 -1
  89. package/dist/commands/compare.js +288 -181
  90. package/dist/commands/diff.d.ts +7 -0
  91. package/dist/commands/diff.d.ts.map +1 -1
  92. package/dist/commands/diff.js +181 -143
  93. package/dist/commands/doc.d.ts +10 -0
  94. package/dist/commands/doc.d.ts.map +1 -1
  95. package/dist/commands/doc.js +135 -77
  96. package/dist/commands/doctor.d.ts +2 -0
  97. package/dist/commands/doctor.d.ts.map +1 -1
  98. package/dist/commands/doctor.js +166 -19
  99. package/dist/commands/download.d.ts +10 -0
  100. package/dist/commands/download.d.ts.map +1 -1
  101. package/dist/commands/download.js +169 -112
  102. package/dist/commands/explain.d.ts +5 -0
  103. package/dist/commands/explain.d.ts.map +1 -1
  104. package/dist/commands/explain.js +242 -156
  105. package/dist/commands/fix-all.d.ts +25 -0
  106. package/dist/commands/fix-all.d.ts.map +1 -0
  107. package/dist/commands/fix-all.js +206 -0
  108. package/dist/commands/fix-plan.d.ts +9 -0
  109. package/dist/commands/fix-plan.d.ts.map +1 -1
  110. package/dist/commands/fix-plan.js +154 -90
  111. package/dist/commands/fix.d.ts +17 -0
  112. package/dist/commands/fix.d.ts.map +1 -0
  113. package/dist/commands/fix.js +111 -0
  114. package/dist/commands/init.d.ts +11 -0
  115. package/dist/commands/init.d.ts.map +1 -1
  116. package/dist/commands/init.js +94 -42
  117. package/dist/commands/login.d.ts +18 -0
  118. package/dist/commands/login.d.ts.map +1 -1
  119. package/dist/commands/login.js +263 -92
  120. package/dist/commands/patch-review.d.ts +11 -0
  121. package/dist/commands/patch-review.d.ts.map +1 -1
  122. package/dist/commands/patch-review.js +160 -98
  123. package/dist/commands/policy.d.ts +31 -0
  124. package/dist/commands/policy.d.ts.map +1 -1
  125. package/dist/commands/policy.js +270 -125
  126. package/dist/commands/release-notes.d.ts +10 -0
  127. package/dist/commands/release-notes.d.ts.map +1 -1
  128. package/dist/commands/release-notes.js +128 -74
  129. package/dist/commands/scan.d.ts +13 -0
  130. package/dist/commands/scan.d.ts.map +1 -0
  131. package/dist/commands/scan.js +133 -0
  132. package/dist/commands/status.d.ts +9 -0
  133. package/dist/commands/status.d.ts.map +1 -0
  134. package/dist/commands/status.js +81 -0
  135. package/dist/commands/suggest.d.ts +10 -0
  136. package/dist/commands/suggest.d.ts.map +1 -1
  137. package/dist/commands/suggest.js +180 -83
  138. package/dist/commands/triage.d.ts +35 -0
  139. package/dist/commands/triage.d.ts.map +1 -1
  140. package/dist/commands/triage.js +207 -82
  141. package/dist/commands/upload.d.ts +9 -0
  142. package/dist/commands/upload.d.ts.map +1 -1
  143. package/dist/commands/upload.js +140 -101
  144. package/dist/commands/verify.d.ts +13 -0
  145. package/dist/commands/verify.d.ts.map +1 -0
  146. package/dist/commands/verify.js +118 -0
  147. package/dist/config/schema.d.ts +4 -0
  148. package/dist/config/schema.d.ts.map +1 -1
  149. package/dist/index.d.ts +3 -2
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/index.js +127 -991
  152. package/dist/interactive/fix-wizard.d.ts +3 -0
  153. package/dist/interactive/fix-wizard.d.ts.map +1 -1
  154. package/dist/interactive/fix-wizard.js +130 -112
  155. package/dist/interactive/init-wizard.d.ts +3 -1
  156. package/dist/interactive/init-wizard.d.ts.map +1 -1
  157. package/dist/interactive/init-wizard.js +207 -138
  158. package/dist/interactive/prompts.d.ts +7 -3
  159. package/dist/interactive/prompts.d.ts.map +1 -1
  160. package/dist/interactive/prompts.js +44 -23
  161. package/dist/output/envelope.d.ts +9 -0
  162. package/dist/output/envelope.d.ts.map +1 -1
  163. package/dist/output/envelope.js +37 -3
  164. package/dist/output/factory.d.ts +2 -1
  165. package/dist/output/factory.d.ts.map +1 -1
  166. package/dist/output/html.d.ts +2 -1
  167. package/dist/output/html.d.ts.map +1 -1
  168. package/dist/output/html.js +3 -2
  169. package/dist/output/human.d.ts +2 -1
  170. package/dist/output/human.d.ts.map +1 -1
  171. package/dist/output/human.js +3 -2
  172. package/dist/output/json.d.ts +2 -1
  173. package/dist/output/json.d.ts.map +1 -1
  174. package/dist/output/junit.d.ts +2 -1
  175. package/dist/output/junit.d.ts.map +1 -1
  176. package/dist/output/sarif.d.ts +2 -1
  177. package/dist/output/sarif.d.ts.map +1 -1
  178. package/dist/policy/schema.d.ts +137 -0
  179. package/dist/policy/schema.d.ts.map +1 -1
  180. package/dist/policy/schema.js +107 -0
  181. package/dist/prompts/command-catalog.js +9 -9
  182. package/dist/types.d.ts +74 -0
  183. package/dist/types.d.ts.map +1 -0
  184. package/dist/types.js +5 -0
  185. package/dist/ui/banner.d.ts +34 -0
  186. package/dist/ui/banner.d.ts.map +1 -1
  187. package/dist/ui/banner.js +97 -5
  188. package/dist/ui/diagnostics.d.ts +9 -4
  189. package/dist/ui/diagnostics.d.ts.map +1 -1
  190. package/dist/ui/diagnostics.js +32 -82
  191. package/dist/ui/strings.d.ts +373 -0
  192. package/dist/ui/strings.d.ts.map +1 -0
  193. package/dist/ui/strings.js +499 -0
  194. package/dist/ui/table.d.ts +0 -2
  195. package/dist/ui/table.d.ts.map +1 -1
  196. package/dist/ui/table.js +3 -4
  197. package/dist/utils/api-client.d.ts +46 -0
  198. package/dist/utils/api-client.d.ts.map +1 -0
  199. package/dist/utils/api-client.js +170 -0
  200. package/dist/utils/client.d.ts +29 -18
  201. package/dist/utils/client.d.ts.map +1 -1
  202. package/dist/utils/client.js +104 -12
  203. package/dist/utils/formatters.d.ts +38 -0
  204. package/dist/utils/formatters.d.ts.map +1 -0
  205. package/dist/utils/formatters.js +277 -0
  206. package/dist/utils/root-args.d.ts +12 -0
  207. package/dist/utils/root-args.d.ts.map +1 -0
  208. package/dist/utils/root-args.js +44 -0
  209. package/dist/utils/stdin.d.ts +7 -0
  210. package/dist/utils/stdin.d.ts.map +1 -1
  211. package/dist/utils/stdin.js +32 -2
  212. package/dist/utils/url-classify.d.ts.map +1 -1
  213. package/dist/utils/url-classify.js +24 -3
  214. package/node_modules/@vertaaux/tui/dist/index.cjs +1216 -27
  215. package/node_modules/@vertaaux/tui/dist/index.cjs.map +1 -1
  216. package/node_modules/@vertaaux/tui/dist/index.d.cts +361 -4
  217. package/node_modules/@vertaaux/tui/dist/index.d.ts +361 -4
  218. package/node_modules/@vertaaux/tui/dist/index.js +1189 -27
  219. package/node_modules/@vertaaux/tui/dist/index.js.map +1 -1
  220. package/node_modules/@vertaaux/tui/package.json +2 -3
  221. package/node_modules/chalk/license +9 -0
  222. package/node_modules/chalk/package.json +83 -0
  223. package/node_modules/chalk/readme.md +297 -0
  224. package/node_modules/chalk/source/index.d.ts +325 -0
  225. package/node_modules/chalk/source/index.js +225 -0
  226. package/node_modules/chalk/source/utilities.js +33 -0
  227. package/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
  228. package/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
  229. package/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
  230. package/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
  231. package/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
  232. package/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
  233. package/package.json +20 -5
  234. package/dist/commands/client.d.ts +0 -14
  235. package/dist/commands/client.d.ts.map +0 -1
  236. package/dist/commands/client.js +0 -362
  237. package/dist/commands/drift.d.ts +0 -15
  238. package/dist/commands/drift.d.ts.map +0 -1
  239. package/dist/commands/drift.js +0 -309
  240. package/dist/commands/protect.d.ts +0 -16
  241. package/dist/commands/protect.d.ts.map +0 -1
  242. package/dist/commands/protect.js +0 -323
  243. package/dist/commands/report.d.ts +0 -15
  244. package/dist/commands/report.d.ts.map +0 -1
  245. package/dist/commands/report.js +0 -214
  246. package/dist/policy/sync.d.ts +0 -67
  247. package/dist/policy/sync.d.ts.map +0 -1
  248. package/dist/policy/sync.js +0 -147
package/CHANGELOG.md ADDED
@@ -0,0 +1,116 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@vertaaux/cli` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.5.1] - 2026-04-07
11
+
12
+ ### Added
13
+
14
+ - **`--profile <name>` flag on `vertaa audit`** — Phase 1.5 of audit profiles is now live on npm. `vertaa audit <url> --profile wcag-aa` (and any profile with a `categories` subset) 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 passes `profile.categories` in the POST body via `apiRequest` when a category subset is resolved; the SDK path is used when no subset applies. See `cli/tests/commands/audit-handler.test.ts` for coverage.
15
+ - **`a11y` command upgrade** — `vertaa a11y <url>` now calls the dedicated `/v1/a11y/audit` endpoint with multi-engine analysis (axe-core + AccessLint + custom analyzers). Added `--mode`, `--fail-on-score`, `--min-impact`, and `--fail-on-findings` flags.
16
+ - **Source tracking** — All CLI-triggered audits now include `source: "cli"` metadata for dashboard visibility.
17
+
18
+ ### Fixed
19
+
20
+ - **Profile-filtered categories now report `null` instead of a false `100`** — Excluded categories in `scores` are `null` (not a fabricated "perfect 100" from `calculateScore([])`). `metadata.filtered_categories` lists profile exclusions; `metadata.skipped_checks` is reserved for runtime failures. `metadata.partial` stays `false` for profile-filtered audits. Server-side fix shipped in PR #375; this release gets it onto the npm-published CLI output path.
21
+
22
+ ### Changed
23
+
24
+ - **SDK upgraded to `@vertaaux/sdk@2.0.0`** — Updated to match v2 API surface with snake_case parameter conventions.
25
+ - **Machine-mode hardening** — Payload output routes consistently through the data writer; enveloped JSON input is unwrapped uniformly across `baseline`, `comment`, and `diff` commands.
26
+
27
+ ## [0.5.0] - 2026-03-19
28
+
29
+ ### Added
30
+
31
+ - **Interactive terminal app** — full-screen menu-driven interface with keyboard navigation, live dashboard, and canvas layout (launched via `vertaa` with no args)
32
+ - **@vertaaux/tui package** — terminal UI primitives (spinner, table, progress, box, error-box, step-list, viewport) bundled into the CLI
33
+ - **PTY test infrastructure** — node-pty based terminal tests with ANSI serializers, xterm-256color emulation, and dedicated vitest config
34
+ - **Subprocess test infrastructure** — process-level E2E tests with build caching, mock audit server, and contract validation
35
+ - **Snapshot test infrastructure** — long-running compilation snapshot tests with NO_COLOR determinism
36
+ - **Package install tests** — artifact validation via `npm pack` and tarball installation
37
+ - **Cross-platform CI matrix** — Ubuntu/macOS/Windows × Node 20/22 in `cli-e2e.yml` workflow
38
+ - **1953 unit tests** across 112 test files covering commands, auth, config, output, security, caching, CI detection, monorepo support, and quality gates
39
+ - **Credential file support** — reads API key from `~/.vertaaux/credentials.json` as fallback (with symlink and permission checks)
40
+ - **Error propagation improvements** — unhandled errors in command handlers now produce exit code 2 with branded error boxes
41
+
42
+ ### Changed
43
+
44
+ - **Commander upgraded to v14** — from v12, with improved help formatting and error handling
45
+ - **Vitest upgraded to v4** — from v3, with `fileParallelism: false` replacing deprecated `poolOptions.forks.singleFork`
46
+ - **Error rendering** — all command errors now render through `renderError()` with suggestion hints and proper exit codes
47
+
48
+ ### Fixed
49
+
50
+ - **Flaky TTY detection** in subprocess tests
51
+ - **Fetch resource leak** — unclosed responses in API client
52
+ - **Timer cleanup** — lingering timers in polling commands
53
+ - **ESLint compliance** — replaced `require()` calls with string concatenation for no-require-imports rule
54
+
55
+ ### Security
56
+
57
+ - **Symlink check on credentials** — refuses to read `~/.vertaaux/credentials.json` if it's a symlink (SECVAL-1)
58
+ - **Permission check on credentials** — warns if file permissions are overly permissive on Unix systems (SECVAL-2)
59
+
60
+ ## [0.4.0] - 2026-02-15
61
+
62
+ ### Added
63
+
64
+ - **Localhost/private URL auditing** via static HTML analysis
65
+ - `whoami` command shows name, email, and plan
66
+
67
+ ## [0.3.3] - 2026-02-10
68
+
69
+ ### Fixed
70
+
71
+ - Documentation accuracy improvements
72
+
73
+ ## [0.3.0] - 2026-02-08
74
+
75
+ ### Added
76
+
77
+ - **AI Intelligence commands** — `suggest`, `triage`, `fix-plan`, `patch-review`, `release-notes`, `compare`, `doc`
78
+ - **Pipeline input** — all AI commands accept stdin pipe, `--file`, or `--job`
79
+ - Per-command format validation with format registry
80
+ - JSON output envelope with metadata
81
+ - `--machine` flag for strict machine-readable output
82
+ - Branded error messages with typo suggestions
83
+ - `doctor` command for CLI health diagnostics
84
+ - Exit code 3 for threshold breaches
85
+
86
+ ### Changed
87
+
88
+ - `--format` moved from global to per-command option
89
+ - Diagnostic output moved to stderr (stdout reserved for format output)
90
+ - Strict input validation with exit code 2
91
+
92
+ ## [0.2.0] - 2026-01-25
93
+
94
+ ### Added
95
+
96
+ - Per-command format system
97
+ - JSON output envelope
98
+ - `--machine` flag
99
+ - `doctor` command
100
+ - Levenshtein suggestions for enum flags
101
+ - Branch name validation
102
+ - Artifact path traversal protection
103
+
104
+ ### Changed
105
+
106
+ - Breaking: `--format` is now per-command
107
+ - Breaking: JSON output wrapped in envelope
108
+ - Breaking: diagnostics moved to stderr
109
+ - Breaking: strict input validation (exit code 2)
110
+ - Breaking: exit code 3 for threshold breach (was 1)
111
+
112
+ [0.5.0]: https://github.com/PetriLahdelma/vertaa/compare/cli-v0.4.0...cli-v0.5.0
113
+ [0.4.0]: https://github.com/PetriLahdelma/vertaa/compare/cli-v0.3.3...cli-v0.4.0
114
+ [0.3.3]: https://github.com/PetriLahdelma/vertaa/compare/cli-v0.3.0...cli-v0.3.3
115
+ [0.3.0]: https://github.com/PetriLahdelma/vertaa/compare/cli-v0.2.0...cli-v0.3.0
116
+ [0.2.0]: https://github.com/PetriLahdelma/vertaa/releases/tag/cli-v0.2.0
package/MIGRATION.md ADDED
@@ -0,0 +1,239 @@
1
+ # VertaaUX CLI Migration Guide
2
+
3
+ ## Upgrading to v0.5.0
4
+
5
+ This release adds the interactive terminal app, credential file support, and a major test infrastructure overhaul. One behavior change: running `vertaa` with no arguments now launches an interactive app instead of printing help — see below for migration.
6
+
7
+ ### New: Interactive App
8
+
9
+ Running `vertaa` with no arguments now launches a full-screen interactive menu. If you have scripts that run `vertaa` with no args and expect help output, add `--help` explicitly:
10
+
11
+ ```bash
12
+ # Before (printed help)
13
+ vertaa
14
+
15
+ # After (launches interactive app)
16
+ vertaa
17
+
18
+ # To get help output in scripts
19
+ vertaa --help
20
+ ```
21
+
22
+ ### New: Credential File Fallback
23
+
24
+ The CLI now reads API keys from `~/.vertaaux/credentials.json` when neither `VERTAAUX_API_KEY` nor `--api-key` is set. This file is created by `vertaa login`.
25
+
26
+ Auth resolution order: `VERTAAUX_API_KEY` env var → `apiKey` in config file (`.vertaaux.yml`) → `~/.vertaaux/credentials.json`.
27
+
28
+ If you relied on the CLI failing when no env var was set (e.g., to detect missing CI configuration), be aware that stored credentials on the machine may now be used as a fallback. To ensure no credentials are used, point `HOME` (or `USERPROFILE` on Windows) to an empty directory.
29
+
30
+ ### New: Error Rendering
31
+
32
+ Unhandled errors in command handlers now produce branded error boxes on stderr with a `vertaa doctor` suggestion, instead of raw stack traces. Exit codes are unchanged (still 2 for errors).
33
+
34
+ ### Dependency Changes
35
+
36
+ | Dependency | Before | After |
37
+ |-----------|--------|-------|
38
+ | `commander` | ^12.x | ^14.0.2 |
39
+ | `@vertaaux/tui` | — | bundled |
40
+ | `node-pty` | — | ^1.1.0 (dev) |
41
+ | `vitest` | ^3.x | ^4.0.15 (dev) |
42
+
43
+ ### Security Hardening
44
+
45
+ - Credentials file is rejected if it's a symlink
46
+ - Warning emitted if credentials file permissions are too open (non-Windows)
47
+
48
+ These checks are transparent — no action needed unless you store credentials as symlinks.
49
+
50
+ ## Upgrading to v0.4.0
51
+
52
+ ### Added
53
+
54
+ - Localhost and private URL auditing via static HTML analysis
55
+ - `whoami` shows name, email, and plan tier
56
+
57
+ No breaking changes.
58
+
59
+ ## Upgrading to v0.2.0
60
+
61
+ This release includes several breaking changes from the CLI hardening phases (36-39). Most changes improve correctness and safety -- existing scripts using standard patterns will work without modification.
62
+
63
+ ### Breaking Changes
64
+
65
+ #### 1. Format Flag Scope Changed
66
+
67
+ **Before:** `--format` was a global flag applied to all commands.
68
+
69
+ **After:** `--format` is a per-command option with different allowed values per command.
70
+
71
+ | Command | Allowed Formats | Default |
72
+ |---------|----------------|---------|
73
+ | `audit` | `human`, `json`, `sarif`, `junit`, `html` | `human` |
74
+ | `comment` | `json`, `markdown` | `markdown` |
75
+ | `explain` | `human`, `json` | `human` |
76
+ | `policy show` | `json`, `yaml` | `yaml` |
77
+ | `diff` | `human`, `json` | `human` |
78
+
79
+ **Migration:**
80
+
81
+ Move `--format` from before the command to after it:
82
+
83
+ ```bash
84
+ # Before
85
+ vertaa --format json audit https://example.com
86
+
87
+ # After
88
+ vertaa audit https://example.com --format json
89
+ ```
90
+
91
+ Using an unsupported format for a command now exits with code 2:
92
+
93
+ ```bash
94
+ vertaa comment --format sarif # Error: Invalid format "sarif" for "comment"
95
+ ```
96
+
97
+ #### 2. JSON Output Wrapped in Envelope
98
+
99
+ **Before:** JSON output was a raw data object.
100
+
101
+ **After:** JSON output is wrapped in an envelope containing metadata.
102
+
103
+ ```json
104
+ // Before
105
+ {
106
+ "scores": { "overall": 85 },
107
+ "issues": [...]
108
+ }
109
+
110
+ // After
111
+ {
112
+ "meta": {
113
+ "version": "0.3.2",
114
+ "timestamp": "2026-02-08T12:00:00.000Z",
115
+ "command": "audit",
116
+ "args": ["https://example.com", "--format", "json"]
117
+ },
118
+ "data": {
119
+ "scores": { "overall": 85 },
120
+ "issues": [...]
121
+ }
122
+ }
123
+ ```
124
+
125
+ **Migration:**
126
+
127
+ Update JSON parsers to access `.data` instead of the top level:
128
+
129
+ ```bash
130
+ # Before
131
+ cat results.json | jq '.scores.overall'
132
+
133
+ # After
134
+ cat results.json | jq '.data.scores.overall'
135
+ ```
136
+
137
+ ```javascript
138
+ // Before
139
+ const result = JSON.parse(output);
140
+ console.log(result.scores.overall);
141
+
142
+ // After
143
+ const envelope = JSON.parse(output);
144
+ console.log(envelope.data.scores.overall);
145
+ // Bonus: envelope.meta.version, envelope.meta.timestamp available
146
+ ```
147
+
148
+ #### 3. Diagnostic Output Moved to stderr
149
+
150
+ **Before:** Banners, progress indicators, and diagnostic messages were mixed into stdout.
151
+
152
+ **After:** Only format output goes to stdout. All diagnostics go to stderr.
153
+
154
+ **Migration:**
155
+
156
+ If you were parsing stdout and filtering out banners, you can now pipe directly:
157
+
158
+ ```bash
159
+ # Before (required filtering)
160
+ vertaa audit https://example.com --format json 2>/dev/null | grep -v "VertaaUX" | jq .
161
+
162
+ # After (clean piping)
163
+ vertaa audit https://example.com --format json | jq .
164
+ ```
165
+
166
+ If you were capturing stderr for errors, note that progress and banner output now also goes to stderr.
167
+
168
+ #### 4. Strict Input Validation
169
+
170
+ **Before:** Invalid flag values were silently accepted or caused confusing runtime errors.
171
+
172
+ **After:** Invalid values are rejected immediately with exit code 2 and clear error messages.
173
+
174
+ ```bash
175
+ # Numeric validation
176
+ vertaa audit https://example.com --timeout abc
177
+ # error: expected a number, got "abc"
178
+ # Exit code: 2
179
+
180
+ # Enum validation with suggestions
181
+ vertaa audit https://example.com --mode depp
182
+ # error: invalid value for --mode
183
+ # hint: Did you mean "deep"?
184
+ # valid: basic, standard, deep
185
+ # Exit code: 2
186
+
187
+ # Range validation
188
+ vertaa audit https://example.com --threshold 150
189
+ # error: expected 0-100, got 150
190
+ # Exit code: 2
191
+ ```
192
+
193
+ **Migration:**
194
+
195
+ No action needed unless your scripts intentionally pass invalid values. Scripts that were relying on invalid values being silently ignored will now fail with exit code 2.
196
+
197
+ #### 5. Branch Name Sanitization
198
+
199
+ **Before:** Any string was accepted as a branch name in `--base-branch`.
200
+
201
+ **After:** Branch names are validated against `/^[a-zA-Z0-9._\/-]+$/` with a maximum length of 255 characters. Shell metacharacters are rejected.
202
+
203
+ **Migration:**
204
+
205
+ No action needed for standard git branch names. If you have branches with unusual characters, they will be rejected.
206
+
207
+ ```bash
208
+ # These work fine
209
+ vertaa audit --incremental --base-branch main
210
+ vertaa audit --incremental --base-branch feature/my-feature
211
+ vertaa audit --incremental --base-branch release/v1.2.3
212
+
213
+ # These are now rejected
214
+ vertaa audit --incremental --base-branch "main; rm -rf /"
215
+ vertaa audit --incremental --base-branch 'feat$(whoami)'
216
+ ```
217
+
218
+ ### New Features
219
+
220
+ | Feature | Description |
221
+ |---------|-------------|
222
+ | `vertaa doctor` | Diagnose CLI health (config, auth, network connectivity) |
223
+ | `--config <path>` | Explicit config file path (overrides auto-detection) |
224
+ | `--machine` | Strict machine-readable output mode (JSON stdout, diagnostics stderr) |
225
+ | Levenshtein suggestions | Typo corrections for enum flags (e.g., `depp` suggests `deep`) |
226
+ | Branded errors | Box-drawn error frames with flag/value context and help hints |
227
+ | `--force` on init | Overwrite existing `.vertaaux.yml` configuration |
228
+ | `--yes` on init | Skip interactive prompts, use defaults |
229
+
230
+ ### Exit Code Changes
231
+
232
+ | Code | Before | After |
233
+ |------|--------|-------|
234
+ | `0` | Success | Success (unchanged) |
235
+ | `1` | Issues found | Issues found (unchanged) |
236
+ | `2` | Error | Error AND validation errors (expanded) |
237
+ | `3` | - | Threshold breach (new) |
238
+
239
+ Exit code 2 now covers all validation errors (previously some caused exit code 1 or undefined behavior). Exit code 3 is new for `--threshold` breaches (previously used exit code 1).
package/README.md CHANGED
@@ -29,22 +29,40 @@ vertaa doctor
29
29
 
30
30
  ## Authentication
31
31
 
32
- The CLI checks for credentials in this order:
32
+ The CLI uses the `@vertaaux/sdk` for all API calls. The SDK handles auth automatically — you
33
+ only need to configure credentials once. Three methods are supported:
33
34
 
34
- 1. **Environment variables** (checked in order):
35
- - `VERTAAUX_TOKEN`
36
- - `VERTAAUX_API_KEY`
35
+ ### 1. Default credentials (recommended)
37
36
 
38
- 2. **Stored credentials** from interactive login:
39
- ```bash
40
- vertaa login
41
- ```
42
- Credentials are stored in `~/.vertaaux/credentials.json`.
37
+ Run `vertaa login` to store credentials in `~/.vertaaux/credentials.json`. The SDK reads
38
+ these on every subsequent command — no flags needed.
43
39
 
44
- 3. **Direct token** for CI/non-interactive use:
45
- ```bash
46
- vertaa login --token <api-key>
47
- ```
40
+ ```bash
41
+ vertaa login
42
+ ```
43
+
44
+ This stores credentials for SDK-based auth. Use `vertaa whoami` to verify.
45
+
46
+ ### 2. Environment variable
47
+
48
+ Set `VERTAAUX_API_KEY` (or `VERTAAUX_TOKEN`) in your shell or CI environment. The SDK
49
+ reads this automatically on every command.
50
+
51
+ ```bash
52
+ export VERTAAUX_API_KEY=vtx_...
53
+ vertaa audit https://example.com --wait
54
+ ```
55
+
56
+ ### 3. `--api-key` flag (override for scripts and CI)
57
+
58
+ Pass `--api-key <key>` to any command to override SDK auth for that invocation. This is
59
+ intended for CI pipelines where the key comes from a secret manager or is passed inline.
60
+
61
+ ```bash
62
+ VERTAAUX_API_KEY=${{ secrets.VERTAAUX_API_KEY }} vertaa audit https://example.com
63
+ ```
64
+
65
+ **Auth priority:** `--api-key` flag > `VERTAAUX_API_KEY` env > `VERTAAUX_TOKEN` env > stored credentials.
48
66
 
49
67
  Verify authentication:
50
68
 
@@ -101,11 +119,27 @@ All AI commands require authentication (`vertaa login` or `VERTAAUX_API_KEY`). T
101
119
  | `upload <file>` | Upload audit results to cloud storage |
102
120
  | `download <id>` | Download audit results from cloud storage |
103
121
 
122
+ ### Accessibility
123
+
124
+ | Command | Description |
125
+ |---------|-------------|
126
+ | `a11y <url>` | Multi-engine accessibility audit (axe-core + AccessLint + custom analyzers) |
127
+
128
+ The `a11y` command uses a dedicated API endpoint (`/v1/a11y/audit`) and returns WCAG-mapped findings with structured fix suggestions and fixability ratings.
129
+
130
+ | Option | Description |
131
+ |--------|-------------|
132
+ | `--mode <basic\|standard\|deep>` | Audit depth (default: `basic`) |
133
+ | `--min-impact <minor\|moderate\|serious\|critical>` | Minimum impact level to report |
134
+ | `--fail-on-score <0-100>` | Exit 1 if accessibility score below this value |
135
+ | `--fail-on-findings <n>` | Exit 1 if critical+serious findings exceed n |
136
+ | `--format <json\|md>` | Output format (default: `json`) |
137
+ | `--timeout <ms>` | Wait timeout (default: 60000) |
138
+
104
139
  ### Aliases
105
140
 
106
141
  | Command | Alias For |
107
142
  |---------|-----------|
108
- | `a11y <url>` | Accessibility-focused audit (filters for a11y issues) |
109
143
  | `scan <url>` | UX scan (alias for audit) |
110
144
  | `compare <urlA> <urlB>` | Compare audits of two URLs (also supports `--before`/`--after` for LLM-powered comparison) |
111
145
 
@@ -116,6 +150,7 @@ Formats are **per-command**, not global. Each command supports a different set o
116
150
  | Command | Formats | Default |
117
151
  |---------|---------|---------|
118
152
  | `audit` | `human`, `json`, `sarif`, `junit`, `html` | `human` |
153
+ | `a11y` | `json`, `md` | `json` |
119
154
  | `comment` | `json`, `markdown` | `markdown` |
120
155
  | `explain` | `human`, `json` | `human` |
121
156
  | `policy show` | `json`, `yaml` | `yaml` |
@@ -147,7 +182,7 @@ The `--machine` global flag enables strict machine-readable mode:
147
182
  ```json
148
183
  {
149
184
  "meta": {
150
- "version": "0.4.0",
185
+ "version": "0.5.0",
151
186
  "timestamp": "2026-02-08T12:00:00.000Z",
152
187
  "command": "audit",
153
188
  "args": ["https://example.com", "--format", "json"]
@@ -339,8 +374,8 @@ JSON envelope output automatically filters CLI arguments containing API keys or
339
374
 
340
375
  | Variable | Purpose |
341
376
  |----------|---------|
342
- | `VERTAAUX_API_KEY` | API authentication key |
343
- | `VERTAAUX_TOKEN` | Alternative auth token (checked first) |
377
+ | `VERTAAUX_API_KEY` | API key (used by SDK; `--api-key` flag overrides this per-command) |
378
+ | `VERTAAUX_TOKEN` | Alternative auth token (checked before `VERTAAUX_API_KEY`) |
344
379
  | `VERTAAUX_API_BASE` | API base URL override |
345
380
  | `VERTAAUX_AUTH_BASE` | Auth endpoint override (default: `https://vertaaux.ai`) |
346
381
  | `VERTAAUX_LOG_LEVEL` | Log verbosity: `debug\|info\|warn\|error` (default: `info`) |
@@ -401,6 +436,16 @@ vertaa error: invalid value for --mode
401
436
  │ valid: basic, standard, deep
402
437
  ```
403
438
 
439
+ ## AI Agent Skill
440
+
441
+ Teach your AI coding agent (Claude Code, Cursor, Codex, Copilot, Gemini CLI, etc.) how to use the VertaaUX CLI:
442
+
443
+ ```bash
444
+ npx skills add VertaaUX/agent-skills
445
+ ```
446
+
447
+ Covers all CLI commands, CI/CD setup, SDK integration, and 10 use-case playbooks. Published on [skills.sh](https://skills.sh/VertaaUX/agent-skills).
448
+
404
449
  ## Related
405
450
 
406
451
  - [Migration Guide](./MIGRATION.md) -- Breaking changes in this release
@@ -0,0 +1,103 @@
1
+ /**
2
+ * InteractiveApp — Persistent 3-section interactive CLI shell.
3
+ *
4
+ * Manages a fixed layout:
5
+ * [Header] — sticky banner at top (buildFrame3)
6
+ * [Canvas] — active view content, fixed height
7
+ * [Footer] — status left, keyboard shortcuts right
8
+ *
9
+ * Uses alternate screen buffer (CSI ?1049h/l) so the layout is scroll-proof.
10
+ * Each frame redraw uses cursor.home + screen.clear — no cursor arithmetic needed.
11
+ *
12
+ * All writes go to the injected output stream (defaults to process.stderr).
13
+ * stdout is reserved for --format json output.
14
+ */
15
+ import type { CommandView, AppState } from "./types.js";
16
+ /**
17
+ * InteractiveApp provides the persistent 3-section layout for the
18
+ * `vertaa` (no-args) interactive mode.
19
+ *
20
+ * Usage:
21
+ * const app = new InteractiveApp();
22
+ * await app.run(); // blocks until Ctrl+C or app.dispose()
23
+ */
24
+ export declare class InteractiveApp {
25
+ /** @internal — exposed for testing via private access */
26
+ _state: AppState;
27
+ /**
28
+ * Whether the app is currently on the alternate screen.
29
+ * @internal — exposed for testing
30
+ */
31
+ private entered;
32
+ /** @internal — exposed for testing */
33
+ _suspended: boolean;
34
+ private output;
35
+ private tickTimer;
36
+ private resizeTimer;
37
+ private frameIndex;
38
+ private version;
39
+ private resolveRun;
40
+ /** Saved menu view so we can restore it after help overlay */
41
+ private savedMenuView;
42
+ constructor(output?: NodeJS.WritableStream);
43
+ /**
44
+ * Start the interactive app.
45
+ *
46
+ * Enters alternate screen buffer, configures stdin for raw keyboard input,
47
+ * renders the initial frame, and returns a Promise that resolves when
48
+ * dispose() is called.
49
+ */
50
+ run(): Promise<void>;
51
+ /**
52
+ * Build the complete frame string for the current state.
53
+ *
54
+ * Frame = header + canvas + footer, sized to terminal dimensions.
55
+ */
56
+ buildFrame(): string;
57
+ /**
58
+ * Redraw the terminal using home+clear on the alternate screen.
59
+ *
60
+ * Guarded by `if (!this.entered) return` — prevents double-redraw race
61
+ * when setView() calls this.redraw() after onMount() completes while
62
+ * the app is suspended (entered === false).
63
+ */
64
+ redraw(): void;
65
+ /**
66
+ * Set the active view, calling lifecycle hooks.
67
+ *
68
+ * Unmounts any existing view, mounts the new one, switches to command
69
+ * screen, and triggers an immediate redraw.
70
+ *
71
+ * NOTE: When the app is suspended (entered === false), the post-onMount
72
+ * redraw() call is a safe no-op — guarded by the `!this.entered` check.
73
+ */
74
+ setView(view: CommandView): Promise<void>;
75
+ /**
76
+ * Unmount the active view and return to the menu screen.
77
+ */
78
+ clearView(): Promise<void>;
79
+ /**
80
+ * Suspend the app — exit alternate screen and stop the tick loop.
81
+ *
82
+ * Call before launching @inquirer/prompts or running a command handler
83
+ * to hand control back to the normal terminal.
84
+ */
85
+ suspend(): void;
86
+ /**
87
+ * Resume the app — re-enter alternate screen and restart the tick loop.
88
+ *
89
+ * Call after a command handler completes to restore the interactive layout.
90
+ */
91
+ resume(): void;
92
+ /**
93
+ * Tear down the app — exits alternate screen, stops tick, removes listeners.
94
+ */
95
+ dispose(): void;
96
+ /** Get the current animation frame index (for spinner rendering in views). */
97
+ getFrameIndex(): number;
98
+ private startTick;
99
+ private stopTick;
100
+ private onResize;
101
+ private onKeyData;
102
+ }
103
+ //# sourceMappingURL=interactive-app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-app.d.ts","sourceRoot":"","sources":["../../src/app/interactive-app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAUH,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAa,MAAM,YAAY,CAAC;AAYnE;;;;;;;GAOG;AACH,qBAAa,cAAc;IACzB,yDAAyD;IACzD,MAAM,EAAE,QAAQ,CAId;IAEF;;;OAGG;IACH,OAAO,CAAC,OAAO,CAAS;IAExB,sCAAsC;IACtC,UAAU,UAAS;IAEnB,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,SAAS,CAA+C;IAChE,OAAO,CAAC,WAAW,CAA8C;IACjE,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAA6B;IAC/C,8DAA8D;IAC9D,OAAO,CAAC,aAAa,CAA4B;gBAErC,MAAM,GAAE,MAAM,CAAC,cAA+B;IAQ1D;;;;;;OAMG;IACG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB1B;;;;OAIG;IACH,UAAU,IAAI,MAAM;IA6BpB;;;;;;OAMG;IACH,MAAM,IAAI,IAAI;IAMd;;;;;;;;OAQG;IACG,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAY/C;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAUhC;;;;;OAKG;IACH,OAAO,IAAI,IAAI;IAsBf;;;;OAIG;IACH,MAAM,IAAI,IAAI;IAoBd;;OAEG;IACH,OAAO,IAAI,IAAI;IAgCf,8EAA8E;IAC9E,aAAa,IAAI,MAAM;IAMvB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,QAAQ,CAWd;IAEF,OAAO,CAAC,SAAS,CAmDf;CACH"}