@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
|
@@ -1,55 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { getProjectIgnoreMatcher, isExcludedDirName, } from "./file-utils.js";
|
|
4
|
-
import { isGeneratedArtifactDirectoryName, isGeneratedOrArtifact, } from "./generated-artifacts.js";
|
|
5
|
-
import { collectSourceFiles, collectSourceFilesAsync, collectSourceFilesWithBudgetAsync, } from "./source-filter.js";
|
|
6
|
-
export function shouldSkipProjectPath(filePath, options) {
|
|
7
|
-
const isDirectory = options.isDirectory === true;
|
|
8
|
-
const matcher = options.ignoreMatcher ?? getProjectIgnoreMatcher(options.rootDir);
|
|
9
|
-
if (matcher.isIgnored(filePath, isDirectory))
|
|
10
|
-
return true;
|
|
11
|
-
const name = path.basename(filePath);
|
|
12
|
-
if (isDirectory) {
|
|
13
|
-
if (isExcludedDirName(name))
|
|
14
|
-
return true;
|
|
15
|
-
return (options.includeGenerated !== true &&
|
|
16
|
-
isGeneratedArtifactDirectoryName(name));
|
|
17
|
-
}
|
|
18
|
-
return (options.includeGenerated !== true &&
|
|
19
|
-
isGeneratedOrArtifact(filePath, {
|
|
20
|
-
readContentHeader: options.inspectGeneratedHeaders !== false,
|
|
21
|
-
includeDeclarations: options.includeDeclarationFiles !== true,
|
|
22
|
-
}));
|
|
23
|
-
}
|
|
24
|
-
export function shouldScanProjectSourceFile(filePath, options) {
|
|
25
|
-
try {
|
|
26
|
-
if (!fs.statSync(filePath).isFile())
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
return !shouldSkipProjectPath(filePath, {
|
|
33
|
-
...options,
|
|
34
|
-
isDirectory: false,
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
export function collectProjectSourceFiles(rootDir, options) {
|
|
38
|
-
return collectSourceFiles(rootDir, options);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Async, chunked-yield twin of {@link collectProjectSourceFiles}. Produces the
|
|
42
|
-
* exact same file list (it shares `classifyEntry` with the sync collector) but
|
|
43
|
-
* yields to the event loop every N entries so a large-tree walk on a hot hook
|
|
44
|
-
* tick (e.g. the per-edit cascade graph rebuild) never holds the loop in one
|
|
45
|
-
* synchronous burst. Prefer this on the per-edit / per-cascade path.
|
|
46
|
-
*/
|
|
47
|
-
export function collectProjectSourceFilesAsync(rootDir, options) {
|
|
48
|
-
return collectSourceFilesAsync(rootDir, options);
|
|
49
|
-
}
|
|
1
|
+
import { collectSourceFilesWithBudgetAsync, } from "./source-filter.js";
|
|
50
2
|
/**
|
|
51
|
-
* Budget-aware
|
|
52
|
-
*
|
|
3
|
+
* Budget-aware source walk (#760): the same walk as
|
|
4
|
+
* `collectProjectSourceFiles`, but returns `{ files, entryBudgetExceeded }` so a caller on a hot
|
|
53
5
|
* path (e.g. the per-edit cascade graph rebuild) can observe that the walk
|
|
54
6
|
* stopped at its `maxScanEntries` entry budget and got a truncated
|
|
55
7
|
* best-effort list rather than a complete enumeration.
|
|
@@ -3,6 +3,7 @@ import { isTestMode } from "./env-utils.js";
|
|
|
3
3
|
import { getGlobalPiLensLogDir } from "./probe-home-state.js";
|
|
4
4
|
import { createNdjsonLogger } from "./ndjson-logger.js";
|
|
5
5
|
import { normalizeFilePath } from "./path-utils.js";
|
|
6
|
+
import { getTurnId } from "./turn-context.js";
|
|
6
7
|
const READ_GUARD_LOG_DIR = getGlobalPiLensLogDir();
|
|
7
8
|
const READ_GUARD_LOG_FILE = path.join(READ_GUARD_LOG_DIR, "read-guard.log");
|
|
8
9
|
const READ_GUARD_LOG_BACKUP_FILE = path.join(READ_GUARD_LOG_DIR, "read-guard.log.1");
|
|
@@ -18,7 +19,7 @@ const VERBOSE_READ_GUARD_LOG = process.env.PI_LENS_READ_GUARD_VERBOSE === "1" ||
|
|
|
18
19
|
const LOG_ALLOWED_EDITS = process.env.PI_LENS_READ_GUARD_LOG_ALLOWS === "1";
|
|
19
20
|
const SNAPSHOT_LOG_SETTING = (process.env.PI_LENS_READ_GUARD_LOG_SNAPSHOTS ?? "1").toLowerCase();
|
|
20
21
|
const LOG_SNAPSHOT_VALIDATION = !["0", "false", "off"].includes(SNAPSHOT_LOG_SETTING);
|
|
21
|
-
|
|
22
|
+
const MAX_EDIT_BATCH_ITEMS = 100;
|
|
22
23
|
let generatedCorrelationCounter = 0;
|
|
23
24
|
export function sanitizeCorrelationId(value) {
|
|
24
25
|
if (typeof value !== "string" && typeof value !== "number")
|
|
@@ -236,6 +237,7 @@ export function logReadGuardEvent(entry) {
|
|
|
236
237
|
writer.log({
|
|
237
238
|
ts: new Date().toISOString(),
|
|
238
239
|
...logEntry,
|
|
240
|
+
turnId: getTurnId(),
|
|
239
241
|
filePath: normalizeFilePath(logEntry.filePath),
|
|
240
242
|
metadata,
|
|
241
243
|
});
|
|
@@ -1396,8 +1396,11 @@ export class ReadGuard {
|
|
|
1396
1396
|
return filePath.endsWith(suffix);
|
|
1397
1397
|
}
|
|
1398
1398
|
if (pattern.includes("*")) {
|
|
1399
|
-
//
|
|
1400
|
-
|
|
1399
|
+
// Adjacent stars are equivalent to one star in this dialect. Collapse
|
|
1400
|
+
// them before compiling so a non-match cannot backtrack over every
|
|
1401
|
+
// nullable `.*` group (#2622).
|
|
1402
|
+
const collapsedPattern = pattern.replace(/\*+/g, "*");
|
|
1403
|
+
const regex = new RegExp(`^${collapsedPattern.replace(/\\/g, "\\\\").replace(/\./g, "\\.").replace(/\*/g, ".*")}$`);
|
|
1401
1404
|
return regex.test(filePath);
|
|
1402
1405
|
}
|
|
1403
1406
|
return filePath === pattern;
|
|
@@ -37,7 +37,7 @@ import { getProjectDataDir } from "./file-utils.js";
|
|
|
37
37
|
import { normalizeFilePath } from "./path-utils.js";
|
|
38
38
|
export const RECENT_TOUCHES_MAX_ENTRIES = 50;
|
|
39
39
|
/** Freshness window for the CHILD session_start consumer (15 minutes). */
|
|
40
|
-
|
|
40
|
+
const RECENT_TOUCHES_FRESHNESS_MS = 15 * 60 * 1000;
|
|
41
41
|
function recentTouchesPath(cwd) {
|
|
42
42
|
return path.join(getProjectDataDir(cwd), "recent-touches.json");
|
|
43
43
|
}
|
|
@@ -46,7 +46,7 @@ function recentTouchesPath(cwd) {
|
|
|
46
46
|
// INTO the same nudge pipeline, so one switch governs the whole path
|
|
47
47
|
// (producer, both consumers) as specified in the issue.
|
|
48
48
|
let _enabledCache;
|
|
49
|
-
|
|
49
|
+
function isRecentTouchesEnabled() {
|
|
50
50
|
if (_enabledCache === undefined) {
|
|
51
51
|
_enabledCache = process.env.PI_LENS_AGENT_NUDGE !== "0";
|
|
52
52
|
}
|
|
@@ -92,8 +92,6 @@ const MAIN_KINDS = new Set([
|
|
|
92
92
|
// so a repo heavy in JSON/YAML/Markdown doesn't trip the cap on files the graph
|
|
93
93
|
// would have filtered out anyway (the cap is on the walk, not on noise). #250.
|
|
94
94
|
const MAIN_KIND_EXTENSIONS = Array.from(MAIN_KINDS).flatMap((kind) => KIND_EXTENSIONS[kind] ?? []);
|
|
95
|
-
/** The bounded, source-filtered extension set shared by graph cache readers. */
|
|
96
|
-
export const REVIEW_GRAPH_SOURCE_EXTENSIONS = MAIN_KIND_EXTENSIONS;
|
|
97
95
|
const CHANGED_SYMBOLS_PREFIX = "session.reviewGraph.changedSymbols:";
|
|
98
96
|
const extractorCache = new Map();
|
|
99
97
|
const REVIEW_GRAPH_MAX_WARM_WORKSPACES = 8;
|
|
@@ -407,7 +405,7 @@ export function estimateReviewGraphStoreBytes(totalNodes, totalEdges) {
|
|
|
407
405
|
// cleared). Bounding only the cache left the full graph resident on the fact, so
|
|
408
406
|
// both sites go through `retainedGraph` below, memoized per graph instance so the
|
|
409
407
|
// two sites share ONE bounded object instead of trimming twice (#2255 review F2).
|
|
410
|
-
|
|
408
|
+
const GRAPH_MAX_IN_MEMORY_BYTES_DEFAULT = 512 * 1024 * 1024;
|
|
411
409
|
function graphMaxInMemoryBytes() {
|
|
412
410
|
const raw = Number(process.env.PI_LENS_GRAPH_MAX_IN_MEMORY_BYTES);
|
|
413
411
|
return Number.isFinite(raw) && raw > 0
|
|
@@ -967,7 +965,7 @@ function diffSignatureMaps(previous, next) {
|
|
|
967
965
|
// `RUNTIME_CONFIG.reviewGraph.maxFiles` constant as the fallback — the ratio
|
|
968
966
|
// table reproduces that same 1,000-file default at the default base, so this
|
|
969
967
|
// is behavior-neutral when nothing is configured.
|
|
970
|
-
|
|
968
|
+
function getReviewGraphMaxFiles(cwd) {
|
|
971
969
|
const override = Number.parseInt(process.env.PI_LENS_REVIEW_GRAPH_MAX_FILES ?? "", 10);
|
|
972
970
|
return Number.isFinite(override) && override > 0
|
|
973
971
|
? override
|
|
@@ -3481,7 +3479,7 @@ function addTreeSitterFile(graph, cwd, filePath, languageId, extracted, ignoredI
|
|
|
3481
3479
|
* SymbolInformation results (including native TypeScript 7) recover the same
|
|
3482
3480
|
* containment through `containerName` when the owner is present in the result.
|
|
3483
3481
|
*/
|
|
3484
|
-
|
|
3482
|
+
function addLspFallbackSymbols(graph, filePath, languageId, symbols) {
|
|
3485
3483
|
const normalized = normalizeMapKey(filePath);
|
|
3486
3484
|
const fileNodeId = `file:${normalized}`;
|
|
3487
3485
|
let added = 0;
|
|
@@ -90,7 +90,7 @@ function resolveDart(cwd, filePath, source) {
|
|
|
90
90
|
// JS/TS extension from the specifier before re-appending candidate extensions
|
|
91
91
|
// lets that universal pattern resolve to the real source file. Exported so
|
|
92
92
|
// builder.ts's warm `localImportToFile` shares the exact same regex (#694).
|
|
93
|
-
|
|
93
|
+
const JS_TS_EXT_RE = /\.(mjs|cjs|mts|cts|jsx?|tsx?)$/i;
|
|
94
94
|
/**
|
|
95
95
|
* Ordered candidate list for resolving a relative JS/TS import specifier
|
|
96
96
|
* (already resolved to an absolute base path) to an on-disk file, with
|
|
@@ -4,6 +4,7 @@ import { getGlobalPiLensLogDir } from "./probe-home-state.js";
|
|
|
4
4
|
import { getMaxLogSizeMB } from "./log-cleanup.js";
|
|
5
5
|
import { createNdjsonLogger } from "./ndjson-logger.js";
|
|
6
6
|
import { normalizeFilePath } from "./path-utils.js";
|
|
7
|
+
import { getTurnId } from "./turn-context.js";
|
|
7
8
|
const REVIEW_GRAPH_LOG_DIR = getGlobalPiLensLogDir();
|
|
8
9
|
const REVIEW_GRAPH_LOG_FILE = path.join(REVIEW_GRAPH_LOG_DIR, "review-graph.log");
|
|
9
10
|
// Bounded like every other global sink (#2505) — see sessionstart-logger.
|
|
@@ -64,6 +65,7 @@ export function logReviewGraph(entry) {
|
|
|
64
65
|
...entry,
|
|
65
66
|
cwd: normalizeFilePath(entry.cwd),
|
|
66
67
|
pid: process.pid,
|
|
68
|
+
turnId: getTurnId(),
|
|
67
69
|
});
|
|
68
70
|
}
|
|
69
71
|
export function getReviewGraphLogPath() {
|
|
@@ -13,6 +13,7 @@ import * as path from "node:path";
|
|
|
13
13
|
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./dispatch/runners/utils/runner-helpers.js";
|
|
14
14
|
import { isFileKind } from "./file-kinds.js";
|
|
15
15
|
import { safeSpawnAsync } from "./safe-spawn.js";
|
|
16
|
+
import { resolveToolCwd } from "./tool-cwd.js";
|
|
16
17
|
import { ruffConfigArgs } from "./tool-policy.js";
|
|
17
18
|
// --- Client ---
|
|
18
19
|
const ruffAvailability = createAvailabilityChecker("ruff", ".exe");
|
|
@@ -44,8 +45,11 @@ export class RuffClient {
|
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
47
|
* Async auto-fix variant for pipeline use (non-blocking spawn).
|
|
47
|
-
* `cwd` is the dispatch language root
|
|
48
|
-
*
|
|
48
|
+
* `cwd` is the dispatch language root. It is the seam's starting point,
|
|
49
|
+
* not the answer: `resolveToolCwd` walks from the file to the nearest
|
|
50
|
+
* `pyproject.toml`/`ruff.toml`/`.ruff.toml` at or above it, capped inside
|
|
51
|
+
* `cwd` (and at `$HOME` when there is none), so a file in a nested package
|
|
52
|
+
* gets that package's config rather than the workspace-root one.
|
|
49
53
|
*/
|
|
50
54
|
async fixFileAsync(filePath, cwd) {
|
|
51
55
|
if (!(await this.ensureAvailable())) {
|
|
@@ -67,15 +71,20 @@ export class RuffClient {
|
|
|
67
71
|
}
|
|
68
72
|
try {
|
|
69
73
|
const before = await fs.promises.readFile(absolutePath, "utf-8");
|
|
74
|
+
// #2894: the root ruff resolves its config from now comes from the
|
|
75
|
+
// shared seam, not a local `cwd ?? path.dirname(file)`. `tool-policy.ts`
|
|
76
|
+
// requires the lint runner (`ruff.ts`, on `resolveRunnerCwd`) and this
|
|
77
|
+
// autofix path to consume the SAME policy; deriving the root two
|
|
78
|
+
// different ways is how they drift, and the hand-rolled form ignored a
|
|
79
|
+
// nested `pyproject.toml` whenever the caller passed a workspace root.
|
|
80
|
+
const ruffCwd = resolveToolCwd("runner", "ruff", absolutePath, {
|
|
81
|
+
...(cwd !== undefined && { cwd }),
|
|
82
|
+
});
|
|
70
83
|
// Shared config-args seam (#1247): the lint runner consumes the same
|
|
71
84
|
// builder, so `check --fix` can never drift to ruff's default rule
|
|
72
85
|
// set when the project lacks its own config and the package-owned
|
|
73
86
|
// core.toml fallback applies.
|
|
74
|
-
const configArgs = ruffConfigArgs(
|
|
75
|
-
const spawnOpts = {
|
|
76
|
-
timeout: 10000,
|
|
77
|
-
cwd: cwd ?? path.dirname(absolutePath),
|
|
78
|
-
};
|
|
87
|
+
const configArgs = ruffConfigArgs(ruffCwd);
|
|
79
88
|
const pre = await safeSpawnAsync(this.ruffCommand, [
|
|
80
89
|
"check",
|
|
81
90
|
"--output-format",
|
|
@@ -84,12 +93,12 @@ export class RuffClient {
|
|
|
84
93
|
"py310",
|
|
85
94
|
...configArgs,
|
|
86
95
|
absolutePath,
|
|
87
|
-
],
|
|
96
|
+
], { timeout: 10000, cwd: ruffCwd });
|
|
88
97
|
const beforeDiags = pre.stdout?.trim()
|
|
89
98
|
? this.parseOutput(pre.stdout, absolutePath)
|
|
90
99
|
: [];
|
|
91
100
|
const fixableCount = beforeDiags.filter((d) => d.fixable).length;
|
|
92
|
-
const fix = await safeSpawnAsync(this.ruffCommand, ["check", "--fix", ...configArgs, absolutePath], { timeout: 15000, cwd:
|
|
101
|
+
const fix = await safeSpawnAsync(this.ruffCommand, ["check", "--fix", ...configArgs, absolutePath], { timeout: 15000, cwd: ruffCwd });
|
|
93
102
|
if (fix.error) {
|
|
94
103
|
return {
|
|
95
104
|
success: false,
|
|
@@ -19,7 +19,7 @@ import { getAutofixPolicyForFile, hasBiomeConfig, hasDetektConfig, hasEslintConf
|
|
|
19
19
|
* path at all (they match on `ownerSessionId`), so this only trades a little
|
|
20
20
|
* extra staleness for guaranteed eventual formatting. (#791)
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
const DEFERRED_FORMAT_STALE_AFTER_MS = 10 * 60_000;
|
|
23
23
|
const DEFERRED_FORMAT_CONCURRENCY = 3;
|
|
24
24
|
function recordProjectChange(args) {
|
|
25
25
|
// One mutation seam (#2000 phase 1): bump + receipt + change-log live in
|
|
@@ -39,6 +39,7 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
|
|
|
39
39
|
// to fall back to "claim as orphaned" (see claimDeferredFormatFiles).
|
|
40
40
|
const { claimed, staleClaimed, deferredToOwner, droppedOrphans } = runtime.claimDeferredMutations(currentSessionId, Date.now(), staleAfterMs, ctxCwd ?? runtime.projectRoot);
|
|
41
41
|
const records = [...claimed, ...staleClaimed];
|
|
42
|
+
const scheduledTurnId = records[0]?.queuedTurnId;
|
|
42
43
|
const requeuedKinds = new Set();
|
|
43
44
|
// S2d (gap 4, #1432 review): the aggregate `agent_end_deferred_mutation_drain`
|
|
44
45
|
// row only carried a coalesced `requeuedKinds` set with no reason, per-call
|
|
@@ -65,6 +66,7 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
|
|
|
65
66
|
toolName: "agent_end",
|
|
66
67
|
filePath: ctxCwd ?? runtime.projectRoot,
|
|
67
68
|
phase: "agent_end_deferred_mutation_requeue",
|
|
69
|
+
turnId: pending[0]?.queuedTurnId,
|
|
68
70
|
durationMs: 0,
|
|
69
71
|
metadata: {
|
|
70
72
|
reason,
|
|
@@ -170,6 +172,7 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
|
|
|
170
172
|
toolName: "agent_end",
|
|
171
173
|
filePath: ctxCwd ?? runtime.projectRoot,
|
|
172
174
|
phase: "agent_end_deferred_format_stale_claim",
|
|
175
|
+
turnId: scheduledTurnId,
|
|
173
176
|
durationMs: 0,
|
|
174
177
|
metadata: {
|
|
175
178
|
fileCount: staleClaimed.length,
|
|
@@ -307,6 +310,7 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
|
|
|
307
310
|
toolName: "agent_end",
|
|
308
311
|
filePath: ctxCwd ?? runtime.projectRoot,
|
|
309
312
|
phase: "agent_end_deferred_format_start",
|
|
313
|
+
turnId: scheduledTurnId,
|
|
310
314
|
durationMs: 0,
|
|
311
315
|
metadata: {
|
|
312
316
|
fileCount: records.length,
|
|
@@ -491,6 +495,7 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
|
|
|
491
495
|
toolName: "agent_end",
|
|
492
496
|
filePath,
|
|
493
497
|
phase: "deferred_format_file",
|
|
498
|
+
turnId: record.queuedTurnId,
|
|
494
499
|
durationMs: Date.now() - fileStart,
|
|
495
500
|
metadata: {
|
|
496
501
|
changed: result.formatChanged,
|
|
@@ -635,6 +640,7 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
|
|
|
635
640
|
toolName: "agent_end",
|
|
636
641
|
filePath: ctxCwd ?? runtime.projectRoot,
|
|
637
642
|
phase: "actionable_warnings_autofix",
|
|
643
|
+
turnId: scheduledTurnId,
|
|
638
644
|
durationMs: Date.now() - fixStart,
|
|
639
645
|
metadata: {
|
|
640
646
|
considered: fixSummary.considered,
|
|
@@ -657,6 +663,7 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
|
|
|
657
663
|
toolName: "agent_end",
|
|
658
664
|
filePath: ctxCwd ?? runtime.projectRoot,
|
|
659
665
|
phase: "agent_end_deferred_mutation_drain",
|
|
666
|
+
turnId: scheduledTurnId,
|
|
660
667
|
durationMs: Date.now() - startedAt,
|
|
661
668
|
metadata: {
|
|
662
669
|
autofixRecords: autofixRecords.length,
|
|
@@ -671,6 +678,7 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
|
|
|
671
678
|
filePath: ctxCwd ?? runtime.projectRoot,
|
|
672
679
|
durationMs: Date.now() - startedAt,
|
|
673
680
|
result: "deferred_format_complete",
|
|
681
|
+
turnId: scheduledTurnId,
|
|
674
682
|
metadata: {
|
|
675
683
|
queued: summary.queued,
|
|
676
684
|
formatted: summary.formatted,
|
|
@@ -685,6 +693,7 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
|
|
|
685
693
|
toolName: "agent_end",
|
|
686
694
|
filePath: ctxCwd ?? runtime.projectRoot,
|
|
687
695
|
phase: "agent_end_deferred_format_done",
|
|
696
|
+
turnId: scheduledTurnId,
|
|
688
697
|
durationMs: Date.now() - startedAt,
|
|
689
698
|
metadata: {
|
|
690
699
|
formatted: summary.formatted,
|
|
@@ -11,6 +11,7 @@ import { ReadGuard } from "./read-guard.js";
|
|
|
11
11
|
import { RUNTIME_CONFIG } from "./runtime-config.js";
|
|
12
12
|
import { TurnSummaryCollector } from "./turn-summary.js";
|
|
13
13
|
import { deriveProviderFromModelId } from "./model-provider.js";
|
|
14
|
+
import { beginTurnContext, setTurnContextSession } from "./turn-context.js";
|
|
14
15
|
/**
|
|
15
16
|
* Bounded receipt ring capacity (defect shape 9: bound the axis that grows —
|
|
16
17
|
* per-mutation receipts are unbounded across a long session). Oldest receipts
|
|
@@ -259,6 +260,7 @@ export class RuntimeCoordinator {
|
|
|
259
260
|
// by resetForSession().
|
|
260
261
|
this._turnStartProjectSeq = this._projectSeq;
|
|
261
262
|
this._turnIndex += 1;
|
|
263
|
+
beginTurnContext(this._telemetrySessionId);
|
|
262
264
|
this._writeIndex = 0;
|
|
263
265
|
this._reportedThisTurn.clear();
|
|
264
266
|
this._writtenThisTurn.clear();
|
|
@@ -362,6 +364,7 @@ export class RuntimeCoordinator {
|
|
|
362
364
|
setTelemetryIdentity(identity) {
|
|
363
365
|
if (identity.sessionId && identity.sessionId.trim()) {
|
|
364
366
|
this._telemetrySessionId = identity.sessionId.trim();
|
|
367
|
+
setTurnContextSession(this._telemetrySessionId);
|
|
365
368
|
}
|
|
366
369
|
const model = identity.model?.trim();
|
|
367
370
|
const provider = identity.provider?.trim();
|
|
@@ -1029,6 +1032,7 @@ export class RuntimeCoordinator {
|
|
|
1029
1032
|
existing.toolNames.add(toolName);
|
|
1030
1033
|
existing.kinds.add(kind);
|
|
1031
1034
|
existing.queuedTurnIndex = this._turnIndex;
|
|
1035
|
+
existing.queuedTurnId = `${this._telemetrySessionId}:${this._turnIndex}`;
|
|
1032
1036
|
existing.ownerSessionId = ownerSessionId;
|
|
1033
1037
|
existing.originCwd = resolvedOriginCwd;
|
|
1034
1038
|
return addedKind;
|
|
@@ -1042,6 +1046,7 @@ export class RuntimeCoordinator {
|
|
|
1042
1046
|
toolNames: new Set([toolName]),
|
|
1043
1047
|
kinds: new Set([kind]),
|
|
1044
1048
|
queuedTurnIndex: this._turnIndex,
|
|
1049
|
+
queuedTurnId: `${this._telemetrySessionId}:${this._turnIndex}`,
|
|
1045
1050
|
ownerSessionId,
|
|
1046
1051
|
originCwd: resolvedOriginCwd,
|
|
1047
1052
|
});
|
|
@@ -5,7 +5,7 @@ import { rotateMessageEndAttribution } from "./message-end-attribution.js";
|
|
|
5
5
|
import { createDeadline, yieldIfOverBudget } from "./cooperative-budget.js";
|
|
6
6
|
import { deadCodeIssueCount } from "./dead-code-client.js";
|
|
7
7
|
import { logDeadCodeScan } from "./dead-code-logger.js";
|
|
8
|
-
import { incrementDegradationCount, resetDegradationLedger, } from "./degradation-ledger.js";
|
|
8
|
+
import { incrementDegradationCount, recordDegradationOnce, resetDegradationLedger, } from "./degradation-ledger.js";
|
|
9
9
|
import { getDiagnosticTracker } from "./diagnostic-tracker.js";
|
|
10
10
|
import { resetPsScriptAnalyzerAvailability } from "./dispatch/runners/psscriptanalyzer.js";
|
|
11
11
|
import { resetInstallRetryLatches } from "./dispatch/runners/utils/availability-policy.js";
|
|
@@ -42,6 +42,7 @@ import { resetSafeSpawnWindowsCommandCache } from "./safe-spawn.js";
|
|
|
42
42
|
import { resetAnalyzerBootstrapSessionState, } from "./bootstrap.js";
|
|
43
43
|
import { getSlowFsVerdict, isSlowFs, slowFsDegradationNotice, } from "./slow-fs.js";
|
|
44
44
|
import { countRecentSmells, formatSmellsSessionStartLine, resetSmellsSessionState, } from "./smells-rollup.js";
|
|
45
|
+
import { resetSituationalToolTelemetry } from "./situational-tool-telemetry.js";
|
|
45
46
|
import { findNearestProjectRoot, getStartupScanMaxEntries, isStartupScanVerdictFresh, resolveStartupScanContext, } from "./startup-scan.js";
|
|
46
47
|
import { getSubagentIdentity, isSubagentSession, subagentLightModeNotice, } from "./subagent-mode.js";
|
|
47
48
|
import { TrivyClient } from "./trivy-client.js";
|
|
@@ -256,11 +257,14 @@ function logProjectSnapshotProbe(args) {
|
|
|
256
257
|
args.dbg(`project_snapshot: miss reason=${args.missReason}`);
|
|
257
258
|
}
|
|
258
259
|
}
|
|
259
|
-
function resolveStartupMode() {
|
|
260
|
+
function resolveStartupMode(projectConfig, globalConfig) {
|
|
260
261
|
const envMode = (process.env.PI_LENS_STARTUP_MODE ?? "").trim().toLowerCase();
|
|
261
262
|
if (envMode === "full" || envMode === "minimal" || envMode === "quick") {
|
|
262
263
|
return envMode;
|
|
263
264
|
}
|
|
265
|
+
const configMode = projectConfig?.startup?.mode ?? globalConfig?.startup?.mode;
|
|
266
|
+
if (configMode)
|
|
267
|
+
return configMode;
|
|
264
268
|
if (isPrintMode()) {
|
|
265
269
|
return "quick";
|
|
266
270
|
}
|
|
@@ -813,6 +817,15 @@ function scheduleStartupScans(deps, runtime, sessionGeneration, analysisRoot, sn
|
|
|
813
817
|
/** The scan bodies, once the analyzers they need are resolved. */
|
|
814
818
|
function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analysisRoot, snapshotRoot, languageProfile, dbg) {
|
|
815
819
|
const { todoScanner, cacheManager, knipClient, jscpdClient, deadCodeClients, govulncheckClient, gitleaksClient, trivyClient, opengrepClient, astGrepClient, depChecker, } = deps;
|
|
820
|
+
const analyzerEnabled = (flag) => !deps.getFlag(flag);
|
|
821
|
+
if (!analyzerEnabled("no-complexity")) {
|
|
822
|
+
dbg("session_start complexity: skipped (disabled by config)");
|
|
823
|
+
recordDegradationOnce({
|
|
824
|
+
kind: "startup-analyzer-disabled",
|
|
825
|
+
subject: "complexity",
|
|
826
|
+
reason: "skipped (disabled by config)",
|
|
827
|
+
});
|
|
828
|
+
}
|
|
816
829
|
// Some background scans are CPU-heavy and arrive on the event loop
|
|
817
830
|
// just as the user is most likely typing (right after /new). Defer
|
|
818
831
|
// those by a few seconds so the perceptible 50-100ms sync bursts they
|
|
@@ -869,7 +882,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
869
882
|
scanNames.push("knip", "jscpd", "ast-grep exports", "project index");
|
|
870
883
|
}
|
|
871
884
|
dbg(`session_start: launching background scans (${scanNames.join(", ")})`);
|
|
872
|
-
runTask("todo", async () => {
|
|
885
|
+
void runTask("todo", async () => {
|
|
873
886
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
874
887
|
return;
|
|
875
888
|
// The original implementation called todoScanner.scanDirectory(), which
|
|
@@ -906,9 +919,19 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
906
919
|
const isSubagent = isSubagentSession();
|
|
907
920
|
const skipHeavyweightScans = isSlowFs(analysisRoot) || isSubagent;
|
|
908
921
|
const runHeavyweightTask = (name, task) => {
|
|
922
|
+
const flag = `no-${name}`;
|
|
923
|
+
if (name !== "opengrep" && name !== "trivy" && !analyzerEnabled(flag)) {
|
|
924
|
+
dbg(`session_start ${name}: skipped (disabled by config)`);
|
|
925
|
+
recordDegradationOnce({
|
|
926
|
+
kind: "startup-analyzer-disabled",
|
|
927
|
+
subject: name,
|
|
928
|
+
reason: "skipped (disabled by config)",
|
|
929
|
+
});
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
909
932
|
if (skipHeavyweightScans)
|
|
910
933
|
return;
|
|
911
|
-
runTask(name, task);
|
|
934
|
+
void runTask(name, task);
|
|
912
935
|
};
|
|
913
936
|
if (skipHeavyweightScans) {
|
|
914
937
|
dbg(`session_start: skipping knip/jscpd/madge/dead-code/govulncheck/gitleaks/trivy/opengrep (${isSubagent ? "subagent" : "slow-fs"})`);
|
|
@@ -1239,7 +1262,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
1239
1262
|
// racing its independently deferred timer. Otherwise a slow graph build leaves
|
|
1240
1263
|
// `runtime.callGraph` unset at this task's start and loses the model for the
|
|
1241
1264
|
// entire session (#1070).
|
|
1242
|
-
runTask("codebase-model", async () => {
|
|
1265
|
+
void runTask("codebase-model", async () => {
|
|
1243
1266
|
await callGraphTask;
|
|
1244
1267
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
1245
1268
|
return;
|
|
@@ -1258,7 +1281,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
1258
1281
|
`${model.totalTokens} tokens, top symbols: ${top3 || "(none)"}`);
|
|
1259
1282
|
});
|
|
1260
1283
|
// ast-grep — export scan for duplicate detection
|
|
1261
|
-
runTask("ast-grep-exports", async () => {
|
|
1284
|
+
void runTask("ast-grep-exports", async () => {
|
|
1262
1285
|
if (await astGrepClient.ensureAvailable()) {
|
|
1263
1286
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
1264
1287
|
return;
|
|
@@ -1275,7 +1298,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
1275
1298
|
// word-index — identifier inverted index + BM25 for ranked symbol search
|
|
1276
1299
|
// (#162). Load -> rebuild-if-stale -> persist lifecycle (#348), shared with
|
|
1277
1300
|
// the quick-mode cold-start warmup pass below.
|
|
1278
|
-
runTask("word-index", async () => {
|
|
1301
|
+
void runTask("word-index", async () => {
|
|
1279
1302
|
await buildOrRefreshWordIndex({
|
|
1280
1303
|
runtime,
|
|
1281
1304
|
sessionGeneration,
|
|
@@ -1339,17 +1362,16 @@ function scheduleDeferredToolProbesWithClients(deps, languageProfile, startupDef
|
|
|
1339
1362
|
/**
|
|
1340
1363
|
* Session-start orientation prepended as a context message (gated by the
|
|
1341
1364
|
* context-injection toggle). Deliberately lean: it names the high-value tools
|
|
1342
|
-
* and the
|
|
1365
|
+
* and the distinction between cached reporting and active verification
|
|
1343
1366
|
* — per-tool argument detail lives in each tool's own registered description, so
|
|
1344
1367
|
* re-documenting it here would just pay the tokens twice every session.
|
|
1345
1368
|
*/
|
|
1346
1369
|
export const SESSION_START_GUIDANCE = [
|
|
1347
1370
|
"📌 pi-lens active — automated checks run on every edit/write; blocking errors (including pre-existing) show inline and must be fixed.\n" +
|
|
1348
1371
|
"Key tools (see each tool's own description for args):\n" +
|
|
1349
|
-
"• lens_diagnostics — session
|
|
1372
|
+
"• lens_diagnostics — source=session reads cache; empty cache ≠ clean; use source=lsp scope=paths for changed files with absent or stale findings.\n" +
|
|
1350
1373
|
"• symbol_search → module_report → read_symbol/read_enclosing — ranked identifier search, then navigable outline/callback handles + exact body reads; cheaper than reading a whole file before editing.\n" +
|
|
1351
|
-
"•
|
|
1352
|
-
"• Situational (activate via pi_lens_activate_tools): lsp_navigation, ast_grep_search, ast_grep_replace, ast_grep_dump.",
|
|
1374
|
+
"• Situational (activate via pi_lens_activate_tools): lsp_navigation, ast_grep_search, ast_grep_replace. Use ast_grep_search with dump=true to inspect AST nodes.",
|
|
1353
1375
|
];
|
|
1354
1376
|
export async function handleSessionStart(deps) {
|
|
1355
1377
|
resetDegradationLedger();
|
|
@@ -1423,7 +1445,7 @@ export async function handleSessionStart(deps) {
|
|
|
1423
1445
|
// entirely — but only when PI_LENS_STARTUP_MODE is unset in the env
|
|
1424
1446
|
// (an explicit env var still takes highest precedence).
|
|
1425
1447
|
// Tunable: PI_LENS_WARMUP_DELAY_MS adjusts the warmup delay.
|
|
1426
|
-
let startupMode = resolveStartupMode();
|
|
1448
|
+
let startupMode = resolveStartupMode(deps.projectConfig, deps.globalConfig);
|
|
1427
1449
|
// SAFETY: these two flags are process-lifetime state pi-lens stashes on
|
|
1428
1450
|
// `globalThis` so a second extension instance in the same process sees the
|
|
1429
1451
|
// first one's warmup. There is no ambient declaration for them, and adding
|
|
@@ -1433,7 +1455,9 @@ export async function handleSessionStart(deps) {
|
|
|
1433
1455
|
const isFirstSessionOfProcess = !processGlobals.__piLensFirstSessionDone;
|
|
1434
1456
|
if (isFirstSessionOfProcess &&
|
|
1435
1457
|
process.env.PI_LENS_COLD_START_QUICK !== "0" &&
|
|
1436
|
-
!process.env.PI_LENS_STARTUP_MODE
|
|
1458
|
+
!process.env.PI_LENS_STARTUP_MODE &&
|
|
1459
|
+
!deps.projectConfig?.startup?.mode &&
|
|
1460
|
+
!deps.globalConfig?.startup?.mode) {
|
|
1437
1461
|
// Apply host-provided override (e.g. MCP server forces "full") before
|
|
1438
1462
|
// falling back to the TUI quick-mode heuristic.
|
|
1439
1463
|
startupMode = deps.startupModeOverride ?? "quick";
|
|
@@ -1790,6 +1814,15 @@ export async function handleSessionStart(deps) {
|
|
|
1790
1814
|
// #1123 item 3: a fresh session can re-report smells that a prior session
|
|
1791
1815
|
// already surfaced once (see `checkSmellsAndNoteOnce`'s once-per-session gate).
|
|
1792
1816
|
resetSmellsSessionState();
|
|
1817
|
+
// #2800 item 8: the situational-tool dead-weight observation (which tools
|
|
1818
|
+
// this session never activated or called) is session-scoped, so its sets
|
|
1819
|
+
// and once-latch re-arm here beside the other registered resets. Both hosts
|
|
1820
|
+
// open the session's row through startSituationalToolTelemetrySession()
|
|
1821
|
+
// BEFORE this handler runs, and a repeated MCP session_start refresh
|
|
1822
|
+
// legitimately re-runs this handler — so the reset only acts when no
|
|
1823
|
+
// telemetry session is open; clearing a live session here would wipe the
|
|
1824
|
+
// calls recorded before the refresh.
|
|
1825
|
+
resetSituationalToolTelemetry();
|
|
1793
1826
|
// #1782: re-arm the workspace-diagnostics cache session clock. Entries
|
|
1794
1827
|
// written before this instant assert findings from a session that is over,
|
|
1795
1828
|
// so they must revalidate before they can be served as current again.
|
|
@@ -2271,7 +2304,10 @@ export async function handleSessionStart(deps) {
|
|
|
2271
2304
|
else {
|
|
2272
2305
|
dbg("session_start: no language defaults selected for pre-install");
|
|
2273
2306
|
}
|
|
2274
|
-
const
|
|
2307
|
+
const startupScansEnabled = deps.projectConfig?.startup?.scans?.enabled ??
|
|
2308
|
+
deps.globalConfig?.startup?.scans?.enabled ??
|
|
2309
|
+
true;
|
|
2310
|
+
const startupScansWillRun = allowBootstrapTasks && startupScan.canWarmCaches && startupScansEnabled;
|
|
2275
2311
|
const jstsHeavyScansWillRun = startupScansWillRun && canRunStartupHeavyScans(languageProfile, "jsts");
|
|
2276
2312
|
if (allowBootstrapTasks) {
|
|
2277
2313
|
scheduleDeferredToolProbes(deps, languageProfile, startupDefaults, jstsHeavyScansWillRun, dbg);
|
|
@@ -2326,6 +2362,14 @@ export async function handleSessionStart(deps) {
|
|
|
2326
2362
|
if (!allowBootstrapTasks) {
|
|
2327
2363
|
dbg("session_start: skipping startup background scans (startup mode)");
|
|
2328
2364
|
}
|
|
2365
|
+
else if (!startupScansEnabled) {
|
|
2366
|
+
dbg("session_start: skipping startup background scans (disabled by config)");
|
|
2367
|
+
recordDegradationOnce({
|
|
2368
|
+
kind: "startup-analyzer-disabled",
|
|
2369
|
+
subject: "startup-scans",
|
|
2370
|
+
reason: "skipped (disabled by config)",
|
|
2371
|
+
});
|
|
2372
|
+
}
|
|
2329
2373
|
else if (!startupScan.canWarmCaches) {
|
|
2330
2374
|
dbg(`session_start: skipping heavy scans (${startupScan.reason ?? "unknown"})`);
|
|
2331
2375
|
dbg(`session_start: skipping TODO scan (${startupScan.reason ?? "unknown"})`);
|
|
@@ -773,7 +773,8 @@ async function handleToolCallImpl(deps) {
|
|
|
773
773
|
// is the client's own answer, hoisted into `tree-sitter-shared.ts` where it
|
|
774
774
|
// needs nothing but the extension registry; `ComplexityClient.isSupportedFile`
|
|
775
775
|
// delegates to it, so this is not a second copy.
|
|
776
|
-
if (!
|
|
776
|
+
if (!getFlag("no-complexity") &&
|
|
777
|
+
!isExternalOrVendor &&
|
|
777
778
|
filePath &&
|
|
778
779
|
!runtime.complexityBaselines.has(filePath) &&
|
|
779
780
|
isComplexitySupportedFile(filePath)) {
|
|
@@ -803,6 +804,15 @@ async function handleToolCallImpl(deps) {
|
|
|
803
804
|
});
|
|
804
805
|
}
|
|
805
806
|
}
|
|
807
|
+
else if (getFlag("no-complexity") &&
|
|
808
|
+
filePath &&
|
|
809
|
+
isComplexitySupportedFile(filePath)) {
|
|
810
|
+
recordDegradationOnce({
|
|
811
|
+
kind: "startup-analyzer-disabled",
|
|
812
|
+
subject: "complexity",
|
|
813
|
+
reason: "skipped (disabled by config)",
|
|
814
|
+
});
|
|
815
|
+
}
|
|
806
816
|
// --- Read-Before-Edit Guard: check edits ---
|
|
807
817
|
// write = full replacement; no prior read needed (you're starting fresh).
|
|
808
818
|
// edit = partial modification; guard enforced to prevent blind overwrites.
|
|
@@ -21,7 +21,7 @@ import { replayThroughMutationBridge, storedLineHashesFor, } from "./observed-mu
|
|
|
21
21
|
import { getAmbientAbortSignal } from "./safe-spawn.js";
|
|
22
22
|
import { resolveToolCallCorrelationId } from "./tool-event.js";
|
|
23
23
|
import { boundedIndexesForCount, createReadGuardEditBatchSummary, getReadGuardCorrelationId, logReadGuardEvent, } from "./read-guard-logger.js";
|
|
24
|
-
import { notifyExternalFileChange } from "./lsp/index.js";
|
|
24
|
+
import { notifyExternalFileChange, resyncGitChangedFiles, } from "./lsp/index.js";
|
|
25
25
|
import { runPipeline } from "./pipeline.js";
|
|
26
26
|
import { renderPostAutofixNotice, } from "./post-autofix-notice.js";
|
|
27
27
|
import { syncGitGuardRecord } from "./git-guard.js";
|
|
@@ -897,6 +897,9 @@ export async function handleToolResult(deps) {
|
|
|
897
897
|
durationMs: Date.now() - started,
|
|
898
898
|
result: `changed:${opaquePaths.length}`,
|
|
899
899
|
});
|
|
900
|
+
void resyncGitChangedFiles(opaquePaths).catch((err) => {
|
|
901
|
+
dbg(`git-change LSP resync failed: ${err}`);
|
|
902
|
+
});
|
|
900
903
|
}
|
|
901
904
|
}
|
|
902
905
|
// wp iterates opaquePaths VERBATIM (already normalizeMapKey keys), so the
|