@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.
- package/bin/registry.js +214 -237
- package/bin/runners/cli-utils.js +33 -2
- package/bin/runners/context/analyzer.js +52 -1
- package/bin/runners/context/generators/cursor.js +2 -49
- package/bin/runners/context/git-context.js +3 -1
- package/bin/runners/context/team-conventions.js +33 -7
- package/bin/runners/lib/analysis-core.js +25 -5
- package/bin/runners/lib/analyzers.js +431 -481
- package/bin/runners/lib/default-config.js +127 -0
- package/bin/runners/lib/doctor/modules/security.js +3 -1
- package/bin/runners/lib/engine/ast-cache.js +210 -0
- package/bin/runners/lib/engine/auth-extractor.js +211 -0
- package/bin/runners/lib/engine/billing-extractor.js +112 -0
- package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
- package/bin/runners/lib/engine/env-extractor.js +207 -0
- package/bin/runners/lib/engine/express-extractor.js +208 -0
- package/bin/runners/lib/engine/extractors.js +849 -0
- package/bin/runners/lib/engine/index.js +207 -0
- package/bin/runners/lib/engine/repo-index.js +514 -0
- package/bin/runners/lib/engine/types.js +124 -0
- package/bin/runners/lib/engines/accessibility-engine.js +18 -218
- package/bin/runners/lib/engines/api-consistency-engine.js +30 -335
- package/bin/runners/lib/engines/cross-file-analysis-engine.js +27 -292
- package/bin/runners/lib/engines/empty-catch-engine.js +17 -127
- package/bin/runners/lib/engines/mock-data-engine.js +10 -53
- package/bin/runners/lib/engines/performance-issues-engine.js +36 -176
- package/bin/runners/lib/engines/security-vulnerabilities-engine.js +54 -382
- package/bin/runners/lib/engines/type-aware-engine.js +39 -263
- package/bin/runners/lib/engines/vibecheck-engines/index.js +13 -122
- package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +73 -373
- package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
- package/bin/runners/lib/entitlements-v2.js +73 -97
- package/bin/runners/lib/error-handler.js +44 -3
- package/bin/runners/lib/error-messages.js +289 -0
- package/bin/runners/lib/evidence-pack.js +7 -1
- package/bin/runners/lib/finding-id.js +69 -0
- package/bin/runners/lib/finding-sorter.js +89 -0
- package/bin/runners/lib/html-proof-report.js +700 -350
- package/bin/runners/lib/missions/plan.js +6 -46
- package/bin/runners/lib/missions/templates.js +0 -232
- package/bin/runners/lib/next-action.js +560 -0
- package/bin/runners/lib/prerequisites.js +149 -0
- package/bin/runners/lib/route-detection.js +137 -68
- package/bin/runners/lib/scan-output.js +91 -76
- package/bin/runners/lib/scan-runner.js +135 -0
- package/bin/runners/lib/schemas/ajv-validator.js +464 -0
- package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
- package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
- package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
- package/bin/runners/lib/schemas/run-request.schema.json +108 -0
- package/bin/runners/lib/schemas/validator.js +27 -0
- package/bin/runners/lib/schemas/verdict.schema.json +140 -0
- package/bin/runners/lib/ship-output-enterprise.js +23 -23
- package/bin/runners/lib/ship-output.js +75 -31
- package/bin/runners/lib/terminal-ui.js +6 -113
- package/bin/runners/lib/truth.js +351 -10
- package/bin/runners/lib/unified-cli-output.js +430 -603
- package/bin/runners/lib/unified-output.js +13 -9
- package/bin/runners/runAIAgent.js +10 -5
- package/bin/runners/runAgent.js +0 -3
- package/bin/runners/runAllowlist.js +389 -0
- package/bin/runners/runApprove.js +0 -33
- package/bin/runners/runAuth.js +73 -45
- package/bin/runners/runCheckpoint.js +51 -11
- package/bin/runners/runClassify.js +85 -21
- package/bin/runners/runContext.js +0 -3
- package/bin/runners/runDoctor.js +41 -28
- package/bin/runners/runEvidencePack.js +362 -0
- package/bin/runners/runFirewall.js +0 -3
- package/bin/runners/runFirewallHook.js +0 -3
- package/bin/runners/runFix.js +66 -76
- package/bin/runners/runGuard.js +18 -411
- package/bin/runners/runInit.js +113 -30
- package/bin/runners/runLabs.js +424 -0
- package/bin/runners/runMcp.js +19 -25
- package/bin/runners/runPolish.js +64 -240
- package/bin/runners/runPromptFirewall.js +12 -5
- package/bin/runners/runProve.js +57 -22
- package/bin/runners/runQuickstart.js +531 -0
- package/bin/runners/runReality.js +59 -68
- package/bin/runners/runReport.js +38 -33
- package/bin/runners/runRuntime.js +8 -5
- package/bin/runners/runScan.js +1413 -190
- package/bin/runners/runShip.js +113 -719
- package/bin/runners/runTruth.js +0 -3
- package/bin/runners/runValidate.js +13 -9
- package/bin/runners/runWatch.js +23 -14
- package/bin/scan.js +6 -1
- package/bin/vibecheck.js +204 -185
- package/mcp-server/deprecation-middleware.js +282 -0
- package/mcp-server/handlers/index.ts +15 -0
- package/mcp-server/handlers/tool-handler.ts +554 -0
- package/mcp-server/index-v1.js +698 -0
- package/mcp-server/index.js +210 -238
- package/mcp-server/lib/cache-wrapper.cjs +383 -0
- package/mcp-server/lib/error-envelope.js +138 -0
- package/mcp-server/lib/executor.ts +499 -0
- package/mcp-server/lib/index.ts +19 -0
- package/mcp-server/lib/rate-limiter.js +166 -0
- package/mcp-server/lib/sandbox.test.ts +519 -0
- package/mcp-server/lib/sandbox.ts +395 -0
- package/mcp-server/lib/types.ts +267 -0
- package/mcp-server/package.json +12 -3
- package/mcp-server/registry/tool-registry.js +794 -0
- package/mcp-server/registry/tools.json +605 -0
- package/mcp-server/registry.test.ts +334 -0
- package/mcp-server/tests/tier-gating.test.js +297 -0
- package/mcp-server/tier-auth.js +378 -45
- package/mcp-server/tools-v3.js +353 -442
- package/mcp-server/tsconfig.json +37 -0
- package/mcp-server/vibecheck-2.0-tools.js +14 -1
- package/package.json +1 -1
- package/bin/runners/lib/agent-firewall/learning/learning-engine.js +0 -849
- package/bin/runners/lib/audit-logger.js +0 -532
- package/bin/runners/lib/authority/authorities/architecture.js +0 -364
- package/bin/runners/lib/authority/authorities/compliance.js +0 -341
- package/bin/runners/lib/authority/authorities/human.js +0 -343
- package/bin/runners/lib/authority/authorities/quality.js +0 -420
- package/bin/runners/lib/authority/authorities/security.js +0 -228
- package/bin/runners/lib/authority/index.js +0 -293
- package/bin/runners/lib/bundle/bundle-intelligence.js +0 -846
- package/bin/runners/lib/cli-charts.js +0 -368
- package/bin/runners/lib/cli-config-display.js +0 -405
- package/bin/runners/lib/cli-demo.js +0 -275
- package/bin/runners/lib/cli-errors.js +0 -438
- package/bin/runners/lib/cli-help-formatter.js +0 -439
- package/bin/runners/lib/cli-interactive-menu.js +0 -509
- package/bin/runners/lib/cli-prompts.js +0 -441
- package/bin/runners/lib/cli-scan-cards.js +0 -362
- package/bin/runners/lib/compliance-reporter.js +0 -710
- package/bin/runners/lib/conductor/index.js +0 -671
- package/bin/runners/lib/easy/README.md +0 -123
- package/bin/runners/lib/easy/index.js +0 -140
- package/bin/runners/lib/easy/interactive-wizard.js +0 -788
- package/bin/runners/lib/easy/one-click-firewall.js +0 -564
- package/bin/runners/lib/easy/zero-config-reality.js +0 -714
- package/bin/runners/lib/engines/async-patterns-engine.js +0 -444
- package/bin/runners/lib/engines/bundle-size-engine.js +0 -433
- package/bin/runners/lib/engines/confidence-scoring.js +0 -276
- package/bin/runners/lib/engines/context-detection.js +0 -264
- package/bin/runners/lib/engines/database-patterns-engine.js +0 -429
- package/bin/runners/lib/engines/duplicate-code-engine.js +0 -354
- package/bin/runners/lib/engines/env-variables-engine.js +0 -458
- package/bin/runners/lib/engines/error-handling-engine.js +0 -437
- package/bin/runners/lib/engines/false-positive-prevention.js +0 -630
- package/bin/runners/lib/engines/framework-adapters/index.js +0 -607
- package/bin/runners/lib/engines/framework-detection.js +0 -508
- package/bin/runners/lib/engines/import-order-engine.js +0 -429
- package/bin/runners/lib/engines/naming-conventions-engine.js +0 -544
- package/bin/runners/lib/engines/noise-reduction-engine.js +0 -452
- package/bin/runners/lib/engines/orchestrator.js +0 -334
- package/bin/runners/lib/engines/react-patterns-engine.js +0 -457
- package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +0 -806
- package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +0 -577
- package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +0 -543
- package/bin/runners/lib/engines/vibecheck-engines.js +0 -514
- package/bin/runners/lib/enhanced-features/index.js +0 -305
- package/bin/runners/lib/enhanced-output.js +0 -631
- package/bin/runners/lib/enterprise.js +0 -300
- package/bin/runners/lib/firewall/command-validator.js +0 -351
- package/bin/runners/lib/firewall/config.js +0 -341
- package/bin/runners/lib/firewall/content-validator.js +0 -519
- package/bin/runners/lib/firewall/index.js +0 -101
- package/bin/runners/lib/firewall/path-validator.js +0 -256
- package/bin/runners/lib/intelligence/cross-repo-intelligence.js +0 -817
- package/bin/runners/lib/mcp-utils.js +0 -425
- package/bin/runners/lib/output/index.js +0 -1022
- package/bin/runners/lib/policy-engine.js +0 -652
- package/bin/runners/lib/polish/autofix/accessibility-fixes.js +0 -333
- package/bin/runners/lib/polish/autofix/async-handlers.js +0 -273
- package/bin/runners/lib/polish/autofix/dead-code.js +0 -280
- package/bin/runners/lib/polish/autofix/imports-optimizer.js +0 -344
- package/bin/runners/lib/polish/autofix/index.js +0 -200
- package/bin/runners/lib/polish/autofix/remove-consoles.js +0 -209
- package/bin/runners/lib/polish/autofix/strengthen-types.js +0 -245
- package/bin/runners/lib/polish/backend-checks.js +0 -148
- package/bin/runners/lib/polish/documentation-checks.js +0 -111
- package/bin/runners/lib/polish/frontend-checks.js +0 -168
- package/bin/runners/lib/polish/index.js +0 -71
- package/bin/runners/lib/polish/infrastructure-checks.js +0 -131
- package/bin/runners/lib/polish/library-detection.js +0 -175
- package/bin/runners/lib/polish/performance-checks.js +0 -100
- package/bin/runners/lib/polish/security-checks.js +0 -148
- package/bin/runners/lib/polish/utils.js +0 -203
- package/bin/runners/lib/prompt-builder.js +0 -540
- package/bin/runners/lib/proof-certificate.js +0 -634
- package/bin/runners/lib/reality/accessibility-audit.js +0 -946
- package/bin/runners/lib/reality/api-contract-validator.js +0 -1012
- package/bin/runners/lib/reality/chaos-engineering.js +0 -1084
- package/bin/runners/lib/reality/performance-tracker.js +0 -1077
- package/bin/runners/lib/reality/scenario-generator.js +0 -1404
- package/bin/runners/lib/reality/visual-regression.js +0 -852
- package/bin/runners/lib/reality-profiler.js +0 -717
- package/bin/runners/lib/replay/flight-recorder-viewer.js +0 -1160
- package/bin/runners/lib/review/ai-code-review.js +0 -832
- package/bin/runners/lib/rules/custom-rule-engine.js +0 -985
- package/bin/runners/lib/sbom-generator.js +0 -641
- package/bin/runners/lib/scan-output-enhanced.js +0 -512
- package/bin/runners/lib/security/owasp-scanner.js +0 -939
- package/bin/runners/lib/validators/contract-validator.js +0 -283
- package/bin/runners/lib/validators/dead-export-detector.js +0 -279
- package/bin/runners/lib/validators/dep-audit.js +0 -245
- package/bin/runners/lib/validators/env-validator.js +0 -319
- package/bin/runners/lib/validators/index.js +0 -120
- package/bin/runners/lib/validators/license-checker.js +0 -252
- package/bin/runners/lib/validators/route-validator.js +0 -290
- package/bin/runners/runAuthority.js +0 -528
- package/bin/runners/runConductor.js +0 -772
- package/bin/runners/runContainer.js +0 -366
- package/bin/runners/runEasy.js +0 -410
- package/bin/runners/runIaC.js +0 -372
- package/bin/runners/runVibe.js +0 -791
- package/mcp-server/tools.js +0 -495
package/mcp-server/tier-auth.js
CHANGED
|
@@ -1,14 +1,42 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP Server Tier Authentication
|
|
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
|
|
6
10
|
* - PRO ($69/mo): Fix, Prove & Enforce
|
|
7
11
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
+
* ┌────────────────────────────────────────────────────────────────────────┐
|
|
13
|
+
* │ MCP Tool │ Tier │ CLI Equivalent │
|
|
14
|
+
* ├────────────────────────────────────────────────────────────────────────┤
|
|
15
|
+
* │ vibecheck.scan │ FREE │ scan │
|
|
16
|
+
* │ vibecheck.scan (--autofix) │ PRO │ scan.autofix │
|
|
17
|
+
* │ vibecheck.ctx │ FREE │ ctx │
|
|
18
|
+
* │ vibecheck.verify │ FREE │ verify │
|
|
19
|
+
* │ vibecheck.report │ FREE │ report │
|
|
20
|
+
* │ vibecheck.status │ FREE │ status │
|
|
21
|
+
* │ vibecheck.doctor │ FREE │ doctor │
|
|
22
|
+
* │ vibecheck.firewall (observe) │ FREE │ firewall.observe │
|
|
23
|
+
* │ vibecheck.firewall (enforce) │ PRO │ firewall.enforce │
|
|
24
|
+
* │ vibecheck.ship │ PRO │ ship │
|
|
25
|
+
* │ vibecheck.fix │ PRO │ fix │
|
|
26
|
+
* │ vibecheck.fix (--apply) │ PRO │ fix.apply │
|
|
27
|
+
* │ vibecheck.prove │ PRO │ prove │
|
|
28
|
+
* │ vibecheck.gate │ PRO │ gate │
|
|
29
|
+
* │ vibecheck.badge │ PRO │ badge │
|
|
30
|
+
* │ vibecheck.reality │ PRO │ reality.full │
|
|
31
|
+
* │ vibecheck.ai_test │ PRO │ ai-test │
|
|
32
|
+
* │ vibecheck.share │ PRO │ share │
|
|
33
|
+
* │ authority.list │ FREE │ (read-only authority) │
|
|
34
|
+
* │ authority.classify │ FREE │ (inventory analysis) │
|
|
35
|
+
* │ authority.approve │ PRO │ (execute authority) │
|
|
36
|
+
* │ vibecheck_conductor_status │ FREE │ (status only) │
|
|
37
|
+
* │ vibecheck_conductor_* │ PRO │ (full coordination) │
|
|
38
|
+
* │ vibecheck_agent_firewall_* │ PRO │ (enforce mode) │
|
|
39
|
+
* └────────────────────────────────────────────────────────────────────────┘
|
|
12
40
|
*/
|
|
13
41
|
|
|
14
42
|
import fs from "fs/promises";
|
|
@@ -16,7 +44,17 @@ import path from "path";
|
|
|
16
44
|
import os from "os";
|
|
17
45
|
|
|
18
46
|
// ============================================================================
|
|
19
|
-
//
|
|
47
|
+
// ERROR CODES - Standard error envelope codes
|
|
48
|
+
// ============================================================================
|
|
49
|
+
export const ERROR_CODES = {
|
|
50
|
+
NOT_ENTITLED: 'NOT_ENTITLED',
|
|
51
|
+
INVALID_API_KEY: 'INVALID_API_KEY',
|
|
52
|
+
RATE_LIMITED: 'RATE_LIMITED',
|
|
53
|
+
OPTION_NOT_ENTITLED: 'OPTION_NOT_ENTITLED',
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// TIERS - Simple 2-tier model matching CLI
|
|
20
58
|
// ============================================================================
|
|
21
59
|
export const TIERS = {
|
|
22
60
|
free: { name: 'FREE', price: 0 },
|
|
@@ -24,43 +62,68 @@ export const TIERS = {
|
|
|
24
62
|
};
|
|
25
63
|
|
|
26
64
|
// ============================================================================
|
|
27
|
-
// MCP TOOLS -
|
|
65
|
+
// MCP TOOLS - Aligned with CLI entitlements-v2.js
|
|
28
66
|
// ============================================================================
|
|
29
67
|
|
|
30
68
|
/**
|
|
31
|
-
* FREE TOOLS
|
|
69
|
+
* FREE TOOLS - Inspect & Observe
|
|
70
|
+
* Matches CLI FREE_FEATURES: scan, ctx, verify, report, status, doctor, etc.
|
|
32
71
|
*/
|
|
33
72
|
export const FREE_TOOLS = [
|
|
34
|
-
// Core
|
|
73
|
+
// Core analysis (CLI: scan, ctx, verify)
|
|
35
74
|
'vibecheck.scan',
|
|
36
75
|
'vibecheck.ctx',
|
|
37
76
|
'vibecheck.verify',
|
|
77
|
+
|
|
78
|
+
// Reports & setup (CLI: report, status, doctor)
|
|
38
79
|
'vibecheck.report',
|
|
39
80
|
'vibecheck.status',
|
|
40
81
|
'vibecheck.doctor',
|
|
41
|
-
|
|
82
|
+
|
|
83
|
+
// Firewall observe mode (CLI: firewall.observe)
|
|
84
|
+
'vibecheck.firewall',
|
|
85
|
+
|
|
42
86
|
// Authority (read-only)
|
|
43
87
|
'authority.list',
|
|
44
88
|
'authority.classify',
|
|
89
|
+
|
|
45
90
|
// Conductor (status only)
|
|
46
91
|
'vibecheck_conductor_status',
|
|
92
|
+
|
|
93
|
+
// Labs & experimental (CLI: labs, mdc)
|
|
94
|
+
'vibecheck.labs',
|
|
95
|
+
'vibecheck.mdc',
|
|
96
|
+
|
|
97
|
+
// Allowlist management
|
|
98
|
+
'vibecheck.allowlist',
|
|
99
|
+
|
|
100
|
+
// Context generation (basic - CLI: ctx)
|
|
101
|
+
'vibecheck.context',
|
|
102
|
+
|
|
103
|
+
// Next action recommendation
|
|
104
|
+
'vibecheck.get_next_action',
|
|
47
105
|
];
|
|
48
106
|
|
|
49
107
|
/**
|
|
50
|
-
* PRO TOOLS
|
|
108
|
+
* PRO TOOLS - Fix, Prove & Enforce
|
|
109
|
+
* Matches CLI PRO_FEATURES: ship, fix, prove, gate, badge, etc.
|
|
51
110
|
*/
|
|
52
111
|
export const PRO_TOOLS = [
|
|
53
|
-
// Core PRO
|
|
112
|
+
// Core PRO (CLI: ship, fix, prove, gate, badge)
|
|
54
113
|
'vibecheck.ship',
|
|
55
114
|
'vibecheck.fix',
|
|
56
115
|
'vibecheck.prove',
|
|
57
116
|
'vibecheck.gate',
|
|
58
117
|
'vibecheck.badge',
|
|
118
|
+
|
|
119
|
+
// Runtime verification (CLI: reality.full, ai-test)
|
|
59
120
|
'vibecheck.reality',
|
|
60
121
|
'vibecheck.ai_test',
|
|
122
|
+
|
|
123
|
+
// Sharing & PR (CLI: share, pr)
|
|
61
124
|
'vibecheck.share',
|
|
62
125
|
|
|
63
|
-
// Authority System (full)
|
|
126
|
+
// Authority System (full - execute verdicts)
|
|
64
127
|
'authority.approve',
|
|
65
128
|
'authority.enforce',
|
|
66
129
|
|
|
@@ -71,31 +134,158 @@ export const PRO_TOOLS = [
|
|
|
71
134
|
'vibecheck_conductor_propose',
|
|
72
135
|
'vibecheck_conductor_terminate',
|
|
73
136
|
|
|
74
|
-
// Agent Firewall (enforce mode)
|
|
137
|
+
// Agent Firewall (enforce mode - CLI: firewall.enforce)
|
|
75
138
|
'vibecheck_agent_firewall_intercept',
|
|
76
139
|
'vibecheck.firewall.enforce',
|
|
140
|
+
|
|
141
|
+
// Advanced features (CLI: checkpoint, polish, guard)
|
|
142
|
+
'vibecheck.checkpoint',
|
|
143
|
+
'vibecheck.polish',
|
|
144
|
+
'vibecheck.guard',
|
|
77
145
|
];
|
|
78
146
|
|
|
79
147
|
export const ALL_TOOLS = [...FREE_TOOLS, ...PRO_TOOLS];
|
|
80
148
|
|
|
149
|
+
/**
|
|
150
|
+
* OPTION-LEVEL GATES
|
|
151
|
+
* Some tools are FREE at base level but specific options require PRO
|
|
152
|
+
*/
|
|
153
|
+
export const OPTION_GATES = {
|
|
154
|
+
'vibecheck.scan': {
|
|
155
|
+
autofix: 'pro', // scan --autofix requires PRO
|
|
156
|
+
fix: 'pro', // scan --fix requires PRO
|
|
157
|
+
},
|
|
158
|
+
'vibecheck.fix': {
|
|
159
|
+
apply: 'pro', // fix --apply requires PRO (plan is PRO too)
|
|
160
|
+
loop: 'pro', // fix --loop requires PRO
|
|
161
|
+
},
|
|
162
|
+
'vibecheck.firewall': {
|
|
163
|
+
enforce: 'pro', // firewall --enforce requires PRO
|
|
164
|
+
mode: { enforce: 'pro' },
|
|
165
|
+
},
|
|
166
|
+
'vibecheck.reality': {
|
|
167
|
+
full: 'pro', // reality full mode requires PRO
|
|
168
|
+
auth: 'pro', // auth boundary testing requires PRO
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
|
|
81
172
|
// ============================================================================
|
|
82
173
|
// TIER CACHE
|
|
83
174
|
// ============================================================================
|
|
84
175
|
const tierCache = new Map();
|
|
85
176
|
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
|
|
86
177
|
|
|
178
|
+
/**
|
|
179
|
+
* Check if developer mode bypass is allowed.
|
|
180
|
+
*
|
|
181
|
+
* SECURITY: VIBECHECK_DEV_PRO is ONLY allowed in non-production environments.
|
|
182
|
+
* This prevents environment variable injection from granting PRO access in production.
|
|
183
|
+
*
|
|
184
|
+
* @returns {{ enabled: boolean, tier?: string }} Dev override status
|
|
185
|
+
*/
|
|
186
|
+
export function getDevModeOverride() {
|
|
187
|
+
// SECURITY: Never allow dev override in production
|
|
188
|
+
if (process.env.NODE_ENV === 'production') {
|
|
189
|
+
return { enabled: false };
|
|
190
|
+
}
|
|
191
|
+
// Also block in CI environments to prevent pipeline exploitation
|
|
192
|
+
if (process.env.CI === 'true' || process.env.CI === '1') {
|
|
193
|
+
return { enabled: false };
|
|
194
|
+
}
|
|
195
|
+
// Only in development with explicit flag
|
|
196
|
+
if (process.env.VIBECHECK_DEV_PRO === '1' && process.env.NODE_ENV === 'development') {
|
|
197
|
+
console.warn('[DEV] VIBECHECK_DEV_PRO override active - PRO features unlocked');
|
|
198
|
+
return { enabled: true, tier: 'pro' };
|
|
199
|
+
}
|
|
200
|
+
return { enabled: false };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Check if developer mode bypass is allowed (legacy function for backward compatibility)
|
|
205
|
+
* @returns {boolean} True only if in development AND VIBECHECK_DEV_PRO=1
|
|
206
|
+
*/
|
|
207
|
+
function isDevProBypassAllowed() {
|
|
208
|
+
return getDevModeOverride().enabled;
|
|
209
|
+
}
|
|
210
|
+
|
|
87
211
|
function hashKey(apiKey) {
|
|
88
212
|
const crypto = require('crypto');
|
|
89
213
|
return crypto.createHash('sha256').update(apiKey).digest('hex').slice(0, 16);
|
|
90
214
|
}
|
|
91
215
|
|
|
216
|
+
// ============================================================================
|
|
217
|
+
// ERROR ENVELOPE - Standard format for tier errors
|
|
218
|
+
// ============================================================================
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Create a standard ErrorEnvelope for tier-related errors
|
|
222
|
+
* @param {string} code - Error code (NOT_ENTITLED, INVALID_API_KEY, etc.)
|
|
223
|
+
* @param {string} message - Human-readable error message
|
|
224
|
+
* @param {object} extra - Additional properties
|
|
225
|
+
* @returns {object} ErrorEnvelope
|
|
226
|
+
*/
|
|
227
|
+
export function createTierErrorEnvelope(code, message, extra = {}) {
|
|
228
|
+
return {
|
|
229
|
+
code,
|
|
230
|
+
message,
|
|
231
|
+
userAction: extra.userAction || 'Open billing',
|
|
232
|
+
retryable: extra.retryable ?? false,
|
|
233
|
+
tier: extra.tier,
|
|
234
|
+
required: extra.required,
|
|
235
|
+
upgradeUrl: 'https://vibecheckai.dev/pricing',
|
|
236
|
+
...extra,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Create NOT_ENTITLED error envelope
|
|
242
|
+
*/
|
|
243
|
+
export function notEntitledError(toolName, currentTier = 'free', requiredTier = 'pro') {
|
|
244
|
+
return createTierErrorEnvelope(ERROR_CODES.NOT_ENTITLED, `Requires ${requiredTier.toUpperCase()}`, {
|
|
245
|
+
tier: currentTier,
|
|
246
|
+
required: requiredTier,
|
|
247
|
+
tool: toolName,
|
|
248
|
+
userAction: 'Open billing',
|
|
249
|
+
retryable: false,
|
|
250
|
+
nextSteps: [
|
|
251
|
+
`Upgrade to ${requiredTier.toUpperCase()} ($69/mo) to unlock this feature`,
|
|
252
|
+
'Visit https://vibecheckai.dev/pricing',
|
|
253
|
+
'Run: vibecheck upgrade',
|
|
254
|
+
],
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Create OPTION_NOT_ENTITLED error envelope
|
|
260
|
+
*/
|
|
261
|
+
export function optionNotEntitledError(toolName, option, currentTier = 'free', requiredTier = 'pro') {
|
|
262
|
+
return createTierErrorEnvelope(ERROR_CODES.OPTION_NOT_ENTITLED, `Option --${option} requires ${requiredTier.toUpperCase()}`, {
|
|
263
|
+
tier: currentTier,
|
|
264
|
+
required: requiredTier,
|
|
265
|
+
tool: toolName,
|
|
266
|
+
option,
|
|
267
|
+
userAction: 'Open billing',
|
|
268
|
+
retryable: false,
|
|
269
|
+
nextSteps: [
|
|
270
|
+
`The --${option} flag requires ${requiredTier.toUpperCase()} subscription`,
|
|
271
|
+
`Base ${toolName} is available on FREE tier`,
|
|
272
|
+
'Visit https://vibecheckai.dev/pricing to upgrade',
|
|
273
|
+
],
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
92
277
|
// ============================================================================
|
|
93
278
|
// TIER VALIDATION
|
|
94
279
|
// ============================================================================
|
|
95
280
|
|
|
96
281
|
export async function getTierFromApiKey(apiKey) {
|
|
282
|
+
// Developer mode bypass (blocked in production)
|
|
283
|
+
if (isDevProBypassAllowed()) {
|
|
284
|
+
return 'pro';
|
|
285
|
+
}
|
|
286
|
+
|
|
97
287
|
if (!apiKey || typeof apiKey !== 'string' || apiKey.length < 10) {
|
|
98
|
-
return null
|
|
288
|
+
return 'free'; // No API key = free tier (not null)
|
|
99
289
|
}
|
|
100
290
|
|
|
101
291
|
const keyHash = hashKey(apiKey);
|
|
@@ -109,28 +299,30 @@ export async function getTierFromApiKey(apiKey) {
|
|
|
109
299
|
|
|
110
300
|
// Validate with API
|
|
111
301
|
try {
|
|
112
|
-
const response = await fetch('https://api.vibecheckai.dev/whoami', {
|
|
302
|
+
const response = await fetch('https://api.vibecheckai.dev/v1/auth/whoami', {
|
|
113
303
|
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
114
304
|
signal: AbortSignal.timeout(10000),
|
|
115
305
|
});
|
|
116
306
|
|
|
117
307
|
if (!response.ok) {
|
|
118
|
-
|
|
308
|
+
// Invalid key - default to free
|
|
309
|
+
tierCache.set(keyHash, { tier: 'free', expiresAt: now + 60000 }); // Short cache for invalid
|
|
310
|
+
return 'free';
|
|
119
311
|
}
|
|
120
312
|
|
|
121
313
|
const data = await response.json();
|
|
122
|
-
const plan = data.plan?.toLowerCase() || 'free';
|
|
314
|
+
const plan = data.plan?.toLowerCase() || data.tier?.toLowerCase() || 'free';
|
|
123
315
|
|
|
124
|
-
//
|
|
316
|
+
// Map any paid plan to 'pro' (STARTER, PRO, ENTERPRISE all = pro)
|
|
125
317
|
const tier = (plan === 'free') ? 'free' : 'pro';
|
|
126
318
|
|
|
127
319
|
tierCache.set(keyHash, { tier, expiresAt: now + CACHE_TTL });
|
|
128
320
|
return tier;
|
|
129
321
|
|
|
130
322
|
} catch {
|
|
131
|
-
// Network error - check stale cache
|
|
323
|
+
// Network error - check stale cache or default to free
|
|
132
324
|
if (cached) return cached.tier;
|
|
133
|
-
return
|
|
325
|
+
return 'free';
|
|
134
326
|
}
|
|
135
327
|
}
|
|
136
328
|
|
|
@@ -139,10 +331,15 @@ export async function getTierFromApiKey(apiKey) {
|
|
|
139
331
|
// ============================================================================
|
|
140
332
|
|
|
141
333
|
export function isPro(tier) {
|
|
334
|
+
// Developer mode bypass (blocked in production)
|
|
335
|
+
if (isDevProBypassAllowed()) return true;
|
|
142
336
|
return tier === 'pro';
|
|
143
337
|
}
|
|
144
338
|
|
|
145
339
|
export function canAccessTool(tier, toolName) {
|
|
340
|
+
// Developer mode bypass (blocked in production)
|
|
341
|
+
if (isDevProBypassAllowed()) return true;
|
|
342
|
+
|
|
146
343
|
// PRO gets everything
|
|
147
344
|
if (tier === 'pro') return true;
|
|
148
345
|
|
|
@@ -150,59 +347,110 @@ export function canAccessTool(tier, toolName) {
|
|
|
150
347
|
return FREE_TOOLS.includes(toolName);
|
|
151
348
|
}
|
|
152
349
|
|
|
350
|
+
/**
|
|
351
|
+
* Check option-level access
|
|
352
|
+
* @param {string} tier - User tier
|
|
353
|
+
* @param {string} toolName - Tool name
|
|
354
|
+
* @param {object} args - Tool arguments
|
|
355
|
+
* @returns {{ allowed: boolean, blockedOption?: string, required?: string }}
|
|
356
|
+
*/
|
|
357
|
+
export function checkOptionAccess(tier, toolName, args) {
|
|
358
|
+
// Developer mode (blocked in production) or PRO = full access
|
|
359
|
+
if (isDevProBypassAllowed() || tier === 'pro') {
|
|
360
|
+
return { allowed: true };
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const gates = OPTION_GATES[toolName];
|
|
364
|
+
if (!gates || !args) {
|
|
365
|
+
return { allowed: true };
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Check each gated option
|
|
369
|
+
for (const [option, requiredTier] of Object.entries(gates)) {
|
|
370
|
+
// Handle nested object gates (e.g., mode: { enforce: 'pro' })
|
|
371
|
+
if (typeof requiredTier === 'object') {
|
|
372
|
+
const argValue = args[option];
|
|
373
|
+
if (argValue && requiredTier[argValue] === 'pro') {
|
|
374
|
+
return { allowed: false, blockedOption: `${option}=${argValue}`, required: 'pro' };
|
|
375
|
+
}
|
|
376
|
+
} else if (args[option] === true && requiredTier === 'pro') {
|
|
377
|
+
return { allowed: false, blockedOption: option, required: 'pro' };
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return { allowed: true };
|
|
382
|
+
}
|
|
383
|
+
|
|
153
384
|
/**
|
|
154
385
|
* Get firewall mode based on tier
|
|
155
386
|
* - FREE: observe (log only)
|
|
156
387
|
* - PRO: enforce (block violations)
|
|
157
388
|
*/
|
|
158
389
|
export function getFirewallMode(tier) {
|
|
390
|
+
if (isDevProBypassAllowed()) return 'enforce';
|
|
159
391
|
return tier === 'pro' ? 'enforce' : 'observe';
|
|
160
392
|
}
|
|
161
393
|
|
|
162
394
|
/**
|
|
163
395
|
* Check if user can use full conductor features
|
|
164
396
|
*/
|
|
165
|
-
export function
|
|
397
|
+
export function canUseConductor(tier) {
|
|
398
|
+
if (isDevProBypassAllowed()) return true;
|
|
166
399
|
return tier === 'pro';
|
|
167
400
|
}
|
|
168
401
|
|
|
402
|
+
// Legacy alias (typo fix)
|
|
403
|
+
export const canUseCondcutor = canUseConductor;
|
|
404
|
+
|
|
169
405
|
/**
|
|
170
406
|
* Check if user can approve authorities
|
|
171
407
|
*/
|
|
172
408
|
export function canApproveAuthority(tier) {
|
|
409
|
+
if (isDevProBypassAllowed()) return true;
|
|
173
410
|
return tier === 'pro';
|
|
174
411
|
}
|
|
175
412
|
|
|
176
|
-
|
|
177
|
-
|
|
413
|
+
/**
|
|
414
|
+
* Get MCP tool access with full ErrorEnvelope support
|
|
415
|
+
*
|
|
416
|
+
* @param {string} toolName - Tool name
|
|
417
|
+
* @param {string} apiKey - API key (optional)
|
|
418
|
+
* @param {object} args - Tool arguments for option-level checks
|
|
419
|
+
* @returns {Promise<{hasAccess: boolean, tier: string, error?: object}>}
|
|
420
|
+
*/
|
|
421
|
+
export async function getMcpToolAccess(toolName, apiKey, args = {}) {
|
|
422
|
+
const tier = await getTierFromApiKey(apiKey);
|
|
423
|
+
|
|
424
|
+
// Check tool-level access
|
|
425
|
+
const hasToolAccess = canAccessTool(tier, toolName);
|
|
426
|
+
|
|
427
|
+
if (!hasToolAccess) {
|
|
178
428
|
return {
|
|
179
|
-
hasAccess:
|
|
180
|
-
tier
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
429
|
+
hasAccess: false,
|
|
430
|
+
tier,
|
|
431
|
+
firewallMode: getFirewallMode(tier),
|
|
432
|
+
error: notEntitledError(toolName, tier, 'pro'),
|
|
433
|
+
reason: `${toolName} requires Pro ($69/mo). Upgrade at https://vibecheckai.dev/pricing`,
|
|
184
434
|
};
|
|
185
435
|
}
|
|
186
436
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (!
|
|
437
|
+
// Check option-level access
|
|
438
|
+
const optionCheck = checkOptionAccess(tier, toolName, args);
|
|
439
|
+
if (!optionCheck.allowed) {
|
|
190
440
|
return {
|
|
191
441
|
hasAccess: false,
|
|
192
|
-
tier
|
|
193
|
-
|
|
442
|
+
tier,
|
|
443
|
+
firewallMode: getFirewallMode(tier),
|
|
444
|
+
error: optionNotEntitledError(toolName, optionCheck.blockedOption, tier, optionCheck.required),
|
|
445
|
+
reason: `Option --${optionCheck.blockedOption} requires Pro`,
|
|
194
446
|
};
|
|
195
447
|
}
|
|
196
448
|
|
|
197
|
-
const hasAccess = canAccessTool(tier, toolName);
|
|
198
|
-
|
|
199
449
|
return {
|
|
200
|
-
hasAccess,
|
|
450
|
+
hasAccess: true,
|
|
201
451
|
tier,
|
|
202
452
|
firewallMode: getFirewallMode(tier),
|
|
203
|
-
reason:
|
|
204
|
-
? 'Access granted'
|
|
205
|
-
: `${toolName} requires Pro ($69/mo). Upgrade at https://vibecheckai.dev/pricing`,
|
|
453
|
+
reason: 'Access granted',
|
|
206
454
|
};
|
|
207
455
|
}
|
|
208
456
|
|
|
@@ -210,17 +458,27 @@ export async function getMcpToolAccess(toolName, apiKey) {
|
|
|
210
458
|
// MIDDLEWARE
|
|
211
459
|
// ============================================================================
|
|
212
460
|
|
|
461
|
+
/**
|
|
462
|
+
* Middleware that wraps a tool handler with tier checking
|
|
463
|
+
* Returns proper ErrorEnvelope on failure
|
|
464
|
+
*/
|
|
213
465
|
export function withTierCheck(toolName, handler) {
|
|
214
466
|
return async (args) => {
|
|
215
|
-
const access = await getMcpToolAccess(toolName, args?.apiKey);
|
|
467
|
+
const access = await getMcpToolAccess(toolName, args?.apiKey, args);
|
|
216
468
|
|
|
217
469
|
if (!access.hasAccess) {
|
|
470
|
+
// Return proper ErrorEnvelope format
|
|
218
471
|
return {
|
|
219
472
|
content: [{
|
|
220
473
|
type: "text",
|
|
221
|
-
text:
|
|
474
|
+
text: JSON.stringify({
|
|
475
|
+
ok: false,
|
|
476
|
+
error: access.error,
|
|
477
|
+
}, null, 2)
|
|
222
478
|
}],
|
|
223
|
-
isError: true
|
|
479
|
+
isError: true,
|
|
480
|
+
// Also include error envelope at top level for structured access
|
|
481
|
+
_error: access.error,
|
|
224
482
|
};
|
|
225
483
|
}
|
|
226
484
|
|
|
@@ -230,6 +488,29 @@ export function withTierCheck(toolName, handler) {
|
|
|
230
488
|
};
|
|
231
489
|
}
|
|
232
490
|
|
|
491
|
+
/**
|
|
492
|
+
* Create tier gate response for direct use in handlers
|
|
493
|
+
* Returns null if access granted, ErrorEnvelope if denied
|
|
494
|
+
*/
|
|
495
|
+
export async function checkTierGate(toolName, apiKey, args = {}) {
|
|
496
|
+
const access = await getMcpToolAccess(toolName, apiKey, args);
|
|
497
|
+
|
|
498
|
+
if (!access.hasAccess) {
|
|
499
|
+
return {
|
|
500
|
+
content: [{
|
|
501
|
+
type: "text",
|
|
502
|
+
text: JSON.stringify({
|
|
503
|
+
ok: false,
|
|
504
|
+
error: access.error,
|
|
505
|
+
}, null, 2)
|
|
506
|
+
}],
|
|
507
|
+
isError: true,
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
return null; // Access granted
|
|
512
|
+
}
|
|
513
|
+
|
|
233
514
|
// ============================================================================
|
|
234
515
|
// USER INFO
|
|
235
516
|
// ============================================================================
|
|
@@ -276,11 +557,63 @@ export async function getAvailableMcpTools(apiKey) {
|
|
|
276
557
|
};
|
|
277
558
|
}
|
|
278
559
|
|
|
279
|
-
//
|
|
280
|
-
|
|
281
|
-
|
|
560
|
+
// ============================================================================
|
|
561
|
+
// LEGACY EXPORTS - Backward compatibility
|
|
562
|
+
// ============================================================================
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* @deprecated Use getMcpToolAccess instead
|
|
566
|
+
*/
|
|
567
|
+
export async function getFeatureAccessStatus(featureName, apiKey, args = {}) {
|
|
568
|
+
const result = await getMcpToolAccess(featureName, apiKey, args);
|
|
569
|
+
// Add upgradeUrl for legacy consumers
|
|
570
|
+
return {
|
|
571
|
+
...result,
|
|
572
|
+
upgradeUrl: 'https://vibecheckai.dev/pricing',
|
|
573
|
+
};
|
|
282
574
|
}
|
|
283
575
|
|
|
576
|
+
/**
|
|
577
|
+
* @deprecated Use withTierCheck instead
|
|
578
|
+
*/
|
|
284
579
|
export function withMcpToolCheck(toolName, handler) {
|
|
285
580
|
return withTierCheck(toolName, handler);
|
|
286
581
|
}
|
|
582
|
+
|
|
583
|
+
// ============================================================================
|
|
584
|
+
// TOOL TIER MAPPING - For documentation and testing
|
|
585
|
+
// ============================================================================
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Get the tier requirements table for all MCP tools
|
|
589
|
+
* Used for documentation and test generation
|
|
590
|
+
*/
|
|
591
|
+
export function getToolTierTable() {
|
|
592
|
+
const table = [];
|
|
593
|
+
|
|
594
|
+
for (const tool of FREE_TOOLS) {
|
|
595
|
+
table.push({ tool, tier: 'FREE', options: OPTION_GATES[tool] || null });
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
for (const tool of PRO_TOOLS) {
|
|
599
|
+
table.push({ tool, tier: 'PRO', options: null });
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
return table;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Print formatted tier table (for CLI/debugging)
|
|
607
|
+
*/
|
|
608
|
+
export function printTierTable() {
|
|
609
|
+
console.log('┌────────────────────────────────────┬──────┬─────────────────────────┐');
|
|
610
|
+
console.log('│ MCP Tool │ Tier │ Gated Options │');
|
|
611
|
+
console.log('├────────────────────────────────────┼──────┼─────────────────────────┤');
|
|
612
|
+
|
|
613
|
+
for (const { tool, tier, options } of getToolTierTable()) {
|
|
614
|
+
const optStr = options ? Object.keys(options).join(', ') : '-';
|
|
615
|
+
console.log(`│ ${tool.padEnd(34)} │ ${tier.padEnd(4)} │ ${optStr.padEnd(23)} │`);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
console.log('└────────────────────────────────────┴──────┴─────────────────────────┘');
|
|
619
|
+
}
|