@herbertgao/pi-extensions 2026.8.6 → 2026.8.8

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 (385) hide show
  1. package/README.md +8 -6
  2. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -2
  3. package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -2
  4. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +19 -7
  5. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +30 -9
  6. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +320 -22
  7. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +94 -77
  8. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/message-display.ts +79 -17
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +27 -0
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +66 -17
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +41 -2
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +75 -6
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +7 -3
  14. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +64 -1
  15. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  16. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
  17. package/node_modules/@herbertgao/pi-subagents/README.md +30 -22
  18. package/node_modules/@herbertgao/pi-subagents/examples/agent-tool-description.md +5 -5
  19. package/node_modules/@herbertgao/pi-subagents/package.json +7 -7
  20. package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +7 -1
  21. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +48 -19
  22. package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +17 -13
  23. package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +26 -2
  24. package/node_modules/@herbertgao/pi-subagents/src/index.ts +219 -40
  25. package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +101 -3
  26. package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +18 -4
  27. package/node_modules/@herbertgao/pi-subagents/src/settings.ts +99 -0
  28. package/node_modules/@herbertgao/pi-subagents/src/types.ts +22 -3
  29. package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +51 -3
  30. package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +20 -2
  31. package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +21 -6
  32. package/node_modules/@herbertgao/pi-subagents/src/usage.ts +129 -1
  33. package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +20 -0
  34. package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +5 -4
  35. package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +174 -100
  36. package/node_modules/@juicesharp/rpiv-ask-user-question/config.ts +25 -0
  37. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/configuration.md +13 -4
  38. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +5 -1
  39. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +10 -2
  40. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/localization.md +10 -6
  41. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/tool-schema.md +11 -5
  42. package/node_modules/@juicesharp/rpiv-ask-user-question/locales/en.json +5 -2
  43. package/node_modules/@juicesharp/rpiv-ask-user-question/locales/zh.json +2 -2
  44. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +3 -2
  45. package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +10 -0
  46. package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +140 -97
  47. package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +63 -28
  48. package/node_modules/@juicesharp/rpiv-ask-user-question/state/selectors/projections.ts +22 -15
  49. package/node_modules/@juicesharp/rpiv-ask-user-question/state/state-reducer.ts +11 -1
  50. package/node_modules/@juicesharp/rpiv-ask-user-question/state/state.ts +14 -6
  51. package/node_modules/@juicesharp/rpiv-ask-user-question/tool/response-envelope.ts +11 -0
  52. package/node_modules/@juicesharp/rpiv-ask-user-question/tool/types.ts +11 -0
  53. package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/multi-select-view.ts +31 -17
  54. package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/preview/preview-block-renderer.ts +15 -6
  55. package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/wrapping-select.ts +15 -6
  56. package/node_modules/@juicesharp/rpiv-ask-user-question/view/dialog-builder.ts +86 -38
  57. package/node_modules/@juicesharp/rpiv-ask-user-question/view/tab-content-strategy.ts +76 -9
  58. package/node_modules/@narumitw/pi-btw/README.md +120 -111
  59. package/node_modules/@narumitw/pi-btw/dist/index.ts +2898 -0
  60. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +7 -0
  61. package/node_modules/@narumitw/pi-btw/package.json +10 -6
  62. package/node_modules/@narumitw/pi-btw/src/btw.ts +36 -40
  63. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +55 -10
  64. package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +390 -0
  65. package/node_modules/@narumitw/pi-btw/src/menu.ts +45 -2
  66. package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +136 -45
  67. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +44 -1856
  68. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
  69. package/node_modules/@pi-plugins/fast-mode/package.json +4 -6
  70. package/node_modules/pi-lens/CHANGELOG.md +999 -0
  71. package/node_modules/pi-lens/README.md +117 -3
  72. package/node_modules/pi-lens/config/ruff/core.toml +42 -0
  73. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +130 -27
  74. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +126 -13
  75. package/node_modules/pi-lens/dist/clients/agent-nudge.js +67 -11
  76. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +9 -3
  77. package/node_modules/pi-lens/dist/clients/atomic-write.js +9 -3
  78. package/node_modules/pi-lens/dist/clients/bash-file-access.js +381 -13
  79. package/node_modules/pi-lens/dist/clients/biome-client.js +61 -30
  80. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +428 -0
  81. package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +129 -0
  82. package/node_modules/pi-lens/dist/clients/bootstrap.js +12 -1
  83. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +12 -3
  84. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +206 -0
  85. package/node_modules/pi-lens/dist/clients/cache-observability.js +353 -76
  86. package/node_modules/pi-lens/dist/clients/cascade-budget.js +196 -0
  87. package/node_modules/pi-lens/dist/clients/cascade-format.js +20 -1
  88. package/node_modules/pi-lens/dist/clients/cascade-types.js +9 -1
  89. package/node_modules/pi-lens/dist/clients/child-unref.js +54 -6
  90. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +76 -24
  91. package/node_modules/pi-lens/dist/clients/dead-code-client.js +123 -31
  92. package/node_modules/pi-lens/dist/clients/deadline-utils.js +8 -1
  93. package/node_modules/pi-lens/dist/clients/debug-handles.js +5 -0
  94. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +84 -14
  95. package/node_modules/pi-lens/dist/clients/demoted-finding-render.js +155 -0
  96. package/node_modules/pi-lens/dist/clients/dependency-checker.js +25 -3
  97. package/node_modules/pi-lens/dist/clients/deps/pi-tui.js +8 -2
  98. package/node_modules/pi-lens/dist/clients/deps/typebox.js +8 -3
  99. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +147 -33
  100. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +298 -0
  101. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +52 -2
  102. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +256 -88
  103. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +7 -4
  104. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +5 -0
  105. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +234 -18
  106. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +187 -19
  107. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +6 -3
  108. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +11 -9
  109. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +398 -0
  110. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +9 -6
  111. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +11 -3
  112. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +12 -7
  113. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +18 -0
  114. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +9 -7
  115. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +895 -0
  116. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +8 -6
  117. package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +4 -0
  118. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +16 -3
  119. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +60 -53
  120. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +16 -2
  121. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +25 -2
  122. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +20 -5
  123. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +44 -11
  124. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +331 -55
  125. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +38 -5
  126. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +97 -19
  127. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +17 -8
  128. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +32 -4
  129. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +47 -3
  130. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +14 -4
  131. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +127 -28
  132. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +12 -7
  133. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +73 -12
  134. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +275 -13
  135. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +21 -6
  136. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +260 -27
  137. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +734 -64
  138. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +86 -11
  139. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +188 -0
  140. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +9 -0
  141. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +21 -10
  142. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +18 -2
  143. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +4 -2
  144. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +28 -5
  145. package/node_modules/pi-lens/dist/clients/extension-log.js +22 -1
  146. package/node_modules/pi-lens/dist/clients/file-kinds.js +8 -2
  147. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +316 -0
  148. package/node_modules/pi-lens/dist/clients/finding-identity.js +88 -0
  149. package/node_modules/pi-lens/dist/clients/formatters-lazy.js +3 -2
  150. package/node_modules/pi-lens/dist/clients/formatters.js +500 -115
  151. package/node_modules/pi-lens/dist/clients/generation-guard.js +216 -0
  152. package/node_modules/pi-lens/dist/clients/git-guard.js +31 -0
  153. package/node_modules/pi-lens/dist/clients/gitleaks-client.js +181 -8
  154. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +109 -9
  155. package/node_modules/pi-lens/dist/clients/grammar-source.js +333 -10
  156. package/node_modules/pi-lens/dist/clients/host-ports.js +8 -0
  157. package/node_modules/pi-lens/dist/clients/installer/index.js +1114 -100
  158. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +58 -0
  159. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +715 -0
  160. package/node_modules/pi-lens/dist/clients/instance-reaper.js +643 -97
  161. package/node_modules/pi-lens/dist/clients/instance-registry.js +87 -17
  162. package/node_modules/pi-lens/dist/clients/jscpd-client.js +87 -8
  163. package/node_modules/pi-lens/dist/clients/knip-client.js +310 -10
  164. package/node_modules/pi-lens/dist/clients/language-policy.js +8 -2
  165. package/node_modules/pi-lens/dist/clients/language-profile.js +9 -2
  166. package/node_modules/pi-lens/dist/clients/latency-logger.js +440 -11
  167. package/node_modules/pi-lens/dist/clients/lazy-import.js +21 -0
  168. package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -0
  169. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
  170. package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +128 -8
  171. package/node_modules/pi-lens/dist/clients/lsp/client.js +1660 -164
  172. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +83 -1
  173. package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +389 -0
  174. package/node_modules/pi-lens/dist/clients/lsp/index.js +2423 -151
  175. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +215 -0
  176. package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +146 -14
  177. package/node_modules/pi-lens/dist/clients/lsp/language.js +48 -4
  178. package/node_modules/pi-lens/dist/clients/lsp/server.js +277 -16
  179. package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +22 -0
  180. package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +43 -0
  181. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +79 -3
  182. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +43 -0
  183. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +422 -28
  184. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +30 -0
  185. package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +175 -0
  186. package/node_modules/pi-lens/dist/clients/lsp-lazy.js +3 -2
  187. package/node_modules/pi-lens/dist/clients/mcp/session.js +10 -2
  188. package/node_modules/pi-lens/dist/clients/module-report.js +22 -1
  189. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +114 -23
  190. package/node_modules/pi-lens/dist/clients/opengrep-client.js +15 -1
  191. package/node_modules/pi-lens/dist/clients/package-manager.js +170 -14
  192. package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +27 -0
  193. package/node_modules/pi-lens/dist/clients/path-utils.js +160 -0
  194. package/node_modules/pi-lens/dist/clients/pipeline.js +154 -33
  195. package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +37 -0
  196. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +17 -3
  197. package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +89 -22
  198. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +84 -14
  199. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +15 -3
  200. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +50 -2
  201. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +23 -9
  202. package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
  203. package/node_modules/pi-lens/dist/clients/project-report.js +62 -27
  204. package/node_modules/pi-lens/dist/clients/project-snapshot.js +299 -0
  205. package/node_modules/pi-lens/dist/clients/quiet-window-config.js +47 -0
  206. package/node_modules/pi-lens/dist/clients/quiet-window.js +11 -25
  207. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +8 -3
  208. package/node_modules/pi-lens/dist/clients/read-guard.js +253 -10
  209. package/node_modules/pi-lens/dist/clients/resource-sampler.js +49 -17
  210. package/node_modules/pi-lens/dist/clients/reverse-deps.js +50 -11
  211. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +194 -31
  212. package/node_modules/pi-lens/dist/clients/review-graph/query.js +52 -4
  213. package/node_modules/pi-lens/dist/clients/review-graph/revision-drift.js +21 -0
  214. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +6 -3
  215. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +96 -7
  216. package/node_modules/pi-lens/dist/clients/runtime-context.js +8 -1
  217. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +352 -45
  218. package/node_modules/pi-lens/dist/clients/runtime-session.js +373 -9
  219. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +217 -22
  220. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +212 -79
  221. package/node_modules/pi-lens/dist/clients/runtime-turn.js +620 -67
  222. package/node_modules/pi-lens/dist/clients/safe-spawn.js +220 -7
  223. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +161 -0
  224. package/node_modules/pi-lens/dist/clients/search-read-registration.js +34 -6
  225. package/node_modules/pi-lens/dist/clients/security-scan-client.js +157 -24
  226. package/node_modules/pi-lens/dist/clients/session-event-guard.js +184 -0
  227. package/node_modules/pi-lens/dist/clients/sg-runner.js +116 -22
  228. package/node_modules/pi-lens/dist/clients/single-flight.js +158 -0
  229. package/node_modules/pi-lens/dist/clients/source-filter.js +6 -2
  230. package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
  231. package/node_modules/pi-lens/dist/clients/startup-scan.js +5 -2
  232. package/node_modules/pi-lens/dist/clients/startup-timing.js +19 -1
  233. package/node_modules/pi-lens/dist/clients/test-runner-client.js +151 -16
  234. package/node_modules/pi-lens/dist/clients/tool-event.js +56 -5
  235. package/node_modules/pi-lens/dist/clients/tool-policy.js +125 -20
  236. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +75 -1
  237. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +769 -64
  238. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +1 -0
  239. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +11 -0
  240. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +90 -0
  241. package/node_modules/pi-lens/dist/clients/trivy-client.js +19 -1
  242. package/node_modules/pi-lens/dist/clients/widget-state.js +336 -36
  243. package/node_modules/pi-lens/dist/clients/zizmor-config.js +214 -14
  244. package/node_modules/pi-lens/dist/index.js +61407 -48577
  245. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +476 -57
  246. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +132 -43
  247. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -7
  248. package/node_modules/pi-lens/docs/agent-guide.md +6 -1
  249. package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +515 -506
  250. package/node_modules/pi-lens/docs/dispositions.md +21 -0
  251. package/node_modules/pi-lens/docs/features.md +19 -5
  252. package/node_modules/pi-lens/docs/globalconfig.md +3 -0
  253. package/node_modules/pi-lens/docs/language-coverage.md +71 -5
  254. package/node_modules/pi-lens/docs/mcp.md +2 -2
  255. package/node_modules/pi-lens/docs/servercapabilities.md +4 -1
  256. package/node_modules/pi-lens/docs/settings.md +19 -1
  257. package/node_modules/pi-lens/docs/usage.md +1 -0
  258. package/node_modules/pi-lens/package.json +27 -10
  259. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-js-snapshot.yml +23 -0
  260. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-snapshot.yml +23 -0
  261. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/ts-void-zero-snapshot.yml +23 -0
  262. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-object-param-test.yml +16 -0
  263. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +15 -1
  264. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-compile-call-test.yml +29 -1
  265. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-dupe-class-members-test.yml +33 -0
  266. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-js-test.yml +7 -1
  267. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-test.yml +7 -1
  268. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-known-value-widening-test.yml +9 -0
  269. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-non-null-assertion-test.yml +216 -0
  270. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +2 -0
  271. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +2 -0
  272. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +2 -1
  273. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +2 -1
  274. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-return-value-in-generator-test.yml +12 -0
  275. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-runtime-typeof-test.yml +33 -0
  276. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-server-bind-wildcard-test.yml +9 -0
  277. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-shape-in-symbol-names-test.yml +13 -0
  278. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-js-test.yml +5 -1
  279. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-test.yml +5 -1
  280. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-parameters-test.yml +12 -0
  281. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-returns-test.yml +16 -0
  282. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-any-test.yml +10 -0
  283. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-unknown-test.yml +8 -0
  284. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/redundant-unsafe-function-test.yml +35 -0
  285. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/require-safety-comment-for-as-unknown-as-test.yml +177 -0
  286. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/ts-void-zero-test.yml +1 -0
  287. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member-js.yml +13 -2
  288. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member.yml +13 -2
  289. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +2 -0
  290. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-object-param.yml +60 -0
  291. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +57 -12
  292. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-compile-call.yml +63 -5
  293. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-dupe-class-members.yml +52 -8
  294. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html-js.yml +27 -2
  295. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html.yml +27 -2
  296. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-known-value-widening.yml +71 -0
  297. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-non-null-assertion.yml +316 -0
  298. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +7 -0
  299. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +22 -2
  300. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +23 -2
  301. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +33 -5
  302. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +34 -8
  303. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-return-value-in-generator.yml +22 -5
  304. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-runtime-typeof.yml +121 -0
  305. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-server-bind-wildcard.yml +23 -7
  306. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-shape-in-symbol-names.yml +68 -0
  307. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code-js.yml +41 -2
  308. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code.yml +41 -2
  309. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +6 -1
  310. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-parameters.yml +67 -0
  311. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-returns.yml +106 -0
  312. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-any.yml +50 -0
  313. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-unknown.yml +56 -0
  314. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +2 -0
  315. package/node_modules/pi-lens/rules/ast-grep-rules/rules/redundant-unsafe-function.yml +32 -0
  316. package/node_modules/pi-lens/rules/ast-grep-rules/rules/require-safety-comment-for-as-unknown-as.yml +184 -0
  317. package/node_modules/pi-lens/rules/ast-grep-rules/rules/ts-void-zero.yml +5 -0
  318. package/node_modules/pi-lens/rules/ast-grep-rules/self-scan-baseline.json +5 -0
  319. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +53 -1
  320. package/node_modules/pi-lens/scripts/download-grammars.js +25 -0
  321. package/node_modules/pi-lens/scripts/grammars.lock.json +9 -0
  322. package/node_modules/pi-lens/scripts/install-selftest.mjs +99 -11
  323. package/node_modules/pi-lens/scripts/lib/host-provided-deps.mjs +75 -0
  324. package/node_modules/pi-lens/scripts/lib/warm-loader-cache.mjs +285 -0
  325. package/node_modules/pi-lens/scripts/warm-loader-cache.mjs +233 -0
  326. package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +2 -0
  327. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +80 -3
  328. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +41 -0
  329. package/node_modules/pi-lens/vendor/grammars/tree-sitter-cue.wasm +0 -0
  330. package/node_modules/pi-mcp-adapter/CHANGELOG.md +36 -0
  331. package/node_modules/pi-mcp-adapter/README.md +47 -5
  332. package/node_modules/pi-mcp-adapter/cli.js +163 -1
  333. package/node_modules/pi-mcp-adapter/commands.ts +128 -22
  334. package/node_modules/pi-mcp-adapter/config.ts +25 -7
  335. package/node_modules/pi-mcp-adapter/direct-tools.ts +5 -4
  336. package/node_modules/pi-mcp-adapter/index.ts +219 -32
  337. package/node_modules/pi-mcp-adapter/init.ts +36 -4
  338. package/node_modules/pi-mcp-adapter/lifecycle.ts +315 -24
  339. package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +39 -6
  340. package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +387 -0
  341. package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +27 -3
  342. package/node_modules/pi-mcp-adapter/mcp-code.ts +4 -0
  343. package/node_modules/pi-mcp-adapter/mcp-panel.ts +42 -13
  344. package/node_modules/pi-mcp-adapter/metadata-cache.ts +32 -21
  345. package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +168 -0
  346. package/node_modules/pi-mcp-adapter/package.json +3 -1
  347. package/node_modules/pi-mcp-adapter/proxy-modes.ts +5 -4
  348. package/node_modules/pi-mcp-adapter/request-headers-command.ts +31 -37
  349. package/node_modules/pi-mcp-adapter/search-ranking.ts +92 -22
  350. package/node_modules/pi-mcp-adapter/server-manager.ts +140 -2
  351. package/node_modules/pi-mcp-adapter/session-recovery.ts +7 -0
  352. package/node_modules/pi-mcp-adapter/tool-approval.ts +15 -2
  353. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +44 -4
  354. package/node_modules/pi-mcp-adapter/types.ts +2 -0
  355. package/node_modules/pi-mcp-adapter/ui-server.ts +18 -16
  356. package/node_modules/pi-mcp-adapter/utils.ts +70 -0
  357. package/node_modules/pi-web-access/CHANGELOG.md +37 -0
  358. package/node_modules/pi-web-access/README.md +32 -13
  359. package/node_modules/pi-web-access/anysearch.ts +4 -2
  360. package/node_modules/pi-web-access/brave.ts +16 -4
  361. package/node_modules/pi-web-access/chrome-cookies.ts +86 -15
  362. package/node_modules/pi-web-access/curator-page.ts +6 -3
  363. package/node_modules/pi-web-access/curator-server.ts +4 -1
  364. package/node_modules/pi-web-access/data-uri-sanitize.ts +406 -0
  365. package/node_modules/pi-web-access/exa.ts +18 -7
  366. package/node_modules/pi-web-access/extract.ts +40 -5
  367. package/node_modules/pi-web-access/firecrawl.ts +18 -2
  368. package/node_modules/pi-web-access/gemini-search.ts +16 -4
  369. package/node_modules/pi-web-access/github-extract.ts +65 -36
  370. package/node_modules/pi-web-access/index.ts +60 -61
  371. package/node_modules/pi-web-access/openai-search.ts +17 -6
  372. package/node_modules/pi-web-access/package.json +1 -1
  373. package/node_modules/pi-web-access/page-query.ts +4 -2
  374. package/node_modules/pi-web-access/parallel-mcp.ts +249 -0
  375. package/node_modules/pi-web-access/parallel.ts +2 -2
  376. package/node_modules/pi-web-access/pdf-extract.ts +18 -5
  377. package/node_modules/pi-web-access/query-rewrite.ts +51 -0
  378. package/node_modules/pi-web-access/serper.ts +211 -0
  379. package/node_modules/pi-web-access/ssrf-protection.ts +12 -2
  380. package/node_modules/pi-web-access/summary-model-scope.ts +12 -4
  381. package/node_modules/pi-web-access/summary-review.ts +44 -22
  382. package/node_modules/pi-web-access/tavily.ts +16 -4
  383. package/node_modules/pi-web-access/utils.ts +87 -0
  384. package/node_modules/pi-web-access/valyu.ts +199 -0
  385. package/package.json +14 -14
@@ -1,6 +1,7 @@
1
1
  import * as nodeFs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { loadBootstrapClients } from "./bootstrap.js";
4
+ import { recordDegradationOnce } from "./degradation-ledger.js";
4
5
  import { detectFileKind } from "./file-kinds.js";
5
6
  import { isPathIgnoredByProject } from "./file-utils.js";
6
7
  import { evaluateGitGuard, isGitCommitOrPushAttempt, } from "./git-guard.js";
@@ -11,12 +12,12 @@ import { getLSPService } from "./lsp/index.js";
11
12
  import { findDocumentSymbolAtLine, getOpenDocumentSymbols, lspSymbolKindName, qualifiedLspSymbolName, } from "./lsp-document-symbols.js";
12
13
  import { computeTrailingWhitespaceOldTextPatch, findUniqueMatchLineRange, } from "./oldtext-autopatch.js";
13
14
  import { applyPartiallyApplicableEdits } from "./partial-edit-apply.js";
14
- import { isExternalOrVendorFile } from "./path-utils.js";
15
+ import { isExternalOrVendorFile, resolveHostPathVariants, resolveHostToolPath, } from "./path-utils.js";
15
16
  import { EXPANSION_BUDGET_MS, EXPANSION_LIMIT_LINES, tryExpandRead, } from "./read-expansion.js";
16
17
  import { boundedIndexesForCount, createReadGuardEditBatchSummary, getReadGuardCorrelationId, logReadGuardEvent, } from "./read-guard-logger.js";
17
18
  import { countFileLines, getTouchedLinesForGuard, relocateEditRange, tryCorrectIndentationMismatch, tryCorrectIndentationMismatchFromContent, } from "./read-guard-tool-lines.js";
18
19
  import { handleToolResult } from "./runtime-tool-result.js";
19
- import { isToolCallEventType } from "./tool-event.js";
20
+ import { isToolCallEventType, resolveToolCallCorrelationId } from "./tool-event.js";
20
21
  import { getSharedTreeSitterClient } from "./tree-sitter-shared.js";
21
22
  const LSP_TOOLCALL_NAV_TOUCH_BUDGET_MS = Math.max(0, Number.parseInt(process.env.PI_LENS_TOOLCALL_NAV_TOUCH_MS ??
22
23
  process.env.PI_LENS_LSP_NAV_CLIENT_WAIT_MS ??
@@ -43,12 +44,41 @@ function getToolCallRawFilePath(toolName, event) {
43
44
  }
44
45
  return undefined;
45
46
  }
47
+ /**
48
+ * Resolve a tool_call's raw path to the file pi will actually touch.
49
+ *
50
+ * The `cwd` basis is the host `ctx.cwd`, which for the pinned host IS the same
51
+ * value the tools were constructed with — `AgentSession` passes its one `_cwd`
52
+ * to both `createAllToolDefinitions`
53
+ * (`@earendil-works/pi-coding-agent/dist/core/agent-session.js:2026`, source
54
+ * `src/core/tools/index.ts:99-124`) and the `ExtensionRunner` behind `ctx.cwd`
55
+ * (`dist/core/agent-session.js:2037`; `runner.js:154`, `:476-479`). Neither is
56
+ * reassigned after construction, so there is no drift TODAY (#1655 item 4).
57
+ * `tests/clients/pi-host-contract.test.ts` pins that, because the day a host
58
+ * lets one move independently, every path here silently retargets.
59
+ *
60
+ * The path is produced the way pi produces it, in pi's two stages (#1655 item
61
+ * 5, plus review F1):
62
+ *
63
+ * 1. `resolveHostToolPath` mirrors pi's BASE resolution, `resolveToCwd`
64
+ * (`dist/core/tools/path-utils.js:42-44`, source
65
+ * `src/core/tools/path-utils.ts:~44-46`) — unicode-space folding, `@`
66
+ * prefix stripping, `~` expansion, `file://` conversion, and Git-Bash
67
+ * drive paths, all BEFORE anything is probed.
68
+ * 2. `resolveHostPathVariants` mirrors pi's fallback LADDER
69
+ * (`dist/core/tools/path-utils.js:45-70`, source
70
+ * `src/core/tools/path-utils.ts:52-83`).
71
+ *
72
+ * Stage 1 was missing in the first cut of this fix, and the ladder cannot
73
+ * stand in for it: an `@`-prefixed path, a `file://` URL, or a non-breaking
74
+ * space are all resolved by pi at stage 1 and are untouched by any of the four
75
+ * stage-2 candidates. A plain `path.resolve` therefore produced a path pi
76
+ * never opens, and the miss looked identical to "file genuinely absent".
77
+ */
46
78
  function resolveToolCallFilePath(rawFilePath, cwd, projectRoot) {
47
79
  if (!rawFilePath)
48
80
  return undefined;
49
- if (path.isAbsolute(rawFilePath))
50
- return rawFilePath;
51
- return path.resolve(cwd ?? projectRoot, rawFilePath);
81
+ return resolveHostPathVariants(resolveHostToolPath(rawFilePath, cwd ?? projectRoot));
52
82
  }
53
83
  function getReadToolInput(toolName, input) {
54
84
  if (toolName !== "read")
@@ -139,18 +169,134 @@ function getNewContentFromToolCall(event) {
139
169
  }
140
170
  return undefined;
141
171
  }
172
+ /**
173
+ * Total guard around the `tool_call` handler body (#1655 item 1).
174
+ *
175
+ * `tool_call` is the ONE pi emit path with no per-handler `try`/`catch`. Every
176
+ * sibling wraps each handler and routes a throw to `emitError`
177
+ * (`emitToolResult` at
178
+ * `@earendil-works/pi-coding-agent/dist/core/extensions/runner.js:649-707`,
179
+ * source `src/core/extensions/runner.ts:877-930`; the generic `emit` at
180
+ * source `runner.ts:801-832`). `emitToolCall`
181
+ * (`dist/core/extensions/runner.js:701-717`, source `runner.ts:932-953`) calls
182
+ * `await handler(event, ctx)` bare, and its caller
183
+ * `AgentSession._installAgentToolHooks`'s `beforeToolCall`
184
+ * (`dist/core/agent-session.js:229-241`, source `agent-session.ts:~228-242`)
185
+ * rethrows: `throw new Error("Extension failed, blocking execution: ...")`.
186
+ *
187
+ * So an unguarded throw anywhere in pi-lens's `tool_call` handler does not
188
+ * degrade pi-lens — it BLOCKS the user's tool call outright. Advisory
189
+ * instrumentation must never be able to do that. Every failure degrades to
190
+ * "pi-lens did nothing for this call" (`undefined`, which pi reads as
191
+ * "no extension opinion") and lands one ledger entry per tool name.
192
+ *
193
+ * Returning `undefined` on a throw is deliberate: a partially-executed handler
194
+ * cannot have earned a `{ block: true }` verdict, and inventing one would turn
195
+ * a pi-lens bug into a refused user tool call — the exact outcome this guard
196
+ * exists to prevent.
197
+ *
198
+ * #1642 F2 (inside the guard): a BLOCKED call (git-guard, read-guard
199
+ * preflight, the duplicate-export check) never gets a paired `tool_result` —
200
+ * the host never lets the tool execute. Any path attribution recorded for it
201
+ * below would otherwise sit in the correlation cache forever (bounded by its
202
+ * LRU cap, but pure garbage that can crowd out a live in-flight record under
203
+ * enough blocked-edit volume — a reviewer-reproduced leak). Clear it eagerly
204
+ * on the way out whenever the call was blocked; a no-op if nothing was
205
+ * recorded (a gitignored SKIP is not a block, so it is unaffected). This
206
+ * cleanup runs INSIDE the try, so a throw out of it is absorbed too.
207
+ */
142
208
  export async function handleToolCall(deps) {
209
+ try {
210
+ const result = await handleToolCallImpl(deps);
211
+ if (result && result.block) {
212
+ // Review F2 — this cleanup gets its OWN catch, and it is not optional
213
+ // tidiness. By the time it runs, `result` is a FINAL `{ block: true }`
214
+ // verdict: the read guard has already refused an edit-without-read, or
215
+ // the git guard has already refused a commit. Letting a throw out of
216
+ // bookkeeping reach the outer catch would convert that verdict into
217
+ // `undefined` — "pi-lens has no opinion" — and the refused edit would
218
+ // execute. A guard that fails OPEN because its telemetry broke is
219
+ // worse than no guard, so the verdict is returned regardless of what
220
+ // the cleanup does.
221
+ try {
222
+ const toolCallId = resolveToolCallCorrelationId(deps.event);
223
+ if (toolCallId !== undefined) {
224
+ deps.runtime.takeToolCallAttribution(toolCallId);
225
+ }
226
+ }
227
+ catch (cleanupError) {
228
+ const reason = cleanupError instanceof Error
229
+ ? cleanupError.message
230
+ : String(cleanupError);
231
+ recordDegradationOnce({
232
+ kind: "tool-call-handler-throw",
233
+ subject: `attribution-cleanup:${deps.event?.toolName ?? "unknown"}`,
234
+ reason,
235
+ });
236
+ try {
237
+ deps.dbg?.(`tool_call blocked-attribution cleanup threw (block verdict preserved): ${reason}`);
238
+ }
239
+ catch {
240
+ // A broken `dbg` must not resurrect the throw just absorbed.
241
+ }
242
+ }
243
+ }
244
+ return result;
245
+ }
246
+ catch (error) {
247
+ const toolName = deps.event?.toolName ?? "unknown";
248
+ const reason = error instanceof Error ? error.message : String(error);
249
+ // Once per tool name per session: a wedged handler fires on every call of
250
+ // that tool, and the ledger is a health surface, not a log.
251
+ recordDegradationOnce({
252
+ kind: "tool-call-handler-throw",
253
+ subject: toolName,
254
+ reason,
255
+ });
256
+ try {
257
+ deps.dbg?.(`tool_call handler threw for ${toolName} (degraded, not blocking): ${reason}`);
258
+ if (error instanceof Error && error.stack) {
259
+ deps.dbg?.(`tool_call handler stack: ${error.stack}`);
260
+ }
261
+ }
262
+ catch {
263
+ // A broken `dbg` must not resurrect the throw this guard just absorbed.
264
+ }
265
+ // Any attribution already recorded is deliberately LEFT in place: the
266
+ // tool now executes (this returns "no opinion"), so its paired
267
+ // `tool_result` still arrives and claims the record exactly once.
268
+ return undefined;
269
+ }
270
+ }
271
+ async function handleToolCallImpl(deps) {
143
272
  const { event, ctx, lensEnabled, getFlag, dbg, runtime, cacheManager, ensureLSPConfigInitialized, updateLspStatus, resetLSPService, getTreeSitterClient = getSharedTreeSitterClient, } = deps;
144
273
  const readGuardCorrelationId = getReadGuardCorrelationId(event);
145
274
  let filePath;
146
275
  const logToolReadGuardEvent = (entry) => logReadGuardEvent({ ...entry, correlationId: readGuardCorrelationId });
147
276
  const toolName = event.toolName ?? "";
148
277
  const editInputForTelemetry = event.input;
278
+ // #1655 item 3: SNAPSHOT the requested batch width here, at handler entry.
279
+ // `input` is a live, mutable, extension-ordered object — pi types it
280
+ // `Record<string, unknown>` and hands the SAME reference to every handler in
281
+ // turn (`@earendil-works/pi-coding-agent/dist/core/extensions/runner.js:701-716`
282
+ // passes `event` unchanged through the loop; source
283
+ // `src/core/extensions/types.ts:914-919`), and pi-lens itself rewrites it in
284
+ // place further down (indent correction, hashline resolution, range
285
+ // relocation). `requestedEditIndexes` was already a snapshot; the totals
286
+ // below used to RE-READ `editInputForTelemetry.edits.length` from the live
287
+ // object hundreds of lines and several `await`s later, so a batch that
288
+ // changed width in between produced an internally inconsistent summary —
289
+ // indexes from the call-time array, totals from the mutated one.
149
290
  const requestedEditIndexes = toolName === "write"
150
291
  ? [0]
151
292
  : Array.isArray(editInputForTelemetry?.edits)
152
293
  ? boundedIndexesForCount(editInputForTelemetry.edits.length)
153
294
  : [0];
295
+ const requestedEditTotal = toolName === "write"
296
+ ? 1
297
+ : Array.isArray(editInputForTelemetry?.edits)
298
+ ? editInputForTelemetry.edits.length
299
+ : 1;
154
300
  const logBlockedEditSummary = (source) => logToolReadGuardEvent({
155
301
  event: "edit_batch_summary",
156
302
  filePath: filePath ?? "",
@@ -159,20 +305,12 @@ export async function handleToolCall(deps) {
159
305
  source,
160
306
  editBatchSummary: createReadGuardEditBatchSummary({
161
307
  requestedIndexes: requestedEditIndexes,
162
- requestedTotal: toolName === "write"
163
- ? 1
164
- : Array.isArray(editInputForTelemetry?.edits)
165
- ? editInputForTelemetry.edits.length
166
- : 1,
308
+ requestedTotal: requestedEditTotal,
167
309
  rejectedReasons: requestedEditIndexes.map((index) => ({
168
310
  index,
169
311
  code: "preflight_blocked",
170
312
  })),
171
- rejectedTotal: toolName === "write"
172
- ? 1
173
- : Array.isArray(editInputForTelemetry?.edits)
174
- ? editInputForTelemetry.edits.length
175
- : 1,
313
+ rejectedTotal: requestedEditTotal,
176
314
  terminalStatus: "blocked",
177
315
  }),
178
316
  },
@@ -190,7 +328,11 @@ export async function handleToolCall(deps) {
190
328
  }
191
329
  }
192
330
  const rawFilePath = getToolCallRawFilePath(toolName, event);
193
- filePath = resolveToolCallFilePath(rawFilePath, ctx.cwd, runtime.projectRoot);
331
+ const pathResolution = resolveToolCallFilePath(rawFilePath, ctx.cwd, runtime.projectRoot);
332
+ filePath = pathResolution?.path;
333
+ if (pathResolution?.variant) {
334
+ dbg(`tool_call: path resolved via host ${pathResolution.variant} variant → ${filePath}`);
335
+ }
194
336
  if (!getFlag("no-lsp")) {
195
337
  try {
196
338
  const configCwd = filePath
@@ -205,9 +347,58 @@ export async function handleToolCall(deps) {
205
347
  if (!filePath)
206
348
  return;
207
349
  dbg(`tool_call fired for: ${filePath} (exists: ${nodeFs.existsSync(filePath)})`);
208
- if (!nodeFs.existsSync(filePath))
350
+ const toolCallId = resolveToolCallCorrelationId(event);
351
+ const attributesMutationTarget = toolCallId !== undefined && (toolName === "write" || toolName === "edit");
352
+ const targetMissing = !nodeFs.existsSync(filePath);
353
+ // #1642 F1: a brand-new file's WRITE is never a "skip" — `tool_call`
354
+ // fires PRE-execution, so `existsSync` is false for every path a write
355
+ // is about to CREATE. Gitignore is a pure pattern match (no existence
356
+ // requirement), so it is checked regardless of `targetMissing`; only an
357
+ // actual ignore verdict is a real "refuse". Folding `targetMissing` into
358
+ // `skipped` (the pre-fix-round-2 shape of this file) made EVERY new-file
359
+ // write's paired tool_result refuse to run diagnostics/autofix/format at
360
+ // all — a full pipeline regression worse than the bug #1642 fixes.
361
+ const targetIgnored = isPathIgnoredByProject(filePath, runtime.projectRoot, false);
362
+ if (attributesMutationTarget) {
363
+ // #1642: record the canonical target BY TOOL-CALL IDENTITY — including
364
+ // (especially) when it is being skipped here. The paired tool_result
365
+ // must take this exact verdict rather than re-deriving its own path
366
+ // from relative diff metadata, which is how a gitignored worktree
367
+ // edit got re-attributed onto a same-relative-path parent file.
368
+ runtime.recordToolCallAttribution(toolCallId, {
369
+ resolvedPath: filePath,
370
+ skipped: targetIgnored,
371
+ originCwd: ctx.cwd ?? runtime.projectRoot,
372
+ });
373
+ }
374
+ if (targetMissing) {
375
+ // #1655 item 5: this early return used to be the whole story — pi-lens
376
+ // did nothing, said nothing, and the file pi went on to read stayed
377
+ // invisible to the read guard, the LSP warm, and the dispatch. The
378
+ // variant ladder above now finds the macOS-shaped cases; when it probed
379
+ // variants and STILL found nothing, say so rather than returning an
380
+ // indistinguishable silence (defect shape 10). `write` is exempt for the
381
+ // same reason #1642 F1 gives just above: a write's target legitimately
382
+ // does not exist yet.
383
+ //
384
+ // Review F1: this used to also require `triedVariants.length > 0`, which
385
+ // silenced exactly the misses the base-normalization gap produced —
386
+ // those paths have no quote and no AM/PM, so every stage-2 candidate
387
+ // collapses onto the base path and nothing is "tried". `unresolved` is
388
+ // the whole condition; the tried list is detail for the reason string.
389
+ if (toolName !== "write" && pathResolution?.unresolved) {
390
+ const tried = pathResolution.triedVariants.length > 0
391
+ ? `tried ${pathResolution.triedVariants.join(", ")}`
392
+ : "no variant differed from the resolved path";
393
+ recordDegradationOnce({
394
+ kind: "path-variant-unresolved",
395
+ subject: filePath,
396
+ reason: `${toolName}: no file at the resolved path, and none of pi's variants matched (${tried})`,
397
+ });
398
+ }
209
399
  return;
210
- if (isPathIgnoredByProject(filePath, runtime.projectRoot, false)) {
400
+ }
401
+ if (targetIgnored) {
211
402
  dbg(`tool_call: skipping gitignored file ${filePath}`);
212
403
  return;
213
404
  }
@@ -670,10 +861,14 @@ export async function handleToolCall(deps) {
670
861
  readGuardCorrelationId,
671
862
  },
672
863
  content: [],
673
- provider: event.provider,
674
- model: event.model,
675
- sessionId: event.sessionId,
676
- session: event.session,
864
+ // #1655 item 2: `provider`/`model`/`sessionId`/`session`
865
+ // used to be forwarded here from the tool_call event.
866
+ // pi builds a `tool_call` with exactly
867
+ // `type`/`toolName`/`toolCallId`/`input`
868
+ // (`@earendil-works/pi-coding-agent/dist/core/agent-session.js:230-234`,
869
+ // source `src/core/agent-session.ts:~228-236`), so all
870
+ // four were always `undefined` and the tool_result
871
+ // branch they fed was unreachable.
677
872
  },
678
873
  getFlag: (name) => getFlag(name),
679
874
  dbg,