@vibecheckai/cli 3.9.1 → 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.
Files changed (85) hide show
  1. package/README.md +1 -1
  2. package/bin/runners/context/generators/cursor-enhanced.js +99 -13
  3. package/mcp-server/.eslintrc.json +24 -0
  4. package/mcp-server/README.md +425 -135
  5. package/mcp-server/SPEC.md +583 -0
  6. package/mcp-server/configs/README.md +172 -0
  7. package/mcp-server/configs/claude-desktop-pro.json +31 -0
  8. package/mcp-server/configs/claude-desktop-with-workspace.json +25 -0
  9. package/mcp-server/configs/claude-desktop.json +19 -0
  10. package/mcp-server/configs/cursor-mcp.json +21 -0
  11. package/mcp-server/configs/windsurf-mcp.json +17 -0
  12. package/mcp-server/mcp-config.example.json +9 -0
  13. package/mcp-server/package.json +49 -34
  14. package/mcp-server/src/cli.ts +185 -0
  15. package/mcp-server/src/index.ts +85 -0
  16. package/mcp-server/src/server.ts +1933 -0
  17. package/mcp-server/src/services/cache-service.ts +466 -0
  18. package/mcp-server/src/services/cli-service.ts +345 -0
  19. package/mcp-server/src/services/context-manager.ts +717 -0
  20. package/mcp-server/src/services/firewall-service.ts +662 -0
  21. package/mcp-server/src/services/git-service.ts +671 -0
  22. package/mcp-server/src/services/index.ts +52 -0
  23. package/mcp-server/src/services/prompt-builder-service.ts +1031 -0
  24. package/mcp-server/src/services/session-service.ts +550 -0
  25. package/mcp-server/src/services/tier-service.ts +470 -0
  26. package/mcp-server/src/types.ts +351 -0
  27. package/mcp-server/tsconfig.json +16 -27
  28. package/package.json +6 -6
  29. package/mcp-server/.guardrail/audit/audit.log.jsonl +0 -2
  30. package/mcp-server/.specs/architecture.mdc +0 -90
  31. package/mcp-server/.specs/security.mdc +0 -30
  32. package/mcp-server/HARDENING_SUMMARY.md +0 -299
  33. package/mcp-server/agent-checkpoint.js +0 -364
  34. package/mcp-server/agent-firewall-interceptor.js +0 -500
  35. package/mcp-server/architect-tools.js +0 -707
  36. package/mcp-server/audit-mcp.js +0 -206
  37. package/mcp-server/authority-tools.js +0 -569
  38. package/mcp-server/codebase-architect-tools.js +0 -838
  39. package/mcp-server/conductor/conflict-resolver.js +0 -588
  40. package/mcp-server/conductor/execution-planner.js +0 -544
  41. package/mcp-server/conductor/index.js +0 -377
  42. package/mcp-server/conductor/lock-manager.js +0 -615
  43. package/mcp-server/conductor/request-queue.js +0 -550
  44. package/mcp-server/conductor/session-manager.js +0 -500
  45. package/mcp-server/conductor/tools.js +0 -510
  46. package/mcp-server/consolidated-tools.js +0 -1170
  47. package/mcp-server/deprecation-middleware.js +0 -282
  48. package/mcp-server/handlers/index.ts +0 -15
  49. package/mcp-server/handlers/tool-handler.ts +0 -593
  50. package/mcp-server/hygiene-tools.js +0 -428
  51. package/mcp-server/index-v1.js +0 -698
  52. package/mcp-server/index.js +0 -2940
  53. package/mcp-server/intelligence-tools.js +0 -664
  54. package/mcp-server/intent-drift-tools.js +0 -873
  55. package/mcp-server/intent-firewall-interceptor.js +0 -529
  56. package/mcp-server/lib/api-client.cjs +0 -13
  57. package/mcp-server/lib/cache-wrapper.cjs +0 -383
  58. package/mcp-server/lib/error-envelope.js +0 -138
  59. package/mcp-server/lib/executor.ts +0 -499
  60. package/mcp-server/lib/index.ts +0 -29
  61. package/mcp-server/lib/logger.cjs +0 -30
  62. package/mcp-server/lib/rate-limiter.js +0 -166
  63. package/mcp-server/lib/sandbox.test.ts +0 -519
  64. package/mcp-server/lib/sandbox.ts +0 -395
  65. package/mcp-server/lib/types.ts +0 -267
  66. package/mcp-server/logger.js +0 -173
  67. package/mcp-server/manifest.json +0 -473
  68. package/mcp-server/mdc-generator.js +0 -298
  69. package/mcp-server/premium-tools.js +0 -1275
  70. package/mcp-server/proof-tools.js +0 -571
  71. package/mcp-server/registry/tool-registry.js +0 -586
  72. package/mcp-server/registry/tools.json +0 -619
  73. package/mcp-server/registry.test.ts +0 -340
  74. package/mcp-server/test-mcp.js +0 -108
  75. package/mcp-server/test-tools.js +0 -36
  76. package/mcp-server/tests/tier-gating.test.js +0 -297
  77. package/mcp-server/tier-auth.js +0 -767
  78. package/mcp-server/tools/index.js +0 -72
  79. package/mcp-server/tools-reorganized.ts +0 -244
  80. package/mcp-server/tools-v3.js +0 -1004
  81. package/mcp-server/truth-context.js +0 -622
  82. package/mcp-server/truth-firewall-tools.js +0 -2183
  83. package/mcp-server/vibecheck-2.0-tools.js +0 -761
  84. package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
  85. 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');