@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
@@ -12,28 +12,28 @@
12
12
  * vertaa release-notes --file diff.json
13
13
  * vertaa release-notes --job-a abc --job-b def
14
14
  */
15
- import chalk from "chalk";
15
+ import { bold, dim, boldColor, brand, renderError, createRenderer, runSteps } from "@vertaaux/tui";
16
16
  import { ExitCode } from "../utils/exit-codes.js";
17
17
  import { resolveApiBase, getApiKey, apiRequest } from "../utils/client.js";
18
18
  import { resolveConfig } from "../config/loader.js";
19
- import { writeJsonOutput, writeOutput } from "../output/envelope.js";
19
+ import { writeDataOutput, writeJsonOutput } from "../output/envelope.js";
20
20
  import { resolveCommandFormat } from "../output/formats.js";
21
- import { createSpinner, succeedSpinner } from "../ui/spinner.js";
22
21
  import { readJsonInput } from "../utils/stdin.js";
23
- import { handleAiCommandError, AI_TIMEOUT_MS } from "../utils/ai-error.js";
22
+ import { AI_TIMEOUT_MS } from "../utils/ai-error.js";
23
+ import { strings } from "../ui/strings.js";
24
24
  // ---------------------------------------------------------------------------
25
25
  // Formatters
26
26
  // ---------------------------------------------------------------------------
27
27
  function formatReleaseNotesHuman(data) {
28
28
  const lines = [];
29
- lines.push(chalk.bold(data.headline));
29
+ lines.push(bold(data.headline));
30
30
  lines.push("");
31
- lines.push(chalk.bold.blue("Developer Notes"));
32
- lines.push(chalk.dim("─".repeat(40)));
31
+ lines.push(boldColor("Developer Notes", brand.teal));
32
+ lines.push(dim("─".repeat(40)));
33
33
  lines.push(data.developer_notes);
34
34
  lines.push("");
35
- lines.push(chalk.bold.green("PM / User-Facing Notes"));
36
- lines.push(chalk.dim("─".repeat(40)));
35
+ lines.push(boldColor("PM / User-Facing Notes", brand.lime));
36
+ lines.push(dim("─".repeat(40)));
37
37
  lines.push(data.pm_notes);
38
38
  return lines.join("\n");
39
39
  }
@@ -50,6 +50,111 @@ function formatReleaseNotesMarkdown(data) {
50
50
  lines.push(data.pm_notes);
51
51
  return lines.join("\n");
52
52
  }
53
+ export async function handleReleaseNotes(opts) {
54
+ const config = { apiKey: opts.apiKey };
55
+ const format = resolveCommandFormat("release-notes", opts.format, opts.machine || false);
56
+ const renderer = createRenderer("auto");
57
+ const baseState = {
58
+ phase: "release-notes",
59
+ phaseIndex: 1,
60
+ phaseTotal: 2,
61
+ url: "",
62
+ mode: "release-notes",
63
+ progress: {},
64
+ totals: {},
65
+ issueCount: 0,
66
+ scorePreview: null,
67
+ verbose: false,
68
+ elapsed: 0,
69
+ };
70
+ const startTime = Date.now();
71
+ let responseData = null;
72
+ const steps = [
73
+ {
74
+ id: "fetch",
75
+ actionText: strings.releaseNotes.generate.action,
76
+ summaryText: "History loaded",
77
+ run: async () => {
78
+ let diffPayload;
79
+ if (opts.jobA && opts.jobB) {
80
+ const base = resolveApiBase(opts.base);
81
+ const apiKey = getApiKey(config.apiKey);
82
+ const diffResult = await apiRequest(base, `/diff?job_a=${encodeURIComponent(opts.jobA)}&job_b=${encodeURIComponent(opts.jobB)}`, { method: "GET" }, apiKey);
83
+ diffPayload = diffResult.data;
84
+ }
85
+ else {
86
+ const input = await readJsonInput(opts.file);
87
+ if (!input) {
88
+ throw new Error("No diff data provided.\nUsage:\n vertaa diff --job-a abc --job-b def --json | vertaa release-notes\n vertaa release-notes --file diff.json\n vertaa release-notes --job-a abc --job-b def");
89
+ }
90
+ const data = input;
91
+ const innerData = (data.data && typeof data.data === "object" ? data.data : data);
92
+ if (!Array.isArray(innerData.new) || !Array.isArray(innerData.fixed)) {
93
+ throw new Error("Invalid diff data. Expected { new: [...], fixed: [...], summary: {...} }\nPipe from: vertaa diff --job-a abc --job-b def --json | vertaa release-notes");
94
+ }
95
+ diffPayload = {
96
+ new: innerData.new,
97
+ fixed: innerData.fixed,
98
+ present: innerData.present || null,
99
+ summary: innerData.summary || {
100
+ newCount: innerData.new.length,
101
+ fixedCount: innerData.fixed.length,
102
+ presentCount: Array.isArray(innerData.present) ? innerData.present.length : null,
103
+ },
104
+ };
105
+ }
106
+ const base = resolveApiBase(opts.base);
107
+ const apiKey = getApiKey(config.apiKey);
108
+ const response = await Promise.race([
109
+ apiRequest(base, "/cli/ai/release-notes", { method: "POST", body: { diff: diffPayload } }, apiKey),
110
+ new Promise((_, reject) => setTimeout(() => reject(new Error("LLM request timed out")), AI_TIMEOUT_MS)),
111
+ ]);
112
+ responseData = response.data;
113
+ },
114
+ },
115
+ {
116
+ id: "generate",
117
+ actionText: "Generating release notes...",
118
+ summaryText: strings.releaseNotes.generate.done(),
119
+ run: async () => {
120
+ // Notes generated in fetch step via API call
121
+ },
122
+ },
123
+ ];
124
+ const { success, states } = await runSteps(steps, {
125
+ onStateChange: (stepStates) => {
126
+ renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
127
+ },
128
+ });
129
+ renderer.finish({
130
+ url: "",
131
+ mode: "release-notes",
132
+ overallScore: success ? 100 : 0,
133
+ scores: {},
134
+ issueCount: 0,
135
+ passed: success,
136
+ elapsed: Date.now() - startTime,
137
+ });
138
+ if (!success) {
139
+ const failed = states.find(s => s.status === "failed");
140
+ process.stderr.write(renderError({
141
+ message: failed?.failReason || "Command failed",
142
+ suggestion: "vertaa doctor",
143
+ }) + "\n");
144
+ process.exitCode = ExitCode.ERROR;
145
+ }
146
+ if (success && responseData) {
147
+ if (format === "json") {
148
+ writeJsonOutput(responseData, "release-notes");
149
+ }
150
+ else if (format === "markdown") {
151
+ writeDataOutput(formatReleaseNotesMarkdown(responseData));
152
+ }
153
+ else {
154
+ writeDataOutput(formatReleaseNotesHuman(responseData));
155
+ }
156
+ }
157
+ }
53
158
  // ---------------------------------------------------------------------------
54
159
  // Command Registration
55
160
  // ---------------------------------------------------------------------------
@@ -72,73 +177,22 @@ Examples:
72
177
  const globalOpts = command.optsWithGlobals();
73
178
  const config = await resolveConfig(globalOpts.config);
74
179
  const machineMode = globalOpts.machine || false;
75
- const format = resolveCommandFormat("release-notes", options.format, machineMode);
76
- // Resolve diff data
77
- let diffPayload;
78
- if (options.jobA && options.jobB) {
79
- // Fetch diff from two jobs via the diff API
80
- const base = resolveApiBase(globalOpts.base);
81
- const apiKey = getApiKey(config.apiKey);
82
- const diffResult = await apiRequest(base, `/diff?job_a=${encodeURIComponent(options.jobA)}&job_b=${encodeURIComponent(options.jobB)}`, { method: "GET" }, apiKey);
83
- diffPayload = diffResult.data;
84
- }
85
- else {
86
- // Read from stdin or --file
87
- const input = await readJsonInput(options.file);
88
- if (!input) {
89
- console.error("Error: No diff data provided.");
90
- console.error("Usage:");
91
- console.error(" vertaa diff --job-a abc --job-b def --json | vertaa release-notes");
92
- console.error(" vertaa release-notes --file diff.json");
93
- console.error(" vertaa release-notes --job-a abc --job-b def");
94
- process.exit(ExitCode.ERROR);
95
- }
96
- const data = input;
97
- const innerData = (data.data && typeof data.data === "object" ? data.data : data);
98
- // Validate shape
99
- if (!Array.isArray(innerData.new) || !Array.isArray(innerData.fixed)) {
100
- console.error("Error: Invalid diff data. Expected { new: [...], fixed: [...], summary: {...} }");
101
- console.error("Pipe from: vertaa diff --job-a abc --job-b def --json | vertaa release-notes");
102
- process.exit(ExitCode.ERROR);
103
- }
104
- diffPayload = {
105
- new: innerData.new,
106
- fixed: innerData.fixed,
107
- present: innerData.present || null,
108
- summary: innerData.summary || {
109
- newCount: innerData.new.length,
110
- fixedCount: innerData.fixed.length,
111
- presentCount: Array.isArray(innerData.present) ? innerData.present.length : null,
112
- },
113
- };
114
- }
115
- // Auth check
116
- const base = resolveApiBase(globalOpts.base);
117
- const apiKey = getApiKey(config.apiKey);
118
- // Call LLM release-notes API
119
- const spinner = createSpinner("Generating release notes...");
120
- try {
121
- const response = await Promise.race([
122
- apiRequest(base, "/cli/ai/release-notes", { method: "POST", body: { diff: diffPayload } }, apiKey),
123
- new Promise((_, reject) => setTimeout(() => reject(new Error("LLM request timed out")), AI_TIMEOUT_MS)),
124
- ]);
125
- succeedSpinner(spinner, "Notes ready");
126
- if (format === "json") {
127
- writeJsonOutput(response.data, "release-notes");
128
- }
129
- else if (format === "markdown") {
130
- writeOutput(formatReleaseNotesMarkdown(response.data));
131
- }
132
- else {
133
- writeOutput(formatReleaseNotesHuman(response.data));
134
- }
135
- }
136
- catch (error) {
137
- handleAiCommandError(error, "release-notes", spinner);
138
- }
180
+ await handleReleaseNotes({
181
+ file: options.file,
182
+ jobA: options.jobA,
183
+ jobB: options.jobB,
184
+ format: options.format,
185
+ base: globalOpts.base,
186
+ machine: machineMode,
187
+ apiKey: config.apiKey,
188
+ });
139
189
  }
140
190
  catch (error) {
141
- console.error("Error:", error instanceof Error ? error.message : String(error));
191
+ process.stderr.write(renderError({
192
+ message: error instanceof Error ? error.message : String(error),
193
+ suggestion: "vertaa audit <url>",
194
+ exitCode: ExitCode.ERROR,
195
+ }) + "\n");
142
196
  process.exit(ExitCode.ERROR);
143
197
  }
144
198
  });
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Legacy scan command handler + shared runAuditCommand implementation.
3
+ * Provides the `scan` alias for audit and the shared audit runner for a11y/scan commands.
4
+ */
5
+ import type { Command } from "commander";
6
+ import type { Flags } from "../types.js";
7
+ /**
8
+ * Shared audit runner used by a11y, scan, and related legacy commands.
9
+ */
10
+ export declare function runAuditCommand(base: string, url: string, flags: Flags, label: "audit" | "scan" | "a11y"): Promise<void>;
11
+ export declare function handleScan(rawUrl: string, cmdOptions: Flags): Promise<void>;
12
+ export declare function registerScanCommand(program: Command): void;
13
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBzC,OAAO,KAAK,EAAE,KAAK,EAAiB,MAAM,aAAa,CAAC;AAExD;;GAEG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,iBA8DjC;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDjF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuB1D"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Legacy scan command handler + shared runAuditCommand implementation.
3
+ * Provides the `scan` alias for audit and the shared audit runner for a11y/scan commands.
4
+ */
5
+ import { renderError, runSteps, createRenderer } from "@vertaaux/tui";
6
+ import { ExitCode } from "../utils/exit-codes.js";
7
+ import { parseMode, parseTimeout, parseInterval, parseScore } from "../utils/validators.js";
8
+ import { resolveApiBase, getString, getBool, getNumber, resolveFormat, createClient, } from "../utils/api-client.js";
9
+ import { waitForAudit } from "../utils/client.js";
10
+ import { normalizeIssues, getCategoryScore, getOverallScore, formatA11yMarkdown, formatAuditMarkdown, printOutput, } from "../utils/formatters.js";
11
+ /**
12
+ * Shared audit runner used by a11y, scan, and related legacy commands.
13
+ */
14
+ export async function runAuditCommand(base, url, flags, label) {
15
+ const mode = getString(flags, "mode") || "basic";
16
+ const timeout = getNumber(flags, "timeout");
17
+ const userAgent = getString(flags, "user-agent");
18
+ const engineVersion = getString(flags, "engine-version");
19
+ const failOnScore = getNumber(flags, "fail-on-score");
20
+ // Use SDK typed client for audit creation
21
+ const sdkClient = createClient({ base: getString(flags, "base") });
22
+ const created = await sdkClient.audits.create({
23
+ url,
24
+ mode: mode,
25
+ timeout,
26
+ user_agent: userAgent,
27
+ engine_version: engineVersion,
28
+ fail_on_score: failOnScore,
29
+ });
30
+ const format = resolveFormat(flags);
31
+ if (!getBool(flags, "wait")) {
32
+ const markdown = `## Audit queued\n- Job ID: ${created.job_id}\n- URL: ${created.url}\n- Mode: ${created.mode}`;
33
+ printOutput(format, created, markdown);
34
+ return;
35
+ }
36
+ if (!created.job_id) {
37
+ throw new Error("Audit response missing job_id");
38
+ }
39
+ const waitTimeout = getNumber(flags, "timeout") || 60000;
40
+ const interval = getNumber(flags, "interval") || 5000;
41
+ const result = await waitForAudit(sdkClient, created.job_id, waitTimeout, interval);
42
+ if (label === "a11y") {
43
+ const a11yScore = getCategoryScore(result.scores, "accessibility");
44
+ if (failOnScore !== undefined && a11yScore !== null && a11yScore < failOnScore) {
45
+ process.exitCode = 1;
46
+ }
47
+ const issues = normalizeIssues(result.issues).filter((issue) => {
48
+ const category = (issue.category || "").toLowerCase();
49
+ return (category.includes("accessibility") ||
50
+ category.includes("a11y") ||
51
+ category.includes("wcag"));
52
+ });
53
+ const payload = {
54
+ ...result,
55
+ accessibility_score: a11yScore,
56
+ accessibility_issues: issues,
57
+ };
58
+ printOutput(format, payload, formatA11yMarkdown(result));
59
+ return;
60
+ }
61
+ const overall = getOverallScore(result.scores);
62
+ if (failOnScore !== undefined && overall !== null && overall < failOnScore) {
63
+ process.exitCode = 1;
64
+ }
65
+ printOutput(format, result, formatAuditMarkdown(result));
66
+ }
67
+ export async function handleScan(rawUrl, cmdOptions) {
68
+ const url = /^https?:\/\//i.test(rawUrl) ? rawUrl : `https://${rawUrl}`;
69
+ const renderer = createRenderer("auto");
70
+ const baseState = {
71
+ phase: "scan",
72
+ phaseIndex: 1,
73
+ phaseTotal: 1,
74
+ url,
75
+ mode: "scan",
76
+ progress: {},
77
+ totals: {},
78
+ issueCount: 0,
79
+ scorePreview: null,
80
+ verbose: false,
81
+ elapsed: 0,
82
+ };
83
+ const startTime = Date.now();
84
+ const steps = [
85
+ {
86
+ id: "scan",
87
+ actionText: "Running UX scan...",
88
+ summaryText: "Scan complete",
89
+ run: async () => {
90
+ const base = resolveApiBase(cmdOptions);
91
+ await runAuditCommand(base, url, { ...cmdOptions, wait: cmdOptions.wait ?? true }, "scan");
92
+ },
93
+ },
94
+ ];
95
+ const { success, states } = await runSteps(steps, {
96
+ failFast: true,
97
+ onStateChange: (stepStates) => {
98
+ renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
99
+ },
100
+ });
101
+ renderer.finish({ url, mode: "scan", overallScore: 0, scores: {}, issueCount: 0, passed: success, elapsed: Date.now() - startTime });
102
+ if (!success) {
103
+ const failed = states.find(s => s.status === "failed");
104
+ process.stderr.write(renderError({
105
+ message: failed?.failReason || "Command failed",
106
+ suggestion: "vertaa doctor",
107
+ }) + "\n");
108
+ process.exitCode = ExitCode.ERROR;
109
+ }
110
+ }
111
+ export function registerScanCommand(program) {
112
+ program
113
+ .command("scan <url>")
114
+ .description("Run UX scan (alias for audit)")
115
+ .option("--mode <mode>", "Audit depth: basic|standard|deep", parseMode, "basic")
116
+ .option("--wait", "Wait for audit completion")
117
+ .option("--timeout <ms>", "Wait timeout in milliseconds (1-300000)", parseTimeout, 60000)
118
+ .option("--interval <ms>", "Poll interval in milliseconds (1-300000)", parseInterval, 5000)
119
+ .option("--fail-on-score <n>", "Exit non-zero if score below n (0-100)", parseScore)
120
+ .action(async (url, cmdOptions) => {
121
+ try {
122
+ await handleScan(url, cmdOptions);
123
+ }
124
+ catch (error) {
125
+ process.stderr.write(renderError({
126
+ message: error instanceof Error ? error.message : String(error),
127
+ suggestion: "vertaa audit <url>",
128
+ exitCode: ExitCode.ERROR,
129
+ }) + "\n");
130
+ process.exit(ExitCode.ERROR);
131
+ }
132
+ });
133
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Legacy status command handler.
3
+ * Gets the status of an audit job.
4
+ */
5
+ import type { Command } from "commander";
6
+ import type { Flags } from "../types.js";
7
+ export declare function handleStatus(jobId: string, cmdOptions: Flags): Promise<void>;
8
+ export declare function registerStatusCommand(program: Command): void;
9
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDlF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmB5D"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Legacy status command handler.
3
+ * Gets the status of an audit job.
4
+ */
5
+ import { renderError, runSteps, createRenderer } from "@vertaaux/tui";
6
+ import { ExitCode } from "../utils/exit-codes.js";
7
+ import { parseScore } from "../utils/validators.js";
8
+ import { resolveApiBase, resolveFormat, getNumber, createClient, } from "../utils/api-client.js";
9
+ import { getOverallScore, formatAuditMarkdown, printOutput, } from "../utils/formatters.js";
10
+ export async function handleStatus(jobId, cmdOptions) {
11
+ const renderer = createRenderer("auto");
12
+ const baseState = {
13
+ phase: "status",
14
+ phaseIndex: 1,
15
+ phaseTotal: 1,
16
+ url: "",
17
+ mode: "status",
18
+ progress: {},
19
+ totals: {},
20
+ issueCount: 0,
21
+ scorePreview: null,
22
+ verbose: false,
23
+ elapsed: 0,
24
+ };
25
+ const startTime = Date.now();
26
+ const steps = [
27
+ {
28
+ id: "fetch",
29
+ actionText: "Fetching audit status...",
30
+ summaryText: "Audit status retrieved",
31
+ run: async () => {
32
+ const base = resolveApiBase(cmdOptions);
33
+ const client = createClient({ base: base });
34
+ const result = await client.audits.retrieve(jobId);
35
+ const format = resolveFormat(cmdOptions);
36
+ const overall = getOverallScore(result.scores);
37
+ const payload = { ...result, overall_score: overall };
38
+ const markdown = formatAuditMarkdown(result);
39
+ const failOnScore = getNumber(cmdOptions, "fail-on-score");
40
+ if (failOnScore !== undefined && overall !== null && overall < failOnScore) {
41
+ process.exitCode = 1;
42
+ }
43
+ printOutput(format, payload, markdown);
44
+ },
45
+ },
46
+ ];
47
+ const { success, states } = await runSteps(steps, {
48
+ failFast: true,
49
+ onStateChange: (stepStates) => {
50
+ renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
51
+ },
52
+ });
53
+ renderer.finish({ url: "", mode: "status", overallScore: 0, scores: {}, issueCount: 0, passed: success, elapsed: Date.now() - startTime });
54
+ if (!success) {
55
+ const failed = states.find(s => s.status === "failed");
56
+ process.stderr.write(renderError({
57
+ message: failed?.failReason || "Command failed",
58
+ suggestion: "vertaa doctor",
59
+ }) + "\n");
60
+ process.exitCode = ExitCode.ERROR;
61
+ }
62
+ }
63
+ export function registerStatusCommand(program) {
64
+ program
65
+ .command("status <jobId>")
66
+ .description("Get status of an audit job")
67
+ .option("--fail-on-score <n>", "Exit non-zero if score below n (0-100)", parseScore)
68
+ .action(async (jobId, cmdOptions) => {
69
+ try {
70
+ await handleStatus(jobId, cmdOptions);
71
+ }
72
+ catch (error) {
73
+ process.stderr.write(renderError({
74
+ message: error instanceof Error ? error.message : String(error),
75
+ suggestion: "vertaa doctor",
76
+ exitCode: ExitCode.ERROR,
77
+ }) + "\n");
78
+ process.exit(ExitCode.ERROR);
79
+ }
80
+ });
81
+ }
@@ -11,6 +11,16 @@
11
11
  * vertaa suggest "set up CI quality gate"
12
12
  */
13
13
  import { Command } from "commander";
14
+ export interface SuggestCommandOptions {
15
+ intent: string;
16
+ format?: string;
17
+ strict?: boolean;
18
+ continueOnError?: boolean;
19
+ machine?: boolean;
20
+ base?: string;
21
+ apiKey?: string;
22
+ }
23
+ export declare function handleSuggest(opts: SuggestCommandOptions): Promise<void>;
14
24
  /**
15
25
  * Register the suggest command with the Commander program.
16
26
  */
@@ -1 +1 @@
1
- {"version":3,"file":"suggest.d.ts","sourceRoot":"","sources":["../../src/commands/suggest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoDpC;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqH7D"}
1
+ {"version":3,"file":"suggest.d.ts","sourceRoot":"","sources":["../../src/commands/suggest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6FpC,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiJ9E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2C7D"}