pi-lens 4.3.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1064 -0
- package/README.md +115 -25
- package/config/dependency-cruiser-eager-allowlist.json +6 -2
- package/dist/chunk-22AVIGXS.js +560 -0
- package/dist/chunk-27BBHSZC.js +106 -0
- package/dist/chunk-2BEMIWEW.js +51 -0
- package/dist/chunk-2EECBNC5.js +89 -0
- package/dist/chunk-34U7PLGE.js +23 -0
- package/dist/chunk-3I5QFT3N.js +181 -0
- package/dist/chunk-3MED75HT.js +37 -0
- package/dist/chunk-47D2BO4S.js +87 -0
- package/dist/chunk-4RERDEXR.js +348 -0
- package/dist/chunk-4W2PLC4J.js +27 -0
- package/dist/chunk-52H5B5TC.js +202 -0
- package/dist/chunk-54B42YRX.js +27 -0
- package/dist/chunk-5RXBNSW2.js +266 -0
- package/dist/chunk-5THXD6X5.js +201 -0
- package/dist/chunk-5W3R6LFT.js +24 -0
- package/dist/chunk-5ZEJHV35.js +341 -0
- package/dist/chunk-6P62QVEA.js +118 -0
- package/dist/chunk-6QIUX4EP.js +459 -0
- package/dist/chunk-6VCD4VKZ.js +78 -0
- package/dist/chunk-7F72PXY2.js +326 -0
- package/dist/chunk-7FBF7NPR.js +998 -0
- package/dist/chunk-7U2IDNXN.js +37 -0
- package/dist/chunk-ABBOA7UD.js +157 -0
- package/dist/chunk-AHDW3GPE.js +50 -0
- package/dist/chunk-AJ3QXTRQ.js +756 -0
- package/dist/chunk-AJVLWNFN.js +1610 -0
- package/dist/chunk-AJXODZY6.js +112 -0
- package/dist/chunk-ARFCXG7S.js +84 -0
- package/dist/chunk-AS44CFQ4.js +708 -0
- package/dist/chunk-AWE5TMPO.js +38 -0
- package/dist/chunk-B3I2UUT4.js +4692 -0
- package/dist/chunk-BRJKOBZP.js +331 -0
- package/dist/chunk-BW5KFIQC.js +59 -0
- package/dist/chunk-C2AUYXQH.js +149 -0
- package/dist/chunk-CGGAIP7J.js +29 -0
- package/dist/chunk-D6QS3U6M.js +30 -0
- package/dist/chunk-DFVMIKMQ.js +349 -0
- package/dist/chunk-DIULIWKU.js +169 -0
- package/dist/chunk-DQ2NZ7C4.js +2317 -0
- package/dist/chunk-E2WFBRHM.js +213 -0
- package/dist/chunk-E4MAEDPM.js +50 -0
- package/dist/chunk-EOKRQ3SA.js +30 -0
- package/dist/chunk-F3AU2TMM.js +2626 -0
- package/dist/chunk-F3P7VQ7H.js +170 -0
- package/dist/chunk-FC4RP4I2.js +12 -0
- package/dist/chunk-FJNKANOS.js +32 -0
- package/dist/chunk-GUOGVTCQ.js +146 -0
- package/dist/chunk-GVXA6CCE.js +18 -0
- package/dist/chunk-HHYAELLJ.js +2334 -0
- package/dist/chunk-HMFXILPV.js +83 -0
- package/dist/chunk-HVUZXSWK.js +421 -0
- package/dist/chunk-HWBZIGMJ.js +62 -0
- package/dist/chunk-I3R7GKDR.js +17 -0
- package/dist/chunk-I7SPGOWI.js +55 -0
- package/dist/chunk-IIXOAGHR.js +38 -0
- package/dist/chunk-IVP5KAB7.js +2250 -0
- package/dist/chunk-IXEBJSUE.js +22 -0
- package/dist/chunk-JOLITGCC.js +27 -0
- package/dist/chunk-K6VYLB2U.js +145 -0
- package/dist/chunk-LJDODBBZ.js +78 -0
- package/dist/chunk-LNAKEO63.js +78 -0
- package/dist/chunk-LSMJ6KBE.js +4139 -0
- package/dist/chunk-LW6XKDZQ.js +5565 -0
- package/dist/chunk-N3YQJI6O.js +899 -0
- package/dist/chunk-NABLC7W3.js +148 -0
- package/dist/chunk-NKOUFPQF.js +659 -0
- package/dist/chunk-NL5GLMFI.js +211 -0
- package/dist/chunk-NMABWBZN.js +327 -0
- package/dist/chunk-NTHH2J74.js +27 -0
- package/dist/chunk-NTUJEGDZ.js +59 -0
- package/dist/chunk-NXL4FFQQ.js +47 -0
- package/dist/chunk-NXPS2L6U.js +466 -0
- package/dist/chunk-O5WILGMI.js +42 -0
- package/dist/chunk-O6TQT6RI.js +48 -0
- package/dist/chunk-OAXNDZJ7.js +323 -0
- package/dist/chunk-ODEEOXPH.js +44 -0
- package/dist/chunk-OQGFCZJ4.js +4533 -0
- package/dist/chunk-ORTMY4Q4.js +282 -0
- package/dist/chunk-OS32RNR2.js +442 -0
- package/dist/chunk-PAK6IDME.js +189 -0
- package/dist/chunk-PWFHBTSF.js +406 -0
- package/dist/chunk-Q5U6FMDI.js +2352 -0
- package/dist/chunk-QOZXJ4NA.js +3364 -0
- package/dist/chunk-QYF5S6P6.js +45 -0
- package/dist/chunk-RIISMHKN.js +36 -0
- package/dist/chunk-RPD4ZSB7.js +25 -0
- package/dist/chunk-RPD5K5NC.js +79 -0
- package/dist/chunk-RUOG5D2C.js +262 -0
- package/dist/chunk-T4ERT73Y.js +599 -0
- package/dist/chunk-T6D4Q4AQ.js +54 -0
- package/dist/chunk-TGPXLY2J.js +391 -0
- package/dist/chunk-TLGFBM3F.js +12116 -0
- package/dist/chunk-TO6WL3GM.js +88 -0
- package/dist/chunk-TT22N74J.js +517 -0
- package/dist/chunk-TVN5N6GY.js +21216 -0
- package/dist/chunk-U3VGR4VU.js +308 -0
- package/dist/chunk-UK3CMEAL.js +1250 -0
- package/dist/chunk-UOPVJQ4N.js +103 -0
- package/dist/chunk-UXVNL3D7.js +23 -0
- package/dist/chunk-UY752QSN.js +45 -0
- package/dist/chunk-V5PXFSZK.js +188 -0
- package/dist/chunk-V7R425XG.js +398 -0
- package/dist/chunk-VCSRSYLF.js +81 -0
- package/dist/chunk-VD4JQCQC.js +162 -0
- package/dist/chunk-VDBPVIKD.js +62 -0
- package/dist/chunk-VHQLPIRJ.js +114 -0
- package/dist/chunk-VN2AXLEX.js +5414 -0
- package/dist/chunk-VNMT7C64.js +478 -0
- package/dist/chunk-WONERJTP.js +309 -0
- package/dist/chunk-XECLWQZN.js +85 -0
- package/dist/chunk-XIMYZ3JA.js +27 -0
- package/dist/chunk-XK4CIILI.js +144 -0
- package/dist/chunk-Y4T27COV.js +562 -0
- package/dist/chunk-YGVYKNSN.js +1860 -0
- package/dist/chunk-YLF3PPT5.js +308 -0
- package/dist/chunk-YSNFMJKN.js +14 -0
- package/dist/chunk-Z3CCVDUB.js +76 -0
- package/dist/chunk-Z54ZSOBZ.js +61 -0
- package/dist/chunk-ZAWW3AF6.js +97 -0
- package/dist/chunk-ZMOL6RQC.js +167 -0
- package/dist/index.js +16456 -8335
- package/dist/mcp/analyze-cli.js +186 -232
- package/dist/mcp/cli.js +137 -98
- package/dist/mcp/server.js +22589 -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 +3 -2
- package/docs/configuration.md +20 -1
- package/docs/environment-variables.md +52 -2
- package/docs/features.md +8 -4
- package/docs/globalconfig.md +1 -0
- package/docs/io-bridge-v2-migration.md +94 -0
- package/docs/lsp-capability-matrix.md +36 -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 +156 -88
- package/docs/pi-lens-investigator.md +74 -26
- package/docs/pi-lens-merge-policy.md +694 -0
- package/docs/pi-lens-monitor.md +73 -7
- package/docs/pi-lens-retro.md +6 -4
- package/docs/pi-lens-reviewer.md +188 -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/servercapabilities.md +53 -49
- package/docs/settings.md +1 -0
- package/docs/usage.md +5 -1
- 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/rules/advisory-registry-subset.yml +50 -0
- 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,378 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* jscpd Client for pi-lens
|
|
3
|
-
*
|
|
4
|
-
* Detects copy-paste / duplicate code blocks across the project.
|
|
5
|
-
* Helps the agent avoid unknowingly duplicating logic that already exists.
|
|
6
|
-
*
|
|
7
|
-
* Requires: npm install -D jscpd
|
|
8
|
-
* Docs: https://github.com/kucherenko/jscpd
|
|
9
|
-
*/
|
|
10
|
-
import { formatToolFailure } from "./dispatch/runners/utils/tool-failure.js";
|
|
11
|
-
import { createSubsystemLogger } from "./extension-log.js";
|
|
12
|
-
import { incrementDegradationCount } from "./degradation-ledger.js";
|
|
13
|
-
import * as fs from "node:fs";
|
|
14
|
-
import { mkdtempSync } from "node:fs";
|
|
15
|
-
import * as os from "node:os";
|
|
16
|
-
import * as path from "node:path";
|
|
17
|
-
import { getExcludedDirGlobs, getProjectIgnoreGlobs, getProjectIgnoreMatcher, } from "./file-utils.js";
|
|
18
|
-
import { findNodeToolBinary } from "./package-manager.js";
|
|
19
|
-
import { isAtOrAboveHomeDir, isFullyQualified } from "./path-utils.js";
|
|
20
|
-
import { getJscpdMaxEntriesDerived } from "./project-scale.js";
|
|
21
|
-
import { createAvailabilityChecker, findManagedNodeToolBinary, resolveAvailableOrInstall, } from "./dispatch/runners/utils/runner-helpers.js";
|
|
22
|
-
import { safeSpawnAsync } from "./safe-spawn.js";
|
|
23
|
-
import { shouldRecurseIntoDir, walkTreeStackSync } from "./source-walker.js";
|
|
24
|
-
const EMPTY_RESULT = {
|
|
25
|
-
success: false,
|
|
26
|
-
clones: [],
|
|
27
|
-
duplicatedLines: 0,
|
|
28
|
-
totalLines: 0,
|
|
29
|
-
percentage: 0,
|
|
30
|
-
};
|
|
31
|
-
const SCAN_TIMEOUT_MS = 30_000;
|
|
32
|
-
/** jscpd's own config-file names, in its discovery order, checked at `cwd` only
|
|
33
|
-
* (jscpd does not walk up). */
|
|
34
|
-
const JSCPD_CONFIG_FILENAMES = [".jscpd.json", "jscpd.json"];
|
|
35
|
-
/**
|
|
36
|
-
* True when the project ships its own jscpd config: a `.jscpd.json`/
|
|
37
|
-
* `jscpd.json` file, or a `package.json` `jscpd` field. jscpd discovers either
|
|
38
|
-
* unaided, but `--min-lines`/`--min-tokens`/`--ignore` on the CLI override
|
|
39
|
-
* whatever the config sets — passing them unconditionally silently discarded a
|
|
40
|
-
* project's own thresholds and ignore list (#1731, discipline A).
|
|
41
|
-
*/
|
|
42
|
-
function hasProjectJscpdConfig(cwd) {
|
|
43
|
-
for (const name of JSCPD_CONFIG_FILENAMES) {
|
|
44
|
-
if (fs.existsSync(path.join(cwd, name)))
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
try {
|
|
48
|
-
const pkg = JSON.parse(fs.readFileSync(path.join(cwd, "package.json"), "utf-8"));
|
|
49
|
-
if (pkg && typeof pkg === "object" && pkg.jscpd !== undefined)
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
// No/malformed package.json — "no project config" is the honest answer.
|
|
54
|
-
}
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
const jscpdAvailability = createAvailabilityChecker("jscpd", "", ["--version"], {
|
|
58
|
-
probeTimeout: 1500,
|
|
59
|
-
// One definition of the managed-shim fast path, shared with knip (#1476).
|
|
60
|
-
fastPath: () => findManagedNodeToolBinary("jscpd"),
|
|
61
|
-
});
|
|
62
|
-
// --- Client ---
|
|
63
|
-
export class JscpdClient {
|
|
64
|
-
// Absolute path of a MANAGED jscpd (the global ~/.pi-lens tools shim
|
|
65
|
-
// discovered by the availability fast path, or the ensureTool install
|
|
66
|
-
// result), else null. Nullable on purpose: a bare-name sentinel can't
|
|
67
|
-
// distinguish "resolved" from "on PATH" — ensureTool may legitimately
|
|
68
|
-
// return a bare command for an already-spawnable tool (#1289 review).
|
|
69
|
-
// Project-local binaries are NOT stored; each scan resolves those against
|
|
70
|
-
// its own cwd via findNodeToolBinary.
|
|
71
|
-
jscpdManagedPath = null;
|
|
72
|
-
inFlight = new Map();
|
|
73
|
-
log;
|
|
74
|
-
constructor(verbose = false) {
|
|
75
|
-
this.log = verbose ? createSubsystemLogger("jscpd") : () => { };
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Wait for scans already started by this client to settle. Test owners use
|
|
79
|
-
* this as the lifecycle barrier before removing fixture roots; the scan
|
|
80
|
-
* promise includes the jscpd child and its report-directory cleanup.
|
|
81
|
-
*/
|
|
82
|
-
async shutdown() {
|
|
83
|
-
await Promise.allSettled(this.inFlight.values());
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Fast recursive source file presence check.
|
|
87
|
-
* Avoids running jscpd when repo has no relevant source files.
|
|
88
|
-
*
|
|
89
|
-
* Originally this gate accepted only JS/TS extensions (commit 8b5d588).
|
|
90
|
-
* That made pi-lens's jscpd integration effectively JS/TS-only even
|
|
91
|
-
* though jscpd's tokenizer covers 15+ languages. Pure-Python /
|
|
92
|
-
* pure-Go / pure-Rust / pure-Java / etc. repos got zero clone
|
|
93
|
-
* detection. Closes #126: extend the gate to every language jscpd
|
|
94
|
-
* tokenizes well. Languages with no jscpd tokenizer (Gleam, Zig,
|
|
95
|
-
* Fish) are deliberately excluded — the gate change wouldn't help
|
|
96
|
-
* them.
|
|
97
|
-
*/
|
|
98
|
-
hasSourceFilesRecursive(rootDir) {
|
|
99
|
-
const ignoreMatcher = getProjectIgnoreMatcher(rootDir);
|
|
100
|
-
const state = { visited: 0 };
|
|
101
|
-
// #776: derived from the `maxProjectFiles` scale knob (project-scale.ts),
|
|
102
|
-
// reproducing this same 6,000 default at the default base.
|
|
103
|
-
const MAX_ENTRIES = getJscpdMaxEntriesDerived(rootDir);
|
|
104
|
-
// #761: the traversal loop, readdir-safety, and directory-recursion
|
|
105
|
-
// decision are the shared `walkTreeStackSync` engine; this client keeps
|
|
106
|
-
// its own per-entry policy (skip ALL symlinks — files too — before the
|
|
107
|
-
// dir/file branch, its own multi-language source regex, and a
|
|
108
|
-
// per-directory entry budget via `shouldStop`, matching the pre-#761
|
|
109
|
-
// `while (stack.length > 0 && visited < MAX_ENTRIES)` condition: the
|
|
110
|
-
// current directory's entry loop always finishes, but no further
|
|
111
|
-
// directory is popped once the budget is spent).
|
|
112
|
-
return walkTreeStackSync(rootDir, (entry, fullPath) => {
|
|
113
|
-
state.visited += 1;
|
|
114
|
-
if (entry.isSymbolicLink())
|
|
115
|
-
return "skip";
|
|
116
|
-
if (entry.isDirectory()) {
|
|
117
|
-
return shouldRecurseIntoDir(entry, fullPath, {
|
|
118
|
-
ignoreMatcher,
|
|
119
|
-
followSymlinks: true,
|
|
120
|
-
})
|
|
121
|
-
? "recurse"
|
|
122
|
-
: "skip";
|
|
123
|
-
}
|
|
124
|
-
if (!entry.isFile())
|
|
125
|
-
return "skip";
|
|
126
|
-
// #1974: extension gate before isIgnored — the regex test is cheap
|
|
127
|
-
// per-call; isIgnored recompiles minimatch patterns per ancestor dir
|
|
128
|
-
// and should only run for files that already look like source.
|
|
129
|
-
if (/\.(ts|tsx|js|jsx|mjs|cjs|py|pyi|java|go|rs|rb|php|swift|kt|kts|dart|lua|scala|c|h|cpp|cc|cxx|hpp|hxx|cs|m|mm)$/.test(entry.name)) {
|
|
130
|
-
if (entry.name.endsWith(".d.ts"))
|
|
131
|
-
return "skip";
|
|
132
|
-
if (ignoreMatcher.isIgnored(fullPath, false))
|
|
133
|
-
return "skip";
|
|
134
|
-
return "stop";
|
|
135
|
-
}
|
|
136
|
-
return "skip";
|
|
137
|
-
}, { shouldStop: () => state.visited >= MAX_ENTRIES });
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Check if jscpd is available, auto-install if not
|
|
141
|
-
*/
|
|
142
|
-
async ensureAvailable() {
|
|
143
|
-
const resolved = await resolveAvailableOrInstall(jscpdAvailability, "jscpd", process.cwd());
|
|
144
|
-
if (!resolved)
|
|
145
|
-
return false;
|
|
146
|
-
if (isFullyQualified(resolved))
|
|
147
|
-
this.jscpdManagedPath = resolved;
|
|
148
|
-
return true;
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* #1623: public availability verdict for callers outside the dispatch
|
|
152
|
-
* graph (mode=full's fresh-fetch) that need to say WHY `ensureAvailable()`
|
|
153
|
-
* most recently returned false, using the SAME outcome/cause the shared
|
|
154
|
-
* `jscpdAvailability` checker already tracks — not a re-guessed "jscpd
|
|
155
|
-
* binary unavailable" that can't tell a transient retry-cooldown probe
|
|
156
|
-
* from a durable absence.
|
|
157
|
-
*/
|
|
158
|
-
getAvailabilityVerdict() {
|
|
159
|
-
const verdict = jscpdAvailability.getVerdict(process.cwd());
|
|
160
|
-
return {
|
|
161
|
-
outcome: verdict.outcome,
|
|
162
|
-
cause: verdict.cause,
|
|
163
|
-
retryAtMs: verdict.retryAtMs,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Scan a directory for duplicate code blocks.
|
|
168
|
-
* Uses a temp output dir to capture JSON report.
|
|
169
|
-
* @param isTsProject - If true, excludes .js files (they're compiled artifacts in TS projects)
|
|
170
|
-
*
|
|
171
|
-
* Root contract (#747/#250): unlike `KnipClient`/`DeadCodeClient`, this
|
|
172
|
-
* client does NOT resolve a project root via `findNearestMarkerRoot`, so it
|
|
173
|
-
* has historically relied on every caller to guard the scan root itself. The
|
|
174
|
-
* `isAtOrAboveHomeDir` refusal below is belt-and-braces internal protection
|
|
175
|
-
* so a FUTURE caller that forgets that contract can't spawn a whole-$HOME
|
|
176
|
-
* jscpd walk (the observed OOM: a jscpd run from a WSL home reached 44 GB
|
|
177
|
-
* RSS). `options.homeDir` overrides `os.homedir()` for tests.
|
|
178
|
-
*/
|
|
179
|
-
async scan(cwd, minLines = 5, minTokens = 50, isTsProject = false, options = {}) {
|
|
180
|
-
const targetDir = path.resolve(cwd);
|
|
181
|
-
// #747/#250: never walk from a cwd at/above $HOME — from there jscpd's
|
|
182
|
-
// tokenizer would run across every unrelated repo under home.
|
|
183
|
-
if (isAtOrAboveHomeDir(targetDir, options.homeDir)) {
|
|
184
|
-
this.log(`Refusing scan of unsafe root at/above home: ${targetDir}`);
|
|
185
|
-
return { ...EMPTY_RESULT };
|
|
186
|
-
}
|
|
187
|
-
// Return early for non-existent or empty directories before probing/installing.
|
|
188
|
-
if (!fs.existsSync(targetDir)) {
|
|
189
|
-
return { ...EMPTY_RESULT };
|
|
190
|
-
}
|
|
191
|
-
if (!this.hasSourceFilesRecursive(targetDir)) {
|
|
192
|
-
return { ...EMPTY_RESULT, success: true };
|
|
193
|
-
}
|
|
194
|
-
if (!(await this.ensureAvailable())) {
|
|
195
|
-
return { ...EMPTY_RESULT };
|
|
196
|
-
}
|
|
197
|
-
const key = `${targetDir}:${minLines}:${minTokens}:${isTsProject}`;
|
|
198
|
-
const existing = this.inFlight.get(key);
|
|
199
|
-
if (existing) {
|
|
200
|
-
this.log(`Scan already in flight for ${targetDir}; sharing result`);
|
|
201
|
-
return existing;
|
|
202
|
-
}
|
|
203
|
-
// Identity-guarded release (#1968's pattern): delete only if THIS run is
|
|
204
|
-
// still the registered one. A bare delete-by-key lets a late-settling run
|
|
205
|
-
// evict a live successor a second writer registered under the same key
|
|
206
|
-
// mid-flight, after which the next caller starts a duplicate scan.
|
|
207
|
-
const promise = this.runScan(targetDir, minLines, minTokens, isTsProject).finally(() => {
|
|
208
|
-
if (this.inFlight.get(key) === promise)
|
|
209
|
-
this.inFlight.delete(key);
|
|
210
|
-
});
|
|
211
|
-
this.inFlight.set(key, promise);
|
|
212
|
-
return promise;
|
|
213
|
-
}
|
|
214
|
-
async runScan(cwd, minLines, minTokens, isTsProject) {
|
|
215
|
-
const outDir = mkdtempSync(`${os.tmpdir()}${path.sep}pi-lens-jscpd-`);
|
|
216
|
-
// Build ignore pattern from shared exclusions + scanner-specific patterns.
|
|
217
|
-
const baseIgnores = [
|
|
218
|
-
...getExcludedDirGlobs(),
|
|
219
|
-
...getProjectIgnoreGlobs(cwd),
|
|
220
|
-
"**/*.md",
|
|
221
|
-
"**/*.txt",
|
|
222
|
-
"**/*.json",
|
|
223
|
-
"**/*.yaml",
|
|
224
|
-
"**/*.yml",
|
|
225
|
-
"**/*.toml",
|
|
226
|
-
"**/*.lock",
|
|
227
|
-
"**/*.test.*",
|
|
228
|
-
"**/*.spec.*",
|
|
229
|
-
"**/*.poc.test.*",
|
|
230
|
-
"**/__tests__/**",
|
|
231
|
-
"**/tests/**",
|
|
232
|
-
];
|
|
233
|
-
if (isTsProject) {
|
|
234
|
-
baseIgnores.push("**/*.js", "**/*.jsx");
|
|
235
|
-
}
|
|
236
|
-
const ignorePattern = baseIgnores.join(",");
|
|
237
|
-
try {
|
|
238
|
-
// Prefer a local/global-installed jscpd (any manager) over npx (#375).
|
|
239
|
-
const bin = await findNodeToolBinary("jscpd", cwd);
|
|
240
|
-
const { cmd, prefix } = bin
|
|
241
|
-
? { cmd: bin, prefix: [] }
|
|
242
|
-
: this.jscpdManagedPath
|
|
243
|
-
? { cmd: this.jscpdManagedPath, prefix: [] }
|
|
244
|
-
: { cmd: "npx", prefix: ["jscpd"] };
|
|
245
|
-
// A project's own jscpd config wins outright (#1731, discipline A):
|
|
246
|
-
// these three flags all override whatever it sets, so none are passed
|
|
247
|
-
// when the project ships one — jscpd discovers it unaided.
|
|
248
|
-
const hasConfig = hasProjectJscpdConfig(cwd);
|
|
249
|
-
const result = await safeSpawnAsync(cmd, [
|
|
250
|
-
...prefix,
|
|
251
|
-
".",
|
|
252
|
-
...(hasConfig
|
|
253
|
-
? []
|
|
254
|
-
: [
|
|
255
|
-
"--min-lines",
|
|
256
|
-
String(minLines),
|
|
257
|
-
"--min-tokens",
|
|
258
|
-
String(minTokens),
|
|
259
|
-
]),
|
|
260
|
-
"--reporters",
|
|
261
|
-
"json",
|
|
262
|
-
"--output",
|
|
263
|
-
outDir,
|
|
264
|
-
...(hasConfig ? [] : ["--ignore", ignorePattern]),
|
|
265
|
-
], {
|
|
266
|
-
timeout: SCAN_TIMEOUT_MS,
|
|
267
|
-
cwd,
|
|
268
|
-
});
|
|
269
|
-
if (result.error) {
|
|
270
|
-
this.log(`Scan error: ${result.error.message}`);
|
|
271
|
-
return { ...EMPTY_RESULT };
|
|
272
|
-
}
|
|
273
|
-
// Empirical exit-code table (jscpd 3.5.10, verified live for #1736's
|
|
274
|
-
// sweep): a genuinely clean run (no clones) exits 0 and writes NO
|
|
275
|
-
// report file — jscpd only writes `jscpd-report.json` when it has
|
|
276
|
-
// something to report. A crashed run (uncaught exception, e.g. a bad
|
|
277
|
-
// scan path) ALSO writes no report file, but exits nonzero. The
|
|
278
|
-
// missing-file check alone can't tell those apart, so a nonzero exit
|
|
279
|
-
// with no report file is reported as errored, never as "0 clones".
|
|
280
|
-
// (Not `spawnFailedWithNoOutput` — the parsed artifact here is a
|
|
281
|
-
// report FILE, not stdout, so the shared stdout-based discriminator
|
|
282
|
-
// doesn't apply; the underlying "nonzero exit -> not clean" rule is
|
|
283
|
-
// the same one.)
|
|
284
|
-
const reportPath = path.join(outDir, "jscpd-report.json");
|
|
285
|
-
if (!fs.existsSync(reportPath)) {
|
|
286
|
-
if (result.status !== 0) {
|
|
287
|
-
// #1816: one shared wording, one truncation, signal named.
|
|
288
|
-
// `reportMissing` is the artifact-tool arm of the same
|
|
289
|
-
// primitive — the parsed artifact here is a report FILE.
|
|
290
|
-
const reason = formatToolFailure({
|
|
291
|
-
tool: "jscpd",
|
|
292
|
-
status: result.status,
|
|
293
|
-
signal: result.signal,
|
|
294
|
-
stderr: result.stderr,
|
|
295
|
-
reportMissing: true,
|
|
296
|
-
fields: { command: cmd },
|
|
297
|
-
});
|
|
298
|
-
this.log(reason);
|
|
299
|
-
incrementDegradationCount({
|
|
300
|
-
kind: "runner-empty-result",
|
|
301
|
-
subject: "jscpd",
|
|
302
|
-
reason,
|
|
303
|
-
});
|
|
304
|
-
return { ...EMPTY_RESULT };
|
|
305
|
-
}
|
|
306
|
-
return { ...EMPTY_RESULT, success: true };
|
|
307
|
-
}
|
|
308
|
-
return this.parseReport(reportPath);
|
|
309
|
-
}
|
|
310
|
-
catch (err) {
|
|
311
|
-
this.log(`Scan error: ${err.message}`);
|
|
312
|
-
return { ...EMPTY_RESULT };
|
|
313
|
-
}
|
|
314
|
-
finally {
|
|
315
|
-
try {
|
|
316
|
-
fs.rmSync(outDir, { recursive: true, force: true });
|
|
317
|
-
}
|
|
318
|
-
catch (err) {
|
|
319
|
-
void err;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
formatResult(result, maxClones = 8) {
|
|
324
|
-
if (!result.success || result.clones.length === 0)
|
|
325
|
-
return "";
|
|
326
|
-
const pct = result.percentage.toFixed(1);
|
|
327
|
-
let output = `[jscpd] ${result.clones.length} duplicate block(s) — ${pct}% of codebase (${result.duplicatedLines}/${result.totalLines} lines):\n`;
|
|
328
|
-
for (const clone of result.clones.slice(0, maxClones)) {
|
|
329
|
-
const a = `${path.basename(clone.fileA)}:${clone.startA}`;
|
|
330
|
-
const b = `${path.basename(clone.fileB)}:${clone.startB}`;
|
|
331
|
-
output += ` ${clone.lines} lines — ${a} ↔ ${b}\n`;
|
|
332
|
-
}
|
|
333
|
-
if (result.clones.length > maxClones) {
|
|
334
|
-
output += ` ... and ${result.clones.length - maxClones} more\n`;
|
|
335
|
-
}
|
|
336
|
-
return output;
|
|
337
|
-
}
|
|
338
|
-
// --- Internal ---
|
|
339
|
-
parseReport(reportPath) {
|
|
340
|
-
try {
|
|
341
|
-
const data = JSON.parse(fs.readFileSync(reportPath, "utf-8"));
|
|
342
|
-
// Stats live in statistics.total, not statistics.clones
|
|
343
|
-
const total = data.statistics?.total ?? {};
|
|
344
|
-
const duplicatedLines = total.duplicatedLines ?? 0;
|
|
345
|
-
const totalLines = total.lines ?? 0;
|
|
346
|
-
const percentage = total.percentage ??
|
|
347
|
-
(totalLines > 0 ? (duplicatedLines / totalLines) * 100 : 0);
|
|
348
|
-
const rawClones = data.duplicates ?? [];
|
|
349
|
-
const clones = rawClones.map((c) => ({
|
|
350
|
-
fileA: c.firstFile?.name ?? "",
|
|
351
|
-
startA: c.firstFile?.start ?? 0,
|
|
352
|
-
fileB: c.secondFile?.name ?? "",
|
|
353
|
-
startB: c.secondFile?.start ?? 0,
|
|
354
|
-
lines: c.lines ?? 0,
|
|
355
|
-
tokens: c.tokens ?? 0,
|
|
356
|
-
}));
|
|
357
|
-
// #2154: the one jscpd site that parsed a scan of this root.
|
|
358
|
-
return {
|
|
359
|
-
success: true,
|
|
360
|
-
analyzed: true,
|
|
361
|
-
clones,
|
|
362
|
-
duplicatedLines,
|
|
363
|
-
totalLines,
|
|
364
|
-
percentage,
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
catch (err) {
|
|
368
|
-
void err;
|
|
369
|
-
return {
|
|
370
|
-
success: false,
|
|
371
|
-
clones: [],
|
|
372
|
-
duplicatedLines: 0,
|
|
373
|
-
totalLines: 0,
|
|
374
|
-
percentage: 0,
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared "read a JSON cache file off disk" boilerplate (#676).
|
|
3
|
-
*
|
|
4
|
-
* At least 7 sites across the codebase hand-duplicated the same shape:
|
|
5
|
-
* `JSON.parse(fs.readFileSync(path, "utf-8"))` → structural/version guard →
|
|
6
|
-
* return the parsed value, or `undefined`/`null` on ANY throw (missing file,
|
|
7
|
-
* unreadable, corrupt JSON, or a `validate` callback itself throwing). This
|
|
8
|
-
* module extracts only that read/parse/try-catch mechanics; every call
|
|
9
|
-
* site's own "is this actually a valid, current-version cache?" logic stays
|
|
10
|
-
* put, as the `validate` callback — consolidation is only meant to remove
|
|
11
|
-
* the duplicated plumbing, not to unify subtly different validation rules
|
|
12
|
-
* that call sites had for good reason (e.g. a second `ruleHash` field check
|
|
13
|
-
* alongside the version check).
|
|
14
|
-
*
|
|
15
|
-
* `validate` returning `undefined` means "treat this like a parse failure" —
|
|
16
|
-
* the same fail-open posture every existing site already had for a
|
|
17
|
-
* wrong-version/wrong-shape cache.
|
|
18
|
-
*/
|
|
19
|
-
import * as fs from "node:fs";
|
|
20
|
-
import { promises as fsPromises } from "node:fs";
|
|
21
|
-
/**
|
|
22
|
-
* Synchronous read: `JSON.parse(fs.readFileSync(path, "utf-8"))`, run through
|
|
23
|
-
* `validate`, with any failure (missing file, unreadable, corrupt JSON,
|
|
24
|
-
* `validate` throwing) swallowed to `undefined`.
|
|
25
|
-
*
|
|
26
|
-
* `onError`, when provided, is invoked with the caught error BEFORE
|
|
27
|
-
* `undefined` is returned — for sites that log a read failure today (e.g.
|
|
28
|
-
* `CacheManager`'s verbose `this.log(...)`) rather than silently swallowing
|
|
29
|
-
* it. `onError` itself is never allowed to throw the failure back out.
|
|
30
|
-
*/
|
|
31
|
-
export function readJsonCache(path, validate, onError) {
|
|
32
|
-
try {
|
|
33
|
-
const parsed = JSON.parse(fs.readFileSync(path, "utf-8"));
|
|
34
|
-
return validate(parsed);
|
|
35
|
-
}
|
|
36
|
-
catch (err) {
|
|
37
|
-
try {
|
|
38
|
-
onError?.(err);
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
/* onError must never mask the original fail-open behavior */
|
|
42
|
-
}
|
|
43
|
-
return undefined;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Async sibling of {@link readJsonCache}, for call sites already on the
|
|
48
|
-
* `fs.promises` API (e.g. `session-state-store.ts`). Same fail-open contract.
|
|
49
|
-
*/
|
|
50
|
-
export async function readJsonCacheAsync(path, validate, onError) {
|
|
51
|
-
try {
|
|
52
|
-
const raw = await fsPromises.readFile(path, "utf-8");
|
|
53
|
-
const parsed = JSON.parse(raw);
|
|
54
|
-
return validate(parsed);
|
|
55
|
-
}
|
|
56
|
-
catch (err) {
|
|
57
|
-
try {
|
|
58
|
-
onError?.(err);
|
|
59
|
-
}
|
|
60
|
-
catch {
|
|
61
|
-
/* onError must never mask the original fail-open behavior */
|
|
62
|
-
}
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
|
-
}
|