pi-lens 4.3.0 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1159 -0
- package/README.md +116 -25
- package/config/dependency-cruiser-eager-allowlist.json +6 -2
- package/dist/chunk-2BEMIWEW.js +51 -0
- package/dist/chunk-2EECBNC5.js +89 -0
- package/dist/chunk-2FQ62SPM.js +83 -0
- package/dist/chunk-2UMYMRI3.js +118 -0
- package/dist/chunk-34OCDWOS.js +48 -0
- package/dist/chunk-3FERWMCH.js +144 -0
- package/dist/chunk-3JL6IFD7.js +97 -0
- package/dist/chunk-3JSEWUWI.js +327 -0
- package/dist/chunk-3MED75HT.js +37 -0
- package/dist/chunk-3MRXIJ6I.js +79 -0
- package/dist/chunk-3P4PF2BX.js +2250 -0
- package/dist/chunk-3PNFWVHT.js +201 -0
- package/dist/chunk-3TTPKMEF.js +162 -0
- package/dist/chunk-5JHXUETW.js +326 -0
- package/dist/chunk-5W3R6LFT.js +24 -0
- package/dist/chunk-64LU2OVH.js +341 -0
- package/dist/chunk-6B5I6ICN.js +44 -0
- package/dist/chunk-6P54TMWL.js +274 -0
- package/dist/chunk-6UYA642J.js +145 -0
- package/dist/chunk-6XX5HCLK.js +398 -0
- package/dist/chunk-7AXO3ZDF.js +30 -0
- package/dist/chunk-7BX5DWSA.js +1907 -0
- package/dist/chunk-7ELY2CSM.js +902 -0
- package/dist/chunk-7M4T5N3V.js +38 -0
- package/dist/chunk-7U2IDNXN.js +37 -0
- package/dist/chunk-ABBOA7UD.js +157 -0
- package/dist/chunk-AFZYMAIV.js +756 -0
- package/dist/chunk-ALQRYH6O.js +112 -0
- package/dist/chunk-AXKPQ6ZI.js +1610 -0
- package/dist/chunk-BHWHXMQ2.js +62 -0
- package/dist/chunk-BJF25SUG.js +22 -0
- package/dist/chunk-BNKLYOOO.js +18 -0
- package/dist/chunk-BW5KFIQC.js +59 -0
- package/dist/chunk-CBD2B5CP.js +599 -0
- package/dist/chunk-CFYISHUW.js +42 -0
- package/dist/chunk-CMU4RMJB.js +30 -0
- package/dist/chunk-CULQYFLU.js +14 -0
- package/dist/chunk-D65GOCJB.js +289 -0
- package/dist/chunk-D6YF5HKX.js +59 -0
- package/dist/chunk-DMS52BEP.js +342 -0
- package/dist/chunk-ELVWJYRV.js +211 -0
- package/dist/chunk-EUT3B22Y.js +27 -0
- package/dist/chunk-F5VLZHUW.js +146 -0
- package/dist/chunk-FC4RP4I2.js +12 -0
- package/dist/chunk-FGALODG3.js +55 -0
- package/dist/chunk-G3RLJYA2.js +2358 -0
- package/dist/chunk-GAYGGICG.js +32 -0
- package/dist/chunk-H2W2AXD3.js +419 -0
- package/dist/chunk-H5EV3VMF.js +114 -0
- package/dist/chunk-HREZQCT3.js +106 -0
- package/dist/chunk-HSIRMK2D.js +517 -0
- package/dist/chunk-IMSQR4WO.js +184 -0
- package/dist/chunk-IQZXOZ7S.js +4816 -0
- package/dist/chunk-IR6XFA5P.js +37 -0
- package/dist/chunk-IUKPRZER.js +78 -0
- package/dist/chunk-IUR76K6A.js +262 -0
- package/dist/chunk-J3FZR3YY.js +98 -0
- package/dist/chunk-J6DFZDFA.js +562 -0
- package/dist/chunk-J7WJZ6W7.js +50 -0
- package/dist/chunk-JONGANYH.js +202 -0
- package/dist/chunk-KJCWXUUS.js +425 -0
- package/dist/chunk-KJN4IOEJ.js +17 -0
- package/dist/chunk-KMGPUKFD.js +25 -0
- package/dist/chunk-LD7WFTRX.js +4533 -0
- package/dist/chunk-LJDODBBZ.js +78 -0
- package/dist/chunk-LNOMA3MP.js +169 -0
- package/dist/chunk-MGIWSROG.js +2334 -0
- package/dist/chunk-MQA2YBAH.js +308 -0
- package/dist/chunk-MTDRLSI7.js +21720 -0
- package/dist/chunk-N2IRDBZI.js +2355 -0
- package/dist/chunk-N77WFUL7.js +50 -0
- package/dist/chunk-N7YNJE5R.js +466 -0
- package/dist/chunk-NABLC7W3.js +148 -0
- package/dist/chunk-NFXP47RV.js +999 -0
- package/dist/chunk-NJF2X5XF.js +45 -0
- package/dist/chunk-NXL4FFQQ.js +47 -0
- package/dist/chunk-O7HZX7CA.js +309 -0
- package/dist/chunk-OC7LYAU5.js +708 -0
- package/dist/chunk-OEX24ECI.js +348 -0
- package/dist/chunk-OYOB3ZFG.js +78 -0
- package/dist/chunk-OYTMZXRF.js +41 -0
- package/dist/chunk-OZJINN4O.js +84 -0
- package/dist/chunk-PCHDGUKT.js +23 -0
- package/dist/chunk-QOZXJ4NA.js +3364 -0
- package/dist/chunk-QYF5S6P6.js +45 -0
- package/dist/chunk-RJFED73B.js +79 -0
- package/dist/chunk-RTQNRM5X.js +27 -0
- package/dist/chunk-S6AMWKPC.js +189 -0
- package/dist/chunk-T4QZ6FEH.js +308 -0
- package/dist/chunk-T54VJRAD.js +5456 -0
- package/dist/chunk-TA5L5KWQ.js +167 -0
- package/dist/chunk-TQFBZVCG.js +27 -0
- package/dist/chunk-U52SAGRM.js +62 -0
- package/dist/chunk-UEAHAMEI.js +5814 -0
- package/dist/chunk-UGSMCQ4D.js +327 -0
- package/dist/chunk-UOPVJQ4N.js +103 -0
- package/dist/chunk-USHG4DLH.js +459 -0
- package/dist/chunk-UXVNL3D7.js +23 -0
- package/dist/chunk-V5MEBST3.js +4139 -0
- package/dist/chunk-VGEVL5EQ.js +29 -0
- package/dist/chunk-VPWKF3GN.js +87 -0
- package/dist/chunk-VSMJK3ZJ.js +1250 -0
- package/dist/chunk-VYKKMYVT.js +560 -0
- package/dist/chunk-VZHJS6DR.js +442 -0
- package/dist/chunk-WATC3IQR.js +213 -0
- package/dist/chunk-WPE5FPGR.js +54 -0
- package/dist/chunk-WSEWKCXU.js +188 -0
- package/dist/chunk-WW5BLB74.js +659 -0
- package/dist/chunk-XGUL4SLQ.js +406 -0
- package/dist/chunk-XHSCVSOL.js +170 -0
- package/dist/chunk-XIMYZ3JA.js +27 -0
- package/dist/chunk-YLN4K6WD.js +385 -0
- package/dist/chunk-Z3CCVDUB.js +76 -0
- package/dist/chunk-Z54ZSOBZ.js +61 -0
- package/dist/chunk-Z6BB4JLQ.js +478 -0
- package/dist/chunk-Z7QQA2KT.js +27 -0
- package/dist/chunk-ZETYB3XG.js +2626 -0
- package/dist/chunk-ZMOMPX2Z.js +87 -0
- package/dist/chunk-ZOEYVXSV.js +149 -0
- package/dist/chunk-ZZUFZUQZ.js +12120 -0
- package/dist/index.js +39712 -29876
- package/dist/mcp/analyze-cli.js +186 -232
- package/dist/mcp/cli.js +137 -98
- package/dist/mcp/server.js +22688 -1573
- package/dist/mcp/worker.js +97 -38
- package/dist/probes/installer.js +135 -0
- package/dist/workers/project-snapshot-persist-worker.js +22 -0
- package/dist/workers/review-graph-persist-worker.js +15 -0
- package/docs/agent-guide.md +13 -4
- package/docs/agent-tools.md +42 -0
- package/docs/ast-grep_rules_catalog.md +5 -4
- package/docs/configuration.md +28 -2
- package/docs/custom-rules.md +25 -2
- package/docs/environment-variables.md +86 -8
- package/docs/features.md +45 -5
- package/docs/globalconfig.md +2 -1
- package/docs/io-bridge-v2-migration.md +94 -0
- package/docs/lsp-capability-matrix.md +37 -4
- package/docs/lsp-idle-eviction.md +124 -0
- package/docs/mcp.md +21 -5
- package/docs/merge-queue-rollout.md +77 -0
- package/docs/pi-lens-fixer.md +160 -88
- package/docs/pi-lens-investigator.md +74 -26
- package/docs/pi-lens-merge-policy.md +736 -0
- package/docs/pi-lens-monitor.md +75 -7
- package/docs/pi-lens-retro.md +6 -4
- package/docs/pi-lens-reviewer.md +189 -48
- package/docs/pi-lens-subagent.md +246 -45
- package/docs/pi-lens-warden.md +18 -7
- package/docs/public-api-stability.md +55 -0
- package/docs/release-qa-baseline.md +84 -17
- package/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
- package/docs/schema/pi-lens-config-v1.json +530 -0
- package/docs/servercapabilities.md +56 -49
- package/docs/settings.md +1 -0
- package/docs/usage.md +5 -1
- package/docs/word-index.md +6 -0
- package/grammars/tree-sitter-bash.wasm +0 -0
- package/grammars/tree-sitter-bash.wasm.json +3 -3
- package/package.json +19 -7
- package/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
- package/rules/ast-grep-rules/rule-tests/no-identity-operator-on-literals-test.yml +12 -2
- package/rules/ast-grep-rules/rule-tests/throw-new-error-js-test.yml +2 -0
- package/rules/ast-grep-rules/rule-tests/throw-new-error-test.yml +2 -0
- package/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
- package/rules/ast-grep-rules/rules/no-identity-operator-on-literals.yml +20 -12
- package/rules/ast-grep-rules/rules/throw-new-error-js.yml +2 -2
- package/rules/ast-grep-rules/rules/throw-new-error.yml +2 -2
- package/scripts/analyze-pi-lens-logs.mjs +1275 -62
- package/scripts/download-grammars.js +5 -0
- package/scripts/grammars.lock.json +6 -1
- package/scripts/install-selftest.mjs +33 -34
- package/scripts/lib/host-provided-deps.mjs +13 -4
- package/scripts/lib/web-tree-sitter-dir.mjs +18 -0
- package/dist/clients/actionable-warnings-logger.js +0 -35
- package/dist/clients/actionable-warnings.js +0 -1610
- package/dist/clients/advisory-provenance.js +0 -593
- package/dist/clients/agent-behavior-client.js +0 -147
- package/dist/clients/agent-nudge.js +0 -325
- package/dist/clients/analysed-root.js +0 -1
- package/dist/clients/ast-grep-client.js +0 -731
- package/dist/clients/ast-grep-rule-manager.js +0 -146
- package/dist/clients/ast-grep-tool-logger.js +0 -118
- package/dist/clients/ast-grep-types.js +0 -10
- package/dist/clients/ast-grep-yaml-synth.js +0 -154
- package/dist/clients/atomic-write-staging.js +0 -75
- package/dist/clients/atomic-write.js +0 -189
- package/dist/clients/availability-probe-flight.js +0 -12
- package/dist/clients/bash-file-access.js +0 -1056
- package/dist/clients/biome-client.js +0 -357
- package/dist/clients/blocker-freshness.js +0 -837
- package/dist/clients/blocker-past-eof.js +0 -129
- package/dist/clients/bootstrap.js +0 -569
- package/dist/clients/bounded-cache.js +0 -190
- package/dist/clients/bounded-pid-file-lock.js +0 -202
- package/dist/clients/bounded-telemetry.js +0 -295
- package/dist/clients/build-identity.js +0 -95
- package/dist/clients/bundled-resource-health.js +0 -113
- package/dist/clients/bus-events-logger.js +0 -105
- package/dist/clients/bus-publish.js +0 -171
- package/dist/clients/cache/rule-cache.js +0 -190
- package/dist/clients/cache-manager.js +0 -524
- package/dist/clients/cache-observability.js +0 -1313
- package/dist/clients/call-graph.js +0 -852
- package/dist/clients/cargo-manifest.js +0 -422
- package/dist/clients/cascade-budget.js +0 -196
- package/dist/clients/cascade-format.js +0 -315
- package/dist/clients/cascade-logger.js +0 -31
- package/dist/clients/cascade-types.js +0 -9
- package/dist/clients/child-unref.js +0 -124
- package/dist/clients/code-quality-warnings.js +0 -286
- package/dist/clients/codebase-model.js +0 -173
- package/dist/clients/collateral-test-role.js +0 -40
- package/dist/clients/complexity-client.js +0 -462
- package/dist/clients/config-core/deny.js +0 -221
- package/dist/clients/config-core/index.js +0 -50
- package/dist/clients/config-core/merge.js +0 -357
- package/dist/clients/config-core/normalize.js +0 -340
- package/dist/clients/config-core/process-spec.js +0 -248
- package/dist/clients/config-core/provenance.js +0 -164
- package/dist/clients/config-core/records.js +0 -218
- package/dist/clients/config-core/resolve.js +0 -125
- package/dist/clients/config-core/safe-object.js +0 -78
- package/dist/clients/config-core/schema.js +0 -165
- package/dist/clients/config-diagnostic-codes.js +0 -285
- package/dist/clients/config-locations.js +0 -388
- package/dist/clients/config-resolve.js +0 -798
- package/dist/clients/config-schema.js +0 -251
- package/dist/clients/config-warn.js +0 -407
- package/dist/clients/console-guard-install.js +0 -26
- package/dist/clients/cooperative-budget.js +0 -42
- package/dist/clients/dead-code-client.js +0 -510
- package/dist/clients/dead-code-logger.js +0 -30
- package/dist/clients/deadline-utils.js +0 -280
- package/dist/clients/debug-handles.js +0 -211
- package/dist/clients/debug-heap.js +0 -174
- package/dist/clients/deferred-lsp-work.js +0 -106
- package/dist/clients/degradation-ledger.js +0 -426
- package/dist/clients/demoted-finding-render.js +0 -169
- package/dist/clients/dependency-checker.js +0 -885
- package/dist/clients/deps/ast-grep-napi.js +0 -22
- package/dist/clients/deps/js-yaml.js +0 -9
- package/dist/clients/deps/minimatch.js +0 -4
- package/dist/clients/deps/pi-tui.js +0 -14
- package/dist/clients/deps/typebox.js +0 -14
- package/dist/clients/deps/vscode-jsonrpc.js +0 -1
- package/dist/clients/deps/web-tree-sitter.js +0 -24
- package/dist/clients/diagnostic-dispositions.js +0 -630
- package/dist/clients/diagnostic-line-freshness.js +0 -305
- package/dist/clients/diagnostic-logger.js +0 -73
- package/dist/clients/diagnostic-tracker.js +0 -105
- package/dist/clients/diagnostics-publish.js +0 -230
- package/dist/clients/dispatch/ast-grep-catalog.js +0 -65
- package/dist/clients/dispatch/auxiliary-lsp.js +0 -343
- package/dist/clients/dispatch/collect-later-tier.js +0 -35
- package/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
- package/dist/clients/dispatch/dispatcher.js +0 -1269
- package/dist/clients/dispatch/fact-provider-types.js +0 -1
- package/dist/clients/dispatch/fact-rule-runner.js +0 -17
- package/dist/clients/dispatch/fact-runner.js +0 -30
- package/dist/clients/dispatch/fact-scheduler.js +0 -68
- package/dist/clients/dispatch/fact-store.js +0 -377
- package/dist/clients/dispatch/facts/comment-facts.js +0 -22
- package/dist/clients/dispatch/facts/file-content.js +0 -19
- package/dist/clients/dispatch/facts/function-facts.js +0 -348
- package/dist/clients/dispatch/facts/import-facts.js +0 -204
- package/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
- package/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
- package/dist/clients/dispatch/finding-policy.js +0 -339
- package/dist/clients/dispatch/indent-detect.js +0 -417
- package/dist/clients/dispatch/inline-suppressions.js +0 -89
- package/dist/clients/dispatch/integration.js +0 -2377
- package/dist/clients/dispatch/lazy.js +0 -11
- package/dist/clients/dispatch/pending-runner-findings.js +0 -87
- package/dist/clients/dispatch/plan.js +0 -278
- package/dist/clients/dispatch/priorities.js +0 -20
- package/dist/clients/dispatch/rule-id-normalize.js +0 -50
- package/dist/clients/dispatch/rule-ignores.js +0 -69
- package/dist/clients/dispatch/rule-policy.js +0 -135
- package/dist/clients/dispatch/rules/async-noise.js +0 -40
- package/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
- package/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
- package/dist/clients/dispatch/rules/error-obscuring.js +0 -32
- package/dist/clients/dispatch/rules/error-swallowing.js +0 -31
- package/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
- package/dist/clients/dispatch/rules/high-complexity.js +0 -72
- package/dist/clients/dispatch/rules/high-fan-out.js +0 -74
- package/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
- package/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
- package/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
- package/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
- package/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
- package/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
- package/dist/clients/dispatch/runner-context.js +0 -52
- package/dist/clients/dispatch/runners/actionlint.js +0 -111
- package/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
- package/dist/clients/dispatch/runners/biome-check.js +0 -296
- package/dist/clients/dispatch/runners/cpp-check.js +0 -219
- package/dist/clients/dispatch/runners/credo.js +0 -82
- package/dist/clients/dispatch/runners/cue-vet.js +0 -416
- package/dist/clients/dispatch/runners/dart-analyze.js +0 -183
- package/dist/clients/dispatch/runners/detekt.js +0 -176
- package/dist/clients/dispatch/runners/dotnet-build.js +0 -164
- package/dist/clients/dispatch/runners/elixir-check.js +0 -195
- package/dist/clients/dispatch/runners/eslint.js +0 -137
- package/dist/clients/dispatch/runners/fact-rules.js +0 -29
- package/dist/clients/dispatch/runners/fish-indent.js +0 -69
- package/dist/clients/dispatch/runners/gleam-check.js +0 -167
- package/dist/clients/dispatch/runners/go-vet.js +0 -104
- package/dist/clients/dispatch/runners/golangci-lint.js +0 -135
- package/dist/clients/dispatch/runners/hadolint.js +0 -91
- package/dist/clients/dispatch/runners/helm-lint.js +0 -171
- package/dist/clients/dispatch/runners/helm-render.js +0 -940
- package/dist/clients/dispatch/runners/htmlhint.js +0 -117
- package/dist/clients/dispatch/runners/index.js +0 -108
- package/dist/clients/dispatch/runners/javac.js +0 -99
- package/dist/clients/dispatch/runners/ktlint.js +0 -110
- package/dist/clients/dispatch/runners/lsp.js +0 -379
- package/dist/clients/dispatch/runners/markdownlint.js +0 -167
- package/dist/clients/dispatch/runners/mypy.js +0 -102
- package/dist/clients/dispatch/runners/oxlint.js +0 -414
- package/dist/clients/dispatch/runners/php-lint.js +0 -85
- package/dist/clients/dispatch/runners/phpstan.js +0 -120
- package/dist/clients/dispatch/runners/prisma-validate.js +0 -62
- package/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
- package/dist/clients/dispatch/runners/pyright.js +0 -169
- package/dist/clients/dispatch/runners/rubocop.js +0 -99
- package/dist/clients/dispatch/runners/ruff.js +0 -88
- package/dist/clients/dispatch/runners/rust-clippy.js +0 -256
- package/dist/clients/dispatch/runners/shellcheck.js +0 -173
- package/dist/clients/dispatch/runners/shfmt.js +0 -102
- package/dist/clients/dispatch/runners/spellcheck.js +0 -128
- package/dist/clients/dispatch/runners/spotbugs.js +0 -259
- package/dist/clients/dispatch/runners/sqlfluff.js +0 -183
- package/dist/clients/dispatch/runners/stylelint.js +0 -166
- package/dist/clients/dispatch/runners/swiftlint.js +0 -163
- package/dist/clients/dispatch/runners/taplo.js +0 -174
- package/dist/clients/dispatch/runners/terragrunt.js +0 -168
- package/dist/clients/dispatch/runners/tflint.js +0 -125
- package/dist/clients/dispatch/runners/tree-sitter.js +0 -643
- package/dist/clients/dispatch/runners/trivy-config.js +0 -253
- package/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
- package/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
- package/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -95
- package/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
- package/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
- package/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
- package/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
- package/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
- package/dist/clients/dispatch/runners/utils.js +0 -15
- package/dist/clients/dispatch/runners/vale.js +0 -128
- package/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
- package/dist/clients/dispatch/runners/yamllint.js +0 -95
- package/dist/clients/dispatch/runners/zig-check.js +0 -79
- package/dist/clients/dispatch/suppress-writer.js +0 -79
- package/dist/clients/dispatch/tool-profile.js +0 -30
- package/dist/clients/dispatch/types.js +0 -21
- package/dist/clients/dispatch/utils/format-utils.js +0 -45
- package/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
- package/dist/clients/disposition-logger.js +0 -32
- package/dist/clients/disposition-publish.js +0 -124
- package/dist/clients/durable-store.js +0 -97
- package/dist/clients/effective-config.js +0 -415
- package/dist/clients/env-utils.js +0 -83
- package/dist/clients/error-class.js +0 -23
- package/dist/clients/eval-timestamp.js +0 -17
- package/dist/clients/event-loop-hold.js +0 -274
- package/dist/clients/event-loop-monitor.js +0 -250
- package/dist/clients/extension-log.js +0 -504
- package/dist/clients/extension-mode.js +0 -73
- package/dist/clients/feature-hints.js +0 -103
- package/dist/clients/file-kinds.js +0 -412
- package/dist/clients/file-role.js +0 -134
- package/dist/clients/file-time.js +0 -160
- package/dist/clients/file-utils.js +0 -1032
- package/dist/clients/finding-delivery-gate.js +0 -494
- package/dist/clients/finding-identity.js +0 -88
- package/dist/clients/fix-worklog.js +0 -103
- package/dist/clients/format-events-publish.js +0 -343
- package/dist/clients/format-service.js +0 -222
- package/dist/clients/formatters-lazy.js +0 -9
- package/dist/clients/formatters.js +0 -2032
- package/dist/clients/freshness-cadence.js +0 -17
- package/dist/clients/freshness.js +0 -38
- package/dist/clients/generated-artifacts.js +0 -394
- package/dist/clients/generation-guard.js +0 -215
- package/dist/clients/git-guard.js +0 -1136
- package/dist/clients/git-tracked-ignore.js +0 -243
- package/dist/clients/gitleaks-client.js +0 -509
- package/dist/clients/go-client.js +0 -104
- package/dist/clients/govulncheck-client.js +0 -605
- package/dist/clients/gradle-ktfmt-style.js +0 -348
- package/dist/clients/grammar-source.js +0 -465
- package/dist/clients/gzip-stage-write.js +0 -135
- package/dist/clients/hashline-anchor.js +0 -424
- package/dist/clients/hook-budgets.js +0 -76
- package/dist/clients/host-edit-normalize.js +0 -140
- package/dist/clients/host-ports.js +0 -39
- package/dist/clients/indent-retarget.js +0 -154
- package/dist/clients/inline-blocker-dispositions.js +0 -186
- package/dist/clients/install-diagnostics.js +0 -156
- package/dist/clients/installer/index.js +0 -5416
- package/dist/clients/installer/managed-tool-refresh-session.js +0 -58
- package/dist/clients/installer/managed-tool-refresh.js +0 -783
- package/dist/clients/instance-reaper-state.js +0 -7
- package/dist/clients/instance-reaper.js +0 -1137
- package/dist/clients/instance-registry-lock.js +0 -145
- package/dist/clients/instance-registry.js +0 -773
- package/dist/clients/jscpd-client.js +0 -378
- package/dist/clients/json-cache-read.js +0 -65
- package/dist/clients/knip-client.js +0 -788
- package/dist/clients/language-policy.js +0 -252
- package/dist/clients/language-profile.js +0 -361
- package/dist/clients/language-registry.js +0 -603
- package/dist/clients/latency-logger.js +0 -727
- package/dist/clients/lazy-import.js +0 -21
- package/dist/clients/ledger-bounds.js +0 -54
- package/dist/clients/lens-config.js +0 -404
- package/dist/clients/lens-engine.js +0 -358
- package/dist/clients/lens-events.js +0 -125
- package/dist/clients/lens-flag-registry.js +0 -467
- package/dist/clients/lens-map.js +0 -1156
- package/dist/clients/live-bus-emitter.js +0 -74
- package/dist/clients/log-cleanup.js +0 -222
- package/dist/clients/lsp/aggregation.js +0 -178
- package/dist/clients/lsp/cascade-tier.js +0 -421
- package/dist/clients/lsp/client.js +0 -4593
- package/dist/clients/lsp/config.js +0 -691
- package/dist/clients/lsp/content-limits.js +0 -41
- package/dist/clients/lsp/diagnostic-binding.js +0 -225
- package/dist/clients/lsp/document-drift.js +0 -467
- package/dist/clients/lsp/edits.js +0 -1219
- package/dist/clients/lsp/index.js +0 -8305
- package/dist/clients/lsp/inferred-project.js +0 -216
- package/dist/clients/lsp/jvm-runtime.js +0 -298
- package/dist/clients/lsp/language.js +0 -63
- package/dist/clients/lsp/launch.js +0 -746
- package/dist/clients/lsp/lombok.js +0 -158
- package/dist/clients/lsp/path-utils.js +0 -5
- package/dist/clients/lsp/pending-aux-coverage.js +0 -251
- package/dist/clients/lsp/position-encoding.js +0 -61
- package/dist/clients/lsp/ruby-drive-dirs.js +0 -83
- package/dist/clients/lsp/server.js +0 -3290
- package/dist/clients/lsp/session-roots.js +0 -192
- package/dist/clients/lsp/spawn-history.js +0 -17
- package/dist/clients/lsp/sync-kind.js +0 -56
- package/dist/clients/lsp/tsserver-sync.js +0 -332
- package/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
- package/dist/clients/lsp/wait-policy/classification.js +0 -85
- package/dist/clients/lsp/wait-policy/index.js +0 -10
- package/dist/clients/lsp/wait-policy/strategies.js +0 -392
- package/dist/clients/lsp/watch-queue.js +0 -61
- package/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
- package/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
- package/dist/clients/lsp/workspace-sweep-hold.js +0 -184
- package/dist/clients/lsp-budget.js +0 -186
- package/dist/clients/lsp-document-symbols.js +0 -110
- package/dist/clients/lsp-lazy.js +0 -9
- package/dist/clients/lsp-mutation.js +0 -396
- package/dist/clients/lsp-status.js +0 -59
- package/dist/clients/map-with-concurrency.js +0 -40
- package/dist/clients/mcp/analyze.js +0 -420
- package/dist/clients/mcp/host-shim.js +0 -31
- package/dist/clients/mcp/ipc.js +0 -523
- package/dist/clients/mcp/review.js +0 -197
- package/dist/clients/mcp/session.js +0 -412
- package/dist/clients/memory-sampler.js +0 -208
- package/dist/clients/message-end-attribution.js +0 -30
- package/dist/clients/metrics-client.js +0 -107
- package/dist/clients/metrics-history.js +0 -327
- package/dist/clients/middle-man-analysis.js +0 -263
- package/dist/clients/model-provider.js +0 -53
- package/dist/clients/module-report-lsp.js +0 -189
- package/dist/clients/module-report.js +0 -2150
- package/dist/clients/mutating-tool.js +0 -651
- package/dist/clients/mutation-attribution.js +0 -368
- package/dist/clients/mutation-bridge.js +0 -240
- package/dist/clients/ndjson-logger.js +0 -734
- package/dist/clients/observed-mutation-sources.js +0 -101
- package/dist/clients/observed-mutation.js +0 -1253
- package/dist/clients/oldtext-autopatch.js +0 -128
- package/dist/clients/opaque-mutation-scan.js +0 -496
- package/dist/clients/opengrep-client.js +0 -333
- package/dist/clients/opengrep-config.js +0 -76
- package/dist/clients/package-manager.js +0 -607
- package/dist/clients/package-root.js +0 -38
- package/dist/clients/partial-edit-apply.js +0 -439
- package/dist/clients/path-attribution-telemetry.js +0 -43
- package/dist/clients/path-keyed-map.js +0 -108
- package/dist/clients/path-utils.js +0 -1244
- package/dist/clients/performance-report.js +0 -331
- package/dist/clients/persist-debounce.js +0 -70
- package/dist/clients/persistent-reverify.js +0 -271
- package/dist/clients/php-cs-fixer-config.js +0 -119
- package/dist/clients/pipeline.js +0 -1480
- package/dist/clients/post-autofix-notice.js +0 -37
- package/dist/clients/print-mode.js +0 -21
- package/dist/clients/probe-home-state.js +0 -228
- package/dist/clients/process-bridge.js +0 -66
- package/dist/clients/process-singletons.js +0 -210
- package/dist/clients/process-snapshot.js +0 -68
- package/dist/clients/project-changes.js +0 -181
- package/dist/clients/project-conventions.js +0 -171
- package/dist/clients/project-diagnostics/cache.js +0 -137
- package/dist/clients/project-diagnostics/extractors.js +0 -109
- package/dist/clients/project-diagnostics/fresh-fetch.js +0 -668
- package/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
- package/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
- package/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
- package/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
- package/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
- package/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
- package/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
- package/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
- package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
- package/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
- package/dist/clients/project-diagnostics/scanner.js +0 -520
- package/dist/clients/project-diagnostics/types.js +0 -1
- package/dist/clients/project-lens-config.js +0 -807
- package/dist/clients/project-report.js +0 -701
- package/dist/clients/project-scale.js +0 -237
- package/dist/clients/project-scan-policy.js +0 -11
- package/dist/clients/project-snapshot-fingerprint.js +0 -48
- package/dist/clients/project-snapshot-persist-worker.js +0 -20
- package/dist/clients/project-snapshot.js +0 -1653
- package/dist/clients/project-trust.js +0 -181
- package/dist/clients/python-environment.js +0 -217
- package/dist/clients/python-provenance.js +0 -639
- package/dist/clients/quiet-window-config.js +0 -47
- package/dist/clients/quiet-window.js +0 -236
- package/dist/clients/read-bridge.js +0 -139
- package/dist/clients/read-expansion.js +0 -266
- package/dist/clients/read-guard-logger.js +0 -251
- package/dist/clients/read-guard-tool-lines.js +0 -1306
- package/dist/clients/read-guard.js +0 -1561
- package/dist/clients/recent-touches.js +0 -240
- package/dist/clients/redact/secrets.js +0 -449
- package/dist/clients/resource-sampler.js +0 -628
- package/dist/clients/reverse-deps.js +0 -270
- package/dist/clients/review-graph/builder.js +0 -5126
- package/dist/clients/review-graph/format.js +0 -33
- package/dist/clients/review-graph/git-identity.js +0 -163
- package/dist/clients/review-graph/import-resolvers.js +0 -481
- package/dist/clients/review-graph/persist-worker.js +0 -10
- package/dist/clients/review-graph/query.js +0 -244
- package/dist/clients/review-graph/revision-drift.js +0 -21
- package/dist/clients/review-graph/service.js +0 -96
- package/dist/clients/review-graph/shared-extraction-ir.js +0 -82
- package/dist/clients/review-graph/symbol-id.js +0 -103
- package/dist/clients/review-graph/tsconfig-paths.js +0 -299
- package/dist/clients/review-graph/types.js +0 -1
- package/dist/clients/review-graph/workspace-modules.js +0 -449
- package/dist/clients/review-graph-logger.js +0 -81
- package/dist/clients/ruff-client.js +0 -179
- package/dist/clients/rules-scanner.js +0 -131
- package/dist/clients/run-duration.js +0 -55
- package/dist/clients/runtime-agent-end.js +0 -746
- package/dist/clients/runtime-config.js +0 -77
- package/dist/clients/runtime-context.js +0 -211
- package/dist/clients/runtime-coordinator.js +0 -1324
- package/dist/clients/runtime-session.js +0 -2485
- package/dist/clients/runtime-tool-call.js +0 -1295
- package/dist/clients/runtime-tool-result.js +0 -2049
- package/dist/clients/runtime-turn.js +0 -3767
- package/dist/clients/rust-client.js +0 -97
- package/dist/clients/safe-spawn.js +0 -2357
- package/dist/clients/sanitize.js +0 -286
- package/dist/clients/scan-utils.js +0 -25
- package/dist/clients/scratch-tree-policy.js +0 -165
- package/dist/clients/search-read-registration.js +0 -94
- package/dist/clients/secret-findings.js +0 -114
- package/dist/clients/security-scan-client.js +0 -352
- package/dist/clients/session-event-guard.js +0 -297
- package/dist/clients/session-lifecycle.js +0 -484
- package/dist/clients/session-start-observability.js +0 -94
- package/dist/clients/session-state-store.js +0 -101
- package/dist/clients/session-summary.js +0 -15
- package/dist/clients/sessionstart-logger.js +0 -27
- package/dist/clients/sg-runner.js +0 -876
- package/dist/clients/sgconfig.js +0 -347
- package/dist/clients/shared-checkout-guard.js +0 -338
- package/dist/clients/single-flight.js +0 -158
- package/dist/clients/situational-tool-telemetry.js +0 -108
- package/dist/clients/skills-resolver.js +0 -141
- package/dist/clients/slow-fs.js +0 -138
- package/dist/clients/smells-rollup.js +0 -231
- package/dist/clients/source-filter.js +0 -596
- package/dist/clients/source-walker.js +0 -211
- package/dist/clients/spawn-output-cap.js +0 -120
- package/dist/clients/spawn-timeout-cooldown.js +0 -110
- package/dist/clients/stale-marker.js +0 -17
- package/dist/clients/startup-scan.js +0 -400
- package/dist/clients/startup-timing.js +0 -130
- package/dist/clients/string-utils.js +0 -33
- package/dist/clients/subagent-mode.js +0 -111
- package/dist/clients/symbol-containment.js +0 -24
- package/dist/clients/symbol-types.js +0 -5
- package/dist/clients/test-runner-client.js +0 -2507
- package/dist/clients/test-runner-delivery.js +0 -287
- package/dist/clients/todo-scanner.js +0 -229
- package/dist/clients/tool-agreement.js +0 -423
- package/dist/clients/tool-config.js +0 -249
- package/dist/clients/tool-cwd.js +0 -270
- package/dist/clients/tool-definition.js +0 -47
- package/dist/clients/tool-event.js +0 -105
- package/dist/clients/tool-policy.js +0 -2755
- package/dist/clients/tool-probe.js +0 -53
- package/dist/clients/tool-render.js +0 -156
- package/dist/clients/tool-set-policy.js +0 -118
- package/dist/clients/tree-sitter-cache.js +0 -364
- package/dist/clients/tree-sitter-client.js +0 -4195
- package/dist/clients/tree-sitter-logger.js +0 -100
- package/dist/clients/tree-sitter-navigator.js +0 -269
- package/dist/clients/tree-sitter-query-loader.js +0 -569
- package/dist/clients/tree-sitter-shared.js +0 -158
- package/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
- package/dist/clients/trivy-client.js +0 -467
- package/dist/clients/tui-fit.js +0 -50
- package/dist/clients/turn-context.js +0 -52
- package/dist/clients/turn-end/lane.js +0 -51
- package/dist/clients/turn-end/lanes/govulncheck.js +0 -112
- package/dist/clients/turn-end/lanes/secrets.js +0 -204
- package/dist/clients/turn-summary-render.js +0 -72
- package/dist/clients/turn-summary.js +0 -132
- package/dist/clients/typos-config.js +0 -29
- package/dist/clients/user-notify.js +0 -51
- package/dist/clients/vanished-instance-marker.js +0 -57
- package/dist/clients/warm-attach.js +0 -305
- package/dist/clients/widget-state.js +0 -1808
- package/dist/clients/word-index-logger.js +0 -49
- package/dist/clients/word-index-store.js +0 -459
- package/dist/clients/word-index.js +0 -2080
- package/dist/clients/workspace-topology.js +0 -443
- package/dist/clients/write-ordering-guard.js +0 -65
- package/dist/clients/zizmor-config.js +0 -340
- package/dist/i18n.js +0 -69
- package/dist/mcp/build-staleness.js +0 -124
- package/dist/scripts/lib/process-scan.mjs +0 -583
- package/dist/scripts/lib/skills-predicate.mjs +0 -129
- package/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -123
- package/dist/tools/activate-tools.js +0 -87
- package/dist/tools/ast-grep-outline.js +0 -137
- package/dist/tools/ast-grep-replace.js +0 -244
- package/dist/tools/ast-grep-search.js +0 -762
- package/dist/tools/effective-config.js +0 -90
- package/dist/tools/lens-diagnostic-mark.js +0 -375
- package/dist/tools/lens-diagnostics.js +0 -2571
- package/dist/tools/lsp-diagnostics.js +0 -1745
- package/dist/tools/lsp-navigation.js +0 -1367
- package/dist/tools/lsp-structured-output.js +0 -294
- package/dist/tools/module-report.js +0 -382
- package/dist/tools/project-report.js +0 -86
- package/dist/tools/render-compact.js +0 -374
- package/dist/tools/scan-progress.js +0 -53
- package/dist/tools/shared.js +0 -29
- package/dist/tools/symbol-search.js +0 -155
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import * as fs from "node:fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
4
|
-
import { pathsEqual } from "../../path-utils.js";
|
|
5
|
-
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
6
|
-
import { getLinterPolicyForCwd } from "../../tool-policy.js";
|
|
7
|
-
import { PRIORITY } from "../priorities.js";
|
|
8
|
-
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
9
|
-
import { parseToolRun } from "./utils/tool-failure.js";
|
|
10
|
-
const detekt = createAvailabilityChecker("detekt", ".bat");
|
|
11
|
-
const DETEKT_CONFIG_CANDIDATES = [
|
|
12
|
-
"detekt.yml",
|
|
13
|
-
".detekt.yml",
|
|
14
|
-
path.join("config", "detekt", "detekt.yml"),
|
|
15
|
-
path.join("detekt", "detekt.yml"),
|
|
16
|
-
];
|
|
17
|
-
// Rules that `detekt --auto-correct` rewrites deterministically. Detekt's
|
|
18
|
-
// formatting ruleset wraps ktlint, whose rules are all autocorrectable; a
|
|
19
|
-
// small handful of style rules also support autocorrect. Detekt's text
|
|
20
|
-
// output does not surface a per-finding `canAutoCorrect` flag, so we keep a
|
|
21
|
-
// curated allowlist here. Source: https://detekt.dev/docs/rules/formatting/
|
|
22
|
-
// plus the autoCorrect-capable rules under style/comments. Conservative —
|
|
23
|
-
// when in doubt, leave a rule off this list.
|
|
24
|
-
const DETEKT_FIXABLE_RULES = new Set([
|
|
25
|
-
// formatting (ktlint wrapper) — every rule supports autocorrect
|
|
26
|
-
"AnnotationOnSeparateLine",
|
|
27
|
-
"AnnotationSpacing",
|
|
28
|
-
"ArgumentListWrapping",
|
|
29
|
-
"BlockCommentInitialStarAlignment",
|
|
30
|
-
"ChainWrapping",
|
|
31
|
-
"CommentSpacing",
|
|
32
|
-
"CommentWrapping",
|
|
33
|
-
"EnumEntryNameCase",
|
|
34
|
-
"Filename",
|
|
35
|
-
"FinalNewline",
|
|
36
|
-
"ImportOrdering",
|
|
37
|
-
"Indentation",
|
|
38
|
-
"MaximumLineLength",
|
|
39
|
-
"ModifierListSpacing",
|
|
40
|
-
"ModifierOrdering",
|
|
41
|
-
"MultiLineIfElse",
|
|
42
|
-
"NoBlankLineBeforeRbrace",
|
|
43
|
-
"NoBlankLinesInChainedMethodCalls",
|
|
44
|
-
"NoConsecutiveBlankLines",
|
|
45
|
-
"NoEmptyClassBody",
|
|
46
|
-
"NoEmptyFirstLineInMethodBlock",
|
|
47
|
-
"NoLineBreakAfterElse",
|
|
48
|
-
"NoLineBreakBeforeAssignment",
|
|
49
|
-
"NoMultipleSpaces",
|
|
50
|
-
"NoSemicolons",
|
|
51
|
-
"NoTrailingSpaces",
|
|
52
|
-
"NoUnitReturn",
|
|
53
|
-
"NoUnusedImports",
|
|
54
|
-
"NoWildcardImports",
|
|
55
|
-
"PackageName",
|
|
56
|
-
"ParameterListWrapping",
|
|
57
|
-
"SpacingAroundAngleBrackets",
|
|
58
|
-
"SpacingAroundColon",
|
|
59
|
-
"SpacingAroundComma",
|
|
60
|
-
"SpacingAroundCurly",
|
|
61
|
-
"SpacingAroundDot",
|
|
62
|
-
"SpacingAroundDoubleColon",
|
|
63
|
-
"SpacingAroundKeyword",
|
|
64
|
-
"SpacingAroundOperators",
|
|
65
|
-
"SpacingAroundParens",
|
|
66
|
-
"SpacingAroundRangeOperator",
|
|
67
|
-
"SpacingAroundUnaryOperator",
|
|
68
|
-
"SpacingBetweenDeclarationsWithAnnotations",
|
|
69
|
-
"SpacingBetweenDeclarationsWithComments",
|
|
70
|
-
"StringTemplate",
|
|
71
|
-
"TrailingCommaOnCallSite",
|
|
72
|
-
"TrailingCommaOnDeclarationSite",
|
|
73
|
-
"TypeArgumentListSpacing",
|
|
74
|
-
"TypeParameterListSpacing",
|
|
75
|
-
"UnnecessaryParenthesesBeforeTrailingLambda",
|
|
76
|
-
"Wrapping",
|
|
77
|
-
// style / comments — these implement autoCorrect in their detekt rule classes
|
|
78
|
-
"OptionalUnit",
|
|
79
|
-
"OptionalAbstractKeyword",
|
|
80
|
-
"ProtectedMemberInFinalClass",
|
|
81
|
-
"UnnecessaryParentheses",
|
|
82
|
-
"UnusedImports",
|
|
83
|
-
"UnusedPrivateClass",
|
|
84
|
-
"RedundantVisibilityModifierRule",
|
|
85
|
-
]);
|
|
86
|
-
export function findDetektConfig(cwd) {
|
|
87
|
-
for (const candidate of DETEKT_CONFIG_CANDIDATES) {
|
|
88
|
-
const full = path.join(cwd, candidate);
|
|
89
|
-
if (fs.existsSync(full))
|
|
90
|
-
return full;
|
|
91
|
-
}
|
|
92
|
-
return undefined;
|
|
93
|
-
}
|
|
94
|
-
// detekt text output: /path/file.kt:10:5: error: Message [RuleId]
|
|
95
|
-
function parseDetektOutput(raw, filePath, cwd) {
|
|
96
|
-
const diagnostics = [];
|
|
97
|
-
const pattern = /^(.+?):(\d+):(\d+): (error|warning): (.+?)(?:\s+\[([^\]]+)\])?$/gm;
|
|
98
|
-
const absTarget = path.resolve(cwd, filePath);
|
|
99
|
-
for (const match of raw.matchAll(pattern)) {
|
|
100
|
-
const [, file, lineStr, colStr, level, message, rule] = match;
|
|
101
|
-
// #3278: one seam for reported-path attribution — see javac.ts.
|
|
102
|
-
if (!pathsEqual(path.resolve(cwd, file.trim()), absTarget))
|
|
103
|
-
continue;
|
|
104
|
-
const severity = level === "error" ? "error" : "warning";
|
|
105
|
-
const lineNum = Number.parseInt(lineStr, 10);
|
|
106
|
-
const colNum = Number.parseInt(colStr, 10);
|
|
107
|
-
const ruleId = rule ?? "detekt";
|
|
108
|
-
const fixable = rule ? DETEKT_FIXABLE_RULES.has(rule) : false;
|
|
109
|
-
diagnostics.push({
|
|
110
|
-
id: `detekt-${ruleId}-${lineNum}-${colNum}`,
|
|
111
|
-
message: rule ? `[${rule}] ${message}` : message,
|
|
112
|
-
filePath,
|
|
113
|
-
line: lineNum,
|
|
114
|
-
column: colNum,
|
|
115
|
-
severity,
|
|
116
|
-
semantic: severity === "error" ? "blocking" : "warning",
|
|
117
|
-
tool: "detekt",
|
|
118
|
-
rule: ruleId,
|
|
119
|
-
defectClass: "style",
|
|
120
|
-
fixable,
|
|
121
|
-
fixSuggestion: fixable
|
|
122
|
-
? "Run `detekt --auto-correct` to apply the deterministic auto-correction for this rule."
|
|
123
|
-
: undefined,
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
return diagnostics;
|
|
127
|
-
}
|
|
128
|
-
const detektRunner = {
|
|
129
|
-
id: "detekt",
|
|
130
|
-
appliesTo: ["kotlin"],
|
|
131
|
-
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
132
|
-
timeoutMs: 90_000,
|
|
133
|
-
skipTestFiles: false,
|
|
134
|
-
async run(ctx) {
|
|
135
|
-
const cwd = resolveRunnerCwd(ctx, "detekt");
|
|
136
|
-
const policy = getLinterPolicyForCwd(ctx.filePath, cwd);
|
|
137
|
-
if (policy && !policy.preferredRunners.includes("detekt")) {
|
|
138
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
139
|
-
}
|
|
140
|
-
const configPath = findDetektConfig(cwd);
|
|
141
|
-
if (!configPath) {
|
|
142
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
143
|
-
}
|
|
144
|
-
const cmd = (await detekt.isAvailableAsync(cwd))
|
|
145
|
-
? detekt.getCommand(cwd)
|
|
146
|
-
: null;
|
|
147
|
-
if (!cmd)
|
|
148
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
149
|
-
const absPath = path.resolve(cwd, ctx.filePath);
|
|
150
|
-
const result = await safeSpawnAsync(cmd, ["--input", absPath, "--config", configPath], { cwd, timeout: 60000 });
|
|
151
|
-
// #1948: detekt reports across both streams, so the gate and the parser
|
|
152
|
-
// read the same concatenated string. A nonzero exit that yields zero
|
|
153
|
-
// findings out of real output is a parser break, not clean Kotlin.
|
|
154
|
-
const raw = `${result.stdout ?? ""}${result.stderr ?? ""}`;
|
|
155
|
-
const run = parseToolRun("detekt", {
|
|
156
|
-
result,
|
|
157
|
-
output: raw,
|
|
158
|
-
// EXIT TABLE (detekt 1.23 measured fixture): 0 clean; 1 findings; 2 error; other nonzero rejected.
|
|
159
|
-
exitCodes: { ran: [1, 2] },
|
|
160
|
-
}, (out) => parseDetektOutput(out, ctx.filePath, cwd));
|
|
161
|
-
if (run.skipped)
|
|
162
|
-
return run.skipped;
|
|
163
|
-
const diagnostics = run.diagnostics;
|
|
164
|
-
if (diagnostics.length === 0) {
|
|
165
|
-
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
166
|
-
}
|
|
167
|
-
const hasErrors = diagnostics.some((d) => d.severity === "error");
|
|
168
|
-
return {
|
|
169
|
-
status: hasErrors ? "failed" : "succeeded",
|
|
170
|
-
diagnostics,
|
|
171
|
-
semantic: hasErrors ? "blocking" : "warning",
|
|
172
|
-
};
|
|
173
|
-
},
|
|
174
|
-
};
|
|
175
|
-
export default detektRunner;
|
|
176
|
-
export { DETEKT_FIXABLE_RULES, parseDetektOutput };
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import * as fs from "node:fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
4
|
-
import { pathsEqual } from "../../path-utils.js";
|
|
5
|
-
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
6
|
-
import { PRIORITY } from "../priorities.js";
|
|
7
|
-
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
8
|
-
import { finishParsedRun, parseToolRun } from "./utils/tool-failure.js";
|
|
9
|
-
const dotnet = createAvailabilityChecker("dotnet", ".exe");
|
|
10
|
-
function findProjectTarget(cwd) {
|
|
11
|
-
const entries = fs.readdirSync(cwd);
|
|
12
|
-
const solution = entries.find((entry) => /\.(sln|slnx)$/i.test(entry));
|
|
13
|
-
if (solution)
|
|
14
|
-
return solution;
|
|
15
|
-
return entries.find((entry) => /\.(csproj)$/i.test(entry));
|
|
16
|
-
}
|
|
17
|
-
function isDotnetRuleId(value) {
|
|
18
|
-
if (value.length < 2)
|
|
19
|
-
return false;
|
|
20
|
-
let sawDigit = false;
|
|
21
|
-
for (const char of value) {
|
|
22
|
-
const code = char.charCodeAt(0);
|
|
23
|
-
const isLetter = (code >= 65 && code <= 90) || (code >= 97 && code <= 122);
|
|
24
|
-
const isDigit = code >= 48 && code <= 57;
|
|
25
|
-
if (isDigit) {
|
|
26
|
-
sawDigit = true;
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
if (!isLetter || sawDigit)
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
return sawDigit;
|
|
33
|
-
}
|
|
34
|
-
function parseDotnetDiagnosticLine(line) {
|
|
35
|
-
const lower = line.toLowerCase();
|
|
36
|
-
const fileEnd = lower.lastIndexOf(".cs(");
|
|
37
|
-
if (fileEnd < 0)
|
|
38
|
-
return null;
|
|
39
|
-
const reportedFile = line.slice(0, fileEnd + 3).trim();
|
|
40
|
-
let cursor = fileEnd + 4;
|
|
41
|
-
const lineStart = cursor;
|
|
42
|
-
while (cursor < line.length &&
|
|
43
|
-
line.charCodeAt(cursor) >= 48 &&
|
|
44
|
-
line.charCodeAt(cursor) <= 57) {
|
|
45
|
-
cursor += 1;
|
|
46
|
-
}
|
|
47
|
-
if (cursor === lineStart || line[cursor] !== ",")
|
|
48
|
-
return null;
|
|
49
|
-
const lineStr = line.slice(lineStart, cursor);
|
|
50
|
-
cursor += 1;
|
|
51
|
-
const colStart = cursor;
|
|
52
|
-
while (cursor < line.length &&
|
|
53
|
-
line.charCodeAt(cursor) >= 48 &&
|
|
54
|
-
line.charCodeAt(cursor) <= 57) {
|
|
55
|
-
cursor += 1;
|
|
56
|
-
}
|
|
57
|
-
if (cursor === colStart || line.slice(cursor, cursor + 3) !== "): ")
|
|
58
|
-
return null;
|
|
59
|
-
const colStr = line.slice(colStart, cursor);
|
|
60
|
-
cursor += 3;
|
|
61
|
-
const tailLower = line.slice(cursor).toLowerCase();
|
|
62
|
-
let severityLabel;
|
|
63
|
-
if (tailLower.startsWith("error ")) {
|
|
64
|
-
severityLabel = "error";
|
|
65
|
-
cursor += "error ".length;
|
|
66
|
-
}
|
|
67
|
-
else if (tailLower.startsWith("warning ")) {
|
|
68
|
-
severityLabel = "warning";
|
|
69
|
-
cursor += "warning ".length;
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
const colon = line.indexOf(":", cursor);
|
|
75
|
-
if (colon < 0)
|
|
76
|
-
return null;
|
|
77
|
-
const rule = line.slice(cursor, colon).trim();
|
|
78
|
-
if (!isDotnetRuleId(rule))
|
|
79
|
-
return null;
|
|
80
|
-
let message = line.slice(colon + 1).trim();
|
|
81
|
-
if (message.endsWith("]")) {
|
|
82
|
-
const projectSuffix = message.lastIndexOf(" [");
|
|
83
|
-
if (projectSuffix >= 0)
|
|
84
|
-
message = message.slice(0, projectSuffix).trimEnd();
|
|
85
|
-
}
|
|
86
|
-
return { reportedFile, lineStr, colStr, severityLabel, rule, message };
|
|
87
|
-
}
|
|
88
|
-
function parseDotnetBuildOutput(raw, filePath, cwd) {
|
|
89
|
-
const diagnostics = [];
|
|
90
|
-
const absTarget = path.resolve(cwd, filePath);
|
|
91
|
-
for (const line of raw.split(/\r?\n/)) {
|
|
92
|
-
const parsed = parseDotnetDiagnosticLine(line);
|
|
93
|
-
if (!parsed)
|
|
94
|
-
continue;
|
|
95
|
-
const { reportedFile, lineStr, colStr, severityLabel, rule, message } = parsed;
|
|
96
|
-
// #3278: one seam for reported-path attribution — see javac.ts.
|
|
97
|
-
if (!pathsEqual(path.resolve(cwd, reportedFile), absTarget))
|
|
98
|
-
continue;
|
|
99
|
-
const severity = severityLabel.toLowerCase() === "error" ? "error" : "warning";
|
|
100
|
-
const lineNum = Number.parseInt(lineStr, 10) || 1;
|
|
101
|
-
const colNum = Number.parseInt(colStr, 10) || 1;
|
|
102
|
-
diagnostics.push({
|
|
103
|
-
id: `dotnet-build-${rule}-${lineNum}-${colNum}`,
|
|
104
|
-
message: `[${rule}] ${message.trim()}`,
|
|
105
|
-
filePath,
|
|
106
|
-
line: lineNum,
|
|
107
|
-
column: colNum,
|
|
108
|
-
severity,
|
|
109
|
-
semantic: severity === "error" ? "blocking" : "warning",
|
|
110
|
-
tool: "dotnet-build",
|
|
111
|
-
rule,
|
|
112
|
-
fixable: false,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
return diagnostics;
|
|
116
|
-
}
|
|
117
|
-
const dotnetBuildRunner = {
|
|
118
|
-
id: "dotnet-build",
|
|
119
|
-
appliesTo: ["csharp"],
|
|
120
|
-
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
121
|
-
timeoutMs: 90_000,
|
|
122
|
-
skipTestFiles: false,
|
|
123
|
-
async run(ctx) {
|
|
124
|
-
const cwd = resolveRunnerCwd(ctx, "dotnet-build");
|
|
125
|
-
if (!(await dotnet.isAvailableAsync(cwd))) {
|
|
126
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
127
|
-
}
|
|
128
|
-
const cmd = dotnet.getCommand(cwd);
|
|
129
|
-
if (!cmd) {
|
|
130
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
131
|
-
}
|
|
132
|
-
const target = findProjectTarget(cwd);
|
|
133
|
-
if (!target) {
|
|
134
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
135
|
-
}
|
|
136
|
-
const result = await safeSpawnAsync(cmd, ["build", target, "--nologo", "--verbosity", "minimal"], {
|
|
137
|
-
cwd,
|
|
138
|
-
timeout: 60000,
|
|
139
|
-
});
|
|
140
|
-
const raw = `${result.stdout ?? ""}\n${result.stderr ?? ""}`.trim();
|
|
141
|
-
const parsed = parseToolRun("dotnet-build", {
|
|
142
|
-
result,
|
|
143
|
-
output: raw,
|
|
144
|
-
// EXIT TABLE (.NET SDK 8 measured fixture): 0 clean; 1 findings; 2 error; other nonzero rejected.
|
|
145
|
-
exitCodes: { ran: [1, 2] },
|
|
146
|
-
}, (output) => parseDotnetBuildOutput(output, ctx.filePath, cwd));
|
|
147
|
-
if (parsed.skipped)
|
|
148
|
-
return parsed.skipped;
|
|
149
|
-
return finishParsedRun({
|
|
150
|
-
tool: "dotnet-build",
|
|
151
|
-
ctx,
|
|
152
|
-
result,
|
|
153
|
-
diagnostics: parsed.diagnostics,
|
|
154
|
-
classify: (diagnostics) => {
|
|
155
|
-
const hasErrors = diagnostics.some((d) => d.severity === "error");
|
|
156
|
-
return {
|
|
157
|
-
status: hasErrors ? "failed" : "succeeded",
|
|
158
|
-
semantic: hasErrors ? "blocking" : "warning",
|
|
159
|
-
};
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
},
|
|
163
|
-
};
|
|
164
|
-
export default dotnetBuildRunner;
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import * as fs from "node:fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { getProjectDataDir } from "../../file-utils.js";
|
|
4
|
-
import { pathsEqual } from "../../path-utils.js";
|
|
5
|
-
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
6
|
-
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
7
|
-
import { PRIORITY } from "../priorities.js";
|
|
8
|
-
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
9
|
-
import { finishParsedRun, parseToolRun } from "./utils/tool-failure.js";
|
|
10
|
-
// Per-cwd cached `--version` probes (#120). Before this, each dispatch
|
|
11
|
-
// invocation fired a fresh `safeSpawnAsync` per command — once per Elixir
|
|
12
|
-
// file save.
|
|
13
|
-
const mix = createAvailabilityChecker("mix", ".bat");
|
|
14
|
-
const elixirc = createAvailabilityChecker("elixirc", ".bat");
|
|
15
|
-
function hasMixExs(cwd) {
|
|
16
|
-
return fs.existsSync(path.join(cwd, "mix.exs"));
|
|
17
|
-
}
|
|
18
|
-
// Elixir 1.16+ emits diagnostics in a multi-line "code snippet" format where
|
|
19
|
-
// the file:line:col lives on a trailing `└─ path:line:col` line, several lines
|
|
20
|
-
// after the `error:`/`warning:` header:
|
|
21
|
-
//
|
|
22
|
-
// warning: variable "x" is unused
|
|
23
|
-
// │
|
|
24
|
-
// 3 │ x = 1
|
|
25
|
-
// │ ~
|
|
26
|
-
// │
|
|
27
|
-
// └─ lib/foo.ex:3:5: Foo.bar/0
|
|
28
|
-
//
|
|
29
|
-
// Older Elixir put the location on the line immediately after `warning:` and
|
|
30
|
-
// reported compile errors as a single `** (Kind) path:line:col: message` line.
|
|
31
|
-
// We support both so the runner works across toolchain versions.
|
|
32
|
-
const ELIXIR_SNIPPET_LOCATION = /└─\s+(.+?):(\d+)(?::(\d+))?(?::|$)/;
|
|
33
|
-
function parseElixirOutput(raw, filePath, cwd = process.cwd()) {
|
|
34
|
-
const diagnostics = [];
|
|
35
|
-
const resolvedTarget = path.resolve(cwd, filePath);
|
|
36
|
-
const lines = raw.split(/\r?\n/);
|
|
37
|
-
// elixirc reports paths RELATIVE to its cwd (e.g. `bad.ex`, not the absolute
|
|
38
|
-
// path we passed), so resolve the reported path against the runner cwd — not
|
|
39
|
-
// process.cwd(). Two resolved spellings of ONE file still differ in ways
|
|
40
|
-
// only the filesystem can settle — Elixir 1.16+ normalizes to a lowercase
|
|
41
|
-
// drive letter and forward slashes (`c:/...`), which never string-equals
|
|
42
|
-
// `C:\...` on Windows — so ask `pathsEqual`, the repo's on-disk identity
|
|
43
|
-
// seam, instead of hand-rolling a win32 case fold here. It folds case
|
|
44
|
-
// exactly where the filesystem does and nowhere else, which a
|
|
45
|
-
// `process.platform` test cannot express; `terragrunt.ts:90` asks the same
|
|
46
|
-
// question the same way (#1193).
|
|
47
|
-
const matchesTarget = (sourcePath) => pathsEqual(path.resolve(cwd, sourcePath.trim()), resolvedTarget);
|
|
48
|
-
for (let index = 0; index < lines.length; index++) {
|
|
49
|
-
const line = lines[index];
|
|
50
|
-
// Defense-in-depth: cap line length before regex matching. The input is
|
|
51
|
-
// trusted, bounded compiler output and the patterns have no exponential
|
|
52
|
-
// backtracking, but this bounds worst-case work regardless (ReDoS guard).
|
|
53
|
-
if (line.length > 2000)
|
|
54
|
-
continue;
|
|
55
|
-
// Legacy one-line compile error: ** (CompileError) path:line:col: message
|
|
56
|
-
const syntax = line.match(/^\*\* \(([^)]+)\)\s+(.+?):(\d+):(?:(\d+):)?\s*(.+)$/);
|
|
57
|
-
if (syntax) {
|
|
58
|
-
const [, kind, sourcePath, lineStr, colStr, message] = syntax;
|
|
59
|
-
if (!matchesTarget(sourcePath))
|
|
60
|
-
continue;
|
|
61
|
-
diagnostics.push({
|
|
62
|
-
id: `elixir-check-${kind}-${lineStr}-${colStr || "1"}`,
|
|
63
|
-
message: `[${kind}] ${message.trim()}`,
|
|
64
|
-
filePath,
|
|
65
|
-
line: Number.parseInt(lineStr, 10) || 1,
|
|
66
|
-
column: Number.parseInt(colStr || "1", 10) || 1,
|
|
67
|
-
severity: "error",
|
|
68
|
-
semantic: "blocking",
|
|
69
|
-
tool: "elixir-check",
|
|
70
|
-
rule: kind,
|
|
71
|
-
fixable: false,
|
|
72
|
-
});
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
// error:/warning: header — may be bare (legacy) or indented (1.16+).
|
|
76
|
-
const header = line.match(/^\s*(error|warning):\s+(.+)$/);
|
|
77
|
-
if (!header)
|
|
78
|
-
continue;
|
|
79
|
-
const [, severityLabel, message] = header;
|
|
80
|
-
const severity = severityLabel === "error" ? "error" : "warning";
|
|
81
|
-
// New format: scan forward for the `└─ path:line:col` snippet footer.
|
|
82
|
-
let located = false;
|
|
83
|
-
for (let lookahead = index + 1; lookahead < lines.length && lookahead <= index + 12; lookahead++) {
|
|
84
|
-
const next = lines[lookahead];
|
|
85
|
-
// A blank gap or another header ends this diagnostic block.
|
|
86
|
-
if (/^\s*(error|warning):\s+/.test(next))
|
|
87
|
-
break;
|
|
88
|
-
const snippet = next.match(ELIXIR_SNIPPET_LOCATION);
|
|
89
|
-
if (snippet) {
|
|
90
|
-
const [, sourcePath, lineStr, colStr] = snippet;
|
|
91
|
-
if (matchesTarget(sourcePath)) {
|
|
92
|
-
diagnostics.push({
|
|
93
|
-
id: `elixir-check-${severity}-${lineStr}-${colStr || "1"}`,
|
|
94
|
-
message: severity === "error"
|
|
95
|
-
? `[error] ${message.trim()}`
|
|
96
|
-
: message.trim(),
|
|
97
|
-
filePath,
|
|
98
|
-
line: Number.parseInt(lineStr, 10) || 1,
|
|
99
|
-
column: Number.parseInt(colStr || "1", 10) || 1,
|
|
100
|
-
severity,
|
|
101
|
-
semantic: severity === "error" ? "blocking" : "warning",
|
|
102
|
-
tool: "elixir-check",
|
|
103
|
-
rule: severity === "error" ? "error" : "warning",
|
|
104
|
-
fixable: false,
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
located = true;
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
if (located)
|
|
112
|
-
continue;
|
|
113
|
-
// Legacy format: location on the immediately following line.
|
|
114
|
-
const location = lines[index + 1]?.match(/^\s+(.+?):(\d+):(?:(\d+):)?$/);
|
|
115
|
-
if (!location)
|
|
116
|
-
continue;
|
|
117
|
-
const [, sourcePath, lineStr, colStr] = location;
|
|
118
|
-
if (!matchesTarget(sourcePath))
|
|
119
|
-
continue;
|
|
120
|
-
diagnostics.push({
|
|
121
|
-
id: `elixir-check-${severity}-${lineStr}-${colStr || "1"}`,
|
|
122
|
-
message: severity === "error" ? `[error] ${message.trim()}` : message.trim(),
|
|
123
|
-
filePath,
|
|
124
|
-
line: Number.parseInt(lineStr, 10) || 1,
|
|
125
|
-
column: Number.parseInt(colStr || "1", 10) || 1,
|
|
126
|
-
severity,
|
|
127
|
-
semantic: severity === "error" ? "blocking" : "warning",
|
|
128
|
-
tool: "elixir-check",
|
|
129
|
-
rule: severity === "error" ? "error" : "warning",
|
|
130
|
-
fixable: false,
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
return diagnostics;
|
|
134
|
-
}
|
|
135
|
-
const elixirCheckRunner = {
|
|
136
|
-
id: "elixir-check",
|
|
137
|
-
appliesTo: ["elixir"],
|
|
138
|
-
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
139
|
-
skipTestFiles: false,
|
|
140
|
-
async run(ctx) {
|
|
141
|
-
const cwd = resolveRunnerCwd(ctx, "elixir-check");
|
|
142
|
-
const absPath = path.resolve(cwd, ctx.filePath);
|
|
143
|
-
let command;
|
|
144
|
-
let args = [];
|
|
145
|
-
if (hasMixExs(cwd) && (await mix.isAvailableAsync(cwd))) {
|
|
146
|
-
command = "mix";
|
|
147
|
-
args = ["compile", "--warnings-as-errors"];
|
|
148
|
-
}
|
|
149
|
-
else if (await elixirc.isAvailableAsync(cwd)) {
|
|
150
|
-
const outDir = path.join(getProjectDataDir(cwd), "elixir-check");
|
|
151
|
-
fs.mkdirSync(outDir, { recursive: true });
|
|
152
|
-
command = "elixirc";
|
|
153
|
-
args = ["-o", outDir, absPath];
|
|
154
|
-
}
|
|
155
|
-
if (!command) {
|
|
156
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
157
|
-
}
|
|
158
|
-
const result = await safeSpawnAsync(command, args, {
|
|
159
|
-
cwd,
|
|
160
|
-
timeout: 30000,
|
|
161
|
-
});
|
|
162
|
-
const raw = `${result.stderr || ""}\n${result.stdout || ""}`;
|
|
163
|
-
const hasProjectContext = command === "mix";
|
|
164
|
-
const parsed = parseToolRun("elixir-check", {
|
|
165
|
-
result,
|
|
166
|
-
output: raw,
|
|
167
|
-
// EXIT TABLE (Elixir 1.16 measured fixture): 0 clean; 1 findings; 2 error; other nonzero rejected.
|
|
168
|
-
exitCodes: { ran: [1, 2] },
|
|
169
|
-
}, (out) => parseElixirOutput(out, ctx.filePath, cwd).map((d) => hasProjectContext
|
|
170
|
-
? d
|
|
171
|
-
: {
|
|
172
|
-
...d,
|
|
173
|
-
// A direct elixirc invocation cannot resolve Mix dependencies.
|
|
174
|
-
// Standalone findings inform the agent, but cannot block it.
|
|
175
|
-
semantic: "warning",
|
|
176
|
-
}));
|
|
177
|
-
if (parsed.skipped)
|
|
178
|
-
return parsed.skipped;
|
|
179
|
-
return finishParsedRun({
|
|
180
|
-
tool: "elixir-check",
|
|
181
|
-
ctx,
|
|
182
|
-
result,
|
|
183
|
-
diagnostics: parsed.diagnostics,
|
|
184
|
-
classify: (diagnostics) => {
|
|
185
|
-
const hasBlocking = diagnostics.some((d) => d.semantic === "blocking");
|
|
186
|
-
return {
|
|
187
|
-
status: hasBlocking ? "failed" : "succeeded",
|
|
188
|
-
semantic: hasBlocking ? "blocking" : "warning",
|
|
189
|
-
};
|
|
190
|
-
},
|
|
191
|
-
});
|
|
192
|
-
},
|
|
193
|
-
};
|
|
194
|
-
export default elixirCheckRunner;
|
|
195
|
-
export { parseElixirOutput };
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint runner for dispatch system
|
|
3
|
-
*
|
|
4
|
-
* Runs ESLint on JS/TS files when an ESLint config is present in the project.
|
|
5
|
-
* Prefers the local node_modules installation over global.
|
|
6
|
-
*
|
|
7
|
-
* Gate: skips when no ESLint config is detected (project uses Biome/OxLint instead).
|
|
8
|
-
*/
|
|
9
|
-
import * as path from "node:path";
|
|
10
|
-
import { pathsEqual } from "../../path-utils.js";
|
|
11
|
-
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
12
|
-
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
13
|
-
import { getAutofixCapability, hasEslintConfig } from "../../tool-policy.js";
|
|
14
|
-
import { PRIORITY } from "../priorities.js";
|
|
15
|
-
import { createCwdCachedProbe, resolveToolCommand, } from "./utils/runner-helpers.js";
|
|
16
|
-
import { finishParsedRun, parseToolRun } from "./utils/tool-failure.js";
|
|
17
|
-
const ESLINT_PROBE_BUDGET_MS = 5000;
|
|
18
|
-
// Per-cwd cached eslint `--version` verification (#120). Before this, every
|
|
19
|
-
// dispatch invocation ran a fresh `safeSpawnAsync(cmd, ["--version"])` after
|
|
20
|
-
// the local cmd resolution. The probe is cached per cwd because
|
|
21
|
-
// `resolveToolCommand("eslint")` is deterministic from cwd; the underlying
|
|
22
|
-
// cmd identity is captured inside the probe closure.
|
|
23
|
-
//
|
|
24
|
-
// The verdict is governed by the shared availability policy (#1494): the probe
|
|
25
|
-
// hands back the spawn result, so one stalled probe on the first JS/TS save
|
|
26
|
-
// expires on a cooldown instead of disabling eslint for the whole session.
|
|
27
|
-
function makeEslintProbe(cmd) {
|
|
28
|
-
return createCwdCachedProbe((cwd) => safeSpawnAsync(cmd, ["--version"], {
|
|
29
|
-
timeout: ESLINT_PROBE_BUDGET_MS,
|
|
30
|
-
cwd,
|
|
31
|
-
}), {
|
|
32
|
-
tool: "eslint",
|
|
33
|
-
budgetMs: ESLINT_PROBE_BUDGET_MS,
|
|
34
|
-
flightKeyComponent: cmd,
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
const eslintAvailabilityByCmd = new Map();
|
|
38
|
-
function getEslintProbe(cmd) {
|
|
39
|
-
const existing = eslintAvailabilityByCmd.get(cmd);
|
|
40
|
-
if (existing)
|
|
41
|
-
return existing;
|
|
42
|
-
const created = makeEslintProbe(cmd);
|
|
43
|
-
eslintAvailabilityByCmd.set(cmd, created);
|
|
44
|
-
return created;
|
|
45
|
-
}
|
|
46
|
-
function parseEslintJson(raw, filePath, cwd) {
|
|
47
|
-
try {
|
|
48
|
-
const results = JSON.parse(raw);
|
|
49
|
-
const autofix = getAutofixCapability("eslint");
|
|
50
|
-
const diagnostics = [];
|
|
51
|
-
const absTarget = path.resolve(cwd, filePath);
|
|
52
|
-
for (const fileResult of results) {
|
|
53
|
-
// #3295: flat config `files`/`ignores` and a directory argv both put a
|
|
54
|
-
// SECOND result in this array; each names its own `filePath`.
|
|
55
|
-
if (fileResult.filePath &&
|
|
56
|
-
!pathsEqual(path.resolve(cwd, fileResult.filePath), absTarget))
|
|
57
|
-
continue;
|
|
58
|
-
for (const msg of fileResult.messages) {
|
|
59
|
-
const severity = msg.severity === 2 ? "error" : "warning";
|
|
60
|
-
diagnostics.push({
|
|
61
|
-
id: `eslint:${msg.ruleId ?? "unknown"}:${msg.line}`,
|
|
62
|
-
message: msg.ruleId ? `${msg.ruleId}: ${msg.message}` : msg.message,
|
|
63
|
-
filePath,
|
|
64
|
-
line: msg.line ?? 1,
|
|
65
|
-
column: msg.column ?? 1,
|
|
66
|
-
severity,
|
|
67
|
-
semantic: severity === "error" ? "blocking" : "warning",
|
|
68
|
-
tool: "eslint",
|
|
69
|
-
rule: msg.ruleId ?? undefined,
|
|
70
|
-
fixable: !!msg.fix,
|
|
71
|
-
autoFixAvailable: !!msg.fix && (autofix?.safePipelineAutofix ?? false),
|
|
72
|
-
fixKind: !!msg.fix && autofix?.fixKind !== "none"
|
|
73
|
-
? autofix?.fixKind
|
|
74
|
-
: undefined,
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return { diagnostics };
|
|
79
|
-
}
|
|
80
|
-
catch (err) {
|
|
81
|
-
return {
|
|
82
|
-
diagnostics: [],
|
|
83
|
-
parseError: err instanceof Error ? err.message : String(err),
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const eslintRunner = {
|
|
88
|
-
id: "eslint",
|
|
89
|
-
appliesTo: ["jsts"],
|
|
90
|
-
priority: PRIORITY.LINT_SECONDARY,
|
|
91
|
-
async run(ctx) {
|
|
92
|
-
const cwd = resolveRunnerCwd(ctx, "eslint");
|
|
93
|
-
const userHasConfig = hasEslintConfig(cwd);
|
|
94
|
-
// Only run if project has an ESLint config.
|
|
95
|
-
if (!userHasConfig) {
|
|
96
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
97
|
-
}
|
|
98
|
-
const cmd = resolveToolCommand(cwd, "eslint") ?? "eslint";
|
|
99
|
-
// Verify ESLint is actually executable (cached per cwd, see getEslintProbe).
|
|
100
|
-
if (!(await getEslintProbe(cmd)(cwd))) {
|
|
101
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
102
|
-
}
|
|
103
|
-
const result = await safeSpawnAsync(cmd, ["--format", "json", "--no-error-on-unmatched-pattern", ctx.filePath], { timeout: 30000, cwd });
|
|
104
|
-
// Exit table: 0 is clean-or-findings, and 1/2 are ran outcomes whose
|
|
105
|
-
// JSON parser decides whether findings or a parse/config error reached the
|
|
106
|
-
// user. In particular, status 2 carries file-local fatal parse messages
|
|
107
|
-
// as JSON and must not be discarded before parsing.
|
|
108
|
-
//
|
|
109
|
-
// ESLint exits 0 whenever nothing reached ERROR severity — that
|
|
110
|
-
// includes a run that found only warnings (#1954), which also prints a
|
|
111
|
-
// full JSON report. So parse stdout unconditionally and branch on the
|
|
112
|
-
// parsed diagnostic count instead of letting the exit code discard the
|
|
113
|
-
// warning case. Stderr is only a fallback for a failing run whose
|
|
114
|
-
// stdout went missing; parsing stderr noise on a healthy exit-0 run
|
|
115
|
-
// would turn deprecation chatter into spurious parse-error findings.
|
|
116
|
-
const stdout = result.stdout ?? "";
|
|
117
|
-
let raw = stdout;
|
|
118
|
-
if (raw.length === 0 && result.status !== 0) {
|
|
119
|
-
raw = result.stderr || "";
|
|
120
|
-
}
|
|
121
|
-
const parsed = parseToolRun("eslint", {
|
|
122
|
-
result,
|
|
123
|
-
output: raw,
|
|
124
|
-
// EXIT TABLE (ESLint 9.10 docs https://eslint.org/docs/latest/use/command-line-interface): 0 clean; 1 findings; 2 fatal findings/error; other nonzero rejected.
|
|
125
|
-
exitCodes: { ran: [1, 2] },
|
|
126
|
-
}, (rawOutput) => parseEslintJson(rawOutput, ctx.filePath, cwd).diagnostics);
|
|
127
|
-
if (parsed.skipped)
|
|
128
|
-
return parsed.skipped;
|
|
129
|
-
return finishParsedRun({
|
|
130
|
-
tool: "eslint",
|
|
131
|
-
ctx,
|
|
132
|
-
result,
|
|
133
|
-
diagnostics: parsed.diagnostics,
|
|
134
|
-
});
|
|
135
|
-
},
|
|
136
|
-
};
|
|
137
|
-
export default eslintRunner;
|