@vibecheckai/cli 3.2.5 → 3.3.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/.generated +25 -25
- package/bin/dev/run-v2-torture.js +30 -30
- package/bin/registry.js +192 -5
- package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -295
- package/bin/runners/lib/agent-firewall/change-packet/builder.js +280 -6
- package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
- package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
- package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
- package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
- package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
- package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
- package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
- package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
- package/bin/runners/lib/agent-firewall/logger.js +141 -0
- package/bin/runners/lib/agent-firewall/policy/loader.js +312 -4
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +113 -1
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +133 -6
- package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
- package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
- package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
- package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
- package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
- package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
- package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
- package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
- package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
- package/bin/runners/lib/agent-firewall/risk/thresholds.js +321 -0
- package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
- package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
- package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
- package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
- package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
- package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
- package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
- package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
- package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
- package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
- package/bin/runners/lib/analyzers.js +81 -18
- package/bin/runners/lib/api-client.js +269 -0
- package/bin/runners/lib/auth-truth.js +193 -193
- package/bin/runners/lib/authority-badge.js +425 -0
- package/bin/runners/lib/backup.js +62 -62
- package/bin/runners/lib/billing.js +107 -107
- package/bin/runners/lib/claims.js +118 -118
- package/bin/runners/lib/cli-output.js +7 -1
- package/bin/runners/lib/cli-ui.js +540 -540
- package/bin/runners/lib/contracts/auth-contract.js +202 -202
- package/bin/runners/lib/contracts/env-contract.js +181 -181
- package/bin/runners/lib/contracts/external-contract.js +206 -206
- package/bin/runners/lib/contracts/guard.js +168 -168
- package/bin/runners/lib/contracts/index.js +89 -89
- package/bin/runners/lib/contracts/plan-validator.js +311 -311
- package/bin/runners/lib/contracts/route-contract.js +199 -199
- package/bin/runners/lib/contracts.js +804 -804
- package/bin/runners/lib/detect.js +89 -89
- package/bin/runners/lib/doctor/autofix.js +254 -254
- package/bin/runners/lib/doctor/index.js +37 -37
- package/bin/runners/lib/doctor/modules/dependencies.js +325 -325
- package/bin/runners/lib/doctor/modules/index.js +46 -46
- package/bin/runners/lib/doctor/modules/network.js +250 -250
- package/bin/runners/lib/doctor/modules/project.js +312 -312
- package/bin/runners/lib/doctor/modules/runtime.js +224 -224
- package/bin/runners/lib/doctor/modules/security.js +348 -348
- package/bin/runners/lib/doctor/modules/system.js +213 -213
- package/bin/runners/lib/doctor/modules/vibecheck.js +394 -394
- package/bin/runners/lib/doctor/reporter.js +262 -262
- package/bin/runners/lib/doctor/service.js +262 -262
- package/bin/runners/lib/doctor/types.js +113 -113
- package/bin/runners/lib/doctor/ui.js +263 -263
- package/bin/runners/lib/doctor-v2.js +608 -608
- package/bin/runners/lib/drift.js +425 -425
- package/bin/runners/lib/enforcement.js +72 -72
- package/bin/runners/lib/enterprise-detect.js +603 -603
- package/bin/runners/lib/enterprise-init.js +942 -942
- package/bin/runners/lib/env-resolver.js +417 -417
- package/bin/runners/lib/env-template.js +66 -66
- package/bin/runners/lib/env.js +189 -189
- package/bin/runners/lib/error-handler.js +16 -9
- package/bin/runners/lib/exit-codes.js +275 -0
- package/bin/runners/lib/extractors/client-calls.js +990 -990
- package/bin/runners/lib/extractors/fastify-route-dump.js +573 -573
- package/bin/runners/lib/extractors/fastify-routes.js +426 -426
- package/bin/runners/lib/extractors/index.js +363 -363
- package/bin/runners/lib/extractors/next-routes.js +524 -524
- package/bin/runners/lib/extractors/proof-graph.js +431 -431
- package/bin/runners/lib/extractors/route-matcher.js +451 -451
- package/bin/runners/lib/extractors/truthpack-v2.js +377 -377
- package/bin/runners/lib/extractors/ui-bindings.js +547 -547
- package/bin/runners/lib/findings-schema.js +281 -281
- package/bin/runners/lib/firewall-prompt.js +50 -50
- package/bin/runners/lib/global-flags.js +37 -0
- package/bin/runners/lib/graph/graph-builder.js +265 -265
- package/bin/runners/lib/graph/html-renderer.js +413 -413
- package/bin/runners/lib/graph/index.js +32 -32
- package/bin/runners/lib/graph/runtime-collector.js +215 -215
- package/bin/runners/lib/graph/static-extractor.js +518 -518
- package/bin/runners/lib/help-formatter.js +413 -0
- package/bin/runners/lib/html-report.js +650 -650
- package/bin/runners/lib/llm.js +75 -75
- package/bin/runners/lib/logger.js +38 -0
- package/bin/runners/lib/meter.js +61 -61
- package/bin/runners/lib/missions/evidence.js +126 -126
- package/bin/runners/lib/patch.js +40 -40
- package/bin/runners/lib/permissions/auth-model.js +213 -213
- package/bin/runners/lib/permissions/idor-prover.js +205 -205
- package/bin/runners/lib/permissions/index.js +45 -45
- package/bin/runners/lib/permissions/matrix-builder.js +198 -198
- package/bin/runners/lib/pkgjson.js +28 -28
- package/bin/runners/lib/policy.js +295 -295
- package/bin/runners/lib/preflight.js +142 -142
- package/bin/runners/lib/reality/correlation-detectors.js +359 -359
- package/bin/runners/lib/reality/index.js +318 -318
- package/bin/runners/lib/reality/request-hashing.js +416 -416
- package/bin/runners/lib/reality/request-mapper.js +453 -453
- package/bin/runners/lib/reality/safety-rails.js +463 -463
- package/bin/runners/lib/reality/semantic-snapshot.js +408 -408
- package/bin/runners/lib/reality/toast-detector.js +393 -393
- package/bin/runners/lib/reality-findings.js +84 -84
- package/bin/runners/lib/receipts.js +179 -179
- package/bin/runners/lib/redact.js +29 -29
- package/bin/runners/lib/replay/capsule-manager.js +154 -154
- package/bin/runners/lib/replay/index.js +263 -263
- package/bin/runners/lib/replay/player.js +348 -348
- package/bin/runners/lib/replay/recorder.js +331 -331
- package/bin/runners/lib/report.js +135 -135
- package/bin/runners/lib/route-detection.js +1140 -1140
- package/bin/runners/lib/sandbox/index.js +59 -59
- package/bin/runners/lib/sandbox/proof-chain.js +399 -399
- package/bin/runners/lib/sandbox/sandbox-runner.js +205 -205
- package/bin/runners/lib/sandbox/worktree.js +174 -174
- package/bin/runners/lib/schema-validator.js +350 -350
- package/bin/runners/lib/schemas/contracts.schema.json +160 -160
- package/bin/runners/lib/schemas/finding.schema.json +100 -100
- package/bin/runners/lib/schemas/mission-pack.schema.json +206 -206
- package/bin/runners/lib/schemas/proof-graph.schema.json +176 -176
- package/bin/runners/lib/schemas/reality-report.schema.json +162 -162
- package/bin/runners/lib/schemas/share-pack.schema.json +180 -180
- package/bin/runners/lib/schemas/ship-report.schema.json +117 -117
- package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -303
- package/bin/runners/lib/schemas/validator.js +438 -438
- package/bin/runners/lib/score-history.js +282 -282
- package/bin/runners/lib/share-pack.js +239 -239
- package/bin/runners/lib/snippets.js +67 -67
- package/bin/runners/lib/unified-cli-output.js +604 -0
- package/bin/runners/lib/upsell.js +658 -510
- package/bin/runners/lib/usage.js +153 -153
- package/bin/runners/lib/validate-patch.js +156 -156
- package/bin/runners/lib/verdict-engine.js +628 -628
- package/bin/runners/reality/engine.js +917 -917
- package/bin/runners/reality/flows.js +122 -122
- package/bin/runners/reality/report.js +378 -378
- package/bin/runners/reality/session.js +193 -193
- package/bin/runners/runAgent.d.ts +5 -0
- package/bin/runners/runApprove.js +1200 -0
- package/bin/runners/runAuth.js +324 -95
- package/bin/runners/runCheckpoint.js +39 -21
- package/bin/runners/runClassify.js +859 -0
- package/bin/runners/runContext.js +136 -24
- package/bin/runners/runDoctor.js +108 -68
- package/bin/runners/runFirewall.d.ts +5 -0
- package/bin/runners/runFirewallHook.d.ts +5 -0
- package/bin/runners/runFix.js +6 -5
- package/bin/runners/runGuard.js +262 -168
- package/bin/runners/runInit.js +3 -2
- package/bin/runners/runMcp.js +130 -52
- package/bin/runners/runPolish.js +43 -20
- package/bin/runners/runProve.js +1 -2
- package/bin/runners/runReport.js +3 -2
- package/bin/runners/runScan.js +145 -44
- package/bin/runners/runShip.js +3 -4
- package/bin/runners/runTruth.d.ts +5 -0
- package/bin/runners/runValidate.js +19 -2
- package/bin/runners/runWatch.js +104 -53
- package/bin/vibecheck.js +106 -19
- package/mcp-server/HARDENING_SUMMARY.md +299 -0
- package/mcp-server/agent-firewall-interceptor.js +367 -31
- package/mcp-server/authority-tools.js +569 -0
- package/mcp-server/conductor/conflict-resolver.js +588 -0
- package/mcp-server/conductor/execution-planner.js +544 -0
- package/mcp-server/conductor/index.js +377 -0
- package/mcp-server/conductor/lock-manager.js +615 -0
- package/mcp-server/conductor/request-queue.js +550 -0
- package/mcp-server/conductor/session-manager.js +500 -0
- package/mcp-server/conductor/tools.js +510 -0
- package/mcp-server/index.js +1199 -208
- package/mcp-server/lib/api-client.cjs +305 -0
- package/mcp-server/lib/logger.cjs +30 -0
- package/mcp-server/logger.js +173 -0
- package/mcp-server/package.json +2 -2
- package/mcp-server/premium-tools.js +2 -2
- package/mcp-server/tier-auth.js +351 -136
- package/mcp-server/tools/index.js +72 -72
- package/mcp-server/truth-firewall-tools.js +145 -15
- package/mcp-server/vibecheck-tools.js +2 -2
- package/package.json +2 -3
- package/mcp-server/index.old.js +0 -4137
- package/mcp-server/package-lock.json +0 -165
package/bin/runners/runMcp.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const path = require("path");
|
|
9
|
+
const fs = require("fs");
|
|
9
10
|
const http = require("http");
|
|
10
11
|
const { URL } = require("url");
|
|
11
12
|
|
|
@@ -14,6 +15,8 @@ const { buildTruthpack, writeTruthpack } = require("./lib/truth");
|
|
|
14
15
|
const { shipCore } = require("./runShip");
|
|
15
16
|
const { generateRunId } = require("./lib/cli-output");
|
|
16
17
|
const { enforceLimit, enforceFeature, trackUsage } = require("./lib/entitlements");
|
|
18
|
+
const { EXIT } = require("./lib/exit-codes");
|
|
19
|
+
const { parseGlobalFlags, shouldSuppressOutput, isJsonMode } = require("./lib/global-flags");
|
|
17
20
|
|
|
18
21
|
// MCP Server class
|
|
19
22
|
class VibecheckMCPServer {
|
|
@@ -642,8 +645,14 @@ class VibecheckMCPServer {
|
|
|
642
645
|
});
|
|
643
646
|
|
|
644
647
|
this.server.on("error", err => {
|
|
645
|
-
console.error("MCP Server failed to start:", err);
|
|
646
|
-
|
|
648
|
+
console.error("MCP Server failed to start:", err.message);
|
|
649
|
+
if (err.code === "EADDRINUSE") {
|
|
650
|
+
console.error(` Port ${this.port} is already in use. Try a different port with --port`);
|
|
651
|
+
} else if (err.code === "EACCES") {
|
|
652
|
+
console.error(` Permission denied for port ${this.port}. Use a port > 1024`);
|
|
653
|
+
}
|
|
654
|
+
// Emit error event for caller to handle
|
|
655
|
+
this.emit?.("error", err);
|
|
647
656
|
});
|
|
648
657
|
}
|
|
649
658
|
|
|
@@ -658,54 +667,77 @@ class VibecheckMCPServer {
|
|
|
658
667
|
// CLI handler
|
|
659
668
|
async function runMcp(args) {
|
|
660
669
|
const opts = parseArgs(args);
|
|
670
|
+
const { flags: globalFlags } = parseGlobalFlags(args);
|
|
671
|
+
const quiet = shouldSuppressOutput(globalFlags);
|
|
672
|
+
const json = isJsonMode(globalFlags);
|
|
661
673
|
|
|
662
674
|
// Check if we're in free tier and only showing help/config
|
|
663
675
|
const isFreeTier = process.env.VIBECHECK_TIER === "free" || !process.env.VIBECHECK_API_KEY;
|
|
664
676
|
const isHelpOrConfig = opts.help || opts.printConfig || opts.status || opts.test;
|
|
665
677
|
|
|
666
678
|
if (isFreeTier && !isHelpOrConfig) {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
679
|
+
if (json) {
|
|
680
|
+
console.log(JSON.stringify({ success: false, error: "MCP Server requires STARTER plan or higher" }));
|
|
681
|
+
} else if (!quiet) {
|
|
682
|
+
console.log("\n🔌 MCP Server requires STARTER plan or higher");
|
|
683
|
+
console.log("Use --help to see available options or");
|
|
684
|
+
console.log("Upgrade: https://vibecheckai.dev/pricing\n");
|
|
685
|
+
}
|
|
686
|
+
return EXIT.TIER_REQUIRED;
|
|
673
687
|
}
|
|
674
688
|
|
|
675
689
|
if (opts.help) {
|
|
676
690
|
printHelp();
|
|
677
|
-
return
|
|
691
|
+
return EXIT.SUCCESS;
|
|
678
692
|
}
|
|
679
693
|
|
|
680
694
|
if (opts.printConfig) {
|
|
681
695
|
printClientConfig(opts);
|
|
682
|
-
return
|
|
696
|
+
return EXIT.SUCCESS;
|
|
683
697
|
}
|
|
684
698
|
|
|
685
699
|
if (opts.status) {
|
|
686
700
|
// Check server status
|
|
687
701
|
try {
|
|
688
|
-
const
|
|
702
|
+
const host = opts.host || "127.0.0.1";
|
|
703
|
+
const port = opts.port || 3000;
|
|
704
|
+
const response = await fetch(`http://${host}:${port}/status`);
|
|
689
705
|
const status = await response.json();
|
|
690
706
|
console.log(JSON.stringify(status, null, 2));
|
|
691
|
-
return
|
|
707
|
+
return EXIT.SUCCESS;
|
|
692
708
|
} catch (err) {
|
|
693
|
-
|
|
694
|
-
|
|
709
|
+
if (json) {
|
|
710
|
+
console.log(JSON.stringify({ success: false, error: "Server not running or not reachable" }));
|
|
711
|
+
} else {
|
|
712
|
+
console.error("Server not running or not reachable");
|
|
713
|
+
console.error(" Start the server with: vibecheck mcp");
|
|
714
|
+
}
|
|
715
|
+
return EXIT.NETWORK_ERROR;
|
|
695
716
|
}
|
|
696
717
|
}
|
|
697
718
|
|
|
698
719
|
if (opts.test) {
|
|
699
720
|
// Test connection
|
|
700
721
|
try {
|
|
701
|
-
const
|
|
722
|
+
const host = opts.host || "127.0.0.1";
|
|
723
|
+
const port = opts.port || 3000;
|
|
724
|
+
const response = await fetch(`http://${host}:${port}/tools`);
|
|
702
725
|
const tools = await response.json();
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
726
|
+
if (json) {
|
|
727
|
+
console.log(JSON.stringify({ success: true, toolCount: tools.tools?.length || 0 }));
|
|
728
|
+
} else {
|
|
729
|
+
console.log("✅ Connection successful");
|
|
730
|
+
console.log(`📋 Available tools: ${tools.tools?.length || 0}`);
|
|
731
|
+
}
|
|
732
|
+
return EXIT.SUCCESS;
|
|
706
733
|
} catch (err) {
|
|
707
|
-
|
|
708
|
-
|
|
734
|
+
if (json) {
|
|
735
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
736
|
+
} else {
|
|
737
|
+
console.error("❌ Connection failed:", err.message);
|
|
738
|
+
console.error(" Ensure the MCP server is running");
|
|
739
|
+
}
|
|
740
|
+
return EXIT.NETWORK_ERROR;
|
|
709
741
|
}
|
|
710
742
|
}
|
|
711
743
|
|
|
@@ -713,42 +745,88 @@ async function runMcp(args) {
|
|
|
713
745
|
let config = {};
|
|
714
746
|
if (opts.config) {
|
|
715
747
|
const configPath = path.resolve(opts.config);
|
|
716
|
-
if (
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
748
|
+
if (!fs.existsSync(configPath)) {
|
|
749
|
+
if (json) {
|
|
750
|
+
console.log(JSON.stringify({ success: false, error: `Config file not found: ${configPath}` }));
|
|
751
|
+
} else {
|
|
752
|
+
console.error(`Config file not found: ${configPath}`);
|
|
753
|
+
}
|
|
754
|
+
return EXIT.NOT_FOUND;
|
|
755
|
+
}
|
|
756
|
+
try {
|
|
757
|
+
config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
758
|
+
} catch (parseErr) {
|
|
759
|
+
if (json) {
|
|
760
|
+
console.log(JSON.stringify({ success: false, error: `Invalid JSON in config: ${parseErr.message}` }));
|
|
761
|
+
} else {
|
|
762
|
+
console.error(`Invalid JSON in config file: ${parseErr.message}`);
|
|
763
|
+
}
|
|
764
|
+
return EXIT.USER_ERROR;
|
|
721
765
|
}
|
|
722
766
|
}
|
|
723
767
|
|
|
724
|
-
//
|
|
725
|
-
const
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
server.start();
|
|
736
|
-
|
|
737
|
-
// Handle shutdown
|
|
738
|
-
process.on("SIGINT", () => {
|
|
739
|
-
console.log("\nShutting down MCP server...");
|
|
740
|
-
server.stop();
|
|
741
|
-
process.exit(0);
|
|
742
|
-
});
|
|
743
|
-
|
|
744
|
-
process.on("SIGTERM", () => {
|
|
745
|
-
console.log("\nShutting down MCP server...");
|
|
746
|
-
server.stop();
|
|
747
|
-
process.exit(0);
|
|
748
|
-
});
|
|
768
|
+
// Validate port
|
|
769
|
+
const port = opts.port || config.server?.port || 3000;
|
|
770
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
771
|
+
if (json) {
|
|
772
|
+
console.log(JSON.stringify({ success: false, error: `Invalid port: ${port}` }));
|
|
773
|
+
} else {
|
|
774
|
+
console.error(`Invalid port: ${port}`);
|
|
775
|
+
console.error(" Port must be a number between 1 and 65535");
|
|
776
|
+
}
|
|
777
|
+
return EXIT.USER_ERROR;
|
|
778
|
+
}
|
|
749
779
|
|
|
750
|
-
|
|
751
|
-
|
|
780
|
+
try {
|
|
781
|
+
// Create and start server
|
|
782
|
+
const server = new VibecheckMCPServer({
|
|
783
|
+
host: opts.host || config.server?.host || "127.0.0.1",
|
|
784
|
+
port: port,
|
|
785
|
+
allowRemote: opts.allowRemote || config.server?.allowRemote || false,
|
|
786
|
+
requireApiKey: opts.requireApiKey !== false,
|
|
787
|
+
apiKey: opts.apiKey || config.auth?.apiKey,
|
|
788
|
+
logLevel: opts.logLevel || config.logging?.level || "info",
|
|
789
|
+
auditLog: opts.auditLog || config.logging?.auditFile
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
// Track if server started successfully
|
|
793
|
+
let serverStarted = false;
|
|
794
|
+
let serverError = null;
|
|
795
|
+
|
|
796
|
+
// Listen for server errors before starting
|
|
797
|
+
server.server?.on?.("error", (err) => {
|
|
798
|
+
serverError = err;
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
server.start();
|
|
802
|
+
serverStarted = true;
|
|
803
|
+
|
|
804
|
+
// Handle shutdown gracefully
|
|
805
|
+
const cleanup = () => {
|
|
806
|
+
if (!quiet) console.log("\nShutting down MCP server...");
|
|
807
|
+
server.stop();
|
|
808
|
+
};
|
|
809
|
+
|
|
810
|
+
process.on("SIGINT", () => {
|
|
811
|
+
cleanup();
|
|
812
|
+
process.exit(EXIT.SUCCESS);
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
process.on("SIGTERM", () => {
|
|
816
|
+
cleanup();
|
|
817
|
+
process.exit(EXIT.SUCCESS);
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
// Keep process alive
|
|
821
|
+
return new Promise(() => {});
|
|
822
|
+
} catch (error) {
|
|
823
|
+
if (json) {
|
|
824
|
+
console.log(JSON.stringify({ success: false, error: error.message }));
|
|
825
|
+
} else {
|
|
826
|
+
console.error(`Failed to start MCP server: ${error.message}`);
|
|
827
|
+
}
|
|
828
|
+
return EXIT.INTERNAL_ERROR;
|
|
829
|
+
}
|
|
752
830
|
}
|
|
753
831
|
|
|
754
832
|
// Argument parsing
|
package/bin/runners/runPolish.js
CHANGED
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
|
|
25
25
|
const fs = require("fs");
|
|
26
26
|
const path = require("path");
|
|
27
|
+
const { EXIT } = require("./lib/exit-codes");
|
|
28
|
+
const { parseGlobalFlags, shouldSuppressOutput, isJsonMode } = require("./lib/global-flags");
|
|
27
29
|
|
|
28
30
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
29
31
|
// TERMINAL STYLING
|
|
@@ -2856,26 +2858,35 @@ function getCategoryIcon(category) {
|
|
|
2856
2858
|
|
|
2857
2859
|
async function runPolish(args) {
|
|
2858
2860
|
const opts = parseArgs(args);
|
|
2861
|
+
const { flags: globalFlags } = parseGlobalFlags(args);
|
|
2862
|
+
const quiet = shouldSuppressOutput(globalFlags);
|
|
2863
|
+
const json = isJsonMode(globalFlags) || opts.json;
|
|
2859
2864
|
|
|
2860
2865
|
if (opts.help) {
|
|
2861
2866
|
printHelp();
|
|
2862
|
-
return
|
|
2867
|
+
return EXIT.SUCCESS;
|
|
2863
2868
|
}
|
|
2864
2869
|
|
|
2865
2870
|
const projectPath = path.resolve(opts.path);
|
|
2866
2871
|
|
|
2867
2872
|
// Verify project exists
|
|
2868
2873
|
if (!await pathExists(projectPath)) {
|
|
2869
|
-
|
|
2870
|
-
|
|
2874
|
+
if (json) {
|
|
2875
|
+
console.log(JSON.stringify({ success: false, error: `Project path does not exist: ${projectPath}` }));
|
|
2876
|
+
} else {
|
|
2877
|
+
console.error(`${c.red}${icons.cross} Project path does not exist: ${projectPath}${c.reset}`);
|
|
2878
|
+
console.error(` Verify the path and try again.`);
|
|
2879
|
+
}
|
|
2880
|
+
return EXIT.NOT_FOUND;
|
|
2871
2881
|
}
|
|
2872
2882
|
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2883
|
+
try {
|
|
2884
|
+
// JSON mode
|
|
2885
|
+
if (json) {
|
|
2886
|
+
const report = await analyzeProject(projectPath, opts);
|
|
2887
|
+
console.log(JSON.stringify(report, null, 2));
|
|
2888
|
+
return report.critical > 0 ? EXIT.BLOCKING : EXIT.SUCCESS;
|
|
2889
|
+
}
|
|
2879
2890
|
|
|
2880
2891
|
// Interactive mode
|
|
2881
2892
|
console.log(`
|
|
@@ -2914,8 +2925,10 @@ ${c.bold}╔══════════════════════
|
|
|
2914
2925
|
console.log(` ${icons.critical} ${report.critical} critical ${icons.high} ${report.high} high ${icons.medium} ${report.medium} medium ${icons.low} ${report.low} low\n`);
|
|
2915
2926
|
|
|
2916
2927
|
if (report.issues.length === 0) {
|
|
2917
|
-
|
|
2918
|
-
|
|
2928
|
+
if (!quiet) {
|
|
2929
|
+
console.log(`\n${c.green}${c.bold}${icons.check} Perfect!${c.reset} No polish issues found. Your project is production-ready! ${icons.rocket}\n`);
|
|
2930
|
+
}
|
|
2931
|
+
return EXIT.SUCCESS;
|
|
2919
2932
|
}
|
|
2920
2933
|
|
|
2921
2934
|
// Group by category
|
|
@@ -3016,16 +3029,26 @@ ${c.bold}╔══════════════════════
|
|
|
3016
3029
|
}
|
|
3017
3030
|
|
|
3018
3031
|
// Next steps
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3032
|
+
if (!quiet) {
|
|
3033
|
+
console.log(`${c.bold}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${c.reset}`);
|
|
3034
|
+
console.log(`${c.bold}${icons.rocket} NEXT STEPS${c.reset}`);
|
|
3035
|
+
console.log(`${c.bold}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${c.reset}\n`);
|
|
3036
|
+
console.log(` 1. Fix ${c.red}critical${c.reset} and ${c.yellow}high${c.reset} severity issues first`);
|
|
3037
|
+
console.log(` 2. Use ${c.cyan}vibecheck polish --prompts${c.reset} to get AI-ready fixes`);
|
|
3038
|
+
console.log(` 3. Copy prompts to your AI assistant (Cursor, Copilot, Claude)`);
|
|
3039
|
+
console.log(` 4. Re-run ${c.cyan}vibecheck polish${c.reset} to verify fixes`);
|
|
3040
|
+
console.log(` 5. Run ${c.cyan}vibecheck ship${c.reset} when score is 80+\n`);
|
|
3041
|
+
}
|
|
3027
3042
|
|
|
3028
|
-
return report.critical > 0 ?
|
|
3043
|
+
return report.critical > 0 ? EXIT.BLOCKING : EXIT.SUCCESS;
|
|
3044
|
+
} catch (error) {
|
|
3045
|
+
if (json) {
|
|
3046
|
+
console.log(JSON.stringify({ success: false, error: error.message }));
|
|
3047
|
+
} else {
|
|
3048
|
+
console.error(`${c.red}${icons.cross} Polish analysis failed: ${error.message}${c.reset}`);
|
|
3049
|
+
}
|
|
3050
|
+
return EXIT.INTERNAL_ERROR;
|
|
3051
|
+
}
|
|
3029
3052
|
}
|
|
3030
3053
|
|
|
3031
3054
|
module.exports = { runPolish };
|
package/bin/runners/runProve.js
CHANGED
|
@@ -26,10 +26,9 @@ const {
|
|
|
26
26
|
generateRunId,
|
|
27
27
|
createJsonOutput,
|
|
28
28
|
writeJsonOutput,
|
|
29
|
-
exitCodeToVerdict,
|
|
30
|
-
verdictToExitCode,
|
|
31
29
|
saveArtifact
|
|
32
30
|
} = require("./lib/cli-output");
|
|
31
|
+
const { EXIT, verdictToExitCode, exitCodeToVerdict } = require("./lib/exit-codes");
|
|
33
32
|
const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
|
|
34
33
|
const upsell = require("./lib/upsell");
|
|
35
34
|
|
package/bin/runners/runReport.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
const path = require("path");
|
|
19
19
|
const fs = require("fs");
|
|
20
20
|
const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
|
|
21
|
+
const { EXIT } = require("./lib/exit-codes");
|
|
21
22
|
|
|
22
23
|
// Entitlements enforcement
|
|
23
24
|
let entitlements;
|
|
@@ -264,11 +265,11 @@ async function runReport(args) {
|
|
|
264
265
|
default:
|
|
265
266
|
spinner.fail(`Unknown format: ${format}`);
|
|
266
267
|
console.log(` ${ansi.dim}Supported: html, md, json, sarif, csv, pdf${ansi.reset}`);
|
|
267
|
-
return
|
|
268
|
+
return EXIT.USER_ERROR;
|
|
268
269
|
}
|
|
269
270
|
} catch (err) {
|
|
270
271
|
spinner.fail(`Failed to generate report: ${err.message}`);
|
|
271
|
-
return
|
|
272
|
+
return EXIT.INTERNAL_ERROR;
|
|
272
273
|
}
|
|
273
274
|
|
|
274
275
|
// Determine output path
|
package/bin/runners/runScan.js
CHANGED
|
@@ -18,6 +18,14 @@ const { withErrorHandling, createUserError } = require("./lib/error-handler");
|
|
|
18
18
|
const { enforceLimit, trackUsage } = require("./lib/entitlements");
|
|
19
19
|
const { emitScanStart, emitScanComplete } = require("./lib/audit-bridge");
|
|
20
20
|
const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
|
|
21
|
+
const {
|
|
22
|
+
createScan,
|
|
23
|
+
updateScanProgress,
|
|
24
|
+
submitScanResults,
|
|
25
|
+
reportScanError,
|
|
26
|
+
isApiAvailable
|
|
27
|
+
} = require("./lib/api-client");
|
|
28
|
+
const { EXIT, verdictToExitCode } = require("./lib/exit-codes");
|
|
21
29
|
|
|
22
30
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
23
31
|
// ENHANCED TERMINAL UI & OUTPUT MODULES
|
|
@@ -163,57 +171,75 @@ function printHelp(showBanner = true) {
|
|
|
163
171
|
console.log(BANNER);
|
|
164
172
|
}
|
|
165
173
|
console.log(`
|
|
166
|
-
${ansi.bold}
|
|
174
|
+
${ansi.bold}USAGE${ansi.reset}
|
|
175
|
+
${colors.accent}vibecheck scan${ansi.reset} [path] [options]
|
|
167
176
|
|
|
168
|
-
${ansi.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
${colors.accent}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
${colors.accent}--
|
|
178
|
-
|
|
179
|
-
${ansi.bold}
|
|
180
|
-
${colors.accent}--
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
${colors.accent}--allowlist
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
${colors.accent}--
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
${colors.accent}--
|
|
195
|
-
${colors.accent}--
|
|
196
|
-
${colors.accent}--
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
177
|
+
${ansi.dim}Aliases: s, check${ansi.reset}
|
|
178
|
+
|
|
179
|
+
The core analysis engine. Scans your codebase for route integrity issues,
|
|
180
|
+
security vulnerabilities, code quality problems, and more.
|
|
181
|
+
|
|
182
|
+
${ansi.bold}SCAN LAYERS${ansi.reset}
|
|
183
|
+
${colors.accent}(default)${ansi.reset} Layer 1: AST static analysis ${ansi.dim}(fast, ~2s)${ansi.reset}
|
|
184
|
+
${colors.accent}--truth, -t${ansi.reset} Layer 1+2: + build manifest verification ${ansi.dim}(CI/ship)${ansi.reset}
|
|
185
|
+
${colors.accent}--reality, -r${ansi.reset} Layer 1+2+3: + Playwright runtime proof ${ansi.dim}[PRO]${ansi.reset}
|
|
186
|
+
${colors.accent}--reality-sniff${ansi.reset} Include Reality Sniff AI artifact detection
|
|
187
|
+
|
|
188
|
+
${ansi.bold}FIX MODE${ansi.reset} ${ansi.cyan}[STARTER]${ansi.reset}
|
|
189
|
+
${colors.accent}--autofix, -f${ansi.reset} Generate AI fix missions for detected issues
|
|
190
|
+
|
|
191
|
+
${ansi.bold}BASELINE TRACKING${ansi.reset}
|
|
192
|
+
${colors.accent}--baseline${ansi.reset} Compare against previous scan ${ansi.dim}(default: on)${ansi.reset}
|
|
193
|
+
${colors.accent}--no-baseline${ansi.reset} Skip baseline comparison
|
|
194
|
+
${colors.accent}--update-baseline${ansi.reset} Save current findings as new baseline
|
|
195
|
+
|
|
196
|
+
${ansi.bold}ALLOWLIST (suppress false positives)${ansi.reset}
|
|
197
|
+
${colors.accent}--allowlist list${ansi.reset} Show all suppressed findings
|
|
198
|
+
${colors.accent}--allowlist add --id <id> --reason "..."${ansi.reset}
|
|
199
|
+
${colors.accent}--allowlist remove --id <id>${ansi.reset} Remove suppression
|
|
200
|
+
${colors.accent}--allowlist check --id <id>${ansi.reset} Check if suppressed
|
|
201
|
+
|
|
202
|
+
${ansi.bold}OUTPUT OPTIONS${ansi.reset}
|
|
203
|
+
${colors.accent}--json${ansi.reset} Output as JSON ${ansi.dim}(machine-readable)${ansi.reset}
|
|
204
|
+
${colors.accent}--sarif${ansi.reset} SARIF format ${ansi.dim}(GitHub code scanning)${ansi.reset}
|
|
205
|
+
${colors.accent}--no-save${ansi.reset} Don't save results to .vibecheck/results/
|
|
206
|
+
${colors.accent}--verbose, -v${ansi.reset} Show detailed progress
|
|
207
|
+
|
|
208
|
+
${ansi.bold}GLOBAL OPTIONS${ansi.reset}
|
|
209
|
+
${colors.accent}--path, -p <dir>${ansi.reset} Run in specified directory
|
|
210
|
+
${colors.accent}--quiet, -q${ansi.reset} Suppress non-essential output
|
|
211
|
+
${colors.accent}--ci${ansi.reset} CI mode ${ansi.dim}(quiet + no-banner)${ansi.reset}
|
|
212
|
+
${colors.accent}--help, -h${ansi.reset} Show this help
|
|
213
|
+
|
|
214
|
+
${ansi.bold}💡 EXAMPLES${ansi.reset}
|
|
215
|
+
|
|
216
|
+
${ansi.dim}# Quick scan (most common)${ansi.reset}
|
|
200
217
|
vibecheck scan
|
|
201
218
|
|
|
202
|
-
${ansi.dim}# Scan
|
|
219
|
+
${ansi.dim}# Scan with AI fix missions${ansi.reset}
|
|
203
220
|
vibecheck scan --autofix
|
|
204
221
|
|
|
205
|
-
${ansi.dim}#
|
|
206
|
-
vibecheck scan --allowlist add --id R_DEAD_abc123 --reason "
|
|
222
|
+
${ansi.dim}# Suppress a false positive${ansi.reset}
|
|
223
|
+
vibecheck scan --allowlist add --id R_DEAD_abc123 --reason "Feature toggle"
|
|
207
224
|
|
|
208
|
-
${ansi.dim}#
|
|
209
|
-
vibecheck scan --
|
|
225
|
+
${ansi.dim}# CI pipeline (JSON output, strict)${ansi.reset}
|
|
226
|
+
vibecheck scan --ci --json > results.json
|
|
210
227
|
|
|
211
|
-
${ansi.dim}# Full proof
|
|
228
|
+
${ansi.dim}# Full reality proof (requires running app)${ansi.reset}
|
|
212
229
|
vibecheck scan --reality --url http://localhost:3000
|
|
213
230
|
|
|
214
|
-
${ansi.bold}
|
|
215
|
-
Results
|
|
216
|
-
Missions
|
|
231
|
+
${ansi.bold}📄 OUTPUT${ansi.reset}
|
|
232
|
+
Results: .vibecheck/results/latest.json
|
|
233
|
+
Missions: .vibecheck/missions/ ${ansi.dim}(with --autofix)${ansi.reset}
|
|
234
|
+
History: .vibecheck/results/history/
|
|
235
|
+
|
|
236
|
+
${ansi.bold}🔗 RELATED COMMANDS${ansi.reset}
|
|
237
|
+
${colors.accent}vibecheck ship${ansi.reset} Get final SHIP/WARN/BLOCK verdict
|
|
238
|
+
${colors.accent}vibecheck fix${ansi.reset} Apply AI-generated fixes ${ansi.cyan}[STARTER]${ansi.reset}
|
|
239
|
+
${colors.accent}vibecheck prove${ansi.reset} Full proof pipeline with evidence ${ansi.magenta}[PRO]${ansi.reset}
|
|
240
|
+
|
|
241
|
+
${ansi.dim}─────────────────────────────────────────────────────────────${ansi.reset}
|
|
242
|
+
${ansi.dim}Documentation: https://docs.vibecheckai.dev/cli/scan${ansi.reset}
|
|
217
243
|
`);
|
|
218
244
|
}
|
|
219
245
|
|
|
@@ -703,6 +729,27 @@ async function runScan(args) {
|
|
|
703
729
|
emitScanStart(projectPath, args);
|
|
704
730
|
const projectName = path.basename(projectPath);
|
|
705
731
|
|
|
732
|
+
// Initialize API integration
|
|
733
|
+
let apiScan = null;
|
|
734
|
+
let apiConnected = false;
|
|
735
|
+
|
|
736
|
+
// Try to connect to API for dashboard integration
|
|
737
|
+
try {
|
|
738
|
+
apiConnected = await isApiAvailable();
|
|
739
|
+
if (apiConnected) {
|
|
740
|
+
// Create scan record in dashboard
|
|
741
|
+
apiScan = await createScan({
|
|
742
|
+
localPath: projectPath,
|
|
743
|
+
branch: opts.branch || 'main',
|
|
744
|
+
enableLLM: opts.llm || false,
|
|
745
|
+
});
|
|
746
|
+
console.log(`${colors.info}📡${ansi.reset} Connected to dashboard (Scan ID: ${apiScan.scanId})`);
|
|
747
|
+
}
|
|
748
|
+
} catch (err) {
|
|
749
|
+
// API connection is optional, continue without it
|
|
750
|
+
console.log(`${colors.dim}ℹ${ansi.reset} Dashboard integration unavailable`);
|
|
751
|
+
}
|
|
752
|
+
|
|
706
753
|
// Validate project path
|
|
707
754
|
if (!fs.existsSync(projectPath)) {
|
|
708
755
|
throw createUserError(`Project path does not exist: ${projectPath}`, "ValidationError");
|
|
@@ -733,7 +780,7 @@ async function runScan(args) {
|
|
|
733
780
|
console.log(` ${colors.warning}⚠${ansi.reset} ${ansi.bold}Reality layer requires --url${ansi.reset}`);
|
|
734
781
|
console.log(` ${ansi.dim}Example: vibecheck scan --reality --url http://localhost:3000${ansi.reset}`);
|
|
735
782
|
console.log();
|
|
736
|
-
return
|
|
783
|
+
return EXIT.USER_ERROR;
|
|
737
784
|
}
|
|
738
785
|
|
|
739
786
|
// Initialize spinner outside try block for error handling
|
|
@@ -1228,6 +1275,28 @@ async function runScan(args) {
|
|
|
1228
1275
|
durationMs: timings.total,
|
|
1229
1276
|
});
|
|
1230
1277
|
|
|
1278
|
+
// Submit results to dashboard if connected
|
|
1279
|
+
if (apiConnected && apiScan) {
|
|
1280
|
+
try {
|
|
1281
|
+
await submitScanResults(apiScan.scanId, {
|
|
1282
|
+
verdict: verdict.verdict,
|
|
1283
|
+
score: report.score?.overall || 0,
|
|
1284
|
+
findings: report.findings || [],
|
|
1285
|
+
filesScanned: report.stats?.filesScanned || 0,
|
|
1286
|
+
linesScanned: report.stats?.linesScanned || 0,
|
|
1287
|
+
durationMs: timings.total,
|
|
1288
|
+
metadata: {
|
|
1289
|
+
layers,
|
|
1290
|
+
profile: opts.profile,
|
|
1291
|
+
version: require('../../package.json').version,
|
|
1292
|
+
},
|
|
1293
|
+
});
|
|
1294
|
+
console.log(`${colors.success}✓${ansi.reset} Results sent to dashboard`);
|
|
1295
|
+
} catch (err) {
|
|
1296
|
+
console.log(`${colors.warning}⚠${ansi.reset} Failed to send results to dashboard: ${err.message}`);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1231
1300
|
return getExitCodeFromUnified ? getExitCodeFromUnified(verdict) : getExitCode(verdict);
|
|
1232
1301
|
} else {
|
|
1233
1302
|
// Legacy fallback output when unified output system isn't available
|
|
@@ -1316,8 +1385,30 @@ async function runScan(args) {
|
|
|
1316
1385
|
issueCount: criticalCount + warningCount,
|
|
1317
1386
|
durationMs: timings.total,
|
|
1318
1387
|
});
|
|
1388
|
+
|
|
1389
|
+
// Submit results to dashboard if connected
|
|
1390
|
+
if (apiConnected && apiScan) {
|
|
1391
|
+
try {
|
|
1392
|
+
await submitScanResults(apiScan.scanId, {
|
|
1393
|
+
verdict,
|
|
1394
|
+
score: verdict === 'SHIP' ? 100 : verdict === 'WARN' ? 70 : 40,
|
|
1395
|
+
findings: normalizedLegacyFindings,
|
|
1396
|
+
filesScanned: result.stats?.filesScanned || 0,
|
|
1397
|
+
linesScanned: result.stats?.linesScanned || 0,
|
|
1398
|
+
durationMs: timings.total,
|
|
1399
|
+
metadata: {
|
|
1400
|
+
layers,
|
|
1401
|
+
profile: opts.profile,
|
|
1402
|
+
version: require('../../package.json').version,
|
|
1403
|
+
},
|
|
1404
|
+
});
|
|
1405
|
+
console.log(`${colors.success}✓${ansi.reset} Results sent to dashboard`);
|
|
1406
|
+
} catch (err) {
|
|
1407
|
+
console.log(`${colors.warning}⚠${ansi.reset} Failed to send results to dashboard: ${err.message}`);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1319
1410
|
|
|
1320
|
-
return verdict
|
|
1411
|
+
return verdictToExitCode(verdict);
|
|
1321
1412
|
}
|
|
1322
1413
|
|
|
1323
1414
|
} catch (error) {
|
|
@@ -1334,6 +1425,16 @@ async function runScan(args) {
|
|
|
1334
1425
|
errorMessage: error.message,
|
|
1335
1426
|
durationMs: Date.now() - startTime,
|
|
1336
1427
|
});
|
|
1428
|
+
|
|
1429
|
+
// Report error to dashboard if connected
|
|
1430
|
+
if (apiConnected && apiScan) {
|
|
1431
|
+
try {
|
|
1432
|
+
await reportScanError(apiScan.scanId, error);
|
|
1433
|
+
console.log(`${colors.info}📡${ansi.reset} Error reported to dashboard`);
|
|
1434
|
+
} catch (err) {
|
|
1435
|
+
console.log(`${colors.warning}⚠${ansi.reset} Failed to report error to dashboard: ${err.message}`);
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1337
1438
|
|
|
1338
1439
|
return exitCode;
|
|
1339
1440
|
}
|