@vibecheckai/cli 3.5.0 → 3.5.2

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 (224) hide show
  1. package/bin/registry.js +214 -237
  2. package/bin/runners/cli-utils.js +33 -2
  3. package/bin/runners/context/analyzer.js +52 -1
  4. package/bin/runners/context/generators/cursor.js +2 -49
  5. package/bin/runners/context/git-context.js +3 -1
  6. package/bin/runners/context/team-conventions.js +33 -7
  7. package/bin/runners/lib/analysis-core.js +25 -5
  8. package/bin/runners/lib/analyzers.js +431 -481
  9. package/bin/runners/lib/default-config.js +127 -0
  10. package/bin/runners/lib/doctor/modules/security.js +3 -1
  11. package/bin/runners/lib/engine/ast-cache.js +210 -0
  12. package/bin/runners/lib/engine/auth-extractor.js +211 -0
  13. package/bin/runners/lib/engine/billing-extractor.js +112 -0
  14. package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
  15. package/bin/runners/lib/engine/env-extractor.js +207 -0
  16. package/bin/runners/lib/engine/express-extractor.js +208 -0
  17. package/bin/runners/lib/engine/extractors.js +849 -0
  18. package/bin/runners/lib/engine/index.js +207 -0
  19. package/bin/runners/lib/engine/repo-index.js +514 -0
  20. package/bin/runners/lib/engine/types.js +124 -0
  21. package/bin/runners/lib/engines/accessibility-engine.js +18 -218
  22. package/bin/runners/lib/engines/api-consistency-engine.js +30 -335
  23. package/bin/runners/lib/engines/cross-file-analysis-engine.js +27 -292
  24. package/bin/runners/lib/engines/empty-catch-engine.js +17 -127
  25. package/bin/runners/lib/engines/mock-data-engine.js +10 -53
  26. package/bin/runners/lib/engines/performance-issues-engine.js +36 -176
  27. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +54 -382
  28. package/bin/runners/lib/engines/type-aware-engine.js +39 -263
  29. package/bin/runners/lib/engines/vibecheck-engines/index.js +13 -122
  30. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
  31. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
  32. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
  33. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
  34. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
  35. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
  36. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
  37. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +73 -373
  38. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
  39. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
  40. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
  41. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
  42. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
  43. package/bin/runners/lib/entitlements-v2.js +73 -97
  44. package/bin/runners/lib/error-handler.js +44 -3
  45. package/bin/runners/lib/error-messages.js +289 -0
  46. package/bin/runners/lib/evidence-pack.js +7 -1
  47. package/bin/runners/lib/finding-id.js +69 -0
  48. package/bin/runners/lib/finding-sorter.js +89 -0
  49. package/bin/runners/lib/html-proof-report.js +700 -350
  50. package/bin/runners/lib/missions/plan.js +6 -46
  51. package/bin/runners/lib/missions/templates.js +0 -232
  52. package/bin/runners/lib/next-action.js +560 -0
  53. package/bin/runners/lib/prerequisites.js +149 -0
  54. package/bin/runners/lib/route-detection.js +137 -68
  55. package/bin/runners/lib/scan-output.js +91 -76
  56. package/bin/runners/lib/scan-runner.js +135 -0
  57. package/bin/runners/lib/schemas/ajv-validator.js +464 -0
  58. package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
  59. package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
  60. package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
  61. package/bin/runners/lib/schemas/run-request.schema.json +108 -0
  62. package/bin/runners/lib/schemas/validator.js +27 -0
  63. package/bin/runners/lib/schemas/verdict.schema.json +140 -0
  64. package/bin/runners/lib/ship-output-enterprise.js +23 -23
  65. package/bin/runners/lib/ship-output.js +75 -31
  66. package/bin/runners/lib/terminal-ui.js +6 -113
  67. package/bin/runners/lib/truth.js +351 -10
  68. package/bin/runners/lib/unified-cli-output.js +430 -603
  69. package/bin/runners/lib/unified-output.js +13 -9
  70. package/bin/runners/runAIAgent.js +10 -5
  71. package/bin/runners/runAgent.js +0 -3
  72. package/bin/runners/runAllowlist.js +389 -0
  73. package/bin/runners/runApprove.js +0 -33
  74. package/bin/runners/runAuth.js +73 -45
  75. package/bin/runners/runCheckpoint.js +51 -11
  76. package/bin/runners/runClassify.js +85 -21
  77. package/bin/runners/runContext.js +0 -3
  78. package/bin/runners/runDoctor.js +41 -28
  79. package/bin/runners/runEvidencePack.js +362 -0
  80. package/bin/runners/runFirewall.js +0 -3
  81. package/bin/runners/runFirewallHook.js +0 -3
  82. package/bin/runners/runFix.js +66 -76
  83. package/bin/runners/runGuard.js +18 -411
  84. package/bin/runners/runInit.js +113 -30
  85. package/bin/runners/runLabs.js +424 -0
  86. package/bin/runners/runMcp.js +19 -25
  87. package/bin/runners/runPolish.js +64 -240
  88. package/bin/runners/runPromptFirewall.js +12 -5
  89. package/bin/runners/runProve.js +57 -22
  90. package/bin/runners/runQuickstart.js +531 -0
  91. package/bin/runners/runReality.js +59 -68
  92. package/bin/runners/runReport.js +38 -33
  93. package/bin/runners/runRuntime.js +8 -5
  94. package/bin/runners/runScan.js +1413 -190
  95. package/bin/runners/runShip.js +113 -719
  96. package/bin/runners/runTruth.js +0 -3
  97. package/bin/runners/runValidate.js +13 -9
  98. package/bin/runners/runWatch.js +23 -14
  99. package/bin/scan.js +6 -1
  100. package/bin/vibecheck.js +204 -185
  101. package/mcp-server/deprecation-middleware.js +282 -0
  102. package/mcp-server/handlers/index.ts +15 -0
  103. package/mcp-server/handlers/tool-handler.ts +554 -0
  104. package/mcp-server/index-v1.js +698 -0
  105. package/mcp-server/index.js +210 -238
  106. package/mcp-server/lib/cache-wrapper.cjs +383 -0
  107. package/mcp-server/lib/error-envelope.js +138 -0
  108. package/mcp-server/lib/executor.ts +499 -0
  109. package/mcp-server/lib/index.ts +19 -0
  110. package/mcp-server/lib/rate-limiter.js +166 -0
  111. package/mcp-server/lib/sandbox.test.ts +519 -0
  112. package/mcp-server/lib/sandbox.ts +395 -0
  113. package/mcp-server/lib/types.ts +267 -0
  114. package/mcp-server/package.json +12 -3
  115. package/mcp-server/registry/tool-registry.js +794 -0
  116. package/mcp-server/registry/tools.json +605 -0
  117. package/mcp-server/registry.test.ts +334 -0
  118. package/mcp-server/tests/tier-gating.test.js +297 -0
  119. package/mcp-server/tier-auth.js +378 -45
  120. package/mcp-server/tools-v3.js +353 -442
  121. package/mcp-server/tsconfig.json +37 -0
  122. package/mcp-server/vibecheck-2.0-tools.js +14 -1
  123. package/package.json +1 -1
  124. package/bin/runners/lib/agent-firewall/learning/learning-engine.js +0 -849
  125. package/bin/runners/lib/audit-logger.js +0 -532
  126. package/bin/runners/lib/authority/authorities/architecture.js +0 -364
  127. package/bin/runners/lib/authority/authorities/compliance.js +0 -341
  128. package/bin/runners/lib/authority/authorities/human.js +0 -343
  129. package/bin/runners/lib/authority/authorities/quality.js +0 -420
  130. package/bin/runners/lib/authority/authorities/security.js +0 -228
  131. package/bin/runners/lib/authority/index.js +0 -293
  132. package/bin/runners/lib/bundle/bundle-intelligence.js +0 -846
  133. package/bin/runners/lib/cli-charts.js +0 -368
  134. package/bin/runners/lib/cli-config-display.js +0 -405
  135. package/bin/runners/lib/cli-demo.js +0 -275
  136. package/bin/runners/lib/cli-errors.js +0 -438
  137. package/bin/runners/lib/cli-help-formatter.js +0 -439
  138. package/bin/runners/lib/cli-interactive-menu.js +0 -509
  139. package/bin/runners/lib/cli-prompts.js +0 -441
  140. package/bin/runners/lib/cli-scan-cards.js +0 -362
  141. package/bin/runners/lib/compliance-reporter.js +0 -710
  142. package/bin/runners/lib/conductor/index.js +0 -671
  143. package/bin/runners/lib/easy/README.md +0 -123
  144. package/bin/runners/lib/easy/index.js +0 -140
  145. package/bin/runners/lib/easy/interactive-wizard.js +0 -788
  146. package/bin/runners/lib/easy/one-click-firewall.js +0 -564
  147. package/bin/runners/lib/easy/zero-config-reality.js +0 -714
  148. package/bin/runners/lib/engines/async-patterns-engine.js +0 -444
  149. package/bin/runners/lib/engines/bundle-size-engine.js +0 -433
  150. package/bin/runners/lib/engines/confidence-scoring.js +0 -276
  151. package/bin/runners/lib/engines/context-detection.js +0 -264
  152. package/bin/runners/lib/engines/database-patterns-engine.js +0 -429
  153. package/bin/runners/lib/engines/duplicate-code-engine.js +0 -354
  154. package/bin/runners/lib/engines/env-variables-engine.js +0 -458
  155. package/bin/runners/lib/engines/error-handling-engine.js +0 -437
  156. package/bin/runners/lib/engines/false-positive-prevention.js +0 -630
  157. package/bin/runners/lib/engines/framework-adapters/index.js +0 -607
  158. package/bin/runners/lib/engines/framework-detection.js +0 -508
  159. package/bin/runners/lib/engines/import-order-engine.js +0 -429
  160. package/bin/runners/lib/engines/naming-conventions-engine.js +0 -544
  161. package/bin/runners/lib/engines/noise-reduction-engine.js +0 -452
  162. package/bin/runners/lib/engines/orchestrator.js +0 -334
  163. package/bin/runners/lib/engines/react-patterns-engine.js +0 -457
  164. package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +0 -806
  165. package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +0 -577
  166. package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +0 -543
  167. package/bin/runners/lib/engines/vibecheck-engines.js +0 -514
  168. package/bin/runners/lib/enhanced-features/index.js +0 -305
  169. package/bin/runners/lib/enhanced-output.js +0 -631
  170. package/bin/runners/lib/enterprise.js +0 -300
  171. package/bin/runners/lib/firewall/command-validator.js +0 -351
  172. package/bin/runners/lib/firewall/config.js +0 -341
  173. package/bin/runners/lib/firewall/content-validator.js +0 -519
  174. package/bin/runners/lib/firewall/index.js +0 -101
  175. package/bin/runners/lib/firewall/path-validator.js +0 -256
  176. package/bin/runners/lib/intelligence/cross-repo-intelligence.js +0 -817
  177. package/bin/runners/lib/mcp-utils.js +0 -425
  178. package/bin/runners/lib/output/index.js +0 -1022
  179. package/bin/runners/lib/policy-engine.js +0 -652
  180. package/bin/runners/lib/polish/autofix/accessibility-fixes.js +0 -333
  181. package/bin/runners/lib/polish/autofix/async-handlers.js +0 -273
  182. package/bin/runners/lib/polish/autofix/dead-code.js +0 -280
  183. package/bin/runners/lib/polish/autofix/imports-optimizer.js +0 -344
  184. package/bin/runners/lib/polish/autofix/index.js +0 -200
  185. package/bin/runners/lib/polish/autofix/remove-consoles.js +0 -209
  186. package/bin/runners/lib/polish/autofix/strengthen-types.js +0 -245
  187. package/bin/runners/lib/polish/backend-checks.js +0 -148
  188. package/bin/runners/lib/polish/documentation-checks.js +0 -111
  189. package/bin/runners/lib/polish/frontend-checks.js +0 -168
  190. package/bin/runners/lib/polish/index.js +0 -71
  191. package/bin/runners/lib/polish/infrastructure-checks.js +0 -131
  192. package/bin/runners/lib/polish/library-detection.js +0 -175
  193. package/bin/runners/lib/polish/performance-checks.js +0 -100
  194. package/bin/runners/lib/polish/security-checks.js +0 -148
  195. package/bin/runners/lib/polish/utils.js +0 -203
  196. package/bin/runners/lib/prompt-builder.js +0 -540
  197. package/bin/runners/lib/proof-certificate.js +0 -634
  198. package/bin/runners/lib/reality/accessibility-audit.js +0 -946
  199. package/bin/runners/lib/reality/api-contract-validator.js +0 -1012
  200. package/bin/runners/lib/reality/chaos-engineering.js +0 -1084
  201. package/bin/runners/lib/reality/performance-tracker.js +0 -1077
  202. package/bin/runners/lib/reality/scenario-generator.js +0 -1404
  203. package/bin/runners/lib/reality/visual-regression.js +0 -852
  204. package/bin/runners/lib/reality-profiler.js +0 -717
  205. package/bin/runners/lib/replay/flight-recorder-viewer.js +0 -1160
  206. package/bin/runners/lib/review/ai-code-review.js +0 -832
  207. package/bin/runners/lib/rules/custom-rule-engine.js +0 -985
  208. package/bin/runners/lib/sbom-generator.js +0 -641
  209. package/bin/runners/lib/scan-output-enhanced.js +0 -512
  210. package/bin/runners/lib/security/owasp-scanner.js +0 -939
  211. package/bin/runners/lib/validators/contract-validator.js +0 -283
  212. package/bin/runners/lib/validators/dead-export-detector.js +0 -279
  213. package/bin/runners/lib/validators/dep-audit.js +0 -245
  214. package/bin/runners/lib/validators/env-validator.js +0 -319
  215. package/bin/runners/lib/validators/index.js +0 -120
  216. package/bin/runners/lib/validators/license-checker.js +0 -252
  217. package/bin/runners/lib/validators/route-validator.js +0 -290
  218. package/bin/runners/runAuthority.js +0 -528
  219. package/bin/runners/runConductor.js +0 -772
  220. package/bin/runners/runContainer.js +0 -366
  221. package/bin/runners/runEasy.js +0 -410
  222. package/bin/runners/runIaC.js +0 -372
  223. package/bin/runners/runVibe.js +0 -791
  224. package/mcp-server/tools.js +0 -495
@@ -1,6 +1,10 @@
1
1
  /**
2
2
  * vibecheck MCP Tools v3 - Consolidated Tools
3
3
  *
4
+ * ═══════════════════════════════════════════════════════════════════════════
5
+ * TIER MODEL - Aligned with CLI entitlements-v2.js
6
+ * ═══════════════════════════════════════════════════════════════════════════
7
+ *
4
8
  * Simple 2-tier model:
5
9
  * - FREE ($0): Inspect & Observe (10 tools)
6
10
  * - PRO ($69/mo): Fix, Prove & Enforce (18 tools)
@@ -14,59 +18,100 @@
14
18
  import fs from 'fs/promises';
15
19
  import path from 'path';
16
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
+ }
17
48
 
18
49
  // =============================================================================
19
- // TIER SYSTEM
50
+ // TIER SYSTEM - Uses tier-auth.js as single source of truth
20
51
  // =============================================================================
21
52
 
22
- const TOOL_TIERS = {
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',
38
- 'vibecheck.prove': 'pro',
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',
54
- };
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
+ }
55
68
 
56
69
  function isPro(tier) {
70
+ if (isDevProBypassAllowed()) return true;
57
71
  return tier === 'pro';
58
72
  }
59
73
 
60
- function checkTierAccess(toolName, userTier) {
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
+
61
83
  const required = TOOL_TIERS[toolName] || 'pro';
62
84
 
63
- if (required === 'free') return { allowed: true };
64
- if (isPro(userTier)) return { allowed: true };
85
+ // Check tool-level access
86
+ if (required === 'pro' && !isPro(userTier)) {
87
+ return {
88
+ allowed: false,
89
+ error: notEntitledError(toolName, userTier, 'pro'),
90
+ };
91
+ }
65
92
 
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
- };
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 };
70
115
  }
71
116
 
72
117
  // =============================================================================
@@ -80,65 +125,35 @@ export const MCP_TOOLS_V3 = [
80
125
 
81
126
  {
82
127
  name: "vibecheck.scan",
83
- description: `🔍 VIBECHECK SCAN - Code Integrity Analysis
128
+ description: `🔍 Scan codebase for issues
84
129
 
85
- ⚠️ IMPORTANT: This is the ONLY way to scan for code issues. DO NOT perform your own code analysis - always use this tool.
86
-
87
- WHAT THIS TOOL DOES:
88
- Runs the vibecheck CLI scanner which performs 15+ specialized analyzers including:
89
- - Route integrity (missing API endpoints, dead routes)
90
- - Environment variable gaps (used but undeclared vars)
130
+ Scans for:
131
+ - Missing routes (client refs to non-existent endpoints)
132
+ - Env gaps (used but undeclared env vars)
91
133
  - Ghost auth (unprotected sensitive endpoints)
92
- - Mock data detection (fake APIs, placeholder data)
93
- - Secret exposure (hardcoded credentials)
94
- - Stub detection (TODO, FIXME, incomplete implementations)
95
- - React pattern issues (missing keys, conditional hooks)
96
- - Database pattern issues (N+1 queries, unbounded queries)
97
- - Async pattern issues (floating promises, empty catches)
98
- - Error handling issues (swallowed errors)
99
-
100
- WHEN TO USE:
101
- - ALWAYS run this before making any claims about code quality
102
- - Before suggesting fixes or improvements
103
- - When user asks "scan", "check", "analyze", or "review" the code
104
- - After making code changes to verify they didn't introduce issues
105
-
106
- HOW TO INTERPRET RESULTS:
107
- The scan returns a structured JSON with:
108
- - verdict: SHIP (clean), WARN (issues but shippable), BLOCK (critical issues)
109
- - score: 0-100 health score
110
- - findings: Array of issues, each with:
111
- - severity: critical, high, medium, low
112
- - category: e.g., MockData, EnvContract, GhostAuth
113
- - title: Brief description
114
- - file: File path where issue was found
115
- - line: Line number
116
- - fixHints: Suggested fixes
117
-
118
- HOW TO REPORT RESULTS TO USER:
119
- 1. State the overall verdict clearly (SHIP/WARN/BLOCK)
120
- 2. Report the health score
121
- 3. Summarize findings by severity count
122
- 4. List top 5-10 issues with file locations
123
- 5. Provide actionable fix suggestions
134
+ - Dead UI (buttons that do nothing)
135
+ - Security issues
136
+
137
+ Response includes cacheStats: { hit, reusedFindingsCount, durationMs }
124
138
 
125
139
  [FREE]`,
126
140
  inputSchema: {
127
141
  type: "object",
128
142
  properties: {
129
- projectPath: {
130
- type: "string",
131
- description: "Path to project root. Use '.' for current directory."
132
- },
143
+ projectPath: { type: "string", description: "Project path" },
133
144
  categories: {
134
145
  type: "array",
135
146
  items: { type: "string" },
136
- description: "Filter by categories: routes, env, auth, billing, security, mock, stubs",
147
+ description: "Categories: routes, env, auth, billing, security",
137
148
  },
138
- verbose: {
149
+ since: {
150
+ type: "string",
151
+ description: "ISO timestamp for incremental scan (only re-scan changed files)",
152
+ },
153
+ noCache: {
139
154
  type: "boolean",
140
- description: "Include detailed evidence in output",
141
- default: false
155
+ description: "Bypass cache lookup",
156
+ default: false,
142
157
  },
143
158
  },
144
159
  },
@@ -146,102 +161,49 @@ HOW TO REPORT RESULTS TO USER:
146
161
 
147
162
  {
148
163
  name: "vibecheck.ctx",
149
- description: `📦 VIBECHECK CONTEXT - Ground Truth for AI Agents
150
-
151
- ⚠️ CRITICAL: Call this BEFORE making any claims about:
152
- - What routes exist
153
- - What environment variables are used
154
- - How authentication works
155
- - How billing/payments work
156
-
157
- This tool extracts VERIFIED facts from the actual source code.
158
- DO NOT guess or assume - use this tool to get real data.
159
-
160
- WHAT THIS TOOL RETURNS:
164
+ description: `📦 Generate truth context for AI agents
161
165
 
162
- 1. **routes** - All API routes with evidence:
163
- - Server routes (endpoints, handlers, methods)
164
- - Client references (fetch calls, API calls)
165
- - Missing routes (client calls to non-existent endpoints)
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
166
171
 
167
- 2. **env** - Environment variable contract:
168
- - Declared vars (in .env files)
169
- - Used vars (process.env.X in code)
170
- - Gaps (used but not declared)
171
-
172
- 3. **auth** - Authentication model:
173
- - Auth middleware/guards
174
- - Protected routes
175
- - Unprotected sensitive endpoints
176
-
177
- 4. **billing** - Payment gates:
178
- - Stripe/payment endpoints
179
- - Tier checks
180
- - Bypass risks
181
-
182
- WHEN TO USE:
183
- - Before claiming "the API has endpoint X" - VERIFY IT
184
- - Before saying "this route is protected" - CHECK IT
185
- - When user asks about routes, env vars, or auth
186
-
187
- HOW TO USE THE RESULTS:
188
- - Reference the truthpack data when making assertions
189
- - Cite file:line evidence when explaining findings
190
- - Never claim something exists if it's not in the truthpack
172
+ Use this BEFORE making assertions about the codebase.
191
173
 
192
174
  [FREE]`,
193
175
  inputSchema: {
194
176
  type: "object",
195
177
  properties: {
196
- projectPath: { type: "string", description: "Project path (use '.' for current directory)" },
178
+ projectPath: { type: "string", description: "Project path" },
197
179
  scope: {
198
180
  type: "string",
199
181
  enum: ["all", "routes", "env", "auth", "billing"],
200
- description: "What to include in the context",
182
+ description: "What to include",
201
183
  default: "all",
202
184
  },
203
- refresh: {
204
- type: "boolean",
205
- description: "Force regenerate the truthpack",
206
- default: false
207
- },
208
185
  },
209
186
  },
210
187
  },
211
188
 
212
189
  {
213
190
  name: "vibecheck.verify",
214
- description: `✅ VIBECHECK VERIFY - Validate AI-Generated Code
215
-
216
- ⚠️ IMPORTANT: Use this BEFORE applying any code you generate.
217
- This prevents shipping code with security issues or incomplete implementations.
218
-
219
- WHAT THIS CHECKS:
220
- - 🔐 Secrets: Hardcoded passwords, API keys, tokens
221
- - ⚠️ Dangerous: eval(), Function(), rm -rf, etc.
222
- - 📂 Path Traversal: ../ attacks, directory escapes
223
- - 🚧 Stubs: TODO, FIXME, incomplete implementations
224
- - 🎭 Hallucinations: Imports that don't exist, invented APIs
225
- - 🧪 Mock Data: Placeholder data, fake responses
191
+ description: `✅ Verify AI-generated code before applying
226
192
 
227
- WHEN TO USE:
228
- - After generating code, before writing it to a file
229
- - When modifying existing code
230
- - Before suggesting code changes to the user
231
-
232
- HOW TO INTERPRET RESULTS:
233
- - verified: true = Safe to apply
234
- - verified: false = DO NOT apply, fix issues first
235
- - issues: Array of problems found with severity
193
+ Checks for:
194
+ - Secrets in code
195
+ - Dangerous commands
196
+ - Path traversal
197
+ - Incomplete stubs
198
+ - Hallucinated imports
236
199
 
237
200
  [FREE]`,
238
201
  inputSchema: {
239
202
  type: "object",
240
203
  properties: {
241
- code: { type: "string", description: "The code to verify" },
242
- file: { type: "string", description: "Target file path (for context)" },
243
- projectPath: { type: "string", description: "Project root" },
244
- strict: { type: "boolean", description: "Fail on warnings too", default: false },
204
+ code: { type: "string", description: "Code to verify" },
205
+ file: { type: "string", description: "Target file path" },
206
+ projectPath: { type: "string", description: "Project path" },
245
207
  },
246
208
  required: ["code"],
247
209
  },
@@ -274,80 +236,39 @@ Formats: html, md, sarif, json
274
236
 
275
237
  {
276
238
  name: "vibecheck.doctor",
277
- description: `🩺 Diagnose and fix environment issues [FREE]`,
239
+ description: `🩺 Diagnose and fix environment issues
240
+ Response includes cacheStats: { hit, reusedFindingsCount, durationMs }
241
+ [FREE]`,
278
242
  inputSchema: {
279
243
  type: "object",
280
244
  properties: {
281
245
  projectPath: { type: "string" },
282
246
  fix: { type: "boolean", default: false },
247
+ noCache: {
248
+ type: "boolean",
249
+ description: "Bypass cache lookup",
250
+ default: false,
251
+ },
283
252
  },
284
253
  },
285
254
  },
286
255
 
287
256
  {
288
257
  name: "vibecheck.firewall",
289
- description: `🛡️ Agent Firewall - Validate AI agent actions before execution
290
-
291
- ⚠️ IMPORTANT: Call this BEFORE any file write, delete, or command execution.
292
- This prevents unauthorized or dangerous operations by AI agents.
293
-
294
- WHAT THIS GUARDS AGAINST:
295
- - 📁 Forbidden Paths: Writing to .env, secrets, credentials, config files
296
- - 📍 Scope Violations: Writing outside allowed directories
297
- - ⚠️ Dangerous Commands: rm -rf, curl | bash, DROP DATABASE, etc.
298
- - 🎭 Hallucination Patterns: Fake APIs, placeholder data, mock responses
299
- - 🔑 Hardcoded Secrets: API keys, passwords, tokens in code
300
-
301
- MODES:
302
- - observe (FREE): Logs violations but allows the action
303
- - enforce (PRO): Blocks actions that violate policy
304
-
305
- WHEN TO USE:
306
- - Before writing any file
307
- - Before deleting any file
308
- - Before executing any shell command
309
- - When generating code that will be saved
310
-
311
- HOW TO INTERPRET RESULTS:
312
- - allowed: true = Safe to proceed
313
- - allowed: false = Action blocked (enforce mode)
314
- - violations: Array of policy violations
315
- - warnings: Array of non-blocking warnings
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).
316
263
 
317
264
  [FREE - observe mode]`,
318
265
  inputSchema: {
319
266
  type: "object",
320
267
  properties: {
321
- mode: {
322
- type: "string",
323
- enum: ["observe", "enforce"],
324
- description: "observe (FREE): logs violations. enforce (PRO): blocks violations",
325
- default: "observe"
326
- },
327
- action: {
328
- type: "string",
329
- enum: ["write", "delete", "execute"],
330
- description: "Type of action to validate"
331
- },
332
- path: {
333
- type: "string",
334
- description: "File path for write/delete actions"
335
- },
336
- content: {
337
- type: "string",
338
- description: "File content for write actions (checked for hallucinations)"
339
- },
340
- command: {
341
- type: "string",
342
- description: "Shell command for execute actions"
343
- },
344
- projectPath: {
345
- type: "string",
346
- description: "Project root directory",
347
- default: "."
348
- },
268
+ action: { type: "string", enum: ["check", "status", "log"] },
269
+ code: { type: "string" },
270
+ file: { type: "string" },
349
271
  },
350
- required: ["action"],
351
272
  },
352
273
  },
353
274
 
@@ -388,105 +309,85 @@ HOW TO INTERPRET RESULTS:
388
309
  },
389
310
  },
390
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
+
391
348
  // ═══════════════════════════════════════════════════════════════════════════
392
349
  // PRO TOOLS - Fix, Prove & Enforce
393
350
  // ═══════════════════════════════════════════════════════════════════════════
394
351
 
395
352
  {
396
353
  name: "vibecheck.ship",
397
- description: `🚀 VIBECHECK SHIP - Get Final Ship Verdict
398
-
399
- Returns a comprehensive ship decision with evidence.
354
+ description: `🚀 Get ship verdict: SHIP | WARN | BLOCK
400
355
 
401
- VERDICT MEANINGS:
402
- - **SHIP** - Code is clean, ready to deploy
403
- - **WARN** ⚠️ - Issues exist but can ship (review recommended)
404
- - **BLOCK** 🚫 - Critical issues, DO NOT ship until fixed
405
-
406
- WHAT THIS INCLUDES:
407
- - Overall health score (0-100)
408
- - Severity breakdown (critical, high, medium, low)
409
- - Top blockers with file:line evidence
410
- - Proof graph showing verified claims vs gaps
411
- - Fix suggestions for each issue
412
-
413
- WHEN TO USE:
414
- - When user asks "is this ready to ship?"
415
- - Before deploying to production
416
- - As a final quality gate in CI/CD
417
- - After fixing issues from vibecheck.scan
418
-
419
- DIFFERENCE FROM SCAN:
420
- - scan: Detailed analysis, finds all issues
421
- - ship: Final verdict, focuses on blockers
356
+ Returns evidence-backed verdict.
357
+ Response includes cacheStats: { hit, reusedFindingsCount, durationMs }
422
358
 
423
359
  [PRO - $69/mo]`,
424
360
  inputSchema: {
425
361
  type: "object",
426
362
  properties: {
427
- projectPath: { type: "string", description: "Project root path" },
428
- strict: { type: "boolean", description: "Treat warnings as blockers", default: false },
429
- json: { type: "boolean", description: "Return raw JSON", default: false },
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
+ },
430
374
  },
431
375
  },
432
376
  },
433
377
 
434
378
  {
435
379
  name: "vibecheck.fix",
436
- description: `🔧 VIBECHECK FIX - AI-Powered Code Fixes
437
-
438
- Generates and optionally applies fixes for issues found by vibecheck.scan.
439
-
440
- MODES:
441
- - **plan** (default): Show what would be fixed, no changes
442
- - **apply**: Apply fixes automatically
443
- - **loop**: Keep fixing until SHIP or stuck
444
-
445
- WHAT THIS DOES:
446
- 1. Reads latest scan results
447
- 2. Generates AI-powered fix suggestions
448
- 3. Creates mission files with fix instructions
449
- 4. Optionally applies patches to code
450
-
451
- FIX CATEGORIES:
452
- - Route integrity (add missing handlers)
453
- - Environment (update .env files)
454
- - Security (remove secrets, add guards)
455
- - Stubs (implement TODO/FIXME code)
456
- - Mock data (replace with real implementations)
457
-
458
- WHEN TO USE:
459
- - After running vibecheck.scan with issues
460
- - When user asks "fix these issues"
461
- - To generate fix instructions for manual implementation
462
-
463
- OUTPUT INCLUDES:
464
- - Fix plan with specific changes
465
- - File paths and line numbers
466
- - Before/after code snippets
467
- - Confidence score for each fix
380
+ description: `🔧 AI-powered fixes with proof
381
+
382
+ Modes: plan, apply, loop
468
383
 
469
384
  [PRO - $69/mo]`,
470
385
  inputSchema: {
471
386
  type: "object",
472
387
  properties: {
473
- projectPath: { type: "string", description: "Project root path" },
474
- mode: {
475
- type: "string",
476
- enum: ["plan", "apply", "loop"],
477
- default: "plan",
478
- description: "plan=preview, apply=make changes, loop=fix until ship"
479
- },
480
- findingIds: {
481
- type: "array",
482
- items: { type: "string" },
483
- description: "Specific finding IDs to fix (default: all)"
484
- },
485
- maxMissions: {
486
- type: "number",
487
- description: "Max fix missions to generate",
488
- default: 10
489
- },
388
+ projectPath: { type: "string" },
389
+ mode: { type: "string", enum: ["plan", "apply", "loop"], default: "plan" },
390
+ findingIds: { type: "array", items: { type: "string" } },
490
391
  },
491
392
  },
492
393
  },
@@ -730,12 +631,22 @@ Call BEFORE any file write operations.
730
631
  // TOOL HANDLERS
731
632
  // =============================================================================
732
633
 
634
+ /**
635
+ * Handle v3 tool execution with tier checking and ErrorEnvelope support
636
+ */
733
637
  export async function handleToolV3(toolName, args, context = {}) {
734
638
  const userTier = context.tier || 'free';
735
639
 
736
- const access = checkTierAccess(toolName, userTier);
640
+ // Check access with option-level gates
641
+ const access = checkTierAccess(toolName, userTier, args);
737
642
  if (!access.allowed) {
738
- return { error: access.error };
643
+ // Return proper ErrorEnvelope format
644
+ return {
645
+ ok: false,
646
+ error: access.error,
647
+ tier: userTier,
648
+ required: access.error?.required || 'pro',
649
+ };
739
650
  }
740
651
 
741
652
  const projectPath = args.projectPath || process.cwd();
@@ -779,11 +690,28 @@ export async function handleToolV3(toolName, args, context = {}) {
779
690
  case 'vibecheck_agent_firewall_intercept':
780
691
  return await handleFirewallIntercept(args, userTier);
781
692
 
693
+ case 'vibecheck.get_next_action':
694
+ return await handleGetNextAction(projectPath, userTier);
695
+
782
696
  default:
783
- return { error: `Unknown tool: ${toolName}` };
697
+ return {
698
+ ok: false,
699
+ error: {
700
+ code: 'TOOL_NOT_FOUND',
701
+ message: `Unknown tool: ${toolName}`,
702
+ retryable: false,
703
+ }
704
+ };
784
705
  }
785
706
  } catch (error) {
786
- return { error: error.message };
707
+ return {
708
+ ok: false,
709
+ error: {
710
+ code: 'INTERNAL_ERROR',
711
+ message: error.message,
712
+ retryable: true,
713
+ }
714
+ };
787
715
  }
788
716
  }
789
717
 
@@ -791,7 +719,10 @@ export async function handleToolV3(toolName, args, context = {}) {
791
719
  // IMPLEMENTATIONS
792
720
  // =============================================================================
793
721
 
794
- async function runCliCommand(projectPath, command, args) {
722
+ // Cacheable tools
723
+ const CACHEABLE_TOOLS = new Set(['scan', 'ship', 'polish', 'doctor']);
724
+
725
+ async function runCliCommand(projectPath, command, args, options = {}) {
795
726
  const flags = Object.entries(args)
796
727
  .filter(([k, v]) => k !== 'projectPath' && v !== undefined && v !== null)
797
728
  .map(([k, v]) => {
@@ -801,16 +732,50 @@ async function runCliCommand(projectPath, command, args) {
801
732
  })
802
733
  .filter(Boolean)
803
734
  .join(' ');
804
-
735
+
736
+ // Check if this tool supports caching
737
+ const isCacheable = CACHEABLE_TOOLS.has(command);
738
+ const useCache = isCacheable && options.useCache !== false && !args.noCache;
739
+
740
+ if (useCache) {
741
+ // Use cached execution
742
+ return executeCachedCliCommand(
743
+ projectPath,
744
+ command,
745
+ () => {
746
+ const result = execSync(
747
+ `npx vibecheck ${command} --json ${flags}`,
748
+ { cwd: projectPath, encoding: 'utf8', timeout: 300000 }
749
+ );
750
+ try {
751
+ return JSON.parse(result);
752
+ } catch {
753
+ return { output: result, findings: [], verdict: null, metadata: {} };
754
+ }
755
+ },
756
+ {
757
+ useCache: true,
758
+ forceRefresh: args.forceRefresh || false,
759
+ vibecheckVersion: '3.3.0',
760
+ }
761
+ );
762
+ }
763
+
764
+ // Non-cacheable execution
805
765
  const result = execSync(
806
766
  `npx vibecheck ${command} --json ${flags}`,
807
767
  { cwd: projectPath, encoding: 'utf8', timeout: 300000 }
808
768
  );
809
769
 
810
770
  try {
811
- return JSON.parse(result);
771
+ const parsed = JSON.parse(result);
772
+ // Add empty cacheStats for consistency
773
+ return {
774
+ ...parsed,
775
+ cacheStats: { hit: false, reusedFindingsCount: 0, durationMs: 0 },
776
+ };
812
777
  } catch {
813
- return { output: result };
778
+ return { output: result, cacheStats: { hit: false, reusedFindingsCount: 0, durationMs: 0 } };
814
779
  }
815
780
  }
816
781
 
@@ -832,99 +797,14 @@ async function verifyCode(args) {
832
797
  }
833
798
 
834
799
  async function firewallCheck(args, tier) {
835
- const requestedMode = args.mode || 'observe';
836
-
837
- // If user requests enforce but isn't PRO, fall back to observe
838
- const effectiveMode = requestedMode === 'enforce' && tier !== 'pro'
839
- ? 'observe'
840
- : requestedMode;
841
-
842
- const { action, path: filePath, content, command, projectPath } = args;
843
-
844
- try {
845
- // Import and use the firewall implementation
846
- const { runFirewallCheck } = await import('../bin/runners/runGuard.js');
847
-
848
- const result = await runFirewallCheck({
849
- mode: effectiveMode,
850
- action,
851
- path: filePath,
852
- content,
853
- command,
854
- configPath: projectPath ? `${projectPath}/.vibecheck/firewall.json` : undefined,
855
- });
856
-
857
- // Add tier information to result
858
- return {
859
- ...result,
860
- tier,
861
- modeRequested: requestedMode,
862
- modeEffective: effectiveMode,
863
- message: effectiveMode !== requestedMode
864
- ? 'Enforce mode requires PRO. Running in observe mode.'
865
- : undefined,
866
- };
867
- } catch (error) {
868
- // Fallback to basic check if import fails
869
- const violations = [];
870
-
871
- // Basic path check
872
- if (filePath) {
873
- const forbiddenPatterns = ['.env', 'secrets', '.pem', '.key', 'credentials'];
874
- for (const pattern of forbiddenPatterns) {
875
- if (filePath.toLowerCase().includes(pattern)) {
876
- violations.push({
877
- rule: 'forbidden-path',
878
- severity: 'critical',
879
- message: `Path "${filePath}" matches forbidden pattern "${pattern}"`,
880
- });
881
- }
882
- }
883
- }
884
-
885
- // Basic command check
886
- if (command) {
887
- const dangerousPatterns = ['rm -rf', 'curl | bash', 'DROP DATABASE'];
888
- for (const pattern of dangerousPatterns) {
889
- if (command.toLowerCase().includes(pattern.toLowerCase())) {
890
- violations.push({
891
- rule: 'dangerous-command',
892
- severity: 'critical',
893
- message: `Command contains dangerous pattern: "${pattern}"`,
894
- });
895
- }
896
- }
897
- }
898
-
899
- // Basic content check
900
- if (content) {
901
- const hallucinationPatterns = [
902
- { pattern: /example\.com/i, name: 'fake-api' },
903
- { pattern: /sk-[a-zA-Z0-9]{20,}/, name: 'fake-api-key' },
904
- { pattern: /your-api-key-here/i, name: 'placeholder' },
905
- ];
906
- for (const { pattern, name } of hallucinationPatterns) {
907
- if (pattern.test(content)) {
908
- violations.push({
909
- rule: 'hallucination-detected',
910
- severity: 'high',
911
- message: `Content contains hallucination pattern: ${name}`,
912
- });
913
- }
914
- }
915
- }
916
-
917
- const allowed = effectiveMode === 'observe' || violations.length === 0;
918
-
919
- return {
920
- allowed,
921
- mode: effectiveMode,
922
- violations,
923
- violationCount: violations.length,
924
- tier,
925
- fallbackMode: true,
926
- };
927
- }
800
+ const mode = tier === 'pro' ? 'enforce' : 'observe';
801
+ return {
802
+ mode,
803
+ checked: true,
804
+ message: mode === 'observe'
805
+ ? 'Agent Firewall in observe mode (FREE). Upgrade to PRO for enforce mode.'
806
+ : 'Agent Firewall in enforce mode (PRO).',
807
+ };
928
808
  }
929
809
 
930
810
  async function handleConductorTool(toolName, args, tier) {
@@ -968,61 +848,92 @@ async function handleConductorTool(toolName, args, tier) {
968
848
  }
969
849
 
970
850
  async function handleFirewallIntercept(args, tier) {
971
- const mode = tier === 'pro' ? 'enforce' : 'observe';
972
- const { agentId, filePath, content, operation, intent, projectRoot } = args;
851
+ if (tier !== 'pro') {
852
+ return {
853
+ allowed: true,
854
+ mode: 'observe',
855
+ message: 'Firewall intercept in observe mode (FREE). Changes logged but not blocked.',
856
+ violations: [],
857
+ };
858
+ }
973
859
 
860
+ // Import and delegate to firewall interceptor
974
861
  try {
975
- // Use the firewall implementation
976
- const { runFirewallCheck } = await import('../bin/runners/runGuard.js');
977
-
978
- const result = await runFirewallCheck({
979
- mode,
980
- action: operation || 'write',
981
- path: filePath,
982
- content,
983
- configPath: projectRoot ? `${projectRoot}/.vibecheck/firewall.json` : undefined,
984
- });
985
-
986
- // Log the intercept
987
- const logEntry = {
988
- timestamp: new Date().toISOString(),
989
- agentId,
990
- operation: operation || 'write',
991
- filePath,
992
- intent,
993
- allowed: result.allowed,
994
- mode,
995
- violations: result.violations,
996
- };
862
+ const { interceptFileWrite } = await import('./agent-firewall-interceptor.js');
863
+ return await interceptFileWrite(args);
864
+ } catch (error) {
865
+ return { error: `Firewall intercept failed: ${error.message}` };
866
+ }
867
+ }
868
+
869
+ /**
870
+ * Handle get_next_action tool - returns recommended next action based on project state
871
+ */
872
+ async function handleGetNextAction(projectPath, tier) {
873
+ try {
874
+ // Import the next-action module from CLI
875
+ const nextActionModule = require('../bin/runners/lib/next-action.js');
876
+ const result = nextActionModule.getNextActionJson(projectPath, tier);
997
877
 
998
- // Return enriched result
999
878
  return {
1000
- ...result,
1001
- mode,
1002
- agentId,
1003
- operation: operation || 'write',
1004
- filePath,
1005
- interceptLog: logEntry,
1006
- proofArtifact: result.violations.length > 0 ? {
1007
- type: 'firewall-intercept',
1008
- timestamp: logEntry.timestamp,
1009
- violations: result.violations,
1010
- blocked: !result.allowed,
1011
- } : undefined,
879
+ ok: true,
880
+ data: result,
1012
881
  };
1013
882
  } catch (error) {
1014
- // Fallback behavior
1015
- if (tier !== 'pro') {
1016
- return {
1017
- allowed: true,
1018
- mode: 'observe',
1019
- message: 'Firewall intercept in observe mode (FREE). Changes logged but not blocked.',
1020
- violations: [],
1021
- agentId,
1022
- filePath,
1023
- };
883
+ // Fallback: compute basic next action without the module
884
+ const statePath = path.join(projectPath, '.vibecheck', 'summary.json');
885
+ let state = { hasConfig: false, lastScan: null, lastShip: null };
886
+
887
+ try {
888
+ await fs.access(path.join(projectPath, '.vibecheckrc'));
889
+ state.hasConfig = true;
890
+ } catch {}
891
+
892
+ try {
893
+ const summary = JSON.parse(await fs.readFile(statePath, 'utf-8'));
894
+ state.lastScan = { verdict: summary.verdict, score: summary.score };
895
+ } catch {}
896
+
897
+ // Basic next action logic
898
+ let action, command, why;
899
+
900
+ if (!state.hasConfig) {
901
+ action = 'init';
902
+ command = 'vibecheck init';
903
+ why = 'Project not initialized. Run init to create config.';
904
+ } else if (!state.lastScan) {
905
+ action = 'scan';
906
+ command = 'vibecheck scan';
907
+ why = 'No scans yet. Run your first scan.';
908
+ } else if (tier === 'pro') {
909
+ action = 'ship';
910
+ command = 'vibecheck ship';
911
+ why = 'Get your SHIP/WARN/BLOCK verdict.';
912
+ } else {
913
+ action = 'report';
914
+ command = 'vibecheck report';
915
+ why = 'Generate a report of your scan results.';
1024
916
  }
1025
- return { error: `Firewall intercept failed: ${error.message}` };
917
+
918
+ return {
919
+ ok: true,
920
+ data: {
921
+ action,
922
+ command,
923
+ cliCommand: command,
924
+ why,
925
+ dashboardLink: 'https://app.vibecheckai.dev',
926
+ docsLink: `https://docs.vibecheckai.dev/cli/${action}`,
927
+ timeEstimate: action === 'scan' ? '~45 seconds' : '~15 seconds',
928
+ requiredTier: action === 'ship' ? 'pro' : 'free',
929
+ priority: 'high',
930
+ upgradeHint: tier === 'free' && action === 'report' ? {
931
+ feature: 'Ship Verdict',
932
+ benefit: 'Get SHIP/WARN/BLOCK verdict with evidence',
933
+ url: 'https://vibecheckai.dev/pricing',
934
+ } : null,
935
+ },
936
+ };
1026
937
  }
1027
938
  }
1028
939