@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/bin/runners/runGuard.js
CHANGED
|
@@ -1,27 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vibecheck guard -
|
|
2
|
+
* vibecheck guard - Unified trust boundary enforcement
|
|
3
3
|
*
|
|
4
4
|
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
-
*
|
|
5
|
+
* World-Class AI Guardrails
|
|
6
6
|
* ═══════════════════════════════════════════════════════════════════════════════
|
|
7
|
-
*
|
|
8
|
-
* Modes:
|
|
9
|
-
* - observe (FREE): Logs violations but doesn't block
|
|
10
|
-
* - enforce (PRO): Blocks AI writes that violate policy
|
|
11
|
-
*
|
|
12
|
-
* What It Guards Against:
|
|
13
|
-
* - Forbidden paths (secrets, .env, config files)
|
|
14
|
-
* - Scope violations (writing outside allowed directories)
|
|
15
|
-
* - Dangerous commands (rm -rf, curl | bash)
|
|
16
|
-
* - Hallucination patterns (fake APIs, placeholder data)
|
|
17
|
-
* - Policy violations (custom rules)
|
|
18
7
|
*/
|
|
19
8
|
|
|
20
9
|
const path = require("path");
|
|
21
10
|
const fs = require("fs");
|
|
22
11
|
const { parseGlobalFlags, shouldSuppressOutput, isJsonMode } = require("./lib/global-flags");
|
|
23
12
|
const { EXIT } = require("./lib/exit-codes");
|
|
24
|
-
const { tierHasFeature, getCurrentTier } = require("./lib/entitlements-v2");
|
|
25
13
|
const {
|
|
26
14
|
ansi,
|
|
27
15
|
sym,
|
|
@@ -31,26 +19,12 @@ const {
|
|
|
31
19
|
renderSuccess,
|
|
32
20
|
renderError,
|
|
33
21
|
renderWarning,
|
|
34
|
-
renderInfo,
|
|
35
22
|
renderFooter,
|
|
36
23
|
Spinner,
|
|
37
24
|
getTierFromKey,
|
|
38
25
|
} = require("./lib/unified-cli-output");
|
|
39
26
|
|
|
40
|
-
//
|
|
41
|
-
const { output } = require("./lib/output/index.js");
|
|
42
|
-
|
|
43
|
-
// Import firewall components
|
|
44
|
-
const {
|
|
45
|
-
loadFirewallConfig,
|
|
46
|
-
PathValidator,
|
|
47
|
-
CommandValidator,
|
|
48
|
-
ContentValidator,
|
|
49
|
-
createFirewall,
|
|
50
|
-
initFirewallConfig,
|
|
51
|
-
} = require("./lib/firewall");
|
|
52
|
-
|
|
53
|
-
// Import underlying implementations for legacy support
|
|
27
|
+
// Import underlying implementations
|
|
54
28
|
let runValidate, runPromptFirewall;
|
|
55
29
|
try {
|
|
56
30
|
runValidate = require("./runValidate").runValidate;
|
|
@@ -63,10 +37,6 @@ try {
|
|
|
63
37
|
runPromptFirewall = null;
|
|
64
38
|
}
|
|
65
39
|
|
|
66
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
67
|
-
// HELP OUTPUT
|
|
68
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
69
|
-
|
|
70
40
|
function printHelp() {
|
|
71
41
|
console.log(`
|
|
72
42
|
${ansi.bold}USAGE${ansi.reset}
|
|
@@ -74,185 +44,46 @@ function printHelp() {
|
|
|
74
44
|
|
|
75
45
|
${ansi.dim}Aliases: ai-guard, firewall, validate${ansi.reset}
|
|
76
46
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
${ansi.bold}MODES${ansi.reset}
|
|
82
|
-
${ansi.cyan}--mode observe${ansi.reset} Log violations but don't block ${ansi.green}(FREE)${ansi.reset}
|
|
83
|
-
${ansi.cyan}--mode enforce${ansi.reset} Block AI writes that violate policy ${ansi.yellow}(PRO)${ansi.reset}
|
|
47
|
+
Validate AI-generated code and prompts. Detects prompt injection attempts,
|
|
48
|
+
verifies claims against your codebase (hallucination checking), and ensures
|
|
49
|
+
AI outputs meet your standards.
|
|
84
50
|
|
|
85
|
-
${ansi.bold}
|
|
86
|
-
${ansi.cyan}--action write${ansi.reset} Validate file write operation
|
|
87
|
-
${ansi.cyan}--action delete${ansi.reset} Validate file delete operation
|
|
88
|
-
${ansi.cyan}--action execute${ansi.reset} Validate command execution
|
|
89
|
-
|
|
90
|
-
${ansi.bold}OPTIONS${ansi.reset}
|
|
91
|
-
${ansi.cyan}--path <path>${ansi.reset} File path to validate
|
|
92
|
-
${ansi.cyan}--content <str>${ansi.reset} Content to validate (or use stdin)
|
|
93
|
-
${ansi.cyan}--command <cmd>${ansi.reset} Shell command to validate
|
|
94
|
-
${ansi.cyan}--config <path>${ansi.reset} Path to firewall config (default: .vibecheck/firewall.json)
|
|
95
|
-
|
|
96
|
-
${ansi.bold}LEGACY CHECK MODES${ansi.reset}
|
|
51
|
+
${ansi.bold}CHECK MODES${ansi.reset}
|
|
97
52
|
${ansi.cyan}--claims${ansi.reset} Verify AI claims against truthpack
|
|
98
53
|
${ansi.cyan}--prompts${ansi.reset} Check code for prompt injection
|
|
99
54
|
${ansi.cyan}--hallucinations${ansi.reset} Detect AI hallucination patterns
|
|
100
55
|
${ansi.dim}(default: run all checks)${ansi.reset}
|
|
101
56
|
|
|
102
|
-
${ansi.bold}
|
|
103
|
-
${ansi.cyan}--
|
|
57
|
+
${ansi.bold}OPTIONS${ansi.reset}
|
|
58
|
+
${ansi.cyan}--file <path>${ansi.reset} Check specific file(s)
|
|
104
59
|
${ansi.cyan}--strict${ansi.reset} Fail on warnings (default: fail on errors only)
|
|
105
60
|
${ansi.cyan}--json${ansi.reset} Output as JSON (CI integration)
|
|
106
61
|
${ansi.cyan}--quiet, -q${ansi.reset} Suppress non-essential output
|
|
107
62
|
${ansi.cyan}--help, -h${ansi.reset} Show this help
|
|
108
63
|
|
|
109
64
|
${ansi.bold}EXAMPLES${ansi.reset}
|
|
110
|
-
${ansi.dim}#
|
|
111
|
-
vibecheck guard
|
|
112
|
-
|
|
113
|
-
${ansi.dim}# Check if path is allowed (observe mode)${ansi.reset}
|
|
114
|
-
vibecheck guard --mode observe --action write --path .env
|
|
115
|
-
|
|
116
|
-
${ansi.dim}# Block write to sensitive file (enforce mode, PRO)${ansi.reset}
|
|
117
|
-
vibecheck guard --mode enforce --action write --path .env
|
|
65
|
+
${ansi.dim}# Run all guardrail checks${ansi.reset}
|
|
66
|
+
vibecheck guard
|
|
118
67
|
|
|
119
|
-
${ansi.dim}#
|
|
120
|
-
vibecheck guard --
|
|
68
|
+
${ansi.dim}# Verify AI claims in specific file${ansi.reset}
|
|
69
|
+
vibecheck guard --claims --file api.ts
|
|
121
70
|
|
|
122
|
-
${ansi.dim}#
|
|
123
|
-
|
|
71
|
+
${ansi.dim}# Prompt injection scan only${ansi.reset}
|
|
72
|
+
vibecheck guard --prompts
|
|
124
73
|
|
|
125
74
|
${ansi.dim}# CI pipeline (strict, JSON output)${ansi.reset}
|
|
126
75
|
vibecheck guard --strict --json
|
|
127
76
|
|
|
128
77
|
${ansi.bold}EXIT CODES${ansi.reset}
|
|
129
|
-
0
|
|
78
|
+
0 All checks passed
|
|
130
79
|
1 Warnings found (non-blocking)
|
|
131
|
-
2
|
|
132
|
-
3 Pro feature required
|
|
133
|
-
|
|
134
|
-
${ansi.bold}CONFIGURATION${ansi.reset}
|
|
135
|
-
Configure via ${ansi.cyan}.vibecheck/firewall.json${ansi.reset}:
|
|
136
|
-
{
|
|
137
|
-
"mode": "observe",
|
|
138
|
-
"paths": {
|
|
139
|
-
"forbidden": [".env", "secrets/**"],
|
|
140
|
-
"allowed": ["src/**", "lib/**"]
|
|
141
|
-
},
|
|
142
|
-
"commands": {
|
|
143
|
-
"blocked": ["rm -rf /", "curl | bash"]
|
|
144
|
-
}
|
|
145
|
-
}
|
|
80
|
+
2 Errors found (blocking issues)
|
|
146
81
|
|
|
147
82
|
${ansi.dim}────────────────────────────────────────────────────────────────────${ansi.reset}
|
|
148
83
|
${ansi.dim}Documentation: https://docs.vibecheckai.dev/cli/guard${ansi.reset}
|
|
149
84
|
`);
|
|
150
85
|
}
|
|
151
86
|
|
|
152
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
153
|
-
// MAIN GUARD FUNCTION - New Firewall Mode
|
|
154
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Run the firewall validation
|
|
158
|
-
* @param {object} options - Validation options
|
|
159
|
-
* @returns {object} Validation result
|
|
160
|
-
*/
|
|
161
|
-
async function runFirewallCheck(options) {
|
|
162
|
-
const { mode = "observe", action, path: filePath, content, command, configPath } = options;
|
|
163
|
-
|
|
164
|
-
// Enforce mode requires PRO
|
|
165
|
-
if (mode === "enforce") {
|
|
166
|
-
const tier = await getCurrentTier();
|
|
167
|
-
if (!tierHasFeature(tier, "firewall.enforce")) {
|
|
168
|
-
return {
|
|
169
|
-
allowed: true,
|
|
170
|
-
reason: "free-tier-passthrough",
|
|
171
|
-
message: "Enforce mode requires VibeCheck Pro. Running in observe mode.",
|
|
172
|
-
tier,
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Load configuration
|
|
178
|
-
const config = loadFirewallConfig(configPath || ".vibecheck/firewall.json");
|
|
179
|
-
|
|
180
|
-
// Create validators
|
|
181
|
-
const pathValidator = new PathValidator(config);
|
|
182
|
-
const commandValidator = new CommandValidator(config);
|
|
183
|
-
const contentValidator = new ContentValidator(config);
|
|
184
|
-
|
|
185
|
-
const violations = [];
|
|
186
|
-
const warnings = [];
|
|
187
|
-
|
|
188
|
-
// Validate path
|
|
189
|
-
if (filePath && (action === "write" || action === "delete" || !action)) {
|
|
190
|
-
const pathResult = pathValidator.validate({ action: action || "write", path: filePath });
|
|
191
|
-
if (!pathResult.valid) {
|
|
192
|
-
violations.push({
|
|
193
|
-
type: "path",
|
|
194
|
-
...pathResult,
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Validate command
|
|
200
|
-
if (command && (action === "execute" || !action)) {
|
|
201
|
-
const cmdResult = commandValidator.validate({ command });
|
|
202
|
-
if (!cmdResult.valid) {
|
|
203
|
-
violations.push({
|
|
204
|
-
type: "command",
|
|
205
|
-
...cmdResult,
|
|
206
|
-
});
|
|
207
|
-
} else if (cmdResult.requiresConfirmation) {
|
|
208
|
-
warnings.push({
|
|
209
|
-
type: "command",
|
|
210
|
-
...cmdResult,
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Validate content
|
|
216
|
-
if (content && (action === "write" || !action)) {
|
|
217
|
-
const contentResult = contentValidator.validate({ content, path: filePath });
|
|
218
|
-
if (!contentResult.valid) {
|
|
219
|
-
violations.push({
|
|
220
|
-
type: "content",
|
|
221
|
-
...contentResult,
|
|
222
|
-
});
|
|
223
|
-
} else if (contentResult.hasWarnings) {
|
|
224
|
-
warnings.push(...contentResult.warnings.map(w => ({
|
|
225
|
-
type: "content",
|
|
226
|
-
...w,
|
|
227
|
-
})));
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const hasViolations = violations.length > 0;
|
|
232
|
-
|
|
233
|
-
// Determine if action is allowed based on mode
|
|
234
|
-
let allowed;
|
|
235
|
-
if (mode === "enforce") {
|
|
236
|
-
allowed = !hasViolations;
|
|
237
|
-
} else {
|
|
238
|
-
// Observe mode: always allow, but log violations
|
|
239
|
-
allowed = true;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
return {
|
|
243
|
-
allowed,
|
|
244
|
-
mode,
|
|
245
|
-
violations,
|
|
246
|
-
warnings,
|
|
247
|
-
violationCount: violations.length,
|
|
248
|
-
warningCount: warnings.length,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
253
|
-
// MAIN ENTRY POINT
|
|
254
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
255
|
-
|
|
256
87
|
async function runGuard(args = []) {
|
|
257
88
|
const { flags: globalFlags } = parseGlobalFlags(args);
|
|
258
89
|
const quiet = shouldSuppressOutput(globalFlags);
|
|
@@ -264,198 +95,7 @@ async function runGuard(args = []) {
|
|
|
264
95
|
printHelp();
|
|
265
96
|
return EXIT.SUCCESS;
|
|
266
97
|
}
|
|
267
|
-
|
|
268
|
-
// Check for --init flag
|
|
269
|
-
if (args.includes("--init")) {
|
|
270
|
-
try {
|
|
271
|
-
const configPath = initFirewallConfig(process.cwd());
|
|
272
|
-
if (!quiet && !json) {
|
|
273
|
-
renderSuccess(`Firewall configuration created at ${configPath}`);
|
|
274
|
-
renderInfo("Edit .vibecheck/firewall.json to customize rules");
|
|
275
|
-
}
|
|
276
|
-
if (json) {
|
|
277
|
-
console.log(JSON.stringify({ success: true, configPath }));
|
|
278
|
-
}
|
|
279
|
-
return EXIT.SUCCESS;
|
|
280
|
-
} catch (error) {
|
|
281
|
-
if (json) {
|
|
282
|
-
console.log(JSON.stringify({ success: false, error: error.message }));
|
|
283
|
-
} else {
|
|
284
|
-
renderError(`Failed to initialize firewall: ${error.message}`);
|
|
285
|
-
}
|
|
286
|
-
return EXIT.INTERNAL_ERROR;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Detect if using new firewall mode (--action, --path, --content, --command)
|
|
291
|
-
const hasAction = args.includes("--action");
|
|
292
|
-
const hasPath = args.includes("--path");
|
|
293
|
-
const hasContent = args.includes("--content");
|
|
294
|
-
const hasCommand = args.includes("--command");
|
|
295
|
-
const hasMode = args.includes("--mode");
|
|
296
|
-
|
|
297
|
-
const isFirewallMode = hasAction || hasPath || hasContent || hasCommand || hasMode;
|
|
298
|
-
|
|
299
|
-
if (isFirewallMode) {
|
|
300
|
-
// New firewall validation mode
|
|
301
|
-
return await runFirewallValidation(args, { quiet, json, startTime });
|
|
302
|
-
} else {
|
|
303
|
-
// Legacy guard mode (claims, prompts, hallucinations)
|
|
304
|
-
return await runLegacyGuard(args, { quiet, json, startTime, globalFlags });
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
98
|
|
|
308
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
309
|
-
// FIREWALL VALIDATION MODE
|
|
310
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
311
|
-
|
|
312
|
-
async function runFirewallValidation(args, { quiet, json, startTime }) {
|
|
313
|
-
// Parse firewall-specific options
|
|
314
|
-
const modeIndex = args.indexOf("--mode");
|
|
315
|
-
const mode = modeIndex !== -1 ? args[modeIndex + 1] : "observe";
|
|
316
|
-
|
|
317
|
-
const actionIndex = args.indexOf("--action");
|
|
318
|
-
const action = actionIndex !== -1 ? args[actionIndex + 1] : null;
|
|
319
|
-
|
|
320
|
-
const pathIndex = args.indexOf("--path");
|
|
321
|
-
const filePath = pathIndex !== -1 ? args[pathIndex + 1] : null;
|
|
322
|
-
|
|
323
|
-
const contentIndex = args.indexOf("--content");
|
|
324
|
-
let content = contentIndex !== -1 ? args[contentIndex + 1] : null;
|
|
325
|
-
|
|
326
|
-
const commandIndex = args.indexOf("--command");
|
|
327
|
-
const command = commandIndex !== -1 ? args[commandIndex + 1] : null;
|
|
328
|
-
|
|
329
|
-
const configIndex = args.indexOf("--config");
|
|
330
|
-
const configPath = configIndex !== -1 ? args[configIndex + 1] : null;
|
|
331
|
-
|
|
332
|
-
// Read content from stdin if not provided
|
|
333
|
-
if (!content && !process.stdin.isTTY) {
|
|
334
|
-
content = await readStdin();
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Validate mode
|
|
338
|
-
if (mode && !["observe", "enforce"].includes(mode)) {
|
|
339
|
-
if (json) {
|
|
340
|
-
console.log(JSON.stringify({ success: false, error: `Invalid mode: ${mode}` }));
|
|
341
|
-
} else {
|
|
342
|
-
renderError(`Invalid mode: ${mode}. Must be 'observe' or 'enforce'`);
|
|
343
|
-
}
|
|
344
|
-
return EXIT.USER_ERROR;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// Validate action
|
|
348
|
-
if (action && !["write", "delete", "execute"].includes(action)) {
|
|
349
|
-
if (json) {
|
|
350
|
-
console.log(JSON.stringify({ success: false, error: `Invalid action: ${action}` }));
|
|
351
|
-
} else {
|
|
352
|
-
renderError(`Invalid action: ${action}. Must be 'write', 'delete', or 'execute'`);
|
|
353
|
-
}
|
|
354
|
-
return EXIT.USER_ERROR;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
try {
|
|
358
|
-
if (!quiet && !json) {
|
|
359
|
-
renderMinimalHeader("guard", "starter");
|
|
360
|
-
renderSectionHeader(`Agent Firewall (${mode} mode)`, sym.shield);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// Run firewall check
|
|
364
|
-
const result = await runFirewallCheck({
|
|
365
|
-
mode,
|
|
366
|
-
action,
|
|
367
|
-
path: filePath,
|
|
368
|
-
content,
|
|
369
|
-
command,
|
|
370
|
-
configPath,
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
const duration = Date.now() - startTime;
|
|
374
|
-
|
|
375
|
-
// Output results
|
|
376
|
-
if (json) {
|
|
377
|
-
console.log(JSON.stringify({
|
|
378
|
-
...result,
|
|
379
|
-
duration,
|
|
380
|
-
success: result.allowed,
|
|
381
|
-
}, null, 2));
|
|
382
|
-
} else if (!quiet) {
|
|
383
|
-
// Display violations
|
|
384
|
-
for (const violation of result.violations) {
|
|
385
|
-
console.log();
|
|
386
|
-
renderError(`${sym.cross} ${violation.rule}: ${violation.message}`);
|
|
387
|
-
if (violation.details) {
|
|
388
|
-
console.log(` ${ansi.dim}Path: ${violation.details.path || violation.details.command || "N/A"}${ansi.reset}`);
|
|
389
|
-
if (violation.details.suggestion) {
|
|
390
|
-
console.log(` ${ansi.cyan}Suggestion: ${violation.details.suggestion}${ansi.reset}`);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// Display warnings
|
|
396
|
-
for (const warning of result.warnings) {
|
|
397
|
-
console.log();
|
|
398
|
-
renderWarning(`${sym.warn} ${warning.rule || warning.type}: ${warning.message}`);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
console.log();
|
|
402
|
-
|
|
403
|
-
if (result.allowed) {
|
|
404
|
-
if (result.violations.length > 0 && mode === "observe") {
|
|
405
|
-
renderVerdict("WARN", {
|
|
406
|
-
warnings: result.violationCount,
|
|
407
|
-
duration,
|
|
408
|
-
message: `${result.violationCount} violation(s) logged (observe mode - not blocking)`,
|
|
409
|
-
});
|
|
410
|
-
} else {
|
|
411
|
-
renderVerdict("PASS", {
|
|
412
|
-
warnings: result.warningCount,
|
|
413
|
-
duration,
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
} else {
|
|
417
|
-
renderVerdict("BLOCK", {
|
|
418
|
-
critical: result.violationCount,
|
|
419
|
-
duration,
|
|
420
|
-
message: `Action blocked: ${result.violations[0]?.message}`,
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
renderFooter({
|
|
425
|
-
nextSteps: result.allowed ? [
|
|
426
|
-
{ cmd: "vibecheck scan", desc: "run full code analysis" },
|
|
427
|
-
] : [
|
|
428
|
-
{ cmd: "vibecheck guard --mode observe", desc: "run in observe mode" },
|
|
429
|
-
{ cmd: "Edit .vibecheck/firewall.json", desc: "customize firewall rules" },
|
|
430
|
-
],
|
|
431
|
-
docsUrl: "https://docs.vibecheckai.dev/cli/guard",
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// Return appropriate exit code
|
|
436
|
-
if (!result.allowed) {
|
|
437
|
-
return EXIT.BLOCKING;
|
|
438
|
-
}
|
|
439
|
-
if (result.violationCount > 0 || result.warningCount > 0) {
|
|
440
|
-
return EXIT.WARNINGS;
|
|
441
|
-
}
|
|
442
|
-
return EXIT.SUCCESS;
|
|
443
|
-
|
|
444
|
-
} catch (error) {
|
|
445
|
-
if (json) {
|
|
446
|
-
console.log(JSON.stringify({ success: false, error: error.message }));
|
|
447
|
-
} else {
|
|
448
|
-
renderError(`Firewall check failed: ${error.message}`);
|
|
449
|
-
}
|
|
450
|
-
return EXIT.INTERNAL_ERROR;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
455
|
-
// LEGACY GUARD MODE (Claims, Prompts, Hallucinations)
|
|
456
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
457
|
-
|
|
458
|
-
async function runLegacyGuard(args, { quiet, json, startTime, globalFlags }) {
|
|
459
99
|
const runClaims = args.includes("--claims") || (!args.includes("--prompts") && !args.includes("--hallucinations"));
|
|
460
100
|
const runPrompts = args.includes("--prompts") || (!args.includes("--claims") && !args.includes("--hallucinations"));
|
|
461
101
|
const runHallucinations = args.includes("--hallucinations") || (!args.includes("--claims") && !args.includes("--prompts"));
|
|
@@ -619,37 +259,4 @@ async function runLegacyGuard(args, { quiet, json, startTime, globalFlags }) {
|
|
|
619
259
|
}
|
|
620
260
|
}
|
|
621
261
|
|
|
622
|
-
|
|
623
|
-
// UTILITY FUNCTIONS
|
|
624
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
625
|
-
|
|
626
|
-
/**
|
|
627
|
-
* Read content from stdin
|
|
628
|
-
* @returns {Promise<string>} Stdin content
|
|
629
|
-
*/
|
|
630
|
-
function readStdin() {
|
|
631
|
-
return new Promise((resolve) => {
|
|
632
|
-
let data = "";
|
|
633
|
-
process.stdin.setEncoding("utf8");
|
|
634
|
-
process.stdin.on("readable", () => {
|
|
635
|
-
let chunk;
|
|
636
|
-
while ((chunk = process.stdin.read()) !== null) {
|
|
637
|
-
data += chunk;
|
|
638
|
-
}
|
|
639
|
-
});
|
|
640
|
-
process.stdin.on("end", () => {
|
|
641
|
-
resolve(data);
|
|
642
|
-
});
|
|
643
|
-
// Timeout after 100ms if no data
|
|
644
|
-
setTimeout(() => resolve(data), 100);
|
|
645
|
-
});
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
649
|
-
// EXPORTS
|
|
650
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
651
|
-
|
|
652
|
-
module.exports = {
|
|
653
|
-
runGuard,
|
|
654
|
-
runFirewallCheck,
|
|
655
|
-
};
|
|
262
|
+
module.exports = { runGuard };
|