@vertaaux/cli 0.3.3 → 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 +14 -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 -1038
- 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 +268 -95
- 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 +9 -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 +9 -1
- package/dist/output/human.d.ts.map +1 -1
- package/dist/output/human.js +17 -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/local-capture.d.ts +25 -0
- package/dist/utils/local-capture.d.ts.map +1 -0
- package/dist/utils/local-capture.js +57 -0
- package/dist/utils/url-classify.d.ts +18 -0
- package/dist/utils/url-classify.d.ts.map +1 -0
- package/dist/utils/url-classify.js +106 -0
- 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,145 +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
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
306
|
+
const info = whoamiResult;
|
|
307
|
+
// Display auth status via writeOutput
|
|
308
|
+
const displayName = info.name || info.email || info.user_id || "Unknown";
|
|
309
|
+
const lines = [
|
|
310
|
+
colorize(strings.login.successWithName(bold(displayName)), brand.lime),
|
|
311
|
+
"",
|
|
312
|
+
];
|
|
313
|
+
if (info.email) {
|
|
314
|
+
lines.push(` Email: ${info.email}`);
|
|
176
315
|
}
|
|
177
|
-
if (info.
|
|
178
|
-
|
|
316
|
+
if (info.tier) {
|
|
317
|
+
lines.push(` Plan: ${info.tier.charAt(0).toUpperCase() + info.tier.slice(1)}`);
|
|
318
|
+
}
|
|
319
|
+
if (info.organization) {
|
|
320
|
+
lines.push(` Organization: ${info.organization}`);
|
|
179
321
|
}
|
|
180
322
|
if (info.scopes && info.scopes.length > 0) {
|
|
181
|
-
|
|
323
|
+
lines.push(` Scopes: ${info.scopes.join(", ")}`);
|
|
182
324
|
}
|
|
183
325
|
if (storedToken?.expiresAt) {
|
|
184
326
|
const expiresAt = new Date(storedToken.expiresAt);
|
|
@@ -186,9 +328,10 @@ async function handleWhoami(options) {
|
|
|
186
328
|
const diffMs = expiresAt.getTime() - now.getTime();
|
|
187
329
|
const diffHours = Math.round(diffMs / (1000 * 60 * 60));
|
|
188
330
|
if (diffHours > 0) {
|
|
189
|
-
|
|
331
|
+
lines.push(` Expires: in ${diffHours} hour${diffHours === 1 ? "" : "s"}`);
|
|
190
332
|
}
|
|
191
333
|
}
|
|
334
|
+
writeOutput(lines.join("\n"));
|
|
192
335
|
}
|
|
193
336
|
/**
|
|
194
337
|
* Register authentication commands with the Commander program.
|
|
@@ -197,19 +340,39 @@ export function registerLoginCommand(program) {
|
|
|
197
340
|
// Login command
|
|
198
341
|
program
|
|
199
342
|
.command("login")
|
|
200
|
-
.description("Authenticate with VertaaUX")
|
|
201
|
-
.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)")
|
|
202
345
|
.option("--sso", "Use SSO login (not yet implemented)")
|
|
203
346
|
.option("-b, --base <url>", "API base URL")
|
|
204
347
|
.action(async (options) => {
|
|
205
|
-
|
|
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
|
+
}
|
|
206
359
|
});
|
|
207
360
|
// Logout command
|
|
208
361
|
program
|
|
209
362
|
.command("logout")
|
|
210
363
|
.description("Clear stored credentials")
|
|
211
364
|
.action(async () => {
|
|
212
|
-
|
|
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
|
+
}
|
|
213
376
|
});
|
|
214
377
|
// Whoami command
|
|
215
378
|
program
|
|
@@ -217,6 +380,16 @@ export function registerLoginCommand(program) {
|
|
|
217
380
|
.description("Show current authentication status")
|
|
218
381
|
.option("-b, --base <url>", "API base URL")
|
|
219
382
|
.action(async (options) => {
|
|
220
|
-
|
|
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
|
+
}
|
|
221
394
|
});
|
|
222
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"}
|