@herbertgao/pi-extensions 2026.8.4 → 2026.8.5
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 +4 -4
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +24 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +91 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +7 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +7 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +21 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +4 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +5 -8
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +22 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +2 -4
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +8 -0
- package/node_modules/@herbertgao/pi-subagents/package.json +8 -4
- package/node_modules/@herbertgao/pi-subagents/src/agent-color.ts +72 -67
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +255 -0
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +191 -3
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +15 -2
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +289 -113
- package/node_modules/@herbertgao/pi-subagents/src/output-file.ts +24 -1
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +24 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/schedule-menu.ts +9 -8
- package/node_modules/@herbertgao/pi-subagents/src/ui/select-item.ts +48 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +7 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +7 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +16 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +4 -2
- package/node_modules/@narumitw/pi-btw/README.md +8 -7
- package/node_modules/@narumitw/pi-btw/package.json +2 -2
- package/node_modules/@narumitw/pi-btw/src/menu.ts +1 -0
- package/node_modules/pi-lens/CHANGELOG.md +2440 -954
- package/node_modules/pi-lens/README.md +13 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +73 -18
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +21 -4
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +68 -16
- package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -1
- package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +37 -10
- package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +63 -0
- package/node_modules/pi-lens/dist/clients/atomic-write.js +114 -14
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +193 -23
- package/node_modules/pi-lens/dist/clients/biome-client.js +29 -25
- package/node_modules/pi-lens/dist/clients/bootstrap.js +11 -2
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +34 -0
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +192 -0
- package/node_modules/pi-lens/dist/clients/bus-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +47 -5
- package/node_modules/pi-lens/dist/clients/cache-manager.js +97 -9
- package/node_modules/pi-lens/dist/clients/cache-observability.js +301 -14
- package/node_modules/pi-lens/dist/clients/call-graph.js +449 -117
- package/node_modules/pi-lens/dist/clients/child-unref.js +85 -0
- package/node_modules/pi-lens/dist/clients/codebase-model.js +52 -23
- package/node_modules/pi-lens/dist/clients/collateral-test-role.js +40 -0
- package/node_modules/pi-lens/dist/clients/complexity-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/console-guard-install.js +14 -0
- package/node_modules/pi-lens/dist/clients/cooperative-budget.js +42 -0
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/debug-handles.js +206 -0
- package/node_modules/pi-lens/dist/clients/debug-heap.js +167 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +153 -0
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +347 -75
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +61 -11
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +63 -20
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +23 -7
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +8 -18
- package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +8 -5
- package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +35 -0
- package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +17 -8
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +1085 -681
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +14 -0
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +11 -1
- package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +50 -0
- package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +135 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +23 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +5 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +3 -2
- 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 +154 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +14 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +4 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +9 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +4 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.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 +163 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +37 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +13 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +3 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +277 -26
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +22 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +5 -4
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/durable-store.js +97 -0
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +94 -3
- package/node_modules/pi-lens/dist/clients/extension-log.js +139 -0
- package/node_modules/pi-lens/dist/clients/extension-mode.js +73 -0
- package/node_modules/pi-lens/dist/clients/file-kinds.js +57 -0
- package/node_modules/pi-lens/dist/clients/file-role.js +18 -3
- package/node_modules/pi-lens/dist/clients/file-utils.js +56 -34
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +16 -3
- package/node_modules/pi-lens/dist/clients/format-service.js +24 -8
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +8 -0
- package/node_modules/pi-lens/dist/clients/formatters.js +358 -61
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +148 -15
- package/node_modules/pi-lens/dist/clients/git-guard.js +681 -11
- package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +4 -0
- package/node_modules/pi-lens/dist/clients/go-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +8 -0
- package/node_modules/pi-lens/dist/clients/grammar-source.js +12 -4
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +21 -3
- package/node_modules/pi-lens/dist/clients/host-ports.js +31 -0
- package/node_modules/pi-lens/dist/clients/installer/index.js +390 -99
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +142 -172
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +31 -54
- package/node_modules/pi-lens/dist/clients/knip-client.js +15 -36
- package/node_modules/pi-lens/dist/clients/language-policy.js +14 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +13 -7
- package/node_modules/pi-lens/dist/clients/latency-logger.js +23 -1
- package/node_modules/pi-lens/dist/clients/lens-config.js +12 -1
- package/node_modules/pi-lens/dist/clients/lens-engine.js +86 -17
- package/node_modules/pi-lens/dist/clients/lens-events.js +27 -4
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
- package/node_modules/pi-lens/dist/clients/lens-map.js +94 -19
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +30 -0
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +493 -48
- package/node_modules/pi-lens/dist/clients/lsp/config.js +13 -2
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +86 -0
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +1012 -121
- package/node_modules/pi-lens/dist/clients/lsp/index.js +1807 -780
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +32 -26
- package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +83 -0
- package/node_modules/pi-lens/dist/clients/lsp/server.js +196 -32
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +28 -4
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +8 -0
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +248 -0
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +123 -32
- package/node_modules/pi-lens/dist/clients/mcp/ipc.js +157 -24
- package/node_modules/pi-lens/dist/clients/mcp/session.js +216 -8
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +115 -0
- package/node_modules/pi-lens/dist/clients/metrics-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/metrics-history.js +2 -1
- package/node_modules/pi-lens/dist/clients/module-report-lsp.js +5 -0
- package/node_modules/pi-lens/dist/clients/module-report.js +168 -3
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +319 -118
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +120 -5
- package/node_modules/pi-lens/dist/clients/path-utils.js +110 -9
- package/node_modules/pi-lens/dist/clients/pipeline.js +47 -13
- package/node_modules/pi-lens/dist/clients/print-mode.js +21 -0
- package/node_modules/pi-lens/dist/clients/project-changes.js +40 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +3 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +8 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +21 -1
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +86 -9
- package/node_modules/pi-lens/dist/clients/project-report.js +27 -13
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +175 -20
- package/node_modules/pi-lens/dist/clients/project-trust.js +181 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +18 -4
- package/node_modules/pi-lens/dist/clients/read-bridge.js +147 -0
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +159 -1
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +150 -29
- package/node_modules/pi-lens/dist/clients/read-guard.js +185 -4
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +70 -84
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +1122 -221
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +2 -1
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +21 -10
- package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +46 -0
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +57 -6
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +51 -3
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +30 -1
- package/node_modules/pi-lens/dist/clients/ruff-client.js +27 -44
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +107 -73
- package/node_modules/pi-lens/dist/clients/runtime-context.js +36 -12
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +74 -6
- package/node_modules/pi-lens/dist/clients/runtime-session.js +405 -117
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +71 -48
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +218 -23
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +237 -64
- package/node_modules/pi-lens/dist/clients/rust-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +777 -62
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/session-state-store.js +3 -2
- package/node_modules/pi-lens/dist/clients/sg-runner.js +284 -174
- package/node_modules/pi-lens/dist/clients/slow-fs.js +2 -1
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +224 -0
- package/node_modules/pi-lens/dist/clients/source-filter.js +184 -20
- package/node_modules/pi-lens/dist/clients/source-walker.js +66 -10
- package/node_modules/pi-lens/dist/clients/startup-scan.js +15 -16
- package/node_modules/pi-lens/dist/clients/startup-timing.js +1 -1
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +38 -8
- package/node_modules/pi-lens/dist/clients/tool-event.js +35 -0
- package/node_modules/pi-lens/dist/clients/tool-policy.js +388 -39
- package/node_modules/pi-lens/dist/clients/tool-render.js +155 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +6 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +419 -50
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +21 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +7 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +7 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +44 -7
- package/node_modules/pi-lens/dist/clients/user-notify.js +51 -0
- package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +57 -0
- package/node_modules/pi-lens/dist/clients/warm-attach.js +33 -13
- package/node_modules/pi-lens/dist/clients/widget-state.js +300 -43
- package/node_modules/pi-lens/dist/clients/word-index.js +391 -64
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +89 -6
- package/node_modules/pi-lens/dist/index.js +49361 -36888
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +182 -29
- package/node_modules/pi-lens/dist/mcp/server.js +211 -44
- package/node_modules/pi-lens/dist/tools/ast-grep-search.js +93 -27
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +200 -36
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +153 -40
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -3
- package/node_modules/pi-lens/dist/tools/module-report.js +9 -0
- package/node_modules/pi-lens/docs/agent-guide.md +2 -2
- package/node_modules/pi-lens/docs/agent-tools.md +21 -10
- package/node_modules/pi-lens/docs/analysisall.md +192 -0
- package/node_modules/pi-lens/docs/api-ports-inventory.md +165 -0
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +5 -2
- package/node_modules/pi-lens/docs/durable-store-audit-1202.md +32 -0
- package/node_modules/pi-lens/docs/environment-variables.md +44 -0
- package/node_modules/pi-lens/docs/fable.md +27 -0
- package/node_modules/pi-lens/docs/features.md +31 -2
- package/node_modules/pi-lens/docs/globalconfig.md +45 -1
- package/node_modules/pi-lens/docs/language-coverage.md +4 -3
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +2 -2
- package/node_modules/pi-lens/docs/mcp.md +37 -4
- package/node_modules/pi-lens/docs/servercapabilities.md +3 -3
- package/node_modules/pi-lens/docs/settings.md +12 -1
- package/node_modules/pi-lens/docs/tools.md +4 -1
- package/node_modules/pi-lens/docs/usage.md +18 -0
- package/node_modules/pi-lens/package.json +10 -10
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-except-test.yml +49 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-host-path-in-win32-branch-test.yml +87 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-nested-links-test.yml +11 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-raw-json-store-write-test.yml +17 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-win32-isabsolute-for-qualification-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-except.yml +3 -15
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +25 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-nested-links.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +30 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +23 -0
- package/node_modules/pi-lens/rules/tree-sitter-queries/tsx/no-nested-links.yml +4 -6
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml +2 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +55 -2
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +25 -0
- package/node_modules/pi-mcp-adapter/README.md +34 -3
- package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +1 -1
- package/node_modules/pi-mcp-adapter/commands.ts +15 -7
- package/node_modules/pi-mcp-adapter/direct-tools.ts +54 -7
- package/node_modules/pi-mcp-adapter/host-html-template.ts +0 -8
- package/node_modules/pi-mcp-adapter/index.ts +8 -3
- package/node_modules/pi-mcp-adapter/init.ts +29 -5
- package/node_modules/pi-mcp-adapter/lifecycle.ts +0 -4
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +1 -2
- package/node_modules/pi-mcp-adapter/mcp-auth.ts +60 -2
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +45 -9
- package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +22 -20
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +27 -4
- package/node_modules/pi-mcp-adapter/npx-resolver.ts +81 -26
- package/node_modules/pi-mcp-adapter/package.json +3 -3
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +108 -26
- package/node_modules/pi-mcp-adapter/search-ranking.ts +86 -7
- package/node_modules/pi-mcp-adapter/server-manager.ts +36 -7
- package/node_modules/pi-mcp-adapter/session-recovery.ts +8 -2
- package/node_modules/pi-mcp-adapter/tool-approval.ts +48 -7
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +42 -4
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +138 -12
- package/node_modules/pi-mcp-adapter/types.ts +93 -27
- package/node_modules/pi-mcp-adapter/ui-server.ts +20 -1
- package/package.json +11 -12
- package/node_modules/pi-lens/dist/clients/ast-grep-parser.js +0 -86
- package/node_modules/pi-lens/dist/clients/lsp/interactive-install.js +0 -367
- package/node_modules/pi-lens/dist/clients/lsp/lsp-index.js +0 -10
- package/node_modules/pi-lens/dist/clients/lsp/server-strategies.js +0 -5
- package/node_modules/pi-lens/dist/clients/project-metadata.js +0 -690
- package/node_modules/pi-lens/dist/clients/source-groups.js +0 -96
- package/node_modules/pi-lens/dist/clients/startup-marker.js +0 -6
- package/node_modules/pi-lens/dist/clients/types.js +0 -11
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { createReadGuardEditBatchSummary, getReadGuardCorrelationId, logReadGuardEvent, } from "./read-guard-logger.js";
|
|
3
|
+
import { appendProjectChange, } from "./project-changes.js";
|
|
4
|
+
import { normalizeMapKey } from "./path-utils.js";
|
|
5
|
+
const MAX_SAMPLES = 100;
|
|
6
|
+
const MAX_SUMMARIES_PER_CONTEXT = 100;
|
|
7
|
+
export function newLspMutationCorrelationId(toolCallId) {
|
|
8
|
+
return getReadGuardCorrelationId(toolCallId ? { toolCallId } : {});
|
|
9
|
+
}
|
|
10
|
+
function allResults(options) {
|
|
11
|
+
return options.results ?? [];
|
|
12
|
+
}
|
|
13
|
+
function combineResults(results) {
|
|
14
|
+
const files = new Set();
|
|
15
|
+
const fileDetails = [];
|
|
16
|
+
const appliedIndexes = [];
|
|
17
|
+
const paths = [];
|
|
18
|
+
let requestedTotal = 0;
|
|
19
|
+
let appliedTotal = 0;
|
|
20
|
+
let textEdits = 0;
|
|
21
|
+
let create = 0;
|
|
22
|
+
let rename = 0;
|
|
23
|
+
let deleteCount = 0;
|
|
24
|
+
for (const result of results) {
|
|
25
|
+
requestedTotal += result.operationTotal;
|
|
26
|
+
appliedTotal += result.appliedOperationTotal;
|
|
27
|
+
textEdits += result.operationCounts.textEdits;
|
|
28
|
+
create += result.operationCounts.create;
|
|
29
|
+
rename += result.operationCounts.rename;
|
|
30
|
+
deleteCount += result.operationCounts.delete;
|
|
31
|
+
for (const index of result.appliedOperationIndexes)
|
|
32
|
+
appliedIndexes.push(index);
|
|
33
|
+
for (const file of result.files) {
|
|
34
|
+
if (!files.has(file)) {
|
|
35
|
+
files.add(file);
|
|
36
|
+
paths.push(file);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
fileDetails.push(...result.fileDetails);
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
requestedTotal,
|
|
43
|
+
appliedTotal,
|
|
44
|
+
appliedIndexes,
|
|
45
|
+
files: [...files],
|
|
46
|
+
fileDetails,
|
|
47
|
+
textEdits,
|
|
48
|
+
create,
|
|
49
|
+
rename,
|
|
50
|
+
delete: deleteCount,
|
|
51
|
+
paths,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function uniqueDetails(files, fileDetails) {
|
|
55
|
+
const byPath = new Map();
|
|
56
|
+
for (const detail of fileDetails) {
|
|
57
|
+
const key = normalizeMapKey(path.resolve(detail.filePath));
|
|
58
|
+
const previous = byPath.get(key);
|
|
59
|
+
if (!previous) {
|
|
60
|
+
byPath.set(key, detail);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
byPath.set(key, {
|
|
64
|
+
filePath: previous.filePath,
|
|
65
|
+
range: previous.range && detail.range
|
|
66
|
+
? {
|
|
67
|
+
start: Math.min(previous.range.start, detail.range.start),
|
|
68
|
+
end: Math.max(previous.range.end, detail.range.end),
|
|
69
|
+
}
|
|
70
|
+
: previous.range ?? detail.range,
|
|
71
|
+
importsChanged: previous.importsChanged || detail.importsChanged,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return files.map((filePath) => byPath.get(normalizeMapKey(path.resolve(filePath))) ?? {
|
|
75
|
+
filePath,
|
|
76
|
+
// Resource operations have no already-computed text range. A small
|
|
77
|
+
// range is still enough to invalidate the touched-file turn state;
|
|
78
|
+
// never synchronously re-read the whole file here.
|
|
79
|
+
range: { start: 1, end: 1 },
|
|
80
|
+
importsChanged: true,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function bookkeepLspMutation(context, files, fileDetails) {
|
|
84
|
+
const details = uniqueDetails(files, fileDetails);
|
|
85
|
+
for (const detail of details) {
|
|
86
|
+
const filePath = path.resolve(detail.filePath);
|
|
87
|
+
if (context.readGuard) {
|
|
88
|
+
try {
|
|
89
|
+
context.readGuard.recordWritten(filePath);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
context.dbg?.(`lsp mutation read-guard stamp failed for ${filePath}: ${err}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const runtime = context.runtime;
|
|
96
|
+
if (runtime?.bumpFileSeq) {
|
|
97
|
+
const { projectSeq, fileSeq } = runtime.bumpFileSeq(filePath);
|
|
98
|
+
try {
|
|
99
|
+
appendProjectChange(context.cwd, {
|
|
100
|
+
seq: projectSeq,
|
|
101
|
+
timestamp: new Date().toISOString(),
|
|
102
|
+
sessionId: runtime.telemetrySessionId ?? "unknown",
|
|
103
|
+
turnIndex: runtime.turnIndex ?? 0,
|
|
104
|
+
source: context.source,
|
|
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
|
+
}
|
|
114
|
+
if (context.cacheManager) {
|
|
115
|
+
try {
|
|
116
|
+
context.cacheManager.addModifiedRange(filePath, detail.range ?? { start: 1, end: 1 }, detail.importsChanged ?? true, context.cwd, runtime?.telemetrySessionId);
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
context.dbg?.(`lsp mutation modified-range tracking failed for ${filePath}: ${err}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (context.recordAutofix && context.source === "autofix") {
|
|
123
|
+
const key = normalizeMapKey(filePath);
|
|
124
|
+
const seen = context.autofixRecordedPaths ?? new Set();
|
|
125
|
+
context.autofixRecordedPaths = seen;
|
|
126
|
+
if (!seen.has(key)) {
|
|
127
|
+
if (seen.size >= MAX_SAMPLES) {
|
|
128
|
+
const oldest = seen.values().next().value;
|
|
129
|
+
if (oldest)
|
|
130
|
+
seen.delete(oldest);
|
|
131
|
+
}
|
|
132
|
+
seen.add(key);
|
|
133
|
+
context.recordAutofix(filePath);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (context.publishFilesTouched && files.length > 0) {
|
|
138
|
+
context.publishFilesTouched(files);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function telemetryFor(context, options) {
|
|
142
|
+
const combined = combineResults(allResults(options));
|
|
143
|
+
const requestedTotal = options.requestedTotal ?? combined.requestedTotal;
|
|
144
|
+
const appliedTotal = combined.appliedTotal;
|
|
145
|
+
const requestedIndexes = Array.from({ length: Math.min(requestedTotal, MAX_SAMPLES) }, (_, index) => index);
|
|
146
|
+
const rejectedTotal = Math.max(0, requestedTotal - appliedTotal);
|
|
147
|
+
const rejectedReasons = Array.from({ length: Math.min(rejectedTotal, MAX_SAMPLES) }, (_, index) => ({ index, code: "write_failed" }));
|
|
148
|
+
const status = options.status ?? (appliedTotal > 0 ? "success" : "skipped");
|
|
149
|
+
const editBatchSummary = createReadGuardEditBatchSummary({
|
|
150
|
+
requestedIndexes,
|
|
151
|
+
requestedTotal,
|
|
152
|
+
resolvedIndexes: requestedIndexes,
|
|
153
|
+
resolvedTotal: requestedTotal,
|
|
154
|
+
rejectedReasons,
|
|
155
|
+
rejectedTotal,
|
|
156
|
+
appliedIndexes: combined.appliedIndexes,
|
|
157
|
+
appliedTotal,
|
|
158
|
+
participantIds: [context.correlationId],
|
|
159
|
+
participantTotal: 1,
|
|
160
|
+
commitStatus: status === "failed"
|
|
161
|
+
? "failed"
|
|
162
|
+
: appliedTotal > 0
|
|
163
|
+
? "committed"
|
|
164
|
+
: "no_changes",
|
|
165
|
+
terminalStatus: status,
|
|
166
|
+
});
|
|
167
|
+
return {
|
|
168
|
+
editBatchSummary,
|
|
169
|
+
operationCounts: {
|
|
170
|
+
requested: requestedTotal,
|
|
171
|
+
applied: appliedTotal,
|
|
172
|
+
textEdits: combined.textEdits,
|
|
173
|
+
create: combined.create,
|
|
174
|
+
rename: combined.rename,
|
|
175
|
+
delete: combined.delete,
|
|
176
|
+
},
|
|
177
|
+
sampledPaths: combined.paths.slice(0, MAX_SAMPLES),
|
|
178
|
+
sampledPathsTotal: combined.paths.length,
|
|
179
|
+
sampledPathsTruncated: combined.paths.length > MAX_SAMPLES,
|
|
180
|
+
considered: options.considered,
|
|
181
|
+
completed: options.completed,
|
|
182
|
+
failedCount: options.failedCount,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
export function recordLspMutation(context, options = {}) {
|
|
186
|
+
const results = allResults(options);
|
|
187
|
+
const combined = combineResults(results);
|
|
188
|
+
if (options.bookkeep !== false && combined.files.length > 0) {
|
|
189
|
+
bookkeepLspMutation(context, combined.files, combined.fileDetails);
|
|
190
|
+
}
|
|
191
|
+
const telemetry = telemetryFor(context, options);
|
|
192
|
+
if (context.emitSummary !== false) {
|
|
193
|
+
const summaryCount = context.summaryCount ?? 0;
|
|
194
|
+
context.summaryEmitted = true;
|
|
195
|
+
if (summaryCount < MAX_SUMMARIES_PER_CONTEXT) {
|
|
196
|
+
context.summaryCount = summaryCount + 1;
|
|
197
|
+
logReadGuardEvent({
|
|
198
|
+
event: "edit_batch_summary",
|
|
199
|
+
correlationId: context.correlationId,
|
|
200
|
+
filePath: combined.files[0] ?? context.cwd,
|
|
201
|
+
metadata: {
|
|
202
|
+
tool: context.tool,
|
|
203
|
+
source: context.source,
|
|
204
|
+
outcome: telemetry.editBatchSummary.terminalStatus,
|
|
205
|
+
// The outer correlation identifies the soliciting tool call; the
|
|
206
|
+
// bounded sequence distinguishes multiple applyEdit requests within it.
|
|
207
|
+
summaryIndex: summaryCount,
|
|
208
|
+
editBatchSummary: telemetry.editBatchSummary,
|
|
209
|
+
operationCounts: telemetry.operationCounts,
|
|
210
|
+
sampledPaths: telemetry.sampledPaths,
|
|
211
|
+
sampledPathsTotal: telemetry.sampledPathsTotal,
|
|
212
|
+
sampledPathsTruncated: telemetry.sampledPathsTruncated,
|
|
213
|
+
considered: telemetry.considered,
|
|
214
|
+
completed: telemetry.completed,
|
|
215
|
+
failedCount: telemetry.failedCount,
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
else if (!context.summaryOverflowed) {
|
|
220
|
+
context.summaryOverflowed = true;
|
|
221
|
+
logReadGuardEvent({
|
|
222
|
+
event: "edit_batch_summary_overflow",
|
|
223
|
+
correlationId: context.correlationId,
|
|
224
|
+
filePath: combined.files[0] ?? context.cwd,
|
|
225
|
+
metadata: {
|
|
226
|
+
tool: context.tool,
|
|
227
|
+
source: context.source,
|
|
228
|
+
summaryLimit: MAX_SUMMARIES_PER_CONTEXT,
|
|
229
|
+
suppressedSummaries: "one or more",
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return telemetry;
|
|
235
|
+
}
|
|
236
|
+
export function recordLspMutationBatch(context, options) {
|
|
237
|
+
const previous = context.emitSummary;
|
|
238
|
+
context.emitSummary = true;
|
|
239
|
+
try {
|
|
240
|
+
return recordLspMutation(context, options);
|
|
241
|
+
}
|
|
242
|
+
finally {
|
|
243
|
+
context.emitSummary = previous;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
export function recordLspMutationOutcome(context, status) {
|
|
247
|
+
return recordLspMutation(context, { status, requestedTotal: 0 });
|
|
248
|
+
}
|
|
@@ -13,16 +13,19 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import * as fs from "node:fs";
|
|
15
15
|
import * as path from "node:path";
|
|
16
|
-
import { CacheManager } from "../cache-manager.js";
|
|
16
|
+
import { CacheManager, MCP_TURN_STATE_OWNER_ID } from "../cache-manager.js";
|
|
17
17
|
import { CASCADE_GRAPH_KINDS, dispatchLintWithResult, getLatencyReports, } from "../dispatch/integration.js";
|
|
18
18
|
import { FactStore } from "../dispatch/fact-store.js";
|
|
19
19
|
import { detectFileKind } from "../file-kinds.js";
|
|
20
20
|
import { getDiagnosticTracker } from "../diagnostic-tracker.js";
|
|
21
21
|
import { getLSPService } from "../lsp/index.js";
|
|
22
|
+
import { PathKeyedMap } from "../path-keyed-map.js";
|
|
23
|
+
import { normalizeMapKey } from "../path-utils.js";
|
|
22
24
|
import { loadProjectSnapshot } from "../project-snapshot.js";
|
|
23
25
|
import { buildOrUpdateGraph } from "../review-graph/service.js";
|
|
24
26
|
import { recordDiagnostics } from "../widget-state.js";
|
|
25
27
|
import { deserializeWordIndex, removeWordIndexDocument, scheduleWordIndexPersist, updateWordIndexDocument, WORD_INDEX_MAX_BYTES, } from "../word-index.js";
|
|
28
|
+
import { logWordIndex } from "../word-index-logger.js";
|
|
26
29
|
import { createMcpHost } from "./host-shim.js";
|
|
27
30
|
// #536: module-scoped FactStore for the warm-analyze graph seam, mirroring the
|
|
28
31
|
// per-edit cascade path's own module-level `sessionFacts` singleton
|
|
@@ -43,7 +46,59 @@ const warmGraphFacts = new FactStore();
|
|
|
43
46
|
// nothing usable" (index missing or pre-phase-2/no-forward-map), distinct from
|
|
44
47
|
// "never checked" (key absent) — avoids re-attempting a snapshot load with no
|
|
45
48
|
// forward index on every single analyze call.
|
|
46
|
-
const
|
|
49
|
+
const DEFAULT_WORD_INDEX_IDLE_EVICT_MS = 20 * 60_000;
|
|
50
|
+
const DEFAULT_WORD_INDEX_MAX_WARM_ROOTS = 8;
|
|
51
|
+
const warmWordIndexes = new PathKeyedMap(normalizeMapKey);
|
|
52
|
+
function positiveEnv(name, fallback) {
|
|
53
|
+
const parsed = Number.parseInt(process.env[name] ?? "", 10);
|
|
54
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
55
|
+
}
|
|
56
|
+
function idleEvictMs() {
|
|
57
|
+
return positiveEnv("PI_LENS_WORD_INDEX_IDLE_EVICT_MS", DEFAULT_WORD_INDEX_IDLE_EVICT_MS);
|
|
58
|
+
}
|
|
59
|
+
function maxWarmRoots() {
|
|
60
|
+
return positiveEnv("PI_LENS_WORD_INDEX_MAX_WARM_ROOTS", DEFAULT_WORD_INDEX_MAX_WARM_ROOTS);
|
|
61
|
+
}
|
|
62
|
+
function clearWarmWordIndexTimer(entry) {
|
|
63
|
+
if (entry.timer)
|
|
64
|
+
clearTimeout(entry.timer);
|
|
65
|
+
entry.timer = undefined;
|
|
66
|
+
}
|
|
67
|
+
function evictWarmWordIndex(key, entry, reason) {
|
|
68
|
+
if (entry.leases > 0 || warmWordIndexes.get(key) !== entry)
|
|
69
|
+
return false;
|
|
70
|
+
clearWarmWordIndexTimer(entry);
|
|
71
|
+
warmWordIndexes.delete(key);
|
|
72
|
+
logWordIndex({
|
|
73
|
+
phase: "warm_cache_evicted",
|
|
74
|
+
cwd: key,
|
|
75
|
+
trigger: "mcp",
|
|
76
|
+
reason,
|
|
77
|
+
});
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
function scheduleWarmWordIndexIdleEviction(key, entry) {
|
|
81
|
+
clearWarmWordIndexTimer(entry);
|
|
82
|
+
const generation = ++entry.generation;
|
|
83
|
+
const timer = setTimeout(() => {
|
|
84
|
+
entry.timer = undefined;
|
|
85
|
+
if (warmWordIndexes.get(key) !== entry || entry.generation !== generation)
|
|
86
|
+
return;
|
|
87
|
+
if (!evictWarmWordIndex(key, entry, "idle"))
|
|
88
|
+
scheduleWarmWordIndexIdleEviction(key, entry);
|
|
89
|
+
}, idleEvictMs());
|
|
90
|
+
timer.unref?.();
|
|
91
|
+
entry.timer = timer;
|
|
92
|
+
}
|
|
93
|
+
function enforceWarmWordIndexLruCap() {
|
|
94
|
+
while (warmWordIndexes.size > maxWarmRoots()) {
|
|
95
|
+
const victim = [...warmWordIndexes.entries()]
|
|
96
|
+
.filter(([, entry]) => entry.leases === 0)
|
|
97
|
+
.sort(([, a], [, b]) => a.lastUsedAt - b.lastUsedAt)[0];
|
|
98
|
+
if (!victim || !evictWarmWordIndex(victim[0], victim[1], "lru"))
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
47
102
|
/**
|
|
48
103
|
* Look up (loading from the persisted snapshot on first use per cwd) the warm
|
|
49
104
|
* in-memory word index this analyze facade keeps mutated in place. Exported so
|
|
@@ -52,26 +107,57 @@ const warmWordIndexes = new Map();
|
|
|
52
107
|
* following a warm `pilens_analyze` call in the SAME process would read a
|
|
53
108
|
* stale on-disk snapshot until the debounced persist (default 1500ms) flushes.
|
|
54
109
|
*/
|
|
55
|
-
export function
|
|
110
|
+
export function acquireWarmWordIndex(cwd) {
|
|
56
111
|
const key = path.resolve(cwd);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
112
|
+
let entry = warmWordIndexes.get(key);
|
|
113
|
+
if (!entry) {
|
|
114
|
+
const snapshot = loadProjectSnapshot(key);
|
|
115
|
+
const index = deserializeWordIndex(snapshot?.wordIndex) ?? undefined;
|
|
116
|
+
entry = {
|
|
117
|
+
index: index?.forward ? index : undefined,
|
|
118
|
+
timer: undefined,
|
|
119
|
+
leases: 0,
|
|
120
|
+
lastUsedAt: Date.now(),
|
|
121
|
+
generation: 0,
|
|
122
|
+
};
|
|
123
|
+
warmWordIndexes.set(key, entry);
|
|
124
|
+
}
|
|
125
|
+
entry.leases++;
|
|
126
|
+
entry.lastUsedAt = Date.now();
|
|
127
|
+
scheduleWarmWordIndexIdleEviction(key, entry);
|
|
128
|
+
enforceWarmWordIndexLruCap();
|
|
129
|
+
let released = false;
|
|
130
|
+
return {
|
|
131
|
+
index: entry.index,
|
|
132
|
+
release() {
|
|
133
|
+
if (released)
|
|
134
|
+
return;
|
|
135
|
+
released = true;
|
|
136
|
+
entry.leases = Math.max(0, entry.leases - 1);
|
|
137
|
+
entry.lastUsedAt = Date.now();
|
|
138
|
+
if (warmWordIndexes.get(key) === entry) {
|
|
139
|
+
scheduleWarmWordIndexIdleEviction(key, entry);
|
|
140
|
+
enforceWarmWordIndexLruCap();
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
};
|
|
67
144
|
}
|
|
68
145
|
/**
|
|
69
146
|
* Test-only reset — the module-level warm cache otherwise survives across
|
|
70
147
|
* unrelated test cases in the same vitest worker.
|
|
71
148
|
*/
|
|
72
149
|
export function _resetWarmWordIndexCacheForTests() {
|
|
150
|
+
for (const entry of warmWordIndexes.values())
|
|
151
|
+
clearWarmWordIndexTimer(entry);
|
|
73
152
|
warmWordIndexes.clear();
|
|
74
153
|
}
|
|
154
|
+
export function _getWarmWordIndexCacheStateForTests() {
|
|
155
|
+
return {
|
|
156
|
+
size: warmWordIndexes.size,
|
|
157
|
+
keys: [...warmWordIndexes.keys()],
|
|
158
|
+
timers: [...warmWordIndexes.values()].flatMap((entry) => entry.timer ? [entry.timer] : []),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
75
161
|
// Generous warm-up budgets: a cold language server needs to spawn AND publish
|
|
76
162
|
// diagnostics. The per-edit dispatch runner caps these tightly (spawn budget +
|
|
77
163
|
// 2500ms) for latency; a review tool prioritises completeness, so we pre-warm
|
|
@@ -167,11 +253,11 @@ export async function analyzeFile(filePath, cwd, options = {}) {
|
|
|
167
253
|
}
|
|
168
254
|
if (options.registerTurnState) {
|
|
169
255
|
// Full-file range, importsChanged=true (conservative → dep/knip re-check
|
|
170
|
-
// broadly).
|
|
171
|
-
//
|
|
256
|
+
// broadly). Clear any stale pi session ID because the MCP Stop route owns
|
|
257
|
+
// this workspace-scoped worklist independently. Best-effort.
|
|
172
258
|
try {
|
|
173
259
|
const lineCount = fs.readFileSync(absPath, "utf8").split("\n").length;
|
|
174
|
-
new CacheManager().addModifiedRange(absPath, { start: 1, end: lineCount }, true, cwd);
|
|
260
|
+
new CacheManager().addModifiedRange(absPath, { start: 1, end: lineCount }, true, cwd, options.ownerId ?? MCP_TURN_STATE_OWNER_ID, "mcp");
|
|
175
261
|
}
|
|
176
262
|
catch {
|
|
177
263
|
// unreadable — skip turn-state registration
|
|
@@ -215,24 +301,30 @@ export async function analyzeFile(filePath, cwd, options = {}) {
|
|
|
215
301
|
// INTERNALLY (PathKeyedMap), so this edit-form key and the build path's
|
|
216
302
|
// walk-derived key converge on the same entry regardless of casing/
|
|
217
303
|
// separator — the old duplicate-orphan hazard is gone at the map layer.
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
304
|
+
const warmLease = acquireWarmWordIndex(cwd);
|
|
305
|
+
const warmIndex = warmLease.index;
|
|
306
|
+
try {
|
|
307
|
+
if (warmIndex) {
|
|
308
|
+
try {
|
|
309
|
+
const content = fs.readFileSync(absPath, "utf8");
|
|
310
|
+
const byteLength = Buffer.byteLength(content, "utf-8");
|
|
311
|
+
if (byteLength > WORD_INDEX_MAX_BYTES) {
|
|
312
|
+
removeWordIndexDocument(warmIndex, absPath);
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
updateWordIndexDocument(warmIndex, { path: absPath, content });
|
|
316
|
+
}
|
|
317
|
+
scheduleWordIndexPersist(cwd, warmIndex);
|
|
225
318
|
}
|
|
226
|
-
|
|
227
|
-
|
|
319
|
+
catch {
|
|
320
|
+
// unreadable/deleted, or an update failure — best-effort, same as the
|
|
321
|
+
// graph update above.
|
|
228
322
|
}
|
|
229
|
-
scheduleWordIndexPersist(cwd, warmIndex);
|
|
230
|
-
}
|
|
231
|
-
catch {
|
|
232
|
-
// unreadable/deleted, or an update failure — best-effort, same as the
|
|
233
|
-
// graph update above.
|
|
234
323
|
}
|
|
235
324
|
}
|
|
325
|
+
finally {
|
|
326
|
+
warmLease.release();
|
|
327
|
+
}
|
|
236
328
|
}
|
|
237
329
|
// dispatchForFile appended a latency report during the call above. Match the
|
|
238
330
|
// newly-added report for this exact path; fall back to the most recent new
|
|
@@ -243,8 +335,7 @@ export async function analyzeFile(filePath, cwd, options = {}) {
|
|
|
243
335
|
const lspRunner = latencyReport?.runners.find((runner) => runner.runnerId === "lsp");
|
|
244
336
|
const lsp = lspRunner
|
|
245
337
|
? {
|
|
246
|
-
ran: lspRunner.status !== "skipped" &&
|
|
247
|
-
lspRunner.status !== "when_skipped",
|
|
338
|
+
ran: lspRunner.status !== "skipped" && lspRunner.status !== "when_skipped",
|
|
248
339
|
status: lspRunner.status,
|
|
249
340
|
diagnosticCount: lspRunner.diagnosticCount,
|
|
250
341
|
durationMs: lspRunner.durationMs,
|