octocode-cli 1.2.7 → 1.2.9
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/README.md +42 -35
- package/out/octocode-cli.js +36 -11719
- package/package.json +36 -36
- package/skills/README.md +42 -114
- package/skills/{octocode-code-engineer → octocode-engineer}/.claude/settings.local.json +2 -1
- package/skills/octocode-engineer/README.md +99 -0
- package/skills/octocode-engineer/SKILL.md +499 -0
- package/skills/octocode-engineer/build.mjs +29 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/eslint.config.mjs +3 -13
- package/skills/{octocode-code-engineer → octocode-engineer}/package.json +28 -27
- package/skills/octocode-engineer/references/ast-reference.md +166 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/references/cli-reference.md +80 -6
- package/skills/octocode-engineer/references/externals.md +86 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/references/output-files.md +46 -6
- package/skills/octocode-engineer/references/quality-indicators.md +202 -0
- package/skills/octocode-engineer/references/tool-workflows.md +298 -0
- package/skills/octocode-engineer/references/validation-playbooks.md +99 -0
- package/skills/octocode-engineer/scripts/ast/search.js +45 -0
- package/skills/octocode-engineer/scripts/ast/tree-search.js +27 -0
- package/skills/octocode-engineer/scripts/index.js +173 -0
- package/skills/octocode-engineer/scripts/run.js +179 -0
- package/skills/octocode-engineer/src/analysis/dependencies.ts +378 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/discovery.test.ts +57 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/discovery.ts +43 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/search.test.ts +113 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/search.ts +64 -1
- package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/tree-sitter.test.ts +118 -2
- package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/tree-sitter.ts +65 -3
- package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/ts-analyzer.test.ts +281 -1
- package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/ts-analyzer.ts +173 -3
- package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/security.test.ts +73 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/security.ts +62 -4
- package/skills/octocode-engineer/src/detector-gating.test.ts +59 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/code-quality.ts +342 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/index.ts +8 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/index.test.ts +565 -11
- package/skills/octocode-engineer/src/index.ts +468 -0
- package/skills/octocode-engineer/src/pipeline/affected.test.ts +147 -0
- package/skills/octocode-engineer/src/pipeline/affected.ts +68 -0
- package/skills/octocode-engineer/src/pipeline/baseline.test.ts +276 -0
- package/skills/octocode-engineer/src/pipeline/baseline.ts +76 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/cli.test.ts +300 -53
- package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/cli.ts +180 -36
- package/skills/octocode-engineer/src/pipeline/config-loader.test.ts +264 -0
- package/skills/octocode-engineer/src/pipeline/config-loader.ts +109 -0
- package/skills/octocode-engineer/src/pipeline/create-options.ts +55 -0
- package/skills/octocode-engineer/src/pipeline/health-score.test.ts +65 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/main.ts +130 -17
- package/skills/octocode-engineer/src/pipeline/progress.ts +51 -0
- package/skills/octocode-engineer/src/pipeline/reporters.test.ts +155 -0
- package/skills/octocode-engineer/src/pipeline/reporters.ts +64 -0
- package/skills/octocode-engineer/src/reporting/graph-features.test.ts +279 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/reporting/output-contract.test.ts +6 -0
- package/skills/octocode-engineer/src/reporting/summary-md.test.ts +1066 -0
- package/skills/octocode-engineer/src/reporting/summary-md.ts +1604 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/reporting/writer.ts +136 -13
- package/skills/octocode-engineer/src/run.ts +78 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/sanity.test.ts +1 -1
- package/skills/octocode-engineer/src/types/analysis.ts +25 -0
- package/skills/octocode-engineer/src/types/collectors.ts +134 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/types/constants.ts +75 -41
- package/skills/octocode-engineer/src/types/core.ts +203 -0
- package/skills/octocode-engineer/src/types/dependency.ts +215 -0
- package/skills/octocode-engineer/src/types/file-entry.ts +108 -0
- package/skills/octocode-engineer/src/types/findings.ts +105 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/src/types/index.ts +60 -30
- package/skills/octocode-engineer/src/types/tree-sitter.ts +38 -0
- package/skills/{octocode-code-engineer → octocode-engineer}/tsconfig.json +1 -0
- package/skills/octocode-research/.octocode/scan/.cache/analysis-cache.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/architecture.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/ast-trees.txt +5566 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/code-quality.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/dead-code.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/file-inventory.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/findings.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/graph.md +189 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/security.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/summary.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/summary.md +265 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/architecture.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/ast-trees.txt +5555 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/code-quality.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/dead-code.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/file-inventory.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/findings.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/graph.md +190 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/security.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/summary.json +1 -0
- package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/summary.md +265 -0
- package/skills/octocode-research/CHANGELOG.md +60 -0
- package/skills/octocode-research/README.md +102 -388
- package/skills/octocode-research/SKILL.md +169 -498
- package/skills/octocode-research/package.json +19 -31
- package/skills/octocode-research/references/PARALLEL_AGENT_PROTOCOL.md +19 -0
- package/skills/octocode-research/references/SESSION_MANAGEMENT.md +38 -0
- package/skills/octocode-research/scripts/server-init.js +1 -1
- package/skills/octocode-research/scripts/server.d.ts +2 -1
- package/skills/octocode-research/scripts/server.js +329 -233
- package/skills/octocode-research/src/__tests__/integration/promptsRoutes.test.ts +180 -0
- package/skills/octocode-research/src/__tests__/integration/serverHttp.test.ts +221 -0
- package/skills/octocode-research/src/__tests__/integration/serverLifecycle.test.ts +194 -0
- package/skills/octocode-research/src/__tests__/integration/toolsRoutes.test.ts +501 -0
- package/skills/octocode-research/src/__tests__/unit/readiness.test.ts +61 -0
- package/skills/octocode-research/src/__tests__/unit/resilience.test.ts +192 -0
- package/skills/octocode-research/src/__tests__/unit/responseFactory.test.ts +172 -0
- package/skills/octocode-research/src/__tests__/unit/responseParser.test.ts +288 -0
- package/skills/octocode-research/src/__tests__/unit/schemas.test.ts +509 -0
- package/skills/octocode-research/src/index.ts +4 -124
- package/skills/octocode-research/src/middleware/queryParser.ts +0 -26
- package/skills/octocode-research/src/routes/lsp.ts +58 -59
- package/skills/octocode-research/src/routes/package.ts +35 -65
- package/skills/octocode-research/src/routes/prompts.ts +3 -3
- package/skills/octocode-research/src/routes/tools.ts +8 -20
- package/skills/octocode-research/src/server-init.ts +30 -237
- package/skills/octocode-research/src/server.ts +50 -23
- package/skills/octocode-research/src/types/errorGuards.ts +9 -80
- package/skills/octocode-research/src/types/guards.ts +0 -28
- package/skills/octocode-research/src/types/mcp.ts +11 -66
- package/skills/octocode-research/src/types/responses.ts +11 -129
- package/skills/octocode-research/src/utils/circuitBreaker.ts +0 -21
- package/skills/octocode-research/src/utils/logger.ts +1 -97
- package/skills/octocode-research/src/utils/resilience.ts +2 -12
- package/skills/octocode-research/src/utils/responseFactory.ts +0 -42
- package/skills/octocode-research/src/utils/responseParser.ts +3 -25
- package/skills/octocode-research/src/utils/retry.ts +0 -63
- package/skills/octocode-research/src/utils/routeFactory.ts +1 -1
- package/skills/octocode-research/src/validation/httpPreprocess.ts +0 -3
- package/skills/octocode-research/src/validation/index.ts +0 -1
- package/skills/octocode-research/src/validation/schemas.ts +0 -63
- package/skills/octocode-research/src/validation/toolCallSchema.ts +3 -3
- package/skills/octocode-research/tsdown.config.ts +4 -0
- package/skills/octocode-research/vitest.config.ts +3 -0
- package/skills/octocode-code-engineer/.plan/VALIDATED_PLAN.md +0 -223
- package/skills/octocode-code-engineer/README.md +0 -178
- package/skills/octocode-code-engineer/SKILL.md +0 -418
- package/skills/octocode-code-engineer/minify-scripts.mjs +0 -32
- package/skills/octocode-code-engineer/references/agent-ast-reading-rfc.md +0 -95
- package/skills/octocode-code-engineer/references/architecture-techniques.md +0 -121
- package/skills/octocode-code-engineer/references/ast-search.md +0 -210
- package/skills/octocode-code-engineer/references/ast-tree-search.md +0 -151
- package/skills/octocode-code-engineer/references/concepts.md +0 -107
- package/skills/octocode-code-engineer/references/finding-categories.md +0 -128
- package/skills/octocode-code-engineer/references/improvement-roadmap.md +0 -304
- package/skills/octocode-code-engineer/references/playbooks.md +0 -204
- package/skills/octocode-code-engineer/references/present-results.md +0 -136
- package/skills/octocode-code-engineer/references/tool-workflows.md +0 -566
- package/skills/octocode-code-engineer/references/validate-investigate.md +0 -225
- package/skills/octocode-code-engineer/scripts/analysis/dependencies.js +0 -1
- package/skills/octocode-code-engineer/scripts/analysis/dependency-summary.js +0 -1
- package/skills/octocode-code-engineer/scripts/analysis/discovery.js +0 -1
- package/skills/octocode-code-engineer/scripts/analysis/graph-analytics.js +0 -1
- package/skills/octocode-code-engineer/scripts/analysis/semantic.js +0 -1
- package/skills/octocode-code-engineer/scripts/ast/helpers.js +0 -1
- package/skills/octocode-code-engineer/scripts/ast/metrics.js +0 -1
- package/skills/octocode-code-engineer/scripts/ast/search.js +0 -2
- package/skills/octocode-code-engineer/scripts/ast/tree-search.js +0 -2
- package/skills/octocode-code-engineer/scripts/ast/tree-sitter.js +0 -1
- package/skills/octocode-code-engineer/scripts/ast/ts-analyzer.js +0 -1
- package/skills/octocode-code-engineer/scripts/collectors/chains.js +0 -1
- package/skills/octocode-code-engineer/scripts/collectors/effects.js +0 -1
- package/skills/octocode-code-engineer/scripts/collectors/input-sources.js +0 -1
- package/skills/octocode-code-engineer/scripts/collectors/performance.js +0 -1
- package/skills/octocode-code-engineer/scripts/collectors/prototype-pollution.js +0 -1
- package/skills/octocode-code-engineer/scripts/collectors/security.js +0 -1
- package/skills/octocode-code-engineer/scripts/collectors/test-profile.js +0 -1
- package/skills/octocode-code-engineer/scripts/common/is-direct-run.js +0 -1
- package/skills/octocode-code-engineer/scripts/common/utils.js +0 -1
- package/skills/octocode-code-engineer/scripts/detectors/code-quality.js +0 -1
- package/skills/octocode-code-engineer/scripts/detectors/cohesion.js +0 -1
- package/skills/octocode-code-engineer/scripts/detectors/coupling.js +0 -1
- package/skills/octocode-code-engineer/scripts/detectors/cycle.js +0 -1
- package/skills/octocode-code-engineer/scripts/detectors/dead-code.js +0 -1
- package/skills/octocode-code-engineer/scripts/detectors/import-style.js +0 -1
- package/skills/octocode-code-engineer/scripts/detectors/index.js +0 -1
- package/skills/octocode-code-engineer/scripts/detectors/security.js +0 -1
- package/skills/octocode-code-engineer/scripts/detectors/semantic.js +0 -1
- package/skills/octocode-code-engineer/scripts/detectors/shared.js +0 -1
- package/skills/octocode-code-engineer/scripts/detectors/test-quality.js +0 -1
- package/skills/octocode-code-engineer/scripts/index.js +0 -1
- package/skills/octocode-code-engineer/scripts/pipeline/cache.js +0 -1
- package/skills/octocode-code-engineer/scripts/pipeline/cli.js +0 -1
- package/skills/octocode-code-engineer/scripts/pipeline/main.js +0 -2
- package/skills/octocode-code-engineer/scripts/reporting/analysis.js +0 -1
- package/skills/octocode-code-engineer/scripts/reporting/summary-md.js +0 -1
- package/skills/octocode-code-engineer/scripts/reporting/writer.js +0 -1
- package/skills/octocode-code-engineer/scripts/types/constants.js +0 -1
- package/skills/octocode-code-engineer/scripts/types/index.js +0 -1
- package/skills/octocode-code-engineer/scripts/types/interfaces.js +0 -1
- package/skills/octocode-code-engineer/src/analysis/dependencies.ts +0 -406
- package/skills/octocode-code-engineer/src/index.ts +0 -403
- package/skills/octocode-code-engineer/src/reporting/summary-md.test.ts +0 -421
- package/skills/octocode-code-engineer/src/reporting/summary-md.ts +0 -714
- package/skills/octocode-code-engineer/src/types/interfaces.ts +0 -682
- package/skills/octocode-research/src/types/toolTypes.ts +0 -33
- package/skills/octocode-research/src/utils/logEmoji.ts +0 -103
- /package/skills/{octocode-code-engineer → octocode-engineer}/.octocode/rfc/RFC-code-engineer-weakness-fixes.md +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/architecture.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/ast-helpers.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/ast-search.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/base.css +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/block-navigation.js +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/cache.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/cli.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/clover.xml +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-effects.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-input-sources.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-performance.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-prototype-pollution.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-security.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-test-profile.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/coverage-final.json +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/dependencies.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/dependency-summary.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/discovery.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/favicon.png +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/graph-analytics.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/index.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/index.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/metrics.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/pipeline.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/prettify.css +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/prettify.js +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/report-analysis.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/report-writer.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/security-detectors.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/semantic-detectors.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/semantic.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/sort-arrow-sprite.png +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/sorter.js +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/summary-md.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/test-quality-detectors.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/tree-sitter-analyzer.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/ts-analyzer.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/types.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/utils.ts.html +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/dependencies.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/dependency-summary.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/dependency-summary.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/graph-analytics.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/graph-analytics.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/semantic.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/semantic.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/helpers.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/helpers.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/metrics.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/metrics.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/tree-search.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/tree-search.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/chains.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/effects.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/effects.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/input-sources.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/input-sources.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/performance.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/performance.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/prototype-pollution.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/prototype-pollution.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/test-profile.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/test-profile.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/common/is-direct-run.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/common/is-direct-run.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/common/utils.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/common/utils.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/cohesion.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/coupling.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/cycle.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/dead-code.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/import-style.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/index.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/security.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/security.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/semantic.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/shared.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/test-quality.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/test-quality.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/cache.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/cache.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/main.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/reporting/analysis.test.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/src/reporting/analysis.ts +0 -0
- /package/skills/{octocode-code-engineer → octocode-engineer}/vitest.config.ts +0 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
var Fo=Object.defineProperty;var N=(e,n)=>()=>(e&&(n=e(e=0)),n);var Wt=(e,n)=>{for(var i in n)Fo(e,i,{get:n[i],enumerable:!0})};function G(e){return e.length<200}function ve(e,n,i){let t=e.importedSymbolsByFile.get(n);if(t){for(let r of t)if(r.resolvedModule===i&&r.lineStart)return{lineStart:r.lineStart,lineEnd:r.lineEnd??r.lineStart}}let s=e.reExportsByFile.get(n);if(s){for(let r of s)if(r.resolvedModule===i&&r.lineStart)return{lineStart:r.lineStart,lineEnd:r.lineEnd??r.lineStart}}return{lineStart:1,lineEnd:1}}function de(e){let n=e.toLowerCase();return!!(/(^|\/)(index|main|app|server|cli|public)\.[mc]?[jt]sx?$/.test(n)||/\.(config)\.[mc]?[jt]sx?$/.test(n))}var ge=N(()=>{"use strict"});var Qt={};Wt(Qt,{ALLOWED_EXTS:()=>qe,ALL_CATEGORIES:()=>Ue,DEFAULT_OPTS:()=>Me,DEFAULT_THRESHOLDS:()=>Vt,IMPORT_RESOLVE_EXTS:()=>Je,PILLAR_CATEGORIES:()=>B,SEMANTIC_CATEGORIES:()=>ft,SEVERITY_ORDER:()=>Pe,TS_CONTROL_KINDS:()=>pt,TS_TREE_SITTER_CONTROL_TYPES:()=>gt,TS_TREE_SITTER_FUNCTION_TYPES:()=>mt});import ko from"node:path";import*as we from"typescript";var Vt,Me,B,Ue,ft,qe,Je,pt,gt,mt,Pe,ht=N(()=>{"use strict";Vt={couplingThreshold:15,fanInThreshold:20,fanOutThreshold:15,godModuleStatements:500,godModuleExports:20,barrelSymbolThreshold:30,sdpMinDelta:.15,sdpMaxSourceInstability:.6,layerOrder:[],minFunctionStatements:6,minFlowStatements:6,criticalComplexityThreshold:30,godFunctionStatements:100,godFunctionMiThreshold:10,cognitiveComplexityThreshold:15,parameterThreshold:5,halsteadEffortThreshold:5e5,maintainabilityIndexThreshold:20,anyThreshold:5,flowDupThreshold:3,similarityThreshold:.85,deepNestingThreshold:5,multipleReturnThreshold:6,magicStringMinOccurrences:3,booleanParamThreshold:3,overrideChainThreshold:3,shotgunThreshold:8,secretEntropyThreshold:4.5,secretMinLength:20,mockThreshold:10},Me={root:process.cwd(),out:null,json:!1,packageRoot:ko.join(process.cwd(),"packages"),parser:"auto",includeTests:!1,emitTree:!0,treeDepth:4,noCache:!1,clearCache:!1,semantic:!1,graph:!1,graphAdvanced:!1,flow:!1,scope:null,scopeSymbols:null,features:null,ignoreDirs:new Set([".git",".next",".yarn",".cache",".octocode","node_modules","dist","coverage","out"]),findingsLimit:1/0,noDiversify:!1,maxRecsPerCategory:2,deepLinkTopN:12,thresholds:{...Vt},affected:null,saveBaseline:!1,ignoreKnown:null,reporter:"default",focus:null,focusDepth:1,collapse:null,atLeast:null,configFile:null},B={architecture:["dependency-cycle","dependency-critical-path","dependency-test-only","architecture-sdp-violation","high-coupling","god-module-coupling","orphan-module","unreachable-module","layer-violation","low-cohesion","mega-folder","distance-from-main-sequence","feature-envy","untested-critical-code","over-abstraction","concrete-dependency","circular-type-dependency","shotgun-surgery","import-side-effect-risk","cycle-cluster","broker-module","bridge-module","package-boundary-chatter","startup-risk-hub","namespace-import","commonjs-in-esm","export-star-leak","mixed-module-format"],"code-quality":["duplicate-function-body","duplicate-flow-structure","function-optimization","cognitive-complexity","god-module","god-function","halstead-effort","low-maintainability","excessive-parameters","unsafe-any","empty-catch","switch-no-default","unused-parameter","deep-override-chain","interface-compliance","type-assertion-escape","promise-misuse","narrowable-type","missing-error-boundary","await-in-loop","sync-io","uncleared-timer","listener-leak-risk","unbounded-collection","similar-function-body","message-chain","deep-nesting","multiple-return-paths","catch-rethrow","magic-string","boolean-parameter-cluster","promise-all-unhandled","export-surface-density","change-risk"],"dead-code":["dead-export","dead-re-export","re-export-duplication","re-export-shadowed","unused-npm-dependency","package-boundary-violation","barrel-explosion","unused-import","orphan-implementation","move-to-caller","semantic-dead-export","dead-file"],security:["hardcoded-secret","eval-usage","unsafe-html","sql-injection-risk","unsafe-regex","prototype-pollution-risk","unvalidated-input-sink","input-passthrough-risk","path-traversal-risk","command-injection-risk","debug-log-leakage","sensitive-data-logging"],"test-quality":["low-assertion-density","test-no-assertion","excessive-mocking","shared-mutable-state","missing-test-cleanup","focused-test","fake-timer-no-restore","missing-mock-restoration"]},Ue=new Set(Object.values(B).flat()),ft=new Set(["over-abstraction","concrete-dependency","circular-type-dependency","unused-parameter","deep-override-chain","interface-compliance","unused-import","orphan-implementation","shotgun-surgery","move-to-caller","narrowable-type","semantic-dead-export"]),qe=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs"]),Je=[".ts",".tsx",".js",".jsx",".mjs",".cjs",".d.ts"],pt=new Set([we.SyntaxKind.IfStatement,we.SyntaxKind.SwitchStatement,we.SyntaxKind.TryStatement,we.SyntaxKind.ForStatement,we.SyntaxKind.WhileStatement,we.SyntaxKind.DoStatement,we.SyntaxKind.ForOfStatement,we.SyntaxKind.ForInStatement,we.SyntaxKind.ConditionalExpression]),gt=new Set(["if_statement","switch_statement","try_statement","for_statement","while_statement","do_statement","for_in_statement","for_of_statement","for_await_statement","conditional_expression","catch_clause"]),mt=new Set(["function_declaration","function","generator_function","generator_function_declaration","method_definition","arrow_function","function_expression"]),Pe={critical:4,high:3,medium:2,low:1,info:0}});var me=N(()=>{"use strict";ht()});import Co from"node:crypto";import To from"node:fs";import Ye from"node:path";import*as Z from"typescript";function Ss(e){switch(e){case".tsx":return Z.ScriptKind.TSX;case".jsx":return Z.ScriptKind.JSX;case".js":case".mjs":case".cjs":return Z.ScriptKind.JS;default:return Z.ScriptKind.TS}}function Ge(e){return Co.createHash("sha1").update(e).digest("hex").slice(0,16)}function $o(e){switch(e){case Z.SyntaxKind.Identifier:return"ID";case Z.SyntaxKind.StringLiteral:case Z.SyntaxKind.NoSubstitutionTemplateLiteral:case Z.SyntaxKind.TemplateMiddle:case Z.SyntaxKind.TemplateHead:return"STR";case Z.SyntaxKind.NumericLiteral:return"NUM";case Z.SyntaxKind.BigIntLiteral:return"BIGINT";case Z.SyntaxKind.TrueKeyword:case Z.SyntaxKind.FalseKeyword:return"BOOL";case Z.SyntaxKind.NullKeyword:return"NULL";default:return Z.SyntaxKind[e]||"UNKNOWN"}}function Jt(e,n=new WeakMap){if(n.has(e))return n.get(e);let i=[],t=r=>{i.push($o(r.kind)),Z.forEachChild(r,t)};t(e);let s=Ge(i.join("|"));return n.set(e,s),s}function Yt(e){let n=[],i=t=>{n.push(t.type);for(let s of t.children)i(s)};return i(e),Ge(n.join("|"))}function R(e,n){let i=e.getLineAndCharacterOfPosition(n.getStart(e)),t=e.getLineAndCharacterOfPosition(n.getEnd());return{lineStart:i.line+1,lineEnd:t.line+1,columnStart:i.character+1,columnEnd:t.character+1}}function Xt(e,n,i,t,s=new WeakSet){if(!e||t.size<=0)return null;t.size-=1;let r=R(n,e),o={kind:Z.SyntaxKind[e.kind]||"UNKNOWN",startLine:r.lineStart,endLine:r.lineEnd,children:[]};return i<=0||s.has(e)?(o.truncated=!0,o):(s.add(e),Z.forEachChild(e,a=>{if(t.size<=0)return;let l=Xt(a,n,i-1,t,s);l&&o.children.push(l)}),o)}function Zt(e,n,i,t,s=new WeakSet){if(!e||t.size<=0)return null;t.size-=1;let r={kind:e.type,startLine:e.startPosition.row+1,endLine:e.endPosition.row+1,children:[]};if(i<=0||s.has(e))return r.truncated=!0,r;s.add(e);for(let o of e.children){if(t.size<=0)break;let a=Zt(o,n,i-1,t,s);a&&r.children.push(a)}return r}function bs(e,n=0){let i=" ".repeat(n),t=e.startLine===e.endLine?`${e.startLine}`:`${e.startLine}:${e.endLine}`,s=e.truncated?" ...":"",r=`${i}${e.kind}[${t}]${s}
|
|
2
|
+
`;for(let o of e.children)r+=bs(o,n+1);return r}function xs(e,n){let i=[`# AST Trees \u2014 ${n}`,""];for(let t of e)i.push(`## ${t.package} \u2014 ${t.file}`),i.push(bs(t.tree));return i.join(`
|
|
3
|
+
`)}function x(e){return/(?:^|[\\/])(?:__tests__|__test__|tests)(?:[\\/]|$)/.test(e)||/(?:\.test|_test|\.spec)\.(?:ts|tsx|js|jsx|mjs|cjs)$/.test(e)}function Es(e,n){return Ye.relative(n,e).replace(/\\/g,"/")}function en(e){return Ye.normalize(e).replace(/\\/g,"/")}function Xe(e,n,i){e.has(n)||e.set(n,new Set),e.get(n).add(i)}function vs(e){return e.startsWith("./")||e.startsWith("../")||e.startsWith(".\\")||e.startsWith("..\\")}function ws(e,n){let i=n.replace(/[?#].*$/,""),t=Ye.resolve(e,i),s=[],r=Ye.extname(t),o={".js":[".ts",".tsx"],".jsx":[".tsx"],".mjs":[".ts",".tsx"],".cjs":[".ts",".tsx"]};if(r){s.push(t);let a=o[r];if(a){let l=t.slice(0,-r.length);for(let c of a){let u=`${l}${c}`;s.push(u)}}}else{for(let a of Je)s.push(`${t}${a}`);for(let a of Je)s.push(Ye.join(t,`index${a}`))}for(let a of s)if(To.existsSync(a))return a;return null}function Se(e,n,i){e.has(n)||e.set(n,[]),e.get(n).push(i)}var W=N(()=>{"use strict";me()});function tn(e){let n=[];if(e.testOnlyModules?.length===0)return n;for(let i of(e.testOnlyModules||[]).slice(0,25)){if(!G(n))break;n.push({severity:"medium",category:"dependency-test-only",file:i.file,lineStart:i.lineStart||1,lineEnd:i.lineEnd||1,title:`Module imported only from tests: ${i.file}`,reason:"No production file imports this module, but tests do. Verify if this module belongs in test fixtures/helpers.",files:[i.file],suggestedFix:{strategy:"Move test-only utilities to test scope or make production usage explicit.",steps:["Re-run import scanning after moving test-only modules to __tests__ or helper folders.","If this is shared production utility, add a non-test entrypoint/import.","Remove dead or stale production references and delete unused module if confirmed."]},impact:"Reduces shipping of non-production-only modules and clarifies ownership boundaries.",tags:["testing","dead-code","dependency"]})}return n}function nn(e,n){let i=[];if(e.cycles?.length===0)return i;for(let t of(e.cycles||[]).slice(0,15)){let s=ve(n,t.path[0],t.path[1]);if(!G(i))break;i.push({severity:"high",category:"dependency-cycle",file:t.path[0],lineStart:s.lineStart,lineEnd:s.lineEnd,title:`Dependency cycle detected (${t.nodeCount} node cycle)`,reason:`Import cycle exists across: ${t.path.join(" -> ")}`,files:t.path,suggestedFix:{strategy:"Break the cycle with a lower-level abstraction or interface module.",steps:["Extract shared contracts/types to a dedicated contract/shared package.","Move implementation in one direction using dependency inversion.","Split stateful modules into protocol and runtime layers."]},impact:"Cycles increase coupling and make incremental loading/debugging and refactors riskier.",tags:["cycle","coupling","dependency","change-risk"],lspHints:[{tool:"lspGotoDefinition",symbolName:t.path[1],lineHint:s.lineStart,file:t.path[0],expectedResult:"navigate to the import that creates the cycle edge"}]})}return i}function Do(e,n){let i={module:e[0],fanOut:0,fanIn:0};for(let t of e){let s=(n.outgoing.get(t)||new Set).size,r=(n.incoming.get(t)||new Set).size;s>i.fanOut&&(i={module:t,fanOut:s,fanIn:r})}return i}function Fs(e,n=.8){if(e.length<=1)return e;let i=[],t=new Set;for(let s=0;s<e.length;s++){if(t.has(s))continue;let r=e[s],o=new Set(r.files),a=[r.file];for(let l=s+1;l<e.length;l++){if(t.has(l))continue;let c=e[l],u=new Set(c.files),d=[...o].filter(g=>u.has(g)).length,f=new Set([...o,...u]).size;if((f>0?d/f:0)>=n){t.add(l),a.push(c.file);for(let g of c.files)o.add(g)}}if(a.length>1){let l=[...o];i.push({...r,title:`Critical dependency chain risk: ${l.length} files (${a.length} entry points)`,reason:r.reason+` Also reached from: ${a.slice(1).join(", ")}.`,files:l})}else i.push(r)}return i}function sn(e,n,i){let t=[];if(e.criticalPaths?.length===0)return t;for(let s of(e.criticalPaths||[]).slice(0,10)){if(s.score<i*3)continue;let r=ve(n,s.path[0],s.path[1]),o=Do(s.path,n);t.push({severity:s.score>=i*6?"critical":"high",category:"dependency-critical-path",file:s.path[0],lineStart:r.lineStart,lineEnd:r.lineEnd,title:`Critical dependency chain risk: ${s.length} files`,reason:`Potentially high-change surface: ${s.path.join(" -> ")} (${s.score} weight).`,files:s.path,suggestedFix:{strategy:`Break chain at \`${o.module}\` (fan-out: ${o.fanOut}, fan-in: ${o.fanIn}).`,steps:[`Extract interface from \`${o.module}\` \u2014 it has ${o.fanOut} outbound dependencies.`,"Downstream modules depend on the interface, not the implementation.","This splits the chain into two independent segments."]},impact:"Critical refactor opportunities; shorter chains reduce blast radius of change.",tags:["change-risk","dependency","blast-radius"]})}return Fs(t)}function rn(e,n){let i=[];for(let t of e.roots||[]){if(x(t)||de(t))continue;let s=(n.incoming.get(t)||new Set).size,r=(n.outgoing.get(t)||new Set).size;if(s===0&&!(r>0)){if(!G(i))break;i.push({severity:"medium",category:"dead-file",file:t,lineStart:1,lineEnd:1,title:`Potential dead file: ${t}`,reason:"File has no inbound imports and no outbound dependencies. It may be stale or orphaned.",files:[t],suggestedFix:{strategy:"Validate ownership and remove if truly unused.",steps:["Confirm the file is not an explicit runtime entrypoint.","Search runtime config/router/bootstrap references for this file path.","Delete file if confirmed dead and re-run scan."]},impact:"Reduces dead surface area and maintenance overhead.",tags:["dead-code","cleanup","hygiene"],lspHints:[{tool:"lspFindReferences",symbolName:t.split("/").pop()||t,lineHint:1,file:t,expectedResult:"confirm zero references exist before deletion"}]})}}return i}function on(e){let n=[];for(let i of e.files){if(x(i)||de(i))continue;let t=(e.incoming.get(i)||new Set).size,s=(e.outgoing.get(i)||new Set).size;t===0&&s===0&&n.push({severity:"medium",category:"orphan-module",file:i,lineStart:1,lineEnd:1,title:`Orphan module: ${i}`,reason:"Module has no inbound or outbound dependencies \u2014 completely disconnected from the module graph.",files:[i],suggestedFix:{strategy:"Delete if truly unused, or wire into module graph.",steps:["Check if the file is a runtime entrypoint, route, or config.","If truly disconnected, delete and re-run scan.","If needed, add an explicit import from the appropriate parent module."]},impact:"Removes dead surface area and clarifies module ownership.",tags:["dead-code","dependency","isolation"]})}return n}function an(e){let n=[],i=new Set;for(let r of e.files)de(r)&&i.add(r);if(i.size===0)for(let r of e.files)(e.incoming.get(r)||new Set).size===0&&i.add(r);let t=new Set,s=[...i];for(;s.length>0;){let r=s.pop();if(!t.has(r)){t.add(r);for(let o of e.outgoing.get(r)||new Set)e.files.has(o)&&!t.has(o)&&s.push(o)}}for(let r of e.files)if(!(x(r)||t.has(r)||de(r))){if(!G(n))break;n.push({severity:"high",category:"unreachable-module",file:r,lineStart:1,lineEnd:1,title:`Unreachable module: ${r}`,reason:"Module is not reachable from any entrypoint via the import graph.",files:[r],suggestedFix:{strategy:"Verify reachability and remove if truly dead.",steps:["Check if this module is loaded dynamically or via framework conventions.","Verify it is not registered as a route, plugin, or middleware.","If confirmed unreachable, delete and re-run scan."]},impact:"Identifies potentially large sections of dead code missed by direct-import checks.",tags:["dead-code","dependency","reachability"]})}return n}var ks=N(()=>{"use strict";ge();ge();W()});function ln(e,n){let i=e+n;return i===0?0:n/i}function cn(e,n=.15,i=.6){let t=[],s=new Map,r=o=>{if(s.has(o))return s.get(o);let a=(e.incoming.get(o)||new Set).size,l=(e.outgoing.get(o)||new Set).size,c=ln(a,l);return s.set(o,c),c};for(let o of e.files){if(x(o))continue;let a=e.outgoing.get(o)||new Set,l=r(o);for(let c of a){if(!e.files.has(c)||x(c))continue;let u=r(c),d=u-l;if(d>n&&l<i){let f=ve(e,o,c);t.push({severity:d>.3?"high":"medium",category:"architecture-sdp-violation",file:o,lineStart:f.lineStart,lineEnd:f.lineEnd,title:"SDP violation: stable module depends on unstable module",reason:`"${o}" (I=${l.toFixed(2)}) depends on "${c}" (I=${u.toFixed(2)}). Delta=${d.toFixed(2)}.`,files:[o,c],suggestedFix:{strategy:"Invert dependency via interface/abstraction or move shared code to a stable utility.",steps:["Extract a stable interface that the stable module depends on.","Have the unstable module implement that interface.","Consider moving shared logic to a lower-instability utility module."]},impact:"Prevents cascading instability and reduces change propagation risk.",tags:["stability","coupling","architecture","sdp"]})}}}return t}function dn(e,n=15){let i=[];for(let t of e.files){if(x(t))continue;let s=(e.incoming.get(t)||new Set).size,r=(e.outgoing.get(t)||new Set).size,o=s+r;o>n&&i.push({severity:o>25?"high":"medium",category:"high-coupling",file:t,lineStart:1,lineEnd:1,title:`High coupling: ${t}`,reason:`Module has ${o} total connections (Ca=${s}, Ce=${r}). Threshold: ${n}.`,files:[t],suggestedFix:{strategy:"Reduce coupling by extracting interfaces or splitting module responsibilities.",steps:["Identify groups of related imports/dependents that can be isolated.","Extract focused sub-modules with single responsibilities.","Use dependency inversion to reduce direct coupling."]},impact:"Lower coupling reduces change ripple effects and improves testability.",tags:["coupling","change-risk","architecture"]})}return i}function un(e,n=20,i=15){let t=[];for(let s of e.files){if(x(s))continue;let r=(e.incoming.get(s)||new Set).size,o=(e.outgoing.get(s)||new Set).size;r>n&&t.push({severity:r>n*1.5?"high":"medium",category:"god-module-coupling",file:s,lineStart:1,lineEnd:1,title:`High fan-in bottleneck: ${s}`,reason:`Module is depended on by ${r} modules (threshold: ${n}). Changes ripple widely.`,files:[s],suggestedFix:{strategy:"Split this module into focused sub-modules to reduce blast radius.",steps:["Identify distinct groups of consumers using different parts of this module.","Extract each group into a dedicated module.","Update import paths incrementally."]},impact:"Reduces change blast radius and improves parallel development.",tags:["coupling","blast-radius","bottleneck"]}),o>i&&t.push({severity:o>i*1.5?"high":"medium",category:"god-module-coupling",file:s,lineStart:1,lineEnd:1,title:`High fan-out: ${s}`,reason:`Module depends on ${o} modules (threshold: ${i}). It may violate single responsibility.`,files:[s],suggestedFix:{strategy:"Reduce dependencies by introducing facade or mediator patterns.",steps:["Group related imports behind a single facade module.","Consider splitting this module by responsibility.","Use dependency injection to reduce direct coupling."]},impact:"Cleaner architecture and easier testing through reduced dependencies.",tags:["coupling","responsibility","sprawl"]})}return t}function fn(e,n){if(n.length<2)return[];let i=[],t=s=>{for(let r=0;r<n.length;r++)if(s.includes(n[r]))return r;return-1};for(let s of e.files){if(x(s))continue;let r=t(s);if(r!==-1)for(let o of e.outgoing.get(s)||new Set){if(!e.files.has(o)||x(o))continue;let a=t(o);if(a!==-1&&a<r){let l=ve(e,s,o);i.push({severity:"high",category:"layer-violation",file:s,lineStart:l.lineStart,lineEnd:l.lineEnd,title:`Layer violation: ${n[r]} imports from ${n[a]}`,reason:`"${s}" (layer: ${n[r]}) imports "${o}" (layer: ${n[a]}). Layer order: ${n.join(" \u2192 ")}.`,files:[s,o],suggestedFix:{strategy:"Respect layer boundaries by inverting the dependency or moving shared logic.",steps:["Extract shared contracts to a lower layer that both can depend on.","Use dependency inversion: define an interface in the lower layer, implement in higher.","If the dependency is justified, reconsider your layer boundaries."]},impact:"Prevents architectural erosion and keeps dependency flow unidirectional.",tags:["architecture","layering","coupling"]})}}}return i}function Cs(e){return e.length===0?0:e.filter(i=>i.kind==="type").length/e.length}function pn(e,n=.7,i=3){let t=[];for(let s of e.files){if(x(s))continue;let r=e.declaredExportsByFile.get(s);if(!r||r.length===0)continue;let o=(e.incoming.get(s)||new Set).size,a=(e.outgoing.get(s)||new Set).size;if(o+a<i)continue;let l=ln(o,a),c=Cs(r),u=Math.abs(c+l-1);if(u<n)continue;let d=c<.2&&l<.3,f=c>.7&&l>.7,p="";if(d?p="Zone of Pain (concrete + stable): hard to extend, painful to change.":f?p="Zone of Uselessness (abstract + unstable): over-abstracted and unused.":p="Far from Main Sequence: balance between abstraction and stability is off.",!G(t))break;t.push({severity:u>.85?"high":"medium",category:"distance-from-main-sequence",file:s,lineStart:1,lineEnd:1,title:`Distance from Main Sequence: ${s} (D=${u.toFixed(2)})`,reason:`${p} A=${c.toFixed(2)}, I=${l.toFixed(2)}, D=${u.toFixed(2)} (threshold: ${n}).`,files:[s],suggestedFix:{strategy:d?"Add abstractions (interfaces/types) or reduce inbound coupling.":f?"Add concrete implementations or remove unused abstractions.":"Rebalance by adjusting abstraction level or dependency direction.",steps:d?["Extract interfaces for key behaviors to increase abstractness.","Consider splitting into abstract contracts + concrete implementations.","Reduce inbound coupling by narrowing the public API surface."]:f?["Verify abstractions have concrete implementations.","Remove unused interfaces/types that serve no consumer.","Consider consolidating with concrete modules."]:["Review the balance between interfaces/types and concrete exports.","Adjust dependency direction to move closer to the Main Sequence.","Consider splitting responsibilities between abstract and concrete modules."]},impact:"Modules on the Main Sequence (D\u22480) have optimal balance between stability and extensibility.",tags:["architecture","stability","abstractness","sdp"]})}return t}var Ts=N(()=>{"use strict";ge();ge();W()});function gn(e,n,i=500,t=20){let s=[];for(let r of e){if(x(r.file))continue;let o=r.functions.reduce((c,u)=>c+u.statementCount,0),a=(n.declaredExportsByFile.get(r.file)||[]).length,l=[];if(o>i&&l.push(`${o} statements (threshold: ${i})`),a>t&&l.push(`${a} exports (threshold: ${t})`),l.length!==0){if(!G(s))break;s.push({severity:"high",category:"god-module",file:r.file,lineStart:1,lineEnd:1,title:`God module: ${r.file}`,reason:`Module is excessively large: ${l.join("; ")}.`,files:[r.file],suggestedFix:{strategy:"Split module into focused sub-modules with single responsibilities.",steps:["Identify distinct functional groups within the module.","Extract each group into a dedicated module.","Create a barrel if backward compatibility is needed.","Update imports incrementally."]},impact:"Smaller modules are easier to understand, test, and maintain.",tags:["complexity","responsibility","size"],lspHints:[{tool:"lspFindReferences",symbolName:r.file.split("/").pop()||r.file,lineHint:1,file:r.file,expectedResult:"identify consumer clusters to guide module splitting strategy"}]})}}return s}function Ro(e){let n=e.replace(/\\/g,"/"),i=n.lastIndexOf("/");return i===-1?".":n.slice(0,i)}function mn(e,n=25,i=.25){let t=[],s=e.filter(a=>!x(a.file));if(s.length===0)return t;let r=new Map;for(let a of s){let l=Ro(a.file);r.has(l)||r.set(l,[]),r.get(l).push(a)}let o=[...r.entries()].map(([a,l])=>({folder:a,entries:l,count:l.length})).filter(({count:a})=>a>=n&&a/s.length>=i).sort((a,l)=>l.count-a.count);for(let a of o){let l=a.count/s.length,c=l>=.5||a.count>=50?"high":"medium",u=a.entries.map(f=>f.file).sort().slice(0,8),d=a.entries[0]?.file??a.folder;if(!G(t))break;t.push({severity:c,category:"mega-folder",file:d,lineStart:1,lineEnd:1,title:`Mega folder: ${a.folder} (${a.count} files)`,reason:`${a.folder} contains ${a.count} production files (${(l*100).toFixed(1)}% of the codebase), which usually indicates mixed responsibilities and weak module boundaries.`,files:u,suggestedFix:{strategy:"Map the import graph, identify domain clusters, then restructure with an automated migration script.",steps:["Extract the local import graph (rg/localSearchCode) and group files into clusters by what imports what.","Design target directories that follow the data flow (e.g., types \u2192 parsing \u2192 analysis \u2192 detection \u2192 reporting \u2192 orchestration).","Write a disposable migration script that maps old basenames to { dir, name } targets, moves files, and rewrites all relative import paths atomically.","Validate after each phase: tsc --noEmit, eslint --fix, test suite.","Move shared primitives into a dedicated common/ folder to avoid cross-domain coupling."]},impact:"Improves navigability, ownership boundaries, and change isolation.",tags:["architecture","modularity","folder-structure","maintainability"],evidence:{folderPath:a.folder,fileCount:a.count,totalProductionFiles:s.length,concentration:l},lspHints:[{tool:"lspGotoDefinition",symbolName:a.folder,lineHint:1,file:d,expectedResult:"inventory representative modules in this folder before planning decomposition"}]})}return t}function hn(e,n=100,i=10){let t=[];for(let r of e)if(!x(r.file))for(let o of r.functions){let a=o.statementCount>n,l=o.maintainabilityIndex!==void 0&&o.maintainabilityIndex<i&&o.lengthLines>30;if(a||l){let c=l&&o.maintainabilityIndex!==void 0?` MI=${o.maintainabilityIndex.toFixed(1)} (threshold: ${i}).`:"",u=a?`${o.statementCount} statements (threshold: ${n}).`:"";t.push({severity:"high",category:"god-function",file:r.file,lineStart:o.lineStart,lineEnd:o.lineEnd,title:`God function: ${o.name}`,reason:`Function "${o.name}" triggers god-function detection. ${u}${c}`.trim(),files:[`${r.file}:${o.lineStart}-${o.lineEnd}`],suggestedFix:{strategy:"Break down into smaller, focused functions.",steps:["Identify logical steps within the function.","Extract each step into a named helper.","Keep the original as a high-level orchestrator.","Test each extracted function independently."]},impact:"Improves readability, testability, and maintenance.",tags:["complexity","responsibility","size"],lspHints:[{tool:"lspCallHierarchy",symbolName:o.name,lineHint:o.lineStart,file:r.file,expectedResult:`map callers and callees to identify safe extraction boundaries for ${o.name}`}]})}}return t}function yn(e,n=3){let i=[];for(let t of e.files){if(x(t)||de(t))continue;let s=e.declaredExportsByFile.get(t);if(!s||s.length<n)continue;let r=new Set(s.map(d=>d.name)),o=new Map;for(let[d,f]of e.importedSymbolsByFile.entries())for(let p of f)p.resolvedModule===t&&r.has(p.importedName)&&(o.has(p.importedName)||o.set(p.importedName,new Set),o.get(p.importedName).add(d));let a=[...o.keys()];if(a.length<2)continue;let l=new Map;for(let d of a)l.set(d,new Set);for(let d of e.importedSymbolsByFile.values()){let f=d.filter(p=>p.resolvedModule===t&&r.has(p.importedName)).map(p=>p.importedName);for(let p=0;p<f.length;p++)for(let g=p+1;g<f.length;g++)l.get(f[p])?.add(f[g]),l.get(f[g])?.add(f[p])}let c=new Set,u=0;for(let d of a){if(c.has(d))continue;u++;let f=[d];for(;f.length>0;){let p=f.pop();if(!c.has(p)){c.add(p);for(let g of l.get(p)||[])c.has(g)||f.push(g)}}}u>1&&i.push({severity:u>=4?"high":"medium",category:"low-cohesion",file:t,lineStart:1,lineEnd:1,title:`Low cohesion: ${t} (LCOM=${u})`,reason:`Module exports ${a.length} consumed symbols that form ${u} independent groups. Consumers never import symbols across groups \u2014 the module serves unrelated purposes.`,files:[t],suggestedFix:{strategy:`Split into ${u} focused modules, one per cohesion group.`,steps:["Identify which exports belong to each independent group.","Create a new module for each group with a descriptive name.","Move exports and their dependencies to the appropriate module.","Update consumer imports to point to the new modules."]},impact:"Higher cohesion = easier navigation, focused testing, and smaller change blast radius.",tags:["cohesion","responsibility","architecture"]})}return i}function Oe(e,n,i,t=20){let s=new Set;for(let a of n.cycles)for(let l of a.path)s.add(l);let r=new Set;for(let a of n.criticalPaths)for(let l of a.path)r.add(l);let o=[];for(let a of e.files){if(x(a))continue;let l=(e.incoming.get(a)||new Set).size,c=(e.outgoing.get(a)||new Set).size,d=i.get(a)?.score??0,f=(e.declaredExportsByFile.get(a)||[]).length,p=s.has(a),g=r.has(a),m=Math.round(l*3+d*.5+f*1.5+c*.5+(p?20:0)+(g?10:0));m>0&&o.push({file:a,riskScore:m,fanIn:l,fanOut:c,complexityScore:d,exportCount:f,inCycle:p,onCriticalPath:g})}return o.sort((a,l)=>l.riskScore-a.riskScore),o.slice(0,t)}function Sn(e,n,i,t=40){let s=[],r=new Set,o=l=>{let c=e.incomingFromTests.get(l);return!!c&&c.size>0},a=(l,c,u)=>{if(r.has(l)||(r.add(l),x(l))||o(l))return;let d=c>=60;G(s)&&s.push({severity:d?"critical":"high",category:"untested-critical-code",file:l,lineStart:1,lineEnd:1,title:`Untested critical code: ${l}`,reason:`High-risk file has no test imports. ${u.join("; ")} (risk score: ${c}).`,files:[l],suggestedFix:{strategy:"Add test coverage for this critical module.",steps:["Create a test file that imports and exercises the public API of this module.","Focus on the highest-complexity functions and exported behaviors first.","Add integration tests if this module sits on a critical dependency path.","Consider property-based tests for complex data transformations."]},impact:"Untested critical code is the highest-risk area for regressions and undetected bugs.",tags:["testing","coverage","change-risk","critical"]})};for(let l of n){let c=[];c.push(`fan-in=${l.fanIn}, fan-out=${l.fanOut}, complexity=${l.complexityScore}`),l.inCycle&&c.push("in dependency cycle"),l.onCriticalPath&&c.push("on critical dependency path"),a(l.file,l.riskScore,c)}for(let[l,c]of i){if(c.score<t)continue;let u=[`high complexity score (${c.score}), ${c.highComplexityFunctions} high-complexity functions`];a(l,c.score,u)}return s.sort((l,c)=>{let u={critical:4,high:3,medium:2,low:1,info:0};return(u[c.severity]||0)-(u[l.severity]||0)}),s.slice(0,25)}function bn(e,n=.6,i=5){let t=[];for(let[s,r]of e.importedSymbolsByFile.entries()){if(x(s)||!e.files.has(s))continue;let o=r.filter(l=>l.resolvedModule&&!l.isTypeOnly);if(o.length<i)continue;let a=new Map;for(let l of o)l.resolvedModule&&a.set(l.resolvedModule,(a.get(l.resolvedModule)||0)+1);for(let[l,c]of a){let u=c/o.length;if(u>=n&&c>=i){let d=ve(e,s,l);t.push({severity:u>.8?"high":"medium",category:"feature-envy",file:s,lineStart:d.lineStart,lineEnd:d.lineEnd,title:`Feature envy: ${s} \u2192 ${l}`,reason:`Module imports ${c}/${o.length} symbols (${(u*100).toFixed(0)}%) from "${l}". This suggests the logic may belong in or closer to the target module.`,files:[s,l],suggestedFix:{strategy:"Move dependent logic to the target module or extract a shared module.",steps:["Identify which functions/logic in this file use the imported symbols.","Move that logic to the target module if it belongs there.","If shared, extract a dedicated module that both can import from.","Reduce the import surface by passing data instead of importing behaviors."]},impact:"Misplaced logic increases coupling and makes changes ripple across module boundaries.",tags:["coupling","responsibility","misplaced-logic"],lspHints:[{tool:"lspCallHierarchy",symbolName:s.split("/").pop()||s,lineHint:d.lineStart,file:s,expectedResult:`trace which functions use imports from ${l} to decide what to move`},{tool:"lspGotoDefinition",symbolName:l.split("/").pop()||l,lineHint:d.lineStart,file:s,expectedResult:"inspect target module to evaluate if logic belongs there"}]})}}}return t}var $s=N(()=>{"use strict";ge();ge();W()});function xn(e,n,i=new Set){if(i.has(e))return 0;i.add(e);let t=n.reExportsByFile.get(e);if(!t||t.length===0)return 0;let s=0;for(let r of t){let o=r.resolvedModule;if(!o)continue;let a=n.reExportsByFile.get(o);a&&a.length>0&&(s=Math.max(s,xn(o,n,i)))}return 1+s}function En(e,n=30){let i=[];for(let[t,s]of e.reExportsByFile.entries()){if(x(t)||s.length===0)continue;s.length>n&&i.push({severity:s.length>n*2?"high":"medium",category:"barrel-explosion",file:t,lineStart:1,lineEnd:1,title:`Barrel explosion: ${t}`,reason:`Barrel re-exports ${s.length} symbols (threshold: ${n}). Large barrels hurt bundling.`,files:[t],suggestedFix:{strategy:"Split barrel or use direct imports to reduce bundler cost.",steps:["Group re-exports by domain into sub-barrels.","Let consumers import directly from source modules.","Remove unused re-exports (check dead-re-export findings)."]},impact:"Reduces bundle size and speeds up IDE/tooling.",tags:["barrel","bundle-size","tree-shaking"]});let r=xn(t,e);r>2&&i.push({severity:"high",category:"barrel-explosion",file:t,lineStart:1,lineEnd:1,title:`Deep barrel chain: ${t} (depth ${r})`,reason:`Barrel chain is ${r} levels deep. Deep chains defeat tree-shaking.`,files:[t],suggestedFix:{strategy:"Flatten barrel chain to at most 2 levels.",steps:["Re-export directly from source modules instead of intermediate barrels.","Remove intermediate barrel layers that add no value."]},impact:"Improves tree-shaking efficiency and import resolution speed.",tags:["barrel","bundle-size","tree-shaking"]})}return i}function vn(e,n,i,t){let s=[],r=new Set;for(let l of i.cycles)for(let c of l.path)r.add(c);let o=new Set;for(let l of i.criticalPaths)for(let c of l.path)o.add(c);let a=new Map;for(let l of t)a.set(l.file,l);for(let l of e){if(x(l.file))continue;let c=l.topLevelEffects;if(!c||c.length===0)continue;let u=0;for(let C of c)u+=C.weight;let d=(n.incoming.get(l.file)||new Set).size,f=0;d>=20?f+=8:d>=8&&(f+=4),o.has(l.file)&&(f+=6),r.has(l.file)&&(f+=3);let p=0;de(l.file)&&(p+=4);let g=u+f-p;if(g<4)continue;let m=g>=18?"critical":g>=12?"high":g>=7?"medium":"low",h=c.filter(C=>C.confidence==="high").length>0?"high":c.some(C=>C.confidence==="medium")?"medium":"low",y=c.map(C=>`${C.detail} (line ${C.lineStart})`).join("; "),D=[];d>=8&&D.push(`fan-in=${d}`),o.has(l.file)&&D.push("on critical path"),r.has(l.file)&&D.push("in dependency cycle"),de(l.file)&&D.push("entrypoint (discounted)");let b=D.length>0?` Architecture context: ${D.join(", ")}.`:"",k=c[0];if(!G(s))break;s.push({severity:m,category:"import-side-effect-risk",file:l.file,lineStart:k.lineStart,lineEnd:k.lineEnd,title:`Import-time side effect${c.length>1?`s (${c.length})`:""}: ${l.file}`,reason:`Module executes work at import time: ${y}. Risk score: ${g} (ast=${u}, impact=+${f}, role=-${p}). Confidence: ${h}.${b}`,files:[l.file],suggestedFix:{strategy:"Move import-time side effects behind explicit initialization or lazy loading.",steps:["Wrap startup logic in an exported init() function instead of running at module scope.","Replace synchronous I/O with async alternatives called at runtime.","Guard side-effect imports with dynamic import() behind feature checks.","If this is an intentional entrypoint, consider adding a suppression comment."]},impact:`Importing this module triggers ${c.length} side effect(s). With fan-in=${d}, unintended imports can degrade startup latency and cause surprising runtime behavior.`,tags:["import-side-effect","startup","architecture","performance"],lspHints:[{tool:"lspFindReferences",symbolName:l.file.split("/").pop()?.replace(/\.[^.]+$/,"")||l.file,lineHint:1,file:l.file,expectedResult:"find all modules that import this file and may trigger side effects"}]})}return s}function wn(e){let n=[];for(let[i,t]of e.importedSymbolsByFile.entries())if(!x(i))for(let s of t){if(s.importedName!=="*"||s.isTypeOnly||s.localName==="require")continue;let r=s.resolvedModule!=null,o=r?(e.incoming.get(s.resolvedModule)||new Set).size:0;n.push({severity:r&&o>5?"high":"medium",category:"namespace-import",file:i,lineStart:s.lineStart||1,lineEnd:s.lineEnd||s.lineStart||1,title:`Namespace import blocks tree-shaking: import * as ${s.localName}`,reason:`\`import * as ${s.localName} from '${s.sourceModule}'\` forces bundlers to include the entire module. Named imports allow dead-code elimination of unused exports.${r?` Target module has fan-in=${o}.`:""}`,files:[`${i}:${s.lineStart||1}-${s.lineEnd||s.lineStart||1}`],suggestedFix:{strategy:"Replace namespace import with named imports for used symbols.",steps:[`Find which properties of \`${s.localName}\` are actually accessed in this file.`,`Replace \`import * as ${s.localName}\` with \`import { usedA, usedB } from '${s.sourceModule}'\`.`,"If many properties are used, consider splitting the source module into smaller modules."]},impact:"Enables bundlers to tree-shake unused exports, reducing bundle size.",tags:["tree-shaking","bundle-size","namespace-import"]})}return n}function Fn(e){let n=[];for(let[i,t]of e.importedSymbolsByFile.entries()){if(x(i))continue;let s=t.filter(a=>a.localName==="require"&&!a.isTypeOnly);if(s.length===0)continue;let r=t.some(a=>a.localName!=="require"),o=r?"high":"medium";for(let a of s)n.push({severity:o,category:r?"mixed-module-format":"commonjs-in-esm",file:i,lineStart:a.lineStart||1,lineEnd:a.lineEnd||a.lineStart||1,title:r?`Mixed ESM/CJS: require('${a.sourceModule}') in ESM file`:`CommonJS require blocks tree-shaking: require('${a.sourceModule}')`,reason:r?`File uses both ESM \`import\` and CJS \`require()\`. Mixed formats force bundlers to treat the module as CJS, disabling tree-shaking entirely. Found ${s.length} require() call(s).`:`\`require('${a.sourceModule}')\` is a CommonJS pattern that bundlers cannot statically analyze. ESM \`import\` enables tree-shaking.`,files:[`${i}:${a.lineStart||1}-${a.lineEnd||a.lineStart||1}`],suggestedFix:{strategy:"Convert require() to ESM import.",steps:[`Replace \`const mod = require('${a.sourceModule}')\` with \`import mod from '${a.sourceModule}'\` or named imports.`,"If the require is conditional, use dynamic `import()` instead.",'Ensure the target module supports ESM (check package.json "type" or "module" field).']},impact:"ESM imports enable tree-shaking; CJS requires pull the entire module.",tags:["tree-shaking","bundle-size","commonjs","module-format"]})}return n}function kn(e){let n=[];for(let[i,t]of e.reExportsByFile.entries()){if(x(i))continue;let s=t.filter(r=>r.isStar&&!r.isTypeOnly);if(s.length!==0)for(let r of s){let o=r.resolvedModule?(e.declaredExportsByFile.get(r.resolvedModule)||[]).length:0,a=r.resolvedModule?(e.reExportsByFile.get(r.resolvedModule)||[]).some(c=>c.isStar):!1,l=a||o>20?"high":"medium";n.push({severity:l,category:"export-star-leak",file:i,lineStart:r.lineStart||1,lineEnd:r.lineEnd||r.lineStart||1,title:`export * leaks entire module surface: ${r.sourceModule}`,reason:`\`export * from '${r.sourceModule}'\` re-exports every symbol from the source, defeating granular tree-shaking.${o>0?` Target exports ${o} symbols.`:""}${a?" Target itself contains export-star chains, amplifying the leak.":""}`,files:[`${i}:${r.lineStart||1}-${r.lineEnd||r.lineStart||1}`],suggestedFix:{strategy:"Replace export * with explicit named re-exports.",steps:[`List the symbols actually consumed from \`${r.sourceModule}\` by downstream modules.`,`Replace \`export * from '${r.sourceModule}'\` with \`export { A, B, C } from '${r.sourceModule}'\`.`,"This lets bundlers eliminate unused re-exports during tree-shaking."]},impact:"Explicit re-exports enable precise tree-shaking and make the public API surface visible.",tags:["tree-shaking","bundle-size","export-star","api-surface"]})}}return n}var Ds=N(()=>{"use strict";ge();ge();W()});function Cn(e){let n=new Map,i=new Map;for(let[t,s]of e.importedSymbolsByFile.entries()){let r=x(t)?i:n;for(let o of s){let a=o.resolvedModule;a&&(r.has(a)||r.set(a,new Set),r.get(a).add(o.importedName))}}for(let[t,s]of e.reExportsByFile.entries()){let r=x(t)?i:n;for(let o of s){let a=o.resolvedModule;a&&(r.has(a)||r.set(a,new Set),r.get(a).add(o.importedName))}}return{production:n,test:i}}function Tn(e,n,i){let t=[];for(let[s,r]of e.declaredExportsByFile.entries()){if(x(s)||de(s))continue;let o=n.get(s)||new Set,a=i?.get(s)||new Set,l=o.has("*"),c=a.has("*");for(let u of r)u.name==="default"&&de(s)||l||o.has(u.name)||c||a.has(u.name)||t.push({severity:u.kind==="type"?"medium":"high",category:"dead-export",file:s,lineStart:u.lineStart||1,lineEnd:u.lineEnd||u.lineStart||1,title:`Unused export: ${u.name}`,reason:`Exported symbol "${u.name}" has no observed import or re-export usage in production or test files.`,files:[`${s}:${u.lineStart||1}-${u.lineEnd||u.lineStart||1}`],suggestedFix:{strategy:"Remove or internalize unused exports.",steps:["Confirm symbol is not part of intentional public API surface.","Remove export modifier or delete symbol if truly unused.","Re-run scan and tests to ensure no hidden runtime usage."]},impact:"Shrinks public API surface and reduces accidental coupling.",tags:["dead-code","api-surface","cleanup"],lspHints:[{tool:"lspFindReferences",symbolName:u.name,lineHint:u.lineStart||1,file:s,expectedResult:`confirm "${u.name}" has no import references before removing`}]})}return t}function $n(e,n){let i=[];for(let[t,s]of e.reExportsByFile.entries()){if(x(t))continue;let r=n.get(t)||new Set,o=r.has("*"),a=new Map,l=new Set((e.declaredExportsByFile.get(t)||[]).map(c=>c.name));for(let c of s){let u=c.exportedAs;a.has(u)||a.set(u,new Set),a.get(u).add(c.resolvedModule||c.sourceModule),o||r.has(u)||c.isStar&&r.size>0||i.push({severity:"medium",category:"dead-re-export",file:t,lineStart:c.lineStart||1,lineEnd:c.lineEnd||c.lineStart||1,title:`Unused re-export: ${u}`,reason:`Re-exported symbol "${u}" from ${c.sourceModule} has no observed downstream imports from this module.`,files:[`${t}:${c.lineStart||1}-${c.lineEnd||c.lineStart||1}`],suggestedFix:{strategy:"Remove stale barrel re-exports.",steps:["Verify no dynamic import/runtime reflection depends on this export.","Remove the re-export clause.","Re-run scan to confirm barrel surface is still complete."]},impact:"Keeps barrel modules focused and easier to reason about.",tags:["dead-code","barrel","cleanup"]})}for(let[c,u]of a.entries())u.size>1&&i.push({severity:"medium",category:"re-export-duplication",file:t,lineStart:1,lineEnd:1,title:`Duplicate re-export paths: ${c}`,reason:`Symbol "${c}" is re-exported from multiple sources in the same barrel.`,files:[t],suggestedFix:{strategy:"Keep one canonical re-export source per symbol.",steps:["Select a canonical module for the symbol.","Remove duplicate re-export paths.","Document intended public export map for the barrel."]},impact:"Reduces API ambiguity and import inconsistency.",tags:["duplication","barrel","api-surface"]}),c!=="*"&&l.has(c)&&i.push({severity:"high",category:"re-export-shadowed",file:t,lineStart:1,lineEnd:1,title:`Shadowed export in barrel: ${c}`,reason:`Barrel exports "${c}" both locally and through re-export, which can hide origin and create ambiguity.`,files:[t],suggestedFix:{strategy:"Disambiguate local vs re-exported symbol ownership.",steps:["Pick a single source of truth for the symbol in this barrel.","Rename or remove the conflicting export path.","Update import call-sites to use the canonical export."]},impact:"Prevents subtle API conflicts and shadowing confusion.",tags:["barrel","api-surface","ambiguity"]})}return i}function Dn(e,n,i={}){let t=[],s=new Set;for(let r of e.values())for(let o of r){let a=o.split("/");s.add(o.startsWith("@")&&a.length>=2?`${a[0]}/${a[1]}`:a[0])}for(let r of Object.keys(n))s.has(r)||t.push({severity:"medium",category:"unused-npm-dependency",file:"package.json",lineStart:1,lineEnd:1,title:`Unused dependency: ${r}`,reason:`Package "${r}" is in dependencies but no import was found.`,files:["package.json"],suggestedFix:{strategy:"Remove unused dependency from package.json.",steps:["Verify the package is not loaded dynamically or via CLI scripts.","Check if it is a peer dependency required at runtime.","Run `npm uninstall` or remove from package.json."]},impact:"Reduces install size and attack surface.",tags:["dependency","hygiene","bundle-size"]});for(let r of Object.keys(i))s.has(r)||t.push({severity:"low",category:"unused-npm-dependency",file:"package.json",lineStart:1,lineEnd:1,title:`Unused devDependency: ${r}`,reason:`Package "${r}" is in devDependencies but no import was found.`,files:["package.json"],suggestedFix:{strategy:"Remove unused devDependency from package.json.",steps:["Verify the package is not used by build scripts, config files, or CLI tools.","Run `npm uninstall` or remove from package.json."]},impact:"Reduces install size and dependency maintenance burden.",tags:["dependency","hygiene","dev-tooling"]});return t}function Rn(e){let n=[];for(let i of e.files){if(x(i))continue;let t=i.match(/^packages\/([^/]+)\//);if(!t)continue;let s=t[1];for(let r of e.outgoing.get(i)||new Set){let o=r.match(/^packages\/([^/]+)\//);if(!o||o[1]===s)continue;if(!/^packages\/[^/]+\/(src\/)?index\.[mc]?[jt]sx?$/.test(r)){let l=r.includes("/internal/")||r.includes("/private/"),c=ve(e,i,r);n.push({severity:l?"high":"medium",category:"package-boundary-violation",file:i,lineStart:c.lineStart,lineEnd:c.lineEnd,title:"Cross-package import bypasses public API",reason:`"${i}" imports "${r}" directly instead of through the package public entry.`,files:[i,r],suggestedFix:{strategy:"Import through the package public API (index file).",steps:["Re-export the needed symbol from the target package index.","Update the import to use the package name or index path.","If the symbol is internal, reconsider the dependency."]},impact:"Enforces clean package boundaries and prevents coupling to internals.",tags:["boundary","coupling","encapsulation"]})}}}return n}var Rs=N(()=>{"use strict";ge();W()});import*as ne from"typescript";function An(e){let n=[];for(let i of e){let t=i.locations[0],s=`Same ${i.kind} body shape appears in ${i.occurrences} places (${i.filesCount} file${i.filesCount>1?"s":""}).`,r=i.occurrences>=6?"high":i.occurrences>=3?"medium":"low";if(!G(n))break;n.push({...t,severity:r,category:"duplicate-function-body",title:`Deduplicate function body: ${i.signature}`,reason:s,files:i.locations.map(o=>`${o.file}:${o.lineStart}-${o.lineEnd}`),suggestedFix:{strategy:"Create a shared helper function once and replace duplicate call sites.",steps:["Extract one function to a dedicated utility module.","Keep behavior unchanged by passing function-specific differences as params.","Replace duplicated blocks with calls to the shared helper.","Add/extend tests around each entry point that previously used duplicates."]},impact:"Lower maintenance cost and reduce regression risk when behavior changes.",tags:["duplication","maintainability","dryness"],lspHints:[{tool:"lspGotoDefinition",symbolName:i.signature,lineHint:t.lineStart,file:t.file,expectedResult:"navigate to one instance to compare implementations side-by-side"}]})}return n}function Mn(e,n){let i=[];for(let t of e){if(t.occurrences<n)continue;let s=t.locations[0],r=`${t.kind} structure appears ${t.occurrences} times across ${t.filesCount} file(s).`,o=t.occurrences>=10?"high":"medium";if(!G(i))break;i.push({...s,severity:o,category:"duplicate-flow-structure",title:`Extract repeated flow structure: ${t.kind}`,reason:r,files:t.locations.map(a=>`${a.file}:${a.lineStart}-${a.lineEnd}`),suggestedFix:{strategy:"Extract a reusable flow helper around the repeated structure.",steps:["Create one clear helper that accepts varying inputs as parameters.","Call helper from each repeated site.","Keep variable names aligned and add local adapter logic where needed.","Document expected invariants for the shared flow."]},impact:"Reduces duplicate control branches and normalizes edge-case handling.",tags:["duplication","control-flow","dryness"]})}return i}function Pn(e,n){let i=[];for(let t of e)for(let s of t.functions){let r=[];if(s.complexity>=n&&r.push(`Cyclomatic-like complexity is high (>=${n}).`),s.maxBranchDepth>=7&&r.push("Branch depth is very deep and hard to reason about."),s.maxLoopDepth>=4&&r.push("Nested loops are high and likely expensive."),s.statementCount>=24&&r.push("Function body is large and may be doing multiple responsibilities."),r.length===0)continue;let o=s.complexity>=n||s.maxBranchDepth>=7||s.maxLoopDepth>=4;i.push({...s,severity:o?"high":"medium",category:"function-optimization",title:`Potential function refactor: ${s.name}`,reason:r.join(" "),files:[`${s.file}:${s.lineStart}-${s.lineEnd}`],suggestedFix:{strategy:"Refactor for readability and testability.",steps:["Split into smaller subroutines with single responsibilities.","Convert deeply nested branches into guard clauses when safe.","Replace loops with intent-specific helpers if one loop owns most lines.","Add unit coverage for each extracted piece before deleting old logic."]},impact:"Cleaner flow, easier review and safer refactors.",tags:["complexity","readability","refactor"],lspHints:[{tool:"lspCallHierarchy",symbolName:s.name,lineHint:s.lineStart,file:s.file,expectedResult:`inspect callers and callees to plan safe decomposition of ${s.name}`}]})}return i}function In(e){let n=0,i=(t,s)=>{let r=0,o=!1;switch(t.kind){case ne.SyntaxKind.IfStatement:case ne.SyntaxKind.ForStatement:case ne.SyntaxKind.ForInStatement:case ne.SyntaxKind.ForOfStatement:case ne.SyntaxKind.WhileStatement:case ne.SyntaxKind.DoStatement:case ne.SyntaxKind.CatchClause:case ne.SyntaxKind.ConditionalExpression:case ne.SyntaxKind.SwitchStatement:r=1,o=!0;break;default:break}if(t.kind===ne.SyntaxKind.BinaryExpression&&(t.operatorToken.kind===ne.SyntaxKind.AmpersandAmpersandToken||t.operatorToken.kind===ne.SyntaxKind.BarBarToken||t.operatorToken.kind===ne.SyntaxKind.QuestionQuestionToken)&&(r=1),t.kind===ne.SyntaxKind.IfStatement&&t.parent&&ne.isIfStatement(t.parent)&&t.parent.elseStatement===t&&(r=1,o=!1),o){n+=r+s,ne.forEachChild(t,a=>i(a,s+1));return}n+=r,ne.forEachChild(t,a=>i(a,s))};return i(e,0),n}function Nn(e,n=15){let i=[];for(let t of e)if(!x(t.file))for(let s of t.functions)s.cognitiveComplexity>n&&i.push({severity:s.cognitiveComplexity>25?"high":"medium",category:"cognitive-complexity",file:t.file,lineStart:s.lineStart,lineEnd:s.lineEnd,title:`High cognitive complexity: ${s.name} (${s.cognitiveComplexity})`,reason:`Function cognitive complexity is ${s.cognitiveComplexity} (threshold: ${n}). Nested branches compound reading difficulty.`,files:[`${t.file}:${s.lineStart}-${s.lineEnd}`],suggestedFix:{strategy:"Reduce nesting and simplify control flow.",steps:["Convert nested branches into early returns / guard clauses.","Extract deeply nested blocks into named helper functions.","Replace complex boolean chains with named predicates."]},impact:"Lower cognitive complexity directly correlates with fewer bugs and faster code reviews.",tags:["complexity","readability","nesting"],lspHints:[{tool:"lspCallHierarchy",symbolName:s.name,lineHint:s.lineStart,file:t.file,expectedResult:`understand call graph before simplifying ${s.name}`}]});return i}function Ln(e,n=5){let i=[];for(let t of e)if(!x(t.file))for(let s of t.functions)s.params==null||s.params<=n||i.push({severity:s.params>7?"high":"medium",category:"excessive-parameters",file:t.file,lineStart:s.lineStart,lineEnd:s.lineEnd,title:`Excessive parameters: ${s.name} (${s.params} params)`,reason:`Function has ${s.params} parameters (threshold: ${n}). High parameter counts make call sites hard to read and signal the function may be doing too much.`,files:[`${t.file}:${s.lineStart}-${s.lineEnd}`],suggestedFix:{strategy:"Introduce a parameter object or split the function.",steps:["Group related parameters into an options/config object.","Use destructuring at the function signature for clarity.","Consider splitting into smaller, focused functions if params serve different concerns."]},impact:"Improves call-site readability and makes the API easier to evolve.",tags:["api-design","readability","refactor"]});return i}function On(e){let n=[];for(let i of e)if(!x(i.file)&&!(!i.emptyCatches||i.emptyCatches.length===0))for(let t of i.emptyCatches)n.push({severity:"medium",category:"empty-catch",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:"Empty catch block silently swallows errors",reason:`Catch block at line ${t.lineStart} has no statements \u2014 errors are silently ignored.`,files:[`${i.file}:${t.lineStart}-${t.lineEnd}`],suggestedFix:{strategy:"Log, re-throw, or handle the error explicitly.",steps:["Add error logging (console.error or a logger) at minimum.","Re-throw if the caller should handle the error.","Add a comment explaining why swallowing is intentional, if it truly is."]},impact:"Prevents silent failures that are extremely hard to debug in production.",tags:["error-handling","reliability","silent-failure"]});return n}function jn(e){let n=[];for(let i of e)if(!x(i.file)&&!(!i.switchesWithoutDefault||i.switchesWithoutDefault.length===0))for(let t of i.switchesWithoutDefault)n.push({severity:"low",category:"switch-no-default",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:"Switch statement missing default case",reason:`Switch at line ${t.lineStart} has no default clause \u2014 unexpected values fall through silently.`,files:[`${i.file}:${t.lineStart}-${t.lineEnd}`],suggestedFix:{strategy:"Add a default case with error handling or exhaustive check.",steps:["Add a default clause that throws an unreachable error for exhaustiveness.","Or log a warning for unexpected values.","In TypeScript, use `never` type assertion for compile-time exhaustive checks."]},impact:"Catches unexpected values early and prevents silent logic bugs.",tags:["control-flow","exhaustiveness","safety"]});return n}function _n(e,n=5){let i=[];for(let t of e)if(!x(t.file)&&!(t.anyCount==null||t.anyCount<=n)){if(!G(i))break;i.push({severity:t.anyCount>10?"high":"medium",category:"unsafe-any",file:t.file,lineStart:1,lineEnd:1,title:`Excessive \`any\` usage: ${t.file} (${t.anyCount} occurrences)`,reason:`File uses \`any\` type ${t.anyCount} times (threshold: ${n}). Each \`any\` disables type checking and allows silent runtime errors.`,files:[t.file],suggestedFix:{strategy:"Replace `any` with specific types, `unknown`, or generics.",steps:["Replace `any` with `unknown` and add type guards where needed.","Use generics for functions that operate on multiple types.","Define proper interfaces for complex data shapes.","Use `as const` assertions instead of `as any` where possible."]},impact:"Restores TypeScript safety and catches bugs at compile time instead of runtime.",tags:["type-safety","reliability","typescript"]})}return i}function Hn(e,n=5e5,i=2){let t=[];for(let s of e)if(!x(s.file))for(let r of s.functions){if(!r.halstead)continue;let{effort:o,estimatedBugs:a,volume:l}=r.halstead;if(o<=n&&a<=i)continue;let c=[];o>n&&c.push(`effort=${Math.round(o)} (threshold: ${n})`),a>i&&c.push(`estimatedBugs=${a.toFixed(2)} (threshold: ${i})`),t.push({severity:o>n*2||a>5?"high":"medium",category:"halstead-effort",file:s.file,lineStart:r.lineStart,lineEnd:r.lineEnd,title:`High Halstead complexity: ${r.name}`,reason:`Function has high implementation complexity: ${c.join("; ")}. Volume=${Math.round(l)}.`,files:[`${s.file}:${r.lineStart}-${r.lineEnd}`],suggestedFix:{strategy:"Reduce operator/operand count by extracting helpers and simplifying expressions.",steps:["Extract complex sub-expressions into named intermediate variables.","Split into smaller functions with fewer unique operators/operands.","Replace imperative loops with declarative array methods where clearer."]},impact:"Lower Halstead effort correlates with fewer bugs and faster comprehension.",tags:["complexity","maintainability","effort"]})}return t}function Bn(e,n=20){let i=[];for(let t of e)if(!x(t.file))for(let s of t.functions)s.maintainabilityIndex==null||s.maintainabilityIndex>=n||i.push({severity:s.maintainabilityIndex<10?"critical":"high",category:"low-maintainability",file:t.file,lineStart:s.lineStart,lineEnd:s.lineEnd,title:`Low maintainability: ${s.name} (MI=${s.maintainabilityIndex.toFixed(1)})`,reason:`Maintainability Index is ${s.maintainabilityIndex.toFixed(1)} (threshold: ${n}, scale 0-100). Combines Halstead volume, cyclomatic complexity, and lines of code.`,files:[`${t.file}:${s.lineStart}-${s.lineEnd}`],suggestedFix:{strategy:"Reduce complexity, shorten the function, and simplify expressions.",steps:["Split into smaller functions to reduce LOC and cyclomatic complexity.","Extract complex expressions to reduce Halstead volume.","Convert nested logic to early returns and guard clauses.","Consider if parts of the function belong in separate modules."]},impact:"Higher MI directly predicts lower maintenance cost and defect rate.",tags:["maintainability","complexity","technical-debt"]});return i}function zn(e){let n=[];for(let i of e){if(x(i.file))continue;let t=i.typeAssertionEscapes;if(!t)continue;let s=t.asAny.length+t.doubleAssertion.length+t.nonNull.length;if(s===0)continue;let r=[];t.asAny.length>0&&r.push(`${t.asAny.length} \`as any\``),t.doubleAssertion.length>0&&r.push(`${t.doubleAssertion.length} double-assertion`),t.nonNull.length>0&&r.push(`${t.nonNull.length} non-null \`!\``);let o=[...t.asAny,...t.doubleAssertion,...t.nonNull].map(l=>l.lineStart),a=Math.min(...o);if(!G(n))break;n.push({severity:t.asAny.length+t.doubleAssertion.length>3?"high":"medium",category:"type-assertion-escape",file:i.file,lineStart:a,lineEnd:a,title:`Type-safety escapes in ${i.file} (${s})`,reason:`Found ${r.join(", ")}. Each assertion bypasses TypeScript's type checker.`,files:[i.file],suggestedFix:{strategy:"Replace type assertions with proper type guards or narrow types.",steps:["Replace `as any` with `unknown` and add runtime type checks.","Replace `as unknown as T` with proper generic constraints.","Replace `!` assertions with explicit null checks."]},impact:"Type assertions silence the compiler \u2014 runtime errors go undetected.",tags:["type-safety","assertions","code-quality"]})}return n}function Kn(e){let n=[];for(let i of e)if(!x(i.file)&&i.unprotectedAsync)for(let t of i.unprotectedAsync){let s=t.awaitCount>=4?"high":t.awaitCount>=2?"medium":"low";n.push({severity:s,category:"missing-error-boundary",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Missing error boundary: ${t.name} (${t.awaitCount} awaits, no try-catch)`,reason:`Async function "${t.name}" has ${t.awaitCount} await(s) but no try-catch. Rejected promises propagate as unhandled rejections.`,files:[i.file],suggestedFix:{strategy:"Wrap await calls in try-catch or add a .catch() handler.",steps:["Add a try-catch block around the await expressions.","Handle errors appropriately (log, return default, re-throw with context).","If the caller handles errors, document it with a comment."]},impact:"Unhandled promise rejections crash Node.js processes and cause silent failures in browsers.",tags:["error-handling","async","reliability"],lspHints:[{tool:"lspCallHierarchy",symbolName:t.name,lineHint:t.lineStart,file:i.file,expectedResult:"check if callers wrap this in try-catch or .catch() \u2014 if so, the boundary may exist upstream"}]})}return n}function Un(e){let n=[];for(let i of e)if(!x(i.file)&&i.asyncWithoutAwait)for(let t of i.asyncWithoutAwait)n.push({severity:"medium",category:"promise-misuse",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Unnecessary async: ${t.name} has no await`,reason:`Function "${t.name}" is declared \`async\` but never uses \`await\`. The \`async\` keyword adds unnecessary Promise wrapping.`,files:[i.file],suggestedFix:{strategy:"Remove the async keyword or add the missing await.",steps:["If the function does not need to be async, remove the `async` keyword.","If an `await` was forgotten, add it to the appropriate call.","Verify callers handle the return value correctly after the change."]},impact:"Unnecessary async wrapping adds microtask overhead and misleads readers.",tags:["async","performance","clarity"]});return n}function qn(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.awaitInLoopLocations||[])n.push({severity:"high",category:"await-in-loop",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:"await inside loop \u2014 sequential async execution",reason:"Each await runs serially. For N iterations this takes N * latency instead of max(latency). Use Promise.all() or Promise.allSettled() for parallel execution.",files:[i.file],suggestedFix:{strategy:"Collect promises and await them in parallel with Promise.all().",steps:["Collect all async operations into an array of promises.","Use await Promise.all(promises) or Promise.allSettled(promises).","If order matters or rate limiting is needed, use a batching utility."]},impact:"Sequential awaits multiply latency by N iterations \u2014 parallelizing can reduce total time to max(single-latency).",tags:["performance","async","n-plus-one"],lspHints:[{tool:"lspGotoDefinition",symbolName:"await",lineHint:t.lineStart,file:i.file,expectedResult:"navigate to the awaited call to check if parallelization is safe"}]});return n}function Gn(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.syncIoCalls||[])n.push({severity:"medium",category:"sync-io",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Synchronous I/O: ${t.name}`,reason:`${t.name} blocks the event loop. In server or UI code this degrades responsiveness for all concurrent operations.`,files:[i.file],suggestedFix:{strategy:"Replace with async equivalent.",steps:[`Replace ${t.name} with its async counterpart (e.g. fs.promises.readFile).`,"Sync I/O is acceptable in CLI scripts, build tools, or one-time init code."]},impact:"Synchronous I/O blocks the event loop, stalling all concurrent requests until the operation completes.",tags:["performance","blocking","io"],lspHints:[{tool:"lspCallHierarchy",symbolName:t.name,lineHint:t.lineStart,file:i.file,expectedResult:"find callers to assess if this sync I/O is in a hot path"}]});return n}function Wn(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.timerCalls||[])t.kind==="setInterval"&&!t.hasCleanup&&n.push({severity:"medium",category:"uncleared-timer",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:"setInterval without clearInterval in scope",reason:"setInterval without cleanup runs indefinitely, causing memory leaks and unexpected behavior after component unmount or scope exit.",files:[i.file],suggestedFix:{strategy:"Store the timer ID and call clearInterval in cleanup.",steps:["Assign the return value: const id = setInterval(...).","Call clearInterval(id) in cleanup (useEffect return, componentWillUnmount, or scope exit)."]},impact:"Uncleared intervals run indefinitely, leaking memory and CPU cycles after their scope is no longer relevant.",tags:["performance","memory-leak","timer"]});return n}function Vn(e){let n=[];for(let i of e){if(x(i.file))continue;let t=i.listenerRegistrations||[],s=i.listenerRemovals||[];t.length>0&&s.length===0&&n.push({severity:"medium",category:"listener-leak-risk",file:i.file,lineStart:t[0].lineStart,lineEnd:t[t.length-1].lineEnd,title:`${t.length} event listener(s) added without any removal`,reason:"addEventListener/on without corresponding removeEventListener/off risks memory leaks if the target outlives the subscriber.",files:[i.file],suggestedFix:{strategy:"Add corresponding listener removal in cleanup.",steps:["Store the handler reference in a variable.","Call removeEventListener/off in cleanup (unmount, dispose, close).","Or use AbortController signal for automatic cleanup."]},impact:"Listener references prevent garbage collection of the subscriber, causing memory growth proportional to event-target lifetime.",tags:["performance","memory-leak","events"]})}return n}function Qn(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.functions)t.loops>=2&&t.calls>=5&&t.maxLoopDepth>=2&&n.push({severity:"low",category:"unbounded-collection",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Potential unbounded collection growth in ${t.name}`,reason:`Function "${t.name}" has ${t.loops} loops nested ${t.maxLoopDepth} levels deep with ${t.calls} calls \u2014 structural signal for unbounded growth. Validate with tools: read the function body and check for collection mutations (.push, .add, .set) inside loops.`,files:[i.file],suggestedFix:{strategy:"Add size limits, pagination, or streaming.",steps:["Add a maximum size check before adding to collections.","Use pagination or streaming for large datasets.","Consider using generators for lazy evaluation."]},impact:"Unbounded collection growth inside nested loops can cause out-of-memory crashes under large input.",tags:["performance","memory","collection"]});return n}function Jn(e,n=.85){let i=[],t=[];for(let r of e.values())for(let o of r)x(o.file)||t.push(o);let s=new Map;for(let r of t){let o=`${r.kind}|${Math.round(r.statementCount/3)}`;s.has(o)||s.set(o,[]),s.get(o).push(r)}for(let[,r]of s)if(!(r.length<2||r.length>50))for(let o=0;o<r.length;o++)for(let a=o+1;a<r.length;a++){let l=r[o],c=r[a];if(l.hash===c.hash||l.file===c.file&&l.lineStart===c.lineStart||Math.min(l.statementCount,c.statementCount)/Math.max(l.statementCount,c.statementCount)<.8)continue;let d=Ao(l,c);d>=n&&i.push({severity:d>=.95?"high":"medium",category:"similar-function-body",file:l.file,lineStart:l.lineStart,lineEnd:l.lineEnd,title:`Similar function: ${l.name} (${(d*100).toFixed(0)}% similar to ${c.name} in ${c.file})`,reason:`"${l.name}" and "${c.name}" have ${(d*100).toFixed(0)}% structural similarity. Near-duplicates diverge over time and should be consolidated.`,files:[l.file,c.file],suggestedFix:{strategy:"Extract shared logic into a parameterized helper.",steps:[`Compare ${l.file}:${l.lineStart} with ${c.file}:${c.lineStart}.`,"Identify the varying parts and extract them as parameters.","Create a shared function and call it from both locations."]},impact:"Near-clone functions diverge over time, causing inconsistent behavior and multiplied maintenance cost.",tags:["duplication","maintainability","near-clone"]})}return i}function Ao(e,n){let i=[[e.metrics.complexity,n.metrics.complexity],[e.metrics.maxBranchDepth,n.metrics.maxBranchDepth],[e.metrics.maxLoopDepth,n.metrics.maxLoopDepth],[e.metrics.returns,n.metrics.returns],[e.metrics.awaits,n.metrics.awaits],[e.metrics.calls,n.metrics.calls],[e.metrics.loops,n.metrics.loops],[e.statementCount,n.statementCount]],t=0;for(let[s,r]of i){let o=Math.max(s,r,1);t+=1-Math.abs(s-r)/o}return t/i.length}function Yn(e){let n=[];for(let i of e){if(!i.messageChains||i.messageChains.length===0)continue;let t=new Map;for(let s of i.messageChains){let r=t.get(s.lineStart);(!r||s.depth>r.depth)&&t.set(s.lineStart,s)}for(let s of t.values()){let r=s.depth>=6?"high":"medium";n.push({severity:r,category:"message-chain",file:i.file,lineStart:s.lineStart,lineEnd:s.lineEnd,title:`Message chain of depth ${s.depth}: ${s.chain.slice(0,50)}`,reason:`A property-access chain of ${s.depth} steps violates the Law of Demeter \u2014 the caller navigates through ${s.depth-1} intermediate objects to reach its target. Deep chains tightly couple the caller to internal object structure, making refactoring brittle.`,files:[i.file],suggestedFix:{strategy:"Apply the Law of Demeter \u2014 talk only to immediate friends.",steps:["Identify the root object and the final method/property being used.","Add a delegating method to the root object (Tell, Don't Ask).","Replace the chain with a single call on the immediate object.","If the chain crosses module boundaries, consider whether the intermediate objects should be passed directly."]},impact:"Deep property chains tightly couple code to internal object structure. When intermediate objects change, every chain accessing them must be updated.",tags:["coupling","law-of-demeter","maintainability"],lspHints:[{tool:"lspGotoDefinition",symbolName:s.chain.split(".")[0],lineHint:s.lineStart,file:i.file,expectedResult:"find the type of the root object to understand what intermediate types the chain traverses"}]})}}return n}function Xn(e,n){let i=[];for(let t of e)if(!x(t.file))for(let s of t.functions){let r=Math.max(s.maxBranchDepth,s.maxLoopDepth);if(r<n)continue;if(!G(i))return i;let o=r>=n+3?"high":r>=n+1?"medium":"low";i.push({severity:o,category:"deep-nesting",file:t.file,lineStart:s.lineStart,lineEnd:s.lineEnd,title:`Deep nesting ${r} levels in ${s.name||"<anon>"}`,reason:`Function has ${r}-level nesting (branch=${s.maxBranchDepth}, loop=${s.maxLoopDepth}), exceeding the ${n}-level threshold. Each nesting level multiplies the reader's cognitive load and increases the likelihood of logic errors.`,files:[t.file],suggestedFix:{strategy:"Flatten nesting with guard clauses, early returns, or extraction.",steps:["Convert nested if-blocks to guard clauses with early returns.","Extract deeply nested logic into named helper functions.","Replace nested loops with array methods (map/filter/reduce)."]},impact:"Deeply nested code is hard to read, test, and modify. Each nesting level compounds the number of control-flow paths.",tags:["nesting","readability","complexity"]})}return i}function Zn(e,n){let i=[];for(let t of e)if(!x(t.file))for(let s of t.functions){if(s.returns<n)continue;if(!G(i))return i;let r=s.returns>=n+4?"high":s.returns>=n+2?"medium":"low";i.push({severity:r,category:"multiple-return-paths",file:t.file,lineStart:s.lineStart,lineEnd:s.lineEnd,title:`${s.returns} return paths in ${s.name||"<anon>"}`,reason:`Function has ${s.returns} return/throw points \u2014 the reader must track every exit path to understand the function's behavior. This exceeds the ${n} threshold.`,files:[t.file],suggestedFix:{strategy:"Consolidate return points to reduce exit-path tracking.",steps:["Replace scattered returns with a single result variable assigned conditionally.","Use early guard clauses for error cases only.","Consider splitting into smaller functions with clear single-responsibility."]},impact:"Many return paths make it harder to reason about what a function returns and to add post-processing.",tags:["returns","readability","flow"]})}return i}function ei(e){let n=[];for(let i of e)if(!x(i.file)&&!(!i.catchRethrows||i.catchRethrows.length===0))for(let t of i.catchRethrows){if(!G(n))return n;n.push({severity:"low",category:"catch-rethrow",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:"Catch-rethrow without transformation",reason:"A catch block that only re-throws the caught error is a no-op \u2014 it adds indentation and obscures the stack trace without adding value.",files:[i.file],suggestedFix:{strategy:"Remove the try-catch or add meaningful error handling.",steps:["If no transformation is needed, remove the try-catch entirely.","If logging is intended, add a log statement before re-throwing.","If wrapping, throw a new error with the original as cause."]},impact:"Pointless catch blocks add noise and can accidentally swallow stack-trace context.",tags:["error-handling","noise","cleanup"]})}return n}function ti(e,n){let i=[],t=new Map;for(let s of e)if(!x(s.file)&&s.magicStrings)for(let r of s.magicStrings){let o=t.get(r.value)||[];o.push({file:r.file,lineStart:r.lineStart,lineEnd:r.lineEnd}),t.set(r.value,o)}for(let[s,r]of t){if(r.length<n)continue;if(!G(i))return i;let o=[...new Set(r.map(l=>l.file))],a=r.length>=8?"high":r.length>=5?"medium":"low";i.push({severity:a,category:"magic-string",file:r[0].file,lineStart:r[0].lineStart,lineEnd:r[0].lineEnd,title:`Magic string "${s.length>30?s.slice(0,27)+"...":s}" appears ${r.length} times`,reason:`The string literal "${s}" is used in ${r.length} comparisons across ${o.length} file(s). If the value changes, every occurrence must be updated \u2014 a classic source of silent bugs.`,files:o,suggestedFix:{strategy:"Extract to a named constant or enum.",steps:[`Create a const (e.g. const ${s.toUpperCase().replace(/[^A-Z0-9]/g,"_")} = '${s}').`,"Replace all usages with the constant reference.","Consider an enum if there are multiple related string values."]},impact:"Magic strings scatter domain knowledge across the codebase and are invisible to refactoring tools.",tags:["magic-value","maintainability","duplication"]})}return i}function ni(e,n){let i=[];for(let t of e)if(!x(t.file)&&t.booleanParamClusters){for(let s of t.booleanParamClusters)if(!(s.booleanCount<n)){if(!G(i))return i;i.push({severity:"medium",category:"boolean-parameter-cluster",file:t.file,lineStart:s.lineStart,lineEnd:s.lineEnd,title:`${s.booleanCount} boolean params in ${s.name||"<anon>"}`,reason:`Function has ${s.booleanCount} boolean parameters out of ${s.totalParams} total. Boolean flags are opaque at call sites (e.g. doThing(true, false, true)) and each flag doubles the function's behavior space.`,files:[t.file],suggestedFix:{strategy:"Replace boolean clusters with an options object or separate functions.",steps:["Create an options/config object type with named fields.","Replace boolean parameters with the options object.","Consider splitting into distinct functions for each behavior variant."]},impact:"Boolean parameter clusters make call sites unreadable and the function hard to test \u2014 2^N behavior combinations.",tags:["api-design","readability","parameters"]})}}return i}function ii(e){let n=[];for(let i of e)if(!x(i.file)&&i.promiseAllUnhandled)for(let t of i.promiseAllUnhandled){if(!G(n))return n;n.push({severity:"medium",category:"promise-all-unhandled",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`${t.kind} without error handling`,reason:`${t.kind} is called without a surrounding try-catch or .catch() chain. If any of the composed promises reject, the rejection will propagate unhandled.`,files:[i.file],suggestedFix:{strategy:"Wrap in try-catch or add .catch() to the promise chain.",steps:["Add a try-catch around the await expression.","Or chain a .catch() handler onto the Promise combinator.","Consider Promise.allSettled if partial failure is acceptable."]},impact:"Unhandled rejections from promise combinators crash Node.js processes and cause silent failures in browsers.",tags:["error-handling","async","reliability"]})}return n}function si(e,n){let i=[];if(!n)return i;for(let t of e){if(x(t.file))continue;let s=t.dependencyProfile;if(!s)continue;let r=t.functions.reduce((c,u)=>c+u.statementCount,0)+t.flows.length;if(r<20)continue;let o=s.declaredExports?.length||0;if(o===0)continue;let a=o/r;if(a<.5)continue;if(!G(i))return i;let l=a>=.8?"high":a>=.6?"medium":"low";i.push({severity:l,category:"export-surface-density",file:t.file,lineStart:1,lineEnd:1,title:`${Math.round(a*100)}% export density (${o} exports / ~${r} statements)`,reason:`This module exports ${o} symbols from ~${r} total statements \u2014 a ${Math.round(a*100)}% export surface. High export density means nearly everything is public API, increasing coupling and reducing the ability to refactor internals.`,files:[t.file],suggestedFix:{strategy:"Reduce the public API by making non-essential symbols internal.",steps:["Audit each export \u2014 does it need to be consumed externally?","Convert unnecessary exports to module-private functions.","Consider splitting into a public facade and private implementation module."]},impact:"High export density couples consumers to internal implementation, making any change a potential breaking change.",tags:["encapsulation","api-surface","coupling"]})}return i}function ri(e,n,i){let t=[];for(let s of e){if(x(s.file))continue;let r=0,o=[],a=s.functions.length>0?s.functions.reduce((f,p)=>f+p.complexity,0)/s.functions.length:0;a>15&&(r+=2,o.push(`high avg complexity (${a.toFixed(1)})`));let l=s.functions.reduce((f,p)=>Math.max(f,p.cognitiveComplexity),0);l>20&&(r+=2,o.push(`high cognitive complexity (${l})`));let c=s.functions.filter(f=>f.maintainabilityIndex!==void 0&&f.maintainabilityIndex<20).length;c>0&&(r+=c,o.push(`${c} function(s) with low MI`)),s.emptyCatches&&s.emptyCatches.length>0&&(r+=1,o.push(`${s.emptyCatches.length} empty catches`)),s.promiseAllUnhandled&&s.promiseAllUnhandled.length>0&&(r+=1,o.push(`${s.promiseAllUnhandled.length} unhandled promise combinators`));let u=s.dependencyProfile;if(u&&u.declaredExports){let f=u.declaredExports.length;f>15&&(r+=1,o.push(`${f} exports`))}if(r<4)continue;if(!G(t))return t;let d=r>=8?"critical":r>=6?"high":"medium";t.push({severity:d,category:"change-risk",file:s.file,lineStart:1,lineEnd:1,title:`Change-risk score ${r}: ${o.slice(0,3).join(", ")}`,reason:`This file has a composite change-risk score of ${r}, derived from: ${o.join("; ")}. Files with multiple overlapping quality signals are the most likely to introduce regressions when modified.`,files:[s.file],suggestedFix:{strategy:"Reduce risk incrementally \u2014 address the highest-impact signal first.",steps:["Check test coverage for this file \u2014 add tests if missing.","Address the highest-severity individual finding first.","Consider splitting the module to isolate high-risk logic."]},impact:"Files with multiple quality issues compound risk \u2014 each change is likely to trigger regressions in hard-to-predict ways.",tags:["risk","composite","priority"]})}return t}var As=N(()=>{"use strict";ge();W()});function oi(e){let n=[];for(let i of e){if(x(i.file))continue;let t=(i.suspiciousStrings||[]).filter(s=>s.kind==="hardcoded-secret"&&s.context!=="regex-definition"&&s.context!=="error-message");if(t.length!==0)for(let s of t)n.push(ue({severity:"high",category:"hardcoded-secret",file:i.file,lineStart:s.lineStart,lineEnd:s.lineEnd,title:`Potential hardcoded secret${s.snippet?`: ${s.snippet.slice(0,20)}\u2026`:""}`,reason:"String literal matches a secret pattern (password, API key, token, high-entropy string). Secrets in source code risk credential leaks. Validate: use localSearchCode to find the variable, then lspFindReferences to check if it is used in auth or network calls.",files:[i.file],suggestedFix:{strategy:"Move secret to environment variable or secrets manager.",steps:["Replace the hardcoded value with process.env.YOUR_SECRET.","Add the variable to your .env file (excluded from git).","Verify the secret is not committed in git history."]},impact:"Credential leak in source code exposes API access, database credentials, or authentication tokens to anyone with repo access.",tags:["security","secrets"],lspHints:[{tool:"lspFindReferences",symbolName:s.snippet?.split(/[=:]/)[0]?.trim()||"secret",lineHint:s.lineStart,file:i.file,expectedResult:"find all usages of this secret value \u2014 if used only in tests or as a regex pattern, it is a false positive"}]},"security.hardcoded-secret","high",{source:s.snippet||"",sink:"runtime usage",context:s.context||"literal",sanitizerStatus:"missing",propagationSteps:[`${i.file}:${s.lineStart}`]}))}return n}function ai(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.evalUsages||[])n.push(ue({severity:"critical",category:"eval-usage",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:"Dynamic code execution (eval/Function)",reason:"eval(), new Function(), or string-based setTimeout/setInterval allows arbitrary code execution. This is a code injection vector.",files:[i.file],suggestedFix:{strategy:"Replace dynamic code execution with safe alternatives.",steps:["For JSON parsing: use JSON.parse() instead of eval().","For dynamic dispatch: use a lookup table or switch statement.","For setTimeout: pass a function reference, not a string."]},impact:"Arbitrary code execution enables full application takeover \u2014 the most severe class of injection vulnerability.",tags:["security","injection","critical"],lspHints:[{tool:"lspCallHierarchy",symbolName:"eval",lineHint:t.lineStart,file:i.file,expectedResult:"trace callers to find how user input reaches the eval site"}]},"security.eval-usage","high",{sink:`eval at ${i.file}:${t.lineStart}-${t.lineEnd}`,sanitizerStatus:"missing"}));return n}function li(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.unsafeHtmlAssignments||[])n.push(ue({severity:"high",category:"unsafe-html",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:"Unsafe HTML manipulation",reason:"innerHTML, outerHTML, dangerouslySetInnerHTML, or document.write can execute unsanitized user input as HTML/script. XSS vector.",files:[i.file],suggestedFix:{strategy:"Use safe DOM APIs or sanitize input before insertion.",steps:["Replace innerHTML with textContent for plain text.","Use a sanitizer library (e.g. DOMPurify) if HTML is required.","In React, avoid dangerouslySetInnerHTML \u2014 use JSX instead."]},impact:"Unsanitized HTML insertion enables cross-site scripting (XSS) \u2014 attackers can steal sessions, credentials, or execute actions as the victim.",tags:["security","xss"]},"security.unsafe-html","high",{sink:"DOM assignment",sanitizerStatus:"missing",propagationSteps:["html assignment"]}));return n}function ci(e){let n=[];for(let i of e){if(x(i.file))continue;let t=(i.suspiciousStrings||[]).filter(s=>s.kind==="sql-injection");for(let s of t)n.push(ue({severity:"high",category:"sql-injection-risk",file:i.file,lineStart:s.lineStart,lineEnd:s.lineEnd,title:"SQL query built with template literal interpolation",reason:"Template literals with SQL keywords and interpolated expressions risk SQL injection if user input flows into the query.",files:[i.file],suggestedFix:{strategy:"Use parameterized queries or a query builder.",steps:["Replace template literal with parameterized query (e.g. db.query(sql, [param])).","Use an ORM or query builder that handles escaping.","If raw SQL is necessary, validate and sanitize all interpolated values."]},impact:"SQL injection can expose, modify, or destroy database contents and potentially escalate to full server compromise.",tags:["security","injection","sql"]},"security.sql-injection-risk","high",{sink:"sql template literal",sanitizerStatus:"missing",propagationSteps:[`${i.file}:${s.lineStart}-${s.lineEnd}`]}))}return n}function di(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.regexLiterals||[])Mo.test(t.pattern)&&n.push(ue({severity:"medium",category:"unsafe-regex",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:"Regex with catastrophic backtracking risk",reason:`Pattern "${t.pattern.slice(0,40)}" has nested quantifiers that can cause exponential backtracking (ReDoS).`,files:[i.file],suggestedFix:{strategy:"Simplify the regex or use atomic groups / possessive quantifiers.",steps:["Remove nested quantifiers \u2014 e.g. change (a+)+ to a+.","Use a regex linter (e.g. safe-regex) to validate patterns.","Consider using string methods instead of complex regexes."]},impact:"Catastrophic backtracking causes CPU exhaustion \u2014 a single crafted input string can hang the event loop (ReDoS).",tags:["security","regex","performance"],lspHints:[{tool:"lspFindReferences",symbolName:t.pattern.slice(0,20),lineHint:t.lineStart,file:i.file,expectedResult:"find where this regex is used to assess if user input reaches it"}]},"security.unsafe-regex","medium",{source:t.pattern,sink:"Regex execution",sanitizerStatus:"not-applicable",propagationSteps:[`${i.file}:${t.lineStart}-${t.lineEnd}`]}));return n}function ui(e){let n=[];for(let i of e)if(!x(i.file)&&!(!i.prototypePollutionSites||i.prototypePollutionSites.length===0))for(let t of i.prototypePollutionSites){let s,r;t.kind==="computed-property-write"?t.guarded?(s="low",r="low"):(s="high",r="medium"):(s="medium",r="medium"),n.push(ue({severity:s,category:"prototype-pollution-risk",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Prototype pollution risk: ${t.kind}${t.guarded?" (guarded)":""}`,reason:`${t.detail}${t.guarded?" \u2014 guards detected (internal iteration or key check), likely false positive. Verify the key variable does not trace to external input.":""}`,files:[i.file],suggestedFix:{strategy:"Guard against __proto__, constructor, and prototype keys before merging.",steps:['Validate keys: reject "__proto__", "constructor", "prototype" before assignment.',"Use Object.create(null) as the target for merges when possible.","Replace custom deep-merge with a hardened library (e.g. lodash.merge with prototype guard).","For Object.assign, ensure the source is sanitized or use structuredClone()."]},impact:"Prototype pollution can override built-in methods, bypass security checks, or achieve remote code execution.",tags:["security","prototype-pollution","injection"],lspHints:[{tool:"lspCallHierarchy",symbolName:t.kind==="computed-property-write"?"bracket-assignment":t.detail.split("(")[0],lineHint:t.lineStart,file:i.file,expectedResult:"trace callers to determine if user-controlled data reaches this site \u2014 if key comes from Object.keys() on internal object, dismiss as false positive"}]},"security.prototype-pollution-risk",r,{source:t.kind,sink:t.detail,guarded:t.guarded,sanitizerStatus:t.guarded?"present":"missing",propagationSteps:[`${i.file}:${t.lineStart}`]}))}return n}function fi(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.inputSources||[]){if(!t.hasSinkInBody||t.hasValidation)continue;let s=t.sinkKinds.join(", "),r=t.paramConfidence==="low"?"medium":"high";n.push(ue({severity:r,category:"unvalidated-input-sink",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Unvalidated input reaches ${s} sink in ${t.functionName}(${t.sourceParams.join(", ")})`,reason:`Parameter${t.sourceParams.length>1?"s":""} '${t.sourceParams.join("', '")}' (external input) flow${t.sourceParams.length===1?"s":""} into ${s} without validation (no type guard, schema call, or conditional check).`,files:[i.file],suggestedFix:{strategy:"Add input validation before the sink operation.",steps:["Add schema validation (e.g. zod, joi) for input parameters.","Use parameterized APIs instead of template interpolation for SQL/exec.",`Trace data flow: lspCallHierarchy(outgoing) on ${t.functionName}.`]},impact:"Unvalidated external input reaching a dangerous sink (eval, SQL, exec, innerHTML, file write) enables injection attacks.",tags:["security","input-validation","injection"],lspHints:[{tool:"lspCallHierarchy",symbolName:t.functionName,lineHint:t.lineStart,file:i.file,expectedResult:`trace outgoing calls to see where ${t.sourceParams.join(", ")} data flows`},{tool:"lspFindReferences",symbolName:t.sourceParams[0],lineHint:t.lineStart,file:i.file,expectedResult:`check all usages of ${t.sourceParams[0]} parameter within function`}]},"security.unvalidated-input-sink",r==="high"?"high":"medium",{sourceParameters:t.sourceParams,sink:s,sanitizerStatus:t.hasValidation?"present":"missing",propagationSteps:t.callsWithInputArgs.map(o=>`${o.callee}:${o.lineStart}`)}))}return n}function pi(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.inputSources||[]){if(t.callsWithInputArgs.length===0||t.hasValidation||t.hasSinkInBody||t.paramConfidence==="low")continue;let s=t.callsWithInputArgs.map(a=>a.callee),r=[...new Set(s)],o=t.paramConfidence==="high"?"medium":"low";n.push(ue({severity:o,category:"input-passthrough-risk",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Input passthrough without validation in ${t.functionName}(${t.sourceParams.join(", ")})`,reason:`Parameter${t.sourceParams.length>1?"s":""} '${t.sourceParams.join("', '")}' (external input) ${t.sourceParams.length===1?"is":"are"} passed to ${r.join(", ")} without validation. Downstream callees may not validate either.`,files:[i.file],suggestedFix:{strategy:"Validate input before passing to downstream functions.",steps:["Add schema validation (e.g. zod, joi) at the entry point.",`Trace downstream: lspCallHierarchy(outgoing) on ${t.functionName} to verify callees validate.`,"Search for validation middleware: localSearchCode for guard/validate/sanitize patterns."]},impact:"Unchecked input passed downstream can reach sinks in callees \u2014 validation gaps compound across the call chain.",tags:["security","input-validation","passthrough"],lspHints:[{tool:"lspCallHierarchy",symbolName:t.functionName,lineHint:t.lineStart,file:i.file,expectedResult:`trace outgoing calls to verify downstream validation of ${t.sourceParams.join(", ")}`},{tool:"lspFindReferences",symbolName:t.sourceParams[0],lineHint:t.lineStart,file:i.file,expectedResult:`find all usages of ${t.sourceParams[0]} to check if validation occurs upstream`}]},"security.input-passthrough-risk",o,{sourceParameters:t.sourceParams,sink:r.join(", "),sanitizerStatus:t.hasValidation?"present":"missing",propagationSteps:t.callsWithInputArgs.map(a=>`${a.callee}:${a.lineStart}`)}))}return n}function gi(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.inputSources||[]){let s=t.sinkKinds.filter(l=>l==="fs-read"||l==="path-resolve");if(s.length===0||t.paramConfidence==="low")continue;let r=t.hasValidation,o=r?"medium":"high",a=s.join(", ");n.push(ue({severity:o,category:"path-traversal-risk",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Path traversal risk: ${t.functionName}(${t.sourceParams.join(", ")}) \u2192 ${a}`,reason:`Parameter${t.sourceParams.length>1?"s":""} '${t.sourceParams.join("', '")}' (external input) flow${t.sourceParams.length===1?"s":""} into ${a} ${r?"with partial validation \u2014 verify path normalization + prefix check + realpath resolution":"without validation. Path traversal (e.g. ../../etc/passwd) can read or write arbitrary files"}.`,files:[i.file],suggestedFix:{strategy:"Add multi-layer path validation before file system operations.",steps:["Normalize the path: path.resolve(basePath, userInput).","Prefix check: resolvedPath.startsWith(basePath + path.sep).","Resolve symlinks: fs.realpathSync() to prevent symlink escape.","Re-validate after symlink resolution."]},impact:"Path traversal enables reading sensitive files (credentials, configs, source code) or writing to arbitrary locations (code injection via file overwrite).",tags:["security","path-traversal","agentic"],lspHints:[{tool:"lspCallHierarchy",symbolName:t.functionName,lineHint:t.lineStart,file:i.file,expectedResult:"trace incoming callers to determine if path parameter comes from user input \u2014 then trace outgoing to the fs/path call"}]},"security.path-traversal-risk",t.paramConfidence==="high"?"high":"medium",{sourceParameters:t.sourceParams,sink:a,sanitizerStatus:r?"partial":"missing",propagationSteps:t.callsWithInputArgs.map(l=>`${l.callee}:${l.lineStart}`)}))}return n}function mi(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.inputSources||[]){if(t.sinkKinds.filter(a=>a==="exec").length===0||t.paramConfidence==="low")continue;let r=t.callsWithInputArgs.filter(a=>/\.exec\b|^exec$|^execSync$|child_process\.exec/.test(a.callee)),o=t.callsWithInputArgs.filter(a=>/\.spawn\b|^spawn$|^spawnSync$|child_process\.spawn/.test(a.callee));if(r.length>0){let a=t.paramConfidence==="high"?"critical":"high";n.push(ue({severity:a,category:"command-injection-risk",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Command injection risk: ${t.functionName}(${t.sourceParams.join(", ")}) \u2192 exec`,reason:`Parameter${t.sourceParams.length>1?"s":""} '${t.sourceParams.join("', '")}' (external input) flow${t.sourceParams.length===1?"s":""} into exec/execSync. exec() runs commands through a shell \u2014 string interpolation enables command injection.`,files:[i.file],suggestedFix:{strategy:"Replace exec with spawn using array arguments (no shell interpretation).",steps:["Replace child_process.exec(cmd) with child_process.spawn(binary, [args]).","Never interpolate user input into command strings.","Use an allowlist for permitted commands if dynamic dispatch is needed.","If shell features are required, validate input against a strict allowlist."]},impact:"Command injection enables arbitrary OS command execution \u2014 full server compromise, data exfiltration, or lateral movement.",tags:["security","command-injection","critical","agentic"],lspHints:[{tool:"lspCallHierarchy",symbolName:t.functionName,lineHint:t.lineStart,file:i.file,expectedResult:"trace incoming callers to verify if user input reaches the exec call \u2014 check for allowlist or sanitization"}]},"security.command-injection-risk",t.paramConfidence==="high"?"high":"medium",{sourceParameters:t.sourceParams,sink:"exec",sanitizerStatus:t.hasValidation?"partial":"missing",propagationSteps:r.map(l=>`${l.callee}:${l.lineStart}`)}))}o.length>0&&r.length===0&&n.push(ue({severity:"high",category:"command-injection-risk",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Potential command injection: ${t.functionName}(${t.sourceParams.join(", ")}) \u2192 spawn`,reason:`Parameter${t.sourceParams.length>1?"s":""} '${t.sourceParams.join("', '")}' (external input) flow${t.sourceParams.length===1?"s":""} into spawn. If shell:true is set, this is equivalent to exec. Verify spawn uses array args without shell option.`,files:[i.file],suggestedFix:{strategy:"Ensure spawn uses array arguments without shell: true.",steps:["Verify spawn is called as spawn(binary, [arg1, arg2]) \u2014 NOT spawn(cmd, { shell: true }).","Remove shell: true if present.","Validate command arguments against an allowlist."]},impact:"spawn with shell:true enables the same command injection as exec. Without shell:true, spawn with array args is safe from injection.",tags:["security","command-injection","agentic"],lspHints:[{tool:"lspCallHierarchy",symbolName:t.functionName,lineHint:t.lineStart,file:i.file,expectedResult:"trace incoming callers \u2014 check if spawn uses shell:true option"}]},"security.command-injection-risk","medium",{sourceParameters:t.sourceParams,sink:"spawn",sanitizerStatus:t.hasValidation?"partial":"missing",propagationSteps:o.map(a=>`${a.callee}:${a.lineStart}`)}))}return n}function hi(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.consoleLogs||[])t.method==="debugger"?n.push(ue({severity:"high",category:"debug-log-leakage",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:"Debugger statement in production code",reason:"A `debugger` statement pauses execution when DevTools are open. In production it can expose internal state and halt the application.",files:[i.file],suggestedFix:{strategy:"Remove the debugger statement before shipping.",steps:["Delete the `debugger;` line.","Use structured logging (pino, winston) or feature-flagged debug helpers instead."]},impact:"Debugger statements in production can halt request processing and expose internal runtime state to anyone with browser DevTools open.",tags:["security","debug","production-safety"]},"security.debug-log-leakage","high",{method:"debugger",line:t.lineStart})):(t.method==="debug"||t.method==="trace")&&n.push(ue({severity:"medium",category:"debug-log-leakage",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`console.${t.method}() in production code`,reason:`console.${t.method}() is a development-only call. Left in production it leaks internal state, variable values, and execution paths \u2014 all useful to attackers.`,files:[i.file],suggestedFix:{strategy:"Replace with a structured logger that respects log-level configuration.",steps:[`Remove or gate the console.${t.method}() call behind a LOG_LEVEL check.`,"Use a structured logger (pino, winston) with level filtering instead.","Ensure debug/trace levels are disabled in production config."]},impact:"Debug/trace logs expose internal object state and execution flow, making reconnaissance easier for attackers and violating minimal disclosure.",tags:["security","debug","information-disclosure"],lspHints:[{tool:"lspFindReferences",symbolName:`console.${t.method}`,lineHint:t.lineStart,file:i.file,expectedResult:"find all debug/trace log calls in this file to assess total leakage surface"}]},"security.debug-log-leakage","medium",{method:t.method,snippet:t.argSnippet,line:t.lineStart}));return n}function yi(e){let n=[];for(let i of e)if(!x(i.file))for(let t of i.consoleLogs||[])t.method==="debugger"||!t.hasSensitiveArg||n.push(ue({severity:"high",category:"sensitive-data-logging",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Sensitive data logged via console.${t.method}()${t.argSnippet?`: ${t.argSnippet.slice(0,40)}`:""}`,reason:`console.${t.method}() argument matches a sensitive-data pattern (password, token, secret, credential, API key, session, SSN). Logging secrets writes them to stdout/stderr, log aggregators, error monitoring services, and persistent log files.`,files:[i.file],suggestedFix:{strategy:"Remove or redact sensitive values before logging.",steps:["Never log raw passwords, tokens, API keys, or session identifiers.",'If logging for debugging, redact: log({ ...user, password: "[REDACTED]" }).',"Use a structured logger with field-level redaction hooks (e.g. pino redact option).","Audit all log aggregation pipelines (Datadog, Splunk, CloudWatch) for secret exposure."]},impact:"Sensitive data in logs is written to stdout/stderr, forwarded to log aggregators (Splunk, Datadog, CloudWatch), and often stored long-term \u2014 creating a persistent credential leak accessible to anyone with log access.",tags:["security","sensitive-data","credential-leak","compliance"],lspHints:[{tool:"lspCallHierarchy",symbolName:t.method,lineHint:t.lineStart,file:i.file,expectedResult:`trace incoming callers to understand where sensitive data originates before reaching console.${t.method}`}]},"security.sensitive-data-logging","high",{method:t.method,snippet:t.argSnippet,line:t.lineStart,sanitizerStatus:"missing"}));return n}var Mo,ue,Si=N(()=>{"use strict";W();Mo=/(\(.+[+*]\))[+*]|(\(.+\?\))\{/,ue=(e,n,i,t)=>({...e,ruleId:n,confidence:i,evidence:t})});var Ze=N(()=>{"use strict";ge();ks();Ts();$s();Ds();Rs();As();Si()});function Ms(e){let n=[];for(let i of e){if(!x(i.file)||!i.testProfile)continue;let{testBlocks:t}=i.testProfile;if(t.length===0)continue;let s=t.reduce((o,a)=>o+a.assertionCount,0),r=s/t.length;r<1&&n.push({severity:"medium",category:"low-assertion-density",file:i.file,lineStart:t[0].lineStart,lineEnd:t[t.length-1].lineEnd,title:`Low assertion density: ${s} assertions across ${t.length} tests`,reason:`Average ${r.toFixed(1)} assertions per test. Tests with few assertions may pass without verifying actual behavior.`,files:[i.file],suggestedFix:{strategy:"Add meaningful assertions to each test case.",steps:["Review each test block and add expect() calls that verify outcomes.","Test both success and failure paths.","Assert return values, state changes, and side effects."]},impact:"Low assertion density means tests pass without verifying behavior \u2014 bugs slip through with false confidence.",tags:["test-quality","assertions"]})}return n}function Ps(e){let n=[];for(let i of e)if(!(!x(i.file)||!i.testProfile))for(let t of i.testProfile.testBlocks)t.assertionCount===0&&n.push({severity:"high",category:"test-no-assertion",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Test "${t.name}" has no assertions`,reason:"A test without assertions always passes. It provides no verification of behavior.",files:[i.file],suggestedFix:{strategy:"Add at least one expect() or assert() call.",steps:["Identify what behavior this test should verify.","Add expect(result).toBe(expected) or similar assertion.","If the test only checks that code does not throw, use expect(() => fn()).not.toThrow()."]},impact:"Zero-assertion tests always pass \u2014 they provide no safety net and create a false sense of coverage.",tags:["test-quality","assertions","false-pass"]});return n}function Is(e,n=10){let i=[];for(let t of e){if(!x(t.file)||!t.testProfile)continue;let{mockCalls:s}=t.testProfile;s.length>n&&i.push({severity:"medium",category:"excessive-mocking",file:t.file,lineStart:s[0].lineStart,lineEnd:s[s.length-1].lineEnd,title:`${s.length} mock/spy calls in test file (threshold: ${n})`,reason:"Excessive mocking couples tests to implementation details, making them brittle and hard to maintain.",files:[t.file],suggestedFix:{strategy:"Reduce mocks by testing through public interfaces.",steps:["Identify mocks that can be replaced with real implementations.","Use dependency injection to simplify test setup.","Consider integration tests for complex interaction chains."]},impact:"Heavy mocking couples tests to implementation details \u2014 any refactor breaks them even if behavior is unchanged.",tags:["test-quality","mocking","brittleness"]})}return i}function Ns(e){let n=[];for(let i of e)if(!(!x(i.file)||!i.testProfile))for(let t of i.testProfile.mutableStateDecls)n.push({severity:"medium",category:"shared-mutable-state",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:"Mutable variable at describe scope",reason:"let/var at describe scope creates shared mutable state between tests. Tests may pass or fail depending on execution order.",files:[i.file],suggestedFix:{strategy:"Move variable declaration inside each test or use beforeEach.",steps:["Move the variable into each it()/test() block that uses it.","Or initialize it in beforeEach() so each test gets a fresh copy.","Use const where possible."]},impact:"Shared mutable state causes order-dependent test results \u2014 tests pass in isolation but fail or flake in suite runs.",tags:["test-quality","isolation","flaky"]});return n}function Ls(e){let n=[];for(let i of e){if(!x(i.file)||!i.testProfile)continue;let{setupCalls:t}=i.testProfile,s=t.some(l=>l.kind==="beforeAll"),r=t.some(l=>l.kind==="afterAll"),o=t.some(l=>l.kind==="beforeEach"),a=t.some(l=>l.kind==="afterEach");if(s&&!r){let l=t.find(c=>c.kind==="beforeAll");n.push({severity:"medium",category:"missing-test-cleanup",file:i.file,lineStart:l.lineStart,lineEnd:l.lineStart,title:"beforeAll without afterAll",reason:"Setup in beforeAll without teardown in afterAll can leak state (open connections, modified globals, temp files) across test suites.",files:[i.file],suggestedFix:{strategy:"Add afterAll() to clean up resources allocated in beforeAll().",steps:["Identify what beforeAll() sets up (connections, mocks, temp state).","Add afterAll() to tear it down."]},impact:"Missing teardown leaks resources (connections, file handles, globals) that poison subsequent test suites.",tags:["test-quality","cleanup","leak"]})}if(o&&!a){let l=t.find(c=>c.kind==="beforeEach");n.push({severity:"medium",category:"missing-test-cleanup",file:i.file,lineStart:l.lineStart,lineEnd:l.lineStart,title:"beforeEach without afterEach",reason:"Setup in beforeEach without teardown in afterEach can accumulate side effects across tests.",files:[i.file],suggestedFix:{strategy:"Add afterEach() to clean up resources allocated in beforeEach().",steps:["Identify what beforeEach() sets up.","Add afterEach() to tear it down or restore state."]},impact:"Per-test setup without teardown accumulates side effects, causing cascading failures in later tests.",tags:["test-quality","cleanup"]})}}return n}function Os(e){let n=[];for(let i of e)if(!(!x(i.file)||!i.testProfile))for(let t of i.testProfile.focusedCalls)n.push({severity:"medium",category:"focused-test",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Focused test marker: ${t.kind}`,reason:`${t.kind} limits scan or production of focused tests; it can hide unrelated failures and reduce suite coverage when committed.`,files:[i.file],suggestedFix:{strategy:"Avoid focused/skip patterns in committed tests.",steps:["Remove `.only`/`.skip`/`.todo` markers before merging.","Use local test filtering only for interactive local debugging.","If temporarily needed, add a TODO and a tracked follow-up task."]},impact:"Focused tests can create a false green signal by skipping broader test coverage.",tags:["test-quality","selection","flaky","coverage"],ruleId:"test-quality.focused-test",confidence:"high",evidence:{marker:t.kind,lineStart:t.lineStart,lineEnd:t.lineEnd,category:"focused-test"}});return n}function js(e){let n=[];for(let i of e){if(!x(i.file)||!i.testProfile)continue;let t=i.testProfile.timerControls.filter(o=>o.kind==="jest.useFakeTimers"||o.kind==="vi.useFakeTimers");if(t.length===0||i.testProfile.timerControls.some(o=>o.kind==="jest.useRealTimers"||o.kind==="vi.useRealTimers"))continue;let r=t[0];n.push({severity:"medium",category:"fake-timer-no-restore",file:i.file,lineStart:r.lineStart,lineEnd:r.lineEnd,title:"Fake timers activated without restore",reason:"Tests that switch to fake timers without restoring real timers can leak timing behavior into subsequent tests.",files:[i.file],suggestedFix:{strategy:"Pair fake timer activation with a restore in the same test scope.",steps:["Call `jest.useRealTimers()` or `vi.useRealTimers()` in afterEach() or afterAll().","Prefer per-test setup/teardown with explicit timer cleanup."]},impact:"Leaked fake-timer configuration can cause subtle, order-dependent failures across unrelated suites.",tags:["test-quality","timers","isolation"],ruleId:"test-quality.fake-timer-no-restore",confidence:"medium",evidence:{fakeTimerActivationLines:t.map(o=>`${o.kind}:${o.lineStart}`)}})}return n}function _s(e){let n=[];for(let i of e){if(!x(i.file)||!i.testProfile||i.testProfile.spyOrStubCalls.length===0||i.testProfile.mockRestores.some(a=>a.kind==="restoreAll"))continue;let s=new Set(i.testProfile.mockRestores.filter(a=>a.kind==="restore"&&!!a.target).map(a=>a.target)),r=i.testProfile.spyOrStubCalls.find(a=>!a.target||!s.has(a.target));if(!r)continue;let o=r;n.push({severity:"medium",category:"missing-mock-restoration",file:i.file,lineStart:o.lineStart,lineEnd:o.lineEnd,title:"Spy/stub not restored",reason:"Spies/stubs modify implementation behavior and must be restored to avoid cross-test leakage.",files:[i.file],suggestedFix:{strategy:"Restore every spy/stub after each test or in a file-level teardown.",steps:["Call `mockRestore()` on each spy/stub returned handle.","Or use `jest.restoreAllMocks()`/`vi.restoreAllMocks()` in afterEach/afterAll."]},impact:"Unrestored spies/stubs make tests order-dependent and can mask regressions.",tags:["test-quality","cleanup","mocks","isolation"],ruleId:"test-quality.missing-mock-restoration",confidence:"high",evidence:{spyOrStubCalls:i.testProfile.spyOrStubCalls.map(a=>`${a.lineStart}`)}})}return n}var Hs=N(()=>{"use strict";W()});import Po from"node:fs";import je from"node:path";function be(e){let n={critical:0,high:0,medium:0,low:0,info:0};for(let i of e)n[i.severity]=(n[i.severity]||0)+1;return n}function Ne(e){let n={};for(let i of e)n[i.category]=(n[i.category]||0)+1;return n}function Io(e,n){return yt(be(e),n)}function yt(e,n){if(n===0)return 100;let i={critical:25,high:10,medium:3,low:1,info:0},t=0;for(let[o,a]of Object.entries(e))t+=(i[o]||0)*a;let s=t/n,r=Math.max(0,Math.min(100,Math.round(100/(1+s/10))));return t===0?r:(e.critical??0)>0?Math.min(r,95):(e.high??0)>0?Math.min(r,98):Math.min(r,99)}function Bs(e){let n=new Map;for(let i of e)if(i.tags)for(let t of i.tags)n.set(t,(n.get(t)||0)+1);return[...n.entries()].map(([i,t])=>({tag:i,count:t})).sort((i,t)=>t.count-i.count)}function zs(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function No(e){let n=new Set(e),i=[];for(let[t,s]of Object.entries(B))if(s.length>0&&s.every(r=>n.has(r))){i.push(t);for(let r of s)n.delete(r)}return[...i,...[...n].sort()]}function Ks(e,n){return n?(B[e]||[]).some(t=>n.has(t)):!0}function xi(e,n){if(!Number.isFinite(n)||n>=e.length)return e;let i=new Map;for(let o of e){let a=o.category;i.has(a)||i.set(a,[]),i.get(a).push(o)}let t=[...i.entries()].sort((o,a)=>{let l=Pe[o[1][0].severity]??0;return(Pe[a[1][0].severity]??0)-l}),s=[],r=new Map;for(let[o]of t)r.set(o,0);for(;s.length<n;){let o=!1;for(let[a,l]of t){if(s.length>=n)break;let c=r.get(a);c<l.length&&(s.push(l[c]),r.set(a,c+1),o=!0)}if(!o)break}return s}function Ei(e,n=20,i=2){let t=[],s=new Map;for(let r of e){let o=s.get(r.category)||0;if(!(o>=i)&&(t.push(r),s.set(r.category,o+1),t.length>=n))break}return t}function Lo(e){return JSON.stringify(e.replace(/\\/g,"/"))}function vi(e){let{dir:n,report:i,outputFiles:t,architectureFindings:s,codeQualityFindings:r,deadCodeFindings:o,hotFiles:a=[],activeFeatures:l=null,scope:c=null,root:u=process.cwd(),scopeSymbols:d=null,semanticEnabled:f=!1,securityFindings:p=[],testQualityFindings:g=[],reportAnalysis:m=null,fileInventory:S=i.fileInventory||[]}=e,h=i.optimizationFindings||[],y=i.summary,D=i.agentOutput,b=D?.findingStats??null,k=i.dependencyGraph,C=je.relative(u,n)||".",A=((c?.[0]??"src/index").split(":")[0]||"src/index").replace(/\\/g,"/"),M=b?.overall??{totalFindings:h.length,severityBreakdown:be(h)},E=[];E.push(`# Code Quality Scan Report
|
|
4
|
+
`),E.push(`**Generated**: ${i.generatedAt} `),E.push(`**Root**: \`${i.repoRoot}\`
|
|
5
|
+
`),E.push(`## Scan Scope
|
|
6
|
+
`),E.push("| Metric | Count |"),E.push("|--------|-------|"),E.push(`| Files analyzed | ${y.totalFiles??"\u2014"} |`),E.push(`| Functions | ${y.totalFunctions??"\u2014"} |`),E.push(`| Flow nodes | ${y.totalFlows??"\u2014"} |`),E.push(`| Dependency files | ${y.totalDependencyFiles??"\u2014"} |`),E.push(`| Packages | ${y.totalPackages??"\u2014"} |`),E.push(""),E.push(`## Findings Overview
|
|
7
|
+
`),E.push("| Severity | Count |"),E.push("|----------|-------|"),E.push(`| Critical | ${M.severityBreakdown.critical??0} |`),E.push(`| High | ${M.severityBreakdown.high??0} |`),E.push(`| Medium | ${M.severityBreakdown.medium??0} |`),E.push(`| Low | ${M.severityBreakdown.low??0} |`),E.push(`| **Total** | **${M.totalFindings}** |`),E.push(""),Yo(E,{allFindings:h,overallFindingStats:M,agentOutput:D,activeFeatures:l,scope:c,root:u,scopeSymbols:d,semanticEnabled:f});let _=(j,X)=>{let re=Ne(X),P=B[j]||[],oe=l!==null;for(let ce of P){let Ae=re[ce]||0,ze=oe&&!l.has(ce);E.push(ze?`- \`${ce}\`: \u2014 *(skipped)*`:`- \`${ce}\`: ${Ae}`)}E.push("")},K=y.totalFiles||1,V=b?.pillars?.architecture,se=b?.pillars?.["code-quality"],fe=b?.pillars?.["dead-code"],H=b?.pillars?.security,te=b?.pillars?.["test-quality"],ye=qo(K,M,{archStats:V,qualStats:se,deadStats:fe,secStats:H,testStats:te,architectureFindings:s,codeQualityFindings:r,deadCodeFindings:o,securityFindings:p,testQualityFindings:g}),Ee=Jo(E,l,t),O=St(h,{fileInventory:S,hotFiles:a,reportAnalysis:m,includeTests:!!i.options?.includeTests});if(Wo(E,ye,l),Vo(E,bt(h,K,l,{hotFiles:a})),Qo(E,O),Xo(E,h),m&&Zo(E,m),ea(E,t,h),E.push(`## Architecture Health
|
|
8
|
+
`),Ee("architecture",V?.totalFindings??s.length,ye.archHealth,"architecture","architecture.json"),k&&(E.push("| Metric | Value |"),E.push("|--------|-------|"),E.push(`| Modules | ${k.totalModules} |`),E.push(`| Import edges | ${k.totalEdges} |`),E.push(`| Cycles | ${k.cycles?.length??0} |`),E.push(`| Critical paths | ${k.criticalPaths?.length??0} |`),E.push(`| Root modules | ${k.rootsCount} |`),E.push(`| Leaf modules | ${k.leavesCount} |`),E.push(`| Test-only modules | ${k.testOnlyModules?.length??0} |`),E.push(`| Unresolved imports | ${k.unresolvedEdgeCount} |`),E.push("")),_("architecture",s),ta(E,a),na(E,{architectureFindings:s,codeQualityFindings:r,deadCodeFindings:o,securityFindings:p,testQualityFindings:g,archStats:V,qualStats:se,deadStats:fe,secStats:H,testStats:te,...ye,activeFeatures:l,outputFiles:t,renderPillarCategories:_,pushPillarSummary:Ee}),ia(E,D),t.astTrees&&sa(E,n,t,u,C,A),ra(E,n,t),i.parseErrors?.length>0){E.push(`## Parse Errors
|
|
9
|
+
`),E.push(`${i.parseErrors.length} file(s) failed to parse:
|
|
10
|
+
`);for(let j of i.parseErrors.slice(0,10))E.push(`- \`${j.file}\`: ${j.message}`);E.push("")}return E.join(`
|
|
11
|
+
`)}function Ie(e){return Math.max(0,Math.min(100,Math.round(e)))}function ee(e,n,i=1.4){return e<=0?0:Math.round(n*(1-Math.exp(-e*i)))}function We(e){return e>=25?"high":e>=8?"medium":"low"}function et(e){return e.length===0?0:e.reduce((n,i)=>n+i,0)/e.length}function it(e){return e.replace(/\\/g,"/")}function _o(e){let n=it(e).toLowerCase();return/(?:^|\/)(?:dist|build|coverage|out|vendor|vendors|generated|gen|\.cache)(?:\/|$)/.test(n)||/\.min\.(?:js|jsx|mjs|cjs|css)$/i.test(n)||/\.bundle\./i.test(n)}function bi(e,n){let i=it(e);return!(!n.includeTests&&x(i)||!n.includeGenerated&&_o(i))}function Ho(e,n){let i=new Set;e.file&&i.add(e.file);for(let t of e.files||[])i.add(t);if(i.size===0)return!0;for(let t of i)if(bi(t,n))return!0;return!1}function Bo(e,n){return e.file&&n.has(e.file)?!0:(e.files||[]).some(i=>n.has(i))}function zo(e){return/^[a-z0-9]+(?:-[a-z0-9]+)+$/.test(e)?"kebab":/^[a-z0-9]+(?:_[a-z0-9]+)+$/.test(e)?"snake":/^[a-z]+(?:[A-Z][a-z0-9]*)+$/.test(e)?"camel":/^[a-z0-9]+$/.test(e)?"flat":"other"}function Ko(e,n){let i=new Set;for(let t of n)i.add(t.file);for(let t of e){t.file&&i.add(t.file);for(let s of t.files||[])i.add(s)}return i}function Ve(e,n,i={}){return e.length===0?0:e.reduce((s,r)=>{let o=Oo[r.severity]??.2,a=i.applyCategoryWeight?jo[r.category]??1:1;return s+o*a},0)/Math.max(1,n)}function Uo(e){if(e.length===0)return[];let n=e.map(t=>it(t).split("/").filter(Boolean)),i=0;for(;;){let t=n[0][i];if(!t)break;if(n.every(s=>s[i]===t)){i+=1;continue}break}return n.map(t=>{let s=t.slice(i);return s.length>0?s.join("/"):t.join("/")})}function St(e,n={}){let i=n.includeTests??!1,t=n.includeGenerated??!1,s={includeTests:i,includeGenerated:t},r=(n.fileInventory||[]).filter(F=>bi(F.file,s)),o=(n.hotFiles||[]).filter(F=>bi(F.file,s)),a=n.reportAnalysis||null,l=e.filter(F=>Ho(F,s)),c=Ko(l,r),u=Math.max(1,c.size),d=r.flatMap(F=>F.functions||[]),f=Math.max(1,d.length),p={architecture:l.filter(F=>(nt[F.category]||"unmapped")==="architecture"),codeQuality:l.filter(F=>(nt[F.category]||"unmapped")==="code-quality"),deadCode:l.filter(F=>(nt[F.category]||"unmapped")==="dead-code"),testQuality:l.filter(F=>(nt[F.category]||"unmapped")==="test-quality")},g=l.filter(F=>F.severity==="critical"||F.severity==="high"),m=[],S=p.architecture.filter(F=>F.severity==="critical"||F.severity==="high"),h=Ve(p.architecture,u,{applyCategoryWeight:!0}),y=Ve(S,u,{applyCategoryWeight:!0}),D=Ve(p.architecture.filter(F=>F.category==="dependency-cycle"||F.category==="cycle-cluster"),u,{applyCategoryWeight:!0}),b=[...o].sort((F,pe)=>pe.riskScore-F.riskScore).slice(0,8),k=Math.min(1,et(b.map(F=>Math.max(0,F.riskScore)))/100),C=a?.strongestGraphSignal?.confidence==="high"?3:a?.strongestGraphSignal?.confidence==="medium"?1:0,A=Ie(100-ee(h,24,1.35)-ee(y,22,1.9)-ee(D,16,2.2)-ee(k,12,1.3)+C);m.push({aspect:"architecture-structure",label:"Architecture & Structure",weight:30,score:A,grade:Fe(A),confidence:We(p.architecture.length),rationale:"Rates structural integrity using architecture findings, severity concentration, cycle pressure, and hotspot intensity, then tempers it with AI graph-signal confidence.",signals:[{label:"Architecture findings / file",value:h.toFixed(2),effect:p.architecture.length>0?"negative":"neutral"},{label:"Severe architecture findings",value:y.toFixed(2),effect:S.length>0?"negative":"neutral"},{label:"Hotspot pressure (avg risk top files)",value:et(b.map(F=>F.riskScore)).toFixed(1),effect:b.length>0?"negative":"neutral"}]});let M=[...c],E=Uo(M),_=E.map(F=>it(F).split("/").filter(Boolean).length),K=et(_),V=new Map,se=new Set,fe=/^(util|utils|common|shared|misc|helper|helpers|tmp|temp)$/i;for(let F of E){let dt=it(F).split("/").filter(Boolean),ut=dt[0]||".";V.set(ut,(V.get(ut)||0)+1);for(let wo of dt.slice(0,-1))se.add(wo)}let H=V.size===0?0:Math.max(...V.values())/u,te=se.size===0?0:[...se].filter(F=>fe.test(F)).length/se.size,ye=Ie(100-ee(Math.max(0,(K-4)/3),20,1.3)-ee(Math.max(0,H-.55),18,2)-ee(te,24,2.2));m.push({aspect:"folder-topology",label:"Folder Topology",weight:15,score:ye,grade:Fe(ye),confidence:We(M.length),rationale:"Rates how navigable the folder model is by blending depth balance, top-level concentration, and reliance on vague utility/common directories.",signals:[{label:"Average path depth",value:K.toFixed(1),effect:K>6?"negative":"neutral"},{label:"Dominant root share",value:`${Math.round(H*100)}%`,effect:H>.65?"negative":"neutral"},{label:"Vague directory ratio",value:`${Math.round(te*100)}%`,effect:te>.2?"negative":"neutral"}]});let Ee=/^(foo|bar|baz|tmp|temp|data|value|handler|util|helper|thing|stuff|fn|func)$/i,O=/^(utils?|helpers?|common|shared|misc|tmp|temp|new|old|types?)$/i,j=d.map(F=>F.name||F.nameHint||"").filter(F=>F.length>0),X=j.filter(F=>F==="<anonymous>"||F==="default").length,re=j.filter(F=>F!=="<anonymous>"&&F!=="default"),P=re.filter(F=>Ee.test(F)).length,oe=re.filter(F=>F.length<=2).length,ce=M.map(F=>je.basename(F,je.extname(F))),Ae=ce.filter(F=>O.test(F)).length,ze=Ie(100-ee(X/f,30,2.3)-ee(P/Math.max(1,re.length),24,2)-ee(Ae/u,15,1.8)-ee(oe/Math.max(1,re.length),10,1.8));m.push({aspect:"naming-quality",label:"Naming Quality",weight:15,score:ze,grade:Fe(ze),confidence:We(d.length),rationale:"Rates naming clarity by balancing anonymous/generic function names, short ambiguous names, and generic file basenames.",signals:[{label:"Anonymous function share",value:`${Math.round(X/f*100)}%`,effect:X>0?"negative":"neutral"},{label:"Generic function names",value:String(P),effect:P>0?"negative":"neutral"},{label:"Generic file names",value:String(Ae),effect:Ae>0?"negative":"neutral"}]});let ho=/(^|\/)(common|shared|utils?|lib|core)(\/|$)/i,ke=r.filter(F=>ho.test(F.file.replace(/\\/g,"/"))),yo=new Set(ke.map(F=>F.file)),ct=l.filter(F=>Bo(F,yo)),So=ct.filter(F=>F.severity==="critical"||F.severity==="high"),zt=et(ke.map(F=>{let pe=F.symbolUsageSummary?.internalImportCount??F.dependencyProfile.importedSymbols.filter(ut=>!!ut.resolvedModule).length,dt=F.symbolUsageSummary?.declaredExportCount??F.dependencyProfile.declaredExports.length;return pe/(dt+1)})),ds=ke.length===0?88:Ie(100-ee(ct.length/ke.length,24,1.6)-ee(So.length/ke.length,28,2.2)-ee(zt,18,1.5));m.push({aspect:"common-layer-health",label:"Common/Shared Layer Health",weight:15,score:ds,grade:Fe(ds),confidence:We(ke.length),rationale:ke.length===0?"No explicit common/shared layer was detected, so this aspect is neutral-positive by default.":"Rates whether shared/common code stays stable and lightweight by combining finding density, severe issue concentration, and internal dependency pressure.",signals:[{label:"Shared files",value:String(ke.length),effect:ke.length===0?"neutral":"positive"},{label:"Shared-layer findings",value:String(ct.length),effect:ct.length>0?"negative":"neutral"},{label:"Shared import pressure",value:zt.toFixed(2),effect:zt>1?"negative":"neutral"}]});let Kt=[...p.codeQuality,...p.deadCode,...p.testQuality],bo=new Set(["test-no-assertion","low-assertion-density","excessive-mocking","missing-test-cleanup","focused-test","fake-timer-no-restore","missing-mock-restoration"]),Ut=l.filter(F=>bo.has(F.category)),qt=et(d.map(F=>F.cognitiveComplexity||F.complexity||0)),us=Ve(Kt,u,{applyCategoryWeight:!0}),xo=Ve(g,u),Eo=Ve(Ut,u,{applyCategoryWeight:!0}),fs=Ie(100-ee(us,20,1.3)-ee(xo,22,1.8)-ee(Math.max(0,(qt-8)/12),22,1.4)-ee(Eo,12,1.5));m.push({aspect:"maintainability-evolvability",label:"Maintainability & Evolvability",weight:15,score:fs,grade:Fe(fs),confidence:We(Kt.length),rationale:"Rates how safely the codebase can evolve by blending quality/dead-code/test debt density, severe issue concentration, and cognitive complexity pressure.",signals:[{label:"Maintainability findings / file",value:us.toFixed(2),effect:Kt.length>0?"negative":"neutral"},{label:"Average cognitive complexity",value:qt.toFixed(1),effect:qt>12?"negative":"neutral"},{label:"Test debt findings",value:String(Ut.length),effect:Ut.length>0?"negative":"neutral"}]});let Ke=new Map;for(let F of ce){let pe=zo(F);Ke.set(pe,(Ke.get(pe)||0)+1)}let Gt=Ke.size===0?1:Math.max(...Ke.values())/u,ps=M.filter(F=>/\.(ts|tsx)$/i.test(F)).length,gs=M.filter(F=>/\.(js|jsx|mjs|cjs)$/i.test(F)).length,ms=Math.min(ps,gs)/u*2,hs=Ie(100-ee(1-Gt,24,2)-ee(ms,12,1.6)-ee(Ae/u,10,1.6));m.push({aspect:"codebase-consistency",label:"Codebase Consistency",weight:10,score:hs,grade:Fe(hs),confidence:We(M.length),rationale:"Rates naming/structure consistency with soft penalties for mixed filename styles, mixed TS/JS surface area, and generic file naming concentration.",signals:[{label:"Dominant naming style",value:`${Math.round(Gt*100)}%`,effect:Gt>=.7?"positive":"negative"},{label:"TS/JS mix ratio",value:`${Math.round(Math.min(ps,gs)/u*100)}%`,effect:ms>.5?"negative":"neutral"},{label:"Detected file naming styles",value:String(Ke.size),effect:Ke.size>3?"negative":"neutral"}]});let vo=m.reduce((F,pe)=>F+pe.weight,0)||1,ys=m.reduce((F,pe)=>F+pe.score*pe.weight,0)/vo;return{model:"hybrid-ai-structure-v1",overallScore:Ie(ys),overallGrade:Fe(Ie(ys)),aspects:m}}function tt(e,n){if(e<=0)return 0;let i=new Set;for(let s of n){s.file&&i.add(s.file);for(let r of s.files??[])i.add(r)}if(i.size===0)return e;let t=Math.max(1,Math.ceil(e*.1));return Math.max(t,Math.min(e,i.size))}function qo(e,n,i){let t=(c,u,d)=>yt(c?.severityBreakdown??be(u),d),s=tt(e,i.architectureFindings),r=tt(e,i.codeQualityFindings),o=tt(e,i.deadCodeFindings),a=tt(e,i.securityFindings),l=tt(e,i.testQualityFindings);return{overallHealth:yt(n.severityBreakdown,e),archHealth:t(i.archStats,i.architectureFindings,s),qualHealth:t(i.qualStats,i.codeQualityFindings,r),deadHealth:t(i.deadStats,i.deadCodeFindings,o),secHealth:t(i.secStats,i.securityFindings,a),testHealth:t(i.testStats,i.testQualityFindings,l)}}function Fe(e){return e>=80?"A":e>=60?"B":e>=40?"C":e>=20?"D":"F"}function Go(e){let n=Object.values(B).flat();return e?n.filter(i=>e.has(i)):n}function bt(e,n,i,t={}){let s=new Map;for(let l of t.hotFiles||[])s.set(l.file,l.riskScore);let r=Go(i),o=new Set(r);for(let l of e)o.has(l.category)||(!i||i.has(l.category))&&(r.push(l.category),o.add(l.category));let a=new Map;for(let l of e)a.has(l.category)||a.set(l.category,[]),a.get(l.category).push(l);return r.map(l=>{let c=a.get(l)||[],u=be(c),d=new Set;for(let b of c){b.file&&d.add(b.file);for(let k of b.files??[])d.add(k)}let f=d.size>0?Math.max(1,d.size):Math.max(1,n),p=yt(u,f),g=0,m=0;for(let b of d){let k=s.get(b)||0;k<=0||(g+=1,m=Math.max(m,k))}let S=d.size>0?g/d.size:0,h=m>=90?10:m>=75?7:m>=60?4:2,y=g===0?0:Math.min(20,Math.round(S*10+h)),D=Math.max(0,p-y);return{category:l,pillar:nt[l]||"unmapped",findings:c.length,affectedFiles:d.size,hotspotHits:g,hotspotMaxRisk:m,contextPenalty:y,severityBreakdown:u,score:D,grade:Fe(D)}}).sort((l,c)=>l.score!==c.score?l.score-c.score:l.findings!==c.findings?c.findings-l.findings:l.category.localeCompare(c.category))}function Wo(e,n,i){e.push(`## Health Scores
|
|
12
|
+
`),e.push("| Pillar | Score | Grade |"),e.push("|--------|-------|-------|");let t=(s,r,o)=>{if(!Ks(r,i)){e.push(`| ${s} | \u2014 | skipped |`);return}e.push(`| ${s} | ${o}/100 | ${Fe(o)} |`)};e.push(`| **Overall** | **${n.overallHealth}/100** | **${Fe(n.overallHealth)}** |`),t("Architecture","architecture",n.archHealth),t("Code Quality","code-quality",n.qualHealth),t("Dead Code & Hygiene","dead-code",n.deadHealth),t("Security","security",n.secHealth),t("Test Quality","test-quality",n.testHealth),e.push("")}function Vo(e,n){e.push(`## Feature Scores
|
|
13
|
+
`),e.push(`Per-category scoring for all active features (or all categories when unfiltered).
|
|
14
|
+
`),e.push("| Category | Pillar | Findings | Affected Files | Hotspot Hits | Context Penalty | Score | Grade |"),e.push("|----------|--------|----------|----------------|--------------|-----------------|-------|-------|");for(let i of n)e.push(`| \`${i.category}\` | ${i.pillar} | ${i.findings} | ${i.affectedFiles} | ${i.hotspotHits} | -${i.contextPenalty} | ${i.score}/100 | ${i.grade} |`);e.push("")}function Qo(e,n){e.push(`## AI + Structure Ratings
|
|
15
|
+
`),e.push(`Hybrid, soft-signal scoring that blends structural findings with architecture context, naming quality, folder topology, and shared-layer health.
|
|
16
|
+
`),e.push(`**Overall Hybrid Rating**: ${n.overallScore}/100 (${n.overallGrade}) `),e.push(`**Model**: \`${n.model}\`
|
|
17
|
+
`),e.push("| Aspect | Weight | Score | Grade | Confidence | Why it scored this way |"),e.push("|--------|--------|-------|-------|------------|------------------------|");for(let i of n.aspects)e.push(`| ${i.label} | ${i.weight}% | ${i.score}/100 | ${i.grade} | ${i.confidence} | ${i.rationale} |`);e.push("")}function Jo(e,n,i){return(t,s,r,o,a)=>{if(!Ks(t,n)){e.push(`> skipped by feature filter
|
|
18
|
+
`);return}if(o&&i[o]){e.push(`> ${s} findings (score: ${r}/100) \u2014 see [\`${a}\`](./${i[o]})
|
|
19
|
+
`);return}if(a){e.push(`> ${s} findings (score: ${r}/100) \u2014 no \`${a}\` written for this scan
|
|
20
|
+
`);return}e.push(`> ${s} findings (score: ${r}/100)
|
|
21
|
+
`)}}function Yo(e,n){let{allFindings:i,overallFindingStats:t,agentOutput:s}=n,r=t.totalFindings||s?.totalBeforeTruncation,o=s?.droppedCategories;if(r&&r>i.length&&(e.push(`> **Truncated**: Showing ${i.length} of ${r} findings (\`--findings-limit ${i.length}\`).`),o&&o.length>0&&e.push(`> Dropped categories: ${o.map(a=>`\`${a}\``).join(", ")}`),e.push("")),n.activeFeatures){let a=No(n.activeFeatures);e.push(`> **Features filter**: \`--features=${a.join(",")}\``),e.push("")}if(n.scope&&n.scope.length>0){let a=n.scope.map(l=>je.relative(n.root,l)).filter(Boolean);if(a.length>0){let l=a.map(c=>`\`${c}\``).join(", ");if(n.scopeSymbols&&n.scopeSymbols.size>0){let c=[];for(let[u,d]of n.scopeSymbols){let f=je.relative(n.root,u);c.push(...d.map(p=>`\`${f}:${p}\``))}l=c.join(", ")}e.push(`> **Scoped scan**: Only showing findings for: ${l}`),e.push("")}}n.semanticEnabled&&(e.push("> **Semantic analysis**: TypeChecker + LanguageService enabled (14 additional categories)"),e.push(""))}function Xo(e,n){let i=Bs(n);if(i.length!==0){e.push(`## Top Concern Tags
|
|
22
|
+
`),e.push("Searchable tags across all findings \u2014 use to filter `findings.json` with `jq`.\n");for(let{tag:t,count:s}of i.slice(0,12))e.push(`- \`${t}\`: ${s} findings`);e.push("")}}function Zo(e,n){e.push(`## Analysis Signals
|
|
23
|
+
`),e.push(`- **Graph Signal**: ${n.strongestGraphSignal?.summary||"No dominant graph signal in this scan."}`),e.push(`- **AST Signal**: ${n.strongestAstSignal?.summary||"No dominant AST signal in this scan."}`),e.push(`- **Combined Interpretation**: ${n.combinedInterpretation?.summary||"No combined interpretation available yet."}`),e.push(`- **Confidence**: ${n.combinedInterpretation?.confidence||n.strongestGraphSignal?.confidence||n.strongestAstSignal?.confidence||"low"}`);let i=n.recommendedValidation?`${n.recommendedValidation.summary} (tools: ${n.recommendedValidation.tools.join(" -> ")})`:"Use Octocode local tools to confirm the strongest signal before presenting it as fact.";e.push(`- **Recommended Validation**: ${i}`);let t=n.graphSignals.find(s=>s.kind==="mega-folder-cluster");if(t&&e.push(`- **Structural Layout Alert**: ${t.summary}`),n.investigationPrompts.length>0){e.push(""),e.push("**Investigation Prompts**");for(let s of n.investigationPrompts.slice(0,4))e.push(`- ${s}`)}e.push("")}function ea(e,n,i){let t=i.some(s=>s.severity==="critical"||s.severity==="high");e.push(`## Agent Instructions \u2014 Validate Before Presenting
|
|
24
|
+
`),e.push(`> **Core rule**: Findings are hypotheses from deterministic AST/graph detectors. Validate with Octocode local + LSP tools before presenting any finding as fact.
|
|
25
|
+
`),e.push(`### Triage Order
|
|
26
|
+
`),e.push("1. **This file first** \u2014 health scores + analysis signals drive triage priority"),t?e.push('2. **High/critical findings** \u2014 filter `findings.json`: `jq \'.optimizationFindings[] | select(.severity == "critical" or .severity == "high")\' findings.json`'):e.push("2. **Findings by severity** \u2014 start from the top of `findings.json` (already sorted by severity)"),e.push("3. **Pillar JSONs** \u2014 drill into `architecture.json`, `code-quality.json`, etc. only for categories that need investigation"),e.push("4. **`file-inventory.json`** \u2014 per-file deep dives: functions, flows, `effectProfile`, `cfgFlags`, `dependencyProfile`"),e.push(""),e.push(`### Validation Tool Chain
|
|
27
|
+
`),e.push("Each finding includes `lspHints[]`, `correlatedSignals[]`, and `recommendedValidation`. Use them.\n"),e.push("```"),e.push("Finding \u2192 localSearchCode (get lineHint) \u2192 LSP tool \u2192 localGetFileContent \u2192 verdict"),e.push("```\n"),e.push("| Step | Tool | Purpose |"),e.push("|------|------|---------|"),e.push("| 1. Search | `localSearchCode(pattern, path)` | **Always first** \u2014 get `lineHint` for LSP. Never guess lineHint. |"),e.push("| 2. Locate | `lspGotoDefinition(lineHint)` | Jump to definition across files |"),e.push("| 3. Consumers | `lspFindReferences(lineHint)` | Count usages, split test/prod with `includePattern`/`excludePattern` |"),e.push("| 4. Call flow | `lspCallHierarchy(lineHint, incoming/outgoing)` | Trace call chains \u2014 **functions only**, fails on types/vars |"),e.push("| 5. Read code | `localGetFileContent(path, matchString=...)` | Confirm code at reported location |"),e.push("| 6. AST proof | `ast/search.js -p <pattern> --root <path>` | Structural proof on **live source** \u2014 zero false positives |"),n.astTrees&&e.push("| 7. AST triage | `ast/tree-search.js -i <scan-dir> -k <Kind>` | Fast triage on scan snapshot \u2014 `-k FunctionDeclaration`, `-p 'IfStatement\\|ForStatement'`, `--file` filter, `-C 2` context |"),e.push(""),e.push(`### False Positive Checklist
|
|
28
|
+
`),e.push(`Before reporting a finding to the user:
|
|
29
|
+
`),e.push("- [ ] Ran `lspHints[]` from the finding \u2014 result matches expectation?"),e.push("- [ ] Code exists at reported `file:lineStart` \u2014 confirmed with `localGetFileContent`?"),e.push("- [ ] Pattern confirmed in live source \u2014 `ast/search.js -p` or `localSearchCode`?"),e.push("- [ ] Not in generated, vendored, or test-only code?"),e.push("- [ ] `correlatedSignals[]` \u2014 multiple signals on same file strengthen confidence"),e.push("- [ ] Consumer count verified with `lspFindReferences` \u2014 matches claimed impact?"),e.push(""),e.push("**Rate each finding**: `confirmed` (evidence supports) \xB7 `dismissed` (explain why) \xB7 `uncertain` (state what's missing)\n")}function ta(e,n){if(!(!n||n.length===0)){e.push(`## Change Risk Hotspots
|
|
30
|
+
`),e.push(`Files most dangerous to change \u2014 high fan-in, complexity, or cycle membership.
|
|
31
|
+
`),e.push("| File | Risk | Fan-In | Fan-Out | Complexity | Exports | Cycle | Critical Path |"),e.push("|------|------|--------|---------|------------|---------|-------|---------------|");for(let i of n.slice(0,15))e.push(`| \`${i.file}\` | ${i.riskScore} | ${i.fanIn} | ${i.fanOut} | ${i.complexityScore} | ${i.exportCount} | ${i.inCycle?"Y":"-"} | ${i.onCriticalPath?"Y":"-"} |`);e.push("")}}function na(e,n){let{architectureFindings:i,codeQualityFindings:t,deadCodeFindings:s,securityFindings:r,testQualityFindings:o}=n,{qualStats:a,deadStats:l,secStats:c,testStats:u}=n,{qualHealth:d,deadHealth:f,secHealth:p,testHealth:g}=n,{renderPillarCategories:m,pushPillarSummary:S}=n;e.push(`## Code Quality
|
|
32
|
+
`),S("code-quality",a?.totalFindings??t.length,d,"codeQuality","code-quality.json"),m("code-quality",t),e.push(`## Dead Code & Hygiene
|
|
33
|
+
`),S("dead-code",l?.totalFindings??s.length,f,"deadCode","dead-code.json"),m("dead-code",s),e.push(`## Security
|
|
34
|
+
`),S("security",c?.totalFindings??r.length,p,"security","security.json"),m("security",r),e.push(`## Test Quality
|
|
35
|
+
`),S("test-quality",u?.totalFindings??o.length,g,"testQuality","test-quality.json"),m("test-quality",o);let h=i.filter(y=>y.category==="untested-critical-code").length;h>0&&(u?.totalFindings??o.length)===0&&e.push(`> **Note**: Test Quality reflects analyzed test files only. ${h} modules flagged as \`untested-critical-code\` (architecture pillar) have no test coverage \u2014 use \`--include-tests\` for test-quality analysis.
|
|
36
|
+
`)}function ia(e,n){let i=n?.topRecommendations??[];if(i.length>0){e.push(`## Top Recommendations
|
|
37
|
+
`);for(let t of i.slice(0,10))e.push(`- **[${t.severity.toUpperCase()}]** \`${t.file}\` \u2014 ${t.title} *(${t.category})* `);e.push("")}}function sa(e,n,i,t,s,r){let o=je.resolve(n,i.astTrees),a=Lo(o);e.push("## AST Trees (`ast-trees.txt`)\n"),e.push("Compact indented text format \u2014 each node is `Kind[startLine:endLine]`, nesting = indentation.\n"),e.push(`Run these commands from the skill directory. Current scan: \`${s}\`.
|
|
38
|
+
`),e.push("```"),e.push("SourceFile[1:152]"),e.push(" ImportDeclaration[1]"),e.push(" FunctionDeclaration[3:20]"),e.push(" Block[4:19]"),e.push(" IfStatement[5:12] ..."),e.push("```\n"),e.push(`**Smart navigation:**
|
|
39
|
+
`),e.push(`- Find functions: \`node scripts/ast/tree-search.js -i ${a} -k function_declaration --limit 25\``),e.push(`- Find classes: \`node scripts/ast/tree-search.js -i ${a} -k class_declaration --limit 25\``),e.push(`- Find control flow: \`node scripts/ast/tree-search.js -i ${a} -p 'IfStatement|SwitchStatement|ForStatement|WhileStatement' --limit 25\``),e.push(`- Narrow to one file: \`node scripts/ast/tree-search.js -i ${a} --file "${r}" -k function_declaration --limit 10\``),e.push(`- Raw text fallback: \`rg 'FunctionDeclaration|IfStatement' ${a}\``),e.push("")}function ra(e,n,i){e.push(`## Output Files
|
|
40
|
+
`),e.push("| File | Size | Description |"),e.push("|------|------|-------------|");let t={summary:"Scan metadata, agent output, parse errors",architecture:"Dependency graph, cycles, critical paths, architecture findings",codeQuality:"Duplicate detection, complexity, god modules/functions",deadCode:"Dead files/exports/re-exports, unused deps, boundary violations",fileInventory:"Per-file function/flow/dependency details",findings:"All findings across all categories (master list)",graph:"Mermaid dependency graph",astTrees:"AST tree snapshots (compact indented text \u2014 grep/regex friendly)",summaryMd:"This file \u2014 human-readable overview"};for(let[s,r]of Object.entries(i)){let o="\u2014";try{o=zs(Po.statSync(je.join(n,r)).size)}catch{o="\u2014"}e.push(`| [\`${r}\`](./${r}) | ${o} | ${t[s]||s} |`)}e.push("")}var nt,Oo,jo,st=N(()=>{"use strict";W();me();nt=Object.entries(B).reduce((e,[n,i])=>{for(let t of i)e[t]=n;return e},{});Oo={critical:1,high:.75,medium:.45,low:.2,info:.05},jo={"dependency-critical-path":.45,"broker-module":.55,"bridge-module":.55,"distance-from-main-sequence":.6,"over-abstraction":.65,"concrete-dependency":.65,"move-to-caller":.35,"similar-function-body":.55,"dead-export":.65,"semantic-dead-export":.6}});import{EventEmitter as oa}from"node:events";function Us(){le.on("progress",e=>{e.detail?process.stderr.write(`[${e.phase}] ${e.message}: ${e.detail}
|
|
41
|
+
`):process.stderr.write(`[${e.phase}] ${e.message}
|
|
42
|
+
`)})}var wi,le,Fi=N(()=>{"use strict";wi=class extends oa{progress(n,i,t){this.emit("progress",{phase:n,message:i,detail:t})}summary(n){this.emit("summary",n)}error(n,i){this.emit("error",{message:n,detail:i})}reset(){this.removeAllListeners()}},le=new wi});var qs={};Wt(qs,{OptionsError:()=>Le,createOptions:()=>xt,resolveExcludeToFeatures:()=>ki});import aa from"node:path";function xt({args:e}){let n={...e};return n.packageRoot=aa.join(n.root,"packages"),la(n),n}function la(e){if(e.features===null)return;let n=new Set(B["test-quality"]);[...e.features].some(i=>n.has(i))&&(e.includeTests=!0)}function ki(e){return new Set([...Ue].filter(n=>!e.has(n)))}var Le,rt=N(()=>{"use strict";me();Le=class extends Error{constructor(n){super(n),this.name="OptionsError"}}});import Ti from"node:path";function Ci(e,n){let i=parseInt(e??"",10);return Number.isNaN(i)?n:i}function ca(e,n){let i=parseFloat(e??"");return Number.isNaN(i)?n:i}function Gs(e,n,i,t){e[n]=Ci(i,t[n])}function da(e,n,i,t){e[n]=ca(i,t[n])}function Ws(e,n){let i=e.split(",").map(s=>s.trim()).filter(Boolean),t=new Set;for(let s of i)if(B[s])for(let r of B[s])t.add(r);else Ue.has(s)?t.add(s):(console.error(`Unknown ${n}: "${s}". Use pillar names (${Object.keys(B).join(", ")}) or category names.`),process.exit(1));return t}function ua(e,n){let i=r=>{let o=r.lastIndexOf(":");if(o<=0||o===r.length-1)return{filePath:r,symbolName:null};let a=r.substring(o+1);return a.includes("/")||a.includes("\\")?{filePath:r,symbolName:null}:{filePath:r.substring(0,o),symbolName:a}},t=[],s=new Map;for(let r of e.split(",").map(o=>o.trim()).filter(Boolean)){let{filePath:o,symbolName:a}=i(r),l=Ti.resolve(n,o);t.push(l),a&&(s.has(l)||s.set(l,[]),s.get(l).push(a))}return{paths:t,symbols:s}}function er(e){let n={...Me,thresholds:{...Me.thresholds}},i=null;for(let t=0;t<e.length;t++){let s=e[t];if(Vs[s]){Vs[s](n,!0);continue}if(Qs[s]){let r=Qs[s];Gs(n,r,e[++t],Me);continue}if(Js[s]){let r=Js[s];Gs(n.thresholds,r,e[++t],Me.thresholds);continue}if(Ys[s]){let r=Ys[s];da(n.thresholds,r,e[++t],Me.thresholds);continue}if(Xs[s]){t=Xs[s](n,e,t);continue}if(s.startsWith("--out=")){n.out=s.slice(6);continue}if(s==="--scope"||s.startsWith("--scope=")){let r=s.startsWith("--scope=")?s.slice(8):e[++t],{paths:o,symbols:a}=ua(r,n.root);n.scope=o,a.size>0&&(n.scopeSymbols=a);continue}if(s==="--features"||s.startsWith("--features=")){let r=s.startsWith("--features=")?s.slice(11):e[++t];n.features=Ws(r,"feature");continue}if(s==="--exclude"||s.startsWith("--exclude=")){let r=s.startsWith("--exclude=")?s.slice(10):e[++t];i=Ws(r,"exclude");continue}if(s==="--affected"||s.startsWith("--affected=")){n.affected=s.startsWith("--affected=")?s.slice(11):e[t+1]&&!e[t+1].startsWith("--")?e[++t]:"HEAD";continue}if(s==="--ignore-known"||s.startsWith("--ignore-known=")){n.ignoreKnown=s.startsWith("--ignore-known=")?s.slice(15):e[t+1]&&!e[t+1].startsWith("--")?e[++t]:".octocode/baseline.json";continue}if(s==="--focus"||s.startsWith("--focus=")){n.focus=s.startsWith("--focus=")?s.slice(8):e[++t];continue}if(s==="--collapse"||s.startsWith("--collapse=")){let r=s.startsWith("--collapse=")?s.slice(11):e[++t];n.collapse=Ci(r,2);continue}if(s==="--at-least"||s.startsWith("--at-least=")){let r=s.startsWith("--at-least=")?s.slice(11):e[++t];n.atLeast=Ci(r,0);continue}s.startsWith("--")&&console.warn(`Warning: unknown flag "${s}" \u2014 ignored.`)}if(n.packageRoot=Ti.join(n.root,"packages"),n.features!==null&&i!==null)throw new Le("--features and --exclude are mutually exclusive. Use one or the other.");if(i!==null&&(n.features=ki(i)),n.features!==null){let t=new Set(B["test-quality"]);[...n.features].some(s=>t.has(s))&&(n.includeTests=!0)}return n}function Zs(){console.log(tr)}var Vs,Qs,Js,Ys,Xs,tr,$i=N(()=>{"use strict";me();rt();Vs={"--json":e=>{e.json=!0},"--include-tests":e=>{e.includeTests=!0},"--emit-tree":e=>{e.emitTree=!0},"--no-tree":e=>{e.emitTree=!1},"--graph":e=>{e.graph=!0},"--semantic":e=>{e.semantic=!0},"--no-diversify":e=>{e.noDiversify=!0},"--no-cache":e=>{e.noCache=!0},"--clear-cache":e=>{e.clearCache=!0},"--graph-advanced":e=>{e.graphAdvanced=!0},"--flow":e=>{e.flow=!0},"--all":e=>{e.includeTests=!0,e.semantic=!0},"--save-baseline":e=>{e.saveBaseline=!0}},Qs={"--findings-limit":"findingsLimit","--deep-link-topn":"deepLinkTopN","--tree-depth":"treeDepth","--max-recs-per-category":"maxRecsPerCategory","--focus-depth":"focusDepth"},Js={"--min-function-statements":"minFunctionStatements","--min-flow-statements":"minFlowStatements","--critical-complexity-threshold":"criticalComplexityThreshold","--coupling-threshold":"couplingThreshold","--fan-in-threshold":"fanInThreshold","--fan-out-threshold":"fanOutThreshold","--god-module-statements":"godModuleStatements","--god-module-exports":"godModuleExports","--god-function-statements":"godFunctionStatements","--god-function-mi-threshold":"godFunctionMiThreshold","--cognitive-complexity-threshold":"cognitiveComplexityThreshold","--barrel-symbol-threshold":"barrelSymbolThreshold","--parameter-threshold":"parameterThreshold","--halstead-effort-threshold":"halsteadEffortThreshold","--maintainability-index-threshold":"maintainabilityIndexThreshold","--any-threshold":"anyThreshold","--flow-dup-threshold":"flowDupThreshold","--override-chain-threshold":"overrideChainThreshold","--shotgun-threshold":"shotgunThreshold","--secret-min-length":"secretMinLength","--mock-threshold":"mockThreshold","--deep-nesting-threshold":"deepNestingThreshold","--multiple-return-threshold":"multipleReturnThreshold","--magic-string-min-occurrences":"magicStringMinOccurrences","--boolean-param-threshold":"booleanParamThreshold"},Ys={"--secret-entropy-threshold":"secretEntropyThreshold","--similarity-threshold":"similarityThreshold","--sdp-min-delta":"sdpMinDelta","--sdp-max-source-instability":"sdpMaxSourceInstability"},Xs={"--parser":(e,n,i)=>{let t=n[i+1];return["auto","typescript","tree-sitter"].includes(t)||(console.error(`Unsupported parser: ${t}. Use auto|typescript|tree-sitter`),process.exit(1)),e.parser=t,i+1},"--root":(e,n,i)=>(e.root=Ti.resolve(n[i+1]),i+1),"--out":(e,n,i)=>(e.out=n[i+1],i+1),"--layer-order":(e,n,i)=>(e.thresholds.layerOrder=n[i+1].split(",").map(t=>t.trim()),i+1),"--reporter":(e,n,i)=>{let t=n[i+1];return["default","compact","github-actions"].includes(t)||(console.error(`Unsupported reporter: ${t}. Use default|compact|github-actions`),process.exit(1)),e.reporter=t,i+1},"--config":(e,n,i)=>(e.configFile=n[i+1],i+1),"--help":()=>(Zs(),process.exit(0)),"-h":()=>(Zs(),process.exit(0))};tr=`
|
|
43
|
+
Usage:
|
|
44
|
+
node scripts/run.js [options]
|
|
45
|
+
|
|
46
|
+
Options:
|
|
47
|
+
--root <path> Analyze a different repo root (default: cwd)
|
|
48
|
+
--out <path> Output directory for split report files (timestamped dir by default).
|
|
49
|
+
If path ends with .json, writes single monolithic file (legacy mode).
|
|
50
|
+
--json Print report JSON to stdout
|
|
51
|
+
--include-tests Include *.test* and *.spec* files
|
|
52
|
+
--parser <auto|typescript|tree-sitter>
|
|
53
|
+
Parser engine for extra AST metadata (default: auto)
|
|
54
|
+
--no-tree Do not write AST trees to report
|
|
55
|
+
--emit-tree Force include tree blocks
|
|
56
|
+
--graph Emit Mermaid dependency graph to .md file alongside JSON
|
|
57
|
+
--graph-advanced Enable advanced graph overlays and additional architecture findings
|
|
58
|
+
--flow Enable lightweight flow enrichment for evidence traces and cfgFlags
|
|
59
|
+
--min-function-statements N Minimum function body statement count for duplicate matching (default 6)
|
|
60
|
+
--min-flow-statements N Minimum control-flow statement count for duplicate matching (default 6)
|
|
61
|
+
--critical-complexity-threshold N
|
|
62
|
+
Complexity threshold for HIGH complexity findings and critical path weighting.
|
|
63
|
+
--findings-limit N Cap findings in the report (default: no limit)
|
|
64
|
+
--deep-link-topn N Max number of critical dependency paths to report (default 12)
|
|
65
|
+
--tree-depth N AST tree depth when tree snapshots are emitted (default 4)
|
|
66
|
+
--coupling-threshold N Ca+Ce threshold for high-coupling findings (default 15)
|
|
67
|
+
--fan-in-threshold N Fan-in threshold for god-module-coupling (default 20)
|
|
68
|
+
--fan-out-threshold N Fan-out threshold for god-module-coupling (default 15)
|
|
69
|
+
--god-module-statements N Statement threshold for god-module findings (default 500)
|
|
70
|
+
--god-module-exports N Export threshold for god-module findings (default 20)
|
|
71
|
+
--god-function-statements N Statement threshold for god-function findings (default 100)
|
|
72
|
+
--god-function-mi-threshold N MI threshold for god-function findings (default 10, fires when MI < N and LOC > 30)
|
|
73
|
+
--cognitive-complexity-threshold N
|
|
74
|
+
Cognitive complexity threshold for findings (default 15)
|
|
75
|
+
--barrel-symbol-threshold N Re-export count threshold for barrel-explosion (default 30)
|
|
76
|
+
--layer-order <layers> Comma-separated layer names for violation detection (e.g. ui,service,repository)
|
|
77
|
+
--parameter-threshold N Max function parameters before flagging (default 5)
|
|
78
|
+
--halstead-effort-threshold N Halstead effort threshold for findings (default 500000)
|
|
79
|
+
--maintainability-index-threshold N
|
|
80
|
+
MI below this triggers a finding (default 20, scale 0-100)
|
|
81
|
+
--any-threshold N Max \`any\` type usages per file before flagging (default 5)
|
|
82
|
+
--flow-dup-threshold N Min occurrences for a repeated flow to become a finding (default 3)
|
|
83
|
+
--max-recs-per-category N Max findings per category in top recommendations (default 2)
|
|
84
|
+
--scope=X,Y,Z Limit scan to specific paths, files, or functions. Comma-separated.
|
|
85
|
+
Supports file:functionName to drill into a specific function.
|
|
86
|
+
Examples: --scope=packages/octocode-mcp
|
|
87
|
+
--scope=packages/octocode-mcp/src/tools
|
|
88
|
+
--scope=packages/octocode-mcp/src/session.ts
|
|
89
|
+
--scope=packages/octocode-mcp/src/session.ts:initSession
|
|
90
|
+
--scope=packages/foo,packages/bar
|
|
91
|
+
--features=X,Y,Z Run only selected features. Accepts pillar names (architecture,
|
|
92
|
+
code-quality, dead-code, security, test-quality) or individual
|
|
93
|
+
category names. Comma-separated.
|
|
94
|
+
Examples: --features=architecture
|
|
95
|
+
--features=dead-code,cognitive-complexity
|
|
96
|
+
--features=dependency-cycle,dead-export
|
|
97
|
+
--exclude=X,Y,Z Run everything EXCEPT the given pillars or categories. Mutually
|
|
98
|
+
exclusive with --features. Same pillar/category names as --features.
|
|
99
|
+
Examples: --exclude=architecture
|
|
100
|
+
--exclude=dead-export,unsafe-any
|
|
101
|
+
--semantic Enable semantic analysis phase (TypeChecker + LanguageService).
|
|
102
|
+
Adds 12 categories: over-abstraction, concrete-dependency,
|
|
103
|
+
circular-type-dependency, unused-parameter,
|
|
104
|
+
deep-override-chain, interface-compliance, unused-import,
|
|
105
|
+
orphan-implementation, shotgun-surgery, move-to-caller,
|
|
106
|
+
narrowable-type, semantic-dead-export.
|
|
107
|
+
--override-chain-threshold N Max method override depth before flagging (default 3, requires --semantic)
|
|
108
|
+
--shotgun-threshold N Unique-file threshold for shotgun-surgery (default 8, requires --semantic)
|
|
109
|
+
--sdp-min-delta N Min instability delta for SDP violations (default 0.15)
|
|
110
|
+
--sdp-max-source-instability N Max source instability to report SDP (default 0.6)
|
|
111
|
+
--secret-entropy-threshold N Shannon entropy threshold for secret detection (default 4.5)
|
|
112
|
+
--secret-min-length N Min string length for entropy-based secret detection (default 20)
|
|
113
|
+
--similarity-threshold N Jaccard similarity threshold for near-clone detection (default 0.85)
|
|
114
|
+
--deep-nesting-threshold N Max branch/loop nesting depth before flagging (default 5)
|
|
115
|
+
--multiple-return-threshold N Max return/throw paths per function before flagging (default 6)
|
|
116
|
+
--magic-string-min-occurrences N
|
|
117
|
+
Min repeated string comparisons to flag as magic string (default 3)
|
|
118
|
+
--boolean-param-threshold N Min boolean params per function to flag as cluster (default 3)
|
|
119
|
+
--mock-threshold N Max mock/spy calls per test file (default 10)
|
|
120
|
+
--no-diversify Disable category-aware diversification when truncating findings.
|
|
121
|
+
By default, --findings-limit interleaves categories so the
|
|
122
|
+
truncated list is diverse. Use this to get pure severity ordering.
|
|
123
|
+
--no-cache Disable incremental cache; re-parse all files
|
|
124
|
+
--clear-cache Delete the analysis cache and exit (no scan)
|
|
125
|
+
--all Enable all features: --include-tests --semantic
|
|
126
|
+
|
|
127
|
+
--affected [revision] Scope to files changed since git revision (default: HEAD) plus
|
|
128
|
+
their transitive dependents. Like dep-cruiser's --affected flag.
|
|
129
|
+
Examples: --affected
|
|
130
|
+
--affected HEAD~3
|
|
131
|
+
--affected main
|
|
132
|
+
--save-baseline Save current findings to .octocode/baseline.json for future
|
|
133
|
+
comparison. Use with --ignore-known for progressive adoption.
|
|
134
|
+
--ignore-known [file] Suppress findings matching a baseline file (default:
|
|
135
|
+
.octocode/baseline.json). Findings are matched by (category, file).
|
|
136
|
+
--reporter <format> Output format: default|compact|github-actions (default: default)
|
|
137
|
+
compact: one-line per finding for terminal/CI logs
|
|
138
|
+
github-actions: ::warning annotations for GitHub Actions
|
|
139
|
+
--focus <module> Show only this module and its neighbors in the dependency graph.
|
|
140
|
+
Requires --graph. Use with --focus-depth to control neighbor hops.
|
|
141
|
+
Examples: --focus src/session.ts
|
|
142
|
+
--focus=src/session.ts
|
|
143
|
+
--focus packages/octocode-mcp/src/tools
|
|
144
|
+
--focus-depth N Neighbor depth for --focus (default 1). 2 = friends-of-friends.
|
|
145
|
+
--collapse N Collapse graph nodes to folder depth N. Reduces large graphs to
|
|
146
|
+
high-level architecture view. Example: --collapse 2
|
|
147
|
+
--at-least N Fail (exit 1) if health score drops below N (0-100). Use in CI
|
|
148
|
+
to enforce a quality floor. Example: --at-least 60
|
|
149
|
+
--config <file> Path to config file. Also auto-discovers .octocode-scan.json,
|
|
150
|
+
.octocode-scan.jsonc, or package.json#octocode in the project root.
|
|
151
|
+
--help Show this message
|
|
152
|
+
`});import Et from"node:fs";import vt from"node:path";function sr(e){let n=vt.join(e,".octocode","scan",".cache","analysis-cache.json");try{let i=JSON.parse(Et.readFileSync(n,"utf8"));return i.version!==ir||i.root!==e||i.schemaVersion!==nr?null:i}catch{return null}}function rr(e,n){let i=vt.join(e,".octocode","scan",".cache");Et.mkdirSync(i,{recursive:!0}),Et.writeFileSync(vt.join(i,"analysis-cache.json"),JSON.stringify(n),"utf8")}function or(e){let n=vt.join(e,".octocode","scan",".cache","analysis-cache.json");try{Et.unlinkSync(n)}catch{}}function ar(e,n,i){if(!e)return!1;let t=e.entries[n];return t?t.mtimeMs===i.mtimeMs&&t.sizeBytes===i.size:!1}function lr(e,n){let i=e.entries[n];return i&&(i.lastAccessMs=Date.now()),i?.result}function Di(e,n,i,t){e.entries[n]={mtimeMs:i.mtimeMs,sizeBytes:i.size,result:t,lastAccessMs:Date.now()}}function cr(e){return{version:ir,schemaVersion:nr,root:e,entries:{}}}function dr(e,n=fa){let i=Date.now(),t=[];for(let[s,r]of Object.entries(e.entries))i-r.lastAccessMs>n&&t.push(s);for(let s of t)delete e.entries[s];return t.length}var nr,ir,fa,ur=N(()=>{"use strict";nr="1.1.0",ir=1,fa=10080*60*1e3});import Ft from"node:fs";import wt from"node:path";function Ri(e,n){if(n){let t=wt.isAbsolute(n)?n:wt.resolve(e,n);return fr(t)}for(let t of pa){let s=wt.join(e,t);if(Ft.existsSync(s))return fr(s)}let i=wt.join(e,"package.json");if(Ft.existsSync(i))try{let t=JSON.parse(Ft.readFileSync(i,"utf8"));if(t.octocode&&typeof t.octocode=="object")return pr(t.octocode)}catch{}return null}function fr(e){try{let n=Ft.readFileSync(e,"utf8");return n=n.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,""),pr(JSON.parse(n))}catch{return null}}function pr(e){let n={};for(let[i,t]of Object.entries(e)){let s=i.replace(/-([a-z])/g,(r,o)=>o.toUpperCase());s==="features"&&typeof t=="string"?n[s]=new Set(t.split(",").map(r=>r.trim())):s==="scope"&&typeof t=="string"?n[s]=t.split(",").map(r=>r.trim()):s==="ignoreDirs"&&Array.isArray(t)?n[s]=new Set(t):n[s]=t}return n}function Ai(e,n,i){let t={...e};for(let[s,r]of Object.entries(n))s==="thresholds"&&typeof r=="object"&&r!==null?t.thresholds={...t.thresholds,...r}:t[s]=r;for(let s of Object.keys(i)){let r=i[s],o=e[s];r!==o&&(t[s]=r)}return t}var pa,Mi=N(()=>{"use strict";pa=[".octocode-scan.json",".octocode-scan.jsonc"]});import{execSync as ga}from"node:child_process";import ma from"node:path";function Pi(e,n,i){let t=ha(e,n);if(t.length===0)return[];let s=new Set(t),r=new Set(s);return ya(s,i,r),[...r]}function ha(e,n){try{let i=ga(`git diff --name-only --diff-filter=ACMRT ${n}`,{cwd:e,encoding:"utf8",timeout:1e4}).trim();return i?i.split(`
|
|
153
|
+
`).filter(t=>{let s=ma.extname(t);return qe.has(s)}):[]}catch{return[]}}function ya(e,n,i){let t=[...e];for(;t.length>0;){let s=t.pop(),r=n.incoming.get(s);if(r)for(let o of r)i.has(o)||(i.add(o),t.push(o))}}var Ii=N(()=>{"use strict";me()});import kt from"node:fs";import Ct from"node:path";function Ni(e,n){let i=Ct.join(e,".octocode","baseline.json"),t=Ct.dirname(i);kt.mkdirSync(t,{recursive:!0});let s=n.map(o=>({category:o.category,file:o.file,title:o.title})),r={generatedAt:new Date().toISOString(),count:s.length,entries:s};return kt.writeFileSync(i,JSON.stringify(r,null,2),"utf8"),i}function Li(e,n,i){let t=Ct.isAbsolute(n)?n:Ct.resolve(i,n);if(!kt.existsSync(t))return{filtered:e,suppressedCount:0};try{let r=JSON.parse(kt.readFileSync(t,"utf8")).entries||[],o=new Set(r.map(l=>`${l.category}::${l.file}`)),a=e.filter(l=>!o.has(`${l.category}::${l.file}`));return{filtered:a,suppressedCount:e.length-a.length}}catch{return{filtered:e,suppressedCount:0}}}var Oi=N(()=>{"use strict"});function ji(e,n,i){switch(n){case"compact":return ba(e,i);case"github-actions":return xa(e,i);default:return""}}function gr(e,n){return e.startsWith(n)?e.slice(n.length+1):e}function Sa(e){switch(e){case"critical":return"error";case"high":return"error";case"medium":return"warning";case"low":return"notice";default:return"warning"}}function ba(e,n){return e.map(i=>{let t=gr(i.file,n),s=i.lineStart?`${t}:${i.lineStart}`:t;return`${i.severity}:${s} - [${i.category}] ${i.title}`}).join(`
|
|
154
|
+
`)}function xa(e,n){return e.map(i=>{let t=gr(i.file,n),s=i.lineStart||1;return`::${Sa(i.severity)} file=${t},line=${s}::${i.title} [${i.category}]`}).join(`
|
|
155
|
+
`)}var _i=N(()=>{"use strict"});import mr from"node:path";import*as L from"typescript";function _e(e,n){return{lineStart:e.getLineAndCharacterOfPosition(n.getStart(e)).line+1,lineEnd:e.getLineAndCharacterOfPosition(n.getEnd()).line+1}}function Tt(e){return L.canHaveModifiers(e)?!!L.getModifiers(e)?.some(n=>n.kind===L.SyntaxKind.ExportKeyword):!1}function Ea(e,n){if(!e.moduleSpecifier||!L.isStringLiteral(e.moduleSpecifier))return;let i=e.moduleSpecifier.text,t=n.resolveSpecifier(i)??void 0,s=_e(n.sourceFile,e),r=e.importClause;if(r&&(r.name&&n.importedSymbols.push({sourceModule:i,resolvedModule:t,importedName:"default",localName:r.name.text,isTypeOnly:r.isTypeOnly,...s}),!!r.namedBindings))if(L.isNamespaceImport(r.namedBindings))n.importedSymbols.push({sourceModule:i,resolvedModule:t,importedName:"*",localName:r.namedBindings.name.text,isTypeOnly:r.isTypeOnly,...s});else for(let o of r.namedBindings.elements)n.importedSymbols.push({sourceModule:i,resolvedModule:t,importedName:o.propertyName?.text??o.name.text,localName:o.name.text,isTypeOnly:r.isTypeOnly||o.isTypeOnly,...s})}function va(e,n){if(!e.moduleSpecifier||!L.isStringLiteral(e.moduleSpecifier))return;let i=e.moduleSpecifier.text,t=n.resolveSpecifier(i)??void 0;if(e.exportClause&&L.isNamedExports(e.exportClause))for(let s of e.exportClause.elements)n.reExports.push({sourceModule:i,resolvedModule:t,exportedAs:s.name.text,importedName:s.propertyName?.text??s.name.text,isStar:!1,isTypeOnly:e.isTypeOnly||s.isTypeOnly,..._e(n.sourceFile,s)});else n.reExports.push({sourceModule:i,resolvedModule:t,exportedAs:"*",importedName:"*",isStar:!0,isTypeOnly:e.isTypeOnly,..._e(n.sourceFile,e)})}function wa(e,n){let i=_e(n.sourceFile,e);if(L.isExportAssignment(e)){n.pushDeclaredExport({name:"default",kind:"value",isDefault:!0,...i});return}if((L.isFunctionDeclaration(e)||L.isClassDeclaration(e))&&Tt(e)){n.pushDeclaredExport({name:e.name?.text||"default",kind:"value",isDefault:!e.name,...i});return}if(L.isEnumDeclaration(e)&&Tt(e)){n.pushDeclaredExport({name:e.name.text,kind:"value",...i});return}if((L.isTypeAliasDeclaration(e)||L.isInterfaceDeclaration(e))&&Tt(e)){n.pushDeclaredExport({name:e.name.text,kind:"type",...i});return}if(L.isVariableStatement(e)&&Tt(e)){for(let t of e.declarationList.declarations)L.isIdentifier(t.name)&&n.pushDeclaredExport({name:t.name.text,kind:"value",..._e(n.sourceFile,t)});return}if(L.isExportDeclaration(e)&&!e.moduleSpecifier&&e.exportClause&&L.isNamedExports(e.exportClause))for(let t of e.exportClause.elements)n.pushDeclaredExport({name:t.name.text,kind:t.isTypeOnly?"type":"unknown",..._e(n.sourceFile,t)})}function Fa(e,n){if(!L.isIdentifier(e.expression)||e.expression.text!=="require"||e.arguments.length!==1||!L.isStringLiteral(e.arguments[0]))return;let i=e.arguments[0].text,t=n.resolveSpecifier(i)??void 0;n.importedSymbols.push({sourceModule:i,resolvedModule:t,importedName:"*",localName:"require",isTypeOnly:!1,..._e(n.sourceFile,e)})}function ka(e,n,i){let t=mr.dirname(n),s=new Set,r=new Set,o=new Set,a=[],u={sourceFile:e,importedSymbols:[],reExports:[],pushDeclaredExport:f=>{a.some(p=>p.name===f.name&&p.kind===f.kind)||a.push(f)},resolveSpecifier:f=>{if(!f||typeof f!="string")return null;if(!vs(f))return r.add(f),null;let p=ws(t,f);if(!p)return o.add(f),null;if(!p.startsWith(i))return r.add(f),null;let g=en(mr.relative(i,p));return s.add(g),g}},d=f=>{L.isImportDeclaration(f)&&Ea(f,u),L.isExportDeclaration(f)&&f.moduleSpecifier&&va(f,u),wa(f,u),L.isCallExpression(f)&&Fa(f,u),L.forEachChild(f,d)};return d(e),{internalDependencies:[...s].sort(),externalDependencies:[...r].sort(),unresolvedDependencies:[...o].sort(),declaredExports:a,importedSymbols:u.importedSymbols,reExports:u.reExports}}function Ca(e,n,i,t){Xe(e.outgoing,n,i),Xe(e.incoming,i,n),t?Xe(e.incomingFromTests,i,n):Xe(e.incomingFromProduction,i,n)}function hr(e,n,i,t,s){let r=Es(n,t.root);s.files.add(r);let o=ka(e,n,t.root),a=x(n);for(let l of o.internalDependencies){let c=en(l);Ca(s,r,c,a)}return o.externalDependencies.length>0&&s.externalCounts.set(r,new Set(o.externalDependencies)),o.unresolvedDependencies.length>0&&s.unresolvedCounts.set(r,new Set(o.unresolvedDependencies)),s.declaredExportsByFile.set(r,o.declaredExports),s.importedSymbolsByFile.set(r,o.importedSymbols),s.reExportsByFile.set(r,o.reExports),{...o,package:i,file:r}}function $t(e,n){let i=n.outgoing.get(e)||new Set,t=n.incoming.get(e)||new Set,s=n.incomingFromProduction.get(e)||new Set,r=n.incomingFromTests.get(e)||new Set,o=n.externalCounts.get(e)||new Set,a=n.unresolvedCounts.get(e)||new Set;return{file:e,outboundCount:i.size,inboundCount:t.size,inboundFromProduction:s.size,inboundFromTests:r.size,externalDependencyCount:o.size,unresolvedDependencyCount:a.size}}var Hi=N(()=>{"use strict";W()});function Bi(e,n,i){let t=[...e.files].sort(),s=0,r=0,o=[],a=[];for(let g of t){s+=e.outgoing.get(g)?.size||0;let m=$t(g,e),S=n.get(g)||{score:1};o.push({file:g,count:m.outboundCount,score:S.score}),a.push({file:g,count:m.inboundCount,score:S.score}),r+=m.unresolvedDependencyCount}let l=t.filter(g=>(e.incoming.get(g)||new Set).size===0),c=t.filter(g=>(e.outgoing.get(g)||new Set).size===0),u=t.filter(g=>!x(g)).filter(g=>{let m=e.incomingFromProduction.get(g),S=e.incomingFromTests.get(g);return(!m||m.size===0)&&S&&S.size>0}).map(g=>({...$t(g,e)})).sort((g,m)=>g.file.localeCompare(m.file)),d=t.map(g=>({...$t(g,e),...n.get(g)||{}})).filter(g=>(g.score||0)>12||g.outboundCount>5||g.inboundCount>8).sort((g,m)=>(m.score||0)+m.inboundCount*.8+m.outboundCount*.4-((g.score||0)+g.inboundCount*.8+g.outboundCount*.4)).slice(0,150).map(g=>({...g,score:Math.round(g.score||0),riskBand:(g.score||0)>=60?"high":(g.score||0)>=30?"medium":"low"})),f=yr(e),p=Sr(e,n,i);return{totalModules:t.length,totalEdges:s,unresolvedEdgeCount:r,externalDependencyFiles:[...e.externalCounts.keys()].length,rootsCount:l.length,leavesCount:c.length,roots:l.slice(0,20),leaves:c.slice(0,20),criticalModules:d.slice(0,20),testOnlyModules:u.slice(0,50),unresolvedSample:r>0?[...e.unresolvedCounts.keys()].slice(0,40):[],outgoingTop:o.sort((g,m)=>m.count-g.count).slice(0,20),inboundTop:a.sort((g,m)=>m.count-g.count).slice(0,20),cycles:f.slice(0,20),criticalPaths:p.slice(0,Math.max(1,i.deepLinkTopN))}}function yr(e){let n=[],i=new Set,t=new Set,s=[],r=new Set,o=l=>{let c=[...l],u=c.slice();for(let d=1;d<c.length;d++){let f=[...c.slice(d),...c.slice(0,d)];f.join(" => ")<u.join(" => ")&&(u=f)}return u.join(" => ")},a=l=>{if(i.has(l)||t.has(l))return;t.add(l),s.push(l);let c=e.outgoing.get(l)||new Set;for(let u of c){let d=s.indexOf(u);if(d!==-1){let f=[...s.slice(d),u],p=o(f);r.has(p)||(r.add(p),n.push({path:f,nodeCount:f.length-1}));continue}e.files.has(u)&&a(u)}s.pop(),t.delete(l),i.add(l)};for(let l of e.files)a(l);return n.sort((l,c)=>c.nodeCount-l.nodeCount)}function Sr(e,n,i){let t=new Map,s=new Set,r=l=>{let c=n.get(l);return c?c.score:1},o=l=>{if(t.has(l))return t.get(l);if(s.has(l))return{path:[l],score:r(l)*.5,containsCycle:!0};s.add(l);let c=e.outgoing.get(l)||new Set,u={path:[l],score:r(l),containsCycle:!1};for(let d of c){if(!e.files.has(d))continue;let f=o(d),p=r(l)+f.score;(p>u.score||p===u.score&&f.path.length>u.path.length)&&(u={path:[l,...f.path],score:p,containsCycle:f.containsCycle})}return s.delete(l),t.set(l,u),u},a=[];for(let l of e.files){let c=o(l);a.push({start:l,path:c.path,score:Math.round(c.score),length:c.path.length,containsCycle:c.containsCycle})}return a.filter(l=>l.length>1).sort((l,c)=>{let u=c.score-l.score;return u!==0?u:c.length-l.length}).slice(0,Math.max(1,i.deepLinkTopN))}var zi=N(()=>{"use strict";Hi();W()});import Ce from"node:fs";import he from"node:path";function $a(e,n){if(!n||n.length===0)return!1;let i=he.normalize(e);return n.some(t=>{let s=he.normalize(t);return i===s||i.startsWith(s+he.sep)})}function Da(e){return/\.min\.(?:js|mjs|cjs)$/i.test(e)}function Ra(e,n){let i=he.relative(n,e);if(!i||i.startsWith(".."))return!1;let t=i.split(he.sep);if(t[0]!=="scripts"||t.length<2)return!1;let s=he.extname(e),r=t.slice(1).join(he.sep).slice(0,-s.length);for(let o of Ta){let a=he.join(n,"src",`${r}${o}`);if(Ce.existsSync(a)&&Ce.statSync(a).isFile())return!0}return!1}function Ki(e,n){let i=[],t=s=>{let r=Ce.readdirSync(s,{withFileTypes:!0});r.sort((o,a)=>o.name.localeCompare(a.name));for(let o of r){if(n.ignoreDirs.has(o.name)||o.isSymbolicLink())continue;let a=he.join(s,o.name);if(o.isDirectory()){t(a);continue}if(!o.isFile()||o.name.endsWith(".d.ts")||!$a(a,n.scope)&&(Da(o.name)||Ra(a,e)))continue;let l=he.extname(o.name);qe.has(l)&&(!n.includeTests&&x(a)||i.push(a))}};return t(e),i}function br(e){try{return Ce.readFileSync(e,"utf8")}catch{return null}}function xr(e,n){if(!Ce.existsSync(n)||!Ce.statSync(n).isDirectory())return[];let i=Ce.readdirSync(n,{withFileTypes:!0}).filter(s=>s.isDirectory()).sort((s,r)=>s.name.localeCompare(r.name)),t=[];for(let s of i){let r=he.join(n,s.name),o=he.join(r,"package.json");if(Ce.existsSync(o))try{let a=JSON.parse(Ce.readFileSync(o,"utf8"));typeof a.name=="string"&&t.push({name:a.name,dir:r,folder:s.name})}catch{}}return t}function Er(e,n){return e.map(i=>({...i,issueIds:n.get(i.file)||[]}))}var Ta,vr=N(()=>{"use strict";W();me();Ta=[".ts",".tsx",".js",".jsx",".mjs",".cjs"]});function Ui(e){let n=e.replace(/\\/g,"/").replace(/^\.?\//,""),i=n.match(/^packages\/([^/]+)/);if(i)return`packages/${i[1]}`;let[t]=n.split("/");return t||"<root>"}function Aa(e){let n=[...e.files].sort(),i=new Map,t=new Map,s=[],r=new Set,o=0,a=[],l=c=>{i.set(c,o),t.set(c,o),o+=1,s.push(c),r.add(c);let u=e.outgoing.get(c)||new Set;for(let y of u)e.files.has(y)&&(i.has(y)?r.has(y)&&t.set(c,Math.min(t.get(c),i.get(y))):(l(y),t.set(c,Math.min(t.get(c),t.get(y)))));if(t.get(c)!==i.get(c))return;let d=[];for(;s.length>0;){let y=s.pop();if(r.delete(y),d.push(y),y===c)break}let f=(e.outgoing.get(c)||new Set).has(c);if(d.length<=1&&!f)return;let p=new Set(d),g=0,m=0,S=0;for(let y of d){for(let D of e.outgoing.get(y)||new Set)e.files.has(D)&&(p.has(D)?g+=1:S+=1);for(let D of e.incoming.get(y)||new Set)p.has(D)||(m+=1)}let h=[...d].sort((y,D)=>{let b=(e.incoming.get(y)||new Set).size*2+(e.outgoing.get(y)||new Set).size;return(e.incoming.get(D)||new Set).size*2+(e.outgoing.get(D)||new Set).size-b}).slice(0,3);a.push({id:`scc-${a.length+1}`,files:d.sort(),nodeCount:d.length,edgeCount:g,entryEdges:m,exitEdges:S,hubFiles:h})};for(let c of n)i.has(c)||l(c);return a.sort((c,u)=>u.nodeCount-c.nodeCount||u.edgeCount-c.edgeCount)}function Ma(e){let n=new Map,i=new Map;for(let s of e.files){let r=Ui(s);n.has(r)||n.set(r,{package:r,inbound:0,outbound:0,internalFiles:0}),n.get(r).internalFiles+=1}for(let[s,r]of e.outgoing.entries()){let o=Ui(s);for(let a of r){if(!e.files.has(a))continue;let l=Ui(a);if(o===l)continue;let c=`${o}=>${l}`;i.set(c,(i.get(c)||0)+1),n.get(o).outbound+=1,n.get(l).inbound+=1}}let t=[...i.entries()].map(([s,r])=>{let[o,a]=s.split("=>");return{from:o,to:a,edges:r}}).sort((s,r)=>r.edges-s.edges).slice(0,20);return{packageCount:n.size,edgeCount:[...i.values()].reduce((s,r)=>s+r,0),packages:[...n.values()].sort((s,r)=>r.inbound+r.outbound-(s.inbound+s.outbound)),hotspots:t}}function wr(e){let n=[...e.files].sort(),i=new Map;for(let d of n)i.set(d,new Set);for(let[d,f]of e.outgoing.entries())for(let p of f)e.files.has(p)&&(i.get(d).add(p),i.get(p).add(d));let t=new Set,s=new Map,r=new Map,o=new Map,a=new Set,l=[],c=0,u=d=>{t.add(d),s.set(d,c),r.set(d,c),c+=1;let f=0;for(let p of i.get(d)||new Set)t.has(p)?p!==o.get(d)&&r.set(d,Math.min(r.get(d),s.get(p))):(f+=1,o.set(p,d),u(p),r.set(d,Math.min(r.get(d),r.get(p))),o.get(d)==null&&f>1&&a.add(d),o.get(d)!=null&&r.get(p)>=s.get(d)&&a.add(d),r.get(p)>s.get(d)&&l.push(d<p?{from:d,to:p}:{from:p,to:d}))};for(let d of n)t.has(d)||(o.set(d,null),u(d));return{articulationPoints:a,bridgeEdges:l}}function Pa(e,n,i,t){let{articulationPoints:s,bridgeEdges:r}=wr(e),o=new Set;for(let c of n.criticalPaths||[])for(let u of c.path)o.add(u);let a=new Map;for(let c of t)for(let u of c.files)a.set(u,(a.get(u)||0)+1);let l=new Map;for(let c of r)l.set(c.from,(l.get(c.from)||0)+1),l.set(c.to,(l.get(c.to)||0)+1);return[...e.files].map(c=>{let u=(e.incoming.get(c)||new Set).size,d=(e.outgoing.get(c)||new Set).size,f=s.has(c),p=l.get(c)||0,g=a.get(c)||0,m=o.has(c),S=i.get(c)?.score||0,h=Math.round(u*3+d*1.2+S/10+(f?12:0)+p*4+g*6+(m?8:0)),y=[];return u>=8&&y.push(`high fan-in (${u})`),d>=6&&y.push(`high fan-out (${d})`),f&&y.push("articulation point"),p>0&&y.push(`${p} bridge edge(s)`),g>0&&y.push(`in ${g} cycle cluster(s)`),m&&y.push("on critical path"),S>=20&&y.push(`high complexity risk (${S})`),{file:c,score:h,reasons:y,fanIn:u,fanOut:d,articulation:f,bridgeCount:p,cycleClusterCount:g,onCriticalPath:m}}).filter(c=>c.score>0&&c.reasons.length>0).sort((c,u)=>u.score-c.score).slice(0,40)}function Dt(e,n,i){let t=Aa(e),{articulationPoints:s,bridgeEdges:r}=wr(e),o=Pa(e,n,i,t);return{sccClusters:t,chokepoints:o,packageGraphSummary:Ma(e),articulationPoints:[...s].sort(),bridgeEdges:r}}function qi(e,n,i){let t=e.importedSymbolsByFile.get(n)||[];for(let s of t)if(!i||s.resolvedModule===i)return{lineStart:s.lineStart||1,lineEnd:s.lineEnd||s.lineStart||1};return{lineStart:1,lineEnd:1}}function Fr(e,n,i){let t=[];for(let r of e.sccClusters.slice(0,6)){if(r.nodeCount<3)continue;let o=r.hubFiles[0]||r.files[0],a=qi(n,o);t.push({severity:r.nodeCount>=5?"high":"medium",category:"cycle-cluster",file:o,lineStart:a.lineStart,lineEnd:a.lineEnd,title:`Cycle cluster detected (${r.nodeCount} files)`,reason:`Strongly connected cluster ${r.id} has ${r.nodeCount} files, ${r.entryEdges} entry edge(s), and ${r.exitEdges} exit edge(s).`,files:r.files,suggestedFix:{strategy:"Break the cluster at one of the hub files and move shared contracts lower.",steps:["Inspect the hub files first.","Extract shared interfaces or types from the cluster.","Remove at least one high-traffic edge to split the SCC."]},impact:"Large cycle clusters spread change risk across multiple files and hide the true architectural boundary.",tags:["architecture","cycle","graph","change-risk"],ruleId:"architecture.cycle-cluster",confidence:"high",evidence:{clusterId:r.id,nodeCount:r.nodeCount,entryEdges:r.entryEdges,exitEdges:r.exitEdges,hubFiles:r.hubFiles}})}for(let r of e.chokepoints.slice(0,8)){if(r.fanIn<3||r.fanOut<3||r.score<18)continue;let o=qi(n,r.file);t.push({severity:r.articulation||r.score>=30?"high":"medium",category:"broker-module",file:r.file,lineStart:o.lineStart,lineEnd:o.lineEnd,title:`Broker module chokepoint: ${r.file}`,reason:`Module concentrates dependency traffic (${r.reasons.join(", ")}).`,files:[r.file],suggestedFix:{strategy:"Split orchestration responsibilities and reduce fan-in/fan-out through narrower seams.",steps:["Identify which consumers rely on this file for unrelated concerns.","Extract narrower APIs or introduce an internal facade.","Move side-effectful or persistence-specific logic into dedicated modules."]},impact:"Broker modules silently become architecture bottlenecks \u2014 a small change cascades broadly.",tags:["architecture","graph","chokepoint","coupling"],ruleId:"architecture.broker-module",confidence:r.articulation?"high":"medium",evidence:{score:r.score,reasons:r.reasons,fanIn:r.fanIn,fanOut:r.fanOut}})}for(let r of e.chokepoints.filter(o=>o.articulation).slice(0,8)){let o=qi(n,r.file);t.push({severity:r.bridgeCount>=2?"high":"medium",category:"bridge-module",file:r.file,lineStart:o.lineStart,lineEnd:o.lineEnd,title:`Bridge module detected: ${r.file}`,reason:`Module acts as a graph articulation point with ${r.bridgeCount} bridge edge(s).`,files:[r.file],suggestedFix:{strategy:"Reduce the amount of architecture that depends on this single bridge module.",steps:["Split unrelated responsibilities out of the bridge module.","Add lower-level contracts so adjacent subsystems do not all route through one file.","Prefer explicit package boundaries over central catch-all utilities."]},impact:"Bridge modules are structurally brittle \u2014 they become the single point where subsystem changes collide.",tags:["architecture","graph","bridge","fragility"],ruleId:"architecture.bridge-module",confidence:"high",evidence:{score:r.score,bridgeCount:r.bridgeCount,reasons:r.reasons}})}for(let r of e.packageGraphSummary.hotspots.slice(0,5))r.edges<4||t.push({severity:r.edges>=8?"high":"medium",category:"package-boundary-chatter",file:r.from,lineStart:1,lineEnd:1,title:`Heavy package chatter: ${r.from} -> ${r.to}`,reason:`Detected ${r.edges} cross-package dependency edge(s) between these package groups.`,files:[r.from,r.to],suggestedFix:{strategy:"Reduce cross-package chatter by consolidating APIs or introducing a narrower shared contract.",steps:["Map the symbols crossing this boundary most often.","Promote a smaller public API surface between the packages.","Move implementation detail imports behind a dedicated package boundary."]},impact:"High package chatter is a sign of architectural erosion \u2014 packages stop behaving like isolated subsystems.",tags:["architecture","packages","boundary","graph"],ruleId:"architecture.package-boundary-chatter",confidence:"medium",evidence:r});let s=new Map(e.chokepoints.map(r=>[r.file,r]));for(let r of i){let o=r.topLevelEffects||[];if(o.length===0)continue;let a=s.get(r.file);if(!a||a.fanIn<8||a.score<18)continue;let l=o[0];t.push({severity:a.fanIn>=20?"high":"medium",category:"startup-risk-hub",file:r.file,lineStart:l.lineStart,lineEnd:l.lineEnd,title:`Startup risk hub: ${r.file}`,reason:`Module performs ${o.length} import-time effect(s) and also behaves as a chokepoint (${a.reasons.join(", ")}).`,files:[r.file],suggestedFix:{strategy:"Move import-time work behind explicit initialization and reduce inbound dependency pressure.",steps:["Extract side effects into init() or lazy code paths.","Avoid importing this module from broad utility or entrypoint chains.","Keep only declarations and light configuration at module scope."]},impact:"Import-time side effects in a high fan-in hub create startup latency, hidden ordering bugs, and broad runtime blast radius.",tags:["architecture","startup","side-effects","graph"],ruleId:"architecture.startup-risk-hub",confidence:"high",evidence:{fanIn:a.fanIn,chokepointScore:a.score,topLevelEffects:o.map(c=>c.kind)}})}return t}var Gi=N(()=>{"use strict"});import Wi from"node:fs";import ot from"node:path";import*as w from"typescript";function Ia(e){let n=w.findConfigFile(e,w.sys.fileExists,"tsconfig.json");if(!n)return null;let i=w.readConfigFile(n,w.sys.readFile);return i.error?null:w.parseJsonConfigFileContent(i.config,w.sys,ot.dirname(n))}function kr(e,n){let t=Ia(n)?.options??{target:w.ScriptTarget.ES2022,module:w.ModuleKind.ESNext,moduleResolution:w.ModuleResolutionKind.Node10,strict:!0,esModuleInterop:!0,skipLibCheck:!0,allowJs:!0},s=new Set(e),r=new Map;for(let u of e)try{r.set(u,Wi.readFileSync(u,"utf8"))}catch{}let o={getScriptFileNames:()=>[...s],getScriptVersion:()=>"1",getScriptSnapshot:u=>{let d=r.get(u);if(d!=null)return w.ScriptSnapshot.fromString(d);try{let f=Wi.readFileSync(u,"utf8");return w.ScriptSnapshot.fromString(f)}catch{return}},getCurrentDirectory:()=>n,getCompilationSettings:()=>t,getDefaultLibFileName:w.getDefaultLibFilePath,fileExists:w.sys.fileExists,readFile:w.sys.readFile,readDirectory:w.sys.readDirectory,directoryExists:w.sys.directoryExists,getDirectories:w.sys.getDirectories},a=w.createLanguageService(o,w.createDocumentRegistry()),l=a.getProgram(),c=l.getTypeChecker();return{service:a,checker:c,program:l,root:n}}function Na(e,n,i,t,s){let r=e.program.getSourceFile(n);if(!r)return{count:-1,uniqueFiles:0};let o=Cr(r,i,t);if(!o)return{count:-1,uniqueFiles:0};let a=e.service.findReferences(n,o.getStart(r));if(!a)return{count:0,uniqueFiles:0};let l=0,c=new Set;for(let u of a)for(let d of u.references)d.isDefinition||!s&&x(d.fileName)||(l++,c.add(d.fileName));return{count:l,uniqueFiles:c.size}}function Cr(e,n,i){let t=e.getPositionOfLineAndCharacter(Math.max(0,i-1),0),s=i<e.getLineAndCharacterOfPosition(e.getEnd()).line+1?e.getPositionOfLineAndCharacter(i,0):e.getEnd(),r,o=a=>{if(!r){if(a.getStart(e)>=t&&a.getEnd()<=s&&w.isIdentifier(a)&&a.text===n){r=a;return}w.forEachChild(a,o)}};return w.forEachChild(e,o),r}function La(e,n){let i=[],t=n,s=0,r=new Set;for(;;){let o=t.getBaseTypes?.()??[];if(o.length===0)break;let a=o[0],l=e.typeToString(a);if(r.has(l)||(r.add(l),i.push(l),s++,t=a,s>20))break}return{depth:s,chain:i}}function Oa(e,n,i,t){let s=new Map,r=i.dependencyProfile?.declaredExports??[];for(let o of r){if(o.lineStart==null)continue;let a=Na(e,n,o.name,o.lineStart,t);s.set(o.name,{count:a.count,uniqueFiles:a.uniqueFiles,lineStart:o.lineStart,lineEnd:o.lineEnd??o.lineStart})}return s}function ja(e,n,i,t){let s=e.getPositionOfLineAndCharacter(Math.max(0,i-1),0),r,o=a=>{if(!r){if(a.getStart(e)>=s&&a.getEnd()<=e.getPositionOfLineAndCharacter(Math.min(t,e.getLineAndCharacterOfPosition(e.getEnd()).line+1)-1,0)+200&&(w.isFunctionDeclaration(a)||w.isMethodDeclaration(a)||w.isArrowFunction(a)||w.isFunctionExpression(a))&&((a.name&&w.isIdentifier(a.name)?a.name.text:"")===n||n==="<anonymous>")){r=a;return}w.forEachChild(a,o)}};return w.forEachChild(e,o),r}function _a(e,n,i,t){let s=[];for(let r of t.functions){if(!r.params||r.params===0||r.name==="<anonymous>"||r.name==="")continue;let o=ja(i,r.name,r.lineStart,r.lineEnd);if(!(!o||!(w.isFunctionDeclaration(o)||w.isMethodDeclaration(o)||w.isArrowFunction(o)||w.isFunctionExpression(o))))for(let a of o.parameters){if(!w.isIdentifier(a.name))continue;let l=a.name.text;if(l.startsWith("_"))continue;let c=e.service.findReferences(n,a.name.getStart(i)),u=0;if(c)for(let d of c)for(let f of d.references)f.isDefinition||u++;u===0&&s.push({functionName:r.name,paramName:l,lineStart:r.lineStart,lineEnd:r.lineEnd})}}return s}function Ha(e,n,i,t){let s=0,r=0,o=i.dependencyProfile?.declaredExports??[],a=l=>{if(w.isClassDeclaration(l)&&l.name){let c=e.checker.getTypeAtLocation(l),{depth:u,chain:d}=La(e.checker,c);if(u>0&&(t.typeHierarchies.push({name:l.name.text,depth:u,chain:d,lineStart:n.getLineAndCharacterOfPosition(l.getStart(n)).line+1}),u>t.typeHierarchyDepth&&(t.typeHierarchyDepth=u)),l.heritageClauses){for(let S of l.heritageClauses)if(S.token===w.SyntaxKind.ImplementsKeyword)for(let h of S.types){let y=e.checker.getTypeAtLocation(h),D=e.checker.typeToString(y),b=e.checker.getTypeAtLocation(l),k=y.getProperties?.()??[],C=new Set((b.getProperties?.()??[]).map(E=>E.name)),A=k.filter(E=>!C.has(E.name)).map(E=>E.name),M=[];for(let E of k)if(C.has(E.name)){let _=b.getProperty?.(E.name);if(_){let K=e.checker.getTypeOfSymbolAtLocation(_,l);e.checker.typeToString(K)==="any"&&M.push(E.name)}}(A.length>0||M.length>0)&&t.interfaceImpls.push({interfaceName:D,className:l.name.text,classFile:i.file,classLine:n.getLineAndCharacterOfPosition(l.getStart(n)).line+1,missingMembers:A,anycastMembers:M})}}l.modifiers?.some(S=>S.kind===w.SyntaxKind.AbstractKeyword)&&s++;let f=new Map,g=e.checker.getTypeAtLocation(l),m=0;for(;;){let S=g.getBaseTypes?.()??[];if(S.length===0)break;m++;let h=S[0];for(let y of h.getProperties?.()??[]){let D=y.getDeclarations?.()?.[0];D&&(w.isMethodDeclaration(D)||w.isMethodSignature(D))&&f.set(y.name,Math.max(f.get(y.name)??0,m))}if(g=h,m>20)break}for(let S of l.members)if(w.isMethodDeclaration(S)&&S.name&&w.isIdentifier(S.name)){let h=S.name.text,y=f.get(h);y!=null&&y>0&&t.overrideChains.push({methodName:h,className:l.name.text,depth:y,chain:[],lineStart:n.getLineAndCharacterOfPosition(S.getStart(n)).line+1})}}w.isInterfaceDeclaration(l)&&(s++,r++),w.isTypeAliasDeclaration(l)&&r++,w.forEachChild(l,a)};return w.forEachChild(n,a),r+=o.length,r>0?s/r:0}function Ba(e,n,i,t){let s=[],r=[],o=t.dependencyProfile?.importedSymbols??[];for(let a of o){if(a.lineStart==null)continue;let l=Cr(i,a.localName,a.lineStart);if(!l)continue;let c=e.service.findReferences(n,l.getStart(i)),u=0;if(c)for(let d of c)for(let f of d.references)f.isDefinition||f.fileName===n&&u++;if(u===0&&s.push({name:a.localName,lineStart:a.lineStart}),a.resolvedModule&&e.program.getSourceFile(ot.resolve(e.root,a.resolvedModule))){let f=e.checker.getSymbolAtLocation(l);if(f){let g=(f.flags&w.SymbolFlags.Alias?e.checker.getAliasedSymbol(f):f).getDeclarations?.()?.[0];g&&w.isClassDeclaration(g)&&(g.modifiers?.some(S=>S.kind===w.SyntaxKind.AbstractKeyword)||r.push({name:a.localName,targetFile:a.resolvedModule,lineStart:a.lineStart}))}}}return{unusedImports:s,concreteImports:r}}function za(e,n,i,t){let s=[],r=t.functions.filter(o=>t.dependencyProfile?.declaredExports?.some(a=>a.name===o.name));for(let o of r){let a=i.getPositionOfLineAndCharacter(Math.max(0,o.lineStart-1),0),l,c=u=>{if(!l){if((w.isFunctionDeclaration(u)||w.isMethodDeclaration(u))&&u.name&&w.isIdentifier(u.name)&&u.name.text===o.name&&u.getStart(i)>=a){l=u;return}w.forEachChild(u,c)}};if(w.forEachChild(i,c),l){let u=e.checker.getSignatureFromDeclaration(l);if(u){let d=e.checker.getReturnTypeOfSignature(u),f=d.symbol||d.aliasSymbol;if(f?.declarations?.[0]){let p=f.declarations[0].getSourceFile().fileName,g=ot.relative(e.root,p);p!==n&&!g.startsWith("node_modules")&&!p.includes("lib.")&&s.push({functionName:o.name,returnType:e.checker.typeToString(d),sourceFile:g,lineStart:o.lineStart})}}}}return s}function Ka(e,n,i,t){let s=[],r=t.functions.filter(o=>t.dependencyProfile?.declaredExports?.some(a=>a.name===o.name));for(let o of r){if(!o.params||o.params<1)continue;let a=i.getPositionOfLineAndCharacter(Math.max(0,o.lineStart-1),0),l,c=u=>{if(!l){if(w.isFunctionDeclaration(u)&&u.name?.text===o.name&&u.getStart(i)>=a){l=u;return}w.forEachChild(u,c)}};if(w.forEachChild(i,c),!!l)for(let u of l.parameters){if(!w.isIdentifier(u.name))continue;let d=e.checker.getTypeAtLocation(u);if(!d.isUnion()&&!(d.flags&(w.TypeFlags.Any|w.TypeFlags.Unknown)))continue;let f=e.checker.typeToString(d),p=e.service.findReferences(n,l.name.getStart(i));if(!p)continue;let g=[],m=!0,S=0;for(let h of p)for(let y of h.references){if(y.isDefinition)continue;let D=e.program.getSourceFile(y.fileName);if(!D)continue;let b=D,k=K=>{K.getStart(D)<=y.textSpan.start&&K.getEnd()>=y.textSpan.start+y.textSpan.length&&(b=K,w.forEachChild(K,k))};w.forEachChild(D,k);let C,A=b;for(;A;){if(w.isCallExpression(A)){C=A;break}A=A.parent}if(!C?.arguments)continue;let M=l.parameters.indexOf(u);if(M<0||M>=C.arguments.length){m=!1;continue}let E=e.checker.getTypeAtLocation(C.arguments[M]),_=e.checker.typeToString(E);g.push(_),S++,(_===f||_==="any"||_==="unknown")&&(m=!1)}if(m&&S>=2&&g.length>0){let h=[...new Set(g)];h.length<=2&&s.push({functionName:o.name,paramName:u.name.text,declaredType:f,actualTypes:h,narrowedType:h.length===1?h[0]:h.join(" | "),lineStart:o.lineStart,lineEnd:o.lineEnd})}}}return s}function Tr(e,n,i,t=!0){let s={file:i.file,referenceCountByExport:new Map,unusedParams:[],interfaceImpls:[],typeHierarchyDepth:0,typeHierarchies:[],overrideChains:[],abstractnessRatio:0,unusedImports:[],concreteImports:[],leakyReturns:[],narrowableParams:[]},r=e.program.getSourceFile(n);if(!r)return s;s.referenceCountByExport=Oa(e,n,i,t),s.unusedParams=_a(e,n,r,i),s.abstractnessRatio=Ha(e,r,i,s);let o=Ba(e,n,r,i);return s.unusedImports=o.unusedImports,s.concreteImports=o.concreteImports,s.leakyReturns=za(e,n,r,i),s.narrowableParams=Ka(e,n,r,i),s}function $r(e,n,i){let t=new Set;for(let s of e)t.add(ot.resolve(i,s.file));for(let s of n.files)t.add(ot.resolve(i,s));return[...t].filter(s=>{try{return Wi.statSync(s).isFile()}catch{return!1}})}var Dr=N(()=>{"use strict";W()});import Vi from"node:path";function Ua(e){for(let n of e.children)if(!n.isNamed&&(n.type==="&&"||n.type==="||"))return!0;return!1}function qa(e,n){let i={complexity:1,maxBranchDepth:0,maxLoopDepth:0,returns:0,awaits:0,calls:0,loops:0,statements:0},t=(s,r,o)=>{if(i.statements+=1,["if_statement","while_statement","do_statement","for_statement","for_in_statement","for_of_statement","for_await_statement","switch_statement","catch_clause"].includes(s.type)&&(i.complexity+=1,r+=1,i.maxBranchDepth=Math.max(i.maxBranchDepth,r)),s.type==="conditional_expression"&&(i.complexity+=1),s.type==="binary_expression"&&Ua(s)&&(i.complexity+=1),(s.type==="return_statement"||s.type==="throw_statement")&&(i.returns+=1),s.type==="await_expression"&&(i.awaits+=1),s.type==="call_expression"&&(i.calls+=1),["for_statement","for_in_statement","for_of_statement","for_await_statement","while_statement","do_statement"].includes(s.type)){let a=o+1;i.loops+=1,i.maxLoopDepth=Math.max(i.maxLoopDepth,a);for(let l of s.children)t(l,r,a);return}for(let a of s.children)t(a,r,o)};return t(e,0,0),i}function Va(e){let n=0,i=(t,s)=>{let r=0,o=!1;if(Ga.has(t.type)&&(r=1,o=!0),t.type==="binary_expression"){for(let a of t.children)if(!a.isNamed&&Wa.has(a.type)){r=1;break}}if(t.type==="if_statement"&&t.parent?.type==="else_clause"&&(r=1,o=!1),o){n+=r+s;for(let a of t.children)i(a,s+1);return}n+=r;for(let a of t.children)i(a,s)};return i(e,0),n}function Qa(e,n){let i=e.namedChildren.find(s=>["identifier","property_identifier","type_identifier"].includes(s.type));if(i)return i.text;let t=e.parent;for(;t;){if(t.type==="variable_declarator"){let s=t.namedChildren.find(r=>["identifier","property_identifier","array_pattern","object_pattern","shorthand_property_identifier_pattern"].includes(r.type));if(s&&s.type==="identifier")return s.text;break}if(t.type==="pair"){let s=t.namedChildren.find(r=>["identifier","string","shorthand_property_identifier_pattern","property_identifier"].includes(r.type));if(s)return s.text;break}if(["assignment_expression","method_definition","property_signature","public_field_definition"].includes(t.type)){let s=t.namedChildren.find(r=>["identifier","property_identifier","string","private_property_identifier"].includes(r.type));if(s)return s.text}if(t.type==="statement_block"||t.type==="program")break;t=t.parent}return"<anonymous>"}function Ja(e){let n=e.namedChildren.find(i=>i.type==="statement_block");return n?n.namedChildren.length:1}function Ya(e){let n=e.namedChildren.find(i=>i.type==="statement_block"||i.type==="switch_body");return n?n.namedChildren.length:e.namedChildren.length}function Rr(e,n,i){return{file:Vi.relative(n,i),lineStart:e.startPosition.row+1,lineEnd:e.endPosition.row+1,columnStart:e.startPosition.column+1,columnEnd:e.endPosition.column+1}}function Qi(e,n,i,t,s){if(!Te?.available)return null;let r=Vi.extname(e),o=r===".tsx"||r===".jsx"?Te.parserTsx:Te.parserTs;if(!o)return null;let a=o.parse(n),l=Vi.relative(i.root,e),c={parseEngine:"tree-sitter",nodeCount:0,functions:[],flows:[]};if(i.emitTree){let d={size:8e3},f=Zt(a.rootNode,n,i.treeDepth,d);f&&(c.tree=f)}let u=d=>{if(c.nodeCount+=1,mt.has(d.type)){let f=Rr(d,i.root,e),p=qa(d,n),g=Ja(d),m=Qa(d,n),S=d.childForFieldName("parameters"),h=S?S.namedChildren.length:0,y={kind:d.type,name:m,nameHint:m,file:l,lineStart:f.lineStart,lineEnd:f.lineEnd,columnStart:f.columnStart,columnEnd:f.columnEnd,statementCount:g,lengthLines:f.lineEnd-f.lineStart+1,params:h,complexity:p.complexity,maxBranchDepth:p.maxBranchDepth,maxLoopDepth:p.maxLoopDepth,returns:p.returns,awaits:p.awaits,calls:p.calls,loops:p.loops,cognitiveComplexity:Va(d),source:"tree-sitter"};if(c.functions.push(y),s&&g>=i.thresholds.minFunctionStatements){let D=d.namedChildren.find(k=>k.type==="statement_block"),b=D?Yt(D):Ge(l);Se(s.flowMap,`${b}|${d.type}`,{...y,hash:b,metrics:p})}}if(gt.has(d.type)){let f=Rr(d,i.root,e),p=Ya(d),g={kind:d.type,file:l,lineStart:f.lineStart,lineEnd:f.lineEnd,columnStart:f.columnStart,columnEnd:f.columnEnd,statementCount:p};if(c.flows.push(g),s&&p>=i.thresholds.minFlowStatements){let m=Yt(d);Se(s.controlMap,`${m}|${d.type}`,{...g,hash:m})}}for(let f of d.children)u(f)};return u(a.rootNode),c}async function Ar(){if(Te!==null)return Te;try{let e=await import("tree-sitter"),n=await import("tree-sitter-typescript"),i=e.default||e,t=n.typescript||n.default?.typescript,s=n.tsx||n.default?.tsx;if(!i||!t)throw new Error("Tree-sitter or tree-sitter-typescript did not expose expected exports");let r=new i;r.setLanguage(t);let o=new i;return o.setLanguage(s||t),Te={available:!0,parserTs:r,parserTsx:o},Te}catch(e){return Te={available:!1,parserTs:null,parserTsx:null,error:String(e?.message||e)},Te}}var Te,Ga,Wa,Mr=N(()=>{"use strict";W();me();Te=null;Ga=new Set(["if_statement","for_statement","for_in_statement","for_of_statement","for_await_statement","while_statement","do_statement","catch_clause","conditional_expression","switch_statement"]),Wa=new Set(["&&","||","??"])});import*as U from"typescript";function ae(e){return U.isFunctionDeclaration(e)||U.isFunctionExpression(e)||U.isArrowFunction(e)||U.isMethodDeclaration(e)||U.isConstructorDeclaration(e)||U.isGetAccessor(e)||U.isSetAccessor(e)}function Qe(e,n){if("name"in e&&e.name&&U.isIdentifier(e.name))return e.name.getText(n);let i=e.parent;return i&&U.isVariableDeclaration(i)&&i.name&&U.isIdentifier(i.name)||i&&U.isPropertyAssignment(i)&&U.isIdentifier(i.name)||i&&U.isPropertyDeclaration(i)&&i.name&&U.isIdentifier(i.name)||i&&U.isMethodDeclaration(i)&&i.name||i&&U.isGetAccessor(i)&&i.name||i&&U.isSetAccessor(i)&&i.name?i.name.getText(n):"<anonymous>"}var He=N(()=>{"use strict"});import*as T from"typescript";function Ji(e){let n={complexity:1,maxBranchDepth:0,maxLoopDepth:0,returns:0,awaits:0,calls:0,loops:0},i=(t,s,r)=>{switch(t.kind){case T.SyntaxKind.IfStatement:case T.SyntaxKind.WhileStatement:case T.SyntaxKind.DoStatement:case T.SyntaxKind.ForStatement:case T.SyntaxKind.ForInStatement:case T.SyntaxKind.ForOfStatement:case T.SyntaxKind.SwitchStatement:case T.SyntaxKind.CatchClause:n.complexity+=1,s+=1,n.maxBranchDepth=Math.max(n.maxBranchDepth,s);break;case T.SyntaxKind.ConditionalExpression:n.complexity+=1;break;case T.SyntaxKind.ReturnStatement:case T.SyntaxKind.ThrowStatement:n.returns+=1;break;case T.SyntaxKind.AwaitExpression:n.awaits+=1;break;case T.SyntaxKind.CallExpression:n.calls+=1;break;default:t.kind===T.SyntaxKind.BinaryExpression&&(t.operatorToken.kind===T.SyntaxKind.AmpersandAmpersandToken||t.operatorToken.kind===T.SyntaxKind.BarBarToken)&&(n.complexity+=1)}if(t.kind===T.SyntaxKind.ForStatement||t.kind===T.SyntaxKind.ForInStatement||t.kind===T.SyntaxKind.ForOfStatement){let o=r+1;n.loops+=1,n.maxLoopDepth=Math.max(n.maxLoopDepth,o),T.forEachChild(t,a=>i(a,s,o));return}T.forEachChild(t,o=>i(o,s,r))};return i(e,0,0),n}function Yi(e){let n=new Map,i=new Map,t=m=>{if(T.isIdentifier(m)||T.isPrivateIdentifier(m)){let S=m.text;i.set(S,(i.get(S)||0)+1)}else if(T.isNumericLiteral(m)||T.isStringLiteral(m)||T.isNoSubstitutionTemplateLiteral(m)){let S=m.getText();i.set(S,(i.get(S)||0)+1)}else if(T.isToken(m)&&Xa.has(m.kind)){let S=T.SyntaxKind[m.kind];n.set(S,(n.get(S)||0)+1)}T.forEachChild(m,t)};t(e);let s=n.size,r=i.size,o=0;for(let m of n.values())o+=m;let a=0;for(let m of i.values())a+=m;let l=s+r,c=o+a,u=l>0?c*Math.log2(l):0,d=r>0?s/2*(a/r):0,f=u*d,p=f/18,g=u/3e3;return{operators:o,operands:a,distinctOperators:s,distinctOperands:r,vocabulary:l,length:c,volume:u,difficulty:d,effort:f,time:p,estimatedBugs:g}}function Xi(e,n,i){let t=Math.max(e,1),s=Math.max(i,1),r=171-5.2*Math.log(t)-.23*n-16.2*Math.log(s);return Math.max(0,r*100/171)}function Zi(e,n){let i=R(e,n);return Math.max(1,i.lineEnd-i.lineStart+1)}var Xa,es=N(()=>{"use strict";W();Xa=new Set([T.SyntaxKind.PlusToken,T.SyntaxKind.MinusToken,T.SyntaxKind.AsteriskToken,T.SyntaxKind.SlashToken,T.SyntaxKind.PercentToken,T.SyntaxKind.AsteriskAsteriskToken,T.SyntaxKind.PlusPlusToken,T.SyntaxKind.MinusMinusToken,T.SyntaxKind.EqualsToken,T.SyntaxKind.PlusEqualsToken,T.SyntaxKind.MinusEqualsToken,T.SyntaxKind.AsteriskEqualsToken,T.SyntaxKind.SlashEqualsToken,T.SyntaxKind.EqualsEqualsToken,T.SyntaxKind.EqualsEqualsEqualsToken,T.SyntaxKind.ExclamationEqualsToken,T.SyntaxKind.ExclamationEqualsEqualsToken,T.SyntaxKind.LessThanToken,T.SyntaxKind.GreaterThanToken,T.SyntaxKind.LessThanEqualsToken,T.SyntaxKind.GreaterThanEqualsToken,T.SyntaxKind.AmpersandAmpersandToken,T.SyntaxKind.BarBarToken,T.SyntaxKind.ExclamationToken,T.SyntaxKind.QuestionQuestionToken,T.SyntaxKind.IfKeyword,T.SyntaxKind.ElseKeyword,T.SyntaxKind.ForKeyword,T.SyntaxKind.WhileKeyword,T.SyntaxKind.DoKeyword,T.SyntaxKind.SwitchKeyword,T.SyntaxKind.CaseKeyword,T.SyntaxKind.ReturnKeyword,T.SyntaxKind.ThrowKeyword,T.SyntaxKind.NewKeyword,T.SyntaxKind.DeleteKeyword,T.SyntaxKind.TypeOfKeyword,T.SyntaxKind.AwaitKeyword,T.SyntaxKind.YieldKeyword,T.SyntaxKind.DotToken,T.SyntaxKind.OpenParenToken,T.SyntaxKind.OpenBracketToken,T.SyntaxKind.EqualsGreaterThanToken,T.SyntaxKind.DotDotDotToken])});import*as xe from"typescript";function el(e,n){let i=0,t=e;for(;xe.isPropertyAccessExpression(t)||xe.isElementAccessExpression(t);)i++,t=t.expression;if(i<Za)return null;let s=e.parent;return xe.isPropertyAccessExpression(s)||xe.isElementAccessExpression(s)?null:{text:e.getText(n),depth:i}}function Pr(e,n,i){let t=[],s=r=>{if(xe.isPropertyAccessExpression(r)||xe.isElementAccessExpression(r)){let o=el(r,e);if(o){let a=R(e,r);t.push({chain:o.text.slice(0,80),depth:o.depth,lineStart:a.lineStart,lineEnd:a.lineEnd})}}xe.forEachChild(r,s)};xe.forEachChild(e,s),t.length>0&&(i.messageChains=t)}var Za,Ir=N(()=>{"use strict";W();Za=4});import*as $ from"typescript";function Or(e,n){let i=[];for(let t of e.statements){if($.isImportDeclaration(t)){if(!t.importClause){let s=t.moduleSpecifier,r=$.isStringLiteral(s)?s.text:"<unknown>",o=R(e,t);i.push({kind:"side-effect-import",lineStart:o.lineStart,lineEnd:o.lineEnd,detail:`import '${r}'`,weight:3,confidence:"medium"})}continue}if(!($.isExportDeclaration(t)||$.isExportAssignment(t))&&!($.isTypeAliasDeclaration(t)||$.isInterfaceDeclaration(t)||$.isEnumDeclaration(t))&&!$.isModuleDeclaration(t)&&!(ae(t)||$.isFunctionDeclaration(t)||$.isClassDeclaration(t))){if($.isVariableStatement(t)){for(let s of t.declarationList.declarations)s.initializer&&Lr(s.initializer,e,i);continue}if($.isExpressionStatement(t)){Lr(t.expression,e,i);continue}($.isIfStatement(t)||$.isForStatement(t)||$.isWhileStatement(t)||$.isDoStatement(t)||$.isForOfStatement(t)||$.isForInStatement(t)||$.isSwitchStatement(t)||$.isTryStatement(t))&&jr(t,e,i)}}return i}function Lr(e,n,i){if($.isAwaitExpression(e)){let t=R(n,e);i.push({kind:"top-level-await",lineStart:t.lineStart,lineEnd:t.lineEnd,detail:"top-level await",weight:4,confidence:"high"});return}if($.isCallExpression(e)){ts(e,n,i);return}if($.isNewExpression(e)&&e.expression.getText(n)==="Function"){let t=R(n,e);i.push({kind:"eval",lineStart:t.lineStart,lineEnd:t.lineEnd,detail:"new Function()",weight:8,confidence:"high"});return}$.isBinaryExpression(e)&&e.operatorToken.kind===$.SyntaxKind.EqualsToken&&$.isCallExpression(e.right)&&ts(e.right,n,i)}function ts(e,n,i){let t=e.expression.getText(n),s=R(n,e);if(t==="eval"||t==="Function"){i.push({kind:"eval",lineStart:s.lineStart,lineEnd:s.lineEnd,detail:`${t}()`,weight:8,confidence:"high"});return}if(t==="setInterval"||t==="setTimeout"){i.push({kind:"timer",lineStart:s.lineStart,lineEnd:s.lineEnd,detail:`${t}()`,weight:4,confidence:"high"});return}if($.isPropertyAccessExpression(e.expression)){let r=e.expression.name.getText(n),o=e.expression.expression.getText(n);if(Nr.has(r)||Nr.has(t)){i.push({kind:"exec-sync",lineStart:s.lineStart,lineEnd:s.lineEnd,detail:t,weight:8,confidence:"high"});return}if(tl.has(r)){i.push({kind:"sync-io",lineStart:s.lineStart,lineEnd:s.lineEnd,detail:t,weight:5,confidence:"high"});return}if(o==="process"&&(r==="on"||r==="once"||r==="addListener")){i.push({kind:"process-handler",lineStart:s.lineStart,lineEnd:s.lineEnd,detail:`${t}()`,weight:4,confidence:"high"});return}if(r==="addEventListener"||r==="on"||r==="addListener"){i.push({kind:"listener",lineStart:s.lineStart,lineEnd:s.lineEnd,detail:`${t}()`,weight:4,confidence:"medium"});return}}($.isCallExpression(e.expression)||t==="import")&&(t.startsWith("import(")||$.isCallExpression(e)&&e.expression.kind===$.SyntaxKind.ImportKeyword)&&i.push({kind:"dynamic-import",lineStart:s.lineStart,lineEnd:s.lineEnd,detail:"dynamic import()",weight:3,confidence:"medium"})}function jr(e,n,i){if(!(ae(e)||$.isClassDeclaration(e))){if($.isCallExpression(e)){ts(e,n,i);return}if($.isAwaitExpression(e)){let t=R(n,e);i.push({kind:"top-level-await",lineStart:t.lineStart,lineEnd:t.lineEnd,detail:"top-level await",weight:4,confidence:"high"});return}if($.isNewExpression(e)&&e.expression.getText(n)==="Function"){let t=R(n,e);i.push({kind:"eval",lineStart:t.lineStart,lineEnd:t.lineEnd,detail:"new Function()",weight:8,confidence:"high"});return}$.forEachChild(e,t=>jr(t,n,i))}}function Rt(e){let n=e.parent;for(;n;){if($.isBlock(n)||$.isSourceFile(n))return n;n=n.parent}return null}function _r(e,n,i){let t=!1,s=r=>{if(!t){if($.isCallExpression(r)&&r.expression.getText(n)===i){t=!0;return}$.forEachChild(r,s)}};return $.forEachChild(e,s),t}var tl,Nr,At=N(()=>{"use strict";He();W();tl=new Set(["readFileSync","writeFileSync","existsSync","mkdirSync","readdirSync","statSync","lstatSync","unlinkSync","rmdirSync","renameSync","copyFileSync","accessSync","appendFileSync","chmodSync","chownSync","openSync","closeSync"]),Nr=new Set(["execSync","execFileSync","spawnSync"])});import*as z from"typescript";function rl(e){let n=!1;for(let i of e){if(nl.test(i))return"high";il.test(i)&&(n=!0)}return n?"medium":"low"}function Hr(e,n,i){let t=[],s=r=>{if(!ae(r)){z.forEachChild(r,s);return}let o=r,a=o.parameters,l=[];for(let h of a){let y=h.name.getText(e);sl.test(y)&&l.push(y)}if(l.length===0){z.forEachChild(r,s);return}let c=o.body;if(!c){z.forEachChild(r,s);return}let u=new Set,d=!1,f=[],p=new Set(l),g=h=>{if(!(ae(h)&&h!==r)){if(z.isCallExpression(h)){let y=h.expression.getText(e);for(let D of ol)if(D.pattern.test(y)){u.add(D.kind);break}(al.test(y)||ll.test(y))&&(d=!0);for(let D of h.arguments){let b=D.getText(e);for(let k of p)if(b===k||b.startsWith(k+".")||b.startsWith(k+"[")){let C=R(e,h);f.push({callee:y,lineStart:C.lineStart});break}}}if(z.isTypeOfExpression(h)){let y=h.expression.getText(e);p.has(y)&&(d=!0)}if(z.isPrefixUnaryExpression(h)&&h.operator===z.SyntaxKind.ExclamationToken){let y=h.operand.getText(e);p.has(y)&&(d=!0)}if(z.isIfStatement(h)||z.isConditionalExpression(h)){let D=(z.isIfStatement(h)?h.expression:h.condition).getText(e);for(let b of p)if(D.includes(b)){d=!0;break}}if(z.isCallExpression(h)&&h.expression.getText(e).endsWith("instanceof")&&(d=!0),z.isBinaryExpression(h)&&h.operatorToken.kind===z.SyntaxKind.InstanceOfKeyword){let y=h.left.getText(e);p.has(y)&&(d=!0)}z.forEachChild(h,g)}};if(z.forEachChild(c,g),z.isTemplateExpression(c)||z.isBlock(c)){let h=c.getText(e);for(let y of p)if(h.includes(y+"?.")){d=!0;break}}let m=R(e,r),S=Qe(r,e);t.push({functionName:S,lineStart:m.lineStart,lineEnd:m.lineEnd,sourceParams:l,hasSinkInBody:u.size>0,sinkKinds:[...u],hasValidation:d,callsWithInputArgs:f,paramConfidence:rl(l)}),z.forEachChild(r,s)};z.forEachChild(e,s),i.inputSources=t}var nl,il,sl,ol,al,ll,Br=N(()=>{"use strict";He();W();nl=/^(req|request|body|rawBody|formData|payload|query|headers|params)$/i,il=/^(input|event|message)$/i,sl=/^(req|request|body|input|payload|data|params|query|headers|event|message|ctx|context|args|rawBody|formData)/i;ol=[{pattern:/^eval$/,kind:"eval"},{pattern:/^Function$/,kind:"eval"},{pattern:/\.exec(Sync)?$/,kind:"exec"},{pattern:/^child_process\.(exec|spawn|fork)/,kind:"exec"},{pattern:/^execSync$|^spawnSync$/,kind:"exec"},{pattern:/^cp\.exec$|^cp\.spawn$/,kind:"exec"},{pattern:/\.innerHTML$|\.outerHTML$/,kind:"innerHTML"},{pattern:/dangerouslySetInnerHTML/,kind:"innerHTML"},{pattern:/\.query$|\.execute$/,kind:"sql"},{pattern:/\.redirect$/,kind:"redirect"},{pattern:/\.send$|\.json$|\.write$/,kind:"response"},{pattern:/fs\.(writeFile|appendFile)/,kind:"fs-write"},{pattern:/writeFileSync|appendFileSync/,kind:"fs-write"},{pattern:/fs\.(readFile|readFileSync|createReadStream)/,kind:"fs-read"},{pattern:/readFileSync|readFile/,kind:"fs-read"},{pattern:/path\.(resolve|join)/,kind:"path-resolve"},{pattern:/^fetch$/,kind:"ssrf"},{pattern:/^(http|https)\.(request|get)/,kind:"ssrf"},{pattern:/axios\.(get|post|put|delete|request)/,kind:"ssrf"}],al=/\.(validate|parse|safeParse|parseAsync|check|verify)\s*\(/,ll=/^(z|zod|Joi|yup|ajv|validator|superstruct|io-ts)\./});import*as ie from"typescript";function zr(e,n,i){let t=[],s=[],r=[],o=[],a=[],l=u=>{let d=u.parent;for(;d;){if(ie.isForStatement(d)||ie.isWhileStatement(d)||ie.isDoStatement(d)||ie.isForOfStatement(d)||ie.isForInStatement(d))return!0;if(ae(d))return!1;d=d.parent}return!1},c=u=>{if(ie.isAwaitExpression(u)&&l(u)){let d=R(e,u);t.push({file:n,lineStart:d.lineStart,lineEnd:d.lineEnd})}if(ie.isCallExpression(u)&&ie.isPropertyAccessExpression(u.expression)){let d=u.expression.name.getText(e);if(cl.has(d)){let f=R(e,u);s.push({name:d,lineStart:f.lineStart,lineEnd:f.lineEnd})}if(d==="addEventListener"||d==="on"||d==="addListener"){let f=R(e,u);o.push({file:n,lineStart:f.lineStart,lineEnd:f.lineEnd})}if(d==="removeEventListener"||d==="off"||d==="removeListener"){let f=R(e,u);a.push({file:n,lineStart:f.lineStart,lineEnd:f.lineEnd})}}if(ie.isCallExpression(u)){let d=u.expression.getText(e);if(d==="setInterval"||d==="setTimeout"){let f=R(e,u),p=d==="setInterval"?"clearInterval":"clearTimeout",g=Rt(u),m=g?_r(g,e,p):!1;r.push({kind:d,lineStart:f.lineStart,lineEnd:f.lineEnd,hasCleanup:m})}}ie.forEachChild(u,c)};ie.forEachChild(e,c),i.awaitInLoopLocations=t,i.syncIoCalls=s,i.timerCalls=r,i.listenerRegistrations=o,i.listenerRemovals=a}var cl,Kr=N(()=>{"use strict";At();He();W();cl=new Set(["readFileSync","writeFileSync","existsSync","mkdirSync","readdirSync","statSync","lstatSync","unlinkSync","rmdirSync","renameSync","copyFileSync","accessSync","appendFileSync","chmodSync","chownSync","openSync","closeSync","execSync","execFileSync","spawnSync"])});import*as Q from"typescript";function ul(e,n){let i=e.argumentExpression;if(!i||!Q.isIdentifier(i))return!1;let t=i.getText(n),s=e.parent;for(;s;){if(Q.isForOfStatement(s)||Q.isForInStatement(s)){let r=s.initializer;if(r&&r.getText(n).includes(t)){let a=s.expression.getText(n);if(/Object\.(keys|values|entries|getOwnPropertyNames)\(/.test(a)||/\.keys\(\)|\.values\(\)|\.entries\(\)/.test(a)||/Array\.from\(/.test(a))return!0}}if(ae(s))break;s=s.parent}return!1}function fl(e,n){let i=Rt(e);if(!i)return!1;let t=i.getText(n);return/__proto__|constructor|prototype/.test(t)&&(t.includes("===")||t.includes("!==")||t.includes("includes(")||t.includes("hasOwnProperty"))}function pl(e,n){let i=e.expression.getText(n),t=e.parent;for(;t;){if(Q.isBlock(t)||Q.isSourceFile(t)){let s=t.getText(n),r=new RegExp(`${i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*=\\s*Object\\.create\\(null\\)`),o=new RegExp(`${i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*=\\s*new\\s+(Map|Set)\\b`);if(r.test(s)||o.test(s))return!0;break}t=t.parent}return!1}function Ur(e){let n=[],i=t=>{if(Q.isCallExpression(t)){let s=t.expression.getText(e);if(s==="Object.assign"&&t.arguments.length>=2){let o=R(e,t);n.push({kind:"object-assign",detail:"Object.assign() merges properties without __proto__ guard",lineStart:o.lineStart,lineEnd:o.lineEnd,guarded:!1})}let r=s.split(".").pop()||"";if(dl.has(r)&&t.arguments.length>=1){let o=R(e,t);n.push({kind:"deep-merge",detail:`${r}() deep-merges without prototype guard`,lineStart:o.lineStart,lineEnd:o.lineEnd,guarded:!1})}}if(Q.isElementAccessExpression(t)&&t.argumentExpression&&!Q.isStringLiteral(t.argumentExpression)&&!Q.isNumericLiteral(t.argumentExpression)&&t.parent&&Q.isBinaryExpression(t.parent)&&t.parent.operatorToken.kind===Q.SyntaxKind.EqualsToken&&t.parent.left===t){let s=ul(t,e)||fl(t,e)||pl(t,e),r=R(e,t);n.push({kind:"computed-property-write",detail:`Dynamic bracket assignment: ${t.getText(e).slice(0,40)}`,lineStart:r.lineStart,lineEnd:r.lineEnd,guarded:s})}Q.forEachChild(t,i)};return Q.forEachChild(e,i),n}var dl,qr=N(()=>{"use strict";At();He();W();dl=new Set(["merge","deepMerge","deepAssign","extend","deepExtend","defaults","defaultsDeep","assign","mixin"])});import*as I from"typescript";function wl(e){let n=e.parent;for(;n;){if(I.isRegularExpressionLiteral(n)||I.isNewExpression(n)&&n.expression.getText(e.getSourceFile())==="RegExp")return!0;n=n.parent}return!1}function Fl(e){return El.test(e)||vl.test(e)}function Wr(e){let n=e.parent;for(;n;){if(I.isPropertyAssignment(n)&&I.isIdentifier(n.name)&&kl.has(n.name.text))return!0;n=n.parent}return!1}function Cl(e){let n=new Map;for(let t of e)n.set(t,(n.get(t)||0)+1);let i=0;for(let t of n.values()){let s=t/e.length;s>0&&(i-=s*Math.log2(s))}return i}function Tl(e,n){let i=e.parent;return I.isVariableDeclaration(i)?I.isIdentifier(i.name)?Mt.test(i.name.text):!1:I.isPropertyAssignment(i)&&(I.isIdentifier(i.name)||I.isStringLiteral(i.name)||I.isNumericLiteral(i.name))?Mt.test(i.name.text):I.isBinaryExpression(i)&&I.isPropertyAccessExpression(i.left)?Mt.test(i.left.name.getText(n)):!1}function $l(e){return Sl.test(e)?!1:gl.some(i=>i.test(e))?!0:!ml.some(i=>i.test(e))||hl.test(e)?!1:yl.test(e)}function Vr(e,n,i){let t=[],s=[],r=[],o=[],a=[],l=c=>{if(I.isDebuggerStatement(c)){let u=R(e,c);o.push({method:"debugger",lineStart:u.lineStart,lineEnd:u.lineEnd,hasSensitiveArg:!1})}if(I.isCallExpression(c)){let u=c.expression;if(I.isPropertyAccessExpression(u)){let d=u.expression.getText(e),f=u.name.getText(e);if(d==="console"&&bl.has(f)){let p=R(e,c),g=c.arguments.map(S=>S.getText(e)).join(" "),m=$l(g);o.push({method:f,lineStart:p.lineStart,lineEnd:p.lineEnd,hasSensitiveArg:m,argSnippet:g.slice(0,80)})}}}if(I.isCallExpression(c)){let u=c.expression.getText(e);if(u==="eval"||u==="Function"){let d=R(e,c);t.push({file:n,lineStart:d.lineStart,lineEnd:d.lineEnd})}if(u==="new Function"){let d=R(e,c);t.push({file:n,lineStart:d.lineStart,lineEnd:d.lineEnd})}if((u==="setTimeout"||u==="setInterval")&&c.arguments.length>0){let d=c.arguments[0];if(I.isStringLiteral(d)||I.isNoSubstitutionTemplateLiteral(d)){let f=R(e,c);t.push({file:n,lineStart:f.lineStart,lineEnd:f.lineEnd})}}if(u==="document.write"||u==="document.writeln"){let d=R(e,c);s.push({file:n,lineStart:d.lineStart,lineEnd:d.lineEnd})}}if(I.isNewExpression(c)&&c.expression.getText(e)==="Function"){let u=R(e,c);t.push({file:n,lineStart:u.lineStart,lineEnd:u.lineEnd})}if(I.isBinaryExpression(c)&&c.operatorToken.kind===I.SyntaxKind.EqualsToken&&I.isPropertyAccessExpression(c.left)){let u=c.left.name.getText(e);if(u==="innerHTML"||u==="outerHTML"){let d=R(e,c);s.push({file:n,lineStart:d.lineStart,lineEnd:d.lineEnd})}}if(I.isJsxAttribute(c)&&c.name.getText(e)==="dangerouslySetInnerHTML"){let u=R(e,c);s.push({file:n,lineStart:u.lineStart,lineEnd:u.lineEnd})}if((I.isStringLiteral(c)||I.isNoSubstitutionTemplateLiteral(c))&&!Wr(c)&&!wl(c)){let u=c.text;if(!Fl(u)){let d=!1;for(let f of Gr)if(f.test(u)){let p=R(e,c);r.push({lineStart:p.lineStart,lineEnd:p.lineEnd,kind:"hardcoded-secret",snippet:u.slice(0,40),context:"literal"}),d=!0;break}if(!d&&u.length>=20&&Cl(u)>4.5&&Tl(c,e)){let f=R(e,c);r.push({lineStart:f.lineStart,lineEnd:f.lineEnd,kind:"hardcoded-secret",context:"literal"})}}}if(I.isRegularExpressionLiteral(c)){let u=c.getText(e);for(let d of Gr)if(d.test(u)){let f=R(e,c);r.push({lineStart:f.lineStart,lineEnd:f.lineEnd,kind:"hardcoded-secret",snippet:u.slice(0,40),context:"regex-definition"});break}}if(I.isTemplateExpression(c)&&!Wr(c)){let u=c.getText(e);if(xl.test(u)&&c.templateSpans.length>0){let d=R(e,c);r.push({lineStart:d.lineStart,lineEnd:d.lineEnd,kind:"sql-injection",snippet:u.slice(0,60)})}}if(I.isRegularExpressionLiteral(c)){let u=c.text,d=R(e,c);a.push({lineStart:d.lineStart,lineEnd:d.lineEnd,pattern:u})}I.forEachChild(c,l)};I.forEachChild(e,l),i.evalUsages=t,i.unsafeHtmlAssignments=s,i.suspiciousStrings=r,i.consoleLogs=o,i.regexLiterals=a}var gl,ml,hl,yl,Sl,Mt,bl,Gr,xl,El,vl,kl,Qr=N(()=>{"use strict";W();gl=[/password/i,/passwd/i,/\bsecret\b/i,/\btoken\b/i,/credential/i,/credit.?card/i,/\bssn\b/i,/social.?security/i,/api[_-]?key/i,/private[_-]?key/i,/access[_-]?key/i],ml=[/\bauth\b/i,/\bsession\b/i],hl=/\b(auth|session)\b.{0,40}\b(flow|status|state|start(?:ed)?|success(?:ful|fully)?|fail(?:ed|ure)?|refresh(?:ed)?|renew(?:ed)?|expire(?:d)?|invalid|chang(?:e|ed)|required|created|destroyed)\b/i,yl=/\b(id|sid|jwt|bearer|cookie|header|authorization|credential|secret|token|key)\b|[:=]|\{|\}/i,Sl=/\busage:\b|\boptions:\b|--[a-z0-9-]+|\bunknown\b.{0,20}\btoken\b|\bpillar names?\b|\bcategory names?\b/i,Mt=/(password|passwd|secret|token|api[_-]?key|private[_-]?key|access[_-]?key|credential|auth|session|jwt|bearer|ssn)/i,bl=new Set(["log","debug","trace","info","warn","error","dir","table"]),Gr=[/password\s*[:=]\s*['"`]/i,/api[_-]?key\s*[:=]\s*['"`]/i,/secret\s*[:=]\s*['"`]/i,/token\s*[:=]\s*['"`]/i,/-----BEGIN.*KEY/,/private[_-]?key\s*[:=]\s*['"`]/i,/auth[_-]?token\s*[:=]\s*['"`]/i],xl=/\b(SELECT|INSERT|UPDATE|DELETE|DROP|ALTER|CREATE|TRUNCATE)\b/i,El=/^(YOUR_|REPLACE_ME|<[a-z_-]+>|\$\{|{{)/i,vl=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;kl=new Set(["suggestedFix","strategy","steps","reason","impact","expectedResult","title"])});import*as q from"typescript";function Ll(e,n){if(!q.isPropertyAccessExpression(e.expression))return;let i=e.expression.name.getText(n),t=e.expression.expression.getText(n);if((t==="jest"||t==="vi")&&i==="spyOn")return"spy";if(t==="sinon"&&(i==="stub"||i==="mock"))return"stub"}function Ol(e,n){let i=e;for(;i.parent;){let t=i.parent;if(q.isVariableDeclaration(t)&&t.initializer===i&&q.isIdentifier(t.name))return t.name.getText(n);if(q.isBinaryExpression(t)&&t.operatorToken.kind===q.SyntaxKind.EqualsToken&&t.right===i)return t.left.getText(n).trim();i=t}}function jl(e,n){if(q.isPropertyAccessExpression(e.expression))return e.expression.expression.getText(n).trim()}function Jr(e,n,i){let t=[],s=[],r=[],o=[],a=[],l=[],c=[],u=[],d=(f,p,g)=>{if(q.isCallExpression(f)){let m=f.expression.getText(e);if(Pl.has(m)){let S=R(e,f);a.push({kind:m,lineStart:S.lineStart,lineEnd:S.lineEnd})}if((m==="it"||m==="test"||m==="it.only"||m==="test.only")&&f.arguments.length>=2){let S=f.arguments[0],h=q.isStringLiteral(S)?S.text:m,y=f.arguments[1],D=R(e,f),b=0,k=C=>{if(q.isCallExpression(C)){let A=C.expression.getText(e);(Dl.has(A.split(".")[0])||A.includes(".to.")||A.includes(".should"))&&b++}q.forEachChild(C,k)};q.forEachChild(y,k),t.push({name:h,lineStart:D.lineStart,lineEnd:D.lineEnd,assertionCount:b}),q.forEachChild(f,C=>d(C,p,!0));return}if(Rl.some(S=>m===S||m.startsWith(S+"("))){let S=R(e,f);s.push({file:n,lineStart:S.lineStart,lineEnd:S.lineEnd});let h=Ll(f,e);h&&u.push({kind:h,file:n,lineStart:S.lineStart,lineEnd:S.lineEnd,target:Ol(f,e)})}if(Il.has(m)){let S=R(e,f);l.push({kind:m,lineStart:S.lineStart,lineEnd:S.lineEnd})}if(Nl.has(m)){let S=R(e,f);l.push({kind:m,lineStart:S.lineStart,lineEnd:S.lineEnd})}if(Al.has(m)){let S=R(e,f);c.push({kind:"restoreAll",file:n,lineStart:S.lineStart,lineEnd:S.lineEnd})}else if(m.endsWith(".mockRestore")){let S=R(e,f);c.push({kind:"restore",file:n,lineStart:S.lineStart,lineEnd:S.lineEnd,target:jl(f,e)})}if(Ml.has(m)){let S=R(e,f);r.push({kind:m,lineStart:S.lineStart})}if(m==="describe"||m==="describe.only"){q.forEachChild(f,S=>d(S,!0,g));return}}if(p&&!g&&q.isVariableStatement(f)){let m=f.declarationList;if(m.flags&q.NodeFlags.Let||!(m.flags&q.NodeFlags.Const)){let S=R(e,f);o.push({file:n,lineStart:S.lineStart,lineEnd:S.lineEnd})}}q.forEachChild(f,m=>d(m,p,g))};q.forEachChild(e,f=>d(f,!1,!1)),i.testProfile={testBlocks:t,mockCalls:s,setupCalls:r,mutableStateDecls:o,focusedCalls:a,timerControls:l,mockRestores:c,spyOrStubCalls:u}}var Dl,Rl,Al,Ml,Pl,Il,Nl,Yr=N(()=>{"use strict";W();Dl=new Set(["expect","assert","should"]),Rl=["jest.mock","vi.mock","sinon.stub","jest.spyOn","vi.spyOn","sinon.mock"],Al=new Set(["jest.restoreAllMocks","vi.restoreAllMocks"]),Ml=new Set(["beforeAll","beforeEach","afterAll","afterEach"]),Pl=new Set(["it.only","test.only","describe.only","it.skip","test.skip","describe.skip","it.todo","test.todo"]),Il=new Set(["jest.useFakeTimers","vi.useFakeTimers"]),Nl=new Set(["jest.useRealTimers","vi.useRealTimers"])});import Zr from"node:path";import*as v from"typescript";function eo(e,n){if(!e||!Array.isArray(e.functions))return{file:e?.file||"<unknown>",complexityRisk:1,highComplexityFunctions:0,functionCount:0,flows:0,score:1};let i=0,t=0;for(let o of e.functions){let a=Number(o.complexity)||0;i+=a,a>=n.thresholds.criticalComplexityThreshold&&(t+=1)}let s=e.flows?e.flows.length:0,r=Math.max(1,Math.round(i*.7+e.functions.length*2+s*.2));return{file:e.file,functionCount:e.functions.length,highComplexityFunctions:t,flows:s,complexitySum:i,complexityRisk:t,score:r}}function _l(e){if(v.isIfStatement(e)){let n=e.thenStatement;return v.isBlock(n)?n.statements.length:1}if(v.isSwitchStatement(e))return e.caseBlock.clauses.length;if(v.isTryStatement(e))return e.tryBlock.statements.length;if(v.isForStatement(e)||v.isWhileStatement(e)||v.isDoStatement(e)||v.isForOfStatement(e)||v.isForInStatement(e)){let n=e.statement;return v.isBlock(n)?n.statements.length:1}return 1}function Xr(e,n,i){let t=R(n,e);return{file:Zr.relative(i,e.getSourceFile().fileName),lineStart:t.lineStart,lineEnd:t.lineEnd,columnStart:t.columnStart,columnEnd:t.columnEnd}}function ns(e,n,i,t,s,r,o){let a=e.fileName,l=Zr.relative(t.root,a);i.fileCount+=1,i.nodeCount+=1,i.kindCounts.SourceFile=(i.kindCounts.SourceFile||0)+1;let c={package:n,file:l,parseEngine:"typescript",nodeCount:0,kindCounts:{},functions:[],flows:[],dependencyProfile:o};if(t.emitTree){let b={size:8e3},k=Xt(e,e,t.treeDepth,b);k&&r.push({package:n,file:l,tree:k})}let u=pt,d=[],f=[],p=[],g=0,m=[],S=[],h=[],y=new Set([0,1,-1,2,100]),D=b=>{c.nodeCount+=1,i.nodeCount+=1;let k=v.SyntaxKind[b.kind]||"UNKNOWN";if(c.kindCounts[k]=(c.kindCounts[k]||0)+1,i.kindCounts[k]=(i.kindCounts[k]||0)+1,v.isCatchClause(b)&&b.block.statements.length===0){let A=R(e,b);d.push({file:l,lineStart:A.lineStart,lineEnd:A.lineEnd})}if(v.isSwitchStatement(b)&&!b.caseBlock.clauses.some(A=>A.kind===v.SyntaxKind.DefaultClause)){let A=R(e,b);f.push({file:l,lineStart:A.lineStart,lineEnd:A.lineEnd})}if(b.kind===v.SyntaxKind.AnyKeyword&&(g+=1),v.isAsExpression(b)&&b.type.kind===v.SyntaxKind.AnyKeyword&&(g+=1),v.isAsExpression(b)){if(b.type.kind===v.SyntaxKind.AnyKeyword){let C=R(e,b);m.push({file:l,lineStart:C.lineStart,lineEnd:C.lineEnd})}if(v.isAsExpression(b.expression)&&b.expression.type.kind===v.SyntaxKind.UnknownKeyword){let C=R(e,b);S.push({file:l,lineStart:C.lineStart,lineEnd:C.lineEnd})}}if(v.isNonNullExpression(b)){let C=R(e,b);h.push({file:l,lineStart:C.lineStart,lineEnd:C.lineEnd})}if(v.isNumericLiteral(b)){let C=Number(b.text);if(!y.has(C)){let A=b.parent,M=A&&v.isVariableDeclaration(A)&&A.parent&&v.isVariableDeclarationList(A.parent)&&(A.parent.flags&v.NodeFlags.Const)!==0,E=A&&v.isEnumMember(A);if(!M&&!E){let _=R(e,b);p.push({value:C,file:l,lineStart:_.lineStart,lineEnd:_.lineEnd})}}}if(ae(b)){let C=b,A=C.body,M=A&&v.isBlock(A)?A.statements.length:1,E=Xr(b,e,t.root),_=Qe(b,e),K=A?Ji(A):{complexity:1,maxBranchDepth:0,maxLoopDepth:0,returns:0,awaits:0,calls:0,loops:0},V={kind:k,name:_,nameHint:_,file:l,lineStart:E.lineStart,lineEnd:E.lineEnd,columnStart:E.columnStart,columnEnd:E.columnEnd,statementCount:M,complexity:K.complexity,maxBranchDepth:K.maxBranchDepth,maxLoopDepth:K.maxLoopDepth,returns:K.returns,awaits:K.awaits,calls:K.calls,loops:K.loops,lengthLines:Zi(e,b),cognitiveComplexity:A?In(A):0};if(A&&(V.halstead=Yi(A),V.maintainabilityIndex=Xi(V.halstead.volume,K.complexity,V.lengthLines)),v.isFunctionDeclaration(b)&&(V.declared=!0),M>=t.thresholds.minFunctionStatements){let se=A?Jt(A):Ge(l);Se(s.flowMap,`${se}|${b.kind}`,{...V,hash:se,metrics:K})}C.parameters&&(V.params=C.parameters.length),c.functions.push(V),i.functions.push(V),i.functionCount+=1}if(u.has(b.kind)){let C=_l(b),A=Xr(b,e,t.root),M={kind:k,file:l,lineStart:A.lineStart,lineEnd:A.lineEnd,columnStart:A.columnStart,columnEnd:A.columnEnd,statementCount:C};if(c.flows.push(M),i.flowCount+=1,C>=t.thresholds.minFlowStatements){let E=Jt(b);Se(s.controlMap,`${E}|${b.kind}`,{...M,hash:E})}}v.forEachChild(b,D)};return v.forEachChild(e,D),c.emptyCatches=d,c.switchesWithoutDefault=f,c.anyCount=g,c.magicNumbers=p,c.typeAssertionEscapes={asAny:m,doubleAssertion:S,nonNull:h},Hl(e,c),Bl(e,l,c),Ul(e,l,c),c}function Hl(e,n){let i=[],t=[];for(let s of n.functions){if(s.awaits===0)continue;let r=e.getPositionOfLineAndCharacter(Math.max(0,s.lineStart-1),0),o,a=p=>{if(!o){if(ae(p)&&p.getStart(e)>=r&&R(e,p).lineStart===s.lineStart){o=p;return}v.forEachChild(p,a)}};if(v.forEachChild(e,a),!o||!o.modifiers?.some(p=>p.kind===v.SyntaxKind.AsyncKeyword))continue;let c=0,u=!1,d=!1,f=p=>{v.isAwaitExpression(p)&&c++,v.isTryStatement(p)&&(u=!0),v.isCallExpression(p)&&v.isPropertyAccessExpression(p.expression)&&p.expression.name.text==="catch"&&(d=!0),!(ae(p)&&p!==o)&&v.forEachChild(p,f)};v.forEachChild(o,f),c===0?i.push({name:s.name,lineStart:s.lineStart,lineEnd:s.lineEnd}):!u&&!d&&t.push({name:s.name,awaitCount:c,lineStart:s.lineStart,lineEnd:s.lineEnd})}n.asyncWithoutAwait=i,n.unprotectedAsync=t}function Bl(e,n,i){if(Vr(e,n,i),x(n)||(Hr(e,n,i),Pr(e,n,i)),zr(e,n,i),x(n)&&Jr(e,n,i),!x(n)){let t=Or(e,n);t.length>0&&(i.topLevelEffects=t);let s=Ur(e);s.length>0&&(i.prototypePollutionSites=s)}}function Ul(e,n,i){if(x(n))return;let t=[],s=[],r=[],o=[],a=new Map,l=c=>{if(v.isBinaryExpression(c)&&(c.operatorToken.kind===v.SyntaxKind.EqualsEqualsEqualsToken||c.operatorToken.kind===v.SyntaxKind.ExclamationEqualsEqualsToken||c.operatorToken.kind===v.SyntaxKind.EqualsEqualsToken||c.operatorToken.kind===v.SyntaxKind.ExclamationEqualsToken)){let u=d=>{if(v.isStringLiteral(d)&&d.text.length>0){let f=R(e,d),p=a.get(d.text)||[];p.push({file:n,lineStart:f.lineStart,lineEnd:f.lineEnd}),a.set(d.text,p)}};u(c.left),u(c.right)}if(v.isSwitchStatement(c)){for(let u of c.caseBlock.clauses)if(v.isCaseClause(u)&&v.isStringLiteral(u.expression)){let d=u.expression.text;if(d.length>0){let f=R(e,u.expression),p=a.get(d)||[];p.push({file:n,lineStart:f.lineStart,lineEnd:f.lineEnd}),a.set(d,p)}}}if(v.isCatchClause(c)){let u=c.block;if(u.statements.length===1&&v.isThrowStatement(u.statements[0])){let d=u.statements[0].expression,f=c.variableDeclaration?.name;if(d&&f&&v.isIdentifier(f)&&v.isIdentifier(d)&&d.text===f.text){let p=R(e,c);s.push({file:n,lineStart:p.lineStart,lineEnd:p.lineEnd})}}}if(ae(c)){let u=c;if(u.parameters&&u.parameters.length>=2){let d=0;for(let f of u.parameters)f.type&&f.type.kind===v.SyntaxKind.BooleanKeyword&&d++;if(d>=3){let f=Qe(c,e),p=R(e,c);r.push({name:f,booleanCount:d,totalParams:u.parameters.length,lineStart:p.lineStart,lineEnd:p.lineEnd})}}}if(v.isCallExpression(c)&&v.isPropertyAccessExpression(c.expression)&&v.isIdentifier(c.expression.expression)&&c.expression.expression.text==="Promise"&&zl.has(c.expression.name.text)){let u=c.expression.name.text,d=!1,f=!1,p=c.parent;for(;p;){if(v.isTryStatement(p)){d=!0;break}if(v.isCallExpression(p)&&v.isPropertyAccessExpression(p.expression)&&p.expression.name.text==="catch"){f=!0;break}if(ae(p))break;p=p.parent}if(!d&&!f){let g=R(e,c);o.push({file:n,lineStart:g.lineStart,lineEnd:g.lineEnd,kind:Kl[u]||"Promise.all"})}}v.forEachChild(c,l)};v.forEachChild(e,l);for(let[c,u]of a)if(u.length>=2)for(let d of u)t.push({...d,value:c});t.length>0&&(i.magicStrings=t),s.length>0&&(i.catchRethrows=s),r.length>0&&(i.booleanParamClusters=r),o.length>0&&(i.promiseAllUnhandled=o)}var zl,Kl,to=N(()=>{"use strict";He();es();Ir();At();Br();Kr();qr();Qr();Yr();W();Ze();me();He();es();zl=new Set(["all","allSettled","race","any"]),Kl={all:"Promise.all",allSettled:"Promise.allSettled",race:"Promise.race",any:"Promise.any"}});import ql from"node:path";import{fileURLToPath as Gl}from"node:url";function no(e,n=process.argv[1]){return n?Gl(e)===ql.resolve(n):!1}var io=N(()=>{"use strict"});import $e from"node:path";import*as Y from"typescript";function Wl(e){let n=[];for(let i of e)for(let[t,s]of i.referenceCountByExport)s.count===0&&n.push({severity:"high",category:"semantic-dead-export",file:i.file,lineStart:s.lineStart,lineEnd:s.lineEnd,title:`Semantically dead export: ${t}`,reason:`Exported symbol "${t}" has zero semantic references across the entire program (confirmed via TypeChecker, not just import matching).`,files:[i.file],suggestedFix:{strategy:"Remove the export or delete the symbol if unused internally.",steps:["Verify the symbol is not used via dynamic imports or runtime reflection.","Remove the export keyword, or delete the symbol entirely if also unused locally.","Re-run scan to confirm finding is resolved."]},impact:"Dead exports bloat the public API surface and confuse contributors.",tags:["architecture","dead-code","semantic"],lspHints:[{tool:"lspFindReferences",symbolName:t,lineHint:s.lineStart,file:i.file,expectedResult:"zero references confirms dead export"}]});return n}function Vl(e,n){let i=[],t=new Map;for(let s of n){let r=e.program.getSourceFile($e.resolve(e.root,s.file));if(!r)continue;let o=a=>{if(Y.isInterfaceDeclaration(a)&&a.name){let l=a.name.text,c=r.getLineAndCharacterOfPosition(a.getStart(r)).line+1,u=e.service.getImplementationAtPosition($e.resolve(e.root,s.file),a.name.getStart(r)),d=new Set;if(u)for(let p of u){let g=p.fileName;(g!==$e.resolve(e.root,s.file)||p.textSpan.start!==a.getStart(r))&&d.add(g)}t.has(l)||t.set(l,{files:new Set,line:c,file:s.file});let f=t.get(l);for(let p of d)f.files.add(p)}Y.forEachChild(a,o)};Y.forEachChild(r,o)}for(let[s,r]of t)if(r.files.size===1){let o=[...r.files][0],a=$e.relative(e.root,o);i.push({severity:"medium",category:"over-abstraction",file:r.file,lineStart:r.line,lineEnd:r.line,title:`Over-abstraction: interface ${s} has exactly 1 implementor`,reason:`Interface "${s}" is implemented only by one class in "${a}". The abstraction layer adds complexity without enabling polymorphism.`,files:[r.file,a],suggestedFix:{strategy:"Inline the interface into the concrete class or keep it only if future implementors are planned.",steps:["Evaluate whether the interface is needed for testing (mocking) or future extensibility.","If not, merge the interface declaration into the concrete class.","Update consumers to depend on the concrete class directly."]},impact:"Over-abstraction adds indirection without polymorphic benefit, increasing cognitive load.",tags:["architecture","abstraction","semantic"],lspHints:[{tool:"lspFindReferences",symbolName:s,lineHint:r.line,file:r.file,expectedResult:"exactly 1 implementation confirms over-abstraction"}]})}return i}function Ql(e){let n=[];for(let i of e)for(let t of i.concreteImports)n.push({severity:"medium",category:"concrete-dependency",file:i.file,lineStart:t.lineStart,lineEnd:t.lineStart,title:`Concrete dependency: ${i.file} imports class ${t.name}`,reason:`Module imports concrete class "${t.name}" from "${t.targetFile}" instead of an interface or abstract class. This violates the Dependency Inversion Principle (DIP).`,files:[i.file,t.targetFile],suggestedFix:{strategy:"Depend on an interface or abstract class instead of the concrete implementation.",steps:["Extract an interface from the concrete class covering the methods used by this module.","Update imports to reference the interface instead of the concrete class.","Use dependency injection to provide the concrete implementation at runtime."]},impact:"Concrete dependencies make modules harder to test and tightly coupled to implementation details.",tags:["architecture","dip","coupling","semantic"],lspHints:[{tool:"lspGotoDefinition",symbolName:t.name,lineHint:t.lineStart,file:i.file,expectedResult:"resolves to concrete class (not interface/abstract)"}]});return n}function Jl(e,n){let i=[],t=new Map;for(let l of n){let c=e.program.getSourceFile($e.resolve(e.root,l.file));if(!c)continue;let u=new Set,d=new Map,f=p=>{if((Y.isInterfaceDeclaration(p)||Y.isTypeAliasDeclaration(p))&&p.name){let g=`${l.file}::${p.name.text}`;u.add(g);let m=new Set,S=h=>{if(Y.isTypeReferenceNode(h)&&Y.isIdentifier(h.typeName)){let y=h.typeName.text,D=e.checker.getSymbolAtLocation(h.typeName);if(D){let b=D.getDeclarations?.()?.[0];if(b){let k=b.getSourceFile().fileName,C=$e.relative(e.root,k);m.add(`${C}::${y}`)}}}Y.forEachChild(h,S)};Y.forEachChild(p,S),d.set(g,m)}Y.forEachChild(p,f)};Y.forEachChild(c,f);for(let[p,g]of d){t.has(p)||t.set(p,new Set);for(let m of g)t.get(p).add(m)}}let s=new Set,r=new Set,o=new Set,a=(l,c)=>{if(r.has(l)){let u=c.indexOf(l);if(u>=0){let d=c.slice(u),f=[...d].sort().join("\u2192");if(!o.has(f)&&d.length>=2){o.add(f);let p=d[0],[g]=p.split("::");i.push({severity:"high",category:"circular-type-dependency",file:g,lineStart:1,lineEnd:1,title:`Circular type dependency: ${d.map(m=>m.split("::")[1]).join(" \u2192 ")}`,reason:`Type-level circular dependency detected: ${d.map(m=>m.split("::")[1]).join(" \u2192 ")} \u2192 ${d[0].split("::")[1]}. Types reference each other creating a cycle.`,files:[...new Set(d.map(m=>m.split("::")[0]))],suggestedFix:{strategy:"Break the type cycle by extracting shared type definitions.",steps:["Identify the minimal set of type properties causing the cycle.","Extract shared types to a dedicated types file that both sides can import.","Replace direct type references with the shared type."]},impact:"Circular type dependencies make types harder to understand, refactor, and can cause issues with type inference.",tags:["architecture","types","cycle","semantic"]})}}return}if(!s.has(l)){r.add(l),c.push(l);for(let u of t.get(l)??[])a(u,c);c.pop(),r.delete(l),s.add(l)}};for(let l of t.keys())a(l,[]);return i}function Yl(e){let n=[];for(let i of e)for(let t of i.unusedParams)n.push({severity:"medium",category:"unused-parameter",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Unused parameter: ${t.paramName} in ${t.functionName}`,reason:`Parameter "${t.paramName}" in function "${t.functionName}" is never referenced in the function body (confirmed via semantic analysis).`,files:[i.file],suggestedFix:{strategy:"Remove the parameter or prefix with underscore to indicate intentional non-use.",steps:["Check if the parameter is required by an interface or callback signature.","If not required, remove it and update all call sites.","If required by contract, prefix with _ (e.g. _unused) to signal intent."]},impact:"Unused parameters add noise to function signatures and confuse callers about what the function actually needs.",tags:["code-quality","parameters","semantic"],lspHints:[{tool:"lspFindReferences",symbolName:t.paramName,lineHint:t.lineStart,file:i.file,expectedResult:"zero non-declaration references confirms unused"}]});return n}function Xl(e,n=3){let i=[];for(let t of e)for(let s of t.overrideChains)s.depth>n&&i.push({severity:s.depth>4?"high":"medium",category:"deep-override-chain",file:t.file,lineStart:s.lineStart,lineEnd:s.lineStart,title:`Deep override chain: ${s.className}.${s.methodName} (depth ${s.depth})`,reason:`Method "${s.methodName}" in class "${s.className}" overrides a method ${s.depth} levels up in the inheritance chain (threshold: ${n}).`,files:[t.file],suggestedFix:{strategy:"Reduce override depth by flattening the class hierarchy or using the template method pattern.",steps:["Identify if intermediate overrides are necessary or if they just pass through.","Consider extracting the behavior into a strategy or template method.","Flatten unnecessary intermediate classes."]},impact:"Deep override chains make method behavior unpredictable \u2014 understanding what runs requires tracing through many classes.",tags:["code-quality","inheritance","override","semantic"]});return i}function Zl(e){let n=[];for(let i of e)for(let t of i.interfaceImpls){let s=[];t.missingMembers.length>0&&s.push(`missing members: ${t.missingMembers.join(", ")}`),t.anycastMembers.length>0&&s.push(`any-cast members: ${t.anycastMembers.join(", ")}`),s.length>0&&n.push({severity:t.missingMembers.length>0?"high":"medium",category:"interface-compliance",file:t.classFile,lineStart:t.classLine,lineEnd:t.classLine,title:`Fragile interface compliance: ${t.className} implements ${t.interfaceName}`,reason:`Class "${t.className}" implements "${t.interfaceName}" with issues: ${s.join("; ")}.`,files:[t.classFile],suggestedFix:{strategy:"Fix the implementation to fully satisfy the interface contract.",steps:[...t.missingMembers.length>0?[`Implement missing members: ${t.missingMembers.join(", ")}.`]:[],...t.anycastMembers.length>0?[`Replace \`any\` types with proper types for: ${t.anycastMembers.join(", ")}.`]:[],"Enable strict type checking to catch these at compile time."]},impact:"Incomplete interface implementations create runtime surprises and defeat the purpose of type contracts.",tags:["code-quality","types","interface","semantic"],lspHints:[{tool:"lspGotoDefinition",symbolName:t.interfaceName,lineHint:t.classLine,file:t.classFile,expectedResult:"interface definition showing expected contract"}]})}return n}function ec(e){let n=[];for(let i of e)for(let t of i.unusedImports)n.push({severity:"low",category:"unused-import",file:i.file,lineStart:t.lineStart,lineEnd:t.lineStart,title:`Unused import: ${t.name}`,reason:`Imported symbol "${t.name}" is never referenced in this file (confirmed via semantic analysis, not just text matching).`,files:[i.file],suggestedFix:{strategy:"Remove the unused import statement.",steps:["Verify the import is not used for side effects (e.g. polyfills, CSS).","Remove the import statement.","If part of a multi-import, remove only the unused symbol."]},impact:"Unused imports slow down IDE performance, increase bundle size (if not tree-shaken), and add noise.",tags:["dead-code","imports","semantic"],lspHints:[{tool:"lspFindReferences",symbolName:t.name,lineHint:t.lineStart,file:i.file,expectedResult:"zero usage references confirms unused import"}]});return n}function tc(e,n){let i=[];for(let t of n){let s=e.program.getSourceFile($e.resolve(e.root,t.file));if(!s)continue;let r=o=>{if(Y.isClassDeclaration(o)&&o.name){if(o.heritageClauses&&o.heritageClauses.length>0){Y.forEachChild(o,r);return}if(!o.modifiers?.some(d=>d.kind===Y.SyntaxKind.ExportKeyword)){Y.forEachChild(o,r);return}let c=e.service.findReferences($e.resolve(e.root,t.file),o.name.getStart(s)),u=0;if(c)for(let d of c)for(let f of d.references)f.isDefinition||f.fileName!==$e.resolve(e.root,t.file)&&u++;if(u===0){let d=s.getLineAndCharacterOfPosition(o.getStart(s)).line+1;i.push({severity:"medium",category:"orphan-implementation",file:t.file,lineStart:d,lineEnd:d,title:`Orphan implementation: class ${o.name.text}`,reason:`Exported class "${o.name.text}" has no external references and does not implement any interface or extend any base class. It may be unreachable dead code.`,files:[t.file],suggestedFix:{strategy:"Verify the class is needed and wire it in, or remove it.",steps:["Check if the class is used via dynamic imports, reflection, or DI containers.","If unused, remove the class and its export.","If needed, wire it into the dependency graph via an interface or direct import."]},impact:"Orphan implementations waste maintenance effort and bloat the codebase.",tags:["dead-code","class","orphan","semantic"],lspHints:[{tool:"lspFindReferences",symbolName:o.name.text,lineHint:d,file:t.file,expectedResult:"zero external references confirms orphan"}]})}}Y.forEachChild(o,r)};Y.forEachChild(s,r)}return i}function nc(e,n=8){let i=[];for(let t of e)for(let[s,r]of t.referenceCountByExport)r.uniqueFiles>=n&&i.push({severity:r.uniqueFiles>12?"high":"medium",category:"shotgun-surgery",file:t.file,lineStart:r.lineStart,lineEnd:r.lineEnd,title:`Shotgun surgery risk: ${s} used in ${r.uniqueFiles} files`,reason:`Exported symbol "${s}" is referenced from ${r.uniqueFiles} unique files (threshold: ${n}). Any change to this symbol forces coordinated edits across all consumers.`,files:[t.file],suggestedFix:{strategy:"Reduce coupling by introducing a facade, adapter, or event-based decoupling.",steps:["Identify the consumers and group them by usage pattern.","Extract a stable interface that consumers depend on instead of the implementation.","Consider the Mediator or Facade pattern to reduce direct dependencies.","If the symbol is a utility, ensure it has a single, well-defined responsibility."]},impact:"High fan-out symbols are the #1 source of cascading changes during refactoring.",tags:["architecture","coupling","change-risk","semantic"],lspHints:[{tool:"lspFindReferences",symbolName:s,lineHint:r.lineStart,file:t.file,expectedResult:`${r.uniqueFiles}+ unique referencing files confirms shotgun surgery risk`}]});return i}function ic(e){let n=[];for(let i of e)for(let[t,s]of i.referenceCountByExport)s.uniqueFiles===1&&s.count>0&&n.push({severity:"low",category:"move-to-caller",file:i.file,lineStart:s.lineStart,lineEnd:s.lineEnd,title:`Single-consumer export: ${t} (used by 1 file)`,reason:`Exported symbol "${t}" is consumed by exactly 1 file. Consider moving it to the consumer or inlining it to reduce module surface.`,files:[i.file],suggestedFix:{strategy:"Move the symbol to its only consumer or inline it.",steps:["Verify no dynamic or reflection-based usage exists.","Move the function/class/constant to the consumer file.","Remove the export and the import from the consumer.","If the symbol is large, keep it but remove the export keyword."]},impact:"Single-consumer exports add unnecessary module surface and indirection.",tags:["dead-code","module-surface","refactoring","semantic"],lspHints:[{tool:"lspFindReferences",symbolName:t,lineHint:s.lineStart,file:i.file,expectedResult:"exactly 1 referencing file confirms single-consumer"}]});return n}function sc(e){let n=[];for(let i of e)for(let t of i.narrowableParams)n.push({severity:"low",category:"narrowable-type",file:i.file,lineStart:t.lineStart,lineEnd:t.lineEnd,title:`Narrowable param: ${t.functionName}(${t.paramName}: ${t.declaredType}) \u2192 ${t.narrowedType}`,reason:`Parameter "${t.paramName}" in "${t.functionName}" is declared as \`${t.declaredType}\` but all call sites pass \`${t.narrowedType}\`. The type can be safely narrowed.`,files:[i.file],suggestedFix:{strategy:"Narrow the parameter type to match actual usage.",steps:[`Change the parameter type from \`${t.declaredType}\` to \`${t.narrowedType}\`.`,"Verify no future callers need the broader type.","If the function is part of a public API, consider keeping the broad type with a narrower overload."]},impact:"Overly broad parameter types weaken type checking \u2014 narrowing catches bugs at compile time.",tags:["code-quality","types","refactoring","semantic"],lspHints:[{tool:"lspCallHierarchy",symbolName:t.functionName,lineHint:t.lineStart,file:i.file,expectedResult:`all incoming calls pass ${t.narrowedType}`}]});return n}function so(e,n,i={}){let t=[];return t.push(...Vl(e,n)),t.push(...Ql(n)),t.push(...Jl(e,n)),t.push(...Yl(n)),t.push(...Xl(n,i.overrideChainThreshold??3)),t.push(...Zl(n)),t.push(...ec(n)),t.push(...tc(e,n)),t.push(...nc(n,i.shotgunThreshold??8)),t.push(...ic(n)),t.push(...sc(n)),t.push(...Wl(n)),t}var ro=N(()=>{"use strict"});function rc(e){let n=e.topLevelEffects||[];if(n.length===0)return;let i={},t=0,s=null,r=-1;for(let o of n)i[o.kind]=(i[o.kind]||0)+1,t+=o.weight,o.weight>r&&(r=o.weight,s=o.kind);return{totalEffects:n.length,totalWeight:t,byKind:i,highestRisk:s}}function oc(e){let n=e.dependencyProfile.importedSymbols.filter(t=>!!t.resolvedModule),i=n.length===0?null:[...n.reduce((t,s)=>{let r=s.resolvedModule||s.sourceModule;return t.set(r,(t.get(r)||0)+1),t},new Map).entries()].sort((t,s)=>s[1]-t[1])[0]?.[0]||null;return{declaredExportCount:e.dependencyProfile.declaredExports.length,importedSymbolCount:e.dependencyProfile.importedSymbols.length,internalImportCount:n.length,externalImportCount:e.dependencyProfile.externalDependencies.length,reExportCount:e.dependencyProfile.reExports.length,dominantInternalDependency:i}}function ac(e){let n=e.file.replace(/\\/g,"/").toLowerCase(),i=[],t=(s,r,o)=>{i.push({role:s,confidence:r,reasons:o})};if(/(^|\/)(index|main|app|server|cli)\.[mc]?[jt]sx?$/.test(n)&&t("entrypoint","high",["path matches a conventional entrypoint filename"]),/(^|\/)(components|ui|pages|screens)\//.test(n)&&t("ui","high",["path indicates UI-facing code"]),/(^|\/)(routes|controllers|handlers|http|api)\//.test(n)&&t("transport","medium",["path indicates controller, handler, or API transport code"]),/(^|\/)(service|services|use-cases|usecases)\//.test(n)&&t("service","medium",["path indicates orchestration or service logic"]),/(^|\/)(repo|repos|repository|repositories|db|persistence)\//.test(n)&&t("persistence","high",["path indicates persistence or repository code"]),(e.topLevelEffects?.length||0)>0&&t("runtime-bootstrap","medium",["module has import-time side effects"]),e.dependencyProfile.declaredExports.length>=8&&e.dependencyProfile.importedSymbols.length<=2&&t("shared-utility","medium",["exports many symbols and imports little internal behavior"]),i.length!==0)return i.slice(0,3)}function lc(e){let n=(e.inputSources||[]).some(o=>o.hasValidation),i=!!e.testProfile?.setupCalls.some(o=>o.kind==="afterAll"||o.kind==="afterEach"),t=e.functions.reduce((o,a)=>o+a.returns,0),s=e.functions.reduce((o,a)=>o+a.awaits,0),r=(e.topLevelEffects?.length||0)>0;return{hasValidationChecks:n,hasCleanupHooks:i,exitPointCount:t,asyncBoundaryCount:s,hasTopLevelEffects:r}}function Pt(e,n={}){let{flowEnabled:i=!1}=n;return e.map(t=>({...t,effectProfile:t.effectProfile||rc(t),symbolUsageSummary:t.symbolUsageSummary||oc(t),boundaryRoleHints:t.boundaryRoleHints||ac(t)||[],cfgFlags:i?t.cfgFlags||lc(t):void 0}))}function cc(e){return["dependency-cycle","dependency-critical-path","architecture-sdp-violation","high-coupling","god-module-coupling","orphan-module","unreachable-module","cycle-cluster","broker-module","bridge-module","mega-folder"].includes(e)?"graph":["layer-violation","low-cohesion","feature-envy","import-side-effect-risk","package-boundary-chatter","startup-risk-hub","unvalidated-input-sink","input-passthrough-risk","missing-test-cleanup","fake-timer-no-restore","missing-mock-restoration"].includes(e)?"hybrid":e.startsWith("dependency-")?"graph":e.startsWith("test-")||e==="focused-test"||["hardcoded-secret","eval-usage","unsafe-html","sql-injection-risk","unsafe-regex","prototype-pollution-risk","path-traversal-risk","command-injection-risk","debug-log-leakage","sensitive-data-logging"].includes(e)||["over-abstraction","concrete-dependency","circular-type-dependency","unused-parameter","deep-override-chain","interface-compliance","unused-import","orphan-implementation","shotgun-surgery","move-to-caller","narrowable-type","semantic-dead-export"].includes(e)?"hybrid":"ast"}function dc(e){return e.confidence?e.confidence:e.severity==="critical"?"high":e.analysisLens==="graph"||e.analysisLens==="hybrid"?"medium":"low"}function uc(e,n){if(!n)return;if(e.flowTrace&&e.flowTrace.length>0)return e.flowTrace;let i=e.evidence?.propagationSteps;if(!Array.isArray(i))return;let t=i.map(s=>{if(typeof s!="string")return null;let r=s.match(/^(.*?):(\d+)(?:-(\d+))?$/);return r?{file:r[1],lineStart:Number(r[2]),lineEnd:Number(r[3]||r[2]),label:"propagation step"}:null}).filter(s=>s!==null);return t.length>0?t:void 0}function fc(e){let n=e.lspHints?.[0];return n?{summary:n.expectedResult,tools:["localSearchCode",n.tool]}:e.analysisLens==="graph"?{summary:"Confirm the dependency edge or hub behavior with localSearchCode and an LSP navigation step.",tools:["localSearchCode","lspGotoDefinition"]}:e.analysisLens==="hybrid"?{summary:"Validate both the structural location and the behavioral path before presenting the claim as fact.",tools:["localSearchCode","lspCallHierarchy"]}:{summary:"Confirm the code location and inspect the matched structure before proposing a refactor.",tools:["localSearchCode"]}}function It(e,n,i,t,s={}){let{flowEnabled:r=!1}=s,o=new Map(n.map(d=>[d.file,d])),a=new Set(i.map(d=>d.file)),l=new Set,c=new Set;if(t){for(let d of t.sccClusters)for(let f of d.files)l.add(f);for(let d of t.chokepoints)d.onCriticalPath&&c.add(d.file)}let u=new Map;for(let d of e)u.has(d.file)||u.set(d.file,new Set),u.get(d.file).add(d.category);return e.map(d=>{let f=d.analysisLens||cc(d.category),p=o.get(d.file),g=new Set(d.correlatedSignals||[]);a.has(d.file)&&g.add("hot-file"),l.has(d.file)&&g.add("cycle-context"),c.has(d.file)&&g.add("critical-path-context"),p?.effectProfile?.totalEffects&&g.add("top-level-effects");for(let S of u.get(d.file)||new Set)S!==d.category&&g.add(`paired:${S}`);let m={category:d.category,location:`${d.file}:${d.lineStart}-${d.lineEnd}`,...d.evidence||{}};return{...d,ruleId:d.ruleId||`${f}.${d.category}`,analysisLens:f,confidence:dc({...d,analysisLens:f}),evidence:m,correlatedSignals:[...g].slice(0,8),recommendedValidation:d.recommendedValidation||fc({...d,analysisLens:f}),flowTrace:uc({...d,evidence:m},r)}})}function De(e,n,i,t,s,r,o,a,l){return{kind:e,lens:n,title:i,summary:t,confidence:s,score:r,files:o,categories:a,evidence:l}}function Nt(e,n,i,t){let s=new Map;for(let h of e)s.has(h.file)||s.set(h.file,new Set),s.get(h.file).add(h.category);let r=[],o=[];if(t?.chokepoints.length){let h=t.chokepoints[0];r.push(De("structural-chokepoint","graph","Structural chokepoint",`${h.file} concentrates dependency pressure (${h.reasons.join(", ")}).`,h.articulation?"high":"medium",h.score,[h.file],["broker-module","bridge-module"],{score:h.score,reasons:h.reasons}))}if(t?.sccClusters.length){let h=t.sccClusters[0];r.push(De("cycle-cluster","graph","Cycle cluster",`${h.id} links ${h.nodeCount} files into a single strongly connected group.`,h.nodeCount>=5?"high":"medium",h.nodeCount*6+h.edgeCount,h.files,["dependency-cycle","cycle-cluster"],{clusterId:h.id,nodeCount:h.nodeCount,hubFiles:h.hubFiles}))}if(t?.packageGraphSummary.hotspots.length){let h=t.packageGraphSummary.hotspots[0];r.push(De("package-chatter","graph","Package boundary chatter",`${h.from} and ${h.to} exchange ${h.edges} cross-package dependency edge(s).`,h.edges>=8?"high":"medium",h.edges*4,[h.from,h.to],["package-boundary-chatter"],h))}let a=e.filter(h=>h.category==="mega-folder").sort((h,y)=>{let D=Number(h.evidence?.fileCount||0);return Number(y.evidence?.fileCount||0)-D});if(a.length>0){let h=a[0],y=h.evidence||{},D=typeof y.folderPath=="string"?y.folderPath:pc(h.file),b=Number(y.fileCount||h.files.length||0),k=Number(y.concentration||0);r.push(De("mega-folder-cluster","graph","Mega folder concentration",`${D} concentrates ${b} files (${(k*100).toFixed(1)}% of analyzed production files), which is a structural decomposition risk.`,k>=.5||b>=50?"high":"medium",Math.round(b*3+k*100),h.files.length>0?h.files:[h.file],["mega-folder"],{folderPath:D,fileCount:b,concentration:k}))}for(let h of n){let y=s.get(h.file)||new Set;y.has("low-cohesion")&&y.has("feature-envy")&&o.push(De("boundary-leak-shape","ast","Boundary leak shape",`${h.file} shows both low cohesion and feature envy, suggesting the module boundary is doing multiple jobs.`,"high",90,[h.file],["low-cohesion","feature-envy"],{file:h.file})),(h.effectProfile?.totalEffects||0)>0&&y.has("import-side-effect-risk")&&o.push(De("hidden-initialization","ast","Hidden initialization logic",`${h.file} performs import-time work that matches the reported side-effect risk.`,"medium",75,[h.file],["import-side-effect-risk"],{totalEffects:h.effectProfile?.totalEffects,highestRisk:h.effectProfile?.highestRisk})),y.has("duplicate-flow-structure")&&y.has("function-optimization")&&o.push(De("orchestration-duplication","ast","Repeated orchestration shape",`${h.file} combines repeated control-flow shape with complex functions, which usually means orchestration duplication.`,"medium",70,[h.file],["duplicate-flow-structure","function-optimization"],{file:h.file}))}let l=r.sort((h,y)=>y.score-h.score)[0]||null,c=o.sort((h,y)=>y.score-h.score)[0]||null,u=null;if(l&&c){let h=l.files.find(D=>c.files.includes(D)),y=h?"high":"medium";u=De("combined-interpretation","hybrid","Combined interpretation",h?`${h} is both a structural hotspot and a suspicious code-shape hotspot, so it should be investigated first.`:`${l.title} and ${c.title} both appear in this scan, so use a hybrid investigation instead of a single-lens conclusion.`,y,Math.round((l.score+c.score)/2),h?[h]:[...new Set([...l.files,...c.files])].slice(0,4),[...new Set([...l.categories,...c.categories])],{graphKind:l.kind,astKind:c.kind,sharedFile:h||null})}else if(l||c){let h=l||c;u=De("combined-interpretation",h.lens,"Combined interpretation",h.summary,h.confidence,h.score,h.files,h.categories,h.evidence)}let d=new Set(u?.files||[]),f=new Set(u?.categories||[]),g=(e.find(h=>d.has(h.file)||f.has(h.category))||e[0])?.recommendedValidation||null,m=new Set;l&&m.add(`Inspect ${l.files[0]} first and validate the graph claim with localSearchCode plus LSP navigation.`),c&&m.add(`Use file-inventory.json for ${c.files[0]} to explain why the code shape matches the finding.`),u?.confidence==="high"?m.add("Treat the aligned graph and AST signal as an architecture priority, not just a local cleanup task."):u&&m.add("Use a hybrid investigation before proposing a refactor because the signals do not fully align yet."),i.length>0&&m.add(`Cross-check the top hotspot ${i[0].file} with the strongest architecture finding before editing code.`);let S=r.find(h=>h.kind==="mega-folder-cluster");return S&&m.add(`Map the import graph of ${S.evidence.folderPath}, identify domain clusters, and restructure with an automated migration script that moves files and rewrites import paths atomically. Validate with tsc + lint + tests after each phase.`),{graphSignals:r.sort((h,y)=>y.score-h.score),astSignals:o.sort((h,y)=>y.score-h.score),combinedSignals:u?[u]:[],strongestGraphSignal:l,strongestAstSignal:c,combinedInterpretation:u,recommendedValidation:g,investigationPrompts:[...m]}}function pc(e){let n=e.replace(/\\/g,"/"),i=n.lastIndexOf("/");return i===-1?".":n.slice(0,i)}var is=N(()=>{"use strict"});import at from"node:fs";import Lt from"node:path";function ss(e,n,i,t,s,r,o={}){at.mkdirSync(e,{recursive:!0});let a=(C,A)=>{at.writeFileSync(Lt.join(e,C),JSON.stringify(A),"utf8")},l={summary:"summary.json",architecture:"architecture.json",codeQuality:"code-quality.json",deadCode:"dead-code.json",fileInventory:"file-inventory.json",findings:"findings.json"},c=Oe(t,s,r),u=n.graphAnalytics??Dt(t,s,r),d=Pt(n.fileInventory||[],{flowEnabled:!!i.flow}),f=It(n.optimizationFindings||[],d,c,u,{flowEnabled:!!i.flow}),p=f.filter(C=>oo.has(C.category)),g=f.filter(C=>ao.has(C.category)),m=f.filter(C=>lo.has(C.category)),S=f.filter(C=>co.has(C.category)),h=f.filter(C=>uo.has(C.category)),y=n.reportAnalysis??Nt(f,d,c,u),D=St(f,{fileInventory:d,hotFiles:c,reportAnalysis:y,includeTests:i.includeTests});if(a("architecture.json",{schemaVersion:Re,generatedAt:n.generatedAt,dependencyGraph:n.dependencyGraph,dependencyFindings:n.dependencyFindings,findings:p,findingsCount:p.length,severityBreakdown:be(p),categoryBreakdown:Ne(p),hotFiles:c,graphSignals:y.graphSignals,chokepoints:u.chokepoints,criticalHubCandidates:u.chokepoints.slice(0,10),sccClusters:i.graphAdvanced?u.sccClusters:[],packageGraphSummary:i.graphAdvanced?u.packageGraphSummary:null,packageHotspots:i.graphAdvanced?u.packageGraphSummary.hotspots:[]}),a("code-quality.json",{schemaVersion:Re,generatedAt:n.generatedAt,duplicateFlows:n.duplicateFlows,optimizationOpportunities:n.optimizationOpportunities,findings:g,findingsCount:g.length,severityBreakdown:be(g),categoryBreakdown:Ne(g)}),a("dead-code.json",{schemaVersion:Re,generatedAt:n.generatedAt,findings:m,findingsCount:m.length,severityBreakdown:be(m),categoryBreakdown:Ne(m)}),S.length>0&&(a("security.json",{schemaVersion:Re,generatedAt:n.generatedAt,findings:S,findingsCount:S.length,severityBreakdown:be(S),categoryBreakdown:Ne(S)}),l.security="security.json"),h.length>0&&(a("test-quality.json",{schemaVersion:Re,generatedAt:n.generatedAt,findings:h,findingsCount:h.length,severityBreakdown:be(h),categoryBreakdown:Ne(h)}),l.testQuality="test-quality.json"),a("file-inventory.json",{schemaVersion:Re,generatedAt:n.generatedAt,fileInventory:d,fileCount:d.length}),a("findings.json",{schemaVersion:Re,generatedAt:n.generatedAt,optimizationFindings:f,totalFindings:f.length}),i.graph){let C=Ot(t,s,r,o);at.writeFileSync(Lt.join(e,"graph.md"),C,"utf8"),l.graph="graph.md"}n.astTrees&&(at.writeFileSync(Lt.join(e,"ast-trees.txt"),xs(n.astTrees,n.generatedAt),"utf8"),l.astTrees="ast-trees.txt");let b={schemaVersion:Re,generatedAt:n.generatedAt,repoRoot:n.repoRoot,options:n.options,parser:n.parser,summary:n.summary,agentOutput:n.agentOutput,analysisSummary:{graphSignals:y.graphSignals,astSignals:y.astSignals,strongestGraphSignal:y.strongestGraphSignal,strongestAstSignal:y.strongestAstSignal,combinedSignals:y.combinedSignals,recommendedValidation:y.recommendedValidation},strongestGraphSignal:y.strongestGraphSignal,strongestAstSignal:y.strongestAstSignal,combinedSignals:y.combinedSignals,featureScores:bt(f,n.summary.totalFiles??0,i.features,{hotFiles:c}),qualityRating:D,recommendedValidation:y.recommendedValidation,investigationPrompts:y.investigationPrompts,parseErrors:n.parseErrors,outputFiles:l};a("summary.json",b);let k=vi({dir:e,report:n,outputFiles:l,architectureFindings:p,codeQualityFindings:g,deadCodeFindings:m,hotFiles:c,activeFeatures:i.features,scope:i.scope,root:i.root,scopeSymbols:i.scopeSymbols,semanticEnabled:i.semantic,securityFindings:S,testQualityFindings:h,reportAnalysis:y,fileInventory:d});return at.writeFileSync(Lt.join(e,"summary.md"),k,"utf8"),l.summaryMd="summary.md",a("summary.json",{...b,outputFiles:l}),l}function Ot(e,n,i,t={}){let s=[];s.push(`# Dependency Graph
|
|
156
|
+
`),s.push(`## Module Dependency Map
|
|
157
|
+
`),s.push("```mermaid"),s.push("graph LR");let r=new Set((n.criticalModules||[]).map(f=>f.file)),o=new Set;for(let f of n.cycles||[])for(let p of f.path)o.add(p);let a=f=>{let p=f.split("/");return p.length<=2?p.join("/"):`${p[0]}/\u2026/${p[p.length-1]}`},l=f=>f.replace(/[^a-zA-Z0-9]/g,"_"),c=new Set,u=new Set,d;if(t.focus)d=gc(t.focus,t.focusDepth??1,e),s.push(`%% Focus: ${t.focus} (depth=${t.focusDepth??1})`);else{let f=[...(n.outgoingTop||[]).slice(0,15),...(n.inboundTop||[]).slice(0,15),...(n.criticalModules||[]).slice(0,10)];d=new Set(f.map(p=>p.file));for(let p of(n.cycles||[]).slice(0,5))for(let g of p.path)d.add(g)}if(t.collapse!=null&&t.collapse>0){let f=mc(d,e,t.collapse);return hc(f,s)}for(let f of d){let p=l(f);if(c.has(p))continue;c.add(p);let g=a(f);o.has(f)?s.push(` ${p}["\u{1F534} ${g}"]`):r.has(f)?s.push(` ${p}["\u26A0\uFE0F ${g}"]`):s.push(` ${p}["${g}"]`)}for(let f of d){let p=e.outgoing.get(f)||new Set;for(let g of p){if(!d.has(g))continue;let m=`${l(f)}-->${l(g)}`;u.has(m)||(u.add(m),o.has(f)&&o.has(g)?s.push(` ${l(f)} -. cycle .-> ${l(g)}`):s.push(` ${l(f)} --> ${l(g)}`))}}if(s.push("```\n"),n.cycles?.length>0){s.push(`## Dependency Cycles
|
|
158
|
+
`),s.push("```mermaid"),s.push("graph LR");for(let[f,p]of n.cycles.slice(0,10).entries())for(let g=0;g<p.path.length-1;g++){let m=l(p.path[g]),S=l(p.path[g+1]);s.push(` ${m}["${a(p.path[g])}"] -. "cycle ${f+1}" .-> ${S}["${a(p.path[g+1])}"]`)}s.push("```\n")}if(n.criticalPaths?.length>0){s.push(`## Critical Dependency Chains
|
|
159
|
+
`),s.push("```mermaid"),s.push("graph LR");for(let f of n.criticalPaths.slice(0,8))for(let p=0;p<f.path.length-1;p++){let g=l(f.path[p]),m=l(f.path[p+1]);s.push(` ${g}["${a(f.path[p])}"] ==> ${m}["${a(f.path[p+1])}"]`)}s.push("```\n")}if(s.push(`## Summary
|
|
160
|
+
`),s.push("| Metric | Value |"),s.push("|--------|-------|"),s.push(`| Total modules | ${n.totalModules} |`),s.push(`| Total edges | ${n.totalEdges} |`),s.push(`| Root modules | ${n.rootsCount} |`),s.push(`| Leaf modules | ${n.leavesCount} |`),s.push(`| Cycles | ${n.cycles?.length||0} |`),s.push(`| Critical paths | ${n.criticalPaths?.length||0} |`),s.push(`| Test-only modules | ${n.testOnlyModules?.length||0} |`),s.push(`| Unresolved imports | ${n.unresolvedEdgeCount||0} |`),s.push(""),n.criticalModules?.length>0){s.push(`## Critical Modules (Hub Nodes)
|
|
161
|
+
`),s.push("| Module | Score | Risk | Inbound | Outbound |"),s.push("|--------|-------|------|---------|----------|");for(let f of n.criticalModules.slice(0,20))s.push(`| \`${f.file}\` | ${f.score} | ${f.riskBand||"-"} | ${f.inboundCount} | ${f.outboundCount} |`);s.push("")}if(n.testOnlyModules?.length>0){s.push(`## Test-Only Modules
|
|
162
|
+
`);for(let f of n.testOnlyModules.slice(0,20))s.push(`- \`${f.file}\``);s.push("")}return s.join(`
|
|
163
|
+
`)}function gc(e,n,i){let t=[...i.outgoing.keys()].find(o=>o===e||o.endsWith(`/${e}`));if(!t)return new Set;let s=new Set([t]),r=new Set([t]);for(let o=0;o<n;o++){let a=new Set;for(let l of r){for(let c of i.outgoing.get(l)||[])s.has(c)||(s.add(c),a.add(c));for(let c of i.incoming.get(l)||[])s.has(c)||(s.add(c),a.add(c))}if(r=a,r.size===0)break}return s}function mc(e,n,i){let t=a=>a.split("/").slice(0,i).join("/"),s=new Set,r=new Map;for(let a of e)s.add(t(a));for(let a of e){let l=t(a);for(let c of n.outgoing.get(a)||[]){let u=t(c);if(l===u)continue;s.add(u);let d=`${l}::${u}`;r.set(d,(r.get(d)||0)+1)}}let o=[];for(let[a,l]of r){let[c,u]=a.split("::");o.push({from:c,to:u,weight:l})}return{nodes:s,edges:o}}function hc(e,n){let i=t=>t.replace(/[^a-zA-Z0-9]/g,"_");for(let t of e.nodes)n.push(` ${i(t)}["${t}"]`);for(let t of e.edges){let s=t.weight>1?`|${t.weight}|`:"";n.push(` ${i(t.from)} -->${s} ${i(t.to)}`)}return n.push("```\n"),n.push(`> Collapsed to folder depth. ${e.nodes.size} folders, ${e.edges.length} edges.
|
|
164
|
+
`),n.join(`
|
|
165
|
+
`)}var Re,oo,ao,lo,co,uo,rs=N(()=>{"use strict";is();st();Gi();W();Ze();me();Re="1.1.0",oo=new Set(B.architecture),ao=new Set(B["code-quality"]),lo=new Set(B["dead-code"]),co=new Set(B.security),uo=new Set(B["test-quality"])});var po={};Wt(po,{EXIT_ERROR:()=>Ht,EXIT_FINDINGS:()=>_t,EXIT_SUCCESS:()=>jt,computeGateScore:()=>os,main:()=>fo});import Be from"node:fs";import J from"node:path";import*as Bt from"typescript";function yc(e,n){let i=xr(e,n);if(!i.length){let t=J.join(e,"package.json");if(Be.existsSync(t))try{let s=JSON.parse(Be.readFileSync(t,"utf8"));i=[{name:typeof s.name=="string"?s.name:J.basename(e),dir:e,folder:J.basename(e)}]}catch{console.error(`No packages found in ${n} and root package.json is unreadable`),process.exit(1)}else console.error(`No packages found in ${n} and no package.json in root`),process.exit(1)}return i}function Sc(e,n,i){let t=[...e.entries()].map(([o,a])=>{if(a.length<2)return null;let[l]=a,[c]=o.split("|"),u=l.name||l.kind||"<flow>",d=[...new Set(a.map(f=>f.file))];return{hash:c,signature:u,kind:l.kind,occurrences:a.length,filesCount:d.length,locations:a.slice(0,20)}}).filter(o=>o!==null).sort((o,a)=>a.occurrences-o.occurrences),s=[...n.entries()].map(([o,a])=>{if(a.length<=1)return null;let[,l]=o.split("|"),c=[...new Set(a.map(u=>u.file))];return{kind:l,occurrences:a.length,filesCount:c.length,locations:a.slice(0,20)}}).filter(o=>o!==null).sort((o,a)=>a.occurrences-o.occurrences),r=[];for(let o of t.slice(0,200))o.occurrences>=2&&r.push({type:"duplicate-function-body",message:`Identical function body for ${o.signature}`,file:o.locations[0]?.file,lineStart:o.locations[0]?.lineStart,lineEnd:o.locations[0]?.lineEnd,details:`Occurs ${o.occurrences} times in ${o.filesCount} files.`});for(let[o,a]of s.slice(0,100).entries())if(a.occurrences>=i&&r.push({type:"repeated-flow",message:`Repeated ${a.kind} control structure`,file:a.locations[0]?.file,lineStart:a.locations[0]?.lineStart,lineEnd:a.locations[0]?.lineEnd,details:`Structure appears ${a.occurrences} times across ${a.filesCount} file(s).`}),o>100)break;return{duplicateFunctions:t,redundantFlows:s,duplicateFlowHints:r}}function bc(e,n,i,t){if(!i.semantic)return[];if(!(!i.features||[...ft].some(r=>i.features.has(r))))return[];try{let r=$r(e,n,i.root),o=kr(r,i.root),a=[];for(let l of e){let c=J.resolve(i.root,l.file);try{a.push(Tr(o,c,l,i.includeTests))}catch{}}return so(o,a,{overrideChainThreshold:i.thresholds.overrideChainThreshold,shotgunThreshold:i.thresholds.shotgunThreshold})}catch(r){return t.push({file:"<semantic>",message:`Semantic analysis failed: ${String(r?.message||r)}`}),[]}}function xc(e,n,i){if(!n.scope)return e;let t=r=>{let o=J.resolve(n.root,r);return n.scope.some(a=>{let l=J.normalize(a),c=J.normalize(o);return c===l||c.startsWith(l+J.sep)})},s=e.filter(r=>t(r.file)||(r.files?.some(t)??!1));if(n.scopeSymbols&&n.scopeSymbols.size>0){let r=[],o=[];for(let[a,l]of n.scopeSymbols){let c=J.relative(n.root,a),u=i.find(d=>d.file===c);if(!u){for(let d of l)o.push(`${c}:${d}`);continue}for(let d of l){let f=u.functions.find(g=>g.name===d);if(f){r.push({file:c,lineStart:f.lineStart,lineEnd:f.lineEnd,name:d});continue}let p=u.dependencyProfile?.declaredExports?.find(g=>g.name===d&&g.lineStart!=null&&g.lineEnd!=null);p?r.push({file:c,lineStart:p.lineStart,lineEnd:p.lineEnd,name:d}):o.push(`${c}:${d}`)}}if(o.length>0&&console.warn(`Warning: symbol scope could not resolve: ${o.join(", ")}. Falling back to file-level scope for those entries.`),r.length>0){let a=(l,c,u,d)=>l<=d&&c>=u;s=s.filter(l=>r.some(c=>l.file===c.file&&a(l.lineStart,l.lineEnd,c.lineStart,c.lineEnd)))}}return s}function Ec(e,n,i,t,s,r,o,a){console.log(`AST analysis complete: ${e.totalFiles} files, ${e.totalFunctions} functions, ${e.totalFlows} flow nodes`),e.totalDependencyFiles!==e.totalFiles&&console.log(`Dependency scan analyzed ${e.totalDependencyFiles} files (including tests where present).`),console.log(`Duplicate function bodies: ${n.length}`);for(let l of n.slice(0,20))console.log(`- ${l.kind} "${l.signature}" occurs ${l.occurrences}x in ${l.filesCount} file(s)`);console.log(`
|
|
166
|
+
Repeated control-flow structures: ${i.length}`);for(let l of i.slice(0,20))console.log(`- ${l.kind} appears ${l.occurrences}x across ${l.filesCount} file(s)`);console.log(`
|
|
167
|
+
Dependency graph: ${t.totalModules} modules, ${t.totalEdges} import edges`),t.totalModules>0&&(console.log(`- Critical chains: ${t.criticalPaths.length} (showing top ${Math.min(o.deepLinkTopN,t.criticalPaths.length)})`),console.log(`- Root modules: ${t.rootsCount}, Leaf modules: ${t.leavesCount}`),console.log(`- Test-only modules: ${t.testOnlyModules.length}`),console.log(`- Cycles: ${t.cycles.length}`)),console.log(`
|
|
168
|
+
Agent Findings: ${s.length}`);for(let l of s.slice(0,20))console.log(`- [${l.severity.toUpperCase()}] ${l.title}`),console.log(` - ${l.reason}`),console.log(` - fix: ${l.suggestedFix.strategy}`);r.length>0&&(console.log(`
|
|
169
|
+
Parse errors: ${r.length}`),r.slice(0,10).forEach(l=>{console.log(`- ${l.file}: ${l.message}`)})),console.log(`
|
|
170
|
+
Parser engine used: ${a}`)}async function vc(e){let n;if(e)n=e;else{let{DEFAULT_OPTS:f}=await Promise.resolve().then(()=>(ht(),Qt)),p=xt({args:er(process.argv.slice(2))}),g=Ri(p.root,p.configFile);n=g?Ai(f,g,p):p}if(!n.json&&!e&&Us(),le.progress("startup","Options parsed",`root=${n.root}`),n.clearCache)return or(n.root),console.error("Cache cleared."),null;let i=new Date().toISOString().replace(/[:.]/g,"-"),t=n.out?.endsWith(".json")??!1,s=t?null:n.out||J.join(n.root,".octocode","scan",i),r=t?n.out??null:null,o=yc(n.root,n.packageRoot),a=n.parser,l=n.parser==="tree-sitter"||n.parser==="auto"?await Ar():{available:!1,error:null,parserTs:null,parserTsx:null},c=(n.parser==="tree-sitter"||n.parser==="auto")&&!!l?.available;n.parser==="tree-sitter"&&!l?.available&&(console.warn(`Tree-sitter requested but unavailable: ${l?.error||"missing parser modules"}`),console.warn("Falling back to TypeScript parser for duplicate detection."),a="typescript"),n.parser==="tree-sitter"&&l?.available&&(a="tree-sitter (primary) + typescript (dependencies)"),n.parser==="auto"&&l?.available&&(a="typescript (primary) + tree-sitter (node count)");let u={},d={};for(let f of o)try{let p=JSON.parse(Be.readFileSync(J.join(f.dir,"package.json"),"utf8"));Object.assign(u,p.dependencies||{}),Object.assign(d,p.devDependencies||{})}catch{}return le.progress("discovery",`Found ${o.length} package(s)`,o.map(f=>f.name).join(", ")),{options:n,packages:o,effectiveParser:a,useTreeSitter:c,summary:{totalPackages:o.length,totalFiles:0,totalNodes:0,totalFunctions:0,totalFlows:0,totalDependencyFiles:0,byPackage:{}},flowMap:new Map,controlMap:new Map,trees:[],fileSummaries:[],parseErrors:[],dependencyState:{files:new Set,outgoing:new Map,incoming:new Map,incomingFromTests:new Map,incomingFromProduction:new Map,externalCounts:new Map,unresolvedCounts:new Map,declaredExportsByFile:new Map,importedSymbolsByFile:new Map,reExportsByFile:new Map},packageFileStats:Object.fromEntries(o.map(f=>[f.name,{fileCount:0,nodeCount:0,functionCount:0,flowCount:0,kindCounts:{},functions:[],flows:[]}])),allPkgJsonDeps:u,allPkgJsonDevDeps:d,cacheHits:0,isLegacyMode:t,outputDir:s,outputPath:r,treeSitterAvailable:c,treeSitterError:l?.available?null:l?.error||null}}function wc(e){let{options:n,packages:i,useTreeSitter:t,summary:s,flowMap:r,controlMap:o,trees:a,fileSummaries:l,parseErrors:c,dependencyState:u,packageFileStats:d}=e;le.progress("cache-check",n.noCache?"Cache disabled":"Loading cache");let f=n.noCache?null:sr(n.root),p=cr(n.root);for(let g of i){let m=d[g.name];m||(m={fileCount:0,nodeCount:0,functionCount:0,flowCount:0,kindCounts:{},functions:[],flows:[]},d[g.name]=m);let S=Ki(g.dir,n),h=Ki(g.dir,{...n,includeTests:!0}),y=k=>n.scope!=null&&n.scope.some(C=>{let A=J.normalize(C),M=J.normalize(k);return M===A||M.startsWith(A+J.sep)}),D=n.scope?S.filter(k=>y(k)):S,b=new Set(D);for(let k of h){let C=br(k);if(C===null){c.push({file:J.relative(n.root,k),message:"Failed to read file"});continue}let A=J.extname(k),M=Bt.createSourceFile(k,C,Bt.ScriptTarget.ESNext,!0,Ss(A));try{let E=hr(M,k,g.name,n,u);if(!b.has(k))continue;let _=J.relative(n.root,k),K=Be.statSync(k),V={mtimeMs:K.mtimeMs,size:K.size};if(f&&ar(f,_,V)){let O=lr(f,_);if(O?.fileEntry){for(let[X,re]of O.flowMapEntries??[])for(let P of re)Se(r,X,P);for(let[X,re]of O.controlMapEntries??[])for(let P of re)Se(o,X,P);let j={...O.fileEntry,dependencyProfile:E};m.fileCount+=1,m.nodeCount+=j.nodeCount,m.functionCount+=j.functions.length,m.flowCount+=j.flows.length;for(let[X,re]of Object.entries(j.kindCounts))m.kindCounts[X]=(m.kindCounts[X]||0)+re;for(let X of j.functions)m.functions.push(X);O.treeEntry&&a.push(O.treeEntry),s.totalFiles+=1,s.totalNodes+=j.nodeCount,s.totalFunctions+=j.functions.length,s.totalFlows+=j.flows.length,l.push(j),Di(p,_,V,O),e.cacheHits++;continue}}let se=new Map,fe=new Map,H=t&&n.parser==="tree-sitter",te;if(H){let O=Qi(k,C,n,g.name,{flowMap:se,controlMap:fe});if(O){let j=J.relative(n.root,k);te={package:g.name,file:j,parseEngine:"tree-sitter",nodeCount:O.nodeCount,kindCounts:{},functions:O.functions,flows:O.flows,dependencyProfile:E},O.tree&&n.emitTree&&a.push({package:g.name,file:j,tree:O.tree}),m.fileCount+=1,m.nodeCount+=O.nodeCount,m.functionCount+=O.functions.length,m.flowCount+=O.flows.length;for(let X of O.functions)m.functions.push(X)}else{let j=ns(M,g.name,m,n,{flowMap:se,controlMap:fe},a,E);j.parserFallback="typescript (tree-sitter failed)",te=j}}else if(te=ns(M,g.name,m,n,{flowMap:se,controlMap:fe},a,E),t)try{let O=Qi(k,C,n,g.name,null);O&&(te.treeSitterNodeCount=O.nodeCount)}catch(O){te.treeSitterError=String(O?.message||O)}for(let[O,j]of se)for(let X of j)Se(r,O,X);for(let[O,j]of fe)for(let X of j)Se(o,O,X);let ye=n.emitTree?a.find(O=>O.file===_):void 0,Ee={fileEntry:te,flowMapEntries:[...se.entries()],controlMapEntries:[...fe.entries()],...ye&&{treeEntry:ye}};Di(p,_,V,Ee),s.totalFiles+=1,s.totalNodes+=te.nodeCount,s.totalFunctions+=te.functions.length,s.totalFlows+=te.flows.length,l.push(te)}catch(E){c.push({file:J.relative(n.root,k),message:String(E?.message||E)})}}s.byPackage[g.name]={files:m.fileCount,nodes:m.nodeCount,functions:m.functionCount,flows:m.flowCount,topKinds:Object.entries(m.kindCounts).sort((k,C)=>C[1]-k[1]).slice(0,8),rootPath:g.folder}}n.noCache||(dr(p),rr(n.root,p)),e.cacheHits>0&&!n.json&&console.error(`Cache: ${e.cacheHits} hits, ${l.length-e.cacheHits} misses`),s.totalDependencyFiles=u.files.size,le.progress("parse",`Parsed ${l.length} files`,`${e.cacheHits} cache hits`)}function Fc(e){le.progress("detect","Running detectors");let{options:n,effectiveParser:i,summary:t,flowMap:s,controlMap:r,trees:o,fileSummaries:a,parseErrors:l,dependencyState:c,allPkgJsonDeps:u,allPkgJsonDevDeps:d,isLegacyMode:f,outputDir:p,outputPath:g,treeSitterAvailable:m,treeSitterError:S}=e,{duplicateFunctions:h,redundantFlows:y,duplicateFlowHints:D}=Sc(s,r,n.thresholds.flowDupThreshold),b=new Map(a.map(P=>[P.file,eo(P,n)])),k=Bi(c,b,n);le.progress("graph","Computing graph analytics");let C=Dt(c,k,b),A=n.graphAdvanced?Fr(C,c,a):[];le.progress("semantic",n.semantic?"Running semantic analysis":"Skipping semantic (not requested)");let M=bc(a,c,n,l),_=go(h,y,a,k,c,n,u,d,b,M,s,A).allFindings;_=xc(_,n,a);let{findings:K,totalBeforeTruncation:V,droppedCategories:se}=ls(_,n),fe=cs(K),H=fe.findings,te=fe.byFile,ye=kc(_),Ee=Pt(a,{flowEnabled:!!n.flow}),O=Oe(c,k,b);if(H=It(H,Ee,O,C,{flowEnabled:!!n.flow}),n.affected){let P=Pi(n.root,n.affected,c);if(P.length>0){let oe=new Set(P);H=H.filter(ce=>oe.has(ce.file)),le.progress("detect",`--affected: ${P.length} files in scope, ${H.length} findings`)}}if(n.ignoreKnown){let{filtered:P,suppressedCount:oe}=Li(H,n.ignoreKnown,n.root);oe>0&&le.progress("detect",`--ignore-known: suppressed ${oe} known findings`),H=P}let j=Nt(H,Ee,O,C),X=Er(Ee,te),re={generatedAt:new Date().toISOString(),repoRoot:n.root,options:{...n,ignoreDirs:[...n.ignoreDirs]},parser:{requested:n.parser,effective:i,treeSitterAvailable:m,treeSitterError:S},summary:t,fileInventory:X,duplicateFlows:{duplicatedFunctions:h.slice(0,200),duplicatedControlFlow:y.slice(0,200),totalFunctionGroups:h.length,totalFlowGroups:y.length},dependencyGraph:k,dependencyFindings:H.filter(P=>P.category?.startsWith("dependency")),agentOutput:{totalFindings:H.length,totalBeforeTruncation:V,droppedCategories:se,findingStats:ye,analysisSummary:{strongestGraphSignal:j.strongestGraphSignal,strongestAstSignal:j.strongestAstSignal,combinedSignals:j.combinedSignals,recommendedValidation:j.recommendedValidation},highPriority:H.filter(P=>P.severity==="high"||P.severity==="critical").length,mediumPriority:H.filter(P=>P.severity==="medium").length,lowPriority:H.filter(P=>P.severity==="low"||P.severity==="info").length,topRecommendations:Ei(H,20,n.maxRecsPerCategory).map(P=>({id:P.id,file:P.file,severity:P.severity,category:P.category,title:P.title,reason:P.reason,suggestedFix:P.suggestedFix})),filesWithIssues:[...te.entries()].map(([P,oe])=>({file:P,issueCount:oe.length,issueIds:oe}))},optimizationOpportunities:D,optimizationFindings:H,parseErrors:l,astTrees:void 0,graphAnalytics:C,reportAnalysis:j};if(n.emitTree&&(re.astTrees=o),le.progress("report",`${H.length} findings generated`),n.saveBaseline){let P=Ni(n.root,H);n.json||console.error(`Baseline saved: ${J.relative(n.root,P)} (${H.length} findings)`)}if(n.reporter!=="default"){let P=ji(H,n.reporter,n.root);process.stdout.write(P+`
|
|
171
|
+
`)}else n.json?console.log(JSON.stringify(re)):Ec(t,h,y,k,H,l,n,re.parser.effective);if(f&&g){if(Be.mkdirSync(J.dirname(g),{recursive:!0}),Be.writeFileSync(g,JSON.stringify(re),"utf8"),n.json||console.log(`
|
|
172
|
+
Full report written to ${J.relative(n.root,g)}`),n.graph){let P={focus:n.focus,focusDepth:n.focusDepth,collapse:n.collapse},oe=Ot(c,k,b,P),ce=g.replace(/\.json$/,"-graph.md");Be.writeFileSync(ce,oe,"utf8"),n.json||console.log(`Dependency graph written to ${J.relative(n.root,ce)}`)}}else if(p){le.progress("write",`Writing report to ${J.relative(n.root,p)}`);let P={focus:n.focus,focusDepth:n.focusDepth,collapse:n.collapse},oe=ss(p,re,n,c,k,b,P);if(!n.json){let ce=J.relative(n.root,p);console.log(`
|
|
173
|
+
Report written to ${ce}/`);for(let[Ae,ze]of Object.entries(oe))console.log(` ${Ae}: ${ze}`)}}if(le.progress("done","Scan complete",`${H.length} findings`),n.atLeast!=null){let P=t.totalFiles??1,oe=os(H.length,P);if(oe<n.atLeast)return console.error(`Gate score ${oe} is below --at-least threshold ${n.atLeast}`),-1}return H.length}function os(e,n){let i=e/Math.max(n,1);return Math.round(100/(1+i/10))}async function fo(e){let n=await vc(e);if(!n)return jt;wc(n);let i=Fc(n);return i<0||i>0?_t:jt}function kc(e){let n=s=>{let r={critical:0,high:0,medium:0,low:0,info:0};for(let o of s)r[o.severity]=(r[o.severity]||0)+1;return r},i={totalFindings:e.length,severityBreakdown:n(e)},t=Object.fromEntries(Object.entries(B).map(([s,r])=>{let o=new Set(r),a=e.filter(l=>o.has(l.category));return[s,{totalFindings:a.length,severityBreakdown:n(a)}]}));return{overall:i,pillars:t}}var jt,_t,Ht,as=N(()=>{"use strict";ur();$i();Mi();rt();Fi();Ii();Oi();_i();Hi();zi();vr();Gi();Dr();Mr();to();io();W();Ze();ro();mo();is();st();rs();me();jt=0,_t=1,Ht=2;no(import.meta.url)&&fo().then(e=>{process.exitCode=e}).catch(e=>{e instanceof Le?(console.error(e.message),process.exitCode=Ht):(console.error(e),process.exitCode=Ht)})});function lt(e,n){return n.some(i=>e.has(i))}function Cc(e){return e?{architecture:lt(e,B.architecture),codeQuality:lt(e,B["code-quality"]),deadCode:lt(e,B["dead-code"]),security:lt(e,B.security),testQuality:lt(e,B["test-quality"])}:{architecture:!0,codeQuality:!0,deadCode:!0,security:!0,testQuality:!0}}function Tc(e,n,i,t,s,r,o,a,l){let c=Oe(n,e,s),u=[()=>tn(e),()=>nn(e,n),()=>sn(e,n,t.thresholds.criticalComplexityThreshold),()=>rn(e,n),()=>Tn(n,r,o),()=>$n(n,r),()=>cn(n,t.thresholds.sdpMinDelta,t.thresholds.sdpMaxSourceInstability),()=>dn(n,t.thresholds.couplingThreshold),()=>un(n,t.thresholds.fanInThreshold,t.thresholds.fanOutThreshold),()=>on(n),()=>an(n),()=>Dn(n.externalCounts,a,l),()=>Rn(n),()=>En(n,t.thresholds.barrelSymbolThreshold),()=>mn(i),()=>yn(n),()=>pn(n),()=>bn(n),()=>Sn(n,c,s),()=>vn(i,n,e,c),()=>wn(n),()=>Fn(n),()=>kn(n)];return t.thresholds.layerOrder.length>=2&&u.push(()=>fn(n,t.thresholds.layerOrder)),u}function $c(e,n,i,t,s,r){return[()=>An(e),()=>Mn(n,t.thresholds.flowDupThreshold),()=>Pn(i,t.thresholds.criticalComplexityThreshold),()=>hn(i,t.thresholds.godFunctionStatements,t.thresholds.godFunctionMiThreshold),()=>Nn(i,t.thresholds.cognitiveComplexityThreshold),()=>Ln(i,t.thresholds.parameterThreshold),()=>On(i),()=>jn(i),()=>_n(i,t.thresholds.anyThreshold),()=>Hn(i,t.thresholds.halsteadEffortThreshold),()=>Bn(i,t.thresholds.maintainabilityIndexThreshold),()=>zn(i),()=>Kn(i),()=>Un(i),()=>qn(i),()=>Gn(i),()=>Wn(i),()=>Vn(i),()=>Qn(i),()=>Yn(i),()=>Jn(s,t.thresholds.similarityThreshold),()=>Xn(i,t.thresholds.deepNestingThreshold),()=>Zn(i,t.thresholds.multipleReturnThreshold),()=>ei(i),()=>ti(i,t.thresholds.magicStringMinOccurrences),()=>ni(i,t.thresholds.booleanParamThreshold),()=>ii(i),()=>si(i,r),()=>ri(i,s,r),...r?[()=>gn(i,r,t.thresholds.godModuleStatements,t.thresholds.godModuleExports)]:[]]}function Dc(e){return[()=>oi(e),()=>ai(e),()=>li(e),()=>ci(e),()=>di(e),()=>fi(e),()=>pi(e),()=>ui(e),()=>gi(e),()=>mi(e),()=>hi(e),()=>yi(e)]}function Rc(e,n){return[()=>Ms(e),()=>Ps(e),()=>Is(e,n.thresholds.mockThreshold),()=>Ns(e),()=>Ls(e),()=>Os(e),()=>js(e),()=>_s(e)]}function go(e,n,i,t,s,r,o={},a={},l=new Map,c=[],u=new Map,d=[]){let f=[],p=M=>{r.features&&!r.features.has(M.category)||f.push(M)},{production:g,test:m}=Cn(s),S=Cc(r.features),h=[...S.architecture||S.deadCode?Tc(t,s,i,r,l,g,m,o,a):[],...S.codeQuality?$c(e,n,i,r,u,s):[],...S.security?Dc(i):[],...S.testQuality?Rc(i,r):[]];for(let M of h)for(let E of M())p(E);for(let M of c)p(M);for(let M of d)p(M);let y=f.sort((M,E)=>{let _=Pe[E.severity]-Pe[M.severity];return _!==0?_:M.category<E.category?-1:M.category>E.category?1:0}),{findings:D,totalBeforeTruncation:b,droppedCategories:k}=ls(y,r),{findings:C,byFile:A}=cs(D);return{allFindings:y,findings:C,byFile:A,totalBeforeTruncation:b,droppedCategories:k}}function ls(e,n){let i=e.length,t=new Set(e.map(l=>l.category)),s=n.findingsLimit,r=!Number.isFinite(s)||s==null?e:n.noDiversify?e.slice(0,s):xi(e,s),o=new Set(r.map(l=>l.category)),a=[...t].filter(l=>!o.has(l));return{findings:r,totalBeforeTruncation:i,droppedCategories:a}}function cs(e){let n=[],i=new Map;for(let[t,s]of e.entries()){let r=`AST-ISSUE-${String(t+1).padStart(4,"0")}`,o={id:r,...s};n.push(o),o.file&&(i.has(o.file)||i.set(o.file,[]),i.get(o.file).push(r))}return{findings:n,byFile:i}}async function Wf(e={}){let{DEFAULT_OPTS:n}=await Promise.resolve().then(()=>(ht(),Qt)),i={...n,...e,thresholds:{...n.thresholds,...e.thresholds}},{createOptions:t}=await Promise.resolve().then(()=>(rt(),qs)),s=t({args:i}),{main:r}=await Promise.resolve().then(()=>(as(),po));return{exitCode:await r(s)}}var mo=N(()=>{Ze();Si();Hs();st();me();Fi();rt();$i();as();Ii();Oi();_i();Mi();zi();rs();st()});mo();export{oo as ARCHITECTURE_CATEGORIES,ao as CODE_QUALITY_CATEGORIES,lo as DEAD_CODE_CATEGORIES,Ht as EXIT_ERROR,_t as EXIT_FINDINGS,jt as EXIT_SUCCESS,tr as HELP_TEXT,Le as OptionsError,Re as REPORT_SCHEMA_VERSION,co as SECURITY_CATEGORIES,uo as TEST_QUALITY_CATEGORIES,ls as applyFindingsLimit,cs as assignFindingIds,Bi as buildDependencySummary,go as buildIssueCatalog,le as bus,Ne as categoryBreakdown,Bs as collectTagCloud,Sr as computeDependencyCriticalPaths,yr as computeDependencyCycles,bt as computeFeatureScores,os as computeGateScore,Io as computeHealthScore,St as computeQualityAspectRatings,xt as createOptions,Ei as diverseTopRecommendations,xi as diversifyFindings,Li as filterKnownFindings,zs as formatFileSize,ji as formatFindings,Ot as generateMermaidGraph,vi as generateSummaryMd,Ri as loadConfigFile,Ai as mergeConfigIntoDefaults,Pi as resolveAffectedFiles,Cc as resolveEnabledPillars,Ni as saveBaseline,Wf as scan,be as severityBreakdown,ss as writeMultiFileReport};
|