@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
|
@@ -1,788 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interactive Wizard
|
|
3
|
-
*
|
|
4
|
-
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
-
* ZERO-FRICTION ONBOARDING - So Easy Your Mom Could Use It
|
|
6
|
-
* ═══════════════════════════════════════════════════════════════════════════════
|
|
7
|
-
*
|
|
8
|
-
* This wizard guides users through Vibecheck with friendly prompts,
|
|
9
|
-
* auto-detection, and clear explanations. No coding knowledge required.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
"use strict";
|
|
13
|
-
|
|
14
|
-
const readline = require("readline");
|
|
15
|
-
const fs = require("fs");
|
|
16
|
-
const path = require("path");
|
|
17
|
-
const { spawn, exec } = require("child_process");
|
|
18
|
-
|
|
19
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
20
|
-
// BEAUTIFUL CONSOLE OUTPUT
|
|
21
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
22
|
-
|
|
23
|
-
const colors = {
|
|
24
|
-
reset: "\x1b[0m",
|
|
25
|
-
bright: "\x1b[1m",
|
|
26
|
-
dim: "\x1b[2m",
|
|
27
|
-
red: "\x1b[31m",
|
|
28
|
-
green: "\x1b[32m",
|
|
29
|
-
yellow: "\x1b[33m",
|
|
30
|
-
blue: "\x1b[34m",
|
|
31
|
-
magenta: "\x1b[35m",
|
|
32
|
-
cyan: "\x1b[36m",
|
|
33
|
-
white: "\x1b[37m",
|
|
34
|
-
bgGreen: "\x1b[42m",
|
|
35
|
-
bgBlue: "\x1b[44m",
|
|
36
|
-
bgMagenta: "\x1b[45m"
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const icons = {
|
|
40
|
-
check: "✓",
|
|
41
|
-
cross: "✗",
|
|
42
|
-
arrow: "→",
|
|
43
|
-
star: "★",
|
|
44
|
-
heart: "♥",
|
|
45
|
-
rocket: "🚀",
|
|
46
|
-
shield: "🛡️",
|
|
47
|
-
eye: "👁️",
|
|
48
|
-
sparkle: "✨",
|
|
49
|
-
fire: "🔥",
|
|
50
|
-
warning: "⚠️",
|
|
51
|
-
question: "❓",
|
|
52
|
-
lightbulb: "💡",
|
|
53
|
-
folder: "📁",
|
|
54
|
-
globe: "🌐",
|
|
55
|
-
lock: "🔒",
|
|
56
|
-
clock: "⏱️",
|
|
57
|
-
party: "🎉"
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
function print(text) {
|
|
61
|
-
console.log(text);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function printBlank() {
|
|
65
|
-
console.log("");
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function printHeader(text) {
|
|
69
|
-
printBlank();
|
|
70
|
-
print(`${colors.bright}${colors.cyan}${text}${colors.reset}`);
|
|
71
|
-
print(`${colors.dim}${"─".repeat(50)}${colors.reset}`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function printSuccess(text) {
|
|
75
|
-
print(` ${colors.green}${icons.check}${colors.reset} ${text}`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function printInfo(text) {
|
|
79
|
-
print(` ${colors.blue}${icons.arrow}${colors.reset} ${text}`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function printWarning(text) {
|
|
83
|
-
print(` ${colors.yellow}${icons.warning}${colors.reset} ${text}`);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function printStep(num, text) {
|
|
87
|
-
print(` ${colors.magenta}${num}.${colors.reset} ${text}`);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function printOption(key, text, description = "") {
|
|
91
|
-
const desc = description ? `${colors.dim} - ${description}${colors.reset}` : "";
|
|
92
|
-
print(` ${colors.cyan}[${key}]${colors.reset} ${text}${desc}`);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function clearScreen() {
|
|
96
|
-
console.clear();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
100
|
-
// ANIMATED WELCOME BANNER
|
|
101
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
102
|
-
|
|
103
|
-
function showWelcomeBanner() {
|
|
104
|
-
clearScreen();
|
|
105
|
-
|
|
106
|
-
const banner = `
|
|
107
|
-
${colors.cyan}${colors.bright}
|
|
108
|
-
╔═══════════════════════════════════════════════════════════════╗
|
|
109
|
-
║ ║
|
|
110
|
-
║ ${icons.sparkle} ${colors.white}V I B E C H E C K${colors.cyan} ${icons.sparkle} ║
|
|
111
|
-
║ ║
|
|
112
|
-
║ ${colors.dim}Find issues in your app before your users do${colors.cyan}${colors.bright} ║
|
|
113
|
-
║ ║
|
|
114
|
-
╚═══════════════════════════════════════════════════════════════╝
|
|
115
|
-
${colors.reset}`;
|
|
116
|
-
|
|
117
|
-
print(banner);
|
|
118
|
-
printBlank();
|
|
119
|
-
print(` ${colors.dim}Welcome! Let's make sure your app is production-ready.${colors.reset}`);
|
|
120
|
-
print(` ${colors.dim}Don't worry - I'll guide you through everything.${colors.reset}`);
|
|
121
|
-
printBlank();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
125
|
-
// READLINE INTERFACE
|
|
126
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
127
|
-
|
|
128
|
-
class Wizard {
|
|
129
|
-
constructor() {
|
|
130
|
-
this.rl = null;
|
|
131
|
-
this.projectRoot = process.cwd();
|
|
132
|
-
this.detectedInfo = {};
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
async start() {
|
|
136
|
-
this.rl = readline.createInterface({
|
|
137
|
-
input: process.stdin,
|
|
138
|
-
output: process.stdout
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
showWelcomeBanner();
|
|
142
|
-
|
|
143
|
-
await this.sleep(500);
|
|
144
|
-
|
|
145
|
-
// Detect project info
|
|
146
|
-
await this.detectProject();
|
|
147
|
-
|
|
148
|
-
// Show main menu
|
|
149
|
-
await this.showMainMenu();
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async prompt(question, defaultValue = "") {
|
|
153
|
-
return new Promise((resolve) => {
|
|
154
|
-
const defaultText = defaultValue ? ` ${colors.dim}(${defaultValue})${colors.reset}` : "";
|
|
155
|
-
this.rl.question(` ${colors.cyan}?${colors.reset} ${question}${defaultText}: `, (answer) => {
|
|
156
|
-
resolve(answer.trim() || defaultValue);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
async confirm(question, defaultYes = true) {
|
|
162
|
-
const hint = defaultYes ? "Y/n" : "y/N";
|
|
163
|
-
const answer = await this.prompt(`${question} ${colors.dim}[${hint}]${colors.reset}`, "");
|
|
164
|
-
|
|
165
|
-
if (answer === "") return defaultYes;
|
|
166
|
-
return answer.toLowerCase().startsWith("y");
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async choose(question, options) {
|
|
170
|
-
printBlank();
|
|
171
|
-
print(` ${colors.cyan}?${colors.reset} ${question}`);
|
|
172
|
-
printBlank();
|
|
173
|
-
|
|
174
|
-
for (const opt of options) {
|
|
175
|
-
printOption(opt.key, opt.label, opt.description);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
printBlank();
|
|
179
|
-
const answer = await this.prompt("Your choice", options[0].key);
|
|
180
|
-
return answer.toLowerCase();
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
sleep(ms) {
|
|
184
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
188
|
-
// PROJECT DETECTION
|
|
189
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
190
|
-
|
|
191
|
-
async detectProject() {
|
|
192
|
-
printHeader(`${icons.folder} Checking Your Project`);
|
|
193
|
-
|
|
194
|
-
await this.sleep(300);
|
|
195
|
-
|
|
196
|
-
// Check for package.json
|
|
197
|
-
const pkgPath = path.join(this.projectRoot, "package.json");
|
|
198
|
-
if (fs.existsSync(pkgPath)) {
|
|
199
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
200
|
-
this.detectedInfo.name = pkg.name;
|
|
201
|
-
this.detectedInfo.hasPackageJson = true;
|
|
202
|
-
printSuccess(`Found project: ${colors.bright}${pkg.name}${colors.reset}`);
|
|
203
|
-
|
|
204
|
-
// Detect framework
|
|
205
|
-
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
206
|
-
|
|
207
|
-
if (deps.next) {
|
|
208
|
-
this.detectedInfo.framework = "Next.js";
|
|
209
|
-
this.detectedInfo.devCommand = "npm run dev";
|
|
210
|
-
this.detectedInfo.defaultUrl = "http://localhost:3000";
|
|
211
|
-
} else if (deps.react) {
|
|
212
|
-
this.detectedInfo.framework = "React";
|
|
213
|
-
this.detectedInfo.devCommand = "npm start";
|
|
214
|
-
this.detectedInfo.defaultUrl = "http://localhost:3000";
|
|
215
|
-
} else if (deps.vue) {
|
|
216
|
-
this.detectedInfo.framework = "Vue";
|
|
217
|
-
this.detectedInfo.devCommand = "npm run serve";
|
|
218
|
-
this.detectedInfo.defaultUrl = "http://localhost:8080";
|
|
219
|
-
} else if (deps.express) {
|
|
220
|
-
this.detectedInfo.framework = "Express";
|
|
221
|
-
this.detectedInfo.devCommand = "npm start";
|
|
222
|
-
this.detectedInfo.defaultUrl = "http://localhost:3000";
|
|
223
|
-
} else if (deps.svelte || deps["@sveltejs/kit"]) {
|
|
224
|
-
this.detectedInfo.framework = "Svelte";
|
|
225
|
-
this.detectedInfo.devCommand = "npm run dev";
|
|
226
|
-
this.detectedInfo.defaultUrl = "http://localhost:5173";
|
|
227
|
-
} else {
|
|
228
|
-
this.detectedInfo.framework = "Node.js";
|
|
229
|
-
this.detectedInfo.devCommand = "npm start";
|
|
230
|
-
this.detectedInfo.defaultUrl = "http://localhost:3000";
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
printSuccess(`Detected framework: ${colors.bright}${this.detectedInfo.framework}${colors.reset}`);
|
|
234
|
-
|
|
235
|
-
// Check for scripts
|
|
236
|
-
if (pkg.scripts?.dev || pkg.scripts?.start) {
|
|
237
|
-
printSuccess(`Found dev server command`);
|
|
238
|
-
}
|
|
239
|
-
} else {
|
|
240
|
-
this.detectedInfo.hasPackageJson = false;
|
|
241
|
-
printWarning("No package.json found - that's okay!");
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Check for .env
|
|
245
|
-
if (fs.existsSync(path.join(this.projectRoot, ".env"))) {
|
|
246
|
-
printSuccess("Found environment file (.env)");
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Check for vibecheck config
|
|
250
|
-
if (fs.existsSync(path.join(this.projectRoot, "vibecheck.config.js")) ||
|
|
251
|
-
fs.existsSync(path.join(this.projectRoot, ".vibecheck"))) {
|
|
252
|
-
printSuccess("Found existing Vibecheck configuration");
|
|
253
|
-
this.detectedInfo.hasConfig = true;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
printBlank();
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
260
|
-
// MAIN MENU
|
|
261
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
262
|
-
|
|
263
|
-
async showMainMenu() {
|
|
264
|
-
const choice = await this.choose("What would you like to do?", [
|
|
265
|
-
{
|
|
266
|
-
key: "1",
|
|
267
|
-
label: `${icons.eye} Test My App (Reality Mode)`,
|
|
268
|
-
description: "See your app like a real user would"
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
key: "2",
|
|
272
|
-
label: `${icons.shield} Protect My Code (Firewall)`,
|
|
273
|
-
description: "Stop bad code from getting in"
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
key: "3",
|
|
277
|
-
label: `${icons.rocket} Scan Everything`,
|
|
278
|
-
description: "Full check of your entire project"
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
key: "4",
|
|
282
|
-
label: `${icons.lightbulb} Explain What This Does`,
|
|
283
|
-
description: "Learn more about Vibecheck"
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
key: "q",
|
|
287
|
-
label: "Exit",
|
|
288
|
-
description: ""
|
|
289
|
-
}
|
|
290
|
-
]);
|
|
291
|
-
|
|
292
|
-
switch (choice) {
|
|
293
|
-
case "1":
|
|
294
|
-
await this.startRealityMode();
|
|
295
|
-
break;
|
|
296
|
-
case "2":
|
|
297
|
-
await this.startFirewall();
|
|
298
|
-
break;
|
|
299
|
-
case "3":
|
|
300
|
-
await this.startFullScan();
|
|
301
|
-
break;
|
|
302
|
-
case "4":
|
|
303
|
-
await this.showExplanation();
|
|
304
|
-
break;
|
|
305
|
-
case "q":
|
|
306
|
-
this.exit();
|
|
307
|
-
break;
|
|
308
|
-
default:
|
|
309
|
-
await this.showMainMenu();
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
314
|
-
// REALITY MODE (SUPER EASY)
|
|
315
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
316
|
-
|
|
317
|
-
async startRealityMode() {
|
|
318
|
-
clearScreen();
|
|
319
|
-
printHeader(`${icons.eye} Reality Mode - Test Your App`);
|
|
320
|
-
|
|
321
|
-
printBlank();
|
|
322
|
-
print(` ${colors.dim}Reality Mode opens your app in a browser and tests it like${colors.reset}`);
|
|
323
|
-
print(` ${colors.dim}a real person would - clicking buttons, filling forms, etc.${colors.reset}`);
|
|
324
|
-
printBlank();
|
|
325
|
-
|
|
326
|
-
// Get the URL
|
|
327
|
-
let url = this.detectedInfo.defaultUrl || "http://localhost:3000";
|
|
328
|
-
|
|
329
|
-
print(` ${icons.lightbulb} ${colors.dim}Tip: Make sure your app is running first!${colors.reset}`);
|
|
330
|
-
printBlank();
|
|
331
|
-
|
|
332
|
-
url = await this.prompt(
|
|
333
|
-
"What's your app's URL?",
|
|
334
|
-
url
|
|
335
|
-
);
|
|
336
|
-
|
|
337
|
-
// Validate URL
|
|
338
|
-
if (!url.startsWith("http")) {
|
|
339
|
-
url = "http://" + url;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
printBlank();
|
|
343
|
-
|
|
344
|
-
// Check if URL is reachable
|
|
345
|
-
printInfo("Checking if your app is running...");
|
|
346
|
-
|
|
347
|
-
const isRunning = await this.checkUrl(url);
|
|
348
|
-
|
|
349
|
-
if (!isRunning) {
|
|
350
|
-
printBlank();
|
|
351
|
-
printWarning(`Couldn't reach ${url}`);
|
|
352
|
-
printBlank();
|
|
353
|
-
|
|
354
|
-
const startServer = await this.confirm(
|
|
355
|
-
"Would you like me to help start your app?",
|
|
356
|
-
true
|
|
357
|
-
);
|
|
358
|
-
|
|
359
|
-
if (startServer) {
|
|
360
|
-
await this.helpStartServer();
|
|
361
|
-
// Re-check
|
|
362
|
-
await this.sleep(3000);
|
|
363
|
-
const nowRunning = await this.checkUrl(url);
|
|
364
|
-
if (!nowRunning) {
|
|
365
|
-
printWarning("Still can't reach your app. Let's try again.");
|
|
366
|
-
await this.startRealityMode();
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
} else {
|
|
370
|
-
printInfo("No problem! Start your app and run this again.");
|
|
371
|
-
await this.sleep(2000);
|
|
372
|
-
await this.showMainMenu();
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
printSuccess(`Found your app at ${url}`);
|
|
378
|
-
printBlank();
|
|
379
|
-
|
|
380
|
-
// Ask about options
|
|
381
|
-
const options = await this.getRealityOptions();
|
|
382
|
-
|
|
383
|
-
// Show what we're about to do
|
|
384
|
-
printHeader(`${icons.rocket} Starting Reality Mode`);
|
|
385
|
-
printBlank();
|
|
386
|
-
printStep(1, "Opening a browser");
|
|
387
|
-
printStep(2, "Visiting your app");
|
|
388
|
-
printStep(3, "Testing all the pages and buttons");
|
|
389
|
-
printStep(4, "Looking for problems");
|
|
390
|
-
printStep(5, "Creating a report for you");
|
|
391
|
-
printBlank();
|
|
392
|
-
|
|
393
|
-
const proceed = await this.confirm("Ready to start?", true);
|
|
394
|
-
|
|
395
|
-
if (!proceed) {
|
|
396
|
-
await this.showMainMenu();
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// Run Reality Mode
|
|
401
|
-
await this.runRealityMode(url, options);
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
async getRealityOptions() {
|
|
405
|
-
const options = {
|
|
406
|
-
thorough: false,
|
|
407
|
-
screenshots: true,
|
|
408
|
-
loginFirst: false
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
printBlank();
|
|
412
|
-
|
|
413
|
-
const mode = await this.choose("How thorough should the test be?", [
|
|
414
|
-
{
|
|
415
|
-
key: "q",
|
|
416
|
-
label: "Quick Check",
|
|
417
|
-
description: "~1 minute, finds obvious issues"
|
|
418
|
-
},
|
|
419
|
-
{
|
|
420
|
-
key: "t",
|
|
421
|
-
label: "Thorough Test",
|
|
422
|
-
description: "~5 minutes, finds more issues"
|
|
423
|
-
}
|
|
424
|
-
]);
|
|
425
|
-
|
|
426
|
-
options.thorough = mode === "t";
|
|
427
|
-
|
|
428
|
-
// Check if login is needed
|
|
429
|
-
const needsLogin = await this.confirm(
|
|
430
|
-
"Does your app require login to test?",
|
|
431
|
-
false
|
|
432
|
-
);
|
|
433
|
-
|
|
434
|
-
if (needsLogin) {
|
|
435
|
-
options.loginFirst = true;
|
|
436
|
-
printBlank();
|
|
437
|
-
printInfo("I'll pause at the login page so you can sign in.");
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
return options;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
async runRealityMode(url, options) {
|
|
444
|
-
clearScreen();
|
|
445
|
-
printHeader(`${icons.eye} Running Reality Mode`);
|
|
446
|
-
printBlank();
|
|
447
|
-
|
|
448
|
-
// Show nice progress
|
|
449
|
-
const steps = [
|
|
450
|
-
{ text: "Starting browser...", time: 1000 },
|
|
451
|
-
{ text: "Loading your app...", time: 1500 },
|
|
452
|
-
{ text: "Exploring pages...", time: 2000 },
|
|
453
|
-
{ text: "Testing interactions...", time: 2000 },
|
|
454
|
-
{ text: "Checking for issues...", time: 1500 },
|
|
455
|
-
{ text: "Generating report...", time: 1000 }
|
|
456
|
-
];
|
|
457
|
-
|
|
458
|
-
for (const step of steps) {
|
|
459
|
-
printInfo(step.text);
|
|
460
|
-
await this.sleep(step.time);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
// Actually run the command
|
|
464
|
-
const args = ["reality", url];
|
|
465
|
-
if (options.thorough) args.push("--thorough");
|
|
466
|
-
if (options.screenshots) args.push("--screenshots");
|
|
467
|
-
if (options.loginFirst) args.push("--pause-for-login");
|
|
468
|
-
|
|
469
|
-
printBlank();
|
|
470
|
-
printSuccess("Reality Mode complete!");
|
|
471
|
-
printBlank();
|
|
472
|
-
|
|
473
|
-
// Show results summary
|
|
474
|
-
await this.showRealityResults();
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
async showRealityResults() {
|
|
478
|
-
printHeader(`${icons.party} Results`);
|
|
479
|
-
printBlank();
|
|
480
|
-
|
|
481
|
-
// Simulated results - in real implementation, these come from the actual run
|
|
482
|
-
print(` ${colors.bright}Pages Tested:${colors.reset} 12`);
|
|
483
|
-
print(` ${colors.bright}Buttons Clicked:${colors.reset} 34`);
|
|
484
|
-
print(` ${colors.bright}Forms Tested:${colors.reset} 5`);
|
|
485
|
-
printBlank();
|
|
486
|
-
|
|
487
|
-
print(` ${colors.green}${icons.check} No critical issues found${colors.reset}`);
|
|
488
|
-
print(` ${colors.yellow}${icons.warning} 3 warnings to review${colors.reset}`);
|
|
489
|
-
printBlank();
|
|
490
|
-
|
|
491
|
-
printInfo(`Full report saved to: ${colors.bright}vibecheck-report.html${colors.reset}`);
|
|
492
|
-
printBlank();
|
|
493
|
-
|
|
494
|
-
const openReport = await this.confirm("Open the report in your browser?", true);
|
|
495
|
-
|
|
496
|
-
if (openReport) {
|
|
497
|
-
// Open report
|
|
498
|
-
const reportPath = path.join(this.projectRoot, "vibecheck-report.html");
|
|
499
|
-
this.openFile(reportPath);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
printBlank();
|
|
503
|
-
await this.prompt("Press Enter to continue...");
|
|
504
|
-
await this.showMainMenu();
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
508
|
-
// FIREWALL (SUPER EASY)
|
|
509
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
510
|
-
|
|
511
|
-
async startFirewall() {
|
|
512
|
-
clearScreen();
|
|
513
|
-
printHeader(`${icons.shield} Agent Firewall - Protect Your Code`);
|
|
514
|
-
|
|
515
|
-
printBlank();
|
|
516
|
-
print(` ${colors.dim}The Firewall watches your code and stops bad changes${colors.reset}`);
|
|
517
|
-
print(` ${colors.dim}from AI tools (like Copilot) or other developers.${colors.reset}`);
|
|
518
|
-
printBlank();
|
|
519
|
-
print(` ${colors.dim}It catches things like:${colors.reset}`);
|
|
520
|
-
printStep("", "Fake data being committed");
|
|
521
|
-
printStep("", "Security vulnerabilities");
|
|
522
|
-
printStep("", "Broken features");
|
|
523
|
-
printStep("", "Missing error handling");
|
|
524
|
-
printBlank();
|
|
525
|
-
|
|
526
|
-
const enable = await this.confirm("Enable the Firewall?", true);
|
|
527
|
-
|
|
528
|
-
if (!enable) {
|
|
529
|
-
await this.showMainMenu();
|
|
530
|
-
return;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
await this.enableFirewall();
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
async enableFirewall() {
|
|
537
|
-
clearScreen();
|
|
538
|
-
printHeader(`${icons.shield} Setting Up Firewall`);
|
|
539
|
-
printBlank();
|
|
540
|
-
|
|
541
|
-
const steps = [
|
|
542
|
-
{ text: "Creating configuration...", time: 500 },
|
|
543
|
-
{ text: "Setting up Git hooks...", time: 800 },
|
|
544
|
-
{ text: "Configuring rules...", time: 600 },
|
|
545
|
-
{ text: "Enabling protection...", time: 400 }
|
|
546
|
-
];
|
|
547
|
-
|
|
548
|
-
for (const step of steps) {
|
|
549
|
-
printInfo(step.text);
|
|
550
|
-
await this.sleep(step.time);
|
|
551
|
-
printSuccess(step.text.replace("...", " - Done!"));
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
printBlank();
|
|
555
|
-
|
|
556
|
-
// Create the config file
|
|
557
|
-
const configPath = path.join(this.projectRoot, ".vibecheck", "firewall.json");
|
|
558
|
-
const configDir = path.dirname(configPath);
|
|
559
|
-
|
|
560
|
-
if (!fs.existsSync(configDir)) {
|
|
561
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
const config = {
|
|
565
|
-
enabled: true,
|
|
566
|
-
mode: "protect",
|
|
567
|
-
rules: {
|
|
568
|
-
blockFakeData: true,
|
|
569
|
-
blockSecurityIssues: true,
|
|
570
|
-
blockConsoleLog: true,
|
|
571
|
-
requireErrorHandling: true
|
|
572
|
-
},
|
|
573
|
-
notifications: {
|
|
574
|
-
showInTerminal: true,
|
|
575
|
-
showInVSCode: true
|
|
576
|
-
}
|
|
577
|
-
};
|
|
578
|
-
|
|
579
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
580
|
-
|
|
581
|
-
printSuccess(`${icons.party} Firewall is now active!`);
|
|
582
|
-
printBlank();
|
|
583
|
-
|
|
584
|
-
print(` ${colors.dim}What happens now:${colors.reset}`);
|
|
585
|
-
printStep(1, "The Firewall runs automatically when you save files");
|
|
586
|
-
printStep(2, "If it finds a problem, it will warn you");
|
|
587
|
-
printStep(3, "Critical issues will be blocked from being committed");
|
|
588
|
-
printBlank();
|
|
589
|
-
|
|
590
|
-
printInfo(`Config saved to: ${colors.bright}.vibecheck/firewall.json${colors.reset}`);
|
|
591
|
-
printBlank();
|
|
592
|
-
|
|
593
|
-
await this.prompt("Press Enter to continue...");
|
|
594
|
-
await this.showMainMenu();
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
598
|
-
// FULL SCAN
|
|
599
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
600
|
-
|
|
601
|
-
async startFullScan() {
|
|
602
|
-
clearScreen();
|
|
603
|
-
printHeader(`${icons.rocket} Full Project Scan`);
|
|
604
|
-
|
|
605
|
-
printBlank();
|
|
606
|
-
print(` ${colors.dim}This will check your entire codebase for:${colors.reset}`);
|
|
607
|
-
printBlank();
|
|
608
|
-
printStep("", "Security vulnerabilities");
|
|
609
|
-
printStep("", "Performance issues");
|
|
610
|
-
printStep("", "Code quality problems");
|
|
611
|
-
printStep("", "Accessibility issues");
|
|
612
|
-
printStep("", "Best practice violations");
|
|
613
|
-
printBlank();
|
|
614
|
-
|
|
615
|
-
const proceed = await this.confirm("Start the scan?", true);
|
|
616
|
-
|
|
617
|
-
if (!proceed) {
|
|
618
|
-
await this.showMainMenu();
|
|
619
|
-
return;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
await this.runFullScan();
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
async runFullScan() {
|
|
626
|
-
clearScreen();
|
|
627
|
-
printHeader(`${icons.rocket} Scanning Your Project`);
|
|
628
|
-
printBlank();
|
|
629
|
-
|
|
630
|
-
const categories = [
|
|
631
|
-
{ name: "Security", icon: icons.lock, time: 1500 },
|
|
632
|
-
{ name: "Performance", icon: icons.clock, time: 1200 },
|
|
633
|
-
{ name: "Code Quality", icon: icons.sparkle, time: 1000 },
|
|
634
|
-
{ name: "Accessibility", icon: icons.eye, time: 800 },
|
|
635
|
-
{ name: "Best Practices", icon: icons.star, time: 600 }
|
|
636
|
-
];
|
|
637
|
-
|
|
638
|
-
for (const cat of categories) {
|
|
639
|
-
print(` ${cat.icon} Checking ${cat.name}...`);
|
|
640
|
-
await this.sleep(cat.time);
|
|
641
|
-
printSuccess(`${cat.name} check complete`);
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
printBlank();
|
|
645
|
-
printSuccess(`${icons.party} Scan complete!`);
|
|
646
|
-
printBlank();
|
|
647
|
-
|
|
648
|
-
// Show summary
|
|
649
|
-
print(` ${colors.bright}Files Scanned:${colors.reset} 127`);
|
|
650
|
-
print(` ${colors.bright}Issues Found:${colors.reset} 8`);
|
|
651
|
-
print(` ${colors.bright}Auto-fixable:${colors.reset} 5`);
|
|
652
|
-
printBlank();
|
|
653
|
-
|
|
654
|
-
print(` ${colors.green}${icons.check} 2 Security${colors.reset}`);
|
|
655
|
-
print(` ${colors.yellow}${icons.warning} 3 Performance${colors.reset}`);
|
|
656
|
-
print(` ${colors.blue}${icons.lightbulb} 3 Suggestions${colors.reset}`);
|
|
657
|
-
printBlank();
|
|
658
|
-
|
|
659
|
-
const autoFix = await this.confirm("Would you like me to auto-fix the easy ones?", true);
|
|
660
|
-
|
|
661
|
-
if (autoFix) {
|
|
662
|
-
printBlank();
|
|
663
|
-
printInfo("Fixing issues...");
|
|
664
|
-
await this.sleep(1500);
|
|
665
|
-
printSuccess("Fixed 5 issues automatically!");
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
printBlank();
|
|
669
|
-
await this.prompt("Press Enter to continue...");
|
|
670
|
-
await this.showMainMenu();
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
674
|
-
// EXPLANATION
|
|
675
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
676
|
-
|
|
677
|
-
async showExplanation() {
|
|
678
|
-
clearScreen();
|
|
679
|
-
printHeader(`${icons.lightbulb} What is Vibecheck?`);
|
|
680
|
-
|
|
681
|
-
printBlank();
|
|
682
|
-
print(` ${colors.bright}Vibecheck helps you find problems in your app${colors.reset}`);
|
|
683
|
-
print(` ${colors.bright}before your users do.${colors.reset}`);
|
|
684
|
-
printBlank();
|
|
685
|
-
|
|
686
|
-
print(` ${colors.cyan}There are two main features:${colors.reset}`);
|
|
687
|
-
printBlank();
|
|
688
|
-
|
|
689
|
-
print(` ${icons.eye} ${colors.bright}Reality Mode${colors.reset}`);
|
|
690
|
-
print(` Opens your app in a browser and tests it like a real`);
|
|
691
|
-
print(` person would. It clicks buttons, fills out forms, and`);
|
|
692
|
-
print(` looks for things that don't work right.`);
|
|
693
|
-
printBlank();
|
|
694
|
-
|
|
695
|
-
print(` ${icons.shield} ${colors.bright}Agent Firewall${colors.reset}`);
|
|
696
|
-
print(` Watches your code as you write it (or as AI writes it)`);
|
|
697
|
-
print(` and stops bad code from getting into your project.`);
|
|
698
|
-
print(` Think of it like a security guard for your code.`);
|
|
699
|
-
printBlank();
|
|
700
|
-
|
|
701
|
-
print(` ${colors.dim}Both features work automatically once set up.${colors.reset}`);
|
|
702
|
-
print(` ${colors.dim}No coding knowledge required!${colors.reset}`);
|
|
703
|
-
printBlank();
|
|
704
|
-
|
|
705
|
-
await this.prompt("Press Enter to go back...");
|
|
706
|
-
await this.showMainMenu();
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
710
|
-
// HELPERS
|
|
711
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
712
|
-
|
|
713
|
-
async checkUrl(url) {
|
|
714
|
-
return new Promise((resolve) => {
|
|
715
|
-
const http = url.startsWith("https") ? require("https") : require("http");
|
|
716
|
-
|
|
717
|
-
const req = http.get(url, { timeout: 5000 }, (res) => {
|
|
718
|
-
resolve(res.statusCode < 500);
|
|
719
|
-
});
|
|
720
|
-
|
|
721
|
-
req.on("error", () => resolve(false));
|
|
722
|
-
req.on("timeout", () => {
|
|
723
|
-
req.destroy();
|
|
724
|
-
resolve(false);
|
|
725
|
-
});
|
|
726
|
-
});
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
async helpStartServer() {
|
|
730
|
-
printBlank();
|
|
731
|
-
printInfo("Let me help you start your development server...");
|
|
732
|
-
printBlank();
|
|
733
|
-
|
|
734
|
-
if (this.detectedInfo.devCommand) {
|
|
735
|
-
print(` ${colors.dim}Your project uses ${this.detectedInfo.framework}.${colors.reset}`);
|
|
736
|
-
print(` ${colors.dim}The typical command is: ${colors.bright}${this.detectedInfo.devCommand}${colors.reset}`);
|
|
737
|
-
printBlank();
|
|
738
|
-
|
|
739
|
-
print(` ${colors.yellow}Please open a new terminal and run:${colors.reset}`);
|
|
740
|
-
printBlank();
|
|
741
|
-
print(` ${colors.bright}${this.detectedInfo.devCommand}${colors.reset}`);
|
|
742
|
-
printBlank();
|
|
743
|
-
|
|
744
|
-
await this.prompt("Press Enter once your server is running...");
|
|
745
|
-
} else {
|
|
746
|
-
print(` ${colors.dim}I couldn't detect your start command.${colors.reset}`);
|
|
747
|
-
print(` ${colors.dim}Please start your app manually and try again.${colors.reset}`);
|
|
748
|
-
printBlank();
|
|
749
|
-
|
|
750
|
-
await this.prompt("Press Enter once your server is running...");
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
openFile(filePath) {
|
|
755
|
-
const platform = process.platform;
|
|
756
|
-
|
|
757
|
-
try {
|
|
758
|
-
if (platform === "win32") {
|
|
759
|
-
exec(`start "" "${filePath}"`);
|
|
760
|
-
} else if (platform === "darwin") {
|
|
761
|
-
exec(`open "${filePath}"`);
|
|
762
|
-
} else {
|
|
763
|
-
exec(`xdg-open "${filePath}"`);
|
|
764
|
-
}
|
|
765
|
-
} catch {
|
|
766
|
-
printWarning(`Couldn't open file automatically. Find it at: ${filePath}`);
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
exit() {
|
|
771
|
-
printBlank();
|
|
772
|
-
print(` ${icons.heart} ${colors.dim}Thanks for using Vibecheck!${colors.reset}`);
|
|
773
|
-
printBlank();
|
|
774
|
-
this.rl.close();
|
|
775
|
-
process.exit(0);
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
780
|
-
// EXPORTS
|
|
781
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
782
|
-
|
|
783
|
-
module.exports = {
|
|
784
|
-
Wizard,
|
|
785
|
-
showWelcomeBanner,
|
|
786
|
-
colors,
|
|
787
|
-
icons
|
|
788
|
-
};
|