@herbertgao/pi-extensions 2026.8.11 → 2026.8.13
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 +23 -10
- package/{node_modules/@herbertgao/pi-mermaid-open/LICENSE → THIRD_PARTY_NOTICES.md} +19 -1
- package/node_modules/@czottmann/pi-automode/CHANGELOG.md +15 -0
- package/node_modules/@czottmann/pi-automode/README.md +5 -3
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-001-permission-precedence-and-trust-boundaries.md +2 -0
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-002-global-config-in-extension-data-directory.md +60 -0
- package/node_modules/@czottmann/pi-automode/docs/adr/INDEX.md +1 -0
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +4 -4
- package/node_modules/@czottmann/pi-automode/docs/configuration.md +20 -4
- package/node_modules/@czottmann/pi-automode/docs/observability-logging.md +1 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/bash.ts +692 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +181 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +4 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +143 -36
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +103 -148
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +32 -6
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +344 -22
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode.ts +1 -0
- package/node_modules/@czottmann/pi-automode/package.json +4 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +4 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +21 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +19 -19
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +4 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +10 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +21 -15
- package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +11 -8
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +184 -106
- package/node_modules/@herbertgao/pi-subagents/src/cross-extension-rpc.ts +31 -11
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +9 -1
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +156 -31
- package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +17 -0
- package/node_modules/@herbertgao/pi-subagents/src/model-resolver.ts +14 -0
- package/node_modules/@herbertgao/pi-subagents/src/schedule.ts +8 -0
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +32 -1
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +17 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +23 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +259 -24
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@luxusai/pi-hindsight/CHANGELOG.md +376 -0
- package/node_modules/@luxusai/pi-hindsight/README.md +92 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/001-memory-lifecycle-and-scope.md +56 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/002-explicit-routing-strategy-seam.md +169 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/003-tui-memory-mode-vocabulary.md +107 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/004-lifeos-dual-bank-design.md +89 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/005-domain-banks-and-agent-first-surface.md +189 -0
- package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark.webp +0 -0
- package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark@2x.webp +0 -0
- package/node_modules/@luxusai/pi-hindsight/docs/coding-memory-evaluation.md +54 -0
- package/node_modules/@luxusai/pi-hindsight/docs/compatibility.md +75 -0
- package/node_modules/@luxusai/pi-hindsight/docs/hindsight-core-functions.md +300 -0
- package/node_modules/@luxusai/pi-hindsight/docs/mission-and-mental-model-quality.md +158 -0
- package/node_modules/@luxusai/pi-hindsight/docs/next-opt-out-design.md +164 -0
- package/node_modules/@luxusai/pi-hindsight/docs/risky-memory-modes.md +139 -0
- package/node_modules/@luxusai/pi-hindsight/docs/starter-mental-model-suggestions.md +74 -0
- package/node_modules/@luxusai/pi-hindsight/docs/surface-reference.md +261 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-operations.ts +151 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-selection.ts +18 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-settings-presenter.ts +46 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-templates.ts +383 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/banking.ts +240 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/knowledge-page-seed.ts +176 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/retain-strategies.ts +178 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client-retry.ts +41 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client.ts +386 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/fetch-compat.ts +39 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/timeout.ts +34 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-defaults.ts +140 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-model.ts +61 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-registry.ts +925 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-field-paths.ts +247 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-normalize.ts +547 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-writer.ts +480 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config.ts +182 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/setup-gate.ts +86 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-execute.ts +1010 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-parse.ts +175 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-plan.ts +425 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-presentation.ts +210 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-sessions.ts +817 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/index.ts +25 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/git-seed.ts +319 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-recall.ts +196 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-retain.ts +189 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-runtime.ts +65 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle.ts +260 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/mental-models.ts +244 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/observation-scopes.ts +59 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-cleanup.ts +82 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-visibility.ts +45 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall.ts +331 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-cursor.ts +354 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-job-builder.ts +66 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-receipts.ts +132 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain.ts +228 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-bank-template-operations.ts +74 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-config-operations.ts +16 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-control-operations.ts +648 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-diagnostics-operations.ts +105 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-identity.ts +68 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-service.ts +71 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-types.ts +13 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-recall-operations.ts +162 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-retain-operations.ts +131 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-scope.ts +104 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-session-operations.ts +37 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/operation-catalog.ts +893 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/reflect-presenter.ts +35 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/scope-migrate.ts +177 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/tools.ts +7 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/flush-presenter.ts +21 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/jsonl-queue-store.ts +112 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-delivery.ts +111 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-lock.ts +214 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-operations.ts +70 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue.ts +392 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/bank-template-presentation.ts +45 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/commands.ts +9 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/guided-setup.ts +860 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/prefill-input.ts +105 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-flow.ts +189 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-server-probe.ts +299 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-actions.ts +201 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-facts.ts +47 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-render.ts +239 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-types.ts +50 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui.ts +259 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/tool-presenters.ts +77 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/types.ts +534 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/diagnostics.ts +319 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/messages.ts +325 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/sanitize.ts +42 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-memory-meta.ts +244 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-operations.ts +56 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session.ts +50 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-fields.ts +167 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-health.ts +207 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status.ts +120 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/version.ts +8 -0
- package/node_modules/@luxusai/pi-hindsight/package.json +118 -0
- package/node_modules/@luxusai/pi-hindsight/skills/hindsight-memory-doctor/SKILL.md +75 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts +143 -46
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
- package/node_modules/@narumitw/pi-btw/package.json +6 -6
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +136 -22
- package/node_modules/{@herbertgao → @tifan}/pi-copy-response/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-copy-response/package.json +5 -15
- package/node_modules/{@herbertgao → @tifan}/pi-handoff/README.md +4 -6
- package/node_modules/@tifan/pi-handoff/package.json +43 -0
- package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/index.ts +1 -1
- package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/package.json +5 -15
- package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/README.md +5 -7
- package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/package.json +5 -19
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/README.md +4 -6
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/package.json +6 -16
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/src/index.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-recap/README.md +4 -6
- package/node_modules/@tifan/pi-recap/package.json +42 -0
- package/node_modules/{@herbertgao → @tifan}/pi-recap/src/models.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-rename/README.md +13 -8
- package/node_modules/@tifan/pi-rename/package.json +47 -0
- package/node_modules/@tifan/pi-rename/src/herdr-label.ts +4 -0
- package/node_modules/{@herbertgao → @tifan}/pi-rename/src/index.ts +4 -16
- package/node_modules/{@herbertgao → @tifan}/pi-rename/src/models.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/package.json +5 -15
- package/node_modules/pi-lens/CHANGELOG.md +96 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +14 -5
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +48 -18
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +16 -4
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +3 -1
- package/node_modules/pi-lens/dist/clients/biome-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +21 -8
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +24 -8
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +4 -3
- package/node_modules/pi-lens/dist/clients/cache-manager.js +6 -7
- package/node_modules/pi-lens/dist/clients/cache-observability.js +461 -66
- package/node_modules/pi-lens/dist/clients/call-graph.js +238 -63
- package/node_modules/pi-lens/dist/clients/codebase-model.js +13 -5
- package/node_modules/pi-lens/dist/clients/complexity-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -8
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +1 -2
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +3 -1
- package/node_modules/pi-lens/dist/clients/debug-heap.js +8 -1
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +1 -1
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +11 -7
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +39 -2
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +13 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -4
- package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +6 -2
- package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +31 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +5 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +10 -14
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +25 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +4 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +25 -10
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +28 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +212 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +8 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +10 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +23 -14
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +7 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +5 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +7 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +17 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +7 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +24 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +35 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/types.js +6 -1
- package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +6 -2
- package/node_modules/pi-lens/dist/clients/extension-log.js +5 -3
- package/node_modules/pi-lens/dist/clients/feature-hints.js +8 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +34 -129
- package/node_modules/pi-lens/dist/clients/file-utils.js +17 -1
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +57 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +144 -27
- package/node_modules/pi-lens/dist/clients/freshness.js +38 -0
- package/node_modules/pi-lens/dist/clients/git-guard.js +43 -13
- package/node_modules/pi-lens/dist/clients/go-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/grammar-source.js +1 -1
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +30 -4
- package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +1 -3
- package/node_modules/pi-lens/dist/clients/install-diagnostics.js +4 -2
- package/node_modules/pi-lens/dist/clients/installer/index.js +86 -77
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +5 -2
- package/node_modules/pi-lens/dist/clients/instance-registry.js +4 -2
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +6 -1
- package/node_modules/pi-lens/dist/clients/knip-client.js +29 -15
- package/node_modules/pi-lens/dist/clients/language-profile.js +4 -1
- package/node_modules/pi-lens/dist/clients/latency-logger.js +13 -2
- package/node_modules/pi-lens/dist/clients/lens-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/lens-map.js +8 -3
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/config.js +4 -6
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +119 -32
- package/node_modules/pi-lens/dist/clients/lsp/index.js +94 -35
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +4 -1
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +11 -3
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +152 -0
- package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -7
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +10 -2
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +9 -4
- package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -3
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +10 -20
- package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +1 -1
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +73 -7
- package/node_modules/pi-lens/dist/clients/metrics-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +8 -3
- package/node_modules/pi-lens/dist/clients/module-report-lsp.js +7 -1
- package/node_modules/pi-lens/dist/clients/module-report.js +14 -17
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +3 -5
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +220 -0
- package/node_modules/pi-lens/dist/clients/package-manager.js +6 -1
- package/node_modules/pi-lens/dist/clients/pipeline.js +57 -9
- package/node_modules/pi-lens/dist/clients/project-conventions.js +2 -8
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +10 -7
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +2 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +3 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +13 -9
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +3 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -2
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +12 -5
- package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +48 -0
- package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +15 -1
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +472 -66
- package/node_modules/pi-lens/dist/clients/read-expansion.js +12 -2
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +5 -4
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +5 -2
- package/node_modules/pi-lens/dist/clients/read-guard.js +1 -1
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +1 -1
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +6 -5
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +42 -17
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +8 -2
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +10 -1
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +2 -1
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +4 -2
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +2 -2
- package/node_modules/pi-lens/dist/clients/ruff-client.js +6 -5
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +63 -31
- package/node_modules/pi-lens/dist/clients/runtime-context.js +12 -4
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +83 -4
- package/node_modules/pi-lens/dist/clients/runtime-session.js +14 -0
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +59 -3
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +148 -34
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -6
- package/node_modules/pi-lens/dist/clients/rust-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +150 -11
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/session-summary.js +3 -1
- package/node_modules/pi-lens/dist/clients/sg-runner.js +1 -3
- package/node_modules/pi-lens/dist/clients/source-filter.js +10 -6
- package/node_modules/pi-lens/dist/clients/source-walker.js +1 -1
- package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +96 -0
- package/node_modules/pi-lens/dist/clients/startup-scan.js +4 -1
- package/node_modules/pi-lens/dist/clients/tool-definition.js +7 -0
- package/node_modules/pi-lens/dist/clients/tool-policy.js +26 -11
- package/node_modules/pi-lens/dist/clients/tool-render.js +2 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +10 -4
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +12 -5
- package/node_modules/pi-lens/dist/clients/warm-attach.js +12 -5
- package/node_modules/pi-lens/dist/clients/widget-state.js +27 -11
- package/node_modules/pi-lens/dist/clients/word-index.js +3 -1
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -2
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +9 -1
- package/node_modules/pi-lens/dist/i18n.js +13 -5
- package/node_modules/pi-lens/dist/index.js +10797 -8627
- package/node_modules/pi-lens/dist/mcp/server.js +3 -1
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +68 -12
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +21 -7
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +164 -35
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +24 -7
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +3 -1
- package/node_modules/pi-lens/dist/tools/module-report.js +1 -1
- package/node_modules/pi-lens/dist/tools/project-report.js +1 -1
- package/node_modules/pi-lens/dist/tools/symbol-search.js +5 -2
- package/node_modules/pi-lens/docs/durable-store-audit-1202.md +1 -1
- package/node_modules/pi-lens/docs/servercapabilities.md +1 -1
- package/node_modules/pi-lens/package.json +160 -156
- package/node_modules/pi-lens/rules/typos/_typos.toml +2 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +31 -13
- package/node_modules/pi-lens/scripts/download-grammars.js +9 -3
- package/node_modules/pi-lens/scripts/rpc-load-check.mjs +30 -9
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +47 -0
- package/node_modules/pi-mcp-adapter/README.md +42 -13
- package/node_modules/pi-mcp-adapter/commands.ts +4 -2
- package/node_modules/pi-mcp-adapter/config.ts +45 -5
- package/node_modules/pi-mcp-adapter/direct-tools.ts +103 -92
- package/node_modules/pi-mcp-adapter/dist/agent-dir.d.ts +10 -0
- package/node_modules/pi-mcp-adapter/dist/agent-dir.js +63 -0
- package/node_modules/pi-mcp-adapter/dist/agent-dir.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.d.ts +8 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js +356 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/config.d.ts +123 -0
- package/node_modules/pi-mcp-adapter/dist/config.js +1087 -0
- package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.d.ts +19 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +319 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.d.ts +2 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js +156 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.d.ts +1 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.js +15 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/types.d.ts +564 -0
- package/node_modules/pi-mcp-adapter/dist/types.js +287 -0
- package/node_modules/pi-mcp-adapter/dist/types.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.d.ts +6 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js +37 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.d.ts +104 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js +59 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.d.ts +4 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js +27 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/utils.d.ts +32 -0
- package/node_modules/pi-mcp-adapter/dist/utils.js +338 -0
- package/node_modules/pi-mcp-adapter/dist/utils.js.map +1 -0
- package/node_modules/pi-mcp-adapter/failure-backoff.ts +23 -0
- package/node_modules/pi-mcp-adapter/index.ts +204 -82
- package/node_modules/pi-mcp-adapter/init.ts +41 -30
- package/node_modules/pi-mcp-adapter/lifecycle.ts +16 -8
- package/node_modules/pi-mcp-adapter/mcp-code.ts +2 -0
- package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +66 -16
- package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +95 -7
- package/node_modules/pi-mcp-adapter/mcp-probe.ts +18 -4
- package/node_modules/pi-mcp-adapter/mcp-references.ts +368 -0
- package/node_modules/pi-mcp-adapter/mcp-status.ts +8 -19
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +20 -12
- package/node_modules/pi-mcp-adapter/namespace-tools.ts +276 -0
- package/node_modules/pi-mcp-adapter/package.json +24 -6
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +66 -10
- package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -0
- package/node_modules/pi-mcp-adapter/server-manager.ts +63 -12
- package/node_modules/pi-mcp-adapter/state.ts +1 -3
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +16 -2
- package/node_modules/pi-mcp-adapter/types.ts +48 -1
- package/node_modules/pi-mcp-adapter/ui-server.ts +3 -19
- package/node_modules/pi-mcp-adapter/ui-session.ts +2 -1
- package/node_modules/pi-mcp-adapter/utils.ts +21 -19
- package/node_modules/pi-web-access/CHANGELOG.md +26 -0
- package/node_modules/pi-web-access/README.md +71 -14
- package/node_modules/pi-web-access/chrome-cookies.ts +115 -35
- package/node_modules/pi-web-access/credential-source.ts +6 -2
- package/node_modules/pi-web-access/curator-page.ts +5 -3
- package/node_modules/pi-web-access/curator-server.ts +2 -1
- package/node_modules/pi-web-access/extract.ts +89 -9
- package/node_modules/pi-web-access/fetch-params.ts +13 -0
- package/node_modules/pi-web-access/gemini-adc.ts +298 -0
- package/node_modules/pi-web-access/gemini-api.ts +59 -15
- package/node_modules/pi-web-access/gemini-search.ts +58 -18
- package/node_modules/pi-web-access/gemini-url-context.ts +3 -2
- package/node_modules/pi-web-access/gemini-web-config.ts +57 -7
- package/node_modules/pi-web-access/gemini-web.ts +9 -3
- package/node_modules/pi-web-access/github-api.ts +5 -4
- package/node_modules/pi-web-access/github-issue-pr.ts +700 -0
- package/node_modules/pi-web-access/index.ts +403 -297
- package/node_modules/pi-web-access/kimi-search.ts +234 -0
- package/node_modules/pi-web-access/openai-search.ts +118 -21
- package/node_modules/pi-web-access/package.json +3 -2
- package/node_modules/pi-web-access/ssrf-protection.ts +4 -1
- package/node_modules/pi-web-access/utils.ts +307 -1
- package/node_modules/pi-web-access/youtube-extract.ts +2 -2
- package/package.json +46 -37
- package/node_modules/@herbertgao/pi-copy-response/CHANGELOG.md +0 -49
- package/node_modules/@herbertgao/pi-copy-response/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-handoff/CHANGELOG.md +0 -83
- package/node_modules/@herbertgao/pi-handoff/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-handoff/package.json +0 -60
- package/node_modules/@herbertgao/pi-inline-skills/CHANGELOG.md +0 -57
- package/node_modules/@herbertgao/pi-inline-skills/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-mermaid-open/CHANGELOG.md +0 -39
- package/node_modules/@herbertgao/pi-preferred-thinking/CHANGELOG.md +0 -63
- package/node_modules/@herbertgao/pi-preferred-thinking/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-recap/CHANGELOG.md +0 -101
- package/node_modules/@herbertgao/pi-recap/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-recap/package.json +0 -55
- package/node_modules/@herbertgao/pi-rename/CHANGELOG.md +0 -49
- package/node_modules/@herbertgao/pi-rename/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-rename/package.json +0 -63
- package/node_modules/@herbertgao/pi-titlebar-spinner/CHANGELOG.md +0 -25
- package/node_modules/@herbertgao/pi-titlebar-spinner/LICENSE +0 -22
- /package/node_modules/{@herbertgao → @tifan}/pi-copy-response/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/complete-text.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/session-query.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/herdr-plugin.toml +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/viewer.mjs +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/model-picker.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/sanitize.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/tui.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/model-picker.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/naming.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/sanitize.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/src/index.ts +0 -0
|
@@ -15,7 +15,7 @@ import { getGlobalPiLensDir } from "../file-utils.js";
|
|
|
15
15
|
import { isFullyQualified } from "../path-utils.js";
|
|
16
16
|
import { findGlobalBinary } from "../package-manager.js";
|
|
17
17
|
import { redactSecrets } from "../redact/secrets.js";
|
|
18
|
-
import { classifySpawnFailure, SpawnFailureError
|
|
18
|
+
import { classifySpawnFailure, SpawnFailureError } from "../safe-spawn.js";
|
|
19
19
|
import { getRubyVersionDirNamesAsync } from "./ruby-drive-dirs.js";
|
|
20
20
|
const isWindows = process.platform === "win32";
|
|
21
21
|
/**
|
|
@@ -176,7 +176,10 @@ export function isCmdShimValid(cmdPath) {
|
|
|
176
176
|
try {
|
|
177
177
|
const content = fs.readFileSync(cmdPath, "utf-8");
|
|
178
178
|
// npm cmd shim pattern: "%~dp0\..\<relpath>" or "%~dp0/<relpath>"
|
|
179
|
-
//
|
|
179
|
+
// The `-` ends the char class, where it is a literal and needs no escape.
|
|
180
|
+
// oxfmt formats this repository (#1844) and rewrites no regex literal, so
|
|
181
|
+
// this line needs no suppression; the directive oxfmt honors, if one is
|
|
182
|
+
// ever needed here, is `// prettier-ignore`.
|
|
180
183
|
const match = content.match(/"%~dp0[/\\]\.\.[/\\]((?:[\w./@-]|\\)+\.(?:mjs|cjs|js))"/i);
|
|
181
184
|
if (!match)
|
|
182
185
|
return true; // non-npm shim — let it through
|
|
@@ -205,7 +208,8 @@ function bypassPs1OnWindows(ps1Path, args) {
|
|
|
205
208
|
// npm-generated PS1 pattern: "$basedir/../<package>/bin/cli.js"
|
|
206
209
|
try {
|
|
207
210
|
const content = fs.readFileSync(ps1Path, "utf-8");
|
|
208
|
-
//
|
|
211
|
+
// Same char class as isCmdShimValid above, and the same note: the trailing
|
|
212
|
+
// `-` is a literal, and oxfmt leaves regex literals alone.
|
|
209
213
|
const match = content.match(/"\$basedir[/\\]\.\.[/\\]((?:[\w./@-]|\\)+\.(?:mjs|cjs|js))"/i);
|
|
210
214
|
if (match) {
|
|
211
215
|
const relPath = match[1].replace(/[/\\]/g, path.sep);
|
|
@@ -263,6 +267,10 @@ function trySpawn(command, args, cwd, env, needsShell) {
|
|
|
263
267
|
// shell:true justified: Windows .cmd/.bat LSP binaries (e.g. typescript-language-server.cmd)
|
|
264
268
|
// cannot be spawned via execFile — cmd.exe must interpret the script wrapper.
|
|
265
269
|
const shellCommand = `"${command}" ${args.map(escapeCmdArg).join(" ")}`;
|
|
270
|
+
// #2015 class-sweep exemption: this is a LONG-LIVED language-server launch,
|
|
271
|
+
// not a bounded probe - killing it on a timeout would be wrong, and its
|
|
272
|
+
// lifetime is owned by the LSP lifecycle, not the spawner. Exempt from the
|
|
273
|
+
// verifyToolBinary/probe tree-kill migration.
|
|
266
274
|
proc = nodeSpawn(shellCommand, [], {
|
|
267
275
|
cwd,
|
|
268
276
|
env,
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #2001/#2002 — collect-later coverage store for slow auxiliary LSP servers.
|
|
3
|
+
*
|
|
4
|
+
* When a `with-auxiliary` touch's aux-grace window expires without a
|
|
5
|
+
* publication from an auxiliary scanner (opengrep on Windows measures ~8s per
|
|
6
|
+
* scan against a 2s grace), that scanner's eventual findings were silently
|
|
7
|
+
* cached inside its LSP client and never surfaced to the agent: the auxiliary
|
|
8
|
+
* contributed ZERO agent-visible coverage on most edits.
|
|
9
|
+
*
|
|
10
|
+
* This module is the bounded hand-off between the two halves of the fix:
|
|
11
|
+
*
|
|
12
|
+
* - PRODUCER (`clients/lsp/index.ts`'s aux-grace wait): after the outcomes
|
|
13
|
+
* are decided, every auxiliary with no publication evidence for this
|
|
14
|
+
* content (`cut_off` or `silent`, minus #1493's published-this-content
|
|
15
|
+
* exemption) marks its (filePath, serverId) pair here. DEFERRED servers
|
|
16
|
+
* are never marked — they never received the content, so their cache
|
|
17
|
+
* still describes the PREVIOUS revision (#1459).
|
|
18
|
+
* - CONSUMER (`clients/runtime-turn.ts` at turn_end): drains the store,
|
|
19
|
+
* probes each pair through the read-only
|
|
20
|
+
* `LSPService.readCachedDiagnosticsForServers` seam, freshness-gates the
|
|
21
|
+
* result against `markedAtMs`, and delivers survivors as the registered
|
|
22
|
+
* `runtime-turn:late-auxiliary-findings` gated surface. A pair whose
|
|
23
|
+
* client is alive but has STILL published nothing is re-armed until
|
|
24
|
+
* readLateAuxRearmTtlMs() (env-overridable via
|
|
25
|
+
* `PI_LENS_LATE_AUX_REARM_TTL_MS`) after the LAST re-arm, so a scan
|
|
26
|
+
* finishing between two turn ends is not lost and a demonstrably alive
|
|
27
|
+
* but slow scanner keeps its window open; `markedAtMs` itself never
|
|
28
|
+
* moves — it stays the immutable freshness baseline the delivery gate
|
|
29
|
+
* stats against. Past the TTL, or when the client is gone, the entry is
|
|
30
|
+
* dropped silently (best-effort by design).
|
|
31
|
+
*
|
|
32
|
+
* Bounds: at most MAX_PENDING_ENTRIES (file, server) pairs, insertion-order
|
|
33
|
+
* eviction of the OLDEST pair when the cap is exceeded (shape 9 discipline —
|
|
34
|
+
* the axis that grows is the pair count, so that is the axis that is capped).
|
|
35
|
+
* Keys fold through `normalizeEphemeralMapKey`: this is a hot single-process
|
|
36
|
+
* index whose keys are produced by this same process's touch path, so the
|
|
37
|
+
* cheap ephemeral normalizer is the lifetime-appropriate choice per the
|
|
38
|
+
* PathKeyedMap guidance — no realpath walk on the per-edit path.
|
|
39
|
+
*/
|
|
40
|
+
import { normalizeEphemeralMapKey } from "../path-utils.js";
|
|
41
|
+
/** Maximum pending (filePath, serverId) pairs; oldest evicted beyond this. */
|
|
42
|
+
export const MAX_PENDING_AUX_ENTRIES = 50;
|
|
43
|
+
/**
|
|
44
|
+
* Default for how long a marked pair keeps being re-probed at successive
|
|
45
|
+
* turn ends when the client is alive but has published nothing yet. Covers
|
|
46
|
+
* opengrep's measured ~8s worst case many times over without pinning state
|
|
47
|
+
* forever. Overridable via `PI_LENS_LATE_AUX_REARM_TTL_MS`.
|
|
48
|
+
*/
|
|
49
|
+
export const DEFAULT_LATE_AUX_REARM_TTL_MS = 5 * 60_000;
|
|
50
|
+
/**
|
|
51
|
+
* Read the `PI_LENS_LATE_AUX_REARM_TTL_MS` env override at call time (not
|
|
52
|
+
* module load time) so tests and users can tune without a rebuild — same
|
|
53
|
+
* shape as `readEnvAuxGraceMs` in clients/lsp/index.ts. Absent, non-numeric,
|
|
54
|
+
* or negative values fall back to {@link DEFAULT_LATE_AUX_REARM_TTL_MS}.
|
|
55
|
+
*/
|
|
56
|
+
export function readLateAuxRearmTtlMs() {
|
|
57
|
+
const raw = process.env.PI_LENS_LATE_AUX_REARM_TTL_MS;
|
|
58
|
+
if (raw === undefined)
|
|
59
|
+
return DEFAULT_LATE_AUX_REARM_TTL_MS;
|
|
60
|
+
const parsed = Number.parseInt(raw, 10);
|
|
61
|
+
if (!Number.isFinite(parsed) || parsed < 0)
|
|
62
|
+
return DEFAULT_LATE_AUX_REARM_TTL_MS;
|
|
63
|
+
return parsed;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Whether a pending pair is past its re-arm TTL and should be retired at the
|
|
67
|
+
* next drain. The TTL anchors on {@link PendingAuxCoverageEntry.lastRearmedAtMs}
|
|
68
|
+
* when present (each successful probe extends the window), else on
|
|
69
|
+
* `markedAtMs`. `nowMs` is injectable so tests are deterministic.
|
|
70
|
+
*/
|
|
71
|
+
export function isPendingAuxiliaryPastRearmTtl(pair, nowMs = Date.now()) {
|
|
72
|
+
const anchor = pair.lastRearmedAtMs ?? pair.markedAtMs;
|
|
73
|
+
return nowMs - anchor >= readLateAuxRearmTtlMs();
|
|
74
|
+
}
|
|
75
|
+
const pending = new Map();
|
|
76
|
+
function pairKey(filePath, serverId) {
|
|
77
|
+
return `${normalizeEphemeralMapKey(filePath)}\u0000${serverId}`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Mark (or re-arm) one file's pending auxiliary coverage for `serverIds`.
|
|
81
|
+
* An existing pair keeps its ORIGINAL `markedAtMs`; only genuinely new pairs
|
|
82
|
+
* stamp the current time. Insertion order updates on re-mark so a re-armed
|
|
83
|
+
* pair is not the next one evicted at the cap.
|
|
84
|
+
*
|
|
85
|
+
* `rearmedAtMs` is the turn-end consumer's re-arm form: it stamps
|
|
86
|
+
* `lastRearmedAtMs` (the TTL anchor) WITHOUT moving the freshness baseline,
|
|
87
|
+
* so each successful probe extends the wait window while the delivery gate
|
|
88
|
+
* keeps comparing mtimes against the original mark. The producer form (no
|
|
89
|
+
* `rearmedAtMs`) marks a NEWER revision, so it resets any prior re-arm stamp
|
|
90
|
+
* along with the baseline — the new pair's TTL starts from its own mark.
|
|
91
|
+
*/
|
|
92
|
+
export function markPendingAuxiliaryCoverage(filePath, serverIds, markedAtMs = Date.now(), rearmedAtMs) {
|
|
93
|
+
for (const serverId of serverIds) {
|
|
94
|
+
const key = pairKey(filePath, serverId);
|
|
95
|
+
const existing = pending.get(key);
|
|
96
|
+
if (existing) {
|
|
97
|
+
// #2027 review: bump the freshness baseline on producer re-mark. A
|
|
98
|
+
// newer touch means the auxiliary is scanning a NEWER revision;
|
|
99
|
+
// keeping the original baseline would make every post-baseline mtime
|
|
100
|
+
// read as stale, permanently dropping current-revision findings.
|
|
101
|
+
// A re-arm form never moves the baseline — only the TTL anchor.
|
|
102
|
+
pending.delete(key);
|
|
103
|
+
pending.set(key, rearmedAtMs === undefined
|
|
104
|
+
? { filePath, serverId, markedAtMs }
|
|
105
|
+
: {
|
|
106
|
+
filePath,
|
|
107
|
+
serverId,
|
|
108
|
+
markedAtMs: existing.markedAtMs,
|
|
109
|
+
lastRearmedAtMs: rearmedAtMs,
|
|
110
|
+
});
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
pending.set(key, rearmedAtMs === undefined
|
|
114
|
+
? { filePath, serverId, markedAtMs }
|
|
115
|
+
: { filePath, serverId, markedAtMs, lastRearmedAtMs: rearmedAtMs });
|
|
116
|
+
while (pending.size > MAX_PENDING_AUX_ENTRIES) {
|
|
117
|
+
const oldest = pending.keys().next().value;
|
|
118
|
+
if (oldest === undefined)
|
|
119
|
+
break;
|
|
120
|
+
pending.delete(oldest);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Remove one pair after its findings were delivered, or whenever the caller
|
|
126
|
+
* knows it is resolved. Unknown pairs are a no-op.
|
|
127
|
+
*/
|
|
128
|
+
export function clearPendingAuxiliaryCoverage(filePath, serverId) {
|
|
129
|
+
pending.delete(pairKey(filePath, serverId));
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Drain ALL pending pairs (removing them from the store) and return them in
|
|
133
|
+
* insertion order. The consumer re-arms the still-waiting subset via
|
|
134
|
+
* {@link markPendingAuxiliaryCoverage}'s `rearmedAtMs` form, which preserves
|
|
135
|
+
* each entry's original `markedAtMs` and stamps `lastRearmedAtMs`.
|
|
136
|
+
*/
|
|
137
|
+
export function drainPendingAuxiliaryCoverage() {
|
|
138
|
+
const drained = [...pending.values()];
|
|
139
|
+
pending.clear();
|
|
140
|
+
return drained;
|
|
141
|
+
}
|
|
142
|
+
/** Test-only: current pending pair count. */
|
|
143
|
+
export function pendingAuxiliaryCoverageSizeForTests() {
|
|
144
|
+
return pending.size;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Session-boundary clear (#1635): pending baselines are unreachable after
|
|
148
|
+
* reset (the generation-stamped keys no longer match any active session).
|
|
149
|
+
*/
|
|
150
|
+
export function resetPendingAuxiliaryCoverage() {
|
|
151
|
+
pending.clear();
|
|
152
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - Platform-specific handling
|
|
8
8
|
*/
|
|
9
9
|
import { existsSync, mkdirSync } from "node:fs";
|
|
10
|
-
import { access, readFile, readdir, stat
|
|
10
|
+
import { access, readFile, readdir, stat } from "node:fs/promises";
|
|
11
11
|
import os from "node:os";
|
|
12
12
|
import path from "node:path";
|
|
13
13
|
import { getGlobalPiLensDir, getProjectIgnoreGlobs, isPathIgnoredByProject, } from "../file-utils.js";
|
|
@@ -16,7 +16,7 @@ import { DOTNET_CSHARP_ROOT_MARKERS, DOTNET_FSHARP_ROOT_MARKERS, KIND_EXTENSIONS
|
|
|
16
16
|
import { direntsHaveMarkerGlobMatch, isAtOrAboveHomeDir, isFullyQualified, isWindowsPath, pathsEqual, } from "../path-utils.js";
|
|
17
17
|
import { ensureTool, getToolEnvironment, getToolPath, } from "../installer/index.js";
|
|
18
18
|
import { resolveOpengrepConfig } from "../opengrep-config.js";
|
|
19
|
-
import { isZizmorAuditTarget, resolveZizmorGitHubToken } from "../zizmor-config.js";
|
|
19
|
+
import { isZizmorAuditTarget, resolveZizmorGitHubToken, } from "../zizmor-config.js";
|
|
20
20
|
import { logLatency } from "../latency-logger.js";
|
|
21
21
|
import { logSessionStart } from "../sessionstart-logger.js";
|
|
22
22
|
import { findLocalSgconfig, resolveBaselineSgconfig } from "../sgconfig.js";
|
|
@@ -1236,7 +1236,9 @@ function isTsFamilyFile(file) {
|
|
|
1236
1236
|
return TS_FAMILY_EXTENSIONS.has(path.extname(file).toLowerCase());
|
|
1237
1237
|
}
|
|
1238
1238
|
function tsConfigMarkersForFile(file) {
|
|
1239
|
-
return isTsFamilyFile(file)
|
|
1239
|
+
return isTsFamilyFile(file)
|
|
1240
|
+
? ["tsconfig.json"]
|
|
1241
|
+
: TS_CONFIG_MARKERS;
|
|
1240
1242
|
}
|
|
1241
1243
|
// Two detector instances (not one parameterized by file) so each keeps its own
|
|
1242
1244
|
// per-directory NearestRoot cache valid for its fixed marker set — a shared
|
|
@@ -1606,7 +1608,9 @@ function extractTomlTableSection(content, tableName) {
|
|
|
1606
1608
|
return "";
|
|
1607
1609
|
const rest = content.slice(match.index + match[0].length);
|
|
1608
1610
|
const nextHeading = rest.match(/^\[{1,2}[^\]]+\]{1,2}[ \t]*(?:#.*)?$/m);
|
|
1609
|
-
return nextHeading?.index !== undefined
|
|
1611
|
+
return nextHeading?.index !== undefined
|
|
1612
|
+
? rest.slice(0, nextHeading.index)
|
|
1613
|
+
: rest;
|
|
1610
1614
|
}
|
|
1611
1615
|
function parseTomlStringArray(content, key) {
|
|
1612
1616
|
const match = content.match(new RegExp(`^[ \\t]*${key}[ \\t]*=[ \\t]*\\[([\\s\\S]*?)\\]`, "m"));
|
|
@@ -1674,7 +1678,10 @@ function matchesCargoWorkspacePattern(pattern, relativePath) {
|
|
|
1674
1678
|
* common case and the one #1671's fixtures exercise — is unaffected.
|
|
1675
1679
|
*/
|
|
1676
1680
|
function cargoWorkspaceDeclaresMember(workspaceContent, parentDir, childDir) {
|
|
1677
|
-
const relativePath = path
|
|
1681
|
+
const relativePath = path
|
|
1682
|
+
.relative(parentDir, childDir)
|
|
1683
|
+
.split(path.sep)
|
|
1684
|
+
.join("/");
|
|
1678
1685
|
if (relativePath === "" || relativePath.startsWith(".."))
|
|
1679
1686
|
return false;
|
|
1680
1687
|
const workspaceSection = extractTomlTableSection(workspaceContent, "workspace");
|
|
@@ -1721,7 +1728,8 @@ function RustWorkspaceRoot() {
|
|
|
1721
1728
|
break;
|
|
1722
1729
|
const parentCargoPath = path.join(parent, "Cargo.toml");
|
|
1723
1730
|
const parentCargoContent = await readTextFileOrUndefined(parentCargoPath);
|
|
1724
|
-
if (parentCargoContent !== undefined &&
|
|
1731
|
+
if (parentCargoContent !== undefined &&
|
|
1732
|
+
/^\s*\[workspace\]/m.test(parentCargoContent)) {
|
|
1725
1733
|
// Test membership against the ORIGINAL crate dir (`root`), never the
|
|
1726
1734
|
// walk cursor (`current`, which may already have climbed through
|
|
1727
1735
|
// gap directories that have no Cargo.toml of their own) — a
|
|
@@ -1786,7 +1794,11 @@ async function declaresMavenModule(parentDir, parentPomPath, childDir) {
|
|
|
1786
1794
|
}
|
|
1787
1795
|
}
|
|
1788
1796
|
function JavaWorkspaceRoot() {
|
|
1789
|
-
const moduleRoot = createRootDetector([
|
|
1797
|
+
const moduleRoot = createRootDetector([
|
|
1798
|
+
"pom.xml",
|
|
1799
|
+
"build.gradle",
|
|
1800
|
+
".classpath",
|
|
1801
|
+
]);
|
|
1790
1802
|
return async (file) => {
|
|
1791
1803
|
const root = await moduleRoot(file);
|
|
1792
1804
|
if (!root)
|
|
@@ -114,9 +114,17 @@ export async function probeTsserverProjectIdentity(options) {
|
|
|
114
114
|
// writing an `lsp_typescript_project_identity` row per didOpen on every
|
|
115
115
|
// server (python, go, opengrep, ...).
|
|
116
116
|
const logOutcome = (outcome, metadata = {}) => logLatency({
|
|
117
|
-
type: "phase",
|
|
117
|
+
type: "phase",
|
|
118
|
+
phase: "lsp_typescript_project_identity",
|
|
119
|
+
filePath: normalizedFile,
|
|
118
120
|
durationMs: Date.now() - startedAt,
|
|
119
|
-
metadata: {
|
|
121
|
+
metadata: {
|
|
122
|
+
serverId: options.serverId,
|
|
123
|
+
launchVariant: options.launchVariant,
|
|
124
|
+
clientRoot: options.clientRoot,
|
|
125
|
+
outcome,
|
|
126
|
+
...metadata,
|
|
127
|
+
},
|
|
120
128
|
});
|
|
121
129
|
if (options.serverId !== "typescript" ||
|
|
122
130
|
options.launchVariant !== "classic" ||
|
|
@@ -6,7 +6,7 @@ import { readJsonCache } from "../json-cache-read.js";
|
|
|
6
6
|
import { createGenerationMap } from "../generation-guard.js";
|
|
7
7
|
import { normalizeMapKey } from "../path-utils.js";
|
|
8
8
|
import { loadReverseDependencyIndexFromSnapshot } from "../reverse-deps.js";
|
|
9
|
-
import {
|
|
9
|
+
import { freshnessFromMtime } from "../freshness.js";
|
|
10
10
|
import { logLatency } from "../latency-logger.js";
|
|
11
11
|
import { workspaceDiagnosticsCacheSessionStart } from "./workspace-diagnostics-session.js";
|
|
12
12
|
import { createDiskBindingCache, } from "./diagnostic-binding.js";
|
|
@@ -344,14 +344,19 @@ export function isEntryFresh(filePath, entry, getImports) {
|
|
|
344
344
|
return entry.depIndexAtScan !== true;
|
|
345
345
|
}
|
|
346
346
|
for (const dep of imports) {
|
|
347
|
+
let mtimeMs;
|
|
347
348
|
try {
|
|
348
|
-
|
|
349
|
-
return false;
|
|
350
|
-
}
|
|
349
|
+
mtimeMs = fs.statSync(dep).mtimeMs;
|
|
351
350
|
}
|
|
352
351
|
catch {
|
|
353
352
|
return false; // dependency deleted/unreadable: fail closed
|
|
354
353
|
}
|
|
354
|
+
const verdict = freshnessFromMtime({
|
|
355
|
+
mtimeMs,
|
|
356
|
+
referenceMs: entry.scannedAt,
|
|
357
|
+
});
|
|
358
|
+
if (verdict.verdict === "stale")
|
|
359
|
+
return false;
|
|
355
360
|
}
|
|
356
361
|
return true;
|
|
357
362
|
}
|
|
@@ -68,9 +68,7 @@ export function findDocumentSymbolAtLine(symbols, oneBasedLine) {
|
|
|
68
68
|
const visit = (items, ancestry) => {
|
|
69
69
|
for (const symbol of items) {
|
|
70
70
|
const range = symbolRange(symbol);
|
|
71
|
-
if (range &&
|
|
72
|
-
range.start.line <= line &&
|
|
73
|
-
range.end.line >= line) {
|
|
71
|
+
if (range && range.start.line <= line && range.end.line >= line) {
|
|
74
72
|
const nextAncestry = [...ancestry, symbol];
|
|
75
73
|
const span = range.end.line - range.start.line;
|
|
76
74
|
if (span <= bestSpan) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { createReadGuardEditBatchSummary, getReadGuardCorrelationId, logReadGuardEvent, } from "./read-guard-logger.js";
|
|
3
|
-
import { appendProjectChange, } from "./project-changes.js";
|
|
4
3
|
import { normalizeMapKey } from "./path-utils.js";
|
|
5
4
|
const MAX_SAMPLES = 100;
|
|
6
5
|
const MAX_SUMMARIES_PER_CONTEXT = 100;
|
|
@@ -67,7 +66,7 @@ function uniqueDetails(files, fileDetails) {
|
|
|
67
66
|
start: Math.min(previous.range.start, detail.range.start),
|
|
68
67
|
end: Math.max(previous.range.end, detail.range.end),
|
|
69
68
|
}
|
|
70
|
-
: previous.range ?? detail.range,
|
|
69
|
+
: (previous.range ?? detail.range),
|
|
71
70
|
importsChanged: previous.importsChanged || detail.importsChanged,
|
|
72
71
|
});
|
|
73
72
|
}
|
|
@@ -93,24 +92,15 @@ function bookkeepLspMutation(context, files, fileDetails) {
|
|
|
93
92
|
}
|
|
94
93
|
}
|
|
95
94
|
const runtime = context.runtime;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
filePath,
|
|
106
|
-
fileSeq,
|
|
107
|
-
changedRange: detail.range,
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
catch (err) {
|
|
111
|
-
context.dbg?.(`lsp mutation project change append failed for ${filePath}: ${err}`);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
95
|
+
// One mutation seam (#2000 phase 1): bump + receipt + change-log live in
|
|
96
|
+
// RuntimeCoordinator.recordProjectMutation.
|
|
97
|
+
runtime?.recordProjectMutation?.({
|
|
98
|
+
filePath,
|
|
99
|
+
source: context.source,
|
|
100
|
+
cwd: context.cwd,
|
|
101
|
+
changedRange: detail.range,
|
|
102
|
+
onAppendError: (err) => context.dbg?.(`lsp mutation project change append failed for ${filePath}: ${err}`),
|
|
103
|
+
});
|
|
114
104
|
if (context.cacheManager) {
|
|
115
105
|
try {
|
|
116
106
|
context.cacheManager.addModifiedRange(filePath, detail.range ?? { start: 1, end: 1 }, detail.importsChanged ?? true, context.cwd, runtime?.telemetrySessionId);
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* coupling the MCP path has to satisfy — everything else under `clients/` is
|
|
10
10
|
* host-neutral.
|
|
11
11
|
*/
|
|
12
|
-
import { loadPiLensGlobalConfig, resolvePiLensFlag
|
|
12
|
+
import { loadPiLensGlobalConfig, resolvePiLensFlag } from "../lens-config.js";
|
|
13
13
|
import { loadPiLensProjectConfig } from "../project-lens-config.js";
|
|
14
14
|
/**
|
|
15
15
|
* Build a `PiAgentAPI` for the MCP path. `overrides` lets a single MCP tool call
|
|
@@ -40,15 +40,63 @@ export const MEMORY_SAMPLE_TURN_INTERVAL = 10;
|
|
|
40
40
|
export function shouldEmitMemorySample(turnIndex) {
|
|
41
41
|
return turnIndex > 0 && turnIndex % MEMORY_SAMPLE_TURN_INTERVAL === 0;
|
|
42
42
|
}
|
|
43
|
-
/**
|
|
44
|
-
*
|
|
45
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Rising-edge cadence (#1999): when heapUsed grows more than
|
|
45
|
+
* {@link HEAP_GROWTH_TIGHTEN_RATIO} between two sampled turns, sampling
|
|
46
|
+
* tightens from every {@link MEMORY_SAMPLE_TURN_INTERVAL} turns to every turn
|
|
47
|
+
* until growth stabilizes. The state below is module-scoped SESSION state —
|
|
48
|
+
* reset it at every primary `session_start` via
|
|
49
|
+
* {@link resetMemorySamplerCadence} (defect shape 17: a process-lifetime latch
|
|
50
|
+
* holding a session-scoped signal).
|
|
51
|
+
*/
|
|
52
|
+
export const HEAP_GROWTH_TIGHTEN_RATIO = 1.2;
|
|
53
|
+
let _lastSampledHeapUsedBytes = 0;
|
|
54
|
+
let _tightenThroughTurn = 0;
|
|
55
|
+
/** Clear the rising-edge cadence state. Called on primary session_start. */
|
|
56
|
+
export function resetMemorySamplerCadence() {
|
|
57
|
+
_lastSampledHeapUsedBytes = 0;
|
|
58
|
+
_tightenThroughTurn = 0;
|
|
59
|
+
}
|
|
60
|
+
/** PURE: >20% heap growth between two sampled readings warrants tightening. */
|
|
61
|
+
export function isRapidHeapGrowth(previousHeapUsedBytes, currentHeapUsedBytes) {
|
|
62
|
+
return (previousHeapUsedBytes > 0 &&
|
|
63
|
+
currentHeapUsedBytes > previousHeapUsedBytes * HEAP_GROWTH_TIGHTEN_RATIO);
|
|
64
|
+
}
|
|
65
|
+
/** Record the heap reading of a sample just emitted at `turnIndex`. A rapid
|
|
66
|
+
* growth edge extends the tightened window through the NEXT turn; each
|
|
67
|
+
* subsequent still-growing sample (including one taken inside an already
|
|
68
|
+
* tightened window) extends it again, so the window naturally expires once
|
|
69
|
+
* growth stabilizes. Monotonic max so an out-of-order turn can never shrink
|
|
70
|
+
* the window. O(1). */
|
|
71
|
+
export function recordMemorySampleOutcome(heapUsedBytes, turnIndex) {
|
|
72
|
+
if (isRapidHeapGrowth(_lastSampledHeapUsedBytes, heapUsedBytes)) {
|
|
73
|
+
_tightenThroughTurn = Math.max(_tightenThroughTurn, turnIndex + 1);
|
|
74
|
+
}
|
|
75
|
+
_lastSampledHeapUsedBytes = heapUsedBytes;
|
|
76
|
+
}
|
|
77
|
+
/** Adaptive gate used by turn_end: base every-10 cadence OR an open tightened
|
|
78
|
+
* window. Pure w.r.t. its argument; the window itself is session state owned
|
|
79
|
+
* by {@link recordMemorySampleOutcome}. */
|
|
80
|
+
export function shouldEmitMemorySampleAdaptive(turnIndex) {
|
|
81
|
+
if (turnIndex <= 0)
|
|
82
|
+
return false;
|
|
83
|
+
return (turnIndex % MEMORY_SAMPLE_TURN_INTERVAL === 0 ||
|
|
84
|
+
turnIndex <= _tightenThroughTurn);
|
|
85
|
+
}
|
|
86
|
+
/** PURE: reshape Node's `process.memoryUsage()` (+ optional
|
|
87
|
+
* `process.resourceUsage()`) into this module's field names — testable
|
|
88
|
+
* without touching the real process. */
|
|
89
|
+
export function toMemoryProcessUsage(mem, resourceUsage) {
|
|
90
|
+
const maxKb = resourceUsage?.maxRSS;
|
|
46
91
|
return {
|
|
47
92
|
rssBytes: mem.rss,
|
|
48
93
|
heapUsedBytes: mem.heapUsed,
|
|
49
94
|
heapTotalBytes: mem.heapTotal,
|
|
50
95
|
externalBytes: mem.external,
|
|
51
96
|
arrayBuffersBytes: mem.arrayBuffers,
|
|
97
|
+
peakWorkingSetBytes: typeof maxKb === "number" && Number.isFinite(maxKb) && maxKb > 0
|
|
98
|
+
? maxKb * 1024
|
|
99
|
+
: null,
|
|
52
100
|
};
|
|
53
101
|
}
|
|
54
102
|
/**
|
|
@@ -86,11 +134,23 @@ export function collectMemorySampleSubsystems(wordIndex) {
|
|
|
86
134
|
};
|
|
87
135
|
}
|
|
88
136
|
/** Assemble one full sample. `mem` is injectable for tests; defaults to a
|
|
89
|
-
* live `process.memoryUsage()` read.
|
|
90
|
-
|
|
137
|
+
* live `process.memoryUsage()` read. `resourceUsage` (peak working set) and
|
|
138
|
+
* `session` are optional ridealongs (#1999); when `resourceUsage` is omitted
|
|
139
|
+
* a live `process.resourceUsage()` read supplies the peak. */
|
|
140
|
+
export function buildMemorySample(wordIndex, mem = process.memoryUsage(), resourceUsage, session) {
|
|
141
|
+
let resolvedResourceUsage = resourceUsage;
|
|
142
|
+
if (!resolvedResourceUsage) {
|
|
143
|
+
try {
|
|
144
|
+
resolvedResourceUsage = process.resourceUsage();
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
resolvedResourceUsage = undefined;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
91
150
|
return {
|
|
92
|
-
process: toMemoryProcessUsage(mem),
|
|
151
|
+
process: toMemoryProcessUsage(mem, resolvedResourceUsage),
|
|
93
152
|
subsystems: collectMemorySampleSubsystems(wordIndex),
|
|
153
|
+
session,
|
|
94
154
|
};
|
|
95
155
|
}
|
|
96
156
|
const toMb = (bytes) => Math.round(bytes / (1024 * 1024));
|
|
@@ -110,6 +170,12 @@ export function formatMemoryHealthLine(sample) {
|
|
|
110
170
|
? `${toMb(subsystems.treeSitter.treeCacheTotalBytes)}MB (${subsystems.treeSitter.treeCacheSize} trees)`
|
|
111
171
|
: "n/a";
|
|
112
172
|
const graph = `${subsystems.reviewGraph.totalNodes}n/${subsystems.reviewGraph.totalEdges}e (${subsystems.reviewGraph.cacheEntries} cwd)`;
|
|
173
|
+
// #1999: peak WS rides along when known — rss far below peak means the
|
|
174
|
+
// periodic samples are catching idle valleys, not the true high-water mark.
|
|
175
|
+
const peak = proc.peakWorkingSetBytes !== null
|
|
176
|
+
? ` · peak WS ${toMb(proc.peakWorkingSetBytes)}MB`
|
|
177
|
+
: "";
|
|
113
178
|
return (`Memory: RSS ${toMb(proc.rssBytes)}MB · heap ${toMb(proc.heapUsedBytes)}/${toMb(proc.heapTotalBytes)}MB` +
|
|
114
|
-
` · external ${toMb(proc.externalBytes)}MB
|
|
179
|
+
` · external ${toMb(proc.externalBytes)}MB${peak}` +
|
|
180
|
+
` · tree-sitter cache ${treeCache} · review-graph ${graph}`);
|
|
115
181
|
}
|
|
@@ -18,9 +18,7 @@ export class MetricsClient {
|
|
|
18
18
|
log;
|
|
19
19
|
fileBaselines = new Map();
|
|
20
20
|
constructor(verbose = false) {
|
|
21
|
-
this.log = verbose
|
|
22
|
-
? createSubsystemLogger("metrics")
|
|
23
|
-
: () => { };
|
|
21
|
+
this.log = verbose ? createSubsystemLogger("metrics") : () => { };
|
|
24
22
|
}
|
|
25
23
|
/**
|
|
26
24
|
* Record initial state of a file when first touched this session
|
|
@@ -50,7 +50,12 @@ const SELF_TOKEN = {
|
|
|
50
50
|
const INTENTIONAL_FORWARDER_NAME = /adapter|facade|proxy|wrapper|decorator/i;
|
|
51
51
|
/** Names that are constructors/destructors (never delegation candidates) in at
|
|
52
52
|
* least one covered language. */
|
|
53
|
-
const CONSTRUCTOR_NAMES = new Set([
|
|
53
|
+
const CONSTRUCTOR_NAMES = new Set([
|
|
54
|
+
"constructor",
|
|
55
|
+
"__init__",
|
|
56
|
+
"__new__",
|
|
57
|
+
"initialize",
|
|
58
|
+
]);
|
|
54
59
|
/** Below this many real (non-accessor, non-constructor) methods, a delegation
|
|
55
60
|
* ratio isn't a meaningful judgment — a one-method utility class forwarding
|
|
56
61
|
* that one call is not "the class only ever delegates", it's just a small
|
|
@@ -130,7 +135,7 @@ function bodyStatementLines(lines, entry, isPython) {
|
|
|
130
135
|
return [];
|
|
131
136
|
body = raw.slice(braceIdx + 1, lastBrace);
|
|
132
137
|
}
|
|
133
|
-
return body
|
|
138
|
+
return (body
|
|
134
139
|
.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
135
140
|
.split("\n")
|
|
136
141
|
.map((l) => l.replace(/\/\/.*$/, ""))
|
|
@@ -140,7 +145,7 @@ function bodyStatementLines(lines, entry, isPython) {
|
|
|
140
145
|
// A lone triple-quoted docstring line in python isn't executable, but
|
|
141
146
|
// distinguishing it textually is unreliable — treat any leading `"""`/`'''`
|
|
142
147
|
// line as noise so a documented one-liner forward still qualifies.
|
|
143
|
-
.filter((l) => !/^("""|''')/.test(l));
|
|
148
|
+
.filter((l) => !/^("""|''')/.test(l)));
|
|
144
149
|
}
|
|
145
150
|
/** Detects an accessor (getter/setter) declaration from its raw source line —
|
|
146
151
|
* accessors are a DIFFERENT smell (anemic class) and excluded from both the
|
|
@@ -82,7 +82,13 @@ function lspLocationsToUsedBy(locs, cap) {
|
|
|
82
82
|
if (seen.has(key))
|
|
83
83
|
continue;
|
|
84
84
|
seen.add(key);
|
|
85
|
-
out.push({
|
|
85
|
+
out.push({
|
|
86
|
+
file,
|
|
87
|
+
symbol: "",
|
|
88
|
+
line,
|
|
89
|
+
relation: "references",
|
|
90
|
+
provenance: "lsp",
|
|
91
|
+
});
|
|
86
92
|
if (out.length >= cap)
|
|
87
93
|
break;
|
|
88
94
|
}
|
|
@@ -1180,7 +1180,8 @@ function unavailableCallGraph(reason) {
|
|
|
1180
1180
|
}
|
|
1181
1181
|
function callGraphCoverage(coverage) {
|
|
1182
1182
|
const languages = coverage.languages;
|
|
1183
|
-
const complete = coverage.complete &&
|
|
1183
|
+
const complete = coverage.complete &&
|
|
1184
|
+
Object.values(languages ?? {}).every((status) => status === "complete");
|
|
1184
1185
|
return {
|
|
1185
1186
|
status: complete ? "complete" : "partial",
|
|
1186
1187
|
complete,
|
|
@@ -1235,7 +1236,8 @@ function readCallGraph(projectRoot, normalizedPath, maxEntries, graphFileCap, id
|
|
|
1235
1236
|
// read-only: do not walk source files or compare an independent mtime map.
|
|
1236
1237
|
if (!reviewGraph)
|
|
1237
1238
|
return unavailableCallGraph("review-graph-missing");
|
|
1238
|
-
if (reviewGraph.persistCoverage?.partial ||
|
|
1239
|
+
if (reviewGraph.persistCoverage?.partial ||
|
|
1240
|
+
reviewGraph.persistCoverage?.inProgress) {
|
|
1239
1241
|
return unavailableCallGraph("partial");
|
|
1240
1242
|
}
|
|
1241
1243
|
if (!identity)
|
|
@@ -1458,9 +1460,7 @@ export async function moduleReport(file, cwd, options) {
|
|
|
1458
1460
|
else if (graph) {
|
|
1459
1461
|
importsProvenance = "cached-review-graph";
|
|
1460
1462
|
}
|
|
1461
|
-
const unavailableGraphProvenance = graphFileCap !== undefined
|
|
1462
|
-
? "unavailable:file-cap"
|
|
1463
|
-
: "none";
|
|
1463
|
+
const unavailableGraphProvenance = graphFileCap !== undefined ? "unavailable:file-cap" : "none";
|
|
1464
1464
|
const blastRadiusProvenance = blastRadius
|
|
1465
1465
|
? "cached-review-graph"
|
|
1466
1466
|
: unavailableGraphProvenance;
|
|
@@ -1495,13 +1495,9 @@ export async function moduleReport(file, cwd, options) {
|
|
|
1495
1495
|
provenance: {
|
|
1496
1496
|
symbols: languageId ? "syntax" : "none",
|
|
1497
1497
|
imports: importsProvenance,
|
|
1498
|
-
usedBy: hasGraphNode
|
|
1499
|
-
? "cached-review-graph"
|
|
1500
|
-
: unavailableGraphProvenance,
|
|
1498
|
+
usedBy: hasGraphNode ? "cached-review-graph" : unavailableGraphProvenance,
|
|
1501
1499
|
callbacks: languageId && !summaryView ? "heuristic-tree-sitter" : "none",
|
|
1502
|
-
...(options?.blastRadius
|
|
1503
|
-
? { blastRadius: blastRadiusProvenance }
|
|
1504
|
-
: {}),
|
|
1500
|
+
...(options?.blastRadius ? { blastRadius: blastRadiusProvenance } : {}),
|
|
1505
1501
|
...(options?.callGraph ? { callGraph: callGraphProvenance } : {}),
|
|
1506
1502
|
},
|
|
1507
1503
|
semantic: {
|
|
@@ -1565,7 +1561,9 @@ function compactEntryLine(entry, width) {
|
|
|
1565
1561
|
const range = padRange(entry.startLine, entry.endLine, width);
|
|
1566
1562
|
const kind = compactKind(entry.kind).padEnd(6);
|
|
1567
1563
|
const sig = entry.signature ? `${entry.name}${entry.signature}` : entry.name;
|
|
1568
|
-
const flagsSuffix = entry.flags && entry.flags.length > 0
|
|
1564
|
+
const flagsSuffix = entry.flags && entry.flags.length > 0
|
|
1565
|
+
? ` [${entry.flags.join(", ")}]`
|
|
1566
|
+
: "";
|
|
1569
1567
|
const docSuffix = entry.doc ? ` — ${entry.doc}` : "";
|
|
1570
1568
|
const usedBySuffix = compactUsedBySuffix(entry.usedBy);
|
|
1571
1569
|
return ` ${range}${kind}${sig}${flagsSuffix}${usedBySuffix}${docSuffix}`;
|
|
@@ -1607,10 +1605,7 @@ export function renderCompactModuleReport(report) {
|
|
|
1607
1605
|
return `${report.path} — unavailable${report.error ? `: ${report.error}` : ""}`;
|
|
1608
1606
|
}
|
|
1609
1607
|
const allEntries = [...report.api, ...report.internal];
|
|
1610
|
-
const allRanges = allEntries.flatMap((e) => [
|
|
1611
|
-
e,
|
|
1612
|
-
...(e.members ?? []),
|
|
1613
|
-
]);
|
|
1608
|
+
const allRanges = allEntries.flatMap((e) => [e, ...(e.members ?? [])]);
|
|
1614
1609
|
const width = Math.max(5, ...allRanges.map((e) => `${e.startLine}-${e.endLine}`.length), ...report.callbacks.map((c) => `${c.startLine}-${c.endLine}`.length)) + 2;
|
|
1615
1610
|
const importsList = [...report.imports.internal, ...report.imports.external];
|
|
1616
1611
|
const importsSuffix = importsList.length > 0
|
|
@@ -1679,7 +1674,9 @@ function baseNameNoExt(p) {
|
|
|
1679
1674
|
function selectMatch(candidates, kind) {
|
|
1680
1675
|
if (candidates.length === 0)
|
|
1681
1676
|
return {};
|
|
1682
|
-
const filtered = kind
|
|
1677
|
+
const filtered = kind
|
|
1678
|
+
? candidates.filter((c) => c.kind === kind)
|
|
1679
|
+
: candidates;
|
|
1683
1680
|
const pool = filtered.length > 0 ? filtered : candidates;
|
|
1684
1681
|
const match = pool[0];
|
|
1685
1682
|
if (pool.length <= 1)
|