@vibecheckai/cli 3.4.0 → 3.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/bin/registry.js +154 -338
- package/bin/runners/context/generators/mcp.js +13 -15
- package/bin/runners/context/proof-context.js +1 -248
- package/bin/runners/lib/analysis-core.js +180 -198
- package/bin/runners/lib/analyzers.js +223 -1669
- package/bin/runners/lib/cli-output.js +210 -242
- package/bin/runners/lib/detectors-v2.js +785 -547
- package/bin/runners/lib/entitlements-v2.js +458 -96
- package/bin/runners/lib/error-handler.js +9 -16
- package/bin/runners/lib/global-flags.js +0 -37
- package/bin/runners/lib/route-truth.js +322 -1167
- package/bin/runners/lib/scan-output.js +469 -448
- package/bin/runners/lib/ship-output.js +27 -280
- package/bin/runners/lib/terminal-ui.js +733 -231
- package/bin/runners/lib/truth.js +321 -1004
- package/bin/runners/lib/unified-output.js +158 -162
- package/bin/runners/lib/upsell.js +204 -104
- package/bin/runners/runAllowlist.js +324 -0
- package/bin/runners/runAuth.js +95 -324
- package/bin/runners/runCheckpoint.js +21 -39
- package/bin/runners/runContext.js +24 -136
- package/bin/runners/runDoctor.js +67 -115
- package/bin/runners/runEvidencePack.js +219 -0
- package/bin/runners/runFix.js +5 -6
- package/bin/runners/runGuard.js +118 -212
- package/bin/runners/runInit.js +2 -14
- package/bin/runners/runInstall.js +281 -0
- package/bin/runners/runLabs.js +341 -0
- package/bin/runners/runMcp.js +52 -130
- package/bin/runners/runPolish.js +20 -43
- package/bin/runners/runProve.js +3 -13
- package/bin/runners/runReality.js +0 -14
- package/bin/runners/runReport.js +2 -3
- package/bin/runners/runScan.js +44 -511
- package/bin/runners/runShip.js +14 -28
- package/bin/runners/runValidate.js +2 -19
- package/bin/runners/runWatch.js +54 -118
- package/bin/vibecheck.js +41 -148
- package/mcp-server/ARCHITECTURE.md +339 -0
- package/mcp-server/__tests__/cache.test.ts +313 -0
- package/mcp-server/__tests__/executor.test.ts +239 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/.cache/webpack/cache.pack +1 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/.next/server/chunk.js +3 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/.turbo/cache.json +3 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/.venv/lib/env.py +3 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/dist/bundle.js +3 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/package.json +5 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/src/app.ts +5 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/venv/lib/config.py +4 -0
- package/mcp-server/__tests__/ids.test.ts +345 -0
- package/mcp-server/__tests__/integration/tools.test.ts +410 -0
- package/mcp-server/__tests__/registry.test.ts +365 -0
- package/mcp-server/__tests__/sandbox.test.ts +323 -0
- package/mcp-server/__tests__/schemas.test.ts +372 -0
- package/mcp-server/benchmarks/run-benchmarks.ts +304 -0
- package/mcp-server/examples/doctor.request.json +14 -0
- package/mcp-server/examples/doctor.response.json +53 -0
- package/mcp-server/examples/error.response.json +15 -0
- package/mcp-server/examples/scan.request.json +14 -0
- package/mcp-server/examples/scan.response.json +108 -0
- package/mcp-server/handlers/tool-handler.ts +671 -0
- package/mcp-server/index-v3.ts +293 -0
- package/mcp-server/index.js +1072 -1573
- package/mcp-server/index.old.js +4137 -0
- package/mcp-server/lib/cache.ts +341 -0
- package/mcp-server/lib/errors.ts +346 -0
- package/mcp-server/lib/executor.ts +792 -0
- package/mcp-server/lib/ids.ts +238 -0
- package/mcp-server/lib/logger.ts +368 -0
- package/mcp-server/lib/metrics.ts +365 -0
- package/mcp-server/lib/sandbox.ts +337 -0
- package/mcp-server/lib/validator.ts +229 -0
- package/mcp-server/package-lock.json +165 -0
- package/mcp-server/package.json +32 -7
- package/mcp-server/premium-tools.js +2 -2
- package/mcp-server/registry/tools.json +476 -0
- package/mcp-server/schemas/error-envelope.schema.json +125 -0
- package/mcp-server/schemas/finding.schema.json +167 -0
- package/mcp-server/schemas/report-artifact.schema.json +88 -0
- package/mcp-server/schemas/run-request.schema.json +75 -0
- package/mcp-server/schemas/verdict.schema.json +168 -0
- package/mcp-server/tier-auth.d.ts +71 -0
- package/mcp-server/tier-auth.js +371 -183
- package/mcp-server/truth-context.js +90 -131
- package/mcp-server/truth-firewall-tools.js +1000 -1611
- package/mcp-server/tsconfig.json +34 -0
- package/mcp-server/vibecheck-tools.js +2 -2
- package/mcp-server/vitest.config.ts +16 -0
- package/package.json +3 -4
- package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +0 -474
- package/bin/runners/lib/agent-firewall/change-packet/builder.js +0 -488
- package/bin/runners/lib/agent-firewall/change-packet/schema.json +0 -228
- package/bin/runners/lib/agent-firewall/change-packet/store.js +0 -200
- package/bin/runners/lib/agent-firewall/claims/claim-types.js +0 -21
- package/bin/runners/lib/agent-firewall/claims/extractor.js +0 -303
- package/bin/runners/lib/agent-firewall/claims/patterns.js +0 -24
- package/bin/runners/lib/agent-firewall/critic/index.js +0 -151
- package/bin/runners/lib/agent-firewall/critic/judge.js +0 -432
- package/bin/runners/lib/agent-firewall/critic/prompts.js +0 -305
- package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +0 -88
- package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +0 -75
- package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +0 -127
- package/bin/runners/lib/agent-firewall/evidence/resolver.js +0 -102
- package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +0 -213
- package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +0 -145
- package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +0 -19
- package/bin/runners/lib/agent-firewall/fs-hook/installer.js +0 -87
- package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +0 -184
- package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +0 -163
- package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +0 -107
- package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +0 -68
- package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +0 -66
- package/bin/runners/lib/agent-firewall/interceptor/base.js +0 -304
- package/bin/runners/lib/agent-firewall/interceptor/cursor.js +0 -35
- package/bin/runners/lib/agent-firewall/interceptor/vscode.js +0 -35
- package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +0 -34
- package/bin/runners/lib/agent-firewall/lawbook/distributor.js +0 -465
- package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +0 -604
- package/bin/runners/lib/agent-firewall/lawbook/index.js +0 -304
- package/bin/runners/lib/agent-firewall/lawbook/registry.js +0 -514
- package/bin/runners/lib/agent-firewall/lawbook/schema.js +0 -420
- package/bin/runners/lib/agent-firewall/logger.js +0 -141
- package/bin/runners/lib/agent-firewall/policy/default-policy.json +0 -90
- package/bin/runners/lib/agent-firewall/policy/engine.js +0 -103
- package/bin/runners/lib/agent-firewall/policy/loader.js +0 -451
- package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +0 -50
- package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +0 -50
- package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +0 -86
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +0 -162
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +0 -189
- package/bin/runners/lib/agent-firewall/policy/rules/scope.js +0 -93
- package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +0 -57
- package/bin/runners/lib/agent-firewall/policy/schema.json +0 -183
- package/bin/runners/lib/agent-firewall/policy/verdict.js +0 -54
- package/bin/runners/lib/agent-firewall/proposal/extractor.js +0 -394
- package/bin/runners/lib/agent-firewall/proposal/index.js +0 -212
- package/bin/runners/lib/agent-firewall/proposal/schema.js +0 -251
- package/bin/runners/lib/agent-firewall/proposal/validator.js +0 -386
- package/bin/runners/lib/agent-firewall/reality/index.js +0 -332
- package/bin/runners/lib/agent-firewall/reality/state.js +0 -625
- package/bin/runners/lib/agent-firewall/reality/watcher.js +0 -322
- package/bin/runners/lib/agent-firewall/risk/index.js +0 -173
- package/bin/runners/lib/agent-firewall/risk/scorer.js +0 -328
- package/bin/runners/lib/agent-firewall/risk/thresholds.js +0 -321
- package/bin/runners/lib/agent-firewall/risk/vectors.js +0 -421
- package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +0 -472
- package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +0 -346
- package/bin/runners/lib/agent-firewall/simulator/index.js +0 -181
- package/bin/runners/lib/agent-firewall/simulator/route-validator.js +0 -380
- package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +0 -661
- package/bin/runners/lib/agent-firewall/time-machine/index.js +0 -267
- package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +0 -436
- package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +0 -490
- package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +0 -530
- package/bin/runners/lib/agent-firewall/truthpack/index.js +0 -67
- package/bin/runners/lib/agent-firewall/truthpack/loader.js +0 -137
- package/bin/runners/lib/agent-firewall/unblock/planner.js +0 -337
- package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +0 -118
- package/bin/runners/lib/api-client.js +0 -269
- package/bin/runners/lib/authority-badge.js +0 -425
- package/bin/runners/lib/engines/accessibility-engine.js +0 -190
- package/bin/runners/lib/engines/api-consistency-engine.js +0 -162
- package/bin/runners/lib/engines/ast-cache.js +0 -99
- package/bin/runners/lib/engines/code-quality-engine.js +0 -255
- package/bin/runners/lib/engines/console-logs-engine.js +0 -115
- package/bin/runners/lib/engines/cross-file-analysis-engine.js +0 -268
- package/bin/runners/lib/engines/dead-code-engine.js +0 -198
- package/bin/runners/lib/engines/deprecated-api-engine.js +0 -226
- package/bin/runners/lib/engines/empty-catch-engine.js +0 -150
- package/bin/runners/lib/engines/file-filter.js +0 -131
- package/bin/runners/lib/engines/hardcoded-secrets-engine.js +0 -251
- package/bin/runners/lib/engines/mock-data-engine.js +0 -272
- package/bin/runners/lib/engines/parallel-processor.js +0 -71
- package/bin/runners/lib/engines/performance-issues-engine.js +0 -265
- package/bin/runners/lib/engines/security-vulnerabilities-engine.js +0 -243
- package/bin/runners/lib/engines/todo-fixme-engine.js +0 -115
- package/bin/runners/lib/engines/type-aware-engine.js +0 -152
- package/bin/runners/lib/engines/unsafe-regex-engine.js +0 -225
- package/bin/runners/lib/engines/vibecheck-engines/README.md +0 -53
- package/bin/runners/lib/engines/vibecheck-engines/index.js +0 -15
- package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +0 -164
- package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +0 -291
- package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +0 -83
- package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +0 -198
- package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +0 -275
- package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +0 -167
- package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +0 -217
- package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +0 -139
- package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +0 -140
- package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +0 -164
- package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +0 -234
- package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +0 -217
- package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +0 -78
- package/bin/runners/lib/engines/vibecheck-engines/package.json +0 -13
- package/bin/runners/lib/exit-codes.js +0 -275
- package/bin/runners/lib/fingerprint.js +0 -377
- package/bin/runners/lib/help-formatter.js +0 -413
- package/bin/runners/lib/logger.js +0 -38
- package/bin/runners/lib/ship-output-enterprise.js +0 -239
- package/bin/runners/lib/unified-cli-output.js +0 -604
- package/bin/runners/runAgent.d.ts +0 -5
- package/bin/runners/runAgent.js +0 -161
- package/bin/runners/runApprove.js +0 -1200
- package/bin/runners/runClassify.js +0 -859
- package/bin/runners/runContext.d.ts +0 -4
- package/bin/runners/runFirewall.d.ts +0 -5
- package/bin/runners/runFirewall.js +0 -134
- package/bin/runners/runFirewallHook.d.ts +0 -5
- package/bin/runners/runFirewallHook.js +0 -56
- package/bin/runners/runPolish.d.ts +0 -4
- package/bin/runners/runProof.zip +0 -0
- package/bin/runners/runTruth.d.ts +0 -5
- package/bin/runners/runTruth.js +0 -101
- package/mcp-server/HARDENING_SUMMARY.md +0 -299
- package/mcp-server/agent-firewall-interceptor.js +0 -500
- package/mcp-server/authority-tools.js +0 -569
- package/mcp-server/conductor/conflict-resolver.js +0 -588
- package/mcp-server/conductor/execution-planner.js +0 -544
- package/mcp-server/conductor/index.js +0 -377
- package/mcp-server/conductor/lock-manager.js +0 -615
- package/mcp-server/conductor/request-queue.js +0 -550
- package/mcp-server/conductor/session-manager.js +0 -500
- package/mcp-server/conductor/tools.js +0 -510
- package/mcp-server/lib/api-client.cjs +0 -13
- package/mcp-server/lib/logger.cjs +0 -30
- package/mcp-server/logger.js +0 -173
- package/mcp-server/tools-v3.js +0 -706
- package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
|
@@ -316,15 +316,11 @@ function renderFindingsBreakdown(findings) {
|
|
|
316
316
|
// BLOCKER DETAILS
|
|
317
317
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
318
318
|
|
|
319
|
-
function renderBlockerDetails(findings, maxShow = 8
|
|
320
|
-
const { tier = 'free' } = options;
|
|
319
|
+
function renderBlockerDetails(findings, maxShow = 8) {
|
|
321
320
|
const blockers = findings.filter(f => f.severity === 'BLOCK' || f.severity === 'critical');
|
|
322
321
|
|
|
323
322
|
if (blockers.length === 0) return '';
|
|
324
323
|
|
|
325
|
-
// Fix hints are PRO only (2-tier model)
|
|
326
|
-
const canShowFixHints = tier === 'pro' || tier === 'compliance' || tier === 'starter'; // starter=legacy compatibility
|
|
327
|
-
|
|
328
324
|
const lines = [];
|
|
329
325
|
lines.push(renderSection(`BLOCKERS (${blockers.length})`, '🚨'));
|
|
330
326
|
lines.push('');
|
|
@@ -333,22 +329,12 @@ function renderBlockerDetails(findings, maxShow = 8, options = {}) {
|
|
|
333
329
|
const icon = getCategoryIcon(blocker.category);
|
|
334
330
|
const severityBg = ansi.bgRgb(80, 20, 20);
|
|
335
331
|
|
|
336
|
-
//
|
|
337
|
-
|
|
338
|
-
const aiTag = isAIPattern ? `${ansi.bgRgb(60, 40, 80)}${ansi.bold} 🤖 AI ${ansi.reset} ` : '';
|
|
339
|
-
|
|
340
|
-
// Severity badge + AI tag + title
|
|
341
|
-
lines.push(` ${severityBg}${ansi.bold} BLOCKER ${ansi.reset} ${aiTag}${icon} ${ansi.bold}${truncate(blocker.title || blocker.message, 45)}${ansi.reset}`);
|
|
332
|
+
// Severity badge + title
|
|
333
|
+
lines.push(` ${severityBg}${ansi.bold} BLOCKER ${ansi.reset} ${icon} ${ansi.bold}${truncate(blocker.title || blocker.message, 50)}${ansi.reset}`);
|
|
342
334
|
|
|
343
|
-
// Why/description
|
|
335
|
+
// Why/description
|
|
344
336
|
if (blocker.why || blocker.description) {
|
|
345
|
-
|
|
346
|
-
lines.push(` ${ansi.dim}${truncate(desc, 55)}${ansi.reset}`);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// AI-specific warning for known patterns
|
|
350
|
-
if (isAIPattern) {
|
|
351
|
-
lines.push(` ${colors.warning}⚠ ${isAIPattern.desc}${ansi.reset}`);
|
|
337
|
+
lines.push(` ${ansi.dim}${truncate(blocker.why || blocker.description, 55)}${ansi.reset}`);
|
|
352
338
|
}
|
|
353
339
|
|
|
354
340
|
// File location
|
|
@@ -364,16 +350,11 @@ function renderBlockerDetails(findings, maxShow = 8, options = {}) {
|
|
|
364
350
|
lines.push(` ${colors.accent}${shipIcons.doc} ${fileDisplay}${ansi.reset}`);
|
|
365
351
|
}
|
|
366
352
|
|
|
367
|
-
// Fix hint
|
|
368
|
-
if (
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
lines.push(` ${colors.success}→ ${truncate(blocker.fix, 50)}${ansi.reset}`);
|
|
373
|
-
}
|
|
374
|
-
} else {
|
|
375
|
-
// Show locked fix hint for FREE tier
|
|
376
|
-
lines.push(` ${ansi.dim}🔒 Fix hints available with PRO ($69/mo)${ansi.reset}`);
|
|
353
|
+
// Fix hint
|
|
354
|
+
if (blocker.fixHints && blocker.fixHints.length > 0) {
|
|
355
|
+
lines.push(` ${colors.success}→ ${truncate(blocker.fixHints[0], 50)}${ansi.reset}`);
|
|
356
|
+
} else if (blocker.fix) {
|
|
357
|
+
lines.push(` ${colors.success}→ ${truncate(blocker.fix, 50)}${ansi.reset}`);
|
|
377
358
|
}
|
|
378
359
|
|
|
379
360
|
lines.push('');
|
|
@@ -384,16 +365,6 @@ function renderBlockerDetails(findings, maxShow = 8, options = {}) {
|
|
|
384
365
|
lines.push('');
|
|
385
366
|
}
|
|
386
367
|
|
|
387
|
-
// Show upsell for fix hints if FREE tier
|
|
388
|
-
if (!canShowFixHints && blockers.length > 0) {
|
|
389
|
-
lines.push(` ${ansi.dim}─────────────────────────────────────────${ansi.reset}`);
|
|
390
|
-
lines.push(` ${colors.accent}💡${ansi.reset} ${ansi.bold}Unlock AI fix suggestions${ansi.reset}`);
|
|
391
|
-
lines.push(` ${ansi.dim}PRO users get specific fix hints and${ansi.reset}`);
|
|
392
|
-
lines.push(` ${ansi.dim}AI mission prompts for every issue.${ansi.reset}`);
|
|
393
|
-
lines.push(` ${colors.accent}Upgrade to PRO ($69/mo)${ansi.reset} ${ansi.dim}→ vibecheckai.dev/pricing${ansi.reset}`);
|
|
394
|
-
lines.push('');
|
|
395
|
-
}
|
|
396
|
-
|
|
397
368
|
return lines.join('\n');
|
|
398
369
|
}
|
|
399
370
|
|
|
@@ -453,37 +424,22 @@ function renderFixResults(fixResults) {
|
|
|
453
424
|
// BADGE OUTPUT
|
|
454
425
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
455
426
|
|
|
456
|
-
function renderBadgeOutput(projectPath, verdict, score
|
|
457
|
-
const { tier = 'free', isVerified = false } = options;
|
|
427
|
+
function renderBadgeOutput(projectPath, verdict, score) {
|
|
458
428
|
const projectName = path.basename(projectPath);
|
|
459
429
|
const projectId = projectName.toLowerCase().replace(/[^a-z0-9]/g, '-');
|
|
460
430
|
|
|
461
431
|
const config = getVerdictConfig(verdict, score);
|
|
462
|
-
const isPro = tier === 'pro' || tier === 'compliance';
|
|
463
432
|
|
|
464
433
|
const lines = [];
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
if (isPro && isVerified) {
|
|
468
|
-
lines.push(renderSection('VERIFIED BADGE', '✅'));
|
|
469
|
-
lines.push('');
|
|
470
|
-
lines.push(` ${ansi.bgRgb(40, 100, 60)}${ansi.bold} ✅ VERIFIED ${ansi.reset} ${ansi.dim}Reality-tested by AI${ansi.reset}`);
|
|
471
|
-
lines.push('');
|
|
472
|
-
} else {
|
|
473
|
-
lines.push(renderSection('SHIP BADGE', '📛'));
|
|
474
|
-
lines.push('');
|
|
475
|
-
}
|
|
434
|
+
lines.push(renderSection('SHIP BADGE', '📛'));
|
|
435
|
+
lines.push('');
|
|
476
436
|
|
|
477
437
|
// Badge preview
|
|
478
|
-
const badgeText =
|
|
479
|
-
? `vibecheck | ✅ VERIFIED | ${score}`
|
|
480
|
-
: `vibecheck | ${verdict} | ${score}`;
|
|
438
|
+
const badgeText = `vibecheck | ${verdict} | ${score}`;
|
|
481
439
|
lines.push(` ${config.bgColor}${ansi.bold} ${badgeText} ${ansi.reset}`);
|
|
482
440
|
lines.push('');
|
|
483
441
|
|
|
484
|
-
|
|
485
|
-
const badgeSuffix = (isPro && isVerified) ? '-verified' : '';
|
|
486
|
-
const badgeUrl = `https://vibecheck.dev/badge/${projectId}${badgeSuffix}.svg`;
|
|
442
|
+
const badgeUrl = `https://vibecheck.dev/badge/${projectId}.svg`;
|
|
487
443
|
const reportUrl = `https://vibecheck.dev/report/${projectId}`;
|
|
488
444
|
const markdown = `[](${reportUrl})`;
|
|
489
445
|
|
|
@@ -496,19 +452,9 @@ function renderBadgeOutput(projectPath, verdict, score, options = {}) {
|
|
|
496
452
|
lines.push(` ${ansi.dim}Add to README.md:${ansi.reset}`);
|
|
497
453
|
lines.push(` ${colors.success}${markdown}${ansi.reset}`);
|
|
498
454
|
|
|
499
|
-
// Show verified badge upsell if not PRO
|
|
500
|
-
if (!isPro) {
|
|
501
|
-
lines.push('');
|
|
502
|
-
lines.push(` ${ansi.dim}─────────────────────────────────────────${ansi.reset}`);
|
|
503
|
-
lines.push(` ${colors.accent}✨${ansi.reset} ${ansi.bold}Want a verified badge?${ansi.reset}`);
|
|
504
|
-
lines.push(` ${ansi.dim}PRO users get a${ansi.reset} ${ansi.bgRgb(40, 100, 60)}${ansi.bold} ✅ VERIFIED ${ansi.reset} ${ansi.dim}badge${ansi.reset}`);
|
|
505
|
-
lines.push(` ${ansi.dim}proving your app was reality-tested by AI.${ansi.reset}`);
|
|
506
|
-
lines.push(` ${colors.accent}vibecheck login${ansi.reset} ${ansi.dim}to upgrade${ansi.reset}`);
|
|
507
|
-
}
|
|
508
|
-
|
|
509
455
|
return {
|
|
510
456
|
output: lines.join('\n'),
|
|
511
|
-
data: { projectId, badgeUrl, reportUrl, markdown
|
|
457
|
+
data: { projectId, badgeUrl, reportUrl, markdown },
|
|
512
458
|
};
|
|
513
459
|
}
|
|
514
460
|
|
|
@@ -516,45 +462,10 @@ function renderBadgeOutput(projectPath, verdict, score, options = {}) {
|
|
|
516
462
|
// NEXT STEPS
|
|
517
463
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
518
464
|
|
|
519
|
-
function renderNextSteps(canShip, hasFix = false
|
|
520
|
-
|
|
521
|
-
const isPro = tier === 'pro' || tier === 'compliance';
|
|
465
|
+
function renderNextSteps(canShip, hasFix = false) {
|
|
466
|
+
if (canShip) return '';
|
|
522
467
|
|
|
523
468
|
const lines = [];
|
|
524
|
-
|
|
525
|
-
// If codebase PASSED - show celebration and PRO upsell for verified badge
|
|
526
|
-
if (canShip) {
|
|
527
|
-
lines.push('');
|
|
528
|
-
lines.push(renderSection('WHAT\'S NEXT?', shipIcons.sparkle));
|
|
529
|
-
lines.push('');
|
|
530
|
-
lines.push(` ${colors.success}${icons.success}${ansi.reset} ${ansi.bold}Congratulations! Your code is ship-ready.${ansi.reset}`);
|
|
531
|
-
lines.push('');
|
|
532
|
-
|
|
533
|
-
if (!isPro) {
|
|
534
|
-
// Upsell PRO for verified badge
|
|
535
|
-
lines.push(` ${ansi.dim}─────────────────────────────────────────${ansi.reset}`);
|
|
536
|
-
lines.push(` ${colors.accent}🏆${ansi.reset} ${ansi.bold}Prove it to the world!${ansi.reset}`);
|
|
537
|
-
lines.push('');
|
|
538
|
-
lines.push(` ${ansi.dim}Upgrade to${ansi.reset} ${colors.accent}PRO${ansi.reset} ${ansi.dim}for a${ansi.reset} ${ansi.bgRgb(40, 100, 60)}${ansi.bold} ✅ VERIFIED ${ansi.reset} ${ansi.dim}badge${ansi.reset}`);
|
|
539
|
-
lines.push('');
|
|
540
|
-
lines.push(` ${ansi.dim}The verified badge proves:${ansi.reset}`);
|
|
541
|
-
lines.push(` ${colors.success}→${ansi.reset} AI reality-tested your app's actual behavior`);
|
|
542
|
-
lines.push(` ${colors.success}→${ansi.reset} Video proof of working features`);
|
|
543
|
-
lines.push(` ${colors.success}→${ansi.reset} Automated auth boundary verification`);
|
|
544
|
-
lines.push('');
|
|
545
|
-
lines.push(` ${colors.accent}vibecheck login${ansi.reset} ${ansi.dim}to start your PRO trial${ansi.reset}`);
|
|
546
|
-
lines.push('');
|
|
547
|
-
} else if (!showBadge) {
|
|
548
|
-
// PRO user who passed - prompt them to generate badge
|
|
549
|
-
lines.push(` ${colors.accent}vibecheck ship --badge${ansi.reset} ${ansi.dim}Generate your verified badge${ansi.reset}`);
|
|
550
|
-
lines.push(` ${colors.accent}vibecheck prove${ansi.reset} ${ansi.dim}Create video proof of working features${ansi.reset}`);
|
|
551
|
-
lines.push('');
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
return lines.join('\n');
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
// If codebase FAILED - show next steps to fix
|
|
558
469
|
lines.push(renderSection('NEXT STEPS', shipIcons.lightning));
|
|
559
470
|
lines.push('');
|
|
560
471
|
|
|
@@ -585,151 +496,12 @@ function renderReportLinks(outputDir, hasFix = false) {
|
|
|
585
496
|
return lines.join('\n');
|
|
586
497
|
}
|
|
587
498
|
|
|
588
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
589
|
-
// AI HALLUCINATION SCORE - Key metric for detecting AI-generated issues
|
|
590
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
591
|
-
|
|
592
|
-
// Categories that indicate common AI hallucination patterns
|
|
593
|
-
const AI_HALLUCINATION_CATEGORIES = {
|
|
594
|
-
'MissingRoute': { weight: 25, label: 'Invented endpoints', desc: 'AI created API routes that don\'t exist' },
|
|
595
|
-
'FakeSuccess': { weight: 20, label: 'Fake success UI', desc: 'Shows success without verifying the operation' },
|
|
596
|
-
'GhostAuth': { weight: 15, label: 'Missing auth', desc: 'Sensitive endpoints without protection' },
|
|
597
|
-
'EnvGap': { weight: 10, label: 'Undefined env vars', desc: 'Uses environment variables that don\'t exist' },
|
|
598
|
-
'DeadUI': { weight: 10, label: 'Dead UI elements', desc: 'Buttons/forms that do nothing' },
|
|
599
|
-
'OwnerModeBypass': { weight: 15, label: 'Backdoor access', desc: 'Production security bypasses' },
|
|
600
|
-
'PaidSurface': { weight: 5, label: 'Billing bypass', desc: 'Paid features without enforcement' },
|
|
601
|
-
};
|
|
602
|
-
|
|
603
|
-
function calculateAIHallucinationScore(findings) {
|
|
604
|
-
if (!findings || findings.length === 0) return { score: 100, breakdown: [], totalIssues: 0 };
|
|
605
|
-
|
|
606
|
-
const breakdown = [];
|
|
607
|
-
let deductions = 0;
|
|
608
|
-
|
|
609
|
-
for (const [category, config] of Object.entries(AI_HALLUCINATION_CATEGORIES)) {
|
|
610
|
-
const categoryFindings = findings.filter(f => f.category === category);
|
|
611
|
-
const blockers = categoryFindings.filter(f => f.severity === 'BLOCK' || f.severity === 'critical');
|
|
612
|
-
const warnings = categoryFindings.filter(f => f.severity === 'WARN' || f.severity === 'warning');
|
|
613
|
-
|
|
614
|
-
if (categoryFindings.length > 0) {
|
|
615
|
-
// Blockers count more than warnings
|
|
616
|
-
const blockerDeduction = blockers.length * config.weight;
|
|
617
|
-
const warningDeduction = warnings.length * Math.floor(config.weight / 2);
|
|
618
|
-
const totalDeduction = blockerDeduction + warningDeduction;
|
|
619
|
-
|
|
620
|
-
deductions += totalDeduction;
|
|
621
|
-
breakdown.push({
|
|
622
|
-
category,
|
|
623
|
-
label: config.label,
|
|
624
|
-
desc: config.desc,
|
|
625
|
-
count: categoryFindings.length,
|
|
626
|
-
blockers: blockers.length,
|
|
627
|
-
warnings: warnings.length,
|
|
628
|
-
deduction: totalDeduction,
|
|
629
|
-
});
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
// Cap at 0
|
|
634
|
-
const score = Math.max(0, 100 - deductions);
|
|
635
|
-
|
|
636
|
-
return {
|
|
637
|
-
score,
|
|
638
|
-
breakdown: breakdown.sort((a, b) => b.deduction - a.deduction),
|
|
639
|
-
totalIssues: findings.length,
|
|
640
|
-
};
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
function renderAIHallucinationScore(findings) {
|
|
644
|
-
const { score, breakdown, totalIssues } = calculateAIHallucinationScore(findings);
|
|
645
|
-
|
|
646
|
-
const lines = [];
|
|
647
|
-
lines.push('');
|
|
648
|
-
lines.push(renderSection('AI REALITY CHECK', '🤖'));
|
|
649
|
-
lines.push('');
|
|
650
|
-
|
|
651
|
-
// Score display with color coding
|
|
652
|
-
const scoreColor = score >= 80 ? colors.success : score >= 50 ? colors.warning : colors.error;
|
|
653
|
-
const scoreLabel = score >= 80 ? 'Low Risk' : score >= 50 ? 'Medium Risk' : 'High Risk';
|
|
654
|
-
|
|
655
|
-
// Visual score bar
|
|
656
|
-
lines.push(` ${ansi.bold}AI Hallucination Risk${ansi.reset}`);
|
|
657
|
-
lines.push(` ${renderProgressBar(100 - score, 40, scoreColor)} ${scoreColor}${ansi.bold}${100 - score}%${ansi.reset} risk`);
|
|
658
|
-
lines.push('');
|
|
659
|
-
|
|
660
|
-
if (breakdown.length === 0) {
|
|
661
|
-
lines.push(` ${colors.success}${icons.success}${ansi.reset} ${ansi.bold}No AI hallucination patterns detected!${ansi.reset}`);
|
|
662
|
-
lines.push(` ${ansi.dim}Your code appears to be grounded in reality.${ansi.reset}`);
|
|
663
|
-
} else {
|
|
664
|
-
lines.push(` ${ansi.dim}Common AI mistakes found:${ansi.reset}`);
|
|
665
|
-
lines.push('');
|
|
666
|
-
|
|
667
|
-
for (const item of breakdown.slice(0, 5)) {
|
|
668
|
-
const itemColor = item.blockers > 0 ? colors.error : colors.warning;
|
|
669
|
-
const severityBadge = item.blockers > 0
|
|
670
|
-
? `${colors.error}${ansi.bold}${item.blockers} BLOCK${ansi.reset}`
|
|
671
|
-
: `${colors.warning}${item.warnings} warn${ansi.reset}`;
|
|
672
|
-
|
|
673
|
-
lines.push(` ${itemColor}•${ansi.reset} ${ansi.bold}${item.label}${ansi.reset} ${ansi.dim}(${item.count})${ansi.reset} ${severityBadge}`);
|
|
674
|
-
lines.push(` ${ansi.dim}${item.desc}${ansi.reset}`);
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
if (breakdown.length > 5) {
|
|
678
|
-
lines.push(` ${ansi.dim}... and ${breakdown.length - 5} more categories${ansi.reset}`);
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
lines.push('');
|
|
683
|
-
return lines.join('\n');
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
687
|
-
// UPGRADE PROMPTS - Show FREE users what they're missing
|
|
688
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
689
|
-
|
|
690
|
-
function renderUpgradePrompts(findings, verdict) {
|
|
691
|
-
const lines = [];
|
|
692
|
-
|
|
693
|
-
// Only show if there are issues to fix
|
|
694
|
-
if (!findings || findings.length === 0) return '';
|
|
695
|
-
|
|
696
|
-
const blockers = findings.filter(f => f.severity === 'BLOCK' || f.severity === 'critical');
|
|
697
|
-
const fixableCount = findings.length;
|
|
698
|
-
|
|
699
|
-
lines.push('');
|
|
700
|
-
lines.push(` ${ansi.dim}${'─'.repeat(60)}${ansi.reset}`);
|
|
701
|
-
lines.push('');
|
|
702
|
-
lines.push(` ${colors.accent}⚡${ansi.reset} ${ansi.bold}Want to fix these automatically?${ansi.reset}`);
|
|
703
|
-
lines.push('');
|
|
704
|
-
|
|
705
|
-
// PRO tier benefits (2-tier: FREE / PRO)
|
|
706
|
-
lines.push(` ${colors.accent}PRO${ansi.reset} ${ansi.dim}($69/mo)${ansi.reset}`);
|
|
707
|
-
lines.push(` ${colors.success}→${ansi.reset} ${ansi.bold}vibecheck fix${ansi.reset} - AI auto-fix for ${fixableCount} issues`);
|
|
708
|
-
lines.push(` ${colors.success}→${ansi.reset} ${ansi.bold}vibecheck ship${ansi.reset} - GO/NO-GO verdicts with proof`);
|
|
709
|
-
lines.push(` ${colors.success}→${ansi.reset} ${ansi.bold}vibecheck prove${ansi.reset} - Video proof your app actually works`);
|
|
710
|
-
lines.push(` ${colors.success}→${ansi.reset} ${ansi.bold}vibecheck reality --agent${ansi.reset} - AI tests your app autonomously`);
|
|
711
|
-
lines.push('');
|
|
712
|
-
|
|
713
|
-
lines.push(` ${ansi.dim}Upgrade: ${colors.accent}vibecheckai.dev/pricing${ansi.reset}`);
|
|
714
|
-
lines.push('');
|
|
715
|
-
|
|
716
|
-
return lines.join('\n');
|
|
717
|
-
}
|
|
718
|
-
|
|
719
499
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
720
500
|
// FULL SHIP OUTPUT
|
|
721
501
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
722
502
|
|
|
723
503
|
function formatShipOutput(result, options = {}) {
|
|
724
|
-
const {
|
|
725
|
-
verbose = false,
|
|
726
|
-
showFix = false,
|
|
727
|
-
showBadge = false,
|
|
728
|
-
outputDir = '.vibecheck',
|
|
729
|
-
projectPath = '.',
|
|
730
|
-
tier = 'free', // User's current tier
|
|
731
|
-
isVerified = false, // Whether reality testing was done (for verified badge)
|
|
732
|
-
} = options;
|
|
504
|
+
const { verbose = false, showFix = false, showBadge = false, outputDir = '.vibecheck', projectPath = '.' } = options;
|
|
733
505
|
|
|
734
506
|
const {
|
|
735
507
|
verdict,
|
|
@@ -744,10 +516,6 @@ function formatShipOutput(result, options = {}) {
|
|
|
744
516
|
cached = false,
|
|
745
517
|
} = result;
|
|
746
518
|
|
|
747
|
-
const isPro = tier === 'pro' || tier === 'compliance' || tier === 'starter'; // starter=legacy compat
|
|
748
|
-
const isProTier = isPro; // 2-tier model: isPro covers all paid tiers
|
|
749
|
-
const canShip = verdict === 'SHIP';
|
|
750
|
-
|
|
751
519
|
const lines = [];
|
|
752
520
|
|
|
753
521
|
// Verdict card (hero moment)
|
|
@@ -760,19 +528,11 @@ function formatShipOutput(result, options = {}) {
|
|
|
760
528
|
cached,
|
|
761
529
|
}));
|
|
762
530
|
|
|
763
|
-
// AI Hallucination Score (always show - this is a key selling point)
|
|
764
|
-
lines.push(renderAIHallucinationScore(findings));
|
|
765
|
-
|
|
766
531
|
// Findings breakdown
|
|
767
532
|
lines.push(renderFindingsBreakdown(findings));
|
|
768
533
|
|
|
769
|
-
// Blocker details
|
|
770
|
-
lines.push(renderBlockerDetails(findings
|
|
771
|
-
|
|
772
|
-
// Upgrade prompts for FREE tier users (if there are fixable issues)
|
|
773
|
-
if (findings.length > 0 && !isProTier) {
|
|
774
|
-
lines.push(renderUpgradePrompts(findings, verdict));
|
|
775
|
-
}
|
|
534
|
+
// Blocker details
|
|
535
|
+
lines.push(renderBlockerDetails(findings));
|
|
776
536
|
|
|
777
537
|
// Verbose: Route truth map
|
|
778
538
|
if (verbose && truthpack) {
|
|
@@ -791,25 +551,18 @@ function formatShipOutput(result, options = {}) {
|
|
|
791
551
|
lines.push(renderFixResults(fixResults));
|
|
792
552
|
}
|
|
793
553
|
|
|
794
|
-
// Badge (if requested
|
|
795
|
-
if (showBadge
|
|
796
|
-
const badgeResult = renderBadgeOutput(projectPath, verdict, score
|
|
554
|
+
// Badge (if requested)
|
|
555
|
+
if (showBadge) {
|
|
556
|
+
const badgeResult = renderBadgeOutput(projectPath, verdict, score);
|
|
797
557
|
lines.push(badgeResult.output);
|
|
798
|
-
} else if (showBadge && !isProTier) {
|
|
799
|
-
// Show badge upsell for FREE users
|
|
800
|
-
lines.push('');
|
|
801
|
-
lines.push(renderSection('BADGE', '📛'));
|
|
802
|
-
lines.push('');
|
|
803
|
-
lines.push(` ${ansi.dim}🔒 Ship badges require PRO ($69/mo)${ansi.reset}`);
|
|
804
|
-
lines.push(` ${colors.accent}vibecheckai.dev/pricing${ansi.reset} ${ansi.dim}to upgrade${ansi.reset}`);
|
|
805
|
-
lines.push('');
|
|
806
558
|
}
|
|
807
559
|
|
|
808
560
|
// Report links
|
|
809
561
|
lines.push(renderReportLinks(outputDir, showFix));
|
|
810
562
|
|
|
811
|
-
// Next steps (
|
|
812
|
-
|
|
563
|
+
// Next steps (if not shipping)
|
|
564
|
+
const canShip = verdict === 'SHIP';
|
|
565
|
+
lines.push(renderNextSteps(canShip, showFix));
|
|
813
566
|
|
|
814
567
|
return lines.filter(Boolean).join('\n');
|
|
815
568
|
}
|
|
@@ -875,12 +628,6 @@ module.exports = {
|
|
|
875
628
|
renderBadgeOutput,
|
|
876
629
|
renderNextSteps,
|
|
877
630
|
renderReportLinks,
|
|
878
|
-
renderAIHallucinationScore,
|
|
879
|
-
renderUpgradePrompts,
|
|
880
|
-
|
|
881
|
-
// AI Hallucination scoring
|
|
882
|
-
calculateAIHallucinationScore,
|
|
883
|
-
AI_HALLUCINATION_CATEGORIES,
|
|
884
631
|
|
|
885
632
|
// Utilities
|
|
886
633
|
getVerdictConfig,
|