@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
|
@@ -14,8 +14,10 @@ import { isFileKind } from "./file-kinds.js";
|
|
|
14
14
|
import { getGlobalPiLensDir } from "./file-utils.js";
|
|
15
15
|
import { findGlobalBinary } from "./package-manager.js";
|
|
16
16
|
import { safeSpawnAsync } from "./safe-spawn.js";
|
|
17
|
+
import { probeToolAsync } from "./tool-probe.js";
|
|
17
18
|
import { createSingleFlight } from "./single-flight.js";
|
|
18
19
|
import { biomeConfigArgs } from "./tool-policy.js";
|
|
20
|
+
import { resolveToolCwd } from "./tool-cwd.js";
|
|
19
21
|
import { resolveManagedToolClient, } from "./dispatch/runners/utils/runner-helpers.js";
|
|
20
22
|
import { classifyProbeFailure, describeInstallAttempt, createAvailabilityLatch, logAvailabilityDecision, startHostStallSampler, } from "./dispatch/runners/utils/availability-policy.js";
|
|
21
23
|
// --- Client ---
|
|
@@ -169,7 +171,14 @@ export class BiomeClient {
|
|
|
169
171
|
let result;
|
|
170
172
|
let hostStallMs;
|
|
171
173
|
try {
|
|
172
|
-
|
|
174
|
+
// The presence probe asks whether biome answers at all, so it goes
|
|
175
|
+
// through the probe seam (no cwd) rather than through
|
|
176
|
+
// `spawnBiomeAsync`, whose optional `cwd` exists for the analysis
|
|
177
|
+
// spawns that DO resolve a project config (#2894).
|
|
178
|
+
const { cmd, args: prefix } = await this.getBiomeBinary();
|
|
179
|
+
result = await probeToolAsync(cmd, [...prefix, "--version"], {
|
|
180
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
181
|
+
});
|
|
173
182
|
}
|
|
174
183
|
finally {
|
|
175
184
|
hostStallMs = sampler.stop();
|
|
@@ -314,7 +323,9 @@ export class BiomeClient {
|
|
|
314
323
|
}
|
|
315
324
|
try {
|
|
316
325
|
const before = await fs.promises.readFile(absolutePath, "utf-8");
|
|
317
|
-
const configCwd =
|
|
326
|
+
const configCwd = resolveToolCwd("runner", "biome", absolutePath, {
|
|
327
|
+
...(cwd !== undefined && { cwd }),
|
|
328
|
+
});
|
|
318
329
|
// Shared config-args seam (#1247): the lint runner consumes the same
|
|
319
330
|
// builder, so `lint --write` can never drift to biome's default
|
|
320
331
|
// config when a user config or the package fallback exists.
|
|
@@ -167,12 +167,6 @@ async function resolveForwardImportsMemoized(cwd, filePath, resolveForwardImport
|
|
|
167
167
|
});
|
|
168
168
|
return imports;
|
|
169
169
|
}
|
|
170
|
-
/** Test-only: clear the extractor and import-resolution memos. */
|
|
171
|
-
export function _resetBlockerFreshnessForTests() {
|
|
172
|
-
extractorCache.clear();
|
|
173
|
-
importResolutionMemo.clear();
|
|
174
|
-
importResolutionMemoTurnIndex = undefined;
|
|
175
|
-
}
|
|
176
170
|
/**
|
|
177
171
|
* Production forward-import resolver. Parses `filePath` with its tree-sitter grammar
|
|
178
172
|
* and resolves every extracted import source to in-project files. Degrades to an
|
|
@@ -114,7 +114,7 @@ const bootstrapFlight = createSingleFlight();
|
|
|
114
114
|
* budget — it is the liveness bound AGENTS.md's both-bounds rule requires, so
|
|
115
115
|
* a wedged module evaluation cannot park a `tool_call` handler forever.
|
|
116
116
|
*/
|
|
117
|
-
|
|
117
|
+
const BOOTSTRAP_LOAD_TIMEOUT_MS = 10_000;
|
|
118
118
|
/**
|
|
119
119
|
* How many consecutive failed builds before the seam stops rebuilding.
|
|
120
120
|
*
|
|
@@ -129,7 +129,7 @@ export const BOOTSTRAP_LOAD_TIMEOUT_MS = 10_000;
|
|
|
129
129
|
* the demand fails OPEN immediately, and `session_start` re-arms the latch so
|
|
130
130
|
* a repaired environment is never locked out for the life of the process.
|
|
131
131
|
*/
|
|
132
|
-
|
|
132
|
+
const BOOTSTRAP_FAILURE_STRIKE_LIMIT = 3;
|
|
133
133
|
/**
|
|
134
134
|
* A stand-in for an analysis client whose module failed to load (an unresolved
|
|
135
135
|
* runtime dependency under a package-manager layout the resolver can't traverse
|
|
@@ -268,7 +268,7 @@ async function buildBootstrapClients() {
|
|
|
268
268
|
* {@link requestBootstrapClients} never says which on its own, so the reason
|
|
269
269
|
* travels in the bounded record and the ledger entry instead.
|
|
270
270
|
*/
|
|
271
|
-
|
|
271
|
+
const BOOTSTRAP_UNAVAILABLE_REASONS = [
|
|
272
272
|
"shutdown",
|
|
273
273
|
"timeout",
|
|
274
274
|
"aborted",
|
|
@@ -276,7 +276,7 @@ export const BOOTSTRAP_UNAVAILABLE_REASONS = [
|
|
|
276
276
|
"latched",
|
|
277
277
|
];
|
|
278
278
|
/** A demand that could not be served. Carries the discriminating reason. */
|
|
279
|
-
|
|
279
|
+
class BootstrapUnavailableError extends Error {
|
|
280
280
|
unavailableReason;
|
|
281
281
|
constructor(unavailableReason, message) {
|
|
282
282
|
super(message);
|
|
@@ -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
|
}
|
|
@@ -50,6 +50,8 @@ 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
|
+
/** #2890: a duplicate pi RPC session_start was admitted but suppressed. */
|
|
54
|
+
"session_start_duplicate_suppressed",
|
|
53
55
|
/**
|
|
54
56
|
* #2467: a demand for the analyzer bootstrap clients was not served and
|
|
55
57
|
* the caller proceeded without them. Rising-edge per demand reason, with
|
|
@@ -171,11 +173,6 @@ export const BOUNDED_TELEMETRY_PHASES = [
|
|
|
171
173
|
*/
|
|
172
174
|
"observed_handled_evicted",
|
|
173
175
|
];
|
|
174
|
-
const REGISTERED_PHASES = new Set(BOUNDED_TELEMETRY_PHASES);
|
|
175
|
-
/** Report whether a phase name is in the registry (used by the sweep). */
|
|
176
|
-
export function isBoundedTelemetryPhase(phase) {
|
|
177
|
-
return REGISTERED_PHASES.has(phase);
|
|
178
|
-
}
|
|
179
176
|
/**
|
|
180
177
|
* Per-turn admission counters, keyed by turn and phase. Multiple turns remain
|
|
181
178
|
* live because async work can finish T1 after T2 has already emitted. The map
|
|
@@ -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.
|
|
@@ -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
|
-
}
|
|
@@ -91,7 +91,7 @@ const CHARS_PER_ESTIMATED_TOKEN = 4;
|
|
|
91
91
|
*/
|
|
92
92
|
export const DEFAULT_PROVIDER_CACHE_TTL_MS = 60_000;
|
|
93
93
|
const _providerCacheTtl = lazyEnvNumber("PI_LENS_PROVIDER_CACHE_TTL_MS", DEFAULT_PROVIDER_CACHE_TTL_MS);
|
|
94
|
-
|
|
94
|
+
const getProviderCacheTtlMs = _providerCacheTtl.get;
|
|
95
95
|
export const _resetProviderCacheTtlForTests = _providerCacheTtl._resetForTests;
|
|
96
96
|
/**
|
|
97
97
|
* A turn counts as "anomalously low" when it reads back less than half of what
|
|
@@ -176,9 +176,50 @@ function newAttributionState() {
|
|
|
176
176
|
injectedCharsSinceLastUsage: 0,
|
|
177
177
|
newTranscriptCharsSinceLastUsage: 0,
|
|
178
178
|
attributionCharsCapped: false,
|
|
179
|
+
injectedBytes: emptyInjectedBytes(),
|
|
180
|
+
injectedFindingsRepeated: 0,
|
|
181
|
+
findingIdentities: new Set(),
|
|
182
|
+
findingIdentityCapRecorded: false,
|
|
183
|
+
turnEndAdvisoryBytes: 0,
|
|
184
|
+
toolResultBytes: 0,
|
|
185
|
+
toolResultsTruncated: 0,
|
|
179
186
|
summary: newCacheUsageSummary(),
|
|
180
187
|
};
|
|
181
188
|
}
|
|
189
|
+
const MAX_FINDING_IDENTITIES = 2_000;
|
|
190
|
+
function emptyInjectedBytes() {
|
|
191
|
+
return {
|
|
192
|
+
sessionGuidance: 0,
|
|
193
|
+
turnFindings: 0,
|
|
194
|
+
testFindings: 0,
|
|
195
|
+
agentNudge: 0,
|
|
196
|
+
turnEndAdvisory: 0,
|
|
197
|
+
other: 0,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function sourceKey(source) {
|
|
201
|
+
return {
|
|
202
|
+
"session-guidance": "sessionGuidance",
|
|
203
|
+
"turn-findings": "turnFindings",
|
|
204
|
+
"test-findings": "testFindings",
|
|
205
|
+
"agent-nudge": "agentNudge",
|
|
206
|
+
}[source];
|
|
207
|
+
}
|
|
208
|
+
/** Best-effort, language-neutral identity extraction from rendered findings. */
|
|
209
|
+
function findingIdentities(text) {
|
|
210
|
+
const out = [];
|
|
211
|
+
for (const line of text.split(/\r?\n/)) {
|
|
212
|
+
const location = line.match(/(?:^|\s)([^\s:]+):(\d+)(?::\d+)?/);
|
|
213
|
+
if (!location)
|
|
214
|
+
continue;
|
|
215
|
+
const rule = line.match(/(?:rule|code)\s*[:=]\s*([\w./-]+)/i)?.[1] ??
|
|
216
|
+
line.match(/\(([\w./-]+)\)\s*$/)?.[1] ??
|
|
217
|
+
line.match(/:\d+(?::\d+)?\s+([\w./-]+)/)?.[1];
|
|
218
|
+
if (rule)
|
|
219
|
+
out.push(`${location[1]}:${location[2]}:${rule}`);
|
|
220
|
+
}
|
|
221
|
+
return out;
|
|
222
|
+
}
|
|
182
223
|
/**
|
|
183
224
|
* Fetch (creating if absent) one session's attribution state, refreshing LRU
|
|
184
225
|
* recency and evicting the oldest entries past the cap — same bounding as
|
|
@@ -688,10 +729,37 @@ export function observeCacheContext(args) {
|
|
|
688
729
|
countsCapped: sliceSize.capped,
|
|
689
730
|
};
|
|
690
731
|
});
|
|
732
|
+
const state = attributionFor(attributionKey(args.sessionId, args.sessionRole));
|
|
733
|
+
for (const slice of injectionSlices) {
|
|
734
|
+
const key = sourceKey(slice.source);
|
|
735
|
+
const bytes = measureInjectedMessages(slice.messages).bytes;
|
|
736
|
+
state.injectedBytes[key] += bytes;
|
|
737
|
+
for (const message of slice.messages) {
|
|
738
|
+
for (const identity of findingIdentities(typeof message.content === "string" ? message.content : "")) {
|
|
739
|
+
if (state.findingIdentities.has(identity)) {
|
|
740
|
+
state.injectedFindingsRepeated += 1;
|
|
741
|
+
continue;
|
|
742
|
+
}
|
|
743
|
+
if (state.findingIdentities.size >= MAX_FINDING_IDENTITIES) {
|
|
744
|
+
if (!state.findingIdentityCapRecorded) {
|
|
745
|
+
state.findingIdentityCapRecorded = true;
|
|
746
|
+
logLatency({
|
|
747
|
+
type: "phase",
|
|
748
|
+
filePath: "<pi-lens>",
|
|
749
|
+
phase: "injected_finding_identity_cap",
|
|
750
|
+
durationMs: 0,
|
|
751
|
+
metadata: { cap: MAX_FINDING_IDENTITIES },
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
state.findingIdentities.add(identity);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
691
760
|
const messageCountCapped = existingMessages.length > MAX_REPORTED_MESSAGES ||
|
|
692
761
|
resultMessages.length > MAX_REPORTED_MESSAGES;
|
|
693
762
|
recordContextAttribution(attributionKey(args.sessionId, args.sessionRole), existingMessages, sizes);
|
|
694
|
-
const state = attributionFor(attributionKey(args.sessionId, args.sessionRole));
|
|
695
763
|
state.sequenceHashTruncatedSinceLastUsage ||=
|
|
696
764
|
beforeSequence.truncated ||
|
|
697
765
|
beforeSequence.contentTruncated ||
|
|
@@ -721,6 +789,10 @@ export function observeCacheContext(args) {
|
|
|
721
789
|
injectedMessageCountCapped: injectedMessages.length > MAX_REPORTED_MESSAGES,
|
|
722
790
|
injectedChars: sizes.chars,
|
|
723
791
|
injectedBytes: sizes.bytes,
|
|
792
|
+
injectedBytesBySource: Object.fromEntries(sourceBreakdown.map((entry) => [
|
|
793
|
+
sourceKey(entry.source),
|
|
794
|
+
entry.bytes,
|
|
795
|
+
])),
|
|
724
796
|
injectedEstimatedTokens: estimateTokens(sizes.chars),
|
|
725
797
|
injectedTokenBasis: "chars-per-token-4-estimate-not-provider-measured",
|
|
726
798
|
injectedCountsCapped: sizes.capped,
|
|
@@ -881,6 +953,13 @@ export function logCacheUsage(message, dbg, context) {
|
|
|
881
953
|
const injectedCharsSinceLastTurn = state.injectedCharsSinceLastUsage;
|
|
882
954
|
const newTranscriptCharsSinceLastTurn = state.newTranscriptCharsSinceLastUsage;
|
|
883
955
|
const attributionCharsCapped = state.attributionCharsCapped;
|
|
956
|
+
const injectedBytes = {
|
|
957
|
+
...state.injectedBytes,
|
|
958
|
+
turnEndAdvisory: state.turnEndAdvisoryBytes + state.injectedBytes.turnEndAdvisory,
|
|
959
|
+
};
|
|
960
|
+
const injectedFindingsRepeated = state.injectedFindingsRepeated;
|
|
961
|
+
const toolResultBytes = state.toolResultBytes;
|
|
962
|
+
const toolResultsTruncated = state.toolResultsTruncated;
|
|
884
963
|
// This record is the turn boundary: reset the per-turn accumulators and
|
|
885
964
|
// re-arm the prefix-break flag so the next verdict describes the NEXT gap.
|
|
886
965
|
state.lastUsageAtMs = nowMs;
|
|
@@ -898,6 +977,11 @@ export function logCacheUsage(message, dbg, context) {
|
|
|
898
977
|
state.injectedCharsSinceLastUsage = 0;
|
|
899
978
|
state.newTranscriptCharsSinceLastUsage = 0;
|
|
900
979
|
state.attributionCharsCapped = false;
|
|
980
|
+
state.injectedBytes = emptyInjectedBytes();
|
|
981
|
+
state.injectedFindingsRepeated = 0;
|
|
982
|
+
state.turnEndAdvisoryBytes = 0;
|
|
983
|
+
state.toolResultBytes = 0;
|
|
984
|
+
state.toolResultsTruncated = 0;
|
|
901
985
|
// Clear the request stamp too: the next turn measures from ITS request, and
|
|
902
986
|
// a turn whose `context` call pi-lens never saw must fall back rather than
|
|
903
987
|
// reuse this one.
|
|
@@ -939,6 +1023,13 @@ export function logCacheUsage(message, dbg, context) {
|
|
|
939
1023
|
injectedCharsSinceLastTurn,
|
|
940
1024
|
newTranscriptCharsSinceLastTurn,
|
|
941
1025
|
attributionCharsCapped,
|
|
1026
|
+
injectedBytes,
|
|
1027
|
+
injectedFindingsRepeated,
|
|
1028
|
+
// Delivered tool-result aggregation over the turn (#2800 item 7):
|
|
1029
|
+
// the sum of each delivered footer's bytes= figure and the count
|
|
1030
|
+
// of results whose bound fired.
|
|
1031
|
+
toolResultBytes,
|
|
1032
|
+
toolResultsTruncated,
|
|
942
1033
|
...(context
|
|
943
1034
|
? {
|
|
944
1035
|
// MessageEndEvent has no request/context id in the host API. These
|
|
@@ -1126,6 +1217,29 @@ export function clearCachePrefixSession(sessionId, sessionRole) {
|
|
|
1126
1217
|
// a stale gap baseline and a stale prefix-break flag.
|
|
1127
1218
|
attributionBySession.delete(key);
|
|
1128
1219
|
}
|
|
1220
|
+
/** Record the exact quiet-window summary content handed to pi.sendMessage. */
|
|
1221
|
+
export function recordTurnEndAdvisoryBytes(sessionId, bytes, sessionRole = "primary") {
|
|
1222
|
+
const state = attributionFor(attributionKey(sessionId, sessionRole));
|
|
1223
|
+
state.turnEndAdvisoryBytes = Math.min(MAX_INJECTED_BYTES, state.turnEndAdvisoryBytes + Math.max(0, bytes));
|
|
1224
|
+
}
|
|
1225
|
+
/**
|
|
1226
|
+
* Fold one delivered tool result into the per-turn aggregation the
|
|
1227
|
+
* `cache_usage` row reports as `toolResultBytes` / `toolResultsTruncated`
|
|
1228
|
+
* (#2800 item 7). `bytes` is the delivered payload's UTF-8 byte count as
|
|
1229
|
+
* stamped in the result's own footer, and `truncated` is the footer's
|
|
1230
|
+
* truncated flag. Called from each host adapter's delivery seam; the row is
|
|
1231
|
+
* emitted by `logCacheUsage`, which resets both figures at the turn boundary.
|
|
1232
|
+
* The byte sum saturates at the attribution bound so the row stays bounded.
|
|
1233
|
+
*/
|
|
1234
|
+
export function recordToolResultDelivery(args) {
|
|
1235
|
+
const state = attributionFor(attributionKey(args.sessionId, args.sessionRole));
|
|
1236
|
+
const bytes = Number.isFinite(args.bytes)
|
|
1237
|
+
? Math.max(0, Math.floor(args.bytes))
|
|
1238
|
+
: 0;
|
|
1239
|
+
state.toolResultBytes = Math.min(MAX_ATTRIBUTION_BYTES, state.toolResultBytes + bytes);
|
|
1240
|
+
if (args.truncated === true)
|
|
1241
|
+
state.toolResultsTruncated += 1;
|
|
1242
|
+
}
|
|
1129
1243
|
/**
|
|
1130
1244
|
* Emit one bounded session summary and retire its attribution state. The
|
|
1131
1245
|
* summary contains fixed-key counters only; it never serializes transcript or
|
|
@@ -1165,10 +1279,12 @@ export function resetCachePrefixObservation() {
|
|
|
1165
1279
|
prefixHashBySession.clear();
|
|
1166
1280
|
attributionBySession.clear();
|
|
1167
1281
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1282
|
+
export function resetCacheFindingIdentitiesSession(sessionId, sessionRole) {
|
|
1283
|
+
const state = attributionBySession.get(attributionKey(sessionId, sessionRole));
|
|
1284
|
+
if (!state)
|
|
1285
|
+
return;
|
|
1286
|
+
state.findingIdentities.clear();
|
|
1287
|
+
state.findingIdentityCapRecorded = false;
|
|
1172
1288
|
}
|
|
1173
1289
|
export function _attributionBySessionHasForTests(key) {
|
|
1174
1290
|
return attributionBySession.has(key);
|
|
@@ -177,7 +177,7 @@ export function parseTomlStringArray(content, key) {
|
|
|
177
177
|
* true`) never matches either — the literal key is immediately followed by
|
|
178
178
|
* `=`, not `.`.
|
|
179
179
|
*/
|
|
180
|
-
|
|
180
|
+
function parseTomlScalarString(content, key) {
|
|
181
181
|
if (content === undefined)
|
|
182
182
|
return undefined;
|
|
183
183
|
const match = content.match(new RegExp(`^[ \\t]*${key}[ \\t]*=[ \\t]*(?:"([^"]*)"|'([^']*)')`, "m"));
|
|
@@ -292,7 +292,7 @@ export function readCargoDependencyNames(content) {
|
|
|
292
292
|
* (`edition.workspace = true`) or the inline-table form
|
|
293
293
|
* (`edition = { workspace = true }`).
|
|
294
294
|
*/
|
|
295
|
-
|
|
295
|
+
function isTomlKeyWorkspaceInherited(content, key) {
|
|
296
296
|
if (content === undefined)
|
|
297
297
|
return false;
|
|
298
298
|
const dotted = new RegExp(`^[ \\t]*${key}\\.workspace[ \\t]*=[ \\t]*true`, "m");
|
|
@@ -29,10 +29,3 @@ export function logCascade(entry) {
|
|
|
29
29
|
filePath: normalizeLoggedPath(entry.filePath),
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
-
export function getCascadeLogPath() {
|
|
33
|
-
return CASCADE_LOG_FILE;
|
|
34
|
-
}
|
|
35
|
-
/** Resolve once all enqueued cascade writes are on disk (tests/shutdown). */
|
|
36
|
-
export function flushCascadeLog() {
|
|
37
|
-
return writer.flush();
|
|
38
|
-
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Shared plumbing for best-effort, fire-and-forget child-process spawns
|
|
3
3
|
* (shape 4 of the recurring-defect catalog in AGENTS.md: "a timer / promise /
|
|
4
4
|
* worker / child that outlives its one-shot settle"). Extracted from the
|
|
5
|
-
* orphan reaper's `unrefReaperChild
|
|
5
|
+
* orphan reaper's `unrefReaperChild` (#1153/#1160) into a
|
|
6
6
|
* shared, dependency-free module so every one-shot
|
|
7
7
|
* `spawn(..., { stdio: ["ignore","pipe",...] })` call site in the codebase —
|
|
8
8
|
* the reaper's enumeration/kill spawns AND the resource sampler's Windows
|
|
@@ -46,24 +46,6 @@ export function unrefChildAndPipes(child) {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
|
-
* Spawn a best-effort, fire-and-forget child, accumulate its full stdout, and
|
|
50
|
-
* resolve with the collected text (empty string on a synchronous spawn
|
|
51
|
-
* failure or an `error` event). Consolidates the spawn → unref →
|
|
52
|
-
* pipe-stdout → `close` plumbing shared by every one-shot OS-process-table
|
|
53
|
-
* query in the codebase — each caller supplies only its command/args/options
|
|
54
|
-
* and does its own output parse. The child + its stdio pipes are `unref`'d
|
|
55
|
-
* here (via `unrefChildAndPipes`) so a settled one-shot `pi --print` process
|
|
56
|
-
* can exit without waiting, and both the unref and the collect plumbing live
|
|
57
|
-
* in exactly ONE place rather than being re-derived at each spawn site.
|
|
58
|
-
* Never rejects — any failure resolves to `""`, which every caller's parse
|
|
59
|
-
* turns into an empty/absent result (the best-effort contract every caller
|
|
60
|
-
* here already has).
|
|
61
|
-
*/
|
|
62
|
-
export function spawnCollectStdout(command, args, options) {
|
|
63
|
-
return spawnCollectStdoutResult(command, args, options).then((result) => result.stdout);
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* `spawnCollectStdout` plus the reason the output is what it is. Same spawn,
|
|
67
49
|
* unref, collect, settle plumbing; the only additions are an optional hard
|
|
68
50
|
* timeout and a status discriminator. Never rejects.
|
|
69
51
|
*/
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { createSubsystemLogger } from "./extension-log.js";
|
|
14
14
|
import * as fs from "node:fs";
|
|
15
15
|
import * as path from "node:path";
|
|
16
|
+
import { calcCyclomaticComplexity } from "./dispatch/facts/function-facts.js";
|
|
16
17
|
import { firstChildOfType, withTreeSitterRoot, isComplexityLanguageId, isComplexitySupportedFile, resolveTreeSitterLanguage, walk, } from "./tree-sitter-shared.js";
|
|
17
18
|
// JS/TS/JSX share one grammar shape.
|
|
18
19
|
const JSTS = {
|
|
@@ -190,6 +191,9 @@ function isLogicalOp(node, nodes) {
|
|
|
190
191
|
}
|
|
191
192
|
/** Cyclomatic contribution of a subtree: decision points + logical operators. */
|
|
192
193
|
function subtreeCyclomatic(root, nodes) {
|
|
194
|
+
// Dispatch uses 1-based McCabe; this client exposes 0-based contributions (#2697).
|
|
195
|
+
if (nodes === JSTS)
|
|
196
|
+
return calcCyclomaticComplexity(root) - 1;
|
|
193
197
|
let cc = 0;
|
|
194
198
|
walk(root, (n) => {
|
|
195
199
|
if (nodes.decision.has(n.type))
|
|
@@ -438,6 +442,7 @@ export class ComplexityClient {
|
|
|
438
442
|
aiCommentPatterns: countAICommentPatterns(content),
|
|
439
443
|
singleUseFunctions: countSingleUseFunctions(functions),
|
|
440
444
|
tryCatchCount: countTryCatch(root, nodes),
|
|
445
|
+
functions,
|
|
441
446
|
};
|
|
442
447
|
}
|
|
443
448
|
aggregateFunctionStats(functions) {
|
|
@@ -31,17 +31,20 @@
|
|
|
31
31
|
* (`loadPiLensProjectConfig`) are now projections of one resolution. #2416
|
|
32
32
|
* brings the `lsp.servers.<id>` shape the schema currently only reserves.
|
|
33
33
|
*/
|
|
34
|
-
export {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
export { SOURCE_TIERS } from "./provenance.js";
|
|
35
|
+
// `merge()` itself is NOT re-exported. Its input type only PROMISES a
|
|
36
|
+
// post-`validate()` value; nothing in the language enforces that a caller
|
|
37
|
+
// who imports it directly honors the promise, and `merge()`'s own bounds are
|
|
38
|
+
// a narrow backstop, not a second validator (see `merge.ts`'s module doc).
|
|
39
|
+
// `resolveConfig` (re-exported at the bottom of this file, from `resolve.js`)
|
|
40
|
+
// is the one supported way in: it always validates
|
|
41
|
+
// every source before merging. `merge()` stays exported from `merge.ts`
|
|
42
|
+
// itself — marked `@internal` there — for this module's own use and for
|
|
43
|
+
// tests that probe it directly.
|
|
41
44
|
// `resolveConfig` and its types live in `./resolve.js` (#2426) so a caller can
|
|
42
45
|
// import the front door without also importing this barrel's width — in
|
|
43
46
|
// particular `process-spec.js` -> `project-trust.js`, which closed three
|
|
44
47
|
// import cycles once the config loaders (all downstream of `file-utils.ts`)
|
|
45
48
|
// started resolving through the core. The public surface is unchanged: this is
|
|
46
49
|
// still where the supported entry point is exported from.
|
|
47
|
-
export { resolveConfig
|
|
50
|
+
export { resolveConfig } from "./resolve.js";
|
|
@@ -36,7 +36,7 @@ import { compareKeys, isRepoTier, } from "./provenance.js";
|
|
|
36
36
|
/** Longest argv a spec may carry. A command line, not a file list. */
|
|
37
37
|
export const MAX_ARGV_ENTRIES = 128;
|
|
38
38
|
/** Total argv bytes a spec may carry. */
|
|
39
|
-
|
|
39
|
+
const MAX_ARGV_BYTES = 32 * 1024;
|
|
40
40
|
/** Most env entries a spec may carry. */
|
|
41
41
|
export const MAX_ENV_ENTRIES = 64;
|
|
42
42
|
/** Total env bytes (names plus values) a spec may carry. */
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Two orderings live here, and they are NOT the same ordering:
|
|
13
13
|
*
|
|
14
|
-
* - `
|
|
14
|
+
* - `SOURCE_TIERS` decides who wins a plain value. Later beats earlier, so a
|
|
15
15
|
* CLI flag beats a project file beats a global file beats a built-in default.
|
|
16
16
|
* - `TIER_CLASS` decides who may LIFT a deny. `deny.ts` builds monotonic deny
|
|
17
17
|
* precedence on this split, and nothing else re-derives it.
|
|
@@ -34,13 +34,6 @@ export const SOURCE_TIERS = [
|
|
|
34
34
|
"cli",
|
|
35
35
|
"host",
|
|
36
36
|
];
|
|
37
|
-
/**
|
|
38
|
-
* Value precedence, lowest first. A later tier's value replaces an earlier
|
|
39
|
-
* tier's value for the same leaf. `merge()` sorts its sources by this order
|
|
40
|
-
* rather than trusting caller order, so a caller that assembles sources in a
|
|
41
|
-
* different order cannot silently invert precedence.
|
|
42
|
-
*/
|
|
43
|
-
export const TIER_PRECEDENCE = SOURCE_TIERS;
|
|
44
37
|
/**
|
|
45
38
|
* Who each tier speaks for. THREE classes, not two (#2440 review finding F3).
|
|
46
39
|
*
|
|
@@ -79,7 +72,7 @@ export const TIER_CLASS = {
|
|
|
79
72
|
};
|
|
80
73
|
/** Numeric precedence of a tier. Higher wins. */
|
|
81
74
|
export function tierPrecedence(tier) {
|
|
82
|
-
return
|
|
75
|
+
return SOURCE_TIERS.indexOf(tier);
|
|
83
76
|
}
|
|
84
77
|
/** True for tiers whose content arrives with the checkout. */
|
|
85
78
|
export function isRepoTier(tier) {
|
|
@@ -101,7 +101,7 @@ export function jsonTypeName(value) {
|
|
|
101
101
|
* A list with no records cannot overflow, so this is the floor under an
|
|
102
102
|
* anchorless producer rather than a case production reaches.
|
|
103
103
|
*/
|
|
104
|
-
|
|
104
|
+
const UNANCHORED_RECORD_LABEL = "(config resolution)";
|
|
105
105
|
/**
|
|
106
106
|
* A bounded collector for one resolution.
|
|
107
107
|
*
|
|
@@ -21,8 +21,6 @@
|
|
|
21
21
|
*
|
|
22
22
|
* Pure accessors only. Nothing here reads a file, and nothing holds state.
|
|
23
23
|
*/
|
|
24
|
-
import { STABILITY_TIER_KEY } from "../config-diagnostic-codes.js";
|
|
25
|
-
export { STABILITY_TIER_KEY };
|
|
26
24
|
/** Narrows to the recursive domain type, not to `unknown`. */
|
|
27
25
|
export function isConfigObject(value) {
|
|
28
26
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -30,7 +28,7 @@ export function isConfigObject(value) {
|
|
|
30
28
|
// --- x-merge-strategy ---
|
|
31
29
|
/** The annotation key selecting how an array node combines across tiers. */
|
|
32
30
|
export const MERGE_STRATEGY_KEY = "x-merge-strategy";
|
|
33
|
-
|
|
31
|
+
const DEFAULT_MERGE_STRATEGY = "replace";
|
|
34
32
|
const KEYED_PREFIX = "keyed:";
|
|
35
33
|
export function isMergeStrategy(value) {
|
|
36
34
|
if (typeof value !== "string")
|
|
@@ -71,7 +69,7 @@ export const DENY_KEY = "x-deny";
|
|
|
71
69
|
* the field someone spelled differently, and silently claims one that merely
|
|
72
70
|
* looks the part. A schema says what it means.
|
|
73
71
|
*/
|
|
74
|
-
|
|
72
|
+
const DENY_POLICIES = ["boolean-false", "array-union"];
|
|
75
73
|
export function isDenyPolicy(value) {
|
|
76
74
|
return (typeof value === "string" &&
|
|
77
75
|
DENY_POLICIES.includes(value));
|
|
@@ -104,7 +102,7 @@ export function schemaType(node) {
|
|
|
104
102
|
* field while the merger replaced it whole, so the same schema typo produced
|
|
105
103
|
* two different merge semantics.
|
|
106
104
|
*/
|
|
107
|
-
|
|
105
|
+
const SCHEMA_TYPES = [
|
|
108
106
|
"object",
|
|
109
107
|
"array",
|
|
110
108
|
"string",
|
|
@@ -34,7 +34,7 @@ export const STABILITY_TIER_KEY = "x-stability";
|
|
|
34
34
|
* The closed tier vocabulary. `experimental` fields may change or be removed
|
|
35
35
|
* in a minor; `stable` fields are covered by the compatibility guarantee.
|
|
36
36
|
*/
|
|
37
|
-
|
|
37
|
+
const STABILITY_TIERS = ["experimental", "stable"];
|
|
38
38
|
export function isStabilityTier(value) {
|
|
39
39
|
return (typeof value === "string" &&
|
|
40
40
|
STABILITY_TIERS.includes(value));
|
|
@@ -171,6 +171,8 @@ export const CONFIG_DIAGNOSTIC_CODES = {
|
|
|
171
171
|
* suppressed" about a configuration that applied nothing at all.
|
|
172
172
|
*/
|
|
173
173
|
PILENS_CFG_0008: "config resolution failed; whole configuration ignored",
|
|
174
|
+
/** A tool key is unknown or names a required, non-disableable tool. */
|
|
175
|
+
PILENS_CFG_0009: "unknown or non-disableable tool config key ignored",
|
|
174
176
|
};
|
|
175
177
|
/** The shape every code in the namespace must match. */
|
|
176
178
|
export const CONFIG_DIAGNOSTIC_CODE_PATTERN = /^PILENS_CFG_\d{4}$/;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*
|
|
13
13
|
* builtin -> global -> project root -> nested-project -> env -> cli -> host
|
|
14
14
|
*
|
|
15
|
-
* It is `config-core`'s own `
|
|
15
|
+
* It is `config-core`'s own `SOURCE_TIERS`, not a second ordering: this
|
|
16
16
|
* module places files into tiers and the core sorts them. `docs/configuration.md`
|
|
17
17
|
* documents the same order once, and `tests/clients/config-resolve.test.ts`
|
|
18
18
|
* walks it.
|
|
@@ -151,7 +151,7 @@ function collectDocuments(dir, locations, tier, onReadError) {
|
|
|
151
151
|
* is `nested-project`, which is what makes "nearest wins, per field" fall out
|
|
152
152
|
* of the core's tier precedence instead of being re-implemented here.
|
|
153
153
|
*/
|
|
154
|
-
|
|
154
|
+
function collectPiLensConfigDocuments(options) {
|
|
155
155
|
const documents = [];
|
|
156
156
|
const { globalDir, onReadError } = options;
|
|
157
157
|
const globalConfigPath = canonicalGlobalFile(options);
|
|
@@ -408,7 +408,7 @@ function assignRaw(target, key, value) {
|
|
|
408
408
|
* half-migrated the file it was written in is the defect this whole change
|
|
409
409
|
* exists to remove.
|
|
410
410
|
*/
|
|
411
|
-
|
|
411
|
+
function configSources(documents) {
|
|
412
412
|
const sources = [];
|
|
413
413
|
for (const document of documents) {
|
|
414
414
|
const value = document.value;
|
|
@@ -576,7 +576,7 @@ function record(input) {
|
|
|
576
576
|
* duplicate notice about a config that failed to load is noise, while silence
|
|
577
577
|
* about it is the failure mode this module exists to prevent.
|
|
578
578
|
*/
|
|
579
|
-
|
|
579
|
+
function configRecordOwner(record) {
|
|
580
580
|
const key = record.canonicalKey ?? record.key;
|
|
581
581
|
if (key.length === 0)
|
|
582
582
|
return undefined;
|
|
@@ -740,8 +740,8 @@ export function reportPiLensConfigRecords(records) {
|
|
|
740
740
|
*/
|
|
741
741
|
export function ignoredRecordCollector(configPath, tier) {
|
|
742
742
|
const noted = [];
|
|
743
|
-
const note = (reason) => {
|
|
744
|
-
|
|
743
|
+
const note = (reason, code = "PILENS_CFG_0001") => {
|
|
744
|
+
let notedRecord = {
|
|
745
745
|
code: "PILENS_CFG_0001",
|
|
746
746
|
file: configPath,
|
|
747
747
|
key: "",
|
|
@@ -752,7 +752,10 @@ export function ignoredRecordCollector(configPath, tier) {
|
|
|
752
752
|
sourceText: reason.sourceText,
|
|
753
753
|
}),
|
|
754
754
|
tier,
|
|
755
|
-
}
|
|
755
|
+
};
|
|
756
|
+
if (code !== "PILENS_CFG_0001")
|
|
757
|
+
notedRecord.code = code;
|
|
758
|
+
noted.push(notedRecord);
|
|
756
759
|
};
|
|
757
760
|
return {
|
|
758
761
|
note,
|