@herbertgao/pi-extensions 2026.9.0 → 2026.9.2

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.
Files changed (360) hide show
  1. package/node_modules/@czottmann/pi-automode/CHANGELOG.md +13 -1
  2. package/node_modules/@czottmann/pi-automode/README.md +20 -0
  3. package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +1 -1
  4. package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +2 -1
  5. package/node_modules/@czottmann/pi-automode/docs/defaults.md +3 -2
  6. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +38 -2
  7. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +5 -3
  8. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +11 -3
  9. package/node_modules/@czottmann/pi-automode/package.json +1 -1
  10. package/node_modules/@narumitw/pi-btw/README.md +57 -141
  11. package/node_modules/@narumitw/pi-btw/dist/index.ts +466 -41
  12. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +4 -4
  13. package/node_modules/@narumitw/pi-btw/docs/workflows.md +74 -0
  14. package/node_modules/@narumitw/pi-btw/package.json +2 -1
  15. package/node_modules/@narumitw/pi-btw/src/btw.ts +15 -1
  16. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +32 -2
  17. package/node_modules/@narumitw/pi-btw/src/keybindings.ts +330 -0
  18. package/node_modules/@narumitw/pi-btw/src/menu.ts +136 -19
  19. package/node_modules/@narumitw/pi-btw/src/settings.ts +32 -0
  20. package/node_modules/@narumitw/pi-btw/src/side-thread.ts +57 -5
  21. package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +52 -30
  22. package/node_modules/@pi-plugins/fast-mode/README.md +5 -3
  23. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
  24. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +20 -55
  25. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
  26. package/node_modules/@pi-plugins/fast-mode/package.json +1 -1
  27. package/node_modules/pi-lens/CHANGELOG.md +1072 -0
  28. package/node_modules/pi-lens/README.md +3 -0
  29. package/node_modules/pi-lens/config/biome/core.jsonc +11 -2
  30. package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +13 -1
  31. package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -9
  32. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +927 -80
  33. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +1 -1
  34. package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +13 -4
  35. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +123 -3
  36. package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +60 -5
  37. package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +2 -9
  38. package/node_modules/pi-lens/dist/clients/ast-grep-types.js +2 -0
  39. package/node_modules/pi-lens/dist/clients/bash-file-access.js +133 -3
  40. package/node_modules/pi-lens/dist/clients/biome-client.js +9 -2
  41. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +14 -6
  42. package/node_modules/pi-lens/dist/clients/bootstrap.js +509 -73
  43. package/node_modules/pi-lens/dist/clients/bounded-cache.js +152 -12
  44. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +1 -1
  45. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +59 -9
  46. package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +113 -0
  47. package/node_modules/pi-lens/dist/clients/bus-events-logger.js +3 -11
  48. package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +31 -4
  49. package/node_modules/pi-lens/dist/clients/cache-manager.js +105 -6
  50. package/node_modules/pi-lens/dist/clients/cache-observability.js +40 -19
  51. package/node_modules/pi-lens/dist/clients/cargo-manifest.js +422 -0
  52. package/node_modules/pi-lens/dist/clients/cascade-logger.js +2 -9
  53. package/node_modules/pi-lens/dist/clients/child-unref.js +1 -19
  54. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +13 -3
  55. package/node_modules/pi-lens/dist/clients/complexity-client.js +16 -5
  56. package/node_modules/pi-lens/dist/clients/config-core/deny.js +221 -0
  57. package/node_modules/pi-lens/dist/clients/config-core/index.js +50 -0
  58. package/node_modules/pi-lens/dist/clients/config-core/merge.js +357 -0
  59. package/node_modules/pi-lens/dist/clients/config-core/normalize.js +340 -0
  60. package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +248 -0
  61. package/node_modules/pi-lens/dist/clients/config-core/provenance.js +164 -0
  62. package/node_modules/pi-lens/dist/clients/config-core/records.js +218 -0
  63. package/node_modules/pi-lens/dist/clients/config-core/resolve.js +125 -0
  64. package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +78 -0
  65. package/node_modules/pi-lens/dist/clients/config-core/schema.js +165 -0
  66. package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +281 -0
  67. package/node_modules/pi-lens/dist/clients/config-locations.js +160 -0
  68. package/node_modules/pi-lens/dist/clients/config-resolve.js +789 -0
  69. package/node_modules/pi-lens/dist/clients/config-schema.js +234 -0
  70. package/node_modules/pi-lens/dist/clients/config-warn.js +407 -0
  71. package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -14
  72. package/node_modules/pi-lens/dist/clients/dead-code-logger.js +2 -6
  73. package/node_modules/pi-lens/dist/clients/deadline-utils.js +178 -0
  74. package/node_modules/pi-lens/dist/clients/debug-handles.js +2 -2
  75. package/node_modules/pi-lens/dist/clients/debug-heap.js +3 -3
  76. package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +106 -0
  77. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +113 -7
  78. package/node_modules/pi-lens/dist/clients/dependency-checker.js +8 -19
  79. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +1 -1
  80. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +12 -9
  81. package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +15 -5
  82. package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +0 -4
  83. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +162 -44
  84. package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +97 -0
  85. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +27 -8
  86. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +0 -6
  87. package/node_modules/pi-lens/dist/clients/dispatch/pending-runner-findings.js +1 -1
  88. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +0 -3
  89. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-complexity.js +2 -2
  90. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-fan-out.js +1 -1
  91. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -1
  92. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +383 -27
  93. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -1
  94. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +4 -1
  95. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -1
  96. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -1
  97. package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -1
  98. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -1
  99. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -1
  100. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -1
  101. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -1
  102. package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -1
  103. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -1
  104. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -1
  105. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +1 -3
  106. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -1
  107. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -1
  108. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -1
  109. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +1 -2
  110. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -1
  111. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -1
  112. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -1
  113. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -1
  114. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -1
  115. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -1
  116. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +14 -18
  117. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -1
  118. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -1
  119. package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -1
  120. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +6 -3
  121. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +7 -4
  122. package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -1
  123. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +1 -2
  124. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -3
  125. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +1 -2
  126. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -1
  127. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +4 -3
  128. package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -1
  129. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -1
  130. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -1
  131. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -1
  132. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -1
  133. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -1
  134. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -1
  135. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -1
  136. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -1
  137. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +3 -0
  138. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +3 -67
  139. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +194 -80
  140. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +84 -15
  141. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils.js +0 -21
  142. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -1
  143. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +2 -20
  144. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +1 -1
  145. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -1
  146. package/node_modules/pi-lens/dist/clients/dispatch/utils/format-utils.js +2 -2
  147. package/node_modules/pi-lens/dist/clients/disposition-logger.js +3 -10
  148. package/node_modules/pi-lens/dist/clients/effective-config.js +403 -0
  149. package/node_modules/pi-lens/dist/clients/error-class.js +23 -0
  150. package/node_modules/pi-lens/dist/clients/event-loop-hold.js +274 -0
  151. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +2 -2
  152. package/node_modules/pi-lens/dist/clients/extension-log.js +2 -2
  153. package/node_modules/pi-lens/dist/clients/feature-hints.js +2 -1
  154. package/node_modules/pi-lens/dist/clients/file-kinds.js +1 -38
  155. package/node_modules/pi-lens/dist/clients/file-time.js +7 -2
  156. package/node_modules/pi-lens/dist/clients/file-utils.js +117 -10
  157. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +50 -13
  158. package/node_modules/pi-lens/dist/clients/format-service.js +6 -2
  159. package/node_modules/pi-lens/dist/clients/formatters.js +385 -104
  160. package/node_modules/pi-lens/dist/clients/freshness-cadence.js +17 -0
  161. package/node_modules/pi-lens/dist/clients/generated-artifacts.js +116 -22
  162. package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -9
  163. package/node_modules/pi-lens/dist/clients/git-guard.js +6 -1
  164. package/node_modules/pi-lens/dist/clients/go-client.js +39 -0
  165. package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +252 -0
  166. package/node_modules/pi-lens/dist/clients/grammar-source.js +3 -3
  167. package/node_modules/pi-lens/dist/clients/hashline-anchor.js +424 -0
  168. package/node_modules/pi-lens/dist/clients/hook-budgets.js +76 -0
  169. package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +5 -2
  170. package/node_modules/pi-lens/dist/clients/host-ports.js +1 -1
  171. package/node_modules/pi-lens/dist/clients/installer/index.js +289 -59
  172. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +84 -18
  173. package/node_modules/pi-lens/dist/clients/instance-reaper.js +110 -236
  174. package/node_modules/pi-lens/dist/clients/instance-registry.js +6 -3
  175. package/node_modules/pi-lens/dist/clients/language-profile.js +0 -9
  176. package/node_modules/pi-lens/dist/clients/language-registry.js +599 -0
  177. package/node_modules/pi-lens/dist/clients/latency-logger.js +165 -9
  178. package/node_modules/pi-lens/dist/clients/ledger-bounds.js +34 -1
  179. package/node_modules/pi-lens/dist/clients/lens-config.js +160 -30
  180. package/node_modules/pi-lens/dist/clients/lens-engine.js +33 -41
  181. package/node_modules/pi-lens/dist/clients/lens-events.js +1 -1
  182. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +77 -6
  183. package/node_modules/pi-lens/dist/clients/lens-map.js +1 -1
  184. package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -38
  185. package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +3 -1
  186. package/node_modules/pi-lens/dist/clients/lsp/client.js +172 -33
  187. package/node_modules/pi-lens/dist/clients/lsp/config.js +484 -158
  188. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +1 -1
  189. package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +1 -1
  190. package/node_modules/pi-lens/dist/clients/lsp/edits.js +18 -5
  191. package/node_modules/pi-lens/dist/clients/lsp/index.js +892 -96
  192. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +1 -1
  193. package/node_modules/pi-lens/dist/clients/lsp/language.js +18 -177
  194. package/node_modules/pi-lens/dist/clients/lsp/launch.js +2 -1
  195. package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
  196. package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +5 -18
  197. package/node_modules/pi-lens/dist/clients/lsp/server.js +284 -147
  198. package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +116 -23
  199. package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +2 -7
  200. package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +0 -1
  201. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +14 -7
  202. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +6 -0
  203. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +2 -1
  204. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +1 -1
  205. package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -1
  206. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +163 -21
  207. package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +36 -0
  208. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +33 -4
  209. package/node_modules/pi-lens/dist/clients/mcp/session.js +5 -16
  210. package/node_modules/pi-lens/dist/clients/memory-sampler.js +8 -3
  211. package/node_modules/pi-lens/dist/clients/metrics-history.js +28 -107
  212. package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +3 -5
  213. package/node_modules/pi-lens/dist/clients/module-report.js +21 -46
  214. package/node_modules/pi-lens/dist/clients/mutating-tool.js +651 -0
  215. package/node_modules/pi-lens/dist/clients/mutation-attribution.js +368 -0
  216. package/node_modules/pi-lens/dist/clients/mutation-bridge.js +240 -0
  217. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +247 -24
  218. package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +101 -0
  219. package/node_modules/pi-lens/dist/clients/observed-mutation.js +1215 -0
  220. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +70 -28
  221. package/node_modules/pi-lens/dist/clients/opengrep-config.js +5 -1
  222. package/node_modules/pi-lens/dist/clients/package-manager.js +195 -26
  223. package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +359 -80
  224. package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +23 -7
  225. package/node_modules/pi-lens/dist/clients/path-keyed-map.js +21 -2
  226. package/node_modules/pi-lens/dist/clients/path-utils.js +451 -15
  227. package/node_modules/pi-lens/dist/clients/performance-report.js +2 -2
  228. package/node_modules/pi-lens/dist/clients/persist-debounce.js +8 -1
  229. package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +114 -0
  230. package/node_modules/pi-lens/dist/clients/pipeline.js +79 -18
  231. package/node_modules/pi-lens/dist/clients/probe-home-state.js +228 -0
  232. package/node_modules/pi-lens/dist/clients/process-bridge.js +66 -0
  233. package/node_modules/pi-lens/dist/clients/process-snapshot.js +68 -0
  234. package/node_modules/pi-lens/dist/clients/project-changes.js +1 -1
  235. package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +1 -1
  236. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +4 -3
  237. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +1 -1
  238. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +1 -1
  239. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +1 -1
  240. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +1 -1
  241. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +28 -4
  242. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +51 -20
  243. package/node_modules/pi-lens/dist/clients/project-lens-config.js +438 -122
  244. package/node_modules/pi-lens/dist/clients/project-scan-policy.js +3 -51
  245. package/node_modules/pi-lens/dist/clients/project-snapshot.js +52 -24
  246. package/node_modules/pi-lens/dist/clients/python-environment.js +217 -0
  247. package/node_modules/pi-lens/dist/clients/python-provenance.js +639 -0
  248. package/node_modules/pi-lens/dist/clients/quiet-window.js +6 -1
  249. package/node_modules/pi-lens/dist/clients/read-bridge.js +13 -21
  250. package/node_modules/pi-lens/dist/clients/read-expansion.js +9 -46
  251. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +16 -5
  252. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +364 -212
  253. package/node_modules/pi-lens/dist/clients/read-guard.js +26 -2
  254. package/node_modules/pi-lens/dist/clients/recent-touches.js +2 -2
  255. package/node_modules/pi-lens/dist/clients/resource-sampler.js +195 -96
  256. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +155 -114
  257. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +1 -1
  258. package/node_modules/pi-lens/dist/clients/review-graph/service.js +55 -3
  259. package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +7 -15
  260. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +10 -74
  261. package/node_modules/pi-lens/dist/clients/review-graph-logger.js +9 -3
  262. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +19 -3
  263. package/node_modules/pi-lens/dist/clients/runtime-context.js +49 -16
  264. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +25 -6
  265. package/node_modules/pi-lens/dist/clients/runtime-session.js +184 -32
  266. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +179 -36
  267. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +797 -243
  268. package/node_modules/pi-lens/dist/clients/runtime-turn.js +1028 -53
  269. package/node_modules/pi-lens/dist/clients/rust-client.js +31 -0
  270. package/node_modules/pi-lens/dist/clients/safe-spawn.js +33 -10
  271. package/node_modules/pi-lens/dist/clients/sanitize.js +7 -12
  272. package/node_modules/pi-lens/dist/clients/scan-utils.js +1 -56
  273. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +1 -3
  274. package/node_modules/pi-lens/dist/clients/security-scan-client.js +3 -0
  275. package/node_modules/pi-lens/dist/clients/session-lifecycle.js +1 -1
  276. package/node_modules/pi-lens/dist/clients/session-start-observability.js +79 -0
  277. package/node_modules/pi-lens/dist/clients/session-summary.js +0 -24
  278. package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +12 -3
  279. package/node_modules/pi-lens/dist/clients/sgconfig.js +7 -6
  280. package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +1 -1
  281. package/node_modules/pi-lens/dist/clients/skills-resolver.js +105 -0
  282. package/node_modules/pi-lens/dist/clients/smells-rollup.js +4 -4
  283. package/node_modules/pi-lens/dist/clients/startup-scan.js +2 -10
  284. package/node_modules/pi-lens/dist/clients/string-utils.js +13 -0
  285. package/node_modules/pi-lens/dist/clients/subagent-mode.js +17 -4
  286. package/node_modules/pi-lens/dist/clients/test-runner-client.js +176 -39
  287. package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +244 -0
  288. package/node_modules/pi-lens/dist/clients/tool-definition.js +41 -1
  289. package/node_modules/pi-lens/dist/clients/tool-policy.js +92 -22
  290. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +40 -40
  291. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +87 -100
  292. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
  293. package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +81 -1
  294. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +51 -46
  295. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +28 -0
  296. package/node_modules/pi-lens/dist/clients/tui-fit.js +0 -4
  297. package/node_modules/pi-lens/dist/clients/typos-config.js +5 -0
  298. package/node_modules/pi-lens/dist/clients/user-notify.js +6 -6
  299. package/node_modules/pi-lens/dist/clients/widget-state.js +191 -26
  300. package/node_modules/pi-lens/dist/clients/word-index-logger.js +2 -9
  301. package/node_modules/pi-lens/dist/clients/word-index-store.js +23 -12
  302. package/node_modules/pi-lens/dist/clients/word-index.js +252 -47
  303. package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -1
  304. package/node_modules/pi-lens/dist/clients/zizmor-config.js +4 -1
  305. package/node_modules/pi-lens/dist/index.js +65899 -55340
  306. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -1
  307. package/node_modules/pi-lens/dist/mcp/build-staleness.js +1 -1
  308. package/node_modules/pi-lens/dist/mcp/server.js +127 -5
  309. package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +583 -0
  310. package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +129 -0
  311. package/node_modules/pi-lens/dist/tools/effective-config.js +89 -0
  312. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +96 -25
  313. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +104 -86
  314. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +37 -16
  315. package/node_modules/pi-lens/dist/tools/lsp-structured-output.js +3 -3
  316. package/node_modules/pi-lens/dist/tools/render-compact.js +1 -1
  317. package/node_modules/pi-lens/dist/tools/shared.js +0 -1
  318. package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -2
  319. package/node_modules/pi-lens/docs/agent-guide.md +64 -1
  320. package/node_modules/pi-lens/docs/configuration.md +222 -0
  321. package/node_modules/pi-lens/docs/dependencies.md +3 -3
  322. package/node_modules/pi-lens/docs/features.md +44 -5
  323. package/node_modules/pi-lens/docs/globalconfig.md +20 -0
  324. package/node_modules/pi-lens/docs/language-coverage.md +2 -2
  325. package/node_modules/pi-lens/docs/lsp-capability-matrix.md +9 -1
  326. package/node_modules/pi-lens/docs/pi-lens-fixer.md +25 -0
  327. package/node_modules/pi-lens/docs/pi-lens-investigator.md +25 -0
  328. package/node_modules/pi-lens/docs/pi-lens-reviewer.md +33 -0
  329. package/node_modules/pi-lens/docs/pi-lens-subagent.md +49 -0
  330. package/node_modules/pi-lens/docs/pi-lens-warden.md +55 -0
  331. package/node_modules/pi-lens/docs/public-api-stability.md +359 -0
  332. package/node_modules/pi-lens/docs/release-qa-baseline.md +190 -0
  333. package/node_modules/pi-lens/docs/servercapabilities.md +7 -3
  334. package/node_modules/pi-lens/docs/subagent-compat.md +110 -30
  335. package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +2 -2
  336. package/node_modules/pi-lens/docs/word-index.md +1 -1
  337. package/node_modules/pi-lens/package.json +18 -35
  338. package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
  339. package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
  340. package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
  341. package/node_modules/pi-lens/rules/typos/_typos.toml +4 -2
  342. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +192 -1
  343. package/node_modules/pi-lens/scripts/install-selftest.mjs +58 -2
  344. package/node_modules/pi-lens/scripts/lib/skills-predicate.mjs +129 -0
  345. package/node_modules/pi-lens/scripts/lib/warm-loader-cache.mjs +1 -1
  346. package/node_modules/pi-lens/scripts/rpc-load-check.mjs +3 -1
  347. package/node_modules/pi-lens/scripts/warm-loader-cache.mjs +4 -2
  348. package/node_modules/pi-web-access/CHANGELOG.md +28 -0
  349. package/node_modules/pi-web-access/README.md +62 -15
  350. package/node_modules/pi-web-access/curator-page.ts +3 -1
  351. package/node_modules/pi-web-access/curator-server.ts +5 -1
  352. package/node_modules/pi-web-access/gemini-search.ts +8 -4
  353. package/node_modules/pi-web-access/github-extract.ts +242 -1
  354. package/node_modules/pi-web-access/index.ts +118 -64
  355. package/node_modules/pi-web-access/mistral-search.ts +281 -0
  356. package/node_modules/pi-web-access/package.json +2 -2
  357. package/node_modules/pi-web-access/perplexity.ts +14 -1
  358. package/node_modules/pi-web-access/utils.ts +23 -6
  359. package/node_modules/pi-web-access/xai-search.ts +96 -33
  360. package/package.json +6 -6
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import * as fs from "node:fs";
8
8
  import * as path from "node:path";
9
+ import { hasCargoWorkspaceTable, readCargoDependencyNames, readCargoPackageName, readCargoWorkspaceMembers, } from "../cargo-manifest.js";
9
10
  import { getProjectIgnoreMatcher, isExcludedDirName, } from "../file-utils.js";
10
11
  import { normalizeMapKey } from "../path-utils.js";
11
12
  import { getWorkspaceManifestMarkers } from "../workspace-topology.js";
@@ -52,8 +53,12 @@ function detectWorkspaceType(cwd) {
52
53
  if (markers.hasCargoToml) {
53
54
  try {
54
55
  const content = fs.readFileSync(path.join(cwd, "Cargo.toml"), "utf-8");
55
- if (content.includes("[workspace]"))
56
+ // The shared presence check (#2498) — see its own doc comment in
57
+ // cargo-manifest.ts for why a bare `.includes`/regex reimplementation
58
+ // of this test is wrong (comment/sentinel handling).
59
+ if (hasCargoWorkspaceTable(content)) {
56
60
  return "cargo";
61
+ }
57
62
  }
58
63
  catch { }
59
64
  }
@@ -146,71 +151,6 @@ function extractYamlList(content, key) {
146
151
  }
147
152
  return values;
148
153
  }
149
- function extractTomlArray(content, key) {
150
- const prefix = `${key}`;
151
- let collecting = false;
152
- let buffer = "";
153
- for (const rawLine of content.split(/\r?\n/)) {
154
- const line = rawLine.split("#", 1)[0].trim();
155
- if (!line)
156
- continue;
157
- if (!collecting) {
158
- if (!line.startsWith(prefix))
159
- continue;
160
- const equalsIndex = line.indexOf("=");
161
- if (equalsIndex === -1 || line.slice(0, equalsIndex).trim() !== key)
162
- continue;
163
- const afterEquals = line.slice(equalsIndex + 1).trim();
164
- if (!afterEquals.startsWith("["))
165
- continue;
166
- collecting = true;
167
- buffer += afterEquals.slice(1);
168
- }
169
- else {
170
- buffer += `,${line}`;
171
- }
172
- const closeIndex = buffer.indexOf("]");
173
- if (closeIndex !== -1) {
174
- buffer = buffer.slice(0, closeIndex);
175
- break;
176
- }
177
- }
178
- return buffer
179
- .split(",")
180
- .map((s) => stripQuotes(s.trim()))
181
- .filter(Boolean);
182
- }
183
- function extractTomlSection(content, section) {
184
- const lines = [];
185
- let inSection = false;
186
- for (const rawLine of content.split(/\r?\n/)) {
187
- const trimmed = rawLine.trim();
188
- if (trimmed === `[${section}]`) {
189
- inSection = true;
190
- continue;
191
- }
192
- if (inSection && trimmed.startsWith("[") && trimmed.endsWith("]"))
193
- break;
194
- if (inSection)
195
- lines.push(rawLine);
196
- }
197
- return lines;
198
- }
199
- function extractTomlString(content, key) {
200
- for (const rawLine of content.split(/\r?\n/)) {
201
- const line = rawLine.split("#", 1)[0].trim();
202
- const equalsIndex = line.indexOf("=");
203
- if (equalsIndex === -1 || line.slice(0, equalsIndex).trim() !== key)
204
- continue;
205
- const value = line.slice(equalsIndex + 1).trim();
206
- const quote = value[0];
207
- if ((quote !== '"' && quote !== "'") || value.length < 2)
208
- return undefined;
209
- const endIndex = value.indexOf(quote, 1);
210
- return endIndex === -1 ? undefined : value.slice(1, endIndex);
211
- }
212
- return undefined;
213
- }
214
154
  function moduleFromPackageJson(cwd, pkgRoot) {
215
155
  const pkgJson = readJsonSafe(path.join(pkgRoot, "package.json"));
216
156
  if (!pkgJson?.name)
@@ -250,7 +190,7 @@ function scanCargoModules(cwd) {
250
190
  let members = [];
251
191
  try {
252
192
  const content = fs.readFileSync(path.join(cwd, "Cargo.toml"), "utf-8");
253
- members = extractTomlArray(content, "members");
193
+ members = readCargoWorkspaceMembers(content);
254
194
  }
255
195
  catch {
256
196
  return [];
@@ -260,15 +200,11 @@ function scanCargoModules(cwd) {
260
200
  const pkgRoot = path.resolve(cwd, member);
261
201
  const memberToml = path.join(pkgRoot, "Cargo.toml");
262
202
  let name = "";
263
- const deps = [];
203
+ let deps = [];
264
204
  try {
265
205
  const content = fs.readFileSync(memberToml, "utf-8");
266
- name = extractTomlString(content, "name") ?? "";
267
- for (const line of extractTomlSection(content, "dependencies")) {
268
- const depName = line.trim().match(/^([A-Za-z0-9_-]+)\s*=/);
269
- if (depName)
270
- deps.push(depName[1]);
271
- }
206
+ name = readCargoPackageName(content) ?? "";
207
+ deps = readCargoDependencyNames(content);
272
208
  }
273
209
  catch {
274
210
  continue;
@@ -1,11 +1,17 @@
1
1
  import * as path from "node:path";
2
2
  import { isTestMode } from "./env-utils.js";
3
- import { getGlobalPiLensDir } from "./file-utils.js";
3
+ import { getGlobalPiLensLogDir } from "./probe-home-state.js";
4
+ import { getMaxLogSizeMB } from "./log-cleanup.js";
4
5
  import { createNdjsonLogger } from "./ndjson-logger.js";
5
6
  import { normalizeFilePath } from "./path-utils.js";
6
- const REVIEW_GRAPH_LOG_DIR = getGlobalPiLensDir();
7
+ const REVIEW_GRAPH_LOG_DIR = getGlobalPiLensLogDir();
7
8
  const REVIEW_GRAPH_LOG_FILE = path.join(REVIEW_GRAPH_LOG_DIR, "review-graph.log");
8
- const writer = createNdjsonLogger({ filePath: REVIEW_GRAPH_LOG_FILE });
9
+ // Bounded like every other global sink (#2505) — see sessionstart-logger.
10
+ const writer = createNdjsonLogger({
11
+ filePath: REVIEW_GRAPH_LOG_FILE,
12
+ maxBytes: getMaxLogSizeMB() * 1024 * 1024,
13
+ backupPath: `${REVIEW_GRAPH_LOG_FILE}.1`,
14
+ });
9
15
  /**
10
16
  * Build the one canonical graph metadata shape used by build and persist logs.
11
17
  * Counts come from the graph instance; source-file count may use the exact
@@ -19,7 +19,7 @@ import { getAutofixPolicyForFile, hasBiomeConfig, hasDetektConfig, hasEslintConf
19
19
  * path at all (they match on `ownerSessionId`), so this only trades a little
20
20
  * extra staleness for guaranteed eventual formatting. (#791)
21
21
  */
22
- export const DEFERRED_FORMAT_STALE_AFTER_MS = 10 * 60_000;
22
+ const DEFERRED_FORMAT_STALE_AFTER_MS = 10 * 60_000;
23
23
  const DEFERRED_FORMAT_CONCURRENCY = 3;
24
24
  function recordProjectChange(args) {
25
25
  // One mutation seam (#2000 phase 1): bump + receipt + change-log live in
@@ -190,6 +190,7 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
190
190
  changed: [],
191
191
  failed: [],
192
192
  skipped: [],
193
+ unavailable: [],
193
194
  };
194
195
  // #502 fix provenance: per-path {tool, kind} entries accumulated across the
195
196
  // deferred-format loop below, passed as `fixes` on the batch
@@ -348,7 +349,8 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
348
349
  return !disabled;
349
350
  });
350
351
  if (formatRecords.length > 0) {
351
- const work = new Array(formatRecords.length);
352
+ const work = [];
353
+ work.length = formatRecords.length;
352
354
  const started = new Set();
353
355
  let nextIndex = 0;
354
356
  const worker = async () => {
@@ -430,6 +432,18 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
430
432
  },
431
433
  ], "format-failed");
432
434
  }
435
+ // #2413: an unavailable formatter is durable, not transient — record it
436
+ // once and DO NOT requeue. Requeuing here is exactly what made
437
+ // `spawn oxfmt ENOENT` re-fire on every agent_end for the same files.
438
+ if (result.formatUnavailable.length > 0) {
439
+ for (const u of result.formatUnavailable) {
440
+ summary.unavailable.push({
441
+ filePath,
442
+ formatter: u.formatter,
443
+ reason: u.reason,
444
+ });
445
+ }
446
+ }
433
447
  if (result.formatChanged) {
434
448
  summary.changed.push(filePath);
435
449
  for (const tool of result.formattersUsed) {
@@ -663,6 +677,7 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
663
677
  changed: summary.changed.length,
664
678
  failed: summary.failed.length,
665
679
  skipped: summary.skipped.length,
680
+ unavailable: summary.unavailable.length,
666
681
  },
667
682
  });
668
683
  logLatency({
@@ -676,9 +691,10 @@ export async function handleAgentEnd({ ctxCwd, getFlag, getFlagSource, notify, d
676
691
  changed: summary.changed.length,
677
692
  failed: summary.failed.length,
678
693
  skipped: summary.skipped.length,
694
+ unavailable: summary.unavailable.length,
679
695
  },
680
696
  });
681
- dbg(`agent_end deferred_format complete: formatted=${summary.formatted} changed=${summary.changed.length} failed=${summary.failed.length} skipped=${summary.skipped.length}`);
697
+ 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}`);
682
698
  if (summary.failed.length > 0) {
683
699
  notify(`pi-lens deferred format: ${summary.changed.length} changed, ${summary.failed.length} failed`, "warning");
684
700
  }
@@ -103,12 +103,58 @@ export function peekTestFindings(cacheManager, cwd, runtime, logDelivery = false
103
103
  {
104
104
  role: "user",
105
105
  content: current
106
- ? `${AUTOMATION_FRAMING}Test failures detected last turn — fix before continuing:\n\n${findings.data.content}`
106
+ ? `${AUTOMATION_FRAMING}${testFindingsCurrentPrefix(findings.data.runnerErrorOnly)}\n\n${findings.data.content}`
107
107
  : `${AUTOMATION_FRAMING}${historicalTestContent(findings.data.content, findings.data.provenance)}`,
108
108
  },
109
109
  ],
110
110
  };
111
111
  }
112
+ /**
113
+ * #2522: a batch made entirely of RUNNER errors (timeout, missing
114
+ * provider/binary — see `TestRunnerFindingsCache.runnerErrorOnly`) is not a
115
+ * failure the agent introduced, so it must not read as a blocker the way a
116
+ * genuine failing test does.
117
+ */
118
+ function testFindingsCurrentPrefix(runnerErrorOnly) {
119
+ return runnerErrorOnly
120
+ ? "Test runner could not complete last turn (advisory — not a failure introduced this turn):"
121
+ : "Test failures detected last turn — fix before continuing:";
122
+ }
123
+ /**
124
+ * Retire a delivered test-findings record: blank the content, keep everything a
125
+ * delivery does not settle.
126
+ *
127
+ * ONE function, called by both `consumeTestFindings` (the in-process context
128
+ * hook) and `acknowledgeTestFindings` (the MCP Stop-hook commit), because
129
+ * "what survives a retire" is exactly the kind of rule that rots when it is
130
+ * stated twice. It already had: round 2 taught the consume copy to preserve
131
+ * `deferredTargets` and left the acknowledge copy dropping them, and the
132
+ * acknowledge copy is the LIVE Stop-hook path — including the branch where
133
+ * `handleTurnEnd` never runs at all — so on that path the deferral set was
134
+ * wiped before anything could ever dispatch it (#2522 review round 3, F2).
135
+ *
136
+ * What survives, and why:
137
+ * - `testRunGeneration` — nulling the slot would let a still-in-flight OLDER
138
+ * batch read `undefined`, pass the strictly-greater suppression check, and
139
+ * resurrect a consumed one-shot advisory with stale results.
140
+ * - `deferredTargets` — delivering the advisory says the agent has SEEN the
141
+ * deferral, not that those targets ran. Dropping the list silently un-defers
142
+ * them and the cut batch is never finished.
143
+ * - `retiredTargets` — the session-scoped deferral cap. Dropping it re-arms a
144
+ * suite already measured as too slow for the batch budget, which puts the
145
+ * livelock back.
146
+ *
147
+ * An empty-content record peeks as undelivered while keeping all three intact.
148
+ */
149
+ function retireTestFindings(cacheManager, cwd) {
150
+ const prior = cacheManager.readCache("test-runner-findings", cwd)?.data;
151
+ cacheManager.writeCache("test-runner-findings", {
152
+ content: "",
153
+ testRunGeneration: prior?.testRunGeneration,
154
+ deferredTargets: prior?.deferredTargets,
155
+ retiredTargets: prior?.retiredTargets,
156
+ }, cwd);
157
+ }
112
158
  export function consumeTestFindings(cacheManager, cwd, runtime) {
113
159
  const record = cacheManager.readCache("test-runner-findings", cwd);
114
160
  if (!record?.data?.content)
@@ -116,16 +162,7 @@ export function consumeTestFindings(cacheManager, cwd, runtime) {
116
162
  const findings = peekTestFindings(cacheManager, cwd, runtime, true);
117
163
  if (!findings)
118
164
  return;
119
- // Retire the content but PRESERVE the generation high-water mark: nulling
120
- // the whole slot would let a still-in-flight OLDER batch see `undefined`,
121
- // pass the strictly-greater suppression check, and resurrect a consumed
122
- // one-shot advisory with stale results. An empty-content record peeks as
123
- // undelivered while keeping late-generation ordering intact.
124
- const priorGeneration = cacheManager.readCache("test-runner-findings", cwd)?.data?.testRunGeneration;
125
- cacheManager.writeCache("test-runner-findings", {
126
- content: "",
127
- testRunGeneration: priorGeneration,
128
- }, cwd);
165
+ retireTestFindings(cacheManager, cwd);
129
166
  return findings;
130
167
  }
131
168
  /** Complete an acknowledged MCP delivery without re-validating or re-rendering it. */
@@ -145,11 +182,7 @@ export function acknowledgeTestFindings(cacheManager, cwd) {
145
182
  const findings = cacheManager.readCache("test-runner-findings", cwd);
146
183
  if (!findings?.data?.content)
147
184
  return;
148
- // Same high-water-mark preservation as consumeTestFindings.
149
- cacheManager.writeCache("test-runner-findings", {
150
- content: "",
151
- testRunGeneration: findings.data.testRunGeneration,
152
- }, cwd);
185
+ retireTestFindings(cacheManager, cwd);
153
186
  }
154
187
  export function consumeSessionStartGuidance(cacheManager, cwd) {
155
188
  const guidance = cacheManager.readCache("session-start-guidance", cwd);
@@ -6,6 +6,7 @@ import { appendProjectChange, } from "./project-changes.js";
6
6
  import { normalizeMapKey, pathsEqual } from "./path-utils.js";
7
7
  import { PathKeyedMap } from "./path-keyed-map.js";
8
8
  import { BoundedLruCache } from "./bounded-cache.js";
9
+ import { PartialApplyRecordStore } from "./partial-edit-apply.js";
9
10
  import { ReadGuard } from "./read-guard.js";
10
11
  import { RUNTIME_CONFIG } from "./runtime-config.js";
11
12
  import { TurnSummaryCollector } from "./turn-summary.js";
@@ -111,6 +112,11 @@ export class RuntimeCoordinator {
111
112
  // (cheap, empty Map) but callers gate recording behind the
112
113
  // `lens-turn-summary` flag so it's a true no-op when the feature is off.
113
114
  _turnSummary = new TurnSummaryCollector();
115
+ // #2402/#1053: session-scoped applied-edit records for exact-retry
116
+ // recognition. Both producers (partial-apply commit, full native-edit
117
+ // success) write here; the preflight consults it before declaring an
118
+ // oldText miss, so an identical retry never re-executes a committed write.
119
+ partialApplyRecords = new PartialApplyRecordStore();
114
120
  resetForSession(startedAt = Date.now()) {
115
121
  this._sessionGeneration += 1;
116
122
  this._sessionStartedAt = startedAt;
@@ -159,6 +165,9 @@ export class RuntimeCoordinator {
159
165
  this._actionableWarningsThisTurn.clear();
160
166
  this._codeQualityWarningsThisTurn.clear();
161
167
  this._turnSummary.clear();
168
+ // #2402: an applied-edit record is a fact about the session that applied
169
+ // it; a new session must re-resolve identical payloads from content.
170
+ this.partialApplyRecords.clear();
162
171
  }
163
172
  get sessionStartedAt() {
164
173
  return this._sessionStartedAt;
@@ -317,9 +326,15 @@ export class RuntimeCoordinator {
317
326
  get droppedMutationReceiptCount() {
318
327
  return this._droppedMutationReceipts;
319
328
  }
320
- /** Atomically records write/edit ordering before debounce can coalesce it. */
321
- recordMutationToolReceipt(filePath, toolName) {
322
- if (toolName === "write") {
329
+ /**
330
+ * Atomically records write/edit ordering before debounce can coalesce it.
331
+ *
332
+ * Takes the classified {@link MutationKind}, not a raw tool name (#2423):
333
+ * an edit-shaped tool pi-lens does not name still demotes this file to the
334
+ * deferred pass, which is the safe timing.
335
+ */
336
+ recordMutationToolReceipt(filePath, kind) {
337
+ if (kind === "write") {
323
338
  this._writtenThisTurn.set(filePath, true);
324
339
  }
325
340
  else if (this._writtenThisTurn.has(filePath)) {
@@ -329,7 +344,7 @@ export class RuntimeCoordinator {
329
344
  this._fixedThisTurn.delete(filePath);
330
345
  }
331
346
  return {
332
- autofixMode: toolName === "edit" || this._autofixDemotedThisTurn.has(filePath)
347
+ autofixMode: kind === "edit" || this._autofixDemotedThisTurn.has(filePath)
333
348
  ? "deferred"
334
349
  : "immediate",
335
350
  };
@@ -999,7 +1014,9 @@ export class RuntimeCoordinator {
999
1014
  * for a same-kind re-touch. Callers publish each kind's first transition
1000
1015
  * without spamming repeated edits before `agent_end`.
1001
1016
  */
1002
- deferMutation(filePath, cwd, toolName, turnStateCwd, kind, ownerSessionId, originCwd) {
1017
+ deferMutation(filePath, cwd,
1018
+ /** Host tool name; any mutating tool, not just `write`/`edit` (#2423). */
1019
+ toolName, turnStateCwd, kind, ownerSessionId, originCwd) {
1003
1020
  const key = path.resolve(filePath);
1004
1021
  const now = Date.now();
1005
1022
  const resolvedOriginCwd = originCwd ?? turnStateCwd;
@@ -1030,7 +1047,9 @@ export class RuntimeCoordinator {
1030
1047
  });
1031
1048
  return true;
1032
1049
  }
1033
- deferFormat(filePath, cwd, toolName, turnStateCwd, ownerSessionId, originCwd) {
1050
+ deferFormat(filePath, cwd,
1051
+ /** Host tool name; any mutating tool, not just `write`/`edit` (#2423). */
1052
+ toolName, turnStateCwd, ownerSessionId, originCwd) {
1034
1053
  return this.deferMutation(filePath, cwd, toolName, turnStateCwd, "format", ownerSessionId, originCwd);
1035
1054
  }
1036
1055
  get pendingDeferredFormatCount() {