@herbertgao/pi-extensions 2026.9.0 → 2026.9.2
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/node_modules/@czottmann/pi-automode/CHANGELOG.md +13 -1
- package/node_modules/@czottmann/pi-automode/README.md +20 -0
- package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +1 -1
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +2 -1
- package/node_modules/@czottmann/pi-automode/docs/defaults.md +3 -2
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +38 -2
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +5 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +11 -3
- package/node_modules/@czottmann/pi-automode/package.json +1 -1
- package/node_modules/@narumitw/pi-btw/README.md +57 -141
- package/node_modules/@narumitw/pi-btw/dist/index.ts +466 -41
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +4 -4
- package/node_modules/@narumitw/pi-btw/docs/workflows.md +74 -0
- package/node_modules/@narumitw/pi-btw/package.json +2 -1
- package/node_modules/@narumitw/pi-btw/src/btw.ts +15 -1
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +32 -2
- package/node_modules/@narumitw/pi-btw/src/keybindings.ts +330 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +136 -19
- package/node_modules/@narumitw/pi-btw/src/settings.ts +32 -0
- package/node_modules/@narumitw/pi-btw/src/side-thread.ts +57 -5
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +52 -30
- package/node_modules/@pi-plugins/fast-mode/README.md +5 -3
- package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +20 -55
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/package.json +1 -1
- package/node_modules/pi-lens/CHANGELOG.md +1072 -0
- package/node_modules/pi-lens/README.md +3 -0
- package/node_modules/pi-lens/config/biome/core.jsonc +11 -2
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +13 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -9
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +927 -80
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +1 -1
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +13 -4
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +123 -3
- package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +60 -5
- package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +2 -9
- package/node_modules/pi-lens/dist/clients/ast-grep-types.js +2 -0
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +133 -3
- package/node_modules/pi-lens/dist/clients/biome-client.js +9 -2
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +14 -6
- package/node_modules/pi-lens/dist/clients/bootstrap.js +509 -73
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +152 -12
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +1 -1
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +59 -9
- package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +113 -0
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +3 -11
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +31 -4
- package/node_modules/pi-lens/dist/clients/cache-manager.js +105 -6
- package/node_modules/pi-lens/dist/clients/cache-observability.js +40 -19
- package/node_modules/pi-lens/dist/clients/cargo-manifest.js +422 -0
- package/node_modules/pi-lens/dist/clients/cascade-logger.js +2 -9
- package/node_modules/pi-lens/dist/clients/child-unref.js +1 -19
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +13 -3
- package/node_modules/pi-lens/dist/clients/complexity-client.js +16 -5
- package/node_modules/pi-lens/dist/clients/config-core/deny.js +221 -0
- package/node_modules/pi-lens/dist/clients/config-core/index.js +50 -0
- package/node_modules/pi-lens/dist/clients/config-core/merge.js +357 -0
- package/node_modules/pi-lens/dist/clients/config-core/normalize.js +340 -0
- package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +248 -0
- package/node_modules/pi-lens/dist/clients/config-core/provenance.js +164 -0
- package/node_modules/pi-lens/dist/clients/config-core/records.js +218 -0
- package/node_modules/pi-lens/dist/clients/config-core/resolve.js +125 -0
- package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +78 -0
- package/node_modules/pi-lens/dist/clients/config-core/schema.js +165 -0
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +281 -0
- package/node_modules/pi-lens/dist/clients/config-locations.js +160 -0
- package/node_modules/pi-lens/dist/clients/config-resolve.js +789 -0
- package/node_modules/pi-lens/dist/clients/config-schema.js +234 -0
- package/node_modules/pi-lens/dist/clients/config-warn.js +407 -0
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -14
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +2 -6
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +178 -0
- package/node_modules/pi-lens/dist/clients/debug-handles.js +2 -2
- package/node_modules/pi-lens/dist/clients/debug-heap.js +3 -3
- package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +106 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +113 -7
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +8 -19
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +1 -1
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +12 -9
- package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +15 -5
- package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +0 -4
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +162 -44
- package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +97 -0
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +27 -8
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +0 -6
- package/node_modules/pi-lens/dist/clients/dispatch/pending-runner-findings.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +0 -3
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-complexity.js +2 -2
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-fan-out.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +383 -27
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +4 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +1 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +14 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +6 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +7 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +1 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +1 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +4 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +3 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +3 -67
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +194 -80
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +84 -15
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils.js +0 -21
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +2 -20
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/utils/format-utils.js +2 -2
- package/node_modules/pi-lens/dist/clients/disposition-logger.js +3 -10
- package/node_modules/pi-lens/dist/clients/effective-config.js +403 -0
- package/node_modules/pi-lens/dist/clients/error-class.js +23 -0
- package/node_modules/pi-lens/dist/clients/event-loop-hold.js +274 -0
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +2 -2
- package/node_modules/pi-lens/dist/clients/extension-log.js +2 -2
- package/node_modules/pi-lens/dist/clients/feature-hints.js +2 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +1 -38
- package/node_modules/pi-lens/dist/clients/file-time.js +7 -2
- package/node_modules/pi-lens/dist/clients/file-utils.js +117 -10
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +50 -13
- package/node_modules/pi-lens/dist/clients/format-service.js +6 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +385 -104
- package/node_modules/pi-lens/dist/clients/freshness-cadence.js +17 -0
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +116 -22
- package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -9
- package/node_modules/pi-lens/dist/clients/git-guard.js +6 -1
- package/node_modules/pi-lens/dist/clients/go-client.js +39 -0
- package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +252 -0
- package/node_modules/pi-lens/dist/clients/grammar-source.js +3 -3
- package/node_modules/pi-lens/dist/clients/hashline-anchor.js +424 -0
- package/node_modules/pi-lens/dist/clients/hook-budgets.js +76 -0
- package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +5 -2
- package/node_modules/pi-lens/dist/clients/host-ports.js +1 -1
- package/node_modules/pi-lens/dist/clients/installer/index.js +289 -59
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +84 -18
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +110 -236
- package/node_modules/pi-lens/dist/clients/instance-registry.js +6 -3
- package/node_modules/pi-lens/dist/clients/language-profile.js +0 -9
- package/node_modules/pi-lens/dist/clients/language-registry.js +599 -0
- package/node_modules/pi-lens/dist/clients/latency-logger.js +165 -9
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +34 -1
- package/node_modules/pi-lens/dist/clients/lens-config.js +160 -30
- package/node_modules/pi-lens/dist/clients/lens-engine.js +33 -41
- package/node_modules/pi-lens/dist/clients/lens-events.js +1 -1
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +77 -6
- package/node_modules/pi-lens/dist/clients/lens-map.js +1 -1
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -38
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +3 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +172 -33
- package/node_modules/pi-lens/dist/clients/lsp/config.js +484 -158
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +18 -5
- package/node_modules/pi-lens/dist/clients/lsp/index.js +892 -96
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/language.js +18 -177
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +5 -18
- package/node_modules/pi-lens/dist/clients/lsp/server.js +284 -147
- package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +116 -23
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +2 -7
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +0 -1
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +14 -7
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +6 -0
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +163 -21
- package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +36 -0
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +33 -4
- package/node_modules/pi-lens/dist/clients/mcp/session.js +5 -16
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +8 -3
- package/node_modules/pi-lens/dist/clients/metrics-history.js +28 -107
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +3 -5
- package/node_modules/pi-lens/dist/clients/module-report.js +21 -46
- package/node_modules/pi-lens/dist/clients/mutating-tool.js +651 -0
- package/node_modules/pi-lens/dist/clients/mutation-attribution.js +368 -0
- package/node_modules/pi-lens/dist/clients/mutation-bridge.js +240 -0
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +247 -24
- package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +101 -0
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +1215 -0
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +70 -28
- package/node_modules/pi-lens/dist/clients/opengrep-config.js +5 -1
- package/node_modules/pi-lens/dist/clients/package-manager.js +195 -26
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +359 -80
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +23 -7
- package/node_modules/pi-lens/dist/clients/path-keyed-map.js +21 -2
- package/node_modules/pi-lens/dist/clients/path-utils.js +451 -15
- package/node_modules/pi-lens/dist/clients/performance-report.js +2 -2
- package/node_modules/pi-lens/dist/clients/persist-debounce.js +8 -1
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +114 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +79 -18
- package/node_modules/pi-lens/dist/clients/probe-home-state.js +228 -0
- package/node_modules/pi-lens/dist/clients/process-bridge.js +66 -0
- package/node_modules/pi-lens/dist/clients/process-snapshot.js +68 -0
- package/node_modules/pi-lens/dist/clients/project-changes.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +4 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +28 -4
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +51 -20
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +438 -122
- package/node_modules/pi-lens/dist/clients/project-scan-policy.js +3 -51
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +52 -24
- package/node_modules/pi-lens/dist/clients/python-environment.js +217 -0
- package/node_modules/pi-lens/dist/clients/python-provenance.js +639 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +6 -1
- package/node_modules/pi-lens/dist/clients/read-bridge.js +13 -21
- package/node_modules/pi-lens/dist/clients/read-expansion.js +9 -46
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +16 -5
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +364 -212
- package/node_modules/pi-lens/dist/clients/read-guard.js +26 -2
- package/node_modules/pi-lens/dist/clients/recent-touches.js +2 -2
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +195 -96
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +155 -114
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +1 -1
- package/node_modules/pi-lens/dist/clients/review-graph/service.js +55 -3
- package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +7 -15
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +10 -74
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +9 -3
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +19 -3
- package/node_modules/pi-lens/dist/clients/runtime-context.js +49 -16
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +25 -6
- package/node_modules/pi-lens/dist/clients/runtime-session.js +184 -32
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +179 -36
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +797 -243
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +1028 -53
- package/node_modules/pi-lens/dist/clients/rust-client.js +31 -0
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +33 -10
- package/node_modules/pi-lens/dist/clients/sanitize.js +7 -12
- package/node_modules/pi-lens/dist/clients/scan-utils.js +1 -56
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +1 -3
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +3 -0
- package/node_modules/pi-lens/dist/clients/session-lifecycle.js +1 -1
- package/node_modules/pi-lens/dist/clients/session-start-observability.js +79 -0
- package/node_modules/pi-lens/dist/clients/session-summary.js +0 -24
- package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +12 -3
- package/node_modules/pi-lens/dist/clients/sgconfig.js +7 -6
- package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +1 -1
- package/node_modules/pi-lens/dist/clients/skills-resolver.js +105 -0
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +4 -4
- package/node_modules/pi-lens/dist/clients/startup-scan.js +2 -10
- package/node_modules/pi-lens/dist/clients/string-utils.js +13 -0
- package/node_modules/pi-lens/dist/clients/subagent-mode.js +17 -4
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +176 -39
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +244 -0
- package/node_modules/pi-lens/dist/clients/tool-definition.js +41 -1
- package/node_modules/pi-lens/dist/clients/tool-policy.js +92 -22
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +40 -40
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +87 -100
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +81 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +51 -46
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +28 -0
- package/node_modules/pi-lens/dist/clients/tui-fit.js +0 -4
- package/node_modules/pi-lens/dist/clients/typos-config.js +5 -0
- package/node_modules/pi-lens/dist/clients/user-notify.js +6 -6
- package/node_modules/pi-lens/dist/clients/widget-state.js +191 -26
- package/node_modules/pi-lens/dist/clients/word-index-logger.js +2 -9
- package/node_modules/pi-lens/dist/clients/word-index-store.js +23 -12
- package/node_modules/pi-lens/dist/clients/word-index.js +252 -47
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -1
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +4 -1
- package/node_modules/pi-lens/dist/index.js +65899 -55340
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -1
- package/node_modules/pi-lens/dist/mcp/build-staleness.js +1 -1
- package/node_modules/pi-lens/dist/mcp/server.js +127 -5
- package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +583 -0
- package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +129 -0
- package/node_modules/pi-lens/dist/tools/effective-config.js +89 -0
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +96 -25
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +104 -86
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +37 -16
- package/node_modules/pi-lens/dist/tools/lsp-structured-output.js +3 -3
- package/node_modules/pi-lens/dist/tools/render-compact.js +1 -1
- package/node_modules/pi-lens/dist/tools/shared.js +0 -1
- package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -2
- package/node_modules/pi-lens/docs/agent-guide.md +64 -1
- package/node_modules/pi-lens/docs/configuration.md +222 -0
- package/node_modules/pi-lens/docs/dependencies.md +3 -3
- package/node_modules/pi-lens/docs/features.md +44 -5
- package/node_modules/pi-lens/docs/globalconfig.md +20 -0
- package/node_modules/pi-lens/docs/language-coverage.md +2 -2
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +9 -1
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +25 -0
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +25 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +33 -0
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +49 -0
- package/node_modules/pi-lens/docs/pi-lens-warden.md +55 -0
- package/node_modules/pi-lens/docs/public-api-stability.md +359 -0
- package/node_modules/pi-lens/docs/release-qa-baseline.md +190 -0
- package/node_modules/pi-lens/docs/servercapabilities.md +7 -3
- package/node_modules/pi-lens/docs/subagent-compat.md +110 -30
- package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +2 -2
- package/node_modules/pi-lens/docs/word-index.md +1 -1
- package/node_modules/pi-lens/package.json +18 -35
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
- package/node_modules/pi-lens/rules/typos/_typos.toml +4 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +192 -1
- package/node_modules/pi-lens/scripts/install-selftest.mjs +58 -2
- package/node_modules/pi-lens/scripts/lib/skills-predicate.mjs +129 -0
- package/node_modules/pi-lens/scripts/lib/warm-loader-cache.mjs +1 -1
- package/node_modules/pi-lens/scripts/rpc-load-check.mjs +3 -1
- package/node_modules/pi-lens/scripts/warm-loader-cache.mjs +4 -2
- package/node_modules/pi-web-access/CHANGELOG.md +28 -0
- package/node_modules/pi-web-access/README.md +62 -15
- package/node_modules/pi-web-access/curator-page.ts +3 -1
- package/node_modules/pi-web-access/curator-server.ts +5 -1
- package/node_modules/pi-web-access/gemini-search.ts +8 -4
- package/node_modules/pi-web-access/github-extract.ts +242 -1
- package/node_modules/pi-web-access/index.ts +118 -64
- package/node_modules/pi-web-access/mistral-search.ts +281 -0
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/perplexity.ts +14 -1
- package/node_modules/pi-web-access/utils.ts +23 -6
- package/node_modules/pi-web-access/xai-search.ts +96 -33
- package/package.json +6 -6
|
@@ -29,16 +29,17 @@
|
|
|
29
29
|
* - rust-analyzer (Rust LSP) [GitHub release]
|
|
30
30
|
* - golangci-lint (Go linting) [GitHub release]
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
* - yaml-language-server
|
|
34
|
-
* -
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* -
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
32
|
+
* Every other managed tool (including several the list above omits, e.g.
|
|
33
|
+
* bash-language-server, yaml-language-server, svelte-language-server,
|
|
34
|
+
* @prisma/language-server, @vue/language-server, dockerfile-language-server-nodejs,
|
|
35
|
+
* and vscode-css-languageserver — all of which ARE auto-installed) is
|
|
36
|
+
* documented by the `TOOLS` array below, not restated here. #2638: a
|
|
37
|
+
* hand-kept "manual install" list naming specific package specs used to live
|
|
38
|
+
* in this comment, drifted from `TOOLS` (it named a since-unpublished npm
|
|
39
|
+
* package for the CSS entry, and several tools it called "manual" were
|
|
40
|
+
* already auto-install above) and nothing caught it. `TOOLS` is the single
|
|
41
|
+
* source of truth for every id, package, and strategy; deleted rather than
|
|
42
|
+
* re-derived, since a comment cannot be generated from code at write time.
|
|
42
43
|
*
|
|
43
44
|
* Strategies:
|
|
44
45
|
* - npm packages via npx/bun
|
|
@@ -234,7 +235,12 @@ export const TOOLS = [
|
|
|
234
235
|
checkCommand: "typescript-language-server",
|
|
235
236
|
checkArgs: ["--version"],
|
|
236
237
|
installStrategy: "npm",
|
|
237
|
-
|
|
238
|
+
// Pinned below the package's own floor: 6.0.0 declares
|
|
239
|
+
// engines.node >=22.22.2, above the pi host's own floor (pi-lens
|
|
240
|
+
// must never require more than pi does — #2633) — an unpinned
|
|
241
|
+
// install here resolves latest and prints EBADENGINE on any pi
|
|
242
|
+
// host's supported Node. 5.3.0's own floor is engines.node >=20.
|
|
243
|
+
packageName: "typescript-language-server@5.3.0",
|
|
238
244
|
binaryName: "typescript-language-server",
|
|
239
245
|
},
|
|
240
246
|
{
|
|
@@ -440,7 +446,7 @@ export const TOOLS = [
|
|
|
440
446
|
checkCommand: "vscode-html-language-server",
|
|
441
447
|
checkArgs: ["--version"],
|
|
442
448
|
installStrategy: "npm",
|
|
443
|
-
packageName: "vscode-
|
|
449
|
+
packageName: "vscode-langservers-extracted",
|
|
444
450
|
binaryName: "vscode-html-language-server",
|
|
445
451
|
},
|
|
446
452
|
{
|
|
@@ -529,7 +535,7 @@ export const TOOLS = [
|
|
|
529
535
|
checkCommand: "vscode-css-language-server",
|
|
530
536
|
checkArgs: ["--version"],
|
|
531
537
|
installStrategy: "npm",
|
|
532
|
-
packageName: "vscode-
|
|
538
|
+
packageName: "vscode-langservers-extracted",
|
|
533
539
|
binaryName: "vscode-css-language-server",
|
|
534
540
|
},
|
|
535
541
|
{
|
|
@@ -542,10 +548,27 @@ export const TOOLS = [
|
|
|
542
548
|
binaryName: "docker-langserver",
|
|
543
549
|
},
|
|
544
550
|
{
|
|
551
|
+
// #2722: intelephense has no CLI — its entry calls createConnection()
|
|
552
|
+
// unconditionally — and Node prints the offending source line before the
|
|
553
|
+
// error. The bundle is one ~4 MB minified line, so the transport-required
|
|
554
|
+
// marker #208 rescues on lands at byte 4,154,741 of a 4,423,356-byte
|
|
555
|
+
// stderr while Node truncates piped stderr at 1 MiB on exit. Measured on
|
|
556
|
+
// intelephense@1.18.5, linux, Node v22.22.1:
|
|
557
|
+
// $ intelephense --version 2>&1 | wc -c -> 1048576
|
|
558
|
+
// $ intelephense --version 2>&1 | grep -c "Connection input stream is not set" -> 0
|
|
559
|
+
// $ intelephense --version 2>err.txt; wc -c < err.txt -> 4423356
|
|
560
|
+
// Same run over the alternatives, each with stdin closed the way
|
|
561
|
+
// verifyToolBinary closes it (`input: ""`):
|
|
562
|
+
// --help, -v, --socket=0 -> identical dump (exit 1, 4423356 bytes,
|
|
563
|
+
// marker at 4154741, 1048576 through a pipe, marker absent)
|
|
564
|
+
// --stdio -> exit 1 with ZERO bytes on either stream,
|
|
565
|
+
// so it carries no marker to rescue on either.
|
|
566
|
+
// No checkArgs value produces a verdict. Verified spawn-free instead.
|
|
545
567
|
id: "intelephense",
|
|
546
568
|
name: "Intelephense",
|
|
547
569
|
checkCommand: "intelephense",
|
|
548
570
|
checkArgs: ["--version"],
|
|
571
|
+
verification: "package-entry",
|
|
549
572
|
installStrategy: "npm",
|
|
550
573
|
packageName: "intelephense",
|
|
551
574
|
binaryName: "intelephense",
|
|
@@ -1823,7 +1846,7 @@ const lspTransportRequiredMatcher = /Connection (?:input|output) stream is not s
|
|
|
1823
1846
|
* correctly reports "no pin" rather than mistaking the scope for a version.
|
|
1824
1847
|
* Returns undefined when packageName has no explicit `@version` suffix.
|
|
1825
1848
|
*/
|
|
1826
|
-
function parsePinnedVersion(packageName) {
|
|
1849
|
+
export function parsePinnedVersion(packageName) {
|
|
1827
1850
|
const at = packageName.lastIndexOf("@");
|
|
1828
1851
|
if (at <= 0)
|
|
1829
1852
|
return undefined;
|
|
@@ -1845,6 +1868,111 @@ function extractVersionToken(output) {
|
|
|
1845
1868
|
* maven/archive) never populate or read this map.
|
|
1846
1869
|
*/
|
|
1847
1870
|
const lastManagedInstallVersion = new Map();
|
|
1871
|
+
/**
|
|
1872
|
+
* The package whose entry module verifies `tool`'s managed install spawn-free,
|
|
1873
|
+
* or undefined when the tool is verified by spawning `checkArgs` (#2722).
|
|
1874
|
+
* Registry-declared per tool — never inferred from the strategy: a spawn probe
|
|
1875
|
+
* is the stronger check everywhere it can actually return a verdict.
|
|
1876
|
+
*/
|
|
1877
|
+
export function packageEntryVerification(tool) {
|
|
1878
|
+
return tool.verification === "package-entry" ? tool.packageName : undefined;
|
|
1879
|
+
}
|
|
1880
|
+
/**
|
|
1881
|
+
* Spawn-free verification of a managed npm install (#2722).
|
|
1882
|
+
*
|
|
1883
|
+
* For an stdio LSP server with no CLI surface, every `checkArgs` value is a
|
|
1884
|
+
* throw, and #208's transport-required rescue is output-ORDER dependent: Node
|
|
1885
|
+
* prints the offending source line ahead of the error, so a server whose bundle
|
|
1886
|
+
* is megabytes of minified JS pushes the marker past both our retained window
|
|
1887
|
+
* and Node's own 1 MiB pipe truncation. The bytes never leave the child, so no
|
|
1888
|
+
* spawn can answer "is this install intact".
|
|
1889
|
+
*
|
|
1890
|
+
* The evidence used instead is the same class the `archive` strategy already
|
|
1891
|
+
* accepts through `treeMarker`: the installed tree is inspected on disk. The
|
|
1892
|
+
* install verifies when the package directory beside the `.bin` shim carries a
|
|
1893
|
+
* readable `package.json` with a `version`, and the entry module that
|
|
1894
|
+
* package.json itself names — `bin[<shim name>]` or a bare `bin` string —
|
|
1895
|
+
* exists as a non-empty file. `main` is deliberately NOT a fallback: npm
|
|
1896
|
+
* creates the `node_modules/.bin/<shim>` this function is given only from a
|
|
1897
|
+
* `bin` field, so a manifest without one cannot be the manifest behind this
|
|
1898
|
+
* shim. That is exactly what `verifyToolBinary` was documented to catch here —
|
|
1899
|
+
* broken symlinks and partial installs — and it is strictly more than the
|
|
1900
|
+
* `--version` spawn can report for this class.
|
|
1901
|
+
*/
|
|
1902
|
+
export async function verifyNpmPackageEntry(binPath, packageName) {
|
|
1903
|
+
// `<...>/node_modules/.bin/<shim>` → `<...>/node_modules`.
|
|
1904
|
+
const nodeModulesDir = path.dirname(path.dirname(binPath));
|
|
1905
|
+
const pinned = parsePinnedVersion(packageName);
|
|
1906
|
+
const bareName = pinned
|
|
1907
|
+
? packageName.slice(0, -(pinned.length + 1))
|
|
1908
|
+
: packageName;
|
|
1909
|
+
const packageDir = path.join(nodeModulesDir, ...bareName.split("/"));
|
|
1910
|
+
const shimName = path
|
|
1911
|
+
.basename(binPath)
|
|
1912
|
+
.replace(/\.(cmd|exe|ps1|bat)$/i, "")
|
|
1913
|
+
.toLowerCase();
|
|
1914
|
+
const fail = (reason) => {
|
|
1915
|
+
logSessionStart(`auto-install verify: failed for ${binPath} (check=package-entry, kind=${reason})`);
|
|
1916
|
+
return false;
|
|
1917
|
+
};
|
|
1918
|
+
// R2-F1: the shim ITSELF, before anything else. Every path below is DERIVED
|
|
1919
|
+
// from `binPath`, so without this a partial install — npm never wrote the
|
|
1920
|
+
// `.bin` entry, or wrote one that is empty, a directory, or a symlink
|
|
1921
|
+
// dangling at a deleted target — verified `true` on the strength of a
|
|
1922
|
+
// package tree that nothing can execute, and `installNpmTool` then recorded
|
|
1923
|
+
// the install as SUCCEEDED. `classifyInstallOutcome` grades any non-"failed"
|
|
1924
|
+
// outcome as `⚠ unavailable (succeeded)`, so that answer re-hid exactly the
|
|
1925
|
+
// nightly row #2722 exists to expose. `statSync` FOLLOWS the link, which is
|
|
1926
|
+
// what makes missing and dangling one branch.
|
|
1927
|
+
try {
|
|
1928
|
+
const shim = statSync(binPath);
|
|
1929
|
+
if (!shim.isFile() || shim.size === 0)
|
|
1930
|
+
return fail("shim-not-a-file");
|
|
1931
|
+
}
|
|
1932
|
+
catch {
|
|
1933
|
+
return fail("shim-missing");
|
|
1934
|
+
}
|
|
1935
|
+
let manifest;
|
|
1936
|
+
try {
|
|
1937
|
+
manifest = JSON.parse(await fs.readFile(path.join(packageDir, "package.json"), "utf8"));
|
|
1938
|
+
}
|
|
1939
|
+
catch {
|
|
1940
|
+
return fail("package-json-unreadable");
|
|
1941
|
+
}
|
|
1942
|
+
if (typeof manifest.version !== "string" || !manifest.version) {
|
|
1943
|
+
return fail("package-json-no-version");
|
|
1944
|
+
}
|
|
1945
|
+
const bin = manifest.bin;
|
|
1946
|
+
const entry = typeof bin === "string"
|
|
1947
|
+
? bin
|
|
1948
|
+
: bin && typeof bin === "object"
|
|
1949
|
+
? Object.entries(bin).find(
|
|
1950
|
+
// Case-folded on purpose: on a case-insensitive filesystem the
|
|
1951
|
+
// shim on disk can differ in case from the manifest key npm
|
|
1952
|
+
// wrote it from, and `path.basename` reads the disk name.
|
|
1953
|
+
([name]) => name.toLowerCase() === shimName)?.[1]
|
|
1954
|
+
: undefined;
|
|
1955
|
+
if (typeof entry !== "string" || !entry) {
|
|
1956
|
+
return fail("package-json-no-entry");
|
|
1957
|
+
}
|
|
1958
|
+
try {
|
|
1959
|
+
const stat = statSync(path.join(packageDir, entry));
|
|
1960
|
+
if (!stat.isFile() || stat.size === 0)
|
|
1961
|
+
return fail("entry-not-a-file");
|
|
1962
|
+
}
|
|
1963
|
+
catch {
|
|
1964
|
+
return fail("entry-missing");
|
|
1965
|
+
}
|
|
1966
|
+
// R2-F3 (catalog shape 31): "did the new verifier run at all, and on what"
|
|
1967
|
+
// has to be answerable from sessionstart.log, not only from a debug build —
|
|
1968
|
+
// the failure branches above already log there. Measured volume on a real
|
|
1969
|
+
// intelephense install, scratch PI_LENS_HOME: TWO rows on the session that
|
|
1970
|
+
// installs (installNpmTool's verify, then the post-install resolution), and
|
|
1971
|
+
// ZERO on every later session — the probe cache answers before any verify
|
|
1972
|
+
// runs (`auto-install ensure intelephense: probe cache hit`).
|
|
1973
|
+
logSessionStart(`auto-install verify: succeeded for ${binPath} (check=package-entry, version=${manifest.version}, entry=${entry})`);
|
|
1974
|
+
return true;
|
|
1975
|
+
}
|
|
1848
1976
|
/**
|
|
1849
1977
|
* Verify a tool binary actually works by running its configured checkArgs.
|
|
1850
1978
|
* This catches broken symlinks, partial installs, and corrupted binaries.
|
|
@@ -1872,7 +2000,26 @@ onTransient,
|
|
|
1872
2000
|
* sensitive caller on the dispatch hot path passes a shorter one and treats
|
|
1873
2001
|
* the expiry as transient rather than as a verdict (#1657).
|
|
1874
2002
|
*/
|
|
1875
|
-
timeoutMs = 10000, verificationArgs = ["--version"]
|
|
2003
|
+
timeoutMs = 10000, verificationArgs = ["--version"],
|
|
2004
|
+
/**
|
|
2005
|
+
* Package name from {@link packageEntryVerification} — present only for a
|
|
2006
|
+
* registry entry declaring `verification: "package-entry"`. When present the
|
|
2007
|
+
* spawn is skipped entirely and {@link verifyNpmPackageEntry} answers (#2722).
|
|
2008
|
+
*/
|
|
2009
|
+
packageEntryOf,
|
|
2010
|
+
/**
|
|
2011
|
+
* Called when a `false` verdict is INCONCLUSIVE rather than a verdict: the
|
|
2012
|
+
* transport-required matcher was armed, never matched, and the child's
|
|
2013
|
+
* output was cut off before the tail arrived, so the #208 rescue could not
|
|
2014
|
+
* be evaluated at all (#2722). Distinct from `onTransient` on purpose — the
|
|
2015
|
+
* prober DID run to completion and re-probing reproduces it exactly, so this
|
|
2016
|
+
* is a durable "cannot be verified", not a stall (catalog shape 13). A
|
|
2017
|
+
* caller must not treat it as "broken" and delete the installation.
|
|
2018
|
+
*/
|
|
2019
|
+
onInconclusive) {
|
|
2020
|
+
if (packageEntryOf !== undefined) {
|
|
2021
|
+
return verifyNpmPackageEntry(binPath, packageEntryOf);
|
|
2022
|
+
}
|
|
1876
2023
|
// #2015: safeSpawnAsync instead of raw spawn. Raw spawn's timeout
|
|
1877
2024
|
// SIGTERMed only cmd.exe on Windows (.cmd shims run shell:true), orphaning
|
|
1878
2025
|
// the grandchild node process - which kept scanning, held handles against
|
|
@@ -1931,6 +2078,31 @@ timeoutMs = 10000, verificationArgs = ["--version"]) {
|
|
|
1931
2078
|
// verdict from the binary (#1569 transient semantics).
|
|
1932
2079
|
if (result.signal !== undefined || result.spawnFailure)
|
|
1933
2080
|
onTransient?.();
|
|
2081
|
+
if (result.outputTruncated &&
|
|
2082
|
+
result.signal === undefined &&
|
|
2083
|
+
!result.spawnFailure) {
|
|
2084
|
+
// #2722: the transport-required matcher above is armed on EVERY probe,
|
|
2085
|
+
// and it never matched — but the output we kept is a prefix, so the
|
|
2086
|
+
// marker may simply sit past it (intelephense emits ~4 MB of bundle
|
|
2087
|
+
// ahead of its own diagnostic). "Unmatched within a truncated prefix"
|
|
2088
|
+
// is not "this binary is broken"; callers must not delete the install
|
|
2089
|
+
// on it. Recorded as its own kind so a monitor can tell an unreadable
|
|
2090
|
+
// probe apart from a rejected binary.
|
|
2091
|
+
//
|
|
2092
|
+
// R2-F4: gated on the probe having actually FINISHED. A verbose child
|
|
2093
|
+
// that is SIGTERMed at the timeout also arrives here truncated, and
|
|
2094
|
+
// that is the #1569 transient class one line above, not this one —
|
|
2095
|
+
// ungated, the two overlapped and `installNpmTool` (which tests
|
|
2096
|
+
// inconclusive first) replaced the #2015 transient message with this
|
|
2097
|
+
// one. The doc comment's "the prober DID run to completion" is now
|
|
2098
|
+
// true rather than aspirational.
|
|
2099
|
+
onInconclusive?.();
|
|
2100
|
+
recordDegradationOnce({
|
|
2101
|
+
kind: "installer-verification-inconclusive",
|
|
2102
|
+
subject: binPath,
|
|
2103
|
+
reason: `transport-required marker unresolved in truncated output (${verificationArgs.join(" ")})`,
|
|
2104
|
+
});
|
|
2105
|
+
}
|
|
1934
2106
|
const kind = result.spawnFailure?.kind ??
|
|
1935
2107
|
(result.signal
|
|
1936
2108
|
? `killed-signal=${result.signal}`
|
|
@@ -2050,7 +2222,7 @@ export async function getAllToolStatuses() {
|
|
|
2050
2222
|
const localPath = installerPlatform() === "win32" ? `${localBase}.cmd` : localBase;
|
|
2051
2223
|
try {
|
|
2052
2224
|
await fs.access(localPath);
|
|
2053
|
-
if (await verifyToolBinary(localPath, undefined, undefined, getToolVerificationTimeout(tool), tool.checkArgs)) {
|
|
2225
|
+
if (await verifyToolBinary(localPath, undefined, undefined, getToolVerificationTimeout(tool), tool.checkArgs, packageEntryVerification(tool))) {
|
|
2054
2226
|
status.installed = true;
|
|
2055
2227
|
status.source = "pi-lens-auto";
|
|
2056
2228
|
status.path = localPath;
|
|
@@ -2219,7 +2391,7 @@ async function getToolPathResolved(toolId, onTransient) {
|
|
|
2219
2391
|
const cmdPath = `${localBase}.cmd`;
|
|
2220
2392
|
try {
|
|
2221
2393
|
await fs.access(cmdPath);
|
|
2222
|
-
if (await verifyToolBinary(cmdPath, recordVersion, onTransient, getToolVerificationTimeout(tool), tool.checkArgs)) {
|
|
2394
|
+
if (await verifyToolBinary(cmdPath, recordVersion, onTransient, getToolVerificationTimeout(tool), tool.checkArgs, packageEntryVerification(tool))) {
|
|
2223
2395
|
return cmdPath;
|
|
2224
2396
|
}
|
|
2225
2397
|
logSessionStart(`auto-install verify: ${cmdPath} exists but is broken, will reinstall`);
|
|
@@ -2232,7 +2404,7 @@ async function getToolPathResolved(toolId, onTransient) {
|
|
|
2232
2404
|
const exePath = `${localBase}.exe`;
|
|
2233
2405
|
try {
|
|
2234
2406
|
await fs.access(exePath);
|
|
2235
|
-
if (await verifyToolBinary(exePath, recordVersion, onTransient, getToolVerificationTimeout(tool), tool.checkArgs)) {
|
|
2407
|
+
if (await verifyToolBinary(exePath, recordVersion, onTransient, getToolVerificationTimeout(tool), tool.checkArgs, packageEntryVerification(tool))) {
|
|
2236
2408
|
return exePath;
|
|
2237
2409
|
}
|
|
2238
2410
|
logSessionStart(`auto-install verify: ${exePath} exists but is broken, will reinstall`);
|
|
@@ -2244,7 +2416,7 @@ async function getToolPathResolved(toolId, onTransient) {
|
|
|
2244
2416
|
if (installerPlatform() !== "win32") {
|
|
2245
2417
|
try {
|
|
2246
2418
|
await fs.access(localBase);
|
|
2247
|
-
if (await verifyToolBinary(localBase, recordVersion, onTransient, getToolVerificationTimeout(tool), tool.checkArgs)) {
|
|
2419
|
+
if (await verifyToolBinary(localBase, recordVersion, onTransient, getToolVerificationTimeout(tool), tool.checkArgs, packageEntryVerification(tool))) {
|
|
2248
2420
|
return localBase;
|
|
2249
2421
|
}
|
|
2250
2422
|
logSessionStart(`auto-install verify: ${localBase} exists but is broken, will reinstall`);
|
|
@@ -2867,6 +3039,7 @@ export function npmToolNeedsPostinstall(packageName) {
|
|
|
2867
3039
|
* that wanders off it.
|
|
2868
3040
|
*/
|
|
2869
3041
|
export function getRefreshableManagedNpmTools() {
|
|
3042
|
+
const seenPackages = new Set();
|
|
2870
3043
|
return getRefreshableManagedTools()
|
|
2871
3044
|
.filter((candidate) => candidate.strategy === "npm")
|
|
2872
3045
|
.map((candidate) => ({
|
|
@@ -2875,7 +3048,13 @@ export function getRefreshableManagedNpmTools() {
|
|
|
2875
3048
|
// have both, so these are total.
|
|
2876
3049
|
packageName: candidate.packageName,
|
|
2877
3050
|
binaryName: candidate.binaryName,
|
|
2878
|
-
}))
|
|
3051
|
+
}))
|
|
3052
|
+
.filter((candidate) => {
|
|
3053
|
+
if (seenPackages.has(candidate.packageName))
|
|
3054
|
+
return false;
|
|
3055
|
+
seenPackages.add(candidate.packageName);
|
|
3056
|
+
return true;
|
|
3057
|
+
});
|
|
2879
3058
|
}
|
|
2880
3059
|
/** The Maven GAV a `maven` entry pins, as a stable identity string. */
|
|
2881
3060
|
function mavenCoordinate(spec) {
|
|
@@ -2922,6 +3101,7 @@ export function getRefreshableManagedTools() {
|
|
|
2922
3101
|
packageName: tool.packageName,
|
|
2923
3102
|
binaryName: tool.binaryName,
|
|
2924
3103
|
verificationTimeoutMs: tool.verificationTimeoutMs,
|
|
3104
|
+
packageEntryOf: packageEntryVerification(tool),
|
|
2925
3105
|
});
|
|
2926
3106
|
break;
|
|
2927
3107
|
}
|
|
@@ -3303,10 +3483,10 @@ async function refreshPackageManagerManagedTool(tool) {
|
|
|
3303
3483
|
const installed = tool.installStrategy === "pip"
|
|
3304
3484
|
? // `-U` is the whole fix: without it pip treats the installed copy as
|
|
3305
3485
|
// satisfying the requirement and the day-one version never moves.
|
|
3306
|
-
await installPipTool(tool.packageName, { upgrade: true })
|
|
3486
|
+
await installPipTool(tool.id, tool.packageName, { upgrade: true })
|
|
3307
3487
|
: // `gem install` always fetches the newest version that satisfies the
|
|
3308
3488
|
// requirement, so the install command IS the upgrade command.
|
|
3309
|
-
await installGemTool(tool.packageName);
|
|
3489
|
+
await installGemTool(tool.id, tool.packageName);
|
|
3310
3490
|
if (!installed) {
|
|
3311
3491
|
return {
|
|
3312
3492
|
ok: false,
|
|
@@ -3734,7 +3914,26 @@ async function installArchiveTool(tool) {
|
|
|
3734
3914
|
return undefined;
|
|
3735
3915
|
}
|
|
3736
3916
|
}
|
|
3737
|
-
|
|
3917
|
+
/**
|
|
3918
|
+
* Record a genuine package-manager install exception against `toolId` and
|
|
3919
|
+
* log it — the one place `installNpmTool`/`installPipTool`/`installGemTool`'s
|
|
3920
|
+
* catch blocks funnel through (#2661 review F3/Sonar: the three catches were
|
|
3921
|
+
* byte-identical but for the strategy label, a duplication SonarCloud's new-
|
|
3922
|
+
* code gate correctly flagged). The real error (registry E404, EBADENGINE, a
|
|
3923
|
+
* network failure, "no version satisfies…") lands in `installFailureReasons`
|
|
3924
|
+
* so a caller that distinguishes a genuine installer defect from a policy
|
|
3925
|
+
* decline (the tool-smoke lane, #2638) sees the actual message, never the
|
|
3926
|
+
* generic fallback `finishInstallAttempt` uses when nothing set it.
|
|
3927
|
+
*/
|
|
3928
|
+
function recordPackageManagerInstallException(toolId, strategyLabel, packageName, err) {
|
|
3929
|
+
const message = err.message;
|
|
3930
|
+
logSessionStart(`auto-install ${strategyLabel} ${packageName}: exception: ${message}`);
|
|
3931
|
+
installFailureReasons.set(toolId, message);
|
|
3932
|
+
return undefined;
|
|
3933
|
+
}
|
|
3934
|
+
async function installNpmTool(toolId, packageName, binaryName, verificationArgs = ["--version"], verificationTimeoutMs = 10_000,
|
|
3935
|
+
/** See {@link packageEntryVerification} — spawn-free verification (#2722). */
|
|
3936
|
+
packageEntryOf) {
|
|
3738
3937
|
try {
|
|
3739
3938
|
// Ensure tools directory exists
|
|
3740
3939
|
await fs.mkdir(TOOLS_DIR, { recursive: true });
|
|
@@ -3814,11 +4013,15 @@ async function installNpmTool(packageName, binaryName, verificationArgs = ["--ve
|
|
|
3814
4013
|
debugLog(`Verifying ${binaryName}...`);
|
|
3815
4014
|
let isValid = false;
|
|
3816
4015
|
let lastAttemptTransient = false;
|
|
4016
|
+
let lastAttemptInconclusive = false;
|
|
3817
4017
|
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
3818
4018
|
lastAttemptTransient = false;
|
|
4019
|
+
lastAttemptInconclusive = false;
|
|
3819
4020
|
isValid = await verifyToolBinary(binPath, undefined, () => {
|
|
3820
4021
|
lastAttemptTransient = true;
|
|
3821
|
-
}, verificationTimeoutMs, verificationArgs)
|
|
4022
|
+
}, verificationTimeoutMs, verificationArgs, packageEntryOf, () => {
|
|
4023
|
+
lastAttemptInconclusive = true;
|
|
4024
|
+
});
|
|
3822
4025
|
if (isValid)
|
|
3823
4026
|
break;
|
|
3824
4027
|
if (attempt < 3) {
|
|
@@ -3826,6 +4029,37 @@ async function installNpmTool(packageName, binaryName, verificationArgs = ["--ve
|
|
|
3826
4029
|
await new Promise((r) => setTimeout(r, 1000 * attempt));
|
|
3827
4030
|
}
|
|
3828
4031
|
}
|
|
4032
|
+
if (!isValid && lastAttemptInconclusive) {
|
|
4033
|
+
// #2722: the probe ran to completion but could not decide — the #208
|
|
4034
|
+
// transport-required matcher was armed, never matched, and the kept
|
|
4035
|
+
// output is a truncated prefix, so the marker may sit past it (the
|
|
4036
|
+
// class intelephense fell into: ~4 MB of bundle ahead of the marker,
|
|
4037
|
+
// unreachable through any pipe). Same rule as the transient branch
|
|
4038
|
+
// below (#2015): a non-verdict must not delete a freshly installed
|
|
4039
|
+
// package. Deliberately NOT folded into `lastAttemptTransient` —
|
|
4040
|
+
// re-probing reproduces this exactly, so it is durable, and a
|
|
4041
|
+
// transient verdict would keep re-arming the reinstall path
|
|
4042
|
+
// (catalog shape 13).
|
|
4043
|
+
// R2-F2: a non-verdict is a reason to keep ONLY while the tree on disk
|
|
4044
|
+
// still looks like a complete install. With intelephense verified
|
|
4045
|
+
// spawn-free, no registry entry reaches this branch healthy (measured:
|
|
4046
|
+
// no other npm-strategy LSP server emits more than 1,527 bytes), so
|
|
4047
|
+
// its live population is BROKEN servers that spew past the retained
|
|
4048
|
+
// window and die — and for those the delete was the only repair that
|
|
4049
|
+
// existed. Measured on npm 9.2.0 against a real managed prefix: a
|
|
4050
|
+
// package file corrupted IN PLACE is not repaired by re-installing
|
|
4051
|
+
// (`up to date`, the zeroed file stays zeroed), while a package
|
|
4052
|
+
// directory, a `.bin` shim or a nested dependency that is GONE is
|
|
4053
|
+
// reinstalled. So the same on-disk evidence `verification:
|
|
4054
|
+
// "package-entry"` uses decides keep-vs-delete here — strictly as a
|
|
4055
|
+
// gate, never as a verdict: the install is still recorded as failed,
|
|
4056
|
+
// so the tool still reads `✗` and nothing is re-hidden.
|
|
4057
|
+
if (await verifyNpmPackageEntry(binPath, packageName)) {
|
|
4058
|
+
logSessionStart(`auto-install ${packageName}: verification inconclusive (output truncated before the transport-required marker) but the installed tree is intact; keeping installation for re-probe`);
|
|
4059
|
+
return undefined;
|
|
4060
|
+
}
|
|
4061
|
+
logSessionStart(`auto-install ${packageName}: verification inconclusive AND the installed tree is incomplete; cleaning up so the next install can repair it`);
|
|
4062
|
+
}
|
|
3829
4063
|
if (!isValid && lastAttemptTransient) {
|
|
3830
4064
|
// #2015: a killed/spawn-failed prober is NOT a verdict about the
|
|
3831
4065
|
// binary (#1569 semantics). Cold-start verifies on fresh installs
|
|
@@ -3858,14 +4092,26 @@ async function installNpmTool(packageName, binaryName, verificationArgs = ["--ve
|
|
|
3858
4092
|
return binPath;
|
|
3859
4093
|
}
|
|
3860
4094
|
catch (err) {
|
|
3861
|
-
|
|
3862
|
-
return undefined;
|
|
4095
|
+
return recordPackageManagerInstallException(toolId, "npm", packageName, err);
|
|
3863
4096
|
}
|
|
3864
4097
|
}
|
|
4098
|
+
/**
|
|
4099
|
+
* The pip command ladder `installPipTool` tries, per platform, in priority
|
|
4100
|
+
* order — exported so a caller that needs to know "is ANY pip toolchain
|
|
4101
|
+
* reachable on this runner" (without running an install) probes the SAME
|
|
4102
|
+
* candidates rather than a second, narrower guess (#2661 review F4/S5: the
|
|
4103
|
+
* tool-smoke lane's own presence check tried bare `pip` only and missed a
|
|
4104
|
+
* `pip3`-only or python-module-only runner).
|
|
4105
|
+
*/
|
|
4106
|
+
export function pipCommandCandidates() {
|
|
4107
|
+
return process.platform === "win32"
|
|
4108
|
+
? ["pip", "py", "python"]
|
|
4109
|
+
: ["pip3", "pip", "python3", "python"];
|
|
4110
|
+
}
|
|
3865
4111
|
/**
|
|
3866
4112
|
* Install a pip package tool
|
|
3867
4113
|
*/
|
|
3868
|
-
async function installPipTool(packageName,
|
|
4114
|
+
async function installPipTool(toolId, packageName,
|
|
3869
4115
|
/**
|
|
3870
4116
|
* Add `-U`, turning the install into an upgrade. Without it `pip install`
|
|
3871
4117
|
* treats an already-present package as satisfied and leaves the day-one
|
|
@@ -3880,30 +4126,16 @@ options = {}) {
|
|
|
3880
4126
|
const verb = options.upgrade
|
|
3881
4127
|
? ["install", "-U", "--user"]
|
|
3882
4128
|
: ["install", "--user"];
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
},
|
|
3894
|
-
]
|
|
3895
|
-
: [
|
|
3896
|
-
{ command: "pip3", args: [...verb, packageName] },
|
|
3897
|
-
{ command: "pip", args: [...verb, packageName] },
|
|
3898
|
-
{
|
|
3899
|
-
command: "python3",
|
|
3900
|
-
args: ["-m", "pip", ...verb, packageName],
|
|
3901
|
-
},
|
|
3902
|
-
{
|
|
3903
|
-
command: "python",
|
|
3904
|
-
args: ["-m", "pip", ...verb, packageName],
|
|
3905
|
-
},
|
|
3906
|
-
];
|
|
4129
|
+
// Built from `pipCommandCandidates()` — the single source of truth this
|
|
4130
|
+
// module and any other caller (the tool-smoke lane's toolchain-presence
|
|
4131
|
+
// probe, #2661 review) share, rather than a second, independently
|
|
4132
|
+
// maintained ladder that can drift.
|
|
4133
|
+
const pipCandidates = pipCommandCandidates().map((command) => ({
|
|
4134
|
+
command,
|
|
4135
|
+
args: command === "pip" || command === "pip3"
|
|
4136
|
+
? [...verb, packageName]
|
|
4137
|
+
: ["-m", "pip", ...verb, packageName],
|
|
4138
|
+
}));
|
|
3907
4139
|
let lastError = "";
|
|
3908
4140
|
for (const candidate of pipCandidates) {
|
|
3909
4141
|
const pipResult = await safeSpawnAsync(candidate.command, candidate.args, {
|
|
@@ -4000,11 +4232,10 @@ options = {}) {
|
|
|
4000
4232
|
throw new Error(`Failed to install ${packageName}: no usable pip command found (${lastError || "unknown error"})`);
|
|
4001
4233
|
}
|
|
4002
4234
|
catch (err) {
|
|
4003
|
-
|
|
4004
|
-
return undefined;
|
|
4235
|
+
return recordPackageManagerInstallException(toolId, "pip", packageName, err);
|
|
4005
4236
|
}
|
|
4006
4237
|
}
|
|
4007
|
-
async function installGemTool(packageName) {
|
|
4238
|
+
async function installGemTool(toolId, packageName) {
|
|
4008
4239
|
try {
|
|
4009
4240
|
const gemResult = await safeSpawnAsync("gem", ["install", packageName, "--no-document"], {
|
|
4010
4241
|
timeout: 120_000,
|
|
@@ -4021,8 +4252,7 @@ async function installGemTool(packageName) {
|
|
|
4021
4252
|
return packageName;
|
|
4022
4253
|
}
|
|
4023
4254
|
catch (err) {
|
|
4024
|
-
|
|
4025
|
-
return undefined;
|
|
4255
|
+
return recordPackageManagerInstallException(toolId, "gem", packageName, err);
|
|
4026
4256
|
}
|
|
4027
4257
|
}
|
|
4028
4258
|
/**
|
|
@@ -4113,7 +4343,7 @@ export async function installTool(toolId) {
|
|
|
4113
4343
|
case "npm": {
|
|
4114
4344
|
if (!tool.packageName || !tool.binaryName)
|
|
4115
4345
|
return false;
|
|
4116
|
-
const npmPath = await installNpmTool(tool.packageName, tool.binaryName, tool.checkArgs, getToolVerificationTimeout(tool));
|
|
4346
|
+
const npmPath = await installNpmTool(tool.id, tool.packageName, tool.binaryName, tool.checkArgs, getToolVerificationTimeout(tool), packageEntryVerification(tool));
|
|
4117
4347
|
if (npmPath !== undefined) {
|
|
4118
4348
|
// #1746 review F4: an install just resolved this package's range
|
|
4119
4349
|
// against the registry, so record it as freshly checked. Otherwise a
|
|
@@ -4139,13 +4369,13 @@ export async function installTool(toolId) {
|
|
|
4139
4369
|
case "pip": {
|
|
4140
4370
|
if (!tool.packageName)
|
|
4141
4371
|
return false;
|
|
4142
|
-
const pipPath = await installPipTool(tool.packageName);
|
|
4372
|
+
const pipPath = await installPipTool(tool.id, tool.packageName);
|
|
4143
4373
|
return finishInstallAttempt(tool.id, pipPath !== undefined, startedAt);
|
|
4144
4374
|
}
|
|
4145
4375
|
case "gem": {
|
|
4146
4376
|
if (!tool.packageName)
|
|
4147
4377
|
return false;
|
|
4148
|
-
const gemPath = await installGemTool(tool.packageName);
|
|
4378
|
+
const gemPath = await installGemTool(tool.id, tool.packageName);
|
|
4149
4379
|
return finishInstallAttempt(tool.id, gemPath !== undefined, startedAt);
|
|
4150
4380
|
}
|
|
4151
4381
|
case "github": {
|