@vertaaux/cli 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +116 -0
- package/MIGRATION.md +239 -0
- package/README.md +62 -17
- package/dist/app/interactive-app.d.ts +103 -0
- package/dist/app/interactive-app.d.ts.map +1 -0
- package/dist/app/interactive-app.js +328 -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 +166 -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 +415 -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 +46 -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 +11 -0
- package/dist/commands/a11y.d.ts.map +1 -0
- package/dist/commands/a11y.js +149 -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 +589 -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 +129 -0
- package/dist/commands/audit/policy.d.ts +27 -0
- package/dist/commands/audit/policy.d.ts.map +1 -0
- package/dist/commands/audit/policy.js +147 -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 +89 -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 +2 -0
- package/dist/commands/baseline.d.ts.map +1 -1
- package/dist/commands/baseline.js +221 -123
- package/dist/commands/comment.d.ts +22 -0
- package/dist/commands/comment.d.ts.map +1 -1
- package/dist/commands/comment.js +127 -62
- package/dist/commands/compare.d.ts +17 -0
- package/dist/commands/compare.d.ts.map +1 -1
- package/dist/commands/compare.js +288 -181
- package/dist/commands/diff.d.ts +7 -0
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +181 -143
- package/dist/commands/doc.d.ts +10 -0
- package/dist/commands/doc.d.ts.map +1 -1
- package/dist/commands/doc.js +135 -77
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +166 -19
- 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 +242 -156
- 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 +154 -90
- 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 +160 -98
- package/dist/commands/policy.d.ts +31 -0
- package/dist/commands/policy.d.ts.map +1 -1
- package/dist/commands/policy.js +270 -125
- 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 +128 -74
- 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 +180 -83
- package/dist/commands/triage.d.ts +35 -0
- package/dist/commands/triage.d.ts.map +1 -1
- package/dist/commands/triage.js +207 -82
- 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/config/schema.d.ts +4 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +127 -991
- 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 +9 -0
- package/dist/output/envelope.d.ts.map +1 -1
- package/dist/output/envelope.js +37 -3
- 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/policy/schema.d.ts +137 -0
- package/dist/policy/schema.d.ts.map +1 -1
- package/dist/policy/schema.js +107 -0
- package/dist/prompts/command-catalog.js +9 -9
- 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 +104 -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/root-args.d.ts +12 -0
- package/dist/utils/root-args.d.ts.map +1 -0
- package/dist/utils/root-args.js +44 -0
- package/dist/utils/stdin.d.ts +7 -0
- package/dist/utils/stdin.d.ts.map +1 -1
- package/dist/utils/stdin.js +32 -2
- 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 +1216 -27
- 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 +1189 -27
- package/node_modules/@vertaaux/tui/dist/index.js.map +1 -1
- package/node_modules/@vertaaux/tui/package.json +2 -3
- package/node_modules/chalk/license +9 -0
- package/node_modules/chalk/package.json +83 -0
- package/node_modules/chalk/readme.md +297 -0
- package/node_modules/chalk/source/index.d.ts +325 -0
- package/node_modules/chalk/source/index.js +225 -0
- package/node_modules/chalk/source/utilities.js +33 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
- package/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
- package/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
- package/package.json +20 -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
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import tty from 'node:tty';
|
|
4
|
+
|
|
5
|
+
// From: https://github.com/sindresorhus/has-flag/blob/main/index.js
|
|
6
|
+
/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
|
|
7
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {
|
|
8
|
+
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
|
|
9
|
+
const position = argv.indexOf(prefix + flag);
|
|
10
|
+
const terminatorPosition = argv.indexOf('--');
|
|
11
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const {env} = process;
|
|
15
|
+
|
|
16
|
+
let flagForceColor;
|
|
17
|
+
if (
|
|
18
|
+
hasFlag('no-color')
|
|
19
|
+
|| hasFlag('no-colors')
|
|
20
|
+
|| hasFlag('color=false')
|
|
21
|
+
|| hasFlag('color=never')
|
|
22
|
+
) {
|
|
23
|
+
flagForceColor = 0;
|
|
24
|
+
} else if (
|
|
25
|
+
hasFlag('color')
|
|
26
|
+
|| hasFlag('colors')
|
|
27
|
+
|| hasFlag('color=true')
|
|
28
|
+
|| hasFlag('color=always')
|
|
29
|
+
) {
|
|
30
|
+
flagForceColor = 1;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function envForceColor() {
|
|
34
|
+
if ('FORCE_COLOR' in env) {
|
|
35
|
+
if (env.FORCE_COLOR === 'true') {
|
|
36
|
+
return 1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (env.FORCE_COLOR === 'false') {
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function translateLevel(level) {
|
|
48
|
+
if (level === 0) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
level,
|
|
54
|
+
hasBasic: true,
|
|
55
|
+
has256: level >= 2,
|
|
56
|
+
has16m: level >= 3,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
|
|
61
|
+
const noFlagForceColor = envForceColor();
|
|
62
|
+
if (noFlagForceColor !== undefined) {
|
|
63
|
+
flagForceColor = noFlagForceColor;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
67
|
+
|
|
68
|
+
if (forceColor === 0) {
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (sniffFlags) {
|
|
73
|
+
if (hasFlag('color=16m')
|
|
74
|
+
|| hasFlag('color=full')
|
|
75
|
+
|| hasFlag('color=truecolor')) {
|
|
76
|
+
return 3;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (hasFlag('color=256')) {
|
|
80
|
+
return 2;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Check for Azure DevOps pipelines.
|
|
85
|
+
// Has to be above the `!streamIsTTY` check.
|
|
86
|
+
if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
|
|
87
|
+
return 1;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const min = forceColor || 0;
|
|
95
|
+
|
|
96
|
+
if (env.TERM === 'dumb') {
|
|
97
|
+
return min;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (process.platform === 'win32') {
|
|
101
|
+
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
|
|
102
|
+
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
|
|
103
|
+
const osRelease = os.release().split('.');
|
|
104
|
+
if (
|
|
105
|
+
Number(osRelease[0]) >= 10
|
|
106
|
+
&& Number(osRelease[2]) >= 10_586
|
|
107
|
+
) {
|
|
108
|
+
return Number(osRelease[2]) >= 14_931 ? 3 : 2;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return 1;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if ('CI' in env) {
|
|
115
|
+
if (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {
|
|
116
|
+
return 3;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
|
|
120
|
+
return 1;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return min;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if ('TEAMCITY_VERSION' in env) {
|
|
127
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (env.COLORTERM === 'truecolor') {
|
|
131
|
+
return 3;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (env.TERM === 'xterm-kitty') {
|
|
135
|
+
return 3;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (env.TERM === 'xterm-ghostty') {
|
|
139
|
+
return 3;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (env.TERM === 'wezterm') {
|
|
143
|
+
return 3;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if ('TERM_PROGRAM' in env) {
|
|
147
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
|
|
148
|
+
|
|
149
|
+
switch (env.TERM_PROGRAM) {
|
|
150
|
+
case 'iTerm.app': {
|
|
151
|
+
return version >= 3 ? 3 : 2;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
case 'Apple_Terminal': {
|
|
155
|
+
return 2;
|
|
156
|
+
}
|
|
157
|
+
// No default
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (/-256(color)?$/i.test(env.TERM)) {
|
|
162
|
+
return 2;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
166
|
+
return 1;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if ('COLORTERM' in env) {
|
|
170
|
+
return 1;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return min;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function createSupportsColor(stream, options = {}) {
|
|
177
|
+
const level = _supportsColor(stream, {
|
|
178
|
+
streamIsTTY: stream && stream.isTTY,
|
|
179
|
+
...options,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
return translateLevel(level);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const supportsColor = {
|
|
186
|
+
stdout: createSupportsColor({isTTY: tty.isatty(1)}),
|
|
187
|
+
stderr: createSupportsColor({isTTY: tty.isatty(2)}),
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
export default supportsColor;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertaaux/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Run automated UX audits, accessibility checks, and performance analysis from the terminal or CI pipelines. Supports policy gating, SARIF output, and multi-page crawling. See https://github.com/PetriLahdelma/vertaa/tree/main/cli#readme for full docs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
12
|
"schemas",
|
|
13
|
-
"README.md"
|
|
13
|
+
"README.md",
|
|
14
|
+
"CHANGELOG.md",
|
|
15
|
+
"MIGRATION.md"
|
|
14
16
|
],
|
|
15
17
|
"keywords": [
|
|
16
18
|
"vertaaux",
|
|
@@ -24,7 +26,7 @@
|
|
|
24
26
|
],
|
|
25
27
|
"repository": {
|
|
26
28
|
"type": "git",
|
|
27
|
-
"url": "https://github.com/PetriLahdelma/vertaa",
|
|
29
|
+
"url": "git+https://github.com/PetriLahdelma/vertaa.git",
|
|
28
30
|
"directory": "cli"
|
|
29
31
|
},
|
|
30
32
|
"homepage": "https://vertaaux.ai",
|
|
@@ -33,23 +35,34 @@
|
|
|
33
35
|
"access": "public"
|
|
34
36
|
},
|
|
35
37
|
"engines": {
|
|
36
|
-
"node": ">=
|
|
38
|
+
"node": ">=20"
|
|
37
39
|
},
|
|
38
40
|
"bundleDependencies": [
|
|
39
41
|
"@vertaaux/tui"
|
|
40
42
|
],
|
|
41
43
|
"scripts": {
|
|
44
|
+
"prebuild": "node scripts/fix-node-pty-permissions.mjs 2>/dev/null || true",
|
|
42
45
|
"build": "tsc",
|
|
43
46
|
"dev": "tsc -w",
|
|
44
47
|
"start": "node dist/index.js",
|
|
48
|
+
"postinstall": "node scripts/fix-node-pty-permissions.mjs 2>/dev/null || true",
|
|
49
|
+
"pretest": "node scripts/fix-node-pty-permissions.mjs 2>/dev/null || true",
|
|
45
50
|
"prepublishOnly": "npm run build && node scripts/verify-package.mjs",
|
|
46
51
|
"test": "vitest run --config vitest.config.ts --exclude tests/e2e/**/*.test.ts",
|
|
52
|
+
"pretest:e2e": "node scripts/fix-node-pty-permissions.mjs 2>/dev/null || true",
|
|
47
53
|
"test:e2e": "vitest run --config vitest.config.ts tests/e2e/cli-contract.test.ts",
|
|
54
|
+
"pretest:e2e:package": "node scripts/fix-node-pty-permissions.mjs 2>/dev/null || true",
|
|
48
55
|
"test:e2e:package": "vitest run --config vitest.config.ts tests/e2e/package-install.test.ts",
|
|
49
|
-
"
|
|
56
|
+
"pretest:e2e:ui": "node scripts/fix-node-pty-permissions.mjs 2>/dev/null || true",
|
|
57
|
+
"test:e2e:ui": "vitest --ui --config vitest.config.ts tests/e2e/cli-contract.test.ts",
|
|
58
|
+
"pretest:pty": "node scripts/fix-node-pty-permissions.mjs 2>/dev/null || true",
|
|
59
|
+
"test:pty": "vitest run --config vitest.config.pty.ts",
|
|
60
|
+
"pretest:snapshot": "node scripts/fix-node-pty-permissions.mjs 2>/dev/null || true",
|
|
61
|
+
"test:snapshot": "vitest run --config vitest.config.snapshot.ts"
|
|
50
62
|
},
|
|
51
63
|
"dependencies": {
|
|
52
64
|
"@inquirer/prompts": "^8.2.0",
|
|
65
|
+
"@vertaaux/sdk": "^2.0.0",
|
|
53
66
|
"@vertaaux/tui": "file:../packages/tui",
|
|
54
67
|
"ajv": "^8.17.1",
|
|
55
68
|
"ajv-formats": "^3.0.1",
|
|
@@ -66,6 +79,8 @@
|
|
|
66
79
|
"@types/node": "^20.11.25",
|
|
67
80
|
"@types/semver": "^7.7.1",
|
|
68
81
|
"@vitest/ui": "^4.0.18",
|
|
82
|
+
"node-pty": "^1.1.0",
|
|
83
|
+
"strip-ansi": "^7.2.0",
|
|
69
84
|
"typescript": "^5.6.3",
|
|
70
85
|
"vitest": "^4.0.15"
|
|
71
86
|
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Client management commands for VertaaUX CLI.
|
|
3
|
-
*
|
|
4
|
-
* Provides agency client CRUD operations and batch auditing
|
|
5
|
-
* across client URL portfolios with bounded concurrency.
|
|
6
|
-
*
|
|
7
|
-
* Implements 46-06: CLI client management and batch audit.
|
|
8
|
-
*/
|
|
9
|
-
import { Command } from "commander";
|
|
10
|
-
/**
|
|
11
|
-
* Register the client command with the Commander program.
|
|
12
|
-
*/
|
|
13
|
-
export declare function registerClientCommand(program: Command): void;
|
|
14
|
-
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/commands/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0HpC;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwX5D"}
|
package/dist/commands/client.js
DELETED
|
@@ -1,362 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Client management commands for VertaaUX CLI.
|
|
3
|
-
*
|
|
4
|
-
* Provides agency client CRUD operations and batch auditing
|
|
5
|
-
* across client URL portfolios with bounded concurrency.
|
|
6
|
-
*
|
|
7
|
-
* Implements 46-06: CLI client management and batch audit.
|
|
8
|
-
*/
|
|
9
|
-
import chalk from "chalk";
|
|
10
|
-
import pLimit from "p-limit";
|
|
11
|
-
import { resolveApiBase, getApiKey, apiRequest } from "../utils/client.js";
|
|
12
|
-
/**
|
|
13
|
-
* Auto-generate a URL-friendly slug from a name.
|
|
14
|
-
*/
|
|
15
|
-
function generateSlug(name) {
|
|
16
|
-
return name
|
|
17
|
-
.toLowerCase()
|
|
18
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
19
|
-
.replace(/^-|-$/g, "");
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Determine if an identifier looks like a CUID (starts with 'c' followed by alphanumerics).
|
|
23
|
-
*/
|
|
24
|
-
function looksLikeCuid(identifier) {
|
|
25
|
-
return /^c[a-z0-9]{20,}$/i.test(identifier);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Resolve API connection settings.
|
|
29
|
-
* Reads from environment variables (standard CLI pattern).
|
|
30
|
-
*/
|
|
31
|
-
function resolveConnection() {
|
|
32
|
-
return {
|
|
33
|
-
base: resolveApiBase(),
|
|
34
|
-
apiKey: getApiKey(),
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Format a date string for display.
|
|
39
|
-
*/
|
|
40
|
-
function formatDate(dateStr) {
|
|
41
|
-
try {
|
|
42
|
-
const d = new Date(dateStr);
|
|
43
|
-
return d.toISOString().split("T")[0];
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
46
|
-
return dateStr;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Wait for an audit to complete by polling the status endpoint.
|
|
51
|
-
*/
|
|
52
|
-
async function waitForAuditCompletion(base, apiKey, jobId, timeoutMs = 120000, intervalMs = 3000) {
|
|
53
|
-
const start = Date.now();
|
|
54
|
-
while (true) {
|
|
55
|
-
const status = await apiRequest(base, `/audit/${jobId}`, { method: "GET" }, apiKey);
|
|
56
|
-
if (status.status === "completed")
|
|
57
|
-
return status;
|
|
58
|
-
if (status.status === "failed") {
|
|
59
|
-
throw new Error(status.error || `Audit ${jobId} failed`);
|
|
60
|
-
}
|
|
61
|
-
if (Date.now() - start > timeoutMs) {
|
|
62
|
-
throw new Error(`Timed out waiting for audit ${jobId}`);
|
|
63
|
-
}
|
|
64
|
-
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Compute overall score as mean of category scores.
|
|
69
|
-
*/
|
|
70
|
-
function computeOverallScore(scores) {
|
|
71
|
-
const values = Object.values(scores);
|
|
72
|
-
if (values.length === 0)
|
|
73
|
-
return null;
|
|
74
|
-
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
75
|
-
return Math.round((sum / values.length) * 100) / 100;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Register the client command with the Commander program.
|
|
79
|
-
*/
|
|
80
|
-
export function registerClientCommand(program) {
|
|
81
|
-
const clientCmd = program
|
|
82
|
-
.command("client")
|
|
83
|
-
.description("Manage agency clients");
|
|
84
|
-
// vertaa client create <name>
|
|
85
|
-
clientCmd
|
|
86
|
-
.command("create <name>")
|
|
87
|
-
.description("Create a new client")
|
|
88
|
-
.option("--slug <slug>", "URL-friendly identifier (auto-generated from name if omitted)")
|
|
89
|
-
.option("--urls <urls...>", "URLs to associate with this client")
|
|
90
|
-
.option("--policy <id>", "Policy ID to assign")
|
|
91
|
-
.action(async (name, options) => {
|
|
92
|
-
try {
|
|
93
|
-
const { base, apiKey } = resolveConnection();
|
|
94
|
-
const slug = options.slug || generateSlug(name);
|
|
95
|
-
const body = { name, slug };
|
|
96
|
-
if (options.urls && options.urls.length > 0) {
|
|
97
|
-
body.urls = options.urls;
|
|
98
|
-
}
|
|
99
|
-
if (options.policy) {
|
|
100
|
-
body.policyId = options.policy;
|
|
101
|
-
}
|
|
102
|
-
const client = await apiRequest(base, "/clients", { method: "POST", body }, apiKey);
|
|
103
|
-
process.stderr.write(chalk.green(`Client created successfully\n\n`));
|
|
104
|
-
process.stderr.write(` Name: ${client.name}\n`);
|
|
105
|
-
process.stderr.write(` Slug: ${client.slug}\n`);
|
|
106
|
-
process.stderr.write(` ID: ${client.id}\n`);
|
|
107
|
-
if (client.urls.length > 0) {
|
|
108
|
-
process.stderr.write(` URLs: ${client.urls.join(", ")}\n`);
|
|
109
|
-
}
|
|
110
|
-
if (client.policy) {
|
|
111
|
-
process.stderr.write(` Policy: ${client.policy.name}\n`);
|
|
112
|
-
}
|
|
113
|
-
process.stderr.write("\n");
|
|
114
|
-
}
|
|
115
|
-
catch (error) {
|
|
116
|
-
process.stderr.write(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}\n`));
|
|
117
|
-
process.exit(1);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
// vertaa client list
|
|
121
|
-
clientCmd
|
|
122
|
-
.command("list")
|
|
123
|
-
.description("List all clients")
|
|
124
|
-
.option("--format <format>", "Output format: human|json", "human")
|
|
125
|
-
.action(async (options) => {
|
|
126
|
-
try {
|
|
127
|
-
const { base, apiKey } = resolveConnection();
|
|
128
|
-
const clients = await apiRequest(base, "/clients", { method: "GET" }, apiKey);
|
|
129
|
-
if (options.format === "json") {
|
|
130
|
-
process.stdout.write(JSON.stringify(clients, null, 2) + "\n");
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
// Human format: table
|
|
134
|
-
if (clients.length === 0) {
|
|
135
|
-
process.stderr.write(chalk.dim("No clients found. Create one with: vertaa client create <name>\n"));
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
// Table header
|
|
139
|
-
const nameWidth = 20;
|
|
140
|
-
const slugWidth = 20;
|
|
141
|
-
const urlsWidth = 8;
|
|
142
|
-
const policyWidth = 20;
|
|
143
|
-
const updatedWidth = 12;
|
|
144
|
-
const header = padRight("Name", nameWidth) +
|
|
145
|
-
padRight("Slug", slugWidth) +
|
|
146
|
-
padRight("URLs", urlsWidth) +
|
|
147
|
-
padRight("Policy", policyWidth) +
|
|
148
|
-
padRight("Updated", updatedWidth);
|
|
149
|
-
process.stderr.write("\n");
|
|
150
|
-
process.stderr.write(chalk.bold(header) + "\n");
|
|
151
|
-
process.stderr.write(chalk.dim("-".repeat(nameWidth + slugWidth + urlsWidth + policyWidth + updatedWidth)) + "\n");
|
|
152
|
-
for (const client of clients) {
|
|
153
|
-
const row = padRight(truncate(client.name, nameWidth - 2), nameWidth) +
|
|
154
|
-
padRight(truncate(client.slug, slugWidth - 2), slugWidth) +
|
|
155
|
-
padRight(String(client.urls.length), urlsWidth) +
|
|
156
|
-
padRight(truncate(client.policy?.name || "-", policyWidth - 2), policyWidth) +
|
|
157
|
-
padRight(formatDate(client.updatedAt), updatedWidth);
|
|
158
|
-
process.stderr.write(row + "\n");
|
|
159
|
-
}
|
|
160
|
-
process.stderr.write("\n");
|
|
161
|
-
process.stderr.write(chalk.dim(`${clients.length} client${clients.length !== 1 ? "s" : ""}\n`));
|
|
162
|
-
}
|
|
163
|
-
catch (error) {
|
|
164
|
-
process.stderr.write(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}\n`));
|
|
165
|
-
process.exit(1);
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
// vertaa client remove <identifier>
|
|
169
|
-
clientCmd
|
|
170
|
-
.command("remove <identifier>")
|
|
171
|
-
.description("Remove a client")
|
|
172
|
-
.option("--force", "Skip confirmation")
|
|
173
|
-
.action(async (identifier, options) => {
|
|
174
|
-
try {
|
|
175
|
-
const { base, apiKey } = resolveConnection();
|
|
176
|
-
// Resolve the client: try ID first, then slug lookup
|
|
177
|
-
let clientId;
|
|
178
|
-
let clientName;
|
|
179
|
-
let urlCount;
|
|
180
|
-
if (looksLikeCuid(identifier)) {
|
|
181
|
-
// Looks like an ID, use directly but verify it exists
|
|
182
|
-
const client = await apiRequest(base, `/clients/${identifier}`, { method: "GET" }, apiKey);
|
|
183
|
-
clientId = client.id;
|
|
184
|
-
clientName = client.name;
|
|
185
|
-
urlCount = client.urls.length;
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
// Treat as slug -- look up in the list
|
|
189
|
-
const clients = await apiRequest(base, "/clients", { method: "GET" }, apiKey);
|
|
190
|
-
const match = clients.find((c) => c.slug === identifier || c.name === identifier);
|
|
191
|
-
if (!match) {
|
|
192
|
-
process.stderr.write(chalk.red(`Error: Client "${identifier}" not found.\n`));
|
|
193
|
-
process.exit(1);
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
clientId = match.id;
|
|
197
|
-
clientName = match.name;
|
|
198
|
-
urlCount = match.urls.length;
|
|
199
|
-
}
|
|
200
|
-
// Confirmation gate
|
|
201
|
-
if (!options.force) {
|
|
202
|
-
process.stderr.write(chalk.yellow(`About to delete client '${clientName}' with ${urlCount} URL${urlCount !== 1 ? "s" : ""}. This cannot be undone.\n`));
|
|
203
|
-
process.stderr.write(chalk.dim("Add --force to confirm deletion.\n"));
|
|
204
|
-
process.exit(1);
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
await apiRequest(base, `/clients/${clientId}`, { method: "DELETE" }, apiKey);
|
|
208
|
-
process.stderr.write(chalk.green(`Client '${clientName}' removed.\n`));
|
|
209
|
-
}
|
|
210
|
-
catch (error) {
|
|
211
|
-
process.stderr.write(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}\n`));
|
|
212
|
-
process.exit(1);
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
// vertaa client audit
|
|
216
|
-
clientCmd
|
|
217
|
-
.command("audit")
|
|
218
|
-
.description("Run batch audit across client URLs")
|
|
219
|
-
.option("--client <names>", "Comma-separated client names/slugs (default: all)")
|
|
220
|
-
.option("--concurrency <n>", "Concurrent audits", "3")
|
|
221
|
-
.option("--format <format>", "Output format: human|json", "human")
|
|
222
|
-
.action(async (options) => {
|
|
223
|
-
try {
|
|
224
|
-
const { base, apiKey } = resolveConnection();
|
|
225
|
-
// Fetch all clients
|
|
226
|
-
const allClients = await apiRequest(base, "/clients", { method: "GET" }, apiKey);
|
|
227
|
-
if (allClients.length === 0) {
|
|
228
|
-
process.stderr.write(chalk.dim("No clients found. Create one with: vertaa client create <name>\n"));
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
// Filter by --client if provided
|
|
232
|
-
let selectedClients;
|
|
233
|
-
if (options.client) {
|
|
234
|
-
const names = options.client.split(",").map((n) => n.trim().toLowerCase());
|
|
235
|
-
selectedClients = allClients.filter((c) => names.includes(c.slug.toLowerCase()) ||
|
|
236
|
-
names.includes(c.name.toLowerCase()));
|
|
237
|
-
if (selectedClients.length === 0) {
|
|
238
|
-
process.stderr.write(chalk.red(`Error: No matching clients found for: ${options.client}\n`));
|
|
239
|
-
process.stderr.write(chalk.dim(`Available: ${allClients.map((c) => c.slug).join(", ")}\n`));
|
|
240
|
-
process.exit(1);
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
selectedClients = allClients;
|
|
246
|
-
}
|
|
247
|
-
// Flatten all URLs
|
|
248
|
-
const urlTasks = [];
|
|
249
|
-
for (const client of selectedClients) {
|
|
250
|
-
for (const url of client.urls) {
|
|
251
|
-
urlTasks.push({ client, url });
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
if (urlTasks.length === 0) {
|
|
255
|
-
process.stderr.write(chalk.dim("No URLs to audit across selected clients.\n"));
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
const concurrency = parseInt(options.concurrency, 10) || 3;
|
|
259
|
-
const limit = pLimit(concurrency);
|
|
260
|
-
process.stderr.write(chalk.dim(`Auditing ${urlTasks.length} URL${urlTasks.length !== 1 ? "s" : ""} across ${selectedClients.length} client${selectedClients.length !== 1 ? "s" : ""} (concurrency: ${concurrency})\n\n`));
|
|
261
|
-
// Run batch audits with bounded concurrency
|
|
262
|
-
const results = [];
|
|
263
|
-
let completed = 0;
|
|
264
|
-
const promises = urlTasks.map(({ client, url }) => limit(async () => {
|
|
265
|
-
completed++;
|
|
266
|
-
process.stderr.write(`[${completed}/${urlTasks.length}] Auditing ${url}...`);
|
|
267
|
-
try {
|
|
268
|
-
// Start audit
|
|
269
|
-
const job = await apiRequest(base, "/audit", { method: "POST", body: { url, mode: "basic" } }, apiKey);
|
|
270
|
-
if (!job.job_id) {
|
|
271
|
-
throw new Error("No job_id in audit response");
|
|
272
|
-
}
|
|
273
|
-
// Wait for completion
|
|
274
|
-
const result = await waitForAuditCompletion(base, apiKey, job.job_id);
|
|
275
|
-
const scores = (result.scores || {});
|
|
276
|
-
const overall = computeOverallScore(scores);
|
|
277
|
-
process.stderr.write(` ${chalk.green("done")} (score: ${overall !== null ? overall : "n/a"})\n`);
|
|
278
|
-
results.push({
|
|
279
|
-
client: client.name,
|
|
280
|
-
url,
|
|
281
|
-
score: overall,
|
|
282
|
-
status: "success",
|
|
283
|
-
jobId: job.job_id,
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
catch (err) {
|
|
287
|
-
process.stderr.write(` ${chalk.red("failed")}\n`);
|
|
288
|
-
results.push({
|
|
289
|
-
client: client.name,
|
|
290
|
-
url,
|
|
291
|
-
score: null,
|
|
292
|
-
status: "error",
|
|
293
|
-
error: err instanceof Error ? err.message : String(err),
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
}));
|
|
297
|
-
await Promise.all(promises);
|
|
298
|
-
// Output results
|
|
299
|
-
process.stderr.write("\n");
|
|
300
|
-
if (options.format === "json") {
|
|
301
|
-
// Group by client for JSON output
|
|
302
|
-
const grouped = {};
|
|
303
|
-
for (const r of results) {
|
|
304
|
-
if (!grouped[r.client])
|
|
305
|
-
grouped[r.client] = [];
|
|
306
|
-
grouped[r.client].push(r);
|
|
307
|
-
}
|
|
308
|
-
process.stdout.write(JSON.stringify(grouped, null, 2) + "\n");
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
// Human format: per-client summary
|
|
312
|
-
const grouped = {};
|
|
313
|
-
for (const r of results) {
|
|
314
|
-
if (!grouped[r.client])
|
|
315
|
-
grouped[r.client] = [];
|
|
316
|
-
grouped[r.client].push(r);
|
|
317
|
-
}
|
|
318
|
-
for (const [clientName, clientResults] of Object.entries(grouped)) {
|
|
319
|
-
process.stderr.write(chalk.bold(`${clientName}\n`));
|
|
320
|
-
for (const r of clientResults) {
|
|
321
|
-
const scoreStr = r.status === "success"
|
|
322
|
-
? r.score !== null
|
|
323
|
-
? String(r.score)
|
|
324
|
-
: "n/a"
|
|
325
|
-
: chalk.red("error");
|
|
326
|
-
process.stderr.write(` ${r.url} ${scoreStr}\n`);
|
|
327
|
-
}
|
|
328
|
-
// Client average
|
|
329
|
-
const successScores = clientResults
|
|
330
|
-
.filter((r) => r.status === "success" && r.score !== null)
|
|
331
|
-
.map((r) => r.score);
|
|
332
|
-
if (successScores.length > 0) {
|
|
333
|
-
const avg = Math.round((successScores.reduce((a, b) => a + b, 0) / successScores.length) * 100) / 100;
|
|
334
|
-
process.stderr.write(chalk.dim(` Average: ${avg}\n`));
|
|
335
|
-
}
|
|
336
|
-
process.stderr.write("\n");
|
|
337
|
-
}
|
|
338
|
-
// Overall summary
|
|
339
|
-
const totalSuccess = results.filter((r) => r.status === "success").length;
|
|
340
|
-
const totalFailed = results.filter((r) => r.status === "error").length;
|
|
341
|
-
process.stderr.write(chalk.dim(`Summary: ${totalSuccess} succeeded, ${totalFailed} failed out of ${results.length} audits\n`));
|
|
342
|
-
}
|
|
343
|
-
catch (error) {
|
|
344
|
-
process.stderr.write(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}\n`));
|
|
345
|
-
process.exit(1);
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Pad a string to the right to a given width.
|
|
351
|
-
*/
|
|
352
|
-
function padRight(str, width) {
|
|
353
|
-
return str.length >= width ? str : str + " ".repeat(width - str.length);
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Truncate a string to a maximum length with ellipsis.
|
|
357
|
-
*/
|
|
358
|
-
function truncate(str, maxLen) {
|
|
359
|
-
if (str.length <= maxLen)
|
|
360
|
-
return str;
|
|
361
|
-
return str.slice(0, maxLen - 1) + "\u2026";
|
|
362
|
-
}
|
package/dist/commands/drift.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Drift detection command for VertaaUX CLI.
|
|
3
|
-
*
|
|
4
|
-
* Compares current audit scores against a baseline and reports
|
|
5
|
-
* per-category regressions with delta magnitudes. Used in local
|
|
6
|
-
* workflows and CI pipelines to detect score regressions before merging.
|
|
7
|
-
*
|
|
8
|
-
* Implements DRIFT-01: CLI drift check command.
|
|
9
|
-
*/
|
|
10
|
-
import { Command } from "commander";
|
|
11
|
-
/**
|
|
12
|
-
* Register the drift command with the Commander program.
|
|
13
|
-
*/
|
|
14
|
-
export declare function registerDriftCommand(program: Command): void;
|
|
15
|
-
//# sourceMappingURL=drift.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"drift.d.ts","sourceRoot":"","sources":["../../src/commands/drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyNpC;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsK3D"}
|