@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.
- package/CHANGELOG.md +97 -0
- package/MIGRATION.md +239 -0
- package/README.md +34 -16
- package/dist/app/interactive-app.d.ts +101 -0
- package/dist/app/interactive-app.d.ts.map +1 -0
- package/dist/app/interactive-app.js +309 -0
- package/dist/app/layout/canvas.d.ts +23 -0
- package/dist/app/layout/canvas.d.ts.map +1 -0
- package/dist/app/layout/canvas.js +36 -0
- package/dist/app/layout/footer.d.ts +31 -0
- package/dist/app/layout/footer.d.ts.map +1 -0
- package/dist/app/layout/footer.js +41 -0
- package/dist/app/layout/header.d.ts +20 -0
- package/dist/app/layout/header.d.ts.map +1 -0
- package/dist/app/layout/header.js +27 -0
- package/dist/app/menu/categories.d.ts +20 -0
- package/dist/app/menu/categories.d.ts.map +1 -0
- package/dist/app/menu/categories.js +181 -0
- package/dist/app/menu/filter.d.ts +17 -0
- package/dist/app/menu/filter.d.ts.map +1 -0
- package/dist/app/menu/filter.js +33 -0
- package/dist/app/menu/menu-view.d.ts +35 -0
- package/dist/app/menu/menu-view.d.ts.map +1 -0
- package/dist/app/menu/menu-view.js +230 -0
- package/dist/app/menu/recent.d.ts +24 -0
- package/dist/app/menu/recent.d.ts.map +1 -0
- package/dist/app/menu/recent.js +49 -0
- package/dist/app/types.d.ts +43 -0
- package/dist/app/types.d.ts.map +1 -0
- package/dist/app/types.js +7 -0
- package/dist/app/views/command-runner.d.ts +36 -0
- package/dist/app/views/command-runner.d.ts.map +1 -0
- package/dist/app/views/command-runner.js +372 -0
- package/dist/app/views/help-overlay.d.ts +21 -0
- package/dist/app/views/help-overlay.d.ts.map +1 -0
- package/dist/app/views/help-overlay.js +45 -0
- package/dist/auth/ci-token.d.ts +8 -2
- package/dist/auth/ci-token.d.ts.map +1 -1
- package/dist/auth/ci-token.js +15 -30
- package/dist/auth/device-flow.d.ts +2 -1
- package/dist/auth/device-flow.d.ts.map +1 -1
- package/dist/auth/device-flow.js +13 -10
- package/dist/auth/token-store.d.ts.map +1 -1
- package/dist/auth/token-store.js +12 -2
- package/dist/baseline/diff.d.ts +2 -2
- package/dist/baseline/diff.d.ts.map +1 -1
- package/dist/baseline/diff.js +15 -34
- package/dist/commands/a11y.d.ts +9 -0
- package/dist/commands/a11y.d.ts.map +1 -0
- package/dist/commands/a11y.js +76 -0
- package/dist/commands/audit/artifacts.d.ts +27 -0
- package/dist/commands/audit/artifacts.d.ts.map +1 -0
- package/dist/commands/audit/artifacts.js +158 -0
- package/dist/commands/audit/ci-detection.d.ts +18 -0
- package/dist/commands/audit/ci-detection.d.ts.map +1 -0
- package/dist/commands/audit/ci-detection.js +71 -0
- package/dist/commands/audit/explain.d.ts +11 -0
- package/dist/commands/audit/explain.d.ts.map +1 -0
- package/dist/commands/audit/explain.js +45 -0
- package/dist/commands/audit/filters.d.ts +17 -0
- package/dist/commands/audit/filters.d.ts.map +1 -0
- package/dist/commands/audit/filters.js +40 -0
- package/dist/commands/audit/index.d.ts +18 -0
- package/dist/commands/audit/index.d.ts.map +1 -0
- package/dist/commands/audit/index.js +564 -0
- package/dist/commands/audit/output.d.ts +32 -0
- package/dist/commands/audit/output.d.ts.map +1 -0
- package/dist/commands/audit/output.js +130 -0
- package/dist/commands/audit/policy.d.ts +19 -0
- package/dist/commands/audit/policy.d.ts.map +1 -0
- package/dist/commands/audit/policy.js +102 -0
- package/dist/commands/audit/scoring.d.ts +23 -0
- package/dist/commands/audit/scoring.d.ts.map +1 -0
- package/dist/commands/audit/scoring.js +70 -0
- package/dist/commands/audit/types.d.ts +88 -0
- package/dist/commands/audit/types.d.ts.map +1 -0
- package/dist/commands/audit/types.js +8 -0
- package/dist/commands/audit.d.ts +2 -60
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +2 -1097
- package/dist/commands/baseline.d.ts +1 -0
- package/dist/commands/baseline.d.ts.map +1 -1
- package/dist/commands/baseline.js +205 -121
- package/dist/commands/comment.d.ts +22 -0
- package/dist/commands/comment.d.ts.map +1 -1
- package/dist/commands/comment.js +122 -58
- package/dist/commands/compare.d.ts +17 -0
- package/dist/commands/compare.d.ts.map +1 -1
- package/dist/commands/compare.js +287 -180
- package/dist/commands/diff.d.ts +5 -0
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +168 -141
- package/dist/commands/doc.d.ts +10 -0
- package/dist/commands/doc.d.ts.map +1 -1
- package/dist/commands/doc.js +134 -76
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +164 -17
- package/dist/commands/download.d.ts +10 -0
- package/dist/commands/download.d.ts.map +1 -1
- package/dist/commands/download.js +169 -112
- package/dist/commands/explain.d.ts +5 -0
- package/dist/commands/explain.d.ts.map +1 -1
- package/dist/commands/explain.js +241 -155
- package/dist/commands/fix-all.d.ts +25 -0
- package/dist/commands/fix-all.d.ts.map +1 -0
- package/dist/commands/fix-all.js +206 -0
- package/dist/commands/fix-plan.d.ts +9 -0
- package/dist/commands/fix-plan.d.ts.map +1 -1
- package/dist/commands/fix-plan.js +152 -89
- package/dist/commands/fix.d.ts +17 -0
- package/dist/commands/fix.d.ts.map +1 -0
- package/dist/commands/fix.js +111 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +94 -42
- package/dist/commands/login.d.ts +18 -0
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +263 -92
- package/dist/commands/patch-review.d.ts +11 -0
- package/dist/commands/patch-review.d.ts.map +1 -1
- package/dist/commands/patch-review.js +159 -97
- package/dist/commands/policy.d.ts +31 -0
- package/dist/commands/policy.d.ts.map +1 -1
- package/dist/commands/policy.js +269 -124
- package/dist/commands/release-notes.d.ts +10 -0
- package/dist/commands/release-notes.d.ts.map +1 -1
- package/dist/commands/release-notes.js +127 -73
- package/dist/commands/scan.d.ts +13 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +133 -0
- package/dist/commands/status.d.ts +9 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +81 -0
- package/dist/commands/suggest.d.ts +10 -0
- package/dist/commands/suggest.d.ts.map +1 -1
- package/dist/commands/suggest.js +153 -82
- package/dist/commands/triage.d.ts +35 -0
- package/dist/commands/triage.d.ts.map +1 -1
- package/dist/commands/triage.js +206 -81
- package/dist/commands/upload.d.ts +9 -0
- package/dist/commands/upload.d.ts.map +1 -1
- package/dist/commands/upload.js +140 -101
- package/dist/commands/verify.d.ts +13 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +118 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +125 -990
- package/dist/interactive/fix-wizard.d.ts +3 -0
- package/dist/interactive/fix-wizard.d.ts.map +1 -1
- package/dist/interactive/fix-wizard.js +130 -112
- package/dist/interactive/init-wizard.d.ts +3 -1
- package/dist/interactive/init-wizard.d.ts.map +1 -1
- package/dist/interactive/init-wizard.js +207 -138
- package/dist/interactive/prompts.d.ts +7 -3
- package/dist/interactive/prompts.d.ts.map +1 -1
- package/dist/interactive/prompts.js +44 -23
- package/dist/output/envelope.d.ts +2 -0
- package/dist/output/envelope.d.ts.map +1 -1
- package/dist/output/envelope.js +18 -2
- package/dist/output/factory.d.ts +2 -1
- package/dist/output/factory.d.ts.map +1 -1
- package/dist/output/html.d.ts +2 -1
- package/dist/output/html.d.ts.map +1 -1
- package/dist/output/html.js +3 -2
- package/dist/output/human.d.ts +2 -1
- package/dist/output/human.d.ts.map +1 -1
- package/dist/output/human.js +3 -2
- package/dist/output/json.d.ts +2 -1
- package/dist/output/json.d.ts.map +1 -1
- package/dist/output/junit.d.ts +2 -1
- package/dist/output/junit.d.ts.map +1 -1
- package/dist/output/sarif.d.ts +2 -1
- package/dist/output/sarif.d.ts.map +1 -1
- package/dist/types.d.ts +74 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/ui/banner.d.ts +34 -0
- package/dist/ui/banner.d.ts.map +1 -1
- package/dist/ui/banner.js +97 -5
- package/dist/ui/diagnostics.d.ts +9 -4
- package/dist/ui/diagnostics.d.ts.map +1 -1
- package/dist/ui/diagnostics.js +32 -82
- package/dist/ui/strings.d.ts +373 -0
- package/dist/ui/strings.d.ts.map +1 -0
- package/dist/ui/strings.js +499 -0
- package/dist/ui/table.d.ts +0 -2
- package/dist/ui/table.d.ts.map +1 -1
- package/dist/ui/table.js +3 -4
- package/dist/utils/api-client.d.ts +46 -0
- package/dist/utils/api-client.d.ts.map +1 -0
- package/dist/utils/api-client.js +170 -0
- package/dist/utils/client.d.ts +29 -18
- package/dist/utils/client.d.ts.map +1 -1
- package/dist/utils/client.js +102 -12
- package/dist/utils/formatters.d.ts +38 -0
- package/dist/utils/formatters.d.ts.map +1 -0
- package/dist/utils/formatters.js +277 -0
- package/dist/utils/url-classify.d.ts.map +1 -1
- package/dist/utils/url-classify.js +24 -3
- package/node_modules/@vertaaux/tui/dist/index.cjs +713 -20
- package/node_modules/@vertaaux/tui/dist/index.cjs.map +1 -1
- package/node_modules/@vertaaux/tui/dist/index.d.cts +361 -4
- package/node_modules/@vertaaux/tui/dist/index.d.ts +361 -4
- package/node_modules/@vertaaux/tui/dist/index.js +689 -21
- package/node_modules/@vertaaux/tui/dist/index.js.map +1 -1
- package/package.json +13 -5
- package/dist/commands/client.d.ts +0 -14
- package/dist/commands/client.d.ts.map +0 -1
- package/dist/commands/client.js +0 -362
- package/dist/commands/drift.d.ts +0 -15
- package/dist/commands/drift.d.ts.map +0 -1
- package/dist/commands/drift.js +0 -309
- package/dist/commands/protect.d.ts +0 -16
- package/dist/commands/protect.d.ts.map +0 -1
- package/dist/commands/protect.js +0 -323
- package/dist/commands/report.d.ts +0 -15
- package/dist/commands/report.d.ts.map +0 -1
- package/dist/commands/report.js +0 -214
- package/dist/policy/sync.d.ts +0 -67
- package/dist/policy/sync.d.ts.map +0 -1
- package/dist/policy/sync.js +0 -147
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
* git diff HEAD~1 | vertaa patch-review --job abc123
|
|
10
10
|
* cat fix.patch | vertaa patch-review --findings findings.json
|
|
11
11
|
*/
|
|
12
|
-
import
|
|
12
|
+
import { bold, dim, colorize, boldColor, brand, severity as severityPalette, renderError, createRenderer, runSteps } from "@vertaaux/tui";
|
|
13
13
|
import { ExitCode } from "../utils/exit-codes.js";
|
|
14
|
-
import { resolveApiBase, getApiKey, apiRequest } from "../utils/client.js";
|
|
14
|
+
import { resolveApiBase, getApiKey, apiRequest, createClient } from "../utils/client.js";
|
|
15
15
|
import { resolveConfig } from "../config/loader.js";
|
|
16
16
|
import { writeJsonOutput, writeOutput } from "../output/envelope.js";
|
|
17
17
|
import { resolveCommandFormat } from "../output/formats.js";
|
|
18
|
-
import { createSpinner, succeedSpinner } from "../ui/spinner.js";
|
|
19
18
|
import { readTextInput, readJsonInput } from "../utils/stdin.js";
|
|
20
|
-
import {
|
|
19
|
+
import { AI_TIMEOUT_MS } from "../utils/ai-error.js";
|
|
20
|
+
import { strings } from "../ui/strings.js";
|
|
21
21
|
// ---------------------------------------------------------------------------
|
|
22
22
|
// Helpers
|
|
23
23
|
// ---------------------------------------------------------------------------
|
|
@@ -50,46 +50,172 @@ function normalizeIssues(issues) {
|
|
|
50
50
|
// Formatters
|
|
51
51
|
// ---------------------------------------------------------------------------
|
|
52
52
|
const VERDICT_DISPLAY = {
|
|
53
|
-
SAFE:
|
|
54
|
-
UNSAFE:
|
|
55
|
-
NEEDS_REVIEW:
|
|
53
|
+
SAFE: boldColor("SAFE", brand.lime),
|
|
54
|
+
UNSAFE: boldColor("UNSAFE", severityPalette.error),
|
|
55
|
+
NEEDS_REVIEW: boldColor("NEEDS REVIEW", severityPalette.warning),
|
|
56
56
|
};
|
|
57
57
|
const CONCERN_SEVERITY = {
|
|
58
|
-
critical:
|
|
59
|
-
warning:
|
|
60
|
-
info:
|
|
58
|
+
critical: colorize("critical", severityPalette.critical),
|
|
59
|
+
warning: colorize("warning", severityPalette.warning),
|
|
60
|
+
info: colorize("info", brand.cyan),
|
|
61
61
|
};
|
|
62
62
|
function formatPatchReviewHuman(data) {
|
|
63
63
|
const lines = [];
|
|
64
|
-
const verdictDisplay = VERDICT_DISPLAY[data.verdict] ||
|
|
64
|
+
const verdictDisplay = VERDICT_DISPLAY[data.verdict] || bold(data.verdict);
|
|
65
65
|
lines.push(`Verdict: ${verdictDisplay} (confidence: ${data.confidence}%)`);
|
|
66
66
|
lines.push("");
|
|
67
67
|
lines.push(data.summary);
|
|
68
68
|
if (data.concerns.length > 0) {
|
|
69
69
|
lines.push("");
|
|
70
|
-
lines.push(
|
|
70
|
+
lines.push(bold("Concerns:"));
|
|
71
71
|
for (const concern of data.concerns) {
|
|
72
|
-
const sev = CONCERN_SEVERITY[concern.severity] ||
|
|
73
|
-
const loc = concern.location ?
|
|
72
|
+
const sev = CONCERN_SEVERITY[concern.severity] || dim(concern.severity);
|
|
73
|
+
const loc = concern.location ? dim(` @ ${concern.location}`) : "";
|
|
74
74
|
lines.push(` ${sev}${loc}: ${concern.description}`);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
if (data.findings_addressed.length > 0) {
|
|
78
78
|
lines.push("");
|
|
79
|
-
lines.push(
|
|
79
|
+
lines.push(colorize(`Findings addressed (${data.findings_addressed.length}):`, brand.lime));
|
|
80
80
|
for (const id of data.findings_addressed) {
|
|
81
|
-
lines.push(` ${
|
|
81
|
+
lines.push(` ${colorize("+", brand.lime)} ${id}`);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
if (data.findings_remaining.length > 0) {
|
|
85
85
|
lines.push("");
|
|
86
|
-
lines.push(
|
|
86
|
+
lines.push(colorize(`Findings remaining (${data.findings_remaining.length}):`, severityPalette.warning));
|
|
87
87
|
for (const id of data.findings_remaining) {
|
|
88
|
-
lines.push(` ${
|
|
88
|
+
lines.push(` ${colorize("-", severityPalette.warning)} ${id}`);
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
return lines.join("\n");
|
|
92
92
|
}
|
|
93
|
+
export async function handlePatchReview(opts) {
|
|
94
|
+
const config = { apiKey: opts.apiKey };
|
|
95
|
+
const format = resolveCommandFormat("patch-review", opts.format, opts.machine || false);
|
|
96
|
+
const renderer = createRenderer("auto");
|
|
97
|
+
const baseState = {
|
|
98
|
+
phase: "patch-review",
|
|
99
|
+
phaseIndex: 1,
|
|
100
|
+
phaseTotal: 2,
|
|
101
|
+
url: "",
|
|
102
|
+
mode: "patch-review",
|
|
103
|
+
progress: {},
|
|
104
|
+
totals: {},
|
|
105
|
+
issueCount: 0,
|
|
106
|
+
scorePreview: null,
|
|
107
|
+
verbose: false,
|
|
108
|
+
elapsed: 0,
|
|
109
|
+
};
|
|
110
|
+
const startTime = Date.now();
|
|
111
|
+
let responseData = null;
|
|
112
|
+
const steps = [
|
|
113
|
+
{
|
|
114
|
+
id: "load",
|
|
115
|
+
actionText: "Loading patch...",
|
|
116
|
+
summaryText: "Patch loaded",
|
|
117
|
+
run: async () => {
|
|
118
|
+
// Read diff content
|
|
119
|
+
let diffContent;
|
|
120
|
+
if (opts.diffFile) {
|
|
121
|
+
const fs = await import("fs");
|
|
122
|
+
const path = await import("path");
|
|
123
|
+
const resolved = path.resolve(process.cwd(), opts.diffFile);
|
|
124
|
+
if (!fs.existsSync(resolved)) {
|
|
125
|
+
throw new Error(`Diff file not found: ${opts.diffFile}`);
|
|
126
|
+
}
|
|
127
|
+
diffContent = fs.readFileSync(resolved, "utf-8");
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
const text = await readTextInput();
|
|
131
|
+
if (!text) {
|
|
132
|
+
throw new Error("No diff provided.\nPipe a diff via stdin or use --diff-file:\n gh pr diff 123 | vertaa patch-review --job abc123\n vertaa patch-review --diff-file fix.patch --findings audit.json");
|
|
133
|
+
}
|
|
134
|
+
diffContent = text;
|
|
135
|
+
}
|
|
136
|
+
// Resolve findings
|
|
137
|
+
let findingsList = null;
|
|
138
|
+
let jobId = null;
|
|
139
|
+
if (opts.job) {
|
|
140
|
+
const sdkClient = createClient({ base: opts.base, apiKey: config.apiKey });
|
|
141
|
+
const result = await sdkClient.audits.retrieve(opts.job);
|
|
142
|
+
findingsList = normalizeIssues(result.issues);
|
|
143
|
+
jobId = result.job_id || opts.job;
|
|
144
|
+
}
|
|
145
|
+
else if (opts.findings) {
|
|
146
|
+
const input = await readJsonInput(opts.findings);
|
|
147
|
+
if (input) {
|
|
148
|
+
const data = input;
|
|
149
|
+
const innerData = (data.data && typeof data.data === "object" ? data.data : data);
|
|
150
|
+
findingsList = normalizeIssues(innerData.issues);
|
|
151
|
+
jobId = innerData.job_id || null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (opts.dryRun) {
|
|
155
|
+
const lines = [];
|
|
156
|
+
lines.push(`${colorize("[dry-run]", severityPalette.warning)} ${strings.patchReview.dryRun}`);
|
|
157
|
+
lines.push(` Diff size: ${diffContent.length} characters`);
|
|
158
|
+
lines.push(` Findings: ${findingsList ? findingsList.length : "none"}`);
|
|
159
|
+
lines.push(` Job ID: ${jobId || "none"}`);
|
|
160
|
+
writeOutput(lines.join("\n"));
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const base = resolveApiBase(opts.base);
|
|
164
|
+
const apiKey = getApiKey(config.apiKey);
|
|
165
|
+
const response = await Promise.race([
|
|
166
|
+
apiRequest(base, "/cli/ai/patch-review", {
|
|
167
|
+
method: "POST",
|
|
168
|
+
body: {
|
|
169
|
+
diff: diffContent,
|
|
170
|
+
findings: findingsList,
|
|
171
|
+
job_id: jobId,
|
|
172
|
+
},
|
|
173
|
+
}, apiKey),
|
|
174
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("LLM request timed out")), AI_TIMEOUT_MS)),
|
|
175
|
+
]);
|
|
176
|
+
responseData = response.data;
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
id: "review",
|
|
181
|
+
actionText: strings.patchReview.analyze.action,
|
|
182
|
+
summaryText: responseData ? strings.patchReview.analyze.done(responseData.verdict) : "Review complete",
|
|
183
|
+
run: async () => {
|
|
184
|
+
// Review happened in load step via API call
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
];
|
|
188
|
+
const { success, states } = await runSteps(steps, {
|
|
189
|
+
onStateChange: (stepStates) => {
|
|
190
|
+
renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
renderer.finish({
|
|
194
|
+
url: "",
|
|
195
|
+
mode: "patch-review",
|
|
196
|
+
overallScore: success ? 100 : 0,
|
|
197
|
+
scores: {},
|
|
198
|
+
issueCount: 0,
|
|
199
|
+
passed: success,
|
|
200
|
+
elapsed: Date.now() - startTime,
|
|
201
|
+
});
|
|
202
|
+
if (!success) {
|
|
203
|
+
const failed = states.find(s => s.status === "failed");
|
|
204
|
+
process.stderr.write(renderError({
|
|
205
|
+
message: failed?.failReason || "Command failed",
|
|
206
|
+
suggestion: "vertaa doctor",
|
|
207
|
+
}) + "\n");
|
|
208
|
+
process.exitCode = ExitCode.ERROR;
|
|
209
|
+
}
|
|
210
|
+
if (success && responseData && !opts.dryRun) {
|
|
211
|
+
if (format === "json") {
|
|
212
|
+
writeJsonOutput(responseData, "patch-review");
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
writeOutput(formatPatchReviewHuman(responseData));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
93
219
|
// ---------------------------------------------------------------------------
|
|
94
220
|
// Command Registration
|
|
95
221
|
// ---------------------------------------------------------------------------
|
|
@@ -113,87 +239,23 @@ Examples:
|
|
|
113
239
|
const config = await resolveConfig(globalOpts.config);
|
|
114
240
|
const machineMode = globalOpts.machine || false;
|
|
115
241
|
const dryRun = globalOpts.dryRun || false;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
diffContent = fs.readFileSync(resolved, "utf-8");
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
const text = await readTextInput();
|
|
131
|
-
if (!text) {
|
|
132
|
-
console.error("Error: No diff provided.");
|
|
133
|
-
console.error("Pipe a diff via stdin or use --diff-file:");
|
|
134
|
-
console.error(" gh pr diff 123 | vertaa patch-review --job abc123");
|
|
135
|
-
console.error(" vertaa patch-review --diff-file fix.patch --findings audit.json");
|
|
136
|
-
process.exit(ExitCode.ERROR);
|
|
137
|
-
}
|
|
138
|
-
diffContent = text;
|
|
139
|
-
}
|
|
140
|
-
// Resolve findings
|
|
141
|
-
let findingsList = null;
|
|
142
|
-
let jobId = null;
|
|
143
|
-
if (options.job) {
|
|
144
|
-
const base = resolveApiBase(globalOpts.base);
|
|
145
|
-
const apiKey = getApiKey(config.apiKey);
|
|
146
|
-
const result = await apiRequest(base, `/audit/${options.job}`, { method: "GET" }, apiKey);
|
|
147
|
-
findingsList = normalizeIssues(result.issues);
|
|
148
|
-
jobId = result.job_id || options.job;
|
|
149
|
-
}
|
|
150
|
-
else if (options.findings) {
|
|
151
|
-
const input = await readJsonInput(options.findings);
|
|
152
|
-
if (input) {
|
|
153
|
-
const data = input;
|
|
154
|
-
const innerData = (data.data && typeof data.data === "object" ? data.data : data);
|
|
155
|
-
findingsList = normalizeIssues(innerData.issues);
|
|
156
|
-
jobId = innerData.job_id || null;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
if (dryRun) {
|
|
160
|
-
console.log(chalk.yellow("[dry-run]") + " Would analyze diff against findings");
|
|
161
|
-
console.log(` Diff size: ${diffContent.length} characters`);
|
|
162
|
-
console.log(` Findings: ${findingsList ? findingsList.length : "none"}`);
|
|
163
|
-
console.log(` Job ID: ${jobId || "none"}`);
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
// Auth check
|
|
167
|
-
const base = resolveApiBase(globalOpts.base);
|
|
168
|
-
const apiKey = getApiKey(config.apiKey);
|
|
169
|
-
// Call LLM patch-review API
|
|
170
|
-
const spinner = createSpinner("Reviewing patch...");
|
|
171
|
-
try {
|
|
172
|
-
const response = await Promise.race([
|
|
173
|
-
apiRequest(base, "/cli/ai/patch-review", {
|
|
174
|
-
method: "POST",
|
|
175
|
-
body: {
|
|
176
|
-
diff: diffContent,
|
|
177
|
-
findings: findingsList,
|
|
178
|
-
job_id: jobId,
|
|
179
|
-
},
|
|
180
|
-
}, apiKey),
|
|
181
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error("LLM request timed out")), AI_TIMEOUT_MS)),
|
|
182
|
-
]);
|
|
183
|
-
succeedSpinner(spinner, "Review complete");
|
|
184
|
-
if (format === "json") {
|
|
185
|
-
writeJsonOutput(response.data, "patch-review");
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
writeOutput(formatPatchReviewHuman(response.data));
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
catch (error) {
|
|
192
|
-
handleAiCommandError(error, "patch-review", spinner);
|
|
193
|
-
}
|
|
242
|
+
await handlePatchReview({
|
|
243
|
+
job: options.job,
|
|
244
|
+
findings: options.findings,
|
|
245
|
+
diffFile: options.diffFile,
|
|
246
|
+
format: options.format,
|
|
247
|
+
base: globalOpts.base,
|
|
248
|
+
machine: machineMode,
|
|
249
|
+
dryRun,
|
|
250
|
+
apiKey: config.apiKey,
|
|
251
|
+
});
|
|
194
252
|
}
|
|
195
253
|
catch (error) {
|
|
196
|
-
|
|
254
|
+
process.stderr.write(renderError({
|
|
255
|
+
message: error instanceof Error ? error.message : String(error),
|
|
256
|
+
suggestion: "vertaa doctor",
|
|
257
|
+
exitCode: ExitCode.ERROR,
|
|
258
|
+
}) + "\n");
|
|
197
259
|
process.exit(ExitCode.ERROR);
|
|
198
260
|
}
|
|
199
261
|
});
|
|
@@ -6,8 +6,39 @@
|
|
|
6
6
|
* Implements CICD-17: Policy-as-code support.
|
|
7
7
|
*/
|
|
8
8
|
import { Command } from "commander";
|
|
9
|
+
import { type PolicyTemplate } from "../policy/index.js";
|
|
10
|
+
/**
|
|
11
|
+
* Policy init command options.
|
|
12
|
+
*/
|
|
13
|
+
interface PolicyInitOptions {
|
|
14
|
+
template?: PolicyTemplate;
|
|
15
|
+
output?: string;
|
|
16
|
+
force?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Policy validate command options.
|
|
20
|
+
*/
|
|
21
|
+
interface PolicyValidateOptions {
|
|
22
|
+
quiet?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Policy show command options.
|
|
26
|
+
*/
|
|
27
|
+
interface PolicyShowOptions {
|
|
28
|
+
branch?: string;
|
|
29
|
+
format?: "yaml" | "json";
|
|
30
|
+
policy?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Unified handlePolicy entry point for CommandRunnerView.
|
|
34
|
+
* Routes to the appropriate sub-command handler.
|
|
35
|
+
*/
|
|
36
|
+
export declare function handlePolicy(subCommand: "init" | "validate" | "show" | "schema", options: PolicyInitOptions & PolicyValidateOptions & PolicyShowOptions & {
|
|
37
|
+
file?: string;
|
|
38
|
+
}): Promise<void>;
|
|
9
39
|
/**
|
|
10
40
|
* Register the policy command with the Commander program.
|
|
11
41
|
*/
|
|
12
42
|
export declare function registerPolicyCommand(program: Command): void;
|
|
43
|
+
export {};
|
|
13
44
|
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/commands/policy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/commands/policy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,OAAO,EASL,KAAK,cAAc,EAIpB,MAAM,oBAAoB,CAAC;AAM5B;;GAEG;AACH,UAAU,iBAAiB;IACzB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,UAAU,qBAAqB;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,UAAU,iBAAiB;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAmZD;;;GAGG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,EACnD,OAAO,EAAE,iBAAiB,GAAG,qBAAqB,GAAG,iBAAiB,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACzF,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqI5D"}
|