@vibecheckai/cli 3.5.4 → 3.6.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/bin/runners/lib/approve-output.js +235 -0
- package/bin/runners/lib/classify-output.js +204 -0
- package/bin/runners/lib/doctor-output.js +226 -0
- package/bin/runners/lib/fix-output.js +228 -0
- package/bin/runners/lib/prove-output.js +220 -0
- package/bin/runners/lib/reality-output.js +231 -0
- package/bin/runners/lib/report-output.js +299 -120
- package/bin/runners/lib/scan-output.js +333 -270
- package/bin/runners/lib/ship-output.js +283 -93
- package/bin/runners/lib/status-output.js +258 -171
- package/bin/runners/runApprove.js +3 -1
- package/bin/runners/runClassify.js +3 -1
- package/bin/runners/runDoctor.js +27 -36
- package/bin/runners/runFix.js +45 -22
- package/bin/runners/runProve.js +18 -58
- package/bin/runners/runReality.js +26 -40
- package/package.json +4 -4
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enterprise Reality Output - V5 "Mission Control" Format
|
|
3
|
+
* Features:
|
|
4
|
+
* - Dynamic "REALITY" ASCII Art
|
|
5
|
+
* - Runtime Verification Status
|
|
6
|
+
* - Browser Test Results
|
|
7
|
+
* - Pixel-perfect 80-char alignment
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
// ANSI Color Helpers
|
|
13
|
+
const ESC = '\x1b';
|
|
14
|
+
const chalk = {
|
|
15
|
+
reset: `${ESC}[0m`,
|
|
16
|
+
bold: `${ESC}[1m`,
|
|
17
|
+
dim: `${ESC}[2m`,
|
|
18
|
+
red: `${ESC}[31m`,
|
|
19
|
+
green: `${ESC}[32m`,
|
|
20
|
+
yellow: `${ESC}[33m`,
|
|
21
|
+
cyan: `${ESC}[36m`,
|
|
22
|
+
magenta: `${ESC}[35m`,
|
|
23
|
+
white: `${ESC}[37m`,
|
|
24
|
+
gray: `${ESC}[90m`,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
28
|
+
// CONFIGURATION
|
|
29
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
30
|
+
|
|
31
|
+
const WIDTH = 80;
|
|
32
|
+
|
|
33
|
+
const BOX = {
|
|
34
|
+
topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',
|
|
35
|
+
horizontal: '═', vertical: '║',
|
|
36
|
+
teeRight: '╠', teeLeft: '╣', teeTop: '╤', teeBottom: '╧',
|
|
37
|
+
cross: '╪',
|
|
38
|
+
lightH: '─', lightV: '│',
|
|
39
|
+
lightTeeLeft: '├', lightTeeRight: '┤', lightCross: '┼'
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// EXTERNAL HEADER
|
|
43
|
+
const LOGO_VIBECHECK = `
|
|
44
|
+
██╗ ██╗██╗██████╗ ███████╗ ██████╗██╗ ██╗███████╗ ██████╗██╗ ██╗
|
|
45
|
+
██║ ██║██║██╔══██╗██╔════╝██╔════╝██║ ██║██╔════╝██╔════╝██║ ██╔╝
|
|
46
|
+
██║ ██║██║██████╔╝█████╗ ██║ ███████║█████╗ ██║ █████╔╝
|
|
47
|
+
╚██╗ ██╔╝██║██╔══██╗██╔══╝ ██║ ██╔══██║██╔══╝ ██║ ██╔═██╗
|
|
48
|
+
╚████╔╝ ██║██████╔╝███████╗╚██████╗██║ ██║███████╗╚██████╗██║ ██╗
|
|
49
|
+
╚═══╝ ╚═╝╚═════╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═════╝╚═╝ ╚═╝
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
// HERO: REALITY (Green/Blue)
|
|
53
|
+
const LOGO_REALITY = `
|
|
54
|
+
██████╗ ███████╗ █████╗ ██╗ ██╗████████╗██╗ ██╗
|
|
55
|
+
██╔══██╗██╔════╝██╔══██╗██║ ██║╚══██╔══╝╚██╗ ██╔╝
|
|
56
|
+
██████╔╝█████╗ ███████║██║ ██║ ██║ ╚████╔╝
|
|
57
|
+
██╔══██╗██╔══╝ ██╔══██║██║ ██║ ██║ ╚██╔╝
|
|
58
|
+
██║ ██║███████╗██║ ██║███████╗██║ ██║ ██║
|
|
59
|
+
╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝
|
|
60
|
+
`;
|
|
61
|
+
|
|
62
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
63
|
+
// UTILITIES
|
|
64
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
65
|
+
|
|
66
|
+
function stripAnsi(str) {
|
|
67
|
+
return str.replace(/\x1b\[[0-9;]*m/g, '');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function padCenter(str, width) {
|
|
71
|
+
const visibleLen = stripAnsi(str).length;
|
|
72
|
+
const padding = Math.max(0, width - visibleLen);
|
|
73
|
+
const left = Math.floor(padding / 2);
|
|
74
|
+
const right = padding - left;
|
|
75
|
+
return ' '.repeat(left) + str + ' '.repeat(right);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function padRight(str, len) {
|
|
79
|
+
const visibleLen = stripAnsi(str).length;
|
|
80
|
+
const truncated = visibleLen > len ? str.substring(0, len - 3) + '...' : str;
|
|
81
|
+
return truncated + ' '.repeat(Math.max(0, len - visibleLen));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
85
|
+
// MAIN FORMATTER
|
|
86
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
87
|
+
|
|
88
|
+
function formatRealityOutput(result, options = {}) {
|
|
89
|
+
const {
|
|
90
|
+
verdict = null,
|
|
91
|
+
tests = [],
|
|
92
|
+
passed = 0,
|
|
93
|
+
failed = 0,
|
|
94
|
+
warnings = 0,
|
|
95
|
+
coverage = 0,
|
|
96
|
+
duration = 0,
|
|
97
|
+
url = null,
|
|
98
|
+
success = false,
|
|
99
|
+
error = null,
|
|
100
|
+
} = result;
|
|
101
|
+
|
|
102
|
+
const isSuccess = success || (verdict === 'SHIP' && failed === 0);
|
|
103
|
+
const themeColor = isSuccess ? chalk.green : error ? chalk.red : chalk.yellow;
|
|
104
|
+
const statusText = isSuccess ? 'VERIFICATION PASSED' : error ? 'VERIFICATION FAILED' : 'VERIFICATION IN PROGRESS';
|
|
105
|
+
|
|
106
|
+
const lines = [];
|
|
107
|
+
|
|
108
|
+
// 1. Render External Header
|
|
109
|
+
lines.push(chalk.cyan + LOGO_VIBECHECK.trim() + chalk.reset);
|
|
110
|
+
lines.push('');
|
|
111
|
+
|
|
112
|
+
// 2. Render Box Top
|
|
113
|
+
lines.push(`${chalk.gray}${BOX.topLeft}${BOX.horizontal.repeat(WIDTH - 2)}${BOX.topRight}${chalk.reset}`);
|
|
114
|
+
lines.push(`${chalk.gray}${BOX.vertical}${' '.repeat(WIDTH - 2)}${BOX.vertical}${chalk.reset}`);
|
|
115
|
+
|
|
116
|
+
// 3. Render Hero Logo (REALITY)
|
|
117
|
+
LOGO_REALITY.trim().split('\n').filter(l => l.trim().length > 0).forEach(l => {
|
|
118
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset}${themeColor}${padCenter(l.trim(), WIDTH - 2)}${chalk.reset}${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
119
|
+
});
|
|
120
|
+
lines.push(`${chalk.gray}${BOX.vertical}${' '.repeat(WIDTH - 2)}${BOX.vertical}${chalk.reset}`);
|
|
121
|
+
|
|
122
|
+
// 4. Info Row
|
|
123
|
+
const version = options.version || 'v3.5.5';
|
|
124
|
+
const infoText = `${chalk.bold}${version} REALITY${chalk.reset} :: STATUS: ${themeColor}${statusText}${chalk.reset}`;
|
|
125
|
+
const metaText = `Tests: ${tests.length} | Passed: ${passed}`;
|
|
126
|
+
const infoLine = ` ${infoText}${' '.repeat(Math.max(1, WIDTH - 6 - stripAnsi(infoText).length - stripAnsi(metaText).length))}${chalk.dim}${metaText}${chalk.reset}`;
|
|
127
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset}${infoLine} ${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
128
|
+
|
|
129
|
+
const urlLine = url ? ` URL: ${padRight(url, 50)}` : ` Project: ${padRight(path.basename(options.projectPath || process.cwd()), 50)}`;
|
|
130
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset}${urlLine}${' '.repeat(WIDTH - 2 - stripAnsi(urlLine).length)}${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
131
|
+
|
|
132
|
+
// 5. Split Pane
|
|
133
|
+
lines.push(`${chalk.gray}${BOX.teeRight}${BOX.horizontal.repeat(44)}${BOX.teeTop}${BOX.horizontal.repeat(WIDTH - 47)}${BOX.teeLeft}${chalk.reset}`);
|
|
134
|
+
|
|
135
|
+
function printSplitRow(left, right) {
|
|
136
|
+
const leftContent = padRight(left || '', 42);
|
|
137
|
+
const rightContent = padRight(right || '', WIDTH - 48);
|
|
138
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset} ${leftContent} ${chalk.gray}${BOX.lightV}${chalk.reset} ${rightContent} ${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Row 1: Headers
|
|
142
|
+
printSplitRow(`${chalk.bold}RUNTIME TESTS${chalk.reset}`, `${chalk.bold}VERIFICATION RESULTS${chalk.reset}`);
|
|
143
|
+
|
|
144
|
+
// Row 2: Divider
|
|
145
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset} ${BOX.lightH.repeat(42)} ${chalk.gray}${BOX.lightCross}${chalk.reset} ${BOX.lightH.repeat(WIDTH - 48)} ${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
146
|
+
|
|
147
|
+
// Prepare Left Column
|
|
148
|
+
const totalTests = tests.length || (passed + failed);
|
|
149
|
+
const passRate = totalTests > 0 ? Math.round((passed / totalTests) * 100) : 0;
|
|
150
|
+
const leftCol = [
|
|
151
|
+
'',
|
|
152
|
+
` VERDICT [${verdict === 'SHIP' ? chalk.green + 'SHIP' : verdict === 'BLOCK' ? chalk.red + 'BLOCK' : chalk.yellow + 'WARN'}${chalk.reset}]`,
|
|
153
|
+
` Status: ${verdict || 'N/A'}`,
|
|
154
|
+
'',
|
|
155
|
+
`${chalk.gray}${BOX.lightH.repeat(42)}${chalk.reset}`,
|
|
156
|
+
`${chalk.bold} TEST RESULTS${chalk.reset}`,
|
|
157
|
+
'',
|
|
158
|
+
` Total: ${chalk.cyan}${totalTests}${chalk.reset}`,
|
|
159
|
+
` Passed: ${chalk.green}${passed}${chalk.reset}`,
|
|
160
|
+
` Failed: ${chalk.red}${failed}${chalk.reset}`,
|
|
161
|
+
` Warnings: ${chalk.yellow}${warnings}${chalk.reset}`,
|
|
162
|
+
` Pass Rate: ${chalk.cyan}${passRate}%${chalk.reset}`,
|
|
163
|
+
];
|
|
164
|
+
|
|
165
|
+
// Prepare Right Column
|
|
166
|
+
const rightCol = [];
|
|
167
|
+
rightCol.push('');
|
|
168
|
+
|
|
169
|
+
rightCol.push(` COVERAGE [${coverage}%]`);
|
|
170
|
+
rightCol.push(` Routes: ${chalk.cyan}${coverage}%${chalk.reset}`);
|
|
171
|
+
rightCol.push('');
|
|
172
|
+
|
|
173
|
+
if (isSuccess) {
|
|
174
|
+
rightCol.push(`${chalk.green} [✓] VERIFIED${chalk.reset}`);
|
|
175
|
+
rightCol.push(` All runtime tests`);
|
|
176
|
+
rightCol.push(` passed.`);
|
|
177
|
+
} else if (error) {
|
|
178
|
+
rightCol.push(`${chalk.red} [!] FAILED${chalk.reset}`);
|
|
179
|
+
rightCol.push(` Verification error.`);
|
|
180
|
+
rightCol.push('');
|
|
181
|
+
let msg = error.message || 'Unknown error';
|
|
182
|
+
if (msg.length > 25) msg = msg.substring(0, 25) + '...';
|
|
183
|
+
rightCol.push(` ${chalk.red}${msg}${chalk.reset}`);
|
|
184
|
+
} else {
|
|
185
|
+
rightCol.push(`${chalk.yellow} [○] IN PROGRESS${chalk.reset}`);
|
|
186
|
+
rightCol.push(` Running browser`);
|
|
187
|
+
rightCol.push(` tests...`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (tests.length > 0) {
|
|
191
|
+
rightCol.push('');
|
|
192
|
+
rightCol.push(`${chalk.bold} TEST SUMMARY${chalk.reset}`);
|
|
193
|
+
tests.slice(0, 3).forEach((test, i) => {
|
|
194
|
+
const status = test.passed ? chalk.green + '✓' : chalk.red + '✖';
|
|
195
|
+
const name = (test.name || test.route || 'Test').substring(0, 20);
|
|
196
|
+
rightCol.push(` ${status}${chalk.reset} ${name}`);
|
|
197
|
+
});
|
|
198
|
+
if (tests.length > 3) {
|
|
199
|
+
rightCol.push(` ${chalk.dim}... ${tests.length - 3} more${chalk.reset}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Merge Columns
|
|
204
|
+
const maxRows = Math.max(leftCol.length, rightCol.length);
|
|
205
|
+
for (let i = 0; i < maxRows; i++) {
|
|
206
|
+
printSplitRow(leftCol[i] || '', rightCol[i] || '');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// 6. Action Footer
|
|
210
|
+
lines.push(`${chalk.gray}${BOX.teeRight}${BOX.horizontal.repeat(WIDTH - 2)}${BOX.teeLeft}${chalk.reset}`);
|
|
211
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset} ${chalk.bold}RUNTIME CONTROL${chalk.reset}${' '.repeat(WIDTH - 17)}${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
212
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset} ${BOX.lightH.repeat(WIDTH - 4)} ${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
213
|
+
|
|
214
|
+
if (isSuccess) {
|
|
215
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset} ${chalk.green}[✓] RUNTIME VERIFIED. READY FOR PRODUCTION.${chalk.reset}${' '.repeat(WIDTH - 45)}${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
216
|
+
lines.push(`${chalk.gray}${BOX.vertical}${' '.repeat(WIDTH - 2)}${BOX.vertical}${chalk.reset}`);
|
|
217
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset} > ${chalk.cyan}vibecheck ship${chalk.reset} [DEPLOY] Proceed with deployment ${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
218
|
+
} else {
|
|
219
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset} ${chalk.red}[!] VERIFICATION FAILED. REVIEW REQUIRED.${chalk.reset}${' '.repeat(WIDTH - 42)}${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
220
|
+
lines.push(`${chalk.gray}${BOX.vertical}${' '.repeat(WIDTH - 2)}${BOX.vertical}${chalk.reset}`);
|
|
221
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset} > ${chalk.cyan}vibecheck reality --retry${chalk.reset} [RETRY] Re-run verification ${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
222
|
+
lines.push(`${chalk.gray}${BOX.vertical}${chalk.reset} > ${chalk.cyan}vibecheck fix --apply${chalk.reset} [FIX] Apply fixes before retry ${chalk.gray}${BOX.vertical}${chalk.reset}`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// 7. Box Bottom
|
|
226
|
+
lines.push(`${chalk.gray}${BOX.bottomLeft}${BOX.horizontal.repeat(WIDTH - 2)}${BOX.bottomRight}${chalk.reset}`);
|
|
227
|
+
|
|
228
|
+
return lines.join('\n');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
module.exports = { formatRealityOutput };
|