@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,175 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Library Detection for Polish Checks
|
|
3
|
-
*
|
|
4
|
-
* Detects installed libraries to reduce false positives.
|
|
5
|
-
* If a library already provides functionality, we skip the corresponding check.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
"use strict";
|
|
9
|
-
|
|
10
|
-
const { loadPackageJsonSync, getAllDependencies } = require('./utils');
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Common libraries that provide specific functionality
|
|
14
|
-
*/
|
|
15
|
-
const LIBRARY_ALTERNATIVES = {
|
|
16
|
-
// Error handling libraries
|
|
17
|
-
errorBoundary: [
|
|
18
|
-
'react-error-boundary',
|
|
19
|
-
'@sentry/react',
|
|
20
|
-
'bugsnag-react',
|
|
21
|
-
],
|
|
22
|
-
|
|
23
|
-
// Toast/notification libraries
|
|
24
|
-
toast: [
|
|
25
|
-
'react-hot-toast',
|
|
26
|
-
'react-toastify',
|
|
27
|
-
'sonner',
|
|
28
|
-
'@radix-ui/react-toast',
|
|
29
|
-
'notistack',
|
|
30
|
-
'react-notifications',
|
|
31
|
-
],
|
|
32
|
-
|
|
33
|
-
// Loading/spinner libraries
|
|
34
|
-
spinner: [
|
|
35
|
-
'react-spinners',
|
|
36
|
-
'react-loader-spinner',
|
|
37
|
-
'react-loading',
|
|
38
|
-
'@chakra-ui/react',
|
|
39
|
-
'@mantine/core',
|
|
40
|
-
],
|
|
41
|
-
|
|
42
|
-
// Skeleton libraries
|
|
43
|
-
skeleton: [
|
|
44
|
-
'react-loading-skeleton',
|
|
45
|
-
'react-content-loader',
|
|
46
|
-
'@chakra-ui/react',
|
|
47
|
-
'@mantine/core',
|
|
48
|
-
'@radix-ui/themes',
|
|
49
|
-
],
|
|
50
|
-
|
|
51
|
-
// Form validation libraries
|
|
52
|
-
formValidation: [
|
|
53
|
-
'react-hook-form',
|
|
54
|
-
'formik',
|
|
55
|
-
'@tanstack/react-form',
|
|
56
|
-
'react-final-form',
|
|
57
|
-
'zod',
|
|
58
|
-
'yup',
|
|
59
|
-
],
|
|
60
|
-
|
|
61
|
-
// Rate limiting libraries
|
|
62
|
-
rateLimiting: [
|
|
63
|
-
'express-rate-limit',
|
|
64
|
-
'rate-limiter-flexible',
|
|
65
|
-
'@upstash/ratelimit',
|
|
66
|
-
'bottleneck',
|
|
67
|
-
],
|
|
68
|
-
|
|
69
|
-
// Logging libraries
|
|
70
|
-
logging: [
|
|
71
|
-
'winston',
|
|
72
|
-
'pino',
|
|
73
|
-
'bunyan',
|
|
74
|
-
'log4js',
|
|
75
|
-
'morgan',
|
|
76
|
-
],
|
|
77
|
-
|
|
78
|
-
// Monitoring libraries
|
|
79
|
-
monitoring: [
|
|
80
|
-
'@sentry/node',
|
|
81
|
-
'@sentry/react',
|
|
82
|
-
'newrelic',
|
|
83
|
-
'datadog-metrics',
|
|
84
|
-
'@opentelemetry/api',
|
|
85
|
-
'prom-client',
|
|
86
|
-
],
|
|
87
|
-
|
|
88
|
-
// Security libraries
|
|
89
|
-
security: [
|
|
90
|
-
'helmet',
|
|
91
|
-
'cors',
|
|
92
|
-
'express-validator',
|
|
93
|
-
'sanitize-html',
|
|
94
|
-
'dompurify',
|
|
95
|
-
],
|
|
96
|
-
|
|
97
|
-
// Auth libraries
|
|
98
|
-
auth: [
|
|
99
|
-
'next-auth',
|
|
100
|
-
'passport',
|
|
101
|
-
'express-jwt',
|
|
102
|
-
'jsonwebtoken',
|
|
103
|
-
'@clerk/nextjs',
|
|
104
|
-
'@auth0/nextjs-auth0',
|
|
105
|
-
],
|
|
106
|
-
|
|
107
|
-
// i18n libraries
|
|
108
|
-
i18n: [
|
|
109
|
-
'next-intl',
|
|
110
|
-
'react-i18next',
|
|
111
|
-
'i18next',
|
|
112
|
-
'next-translate',
|
|
113
|
-
'formatjs',
|
|
114
|
-
'react-intl',
|
|
115
|
-
],
|
|
116
|
-
|
|
117
|
-
// Accessibility libraries
|
|
118
|
-
accessibility: [
|
|
119
|
-
'@radix-ui/react-accessible-icon',
|
|
120
|
-
'react-aria',
|
|
121
|
-
'@react-aria/focus',
|
|
122
|
-
'focus-visible',
|
|
123
|
-
'@chakra-ui/react',
|
|
124
|
-
],
|
|
125
|
-
|
|
126
|
-
// SEO libraries
|
|
127
|
-
seo: [
|
|
128
|
-
'next-seo',
|
|
129
|
-
'react-helmet',
|
|
130
|
-
'react-helmet-async',
|
|
131
|
-
'@tanstack/react-query',
|
|
132
|
-
],
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Check if a library category is covered by installed dependencies
|
|
137
|
-
*/
|
|
138
|
-
function hasLibrary(deps, category) {
|
|
139
|
-
const alternatives = LIBRARY_ALTERNATIVES[category];
|
|
140
|
-
if (!alternatives) return false;
|
|
141
|
-
|
|
142
|
-
return alternatives.some(lib => deps[lib] !== undefined);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Detect all installed libraries and return coverage map
|
|
147
|
-
*/
|
|
148
|
-
function detectInstalledLibraries(projectPath) {
|
|
149
|
-
const pkg = loadPackageJsonSync(projectPath);
|
|
150
|
-
if (!pkg) return { deps: {}, coverage: {} };
|
|
151
|
-
|
|
152
|
-
const deps = getAllDependencies(pkg);
|
|
153
|
-
const coverage = {};
|
|
154
|
-
|
|
155
|
-
for (const [category, libs] of Object.entries(LIBRARY_ALTERNATIVES)) {
|
|
156
|
-
coverage[category] = libs.filter(lib => deps[lib] !== undefined);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return { deps, coverage };
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Get a list of detected libraries for a category
|
|
164
|
-
*/
|
|
165
|
-
function getDetectedLibraries(projectPath, category) {
|
|
166
|
-
const { coverage } = detectInstalledLibraries(projectPath);
|
|
167
|
-
return coverage[category] || [];
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
module.exports = {
|
|
171
|
-
LIBRARY_ALTERNATIVES,
|
|
172
|
-
hasLibrary,
|
|
173
|
-
detectInstalledLibraries,
|
|
174
|
-
getDetectedLibraries,
|
|
175
|
-
};
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Performance Polish Checks
|
|
3
|
-
*
|
|
4
|
-
* Checks for performance production readiness:
|
|
5
|
-
* - Caching configuration
|
|
6
|
-
* - Image optimization
|
|
7
|
-
* - Bundle optimization
|
|
8
|
-
* - Lazy loading
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
"use strict";
|
|
12
|
-
|
|
13
|
-
const path = require("path");
|
|
14
|
-
const { pathExists, findAllFiles, readFileSafe } = require('./utils');
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Check for image optimization
|
|
18
|
-
*/
|
|
19
|
-
async function checkImageOptimization(projectPath, options = {}) {
|
|
20
|
-
const findings = [];
|
|
21
|
-
|
|
22
|
-
// Check for next/image usage or image optimization packages
|
|
23
|
-
const files = await findAllFiles(projectPath, /\.(tsx?|jsx?)$/);
|
|
24
|
-
let hasImageOptimization = false;
|
|
25
|
-
|
|
26
|
-
for (const file of files) {
|
|
27
|
-
const content = await readFileSafe(file);
|
|
28
|
-
if (content && /next\/image|@next\/image|Image.*src=/i.test(content)) {
|
|
29
|
-
hasImageOptimization = true;
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!hasImageOptimization) {
|
|
35
|
-
findings.push({
|
|
36
|
-
id: 'no-image-optimization',
|
|
37
|
-
category: 'performance',
|
|
38
|
-
priority: 'medium',
|
|
39
|
-
title: 'No Image Optimization',
|
|
40
|
-
description: 'Not using optimized image components. Large images slow down page load.',
|
|
41
|
-
fix: 'Use next/image for automatic image optimization',
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return findings;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Check for bundle analyzer
|
|
50
|
-
*/
|
|
51
|
-
async function checkBundleAnalyzer(projectPath, options = {}) {
|
|
52
|
-
const findings = [];
|
|
53
|
-
|
|
54
|
-
const pkg = await readFileSafe(path.join(projectPath, 'package.json'));
|
|
55
|
-
if (pkg && /@next\/bundle-analyzer|webpack-bundle-analyzer/i.test(pkg)) {
|
|
56
|
-
return findings;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
findings.push({
|
|
60
|
-
id: 'no-bundle-analyzer',
|
|
61
|
-
category: 'performance',
|
|
62
|
-
priority: 'low',
|
|
63
|
-
title: 'No Bundle Analyzer',
|
|
64
|
-
description: 'Bundle analyzer not configured. Hard to identify large dependencies.',
|
|
65
|
-
fix: 'Install @next/bundle-analyzer to monitor bundle size',
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
return findings;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Run all performance checks
|
|
73
|
-
*/
|
|
74
|
-
async function runChecks(projectPath, options = {}) {
|
|
75
|
-
const allFindings = [];
|
|
76
|
-
|
|
77
|
-
const checks = [
|
|
78
|
-
checkImageOptimization,
|
|
79
|
-
checkBundleAnalyzer,
|
|
80
|
-
];
|
|
81
|
-
|
|
82
|
-
for (const check of checks) {
|
|
83
|
-
try {
|
|
84
|
-
const findings = await check(projectPath, options);
|
|
85
|
-
allFindings.push(...findings);
|
|
86
|
-
} catch (error) {
|
|
87
|
-
if (options.verbose) {
|
|
88
|
-
console.warn(`Check failed: ${check.name}`, error.message);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return allFindings;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
module.exports = {
|
|
97
|
-
runChecks,
|
|
98
|
-
checkImageOptimization,
|
|
99
|
-
checkBundleAnalyzer,
|
|
100
|
-
};
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Security Polish Checks
|
|
3
|
-
*
|
|
4
|
-
* Checks for security production readiness:
|
|
5
|
-
* - HTTPS enforcement
|
|
6
|
-
* - CORS configuration
|
|
7
|
-
* - CSP headers
|
|
8
|
-
* - Secrets management
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
"use strict";
|
|
12
|
-
|
|
13
|
-
const path = require("path");
|
|
14
|
-
const { pathExists, findAllFiles, readFileSafe } = require('./utils');
|
|
15
|
-
const { detectInstalledLibraries } = require('./library-detection');
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Check for HTTPS enforcement
|
|
19
|
-
*/
|
|
20
|
-
async function checkHTTPS(projectPath, options = {}) {
|
|
21
|
-
const findings = [];
|
|
22
|
-
|
|
23
|
-
// Check for HTTPS patterns
|
|
24
|
-
const files = await findAllFiles(projectPath, /\.(ts|js)$/);
|
|
25
|
-
let hasHTTPS = false;
|
|
26
|
-
|
|
27
|
-
for (const file of files) {
|
|
28
|
-
const content = await readFileSafe(file);
|
|
29
|
-
if (content && /forceSSL|https.*redirect|x-forwarded-proto/i.test(content)) {
|
|
30
|
-
hasHTTPS = true;
|
|
31
|
-
break;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Also check environment or config files
|
|
36
|
-
const configFiles = ['next.config.js', 'next.config.ts', 'vercel.json', 'netlify.toml'];
|
|
37
|
-
for (const cf of configFiles) {
|
|
38
|
-
if (await pathExists(path.join(projectPath, cf))) {
|
|
39
|
-
hasHTTPS = true;
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (!hasHTTPS) {
|
|
45
|
-
findings.push({
|
|
46
|
-
id: 'no-https-enforcement',
|
|
47
|
-
category: 'security',
|
|
48
|
-
priority: 'high',
|
|
49
|
-
title: 'HTTPS Not Enforced',
|
|
50
|
-
description: 'No HTTPS redirect or SSL enforcement found.',
|
|
51
|
-
fix: 'Configure HTTPS redirect in your server or platform settings',
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return findings;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Check for helmet/security headers
|
|
60
|
-
*/
|
|
61
|
-
async function checkSecurityHeaders(projectPath, options = {}) {
|
|
62
|
-
const findings = [];
|
|
63
|
-
const { coverage } = detectInstalledLibraries(projectPath);
|
|
64
|
-
|
|
65
|
-
if (coverage.security && coverage.security.length > 0) {
|
|
66
|
-
return findings;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Check for security header patterns
|
|
70
|
-
const files = await findAllFiles(projectPath, /\.(ts|js)$/);
|
|
71
|
-
let hasSecurityHeaders = false;
|
|
72
|
-
|
|
73
|
-
for (const file of files) {
|
|
74
|
-
const content = await readFileSafe(file);
|
|
75
|
-
if (content && /helmet|Content-Security-Policy|X-Frame-Options|X-XSS-Protection/i.test(content)) {
|
|
76
|
-
hasSecurityHeaders = true;
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (!hasSecurityHeaders) {
|
|
82
|
-
findings.push({
|
|
83
|
-
id: 'missing-security-headers',
|
|
84
|
-
category: 'security',
|
|
85
|
-
priority: 'high',
|
|
86
|
-
title: 'Missing Security Headers',
|
|
87
|
-
description: 'No security headers configured. Vulnerable to XSS, clickjacking, etc.',
|
|
88
|
-
fix: 'Install helmet package or configure security headers manually',
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return findings;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Check for env file in .gitignore
|
|
97
|
-
*/
|
|
98
|
-
async function checkEnvGitignore(projectPath, options = {}) {
|
|
99
|
-
const findings = [];
|
|
100
|
-
|
|
101
|
-
const gitignore = await readFileSafe(path.join(projectPath, '.gitignore'));
|
|
102
|
-
|
|
103
|
-
if (!gitignore || !/\.env/i.test(gitignore)) {
|
|
104
|
-
findings.push({
|
|
105
|
-
id: 'env-not-gitignored',
|
|
106
|
-
category: 'security',
|
|
107
|
-
priority: 'critical',
|
|
108
|
-
title: '.env Not in .gitignore',
|
|
109
|
-
description: 'Environment files may be committed, exposing secrets.',
|
|
110
|
-
fix: 'Add .env* to your .gitignore file',
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return findings;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Run all security checks
|
|
119
|
-
*/
|
|
120
|
-
async function runChecks(projectPath, options = {}) {
|
|
121
|
-
const allFindings = [];
|
|
122
|
-
|
|
123
|
-
const checks = [
|
|
124
|
-
checkHTTPS,
|
|
125
|
-
checkSecurityHeaders,
|
|
126
|
-
checkEnvGitignore,
|
|
127
|
-
];
|
|
128
|
-
|
|
129
|
-
for (const check of checks) {
|
|
130
|
-
try {
|
|
131
|
-
const findings = await check(projectPath, options);
|
|
132
|
-
allFindings.push(...findings);
|
|
133
|
-
} catch (error) {
|
|
134
|
-
if (options.verbose) {
|
|
135
|
-
console.warn(`Check failed: ${check.name}`, error.message);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return allFindings;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
module.exports = {
|
|
144
|
-
runChecks,
|
|
145
|
-
checkHTTPS,
|
|
146
|
-
checkSecurityHeaders,
|
|
147
|
-
checkEnvGitignore,
|
|
148
|
-
};
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Polish Check Utilities
|
|
3
|
-
*
|
|
4
|
-
* Common file system and pattern matching utilities used by polish checks.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
"use strict";
|
|
8
|
-
|
|
9
|
-
const fs = require("fs");
|
|
10
|
-
const path = require("path");
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Check if a path exists
|
|
14
|
-
*/
|
|
15
|
-
async function pathExists(filePath) {
|
|
16
|
-
try {
|
|
17
|
-
await fs.promises.access(filePath);
|
|
18
|
-
return true;
|
|
19
|
-
} catch {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Check if a path exists (sync version)
|
|
26
|
-
*/
|
|
27
|
-
function pathExistsSync(filePath) {
|
|
28
|
-
try {
|
|
29
|
-
fs.accessSync(filePath);
|
|
30
|
-
return true;
|
|
31
|
-
} catch {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Read file contents safely
|
|
38
|
-
*/
|
|
39
|
-
async function readFileSafe(filePath) {
|
|
40
|
-
try {
|
|
41
|
-
return await fs.promises.readFile(filePath, 'utf8');
|
|
42
|
-
} catch {
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Read file contents safely (sync version)
|
|
49
|
-
*/
|
|
50
|
-
function readFileSafeSync(filePath) {
|
|
51
|
-
try {
|
|
52
|
-
return fs.readFileSync(filePath, 'utf8');
|
|
53
|
-
} catch {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Check if file contains a pattern
|
|
60
|
-
*/
|
|
61
|
-
async function fileContains(filePath, pattern) {
|
|
62
|
-
const content = await readFileSafe(filePath);
|
|
63
|
-
if (!content) return false;
|
|
64
|
-
return pattern.test(content);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Check if file contains a pattern (sync version)
|
|
69
|
-
*/
|
|
70
|
-
function fileContainsSync(filePath, pattern) {
|
|
71
|
-
const content = readFileSafeSync(filePath);
|
|
72
|
-
if (!content) return false;
|
|
73
|
-
return pattern.test(content);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Find all files matching a pattern
|
|
78
|
-
*/
|
|
79
|
-
async function findAllFiles(dir, pattern, maxDepth = 5, currentDepth = 0) {
|
|
80
|
-
if (currentDepth >= maxDepth) return [];
|
|
81
|
-
const results = [];
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
85
|
-
|
|
86
|
-
for (const entry of entries) {
|
|
87
|
-
// Skip hidden dirs, node_modules, etc.
|
|
88
|
-
if (entry.name.startsWith('.') ||
|
|
89
|
-
entry.name === 'node_modules' ||
|
|
90
|
-
entry.name === 'dist' ||
|
|
91
|
-
entry.name === 'build' ||
|
|
92
|
-
entry.name === '.next' ||
|
|
93
|
-
entry.name === 'coverage') {
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const fullPath = path.join(dir, entry.name);
|
|
98
|
-
|
|
99
|
-
if (entry.isDirectory()) {
|
|
100
|
-
const found = await findAllFiles(fullPath, pattern, maxDepth, currentDepth + 1);
|
|
101
|
-
results.push(...found);
|
|
102
|
-
} else if (pattern.test(entry.name)) {
|
|
103
|
-
results.push(fullPath);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
} catch {
|
|
107
|
-
// Ignore errors (permission issues, etc.)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return results;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Find all files matching a pattern (sync version)
|
|
115
|
-
*/
|
|
116
|
-
function findAllFilesSync(dir, pattern, maxDepth = 5, currentDepth = 0) {
|
|
117
|
-
if (currentDepth >= maxDepth) return [];
|
|
118
|
-
const results = [];
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
122
|
-
|
|
123
|
-
for (const entry of entries) {
|
|
124
|
-
if (entry.name.startsWith('.') ||
|
|
125
|
-
entry.name === 'node_modules' ||
|
|
126
|
-
entry.name === 'dist' ||
|
|
127
|
-
entry.name === 'build' ||
|
|
128
|
-
entry.name === '.next' ||
|
|
129
|
-
entry.name === 'coverage') {
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const fullPath = path.join(dir, entry.name);
|
|
134
|
-
|
|
135
|
-
if (entry.isDirectory()) {
|
|
136
|
-
const found = findAllFilesSync(fullPath, pattern, maxDepth, currentDepth + 1);
|
|
137
|
-
results.push(...found);
|
|
138
|
-
} else if (pattern.test(entry.name)) {
|
|
139
|
-
results.push(fullPath);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
} catch {
|
|
143
|
-
// Ignore errors
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return results;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Load package.json from a project
|
|
151
|
-
*/
|
|
152
|
-
async function loadPackageJson(projectPath) {
|
|
153
|
-
const pkgPath = path.join(projectPath, 'package.json');
|
|
154
|
-
const content = await readFileSafe(pkgPath);
|
|
155
|
-
if (!content) return null;
|
|
156
|
-
|
|
157
|
-
try {
|
|
158
|
-
return JSON.parse(content);
|
|
159
|
-
} catch {
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Load package.json from a project (sync version)
|
|
166
|
-
*/
|
|
167
|
-
function loadPackageJsonSync(projectPath) {
|
|
168
|
-
const pkgPath = path.join(projectPath, 'package.json');
|
|
169
|
-
const content = readFileSafeSync(pkgPath);
|
|
170
|
-
if (!content) return null;
|
|
171
|
-
|
|
172
|
-
try {
|
|
173
|
-
return JSON.parse(content);
|
|
174
|
-
} catch {
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Get all dependencies from package.json
|
|
181
|
-
*/
|
|
182
|
-
function getAllDependencies(pkg) {
|
|
183
|
-
if (!pkg) return {};
|
|
184
|
-
return {
|
|
185
|
-
...pkg.dependencies || {},
|
|
186
|
-
...pkg.devDependencies || {},
|
|
187
|
-
...pkg.peerDependencies || {},
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
module.exports = {
|
|
192
|
-
pathExists,
|
|
193
|
-
pathExistsSync,
|
|
194
|
-
readFileSafe,
|
|
195
|
-
readFileSafeSync,
|
|
196
|
-
fileContains,
|
|
197
|
-
fileContainsSync,
|
|
198
|
-
findAllFiles,
|
|
199
|
-
findAllFilesSync,
|
|
200
|
-
loadPackageJson,
|
|
201
|
-
loadPackageJsonSync,
|
|
202
|
-
getAllDependencies,
|
|
203
|
-
};
|