pi-lens 4.1.2 → 4.1.4
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/CHANGELOG.md +1308 -0
- package/README.md +3 -0
- package/config/biome/core.jsonc +11 -2
- package/config/dependency-cruiser-eager-allowlist.json +91 -0
- package/dist/clients/actionable-warnings-logger.js +18 -3
- package/dist/clients/actionable-warnings.js +927 -80
- package/dist/clients/agent-behavior-client.js +13 -4
- package/dist/clients/ast-grep-client.js +136 -9
- package/dist/clients/ast-grep-rule-manager.js +60 -5
- package/dist/clients/ast-grep-tool-logger.js +2 -2
- package/dist/clients/availability-probe-flight.js +12 -0
- package/dist/clients/bash-file-access.js +1 -3
- package/dist/clients/biome-client.js +16 -2
- package/dist/clients/blocker-freshness.js +34 -0
- package/dist/clients/bootstrap.js +509 -73
- package/dist/clients/bounded-cache.js +152 -12
- package/dist/clients/bounded-telemetry.js +115 -23
- package/dist/clients/build-identity.js +95 -0
- package/dist/clients/bundled-resource-health.js +113 -0
- package/dist/clients/bus-events-logger.js +2 -2
- package/dist/clients/bus-publish.js +3 -0
- package/dist/clients/cache/rule-cache.js +33 -5
- package/dist/clients/cache-manager.js +105 -6
- package/dist/clients/cache-observability.js +46 -19
- package/dist/clients/cargo-manifest.js +422 -0
- package/dist/clients/cascade-logger.js +17 -3
- package/dist/clients/code-quality-warnings.js +13 -3
- package/dist/clients/complexity-client.js +16 -5
- package/dist/clients/config-core/deny.js +221 -0
- package/dist/clients/config-core/index.js +47 -0
- package/dist/clients/config-core/merge.js +357 -0
- package/dist/clients/config-core/normalize.js +340 -0
- package/dist/clients/config-core/process-spec.js +248 -0
- package/dist/clients/config-core/provenance.js +171 -0
- package/dist/clients/config-core/records.js +218 -0
- package/dist/clients/config-core/resolve.js +125 -0
- package/dist/clients/config-core/safe-object.js +78 -0
- package/dist/clients/config-core/schema.js +167 -0
- package/dist/clients/config-diagnostic-codes.js +281 -0
- package/dist/clients/config-locations.js +160 -0
- package/dist/clients/config-resolve.js +789 -0
- package/dist/clients/config-schema.js +197 -0
- package/dist/clients/config-warn.js +407 -0
- package/dist/clients/dead-code-client.js +33 -25
- package/dist/clients/dead-code-logger.js +2 -2
- package/dist/clients/deadline-utils.js +178 -0
- package/dist/clients/debug-handles.js +2 -2
- package/dist/clients/debug-heap.js +3 -3
- package/dist/clients/deferred-lsp-work.js +106 -0
- package/dist/clients/degradation-ledger.js +166 -8
- package/dist/clients/demoted-finding-render.js +14 -0
- package/dist/clients/dependency-checker.js +28 -22
- package/dist/clients/deps/minimatch.js +1 -1
- package/dist/clients/diagnostic-line-freshness.js +12 -9
- package/dist/clients/diagnostic-logger.js +14 -4
- package/dist/clients/dispatch/collect-later-tier.js +39 -0
- package/dist/clients/dispatch/dispatcher.js +304 -19
- package/dist/clients/dispatch/fact-store.js +328 -9
- package/dist/clients/dispatch/integration.js +214 -107
- package/dist/clients/dispatch/pending-runner-findings.js +87 -0
- package/dist/clients/dispatch/plan.js +21 -5
- package/dist/clients/dispatch/runners/actionlint.js +0 -1
- package/dist/clients/dispatch/runners/ast-grep-napi.js +550 -77
- package/dist/clients/dispatch/runners/biome-check.js +0 -1
- package/dist/clients/dispatch/runners/cpp-check.js +0 -1
- package/dist/clients/dispatch/runners/credo.js +0 -1
- package/dist/clients/dispatch/runners/cue-vet.js +0 -1
- package/dist/clients/dispatch/runners/dart-analyze.js +0 -1
- package/dist/clients/dispatch/runners/detekt.js +0 -1
- package/dist/clients/dispatch/runners/dotnet-build.js +0 -1
- package/dist/clients/dispatch/runners/elixir-check.js +0 -1
- package/dist/clients/dispatch/runners/eslint.js +5 -2
- package/dist/clients/dispatch/runners/fact-rules.js +0 -1
- package/dist/clients/dispatch/runners/fish-indent.js +0 -1
- package/dist/clients/dispatch/runners/gleam-check.js +0 -1
- package/dist/clients/dispatch/runners/go-vet.js +1 -3
- package/dist/clients/dispatch/runners/golangci-lint.js +0 -1
- package/dist/clients/dispatch/runners/hadolint.js +0 -1
- package/dist/clients/dispatch/runners/helm-lint.js +16 -4
- package/dist/clients/dispatch/runners/helm-render.js +54 -10
- package/dist/clients/dispatch/runners/htmlhint.js +0 -1
- package/dist/clients/dispatch/runners/index.js +1 -3
- package/dist/clients/dispatch/runners/javac.js +0 -1
- package/dist/clients/dispatch/runners/ktlint.js +0 -1
- package/dist/clients/dispatch/runners/lsp.js +37 -2
- package/dist/clients/dispatch/runners/markdownlint.js +4 -2
- package/dist/clients/dispatch/runners/mypy.js +0 -1
- package/dist/clients/dispatch/runners/oxlint.js +24 -22
- package/dist/clients/dispatch/runners/php-lint.js +0 -1
- package/dist/clients/dispatch/runners/phpstan.js +0 -1
- package/dist/clients/dispatch/runners/prisma-validate.js +0 -1
- package/dist/clients/dispatch/runners/psscriptanalyzer.js +4 -1
- package/dist/clients/dispatch/runners/pyright.js +7 -4
- package/dist/clients/dispatch/runners/rubocop.js +0 -1
- package/dist/clients/dispatch/runners/ruff.js +0 -1
- package/dist/clients/dispatch/runners/rust-clippy.js +9 -6
- package/dist/clients/dispatch/runners/shellcheck.js +0 -1
- package/dist/clients/dispatch/runners/shfmt.js +0 -1
- package/dist/clients/dispatch/runners/spellcheck.js +0 -1
- package/dist/clients/dispatch/runners/spotbugs.js +0 -1
- package/dist/clients/dispatch/runners/sqlfluff.js +0 -1
- package/dist/clients/dispatch/runners/stylelint.js +0 -1
- package/dist/clients/dispatch/runners/swiftlint.js +0 -1
- package/dist/clients/dispatch/runners/taplo.js +0 -1
- package/dist/clients/dispatch/runners/terragrunt.js +0 -1
- package/dist/clients/dispatch/runners/tflint.js +0 -1
- package/dist/clients/dispatch/runners/tree-sitter.js +0 -1
- package/dist/clients/dispatch/runners/trivy-config.js +0 -1
- package/dist/clients/dispatch/runners/utils/availability-policy.js +3 -0
- package/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +3 -4
- package/dist/clients/dispatch/runners/utils/runner-helpers.js +270 -105
- package/dist/clients/dispatch/runners/utils/spawn-outcome.js +4 -0
- package/dist/clients/dispatch/runners/utils/tool-failure.js +19 -7
- package/dist/clients/dispatch/runners/utils/toolchain-availability.js +89 -26
- package/dist/clients/dispatch/runners/vale.js +0 -1
- package/dist/clients/dispatch/runners/yaml-rule-parser.js +51 -17
- package/dist/clients/dispatch/runners/yamllint.js +0 -1
- package/dist/clients/dispatch/runners/zig-check.js +0 -1
- package/dist/clients/disposition-logger.js +3 -3
- package/dist/clients/effective-config.js +403 -0
- package/dist/clients/error-class.js +23 -0
- package/dist/clients/event-loop-hold.js +274 -0
- package/dist/clients/event-loop-monitor.js +66 -1
- package/dist/clients/extension-log.js +2 -2
- package/dist/clients/feature-hints.js +2 -1
- package/dist/clients/file-time.js +6 -1
- package/dist/clients/file-utils.js +266 -13
- package/dist/clients/finding-delivery-gate.js +55 -13
- package/dist/clients/format-service.js +6 -1
- package/dist/clients/formatters.js +303 -104
- package/dist/clients/freshness-cadence.js +17 -0
- package/dist/clients/generated-artifacts.js +114 -19
- package/dist/clients/generation-guard.js +4 -9
- package/dist/clients/git-guard.js +198 -48
- package/dist/clients/git-tracked-ignore.js +32 -1
- package/dist/clients/go-client.js +39 -0
- package/dist/clients/govulncheck-client.js +5 -1
- package/dist/clients/gradle-ktfmt-style.js +252 -0
- package/dist/clients/gzip-stage-write.js +7 -0
- package/dist/clients/hashline-anchor.js +424 -0
- package/dist/clients/hook-budgets.js +76 -0
- package/dist/clients/host-edit-normalize.js +5 -2
- package/dist/clients/host-ports.js +1 -1
- package/dist/clients/installer/index.js +200 -84
- package/dist/clients/installer/managed-tool-refresh.js +3 -1
- package/dist/clients/instance-reaper.js +108 -243
- package/dist/clients/instance-registry-lock.js +145 -0
- package/dist/clients/instance-registry.js +435 -122
- package/dist/clients/jscpd-client.js +6 -1
- package/dist/clients/language-profile.js +4 -2
- package/dist/clients/language-registry.js +595 -0
- package/dist/clients/latency-logger.js +179 -3
- package/dist/clients/ledger-bounds.js +13 -0
- package/dist/clients/lens-config.js +141 -30
- package/dist/clients/lens-engine.js +30 -37
- package/dist/clients/lens-flag-registry.js +67 -6
- package/dist/clients/lens-map.js +3 -1
- package/dist/clients/log-cleanup.js +2 -2
- package/dist/clients/lsp/aggregation.js +3 -1
- package/dist/clients/lsp/cascade-tier.js +4 -0
- package/dist/clients/lsp/client.js +672 -49
- package/dist/clients/lsp/config.js +504 -156
- package/dist/clients/lsp/diagnostic-binding.js +10 -5
- package/dist/clients/lsp/edits.js +15 -2
- package/dist/clients/lsp/index.js +1179 -247
- package/dist/clients/lsp/jvm-runtime.js +5 -0
- package/dist/clients/lsp/language.js +18 -169
- package/dist/clients/lsp/launch.js +38 -9
- package/dist/clients/lsp/pending-aux-coverage.js +113 -12
- package/dist/clients/lsp/server.js +426 -160
- package/dist/clients/lsp/session-roots.js +192 -0
- package/dist/clients/lsp/spawn-history.js +2 -7
- package/dist/clients/lsp/tsserver-sync.js +9 -2
- package/dist/clients/lsp/workspace-diagnostics-cache.js +17 -7
- package/dist/clients/lsp/workspace-sweep-hold.js +32 -23
- package/dist/clients/lsp-mutation.js +179 -23
- package/dist/clients/map-with-concurrency.js +36 -0
- package/dist/clients/mcp/analyze.js +45 -10
- package/dist/clients/mcp/session.js +19 -17
- package/dist/clients/memory-sampler.js +28 -1
- package/dist/clients/message-end-attribution.js +30 -0
- package/dist/clients/metrics-history.js +21 -4
- package/dist/clients/middle-man-analysis.js +2 -4
- package/dist/clients/module-report.js +20 -45
- package/dist/clients/mutating-tool.js +651 -0
- package/dist/clients/mutation-attribution.js +368 -0
- package/dist/clients/mutation-bridge.js +240 -0
- package/dist/clients/ndjson-logger.js +247 -20
- package/dist/clients/observed-mutation-sources.js +101 -0
- package/dist/clients/observed-mutation.js +1215 -0
- package/dist/clients/opaque-mutation-scan.js +300 -40
- package/dist/clients/opengrep-config.js +4 -0
- package/dist/clients/package-manager.js +201 -44
- package/dist/clients/partial-edit-apply.js +359 -80
- package/dist/clients/path-attribution-telemetry.js +23 -7
- package/dist/clients/path-keyed-map.js +35 -3
- package/dist/clients/path-utils.js +460 -13
- package/dist/clients/persist-debounce.js +8 -1
- package/dist/clients/php-cs-fixer-config.js +114 -0
- package/dist/clients/pipeline.js +77 -24
- package/dist/clients/probe-home-state.js +228 -0
- package/dist/clients/process-bridge.js +66 -0
- package/dist/clients/process-singletons.js +210 -0
- package/dist/clients/process-snapshot.js +68 -0
- package/dist/clients/project-diagnostics/fresh-fetch.js +4 -3
- package/dist/clients/project-diagnostics/runner-adapters/madge.js +2 -1
- package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +27 -3
- package/dist/clients/project-diagnostics/scanner.js +61 -24
- package/dist/clients/project-lens-config.js +393 -122
- package/dist/clients/project-snapshot.js +85 -35
- package/dist/clients/python-environment.js +217 -0
- package/dist/clients/python-provenance.js +639 -0
- package/dist/clients/quiet-window.js +6 -1
- package/dist/clients/read-bridge.js +13 -21
- package/dist/clients/read-expansion.js +9 -46
- package/dist/clients/read-guard-logger.js +39 -6
- package/dist/clients/read-guard-tool-lines.js +364 -212
- package/dist/clients/read-guard.js +95 -7
- package/dist/clients/recent-touches.js +17 -5
- package/dist/clients/resource-sampler.js +195 -96
- package/dist/clients/review-graph/builder.js +752 -132
- package/dist/clients/review-graph/service.js +55 -3
- package/dist/clients/review-graph/shared-extraction-ir.js +7 -15
- package/dist/clients/review-graph/tsconfig-paths.js +5 -1
- package/dist/clients/review-graph/workspace-modules.js +10 -74
- package/dist/clients/review-graph-logger.js +30 -4
- package/dist/clients/runtime-agent-end.js +18 -2
- package/dist/clients/runtime-context.js +49 -16
- package/dist/clients/runtime-coordinator.js +93 -6
- package/dist/clients/runtime-session.js +169 -34
- package/dist/clients/runtime-tool-call.js +183 -35
- package/dist/clients/runtime-tool-result.js +894 -241
- package/dist/clients/runtime-turn.js +1264 -74
- package/dist/clients/rust-client.js +31 -0
- package/dist/clients/safe-spawn.js +191 -28
- package/dist/clients/sanitize.js +7 -1
- package/dist/clients/scratch-tree-policy.js +1 -3
- package/dist/clients/security-scan-client.js +51 -17
- package/dist/clients/session-lifecycle.js +238 -42
- package/dist/clients/session-start-observability.js +79 -0
- package/dist/clients/sessionstart-logger.js +12 -3
- package/dist/clients/sg-runner.js +27 -15
- package/dist/clients/sgconfig.js +6 -1
- package/dist/clients/shared-checkout-guard.js +338 -0
- package/dist/clients/skills-resolver.js +105 -0
- package/dist/clients/smells-rollup.js +2 -2
- package/dist/clients/spawn-output-cap.js +37 -0
- package/dist/clients/spawn-timeout-cooldown.js +15 -1
- package/dist/clients/startup-scan.js +6 -7
- package/dist/clients/startup-timing.js +69 -4
- package/dist/clients/string-utils.js +33 -0
- package/dist/clients/subagent-mode.js +17 -4
- package/dist/clients/test-runner-client.js +586 -118
- package/dist/clients/test-runner-delivery.js +239 -0
- package/dist/clients/tool-definition.js +41 -1
- package/dist/clients/tool-policy.js +92 -22
- package/dist/clients/tree-sitter-cache.js +40 -40
- package/dist/clients/tree-sitter-client.js +97 -53
- package/dist/clients/tree-sitter-logger.js +19 -3
- package/dist/clients/tree-sitter-query-loader.js +81 -1
- package/dist/clients/tree-sitter-shared.js +51 -46
- package/dist/clients/tree-sitter-symbol-extractor.js +28 -0
- package/dist/clients/typos-config.js +5 -0
- package/dist/clients/user-notify.js +6 -2
- package/dist/clients/warm-attach.js +8 -10
- package/dist/clients/widget-state.js +191 -26
- package/dist/clients/word-index-logger.js +15 -3
- package/dist/clients/word-index-store.js +463 -0
- package/dist/clients/word-index.js +815 -125
- package/dist/clients/workspace-topology.js +25 -1
- package/dist/clients/zizmor-config.js +29 -6
- package/dist/index.js +68577 -53950
- package/dist/mcp/analyze-cli.js +3 -1
- package/dist/mcp/build-staleness.js +8 -7
- package/dist/mcp/cli.js +3 -1
- package/dist/mcp/server.js +133 -6
- package/dist/scripts/lib/process-scan.mjs +583 -0
- package/dist/scripts/lib/skills-predicate.mjs +129 -0
- package/dist/tools/effective-config.js +89 -0
- package/dist/tools/lens-diagnostics.js +99 -24
- package/dist/tools/lsp-diagnostics.js +81 -85
- package/dist/tools/lsp-navigation.js +40 -17
- package/dist/tools/shared.js +0 -1
- package/docs/agent-guide.md +68 -3
- package/docs/ast-grep_rules_catalog.md +41 -10
- package/docs/astplayground.md +26 -17
- package/docs/configuration.md +222 -0
- package/docs/dependencies.md +3 -3
- package/docs/features.md +44 -5
- package/docs/language-coverage.md +2 -2
- package/docs/pi-lens-fixer.md +25 -0
- package/docs/pi-lens-investigator.md +25 -0
- package/docs/pi-lens-reviewer.md +27 -0
- package/docs/pi-lens-subagent.md +38 -0
- package/docs/pi-lens-warden.md +55 -0
- package/docs/public-api-stability.md +359 -0
- package/docs/release-qa-baseline.md +182 -0
- package/docs/subagent-compat.md +110 -30
- package/docs/tree-sitter_rules_catalog.md +2 -2
- package/package.json +17 -21
- package/rules/ast-grep-rules/rule-tests/c-no-malloc-free-test.yml +20 -0
- package/rules/ast-grep-rules/rule-tests/cpp-no-malloc-free-test.yml +25 -0
- package/rules/ast-grep-rules/rule-tests/cpp-no-printf-test.yml +19 -0
- package/rules/ast-grep-rules/rule-tests/go-no-fmt-println-test.yml +19 -0
- package/rules/ast-grep-rules/rule-tests/go-no-panic-in-lib-test.yml +17 -0
- package/rules/ast-grep-rules/rule-tests/go-no-underscore-func-name-test.yml +18 -0
- package/rules/ast-grep-rules/rule-tests/go-prefer-errors-is-test.yml +15 -0
- package/rules/ast-grep-rules/rule-tests/go-prefer-string-builder-test.yml +21 -0
- package/rules/ast-grep-rules/rule-tests/hyphenated-svg-attribute-test.yml +11 -0
- package/rules/ast-grep-rules/rule-tests/kotlin-no-lateinit-test.yml +17 -0
- package/rules/ast-grep-rules/rule-tests/kotlin-no-nullable-boolean-test.yml +15 -0
- package/rules/ast-grep-rules/rule-tests/kotlin-no-println-test.yml +19 -0
- package/rules/ast-grep-rules/rule-tests/kotlin-no-unnecessary-let-test.yml +7 -0
- package/rules/ast-grep-rules/rule-tests/kotlin-no-unsafe-cast-test.yml +7 -0
- package/rules/ast-grep-rules/rule-tests/kotlin-no-var-test.yml +7 -0
- package/rules/ast-grep-rules/rule-tests/kotlin-prefer-data-class-test.yml +25 -0
- package/rules/ast-grep-rules/rule-tests/kotlin-prefer-is-empty-test.yml +11 -0
- package/rules/ast-grep-rules/rule-tests/no-important-test.yml +21 -0
- package/rules/ast-grep-rules/rule-tests/no-raw-types-test.yml +30 -0
- package/rules/ast-grep-rules/rule-tests/no-string-concat-in-loop-test.yml +100 -0
- package/rules/ast-grep-rules/rule-tests/no-system-out-println-test.yml +7 -0
- package/rules/ast-grep-rules/rule-tests/prefer-string-is-empty-test.yml +7 -0
- package/rules/ast-grep-rules/rule-tests/python-optional-type-test.yml +9 -0
- package/rules/ast-grep-rules/rule-tests/reducible-list-comprehension-test.yml +11 -0
- package/rules/ast-grep-rules/rule-tests/ruby-symbol-to-proc-candidate-test.yml +10 -0
- package/rules/ast-grep-rules/rule-tests/rust-no-chars-enumerate-test.yml +7 -0
- package/rules/ast-grep-rules/rules/c-no-malloc-free.yml +39 -0
- package/rules/ast-grep-rules/rules/cpp-no-malloc-free.yml +45 -0
- package/rules/ast-grep-rules/rules/cpp-no-printf.yml +41 -0
- package/rules/ast-grep-rules/rules/go-no-fmt-println.yml +43 -0
- package/rules/ast-grep-rules/rules/go-no-panic-in-lib.yml +41 -0
- package/rules/ast-grep-rules/rules/go-no-underscore-func-name.yml +35 -0
- package/rules/ast-grep-rules/rules/go-prefer-errors-is.yml +40 -0
- package/rules/ast-grep-rules/rules/go-prefer-string-builder.yml +43 -0
- package/rules/ast-grep-rules/rules/hyphenated-svg-attribute.yml +32 -0
- package/rules/ast-grep-rules/rules/kotlin-no-lateinit.yml +37 -0
- package/rules/ast-grep-rules/rules/kotlin-no-nullable-boolean.yml +33 -0
- package/rules/ast-grep-rules/rules/kotlin-no-println.yml +42 -0
- package/rules/ast-grep-rules/rules/kotlin-no-unnecessary-let.yml +28 -0
- package/rules/ast-grep-rules/rules/kotlin-no-unsafe-cast.yml +28 -0
- package/rules/ast-grep-rules/rules/kotlin-no-var.yml +35 -0
- package/rules/ast-grep-rules/rules/kotlin-prefer-data-class.yml +66 -0
- package/rules/ast-grep-rules/rules/kotlin-prefer-is-empty.yml +35 -0
- package/rules/ast-grep-rules/rules/no-important.yml +21 -0
- package/rules/ast-grep-rules/rules/no-raw-types.yml +33 -0
- package/rules/ast-grep-rules/rules/no-string-concat-in-loop.yml +90 -0
- package/rules/ast-grep-rules/rules/no-system-out-println.yml +16 -0
- package/rules/ast-grep-rules/rules/prefer-string-is-empty.yml +11 -0
- package/rules/ast-grep-rules/rules/python-optional-type.yml +22 -0
- package/rules/ast-grep-rules/rules/reducible-list-comprehension.yml +29 -0
- package/rules/ast-grep-rules/rules/ruby-symbol-to-proc-candidate.yml +25 -0
- package/rules/ast-grep-rules/rules/rust-no-chars-enumerate.yml +19 -0
- package/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
- package/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
- package/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
- package/scripts/analyze-pi-lens-logs.mjs +192 -1
- package/scripts/install-selftest.mjs +58 -2
- package/scripts/lib/skills-predicate.mjs +129 -0
- package/scripts/rpc-load-check.mjs +3 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as nodeFs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { resetBoundedTelemetry } from "./bounded-telemetry.js";
|
|
4
|
+
import { rotateMessageEndAttribution } from "./message-end-attribution.js";
|
|
4
5
|
import { createDeadline, yieldIfOverBudget } from "./cooperative-budget.js";
|
|
5
6
|
import { deadCodeIssueCount } from "./dead-code-client.js";
|
|
6
7
|
import { logDeadCodeScan } from "./dead-code-logger.js";
|
|
@@ -10,9 +11,12 @@ import { resetPsScriptAnalyzerAvailability } from "./dispatch/runners/psscriptan
|
|
|
10
11
|
import { resetInstallRetryLatches } from "./dispatch/runners/utils/availability-policy.js";
|
|
11
12
|
import { resetLazyInstallAttempts } from "./dispatch/runners/utils/lazy-installer.js";
|
|
12
13
|
import { resetDispatchAvailabilityState } from "./dispatch/runners/utils/runner-helpers.js";
|
|
14
|
+
import { resetObservedRunnerLatency } from "./dispatch/collect-later-tier.js";
|
|
15
|
+
import { resetPendingRunnerFindings } from "./dispatch/pending-runner-findings.js";
|
|
13
16
|
import { clearAllSessions as clearFileTimeSessions } from "./file-time.js";
|
|
14
17
|
import { getGlobalPiLensDir, getKnipIgnorePatterns, getProjectDataDir, } from "./file-utils.js";
|
|
15
18
|
import { GitleaksClient } from "./gitleaks-client.js";
|
|
19
|
+
import { resetGoAvailability } from "./go-client.js";
|
|
16
20
|
import { GovulncheckClient, } from "./govulncheck-client.js";
|
|
17
21
|
import { sweepAtomicWriteStages } from "./instance-reaper.js";
|
|
18
22
|
import { canRunStartupHeavyScans } from "./language-policy.js";
|
|
@@ -22,7 +26,7 @@ import { runLogCleanup } from "./log-cleanup.js";
|
|
|
22
26
|
import { resetCascadeTierSessionState } from "./lsp/cascade-tier.js";
|
|
23
27
|
import { initLSPConfig, loadLSPConfig } from "./lsp/config.js";
|
|
24
28
|
import { resetWorkspaceDiagnosticsCacheSession } from "./lsp/workspace-diagnostics-session.js";
|
|
25
|
-
import { resetDirectLspCommandAvailability } from "./lsp/server.js";
|
|
29
|
+
import { resetDirectLspCommandAvailability, resetLSPCaseSensitivityState, } from "./lsp/server.js";
|
|
26
30
|
import { loadLspService } from "./lsp-lazy.js";
|
|
27
31
|
import { resetManagedToolRefreshSession } from "./installer/managed-tool-refresh-session.js";
|
|
28
32
|
import { resetResolvedPathCache } from "./installer/index.js";
|
|
@@ -32,9 +36,10 @@ import { isAtOrAboveHomeDir } from "./path-utils.js";
|
|
|
32
36
|
import { isPrintMode } from "./print-mode.js";
|
|
33
37
|
import { readLatestProjectSequence, readLatestProjectSequenceAsync, } from "./project-changes.js";
|
|
34
38
|
import { getProjectSnapshotPath, getProjectSnapshotLegacyPath, hydrateRuntimeFromProjectSnapshot, hydrateRuntimeFromProjectSnapshotIfIdle, isProjectSnapshotFresh, isProjectSnapshotMetaStale, loadProjectSnapshot, loadProjectSnapshotExportsAndRules, PROJECT_SNAPSHOT_VERSION, readProjectSnapshotMeta, saveRuntimeProjectSnapshot, } from "./project-snapshot.js";
|
|
35
|
-
import { clearTsconfigPathsCache } from "./review-graph/tsconfig-paths.js";
|
|
36
39
|
import { scanProjectRules } from "./rules-scanner.js";
|
|
40
|
+
import { resetRustAvailability } from "./rust-client.js";
|
|
37
41
|
import { resetSafeSpawnWindowsCommandCache } from "./safe-spawn.js";
|
|
42
|
+
import { resetAnalyzerBootstrapSessionState, } from "./bootstrap.js";
|
|
38
43
|
import { getSlowFsVerdict, isSlowFs, slowFsDegradationNotice, } from "./slow-fs.js";
|
|
39
44
|
import { countRecentSmells, formatSmellsSessionStartLine, resetSmellsSessionState, } from "./smells-rollup.js";
|
|
40
45
|
import { findNearestProjectRoot, getStartupScanMaxEntries, isStartupScanVerdictFresh, resolveStartupScanContext, } from "./startup-scan.js";
|
|
@@ -44,10 +49,29 @@ import { isWarmAttached } from "./warm-attach.js";
|
|
|
44
49
|
import { setSessionLanguages } from "./widget-state.js";
|
|
45
50
|
import { logWordIndex } from "./word-index-logger.js";
|
|
46
51
|
import { resetOpaqueMutationState } from "./opaque-mutation-scan.js";
|
|
52
|
+
import { primePersistedMutationAttribution, resetMutationAttribution, } from "./mutation-attribution.js";
|
|
53
|
+
import { resetObservedMutationNet } from "./observed-mutation.js";
|
|
47
54
|
import { resetPendingAuxiliaryCoverage } from "./lsp/pending-aux-coverage.js";
|
|
48
55
|
import { resetWorkspaceTopology } from "./workspace-topology.js";
|
|
49
56
|
import { resetZizmorTokenAvailability } from "./zizmor-config.js";
|
|
50
57
|
import { resetSpawnTimeoutCooldowns } from "./spawn-timeout-cooldown.js";
|
|
58
|
+
import { resetTestRunnerDelivery } from "./test-runner-delivery.js";
|
|
59
|
+
import { resetLspMutationNoBridgeDbgLatch } from "./lsp-mutation.js";
|
|
60
|
+
/**
|
|
61
|
+
* `deps` with resolved analyzer clients merged in, or `null` when the
|
|
62
|
+
* bootstrap could not be served and the caller must proceed without them.
|
|
63
|
+
*
|
|
64
|
+
* No cast and no "is one representative field present?" probe: the seam
|
|
65
|
+
* answers with all seventeen clients or with `null`, so the two outcomes are
|
|
66
|
+
* the two branches. A skipped consumer is already counted in the ledger under
|
|
67
|
+
* `analyzer-bootstrap-unavailable`, so it is never mistaken for a clean one.
|
|
68
|
+
*/
|
|
69
|
+
async function demandBootstrapDeps(deps, reason) {
|
|
70
|
+
const clients = await deps.bootstrap.request(reason);
|
|
71
|
+
if (!clients)
|
|
72
|
+
return null;
|
|
73
|
+
return { ...deps, ...clients };
|
|
74
|
+
}
|
|
51
75
|
const HOST_STALL_THRESHOLD_MS = 30_000;
|
|
52
76
|
function logHostReadyDelay(deps, cwd) {
|
|
53
77
|
if (!deps.emitHostReadyDelay ||
|
|
@@ -623,7 +647,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
623
647
|
const snapshot = loadProjectSnapshot(snapshotRoot);
|
|
624
648
|
const snapshotLoadMs = Date.now() - snapshotLoadStartMs;
|
|
625
649
|
if (snapshot?.wordIndex) {
|
|
626
|
-
const { deserializeWordIndex, refreshWordIndexIncrementally } = await import("./word-index.js");
|
|
650
|
+
const { deserializeWordIndex, refreshWordIndexIncrementally, countWordIndexPostingEntries, estimateWordIndexResidentBytes, } = await import("./word-index.js");
|
|
627
651
|
const deserializeStartMs = Date.now();
|
|
628
652
|
const index = deserializeWordIndex(snapshot.wordIndex);
|
|
629
653
|
const deserializeMs = Date.now() - deserializeStartMs;
|
|
@@ -675,6 +699,8 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
675
699
|
durationMs: Date.now() - startMs,
|
|
676
700
|
indexedFileCount: index.docCount,
|
|
677
701
|
tokens: index.postings.size,
|
|
702
|
+
postingEntries: countWordIndexPostingEntries(index),
|
|
703
|
+
residentBytes: estimateWordIndexResidentBytes(index),
|
|
678
704
|
truncated: index.truncated,
|
|
679
705
|
phaseDurationsMs: {
|
|
680
706
|
snapshotLoadMs,
|
|
@@ -714,7 +740,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
714
740
|
// implementation backs this task, the quick-mode warmup call below, AND the
|
|
715
741
|
// stateless cold-query background trigger in word-index.ts — a bound/skip
|
|
716
742
|
// -rule change lands once, not in three copies.
|
|
717
|
-
const { buildWordIndexAsync, collectWordIndexDocs } = await import("./word-index.js");
|
|
743
|
+
const { buildWordIndexAsync, collectWordIndexDocs, countWordIndexPostingEntries, estimateWordIndexResidentBytes, } = await import("./word-index.js");
|
|
718
744
|
const docs = await collectWordIndexDocs(analysisRoot, () => runtime.isCurrentSession(sessionGeneration), rebuildPreflightFiles);
|
|
719
745
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
720
746
|
return;
|
|
@@ -751,6 +777,8 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
751
777
|
durationMs: Date.now() - startMs,
|
|
752
778
|
indexedFileCount: runtime.wordIndex.docCount,
|
|
753
779
|
tokens: runtime.wordIndex.postings.size,
|
|
780
|
+
postingEntries: countWordIndexPostingEntries(runtime.wordIndex),
|
|
781
|
+
residentBytes: estimateWordIndexResidentBytes(runtime.wordIndex),
|
|
754
782
|
truncated: runtime.wordIndex.truncated,
|
|
755
783
|
skipped: docs.skipped,
|
|
756
784
|
});
|
|
@@ -766,6 +794,24 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
766
794
|
// Each consumer already handles the "not ready yet" case gracefully
|
|
767
795
|
// (cachedExports.size > 0, cache miss paths).
|
|
768
796
|
function scheduleStartupScans(deps, runtime, sessionGeneration, analysisRoot, snapshotRoot, languageProfile, dbg) {
|
|
797
|
+
// #2467: the analyzers these scans drive are loaded HERE, on the deferred
|
|
798
|
+
// background path, instead of before the handler ran. This function was
|
|
799
|
+
// already fire-and-forget ("don't block session start"), so resolving them
|
|
800
|
+
// across one await adds no wait to the interactive path and changes no
|
|
801
|
+
// ordering its caller depends on — the caller never awaited it.
|
|
802
|
+
void (async () => {
|
|
803
|
+
const resolved = await demandBootstrapDeps(deps, "session-start-scans");
|
|
804
|
+
// Fail open: no analyzers means no scans, said out loud. The demand is
|
|
805
|
+
// already counted in the ledger, so this is not a silent skip.
|
|
806
|
+
if (!resolved) {
|
|
807
|
+
dbg("session_start scans: analyzer bootstrap unavailable — skipped");
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
scheduleStartupScansWithClients(resolved, runtime, sessionGeneration, analysisRoot, snapshotRoot, languageProfile, dbg);
|
|
811
|
+
})();
|
|
812
|
+
}
|
|
813
|
+
/** The scan bodies, once the analyzers they need are resolved. */
|
|
814
|
+
function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analysisRoot, snapshotRoot, languageProfile, dbg) {
|
|
769
815
|
const { todoScanner, cacheManager, knipClient, jscpdClient, deadCodeClients, govulncheckClient, gitleaksClient, trivyClient, opengrepClient, astGrepClient, depChecker, } = deps;
|
|
770
816
|
// Some background scans are CPU-heavy and arrive on the event loop
|
|
771
817
|
// just as the user is most likely typing (right after /new). Defer
|
|
@@ -1150,7 +1196,12 @@ function scheduleStartupScans(deps, runtime, sessionGeneration, analysisRoot, sn
|
|
|
1150
1196
|
// Build (or hydrate) the canonical review graph first. The call graph is a
|
|
1151
1197
|
// derived projection of that graph, so its freshness is the review graph's
|
|
1152
1198
|
// version/signature—not a second source walk and mtime policy.
|
|
1153
|
-
|
|
1199
|
+
// Subject labels this store's capacity-eviction telemetry distinctly
|
|
1200
|
+
// from the other five production FactStore instances (#2243 review
|
|
1201
|
+
// round 3, F1) — this session-start walk runs BEFORE any dispatch and
|
|
1202
|
+
// can visit every file in the project, so a shared subject would let
|
|
1203
|
+
// it consume the dispatch store's once-per-session ledger slot first.
|
|
1204
|
+
const sessionFacts = new FactStore("runtime-session-call-graph");
|
|
1154
1205
|
const graph = await buildOrUpdateGraph(analysisRoot, [], sessionFacts);
|
|
1155
1206
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
1156
1207
|
return;
|
|
@@ -1235,6 +1286,20 @@ function scheduleStartupScans(deps, runtime, sessionGeneration, analysisRoot, sn
|
|
|
1235
1286
|
});
|
|
1236
1287
|
}
|
|
1237
1288
|
function scheduleDeferredToolProbes(deps, languageProfile, startupDefaults, startupScansWillRun, dbg) {
|
|
1289
|
+
// #2467: same deferral as `scheduleStartupScans` — the probes were already
|
|
1290
|
+
// fire-and-forget, so the analyzers they probe load here rather than before
|
|
1291
|
+
// the handler.
|
|
1292
|
+
void (async () => {
|
|
1293
|
+
const resolved = await demandBootstrapDeps(deps, "session-start-tool-probes");
|
|
1294
|
+
if (!resolved) {
|
|
1295
|
+
dbg("session_start tools: analyzer bootstrap unavailable — no probes");
|
|
1296
|
+
return;
|
|
1297
|
+
}
|
|
1298
|
+
scheduleDeferredToolProbesWithClients(resolved, languageProfile, startupDefaults, startupScansWillRun, dbg);
|
|
1299
|
+
})();
|
|
1300
|
+
}
|
|
1301
|
+
/** The probe bodies, once the analyzers they probe are resolved. */
|
|
1302
|
+
function scheduleDeferredToolProbesWithClients(deps, languageProfile, startupDefaults, startupScansWillRun, dbg) {
|
|
1238
1303
|
const { biomeClient, ruffClient, depChecker } = deps;
|
|
1239
1304
|
const defaultTools = new Set(startupDefaults);
|
|
1240
1305
|
const probes = [];
|
|
@@ -1288,29 +1353,40 @@ export const SESSION_START_GUIDANCE = [
|
|
|
1288
1353
|
];
|
|
1289
1354
|
export async function handleSessionStart(deps) {
|
|
1290
1355
|
resetDegradationLedger();
|
|
1356
|
+
// #2467: re-arm the analyzer bootstrap's shutdown gate. The gate is a
|
|
1357
|
+
// per-SESSION claim ("this session is over") held in process-lived storage,
|
|
1358
|
+
// so without this a replacement session in the same process would find
|
|
1359
|
+
// every analyzer refused for the rest of the process — AGENTS.md defect
|
|
1360
|
+
// shape 17. The resident clients themselves are deliberately kept.
|
|
1361
|
+
resetAnalyzerBootstrapSessionState();
|
|
1362
|
+
resetTestRunnerDelivery();
|
|
1363
|
+
// #2450 fix round 3, catalog shape 17: the "bridge unavailable" dbg latch
|
|
1364
|
+
// (`clients/lsp-mutation.ts`) is a process-lifetime once-per-session flag,
|
|
1365
|
+
// same shape as the ledger's own once-per-subject bookkeeping above, but
|
|
1366
|
+
// kept as its own reset (not folded into `resetDegradationLedger`) to
|
|
1367
|
+
// avoid that module reaching back into this one — see the latch's own
|
|
1368
|
+
// comment for why.
|
|
1369
|
+
resetLspMutationNoBridgeDbgLatch();
|
|
1291
1370
|
// #1743: the bounded-telemetry per-turn counters. The rising-edge state is
|
|
1292
1371
|
// NOT here — it is the ledger's own tally, reset on the line above. These
|
|
1293
1372
|
// counters are keyed by turn index, and a new session restarts turn
|
|
1294
1373
|
// numbering at 0, so without this a stale count could survive a session
|
|
1295
1374
|
// boundary that happened to land on the same index.
|
|
1296
1375
|
resetBoundedTelemetry();
|
|
1376
|
+
// #1956 R3: stale message_end events drain after replacement. Rotate the
|
|
1377
|
+
// live anchor into one bounded previous slot so the queued event keeps the
|
|
1378
|
+
// replaced session's attribution until a newer live message_end is seen.
|
|
1379
|
+
rotateMessageEndAttribution();
|
|
1380
|
+
// #2526: the once-per-session `config_resolved` claim is NOT re-armed here.
|
|
1381
|
+
// index.ts resolves this session's config in `ensureLSPConfigInitialized`
|
|
1382
|
+
// BEFORE it calls this handler, so a re-arm on this line would fire between
|
|
1383
|
+
// the session's own two resolutions and the deferred `loadLSPConfig` below
|
|
1384
|
+
// would write a second row for one session (review round 2, F1). The re-arm
|
|
1385
|
+
// lives in index.ts's `session_start` closure, ahead of that ensure and
|
|
1386
|
+
// behind the #473 gate — see `resetOncePerSessionPhases`'s doc comment.
|
|
1297
1387
|
const handlerEnteredAt = Date.now();
|
|
1298
1388
|
const sessionStartMs = deps.sessionStartFiredAt ?? handlerEnteredAt;
|
|
1299
1389
|
const cwdForTelemetry = deps.ctxCwd ?? process.cwd();
|
|
1300
|
-
if (deps.bootstrapClientsStartedAt !== undefined &&
|
|
1301
|
-
deps.bootstrapClientsDurationMs !== undefined) {
|
|
1302
|
-
logLatency({
|
|
1303
|
-
type: "phase",
|
|
1304
|
-
filePath: cwdForTelemetry,
|
|
1305
|
-
phase: "bootstrap_clients_load",
|
|
1306
|
-
startedAt: new Date(deps.bootstrapClientsStartedAt).toISOString(),
|
|
1307
|
-
durationMs: deps.bootstrapClientsDurationMs,
|
|
1308
|
-
metadata: {
|
|
1309
|
-
parent: "session_start_prehandler",
|
|
1310
|
-
reason: deps.sessionReason,
|
|
1311
|
-
},
|
|
1312
|
-
});
|
|
1313
|
-
}
|
|
1314
1390
|
if (deps.sessionStartFiredAt !== undefined) {
|
|
1315
1391
|
logLatency({
|
|
1316
1392
|
type: "phase",
|
|
@@ -1590,7 +1666,7 @@ export async function handleSessionStart(deps) {
|
|
|
1590
1666
|
}
|
|
1591
1667
|
const allowBootstrapTasks = startupMode === "full";
|
|
1592
1668
|
const quickMode = startupMode === "quick";
|
|
1593
|
-
const { ctxCwd, getFlag, notify, dbg, log, runtime,
|
|
1669
|
+
const { ctxCwd, getFlag, notify, dbg, log, runtime, cacheManager, ensureTool, cleanStaleTsBuildInfo, resetDispatchBaselines, resetLSPService, } = deps;
|
|
1594
1670
|
// Lightweight phase timer — resets after each call so each log line shows
|
|
1595
1671
|
// the cost of that phase alone, not cumulative time from session start.
|
|
1596
1672
|
let _phaseT = Date.now();
|
|
@@ -1598,23 +1674,31 @@ export async function handleSessionStart(deps) {
|
|
|
1598
1674
|
dbg(`session_start phase ${name}: ${Date.now() - _phaseT}ms`);
|
|
1599
1675
|
_phaseT = Date.now();
|
|
1600
1676
|
};
|
|
1601
|
-
|
|
1677
|
+
// #2467: `peek`, never a load. A metrics client that was never constructed
|
|
1678
|
+
// holds no per-session state to re-arm, so the reset is vacuous — and
|
|
1679
|
+
// loading the analyzer graph in order to reset nothing is the interactive-
|
|
1680
|
+
// path cost this issue removes.
|
|
1681
|
+
deps.bootstrap.peek()?.metricsClient.reset();
|
|
1602
1682
|
getDiagnosticTracker().reset();
|
|
1603
1683
|
clearFileTimeSessions();
|
|
1604
1684
|
runtime.complexityBaselines.clear();
|
|
1605
1685
|
resetDispatchBaselines(ctxCwd);
|
|
1606
|
-
// #806:
|
|
1607
|
-
//
|
|
1608
|
-
//
|
|
1609
|
-
// sessions is picked up fresh instead of only on process restart — this
|
|
1610
|
-
// also fixes #805's mid-session tsconfig staleness (the matcher cache was
|
|
1611
|
-
// previously session-lived with no reset hook at all).
|
|
1686
|
+
// #806: clear the shared per-directory marker index and registered
|
|
1687
|
+
// topology-derived caches only at session start. Mid-session edits are NOT
|
|
1688
|
+
// detected; #805's tsconfig matcher cache follows the same registry reset.
|
|
1612
1689
|
resetWorkspaceTopology();
|
|
1613
|
-
clearTsconfigPathsCache();
|
|
1614
1690
|
// #2000: opaque-recovery baselines are keyed cwd:generation (unreachable
|
|
1615
1691
|
// after reset) and the git-worktree memo must re-probe after a session
|
|
1616
1692
|
// that may have seen a non-git dir become one.
|
|
1617
1693
|
resetOpaqueMutationState();
|
|
1694
|
+
// #2430: the observational net's pending baselines are keyed by tool-call
|
|
1695
|
+
// id and its content ledger describes the previous session's files; both
|
|
1696
|
+
// mis-answer forever without this. The learned attribution map is cleared
|
|
1697
|
+
// and then RE-PRIMED from this project's persisted file, so a tool an
|
|
1698
|
+
// earlier session observed is classified by name with no snapshot at all.
|
|
1699
|
+
resetObservedMutationNet();
|
|
1700
|
+
resetMutationAttribution();
|
|
1701
|
+
primePersistedMutationAttribution(ctxCwd);
|
|
1618
1702
|
// #2026: pending auxiliary baselines are unreachable after generation bump.
|
|
1619
1703
|
resetPendingAuxiliaryCoverage();
|
|
1620
1704
|
// #817/#1199: Windows command resolution is cached per (command, canonical
|
|
@@ -1630,6 +1714,10 @@ export async function handleSessionStart(deps) {
|
|
|
1630
1714
|
// the tool for the rest of the process lifetime. Clear it here, same
|
|
1631
1715
|
// boundary as the other per-session caches on this line.
|
|
1632
1716
|
resetDispatchAvailabilityState();
|
|
1717
|
+
// Runner collect-later observations and their late findings are session
|
|
1718
|
+
// scoped. A new session must re-probe rather than inherit a process latch.
|
|
1719
|
+
resetObservedRunnerLatency();
|
|
1720
|
+
resetPendingRunnerFindings();
|
|
1633
1721
|
// #1995: a command that TIMED OUT (not merely failed a probe) cools down
|
|
1634
1722
|
// for the rest of the session so a hot loop of edits cannot hand the same
|
|
1635
1723
|
// wedged .cmd shim a second budget. A new session may retry: the executable
|
|
@@ -1650,6 +1738,18 @@ export async function handleSessionStart(deps) {
|
|
|
1650
1738
|
// login` and starts a fresh session still reads the previous session's
|
|
1651
1739
|
// stale "no token" verdict until the cooldown (if any) happens to expire.
|
|
1652
1740
|
resetZizmorTokenAvailability();
|
|
1741
|
+
// #2455: same #1496/#1535 process-lifetime-latch shape, one caller later —
|
|
1742
|
+
// the `goClient`/`rustClient` singletons each hold their own
|
|
1743
|
+
// `createAvailabilityLatch()` outside the dispatch generation counter above
|
|
1744
|
+
// (they predate `createCwdCachedProbe`). A "missing" verdict never expires
|
|
1745
|
+
// on its own, so without these a go/cargo install between sessions stayed
|
|
1746
|
+
// unobserved for the rest of the process's life. Found by hand while
|
|
1747
|
+
// auditing #2455's detector widening, NOT surfaced by it: the sweep skips
|
|
1748
|
+
// any file exporting no reset at all, and neither client module exported
|
|
1749
|
+
// one, so no container predicate could have yielded them (#2455 fix round 4,
|
|
1750
|
+
// F5 — an earlier draft of this comment had the causality backwards).
|
|
1751
|
+
resetGoAvailability();
|
|
1752
|
+
resetRustAvailability();
|
|
1653
1753
|
// psscriptanalyzer's three latches (interpreter, module, -File exec) are
|
|
1654
1754
|
// module-local, so the generation counter above does not reach them
|
|
1655
1755
|
// (#1490, #1540).
|
|
@@ -1670,6 +1770,9 @@ export async function handleSessionStart(deps) {
|
|
|
1670
1770
|
// #1897: direct-LSP negative availability and bare installer paths are
|
|
1671
1771
|
// session facts. A command or PATH entry can appear between sessions.
|
|
1672
1772
|
resetDirectLspCommandAvailability();
|
|
1773
|
+
// #2052: a root may not exist when the case-sensitivity probe first sees it.
|
|
1774
|
+
// Re-probe it at the next session boundary after the workspace is created.
|
|
1775
|
+
resetLSPCaseSensitivityState();
|
|
1673
1776
|
resetResolvedPathCache();
|
|
1674
1777
|
// #1653: pnpm/yarn/bun/npm's availability latches (package-manager.ts) are
|
|
1675
1778
|
// module-local, same #1490/#1535 shape as the two lines above — the
|
|
@@ -1694,7 +1797,9 @@ export async function handleSessionStart(deps) {
|
|
|
1694
1797
|
// Some embedders inject a capability-shaped Knip client rather than the
|
|
1695
1798
|
// concrete KnipClient. Session reset is an optional lifecycle capability;
|
|
1696
1799
|
// its absence must not make session_start fail.
|
|
1697
|
-
|
|
1800
|
+
// #2467: `peek` for the same reason as `metricsClient.reset()` above —
|
|
1801
|
+
// an unloaded knip client has no session state to clear.
|
|
1802
|
+
deps.bootstrap.peek()?.knipClient.resetSessionState?.();
|
|
1698
1803
|
// #1910: the tier-3 cascade outstanding-touch registry and its
|
|
1699
1804
|
// sweep-scoped expired/evicted counters (clients/lsp/cascade-tier.ts) are
|
|
1700
1805
|
// a per-SESSION claim about touches THIS session fired. #1899 bounded the
|
|
@@ -1751,6 +1856,12 @@ export async function handleSessionStart(deps) {
|
|
|
1751
1856
|
}
|
|
1752
1857
|
const hasWorkspaceCwd = typeof ctxCwd === "string" && ctxCwd.length > 0;
|
|
1753
1858
|
const cwd = ctxCwd ?? process.cwd();
|
|
1859
|
+
// #2526 review round 3, S1: this handler no longer predicts whether config
|
|
1860
|
+
// will resolve. `loadLSPConfig` itself publishes a `config_resolution_pending`
|
|
1861
|
+
// mark, from inside the function, at the instant a resolution is actually
|
|
1862
|
+
// attempted — see that function's doc comment (`clients/lsp/config.ts`) for
|
|
1863
|
+
// why a prediction mirrored against this handler's own gates drifted from
|
|
1864
|
+
// what index.ts and this handler's callers actually schedule.
|
|
1754
1865
|
// #1228: generic atomic-write stages are shared by several project stores,
|
|
1755
1866
|
// so the review-graph-specific sweep cannot own this namespace. Sweep the
|
|
1756
1867
|
// project data roots and machine-global registry root once per session start;
|
|
@@ -1920,7 +2031,18 @@ export async function handleSessionStart(deps) {
|
|
|
1920
2031
|
filePath: cwd,
|
|
1921
2032
|
startedAt: new Date(sessionStartMs).toISOString(),
|
|
1922
2033
|
durationMs: totalDurationMs,
|
|
1923
|
-
metadata: {
|
|
2034
|
+
metadata: {
|
|
2035
|
+
mode: startupMode,
|
|
2036
|
+
reason: deps.sessionReason,
|
|
2037
|
+
// #2129: the root-identity input decideSessionStart consulted,
|
|
2038
|
+
// alongside `mode` — every start reaching this line already
|
|
2039
|
+
// classified `primary`/`sequential-replacement` (a `secondary-root`
|
|
2040
|
+
// start returns before `handleSessionStart` is ever called).
|
|
2041
|
+
classification: deps.sessionStartClassification,
|
|
2042
|
+
// `undefined` is omitted by JSON.stringify. Keep unknown explicit so
|
|
2043
|
+
// strict log readers can distinguish it from legacy omission.
|
|
2044
|
+
sameRoot: deps.sessionStartSameRoot ?? "unknown",
|
|
2045
|
+
},
|
|
1924
2046
|
});
|
|
1925
2047
|
logHostReadyDelay(deps, cwd);
|
|
1926
2048
|
emitSmellsSessionStartLine(dbg, sessionStartMs);
|
|
@@ -2162,13 +2284,19 @@ export async function handleSessionStart(deps) {
|
|
|
2162
2284
|
else {
|
|
2163
2285
|
dbg("session_start: skipping prettier preinstall probe (startup mode)");
|
|
2164
2286
|
}
|
|
2165
|
-
|
|
2287
|
+
// #2467: the first point on the FULL-mode path that genuinely needs the
|
|
2288
|
+
// analyzer clients, so it is where the load is paid. Quick mode — the
|
|
2289
|
+
// process's first session, the one the user is waiting on — returns above
|
|
2290
|
+
// and never reaches here. Fail open: an unavailable bootstrap drops these
|
|
2291
|
+
// three entries from the "Active tools" line rather than failing the start.
|
|
2292
|
+
const summaryClients = await deps.bootstrap.request("session-start-tools");
|
|
2293
|
+
const detectedRunner = summaryClients?.testRunnerClient.detectRunner(analysisRoot);
|
|
2166
2294
|
phase("test-runner-detect");
|
|
2167
2295
|
if (detectedRunner)
|
|
2168
2296
|
tools.push(`Test runner (${detectedRunner.runner})`);
|
|
2169
|
-
if (await goClient.isGoAvailableAsync())
|
|
2297
|
+
if (await summaryClients?.goClient.isGoAvailableAsync())
|
|
2170
2298
|
tools.push("Go (go vet)");
|
|
2171
|
-
if (await rustClient.isAvailableAsync())
|
|
2299
|
+
if (await summaryClients?.rustClient.isAvailableAsync())
|
|
2172
2300
|
tools.push("Rust (cargo)");
|
|
2173
2301
|
log(`Active tools: ${tools.join(", ")}`);
|
|
2174
2302
|
dbg(`session_start tools: ${tools.join(", ")}`);
|
|
@@ -2264,7 +2392,14 @@ export async function handleSessionStart(deps) {
|
|
|
2264
2392
|
filePath: cwd,
|
|
2265
2393
|
startedAt: new Date(sessionStartMs).toISOString(),
|
|
2266
2394
|
durationMs: totalDurationMs,
|
|
2267
|
-
metadata: {
|
|
2395
|
+
metadata: {
|
|
2396
|
+
mode: startupMode,
|
|
2397
|
+
reason: deps.sessionReason,
|
|
2398
|
+
// #2129: see the quick-mode session_start_total record above.
|
|
2399
|
+
classification: deps.sessionStartClassification,
|
|
2400
|
+
// Keep the full path's durable shape identical to quick mode.
|
|
2401
|
+
sameRoot: deps.sessionStartSameRoot ?? "unknown",
|
|
2402
|
+
},
|
|
2268
2403
|
});
|
|
2269
2404
|
logHostReadyDelay(deps, cwd);
|
|
2270
2405
|
emitSmellsSessionStartLine(dbg, sessionStartMs);
|