@vibecheckai/cli 3.1.4 → 3.1.5
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.
|
@@ -49,10 +49,13 @@ function generateWorldClassHTML(reportData, opts = {}) {
|
|
|
49
49
|
|
|
50
50
|
return `<!DOCTYPE html>
|
|
51
51
|
<html lang="en" data-theme="${theme}">
|
|
52
|
-
<head>
|
|
52
|
+
<head>
|
|
53
53
|
<meta charset="UTF-8">
|
|
54
54
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
55
55
|
<meta name="color-scheme" content="dark light">
|
|
56
|
+
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
|
57
|
+
<meta http-equiv="Pragma" content="no-cache">
|
|
58
|
+
<meta http-equiv="Expires" content="0">
|
|
56
59
|
<title>VibeCheck Report — ${meta.projectName}</title>
|
|
57
60
|
<style>
|
|
58
61
|
/* ========================================
|
|
@@ -128,8 +128,8 @@ function formatHelp() {
|
|
|
128
128
|
Generate beautiful, professional reports for stakeholders.
|
|
129
129
|
|
|
130
130
|
${ansi.bold}Report Types${ansi.reset}
|
|
131
|
-
${colors.accent}
|
|
132
|
-
${colors.accent}
|
|
131
|
+
${colors.accent}technical${ansi.reset} Detailed findings for developers/CTOs (default)
|
|
132
|
+
${colors.accent}executive${ansi.reset} One-page overview for stakeholders
|
|
133
133
|
${colors.accent}compliance${ansi.reset} SOC2/HIPAA-ready language for regulated industries
|
|
134
134
|
${colors.accent}trend${ansi.reset} Historical score analysis over time
|
|
135
135
|
|
package/bin/runners/runReport.js
CHANGED
|
@@ -193,7 +193,9 @@ async function runReport(args) {
|
|
|
193
193
|
|
|
194
194
|
if (!shipResults) {
|
|
195
195
|
spinner.warn("No scan results found - using demo data");
|
|
196
|
-
|
|
196
|
+
if (!opts.quiet) {
|
|
197
|
+
console.log(` ${ansi.dim}Tip: Run 'vibecheck ship' first for real results.${ansi.reset}\n`);
|
|
198
|
+
}
|
|
197
199
|
shipResults = getDemoData();
|
|
198
200
|
}
|
|
199
201
|
|
|
@@ -218,6 +220,14 @@ async function runReport(args) {
|
|
|
218
220
|
try {
|
|
219
221
|
switch (format) {
|
|
220
222
|
case "html":
|
|
223
|
+
// Debug: Log which HTML generator will be used
|
|
224
|
+
if (opts.verbose || opts.type === "technical") {
|
|
225
|
+
if (reportHtml && typeof reportHtml.generateWorldClassHTML === 'function') {
|
|
226
|
+
console.log(` ${ansi.dim}Using world-class HTML generator${ansi.reset}`);
|
|
227
|
+
} else {
|
|
228
|
+
console.log(` ${ansi.dim}Using basic HTML generator (report-html module not available)${ansi.reset}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
221
231
|
reportContent = generateHTMLReport(reportData, opts);
|
|
222
232
|
break;
|
|
223
233
|
case "md":
|
|
@@ -257,9 +267,20 @@ async function runReport(args) {
|
|
|
257
267
|
fs.mkdirSync(outputDirPath, { recursive: true });
|
|
258
268
|
}
|
|
259
269
|
|
|
260
|
-
// Write report
|
|
270
|
+
// Write report (always overwrite to ensure fresh content)
|
|
261
271
|
spinner.update("Writing report");
|
|
262
|
-
fs.writeFileSync(outputFileName, reportContent);
|
|
272
|
+
fs.writeFileSync(outputFileName, reportContent, 'utf8');
|
|
273
|
+
|
|
274
|
+
// If this is the default report.html, also update the timestamp to help with cache busting
|
|
275
|
+
if (!opts.output && fileExtension === 'html') {
|
|
276
|
+
try {
|
|
277
|
+
// Touch the file to update its modification time
|
|
278
|
+
const now = new Date();
|
|
279
|
+
fs.utimesSync(outputFileName, now, now);
|
|
280
|
+
} catch {
|
|
281
|
+
// Ignore errors on utimes
|
|
282
|
+
}
|
|
283
|
+
}
|
|
263
284
|
|
|
264
285
|
// Save report history for trend analysis
|
|
265
286
|
saveReportHistory(outputDir, reportData);
|
|
@@ -407,6 +428,7 @@ function generateHTMLReport(reportData, opts) {
|
|
|
407
428
|
opts
|
|
408
429
|
);
|
|
409
430
|
}
|
|
431
|
+
// Fall through if template not available
|
|
410
432
|
break;
|
|
411
433
|
case "compliance":
|
|
412
434
|
if (reportTemplates?.generateEnhancedComplianceReport) {
|
|
@@ -415,15 +437,39 @@ function generateHTMLReport(reportData, opts) {
|
|
|
415
437
|
opts
|
|
416
438
|
);
|
|
417
439
|
}
|
|
440
|
+
// Fall through if template not available
|
|
418
441
|
break;
|
|
419
442
|
default:
|
|
420
|
-
// Technical report - use world-class HTML generator
|
|
421
|
-
if (reportHtml
|
|
422
|
-
|
|
443
|
+
// Technical report - ALWAYS use world-class HTML generator
|
|
444
|
+
if (reportHtml && typeof reportHtml.generateWorldClassHTML === 'function') {
|
|
445
|
+
try {
|
|
446
|
+
// Ensure reportData has required structure
|
|
447
|
+
if (!reportData.meta) {
|
|
448
|
+
reportData.meta = { projectName: 'Unknown', generatedAt: new Date().toISOString(), version: '2.0.0' };
|
|
449
|
+
}
|
|
450
|
+
if (!reportData.summary) {
|
|
451
|
+
reportData.summary = { score: 0, verdict: 'WARN', totalFindings: 0, severityCounts: {} };
|
|
452
|
+
}
|
|
453
|
+
if (!reportData.findings) {
|
|
454
|
+
reportData.findings = [];
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return reportHtml.generateWorldClassHTML(reportData, opts);
|
|
458
|
+
} catch (err) {
|
|
459
|
+
console.error(`\n ${colors.error}${icons.error}${ansi.reset} Error generating world-class HTML: ${err.message}`);
|
|
460
|
+
if (opts.verbose) {
|
|
461
|
+
console.error(err.stack);
|
|
462
|
+
}
|
|
463
|
+
// Fall through to basic HTML only on error
|
|
464
|
+
}
|
|
465
|
+
} else {
|
|
466
|
+
console.warn(`\n ${colors.warning}${icons.warning}${ansi.reset} report-html module not available, using basic HTML template`);
|
|
423
467
|
}
|
|
468
|
+
break;
|
|
424
469
|
}
|
|
425
470
|
|
|
426
|
-
// Fallback to basic HTML
|
|
471
|
+
// Fallback to basic HTML only if world-class generator failed or not available
|
|
472
|
+
console.warn(` ${ansi.dim}Using basic HTML fallback${ansi.reset}`);
|
|
427
473
|
return generateBasicHTML(reportData, opts);
|
|
428
474
|
}
|
|
429
475
|
|