vibecheck-ai 2.0.2 → 5.0.0
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/.generated +25 -0
- package/bin/_deprecations.js +463 -0
- package/bin/_router.js +46 -0
- package/bin/cli-hygiene.js +241 -0
- package/bin/dev/run-v2-torture.js +30 -0
- package/bin/registry.js +656 -0
- package/bin/runners/CLI_REFACTOR_SUMMARY.md +229 -0
- package/bin/runners/ENHANCEMENT_GUIDE.md +121 -0
- package/bin/runners/REPORT_AUDIT.md +64 -0
- package/bin/runners/cli-utils.js +1070 -0
- package/bin/runners/context/ai-task-decomposer.js +337 -0
- package/bin/runners/context/analyzer.js +513 -0
- package/bin/runners/context/api-contracts.js +427 -0
- package/bin/runners/context/context-diff.js +342 -0
- package/bin/runners/context/context-pruner.js +291 -0
- package/bin/runners/context/dependency-graph.js +414 -0
- package/bin/runners/context/generators/claude.js +107 -0
- package/bin/runners/context/generators/codex.js +108 -0
- package/bin/runners/context/generators/copilot.js +119 -0
- package/bin/runners/context/generators/cursor-enhanced.js +2525 -0
- package/bin/runners/context/generators/cursor.js +514 -0
- package/bin/runners/context/generators/mcp.js +169 -0
- package/bin/runners/context/generators/windsurf.js +180 -0
- package/bin/runners/context/git-context.js +304 -0
- package/bin/runners/context/index.js +1110 -0
- package/bin/runners/context/insights.js +173 -0
- package/bin/runners/context/mcp-server/generate-rules.js +337 -0
- package/bin/runners/context/mcp-server/index.js +1176 -0
- package/bin/runners/context/mcp-server/package.json +24 -0
- package/bin/runners/context/memory.js +200 -0
- package/bin/runners/context/monorepo.js +215 -0
- package/bin/runners/context/multi-repo-federation.js +404 -0
- package/bin/runners/context/patterns.js +253 -0
- package/bin/runners/context/proof-context.js +1264 -0
- package/bin/runners/context/security-scanner.js +541 -0
- package/bin/runners/context/semantic-search.js +350 -0
- package/bin/runners/context/shared.js +264 -0
- package/bin/runners/context/team-conventions.js +336 -0
- package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -0
- package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +474 -0
- package/bin/runners/lib/agent-firewall/change-packet/builder.js +488 -0
- package/bin/runners/lib/agent-firewall/change-packet/schema.json +228 -0
- package/bin/runners/lib/agent-firewall/change-packet/store.js +200 -0
- package/bin/runners/lib/agent-firewall/claims/claim-types.js +21 -0
- package/bin/runners/lib/agent-firewall/claims/extractor.js +303 -0
- package/bin/runners/lib/agent-firewall/claims/patterns.js +24 -0
- package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
- package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
- package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
- package/bin/runners/lib/agent-firewall/enforcement/gateway.js +1059 -0
- package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -0
- package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -0
- package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -0
- package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/change-event.schema.json +173 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/intent.schema.json +181 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/verdict.schema.json +222 -0
- package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -0
- package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +88 -0
- package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +75 -0
- package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +127 -0
- package/bin/runners/lib/agent-firewall/evidence/resolver.js +102 -0
- package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +213 -0
- package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +145 -0
- package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +19 -0
- package/bin/runners/lib/agent-firewall/fs-hook/installer.js +87 -0
- package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +184 -0
- package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +163 -0
- package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +107 -0
- package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +68 -0
- package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +66 -0
- package/bin/runners/lib/agent-firewall/index.js +200 -0
- package/bin/runners/lib/agent-firewall/integration/index.js +20 -0
- package/bin/runners/lib/agent-firewall/integration/ship-gate.js +437 -0
- package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +634 -0
- package/bin/runners/lib/agent-firewall/intent/auto-detect.js +426 -0
- package/bin/runners/lib/agent-firewall/intent/index.js +102 -0
- package/bin/runners/lib/agent-firewall/intent/schema.js +352 -0
- package/bin/runners/lib/agent-firewall/intent/store.js +283 -0
- package/bin/runners/lib/agent-firewall/interception/fs-interceptor.js +502 -0
- package/bin/runners/lib/agent-firewall/interception/index.js +23 -0
- package/bin/runners/lib/agent-firewall/interceptor/base.js +308 -0
- package/bin/runners/lib/agent-firewall/interceptor/cursor.js +35 -0
- package/bin/runners/lib/agent-firewall/interceptor/vscode.js +35 -0
- package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +34 -0
- package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
- package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
- package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
- package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
- package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
- package/bin/runners/lib/agent-firewall/logger.js +141 -0
- package/bin/runners/lib/agent-firewall/policy/default-policy.json +90 -0
- package/bin/runners/lib/agent-firewall/policy/engine.js +103 -0
- package/bin/runners/lib/agent-firewall/policy/loader.js +451 -0
- package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +50 -0
- package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +50 -0
- package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +79 -0
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +227 -0
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +191 -0
- package/bin/runners/lib/agent-firewall/policy/rules/scope.js +93 -0
- package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +57 -0
- package/bin/runners/lib/agent-firewall/policy/schema.json +183 -0
- package/bin/runners/lib/agent-firewall/policy/verdict.js +54 -0
- package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
- package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
- package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
- package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
- package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
- package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
- package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
- package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
- package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
- package/bin/runners/lib/agent-firewall/risk/thresholds.js +322 -0
- package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
- package/bin/runners/lib/agent-firewall/session/collector.js +451 -0
- package/bin/runners/lib/agent-firewall/session/index.js +26 -0
- package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
- package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
- package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
- package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
- package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
- package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
- package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
- package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
- package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
- package/bin/runners/lib/agent-firewall/truthpack/index.js +67 -0
- package/bin/runners/lib/agent-firewall/truthpack/loader.js +137 -0
- package/bin/runners/lib/agent-firewall/unblock/planner.js +337 -0
- package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +118 -0
- package/bin/runners/lib/ai-bridge.js +416 -0
- package/bin/runners/lib/analysis-core.js +309 -0
- package/bin/runners/lib/analyzers.js +2500 -0
- package/bin/runners/lib/api-client.js +269 -0
- package/bin/runners/lib/approve-output.js +235 -0
- package/bin/runners/lib/artifact-envelope.js +540 -0
- package/bin/runners/lib/assets/vibecheck-logo.png +0 -0
- package/bin/runners/lib/audit-bridge.js +391 -0
- package/bin/runners/lib/auth-shared.js +977 -0
- package/bin/runners/lib/auth-truth.js +193 -0
- package/bin/runners/lib/auth.js +215 -0
- package/bin/runners/lib/authority-badge.js +425 -0
- package/bin/runners/lib/backup.js +62 -0
- package/bin/runners/lib/billing.js +107 -0
- package/bin/runners/lib/checkpoint.js +941 -0
- package/bin/runners/lib/claims.js +118 -0
- package/bin/runners/lib/classify-output.js +204 -0
- package/bin/runners/lib/cleanup/engine.js +571 -0
- package/bin/runners/lib/cleanup/index.js +53 -0
- package/bin/runners/lib/cleanup/output.js +375 -0
- package/bin/runners/lib/cleanup/rules.js +1060 -0
- package/bin/runners/lib/cli-output.js +400 -0
- package/bin/runners/lib/cli-ui.js +540 -0
- package/bin/runners/lib/compliance-bridge-new.js +0 -0
- package/bin/runners/lib/compliance-bridge.js +165 -0
- package/bin/runners/lib/contracts/auth-contract.js +202 -0
- package/bin/runners/lib/contracts/env-contract.js +181 -0
- package/bin/runners/lib/contracts/external-contract.js +206 -0
- package/bin/runners/lib/contracts/guard.js +168 -0
- package/bin/runners/lib/contracts/index.js +89 -0
- package/bin/runners/lib/contracts/plan-validator.js +311 -0
- package/bin/runners/lib/contracts/route-contract.js +199 -0
- package/bin/runners/lib/contracts.js +804 -0
- package/bin/runners/lib/default-config.js +127 -0
- package/bin/runners/lib/detect.js +89 -0
- package/bin/runners/lib/detectors-v2.js +622 -0
- package/bin/runners/lib/doctor/autofix.js +254 -0
- package/bin/runners/lib/doctor/diagnosis-receipt.js +454 -0
- package/bin/runners/lib/doctor/failure-signatures.js +526 -0
- package/bin/runners/lib/doctor/fix-script.js +336 -0
- package/bin/runners/lib/doctor/index.js +37 -0
- package/bin/runners/lib/doctor/modules/build-tools.js +453 -0
- package/bin/runners/lib/doctor/modules/dependencies.js +325 -0
- package/bin/runners/lib/doctor/modules/index.js +105 -0
- package/bin/runners/lib/doctor/modules/network.js +250 -0
- package/bin/runners/lib/doctor/modules/os-quirks.js +706 -0
- package/bin/runners/lib/doctor/modules/project.js +312 -0
- package/bin/runners/lib/doctor/modules/repo-integrity.js +485 -0
- package/bin/runners/lib/doctor/modules/runtime.js +224 -0
- package/bin/runners/lib/doctor/modules/security.js +350 -0
- package/bin/runners/lib/doctor/modules/system.js +213 -0
- package/bin/runners/lib/doctor/modules/vibecheck.js +394 -0
- package/bin/runners/lib/doctor/reporter.js +262 -0
- package/bin/runners/lib/doctor/safe-repair.js +384 -0
- package/bin/runners/lib/doctor/service.js +262 -0
- package/bin/runners/lib/doctor/types.js +113 -0
- package/bin/runners/lib/doctor/ui.js +263 -0
- package/bin/runners/lib/doctor-enhanced.js +233 -0
- package/bin/runners/lib/doctor-output.js +226 -0
- package/bin/runners/lib/doctor-v2.js +608 -0
- package/bin/runners/lib/drift.js +425 -0
- package/bin/runners/lib/enforcement.js +72 -0
- 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 +190 -0
- package/bin/runners/lib/engines/api-consistency-engine.js +162 -0
- package/bin/runners/lib/engines/ast-cache.js +99 -0
- package/bin/runners/lib/engines/attack-detector.js +1192 -0
- package/bin/runners/lib/engines/code-quality-engine.js +255 -0
- package/bin/runners/lib/engines/console-logs-engine.js +115 -0
- package/bin/runners/lib/engines/cross-file-analysis-engine.js +268 -0
- package/bin/runners/lib/engines/dead-code-engine.js +198 -0
- package/bin/runners/lib/engines/deprecated-api-engine.js +226 -0
- package/bin/runners/lib/engines/empty-catch-engine.js +150 -0
- package/bin/runners/lib/engines/file-filter.js +131 -0
- package/bin/runners/lib/engines/hardcoded-secrets-engine.js +251 -0
- package/bin/runners/lib/engines/mock-data-engine.js +272 -0
- package/bin/runners/lib/engines/parallel-processor.js +71 -0
- package/bin/runners/lib/engines/performance-issues-engine.js +265 -0
- package/bin/runners/lib/engines/security-vulnerabilities-engine.js +243 -0
- package/bin/runners/lib/engines/todo-fixme-engine.js +115 -0
- package/bin/runners/lib/engines/type-aware-engine.js +152 -0
- package/bin/runners/lib/engines/unsafe-regex-engine.js +225 -0
- package/bin/runners/lib/engines/vibecheck-engines/README.md +53 -0
- package/bin/runners/lib/engines/vibecheck-engines/index.js +15 -0
- 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 +139 -0
- 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/engines/vibecheck-engines/package.json +13 -0
- package/bin/runners/lib/enterprise-detect.js +603 -0
- package/bin/runners/lib/enterprise-init.js +942 -0
- package/bin/runners/lib/entitlements-v2.js +265 -0
- package/bin/runners/lib/entitlements.generated.js +0 -0
- package/bin/runners/lib/entitlements.js +340 -0
- package/bin/runners/lib/env-resolver.js +417 -0
- package/bin/runners/lib/env-template.js +66 -0
- package/bin/runners/lib/env.js +189 -0
- package/bin/runners/lib/error-handler.js +368 -0
- package/bin/runners/lib/error-messages.js +289 -0
- package/bin/runners/lib/evidence-pack.js +684 -0
- package/bin/runners/lib/exit-codes.js +275 -0
- package/bin/runners/lib/extractors/client-calls.js +990 -0
- package/bin/runners/lib/extractors/fastify-route-dump.js +573 -0
- package/bin/runners/lib/extractors/fastify-routes.js +426 -0
- package/bin/runners/lib/extractors/index.js +363 -0
- package/bin/runners/lib/extractors/next-routes.js +524 -0
- package/bin/runners/lib/extractors/proof-graph.js +431 -0
- package/bin/runners/lib/extractors/route-matcher.js +451 -0
- package/bin/runners/lib/extractors/truthpack-v2.js +377 -0
- package/bin/runners/lib/extractors/ui-bindings.js +547 -0
- package/bin/runners/lib/finding-id.js +69 -0
- package/bin/runners/lib/finding-sorter.js +89 -0
- package/bin/runners/lib/findings-schema.js +281 -0
- package/bin/runners/lib/fingerprint.js +377 -0
- package/bin/runners/lib/firewall-prompt.js +50 -0
- package/bin/runners/lib/fix-output.js +228 -0
- package/bin/runners/lib/global-flags.js +250 -0
- package/bin/runners/lib/graph/graph-builder.js +265 -0
- package/bin/runners/lib/graph/html-renderer.js +413 -0
- package/bin/runners/lib/graph/index.js +32 -0
- package/bin/runners/lib/graph/runtime-collector.js +215 -0
- package/bin/runners/lib/graph/static-extractor.js +518 -0
- package/bin/runners/lib/help-formatter.js +413 -0
- package/bin/runners/lib/html-proof-report.js +913 -0
- package/bin/runners/lib/html-report.js +650 -0
- package/bin/runners/lib/init-wizard.js +601 -0
- package/bin/runners/lib/interactive-menu.js +1496 -0
- package/bin/runners/lib/json-output.js +76 -0
- package/bin/runners/lib/llm.js +75 -0
- package/bin/runners/lib/logger.js +38 -0
- package/bin/runners/lib/meter.js +61 -0
- package/bin/runners/lib/missions/briefing.js +427 -0
- package/bin/runners/lib/missions/checkpoint.js +753 -0
- package/bin/runners/lib/missions/evidence.js +126 -0
- package/bin/runners/lib/missions/hardening.js +851 -0
- package/bin/runners/lib/missions/plan.js +648 -0
- package/bin/runners/lib/missions/safety-gates.js +645 -0
- package/bin/runners/lib/missions/schema.js +478 -0
- package/bin/runners/lib/missions/templates.js +317 -0
- package/bin/runners/lib/next-action.js +560 -0
- package/bin/runners/lib/packs/bundle.js +675 -0
- package/bin/runners/lib/packs/evidence-pack.js +671 -0
- package/bin/runners/lib/packs/pack-factory.js +837 -0
- package/bin/runners/lib/packs/permissions-pack.js +686 -0
- package/bin/runners/lib/packs/proof-graph-pack.js +779 -0
- package/bin/runners/lib/patch.js +40 -0
- package/bin/runners/lib/permissions/auth-model.js +213 -0
- package/bin/runners/lib/permissions/idor-prover.js +205 -0
- package/bin/runners/lib/permissions/index.js +45 -0
- package/bin/runners/lib/permissions/matrix-builder.js +198 -0
- package/bin/runners/lib/pkgjson.js +28 -0
- package/bin/runners/lib/policy.js +295 -0
- package/bin/runners/lib/polish/accessibility.js +62 -0
- package/bin/runners/lib/polish/analyzer.js +93 -0
- package/bin/runners/lib/polish/backend.js +87 -0
- package/bin/runners/lib/polish/configuration.js +83 -0
- package/bin/runners/lib/polish/documentation.js +83 -0
- package/bin/runners/lib/polish/frontend.js +817 -0
- package/bin/runners/lib/polish/index.js +27 -0
- package/bin/runners/lib/polish/infrastructure.js +80 -0
- package/bin/runners/lib/polish/internationalization.js +85 -0
- package/bin/runners/lib/polish/libraries.js +180 -0
- package/bin/runners/lib/polish/observability.js +75 -0
- package/bin/runners/lib/polish/performance.js +64 -0
- package/bin/runners/lib/polish/privacy.js +110 -0
- package/bin/runners/lib/polish/resilience.js +92 -0
- package/bin/runners/lib/polish/security.js +78 -0
- package/bin/runners/lib/polish/seo.js +71 -0
- package/bin/runners/lib/polish/styles.js +62 -0
- package/bin/runners/lib/polish/utils.js +104 -0
- package/bin/runners/lib/preflight.js +142 -0
- package/bin/runners/lib/prerequisites.js +149 -0
- package/bin/runners/lib/prove-output.js +220 -0
- package/bin/runners/lib/reality/correlation-detectors.js +359 -0
- package/bin/runners/lib/reality/index.js +318 -0
- package/bin/runners/lib/reality/request-hashing.js +416 -0
- package/bin/runners/lib/reality/request-mapper.js +453 -0
- package/bin/runners/lib/reality/safety-rails.js +463 -0
- package/bin/runners/lib/reality/semantic-snapshot.js +408 -0
- package/bin/runners/lib/reality/toast-detector.js +393 -0
- package/bin/runners/lib/reality-findings.js +84 -0
- package/bin/runners/lib/reality-output.js +231 -0
- package/bin/runners/lib/receipts.js +179 -0
- package/bin/runners/lib/redact.js +29 -0
- package/bin/runners/lib/replay/capsule-manager.js +154 -0
- package/bin/runners/lib/replay/index.js +263 -0
- package/bin/runners/lib/replay/player.js +348 -0
- package/bin/runners/lib/replay/recorder.js +331 -0
- package/bin/runners/lib/report-engine.js +626 -0
- package/bin/runners/lib/report-html.js +1233 -0
- package/bin/runners/lib/report-output.js +366 -0
- package/bin/runners/lib/report-templates.js +967 -0
- package/bin/runners/lib/report.js +135 -0
- package/bin/runners/lib/route-detection.js +1209 -0
- package/bin/runners/lib/route-truth.js +1322 -0
- package/bin/runners/lib/safelist/index.js +96 -0
- package/bin/runners/lib/safelist/integration.js +334 -0
- package/bin/runners/lib/safelist/matcher.js +696 -0
- package/bin/runners/lib/safelist/schema.js +948 -0
- package/bin/runners/lib/safelist/store.js +438 -0
- package/bin/runners/lib/sandbox/index.js +59 -0
- package/bin/runners/lib/sandbox/proof-chain.js +399 -0
- package/bin/runners/lib/sandbox/sandbox-runner.js +205 -0
- package/bin/runners/lib/sandbox/worktree.js +174 -0
- package/bin/runners/lib/scan-cache.js +330 -0
- package/bin/runners/lib/scan-output-schema.js +344 -0
- package/bin/runners/lib/scan-output.js +631 -0
- package/bin/runners/lib/scan-runner.js +135 -0
- package/bin/runners/lib/schema-validator.js +350 -0
- package/bin/runners/lib/schemas/ajv-validator.js +464 -0
- package/bin/runners/lib/schemas/contracts.schema.json +160 -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/finding.schema.json +100 -0
- package/bin/runners/lib/schemas/mission-pack.schema.json +206 -0
- package/bin/runners/lib/schemas/proof-graph.schema.json +176 -0
- package/bin/runners/lib/schemas/reality-report.schema.json +162 -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/share-pack.schema.json +180 -0
- package/bin/runners/lib/schemas/ship-manifest.schema.json +251 -0
- package/bin/runners/lib/schemas/ship-report.schema.json +117 -0
- package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -0
- package/bin/runners/lib/schemas/validator.js +465 -0
- package/bin/runners/lib/schemas/verdict.schema.json +140 -0
- package/bin/runners/lib/score-history.js +282 -0
- package/bin/runners/lib/security-bridge.js +249 -0
- package/bin/runners/lib/server-usage.js +513 -0
- package/bin/runners/lib/share-pack.js +239 -0
- package/bin/runners/lib/ship-gate.js +832 -0
- package/bin/runners/lib/ship-manifest.js +1153 -0
- package/bin/runners/lib/ship-output-enterprise.js +239 -0
- package/bin/runners/lib/ship-output.js +1128 -0
- package/bin/runners/lib/snippets.js +67 -0
- package/bin/runners/lib/status-output.js +340 -0
- package/bin/runners/lib/terminal-ui.js +356 -0
- package/bin/runners/lib/truth.js +1691 -0
- package/bin/runners/lib/ui.js +562 -0
- package/bin/runners/lib/unified-cli-output.js +947 -0
- package/bin/runners/lib/unified-output.js +197 -0
- package/bin/runners/lib/upsell.js +410 -0
- package/bin/runners/lib/usage.js +153 -0
- package/bin/runners/lib/validate-patch.js +156 -0
- package/bin/runners/lib/verdict-engine.js +628 -0
- package/bin/runners/lib/verification.js +345 -0
- package/bin/runners/lib/why-tree.js +650 -0
- package/bin/runners/reality/engine.js +917 -0
- package/bin/runners/reality/flows.js +122 -0
- package/bin/runners/reality/report.js +378 -0
- package/bin/runners/reality/session.js +193 -0
- package/bin/runners/runAIAgent.js +229 -0
- package/bin/runners/runAgent.d.ts +5 -0
- package/bin/runners/runAgent.js +161 -0
- package/bin/runners/runAllowlist.js +418 -0
- package/bin/runners/runApprove.js +320 -0
- package/bin/runners/runAudit.js +692 -0
- package/bin/runners/runAuth.js +731 -0
- package/bin/runners/runCI.js +353 -0
- package/bin/runners/runCheckpoint.js +530 -0
- package/bin/runners/runClassify.js +928 -0
- package/bin/runners/runCleanup.js +343 -0
- package/bin/runners/runContext.d.ts +4 -0
- package/bin/runners/runContext.js +175 -0
- package/bin/runners/runDoctor.js +877 -0
- package/bin/runners/runEvidencePack.js +362 -0
- package/bin/runners/runFirewall.d.ts +5 -0
- package/bin/runners/runFirewall.js +134 -0
- package/bin/runners/runFirewallHook.d.ts +5 -0
- package/bin/runners/runFirewallHook.js +56 -0
- package/bin/runners/runFix.js +1355 -0
- package/bin/runners/runForge.js +451 -0
- package/bin/runners/runGuard.js +262 -0
- package/bin/runners/runInit.js +1927 -0
- package/bin/runners/runIntent.js +906 -0
- package/bin/runners/runKickoff.js +878 -0
- package/bin/runners/runLabs.js +424 -0
- package/bin/runners/runLaunch.js +2000 -0
- package/bin/runners/runLink.js +785 -0
- package/bin/runners/runMcp.js +1875 -0
- package/bin/runners/runPacks.js +2089 -0
- package/bin/runners/runPolish.d.ts +4 -0
- package/bin/runners/runPolish.js +390 -0
- package/bin/runners/runPromptFirewall.js +211 -0
- package/bin/runners/runProve.js +1411 -0
- package/bin/runners/runQuickstart.js +531 -0
- package/bin/runners/runReality.js +2260 -0
- package/bin/runners/runReport.js +726 -0
- package/bin/runners/runRuntime.js +110 -0
- package/bin/runners/runSafelist.js +1190 -0
- package/bin/runners/runScan.js +688 -0
- package/bin/runners/runShield.js +1282 -0
- package/bin/runners/runShip.js +1660 -0
- package/bin/runners/runTruth.d.ts +5 -0
- package/bin/runners/runTruth.js +101 -0
- package/bin/runners/runValidate.js +179 -0
- package/bin/runners/runWatch.js +478 -0
- package/bin/runners/utils.js +360 -0
- package/bin/scan.js +617 -0
- package/bin/vibecheck.js +1617 -0
- package/dist/guardrail/index.d.ts +2405 -0
- package/dist/guardrail/index.js +9747 -0
- package/dist/guardrail/index.js.map +1 -0
- package/dist/scanner/index.d.ts +282 -0
- package/dist/scanner/index.js +3395 -0
- package/dist/scanner/index.js.map +1 -0
- package/package.json +123 -104
- package/README.md +0 -491
- package/dist/index.js +0 -99711
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/scanner/index.ts","../../src/scanner/classifiers/path-classifier.ts","../../src/scanner/utils/dedup.ts","../../src/scanner/rules/catalog.ts","../../src/scanner/engines/credentials.ts","../../src/scanner/engines/security.ts","../../src/scanner/engines/fake-features.ts","../../src/scanner/engines/hallucinations.ts","../../src/scanner/engines/dead-ui.ts","../../src/scanner/engines/code-quality.ts","../../src/scanner/engines/import-graph.ts","../../src/scanner/engines/runtime-verify.ts","../../src/scanner/engines/auto-fix.ts"],"sourcesContent":["/**\n * VibeCheck Unified Scanner\n * \n * The most accurate AI code scanner on the market.\n * \n * Combines 6 specialized engines running in parallel:\n * 1. Credentials — hardcoded secrets, API keys, tokens (20 patterns)\n * 2. Security — injection, XSS, SSRF, prototype pollution (30 patterns)\n * 3. Fake Features — stubs, fake success, auth bypass, silent failures (25+ patterns)\n * 4. Hallucinations — fake packages, ghost routes, placeholder URLs (13 patterns)\n * 5. Dead UI — dead links, noop handlers, coming soon, disabled without reason (5 checks)\n * 6. Code Quality — debug code, type safety, mock data (18 patterns)\n * \n * Plus:\n * - PathClassifier for smart file filtering (from FOUR v3.5.1)\n * - Rule Catalog with human-readable \"why\" + \"fix\" for every finding\n * - Cross-engine deduplication with confidence boosting\n * - Severity escalation for critical-path files (api/, auth/, payment/)\n * \n * Architecture:\n * Files → Classify → [6 Engines in parallel] → Deduplicate → Score → Report\n */\n\nimport { readFileSync, readdirSync, statSync, existsSync } from 'fs';\nimport { join, extname, relative } from 'path';\nimport { createHash } from 'crypto';\n\nimport type {\n ScanOptions,\n ScanReport,\n ScanEngine,\n FileContext,\n Finding,\n Severity,\n EngineResult,\n FixReport,\n} from './types/index.js';\n\nimport { classifyPath, isCodeFile } from './classifiers/path-classifier.js';\nimport { deduplicateFindings } from './utils/dedup.js';\n\n// Engines\nimport { credentialsEngine } from './engines/credentials.js';\nimport { securityEngine } from './engines/security.js';\nimport { fakeFeaturesEngine } from './engines/fake-features.js';\nimport { hallucinationsEngine } from './engines/hallucinations.js';\nimport { deadUIEngine } from './engines/dead-ui.js';\nimport { codeQualityEngine } from './engines/code-quality.js';\nimport { importGraphEngine } from './engines/import-graph.js';\nimport { runtimeVerifyEngine } from './engines/runtime-verify.js';\nimport { applyFixes } from './engines/auto-fix.js';\n\n// ============================================================================\n// All Engines\n// ============================================================================\n\nconst ALL_ENGINES: ScanEngine[] = [\n credentialsEngine,\n securityEngine,\n fakeFeaturesEngine,\n hallucinationsEngine,\n deadUIEngine,\n codeQualityEngine,\n importGraphEngine,\n runtimeVerifyEngine,\n];\n\n// ============================================================================\n// File Loading\n// ============================================================================\n\nconst DEFAULT_EXCLUDE = [\n 'node_modules', '.git', 'dist', 'build', '.next', '.nuxt',\n 'coverage', '__pycache__', '.venv', 'venv', '.output',\n];\n\nfunction loadFiles(projectRoot: string, options: ScanOptions): Map<string, FileContext> {\n const files = new Map<string, FileContext>();\n const exclude = options.exclude ?? DEFAULT_EXCLUDE;\n const maxFileSize = 512 * 1024; // 512KB max per file\n\n function walk(dir: string): void {\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return;\n }\n\n for (const entry of entries) {\n const fullPath = join(dir, entry);\n\n // Skip excluded directories early\n if (exclude.some(e => entry === e || entry.startsWith('.'))) {\n try {\n if (statSync(fullPath).isDirectory()) continue;\n } catch {\n continue;\n }\n }\n\n let stat;\n try {\n stat = statSync(fullPath);\n } catch {\n continue;\n }\n\n if (stat.isDirectory()) {\n walk(fullPath);\n continue;\n }\n\n // Only code files\n if (!isCodeFile(fullPath)) continue;\n\n // Skip large files\n if (stat.size > maxFileSize) continue;\n\n const relativePath = relative(projectRoot, fullPath);\n const classification = classifyPath(relativePath);\n\n // Skip files excluded by default (unless override)\n if (classification.excludeByDefault && classification.category !== 'test') continue;\n\n // Skip test files unless included\n if (classification.category === 'test' && !options.includeTests) continue;\n\n try {\n const content = readFileSync(fullPath, 'utf-8');\n const hash = createHash('md5').update(content).digest('hex');\n\n files.set(relativePath, {\n path: relativePath,\n absolutePath: fullPath,\n content,\n lines: content.split('\\n'),\n ext: extname(fullPath).toLowerCase(),\n hash,\n classification,\n });\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n // If specific files provided, load only those\n if (options.files && options.files.length > 0) {\n for (const filePath of options.files) {\n const fullPath = join(projectRoot, filePath);\n if (!existsSync(fullPath)) continue;\n try {\n const content = readFileSync(fullPath, 'utf-8');\n const hash = createHash('md5').update(content).digest('hex');\n const classification = classifyPath(filePath);\n files.set(filePath, {\n path: filePath,\n absolutePath: fullPath,\n content,\n lines: content.split('\\n'),\n ext: extname(fullPath).toLowerCase(),\n hash,\n classification,\n });\n } catch {\n // Skip\n }\n }\n } else {\n walk(projectRoot);\n }\n\n return files;\n}\n\n// ============================================================================\n// Health Score\n// ============================================================================\n\nfunction calculateHealthScore(findings: Finding[]): number {\n let score = 100;\n\n for (const f of findings) {\n switch (f.severity) {\n case 'critical': score -= 15; break;\n case 'high': score -= 8; break;\n case 'medium': score -= 3; break;\n case 'low': score -= 1; break;\n }\n\n // Extra penalty for hallucinations and auth bypasses\n if (f.category === 'hallucinations') score -= 3;\n if (f.ruleId === 'FAKE005') score -= 5; // Auth bypass\n }\n\n return Math.max(0, Math.min(100, score));\n}\n\n// ============================================================================\n// Main Scan\n// ============================================================================\n\nexport async function scan(options: ScanOptions): Promise<ScanReport> {\n const startTime = Date.now();\n const scanId = `scan-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n\n // 1. Load and classify files\n options.onProgress?.({\n phase: 'loading',\n processed: 0,\n total: 0,\n percentage: 0,\n elapsedMs: 0,\n });\n\n const files = loadFiles(options.projectRoot, options);\n\n options.onProgress?.({\n phase: 'classifying',\n processed: files.size,\n total: files.size,\n percentage: 10,\n elapsedMs: Date.now() - startTime,\n });\n\n // 2. Select engines\n const enabledEngines = options.engines\n ? ALL_ENGINES.filter(e => options.engines!.includes(e.name))\n : ALL_ENGINES;\n\n // 3. Run engines (parallel or sequential)\n const engineResults: EngineResult[] = [];\n let allFindings: Finding[] = [];\n\n if (options.parallel !== false) {\n // Parallel execution\n const promises = enabledEngines.map(async (engine) => {\n const engineStart = Date.now();\n try {\n const findings = await Promise.race([\n engine.scan(files, options),\n new Promise<Finding[]>((_, reject) =>\n setTimeout(() => reject(new Error('Engine timeout')), options.engineTimeout ?? 30000)\n ),\n ]);\n return {\n engine: engine.name,\n findings: findings.length,\n durationMs: Date.now() - engineStart,\n success: true,\n result: findings,\n };\n } catch (err) {\n return {\n engine: engine.name,\n findings: 0,\n durationMs: Date.now() - engineStart,\n success: false,\n error: err instanceof Error ? err.message : 'Unknown error',\n result: [] as Finding[],\n };\n }\n });\n\n const results = await Promise.all(promises);\n for (const r of results) {\n engineResults.push({\n engine: r.engine,\n findings: r.findings,\n durationMs: r.durationMs,\n success: r.success,\n error: r.error,\n });\n allFindings.push(...r.result);\n }\n } else {\n // Sequential execution\n for (const engine of enabledEngines) {\n const engineStart = Date.now();\n try {\n const findings = await engine.scan(files, options);\n engineResults.push({\n engine: engine.name,\n findings: findings.length,\n durationMs: Date.now() - engineStart,\n success: true,\n });\n allFindings.push(...findings);\n } catch (err) {\n engineResults.push({\n engine: engine.name,\n findings: 0,\n durationMs: Date.now() - engineStart,\n success: false,\n error: err instanceof Error ? err.message : 'Unknown error',\n });\n }\n }\n }\n\n options.onProgress?.({\n phase: 'deduplicating',\n processed: allFindings.length,\n total: allFindings.length,\n percentage: 85,\n elapsedMs: Date.now() - startTime,\n });\n\n // 4. Deduplicate\n const { deduplicated, suppressedCount } = deduplicateFindings(allFindings);\n\n // 5. Apply severity threshold\n const severityOrder: Severity[] = ['low', 'medium', 'high', 'critical'];\n const minSeverityIndex = severityOrder.indexOf(options.severityThreshold ?? 'low');\n const filtered = deduplicated.filter(\n f => severityOrder.indexOf(f.severity) >= minSeverityIndex\n );\n\n // 6. Notify findings\n if (options.onFinding) {\n for (const f of filtered) {\n options.onFinding(f);\n }\n }\n\n // 7. Build summary\n const bySeverity: Record<Severity, number> = { critical: 0, high: 0, medium: 0, low: 0 };\n const byCategory: Record<string, number> = {};\n const byEngine: Record<string, number> = {};\n\n for (const f of filtered) {\n bySeverity[f.severity]++;\n byCategory[f.category] = (byCategory[f.category] ?? 0) + 1;\n byEngine[f.engine] = (byEngine[f.engine] ?? 0) + 1;\n }\n\n const durationMs = Date.now() - startTime;\n const engineTimings: Record<string, number> = {};\n for (const r of engineResults) {\n engineTimings[r.engine] = r.durationMs;\n }\n\n options.onProgress?.({\n phase: 'complete',\n processed: files.size,\n total: files.size,\n percentage: 100,\n elapsedMs: durationMs,\n });\n\n return {\n scanId,\n timestamp: new Date().toISOString(),\n findings: filtered,\n summary: {\n totalFiles: files.size,\n filesScanned: files.size,\n totalFindings: filtered.length,\n bySeverity,\n byCategory,\n byEngine,\n autoFixable: filtered.filter(f => f.autoFixable).length,\n suppressedDuplicates: suppressedCount,\n },\n healthScore: calculateHealthScore(filtered),\n engineResults,\n metrics: {\n durationMs,\n filesPerSecond: files.size > 0 ? Math.round((files.size / durationMs) * 1000) : 0,\n engineTimings,\n },\n };\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n// ============================================================================\n// Auto-Fix\n// ============================================================================\n\nexport async function fix(options: ScanOptions & { dryRun?: boolean }): Promise<{ report: ScanReport; fixReport: FixReport }> {\n const report = await scan(options);\n const fixReport = applyFixes({\n findings: report.findings,\n projectRoot: options.projectRoot,\n dryRun: options.dryRun ?? false,\n });\n return { report, fixReport };\n}\n\nexport { ALL_ENGINES, applyFixes };\nexport type { ScanOptions, ScanReport, Finding, FileContext, ScanEngine, FixReport };\nexport { RULE_CATALOG, getRuleOrDefault } from './rules/catalog.js';\nexport { classifyPath } from './classifiers/path-classifier.js';\n","/**\n * Path Classifier\n * \n * Categorizes files for smart filtering. Reduces false positives by\n * understanding file context (test vs prod, generated vs authored, etc.)\n * \n * Source: FOUR (v3.5.1) path-classifier, enhanced\n */\n\nimport { basename, extname } from 'path';\nimport type { PathCategory, PathClassification } from '../types/index.js';\n\n// ============================================================================\n// Pattern Definitions\n// ============================================================================\n\ninterface PatternDef {\n patterns: RegExp[];\n category: PathCategory;\n excludeByDefault: boolean;\n}\n\nconst CATEGORY_PATTERNS: PatternDef[] = [\n {\n category: 'third_party',\n excludeByDefault: true,\n patterns: [\n /node_modules\\//,\n /vendor\\//,\n /\\.yarn\\//,\n /\\.pnpm\\//,\n /bower_components\\//,\n /packages\\/.*\\/node_modules/,\n ],\n },\n {\n category: 'build_output',\n excludeByDefault: true,\n patterns: [\n /\\/dist\\//,\n /\\/build\\//,\n /\\/.next\\//,\n /\\/.nuxt\\//,\n /\\/\\.output\\//,\n /\\/out\\//,\n /\\/coverage\\//,\n /\\/__generated__\\//,\n /\\.min\\.(js|css)$/,\n /\\.bundle\\.(js|css)$/,\n /\\.chunk\\.(js|css)$/,\n ],\n },\n {\n category: 'generated',\n excludeByDefault: true,\n patterns: [\n /\\.d\\.ts$/,\n /generated\\//,\n /\\.gen\\.(ts|js)$/,\n /prisma\\/generated\\//,\n /graphql\\/generated\\//,\n /swagger-output\\./,\n /openapi-generated\\//,\n /\\.lock$/,\n /lock\\.json$/,\n ],\n },\n {\n category: 'test',\n excludeByDefault: false, // We scan tests separately\n patterns: [\n /\\.(test|spec)\\.(ts|tsx|js|jsx)$/,\n /__tests__\\//,\n /__mocks__\\//,\n /\\.stories\\.(ts|tsx|js|jsx)$/,\n /\\.storybook\\//,\n /test-utils?\\.(ts|tsx|js|jsx)$/,\n /fixtures?\\//,\n /cypress\\//,\n /playwright\\//,\n /e2e\\//,\n /setupTests\\.(ts|js)$/,\n /jest\\.config\\./,\n /vitest\\.config\\./,\n ],\n },\n {\n category: 'config',\n excludeByDefault: false,\n patterns: [\n /\\.(config|rc)\\.(ts|js|mjs|cjs|json|yaml|yml)$/,\n /\\.eslintrc/,\n /\\.prettierrc/,\n /tsconfig.*\\.json$/,\n /\\.babelrc/,\n /tailwind\\.config/,\n /next\\.config/,\n /vite\\.config/,\n /webpack\\.config/,\n ],\n },\n {\n category: 'documentation',\n excludeByDefault: true,\n patterns: [\n /\\.(md|mdx|rst|txt)$/,\n /\\/docs?\\//,\n /\\/documentation\\//,\n /README/i,\n /CHANGELOG/i,\n /LICENSE/i,\n /CONTRIBUTING/i,\n ],\n },\n];\n\n// Critical paths - findings here get severity escalation\nconst CRITICAL_PATH_PATTERNS = [\n /\\/api\\//,\n /\\/auth\\//,\n /\\/payment/,\n /\\/billing/,\n /\\/admin/,\n /\\/checkout/,\n /\\/users\\//,\n /\\/account/,\n /\\/webhook/,\n /\\/security/,\n /middleware\\.(ts|js)/,\n /\\/lib\\/auth/,\n /\\/lib\\/db/,\n /\\/lib\\/stripe/,\n];\n\n// Always exclude - binary / irrelevant\nconst ALWAYS_EXCLUDE = [\n /\\.git\\//,\n /\\.DS_Store$/,\n /thumbs\\.db$/i,\n /\\.(png|jpg|jpeg|gif|webp|svg|ico|bmp|tiff?)$/i,\n /\\.(woff2?|ttf|eot|otf)$/i,\n /\\.(mp3|mp4|wav|ogg|webm|avi|mov)$/i,\n /\\.(pdf|doc|docx|xls|xlsx|ppt|pptx)$/i,\n /\\.(zip|tar|gz|bz2|7z|rar)$/i,\n /\\.(exe|dll|so|dylib|bin)$/i,\n /\\.(sqlite|db)$/i,\n];\n\n// ============================================================================\n// Classifier\n// ============================================================================\n\nexport function classifyPath(relativePath: string): PathClassification {\n const normalizedPath = relativePath.replace(/\\\\/g, '/');\n\n // Always-exclude check\n for (const pattern of ALWAYS_EXCLUDE) {\n if (pattern.test(normalizedPath)) {\n return {\n category: 'build_output',\n reason: `Binary/irrelevant file: ${pattern.source}`,\n excludeByDefault: true,\n isCriticalPath: false,\n };\n }\n }\n\n // Check category patterns\n for (const def of CATEGORY_PATTERNS) {\n for (const pattern of def.patterns) {\n if (pattern.test(normalizedPath)) {\n return {\n category: def.category,\n reason: `Matched pattern: ${pattern.source}`,\n excludeByDefault: def.excludeByDefault,\n isCriticalPath: false,\n };\n }\n }\n }\n\n // Default: user code\n const isCritical = CRITICAL_PATH_PATTERNS.some(p => p.test(normalizedPath));\n\n return {\n category: 'user_code',\n reason: 'Application source code',\n excludeByDefault: false,\n isCriticalPath: isCritical,\n };\n}\n\nexport function isCodeFile(filePath: string): boolean {\n const ext = extname(filePath).toLowerCase();\n return [\n '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',\n '.py', '.java', '.go', '.rs', '.rb', '.php',\n '.vue', '.svelte',\n ].includes(ext);\n}\n\nexport function isUIFile(filePath: string): boolean {\n const ext = extname(filePath).toLowerCase();\n return ['.tsx', '.jsx', '.vue', '.svelte'].includes(ext);\n}\n\nexport function isConfigFile(filePath: string): boolean {\n const name = basename(filePath).toLowerCase();\n return (\n name.includes('.config.') ||\n name.includes('.env') ||\n name.endsWith('.json') ||\n name.endsWith('.yaml') ||\n name.endsWith('.yml')\n );\n}\n\n/**\n * Escalate severity if finding is in a critical path\n */\nexport function escalateSeverity(\n severity: 'critical' | 'high' | 'medium' | 'low',\n isCriticalPath: boolean\n): 'critical' | 'high' | 'medium' | 'low' {\n if (!isCriticalPath) return severity;\n const escalation: Record<string, 'critical' | 'high' | 'medium' | 'low'> = {\n low: 'medium',\n medium: 'high',\n high: 'critical',\n critical: 'critical',\n };\n return escalation[severity];\n}\n","/**\n * Finding Deduplication\n * \n * When 6 engines run in parallel, they often flag the same code from different angles.\n * This deduplicator merges overlapping findings, keeping the highest-confidence version.\n * \n * Strategy:\n * 1. Group by file:line (same location)\n * 2. Within a group, keep the finding with highest confidence\n * 3. Merge tags and evidence from all variants\n * 4. Escalate severity if multiple engines agree\n */\n\nimport type { Finding, Severity } from '../types/index.js';\n\nconst SEVERITY_ORDER: Record<Severity, number> = {\n critical: 4,\n high: 3,\n medium: 2,\n low: 1,\n};\n\nexport function deduplicateFindings(findings: Finding[]): {\n deduplicated: Finding[];\n suppressedCount: number;\n} {\n // Group by file:line\n const groups = new Map<string, Finding[]>();\n\n for (const finding of findings) {\n const key = `${finding.file}:${finding.line}`;\n if (!groups.has(key)) {\n groups.set(key, []);\n }\n groups.get(key)!.push(finding);\n }\n\n const deduplicated: Finding[] = [];\n let suppressedCount = 0;\n\n for (const [, group] of groups) {\n if (group.length === 1) {\n deduplicated.push(group[0]);\n continue;\n }\n\n // Multiple findings at same location — merge\n // Sub-group by category to avoid merging unrelated findings\n const subGroups = new Map<string, Finding[]>();\n for (const f of group) {\n const subKey = f.category;\n if (!subGroups.has(subKey)) subGroups.set(subKey, []);\n subGroups.get(subKey)!.push(f);\n }\n\n for (const [, subGroup] of subGroups) {\n if (subGroup.length === 1) {\n deduplicated.push(subGroup[0]);\n continue;\n }\n\n // Sort by confidence (highest first), then severity\n subGroup.sort((a, b) => {\n const confDiff = b.confidenceScore - a.confidenceScore;\n if (confDiff !== 0) return confDiff;\n return (SEVERITY_ORDER[b.severity] ?? 0) - (SEVERITY_ORDER[a.severity] ?? 0);\n });\n\n // Keep the best finding\n const best = { ...subGroup[0] };\n\n // Merge tags from all variants\n const allTags = new Set<string>();\n for (const f of subGroup) {\n for (const tag of f.tags) allTags.add(tag);\n }\n best.tags = Array.from(allTags);\n\n // If 2+ engines agree, boost confidence\n const uniqueEngines = new Set(subGroup.map(f => f.engine));\n if (uniqueEngines.size >= 2) {\n best.verified = true;\n // Escalate severity if multiple engines flagged the same thing\n if (best.severity !== 'critical') {\n const maxSeverity = subGroup.reduce<Severity>(\n (max, f) => (SEVERITY_ORDER[f.severity] > SEVERITY_ORDER[max] ? f.severity : max),\n best.severity\n );\n best.severity = maxSeverity;\n }\n best.confidenceScore = Math.min(99, best.confidenceScore + 5);\n }\n\n deduplicated.push(best);\n suppressedCount += subGroup.length - 1;\n }\n }\n\n // Sort final results: critical first, then by confidence\n deduplicated.sort((a, b) => {\n const sevDiff = (SEVERITY_ORDER[b.severity] ?? 0) - (SEVERITY_ORDER[a.severity] ?? 0);\n if (sevDiff !== 0) return sevDiff;\n return b.confidenceScore - a.confidenceScore;\n });\n\n return { deduplicated, suppressedCount };\n}\n","/**\n * Rule Catalog\n * \n * Every rule has a human-readable \"why\" and \"fix\" so users understand\n * exactly what's wrong and how to fix it.\n * \n * Source: FOUR (v3.5.1) rule catalog, expanded with CORE + CLI5 rules\n */\n\nexport interface RuleDefinition {\n ruleId: string;\n name: string;\n category: string;\n severity: 'critical' | 'high' | 'medium' | 'low';\n description: string;\n why: string;\n fix: string;\n tags: string[];\n autoFixable: boolean;\n cwe?: string;\n}\n\nexport const RULE_CATALOG: Record<string, RuleDefinition> = {\n // ═══════════════════════════════════════════════════════════════════════════\n // CREDENTIALS (CRED)\n // ═══════════════════════════════════════════════════════════════════════════\n CRED001: {\n ruleId: 'CRED001',\n name: 'Hardcoded API Key',\n category: 'credentials',\n severity: 'critical',\n description: 'Hardcoded API key (Stripe, AWS, OpenAI, etc.) in source code',\n why: 'If your code is ever exposed (git push, npm publish, source maps), these credentials will be compromised. Attackers automate scanning for leaked keys.',\n fix: 'Move to environment variable. Use process.env.API_KEY and add to .env (gitignored).',\n tags: ['secrets', 'api-key', 'credentials'],\n autoFixable: false,\n cwe: 'CWE-798',\n },\n CRED002: {\n ruleId: 'CRED002',\n name: 'Hardcoded Password',\n category: 'credentials',\n severity: 'critical',\n description: 'Hardcoded password or database credential in source code',\n why: 'Passwords in code can be extracted from builds, logs, or version history. A single leaked DB password can compromise all user data.',\n fix: 'Use environment variables or a secrets manager (Vault, AWS Secrets Manager).',\n tags: ['secrets', 'password', 'database'],\n autoFixable: false,\n cwe: 'CWE-798',\n },\n CRED003: {\n ruleId: 'CRED003',\n name: 'Hardcoded JWT Secret',\n category: 'credentials',\n severity: 'critical',\n description: 'JWT signing secret hardcoded in source',\n why: 'Anyone with the JWT secret can forge authentication tokens and impersonate any user, including admins.',\n fix: 'Store in JWT_SECRET environment variable. Rotate regularly.',\n tags: ['secrets', 'jwt', 'auth'],\n autoFixable: false,\n cwe: 'CWE-798',\n },\n CRED004: {\n ruleId: 'CRED004',\n name: 'Private Key in Source',\n category: 'credentials',\n severity: 'critical',\n description: 'Private key (RSA, PEM, SSH) embedded in source code',\n why: 'Private keys grant access to encrypted communications, server authentication, and code signing. A leaked key requires full rotation.',\n fix: 'Store in secure key management. Load from file path in env var.',\n tags: ['secrets', 'private-key', 'cryptography'],\n autoFixable: false,\n cwe: 'CWE-321',\n },\n CRED005: {\n ruleId: 'CRED005',\n name: 'Connection String Exposed',\n category: 'credentials',\n severity: 'critical',\n description: 'Database connection string with credentials in source',\n why: 'Connection strings contain host, username, password, and database name. One string = complete database access.',\n fix: 'Use DATABASE_URL environment variable. Never commit .env files.',\n tags: ['secrets', 'database', 'connection-string'],\n autoFixable: false,\n cwe: 'CWE-798',\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // SECURITY (SEC)\n // ═══════════════════════════════════════════════════════════════════════════\n SEC001: {\n ruleId: 'SEC001',\n name: 'SQL Injection Risk',\n category: 'security',\n severity: 'critical',\n description: 'User input concatenated into SQL query',\n why: 'SQL injection allows attackers to read, modify, or delete all database data. It remains the #1 web vulnerability.',\n fix: 'Use parameterized queries or an ORM. Never concatenate user input into SQL.',\n tags: ['injection', 'sql', 'database'],\n autoFixable: false,\n cwe: 'CWE-89',\n },\n SEC002: {\n ruleId: 'SEC002',\n name: 'Command Injection Risk',\n category: 'security',\n severity: 'critical',\n description: 'User input passed to shell execution (exec, execSync, spawn)',\n why: 'Command injection lets attackers run arbitrary OS commands on your server — install backdoors, exfiltrate data, destroy files.',\n fix: 'Use execFile() with args array. Never pass user input to exec().',\n tags: ['injection', 'command', 'shell'],\n autoFixable: false,\n cwe: 'CWE-78',\n },\n SEC003: {\n ruleId: 'SEC003',\n name: 'XSS Vulnerability',\n category: 'security',\n severity: 'high',\n description: 'Unescaped user input rendered in HTML (innerHTML, dangerouslySetInnerHTML)',\n why: 'XSS lets attackers execute JavaScript in other users\\' browsers — steal sessions, redirect to phishing, deface UI.',\n fix: 'Use textContent instead of innerHTML. Sanitize with DOMPurify if HTML is required.',\n tags: ['xss', 'injection', 'html'],\n autoFixable: false,\n cwe: 'CWE-79',\n },\n SEC004: {\n ruleId: 'SEC004',\n name: 'Path Traversal Risk',\n category: 'security',\n severity: 'high',\n description: 'User input used in file path without sanitization',\n why: 'Path traversal (../../etc/passwd) lets attackers read any file on the server, including configs and secrets.',\n fix: 'Use path.resolve() and verify the result is within allowed directory.',\n tags: ['path-traversal', 'file-access'],\n autoFixable: false,\n cwe: 'CWE-22',\n },\n SEC005: {\n ruleId: 'SEC005',\n name: 'SSRF Risk',\n category: 'security',\n severity: 'high',\n description: 'User-controlled URL passed to server-side fetch/request',\n why: 'SSRF lets attackers make your server request internal services, cloud metadata endpoints (169.254.169.254), or scan your network.',\n fix: 'Validate URL against allowlist of domains. Block private IPs.',\n tags: ['ssrf', 'network'],\n autoFixable: false,\n cwe: 'CWE-918',\n },\n SEC006: {\n ruleId: 'SEC006',\n name: 'Prototype Pollution',\n category: 'security',\n severity: 'high',\n description: '__proto__ or prototype[] manipulation detected',\n why: 'Prototype pollution can lead to property injection across all objects, causing auth bypass or RCE.',\n fix: 'Use Object.create(null) for lookup objects. Validate property names.',\n tags: ['prototype-pollution', 'injection'],\n autoFixable: false,\n cwe: 'CWE-1321',\n },\n SEC007: {\n ruleId: 'SEC007',\n name: 'eval() Usage',\n category: 'security',\n severity: 'critical',\n description: 'eval() or new Function() with potentially dynamic input',\n why: 'eval() executes arbitrary code. If any input is user-controlled, it\\'s equivalent to giving the attacker a shell.',\n fix: 'Use JSON.parse() for data. Use a sandboxed interpreter for expressions.',\n tags: ['eval', 'code-execution'],\n autoFixable: false,\n cwe: 'CWE-95',\n },\n SEC008: {\n ruleId: 'SEC008',\n name: 'Mass Assignment',\n category: 'security',\n severity: 'high',\n description: 'Request body spread directly into database/object update',\n why: 'Mass assignment lets attackers set fields they shouldn\\'t (isAdmin: true, role: \"admin\") by adding extra fields to requests.',\n fix: 'Whitelist allowed fields explicitly. Use DTOs or pick() to select safe properties.',\n tags: ['mass-assignment', 'injection'],\n autoFixable: false,\n cwe: 'CWE-915',\n },\n SEC009: {\n ruleId: 'SEC009',\n name: 'Insecure Randomness',\n category: 'security',\n severity: 'high',\n description: 'Math.random() used for security-sensitive values (tokens, IDs, secrets)',\n why: 'Math.random() is not cryptographically secure. Tokens generated with it can be predicted.',\n fix: 'Use crypto.randomUUID() or crypto.randomBytes() for security-sensitive values.',\n tags: ['randomness', 'cryptography'],\n autoFixable: true,\n cwe: 'CWE-330',\n },\n SEC010: {\n ruleId: 'SEC010',\n name: 'Regex DoS Risk',\n category: 'security',\n severity: 'medium',\n description: 'Regular expression with catastrophic backtracking potential',\n why: 'A crafted input string can make a vulnerable regex take minutes/hours, causing denial of service.',\n fix: 'Use linear-time regex engines (re2) or simplify the pattern.',\n tags: ['redos', 'regex', 'dos'],\n autoFixable: false,\n cwe: 'CWE-1333',\n },\n SEC011: {\n ruleId: 'SEC011',\n name: 'Unfiltered DELETE/DROP',\n category: 'security',\n severity: 'critical',\n description: 'DELETE FROM or DROP TABLE without WHERE clause',\n why: 'Unfiltered destructive SQL operations can wipe entire tables in a single request.',\n fix: 'Always include WHERE clause. Add confirmation logic for destructive operations.',\n tags: ['sql', 'destructive'],\n autoFixable: false,\n cwe: 'CWE-89',\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // HALLUCINATIONS (HAL) — AI-specific detection\n // ═══════════════════════════════════════════════════════════════════════════\n HAL001: {\n ruleId: 'HAL001',\n name: 'Fake npm Package',\n category: 'hallucinations',\n severity: 'critical',\n description: 'Import from a package that doesn\\'t exist on npm',\n why: 'AI models frequently hallucinate package names. Installing a non-existent package can pull in a typosquatting malware package instead.',\n fix: 'Verify package exists on npmjs.com before importing. Check package.json dependencies.',\n tags: ['hallucination', 'npm', 'supply-chain'],\n autoFixable: false,\n cwe: 'CWE-829',\n },\n HAL002: {\n ruleId: 'HAL002',\n name: 'Fake API Method',\n category: 'hallucinations',\n severity: 'high',\n description: 'Call to a method that doesn\\'t exist on the referenced library/object',\n why: 'AI models invent plausible-sounding method names. Code compiles in TS only with \\'any\\' types, then crashes at runtime.',\n fix: 'Check the library\\'s actual API documentation. Use TypeScript strict mode.',\n tags: ['hallucination', 'api', 'method'],\n autoFixable: false,\n },\n HAL003: {\n ruleId: 'HAL003',\n name: 'Placeholder URL',\n category: 'hallucinations',\n severity: 'high',\n description: 'URL containing example.com, placeholder, or clearly fake domain',\n why: 'AI generates placeholder URLs that look real. Shipping these means features silently fail or hit wrong endpoints.',\n fix: 'Replace with actual API endpoint from environment variable.',\n tags: ['hallucination', 'url', 'placeholder'],\n autoFixable: false,\n },\n HAL004: {\n ruleId: 'HAL004',\n name: 'Invented Config Option',\n category: 'hallucinations',\n severity: 'medium',\n description: 'Configuration key that doesn\\'t exist in the library\\'s schema',\n why: 'AI invents plausible config options. The option is silently ignored, and the expected behavior never activates.',\n fix: 'Check the library docs for valid configuration options.',\n tags: ['hallucination', 'config'],\n autoFixable: false,\n },\n HAL005: {\n ruleId: 'HAL005',\n name: 'Ghost Route',\n category: 'hallucinations',\n severity: 'high',\n description: 'Frontend references an API route that doesn\\'t exist in the backend',\n why: 'AI generates matching frontend + backend code, but sometimes only one side. The missing route means the feature silently 404s.',\n fix: 'Verify route exists in your API. Run vibecheck truth to generate route manifest.',\n tags: ['hallucination', 'route', 'api'],\n autoFixable: false,\n },\n HAL006: {\n ruleId: 'HAL006',\n name: 'Ghost Env Variable',\n category: 'hallucinations',\n severity: 'high',\n description: 'process.env.X references a variable not declared in any .env file',\n why: 'AI adds env var references without updating .env. The code silently uses undefined, causing subtle runtime bugs.',\n fix: 'Add the variable to .env.example and .env. Use required() wrapper for critical vars.',\n tags: ['hallucination', 'env', 'config'],\n autoFixable: true,\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // FAKE FEATURES (FAKE) — Stubs, placeholders, empty implementations\n // ═══════════════════════════════════════════════════════════════════════════\n FAKE001: {\n ruleId: 'FAKE001',\n name: 'Empty Function Body',\n category: 'fake-features',\n severity: 'high',\n description: 'Function declared but body is empty or returns nothing',\n why: 'AI generates function signatures that look complete but have empty bodies. The feature appears to exist but does nothing.',\n fix: 'Implement the function body or remove if not needed.',\n tags: ['stub', 'empty', 'fake-feature'],\n autoFixable: false,\n },\n FAKE002: {\n ruleId: 'FAKE002',\n name: 'Hardcoded Success',\n category: 'fake-features',\n severity: 'high',\n description: 'Function always returns true/success without doing actual work',\n why: 'Auth checks, validation, and payment processing that always return success means no actual protection is in place.',\n fix: 'Implement actual logic. If intentionally stubbed, add @stub annotation.',\n tags: ['fake-success', 'stub', 'auth'],\n autoFixable: false,\n },\n FAKE003: {\n ruleId: 'FAKE003',\n name: 'Silent Error Swallowing',\n category: 'fake-features',\n severity: 'high',\n description: 'Empty catch block or catch that returns null/undefined',\n why: 'Silent failures hide bugs. Users see no error but the operation didn\\'t complete. Data loss and corruption follow.',\n fix: 'Log the error and either re-throw, return error state, or handle gracefully.',\n tags: ['error-handling', 'silent-failure'],\n autoFixable: false,\n },\n FAKE004: {\n ruleId: 'FAKE004',\n name: 'Placeholder/TODO in Production',\n category: 'fake-features',\n severity: 'medium',\n description: 'TODO, FIXME, HACK, WIP, CHANGEME markers in production code',\n why: 'Placeholder markers indicate incomplete implementation. Shipping them means features are partially broken.',\n fix: 'Complete the implementation or create a tracked issue.',\n tags: ['placeholder', 'todo', 'incomplete'],\n autoFixable: false,\n },\n FAKE005: {\n ruleId: 'FAKE005',\n name: 'Auth Bypass Pattern',\n category: 'fake-features',\n severity: 'critical',\n description: 'Authentication check that can be bypassed (skipAuth, isAdmin=true)',\n why: 'Auth bypasses in code are the most common security vulnerability. Any user can access protected resources.',\n fix: 'Remove the bypass. Use proper role-based access control.',\n tags: ['auth', 'bypass', 'security'],\n autoFixable: false,\n cwe: 'CWE-287',\n },\n FAKE006: {\n ruleId: 'FAKE006',\n name: 'Dangerous Default Value',\n category: 'fake-features',\n severity: 'high',\n description: 'Secret/credential env var with insecure fallback default',\n why: 'If the env var is missing, the insecure default is used in production — often a test key or empty string.',\n fix: 'Throw an error if required env vars are missing. Never provide fallback defaults for secrets.',\n tags: ['default', 'secret', 'env'],\n autoFixable: false,\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // DEAD UI (UI)\n // ═══════════════════════════════════════════════════════════════════════════\n UI001: {\n ruleId: 'UI001',\n name: 'Dead Link',\n category: 'dead-ui',\n severity: 'high',\n description: 'href=\"#\" or javascript:void(0) — link goes nowhere',\n why: 'Dead links frustrate users and indicate unfinished UI. Screen readers announce them as real links.',\n fix: 'Replace with actual route, use <button> for actions, or remove.',\n tags: ['ui', 'accessibility', 'dead-link'],\n autoFixable: false,\n },\n UI002: {\n ruleId: 'UI002',\n name: 'Noop Click Handler',\n category: 'dead-ui',\n severity: 'high',\n description: 'onClick={() => {}} — button/element does nothing when clicked',\n why: 'Users click the button expecting something to happen. Nothing does. This erodes trust in the entire application.',\n fix: 'Implement the handler or remove the onClick.',\n tags: ['ui', 'noop', 'handler'],\n autoFixable: false,\n },\n UI003: {\n ruleId: 'UI003',\n name: 'Coming Soon in Production',\n category: 'dead-ui',\n severity: 'medium',\n description: '\"Coming soon\", \"under construction\", \"not available\" in production UI',\n why: 'Users see a broken product. Competitors see an incomplete product. Neither is a good look.',\n fix: 'Hide the feature until ready, or implement it.',\n tags: ['ui', 'placeholder', 'coming-soon'],\n autoFixable: false,\n },\n UI004: {\n ruleId: 'UI004',\n name: 'Disabled Without Reason',\n category: 'dead-ui',\n severity: 'medium',\n description: 'Disabled button/input without tooltip or explanation',\n why: 'Users don\\'t know why they can\\'t click. This is a UX and accessibility failure.',\n fix: 'Add tooltip, aria-label, or visible text explaining why it\\'s disabled.',\n tags: ['ui', 'accessibility', 'disabled'],\n autoFixable: false,\n },\n UI005: {\n ruleId: 'UI005',\n name: 'Raw Fetch in Component',\n category: 'dead-ui',\n severity: 'low',\n description: 'Direct fetch(\"/api/...\") call in a UI component',\n why: 'Scattered fetch calls are hard to maintain, don\\'t handle loading/error states consistently, and bypass caching.',\n fix: 'Use React Query, SWR, tRPC, or a centralized API client.',\n tags: ['ui', 'fetch', 'architecture'],\n autoFixable: false,\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // CODE QUALITY (QLT)\n // ═══════════════════════════════════════════════════════════════════════════\n QLT001: {\n ruleId: 'QLT001',\n name: 'Console.log in Production',\n category: 'code-quality',\n severity: 'medium',\n description: 'console.log/debug/trace statement in production code',\n why: 'Console logs leak information in browser devtools, slow down rendering, and indicate debug code left behind.',\n fix: 'Remove or replace with a proper logging library (winston, pino).',\n tags: ['console', 'debug', 'quality'],\n autoFixable: true,\n },\n QLT002: {\n ruleId: 'QLT002',\n name: 'Debugger Statement',\n category: 'code-quality',\n severity: 'high',\n description: 'debugger statement left in production code',\n why: 'Debugger statements freeze the browser for any user with devtools open. In production, this is a showstopper.',\n fix: 'Remove the debugger statement.',\n tags: ['debugger', 'debug', 'quality'],\n autoFixable: true,\n },\n QLT003: {\n ruleId: 'QLT003',\n name: 'Hardcoded Mock Data',\n category: 'code-quality',\n severity: 'high',\n description: 'Mock/fake/dummy data in production source files',\n why: 'Mock data makes features look functional but returns stale/fake information to real users.',\n fix: 'Connect to actual data source. Move mock data to test files.',\n tags: ['mock', 'fake-data', 'quality'],\n autoFixable: false,\n },\n QLT004: {\n ruleId: 'QLT004',\n name: 'Unused Import',\n category: 'code-quality',\n severity: 'low',\n description: 'Import that is never used in the file',\n why: 'Unused imports increase bundle size and confuse other developers about what the file depends on.',\n fix: 'Remove the unused import.',\n tags: ['unused', 'import', 'quality'],\n autoFixable: true,\n },\n QLT005: {\n ruleId: 'QLT005',\n name: 'Type Assertion Abuse',\n category: 'code-quality',\n severity: 'medium',\n description: '\"as any\" or type assertion bypassing type safety',\n why: 'Type assertions silence the compiler but don\\'t fix the underlying type issue. Runtime errors follow.',\n fix: 'Fix the type properly. Use type guards or proper generic types.',\n tags: ['typescript', 'type-safety', 'quality'],\n autoFixable: false,\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // IMPORT GRAPH (IG) — Cross-file structural analysis\n // ═══════════════════════════════════════════════════════════════════════════\n IG001: {\n ruleId: 'IG001',\n name: 'Circular Dependency',\n category: 'import-graph',\n severity: 'high',\n description: 'Circular import chain detected between modules',\n why: 'Circular dependencies cause unpredictable initialization order, undefined values at import time, and make refactoring dangerous.',\n fix: 'Extract shared types/interfaces into a separate module. Break the cycle with dependency inversion.',\n tags: ['imports', 'circular', 'architecture'],\n autoFixable: false,\n },\n IG002: {\n ruleId: 'IG002',\n name: 'Orphan Module',\n category: 'import-graph',\n severity: 'medium',\n description: 'File is never imported by any other module in the project',\n why: 'Orphan modules are dead code that increases bundle size, confuses developers, and accumulates tech debt.',\n fix: 'Delete the file if unused, or add it to your entry points if it should be included.',\n tags: ['imports', 'dead-code', 'orphan'],\n autoFixable: false,\n },\n IG003: {\n ruleId: 'IG003',\n name: 'Ghost Route',\n category: 'import-graph',\n severity: 'high',\n description: 'Frontend fetches an API route that has no corresponding backend handler',\n why: 'Ghost routes cause silent 404s in production. Users see loading spinners that never resolve or cryptic error messages.',\n fix: 'Create the missing API route handler, or remove the frontend fetch call.',\n tags: ['imports', 'route', 'api', 'ghost'],\n autoFixable: false,\n },\n IG004: {\n ruleId: 'IG004',\n name: 'Ghost Env Variable',\n category: 'import-graph',\n severity: 'high',\n description: 'process.env.X referenced in code but not declared in any .env file',\n why: 'Missing env vars silently evaluate to undefined, causing features to break in production with no error message.',\n fix: 'Add the variable to .env and .env.example with a placeholder value.',\n tags: ['env', 'config', 'ghost'],\n autoFixable: true,\n },\n IG005: {\n ruleId: 'IG005',\n name: 'Barrel Re-export Bloat',\n category: 'import-graph',\n severity: 'low',\n description: 'Barrel index.ts re-exports everything, defeating tree-shaking',\n why: 'Barrel files that re-export entire modules prevent bundlers from tree-shaking unused code, increasing bundle size.',\n fix: 'Use direct imports instead of barrel imports for large modules.',\n tags: ['imports', 'barrel', 'performance'],\n autoFixable: false,\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // RUNTIME VERIFY (RV) — Static analysis for runtime issues\n // ═══════════════════════════════════════════════════════════════════════════\n RV001: {\n ruleId: 'RV001',\n name: 'Unhandled Promise',\n category: 'runtime-verify',\n severity: 'high',\n description: 'Promise chain without .catch() or try/catch around await',\n why: 'Unhandled promise rejections crash Node.js processes and leave users with white screens in browsers.',\n fix: 'Add .catch() to the promise chain, or wrap await in try/catch.',\n tags: ['async', 'promise', 'error-handling'],\n autoFixable: false,\n cwe: 'CWE-755',\n },\n RV002: {\n ruleId: 'RV002',\n name: 'Async Without Await',\n category: 'runtime-verify',\n severity: 'medium',\n description: 'Async function declared but never uses await',\n why: 'An async function without await still returns a Promise, which can mask bugs if the caller doesn\\'t await it.',\n fix: 'Remove async keyword if not needed, or add await for async operations inside.',\n tags: ['async', 'promise', 'quality'],\n autoFixable: false,\n },\n RV003: {\n ruleId: 'RV003',\n name: 'Dead Export',\n category: 'runtime-verify',\n severity: 'medium',\n description: 'Exported function/variable is never imported by any other file',\n why: 'Dead exports increase API surface area, confuse developers about the public API, and prevent safe refactoring.',\n fix: 'Remove the export keyword if the symbol is only used locally, or delete if truly unused.',\n tags: ['exports', 'dead-code', 'quality'],\n autoFixable: false,\n },\n RV004: {\n ruleId: 'RV004',\n name: 'Floating Promise',\n category: 'runtime-verify',\n severity: 'high',\n description: 'Async function called without await, .then(), or void operator',\n why: 'Floating promises run in the background with no error handling. Failures are silently swallowed.',\n fix: 'Add await, .then()/.catch(), or prefix with void if intentionally fire-and-forget.',\n tags: ['async', 'promise', 'fire-and-forget'],\n autoFixable: false,\n cwe: 'CWE-755',\n },\n RV005: {\n ruleId: 'RV005',\n name: 'Race Condition Risk',\n category: 'runtime-verify',\n severity: 'medium',\n description: 'Shared mutable state accessed in async context without synchronization',\n why: 'Concurrent async operations reading/writing the same variable cause intermittent bugs that are extremely hard to reproduce.',\n fix: 'Use a mutex/lock, or restructure to avoid shared mutable state.',\n tags: ['async', 'race-condition', 'concurrency'],\n autoFixable: false,\n },\n};\n\nexport function getRule(ruleId: string): RuleDefinition | undefined {\n return RULE_CATALOG[ruleId];\n}\n\nexport function getRuleOrDefault(ruleId: string): RuleDefinition {\n return RULE_CATALOG[ruleId] ?? {\n ruleId,\n name: ruleId,\n category: 'code-quality',\n severity: 'medium',\n description: `Rule ${ruleId}`,\n why: 'See rule documentation.',\n fix: 'Review and fix the flagged code.',\n tags: [],\n autoFixable: false,\n };\n}\n","/**\n * Credentials Engine\n * \n * Detects hardcoded API keys, secrets, passwords, tokens, and connection strings.\n * \n * Sources: CORE UltimateScanner (19 credential patterns), enhanced\n * \n * Design: Each pattern has a high-precision regex with confidence scoring.\n * Test files are scanned for live keys only (even test files shouldn't have sk_live_).\n */\n\nimport type { Finding, FileContext, ScanOptions, ScanEngine } from '../types/index.js';\nimport { getRuleOrDefault } from '../rules/catalog.js';\nimport { escalateSeverity } from '../classifiers/path-classifier.js';\n\ninterface CredentialPattern {\n name: string;\n ruleId: string;\n regex: RegExp;\n severity: 'critical' | 'high' | 'medium' | 'low';\n message: string;\n fix: string;\n confidence: number;\n /** If true, flag even in test files */\n flagInTests: boolean;\n /** Skip in .example, .sample, .template files */\n skipInExamples: boolean;\n cwe?: string;\n}\n\nconst PATTERNS: CredentialPattern[] = [\n // ── Live payment keys (always flag) ──\n {\n name: 'stripe-live-secret',\n ruleId: 'CRED001',\n regex: /['\"`](sk_live_[a-zA-Z0-9]{20,})['\"`]/,\n severity: 'critical',\n message: 'Stripe live secret key hardcoded',\n fix: 'Use process.env.STRIPE_SECRET_KEY',\n confidence: 99,\n flagInTests: true,\n skipInExamples: false,\n cwe: 'CWE-798',\n },\n {\n name: 'stripe-live-publishable',\n ruleId: 'CRED001',\n regex: /['\"`](pk_live_[a-zA-Z0-9]{20,})['\"`]/,\n severity: 'high',\n message: 'Stripe live publishable key hardcoded',\n fix: 'Use process.env.NEXT_PUBLIC_STRIPE_KEY',\n confidence: 95,\n flagInTests: false,\n skipInExamples: true,\n },\n {\n name: 'stripe-test-secret',\n ruleId: 'CRED001',\n regex: /['\"`](sk_test_[a-zA-Z0-9]{20,})['\"`]/,\n severity: 'high',\n message: 'Stripe test key hardcoded — use env var even for test keys',\n fix: 'Use process.env.STRIPE_TEST_KEY',\n confidence: 90,\n flagInTests: false,\n skipInExamples: true,\n },\n\n // ── AWS ──\n {\n name: 'aws-access-key',\n ruleId: 'CRED001',\n regex: /['\"`](AKIA[0-9A-Z]{16})['\"`]/,\n severity: 'critical',\n message: 'AWS Access Key ID hardcoded',\n fix: 'Use AWS SDK credential chain or AWS_ACCESS_KEY_ID env var',\n confidence: 99,\n flagInTests: true,\n skipInExamples: false,\n cwe: 'CWE-798',\n },\n {\n name: 'aws-secret-key',\n ruleId: 'CRED001',\n regex: /aws_secret_access_key\\s*[:=]\\s*['\"`]([^'\"`]{20,})['\"`]/i,\n severity: 'critical',\n message: 'AWS Secret Access Key hardcoded',\n fix: 'Use AWS_SECRET_ACCESS_KEY environment variable',\n confidence: 98,\n flagInTests: true,\n skipInExamples: false,\n cwe: 'CWE-798',\n },\n\n // ── AI providers ──\n {\n name: 'openai-key',\n ruleId: 'CRED001',\n regex: /['\"`](sk-[a-zA-Z0-9]{32,})['\"`]/,\n severity: 'critical',\n message: 'OpenAI API key hardcoded',\n fix: 'Use process.env.OPENAI_API_KEY',\n confidence: 92,\n flagInTests: true,\n skipInExamples: false,\n },\n {\n name: 'anthropic-key',\n ruleId: 'CRED001',\n regex: /['\"`](sk-ant-[a-zA-Z0-9-]{20,})['\"`]/,\n severity: 'critical',\n message: 'Anthropic API key hardcoded',\n fix: 'Use process.env.ANTHROPIC_API_KEY',\n confidence: 98,\n flagInTests: true,\n skipInExamples: false,\n },\n\n // ── GitHub / Git ──\n {\n name: 'github-token',\n ruleId: 'CRED001',\n regex: /['\"`](ghp_[a-zA-Z0-9]{36,})['\"`]/,\n severity: 'critical',\n message: 'GitHub personal access token hardcoded',\n fix: 'Use process.env.GITHUB_TOKEN',\n confidence: 99,\n flagInTests: true,\n skipInExamples: false,\n },\n {\n name: 'github-oauth',\n ruleId: 'CRED001',\n regex: /['\"`](gho_[a-zA-Z0-9]{36,})['\"`]/,\n severity: 'critical',\n message: 'GitHub OAuth token hardcoded',\n fix: 'Use process.env.GITHUB_OAUTH_TOKEN',\n confidence: 99,\n flagInTests: true,\n skipInExamples: false,\n },\n\n // ── Google / Firebase ──\n {\n name: 'google-api-key',\n ruleId: 'CRED001',\n regex: /['\"`](AIza[0-9A-Za-z_-]{35})['\"`]/,\n severity: 'high',\n message: 'Google API key hardcoded',\n fix: 'Use process.env.GOOGLE_API_KEY',\n confidence: 95,\n flagInTests: false,\n skipInExamples: true,\n },\n\n // ── Generic secrets ──\n {\n name: 'jwt-secret',\n ruleId: 'CRED003',\n regex: /(?:jwt[_-]?secret|JWT_SECRET)\\s*[:=]\\s*['\"`]([^'\"`]{8,})['\"`]/i,\n severity: 'critical',\n message: 'JWT signing secret hardcoded',\n fix: 'Use process.env.JWT_SECRET',\n confidence: 90,\n flagInTests: false,\n skipInExamples: true,\n cwe: 'CWE-798',\n },\n {\n name: 'generic-password',\n ruleId: 'CRED002',\n regex: /(?:password|passwd|pwd)\\s*[:=]\\s*['\"`]([^'\"`]{4,})['\"`]/i,\n severity: 'high',\n message: 'Hardcoded password detected',\n fix: 'Use environment variable or secrets manager',\n confidence: 75,\n flagInTests: false,\n skipInExamples: true,\n cwe: 'CWE-798',\n },\n {\n name: 'generic-secret',\n ruleId: 'CRED002',\n regex: /(?:secret|api[_-]?key|auth[_-]?token)\\s*[:=]\\s*['\"`]([^'\"`]{8,})['\"`]/i,\n severity: 'high',\n message: 'Hardcoded secret/token detected',\n fix: 'Use environment variable',\n confidence: 70,\n flagInTests: false,\n skipInExamples: true,\n },\n {\n name: 'private-key-pem',\n ruleId: 'CRED004',\n regex: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/,\n severity: 'critical',\n message: 'Private key embedded in source code',\n fix: 'Store key in file, reference via env var path',\n confidence: 99,\n flagInTests: true,\n skipInExamples: false,\n cwe: 'CWE-321',\n },\n {\n name: 'connection-string',\n ruleId: 'CRED005',\n regex: /['\"`](?:mongodb(?:\\+srv)?|postgres(?:ql)?|mysql|redis|amqp):\\/\\/[^'\"`\\s]{10,}['\"`]/i,\n severity: 'critical',\n message: 'Database connection string with credentials in source',\n fix: 'Use DATABASE_URL environment variable',\n confidence: 92,\n flagInTests: false,\n skipInExamples: true,\n cwe: 'CWE-798',\n },\n\n // ── Additional providers ──\n {\n name: 'slack-token',\n ruleId: 'CRED001',\n regex: /['\"`](xox[bpoas]-[0-9a-zA-Z-]{10,})['\"`]/,\n severity: 'critical',\n message: 'Slack token hardcoded',\n fix: 'Use process.env.SLACK_TOKEN',\n confidence: 97,\n flagInTests: true,\n skipInExamples: false,\n },\n {\n name: 'sendgrid-key',\n ruleId: 'CRED001',\n regex: /['\"`](SG\\.[a-zA-Z0-9_-]{22}\\.[a-zA-Z0-9_-]{43})['\"`]/,\n severity: 'critical',\n message: 'SendGrid API key hardcoded',\n fix: 'Use process.env.SENDGRID_API_KEY',\n confidence: 99,\n flagInTests: true,\n skipInExamples: false,\n },\n {\n name: 'twilio-key',\n ruleId: 'CRED001',\n regex: /['\"`](SK[a-f0-9]{32})['\"`]/,\n severity: 'high',\n message: 'Twilio API key hardcoded',\n fix: 'Use process.env.TWILIO_API_KEY',\n confidence: 85,\n flagInTests: false,\n skipInExamples: true,\n },\n {\n name: 'npm-token',\n ruleId: 'CRED001',\n regex: /['\"`](npm_[a-zA-Z0-9]{36,})['\"`]/,\n severity: 'critical',\n message: 'npm auth token hardcoded',\n fix: 'Use .npmrc with env var interpolation',\n confidence: 98,\n flagInTests: true,\n skipInExamples: false,\n },\n];\n\n// ============================================================================\n// Engine\n// ============================================================================\n\nexport const credentialsEngine: ScanEngine = {\n name: 'credentials',\n description: 'Detects hardcoded API keys, secrets, passwords, tokens',\n\n async scan(files: Map<string, FileContext>, options: ScanOptions): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n for (const [, file] of files) {\n const isTest = file.classification.category === 'test';\n const isExample = /\\.(example|sample|template)\\b/.test(file.path);\n const isCritical = file.classification.isCriticalPath;\n\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n\n // Skip comment-only lines (basic check)\n const trimmed = line.trim();\n if (trimmed.startsWith('//') && !trimmed.includes('=')) continue;\n if (trimmed.startsWith('*')) continue;\n\n for (const pattern of PATTERNS) {\n // Skip test-only exclusions\n if (isTest && !pattern.flagInTests) continue;\n // Skip example files\n if (isExample && pattern.skipInExamples) continue;\n\n const match = line.match(pattern.regex);\n if (!match) continue;\n\n // Extra validation for generic patterns to reduce FPs\n if (pattern.name === 'generic-password') {\n // Skip if it's a type annotation or variable declaration without value\n if (/type\\s|interface\\s|placeholder|example/i.test(line)) continue;\n // Skip if the \"password\" is a common test value\n const val = match[1];\n if (!val || val.length < 6) continue;\n }\n\n if (pattern.name === 'generic-secret') {\n const val = match[1];\n if (!val || /^[a-z_]+$/i.test(val)) continue; // Skip if looks like another var name\n if (/placeholder|example|your[_-]/i.test(val)) continue; // Skip obvious placeholders\n }\n\n const rule = getRuleOrDefault(pattern.ruleId);\n const severity = escalateSeverity(pattern.severity, isCritical);\n\n findings.push({\n id: `${pattern.ruleId}-${file.path}-${i + 1}`,\n ruleId: pattern.ruleId,\n engine: 'credentials',\n category: 'credentials',\n severity,\n confidence: pattern.confidence >= 90 ? 'certain' : pattern.confidence >= 70 ? 'likely' : 'possible',\n confidenceScore: pattern.confidence,\n file: file.path,\n line: i + 1,\n column: match.index,\n code: trimmed,\n message: pattern.message,\n why: rule.why,\n fix: pattern.fix,\n autoFixable: false,\n tags: rule.tags,\n cwe: pattern.cwe,\n verified: false,\n _dedup: `${pattern.name}:${file.path}:${i + 1}`,\n });\n }\n }\n }\n\n return findings;\n },\n};\n","/**\n * Security Engine\n * \n * Detects injection vulnerabilities, XSS, SSRF, prototype pollution,\n * and other security anti-patterns.\n * \n * Sources: CORE UltimateScanner (37 security patterns), CORE Firewall unsafe-side-effect rule\n */\n\nimport type { Finding, FileContext, ScanOptions, ScanEngine } from '../types/index.js';\nimport { getRuleOrDefault } from '../rules/catalog.js';\nimport { escalateSeverity } from '../classifiers/path-classifier.js';\n\ninterface SecurityPattern {\n name: string;\n ruleId: string;\n regex: RegExp;\n severity: 'critical' | 'high' | 'medium' | 'low';\n message: string;\n fix: string;\n confidence: number;\n excludeInTests: boolean;\n cwe?: string;\n /** Optional context validator to reduce FPs */\n validate?: (line: string, lines: string[], index: number) => boolean;\n}\n\nconst PATTERNS: SecurityPattern[] = [\n // ── Injection ──\n {\n name: 'sql-injection-concat',\n ruleId: 'SEC001',\n regex: /(?:query|execute|raw)\\s*\\(\\s*[`'\"](?:SELECT|INSERT|UPDATE|DELETE|DROP|ALTER)\\s[^`'\"]*\\$\\{/i,\n severity: 'critical',\n message: 'SQL injection: template literal in query',\n fix: 'Use parameterized queries: db.query(\"SELECT * FROM users WHERE id = $1\", [userId])',\n confidence: 92,\n excludeInTests: true,\n cwe: 'CWE-89',\n },\n {\n name: 'sql-injection-plus',\n ruleId: 'SEC001',\n regex: /(?:query|execute|raw)\\s*\\(\\s*['\"](?:SELECT|INSERT|UPDATE|DELETE)\\s[^'\"]*['\"]\\s*\\+/i,\n severity: 'critical',\n message: 'SQL injection: string concatenation in query',\n fix: 'Use parameterized queries. Never concatenate user input into SQL.',\n confidence: 90,\n excludeInTests: true,\n cwe: 'CWE-89',\n },\n {\n name: 'unfiltered-delete',\n ruleId: 'SEC011',\n regex: /DELETE\\s+FROM\\s+\\w+\\s*;?\\s*$/im,\n severity: 'critical',\n message: 'Unfiltered DELETE statement (no WHERE clause)',\n fix: 'Add WHERE clause. Add confirmation logic for destructive operations.',\n confidence: 85,\n excludeInTests: true,\n cwe: 'CWE-89',\n },\n {\n name: 'drop-table',\n ruleId: 'SEC011',\n regex: /DROP\\s+TABLE/i,\n severity: 'critical',\n message: 'DROP TABLE statement in application code',\n fix: 'Use migrations for schema changes. Never DROP in application logic.',\n confidence: 88,\n excludeInTests: true,\n },\n\n // ── Command Injection ──\n {\n name: 'exec-template',\n ruleId: 'SEC002',\n regex: /(?:exec|execSync|spawn|spawnSync)\\s*\\(\\s*`[^`]*\\$\\{/,\n severity: 'critical',\n message: 'Command injection: template literal in shell command',\n fix: 'Use execFile() with args array: execFile(\"cmd\", [arg1, arg2])',\n confidence: 95,\n excludeInTests: true,\n cwe: 'CWE-78',\n },\n {\n name: 'exec-concat',\n ruleId: 'SEC002',\n regex: /(?:exec|execSync)\\s*\\(\\s*['\"][^'\"]*['\"]\\s*\\+/,\n severity: 'critical',\n message: 'Command injection: concatenation in shell command',\n fix: 'Use execFile() with args array.',\n confidence: 93,\n excludeInTests: true,\n cwe: 'CWE-78',\n },\n {\n name: 'child-process-exec',\n ruleId: 'SEC002',\n regex: /child_process\\s*\\.\\s*exec\\s*\\(/,\n severity: 'high',\n message: 'child_process.exec() can run arbitrary shell commands',\n fix: 'Prefer execFile() or spawn() with explicit args array.',\n confidence: 80,\n excludeInTests: true,\n cwe: 'CWE-78',\n },\n\n // ── XSS ──\n {\n name: 'innerhtml-assignment',\n ruleId: 'SEC003',\n regex: /\\.innerHTML\\s*=/,\n severity: 'high',\n message: 'innerHTML assignment — potential XSS if content is user-controlled',\n fix: 'Use textContent for text. Use DOMPurify.sanitize() if HTML is needed.',\n confidence: 75,\n excludeInTests: true,\n cwe: 'CWE-79',\n },\n {\n name: 'dangerously-set-innerhtml',\n ruleId: 'SEC003',\n regex: /dangerouslySetInnerHTML/,\n severity: 'high',\n message: 'dangerouslySetInnerHTML — ensure content is sanitized',\n fix: 'Sanitize with DOMPurify before passing to dangerouslySetInnerHTML.',\n confidence: 70,\n excludeInTests: true,\n cwe: 'CWE-79',\n },\n {\n name: 'document-write',\n ruleId: 'SEC003',\n regex: /document\\.write\\s*\\(/,\n severity: 'high',\n message: 'document.write() can overwrite entire page with unescaped content',\n fix: 'Use DOM manipulation methods instead.',\n confidence: 80,\n excludeInTests: true,\n cwe: 'CWE-79',\n },\n\n // ── Path Traversal ──\n {\n name: 'path-traversal-join',\n ruleId: 'SEC004',\n regex: /(?:path\\.join|path\\.resolve)\\s*\\([^)]*(?:req\\.|params\\.|query\\.|body\\.)/,\n severity: 'high',\n message: 'User input in file path — potential path traversal',\n fix: 'Validate resolved path is within allowed directory: resolvedPath.startsWith(allowedDir)',\n confidence: 82,\n excludeInTests: true,\n cwe: 'CWE-22',\n },\n {\n name: 'fs-read-user-input',\n ruleId: 'SEC004',\n regex: /fs\\.(?:readFile|readFileSync|createReadStream)\\s*\\([^)]*(?:req\\.|params\\.|query\\.)/,\n severity: 'high',\n message: 'User input passed directly to file read operation',\n fix: 'Sanitize path and verify it\\'s within allowed directory.',\n confidence: 85,\n excludeInTests: true,\n cwe: 'CWE-22',\n },\n\n // ── SSRF ──\n {\n name: 'ssrf-fetch',\n ruleId: 'SEC005',\n regex: /fetch\\s*\\(\\s*(?:req\\.|params\\.|query\\.|body\\.|url|href)/,\n severity: 'high',\n message: 'User-controlled URL in server-side fetch — SSRF risk',\n fix: 'Validate URL against allowlist. Block private IPs (10.x, 172.16-31.x, 192.168.x, 169.254.x).',\n confidence: 78,\n excludeInTests: true,\n cwe: 'CWE-918',\n },\n {\n name: 'ssrf-axios',\n ruleId: 'SEC005',\n regex: /axios\\s*(?:\\.get|\\.post|\\.put|\\.delete|\\.request)\\s*\\(\\s*(?:req\\.|params\\.|query\\.|body\\.)/,\n severity: 'high',\n message: 'User-controlled URL in axios request — SSRF risk',\n fix: 'Validate URL against allowlist of allowed domains.',\n confidence: 78,\n excludeInTests: true,\n cwe: 'CWE-918',\n },\n\n // ── Code Execution ──\n {\n name: 'eval-usage',\n ruleId: 'SEC007',\n regex: /\\beval\\s*\\(/,\n severity: 'critical',\n message: 'eval() can execute arbitrary code',\n fix: 'Use JSON.parse() for data. Use a sandboxed interpreter for expressions.',\n confidence: 88,\n excludeInTests: true,\n cwe: 'CWE-95',\n validate: (line) => !/\\/\\/.*eval|['\"]eval['\"]/.test(line),\n },\n {\n name: 'new-function',\n ruleId: 'SEC007',\n regex: /\\bnew\\s+Function\\s*\\(/,\n severity: 'critical',\n message: 'new Function() can execute arbitrary code',\n fix: 'Avoid dynamic code generation. Use a template engine or parser.',\n confidence: 90,\n excludeInTests: true,\n cwe: 'CWE-95',\n },\n\n // ── Prototype Pollution ──\n {\n name: 'proto-access',\n ruleId: 'SEC006',\n regex: /__proto__|prototype\\s*\\[/,\n severity: 'high',\n message: 'Prototype pollution risk — __proto__ or prototype[] access',\n fix: 'Use Object.create(null) for lookup objects. Validate property names.',\n confidence: 82,\n excludeInTests: true,\n cwe: 'CWE-1321',\n },\n {\n name: 'mass-assignment',\n ruleId: 'SEC008',\n regex: /Object\\.assign\\s*\\([^,]+,\\s*req\\.body/,\n severity: 'high',\n message: 'Mass assignment — spreading request body into object',\n fix: 'Whitelist allowed fields: const { name, email } = req.body',\n confidence: 85,\n excludeInTests: true,\n cwe: 'CWE-915',\n },\n {\n name: 'spread-req-body',\n ruleId: 'SEC008',\n regex: /\\{\\s*\\.\\.\\.req\\.body\\s*\\}/,\n severity: 'high',\n message: 'Mass assignment — spreading request body directly',\n fix: 'Destructure only needed fields from req.body.',\n confidence: 88,\n excludeInTests: true,\n cwe: 'CWE-915',\n },\n\n // ── Insecure Randomness ──\n {\n name: 'math-random-token',\n ruleId: 'SEC009',\n regex: /Math\\.random\\s*\\(\\s*\\).*(?:token|id|key|secret|session|nonce|csrf)/i,\n severity: 'high',\n message: 'Math.random() used for security-sensitive value',\n fix: 'Use crypto.randomUUID() or crypto.randomBytes()',\n confidence: 85,\n excludeInTests: true,\n cwe: 'CWE-330',\n },\n {\n name: 'math-random-hex',\n ruleId: 'SEC009',\n regex: /Math\\.random\\(\\)\\.toString\\((?:16|36)\\)/,\n severity: 'medium',\n message: 'Math.random() for ID generation — not cryptographically secure',\n fix: 'Use crypto.randomUUID() for unique IDs',\n confidence: 80,\n excludeInTests: true,\n cwe: 'CWE-330',\n },\n\n // ── Destructive Operations ──\n {\n name: 'rm-rf-root',\n ruleId: 'SEC002',\n regex: /rm\\s+-rf\\s+\\//,\n severity: 'critical',\n message: 'Recursive delete from root directory',\n fix: 'Use explicit, validated path. Never delete from root.',\n confidence: 98,\n excludeInTests: false,\n },\n {\n name: 'rm-rf-wildcard',\n ruleId: 'SEC002',\n regex: /rm\\s+-rf\\s+\\*/,\n severity: 'critical',\n message: 'Recursive delete with wildcard',\n fix: 'Use explicit, validated path.',\n confidence: 95,\n excludeInTests: false,\n },\n\n // ── Dynamic Require/Import ──\n {\n name: 'dynamic-require',\n ruleId: 'SEC007',\n regex: /require\\s*\\(\\s*[^'\"][a-zA-Z_$]/,\n severity: 'medium',\n message: 'Dynamic require() — path injection risk',\n fix: 'Use static imports. Validate path against allowlist if dynamic is needed.',\n confidence: 72,\n excludeInTests: true,\n },\n {\n name: 'dynamic-import',\n ruleId: 'SEC007',\n regex: /import\\s*\\(\\s*[^'\"][a-zA-Z_$]/,\n severity: 'medium',\n message: 'Dynamic import() — path injection risk',\n fix: 'Use static imports when possible. Validate path.',\n confidence: 68,\n excludeInTests: true,\n },\n\n // ── File Deletion ──\n {\n name: 'fs-unlink',\n ruleId: 'SEC002',\n regex: /fs\\.(?:unlink|rmdir|rm)(?:Sync)?\\s*\\(/,\n severity: 'medium',\n message: 'File/directory deletion — ensure path is validated',\n fix: 'Validate path is within allowed directory before deletion.',\n confidence: 65,\n excludeInTests: true,\n validate: (line) => !line.includes('temp') && !line.includes('tmp'),\n },\n\n // ── Weak Crypto ──\n {\n name: 'md5-usage',\n ruleId: 'SEC009',\n regex: /createHash\\s*\\(\\s*['\"`]md5['\"`]\\s*\\)/,\n severity: 'medium',\n message: 'MD5 hash — cryptographically broken',\n fix: 'Use SHA-256 or better: crypto.createHash(\"sha256\")',\n confidence: 90,\n excludeInTests: true,\n cwe: 'CWE-328',\n },\n {\n name: 'sha1-usage',\n ruleId: 'SEC009',\n regex: /createHash\\s*\\(\\s*['\"`]sha1['\"`]\\s*\\)/,\n severity: 'medium',\n message: 'SHA-1 hash — deprecated for security use',\n fix: 'Use SHA-256: crypto.createHash(\"sha256\")',\n confidence: 85,\n excludeInTests: true,\n cwe: 'CWE-328',\n },\n\n // ── CORS Misconfiguration ──\n {\n name: 'cors-wildcard',\n ruleId: 'SEC005',\n regex: /(?:Access-Control-Allow-Origin|origin)\\s*[:=]\\s*['\"`]\\*['\"`]/,\n severity: 'high',\n message: 'CORS wildcard allows any origin',\n fix: 'Restrict to specific allowed origins.',\n confidence: 80,\n excludeInTests: true,\n },\n\n // ── NoSQL Injection ──\n {\n name: 'nosql-injection',\n ruleId: 'SEC001',\n regex: /\\$(?:where|regex|gt|lt|ne|or|and)\\s*[:=]\\s*(?:req\\.|params\\.|query\\.|body\\.)/,\n severity: 'high',\n message: 'NoSQL injection — MongoDB operator from user input',\n fix: 'Sanitize input. Use mongoose-sanitize or explicit field selection.',\n confidence: 82,\n excludeInTests: true,\n cwe: 'CWE-943',\n },\n];\n\n// ============================================================================\n// Engine\n// ============================================================================\n\nexport const securityEngine: ScanEngine = {\n name: 'security',\n description: 'Detects injection, XSS, SSRF, prototype pollution, and security anti-patterns',\n\n async scan(files: Map<string, FileContext>, options: ScanOptions): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n for (const [, file] of files) {\n const isTest = file.classification.category === 'test';\n const isCritical = file.classification.isCriticalPath;\n\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n const trimmed = line.trim();\n\n // Skip pure comments\n if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*')) continue;\n\n for (const pattern of PATTERNS) {\n if (isTest && pattern.excludeInTests) continue;\n\n const match = line.match(pattern.regex);\n if (!match) continue;\n\n // Run custom validator if present\n if (pattern.validate && !pattern.validate(line, file.lines, i)) continue;\n\n const rule = getRuleOrDefault(pattern.ruleId);\n const severity = escalateSeverity(pattern.severity, isCritical);\n\n findings.push({\n id: `${pattern.ruleId}-${file.path}-${i + 1}`,\n ruleId: pattern.ruleId,\n engine: 'security',\n category: 'security',\n severity,\n confidence: pattern.confidence >= 90 ? 'certain' : pattern.confidence >= 70 ? 'likely' : 'possible',\n confidenceScore: pattern.confidence,\n file: file.path,\n line: i + 1,\n column: match.index,\n code: trimmed,\n message: pattern.message,\n why: rule.why,\n fix: pattern.fix,\n autoFixable: false,\n tags: rule.tags,\n cwe: pattern.cwe,\n verified: false,\n _dedup: `${pattern.name}:${file.path}:${i + 1}`,\n });\n }\n }\n }\n\n return findings;\n },\n};\n","/**\n * Fake Features Engine\n * \n * Detects stub functions, fake success returns, silent error swallowing,\n * auth bypasses, dangerous defaults, and placeholder markers.\n * \n * Sources: CLI5 RealitySniffScanner (best false-positive reduction),\n * CORE UltimateScanner fake-features patterns\n * \n * Design: Each pattern has contextual validators to minimize false positives.\n * This is where most AI-generated \"looks-done-but-isn't\" code gets caught.\n */\n\nimport type { Finding, FileContext, ScanOptions, ScanEngine } from '../types/index.js';\nimport { getRuleOrDefault } from '../rules/catalog.js';\nimport { escalateSeverity } from '../classifiers/path-classifier.js';\n\n// ============================================================================\n// Pattern Groups (from CLI5 RealitySniff, refined)\n// ============================================================================\n\nconst PLACEHOLDER_PATTERNS: RegExp[] = [\n // Match 'placeholder' when used as value, not HTML attribute\n /[=:]\\s*['\"]?placeholder['\"]?(?:\\s*[,;}\\]]|$)/i,\n // Match 'stub' in function/method context\n /\\bstub(?:bed|bing)?\\s*(?:function|method|implementation|out)/i,\n // Match 'dummy' in data contexts\n /\\bdummy[-_]?(?:data|value|user|id|token|response)\\b/i,\n // Match 'fake' in data contexts (not test files)\n /\\bfake[-_]?(?:data|response|user|api|endpoint)\\b/i,\n // Hardcoded credential placeholders\n /\\bhardcoded\\s*(?:secret|password|key|token|credential)/i,\n // TODO with action verbs\n /\\bTODO\\b.*(?:implement|fix|complete|replace|remove)/i,\n // Work in progress markers\n /\\bWIP\\b(?:\\s*[-:]\\s|\\s+)/i,\n // TBD markers\n /\\bTBD\\b(?:\\s*[-:]\\s|\\s+)/i,\n // Not yet implemented\n /\\bNYI\\b/i,\n /\\bcoming\\s+soon\\b/i,\n // CHANGEME / REPLACEME\n /\\bCHANGE[-_]?ME\\b/i,\n /\\bREPLACE[-_]?ME\\b/i,\n];\n\nconst FAKE_SUCCESS_PATTERNS: RegExp[] = [\n // Return true with nothing else in the function\n /^\\s*return\\s+true\\s*;?\\s*$/i,\n // Hardcoded success without checking\n /return\\s*{\\s*success:\\s*true\\s*}/i,\n // Always returning ok\n /return\\s*{\\s*status:\\s*[\"']ok[\"']\\s*}/i,\n // Mock/fake success comments\n /\\/\\/\\s*(?:fake|mock|stub)\\s*success/i,\n];\n\nconst SILENT_FAILURE_PATTERNS: RegExp[] = [\n // Completely empty catch blocks\n /catch\\s*\\(\\s*(?:_|e|err|error)?\\s*\\)\\s*{\\s*}/,\n // Catch that just returns undefined/null\n /catch\\s*\\([^)]*\\)\\s*{\\s*return(?:\\s+(?:undefined|null))?\\s*;?\\s*}/,\n // Catch with only a comment\n /catch\\s*\\([^)]*\\)\\s*{\\s*\\/\\/[^\\n]*\\s*}/,\n // Catch with only console.log (no actual handling)\n /catch\\s*\\([^)]*\\)\\s*{\\s*console\\.log\\([^)]+\\)\\s*;?\\s*}/,\n];\n\nconst AUTH_BYPASS_PATTERNS: RegExp[] = [\n // Hardcoded admin bypasses\n /(?:if|&&|\\|\\|)\\s*\\(\\s*(?:true|1)\\s*\\)\\s*.*(?:admin|auth)/i,\n // Skip/disable auth flags\n /\\b(?:skip|disable|bypass)Auth(?:entication)?\\s*[=:]\\s*true\\b/i,\n // Hardcoded isAdmin = true\n /\\b(?:const|let|var)\\s+isAdmin\\s*=\\s*true\\b/i,\n // Auth bypass comments\n /\\/\\/\\s*(?:bypass|skip|disable)\\s*auth/i,\n // UI-only gating\n /\\/\\/\\s*(?:ui|client)[-\\s]*only\\s*(?:check|gating|validation)/i,\n // Wildcard permissions\n /permissions?\\s*[=:]\\s*\\[\\s*['\"]?\\*['\"]?\\s*\\]/i,\n // Always-true auth functions\n /(?:isAuth|isAdmin|hasPermission|canAccess)\\s*[=:]\\s*\\(\\)\\s*=>\\s*true/i,\n];\n\nconst DANGEROUS_DEFAULT_PATTERNS: RegExp[] = [\n // Secret env vars with insecure defaults\n /process\\.env\\.(?:\\w*(?:SECRET|KEY|TOKEN|PASSWORD|CREDENTIAL)\\w*)\\s*\\|\\|\\s*[\"'][^'\"]{0,50}[\"']/i,\n // Database URLs with placeholder passwords\n /(?:DATABASE|DB|MONGO|POSTGRES|MYSQL|REDIS)_URL\\s*[=:]\\s*[\"'][^'\"]*(?:password|changeme|replace)[^'\"]*[\"']/i,\n // Placeholder markers in credentials\n /(?:api[_-]?key|secret|token|password)\\s*[=:]\\s*[\"'](?:CHANGEME|REPLACE_ME|YOUR_[A-Z_]+|xxx+|TODO)[\"']/i,\n // Auth endpoints pointing to localhost\n /(?:AUTH|BILLING|PAYMENT|WEBHOOK)_(?:URL|ENDPOINT)\\s*[=:]\\s*[\"']https?:\\/\\/localhost/i,\n // Empty string defaults for required secrets\n /(?:SECRET|API_KEY|TOKEN|PASSWORD)\\s*[=:]\\s*process\\.env\\.\\w+\\s*\\|\\|\\s*[\"']\\s*[\"']/i,\n];\n\nconst EMPTY_FUNCTION_PATTERNS: RegExp[] = [\n // async function with empty body\n /async\\s+(?:function\\s+\\w+|(?:const|let)\\s+\\w+\\s*=\\s*async)\\s*\\([^)]*\\)\\s*(?::\\s*\\w+[<>\\[\\]]*\\s*)?\\s*{\\s*}/,\n // function with only return undefined\n /function\\s+\\w+\\s*\\([^)]*\\)\\s*{\\s*return\\s*;?\\s*}/,\n // arrow function with empty body\n /=>\\s*{\\s*}\\s*[;,)]/,\n];\n\n// ============================================================================\n// Validators (from CLI5 — key to reducing false positives)\n// ============================================================================\n\nfunction isCommentLine(line: string): boolean {\n return /^\\s*(?:\\/\\/|\\/\\*|\\*|#|<!--|\"\"\"|''')/.test(line);\n}\n\nfunction isDocContext(filePath: string, line: string): boolean {\n const lp = filePath.toLowerCase();\n if (/\\.(md|mdx|rst|txt)$/.test(lp)) return true;\n if (lp.includes('/docs/') || lp.includes('/documentation/')) return true;\n if (lp.includes('/examples/') || lp.includes('/example/')) return true;\n if (/^\\s*\\*\\s*@(?:example|see|param|returns)/.test(line)) return true;\n return false;\n}\n\nfunction isInErrorContext(lines: string[], lineIndex: number): boolean {\n const before = lines.slice(Math.max(0, lineIndex - 5), lineIndex).join('\\n');\n return /catch|onError|fallback|error|exception/i.test(before);\n}\n\nfunction validatePlaceholder(line: string, filePath: string): boolean {\n const ll = line.toLowerCase();\n // Skip CSS/HTML placeholder attributes\n if (/placeholder\\s*[=:]/.test(ll) && !ll.includes('=')) return false;\n // Skip type definitions\n if (ll.includes('type ') || ll.includes('interface ')) return false;\n return true;\n}\n\nfunction validateFakeSuccess(line: string, filePath: string): boolean {\n const ll = line.toLowerCase();\n // Skip test assertions\n if (ll.includes('expect(') || ll.includes('assert')) return false;\n // Skip test files\n if (filePath.includes('.test.') || filePath.includes('.spec.')) return false;\n return true;\n}\n\n// ============================================================================\n// Engine\n// ============================================================================\n\nexport const fakeFeaturesEngine: ScanEngine = {\n name: 'fake-features',\n description: 'Detects stubs, fake success, silent failures, auth bypasses, placeholders',\n\n async scan(files: Map<string, FileContext>, options: ScanOptions): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n for (const [, file] of files) {\n if (file.classification.category === 'test' && !options.includeTests) continue;\n if (file.classification.category === 'documentation') continue;\n\n const isCritical = file.classification.isCriticalPath;\n\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n const trimmed = line.trim();\n\n // ── Placeholders ──\n if (!isCommentLine(trimmed) || /\\b(?:TODO|FIXME|WIP|TBD)\\b/i.test(trimmed)) {\n if (!isDocContext(file.path, trimmed)) {\n for (const pattern of PLACEHOLDER_PATTERNS) {\n if (pattern.test(line) && validatePlaceholder(line, file.path)) {\n findings.push(makeFinding('FAKE004', file, i, trimmed, 'placeholder', 'medium', 65, isCritical));\n break;\n }\n }\n }\n }\n\n // Skip comments for remaining checks\n if (isCommentLine(trimmed)) continue;\n\n // ── Fake Success ──\n const inErrorCtx = isInErrorContext(file.lines, i);\n for (const pattern of FAKE_SUCCESS_PATTERNS) {\n if (pattern.test(line) && validateFakeSuccess(line, file.path)) {\n const sev = inErrorCtx ? 'high' : 'medium';\n findings.push(makeFinding('FAKE002', file, i, trimmed, 'fake-success', sev, inErrorCtx ? 80 : 65, isCritical));\n break;\n }\n }\n\n // ── Silent Failures ──\n for (const pattern of SILENT_FAILURE_PATTERNS) {\n if (pattern.test(line)) {\n // Don't flag in finally blocks\n if (line.toLowerCase().includes('finally')) continue;\n findings.push(makeFinding('FAKE003', file, i, trimmed, 'silent-failure', 'high', 85, isCritical));\n break;\n }\n }\n\n // ── Auth Bypass ──\n for (const pattern of AUTH_BYPASS_PATTERNS) {\n if (pattern.test(line)) {\n // Skip config/env files\n if (file.path.includes('.config.') || file.path.includes('.env')) continue;\n findings.push(makeFinding('FAKE005', file, i, trimmed, 'auth-bypass', 'critical', 88, isCritical));\n break;\n }\n }\n\n // ── Dangerous Defaults ──\n for (const pattern of DANGEROUS_DEFAULT_PATTERNS) {\n if (pattern.test(line)) {\n if (file.path.includes('.example') || file.path.includes('.template')) continue;\n if (file.path.includes('.env.sample')) continue;\n findings.push(makeFinding('FAKE006', file, i, trimmed, 'dangerous-default', 'high', 82, isCritical));\n break;\n }\n }\n\n // ── Empty Functions ──\n for (const pattern of EMPTY_FUNCTION_PATTERNS) {\n if (pattern.test(line)) {\n // Skip intentional noop patterns (event handler stubs, interface implementations)\n if (/noop|passthrough|abstract|interface|override/i.test(line)) continue;\n findings.push(makeFinding('FAKE001', file, i, trimmed, 'empty-function', 'high', 75, isCritical));\n break;\n }\n }\n }\n }\n\n return findings;\n },\n};\n\nfunction makeFinding(\n ruleId: string,\n file: FileContext,\n lineIndex: number,\n code: string,\n tag: string,\n severity: 'critical' | 'high' | 'medium' | 'low',\n confidence: number,\n isCritical: boolean,\n): Finding {\n const rule = getRuleOrDefault(ruleId);\n const finalSeverity = escalateSeverity(severity, isCritical);\n return {\n id: `${ruleId}-${file.path}-${lineIndex + 1}`,\n ruleId,\n engine: 'fake-features',\n category: 'fake-features',\n severity: finalSeverity,\n confidence: confidence >= 85 ? 'certain' : confidence >= 65 ? 'likely' : 'possible',\n confidenceScore: confidence,\n file: file.path,\n line: lineIndex + 1,\n code,\n message: rule.description,\n why: rule.why,\n fix: rule.fix,\n autoFixable: rule.autoFixable,\n tags: [...rule.tags, tag],\n verified: false,\n _dedup: `${ruleId}:${file.path}:${lineIndex + 1}`,\n };\n}\n","/**\n * Hallucinations Engine\n * \n * Detects AI-hallucinated code: fake npm packages, invented API methods,\n * placeholder URLs, ghost routes, ghost env vars, invented config options.\n * \n * Sources: CORE UltimateScanner (13 hallucination patterns), CORE Firewall ghost-route/ghost-env rules\n */\n\nimport type { Finding, FileContext, ScanOptions, ScanEngine } from '../types/index.js';\nimport { getRuleOrDefault } from '../rules/catalog.js';\nimport { escalateSeverity } from '../classifiers/path-classifier.js';\n\ninterface HalPattern {\n name: string;\n ruleId: string;\n regex: RegExp;\n severity: 'critical' | 'high' | 'medium' | 'low';\n message: string;\n fix: string;\n confidence: number;\n excludeInTests: boolean;\n validate?: (line: string, file: FileContext) => boolean;\n}\n\nconst PATTERNS: HalPattern[] = [\n // ── Fake npm packages (known hallucinated package names) ──\n {\n name: 'fake-npm-react-auth',\n ruleId: 'HAL001',\n regex: /from\\s+['\"](?:react-auth-provider|react-secure-auth|next-auth-helpers|react-auth-kit-v2)['\"]|require\\s*\\(\\s*['\"](?:react-auth-provider|react-secure-auth|next-auth-helpers)['\"]/, \n severity: 'critical',\n message: 'Import from frequently hallucinated npm package',\n fix: 'Verify package exists on npmjs.com. AI often invents auth/utility packages.',\n confidence: 88,\n excludeInTests: false,\n },\n {\n name: 'fake-npm-util',\n ruleId: 'HAL001',\n regex: /from\\s+['\"](?:string-utils-pro|array-helpers-ts|object-deep-merge|config-loader-pro|api-response-handler)['\"]|require\\s*\\(\\s*['\"](?:string-utils-pro|array-helpers-ts|object-deep-merge)['\"]/, \n severity: 'critical',\n message: 'Import from frequently hallucinated npm package',\n fix: 'Check npmjs.com. These utility package names are commonly invented by AI.',\n confidence: 85,\n excludeInTests: false,\n },\n\n // ── Placeholder URLs ──\n {\n name: 'placeholder-url',\n ruleId: 'HAL003',\n regex: /['\"`]https?:\\/\\/(?:api\\.)?example\\.com[^'\"`]*['\"`]/i,\n severity: 'high',\n message: 'Placeholder URL (example.com) in source code',\n fix: 'Replace with actual API endpoint from environment variable.',\n confidence: 92,\n excludeInTests: true,\n },\n {\n name: 'placeholder-url-yoursite',\n ruleId: 'HAL003',\n regex: /['\"`]https?:\\/\\/(?:your-?(?:site|app|domain|api)|my-?(?:api|app|site))\\.[a-z]+[^'\"`]*['\"`]/i,\n severity: 'high',\n message: 'Placeholder URL (your-site/my-api) — AI-generated placeholder',\n fix: 'Replace with actual URL from environment variable.',\n confidence: 95,\n excludeInTests: true,\n },\n {\n name: 'placeholder-url-todo',\n ruleId: 'HAL003',\n regex: /['\"`]https?:\\/\\/(?:todo|fixme|placeholder|changeme)\\.[a-z]+[^'\"`]*['\"`]/i,\n severity: 'high',\n message: 'Placeholder URL with marker keyword',\n fix: 'Replace with actual URL.',\n confidence: 98,\n excludeInTests: true,\n },\n {\n name: 'localhost-in-prod',\n ruleId: 'HAL003',\n regex: /(?:API_URL|BASE_URL|BACKEND_URL|SERVER_URL)\\s*[=:]\\s*['\"`]https?:\\/\\/localhost/i,\n severity: 'high',\n message: 'Localhost URL in production configuration',\n fix: 'Use environment variable: process.env.API_URL',\n confidence: 80,\n excludeInTests: true,\n validate: (line, file) => !file.path.includes('.env') && !file.path.includes('.local'),\n },\n\n // ── Invented API methods ──\n {\n name: 'prisma-hallucinated',\n ruleId: 'HAL002',\n regex: /prisma\\.\\w+\\.(?:getAll|fetchAll|search|getOne|fetchOne|removeAll|updateAll|createOrUpdate|findFirst|getById)\\s*\\(/,\n severity: 'high',\n message: 'Possible hallucinated Prisma method — verify against Prisma docs',\n fix: 'Prisma uses findMany, findUnique, create, update, delete, upsert. Check docs.',\n confidence: 65,\n excludeInTests: true,\n validate: (line) => {\n // findFirst is actually valid in Prisma\n if (line.includes('findFirst')) return false;\n return true;\n },\n },\n {\n name: 'express-hallucinated',\n ruleId: 'HAL002',\n regex: /(?:app|router)\\.(?:handle|serve|mount|listen)\\s*\\(\\s*['\"]\\/\\w/,\n severity: 'medium',\n message: 'Possible hallucinated Express method — verify against Express docs',\n fix: 'Express uses .get(), .post(), .put(), .delete(), .use(), .all(). Check docs.',\n confidence: 60,\n excludeInTests: true,\n },\n\n // ── Invented config options ──\n {\n name: 'next-config-hallucinated',\n ruleId: 'HAL004',\n regex: /(?:next\\.config|nextConfig)\\s*(?:=|\\.)\\s*\\{[^}]*(?:enableSSR|enableCSR|autoOptimize|smartBundling|lazyHydration|autoCache)/,\n severity: 'medium',\n message: 'Possible hallucinated Next.js config option',\n fix: 'Check next.config.js docs for valid options.',\n confidence: 70,\n excludeInTests: true,\n },\n\n // ── Fake test data in production ──\n {\n name: 'test-email-prod',\n ruleId: 'HAL003',\n regex: /['\"`](?:test|user|admin|john|jane|foo|bar)@(?:test|example|fake|dummy|placeholder)\\.\\w+['\"`]/i,\n severity: 'medium',\n message: 'Test/fake email address in production code',\n fix: 'Replace with actual user data or remove.',\n confidence: 78,\n excludeInTests: true,\n },\n {\n name: 'test-phone-prod',\n ruleId: 'HAL003',\n regex: /['\"`]\\+?1?[-.\\s]?\\(?(?:555|000|123)\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}['\"`]/,\n severity: 'medium',\n message: 'Fake phone number (555/000/123 prefix) in production code',\n fix: 'Replace with actual data or remove.',\n confidence: 82,\n excludeInTests: true,\n },\n\n // ── Lorem ipsum ──\n {\n name: 'lorem-ipsum',\n ruleId: 'HAL003',\n regex: /lorem\\s+ipsum/i,\n severity: 'medium',\n message: 'Lorem ipsum placeholder text in production code',\n fix: 'Replace with actual content.',\n confidence: 95,\n excludeInTests: true,\n },\n];\n\n// ============================================================================\n// Engine\n// ============================================================================\n\nexport const hallucinationsEngine: ScanEngine = {\n name: 'hallucinations',\n description: 'Detects AI-hallucinated code: fake packages, invented methods, placeholder URLs',\n\n async scan(files: Map<string, FileContext>, options: ScanOptions): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n for (const [, file] of files) {\n const isTest = file.classification.category === 'test';\n const isCritical = file.classification.isCriticalPath;\n\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n const trimmed = line.trim();\n\n if (trimmed.startsWith('//') || trimmed.startsWith('*')) continue;\n\n for (const pattern of PATTERNS) {\n if (isTest && pattern.excludeInTests) continue;\n\n const match = line.match(pattern.regex);\n if (!match) continue;\n\n if (pattern.validate && !pattern.validate(line, file)) continue;\n\n const rule = getRuleOrDefault(pattern.ruleId);\n const severity = escalateSeverity(pattern.severity, isCritical);\n\n findings.push({\n id: `${pattern.ruleId}-${file.path}-${i + 1}`,\n ruleId: pattern.ruleId,\n engine: 'hallucinations',\n category: 'hallucinations',\n severity,\n confidence: pattern.confidence >= 85 ? 'certain' : pattern.confidence >= 65 ? 'likely' : 'possible',\n confidenceScore: pattern.confidence,\n file: file.path,\n line: i + 1,\n column: match.index,\n code: trimmed,\n message: pattern.message,\n why: rule.why,\n fix: pattern.fix,\n autoFixable: false,\n tags: [...rule.tags],\n verified: false,\n _dedup: `${pattern.name}:${file.path}:${i + 1}`,\n });\n }\n }\n }\n\n return findings;\n },\n};\n","/**\n * Dead UI Engine\n * \n * Detects dead links, noop handlers, \"coming soon\" UI, disabled without reason,\n * and raw fetch calls in components.\n * \n * Source: CLI5 DeadUIDetector (complete with legitimate-context filtering)\n */\n\nimport type { Finding, FileContext, ScanOptions, ScanEngine } from '../types/index.js';\nimport { getRuleOrDefault } from '../rules/catalog.js';\nimport { isUIFile } from '../classifiers/path-classifier.js';\n\n// Legitimate context patterns (from CLI5 — key to FP reduction)\nconst LEGIT_HASH_LINK = [/aria-controls=/i, /role=[\"']tab[\"']/i, /role=[\"']button[\"']/i, /data-toggle=/i, /data-bs-toggle=/i, /onClick\\s*=\\s*\\{[^}]+\\}/, /tabIndex=/i];\nconst LEGIT_NOOP = [/disabled/i, /aria-disabled/i, /loading/i, /pending/i, /isLoading/i, /stopPropagation/i, /preventDefault/i];\nconst LEGIT_COMING_SOON = [/changelog/i, /readme/i, /roadmap/i, /\\/\\//, /\\/\\*/, /translation/i, /i18n/i, /t\\(['\"`]/i];\nconst LEGIT_DISABLED = [/aria-disabled/i, /isDisabled/i, /isLoading/i, /disabled=\\{/i, /&&\\s*disabled/i, /\\?\\s*disabled/i];\nconst LEGIT_FETCH = [/useQuery/i, /useMutation/i, /useSWR/i, /createApi/i, /trpc/i, /\\.server\\./i, /route\\.ts$/i, /api\\/.*\\.ts$/i];\n\nfunction hasContext(line: string, patterns: RegExp[]): boolean {\n return patterns.some(p => p.test(line));\n}\n\nexport const deadUIEngine: ScanEngine = {\n name: 'dead-ui',\n description: 'Detects dead links, noop handlers, coming soon UI, disabled without reason',\n\n async scan(files: Map<string, FileContext>, options: ScanOptions): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n for (const [, file] of files) {\n if (!isUIFile(file.path)) continue;\n if (file.classification.category === 'test' && !options.includeTests) continue;\n if (file.classification.category === 'documentation') continue;\n\n const isApiFile = /\\/api\\/|\\/routes\\/|\\.server\\./.test(file.path.toLowerCase());\n\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n const trimmed = line.trim();\n\n // Dead links\n if (/href=[\"']#[\"']|href=[\"']javascript:void\\(0\\)[\"']/g.test(line)) {\n if (!hasContext(line, LEGIT_HASH_LINK)) {\n findings.push(make('UI001', file, i, trimmed, 'high', 88));\n }\n }\n\n // Noop handlers\n if (/onClick\\s*=\\s*\\{\\s*\\(\\)\\s*=>\\s*\\{\\s*\\}\\s*\\}/.test(line)) {\n if (!hasContext(line, LEGIT_NOOP)) {\n findings.push(make('UI002', file, i, trimmed, 'high', 90));\n }\n }\n\n // Coming soon\n if (/coming\\s+soon|under\\s+construction|not\\s+available|work\\s+in\\s+progress/gi.test(line)) {\n if (!hasContext(line, LEGIT_COMING_SOON) && !trimmed.startsWith('//') && !trimmed.startsWith('*')) {\n findings.push(make('UI003', file, i, trimmed, 'medium', 72));\n }\n }\n\n // Disabled without reason\n if (line.includes('disabled') && !/tooltip|aria-label|aria-describedby|title|reason/i.test(line)) {\n if (!hasContext(line, LEGIT_DISABLED) && !/disabled=\\{[^}]*\\}/.test(line)) {\n findings.push(make('UI004', file, i, trimmed, 'medium', 68));\n }\n }\n\n // Raw fetch in components\n if (!isApiFile && /fetch\\s*\\(\\s*[\"'`]\\/api\\//.test(line)) {\n if (!hasContext(line, LEGIT_FETCH)) {\n findings.push(make('UI005', file, i, trimmed, 'low', 60));\n }\n }\n }\n }\n\n return findings;\n },\n};\n\nfunction make(ruleId: string, file: FileContext, lineIdx: number, code: string, severity: Finding['severity'], confidence: number): Finding {\n const rule = getRuleOrDefault(ruleId);\n return {\n id: `${ruleId}-${file.path}-${lineIdx + 1}`,\n ruleId,\n engine: 'dead-ui',\n category: 'dead-ui',\n severity,\n confidence: confidence >= 85 ? 'certain' : confidence >= 65 ? 'likely' : 'possible',\n confidenceScore: confidence,\n file: file.path,\n line: lineIdx + 1,\n code,\n message: rule.description,\n why: rule.why,\n fix: rule.fix,\n autoFixable: false,\n tags: rule.tags,\n verified: false,\n _dedup: `${ruleId}:${file.path}:${lineIdx + 1}`,\n };\n}\n","/**\n * Code Quality Engine\n * \n * Detects debug code, type safety issues, mock data in prod, and quality anti-patterns.\n * \n * Sources: CORE CodeQualityScanner (58 patterns), CORE UltimateScanner code-quality patterns\n */\n\nimport type { Finding, FileContext, ScanOptions, ScanEngine } from '../types/index.js';\nimport { getRuleOrDefault } from '../rules/catalog.js';\n\ninterface QualityPattern {\n name: string;\n ruleId: string;\n regex: RegExp;\n severity: 'critical' | 'high' | 'medium' | 'low';\n message: string;\n fix: string;\n confidence: number;\n excludeInTests: boolean;\n autoFixable: boolean;\n}\n\nconst PATTERNS: QualityPattern[] = [\n // ── Debug Code ──\n {\n name: 'console-log',\n ruleId: 'QLT001',\n regex: /\\bconsole\\.log\\s*\\(/,\n severity: 'medium',\n message: 'console.log() in production code',\n fix: 'Remove or replace with proper logger (winston, pino)',\n confidence: 92,\n excludeInTests: true,\n autoFixable: true,\n },\n {\n name: 'console-debug',\n ruleId: 'QLT001',\n regex: /\\bconsole\\.debug\\s*\\(/,\n severity: 'medium',\n message: 'console.debug() in production code',\n fix: 'Remove or replace with proper logger',\n confidence: 92,\n excludeInTests: true,\n autoFixable: true,\n },\n {\n name: 'console-trace',\n ruleId: 'QLT001',\n regex: /\\bconsole\\.trace\\s*\\(/,\n severity: 'medium',\n message: 'console.trace() in production code',\n fix: 'Remove or use proper debugging tools',\n confidence: 92,\n excludeInTests: true,\n autoFixable: true,\n },\n {\n name: 'debugger',\n ruleId: 'QLT002',\n regex: /\\bdebugger\\b\\s*;?/,\n severity: 'high',\n message: 'debugger statement left in code',\n fix: 'Remove the debugger statement',\n confidence: 98,\n excludeInTests: true,\n autoFixable: true,\n },\n {\n name: 'alert-call',\n ruleId: 'QLT001',\n regex: /\\balert\\s*\\(\\s*['\"`]/,\n severity: 'medium',\n message: 'alert() call in production code',\n fix: 'Use a proper notification/toast component',\n confidence: 85,\n excludeInTests: true,\n autoFixable: false,\n },\n\n // ── Type Safety ──\n {\n name: 'as-any',\n ruleId: 'QLT005',\n regex: /\\bas\\s+any\\b/,\n severity: 'medium',\n message: '\"as any\" bypasses TypeScript safety',\n fix: 'Fix the type properly. Use type guards or generics.',\n confidence: 88,\n excludeInTests: true,\n autoFixable: false,\n },\n {\n name: 'ts-ignore',\n ruleId: 'QLT005',\n regex: /@ts-ignore(?!\\s*\\()/,\n severity: 'medium',\n message: '@ts-ignore suppresses type errors without explanation',\n fix: 'Use @ts-expect-error with explanation, or fix the type.',\n confidence: 90,\n excludeInTests: true,\n autoFixable: false,\n },\n {\n name: 'any-type-annotation',\n ruleId: 'QLT005',\n regex: /:\\s*any\\b(?!\\s*\\[\\])/,\n severity: 'low',\n message: 'Explicit \"any\" type annotation',\n fix: 'Use a proper type. Use unknown for truly dynamic values.',\n confidence: 75,\n excludeInTests: true,\n autoFixable: false,\n },\n\n // ── Mock Data in Production ──\n {\n name: 'mock-data-array',\n ruleId: 'QLT003',\n regex: /(?:const|let|var)\\s+(?:mock|fake|dummy|sample|test)(?:Data|Users?|Items?|Products?|Orders?)\\s*[=:]/i,\n severity: 'high',\n message: 'Mock/fake data variable in production code',\n fix: 'Connect to actual data source. Move mock data to test files.',\n confidence: 80,\n excludeInTests: true,\n autoFixable: false,\n },\n {\n name: 'hardcoded-user',\n ruleId: 'QLT003',\n regex: /(?:name|email|username)\\s*:\\s*['\"`](?:John\\s*Doe|Jane\\s*Doe|Test\\s*User|Admin\\s*User|user@example\\.com)['\"`]/i,\n severity: 'high',\n message: 'Hardcoded fake user data in production code',\n fix: 'Replace with actual user data from database/auth.',\n confidence: 85,\n excludeInTests: true,\n autoFixable: false,\n },\n {\n name: 'hardcoded-price',\n ruleId: 'QLT003',\n regex: /(?:price|amount|cost)\\s*:\\s*(?:9\\.99|19\\.99|29\\.99|49\\.99|99\\.99|0\\.00)\\b/i,\n severity: 'medium',\n message: 'Hardcoded price/amount — likely mock data',\n fix: 'Fetch pricing from database/config.',\n confidence: 72,\n excludeInTests: true,\n autoFixable: false,\n },\n\n // ── Error Handling Smells ──\n {\n name: 'throw-string',\n ruleId: 'QLT001',\n regex: /throw\\s+['\"`][^'\"`]+['\"`]/,\n severity: 'medium',\n message: 'Throwing a string instead of an Error object',\n fix: 'Throw an Error: throw new Error(\"message\")',\n confidence: 92,\n excludeInTests: true,\n autoFixable: true,\n },\n {\n name: 'promise-no-catch',\n ruleId: 'QLT001',\n regex: /\\.then\\s*\\([^)]*\\)\\s*(?:$|;|\\n)(?!.*\\.catch)/,\n severity: 'medium',\n message: 'Promise chain without .catch() — unhandled rejection risk',\n fix: 'Add .catch() handler or use async/await with try/catch.',\n confidence: 68,\n excludeInTests: true,\n autoFixable: false,\n },\n\n // ── Dead Code Indicators ──\n {\n name: 'unreachable-code',\n ruleId: 'QLT004',\n regex: /^\\s*(?:const|let|var|function|class|return|throw)\\b.*$/,\n severity: 'low',\n message: 'Potentially unreachable code after return/throw',\n fix: 'Remove dead code.',\n confidence: 45,\n excludeInTests: true,\n autoFixable: true,\n },\n\n // ── Performance ──\n {\n name: 'sync-fs-in-handler',\n ruleId: 'QLT001',\n regex: /(?:readFileSync|writeFileSync|existsSync|readdirSync|statSync)\\s*\\(/,\n severity: 'medium',\n message: 'Synchronous file operation — blocks event loop',\n fix: 'Use async version: fs.promises.readFile() or fs.readFile()',\n confidence: 70,\n excludeInTests: true,\n autoFixable: false,\n },\n];\n\n// ============================================================================\n// Engine\n// ============================================================================\n\nexport const codeQualityEngine: ScanEngine = {\n name: 'code-quality',\n description: 'Detects debug code, type safety issues, mock data, and quality anti-patterns',\n\n async scan(files: Map<string, FileContext>, options: ScanOptions): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n for (const [, file] of files) {\n const isTest = file.classification.category === 'test';\n\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n const trimmed = line.trim();\n\n // Skip comments\n if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*')) continue;\n\n for (const pattern of PATTERNS) {\n if (isTest && pattern.excludeInTests) continue;\n\n const match = line.match(pattern.regex);\n if (!match) continue;\n\n // Special validation for unreachable code\n if (pattern.name === 'unreachable-code') {\n if (i === 0 || !/\\b(?:return|throw)\\b/.test(file.lines[i - 1])) continue;\n }\n\n const rule = getRuleOrDefault(pattern.ruleId);\n\n findings.push({\n id: `${pattern.ruleId}-${file.path}-${i + 1}`,\n ruleId: pattern.ruleId,\n engine: 'code-quality',\n category: 'code-quality',\n severity: pattern.severity,\n confidence: pattern.confidence >= 85 ? 'certain' : pattern.confidence >= 65 ? 'likely' : 'possible',\n confidenceScore: pattern.confidence,\n file: file.path,\n line: i + 1,\n column: match.index,\n code: trimmed,\n message: pattern.message,\n why: rule.why,\n fix: pattern.fix,\n autoFixable: pattern.autoFixable,\n tags: rule.tags,\n verified: false,\n _dedup: `${pattern.name}:${file.path}:${i + 1}`,\n });\n }\n }\n }\n\n return findings;\n },\n};\n","/**\n * Import Graph Engine\n * \n * Builds a cross-file import graph and detects:\n * - IG001: Circular dependencies\n * - IG002: Orphan modules (never imported)\n * - IG003: Ghost routes (frontend fetches API routes that don't exist)\n * - IG004: Ghost env variables (process.env.X not in .env files)\n * - IG005: Barrel re-export bloat\n * \n * This engine requires the full file map to perform cross-file analysis.\n */\n\nimport type { Finding, FileContext, ScanOptions, ScanEngine } from '../types/index.js';\nimport { getRuleOrDefault } from '../rules/catalog.js';\nimport { existsSync, readFileSync } from 'fs';\nimport { join, dirname, resolve } from 'path';\n\n// ============================================================================\n// Import Graph Builder\n// ============================================================================\n\ninterface ImportEdge {\n from: string;\n to: string;\n specifier: string;\n line: number;\n}\n\n/**\n * Extract import/require specifiers from file content.\n */\nfunction extractImports(file: FileContext): ImportEdge[] {\n const edges: ImportEdge[] = [];\n const importRegex = /(?:import\\s+(?:[\\s\\S]*?)\\s+from\\s+['\"]([^'\"]+)['\"]|import\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)|require\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\))/g;\n\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n let match;\n importRegex.lastIndex = 0;\n\n // Reset per-line since we use global regex\n const lineRegex = /(?:import\\s+(?:[\\s\\S]*?)\\s+from\\s+['\"]([^'\"]+)['\"]|import\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)|require\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\))/g;\n while ((match = lineRegex.exec(line)) !== null) {\n const specifier = match[1] || match[2] || match[3];\n if (specifier) {\n edges.push({\n from: file.path,\n to: specifier,\n specifier,\n line: i + 1,\n });\n }\n }\n }\n\n return edges;\n}\n\n/**\n * Resolve a relative import specifier to a file path in the file map.\n */\nfunction resolveImport(from: string, specifier: string, fileMap: Map<string, FileContext>): string | null {\n // Skip node_modules / bare specifiers\n if (!specifier.startsWith('.') && !specifier.startsWith('/')) return null;\n\n const fromDir = dirname(from);\n const resolved = join(fromDir, specifier).replace(/\\\\/g, '/');\n\n // Try exact match, then with extensions\n const extensions = ['', '.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx', '/index.js'];\n for (const ext of extensions) {\n const candidate = resolved + ext;\n // Normalize for map lookup\n const normalized = candidate.replace(/\\\\/g, '/');\n if (fileMap.has(normalized)) return normalized;\n // Try with backslashes too (Windows)\n const winNormalized = candidate.replace(/\\//g, '\\\\');\n if (fileMap.has(winNormalized)) return winNormalized;\n }\n\n // Try without leading ./\n for (const ext of extensions) {\n const candidate = (resolved.startsWith('./') ? resolved.slice(2) : resolved) + ext;\n if (fileMap.has(candidate)) return candidate;\n }\n\n return null;\n}\n\n/**\n * Detect circular dependencies using DFS.\n */\nfunction findCircularDeps(adjacency: Map<string, string[]>): string[][] {\n const cycles: string[][] = [];\n const visited = new Set<string>();\n const inStack = new Set<string>();\n const path: string[] = [];\n\n function dfs(node: string): void {\n if (inStack.has(node)) {\n // Found a cycle — extract it\n const cycleStart = path.indexOf(node);\n if (cycleStart >= 0) {\n cycles.push(path.slice(cycleStart).concat(node));\n }\n return;\n }\n if (visited.has(node)) return;\n\n visited.add(node);\n inStack.add(node);\n path.push(node);\n\n for (const neighbor of adjacency.get(node) ?? []) {\n dfs(neighbor);\n }\n\n path.pop();\n inStack.delete(node);\n }\n\n for (const node of adjacency.keys()) {\n dfs(node);\n }\n\n return cycles;\n}\n\n/**\n * Extract fetch/axios API route patterns from file content.\n */\nfunction extractFetchRoutes(file: FileContext): { route: string; line: number }[] {\n const routes: { route: string; line: number }[] = [];\n const fetchRegex = /(?:fetch|axios\\.(?:get|post|put|patch|delete)|\\.get|\\.post|\\.put|\\.patch|\\.delete)\\s*\\(\\s*[`'\"](\\/api\\/[^`'\"]*)[`'\"]/g;\n\n for (let i = 0; i < file.lines.length; i++) {\n let match;\n fetchRegex.lastIndex = 0;\n while ((match = fetchRegex.exec(file.lines[i])) !== null) {\n routes.push({ route: match[1], line: i + 1 });\n }\n }\n return routes;\n}\n\n/**\n * Extract API route handlers defined in code.\n */\nfunction extractRouteHandlers(file: FileContext): string[] {\n const handlers: string[] = [];\n const handlerRegex = /(?:app|router|server)\\s*\\.\\s*(?:get|post|put|patch|delete|all)\\s*\\(\\s*[`'\"](\\/api\\/[^`'\"]*)[`'\"]/g;\n\n for (const line of file.lines) {\n let match;\n handlerRegex.lastIndex = 0;\n while ((match = handlerRegex.exec(line)) !== null) {\n handlers.push(match[1]);\n }\n }\n\n // Also detect Next.js/Remix route files\n const normalized = file.path.replace(/\\\\/g, '/');\n if (normalized.includes('/api/') || normalized.includes('/routes/')) {\n // Extract route from file path (e.g., pages/api/users.ts → /api/users)\n const apiMatch = normalized.match(/(?:pages|app)(\\/api\\/[^.]+)/);\n if (apiMatch) {\n handlers.push(apiMatch[1].replace(/\\/route$/, '').replace(/\\/index$/, ''));\n }\n }\n\n return handlers;\n}\n\n/**\n * Extract process.env.X references.\n */\nfunction extractEnvRefs(file: FileContext): { name: string; line: number }[] {\n const refs: { name: string; line: number }[] = [];\n const envRegex = /process\\.env\\.([A-Z_][A-Z0-9_]*)/g;\n\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n // Skip comments\n if (line.trim().startsWith('//') || line.trim().startsWith('*')) continue;\n\n let match;\n envRegex.lastIndex = 0;\n while ((match = envRegex.exec(line)) !== null) {\n refs.push({ name: match[1], line: i + 1 });\n }\n }\n return refs;\n}\n\n/**\n * Load env vars from .env files.\n */\nfunction loadEnvVars(projectRoot: string): Set<string> {\n const vars = new Set<string>();\n const envFiles = ['.env', '.env.local', '.env.development', '.env.production', '.env.example'];\n\n for (const envFile of envFiles) {\n const envPath = join(projectRoot, envFile);\n try {\n if (existsSync(envPath)) {\n const content = readFileSync(envPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const match = line.match(/^\\s*([A-Z_][A-Z0-9_]*)\\s*=/);\n if (match) vars.add(match[1]);\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n // Also add common well-known env vars that are always available\n const builtins = ['NODE_ENV', 'PORT', 'HOME', 'PATH', 'PWD', 'USER', 'SHELL', 'TERM', 'LANG',\n 'CI', 'GITHUB_ACTIONS', 'VERCEL', 'NETLIFY', 'HEROKU', 'npm_package_version'];\n for (const b of builtins) vars.add(b);\n\n return vars;\n}\n\n/**\n * Detect barrel files with excessive re-exports.\n */\nfunction isBarrelFile(file: FileContext): { isBarrel: boolean; reExportCount: number } {\n if (!file.path.endsWith('index.ts') && !file.path.endsWith('index.js')) {\n return { isBarrel: false, reExportCount: 0 };\n }\n\n let reExportCount = 0;\n for (const line of file.lines) {\n if (/^export\\s+\\*\\s+from\\s+/.test(line.trim()) || /^export\\s+\\{[^}]+\\}\\s+from\\s+/.test(line.trim())) {\n reExportCount++;\n }\n }\n\n return { isBarrel: reExportCount >= 5, reExportCount };\n}\n\n// ============================================================================\n// Engine\n// ============================================================================\n\nexport const importGraphEngine: ScanEngine = {\n name: 'import-graph',\n description: 'Cross-file import graph analysis: circular deps, orphans, ghost routes, ghost env vars',\n\n async scan(files: Map<string, FileContext>, options: ScanOptions): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n // 1. Build import graph\n const adjacency = new Map<string, string[]>();\n const allImported = new Set<string>();\n const allEdges: ImportEdge[] = [];\n\n for (const [path, file] of files) {\n const edges = extractImports(file);\n const resolved: string[] = [];\n\n for (const edge of edges) {\n const target = resolveImport(path, edge.specifier, files);\n if (target) {\n resolved.push(target);\n allImported.add(target);\n allEdges.push({ ...edge, to: target });\n }\n }\n\n adjacency.set(path, resolved);\n }\n\n // 2. Detect circular dependencies (IG001)\n const cycles = findCircularDeps(adjacency);\n const reportedCycles = new Set<string>();\n\n for (const cycle of cycles) {\n // Deduplicate cycles (same cycle can be found starting from different nodes)\n const cycleKey = [...cycle].sort().join('→');\n if (reportedCycles.has(cycleKey)) continue;\n reportedCycles.add(cycleKey);\n\n const file = files.get(cycle[0]);\n if (!file) continue;\n\n const rule = getRuleOrDefault('IG001');\n const cyclePath = cycle.map(p => p.split('/').pop()).join(' → ');\n\n findings.push({\n id: `IG001-${cycle[0]}-cycle`,\n ruleId: 'IG001',\n engine: 'import-graph',\n category: 'import-graph',\n severity: 'high',\n confidence: 'certain',\n confidenceScore: 95,\n file: cycle[0],\n line: 1,\n code: `Circular: ${cyclePath}`,\n message: `Circular dependency chain: ${cyclePath}`,\n why: rule.why,\n fix: rule.fix,\n autoFixable: false,\n tags: rule.tags,\n verified: false,\n _dedup: `IG001:${cycleKey}`,\n });\n }\n\n // 3. Detect orphan modules (IG002)\n const entryPatterns = /(?:index|main|app|server|cli|entry)\\.[tj]sx?$/;\n for (const [path, file] of files) {\n // Skip entry points, config files, and test files\n if (entryPatterns.test(path)) continue;\n if (file.classification.category === 'test') continue;\n if (file.classification.category === 'config') continue;\n if (path.includes('.config.')) continue;\n if (path.includes('.d.ts')) continue;\n\n if (!allImported.has(path)) {\n const rule = getRuleOrDefault('IG002');\n findings.push({\n id: `IG002-${path}`,\n ruleId: 'IG002',\n engine: 'import-graph',\n category: 'import-graph',\n severity: 'medium',\n confidence: 'likely',\n confidenceScore: 75,\n file: path,\n line: 1,\n code: path,\n message: `Orphan module: ${path.split(/[/\\\\]/).pop()} is never imported`,\n why: rule.why,\n fix: rule.fix,\n autoFixable: false,\n tags: rule.tags,\n verified: false,\n _dedup: `IG002:${path}`,\n });\n }\n }\n\n // 4. Detect ghost routes (IG003)\n const allFetchedRoutes: { route: string; file: string; line: number }[] = [];\n const allHandlerRoutes = new Set<string>();\n\n for (const [, file] of files) {\n const fetched = extractFetchRoutes(file);\n for (const f of fetched) {\n allFetchedRoutes.push({ ...f, file: file.path });\n }\n const handlers = extractRouteHandlers(file);\n for (const h of handlers) {\n allHandlerRoutes.add(h);\n }\n }\n\n for (const fetchedRoute of allFetchedRoutes) {\n // Normalize route for comparison (strip trailing slash, parameters)\n const normalized = fetchedRoute.route.replace(/\\/$/g, '').replace(/\\/:[^/]+/g, '/[param]');\n const hasHandler = [...allHandlerRoutes].some(handler => {\n const normHandler = handler.replace(/\\/$/g, '').replace(/\\/:[^/]+/g, '/[param]');\n return normHandler === normalized || normalized.startsWith(normHandler);\n });\n\n if (!hasHandler && allHandlerRoutes.size > 0) {\n const rule = getRuleOrDefault('IG003');\n findings.push({\n id: `IG003-${fetchedRoute.file}-${fetchedRoute.line}`,\n ruleId: 'IG003',\n engine: 'import-graph',\n category: 'import-graph',\n severity: 'high',\n confidence: 'likely',\n confidenceScore: 80,\n file: fetchedRoute.file,\n line: fetchedRoute.line,\n code: `fetch(\"${fetchedRoute.route}\")`,\n message: `Ghost route: ${fetchedRoute.route} has no matching backend handler`,\n why: rule.why,\n fix: rule.fix,\n autoFixable: false,\n tags: rule.tags,\n verified: false,\n _dedup: `IG003:${fetchedRoute.file}:${fetchedRoute.route}`,\n });\n }\n }\n\n // 5. Detect ghost env variables (IG004)\n const declaredEnvVars = loadEnvVars(options.projectRoot);\n const allEnvRefs: { name: string; file: string; line: number }[] = [];\n\n for (const [, file] of files) {\n const refs = extractEnvRefs(file);\n for (const ref of refs) {\n allEnvRefs.push({ ...ref, file: file.path });\n }\n }\n\n const reportedEnvVars = new Set<string>();\n for (const ref of allEnvRefs) {\n if (declaredEnvVars.has(ref.name)) continue;\n if (reportedEnvVars.has(ref.name)) continue;\n reportedEnvVars.add(ref.name);\n\n const rule = getRuleOrDefault('IG004');\n findings.push({\n id: `IG004-${ref.file}-${ref.line}`,\n ruleId: 'IG004',\n engine: 'import-graph',\n category: 'import-graph',\n severity: 'high',\n confidence: 'likely',\n confidenceScore: 82,\n file: ref.file,\n line: ref.line,\n code: `process.env.${ref.name}`,\n message: `Ghost env variable: ${ref.name} not found in any .env file`,\n why: rule.why,\n fix: rule.fix,\n autoFixable: true,\n tags: rule.tags,\n verified: false,\n _dedup: `IG004:${ref.name}`,\n });\n }\n\n // 6. Detect barrel re-export bloat (IG005)\n for (const [path, file] of files) {\n const { isBarrel, reExportCount } = isBarrelFile(file);\n if (isBarrel) {\n const rule = getRuleOrDefault('IG005');\n findings.push({\n id: `IG005-${path}`,\n ruleId: 'IG005',\n engine: 'import-graph',\n category: 'import-graph',\n severity: 'low',\n confidence: 'likely',\n confidenceScore: 78,\n file: path,\n line: 1,\n code: `${reExportCount} re-exports from index file`,\n message: `Barrel file with ${reExportCount} re-exports may defeat tree-shaking`,\n why: rule.why,\n fix: rule.fix,\n autoFixable: false,\n tags: rule.tags,\n verified: false,\n _dedup: `IG005:${path}`,\n });\n }\n }\n\n return findings;\n },\n};\n","/**\n * Runtime Verification Engine\n * \n * Static analysis that catches issues that would only surface at runtime:\n * - RV001: Unhandled promises (.then() without .catch(), await without try/catch)\n * - RV002: Async functions that never use await\n * - RV003: Dead exports (exported but never imported within the project)\n * - RV004: Floating promises (async call without await/.then()/void)\n * - RV005: Race condition risk (shared mutable state in async context)\n * \n * This is a pure static analysis engine — no browser or runtime needed.\n */\n\nimport type { Finding, FileContext, ScanOptions, ScanEngine } from '../types/index.js';\nimport { getRuleOrDefault } from '../rules/catalog.js';\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Find all exported symbol names from a file.\n */\nfunction extractExports(file: FileContext): { name: string; line: number }[] {\n const exports: { name: string; line: number }[] = [];\n const exportRegex = /export\\s+(?:async\\s+)?(?:function|const|let|var|class|enum|type|interface)\\s+([A-Za-z_$][A-Za-z0-9_$]*)/;\n\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n const match = line.match(exportRegex);\n if (match) {\n exports.push({ name: match[1], line: i + 1 });\n }\n // Also handle: export { foo, bar }\n const namedExport = line.match(/export\\s+\\{([^}]+)\\}/);\n if (namedExport) {\n const names = namedExport[1].split(',').map(n => n.trim().split(/\\s+as\\s+/)[0].trim());\n for (const name of names) {\n if (name && /^[A-Za-z_$]/.test(name)) {\n exports.push({ name, line: i + 1 });\n }\n }\n }\n }\n return exports;\n}\n\n/**\n * Find all imported symbol names from a file.\n */\nfunction extractImportedSymbols(file: FileContext): Set<string> {\n const symbols = new Set<string>();\n const importRegex = /import\\s+\\{([^}]+)\\}\\s+from/g;\n const defaultImportRegex = /import\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s+from/g;\n\n for (const line of file.lines) {\n let match;\n\n importRegex.lastIndex = 0;\n while ((match = importRegex.exec(line)) !== null) {\n const names = match[1].split(',').map(n => {\n const parts = n.trim().split(/\\s+as\\s+/);\n return parts[0].trim();\n });\n for (const name of names) {\n if (name) symbols.add(name);\n }\n }\n\n defaultImportRegex.lastIndex = 0;\n while ((match = defaultImportRegex.exec(line)) !== null) {\n symbols.add(match[1]);\n }\n }\n return symbols;\n}\n\n/**\n * Detect async functions and whether they contain await.\n */\ninterface AsyncFunctionInfo {\n name: string;\n startLine: number;\n hasAwait: boolean;\n endLine: number;\n}\n\nfunction findAsyncFunctions(file: FileContext): AsyncFunctionInfo[] {\n const functions: AsyncFunctionInfo[] = [];\n const asyncDeclRegex = /(?:export\\s+)?async\\s+function\\s+([A-Za-z_$][A-Za-z0-9_$]*)/;\n const asyncArrowRegex = /(?:export\\s+)?(?:const|let|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*=\\s*async/;\n\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n const declMatch = line.match(asyncDeclRegex);\n const arrowMatch = line.match(asyncArrowRegex);\n const match = declMatch || arrowMatch;\n\n if (match) {\n const name = match[1];\n const startLine = i + 1;\n\n // Find the end of the function by tracking braces\n let braceCount = 0;\n let hasAwait = false;\n let endLine = startLine;\n let started = false;\n\n for (let j = i; j < file.lines.length; j++) {\n const fLine = file.lines[j];\n for (const ch of fLine) {\n if (ch === '{') { braceCount++; started = true; }\n if (ch === '}') braceCount--;\n }\n if (/\\bawait\\b/.test(fLine) && j > i) {\n hasAwait = true;\n }\n if (started && braceCount === 0) {\n endLine = j + 1;\n break;\n }\n }\n\n // Also check the first line for await (arrow functions on same line)\n if (/\\bawait\\b/.test(line) && line.indexOf('await') > line.indexOf('async')) {\n hasAwait = true;\n }\n\n functions.push({ name, startLine, hasAwait, endLine });\n }\n }\n return functions;\n}\n\n/**\n * Check if a line is inside a try block by looking backwards.\n */\nfunction isInsideTryCatch(lines: string[], lineIndex: number): boolean {\n let braceDepth = 0;\n for (let i = lineIndex; i >= 0; i--) {\n const line = lines[i];\n for (let j = line.length - 1; j >= 0; j--) {\n if (line[j] === '}') braceDepth++;\n if (line[j] === '{') braceDepth--;\n }\n if (braceDepth < 0 && /\\btry\\b/.test(lines[i])) return true;\n if (braceDepth < 0 && /\\bcatch\\b/.test(lines[i])) return true;\n }\n return false;\n}\n\n// ============================================================================\n// Engine\n// ============================================================================\n\nexport const runtimeVerifyEngine: ScanEngine = {\n name: 'runtime-verify',\n description: 'Static analysis for runtime issues: unhandled promises, dead exports, async bugs',\n\n async scan(files: Map<string, FileContext>, options: ScanOptions): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n // ── Build project-wide import map for dead export detection (RV003) ──\n const allImportedSymbols = new Set<string>();\n for (const [, file] of files) {\n const symbols = extractImportedSymbols(file);\n for (const s of symbols) allImportedSymbols.add(s);\n }\n\n for (const [path, file] of files) {\n // Skip non-code files\n if (!['.ts', '.tsx', '.js', '.jsx'].includes(file.ext)) continue;\n\n const asyncFunctions = findAsyncFunctions(file);\n\n // ── RV001: Unhandled Promises ──\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n const trimmed = line.trim();\n\n // Skip comments\n if (trimmed.startsWith('//') || trimmed.startsWith('*')) continue;\n\n // Detect .then() without .catch()\n if (/\\.then\\s*\\(/.test(trimmed) && !/.catch\\s*\\(/.test(trimmed)) {\n // Check next few lines for .catch\n const nextLines = file.lines.slice(i + 1, i + 4).join(' ');\n if (!/.catch\\s*\\(/.test(nextLines)) {\n const rule = getRuleOrDefault('RV001');\n findings.push({\n id: `RV001-${path}-${i + 1}`,\n ruleId: 'RV001',\n engine: 'runtime-verify',\n category: 'runtime-verify',\n severity: 'high',\n confidence: 'likely',\n confidenceScore: 82,\n file: path,\n line: i + 1,\n code: trimmed,\n message: 'Promise .then() without .catch() — rejection will be unhandled',\n why: rule.why,\n fix: rule.fix,\n autoFixable: false,\n tags: rule.tags,\n verified: false,\n _dedup: `RV001:${path}:${i + 1}`,\n });\n }\n }\n\n // Detect await outside try/catch\n if (/\\bawait\\b/.test(trimmed) && !isInsideTryCatch(file.lines, i)) {\n // Check if this is inside a function that has a try/catch wrapping it\n // Only flag if no surrounding try/catch at all\n const rule = getRuleOrDefault('RV001');\n findings.push({\n id: `RV001-await-${path}-${i + 1}`,\n ruleId: 'RV001',\n engine: 'runtime-verify',\n category: 'runtime-verify',\n severity: 'medium',\n confidence: 'possible',\n confidenceScore: 65,\n file: path,\n line: i + 1,\n code: trimmed,\n message: 'await without surrounding try/catch — rejection may be unhandled',\n why: rule.why,\n fix: rule.fix,\n autoFixable: false,\n tags: rule.tags,\n verified: false,\n _dedup: `RV001-await:${path}:${i + 1}`,\n });\n }\n }\n\n // ── RV002: Async Without Await ──\n for (const fn of asyncFunctions) {\n if (!fn.hasAwait && fn.endLine - fn.startLine > 1) {\n const rule = getRuleOrDefault('RV002');\n findings.push({\n id: `RV002-${path}-${fn.startLine}`,\n ruleId: 'RV002',\n engine: 'runtime-verify',\n category: 'runtime-verify',\n severity: 'medium',\n confidence: 'likely',\n confidenceScore: 80,\n file: path,\n line: fn.startLine,\n code: file.lines[fn.startLine - 1]?.trim() ?? '',\n message: `Async function '${fn.name}' never uses await`,\n why: rule.why,\n fix: rule.fix,\n autoFixable: false,\n tags: rule.tags,\n verified: false,\n _dedup: `RV002:${path}:${fn.startLine}`,\n });\n }\n }\n\n // ── RV003: Dead Exports ──\n const exports = extractExports(file);\n // Skip entry points and types files\n const isEntry = /(?:index|main|app|server|cli)\\.[tj]sx?$/.test(path);\n if (!isEntry) {\n for (const exp of exports) {\n if (!allImportedSymbols.has(exp.name)) {\n const rule = getRuleOrDefault('RV003');\n findings.push({\n id: `RV003-${path}-${exp.line}`,\n ruleId: 'RV003',\n engine: 'runtime-verify',\n category: 'runtime-verify',\n severity: 'medium',\n confidence: 'possible',\n confidenceScore: 68,\n file: path,\n line: exp.line,\n code: file.lines[exp.line - 1]?.trim() ?? '',\n message: `Dead export: '${exp.name}' is exported but never imported`,\n why: rule.why,\n fix: rule.fix,\n autoFixable: false,\n tags: rule.tags,\n verified: false,\n _dedup: `RV003:${path}:${exp.name}`,\n });\n }\n }\n }\n\n // ── RV004: Floating Promises ──\n const asyncFuncNames = new Set(asyncFunctions.map(f => f.name));\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n const trimmed = line.trim();\n\n // Skip comments, imports, exports, function declarations\n if (trimmed.startsWith('//') || trimmed.startsWith('*')) continue;\n if (trimmed.startsWith('import ') || trimmed.startsWith('export ')) continue;\n if (/^(?:async\\s+)?function\\s/.test(trimmed)) continue;\n\n // Check if a known async function is called without await/then/void\n for (const asyncName of asyncFuncNames) {\n const callRegex = new RegExp(`(?<!await\\\\s)(?<!void\\\\s)\\\\b${asyncName}\\\\s*\\\\(`);\n if (callRegex.test(trimmed) && !trimmed.includes('.then(') && !trimmed.includes('await ')) {\n // Don't flag if it's an assignment (const x = asyncFn())\n if (/(?:const|let|var|return)\\s/.test(trimmed)) continue;\n\n const rule = getRuleOrDefault('RV004');\n findings.push({\n id: `RV004-${path}-${i + 1}`,\n ruleId: 'RV004',\n engine: 'runtime-verify',\n category: 'runtime-verify',\n severity: 'high',\n confidence: 'likely',\n confidenceScore: 78,\n file: path,\n line: i + 1,\n code: trimmed,\n message: `Floating promise: '${asyncName}()' called without await or .then()`,\n why: rule.why,\n fix: rule.fix,\n autoFixable: false,\n tags: rule.tags,\n verified: false,\n _dedup: `RV004:${path}:${i + 1}`,\n });\n }\n }\n }\n\n // ── RV005: Race Condition Risk ──\n // Detect let/var declared at module scope that is written inside async functions\n const moduleVars: { name: string; line: number }[] = [];\n let depth = 0;\n for (let i = 0; i < file.lines.length; i++) {\n const line = file.lines[i];\n for (const ch of line) {\n if (ch === '{') depth++;\n if (ch === '}') depth--;\n }\n if (depth === 0) {\n const varMatch = line.match(/(?:let|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)/);\n if (varMatch) {\n moduleVars.push({ name: varMatch[1], line: i + 1 });\n }\n }\n }\n\n for (const fn of asyncFunctions) {\n for (const v of moduleVars) {\n // Check if the async function writes to the module-scope variable\n for (let j = fn.startLine - 1; j < fn.endLine && j < file.lines.length; j++) {\n const fLine = file.lines[j];\n const writeRegex = new RegExp(`\\\\b${v.name}\\\\s*(?:=|\\\\+=|-=|\\\\+\\\\+|--)`);\n if (writeRegex.test(fLine)) {\n const rule = getRuleOrDefault('RV005');\n findings.push({\n id: `RV005-${path}-${j + 1}`,\n ruleId: 'RV005',\n engine: 'runtime-verify',\n category: 'runtime-verify',\n severity: 'medium',\n confidence: 'possible',\n confidenceScore: 65,\n file: path,\n line: j + 1,\n code: fLine.trim(),\n message: `Race condition risk: async function '${fn.name}' mutates shared variable '${v.name}'`,\n why: rule.why,\n fix: rule.fix,\n autoFixable: false,\n tags: rule.tags,\n verified: false,\n _dedup: `RV005:${path}:${v.name}:${fn.name}`,\n });\n break;\n }\n }\n }\n }\n }\n\n return findings;\n },\n};\n","/**\n * Auto-Fix Engine\n * \n * Applies automated fixes for findings marked with autoFixable: true.\n * \n * Supported fixes:\n * - QLT001: Remove console.log/debug/trace statements\n * - QLT002: Remove debugger statements\n * - QLT004: Remove unused imports (basic)\n * - SEC009: Replace Math.random() with crypto.randomUUID()\n * - IG004/HAL006: Add missing env vars to .env.example\n * \n * Supports --dry-run mode to preview changes without writing.\n * Fixes are applied bottom-up (highest line first) to avoid offset drift.\n */\n\nimport { readFileSync, writeFileSync, existsSync, appendFileSync } from 'fs';\nimport { join } from 'path';\nimport type { Finding, FixResult, FixReport } from '../types/index.js';\n\n// ============================================================================\n// Fix Strategies\n// ============================================================================\n\ninterface FixStrategy {\n ruleId: string;\n apply(finding: Finding, lines: string[], projectRoot: string): { replacement: string; description: string } | null;\n}\n\nconst fixStrategies: FixStrategy[] = [\n // ── QLT001: Remove console.log ──\n {\n ruleId: 'QLT001',\n apply(finding, lines) {\n const lineIdx = finding.line - 1;\n const line = lines[lineIdx];\n if (!line) return null;\n\n const trimmed = line.trim();\n // Only remove if the entire line is a console statement\n if (/^\\s*console\\.(log|debug|trace|info|warn)\\s*\\(/.test(line)) {\n // Check if the console call spans multiple lines\n let fullStatement = trimmed;\n let endIdx = lineIdx;\n let parenCount = 0;\n for (let i = lineIdx; i < lines.length; i++) {\n for (const ch of lines[i]) {\n if (ch === '(') parenCount++;\n if (ch === ')') parenCount--;\n }\n if (parenCount <= 0) {\n endIdx = i;\n break;\n }\n }\n\n return {\n replacement: endIdx === lineIdx ? '' : '',\n description: `Remove ${trimmed.split('(')[0]}() statement`,\n };\n }\n\n // If console is part of a larger expression, we can't safely remove\n return null;\n },\n },\n\n // ── QLT002: Remove debugger ──\n {\n ruleId: 'QLT002',\n apply(finding, lines) {\n const lineIdx = finding.line - 1;\n const line = lines[lineIdx];\n if (!line) return null;\n\n if (/^\\s*debugger\\s*;?\\s*$/.test(line)) {\n return {\n replacement: '',\n description: 'Remove debugger statement',\n };\n }\n return null;\n },\n },\n\n // ── SEC009: Replace Math.random() with crypto.randomUUID() ──\n {\n ruleId: 'SEC009',\n apply(finding, lines) {\n const lineIdx = finding.line - 1;\n const line = lines[lineIdx];\n if (!line) return null;\n\n // Replace Math.random() calls in security context\n if (/Math\\.random\\(\\)/.test(line)) {\n const fixed = line.replace(\n /Math\\.random\\(\\)\\.toString\\(\\d*\\)(?:\\.slice\\(\\d+\\))?/g,\n 'crypto.randomUUID()'\n ).replace(\n /Math\\.random\\(\\)/g,\n 'crypto.randomUUID()'\n );\n\n if (fixed !== line) {\n return {\n replacement: fixed,\n description: 'Replace Math.random() with crypto.randomUUID()',\n };\n }\n }\n return null;\n },\n },\n\n // ── IG004/HAL006: Add missing env var to .env.example ──\n {\n ruleId: 'IG004',\n apply(finding, _lines, projectRoot) {\n const envVarMatch = finding.code.match(/process\\.env\\.([A-Z_][A-Z0-9_]*)/);\n if (!envVarMatch) return null;\n\n const varName = envVarMatch[1];\n const envExamplePath = join(projectRoot, '.env.example');\n\n // Check if already in .env.example\n if (existsSync(envExamplePath)) {\n const content = readFileSync(envExamplePath, 'utf-8');\n if (content.includes(`${varName}=`)) return null;\n }\n\n return {\n replacement: `${varName}=`,\n description: `Add ${varName} to .env.example`,\n };\n },\n },\n];\n\n// ============================================================================\n// Fix Applier\n// ============================================================================\n\nexport interface FixOptions {\n /** Findings to fix (only autoFixable ones are processed) */\n findings: Finding[];\n /** Project root directory */\n projectRoot: string;\n /** If true, show what would change without writing */\n dryRun: boolean;\n}\n\n/**\n * Apply auto-fixes for all fixable findings.\n * \n * Fixes are grouped by file and applied bottom-up to avoid line offset drift.\n */\nexport function applyFixes(options: FixOptions): FixReport {\n const startTime = Date.now();\n const fixResults: FixResult[] = [];\n\n // Filter to only autoFixable findings\n const fixable = options.findings.filter(f => f.autoFixable);\n\n // Group by file\n const byFile = new Map<string, Finding[]>();\n for (const f of fixable) {\n if (!byFile.has(f.file)) byFile.set(f.file, []);\n byFile.get(f.file)!.push(f);\n }\n\n // Track env vars to add to .env.example (special case)\n const envVarsToAdd: string[] = [];\n\n for (const [filePath, findings] of byFile) {\n const absPath = join(options.projectRoot, filePath);\n\n // Read current file content\n let lines: string[];\n try {\n const content = readFileSync(absPath, 'utf-8');\n lines = content.split('\\n');\n } catch {\n // File not readable, skip all findings for this file\n for (const f of findings) {\n fixResults.push({\n findingId: f.id,\n ruleId: f.ruleId,\n file: filePath,\n line: f.line,\n original: f.code,\n replacement: '',\n applied: false,\n description: 'File not readable, skipped',\n });\n }\n continue;\n }\n\n // Sort findings by line number DESCENDING so we fix from bottom up\n const sorted = [...findings].sort((a, b) => b.line - a.line);\n\n let modified = false;\n for (const finding of sorted) {\n const strategy = fixStrategies.find(s => s.ruleId === finding.ruleId);\n if (!strategy) {\n fixResults.push({\n findingId: finding.id,\n ruleId: finding.ruleId,\n file: filePath,\n line: finding.line,\n original: finding.code,\n replacement: '',\n applied: false,\n description: 'No fix strategy available',\n });\n continue;\n }\n\n const result = strategy.apply(finding, lines, options.projectRoot);\n if (!result) {\n fixResults.push({\n findingId: finding.id,\n ruleId: finding.ruleId,\n file: filePath,\n line: finding.line,\n original: finding.code,\n replacement: '',\n applied: false,\n description: 'Fix not applicable to this code pattern',\n });\n continue;\n }\n\n const lineIdx = finding.line - 1;\n const original = lines[lineIdx] ?? '';\n\n // Special handling for env var additions\n if (finding.ruleId === 'IG004' || finding.ruleId === 'HAL006') {\n envVarsToAdd.push(result.replacement);\n fixResults.push({\n findingId: finding.id,\n ruleId: finding.ruleId,\n file: '.env.example',\n line: 0,\n original: '',\n replacement: result.replacement,\n applied: !options.dryRun,\n description: result.description,\n });\n continue;\n }\n\n if (result.replacement === '') {\n // Remove the line entirely\n lines.splice(lineIdx, 1);\n } else {\n lines[lineIdx] = result.replacement;\n }\n modified = true;\n\n fixResults.push({\n findingId: finding.id,\n ruleId: finding.ruleId,\n file: filePath,\n line: finding.line,\n original,\n replacement: result.replacement || '(line removed)',\n applied: !options.dryRun,\n description: result.description,\n });\n }\n\n // Write modified file\n if (modified && !options.dryRun) {\n try {\n writeFileSync(absPath, lines.join('\\n'), 'utf-8');\n } catch {\n // Mark all fixes for this file as not applied\n for (const r of fixResults) {\n if (r.file === filePath) r.applied = false;\n }\n }\n }\n }\n\n // Write env vars to .env.example\n if (envVarsToAdd.length > 0 && !options.dryRun) {\n const envExamplePath = join(options.projectRoot, '.env.example');\n try {\n const additions = envVarsToAdd.map(v => `${v}\\n`).join('');\n if (existsSync(envExamplePath)) {\n appendFileSync(envExamplePath, `\\n# Added by VibeCheck auto-fix\\n${additions}`, 'utf-8');\n } else {\n writeFileSync(envExamplePath, `# Environment Variables\\n# Added by VibeCheck auto-fix\\n${additions}`, 'utf-8');\n }\n } catch {\n // Mark env fixes as not applied\n for (const r of fixResults) {\n if (r.file === '.env.example') r.applied = false;\n }\n }\n }\n\n const applied = fixResults.filter(r => r.applied).length;\n\n return {\n totalFixable: fixable.length,\n applied,\n skipped: fixable.length - applied,\n fixes: fixResults,\n durationMs: Date.now() - startTime,\n };\n}\n"],"mappings":"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","names":["import_fs","import_path","PATTERNS","PATTERNS","PATTERNS","import_path","exports","import_fs","import_path"]}
|