@vibecheckai/cli 3.1.8 → 3.2.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 +106 -116
- package/bin/runners/context/generators/mcp.js +18 -0
- package/bin/runners/context/index.js +72 -4
- package/bin/runners/context/proof-context.js +293 -1
- package/bin/runners/context/security-scanner.js +311 -73
- package/bin/runners/lib/agent-firewall/change-packet/builder.js +214 -0
- package/bin/runners/lib/agent-firewall/change-packet/schema.json +228 -0
- package/bin/runners/lib/agent-firewall/change-packet/store.js +200 -0
- package/bin/runners/lib/agent-firewall/claims/claim-types.js +21 -0
- package/bin/runners/lib/agent-firewall/claims/extractor.js +214 -0
- package/bin/runners/lib/agent-firewall/claims/patterns.js +24 -0
- package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +88 -0
- package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +75 -0
- package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +118 -0
- package/bin/runners/lib/agent-firewall/evidence/resolver.js +102 -0
- package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +142 -0
- package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +145 -0
- package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +19 -0
- package/bin/runners/lib/agent-firewall/fs-hook/installer.js +87 -0
- package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +184 -0
- package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +163 -0
- package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +107 -0
- package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +68 -0
- package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +66 -0
- package/bin/runners/lib/agent-firewall/interceptor/base.js +304 -0
- package/bin/runners/lib/agent-firewall/interceptor/cursor.js +35 -0
- package/bin/runners/lib/agent-firewall/interceptor/vscode.js +35 -0
- package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +34 -0
- package/bin/runners/lib/agent-firewall/policy/default-policy.json +84 -0
- package/bin/runners/lib/agent-firewall/policy/engine.js +72 -0
- package/bin/runners/lib/agent-firewall/policy/loader.js +143 -0
- package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +50 -0
- package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +50 -0
- package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +61 -0
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +50 -0
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +50 -0
- package/bin/runners/lib/agent-firewall/policy/rules/scope.js +93 -0
- package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +57 -0
- package/bin/runners/lib/agent-firewall/policy/schema.json +183 -0
- package/bin/runners/lib/agent-firewall/policy/verdict.js +54 -0
- package/bin/runners/lib/agent-firewall/truthpack/index.js +67 -0
- package/bin/runners/lib/agent-firewall/truthpack/loader.js +116 -0
- package/bin/runners/lib/agent-firewall/unblock/planner.js +337 -0
- package/bin/runners/lib/analysis-core.js +198 -180
- package/bin/runners/lib/analyzers.js +1394 -224
- package/bin/runners/lib/detectors-v2.js +560 -641
- package/bin/runners/lib/entitlements-v2.js +48 -1
- package/bin/runners/lib/evidence-pack.js +678 -0
- package/bin/runners/lib/fingerprint.js +377 -0
- package/bin/runners/lib/html-proof-report.js +913 -0
- package/bin/runners/lib/missions/plan.js +231 -41
- package/bin/runners/lib/missions/templates.js +125 -0
- package/bin/runners/lib/route-truth.js +1167 -322
- package/bin/runners/lib/scan-output.js +558 -235
- package/bin/runners/lib/ship-output.js +901 -641
- package/bin/runners/lib/truth.js +1004 -321
- package/bin/runners/runAgent.js +161 -0
- package/bin/runners/runCheckpoint.js +44 -3
- package/bin/runners/runContext.d.ts +4 -0
- package/bin/runners/runDoctor.js +10 -2
- package/bin/runners/runFirewall.js +134 -0
- package/bin/runners/runFirewallHook.js +56 -0
- package/bin/runners/runFix.js +51 -341
- package/bin/runners/runInit.js +11 -0
- package/bin/runners/runPolish.d.ts +4 -0
- package/bin/runners/runPolish.js +608 -29
- package/bin/runners/runProve.js +210 -25
- package/bin/runners/runReality.js +846 -101
- package/bin/runners/runScan.js +351 -14
- package/bin/runners/runShip.js +19 -3
- package/bin/runners/runTruth.js +89 -0
- package/bin/runners/runWatch.js +14 -1
- package/bin/vibecheck.js +32 -2
- package/mcp-server/agent-firewall-interceptor.js +164 -0
- package/mcp-server/consolidated-tools.js +408 -42
- package/mcp-server/index.js +498 -327
- package/mcp-server/proof-tools.js +571 -0
- package/mcp-server/tier-auth.js +22 -19
- package/mcp-server/tools-v3.js +744 -0
- package/mcp-server/truth-context.js +131 -90
- package/mcp-server/truth-firewall-tools.js +1494 -941
- package/package.json +3 -1
- package/bin/runners/runInstall.js +0 -281
- package/bin/runners/runLabs.js +0 -341
package/bin/vibecheck.js
CHANGED
|
@@ -888,6 +888,14 @@ ${c.green}QUICK START - The 5-Step Journey${c.reset}
|
|
|
888
888
|
4. ${c.bold}Prove${c.reset} ${c.cyan}vibecheck prove${c.reset} ${c.magenta}[PRO]${c.reset}
|
|
889
889
|
5. ${c.bold}Ship${c.reset} ${c.cyan}vibecheck ship${c.reset}
|
|
890
890
|
|
|
891
|
+
${c.bold}GLOBAL OPTIONS${c.reset}
|
|
892
|
+
|
|
893
|
+
${c.cyan}--offline, --local${c.reset} Run in offline mode (no API, unlimited local scans)
|
|
894
|
+
${c.cyan}--json${c.reset} Output as JSON
|
|
895
|
+
${c.cyan}--quiet, -q${c.reset} Suppress output
|
|
896
|
+
${c.cyan}--verbose${c.reset} Show detailed output
|
|
897
|
+
${c.cyan}--path, -p <dir>${c.reset} Run in specified directory
|
|
898
|
+
|
|
891
899
|
${c.bold}SHELL COMPLETIONS${c.reset}
|
|
892
900
|
|
|
893
901
|
${c.cyan}vibecheck completion bash${c.reset} ${c.dim}# Add to ~/.bashrc${c.reset}
|
|
@@ -939,6 +947,7 @@ function parseGlobalFlags(rawArgs) {
|
|
|
939
947
|
debug: false,
|
|
940
948
|
strict: false,
|
|
941
949
|
noBanner: false,
|
|
950
|
+
offline: false,
|
|
942
951
|
path: process.cwd(),
|
|
943
952
|
output: null,
|
|
944
953
|
};
|
|
@@ -980,6 +989,10 @@ function parseGlobalFlags(rawArgs) {
|
|
|
980
989
|
case "--no-banner":
|
|
981
990
|
flags.noBanner = true;
|
|
982
991
|
break;
|
|
992
|
+
case "--offline":
|
|
993
|
+
case "--local":
|
|
994
|
+
flags.offline = true;
|
|
995
|
+
break;
|
|
983
996
|
case "--path":
|
|
984
997
|
case "-p":
|
|
985
998
|
flags.path = rawArgs[++i] || process.cwd();
|
|
@@ -1077,6 +1090,7 @@ async function main() {
|
|
|
1077
1090
|
}
|
|
1078
1091
|
if (globalFlags.verbose) cmdArgs.push("--verbose");
|
|
1079
1092
|
if (globalFlags.strict) cmdArgs.push("--strict");
|
|
1093
|
+
if (globalFlags.offline) cmdArgs.push("--offline");
|
|
1080
1094
|
|
|
1081
1095
|
// Unknown command
|
|
1082
1096
|
if (!COMMANDS[cmd]) {
|
|
@@ -1103,8 +1117,13 @@ async function main() {
|
|
|
1103
1117
|
const cmdDef = COMMANDS[cmd];
|
|
1104
1118
|
let authInfo = { key: null };
|
|
1105
1119
|
|
|
1106
|
-
//
|
|
1107
|
-
|
|
1120
|
+
// Check for offline mode (via flag or env var)
|
|
1121
|
+
const isOffline = globalFlags.offline ||
|
|
1122
|
+
process.env.VIBECHECK_OFFLINE === '1' ||
|
|
1123
|
+
process.env.VIBECHECK_LOCAL === '1';
|
|
1124
|
+
|
|
1125
|
+
// Auth check (unless skipAuth or offline mode)
|
|
1126
|
+
if (!cmdDef.skipAuth && !isOffline) {
|
|
1108
1127
|
const auth = getAuthModule();
|
|
1109
1128
|
const { key } = auth.getApiKey();
|
|
1110
1129
|
authInfo.key = key;
|
|
@@ -1136,6 +1155,17 @@ async function main() {
|
|
|
1136
1155
|
}
|
|
1137
1156
|
|
|
1138
1157
|
authInfo.access = access;
|
|
1158
|
+
} else if (isOffline) {
|
|
1159
|
+
// Offline mode - provide basic access info
|
|
1160
|
+
if (!config.quiet && !config.noBanner) {
|
|
1161
|
+
console.log(`${c.cyan}${sym.arrowRight} OFFLINE${c.reset} ${c.dim}mode - local scanning without API${c.reset}`);
|
|
1162
|
+
}
|
|
1163
|
+
authInfo.access = {
|
|
1164
|
+
allowed: true,
|
|
1165
|
+
tier: 'free',
|
|
1166
|
+
caps: { maxFiles: 100, maxDepth: 3 },
|
|
1167
|
+
offline: true
|
|
1168
|
+
};
|
|
1139
1169
|
}
|
|
1140
1170
|
|
|
1141
1171
|
// Update state
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Firewall Interceptor - MCP Tool
|
|
3
|
+
*
|
|
4
|
+
* Intercepts file write/patch tool calls from AI agents.
|
|
5
|
+
* Validates changes against truthpack and policy before allowing writes.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
"use strict";
|
|
9
|
+
|
|
10
|
+
const path = require("path");
|
|
11
|
+
const fs = require("fs");
|
|
12
|
+
const { interceptFileWrite, interceptMultiFileWrite } = require("../../bin/runners/lib/agent-firewall/interceptor/base");
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* MCP Tool Definition
|
|
16
|
+
*/
|
|
17
|
+
const AGENT_FIREWALL_TOOL = {
|
|
18
|
+
name: "vibecheck_agent_firewall_intercept",
|
|
19
|
+
description: `🛡️ Agent Firewall - Intercepts AI code changes and validates against repo truth.
|
|
20
|
+
|
|
21
|
+
This tool MUST be called before any file write/patch operations.
|
|
22
|
+
It validates changes against truthpack and policy rules.
|
|
23
|
+
|
|
24
|
+
Returns: { allowed, verdict, violations, unblockPlan }`,
|
|
25
|
+
inputSchema: {
|
|
26
|
+
type: "object",
|
|
27
|
+
required: ["agentId", "filePath", "content"],
|
|
28
|
+
properties: {
|
|
29
|
+
agentId: {
|
|
30
|
+
type: "string",
|
|
31
|
+
description: "Agent identifier (e.g., 'cursor', 'windsurf', 'copilot')"
|
|
32
|
+
},
|
|
33
|
+
filePath: {
|
|
34
|
+
type: "string",
|
|
35
|
+
description: "File path relative to project root"
|
|
36
|
+
},
|
|
37
|
+
content: {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: "New file content"
|
|
40
|
+
},
|
|
41
|
+
oldContent: {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "Old file content (optional, for diff generation)"
|
|
44
|
+
},
|
|
45
|
+
intent: {
|
|
46
|
+
type: "string",
|
|
47
|
+
description: "Agent's stated intent for this change"
|
|
48
|
+
},
|
|
49
|
+
projectRoot: {
|
|
50
|
+
type: "string",
|
|
51
|
+
default: ".",
|
|
52
|
+
description: "Project root directory"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Handle MCP tool call
|
|
60
|
+
* @param {string} name - Tool name (unused, for consistency)
|
|
61
|
+
* @param {object} args - Tool arguments
|
|
62
|
+
* @returns {object} MCP tool response
|
|
63
|
+
*/
|
|
64
|
+
async function handleAgentFirewallIntercept(name, args) {
|
|
65
|
+
const projectRoot = path.resolve(args.projectRoot || ".");
|
|
66
|
+
const agentId = args.agentId || "unknown";
|
|
67
|
+
const filePath = args.filePath;
|
|
68
|
+
const content = args.content;
|
|
69
|
+
const oldContent = args.oldContent || null;
|
|
70
|
+
const intent = args.intent || "No intent provided";
|
|
71
|
+
|
|
72
|
+
// Validate file path is within project root
|
|
73
|
+
const fileAbs = path.resolve(projectRoot, filePath);
|
|
74
|
+
if (!fileAbs.startsWith(projectRoot + path.sep) && fileAbs !== projectRoot) {
|
|
75
|
+
return {
|
|
76
|
+
content: [{
|
|
77
|
+
type: "text",
|
|
78
|
+
text: `❌ BLOCKED: File path outside project root: ${filePath}`
|
|
79
|
+
}],
|
|
80
|
+
isError: true
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
// Read old content if not provided
|
|
86
|
+
let actualOldContent = oldContent;
|
|
87
|
+
if (!actualOldContent && fs.existsSync(fileAbs)) {
|
|
88
|
+
actualOldContent = fs.readFileSync(fileAbs, "utf8");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Intercept the write
|
|
92
|
+
const result = await interceptFileWrite({
|
|
93
|
+
projectRoot,
|
|
94
|
+
agentId,
|
|
95
|
+
intent,
|
|
96
|
+
filePath,
|
|
97
|
+
content,
|
|
98
|
+
oldContent: actualOldContent
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Check policy mode (already loaded in interceptFileWrite, but we need it for mode check)
|
|
102
|
+
const { loadPolicy } = require("../../bin/runners/lib/agent-firewall/policy/loader");
|
|
103
|
+
const policy = loadPolicy(projectRoot);
|
|
104
|
+
|
|
105
|
+
if (policy.mode === "observe") {
|
|
106
|
+
// Observe mode - log but don't block
|
|
107
|
+
return {
|
|
108
|
+
content: [{
|
|
109
|
+
type: "text",
|
|
110
|
+
text: `📊 OBSERVE MODE: ${result.verdict}\n\n${result.message}\n\nPacket ID: ${result.packetId}`
|
|
111
|
+
}]
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Enforce mode - block if not allowed
|
|
116
|
+
if (!result.allowed) {
|
|
117
|
+
let message = `❌ BLOCKED: ${result.message}\n\n`;
|
|
118
|
+
|
|
119
|
+
if (result.violations && result.violations.length > 0) {
|
|
120
|
+
message += "Violations:\n";
|
|
121
|
+
for (const violation of result.violations) {
|
|
122
|
+
message += ` - ${violation.rule}: ${violation.message}\n`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (result.unblockPlan && result.unblockPlan.steps.length > 0) {
|
|
127
|
+
message += "\nTo unblock:\n";
|
|
128
|
+
for (const step of result.unblockPlan.steps) {
|
|
129
|
+
message += ` ${step.action === "create" ? "Create" : "Modify"} ${step.file || "file"}: ${step.description}\n`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
content: [{
|
|
135
|
+
type: "text",
|
|
136
|
+
text: message
|
|
137
|
+
}],
|
|
138
|
+
isError: true
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Allowed
|
|
143
|
+
return {
|
|
144
|
+
content: [{
|
|
145
|
+
type: "text",
|
|
146
|
+
text: `✅ ALLOWED: ${result.message}\n\nPacket ID: ${result.packetId}`
|
|
147
|
+
}]
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
} catch (error) {
|
|
151
|
+
return {
|
|
152
|
+
content: [{
|
|
153
|
+
type: "text",
|
|
154
|
+
text: `❌ Error intercepting write: ${error.message}\n\n${error.stack}`
|
|
155
|
+
}],
|
|
156
|
+
isError: true
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
module.exports = {
|
|
162
|
+
AGENT_FIREWALL_TOOL,
|
|
163
|
+
handleAgentFirewallIntercept
|
|
164
|
+
};
|