@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,577 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Smart Fix Suggestions Engine
|
|
3
|
-
*
|
|
4
|
-
* AI-powered fix recommendations with confidence scoring.
|
|
5
|
-
* Generates actionable, context-aware fix suggestions for vibecheck findings.
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Context-aware fix generation based on surrounding code
|
|
9
|
-
* - Framework-specific fixes (React, Next.js, Express, etc.)
|
|
10
|
-
* - Confidence scoring for each suggestion
|
|
11
|
-
* - Auto-applicable fixes vs manual review required
|
|
12
|
-
* - Code snippets for common patterns
|
|
13
|
-
*
|
|
14
|
-
* @module smart-fix-engine
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
"use strict";
|
|
18
|
-
|
|
19
|
-
const path = require("path");
|
|
20
|
-
const fs = require("fs");
|
|
21
|
-
|
|
22
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
23
|
-
// FIX TEMPLATES - Common fix patterns for different issue types
|
|
24
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
25
|
-
|
|
26
|
-
const FIX_TEMPLATES = {
|
|
27
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
28
|
-
// FAKE SUCCESS FIXES
|
|
29
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
30
|
-
"fake-success": {
|
|
31
|
-
patterns: [
|
|
32
|
-
{
|
|
33
|
-
match: /return\s*{\s*success:\s*true\s*}/,
|
|
34
|
-
replace: `// TODO: Implement actual logic before returning success
|
|
35
|
-
const result = await performActualOperation();
|
|
36
|
-
if (!result.ok) {
|
|
37
|
-
return { success: false, error: result.error };
|
|
38
|
-
}
|
|
39
|
-
return { success: true, data: result.data };`,
|
|
40
|
-
confidence: 0.85,
|
|
41
|
-
autoApplicable: false,
|
|
42
|
-
message: "Replace hardcoded success with actual operation result",
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
manualSteps: [
|
|
46
|
-
"Identify what operation this function should perform",
|
|
47
|
-
"Implement the actual business logic",
|
|
48
|
-
"Add error handling for failure cases",
|
|
49
|
-
"Return success only after verifying the operation completed",
|
|
50
|
-
],
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
54
|
-
// EMPTY CATCH FIXES
|
|
55
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
56
|
-
"empty-catch": {
|
|
57
|
-
patterns: [
|
|
58
|
-
{
|
|
59
|
-
match: /catch\s*\(\s*(?:e|err|error|_)?\s*\)\s*{\s*}/,
|
|
60
|
-
replace: `catch (error) {
|
|
61
|
-
console.error('Operation failed:', error);
|
|
62
|
-
throw error; // Re-throw to let caller handle
|
|
63
|
-
}`,
|
|
64
|
-
confidence: 0.90,
|
|
65
|
-
autoApplicable: true,
|
|
66
|
-
message: "Add proper error handling - log and rethrow",
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
// Catch with only console.log
|
|
70
|
-
match: /catch\s*\(\s*(\w+)\s*\)\s*{\s*console\.log\([^)]+\)\s*;?\s*}/,
|
|
71
|
-
replace: (match, varName) => `catch (${varName}) {
|
|
72
|
-
console.error('Operation failed:', ${varName});
|
|
73
|
-
// Choose one:
|
|
74
|
-
// throw ${varName}; // Re-throw for caller to handle
|
|
75
|
-
// return { success: false, error: ${varName}.message }; // Return error response
|
|
76
|
-
}`,
|
|
77
|
-
confidence: 0.85,
|
|
78
|
-
autoApplicable: false,
|
|
79
|
-
message: "Improve error handling beyond just logging",
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
manualSteps: [
|
|
83
|
-
"Decide how this error should be handled in context",
|
|
84
|
-
"Either: rethrow the error for upstream handling",
|
|
85
|
-
"Or: return an error response to the caller",
|
|
86
|
-
"Or: implement recovery/retry logic if appropriate",
|
|
87
|
-
"Consider adding error reporting to a monitoring service",
|
|
88
|
-
],
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
92
|
-
// PLACEHOLDER DATA FIXES
|
|
93
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
94
|
-
"placeholder-data": {
|
|
95
|
-
patterns: [
|
|
96
|
-
{
|
|
97
|
-
// Placeholder UUID
|
|
98
|
-
match: /["'](?:12345678-1234-1234-1234-123456789012|00000000-0000-0000-0000-000000000000)["']/,
|
|
99
|
-
replace: `crypto.randomUUID() // Generate real UUID`,
|
|
100
|
-
confidence: 0.95,
|
|
101
|
-
autoApplicable: false,
|
|
102
|
-
message: "Replace placeholder UUID with dynamically generated one",
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
// Placeholder email
|
|
106
|
-
match: /["'](?:test@test\.com|user@example\.com)["']/i,
|
|
107
|
-
replace: `process.env.USER_EMAIL || throw new Error('USER_EMAIL not set')`,
|
|
108
|
-
confidence: 0.75,
|
|
109
|
-
autoApplicable: false,
|
|
110
|
-
message: "Replace placeholder email with environment variable or actual user data",
|
|
111
|
-
},
|
|
112
|
-
],
|
|
113
|
-
manualSteps: [
|
|
114
|
-
"Identify where this data should come from (database, user input, env var)",
|
|
115
|
-
"Replace the hardcoded value with dynamic data",
|
|
116
|
-
"Add validation for the data source",
|
|
117
|
-
"Update tests to use proper test fixtures",
|
|
118
|
-
],
|
|
119
|
-
},
|
|
120
|
-
|
|
121
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
122
|
-
// PLACEHOLDER API URL FIXES
|
|
123
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
124
|
-
"placeholder-api": {
|
|
125
|
-
patterns: [
|
|
126
|
-
{
|
|
127
|
-
match: /fetch\s*\(\s*["']https?:\/\/(?:example\.com|api\.example|your-api|my-api)/i,
|
|
128
|
-
replace: `fetch(process.env.API_URL + '/endpoint')`,
|
|
129
|
-
confidence: 0.90,
|
|
130
|
-
autoApplicable: false,
|
|
131
|
-
message: "Use environment variable for API URL",
|
|
132
|
-
},
|
|
133
|
-
],
|
|
134
|
-
manualSteps: [
|
|
135
|
-
"Add API_URL to your .env file with the real endpoint",
|
|
136
|
-
"Update all fetch calls to use the environment variable",
|
|
137
|
-
"Add API_URL to .env.example for documentation",
|
|
138
|
-
"Verify the endpoint exists and is accessible",
|
|
139
|
-
],
|
|
140
|
-
},
|
|
141
|
-
|
|
142
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
143
|
-
// STUB IMPLEMENTATION FIXES
|
|
144
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
145
|
-
"stub-implementation": {
|
|
146
|
-
patterns: [
|
|
147
|
-
{
|
|
148
|
-
match: /{\s*throw\s+(?:new\s+Error\()?["'](?:not\s+implemented|TODO|NYI)/i,
|
|
149
|
-
replace: `{
|
|
150
|
-
// TODO: Implement this function
|
|
151
|
-
// 1. Validate inputs
|
|
152
|
-
// 2. Perform the operation
|
|
153
|
-
// 3. Return the result
|
|
154
|
-
throw new Error('Not implemented - remove this after implementing');
|
|
155
|
-
}`,
|
|
156
|
-
confidence: 0.80,
|
|
157
|
-
autoApplicable: false,
|
|
158
|
-
message: "Implement the function logic",
|
|
159
|
-
},
|
|
160
|
-
],
|
|
161
|
-
manualSteps: [
|
|
162
|
-
"Review the function signature and docstring to understand what it should do",
|
|
163
|
-
"Implement the actual business logic",
|
|
164
|
-
"Add input validation",
|
|
165
|
-
"Add proper error handling",
|
|
166
|
-
"Write tests to verify the implementation",
|
|
167
|
-
"Remove any 'not implemented' throws",
|
|
168
|
-
],
|
|
169
|
-
},
|
|
170
|
-
|
|
171
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
172
|
-
// HARDCODED SECRET FIXES
|
|
173
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
174
|
-
"hardcoded-secret": {
|
|
175
|
-
patterns: [
|
|
176
|
-
{
|
|
177
|
-
match: /(?:api[_-]?key|apiKey|API_KEY)\s*[=:]\s*["']([^"']+)["']/i,
|
|
178
|
-
replace: `apiKey: process.env.API_KEY || throw new Error('API_KEY not configured')`,
|
|
179
|
-
confidence: 0.95,
|
|
180
|
-
autoApplicable: false,
|
|
181
|
-
message: "Move secret to environment variable",
|
|
182
|
-
},
|
|
183
|
-
],
|
|
184
|
-
manualSteps: [
|
|
185
|
-
"Add the secret to your .env file (never commit this)",
|
|
186
|
-
"Add the variable name (without value) to .env.example",
|
|
187
|
-
"Update code to read from process.env",
|
|
188
|
-
"Add validation to ensure the env var is set",
|
|
189
|
-
"Consider using a secrets manager in production",
|
|
190
|
-
"IMPORTANT: If this was committed, rotate the secret immediately",
|
|
191
|
-
],
|
|
192
|
-
},
|
|
193
|
-
|
|
194
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
195
|
-
// ASYNC WITHOUT AWAIT FIXES
|
|
196
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
197
|
-
"async-without-await": {
|
|
198
|
-
patterns: [
|
|
199
|
-
{
|
|
200
|
-
match: /async\s+(?:function\s+)?(\w+)\s*\([^)]*\)\s*{/,
|
|
201
|
-
replace: (match, funcName) => `// If this function doesn't need to be async, remove 'async':
|
|
202
|
-
function ${funcName}(`,
|
|
203
|
-
confidence: 0.60,
|
|
204
|
-
autoApplicable: false,
|
|
205
|
-
message: "Either add await calls or remove async keyword",
|
|
206
|
-
},
|
|
207
|
-
],
|
|
208
|
-
manualSteps: [
|
|
209
|
-
"Check if this function actually needs to be async",
|
|
210
|
-
"If yes: add await for async operations inside",
|
|
211
|
-
"If no: remove the async keyword to avoid confusion",
|
|
212
|
-
"Async functions always return Promises - make sure callers expect this",
|
|
213
|
-
],
|
|
214
|
-
},
|
|
215
|
-
|
|
216
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
217
|
-
// CONSOLE.LOG IN PRODUCTION FIXES
|
|
218
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
219
|
-
"console-log": {
|
|
220
|
-
patterns: [
|
|
221
|
-
{
|
|
222
|
-
match: /console\.log\s*\(/,
|
|
223
|
-
replace: `// Use a proper logger instead:
|
|
224
|
-
logger.debug(`,
|
|
225
|
-
confidence: 0.70,
|
|
226
|
-
autoApplicable: false,
|
|
227
|
-
message: "Replace console.log with proper logger",
|
|
228
|
-
},
|
|
229
|
-
],
|
|
230
|
-
manualSteps: [
|
|
231
|
-
"Set up a proper logging library (pino, winston, etc.)",
|
|
232
|
-
"Replace console.log with logger.debug or logger.info",
|
|
233
|
-
"Configure log levels for different environments",
|
|
234
|
-
"Remove or downgrade debug logs before shipping",
|
|
235
|
-
],
|
|
236
|
-
},
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
240
|
-
// FRAMEWORK-SPECIFIC FIXES
|
|
241
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
242
|
-
|
|
243
|
-
const FRAMEWORK_FIXES = {
|
|
244
|
-
nextjs: {
|
|
245
|
-
"api-handler-error": {
|
|
246
|
-
patterns: [
|
|
247
|
-
{
|
|
248
|
-
match: /export\s+(?:default\s+)?(?:async\s+)?function\s+handler/,
|
|
249
|
-
fix: `export default async function handler(req, res) {
|
|
250
|
-
try {
|
|
251
|
-
// Your logic here
|
|
252
|
-
return res.status(200).json({ success: true, data: result });
|
|
253
|
-
} catch (error) {
|
|
254
|
-
console.error('API Error:', error);
|
|
255
|
-
return res.status(500).json({ success: false, error: error.message });
|
|
256
|
-
}
|
|
257
|
-
}`,
|
|
258
|
-
message: "Next.js API handler should have try-catch",
|
|
259
|
-
},
|
|
260
|
-
],
|
|
261
|
-
},
|
|
262
|
-
},
|
|
263
|
-
|
|
264
|
-
react: {
|
|
265
|
-
"missing-error-boundary": {
|
|
266
|
-
patterns: [
|
|
267
|
-
{
|
|
268
|
-
message: "Wrap components with ErrorBoundary for better error handling",
|
|
269
|
-
fix: `import { ErrorBoundary } from 'react-error-boundary';
|
|
270
|
-
|
|
271
|
-
function ErrorFallback({error}) {
|
|
272
|
-
return <div role="alert">Something went wrong: {error.message}</div>
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Wrap your component:
|
|
276
|
-
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
|
277
|
-
<YourComponent />
|
|
278
|
-
</ErrorBoundary>`,
|
|
279
|
-
},
|
|
280
|
-
],
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
|
|
284
|
-
express: {
|
|
285
|
-
"missing-error-middleware": {
|
|
286
|
-
patterns: [
|
|
287
|
-
{
|
|
288
|
-
message: "Add error handling middleware",
|
|
289
|
-
fix: `// Add at the end of your routes:
|
|
290
|
-
app.use((err, req, res, next) => {
|
|
291
|
-
console.error('Server Error:', err);
|
|
292
|
-
res.status(err.status || 500).json({
|
|
293
|
-
success: false,
|
|
294
|
-
error: process.env.NODE_ENV === 'production'
|
|
295
|
-
? 'Internal server error'
|
|
296
|
-
: err.message
|
|
297
|
-
});
|
|
298
|
-
});`,
|
|
299
|
-
},
|
|
300
|
-
],
|
|
301
|
-
},
|
|
302
|
-
},
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
306
|
-
// SMART FIX GENERATOR
|
|
307
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Generate smart fix suggestions for a finding
|
|
311
|
-
* @param {object} finding - The finding to generate fixes for
|
|
312
|
-
* @param {object} context - Context about the file and project
|
|
313
|
-
* @returns {object} Fix suggestions with confidence
|
|
314
|
-
*/
|
|
315
|
-
function generateFixSuggestions(finding, context = {}) {
|
|
316
|
-
const {
|
|
317
|
-
fileContent = "",
|
|
318
|
-
filePath = "",
|
|
319
|
-
framework = null,
|
|
320
|
-
projectType = null,
|
|
321
|
-
} = context;
|
|
322
|
-
|
|
323
|
-
const suggestions = [];
|
|
324
|
-
|
|
325
|
-
// Get template for finding type
|
|
326
|
-
const findingType = normalizeFindingType(finding.type || finding.category);
|
|
327
|
-
const template = FIX_TEMPLATES[findingType];
|
|
328
|
-
|
|
329
|
-
if (template) {
|
|
330
|
-
// Generate pattern-based fixes
|
|
331
|
-
for (const pattern of template.patterns) {
|
|
332
|
-
const match = fileContent.match(pattern.match);
|
|
333
|
-
|
|
334
|
-
if (match) {
|
|
335
|
-
let replacement = pattern.replace;
|
|
336
|
-
|
|
337
|
-
// If replace is a function, call it with match groups
|
|
338
|
-
if (typeof replacement === "function") {
|
|
339
|
-
replacement = replacement(match[0], ...match.slice(1));
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
suggestions.push({
|
|
343
|
-
type: "code-fix",
|
|
344
|
-
confidence: pattern.confidence,
|
|
345
|
-
autoApplicable: pattern.autoApplicable,
|
|
346
|
-
message: pattern.message,
|
|
347
|
-
original: match[0],
|
|
348
|
-
replacement,
|
|
349
|
-
location: {
|
|
350
|
-
file: filePath,
|
|
351
|
-
line: finding.line,
|
|
352
|
-
matchIndex: match.index,
|
|
353
|
-
},
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// Add manual steps
|
|
359
|
-
if (template.manualSteps) {
|
|
360
|
-
suggestions.push({
|
|
361
|
-
type: "manual-steps",
|
|
362
|
-
confidence: 0.95,
|
|
363
|
-
autoApplicable: false,
|
|
364
|
-
message: "Manual fix steps",
|
|
365
|
-
steps: template.manualSteps,
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// Add framework-specific fixes
|
|
371
|
-
if (framework && FRAMEWORK_FIXES[framework]) {
|
|
372
|
-
const frameworkFixes = FRAMEWORK_FIXES[framework];
|
|
373
|
-
|
|
374
|
-
for (const [fixType, fixData] of Object.entries(frameworkFixes)) {
|
|
375
|
-
// Check if this fix is relevant
|
|
376
|
-
if (isFixRelevant(finding, fixType)) {
|
|
377
|
-
for (const pattern of fixData.patterns) {
|
|
378
|
-
suggestions.push({
|
|
379
|
-
type: "framework-fix",
|
|
380
|
-
framework,
|
|
381
|
-
confidence: 0.75,
|
|
382
|
-
autoApplicable: false,
|
|
383
|
-
message: pattern.message,
|
|
384
|
-
codeExample: pattern.fix,
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// Add general best practice suggestions
|
|
392
|
-
suggestions.push(...generateBestPracticeSuggestions(finding, context));
|
|
393
|
-
|
|
394
|
-
// Sort by confidence
|
|
395
|
-
suggestions.sort((a, b) => b.confidence - a.confidence);
|
|
396
|
-
|
|
397
|
-
return {
|
|
398
|
-
finding: finding.id || finding.type,
|
|
399
|
-
fixCount: suggestions.length,
|
|
400
|
-
hasAutoFix: suggestions.some(s => s.autoApplicable),
|
|
401
|
-
suggestions: suggestions.slice(0, 5), // Top 5 suggestions
|
|
402
|
-
priority: calculateFixPriority(finding, suggestions),
|
|
403
|
-
};
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Normalize finding type to match template keys
|
|
408
|
-
*/
|
|
409
|
-
function normalizeFindingType(type) {
|
|
410
|
-
const typeMap = {
|
|
411
|
-
"hardcoded-success-object": "fake-success",
|
|
412
|
-
"async-fake-success": "fake-success",
|
|
413
|
-
"api-fake-success": "fake-success",
|
|
414
|
-
"catch-returns-success": "empty-catch",
|
|
415
|
-
"catch-log-only": "empty-catch",
|
|
416
|
-
"catch-todo-comment": "empty-catch",
|
|
417
|
-
"empty-catch": "empty-catch",
|
|
418
|
-
"swallowed-errors": "empty-catch",
|
|
419
|
-
"placeholder-uuid": "placeholder-data",
|
|
420
|
-
"placeholder-email": "placeholder-data",
|
|
421
|
-
"fetch-example-url": "placeholder-api",
|
|
422
|
-
"placeholder-api-url": "placeholder-api",
|
|
423
|
-
"throws-not-implemented": "stub-implementation",
|
|
424
|
-
"comment-only-function": "stub-implementation",
|
|
425
|
-
"placeholder-api-key": "hardcoded-secret",
|
|
426
|
-
"HardcodedSecret": "hardcoded-secret",
|
|
427
|
-
"async-without-await": "async-without-await",
|
|
428
|
-
"ConsoleLog": "console-log",
|
|
429
|
-
};
|
|
430
|
-
|
|
431
|
-
return typeMap[type] || type?.toLowerCase().replace(/_/g, "-");
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Check if a framework fix is relevant for a finding
|
|
436
|
-
*/
|
|
437
|
-
function isFixRelevant(finding, fixType) {
|
|
438
|
-
const relevanceMap = {
|
|
439
|
-
"api-handler-error": ["fake-success", "empty-catch", "FakeSuccess"],
|
|
440
|
-
"missing-error-boundary": ["empty-catch", "swallowed-errors"],
|
|
441
|
-
"missing-error-middleware": ["empty-catch", "silent-failure"],
|
|
442
|
-
};
|
|
443
|
-
|
|
444
|
-
const relevantTypes = relevanceMap[fixType] || [];
|
|
445
|
-
return relevantTypes.some(t =>
|
|
446
|
-
finding.type?.includes(t) || finding.category?.includes(t)
|
|
447
|
-
);
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
/**
|
|
451
|
-
* Generate best practice suggestions
|
|
452
|
-
*/
|
|
453
|
-
function generateBestPracticeSuggestions(finding, context) {
|
|
454
|
-
const suggestions = [];
|
|
455
|
-
|
|
456
|
-
// Error handling best practices
|
|
457
|
-
if (finding.category?.includes("Error") || finding.type?.includes("catch")) {
|
|
458
|
-
suggestions.push({
|
|
459
|
-
type: "best-practice",
|
|
460
|
-
confidence: 0.80,
|
|
461
|
-
autoApplicable: false,
|
|
462
|
-
message: "Error Handling Best Practices",
|
|
463
|
-
tips: [
|
|
464
|
-
"Always handle or rethrow errors - never swallow them",
|
|
465
|
-
"Use typed error classes for different error types",
|
|
466
|
-
"Log errors with context (user ID, request ID, etc.)",
|
|
467
|
-
"Consider using a centralized error handler",
|
|
468
|
-
"In production, never expose internal error details to users",
|
|
469
|
-
],
|
|
470
|
-
});
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
// API best practices
|
|
474
|
-
if (finding.type?.includes("api") || finding.category?.includes("API")) {
|
|
475
|
-
suggestions.push({
|
|
476
|
-
type: "best-practice",
|
|
477
|
-
confidence: 0.80,
|
|
478
|
-
autoApplicable: false,
|
|
479
|
-
message: "API Best Practices",
|
|
480
|
-
tips: [
|
|
481
|
-
"Always use environment variables for API URLs",
|
|
482
|
-
"Add timeout and retry logic for external API calls",
|
|
483
|
-
"Validate API responses before using the data",
|
|
484
|
-
"Use TypeScript interfaces for API response types",
|
|
485
|
-
"Add error handling for network failures",
|
|
486
|
-
],
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
return suggestions;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
/**
|
|
494
|
-
* Calculate fix priority
|
|
495
|
-
*/
|
|
496
|
-
function calculateFixPriority(finding, suggestions) {
|
|
497
|
-
let priority = 0;
|
|
498
|
-
|
|
499
|
-
// Higher priority for blockers
|
|
500
|
-
if (finding.severity === "BLOCK" || finding.severity === "critical") {
|
|
501
|
-
priority += 30;
|
|
502
|
-
} else if (finding.severity === "WARN") {
|
|
503
|
-
priority += 15;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
// Higher priority for auto-fixable issues
|
|
507
|
-
if (suggestions.some(s => s.autoApplicable)) {
|
|
508
|
-
priority += 20;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
// Higher priority for high-confidence fixes
|
|
512
|
-
const maxConfidence = Math.max(...suggestions.map(s => s.confidence || 0));
|
|
513
|
-
priority += maxConfidence * 10;
|
|
514
|
-
|
|
515
|
-
// Higher priority for security issues
|
|
516
|
-
if (finding.category?.includes("Security") || finding.type?.includes("secret")) {
|
|
517
|
-
priority += 25;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
return Math.min(100, priority);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
/**
|
|
524
|
-
* Generate fix plan for multiple findings
|
|
525
|
-
* @param {Array} findings - Array of findings
|
|
526
|
-
* @param {object} context - Project context
|
|
527
|
-
* @returns {object} Comprehensive fix plan
|
|
528
|
-
*/
|
|
529
|
-
function generateFixPlan(findings, context = {}) {
|
|
530
|
-
const fixes = findings.map(f => generateFixSuggestions(f, context));
|
|
531
|
-
|
|
532
|
-
// Sort by priority
|
|
533
|
-
fixes.sort((a, b) => b.priority - a.priority);
|
|
534
|
-
|
|
535
|
-
// Group by fix type
|
|
536
|
-
const autoFixable = fixes.filter(f => f.hasAutoFix);
|
|
537
|
-
const manualRequired = fixes.filter(f => !f.hasAutoFix);
|
|
538
|
-
|
|
539
|
-
// Calculate estimated effort
|
|
540
|
-
const autoFixTime = autoFixable.length * 2; // ~2 min per auto-fix
|
|
541
|
-
const manualFixTime = manualRequired.reduce((sum, f) => {
|
|
542
|
-
const severity = findings.find(finding => finding.id === f.finding)?.severity;
|
|
543
|
-
return sum + (severity === "BLOCK" ? 30 : 15); // 30 min for blockers, 15 for warnings
|
|
544
|
-
}, 0);
|
|
545
|
-
|
|
546
|
-
return {
|
|
547
|
-
summary: {
|
|
548
|
-
totalFindings: findings.length,
|
|
549
|
-
autoFixable: autoFixable.length,
|
|
550
|
-
manualRequired: manualRequired.length,
|
|
551
|
-
estimatedTimeMinutes: autoFixTime + manualFixTime,
|
|
552
|
-
},
|
|
553
|
-
prioritized: fixes,
|
|
554
|
-
autoFixes: autoFixable,
|
|
555
|
-
manualFixes: manualRequired,
|
|
556
|
-
recommendations: [
|
|
557
|
-
autoFixable.length > 0 ?
|
|
558
|
-
`Run 'vibecheck fix --auto' to apply ${autoFixable.length} automatic fixes` : null,
|
|
559
|
-
manualRequired.length > 0 ?
|
|
560
|
-
`${manualRequired.length} issues require manual review and fixes` : null,
|
|
561
|
-
fixes.some(f => f.priority > 50) ?
|
|
562
|
-
"Start with high-priority fixes marked with priority > 50" : null,
|
|
563
|
-
].filter(Boolean),
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
568
|
-
// EXPORTS
|
|
569
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
570
|
-
|
|
571
|
-
module.exports = {
|
|
572
|
-
generateFixSuggestions,
|
|
573
|
-
generateFixPlan,
|
|
574
|
-
FIX_TEMPLATES,
|
|
575
|
-
FRAMEWORK_FIXES,
|
|
576
|
-
normalizeFindingType,
|
|
577
|
-
};
|