pi-lens 4.3.0 → 4.4.0
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 +1064 -0
- package/README.md +115 -25
- package/config/dependency-cruiser-eager-allowlist.json +6 -2
- package/dist/chunk-22AVIGXS.js +560 -0
- package/dist/chunk-27BBHSZC.js +106 -0
- package/dist/chunk-2BEMIWEW.js +51 -0
- package/dist/chunk-2EECBNC5.js +89 -0
- package/dist/chunk-34U7PLGE.js +23 -0
- package/dist/chunk-3I5QFT3N.js +181 -0
- package/dist/chunk-3MED75HT.js +37 -0
- package/dist/chunk-47D2BO4S.js +87 -0
- package/dist/chunk-4RERDEXR.js +348 -0
- package/dist/chunk-4W2PLC4J.js +27 -0
- package/dist/chunk-52H5B5TC.js +202 -0
- package/dist/chunk-54B42YRX.js +27 -0
- package/dist/chunk-5RXBNSW2.js +266 -0
- package/dist/chunk-5THXD6X5.js +201 -0
- package/dist/chunk-5W3R6LFT.js +24 -0
- package/dist/chunk-5ZEJHV35.js +341 -0
- package/dist/chunk-6P62QVEA.js +118 -0
- package/dist/chunk-6QIUX4EP.js +459 -0
- package/dist/chunk-6VCD4VKZ.js +78 -0
- package/dist/chunk-7F72PXY2.js +326 -0
- package/dist/chunk-7FBF7NPR.js +998 -0
- package/dist/chunk-7U2IDNXN.js +37 -0
- package/dist/chunk-ABBOA7UD.js +157 -0
- package/dist/chunk-AHDW3GPE.js +50 -0
- package/dist/chunk-AJ3QXTRQ.js +756 -0
- package/dist/chunk-AJVLWNFN.js +1610 -0
- package/dist/chunk-AJXODZY6.js +112 -0
- package/dist/chunk-ARFCXG7S.js +84 -0
- package/dist/chunk-AS44CFQ4.js +708 -0
- package/dist/chunk-AWE5TMPO.js +38 -0
- package/dist/chunk-B3I2UUT4.js +4692 -0
- package/dist/chunk-BRJKOBZP.js +331 -0
- package/dist/chunk-BW5KFIQC.js +59 -0
- package/dist/chunk-C2AUYXQH.js +149 -0
- package/dist/chunk-CGGAIP7J.js +29 -0
- package/dist/chunk-D6QS3U6M.js +30 -0
- package/dist/chunk-DFVMIKMQ.js +349 -0
- package/dist/chunk-DIULIWKU.js +169 -0
- package/dist/chunk-DQ2NZ7C4.js +2317 -0
- package/dist/chunk-E2WFBRHM.js +213 -0
- package/dist/chunk-E4MAEDPM.js +50 -0
- package/dist/chunk-EOKRQ3SA.js +30 -0
- package/dist/chunk-F3AU2TMM.js +2626 -0
- package/dist/chunk-F3P7VQ7H.js +170 -0
- package/dist/chunk-FC4RP4I2.js +12 -0
- package/dist/chunk-FJNKANOS.js +32 -0
- package/dist/chunk-GUOGVTCQ.js +146 -0
- package/dist/chunk-GVXA6CCE.js +18 -0
- package/dist/chunk-HHYAELLJ.js +2334 -0
- package/dist/chunk-HMFXILPV.js +83 -0
- package/dist/chunk-HVUZXSWK.js +421 -0
- package/dist/chunk-HWBZIGMJ.js +62 -0
- package/dist/chunk-I3R7GKDR.js +17 -0
- package/dist/chunk-I7SPGOWI.js +55 -0
- package/dist/chunk-IIXOAGHR.js +38 -0
- package/dist/chunk-IVP5KAB7.js +2250 -0
- package/dist/chunk-IXEBJSUE.js +22 -0
- package/dist/chunk-JOLITGCC.js +27 -0
- package/dist/chunk-K6VYLB2U.js +145 -0
- package/dist/chunk-LJDODBBZ.js +78 -0
- package/dist/chunk-LNAKEO63.js +78 -0
- package/dist/chunk-LSMJ6KBE.js +4139 -0
- package/dist/chunk-LW6XKDZQ.js +5565 -0
- package/dist/chunk-N3YQJI6O.js +899 -0
- package/dist/chunk-NABLC7W3.js +148 -0
- package/dist/chunk-NKOUFPQF.js +659 -0
- package/dist/chunk-NL5GLMFI.js +211 -0
- package/dist/chunk-NMABWBZN.js +327 -0
- package/dist/chunk-NTHH2J74.js +27 -0
- package/dist/chunk-NTUJEGDZ.js +59 -0
- package/dist/chunk-NXL4FFQQ.js +47 -0
- package/dist/chunk-NXPS2L6U.js +466 -0
- package/dist/chunk-O5WILGMI.js +42 -0
- package/dist/chunk-O6TQT6RI.js +48 -0
- package/dist/chunk-OAXNDZJ7.js +323 -0
- package/dist/chunk-ODEEOXPH.js +44 -0
- package/dist/chunk-OQGFCZJ4.js +4533 -0
- package/dist/chunk-ORTMY4Q4.js +282 -0
- package/dist/chunk-OS32RNR2.js +442 -0
- package/dist/chunk-PAK6IDME.js +189 -0
- package/dist/chunk-PWFHBTSF.js +406 -0
- package/dist/chunk-Q5U6FMDI.js +2352 -0
- package/dist/chunk-QOZXJ4NA.js +3364 -0
- package/dist/chunk-QYF5S6P6.js +45 -0
- package/dist/chunk-RIISMHKN.js +36 -0
- package/dist/chunk-RPD4ZSB7.js +25 -0
- package/dist/chunk-RPD5K5NC.js +79 -0
- package/dist/chunk-RUOG5D2C.js +262 -0
- package/dist/chunk-T4ERT73Y.js +599 -0
- package/dist/chunk-T6D4Q4AQ.js +54 -0
- package/dist/chunk-TGPXLY2J.js +391 -0
- package/dist/chunk-TLGFBM3F.js +12116 -0
- package/dist/chunk-TO6WL3GM.js +88 -0
- package/dist/chunk-TT22N74J.js +517 -0
- package/dist/chunk-TVN5N6GY.js +21216 -0
- package/dist/chunk-U3VGR4VU.js +308 -0
- package/dist/chunk-UK3CMEAL.js +1250 -0
- package/dist/chunk-UOPVJQ4N.js +103 -0
- package/dist/chunk-UXVNL3D7.js +23 -0
- package/dist/chunk-UY752QSN.js +45 -0
- package/dist/chunk-V5PXFSZK.js +188 -0
- package/dist/chunk-V7R425XG.js +398 -0
- package/dist/chunk-VCSRSYLF.js +81 -0
- package/dist/chunk-VD4JQCQC.js +162 -0
- package/dist/chunk-VDBPVIKD.js +62 -0
- package/dist/chunk-VHQLPIRJ.js +114 -0
- package/dist/chunk-VN2AXLEX.js +5414 -0
- package/dist/chunk-VNMT7C64.js +478 -0
- package/dist/chunk-WONERJTP.js +309 -0
- package/dist/chunk-XECLWQZN.js +85 -0
- package/dist/chunk-XIMYZ3JA.js +27 -0
- package/dist/chunk-XK4CIILI.js +144 -0
- package/dist/chunk-Y4T27COV.js +562 -0
- package/dist/chunk-YGVYKNSN.js +1860 -0
- package/dist/chunk-YLF3PPT5.js +308 -0
- package/dist/chunk-YSNFMJKN.js +14 -0
- package/dist/chunk-Z3CCVDUB.js +76 -0
- package/dist/chunk-Z54ZSOBZ.js +61 -0
- package/dist/chunk-ZAWW3AF6.js +97 -0
- package/dist/chunk-ZMOL6RQC.js +167 -0
- package/dist/index.js +16456 -8335
- package/dist/mcp/analyze-cli.js +186 -232
- package/dist/mcp/cli.js +137 -98
- package/dist/mcp/server.js +22589 -1573
- package/dist/mcp/worker.js +97 -38
- package/dist/probes/installer.js +135 -0
- package/dist/workers/project-snapshot-persist-worker.js +22 -0
- package/dist/workers/review-graph-persist-worker.js +15 -0
- package/docs/agent-guide.md +13 -4
- package/docs/agent-tools.md +42 -0
- package/docs/ast-grep_rules_catalog.md +3 -2
- package/docs/configuration.md +20 -1
- package/docs/environment-variables.md +52 -2
- package/docs/features.md +8 -4
- package/docs/globalconfig.md +1 -0
- package/docs/io-bridge-v2-migration.md +94 -0
- package/docs/lsp-capability-matrix.md +36 -4
- package/docs/lsp-idle-eviction.md +124 -0
- package/docs/mcp.md +21 -5
- package/docs/merge-queue-rollout.md +77 -0
- package/docs/pi-lens-fixer.md +156 -88
- package/docs/pi-lens-investigator.md +74 -26
- package/docs/pi-lens-merge-policy.md +694 -0
- package/docs/pi-lens-monitor.md +73 -7
- package/docs/pi-lens-retro.md +6 -4
- package/docs/pi-lens-reviewer.md +188 -48
- package/docs/pi-lens-subagent.md +246 -45
- package/docs/pi-lens-warden.md +18 -7
- package/docs/public-api-stability.md +55 -0
- package/docs/release-qa-baseline.md +84 -17
- package/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
- package/docs/servercapabilities.md +53 -49
- package/docs/settings.md +1 -0
- package/docs/usage.md +5 -1
- package/grammars/tree-sitter-bash.wasm +0 -0
- package/grammars/tree-sitter-bash.wasm.json +3 -3
- package/package.json +19 -7
- package/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
- package/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
- package/scripts/analyze-pi-lens-logs.mjs +1275 -62
- package/scripts/download-grammars.js +5 -0
- package/scripts/grammars.lock.json +6 -1
- package/scripts/install-selftest.mjs +33 -34
- package/scripts/lib/host-provided-deps.mjs +13 -4
- package/scripts/lib/web-tree-sitter-dir.mjs +18 -0
- package/dist/clients/actionable-warnings-logger.js +0 -35
- package/dist/clients/actionable-warnings.js +0 -1610
- package/dist/clients/advisory-provenance.js +0 -593
- package/dist/clients/agent-behavior-client.js +0 -147
- package/dist/clients/agent-nudge.js +0 -325
- package/dist/clients/analysed-root.js +0 -1
- package/dist/clients/ast-grep-client.js +0 -731
- package/dist/clients/ast-grep-rule-manager.js +0 -146
- package/dist/clients/ast-grep-tool-logger.js +0 -118
- package/dist/clients/ast-grep-types.js +0 -10
- package/dist/clients/ast-grep-yaml-synth.js +0 -154
- package/dist/clients/atomic-write-staging.js +0 -75
- package/dist/clients/atomic-write.js +0 -189
- package/dist/clients/availability-probe-flight.js +0 -12
- package/dist/clients/bash-file-access.js +0 -1056
- package/dist/clients/biome-client.js +0 -357
- package/dist/clients/blocker-freshness.js +0 -837
- package/dist/clients/blocker-past-eof.js +0 -129
- package/dist/clients/bootstrap.js +0 -569
- package/dist/clients/bounded-cache.js +0 -190
- package/dist/clients/bounded-pid-file-lock.js +0 -202
- package/dist/clients/bounded-telemetry.js +0 -295
- package/dist/clients/build-identity.js +0 -95
- package/dist/clients/bundled-resource-health.js +0 -113
- package/dist/clients/bus-events-logger.js +0 -105
- package/dist/clients/bus-publish.js +0 -171
- package/dist/clients/cache/rule-cache.js +0 -190
- package/dist/clients/cache-manager.js +0 -524
- package/dist/clients/cache-observability.js +0 -1313
- package/dist/clients/call-graph.js +0 -852
- package/dist/clients/cargo-manifest.js +0 -422
- package/dist/clients/cascade-budget.js +0 -196
- package/dist/clients/cascade-format.js +0 -315
- package/dist/clients/cascade-logger.js +0 -31
- package/dist/clients/cascade-types.js +0 -9
- package/dist/clients/child-unref.js +0 -124
- package/dist/clients/code-quality-warnings.js +0 -286
- package/dist/clients/codebase-model.js +0 -173
- package/dist/clients/collateral-test-role.js +0 -40
- package/dist/clients/complexity-client.js +0 -462
- package/dist/clients/config-core/deny.js +0 -221
- package/dist/clients/config-core/index.js +0 -50
- package/dist/clients/config-core/merge.js +0 -357
- package/dist/clients/config-core/normalize.js +0 -340
- package/dist/clients/config-core/process-spec.js +0 -248
- package/dist/clients/config-core/provenance.js +0 -164
- package/dist/clients/config-core/records.js +0 -218
- package/dist/clients/config-core/resolve.js +0 -125
- package/dist/clients/config-core/safe-object.js +0 -78
- package/dist/clients/config-core/schema.js +0 -165
- package/dist/clients/config-diagnostic-codes.js +0 -285
- package/dist/clients/config-locations.js +0 -388
- package/dist/clients/config-resolve.js +0 -798
- package/dist/clients/config-schema.js +0 -251
- package/dist/clients/config-warn.js +0 -407
- package/dist/clients/console-guard-install.js +0 -26
- package/dist/clients/cooperative-budget.js +0 -42
- package/dist/clients/dead-code-client.js +0 -510
- package/dist/clients/dead-code-logger.js +0 -30
- package/dist/clients/deadline-utils.js +0 -280
- package/dist/clients/debug-handles.js +0 -211
- package/dist/clients/debug-heap.js +0 -174
- package/dist/clients/deferred-lsp-work.js +0 -106
- package/dist/clients/degradation-ledger.js +0 -426
- package/dist/clients/demoted-finding-render.js +0 -169
- package/dist/clients/dependency-checker.js +0 -885
- package/dist/clients/deps/ast-grep-napi.js +0 -22
- package/dist/clients/deps/js-yaml.js +0 -9
- package/dist/clients/deps/minimatch.js +0 -4
- package/dist/clients/deps/pi-tui.js +0 -14
- package/dist/clients/deps/typebox.js +0 -14
- package/dist/clients/deps/vscode-jsonrpc.js +0 -1
- package/dist/clients/deps/web-tree-sitter.js +0 -24
- package/dist/clients/diagnostic-dispositions.js +0 -630
- package/dist/clients/diagnostic-line-freshness.js +0 -305
- package/dist/clients/diagnostic-logger.js +0 -73
- package/dist/clients/diagnostic-tracker.js +0 -105
- package/dist/clients/diagnostics-publish.js +0 -230
- package/dist/clients/dispatch/ast-grep-catalog.js +0 -65
- package/dist/clients/dispatch/auxiliary-lsp.js +0 -343
- package/dist/clients/dispatch/collect-later-tier.js +0 -35
- package/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
- package/dist/clients/dispatch/dispatcher.js +0 -1269
- package/dist/clients/dispatch/fact-provider-types.js +0 -1
- package/dist/clients/dispatch/fact-rule-runner.js +0 -17
- package/dist/clients/dispatch/fact-runner.js +0 -30
- package/dist/clients/dispatch/fact-scheduler.js +0 -68
- package/dist/clients/dispatch/fact-store.js +0 -377
- package/dist/clients/dispatch/facts/comment-facts.js +0 -22
- package/dist/clients/dispatch/facts/file-content.js +0 -19
- package/dist/clients/dispatch/facts/function-facts.js +0 -348
- package/dist/clients/dispatch/facts/import-facts.js +0 -204
- package/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
- package/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
- package/dist/clients/dispatch/finding-policy.js +0 -339
- package/dist/clients/dispatch/indent-detect.js +0 -417
- package/dist/clients/dispatch/inline-suppressions.js +0 -89
- package/dist/clients/dispatch/integration.js +0 -2377
- package/dist/clients/dispatch/lazy.js +0 -11
- package/dist/clients/dispatch/pending-runner-findings.js +0 -87
- package/dist/clients/dispatch/plan.js +0 -278
- package/dist/clients/dispatch/priorities.js +0 -20
- package/dist/clients/dispatch/rule-id-normalize.js +0 -50
- package/dist/clients/dispatch/rule-ignores.js +0 -69
- package/dist/clients/dispatch/rule-policy.js +0 -135
- package/dist/clients/dispatch/rules/async-noise.js +0 -40
- package/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
- package/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
- package/dist/clients/dispatch/rules/error-obscuring.js +0 -32
- package/dist/clients/dispatch/rules/error-swallowing.js +0 -31
- package/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
- package/dist/clients/dispatch/rules/high-complexity.js +0 -72
- package/dist/clients/dispatch/rules/high-fan-out.js +0 -74
- package/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
- package/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
- package/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
- package/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
- package/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
- package/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
- package/dist/clients/dispatch/runner-context.js +0 -52
- package/dist/clients/dispatch/runners/actionlint.js +0 -111
- package/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
- package/dist/clients/dispatch/runners/biome-check.js +0 -296
- package/dist/clients/dispatch/runners/cpp-check.js +0 -219
- package/dist/clients/dispatch/runners/credo.js +0 -82
- package/dist/clients/dispatch/runners/cue-vet.js +0 -416
- package/dist/clients/dispatch/runners/dart-analyze.js +0 -183
- package/dist/clients/dispatch/runners/detekt.js +0 -176
- package/dist/clients/dispatch/runners/dotnet-build.js +0 -164
- package/dist/clients/dispatch/runners/elixir-check.js +0 -195
- package/dist/clients/dispatch/runners/eslint.js +0 -137
- package/dist/clients/dispatch/runners/fact-rules.js +0 -29
- package/dist/clients/dispatch/runners/fish-indent.js +0 -69
- package/dist/clients/dispatch/runners/gleam-check.js +0 -167
- package/dist/clients/dispatch/runners/go-vet.js +0 -104
- package/dist/clients/dispatch/runners/golangci-lint.js +0 -135
- package/dist/clients/dispatch/runners/hadolint.js +0 -91
- package/dist/clients/dispatch/runners/helm-lint.js +0 -171
- package/dist/clients/dispatch/runners/helm-render.js +0 -940
- package/dist/clients/dispatch/runners/htmlhint.js +0 -117
- package/dist/clients/dispatch/runners/index.js +0 -108
- package/dist/clients/dispatch/runners/javac.js +0 -99
- package/dist/clients/dispatch/runners/ktlint.js +0 -110
- package/dist/clients/dispatch/runners/lsp.js +0 -379
- package/dist/clients/dispatch/runners/markdownlint.js +0 -167
- package/dist/clients/dispatch/runners/mypy.js +0 -102
- package/dist/clients/dispatch/runners/oxlint.js +0 -414
- package/dist/clients/dispatch/runners/php-lint.js +0 -85
- package/dist/clients/dispatch/runners/phpstan.js +0 -120
- package/dist/clients/dispatch/runners/prisma-validate.js +0 -62
- package/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
- package/dist/clients/dispatch/runners/pyright.js +0 -169
- package/dist/clients/dispatch/runners/rubocop.js +0 -99
- package/dist/clients/dispatch/runners/ruff.js +0 -88
- package/dist/clients/dispatch/runners/rust-clippy.js +0 -256
- package/dist/clients/dispatch/runners/shellcheck.js +0 -173
- package/dist/clients/dispatch/runners/shfmt.js +0 -102
- package/dist/clients/dispatch/runners/spellcheck.js +0 -128
- package/dist/clients/dispatch/runners/spotbugs.js +0 -259
- package/dist/clients/dispatch/runners/sqlfluff.js +0 -183
- package/dist/clients/dispatch/runners/stylelint.js +0 -166
- package/dist/clients/dispatch/runners/swiftlint.js +0 -163
- package/dist/clients/dispatch/runners/taplo.js +0 -174
- package/dist/clients/dispatch/runners/terragrunt.js +0 -168
- package/dist/clients/dispatch/runners/tflint.js +0 -125
- package/dist/clients/dispatch/runners/tree-sitter.js +0 -643
- package/dist/clients/dispatch/runners/trivy-config.js +0 -253
- package/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
- package/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
- package/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -95
- package/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
- package/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
- package/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
- package/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
- package/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
- package/dist/clients/dispatch/runners/utils.js +0 -15
- package/dist/clients/dispatch/runners/vale.js +0 -128
- package/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
- package/dist/clients/dispatch/runners/yamllint.js +0 -95
- package/dist/clients/dispatch/runners/zig-check.js +0 -79
- package/dist/clients/dispatch/suppress-writer.js +0 -79
- package/dist/clients/dispatch/tool-profile.js +0 -30
- package/dist/clients/dispatch/types.js +0 -21
- package/dist/clients/dispatch/utils/format-utils.js +0 -45
- package/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
- package/dist/clients/disposition-logger.js +0 -32
- package/dist/clients/disposition-publish.js +0 -124
- package/dist/clients/durable-store.js +0 -97
- package/dist/clients/effective-config.js +0 -415
- package/dist/clients/env-utils.js +0 -83
- package/dist/clients/error-class.js +0 -23
- package/dist/clients/eval-timestamp.js +0 -17
- package/dist/clients/event-loop-hold.js +0 -274
- package/dist/clients/event-loop-monitor.js +0 -250
- package/dist/clients/extension-log.js +0 -504
- package/dist/clients/extension-mode.js +0 -73
- package/dist/clients/feature-hints.js +0 -103
- package/dist/clients/file-kinds.js +0 -412
- package/dist/clients/file-role.js +0 -134
- package/dist/clients/file-time.js +0 -160
- package/dist/clients/file-utils.js +0 -1032
- package/dist/clients/finding-delivery-gate.js +0 -494
- package/dist/clients/finding-identity.js +0 -88
- package/dist/clients/fix-worklog.js +0 -103
- package/dist/clients/format-events-publish.js +0 -343
- package/dist/clients/format-service.js +0 -222
- package/dist/clients/formatters-lazy.js +0 -9
- package/dist/clients/formatters.js +0 -2032
- package/dist/clients/freshness-cadence.js +0 -17
- package/dist/clients/freshness.js +0 -38
- package/dist/clients/generated-artifacts.js +0 -394
- package/dist/clients/generation-guard.js +0 -215
- package/dist/clients/git-guard.js +0 -1136
- package/dist/clients/git-tracked-ignore.js +0 -243
- package/dist/clients/gitleaks-client.js +0 -509
- package/dist/clients/go-client.js +0 -104
- package/dist/clients/govulncheck-client.js +0 -605
- package/dist/clients/gradle-ktfmt-style.js +0 -348
- package/dist/clients/grammar-source.js +0 -465
- package/dist/clients/gzip-stage-write.js +0 -135
- package/dist/clients/hashline-anchor.js +0 -424
- package/dist/clients/hook-budgets.js +0 -76
- package/dist/clients/host-edit-normalize.js +0 -140
- package/dist/clients/host-ports.js +0 -39
- package/dist/clients/indent-retarget.js +0 -154
- package/dist/clients/inline-blocker-dispositions.js +0 -186
- package/dist/clients/install-diagnostics.js +0 -156
- package/dist/clients/installer/index.js +0 -5416
- package/dist/clients/installer/managed-tool-refresh-session.js +0 -58
- package/dist/clients/installer/managed-tool-refresh.js +0 -783
- package/dist/clients/instance-reaper-state.js +0 -7
- package/dist/clients/instance-reaper.js +0 -1137
- package/dist/clients/instance-registry-lock.js +0 -145
- package/dist/clients/instance-registry.js +0 -773
- package/dist/clients/jscpd-client.js +0 -378
- package/dist/clients/json-cache-read.js +0 -65
- package/dist/clients/knip-client.js +0 -788
- package/dist/clients/language-policy.js +0 -252
- package/dist/clients/language-profile.js +0 -361
- package/dist/clients/language-registry.js +0 -603
- package/dist/clients/latency-logger.js +0 -727
- package/dist/clients/lazy-import.js +0 -21
- package/dist/clients/ledger-bounds.js +0 -54
- package/dist/clients/lens-config.js +0 -404
- package/dist/clients/lens-engine.js +0 -358
- package/dist/clients/lens-events.js +0 -125
- package/dist/clients/lens-flag-registry.js +0 -467
- package/dist/clients/lens-map.js +0 -1156
- package/dist/clients/live-bus-emitter.js +0 -74
- package/dist/clients/log-cleanup.js +0 -222
- package/dist/clients/lsp/aggregation.js +0 -178
- package/dist/clients/lsp/cascade-tier.js +0 -421
- package/dist/clients/lsp/client.js +0 -4593
- package/dist/clients/lsp/config.js +0 -691
- package/dist/clients/lsp/content-limits.js +0 -41
- package/dist/clients/lsp/diagnostic-binding.js +0 -225
- package/dist/clients/lsp/document-drift.js +0 -467
- package/dist/clients/lsp/edits.js +0 -1219
- package/dist/clients/lsp/index.js +0 -8305
- package/dist/clients/lsp/inferred-project.js +0 -216
- package/dist/clients/lsp/jvm-runtime.js +0 -298
- package/dist/clients/lsp/language.js +0 -63
- package/dist/clients/lsp/launch.js +0 -746
- package/dist/clients/lsp/lombok.js +0 -158
- package/dist/clients/lsp/path-utils.js +0 -5
- package/dist/clients/lsp/pending-aux-coverage.js +0 -251
- package/dist/clients/lsp/position-encoding.js +0 -61
- package/dist/clients/lsp/ruby-drive-dirs.js +0 -83
- package/dist/clients/lsp/server.js +0 -3290
- package/dist/clients/lsp/session-roots.js +0 -192
- package/dist/clients/lsp/spawn-history.js +0 -17
- package/dist/clients/lsp/sync-kind.js +0 -56
- package/dist/clients/lsp/tsserver-sync.js +0 -332
- package/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
- package/dist/clients/lsp/wait-policy/classification.js +0 -85
- package/dist/clients/lsp/wait-policy/index.js +0 -10
- package/dist/clients/lsp/wait-policy/strategies.js +0 -392
- package/dist/clients/lsp/watch-queue.js +0 -61
- package/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
- package/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
- package/dist/clients/lsp/workspace-sweep-hold.js +0 -184
- package/dist/clients/lsp-budget.js +0 -186
- package/dist/clients/lsp-document-symbols.js +0 -110
- package/dist/clients/lsp-lazy.js +0 -9
- package/dist/clients/lsp-mutation.js +0 -396
- package/dist/clients/lsp-status.js +0 -59
- package/dist/clients/map-with-concurrency.js +0 -40
- package/dist/clients/mcp/analyze.js +0 -420
- package/dist/clients/mcp/host-shim.js +0 -31
- package/dist/clients/mcp/ipc.js +0 -523
- package/dist/clients/mcp/review.js +0 -197
- package/dist/clients/mcp/session.js +0 -412
- package/dist/clients/memory-sampler.js +0 -208
- package/dist/clients/message-end-attribution.js +0 -30
- package/dist/clients/metrics-client.js +0 -107
- package/dist/clients/metrics-history.js +0 -327
- package/dist/clients/middle-man-analysis.js +0 -263
- package/dist/clients/model-provider.js +0 -53
- package/dist/clients/module-report-lsp.js +0 -189
- package/dist/clients/module-report.js +0 -2150
- package/dist/clients/mutating-tool.js +0 -651
- package/dist/clients/mutation-attribution.js +0 -368
- package/dist/clients/mutation-bridge.js +0 -240
- package/dist/clients/ndjson-logger.js +0 -734
- package/dist/clients/observed-mutation-sources.js +0 -101
- package/dist/clients/observed-mutation.js +0 -1253
- package/dist/clients/oldtext-autopatch.js +0 -128
- package/dist/clients/opaque-mutation-scan.js +0 -496
- package/dist/clients/opengrep-client.js +0 -333
- package/dist/clients/opengrep-config.js +0 -76
- package/dist/clients/package-manager.js +0 -607
- package/dist/clients/package-root.js +0 -38
- package/dist/clients/partial-edit-apply.js +0 -439
- package/dist/clients/path-attribution-telemetry.js +0 -43
- package/dist/clients/path-keyed-map.js +0 -108
- package/dist/clients/path-utils.js +0 -1244
- package/dist/clients/performance-report.js +0 -331
- package/dist/clients/persist-debounce.js +0 -70
- package/dist/clients/persistent-reverify.js +0 -271
- package/dist/clients/php-cs-fixer-config.js +0 -119
- package/dist/clients/pipeline.js +0 -1480
- package/dist/clients/post-autofix-notice.js +0 -37
- package/dist/clients/print-mode.js +0 -21
- package/dist/clients/probe-home-state.js +0 -228
- package/dist/clients/process-bridge.js +0 -66
- package/dist/clients/process-singletons.js +0 -210
- package/dist/clients/process-snapshot.js +0 -68
- package/dist/clients/project-changes.js +0 -181
- package/dist/clients/project-conventions.js +0 -171
- package/dist/clients/project-diagnostics/cache.js +0 -137
- package/dist/clients/project-diagnostics/extractors.js +0 -109
- package/dist/clients/project-diagnostics/fresh-fetch.js +0 -668
- package/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
- package/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
- package/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
- package/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
- package/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
- package/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
- package/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
- package/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
- package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
- package/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
- package/dist/clients/project-diagnostics/scanner.js +0 -520
- package/dist/clients/project-diagnostics/types.js +0 -1
- package/dist/clients/project-lens-config.js +0 -807
- package/dist/clients/project-report.js +0 -701
- package/dist/clients/project-scale.js +0 -237
- package/dist/clients/project-scan-policy.js +0 -11
- package/dist/clients/project-snapshot-fingerprint.js +0 -48
- package/dist/clients/project-snapshot-persist-worker.js +0 -20
- package/dist/clients/project-snapshot.js +0 -1653
- package/dist/clients/project-trust.js +0 -181
- package/dist/clients/python-environment.js +0 -217
- package/dist/clients/python-provenance.js +0 -639
- package/dist/clients/quiet-window-config.js +0 -47
- package/dist/clients/quiet-window.js +0 -236
- package/dist/clients/read-bridge.js +0 -139
- package/dist/clients/read-expansion.js +0 -266
- package/dist/clients/read-guard-logger.js +0 -251
- package/dist/clients/read-guard-tool-lines.js +0 -1306
- package/dist/clients/read-guard.js +0 -1561
- package/dist/clients/recent-touches.js +0 -240
- package/dist/clients/redact/secrets.js +0 -449
- package/dist/clients/resource-sampler.js +0 -628
- package/dist/clients/reverse-deps.js +0 -270
- package/dist/clients/review-graph/builder.js +0 -5126
- package/dist/clients/review-graph/format.js +0 -33
- package/dist/clients/review-graph/git-identity.js +0 -163
- package/dist/clients/review-graph/import-resolvers.js +0 -481
- package/dist/clients/review-graph/persist-worker.js +0 -10
- package/dist/clients/review-graph/query.js +0 -244
- package/dist/clients/review-graph/revision-drift.js +0 -21
- package/dist/clients/review-graph/service.js +0 -96
- package/dist/clients/review-graph/shared-extraction-ir.js +0 -82
- package/dist/clients/review-graph/symbol-id.js +0 -103
- package/dist/clients/review-graph/tsconfig-paths.js +0 -299
- package/dist/clients/review-graph/types.js +0 -1
- package/dist/clients/review-graph/workspace-modules.js +0 -449
- package/dist/clients/review-graph-logger.js +0 -81
- package/dist/clients/ruff-client.js +0 -179
- package/dist/clients/rules-scanner.js +0 -131
- package/dist/clients/run-duration.js +0 -55
- package/dist/clients/runtime-agent-end.js +0 -746
- package/dist/clients/runtime-config.js +0 -77
- package/dist/clients/runtime-context.js +0 -211
- package/dist/clients/runtime-coordinator.js +0 -1324
- package/dist/clients/runtime-session.js +0 -2485
- package/dist/clients/runtime-tool-call.js +0 -1295
- package/dist/clients/runtime-tool-result.js +0 -2049
- package/dist/clients/runtime-turn.js +0 -3767
- package/dist/clients/rust-client.js +0 -97
- package/dist/clients/safe-spawn.js +0 -2357
- package/dist/clients/sanitize.js +0 -286
- package/dist/clients/scan-utils.js +0 -25
- package/dist/clients/scratch-tree-policy.js +0 -165
- package/dist/clients/search-read-registration.js +0 -94
- package/dist/clients/secret-findings.js +0 -114
- package/dist/clients/security-scan-client.js +0 -352
- package/dist/clients/session-event-guard.js +0 -297
- package/dist/clients/session-lifecycle.js +0 -484
- package/dist/clients/session-start-observability.js +0 -94
- package/dist/clients/session-state-store.js +0 -101
- package/dist/clients/session-summary.js +0 -15
- package/dist/clients/sessionstart-logger.js +0 -27
- package/dist/clients/sg-runner.js +0 -876
- package/dist/clients/sgconfig.js +0 -347
- package/dist/clients/shared-checkout-guard.js +0 -338
- package/dist/clients/single-flight.js +0 -158
- package/dist/clients/situational-tool-telemetry.js +0 -108
- package/dist/clients/skills-resolver.js +0 -141
- package/dist/clients/slow-fs.js +0 -138
- package/dist/clients/smells-rollup.js +0 -231
- package/dist/clients/source-filter.js +0 -596
- package/dist/clients/source-walker.js +0 -211
- package/dist/clients/spawn-output-cap.js +0 -120
- package/dist/clients/spawn-timeout-cooldown.js +0 -110
- package/dist/clients/stale-marker.js +0 -17
- package/dist/clients/startup-scan.js +0 -400
- package/dist/clients/startup-timing.js +0 -130
- package/dist/clients/string-utils.js +0 -33
- package/dist/clients/subagent-mode.js +0 -111
- package/dist/clients/symbol-containment.js +0 -24
- package/dist/clients/symbol-types.js +0 -5
- package/dist/clients/test-runner-client.js +0 -2507
- package/dist/clients/test-runner-delivery.js +0 -287
- package/dist/clients/todo-scanner.js +0 -229
- package/dist/clients/tool-agreement.js +0 -423
- package/dist/clients/tool-config.js +0 -249
- package/dist/clients/tool-cwd.js +0 -270
- package/dist/clients/tool-definition.js +0 -47
- package/dist/clients/tool-event.js +0 -105
- package/dist/clients/tool-policy.js +0 -2755
- package/dist/clients/tool-probe.js +0 -53
- package/dist/clients/tool-render.js +0 -156
- package/dist/clients/tool-set-policy.js +0 -118
- package/dist/clients/tree-sitter-cache.js +0 -364
- package/dist/clients/tree-sitter-client.js +0 -4195
- package/dist/clients/tree-sitter-logger.js +0 -100
- package/dist/clients/tree-sitter-navigator.js +0 -269
- package/dist/clients/tree-sitter-query-loader.js +0 -569
- package/dist/clients/tree-sitter-shared.js +0 -158
- package/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
- package/dist/clients/trivy-client.js +0 -467
- package/dist/clients/tui-fit.js +0 -50
- package/dist/clients/turn-context.js +0 -52
- package/dist/clients/turn-end/lane.js +0 -51
- package/dist/clients/turn-end/lanes/govulncheck.js +0 -112
- package/dist/clients/turn-end/lanes/secrets.js +0 -204
- package/dist/clients/turn-summary-render.js +0 -72
- package/dist/clients/turn-summary.js +0 -132
- package/dist/clients/typos-config.js +0 -29
- package/dist/clients/user-notify.js +0 -51
- package/dist/clients/vanished-instance-marker.js +0 -57
- package/dist/clients/warm-attach.js +0 -305
- package/dist/clients/widget-state.js +0 -1808
- package/dist/clients/word-index-logger.js +0 -49
- package/dist/clients/word-index-store.js +0 -459
- package/dist/clients/word-index.js +0 -2080
- package/dist/clients/workspace-topology.js +0 -443
- package/dist/clients/write-ordering-guard.js +0 -65
- package/dist/clients/zizmor-config.js +0 -340
- package/dist/i18n.js +0 -69
- package/dist/mcp/build-staleness.js +0 -124
- package/dist/scripts/lib/process-scan.mjs +0 -583
- package/dist/scripts/lib/skills-predicate.mjs +0 -129
- package/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -123
- package/dist/tools/activate-tools.js +0 -87
- package/dist/tools/ast-grep-outline.js +0 -137
- package/dist/tools/ast-grep-replace.js +0 -244
- package/dist/tools/ast-grep-search.js +0 -762
- package/dist/tools/effective-config.js +0 -90
- package/dist/tools/lens-diagnostic-mark.js +0 -375
- package/dist/tools/lens-diagnostics.js +0 -2571
- package/dist/tools/lsp-diagnostics.js +0 -1745
- package/dist/tools/lsp-navigation.js +0 -1367
- package/dist/tools/lsp-structured-output.js +0 -294
- package/dist/tools/module-report.js +0 -382
- package/dist/tools/project-report.js +0 -86
- package/dist/tools/render-compact.js +0 -374
- package/dist/tools/scan-progress.js +0 -53
- package/dist/tools/shared.js +0 -29
- package/dist/tools/symbol-search.js +0 -155
|
@@ -1,746 +0,0 @@
|
|
|
1
|
-
import * as nodeFs from "node:fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { applyConservativeActionableWarningFixes, checkActionableWarningsReportFresh, } from "./actionable-warnings.js";
|
|
4
|
-
import { publishFilesTouched } from "./bus-publish.js";
|
|
5
|
-
import { publishAutofixStart, publishFormatStart, } from "./format-events-publish.js";
|
|
6
|
-
import { logLatency } from "./latency-logger.js";
|
|
7
|
-
import { isPathIgnoredByProject } from "./file-utils.js";
|
|
8
|
-
import { admitBounded, emitBounded } from "./bounded-telemetry.js";
|
|
9
|
-
import { bounded } from "./deadline-utils.js";
|
|
10
|
-
import { HOOK_WALL_BUDGET_MS } from "./hook-budgets.js";
|
|
11
|
-
import { newLspMutationCorrelationId, } from "./lsp-mutation.js";
|
|
12
|
-
import { getGlobalActionableWarningMaxFixes, } from "./lens-config.js";
|
|
13
|
-
import { resyncLspFile, runAutofix, runFormatPhase } from "./pipeline.js";
|
|
14
|
-
import { getAmbientAbortSignal } from "./safe-spawn.js";
|
|
15
|
-
import { getAutofixPolicyForFile, hasBiomeConfig, hasDetektConfig, hasEslintConfig, hasGolangciConfig, hasKtfmtConfig, hasKtlintConfig, hasOxlintConfig, hasRubocopConfig, hasSqlfluffConfig, hasStylelintConfig, } from "./tool-policy.js";
|
|
16
|
-
/**
|
|
17
|
-
* A queued file is claimed by any flush once it has sat unclaimed by its own
|
|
18
|
-
* owning session for this long — recovery for an orphaned record whose
|
|
19
|
-
* owner (e.g. a primary session that crashed mid-run) will never flush it
|
|
20
|
-
* itself. Generous on purpose: normal same-session flushes never hit this
|
|
21
|
-
* path at all (they match on `ownerSessionId`), so this only trades a little
|
|
22
|
-
* extra staleness for guaranteed eventual formatting. (#791)
|
|
23
|
-
*/
|
|
24
|
-
const DEFERRED_FORMAT_STALE_AFTER_MS = 10 * 60_000;
|
|
25
|
-
const DEFERRED_FORMAT_CONCURRENCY = 3;
|
|
26
|
-
function recordProjectChange(args) {
|
|
27
|
-
// One mutation seam (#2000 phase 1): bump + receipt + change-log live in
|
|
28
|
-
// RuntimeCoordinator.recordProjectMutation; this wrapper only carries the
|
|
29
|
-
// legacy dbg shape.
|
|
30
|
-
args.runtime.recordProjectMutation?.({
|
|
31
|
-
filePath: args.filePath,
|
|
32
|
-
source: args.source,
|
|
33
|
-
cwd: args.cwd,
|
|
34
|
-
onAppendError: (err) => args.dbg(`project change log append failed for ${args.filePath}: ${err}`),
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
export async function handleAgentEnd({ signal, ctxCwd, getFlag, getFlagSource, notify, dbg, runtime, cacheManager, getFormatService, biomeClient, ruffClient, getAutofixClients, currentSessionId, staleAfterMs = DEFERRED_FORMAT_STALE_AFTER_MS, }) {
|
|
38
|
-
// #791: ownership-filtered drain — records queued by a DIFFERENT known
|
|
39
|
-
// session (e.g. a concurrent in-process secondary/subagent) stay queued
|
|
40
|
-
// for their owner's own agent_end, unless they've been stale long enough
|
|
41
|
-
// to fall back to "claim as orphaned" (see claimDeferredFormatFiles).
|
|
42
|
-
const { claimed, staleClaimed, deferredToOwner, droppedOrphans } = runtime.claimDeferredMutations(currentSessionId, Date.now(), staleAfterMs, ctxCwd ?? runtime.projectRoot);
|
|
43
|
-
const records = [...claimed, ...staleClaimed];
|
|
44
|
-
const scheduledTurnId = records[0]?.queuedTurnId;
|
|
45
|
-
const requeuedKinds = new Set();
|
|
46
|
-
// S2d (gap 4, #1432 review): the aggregate `agent_end_deferred_mutation_drain`
|
|
47
|
-
// row only carried a coalesced `requeuedKinds` set with no reason, per-call
|
|
48
|
-
// file count, or tool provenance — every requeue (abort mid-drain, missing
|
|
49
|
-
// autofix clients, an autofix/format failure) collapsed into one
|
|
50
|
-
// indistinguishable bucket. Log one bounded record PER requeue call instead,
|
|
51
|
-
// so a real incident can tell "aborted with N files still queued" apart
|
|
52
|
-
// from "M files failed to format".
|
|
53
|
-
const requeue = (pending, reason) => {
|
|
54
|
-
if (pending.length === 0)
|
|
55
|
-
return;
|
|
56
|
-
const kinds = new Set();
|
|
57
|
-
const toolNames = new Set();
|
|
58
|
-
for (const record of pending) {
|
|
59
|
-
for (const kind of record.kinds) {
|
|
60
|
-
requeuedKinds.add(kind);
|
|
61
|
-
kinds.add(kind);
|
|
62
|
-
}
|
|
63
|
-
for (const toolName of record.toolNames)
|
|
64
|
-
toolNames.add(toolName);
|
|
65
|
-
}
|
|
66
|
-
logLatency({
|
|
67
|
-
type: "phase",
|
|
68
|
-
toolName: "agent_end",
|
|
69
|
-
filePath: ctxCwd ?? runtime.projectRoot,
|
|
70
|
-
phase: "agent_end_deferred_mutation_requeue",
|
|
71
|
-
turnId: pending[0]?.queuedTurnId,
|
|
72
|
-
durationMs: 0,
|
|
73
|
-
metadata: {
|
|
74
|
-
reason,
|
|
75
|
-
kinds: [...kinds].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)),
|
|
76
|
-
fileCount: pending.length,
|
|
77
|
-
toolNames: [...toolNames].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)),
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
runtime.requeueDeferredMutations(pending);
|
|
81
|
-
};
|
|
82
|
-
const rootActionableAutofixEnabled = !!getFlag("lens-actionable-warning-autofix");
|
|
83
|
-
// The actionable-warnings cache is only ever written when the
|
|
84
|
-
// "lens-actionable-warnings" writer flag is on (clients/runtime-turn.ts).
|
|
85
|
-
// A reader that ignores this gate always misses in a host where the
|
|
86
|
-
// writer is off and logs "cache missing or expired" at every agent_end,
|
|
87
|
-
// misdirecting the debug log toward a bogus cache problem instead of the
|
|
88
|
-
// real cause: the feature that populates the cache is disabled (#1607).
|
|
89
|
-
const actionableWarningsWriterEnabled = !!getFlag("lens-actionable-warnings");
|
|
90
|
-
// A path-aware source resolver signals that nested configs may re-enable
|
|
91
|
-
// actionable autofix even when the root default is off. Legacy/test hosts
|
|
92
|
-
// without that resolver keep the old fast exit and avoid a cache read.
|
|
93
|
-
const inspectActionableReport = actionableWarningsWriterEnabled &&
|
|
94
|
-
typeof cacheManager.readCache === "function" &&
|
|
95
|
-
(rootActionableAutofixEnabled || getFlagSource !== undefined);
|
|
96
|
-
if (droppedOrphans.length > 0) {
|
|
97
|
-
// #1642 F3: a stale/foreign record whose origin (the cwd/worktree it
|
|
98
|
-
// was actually queued under) does NOT match this flush's own
|
|
99
|
-
// workspace/worktree is left queued and NEVER formatted by this
|
|
100
|
-
// flush — claiming it would be the same worktree→parent
|
|
101
|
-
// re-attribution the reported incident hit, just via the orphan
|
|
102
|
-
// fallback instead of tool_result's path resolution. It stays in
|
|
103
|
-
// `_pendingDeferredMutations` (not deleted) so a flush whose origin
|
|
104
|
-
// actually matches can still claim it later; a genuinely abandoned
|
|
105
|
-
// origin will keep surfacing this record on every subsequent
|
|
106
|
-
// agent_end, which is the deliberately safer trade-off over silently
|
|
107
|
-
// losing it forever.
|
|
108
|
-
dbg(`agent_end deferred_format: left ${droppedOrphans.length} orphaned file(s) queued due to a mismatched origin (unclaimed >${staleAfterMs}ms, not formatted by this flush): ${droppedOrphans
|
|
109
|
-
.map((r) => `${r.filePath} origin=${r.originCwd}`)
|
|
110
|
-
.join(", ")}`);
|
|
111
|
-
// #1678 item 1: a genuinely abandoned origin re-surfaces the SAME
|
|
112
|
-
// record on every subsequent agent_end for as long as the queued
|
|
113
|
-
// entry lives — by design (see the comment above), but the repo
|
|
114
|
-
// invariant is that a repeated degradation goes through the ledger's
|
|
115
|
-
// counting path instead of accumulating as unbounded raw log lines.
|
|
116
|
-
// The ledger is the single source of truth for whether THIS is a
|
|
117
|
-
// record's first appearance (its return value): the detailed forensic
|
|
118
|
-
// record below names only the orphans on that rising edge, with file
|
|
119
|
-
// identity/origin/age. Every later repeat of
|
|
120
|
-
// the same record is counted ONLY by the ledger's running count —
|
|
121
|
-
// no second raw event, no parallel "already logged" latch to
|
|
122
|
-
// maintain here.
|
|
123
|
-
// #1743: `admitBounded` IS that ledger call, plus the registry
|
|
124
|
-
// membership the bounded-telemetry sweep checks. This site admits PER
|
|
125
|
-
// ORPHAN and then writes ONE batched record naming the admitted ones,
|
|
126
|
-
// which is why it uses `admitBounded` directly instead of a per-record
|
|
127
|
-
// `emitBounded` — the per-call form would turn one log line into N.
|
|
128
|
-
const firstSeenOrphans = [];
|
|
129
|
-
for (const record of droppedOrphans) {
|
|
130
|
-
const isFirstOccurrence = admitBounded("agent_end_deferred_format_orphan_origin_mismatch", record.filePath, {
|
|
131
|
-
ledgerKind: "path-attribution-orphan-unresolved",
|
|
132
|
-
risingEdgePer: "identity",
|
|
133
|
-
reason: `origin=${record.originCwd} unclaimed >${staleAfterMs}ms`,
|
|
134
|
-
});
|
|
135
|
-
if (isFirstOccurrence)
|
|
136
|
-
firstSeenOrphans.push(record);
|
|
137
|
-
}
|
|
138
|
-
if (firstSeenOrphans.length > 0) {
|
|
139
|
-
// Already admitted above, one orphan at a time — hence no bounding
|
|
140
|
-
// options here. The batch's own identity is the origin this flush ran
|
|
141
|
-
// under; per-file identity rides in `metadata.files`.
|
|
142
|
-
emitBounded("agent_end_deferred_format_orphan_origin_mismatch", ctxCwd ?? runtime.projectRoot, {
|
|
143
|
-
type: "phase",
|
|
144
|
-
toolName: "agent_end",
|
|
145
|
-
durationMs: 0,
|
|
146
|
-
metadata: {
|
|
147
|
-
fileCount: firstSeenOrphans.length,
|
|
148
|
-
staleAfterMs,
|
|
149
|
-
currentOriginCwd: ctxCwd ?? runtime.projectRoot,
|
|
150
|
-
files: firstSeenOrphans.map((r) => ({
|
|
151
|
-
filePath: r.filePath,
|
|
152
|
-
originCwd: r.originCwd,
|
|
153
|
-
ownerSessionId: r.ownerSessionId,
|
|
154
|
-
queuedTurnIndex: r.queuedTurnIndex,
|
|
155
|
-
ageMs: Date.now() - r.lastTouchedAt,
|
|
156
|
-
})),
|
|
157
|
-
},
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
if (records.length === 0 && !inspectActionableReport)
|
|
162
|
-
return undefined;
|
|
163
|
-
if (deferredToOwner.length > 0) {
|
|
164
|
-
dbg(`agent_end deferred_format: leaving ${deferredToOwner.length} file(s) queued for their owning session (${deferredToOwner
|
|
165
|
-
.map((r) => `${r.filePath} owner=${r.ownerSessionId}`)
|
|
166
|
-
.join(", ")})`);
|
|
167
|
-
}
|
|
168
|
-
if (staleClaimed.length > 0) {
|
|
169
|
-
dbg(`agent_end deferred_format: staleness fallback claimed ${staleClaimed.length} orphaned file(s) (unclaimed >${staleAfterMs}ms): ${staleClaimed
|
|
170
|
-
.map((r) => r.filePath)
|
|
171
|
-
.join(", ")}`);
|
|
172
|
-
logLatency({
|
|
173
|
-
type: "phase",
|
|
174
|
-
toolName: "agent_end",
|
|
175
|
-
filePath: ctxCwd ?? runtime.projectRoot,
|
|
176
|
-
phase: "agent_end_deferred_format_stale_claim",
|
|
177
|
-
turnId: scheduledTurnId,
|
|
178
|
-
durationMs: 0,
|
|
179
|
-
metadata: {
|
|
180
|
-
fileCount: staleClaimed.length,
|
|
181
|
-
staleAfterMs,
|
|
182
|
-
files: staleClaimed.map((r) => ({
|
|
183
|
-
filePath: r.filePath,
|
|
184
|
-
ownerSessionId: r.ownerSessionId,
|
|
185
|
-
queuedTurnIndex: r.queuedTurnIndex,
|
|
186
|
-
ageMs: Date.now() - r.lastTouchedAt,
|
|
187
|
-
})),
|
|
188
|
-
},
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
const startedAt = Date.now();
|
|
192
|
-
const summary = {
|
|
193
|
-
queued: records.length,
|
|
194
|
-
formatted: 0,
|
|
195
|
-
changed: [],
|
|
196
|
-
failed: [],
|
|
197
|
-
skipped: [],
|
|
198
|
-
unavailable: [],
|
|
199
|
-
};
|
|
200
|
-
// #502 fix provenance: per-path {tool, kind} entries accumulated across the
|
|
201
|
-
// deferred-format loop below, passed as `fixes` on the batch
|
|
202
|
-
// publishFilesTouched call so consumers can tell "pi-lens formatted this"
|
|
203
|
-
// from an agent edit.
|
|
204
|
-
const deferredFormatFixes = [];
|
|
205
|
-
const deferredAutofixFixes = [];
|
|
206
|
-
const deferredAutofixChanged = new Set();
|
|
207
|
-
// Mutation ordering is intentional: lint --write may disturb wrapping, so
|
|
208
|
-
// autofix reaches the final edited state first and formatting stabilizes it.
|
|
209
|
-
const ambientSignal = signal ?? getAmbientAbortSignal();
|
|
210
|
-
const executedAutofixScopes = new Set();
|
|
211
|
-
const autofixRecords = records.filter((candidate) => candidate.kinds.has("autofix"));
|
|
212
|
-
if (autofixRecords.length > 0 &&
|
|
213
|
-
(!biomeClient || !ruffClient) &&
|
|
214
|
-
getAutofixClients) {
|
|
215
|
-
({ biomeClient, ruffClient } = await getAutofixClients());
|
|
216
|
-
}
|
|
217
|
-
for (let autofixIndex = 0; autofixIndex < autofixRecords.length; autofixIndex++) {
|
|
218
|
-
const record = autofixRecords[autofixIndex];
|
|
219
|
-
if (ambientSignal?.aborted) {
|
|
220
|
-
requeue(autofixRecords.slice(autofixIndex).map((pending) => ({
|
|
221
|
-
...pending,
|
|
222
|
-
kinds: new Set(["autofix"]),
|
|
223
|
-
toolNames: new Set(pending.toolNames),
|
|
224
|
-
})), "abort");
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
227
|
-
const filePath = path.resolve(record.filePath);
|
|
228
|
-
if (!nodeFs.existsSync(filePath)) {
|
|
229
|
-
summary.skipped.push({ filePath, reason: "missing" });
|
|
230
|
-
continue;
|
|
231
|
-
}
|
|
232
|
-
if (!biomeClient || !ruffClient) {
|
|
233
|
-
dbg(`agent_end deferred_autofix: clients unavailable for ${filePath}`);
|
|
234
|
-
requeue([
|
|
235
|
-
{
|
|
236
|
-
...record,
|
|
237
|
-
kinds: new Set(["autofix"]),
|
|
238
|
-
toolNames: new Set(record.toolNames),
|
|
239
|
-
},
|
|
240
|
-
], "clients-unavailable");
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
const policy = getAutofixPolicyForFile(filePath, {
|
|
244
|
-
hasEslintConfig: hasEslintConfig(record.cwd),
|
|
245
|
-
hasStylelintConfig: hasStylelintConfig(record.cwd),
|
|
246
|
-
hasSqlfluffConfig: hasSqlfluffConfig(record.cwd),
|
|
247
|
-
hasRubocopConfig: hasRubocopConfig(record.cwd),
|
|
248
|
-
hasBiomeConfig: hasBiomeConfig(record.cwd),
|
|
249
|
-
hasGolangciConfig: hasGolangciConfig(record.cwd),
|
|
250
|
-
hasDetektConfig: hasDetektConfig(record.cwd),
|
|
251
|
-
hasOxlintConfig: hasOxlintConfig(record.cwd),
|
|
252
|
-
hasKtfmtConfig: hasKtfmtConfig(record.cwd),
|
|
253
|
-
hasKtlintConfig: hasKtlintConfig(record.cwd),
|
|
254
|
-
});
|
|
255
|
-
const scopeKey = policy?.scope && policy.scope !== "file"
|
|
256
|
-
? `${policy.defaultTool ?? "unknown"}:${path.resolve(record.cwd)}`
|
|
257
|
-
: `${policy?.defaultTool ?? "unknown"}:${filePath}`;
|
|
258
|
-
if (executedAutofixScopes.has(scopeKey))
|
|
259
|
-
continue;
|
|
260
|
-
executedAutofixScopes.add(scopeKey);
|
|
261
|
-
try {
|
|
262
|
-
const result = await runAutofix(filePath, record.cwd, getFlag, dbg, { biomeClient, ruffClient, fixedThisTurn: runtime.fixedThisTurn }, getFlagSource);
|
|
263
|
-
const tools = result.autofixTools.map((label) => label.split(":")[0]);
|
|
264
|
-
for (const changed of result.changedFiles) {
|
|
265
|
-
const changedPath = path.resolve(changed);
|
|
266
|
-
deferredAutofixChanged.add(changedPath);
|
|
267
|
-
for (const tool of tools)
|
|
268
|
-
deferredAutofixFixes.push({
|
|
269
|
-
path: changedPath,
|
|
270
|
-
tool,
|
|
271
|
-
kind: "autofix",
|
|
272
|
-
});
|
|
273
|
-
if (!nodeFs.existsSync(changedPath))
|
|
274
|
-
continue;
|
|
275
|
-
recordProjectChange({
|
|
276
|
-
runtime,
|
|
277
|
-
cwd: record.turnStateCwd,
|
|
278
|
-
filePath: changedPath,
|
|
279
|
-
source: "autofix",
|
|
280
|
-
dbg,
|
|
281
|
-
});
|
|
282
|
-
if (!getFlag("no-read-guard"))
|
|
283
|
-
runtime.readGuard.recordWritten(changedPath);
|
|
284
|
-
const content = nodeFs.readFileSync(changedPath, "utf-8");
|
|
285
|
-
cacheManager.addModifiedRange(changedPath, { start: 1, end: content.split("\n").length }, /^import\s/m.test(content), record.turnStateCwd, currentSessionId ?? runtime.telemetrySessionId, "pi");
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
catch (err) {
|
|
289
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
290
|
-
summary.failed.push({ filePath, errors: [message] });
|
|
291
|
-
requeue([
|
|
292
|
-
{
|
|
293
|
-
...record,
|
|
294
|
-
kinds: new Set(["autofix"]),
|
|
295
|
-
toolNames: new Set(record.toolNames),
|
|
296
|
-
},
|
|
297
|
-
], "autofix-failed");
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
if (deferredAutofixFixes.length > 0) {
|
|
301
|
-
publishFilesTouched({
|
|
302
|
-
reason: "autofix",
|
|
303
|
-
paths: [...new Set(deferredAutofixFixes.map((fix) => fix.path))],
|
|
304
|
-
cwd: ctxCwd ?? runtime.projectRoot,
|
|
305
|
-
dbg,
|
|
306
|
-
fixes: deferredAutofixFixes,
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
dbg(`agent_end deferred_format: ${records.length} file(s)`);
|
|
310
|
-
logLatency({
|
|
311
|
-
type: "phase",
|
|
312
|
-
toolName: "agent_end",
|
|
313
|
-
filePath: ctxCwd ?? runtime.projectRoot,
|
|
314
|
-
phase: "agent_end_deferred_format_start",
|
|
315
|
-
turnId: scheduledTurnId,
|
|
316
|
-
durationMs: 0,
|
|
317
|
-
metadata: {
|
|
318
|
-
fileCount: records.length,
|
|
319
|
-
currentSessionId,
|
|
320
|
-
// #791: per-record provenance so a future incident can be diagnosed
|
|
321
|
-
// straight from latency.log — which session/turn queued each file,
|
|
322
|
-
// and whether it was claimed via the staleness fallback.
|
|
323
|
-
records: records.map((r) => ({
|
|
324
|
-
filePath: r.filePath,
|
|
325
|
-
queuedTurnIndex: r.queuedTurnIndex,
|
|
326
|
-
ownerSessionId: r.ownerSessionId,
|
|
327
|
-
staleClaim: staleClaimed.includes(r),
|
|
328
|
-
})),
|
|
329
|
-
deferredToOwnerCount: deferredToOwner.length,
|
|
330
|
-
},
|
|
331
|
-
});
|
|
332
|
-
// #673: same moment as the latency phase above — a same-process listener
|
|
333
|
-
// (e.g. a review/snapshot controller) can use this to know the deferred-
|
|
334
|
-
// format phase is starting and these specific paths may still be mutated.
|
|
335
|
-
if (records.length > 0) {
|
|
336
|
-
publishFormatStart({
|
|
337
|
-
cwd: ctxCwd ?? runtime.projectRoot,
|
|
338
|
-
paths: records.map((r) => r.filePath),
|
|
339
|
-
dbg,
|
|
340
|
-
kinds: [...new Set(records.flatMap((record) => [...record.kinds]))],
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
const formatRecords = records
|
|
344
|
-
.filter((record) => record.kinds.has("format"))
|
|
345
|
-
.filter((record) => {
|
|
346
|
-
const disabled = !!getFlag("no-autoformat", record.filePath);
|
|
347
|
-
if (disabled) {
|
|
348
|
-
const source = getFlagSource?.("no-autoformat", record.filePath);
|
|
349
|
-
dbg(`agent_end deferred_format: skipping ${record.filePath} (--no-autoformat${source ? `, source=${source}` : ""})`);
|
|
350
|
-
summary.skipped.push({
|
|
351
|
-
filePath: record.filePath,
|
|
352
|
-
reason: "no-autoformat",
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
return !disabled;
|
|
356
|
-
});
|
|
357
|
-
if (formatRecords.length > 0) {
|
|
358
|
-
const work = [];
|
|
359
|
-
work.length = formatRecords.length;
|
|
360
|
-
const started = new Set();
|
|
361
|
-
let nextIndex = 0;
|
|
362
|
-
const worker = async () => {
|
|
363
|
-
while (nextIndex < formatRecords.length) {
|
|
364
|
-
const index = nextIndex++;
|
|
365
|
-
if (ambientSignal?.aborted)
|
|
366
|
-
return;
|
|
367
|
-
const record = formatRecords[index];
|
|
368
|
-
const fileStart = Date.now();
|
|
369
|
-
const filePath = path.resolve(record.filePath);
|
|
370
|
-
started.add(index);
|
|
371
|
-
if (!nodeFs.existsSync(filePath)) {
|
|
372
|
-
work[index] = {
|
|
373
|
-
record,
|
|
374
|
-
filePath,
|
|
375
|
-
fileStart,
|
|
376
|
-
result: undefined,
|
|
377
|
-
missing: true,
|
|
378
|
-
};
|
|
379
|
-
continue;
|
|
380
|
-
}
|
|
381
|
-
try {
|
|
382
|
-
work[index] = {
|
|
383
|
-
record,
|
|
384
|
-
filePath,
|
|
385
|
-
fileStart,
|
|
386
|
-
result: await bounded(runFormatPhase(filePath, getFormatService, dbg, ambientSignal, 30_000, "agent_settled"), {
|
|
387
|
-
ms: HOOK_WALL_BUDGET_MS.agent_settled,
|
|
388
|
-
signal: ambientSignal,
|
|
389
|
-
hook: "agent_settled",
|
|
390
|
-
label: "deferred-format",
|
|
391
|
-
}),
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
catch (err) {
|
|
395
|
-
work[index] = {
|
|
396
|
-
record,
|
|
397
|
-
filePath,
|
|
398
|
-
fileStart,
|
|
399
|
-
result: undefined,
|
|
400
|
-
error: err instanceof Error ? err.message : String(err),
|
|
401
|
-
};
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
};
|
|
405
|
-
await Promise.all(Array.from({ length: Math.min(DEFERRED_FORMAT_CONCURRENCY, formatRecords.length) }, () => worker()));
|
|
406
|
-
if (ambientSignal?.aborted) {
|
|
407
|
-
requeue(formatRecords
|
|
408
|
-
.filter((_, index) => !started.has(index))
|
|
409
|
-
.map((record) => ({
|
|
410
|
-
...record,
|
|
411
|
-
kinds: new Set(["format"]),
|
|
412
|
-
toolNames: new Set(record.toolNames),
|
|
413
|
-
})), "abort");
|
|
414
|
-
}
|
|
415
|
-
for (const entry of work) {
|
|
416
|
-
if (!entry)
|
|
417
|
-
continue;
|
|
418
|
-
await new Promise((resolve) => setImmediate(resolve));
|
|
419
|
-
const { record, filePath, fileStart } = entry;
|
|
420
|
-
if (entry.missing) {
|
|
421
|
-
dbg(`agent_end deferred_format skipped missing file: ${filePath}`);
|
|
422
|
-
if (!summary.skipped.some((item) => item.filePath === filePath && item.reason === "missing")) {
|
|
423
|
-
summary.skipped.push({ filePath, reason: "missing" });
|
|
424
|
-
}
|
|
425
|
-
continue;
|
|
426
|
-
}
|
|
427
|
-
if (entry.error) {
|
|
428
|
-
dbg(`agent_end deferred_format failed for ${filePath}: ${entry.error}`);
|
|
429
|
-
summary.failed.push({ filePath, errors: [entry.error] });
|
|
430
|
-
requeue([
|
|
431
|
-
{
|
|
432
|
-
...record,
|
|
433
|
-
kinds: new Set(["format"]),
|
|
434
|
-
toolNames: new Set(record.toolNames),
|
|
435
|
-
},
|
|
436
|
-
], "format-failed");
|
|
437
|
-
continue;
|
|
438
|
-
}
|
|
439
|
-
const result = entry.result;
|
|
440
|
-
if (!result) {
|
|
441
|
-
// The abort branch above already requeues work that never started;
|
|
442
|
-
// preserve its established ownership for an in-flight caller abort.
|
|
443
|
-
if (ambientSignal?.aborted)
|
|
444
|
-
continue;
|
|
445
|
-
const reason = entry.error ?? "deferred formatter exceeded agent_settled budget";
|
|
446
|
-
summary.failed.push({ filePath, errors: [reason] });
|
|
447
|
-
requeue([
|
|
448
|
-
{
|
|
449
|
-
...record,
|
|
450
|
-
kinds: new Set(["format"]),
|
|
451
|
-
toolNames: new Set(record.toolNames),
|
|
452
|
-
},
|
|
453
|
-
], "format-failed");
|
|
454
|
-
continue;
|
|
455
|
-
}
|
|
456
|
-
summary.formatted++;
|
|
457
|
-
if (result.formatFailures.length > 0) {
|
|
458
|
-
summary.failed.push({ filePath, errors: result.formatFailures });
|
|
459
|
-
requeue([
|
|
460
|
-
{
|
|
461
|
-
...record,
|
|
462
|
-
kinds: new Set(["format"]),
|
|
463
|
-
toolNames: new Set(record.toolNames),
|
|
464
|
-
},
|
|
465
|
-
], "format-failed");
|
|
466
|
-
}
|
|
467
|
-
// #2413: an unavailable formatter is durable, not transient — record it
|
|
468
|
-
// once and DO NOT requeue. Requeuing here is exactly what made
|
|
469
|
-
// `spawn oxfmt ENOENT` re-fire on every agent_end for the same files.
|
|
470
|
-
if (result.formatUnavailable.length > 0) {
|
|
471
|
-
for (const u of result.formatUnavailable) {
|
|
472
|
-
summary.unavailable.push({
|
|
473
|
-
filePath,
|
|
474
|
-
formatter: u.formatter,
|
|
475
|
-
reason: u.reason,
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
if (result.formatChanged) {
|
|
480
|
-
summary.changed.push(filePath);
|
|
481
|
-
for (const tool of result.formattersUsed) {
|
|
482
|
-
deferredFormatFixes.push({ path: filePath, tool, kind: "format" });
|
|
483
|
-
}
|
|
484
|
-
// turnStateCwd is required on DeferredFormatRecord (PR #114) — the
|
|
485
|
-
// previous fallback chain through ctxCwd / projectRoot / record.cwd
|
|
486
|
-
// could silently regress the monorepo cwd-mismatch fix from PR #105.
|
|
487
|
-
const bookkeepingCwd = record.turnStateCwd;
|
|
488
|
-
recordProjectChange({
|
|
489
|
-
runtime,
|
|
490
|
-
cwd: bookkeepingCwd,
|
|
491
|
-
filePath,
|
|
492
|
-
source: "format",
|
|
493
|
-
dbg,
|
|
494
|
-
});
|
|
495
|
-
if (!getFlag("no-read-guard")) {
|
|
496
|
-
runtime.readGuard.recordWritten(filePath);
|
|
497
|
-
}
|
|
498
|
-
try {
|
|
499
|
-
const content = nodeFs.readFileSync(filePath, "utf-8");
|
|
500
|
-
const lineCount = content.split("\n").length;
|
|
501
|
-
const hasImports = /^import\s/m.test(content);
|
|
502
|
-
cacheManager.addModifiedRange(filePath, { start: 1, end: lineCount }, hasImports, bookkeepingCwd, currentSessionId ?? runtime.telemetrySessionId, "pi");
|
|
503
|
-
}
|
|
504
|
-
catch (err) {
|
|
505
|
-
dbg(`agent_end deferred_format modified-range tracking failed for ${filePath}: ${err}`);
|
|
506
|
-
}
|
|
507
|
-
// #484: opt-in per-turn summary — deferred format is the OTHER
|
|
508
|
-
// half of the format signal (immediate-mode is recorded at the
|
|
509
|
-
// runtime-tool-result.ts seam); same result.formattersUsed the
|
|
510
|
-
// latency phase below already logs, no new plumbing.
|
|
511
|
-
if (getFlag("lens-turn-summary")) {
|
|
512
|
-
for (const tool of result.formattersUsed) {
|
|
513
|
-
runtime.turnSummary.recordFormat(filePath, { tool });
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
if (result.fileContent) {
|
|
518
|
-
await resyncLspFile(filePath, result.fileContent, true, false, getFlag, dbg);
|
|
519
|
-
}
|
|
520
|
-
dbg(`agent_end deferred_format file ${filePath}: changed=${result.formatChanged} duration=${Date.now() - fileStart}ms`);
|
|
521
|
-
logLatency({
|
|
522
|
-
type: "phase",
|
|
523
|
-
toolName: "agent_end",
|
|
524
|
-
filePath,
|
|
525
|
-
phase: "deferred_format_file",
|
|
526
|
-
turnId: record.queuedTurnId,
|
|
527
|
-
durationMs: Date.now() - fileStart,
|
|
528
|
-
metadata: {
|
|
529
|
-
changed: result.formatChanged,
|
|
530
|
-
formattersUsed: result.formattersUsed,
|
|
531
|
-
failureCount: result.formatFailures.length,
|
|
532
|
-
},
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
if (summary.changed.length > 0) {
|
|
536
|
-
publishFilesTouched({
|
|
537
|
-
reason: "format",
|
|
538
|
-
paths: summary.changed,
|
|
539
|
-
cwd: ctxCwd ?? runtime.projectRoot,
|
|
540
|
-
dbg,
|
|
541
|
-
fixes: deferredFormatFixes,
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
// LSP sees only authoritative content after both mutation phases. In
|
|
546
|
-
// particular, never publish the autofix intermediate state before format.
|
|
547
|
-
for (const changedPath of deferredAutofixChanged) {
|
|
548
|
-
if (!nodeFs.existsSync(changedPath))
|
|
549
|
-
continue;
|
|
550
|
-
const content = nodeFs.readFileSync(changedPath, "utf-8");
|
|
551
|
-
await resyncLspFile(changedPath, content, true, false, getFlag, dbg);
|
|
552
|
-
}
|
|
553
|
-
if (inspectActionableReport) {
|
|
554
|
-
const actionCwd = ctxCwd ?? runtime.projectRoot;
|
|
555
|
-
const actionableWarningsMaxAgeMs = 10 * 60_000;
|
|
556
|
-
const actionReport = cacheManager.readCache("actionable-warnings", actionCwd, actionableWarningsMaxAgeMs);
|
|
557
|
-
if (!actionReport?.data) {
|
|
558
|
-
// Distinguish "no cache file was ever written" from "a cache file
|
|
559
|
-
// exists but its TTL elapsed" (#1607) — both used to collapse into
|
|
560
|
-
// one "cache missing or expired" line, which doesn't tell a reader
|
|
561
|
-
// whether the writer ran and produced a stale file, or never ran.
|
|
562
|
-
const inspection = typeof cacheManager.inspectCache === "function"
|
|
563
|
-
? cacheManager.inspectCache("actionable-warnings", actionCwd, actionableWarningsMaxAgeMs)
|
|
564
|
-
: undefined;
|
|
565
|
-
if (inspection === "missing") {
|
|
566
|
-
dbg("agent_end actionable_warnings_autofix: cache absent, skipping fixes");
|
|
567
|
-
}
|
|
568
|
-
else if (inspection === "stale") {
|
|
569
|
-
dbg("agent_end actionable_warnings_autofix: cache expired, skipping fixes");
|
|
570
|
-
}
|
|
571
|
-
else {
|
|
572
|
-
dbg(`agent_end actionable_warnings_autofix: cache missing or expired${inspection ? ` (${inspection})` : ""}, skipping fixes`);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
else {
|
|
576
|
-
const enabledFiles = actionReport.data.files.filter((file) => {
|
|
577
|
-
// #1247: the per-edit dispatch surface gates ignored files before
|
|
578
|
-
// running; the turn-end autofix must apply the same filter or a
|
|
579
|
-
// `.pi-lens.json` `ignore` entry cannot protect a prose file
|
|
580
|
-
// (CHANGELOG.md / AGENTS.md) from being rewritten here.
|
|
581
|
-
if (isPathIgnoredByProject(file.filePath, ctxCwd ?? runtime.projectRoot)) {
|
|
582
|
-
dbg(`agent_end actionable_warnings_autofix: skipped ${file.filePath} (ignored by project)`);
|
|
583
|
-
return false;
|
|
584
|
-
}
|
|
585
|
-
const enabled = !!getFlag("lens-actionable-warning-autofix", file.filePath);
|
|
586
|
-
if (!enabled) {
|
|
587
|
-
const source = getFlagSource?.("lens-actionable-warning-autofix", file.filePath);
|
|
588
|
-
dbg(`agent_end actionable_warnings_autofix: skipped ${file.filePath} (disabled${source ? `, source=${source}` : ""})`);
|
|
589
|
-
}
|
|
590
|
-
return enabled;
|
|
591
|
-
});
|
|
592
|
-
const eligibleCount = enabledFiles.reduce((total, file) => total +
|
|
593
|
-
file.warnings.reduce((count, warning) => count +
|
|
594
|
-
(warning.suppressed
|
|
595
|
-
? 0
|
|
596
|
-
: warning.actions.filter((action) => action.autoFixEligible)
|
|
597
|
-
.length), 0), 0);
|
|
598
|
-
const eligibleReport = {
|
|
599
|
-
...actionReport.data,
|
|
600
|
-
files: enabledFiles,
|
|
601
|
-
summary: {
|
|
602
|
-
...actionReport.data.summary,
|
|
603
|
-
files: enabledFiles.length,
|
|
604
|
-
autoFixEligible: eligibleCount,
|
|
605
|
-
},
|
|
606
|
-
};
|
|
607
|
-
const freshness = checkActionableWarningsReportFresh({
|
|
608
|
-
report: eligibleReport,
|
|
609
|
-
currentProjectSeq: runtime.projectSeq,
|
|
610
|
-
getFileSeq: (filePath) => runtime.getFileSeq(filePath),
|
|
611
|
-
});
|
|
612
|
-
if (!freshness.fresh) {
|
|
613
|
-
dbg(`agent_end actionable_warnings_autofix: stale report (${freshness.reason}; reportProjectSeqEnd=${freshness.reportProjectSeqEnd ?? "missing"}; currentProjectSeq=${freshness.currentProjectSeq}${freshness.filePath ? `; file=${freshness.filePath}; reportFileSeq=${freshness.reportFileSeq}; currentFileSeq=${freshness.currentFileSeq}` : ""}), skipping fixes`);
|
|
614
|
-
}
|
|
615
|
-
else if (eligibleReport.summary.autoFixEligible > 0) {
|
|
616
|
-
// #684: same "genuine work about to happen" gate as
|
|
617
|
-
// publishFormatStart — only fires when the report is fresh AND
|
|
618
|
-
// has at least one autofix-eligible warning, right before
|
|
619
|
-
// applyConservativeActionableWarningFixes actually starts.
|
|
620
|
-
publishAutofixStart({
|
|
621
|
-
cwd: ctxCwd ?? runtime.projectRoot,
|
|
622
|
-
paths: eligibleReport.files
|
|
623
|
-
.filter((file) => file.warnings.some((warning) => !warning.suppressed &&
|
|
624
|
-
warning.actions.some((action) => action.autoFixEligible)))
|
|
625
|
-
.map((file) => file.filePath),
|
|
626
|
-
eligibleCount: eligibleReport.summary.autoFixEligible,
|
|
627
|
-
dbg,
|
|
628
|
-
});
|
|
629
|
-
const fixStart = Date.now();
|
|
630
|
-
const fixCwd = ctxCwd ?? runtime.projectRoot;
|
|
631
|
-
const mutationContext = {
|
|
632
|
-
cwd: fixCwd,
|
|
633
|
-
correlationId: newLspMutationCorrelationId(),
|
|
634
|
-
tool: "lsp-quickfix",
|
|
635
|
-
source: "autofix",
|
|
636
|
-
runtime,
|
|
637
|
-
cacheManager,
|
|
638
|
-
readGuard: getFlag("no-read-guard") ? undefined : runtime.readGuard,
|
|
639
|
-
recordAutofix: getFlag("lens-turn-summary")
|
|
640
|
-
? (filePath) => runtime.turnSummary.recordAutofix(filePath, {
|
|
641
|
-
tool: "lsp-quickfix",
|
|
642
|
-
})
|
|
643
|
-
: undefined,
|
|
644
|
-
dbg,
|
|
645
|
-
};
|
|
646
|
-
const fixSummary = await applyConservativeActionableWarningFixes({
|
|
647
|
-
cwd: fixCwd,
|
|
648
|
-
report: eligibleReport,
|
|
649
|
-
maxFixes: getGlobalActionableWarningMaxFixes(),
|
|
650
|
-
dbg,
|
|
651
|
-
mutationContext,
|
|
652
|
-
});
|
|
653
|
-
if (fixSummary.changedFiles.length > 0) {
|
|
654
|
-
publishFilesTouched({
|
|
655
|
-
reason: "autofix",
|
|
656
|
-
paths: fixSummary.changedFiles,
|
|
657
|
-
cwd: ctxCwd ?? runtime.projectRoot,
|
|
658
|
-
dbg,
|
|
659
|
-
fixes: fixSummary.changedFiles.map((changedFile) => ({
|
|
660
|
-
path: changedFile,
|
|
661
|
-
tool: "lsp-quickfix",
|
|
662
|
-
kind: "autofix",
|
|
663
|
-
})),
|
|
664
|
-
});
|
|
665
|
-
}
|
|
666
|
-
logLatency({
|
|
667
|
-
type: "phase",
|
|
668
|
-
toolName: "agent_end",
|
|
669
|
-
filePath: ctxCwd ?? runtime.projectRoot,
|
|
670
|
-
phase: "actionable_warnings_autofix",
|
|
671
|
-
turnId: scheduledTurnId,
|
|
672
|
-
durationMs: Date.now() - fixStart,
|
|
673
|
-
metadata: {
|
|
674
|
-
considered: fixSummary.considered,
|
|
675
|
-
applied: fixSummary.applied,
|
|
676
|
-
changedFiles: fixSummary.changedFiles.length,
|
|
677
|
-
skipped: fixSummary.skipped.length,
|
|
678
|
-
},
|
|
679
|
-
});
|
|
680
|
-
if (fixSummary.applied > 0) {
|
|
681
|
-
notify(`pi-lens applied ${fixSummary.applied} conservative LSP warning quickfix(es)`, "info");
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
else {
|
|
685
|
-
dbg("agent_end actionable_warnings_autofix: fresh report, 0 autofix-eligible warnings, skipping");
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
logLatency({
|
|
690
|
-
type: "phase",
|
|
691
|
-
toolName: "agent_end",
|
|
692
|
-
filePath: ctxCwd ?? runtime.projectRoot,
|
|
693
|
-
phase: "agent_end_deferred_mutation_drain",
|
|
694
|
-
turnId: scheduledTurnId,
|
|
695
|
-
durationMs: Date.now() - startedAt,
|
|
696
|
-
metadata: {
|
|
697
|
-
autofixRecords: autofixRecords.length,
|
|
698
|
-
formatRecords: formatRecords.length,
|
|
699
|
-
coalescedPaths: records.length,
|
|
700
|
-
requeuedKinds: [...requeuedKinds].sort((a, b) => a < b ? -1 : a > b ? 1 : 0),
|
|
701
|
-
},
|
|
702
|
-
});
|
|
703
|
-
logLatency({
|
|
704
|
-
type: "tool_result",
|
|
705
|
-
toolName: "agent_end",
|
|
706
|
-
filePath: ctxCwd ?? runtime.projectRoot,
|
|
707
|
-
durationMs: Date.now() - startedAt,
|
|
708
|
-
result: "deferred_format_complete",
|
|
709
|
-
turnId: scheduledTurnId,
|
|
710
|
-
metadata: {
|
|
711
|
-
queued: summary.queued,
|
|
712
|
-
formatted: summary.formatted,
|
|
713
|
-
changed: summary.changed.length,
|
|
714
|
-
failed: summary.failed.length,
|
|
715
|
-
skipped: summary.skipped.length,
|
|
716
|
-
unavailable: summary.unavailable.length,
|
|
717
|
-
},
|
|
718
|
-
});
|
|
719
|
-
logLatency({
|
|
720
|
-
type: "phase",
|
|
721
|
-
toolName: "agent_end",
|
|
722
|
-
filePath: ctxCwd ?? runtime.projectRoot,
|
|
723
|
-
phase: "agent_end_deferred_format_done",
|
|
724
|
-
turnId: scheduledTurnId,
|
|
725
|
-
durationMs: Date.now() - startedAt,
|
|
726
|
-
metadata: {
|
|
727
|
-
formatted: summary.formatted,
|
|
728
|
-
changed: summary.changed.length,
|
|
729
|
-
failed: summary.failed.length,
|
|
730
|
-
skipped: summary.skipped.length,
|
|
731
|
-
unavailable: summary.unavailable.length,
|
|
732
|
-
},
|
|
733
|
-
});
|
|
734
|
-
dbg(`agent_end deferred_format complete: formatted=${summary.formatted} changed=${summary.changed.length} failed=${summary.failed.length} skipped=${summary.skipped.length} unavailable=${summary.unavailable.length}`);
|
|
735
|
-
if (summary.failed.length > 0) {
|
|
736
|
-
notify(`pi-lens deferred format: ${summary.changed.length} changed, ${summary.failed.length} failed`, "warning");
|
|
737
|
-
}
|
|
738
|
-
else if (summary.changed.length > 0 && !getFlag("lens-turn-summary")) {
|
|
739
|
-
// The info-level success toast is redundant once the turn-summary entry
|
|
740
|
-
// (#484) is opted in — it would repeat the same "N reformatted" fact the
|
|
741
|
-
// transcript entry already carries. Failures above stay untouched either way.
|
|
742
|
-
const names = summary.changed.map((f) => path.basename(f)).join(", ");
|
|
743
|
-
notify(`pi-lens deferred format applied to ${summary.changed.length} file(s): ${names}`, "info");
|
|
744
|
-
}
|
|
745
|
-
return summary;
|
|
746
|
-
}
|