@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
package/dist/commands/login.js
CHANGED
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
* - vertaa logout: Clear stored credentials
|
|
7
7
|
* - vertaa whoami: Show current authentication status
|
|
8
8
|
*/
|
|
9
|
-
import
|
|
9
|
+
import { colorize, bold, brand, severity as severityPalette, renderError, renderWarning, runSteps, createRenderer } from "@vertaaux/tui";
|
|
10
10
|
import { saveToken, loadToken, clearToken, isTokenExpired, } from "../auth/token-store.js";
|
|
11
11
|
import { startDeviceFlow } from "../auth/device-flow.js";
|
|
12
12
|
import { validateCIToken, getCIToken, getTokenInfo } from "../auth/ci-token.js";
|
|
13
13
|
import { isInteractive } from "../interactive/prompts.js";
|
|
14
14
|
import { ExitCode } from "../utils/exit-codes.js";
|
|
15
|
+
import { writeOutput } from "../output/envelope.js";
|
|
16
|
+
import { strings } from "../ui/strings.js";
|
|
15
17
|
/**
|
|
16
18
|
* OAuth client ID for the CLI.
|
|
17
19
|
* This is a public client ID, not a secret.
|
|
@@ -40,147 +42,285 @@ function getApiBase() {
|
|
|
40
42
|
/**
|
|
41
43
|
* Handle the login command.
|
|
42
44
|
*/
|
|
43
|
-
async function handleLogin(options) {
|
|
45
|
+
export async function handleLogin(options) {
|
|
44
46
|
// Check for SSO placeholder
|
|
45
47
|
if (options.sso) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
process.stderr.write(renderWarning({
|
|
49
|
+
message: strings.login.ssoNotImplemented,
|
|
50
|
+
suggestion: "vertaa login",
|
|
51
|
+
}) + "\n");
|
|
48
52
|
process.exit(ExitCode.ERROR);
|
|
49
53
|
}
|
|
54
|
+
const renderer = createRenderer("auto");
|
|
55
|
+
const baseState = {
|
|
56
|
+
phase: "login",
|
|
57
|
+
phaseIndex: 1,
|
|
58
|
+
phaseTotal: 1,
|
|
59
|
+
url: "",
|
|
60
|
+
mode: "login",
|
|
61
|
+
progress: {},
|
|
62
|
+
totals: {},
|
|
63
|
+
issueCount: 0,
|
|
64
|
+
scorePreview: null,
|
|
65
|
+
verbose: false,
|
|
66
|
+
elapsed: 0,
|
|
67
|
+
};
|
|
68
|
+
const startTime = Date.now();
|
|
50
69
|
// Option 1: Direct token authentication (CI mode)
|
|
51
70
|
if (options.token) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
71
|
+
const steps = [
|
|
72
|
+
{
|
|
73
|
+
id: "validate",
|
|
74
|
+
actionText: strings.login.validatingToken,
|
|
75
|
+
summaryText: "Token validated",
|
|
76
|
+
run: async () => {
|
|
77
|
+
const apiBase = options.base || getApiBase();
|
|
78
|
+
const isValid = await validateCIToken(options.token, apiBase);
|
|
79
|
+
if (!isValid) {
|
|
80
|
+
throw new Error(strings.login.errors.invalidToken);
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: "save",
|
|
86
|
+
actionText: "Saving credentials...",
|
|
87
|
+
summaryText: "Credentials saved",
|
|
88
|
+
run: async () => {
|
|
89
|
+
const tokenData = {
|
|
90
|
+
accessToken: options.token,
|
|
91
|
+
type: "ci",
|
|
92
|
+
savedAt: new Date().toISOString(),
|
|
93
|
+
};
|
|
94
|
+
await saveToken(tokenData);
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
];
|
|
98
|
+
await runSteps(steps, {
|
|
99
|
+
failFast: true,
|
|
100
|
+
onStateChange: (stepStates) => {
|
|
101
|
+
renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
renderer.finish({ url: "", mode: "login", overallScore: 0, scores: {}, issueCount: 0, passed: true, elapsed: Date.now() - startTime });
|
|
105
|
+
writeOutput(colorize(strings.login.success, brand.lime) + "\n" + strings.login.tokenSaved);
|
|
68
106
|
return;
|
|
69
107
|
}
|
|
70
108
|
// Option 2: Check for CI token in environment
|
|
71
109
|
const envToken = getCIToken();
|
|
72
110
|
if (envToken && !isInteractive()) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
111
|
+
const steps = [
|
|
112
|
+
{
|
|
113
|
+
id: "validate",
|
|
114
|
+
actionText: strings.login.envTokenFound,
|
|
115
|
+
summaryText: "Environment token validated",
|
|
116
|
+
run: async () => {
|
|
117
|
+
const apiBase = options.base || getApiBase();
|
|
118
|
+
const isValid = await validateCIToken(envToken, apiBase);
|
|
119
|
+
if (!isValid) {
|
|
120
|
+
throw new Error(strings.login.errors.envTokenInvalid);
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
id: "save",
|
|
126
|
+
actionText: "Saving credentials...",
|
|
127
|
+
summaryText: "Credentials saved",
|
|
128
|
+
run: async () => {
|
|
129
|
+
const tokenData = {
|
|
130
|
+
accessToken: envToken,
|
|
131
|
+
type: "ci",
|
|
132
|
+
savedAt: new Date().toISOString(),
|
|
133
|
+
};
|
|
134
|
+
await saveToken(tokenData);
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
await runSteps(steps, {
|
|
139
|
+
failFast: true,
|
|
140
|
+
onStateChange: (stepStates) => {
|
|
141
|
+
renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
renderer.finish({ url: "", mode: "login", overallScore: 0, scores: {}, issueCount: 0, passed: true, elapsed: Date.now() - startTime });
|
|
145
|
+
writeOutput(colorize(strings.login.success, brand.lime) + "\n" + strings.login.envTokenSaved);
|
|
88
146
|
return;
|
|
89
147
|
}
|
|
90
148
|
// Option 3: Interactive device code flow (requires TTY)
|
|
91
149
|
if (!isInteractive()) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
150
|
+
process.stderr.write(renderError({
|
|
151
|
+
message: strings.login.errors.requiresTerminal,
|
|
152
|
+
suggestion: "vertaa login --token <api-key>",
|
|
153
|
+
exitCode: ExitCode.ERROR,
|
|
154
|
+
}) + "\n");
|
|
95
155
|
process.exit(ExitCode.ERROR);
|
|
96
156
|
}
|
|
97
157
|
// Start device code flow
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
158
|
+
const steps = [
|
|
159
|
+
{
|
|
160
|
+
id: "auth",
|
|
161
|
+
actionText: strings.login.startingAuth,
|
|
162
|
+
summaryText: "Authenticated",
|
|
163
|
+
run: async () => {
|
|
164
|
+
const authBase = options.base ? options.base.replace("/v1", "") : getAuthBase();
|
|
165
|
+
const result = await startDeviceFlow(CLI_CLIENT_ID, authBase);
|
|
166
|
+
// Calculate expiration time
|
|
167
|
+
const expiresAt = new Date(Date.now() + result.expiresIn * 1000).toISOString();
|
|
168
|
+
// Save token
|
|
169
|
+
const tokenData = {
|
|
170
|
+
accessToken: result.accessToken,
|
|
171
|
+
refreshToken: result.refreshToken,
|
|
172
|
+
expiresAt,
|
|
173
|
+
type: "device",
|
|
174
|
+
savedAt: new Date().toISOString(),
|
|
175
|
+
};
|
|
176
|
+
await saveToken(tokenData);
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
];
|
|
180
|
+
await runSteps(steps, {
|
|
181
|
+
failFast: true,
|
|
182
|
+
onStateChange: (stepStates) => {
|
|
183
|
+
renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
renderer.finish({ url: "", mode: "login", overallScore: 0, scores: {}, issueCount: 0, passed: true, elapsed: Date.now() - startTime });
|
|
187
|
+
writeOutput(colorize(strings.login.success, brand.lime) + "\n" + strings.login.tokenSaved);
|
|
120
188
|
}
|
|
121
189
|
/**
|
|
122
190
|
* Handle the logout command.
|
|
123
191
|
*/
|
|
124
|
-
async function handleLogout() {
|
|
192
|
+
export async function handleLogout() {
|
|
193
|
+
const renderer = createRenderer("auto");
|
|
194
|
+
const baseState = {
|
|
195
|
+
phase: "logout",
|
|
196
|
+
phaseIndex: 1,
|
|
197
|
+
phaseTotal: 1,
|
|
198
|
+
url: "",
|
|
199
|
+
mode: "logout",
|
|
200
|
+
progress: {},
|
|
201
|
+
totals: {},
|
|
202
|
+
issueCount: 0,
|
|
203
|
+
scorePreview: null,
|
|
204
|
+
verbose: false,
|
|
205
|
+
elapsed: 0,
|
|
206
|
+
};
|
|
207
|
+
const startTime = Date.now();
|
|
208
|
+
const steps = [
|
|
209
|
+
{
|
|
210
|
+
id: "clear",
|
|
211
|
+
actionText: "Clearing credentials...",
|
|
212
|
+
summaryText: "Credentials cleared",
|
|
213
|
+
run: async () => {
|
|
214
|
+
const existingToken = await loadToken();
|
|
215
|
+
if (!existingToken) {
|
|
216
|
+
// Not an error — just nothing to clear
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
await clearToken();
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
];
|
|
223
|
+
// Check if already logged out before step-list
|
|
125
224
|
const existingToken = await loadToken();
|
|
126
225
|
if (!existingToken) {
|
|
127
|
-
|
|
226
|
+
writeOutput(strings.login.noStoredCredentials);
|
|
128
227
|
return;
|
|
129
228
|
}
|
|
130
|
-
await
|
|
131
|
-
|
|
132
|
-
|
|
229
|
+
await runSteps(steps, {
|
|
230
|
+
failFast: true,
|
|
231
|
+
onStateChange: (stepStates) => {
|
|
232
|
+
renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
renderer.finish({ url: "", mode: "logout", overallScore: 0, scores: {}, issueCount: 0, passed: true, elapsed: Date.now() - startTime });
|
|
236
|
+
writeOutput(colorize(strings.login.logoutSuccess, brand.lime) + "\n" + strings.login.credentialsRemoved);
|
|
133
237
|
}
|
|
134
238
|
/**
|
|
135
239
|
* Handle the whoami command.
|
|
136
240
|
*/
|
|
137
|
-
async function handleWhoami(options) {
|
|
241
|
+
export async function handleWhoami(options) {
|
|
242
|
+
const renderer = createRenderer("auto");
|
|
243
|
+
const baseState = {
|
|
244
|
+
phase: "whoami",
|
|
245
|
+
phaseIndex: 1,
|
|
246
|
+
phaseTotal: 1,
|
|
247
|
+
url: "",
|
|
248
|
+
mode: "whoami",
|
|
249
|
+
progress: {},
|
|
250
|
+
totals: {},
|
|
251
|
+
issueCount: 0,
|
|
252
|
+
scorePreview: null,
|
|
253
|
+
verbose: false,
|
|
254
|
+
elapsed: 0,
|
|
255
|
+
};
|
|
256
|
+
const startTime = Date.now();
|
|
138
257
|
// Check for token in credentials file
|
|
139
258
|
const storedToken = await loadToken();
|
|
140
259
|
// Check for token in environment
|
|
141
260
|
const envToken = getCIToken();
|
|
142
261
|
if (!storedToken && !envToken) {
|
|
143
|
-
|
|
144
|
-
|
|
262
|
+
writeOutput(colorize(strings.login.notAuthenticated, severityPalette.warning) +
|
|
263
|
+
"\n" + strings.login.runLoginHint);
|
|
145
264
|
return;
|
|
146
265
|
}
|
|
147
266
|
// Use stored token or env token
|
|
148
267
|
const token = storedToken?.accessToken || envToken;
|
|
149
|
-
const tokenSource = storedToken ? "stored" : "environment";
|
|
150
268
|
if (!token) {
|
|
151
|
-
|
|
152
|
-
|
|
269
|
+
writeOutput(colorize(strings.login.notAuthenticated, severityPalette.warning) +
|
|
270
|
+
"\n" + strings.login.runLoginHint);
|
|
153
271
|
return;
|
|
154
272
|
}
|
|
155
273
|
// Check expiration for stored device tokens
|
|
156
274
|
if (storedToken && storedToken.type === "device" && isTokenExpired(storedToken)) {
|
|
157
|
-
|
|
158
|
-
|
|
275
|
+
writeOutput(colorize(strings.login.tokenExpired, severityPalette.warning) +
|
|
276
|
+
"\n" + strings.login.runLoginRefreshHint);
|
|
159
277
|
return;
|
|
160
278
|
}
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
279
|
+
let whoamiResult = null;
|
|
280
|
+
const steps = [
|
|
281
|
+
{
|
|
282
|
+
id: "check",
|
|
283
|
+
actionText: "Checking identity...",
|
|
284
|
+
summaryText: "Identity verified",
|
|
285
|
+
run: async () => {
|
|
286
|
+
const apiBase = options.base || getApiBase();
|
|
287
|
+
whoamiResult = await getTokenInfo(token, apiBase);
|
|
288
|
+
if (!whoamiResult || !whoamiResult.valid) {
|
|
289
|
+
throw new Error(strings.login.tokenInvalidOrExpired);
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
];
|
|
294
|
+
await runSteps(steps, {
|
|
295
|
+
failFast: true,
|
|
296
|
+
onStateChange: (stepStates) => {
|
|
297
|
+
renderer.update({ ...baseState, stepStates, elapsed: Date.now() - startTime });
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
renderer.finish({ url: "", mode: "whoami", overallScore: 0, scores: {}, issueCount: 0, passed: true, elapsed: Date.now() - startTime });
|
|
301
|
+
if (!whoamiResult || !whoamiResult.valid) {
|
|
302
|
+
writeOutput(colorize(strings.login.tokenInvalidOrExpired, severityPalette.warning) +
|
|
303
|
+
"\n" + strings.login.runLoginRefreshHint);
|
|
167
304
|
return;
|
|
168
305
|
}
|
|
169
|
-
|
|
306
|
+
const info = whoamiResult;
|
|
307
|
+
// Display auth status via writeOutput
|
|
170
308
|
const displayName = info.name || info.email || info.user_id || "Unknown";
|
|
171
|
-
|
|
172
|
-
|
|
309
|
+
const lines = [
|
|
310
|
+
colorize(strings.login.successWithName(bold(displayName)), brand.lime),
|
|
311
|
+
"",
|
|
312
|
+
];
|
|
173
313
|
if (info.email) {
|
|
174
|
-
|
|
314
|
+
lines.push(` Email: ${info.email}`);
|
|
175
315
|
}
|
|
176
316
|
if (info.tier) {
|
|
177
|
-
|
|
317
|
+
lines.push(` Plan: ${info.tier.charAt(0).toUpperCase() + info.tier.slice(1)}`);
|
|
178
318
|
}
|
|
179
319
|
if (info.organization) {
|
|
180
|
-
|
|
320
|
+
lines.push(` Organization: ${info.organization}`);
|
|
181
321
|
}
|
|
182
322
|
if (info.scopes && info.scopes.length > 0) {
|
|
183
|
-
|
|
323
|
+
lines.push(` Scopes: ${info.scopes.join(", ")}`);
|
|
184
324
|
}
|
|
185
325
|
if (storedToken?.expiresAt) {
|
|
186
326
|
const expiresAt = new Date(storedToken.expiresAt);
|
|
@@ -188,9 +328,10 @@ async function handleWhoami(options) {
|
|
|
188
328
|
const diffMs = expiresAt.getTime() - now.getTime();
|
|
189
329
|
const diffHours = Math.round(diffMs / (1000 * 60 * 60));
|
|
190
330
|
if (diffHours > 0) {
|
|
191
|
-
|
|
331
|
+
lines.push(` Expires: in ${diffHours} hour${diffHours === 1 ? "" : "s"}`);
|
|
192
332
|
}
|
|
193
333
|
}
|
|
334
|
+
writeOutput(lines.join("\n"));
|
|
194
335
|
}
|
|
195
336
|
/**
|
|
196
337
|
* Register authentication commands with the Commander program.
|
|
@@ -199,19 +340,39 @@ export function registerLoginCommand(program) {
|
|
|
199
340
|
// Login command
|
|
200
341
|
program
|
|
201
342
|
.command("login")
|
|
202
|
-
.description("Authenticate with VertaaUX")
|
|
203
|
-
.option("--token <token>", "Use API token directly (
|
|
343
|
+
.description("Authenticate with VertaaUX (stores SDK credentials in ~/.vertaaux/credentials.json)")
|
|
344
|
+
.option("--token <token>", "Use API token directly (stored as SDK default credentials)")
|
|
204
345
|
.option("--sso", "Use SSO login (not yet implemented)")
|
|
205
346
|
.option("-b, --base <url>", "API base URL")
|
|
206
347
|
.action(async (options) => {
|
|
207
|
-
|
|
348
|
+
try {
|
|
349
|
+
await handleLogin(options);
|
|
350
|
+
}
|
|
351
|
+
catch (error) {
|
|
352
|
+
process.stderr.write(renderError({
|
|
353
|
+
message: error instanceof Error ? error.message : String(error),
|
|
354
|
+
suggestion: "vertaa login",
|
|
355
|
+
exitCode: ExitCode.ERROR,
|
|
356
|
+
}) + "\n");
|
|
357
|
+
process.exit(ExitCode.ERROR);
|
|
358
|
+
}
|
|
208
359
|
});
|
|
209
360
|
// Logout command
|
|
210
361
|
program
|
|
211
362
|
.command("logout")
|
|
212
363
|
.description("Clear stored credentials")
|
|
213
364
|
.action(async () => {
|
|
214
|
-
|
|
365
|
+
try {
|
|
366
|
+
await handleLogout();
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
process.stderr.write(renderError({
|
|
370
|
+
message: error instanceof Error ? error.message : String(error),
|
|
371
|
+
suggestion: "vertaa login",
|
|
372
|
+
exitCode: ExitCode.ERROR,
|
|
373
|
+
}) + "\n");
|
|
374
|
+
process.exit(ExitCode.ERROR);
|
|
375
|
+
}
|
|
215
376
|
});
|
|
216
377
|
// Whoami command
|
|
217
378
|
program
|
|
@@ -219,6 +380,16 @@ export function registerLoginCommand(program) {
|
|
|
219
380
|
.description("Show current authentication status")
|
|
220
381
|
.option("-b, --base <url>", "API base URL")
|
|
221
382
|
.action(async (options) => {
|
|
222
|
-
|
|
383
|
+
try {
|
|
384
|
+
await handleWhoami(options);
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
process.stderr.write(renderError({
|
|
388
|
+
message: error instanceof Error ? error.message : String(error),
|
|
389
|
+
suggestion: "vertaa whoami",
|
|
390
|
+
exitCode: ExitCode.ERROR,
|
|
391
|
+
}) + "\n");
|
|
392
|
+
process.exit(ExitCode.ERROR);
|
|
393
|
+
}
|
|
223
394
|
});
|
|
224
395
|
}
|
|
@@ -10,5 +10,16 @@
|
|
|
10
10
|
* cat fix.patch | vertaa patch-review --findings findings.json
|
|
11
11
|
*/
|
|
12
12
|
import { Command } from "commander";
|
|
13
|
+
export interface PatchReviewCommandOptions {
|
|
14
|
+
job?: string;
|
|
15
|
+
findings?: string;
|
|
16
|
+
diffFile?: string;
|
|
17
|
+
format?: string;
|
|
18
|
+
base?: string;
|
|
19
|
+
machine?: boolean;
|
|
20
|
+
dryRun?: boolean;
|
|
21
|
+
apiKey?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function handlePatchReview(opts: PatchReviewCommandOptions): Promise<void>;
|
|
13
24
|
export declare function registerPatchReviewCommand(program: Command): void;
|
|
14
25
|
//# sourceMappingURL=patch-review.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patch-review.d.ts","sourceRoot":"","sources":["../../src/commands/patch-review.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmIpC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"patch-review.d.ts","sourceRoot":"","sources":["../../src/commands/patch-review.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmIpC,MAAM,WAAW,yBAAyB;IACxC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkJtF;AAMD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6CjE"}
|