@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}executive${ansi.reset} One-page overview for stakeholders (default)
132
- ${colors.accent}technical${ansi.reset} Detailed findings for developers/CTOs
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
 
@@ -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
- console.log(` ${ansi.dim}Tip: Run 'vibecheck ship' first for real results.${ansi.reset}\n`);
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?.generateWorldClassHTML) {
422
- return reportHtml.generateWorldClassHTML(reportData, opts);
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibecheckai/cli",
3
- "version": "3.1.4",
3
+ "version": "3.1.5",
4
4
  "description": "Vibecheck CLI - Ship with confidence. One verdict: SHIP | WARN | BLOCK.",
5
5
  "main": "bin/vibecheck.js",
6
6
  "bin": {