@vibecheckai/cli 3.9.0 → 4.0.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/README.md +1 -1
- package/bin/runners/context/generators/cursor-enhanced.js +99 -13
- package/bin/runners/lib/unified-cli-output.js +16 -0
- package/bin/runners/runCI.js +353 -0
- package/bin/runners/runCheckpoint.js +2 -2
- package/mcp-server/.eslintrc.json +24 -0
- package/mcp-server/README.md +425 -135
- package/mcp-server/SPEC.md +583 -0
- package/mcp-server/configs/README.md +172 -0
- package/mcp-server/configs/claude-desktop-pro.json +31 -0
- package/mcp-server/configs/claude-desktop-with-workspace.json +25 -0
- package/mcp-server/configs/claude-desktop.json +19 -0
- package/mcp-server/configs/cursor-mcp.json +21 -0
- package/mcp-server/configs/windsurf-mcp.json +17 -0
- package/mcp-server/mcp-config.example.json +9 -0
- package/mcp-server/package.json +49 -34
- package/mcp-server/src/cli.ts +185 -0
- package/mcp-server/src/index.ts +85 -0
- package/mcp-server/src/server.ts +1933 -0
- package/mcp-server/src/services/cache-service.ts +466 -0
- package/mcp-server/src/services/cli-service.ts +345 -0
- package/mcp-server/src/services/context-manager.ts +717 -0
- package/mcp-server/src/services/firewall-service.ts +662 -0
- package/mcp-server/src/services/git-service.ts +671 -0
- package/mcp-server/src/services/index.ts +52 -0
- package/mcp-server/src/services/prompt-builder-service.ts +1031 -0
- package/mcp-server/src/services/session-service.ts +550 -0
- package/mcp-server/src/services/tier-service.ts +470 -0
- package/mcp-server/src/types.ts +351 -0
- package/mcp-server/tsconfig.json +16 -27
- package/package.json +6 -6
- package/mcp-server/.guardrail/audit/audit.log.jsonl +0 -2
- package/mcp-server/.specs/architecture.mdc +0 -90
- package/mcp-server/.specs/security.mdc +0 -30
- package/mcp-server/HARDENING_SUMMARY.md +0 -299
- package/mcp-server/agent-checkpoint.js +0 -364
- package/mcp-server/agent-firewall-interceptor.js +0 -500
- package/mcp-server/architect-tools.js +0 -707
- package/mcp-server/audit-mcp.js +0 -206
- package/mcp-server/authority-tools.js +0 -569
- package/mcp-server/codebase-architect-tools.js +0 -838
- package/mcp-server/conductor/conflict-resolver.js +0 -588
- package/mcp-server/conductor/execution-planner.js +0 -544
- package/mcp-server/conductor/index.js +0 -377
- package/mcp-server/conductor/lock-manager.js +0 -615
- package/mcp-server/conductor/request-queue.js +0 -550
- package/mcp-server/conductor/session-manager.js +0 -500
- package/mcp-server/conductor/tools.js +0 -510
- package/mcp-server/consolidated-tools.js +0 -1170
- package/mcp-server/deprecation-middleware.js +0 -282
- package/mcp-server/handlers/index.ts +0 -15
- package/mcp-server/handlers/tool-handler.ts +0 -593
- package/mcp-server/hygiene-tools.js +0 -428
- package/mcp-server/index-v1.js +0 -698
- package/mcp-server/index.js +0 -2940
- package/mcp-server/intelligence-tools.js +0 -664
- package/mcp-server/intent-drift-tools.js +0 -873
- package/mcp-server/intent-firewall-interceptor.js +0 -529
- package/mcp-server/lib/api-client.cjs +0 -13
- package/mcp-server/lib/cache-wrapper.cjs +0 -383
- package/mcp-server/lib/error-envelope.js +0 -138
- package/mcp-server/lib/executor.ts +0 -499
- package/mcp-server/lib/index.ts +0 -29
- package/mcp-server/lib/logger.cjs +0 -30
- package/mcp-server/lib/rate-limiter.js +0 -166
- package/mcp-server/lib/sandbox.test.ts +0 -519
- package/mcp-server/lib/sandbox.ts +0 -395
- package/mcp-server/lib/types.ts +0 -267
- package/mcp-server/logger.js +0 -173
- package/mcp-server/manifest.json +0 -473
- package/mcp-server/mdc-generator.js +0 -298
- package/mcp-server/premium-tools.js +0 -1275
- package/mcp-server/proof-tools.js +0 -571
- package/mcp-server/registry/tool-registry.js +0 -586
- package/mcp-server/registry/tools.json +0 -619
- package/mcp-server/registry.test.ts +0 -340
- package/mcp-server/test-mcp.js +0 -108
- package/mcp-server/test-tools.js +0 -36
- package/mcp-server/tests/tier-gating.test.js +0 -297
- package/mcp-server/tier-auth.js +0 -767
- package/mcp-server/tools/index.js +0 -72
- package/mcp-server/tools-reorganized.ts +0 -244
- package/mcp-server/tools-v3.js +0 -1004
- package/mcp-server/truth-context.js +0 -622
- package/mcp-server/truth-firewall-tools.js +0 -2183
- package/mcp-server/vibecheck-2.0-tools.js +0 -761
- package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
- package/mcp-server/vibecheck-tools.js +0 -1075
|
@@ -1,529 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Intent-Aware Firewall Interceptor - MCP Tool v3.0
|
|
3
|
-
*
|
|
4
|
-
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
-
* AGENT FIREWALL™ v3.0 - UNIFIED ENFORCEMENT GATEWAY
|
|
6
|
-
* ═══════════════════════════════════════════════════════════════════════════════
|
|
7
|
-
*
|
|
8
|
-
* SEAMLESS UX: When no intent is declared, changes are OBSERVED (not blocked).
|
|
9
|
-
* Changes are logged to the session collector for later approval.
|
|
10
|
-
*
|
|
11
|
-
* Now uses the unified EnforcementGateway for all operations:
|
|
12
|
-
* - Real-time interception with explainable blocks
|
|
13
|
-
* - Signed verdicts for audit trail
|
|
14
|
-
* - Fix guidance for each violation
|
|
15
|
-
*
|
|
16
|
-
* Modes:
|
|
17
|
-
* - No intent → OBSERVE: Log changes, allow to proceed, prompt for intent
|
|
18
|
-
* - Intent exists → ENFORCE: Check alignment, block if not aligned
|
|
19
|
-
*
|
|
20
|
-
* @module intent-firewall-interceptor
|
|
21
|
-
* @version 3.0.0
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
import path from "path";
|
|
25
|
-
import fs from "fs";
|
|
26
|
-
import { createRequire } from "module";
|
|
27
|
-
|
|
28
|
-
// Import tier auth for secure tier validation
|
|
29
|
-
import { getMcpToolAccess } from "./tier-auth.js";
|
|
30
|
-
|
|
31
|
-
const require = createRequire(import.meta.url);
|
|
32
|
-
|
|
33
|
-
// Import v3 unified enforcement gateway
|
|
34
|
-
let createGateway, IntentStore, checkAlignment, MODE, VERDICT, SessionCollector;
|
|
35
|
-
let createOrchestrator, ModeConfig; // Legacy compatibility
|
|
36
|
-
try {
|
|
37
|
-
const agentFirewall = require("../bin/runners/lib/agent-firewall");
|
|
38
|
-
createGateway = agentFirewall.createGateway;
|
|
39
|
-
IntentStore = agentFirewall.IntentStore;
|
|
40
|
-
checkAlignment = agentFirewall.checkAlignment;
|
|
41
|
-
MODE = agentFirewall.MODE;
|
|
42
|
-
VERDICT = agentFirewall.VERDICT;
|
|
43
|
-
SessionCollector = agentFirewall.SessionCollector;
|
|
44
|
-
|
|
45
|
-
// Legacy compatibility
|
|
46
|
-
createOrchestrator = agentFirewall.createOrchestrator;
|
|
47
|
-
ModeConfig = agentFirewall.ModeConfig;
|
|
48
|
-
} catch (err) {
|
|
49
|
-
console.warn(`[Intent Firewall] v3 modules not available: ${err.message}`);
|
|
50
|
-
|
|
51
|
-
// Fallback to v2 imports
|
|
52
|
-
try {
|
|
53
|
-
const enforcement = require("../bin/runners/lib/agent-firewall/enforcement");
|
|
54
|
-
createOrchestrator = enforcement.createOrchestrator;
|
|
55
|
-
createGateway = enforcement.createGateway;
|
|
56
|
-
MODE = enforcement.MODE;
|
|
57
|
-
VERDICT = enforcement.VERDICT;
|
|
58
|
-
ModeConfig = enforcement.ModeConfig;
|
|
59
|
-
|
|
60
|
-
const intent = require("../bin/runners/lib/agent-firewall/intent");
|
|
61
|
-
IntentStore = intent.IntentStore;
|
|
62
|
-
checkAlignment = intent.checkAlignment;
|
|
63
|
-
|
|
64
|
-
const session = require("../bin/runners/lib/agent-firewall/session");
|
|
65
|
-
SessionCollector = session.SessionCollector;
|
|
66
|
-
} catch (err2) {
|
|
67
|
-
console.warn(`[Intent Firewall] Fallback failed: ${err2.message}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* MCP Tool Definition for Intent-Aware Interception
|
|
73
|
-
*/
|
|
74
|
-
const INTENT_FIREWALL_TOOL = {
|
|
75
|
-
name: "vibecheck_intent_firewall_intercept",
|
|
76
|
-
description: `🛡️ Intent-Aware Agent Firewall v2.1 - SEAMLESS enforcement.
|
|
77
|
-
|
|
78
|
-
Intercepts AI code changes with seamless UX:
|
|
79
|
-
- No intent declared? → OBSERVE mode (changes logged, allowed to proceed)
|
|
80
|
-
- Intent declared? → ENFORCE mode (check alignment, block if not aligned)
|
|
81
|
-
|
|
82
|
-
After a vibe session, run: vibecheck approve
|
|
83
|
-
This reviews logged changes and creates intent retroactively.
|
|
84
|
-
|
|
85
|
-
Returns: { mode, decision, logged, intent_prompt }`,
|
|
86
|
-
inputSchema: {
|
|
87
|
-
type: "object",
|
|
88
|
-
required: ["agentId", "filePath", "content"],
|
|
89
|
-
properties: {
|
|
90
|
-
agentId: {
|
|
91
|
-
type: "string",
|
|
92
|
-
description: "Agent identifier (e.g., 'cursor', 'windsurf', 'copilot')"
|
|
93
|
-
},
|
|
94
|
-
filePath: {
|
|
95
|
-
type: "string",
|
|
96
|
-
description: "File path relative to project root"
|
|
97
|
-
},
|
|
98
|
-
content: {
|
|
99
|
-
type: "string",
|
|
100
|
-
description: "New file content"
|
|
101
|
-
},
|
|
102
|
-
oldContent: {
|
|
103
|
-
type: "string",
|
|
104
|
-
description: "Old file content (optional, for diff generation)"
|
|
105
|
-
},
|
|
106
|
-
intent: {
|
|
107
|
-
type: "string",
|
|
108
|
-
description: "Agent's stated intent for this change (NOT user intent - user intent must be declared via CLI)"
|
|
109
|
-
},
|
|
110
|
-
projectRoot: {
|
|
111
|
-
type: "string",
|
|
112
|
-
default: ".",
|
|
113
|
-
description: "Project root directory"
|
|
114
|
-
},
|
|
115
|
-
apiKey: {
|
|
116
|
-
type: "string",
|
|
117
|
-
description: "API key for authentication"
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Handle MCP tool call for intent-aware interception
|
|
125
|
-
* Uses the unified EnforcementGateway for all operations
|
|
126
|
-
*
|
|
127
|
-
* @param {string} name - Tool name (unused)
|
|
128
|
-
* @param {object} args - Tool arguments
|
|
129
|
-
* @returns {object} MCP tool response
|
|
130
|
-
*/
|
|
131
|
-
async function handleIntentFirewallIntercept(name, args) {
|
|
132
|
-
const projectRoot = path.resolve(args.projectRoot || ".");
|
|
133
|
-
const agentId = args.agentId || "unknown";
|
|
134
|
-
const filePath = args.filePath;
|
|
135
|
-
const content = args.content;
|
|
136
|
-
const oldContent = args.oldContent || null;
|
|
137
|
-
const agentIntent = args.intent || "No intent provided";
|
|
138
|
-
|
|
139
|
-
// Validate modules are available
|
|
140
|
-
if (!createGateway && !IntentStore) {
|
|
141
|
-
return {
|
|
142
|
-
content: [{
|
|
143
|
-
type: "text",
|
|
144
|
-
text: `⚠️ Intent Firewall modules not available. Change allowed but not tracked.`
|
|
145
|
-
}]
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Validate file path is within project root
|
|
150
|
-
const fileAbs = path.resolve(projectRoot, filePath);
|
|
151
|
-
if (!fileAbs.startsWith(projectRoot + path.sep) && fileAbs !== projectRoot) {
|
|
152
|
-
return {
|
|
153
|
-
content: [{
|
|
154
|
-
type: "text",
|
|
155
|
-
text: `❌ BLOCKED: File path outside project root: ${filePath}`
|
|
156
|
-
}],
|
|
157
|
-
isError: true
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
try {
|
|
162
|
-
// Create enforcement gateway
|
|
163
|
-
const gateway = createGateway ? createGateway(projectRoot) : null;
|
|
164
|
-
|
|
165
|
-
// Build raw change for gateway
|
|
166
|
-
const rawChange = {
|
|
167
|
-
type: oldContent ? "file_write" : "file_create",
|
|
168
|
-
path: filePath,
|
|
169
|
-
content,
|
|
170
|
-
diff: oldContent ? {
|
|
171
|
-
before: oldContent,
|
|
172
|
-
after: content,
|
|
173
|
-
} : null,
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
// Use gateway if available
|
|
177
|
-
if (gateway) {
|
|
178
|
-
const verdict = await gateway.intercept(rawChange, {
|
|
179
|
-
agentId,
|
|
180
|
-
interceptionPoint: "mcp_tool",
|
|
181
|
-
toolName: "vibecheck_intent_firewall_intercept",
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
// Handle OBSERVE mode (WOULD_PASS/WOULD_BLOCK)
|
|
185
|
-
if (verdict.decision === "WOULD_PASS" || verdict.decision === "WOULD_BLOCK") {
|
|
186
|
-
const wouldBlock = verdict.decision === "WOULD_BLOCK";
|
|
187
|
-
|
|
188
|
-
return {
|
|
189
|
-
content: [{
|
|
190
|
-
type: "text",
|
|
191
|
-
text: `📋 OBSERVE MODE - Change ${wouldBlock ? "would be blocked" : "logged"}
|
|
192
|
-
|
|
193
|
-
File: ${filePath}
|
|
194
|
-
Agent: ${agentId}
|
|
195
|
-
✓ Logged to session for later review
|
|
196
|
-
${wouldBlock ? `\n⚠️ Would block: ${verdict.summary}` : ""}
|
|
197
|
-
|
|
198
|
-
═══════════════════════════════════════════════════════════════
|
|
199
|
-
No intent declared - running in OBSERVE mode.
|
|
200
|
-
Changes are allowed but logged for review.
|
|
201
|
-
|
|
202
|
-
After your vibe session, run:
|
|
203
|
-
vibecheck approve
|
|
204
|
-
|
|
205
|
-
Or declare intent now for enforcement:
|
|
206
|
-
vibecheck i "${agentIntent || "your intent"}"
|
|
207
|
-
═══════════════════════════════════════════════════════════════
|
|
208
|
-
|
|
209
|
-
💡 TIP: Quick intent declaration:
|
|
210
|
-
vibecheck i "fix login bug"
|
|
211
|
-
|
|
212
|
-
This auto-infers constraints from your git context.`
|
|
213
|
-
}]
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Handle BLOCK
|
|
218
|
-
if (verdict.decision === "BLOCK") {
|
|
219
|
-
// Format violations with fix guidance
|
|
220
|
-
const violationLines = verdict.violations.map(v => {
|
|
221
|
-
let line = `❌ [${v.code}] ${v.message}`;
|
|
222
|
-
if (v.evidence?.file) line += `\n File: ${v.evidence.file}:${v.evidence.line || ''}`;
|
|
223
|
-
if (v.evidence?.snippet) line += `\n Snippet: ${v.evidence.snippet.substring(0, 60)}...`;
|
|
224
|
-
if (v.fix_hint) line += `\n Fix: ${v.fix_hint}`;
|
|
225
|
-
return line;
|
|
226
|
-
}).join("\n\n");
|
|
227
|
-
|
|
228
|
-
// Format fix guidance
|
|
229
|
-
const fixCommands = (verdict.fix_guidance || [])
|
|
230
|
-
.filter(f => f.command)
|
|
231
|
-
.map(f => ` ${f.command}`)
|
|
232
|
-
.join("\n");
|
|
233
|
-
|
|
234
|
-
return {
|
|
235
|
-
content: [{
|
|
236
|
-
type: "text",
|
|
237
|
-
text: `═══════════════════════════════════════════════════════════════════════════════
|
|
238
|
-
BLOCKED BY AGENT FIREWALL
|
|
239
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
240
|
-
|
|
241
|
-
${violationLines}
|
|
242
|
-
|
|
243
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
244
|
-
Verdict: ${verdict.decision}
|
|
245
|
-
Violations: ${verdict.violations.length}
|
|
246
|
-
Intent Hash: ${verdict.intent_hash?.slice(0, 16) || "NONE"}...
|
|
247
|
-
Verdict Hash: ${verdict.verdict_hash?.slice(0, 16)}...
|
|
248
|
-
|
|
249
|
-
To proceed:
|
|
250
|
-
${fixCommands || " Review and fix the violations above"}
|
|
251
|
-
═══════════════════════════════════════════════════════════════════════════════`
|
|
252
|
-
}],
|
|
253
|
-
isError: true
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Handle PASS
|
|
258
|
-
const intentStore = new IntentStore(projectRoot);
|
|
259
|
-
const userIntent = intentStore.getCurrent({ allowMissing: true });
|
|
260
|
-
|
|
261
|
-
return {
|
|
262
|
-
content: [{
|
|
263
|
-
type: "text",
|
|
264
|
-
text: `✅ ALLOWED BY AGENT FIREWALL
|
|
265
|
-
|
|
266
|
-
Verdict: ${verdict.decision}
|
|
267
|
-
File: ${filePath}
|
|
268
|
-
|
|
269
|
-
Intent Aligned:
|
|
270
|
-
"${userIntent?.summary || "No intent"}"
|
|
271
|
-
|
|
272
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
273
|
-
Intent Hash: ${verdict.intent_hash?.slice(0, 16) || "NONE"}...
|
|
274
|
-
Verdict Hash: ${verdict.verdict_hash?.slice(0, 16)}...
|
|
275
|
-
Proofs: ${verdict.proofs?.length || 0} verified
|
|
276
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
277
|
-
|
|
278
|
-
Change may proceed.`
|
|
279
|
-
}]
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// Fallback to legacy orchestrator if gateway not available
|
|
284
|
-
const intentStore = new IntentStore(projectRoot);
|
|
285
|
-
const userIntent = intentStore.getCurrent({ allowMissing: true });
|
|
286
|
-
const hasUserIntent = intentStore.hasIntent();
|
|
287
|
-
const isBlockingIntent = userIntent?.summary?.includes("NO INTENT DECLARED");
|
|
288
|
-
|
|
289
|
-
// OBSERVE mode fallback
|
|
290
|
-
if (!hasUserIntent || isBlockingIntent) {
|
|
291
|
-
if (SessionCollector) {
|
|
292
|
-
try {
|
|
293
|
-
const collector = new SessionCollector(projectRoot);
|
|
294
|
-
collector.record({
|
|
295
|
-
type: oldContent ? "file_modify" : "file_create",
|
|
296
|
-
path: filePath,
|
|
297
|
-
agent_id: agentId,
|
|
298
|
-
});
|
|
299
|
-
} catch {}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
return {
|
|
303
|
-
content: [{
|
|
304
|
-
type: "text",
|
|
305
|
-
text: `📋 OBSERVE MODE - Change logged
|
|
306
|
-
|
|
307
|
-
File: ${filePath}
|
|
308
|
-
Agent: ${agentId}
|
|
309
|
-
|
|
310
|
-
═══════════════════════════════════════════════════════════════
|
|
311
|
-
No intent declared. Run: vibecheck approve after session.
|
|
312
|
-
═══════════════════════════════════════════════════════════════`
|
|
313
|
-
}]
|
|
314
|
-
};
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Legacy alignment check
|
|
318
|
-
const changeEvent = {
|
|
319
|
-
type: oldContent ? "file_write" : "file_create",
|
|
320
|
-
location: filePath,
|
|
321
|
-
diff: oldContent ? { before: oldContent, after: content } : null,
|
|
322
|
-
content,
|
|
323
|
-
domain: classifyDomain(filePath),
|
|
324
|
-
claims: [],
|
|
325
|
-
timestamp: new Date().toISOString(),
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
const alignmentResult = checkAlignment(userIntent, changeEvent);
|
|
329
|
-
|
|
330
|
-
if (!alignmentResult.aligned) {
|
|
331
|
-
const violations = alignmentResult.violations.map(v =>
|
|
332
|
-
`- [${v.code}] ${v.message}\n Resource: ${v.resource}`
|
|
333
|
-
).join("\n\n");
|
|
334
|
-
|
|
335
|
-
return {
|
|
336
|
-
content: [{
|
|
337
|
-
type: "text",
|
|
338
|
-
text: `❌ BLOCKED BY AGENT FIREWALL
|
|
339
|
-
|
|
340
|
-
${violations}
|
|
341
|
-
|
|
342
|
-
Intent: "${userIntent.summary}"
|
|
343
|
-
Intent Hash: ${userIntent.hash?.slice(0, 16)}...`
|
|
344
|
-
}],
|
|
345
|
-
isError: true
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
return {
|
|
350
|
-
content: [{
|
|
351
|
-
type: "text",
|
|
352
|
-
text: `✅ ALLOWED - Intent aligned: "${userIntent.summary}"`
|
|
353
|
-
}]
|
|
354
|
-
};
|
|
355
|
-
|
|
356
|
-
} catch (error) {
|
|
357
|
-
return {
|
|
358
|
-
content: [{
|
|
359
|
-
type: "text",
|
|
360
|
-
text: `❌ BLOCKED: Enforcement error: ${error.message}\n\n${error.stack}`
|
|
361
|
-
}],
|
|
362
|
-
isError: true
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Classify file domain
|
|
369
|
-
* @param {string} filePath - File path
|
|
370
|
-
* @returns {string} Domain
|
|
371
|
-
*/
|
|
372
|
-
function classifyDomain(filePath) {
|
|
373
|
-
if (!filePath) return "general";
|
|
374
|
-
const s = filePath.toLowerCase();
|
|
375
|
-
if (s.includes("auth")) return "auth";
|
|
376
|
-
if (s.includes("stripe") || s.includes("payment")) return "payments";
|
|
377
|
-
if (s.includes("routes") || s.includes("router") || s.includes("api")) return "routes";
|
|
378
|
-
if (s.includes("schema") || s.includes("contract")) return "contracts";
|
|
379
|
-
if (s.includes("ui") || s.includes("components") || s.includes("pages")) return "ui";
|
|
380
|
-
if (s.includes("database") || s.includes("prisma") || s.includes("migration")) return "database";
|
|
381
|
-
return "general";
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* MCP Tool for getting current intent status
|
|
386
|
-
*/
|
|
387
|
-
const INTENT_STATUS_TOOL = {
|
|
388
|
-
name: "vibecheck_intent_status",
|
|
389
|
-
description: `📋 Get current firewall status and pending changes.
|
|
390
|
-
|
|
391
|
-
Shows:
|
|
392
|
-
- Current mode (OBSERVE/ENFORCE)
|
|
393
|
-
- Intent status (if declared)
|
|
394
|
-
- Pending session changes (if in OBSERVE mode)
|
|
395
|
-
|
|
396
|
-
Returns: { mode, hasIntent, pendingChanges, summary }`,
|
|
397
|
-
inputSchema: {
|
|
398
|
-
type: "object",
|
|
399
|
-
properties: {
|
|
400
|
-
projectRoot: {
|
|
401
|
-
type: "string",
|
|
402
|
-
default: ".",
|
|
403
|
-
description: "Project root directory"
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* Handle intent status tool call
|
|
411
|
-
*/
|
|
412
|
-
async function handleIntentStatus(name, args) {
|
|
413
|
-
const projectRoot = path.resolve(args.projectRoot || ".");
|
|
414
|
-
|
|
415
|
-
if (!IntentStore) {
|
|
416
|
-
return {
|
|
417
|
-
content: [{
|
|
418
|
-
type: "text",
|
|
419
|
-
text: `⚠️ Intent system not available`
|
|
420
|
-
}]
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
try {
|
|
425
|
-
const intentStore = new IntentStore(projectRoot);
|
|
426
|
-
const intent = intentStore.getCurrent({ allowMissing: true });
|
|
427
|
-
const hasIntent = intentStore.hasIntent();
|
|
428
|
-
const isBlocking = intent?.summary?.includes("NO INTENT DECLARED");
|
|
429
|
-
|
|
430
|
-
// Get session info if available
|
|
431
|
-
let sessionInfo = null;
|
|
432
|
-
if (SessionCollector) {
|
|
433
|
-
try {
|
|
434
|
-
const collector = new SessionCollector(projectRoot);
|
|
435
|
-
if (collector.hasPending()) {
|
|
436
|
-
sessionInfo = collector.getSummary();
|
|
437
|
-
}
|
|
438
|
-
} catch {
|
|
439
|
-
// Ignore session errors
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
if (!hasIntent || isBlocking) {
|
|
444
|
-
// OBSERVE MODE - show session info
|
|
445
|
-
let response = `📋 OBSERVE MODE (no intent declared)\n\n`;
|
|
446
|
-
response += `Changes are allowed and logged for later review.\n\n`;
|
|
447
|
-
|
|
448
|
-
if (sessionInfo) {
|
|
449
|
-
response += `═══════════════════════════════════════════════════════════════\n`;
|
|
450
|
-
response += `SESSION CHANGES\n`;
|
|
451
|
-
response += ` Files touched: ${sessionInfo.files_touched}\n`;
|
|
452
|
-
response += ` Total changes: ${sessionInfo.total_changes}\n`;
|
|
453
|
-
response += ` Duration: ${sessionInfo.duration_minutes} minutes\n`;
|
|
454
|
-
response += ` Domains: ${sessionInfo.domains.join(", ") || "(none)"}\n`;
|
|
455
|
-
response += `═══════════════════════════════════════════════════════════════\n\n`;
|
|
456
|
-
response += `When done, run: vibecheck approve\n`;
|
|
457
|
-
} else {
|
|
458
|
-
response += `No changes logged yet in this session.\n`;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
response += `\n💡 Quick intent: vibecheck i "your intent"\n`;
|
|
462
|
-
|
|
463
|
-
return {
|
|
464
|
-
content: [{
|
|
465
|
-
type: "text",
|
|
466
|
-
text: response
|
|
467
|
-
}]
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
// ENFORCE MODE - show intent
|
|
472
|
-
let response = `✅ ENFORCE MODE (intent active)\n\n`;
|
|
473
|
-
response += `Summary: ${intent.summary}\n\n`;
|
|
474
|
-
|
|
475
|
-
if (intent.constraints && intent.constraints.length > 0) {
|
|
476
|
-
response += `Constraints:\n`;
|
|
477
|
-
for (const c of intent.constraints) {
|
|
478
|
-
response += ` - ${c}\n`;
|
|
479
|
-
}
|
|
480
|
-
response += "\n";
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
if (intent.allowed_changes && intent.allowed_changes.length > 0) {
|
|
484
|
-
response += `Allowed Changes:\n`;
|
|
485
|
-
for (const ac of intent.allowed_changes) {
|
|
486
|
-
response += ` - [${ac.type}] ${ac.target || ac.pattern}\n`;
|
|
487
|
-
}
|
|
488
|
-
response += "\n";
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
if (intent.scope) {
|
|
492
|
-
response += `Scope:\n`;
|
|
493
|
-
if (intent.scope.directories) {
|
|
494
|
-
response += ` Directories: ${intent.scope.directories.join(", ")}\n`;
|
|
495
|
-
}
|
|
496
|
-
if (intent.scope.domains) {
|
|
497
|
-
response += ` Domains: ${intent.scope.domains.join(", ")}\n`;
|
|
498
|
-
}
|
|
499
|
-
response += "\n";
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
response += `Hash: ${intent.hash?.slice(0, 16)}...\n`;
|
|
503
|
-
response += `Version: ${intent.version || 1}\n`;
|
|
504
|
-
response += `Created: ${intent.created_at}`;
|
|
505
|
-
|
|
506
|
-
return {
|
|
507
|
-
content: [{
|
|
508
|
-
type: "text",
|
|
509
|
-
text: response
|
|
510
|
-
}]
|
|
511
|
-
};
|
|
512
|
-
|
|
513
|
-
} catch (error) {
|
|
514
|
-
return {
|
|
515
|
-
content: [{
|
|
516
|
-
type: "text",
|
|
517
|
-
text: `❌ Error: ${error.message}`
|
|
518
|
-
}],
|
|
519
|
-
isError: true
|
|
520
|
-
};
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
export {
|
|
525
|
-
INTENT_FIREWALL_TOOL,
|
|
526
|
-
handleIntentFirewallIntercept,
|
|
527
|
-
INTENT_STATUS_TOOL,
|
|
528
|
-
handleIntentStatus
|
|
529
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* API Client - MCP Server Re-export
|
|
3
|
-
*
|
|
4
|
-
* This module re-exports from the canonical bin/runners/lib/api-client.js
|
|
5
|
-
* DO NOT add implementation here.
|
|
6
|
-
*
|
|
7
|
-
* @see ../../../bin/runners/lib/api-client.js for the canonical implementation
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
"use strict";
|
|
11
|
-
|
|
12
|
-
// Re-export everything from the canonical api-client
|
|
13
|
-
module.exports = require('../../bin/runners/lib/api-client.js');
|