octocode-cli 1.2.8 → 1.2.10
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 +45 -38
- package/out/octocode-cli.js +73 -11763
- package/package.json +35 -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 +413 -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
|
@@ -5,9 +5,11 @@ import { isTestFile } from '../common/utils.js';
|
|
|
5
5
|
|
|
6
6
|
import type { FindingDraft } from './shared.js';
|
|
7
7
|
import type {
|
|
8
|
+
DependencyState,
|
|
8
9
|
DuplicateGroup,
|
|
9
10
|
FileEntry,
|
|
10
11
|
Finding,
|
|
12
|
+
FlowMapEntry,
|
|
11
13
|
RedundantFlowGroup,
|
|
12
14
|
} from '../types/index.js';
|
|
13
15
|
|
|
@@ -964,3 +966,343 @@ export function detectMessageChains(fileSummaries: FileEntry[]): FindingDraft[]
|
|
|
964
966
|
}
|
|
965
967
|
return findings;
|
|
966
968
|
}
|
|
969
|
+
|
|
970
|
+
export function detectDeepNesting(
|
|
971
|
+
fileSummaries: FileEntry[],
|
|
972
|
+
threshold: number
|
|
973
|
+
): FindingDraft[] {
|
|
974
|
+
const findings: FindingDraft[] = [];
|
|
975
|
+
for (const entry of fileSummaries) {
|
|
976
|
+
if (isTestFile(entry.file)) continue;
|
|
977
|
+
for (const fn of entry.functions) {
|
|
978
|
+
const maxDepth = Math.max(fn.maxBranchDepth, fn.maxLoopDepth);
|
|
979
|
+
if (maxDepth < threshold) continue;
|
|
980
|
+
if (!canAddFinding(findings)) return findings;
|
|
981
|
+
const severity: Finding['severity'] = maxDepth >= threshold + 3 ? 'high' : maxDepth >= threshold + 1 ? 'medium' : 'low';
|
|
982
|
+
findings.push({
|
|
983
|
+
severity,
|
|
984
|
+
category: 'deep-nesting',
|
|
985
|
+
file: entry.file,
|
|
986
|
+
lineStart: fn.lineStart,
|
|
987
|
+
lineEnd: fn.lineEnd,
|
|
988
|
+
title: `Deep nesting ${maxDepth} levels in ${fn.name || '<anon>'}`,
|
|
989
|
+
reason: `Function has ${maxDepth}-level nesting (branch=${fn.maxBranchDepth}, loop=${fn.maxLoopDepth}), exceeding the ${threshold}-level threshold. Each nesting level multiplies the reader's cognitive load and increases the likelihood of logic errors.`,
|
|
990
|
+
files: [entry.file],
|
|
991
|
+
suggestedFix: {
|
|
992
|
+
strategy: 'Flatten nesting with guard clauses, early returns, or extraction.',
|
|
993
|
+
steps: [
|
|
994
|
+
'Convert nested if-blocks to guard clauses with early returns.',
|
|
995
|
+
'Extract deeply nested logic into named helper functions.',
|
|
996
|
+
'Replace nested loops with array methods (map/filter/reduce).',
|
|
997
|
+
],
|
|
998
|
+
},
|
|
999
|
+
impact: 'Deeply nested code is hard to read, test, and modify. Each nesting level compounds the number of control-flow paths.',
|
|
1000
|
+
tags: ['nesting', 'readability', 'complexity'],
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
return findings;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
export function detectMultipleReturnPaths(
|
|
1008
|
+
fileSummaries: FileEntry[],
|
|
1009
|
+
threshold: number
|
|
1010
|
+
): FindingDraft[] {
|
|
1011
|
+
const findings: FindingDraft[] = [];
|
|
1012
|
+
for (const entry of fileSummaries) {
|
|
1013
|
+
if (isTestFile(entry.file)) continue;
|
|
1014
|
+
for (const fn of entry.functions) {
|
|
1015
|
+
if (fn.returns < threshold) continue;
|
|
1016
|
+
if (!canAddFinding(findings)) return findings;
|
|
1017
|
+
const severity: Finding['severity'] = fn.returns >= threshold + 4 ? 'high' : fn.returns >= threshold + 2 ? 'medium' : 'low';
|
|
1018
|
+
findings.push({
|
|
1019
|
+
severity,
|
|
1020
|
+
category: 'multiple-return-paths',
|
|
1021
|
+
file: entry.file,
|
|
1022
|
+
lineStart: fn.lineStart,
|
|
1023
|
+
lineEnd: fn.lineEnd,
|
|
1024
|
+
title: `${fn.returns} return paths in ${fn.name || '<anon>'}`,
|
|
1025
|
+
reason: `Function has ${fn.returns} return/throw points — the reader must track every exit path to understand the function's behavior. This exceeds the ${threshold} threshold.`,
|
|
1026
|
+
files: [entry.file],
|
|
1027
|
+
suggestedFix: {
|
|
1028
|
+
strategy: 'Consolidate return points to reduce exit-path tracking.',
|
|
1029
|
+
steps: [
|
|
1030
|
+
'Replace scattered returns with a single result variable assigned conditionally.',
|
|
1031
|
+
'Use early guard clauses for error cases only.',
|
|
1032
|
+
'Consider splitting into smaller functions with clear single-responsibility.',
|
|
1033
|
+
],
|
|
1034
|
+
},
|
|
1035
|
+
impact: 'Many return paths make it harder to reason about what a function returns and to add post-processing.',
|
|
1036
|
+
tags: ['returns', 'readability', 'flow'],
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
return findings;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
export function detectCatchRethrow(fileSummaries: FileEntry[]): FindingDraft[] {
|
|
1044
|
+
const findings: FindingDraft[] = [];
|
|
1045
|
+
for (const entry of fileSummaries) {
|
|
1046
|
+
if (isTestFile(entry.file)) continue;
|
|
1047
|
+
if (!entry.catchRethrows || entry.catchRethrows.length === 0) continue;
|
|
1048
|
+
for (const loc of entry.catchRethrows) {
|
|
1049
|
+
if (!canAddFinding(findings)) return findings;
|
|
1050
|
+
findings.push({
|
|
1051
|
+
severity: 'low',
|
|
1052
|
+
category: 'catch-rethrow',
|
|
1053
|
+
file: entry.file,
|
|
1054
|
+
lineStart: loc.lineStart,
|
|
1055
|
+
lineEnd: loc.lineEnd,
|
|
1056
|
+
title: 'Catch-rethrow without transformation',
|
|
1057
|
+
reason: 'A catch block that only re-throws the caught error is a no-op — it adds indentation and obscures the stack trace without adding value.',
|
|
1058
|
+
files: [entry.file],
|
|
1059
|
+
suggestedFix: {
|
|
1060
|
+
strategy: 'Remove the try-catch or add meaningful error handling.',
|
|
1061
|
+
steps: [
|
|
1062
|
+
'If no transformation is needed, remove the try-catch entirely.',
|
|
1063
|
+
'If logging is intended, add a log statement before re-throwing.',
|
|
1064
|
+
'If wrapping, throw a new error with the original as cause.',
|
|
1065
|
+
],
|
|
1066
|
+
},
|
|
1067
|
+
impact: 'Pointless catch blocks add noise and can accidentally swallow stack-trace context.',
|
|
1068
|
+
tags: ['error-handling', 'noise', 'cleanup'],
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
return findings;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
export function detectMagicStrings(
|
|
1076
|
+
fileSummaries: FileEntry[],
|
|
1077
|
+
minOccurrences: number
|
|
1078
|
+
): FindingDraft[] {
|
|
1079
|
+
const findings: FindingDraft[] = [];
|
|
1080
|
+
const globalCounts = new Map<string, Array<{ file: string; lineStart: number; lineEnd: number }>>();
|
|
1081
|
+
|
|
1082
|
+
for (const entry of fileSummaries) {
|
|
1083
|
+
if (isTestFile(entry.file)) continue;
|
|
1084
|
+
if (!entry.magicStrings) continue;
|
|
1085
|
+
for (const ms of entry.magicStrings) {
|
|
1086
|
+
const list = globalCounts.get(ms.value) || [];
|
|
1087
|
+
list.push({ file: ms.file, lineStart: ms.lineStart, lineEnd: ms.lineEnd });
|
|
1088
|
+
globalCounts.set(ms.value, list);
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
for (const [value, locs] of globalCounts) {
|
|
1093
|
+
if (locs.length < minOccurrences) continue;
|
|
1094
|
+
if (!canAddFinding(findings)) return findings;
|
|
1095
|
+
const uniqueFiles = [...new Set(locs.map(l => l.file))];
|
|
1096
|
+
const severity: Finding['severity'] = locs.length >= 8 ? 'high' : locs.length >= 5 ? 'medium' : 'low';
|
|
1097
|
+
findings.push({
|
|
1098
|
+
severity,
|
|
1099
|
+
category: 'magic-string',
|
|
1100
|
+
file: locs[0].file,
|
|
1101
|
+
lineStart: locs[0].lineStart,
|
|
1102
|
+
lineEnd: locs[0].lineEnd,
|
|
1103
|
+
title: `Magic string "${value.length > 30 ? value.slice(0, 27) + '...' : value}" appears ${locs.length} times`,
|
|
1104
|
+
reason: `The string literal "${value}" is used in ${locs.length} comparisons across ${uniqueFiles.length} file(s). If the value changes, every occurrence must be updated — a classic source of silent bugs.`,
|
|
1105
|
+
files: uniqueFiles,
|
|
1106
|
+
suggestedFix: {
|
|
1107
|
+
strategy: 'Extract to a named constant or enum.',
|
|
1108
|
+
steps: [
|
|
1109
|
+
`Create a const (e.g. const ${value.toUpperCase().replace(/[^A-Z0-9]/g, '_')} = '${value}').`,
|
|
1110
|
+
'Replace all usages with the constant reference.',
|
|
1111
|
+
'Consider an enum if there are multiple related string values.',
|
|
1112
|
+
],
|
|
1113
|
+
},
|
|
1114
|
+
impact: 'Magic strings scatter domain knowledge across the codebase and are invisible to refactoring tools.',
|
|
1115
|
+
tags: ['magic-value', 'maintainability', 'duplication'],
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
return findings;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
export function detectBooleanParameterCluster(
|
|
1122
|
+
fileSummaries: FileEntry[],
|
|
1123
|
+
threshold: number
|
|
1124
|
+
): FindingDraft[] {
|
|
1125
|
+
const findings: FindingDraft[] = [];
|
|
1126
|
+
for (const entry of fileSummaries) {
|
|
1127
|
+
if (isTestFile(entry.file)) continue;
|
|
1128
|
+
if (!entry.booleanParamClusters) continue;
|
|
1129
|
+
for (const cluster of entry.booleanParamClusters) {
|
|
1130
|
+
if (cluster.booleanCount < threshold) continue;
|
|
1131
|
+
if (!canAddFinding(findings)) return findings;
|
|
1132
|
+
findings.push({
|
|
1133
|
+
severity: 'medium',
|
|
1134
|
+
category: 'boolean-parameter-cluster',
|
|
1135
|
+
file: entry.file,
|
|
1136
|
+
lineStart: cluster.lineStart,
|
|
1137
|
+
lineEnd: cluster.lineEnd,
|
|
1138
|
+
title: `${cluster.booleanCount} boolean params in ${cluster.name || '<anon>'}`,
|
|
1139
|
+
reason: `Function has ${cluster.booleanCount} boolean parameters out of ${cluster.totalParams} total. Boolean flags are opaque at call sites (e.g. doThing(true, false, true)) and each flag doubles the function's behavior space.`,
|
|
1140
|
+
files: [entry.file],
|
|
1141
|
+
suggestedFix: {
|
|
1142
|
+
strategy: 'Replace boolean clusters with an options object or separate functions.',
|
|
1143
|
+
steps: [
|
|
1144
|
+
'Create an options/config object type with named fields.',
|
|
1145
|
+
'Replace boolean parameters with the options object.',
|
|
1146
|
+
'Consider splitting into distinct functions for each behavior variant.',
|
|
1147
|
+
],
|
|
1148
|
+
},
|
|
1149
|
+
impact: 'Boolean parameter clusters make call sites unreadable and the function hard to test — 2^N behavior combinations.',
|
|
1150
|
+
tags: ['api-design', 'readability', 'parameters'],
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
return findings;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
export function detectPromiseAllUnhandled(fileSummaries: FileEntry[]): FindingDraft[] {
|
|
1158
|
+
const findings: FindingDraft[] = [];
|
|
1159
|
+
for (const entry of fileSummaries) {
|
|
1160
|
+
if (isTestFile(entry.file)) continue;
|
|
1161
|
+
if (!entry.promiseAllUnhandled) continue;
|
|
1162
|
+
for (const loc of entry.promiseAllUnhandled) {
|
|
1163
|
+
if (!canAddFinding(findings)) return findings;
|
|
1164
|
+
findings.push({
|
|
1165
|
+
severity: 'medium',
|
|
1166
|
+
category: 'promise-all-unhandled',
|
|
1167
|
+
file: entry.file,
|
|
1168
|
+
lineStart: loc.lineStart,
|
|
1169
|
+
lineEnd: loc.lineEnd,
|
|
1170
|
+
title: `${loc.kind} without error handling`,
|
|
1171
|
+
reason: `${loc.kind} is called without a surrounding try-catch or .catch() chain. If any of the composed promises reject, the rejection will propagate unhandled.`,
|
|
1172
|
+
files: [entry.file],
|
|
1173
|
+
suggestedFix: {
|
|
1174
|
+
strategy: 'Wrap in try-catch or add .catch() to the promise chain.',
|
|
1175
|
+
steps: [
|
|
1176
|
+
'Add a try-catch around the await expression.',
|
|
1177
|
+
'Or chain a .catch() handler onto the Promise combinator.',
|
|
1178
|
+
'Consider Promise.allSettled if partial failure is acceptable.',
|
|
1179
|
+
],
|
|
1180
|
+
},
|
|
1181
|
+
impact: 'Unhandled rejections from promise combinators crash Node.js processes and cause silent failures in browsers.',
|
|
1182
|
+
tags: ['error-handling', 'async', 'reliability'],
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
return findings;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
export function detectExportSurfaceDensity(
|
|
1190
|
+
fileSummaries: FileEntry[],
|
|
1191
|
+
dependencyState?: DependencyState
|
|
1192
|
+
): FindingDraft[] {
|
|
1193
|
+
const findings: FindingDraft[] = [];
|
|
1194
|
+
if (!dependencyState) return findings;
|
|
1195
|
+
|
|
1196
|
+
for (const entry of fileSummaries) {
|
|
1197
|
+
if (isTestFile(entry.file)) continue;
|
|
1198
|
+
const depProfile = entry.dependencyProfile;
|
|
1199
|
+
if (!depProfile) continue;
|
|
1200
|
+
const totalStatements = entry.functions.reduce((s, f) => s + f.statementCount, 0)
|
|
1201
|
+
+ entry.flows.length;
|
|
1202
|
+
if (totalStatements < 20) continue;
|
|
1203
|
+
const exportCount = depProfile.declaredExports?.length || 0;
|
|
1204
|
+
if (exportCount === 0) continue;
|
|
1205
|
+
const ratio = exportCount / totalStatements;
|
|
1206
|
+
if (ratio < 0.5) continue;
|
|
1207
|
+
if (!canAddFinding(findings)) return findings;
|
|
1208
|
+
const severity: Finding['severity'] = ratio >= 0.8 ? 'high' : ratio >= 0.6 ? 'medium' : 'low';
|
|
1209
|
+
findings.push({
|
|
1210
|
+
severity,
|
|
1211
|
+
category: 'export-surface-density',
|
|
1212
|
+
file: entry.file,
|
|
1213
|
+
lineStart: 1,
|
|
1214
|
+
lineEnd: 1,
|
|
1215
|
+
title: `${Math.round(ratio * 100)}% export density (${exportCount} exports / ~${totalStatements} statements)`,
|
|
1216
|
+
reason: `This module exports ${exportCount} symbols from ~${totalStatements} total statements — a ${Math.round(ratio * 100)}% export surface. High export density means nearly everything is public API, increasing coupling and reducing the ability to refactor internals.`,
|
|
1217
|
+
files: [entry.file],
|
|
1218
|
+
suggestedFix: {
|
|
1219
|
+
strategy: 'Reduce the public API by making non-essential symbols internal.',
|
|
1220
|
+
steps: [
|
|
1221
|
+
'Audit each export — does it need to be consumed externally?',
|
|
1222
|
+
'Convert unnecessary exports to module-private functions.',
|
|
1223
|
+
'Consider splitting into a public facade and private implementation module.',
|
|
1224
|
+
],
|
|
1225
|
+
},
|
|
1226
|
+
impact: 'High export density couples consumers to internal implementation, making any change a potential breaking change.',
|
|
1227
|
+
tags: ['encapsulation', 'api-surface', 'coupling'],
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
return findings;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
export function detectChangeRisk(
|
|
1234
|
+
fileSummaries: FileEntry[],
|
|
1235
|
+
_flowMap: Map<string, FlowMapEntry[]>,
|
|
1236
|
+
_dependencyState?: DependencyState
|
|
1237
|
+
): FindingDraft[] {
|
|
1238
|
+
const findings: FindingDraft[] = [];
|
|
1239
|
+
|
|
1240
|
+
for (const entry of fileSummaries) {
|
|
1241
|
+
if (isTestFile(entry.file)) continue;
|
|
1242
|
+
let riskScore = 0;
|
|
1243
|
+
const signals: string[] = [];
|
|
1244
|
+
|
|
1245
|
+
const avgComplexity = entry.functions.length > 0
|
|
1246
|
+
? entry.functions.reduce((s, f) => s + f.complexity, 0) / entry.functions.length
|
|
1247
|
+
: 0;
|
|
1248
|
+
if (avgComplexity > 15) {
|
|
1249
|
+
riskScore += 2;
|
|
1250
|
+
signals.push(`high avg complexity (${avgComplexity.toFixed(1)})`);
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
const maxCognitive = entry.functions.reduce((m, f) => Math.max(m, f.cognitiveComplexity), 0);
|
|
1254
|
+
if (maxCognitive > 20) {
|
|
1255
|
+
riskScore += 2;
|
|
1256
|
+
signals.push(`high cognitive complexity (${maxCognitive})`);
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
const lowMiCount = entry.functions.filter(f => f.maintainabilityIndex !== undefined && f.maintainabilityIndex < 20).length;
|
|
1260
|
+
if (lowMiCount > 0) {
|
|
1261
|
+
riskScore += lowMiCount;
|
|
1262
|
+
signals.push(`${lowMiCount} function(s) with low MI`);
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
if (entry.emptyCatches && entry.emptyCatches.length > 0) {
|
|
1266
|
+
riskScore += 1;
|
|
1267
|
+
signals.push(`${entry.emptyCatches.length} empty catches`);
|
|
1268
|
+
}
|
|
1269
|
+
if (entry.promiseAllUnhandled && entry.promiseAllUnhandled.length > 0) {
|
|
1270
|
+
riskScore += 1;
|
|
1271
|
+
signals.push(`${entry.promiseAllUnhandled.length} unhandled promise combinators`);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
const depProfile = entry.dependencyProfile;
|
|
1275
|
+
if (depProfile && depProfile.declaredExports) {
|
|
1276
|
+
const exportCount = depProfile.declaredExports.length;
|
|
1277
|
+
if (exportCount > 15) {
|
|
1278
|
+
riskScore += 1;
|
|
1279
|
+
signals.push(`${exportCount} exports`);
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
if (riskScore < 4) continue;
|
|
1284
|
+
if (!canAddFinding(findings)) return findings;
|
|
1285
|
+
const severity: Finding['severity'] = riskScore >= 8 ? 'critical' : riskScore >= 6 ? 'high' : 'medium';
|
|
1286
|
+
findings.push({
|
|
1287
|
+
severity,
|
|
1288
|
+
category: 'change-risk',
|
|
1289
|
+
file: entry.file,
|
|
1290
|
+
lineStart: 1,
|
|
1291
|
+
lineEnd: 1,
|
|
1292
|
+
title: `Change-risk score ${riskScore}: ${signals.slice(0, 3).join(', ')}`,
|
|
1293
|
+
reason: `This file has a composite change-risk score of ${riskScore}, derived from: ${signals.join('; ')}. Files with multiple overlapping quality signals are the most likely to introduce regressions when modified.`,
|
|
1294
|
+
files: [entry.file],
|
|
1295
|
+
suggestedFix: {
|
|
1296
|
+
strategy: 'Reduce risk incrementally — address the highest-impact signal first.',
|
|
1297
|
+
steps: [
|
|
1298
|
+
'Check test coverage for this file — add tests if missing.',
|
|
1299
|
+
'Address the highest-severity individual finding first.',
|
|
1300
|
+
'Consider splitting the module to isolate high-risk logic.',
|
|
1301
|
+
],
|
|
1302
|
+
},
|
|
1303
|
+
impact: 'Files with multiple quality issues compound risk — each change is likely to trigger regressions in hard-to-predict ways.',
|
|
1304
|
+
tags: ['risk', 'composite', 'priority'],
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
return findings;
|
|
1308
|
+
}
|
|
@@ -70,6 +70,14 @@ export {
|
|
|
70
70
|
detectListenerLeakRisk,
|
|
71
71
|
detectUnboundedCollection,
|
|
72
72
|
detectSimilarFunctionBodies,
|
|
73
|
+
detectDeepNesting,
|
|
74
|
+
detectMultipleReturnPaths,
|
|
75
|
+
detectCatchRethrow,
|
|
76
|
+
detectMagicStrings,
|
|
77
|
+
detectBooleanParameterCluster,
|
|
78
|
+
detectPromiseAllUnhandled,
|
|
79
|
+
detectExportSurfaceDensity,
|
|
80
|
+
detectChangeRisk,
|
|
73
81
|
} from './code-quality.js';
|
|
74
82
|
|
|
75
83
|
export {
|