pi-lens 4.3.0 → 4.4.1

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 (659) hide show
  1. package/CHANGELOG.md +1159 -0
  2. package/README.md +116 -25
  3. package/config/dependency-cruiser-eager-allowlist.json +6 -2
  4. package/dist/chunk-2BEMIWEW.js +51 -0
  5. package/dist/chunk-2EECBNC5.js +89 -0
  6. package/dist/chunk-2FQ62SPM.js +83 -0
  7. package/dist/chunk-2UMYMRI3.js +118 -0
  8. package/dist/chunk-34OCDWOS.js +48 -0
  9. package/dist/chunk-3FERWMCH.js +144 -0
  10. package/dist/chunk-3JL6IFD7.js +97 -0
  11. package/dist/chunk-3JSEWUWI.js +327 -0
  12. package/dist/chunk-3MED75HT.js +37 -0
  13. package/dist/chunk-3MRXIJ6I.js +79 -0
  14. package/dist/chunk-3P4PF2BX.js +2250 -0
  15. package/dist/chunk-3PNFWVHT.js +201 -0
  16. package/dist/chunk-3TTPKMEF.js +162 -0
  17. package/dist/chunk-5JHXUETW.js +326 -0
  18. package/dist/chunk-5W3R6LFT.js +24 -0
  19. package/dist/chunk-64LU2OVH.js +341 -0
  20. package/dist/chunk-6B5I6ICN.js +44 -0
  21. package/dist/chunk-6P54TMWL.js +274 -0
  22. package/dist/chunk-6UYA642J.js +145 -0
  23. package/dist/chunk-6XX5HCLK.js +398 -0
  24. package/dist/chunk-7AXO3ZDF.js +30 -0
  25. package/dist/chunk-7BX5DWSA.js +1907 -0
  26. package/dist/chunk-7ELY2CSM.js +902 -0
  27. package/dist/chunk-7M4T5N3V.js +38 -0
  28. package/dist/chunk-7U2IDNXN.js +37 -0
  29. package/dist/chunk-ABBOA7UD.js +157 -0
  30. package/dist/chunk-AFZYMAIV.js +756 -0
  31. package/dist/chunk-ALQRYH6O.js +112 -0
  32. package/dist/chunk-AXKPQ6ZI.js +1610 -0
  33. package/dist/chunk-BHWHXMQ2.js +62 -0
  34. package/dist/chunk-BJF25SUG.js +22 -0
  35. package/dist/chunk-BNKLYOOO.js +18 -0
  36. package/dist/chunk-BW5KFIQC.js +59 -0
  37. package/dist/chunk-CBD2B5CP.js +599 -0
  38. package/dist/chunk-CFYISHUW.js +42 -0
  39. package/dist/chunk-CMU4RMJB.js +30 -0
  40. package/dist/chunk-CULQYFLU.js +14 -0
  41. package/dist/chunk-D65GOCJB.js +289 -0
  42. package/dist/chunk-D6YF5HKX.js +59 -0
  43. package/dist/chunk-DMS52BEP.js +342 -0
  44. package/dist/chunk-ELVWJYRV.js +211 -0
  45. package/dist/chunk-EUT3B22Y.js +27 -0
  46. package/dist/chunk-F5VLZHUW.js +146 -0
  47. package/dist/chunk-FC4RP4I2.js +12 -0
  48. package/dist/chunk-FGALODG3.js +55 -0
  49. package/dist/chunk-G3RLJYA2.js +2358 -0
  50. package/dist/chunk-GAYGGICG.js +32 -0
  51. package/dist/chunk-H2W2AXD3.js +419 -0
  52. package/dist/chunk-H5EV3VMF.js +114 -0
  53. package/dist/chunk-HREZQCT3.js +106 -0
  54. package/dist/chunk-HSIRMK2D.js +517 -0
  55. package/dist/chunk-IMSQR4WO.js +184 -0
  56. package/dist/chunk-IQZXOZ7S.js +4816 -0
  57. package/dist/chunk-IR6XFA5P.js +37 -0
  58. package/dist/chunk-IUKPRZER.js +78 -0
  59. package/dist/chunk-IUR76K6A.js +262 -0
  60. package/dist/chunk-J3FZR3YY.js +98 -0
  61. package/dist/chunk-J6DFZDFA.js +562 -0
  62. package/dist/chunk-J7WJZ6W7.js +50 -0
  63. package/dist/chunk-JONGANYH.js +202 -0
  64. package/dist/chunk-KJCWXUUS.js +425 -0
  65. package/dist/chunk-KJN4IOEJ.js +17 -0
  66. package/dist/chunk-KMGPUKFD.js +25 -0
  67. package/dist/chunk-LD7WFTRX.js +4533 -0
  68. package/dist/chunk-LJDODBBZ.js +78 -0
  69. package/dist/chunk-LNOMA3MP.js +169 -0
  70. package/dist/chunk-MGIWSROG.js +2334 -0
  71. package/dist/chunk-MQA2YBAH.js +308 -0
  72. package/dist/chunk-MTDRLSI7.js +21720 -0
  73. package/dist/chunk-N2IRDBZI.js +2355 -0
  74. package/dist/chunk-N77WFUL7.js +50 -0
  75. package/dist/chunk-N7YNJE5R.js +466 -0
  76. package/dist/chunk-NABLC7W3.js +148 -0
  77. package/dist/chunk-NFXP47RV.js +999 -0
  78. package/dist/chunk-NJF2X5XF.js +45 -0
  79. package/dist/chunk-NXL4FFQQ.js +47 -0
  80. package/dist/chunk-O7HZX7CA.js +309 -0
  81. package/dist/chunk-OC7LYAU5.js +708 -0
  82. package/dist/chunk-OEX24ECI.js +348 -0
  83. package/dist/chunk-OYOB3ZFG.js +78 -0
  84. package/dist/chunk-OYTMZXRF.js +41 -0
  85. package/dist/chunk-OZJINN4O.js +84 -0
  86. package/dist/chunk-PCHDGUKT.js +23 -0
  87. package/dist/chunk-QOZXJ4NA.js +3364 -0
  88. package/dist/chunk-QYF5S6P6.js +45 -0
  89. package/dist/chunk-RJFED73B.js +79 -0
  90. package/dist/chunk-RTQNRM5X.js +27 -0
  91. package/dist/chunk-S6AMWKPC.js +189 -0
  92. package/dist/chunk-T4QZ6FEH.js +308 -0
  93. package/dist/chunk-T54VJRAD.js +5456 -0
  94. package/dist/chunk-TA5L5KWQ.js +167 -0
  95. package/dist/chunk-TQFBZVCG.js +27 -0
  96. package/dist/chunk-U52SAGRM.js +62 -0
  97. package/dist/chunk-UEAHAMEI.js +5814 -0
  98. package/dist/chunk-UGSMCQ4D.js +327 -0
  99. package/dist/chunk-UOPVJQ4N.js +103 -0
  100. package/dist/chunk-USHG4DLH.js +459 -0
  101. package/dist/chunk-UXVNL3D7.js +23 -0
  102. package/dist/chunk-V5MEBST3.js +4139 -0
  103. package/dist/chunk-VGEVL5EQ.js +29 -0
  104. package/dist/chunk-VPWKF3GN.js +87 -0
  105. package/dist/chunk-VSMJK3ZJ.js +1250 -0
  106. package/dist/chunk-VYKKMYVT.js +560 -0
  107. package/dist/chunk-VZHJS6DR.js +442 -0
  108. package/dist/chunk-WATC3IQR.js +213 -0
  109. package/dist/chunk-WPE5FPGR.js +54 -0
  110. package/dist/chunk-WSEWKCXU.js +188 -0
  111. package/dist/chunk-WW5BLB74.js +659 -0
  112. package/dist/chunk-XGUL4SLQ.js +406 -0
  113. package/dist/chunk-XHSCVSOL.js +170 -0
  114. package/dist/chunk-XIMYZ3JA.js +27 -0
  115. package/dist/chunk-YLN4K6WD.js +385 -0
  116. package/dist/chunk-Z3CCVDUB.js +76 -0
  117. package/dist/chunk-Z54ZSOBZ.js +61 -0
  118. package/dist/chunk-Z6BB4JLQ.js +478 -0
  119. package/dist/chunk-Z7QQA2KT.js +27 -0
  120. package/dist/chunk-ZETYB3XG.js +2626 -0
  121. package/dist/chunk-ZMOMPX2Z.js +87 -0
  122. package/dist/chunk-ZOEYVXSV.js +149 -0
  123. package/dist/chunk-ZZUFZUQZ.js +12120 -0
  124. package/dist/index.js +39712 -29876
  125. package/dist/mcp/analyze-cli.js +186 -232
  126. package/dist/mcp/cli.js +137 -98
  127. package/dist/mcp/server.js +22688 -1573
  128. package/dist/mcp/worker.js +97 -38
  129. package/dist/probes/installer.js +135 -0
  130. package/dist/workers/project-snapshot-persist-worker.js +22 -0
  131. package/dist/workers/review-graph-persist-worker.js +15 -0
  132. package/docs/agent-guide.md +13 -4
  133. package/docs/agent-tools.md +42 -0
  134. package/docs/ast-grep_rules_catalog.md +5 -4
  135. package/docs/configuration.md +28 -2
  136. package/docs/custom-rules.md +25 -2
  137. package/docs/environment-variables.md +86 -8
  138. package/docs/features.md +45 -5
  139. package/docs/globalconfig.md +2 -1
  140. package/docs/io-bridge-v2-migration.md +94 -0
  141. package/docs/lsp-capability-matrix.md +37 -4
  142. package/docs/lsp-idle-eviction.md +124 -0
  143. package/docs/mcp.md +21 -5
  144. package/docs/merge-queue-rollout.md +77 -0
  145. package/docs/pi-lens-fixer.md +160 -88
  146. package/docs/pi-lens-investigator.md +74 -26
  147. package/docs/pi-lens-merge-policy.md +736 -0
  148. package/docs/pi-lens-monitor.md +75 -7
  149. package/docs/pi-lens-retro.md +6 -4
  150. package/docs/pi-lens-reviewer.md +189 -48
  151. package/docs/pi-lens-subagent.md +246 -45
  152. package/docs/pi-lens-warden.md +18 -7
  153. package/docs/public-api-stability.md +55 -0
  154. package/docs/release-qa-baseline.md +84 -17
  155. package/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
  156. package/docs/schema/pi-lens-config-v1.json +530 -0
  157. package/docs/servercapabilities.md +56 -49
  158. package/docs/settings.md +1 -0
  159. package/docs/usage.md +5 -1
  160. package/docs/word-index.md +6 -0
  161. package/grammars/tree-sitter-bash.wasm +0 -0
  162. package/grammars/tree-sitter-bash.wasm.json +3 -3
  163. package/package.json +19 -7
  164. package/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
  165. package/rules/ast-grep-rules/rule-tests/no-identity-operator-on-literals-test.yml +12 -2
  166. package/rules/ast-grep-rules/rule-tests/throw-new-error-js-test.yml +2 -0
  167. package/rules/ast-grep-rules/rule-tests/throw-new-error-test.yml +2 -0
  168. package/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
  169. package/rules/ast-grep-rules/rules/no-identity-operator-on-literals.yml +20 -12
  170. package/rules/ast-grep-rules/rules/throw-new-error-js.yml +2 -2
  171. package/rules/ast-grep-rules/rules/throw-new-error.yml +2 -2
  172. package/scripts/analyze-pi-lens-logs.mjs +1275 -62
  173. package/scripts/download-grammars.js +5 -0
  174. package/scripts/grammars.lock.json +6 -1
  175. package/scripts/install-selftest.mjs +33 -34
  176. package/scripts/lib/host-provided-deps.mjs +13 -4
  177. package/scripts/lib/web-tree-sitter-dir.mjs +18 -0
  178. package/dist/clients/actionable-warnings-logger.js +0 -35
  179. package/dist/clients/actionable-warnings.js +0 -1610
  180. package/dist/clients/advisory-provenance.js +0 -593
  181. package/dist/clients/agent-behavior-client.js +0 -147
  182. package/dist/clients/agent-nudge.js +0 -325
  183. package/dist/clients/analysed-root.js +0 -1
  184. package/dist/clients/ast-grep-client.js +0 -731
  185. package/dist/clients/ast-grep-rule-manager.js +0 -146
  186. package/dist/clients/ast-grep-tool-logger.js +0 -118
  187. package/dist/clients/ast-grep-types.js +0 -10
  188. package/dist/clients/ast-grep-yaml-synth.js +0 -154
  189. package/dist/clients/atomic-write-staging.js +0 -75
  190. package/dist/clients/atomic-write.js +0 -189
  191. package/dist/clients/availability-probe-flight.js +0 -12
  192. package/dist/clients/bash-file-access.js +0 -1056
  193. package/dist/clients/biome-client.js +0 -357
  194. package/dist/clients/blocker-freshness.js +0 -837
  195. package/dist/clients/blocker-past-eof.js +0 -129
  196. package/dist/clients/bootstrap.js +0 -569
  197. package/dist/clients/bounded-cache.js +0 -190
  198. package/dist/clients/bounded-pid-file-lock.js +0 -202
  199. package/dist/clients/bounded-telemetry.js +0 -295
  200. package/dist/clients/build-identity.js +0 -95
  201. package/dist/clients/bundled-resource-health.js +0 -113
  202. package/dist/clients/bus-events-logger.js +0 -105
  203. package/dist/clients/bus-publish.js +0 -171
  204. package/dist/clients/cache/rule-cache.js +0 -190
  205. package/dist/clients/cache-manager.js +0 -524
  206. package/dist/clients/cache-observability.js +0 -1313
  207. package/dist/clients/call-graph.js +0 -852
  208. package/dist/clients/cargo-manifest.js +0 -422
  209. package/dist/clients/cascade-budget.js +0 -196
  210. package/dist/clients/cascade-format.js +0 -315
  211. package/dist/clients/cascade-logger.js +0 -31
  212. package/dist/clients/cascade-types.js +0 -9
  213. package/dist/clients/child-unref.js +0 -124
  214. package/dist/clients/code-quality-warnings.js +0 -286
  215. package/dist/clients/codebase-model.js +0 -173
  216. package/dist/clients/collateral-test-role.js +0 -40
  217. package/dist/clients/complexity-client.js +0 -462
  218. package/dist/clients/config-core/deny.js +0 -221
  219. package/dist/clients/config-core/index.js +0 -50
  220. package/dist/clients/config-core/merge.js +0 -357
  221. package/dist/clients/config-core/normalize.js +0 -340
  222. package/dist/clients/config-core/process-spec.js +0 -248
  223. package/dist/clients/config-core/provenance.js +0 -164
  224. package/dist/clients/config-core/records.js +0 -218
  225. package/dist/clients/config-core/resolve.js +0 -125
  226. package/dist/clients/config-core/safe-object.js +0 -78
  227. package/dist/clients/config-core/schema.js +0 -165
  228. package/dist/clients/config-diagnostic-codes.js +0 -285
  229. package/dist/clients/config-locations.js +0 -388
  230. package/dist/clients/config-resolve.js +0 -798
  231. package/dist/clients/config-schema.js +0 -251
  232. package/dist/clients/config-warn.js +0 -407
  233. package/dist/clients/console-guard-install.js +0 -26
  234. package/dist/clients/cooperative-budget.js +0 -42
  235. package/dist/clients/dead-code-client.js +0 -510
  236. package/dist/clients/dead-code-logger.js +0 -30
  237. package/dist/clients/deadline-utils.js +0 -280
  238. package/dist/clients/debug-handles.js +0 -211
  239. package/dist/clients/debug-heap.js +0 -174
  240. package/dist/clients/deferred-lsp-work.js +0 -106
  241. package/dist/clients/degradation-ledger.js +0 -426
  242. package/dist/clients/demoted-finding-render.js +0 -169
  243. package/dist/clients/dependency-checker.js +0 -885
  244. package/dist/clients/deps/ast-grep-napi.js +0 -22
  245. package/dist/clients/deps/js-yaml.js +0 -9
  246. package/dist/clients/deps/minimatch.js +0 -4
  247. package/dist/clients/deps/pi-tui.js +0 -14
  248. package/dist/clients/deps/typebox.js +0 -14
  249. package/dist/clients/deps/vscode-jsonrpc.js +0 -1
  250. package/dist/clients/deps/web-tree-sitter.js +0 -24
  251. package/dist/clients/diagnostic-dispositions.js +0 -630
  252. package/dist/clients/diagnostic-line-freshness.js +0 -305
  253. package/dist/clients/diagnostic-logger.js +0 -73
  254. package/dist/clients/diagnostic-tracker.js +0 -105
  255. package/dist/clients/diagnostics-publish.js +0 -230
  256. package/dist/clients/dispatch/ast-grep-catalog.js +0 -65
  257. package/dist/clients/dispatch/auxiliary-lsp.js +0 -343
  258. package/dist/clients/dispatch/collect-later-tier.js +0 -35
  259. package/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
  260. package/dist/clients/dispatch/dispatcher.js +0 -1269
  261. package/dist/clients/dispatch/fact-provider-types.js +0 -1
  262. package/dist/clients/dispatch/fact-rule-runner.js +0 -17
  263. package/dist/clients/dispatch/fact-runner.js +0 -30
  264. package/dist/clients/dispatch/fact-scheduler.js +0 -68
  265. package/dist/clients/dispatch/fact-store.js +0 -377
  266. package/dist/clients/dispatch/facts/comment-facts.js +0 -22
  267. package/dist/clients/dispatch/facts/file-content.js +0 -19
  268. package/dist/clients/dispatch/facts/function-facts.js +0 -348
  269. package/dist/clients/dispatch/facts/import-facts.js +0 -204
  270. package/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
  271. package/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
  272. package/dist/clients/dispatch/finding-policy.js +0 -339
  273. package/dist/clients/dispatch/indent-detect.js +0 -417
  274. package/dist/clients/dispatch/inline-suppressions.js +0 -89
  275. package/dist/clients/dispatch/integration.js +0 -2377
  276. package/dist/clients/dispatch/lazy.js +0 -11
  277. package/dist/clients/dispatch/pending-runner-findings.js +0 -87
  278. package/dist/clients/dispatch/plan.js +0 -278
  279. package/dist/clients/dispatch/priorities.js +0 -20
  280. package/dist/clients/dispatch/rule-id-normalize.js +0 -50
  281. package/dist/clients/dispatch/rule-ignores.js +0 -69
  282. package/dist/clients/dispatch/rule-policy.js +0 -135
  283. package/dist/clients/dispatch/rules/async-noise.js +0 -40
  284. package/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
  285. package/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
  286. package/dist/clients/dispatch/rules/error-obscuring.js +0 -32
  287. package/dist/clients/dispatch/rules/error-swallowing.js +0 -31
  288. package/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
  289. package/dist/clients/dispatch/rules/high-complexity.js +0 -72
  290. package/dist/clients/dispatch/rules/high-fan-out.js +0 -74
  291. package/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
  292. package/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
  293. package/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
  294. package/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
  295. package/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
  296. package/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
  297. package/dist/clients/dispatch/runner-context.js +0 -52
  298. package/dist/clients/dispatch/runners/actionlint.js +0 -111
  299. package/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
  300. package/dist/clients/dispatch/runners/biome-check.js +0 -296
  301. package/dist/clients/dispatch/runners/cpp-check.js +0 -219
  302. package/dist/clients/dispatch/runners/credo.js +0 -82
  303. package/dist/clients/dispatch/runners/cue-vet.js +0 -416
  304. package/dist/clients/dispatch/runners/dart-analyze.js +0 -183
  305. package/dist/clients/dispatch/runners/detekt.js +0 -176
  306. package/dist/clients/dispatch/runners/dotnet-build.js +0 -164
  307. package/dist/clients/dispatch/runners/elixir-check.js +0 -195
  308. package/dist/clients/dispatch/runners/eslint.js +0 -137
  309. package/dist/clients/dispatch/runners/fact-rules.js +0 -29
  310. package/dist/clients/dispatch/runners/fish-indent.js +0 -69
  311. package/dist/clients/dispatch/runners/gleam-check.js +0 -167
  312. package/dist/clients/dispatch/runners/go-vet.js +0 -104
  313. package/dist/clients/dispatch/runners/golangci-lint.js +0 -135
  314. package/dist/clients/dispatch/runners/hadolint.js +0 -91
  315. package/dist/clients/dispatch/runners/helm-lint.js +0 -171
  316. package/dist/clients/dispatch/runners/helm-render.js +0 -940
  317. package/dist/clients/dispatch/runners/htmlhint.js +0 -117
  318. package/dist/clients/dispatch/runners/index.js +0 -108
  319. package/dist/clients/dispatch/runners/javac.js +0 -99
  320. package/dist/clients/dispatch/runners/ktlint.js +0 -110
  321. package/dist/clients/dispatch/runners/lsp.js +0 -379
  322. package/dist/clients/dispatch/runners/markdownlint.js +0 -167
  323. package/dist/clients/dispatch/runners/mypy.js +0 -102
  324. package/dist/clients/dispatch/runners/oxlint.js +0 -414
  325. package/dist/clients/dispatch/runners/php-lint.js +0 -85
  326. package/dist/clients/dispatch/runners/phpstan.js +0 -120
  327. package/dist/clients/dispatch/runners/prisma-validate.js +0 -62
  328. package/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
  329. package/dist/clients/dispatch/runners/pyright.js +0 -169
  330. package/dist/clients/dispatch/runners/rubocop.js +0 -99
  331. package/dist/clients/dispatch/runners/ruff.js +0 -88
  332. package/dist/clients/dispatch/runners/rust-clippy.js +0 -256
  333. package/dist/clients/dispatch/runners/shellcheck.js +0 -173
  334. package/dist/clients/dispatch/runners/shfmt.js +0 -102
  335. package/dist/clients/dispatch/runners/spellcheck.js +0 -128
  336. package/dist/clients/dispatch/runners/spotbugs.js +0 -259
  337. package/dist/clients/dispatch/runners/sqlfluff.js +0 -183
  338. package/dist/clients/dispatch/runners/stylelint.js +0 -166
  339. package/dist/clients/dispatch/runners/swiftlint.js +0 -163
  340. package/dist/clients/dispatch/runners/taplo.js +0 -174
  341. package/dist/clients/dispatch/runners/terragrunt.js +0 -168
  342. package/dist/clients/dispatch/runners/tflint.js +0 -125
  343. package/dist/clients/dispatch/runners/tree-sitter.js +0 -643
  344. package/dist/clients/dispatch/runners/trivy-config.js +0 -253
  345. package/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
  346. package/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
  347. package/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -95
  348. package/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
  349. package/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
  350. package/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
  351. package/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
  352. package/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
  353. package/dist/clients/dispatch/runners/utils.js +0 -15
  354. package/dist/clients/dispatch/runners/vale.js +0 -128
  355. package/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
  356. package/dist/clients/dispatch/runners/yamllint.js +0 -95
  357. package/dist/clients/dispatch/runners/zig-check.js +0 -79
  358. package/dist/clients/dispatch/suppress-writer.js +0 -79
  359. package/dist/clients/dispatch/tool-profile.js +0 -30
  360. package/dist/clients/dispatch/types.js +0 -21
  361. package/dist/clients/dispatch/utils/format-utils.js +0 -45
  362. package/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
  363. package/dist/clients/disposition-logger.js +0 -32
  364. package/dist/clients/disposition-publish.js +0 -124
  365. package/dist/clients/durable-store.js +0 -97
  366. package/dist/clients/effective-config.js +0 -415
  367. package/dist/clients/env-utils.js +0 -83
  368. package/dist/clients/error-class.js +0 -23
  369. package/dist/clients/eval-timestamp.js +0 -17
  370. package/dist/clients/event-loop-hold.js +0 -274
  371. package/dist/clients/event-loop-monitor.js +0 -250
  372. package/dist/clients/extension-log.js +0 -504
  373. package/dist/clients/extension-mode.js +0 -73
  374. package/dist/clients/feature-hints.js +0 -103
  375. package/dist/clients/file-kinds.js +0 -412
  376. package/dist/clients/file-role.js +0 -134
  377. package/dist/clients/file-time.js +0 -160
  378. package/dist/clients/file-utils.js +0 -1032
  379. package/dist/clients/finding-delivery-gate.js +0 -494
  380. package/dist/clients/finding-identity.js +0 -88
  381. package/dist/clients/fix-worklog.js +0 -103
  382. package/dist/clients/format-events-publish.js +0 -343
  383. package/dist/clients/format-service.js +0 -222
  384. package/dist/clients/formatters-lazy.js +0 -9
  385. package/dist/clients/formatters.js +0 -2032
  386. package/dist/clients/freshness-cadence.js +0 -17
  387. package/dist/clients/freshness.js +0 -38
  388. package/dist/clients/generated-artifacts.js +0 -394
  389. package/dist/clients/generation-guard.js +0 -215
  390. package/dist/clients/git-guard.js +0 -1136
  391. package/dist/clients/git-tracked-ignore.js +0 -243
  392. package/dist/clients/gitleaks-client.js +0 -509
  393. package/dist/clients/go-client.js +0 -104
  394. package/dist/clients/govulncheck-client.js +0 -605
  395. package/dist/clients/gradle-ktfmt-style.js +0 -348
  396. package/dist/clients/grammar-source.js +0 -465
  397. package/dist/clients/gzip-stage-write.js +0 -135
  398. package/dist/clients/hashline-anchor.js +0 -424
  399. package/dist/clients/hook-budgets.js +0 -76
  400. package/dist/clients/host-edit-normalize.js +0 -140
  401. package/dist/clients/host-ports.js +0 -39
  402. package/dist/clients/indent-retarget.js +0 -154
  403. package/dist/clients/inline-blocker-dispositions.js +0 -186
  404. package/dist/clients/install-diagnostics.js +0 -156
  405. package/dist/clients/installer/index.js +0 -5416
  406. package/dist/clients/installer/managed-tool-refresh-session.js +0 -58
  407. package/dist/clients/installer/managed-tool-refresh.js +0 -783
  408. package/dist/clients/instance-reaper-state.js +0 -7
  409. package/dist/clients/instance-reaper.js +0 -1137
  410. package/dist/clients/instance-registry-lock.js +0 -145
  411. package/dist/clients/instance-registry.js +0 -773
  412. package/dist/clients/jscpd-client.js +0 -378
  413. package/dist/clients/json-cache-read.js +0 -65
  414. package/dist/clients/knip-client.js +0 -788
  415. package/dist/clients/language-policy.js +0 -252
  416. package/dist/clients/language-profile.js +0 -361
  417. package/dist/clients/language-registry.js +0 -603
  418. package/dist/clients/latency-logger.js +0 -727
  419. package/dist/clients/lazy-import.js +0 -21
  420. package/dist/clients/ledger-bounds.js +0 -54
  421. package/dist/clients/lens-config.js +0 -404
  422. package/dist/clients/lens-engine.js +0 -358
  423. package/dist/clients/lens-events.js +0 -125
  424. package/dist/clients/lens-flag-registry.js +0 -467
  425. package/dist/clients/lens-map.js +0 -1156
  426. package/dist/clients/live-bus-emitter.js +0 -74
  427. package/dist/clients/log-cleanup.js +0 -222
  428. package/dist/clients/lsp/aggregation.js +0 -178
  429. package/dist/clients/lsp/cascade-tier.js +0 -421
  430. package/dist/clients/lsp/client.js +0 -4593
  431. package/dist/clients/lsp/config.js +0 -691
  432. package/dist/clients/lsp/content-limits.js +0 -41
  433. package/dist/clients/lsp/diagnostic-binding.js +0 -225
  434. package/dist/clients/lsp/document-drift.js +0 -467
  435. package/dist/clients/lsp/edits.js +0 -1219
  436. package/dist/clients/lsp/index.js +0 -8305
  437. package/dist/clients/lsp/inferred-project.js +0 -216
  438. package/dist/clients/lsp/jvm-runtime.js +0 -298
  439. package/dist/clients/lsp/language.js +0 -63
  440. package/dist/clients/lsp/launch.js +0 -746
  441. package/dist/clients/lsp/lombok.js +0 -158
  442. package/dist/clients/lsp/path-utils.js +0 -5
  443. package/dist/clients/lsp/pending-aux-coverage.js +0 -251
  444. package/dist/clients/lsp/position-encoding.js +0 -61
  445. package/dist/clients/lsp/ruby-drive-dirs.js +0 -83
  446. package/dist/clients/lsp/server.js +0 -3290
  447. package/dist/clients/lsp/session-roots.js +0 -192
  448. package/dist/clients/lsp/spawn-history.js +0 -17
  449. package/dist/clients/lsp/sync-kind.js +0 -56
  450. package/dist/clients/lsp/tsserver-sync.js +0 -332
  451. package/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
  452. package/dist/clients/lsp/wait-policy/classification.js +0 -85
  453. package/dist/clients/lsp/wait-policy/index.js +0 -10
  454. package/dist/clients/lsp/wait-policy/strategies.js +0 -392
  455. package/dist/clients/lsp/watch-queue.js +0 -61
  456. package/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
  457. package/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
  458. package/dist/clients/lsp/workspace-sweep-hold.js +0 -184
  459. package/dist/clients/lsp-budget.js +0 -186
  460. package/dist/clients/lsp-document-symbols.js +0 -110
  461. package/dist/clients/lsp-lazy.js +0 -9
  462. package/dist/clients/lsp-mutation.js +0 -396
  463. package/dist/clients/lsp-status.js +0 -59
  464. package/dist/clients/map-with-concurrency.js +0 -40
  465. package/dist/clients/mcp/analyze.js +0 -420
  466. package/dist/clients/mcp/host-shim.js +0 -31
  467. package/dist/clients/mcp/ipc.js +0 -523
  468. package/dist/clients/mcp/review.js +0 -197
  469. package/dist/clients/mcp/session.js +0 -412
  470. package/dist/clients/memory-sampler.js +0 -208
  471. package/dist/clients/message-end-attribution.js +0 -30
  472. package/dist/clients/metrics-client.js +0 -107
  473. package/dist/clients/metrics-history.js +0 -327
  474. package/dist/clients/middle-man-analysis.js +0 -263
  475. package/dist/clients/model-provider.js +0 -53
  476. package/dist/clients/module-report-lsp.js +0 -189
  477. package/dist/clients/module-report.js +0 -2150
  478. package/dist/clients/mutating-tool.js +0 -651
  479. package/dist/clients/mutation-attribution.js +0 -368
  480. package/dist/clients/mutation-bridge.js +0 -240
  481. package/dist/clients/ndjson-logger.js +0 -734
  482. package/dist/clients/observed-mutation-sources.js +0 -101
  483. package/dist/clients/observed-mutation.js +0 -1253
  484. package/dist/clients/oldtext-autopatch.js +0 -128
  485. package/dist/clients/opaque-mutation-scan.js +0 -496
  486. package/dist/clients/opengrep-client.js +0 -333
  487. package/dist/clients/opengrep-config.js +0 -76
  488. package/dist/clients/package-manager.js +0 -607
  489. package/dist/clients/package-root.js +0 -38
  490. package/dist/clients/partial-edit-apply.js +0 -439
  491. package/dist/clients/path-attribution-telemetry.js +0 -43
  492. package/dist/clients/path-keyed-map.js +0 -108
  493. package/dist/clients/path-utils.js +0 -1244
  494. package/dist/clients/performance-report.js +0 -331
  495. package/dist/clients/persist-debounce.js +0 -70
  496. package/dist/clients/persistent-reverify.js +0 -271
  497. package/dist/clients/php-cs-fixer-config.js +0 -119
  498. package/dist/clients/pipeline.js +0 -1480
  499. package/dist/clients/post-autofix-notice.js +0 -37
  500. package/dist/clients/print-mode.js +0 -21
  501. package/dist/clients/probe-home-state.js +0 -228
  502. package/dist/clients/process-bridge.js +0 -66
  503. package/dist/clients/process-singletons.js +0 -210
  504. package/dist/clients/process-snapshot.js +0 -68
  505. package/dist/clients/project-changes.js +0 -181
  506. package/dist/clients/project-conventions.js +0 -171
  507. package/dist/clients/project-diagnostics/cache.js +0 -137
  508. package/dist/clients/project-diagnostics/extractors.js +0 -109
  509. package/dist/clients/project-diagnostics/fresh-fetch.js +0 -668
  510. package/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
  511. package/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
  512. package/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
  513. package/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
  514. package/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
  515. package/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
  516. package/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
  517. package/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
  518. package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
  519. package/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
  520. package/dist/clients/project-diagnostics/scanner.js +0 -520
  521. package/dist/clients/project-diagnostics/types.js +0 -1
  522. package/dist/clients/project-lens-config.js +0 -807
  523. package/dist/clients/project-report.js +0 -701
  524. package/dist/clients/project-scale.js +0 -237
  525. package/dist/clients/project-scan-policy.js +0 -11
  526. package/dist/clients/project-snapshot-fingerprint.js +0 -48
  527. package/dist/clients/project-snapshot-persist-worker.js +0 -20
  528. package/dist/clients/project-snapshot.js +0 -1653
  529. package/dist/clients/project-trust.js +0 -181
  530. package/dist/clients/python-environment.js +0 -217
  531. package/dist/clients/python-provenance.js +0 -639
  532. package/dist/clients/quiet-window-config.js +0 -47
  533. package/dist/clients/quiet-window.js +0 -236
  534. package/dist/clients/read-bridge.js +0 -139
  535. package/dist/clients/read-expansion.js +0 -266
  536. package/dist/clients/read-guard-logger.js +0 -251
  537. package/dist/clients/read-guard-tool-lines.js +0 -1306
  538. package/dist/clients/read-guard.js +0 -1561
  539. package/dist/clients/recent-touches.js +0 -240
  540. package/dist/clients/redact/secrets.js +0 -449
  541. package/dist/clients/resource-sampler.js +0 -628
  542. package/dist/clients/reverse-deps.js +0 -270
  543. package/dist/clients/review-graph/builder.js +0 -5126
  544. package/dist/clients/review-graph/format.js +0 -33
  545. package/dist/clients/review-graph/git-identity.js +0 -163
  546. package/dist/clients/review-graph/import-resolvers.js +0 -481
  547. package/dist/clients/review-graph/persist-worker.js +0 -10
  548. package/dist/clients/review-graph/query.js +0 -244
  549. package/dist/clients/review-graph/revision-drift.js +0 -21
  550. package/dist/clients/review-graph/service.js +0 -96
  551. package/dist/clients/review-graph/shared-extraction-ir.js +0 -82
  552. package/dist/clients/review-graph/symbol-id.js +0 -103
  553. package/dist/clients/review-graph/tsconfig-paths.js +0 -299
  554. package/dist/clients/review-graph/types.js +0 -1
  555. package/dist/clients/review-graph/workspace-modules.js +0 -449
  556. package/dist/clients/review-graph-logger.js +0 -81
  557. package/dist/clients/ruff-client.js +0 -179
  558. package/dist/clients/rules-scanner.js +0 -131
  559. package/dist/clients/run-duration.js +0 -55
  560. package/dist/clients/runtime-agent-end.js +0 -746
  561. package/dist/clients/runtime-config.js +0 -77
  562. package/dist/clients/runtime-context.js +0 -211
  563. package/dist/clients/runtime-coordinator.js +0 -1324
  564. package/dist/clients/runtime-session.js +0 -2485
  565. package/dist/clients/runtime-tool-call.js +0 -1295
  566. package/dist/clients/runtime-tool-result.js +0 -2049
  567. package/dist/clients/runtime-turn.js +0 -3767
  568. package/dist/clients/rust-client.js +0 -97
  569. package/dist/clients/safe-spawn.js +0 -2357
  570. package/dist/clients/sanitize.js +0 -286
  571. package/dist/clients/scan-utils.js +0 -25
  572. package/dist/clients/scratch-tree-policy.js +0 -165
  573. package/dist/clients/search-read-registration.js +0 -94
  574. package/dist/clients/secret-findings.js +0 -114
  575. package/dist/clients/security-scan-client.js +0 -352
  576. package/dist/clients/session-event-guard.js +0 -297
  577. package/dist/clients/session-lifecycle.js +0 -484
  578. package/dist/clients/session-start-observability.js +0 -94
  579. package/dist/clients/session-state-store.js +0 -101
  580. package/dist/clients/session-summary.js +0 -15
  581. package/dist/clients/sessionstart-logger.js +0 -27
  582. package/dist/clients/sg-runner.js +0 -876
  583. package/dist/clients/sgconfig.js +0 -347
  584. package/dist/clients/shared-checkout-guard.js +0 -338
  585. package/dist/clients/single-flight.js +0 -158
  586. package/dist/clients/situational-tool-telemetry.js +0 -108
  587. package/dist/clients/skills-resolver.js +0 -141
  588. package/dist/clients/slow-fs.js +0 -138
  589. package/dist/clients/smells-rollup.js +0 -231
  590. package/dist/clients/source-filter.js +0 -596
  591. package/dist/clients/source-walker.js +0 -211
  592. package/dist/clients/spawn-output-cap.js +0 -120
  593. package/dist/clients/spawn-timeout-cooldown.js +0 -110
  594. package/dist/clients/stale-marker.js +0 -17
  595. package/dist/clients/startup-scan.js +0 -400
  596. package/dist/clients/startup-timing.js +0 -130
  597. package/dist/clients/string-utils.js +0 -33
  598. package/dist/clients/subagent-mode.js +0 -111
  599. package/dist/clients/symbol-containment.js +0 -24
  600. package/dist/clients/symbol-types.js +0 -5
  601. package/dist/clients/test-runner-client.js +0 -2507
  602. package/dist/clients/test-runner-delivery.js +0 -287
  603. package/dist/clients/todo-scanner.js +0 -229
  604. package/dist/clients/tool-agreement.js +0 -423
  605. package/dist/clients/tool-config.js +0 -249
  606. package/dist/clients/tool-cwd.js +0 -270
  607. package/dist/clients/tool-definition.js +0 -47
  608. package/dist/clients/tool-event.js +0 -105
  609. package/dist/clients/tool-policy.js +0 -2755
  610. package/dist/clients/tool-probe.js +0 -53
  611. package/dist/clients/tool-render.js +0 -156
  612. package/dist/clients/tool-set-policy.js +0 -118
  613. package/dist/clients/tree-sitter-cache.js +0 -364
  614. package/dist/clients/tree-sitter-client.js +0 -4195
  615. package/dist/clients/tree-sitter-logger.js +0 -100
  616. package/dist/clients/tree-sitter-navigator.js +0 -269
  617. package/dist/clients/tree-sitter-query-loader.js +0 -569
  618. package/dist/clients/tree-sitter-shared.js +0 -158
  619. package/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
  620. package/dist/clients/trivy-client.js +0 -467
  621. package/dist/clients/tui-fit.js +0 -50
  622. package/dist/clients/turn-context.js +0 -52
  623. package/dist/clients/turn-end/lane.js +0 -51
  624. package/dist/clients/turn-end/lanes/govulncheck.js +0 -112
  625. package/dist/clients/turn-end/lanes/secrets.js +0 -204
  626. package/dist/clients/turn-summary-render.js +0 -72
  627. package/dist/clients/turn-summary.js +0 -132
  628. package/dist/clients/typos-config.js +0 -29
  629. package/dist/clients/user-notify.js +0 -51
  630. package/dist/clients/vanished-instance-marker.js +0 -57
  631. package/dist/clients/warm-attach.js +0 -305
  632. package/dist/clients/widget-state.js +0 -1808
  633. package/dist/clients/word-index-logger.js +0 -49
  634. package/dist/clients/word-index-store.js +0 -459
  635. package/dist/clients/word-index.js +0 -2080
  636. package/dist/clients/workspace-topology.js +0 -443
  637. package/dist/clients/write-ordering-guard.js +0 -65
  638. package/dist/clients/zizmor-config.js +0 -340
  639. package/dist/i18n.js +0 -69
  640. package/dist/mcp/build-staleness.js +0 -124
  641. package/dist/scripts/lib/process-scan.mjs +0 -583
  642. package/dist/scripts/lib/skills-predicate.mjs +0 -129
  643. package/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -123
  644. package/dist/tools/activate-tools.js +0 -87
  645. package/dist/tools/ast-grep-outline.js +0 -137
  646. package/dist/tools/ast-grep-replace.js +0 -244
  647. package/dist/tools/ast-grep-search.js +0 -762
  648. package/dist/tools/effective-config.js +0 -90
  649. package/dist/tools/lens-diagnostic-mark.js +0 -375
  650. package/dist/tools/lens-diagnostics.js +0 -2571
  651. package/dist/tools/lsp-diagnostics.js +0 -1745
  652. package/dist/tools/lsp-navigation.js +0 -1367
  653. package/dist/tools/lsp-structured-output.js +0 -294
  654. package/dist/tools/module-report.js +0 -382
  655. package/dist/tools/project-report.js +0 -86
  656. package/dist/tools/render-compact.js +0 -374
  657. package/dist/tools/scan-progress.js +0 -53
  658. package/dist/tools/shared.js +0 -29
  659. package/dist/tools/symbol-search.js +0 -155
@@ -1,147 +0,0 @@
1
- /**
2
- * AgentBehaviorClient for pi-lens
3
- *
4
- * Tracks tool call sequences and flags anti-patterns in real-time:
5
- * - Blind writes: editing or writing without reading first (a same-session
6
- * write/edit of the same path counts as file knowledge)
7
- * - Thrashing: repeated identical tool calls with no progress
8
- *
9
- * No external dependencies — purely tracks tool call history.
10
- */
11
- import { isMutatingToolName } from "./mutating-tool.js";
12
- import { normalizeMapKey } from "./path-utils.js";
13
- // --- Constants ---
14
- // #2423: mutating-tool membership comes from the seam
15
- // (`clients/mutating-tool.ts`), the single source of truth for the built-in
16
- // table. The hand-maintained set this replaced also carried a dead
17
- // `"multiedit"` entry that no host emits.
18
- //
19
- // Known gap, stated rather than hidden: this client is handed a tool NAME and a
20
- // path, never the event, so it cannot see a third-party mutating tool the way
21
- // the shape adapters can. Blind-write and thrash detection covers pi's
22
- // built-ins only.
23
- const READ_OPS = new Set(["read", "bash", "grep", "glob", "find", "rg"]);
24
- const BLIND_WRITE_WINDOW = 5; // Check last N tool calls for a read
25
- const THRASH_THRESHOLD = 3; // Flag after N consecutive identical tool+file pairs
26
- const THRASH_TIMEOUT_MS = 30_000; // Reset thrash counter if gap > 30s
27
- // --- Client ---
28
- export class AgentBehaviorClient {
29
- toolHistory = [];
30
- consecutiveCount = 0;
31
- lastToolName = null;
32
- lastToolFilePath = null;
33
- lastToolTimestamp = 0;
34
- // Per-file tracking
35
- fileEditCount = new Map();
36
- static FILE_EDIT_IDLE_MS = 30 * 60_000;
37
- /**
38
- * Record a tool call and return any warnings triggered.
39
- * Called from tool_result handler.
40
- */
41
- recordToolCall(toolName, filePath) {
42
- const warnings = [];
43
- const now = Date.now();
44
- // Track consecutive identical tool+file pairs (thrashing).
45
- // Editing different files in sequence is normal agent behaviour — only flag
46
- // when the same tool is called on the same file N times without making
47
- // progress on anything else.
48
- const normalizedPath = filePath ? normalizeMapKey(filePath) : null;
49
- if (toolName === this.lastToolName &&
50
- normalizedPath === this.lastToolFilePath &&
51
- now - this.lastToolTimestamp < THRASH_TIMEOUT_MS) {
52
- this.consecutiveCount++;
53
- }
54
- else {
55
- this.consecutiveCount = 1;
56
- }
57
- this.lastToolName = toolName;
58
- this.lastToolFilePath = normalizedPath;
59
- this.lastToolTimestamp = now;
60
- // Check for thrashing
61
- if (this.consecutiveCount === THRASH_THRESHOLD) {
62
- const fileLabel = filePath ? ` on \`${filePath}\`` : "";
63
- warnings.push({
64
- type: "thrashing",
65
- message: `🔴 THRASHING — ${THRASH_THRESHOLD} consecutive \`${toolName}\`${fileLabel} calls with no progress. Consider fixing the root cause instead of re-running.`,
66
- severity: "error",
67
- details: {
68
- toolName,
69
- filePath,
70
- callCount: this.consecutiveCount,
71
- },
72
- });
73
- }
74
- // Check for blind writes
75
- if (isMutatingToolName(toolName)) {
76
- const recentWindow = this.toolHistory.slice(-BLIND_WRITE_WINDOW);
77
- // A read in the window proves file knowledge; so does a same-session
78
- // write/edit of THIS path — the agent authored the content, so the
79
- // write-then-edit loop on a self-authored file is not a blind write.
80
- const hasRecentRead = recentWindow.some((r) => READ_OPS.has(r.toolName) ||
81
- (isMutatingToolName(r.toolName) &&
82
- r.filePath !== undefined &&
83
- normalizedPath !== null &&
84
- normalizeMapKey(r.filePath) === normalizedPath));
85
- if (!hasRecentRead && recentWindow.length > 0) {
86
- // Count how many writes in the window without reads
87
- const writesWithoutRead = recentWindow.filter((r) => isMutatingToolName(r.toolName)).length;
88
- if (writesWithoutRead >= 2) {
89
- warnings.push({
90
- type: "blind-write",
91
- message: `⚠ BLIND WRITE — editing \`${filePath ?? "file"}\` without reading in the last ${BLIND_WRITE_WINDOW} tool calls. Read the file first to avoid assumptions.`,
92
- severity: "warning",
93
- details: {
94
- filePath,
95
- windowSize: recentWindow.length,
96
- },
97
- });
98
- }
99
- }
100
- // Track edits per file
101
- if (filePath) {
102
- const key = normalizeMapKey(filePath);
103
- this.fileEditCount.set(key, {
104
- count: (this.fileEditCount.get(key)?.count ?? 0) + 1,
105
- lastUsedAt: now,
106
- });
107
- for (const [pathKey, entry] of this.fileEditCount) {
108
- if (now - entry.lastUsedAt > AgentBehaviorClient.FILE_EDIT_IDLE_MS) {
109
- this.fileEditCount.delete(pathKey);
110
- }
111
- }
112
- }
113
- }
114
- // Add to history (keep last 50 entries)
115
- this.toolHistory.push({ toolName, filePath, timestamp: now });
116
- if (this.toolHistory.length > 50) {
117
- this.toolHistory = this.toolHistory.slice(-50);
118
- }
119
- return warnings;
120
- }
121
- /**
122
- * Format warnings for LLM consumption.
123
- */
124
- formatWarnings(warnings) {
125
- if (warnings.length === 0)
126
- return "";
127
- return warnings.map((w) => w.message).join("\n");
128
- }
129
- /**
130
- * Get edit count for a file in this session.
131
- */
132
- getEditCount(filePath) {
133
- return this.fileEditCount.get(normalizeMapKey(filePath))?.count ?? 0;
134
- }
135
- /**
136
- * Reset state (e.g., on session start).
137
- */
138
- reset() {
139
- this.toolHistory = [];
140
- this.consecutiveCount = 0;
141
- this.lastToolName = null;
142
- this.lastToolTimestamp = 0;
143
- this.fileEditCount.clear();
144
- }
145
- }
146
- /** Process-wide behaviour history, independent of analyzer bootstrap residency. */
147
- export const agentBehaviorClient = new AgentBehaviorClient();
@@ -1,325 +0,0 @@
1
- import { logLatency } from "./latency-logger.js";
2
- import { normalizeMapKey } from "./path-utils.js";
3
- const BUS_FILES_TOUCHED_EVENT = "pilens:files:touched";
4
- const MAX_NAMES_SHOWN = 5;
5
- // Module-level accumulator: one process/session, so a plain map keyed via
6
- // normalizeMapKey (house style — every map/set key in this module MUST go
7
- // through it; a hand-rolled replace() is the exact trap that cost two red CI
8
- // rounds on #458's reconcile tests, PR #491) is sufficient. Cleared ONLY
9
- // inside consumeAgentNudge() (i.e. only at actual injection into a `context`
10
- // call) — deliberately NOT tied to turn_start/agent_end/agent_settled, so
11
- // entries accumulated during run A's turn_end survive until run B's first
12
- // `context` call in the same session (the cross-run `git status` case).
13
- const _touched = new Map();
14
- // Count of bus-reported paths dropped by the relevance filter (file never
15
- // read/edited this session) since the last consume — drained alongside the
16
- // accumulator so the `agent_nudge` phase can report how much the filter
17
- // actually suppresses, which is the metric that validates (or indicts) the
18
- // "only nudge for files the session saw" rule.
19
- let _relevanceFilteredCount = 0;
20
- /** Test-only: clear accumulator state between test files/cases. */
21
- export function _resetAgentNudgeForTests() {
22
- _touched.clear();
23
- _relevanceFilteredCount = 0;
24
- _enabledCache = undefined;
25
- }
26
- // --- Kill switch (lazy, memoized — house style per clients/quiet-window.ts) ---
27
- let _enabledCache;
28
- /** `PI_LENS_AGENT_NUDGE=0` disables accumulation and injection outright. */
29
- export function isAgentNudgeEnabled() {
30
- if (_enabledCache === undefined) {
31
- _enabledCache = process.env.PI_LENS_AGENT_NUDGE !== "0";
32
- }
33
- return _enabledCache;
34
- }
35
- function isValidPayload(data) {
36
- if (!data || typeof data !== "object")
37
- return false;
38
- const p = data;
39
- return (p.v === 1 &&
40
- p.source === "pi-lens" &&
41
- (p.reason === "autofix" || p.reason === "format") &&
42
- Array.isArray(p.paths));
43
- }
44
- /**
45
- * Record a `pilens:files:touched` event into the accumulator, filtered to
46
- * files the session has actually read or edited (read-guard is the source of
47
- * truth — `getReadHistory`/`getEditHistory` both key internally via
48
- * `normalizeFilePath`, so either separator form on the incoming bus payload
49
- * or the guard's stored records resolves to the same record regardless of
50
- * which form was recorded first).
51
- */
52
- function recordTouchedEvent(payload, getReadGuard) {
53
- const readGuard = getReadGuard();
54
- if (!readGuard)
55
- return;
56
- for (const rawPath of payload.paths) {
57
- const isRelevant = readGuard.getReadHistory(rawPath).length > 0 ||
58
- readGuard.getEditHistory(rawPath).length > 0;
59
- if (!isRelevant) {
60
- _relevanceFilteredCount++;
61
- continue;
62
- }
63
- const mapKey = normalizeMapKey(rawPath);
64
- const existing = _touched.get(mapKey);
65
- if (existing) {
66
- existing.reasons.add(payload.reason);
67
- // "local" is sticky — see AccumulatedFileOrigin doc. A file already
68
- // recorded via the cross-process feed, now also reported by this
69
- // session's own bus, upgrades to "local".
70
- existing.origin = "local";
71
- // #1464: a fresh touch invalidates any content already delivered for
72
- // this path (the default deferred format at agent_end, a cascade
73
- // autofix) — those bytes no longer describe the file.
74
- existing.contentDelivered = false;
75
- }
76
- else {
77
- _touched.set(mapKey, {
78
- displayPath: rawPath,
79
- reasons: new Set([payload.reason]),
80
- origin: "local",
81
- contentDelivered: false,
82
- });
83
- }
84
- }
85
- }
86
- /**
87
- * Feed entries read from the cross-process `recent-touches.json` record
88
- * (#492, clients/recent-touches.ts) into the SAME accumulator #485 uses for
89
- * in-process bus events — one accumulator, one `consumeAgentNudge` call, one
90
- * batched context message regardless of how many files came from which
91
- * channel.
92
- *
93
- * Relevance filtering differs by call site (#492 point 6) and is therefore
94
- * the CALLER's responsibility, not this function's:
95
- * - parent at turn_start: read-guard history FIRST (a parent usually has
96
- * one), falling back to recency-only for files it hasn't read (a parent
97
- * about to `git commit` needs attribution even for unread files);
98
- * - child at session_start: recency + file-existence only (no read
99
- * history exists yet this early).
100
- * `readCrossProcessTouchesForTurnStart` / `...ForSessionStart` in
101
- * recent-touches.ts already apply their own recency/existence/self-pid
102
- * filtering before entries reach here — this function does not re-derive
103
- * relevance, it only merges into the accumulator and marks provenance.
104
- *
105
- * Self-exclusion (an entry this process itself published never nudges
106
- * itself) and path+ts dedup across repeated reads of the record are both
107
- * handled upstream in recent-touches.ts (pid filter + last-consumed cursor),
108
- * so entries reaching this function are already the "new, foreign" set.
109
- */
110
- export function recordCrossProcessTouches(entries) {
111
- if (!isAgentNudgeEnabled())
112
- return;
113
- for (const entry of entries) {
114
- const mapKey = normalizeMapKey(entry.path);
115
- const existing = _touched.get(mapKey);
116
- if (existing) {
117
- existing.reasons.add(entry.reason);
118
- // "local" is sticky (see AccumulatedFileOrigin) — never downgrade an
119
- // already-local entry back to cross-process.
120
- // #1464: a foreign process touching this file invalidates whatever
121
- // content this session's write path already delivered for it.
122
- existing.contentDelivered = false;
123
- }
124
- else {
125
- _touched.set(mapKey, {
126
- displayPath: entry.path,
127
- reasons: new Set([entry.reason]),
128
- origin: "cross-process",
129
- contentDelivered: false,
130
- });
131
- }
132
- }
133
- }
134
- /**
135
- * Record the write path's authoritative-content attachment outcome for one
136
- * path (#1464).
137
- *
138
- * `attached` is the SAME boolean that drove the attachment in
139
- * `handleToolResult` (clients/runtime-tool-result.ts) — this module never
140
- * re-derives it from config, byte counts, or the aggregate budget. `true`
141
- * means the post-fix bytes went out in the write's own tool result and the
142
- * agent already holds them, so "re-read before editing" is noise. `false` is
143
- * the size cap and the per-command aggregate budget degrading an attachment
144
- * to a re-read warning: there the nudge is the whole signal, and calling this
145
- * with `false` re-arms a path an earlier per-file decision had suppressed
146
- * (the bash multi-file case, where the outer budget loop overrides the inner
147
- * per-file "attached").
148
- *
149
- * Marks an EXISTING accumulator entry only. `publishFilesTouched` fires
150
- * synchronously inside the `runPipeline` call this decision belongs to (pi's
151
- * event bus is a plain `EventEmitter`), so the entry is already there for any
152
- * path the relevance filter admitted; a path with no entry has nothing to
153
- * suppress. Deferred-edit autofix at `agent_end` never reaches here — it
154
- * attaches nothing, so it keeps nudging.
155
- */
156
- export function noteAuthoritativeContentAttachment(filePath, attached) {
157
- const entry = _touched.get(normalizeMapKey(filePath));
158
- if (entry)
159
- entry.contentDelivered = attached;
160
- }
161
- /**
162
- * Subscribe to `pilens:files:touched` on pi's shared event bus. Called once
163
- * at extension factory time from index.ts, mirroring `wireBusEmitter`'s
164
- * placement (clients/bus-publish.ts). No-ops silently when `pi.events` or
165
- * `.on` is unavailable (older pi host) — never throws.
166
- */
167
- export function wireAgentNudgeSubscriber(args) {
168
- const { events, getReadGuard, dbg } = args;
169
- if (!events?.on)
170
- return;
171
- try {
172
- events.on(BUS_FILES_TOUCHED_EVENT, (data) => {
173
- if (!isAgentNudgeEnabled())
174
- return;
175
- if (!isValidPayload(data))
176
- return;
177
- try {
178
- recordTouchedEvent(data, getReadGuard);
179
- }
180
- catch (err) {
181
- dbg?.(`agent-nudge: failed to record touched event: ${err}`);
182
- }
183
- });
184
- }
185
- catch (err) {
186
- dbg?.(`agent-nudge: subscribe failed (older pi host?): ${err}`);
187
- }
188
- }
189
- /**
190
- * Consume the accumulated touched-file set and produce (at most) one context
191
- * message, e.g.:
192
- * "pi-lens: 2 file(s) were autoformatted after your last turn: a.ts, b.ts —
193
- * working-tree changes to these are expected; re-read before editing."
194
- * The provenance framing ("pi-lens ... expected") matters: the primary pain
195
- * case is an agent running `git status` (often at the START of a brand-new
196
- * run/session, not just mid-run) and burning turns investigating diffs it
197
- * did not knowingly make. Naming pi-lens as the source lets the agent act
198
- * (re-read, proceed) instead of investigating.
199
- *
200
- * #492: attribution is three-way by the batch's origin mix (see
201
- * AccumulatedFileOrigin) — still ONE message total (never split local vs.
202
- * cross-process into two separate injections; the agent gets one coherent
203
- * picture of everything unexplained in the working tree), but the wording
204
- * must never assign a LOCAL file to another instance:
205
- * - all local → "after your last turn" (the original #485 wording,
206
- * unchanged — verified by the pre-existing #485
207
- * tests);
208
- * - all cross-process → "by an automatic run outside your turn";
209
- * - mixed → "after your last turn (N of them by an automatic
210
- * run outside it)" — the base framing stays local
211
- * and the cross-process portion is counted out
212
- * precisely, so no local file is ever misattributed.
213
- *
214
- * The cross-process wording names the ACTION, not the process identity. It
215
- * used to read "by another pi-lens instance (e.g. a subagent's)", which sent
216
- * agents investigating what other instance was running — the exact behavior
217
- * this nudge exists to prevent. Which process formatted the file is an
218
- * implementation detail the reading agent cannot act on; that it was an
219
- * automatic run outside their turn is the whole actionable content. The
220
- * origin split stays exact in the telemetry for human debugging.
221
- *
222
- * Clears the accumulator ONLY here, on actual injection — never on
223
- * agent_end/agent_settled/turn_start. Files formatted at the last turn_end of
224
- * a PREVIOUS run must still nudge at the first turn of the NEXT run in the
225
- * same session: this function is invoked from the `context` extension event
226
- * (index.ts), which fires before every provider/LLM call — including the
227
- * very first call of a fresh `agent_start` — so the accumulator surviving
228
- * across run boundaries is exactly what makes that cross-run delivery work.
229
- * Empty accumulator ⇒ returns undefined ⇒ zero bytes injected.
230
- *
231
- * #1464: paths whose post-fix content the write path already attached to its
232
- * OWN tool result are dropped from the batch here (see
233
- * `noteAuthoritativeContentAttachment`) — the agent holds those bytes, so
234
- * "re-read before editing" would spend context to re-fetch what it has. A
235
- * batch that is ENTIRELY such paths injects nothing.
236
- */
237
- export function consumeAgentNudge(dbg) {
238
- const drained = Array.from(_touched.values());
239
- _touched.clear();
240
- const filesFiltered = _relevanceFilteredCount;
241
- _relevanceFilteredCount = 0;
242
- if (!isAgentNudgeEnabled())
243
- return undefined;
244
- if (drained.length === 0)
245
- return undefined;
246
- try {
247
- // #1464: a write whose post-fix bytes were attached to its own tool
248
- // result already told the agent everything this nudge would. Drop those
249
- // paths from the message but keep counting them, so over-suppression is
250
- // visible in telemetry instead of only in the absence of complaints.
251
- const entries = drained.filter((e) => !e.contentDelivered);
252
- const filesContentDelivered = drained.length - entries.length;
253
- const filesTotal = entries.length;
254
- const shown = entries.slice(0, MAX_NAMES_SHOWN);
255
- const remaining = filesTotal - shown.length;
256
- // Determine a single verb covering every reason seen across all
257
- // accumulated files (not just the shown subset) — most turns will have
258
- // a single uniform reason, so keep that common case terse; a mix of
259
- // autofix + format across the batch falls back to a combined verb.
260
- const allReasons = new Set();
261
- for (const e of entries) {
262
- for (const r of e.reasons)
263
- allReasons.add(r);
264
- }
265
- const verbLabel = allReasons.size > 1
266
- ? "autofixed/reformatted"
267
- : allReasons.has("format")
268
- ? "reformatted"
269
- : "autofixed";
270
- const names = shown.map((e) => e.displayPath);
271
- const nameList = remaining > 0
272
- ? `${names.join(", ")}, and ${remaining} more`
273
- : names.join(", ");
274
- const crossProcessCount = entries.filter((e) => e.origin === "cross-process").length;
275
- const localCount = filesTotal - crossProcessCount;
276
- logLatency({
277
- type: "phase",
278
- filePath: "<pi-lens>",
279
- phase: "agent_nudge",
280
- durationMs: 0,
281
- metadata: {
282
- filesTotal,
283
- filesShown: shown.length,
284
- // Relevance-filter drops since the last consume (files the session
285
- // never read/edited) — NOT the display overflow, which is
286
- // filesTotal - filesShown.
287
- filesFiltered,
288
- // #1464: drops because the write's own tool result already carried
289
- // the post-fix bytes. A third, distinct count: these paths passed
290
- // the relevance filter and were accumulated, then suppressed here.
291
- filesContentDelivered,
292
- reasonMix: Array.from(allReasons),
293
- // #492: origin mix so cross-process pickup rate is observable
294
- // alongside the existing relevance-filter metric.
295
- originLocal: localCount,
296
- originCrossProcess: crossProcessCount,
297
- },
298
- });
299
- // Everything drained was delivered in a write's own tool result — the
300
- // row above records that it happened, and zero bytes get injected.
301
- if (filesTotal === 0)
302
- return undefined;
303
- // Three-way attribution (see the function doc): never assign a local
304
- // file to another instance — a mixed batch keeps the local base framing
305
- // and calls out the cross-process portion by exact count.
306
- const attribution = localCount === 0
307
- ? "by an automatic run outside your turn"
308
- : crossProcessCount === 0
309
- ? "after your last turn"
310
- : `after your last turn (${crossProcessCount} of them by an automatic run outside it)`;
311
- const message = `pi-lens: ${filesTotal} file(s) were ${verbLabel} ${attribution}: ${nameList} — working-tree changes to these are expected; re-read before editing.`;
312
- return {
313
- messages: [
314
- {
315
- role: "user",
316
- content: `[pi-lens automated context — not a user request] ${message}`,
317
- },
318
- ],
319
- };
320
- }
321
- catch (err) {
322
- dbg?.(`agent-nudge: consume failed: ${err}`);
323
- return undefined;
324
- }
325
- }
@@ -1 +0,0 @@
1
- export {};