@vibecheckai/cli 3.5.5 → 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 +1 -1
package/bin/runners/runFix.js
CHANGED
|
@@ -39,6 +39,9 @@ const { EXIT, verdictToExitCode } = require('./lib/exit-codes');
|
|
|
39
39
|
const entitlements = require('./lib/entitlements-v2');
|
|
40
40
|
const upsell = require('./lib/upsell');
|
|
41
41
|
|
|
42
|
+
// Mission Control output formatter
|
|
43
|
+
const { formatFixOutput } = require('./lib/fix-output');
|
|
44
|
+
|
|
42
45
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
43
46
|
// ADVANCED TERMINAL - ANSI CODES & UTILITIES
|
|
44
47
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
@@ -539,12 +542,19 @@ async function runFix(args) {
|
|
|
539
542
|
stopSpinner('Codebase analyzed', true);
|
|
540
543
|
|
|
541
544
|
if (first.verdict === "SHIP") {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
545
|
+
// Mission Control output
|
|
546
|
+
if (!opts.json && !opts.quiet) {
|
|
547
|
+
console.log(formatFixOutput({
|
|
548
|
+
missions: [],
|
|
549
|
+
verdict: first.verdict,
|
|
550
|
+
beforeVerdict: first.verdict,
|
|
551
|
+
afterVerdict: first.verdict,
|
|
552
|
+
appliedMissions: 0,
|
|
553
|
+
totalMissions: 0,
|
|
554
|
+
duration: 0,
|
|
555
|
+
success: true,
|
|
556
|
+
}, { apply: opts.apply, promptOnly: opts.promptOnly, loop: opts.loop || opts.autopilot }));
|
|
557
|
+
}
|
|
548
558
|
return 0;
|
|
549
559
|
}
|
|
550
560
|
|
|
@@ -610,11 +620,6 @@ async function runFix(args) {
|
|
|
610
620
|
|
|
611
621
|
if (before.verdict === "SHIP") {
|
|
612
622
|
const duration = Date.now() - startTime;
|
|
613
|
-
printSection('MISSION COMPLETE', ICONS.rocket);
|
|
614
|
-
console.log();
|
|
615
|
-
console.log(` ${colors.shipGreen}${ICONS.sparkle}${c.reset} ${c.bold}SHIP achieved in ${step - 1} steps!${c.reset}`);
|
|
616
|
-
console.log(` ${c.dim}Duration: ${formatDuration(duration)}${c.reset}`);
|
|
617
|
-
console.log();
|
|
618
623
|
|
|
619
624
|
// Generate share bundle if requested
|
|
620
625
|
if (opts.share) {
|
|
@@ -622,15 +627,25 @@ async function runFix(args) {
|
|
|
622
627
|
startSpinner('Generating share bundle...', 'dots');
|
|
623
628
|
const shareResult = buildSharePack({ repoRoot: root, missionDirAbs: outDir });
|
|
624
629
|
stopSpinner('Share bundle generated', true);
|
|
625
|
-
console.log(` ${ICONS.package} ${colors.accent}${path.relative(root, shareResult.outputDir)}${c.reset}`);
|
|
626
630
|
} catch (e) {
|
|
627
631
|
stopSpinner('Share bundle failed', false);
|
|
628
|
-
console.log(` ${c.dim}${e.message}${c.reset}`);
|
|
629
632
|
}
|
|
630
633
|
}
|
|
631
634
|
|
|
632
|
-
|
|
633
|
-
|
|
635
|
+
// Mission Control output
|
|
636
|
+
if (!opts.json && !opts.quiet) {
|
|
637
|
+
console.log(formatFixOutput({
|
|
638
|
+
missions,
|
|
639
|
+
verdict: before.verdict,
|
|
640
|
+
beforeVerdict: first.verdict,
|
|
641
|
+
afterVerdict: before.verdict,
|
|
642
|
+
appliedMissions: step - 1,
|
|
643
|
+
totalMissions: missions.length,
|
|
644
|
+
duration,
|
|
645
|
+
success: true,
|
|
646
|
+
}, { apply: opts.apply, promptOnly: opts.promptOnly, loop: opts.loop || opts.autopilot }));
|
|
647
|
+
}
|
|
648
|
+
|
|
634
649
|
return 0;
|
|
635
650
|
}
|
|
636
651
|
|
|
@@ -802,11 +817,7 @@ async function runFix(args) {
|
|
|
802
817
|
|
|
803
818
|
// Max steps reached
|
|
804
819
|
const duration = Date.now() - startTime;
|
|
805
|
-
|
|
806
|
-
console.log();
|
|
807
|
-
console.log(` ${colors.warnAmber}${ICONS.warning}${c.reset} Max steps reached (${maxSteps})`);
|
|
808
|
-
console.log(` ${c.dim}Duration: ${formatDuration(duration)}${c.reset}`);
|
|
809
|
-
console.log();
|
|
820
|
+
const lastShip = await shipCore({ repoRoot: root, fastifyEntry: opts.fastifyEntry, noWrite: false });
|
|
810
821
|
|
|
811
822
|
// Generate share bundle if requested
|
|
812
823
|
if (opts.share) {
|
|
@@ -814,13 +825,25 @@ async function runFix(args) {
|
|
|
814
825
|
startSpinner('Generating share bundle...', 'dots');
|
|
815
826
|
const shareResult = buildSharePack({ repoRoot: root, missionDirAbs: outDir });
|
|
816
827
|
stopSpinner('Share bundle generated', true);
|
|
817
|
-
console.log(` ${ICONS.package} ${colors.accent}${path.relative(root, shareResult.outputDir)}${c.reset}`);
|
|
818
828
|
} catch (e) {
|
|
819
829
|
stopSpinner('Share bundle failed', false);
|
|
820
|
-
console.log(` ${c.dim}${e.message}${c.reset}`);
|
|
821
830
|
}
|
|
822
831
|
}
|
|
823
832
|
|
|
833
|
+
// Mission Control output
|
|
834
|
+
if (!opts.json && !opts.quiet) {
|
|
835
|
+
console.log(formatFixOutput({
|
|
836
|
+
missions,
|
|
837
|
+
verdict: lastShip.verdict,
|
|
838
|
+
beforeVerdict: first.verdict,
|
|
839
|
+
afterVerdict: lastShip.verdict,
|
|
840
|
+
appliedMissions: maxSteps,
|
|
841
|
+
totalMissions: missions.length,
|
|
842
|
+
duration,
|
|
843
|
+
success: false,
|
|
844
|
+
}, { apply: opts.apply, promptOnly: opts.promptOnly, loop: opts.loop || opts.autopilot }));
|
|
845
|
+
}
|
|
846
|
+
|
|
824
847
|
return EXIT.WARNINGS; // Max steps reached, incomplete
|
|
825
848
|
}
|
|
826
849
|
|
package/bin/runners/runProve.js
CHANGED
|
@@ -1355,68 +1355,28 @@ async function runProve(argsOrOpts = {}, context = {}) {
|
|
|
1355
1355
|
|
|
1356
1356
|
// Final verdict display (unless JSON or CI mode)
|
|
1357
1357
|
if (!json && !ci) {
|
|
1358
|
-
|
|
1358
|
+
// Use Mission Control format
|
|
1359
|
+
const { formatProveOutput } = require('./lib/prove-output');
|
|
1360
|
+
const steps = timeline.map(t => ({
|
|
1361
|
+
name: t.step || t.action || 'Step',
|
|
1362
|
+
success: t.status === 'success' || t.status === 'complete',
|
|
1363
|
+
error: t.status === 'error' ? t.error : null,
|
|
1364
|
+
}));
|
|
1359
1365
|
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
+
console.log(formatProveOutput({
|
|
1367
|
+
verdict: finalVerdict,
|
|
1368
|
+
finalVerdict,
|
|
1369
|
+
steps,
|
|
1370
|
+
runtimeTests: report.tests?.length || 0,
|
|
1371
|
+
runtimePassed: report.tests?.filter(t => t.passed).length || 0,
|
|
1372
|
+
duration,
|
|
1373
|
+
success: finalVerdict === 'SHIP',
|
|
1374
|
+
}, { version: 'v3.5.5' }));
|
|
1366
1375
|
|
|
1367
|
-
//
|
|
1376
|
+
// Show artifacts if available
|
|
1368
1377
|
if (htmlReportPath) {
|
|
1369
|
-
console.log(
|
|
1370
|
-
console.log(` ${colors.accent}${path.relative(root, htmlReportPath)}${c.reset}`);
|
|
1371
|
-
console.log(` ${c.dim}↳ Open in browser to see video evidence${c.reset}`);
|
|
1372
|
-
console.log();
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
// Show video/trace artifacts if available
|
|
1376
|
-
if (report.artifacts) {
|
|
1377
|
-
if (report.artifacts.videos?.anon || report.artifacts.videos?.auth) {
|
|
1378
|
-
console.log(` ${c.dim}🎬 Videos:${c.reset} ${report.artifacts.videos?.directory || 'N/A'}`);
|
|
1379
|
-
}
|
|
1380
|
-
if (report.artifacts.traces?.anon || report.artifacts.traces?.auth) {
|
|
1381
|
-
console.log(` ${c.dim}📊 Traces:${c.reset} ${report.artifacts.traces?.directory || 'N/A'}`);
|
|
1382
|
-
console.log(` ${c.dim}↳ Upload to trace.playwright.dev for debugging${c.reset}`);
|
|
1383
|
-
}
|
|
1384
|
-
if (report.artifacts.har?.directory) {
|
|
1385
|
-
console.log(` ${c.dim}📡 HAR:${c.reset} ${report.artifacts.har?.directory || 'N/A'}`);
|
|
1386
|
-
}
|
|
1387
|
-
console.log();
|
|
1378
|
+
console.log(`\n ${colors.shipGreen}${ICONS.sparkle}${c.reset} ${c.bold}HTML Proof Report:${c.reset} ${colors.accent}${path.relative(root, htmlReportPath)}${c.reset}`);
|
|
1388
1379
|
}
|
|
1389
|
-
|
|
1390
|
-
console.log(` ${c.dim}JSON Report:${c.reset} ${path.relative(root, path.join(outDir, 'prove_report.json'))}`);
|
|
1391
|
-
console.log();
|
|
1392
|
-
|
|
1393
|
-
// CI Integration tip
|
|
1394
|
-
printSection('CI INTEGRATION', ICONS.lightning);
|
|
1395
|
-
console.log();
|
|
1396
|
-
console.log(` ${c.dim}Add to your CI pipeline:${c.reset}`);
|
|
1397
|
-
console.log(` ${colors.accent}npx vibecheck prove --url \$APP_URL --ci${c.reset}`);
|
|
1398
|
-
console.log(` ${c.dim}Exit codes: 0=SHIP, 1=WARN, 2=BLOCK${c.reset}`);
|
|
1399
|
-
console.log();
|
|
1400
|
-
|
|
1401
|
-
// Next steps if not proved
|
|
1402
|
-
if (finalVerdict !== 'SHIP') {
|
|
1403
|
-
printSection('NEXT STEPS', ICONS.lightning);
|
|
1404
|
-
console.log();
|
|
1405
|
-
if (skipFix) {
|
|
1406
|
-
console.log(` ${colors.accent}vibecheck prove --url ${url || '<url>'}${c.reset} ${c.dim}Enable auto-fix${c.reset}`);
|
|
1407
|
-
} else if (fixRound >= maxFixRounds) {
|
|
1408
|
-
console.log(` ${colors.accent}vibecheck prove --max-fix-rounds ${maxFixRounds + 2}${c.reset} ${c.dim}Try more fix rounds${c.reset}`);
|
|
1409
|
-
}
|
|
1410
|
-
console.log(` ${colors.accent}vibecheck ship --fix${c.reset} ${c.dim}Manual fix mode${c.reset}`);
|
|
1411
|
-
console.log();
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
// Upsell for upgrade
|
|
1415
|
-
console.log(upsell.formatNextSteps("prove", finalVerdict, "free"));
|
|
1416
|
-
console.log();
|
|
1417
|
-
console.log(` ${c.dim}${upsell.sym.star} Upgrade for unlimited prove runs + video artifacts${c.reset}`);
|
|
1418
|
-
console.log(` ${c.dim}${upsell.sym.arrow} ${upsell.PRICING_URL}${c.reset}`);
|
|
1419
|
-
console.log();
|
|
1420
1380
|
} else if (ci) {
|
|
1421
1381
|
// CI mode - structured output for easy parsing
|
|
1422
1382
|
console.log(`::group::vibecheck prove summary`);
|
|
@@ -2046,48 +2046,34 @@ async function runReality(argsOrOpts = {}) {
|
|
|
2046
2046
|
// OUTPUT
|
|
2047
2047
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
2048
2048
|
|
|
2049
|
-
//
|
|
2050
|
-
|
|
2049
|
+
// Determine verdict
|
|
2050
|
+
const verdict = blocks > 0 ? 'BLOCK' : warns > 0 ? 'WARN' : 'SHIP';
|
|
2051
2051
|
|
|
2052
|
-
//
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
// Report links
|
|
2062
|
-
printSection('REPORTS', ICONS.page);
|
|
2063
|
-
console.log();
|
|
2064
|
-
console.log(` ${colors.accent}${path.relative(root, outBase)}/reality_report.json${c.reset}`);
|
|
2065
|
-
console.log(` ${c.dim}${path.join('.vibecheck', 'reality', 'last_reality.json')}${c.reset}`);
|
|
2066
|
-
if (anonPass.findings.some(f => f.screenshot) || authPass?.findings?.some(f => f.screenshot)) {
|
|
2067
|
-
console.log(` ${colors.accent}${ICONS.screenshot} ${path.relative(root, shotsDir)}/${c.reset} ${c.dim}(screenshots)${c.reset}`);
|
|
2068
|
-
}
|
|
2069
|
-
console.log();
|
|
2070
|
-
|
|
2071
|
-
// Next steps if issues found
|
|
2072
|
-
if (blocks > 0 || warns > 0) {
|
|
2073
|
-
printSection('NEXT STEPS', ICONS.lightning);
|
|
2074
|
-
console.log();
|
|
2075
|
-
console.log(` ${colors.accent}vibecheck fix${c.reset} ${c.dim}Auto-fix dead UI issues${c.reset}`);
|
|
2076
|
-
console.log(` ${colors.accent}vibecheck ship${c.reset} ${c.dim}Re-check ship readiness${c.reset}`);
|
|
2077
|
-
console.log();
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
// Upsell for free tier users running in preview mode
|
|
2081
|
-
const currentTier = entitlements.getCurrentTierSync ? entitlements.getCurrentTierSync() : 'free';
|
|
2082
|
-
if (currentTier === 'free') {
|
|
2083
|
-
console.log(upsell.formatEarnedUpsell({
|
|
2084
|
-
cmd: "reality",
|
|
2085
|
-
why: "cap_hit",
|
|
2086
|
-
topIssues: findings.slice(0, 5),
|
|
2087
|
-
upgradeTier: "starter",
|
|
2052
|
+
// Use Mission Control format
|
|
2053
|
+
if (!opts.json && !opts.quiet) {
|
|
2054
|
+
const { formatRealityOutput } = require('./lib/reality-output');
|
|
2055
|
+
|
|
2056
|
+
// Build test results from findings
|
|
2057
|
+
const tests = findings.map(f => ({
|
|
2058
|
+
name: f.title || f.category || 'Test',
|
|
2059
|
+
route: f.page || f.url || '',
|
|
2060
|
+
passed: f.severity !== 'BLOCK',
|
|
2088
2061
|
}));
|
|
2089
|
-
|
|
2090
|
-
console.log(
|
|
2062
|
+
|
|
2063
|
+
console.log(formatRealityOutput({
|
|
2064
|
+
verdict,
|
|
2065
|
+
tests,
|
|
2066
|
+
passed: tests.filter(t => t.passed).length,
|
|
2067
|
+
failed: tests.filter(t => !t.passed).length,
|
|
2068
|
+
warnings: warns,
|
|
2069
|
+
coverage: coverage.percent || 0,
|
|
2070
|
+
duration,
|
|
2071
|
+
url: baseUrl,
|
|
2072
|
+
success: verdict === 'SHIP',
|
|
2073
|
+
}, { projectPath: root, version: 'v3.5.5' }));
|
|
2074
|
+
|
|
2075
|
+
// Show report path
|
|
2076
|
+
console.log(`\n ${colors.accent}Report:${c.reset} ${path.relative(root, outBase)}/reality_report.json`);
|
|
2091
2077
|
}
|
|
2092
2078
|
|
|
2093
2079
|
process.exitCode = blocks ? 2 : warns ? 1 : 0;
|