@vibecheckai/cli 3.4.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/bin/registry.js +243 -152
  2. package/bin/runners/cli-utils.js +2 -33
  3. package/bin/runners/context/generators/cursor.js +49 -2
  4. package/bin/runners/lib/agent-firewall/learning/learning-engine.js +849 -0
  5. package/bin/runners/lib/analyzers.js +544 -19
  6. package/bin/runners/lib/audit-logger.js +532 -0
  7. package/bin/runners/lib/authority/authorities/architecture.js +364 -0
  8. package/bin/runners/lib/authority/authorities/compliance.js +341 -0
  9. package/bin/runners/lib/authority/authorities/human.js +343 -0
  10. package/bin/runners/lib/authority/authorities/quality.js +420 -0
  11. package/bin/runners/lib/authority/authorities/security.js +228 -0
  12. package/bin/runners/lib/authority/index.js +293 -0
  13. package/bin/runners/lib/authority-badge.js +425 -425
  14. package/bin/runners/lib/bundle/bundle-intelligence.js +846 -0
  15. package/bin/runners/lib/cli-charts.js +368 -0
  16. package/bin/runners/lib/cli-config-display.js +405 -0
  17. package/bin/runners/lib/cli-demo.js +275 -0
  18. package/bin/runners/lib/cli-errors.js +438 -0
  19. package/bin/runners/lib/cli-help-formatter.js +439 -0
  20. package/bin/runners/lib/cli-interactive-menu.js +509 -0
  21. package/bin/runners/lib/cli-prompts.js +441 -0
  22. package/bin/runners/lib/cli-scan-cards.js +362 -0
  23. package/bin/runners/lib/compliance-reporter.js +710 -0
  24. package/bin/runners/lib/conductor/index.js +671 -0
  25. package/bin/runners/lib/easy/README.md +123 -0
  26. package/bin/runners/lib/easy/index.js +140 -0
  27. package/bin/runners/lib/easy/interactive-wizard.js +788 -0
  28. package/bin/runners/lib/easy/one-click-firewall.js +564 -0
  29. package/bin/runners/lib/easy/zero-config-reality.js +714 -0
  30. package/bin/runners/lib/engines/accessibility-engine.js +218 -18
  31. package/bin/runners/lib/engines/api-consistency-engine.js +335 -30
  32. package/bin/runners/lib/engines/async-patterns-engine.js +444 -0
  33. package/bin/runners/lib/engines/bundle-size-engine.js +433 -0
  34. package/bin/runners/lib/engines/confidence-scoring.js +276 -0
  35. package/bin/runners/lib/engines/context-detection.js +264 -0
  36. package/bin/runners/lib/engines/cross-file-analysis-engine.js +292 -27
  37. package/bin/runners/lib/engines/database-patterns-engine.js +429 -0
  38. package/bin/runners/lib/engines/duplicate-code-engine.js +354 -0
  39. package/bin/runners/lib/engines/empty-catch-engine.js +127 -17
  40. package/bin/runners/lib/engines/env-variables-engine.js +458 -0
  41. package/bin/runners/lib/engines/error-handling-engine.js +437 -0
  42. package/bin/runners/lib/engines/false-positive-prevention.js +630 -0
  43. package/bin/runners/lib/engines/framework-adapters/index.js +607 -0
  44. package/bin/runners/lib/engines/framework-detection.js +508 -0
  45. package/bin/runners/lib/engines/import-order-engine.js +429 -0
  46. package/bin/runners/lib/engines/mock-data-engine.js +53 -10
  47. package/bin/runners/lib/engines/naming-conventions-engine.js +544 -0
  48. package/bin/runners/lib/engines/noise-reduction-engine.js +452 -0
  49. package/bin/runners/lib/engines/orchestrator.js +334 -0
  50. package/bin/runners/lib/engines/performance-issues-engine.js +176 -36
  51. package/bin/runners/lib/engines/react-patterns-engine.js +457 -0
  52. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +382 -54
  53. package/bin/runners/lib/engines/type-aware-engine.js +263 -39
  54. package/bin/runners/lib/engines/vibecheck-engines/index.js +122 -13
  55. package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +806 -0
  56. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +373 -73
  57. package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +577 -0
  58. package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +543 -0
  59. package/bin/runners/lib/engines/vibecheck-engines.js +514 -0
  60. package/bin/runners/lib/enhanced-features/index.js +305 -0
  61. package/bin/runners/lib/enhanced-output.js +631 -0
  62. package/bin/runners/lib/enterprise.js +300 -0
  63. package/bin/runners/lib/entitlements-v2.js +103 -11
  64. package/bin/runners/lib/firewall/command-validator.js +351 -0
  65. package/bin/runners/lib/firewall/config.js +341 -0
  66. package/bin/runners/lib/firewall/content-validator.js +519 -0
  67. package/bin/runners/lib/firewall/index.js +101 -0
  68. package/bin/runners/lib/firewall/path-validator.js +256 -0
  69. package/bin/runners/lib/html-proof-report.js +350 -700
  70. package/bin/runners/lib/intelligence/cross-repo-intelligence.js +817 -0
  71. package/bin/runners/lib/mcp-utils.js +425 -0
  72. package/bin/runners/lib/missions/plan.js +46 -6
  73. package/bin/runners/lib/missions/templates.js +232 -0
  74. package/bin/runners/lib/output/index.js +1022 -0
  75. package/bin/runners/lib/policy-engine.js +652 -0
  76. package/bin/runners/lib/polish/autofix/accessibility-fixes.js +333 -0
  77. package/bin/runners/lib/polish/autofix/async-handlers.js +273 -0
  78. package/bin/runners/lib/polish/autofix/dead-code.js +280 -0
  79. package/bin/runners/lib/polish/autofix/imports-optimizer.js +344 -0
  80. package/bin/runners/lib/polish/autofix/index.js +200 -0
  81. package/bin/runners/lib/polish/autofix/remove-consoles.js +209 -0
  82. package/bin/runners/lib/polish/autofix/strengthen-types.js +245 -0
  83. package/bin/runners/lib/polish/backend-checks.js +148 -0
  84. package/bin/runners/lib/polish/documentation-checks.js +111 -0
  85. package/bin/runners/lib/polish/frontend-checks.js +168 -0
  86. package/bin/runners/lib/polish/index.js +71 -0
  87. package/bin/runners/lib/polish/infrastructure-checks.js +131 -0
  88. package/bin/runners/lib/polish/library-detection.js +175 -0
  89. package/bin/runners/lib/polish/performance-checks.js +100 -0
  90. package/bin/runners/lib/polish/security-checks.js +148 -0
  91. package/bin/runners/lib/polish/utils.js +203 -0
  92. package/bin/runners/lib/prompt-builder.js +540 -0
  93. package/bin/runners/lib/proof-certificate.js +634 -0
  94. package/bin/runners/lib/reality/accessibility-audit.js +946 -0
  95. package/bin/runners/lib/reality/api-contract-validator.js +1012 -0
  96. package/bin/runners/lib/reality/chaos-engineering.js +1084 -0
  97. package/bin/runners/lib/reality/performance-tracker.js +1077 -0
  98. package/bin/runners/lib/reality/scenario-generator.js +1404 -0
  99. package/bin/runners/lib/reality/visual-regression.js +852 -0
  100. package/bin/runners/lib/reality-profiler.js +717 -0
  101. package/bin/runners/lib/replay/flight-recorder-viewer.js +1160 -0
  102. package/bin/runners/lib/review/ai-code-review.js +832 -0
  103. package/bin/runners/lib/rules/custom-rule-engine.js +985 -0
  104. package/bin/runners/lib/sbom-generator.js +641 -0
  105. package/bin/runners/lib/scan-output-enhanced.js +512 -0
  106. package/bin/runners/lib/scan-output.js +47 -0
  107. package/bin/runners/lib/security/owasp-scanner.js +939 -0
  108. package/bin/runners/lib/terminal-ui.js +113 -1
  109. package/bin/runners/lib/unified-cli-output.js +603 -430
  110. package/bin/runners/lib/validators/contract-validator.js +283 -0
  111. package/bin/runners/lib/validators/dead-export-detector.js +279 -0
  112. package/bin/runners/lib/validators/dep-audit.js +245 -0
  113. package/bin/runners/lib/validators/env-validator.js +319 -0
  114. package/bin/runners/lib/validators/index.js +120 -0
  115. package/bin/runners/lib/validators/license-checker.js +252 -0
  116. package/bin/runners/lib/validators/route-validator.js +290 -0
  117. package/bin/runners/runAIAgent.js +5 -10
  118. package/bin/runners/runAgent.js +3 -0
  119. package/bin/runners/runApprove.js +1233 -1200
  120. package/bin/runners/runAuth.js +22 -1
  121. package/bin/runners/runAuthority.js +528 -0
  122. package/bin/runners/runCheckpoint.js +4 -24
  123. package/bin/runners/runClassify.js +862 -859
  124. package/bin/runners/runConductor.js +772 -0
  125. package/bin/runners/runContainer.js +366 -0
  126. package/bin/runners/runContext.js +3 -0
  127. package/bin/runners/runDoctor.js +28 -41
  128. package/bin/runners/runEasy.js +410 -0
  129. package/bin/runners/runFirewall.js +3 -0
  130. package/bin/runners/runFirewallHook.js +3 -0
  131. package/bin/runners/runFix.js +76 -66
  132. package/bin/runners/runGuard.js +411 -18
  133. package/bin/runners/runIaC.js +372 -0
  134. package/bin/runners/runInit.js +10 -60
  135. package/bin/runners/runMcp.js +11 -12
  136. package/bin/runners/runPolish.js +240 -64
  137. package/bin/runners/runPromptFirewall.js +5 -12
  138. package/bin/runners/runProve.js +20 -55
  139. package/bin/runners/runReality.js +68 -59
  140. package/bin/runners/runReport.js +31 -5
  141. package/bin/runners/runRuntime.js +5 -8
  142. package/bin/runners/runScan.js +194 -1286
  143. package/bin/runners/runShip.js +695 -47
  144. package/bin/runners/runTruth.js +3 -0
  145. package/bin/runners/runValidate.js +7 -11
  146. package/bin/runners/runVibe.js +791 -0
  147. package/bin/runners/runWatch.js +14 -23
  148. package/bin/vibecheck.js +175 -56
  149. package/mcp-server/index.js +190 -14
  150. package/mcp-server/package.json +1 -1
  151. package/mcp-server/tools-v3.js +397 -64
  152. package/mcp-server/tools.js +495 -0
  153. package/package.json +1 -1
  154. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +0 -164
  155. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +0 -291
  156. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +0 -83
  157. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +0 -198
  158. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +0 -275
  159. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +0 -167
  160. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +0 -217
  161. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +0 -140
  162. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +0 -164
  163. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +0 -234
  164. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +0 -217
  165. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +0 -78
  166. package/mcp-server/index-v1.js +0 -698
@@ -0,0 +1,564 @@
1
+ /**
2
+ * One-Click Firewall
3
+ *
4
+ * ═══════════════════════════════════════════════════════════════════════════════
5
+ * PROTECTION IN ONE COMMAND - Just Works™
6
+ * ═══════════════════════════════════════════════════════════════════════════════
7
+ *
8
+ * Just run: npx vibecheck protect
9
+ *
10
+ * This module:
11
+ * 1. Sets up the firewall with smart defaults
12
+ * 2. Installs git hooks automatically
13
+ * 3. Configures VS Code integration
14
+ * 4. Starts protecting immediately
15
+ */
16
+
17
+ "use strict";
18
+
19
+ const fs = require("fs");
20
+ const path = require("path");
21
+ const { exec, execSync } = require("child_process");
22
+ const { colors, icons } = require("./interactive-wizard");
23
+ const { SimpleOutput } = require("./zero-config-reality");
24
+
25
+ // ═══════════════════════════════════════════════════════════════════════════════
26
+ // DEFAULT CONFIGURATIONS
27
+ // ═══════════════════════════════════════════════════════════════════════════════
28
+
29
+ const DEFAULT_FIREWALL_CONFIG = {
30
+ version: "1.0",
31
+ enabled: true,
32
+ mode: "protect", // "monitor" | "protect" | "strict"
33
+
34
+ // What to check
35
+ rules: {
36
+ // Critical - Always block
37
+ security: {
38
+ enabled: true,
39
+ block: true,
40
+ checks: ["hardcoded-secrets", "sql-injection", "xss", "eval"]
41
+ },
42
+
43
+ // Important - Block by default
44
+ quality: {
45
+ enabled: true,
46
+ block: true,
47
+ checks: ["fake-data", "mock-apis", "todo-in-production", "console-logs"]
48
+ },
49
+
50
+ // Nice to have - Warn only
51
+ suggestions: {
52
+ enabled: true,
53
+ block: false,
54
+ checks: ["missing-error-handling", "any-type", "magic-numbers"]
55
+ }
56
+ },
57
+
58
+ // Where to apply
59
+ scope: {
60
+ include: ["src/**/*", "app/**/*", "pages/**/*", "components/**/*"],
61
+ exclude: ["**/*.test.*", "**/*.spec.*", "**/test/**", "**/tests/**", "**/__tests__/**"]
62
+ },
63
+
64
+ // How to notify
65
+ notifications: {
66
+ terminal: true,
67
+ vscode: true,
68
+ sound: false // Don't be annoying
69
+ },
70
+
71
+ // Learning settings
72
+ learning: {
73
+ enabled: true,
74
+ autoDismissAfter: 3 // Auto-dismiss after 3 false positives
75
+ }
76
+ };
77
+
78
+ const GIT_PRE_COMMIT_HOOK = `#!/bin/sh
79
+ # Vibecheck Firewall - Pre-commit Hook
80
+ # This hook runs automatically before each commit
81
+
82
+ # Run vibecheck firewall check
83
+ npx vibecheck check --staged
84
+
85
+ # If vibecheck fails, block the commit
86
+ if [ $? -ne 0 ]; then
87
+ echo ""
88
+ echo "\\033[31m✗ Commit blocked by Vibecheck Firewall\\033[0m"
89
+ echo "\\033[33m Fix the issues above or use --no-verify to bypass\\033[0m"
90
+ echo ""
91
+ exit 1
92
+ fi
93
+
94
+ exit 0
95
+ `;
96
+
97
+ const VSCODE_SETTINGS = {
98
+ "vibecheck.enabled": true,
99
+ "vibecheck.firewallMode": "protect",
100
+ "vibecheck.showInlineWarnings": true,
101
+ "vibecheck.autoFix": false
102
+ };
103
+
104
+ // ═══════════════════════════════════════════════════════════════════════════════
105
+ // ONE-CLICK FIREWALL
106
+ // ═══════════════════════════════════════════════════════════════════════════════
107
+
108
+ class OneClickFirewall {
109
+ constructor(options = {}) {
110
+ this.options = {
111
+ mode: options.mode || "protect",
112
+ skipGitHooks: options.skipGitHooks || false,
113
+ skipVscode: options.skipVscode || false,
114
+ quiet: options.quiet || false,
115
+ ...options
116
+ };
117
+
118
+ this.projectRoot = process.cwd();
119
+ this.output = new SimpleOutput();
120
+ }
121
+
122
+ async enable() {
123
+ try {
124
+ if (!this.options.quiet) {
125
+ this.showWelcome();
126
+ }
127
+
128
+ // Step 1: Create config directory
129
+ await this.createConfigDir();
130
+
131
+ // Step 2: Write firewall config
132
+ await this.writeFirewallConfig();
133
+
134
+ // Step 3: Set up git hooks
135
+ if (!this.options.skipGitHooks) {
136
+ await this.setupGitHooks();
137
+ }
138
+
139
+ // Step 4: Set up VS Code
140
+ if (!this.options.skipVscode) {
141
+ await this.setupVscode();
142
+ }
143
+
144
+ // Step 5: Create initial truthpack
145
+ await this.createTruthpack();
146
+
147
+ // Done!
148
+ this.showSuccess();
149
+
150
+ return { success: true };
151
+
152
+ } catch (error) {
153
+ this.output.error(`Setup failed: ${error.message}`);
154
+ return { success: false, error };
155
+ }
156
+ }
157
+
158
+ showWelcome() {
159
+ console.clear();
160
+ console.log("");
161
+ console.log(` ${colors.cyan}${colors.bright}${icons.shield} Vibecheck Firewall${colors.reset}`);
162
+ console.log(` ${colors.dim}One-click protection for your code${colors.reset}`);
163
+ console.log("");
164
+ }
165
+
166
+ async createConfigDir() {
167
+ this.output.step("Creating configuration...");
168
+
169
+ const configDir = path.join(this.projectRoot, ".vibecheck");
170
+
171
+ if (!fs.existsSync(configDir)) {
172
+ fs.mkdirSync(configDir, { recursive: true });
173
+ }
174
+
175
+ // Create .gitignore for the config dir
176
+ const gitignorePath = path.join(configDir, ".gitignore");
177
+ if (!fs.existsSync(gitignorePath)) {
178
+ fs.writeFileSync(gitignorePath, `# Vibecheck local files
179
+ learning.json
180
+ .cache/
181
+ *.local.json
182
+ `);
183
+ }
184
+
185
+ this.output.success("Config directory created");
186
+ }
187
+
188
+ async writeFirewallConfig() {
189
+ this.output.step("Writing firewall rules...");
190
+
191
+ const configPath = path.join(this.projectRoot, ".vibecheck", "firewall.json");
192
+
193
+ // Customize config based on mode
194
+ const config = { ...DEFAULT_FIREWALL_CONFIG };
195
+ config.mode = this.options.mode;
196
+
197
+ if (this.options.mode === "monitor") {
198
+ // Monitor mode - don't block anything
199
+ config.rules.security.block = false;
200
+ config.rules.quality.block = false;
201
+ } else if (this.options.mode === "strict") {
202
+ // Strict mode - block everything
203
+ config.rules.suggestions.block = true;
204
+ }
205
+
206
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
207
+
208
+ this.output.success("Firewall rules configured");
209
+ }
210
+
211
+ async setupGitHooks() {
212
+ this.output.step("Setting up Git protection...");
213
+
214
+ // Check if this is a git repo
215
+ const gitDir = path.join(this.projectRoot, ".git");
216
+
217
+ if (!fs.existsSync(gitDir)) {
218
+ this.output.warning("Not a Git repository - skipping hooks");
219
+ return;
220
+ }
221
+
222
+ const hooksDir = path.join(gitDir, "hooks");
223
+
224
+ if (!fs.existsSync(hooksDir)) {
225
+ fs.mkdirSync(hooksDir, { recursive: true });
226
+ }
227
+
228
+ // Write pre-commit hook
229
+ const preCommitPath = path.join(hooksDir, "pre-commit");
230
+
231
+ // Backup existing hook if present
232
+ if (fs.existsSync(preCommitPath)) {
233
+ const existing = fs.readFileSync(preCommitPath, "utf8");
234
+ if (!existing.includes("vibecheck")) {
235
+ fs.writeFileSync(preCommitPath + ".backup", existing);
236
+ }
237
+ }
238
+
239
+ fs.writeFileSync(preCommitPath, GIT_PRE_COMMIT_HOOK);
240
+
241
+ // Make executable
242
+ try {
243
+ fs.chmodSync(preCommitPath, "755");
244
+ } catch {
245
+ // Windows doesn't support chmod, but that's OK
246
+ }
247
+
248
+ this.output.success("Git hooks installed");
249
+ }
250
+
251
+ async setupVscode() {
252
+ this.output.step("Configuring VS Code...");
253
+
254
+ const vscodeDir = path.join(this.projectRoot, ".vscode");
255
+
256
+ if (!fs.existsSync(vscodeDir)) {
257
+ fs.mkdirSync(vscodeDir, { recursive: true });
258
+ }
259
+
260
+ const settingsPath = path.join(vscodeDir, "settings.json");
261
+ let settings = {};
262
+
263
+ // Read existing settings
264
+ if (fs.existsSync(settingsPath)) {
265
+ try {
266
+ settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
267
+ } catch {
268
+ settings = {};
269
+ }
270
+ }
271
+
272
+ // Merge our settings
273
+ settings = { ...settings, ...VSCODE_SETTINGS };
274
+
275
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
276
+
277
+ // Recommend extension
278
+ const extensionsPath = path.join(vscodeDir, "extensions.json");
279
+ let extensions = { recommendations: [] };
280
+
281
+ if (fs.existsSync(extensionsPath)) {
282
+ try {
283
+ extensions = JSON.parse(fs.readFileSync(extensionsPath, "utf8"));
284
+ } catch {
285
+ extensions = { recommendations: [] };
286
+ }
287
+ }
288
+
289
+ if (!extensions.recommendations.includes("vibecheck.vibecheck-ai")) {
290
+ extensions.recommendations.push("vibecheck.vibecheck-ai");
291
+ fs.writeFileSync(extensionsPath, JSON.stringify(extensions, null, 2));
292
+ }
293
+
294
+ this.output.success("VS Code configured");
295
+ }
296
+
297
+ async createTruthpack() {
298
+ this.output.step("Creating project truthpack...");
299
+
300
+ // Create initial truthpack with basic project info
301
+ const truthpack = {
302
+ version: "1.0",
303
+ generated: new Date().toISOString(),
304
+ project: {
305
+ root: this.projectRoot,
306
+ name: this.getProjectName()
307
+ },
308
+ routes: [],
309
+ envVars: this.detectEnvVars(),
310
+ auth: this.detectAuthPatterns()
311
+ };
312
+
313
+ const truthpackPath = path.join(this.projectRoot, ".vibecheck", "truthpack.json");
314
+ fs.writeFileSync(truthpackPath, JSON.stringify(truthpack, null, 2));
315
+
316
+ this.output.success("Truthpack created");
317
+ }
318
+
319
+ getProjectName() {
320
+ try {
321
+ const pkg = JSON.parse(fs.readFileSync(
322
+ path.join(this.projectRoot, "package.json"), "utf8"
323
+ ));
324
+ return pkg.name || path.basename(this.projectRoot);
325
+ } catch {
326
+ return path.basename(this.projectRoot);
327
+ }
328
+ }
329
+
330
+ detectEnvVars() {
331
+ const envVars = [];
332
+ const envPath = path.join(this.projectRoot, ".env.example");
333
+
334
+ if (fs.existsSync(envPath)) {
335
+ const content = fs.readFileSync(envPath, "utf8");
336
+ const lines = content.split("\n");
337
+
338
+ for (const line of lines) {
339
+ const match = line.match(/^([A-Z_][A-Z0-9_]*)=/);
340
+ if (match) {
341
+ envVars.push(match[1]);
342
+ }
343
+ }
344
+ }
345
+
346
+ return envVars;
347
+ }
348
+
349
+ detectAuthPatterns() {
350
+ // Basic auth detection
351
+ return {
352
+ detected: false,
353
+ type: null,
354
+ routes: []
355
+ };
356
+ }
357
+
358
+ showSuccess() {
359
+ this.output.blank();
360
+ console.log(` ${colors.green}${colors.bright}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${colors.reset}`);
361
+ console.log(` ${colors.green}${colors.bright} ${icons.check} Firewall is now ACTIVE!${colors.reset}`);
362
+ console.log(` ${colors.green}${colors.bright}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${colors.reset}`);
363
+ this.output.blank();
364
+
365
+ console.log(` ${colors.dim}What's protected:${colors.reset}`);
366
+ console.log(` ${colors.green}${icons.check}${colors.reset} Security issues (secrets, injection, XSS)`);
367
+ console.log(` ${colors.green}${icons.check}${colors.reset} Quality issues (fake data, console.log)`);
368
+ console.log(` ${colors.green}${icons.check}${colors.reset} Git commits (bad code won't be committed)`);
369
+ this.output.blank();
370
+
371
+ console.log(` ${colors.dim}How it works:${colors.reset}`);
372
+ console.log(` 1. Edit code normally`);
373
+ console.log(` 2. If there's a problem, you'll see a warning`);
374
+ console.log(` 3. Critical issues block commits automatically`);
375
+ this.output.blank();
376
+
377
+ const modeText = this.options.mode === "strict" ? "STRICT" :
378
+ this.options.mode === "monitor" ? "MONITOR" : "PROTECT";
379
+
380
+ console.log(` ${colors.cyan}Mode:${colors.reset} ${modeText}`);
381
+ console.log(` ${colors.cyan}Config:${colors.reset} .vibecheck/firewall.json`);
382
+ this.output.blank();
383
+
384
+ console.log(` ${colors.dim}To change settings, edit .vibecheck/firewall.json${colors.reset}`);
385
+ console.log(` ${colors.dim}To disable, run: npx vibecheck protect --off${colors.reset}`);
386
+ this.output.blank();
387
+ }
388
+
389
+ async disable() {
390
+ this.output.step("Disabling firewall...");
391
+
392
+ const configPath = path.join(this.projectRoot, ".vibecheck", "firewall.json");
393
+
394
+ if (fs.existsSync(configPath)) {
395
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
396
+ config.enabled = false;
397
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
398
+ }
399
+
400
+ // Remove git hook
401
+ const preCommitPath = path.join(this.projectRoot, ".git", "hooks", "pre-commit");
402
+ if (fs.existsSync(preCommitPath)) {
403
+ const content = fs.readFileSync(preCommitPath, "utf8");
404
+ if (content.includes("vibecheck")) {
405
+ fs.unlinkSync(preCommitPath);
406
+
407
+ // Restore backup if exists
408
+ const backupPath = preCommitPath + ".backup";
409
+ if (fs.existsSync(backupPath)) {
410
+ fs.renameSync(backupPath, preCommitPath);
411
+ }
412
+ }
413
+ }
414
+
415
+ this.output.success("Firewall disabled");
416
+ this.output.info("Run 'npx vibecheck protect' to enable again");
417
+ }
418
+
419
+ async status() {
420
+ const configPath = path.join(this.projectRoot, ".vibecheck", "firewall.json");
421
+
422
+ if (!fs.existsSync(configPath)) {
423
+ console.log("");
424
+ console.log(` ${colors.yellow}${icons.warning} Firewall not configured${colors.reset}`);
425
+ console.log(` ${colors.dim}Run 'npx vibecheck protect' to enable${colors.reset}`);
426
+ console.log("");
427
+ return { enabled: false };
428
+ }
429
+
430
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
431
+
432
+ console.log("");
433
+ console.log(` ${colors.cyan}${icons.shield} Firewall Status${colors.reset}`);
434
+ console.log(` ${colors.dim}${"─".repeat(40)}${colors.reset}`);
435
+
436
+ const status = config.enabled ?
437
+ `${colors.green}ACTIVE${colors.reset}` :
438
+ `${colors.red}DISABLED${colors.reset}`;
439
+
440
+ console.log(` Status: ${status}`);
441
+ console.log(` Mode: ${config.mode}`);
442
+ console.log(` Config: .vibecheck/firewall.json`);
443
+ console.log("");
444
+
445
+ if (config.enabled) {
446
+ console.log(` ${colors.dim}Blocking:${colors.reset}`);
447
+ if (config.rules?.security?.block) console.log(` ${colors.green}${icons.check}${colors.reset} Security issues`);
448
+ if (config.rules?.quality?.block) console.log(` ${colors.green}${icons.check}${colors.reset} Quality issues`);
449
+ if (config.rules?.suggestions?.block) console.log(` ${colors.green}${icons.check}${colors.reset} Suggestions`);
450
+ console.log("");
451
+ }
452
+
453
+ return { enabled: config.enabled, config };
454
+ }
455
+ }
456
+
457
+ // ═══════════════════════════════════════════════════════════════════════════════
458
+ // QUICK CHECK COMMAND (for git hooks)
459
+ // ═══════════════════════════════════════════════════════════════════════════════
460
+
461
+ async function quickCheck(options = {}) {
462
+ const output = new SimpleOutput();
463
+
464
+ const configPath = path.join(process.cwd(), ".vibecheck", "firewall.json");
465
+
466
+ if (!fs.existsSync(configPath)) {
467
+ // No config - allow through
468
+ return { passed: true };
469
+ }
470
+
471
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
472
+
473
+ if (!config.enabled) {
474
+ return { passed: true };
475
+ }
476
+
477
+ // Get staged files if checking staged
478
+ let filesToCheck = [];
479
+
480
+ if (options.staged) {
481
+ try {
482
+ const stdout = execSync("git diff --cached --name-only --diff-filter=ACMR", {
483
+ encoding: "utf8"
484
+ });
485
+ filesToCheck = stdout.trim().split("\n").filter(Boolean);
486
+ } catch {
487
+ filesToCheck = [];
488
+ }
489
+ }
490
+
491
+ if (filesToCheck.length === 0) {
492
+ return { passed: true };
493
+ }
494
+
495
+ // Quick check the files
496
+ const issues = [];
497
+
498
+ for (const file of filesToCheck) {
499
+ // Skip non-JS/TS files
500
+ if (!/\.(js|jsx|ts|tsx)$/.test(file)) continue;
501
+
502
+ const filePath = path.join(process.cwd(), file);
503
+ if (!fs.existsSync(filePath)) continue;
504
+
505
+ const content = fs.readFileSync(filePath, "utf8");
506
+
507
+ // Quick pattern checks
508
+ const patterns = [
509
+ { name: "console.log", pattern: /console\.log\(/, severity: "warning" },
510
+ { name: "Hardcoded secret", pattern: /(?:password|secret|api[_-]?key)\s*[:=]\s*['"][^'"]{8,}['"]/i, severity: "critical" },
511
+ { name: "TODO in code", pattern: /\/\/\s*TODO:/i, severity: "warning" },
512
+ { name: "Fake data", pattern: /(?:fake|mock|dummy|test)(?:Data|User|Email)/i, severity: "warning" }
513
+ ];
514
+
515
+ for (const p of patterns) {
516
+ if (p.pattern.test(content)) {
517
+ issues.push({
518
+ file,
519
+ issue: p.name,
520
+ severity: p.severity
521
+ });
522
+ }
523
+ }
524
+ }
525
+
526
+ // Report issues
527
+ const criticalIssues = issues.filter(i => i.severity === "critical");
528
+ const warnings = issues.filter(i => i.severity === "warning");
529
+
530
+ if (issues.length > 0) {
531
+ console.log("");
532
+ console.log(` ${colors.cyan}${icons.shield} Vibecheck Firewall${colors.reset}`);
533
+ console.log("");
534
+
535
+ for (const issue of issues) {
536
+ const icon = issue.severity === "critical" ? icons.cross : icons.warning;
537
+ const color = issue.severity === "critical" ? colors.magenta : colors.yellow;
538
+ console.log(` ${color}${icon}${colors.reset} ${issue.issue} in ${issue.file}`);
539
+ }
540
+ console.log("");
541
+ }
542
+
543
+ // Block if critical issues and config says to block
544
+ if (criticalIssues.length > 0 && config.rules?.security?.block) {
545
+ return { passed: false, issues: criticalIssues };
546
+ }
547
+
548
+ // Block if quality issues and config says to block
549
+ if (warnings.length > 0 && config.rules?.quality?.block) {
550
+ return { passed: false, issues: warnings };
551
+ }
552
+
553
+ return { passed: true, issues };
554
+ }
555
+
556
+ // ═══════════════════════════════════════════════════════════════════════════════
557
+ // EXPORTS
558
+ // ═══════════════════════════════════════════════════════════════════════════════
559
+
560
+ module.exports = {
561
+ OneClickFirewall,
562
+ quickCheck,
563
+ DEFAULT_FIREWALL_CONFIG
564
+ };