@vibecheckai/cli 3.2.0 → 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/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 +1119 -536
- package/bin/runners/lib/detectors-v2.js +547 -785
- package/bin/runners/lib/fingerprint.js +377 -0
- package/bin/runners/lib/route-truth.js +1167 -322
- package/bin/runners/lib/scan-output.js +93 -9
- package/bin/runners/lib/truth.js +1004 -321
- package/bin/runners/runAgent.js +161 -0
- package/bin/runners/runFirewall.js +134 -0
- package/bin/runners/runFirewallHook.js +56 -0
- package/bin/runners/runScan.js +113 -10
- package/bin/runners/runTruth.js +89 -0
- package/mcp-server/agent-firewall-interceptor.js +164 -0
- package/mcp-server/index.js +347 -313
- package/mcp-server/truth-context.js +131 -90
- package/mcp-server/truth-firewall-tools.js +1412 -1045
- package/package.json +1 -1
|
@@ -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
|
+
};
|