@herbertgao/pi-extensions 2026.9.1 → 2026.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/THIRD_PARTY_NOTICES.md +24 -0
- package/node_modules/@herbertgao/sol-pi/LICENSE +19 -0
- package/node_modules/@herbertgao/sol-pi/README.md +159 -0
- package/node_modules/@herbertgao/sol-pi/SECURITY.md +26 -0
- package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +19 -0
- package/node_modules/@herbertgao/sol-pi/agents-install.md +150 -0
- package/node_modules/@herbertgao/sol-pi/assets/sol-pi-hero.png +0 -0
- package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +69 -0
- package/node_modules/@herbertgao/sol-pi/docs/configuration.md +75 -0
- package/node_modules/@herbertgao/sol-pi/package.json +76 -0
- package/node_modules/@herbertgao/sol-pi/scripts/check-pi-compat.mjs +32 -0
- package/node_modules/@herbertgao/sol-pi/scripts/check-sol-pi-config.mjs +120 -0
- package/node_modules/@herbertgao/sol-pi/sol-pi.example.json +10 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/config.ts +135 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/file-queue.ts +74 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +185 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/then-run.ts +128 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/archive.ts +53 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/candidate.ts +101 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/config.ts +71 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/index.ts +220 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/journal.ts +25 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/provider.ts +164 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/receipt.ts +177 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/index.ts +227 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/ledger.ts +20 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/observation.ts +252 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/economics.ts +237 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/extension.ts +455 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/index.ts +49 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/plan.ts +79 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +208 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/tools.ts +100 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/index.ts +42 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/runtime-paths.ts +17 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/tui.ts +71 -0
- package/node_modules/@narumitw/pi-btw/README.md +57 -141
- package/node_modules/@narumitw/pi-btw/dist/index.ts +478 -43
- 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 +28 -3
- 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-lens/CHANGELOG.md +260 -0
- package/node_modules/pi-lens/README.md +13 -8
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +3 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +0 -7
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +1 -1
- package/node_modules/pi-lens/dist/clients/analysed-root.js +1 -0
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +1 -8
- 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 -1
- package/node_modules/pi-lens/dist/clients/biome-client.js +13 -2
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +0 -6
- package/node_modules/pi-lens/dist/clients/bootstrap.js +4 -4
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +1 -1
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +2 -5
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +1 -9
- package/node_modules/pi-lens/dist/clients/cache-observability.js +122 -6
- package/node_modules/pi-lens/dist/clients/cargo-manifest.js +2 -2
- package/node_modules/pi-lens/dist/clients/cascade-logger.js +0 -7
- package/node_modules/pi-lens/dist/clients/child-unref.js +1 -19
- package/node_modules/pi-lens/dist/clients/complexity-client.js +5 -0
- package/node_modules/pi-lens/dist/clients/config-core/index.js +11 -8
- package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +1 -1
- package/node_modules/pi-lens/dist/clients/config-core/provenance.js +2 -9
- package/node_modules/pi-lens/dist/clients/config-core/records.js +1 -1
- package/node_modules/pi-lens/dist/clients/config-core/schema.js +3 -5
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +3 -1
- package/node_modules/pi-lens/dist/clients/config-resolve.js +10 -7
- package/node_modules/pi-lens/dist/clients/config-schema.js +56 -2
- package/node_modules/pi-lens/dist/clients/config-warn.js +2 -2
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +8 -1
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +0 -4
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +5 -1
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +1 -1
- package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +0 -4
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +38 -41
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +18 -1
- 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 +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +7 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +19 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +15 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +3 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +12 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +5 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +5 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +2 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +1 -64
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +8 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils.js +0 -21
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +2 -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 +5 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +2 -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 +0 -7
- package/node_modules/pi-lens/dist/clients/effective-config.js +12 -2
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +2 -2
- package/node_modules/pi-lens/dist/clients/extension-log.js +2 -0
- package/node_modules/pi-lens/dist/clients/file-kinds.js +1 -38
- package/node_modules/pi-lens/dist/clients/file-role.js +18 -1
- package/node_modules/pi-lens/dist/clients/file-time.js +1 -1
- package/node_modules/pi-lens/dist/clients/file-utils.js +5 -1
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +4 -0
- package/node_modules/pi-lens/dist/clients/format-service.js +0 -1
- package/node_modules/pi-lens/dist/clients/formatters.js +66 -93
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +3 -4
- package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -0
- package/node_modules/pi-lens/dist/clients/git-guard.js +5 -0
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +42 -6
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +48 -7
- package/node_modules/pi-lens/dist/clients/grammar-source.js +3 -3
- package/node_modules/pi-lens/dist/clients/installer/index.js +416 -61
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +84 -18
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +6 -6
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +9 -1
- package/node_modules/pi-lens/dist/clients/knip-client.js +9 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +12 -11
- package/node_modules/pi-lens/dist/clients/language-registry.js +5 -1
- package/node_modules/pi-lens/dist/clients/latency-logger.js +7 -7
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -1
- package/node_modules/pi-lens/dist/clients/lens-config.js +23 -0
- package/node_modules/pi-lens/dist/clients/lens-engine.js +3 -4
- package/node_modules/pi-lens/dist/clients/lens-events.js +1 -1
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +18 -0
- package/node_modules/pi-lens/dist/clients/lens-map.js +1 -1
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +0 -36
- package/node_modules/pi-lens/dist/clients/lsp/client.js +4 -3
- package/node_modules/pi-lens/dist/clients/lsp/config.js +37 -7
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +24 -1
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +79 -1
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +3 -3
- package/node_modules/pi-lens/dist/clients/lsp/index.js +491 -64
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/language.js +0 -8
- 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 +0 -2
- package/node_modules/pi-lens/dist/clients/lsp/server.js +62 -15
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +0 -1
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +5 -5
- 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 +37 -4
- package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -1
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +3 -0
- package/node_modules/pi-lens/dist/clients/mcp/session.js +2 -0
- package/node_modules/pi-lens/dist/clients/metrics-history.js +28 -107
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +1 -1
- package/node_modules/pi-lens/dist/clients/module-report.js +1 -1
- package/node_modules/pi-lens/dist/clients/mutating-tool.js +3 -3
- package/node_modules/pi-lens/dist/clients/mutation-attribution.js +3 -3
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +0 -4
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +9 -9
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +2 -6
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +2 -0
- package/node_modules/pi-lens/dist/clients/opengrep-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/package-manager.js +2 -1
- package/node_modules/pi-lens/dist/clients/path-utils.js +23 -2
- package/node_modules/pi-lens/dist/clients/performance-report.js +2 -2
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +9 -4
- package/node_modules/pi-lens/dist/clients/pipeline.js +5 -4
- 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 +38 -10
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +10 -9
- 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 +1 -1
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +49 -1
- package/node_modules/pi-lens/dist/clients/project-scan-policy.js +3 -51
- package/node_modules/pi-lens/dist/clients/python-provenance.js +1 -1
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +3 -1
- package/node_modules/pi-lens/dist/clients/read-guard.js +5 -2
- package/node_modules/pi-lens/dist/clients/recent-touches.js +2 -2
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +3 -5
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +1 -1
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +2 -0
- package/node_modules/pi-lens/dist/clients/ruff-client.js +18 -9
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +10 -1
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +5 -0
- package/node_modules/pi-lens/dist/clients/runtime-session.js +58 -14
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +11 -1
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +4 -1
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +48 -1
- package/node_modules/pi-lens/dist/clients/sanitize.js +0 -11
- package/node_modules/pi-lens/dist/clients/scan-utils.js +1 -56
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +2 -2
- package/node_modules/pi-lens/dist/clients/session-event-guard.js +69 -1
- package/node_modules/pi-lens/dist/clients/session-summary.js +0 -24
- package/node_modules/pi-lens/dist/clients/sg-runner.js +2 -1
- package/node_modules/pi-lens/dist/clients/sgconfig.js +1 -5
- package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +1 -1
- package/node_modules/pi-lens/dist/clients/situational-tool-telemetry.js +108 -0
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +2 -2
- package/node_modules/pi-lens/dist/clients/startup-scan.js +2 -10
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +291 -76
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +77 -72
- package/node_modules/pi-lens/dist/clients/tool-config.js +199 -0
- package/node_modules/pi-lens/dist/clients/tool-cwd.js +299 -0
- package/node_modules/pi-lens/dist/clients/tool-policy.js +1 -1
- package/node_modules/pi-lens/dist/clients/tool-probe.js +53 -0
- package/node_modules/pi-lens/dist/clients/tool-set-policy.js +42 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +1 -52
- package/node_modules/pi-lens/dist/clients/trivy-client.js +9 -1
- package/node_modules/pi-lens/dist/clients/tui-fit.js +0 -4
- package/node_modules/pi-lens/dist/clients/turn-context.js +52 -0
- package/node_modules/pi-lens/dist/clients/user-notify.js +0 -4
- package/node_modules/pi-lens/dist/clients/widget-state.js +4 -3
- package/node_modules/pi-lens/dist/clients/word-index-logger.js +0 -7
- package/node_modules/pi-lens/dist/clients/word-index-store.js +3 -7
- package/node_modules/pi-lens/dist/clients/word-index.js +9 -16
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +1 -1
- package/node_modules/pi-lens/dist/index.js +19969 -17481
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -2
- package/node_modules/pi-lens/dist/mcp/build-staleness.js +1 -1
- package/node_modules/pi-lens/dist/mcp/server.js +135 -159
- package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +1 -1
- package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +1 -1
- package/node_modules/pi-lens/dist/tools/activate-tools.js +10 -7
- package/node_modules/pi-lens/dist/tools/ast-grep-outline.js +2 -13
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +8 -13
- package/node_modules/pi-lens/dist/tools/ast-grep-search.js +83 -39
- package/node_modules/pi-lens/dist/tools/effective-config.js +4 -3
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +1 -10
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +354 -86
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +54 -112
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +20 -44
- package/node_modules/pi-lens/dist/tools/lsp-structured-output.js +3 -3
- package/node_modules/pi-lens/dist/tools/module-report.js +5 -9
- package/node_modules/pi-lens/dist/tools/project-report.js +9 -17
- package/node_modules/pi-lens/dist/tools/render-compact.js +281 -2
- package/node_modules/pi-lens/dist/tools/symbol-search.js +3 -4
- package/node_modules/pi-lens/docs/agent-guide.md +3 -4
- package/node_modules/pi-lens/docs/agent-tools.md +46 -22
- package/node_modules/pi-lens/docs/configuration.md +9 -0
- package/node_modules/pi-lens/docs/environment-variables.md +0 -5
- package/node_modules/pi-lens/docs/features.md +5 -5
- package/node_modules/pi-lens/docs/globalconfig.md +31 -1
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +9 -1
- package/node_modules/pi-lens/docs/mcp.md +13 -1
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +71 -0
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +15 -0
- package/node_modules/pi-lens/docs/pi-lens-monitor.md +88 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +41 -0
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +21 -2
- package/node_modules/pi-lens/docs/public-api-stability.md +1 -0
- package/node_modules/pi-lens/docs/real-harness.md +46 -0
- package/node_modules/pi-lens/docs/release-qa-baseline.md +17 -5
- package/node_modules/pi-lens/docs/servercapabilities.md +2 -3
- package/node_modules/pi-lens/docs/settings.md +37 -2
- package/node_modules/pi-lens/docs/tools_improvement2.md +4 -4
- package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +1 -1
- package/node_modules/pi-lens/docs/usage.md +13 -3
- package/node_modules/pi-lens/docs/word-index.md +1 -1
- package/node_modules/pi-lens/package.json +15 -15
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +7 -3
- package/node_modules/pi-lens/rules/typos/_typos.toml +4 -2
- package/node_modules/pi-lens/scripts/lib/skills-predicate.mjs +1 -1
- package/node_modules/pi-lens/scripts/lib/warm-loader-cache.mjs +1 -1
- package/node_modules/pi-lens/scripts/warm-loader-cache.mjs +4 -2
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +8 -6
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +19 -9
- package/node_modules/pi-web-access/CHANGELOG.md +29 -0
- package/node_modules/pi-web-access/README.md +33 -22
- package/node_modules/pi-web-access/abortable.ts +17 -0
- package/node_modules/pi-web-access/crawl4ai.ts +204 -0
- package/node_modules/pi-web-access/credential-source.ts +1 -0
- package/node_modules/pi-web-access/curator-page.ts +20 -2
- package/node_modules/pi-web-access/curator-run.ts +44 -0
- package/node_modules/pi-web-access/curator-server.ts +3 -1
- package/node_modules/pi-web-access/duckduckgo.ts +1 -1
- package/node_modules/pi-web-access/extract.ts +57 -12
- package/node_modules/pi-web-access/fetch-params.ts +1 -1
- package/node_modules/pi-web-access/gemini-search.ts +9 -5
- package/node_modules/pi-web-access/index.ts +25 -18
- package/node_modules/pi-web-access/openai-search.ts +35 -13
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/page-query.ts +5 -2
- package/node_modules/pi-web-access/query-rewrite.ts +5 -2
- package/node_modules/pi-web-access/serpapi.ts +220 -0
- package/node_modules/pi-web-access/ssrf-protection.ts +5 -1
- package/node_modules/pi-web-access/storage.ts +10 -0
- package/node_modules/pi-web-access/summary-review.ts +34 -21
- package/node_modules/pi-web-access/utils.ts +6 -4
- package/package.json +7 -4
- package/node_modules/pi-lens/dist/tools/ast-dump.js +0 -103
|
@@ -42,8 +42,9 @@ import { LEGACY_ROOT_LSP_KEYS, LSP_NAMESPACE_KEY } from "./config-locations.js";
|
|
|
42
42
|
// every config loader's import graph for one type alias.
|
|
43
43
|
import { DENY_KEY, } from "./config-core/schema.js";
|
|
44
44
|
import { flagConfigSectionKeys, GLOBAL_NON_FLAG_CONFIG_SECTIONS, LENS_FLAGS, PROJECT_FOREIGN_CONFIG_NAMESPACES, PROJECT_NON_FLAG_CONFIG_SECTIONS, } from "./lens-flag-registry.js";
|
|
45
|
+
import { LENS_TOOL_NAMES } from "./tool-config.js";
|
|
45
46
|
/** The JSON Schema dialect the published artifact declares. */
|
|
46
|
-
|
|
47
|
+
const CONFIG_SCHEMA_DIALECT = "https://json-schema.org/draft/2020-12/schema";
|
|
47
48
|
/**
|
|
48
49
|
* A node the schema says nothing else about. `config-core` treats a node with
|
|
49
50
|
* no `type` as opaque and walks its children OPEN, so an undeclared section
|
|
@@ -109,7 +110,6 @@ export { LSP_KEY_TYPES };
|
|
|
109
110
|
const LSP_KEY_DENY = {
|
|
110
111
|
disabledServers: "array-union",
|
|
111
112
|
};
|
|
112
|
-
export { LSP_KEY_DENY };
|
|
113
113
|
/** The `x-deny` annotation for a key, or nothing when it carries no denial. */
|
|
114
114
|
function denyAnnotation(key) {
|
|
115
115
|
const policy = LSP_KEY_DENY[key];
|
|
@@ -155,12 +155,66 @@ function buildConfigSchema() {
|
|
|
155
155
|
]) {
|
|
156
156
|
properties[key] = opaque("stable");
|
|
157
157
|
}
|
|
158
|
+
properties.tools = {
|
|
159
|
+
type: "object",
|
|
160
|
+
additionalProperties: true,
|
|
161
|
+
properties: Object.fromEntries(LENS_TOOL_NAMES.map((name) => [
|
|
162
|
+
name,
|
|
163
|
+
{
|
|
164
|
+
type: "object",
|
|
165
|
+
additionalProperties: true,
|
|
166
|
+
properties: {
|
|
167
|
+
enabled: { type: "boolean", [STABILITY_TIER_KEY]: "experimental" },
|
|
168
|
+
},
|
|
169
|
+
[STABILITY_TIER_KEY]: "experimental",
|
|
170
|
+
},
|
|
171
|
+
])),
|
|
172
|
+
[STABILITY_TIER_KEY]: "stable",
|
|
173
|
+
};
|
|
158
174
|
// Namespaces owned by another tool that ride in the same file (`trivy`,
|
|
159
175
|
// `helm`). Reserved so they survive validation, `experimental` because their
|
|
160
176
|
// shape belongs to those runners, not to this schema.
|
|
161
177
|
for (const key of PROJECT_FOREIGN_CONFIG_NAMESPACES) {
|
|
162
178
|
properties[key] ??= opaque("experimental");
|
|
163
179
|
}
|
|
180
|
+
for (const key of [
|
|
181
|
+
"knip",
|
|
182
|
+
"jscpd",
|
|
183
|
+
"madge",
|
|
184
|
+
"gitleaks",
|
|
185
|
+
"govulncheck",
|
|
186
|
+
"deadCode",
|
|
187
|
+
"complexity",
|
|
188
|
+
]) {
|
|
189
|
+
properties[key] = {
|
|
190
|
+
type: "object",
|
|
191
|
+
additionalProperties: true,
|
|
192
|
+
properties: {
|
|
193
|
+
enabled: { type: "boolean", [STABILITY_TIER_KEY]: "experimental" },
|
|
194
|
+
},
|
|
195
|
+
[STABILITY_TIER_KEY]: "stable",
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
properties.startup = {
|
|
199
|
+
type: "object",
|
|
200
|
+
additionalProperties: true,
|
|
201
|
+
properties: {
|
|
202
|
+
mode: {
|
|
203
|
+
type: "string",
|
|
204
|
+
enum: ["quick", "full", "minimal"],
|
|
205
|
+
[STABILITY_TIER_KEY]: "experimental",
|
|
206
|
+
},
|
|
207
|
+
scans: {
|
|
208
|
+
type: "object",
|
|
209
|
+
additionalProperties: true,
|
|
210
|
+
properties: {
|
|
211
|
+
enabled: { type: "boolean", [STABILITY_TIER_KEY]: "experimental" },
|
|
212
|
+
},
|
|
213
|
+
[STABILITY_TIER_KEY]: "experimental",
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
[STABILITY_TIER_KEY]: "stable",
|
|
217
|
+
};
|
|
164
218
|
// The four legacy ROOT LSP keys. Still accepted for their deprecation window
|
|
165
219
|
// (#2418 registry), and `experimental` because they are scheduled for
|
|
166
220
|
// removal — a `stable` tier on a key with a `removeNotBefore` would be two
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* extraction — the prose is not API (the code is), but silently rewording a
|
|
23
23
|
* warning inside a refactor is still not a thing this PR does.
|
|
24
24
|
*/
|
|
25
|
-
import { DEPRECATED_CONFIG_SURFACES, } from "./config-diagnostic-codes.js";
|
|
25
|
+
import { DEPRECATED_CONFIG_SURFACES, withConfigDiagnosticCode, } from "./config-diagnostic-codes.js";
|
|
26
26
|
import { recordDegradationOnce } from "./degradation-ledger.js";
|
|
27
27
|
import { errorClassName } from "./error-class.js";
|
|
28
28
|
import { logExtension } from "./extension-log.js";
|
|
@@ -378,7 +378,7 @@ export function warnIgnoredConfigOnce(options) {
|
|
|
378
378
|
logExtension({
|
|
379
379
|
subsystem,
|
|
380
380
|
level: "warn",
|
|
381
|
-
message,
|
|
381
|
+
message: withConfigDiagnosticCode(message, code),
|
|
382
382
|
metadata: { configPath: file, reason, code, ...(key ? { key } : {}) },
|
|
383
383
|
});
|
|
384
384
|
// HUMAN-audience too: a config the user wrote is being ignored. Routed
|
|
@@ -19,6 +19,7 @@ import { findLocalBinsAt, VENV_BIN_DIRS } from "./package-manager.js";
|
|
|
19
19
|
import { findNearestMarkerRoot } from "./path-utils.js";
|
|
20
20
|
import { getScratchTreeFnmatchPatterns } from "./scratch-tree-policy.js";
|
|
21
21
|
import { safeSpawnAsync } from "./safe-spawn.js";
|
|
22
|
+
import { probeToolAsync } from "./tool-probe.js";
|
|
22
23
|
import { classifyProbeFailure, createAvailabilityLatch, logAvailabilityDecision, startHostStallSampler, } from "./dispatch/runners/utils/availability-policy.js";
|
|
23
24
|
import { firstOutputLine, spawnFailedWithNoOutput, } from "./dispatch/runners/utils/spawn-outcome.js";
|
|
24
25
|
import { formatToolFailure } from "./dispatch/runners/utils/tool-failure.js";
|
|
@@ -229,7 +230,7 @@ export class PythonDeadCodeClient {
|
|
|
229
230
|
let probe;
|
|
230
231
|
let hostStallMs;
|
|
231
232
|
try {
|
|
232
|
-
probe = await
|
|
233
|
+
probe = await probeToolAsync(c.cmd, [...c.prefix, "--version"], {
|
|
233
234
|
timeout: 5000,
|
|
234
235
|
});
|
|
235
236
|
}
|
|
@@ -415,9 +416,13 @@ export class PythonDeadCodeClient {
|
|
|
415
416
|
durationMs,
|
|
416
417
|
};
|
|
417
418
|
}
|
|
419
|
+
// vulture's verified exit-code table (above): exit 0 with empty
|
|
420
|
+
// stdout IS the clean-run signal, so this ran over the root
|
|
421
|
+
// (#2154) — unlike knip, whose clean run always prints JSON.
|
|
418
422
|
return {
|
|
419
423
|
...emptyResult(this.language),
|
|
420
424
|
success: true,
|
|
425
|
+
analyzed: true,
|
|
421
426
|
summary: "No dead code found",
|
|
422
427
|
durationMs,
|
|
423
428
|
};
|
|
@@ -430,6 +435,8 @@ export class PythonDeadCodeClient {
|
|
|
430
435
|
return {
|
|
431
436
|
...emptyResult(this.language),
|
|
432
437
|
success: true,
|
|
438
|
+
// #2154: parsed vulture output for this root.
|
|
439
|
+
analyzed: true,
|
|
433
440
|
unusedExports,
|
|
434
441
|
summary: total === 0
|
|
435
442
|
? "No dead code found"
|
|
@@ -28,7 +28,3 @@ export function logDeadCodeScan(event) {
|
|
|
28
28
|
return;
|
|
29
29
|
writer.log({ ts: new Date().toISOString(), ...event });
|
|
30
30
|
}
|
|
31
|
-
/** Resolve once all enqueued dead-code writes are on disk (tests/shutdown). */
|
|
32
|
-
export function flushDeadCodeLog() {
|
|
33
|
-
return writer.flush();
|
|
34
|
-
}
|
|
@@ -815,7 +815,11 @@ export class DependencyChecker {
|
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
817
|
this.publishState(gen, circular, circularFiles);
|
|
818
|
-
|
|
818
|
+
// #2154: the one madge site that parsed a graph for this root. Every
|
|
819
|
+
// other return here (missing root, no top-level source file, madge
|
|
820
|
+
// unavailable, spawn error, parse throw) is the SAME empty shape and
|
|
821
|
+
// must not be read as "no cycles in this project".
|
|
822
|
+
return { circular, count: circular.length, analyzed: true };
|
|
819
823
|
}
|
|
820
824
|
catch (err) {
|
|
821
825
|
this.log(`Scan error: ${err.message}`);
|
|
@@ -128,7 +128,7 @@ export function computeStrictAnchor(args) {
|
|
|
128
128
|
});
|
|
129
129
|
}
|
|
130
130
|
/** Intent-level anchor — see module doc. Used for defer/flagged/suppress. */
|
|
131
|
-
|
|
131
|
+
function computeWeakAnchor(args) {
|
|
132
132
|
return stableFindingId("ddw:", {
|
|
133
133
|
cwd: args.cwd,
|
|
134
134
|
filePath: args.filePath,
|
|
@@ -23,7 +23,7 @@ export function getDiagnosticLogger() {
|
|
|
23
23
|
}
|
|
24
24
|
return _logger;
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
function createDiagnosticLogger() {
|
|
27
27
|
// Lazy filePath: the log file is keyed on the current date, resolved per
|
|
28
28
|
// drain so a long-lived logger rolls over at midnight. A daily rollover
|
|
29
29
|
// is NOT a size bound (#2505): one very busy day, or a long-lived
|
|
@@ -33,7 +33,3 @@ export function observeRunnerLatency(options) {
|
|
|
33
33
|
export function resetObservedRunnerLatency() {
|
|
34
34
|
slowRunners.clear();
|
|
35
35
|
}
|
|
36
|
-
/** Test-only inspection without exposing mutable state. */
|
|
37
|
-
export function observedRunnerTierForTests(projectRoot, runnerId) {
|
|
38
|
-
return classifyObservedRunner(projectRoot, runnerId);
|
|
39
|
-
}
|
|
@@ -29,7 +29,7 @@ import { isSpawnableCommand } from "../installer/index.js";
|
|
|
29
29
|
import { isAbsoluteFilePath, normalizeEphemeralMapKey, normalizeMapKey, } from "../path-utils.js";
|
|
30
30
|
import { loadPiLensProjectConfig } from "../project-lens-config.js";
|
|
31
31
|
import { RUNTIME_CONFIG, getRunnerTimeoutFloorMs } from "../runtime-config.js";
|
|
32
|
-
import {
|
|
32
|
+
import { probeToolAsync } from "../tool-probe.js";
|
|
33
33
|
import { classifyDiagnostic } from "./diagnostic-taxonomy.js";
|
|
34
34
|
import { classifyProbeFailure, logAvailabilityDecision, startHostStallSampler, transientRetryDelayMs, } from "./runners/utils/availability-policy.js";
|
|
35
35
|
import { recordAvailabilityProbeOverrun, getDispatchAvailabilityGeneration, } from "./runners/utils/runner-helpers.js";
|
|
@@ -147,7 +147,7 @@ export async function checkToolAvailability(command, facts) {
|
|
|
147
147
|
let hostStallMs;
|
|
148
148
|
let probeJoined = false;
|
|
149
149
|
try {
|
|
150
|
-
const shared = dispatcherProbeFlights.run(`dispatcher:${key}`, () =>
|
|
150
|
+
const shared = dispatcherProbeFlights.run(`dispatcher:${key}`, () => probeToolAsync(command, ["--version"], {
|
|
151
151
|
timeout: TOOL_PROBE_TIMEOUT_MS,
|
|
152
152
|
}));
|
|
153
153
|
probeJoined = shared.joined;
|
|
@@ -285,11 +285,13 @@ telemetryModel, telemetryProvider) {
|
|
|
285
285
|
async hasTool(command) {
|
|
286
286
|
return checkToolAvailability(command, facts);
|
|
287
287
|
},
|
|
288
|
-
log(message) {
|
|
288
|
+
log(message, level) {
|
|
289
289
|
// #1333: pi owns the terminal — a runner advisory must never be a raw
|
|
290
290
|
// write. Every DispatchContext.log line lands in extension.log instead.
|
|
291
291
|
logExtension({
|
|
292
292
|
subsystem: "dispatch",
|
|
293
|
+
// exactOptionalPropertyTypes: an omitted level must stay omitted.
|
|
294
|
+
...(level !== undefined && { level }),
|
|
293
295
|
message,
|
|
294
296
|
metadata: { filePath: normalizedFilePath, kind },
|
|
295
297
|
});
|
|
@@ -446,31 +448,49 @@ function buildCoverageNotice(ctx, runnerLatencies) {
|
|
|
446
448
|
...new Set(relevant.flatMap((r) => r.unconfirmedServerIds ?? [])),
|
|
447
449
|
];
|
|
448
450
|
if (unconfirmedServerIds.length > 0) {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
451
|
+
const deferredIds = new Set(relevant.flatMap((r) => r.deferredServerIds ?? []));
|
|
452
|
+
const markerFor = (ids) => {
|
|
453
|
+
const shown = ids.slice(0, 4);
|
|
454
|
+
const remainder = ids.length - shown.length;
|
|
455
|
+
return `${shown.join(", ")}${remainder > 0 ? ` +${remainder}` : ""}`;
|
|
456
|
+
};
|
|
457
|
+
const deferredServerIds = unconfirmedServerIds.filter((id) => deferredIds.has(id));
|
|
458
|
+
const silentServerIds = unconfirmedServerIds.filter((id) => !deferredIds.has(id));
|
|
459
|
+
// The marker describes this exact scanner set. A scanner can recover
|
|
460
|
+
// while another goes dark on the same file, so the set belongs in the
|
|
461
|
+
// session dedupe identity rather than only kind and path.
|
|
452
462
|
// #2016: these are SCANNER IDS, not filesystem paths. `normalizeMapKey`
|
|
453
463
|
// would realpath each one; on Windows that fails, falls through to
|
|
454
464
|
// `resolveNonExisting`, and resolves the id against the CURRENT process
|
|
455
465
|
// cwd, so the dedupe key differed by platform and by cwd (the #2219
|
|
456
466
|
// non-path-sentinel class). The cheap syntactic fold is what this
|
|
457
|
-
// session-scoped dedupe key actually needs.
|
|
458
|
-
|
|
467
|
+
// session-scoped dedupe key actually needs. Code-unit comparator: the
|
|
468
|
+
// sorted set is a KEY, so ordering must be deterministic across locales
|
|
469
|
+
// — localeCompare is not.
|
|
470
|
+
const dedupeSet = (ids) => [...new Set(ids)]
|
|
459
471
|
.map(normalizeEphemeralMapKey)
|
|
460
|
-
// Code-unit comparator: the sorted set is a dedupe KEY, so ordering
|
|
461
|
-
// must be deterministic across locales — localeCompare is not.
|
|
462
472
|
.sort((a, b) => Number(a > b) - Number(a < b))
|
|
463
473
|
.join(",");
|
|
464
|
-
|
|
474
|
+
// #2810 round 4: the PARTITION is part of the identity, not just the
|
|
475
|
+
// scanner set. The same scanner can be silent on one edit and marked for
|
|
476
|
+
// late delivery on the next; keying on the unconfirmed set alone showed
|
|
477
|
+
// the session whichever message came first and suppressed the other, so a
|
|
478
|
+
// scanner that recovered a delivery path (or lost one) kept the stale
|
|
479
|
+
// wording for the rest of the session.
|
|
480
|
+
const onceKey = `${ctx.kind}:${ctx.filePath}:${dedupeSet(silentServerIds)}|${dedupeSet(deferredServerIds)}`;
|
|
465
481
|
if (coverageNoticeSeen.has(onceKey))
|
|
466
482
|
return undefined;
|
|
467
483
|
coverageNoticeSeen.add(onceKey);
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
484
|
+
const coverageParts = [];
|
|
485
|
+
if (deferredServerIds.length > 0) {
|
|
486
|
+
coverageParts.push(`coverage: ${markerFor(deferredServerIds)} deferred — diagnostics are incomplete; findings arrive at turn end if the scan lands.`);
|
|
487
|
+
}
|
|
488
|
+
if (silentServerIds.length > 0) {
|
|
489
|
+
coverageParts.push(`coverage: ${markerFor(silentServerIds)} silent — diagnostics are incomplete (not a clean result).`);
|
|
490
|
+
}
|
|
471
491
|
return {
|
|
472
492
|
id: `coverage-partial:${ctx.kind}:${path.basename(ctx.filePath)}`,
|
|
473
|
-
message:
|
|
493
|
+
message: coverageParts.join("\n"),
|
|
474
494
|
filePath: ctx.filePath,
|
|
475
495
|
severity: "warning",
|
|
476
496
|
semantic: "warning",
|
|
@@ -837,6 +857,9 @@ async function runGroup(ctx, group, registry, onRunnerResult) {
|
|
|
837
857
|
...(result.unconfirmedServerIds !== undefined && {
|
|
838
858
|
unconfirmedServerIds: result.unconfirmedServerIds,
|
|
839
859
|
}),
|
|
860
|
+
...(result.deferredServerIds !== undefined && {
|
|
861
|
+
deferredServerIds: result.deferredServerIds,
|
|
862
|
+
}),
|
|
840
863
|
});
|
|
841
864
|
logLatency({
|
|
842
865
|
type: "runner",
|
|
@@ -1237,29 +1260,3 @@ async function runRunner(ctx, runner, defaultSemantic) {
|
|
|
1237
1260
|
}
|
|
1238
1261
|
}
|
|
1239
1262
|
// --- Simple Integration Helper ---
|
|
1240
|
-
/**
|
|
1241
|
-
* @internal
|
|
1242
|
-
* Low-level dispatch entry point. Use `dispatchLint` from `./integration.js` instead —
|
|
1243
|
-
* that version provides session-persistent baselines and FactStore.
|
|
1244
|
-
* This function creates an ephemeral FactStore per call; facts do not persist across calls.
|
|
1245
|
-
*/
|
|
1246
|
-
export async function dispatchLint(filePath, cwd, pi, facts, registry) {
|
|
1247
|
-
// By default, only run BLOCKING rules for fast feedback on file write
|
|
1248
|
-
const ctx = createDispatchContext(filePath, cwd, pi, facts, true);
|
|
1249
|
-
// Get runners for this file kind
|
|
1250
|
-
if (!ctx.kind)
|
|
1251
|
-
return "";
|
|
1252
|
-
const runners = registry.getForKind(ctx.kind, ctx.filePath);
|
|
1253
|
-
if (runners.length === 0) {
|
|
1254
|
-
return "";
|
|
1255
|
-
}
|
|
1256
|
-
// Create groups from registered runners (all in fallback mode)
|
|
1257
|
-
const groups = [
|
|
1258
|
-
{
|
|
1259
|
-
mode: "fallback",
|
|
1260
|
-
runnerIds: runners.map((r) => r.id),
|
|
1261
|
-
},
|
|
1262
|
-
];
|
|
1263
|
-
const result = await dispatchForFile(ctx, groups, registry);
|
|
1264
|
-
return result.output;
|
|
1265
|
-
}
|
|
@@ -135,7 +135,7 @@ function isCallPassThrough(stmt, paramNames) {
|
|
|
135
135
|
}
|
|
136
136
|
return { pass: true, target: (expr.children ?? [])[0]?.text };
|
|
137
137
|
}
|
|
138
|
-
function calcCyclomaticComplexity(body) {
|
|
138
|
+
export function calcCyclomaticComplexity(body) {
|
|
139
139
|
let cc = 1;
|
|
140
140
|
walk(body, (node) => {
|
|
141
141
|
if (COMPLEXITY_TYPES.has(node.type)) {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { logLatency } from "../../latency-logger.js";
|
|
2
2
|
import { isJstsFactFile } from "../../file-kinds.js";
|
|
3
3
|
import { childrenOfType, firstChildOfType, withFactTree, walk, } from "./tree-sitter-facts.js";
|
|
4
|
+
/** Whether the import-facts provider applies to a source path. */
|
|
5
|
+
export function importFactsApplyTo(filePath) {
|
|
6
|
+
return isJstsFactFile(filePath);
|
|
7
|
+
}
|
|
4
8
|
function stripQuotes(raw) {
|
|
5
9
|
return raw.replace(/^["'`]+|["'`]+$/g, "");
|
|
6
10
|
}
|
|
@@ -69,7 +73,7 @@ export const importFactProvider = {
|
|
|
69
73
|
provides: ["file.imports", "file.reexports", "file.importFactsCoverage"],
|
|
70
74
|
requires: ["file.content"],
|
|
71
75
|
appliesTo(ctx) {
|
|
72
|
-
return
|
|
76
|
+
return importFactsApplyTo(ctx.filePath);
|
|
73
77
|
},
|
|
74
78
|
async run(ctx, store) {
|
|
75
79
|
const content = store.getFileFact(ctx.filePath, "file.content");
|
|
@@ -1489,7 +1489,9 @@ export async function computeCascadeForFile(filePath, cwd, options = {}) {
|
|
|
1489
1489
|
try {
|
|
1490
1490
|
const snapshots = (await lspService.getCapabilitySnapshots?.(neighborPath)) ?? [];
|
|
1491
1491
|
const tier = classifyCascadeWaitTier(lspService, neighborPath, snapshots);
|
|
1492
|
-
if (tier === "tier3-silent" ||
|
|
1492
|
+
if (tier === "tier3-silent" ||
|
|
1493
|
+
tier === "collect-later" ||
|
|
1494
|
+
tier === "diagnostics-unsupported") {
|
|
1493
1495
|
const spawnedForTouch = await lspService.getClientForFile(neighborPath);
|
|
1494
1496
|
if (spawnedForTouch) {
|
|
1495
1497
|
// Sampled BEFORE the touchFile notify: a publish landing
|
|
@@ -1505,6 +1507,21 @@ export async function computeCascadeForFile(filePath, cwd, options = {}) {
|
|
|
1505
1507
|
source: "cascade",
|
|
1506
1508
|
clientScope: "primary",
|
|
1507
1509
|
});
|
|
1510
|
+
if (tier === "diagnostics-unsupported") {
|
|
1511
|
+
logCascade({
|
|
1512
|
+
phase: "cascade_skip",
|
|
1513
|
+
filePath,
|
|
1514
|
+
neighborFile: neighborPath,
|
|
1515
|
+
durationMs: Date.now() - neighborStart,
|
|
1516
|
+
lspServerCount: configuredServerCount,
|
|
1517
|
+
coldSnapshot: isColdSnapshot,
|
|
1518
|
+
metadata: {
|
|
1519
|
+
serverId: spawnedForTouch.client.serverId,
|
|
1520
|
+
waitTier: tier,
|
|
1521
|
+
},
|
|
1522
|
+
});
|
|
1523
|
+
return undefined;
|
|
1524
|
+
}
|
|
1508
1525
|
recordOutstandingCascadeTouch({
|
|
1509
1526
|
filePath: neighborPath,
|
|
1510
1527
|
serverId: spawnedForTouch.client.serverId,
|
|
@@ -9,9 +9,3 @@ export function warmDispatchIntegration() {
|
|
|
9
9
|
export function loadDispatchIntegration() {
|
|
10
10
|
return warmDispatchIntegration();
|
|
11
11
|
}
|
|
12
|
-
/** Test-only reset; production sessions intentionally retain the promise
|
|
13
|
-
* across successful loads (a rejection already evicts itself — see
|
|
14
|
-
* `createLazyImport`). */
|
|
15
|
-
export function resetDispatchIntegrationForTests() {
|
|
16
|
-
lazyIntegration.resetForTests();
|
|
17
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Turn-end handoff for runners moved off the post-write critical path. */
|
|
2
2
|
import { incrementDegradationCount } from "../degradation-ledger.js";
|
|
3
3
|
const pending = [];
|
|
4
|
-
|
|
4
|
+
const MAX_PENDING_RUNNER_FINDINGS = 50;
|
|
5
5
|
export function deferRunnerFindings(entry) {
|
|
6
6
|
const tracked = { ...entry, settled: false };
|
|
7
7
|
// Attach exactly once at ownership time. Re-attaching at every turn end
|
|
@@ -3,8 +3,8 @@ import { isTestSuiteOrganizer } from "./framework-call-noise.js";
|
|
|
3
3
|
// projects without a config. Project-specific overrides are read from the
|
|
4
4
|
// per-dispatch context; these mutable fallbacks exist for tests/legacy direct
|
|
5
5
|
// rule evaluation only.
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
const DEFAULT_HIGH_COMPLEXITY_THRESHOLD = 15;
|
|
7
|
+
const DEFAULT_HIGH_COMPLEXITY_DEPTH_THRESHOLD = 6;
|
|
8
8
|
let ccThreshold = DEFAULT_HIGH_COMPLEXITY_THRESHOLD;
|
|
9
9
|
let depthThreshold = DEFAULT_HIGH_COMPLEXITY_DEPTH_THRESHOLD;
|
|
10
10
|
function isPositiveFiniteThreshold(value) {
|
|
@@ -3,7 +3,7 @@ import { isTestFrameworkNoiseCall, isTestSuiteOrganizer, } from "./framework-cal
|
|
|
3
3
|
// projects without a config. Project-specific overrides are read from the
|
|
4
4
|
// per-dispatch context; this mutable fallback exists for tests/legacy direct
|
|
5
5
|
// rule evaluation only.
|
|
6
|
-
|
|
6
|
+
const DEFAULT_HIGH_FAN_OUT_THRESHOLD = 20;
|
|
7
7
|
let fanOutThreshold = DEFAULT_HIGH_FAN_OUT_THRESHOLD;
|
|
8
8
|
/** Override fallback threshold for tests/legacy direct rule evaluation. */
|
|
9
9
|
export function setHighFanOutThreshold(n) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
3
4
|
import { PRIORITY } from "../priorities.js";
|
|
4
5
|
import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
5
6
|
const actionlint = createAvailabilityChecker("actionlint", ".exe");
|
|
@@ -66,7 +67,7 @@ const actionlintRunner = {
|
|
|
66
67
|
return isGitHubWorkflowFile(ctx.filePath);
|
|
67
68
|
},
|
|
68
69
|
async run(ctx) {
|
|
69
|
-
const cwd = ctx
|
|
70
|
+
const cwd = resolveRunnerCwd(ctx, "actionlint");
|
|
70
71
|
let cmd = null;
|
|
71
72
|
if (await actionlint.isAvailableAsync(cwd)) {
|
|
72
73
|
cmd = actionlint.getCommand(cwd);
|
|
@@ -184,7 +184,9 @@ export async function loadSg() {
|
|
|
184
184
|
}
|
|
185
185
|
})();
|
|
186
186
|
sgLoadPromise = task;
|
|
187
|
-
task
|
|
187
|
+
// `task` never rejects (the IIFE catches), so the derived promise is inert;
|
|
188
|
+
// `void` records that no consumer awaits it (oxlint no-floating-promises).
|
|
189
|
+
void task.finally(() => {
|
|
188
190
|
if (sgLoadPromise === task)
|
|
189
191
|
sgLoadPromise = undefined;
|
|
190
192
|
});
|
|
@@ -5,13 +5,12 @@
|
|
|
5
5
|
* Autofix is handled earlier by the post-write pipeline to avoid
|
|
6
6
|
* mutating files mid-dispatch after LSP sync has already happened.
|
|
7
7
|
*/
|
|
8
|
-
import * as path from "node:path";
|
|
9
8
|
import { incrementDegradationCount } from "../../degradation-ledger.js";
|
|
10
9
|
import { mapWithConcurrency } from "../../dependency-checker.js";
|
|
11
10
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
12
11
|
import { biomeConfigArgs, getAutofixCapability, getJstsLintPolicyForCwd, } from "../../tool-policy.js";
|
|
13
12
|
import { PRIORITY } from "../priorities.js";
|
|
14
|
-
import { resolveToolCommandWithInstallFallback } from "./utils/runner-helpers.js";
|
|
13
|
+
import { resolveRunnerCwd, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
15
14
|
import { finishParsedRun } from "./utils/tool-failure.js";
|
|
16
15
|
/**
|
|
17
16
|
* Map biome's own severity vocabulary onto the four-tier `Diagnostic.severity`
|
|
@@ -198,7 +197,7 @@ const biomeCheckJsonRunner = {
|
|
|
198
197
|
appliesTo: ["jsts"],
|
|
199
198
|
priority: PRIORITY.FORMAT_AND_LINT_PRIMARY,
|
|
200
199
|
async run(ctx) {
|
|
201
|
-
const cwd = ctx
|
|
200
|
+
const cwd = resolveRunnerCwd(ctx, "biome");
|
|
202
201
|
const policy = getJstsLintPolicyForCwd(cwd);
|
|
203
202
|
// Defer to ESLint/oxlint if the project has explicitly configured one —
|
|
204
203
|
// biome runs as the default linter only when no alternative is present.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
4
|
+
import { probeToolAsync } from "../../tool-probe.js";
|
|
5
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
4
6
|
import { PRIORITY } from "../priorities.js";
|
|
5
7
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
6
8
|
// Per-compiler availability checkers — each one caches per-cwd and
|
|
@@ -97,7 +99,10 @@ async function resolveCompiler(absPath, cwd) {
|
|
|
97
99
|
flavor: "msvc",
|
|
98
100
|
};
|
|
99
101
|
}
|
|
100
|
-
|
|
102
|
+
// Mirrors the deliberate global-PATH probes in utils/runner-helpers.ts:
|
|
103
|
+
// this never resolves a config file or a target path, so there is no cwd
|
|
104
|
+
// for it to get wrong.
|
|
105
|
+
const clProbe = await probeToolAsync("cl", [], { timeout: 5000 });
|
|
101
106
|
if (!clProbe.error && clProbe.status !== null) {
|
|
102
107
|
return {
|
|
103
108
|
command: "cl",
|
|
@@ -177,7 +182,7 @@ const cppCheckRunner = {
|
|
|
177
182
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
178
183
|
skipTestFiles: false,
|
|
179
184
|
async run(ctx) {
|
|
180
|
-
const cwd = ctx
|
|
185
|
+
const cwd = resolveRunnerCwd(ctx, "cpp-check");
|
|
181
186
|
const absPath = path.resolve(cwd, ctx.filePath);
|
|
182
187
|
const compiler = await resolveCompiler(absPath, cwd);
|
|
183
188
|
if (!compiler) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
4
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
4
5
|
import { PRIORITY } from "../priorities.js";
|
|
5
6
|
import { createCwdCachedProbe } from "./utils/runner-helpers.js";
|
|
6
7
|
const CREDO_PROBE_BUDGET_MS = 10_000;
|
|
@@ -50,7 +51,7 @@ const credoRunner = {
|
|
|
50
51
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
51
52
|
skipTestFiles: false,
|
|
52
53
|
async run(ctx) {
|
|
53
|
-
const cwd = ctx
|
|
54
|
+
const cwd = resolveRunnerCwd(ctx, "credo");
|
|
54
55
|
if (!hasMixExs(cwd)) {
|
|
55
56
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
56
57
|
}
|
|
@@ -104,6 +104,7 @@
|
|
|
104
104
|
import * as fs from "node:fs";
|
|
105
105
|
import * as path from "node:path";
|
|
106
106
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
107
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
107
108
|
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
108
109
|
import { spawnFailedWithNoOutput } from "./utils/spawn-outcome.js";
|
|
109
110
|
import { PRIORITY } from "../priorities.js";
|
|
@@ -281,7 +282,7 @@ const cueVetRunner = {
|
|
|
281
282
|
skipTestFiles: false,
|
|
282
283
|
timeoutMs: 30_000,
|
|
283
284
|
async run(ctx) {
|
|
284
|
-
const cwd = ctx
|
|
285
|
+
const cwd = resolveRunnerCwd(ctx, "cue-vet");
|
|
285
286
|
let cmd = null;
|
|
286
287
|
if (await cue.isAvailableAsync(cwd)) {
|
|
287
288
|
cmd = cue.getCommand(cwd);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
3
4
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
4
5
|
import { PRIORITY } from "../priorities.js";
|
|
5
6
|
const dart = createAvailabilityChecker("dart", ".exe");
|
|
@@ -147,7 +148,7 @@ const dartAnalyzeRunner = {
|
|
|
147
148
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
148
149
|
skipTestFiles: false,
|
|
149
150
|
async run(ctx) {
|
|
150
|
-
const cwd = ctx
|
|
151
|
+
const cwd = resolveRunnerCwd(ctx, "dart-analyze");
|
|
151
152
|
const absPath = path.resolve(cwd, ctx.filePath);
|
|
152
153
|
const dartAvailable = await dart.isAvailableAsync(cwd);
|
|
153
154
|
const flutterAvailable = !dartAvailable && (await flutter.isAvailableAsync(cwd));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
4
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
4
5
|
import { getLinterPolicyForCwd } from "../../tool-policy.js";
|
|
5
6
|
import { PRIORITY } from "../priorities.js";
|
|
6
7
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
@@ -129,7 +130,7 @@ const detektRunner = {
|
|
|
129
130
|
timeoutMs: 90_000,
|
|
130
131
|
skipTestFiles: false,
|
|
131
132
|
async run(ctx) {
|
|
132
|
-
const cwd = ctx
|
|
133
|
+
const cwd = resolveRunnerCwd(ctx, "detekt");
|
|
133
134
|
const policy = getLinterPolicyForCwd(ctx.filePath, cwd);
|
|
134
135
|
if (policy && !policy.preferredRunners.includes("detekt")) {
|
|
135
136
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
4
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
4
5
|
import { PRIORITY } from "../priorities.js";
|
|
5
6
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
6
7
|
const dotnet = createAvailabilityChecker("dotnet", ".exe");
|
|
@@ -118,7 +119,7 @@ const dotnetBuildRunner = {
|
|
|
118
119
|
timeoutMs: 90_000,
|
|
119
120
|
skipTestFiles: false,
|
|
120
121
|
async run(ctx) {
|
|
121
|
-
const cwd = ctx
|
|
122
|
+
const cwd = resolveRunnerCwd(ctx, "dotnet-build");
|
|
122
123
|
if (!(await dotnet.isAvailableAsync(cwd))) {
|
|
123
124
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
124
125
|
}
|
|
@@ -2,6 +2,7 @@ import * as fs from "node:fs";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { getProjectDataDir } from "../../file-utils.js";
|
|
4
4
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
5
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
5
6
|
import { PRIORITY } from "../priorities.js";
|
|
6
7
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
7
8
|
// Per-cwd cached `--version` probes (#120). Before this, each dispatch
|
|
@@ -141,7 +142,7 @@ const elixirCheckRunner = {
|
|
|
141
142
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
142
143
|
skipTestFiles: false,
|
|
143
144
|
async run(ctx) {
|
|
144
|
-
const cwd = ctx
|
|
145
|
+
const cwd = resolveRunnerCwd(ctx, "elixir-check");
|
|
145
146
|
const absPath = path.resolve(cwd, ctx.filePath);
|
|
146
147
|
let command;
|
|
147
148
|
let args = [];
|