@herbertgao/pi-extensions 2026.9.0 → 2026.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node_modules/@czottmann/pi-automode/CHANGELOG.md +13 -1
- package/node_modules/@czottmann/pi-automode/README.md +20 -0
- package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +1 -1
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +2 -1
- package/node_modules/@czottmann/pi-automode/docs/defaults.md +3 -2
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +38 -2
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +5 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +11 -3
- package/node_modules/@czottmann/pi-automode/package.json +1 -1
- package/node_modules/@narumitw/pi-btw/README.md +57 -141
- package/node_modules/@narumitw/pi-btw/dist/index.ts +466 -41
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +4 -4
- package/node_modules/@narumitw/pi-btw/docs/workflows.md +74 -0
- package/node_modules/@narumitw/pi-btw/package.json +2 -1
- package/node_modules/@narumitw/pi-btw/src/btw.ts +15 -1
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +32 -2
- package/node_modules/@narumitw/pi-btw/src/keybindings.ts +330 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +136 -19
- package/node_modules/@narumitw/pi-btw/src/settings.ts +32 -0
- package/node_modules/@narumitw/pi-btw/src/side-thread.ts +57 -5
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +52 -30
- package/node_modules/@pi-plugins/fast-mode/README.md +5 -3
- package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +20 -55
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/package.json +1 -1
- package/node_modules/pi-lens/CHANGELOG.md +1072 -0
- package/node_modules/pi-lens/README.md +3 -0
- package/node_modules/pi-lens/config/biome/core.jsonc +11 -2
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +13 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -9
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +927 -80
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +1 -1
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +13 -4
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +123 -3
- package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +60 -5
- package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +2 -9
- package/node_modules/pi-lens/dist/clients/ast-grep-types.js +2 -0
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +133 -3
- package/node_modules/pi-lens/dist/clients/biome-client.js +9 -2
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +14 -6
- package/node_modules/pi-lens/dist/clients/bootstrap.js +509 -73
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +152 -12
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +1 -1
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +59 -9
- package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +113 -0
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +3 -11
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +31 -4
- package/node_modules/pi-lens/dist/clients/cache-manager.js +105 -6
- package/node_modules/pi-lens/dist/clients/cache-observability.js +40 -19
- package/node_modules/pi-lens/dist/clients/cargo-manifest.js +422 -0
- package/node_modules/pi-lens/dist/clients/cascade-logger.js +2 -9
- package/node_modules/pi-lens/dist/clients/child-unref.js +1 -19
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +13 -3
- package/node_modules/pi-lens/dist/clients/complexity-client.js +16 -5
- package/node_modules/pi-lens/dist/clients/config-core/deny.js +221 -0
- package/node_modules/pi-lens/dist/clients/config-core/index.js +50 -0
- package/node_modules/pi-lens/dist/clients/config-core/merge.js +357 -0
- package/node_modules/pi-lens/dist/clients/config-core/normalize.js +340 -0
- package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +248 -0
- package/node_modules/pi-lens/dist/clients/config-core/provenance.js +164 -0
- package/node_modules/pi-lens/dist/clients/config-core/records.js +218 -0
- package/node_modules/pi-lens/dist/clients/config-core/resolve.js +125 -0
- package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +78 -0
- package/node_modules/pi-lens/dist/clients/config-core/schema.js +165 -0
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +281 -0
- package/node_modules/pi-lens/dist/clients/config-locations.js +160 -0
- package/node_modules/pi-lens/dist/clients/config-resolve.js +789 -0
- package/node_modules/pi-lens/dist/clients/config-schema.js +234 -0
- package/node_modules/pi-lens/dist/clients/config-warn.js +407 -0
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -14
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +2 -6
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +178 -0
- package/node_modules/pi-lens/dist/clients/debug-handles.js +2 -2
- package/node_modules/pi-lens/dist/clients/debug-heap.js +3 -3
- package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +106 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +113 -7
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +8 -19
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +1 -1
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +12 -9
- package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +15 -5
- package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +0 -4
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +162 -44
- package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +97 -0
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +27 -8
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +0 -6
- package/node_modules/pi-lens/dist/clients/dispatch/pending-runner-findings.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +0 -3
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-complexity.js +2 -2
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-fan-out.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +383 -27
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +4 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +1 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +14 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +6 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +7 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +1 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +1 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +4 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +3 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +3 -67
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +194 -80
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +84 -15
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils.js +0 -21
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +2 -20
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/utils/format-utils.js +2 -2
- package/node_modules/pi-lens/dist/clients/disposition-logger.js +3 -10
- package/node_modules/pi-lens/dist/clients/effective-config.js +403 -0
- package/node_modules/pi-lens/dist/clients/error-class.js +23 -0
- package/node_modules/pi-lens/dist/clients/event-loop-hold.js +274 -0
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +2 -2
- package/node_modules/pi-lens/dist/clients/extension-log.js +2 -2
- package/node_modules/pi-lens/dist/clients/feature-hints.js +2 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +1 -38
- package/node_modules/pi-lens/dist/clients/file-time.js +7 -2
- package/node_modules/pi-lens/dist/clients/file-utils.js +117 -10
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +50 -13
- package/node_modules/pi-lens/dist/clients/format-service.js +6 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +385 -104
- package/node_modules/pi-lens/dist/clients/freshness-cadence.js +17 -0
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +116 -22
- package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -9
- package/node_modules/pi-lens/dist/clients/git-guard.js +6 -1
- package/node_modules/pi-lens/dist/clients/go-client.js +39 -0
- package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +252 -0
- package/node_modules/pi-lens/dist/clients/grammar-source.js +3 -3
- package/node_modules/pi-lens/dist/clients/hashline-anchor.js +424 -0
- package/node_modules/pi-lens/dist/clients/hook-budgets.js +76 -0
- package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +5 -2
- package/node_modules/pi-lens/dist/clients/host-ports.js +1 -1
- package/node_modules/pi-lens/dist/clients/installer/index.js +289 -59
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +84 -18
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +110 -236
- package/node_modules/pi-lens/dist/clients/instance-registry.js +6 -3
- package/node_modules/pi-lens/dist/clients/language-profile.js +0 -9
- package/node_modules/pi-lens/dist/clients/language-registry.js +599 -0
- package/node_modules/pi-lens/dist/clients/latency-logger.js +165 -9
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +34 -1
- package/node_modules/pi-lens/dist/clients/lens-config.js +160 -30
- package/node_modules/pi-lens/dist/clients/lens-engine.js +33 -41
- package/node_modules/pi-lens/dist/clients/lens-events.js +1 -1
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +77 -6
- package/node_modules/pi-lens/dist/clients/lens-map.js +1 -1
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -38
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +3 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +172 -33
- package/node_modules/pi-lens/dist/clients/lsp/config.js +484 -158
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +18 -5
- package/node_modules/pi-lens/dist/clients/lsp/index.js +892 -96
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/language.js +18 -177
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +5 -18
- package/node_modules/pi-lens/dist/clients/lsp/server.js +284 -147
- package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +116 -23
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +2 -7
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +0 -1
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +14 -7
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +6 -0
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +163 -21
- package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +36 -0
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +33 -4
- package/node_modules/pi-lens/dist/clients/mcp/session.js +5 -16
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +8 -3
- package/node_modules/pi-lens/dist/clients/metrics-history.js +28 -107
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +3 -5
- package/node_modules/pi-lens/dist/clients/module-report.js +21 -46
- package/node_modules/pi-lens/dist/clients/mutating-tool.js +651 -0
- package/node_modules/pi-lens/dist/clients/mutation-attribution.js +368 -0
- package/node_modules/pi-lens/dist/clients/mutation-bridge.js +240 -0
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +247 -24
- package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +101 -0
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +1215 -0
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +70 -28
- package/node_modules/pi-lens/dist/clients/opengrep-config.js +5 -1
- package/node_modules/pi-lens/dist/clients/package-manager.js +195 -26
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +359 -80
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +23 -7
- package/node_modules/pi-lens/dist/clients/path-keyed-map.js +21 -2
- package/node_modules/pi-lens/dist/clients/path-utils.js +451 -15
- package/node_modules/pi-lens/dist/clients/performance-report.js +2 -2
- package/node_modules/pi-lens/dist/clients/persist-debounce.js +8 -1
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +114 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +79 -18
- package/node_modules/pi-lens/dist/clients/probe-home-state.js +228 -0
- package/node_modules/pi-lens/dist/clients/process-bridge.js +66 -0
- package/node_modules/pi-lens/dist/clients/process-snapshot.js +68 -0
- package/node_modules/pi-lens/dist/clients/project-changes.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +4 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +28 -4
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +51 -20
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +438 -122
- package/node_modules/pi-lens/dist/clients/project-scan-policy.js +3 -51
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +52 -24
- package/node_modules/pi-lens/dist/clients/python-environment.js +217 -0
- package/node_modules/pi-lens/dist/clients/python-provenance.js +639 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +6 -1
- package/node_modules/pi-lens/dist/clients/read-bridge.js +13 -21
- package/node_modules/pi-lens/dist/clients/read-expansion.js +9 -46
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +16 -5
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +364 -212
- package/node_modules/pi-lens/dist/clients/read-guard.js +26 -2
- package/node_modules/pi-lens/dist/clients/recent-touches.js +2 -2
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +195 -96
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +155 -114
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +1 -1
- package/node_modules/pi-lens/dist/clients/review-graph/service.js +55 -3
- package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +7 -15
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +10 -74
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +9 -3
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +19 -3
- package/node_modules/pi-lens/dist/clients/runtime-context.js +49 -16
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +25 -6
- package/node_modules/pi-lens/dist/clients/runtime-session.js +184 -32
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +179 -36
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +797 -243
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +1028 -53
- package/node_modules/pi-lens/dist/clients/rust-client.js +31 -0
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +33 -10
- package/node_modules/pi-lens/dist/clients/sanitize.js +7 -12
- package/node_modules/pi-lens/dist/clients/scan-utils.js +1 -56
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +1 -3
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +3 -0
- package/node_modules/pi-lens/dist/clients/session-lifecycle.js +1 -1
- package/node_modules/pi-lens/dist/clients/session-start-observability.js +79 -0
- package/node_modules/pi-lens/dist/clients/session-summary.js +0 -24
- package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +12 -3
- package/node_modules/pi-lens/dist/clients/sgconfig.js +7 -6
- package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +1 -1
- package/node_modules/pi-lens/dist/clients/skills-resolver.js +105 -0
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +4 -4
- package/node_modules/pi-lens/dist/clients/startup-scan.js +2 -10
- package/node_modules/pi-lens/dist/clients/string-utils.js +13 -0
- package/node_modules/pi-lens/dist/clients/subagent-mode.js +17 -4
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +176 -39
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +244 -0
- package/node_modules/pi-lens/dist/clients/tool-definition.js +41 -1
- package/node_modules/pi-lens/dist/clients/tool-policy.js +92 -22
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +40 -40
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +87 -100
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +81 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +51 -46
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +28 -0
- package/node_modules/pi-lens/dist/clients/tui-fit.js +0 -4
- package/node_modules/pi-lens/dist/clients/typos-config.js +5 -0
- package/node_modules/pi-lens/dist/clients/user-notify.js +6 -6
- package/node_modules/pi-lens/dist/clients/widget-state.js +191 -26
- package/node_modules/pi-lens/dist/clients/word-index-logger.js +2 -9
- package/node_modules/pi-lens/dist/clients/word-index-store.js +23 -12
- package/node_modules/pi-lens/dist/clients/word-index.js +252 -47
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -1
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +4 -1
- package/node_modules/pi-lens/dist/index.js +65899 -55340
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -1
- package/node_modules/pi-lens/dist/mcp/build-staleness.js +1 -1
- package/node_modules/pi-lens/dist/mcp/server.js +127 -5
- package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +583 -0
- package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +129 -0
- package/node_modules/pi-lens/dist/tools/effective-config.js +89 -0
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +96 -25
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +104 -86
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +37 -16
- package/node_modules/pi-lens/dist/tools/lsp-structured-output.js +3 -3
- package/node_modules/pi-lens/dist/tools/render-compact.js +1 -1
- package/node_modules/pi-lens/dist/tools/shared.js +0 -1
- package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -2
- package/node_modules/pi-lens/docs/agent-guide.md +64 -1
- package/node_modules/pi-lens/docs/configuration.md +222 -0
- package/node_modules/pi-lens/docs/dependencies.md +3 -3
- package/node_modules/pi-lens/docs/features.md +44 -5
- package/node_modules/pi-lens/docs/globalconfig.md +20 -0
- package/node_modules/pi-lens/docs/language-coverage.md +2 -2
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +9 -1
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +25 -0
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +25 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +33 -0
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +49 -0
- package/node_modules/pi-lens/docs/pi-lens-warden.md +55 -0
- package/node_modules/pi-lens/docs/public-api-stability.md +359 -0
- package/node_modules/pi-lens/docs/release-qa-baseline.md +190 -0
- package/node_modules/pi-lens/docs/servercapabilities.md +7 -3
- package/node_modules/pi-lens/docs/subagent-compat.md +110 -30
- package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +2 -2
- package/node_modules/pi-lens/docs/word-index.md +1 -1
- package/node_modules/pi-lens/package.json +18 -35
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
- package/node_modules/pi-lens/rules/typos/_typos.toml +4 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +192 -1
- package/node_modules/pi-lens/scripts/install-selftest.mjs +58 -2
- package/node_modules/pi-lens/scripts/lib/skills-predicate.mjs +129 -0
- package/node_modules/pi-lens/scripts/lib/warm-loader-cache.mjs +1 -1
- package/node_modules/pi-lens/scripts/rpc-load-check.mjs +3 -1
- package/node_modules/pi-lens/scripts/warm-loader-cache.mjs +4 -2
- package/node_modules/pi-web-access/CHANGELOG.md +28 -0
- package/node_modules/pi-web-access/README.md +62 -15
- package/node_modules/pi-web-access/curator-page.ts +3 -1
- package/node_modules/pi-web-access/curator-server.ts +5 -1
- package/node_modules/pi-web-access/gemini-search.ts +8 -4
- package/node_modules/pi-web-access/github-extract.ts +242 -1
- package/node_modules/pi-web-access/index.ts +118 -64
- package/node_modules/pi-web-access/mistral-search.ts +281 -0
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/perplexity.ts +14 -1
- package/node_modules/pi-web-access/utils.ts +23 -6
- package/node_modules/pi-web-access/xai-search.ts +96 -33
- package/package.json +6 -6
|
@@ -1,30 +1,73 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Small insertion-ordered FIFO map used for process-lifetime memo tables
|
|
3
|
+
* whose eviction order must not be perturbed by reads: `get` never
|
|
4
|
+
* re-inserts, and `set` never reorders an already-present key — it behaves
|
|
5
|
+
* exactly like native `Map#set` on an existing key. A caller that wants a
|
|
6
|
+
* WRITE (not a read) to refresh recency does its own `delete` + `set` around
|
|
7
|
+
* this map, exactly as it would against a raw `Map` (#2442).
|
|
8
|
+
*
|
|
9
|
+
* {@link BoundedLruCache} extends this class and overrides exactly the two
|
|
10
|
+
* methods that differ (`get` re-inserts; `set` deletes first so a write moves
|
|
11
|
+
* the key to most-recently-used). Eviction, capacity and the whole `Map`-ish
|
|
12
|
+
* surface live here once — the two classes shipped as near-identical copies
|
|
13
|
+
* until #2442's review round flagged the duplication.
|
|
14
|
+
*/
|
|
15
|
+
export class BoundedFifoMap {
|
|
4
16
|
entries = new Map();
|
|
17
|
+
maxEntries;
|
|
5
18
|
constructor(maxEntries) {
|
|
6
19
|
this.maxEntries = maxEntries;
|
|
7
20
|
}
|
|
8
21
|
get(key) {
|
|
9
|
-
|
|
10
|
-
if (value !== undefined) {
|
|
11
|
-
this.entries.delete(key);
|
|
12
|
-
this.entries.set(key, value);
|
|
13
|
-
}
|
|
14
|
-
return value;
|
|
22
|
+
return this.entries.get(key);
|
|
15
23
|
}
|
|
16
24
|
has(key) {
|
|
17
25
|
return this.entries.has(key);
|
|
18
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Insert or update `key` without reordering. Evicts the oldest
|
|
29
|
+
* (insertion-order) entries once the map exceeds capacity.
|
|
30
|
+
*
|
|
31
|
+
* Returns the evicted `[key, value]` pairs, oldest first — callers with
|
|
32
|
+
* eviction-side bookkeeping use the return value instead of hand-rolling
|
|
33
|
+
* `keys().next().value` (#2442). The VALUE is returned, not just the key,
|
|
34
|
+
* because the eviction-coupled sites need it: `tree-sitter-cache.ts` has to
|
|
35
|
+
* retire the dropped entry's WASM-heap tree (#417/#890) and
|
|
36
|
+
* `tree-sitter-client.ts` has to `delete()` the dropped compiled query.
|
|
37
|
+
* Handing back only the key would force those sites to read the value out
|
|
38
|
+
* of the map before eviction — i.e. to hand-roll the block this class
|
|
39
|
+
* exists to delete.
|
|
40
|
+
*/
|
|
19
41
|
set(key, value) {
|
|
20
|
-
this.entries.delete(key);
|
|
21
42
|
this.entries.set(key, value);
|
|
43
|
+
return this.evictOverflow();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Change the capacity ceiling, evicting down to it immediately when it
|
|
47
|
+
* shrinks. Returns the evicted `[key, value]` pairs, oldest first, on the
|
|
48
|
+
* same contract as {@link set} — a caller with a DYNAMIC cap (an env-read
|
|
49
|
+
* ceiling, `TreeCache.setMaxSize`) needs the shrink to free the same
|
|
50
|
+
* resources an ordinary overflow frees.
|
|
51
|
+
*/
|
|
52
|
+
setMaxEntries(maxEntries) {
|
|
53
|
+
this.maxEntries = maxEntries;
|
|
54
|
+
return this.evictOverflow();
|
|
55
|
+
}
|
|
56
|
+
/** Current capacity ceiling. */
|
|
57
|
+
getMaxEntries() {
|
|
58
|
+
return this.maxEntries;
|
|
59
|
+
}
|
|
60
|
+
/** Drop oldest-first until within capacity. The one eviction block. */
|
|
61
|
+
evictOverflow() {
|
|
62
|
+
const evicted = [];
|
|
22
63
|
while (this.entries.size > this.maxEntries) {
|
|
23
|
-
const oldest = this.entries.
|
|
64
|
+
const oldest = this.entries.entries().next().value;
|
|
24
65
|
if (oldest === undefined)
|
|
25
66
|
break;
|
|
26
|
-
this.entries.delete(oldest);
|
|
67
|
+
this.entries.delete(oldest[0]);
|
|
68
|
+
evicted.push(oldest);
|
|
27
69
|
}
|
|
70
|
+
return evicted;
|
|
28
71
|
}
|
|
29
72
|
delete(key) {
|
|
30
73
|
return this.entries.delete(key);
|
|
@@ -48,3 +91,100 @@ export class BoundedLruCache {
|
|
|
48
91
|
return this.entries[Symbol.iterator]();
|
|
49
92
|
}
|
|
50
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Small insertion-ordered FIFO SET used for process-lifetime membership-only
|
|
96
|
+
* caps — "is this key known", with no associated value.
|
|
97
|
+
*
|
|
98
|
+
* A thin wrapper over `BoundedFifoMap<T, true>` (#2460 review T1): eviction,
|
|
99
|
+
* capacity and the whole Map-ish surface already live in `BoundedFifoMap`
|
|
100
|
+
* exactly once, and this class's earlier standalone `Set`-backed
|
|
101
|
+
* implementation was a byte-for-byte copy of that eviction block one layer
|
|
102
|
+
* down — the exact duplication `BoundedFifoMap`'s own header describes
|
|
103
|
+
* `BoundedLruCache` existing to delete (#2442). The `true` dummy value never
|
|
104
|
+
* escapes this wrapper: it is not a cost paid by call sites, only by this
|
|
105
|
+
* file, so the earlier objection to building membership on top of the K,V
|
|
106
|
+
* map (#2460's first review, about `clients/observed-mutation.ts`'s
|
|
107
|
+
* `handled` set) does not apply here — that objection was about a caller
|
|
108
|
+
* storing a dummy value itself, not about a wrapper hiding one.
|
|
109
|
+
*
|
|
110
|
+
* Same eviction contract as {@link BoundedFifoMap}: `add` never reorders an
|
|
111
|
+
* already-present member (matches native `Set#add`), and both `add` and
|
|
112
|
+
* {@link setMaxEntries} return the evicted values, oldest first, so a call
|
|
113
|
+
* site with an eviction side effect (naming the dropped identity in a bounded
|
|
114
|
+
* telemetry record) consumes the return value instead of hand-rolling
|
|
115
|
+
* `values().next().value` or a `for (... of set) { …; break }` walk (#2442).
|
|
116
|
+
*/
|
|
117
|
+
export class BoundedSet {
|
|
118
|
+
entries;
|
|
119
|
+
constructor(maxEntries) {
|
|
120
|
+
this.entries = new BoundedFifoMap(maxEntries);
|
|
121
|
+
}
|
|
122
|
+
has(value) {
|
|
123
|
+
return this.entries.has(value);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Insert `value` without reordering an already-present member. Evicts the
|
|
127
|
+
* oldest (insertion-order) members once the set exceeds capacity.
|
|
128
|
+
*
|
|
129
|
+
* Returns the evicted values, oldest first — see the class doc for why a
|
|
130
|
+
* call site consumes this instead of hand-rolling the drop.
|
|
131
|
+
*/
|
|
132
|
+
add(value) {
|
|
133
|
+
return this.entries.set(value, true).map(([evicted]) => evicted);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Change the capacity ceiling, evicting down to it immediately when it
|
|
137
|
+
* shrinks. Returns the evicted values, oldest first, on the same contract
|
|
138
|
+
* as {@link add}.
|
|
139
|
+
*/
|
|
140
|
+
setMaxEntries(maxEntries) {
|
|
141
|
+
return this.entries.setMaxEntries(maxEntries).map(([evicted]) => evicted);
|
|
142
|
+
}
|
|
143
|
+
/** Current capacity ceiling. */
|
|
144
|
+
getMaxEntries() {
|
|
145
|
+
return this.entries.getMaxEntries();
|
|
146
|
+
}
|
|
147
|
+
delete(value) {
|
|
148
|
+
return this.entries.delete(value);
|
|
149
|
+
}
|
|
150
|
+
clear() {
|
|
151
|
+
this.entries.clear();
|
|
152
|
+
}
|
|
153
|
+
get size() {
|
|
154
|
+
return this.entries.size;
|
|
155
|
+
}
|
|
156
|
+
values() {
|
|
157
|
+
return this.entries.keys();
|
|
158
|
+
}
|
|
159
|
+
[Symbol.iterator]() {
|
|
160
|
+
return this.entries.keys();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Small insertion-ordered LRU used for process-lifetime memo tables. Same
|
|
165
|
+
* bounded-`Map` surface as {@link BoundedFifoMap}; the only two differences
|
|
166
|
+
* are overridden below.
|
|
167
|
+
*/
|
|
168
|
+
export class BoundedLruCache extends BoundedFifoMap {
|
|
169
|
+
/**
|
|
170
|
+
* Read and promote to most-recently-used.
|
|
171
|
+
*
|
|
172
|
+
* A stored `undefined` value is NOT promoted — the hit is indistinguishable
|
|
173
|
+
* from a miss on this signature, and pre-#2442 `BoundedLruCache` behaved
|
|
174
|
+
* the same way. No caller stores `undefined`; the note exists so a future
|
|
175
|
+
* one does not assume otherwise.
|
|
176
|
+
*/
|
|
177
|
+
get(key) {
|
|
178
|
+
const value = this.entries.get(key);
|
|
179
|
+
if (value !== undefined) {
|
|
180
|
+
this.entries.delete(key);
|
|
181
|
+
this.entries.set(key, value);
|
|
182
|
+
}
|
|
183
|
+
return value;
|
|
184
|
+
}
|
|
185
|
+
/** Insert or update `key`, moving it to the most-recently-used position. */
|
|
186
|
+
set(key, value) {
|
|
187
|
+
this.entries.delete(key);
|
|
188
|
+
return super.set(key, value);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -194,7 +194,7 @@ export function acquireBoundedPidFileLock(lockPath, options) {
|
|
|
194
194
|
options.logContention();
|
|
195
195
|
return null;
|
|
196
196
|
}
|
|
197
|
-
throw new Error(options.timeoutMessage);
|
|
197
|
+
throw new Error(options.timeoutMessage, { cause: error });
|
|
198
198
|
}
|
|
199
199
|
Atomics.wait(waitArray, 0, 0, options.retryMs);
|
|
200
200
|
}
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
* get the bounding right. This module is the intersection of those four, not
|
|
11
11
|
* a speculative framework. Three of its four options come straight from those
|
|
12
12
|
* sites. The fourth, `capPerTurn`, expresses #1733's per-turn bound
|
|
13
|
-
* structurally
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* structurally and now caps re-raised auxiliary coverage-gap detail rows
|
|
14
|
+
* (#2356), while the aggregate count and ledger retain bounded latest
|
|
15
|
+
* identities plus the dropped count.
|
|
16
16
|
*
|
|
17
17
|
* Three rules the helper makes structural instead of prose:
|
|
18
18
|
*
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
* stated reason for staying raw.
|
|
39
39
|
*
|
|
40
40
|
* Nothing here ever throws. Telemetry must not perturb the path it observes —
|
|
41
|
-
*
|
|
41
|
+
* each caller has already decided its outcome before
|
|
42
42
|
* calling in.
|
|
43
43
|
*/
|
|
44
44
|
import { incrementDegradationCount } from "./degradation-ledger.js";
|
|
@@ -50,6 +50,13 @@ import { logLatency } from "./latency-logger.js";
|
|
|
50
50
|
* must not also be written by a raw `logLatency` call somewhere else.
|
|
51
51
|
*/
|
|
52
52
|
export const BOUNDED_TELEMETRY_PHASES = [
|
|
53
|
+
/**
|
|
54
|
+
* #2467: a demand for the analyzer bootstrap clients was not served and
|
|
55
|
+
* the caller proceeded without them. Rising-edge per demand reason, with
|
|
56
|
+
* the ledger holding the exact count — a wedged or missing analyzer graph
|
|
57
|
+
* must not turn every tool call into a log line.
|
|
58
|
+
*/
|
|
59
|
+
"bootstrap_clients_unavailable",
|
|
53
60
|
/** #1705: a deferred-format record whose origin worktree never claimed it. */
|
|
54
61
|
"agent_end_deferred_format_orphan_origin_mismatch",
|
|
55
62
|
/** #1713: a `textDocument`/`workspace` diagnostic pull abandoned at budget. */
|
|
@@ -92,6 +99,8 @@ export const BOUNDED_TELEMETRY_PHASES = [
|
|
|
92
99
|
* the state cap. Selection checks and detailed rows are both capped per turn.
|
|
93
100
|
*/
|
|
94
101
|
"test_runner_failed_target_state",
|
|
102
|
+
/** #2366: bounded lifecycle records for automatic test-result delivery. */
|
|
103
|
+
"test_runner_delivery",
|
|
95
104
|
/**
|
|
96
105
|
* #1723: an event-loop block at or above the floor. Not a degradation, so
|
|
97
106
|
* no ledger kind; bounded by call cadence (one `turn_end` runs it once per
|
|
@@ -115,12 +124,53 @@ export const BOUNDED_TELEMETRY_PHASES = [
|
|
|
115
124
|
* command was declined on an UNKNOWN rather than assumed clean.
|
|
116
125
|
*/
|
|
117
126
|
"shared_checkout_probe_failed",
|
|
127
|
+
/** #2356: a notify-stall auxiliary remained uncovered after its bounded
|
|
128
|
+
* replacement window. Detailed rows are capped per turn; the ledger and
|
|
129
|
+
* aggregate turn-end row retain the complete count and identity. */
|
|
130
|
+
"lsp_scanner_coverage_gap",
|
|
131
|
+
/** #2358: a busy CPU discriminator deferred notify-stall teardown. */
|
|
132
|
+
"lsp_notify_stall_cpu_busy",
|
|
133
|
+
/**
|
|
134
|
+
* #2430: an observational pre/post snapshot was declined or cut short — the
|
|
135
|
+
* per-turn budget was already spent, the capture timed out, or the turn was
|
|
136
|
+
* aborted. Every unclassified tool call in a busy turn can reach this, so
|
|
137
|
+
* it is capped per turn with the ledger holding the exact count.
|
|
138
|
+
*/
|
|
139
|
+
"observed_mutation_budget_exhausted",
|
|
140
|
+
/**
|
|
141
|
+
* #2430: the `agent_settled` tracked-file sweep could not complete within
|
|
142
|
+
* its bound. Once per settle at most, capped for the same reason.
|
|
143
|
+
*/
|
|
144
|
+
"observed_sweep_skipped_budget",
|
|
145
|
+
/**
|
|
146
|
+
* #2430: a tracked file's size/mtime moved but no hashed baseline could
|
|
147
|
+
* confirm the bytes actually changed — too large for the sweep's read
|
|
148
|
+
* budget, or never hashed. Named rather than replayed, because a `touch`
|
|
149
|
+
* moves mtime without moving a byte (#2449 review round 2, F7). Bounded
|
|
150
|
+
* per turn: one settle can find many such files at once.
|
|
151
|
+
*/
|
|
152
|
+
"observed_sweep_unverifiable",
|
|
153
|
+
/**
|
|
154
|
+
* #2430: an armed observation's universe was TRUNCATED because the tool
|
|
155
|
+
* named a directory with more entries than the net may watch. Bounded per
|
|
156
|
+
* turn with the ledger holding the exact count, and the identity is the
|
|
157
|
+
* tool name so the record answers WHICH tool is being watched partially
|
|
158
|
+
* (#2449 review round 3).
|
|
159
|
+
*/
|
|
160
|
+
"observed_target_dir_capped",
|
|
161
|
+
/**
|
|
162
|
+
* #2430: the "pi-lens wrote these bytes itself" set hit
|
|
163
|
+
* `OBSERVED_HANDLED_MAX` and dropped its oldest entry. The dropped file is
|
|
164
|
+
* NAMED, because the eviction silently reintroduces the exact defect
|
|
165
|
+
* #2449 round 3 (S5) fixed: the ledger still holds the pre-drain bytes
|
|
166
|
+
* while the only record that those bytes were ours is gone, so the next
|
|
167
|
+
* settled sweep replays pi-lens's own formatter output as third-party
|
|
168
|
+
* drift. A cap that drops a mark has to say which one (catalog shape 10);
|
|
169
|
+
* capped per turn because a turn that overflows the set overflows it many
|
|
170
|
+
* times (#2449 review round 4, S2).
|
|
171
|
+
*/
|
|
172
|
+
"observed_handled_evicted",
|
|
118
173
|
];
|
|
119
|
-
const REGISTERED_PHASES = new Set(BOUNDED_TELEMETRY_PHASES);
|
|
120
|
-
/** Report whether a phase name is in the registry (used by the sweep). */
|
|
121
|
-
export function isBoundedTelemetryPhase(phase) {
|
|
122
|
-
return REGISTERED_PHASES.has(phase);
|
|
123
|
-
}
|
|
124
174
|
/**
|
|
125
175
|
* Per-turn admission counters, keyed by turn and phase. Multiple turns remain
|
|
126
176
|
* live because async work can finish T1 after T2 has already emitted. The map
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared health classification + degradation reporting for a bundled
|
|
3
|
+
* resource directory read DIRECTLY by pi-lens (never handed to an external
|
|
4
|
+
* spawned tool as a `--config`/`--rule-dir` argument — that class already
|
|
5
|
+
* fails loudly through the tool's own spawn-failure path).
|
|
6
|
+
*
|
|
7
|
+
* #2626 fixed this shape for `clients/skills-resolver.ts`'s `skills/`
|
|
8
|
+
* directory: `resolvePackagePath(import.meta.url, …)` walks up from the
|
|
9
|
+
* loaded entry file to the nearest `package.json`, which is correct for both
|
|
10
|
+
* the source and compiled `dist/` layouts, but goes wrong SILENTLY, not
|
|
11
|
+
* loudly, when that walk lands somewhere with no resource dir beside it —
|
|
12
|
+
* the bundled dir missing from an installed package, or the entry file
|
|
13
|
+
* copied out of the package tree by a managed extension cache so the
|
|
14
|
+
* nearest `package.json` is the cache's own. #2636 is the class sweep:
|
|
15
|
+
* `clients/ast-grep-client.ts`'s `rules` fallback and the bundled
|
|
16
|
+
* tree-sitter-queries root (read identically by `clients/cache/rule-cache.ts`
|
|
17
|
+
* and `clients/tree-sitter-query-loader.ts`) have the exact same gap.
|
|
18
|
+
*
|
|
19
|
+
* Both callers reuse this ONE classify+report pair rather than each
|
|
20
|
+
* hand-rolling the ENOENT/EACCES distinction (#2626 review F4) a second and
|
|
21
|
+
* third time.
|
|
22
|
+
*/
|
|
23
|
+
import * as fs from "node:fs";
|
|
24
|
+
import { incrementDegradationCount, } from "./degradation-ledger.js";
|
|
25
|
+
import { notifyUserDegradation } from "./user-notify.js";
|
|
26
|
+
/**
|
|
27
|
+
* Classify `dir`: does it exist, is it readable, and does it hold anything?
|
|
28
|
+
* Fail-closed and never throws. Distinguishes `ENOENT` (the common
|
|
29
|
+
* managed-cache-relocation case) from any OTHER `readdirSync` error
|
|
30
|
+
* (`EACCES` and friends) — an unreadable directory might genuinely hold a
|
|
31
|
+
* real resource pi-lens simply cannot read, so the honest report is "cannot
|
|
32
|
+
* read it", never "nothing is there" (#2626 review F4).
|
|
33
|
+
*
|
|
34
|
+
* `countEntries` lets a caller supply its OWN notion of "found" — e.g.
|
|
35
|
+
* `skills-resolver.ts` counts pi-loadable skill entry points via
|
|
36
|
+
* `scanEntriesForSkills`, not a bare directory listing — while still sharing
|
|
37
|
+
* this function's ENOENT/EACCES/empty classification shell (#2636 review F4:
|
|
38
|
+
* that shell was duplicated character-for-character between the two modules
|
|
39
|
+
* before this parameter existed). The default counts plain directory
|
|
40
|
+
* entries, which is what every OTHER caller (ast-grep's rules dir, the
|
|
41
|
+
* bundled tree-sitter-queries root) actually wants.
|
|
42
|
+
*/
|
|
43
|
+
export function classifyBundledResourceDir(dir, countEntries = (d) => fs.readdirSync(d).length) {
|
|
44
|
+
let entryCount;
|
|
45
|
+
try {
|
|
46
|
+
entryCount = countEntries(dir);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
const fsErrorCode = error?.code ?? "UNKNOWN";
|
|
50
|
+
if (fsErrorCode === "ENOENT")
|
|
51
|
+
return { status: "absent" };
|
|
52
|
+
return { status: "unreadable", fsErrorCode };
|
|
53
|
+
}
|
|
54
|
+
return entryCount > 0
|
|
55
|
+
? { status: "healthy", entryCount }
|
|
56
|
+
: { status: "empty" };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Render `health` as a reason string. `emptyDescription` lets a caller name
|
|
60
|
+
* what "nothing found" actually means for its own resource (skills' loader
|
|
61
|
+
* cares about `SKILL.md`, not bare directory entries); every other status's
|
|
62
|
+
* prose is shared verbatim, since ENOENT/EACCES mean the exact same thing
|
|
63
|
+
* regardless of which resource directory hit them.
|
|
64
|
+
*/
|
|
65
|
+
export function describeBundledResourceHealth(health, dir, emptyDescription = `${dir} exists but holds nothing`) {
|
|
66
|
+
switch (health.status) {
|
|
67
|
+
case "absent":
|
|
68
|
+
return `no such directory: ${dir}`;
|
|
69
|
+
case "unreadable":
|
|
70
|
+
return `cannot read ${dir} (${health.fsErrorCode})`;
|
|
71
|
+
case "empty":
|
|
72
|
+
return emptyDescription;
|
|
73
|
+
default:
|
|
74
|
+
// unreachable for the "healthy" case — callers only report unhealthy ones.
|
|
75
|
+
return `${dir}: unexpected health status`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Record ONE bounded `kind` degradation plus one `notifyUserDegradation`
|
|
80
|
+
* warning per (kind, dir) per session, when `health` is not healthy.
|
|
81
|
+
* Pure no-op when healthy. `incrementDegradationCount`'s own return value
|
|
82
|
+
* (not a hand-rolled Set) gates the notify to the rising edge, so a caller
|
|
83
|
+
* invoked on every dispatch (e.g. `RuleCache`'s constructor) can call this
|
|
84
|
+
* unconditionally without spamming the notify surface.
|
|
85
|
+
*
|
|
86
|
+
* `reasonOverride` lets a caller build a richer reason (skills-resolver.ts
|
|
87
|
+
* appends the entry file's directory) while still sharing the
|
|
88
|
+
* increment/notify mechanics below; the default is this module's own
|
|
89
|
+
* `describeBundledResourceHealth`.
|
|
90
|
+
*
|
|
91
|
+
* `notifyMessage` lets a caller replace the DEFAULT `pi-lens: <label>
|
|
92
|
+
* unavailable — <reason>.` sentence with its own finished wording (#2636
|
|
93
|
+
* review round 2, F1): `skills-resolver.ts`'s shipped notify text ("registers
|
|
94
|
+
* zero skills") is user-visible product text #2626 chose deliberately — the
|
|
95
|
+
* SYMPTOM the notification exists to surface — and folding onto this shared
|
|
96
|
+
* helper must never silently reword a string a maintainer already tuned.
|
|
97
|
+
*/
|
|
98
|
+
export function reportBundledResourceDirHealth(kind, dir, health, label, reasonOverride, notifyMessage) {
|
|
99
|
+
if (health.status === "healthy")
|
|
100
|
+
return;
|
|
101
|
+
const reason = reasonOverride ?? describeBundledResourceHealth(health, dir);
|
|
102
|
+
const isFirstOccurrence = incrementDegradationCount({
|
|
103
|
+
kind,
|
|
104
|
+
subject: dir,
|
|
105
|
+
reason,
|
|
106
|
+
metadata: health.status === "unreadable"
|
|
107
|
+
? { fsErrorCode: health.fsErrorCode }
|
|
108
|
+
: undefined,
|
|
109
|
+
});
|
|
110
|
+
if (isFirstOccurrence) {
|
|
111
|
+
notifyUserDegradation(notifyMessage ?? `pi-lens: ${label} unavailable — ${reason}.`, "warning");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -22,8 +22,7 @@
|
|
|
22
22
|
* This module gives bus events the same durable trace every other pi-lens
|
|
23
23
|
* subsystem already has (latency.log, cascade.log, read-guard.log, ...) —
|
|
24
24
|
* see clients/latency-logger.ts for the house pattern this mirrors exactly:
|
|
25
|
-
* one shared `createNdjsonLogger` writer, `isTestMode()` no-op guard
|
|
26
|
-
* `getBusEventsLogPath()` for testability.
|
|
25
|
+
* one shared `createNdjsonLogger` writer, `isTestMode()` no-op guard.
|
|
27
26
|
*
|
|
28
27
|
* Logging volume: `emitted` and `emit_failed` are logged on every call —
|
|
29
28
|
* they're the two outcomes an operator actually needs a per-event trace for.
|
|
@@ -44,11 +43,11 @@
|
|
|
44
43
|
*/
|
|
45
44
|
import * as path from "node:path";
|
|
46
45
|
import { isTestMode } from "./env-utils.js";
|
|
47
|
-
import {
|
|
46
|
+
import { getGlobalPiLensLogDir } from "./probe-home-state.js";
|
|
48
47
|
import { createNdjsonLogger } from "./ndjson-logger.js";
|
|
49
48
|
import { getMaxLogSizeMB } from "./log-cleanup.js";
|
|
50
49
|
import { logLatency } from "./latency-logger.js";
|
|
51
|
-
const BUS_EVENTS_LOG_FILE = path.join(
|
|
50
|
+
const BUS_EVENTS_LOG_FILE = path.join(getGlobalPiLensLogDir(), "bus-events.log");
|
|
52
51
|
const writer = createNdjsonLogger({
|
|
53
52
|
filePath: BUS_EVENTS_LOG_FILE,
|
|
54
53
|
maxBytes: getMaxLogSizeMB() * 1024 * 1024,
|
|
@@ -104,10 +103,3 @@ export function emitBusEventRollupAtSessionEnd(cwd) {
|
|
|
104
103
|
}
|
|
105
104
|
resetBusEventRollupCounts();
|
|
106
105
|
}
|
|
107
|
-
export function getBusEventsLogPath() {
|
|
108
|
-
return BUS_EVENTS_LOG_FILE;
|
|
109
|
-
}
|
|
110
|
-
/** Resolve once all enqueued bus-event writes are on disk (tests/shutdown). */
|
|
111
|
-
export function flushBusEventsLog() {
|
|
112
|
-
return writer.flush();
|
|
113
|
-
}
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
import * as crypto from "node:crypto";
|
|
8
8
|
import * as fs from "node:fs";
|
|
9
9
|
import * as path from "node:path";
|
|
10
|
+
import { reportBundledResourceDirHealth } from "../bundled-resource-health.js";
|
|
10
11
|
import { getProjectDataDir } from "../file-utils.js";
|
|
11
12
|
import { readJsonCache } from "../json-cache-read.js";
|
|
12
|
-
import {
|
|
13
|
+
import { BUNDLED_QUERIES_ROOT, getBundledQueriesRootHealth, } from "../tree-sitter-query-loader.js";
|
|
13
14
|
import { writeFileAtomic } from "../atomic-write.js";
|
|
14
15
|
import { compareOrdinal } from "../string-utils.js";
|
|
15
16
|
// v4: cache skip_test_files + fix_action — v3 entries silently dropped them,
|
|
@@ -48,11 +49,36 @@ export const CACHE_VERSION = "v7";
|
|
|
48
49
|
* on this prefix mirrors the split `yaml-rule-parser.ts`/`ast-grep-napi.ts`
|
|
49
50
|
* already use for the ast-grep side of the same class (#1105): project-origin
|
|
50
51
|
* trees get a content-hash CONFIRM, bundled trees stay mtime-cheap.
|
|
52
|
+
*
|
|
53
|
+
* #2636 review F4: re-exported from `tree-sitter-query-loader.ts`'s
|
|
54
|
+
* `BUNDLED_QUERIES_ROOT` rather than computed a second time here — the two
|
|
55
|
+
* modules read the IDENTICAL physical directory, and the "one ledger row"
|
|
56
|
+
* claim below rests on that being reference equality, not two independently
|
|
57
|
+
* `resolvePackagePath`-resolved strings that happen to match.
|
|
51
58
|
*/
|
|
52
|
-
|
|
59
|
+
export { BUNDLED_QUERIES_ROOT as BUNDLED_RULES_ROOT } from "../tree-sitter-query-loader.js";
|
|
53
60
|
function isBundledRuleFile(resolvedFile) {
|
|
54
|
-
return (resolvedFile ===
|
|
55
|
-
resolvedFile.startsWith(
|
|
61
|
+
return (resolvedFile === BUNDLED_QUERIES_ROOT ||
|
|
62
|
+
resolvedFile.startsWith(BUNDLED_QUERIES_ROOT + path.sep));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* #2636 (the #2626 class sweep's tree-sitter leg): the bundled
|
|
66
|
+
* tree-sitter-queries root above was used unconditionally with no existence
|
|
67
|
+
* check — same managed-cache-relocation gap #2626 fixed for `skills/`.
|
|
68
|
+
* Purely observational (never gates `isBundledRuleFile`'s classification):
|
|
69
|
+
* records a bounded `tree-sitter-queries-dir-missing` degradation only when
|
|
70
|
+
* the bundled root is absent, unreadable, or (uncommonly) present but empty.
|
|
71
|
+
* Shares the exact kind + subject `clients/tree-sitter-query-loader.ts`'s
|
|
72
|
+
* `ruleFilesForLanguage` reports under — both read the SAME physical
|
|
73
|
+
* directory (`getBundledQueriesRootHealth`'s process-lifetime memo, #2636
|
|
74
|
+
* review F6 — this constructor runs per dispatched file, so an unmemoized
|
|
75
|
+
* `readdirSync` here would be the same unconditional hot-path cost the
|
|
76
|
+
* class doc comment above forbids for rule-file hashing), so the ledger's
|
|
77
|
+
* own (kind, subject) dedup collapses whichever call site observes it first
|
|
78
|
+
* into ONE row rather than two duplicates.
|
|
79
|
+
*/
|
|
80
|
+
function reportBundledRulesRootHealth() {
|
|
81
|
+
reportBundledResourceDirHealth("tree-sitter-queries-dir-missing", BUNDLED_QUERIES_ROOT, getBundledQueriesRootHealth(), "bundled tree-sitter query rules");
|
|
56
82
|
}
|
|
57
83
|
export class RuleCache {
|
|
58
84
|
cacheFile;
|
|
@@ -60,6 +86,7 @@ export class RuleCache {
|
|
|
60
86
|
language;
|
|
61
87
|
constructor(language, rootDir = process.cwd()) {
|
|
62
88
|
this.language = language;
|
|
89
|
+
reportBundledRulesRootHealth();
|
|
63
90
|
this.cacheDir = path.join(getProjectDataDir(rootDir), "cache");
|
|
64
91
|
this.cacheFile = path.join(this.cacheDir, `${language}-rules-${CACHE_VERSION}.json`);
|
|
65
92
|
}
|