@herbertgao/pi-extensions 2026.10.1 → 2026.10.3

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 (934) hide show
  1. package/README.md +14 -17
  2. package/THIRD_PARTY_NOTICES.md +2 -2
  3. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-audit.md +2 -2
  4. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-debt.md +2 -2
  5. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-gain.md +1 -1
  6. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-help.md +1 -1
  7. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-review.md +2 -2
  8. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail.md +1 -1
  9. package/node_modules/@dietrichgebert/ponytail/.qoder/rules/ponytail.md +21 -21
  10. package/node_modules/@dietrichgebert/ponytail/.qoder-plugin/plugin.json +1 -1
  11. package/node_modules/@dietrichgebert/ponytail/AGENTS.md +21 -21
  12. package/node_modules/@dietrichgebert/ponytail/README.md +68 -72
  13. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-activate.js +7 -0
  14. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-instructions.js +30 -30
  15. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-map.js +103 -0
  16. package/node_modules/@dietrichgebert/ponytail/package.json +2 -2
  17. package/node_modules/@dietrichgebert/ponytail/skills/ponytail/SKILL.md +33 -101
  18. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-audit/SKILL.md +89 -32
  19. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-debt/SKILL.md +13 -12
  20. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-gain/SKILL.md +17 -16
  21. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-help/SKILL.md +9 -10
  22. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-review/SKILL.md +96 -57
  23. package/node_modules/{remote-pi → @herbertgao/pi-agency}/LICENSE +1 -1
  24. package/node_modules/@herbertgao/pi-agency/README.md +40 -0
  25. package/node_modules/@herbertgao/pi-agency/package.json +53 -0
  26. package/node_modules/@herbertgao/pi-agency/src/index.ts +441 -0
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +12 -12
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +30 -6
  29. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +15 -9
  30. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +27 -9
  31. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +4 -1
  32. package/node_modules/@herbertgao/pi-cc-extensions/package.json +2 -2
  33. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +8 -0
  34. package/node_modules/@herbertgao/pi-subagents/README.md +1 -1
  35. package/node_modules/@herbertgao/pi-subagents/package.json +4 -5
  36. package/node_modules/@herbertgao/pi-subagents/src/index.ts +1 -1
  37. package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +1 -1
  38. package/node_modules/@herbertgao/pi-subagents/src/mention-clone.ts +48 -72
  39. package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +1 -1
  40. package/node_modules/@herbertgao/pi-subagents/src/output-file.ts +15 -6
  41. package/node_modules/@herbertgao/pi-subagents/src/workflow/collisions.ts +4 -1
  42. package/node_modules/@herbertgao/pi-subagents/src/workflow/json-schema.ts +9 -8
  43. package/node_modules/@narumitw/pi-caffeinate/dist/index.ts +6 -1
  44. package/node_modules/@narumitw/pi-caffeinate/dist/index.ts.map +2 -2
  45. package/node_modules/@narumitw/pi-caffeinate/package.json +3 -3
  46. package/node_modules/@narumitw/pi-caffeinate/src/dbus-inhibit.ts +13 -1
  47. package/node_modules/@tifan/pi-mermaid-open/package.json +5 -1
  48. package/node_modules/@tifan/pi-mermaid-open/src/index.ts +26 -9
  49. package/node_modules/@tifan/pi-recap/package.json +1 -1
  50. package/node_modules/@tifan/pi-recap/src/index.ts +104 -20
  51. package/node_modules/@tifan/pi-recap/src/models.ts +46 -4
  52. package/node_modules/pi-antigravity/README.md +23 -2
  53. package/node_modules/pi-antigravity/package.json +5 -3
  54. package/node_modules/pi-antigravity/src/diagnostics/diagnostics.ts +3 -2
  55. package/node_modules/pi-antigravity/src/features/generate-image.ts +72 -0
  56. package/node_modules/pi-antigravity/src/features/google-search.ts +71 -0
  57. package/node_modules/pi-antigravity/src/image/image.ts +86 -47
  58. package/node_modules/pi-antigravity/src/image/native.ts +69 -0
  59. package/node_modules/pi-antigravity/src/index.ts +52 -137
  60. package/node_modules/pi-antigravity/src/search/search.ts +130 -31
  61. package/node_modules/pi-antigravity/src/stream/stream.ts +162 -113
  62. package/node_modules/pi-antigravity/src/types/enums.ts +1 -0
  63. package/node_modules/pi-antigravity/src/types/types.ts +1 -1
  64. package/node_modules/pi-antigravity/src/utils/security.ts +47 -1
  65. package/node_modules/pi-antigravity/src/utils/util.ts +38 -6
  66. package/node_modules/pi-lens/CHANGELOG.md +1159 -0
  67. package/node_modules/pi-lens/README.md +116 -25
  68. package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +6 -2
  69. package/node_modules/pi-lens/dist/chunk-2BEMIWEW.js +51 -0
  70. package/node_modules/pi-lens/dist/chunk-2EECBNC5.js +89 -0
  71. package/node_modules/pi-lens/dist/chunk-2FQ62SPM.js +83 -0
  72. package/node_modules/pi-lens/dist/chunk-2UMYMRI3.js +118 -0
  73. package/node_modules/pi-lens/dist/chunk-34OCDWOS.js +48 -0
  74. package/node_modules/pi-lens/dist/chunk-3FERWMCH.js +144 -0
  75. package/node_modules/pi-lens/dist/chunk-3JL6IFD7.js +97 -0
  76. package/node_modules/pi-lens/dist/chunk-3JSEWUWI.js +327 -0
  77. package/node_modules/pi-lens/dist/chunk-3MED75HT.js +37 -0
  78. package/node_modules/pi-lens/dist/chunk-3MRXIJ6I.js +79 -0
  79. package/node_modules/pi-lens/dist/chunk-3P4PF2BX.js +2250 -0
  80. package/node_modules/pi-lens/dist/chunk-3PNFWVHT.js +201 -0
  81. package/node_modules/pi-lens/dist/chunk-3TTPKMEF.js +162 -0
  82. package/node_modules/pi-lens/dist/chunk-5JHXUETW.js +326 -0
  83. package/node_modules/pi-lens/dist/chunk-5W3R6LFT.js +24 -0
  84. package/node_modules/pi-lens/dist/chunk-64LU2OVH.js +341 -0
  85. package/node_modules/pi-lens/dist/chunk-6B5I6ICN.js +44 -0
  86. package/node_modules/pi-lens/dist/chunk-6P54TMWL.js +274 -0
  87. package/node_modules/pi-lens/dist/chunk-6UYA642J.js +145 -0
  88. package/node_modules/pi-lens/dist/chunk-6XX5HCLK.js +398 -0
  89. package/node_modules/pi-lens/dist/chunk-7AXO3ZDF.js +30 -0
  90. package/node_modules/pi-lens/dist/chunk-7BX5DWSA.js +1907 -0
  91. package/node_modules/pi-lens/dist/chunk-7ELY2CSM.js +902 -0
  92. package/node_modules/pi-lens/dist/chunk-7M4T5N3V.js +38 -0
  93. package/node_modules/pi-lens/dist/chunk-7U2IDNXN.js +37 -0
  94. package/node_modules/pi-lens/dist/chunk-ABBOA7UD.js +157 -0
  95. package/node_modules/pi-lens/dist/chunk-AFZYMAIV.js +756 -0
  96. package/node_modules/pi-lens/dist/chunk-ALQRYH6O.js +112 -0
  97. package/node_modules/pi-lens/dist/chunk-AXKPQ6ZI.js +1610 -0
  98. package/node_modules/pi-lens/dist/chunk-BHWHXMQ2.js +62 -0
  99. package/node_modules/pi-lens/dist/chunk-BJF25SUG.js +22 -0
  100. package/node_modules/pi-lens/dist/chunk-BNKLYOOO.js +18 -0
  101. package/node_modules/pi-lens/dist/chunk-BW5KFIQC.js +59 -0
  102. package/node_modules/pi-lens/dist/chunk-CBD2B5CP.js +599 -0
  103. package/node_modules/pi-lens/dist/chunk-CFYISHUW.js +42 -0
  104. package/node_modules/pi-lens/dist/chunk-CMU4RMJB.js +30 -0
  105. package/node_modules/pi-lens/dist/chunk-CULQYFLU.js +14 -0
  106. package/node_modules/pi-lens/dist/chunk-D65GOCJB.js +289 -0
  107. package/node_modules/pi-lens/dist/chunk-D6YF5HKX.js +59 -0
  108. package/node_modules/pi-lens/dist/chunk-DMS52BEP.js +342 -0
  109. package/node_modules/pi-lens/dist/chunk-ELVWJYRV.js +211 -0
  110. package/node_modules/pi-lens/dist/chunk-EUT3B22Y.js +27 -0
  111. package/node_modules/pi-lens/dist/chunk-F5VLZHUW.js +146 -0
  112. package/node_modules/pi-lens/dist/chunk-FC4RP4I2.js +12 -0
  113. package/node_modules/pi-lens/dist/chunk-FGALODG3.js +55 -0
  114. package/node_modules/pi-lens/dist/chunk-G3RLJYA2.js +2358 -0
  115. package/node_modules/pi-lens/dist/chunk-GAYGGICG.js +32 -0
  116. package/node_modules/pi-lens/dist/chunk-H2W2AXD3.js +419 -0
  117. package/node_modules/pi-lens/dist/chunk-H5EV3VMF.js +114 -0
  118. package/node_modules/pi-lens/dist/chunk-HREZQCT3.js +106 -0
  119. package/node_modules/pi-lens/dist/chunk-HSIRMK2D.js +517 -0
  120. package/node_modules/pi-lens/dist/chunk-IMSQR4WO.js +184 -0
  121. package/node_modules/pi-lens/dist/chunk-IQZXOZ7S.js +4816 -0
  122. package/node_modules/pi-lens/dist/chunk-IR6XFA5P.js +37 -0
  123. package/node_modules/pi-lens/dist/chunk-IUKPRZER.js +78 -0
  124. package/node_modules/pi-lens/dist/chunk-IUR76K6A.js +262 -0
  125. package/node_modules/pi-lens/dist/chunk-J3FZR3YY.js +98 -0
  126. package/node_modules/pi-lens/dist/chunk-J6DFZDFA.js +562 -0
  127. package/node_modules/pi-lens/dist/chunk-J7WJZ6W7.js +50 -0
  128. package/node_modules/pi-lens/dist/chunk-JONGANYH.js +202 -0
  129. package/node_modules/pi-lens/dist/chunk-KJCWXUUS.js +425 -0
  130. package/node_modules/pi-lens/dist/chunk-KJN4IOEJ.js +17 -0
  131. package/node_modules/pi-lens/dist/chunk-KMGPUKFD.js +25 -0
  132. package/node_modules/pi-lens/dist/chunk-LD7WFTRX.js +4533 -0
  133. package/node_modules/pi-lens/dist/chunk-LJDODBBZ.js +78 -0
  134. package/node_modules/pi-lens/dist/chunk-LNOMA3MP.js +169 -0
  135. package/node_modules/pi-lens/dist/chunk-MGIWSROG.js +2334 -0
  136. package/node_modules/pi-lens/dist/chunk-MQA2YBAH.js +308 -0
  137. package/node_modules/pi-lens/dist/chunk-MTDRLSI7.js +21720 -0
  138. package/node_modules/pi-lens/dist/chunk-N2IRDBZI.js +2355 -0
  139. package/node_modules/pi-lens/dist/chunk-N77WFUL7.js +50 -0
  140. package/node_modules/pi-lens/dist/chunk-N7YNJE5R.js +466 -0
  141. package/node_modules/pi-lens/dist/chunk-NABLC7W3.js +148 -0
  142. package/node_modules/pi-lens/dist/chunk-NFXP47RV.js +999 -0
  143. package/node_modules/pi-lens/dist/chunk-NJF2X5XF.js +45 -0
  144. package/node_modules/pi-lens/dist/chunk-NXL4FFQQ.js +47 -0
  145. package/node_modules/pi-lens/dist/chunk-O7HZX7CA.js +309 -0
  146. package/node_modules/pi-lens/dist/chunk-OC7LYAU5.js +708 -0
  147. package/node_modules/pi-lens/dist/chunk-OEX24ECI.js +348 -0
  148. package/node_modules/pi-lens/dist/chunk-OYOB3ZFG.js +78 -0
  149. package/node_modules/pi-lens/dist/chunk-OYTMZXRF.js +41 -0
  150. package/node_modules/pi-lens/dist/chunk-OZJINN4O.js +84 -0
  151. package/node_modules/pi-lens/dist/chunk-PCHDGUKT.js +23 -0
  152. package/node_modules/pi-lens/dist/chunk-QOZXJ4NA.js +3364 -0
  153. package/node_modules/pi-lens/dist/chunk-QYF5S6P6.js +45 -0
  154. package/node_modules/pi-lens/dist/chunk-RJFED73B.js +79 -0
  155. package/node_modules/pi-lens/dist/chunk-RTQNRM5X.js +27 -0
  156. package/node_modules/pi-lens/dist/chunk-S6AMWKPC.js +189 -0
  157. package/node_modules/pi-lens/dist/chunk-T4QZ6FEH.js +308 -0
  158. package/node_modules/pi-lens/dist/chunk-T54VJRAD.js +5456 -0
  159. package/node_modules/pi-lens/dist/chunk-TA5L5KWQ.js +167 -0
  160. package/node_modules/pi-lens/dist/chunk-TQFBZVCG.js +27 -0
  161. package/node_modules/pi-lens/dist/chunk-U52SAGRM.js +62 -0
  162. package/node_modules/pi-lens/dist/chunk-UEAHAMEI.js +5814 -0
  163. package/node_modules/pi-lens/dist/chunk-UGSMCQ4D.js +327 -0
  164. package/node_modules/pi-lens/dist/chunk-UOPVJQ4N.js +103 -0
  165. package/node_modules/pi-lens/dist/chunk-USHG4DLH.js +459 -0
  166. package/node_modules/pi-lens/dist/chunk-UXVNL3D7.js +23 -0
  167. package/node_modules/pi-lens/dist/chunk-V5MEBST3.js +4139 -0
  168. package/node_modules/pi-lens/dist/chunk-VGEVL5EQ.js +29 -0
  169. package/node_modules/pi-lens/dist/chunk-VPWKF3GN.js +87 -0
  170. package/node_modules/pi-lens/dist/chunk-VSMJK3ZJ.js +1250 -0
  171. package/node_modules/pi-lens/dist/chunk-VYKKMYVT.js +560 -0
  172. package/node_modules/pi-lens/dist/chunk-VZHJS6DR.js +442 -0
  173. package/node_modules/pi-lens/dist/chunk-WATC3IQR.js +213 -0
  174. package/node_modules/pi-lens/dist/chunk-WPE5FPGR.js +54 -0
  175. package/node_modules/pi-lens/dist/chunk-WSEWKCXU.js +188 -0
  176. package/node_modules/pi-lens/dist/chunk-WW5BLB74.js +659 -0
  177. package/node_modules/pi-lens/dist/chunk-XGUL4SLQ.js +406 -0
  178. package/node_modules/pi-lens/dist/chunk-XHSCVSOL.js +170 -0
  179. package/node_modules/pi-lens/dist/chunk-XIMYZ3JA.js +27 -0
  180. package/node_modules/pi-lens/dist/chunk-YLN4K6WD.js +385 -0
  181. package/node_modules/pi-lens/dist/chunk-Z3CCVDUB.js +76 -0
  182. package/node_modules/pi-lens/dist/chunk-Z54ZSOBZ.js +61 -0
  183. package/node_modules/pi-lens/dist/chunk-Z6BB4JLQ.js +478 -0
  184. package/node_modules/pi-lens/dist/chunk-Z7QQA2KT.js +27 -0
  185. package/node_modules/pi-lens/dist/chunk-ZETYB3XG.js +2626 -0
  186. package/node_modules/pi-lens/dist/chunk-ZMOMPX2Z.js +87 -0
  187. package/node_modules/pi-lens/dist/chunk-ZOEYVXSV.js +149 -0
  188. package/node_modules/pi-lens/dist/chunk-ZZUFZUQZ.js +12120 -0
  189. package/node_modules/pi-lens/dist/index.js +39712 -29876
  190. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +186 -232
  191. package/node_modules/pi-lens/dist/mcp/cli.js +137 -98
  192. package/node_modules/pi-lens/dist/mcp/server.js +22688 -1573
  193. package/node_modules/pi-lens/dist/mcp/worker.js +97 -38
  194. package/node_modules/pi-lens/dist/probes/installer.js +135 -0
  195. package/node_modules/pi-lens/dist/workers/project-snapshot-persist-worker.js +22 -0
  196. package/node_modules/pi-lens/dist/workers/review-graph-persist-worker.js +15 -0
  197. package/node_modules/pi-lens/docs/agent-guide.md +13 -4
  198. package/node_modules/pi-lens/docs/agent-tools.md +42 -0
  199. package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +5 -4
  200. package/node_modules/pi-lens/docs/configuration.md +28 -2
  201. package/node_modules/pi-lens/docs/custom-rules.md +25 -2
  202. package/node_modules/pi-lens/docs/environment-variables.md +86 -8
  203. package/node_modules/pi-lens/docs/features.md +45 -5
  204. package/node_modules/pi-lens/docs/globalconfig.md +2 -1
  205. package/node_modules/pi-lens/docs/io-bridge-v2-migration.md +94 -0
  206. package/node_modules/pi-lens/docs/lsp-capability-matrix.md +37 -4
  207. package/node_modules/pi-lens/docs/lsp-idle-eviction.md +124 -0
  208. package/node_modules/pi-lens/docs/mcp.md +21 -5
  209. package/node_modules/pi-lens/docs/merge-queue-rollout.md +77 -0
  210. package/node_modules/pi-lens/docs/pi-lens-fixer.md +160 -88
  211. package/node_modules/pi-lens/docs/pi-lens-investigator.md +74 -26
  212. package/node_modules/pi-lens/docs/pi-lens-merge-policy.md +736 -0
  213. package/node_modules/pi-lens/docs/pi-lens-monitor.md +75 -7
  214. package/node_modules/pi-lens/docs/pi-lens-retro.md +6 -4
  215. package/node_modules/pi-lens/docs/pi-lens-reviewer.md +189 -48
  216. package/node_modules/pi-lens/docs/pi-lens-subagent.md +246 -45
  217. package/node_modules/pi-lens/docs/pi-lens-warden.md +18 -7
  218. package/node_modules/pi-lens/docs/public-api-stability.md +55 -0
  219. package/node_modules/pi-lens/docs/release-qa-baseline.md +84 -17
  220. package/node_modules/pi-lens/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
  221. package/node_modules/pi-lens/docs/schema/pi-lens-config-v1.json +530 -0
  222. package/node_modules/pi-lens/docs/servercapabilities.md +56 -49
  223. package/node_modules/pi-lens/docs/settings.md +1 -0
  224. package/node_modules/pi-lens/docs/usage.md +5 -1
  225. package/node_modules/pi-lens/docs/word-index.md +6 -0
  226. package/node_modules/pi-lens/grammars/tree-sitter-bash.wasm +0 -0
  227. package/node_modules/pi-lens/grammars/tree-sitter-bash.wasm.json +3 -3
  228. package/node_modules/pi-lens/package.json +18 -6
  229. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
  230. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-identity-operator-on-literals-test.yml +12 -2
  231. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/throw-new-error-js-test.yml +2 -0
  232. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/throw-new-error-test.yml +2 -0
  233. package/node_modules/pi-lens/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
  234. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-identity-operator-on-literals.yml +20 -12
  235. package/node_modules/pi-lens/rules/ast-grep-rules/rules/throw-new-error-js.yml +2 -2
  236. package/node_modules/pi-lens/rules/ast-grep-rules/rules/throw-new-error.yml +2 -2
  237. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +1275 -62
  238. package/node_modules/pi-lens/scripts/download-grammars.js +5 -0
  239. package/node_modules/pi-lens/scripts/grammars.lock.json +6 -1
  240. package/node_modules/pi-lens/scripts/install-selftest.mjs +33 -34
  241. package/node_modules/pi-lens/scripts/lib/host-provided-deps.mjs +13 -4
  242. package/node_modules/pi-lens/scripts/lib/web-tree-sitter-dir.mjs +18 -0
  243. package/node_modules/pi-web-access/CHANGELOG.md +28 -0
  244. package/node_modules/pi-web-access/README.md +10 -6
  245. package/node_modules/pi-web-access/ceramic.ts +219 -0
  246. package/node_modules/pi-web-access/curator-page.ts +3 -1
  247. package/node_modules/pi-web-access/curator-server.ts +1 -0
  248. package/node_modules/pi-web-access/dist/index.js +846 -588
  249. package/node_modules/pi-web-access/dist/mcp-cli.js +725 -516
  250. package/node_modules/pi-web-access/gemini-search.ts +8 -4
  251. package/node_modules/pi-web-access/github-extract.ts +34 -2
  252. package/node_modules/pi-web-access/index.ts +72 -30
  253. package/node_modules/pi-web-access/openai-search.ts +3 -3
  254. package/node_modules/pi-web-access/package.json +2 -2
  255. package/node_modules/pi-web-access/page-query.ts +6 -9
  256. package/node_modules/pi-web-access/parallel-mcp.ts +2 -0
  257. package/node_modules/pi-web-access/query-rewrite.ts +2 -2
  258. package/node_modules/pi-web-access/storage.ts +49 -0
  259. package/node_modules/pi-web-access/summary-review.ts +7 -6
  260. package/node_modules/pi-web-access/utils.ts +21 -6
  261. package/node_modules/pi-web-access/web-tool-core.ts +1 -0
  262. package/package.json +19 -19
  263. package/node_modules/@dietrichgebert/ponytail/README.es.md +0 -212
  264. package/node_modules/@dietrichgebert/ponytail/README.ja.md +0 -212
  265. package/node_modules/@dietrichgebert/ponytail/README.ko.md +0 -212
  266. package/node_modules/@dietrichgebert/ponytail/README.zh-CN.md +0 -212
  267. package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +0 -35
  268. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +0 -1610
  269. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +0 -593
  270. package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +0 -147
  271. package/node_modules/pi-lens/dist/clients/agent-nudge.js +0 -325
  272. package/node_modules/pi-lens/dist/clients/analysed-root.js +0 -1
  273. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +0 -731
  274. package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +0 -146
  275. package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +0 -118
  276. package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -10
  277. package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +0 -154
  278. package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +0 -75
  279. package/node_modules/pi-lens/dist/clients/atomic-write.js +0 -189
  280. package/node_modules/pi-lens/dist/clients/availability-probe-flight.js +0 -12
  281. package/node_modules/pi-lens/dist/clients/bash-file-access.js +0 -1056
  282. package/node_modules/pi-lens/dist/clients/biome-client.js +0 -357
  283. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +0 -837
  284. package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +0 -129
  285. package/node_modules/pi-lens/dist/clients/bootstrap.js +0 -569
  286. package/node_modules/pi-lens/dist/clients/bounded-cache.js +0 -190
  287. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +0 -202
  288. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +0 -295
  289. package/node_modules/pi-lens/dist/clients/build-identity.js +0 -95
  290. package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +0 -113
  291. package/node_modules/pi-lens/dist/clients/bus-events-logger.js +0 -105
  292. package/node_modules/pi-lens/dist/clients/bus-publish.js +0 -171
  293. package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +0 -190
  294. package/node_modules/pi-lens/dist/clients/cache-manager.js +0 -524
  295. package/node_modules/pi-lens/dist/clients/cache-observability.js +0 -1313
  296. package/node_modules/pi-lens/dist/clients/call-graph.js +0 -852
  297. package/node_modules/pi-lens/dist/clients/cargo-manifest.js +0 -422
  298. package/node_modules/pi-lens/dist/clients/cascade-budget.js +0 -196
  299. package/node_modules/pi-lens/dist/clients/cascade-format.js +0 -315
  300. package/node_modules/pi-lens/dist/clients/cascade-logger.js +0 -31
  301. package/node_modules/pi-lens/dist/clients/cascade-types.js +0 -9
  302. package/node_modules/pi-lens/dist/clients/child-unref.js +0 -124
  303. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +0 -286
  304. package/node_modules/pi-lens/dist/clients/codebase-model.js +0 -173
  305. package/node_modules/pi-lens/dist/clients/collateral-test-role.js +0 -40
  306. package/node_modules/pi-lens/dist/clients/complexity-client.js +0 -462
  307. package/node_modules/pi-lens/dist/clients/config-core/deny.js +0 -221
  308. package/node_modules/pi-lens/dist/clients/config-core/index.js +0 -50
  309. package/node_modules/pi-lens/dist/clients/config-core/merge.js +0 -357
  310. package/node_modules/pi-lens/dist/clients/config-core/normalize.js +0 -340
  311. package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +0 -248
  312. package/node_modules/pi-lens/dist/clients/config-core/provenance.js +0 -164
  313. package/node_modules/pi-lens/dist/clients/config-core/records.js +0 -218
  314. package/node_modules/pi-lens/dist/clients/config-core/resolve.js +0 -125
  315. package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +0 -78
  316. package/node_modules/pi-lens/dist/clients/config-core/schema.js +0 -165
  317. package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +0 -285
  318. package/node_modules/pi-lens/dist/clients/config-locations.js +0 -388
  319. package/node_modules/pi-lens/dist/clients/config-resolve.js +0 -798
  320. package/node_modules/pi-lens/dist/clients/config-schema.js +0 -251
  321. package/node_modules/pi-lens/dist/clients/config-warn.js +0 -407
  322. package/node_modules/pi-lens/dist/clients/console-guard-install.js +0 -26
  323. package/node_modules/pi-lens/dist/clients/cooperative-budget.js +0 -42
  324. package/node_modules/pi-lens/dist/clients/dead-code-client.js +0 -510
  325. package/node_modules/pi-lens/dist/clients/dead-code-logger.js +0 -30
  326. package/node_modules/pi-lens/dist/clients/deadline-utils.js +0 -280
  327. package/node_modules/pi-lens/dist/clients/debug-handles.js +0 -211
  328. package/node_modules/pi-lens/dist/clients/debug-heap.js +0 -174
  329. package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +0 -106
  330. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +0 -426
  331. package/node_modules/pi-lens/dist/clients/demoted-finding-render.js +0 -169
  332. package/node_modules/pi-lens/dist/clients/dependency-checker.js +0 -885
  333. package/node_modules/pi-lens/dist/clients/deps/ast-grep-napi.js +0 -22
  334. package/node_modules/pi-lens/dist/clients/deps/js-yaml.js +0 -9
  335. package/node_modules/pi-lens/dist/clients/deps/minimatch.js +0 -4
  336. package/node_modules/pi-lens/dist/clients/deps/pi-tui.js +0 -14
  337. package/node_modules/pi-lens/dist/clients/deps/typebox.js +0 -14
  338. package/node_modules/pi-lens/dist/clients/deps/vscode-jsonrpc.js +0 -1
  339. package/node_modules/pi-lens/dist/clients/deps/web-tree-sitter.js +0 -24
  340. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +0 -630
  341. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +0 -305
  342. package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +0 -73
  343. package/node_modules/pi-lens/dist/clients/diagnostic-tracker.js +0 -105
  344. package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +0 -230
  345. package/node_modules/pi-lens/dist/clients/dispatch/ast-grep-catalog.js +0 -65
  346. package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +0 -343
  347. package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +0 -35
  348. package/node_modules/pi-lens/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
  349. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +0 -1269
  350. package/node_modules/pi-lens/dist/clients/dispatch/fact-provider-types.js +0 -1
  351. package/node_modules/pi-lens/dist/clients/dispatch/fact-rule-runner.js +0 -17
  352. package/node_modules/pi-lens/dist/clients/dispatch/fact-runner.js +0 -30
  353. package/node_modules/pi-lens/dist/clients/dispatch/fact-scheduler.js +0 -68
  354. package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +0 -377
  355. package/node_modules/pi-lens/dist/clients/dispatch/facts/comment-facts.js +0 -22
  356. package/node_modules/pi-lens/dist/clients/dispatch/facts/file-content.js +0 -19
  357. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +0 -348
  358. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +0 -204
  359. package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
  360. package/node_modules/pi-lens/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
  361. package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +0 -339
  362. package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +0 -417
  363. package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +0 -89
  364. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +0 -2377
  365. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +0 -11
  366. package/node_modules/pi-lens/dist/clients/dispatch/pending-runner-findings.js +0 -87
  367. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +0 -278
  368. package/node_modules/pi-lens/dist/clients/dispatch/priorities.js +0 -20
  369. package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +0 -50
  370. package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +0 -69
  371. package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +0 -135
  372. package/node_modules/pi-lens/dist/clients/dispatch/rules/async-noise.js +0 -40
  373. package/node_modules/pi-lens/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
  374. package/node_modules/pi-lens/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
  375. package/node_modules/pi-lens/dist/clients/dispatch/rules/error-obscuring.js +0 -32
  376. package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +0 -31
  377. package/node_modules/pi-lens/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
  378. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-complexity.js +0 -72
  379. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-fan-out.js +0 -74
  380. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
  381. package/node_modules/pi-lens/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
  382. package/node_modules/pi-lens/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
  383. package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
  384. package/node_modules/pi-lens/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
  385. package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
  386. package/node_modules/pi-lens/dist/clients/dispatch/runner-context.js +0 -52
  387. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -111
  388. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
  389. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -296
  390. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +0 -219
  391. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -82
  392. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -416
  393. package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -183
  394. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -176
  395. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -164
  396. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -195
  397. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -137
  398. package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -29
  399. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -69
  400. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -167
  401. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +0 -104
  402. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -135
  403. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -91
  404. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -171
  405. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +0 -940
  406. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -117
  407. package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +0 -108
  408. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -99
  409. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -110
  410. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -379
  411. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -167
  412. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -102
  413. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +0 -414
  414. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -85
  415. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -120
  416. package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -62
  417. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
  418. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +0 -169
  419. package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -99
  420. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +0 -88
  421. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +0 -256
  422. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +0 -173
  423. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -102
  424. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +0 -128
  425. package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -259
  426. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -183
  427. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -166
  428. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -163
  429. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -174
  430. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -168
  431. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -125
  432. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -643
  433. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -253
  434. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
  435. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
  436. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -95
  437. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
  438. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
  439. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
  440. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
  441. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
  442. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils.js +0 -15
  443. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -128
  444. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
  445. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +0 -95
  446. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -79
  447. package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +0 -79
  448. package/node_modules/pi-lens/dist/clients/dispatch/tool-profile.js +0 -30
  449. package/node_modules/pi-lens/dist/clients/dispatch/types.js +0 -21
  450. package/node_modules/pi-lens/dist/clients/dispatch/utils/format-utils.js +0 -45
  451. package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
  452. package/node_modules/pi-lens/dist/clients/disposition-logger.js +0 -32
  453. package/node_modules/pi-lens/dist/clients/disposition-publish.js +0 -124
  454. package/node_modules/pi-lens/dist/clients/durable-store.js +0 -97
  455. package/node_modules/pi-lens/dist/clients/effective-config.js +0 -415
  456. package/node_modules/pi-lens/dist/clients/env-utils.js +0 -83
  457. package/node_modules/pi-lens/dist/clients/error-class.js +0 -23
  458. package/node_modules/pi-lens/dist/clients/eval-timestamp.js +0 -17
  459. package/node_modules/pi-lens/dist/clients/event-loop-hold.js +0 -274
  460. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +0 -250
  461. package/node_modules/pi-lens/dist/clients/extension-log.js +0 -504
  462. package/node_modules/pi-lens/dist/clients/extension-mode.js +0 -73
  463. package/node_modules/pi-lens/dist/clients/feature-hints.js +0 -103
  464. package/node_modules/pi-lens/dist/clients/file-kinds.js +0 -412
  465. package/node_modules/pi-lens/dist/clients/file-role.js +0 -134
  466. package/node_modules/pi-lens/dist/clients/file-time.js +0 -160
  467. package/node_modules/pi-lens/dist/clients/file-utils.js +0 -1032
  468. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +0 -494
  469. package/node_modules/pi-lens/dist/clients/finding-identity.js +0 -88
  470. package/node_modules/pi-lens/dist/clients/fix-worklog.js +0 -103
  471. package/node_modules/pi-lens/dist/clients/format-events-publish.js +0 -343
  472. package/node_modules/pi-lens/dist/clients/format-service.js +0 -222
  473. package/node_modules/pi-lens/dist/clients/formatters-lazy.js +0 -9
  474. package/node_modules/pi-lens/dist/clients/formatters.js +0 -2032
  475. package/node_modules/pi-lens/dist/clients/freshness-cadence.js +0 -17
  476. package/node_modules/pi-lens/dist/clients/freshness.js +0 -38
  477. package/node_modules/pi-lens/dist/clients/generated-artifacts.js +0 -394
  478. package/node_modules/pi-lens/dist/clients/generation-guard.js +0 -215
  479. package/node_modules/pi-lens/dist/clients/git-guard.js +0 -1136
  480. package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +0 -243
  481. package/node_modules/pi-lens/dist/clients/gitleaks-client.js +0 -509
  482. package/node_modules/pi-lens/dist/clients/go-client.js +0 -104
  483. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +0 -605
  484. package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +0 -348
  485. package/node_modules/pi-lens/dist/clients/grammar-source.js +0 -465
  486. package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +0 -135
  487. package/node_modules/pi-lens/dist/clients/hashline-anchor.js +0 -424
  488. package/node_modules/pi-lens/dist/clients/hook-budgets.js +0 -76
  489. package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +0 -140
  490. package/node_modules/pi-lens/dist/clients/host-ports.js +0 -39
  491. package/node_modules/pi-lens/dist/clients/indent-retarget.js +0 -154
  492. package/node_modules/pi-lens/dist/clients/inline-blocker-dispositions.js +0 -186
  493. package/node_modules/pi-lens/dist/clients/install-diagnostics.js +0 -156
  494. package/node_modules/pi-lens/dist/clients/installer/index.js +0 -5416
  495. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +0 -58
  496. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +0 -783
  497. package/node_modules/pi-lens/dist/clients/instance-reaper-state.js +0 -7
  498. package/node_modules/pi-lens/dist/clients/instance-reaper.js +0 -1137
  499. package/node_modules/pi-lens/dist/clients/instance-registry-lock.js +0 -145
  500. package/node_modules/pi-lens/dist/clients/instance-registry.js +0 -773
  501. package/node_modules/pi-lens/dist/clients/jscpd-client.js +0 -378
  502. package/node_modules/pi-lens/dist/clients/json-cache-read.js +0 -65
  503. package/node_modules/pi-lens/dist/clients/knip-client.js +0 -788
  504. package/node_modules/pi-lens/dist/clients/language-policy.js +0 -252
  505. package/node_modules/pi-lens/dist/clients/language-profile.js +0 -361
  506. package/node_modules/pi-lens/dist/clients/language-registry.js +0 -603
  507. package/node_modules/pi-lens/dist/clients/latency-logger.js +0 -727
  508. package/node_modules/pi-lens/dist/clients/lazy-import.js +0 -21
  509. package/node_modules/pi-lens/dist/clients/ledger-bounds.js +0 -54
  510. package/node_modules/pi-lens/dist/clients/lens-config.js +0 -404
  511. package/node_modules/pi-lens/dist/clients/lens-engine.js +0 -358
  512. package/node_modules/pi-lens/dist/clients/lens-events.js +0 -125
  513. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +0 -467
  514. package/node_modules/pi-lens/dist/clients/lens-map.js +0 -1156
  515. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +0 -74
  516. package/node_modules/pi-lens/dist/clients/log-cleanup.js +0 -222
  517. package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +0 -178
  518. package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +0 -421
  519. package/node_modules/pi-lens/dist/clients/lsp/client.js +0 -4593
  520. package/node_modules/pi-lens/dist/clients/lsp/config.js +0 -691
  521. package/node_modules/pi-lens/dist/clients/lsp/content-limits.js +0 -41
  522. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +0 -225
  523. package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +0 -467
  524. package/node_modules/pi-lens/dist/clients/lsp/edits.js +0 -1219
  525. package/node_modules/pi-lens/dist/clients/lsp/index.js +0 -8305
  526. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +0 -216
  527. package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +0 -298
  528. package/node_modules/pi-lens/dist/clients/lsp/language.js +0 -63
  529. package/node_modules/pi-lens/dist/clients/lsp/launch.js +0 -746
  530. package/node_modules/pi-lens/dist/clients/lsp/lombok.js +0 -158
  531. package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +0 -5
  532. package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +0 -251
  533. package/node_modules/pi-lens/dist/clients/lsp/position-encoding.js +0 -61
  534. package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +0 -83
  535. package/node_modules/pi-lens/dist/clients/lsp/server.js +0 -3290
  536. package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +0 -192
  537. package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +0 -17
  538. package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +0 -56
  539. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +0 -332
  540. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
  541. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +0 -85
  542. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/index.js +0 -10
  543. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +0 -392
  544. package/node_modules/pi-lens/dist/clients/lsp/watch-queue.js +0 -61
  545. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
  546. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
  547. package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +0 -184
  548. package/node_modules/pi-lens/dist/clients/lsp-budget.js +0 -186
  549. package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +0 -110
  550. package/node_modules/pi-lens/dist/clients/lsp-lazy.js +0 -9
  551. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +0 -396
  552. package/node_modules/pi-lens/dist/clients/lsp-status.js +0 -59
  553. package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +0 -40
  554. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +0 -420
  555. package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +0 -31
  556. package/node_modules/pi-lens/dist/clients/mcp/ipc.js +0 -523
  557. package/node_modules/pi-lens/dist/clients/mcp/review.js +0 -197
  558. package/node_modules/pi-lens/dist/clients/mcp/session.js +0 -412
  559. package/node_modules/pi-lens/dist/clients/memory-sampler.js +0 -208
  560. package/node_modules/pi-lens/dist/clients/message-end-attribution.js +0 -30
  561. package/node_modules/pi-lens/dist/clients/metrics-client.js +0 -107
  562. package/node_modules/pi-lens/dist/clients/metrics-history.js +0 -327
  563. package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +0 -263
  564. package/node_modules/pi-lens/dist/clients/model-provider.js +0 -53
  565. package/node_modules/pi-lens/dist/clients/module-report-lsp.js +0 -189
  566. package/node_modules/pi-lens/dist/clients/module-report.js +0 -2150
  567. package/node_modules/pi-lens/dist/clients/mutating-tool.js +0 -651
  568. package/node_modules/pi-lens/dist/clients/mutation-attribution.js +0 -368
  569. package/node_modules/pi-lens/dist/clients/mutation-bridge.js +0 -240
  570. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +0 -734
  571. package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +0 -101
  572. package/node_modules/pi-lens/dist/clients/observed-mutation.js +0 -1253
  573. package/node_modules/pi-lens/dist/clients/oldtext-autopatch.js +0 -128
  574. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +0 -496
  575. package/node_modules/pi-lens/dist/clients/opengrep-client.js +0 -333
  576. package/node_modules/pi-lens/dist/clients/opengrep-config.js +0 -76
  577. package/node_modules/pi-lens/dist/clients/package-manager.js +0 -607
  578. package/node_modules/pi-lens/dist/clients/package-root.js +0 -38
  579. package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +0 -439
  580. package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +0 -43
  581. package/node_modules/pi-lens/dist/clients/path-keyed-map.js +0 -108
  582. package/node_modules/pi-lens/dist/clients/path-utils.js +0 -1244
  583. package/node_modules/pi-lens/dist/clients/performance-report.js +0 -331
  584. package/node_modules/pi-lens/dist/clients/persist-debounce.js +0 -70
  585. package/node_modules/pi-lens/dist/clients/persistent-reverify.js +0 -271
  586. package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +0 -119
  587. package/node_modules/pi-lens/dist/clients/pipeline.js +0 -1480
  588. package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +0 -37
  589. package/node_modules/pi-lens/dist/clients/print-mode.js +0 -21
  590. package/node_modules/pi-lens/dist/clients/probe-home-state.js +0 -228
  591. package/node_modules/pi-lens/dist/clients/process-bridge.js +0 -66
  592. package/node_modules/pi-lens/dist/clients/process-singletons.js +0 -210
  593. package/node_modules/pi-lens/dist/clients/process-snapshot.js +0 -68
  594. package/node_modules/pi-lens/dist/clients/project-changes.js +0 -181
  595. package/node_modules/pi-lens/dist/clients/project-conventions.js +0 -171
  596. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +0 -137
  597. package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +0 -109
  598. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +0 -668
  599. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
  600. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
  601. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
  602. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
  603. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
  604. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
  605. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
  606. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
  607. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
  608. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
  609. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +0 -520
  610. package/node_modules/pi-lens/dist/clients/project-diagnostics/types.js +0 -1
  611. package/node_modules/pi-lens/dist/clients/project-lens-config.js +0 -807
  612. package/node_modules/pi-lens/dist/clients/project-report.js +0 -701
  613. package/node_modules/pi-lens/dist/clients/project-scale.js +0 -237
  614. package/node_modules/pi-lens/dist/clients/project-scan-policy.js +0 -11
  615. package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +0 -48
  616. package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +0 -20
  617. package/node_modules/pi-lens/dist/clients/project-snapshot.js +0 -1653
  618. package/node_modules/pi-lens/dist/clients/project-trust.js +0 -181
  619. package/node_modules/pi-lens/dist/clients/python-environment.js +0 -217
  620. package/node_modules/pi-lens/dist/clients/python-provenance.js +0 -639
  621. package/node_modules/pi-lens/dist/clients/quiet-window-config.js +0 -47
  622. package/node_modules/pi-lens/dist/clients/quiet-window.js +0 -236
  623. package/node_modules/pi-lens/dist/clients/read-bridge.js +0 -139
  624. package/node_modules/pi-lens/dist/clients/read-expansion.js +0 -266
  625. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +0 -251
  626. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +0 -1306
  627. package/node_modules/pi-lens/dist/clients/read-guard.js +0 -1561
  628. package/node_modules/pi-lens/dist/clients/recent-touches.js +0 -240
  629. package/node_modules/pi-lens/dist/clients/redact/secrets.js +0 -449
  630. package/node_modules/pi-lens/dist/clients/resource-sampler.js +0 -628
  631. package/node_modules/pi-lens/dist/clients/reverse-deps.js +0 -270
  632. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +0 -5126
  633. package/node_modules/pi-lens/dist/clients/review-graph/format.js +0 -33
  634. package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +0 -163
  635. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +0 -481
  636. package/node_modules/pi-lens/dist/clients/review-graph/persist-worker.js +0 -10
  637. package/node_modules/pi-lens/dist/clients/review-graph/query.js +0 -244
  638. package/node_modules/pi-lens/dist/clients/review-graph/revision-drift.js +0 -21
  639. package/node_modules/pi-lens/dist/clients/review-graph/service.js +0 -96
  640. package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +0 -82
  641. package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +0 -103
  642. package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +0 -299
  643. package/node_modules/pi-lens/dist/clients/review-graph/types.js +0 -1
  644. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +0 -449
  645. package/node_modules/pi-lens/dist/clients/review-graph-logger.js +0 -81
  646. package/node_modules/pi-lens/dist/clients/ruff-client.js +0 -179
  647. package/node_modules/pi-lens/dist/clients/rules-scanner.js +0 -131
  648. package/node_modules/pi-lens/dist/clients/run-duration.js +0 -55
  649. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +0 -746
  650. package/node_modules/pi-lens/dist/clients/runtime-config.js +0 -77
  651. package/node_modules/pi-lens/dist/clients/runtime-context.js +0 -211
  652. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +0 -1324
  653. package/node_modules/pi-lens/dist/clients/runtime-session.js +0 -2485
  654. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +0 -1295
  655. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +0 -2049
  656. package/node_modules/pi-lens/dist/clients/runtime-turn.js +0 -3767
  657. package/node_modules/pi-lens/dist/clients/rust-client.js +0 -97
  658. package/node_modules/pi-lens/dist/clients/safe-spawn.js +0 -2357
  659. package/node_modules/pi-lens/dist/clients/sanitize.js +0 -286
  660. package/node_modules/pi-lens/dist/clients/scan-utils.js +0 -25
  661. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +0 -165
  662. package/node_modules/pi-lens/dist/clients/search-read-registration.js +0 -94
  663. package/node_modules/pi-lens/dist/clients/secret-findings.js +0 -114
  664. package/node_modules/pi-lens/dist/clients/security-scan-client.js +0 -352
  665. package/node_modules/pi-lens/dist/clients/session-event-guard.js +0 -297
  666. package/node_modules/pi-lens/dist/clients/session-lifecycle.js +0 -484
  667. package/node_modules/pi-lens/dist/clients/session-start-observability.js +0 -94
  668. package/node_modules/pi-lens/dist/clients/session-state-store.js +0 -101
  669. package/node_modules/pi-lens/dist/clients/session-summary.js +0 -15
  670. package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +0 -27
  671. package/node_modules/pi-lens/dist/clients/sg-runner.js +0 -876
  672. package/node_modules/pi-lens/dist/clients/sgconfig.js +0 -347
  673. package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +0 -338
  674. package/node_modules/pi-lens/dist/clients/single-flight.js +0 -158
  675. package/node_modules/pi-lens/dist/clients/situational-tool-telemetry.js +0 -108
  676. package/node_modules/pi-lens/dist/clients/skills-resolver.js +0 -141
  677. package/node_modules/pi-lens/dist/clients/slow-fs.js +0 -138
  678. package/node_modules/pi-lens/dist/clients/smells-rollup.js +0 -231
  679. package/node_modules/pi-lens/dist/clients/source-filter.js +0 -596
  680. package/node_modules/pi-lens/dist/clients/source-walker.js +0 -211
  681. package/node_modules/pi-lens/dist/clients/spawn-output-cap.js +0 -120
  682. package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +0 -110
  683. package/node_modules/pi-lens/dist/clients/stale-marker.js +0 -17
  684. package/node_modules/pi-lens/dist/clients/startup-scan.js +0 -400
  685. package/node_modules/pi-lens/dist/clients/startup-timing.js +0 -130
  686. package/node_modules/pi-lens/dist/clients/string-utils.js +0 -33
  687. package/node_modules/pi-lens/dist/clients/subagent-mode.js +0 -111
  688. package/node_modules/pi-lens/dist/clients/symbol-containment.js +0 -24
  689. package/node_modules/pi-lens/dist/clients/symbol-types.js +0 -5
  690. package/node_modules/pi-lens/dist/clients/test-runner-client.js +0 -2507
  691. package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +0 -287
  692. package/node_modules/pi-lens/dist/clients/todo-scanner.js +0 -229
  693. package/node_modules/pi-lens/dist/clients/tool-agreement.js +0 -423
  694. package/node_modules/pi-lens/dist/clients/tool-config.js +0 -249
  695. package/node_modules/pi-lens/dist/clients/tool-cwd.js +0 -270
  696. package/node_modules/pi-lens/dist/clients/tool-definition.js +0 -47
  697. package/node_modules/pi-lens/dist/clients/tool-event.js +0 -105
  698. package/node_modules/pi-lens/dist/clients/tool-policy.js +0 -2755
  699. package/node_modules/pi-lens/dist/clients/tool-probe.js +0 -53
  700. package/node_modules/pi-lens/dist/clients/tool-render.js +0 -156
  701. package/node_modules/pi-lens/dist/clients/tool-set-policy.js +0 -118
  702. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +0 -364
  703. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +0 -4195
  704. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +0 -100
  705. package/node_modules/pi-lens/dist/clients/tree-sitter-navigator.js +0 -269
  706. package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +0 -569
  707. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +0 -158
  708. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
  709. package/node_modules/pi-lens/dist/clients/trivy-client.js +0 -467
  710. package/node_modules/pi-lens/dist/clients/tui-fit.js +0 -50
  711. package/node_modules/pi-lens/dist/clients/turn-context.js +0 -52
  712. package/node_modules/pi-lens/dist/clients/turn-end/lane.js +0 -51
  713. package/node_modules/pi-lens/dist/clients/turn-end/lanes/govulncheck.js +0 -112
  714. package/node_modules/pi-lens/dist/clients/turn-end/lanes/secrets.js +0 -204
  715. package/node_modules/pi-lens/dist/clients/turn-summary-render.js +0 -72
  716. package/node_modules/pi-lens/dist/clients/turn-summary.js +0 -132
  717. package/node_modules/pi-lens/dist/clients/typos-config.js +0 -29
  718. package/node_modules/pi-lens/dist/clients/user-notify.js +0 -51
  719. package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +0 -57
  720. package/node_modules/pi-lens/dist/clients/warm-attach.js +0 -305
  721. package/node_modules/pi-lens/dist/clients/widget-state.js +0 -1808
  722. package/node_modules/pi-lens/dist/clients/word-index-logger.js +0 -49
  723. package/node_modules/pi-lens/dist/clients/word-index-store.js +0 -459
  724. package/node_modules/pi-lens/dist/clients/word-index.js +0 -2080
  725. package/node_modules/pi-lens/dist/clients/workspace-topology.js +0 -443
  726. package/node_modules/pi-lens/dist/clients/write-ordering-guard.js +0 -65
  727. package/node_modules/pi-lens/dist/clients/zizmor-config.js +0 -340
  728. package/node_modules/pi-lens/dist/i18n.js +0 -69
  729. package/node_modules/pi-lens/dist/mcp/build-staleness.js +0 -124
  730. package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +0 -583
  731. package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +0 -129
  732. package/node_modules/pi-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -123
  733. package/node_modules/pi-lens/dist/tools/activate-tools.js +0 -87
  734. package/node_modules/pi-lens/dist/tools/ast-grep-outline.js +0 -137
  735. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +0 -244
  736. package/node_modules/pi-lens/dist/tools/ast-grep-search.js +0 -762
  737. package/node_modules/pi-lens/dist/tools/effective-config.js +0 -90
  738. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +0 -375
  739. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +0 -2571
  740. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +0 -1745
  741. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +0 -1367
  742. package/node_modules/pi-lens/dist/tools/lsp-structured-output.js +0 -294
  743. package/node_modules/pi-lens/dist/tools/module-report.js +0 -382
  744. package/node_modules/pi-lens/dist/tools/project-report.js +0 -86
  745. package/node_modules/pi-lens/dist/tools/render-compact.js +0 -374
  746. package/node_modules/pi-lens/dist/tools/scan-progress.js +0 -53
  747. package/node_modules/pi-lens/dist/tools/shared.js +0 -29
  748. package/node_modules/pi-lens/dist/tools/symbol-search.js +0 -155
  749. package/node_modules/pi-web-access/opencode-session-headers.ts +0 -24
  750. package/node_modules/remote-pi/README.md +0 -675
  751. package/node_modules/remote-pi/dist/actions/handlers.d.ts +0 -122
  752. package/node_modules/remote-pi/dist/actions/handlers.js +0 -160
  753. package/node_modules/remote-pi/dist/actions/handlers.js.map +0 -1
  754. package/node_modules/remote-pi/dist/actions/registry.d.ts +0 -39
  755. package/node_modules/remote-pi/dist/actions/registry.js +0 -58
  756. package/node_modules/remote-pi/dist/actions/registry.js.map +0 -1
  757. package/node_modules/remote-pi/dist/bin/supervisord.d.ts +0 -2
  758. package/node_modules/remote-pi/dist/bin/supervisord.js +0 -86
  759. package/node_modules/remote-pi/dist/bin/supervisord.js.map +0 -1
  760. package/node_modules/remote-pi/dist/commands/builtin_mirror.d.ts +0 -58
  761. package/node_modules/remote-pi/dist/commands/builtin_mirror.js +0 -71
  762. package/node_modules/remote-pi/dist/commands/builtin_mirror.js.map +0 -1
  763. package/node_modules/remote-pi/dist/commands/list_commands.d.ts +0 -60
  764. package/node_modules/remote-pi/dist/commands/list_commands.js +0 -73
  765. package/node_modules/remote-pi/dist/commands/list_commands.js.map +0 -1
  766. package/node_modules/remote-pi/dist/config.d.ts +0 -62
  767. package/node_modules/remote-pi/dist/config.js +0 -115
  768. package/node_modules/remote-pi/dist/config.js.map +0 -1
  769. package/node_modules/remote-pi/dist/daemon/client.d.ts +0 -20
  770. package/node_modules/remote-pi/dist/daemon/client.js +0 -131
  771. package/node_modules/remote-pi/dist/daemon/client.js.map +0 -1
  772. package/node_modules/remote-pi/dist/daemon/control_protocol.d.ts +0 -176
  773. package/node_modules/remote-pi/dist/daemon/control_protocol.js +0 -63
  774. package/node_modules/remote-pi/dist/daemon/control_protocol.js.map +0 -1
  775. package/node_modules/remote-pi/dist/daemon/cron_log.d.ts +0 -45
  776. package/node_modules/remote-pi/dist/daemon/cron_log.js +0 -72
  777. package/node_modules/remote-pi/dist/daemon/cron_log.js.map +0 -1
  778. package/node_modules/remote-pi/dist/daemon/cron_registry.d.ts +0 -80
  779. package/node_modules/remote-pi/dist/daemon/cron_registry.js +0 -194
  780. package/node_modules/remote-pi/dist/daemon/cron_registry.js.map +0 -1
  781. package/node_modules/remote-pi/dist/daemon/id.d.ts +0 -24
  782. package/node_modules/remote-pi/dist/daemon/id.js +0 -36
  783. package/node_modules/remote-pi/dist/daemon/id.js.map +0 -1
  784. package/node_modules/remote-pi/dist/daemon/install.d.ts +0 -170
  785. package/node_modules/remote-pi/dist/daemon/install.js +0 -547
  786. package/node_modules/remote-pi/dist/daemon/install.js.map +0 -1
  787. package/node_modules/remote-pi/dist/daemon/registry.d.ts +0 -63
  788. package/node_modules/remote-pi/dist/daemon/registry.js +0 -153
  789. package/node_modules/remote-pi/dist/daemon/registry.js.map +0 -1
  790. package/node_modules/remote-pi/dist/daemon/rpc_child.d.ts +0 -194
  791. package/node_modules/remote-pi/dist/daemon/rpc_child.js +0 -389
  792. package/node_modules/remote-pi/dist/daemon/rpc_child.js.map +0 -1
  793. package/node_modules/remote-pi/dist/daemon/supervisor.d.ts +0 -93
  794. package/node_modules/remote-pi/dist/daemon/supervisor.js +0 -596
  795. package/node_modules/remote-pi/dist/daemon/supervisor.js.map +0 -1
  796. package/node_modules/remote-pi/dist/extension_ui_bridge.d.ts +0 -26
  797. package/node_modules/remote-pi/dist/extension_ui_bridge.js +0 -341
  798. package/node_modules/remote-pi/dist/extension_ui_bridge.js.map +0 -1
  799. package/node_modules/remote-pi/dist/index.d.ts +0 -213
  800. package/node_modules/remote-pi/dist/index.js +0 -4996
  801. package/node_modules/remote-pi/dist/index.js.map +0 -1
  802. package/node_modules/remote-pi/dist/mcp/mesh_result.d.ts +0 -10
  803. package/node_modules/remote-pi/dist/mcp/mesh_result.js +0 -42
  804. package/node_modules/remote-pi/dist/mcp/mesh_result.js.map +0 -1
  805. package/node_modules/remote-pi/dist/mcp/mesh_server.d.ts +0 -16
  806. package/node_modules/remote-pi/dist/mcp/mesh_server.js +0 -327
  807. package/node_modules/remote-pi/dist/mcp/mesh_server.js.map +0 -1
  808. package/node_modules/remote-pi/dist/mesh/canonical.d.ts +0 -30
  809. package/node_modules/remote-pi/dist/mesh/canonical.js +0 -61
  810. package/node_modules/remote-pi/dist/mesh/canonical.js.map +0 -1
  811. package/node_modules/remote-pi/dist/mesh/client.d.ts +0 -18
  812. package/node_modules/remote-pi/dist/mesh/client.js +0 -125
  813. package/node_modules/remote-pi/dist/mesh/client.js.map +0 -1
  814. package/node_modules/remote-pi/dist/mesh/encoding.d.ts +0 -38
  815. package/node_modules/remote-pi/dist/mesh/encoding.js +0 -216
  816. package/node_modules/remote-pi/dist/mesh/encoding.js.map +0 -1
  817. package/node_modules/remote-pi/dist/mesh/self_revoke.d.ts +0 -73
  818. package/node_modules/remote-pi/dist/mesh/self_revoke.js +0 -401
  819. package/node_modules/remote-pi/dist/mesh/self_revoke.js.map +0 -1
  820. package/node_modules/remote-pi/dist/mesh/siblings.d.ts +0 -49
  821. package/node_modules/remote-pi/dist/mesh/siblings.js +0 -159
  822. package/node_modules/remote-pi/dist/mesh/siblings.js.map +0 -1
  823. package/node_modules/remote-pi/dist/mesh/types.d.ts +0 -34
  824. package/node_modules/remote-pi/dist/mesh/types.js +0 -11
  825. package/node_modules/remote-pi/dist/mesh/types.js.map +0 -1
  826. package/node_modules/remote-pi/dist/mesh/verify.d.ts +0 -17
  827. package/node_modules/remote-pi/dist/mesh/verify.js +0 -86
  828. package/node_modules/remote-pi/dist/mesh/verify.js.map +0 -1
  829. package/node_modules/remote-pi/dist/pairing/crypto.d.ts +0 -8
  830. package/node_modules/remote-pi/dist/pairing/crypto.js +0 -22
  831. package/node_modules/remote-pi/dist/pairing/crypto.js.map +0 -1
  832. package/node_modules/remote-pi/dist/pairing/handshake.d.ts +0 -28
  833. package/node_modules/remote-pi/dist/pairing/handshake.js +0 -113
  834. package/node_modules/remote-pi/dist/pairing/handshake.js.map +0 -1
  835. package/node_modules/remote-pi/dist/pairing/noise-sha256.d.ts +0 -16
  836. package/node_modules/remote-pi/dist/pairing/noise-sha256.js +0 -103
  837. package/node_modules/remote-pi/dist/pairing/noise-sha256.js.map +0 -1
  838. package/node_modules/remote-pi/dist/pairing/qr.d.ts +0 -59
  839. package/node_modules/remote-pi/dist/pairing/qr.js +0 -125
  840. package/node_modules/remote-pi/dist/pairing/qr.js.map +0 -1
  841. package/node_modules/remote-pi/dist/pairing/storage.d.ts +0 -120
  842. package/node_modules/remote-pi/dist/pairing/storage.js +0 -604
  843. package/node_modules/remote-pi/dist/pairing/storage.js.map +0 -1
  844. package/node_modules/remote-pi/dist/protocol/codec.d.ts +0 -7
  845. package/node_modules/remote-pi/dist/protocol/codec.js +0 -49
  846. package/node_modules/remote-pi/dist/protocol/codec.js.map +0 -1
  847. package/node_modules/remote-pi/dist/protocol/types.d.ts +0 -393
  848. package/node_modules/remote-pi/dist/protocol/types.js +0 -2
  849. package/node_modules/remote-pi/dist/protocol/types.js.map +0 -1
  850. package/node_modules/remote-pi/dist/rooms.d.ts +0 -29
  851. package/node_modules/remote-pi/dist/rooms.js +0 -57
  852. package/node_modules/remote-pi/dist/rooms.js.map +0 -1
  853. package/node_modules/remote-pi/dist/session/address.d.ts +0 -49
  854. package/node_modules/remote-pi/dist/session/address.js +0 -58
  855. package/node_modules/remote-pi/dist/session/address.js.map +0 -1
  856. package/node_modules/remote-pi/dist/session/agent_bridge.d.ts +0 -55
  857. package/node_modules/remote-pi/dist/session/agent_bridge.js +0 -146
  858. package/node_modules/remote-pi/dist/session/agent_bridge.js.map +0 -1
  859. package/node_modules/remote-pi/dist/session/bridge.d.ts +0 -37
  860. package/node_modules/remote-pi/dist/session/bridge.js +0 -130
  861. package/node_modules/remote-pi/dist/session/bridge.js.map +0 -1
  862. package/node_modules/remote-pi/dist/session/broker.d.ts +0 -189
  863. package/node_modules/remote-pi/dist/session/broker.js +0 -507
  864. package/node_modules/remote-pi/dist/session/broker.js.map +0 -1
  865. package/node_modules/remote-pi/dist/session/broker_remote.d.ts +0 -74
  866. package/node_modules/remote-pi/dist/session/broker_remote.js +0 -583
  867. package/node_modules/remote-pi/dist/session/broker_remote.js.map +0 -1
  868. package/node_modules/remote-pi/dist/session/cwd_lock.d.ts +0 -33
  869. package/node_modules/remote-pi/dist/session/cwd_lock.js +0 -126
  870. package/node_modules/remote-pi/dist/session/cwd_lock.js.map +0 -1
  871. package/node_modules/remote-pi/dist/session/envelope.d.ts +0 -33
  872. package/node_modules/remote-pi/dist/session/envelope.js +0 -117
  873. package/node_modules/remote-pi/dist/session/envelope.js.map +0 -1
  874. package/node_modules/remote-pi/dist/session/global_config.d.ts +0 -33
  875. package/node_modules/remote-pi/dist/session/global_config.js +0 -73
  876. package/node_modules/remote-pi/dist/session/global_config.js.map +0 -1
  877. package/node_modules/remote-pi/dist/session/ipc.d.ts +0 -27
  878. package/node_modules/remote-pi/dist/session/ipc.js +0 -22
  879. package/node_modules/remote-pi/dist/session/ipc.js.map +0 -1
  880. package/node_modules/remote-pi/dist/session/leader_election.d.ts +0 -32
  881. package/node_modules/remote-pi/dist/session/leader_election.js +0 -106
  882. package/node_modules/remote-pi/dist/session/leader_election.js.map +0 -1
  883. package/node_modules/remote-pi/dist/session/local_config.d.ts +0 -55
  884. package/node_modules/remote-pi/dist/session/local_config.js +0 -157
  885. package/node_modules/remote-pi/dist/session/local_config.js.map +0 -1
  886. package/node_modules/remote-pi/dist/session/mesh_message.d.ts +0 -20
  887. package/node_modules/remote-pi/dist/session/mesh_message.js +0 -28
  888. package/node_modules/remote-pi/dist/session/mesh_message.js.map +0 -1
  889. package/node_modules/remote-pi/dist/session/mesh_node.d.ts +0 -116
  890. package/node_modules/remote-pi/dist/session/mesh_node.js +0 -573
  891. package/node_modules/remote-pi/dist/session/mesh_node.js.map +0 -1
  892. package/node_modules/remote-pi/dist/session/peer.d.ts +0 -139
  893. package/node_modules/remote-pi/dist/session/peer.js +0 -451
  894. package/node_modules/remote-pi/dist/session/peer.js.map +0 -1
  895. package/node_modules/remote-pi/dist/session/peer_inventory.d.ts +0 -13
  896. package/node_modules/remote-pi/dist/session/peer_inventory.js +0 -48
  897. package/node_modules/remote-pi/dist/session/peer_inventory.js.map +0 -1
  898. package/node_modules/remote-pi/dist/session/peer_limits.d.ts +0 -9
  899. package/node_modules/remote-pi/dist/session/peer_limits.js +0 -21
  900. package/node_modules/remote-pi/dist/session/peer_limits.js.map +0 -1
  901. package/node_modules/remote-pi/dist/session/setup_wizard.d.ts +0 -39
  902. package/node_modules/remote-pi/dist/session/setup_wizard.js +0 -63
  903. package/node_modules/remote-pi/dist/session/setup_wizard.js.map +0 -1
  904. package/node_modules/remote-pi/dist/session/tool_gate.d.ts +0 -5
  905. package/node_modules/remote-pi/dist/session/tool_gate.js +0 -11
  906. package/node_modules/remote-pi/dist/session/tool_gate.js.map +0 -1
  907. package/node_modules/remote-pi/dist/session/tools.d.ts +0 -24
  908. package/node_modules/remote-pi/dist/session/tools.js +0 -252
  909. package/node_modules/remote-pi/dist/session/tools.js.map +0 -1
  910. package/node_modules/remote-pi/dist/session/wizard.d.ts +0 -13
  911. package/node_modules/remote-pi/dist/session/wizard.js +0 -20
  912. package/node_modules/remote-pi/dist/session/wizard.js.map +0 -1
  913. package/node_modules/remote-pi/dist/settings.d.ts +0 -15
  914. package/node_modules/remote-pi/dist/settings.js +0 -52
  915. package/node_modules/remote-pi/dist/settings.js.map +0 -1
  916. package/node_modules/remote-pi/dist/transport/peer_channel.d.ts +0 -37
  917. package/node_modules/remote-pi/dist/transport/peer_channel.js +0 -98
  918. package/node_modules/remote-pi/dist/transport/peer_channel.js.map +0 -1
  919. package/node_modules/remote-pi/dist/transport/pi_forward_client.d.ts +0 -29
  920. package/node_modules/remote-pi/dist/transport/pi_forward_client.js +0 -62
  921. package/node_modules/remote-pi/dist/transport/pi_forward_client.js.map +0 -1
  922. package/node_modules/remote-pi/dist/transport/relay_client.d.ts +0 -91
  923. package/node_modules/remote-pi/dist/transport/relay_client.js +0 -206
  924. package/node_modules/remote-pi/dist/transport/relay_client.js.map +0 -1
  925. package/node_modules/remote-pi/dist/ui/footer.d.ts +0 -32
  926. package/node_modules/remote-pi/dist/ui/footer.js +0 -34
  927. package/node_modules/remote-pi/dist/ui/footer.js.map +0 -1
  928. package/node_modules/remote-pi/docs/daemon.md +0 -289
  929. package/node_modules/remote-pi/package.json +0 -92
  930. package/node_modules/remote-pi/service-templates/launchd.plist.template +0 -35
  931. package/node_modules/remote-pi/service-templates/systemd.service.template +0 -19
  932. package/node_modules/remote-pi/service-templates/task-launcher.vbs.template +0 -10
  933. package/node_modules/remote-pi/service-templates/task-scheduler.xml.template +0 -38
  934. package/node_modules/remote-pi/skills/agent-network/SKILL.md +0 -310
@@ -79,6 +79,7 @@ async function main() {
79
79
  analyzeActionableWarnings(files.actionableWarnings, state),
80
80
  analyzeAstGrepTools(files.astGrepTools, state),
81
81
  analyzeWorklog(files.worklog, state),
82
+ analyzeExtension(files.extension, state),
82
83
  ]);
83
84
 
84
85
  const report = buildReport(state);
@@ -165,18 +166,34 @@ function discoverLogFiles(logRoot, archived) {
165
166
  });
166
167
 
167
168
  return {
168
- latency: byPrefix("latency"),
169
- sessionStart: byPrefix("sessionstart"),
170
- cascade: byPrefix("cascade"),
171
- readGuard: byPrefix("read-guard"),
172
- treeSitter: byPrefix("tree-sitter"),
173
- actionableWarnings: byPrefix("actionable-warnings"),
174
- astGrepTools: byPrefix("ast-grep-tools"),
169
+ latency: chronologicalFiles(byPrefix("latency")),
170
+ sessionStart: chronologicalFiles(byPrefix("sessionstart")),
171
+ cascade: chronologicalFiles(byPrefix("cascade")),
172
+ readGuard: chronologicalFiles(byPrefix("read-guard")),
173
+ treeSitter: chronologicalFiles(byPrefix("tree-sitter")),
174
+ actionableWarnings: chronologicalFiles(byPrefix("actionable-warnings")),
175
+ astGrepTools: chronologicalFiles(byPrefix("ast-grep-tools")),
176
+ extension: chronologicalFiles(byPrefix("extension")),
175
177
  diagnostics: dailyLogs,
176
178
  worklog: worklogs,
177
179
  };
178
180
  }
179
181
 
182
+ /**
183
+ * Rotated siblings (`x.log.1`) carry older rows than the active `x.log`. The
184
+ * run-splitting detectors (D3/D4/D5) and the read-guard evidence walk (D10)
185
+ * only read correctly in chronological order, so order every multi-file stream
186
+ * oldest-first with the active file last.
187
+ */
188
+ function chronologicalFiles(files) {
189
+ return [...files].sort((a, b) => {
190
+ const activeA = path.basename(a).endsWith(".log");
191
+ const activeB = path.basename(b).endsWith(".log");
192
+ if (activeA !== activeB) return activeA ? 1 : -1;
193
+ return a.localeCompare(b);
194
+ });
195
+ }
196
+
180
197
  function safeReaddir(dir) {
181
198
  try {
182
199
  return fs.readdirSync(dir);
@@ -205,6 +222,45 @@ function createState(files) {
205
222
  toolResults: counter(),
206
223
  phaseCounts: counter(),
207
224
  phaseTimeouts: counter(),
225
+ // D1: every latency row timestamp (ms) in window, for the coverage-gap
226
+ // scan. Sorted after all files are read.
227
+ rowTs: [],
228
+ cascadeTs: [],
229
+ // D2: real-log pollution — rows whose filePath points at a test
230
+ // home, grouped by pid.
231
+ scratchRows: new Map(),
232
+ // D5: test_runner_delivery outcomes per session, joined with the
233
+ // sessionstart firing/stale text into one delivery-health verdict.
234
+ testRunnerDelivery: new Map(),
235
+ // D6: `phase: knip` executed rows per pid, for the drift and cost rules.
236
+ knip: new Map(),
237
+ // D7: hook-await-exceeded overruns plus the per-pid degradation census.
238
+ hookAwaitExceeded: [],
239
+ degradationKinds: new Map(),
240
+ // D8: turn_end `tool_result` summaries per pid, and the retained-state text.
241
+ turnEndTools: new Map(),
242
+ retainingNewerTurn: [],
243
+ // D9: empty-candidate LSP waits, edit touches that saw no client, and
244
+ // warm-reuse selections, joined into the wait/contradiction verdict.
245
+ lspWaitEmpty: new Map(),
246
+ lspTouchEdit: new Map(),
247
+ lspTouchNoClients: [],
248
+ lspClientSelectedWarm: [],
249
+ // D11: read-set carry outcomes at a restart boundary.
250
+ carryRestart: [],
251
+ // D12: nudges and scope transitions, joined by pid + wall clock.
252
+ agentNudges: [],
253
+ sessionScopeTransitions: [],
254
+ // D13: deferred runner failures joined to their delivery row by (pid, turnId).
255
+ deferredRunnerFailed: [],
256
+ lateRunnerFindings: [],
257
+ // D14: auxiliary stuck pair (pid, filePath, serverId) recurrence.
258
+ auxStuck: new Map(),
259
+ // D15: advisory provenance decisions with unknown provenance.
260
+ advisoryProvenance: [],
261
+ // D8/D15: first latency row timestamp per pid (lifetime base).
262
+ pidFirstTs: new Map(),
263
+ pidLastTs: new Map(),
208
264
  workspace: {
209
265
  started: 0,
210
266
  completed: 0,
@@ -280,6 +336,24 @@ function createState(files) {
280
336
  staleRanges: [],
281
337
  zeroReads: [],
282
338
  unavailableSnapshots: [],
339
+ // E2: the block/warn split. These rows do not carry a host-side
340
+ // decision, so the analyzer must not invent one.
341
+ blocks: [],
342
+ warns: [],
343
+ blockByKind: counter(),
344
+ bypassedMismatch: 0,
345
+ // D10: per-(session,file) evidence that a read or a committed edit
346
+ // happened earlier in the session, so a later `zero_read` block is a
347
+ // lost read-set rather than a genuine cold edit.
348
+ fileEvidence: new Map(),
349
+ stateLost: [],
350
+ genuineZeroRead: [],
351
+ },
352
+ extension: {
353
+ // D2: extension.log rows whose payload names a test home
354
+ // directory, grouped by pid, plus the warn/error census.
355
+ scratchRows: new Map(),
356
+ warnErrorGroups: counter(),
283
357
  },
284
358
  treeSitter: {
285
359
  phases: counter(),
@@ -292,12 +366,26 @@ function createState(files) {
292
366
  session: {
293
367
  starts: 0,
294
368
  cwds: counter(),
369
+ // E4: per-start build identity (`commit=`), so every rate can be split
370
+ // by build. Keyed by commit, with the start timestamps that carried it.
371
+ commits: counter(),
295
372
  slowStarts: [],
296
373
  slowTasks: [],
297
374
  toolNoise: counter(),
298
375
  lspNoise: counter(),
299
376
  errors: [],
300
- rotations: counter(),
377
+ // D1: every sessionstart line timestamp (ms) in window.
378
+ rowTs: [],
379
+ // D16: `pi-lens loaded: Nms` lines, with their wall clock so a short
380
+ // lived pid can be marked.
381
+ slowLoads: [],
382
+ // D16: the wall clock of every `session_start fired`, so a load with no
383
+ // session start within 60 s (a short-lived pid) is visible.
384
+ firedTs: [],
385
+ // D3/D4/D5/D8: one run per `session_start fired`. Run splitting is the
386
+ // only way to attribute a turn-end test decision to the session that made it.
387
+ runs: [],
388
+ currentRun: newRun(),
301
389
  },
302
390
  actionable: {
303
391
  events: counter(),
@@ -329,13 +417,26 @@ function createState(files) {
329
417
  };
330
418
  }
331
419
 
420
+ /**
421
+ * The failure kind of a `failed` or `crashed` runner row. `metadata.failureKind`
422
+ * is exact: inline rows carry it (#3781) and collect-later rows too (#3796).
423
+ * Rows written by released versions never carry it, so the count heuristic
424
+ * (a failure with diagnostics is found-errors) stays only as that fallback.
425
+ */
426
+ function runnerFailureKind(entry) {
427
+ if (entry.metadata?.failureKind) return entry.metadata.failureKind;
428
+ if (entry.status === "crashed") return "crashed";
429
+ return (entry.diagnosticCount ?? 0) > 0 ? "blocking_diagnostics" : "unknown";
430
+ }
431
+
332
432
  async function analyzeLatency(files, state) {
333
433
  for (const file of files) {
334
434
  await forEachJsonLine(file, "latency", state, (entry) => {
335
435
  const ts = dateOf(entry.ts);
336
436
  if (!inWindow(ts)) return;
337
437
  state.seen.inc("latency");
338
- trackProject(state, entry.filePath);
438
+ trackLatencyProject(state, entry);
439
+ trackLatencySignals(state, entry, ts);
339
440
 
340
441
  if (entry.type === "runner") {
341
442
  const status = entry.status ?? "unknown";
@@ -344,15 +445,8 @@ async function analyzeLatency(files, state) {
344
445
  if (status === "failed" || status === "crashed") {
345
446
  // Separate a genuine runner breakage from "the check ran and found
346
447
  // blocking issues" (e.g. the LSP runner reports status:failed when a
347
- // file has type errors). Prefer the logged failureKind; fall back to
348
- // the heuristic that a failure carrying diagnostics is found-errors.
349
- const kind =
350
- entry.metadata?.failureKind ??
351
- (status === "crashed"
352
- ? "crashed"
353
- : (entry.diagnosticCount ?? 0) > 0
354
- ? "blocking_diagnostics"
355
- : "unknown");
448
+ // file has type errors).
449
+ const kind = runnerFailureKind(entry);
356
450
  state.latency.runnerFailureKinds.inc(`${runner}:${kind}`);
357
451
  if (kind === "blocking_diagnostics") {
358
452
  state.latency.runnerBlockingFindings.inc(runner);
@@ -543,6 +637,7 @@ async function analyzeCascade(files, state) {
543
637
  const ts = dateOf(entry.ts);
544
638
  if (!inWindow(ts)) return;
545
639
  state.seen.inc("cascade");
640
+ if (ts) state.latency.cascadeTs.push(ts.getTime());
546
641
  trackProject(state, entry.filePath);
547
642
  const phase = entry.phase ?? "unknown";
548
643
  state.cascade.phases.inc(phase);
@@ -589,24 +684,76 @@ async function analyzeReadGuard(files, state) {
589
684
  for (const file of files) {
590
685
  await forEachJsonLine(file, "read-guard", state, (entry) => {
591
686
  const ts = dateOf(entry.ts);
592
- if (!inWindow(ts)) return;
687
+ if (!inWindow(ts)) {
688
+ // D10 needs evidence that may precede a live-monitor window.
689
+ // Keep this lookback state private; outside rows never affect counts.
690
+ if (hasReadEvidence(entry)) {
691
+ const key = `${readGuardSessionOf(entry) ?? "?"}\u0000${entry.filePath ?? "?"}`;
692
+ state.readGuard.fileEvidence.set(key, true);
693
+ }
694
+ return;
695
+ }
593
696
  state.seen.inc("read-guard");
594
697
  trackProject(state, entry.filePath);
595
698
  const event = entry.event ?? "unknown";
699
+ const md = entry.metadata ?? {};
596
700
  state.readGuard.events.inc(event);
597
701
  state.readGuard.byFile.inc(shortPath(entry.filePath));
598
- const reasonKind = entry.metadata?.reasonKind;
702
+ const reasonKind = md.reasonKind;
599
703
  if (reasonKind) state.readGuard.byReason.inc(reasonKind);
704
+
705
+ // D10: evidence that this file was read or edited earlier in the
706
+ // SAME session. Read before this row's own evidence is recorded, so a
707
+ // later `zero_read` block sees only the prior rows. An
708
+ // `edit_batch_summary` carries no sessionId, so its session is the
709
+ // turnId prefix before the last `:`.
710
+ const evidenceKey = `${readGuardSessionOf(entry) ?? "?"}\u0000${entry.filePath ?? "?"}`;
711
+ const hadEvidence =
712
+ state.readGuard.fileEvidence.get(evidenceKey) === true;
713
+
600
714
  if (event === "edit_preflight_blocked") {
601
715
  state.readGuard.preflightReasons.inc(reasonKind ?? "unknown");
716
+ registerBlock(state, entry, "preflight");
717
+ }
718
+ if (event === "edit_blocked") {
719
+ const summary = registerBlock(state, entry, "blocked");
720
+ if (reasonKind === "zero_read") {
721
+ pushTop(state.readGuard.zeroReads, summary, limit * 3, byLine);
722
+ if (hadEvidence) {
723
+ pushTop(
724
+ state.readGuard.stateLost,
725
+ { ...summary, classification: "state-lost" },
726
+ limit * 3,
727
+ byLine,
728
+ );
729
+ } else {
730
+ pushTop(
731
+ state.readGuard.genuineZeroRead,
732
+ { ...summary, classification: "genuine" },
733
+ limit * 3,
734
+ byLine,
735
+ );
736
+ }
737
+ }
738
+ }
739
+ if (event === "edit_warned") {
740
+ pushTop(
741
+ state.readGuard.warns,
742
+ summarizeReadGuard(entry),
743
+ limit * 3,
744
+ byLine,
745
+ );
602
746
  }
603
747
  if (event === "range_snapshot_validation") {
604
- const status = entry.metadata?.status ?? "unknown";
748
+ const status = md.status ?? "unknown";
749
+ const outcome = String(md.outcome ?? "");
605
750
  state.readGuard.snapshotStatus.inc(status);
606
751
  state.readGuard.snapshotEnforcement.inc(
607
- entry.metadata?.enforced ? "enforced" : "not_enforced",
752
+ md.enforced ? "enforced" : "not_enforced",
608
753
  );
609
- if (status === "mismatch") {
754
+ // E3: `bypassed-content-match` is an allowed edit, not a stale
755
+ // read. Only a mismatch the caller did NOT bypass is a smell.
756
+ if (status === "mismatch" && !outcome.startsWith("bypassed")) {
610
757
  state.smellTotals.inc("read-guard-stale-ranges");
611
758
  pushTop(
612
759
  state.readGuard.staleRanges,
@@ -614,6 +761,8 @@ async function analyzeReadGuard(files, state) {
614
761
  limit * 3,
615
762
  byLine,
616
763
  );
764
+ } else if (status === "mismatch") {
765
+ state.readGuard.bypassedMismatch += 1;
617
766
  } else if (status === "unavailable") {
618
767
  pushTop(
619
768
  state.readGuard.unavailableSnapshots,
@@ -623,21 +772,11 @@ async function analyzeReadGuard(files, state) {
623
772
  );
624
773
  }
625
774
  }
626
- if (event === "edit_blocked" || event === "edit_warned") {
627
- state.smellTotals.inc("read-guard-friction");
628
- const summary = summarizeReadGuard(entry);
629
- pushTop(state.readGuard.blocked, summary, limit * 3, byLine);
630
- if (reasonKind === "zero_read") {
631
- pushTop(state.readGuard.zeroReads, summary, limit * 3, byLine);
632
- }
633
- }
634
775
  if (
635
776
  event === "oldtext_not_found" ||
636
777
  event === "oldtext_duplicate" ||
637
- event === "touched_lines_missing" ||
638
- event === "edit_preflight_blocked"
778
+ event === "touched_lines_missing"
639
779
  ) {
640
- state.smellTotals.inc("read-guard-friction");
641
780
  pushTop(
642
781
  state.readGuard.oldTextIssues,
643
782
  summarizeReadGuard(entry),
@@ -645,10 +784,48 @@ async function analyzeReadGuard(files, state) {
645
784
  byLine,
646
785
  );
647
786
  }
787
+
788
+ if (hasReadEvidence(entry))
789
+ state.readGuard.fileEvidence.set(evidenceKey, true);
648
790
  });
649
791
  }
650
792
  }
651
793
 
794
+ /** D10: a row proving the file was read or edited earlier in its session. */
795
+ function hasReadEvidence(entry) {
796
+ const md = entry.metadata ?? {};
797
+ return (
798
+ entry.event === "edit_batch_summary" ||
799
+ (entry.event === "range_snapshot_validation" &&
800
+ Number(md.candidateReadCount ?? 0) > 0) ||
801
+ (entry.event === "edit_warned" && Number(md.readCount ?? 0) > 0)
802
+ );
803
+ }
804
+
805
+ /**
806
+ * D10: the session a read-guard row belongs to. `edit_batch_summary` rows carry
807
+ * no `sessionId`, so fall back to the turnId prefix before the last `:` (the
808
+ * report's own join instruction).
809
+ */
810
+ function readGuardSessionOf(entry) {
811
+ if (typeof entry.sessionId === "string" && entry.sessionId)
812
+ return entry.sessionId;
813
+ const turnId = entry.turnId;
814
+ if (typeof turnId === "string" && turnId.includes(":"))
815
+ return turnId.slice(0, turnId.lastIndexOf(":"));
816
+ return null;
817
+ }
818
+
819
+ /** E2: one blocked edit. Host/model provenance is not present on this row. */
820
+ function registerBlock(state, entry, source) {
821
+ const summary = summarizeReadGuard(entry);
822
+ pushTop(state.readGuard.blocks, summary, limit * 3, byLine);
823
+ state.readGuard.blockByKind.inc(
824
+ `${source}:${entry.metadata?.reasonKind ?? "unknown"}`,
825
+ );
826
+ return summary;
827
+ }
828
+
652
829
  async function analyzeTreeSitter(files, state) {
653
830
  for (const file of files) {
654
831
  await forEachJsonLine(file, "tree-sitter", state, (entry) => {
@@ -704,21 +881,48 @@ async function analyzeSessionStart(files, state) {
704
881
  const match = lineRe.exec(line);
705
882
  if (!match) return;
706
883
  const ts = dateOf(match[1]);
707
- if (!inWindow(ts)) return;
708
884
  const message = match[2];
885
+ if (!inWindow(ts)) {
886
+ // A --since window can begin after the session_start that owns its
887
+ // rows. Carry only that run anchor into the visible window.
888
+ if (message.startsWith("session_start fired")) {
889
+ state.session.currentRun = newRun();
890
+ state.session.currentRun.startTs = iso(ts);
891
+ }
892
+ return;
893
+ }
709
894
  if (isExcludedText(message)) {
710
895
  state.excludedRows++;
711
896
  return;
712
897
  }
713
898
  state.seen.inc("sessionstart");
899
+ if (ts) state.session.rowTs.push(ts.getTime());
900
+
901
+ // E4: starts are counted from `session_start fired`, which every mode
902
+ // writes, instead of the dead `session_start cwd:` full-mode line. The
903
+ // same line opens a D3/D4/D5/D8 run.
904
+ if (message.startsWith("session_start fired")) {
905
+ state.session.starts++;
906
+ if (ts) state.session.firedTs.push(ts.getTime());
907
+ state.session.runs.push(state.session.currentRun);
908
+ state.session.currentRun = newRun();
909
+ state.session.currentRun.startTs = iso(ts);
910
+ }
714
911
 
715
912
  const cwd = /session_start cwd:\s*(.*)$/.exec(message)?.[1];
716
913
  if (cwd) {
717
- state.session.starts++;
718
914
  state.session.cwds.inc(projectOf(cwd));
719
915
  trackProject(state, cwd);
720
916
  }
721
917
 
918
+ // E4: build identity for the session that just started.
919
+ const buildIdentity =
920
+ /session_start: build identity [—-] commit=(\w+)/.exec(message);
921
+ if (buildIdentity) {
922
+ state.session.commits.inc(buildIdentity[1]);
923
+ state.session.currentRun.commit = buildIdentity[1];
924
+ }
925
+
722
926
  // #2526 R3 S1: this session's config-resolution PENDING mark, published
723
927
  // by `loadLSPConfig` itself at the instant a resolution is actually
724
928
  // attempted — never a start-line prediction from `no-lsp`/subagent/
@@ -780,8 +984,49 @@ async function analyzeSessionStart(files, state) {
780
984
  );
781
985
  }
782
986
 
783
- if (message.includes("log_cleanup: rotated"))
784
- state.session.rotations.inc(message.replace(/^log_cleanup:\s*/, ""));
987
+ // D16: extension load time is invisible to `slow-session-start`, which
988
+ // reads `session_start total:` (a quick-mode total of tens of ms).
989
+ const load = /pi-lens loaded: (\d+)ms after process start/.exec(message);
990
+ if (load) {
991
+ state.session.slowLoads.push({
992
+ ts: iso(ts),
993
+ ms: ts ? ts.getTime() : null,
994
+ durationMs: Number(load[1]),
995
+ message,
996
+ });
997
+ }
998
+
999
+ const run = state.session.currentRun;
1000
+ const modified = /turn_end: (\d+) file\(s\) modified/.exec(message);
1001
+ if (modified) run.edits += 1;
1002
+ if (message.includes("excluded by the built-in turn-end policy")) {
1003
+ run.excluded += 1;
1004
+ const excludedPath = /turn_end:\s*(\S+)\s+→ test target excluded/.exec(
1005
+ message,
1006
+ )?.[1];
1007
+ if (excludedPath) run.excludedTestFiles.push(excludedPath);
1008
+ }
1009
+ if (message.includes("→ no test file found")) run.noTestFile += 1;
1010
+ const vitest =
1011
+ /^turn_end:\s+(.+?)\s+→\s+test vitest\s+(\S+)\s+\(([^)]+)\)/.exec(
1012
+ message,
1013
+ );
1014
+ if (vitest) {
1015
+ run.ran += 1;
1016
+ const [, src, tgt, mode] = vitest;
1017
+ if (mode.includes("failed-first")) {
1018
+ run.failedFirst += 1;
1019
+ const a = checkoutOf(src);
1020
+ const b = checkoutOf(tgt);
1021
+ if (a && b && a !== b) run.crossCheckout += 1;
1022
+ }
1023
+ }
1024
+ if (/turn_end: firing \d+ test target\(s\) async/.test(message))
1025
+ run.testFirings += 1;
1026
+ if (/\(stale\s*[—-]\s*turn advanced while tests ran\)/.test(message))
1027
+ run.testStale += 1;
1028
+ if (/turn_end: retaining newer turn state/.test(message))
1029
+ run.retainingNewerTurn += 1;
785
1030
 
786
1031
  const lower = message.toLowerCase();
787
1032
  if (
@@ -792,8 +1037,16 @@ async function analyzeSessionStart(files, state) {
792
1037
  state.smellTotals.inc("tool-install-noise");
793
1038
  state.session.toolNoise.inc(normalizeSessionNoise(message));
794
1039
  }
1040
+ // E1: anchor to the production failure emitters so a worktree name
1041
+ // such as `468-wait-timeout` inside a `cwd=`/`command=` token cannot
1042
+ // match (the 20 false positives in the live session). Every emitter
1043
+ // puts the failure word before any `key=` token: `lsp spawn <id>:
1044
+ // unavailable|failed` (clients/lsp/index.ts) and `lsp launch
1045
+ // candidate|managed|bundle|tree-bin failed` (clients/lsp/server.ts).
1046
+ // `lsp read warm unavailable` is informational, and `lsp process
1047
+ // <cmd>:` only ever logs `spawn-error` or `closed` (clients/lsp/launch.ts).
795
1048
  if (
796
- /lsp .*?(unavailable|failed|timeout|skipped_broken|exited immediately|binary not found)/i.test(
1049
+ /^lsp (?:spawn [^:]+: (?:unavailable|failed)|launch (?:candidate|managed|bundle|tree-bin) failed)/.test(
797
1050
  message,
798
1051
  )
799
1052
  ) {
@@ -814,6 +1067,9 @@ async function analyzeSessionStart(files, state) {
814
1067
  }
815
1068
  });
816
1069
  }
1070
+ // Close the final run so the last `session_start fired` block is analyzed.
1071
+ if (state.session.currentRun.startTs)
1072
+ state.session.runs.push(state.session.currentRun);
817
1073
  }
818
1074
 
819
1075
  async function analyzeActionableWarnings(files, state) {
@@ -984,12 +1240,18 @@ function pathValues(value, key = "") {
984
1240
  }
985
1241
 
986
1242
  function isExcludedText(text) {
1243
+ // E4: the old match only ever saw the dead `session_start cwd:` line. The
1244
+ // live cwd/root carriers are the pending-resolution mark and the spawn lines.
1245
+ const values = [];
987
1246
  const cwd = /session_start cwd:\s*(.*)$/.exec(text)?.[1];
988
- return cwd
989
- ? excludeGlobs.some((glob) =>
990
- minimatch(normalizePath(cwd), glob, { nocase: true, dot: true }),
991
- )
992
- : false;
1247
+ if (cwd) values.push(cwd);
1248
+ for (const match of text.matchAll(/\b(?:cwd|root)=(\S+)/g))
1249
+ values.push(match[1]);
1250
+ return values.some((value) =>
1251
+ excludeGlobs.some((glob) =>
1252
+ minimatch(normalizePath(value), glob, { nocase: true, dot: true }),
1253
+ ),
1254
+ );
993
1255
  }
994
1256
 
995
1257
  async function forEachLine(file, visitor) {
@@ -1200,19 +1462,18 @@ function summarizeCascade(entry) {
1200
1462
  }
1201
1463
 
1202
1464
  function summarizeReadGuard(entry) {
1465
+ const md = entry.metadata ?? {};
1466
+ // R2: the old offset/limit/symbol fields were undefined on 100% of rows.
1467
+ // `touchedLines[0]`/`range[0]` are the real line identity the rows carry.
1468
+ const touched = Array.isArray(md.touchedLines) ? md.touchedLines : [];
1469
+ const range = Array.isArray(md.range) ? md.range : [];
1203
1470
  return {
1204
1471
  ts: entry.ts,
1205
1472
  event: entry.event,
1206
1473
  filePath: shortPath(entry.filePath),
1207
1474
  project: projectOf(entry.filePath),
1208
- requestedOffset: entry.requestedOffset,
1209
- requestedLimit: entry.requestedLimit,
1210
- effectiveOffset: entry.effectiveOffset,
1211
- effectiveLimit: entry.effectiveLimit,
1212
- symbol: entry.symbol,
1213
- symbolKind: entry.symbolKind,
1214
- line: entry.symbolStartLine,
1215
- metadata: entry.metadata,
1475
+ line: touched[0] ?? range[0],
1476
+ metadata: md,
1216
1477
  };
1217
1478
  }
1218
1479
 
@@ -1295,9 +1556,613 @@ function normalizePath(filePath) {
1295
1556
  return String(filePath).replace(/\\/g, "/");
1296
1557
  }
1297
1558
 
1559
+ /** One D3/D4/D5/D8 run, opened by a `session_start fired` line. */
1560
+ function newRun() {
1561
+ return {
1562
+ startTs: null,
1563
+ commit: null,
1564
+ edits: 0,
1565
+ ran: 0,
1566
+ failedFirst: 0,
1567
+ crossCheckout: 0,
1568
+ excluded: 0,
1569
+ excludedTestFiles: [],
1570
+ noTestFile: 0,
1571
+ retainingNewerTurn: 0,
1572
+ testFirings: 0,
1573
+ testStale: 0,
1574
+ };
1575
+ }
1576
+
1577
+ /** The checkout a turn-end path belongs to (`.worktrees/<id>/` or the main `src/`). */
1578
+ function checkoutOf(p) {
1579
+ const m = /\.worktrees\/([^/]+)\//.exec(p);
1580
+ if (m) return m[1];
1581
+ if (/^(?:src|tests?)\//.test(p)) return "main";
1582
+ return null;
1583
+ }
1584
+
1585
+ /**
1586
+ * D2: the markers only a test home carries: the #3521 fork-tree witness home
1587
+ * and the suite's `pi-lens-test-*` temp dirs. `pi-lens-worktrees`,
1588
+ * `pi-lens-orchestrator/tmp` and `.probe-home/` are not markers: real
1589
+ * sessions edit there (the orchestrator writes its task files under
1590
+ * `.probe-home/orchestration/`).
1591
+ */
1592
+ const SCRATCH_PATH_RE = /(witness-home|pi-lens-test-)/;
1593
+
1594
+ /**
1595
+ * E5/D2: the `opaque_mutation_*` phases log the bash command as `filePath`
1596
+ * (clients/runtime-tool-call.ts, clients/runtime-tool-result.ts), except
1597
+ * `opaque_mutation_recovered`, which logs the recovered paths.
1598
+ */
1599
+ function isCommandTextRow(entry) {
1600
+ const phase = String(entry.phase ?? "");
1601
+ return (
1602
+ phase.startsWith("opaque_mutation_") &&
1603
+ phase !== "opaque_mutation_recovered"
1604
+ );
1605
+ }
1606
+
1607
+ /** E5: track a latency row's project unless its `filePath` is a shell command. */
1608
+ function trackLatencyProject(state, entry) {
1609
+ const filePath = entry?.filePath;
1610
+ if (typeof filePath !== "string" || filePath.length === 0) return;
1611
+ if (isCommandTextRow(entry)) return;
1612
+ // The `<pi-lens>` sentinel is never a project path.
1613
+ if (filePath.startsWith("<")) return;
1614
+ state.projects.inc(projectOf(filePath));
1615
+ }
1616
+
1617
+ function trackLatencyPollution(state, entry) {
1618
+ if (isCommandTextRow(entry)) return;
1619
+ const hit = pathValues(entry).some((value) => SCRATCH_PATH_RE.test(value));
1620
+ if (!hit) return;
1621
+ const pid = String(entry.pid ?? "unknown");
1622
+ state.latency.scratchRows.set(
1623
+ pid,
1624
+ (state.latency.scratchRows.get(pid) ?? 0) + 1,
1625
+ );
1626
+ }
1627
+
1628
+ /**
1629
+ * Every latency signal the D5/D6/D7/D9/D11-D15 detectors read. Kept in one
1630
+ * function so the streaming visitor stays a thin fan-out.
1631
+ */
1632
+ function trackLatencySignals(state, entry, ts) {
1633
+ const ms = ts instanceof Date ? ts.getTime() : null;
1634
+ if (ms != null && Number.isFinite(ms)) state.latency.rowTs.push(ms);
1635
+ const pid = String(entry.pid ?? "unknown");
1636
+ if (ms != null && Number.isFinite(ms)) {
1637
+ const first = state.latency.pidFirstTs.get(pid);
1638
+ if (first == null || ms < first) state.latency.pidFirstTs.set(pid, ms);
1639
+ const last = state.latency.pidLastTs.get(pid);
1640
+ if (last == null || ms > last) state.latency.pidLastTs.set(pid, ms);
1641
+ }
1642
+ trackLatencyPollution(state, entry);
1643
+
1644
+ if (entry.type === "runner") {
1645
+ const md = entry.metadata ?? {};
1646
+ if (
1647
+ entry.status === "failed" &&
1648
+ md.tier === "collect-later" &&
1649
+ Number(entry.diagnosticCount ?? 0) > 0 &&
1650
+ runnerFailureKind(entry) === "blocking_diagnostics"
1651
+ ) {
1652
+ state.latency.deferredRunnerFailed.push({
1653
+ ts: entry.ts,
1654
+ ms,
1655
+ pid,
1656
+ turnId: entry.turnId,
1657
+ runnerId: entry.runnerId,
1658
+ diagnosticCount: Number(entry.diagnosticCount ?? 0),
1659
+ filePath: entry.filePath,
1660
+ });
1661
+ }
1662
+ return;
1663
+ }
1664
+
1665
+ if (entry.type === "tool_result") {
1666
+ // D8: the turn_end summary row carries `blockerSections`; the existing
1667
+ // tool_result branch only counts `result`, so it never saw this duration.
1668
+ if (entry.metadata && entry.metadata.blockerSections != null) {
1669
+ const rows = state.latency.turnEndTools.get(pid) ?? [];
1670
+ rows.push({
1671
+ ts: entry.ts,
1672
+ ms,
1673
+ durationMs: Number(entry.durationMs ?? 0),
1674
+ });
1675
+ state.latency.turnEndTools.set(pid, rows);
1676
+ }
1677
+ return;
1678
+ }
1679
+ if (entry.type !== "phase") return;
1680
+
1681
+ const phase = entry.phase ?? "unknown";
1682
+ const md = entry.metadata ?? {};
1683
+ const nowIso = entry.ts;
1684
+
1685
+ if (phase === "test_runner_delivery") {
1686
+ const sid = md.sessionId ?? pid;
1687
+ const c = state.latency.testRunnerDelivery.get(sid) ?? counter();
1688
+ c.inc(md.outcome ?? "unknown");
1689
+ state.latency.testRunnerDelivery.set(sid, c);
1690
+ } else if (phase === "knip") {
1691
+ if (
1692
+ md.execution === "executed" &&
1693
+ Number.isFinite(Number(md.totalIssues))
1694
+ ) {
1695
+ const rows = state.latency.knip.get(pid) ?? [];
1696
+ rows.push({
1697
+ ts: nowIso,
1698
+ ms,
1699
+ durationMs: Number(entry.durationMs ?? 0),
1700
+ totalIssues: Number(md.totalIssues),
1701
+ });
1702
+ state.latency.knip.set(pid, rows);
1703
+ }
1704
+ } else if (phase === "degradation_ledger") {
1705
+ const kind = md.kind ?? "unknown";
1706
+ const perPid = state.latency.degradationKinds.get(pid) ?? new Map();
1707
+ perPid.set(kind, Math.max(perPid.get(kind) ?? 0, Number(md.count ?? 0)));
1708
+ state.latency.degradationKinds.set(pid, perPid);
1709
+ if (kind === "hook-await-exceeded") {
1710
+ const budgetMs = Number(md.budgetMs);
1711
+ const elapsedMs = Number(md.elapsedMs);
1712
+ state.latency.hookAwaitExceeded.push({
1713
+ ts: nowIso,
1714
+ pid,
1715
+ hook: md.hook,
1716
+ label: md.label,
1717
+ budgetMs,
1718
+ elapsedMs,
1719
+ cause: md.cause,
1720
+ ratio: budgetMs > 0 ? elapsedMs / budgetMs : 0,
1721
+ });
1722
+ }
1723
+ } else if (phase === "lsp_client_wait_timeout") {
1724
+ const serverIds = Array.isArray(md.serverIds) ? md.serverIds : [];
1725
+ if (serverIds.length === 0) {
1726
+ const cur = state.latency.lspWaitEmpty.get(pid) ?? { ms: 0, rows: 0 };
1727
+ cur.ms += Number(entry.durationMs ?? 0);
1728
+ cur.rows += 1;
1729
+ state.latency.lspWaitEmpty.set(pid, cur);
1730
+ }
1731
+ } else if (phase === "lsp_touch_file") {
1732
+ const cur = state.latency.lspTouchEdit.get(pid) ?? {
1733
+ rows: 0,
1734
+ noClients: 0,
1735
+ };
1736
+ if (md.source === "tool_call:edit") {
1737
+ cur.rows += 1;
1738
+ if (md.failureKind === "no_clients_none_spawning") cur.noClients += 1;
1739
+ }
1740
+ state.latency.lspTouchEdit.set(pid, cur);
1741
+ if (
1742
+ md.source === "tool_call:edit" &&
1743
+ md.failureKind === "no_clients_none_spawning"
1744
+ ) {
1745
+ state.latency.lspTouchNoClients.push({
1746
+ ts: nowIso,
1747
+ ms,
1748
+ pid,
1749
+ filePath: entry.filePath,
1750
+ });
1751
+ }
1752
+ } else if (phase === "lsp_client_selected") {
1753
+ if (md.outcome === "warm-reuse") {
1754
+ state.latency.lspClientSelectedWarm.push({
1755
+ ts: nowIso,
1756
+ ms,
1757
+ pid,
1758
+ filePath: entry.filePath,
1759
+ });
1760
+ }
1761
+ } else if (phase === "read_guard_branch_retained") {
1762
+ state.latency.carryRestart.push({
1763
+ ts: nowIso,
1764
+ pid,
1765
+ trigger: md.trigger,
1766
+ source: md.source,
1767
+ kept: Number(md.kept ?? 0),
1768
+ dropped: Number(md.dropped ?? 0),
1769
+ branchToolResults: Number(md.branchToolResults ?? 0),
1770
+ branchReadable: md.branchReadable === true,
1771
+ });
1772
+ } else if (phase === "agent_nudge") {
1773
+ state.latency.agentNudges.push({
1774
+ ts: nowIso,
1775
+ ms,
1776
+ pid,
1777
+ originCrossProcess: Number(md.originCrossProcess ?? 0),
1778
+ originLocal: Number(md.originLocal ?? 0),
1779
+ reasonMix: md.reasonMix,
1780
+ });
1781
+ } else if (phase === "session_scope_transition") {
1782
+ state.latency.sessionScopeTransitions.push({
1783
+ ts: nowIso,
1784
+ ms,
1785
+ pid,
1786
+ handoffSource: md.handoffSource,
1787
+ sessionId: md.sessionId,
1788
+ });
1789
+ } else if (phase === "late_runner_findings") {
1790
+ state.latency.lateRunnerFindings.push({
1791
+ ts: nowIso,
1792
+ ms,
1793
+ pid,
1794
+ turnId: entry.turnId,
1795
+ failed: Number(md.failed ?? 0),
1796
+ delivered: Number(md.delivered ?? 0),
1797
+ dropped: Number(md.dropped ?? 0),
1798
+ pending: Number(md.pending ?? 0),
1799
+ });
1800
+ } else if (phase === "late_auxiliary_findings") {
1801
+ const pairs = Array.isArray(md.stuckPairs) ? md.stuckPairs : [];
1802
+ for (const pair of pairs) {
1803
+ if (!pair?.filePath || !pair?.serverId) continue;
1804
+ const key = `${pid}\u0000${pair.filePath}\u0000${pair.serverId}`;
1805
+ state.latency.auxStuck.set(
1806
+ key,
1807
+ (state.latency.auxStuck.get(key) ?? 0) + 1,
1808
+ );
1809
+ }
1810
+ } else if (phase === "advisory_provenance_decision") {
1811
+ const reasons = Array.isArray(md.reasons) ? md.reasons : [];
1812
+ // The malformed reason implies decision "historical": the validator
1813
+ // returns status "unknown" with it (clients/advisory-provenance.ts) and
1814
+ // the row logs every non-current status as historical
1815
+ // (clients/runtime-context.ts), so the reason alone is the rule.
1816
+ if (reasons.includes("malformed-or-legacy-provenance")) {
1817
+ state.latency.advisoryProvenance.push({
1818
+ ts: nowIso,
1819
+ ms,
1820
+ pid,
1821
+ reasons,
1822
+ provenanceStamp: md.provenanceStamp,
1823
+ advisoryKind: md.advisoryKind,
1824
+ });
1825
+ }
1826
+ }
1827
+ }
1828
+
1829
+ /** D2: extension.log rows that name a test home. */
1830
+ async function analyzeExtension(files, state) {
1831
+ for (const file of files) {
1832
+ await forEachJsonLine(file, "extension", state, (entry) => {
1833
+ const ts = dateOf(entry.ts);
1834
+ if (!inWindow(ts)) return;
1835
+ state.seen.inc("extension");
1836
+ if (SCRATCH_PATH_RE.test(JSON.stringify(entry))) {
1837
+ const pid = String(entry.pid ?? "unknown");
1838
+ state.extension.scratchRows.set(
1839
+ pid,
1840
+ (state.extension.scratchRows.get(pid) ?? 0) + 1,
1841
+ );
1842
+ }
1843
+ const level = String(entry.level ?? "").toLowerCase();
1844
+ if (level === "warn" || level === "error") {
1845
+ const message = String(entry.message ?? "").slice(0, 80);
1846
+ state.extension.warnErrorGroups.inc(
1847
+ `${entry.subsystem ?? "unknown"}: ${message}`,
1848
+ );
1849
+ }
1850
+ });
1851
+ }
1852
+ }
1853
+
1854
+ function countBetween(sorted, a, b) {
1855
+ let n = 0;
1856
+ for (const value of sorted) {
1857
+ if (value > a && value < b) n += 1;
1858
+ else if (value >= b) break;
1859
+ }
1860
+ return n;
1861
+ }
1862
+
1863
+ /** D1: latency gaps >= 10 min that a live session filled with >= 20 rows. */
1864
+ function computeCoverageGaps(state) {
1865
+ const lat = [...state.latency.rowTs].sort((a, b) => a - b);
1866
+ const ss = [...state.session.rowTs].sort((a, b) => a - b);
1867
+ const cas = [...state.latency.cascadeTs].sort((a, b) => a - b);
1868
+ const gaps = [];
1869
+ for (let i = 1; i < lat.length; i += 1) {
1870
+ const a = lat[i - 1];
1871
+ const b = lat[i];
1872
+ const minutes = (b - a) / 60000;
1873
+ if (minutes < 10) continue;
1874
+ const sessionstartRows = countBetween(ss, a, b);
1875
+ if (sessionstartRows < 20) continue;
1876
+ gaps.push({
1877
+ start: new Date(a).toISOString(),
1878
+ end: new Date(b).toISOString(),
1879
+ minutes: Math.round(minutes),
1880
+ sessionstartRows,
1881
+ cascadeRows: countBetween(cas, a, b),
1882
+ });
1883
+ }
1884
+ return gaps;
1885
+ }
1886
+
1887
+ /** D5: per-session firing/stale text and per-session delivery outcomes. */
1888
+ function computeTestRunnerHealth(state) {
1889
+ const runs = state.session.runs.map((r) => ({
1890
+ startTs: r.startTs,
1891
+ firings: r.testFirings,
1892
+ stale: r.testStale,
1893
+ }));
1894
+ const staleRuns = runs.filter(
1895
+ (r) => r.firings >= 10 && r.stale / r.firings >= 0.5,
1896
+ );
1897
+ const firings = runs.reduce((n, r) => n + r.firings, 0);
1898
+ const stale = runs.reduce((n, r) => n + r.stale, 0);
1899
+ const sessions = [];
1900
+ for (const [sessionId, c] of state.latency.testRunnerDelivery) {
1901
+ const total = c.entries().reduce((n, [, v]) => n + v, 0);
1902
+ const delivered = c.get("delivered");
1903
+ sessions.push({
1904
+ sessionId,
1905
+ total,
1906
+ staged: c.get("staged"),
1907
+ eligible: c.get("eligible"),
1908
+ delivered,
1909
+ superseded: c.get("superseded"),
1910
+ deliveredShare: total ? delivered / total : 0,
1911
+ });
1912
+ }
1913
+ const lowDelivery = sessions.filter(
1914
+ (s) => s.total >= 10 && s.deliveredShare < 0.25,
1915
+ );
1916
+ return {
1917
+ firings,
1918
+ stale,
1919
+ staleShare: firings ? stale / firings : 0,
1920
+ staleRuns,
1921
+ sessions,
1922
+ lowDelivery,
1923
+ };
1924
+ }
1925
+
1926
+ /** D6: scanner issue-count drift and turn-end knip wall cost, per pid. */
1927
+ function computeKnip(state) {
1928
+ const drift = [];
1929
+ const cost = [];
1930
+ for (const [pid, rowsRaw] of state.latency.knip) {
1931
+ const rows = [...rowsRaw]
1932
+ .filter((r) => r.ms != null)
1933
+ .sort((a, b) => a.ms - b.ms);
1934
+ if (rows.length >= 10) {
1935
+ const issues = rows.map((r) => r.totalIssues);
1936
+ let increments = 0;
1937
+ for (let i = 1; i < issues.length; i += 1)
1938
+ if (issues[i] - issues[i - 1] >= 100) increments += 1;
1939
+ const min = Math.min(...issues);
1940
+ const max = Math.max(...issues);
1941
+ const spread = min > 0 ? (max - min) / min : 0;
1942
+ if (increments >= 5 || spread >= 0.25)
1943
+ drift.push({ pid, rows: rows.length, increments, min, max, spread });
1944
+ }
1945
+ const first = state.latency.pidFirstTs.get(pid);
1946
+ const last = state.latency.pidLastTs.get(pid);
1947
+ const hours = first != null && last != null ? (last - first) / 3600000 : 0;
1948
+ const totalMs = rows.reduce((n, r) => n + r.durationMs, 0);
1949
+ const maxRow = rows.reduce((n, r) => Math.max(n, r.durationMs), 0);
1950
+ // A lifetime under an hour counts as one hour, so a short pid's few
1951
+ // seconds of knip cannot extrapolate to a large hourly rate.
1952
+ const perHour = totalMs / Math.max(hours, 1);
1953
+ if (perHour >= 30000 || maxRow >= 5000)
1954
+ cost.push({ pid, rows: rows.length, totalMs, hours, perHour, maxRow });
1955
+ }
1956
+ return { drift, cost };
1957
+ }
1958
+
1959
+ /** D7: hook deopts that overran their budget, plus the degradation census. */
1960
+ function computeHookAwait(state) {
1961
+ const rows = [...state.latency.hookAwaitExceeded].sort((a, b) =>
1962
+ String(b.ts).localeCompare(String(a.ts)),
1963
+ );
1964
+ const census = [];
1965
+ for (const [pid, kinds] of state.latency.degradationKinds) {
1966
+ census.push({
1967
+ pid,
1968
+ kinds: [...kinds.entries()]
1969
+ .sort((a, b) => b[1] - a[1])
1970
+ .slice(0, 12)
1971
+ .map(([kind, count]) => `${kind}=${count}`),
1972
+ });
1973
+ }
1974
+ return { rows, over: rows.filter((r) => r.ratio >= 1.1).length, census };
1975
+ }
1976
+
1977
+ /** D8: turn_end hook duration per pid, and the retained-turn-state runs. */
1978
+ function computeTurnEndSlow(state) {
1979
+ const flagged = [];
1980
+ for (const [pid, rows] of state.latency.turnEndTools) {
1981
+ const slow = rows.filter((r) => r.durationMs > 3000).length;
1982
+ const max = rows.reduce((n, r) => Math.max(n, r.durationMs), 0);
1983
+ const share = rows.length ? slow / rows.length : 0;
1984
+ if ((rows.length >= 20 && share >= 0.1) || max >= 8000)
1985
+ flagged.push({ pid, rows: rows.length, slow, share, max });
1986
+ }
1987
+ const retainRuns = state.session.runs
1988
+ .filter((r) => r.retainingNewerTurn >= 5)
1989
+ .map((r) => ({ start: r.startTs, count: r.retainingNewerTurn }));
1990
+ return { flagged, retainRuns };
1991
+ }
1992
+
1993
+ /** D9: empty-candidate waits, edit touches with no client, warm-reuse clashes. */
1994
+ function computeLspWait(state) {
1995
+ const empty = [];
1996
+ for (const [pid, cur] of state.latency.lspWaitEmpty)
1997
+ if (cur.ms >= 5000) empty.push({ pid, ms: cur.ms, rows: cur.rows });
1998
+ const noClients = [];
1999
+ for (const [pid, cur] of state.latency.lspTouchEdit)
2000
+ if (cur.rows >= 20 && cur.noClients / cur.rows >= 0.2)
2001
+ noClients.push({
2002
+ pid,
2003
+ rows: cur.rows,
2004
+ noClients: cur.noClients,
2005
+ share: cur.noClients / cur.rows,
2006
+ });
2007
+ const contradictions = [];
2008
+ for (const touch of state.latency.lspTouchNoClients) {
2009
+ const match = state.latency.lspClientSelectedWarm.find(
2010
+ (w) =>
2011
+ w.pid === touch.pid &&
2012
+ w.filePath === touch.filePath &&
2013
+ touch.ms != null &&
2014
+ w.ms != null &&
2015
+ Math.abs(w.ms - touch.ms) <= 500,
2016
+ );
2017
+ if (match)
2018
+ contradictions.push({
2019
+ pid: touch.pid,
2020
+ filePath: touch.filePath,
2021
+ touchTs: touch.ts,
2022
+ selectedTs: match.ts,
2023
+ });
2024
+ }
2025
+ const pids = new Set([
2026
+ ...empty.map((e) => e.pid),
2027
+ ...noClients.map((e) => e.pid),
2028
+ ...contradictions.map((c) => c.pid),
2029
+ ]);
2030
+ return { empty, noClients, contradictions, pidCount: pids.size };
2031
+ }
2032
+
2033
+ /** D11: a restart kept nothing while the branch held a populated read set. */
2034
+ function computeCarryRestart(state) {
2035
+ return state.latency.carryRestart.filter(
2036
+ (r) =>
2037
+ ["startup", "resume", "fork", "reload"].includes(r.trigger) &&
2038
+ r.source !== "none" &&
2039
+ r.kept + r.dropped === 0 &&
2040
+ r.branchToolResults >= 50 &&
2041
+ r.branchReadable,
2042
+ );
2043
+ }
2044
+
2045
+ /** D12: a cross-process nudge right after a sidecar handoff (suspect grade). */
2046
+ function computeRestartSelfNudge(state) {
2047
+ const flags = [];
2048
+ for (const nudge of state.latency.agentNudges) {
2049
+ if (nudge.originCrossProcess < 1) continue;
2050
+ const transition = state.latency.sessionScopeTransitions.find(
2051
+ (t) =>
2052
+ t.pid === nudge.pid &&
2053
+ ["own-sidecar", "parent-sidecar"].includes(t.handoffSource) &&
2054
+ nudge.ms != null &&
2055
+ t.ms != null &&
2056
+ nudge.ms >= t.ms &&
2057
+ nudge.ms - t.ms <= 300000,
2058
+ );
2059
+ if (transition) flags.push({ ...nudge, transitionTs: transition.ts });
2060
+ }
2061
+ return flags;
2062
+ }
2063
+
2064
+ /** D13: a collect-later runner failed with findings and nothing was delivered. */
2065
+ function computeDeferredRunner(state) {
2066
+ const flags = [];
2067
+ for (const runner of state.latency.deferredRunnerFailed) {
2068
+ const delivery = state.latency.lateRunnerFindings.find(
2069
+ (f) =>
2070
+ f.pid === runner.pid &&
2071
+ f.turnId === runner.turnId &&
2072
+ (runner.ms == null || f.ms == null || f.ms >= runner.ms),
2073
+ );
2074
+ if (
2075
+ delivery &&
2076
+ delivery.failed >= 1 &&
2077
+ delivery.delivered === 0 &&
2078
+ delivery.dropped === 0
2079
+ )
2080
+ flags.push({
2081
+ ...runner,
2082
+ deliveryTs: delivery.ts,
2083
+ pending: delivery.pending,
2084
+ });
2085
+ }
2086
+ return flags;
2087
+ }
2088
+
2089
+ /** D14: an auxiliary (file, server) pair stuck in two or more turn ends. */
2090
+ function computeAuxStuck(state) {
2091
+ const flagged = [];
2092
+ for (const [key, count] of state.latency.auxStuck) {
2093
+ if (count < 2) continue;
2094
+ const [pid, filePath, serverId] = key.split("\u0000");
2095
+ flagged.push({ pid, filePath, serverId, count });
2096
+ }
2097
+ flagged.sort((a, b) => b.count - a.count);
2098
+ return flagged;
2099
+ }
2100
+
2101
+ /** D15: `historical` provenance with a malformed/legacy stamp. */
2102
+ function computeAdvisoryProvenance(state) {
2103
+ return state.latency.advisoryProvenance.map((row) => {
2104
+ const first = state.latency.pidFirstTs.get(row.pid);
2105
+ const seconds =
2106
+ first != null && row.ms != null
2107
+ ? Math.round((row.ms - first) / 1000)
2108
+ : null;
2109
+ return { ...row, secondsSinceFirstRow: seconds };
2110
+ });
2111
+ }
2112
+
2113
+ /** D16: `pi-lens loaded: Nms` loads over 2 s. A load with no
2114
+ * `session_start fired` within the next 60 s is a short-lived pid. */
2115
+ function computeSlowExtensionLoad(state) {
2116
+ const fired = state.session.firedTs;
2117
+ return state.session.slowLoads
2118
+ .filter((l) => l.durationMs >= 2000)
2119
+ .map((l) => ({
2120
+ ...l,
2121
+ shortLived: !(
2122
+ Number.isFinite(l.ms) &&
2123
+ fired.some((f) => f >= l.ms && f - l.ms <= 60000)
2124
+ ),
2125
+ }));
2126
+ }
2127
+
1298
2128
  function buildReport(state) {
1299
2129
  const smells = [];
1300
2130
  const smellCount = (id) => state.smellTotals.get(id);
2131
+
2132
+ // D1-D16 detector computations. Kept out of the smell list so every value
2133
+ // they produce is assertable on its own, not only through a smell count.
2134
+ const coverageGaps = computeCoverageGaps(state);
2135
+ const testRunnerHealth = computeTestRunnerHealth(state);
2136
+ const knip = computeKnip(state);
2137
+ const hookAwait = computeHookAwait(state);
2138
+ const turnEndSlow = computeTurnEndSlow(state);
2139
+ const lspWait = computeLspWait(state);
2140
+ const carryRestart = computeCarryRestart(state);
2141
+ const restartSelfNudge = computeRestartSelfNudge(state);
2142
+ const deferredRunner = computeDeferredRunner(state);
2143
+ const auxStuck = computeAuxStuck(state);
2144
+ const advisoryProvenance = computeAdvisoryProvenance(state);
2145
+ const slowExtensionLoad = computeSlowExtensionLoad(state);
2146
+ const latencyScratch = [...state.latency.scratchRows.values()].reduce(
2147
+ (n, v) => n + v,
2148
+ 0,
2149
+ );
2150
+ const extensionScratch = [...state.extension.scratchRows.values()].reduce(
2151
+ (n, v) => n + v,
2152
+ 0,
2153
+ );
2154
+ const d3Runs = state.session.runs.filter((r) => {
2155
+ const excludedTest = r.excludedTestFiles.some((p) =>
2156
+ /\.(test|spec)\.|\/tests?\//.test(p),
2157
+ );
2158
+ return (r.excluded >= 1 && excludedTest) || (r.edits >= 10 && r.ran === 0);
2159
+ });
2160
+ const d4Cross = state.session.runs.reduce(
2161
+ (n, r) => n + (r.crossCheckout >= 3 ? r.crossCheckout : 0),
2162
+ 0,
2163
+ );
2164
+ const testRunnerSmellCount =
2165
+ testRunnerHealth.staleRuns.length + testRunnerHealth.lowDelivery.length;
1301
2166
  addSmell(
1302
2167
  smells,
1303
2168
  "diagnostic-blockers",
@@ -1407,19 +2272,17 @@ function buildReport(state) {
1407
2272
  );
1408
2273
  addSmell(
1409
2274
  smells,
1410
- "read-guard-friction",
1411
- smellCount("read-guard-friction"),
1412
- "Read-guard blocked/warned edits or exact replacement misses",
1413
- [...state.readGuard.blocked, ...state.readGuard.oldTextIssues].slice(
1414
- 0,
1415
- limit,
1416
- ),
2275
+ "read-guard-blocks",
2276
+ state.readGuard.events.get("edit_blocked") +
2277
+ state.readGuard.events.get("edit_preflight_blocked"),
2278
+ "Read-guard blocked edits; host/model provenance is not present on the block rows, and warns and exact-replacement misses are informational",
2279
+ state.readGuard.blocks.slice(0, limit),
1417
2280
  );
1418
2281
  addSmell(
1419
2282
  smells,
1420
2283
  "read-guard-stale-ranges",
1421
2284
  smellCount("read-guard-stale-ranges"),
1422
- "Covered edit ranges whose read snapshot no longer matched current content",
2285
+ `Enforced range mismatches whose read snapshot no longer matched (bypassed-content-match ${state.readGuard.bypassedMismatch} excluded as an allowed edit)`,
1423
2286
  state.readGuard.staleRanges.slice(0, limit),
1424
2287
  );
1425
2288
  addSmell(
@@ -1479,6 +2342,258 @@ function buildReport(state) {
1479
2342
  ws.sweeps.slice(0, limit),
1480
2343
  );
1481
2344
 
2345
+ // D1: a latency gap a live session filled.
2346
+ addSmell(
2347
+ smells,
2348
+ "log-coverage-gap",
2349
+ coverageGaps.length,
2350
+ "Latency stream gap >= 10 min that a live session filled with >= 20 sessionstart rows",
2351
+ coverageGaps.slice(0, limit).map((g) => ({
2352
+ ts: g.start,
2353
+ message: `${g.minutes} min gap ${g.start} -> ${g.end}; sessionstartRows=${g.sessionstartRows}; cascadeRows=${g.cascadeRows}`,
2354
+ })),
2355
+ );
2356
+ // D2: test home markers in a real log. Never added to the
2357
+ // default denylist so the pollution stays visible.
2358
+ addSmell(
2359
+ smells,
2360
+ "real-log-test-pollution",
2361
+ latencyScratch + extensionScratch,
2362
+ `Rows naming a test home (witness-home, pi-lens-test-*) (latency ${latencyScratch}, extension ${extensionScratch}); these never belong in a real log`,
2363
+ [
2364
+ ...[...state.latency.scratchRows.entries()].map(([pid, count]) => ({
2365
+ key: `latency pid ${pid}`,
2366
+ count,
2367
+ })),
2368
+ ...[...state.extension.scratchRows.entries()].map(([pid, count]) => ({
2369
+ key: `extension pid ${pid}`,
2370
+ count,
2371
+ })),
2372
+ ].slice(0, limit),
2373
+ );
2374
+ addSmell(
2375
+ smells,
2376
+ "extension-warn-errors",
2377
+ state.extension.warnErrorGroups.size,
2378
+ "extension.log warn/error groups by subsystem and message prefix",
2379
+ state.extension.warnErrorGroups.top(limit),
2380
+ );
2381
+ // D3: a run that excluded its own test files, or edited without running one.
2382
+ addSmell(
2383
+ smells,
2384
+ "turn-end-tests-excluded",
2385
+ d3Runs.length,
2386
+ "Turn-end runs that skipped test files by policy, or edited >= 10 files and ran no test",
2387
+ d3Runs.slice(0, limit).map((r) => ({
2388
+ ts: r.startTs,
2389
+ message: `edits=${r.edits} ran=${r.ran} excluded=${r.excluded} noTestFile=${r.noTestFile}${
2390
+ r.excludedTestFiles.length ? `: ${r.excludedTestFiles.join(", ")}` : ""
2391
+ }`,
2392
+ })),
2393
+ );
2394
+ // D4: a failed-first target that resolved to a different checkout (#3649).
2395
+ addSmell(
2396
+ smells,
2397
+ "test-target-cross-checkout",
2398
+ d4Cross,
2399
+ "Failed-first test targets resolved to a different checkout than the edited source (regression guard for #3649)",
2400
+ state.session.runs
2401
+ .filter((r) => r.crossCheckout >= 3)
2402
+ .slice(0, limit)
2403
+ .map((r) => ({
2404
+ ts: r.startTs,
2405
+ message: `${r.crossCheckout} cross-checkout of ${r.failedFirst} failed-first`,
2406
+ })),
2407
+ );
2408
+ // D5: sessions whose turn-end verdicts went stale, or were rarely delivered.
2409
+ addSmell(
2410
+ smells,
2411
+ "test-runner-stale-verdicts",
2412
+ testRunnerSmellCount,
2413
+ `Sessions with >= 10 test firings and >= 50% stale (${testRunnerHealth.staleRuns.length}), or >= 10 delivery rows and < 25% delivered (${testRunnerHealth.lowDelivery.length}); window firings ${testRunnerHealth.firings}, stale ${testRunnerHealth.stale}`,
2414
+ [
2415
+ ...testRunnerHealth.staleRuns.map((r) => ({
2416
+ ts: r.startTs,
2417
+ count: r.stale,
2418
+ message: `firings=${r.firings} stale=${r.stale}`,
2419
+ })),
2420
+ ...testRunnerHealth.lowDelivery.map((s) => ({
2421
+ key: s.sessionId,
2422
+ count: s.delivered,
2423
+ message: `delivered ${s.delivered}/${s.total} (${Math.round(
2424
+ s.deliveredShare * 100,
2425
+ )}%), staged ${s.staged}, eligible ${s.eligible}, superseded ${s.superseded}`,
2426
+ })),
2427
+ ].slice(0, limit),
2428
+ );
2429
+ // D6: scanner-count drift and knip wall cost.
2430
+ addSmell(
2431
+ smells,
2432
+ "scanner-count-drift",
2433
+ knip.drift.length,
2434
+ "knip totalIssues rose by >= 100 between consecutive executed runs at least 5 times, or its spread >= 25% (pids with >= 10 executed runs)",
2435
+ knip.drift.slice(0, limit).map((d) => ({
2436
+ key: `pid ${d.pid}`,
2437
+ count: d.increments,
2438
+ message: `issues ${d.min} -> ${d.max} (+${Math.round(
2439
+ d.spread * 100,
2440
+ )}%), ${d.increments} increments >= 100`,
2441
+ })),
2442
+ );
2443
+ addSmell(
2444
+ smells,
2445
+ "turn-end-knip-cost",
2446
+ knip.cost.length,
2447
+ "knip consumed >= 30 s per hour of pid lifetime (a lifetime under an hour counts as one hour), or a single run took >= 5 s",
2448
+ knip.cost.slice(0, limit).map((c) => ({
2449
+ key: `pid ${c.pid}`,
2450
+ count: Math.round(c.perHour),
2451
+ message: `${c.totalMs}ms over ${c.hours.toFixed(2)}h = ${Math.round(
2452
+ c.perHour,
2453
+ )}ms/h, max ${c.maxRow}ms`,
2454
+ })),
2455
+ );
2456
+ // D7: hook deopts that overran their budget.
2457
+ addSmell(
2458
+ smells,
2459
+ "hook-await-exceeded",
2460
+ hookAwait.rows.length,
2461
+ `Hook awaits that overran their budget (${hookAwait.over} with ratio >= 1.1)`,
2462
+ hookAwait.rows.slice(0, limit).map((r) => ({
2463
+ ts: r.ts,
2464
+ message: `${r.hook}:${r.label} ${r.elapsedMs}/${r.budgetMs}ms (${r.ratio.toFixed(
2465
+ 3,
2466
+ )}) pid=${r.pid} cause=${r.cause}`,
2467
+ })),
2468
+ );
2469
+ // D8: turn_end hook duration and retained-state churn.
2470
+ addSmell(
2471
+ smells,
2472
+ "turn-end-slow",
2473
+ turnEndSlow.flagged.length,
2474
+ "turn_end hook duration over budget (a pid with >= 10% of summaries > 3 s, or one >= 8 s)",
2475
+ turnEndSlow.flagged.slice(0, limit).map((f) => ({
2476
+ key: `pid ${f.pid}`,
2477
+ count: f.slow,
2478
+ message: `${f.slow}/${f.rows} over 3s (${Math.round(
2479
+ f.share * 100,
2480
+ )}%), max ${f.max}ms`,
2481
+ })),
2482
+ );
2483
+ addSmell(
2484
+ smells,
2485
+ "turn-end-retained-state",
2486
+ turnEndSlow.retainRuns.length,
2487
+ "Turn-end retained newer turn state at least 5 times in one session",
2488
+ turnEndSlow.retainRuns.slice(0, limit).map((r) => ({
2489
+ ts: r.start,
2490
+ count: r.count,
2491
+ })),
2492
+ );
2493
+ // D9: empty-candidate waits and no-client/edit warm-reuse contradictions.
2494
+ addSmell(
2495
+ smells,
2496
+ "lsp-wait-empty-candidates",
2497
+ lspWait.pidCount,
2498
+ `LSP touch saw no client while a warm client was selected, or waited with an empty candidate set (empty ${lspWait.empty.length}, noClients ${lspWait.noClients.length}, contradictions ${lspWait.contradictions.length})`,
2499
+ [
2500
+ ...lspWait.empty.map((e) => ({
2501
+ key: `pid ${e.pid}`,
2502
+ count: e.rows,
2503
+ message: `${e.ms}ms waiting with no candidate server`,
2504
+ })),
2505
+ ...lspWait.noClients.map((e) => ({
2506
+ key: `pid ${e.pid}`,
2507
+ count: Math.round(e.share * 100),
2508
+ message: `${e.noClients}/${e.rows} edits saw no client (${Math.round(
2509
+ e.share * 100,
2510
+ )}%)`,
2511
+ })),
2512
+ ...lspWait.contradictions.map((c) => ({
2513
+ key: `pid ${c.pid}`,
2514
+ count: 1,
2515
+ message: `${c.filePath}: no-client touch at ${c.touchTs}, warm-reuse at ${c.selectedTs}`,
2516
+ })),
2517
+ ].slice(0, limit),
2518
+ );
2519
+ // D10: a zero_read block that contradicts earlier read/edit evidence.
2520
+ addSmell(
2521
+ smells,
2522
+ "resume-state-loss",
2523
+ state.readGuard.stateLost.length,
2524
+ `zero_read edits blocked despite earlier read/edit evidence in the same session (genuine ${state.readGuard.genuineZeroRead.length})`,
2525
+ state.readGuard.stateLost.slice(0, limit),
2526
+ );
2527
+ // D11: a restart whose read-set carry was empty while the branch was populated.
2528
+ addSmell(
2529
+ smells,
2530
+ "carry-empty-restart",
2531
+ carryRestart.length,
2532
+ "Restart carry kept and dropped nothing while the branch held a populated read set",
2533
+ carryRestart.slice(0, limit).map((r) => ({
2534
+ key: `pid ${r.pid}`,
2535
+ count: r.branchToolResults,
2536
+ message: `trigger=${r.trigger} source=${r.source} kept=${r.kept} dropped=${r.dropped} branchToolResults=${r.branchToolResults}`,
2537
+ })),
2538
+ );
2539
+ // D12: a cross-process nudge right after a sidecar handoff (suspect until O7).
2540
+ addSmell(
2541
+ smells,
2542
+ "restart-self-nudge",
2543
+ restartSelfNudge.length,
2544
+ "Cross-process nudge within 300 s of a sidecar handoff (suspect-grade until the nudge carries a file id, O7)",
2545
+ restartSelfNudge.slice(0, limit).map((r) => ({
2546
+ key: `pid ${r.pid}`,
2547
+ count: r.originCrossProcess,
2548
+ message: `${JSON.stringify(r.reasonMix)} crossProcess=${r.originCrossProcess} after ${r.transitionTs}`,
2549
+ })),
2550
+ );
2551
+ // D13: a collect-later runner failed with findings and none were delivered.
2552
+ addSmell(
2553
+ smells,
2554
+ "deferred-runner-failed-undelivered",
2555
+ deferredRunner.length,
2556
+ "collect-later runner failed with findings and the delivery row shows failed>=1, delivered=0, dropped=0 (#3796 witness)",
2557
+ deferredRunner.slice(0, limit).map((r) => ({
2558
+ ts: r.ts,
2559
+ message: `${r.runnerId} pid=${r.pid} turnId=${r.turnId} diagnostics=${r.diagnosticCount} delivery=${r.deliveryTs}`,
2560
+ })),
2561
+ );
2562
+ // D14: an auxiliary (file, server) pair stuck in >= 2 turn ends.
2563
+ addSmell(
2564
+ smells,
2565
+ "aux-stuck-pair",
2566
+ auxStuck.length,
2567
+ "Auxiliary (file, server) pair stuck in >= 2 turn ends",
2568
+ auxStuck.slice(0, limit).map((p) => ({
2569
+ key: p.serverId,
2570
+ count: p.count,
2571
+ message: `${p.filePath} pid=${p.pid}`,
2572
+ })),
2573
+ );
2574
+ // D15: historical provenance with a malformed/legacy stamp.
2575
+ addSmell(
2576
+ smells,
2577
+ "advisory-provenance-unknown",
2578
+ advisoryProvenance.length,
2579
+ "Advisory provenance resolved to historical with a malformed-or-legacy stamp",
2580
+ advisoryProvenance.slice(0, limit).map((r) => ({
2581
+ ts: r.ts,
2582
+ message: `${r.provenanceStamp} (${r.advisoryKind}) ${r.secondsSinceFirstRow}s after pid start`,
2583
+ })),
2584
+ );
2585
+ // D16: extension load time over 2 s.
2586
+ addSmell(
2587
+ smells,
2588
+ "slow-extension-load",
2589
+ slowExtensionLoad.length,
2590
+ "pi-lens loaded >= 2000ms after process start (short-lived: no session_start fired within 60 s)",
2591
+ slowExtensionLoad.slice(0, limit).map((l) => ({
2592
+ ...l,
2593
+ message: `${l.message}${l.shortLived ? " [short-lived]" : ""}`,
2594
+ })),
2595
+ );
2596
+
1482
2597
  return {
1483
2598
  window: state.window,
1484
2599
  filesScanned: Object.fromEntries(
@@ -1549,6 +2664,12 @@ function buildReport(state) {
1549
2664
  0,
1550
2665
  limit,
1551
2666
  ),
2667
+ // E2/D10: the block/warn split and the lost-read-set classification.
2668
+ warns: state.readGuard.warns.slice(0, limit),
2669
+ blockByKind: state.readGuard.blockByKind.toJSON(),
2670
+ bypassedMismatch: state.readGuard.bypassedMismatch,
2671
+ stateLost: state.readGuard.stateLost.slice(0, limit),
2672
+ genuineZeroRead: state.readGuard.genuineZeroRead.slice(0, limit),
1552
2673
  },
1553
2674
  treeSitter: {
1554
2675
  phases: state.treeSitter.phases.toJSON(),
@@ -1559,7 +2680,8 @@ function buildReport(state) {
1559
2680
  session: {
1560
2681
  starts: state.session.starts,
1561
2682
  cwds: state.session.cwds.top(limit),
1562
- rotations: state.session.rotations.toJSON(),
2683
+ commits: state.session.commits.toJSON(),
2684
+ slowLoads: state.session.slowLoads.slice(0, limit),
1563
2685
  errors: state.session.errors.slice(0, limit),
1564
2686
  },
1565
2687
  // #2526: the positive-observability counters behind the
@@ -1602,6 +2724,43 @@ function buildReport(state) {
1602
2724
  .sort((a, b) => b.total - a.total)
1603
2725
  .slice(0, limit * 3),
1604
2726
  },
2727
+ // D1-D16: the per-detector values behind the smells above, so a test can
2728
+ // pin the rule (not only the rendered count) and a reader can see WHY.
2729
+ detectors: {
2730
+ logCoverageGap: { gaps: coverageGaps },
2731
+ realLogTestPollution: {
2732
+ latencyByPid: Object.fromEntries(state.latency.scratchRows),
2733
+ extensionByPid: Object.fromEntries(state.extension.scratchRows),
2734
+ latencyTotal: latencyScratch,
2735
+ extensionTotal: extensionScratch,
2736
+ },
2737
+ turnEndTestsExcluded: {
2738
+ runs: d3Runs.map((r) => ({ ...r })),
2739
+ },
2740
+ testTargetCrossCheckout: {
2741
+ runs: state.session.runs.map((r) => ({
2742
+ startTs: r.startTs,
2743
+ crossCheckout: r.crossCheckout,
2744
+ failedFirst: r.failedFirst,
2745
+ })),
2746
+ },
2747
+ testRunnerStaleVerdicts: testRunnerHealth,
2748
+ knip,
2749
+ hookAwait,
2750
+ turnEndSlow,
2751
+ lspWait,
2752
+ resumeStateLoss: {
2753
+ stateLost: state.readGuard.stateLost,
2754
+ genuine: state.readGuard.genuineZeroRead,
2755
+ },
2756
+ carryEmptyRestart: carryRestart,
2757
+ restartSelfNudge,
2758
+ deferredRunnerFailedUndelivered: deferredRunner,
2759
+ auxStuckPairs: auxStuck,
2760
+ advisoryProvenanceUnknown: advisoryProvenance,
2761
+ slowExtensionLoad,
2762
+ extensionWarnErrors: state.extension.warnErrorGroups.toJSON(),
2763
+ },
1605
2764
  };
1606
2765
  }
1607
2766
 
@@ -1649,6 +2808,60 @@ function printReport(report) {
1649
2808
  }
1650
2809
  }
1651
2810
 
2811
+ // D1/D2/D5/D6/D7: the non-smell breakdown behind the new detectors.
2812
+ const det = report.detectors ?? {};
2813
+ const gap = det.logCoverageGap;
2814
+ if (gap?.gaps?.length) {
2815
+ console.log("\nLog coverage");
2816
+ for (const g of gap.gaps ?? [])
2817
+ console.log(
2818
+ ` gap ${g.minutes}min ${g.start} → ${g.end} sessionstart=${g.sessionstartRows} cascade=${g.cascadeRows}`,
2819
+ );
2820
+ }
2821
+ const warnErrors = Object.entries(det.extensionWarnErrors ?? {});
2822
+ if (warnErrors.length) {
2823
+ console.log("\nExtension diagnostics");
2824
+ for (const [k, v] of warnErrors.slice(0, limit))
2825
+ console.log(` ${String(v).padStart(5)} ${k}`);
2826
+ }
2827
+ const deg = det.hookAwait?.census ?? [];
2828
+ if (deg.length) {
2829
+ console.log("\nDegradation ledger census (max count per pid)");
2830
+ for (const row of deg.slice(0, limit))
2831
+ console.log(` pid ${row.pid}: ${row.kinds.join(", ")}`);
2832
+ }
2833
+ const delivery = det.testRunnerStaleVerdicts;
2834
+ if (delivery) {
2835
+ console.log("\nTest-runner delivery");
2836
+ console.log(
2837
+ ` firings=${delivery.firings} stale=${delivery.stale} (${(
2838
+ delivery.staleShare * 100
2839
+ ).toFixed(1)}%)`,
2840
+ );
2841
+ for (const s of delivery.sessions ?? [])
2842
+ console.log(
2843
+ ` ${s.sessionId}: delivered ${s.delivered}/${s.total} staged=${s.staged} eligible=${s.eligible} superseded=${s.superseded}`,
2844
+ );
2845
+ }
2846
+ const knip = det.knip;
2847
+ if (knip && (knip.drift.length || knip.cost.length)) {
2848
+ console.log("\nknip drift and cost");
2849
+ for (const d of knip.drift)
2850
+ console.log(
2851
+ ` pid ${d.pid}: issues ${d.min} → ${d.max} (${d.increments} increments >= 100)`,
2852
+ );
2853
+ for (const c of knip.cost)
2854
+ console.log(
2855
+ ` pid ${c.pid}: ${Math.round(c.perHour)}ms/h, max ${c.maxRow}ms`,
2856
+ );
2857
+ }
2858
+ const extLoads = det.slowExtensionLoad ?? [];
2859
+ if (extLoads.length) {
2860
+ const shortLived = extLoads.filter((l) => l.shortLived).length;
2861
+ console.log("\nExtension loads");
2862
+ console.log(` slow=${extLoads.length} shortLived=${shortLived}`);
2863
+ }
2864
+
1652
2865
  section(
1653
2866
  "Diagnostic rules",
1654
2867
  report.diagnostics.byRule,
@@ -1705,7 +2918,7 @@ function printReport(report) {
1705
2918
  report.latency.testRunnerVerdicts ?? {},
1706
2919
  );
1707
2920
  if (verdictSessions.length) {
1708
- console.log("\nTest-runner stale verdicts per session");
2921
+ console.log("\nTest-runner stale verdicts per session (verdict rows only)");
1709
2922
  for (const [sessionId, summary] of verdictSessions) {
1710
2923
  console.log(
1711
2924
  ` ${sessionId}: ${summary.stale}/${summary.total} stale (${(summary.rate * 100).toFixed(1)}%)`,