@vertaaux/cli 0.4.0 → 0.5.0

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 (223) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/MIGRATION.md +239 -0
  3. package/README.md +34 -16
  4. package/dist/app/interactive-app.d.ts +101 -0
  5. package/dist/app/interactive-app.d.ts.map +1 -0
  6. package/dist/app/interactive-app.js +309 -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 +181 -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 +372 -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 +45 -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 +9 -0
  49. package/dist/commands/a11y.d.ts.map +1 -0
  50. package/dist/commands/a11y.js +76 -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 +564 -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 +130 -0
  69. package/dist/commands/audit/policy.d.ts +19 -0
  70. package/dist/commands/audit/policy.d.ts.map +1 -0
  71. package/dist/commands/audit/policy.js +102 -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 +88 -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 +1 -0
  82. package/dist/commands/baseline.d.ts.map +1 -1
  83. package/dist/commands/baseline.js +205 -121
  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 +122 -58
  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 +287 -180
  90. package/dist/commands/diff.d.ts +5 -0
  91. package/dist/commands/diff.d.ts.map +1 -1
  92. package/dist/commands/diff.js +168 -141
  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 +134 -76
  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 +164 -17
  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 +241 -155
  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 +152 -89
  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 +159 -97
  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 +269 -124
  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 +127 -73
  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 +153 -82
  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 +206 -81
  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/index.d.ts +3 -2
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +125 -990
  150. package/dist/interactive/fix-wizard.d.ts +3 -0
  151. package/dist/interactive/fix-wizard.d.ts.map +1 -1
  152. package/dist/interactive/fix-wizard.js +130 -112
  153. package/dist/interactive/init-wizard.d.ts +3 -1
  154. package/dist/interactive/init-wizard.d.ts.map +1 -1
  155. package/dist/interactive/init-wizard.js +207 -138
  156. package/dist/interactive/prompts.d.ts +7 -3
  157. package/dist/interactive/prompts.d.ts.map +1 -1
  158. package/dist/interactive/prompts.js +44 -23
  159. package/dist/output/envelope.d.ts +2 -0
  160. package/dist/output/envelope.d.ts.map +1 -1
  161. package/dist/output/envelope.js +18 -2
  162. package/dist/output/factory.d.ts +2 -1
  163. package/dist/output/factory.d.ts.map +1 -1
  164. package/dist/output/html.d.ts +2 -1
  165. package/dist/output/html.d.ts.map +1 -1
  166. package/dist/output/html.js +3 -2
  167. package/dist/output/human.d.ts +2 -1
  168. package/dist/output/human.d.ts.map +1 -1
  169. package/dist/output/human.js +3 -2
  170. package/dist/output/json.d.ts +2 -1
  171. package/dist/output/json.d.ts.map +1 -1
  172. package/dist/output/junit.d.ts +2 -1
  173. package/dist/output/junit.d.ts.map +1 -1
  174. package/dist/output/sarif.d.ts +2 -1
  175. package/dist/output/sarif.d.ts.map +1 -1
  176. package/dist/types.d.ts +74 -0
  177. package/dist/types.d.ts.map +1 -0
  178. package/dist/types.js +5 -0
  179. package/dist/ui/banner.d.ts +34 -0
  180. package/dist/ui/banner.d.ts.map +1 -1
  181. package/dist/ui/banner.js +97 -5
  182. package/dist/ui/diagnostics.d.ts +9 -4
  183. package/dist/ui/diagnostics.d.ts.map +1 -1
  184. package/dist/ui/diagnostics.js +32 -82
  185. package/dist/ui/strings.d.ts +373 -0
  186. package/dist/ui/strings.d.ts.map +1 -0
  187. package/dist/ui/strings.js +499 -0
  188. package/dist/ui/table.d.ts +0 -2
  189. package/dist/ui/table.d.ts.map +1 -1
  190. package/dist/ui/table.js +3 -4
  191. package/dist/utils/api-client.d.ts +46 -0
  192. package/dist/utils/api-client.d.ts.map +1 -0
  193. package/dist/utils/api-client.js +170 -0
  194. package/dist/utils/client.d.ts +29 -18
  195. package/dist/utils/client.d.ts.map +1 -1
  196. package/dist/utils/client.js +102 -12
  197. package/dist/utils/formatters.d.ts +38 -0
  198. package/dist/utils/formatters.d.ts.map +1 -0
  199. package/dist/utils/formatters.js +277 -0
  200. package/dist/utils/url-classify.d.ts.map +1 -1
  201. package/dist/utils/url-classify.js +24 -3
  202. package/node_modules/@vertaaux/tui/dist/index.cjs +713 -20
  203. package/node_modules/@vertaaux/tui/dist/index.cjs.map +1 -1
  204. package/node_modules/@vertaaux/tui/dist/index.d.cts +361 -4
  205. package/node_modules/@vertaaux/tui/dist/index.d.ts +361 -4
  206. package/node_modules/@vertaaux/tui/dist/index.js +689 -21
  207. package/node_modules/@vertaaux/tui/dist/index.js.map +1 -1
  208. package/package.json +13 -5
  209. package/dist/commands/client.d.ts +0 -14
  210. package/dist/commands/client.d.ts.map +0 -1
  211. package/dist/commands/client.js +0 -362
  212. package/dist/commands/drift.d.ts +0 -15
  213. package/dist/commands/drift.d.ts.map +0 -1
  214. package/dist/commands/drift.js +0 -309
  215. package/dist/commands/protect.d.ts +0 -16
  216. package/dist/commands/protect.d.ts.map +0 -1
  217. package/dist/commands/protect.js +0 -323
  218. package/dist/commands/report.d.ts +0 -15
  219. package/dist/commands/report.d.ts.map +0 -1
  220. package/dist/commands/report.js +0 -214
  221. package/dist/policy/sync.d.ts +0 -67
  222. package/dist/policy/sync.d.ts.map +0 -1
  223. package/dist/policy/sync.js +0 -147
@@ -1,214 +0,0 @@
1
- /**
2
- * Report generation command for VertaaUX CLI.
3
- *
4
- * Generates consolidated multi-client reports by delegating
5
- * data aggregation to the server-side consolidated report API.
6
- * The CLI handles formatting only -- no data computation.
7
- *
8
- * Implements 46-06: CLI report command.
9
- */
10
- import chalk from "chalk";
11
- import fs from "fs";
12
- import { resolveApiBase, getApiKey, apiRequest } from "../utils/client.js";
13
- /**
14
- * Resolve API connection settings.
15
- */
16
- function resolveConnection() {
17
- return {
18
- base: resolveApiBase(),
19
- apiKey: getApiKey(),
20
- };
21
- }
22
- /**
23
- * Get a traffic-light status indicator for a client based on scores and policy.
24
- */
25
- function getStatusIndicator(client) {
26
- // Red: any URL with score < 50 or policy violations
27
- const hasLowScore = client.urls.some((u) => u.overall !== null && u.overall < 50);
28
- if (hasLowScore || client.policyViolations > 0) {
29
- return chalk.red("\u25cf");
30
- }
31
- // Yellow: some URLs below threshold (< 70)
32
- const hasMediumScore = client.urls.some((u) => u.overall !== null && u.overall < 70);
33
- if (hasMediumScore) {
34
- return chalk.yellow("\u25cf");
35
- }
36
- // Green: all URLs passing or above 70
37
- return chalk.green("\u25cf");
38
- }
39
- /**
40
- * Get trend arrow for display.
41
- */
42
- function getTrendArrow(trend) {
43
- switch (trend) {
44
- case "improving":
45
- return chalk.green("\u2191");
46
- case "declining":
47
- return chalk.red("\u2193");
48
- case "stable":
49
- return chalk.dim("-");
50
- default:
51
- return chalk.dim("?");
52
- }
53
- }
54
- /**
55
- * Pad a string to the right to a given width.
56
- */
57
- function padRight(str, width) {
58
- if (str.length >= width)
59
- return str;
60
- return str + " ".repeat(width - str.length);
61
- }
62
- /**
63
- * Truncate a string to a maximum length with ellipsis.
64
- */
65
- function truncate(str, maxLen) {
66
- if (str.length <= maxLen)
67
- return str;
68
- return str.slice(0, maxLen - 1) + "\u2026";
69
- }
70
- /**
71
- * Format the consolidated report as human-readable output.
72
- */
73
- function formatHumanReport(report) {
74
- const lines = [];
75
- // Header
76
- lines.push("");
77
- lines.push(chalk.bold(`Consolidated Report: ${report.orgName}`));
78
- lines.push(chalk.dim(`Generated: ${new Date(report.generatedAt).toISOString().split("T")[0]}`));
79
- lines.push("");
80
- // Per-client sections
81
- for (const client of report.clients) {
82
- const indicator = getStatusIndicator(client);
83
- const avgStr = client.averageScore !== null
84
- ? String(client.averageScore)
85
- : "n/a";
86
- lines.push(`${indicator} ${chalk.bold(client.name)} (avg: ${avgStr})`);
87
- // URL table
88
- const urlWidth = 40;
89
- const scoreWidth = 8;
90
- const policyWidth = 10;
91
- const trendWidth = 6;
92
- const header = " " +
93
- padRight("URL", urlWidth) +
94
- padRight("Score", scoreWidth) +
95
- padRight("Policy", policyWidth) +
96
- padRight("Trend", trendWidth);
97
- lines.push(chalk.dim(header));
98
- lines.push(chalk.dim(" " + "-".repeat(urlWidth + scoreWidth + policyWidth + trendWidth)));
99
- for (const u of client.urls) {
100
- const scoreStr = u.overall !== null ? String(u.overall) : "n/a";
101
- const policyStr = u.policyStatus === "passing"
102
- ? chalk.green("pass")
103
- : u.policyStatus === "failing"
104
- ? chalk.red("fail")
105
- : chalk.dim("none");
106
- const trendStr = getTrendArrow(u.trend);
107
- const row = " " +
108
- padRight(truncate(u.url, urlWidth - 2), urlWidth) +
109
- padRight(scoreStr, scoreWidth) +
110
- padRight(policyStr, policyWidth) +
111
- trendStr;
112
- lines.push(row);
113
- }
114
- lines.push("");
115
- }
116
- // Summary
117
- lines.push(chalk.bold("Summary"));
118
- lines.push(` Clients: ${report.summary.totalClients} | URLs: ${report.summary.totalUrls} | Avg Score: ${report.summary.averageScore ?? "n/a"}`);
119
- lines.push(` Policies: ${chalk.green(String(report.summary.passingPolicies) + " passing")} ${chalk.red(String(report.summary.failingPolicies) + " failing")}`);
120
- lines.push("");
121
- return lines.join("\n");
122
- }
123
- /**
124
- * Format the consolidated report as CSV.
125
- */
126
- function formatCsvReport(report) {
127
- const lines = [];
128
- // Header
129
- lines.push("Client,URL,Overall,Accessibility,Performance,UX,Policy,Trend");
130
- // Data rows
131
- for (const client of report.clients) {
132
- for (const u of client.urls) {
133
- const overall = u.overall !== null ? String(u.overall) : "";
134
- const accessibility = u.scores.accessibility !== undefined
135
- ? String(u.scores.accessibility)
136
- : "";
137
- const performance = u.scores.performance !== undefined
138
- ? String(u.scores.performance)
139
- : "";
140
- const ux = u.scores.ux !== undefined ? String(u.scores.ux) : "";
141
- const policy = u.policyStatus;
142
- const trend = u.trend;
143
- // Escape client name and URL for CSV (wrap in quotes if contains comma)
144
- const escapeCsv = (s) => s.includes(",") || s.includes('"')
145
- ? `"${s.replace(/"/g, '""')}"`
146
- : s;
147
- lines.push([
148
- escapeCsv(client.name),
149
- escapeCsv(u.url),
150
- overall,
151
- accessibility,
152
- performance,
153
- ux,
154
- policy,
155
- trend,
156
- ].join(","));
157
- }
158
- }
159
- return lines.join("\n") + "\n";
160
- }
161
- /**
162
- * Register the report command with the Commander program.
163
- */
164
- export function registerReportCommand(program) {
165
- program
166
- .command("report")
167
- .description("Generate consolidated reports")
168
- .option("--clients", "Generate multi-client consolidated report")
169
- .option("--client <names>", "Comma-separated client names/slugs (default: all)")
170
- .option("--format <format>", "Output format: human|json|csv", "human")
171
- .option("--output <path>", "Write report to file instead of stdout")
172
- .action(async (options) => {
173
- try {
174
- // Currently only consolidated client reports are supported
175
- if (!options.clients) {
176
- process.stderr.write(chalk.yellow("The report command requires --clients flag.\n"));
177
- process.stderr.write(chalk.dim("Usage: vertaa report --clients [--client <names>] [--format human|json|csv]\n"));
178
- process.exit(1);
179
- return;
180
- }
181
- const { base, apiKey } = resolveConnection();
182
- // Build API URL with optional client filter
183
- let apiPath = "/reports/consolidated";
184
- if (options.client) {
185
- const encoded = encodeURIComponent(options.client);
186
- apiPath += `?clients=${encoded}`;
187
- }
188
- const report = await apiRequest(base, apiPath, { method: "GET" }, apiKey);
189
- // Format output
190
- let output;
191
- if (options.format === "json") {
192
- output = JSON.stringify(report, null, 2) + "\n";
193
- }
194
- else if (options.format === "csv") {
195
- output = formatCsvReport(report);
196
- }
197
- else {
198
- output = formatHumanReport(report);
199
- }
200
- // Write to file or stdout
201
- if (options.output) {
202
- fs.writeFileSync(options.output, output, "utf-8");
203
- process.stderr.write(chalk.green(`Report written to ${options.output}\n`));
204
- }
205
- else {
206
- process.stdout.write(output);
207
- }
208
- }
209
- catch (error) {
210
- process.stderr.write(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}\n`));
211
- process.exit(1);
212
- }
213
- });
214
- }
@@ -1,67 +0,0 @@
1
- /**
2
- * Policy push/pull sync module for VertaaUX CLI.
3
- *
4
- * Provides bidirectional sync between local policy files and the server API.
5
- * Uses the established CLI API patterns (resolveApiBase, getApiKey, apiRequest).
6
- *
7
- * Implements POL-10: Policy push/pull sync.
8
- */
9
- import type { PolicyFile } from "@vertaaux/quality-control";
10
- import type { VertaauxConfig } from "../config/schema.js";
11
- export interface SyncConfig {
12
- apiBase: string;
13
- apiKey: string;
14
- }
15
- /**
16
- * Build sync config from CLI config and environment.
17
- * Uses the established CLI pattern: resolveApiBase + getApiKey.
18
- */
19
- export declare function buildSyncConfig(cliConfig?: VertaauxConfig): SyncConfig;
20
- export interface PushResult {
21
- success: boolean;
22
- policyId: string;
23
- version: number;
24
- created: boolean;
25
- error?: string;
26
- }
27
- export interface PullResult {
28
- success: boolean;
29
- policy?: PolicyFile;
30
- policyId?: string;
31
- version?: number;
32
- name?: string;
33
- error?: string;
34
- }
35
- /**
36
- * Push a local policy file to the server.
37
- *
38
- * If a policy with the given name already exists, updates it (with optional
39
- * optimistic locking via expectedVersion). Otherwise creates a new policy.
40
- *
41
- * @param policy - The policy content to push
42
- * @param config - API connection config
43
- * @param options - Push options (name, description, force, etc.)
44
- * @returns Push result with success status, policy ID, and version
45
- */
46
- export declare function pushPolicy(policy: PolicyFile, config: SyncConfig, options: {
47
- name: string;
48
- description?: string;
49
- changeMessage?: string;
50
- expectedVersion?: number;
51
- force?: boolean;
52
- }): Promise<PushResult>;
53
- /**
54
- * Pull a policy from the server.
55
- *
56
- * Finds the policy by ID, name, or defaults to the default/first policy.
57
- * Returns the full policy content for writing to a local file.
58
- *
59
- * @param config - API connection config
60
- * @param options - Pull options (policyId or policyName)
61
- * @returns Pull result with policy content and metadata
62
- */
63
- export declare function pullPolicy(config: SyncConfig, options: {
64
- policyId?: string;
65
- policyName?: string;
66
- }): Promise<PullResult>;
67
- //# sourceMappingURL=sync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/policy/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,CAAC,EAAE,cAAc,GAAG,UAAU,CAKtE;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4BD;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GACA,OAAO,CAAC,UAAU,CAAC,CA+ErB;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACA,OAAO,CAAC,UAAU,CAAC,CAuDrB"}
@@ -1,147 +0,0 @@
1
- /**
2
- * Policy push/pull sync module for VertaaUX CLI.
3
- *
4
- * Provides bidirectional sync between local policy files and the server API.
5
- * Uses the established CLI API patterns (resolveApiBase, getApiKey, apiRequest).
6
- *
7
- * Implements POL-10: Policy push/pull sync.
8
- */
9
- import { resolveApiBase, getApiKey, apiRequest } from "../utils/client.js";
10
- /**
11
- * Build sync config from CLI config and environment.
12
- * Uses the established CLI pattern: resolveApiBase + getApiKey.
13
- */
14
- export function buildSyncConfig(cliConfig) {
15
- return {
16
- apiBase: resolveApiBase(undefined, undefined),
17
- apiKey: getApiKey(cliConfig?.apiKey),
18
- };
19
- }
20
- /**
21
- * Push a local policy file to the server.
22
- *
23
- * If a policy with the given name already exists, updates it (with optional
24
- * optimistic locking via expectedVersion). Otherwise creates a new policy.
25
- *
26
- * @param policy - The policy content to push
27
- * @param config - API connection config
28
- * @param options - Push options (name, description, force, etc.)
29
- * @returns Push result with success status, policy ID, and version
30
- */
31
- export async function pushPolicy(policy, config, options) {
32
- try {
33
- // First, try to find existing policy by name
34
- const listData = await apiRequest(config.apiBase, "/policies", { method: "GET" }, config.apiKey);
35
- const existing = listData.policies?.find((p) => p.name === options.name);
36
- if (existing) {
37
- // Update existing policy
38
- const body = {
39
- content: policy,
40
- changeMessage: options.changeMessage || "Pushed from CLI",
41
- };
42
- if (options.expectedVersion && !options.force) {
43
- body.expectedVersion = options.expectedVersion;
44
- }
45
- try {
46
- const updated = await apiRequest(config.apiBase, `/policies/${existing.id}`, { method: "PUT", body }, config.apiKey);
47
- return {
48
- success: true,
49
- policyId: existing.id,
50
- version: updated.latestVersion || 0,
51
- created: false,
52
- };
53
- }
54
- catch (err) {
55
- const message = err instanceof Error ? err.message : String(err);
56
- if (message.includes("409")) {
57
- return {
58
- success: false,
59
- policyId: existing.id,
60
- version: existing.latestVersion || 0,
61
- created: false,
62
- error: "Policy has been modified on server. Pull latest first, or use --force.",
63
- };
64
- }
65
- throw err;
66
- }
67
- }
68
- else {
69
- // Create new policy
70
- const created = await apiRequest(config.apiBase, "/policies", {
71
- method: "POST",
72
- body: {
73
- name: options.name,
74
- description: options.description,
75
- content: policy,
76
- },
77
- }, config.apiKey);
78
- return {
79
- success: true,
80
- policyId: created.id || "",
81
- version: 1,
82
- created: true,
83
- };
84
- }
85
- }
86
- catch (err) {
87
- return {
88
- success: false,
89
- policyId: "",
90
- version: 0,
91
- created: false,
92
- error: err instanceof Error ? err.message : String(err),
93
- };
94
- }
95
- }
96
- /**
97
- * Pull a policy from the server.
98
- *
99
- * Finds the policy by ID, name, or defaults to the default/first policy.
100
- * Returns the full policy content for writing to a local file.
101
- *
102
- * @param config - API connection config
103
- * @param options - Pull options (policyId or policyName)
104
- * @returns Pull result with policy content and metadata
105
- */
106
- export async function pullPolicy(config, options) {
107
- try {
108
- let policyId = options.policyId;
109
- // If no ID, find by name or get default
110
- if (!policyId) {
111
- const listData = await apiRequest(config.apiBase, "/policies", { method: "GET" }, config.apiKey);
112
- if (options.policyName) {
113
- const found = listData.policies?.find((p) => p.name === options.policyName);
114
- if (!found) {
115
- return {
116
- success: false,
117
- error: `Policy "${options.policyName}" not found on server`,
118
- };
119
- }
120
- policyId = found.id;
121
- }
122
- else {
123
- const defaultPolicy = listData.policies?.find((p) => p.isDefault);
124
- const target = defaultPolicy || listData.policies?.[0];
125
- if (!target) {
126
- return { success: false, error: "No policies found on server" };
127
- }
128
- policyId = target.id;
129
- }
130
- }
131
- // Fetch full policy with content
132
- const data = await apiRequest(config.apiBase, `/policies/${policyId}`, { method: "GET" }, config.apiKey);
133
- return {
134
- success: true,
135
- policy: data.content,
136
- policyId: data.id || policyId,
137
- version: data.latestVersion,
138
- name: data.name,
139
- };
140
- }
141
- catch (err) {
142
- return {
143
- success: false,
144
- error: err instanceof Error ? err.message : String(err),
145
- };
146
- }
147
- }