@vibecheckai/cli 3.2.6 → 3.4.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/registry.js +306 -90
- 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 +136 -141
- package/bin/runners/lib/authority-badge.js +425 -0
- package/bin/runners/lib/cli-output.js +7 -1
- package/bin/runners/lib/entitlements-v2.js +96 -505
- package/bin/runners/lib/error-handler.js +16 -9
- package/bin/runners/lib/exit-codes.js +275 -0
- package/bin/runners/lib/global-flags.js +37 -0
- package/bin/runners/lib/help-formatter.js +413 -0
- package/bin/runners/lib/logger.js +38 -0
- package/bin/runners/lib/scan-output.js +18 -19
- package/bin/runners/lib/ship-output.js +18 -25
- package/bin/runners/lib/unified-cli-output.js +604 -0
- package/bin/runners/lib/upsell.js +105 -205
- 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/runFix.js +6 -5
- package/bin/runners/runGuard.js +212 -118
- 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 +77 -45
- package/bin/runners/runShip.js +3 -4
- package/bin/runners/runValidate.js +19 -2
- package/bin/runners/runWatch.js +104 -53
- package/bin/vibecheck.js +103 -21
- 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 +1152 -856
- package/mcp-server/lib/api-client.cjs +13 -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 +194 -383
- package/mcp-server/tools-v3.js +495 -533
- 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/lib/api-client.js +0 -269
- package/mcp-server/package-lock.json +0 -165
package/mcp-server/tools-v3.js
CHANGED
|
@@ -1,28 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vibecheck MCP Tools v3 - Consolidated
|
|
2
|
+
* vibecheck MCP Tools v3 - Consolidated Tools
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Simple 2-tier model:
|
|
5
|
+
* - FREE ($0): Inspect & Observe (10 tools)
|
|
6
|
+
* - PRO ($69/mo): Fix, Prove & Enforce (18 tools)
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* 2. vibecheck.scan - Deep scan for issues
|
|
12
|
-
* 3. vibecheck.fix - Generate/apply fixes
|
|
13
|
-
* 4. vibecheck.prove - Full proof loop (PRO)
|
|
14
|
-
*
|
|
15
|
-
* TRUTH (3):
|
|
16
|
-
* 5. vibecheck.truthpack - Get ground truth (routes, env, auth, billing)
|
|
17
|
-
* 6. vibecheck.validate - Validate a claim with evidence
|
|
18
|
-
* 7. vibecheck.search - Search codebase with evidence
|
|
19
|
-
*
|
|
20
|
-
* OUTPUT (2):
|
|
21
|
-
* 8. vibecheck.report - Generate reports (HTML, SARIF, etc.)
|
|
22
|
-
* 9. vibecheck.allowlist - Manage false positive allowlist
|
|
23
|
-
*
|
|
24
|
-
* UTILITY (1):
|
|
25
|
-
* 10. vibecheck.status - Health check and status
|
|
8
|
+
* PRO includes:
|
|
9
|
+
* - Authority System (verdicts, approvals)
|
|
10
|
+
* - Agent Conductor (multi-agent coordination)
|
|
11
|
+
* - Agent Firewall (enforce mode)
|
|
26
12
|
*/
|
|
27
13
|
|
|
28
14
|
import fs from 'fs/promises';
|
|
@@ -30,388 +16,503 @@ import path from 'path';
|
|
|
30
16
|
import { execSync } from 'child_process';
|
|
31
17
|
|
|
32
18
|
// =============================================================================
|
|
33
|
-
// TIER
|
|
19
|
+
// TIER SYSTEM
|
|
34
20
|
// =============================================================================
|
|
35
21
|
|
|
36
22
|
const TOOL_TIERS = {
|
|
37
|
-
|
|
38
|
-
'vibecheck.scan': '
|
|
39
|
-
'vibecheck.
|
|
23
|
+
// FREE - Inspect & Observe
|
|
24
|
+
'vibecheck.scan': 'free',
|
|
25
|
+
'vibecheck.ctx': 'free',
|
|
26
|
+
'vibecheck.verify': 'free',
|
|
27
|
+
'vibecheck.report': 'free',
|
|
28
|
+
'vibecheck.status': 'free',
|
|
29
|
+
'vibecheck.doctor': 'free',
|
|
30
|
+
'vibecheck.firewall': 'free', // Observe mode
|
|
31
|
+
'authority.list': 'free',
|
|
32
|
+
'authority.classify': 'free',
|
|
33
|
+
'vibecheck_conductor_status': 'free',
|
|
34
|
+
|
|
35
|
+
// PRO - Fix, Prove & Enforce
|
|
36
|
+
'vibecheck.ship': 'pro',
|
|
37
|
+
'vibecheck.fix': 'pro',
|
|
40
38
|
'vibecheck.prove': 'pro',
|
|
41
|
-
'vibecheck.
|
|
42
|
-
'vibecheck.
|
|
43
|
-
'vibecheck.
|
|
44
|
-
'vibecheck.
|
|
45
|
-
'vibecheck.
|
|
46
|
-
|
|
39
|
+
'vibecheck.gate': 'pro',
|
|
40
|
+
'vibecheck.badge': 'pro',
|
|
41
|
+
'vibecheck.reality': 'pro',
|
|
42
|
+
'vibecheck.ai_test': 'pro',
|
|
43
|
+
'vibecheck.share': 'pro',
|
|
44
|
+
// Authority (full)
|
|
45
|
+
'authority.approve': 'pro',
|
|
46
|
+
// Conductor (full)
|
|
47
|
+
'vibecheck_conductor_register': 'pro',
|
|
48
|
+
'vibecheck_conductor_acquire_lock': 'pro',
|
|
49
|
+
'vibecheck_conductor_release_lock': 'pro',
|
|
50
|
+
'vibecheck_conductor_propose': 'pro',
|
|
51
|
+
'vibecheck_conductor_terminate': 'pro',
|
|
52
|
+
// Firewall (enforce)
|
|
53
|
+
'vibecheck_agent_firewall_intercept': 'pro',
|
|
47
54
|
};
|
|
48
55
|
|
|
56
|
+
function isPro(tier) {
|
|
57
|
+
return tier === 'pro';
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
function checkTierAccess(toolName, userTier) {
|
|
50
|
-
const
|
|
51
|
-
const tierOrder = { free: 0, starter: 1, pro: 2, compliance: 3 };
|
|
52
|
-
|
|
53
|
-
const userLevel = tierOrder[userTier] || 0;
|
|
54
|
-
const requiredLevel = tierOrder[requiredTier] || 1;
|
|
61
|
+
const required = TOOL_TIERS[toolName] || 'pro';
|
|
55
62
|
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
allowed: false,
|
|
59
|
-
error: `🔒 ${toolName} requires ${requiredTier.toUpperCase()} tier. You have: ${userTier.toUpperCase()}. Upgrade at vibecheck.dev/pricing`
|
|
60
|
-
};
|
|
61
|
-
}
|
|
63
|
+
if (required === 'free') return { allowed: true };
|
|
64
|
+
if (isPro(userTier)) return { allowed: true };
|
|
62
65
|
|
|
63
|
-
return {
|
|
66
|
+
return {
|
|
67
|
+
allowed: false,
|
|
68
|
+
error: `This tool requires Pro ($69/mo).\n\n${toolName} is a Pro feature.\n\nUpgrade at https://vibecheckai.dev/pricing`
|
|
69
|
+
};
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
// =============================================================================
|
|
67
|
-
// TOOL DEFINITIONS
|
|
73
|
+
// TOOL DEFINITIONS
|
|
68
74
|
// =============================================================================
|
|
69
75
|
|
|
70
76
|
export const MCP_TOOLS_V3 = [
|
|
71
77
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
72
|
-
//
|
|
78
|
+
// FREE TOOLS - Inspect & Observe
|
|
73
79
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
74
80
|
|
|
75
81
|
{
|
|
76
|
-
name: "vibecheck.
|
|
77
|
-
description:
|
|
78
|
-
|
|
79
|
-
Returns a verdict with evidence-backed findings. Use this to check if code is ready to ship.
|
|
82
|
+
name: "vibecheck.scan",
|
|
83
|
+
description: `🔍 Scan codebase for issues
|
|
80
84
|
|
|
81
|
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
85
|
+
Scans for:
|
|
86
|
+
- Missing routes (client refs to non-existent endpoints)
|
|
87
|
+
- Env gaps (used but undeclared env vars)
|
|
88
|
+
- Ghost auth (unprotected sensitive endpoints)
|
|
89
|
+
- Dead UI (buttons that do nothing)
|
|
90
|
+
- Security issues
|
|
86
91
|
|
|
87
|
-
[
|
|
92
|
+
[FREE]`,
|
|
88
93
|
inputSchema: {
|
|
89
94
|
type: "object",
|
|
90
95
|
properties: {
|
|
91
|
-
projectPath: {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
type: "boolean",
|
|
97
|
-
description: "Treat warnings as blockers",
|
|
98
|
-
default: false,
|
|
96
|
+
projectPath: { type: "string", description: "Project path" },
|
|
97
|
+
categories: {
|
|
98
|
+
type: "array",
|
|
99
|
+
items: { type: "string" },
|
|
100
|
+
description: "Categories: routes, env, auth, billing, security",
|
|
99
101
|
},
|
|
100
102
|
},
|
|
101
103
|
},
|
|
102
104
|
},
|
|
103
105
|
|
|
104
106
|
{
|
|
105
|
-
name: "vibecheck.
|
|
106
|
-
description:
|
|
107
|
+
name: "vibecheck.ctx",
|
|
108
|
+
description: `📦 Generate truth context for AI agents
|
|
107
109
|
|
|
108
|
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
- Dead UI (buttons that do nothing)
|
|
110
|
+
Returns verified facts about:
|
|
111
|
+
- routes: Server routes and client references
|
|
112
|
+
- env: Environment variables (used, declared, gaps)
|
|
113
|
+
- auth: Authentication model and protected routes
|
|
114
|
+
- billing: Payment gates and enforcement
|
|
114
115
|
|
|
115
|
-
|
|
116
|
+
Use this BEFORE making assertions about the codebase.
|
|
117
|
+
|
|
118
|
+
[FREE]`,
|
|
116
119
|
inputSchema: {
|
|
117
120
|
type: "object",
|
|
118
121
|
properties: {
|
|
119
|
-
projectPath: {
|
|
122
|
+
projectPath: { type: "string", description: "Project path" },
|
|
123
|
+
scope: {
|
|
120
124
|
type: "string",
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
type: "array",
|
|
125
|
-
items: { type: "string" },
|
|
126
|
-
description: "Categories to scan: routes, env, auth, billing, security",
|
|
125
|
+
enum: ["all", "routes", "env", "auth", "billing"],
|
|
126
|
+
description: "What to include",
|
|
127
|
+
default: "all",
|
|
127
128
|
},
|
|
128
129
|
},
|
|
129
130
|
},
|
|
130
131
|
},
|
|
131
132
|
|
|
132
133
|
{
|
|
133
|
-
name: "vibecheck.
|
|
134
|
-
description:
|
|
134
|
+
name: "vibecheck.verify",
|
|
135
|
+
description: `✅ Verify AI-generated code before applying
|
|
135
136
|
|
|
136
|
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
137
|
+
Checks for:
|
|
138
|
+
- Secrets in code
|
|
139
|
+
- Dangerous commands
|
|
140
|
+
- Path traversal
|
|
141
|
+
- Incomplete stubs
|
|
142
|
+
- Hallucinated imports
|
|
140
143
|
|
|
141
|
-
[
|
|
144
|
+
[FREE]`,
|
|
142
145
|
inputSchema: {
|
|
143
146
|
type: "object",
|
|
144
147
|
properties: {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
},
|
|
149
|
-
mode: {
|
|
150
|
-
type: "string",
|
|
151
|
-
enum: ["plan", "apply", "loop"],
|
|
152
|
-
description: "Fix mode (default: plan)",
|
|
153
|
-
default: "plan",
|
|
154
|
-
},
|
|
155
|
-
findingIds: {
|
|
156
|
-
type: "array",
|
|
157
|
-
items: { type: "string" },
|
|
158
|
-
description: "Specific finding IDs to fix (optional)",
|
|
159
|
-
},
|
|
148
|
+
code: { type: "string", description: "Code to verify" },
|
|
149
|
+
file: { type: "string", description: "Target file path" },
|
|
150
|
+
projectPath: { type: "string", description: "Project path" },
|
|
160
151
|
},
|
|
152
|
+
required: ["code"],
|
|
161
153
|
},
|
|
162
154
|
},
|
|
163
155
|
|
|
164
156
|
{
|
|
165
|
-
name: "vibecheck.
|
|
166
|
-
description:
|
|
157
|
+
name: "vibecheck.report",
|
|
158
|
+
description: `📄 Generate reports
|
|
167
159
|
|
|
168
|
-
|
|
169
|
-
Continues until SHIP verdict or stuck.
|
|
160
|
+
Formats: html, md, sarif, json
|
|
170
161
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
162
|
+
[FREE]`,
|
|
163
|
+
inputSchema: {
|
|
164
|
+
type: "object",
|
|
165
|
+
properties: {
|
|
166
|
+
projectPath: { type: "string" },
|
|
167
|
+
format: { type: "string", enum: ["html", "md", "sarif", "json"], default: "html" },
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
176
171
|
|
|
177
|
-
|
|
172
|
+
{
|
|
173
|
+
name: "vibecheck.status",
|
|
174
|
+
description: `📊 Check vibecheck status and health [FREE]`,
|
|
175
|
+
inputSchema: {
|
|
176
|
+
type: "object",
|
|
177
|
+
properties: { projectPath: { type: "string" } },
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
{
|
|
182
|
+
name: "vibecheck.doctor",
|
|
183
|
+
description: `🩺 Diagnose and fix environment issues [FREE]`,
|
|
178
184
|
inputSchema: {
|
|
179
185
|
type: "object",
|
|
180
186
|
properties: {
|
|
181
|
-
projectPath: {
|
|
182
|
-
|
|
183
|
-
description: "Project path",
|
|
184
|
-
},
|
|
185
|
-
url: {
|
|
186
|
-
type: "string",
|
|
187
|
-
description: "Base URL for runtime testing (e.g., http://localhost:3000)",
|
|
188
|
-
},
|
|
189
|
-
maxIterations: {
|
|
190
|
-
type: "number",
|
|
191
|
-
description: "Max fix iterations (default: 5)",
|
|
192
|
-
default: 5,
|
|
193
|
-
},
|
|
194
|
-
recordVideo: {
|
|
195
|
-
type: "boolean",
|
|
196
|
-
description: "Record video of browser sessions",
|
|
197
|
-
default: true,
|
|
198
|
-
},
|
|
187
|
+
projectPath: { type: "string" },
|
|
188
|
+
fix: { type: "boolean", default: false },
|
|
199
189
|
},
|
|
200
190
|
},
|
|
201
191
|
},
|
|
202
192
|
|
|
193
|
+
{
|
|
194
|
+
name: "vibecheck.firewall",
|
|
195
|
+
description: `🛡️ Agent Firewall - observe mode
|
|
196
|
+
|
|
197
|
+
Validates AI code changes against repo truth.
|
|
198
|
+
FREE tier: Observe only (logs but doesn't block).
|
|
199
|
+
PRO tier: Enforce mode (blocks violations).
|
|
200
|
+
|
|
201
|
+
[FREE - observe mode]`,
|
|
202
|
+
inputSchema: {
|
|
203
|
+
type: "object",
|
|
204
|
+
properties: {
|
|
205
|
+
action: { type: "string", enum: ["check", "status", "log"] },
|
|
206
|
+
code: { type: "string" },
|
|
207
|
+
file: { type: "string" },
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
{
|
|
213
|
+
name: "authority.list",
|
|
214
|
+
description: `📋 List available authorities [FREE]`,
|
|
215
|
+
inputSchema: {
|
|
216
|
+
type: "object",
|
|
217
|
+
properties: {
|
|
218
|
+
tier: { type: "string", enum: ["free", "pro"] },
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
{
|
|
224
|
+
name: "authority.classify",
|
|
225
|
+
description: `📊 Inventory Authority - analyze duplication and legacy code [FREE]`,
|
|
226
|
+
inputSchema: {
|
|
227
|
+
type: "object",
|
|
228
|
+
properties: {
|
|
229
|
+
projectPath: { type: "string", default: "." },
|
|
230
|
+
includeNear: { type: "boolean", default: true },
|
|
231
|
+
format: { type: "string", enum: ["json", "table", "markdown"], default: "json" },
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
|
|
236
|
+
{
|
|
237
|
+
name: "vibecheck_conductor_status",
|
|
238
|
+
description: `📡 Get multi-agent coordination status [FREE]`,
|
|
239
|
+
inputSchema: {
|
|
240
|
+
type: "object",
|
|
241
|
+
properties: {
|
|
242
|
+
projectRoot: { type: "string" },
|
|
243
|
+
includeDetails: { type: "boolean", default: false },
|
|
244
|
+
},
|
|
245
|
+
required: ["projectRoot"],
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
|
|
203
249
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
204
|
-
//
|
|
250
|
+
// PRO TOOLS - Fix, Prove & Enforce
|
|
205
251
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
206
252
|
|
|
207
253
|
{
|
|
208
|
-
name: "vibecheck.
|
|
209
|
-
description:
|
|
254
|
+
name: "vibecheck.ship",
|
|
255
|
+
description: `🚀 Get ship verdict: SHIP | WARN | BLOCK
|
|
210
256
|
|
|
211
|
-
Returns
|
|
212
|
-
|
|
213
|
-
-
|
|
214
|
-
|
|
215
|
-
|
|
257
|
+
Returns evidence-backed verdict.
|
|
258
|
+
|
|
259
|
+
[PRO - $69/mo]`,
|
|
260
|
+
inputSchema: {
|
|
261
|
+
type: "object",
|
|
262
|
+
properties: {
|
|
263
|
+
projectPath: { type: "string" },
|
|
264
|
+
strict: { type: "boolean" },
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
},
|
|
216
268
|
|
|
217
|
-
|
|
269
|
+
{
|
|
270
|
+
name: "vibecheck.fix",
|
|
271
|
+
description: `🔧 AI-powered fixes with proof
|
|
218
272
|
|
|
219
|
-
|
|
273
|
+
Modes: plan, apply, loop
|
|
220
274
|
|
|
221
|
-
[
|
|
275
|
+
[PRO - $69/mo]`,
|
|
222
276
|
inputSchema: {
|
|
223
277
|
type: "object",
|
|
224
278
|
properties: {
|
|
225
|
-
projectPath: {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
},
|
|
229
|
-
scope: {
|
|
230
|
-
type: "string",
|
|
231
|
-
enum: ["all", "routes", "env", "auth", "billing"],
|
|
232
|
-
description: "What to include (default: all)",
|
|
233
|
-
default: "all",
|
|
234
|
-
},
|
|
235
|
-
refresh: {
|
|
236
|
-
type: "boolean",
|
|
237
|
-
description: "Force rebuild (default: use cache)",
|
|
238
|
-
default: false,
|
|
239
|
-
},
|
|
279
|
+
projectPath: { type: "string" },
|
|
280
|
+
mode: { type: "string", enum: ["plan", "apply", "loop"], default: "plan" },
|
|
281
|
+
findingIds: { type: "array", items: { type: "string" } },
|
|
240
282
|
},
|
|
241
283
|
},
|
|
242
284
|
},
|
|
243
285
|
|
|
244
286
|
{
|
|
245
|
-
name: "vibecheck.
|
|
246
|
-
description:
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
- true: Claim verified with evidence citations
|
|
250
|
-
- false: Claim disproven with counterexamples
|
|
251
|
-
- unknown: Insufficient evidence (DO NOT proceed)
|
|
252
|
-
|
|
253
|
-
Claim types:
|
|
254
|
-
- route_exists: Check if route exists
|
|
255
|
-
- env_var_exists: Check if env var is declared
|
|
256
|
-
- auth_enforced: Check if route is protected
|
|
257
|
-
- file_exists: Check if file exists
|
|
258
|
-
- function_exists: Check if function exists
|
|
259
|
-
|
|
260
|
-
[STARTER tier required]`,
|
|
287
|
+
name: "vibecheck.prove",
|
|
288
|
+
description: `🔬 Full proof loop with runtime verification
|
|
289
|
+
|
|
290
|
+
[PRO - $69/mo]`,
|
|
261
291
|
inputSchema: {
|
|
262
292
|
type: "object",
|
|
263
293
|
properties: {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
},
|
|
269
|
-
subject: {
|
|
270
|
-
type: "object",
|
|
271
|
-
description: "What the claim is about",
|
|
272
|
-
properties: {
|
|
273
|
-
path: { type: "string", description: "Route path or file path" },
|
|
274
|
-
method: { type: "string", description: "HTTP method (for routes)" },
|
|
275
|
-
name: { type: "string", description: "Name of env var/function" },
|
|
276
|
-
},
|
|
277
|
-
},
|
|
278
|
-
projectPath: {
|
|
279
|
-
type: "string",
|
|
280
|
-
description: "Project path",
|
|
281
|
-
},
|
|
294
|
+
projectPath: { type: "string" },
|
|
295
|
+
url: { type: "string" },
|
|
296
|
+
maxIterations: { type: "number", default: 5 },
|
|
297
|
+
recordVideo: { type: "boolean", default: true },
|
|
282
298
|
},
|
|
283
|
-
required: ["claim", "subject"],
|
|
284
299
|
},
|
|
285
300
|
},
|
|
286
301
|
|
|
287
302
|
{
|
|
288
|
-
name: "vibecheck.
|
|
289
|
-
description:
|
|
303
|
+
name: "vibecheck.gate",
|
|
304
|
+
description: `🚧 CI/CD enforcement - fail builds on issues [PRO - $69/mo]`,
|
|
305
|
+
inputSchema: {
|
|
306
|
+
type: "object",
|
|
307
|
+
properties: {
|
|
308
|
+
projectPath: { type: "string" },
|
|
309
|
+
strict: { type: "boolean" },
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
},
|
|
290
313
|
|
|
291
|
-
|
|
292
|
-
|
|
314
|
+
{
|
|
315
|
+
name: "vibecheck.badge",
|
|
316
|
+
description: `🏷️ Generate ship badge [PRO - $69/mo]`,
|
|
317
|
+
inputSchema: {
|
|
318
|
+
type: "object",
|
|
319
|
+
properties: {
|
|
320
|
+
projectPath: { type: "string" },
|
|
321
|
+
outputPath: { type: "string" },
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
},
|
|
293
325
|
|
|
294
|
-
|
|
326
|
+
{
|
|
327
|
+
name: "vibecheck.reality",
|
|
328
|
+
description: `🧪 Full runtime verification with auth boundary testing [PRO - $69/mo]`,
|
|
295
329
|
inputSchema: {
|
|
296
330
|
type: "object",
|
|
297
331
|
properties: {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
},
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
},
|
|
332
|
+
url: { type: "string" },
|
|
333
|
+
auth: { type: "string" },
|
|
334
|
+
headed: { type: "boolean" },
|
|
335
|
+
maxPages: { type: "number", default: 20 },
|
|
336
|
+
},
|
|
337
|
+
required: ["url"],
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
{
|
|
342
|
+
name: "vibecheck.ai_test",
|
|
343
|
+
description: `🤖 AI agent testing - autonomous exploration [PRO - $69/mo]`,
|
|
344
|
+
inputSchema: {
|
|
345
|
+
type: "object",
|
|
346
|
+
properties: {
|
|
347
|
+
url: { type: "string" },
|
|
348
|
+
goal: { type: "string" },
|
|
349
|
+
maxActions: { type: "number", default: 50 },
|
|
350
|
+
},
|
|
351
|
+
required: ["url"],
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
|
|
355
|
+
{
|
|
356
|
+
name: "vibecheck.share",
|
|
357
|
+
description: `📤 Generate PR/review bundle [PRO - $69/mo]`,
|
|
358
|
+
inputSchema: {
|
|
359
|
+
type: "object",
|
|
360
|
+
properties: {
|
|
361
|
+
projectPath: { type: "string" },
|
|
362
|
+
format: { type: "string", enum: ["github", "gitlab", "slack", "json"], default: "github" },
|
|
315
363
|
},
|
|
316
|
-
required: ["query"],
|
|
317
364
|
},
|
|
318
365
|
},
|
|
319
366
|
|
|
320
367
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
321
|
-
//
|
|
368
|
+
// AUTHORITY SYSTEM (PRO)
|
|
322
369
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
323
370
|
|
|
324
371
|
{
|
|
325
|
-
name: "
|
|
326
|
-
description:
|
|
372
|
+
name: "authority.approve",
|
|
373
|
+
description: `🛡️ Authority Approval - Execute authority & get verdict (PROCEED/STOP/DEFER)
|
|
327
374
|
|
|
328
|
-
|
|
329
|
-
- html: Interactive HTML report
|
|
330
|
-
- md: Markdown report
|
|
331
|
-
- sarif: SARIF for GitHub code scanning
|
|
332
|
-
- json: Machine-readable JSON
|
|
375
|
+
Execute an authority to get a structured verdict with proofs.
|
|
333
376
|
|
|
334
|
-
[
|
|
377
|
+
[PRO - $69/mo]`,
|
|
335
378
|
inputSchema: {
|
|
336
379
|
type: "object",
|
|
337
380
|
properties: {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
},
|
|
342
|
-
format: {
|
|
343
|
-
type: "string",
|
|
344
|
-
enum: ["html", "md", "sarif", "json"],
|
|
345
|
-
description: "Output format (default: html)",
|
|
346
|
-
default: "html",
|
|
347
|
-
},
|
|
348
|
-
outputPath: {
|
|
349
|
-
type: "string",
|
|
350
|
-
description: "Output file path (optional)",
|
|
351
|
-
},
|
|
381
|
+
authority: { type: "string", description: "Authority ID (e.g., 'safe-consolidation')" },
|
|
382
|
+
projectPath: { type: "string", default: "." },
|
|
383
|
+
dryRun: { type: "boolean", default: false },
|
|
352
384
|
},
|
|
385
|
+
required: ["authority"],
|
|
353
386
|
},
|
|
354
387
|
},
|
|
355
388
|
|
|
389
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
390
|
+
// AGENT CONDUCTOR (PRO) - Multi-Agent Coordination
|
|
391
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
392
|
+
|
|
356
393
|
{
|
|
357
|
-
name: "
|
|
358
|
-
description:
|
|
394
|
+
name: "vibecheck_conductor_register",
|
|
395
|
+
description: `📡 Register AI agent for multi-agent coordination
|
|
359
396
|
|
|
360
|
-
|
|
361
|
-
- list: Show all allowlist entries
|
|
362
|
-
- add: Add finding to allowlist
|
|
363
|
-
- remove: Remove from allowlist
|
|
364
|
-
- check: Check if finding is allowlisted
|
|
397
|
+
Call this at the start of any multi-agent workflow.
|
|
365
398
|
|
|
366
|
-
[
|
|
399
|
+
[PRO - $69/mo]`,
|
|
367
400
|
inputSchema: {
|
|
368
401
|
type: "object",
|
|
369
402
|
properties: {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
403
|
+
agentId: { type: "string", description: "Agent ID (e.g., 'cursor', 'copilot')" },
|
|
404
|
+
projectRoot: { type: "string" },
|
|
405
|
+
workingFiles: { type: "array", items: { type: "string" } },
|
|
406
|
+
},
|
|
407
|
+
required: ["agentId", "projectRoot"],
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
|
|
411
|
+
{
|
|
412
|
+
name: "vibecheck_conductor_acquire_lock",
|
|
413
|
+
description: `🔒 Acquire lock on file/folder for exclusive access
|
|
414
|
+
|
|
415
|
+
Prevents concurrent modifications by other agents.
|
|
416
|
+
|
|
417
|
+
[PRO - $69/mo]`,
|
|
418
|
+
inputSchema: {
|
|
419
|
+
type: "object",
|
|
420
|
+
properties: {
|
|
421
|
+
sessionId: { type: "string" },
|
|
422
|
+
path: { type: "string" },
|
|
423
|
+
type: { type: "string", enum: ["exclusive", "shared"], default: "exclusive" },
|
|
424
|
+
reason: { type: "string" },
|
|
425
|
+
},
|
|
426
|
+
required: ["sessionId", "path"],
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
|
|
430
|
+
{
|
|
431
|
+
name: "vibecheck_conductor_release_lock",
|
|
432
|
+
description: `🔓 Release a previously acquired lock [PRO - $69/mo]`,
|
|
433
|
+
inputSchema: {
|
|
434
|
+
type: "object",
|
|
435
|
+
properties: {
|
|
436
|
+
lockId: { type: "string" },
|
|
437
|
+
sessionId: { type: "string" },
|
|
438
|
+
},
|
|
439
|
+
required: ["lockId", "sessionId"],
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
|
|
443
|
+
{
|
|
444
|
+
name: "vibecheck_conductor_propose",
|
|
445
|
+
description: `📋 Submit change proposal for multi-agent coordination
|
|
446
|
+
|
|
447
|
+
Checks for conflicts with other agents before proceeding.
|
|
448
|
+
|
|
449
|
+
[PRO - $69/mo]`,
|
|
450
|
+
inputSchema: {
|
|
451
|
+
type: "object",
|
|
452
|
+
properties: {
|
|
453
|
+
sessionId: { type: "string" },
|
|
454
|
+
proposalId: { type: "string" },
|
|
455
|
+
intent: { type: "string" },
|
|
456
|
+
operations: {
|
|
457
|
+
type: "array",
|
|
458
|
+
items: {
|
|
459
|
+
type: "object",
|
|
460
|
+
properties: {
|
|
461
|
+
type: { type: "string", enum: ["create", "modify", "delete", "move"] },
|
|
462
|
+
path: { type: "string" },
|
|
463
|
+
content: { type: "string" },
|
|
464
|
+
},
|
|
465
|
+
},
|
|
386
466
|
},
|
|
467
|
+
projectRoot: { type: "string" },
|
|
387
468
|
},
|
|
388
|
-
required: ["
|
|
469
|
+
required: ["sessionId", "proposalId", "intent", "operations", "projectRoot"],
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
|
|
473
|
+
{
|
|
474
|
+
name: "vibecheck_conductor_terminate",
|
|
475
|
+
description: `🛑 Terminate agent session and release all locks [PRO - $69/mo]`,
|
|
476
|
+
inputSchema: {
|
|
477
|
+
type: "object",
|
|
478
|
+
properties: {
|
|
479
|
+
sessionId: { type: "string" },
|
|
480
|
+
},
|
|
481
|
+
required: ["sessionId"],
|
|
389
482
|
},
|
|
390
483
|
},
|
|
391
484
|
|
|
392
485
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
393
|
-
//
|
|
486
|
+
// AGENT FIREWALL (PRO) - Enforce Mode
|
|
394
487
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
395
488
|
|
|
396
489
|
{
|
|
397
|
-
name: "
|
|
398
|
-
description:
|
|
490
|
+
name: "vibecheck_agent_firewall_intercept",
|
|
491
|
+
description: `🛡️ Agent Firewall (Sentinel) - ENFORCE MODE
|
|
492
|
+
|
|
493
|
+
Intercepts AI code changes and validates against repo truth.
|
|
494
|
+
Blocks violations. Generates proof artifacts.
|
|
495
|
+
|
|
496
|
+
Features:
|
|
497
|
+
- Reality state validation (routes, env, services)
|
|
498
|
+
- Risk scoring (surface area, blast radius)
|
|
499
|
+
- Diff simulation (broken imports, orphaned files)
|
|
500
|
+
- Assumption verification
|
|
501
|
+
- Proof artifact generation
|
|
399
502
|
|
|
400
|
-
|
|
401
|
-
- version: CLI version
|
|
402
|
-
- lastVerdict: Last ship verdict
|
|
403
|
-
- findingsCount: Current findings
|
|
404
|
-
- truthpackAge: When truthpack was last built
|
|
405
|
-
- config: Project configuration
|
|
503
|
+
Call BEFORE any file write operations.
|
|
406
504
|
|
|
407
|
-
[
|
|
505
|
+
[PRO - $69/mo]`,
|
|
408
506
|
inputSchema: {
|
|
409
507
|
type: "object",
|
|
508
|
+
required: ["agentId", "filePath", "content"],
|
|
410
509
|
properties: {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
},
|
|
510
|
+
agentId: { type: "string", description: "Agent ID" },
|
|
511
|
+
filePath: { type: "string", description: "File to write" },
|
|
512
|
+
content: { type: "string", description: "New content" },
|
|
513
|
+
operation: { type: "string", enum: ["create", "modify", "delete"], default: "modify" },
|
|
514
|
+
intent: { type: "string", description: "What this change accomplishes" },
|
|
515
|
+
projectRoot: { type: "string" },
|
|
415
516
|
},
|
|
416
517
|
},
|
|
417
518
|
},
|
|
@@ -424,321 +525,182 @@ Returns:
|
|
|
424
525
|
export async function handleToolV3(toolName, args, context = {}) {
|
|
425
526
|
const userTier = context.tier || 'free';
|
|
426
527
|
|
|
427
|
-
// Check tier access
|
|
428
528
|
const access = checkTierAccess(toolName, userTier);
|
|
429
529
|
if (!access.allowed) {
|
|
430
|
-
return { error: access.error
|
|
530
|
+
return { error: access.error };
|
|
431
531
|
}
|
|
432
532
|
|
|
433
533
|
const projectPath = args.projectPath || process.cwd();
|
|
434
534
|
|
|
435
535
|
try {
|
|
436
536
|
switch (toolName) {
|
|
437
|
-
case 'vibecheck.ship':
|
|
438
|
-
return await runShip(projectPath, args);
|
|
439
|
-
|
|
440
537
|
case 'vibecheck.scan':
|
|
441
|
-
|
|
442
|
-
|
|
538
|
+
case 'vibecheck.ctx':
|
|
539
|
+
case 'vibecheck.report':
|
|
540
|
+
case 'vibecheck.status':
|
|
541
|
+
case 'vibecheck.doctor':
|
|
542
|
+
case 'vibecheck.ship':
|
|
443
543
|
case 'vibecheck.fix':
|
|
444
|
-
return await runFix(projectPath, args, userTier);
|
|
445
|
-
|
|
446
544
|
case 'vibecheck.prove':
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
case 'vibecheck.
|
|
450
|
-
|
|
545
|
+
case 'vibecheck.gate':
|
|
546
|
+
case 'vibecheck.badge':
|
|
547
|
+
case 'vibecheck.reality':
|
|
548
|
+
case 'vibecheck.ai_test':
|
|
549
|
+
case 'vibecheck.share':
|
|
550
|
+
return await runCliCommand(projectPath, toolName.replace('vibecheck.', ''), args);
|
|
451
551
|
|
|
452
|
-
case 'vibecheck.
|
|
453
|
-
return await
|
|
552
|
+
case 'vibecheck.verify':
|
|
553
|
+
return await verifyCode(args);
|
|
454
554
|
|
|
455
|
-
case 'vibecheck.
|
|
456
|
-
return await
|
|
555
|
+
case 'vibecheck.firewall':
|
|
556
|
+
return await firewallCheck(args, userTier);
|
|
457
557
|
|
|
458
|
-
case '
|
|
459
|
-
|
|
558
|
+
case 'authority.list':
|
|
559
|
+
case 'authority.classify':
|
|
560
|
+
case 'authority.approve':
|
|
561
|
+
return await runCliCommand(projectPath, toolName.replace('authority.', 'authority '), args);
|
|
460
562
|
|
|
461
|
-
case '
|
|
462
|
-
|
|
563
|
+
case 'vibecheck_conductor_status':
|
|
564
|
+
case 'vibecheck_conductor_register':
|
|
565
|
+
case 'vibecheck_conductor_acquire_lock':
|
|
566
|
+
case 'vibecheck_conductor_release_lock':
|
|
567
|
+
case 'vibecheck_conductor_propose':
|
|
568
|
+
case 'vibecheck_conductor_terminate':
|
|
569
|
+
return await handleConductorTool(toolName, args, userTier);
|
|
463
570
|
|
|
464
|
-
case '
|
|
465
|
-
return await
|
|
571
|
+
case 'vibecheck_agent_firewall_intercept':
|
|
572
|
+
return await handleFirewallIntercept(args, userTier);
|
|
466
573
|
|
|
467
574
|
default:
|
|
468
575
|
return { error: `Unknown tool: ${toolName}` };
|
|
469
576
|
}
|
|
470
577
|
} catch (error) {
|
|
471
|
-
return { error: error.message
|
|
578
|
+
return { error: error.message };
|
|
472
579
|
}
|
|
473
580
|
}
|
|
474
581
|
|
|
475
582
|
// =============================================================================
|
|
476
|
-
//
|
|
583
|
+
// IMPLEMENTATIONS
|
|
477
584
|
// =============================================================================
|
|
478
585
|
|
|
479
|
-
async function
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
|
|
586
|
+
async function runCliCommand(projectPath, command, args) {
|
|
587
|
+
const flags = Object.entries(args)
|
|
588
|
+
.filter(([k, v]) => k !== 'projectPath' && v !== undefined && v !== null)
|
|
589
|
+
.map(([k, v]) => {
|
|
590
|
+
if (typeof v === 'boolean') return v ? `--${k}` : '';
|
|
591
|
+
if (Array.isArray(v)) return `--${k} ${v.join(',')}`;
|
|
592
|
+
return `--${k} "${v}"`;
|
|
593
|
+
})
|
|
594
|
+
.filter(Boolean)
|
|
595
|
+
.join(' ');
|
|
596
|
+
|
|
489
597
|
const result = execSync(
|
|
490
|
-
`
|
|
491
|
-
{ cwd: projectPath, encoding: 'utf8', timeout:
|
|
598
|
+
`npx vibecheck ${command} --json ${flags}`,
|
|
599
|
+
{ cwd: projectPath, encoding: 'utf8', timeout: 300000 }
|
|
492
600
|
);
|
|
493
|
-
|
|
601
|
+
|
|
602
|
+
try {
|
|
603
|
+
return JSON.parse(result);
|
|
604
|
+
} catch {
|
|
605
|
+
return { output: result };
|
|
606
|
+
}
|
|
494
607
|
}
|
|
495
608
|
|
|
496
|
-
async function
|
|
497
|
-
const
|
|
609
|
+
async function verifyCode(args) {
|
|
610
|
+
const { code } = args;
|
|
611
|
+
const issues = [];
|
|
498
612
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
613
|
+
if (/(?:password|secret|api_?key|token)\s*[:=]\s*['"][^'"]+['"]/i.test(code)) {
|
|
614
|
+
issues.push({ type: 'secret', message: 'Possible hardcoded secret' });
|
|
615
|
+
}
|
|
616
|
+
if (/eval\s*\(|Function\s*\(/.test(code)) {
|
|
617
|
+
issues.push({ type: 'danger', message: 'eval() or Function() detected' });
|
|
618
|
+
}
|
|
619
|
+
if (/TODO|FIXME|XXX|HACK/i.test(code)) {
|
|
620
|
+
issues.push({ type: 'stub', message: 'Incomplete code stub' });
|
|
502
621
|
}
|
|
503
622
|
|
|
504
|
-
|
|
505
|
-
const result = execSync(
|
|
506
|
-
`node "${path.join(projectPath, 'node_modules/.bin/vibecheck')}" fix ${modeFlag} --json`,
|
|
507
|
-
{ cwd: projectPath, encoding: 'utf8', timeout: 300000 }
|
|
508
|
-
);
|
|
509
|
-
return JSON.parse(result);
|
|
623
|
+
return { verified: issues.length === 0, issues };
|
|
510
624
|
}
|
|
511
625
|
|
|
512
|
-
async function
|
|
513
|
-
const
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
return JSON.parse(result);
|
|
626
|
+
async function firewallCheck(args, tier) {
|
|
627
|
+
const mode = tier === 'pro' ? 'enforce' : 'observe';
|
|
628
|
+
return {
|
|
629
|
+
mode,
|
|
630
|
+
checked: true,
|
|
631
|
+
message: mode === 'observe'
|
|
632
|
+
? 'Agent Firewall in observe mode (FREE). Upgrade to PRO for enforce mode.'
|
|
633
|
+
: 'Agent Firewall in enforce mode (PRO).',
|
|
634
|
+
};
|
|
522
635
|
}
|
|
523
636
|
|
|
524
|
-
async function
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
{ cwd: projectPath, encoding: 'utf8', timeout: 60000 }
|
|
531
|
-
);
|
|
637
|
+
async function handleConductorTool(toolName, args, tier) {
|
|
638
|
+
// For full conductor features, require PRO
|
|
639
|
+
if (toolName !== 'vibecheck_conductor_status' && tier !== 'pro') {
|
|
640
|
+
return {
|
|
641
|
+
error: 'Full Conductor features require PRO. Upgrade at https://vibecheckai.dev/pricing'
|
|
642
|
+
};
|
|
532
643
|
}
|
|
533
644
|
|
|
645
|
+
// Import and delegate to conductor handlers
|
|
534
646
|
try {
|
|
535
|
-
const
|
|
536
|
-
|
|
647
|
+
const {
|
|
648
|
+
handleConductorRegister,
|
|
649
|
+
handleConductorAcquireLock,
|
|
650
|
+
handleConductorReleaseLock,
|
|
651
|
+
handleConductorPropose,
|
|
652
|
+
handleConductorStatus,
|
|
653
|
+
handleConductorTerminate,
|
|
654
|
+
} = await import('./conductor/tools.js');
|
|
537
655
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
656
|
+
switch (toolName) {
|
|
657
|
+
case 'vibecheck_conductor_status':
|
|
658
|
+
return await handleConductorStatus(args);
|
|
659
|
+
case 'vibecheck_conductor_register':
|
|
660
|
+
return await handleConductorRegister(args);
|
|
661
|
+
case 'vibecheck_conductor_acquire_lock':
|
|
662
|
+
return await handleConductorAcquireLock(args);
|
|
663
|
+
case 'vibecheck_conductor_release_lock':
|
|
664
|
+
return await handleConductorReleaseLock(args);
|
|
665
|
+
case 'vibecheck_conductor_propose':
|
|
666
|
+
return await handleConductorPropose(args);
|
|
667
|
+
case 'vibecheck_conductor_terminate':
|
|
668
|
+
return await handleConductorTerminate(args);
|
|
669
|
+
default:
|
|
670
|
+
return { error: `Unknown conductor tool: ${toolName}` };
|
|
541
671
|
}
|
|
542
|
-
|
|
543
|
-
return truthpack;
|
|
544
672
|
} catch (error) {
|
|
545
|
-
return { error:
|
|
673
|
+
return { error: `Conductor not available: ${error.message}` };
|
|
546
674
|
}
|
|
547
675
|
}
|
|
548
676
|
|
|
549
|
-
async function
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
const routes = truthpack.routes?.server || [];
|
|
558
|
-
const found = routes.find(r =>
|
|
559
|
-
r.path === subject.path &&
|
|
560
|
-
(!subject.method || r.method === subject.method || r.method === '*')
|
|
561
|
-
);
|
|
562
|
-
return {
|
|
563
|
-
result: found ? 'true' : 'false',
|
|
564
|
-
evidence: found ? [{ file: found.file, line: found.line }] : [],
|
|
565
|
-
claim,
|
|
566
|
-
subject,
|
|
567
|
-
};
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
case 'env_var_exists': {
|
|
571
|
-
const declared = new Set(truthpack.env?.declared || []);
|
|
572
|
-
return {
|
|
573
|
-
result: declared.has(subject.name) ? 'true' : 'false',
|
|
574
|
-
evidence: [],
|
|
575
|
-
claim,
|
|
576
|
-
subject,
|
|
577
|
-
};
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
case 'auth_enforced': {
|
|
581
|
-
const authRoutes = truthpack.auth?.protectedRoutes || [];
|
|
582
|
-
const found = authRoutes.find(r => r.path === subject.path);
|
|
583
|
-
return {
|
|
584
|
-
result: found ? 'true' : 'unknown',
|
|
585
|
-
evidence: found ? [{ file: found.file, line: found.line }] : [],
|
|
586
|
-
claim,
|
|
587
|
-
subject,
|
|
588
|
-
};
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
case 'file_exists': {
|
|
592
|
-
try {
|
|
593
|
-
await fs.access(path.join(projectPath, subject.path));
|
|
594
|
-
return { result: 'true', evidence: [{ file: subject.path }], claim, subject };
|
|
595
|
-
} catch {
|
|
596
|
-
return { result: 'false', evidence: [], claim, subject };
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
case 'function_exists': {
|
|
601
|
-
// Simple grep-based search
|
|
602
|
-
try {
|
|
603
|
-
const result = execSync(
|
|
604
|
-
`grep -rn "function ${subject.name}\\|const ${subject.name}\\|${subject.name} =" --include="*.ts" --include="*.js" .`,
|
|
605
|
-
{ cwd: projectPath, encoding: 'utf8', timeout: 10000 }
|
|
606
|
-
);
|
|
607
|
-
const lines = result.trim().split('\n').filter(Boolean);
|
|
608
|
-
return {
|
|
609
|
-
result: lines.length > 0 ? 'true' : 'false',
|
|
610
|
-
evidence: lines.slice(0, 3).map(l => {
|
|
611
|
-
const [file, line] = l.split(':');
|
|
612
|
-
return { file, line: parseInt(line) };
|
|
613
|
-
}),
|
|
614
|
-
claim,
|
|
615
|
-
subject,
|
|
616
|
-
};
|
|
617
|
-
} catch {
|
|
618
|
-
return { result: 'false', evidence: [], claim, subject };
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
default:
|
|
623
|
-
return { result: 'unknown', error: `Unknown claim type: ${claim}` };
|
|
677
|
+
async function handleFirewallIntercept(args, tier) {
|
|
678
|
+
if (tier !== 'pro') {
|
|
679
|
+
return {
|
|
680
|
+
allowed: true,
|
|
681
|
+
mode: 'observe',
|
|
682
|
+
message: 'Firewall intercept in observe mode (FREE). Changes logged but not blocked.',
|
|
683
|
+
violations: [],
|
|
684
|
+
};
|
|
624
685
|
}
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
async function searchCode(projectPath, args) {
|
|
628
|
-
const { query, filePattern, maxResults = 20 } = args;
|
|
629
686
|
|
|
687
|
+
// Import and delegate to firewall interceptor
|
|
630
688
|
try {
|
|
631
|
-
const
|
|
632
|
-
|
|
633
|
-
`grep -rn "${query}" ${globFlag} . | head -${maxResults}`,
|
|
634
|
-
{ cwd: projectPath, encoding: 'utf8', timeout: 30000 }
|
|
635
|
-
);
|
|
636
|
-
|
|
637
|
-
const matches = result.trim().split('\n').filter(Boolean).map(line => {
|
|
638
|
-
const colonIndex = line.indexOf(':');
|
|
639
|
-
const secondColon = line.indexOf(':', colonIndex + 1);
|
|
640
|
-
return {
|
|
641
|
-
file: line.substring(0, colonIndex),
|
|
642
|
-
line: parseInt(line.substring(colonIndex + 1, secondColon)),
|
|
643
|
-
content: line.substring(secondColon + 1).trim(),
|
|
644
|
-
};
|
|
645
|
-
});
|
|
646
|
-
|
|
647
|
-
return { query, matches, total: matches.length };
|
|
689
|
+
const { interceptFileWrite } = await import('./agent-firewall-interceptor.js');
|
|
690
|
+
return await interceptFileWrite(args);
|
|
648
691
|
} catch (error) {
|
|
649
|
-
return {
|
|
692
|
+
return { error: `Firewall intercept failed: ${error.message}` };
|
|
650
693
|
}
|
|
651
694
|
}
|
|
652
695
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
`node "${path.join(projectPath, 'node_modules/.bin/vibecheck')}" report --format ${format} --json`,
|
|
657
|
-
{ cwd: projectPath, encoding: 'utf8', timeout: 60000 }
|
|
658
|
-
);
|
|
659
|
-
return JSON.parse(result);
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
async function manageAllowlist(projectPath, args) {
|
|
663
|
-
const { action, findingId, reason } = args;
|
|
664
|
-
|
|
665
|
-
switch (action) {
|
|
666
|
-
case 'list':
|
|
667
|
-
return execSync(
|
|
668
|
-
`node "${path.join(projectPath, 'node_modules/.bin/vibecheck')}" scan --allowlist list --json`,
|
|
669
|
-
{ cwd: projectPath, encoding: 'utf8', timeout: 30000 }
|
|
670
|
-
);
|
|
671
|
-
|
|
672
|
-
case 'add':
|
|
673
|
-
if (!findingId || !reason) {
|
|
674
|
-
return { error: 'findingId and reason required for add' };
|
|
675
|
-
}
|
|
676
|
-
return execSync(
|
|
677
|
-
`node "${path.join(projectPath, 'node_modules/.bin/vibecheck')}" scan --allowlist add --id "${findingId}" --reason "${reason}"`,
|
|
678
|
-
{ cwd: projectPath, encoding: 'utf8', timeout: 30000 }
|
|
679
|
-
);
|
|
680
|
-
|
|
681
|
-
case 'remove':
|
|
682
|
-
if (!findingId) {
|
|
683
|
-
return { error: 'findingId required for remove' };
|
|
684
|
-
}
|
|
685
|
-
return execSync(
|
|
686
|
-
`node "${path.join(projectPath, 'node_modules/.bin/vibecheck')}" scan --allowlist remove --id "${findingId}"`,
|
|
687
|
-
{ cwd: projectPath, encoding: 'utf8', timeout: 30000 }
|
|
688
|
-
);
|
|
689
|
-
|
|
690
|
-
case 'check':
|
|
691
|
-
if (!findingId) {
|
|
692
|
-
return { error: 'findingId required for check' };
|
|
693
|
-
}
|
|
694
|
-
return execSync(
|
|
695
|
-
`node "${path.join(projectPath, 'node_modules/.bin/vibecheck')}" scan --allowlist check --id "${findingId}" --json`,
|
|
696
|
-
{ cwd: projectPath, encoding: 'utf8', timeout: 30000 }
|
|
697
|
-
);
|
|
698
|
-
|
|
699
|
-
default:
|
|
700
|
-
return { error: `Unknown action: ${action}` };
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
async function getStatus(projectPath) {
|
|
705
|
-
const configPath = path.join(projectPath, '.vibecheck', 'config.json');
|
|
706
|
-
const truthpackPath = path.join(projectPath, '.vibecheck', 'truthpack.json');
|
|
707
|
-
const resultsPath = path.join(projectPath, '.vibecheck', 'results', 'latest.json');
|
|
708
|
-
|
|
709
|
-
const status = {
|
|
710
|
-
version: '3.2.0',
|
|
711
|
-
projectPath,
|
|
712
|
-
initialized: false,
|
|
713
|
-
lastVerdict: null,
|
|
714
|
-
findingsCount: 0,
|
|
715
|
-
truthpackAge: null,
|
|
716
|
-
};
|
|
717
|
-
|
|
718
|
-
try {
|
|
719
|
-
await fs.access(configPath);
|
|
720
|
-
status.initialized = true;
|
|
721
|
-
} catch {}
|
|
722
|
-
|
|
723
|
-
try {
|
|
724
|
-
const stats = await fs.stat(truthpackPath);
|
|
725
|
-
status.truthpackAge = stats.mtime.toISOString();
|
|
726
|
-
} catch {}
|
|
727
|
-
|
|
728
|
-
try {
|
|
729
|
-
const results = JSON.parse(await fs.readFile(resultsPath, 'utf8'));
|
|
730
|
-
status.lastVerdict = results.verdict;
|
|
731
|
-
status.findingsCount = results.findings?.length || 0;
|
|
732
|
-
} catch {}
|
|
733
|
-
|
|
734
|
-
return status;
|
|
735
|
-
}
|
|
696
|
+
// =============================================================================
|
|
697
|
+
// EXPORTS
|
|
698
|
+
// =============================================================================
|
|
736
699
|
|
|
737
|
-
export { TOOL_TIERS, checkTierAccess };
|
|
700
|
+
export { TOOL_TIERS, checkTierAccess, isPro };
|
|
738
701
|
|
|
739
702
|
export default {
|
|
740
703
|
MCP_TOOLS_V3,
|
|
741
704
|
handleToolV3,
|
|
742
705
|
TOOL_TIERS,
|
|
743
|
-
checkTierAccess,
|
|
744
706
|
};
|