@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
@@ -14,7 +14,9 @@ export interface BaselineCommandOptions {
14
14
  reason?: string;
15
15
  list?: boolean;
16
16
  base?: string;
17
+ apiKey?: string;
17
18
  }
19
+ export declare function handleBaseline(jobIdArg: string | undefined, cmdOptions: BaselineCommandOptions): Promise<void>;
18
20
  /**
19
21
  * Register the baseline command with the Commander program.
20
22
  */
@@ -1 +1 @@
1
- {"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../src/commands/baseline.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoIzC,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8H9D"}
1
+ {"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../src/commands/baseline.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2FzC,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,UAAU,EAAE,sBAAsB,GACjC,OAAO,CAAC,IAAI,CAAC,CAwOf;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmC9D"}
@@ -8,51 +8,20 @@
8
8
  */
9
9
  import { readFile } from "fs/promises";
10
10
  import { existsSync } from "fs";
11
+ import { renderError, renderWarning, runSteps, createRenderer } from "@vertaaux/tui";
11
12
  import { ExitCode } from "../utils/exit-codes.js";
13
+ import { createClient } from "../utils/client.js";
14
+ import { resolveConfig } from "../config/loader.js";
12
15
  import { loadBaseline, saveBaseline, createBaseline, addToBaseline, DEFAULT_BASELINE_PATH, } from "../baseline/manager.js";
13
16
  import { generateFingerprint } from "../baseline/hash.js";
14
- const DEFAULT_API_BASE = "https://vertaaux.ai/v1";
17
+ import { writeDataOutput } from "../output/envelope.js";
18
+ import { strings } from "../ui/strings.js";
19
+ import { unwrapJsonEnvelope } from "../utils/stdin.js";
15
20
  /**
16
- * Get API base URL from environment.
21
+ * Fetch audit results via SDK client.
17
22
  */
18
- function getApiBase() {
19
- return (process.env.VERTAAUX_API_BASE || DEFAULT_API_BASE).replace(/\/$/, "");
20
- }
21
- /**
22
- * Get API key from environment.
23
- */
24
- function getApiKey() {
25
- const key = process.env.VERTAAUX_API_KEY;
26
- if (!key) {
27
- throw new Error("VERTAAUX_API_KEY is required");
28
- }
29
- return key;
30
- }
31
- /**
32
- * Fetch audit results from API.
33
- */
34
- async function fetchAudit(jobId) {
35
- const base = getApiBase();
36
- const url = `${base}/audit/${jobId}`;
37
- const res = await fetch(url, {
38
- method: "GET",
39
- headers: {
40
- "Content-Type": "application/json",
41
- "X-API-Key": getApiKey(),
42
- },
43
- });
44
- if (!res.ok) {
45
- let detail = res.statusText;
46
- try {
47
- const data = await res.json();
48
- detail = data.error || data.message || detail;
49
- }
50
- catch {
51
- // ignore
52
- }
53
- throw new Error(`HTTP ${res.status}: ${detail}`);
54
- }
55
- return (await res.json());
23
+ async function fetchAudit(jobId, options) {
24
+ return createClient(options).audits.retrieve(jobId);
56
25
  }
57
26
  /**
58
27
  * Normalize issues from various API response formats.
@@ -106,6 +75,205 @@ function formatBaselineSummary(baseline) {
106
75
  }
107
76
  return lines.join("\n");
108
77
  }
78
+ export async function handleBaseline(jobIdArg, cmdOptions) {
79
+ const baselinePath = cmdOptions.path || DEFAULT_BASELINE_PATH;
80
+ const renderer = createRenderer("auto");
81
+ const baseState = {
82
+ phase: "baseline",
83
+ phaseIndex: 1,
84
+ phaseTotal: 1,
85
+ url: "",
86
+ mode: "baseline",
87
+ progress: {},
88
+ totals: {},
89
+ issueCount: 0,
90
+ scorePreview: null,
91
+ verbose: false,
92
+ elapsed: 0,
93
+ };
94
+ const startTime = Date.now();
95
+ // Handle --list: show baseline summary
96
+ if (cmdOptions.list) {
97
+ const steps = [
98
+ {
99
+ id: "fetch",
100
+ actionText: "Fetching baseline...",
101
+ summaryText: "Baseline loaded",
102
+ run: async () => {
103
+ const baseline = await loadBaseline(baselinePath);
104
+ if (!baseline) {
105
+ process.stderr.write(renderWarning({
106
+ message: "No baseline found.",
107
+ suggestion: `vertaa baseline <job-id> --path ${baselinePath}`,
108
+ }) + "\n");
109
+ return;
110
+ }
111
+ writeDataOutput(formatBaselineSummary(baseline));
112
+ },
113
+ },
114
+ ];
115
+ const { success, states } = await runSteps(steps, {
116
+ failFast: true,
117
+ onStateChange: (stepStates) => {
118
+ renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
119
+ },
120
+ });
121
+ renderer.finish({ url: "", mode: "baseline", overallScore: 0, scores: {}, issueCount: 0, passed: success, elapsed: Date.now() - startTime });
122
+ if (!success) {
123
+ const failed = states.find(s => s.status === "failed");
124
+ process.stderr.write(renderError({
125
+ message: failed?.failReason || "Command failed",
126
+ suggestion: "vertaa doctor",
127
+ }) + "\n");
128
+ process.exitCode = ExitCode.ERROR;
129
+ }
130
+ return;
131
+ }
132
+ // Handle --ignore: add single issue to baseline
133
+ if (cmdOptions.ignore) {
134
+ const issueId = cmdOptions.ignore;
135
+ const steps = [
136
+ {
137
+ id: "update",
138
+ actionText: "Updating baseline...",
139
+ summaryText: "Baseline updated",
140
+ run: async () => {
141
+ let baseline = await loadBaseline(baselinePath);
142
+ if (!baseline) {
143
+ throw new Error("No baseline found. Create one first with: vertaa baseline <job-id>");
144
+ }
145
+ // Need to find the issue to add it properly
146
+ let issue;
147
+ if (jobIdArg) {
148
+ const audit = await fetchAudit(jobIdArg, {
149
+ base: cmdOptions.base,
150
+ apiKey: cmdOptions.apiKey,
151
+ });
152
+ const issues = normalizeIssues(audit.issues);
153
+ const found = findIssueById(issues, issueId);
154
+ if (!found) {
155
+ throw new Error(`Issue "${issueId}" not found in job ${jobIdArg}`);
156
+ }
157
+ issue = found;
158
+ }
159
+ else {
160
+ // Create minimal issue from ID only
161
+ issue = { id: issueId, description: `Ignored: ${issueId}` };
162
+ }
163
+ baseline = addToBaseline(baseline, issue, cmdOptions.reason);
164
+ await saveBaseline(baseline, baselinePath);
165
+ },
166
+ },
167
+ ];
168
+ const { success: ignoreSuccess, states: ignoreStates } = await runSteps(steps, {
169
+ failFast: true,
170
+ onStateChange: (stepStates) => {
171
+ renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
172
+ },
173
+ });
174
+ renderer.finish({ url: "", mode: "baseline", overallScore: 0, scores: {}, issueCount: 0, passed: ignoreSuccess, elapsed: Date.now() - startTime });
175
+ if (!ignoreSuccess) {
176
+ const failed = ignoreStates.find(s => s.status === "failed");
177
+ process.stderr.write(renderError({
178
+ message: failed?.failReason || "Command failed",
179
+ suggestion: "vertaa doctor",
180
+ }) + "\n");
181
+ process.exitCode = ExitCode.ERROR;
182
+ }
183
+ writeDataOutput(`Added issue ${issueId} to baseline${cmdOptions.reason ? `\nReason: ${cmdOptions.reason}` : ""}`);
184
+ return;
185
+ }
186
+ // Handle --from-file: create baseline from JSON file
187
+ if (cmdOptions.fromFile) {
188
+ const filePath = cmdOptions.fromFile;
189
+ if (!existsSync(filePath)) {
190
+ process.stderr.write(renderError({
191
+ message: `File not found: ${filePath}`,
192
+ suggestion: "vertaa audit <url>",
193
+ exitCode: ExitCode.ERROR,
194
+ }) + "\n");
195
+ process.exit(ExitCode.ERROR);
196
+ }
197
+ const steps = [
198
+ {
199
+ id: "save",
200
+ actionText: "Saving baseline...",
201
+ summaryText: "Baseline saved",
202
+ run: async () => {
203
+ const content = await readFile(filePath, "utf-8");
204
+ const data = unwrapJsonEnvelope(JSON.parse(content));
205
+ const issues = normalizeIssues(data.issues);
206
+ const url = data.url || "unknown";
207
+ const baseline = createBaseline(issues, url);
208
+ await saveBaseline(baseline, baselinePath);
209
+ writeDataOutput(`Baseline created with ${issues.length} issues\nSaved to: ${baselinePath}`);
210
+ },
211
+ },
212
+ ];
213
+ const { success: fileSuccess, states: fileStates } = await runSteps(steps, {
214
+ failFast: true,
215
+ onStateChange: (stepStates) => {
216
+ renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
217
+ },
218
+ });
219
+ renderer.finish({ url: "", mode: "baseline", overallScore: 0, scores: {}, issueCount: 0, passed: fileSuccess, elapsed: Date.now() - startTime });
220
+ if (!fileSuccess) {
221
+ const failed = fileStates.find(s => s.status === "failed");
222
+ process.stderr.write(renderError({
223
+ message: failed?.failReason || "Command failed",
224
+ suggestion: "vertaa doctor",
225
+ }) + "\n");
226
+ process.exitCode = ExitCode.ERROR;
227
+ }
228
+ return;
229
+ }
230
+ // Handle job-id: create baseline from API audit
231
+ if (!jobIdArg) {
232
+ process.stderr.write(renderError({
233
+ message: "Provide job ID or use --from-file or --list",
234
+ context: "Usage: vertaa baseline <job-id>\n vertaa baseline --from-file <audit.json>\n vertaa baseline --list",
235
+ suggestion: "vertaa baseline --list",
236
+ exitCode: ExitCode.ERROR,
237
+ }) + "\n");
238
+ process.exit(ExitCode.ERROR);
239
+ }
240
+ const steps = [
241
+ {
242
+ id: "fetch",
243
+ actionText: "Fetching audit results...",
244
+ summaryText: "Audit results loaded",
245
+ run: async () => {
246
+ const audit = await fetchAudit(jobIdArg, {
247
+ base: cmdOptions.base,
248
+ apiKey: cmdOptions.apiKey,
249
+ });
250
+ if (audit.status !== "completed") {
251
+ throw new Error(strings.fixAll.auditIncomplete(jobIdArg, audit.status || "unknown"));
252
+ }
253
+ const issues = normalizeIssues(audit.issues);
254
+ const url = audit.url || "unknown";
255
+ const baseline = createBaseline(issues, url);
256
+ await saveBaseline(baseline, baselinePath);
257
+ writeDataOutput(`Baseline created with ${issues.length} issues\nSaved to: ${baselinePath}`);
258
+ },
259
+ },
260
+ ];
261
+ const { success: jobSuccess, states: jobStates } = await runSteps(steps, {
262
+ failFast: true,
263
+ onStateChange: (stepStates) => {
264
+ renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
265
+ },
266
+ });
267
+ renderer.finish({ url: "", mode: "baseline", overallScore: 0, scores: {}, issueCount: 0, passed: jobSuccess, elapsed: Date.now() - startTime });
268
+ if (!jobSuccess) {
269
+ const failed = jobStates.find(s => s.status === "failed");
270
+ process.stderr.write(renderError({
271
+ message: failed?.failReason || "Command failed",
272
+ suggestion: "vertaa doctor",
273
+ }) + "\n");
274
+ process.exitCode = ExitCode.ERROR;
275
+ }
276
+ }
109
277
  /**
110
278
  * Register the baseline command with the Commander program.
111
279
  */
@@ -118,92 +286,22 @@ export function registerBaselineCommand(program) {
118
286
  .option("--ignore <id>", "Add single issue to existing baseline by ID")
119
287
  .option("--reason <text>", "Reason for baseline/ignore (optional)")
120
288
  .option("--list", "Show baselined issues count and last update")
121
- .action(async (jobIdArg, cmdOptions) => {
289
+ .action(async (jobIdArg, cmdOptions, command) => {
122
290
  try {
123
- const baselinePath = cmdOptions.path || DEFAULT_BASELINE_PATH;
124
- // Handle --list: show baseline summary
125
- if (cmdOptions.list) {
126
- const baseline = await loadBaseline(baselinePath);
127
- if (!baseline) {
128
- console.error("No baseline found.");
129
- console.error(`Create one with: vertaa baseline <job-id> --path ${baselinePath}`);
130
- return;
131
- }
132
- console.error(formatBaselineSummary(baseline));
133
- return;
134
- }
135
- // Handle --ignore: add single issue to baseline
136
- if (cmdOptions.ignore) {
137
- const issueId = cmdOptions.ignore;
138
- let baseline = await loadBaseline(baselinePath);
139
- if (!baseline) {
140
- console.error("No baseline found. Create one first with: vertaa baseline <job-id>");
141
- process.exit(ExitCode.ERROR);
142
- }
143
- // Need to find the issue to add it properly
144
- // If we have a job ID, fetch the audit; otherwise use a minimal issue
145
- let issue;
146
- if (jobIdArg) {
147
- const audit = await fetchAudit(jobIdArg);
148
- const issues = normalizeIssues(audit.issues);
149
- const found = findIssueById(issues, issueId);
150
- if (!found) {
151
- console.error(`Issue "${issueId}" not found in job ${jobIdArg}`);
152
- process.exit(ExitCode.ERROR);
153
- }
154
- issue = found;
155
- }
156
- else {
157
- // Create minimal issue from ID only
158
- issue = { id: issueId, description: `Ignored: ${issueId}` };
159
- }
160
- baseline = addToBaseline(baseline, issue, cmdOptions.reason);
161
- await saveBaseline(baseline, baselinePath);
162
- console.error(`Added issue ${issueId} to baseline`);
163
- if (cmdOptions.reason) {
164
- console.error(`Reason: ${cmdOptions.reason}`);
165
- }
166
- return;
167
- }
168
- // Handle --from-file: create baseline from JSON file
169
- if (cmdOptions.fromFile) {
170
- const filePath = cmdOptions.fromFile;
171
- if (!existsSync(filePath)) {
172
- console.error(`File not found: ${filePath}`);
173
- process.exit(ExitCode.ERROR);
174
- }
175
- const content = await readFile(filePath, "utf-8");
176
- const data = JSON.parse(content);
177
- const issues = normalizeIssues(data.issues);
178
- const url = data.url || "unknown";
179
- const baseline = createBaseline(issues, url);
180
- await saveBaseline(baseline, baselinePath);
181
- console.error(`Baseline created with ${issues.length} issues`);
182
- console.error(`Saved to: ${baselinePath}`);
183
- return;
184
- }
185
- // Handle job-id: create baseline from API audit
186
- if (!jobIdArg) {
187
- console.error("Provide job ID or use --from-file or --list");
188
- console.error("Usage: vertaa baseline <job-id>");
189
- console.error(" vertaa baseline --from-file <audit.json>");
190
- console.error(" vertaa baseline --list");
191
- process.exit(ExitCode.ERROR);
192
- }
193
- const audit = await fetchAudit(jobIdArg);
194
- if (audit.status !== "completed") {
195
- console.error(`Audit ${jobIdArg} is not completed (status: ${audit.status})`);
196
- process.exit(ExitCode.ERROR);
197
- }
198
- const issues = normalizeIssues(audit.issues);
199
- const url = audit.url || "unknown";
200
- const baseline = createBaseline(issues, url);
201
- await saveBaseline(baseline, baselinePath);
202
- console.error(`Baseline created with ${issues.length} issues`);
203
- console.error(`Saved to: ${baselinePath}`);
291
+ const globalOpts = command.optsWithGlobals?.() || {};
292
+ const config = await resolveConfig(globalOpts.config);
293
+ await handleBaseline(jobIdArg, {
294
+ ...cmdOptions,
295
+ base: globalOpts.base,
296
+ apiKey: config.apiKey,
297
+ });
204
298
  }
205
299
  catch (error) {
206
- console.error("Error:", error instanceof Error ? error.message : String(error));
300
+ process.stderr.write(renderError({
301
+ message: error instanceof Error ? error.message : String(error),
302
+ suggestion: "vertaa audit <url>",
303
+ exitCode: ExitCode.ERROR,
304
+ }) + "\n");
207
305
  process.exit(ExitCode.ERROR);
208
306
  }
209
307
  });
@@ -6,6 +6,28 @@
6
6
  * Uses sticky comment semantics to update existing comments.
7
7
  */
8
8
  import { Command } from "commander";
9
+ import { type MarkdownOptions } from "../output/markdown.js";
10
+ /**
11
+ * Options for comment generation.
12
+ */
13
+ interface CommentOptions {
14
+ input?: string;
15
+ baseline?: string;
16
+ format?: "markdown" | "json";
17
+ output?: string;
18
+ collapse?: boolean;
19
+ groupBy?: MarkdownOptions["groupBy"];
20
+ post?: boolean;
21
+ githubToken?: string;
22
+ gitlabToken?: string;
23
+ pr?: number;
24
+ repo?: string;
25
+ noPostIfClean?: boolean;
26
+ }
27
+ /**
28
+ * Handle the comment command.
29
+ */
30
+ export declare function handleComment(options: CommentOptions): Promise<void>;
9
31
  /**
10
32
  * Register the comment command with the Commander program.
11
33
  */
@@ -1 +1 @@
1
- {"version":3,"file":"comment.d.ts","sourceRoot":"","sources":["../../src/commands/comment.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgZpC;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6F7D;AAGD,OAAO,EAAE,qBAAqB,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"comment.d.ts","sourceRoot":"","sources":["../../src/commands/comment.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AA2B/B;;GAEG;AACH,UAAU,cAAc;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IAErC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAqJD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAyQ1E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgG7D;AAGD,OAAO,EAAE,qBAAqB,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC"}