@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
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import * as os from "node:os";
|
|
2
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { logExtension } from "./extension-log.js";
|
|
5
|
+
import { isRealGitMarker, isAtOrAboveHomeDir, isUnderDir, isWindowsPath, nameMatchesMarkerGlob, normalizeEphemeralMapKey, } from "./path-utils.js";
|
|
6
|
+
import { getDegradationLedgerGeneration, recordDegradationOnce, } from "./degradation-ledger.js";
|
|
7
|
+
import { createGenerationMap, createGenerationSource, } from "./generation-guard.js";
|
|
8
|
+
export const FORMATTER_MARKERS = {
|
|
9
|
+
biome: ["biome.json", "biome.jsonc", "package.json", ".gitignore"],
|
|
10
|
+
prettier: [
|
|
11
|
+
".prettierrc",
|
|
12
|
+
".prettierrc.json",
|
|
13
|
+
".prettierrc.yaml",
|
|
14
|
+
".prettierrc.yml",
|
|
15
|
+
".prettierrc.js",
|
|
16
|
+
".prettierrc.cjs",
|
|
17
|
+
".prettierrc.mjs",
|
|
18
|
+
"prettier.config.js",
|
|
19
|
+
"prettier.config.cjs",
|
|
20
|
+
"prettier.config.mjs",
|
|
21
|
+
".prettierignore",
|
|
22
|
+
"package.json",
|
|
23
|
+
".gitignore",
|
|
24
|
+
],
|
|
25
|
+
ruff: ["pyproject.toml", "ruff.toml", ".ruff.toml", ".gitignore"],
|
|
26
|
+
black: ["pyproject.toml", "black.toml", ".black", ".gitignore"],
|
|
27
|
+
"php-cs-fixer": [".php-cs-fixer.php", ".php-cs-fixer.dist.php", ".gitignore"],
|
|
28
|
+
sqlfluff: [".sqlfluff", "pyproject.toml", "setup.cfg", ".gitignore"],
|
|
29
|
+
oxfmt: [
|
|
30
|
+
"oxfmt.toml",
|
|
31
|
+
".oxfmtrc.json",
|
|
32
|
+
"vite-plus.json",
|
|
33
|
+
"package.json",
|
|
34
|
+
".gitignore",
|
|
35
|
+
],
|
|
36
|
+
rustfmt: ["rustfmt.toml", ".rustfmt.toml", "Cargo.toml", ".gitignore"],
|
|
37
|
+
rubocop: [".rubocop.yml", ".rubocop.yaml", ".gitignore"],
|
|
38
|
+
standardrb: [".standard.yml", ".standard.yaml", ".gitignore"],
|
|
39
|
+
"clang-format": [".clang-format", "_clang-format", ".gitignore"],
|
|
40
|
+
stylua: ["stylua.toml", ".stylua.toml", ".gitignore"],
|
|
41
|
+
ocamlformat: [".ocamlformat", ".gitignore"],
|
|
42
|
+
"google-java-format": [".google-java-format", ".editorconfig", ".gitignore"],
|
|
43
|
+
cljfmt: [".cljfmt.edn", "cljfmt.edn", ".cljfmt", ".gitignore"],
|
|
44
|
+
"cmake-format": [
|
|
45
|
+
".cmake-format",
|
|
46
|
+
".cmake-format.yaml",
|
|
47
|
+
".cmake-format.yml",
|
|
48
|
+
".cmake-format.json",
|
|
49
|
+
".cmake-format.py",
|
|
50
|
+
"cmake-format.yaml",
|
|
51
|
+
"cmake-format.yml",
|
|
52
|
+
".editorconfig",
|
|
53
|
+
".gitignore",
|
|
54
|
+
],
|
|
55
|
+
"psscriptanalyzer-format": [
|
|
56
|
+
"PSScriptAnalyzerSettings.psd1",
|
|
57
|
+
"ScriptAnalyzerSettings.psd1",
|
|
58
|
+
".gitignore",
|
|
59
|
+
],
|
|
60
|
+
csharpier: [
|
|
61
|
+
".csharpierrc",
|
|
62
|
+
".csharpierrc.json",
|
|
63
|
+
".csharpierrc.yaml",
|
|
64
|
+
".csharpierrc.yml",
|
|
65
|
+
".gitignore",
|
|
66
|
+
],
|
|
67
|
+
ormolu: [".ormolu", ".gitignore"],
|
|
68
|
+
taplo: ["taplo.toml", ".taplo.toml", ".gitignore"],
|
|
69
|
+
terraform: [".terraform.lock.hcl", ".gitignore"],
|
|
70
|
+
swiftformat: [".swiftformat", ".gitignore"],
|
|
71
|
+
fantomas: [".fantomasignore", ".editorconfig", ".gitignore"],
|
|
72
|
+
mix: [".formatter.exs", ".gitignore"],
|
|
73
|
+
shfmt: [".editorconfig", ".gitignore"],
|
|
74
|
+
ktlint: [".editorconfig", ".gitignore"],
|
|
75
|
+
ktfmt: [
|
|
76
|
+
".editorconfig",
|
|
77
|
+
".ktfmt",
|
|
78
|
+
".ktfmt.kts",
|
|
79
|
+
"build.gradle",
|
|
80
|
+
"build.gradle.kts",
|
|
81
|
+
"settings.gradle",
|
|
82
|
+
"settings.gradle.kts",
|
|
83
|
+
".gitignore",
|
|
84
|
+
],
|
|
85
|
+
};
|
|
86
|
+
const RUNNER_MARKERS = {
|
|
87
|
+
yamllint: [".yamllint", "yamllint.yaml", "yamllint.yml", "pyproject.toml"],
|
|
88
|
+
ruff: ["pyproject.toml", "ruff.toml", ".ruff.toml"],
|
|
89
|
+
"spellcheck/typos": ["_typos.toml", "typos.toml"],
|
|
90
|
+
biome: ["biome.json", "biome.jsonc", "package.json"],
|
|
91
|
+
oxlint: [".oxlintrc.json", "oxlint.config.js", "package.json"],
|
|
92
|
+
sqlfluff: [".sqlfluff", "pyproject.toml", "setup.cfg"],
|
|
93
|
+
prettier: [".prettierignore", "package.json"],
|
|
94
|
+
// #2894: cargo must run at the package root. This is the marker walk
|
|
95
|
+
// `rust-clippy.ts` used to do for itself with `findNearestContaining`.
|
|
96
|
+
"rust-clippy": ["Cargo.toml"],
|
|
97
|
+
};
|
|
98
|
+
const toolCwdGeneration = createGenerationSource("tool-cwd");
|
|
99
|
+
const logged = createGenerationMap("tool-cwd-resolution-log");
|
|
100
|
+
const markerWalks = new Map();
|
|
101
|
+
const markerWalkGenerations = createGenerationMap("tool-cwd-marker-walks");
|
|
102
|
+
let markerWalkCount = 0;
|
|
103
|
+
/** Pure key seam for ephemeral tool-cwd memo and log identity. */
|
|
104
|
+
export function _toolCwdEphemeralKey(parts) {
|
|
105
|
+
return parts.map(normalizeEphemeralMapKey).join("\0");
|
|
106
|
+
}
|
|
107
|
+
/** Test probe for the per-generation walk memo; not part of runtime behavior. */
|
|
108
|
+
export function _getToolCwdMarkerWalkCount() {
|
|
109
|
+
return markerWalkCount;
|
|
110
|
+
}
|
|
111
|
+
function syncGeneration() {
|
|
112
|
+
if (toolCwdGeneration.current() === getDegradationLedgerGeneration())
|
|
113
|
+
return;
|
|
114
|
+
markerWalks.clear();
|
|
115
|
+
markerWalkGenerations.clear();
|
|
116
|
+
logged.clear();
|
|
117
|
+
while (toolCwdGeneration.current() < getDegradationLedgerGeneration()) {
|
|
118
|
+
toolCwdGeneration.bump();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function findMarkerRoot(startDir, markers, homeDir) {
|
|
122
|
+
syncGeneration();
|
|
123
|
+
const key = _toolCwdEphemeralKey([
|
|
124
|
+
path.resolve(startDir),
|
|
125
|
+
...markers,
|
|
126
|
+
path.resolve(homeDir),
|
|
127
|
+
]);
|
|
128
|
+
const cached = markerWalks.get(key);
|
|
129
|
+
if (cached && markerWalkGenerations.current(key) !== 0) {
|
|
130
|
+
// A negative walk is not stable: a project marker can be created after
|
|
131
|
+
// the first resolution, so do not cache absence across calls. Positive
|
|
132
|
+
// results remain memoized and are still revalidated when their marker is
|
|
133
|
+
// deleted (#2894).
|
|
134
|
+
if (!cached.marker || !cached.root) {
|
|
135
|
+
markerWalks.delete(key);
|
|
136
|
+
markerWalkGenerations.forget(key);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
// #2777: a marker can disappear during a session; do not reuse a stale root.
|
|
140
|
+
if (existsSync(path.join(cached.root, cached.marker)))
|
|
141
|
+
return cached;
|
|
142
|
+
markerWalks.delete(key);
|
|
143
|
+
markerWalkGenerations.forget(key);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
markerWalkCount++;
|
|
147
|
+
let current = path.resolve(startDir);
|
|
148
|
+
let result = { root: null };
|
|
149
|
+
for (let depth = 0; depth < 64; depth++) {
|
|
150
|
+
if (isAtOrAboveHomeDir(current, homeDir))
|
|
151
|
+
break;
|
|
152
|
+
for (const marker of markers) {
|
|
153
|
+
const slash = marker.replace(/\\/g, "/").lastIndexOf("/");
|
|
154
|
+
const parent = slash >= 0 ? marker.slice(0, slash) : "";
|
|
155
|
+
const basename = slash >= 0 ? marker.slice(slash + 1) : marker;
|
|
156
|
+
const target = parent
|
|
157
|
+
? path.join(current, ...parent.split("/").filter(Boolean))
|
|
158
|
+
: current;
|
|
159
|
+
let found = false;
|
|
160
|
+
if (basename.includes("*")) {
|
|
161
|
+
try {
|
|
162
|
+
found = readdirSync(target, { withFileTypes: true }).some((entry) => (entry.isFile() || entry.isSymbolicLink()) &&
|
|
163
|
+
nameMatchesMarkerGlob(entry.name, basename));
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
found = false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
found = existsSync(path.join(target, basename));
|
|
171
|
+
}
|
|
172
|
+
if (found) {
|
|
173
|
+
result = { root: current, marker };
|
|
174
|
+
markerWalks.set(key, result);
|
|
175
|
+
markerWalkGenerations.bump(key);
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const parentDir = path.dirname(current);
|
|
180
|
+
if (parentDir === current)
|
|
181
|
+
break;
|
|
182
|
+
current = parentDir;
|
|
183
|
+
}
|
|
184
|
+
markerWalks.set(key, result);
|
|
185
|
+
markerWalkGenerations.bump(key);
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
function markersFor(kind, tool, ctx) {
|
|
189
|
+
if (kind === "lsp")
|
|
190
|
+
return ctx.rootMarkers ?? [];
|
|
191
|
+
// #2871: caller-supplied markers count for runners too. `RUNNER_MARKERS`
|
|
192
|
+
// covers the linter/formatter-shaped runners this module has always known;
|
|
193
|
+
// a caller that owns its own marker table — the test runner, whose
|
|
194
|
+
// `RUNNERS[x].configFiles` IS that table — passes it here rather than
|
|
195
|
+
// registering a second copy of the same data in this file.
|
|
196
|
+
if (kind === "runner")
|
|
197
|
+
return ctx.rootMarkers ?? RUNNER_MARKERS[tool] ?? [];
|
|
198
|
+
return FORMATTER_MARKERS[tool] ?? [".gitignore"];
|
|
199
|
+
}
|
|
200
|
+
function emitResolution(kind, tool, cwd, reason) {
|
|
201
|
+
syncGeneration();
|
|
202
|
+
const key = _toolCwdEphemeralKey([kind, tool, cwd, reason]);
|
|
203
|
+
if (logged.current(key) !== 0)
|
|
204
|
+
return;
|
|
205
|
+
logged.bump(key);
|
|
206
|
+
logExtension({
|
|
207
|
+
subsystem: "tool-cwd",
|
|
208
|
+
level: "debug",
|
|
209
|
+
message: `cwd ${kind} ${tool} cwd=${cwd} reason=${reason}`,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Emit a constant runner advisory once per (tool, resolved root) per session
|
|
214
|
+
* (#2811): the yamllint/stylelint/sqlfluff "no config detected" lines and
|
|
215
|
+
* markdownlint's spawn-timeout cooldown notice logged once PER FILE at error
|
|
216
|
+
* level — 17 lines in one session for one tool. The throttle shares the
|
|
217
|
+
* resolution-log map and its ledger-generation reset, so `session_start`
|
|
218
|
+
* re-arms it like every once-latch in this module. The message rides
|
|
219
|
+
* `ctx.log` at debug level so the dispatch seam stays the one sink for
|
|
220
|
+
* runner lines, with its own filePath/kind metadata.
|
|
221
|
+
*/
|
|
222
|
+
export function logRunnerAdvisoryOnce(ctx, tool, root, message) {
|
|
223
|
+
syncGeneration();
|
|
224
|
+
const key = _toolCwdEphemeralKey(["runner-advisory", tool, root]);
|
|
225
|
+
if (logged.current(key) !== 0)
|
|
226
|
+
return;
|
|
227
|
+
logged.bump(key);
|
|
228
|
+
ctx.log(message, "debug");
|
|
229
|
+
}
|
|
230
|
+
/** Resolve every child process cwd/root through one bounded, synchronous seam. */
|
|
231
|
+
export function resolveToolCwd(kind, tool, file, ctx) {
|
|
232
|
+
const dispatchRoot = path.resolve(ctx.cwd ?? process.cwd());
|
|
233
|
+
const absoluteFile = path.resolve(file);
|
|
234
|
+
const fileDir = path.dirname(absoluteFile);
|
|
235
|
+
const homeDir = ctx.homeDir ?? os.homedir();
|
|
236
|
+
const insideDispatch = isUnderDir(absoluteFile, dispatchRoot);
|
|
237
|
+
if (ctx.serverRoot) {
|
|
238
|
+
const rootPath = isWindowsPath(ctx.serverRoot) ? path.win32 : path;
|
|
239
|
+
const serverRoot = rootPath.resolve(ctx.serverRoot);
|
|
240
|
+
if (!ctx.suppressTelemetry)
|
|
241
|
+
emitResolution(kind, tool, serverRoot, "server-root");
|
|
242
|
+
return serverRoot;
|
|
243
|
+
}
|
|
244
|
+
const markers = markersFor(kind, tool, ctx);
|
|
245
|
+
const markerResult = markers.length
|
|
246
|
+
? findMarkerRoot(fileDir, markers, ctx.allowHomeMarker ? path.parse(homeDir).root : homeDir)
|
|
247
|
+
: { root: null };
|
|
248
|
+
const markerRoot = markerResult.root;
|
|
249
|
+
if (markerRoot &&
|
|
250
|
+
(insideDispatch ? isUnderDir(markerRoot, dispatchRoot) : true)) {
|
|
251
|
+
const finalReason = `marker:${markerResult.marker ?? markers[0]}`;
|
|
252
|
+
if (!ctx.suppressTelemetry)
|
|
253
|
+
emitResolution(kind, tool, markerRoot, finalReason);
|
|
254
|
+
return markerRoot;
|
|
255
|
+
}
|
|
256
|
+
const gitResult = findMarkerRoot(fileDir, [".git"], homeDir);
|
|
257
|
+
const gitRoot = gitResult.root && isRealGitMarker(path.join(gitResult.root, ".git"))
|
|
258
|
+
? gitResult.root
|
|
259
|
+
: null;
|
|
260
|
+
if (gitRoot && (insideDispatch ? isUnderDir(gitRoot, dispatchRoot) : true)) {
|
|
261
|
+
if (!ctx.suppressTelemetry)
|
|
262
|
+
emitResolution(kind, tool, gitRoot, "git-root");
|
|
263
|
+
return gitRoot;
|
|
264
|
+
}
|
|
265
|
+
if (insideDispatch) {
|
|
266
|
+
if (kind === "formatter") {
|
|
267
|
+
if (!ctx.suppressTelemetry)
|
|
268
|
+
emitResolution(kind, tool, fileDir, "file-dir-fallback");
|
|
269
|
+
if (!ctx.suppressTelemetry && !isUnderDir(fileDir, homeDir)) {
|
|
270
|
+
recordDegradationOnce({
|
|
271
|
+
kind: "tool-cwd-resolution",
|
|
272
|
+
subject: tool,
|
|
273
|
+
reason: `${kind}:home-cap:${absoluteFile}`,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
return fileDir;
|
|
277
|
+
}
|
|
278
|
+
if (!ctx.suppressTelemetry)
|
|
279
|
+
emitResolution(kind, tool, dispatchRoot, "dispatch-root");
|
|
280
|
+
return dispatchRoot;
|
|
281
|
+
}
|
|
282
|
+
const reason = isUnderDir(fileDir, homeDir)
|
|
283
|
+
? "file-dir-fallback"
|
|
284
|
+
: "home-cap";
|
|
285
|
+
const fallback = isUnderDir(fileDir, homeDir) ? fileDir : homeDir;
|
|
286
|
+
if (!ctx.suppressTelemetry)
|
|
287
|
+
recordDegradationOnce({
|
|
288
|
+
kind: "tool-cwd-resolution",
|
|
289
|
+
subject: tool,
|
|
290
|
+
reason: `${kind}:${reason}:${absoluteFile}`,
|
|
291
|
+
});
|
|
292
|
+
if (!ctx.suppressTelemetry)
|
|
293
|
+
emitResolution(kind, tool, fallback, reason);
|
|
294
|
+
return fallback;
|
|
295
|
+
}
|
|
296
|
+
/** Runner-shaped adapter kept at the same seam for every runner consumer. */
|
|
297
|
+
export function resolveRunnerCwd(ctx, tool) {
|
|
298
|
+
return resolveToolCwd("runner", tool, ctx.filePath, ctx);
|
|
299
|
+
}
|
|
@@ -756,7 +756,7 @@ const FORMATTER_POLICY_BY_FILENAME = new Map(TERRAGRUNT_FILENAMES.map((name) =>
|
|
|
756
756
|
// lines don't fall at the head of the pre-existing lookup-table duplication and
|
|
757
757
|
// get counted as new duplicated code. Bindings are live, so position is safe.
|
|
758
758
|
export { AUTO_INSTALLABLE_DEFAULT_FORMATTERS, FORMATTER_POLICY_BY_EXTENSION, FORMATTER_POLICY_BY_FILENAME, };
|
|
759
|
-
|
|
759
|
+
function getFormatterPolicyForExtension(ext) {
|
|
760
760
|
return FORMATTER_POLICY_BY_EXTENSION.get(ext.toLowerCase());
|
|
761
761
|
}
|
|
762
762
|
export function getFormatterPolicyForFile(filePath) {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tool-probe spawn seam (#2894).
|
|
3
|
+
*
|
|
4
|
+
* A sibling of `tool-cwd.ts`: that module owns where a child that READS A
|
|
5
|
+
* PROJECT starts, this one owns the fact that a child which reads no project
|
|
6
|
+
* starts nowhere in particular.
|
|
7
|
+
*
|
|
8
|
+
* It is a module of its own rather than another export on `safe-spawn.ts`
|
|
9
|
+
* deliberately. Every availability test in this repo fakes the process
|
|
10
|
+
* boundary with `vi.mock("clients/safe-spawn.js", … { safeSpawnAsync })`, and
|
|
11
|
+
* a same-module helper would call the module's own unmocked binding — the
|
|
12
|
+
* probe would spawn for real while the test believed it had the boundary. One
|
|
13
|
+
* module hop keeps every existing double production-faithful.
|
|
14
|
+
*/
|
|
15
|
+
import { safeSpawnAsync } from "./safe-spawn.js";
|
|
16
|
+
/**
|
|
17
|
+
* Run a tool's own presence/version invocation — `<tool> --version`, `cl`,
|
|
18
|
+
* `go version`, `which <pm>`, `Get-Module -ListAvailable …` — and hand back
|
|
19
|
+
* the raw spawn result for the caller's availability policy to classify.
|
|
20
|
+
*
|
|
21
|
+
* ## The contract: a probe never gets a `cwd`
|
|
22
|
+
*
|
|
23
|
+
* A probe asks whether a binary exists and what it calls itself. The answer
|
|
24
|
+
* does not depend on the directory the child starts in, so this seam passes
|
|
25
|
+
* NONE — the child inherits the host's directory and nothing it reports is
|
|
26
|
+
* read out of a project. That is why the sweep in
|
|
27
|
+
* `tests/clients/dispatch/runners/runner-spawn-cwd-sweep.test.ts` admits ONE
|
|
28
|
+
* cwd-less spawn here instead of the 23 it admitted before: every one of those
|
|
29
|
+
* sites re-decided the same thing in its own words, and 23 sentences a
|
|
30
|
+
* reviewer has to re-read one at a time is how an admission table stops being
|
|
31
|
+
* auditable (#2872 round 3 shipped 127 rows carrying two canned sentences,
|
|
32
|
+
* four of them false where they were read).
|
|
33
|
+
*
|
|
34
|
+
* `cwd` is STRIPPED rather than merely left out of {@link ProbeSpawnOptions}:
|
|
35
|
+
* the type stops an object literal from carrying one, and the destructure
|
|
36
|
+
* below removes one that arrived inside an already-typed options object a
|
|
37
|
+
* caller widened or spread. Both halves are guarded — deleting the
|
|
38
|
+
* destructure changes this call's text, which retires the sweep's admission
|
|
39
|
+
* row, and `tests/clients/probe-and-root-spawn-cwd.test.ts` reds on the
|
|
40
|
+
* smuggled cwd reaching the child. A probe that genuinely needs to
|
|
41
|
+
* run somewhere — `mix credo --version` needs a mix project, `cargo clippy
|
|
42
|
+
* --version` needs a package, `eslint --version` resolves a project-local
|
|
43
|
+
* binary — must call `safeSpawnAsync` directly and be admitted by that sweep
|
|
44
|
+
* on its own reason.
|
|
45
|
+
*/
|
|
46
|
+
export async function probeToolAsync(command, args, options) {
|
|
47
|
+
// Destructured away rather than overwritten with `undefined`: the key is
|
|
48
|
+
// then genuinely ABSENT from what reaches the spawn, which is both what the
|
|
49
|
+
// contract says and what `exactOptionalPropertyTypes` wants (a present
|
|
50
|
+
// `cwd: undefined` is a strictness spike the `tests/config` ratchet counts).
|
|
51
|
+
const { cwd: _strippedCwd, ...rest } = (options ?? {});
|
|
52
|
+
return safeSpawnAsync(command, [...args], { ...rest });
|
|
53
|
+
}
|
|
@@ -1,4 +1,46 @@
|
|
|
1
1
|
import { logLatency } from "./latency-logger.js";
|
|
2
|
+
import { BoundedFifoMap } from "./bounded-cache.js";
|
|
3
|
+
import { recordDegradationOnce } from "./degradation-ledger.js";
|
|
4
|
+
// pi re-runs the extension factory for session rebuilds, but imports this
|
|
5
|
+
// module once per process. Keep conversation activation memory here, keyed by
|
|
6
|
+
// pi's session file rather than by a factory closure or process-wide session.
|
|
7
|
+
export const REMEMBERED_LAZY_TOOLS_MAX_SESSIONS = 128;
|
|
8
|
+
const rememberedLazyToolsBySessionFile = new BoundedFifoMap(REMEMBERED_LAZY_TOOLS_MAX_SESSIONS);
|
|
9
|
+
export function rememberLazyTools(sessionFile, names) {
|
|
10
|
+
if (!sessionFile) {
|
|
11
|
+
recordDegradationOnce({
|
|
12
|
+
kind: "tool-set-session-file-unavailable",
|
|
13
|
+
subject: "activation",
|
|
14
|
+
reason: "session-file identity unavailable; activation memory is inert",
|
|
15
|
+
});
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const remembered = rememberedLazyToolsBySessionFile.get(sessionFile) ?? new Set();
|
|
19
|
+
for (const name of names)
|
|
20
|
+
remembered.add(name);
|
|
21
|
+
rememberedLazyToolsBySessionFile.set(sessionFile, remembered);
|
|
22
|
+
}
|
|
23
|
+
export function getRememberedLazyTools(sessionFile) {
|
|
24
|
+
return sessionFile
|
|
25
|
+
? (rememberedLazyToolsBySessionFile.get(sessionFile) ?? new Set())
|
|
26
|
+
: new Set();
|
|
27
|
+
}
|
|
28
|
+
export function clearRememberedLazyTools(sessionFile) {
|
|
29
|
+
if (sessionFile)
|
|
30
|
+
rememberedLazyToolsBySessionFile.delete(sessionFile);
|
|
31
|
+
}
|
|
32
|
+
export function inheritRememberedLazyTools(parentSessionFile, childSessionFile) {
|
|
33
|
+
if (!parentSessionFile ||
|
|
34
|
+
!childSessionFile ||
|
|
35
|
+
parentSessionFile === childSessionFile)
|
|
36
|
+
return;
|
|
37
|
+
const remembered = rememberedLazyToolsBySessionFile.get(parentSessionFile);
|
|
38
|
+
if (remembered)
|
|
39
|
+
rememberedLazyToolsBySessionFile.set(childSessionFile, new Set(remembered));
|
|
40
|
+
}
|
|
41
|
+
export function resetRememberedLazyToolsForTests() {
|
|
42
|
+
rememberedLazyToolsBySessionFile.clear();
|
|
43
|
+
}
|
|
2
44
|
/**
|
|
3
45
|
* Whether the host will send this model deferred (searchable) tool
|
|
4
46
|
* definitions rather than the full inline list.
|
|
@@ -80,7 +80,7 @@ function grammarFileStamp(filePath) {
|
|
|
80
80
|
return undefined;
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
function isTreeSitterWasmAbortError(error) {
|
|
84
84
|
const message = error instanceof Error ? error.message : String(error);
|
|
85
85
|
return message.includes("Aborted") || message.includes("abort()");
|
|
86
86
|
}
|
|
@@ -4012,54 +4012,3 @@ export class TreeSitterClient {
|
|
|
4012
4012
|
}
|
|
4013
4013
|
}
|
|
4014
4014
|
// --- Simplified Pattern Search (regex fallback) ---
|
|
4015
|
-
/**
|
|
4016
|
-
* Fallback structural search using regex when tree-sitter unavailable
|
|
4017
|
-
* Less accurate but works without WASM dependencies
|
|
4018
|
-
*/
|
|
4019
|
-
export function regexStructuralSearch(pattern, files, options = {}) {
|
|
4020
|
-
const matches = [];
|
|
4021
|
-
const maxResults = options.maxResults ?? 50;
|
|
4022
|
-
// Extract pattern structure for regex
|
|
4023
|
-
// "console.log($MSG)" -> /console\.log\(([^)]+)\)/
|
|
4024
|
-
const regexPattern = pattern
|
|
4025
|
-
.replace(/\\/g, "\\\\")
|
|
4026
|
-
.replace(/\./g, "\\.")
|
|
4027
|
-
.replace(/\$\$\$[A-Z_][A-Z0-9_]*/g, "(.*?)") // variadic - non-greedy
|
|
4028
|
-
.replace(/\$[A-Z_][A-Z0-9_]*/g, "([^,)]+)"); // single - capture group
|
|
4029
|
-
try {
|
|
4030
|
-
const regex = new RegExp(regexPattern, "g");
|
|
4031
|
-
for (const file of files) {
|
|
4032
|
-
if (matches.length >= maxResults)
|
|
4033
|
-
break;
|
|
4034
|
-
try {
|
|
4035
|
-
const content = fs.readFileSync(file, "utf-8");
|
|
4036
|
-
const lines = content.split("\n");
|
|
4037
|
-
for (let i = 0; i < lines.length; i++) {
|
|
4038
|
-
regex.lastIndex = 0;
|
|
4039
|
-
const match = regex.exec(lines[i]);
|
|
4040
|
-
if (match) {
|
|
4041
|
-
const captures = {};
|
|
4042
|
-
// Extract captures
|
|
4043
|
-
for (let j = 1; j < match.length; j++) {
|
|
4044
|
-
captures[`$${j}`] = match[j];
|
|
4045
|
-
}
|
|
4046
|
-
matches.push({
|
|
4047
|
-
file,
|
|
4048
|
-
line: i + 1,
|
|
4049
|
-
column: match.index + 1,
|
|
4050
|
-
matchedText: match[0],
|
|
4051
|
-
captures,
|
|
4052
|
-
});
|
|
4053
|
-
if (matches.length >= maxResults)
|
|
4054
|
-
break;
|
|
4055
|
-
}
|
|
4056
|
-
}
|
|
4057
|
-
}
|
|
4058
|
-
catch { }
|
|
4059
|
-
}
|
|
4060
|
-
}
|
|
4061
|
-
catch {
|
|
4062
|
-
// Invalid regex
|
|
4063
|
-
}
|
|
4064
|
-
return matches;
|
|
4065
|
-
}
|
|
@@ -272,7 +272,15 @@ export class TrivyClient extends SecurityScanClient {
|
|
|
272
272
|
const findings = parseTrivyReport(raw);
|
|
273
273
|
const secrets = parseTrivySecrets(raw);
|
|
274
274
|
const licenses = parseTrivyLicenses(raw);
|
|
275
|
-
|
|
275
|
+
// #2154: the one trivy site that parsed a scan of this root.
|
|
276
|
+
return {
|
|
277
|
+
success: true,
|
|
278
|
+
analyzed: true,
|
|
279
|
+
findings,
|
|
280
|
+
secrets,
|
|
281
|
+
licenses,
|
|
282
|
+
scannedAt,
|
|
283
|
+
};
|
|
276
284
|
}
|
|
277
285
|
catch (err) {
|
|
278
286
|
return {
|
|
@@ -18,10 +18,6 @@
|
|
|
18
18
|
import { truncateToWidth } from "./deps/pi-tui.js";
|
|
19
19
|
const ELLIPSIS_KIND = { "…": 0, "...": 1, "": 2 };
|
|
20
20
|
let truncateIsNative = null;
|
|
21
|
-
/** Test-only: reset the signature probe between test cases. */
|
|
22
|
-
export function _resetTruncateProbeForTests() {
|
|
23
|
-
truncateIsNative = null;
|
|
24
|
-
}
|
|
25
21
|
export function fitLine(s, maxWidth, ellipsis = "...") {
|
|
26
22
|
const w = Math.max(0, maxWidth);
|
|
27
23
|
const fn = truncateToWidth;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
import { getProcessSingleton } from "./process-singletons.js";
|
|
3
|
+
const FAMILY = "turn-context";
|
|
4
|
+
const VERSION = 2;
|
|
5
|
+
function state() {
|
|
6
|
+
return getProcessSingleton(FAMILY, VERSION, () => ({
|
|
7
|
+
sessions: new Map(),
|
|
8
|
+
activeSession: new AsyncLocalStorage(),
|
|
9
|
+
}));
|
|
10
|
+
}
|
|
11
|
+
function sessionState(sessionId) {
|
|
12
|
+
const current = state();
|
|
13
|
+
let session = current.sessions.get(sessionId);
|
|
14
|
+
if (!session) {
|
|
15
|
+
session = { turnId: `${sessionId}:0`, turnIndex: 0 };
|
|
16
|
+
current.sessions.set(sessionId, session);
|
|
17
|
+
}
|
|
18
|
+
return session;
|
|
19
|
+
}
|
|
20
|
+
/** Reset the emit identity before a new session can publish rows. */
|
|
21
|
+
export function resetTurnContext(sessionId) {
|
|
22
|
+
const current = state();
|
|
23
|
+
if (sessionId === undefined)
|
|
24
|
+
return;
|
|
25
|
+
current.sessions.set(sessionId, { turnId: `${sessionId}:0`, turnIndex: 0 });
|
|
26
|
+
}
|
|
27
|
+
/** Ensure a stable host session has a counter without changing detached identity. */
|
|
28
|
+
export function setTurnContextSession(sessionId) {
|
|
29
|
+
const stableSessionId = sessionId?.trim();
|
|
30
|
+
if (stableSessionId !== undefined && stableSessionId !== "")
|
|
31
|
+
sessionState(stableSessionId);
|
|
32
|
+
}
|
|
33
|
+
/** Mint the one id shared by every row emitted during this turn. */
|
|
34
|
+
export function beginTurnContext(sessionId) {
|
|
35
|
+
const session = sessionState(sessionId);
|
|
36
|
+
session.turnIndex += 1;
|
|
37
|
+
session.turnId = `${sessionId}:${session.turnIndex}`;
|
|
38
|
+
return session.turnId;
|
|
39
|
+
}
|
|
40
|
+
/** Run a host event with the session identity that owns its writes. */
|
|
41
|
+
export function runWithTurnContext(sessionId, fn) {
|
|
42
|
+
if (sessionId === undefined)
|
|
43
|
+
return fn();
|
|
44
|
+
return state().activeSession.run(sessionId, fn);
|
|
45
|
+
}
|
|
46
|
+
export function getTurnId() {
|
|
47
|
+
const current = state();
|
|
48
|
+
const sessionId = current.activeSession.getStore();
|
|
49
|
+
if (sessionId === undefined)
|
|
50
|
+
return "turn:0";
|
|
51
|
+
return sessionState(sessionId).turnId;
|
|
52
|
+
}
|
|
@@ -32,10 +32,6 @@ export function wireUserNotifier(portsOrGetter) {
|
|
|
32
32
|
export function resetUserNotifier() {
|
|
33
33
|
notifierGetter = undefined;
|
|
34
34
|
}
|
|
35
|
-
/** True when a host render path is available (for callers that want to branch). */
|
|
36
|
-
export function hasUserNotifier() {
|
|
37
|
-
return notifierGetter !== undefined;
|
|
38
|
-
}
|
|
39
35
|
/**
|
|
40
36
|
* Best-effort delivery of a user-facing degradation. Never throws — a stale
|
|
41
37
|
* `ctx` after a session replacement must degrade to a no-op, not break the
|
|
@@ -358,7 +358,7 @@ observedAt) {
|
|
|
358
358
|
// #555 guard.
|
|
359
359
|
const key = fileMapKey(filePath);
|
|
360
360
|
if (!diagnosticsWriteGuard.shouldWrite(key, writeIndex))
|
|
361
|
-
return;
|
|
361
|
+
return false;
|
|
362
362
|
// Keep runner state ordered with the final diagnostic replacement. The
|
|
363
363
|
// guards are deliberately advanced in both directions because either verb
|
|
364
364
|
// may be the first completion from a pipeline.
|
|
@@ -369,6 +369,7 @@ observedAt) {
|
|
|
369
369
|
const observedTs = observedAt ?? Date.now();
|
|
370
370
|
const rec = getOrCreate(filePath, key);
|
|
371
371
|
commitDiagnostics(rec, filePath, normalizeDiagnostics(filePath, diagnostics, observedTs), observedTs, key);
|
|
372
|
+
return true;
|
|
372
373
|
}
|
|
373
374
|
/** Map the raw diagnostic shape callers pass into stored {@link WidgetDiagnostic}s.
|
|
374
375
|
* Every produced entry is stamped with `observedTs` (#1186) — the time THIS batch
|
|
@@ -605,8 +606,8 @@ export function reconcileCascadeNeighborLspErrors(filePath, lspErrorDiagnostics,
|
|
|
605
606
|
*/
|
|
606
607
|
export function reconcileScanDiagnostics(filePath, diagnostics, confirmed, writeIndex, observedAt) {
|
|
607
608
|
if (!confirmed)
|
|
608
|
-
return;
|
|
609
|
-
recordDiagnostics(filePath, diagnostics, writeIndex, observedAt);
|
|
609
|
+
return false;
|
|
610
|
+
return recordDiagnostics(filePath, diagnostics, writeIndex, observedAt);
|
|
610
611
|
}
|
|
611
612
|
/**
|
|
612
613
|
* Commit the already-correlated result of a full diagnostics scan.
|
|
@@ -47,10 +47,3 @@ export function logWordIndex(entry) {
|
|
|
47
47
|
cwd: normalizeFilePath(entry.cwd),
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
-
export function getWordIndexLogPath() {
|
|
51
|
-
return WORD_INDEX_LOG_FILE;
|
|
52
|
-
}
|
|
53
|
-
/** Resolve once all enqueued word-index writes are on disk (tests/shutdown). */
|
|
54
|
-
export function flushWordIndexLog() {
|
|
55
|
-
return writer.flush();
|
|
56
|
-
}
|
|
@@ -30,8 +30,8 @@ import { createDeadline, yieldIfOverBudget, } from "./cooperative-budget.js";
|
|
|
30
30
|
/**
|
|
31
31
|
* Bytes of backing store per posting entry: one `fileId` lane and one `line`
|
|
32
32
|
* lane, both `Int32`. This is the constant #2069's acceptance criterion is
|
|
33
|
-
* written against, and
|
|
34
|
-
*
|
|
33
|
+
* written against, and the arithmetic the memory-sample record and the
|
|
34
|
+
* regression test both read.
|
|
35
35
|
*/
|
|
36
36
|
export const WORD_POSTING_ENTRY_BYTES = 8;
|
|
37
37
|
/**
|
|
@@ -189,10 +189,6 @@ export class WordPostingList {
|
|
|
189
189
|
return list;
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
/** Estimated bytes one posting list holds, backing store plus fixed headers. */
|
|
193
|
-
export function estimatePostingListBytes(list) {
|
|
194
|
-
return list.byteLength + WORD_POSTING_LIST_OVERHEAD_BYTES;
|
|
195
|
-
}
|
|
196
192
|
/**
|
|
197
193
|
* Re-home every posting list into ONE shared `ArrayBuffer`, exactly sized.
|
|
198
194
|
*
|
|
@@ -405,7 +401,7 @@ export class WordForwardEntry {
|
|
|
405
401
|
* Bytes per forward entry: one pointer-compressed slot for the shared token
|
|
406
402
|
* string and one `Int32` count lane.
|
|
407
403
|
*/
|
|
408
|
-
|
|
404
|
+
const WORD_FORWARD_ENTRY_BYTES = 8;
|
|
409
405
|
/**
|
|
410
406
|
* The word index's dense file-id space: canonical path key → integer id →
|
|
411
407
|
* display path.
|