@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,105 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Type-Aware Analysis Engine
|
|
3
3
|
* Uses TypeScript type information for more accurate detection
|
|
4
|
-
* Enhanced with context-aware detection:
|
|
5
|
-
* - Legitimate uses of `any` in generics, catch clauses, type definitions
|
|
6
|
-
* - Non-null assertions preceded by null checks
|
|
7
|
-
* - @ts-ignore with explanatory comments
|
|
8
|
-
* - Framework-specific patterns (React, Next.js)
|
|
9
4
|
*/
|
|
10
5
|
|
|
11
6
|
const { getAST } = require("./ast-cache");
|
|
12
7
|
const traverse = require("@babel/traverse").default;
|
|
13
8
|
const t = require("@babel/types");
|
|
14
9
|
|
|
15
|
-
/**
|
|
16
|
-
* Contexts where `any` is legitimate
|
|
17
|
-
*/
|
|
18
|
-
const LEGITIMATE_ANY_CONTEXTS = [
|
|
19
|
-
// Catch clause parameter
|
|
20
|
-
/catch\s*\(\s*\w+\s*:\s*any/,
|
|
21
|
-
// Generic constraints
|
|
22
|
-
/<[^>]*any[^>]*>/,
|
|
23
|
-
// Type utility definitions
|
|
24
|
-
/type\s+\w+<.*any.*>/,
|
|
25
|
-
// Third-party library type fixes
|
|
26
|
-
/\/\/\s*@types\/|\/\/\s*TODO:\s*fix\s*types?/i,
|
|
27
|
-
// Conditional types
|
|
28
|
-
/extends\s+any/,
|
|
29
|
-
// Mapped types
|
|
30
|
-
/\[\s*\w+\s+in\s+keyof\s+any\s*\]/,
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Check if `any` is in a legitimate context
|
|
35
|
-
*/
|
|
36
|
-
function isLegitimateAnyContext(line, lines, lineIndex) {
|
|
37
|
-
// Check the current line
|
|
38
|
-
if (LEGITIMATE_ANY_CONTEXTS.some(pattern => pattern.test(line))) {
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Check surrounding context (type definitions often span multiple lines)
|
|
43
|
-
const start = Math.max(0, lineIndex - 2);
|
|
44
|
-
const end = Math.min(lines.length, lineIndex + 2);
|
|
45
|
-
const context = lines.slice(start, end).join('\n');
|
|
46
|
-
|
|
47
|
-
// Type definition files (.d.ts)
|
|
48
|
-
if (context.includes('declare ') || context.includes('export type ') || context.includes('export interface ')) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Event handlers often need any for native events
|
|
53
|
-
if (/on\w+\s*=|addEventListener|handleEvent/.test(context)) {
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// JSON parsing (any is common and acceptable)
|
|
58
|
-
if (/JSON\.parse|\.json\(\)|response\.json/.test(context)) {
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Check if non-null assertion is preceded by a null check
|
|
67
|
-
*/
|
|
68
|
-
function hasPrecedingNullCheck(lines, lineIndex, varName) {
|
|
69
|
-
// Look back a few lines for null checks
|
|
70
|
-
const start = Math.max(0, lineIndex - 5);
|
|
71
|
-
const context = lines.slice(start, lineIndex + 1).join('\n');
|
|
72
|
-
|
|
73
|
-
// Common null check patterns
|
|
74
|
-
const nullCheckPatterns = [
|
|
75
|
-
new RegExp(`if\\s*\\(\\s*!?${varName}\\s*\\)`, 'i'),
|
|
76
|
-
new RegExp(`if\\s*\\(\\s*${varName}\\s*!==?\\s*(?:null|undefined)`, 'i'),
|
|
77
|
-
new RegExp(`if\\s*\\(\\s*${varName}\\s*&&`, 'i'),
|
|
78
|
-
new RegExp(`${varName}\\s*&&\\s*${varName}`, 'i'),
|
|
79
|
-
new RegExp(`${varName}\\s*\\?\\?`, 'i'), // Nullish coalescing
|
|
80
|
-
/\.filter\(|\.find\(|\.some\(|\.every\(/, // Array methods often guarantee non-null
|
|
81
|
-
];
|
|
82
|
-
|
|
83
|
-
return nullCheckPatterns.some(pattern => pattern.test(context));
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Check if @ts-ignore has an explanation
|
|
88
|
-
*/
|
|
89
|
-
function hasExplanation(line, nextLine) {
|
|
90
|
-
// Check if the same line has an explanation
|
|
91
|
-
const hasInlineExplanation = /@ts-(?:ignore|expect-error)\s*[-:]\s*\w/.test(line);
|
|
92
|
-
if (hasInlineExplanation) return true;
|
|
93
|
-
|
|
94
|
-
// Check if there's a comment on the previous or next line explaining why
|
|
95
|
-
const explanationPatterns = [
|
|
96
|
-
/\/\/.*(?:because|due to|reason|workaround|todo|fixme|third[- ]?party|library|types? (?:issue|bug|missing))/i,
|
|
97
|
-
/\/\/.*https?:\/\//, // Link to issue/discussion
|
|
98
|
-
];
|
|
99
|
-
|
|
100
|
-
return explanationPatterns.some(pattern => pattern.test(line) || pattern.test(nextLine || ''));
|
|
101
|
-
}
|
|
102
|
-
|
|
103
10
|
/**
|
|
104
11
|
* Analyze type-related issues
|
|
105
12
|
*/
|
|
@@ -110,38 +17,13 @@ function analyzeTypeAware(code, filePath) {
|
|
|
110
17
|
|
|
111
18
|
const lines = code.split("\n");
|
|
112
19
|
const isTypeScript = filePath.endsWith(".ts") || filePath.endsWith(".tsx");
|
|
113
|
-
|
|
114
|
-
// Skip .d.ts declaration files (they legitimately use `any` for typing)
|
|
115
|
-
if (filePath.endsWith(".d.ts")) {
|
|
116
|
-
return findings;
|
|
117
|
-
}
|
|
118
20
|
|
|
119
21
|
// Type safety issues
|
|
120
22
|
traverse(ast, {
|
|
121
|
-
// Any types in TypeScript
|
|
23
|
+
// Any types in TypeScript
|
|
122
24
|
TSAnyKeyword(path) {
|
|
123
25
|
if (isTypeScript) {
|
|
124
26
|
const line = path.node.loc.start.line;
|
|
125
|
-
const lineContent = lines[line - 1] || "";
|
|
126
|
-
|
|
127
|
-
// Skip if in a legitimate context
|
|
128
|
-
if (isLegitimateAnyContext(lineContent, lines, line - 1)) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Check parent node for more context
|
|
133
|
-
const parent = path.parent;
|
|
134
|
-
|
|
135
|
-
// Skip catch clause parameters
|
|
136
|
-
if (t.isCatchClause(path.parentPath?.parent)) {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Skip type parameters (generics)
|
|
141
|
-
if (t.isTSTypeParameterDeclaration(parent)) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
27
|
findings.push({
|
|
146
28
|
type: "any_type",
|
|
147
29
|
severity: "WARN",
|
|
@@ -150,66 +32,40 @@ function analyzeTypeAware(code, filePath) {
|
|
|
150
32
|
line,
|
|
151
33
|
column: path.node.loc.start.column,
|
|
152
34
|
title: "Use of 'any' type",
|
|
153
|
-
message: "Using 'any' defeats TypeScript's type safety
|
|
154
|
-
codeSnippet:
|
|
35
|
+
message: "Using 'any' type defeats TypeScript's type safety",
|
|
36
|
+
codeSnippet: lines[line - 1]?.trim(),
|
|
155
37
|
confidence: "high",
|
|
156
|
-
fixHint: "Replace 'any' with a specific type or 'unknown' for type safety",
|
|
157
38
|
});
|
|
158
39
|
}
|
|
159
40
|
},
|
|
160
41
|
|
|
161
|
-
// @ts-ignore comments
|
|
42
|
+
// @ts-ignore comments
|
|
162
43
|
Comment(path) {
|
|
163
44
|
const comment = path.node;
|
|
164
45
|
if (comment.type === "CommentLine" || comment.type === "CommentBlock") {
|
|
165
46
|
const text = comment.value || "";
|
|
166
|
-
|
|
167
|
-
if (match) {
|
|
47
|
+
if (/@ts-ignore|@ts-expect-error|@ts-nocheck/.test(text)) {
|
|
168
48
|
const line = comment.loc.start.line;
|
|
169
|
-
const lineContent = lines[line - 1] || "";
|
|
170
|
-
const nextLine = lines[line] || "";
|
|
171
|
-
|
|
172
|
-
// Lower severity if has explanation or is @ts-expect-error (better practice)
|
|
173
|
-
const hasExplanationComment = hasExplanation(lineContent, nextLine);
|
|
174
|
-
const isExpectError = match[1] === "expect-error";
|
|
175
|
-
|
|
176
|
-
// @ts-nocheck on whole files is worse
|
|
177
|
-
const isNocheck = match[1] === "nocheck";
|
|
178
|
-
|
|
179
49
|
findings.push({
|
|
180
50
|
type: "ts_ignore",
|
|
181
|
-
severity:
|
|
51
|
+
severity: "WARN",
|
|
182
52
|
category: "TypeSafety",
|
|
183
53
|
file: filePath,
|
|
184
54
|
line,
|
|
185
55
|
column: comment.loc.start.column,
|
|
186
|
-
title:
|
|
187
|
-
message:
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
? `Using ${match[0]} with explanation - consider fixing the underlying issue`
|
|
191
|
-
: `Using ${match[0]} without explanation - add a comment explaining why`,
|
|
192
|
-
codeSnippet: lineContent.trim(),
|
|
193
|
-
confidence: hasExplanationComment ? "med" : "high",
|
|
194
|
-
fixHint: isExpectError
|
|
195
|
-
? "@ts-expect-error is preferred over @ts-ignore (fails if error goes away)"
|
|
196
|
-
: "Add an explanation comment or fix the underlying type issue",
|
|
56
|
+
title: "TypeScript error suppression",
|
|
57
|
+
message: `Using ${text.match(/@ts-\w+/)?.[0]} suppresses type checking - fix the underlying issue`,
|
|
58
|
+
codeSnippet: lines[line - 1]?.trim(),
|
|
59
|
+
confidence: "high",
|
|
197
60
|
});
|
|
198
61
|
}
|
|
199
62
|
}
|
|
200
63
|
},
|
|
201
64
|
|
|
202
|
-
// Unsafe type assertions (as any)
|
|
65
|
+
// Unsafe type assertions (as any)
|
|
203
66
|
TSAsExpression(path) {
|
|
204
67
|
if (t.isTSAnyKeyword(path.node.typeAnnotation)) {
|
|
205
68
|
const line = path.node.loc.start.line;
|
|
206
|
-
const lineContent = lines[line - 1] || "";
|
|
207
|
-
|
|
208
|
-
// Skip if in legitimate context
|
|
209
|
-
if (isLegitimateAnyContext(lineContent, lines, line - 1)) {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
69
|
findings.push({
|
|
214
70
|
type: "unsafe_type_assertion",
|
|
215
71
|
severity: "WARN",
|
|
@@ -218,48 +74,16 @@ function analyzeTypeAware(code, filePath) {
|
|
|
218
74
|
line,
|
|
219
75
|
column: path.node.loc.start.column,
|
|
220
76
|
title: "Unsafe type assertion (as any)",
|
|
221
|
-
message: "Type assertion to 'any' bypasses type checking
|
|
222
|
-
codeSnippet:
|
|
77
|
+
message: "Type assertion to 'any' bypasses type checking",
|
|
78
|
+
codeSnippet: lines[line - 1]?.trim(),
|
|
223
79
|
confidence: "high",
|
|
224
|
-
fixHint: "Use 'as unknown as Type' for explicit type narrowing or fix the underlying type issue",
|
|
225
80
|
});
|
|
226
81
|
}
|
|
227
82
|
},
|
|
228
83
|
|
|
229
|
-
// Non-null assertions (!)
|
|
84
|
+
// Non-null assertions (!)
|
|
230
85
|
TSNonNullExpression(path) {
|
|
231
86
|
const line = path.node.loc.start.line;
|
|
232
|
-
const lineContent = lines[line - 1] || "";
|
|
233
|
-
|
|
234
|
-
// Try to get the variable name being asserted
|
|
235
|
-
let varName = "";
|
|
236
|
-
if (t.isIdentifier(path.node.expression)) {
|
|
237
|
-
varName = path.node.expression.name;
|
|
238
|
-
} else if (t.isMemberExpression(path.node.expression)) {
|
|
239
|
-
// Get the full member expression (e.g., "obj.prop")
|
|
240
|
-
if (t.isIdentifier(path.node.expression.property)) {
|
|
241
|
-
varName = path.node.expression.property.name;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Skip if there's a preceding null check
|
|
246
|
-
if (varName && hasPrecedingNullCheck(lines, line - 1, varName)) {
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Skip common safe patterns
|
|
251
|
-
const safePatterns = [
|
|
252
|
-
/\.filter\([^)]+\).*!/, // After filter
|
|
253
|
-
/\.find\([^)]+\).*!/, // After find with condition
|
|
254
|
-
/assert.*!/, // After assertion
|
|
255
|
-
/if\s*\(.*!\s*\)/, // Inside if condition
|
|
256
|
-
/\?\?.*!/, // After nullish coalescing
|
|
257
|
-
];
|
|
258
|
-
|
|
259
|
-
if (safePatterns.some(p => p.test(lineContent))) {
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
87
|
findings.push({
|
|
264
88
|
type: "non_null_assertion",
|
|
265
89
|
severity: "WARN",
|
|
@@ -269,99 +93,51 @@ function analyzeTypeAware(code, filePath) {
|
|
|
269
93
|
column: path.node.loc.start.column,
|
|
270
94
|
title: "Non-null assertion operator (!)",
|
|
271
95
|
message: "Non-null assertion can cause runtime errors if value is null/undefined",
|
|
272
|
-
codeSnippet:
|
|
96
|
+
codeSnippet: lines[line - 1]?.trim(),
|
|
273
97
|
confidence: "med",
|
|
274
|
-
fixHint: "Add a null check before using the value, or use optional chaining (?.) with a default",
|
|
275
98
|
});
|
|
276
99
|
},
|
|
277
100
|
|
|
278
|
-
//
|
|
279
|
-
|
|
101
|
+
// Optional chaining without null check
|
|
102
|
+
OptionalMemberExpression(path) {
|
|
103
|
+
// Check if result is used without null check
|
|
104
|
+
const parent = path.parent;
|
|
105
|
+
if (!t.isIfStatement(parent) && !t.isConditionalExpression(parent)) {
|
|
106
|
+
const line = path.node.loc.start.line;
|
|
107
|
+
findings.push({
|
|
108
|
+
type: "unsafe_optional_chaining",
|
|
109
|
+
severity: "WARN",
|
|
110
|
+
category: "TypeSafety",
|
|
111
|
+
file: filePath,
|
|
112
|
+
line,
|
|
113
|
+
column: path.node.loc.start.column,
|
|
114
|
+
title: "Optional chaining without null check",
|
|
115
|
+
message: "Optional chaining result should be checked for null/undefined",
|
|
116
|
+
codeSnippet: lines[line - 1]?.trim(),
|
|
117
|
+
confidence: "low",
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
},
|
|
280
121
|
});
|
|
281
122
|
|
|
282
|
-
// Missing return type annotations
|
|
123
|
+
// Missing return type annotations
|
|
283
124
|
if (isTypeScript) {
|
|
284
125
|
traverse(ast, {
|
|
285
126
|
FunctionDeclaration(path) {
|
|
286
127
|
const node = path.node;
|
|
287
128
|
if (!node.returnType && node.id) {
|
|
288
|
-
// Only flag exported functions (public API)
|
|
289
|
-
const isExported = path.parent &&
|
|
290
|
-
(t.isExportNamedDeclaration(path.parent) ||
|
|
291
|
-
t.isExportDefaultDeclaration(path.parent));
|
|
292
|
-
|
|
293
|
-
// Skip short utility functions (likely internal)
|
|
294
|
-
const lineCount = node.loc.end.line - node.loc.start.line;
|
|
295
|
-
if (!isExported && lineCount < 5) {
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Skip functions that clearly return void (no return statement or only return;)
|
|
300
|
-
let hasNonVoidReturn = false;
|
|
301
|
-
traverse(node, {
|
|
302
|
-
ReturnStatement(returnPath) {
|
|
303
|
-
if (returnPath.node.argument) {
|
|
304
|
-
hasNonVoidReturn = true;
|
|
305
|
-
}
|
|
306
|
-
},
|
|
307
|
-
}, path.scope, path);
|
|
308
|
-
|
|
309
|
-
if (!hasNonVoidReturn && !isExported) {
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
129
|
const line = node.loc.start.line;
|
|
314
130
|
findings.push({
|
|
315
131
|
type: "missing_return_type",
|
|
316
|
-
severity:
|
|
132
|
+
severity: "WARN",
|
|
317
133
|
category: "TypeSafety",
|
|
318
134
|
file: filePath,
|
|
319
135
|
line,
|
|
320
136
|
column: node.loc.start.column,
|
|
321
|
-
title: `Missing return type: ${node.id.name}`,
|
|
322
|
-
message:
|
|
323
|
-
? "Exported function should have explicit return type for better API documentation"
|
|
324
|
-
: "Consider adding return type annotation for clarity",
|
|
137
|
+
title: `Missing return type annotation: ${node.id.name}`,
|
|
138
|
+
message: "Function should have explicit return type annotation",
|
|
325
139
|
codeSnippet: lines[line - 1]?.trim(),
|
|
326
140
|
confidence: "med",
|
|
327
|
-
fixHint: "Add return type annotation after the parameters: function name(): ReturnType",
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
},
|
|
331
|
-
|
|
332
|
-
// Also check arrow functions assigned to exports
|
|
333
|
-
ArrowFunctionExpression(path) {
|
|
334
|
-
const parent = path.parent;
|
|
335
|
-
const grandparent = path.parentPath?.parent;
|
|
336
|
-
|
|
337
|
-
// Check if it's an exported arrow function
|
|
338
|
-
const isExportedConst =
|
|
339
|
-
t.isVariableDeclarator(parent) &&
|
|
340
|
-
t.isVariableDeclaration(grandparent) &&
|
|
341
|
-
path.parentPath?.parentPath?.parent &&
|
|
342
|
-
(t.isExportNamedDeclaration(path.parentPath.parentPath.parent) ||
|
|
343
|
-
t.isExportDefaultDeclaration(path.parentPath.parentPath.parent));
|
|
344
|
-
|
|
345
|
-
if (isExportedConst && !path.node.returnType) {
|
|
346
|
-
const varName = parent.id?.name || "anonymous";
|
|
347
|
-
const line = path.node.loc.start.line;
|
|
348
|
-
|
|
349
|
-
// Skip short arrow functions
|
|
350
|
-
const lineCount = path.node.loc.end.line - path.node.loc.start.line;
|
|
351
|
-
if (lineCount < 3) return;
|
|
352
|
-
|
|
353
|
-
findings.push({
|
|
354
|
-
type: "missing_return_type",
|
|
355
|
-
severity: "INFO",
|
|
356
|
-
category: "TypeSafety",
|
|
357
|
-
file: filePath,
|
|
358
|
-
line,
|
|
359
|
-
column: path.node.loc.start.column,
|
|
360
|
-
title: `Missing return type: ${varName}`,
|
|
361
|
-
message: "Exported arrow function could benefit from explicit return type",
|
|
362
|
-
codeSnippet: lines[line - 1]?.trim(),
|
|
363
|
-
confidence: "low",
|
|
364
|
-
fixHint: "Add return type: const fn = (): ReturnType => { ... }",
|
|
365
141
|
});
|
|
366
142
|
}
|
|
367
143
|
},
|
|
@@ -1,124 +1,15 @@
|
|
|
1
|
-
// Core utilities (use parent directory versions - newer/enhanced)
|
|
2
|
-
const astCache = require('../ast-cache');
|
|
3
|
-
const fileFilter = require('../file-filter');
|
|
4
|
-
const parallelProcessor = require('../parallel-processor');
|
|
5
|
-
|
|
6
|
-
// Analysis engines (use parent directory versions when available - they're newer)
|
|
7
|
-
const deadCodeEngine = require('../dead-code-engine');
|
|
8
|
-
const emptyCatchEngine = require('../empty-catch-engine');
|
|
9
|
-
const codeQualityEngine = require('../code-quality-engine');
|
|
10
|
-
const consoleLogsEngine = require('../console-logs-engine');
|
|
11
|
-
const deprecatedApiEngine = require('../deprecated-api-engine'); // Use enhanced top-level version
|
|
12
|
-
const hardcodedSecretsEngine = require('../hardcoded-secrets-engine'); // Use top-level version
|
|
13
|
-
const mockDataEngine = require('../mock-data-engine'); // Use enhanced top-level version
|
|
14
|
-
const performanceIssuesEngine = require('../performance-issues-engine');
|
|
15
|
-
const typeAwareEngine = require('../type-aware-engine');
|
|
16
|
-
const unsafeRegexEngine = require('../unsafe-regex-engine');
|
|
17
|
-
|
|
18
|
-
// NEW: Advanced vibecheck engines
|
|
19
|
-
const aiHallucinationEngine = require('./lib/ai-hallucination-engine');
|
|
20
|
-
const vibeScoreEngine = require('./lib/vibe-score-engine');
|
|
21
|
-
const smartFixEngine = require('./lib/smart-fix-engine');
|
|
22
|
-
|
|
23
|
-
// New engines from parent directory
|
|
24
|
-
const bundleSizeEngine = require('../bundle-size-engine');
|
|
25
|
-
const duplicateCodeEngine = require('../duplicate-code-engine');
|
|
26
|
-
const envVariablesEngine = require('../env-variables-engine');
|
|
27
|
-
const asyncPatternsEngine = require('../async-patterns-engine');
|
|
28
|
-
const namingConventionsEngine = require('../naming-conventions-engine');
|
|
29
|
-
const importOrderEngine = require('../import-order-engine');
|
|
30
|
-
const reactPatternsEngine = require('../react-patterns-engine');
|
|
31
|
-
const errorHandlingEngine = require('../error-handling-engine');
|
|
32
|
-
const databasePatternsEngine = require('../database-patterns-engine');
|
|
33
|
-
|
|
34
|
-
// Shared utilities from parent engines directory
|
|
35
|
-
const confidenceScoring = require('../confidence-scoring');
|
|
36
|
-
const frameworkDetection = require('../framework-detection');
|
|
37
|
-
const contextDetection = require('../context-detection');
|
|
38
|
-
|
|
39
1
|
module.exports = {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
analyzeConsoleLogs: consoleLogsEngine.analyzeConsoleLogs,
|
|
54
|
-
analyzeDeprecatedApi: deprecatedApiEngine.analyzeDeprecatedApi,
|
|
55
|
-
analyzeHardcodedSecrets: hardcodedSecretsEngine.analyzeHardcodedSecrets,
|
|
56
|
-
analyzeMockData: mockDataEngine.analyzeMockData,
|
|
57
|
-
analyzePerformanceIssues: performanceIssuesEngine.analyzePerformanceIssues,
|
|
58
|
-
analyzeTypeAware: typeAwareEngine.analyzeTypeAware,
|
|
59
|
-
analyzeUnsafeRegex: unsafeRegexEngine.analyzeUnsafeRegex,
|
|
60
|
-
|
|
61
|
-
// NEW: Advanced vibecheck analysis
|
|
62
|
-
analyzeAIHallucinations: aiHallucinationEngine.analyzeAIHallucinations,
|
|
63
|
-
calculateVibeScore: vibeScoreEngine.calculateVibeScore,
|
|
64
|
-
generateVibeReport: vibeScoreEngine.generateVibeReport,
|
|
65
|
-
generateVibeReportJSON: vibeScoreEngine.generateVibeReportJSON,
|
|
66
|
-
generateFixSuggestions: smartFixEngine.generateFixSuggestions,
|
|
67
|
-
generateFixPlan: smartFixEngine.generateFixPlan,
|
|
68
|
-
|
|
69
|
-
// NEW: Engine exports for direct access
|
|
70
|
-
aiHallucinationEngine,
|
|
71
|
-
vibeScoreEngine,
|
|
72
|
-
smartFixEngine,
|
|
73
|
-
|
|
74
|
-
// New analysis functions
|
|
75
|
-
analyzeBundleSize: bundleSizeEngine.analyzeBundleSize,
|
|
76
|
-
analyzeDuplicateCode: duplicateCodeEngine.analyzeDuplicateCode,
|
|
77
|
-
findDuplicatesAcrossFiles: duplicateCodeEngine.findDuplicatesAcrossFiles,
|
|
78
|
-
analyzeEnvVariables: envVariablesEngine.analyzeEnvVariables,
|
|
79
|
-
analyzeEnvSetup: envVariablesEngine.analyzeEnvSetup,
|
|
80
|
-
analyzeAsyncPatterns: asyncPatternsEngine.analyzeAsyncPatterns,
|
|
81
|
-
analyzeNamingConventions: namingConventionsEngine.analyzeNamingConventions,
|
|
82
|
-
analyzeImportOrder: importOrderEngine.analyzeImportOrder,
|
|
83
|
-
analyzeReactPatterns: reactPatternsEngine.analyzeReactPatterns,
|
|
84
|
-
analyzeErrorHandling: errorHandlingEngine.analyzeErrorHandling,
|
|
85
|
-
analyzeDatabasePatterns: databasePatternsEngine.analyzeDatabasePatterns,
|
|
86
|
-
|
|
87
|
-
// Shared utilities
|
|
88
|
-
confidenceScoring,
|
|
89
|
-
frameworkDetection,
|
|
90
|
-
contextDetection,
|
|
91
|
-
bundleSizeEngine,
|
|
92
|
-
duplicateCodeEngine,
|
|
93
|
-
envVariablesEngine,
|
|
94
|
-
asyncPatternsEngine,
|
|
95
|
-
namingConventionsEngine,
|
|
96
|
-
importOrderEngine,
|
|
97
|
-
reactPatternsEngine,
|
|
98
|
-
errorHandlingEngine,
|
|
99
|
-
databasePatternsEngine,
|
|
100
|
-
|
|
101
|
-
// Confidence scoring exports (for convenience)
|
|
102
|
-
CONFIDENCE: confidenceScoring.CONFIDENCE,
|
|
103
|
-
createFinding: confidenceScoring.createFinding,
|
|
104
|
-
normalizeConfidence: confidenceScoring.normalizeConfidence,
|
|
105
|
-
|
|
106
|
-
// Framework detection exports (for convenience)
|
|
107
|
-
FRAMEWORKS: frameworkDetection.FRAMEWORKS,
|
|
108
|
-
getFileContext: frameworkDetection.getFileContext,
|
|
109
|
-
hasFramework: frameworkDetection.hasFramework,
|
|
110
|
-
|
|
111
|
-
// Bundle size exports
|
|
112
|
-
HEAVY_PACKAGES: bundleSizeEngine.HEAVY_PACKAGES,
|
|
113
|
-
isClientFile: bundleSizeEngine.isClientFile,
|
|
114
|
-
|
|
115
|
-
// Vibe Score exports (for convenience)
|
|
116
|
-
SCORE_WEIGHTS: vibeScoreEngine.SCORE_WEIGHTS,
|
|
117
|
-
GRADE_THRESHOLDS: vibeScoreEngine.GRADE_THRESHOLDS,
|
|
118
|
-
|
|
119
|
-
// AI Hallucination exports
|
|
120
|
-
HALLUCINATION_PATTERNS: aiHallucinationEngine.HALLUCINATION_PATTERNS,
|
|
121
|
-
|
|
122
|
-
// Smart Fix exports
|
|
123
|
-
FIX_TEMPLATES: smartFixEngine.FIX_TEMPLATES,
|
|
2
|
+
...require('./lib/ast-cache'),
|
|
3
|
+
fileFilter: require('./lib/file-filter'),
|
|
4
|
+
parallelProcessor: require('./lib/parallel-processor'),
|
|
5
|
+
analyzeDeadCode: require('./lib/dead-code-engine').analyzeDeadCode,
|
|
6
|
+
analyzeEmptyCatch: require('./lib/empty-catch-engine').analyzeEmptyCatch,
|
|
7
|
+
analyzeCodeQuality: require('./lib/code-quality-engine').analyzeCodeQuality,
|
|
8
|
+
analyzeConsoleLogs: require('./lib/console-logs-engine').analyzeConsoleLogs,
|
|
9
|
+
analyzeDeprecatedApi: require('./lib/deprecated-api-engine').analyzeDeprecatedApi,
|
|
10
|
+
analyzeHardcodedSecrets: require('./lib/hardcoded-secrets-engine').analyzeHardcodedSecrets,
|
|
11
|
+
analyzeMockData: require('./lib/mock-data-engine').analyzeMockData,
|
|
12
|
+
analyzePerformanceIssues: require('./lib/performance-issues-engine').analyzePerformanceIssues,
|
|
13
|
+
analyzeTypeAware: require('./lib/type-aware-engine').analyzeTypeAware,
|
|
14
|
+
analyzeUnsafeRegex: require('./lib/unsafe-regex-engine').analyzeUnsafeRegex,
|
|
124
15
|
};
|