@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,1004 +0,0 @@
1
- /**
2
- * vibecheck MCP Tools v3 - Consolidated Tools
3
- *
4
- * ═══════════════════════════════════════════════════════════════════════════
5
- * TIER MODEL - Aligned with CLI entitlements-v2.js
6
- * ═══════════════════════════════════════════════════════════════════════════
7
- *
8
- * Simple 2-tier model:
9
- * - FREE ($0): Inspect & Observe (10 tools)
10
- * - PRO ($49/mo): Fix, Prove & Enforce (18 tools)
11
- *
12
- * PRO includes:
13
- * - Authority System (verdicts, approvals)
14
- * - Agent Conductor (multi-agent coordination)
15
- * - Agent Firewall (enforce mode)
16
- */
17
-
18
- import fs from 'fs/promises';
19
- import path from 'path';
20
- import { execSync } from 'child_process';
21
- import { createRequire } from 'module';
22
-
23
- // Import cache wrapper for persistent caching
24
- const require = createRequire(import.meta.url);
25
- const { executeCachedCliCommand, ToolCache } = require('./lib/cache-wrapper.cjs');
26
-
27
- // Import tier auth for consistent tier checking
28
- import {
29
- FREE_TOOLS,
30
- PRO_TOOLS,
31
- OPTION_GATES,
32
- getMcpToolAccess,
33
- notEntitledError,
34
- optionNotEntitledError,
35
- ERROR_CODES,
36
- isPro as tierAuthIsPro,
37
- getDevModeOverride,
38
- } from './tier-auth.js';
39
-
40
- /**
41
- * Check if developer mode bypass is allowed.
42
- * SECURITY: VIBECHECK_DEV_PRO is ONLY allowed in non-production environments.
43
- * Uses centralized function from tier-auth.js
44
- */
45
- function isDevProBypassAllowed() {
46
- return getDevModeOverride().enabled;
47
- }
48
-
49
- // =============================================================================
50
- // TIER SYSTEM - Uses tier-auth.js as single source of truth
51
- // =============================================================================
52
-
53
- /**
54
- * TOOL_TIERS - Derived from tier-auth.js for consistency
55
- * This ensures MCP tools-v3.js and tier-auth.js stay in sync
56
- */
57
- const TOOL_TIERS = {};
58
-
59
- // Populate from FREE_TOOLS
60
- for (const tool of FREE_TOOLS) {
61
- TOOL_TIERS[tool] = 'free';
62
- }
63
-
64
- // Populate from PRO_TOOLS
65
- for (const tool of PRO_TOOLS) {
66
- TOOL_TIERS[tool] = 'pro';
67
- }
68
-
69
- function isPro(tier) {
70
- if (isDevProBypassAllowed()) return true;
71
- return tier === 'pro';
72
- }
73
-
74
- /**
75
- * Check tier access with proper ErrorEnvelope support
76
- */
77
- function checkTierAccess(toolName, userTier, args = {}) {
78
- // Developer mode bypass (blocked in production)
79
- if (isDevProBypassAllowed()) {
80
- return { allowed: true };
81
- }
82
-
83
- const required = TOOL_TIERS[toolName] || 'pro';
84
-
85
- // Check tool-level access
86
- if (required === 'pro' && !isPro(userTier)) {
87
- return {
88
- allowed: false,
89
- error: notEntitledError(toolName, userTier, 'pro'),
90
- };
91
- }
92
-
93
- // Check option-level access
94
- const gates = OPTION_GATES[toolName];
95
- if (gates && args) {
96
- for (const [option, requiredTier] of Object.entries(gates)) {
97
- if (typeof requiredTier === 'object') {
98
- const argValue = args[option];
99
- if (argValue && requiredTier[argValue] === 'pro' && !isPro(userTier)) {
100
- return {
101
- allowed: false,
102
- error: optionNotEntitledError(toolName, `${option}=${argValue}`, userTier, 'pro'),
103
- };
104
- }
105
- } else if (args[option] === true && requiredTier === 'pro' && !isPro(userTier)) {
106
- return {
107
- allowed: false,
108
- error: optionNotEntitledError(toolName, option, userTier, 'pro'),
109
- };
110
- }
111
- }
112
- }
113
-
114
- return { allowed: true };
115
- }
116
-
117
- // =============================================================================
118
- // TOOL DEFINITIONS
119
- // =============================================================================
120
-
121
- export const MCP_TOOLS_V3 = [
122
- // ═══════════════════════════════════════════════════════════════════════════
123
- // FREE TOOLS - Inspect & Observe
124
- // ═══════════════════════════════════════════════════════════════════════════
125
-
126
- {
127
- name: "vibecheck.scan",
128
- description: `🔍 Scan codebase for issues
129
-
130
- Scans for:
131
- - Missing routes (client refs to non-existent endpoints)
132
- - Env gaps (used but undeclared env vars)
133
- - Ghost auth (unprotected sensitive endpoints)
134
- - Dead UI (buttons that do nothing)
135
- - Security issues
136
-
137
- Response includes cacheStats: { hit, reusedFindingsCount, durationMs }
138
-
139
- [FREE]`,
140
- inputSchema: {
141
- type: "object",
142
- properties: {
143
- projectPath: { type: "string", description: "Project path" },
144
- categories: {
145
- type: "array",
146
- items: { type: "string" },
147
- description: "Categories: routes, env, auth, billing, security",
148
- },
149
- since: {
150
- type: "string",
151
- description: "ISO timestamp for incremental scan (only re-scan changed files)",
152
- },
153
- noCache: {
154
- type: "boolean",
155
- description: "Bypass cache lookup",
156
- default: false,
157
- },
158
- },
159
- },
160
- },
161
-
162
- {
163
- name: "vibecheck.ctx",
164
- description: `📦 Generate truth context for AI agents
165
-
166
- Returns verified facts about:
167
- - routes: Server routes and client references
168
- - env: Environment variables (used, declared, gaps)
169
- - auth: Authentication model and protected routes
170
- - billing: Payment gates and enforcement
171
-
172
- Use this BEFORE making assertions about the codebase.
173
-
174
- [FREE]`,
175
- inputSchema: {
176
- type: "object",
177
- properties: {
178
- projectPath: { type: "string", description: "Project path" },
179
- scope: {
180
- type: "string",
181
- enum: ["all", "routes", "env", "auth", "billing"],
182
- description: "What to include",
183
- default: "all",
184
- },
185
- },
186
- },
187
- },
188
-
189
- {
190
- name: "vibecheck.verify",
191
- description: `✅ Verify AI-generated code before applying
192
-
193
- Checks for:
194
- - Secrets in code
195
- - Dangerous commands
196
- - Path traversal
197
- - Incomplete stubs
198
- - Hallucinated imports
199
-
200
- [FREE]`,
201
- inputSchema: {
202
- type: "object",
203
- properties: {
204
- code: { type: "string", description: "Code to verify" },
205
- file: { type: "string", description: "Target file path" },
206
- projectPath: { type: "string", description: "Project path" },
207
- },
208
- required: ["code"],
209
- },
210
- },
211
-
212
- {
213
- name: "vibecheck.report",
214
- description: `📄 Generate reports
215
-
216
- Formats: html, md, sarif, json
217
-
218
- [FREE]`,
219
- inputSchema: {
220
- type: "object",
221
- properties: {
222
- projectPath: { type: "string" },
223
- format: { type: "string", enum: ["html", "md", "sarif", "json"], default: "html" },
224
- },
225
- },
226
- },
227
-
228
- {
229
- name: "vibecheck.status",
230
- description: `📊 Check vibecheck status and health [FREE]`,
231
- inputSchema: {
232
- type: "object",
233
- properties: { projectPath: { type: "string" } },
234
- },
235
- },
236
-
237
- {
238
- name: "vibecheck.doctor",
239
- description: `🩺 Diagnose and fix environment issues
240
- Response includes cacheStats: { hit, reusedFindingsCount, durationMs }
241
- [FREE]`,
242
- inputSchema: {
243
- type: "object",
244
- properties: {
245
- projectPath: { type: "string" },
246
- fix: { type: "boolean", default: false },
247
- noCache: {
248
- type: "boolean",
249
- description: "Bypass cache lookup",
250
- default: false,
251
- },
252
- },
253
- },
254
- },
255
-
256
- {
257
- name: "vibecheck.firewall",
258
- description: `🛡️ Agent Firewall - observe mode
259
-
260
- Validates AI code changes against repo truth.
261
- FREE tier: Observe only (logs but doesn't block).
262
- PRO tier: Enforce mode (blocks violations).
263
-
264
- [FREE - observe mode]`,
265
- inputSchema: {
266
- type: "object",
267
- properties: {
268
- action: { type: "string", enum: ["check", "status", "log"] },
269
- code: { type: "string" },
270
- file: { type: "string" },
271
- },
272
- },
273
- },
274
-
275
- {
276
- name: "authority.list",
277
- description: `📋 List available authorities [FREE]`,
278
- inputSchema: {
279
- type: "object",
280
- properties: {
281
- tier: { type: "string", enum: ["free", "pro"] },
282
- },
283
- },
284
- },
285
-
286
- {
287
- name: "authority.classify",
288
- description: `📊 Inventory Authority - analyze duplication and legacy code [FREE]`,
289
- inputSchema: {
290
- type: "object",
291
- properties: {
292
- projectPath: { type: "string", default: "." },
293
- includeNear: { type: "boolean", default: true },
294
- format: { type: "string", enum: ["json", "table", "markdown"], default: "json" },
295
- },
296
- },
297
- },
298
-
299
- {
300
- name: "vibecheck_conductor_status",
301
- description: `📡 Get multi-agent coordination status [FREE]`,
302
- inputSchema: {
303
- type: "object",
304
- properties: {
305
- projectRoot: { type: "string" },
306
- includeDetails: { type: "boolean", default: false },
307
- },
308
- required: ["projectRoot"],
309
- },
310
- },
311
-
312
- {
313
- name: "vibecheck.get_next_action",
314
- description: `🎯 Get next best action recommendation
315
-
316
- Returns what the user should do next based on project state.
317
- Uses the same logic as CLI/Web/VS Code for consistency.
318
-
319
- Response:
320
- - action: string (init, scan, ship, fix, etc.)
321
- - command: string (full CLI command)
322
- - why: string (explanation)
323
- - dashboardLink: string (URL to view in dashboard)
324
- - timeEstimate: string (~30 seconds, ~45 seconds, etc.)
325
- - requiredTier: string (free or pro)
326
- - priority: string (high, medium, low)
327
- - upgradeHint: object (if action requires upgrade)
328
-
329
- [FREE]`,
330
- inputSchema: {
331
- type: "object",
332
- properties: {
333
- projectPath: {
334
- type: "string",
335
- description: "Project path to analyze",
336
- default: "."
337
- },
338
- currentTier: {
339
- type: "string",
340
- enum: ["free", "pro"],
341
- description: "User's current tier",
342
- default: "free"
343
- },
344
- },
345
- },
346
- },
347
-
348
- // ═══════════════════════════════════════════════════════════════════════════
349
- // PRO TOOLS - Fix, Prove & Enforce
350
- // ═══════════════════════════════════════════════════════════════════════════
351
-
352
- {
353
- name: "vibecheck.ship",
354
- description: `🚀 Get ship verdict: SHIP | WARN | BLOCK
355
-
356
- Returns evidence-backed verdict.
357
- Response includes cacheStats: { hit, reusedFindingsCount, durationMs }
358
-
359
- [PRO - $49/mo]`,
360
- inputSchema: {
361
- type: "object",
362
- properties: {
363
- projectPath: { type: "string" },
364
- strict: { type: "boolean" },
365
- since: {
366
- type: "string",
367
- description: "ISO timestamp for incremental check (only re-check changed files)",
368
- },
369
- noCache: {
370
- type: "boolean",
371
- description: "Bypass cache lookup",
372
- default: false,
373
- },
374
- },
375
- },
376
- },
377
-
378
- {
379
- name: "vibecheck.fix",
380
- description: `🔧 AI-powered fixes with proof
381
-
382
- Modes: plan, apply, loop
383
-
384
- [PRO - $49/mo]`,
385
- inputSchema: {
386
- type: "object",
387
- properties: {
388
- projectPath: { type: "string" },
389
- mode: { type: "string", enum: ["plan", "apply", "loop"], default: "plan" },
390
- findingIds: { type: "array", items: { type: "string" } },
391
- },
392
- },
393
- },
394
-
395
- {
396
- name: "vibecheck.prove",
397
- description: `🔬 Full proof loop with runtime verification
398
-
399
- [PRO - $49/mo]`,
400
- inputSchema: {
401
- type: "object",
402
- properties: {
403
- projectPath: { type: "string" },
404
- url: { type: "string" },
405
- maxIterations: { type: "number", default: 5 },
406
- recordVideo: { type: "boolean", default: true },
407
- },
408
- },
409
- },
410
-
411
- {
412
- name: "vibecheck.gate",
413
- description: `🚧 CI/CD enforcement - fail builds on issues [PRO - $49/mo]`,
414
- inputSchema: {
415
- type: "object",
416
- properties: {
417
- projectPath: { type: "string" },
418
- strict: { type: "boolean" },
419
- },
420
- },
421
- },
422
-
423
- {
424
- name: "vibecheck.badge",
425
- description: `🏷️ Generate ship badge [PRO - $49/mo]`,
426
- inputSchema: {
427
- type: "object",
428
- properties: {
429
- projectPath: { type: "string" },
430
- outputPath: { type: "string" },
431
- },
432
- },
433
- },
434
-
435
- {
436
- name: "vibecheck.reality",
437
- description: `🧪 Full runtime verification with auth boundary testing [PRO - $49/mo]`,
438
- inputSchema: {
439
- type: "object",
440
- properties: {
441
- url: { type: "string" },
442
- auth: { type: "string" },
443
- headed: { type: "boolean" },
444
- maxPages: { type: "number", default: 20 },
445
- },
446
- required: ["url"],
447
- },
448
- },
449
-
450
- {
451
- name: "vibecheck.ai_test",
452
- description: `🤖 AI agent testing - autonomous exploration [PRO - $49/mo]`,
453
- inputSchema: {
454
- type: "object",
455
- properties: {
456
- url: { type: "string" },
457
- goal: { type: "string" },
458
- maxActions: { type: "number", default: 50 },
459
- },
460
- required: ["url"],
461
- },
462
- },
463
-
464
- {
465
- name: "vibecheck.share",
466
- description: `📤 Generate PR/review bundle [PRO - $49/mo]`,
467
- inputSchema: {
468
- type: "object",
469
- properties: {
470
- projectPath: { type: "string" },
471
- format: { type: "string", enum: ["github", "gitlab", "slack", "json"], default: "github" },
472
- },
473
- },
474
- },
475
-
476
- // ═══════════════════════════════════════════════════════════════════════════
477
- // AUTHORITY SYSTEM (PRO)
478
- // ═══════════════════════════════════════════════════════════════════════════
479
-
480
- {
481
- name: "authority.approve",
482
- description: `🛡️ Authority Approval - Execute authority & get verdict (PROCEED/STOP/DEFER)
483
-
484
- Execute an authority to get a structured verdict with proofs.
485
-
486
- [PRO - $49/mo]`,
487
- inputSchema: {
488
- type: "object",
489
- properties: {
490
- authority: { type: "string", description: "Authority ID (e.g., 'safe-consolidation')" },
491
- projectPath: { type: "string", default: "." },
492
- dryRun: { type: "boolean", default: false },
493
- },
494
- required: ["authority"],
495
- },
496
- },
497
-
498
- // ═══════════════════════════════════════════════════════════════════════════
499
- // AGENT CONDUCTOR (PRO) - Multi-Agent Coordination
500
- // ═══════════════════════════════════════════════════════════════════════════
501
-
502
- {
503
- name: "vibecheck_conductor_register",
504
- description: `📡 Register AI agent for multi-agent coordination
505
-
506
- Call this at the start of any multi-agent workflow.
507
-
508
- [PRO - $49/mo]`,
509
- inputSchema: {
510
- type: "object",
511
- properties: {
512
- agentId: { type: "string", description: "Agent ID (e.g., 'cursor', 'copilot')" },
513
- projectRoot: { type: "string" },
514
- workingFiles: { type: "array", items: { type: "string" } },
515
- },
516
- required: ["agentId", "projectRoot"],
517
- },
518
- },
519
-
520
- {
521
- name: "vibecheck_conductor_acquire_lock",
522
- description: `🔒 Acquire lock on file/folder for exclusive access
523
-
524
- Prevents concurrent modifications by other agents.
525
-
526
- [PRO - $49/mo]`,
527
- inputSchema: {
528
- type: "object",
529
- properties: {
530
- sessionId: { type: "string" },
531
- path: { type: "string" },
532
- type: { type: "string", enum: ["exclusive", "shared"], default: "exclusive" },
533
- reason: { type: "string" },
534
- },
535
- required: ["sessionId", "path"],
536
- },
537
- },
538
-
539
- {
540
- name: "vibecheck_conductor_release_lock",
541
- description: `🔓 Release a previously acquired lock [PRO - $49/mo]`,
542
- inputSchema: {
543
- type: "object",
544
- properties: {
545
- lockId: { type: "string" },
546
- sessionId: { type: "string" },
547
- },
548
- required: ["lockId", "sessionId"],
549
- },
550
- },
551
-
552
- {
553
- name: "vibecheck_conductor_propose",
554
- description: `📋 Submit change proposal for multi-agent coordination
555
-
556
- Checks for conflicts with other agents before proceeding.
557
-
558
- [PRO - $49/mo]`,
559
- inputSchema: {
560
- type: "object",
561
- properties: {
562
- sessionId: { type: "string" },
563
- proposalId: { type: "string" },
564
- intent: { type: "string" },
565
- operations: {
566
- type: "array",
567
- items: {
568
- type: "object",
569
- properties: {
570
- type: { type: "string", enum: ["create", "modify", "delete", "move"] },
571
- path: { type: "string" },
572
- content: { type: "string" },
573
- },
574
- },
575
- },
576
- projectRoot: { type: "string" },
577
- },
578
- required: ["sessionId", "proposalId", "intent", "operations", "projectRoot"],
579
- },
580
- },
581
-
582
- {
583
- name: "vibecheck_conductor_terminate",
584
- description: `🛑 Terminate agent session and release all locks [PRO - $49/mo]`,
585
- inputSchema: {
586
- type: "object",
587
- properties: {
588
- sessionId: { type: "string" },
589
- },
590
- required: ["sessionId"],
591
- },
592
- },
593
-
594
- // ═══════════════════════════════════════════════════════════════════════════
595
- // AGENT FIREWALL (PRO) - Enforce Mode
596
- // ═══════════════════════════════════════════════════════════════════════════
597
-
598
- {
599
- name: "vibecheck_agent_firewall_intercept",
600
- description: `🛡️ Agent Firewall (Sentinel) - ENFORCE MODE
601
-
602
- Intercepts AI code changes and validates against repo truth.
603
- Blocks violations. Generates proof artifacts.
604
-
605
- Features:
606
- - Reality state validation (routes, env, services)
607
- - Risk scoring (surface area, blast radius)
608
- - Diff simulation (broken imports, orphaned files)
609
- - Assumption verification
610
- - Proof artifact generation
611
-
612
- Call BEFORE any file write operations.
613
-
614
- [PRO - $49/mo]`,
615
- inputSchema: {
616
- type: "object",
617
- required: ["agentId", "filePath", "content"],
618
- properties: {
619
- agentId: { type: "string", description: "Agent ID" },
620
- filePath: { type: "string", description: "File to write" },
621
- content: { type: "string", description: "New content" },
622
- operation: { type: "string", enum: ["create", "modify", "delete"], default: "modify" },
623
- intent: { type: "string", description: "What this change accomplishes" },
624
- projectRoot: { type: "string" },
625
- },
626
- },
627
- },
628
-
629
- // ═══════════════════════════════════════════════════════════════════════════
630
- // INTENT FIREWALL v2 (PRO) - Intent-Aware BLOCKING Enforcement
631
- // ═══════════════════════════════════════════════════════════════════════════
632
-
633
- {
634
- name: "vibecheck_intent_firewall_intercept",
635
- description: `🛡️ Intent-Aware Firewall v2 - BLOCKING enforcement
636
-
637
- Intercepts AI code changes and BLOCKS unless:
638
- 1. User intent is declared (via vibecheck intent set)
639
- 2. Changes align with declared intent
640
- 3. Reality proofs pass
641
-
642
- ⚠️ If no intent is declared, ALL CHANGES ARE BLOCKED.
643
-
644
- This is enforcement infrastructure that cannot be bypassed.
645
- Declare intent BEFORE making AI changes:
646
- vibecheck intent set -s "Your intent"
647
-
648
- Returns: { decision: "PASS"|"BLOCK", violations, intent_hash }
649
-
650
- [PRO - $49/mo]`,
651
- inputSchema: {
652
- type: "object",
653
- required: ["agentId", "filePath", "content"],
654
- properties: {
655
- agentId: { type: "string", description: "Agent ID" },
656
- filePath: { type: "string", description: "File to write" },
657
- content: { type: "string", description: "New content" },
658
- oldContent: { type: "string", description: "Old content (for diff)" },
659
- intent: { type: "string", description: "Agent's stated intent (NOT user intent)" },
660
- projectRoot: { type: "string" },
661
- },
662
- },
663
- },
664
-
665
- {
666
- name: "vibecheck_intent_status",
667
- description: `📋 Get current intent status for Agent Firewall v2
668
-
669
- Shows whether intent is declared and what changes are allowed.
670
- Use this BEFORE making AI changes to understand constraints.
671
-
672
- Returns: { hasIntent, summary, constraints, allowed_changes, hash }
673
-
674
- [FREE]`,
675
- inputSchema: {
676
- type: "object",
677
- properties: {
678
- projectRoot: { type: "string", default: "." },
679
- },
680
- },
681
- },
682
- ];
683
-
684
- // =============================================================================
685
- // TOOL HANDLERS
686
- // =============================================================================
687
-
688
- /**
689
- * Handle v3 tool execution with tier checking and ErrorEnvelope support
690
- */
691
- export async function handleToolV3(toolName, args, context = {}) {
692
- const userTier = context.tier || 'free';
693
-
694
- // Check access with option-level gates
695
- const access = checkTierAccess(toolName, userTier, args);
696
- if (!access.allowed) {
697
- // Return proper ErrorEnvelope format
698
- return {
699
- ok: false,
700
- error: access.error,
701
- tier: userTier,
702
- required: access.error?.required || 'pro',
703
- };
704
- }
705
-
706
- const projectPath = args.projectPath || process.cwd();
707
-
708
- try {
709
- switch (toolName) {
710
- case 'vibecheck.scan':
711
- case 'vibecheck.ctx':
712
- case 'vibecheck.report':
713
- case 'vibecheck.status':
714
- case 'vibecheck.doctor':
715
- case 'vibecheck.ship':
716
- case 'vibecheck.fix':
717
- case 'vibecheck.prove':
718
- case 'vibecheck.gate':
719
- case 'vibecheck.badge':
720
- case 'vibecheck.reality':
721
- case 'vibecheck.ai_test':
722
- case 'vibecheck.share':
723
- return await runCliCommand(projectPath, toolName.replace('vibecheck.', ''), args);
724
-
725
- case 'vibecheck.verify':
726
- return await verifyCode(args);
727
-
728
- case 'vibecheck.firewall':
729
- return await firewallCheck(args, userTier);
730
-
731
- case 'authority.list':
732
- case 'authority.classify':
733
- case 'authority.approve':
734
- return await runCliCommand(projectPath, toolName.replace('authority.', 'authority '), args);
735
-
736
- case 'vibecheck_conductor_status':
737
- case 'vibecheck_conductor_register':
738
- case 'vibecheck_conductor_acquire_lock':
739
- case 'vibecheck_conductor_release_lock':
740
- case 'vibecheck_conductor_propose':
741
- case 'vibecheck_conductor_terminate':
742
- return await handleConductorTool(toolName, args, userTier);
743
-
744
- case 'vibecheck_agent_firewall_intercept':
745
- return await handleFirewallIntercept(args, userTier);
746
-
747
- case 'vibecheck.get_next_action':
748
- return await handleGetNextAction(projectPath, userTier);
749
-
750
- default:
751
- return {
752
- ok: false,
753
- error: {
754
- code: 'TOOL_NOT_FOUND',
755
- message: `Unknown tool: ${toolName}`,
756
- retryable: false,
757
- }
758
- };
759
- }
760
- } catch (error) {
761
- return {
762
- ok: false,
763
- error: {
764
- code: 'INTERNAL_ERROR',
765
- message: error.message,
766
- retryable: true,
767
- }
768
- };
769
- }
770
- }
771
-
772
- // =============================================================================
773
- // IMPLEMENTATIONS
774
- // =============================================================================
775
-
776
- // Cacheable tools
777
- const CACHEABLE_TOOLS = new Set(['scan', 'ship', 'polish', 'doctor']);
778
-
779
- async function runCliCommand(projectPath, command, args, options = {}) {
780
- const flags = Object.entries(args)
781
- .filter(([k, v]) => k !== 'projectPath' && v !== undefined && v !== null)
782
- .map(([k, v]) => {
783
- if (typeof v === 'boolean') return v ? `--${k}` : '';
784
- if (Array.isArray(v)) return `--${k} ${v.join(',')}`;
785
- return `--${k} "${v}"`;
786
- })
787
- .filter(Boolean)
788
- .join(' ');
789
-
790
- // Check if this tool supports caching
791
- const isCacheable = CACHEABLE_TOOLS.has(command);
792
- const useCache = isCacheable && options.useCache !== false && !args.noCache;
793
-
794
- if (useCache) {
795
- // Use cached execution
796
- return executeCachedCliCommand(
797
- projectPath,
798
- command,
799
- () => {
800
- const result = execSync(
801
- `npx vibecheck ${command} --json ${flags}`,
802
- { cwd: projectPath, encoding: 'utf8', timeout: 300000 }
803
- );
804
- try {
805
- return JSON.parse(result);
806
- } catch {
807
- return { output: result, findings: [], verdict: null, metadata: {} };
808
- }
809
- },
810
- {
811
- useCache: true,
812
- forceRefresh: args.forceRefresh || false,
813
- vibecheckVersion: '3.3.0',
814
- }
815
- );
816
- }
817
-
818
- // Non-cacheable execution
819
- const result = execSync(
820
- `npx vibecheck ${command} --json ${flags}`,
821
- { cwd: projectPath, encoding: 'utf8', timeout: 300000 }
822
- );
823
-
824
- try {
825
- const parsed = JSON.parse(result);
826
- // Add empty cacheStats for consistency
827
- return {
828
- ...parsed,
829
- cacheStats: { hit: false, reusedFindingsCount: 0, durationMs: 0 },
830
- };
831
- } catch {
832
- return { output: result, cacheStats: { hit: false, reusedFindingsCount: 0, durationMs: 0 } };
833
- }
834
- }
835
-
836
- async function verifyCode(args) {
837
- const { code } = args;
838
- const issues = [];
839
-
840
- if (/(?:password|secret|api_?key|token)\s*[:=]\s*['"][^'"]+['"]/i.test(code)) {
841
- issues.push({ type: 'secret', message: 'Possible hardcoded secret' });
842
- }
843
- if (/eval\s*\(|Function\s*\(/.test(code)) {
844
- issues.push({ type: 'danger', message: 'eval() or Function() detected' });
845
- }
846
- if (/TODO|FIXME|XXX|HACK/i.test(code)) {
847
- issues.push({ type: 'stub', message: 'Incomplete code stub' });
848
- }
849
-
850
- return { verified: issues.length === 0, issues };
851
- }
852
-
853
- async function firewallCheck(args, tier) {
854
- const mode = tier === 'pro' ? 'enforce' : 'observe';
855
- return {
856
- mode,
857
- checked: true,
858
- message: mode === 'observe'
859
- ? 'Agent Firewall in observe mode (FREE). Upgrade to PRO for enforce mode.'
860
- : 'Agent Firewall in enforce mode (PRO).',
861
- };
862
- }
863
-
864
- async function handleConductorTool(toolName, args, tier) {
865
- // For full conductor features, require PRO
866
- if (toolName !== 'vibecheck_conductor_status' && tier !== 'pro') {
867
- return {
868
- error: 'Full Conductor features require PRO. Upgrade at https://vibecheckai.dev/pricing'
869
- };
870
- }
871
-
872
- // Import and delegate to conductor handlers
873
- try {
874
- const {
875
- handleConductorRegister,
876
- handleConductorAcquireLock,
877
- handleConductorReleaseLock,
878
- handleConductorPropose,
879
- handleConductorStatus,
880
- handleConductorTerminate,
881
- } = await import('./conductor/tools.js');
882
-
883
- switch (toolName) {
884
- case 'vibecheck_conductor_status':
885
- return await handleConductorStatus(args);
886
- case 'vibecheck_conductor_register':
887
- return await handleConductorRegister(args);
888
- case 'vibecheck_conductor_acquire_lock':
889
- return await handleConductorAcquireLock(args);
890
- case 'vibecheck_conductor_release_lock':
891
- return await handleConductorReleaseLock(args);
892
- case 'vibecheck_conductor_propose':
893
- return await handleConductorPropose(args);
894
- case 'vibecheck_conductor_terminate':
895
- return await handleConductorTerminate(args);
896
- default:
897
- return { error: `Unknown conductor tool: ${toolName}` };
898
- }
899
- } catch (error) {
900
- return { error: `Conductor not available: ${error.message}` };
901
- }
902
- }
903
-
904
- async function handleFirewallIntercept(args, tier) {
905
- if (tier !== 'pro') {
906
- return {
907
- allowed: true,
908
- mode: 'observe',
909
- message: 'Firewall intercept in observe mode (FREE). Changes logged but not blocked.',
910
- violations: [],
911
- };
912
- }
913
-
914
- // Import and delegate to firewall interceptor
915
- try {
916
- const { interceptFileWrite } = await import('./agent-firewall-interceptor.js');
917
- return await interceptFileWrite(args);
918
- } catch (error) {
919
- return { error: `Firewall intercept failed: ${error.message}` };
920
- }
921
- }
922
-
923
- /**
924
- * Handle get_next_action tool - returns recommended next action based on project state
925
- */
926
- async function handleGetNextAction(projectPath, tier) {
927
- try {
928
- // Import the next-action module from CLI
929
- const nextActionModule = require('../bin/runners/lib/next-action.js');
930
- const result = nextActionModule.getNextActionJson(projectPath, tier);
931
-
932
- return {
933
- ok: true,
934
- data: result,
935
- };
936
- } catch (error) {
937
- // Fallback: compute basic next action without the module
938
- const statePath = path.join(projectPath, '.vibecheck', 'summary.json');
939
- let state = { hasConfig: false, lastScan: null, lastShip: null };
940
-
941
- try {
942
- await fs.access(path.join(projectPath, '.vibecheckrc'));
943
- state.hasConfig = true;
944
- } catch {}
945
-
946
- try {
947
- const summary = JSON.parse(await fs.readFile(statePath, 'utf-8'));
948
- state.lastScan = { verdict: summary.verdict, score: summary.score };
949
- } catch {}
950
-
951
- // Basic next action logic
952
- let action, command, why;
953
-
954
- if (!state.hasConfig) {
955
- action = 'init';
956
- command = 'vibecheck init';
957
- why = 'Project not initialized. Run init to create config.';
958
- } else if (!state.lastScan) {
959
- action = 'scan';
960
- command = 'vibecheck scan';
961
- why = 'No scans yet. Run your first scan.';
962
- } else if (tier === 'pro') {
963
- action = 'ship';
964
- command = 'vibecheck ship';
965
- why = 'Get your SHIP/WARN/BLOCK verdict.';
966
- } else {
967
- action = 'report';
968
- command = 'vibecheck report';
969
- why = 'Generate a report of your scan results.';
970
- }
971
-
972
- return {
973
- ok: true,
974
- data: {
975
- action,
976
- command,
977
- cliCommand: command,
978
- why,
979
- dashboardLink: 'https://app.vibecheckai.dev',
980
- docsLink: `https://docs.vibecheckai.dev/cli/${action}`,
981
- timeEstimate: action === 'scan' ? '~45 seconds' : '~15 seconds',
982
- requiredTier: action === 'ship' ? 'pro' : 'free',
983
- priority: 'high',
984
- upgradeHint: tier === 'free' && action === 'report' ? {
985
- feature: 'Ship Verdict',
986
- benefit: 'Get SHIP/WARN/BLOCK verdict with evidence',
987
- url: 'https://vibecheckai.dev/pricing',
988
- } : null,
989
- },
990
- };
991
- }
992
- }
993
-
994
- // =============================================================================
995
- // EXPORTS
996
- // =============================================================================
997
-
998
- export { TOOL_TIERS, checkTierAccess, isPro };
999
-
1000
- export default {
1001
- MCP_TOOLS_V3,
1002
- handleToolV3,
1003
- TOOL_TIERS,
1004
- };