@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
@@ -8,11 +8,12 @@
8
8
  import fs from "fs";
9
9
  import path from "path";
10
10
  import yaml from "yaml";
11
- import chalk from "chalk";
11
+ import { colorize, dim, brand, renderError, renderWarning, runSteps, createRenderer } from "@vertaaux/tui";
12
12
  import { loadPolicy, loadPolicyFile, resolveBranchPolicy, POLICY_TEMPLATES, policyJsonSchema, PolicyValidationError, PolicyLoadError, } from "../policy/index.js";
13
13
  import { ExitCode } from "../utils/exit-codes.js";
14
- import { writeJsonOutput, writeOutput } from "../output/envelope.js";
14
+ import { writeDataOutput, writeJsonOutput, writeOutput } from "../output/envelope.js";
15
15
  import { resolveCommandFormat } from "../output/formats.js";
16
+ import { strings } from "../ui/strings.js";
16
17
  /**
17
18
  * Default policy file path.
18
19
  */
@@ -123,94 +124,155 @@ async function initPolicy(options) {
123
124
  const absolutePath = path.resolve(process.cwd(), outputPath);
124
125
  // Check if file exists
125
126
  if (fs.existsSync(absolutePath) && !options.force) {
126
- console.error(chalk.red(`Policy file already exists: ${absolutePath}`));
127
- console.error(chalk.dim("Use --force to overwrite."));
127
+ process.stderr.write(renderWarning({
128
+ message: strings.policy.fileExists(absolutePath),
129
+ suggestion: "vertaa policy init --force",
130
+ }) + "\n");
128
131
  process.exit(ExitCode.ERROR);
129
132
  }
130
133
  // Validate template
131
134
  if (!POLICY_TEMPLATES[template]) {
132
- console.error(chalk.red(`Unknown template: ${template}`));
133
- console.error(chalk.dim(`Available templates: ${Object.keys(POLICY_TEMPLATES).join(", ")}`));
135
+ process.stderr.write(renderError({
136
+ message: strings.policy.unknownTemplate(template, Object.keys(POLICY_TEMPLATES).join(", ")),
137
+ suggestion: "vertaa policy init --template basic",
138
+ exitCode: ExitCode.ERROR,
139
+ }) + "\n");
134
140
  process.exit(ExitCode.ERROR);
135
141
  }
136
- // Generate policy
137
- const policyYaml = generatePolicyYaml(template);
138
- // Write file
139
- fs.writeFileSync(absolutePath, policyYaml, "utf-8");
140
- console.error(chalk.green(`Created policy file: ${absolutePath}`));
141
- console.error(chalk.dim(`Template: ${template}`));
142
- console.error("");
143
- console.error("Next steps:");
144
- console.error(` 1. Review and customize ${outputPath}`);
145
- console.error(" 2. Commit the file to your repository");
146
- console.error(" 3. Run 'vertaa policy validate' to verify");
142
+ const renderer = createRenderer("auto");
143
+ const baseState = {
144
+ phase: "policy",
145
+ phaseIndex: 1,
146
+ phaseTotal: 1,
147
+ url: "",
148
+ mode: "policy",
149
+ progress: {},
150
+ totals: {},
151
+ issueCount: 0,
152
+ scorePreview: null,
153
+ verbose: false,
154
+ elapsed: 0,
155
+ };
156
+ const startTime = Date.now();
157
+ const steps = [
158
+ {
159
+ id: "load",
160
+ actionText: "Loading policy template...",
161
+ summaryText: "Policy created",
162
+ run: async () => {
163
+ // Generate policy
164
+ const policyYaml = generatePolicyYaml(template);
165
+ // Write file
166
+ fs.writeFileSync(absolutePath, policyYaml, "utf-8");
167
+ },
168
+ },
169
+ ];
170
+ await runSteps(steps, {
171
+ failFast: true,
172
+ onStateChange: (stepStates) => {
173
+ renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
174
+ },
175
+ });
176
+ renderer.finish({ url: "", mode: "policy", overallScore: 0, scores: {}, issueCount: 0, passed: true, elapsed: Date.now() - startTime });
177
+ const outputLines = [
178
+ colorize(strings.policy.created(absolutePath, template), brand.lime),
179
+ "",
180
+ "Next steps:",
181
+ ` 1. Review and customize ${outputPath}`,
182
+ " 2. Commit the file to your repository",
183
+ " 3. Run 'vertaa policy validate' to verify",
184
+ ];
185
+ writeOutput(outputLines.join("\n"));
147
186
  }
148
187
  /**
149
188
  * Validate a policy file.
150
189
  */
151
190
  async function validatePolicyCommand(filePath, options) {
152
191
  const quiet = options.quiet ?? false;
153
- try {
154
- // Load policy from path or search
155
- let policy;
156
- let policyPath;
157
- if (filePath) {
158
- policy = await loadPolicyFile(filePath);
159
- policyPath = filePath;
160
- }
161
- else {
162
- const result = await loadPolicy();
163
- policy = result.policy;
164
- policyPath = result.path;
165
- }
166
- if (!policyPath) {
167
- console.error(chalk.yellow("No policy file found. Using defaults."));
168
- console.error(chalk.dim("Create a policy file with: vertaa policy init"));
169
- return;
170
- }
171
- // Validation passed if we got here
172
- if (!quiet) {
173
- console.error(chalk.green(`Policy file valid: ${policyPath}`));
174
- console.error("");
175
- console.error("Summary:");
176
- console.error(` Version: ${policy.version}`);
177
- console.error(` Name: ${policy.name || "(unnamed)"}`);
178
- if (policy.assertions) {
179
- console.error(" Assertions:");
180
- if (policy.assertions.fail_on) {
181
- console.error(` - Fail on: ${policy.assertions.fail_on}`);
192
+ const renderer = createRenderer("auto");
193
+ const baseState = {
194
+ phase: "policy",
195
+ phaseIndex: 1,
196
+ phaseTotal: 1,
197
+ url: "",
198
+ mode: "policy",
199
+ progress: {},
200
+ totals: {},
201
+ issueCount: 0,
202
+ scorePreview: null,
203
+ verbose: false,
204
+ elapsed: 0,
205
+ };
206
+ const startTime = Date.now();
207
+ const ctx = {
208
+ policy: null,
209
+ policyPath: null,
210
+ };
211
+ const steps = [
212
+ {
213
+ id: "load",
214
+ actionText: "Loading policy...",
215
+ summaryText: "Policy loaded",
216
+ run: async () => {
217
+ if (filePath) {
218
+ ctx.policy = await loadPolicyFile(filePath);
219
+ ctx.policyPath = filePath;
182
220
  }
183
- if (policy.assertions.overall_score !== undefined) {
184
- console.error(` - Overall score >= ${policy.assertions.overall_score}`);
221
+ else {
222
+ const result = await loadPolicy();
223
+ ctx.policy = result.policy;
224
+ ctx.policyPath = result.path;
185
225
  }
186
- if (policy.assertions.max_new_errors !== undefined) {
187
- console.error(` - Max new errors: ${policy.assertions.max_new_errors}`);
226
+ if (!ctx.policyPath) {
227
+ process.stderr.write(renderWarning({
228
+ message: strings.policy.noPolicy,
229
+ suggestion: "vertaa policy init",
230
+ }) + "\n");
188
231
  }
232
+ },
233
+ },
234
+ ];
235
+ await runSteps(steps, {
236
+ failFast: true,
237
+ onStateChange: (stepStates) => {
238
+ renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
239
+ },
240
+ });
241
+ renderer.finish({ url: "", mode: "policy", overallScore: 0, scores: {}, issueCount: 0, passed: true, elapsed: Date.now() - startTime });
242
+ const { policy, policyPath } = ctx;
243
+ if (!policy || !policyPath)
244
+ return;
245
+ // Validation passed if we got here
246
+ if (!quiet) {
247
+ const outputLines = [
248
+ colorize(strings.policy.valid(policyPath), brand.lime),
249
+ "",
250
+ "Summary:",
251
+ ` Version: ${policy.version}`,
252
+ ` Name: ${policy.name || "(unnamed)"}`,
253
+ ];
254
+ if (policy.assertions) {
255
+ outputLines.push(" Assertions:");
256
+ if (policy.assertions.fail_on) {
257
+ outputLines.push(` - Fail on: ${policy.assertions.fail_on}`);
189
258
  }
190
- if (policy.branches) {
191
- console.error(` Branches: ${Object.keys(policy.branches).join(", ")}`);
192
- }
193
- if (policy.rules) {
194
- console.error(` Rule overrides: ${Object.keys(policy.rules).length}`);
259
+ if (policy.assertions.overall_score !== undefined) {
260
+ outputLines.push(` - Overall score >= ${policy.assertions.overall_score}`);
195
261
  }
196
- if (policy.bypass_labels?.length) {
197
- console.error(` Bypass labels: ${policy.bypass_labels.join(", ")}`);
262
+ if (policy.assertions.max_new_errors !== undefined) {
263
+ outputLines.push(` - Max new errors: ${policy.assertions.max_new_errors}`);
198
264
  }
199
265
  }
200
- }
201
- catch (error) {
202
- if (error instanceof PolicyValidationError) {
203
- console.error(chalk.red("Policy validation failed:"));
204
- for (const err of error.errors) {
205
- console.error(chalk.red(` - ${err}`));
206
- }
207
- process.exit(ExitCode.ERROR);
266
+ if (policy.branches) {
267
+ outputLines.push(` Branches: ${Object.keys(policy.branches).join(", ")}`);
208
268
  }
209
- if (error instanceof PolicyLoadError) {
210
- console.error(chalk.red(`Failed to load policy: ${error.message}`));
211
- process.exit(ExitCode.ERROR);
269
+ if (policy.rules) {
270
+ outputLines.push(` Rule overrides: ${Object.keys(policy.rules).length}`);
212
271
  }
213
- throw error;
272
+ if (policy.bypass_labels?.length) {
273
+ outputLines.push(` Bypass labels: ${policy.bypass_labels.join(", ")}`);
274
+ }
275
+ writeOutput(outputLines.join("\n"));
214
276
  }
215
277
  }
216
278
  /**
@@ -219,60 +281,77 @@ async function validatePolicyCommand(filePath, options) {
219
281
  async function showPolicy(options) {
220
282
  const branch = options.branch || "";
221
283
  const format = options.format || "yaml";
222
- try {
223
- // Load policy
224
- let policy;
225
- let policyPath;
226
- if (options.policy) {
227
- policy = await loadPolicyFile(options.policy);
228
- policyPath = options.policy;
229
- }
230
- else {
231
- const result = await loadPolicy();
232
- policy = result.policy;
233
- policyPath = result.path;
234
- }
235
- // Resolve branch-specific overrides
236
- let effectivePolicy = policy;
237
- let branchInfo = "";
238
- if (branch) {
239
- effectivePolicy = resolveBranchPolicy(policy, branch);
240
- branchInfo = ` (branch: ${branch})`;
241
- }
242
- // Output
243
- if (policyPath) {
244
- console.error(chalk.dim(`Policy: ${policyPath}${branchInfo}`));
245
- console.error("");
246
- }
247
- else {
248
- console.error(chalk.dim(`Using default policy${branchInfo}`));
249
- console.error("");
250
- }
251
- if (format === "json") {
252
- writeJsonOutput(effectivePolicy, "policy-show");
253
- }
254
- else {
255
- // YAML output
256
- const yamlOutput = yaml.stringify(effectivePolicy, {
257
- indent: 2,
258
- lineWidth: 100,
259
- });
260
- writeOutput(yamlOutput);
261
- }
284
+ const renderer = createRenderer("auto");
285
+ const baseState = {
286
+ phase: "policy",
287
+ phaseIndex: 1,
288
+ phaseTotal: 1,
289
+ url: "",
290
+ mode: "policy",
291
+ progress: {},
292
+ totals: {},
293
+ issueCount: 0,
294
+ scorePreview: null,
295
+ verbose: false,
296
+ elapsed: 0,
297
+ };
298
+ const startTime = Date.now();
299
+ const ctx = {
300
+ policy: null,
301
+ policyPath: null,
302
+ };
303
+ const steps = [
304
+ {
305
+ id: "load",
306
+ actionText: "Loading policy...",
307
+ summaryText: "Policy loaded",
308
+ run: async () => {
309
+ if (options.policy) {
310
+ ctx.policy = await loadPolicyFile(options.policy);
311
+ ctx.policyPath = options.policy;
312
+ }
313
+ else {
314
+ const result = await loadPolicy();
315
+ ctx.policy = result.policy;
316
+ ctx.policyPath = result.path;
317
+ }
318
+ },
319
+ },
320
+ ];
321
+ await runSteps(steps, {
322
+ failFast: true,
323
+ onStateChange: (stepStates) => {
324
+ renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
325
+ },
326
+ });
327
+ renderer.finish({ url: "", mode: "policy", overallScore: 0, scores: {}, issueCount: 0, passed: true, elapsed: Date.now() - startTime });
328
+ const { policy, policyPath } = ctx;
329
+ if (!policy)
330
+ return;
331
+ // Resolve branch-specific overrides
332
+ let effectivePolicy = policy;
333
+ let branchInfo = "";
334
+ if (branch) {
335
+ effectivePolicy = resolveBranchPolicy(policy, branch);
336
+ branchInfo = ` (branch: ${branch})`;
262
337
  }
263
- catch (error) {
264
- if (error instanceof PolicyValidationError) {
265
- console.error(chalk.red("Policy validation failed:"));
266
- for (const err of error.errors) {
267
- console.error(chalk.red(` - ${err}`));
268
- }
269
- process.exit(ExitCode.ERROR);
270
- }
271
- if (error instanceof PolicyLoadError) {
272
- console.error(chalk.red(`Failed to load policy: ${error.message}`));
273
- process.exit(ExitCode.ERROR);
274
- }
275
- throw error;
338
+ // Output
339
+ if (policyPath) {
340
+ writeOutput(dim(strings.policy.usingPolicy(policyPath, branchInfo)));
341
+ }
342
+ else {
343
+ writeOutput(dim(strings.policy.usingDefault(branchInfo)));
344
+ }
345
+ if (format === "json") {
346
+ writeJsonOutput(effectivePolicy, "policy-show");
347
+ }
348
+ else {
349
+ // YAML output
350
+ const yamlOutput = yaml.stringify(effectivePolicy, {
351
+ indent: 2,
352
+ lineWidth: 100,
353
+ });
354
+ writeDataOutput(yamlOutput);
276
355
  }
277
356
  }
278
357
  /**
@@ -281,6 +360,26 @@ async function showPolicy(options) {
281
360
  function outputSchema() {
282
361
  writeJsonOutput(policyJsonSchema, "policy-schema");
283
362
  }
363
+ /**
364
+ * Unified handlePolicy entry point for CommandRunnerView.
365
+ * Routes to the appropriate sub-command handler.
366
+ */
367
+ export async function handlePolicy(subCommand, options) {
368
+ switch (subCommand) {
369
+ case "init":
370
+ await initPolicy(options);
371
+ break;
372
+ case "validate":
373
+ await validatePolicyCommand(options.file, options);
374
+ break;
375
+ case "show":
376
+ await showPolicy(options);
377
+ break;
378
+ case "schema":
379
+ outputSchema();
380
+ break;
381
+ }
382
+ }
284
383
  /**
285
384
  * Register the policy command with the Commander program.
286
385
  */
@@ -300,7 +399,11 @@ export function registerPolicyCommand(program) {
300
399
  await initPolicy(options);
301
400
  }
302
401
  catch (error) {
303
- console.error("Error:", error instanceof Error ? error.message : String(error));
402
+ process.stderr.write(renderError({
403
+ message: error instanceof Error ? error.message : String(error),
404
+ suggestion: "vertaa policy init",
405
+ exitCode: ExitCode.ERROR,
406
+ }) + "\n");
304
407
  process.exit(ExitCode.ERROR);
305
408
  }
306
409
  });
@@ -314,7 +417,28 @@ export function registerPolicyCommand(program) {
314
417
  await validatePolicyCommand(filePath, options);
315
418
  }
316
419
  catch (error) {
317
- console.error("Error:", error instanceof Error ? error.message : String(error));
420
+ if (error instanceof PolicyValidationError) {
421
+ process.stderr.write(renderError({
422
+ message: strings.policy.errors.validationFailed,
423
+ context: error.errors.map((e) => `- ${e}`).join("\n"),
424
+ suggestion: "vertaa policy validate <file>",
425
+ exitCode: ExitCode.ERROR,
426
+ }) + "\n");
427
+ process.exit(ExitCode.ERROR);
428
+ }
429
+ if (error instanceof PolicyLoadError) {
430
+ process.stderr.write(renderError({
431
+ message: strings.policy.errors.loadFailed(error.message),
432
+ suggestion: "vertaa policy init",
433
+ exitCode: ExitCode.ERROR,
434
+ }) + "\n");
435
+ process.exit(ExitCode.ERROR);
436
+ }
437
+ process.stderr.write(renderError({
438
+ message: error instanceof Error ? error.message : String(error),
439
+ suggestion: "vertaa policy validate",
440
+ exitCode: ExitCode.ERROR,
441
+ }) + "\n");
318
442
  process.exit(ExitCode.ERROR);
319
443
  }
320
444
  });
@@ -333,7 +457,28 @@ export function registerPolicyCommand(program) {
333
457
  await showPolicy({ ...options, format: validatedFormat });
334
458
  }
335
459
  catch (error) {
336
- console.error("Error:", error instanceof Error ? error.message : String(error));
460
+ if (error instanceof PolicyValidationError) {
461
+ process.stderr.write(renderError({
462
+ message: strings.policy.errors.validationFailed,
463
+ context: error.errors.map((e) => `- ${e}`).join("\n"),
464
+ suggestion: "vertaa policy validate <file>",
465
+ exitCode: ExitCode.ERROR,
466
+ }) + "\n");
467
+ process.exit(ExitCode.ERROR);
468
+ }
469
+ if (error instanceof PolicyLoadError) {
470
+ process.stderr.write(renderError({
471
+ message: strings.policy.errors.loadFailed(error.message),
472
+ suggestion: "vertaa policy init",
473
+ exitCode: ExitCode.ERROR,
474
+ }) + "\n");
475
+ process.exit(ExitCode.ERROR);
476
+ }
477
+ process.stderr.write(renderError({
478
+ message: error instanceof Error ? error.message : String(error),
479
+ suggestion: "vertaa policy show",
480
+ exitCode: ExitCode.ERROR,
481
+ }) + "\n");
337
482
  process.exit(ExitCode.ERROR);
338
483
  }
339
484
  });
@@ -13,5 +13,15 @@
13
13
  * vertaa release-notes --job-a abc --job-b def
14
14
  */
15
15
  import { Command } from "commander";
16
+ export interface ReleaseNotesCommandOptions {
17
+ file?: string;
18
+ jobA?: string;
19
+ jobB?: string;
20
+ format?: string;
21
+ base?: string;
22
+ machine?: boolean;
23
+ apiKey?: string;
24
+ }
25
+ export declare function handleReleaseNotes(opts: ReleaseNotesCommandOptions): Promise<void>;
16
26
  export declare function registerReleaseNotesCommand(program: Command): void;
17
27
  //# sourceMappingURL=release-notes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"release-notes.d.ts","sourceRoot":"","sources":["../../src/commands/release-notes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0EpC,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgHlE"}
1
+ {"version":3,"file":"release-notes.d.ts","sourceRoot":"","sources":["../../src/commands/release-notes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0EpC,MAAM,WAAW,0BAA0B;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAqIxF;AAMD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2ClE"}