vaspera 2.9.2 → 2.10.1
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/CHANGELOG.md +68 -0
- package/README.md +58 -1
- package/dist/__tests__/autofix/branch-manager.test.d.ts +2 -0
- package/dist/__tests__/autofix/branch-manager.test.d.ts.map +1 -0
- package/dist/__tests__/autofix/branch-manager.test.js +60 -0
- package/dist/__tests__/autofix/branch-manager.test.js.map +1 -0
- package/dist/__tests__/autofix/commit-generator.test.d.ts +2 -0
- package/dist/__tests__/autofix/commit-generator.test.d.ts.map +1 -0
- package/dist/__tests__/autofix/commit-generator.test.js +147 -0
- package/dist/__tests__/autofix/commit-generator.test.js.map +1 -0
- package/dist/__tests__/autofix/constitution.test.d.ts +9 -0
- package/dist/__tests__/autofix/constitution.test.d.ts.map +1 -0
- package/dist/__tests__/autofix/constitution.test.js +421 -0
- package/dist/__tests__/autofix/constitution.test.js.map +1 -0
- package/dist/__tests__/autofix/pr-generator.test.d.ts +2 -0
- package/dist/__tests__/autofix/pr-generator.test.d.ts.map +1 -0
- package/dist/__tests__/autofix/pr-generator.test.js +152 -0
- package/dist/__tests__/autofix/pr-generator.test.js.map +1 -0
- package/dist/__tests__/property-test-helpers.d.ts +87 -0
- package/dist/__tests__/property-test-helpers.d.ts.map +1 -0
- package/dist/__tests__/property-test-helpers.js +136 -0
- package/dist/__tests__/property-test-helpers.js.map +1 -0
- package/dist/__tests__/scanners/ai-code/ai-detector.test.d.ts +2 -0
- package/dist/__tests__/scanners/ai-code/ai-detector.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/ai-code/ai-detector.test.js +188 -0
- package/dist/__tests__/scanners/ai-code/ai-detector.test.js.map +1 -0
- package/dist/__tests__/scanners/ai-code/confidence-scorer.test.d.ts +2 -0
- package/dist/__tests__/scanners/ai-code/confidence-scorer.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/ai-code/confidence-scorer.test.js +363 -0
- package/dist/__tests__/scanners/ai-code/confidence-scorer.test.js.map +1 -0
- package/dist/__tests__/scanners/ai-code/hallucination-checker.test.d.ts +2 -0
- package/dist/__tests__/scanners/ai-code/hallucination-checker.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/ai-code/hallucination-checker.test.js +226 -0
- package/dist/__tests__/scanners/ai-code/hallucination-checker.test.js.map +1 -0
- package/dist/__tests__/scanners/ai-code/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/ai-code/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/ai-code/index.test.js +214 -0
- package/dist/__tests__/scanners/ai-code/index.test.js.map +1 -0
- package/dist/__tests__/scanners/dast/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/dast/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/dast/index.test.js +183 -0
- package/dist/__tests__/scanners/dast/index.test.js.map +1 -0
- package/dist/__tests__/scanners/dast/nuclei.test.d.ts +2 -0
- package/dist/__tests__/scanners/dast/nuclei.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/dast/nuclei.test.js +166 -0
- package/dist/__tests__/scanners/dast/nuclei.test.js.map +1 -0
- package/dist/__tests__/scanners/dast/zap.test.d.ts +2 -0
- package/dist/__tests__/scanners/dast/zap.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/dast/zap.test.js +158 -0
- package/dist/__tests__/scanners/dast/zap.test.js.map +1 -0
- package/dist/__tests__/scanners/deploy/health-checker.test.d.ts +2 -0
- package/dist/__tests__/scanners/deploy/health-checker.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/deploy/health-checker.test.js +67 -0
- package/dist/__tests__/scanners/deploy/health-checker.test.js.map +1 -0
- package/dist/__tests__/scanners/deploy/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/deploy/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/deploy/index.test.js +84 -0
- package/dist/__tests__/scanners/deploy/index.test.js.map +1 -0
- package/dist/__tests__/scanners/deploy/provider-detector.test.d.ts +2 -0
- package/dist/__tests__/scanners/deploy/provider-detector.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/deploy/provider-detector.test.js +88 -0
- package/dist/__tests__/scanners/deploy/provider-detector.test.js.map +1 -0
- package/dist/__tests__/scanners/deploy/types.test.d.ts +2 -0
- package/dist/__tests__/scanners/deploy/types.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/deploy/types.test.js +126 -0
- package/dist/__tests__/scanners/deploy/types.test.js.map +1 -0
- package/dist/__tests__/scanners/fp-feedback.test.d.ts +2 -0
- package/dist/__tests__/scanners/fp-feedback.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/fp-feedback.test.js +202 -0
- package/dist/__tests__/scanners/fp-feedback.test.js.map +1 -0
- package/dist/__tests__/scanners/fp-filter.property.test.d.ts +9 -0
- package/dist/__tests__/scanners/fp-filter.property.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/fp-filter.property.test.js +253 -0
- package/dist/__tests__/scanners/fp-filter.property.test.js.map +1 -0
- package/dist/__tests__/scanners/fp-filter.test.d.ts +2 -0
- package/dist/__tests__/scanners/fp-filter.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/fp-filter.test.js +234 -0
- package/dist/__tests__/scanners/fp-filter.test.js.map +1 -0
- package/dist/__tests__/scanners/fp-tracker.test.d.ts +2 -0
- package/dist/__tests__/scanners/fp-tracker.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/fp-tracker.test.js +262 -0
- package/dist/__tests__/scanners/fp-tracker.test.js.map +1 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.d.ts +10 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.js +238 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.js.map +1 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.test.d.ts +2 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.test.js +55 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.test.js.map +1 -0
- package/dist/__tests__/scanners/logic/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/logic/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/logic/index.test.js +165 -0
- package/dist/__tests__/scanners/logic/index.test.js.map +1 -0
- package/dist/__tests__/scanners/logic/types.test.d.ts +2 -0
- package/dist/__tests__/scanners/logic/types.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/logic/types.test.js +85 -0
- package/dist/__tests__/scanners/logic/types.test.js.map +1 -0
- package/dist/__tests__/scanners/runtime/app-launcher.test.d.ts +2 -0
- package/dist/__tests__/scanners/runtime/app-launcher.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/runtime/app-launcher.test.js +94 -0
- package/dist/__tests__/scanners/runtime/app-launcher.test.js.map +1 -0
- package/dist/__tests__/scanners/runtime/golden-path-runner.test.d.ts +2 -0
- package/dist/__tests__/scanners/runtime/golden-path-runner.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/runtime/golden-path-runner.test.js +195 -0
- package/dist/__tests__/scanners/runtime/golden-path-runner.test.js.map +1 -0
- package/dist/__tests__/scanners/runtime/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/runtime/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/runtime/index.test.js +120 -0
- package/dist/__tests__/scanners/runtime/index.test.js.map +1 -0
- package/dist/__tests__/scanners/runtime/types.test.d.ts +2 -0
- package/dist/__tests__/scanners/runtime/types.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/runtime/types.test.js +126 -0
- package/dist/__tests__/scanners/runtime/types.test.js.map +1 -0
- package/dist/__tests__/scanners/scale/bottleneck-detector.test.d.ts +2 -0
- package/dist/__tests__/scanners/scale/bottleneck-detector.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/scale/bottleneck-detector.test.js +187 -0
- package/dist/__tests__/scanners/scale/bottleneck-detector.test.js.map +1 -0
- package/dist/__tests__/scanners/scale/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/scale/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/scale/index.test.js +87 -0
- package/dist/__tests__/scanners/scale/index.test.js.map +1 -0
- package/dist/__tests__/scanners/scale/load-profiler.test.d.ts +2 -0
- package/dist/__tests__/scanners/scale/load-profiler.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/scale/load-profiler.test.js +122 -0
- package/dist/__tests__/scanners/scale/load-profiler.test.js.map +1 -0
- package/dist/__tests__/scanners/scale/types.test.d.ts +2 -0
- package/dist/__tests__/scanners/scale/types.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/scale/types.test.js +129 -0
- package/dist/__tests__/scanners/scale/types.test.js.map +1 -0
- package/dist/action/pr-comment.test.js +4 -0
- package/dist/action/pr-comment.test.js.map +1 -1
- package/dist/action/sarif-upload.test.js +4 -0
- package/dist/action/sarif-upload.test.js.map +1 -1
- package/dist/autofix/branch-manager.d.ts +115 -0
- package/dist/autofix/branch-manager.d.ts.map +1 -0
- package/dist/autofix/branch-manager.js +308 -0
- package/dist/autofix/branch-manager.js.map +1 -0
- package/dist/autofix/commit-generator.d.ts +55 -0
- package/dist/autofix/commit-generator.d.ts.map +1 -0
- package/dist/autofix/commit-generator.js +277 -0
- package/dist/autofix/commit-generator.js.map +1 -0
- package/dist/autofix/constitution.d.ts +77 -0
- package/dist/autofix/constitution.d.ts.map +1 -0
- package/dist/autofix/constitution.js +261 -0
- package/dist/autofix/constitution.js.map +1 -0
- package/dist/autofix/constitution.schema.d.ts +441 -0
- package/dist/autofix/constitution.schema.d.ts.map +1 -0
- package/dist/autofix/constitution.schema.js +144 -0
- package/dist/autofix/constitution.schema.js.map +1 -0
- package/dist/autofix/index.d.ts +13 -0
- package/dist/autofix/index.d.ts.map +1 -0
- package/dist/autofix/index.js +15 -0
- package/dist/autofix/index.js.map +1 -0
- package/dist/autofix/pr-generator.d.ts +57 -0
- package/dist/autofix/pr-generator.d.ts.map +1 -0
- package/dist/autofix/pr-generator.js +597 -0
- package/dist/autofix/pr-generator.js.map +1 -0
- package/dist/autofix/types.d.ts +151 -0
- package/dist/autofix/types.d.ts.map +1 -0
- package/dist/autofix/types.js +22 -0
- package/dist/autofix/types.js.map +1 -0
- package/dist/eval/fixtures.d.ts +20 -0
- package/dist/eval/fixtures.d.ts.map +1 -1
- package/dist/eval/fixtures.js +430 -0
- package/dist/eval/fixtures.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +874 -0
- package/dist/index.js.map +1 -1
- package/dist/install-skills.d.ts +11 -0
- package/dist/install-skills.d.ts.map +1 -0
- package/dist/install-skills.js +81 -0
- package/dist/install-skills.js.map +1 -0
- package/dist/scanners/ai-code/ai-detector.d.ts +25 -0
- package/dist/scanners/ai-code/ai-detector.d.ts.map +1 -0
- package/dist/scanners/ai-code/ai-detector.js +192 -0
- package/dist/scanners/ai-code/ai-detector.js.map +1 -0
- package/dist/scanners/ai-code/confidence-scorer.d.ts +40 -0
- package/dist/scanners/ai-code/confidence-scorer.d.ts.map +1 -0
- package/dist/scanners/ai-code/confidence-scorer.js +148 -0
- package/dist/scanners/ai-code/confidence-scorer.js.map +1 -0
- package/dist/scanners/ai-code/hallucination-checker.d.ts +36 -0
- package/dist/scanners/ai-code/hallucination-checker.d.ts.map +1 -0
- package/dist/scanners/ai-code/hallucination-checker.js +298 -0
- package/dist/scanners/ai-code/hallucination-checker.js.map +1 -0
- package/dist/scanners/ai-code/index.d.ts +30 -0
- package/dist/scanners/ai-code/index.d.ts.map +1 -0
- package/dist/scanners/ai-code/index.js +224 -0
- package/dist/scanners/ai-code/index.js.map +1 -0
- package/dist/scanners/ai-code/types.d.ts +192 -0
- package/dist/scanners/ai-code/types.d.ts.map +1 -0
- package/dist/scanners/ai-code/types.js +37 -0
- package/dist/scanners/ai-code/types.js.map +1 -0
- package/dist/scanners/cache.d.ts.map +1 -1
- package/dist/scanners/cache.js +4 -0
- package/dist/scanners/cache.js.map +1 -1
- package/dist/scanners/dast/index.d.ts +39 -0
- package/dist/scanners/dast/index.d.ts.map +1 -0
- package/dist/scanners/dast/index.js +259 -0
- package/dist/scanners/dast/index.js.map +1 -0
- package/dist/scanners/dast/nuclei.d.ts +26 -0
- package/dist/scanners/dast/nuclei.d.ts.map +1 -0
- package/dist/scanners/dast/nuclei.js +354 -0
- package/dist/scanners/dast/nuclei.js.map +1 -0
- package/dist/scanners/dast/types.d.ts +306 -0
- package/dist/scanners/dast/types.d.ts.map +1 -0
- package/dist/scanners/dast/types.js +52 -0
- package/dist/scanners/dast/types.js.map +1 -0
- package/dist/scanners/dast/zap.d.ts +26 -0
- package/dist/scanners/dast/zap.d.ts.map +1 -0
- package/dist/scanners/dast/zap.js +453 -0
- package/dist/scanners/dast/zap.js.map +1 -0
- package/dist/scanners/deploy/health-checker.d.ts +38 -0
- package/dist/scanners/deploy/health-checker.d.ts.map +1 -0
- package/dist/scanners/deploy/health-checker.js +272 -0
- package/dist/scanners/deploy/health-checker.js.map +1 -0
- package/dist/scanners/deploy/index.d.ts +44 -0
- package/dist/scanners/deploy/index.d.ts.map +1 -0
- package/dist/scanners/deploy/index.js +208 -0
- package/dist/scanners/deploy/index.js.map +1 -0
- package/dist/scanners/deploy/provider-detector.d.ts +25 -0
- package/dist/scanners/deploy/provider-detector.d.ts.map +1 -0
- package/dist/scanners/deploy/provider-detector.js +177 -0
- package/dist/scanners/deploy/provider-detector.js.map +1 -0
- package/dist/scanners/deploy/types.d.ts +406 -0
- package/dist/scanners/deploy/types.d.ts.map +1 -0
- package/dist/scanners/deploy/types.js +58 -0
- package/dist/scanners/deploy/types.js.map +1 -0
- package/dist/scanners/deploy/vercel-integration.d.ts +52 -0
- package/dist/scanners/deploy/vercel-integration.d.ts.map +1 -0
- package/dist/scanners/deploy/vercel-integration.js +280 -0
- package/dist/scanners/deploy/vercel-integration.js.map +1 -0
- package/dist/scanners/fp-feedback.d.ts +140 -0
- package/dist/scanners/fp-feedback.d.ts.map +1 -0
- package/dist/scanners/fp-feedback.js +292 -0
- package/dist/scanners/fp-feedback.js.map +1 -0
- package/dist/scanners/fp-filter.d.ts +94 -0
- package/dist/scanners/fp-filter.d.ts.map +1 -0
- package/dist/scanners/fp-filter.js +397 -0
- package/dist/scanners/fp-filter.js.map +1 -0
- package/dist/scanners/fp-tracker.d.ts +125 -0
- package/dist/scanners/fp-tracker.d.ts.map +1 -0
- package/dist/scanners/fp-tracker.js +330 -0
- package/dist/scanners/fp-tracker.js.map +1 -0
- package/dist/scanners/index.d.ts.map +1 -1
- package/dist/scanners/index.js +56 -0
- package/dist/scanners/index.js.map +1 -1
- package/dist/scanners/index.test.js +6 -6
- package/dist/scanners/index.test.js.map +1 -1
- package/dist/scanners/logic/auth-flow-analyzer.d.ts +18 -0
- package/dist/scanners/logic/auth-flow-analyzer.d.ts.map +1 -0
- package/dist/scanners/logic/auth-flow-analyzer.js +384 -0
- package/dist/scanners/logic/auth-flow-analyzer.js.map +1 -0
- package/dist/scanners/logic/endpoint-analyzer.d.ts +29 -0
- package/dist/scanners/logic/endpoint-analyzer.d.ts.map +1 -0
- package/dist/scanners/logic/endpoint-analyzer.js +528 -0
- package/dist/scanners/logic/endpoint-analyzer.js.map +1 -0
- package/dist/scanners/logic/index.d.ts +41 -0
- package/dist/scanners/logic/index.d.ts.map +1 -0
- package/dist/scanners/logic/index.js +268 -0
- package/dist/scanners/logic/index.js.map +1 -0
- package/dist/scanners/logic/types.d.ts +254 -0
- package/dist/scanners/logic/types.d.ts.map +1 -0
- package/dist/scanners/logic/types.js +142 -0
- package/dist/scanners/logic/types.js.map +1 -0
- package/dist/scanners/runtime/app-launcher.d.ts +33 -0
- package/dist/scanners/runtime/app-launcher.d.ts.map +1 -0
- package/dist/scanners/runtime/app-launcher.js +419 -0
- package/dist/scanners/runtime/app-launcher.js.map +1 -0
- package/dist/scanners/runtime/golden-path-runner.d.ts +48 -0
- package/dist/scanners/runtime/golden-path-runner.d.ts.map +1 -0
- package/dist/scanners/runtime/golden-path-runner.js +373 -0
- package/dist/scanners/runtime/golden-path-runner.js.map +1 -0
- package/dist/scanners/runtime/index.d.ts +41 -0
- package/dist/scanners/runtime/index.d.ts.map +1 -0
- package/dist/scanners/runtime/index.js +164 -0
- package/dist/scanners/runtime/index.js.map +1 -0
- package/dist/scanners/runtime/playwright-executor.d.ts +50 -0
- package/dist/scanners/runtime/playwright-executor.d.ts.map +1 -0
- package/dist/scanners/runtime/playwright-executor.js +387 -0
- package/dist/scanners/runtime/playwright-executor.js.map +1 -0
- package/dist/scanners/runtime/types.d.ts +215 -0
- package/dist/scanners/runtime/types.d.ts.map +1 -0
- package/dist/scanners/runtime/types.js +40 -0
- package/dist/scanners/runtime/types.js.map +1 -0
- package/dist/scanners/scale/bottleneck-detector.d.ts +17 -0
- package/dist/scanners/scale/bottleneck-detector.d.ts.map +1 -0
- package/dist/scanners/scale/bottleneck-detector.js +250 -0
- package/dist/scanners/scale/bottleneck-detector.js.map +1 -0
- package/dist/scanners/scale/capacity-estimator.d.ts +17 -0
- package/dist/scanners/scale/capacity-estimator.d.ts.map +1 -0
- package/dist/scanners/scale/capacity-estimator.js +197 -0
- package/dist/scanners/scale/capacity-estimator.js.map +1 -0
- package/dist/scanners/scale/index.d.ts +37 -0
- package/dist/scanners/scale/index.d.ts.map +1 -0
- package/dist/scanners/scale/index.js +101 -0
- package/dist/scanners/scale/index.js.map +1 -0
- package/dist/scanners/scale/load-profiler.d.ts +48 -0
- package/dist/scanners/scale/load-profiler.d.ts.map +1 -0
- package/dist/scanners/scale/load-profiler.js +377 -0
- package/dist/scanners/scale/load-profiler.js.map +1 -0
- package/dist/scanners/scale/types.d.ts +529 -0
- package/dist/scanners/scale/types.d.ts.map +1 -0
- package/dist/scanners/scale/types.js +57 -0
- package/dist/scanners/scale/types.js.map +1 -0
- package/dist/scanners/secrets.d.ts.map +1 -1
- package/dist/scanners/secrets.js +13 -2
- package/dist/scanners/secrets.js.map +1 -1
- package/dist/scanners/types.d.ts +1 -1
- package/dist/scanners/types.d.ts.map +1 -1
- package/dist/scanners/types.js +4 -0
- package/dist/scanners/types.js.map +1 -1
- package/package.json +8 -4
- package/skills/vaspera-add-tests/SKILL.md +102 -0
- package/skills/vaspera-ai-verify/SKILL.md +166 -0
- package/skills/vaspera-audit/SKILL.md +67 -0
- package/skills/vaspera-certify/SKILL.md +130 -0
- package/skills/vaspera-deploy/SKILL.md +152 -0
- package/skills/vaspera-fix-critical/SKILL.md +52 -0
- package/skills/vaspera-fix-high/SKILL.md +81 -0
- package/skills/vaspera-fix-medium/SKILL.md +56 -0
- package/skills/vaspera-fix-rls/SKILL.md +85 -0
- package/skills/vaspera-harden/SKILL.md +102 -0
- package/skills/vaspera-help/SKILL.md +61 -0
- package/skills/vaspera-load-test/SKILL.md +167 -0
- package/skills/vaspera-verify/SKILL.md +70 -0
- package/skills/vaspera-verify-e2e/SKILL.md +117 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* False Positive Filter
|
|
3
|
+
*
|
|
4
|
+
* Context-aware filtering to reduce false positives from scanners.
|
|
5
|
+
* Analyzes code context, semantic patterns, and historical data.
|
|
6
|
+
*
|
|
7
|
+
* @module scanners/fp-filter
|
|
8
|
+
*/
|
|
9
|
+
import { readFile } from "fs/promises";
|
|
10
|
+
import { join, basename } from "path";
|
|
11
|
+
import { logger } from "../logger.js";
|
|
12
|
+
/**
|
|
13
|
+
* Patterns that indicate test files
|
|
14
|
+
*/
|
|
15
|
+
const TEST_FILE_PATTERNS = [
|
|
16
|
+
/\.test\.[jt]sx?$/,
|
|
17
|
+
/\.spec\.[jt]sx?$/,
|
|
18
|
+
/__tests__\//,
|
|
19
|
+
/__mocks__\//,
|
|
20
|
+
/(?:^|\/)test\//,
|
|
21
|
+
/(?:^|\/)tests\//,
|
|
22
|
+
/\.stories\.[jt]sx?$/,
|
|
23
|
+
/\.mock\.[jt]sx?$/,
|
|
24
|
+
/(?:^|\/)cypress\//,
|
|
25
|
+
/(?:^|\/)e2e\//,
|
|
26
|
+
/(?:^|\/)playwright\//,
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* Patterns that indicate generated code
|
|
30
|
+
*/
|
|
31
|
+
const GENERATED_CODE_PATTERNS = [
|
|
32
|
+
/\.generated\.[jt]sx?$/,
|
|
33
|
+
/\.gen\.[jt]sx?$/,
|
|
34
|
+
/generated\//,
|
|
35
|
+
/__generated__\//,
|
|
36
|
+
/\.d\.ts$/,
|
|
37
|
+
/swagger-client/,
|
|
38
|
+
/openapi-client/,
|
|
39
|
+
/graphql\.ts$/,
|
|
40
|
+
/prisma\/client/,
|
|
41
|
+
];
|
|
42
|
+
/**
|
|
43
|
+
* Patterns that indicate vendored/third-party code
|
|
44
|
+
*/
|
|
45
|
+
const VENDOR_PATTERNS = [
|
|
46
|
+
/node_modules\//,
|
|
47
|
+
/vendor\//,
|
|
48
|
+
/third[_-]?party\//,
|
|
49
|
+
/external\//,
|
|
50
|
+
/lib\/vendor/,
|
|
51
|
+
/\.min\.js$/,
|
|
52
|
+
/bundle\.js$/,
|
|
53
|
+
];
|
|
54
|
+
/**
|
|
55
|
+
* Patterns that indicate fixture/example files
|
|
56
|
+
*/
|
|
57
|
+
const FIXTURE_PATTERNS = [
|
|
58
|
+
/fixtures?\//,
|
|
59
|
+
/samples?\//,
|
|
60
|
+
/examples?\//,
|
|
61
|
+
/demo\//,
|
|
62
|
+
/seed\//,
|
|
63
|
+
/seeds\//,
|
|
64
|
+
/mock[_-]?data/,
|
|
65
|
+
];
|
|
66
|
+
/**
|
|
67
|
+
* Rules that are commonly false positives in certain contexts
|
|
68
|
+
*/
|
|
69
|
+
const CONTEXT_SENSITIVE_RULES = {
|
|
70
|
+
"hardcoded-secret": {
|
|
71
|
+
filterInTests: true,
|
|
72
|
+
filterInGenerated: false,
|
|
73
|
+
filterIfConstant: false,
|
|
74
|
+
filterIfEnvVar: true,
|
|
75
|
+
},
|
|
76
|
+
"sql-injection": {
|
|
77
|
+
filterInTests: true,
|
|
78
|
+
filterInGenerated: true,
|
|
79
|
+
filterIfConstant: true,
|
|
80
|
+
filterIfEnvVar: false,
|
|
81
|
+
},
|
|
82
|
+
"xss": {
|
|
83
|
+
filterInTests: true,
|
|
84
|
+
filterInGenerated: true,
|
|
85
|
+
filterIfConstant: true,
|
|
86
|
+
filterIfEnvVar: false,
|
|
87
|
+
},
|
|
88
|
+
"command-injection": {
|
|
89
|
+
filterInTests: true,
|
|
90
|
+
filterInGenerated: true,
|
|
91
|
+
filterIfConstant: true,
|
|
92
|
+
filterIfEnvVar: false,
|
|
93
|
+
},
|
|
94
|
+
"path-traversal": {
|
|
95
|
+
filterInTests: true,
|
|
96
|
+
filterInGenerated: true,
|
|
97
|
+
filterIfConstant: true,
|
|
98
|
+
filterIfEnvVar: false,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Analyze file path to determine code context
|
|
103
|
+
*/
|
|
104
|
+
export function analyzeFilePath(filePath) {
|
|
105
|
+
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
106
|
+
const fileName = basename(filePath);
|
|
107
|
+
return {
|
|
108
|
+
isTestFile: TEST_FILE_PATTERNS.some((p) => p.test(normalizedPath)),
|
|
109
|
+
isGeneratedCode: GENERATED_CODE_PATTERNS.some((p) => p.test(normalizedPath)),
|
|
110
|
+
isThirdPartyVendored: VENDOR_PATTERNS.some((p) => p.test(normalizedPath)),
|
|
111
|
+
isMockFile: /\.mock\.[jt]sx?$/.test(fileName) || /mocks?\//i.test(normalizedPath),
|
|
112
|
+
isFixtureFile: FIXTURE_PATTERNS.some((p) => p.test(normalizedPath)),
|
|
113
|
+
isExampleFile: /examples?\//i.test(normalizedPath) || /demo\//i.test(normalizedPath),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Analyze code content for semantic context
|
|
118
|
+
*/
|
|
119
|
+
export async function analyzeCodeContext(projectPath, finding) {
|
|
120
|
+
const defaultContext = {
|
|
121
|
+
hasValidation: false,
|
|
122
|
+
hasEncoding: false,
|
|
123
|
+
isSanitized: false,
|
|
124
|
+
isConstant: false,
|
|
125
|
+
isEnvironmentVariable: false,
|
|
126
|
+
};
|
|
127
|
+
if (!finding.file) {
|
|
128
|
+
return defaultContext;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const filePath = join(projectPath, finding.file);
|
|
132
|
+
const content = await readFile(filePath, "utf-8");
|
|
133
|
+
const lines = content.split("\n");
|
|
134
|
+
// Get surrounding context (5 lines before and after)
|
|
135
|
+
const startLine = Math.max(0, (finding.line || 1) - 6);
|
|
136
|
+
const endLine = Math.min(lines.length, (finding.line || 1) + 5);
|
|
137
|
+
const context = lines.slice(startLine, endLine).join("\n");
|
|
138
|
+
// Check for validation patterns
|
|
139
|
+
const validationPatterns = [
|
|
140
|
+
/validate/i,
|
|
141
|
+
/sanitize/i,
|
|
142
|
+
/escape/i,
|
|
143
|
+
/encode/i,
|
|
144
|
+
/\.parse\(/,
|
|
145
|
+
/z\.\w+\(/, // Zod validation
|
|
146
|
+
/yup\.\w+/, // Yup validation
|
|
147
|
+
/joi\.\w+/, // Joi validation
|
|
148
|
+
/validator\./,
|
|
149
|
+
];
|
|
150
|
+
const hasValidation = validationPatterns.some((p) => p.test(context));
|
|
151
|
+
// Check for encoding patterns
|
|
152
|
+
const encodingPatterns = [
|
|
153
|
+
/encodeURIComponent/,
|
|
154
|
+
/encodeURI/,
|
|
155
|
+
/htmlEncode/,
|
|
156
|
+
/escapeHtml/,
|
|
157
|
+
/DOMPurify/,
|
|
158
|
+
/sanitizeHtml/,
|
|
159
|
+
];
|
|
160
|
+
const hasEncoding = encodingPatterns.some((p) => p.test(context));
|
|
161
|
+
// Check for sanitization
|
|
162
|
+
const sanitizationPatterns = [
|
|
163
|
+
/sanitize/i,
|
|
164
|
+
/clean/i,
|
|
165
|
+
/purify/i,
|
|
166
|
+
/strip/i,
|
|
167
|
+
/filter\s*\(/,
|
|
168
|
+
];
|
|
169
|
+
const isSanitized = sanitizationPatterns.some((p) => p.test(context));
|
|
170
|
+
// Check if value is constant
|
|
171
|
+
const line = lines[(finding.line || 1) - 1] || "";
|
|
172
|
+
const isConstant = /const\s+\w+\s*=\s*["'`]/.test(line) ||
|
|
173
|
+
/readonly\s/.test(line) ||
|
|
174
|
+
/as\s+const/.test(line);
|
|
175
|
+
// Check if value comes from environment variable
|
|
176
|
+
const isEnvironmentVariable = /process\.env\./i.test(context) ||
|
|
177
|
+
/import\.meta\.env/i.test(context) ||
|
|
178
|
+
/\$\{.*ENV.*\}/i.test(context);
|
|
179
|
+
return {
|
|
180
|
+
hasValidation,
|
|
181
|
+
hasEncoding,
|
|
182
|
+
isSanitized,
|
|
183
|
+
isConstant,
|
|
184
|
+
isEnvironmentVariable,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
logger.debug("fp_filter.analyze_failed", {
|
|
189
|
+
file: finding.file,
|
|
190
|
+
error: String(error),
|
|
191
|
+
});
|
|
192
|
+
return defaultContext;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Determine if a finding should be filtered as a false positive
|
|
197
|
+
*/
|
|
198
|
+
export function shouldFilter(finding, context) {
|
|
199
|
+
const { codeContext, semanticContext, historicalContext } = context;
|
|
200
|
+
// Always filter vendored/third-party code
|
|
201
|
+
if (codeContext.isThirdPartyVendored) {
|
|
202
|
+
return {
|
|
203
|
+
filter: true,
|
|
204
|
+
reason: "Third-party/vendored code",
|
|
205
|
+
confidence: 95,
|
|
206
|
+
suggestion: "suppress",
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
// Get rule-specific filtering rules
|
|
210
|
+
const category = finding.category || extractCategory(finding.ruleId);
|
|
211
|
+
const ruleConfig = CONTEXT_SENSITIVE_RULES[category];
|
|
212
|
+
if (ruleConfig) {
|
|
213
|
+
// Filter in test files for certain rules
|
|
214
|
+
if (ruleConfig.filterInTests && codeContext.isTestFile) {
|
|
215
|
+
return {
|
|
216
|
+
filter: true,
|
|
217
|
+
reason: "Test file - rule typically FP in tests",
|
|
218
|
+
confidence: 85,
|
|
219
|
+
suggestion: "suppress",
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
// Filter in generated code
|
|
223
|
+
if (ruleConfig.filterInGenerated && codeContext.isGeneratedCode) {
|
|
224
|
+
return {
|
|
225
|
+
filter: true,
|
|
226
|
+
reason: "Generated code",
|
|
227
|
+
confidence: 90,
|
|
228
|
+
suggestion: "suppress",
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
// Filter if value is constant
|
|
232
|
+
if (ruleConfig.filterIfConstant && semanticContext.isConstant) {
|
|
233
|
+
return {
|
|
234
|
+
filter: true,
|
|
235
|
+
reason: "Constant value - not user-controlled",
|
|
236
|
+
confidence: 75,
|
|
237
|
+
suggestion: "review",
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
// Filter if environment variable
|
|
241
|
+
if (ruleConfig.filterIfEnvVar && semanticContext.isEnvironmentVariable) {
|
|
242
|
+
return {
|
|
243
|
+
filter: true,
|
|
244
|
+
reason: "Environment variable reference",
|
|
245
|
+
confidence: 80,
|
|
246
|
+
suggestion: "review",
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Filter fixture/example files with lower confidence
|
|
251
|
+
if (codeContext.isFixtureFile || codeContext.isExampleFile) {
|
|
252
|
+
return {
|
|
253
|
+
filter: true,
|
|
254
|
+
reason: "Fixture/example file",
|
|
255
|
+
confidence: 70,
|
|
256
|
+
suggestion: "review",
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
// Check if sanitization is present
|
|
260
|
+
if (semanticContext.isSanitized || semanticContext.hasValidation || semanticContext.hasEncoding) {
|
|
261
|
+
return {
|
|
262
|
+
filter: false,
|
|
263
|
+
reason: "Sanitization detected but manual review recommended",
|
|
264
|
+
confidence: 60,
|
|
265
|
+
suggestion: "review",
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
// Check historical suppressions
|
|
269
|
+
if (historicalContext.suppressions.includes(finding.ruleId)) {
|
|
270
|
+
return {
|
|
271
|
+
filter: true,
|
|
272
|
+
reason: "Previously suppressed rule",
|
|
273
|
+
confidence: 70,
|
|
274
|
+
suggestion: "review",
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
// Check historical accuracy
|
|
278
|
+
if (historicalContext.ruleAccuracy < 0.3) {
|
|
279
|
+
return {
|
|
280
|
+
filter: false,
|
|
281
|
+
reason: `Low historical accuracy (${Math.round(historicalContext.ruleAccuracy * 100)}%)`,
|
|
282
|
+
confidence: 50,
|
|
283
|
+
suggestion: "review",
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
// No filtering
|
|
287
|
+
return {
|
|
288
|
+
filter: false,
|
|
289
|
+
confidence: 100,
|
|
290
|
+
suggestion: "confirm",
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Extract category from rule ID
|
|
295
|
+
*/
|
|
296
|
+
function extractCategory(ruleId) {
|
|
297
|
+
// Common patterns: "scanner:category.rule" or "category-rule"
|
|
298
|
+
const colonMatch = ruleId.match(/^[^:]+:([^.]+)/);
|
|
299
|
+
if (colonMatch) {
|
|
300
|
+
return colonMatch[1];
|
|
301
|
+
}
|
|
302
|
+
const dashMatch = ruleId.match(/^([a-z-]+)-\d+$/i);
|
|
303
|
+
if (dashMatch) {
|
|
304
|
+
return dashMatch[1];
|
|
305
|
+
}
|
|
306
|
+
return ruleId;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Filter findings and return filtered results with reasons
|
|
310
|
+
*/
|
|
311
|
+
export async function filterFindings(projectPath, findings, options) {
|
|
312
|
+
const minConfidence = options?.minConfidence ?? 70;
|
|
313
|
+
const historicalData = options?.historicalData ?? new Map();
|
|
314
|
+
const filtered = [];
|
|
315
|
+
const removed = [];
|
|
316
|
+
const byReason = {};
|
|
317
|
+
for (const finding of findings) {
|
|
318
|
+
// Build context
|
|
319
|
+
const codeContext = analyzeFilePath(finding.file);
|
|
320
|
+
const semanticContext = await analyzeCodeContext(projectPath, finding);
|
|
321
|
+
const ruleHistory = historicalData.get(finding.ruleId);
|
|
322
|
+
const historicalContext = {
|
|
323
|
+
previousFPs: [],
|
|
324
|
+
ruleAccuracy: ruleHistory?.fpRate ?? 1.0,
|
|
325
|
+
suppressions: ruleHistory?.suppressions ?? [],
|
|
326
|
+
};
|
|
327
|
+
const context = {
|
|
328
|
+
codeContext,
|
|
329
|
+
semanticContext,
|
|
330
|
+
historicalContext,
|
|
331
|
+
};
|
|
332
|
+
const result = shouldFilter(finding, context);
|
|
333
|
+
if (result.filter && result.confidence >= minConfidence) {
|
|
334
|
+
removed.push({
|
|
335
|
+
finding,
|
|
336
|
+
reason: result.reason || "Filtered",
|
|
337
|
+
confidence: result.confidence,
|
|
338
|
+
});
|
|
339
|
+
byReason[result.reason || "Unknown"] = (byReason[result.reason || "Unknown"] || 0) + 1;
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
filtered.push(finding);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
logger.info("fp_filter.complete", {
|
|
346
|
+
total: findings.length,
|
|
347
|
+
kept: filtered.length,
|
|
348
|
+
filtered: removed.length,
|
|
349
|
+
});
|
|
350
|
+
return {
|
|
351
|
+
filtered,
|
|
352
|
+
removed,
|
|
353
|
+
stats: {
|
|
354
|
+
total: findings.length,
|
|
355
|
+
kept: filtered.length,
|
|
356
|
+
filtered: removed.length,
|
|
357
|
+
byReason,
|
|
358
|
+
},
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Get suggested suppressions for a finding
|
|
363
|
+
*/
|
|
364
|
+
export function getSuppressSuggestion(finding, context) {
|
|
365
|
+
const scanner = finding.scanner;
|
|
366
|
+
const ruleId = finding.ruleId;
|
|
367
|
+
// Generate scanner-specific suppression comments
|
|
368
|
+
let inlineComment;
|
|
369
|
+
let fileComment;
|
|
370
|
+
switch (scanner) {
|
|
371
|
+
case "semgrep":
|
|
372
|
+
inlineComment = `// nosemgrep: ${ruleId}`;
|
|
373
|
+
fileComment = `// nosemgrep`;
|
|
374
|
+
break;
|
|
375
|
+
case "eslint":
|
|
376
|
+
inlineComment = `// eslint-disable-next-line ${ruleId}`;
|
|
377
|
+
fileComment = `/* eslint-disable ${ruleId} */`;
|
|
378
|
+
break;
|
|
379
|
+
case "gitleaks":
|
|
380
|
+
inlineComment = `// gitleaks:allow`;
|
|
381
|
+
fileComment = `# gitleaks:allow`;
|
|
382
|
+
break;
|
|
383
|
+
case "bandit":
|
|
384
|
+
inlineComment = `# nosec ${ruleId}`;
|
|
385
|
+
fileComment = `# nosec`;
|
|
386
|
+
break;
|
|
387
|
+
default:
|
|
388
|
+
inlineComment = `// @suppress ${ruleId}`;
|
|
389
|
+
fileComment = `// @suppress-file ${ruleId}`;
|
|
390
|
+
}
|
|
391
|
+
return {
|
|
392
|
+
suppressionComment: `Suppressed: ${finding.message} (${context.codeContext.isTestFile ? "test file" : "reviewed"})`,
|
|
393
|
+
inlineSuppress: inlineComment,
|
|
394
|
+
fileSuppress: fileComment,
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
//# sourceMappingURL=fp-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fp-filter.js","sourceRoot":"","sources":["../../src/scanners/fp-filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* False Positive Tracker
|
|
3
|
+
*
|
|
4
|
+
* Tracks false positive rates per scanner/rule and adjusts
|
|
5
|
+
* finding confidence accordingly.
|
|
6
|
+
*
|
|
7
|
+
* @module scanners/fp-tracker
|
|
8
|
+
*/
|
|
9
|
+
import type { ScannerType, DeterministicFinding } from "./types.js";
|
|
10
|
+
import type { Severity } from "../certification/types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Metrics for a specific rule
|
|
13
|
+
*/
|
|
14
|
+
export interface RuleMetrics {
|
|
15
|
+
/** Scanner that generated this rule */
|
|
16
|
+
scanner: ScannerType;
|
|
17
|
+
/** Rule ID */
|
|
18
|
+
ruleId: string;
|
|
19
|
+
/** Total findings reported by this rule */
|
|
20
|
+
totalReported: number;
|
|
21
|
+
/** Number confirmed as true positives */
|
|
22
|
+
confirmedTP: number;
|
|
23
|
+
/** Number confirmed as false positives */
|
|
24
|
+
confirmedFP: number;
|
|
25
|
+
/** Number still pending review */
|
|
26
|
+
pendingReview: number;
|
|
27
|
+
/** Calculated FP rate (0-1) */
|
|
28
|
+
fpRate: number;
|
|
29
|
+
/** Calculated TP rate (0-1) */
|
|
30
|
+
tpRate: number;
|
|
31
|
+
/** Confidence adjustment factor based on history */
|
|
32
|
+
adjustmentFactor: number;
|
|
33
|
+
/** Last updated timestamp */
|
|
34
|
+
lastUpdated: string;
|
|
35
|
+
/** Severity distribution of findings */
|
|
36
|
+
severityDistribution: Partial<Record<Severity, number>>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Aggregated scanner metrics
|
|
40
|
+
*/
|
|
41
|
+
export interface ScannerMetrics {
|
|
42
|
+
scanner: ScannerType;
|
|
43
|
+
totalRules: number;
|
|
44
|
+
totalFindings: number;
|
|
45
|
+
overallFPRate: number;
|
|
46
|
+
overallTPRate: number;
|
|
47
|
+
ruleMetrics: Map<string, RuleMetrics>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* FP tracking data store
|
|
51
|
+
*/
|
|
52
|
+
export interface FPTrackingData {
|
|
53
|
+
version: string;
|
|
54
|
+
lastUpdated: string;
|
|
55
|
+
projectPath: string;
|
|
56
|
+
scanners: Record<string, ScannerMetrics>;
|
|
57
|
+
globalStats: {
|
|
58
|
+
totalFindings: number;
|
|
59
|
+
totalTP: number;
|
|
60
|
+
totalFP: number;
|
|
61
|
+
totalPending: number;
|
|
62
|
+
overallAccuracy: number;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Load FP tracking data from disk
|
|
67
|
+
*/
|
|
68
|
+
export declare function loadTrackingData(projectPath: string): Promise<FPTrackingData>;
|
|
69
|
+
/**
|
|
70
|
+
* Save FP tracking data to disk
|
|
71
|
+
*/
|
|
72
|
+
export declare function saveTrackingData(projectPath: string, data: FPTrackingData): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Record a new finding for tracking
|
|
75
|
+
*/
|
|
76
|
+
export declare function recordFinding(projectPath: string, finding: DeterministicFinding): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Mark a finding as true positive
|
|
79
|
+
*/
|
|
80
|
+
export declare function markTruePositive(projectPath: string, scanner: ScannerType, ruleId: string): Promise<RuleMetrics | undefined>;
|
|
81
|
+
/**
|
|
82
|
+
* Mark a finding as false positive
|
|
83
|
+
*/
|
|
84
|
+
export declare function markFalsePositive(projectPath: string, scanner: ScannerType, ruleId: string, reason?: string): Promise<RuleMetrics | undefined>;
|
|
85
|
+
/**
|
|
86
|
+
* Adjust finding confidence based on historical FP rates
|
|
87
|
+
*/
|
|
88
|
+
export declare function adjustFindingConfidence(finding: DeterministicFinding, metrics: RuleMetrics | undefined): number;
|
|
89
|
+
/**
|
|
90
|
+
* Get metrics for a specific rule
|
|
91
|
+
*/
|
|
92
|
+
export declare function getRuleMetrics(projectPath: string, scanner: ScannerType, ruleId: string): Promise<RuleMetrics | undefined>;
|
|
93
|
+
/**
|
|
94
|
+
* Get all scanner metrics
|
|
95
|
+
*/
|
|
96
|
+
export declare function getAllMetrics(projectPath: string): Promise<FPTrackingData>;
|
|
97
|
+
/**
|
|
98
|
+
* Get rules with high FP rates
|
|
99
|
+
*/
|
|
100
|
+
export declare function getHighFPRules(projectPath: string, threshold?: number, minSampleSize?: number): Promise<RuleMetrics[]>;
|
|
101
|
+
/**
|
|
102
|
+
* Generate FP tracking report
|
|
103
|
+
*/
|
|
104
|
+
export declare function generateFPReport(projectPath: string, options?: {
|
|
105
|
+
minSampleSize?: number;
|
|
106
|
+
includeAllRules?: boolean;
|
|
107
|
+
}): Promise<{
|
|
108
|
+
summary: {
|
|
109
|
+
totalScanners: number;
|
|
110
|
+
totalRules: number;
|
|
111
|
+
totalFindings: number;
|
|
112
|
+
overallAccuracy: number;
|
|
113
|
+
highFPRuleCount: number;
|
|
114
|
+
};
|
|
115
|
+
scannerBreakdown: Array<{
|
|
116
|
+
scanner: ScannerType;
|
|
117
|
+
totalFindings: number;
|
|
118
|
+
fpRate: number;
|
|
119
|
+
tpRate: number;
|
|
120
|
+
ruleCount: number;
|
|
121
|
+
}>;
|
|
122
|
+
highFPRules: RuleMetrics[];
|
|
123
|
+
recommendations: string[];
|
|
124
|
+
}>;
|
|
125
|
+
//# sourceMappingURL=fp-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fp-tracker.d.ts","sourceRoot":"","sources":["../../src/scanners/fp-tracker.ts"],"names":[],"mappings":"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"}
|