@herbertgao/pi-extensions 2026.8.5 → 2026.8.7

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 (389) hide show
  1. package/README.md +5 -5
  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 +272 -22
  7. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +74 -5
  8. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +94 -77
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +48 -6
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/message-display.ts +1 -1
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +14 -0
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +55 -17
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +41 -2
  14. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +75 -6
  15. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +7 -3
  16. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +64 -1
  17. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  18. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +16 -0
  19. package/node_modules/@herbertgao/pi-subagents/README.md +30 -22
  20. package/node_modules/@herbertgao/pi-subagents/examples/agent-tool-description.md +5 -5
  21. package/node_modules/@herbertgao/pi-subagents/package.json +7 -7
  22. package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +7 -1
  23. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +48 -19
  24. package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +22 -15
  25. package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +26 -2
  26. package/node_modules/@herbertgao/pi-subagents/src/index.ts +219 -40
  27. package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +101 -3
  28. package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +18 -4
  29. package/node_modules/@herbertgao/pi-subagents/src/settings.ts +99 -0
  30. package/node_modules/@herbertgao/pi-subagents/src/types.ts +22 -3
  31. package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +51 -3
  32. package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +20 -2
  33. package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +34 -10
  34. package/node_modules/@herbertgao/pi-subagents/src/usage.ts +129 -1
  35. package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +29 -5
  36. package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +3 -0
  37. package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +46 -10
  38. package/node_modules/@juicesharp/rpiv-ask-user-question/config.ts +25 -0
  39. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/configuration.md +13 -4
  40. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +8 -1
  41. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/localization.md +3 -1
  42. package/node_modules/@juicesharp/rpiv-ask-user-question/locales/en.json +2 -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 +3 -1
  47. package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +30 -7
  48. package/node_modules/@juicesharp/rpiv-ask-user-question/state/state.ts +14 -6
  49. package/node_modules/@juicesharp/rpiv-ask-user-question/view/dialog-builder.ts +30 -4
  50. package/node_modules/@juicesharp/rpiv-ask-user-question/view/tab-content-strategy.ts +26 -5
  51. package/node_modules/@narumitw/pi-btw/README.md +119 -103
  52. package/node_modules/@narumitw/pi-btw/dist/index.ts +2898 -0
  53. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +7 -0
  54. package/node_modules/@narumitw/pi-btw/package.json +13 -9
  55. package/node_modules/@narumitw/pi-btw/src/btw.ts +40 -42
  56. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +55 -10
  57. package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +390 -0
  58. package/node_modules/@narumitw/pi-btw/src/menu.ts +78 -15
  59. package/node_modules/@narumitw/pi-btw/src/settings.ts +22 -2
  60. package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +136 -45
  61. package/node_modules/pi-lens/CHANGELOG.md +1004 -0
  62. package/node_modules/pi-lens/README.md +11 -3
  63. package/node_modules/pi-lens/config/ruff/core.toml +42 -0
  64. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +130 -27
  65. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +427 -0
  66. package/node_modules/pi-lens/dist/clients/agent-nudge.js +79 -16
  67. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +9 -3
  68. package/node_modules/pi-lens/dist/clients/atomic-write.js +9 -3
  69. package/node_modules/pi-lens/dist/clients/bash-file-access.js +285 -8
  70. package/node_modules/pi-lens/dist/clients/biome-client.js +176 -37
  71. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +428 -0
  72. package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +119 -0
  73. package/node_modules/pi-lens/dist/clients/bootstrap.js +12 -1
  74. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +12 -3
  75. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +192 -0
  76. package/node_modules/pi-lens/dist/clients/bus-events-logger.js +62 -6
  77. package/node_modules/pi-lens/dist/clients/bus-publish.js +11 -3
  78. package/node_modules/pi-lens/dist/clients/cascade-budget.js +196 -0
  79. package/node_modules/pi-lens/dist/clients/cascade-format.js +76 -2
  80. package/node_modules/pi-lens/dist/clients/cascade-types.js +9 -1
  81. package/node_modules/pi-lens/dist/clients/child-unref.js +54 -6
  82. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +76 -24
  83. package/node_modules/pi-lens/dist/clients/console-guard-install.js +16 -4
  84. package/node_modules/pi-lens/dist/clients/dead-code-client.js +249 -52
  85. package/node_modules/pi-lens/dist/clients/deadline-utils.js +8 -1
  86. package/node_modules/pi-lens/dist/clients/debug-handles.js +5 -0
  87. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +62 -13
  88. package/node_modules/pi-lens/dist/clients/dependency-checker.js +43 -9
  89. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +153 -37
  90. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +298 -0
  91. package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +10 -3
  92. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +165 -11
  93. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +325 -72
  94. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +7 -4
  95. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +5 -0
  96. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +234 -18
  97. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +187 -19
  98. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +6 -3
  99. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +11 -9
  100. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +398 -0
  101. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +11 -3
  102. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +12 -7
  103. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +18 -0
  104. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +895 -0
  105. package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +4 -0
  106. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +16 -3
  107. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +81 -41
  108. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +16 -0
  109. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +23 -0
  110. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +331 -55
  111. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +38 -5
  112. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +97 -19
  113. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +14 -0
  114. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +20 -0
  115. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +22 -0
  116. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +10 -0
  117. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +18 -6
  118. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +73 -12
  119. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +488 -0
  120. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +84 -0
  121. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +260 -27
  122. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +943 -93
  123. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +86 -11
  124. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +72 -0
  125. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +106 -0
  126. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +9 -0
  127. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +18 -1
  128. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +4 -2
  129. package/node_modules/pi-lens/dist/clients/disposition-publish.js +10 -3
  130. package/node_modules/pi-lens/dist/clients/eval-timestamp.js +17 -0
  131. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +28 -5
  132. package/node_modules/pi-lens/dist/clients/extension-log.js +317 -3
  133. package/node_modules/pi-lens/dist/clients/file-kinds.js +8 -2
  134. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +294 -0
  135. package/node_modules/pi-lens/dist/clients/finding-identity.js +88 -0
  136. package/node_modules/pi-lens/dist/clients/fix-worklog.js +5 -1
  137. package/node_modules/pi-lens/dist/clients/format-events-publish.js +39 -8
  138. package/node_modules/pi-lens/dist/clients/formatters-lazy.js +3 -2
  139. package/node_modules/pi-lens/dist/clients/formatters.js +500 -115
  140. package/node_modules/pi-lens/dist/clients/generation-guard.js +216 -0
  141. package/node_modules/pi-lens/dist/clients/git-guard.js +49 -21
  142. package/node_modules/pi-lens/dist/clients/gitleaks-client.js +181 -8
  143. package/node_modules/pi-lens/dist/clients/go-client.js +21 -39
  144. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +219 -10
  145. package/node_modules/pi-lens/dist/clients/grammar-source.js +333 -10
  146. package/node_modules/pi-lens/dist/clients/host-ports.js +9 -1
  147. package/node_modules/pi-lens/dist/clients/installer/index.js +1119 -101
  148. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +58 -0
  149. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +715 -0
  150. package/node_modules/pi-lens/dist/clients/instance-reaper.js +643 -97
  151. package/node_modules/pi-lens/dist/clients/instance-registry.js +87 -17
  152. package/node_modules/pi-lens/dist/clients/jscpd-client.js +86 -15
  153. package/node_modules/pi-lens/dist/clients/knip-client.js +361 -24
  154. package/node_modules/pi-lens/dist/clients/language-policy.js +8 -2
  155. package/node_modules/pi-lens/dist/clients/language-profile.js +2 -0
  156. package/node_modules/pi-lens/dist/clients/latency-logger.js +487 -9
  157. package/node_modules/pi-lens/dist/clients/lazy-import.js +21 -0
  158. package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -0
  159. package/node_modules/pi-lens/dist/clients/lens-events.js +56 -25
  160. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +16 -0
  161. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +45 -2
  162. package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +30 -4
  163. package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +160 -20
  164. package/node_modules/pi-lens/dist/clients/lsp/client.js +1666 -148
  165. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +111 -0
  166. package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +389 -0
  167. package/node_modules/pi-lens/dist/clients/lsp/index.js +2496 -171
  168. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +215 -0
  169. package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +146 -14
  170. package/node_modules/pi-lens/dist/clients/lsp/language.js +48 -4
  171. package/node_modules/pi-lens/dist/clients/lsp/server.js +517 -69
  172. package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +22 -0
  173. package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +43 -0
  174. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +172 -0
  175. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +21 -5
  176. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +61 -3
  177. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +422 -28
  178. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +30 -0
  179. package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +175 -0
  180. package/node_modules/pi-lens/dist/clients/lsp-lazy.js +3 -2
  181. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +4 -0
  182. package/node_modules/pi-lens/dist/clients/mcp/session.js +39 -18
  183. package/node_modules/pi-lens/dist/clients/model-provider.js +53 -0
  184. package/node_modules/pi-lens/dist/clients/module-report.js +8 -0
  185. package/node_modules/pi-lens/dist/clients/opengrep-client.js +15 -1
  186. package/node_modules/pi-lens/dist/clients/package-manager.js +170 -14
  187. package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +27 -0
  188. package/node_modules/pi-lens/dist/clients/path-utils.js +160 -0
  189. package/node_modules/pi-lens/dist/clients/pipeline.js +178 -30
  190. package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +37 -0
  191. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +17 -3
  192. package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +89 -22
  193. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +85 -15
  194. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +15 -3
  195. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +23 -2
  196. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +50 -2
  197. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -0
  198. package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
  199. package/node_modules/pi-lens/dist/clients/project-snapshot.js +299 -0
  200. package/node_modules/pi-lens/dist/clients/quiet-window-config.js +47 -0
  201. package/node_modules/pi-lens/dist/clients/quiet-window.js +11 -25
  202. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +1 -1
  203. package/node_modules/pi-lens/dist/clients/read-guard.js +184 -10
  204. package/node_modules/pi-lens/dist/clients/resource-sampler.js +49 -17
  205. package/node_modules/pi-lens/dist/clients/reverse-deps.js +50 -11
  206. package/node_modules/pi-lens/dist/clients/review-graph/query.js +76 -4
  207. package/node_modules/pi-lens/dist/clients/run-duration.js +55 -0
  208. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +248 -13
  209. package/node_modules/pi-lens/dist/clients/runtime-context.js +112 -12
  210. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +472 -61
  211. package/node_modules/pi-lens/dist/clients/runtime-session.js +359 -13
  212. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +217 -22
  213. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +269 -22
  214. package/node_modules/pi-lens/dist/clients/runtime-turn.js +948 -87
  215. package/node_modules/pi-lens/dist/clients/rust-client.js +21 -37
  216. package/node_modules/pi-lens/dist/clients/safe-spawn.js +220 -7
  217. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +161 -0
  218. package/node_modules/pi-lens/dist/clients/search-read-registration.js +34 -6
  219. package/node_modules/pi-lens/dist/clients/security-scan-client.js +224 -8
  220. package/node_modules/pi-lens/dist/clients/sg-runner.js +249 -37
  221. package/node_modules/pi-lens/dist/clients/single-flight.js +158 -0
  222. package/node_modules/pi-lens/dist/clients/smells-rollup.js +18 -11
  223. package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
  224. package/node_modules/pi-lens/dist/clients/startup-timing.js +26 -2
  225. package/node_modules/pi-lens/dist/clients/test-runner-client.js +574 -32
  226. package/node_modules/pi-lens/dist/clients/tool-event.js +56 -5
  227. package/node_modules/pi-lens/dist/clients/tool-policy.js +127 -20
  228. package/node_modules/pi-lens/dist/clients/tool-set-policy.js +76 -0
  229. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +75 -1
  230. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +769 -64
  231. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +11 -0
  232. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +90 -0
  233. package/node_modules/pi-lens/dist/clients/trivy-client.js +19 -1
  234. package/node_modules/pi-lens/dist/clients/warm-attach.js +17 -0
  235. package/node_modules/pi-lens/dist/clients/widget-state.js +336 -36
  236. package/node_modules/pi-lens/dist/clients/word-index.js +305 -33
  237. package/node_modules/pi-lens/dist/clients/zizmor-config.js +214 -14
  238. package/node_modules/pi-lens/dist/index.js +64677 -49484
  239. package/node_modules/pi-lens/dist/mcp/server.js +8 -2
  240. package/node_modules/pi-lens/dist/tools/activate-tools.js +17 -5
  241. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +9 -4
  242. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +5 -2
  243. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +469 -56
  244. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +190 -46
  245. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -7
  246. package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -1
  247. package/node_modules/pi-lens/docs/agent-guide.md +44 -14
  248. package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +518 -501
  249. package/node_modules/pi-lens/docs/dispositions.md +21 -0
  250. package/node_modules/pi-lens/docs/features.md +33 -6
  251. package/node_modules/pi-lens/docs/globalconfig.md +14 -0
  252. package/node_modules/pi-lens/docs/language-coverage.md +71 -5
  253. package/node_modules/pi-lens/docs/mcp.md +2 -2
  254. package/node_modules/pi-lens/docs/servercapabilities.md +4 -1
  255. package/node_modules/pi-lens/docs/settings.md +25 -1
  256. package/node_modules/pi-lens/docs/usage.md +24 -5
  257. package/node_modules/pi-lens/docs/word-index.md +35 -0
  258. package/node_modules/pi-lens/package.json +10 -6
  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 +22 -0
  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-conditional-empty-object-spread-js-test.yml +9 -0
  266. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-test.yml +9 -0
  267. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-dupe-class-members-test.yml +33 -0
  268. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-js-test.yml +7 -1
  269. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-test.yml +7 -1
  270. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-known-value-widening-test.yml +9 -0
  271. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-non-null-assertion-test.yml +216 -0
  272. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +9 -0
  273. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +9 -0
  274. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +9 -0
  275. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +9 -0
  276. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-return-value-in-generator-test.yml +12 -0
  277. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-runtime-typeof-test.yml +33 -0
  278. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-server-bind-wildcard-test.yml +9 -0
  279. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-shape-in-symbol-names-test.yml +13 -0
  280. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-js-test.yml +5 -1
  281. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-test.yml +5 -1
  282. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-laundering-test.yml +11 -0
  283. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-parameters-test.yml +12 -0
  284. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-returns-test.yml +16 -0
  285. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-any-test.yml +10 -0
  286. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-unknown-test.yml +8 -0
  287. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/redundant-unsafe-function-test.yml +35 -0
  288. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/require-safety-comment-for-as-unknown-as-test.yml +177 -0
  289. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/ts-void-zero-test.yml +1 -0
  290. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member-js.yml +13 -2
  291. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member.yml +13 -2
  292. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +2 -0
  293. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-object-param.yml +60 -0
  294. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +66 -0
  295. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-compile-call.yml +63 -5
  296. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread-js.yml +21 -0
  297. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread.yml +29 -0
  298. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-dupe-class-members.yml +52 -8
  299. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html-js.yml +27 -2
  300. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html.yml +27 -2
  301. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-known-value-widening.yml +71 -0
  302. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-non-null-assertion.yml +316 -0
  303. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +7 -0
  304. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +29 -0
  305. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +30 -0
  306. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +41 -0
  307. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +42 -0
  308. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-return-value-in-generator.yml +22 -5
  309. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-runtime-typeof.yml +121 -0
  310. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-server-bind-wildcard.yml +23 -7
  311. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-shape-in-symbol-names.yml +68 -0
  312. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code-js.yml +41 -2
  313. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code.yml +41 -2
  314. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +32 -0
  315. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-parameters.yml +67 -0
  316. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-returns.yml +106 -0
  317. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-any.yml +50 -0
  318. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-unknown.yml +56 -0
  319. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +2 -0
  320. package/node_modules/pi-lens/rules/ast-grep-rules/rules/redundant-unsafe-function.yml +32 -0
  321. package/node_modules/pi-lens/rules/ast-grep-rules/rules/require-safety-comment-for-as-unknown-as.yml +184 -0
  322. package/node_modules/pi-lens/rules/ast-grep-rules/rules/ts-void-zero.yml +5 -0
  323. package/node_modules/pi-lens/rules/ast-grep-rules/self-scan-baseline.json +5 -0
  324. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +132 -1
  325. package/node_modules/pi-lens/scripts/download-grammars.js +25 -0
  326. package/node_modules/pi-lens/scripts/grammars.lock.json +9 -0
  327. package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +12 -11
  328. package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +22 -22
  329. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +87 -116
  330. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +170 -0
  331. package/node_modules/pi-lens/skills/pi-lens-write-tree-sitter-rule/SKILL.md +3 -1
  332. package/node_modules/pi-lens/vendor/grammars/tree-sitter-cue.wasm +0 -0
  333. package/node_modules/pi-mcp-adapter/CHANGELOG.md +49 -0
  334. package/node_modules/pi-mcp-adapter/README.md +51 -6
  335. package/node_modules/pi-mcp-adapter/agent-dir.ts +12 -4
  336. package/node_modules/pi-mcp-adapter/cli.js +188 -5
  337. package/node_modules/pi-mcp-adapter/commands.ts +128 -22
  338. package/node_modules/pi-mcp-adapter/config.ts +28 -10
  339. package/node_modules/pi-mcp-adapter/direct-tools.ts +23 -19
  340. package/node_modules/pi-mcp-adapter/index.ts +219 -32
  341. package/node_modules/pi-mcp-adapter/init.ts +36 -4
  342. package/node_modules/pi-mcp-adapter/lifecycle.ts +315 -24
  343. package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +39 -6
  344. package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +387 -0
  345. package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +27 -3
  346. package/node_modules/pi-mcp-adapter/mcp-code.ts +4 -0
  347. package/node_modules/pi-mcp-adapter/mcp-panel.ts +42 -13
  348. package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +2 -1
  349. package/node_modules/pi-mcp-adapter/metadata-cache.ts +46 -25
  350. package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +168 -0
  351. package/node_modules/pi-mcp-adapter/package.json +4 -1
  352. package/node_modules/pi-mcp-adapter/proxy-modes.ts +5 -4
  353. package/node_modules/pi-mcp-adapter/request-headers-command.ts +330 -0
  354. package/node_modules/pi-mcp-adapter/search-ranking.ts +92 -22
  355. package/node_modules/pi-mcp-adapter/server-manager.ts +145 -2
  356. package/node_modules/pi-mcp-adapter/session-recovery.ts +7 -0
  357. package/node_modules/pi-mcp-adapter/tool-approval.ts +15 -2
  358. package/node_modules/pi-mcp-adapter/tool-metadata.ts +38 -18
  359. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +44 -4
  360. package/node_modules/pi-mcp-adapter/types.ts +95 -10
  361. package/node_modules/pi-mcp-adapter/ui-server.ts +18 -16
  362. package/node_modules/pi-mcp-adapter/utils.ts +70 -0
  363. package/node_modules/pi-web-access/CHANGELOG.md +37 -0
  364. package/node_modules/pi-web-access/README.md +38 -14
  365. package/node_modules/pi-web-access/anysearch.ts +4 -2
  366. package/node_modules/pi-web-access/auth-fetch.ts +148 -0
  367. package/node_modules/pi-web-access/brave.ts +16 -4
  368. package/node_modules/pi-web-access/chrome-cookies.ts +110 -23
  369. package/node_modules/pi-web-access/curator-page.ts +8 -3
  370. package/node_modules/pi-web-access/curator-server.ts +5 -1
  371. package/node_modules/pi-web-access/exa.ts +18 -7
  372. package/node_modules/pi-web-access/extract.ts +134 -37
  373. package/node_modules/pi-web-access/fetch-params.ts +17 -3
  374. package/node_modules/pi-web-access/firecrawl.ts +172 -12
  375. package/node_modules/pi-web-access/gemini-search.ts +33 -7
  376. package/node_modules/pi-web-access/index.ts +160 -104
  377. package/node_modules/pi-web-access/package.json +2 -2
  378. package/node_modules/pi-web-access/page-query.ts +4 -2
  379. package/node_modules/pi-web-access/parallel-mcp.ts +249 -0
  380. package/node_modules/pi-web-access/parallel.ts +2 -2
  381. package/node_modules/pi-web-access/query-rewrite.ts +51 -0
  382. package/node_modules/pi-web-access/serper.ts +211 -0
  383. package/node_modules/pi-web-access/summary-model-scope.ts +12 -4
  384. package/node_modules/pi-web-access/summary-review.ts +51 -23
  385. package/node_modules/pi-web-access/tavily.ts +16 -4
  386. package/node_modules/pi-web-access/utils.ts +87 -0
  387. package/node_modules/pi-web-access/valyu.ts +199 -0
  388. package/node_modules/pi-web-access/youtube-extract.ts +2 -2
  389. package/package.json +13 -13
@@ -33,13 +33,19 @@
33
33
  * enumerate the built-ins only; pi-lens's `tool_call`/`tool_result` paths
34
34
  * also key off `lsp_navigation` and pi-lens's own registered tools, which no
35
35
  * host discriminator names.
36
- * 4. **Narrowing to the host union would LOSE fields pi-lens reads.** The host
36
+ * 4. **The host union is narrower than the events pi-lens handles.** The host
37
37
  * `ToolResultEvent` declares `toolCallId`/`input`/`content`/`isError`/
38
38
  * `details`/`usage`; pi-lens's local `ToolResultEvent`
39
- * (`clients/runtime-tool-result.ts`) additionally carries
40
- * `id`/`callId`/`requestId`/`provider`/`model`/`sessionId`/`session`, which
41
- * the telemetry-identity path reads. A guard that narrowed to
42
- * `EditToolResultEvent` would drop them.
39
+ * (`clients/runtime-tool-result.ts`) declares the subset it reads. It used
40
+ * to additionally carry `id`/`callId`/`requestId`/`provider`/`model`/
41
+ * `sessionId`/`session` "for the telemetry-identity path" — #1655 item 2
42
+ * deleted all seven, because pi's `afterToolCall` builds the event with
43
+ * exactly `type`/`toolName`/`toolCallId`/`input`/`content`/`details`/
44
+ * `isError`/`usage` (`dist/core/agent-session.js:243-256`, source
45
+ * `src/core/agent-session.ts:502-516`), so the branch reading them was dead
46
+ * code. The standing reason not to narrow is point 3: pi-lens also
47
+ * synthesizes its OWN `tool_result` payloads (bash-derived writes,
48
+ * partial-apply) that no host discriminator would admit.
43
49
  *
44
50
  * What IS consolidated is the part that costs nothing: the host's `details`
45
51
  * SHAPES are type-only exports, so `EditToolDetails` & co. are imported as
@@ -47,8 +53,53 @@
47
53
  * payloads (`searchReads`, `piLensPartialApply`) stay hand-declared — no host
48
54
  * type describes them.
49
55
  */
56
+ import { sanitizeCorrelationId } from "./read-guard-logger.js";
50
57
  export function isToolCallEventType(toolName, event) {
51
58
  return (!!event &&
52
59
  typeof event === "object" &&
53
60
  event.toolName === toolName);
54
61
  }
62
+ /**
63
+ * Resolve a STABLE correlation id shared between a `tool_call` and its
64
+ * paired `tool_result`, checking every field name a host is known to use
65
+ * (#1642 F4) — the SDK declares `toolCallId` (see the file header above for
66
+ * why pi-lens can't import the SDK's own type at runtime), but
67
+ * `read-guard-logger.ts`'s `getReadGuardCorrelationId` already had to widen
68
+ * to `callId`/`requestId`/`id` for hosts that populate one of those instead.
69
+ * Single source of truth for that field list — do not hand-roll a narrower
70
+ * `event.toolCallId` read at a new call site.
71
+ *
72
+ * Deliberately does NOT fall back to a generated id the way
73
+ * `getReadGuardCorrelationId` does: that fallback is minted fresh on EVERY
74
+ * call (a bare per-invocation counter), which is exactly right for grouping
75
+ * one call's own log lines but useless — actively misleading — for
76
+ * correlating two SEPARATE events (a `tool_call` and its `tool_result`)
77
+ * against each other. `undefined` means the host supplies no stable
78
+ * identity at all under any known field; callers decide their own safe
79
+ * default for that case rather than treat a generated id as a match.
80
+ */
81
+ export function resolveToolCallCorrelationId(event) {
82
+ const value = (event ?? {});
83
+ for (const candidate of [
84
+ value.toolCallId,
85
+ value.callId,
86
+ value.requestId,
87
+ // Widest rung, only reached when toolCallId/callId/requestId are all
88
+ // absent (#1678 item 2): this assumes a host's `id` field identifies
89
+ // one TOOL CALL. A host that instead populates `id` per MESSAGE (one
90
+ // id shared by every tool call in that message) would cross two
91
+ // parallel calls in the same turn under the same id. Stated plainly:
92
+ // real pi builds `tool_call`/`tool_result` events with exactly
93
+ // `toolCallId` and no bare `id` field at all (see the file header
94
+ // above, #1655 item 2, `src/core/agent-session.ts:502-516`), so this
95
+ // rung is dead code against today's host — kept only in case a
96
+ // different host shape needs it; drop it once #1655's audit confirms
97
+ // none does.
98
+ value.id,
99
+ ]) {
100
+ const sanitized = sanitizeCorrelationId(candidate);
101
+ if (sanitized)
102
+ return sanitized;
103
+ }
104
+ return undefined;
105
+ }
@@ -3,7 +3,7 @@ import * as path from "node:path";
3
3
  import { TERRAGRUNT_FILENAMES } from "./file-kinds.js";
4
4
  import { logLatency } from "./latency-logger.js";
5
5
  import { resolvePackagePath } from "./package-root.js";
6
- import { findNearestContaining, walkUpDirs } from "./path-utils.js";
6
+ import { findNearestContaining, normalizeMapKey, walkUpDirs, } from "./path-utils.js";
7
7
  import { loadProjectSnapshotWithoutWordIndex } from "./project-snapshot.js";
8
8
  // Extension → formatter policy. This map, `FORMATTER_POLICY_BY_FILENAME`, and
9
9
  // `AUTO_INSTALLABLE_DEFAULT_FORMATTERS` are the inverse of the formatter
@@ -272,7 +272,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
272
272
  formatterNames: ["swiftformat"],
273
273
  defaultFormatter: "swiftformat",
274
274
  defaultWhenUnconfigured: false,
275
- gate: "smart-default",
275
+ gate: "config-first",
276
276
  },
277
277
  ],
278
278
  [
@@ -281,7 +281,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
281
281
  formatterNames: ["fantomas"],
282
282
  defaultFormatter: "fantomas",
283
283
  defaultWhenUnconfigured: false,
284
- gate: "smart-default",
284
+ gate: "config-first",
285
285
  },
286
286
  ],
287
287
  [
@@ -290,7 +290,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
290
290
  formatterNames: ["fantomas"],
291
291
  defaultFormatter: "fantomas",
292
292
  defaultWhenUnconfigured: false,
293
- gate: "smart-default",
293
+ gate: "config-first",
294
294
  },
295
295
  ],
296
296
  [
@@ -299,7 +299,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
299
299
  formatterNames: ["fantomas"],
300
300
  defaultFormatter: "fantomas",
301
301
  defaultWhenUnconfigured: false,
302
- gate: "smart-default",
302
+ gate: "config-first",
303
303
  },
304
304
  ],
305
305
  [
@@ -317,7 +317,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
317
317
  formatterNames: ["mix"],
318
318
  defaultFormatter: "mix",
319
319
  defaultWhenUnconfigured: false,
320
- gate: "smart-default",
320
+ gate: "config-first",
321
321
  },
322
322
  ],
323
323
  [
@@ -326,7 +326,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
326
326
  formatterNames: ["mix"],
327
327
  defaultFormatter: "mix",
328
328
  defaultWhenUnconfigured: false,
329
- gate: "smart-default",
329
+ gate: "config-first",
330
330
  },
331
331
  ],
332
332
  [
@@ -335,7 +335,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
335
335
  formatterNames: ["mix"],
336
336
  defaultFormatter: "mix",
337
337
  defaultWhenUnconfigured: false,
338
- gate: "smart-default",
338
+ gate: "config-first",
339
339
  },
340
340
  ],
341
341
  [
@@ -344,7 +344,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
344
344
  formatterNames: ["mix"],
345
345
  defaultFormatter: "mix",
346
346
  defaultWhenUnconfigured: false,
347
- gate: "smart-default",
347
+ gate: "config-first",
348
348
  },
349
349
  ],
350
350
  [
@@ -353,7 +353,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
353
353
  formatterNames: ["mix"],
354
354
  defaultFormatter: "mix",
355
355
  defaultWhenUnconfigured: false,
356
- gate: "smart-default",
356
+ gate: "config-first",
357
357
  },
358
358
  ],
359
359
  [
@@ -443,7 +443,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
443
443
  formatterNames: ["csharpier"],
444
444
  defaultFormatter: "csharpier",
445
445
  defaultWhenUnconfigured: false,
446
- gate: "smart-default",
446
+ gate: "config-first",
447
447
  },
448
448
  ],
449
449
  [
@@ -461,7 +461,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
461
461
  formatterNames: ["ormolu"],
462
462
  defaultFormatter: "ormolu",
463
463
  defaultWhenUnconfigured: false,
464
- gate: "smart-default",
464
+ gate: "config-first",
465
465
  },
466
466
  ],
467
467
  [
@@ -470,7 +470,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
470
470
  formatterNames: ["ormolu"],
471
471
  defaultFormatter: "ormolu",
472
472
  defaultWhenUnconfigured: false,
473
- gate: "smart-default",
473
+ gate: "config-first",
474
474
  },
475
475
  ],
476
476
  [
@@ -533,7 +533,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
533
533
  formatterNames: ["taplo"],
534
534
  defaultFormatter: "taplo",
535
535
  defaultWhenUnconfigured: false,
536
- gate: "smart-default",
536
+ gate: "config-first",
537
537
  },
538
538
  ],
539
539
  [
@@ -542,7 +542,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
542
542
  formatterNames: ["terraform"],
543
543
  defaultFormatter: "terraform",
544
544
  defaultWhenUnconfigured: false,
545
- gate: "smart-default",
545
+ gate: "config-first",
546
546
  },
547
547
  ],
548
548
  [
@@ -551,7 +551,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
551
551
  formatterNames: ["terraform"],
552
552
  defaultFormatter: "terraform",
553
553
  defaultWhenUnconfigured: false,
554
- gate: "smart-default",
554
+ gate: "config-first",
555
555
  },
556
556
  ],
557
557
  [
@@ -653,6 +653,15 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
653
653
  gate: "smart-default",
654
654
  },
655
655
  ],
656
+ [
657
+ ".cue",
658
+ {
659
+ formatterNames: ["cue"],
660
+ defaultFormatter: "cue",
661
+ defaultWhenUnconfigured: true,
662
+ gate: "smart-default",
663
+ },
664
+ ],
656
665
  ]);
657
666
  // oxfmt supports these extensions — registered as a candidate formatter for each.
658
667
  // Using a post-processing pass avoids repeating the same modification across
@@ -1453,6 +1462,7 @@ export function getAutofixPolicyForFile(filePath, context = {}) {
1453
1462
  defaultWhenUnconfigured: true,
1454
1463
  gate: "smart-default",
1455
1464
  safe: true,
1465
+ scope: "cargo-project",
1456
1466
  };
1457
1467
  }
1458
1468
  if ([".json", ".jsonc"].includes(ext)) {
@@ -1595,6 +1605,7 @@ export function getAutofixPolicyForFile(filePath, context = {}) {
1595
1605
  defaultWhenUnconfigured: true,
1596
1606
  gate: "smart-default",
1597
1607
  safe: true,
1608
+ scope: "dart-project",
1598
1609
  };
1599
1610
  }
1600
1611
  return undefined;
@@ -2023,10 +2034,17 @@ export function ruffConfigArgs(cwd) {
2023
2034
  * `config/biome/core.jsonc` fallback — applies on `lint --write` too.
2024
2035
  */
2025
2036
  export function biomeConfigArgs(cwd) {
2037
+ // A project config wins outright (#1731, discipline A): passing
2038
+ // `--config-path` even when the project ships `biome.json(c)` pinned
2039
+ // biome's config resolution to that ONE file, so a monorepo package
2040
+ // underneath `cwd` with its own `biome.json` never got to extend/override
2041
+ // the root config the way biome's own nested-config resolution allows. No
2042
+ // flag at all lets biome discover it unaided, exactly like the ruff/
2043
+ // markdownlint fallbacks above skip `--config` under the same condition.
2044
+ if (getBiomeConfigPath(cwd))
2045
+ return [];
2026
2046
  return [
2027
- "--config-path=" +
2028
- (getBiomeConfigPath(cwd) ??
2029
- resolvePackagePath(import.meta.url, "config/biome/core.jsonc")),
2047
+ "--config-path=" + resolvePackagePath(import.meta.url, "config/biome/core.jsonc"),
2030
2048
  ];
2031
2049
  }
2032
2050
  export function hasGolangciConfig(cwd) {
@@ -2077,6 +2095,89 @@ export function hasCmakeFormatConfig(cwd) {
2077
2095
  "cmake-format.yml",
2078
2096
  ]) !== undefined);
2079
2097
  }
2098
+ // PSScriptAnalyzerSettings.psd1 is the conventional settings file PowerShell
2099
+ // projects use to configure `Invoke-Formatter`/`Invoke-ScriptAnalyzer` (passed
2100
+ // via `-Settings`); `ScriptAnalyzerSettings.psd1` is the same convention minus
2101
+ // the "PS" prefix and shows up in some repos too. Either one opting a project
2102
+ // into explicit PSScriptAnalyzer config is enough to select the formatter
2103
+ // (#1572 — `psscriptanalyzer-format` had no case here at all, so it could
2104
+ // never be selected regardless of project config).
2105
+ const PSSCRIPTANALYZER_SETTINGS_FILES = [
2106
+ "PSScriptAnalyzerSettings.psd1",
2107
+ "ScriptAnalyzerSettings.psd1",
2108
+ ];
2109
+ /**
2110
+ * The nearest PSScriptAnalyzer settings file's full path, or `undefined`.
2111
+ * `formatters.ts`'s `resolveCommand` passes this straight to
2112
+ * `Invoke-Formatter -Settings` (#1572 review F2) — gating on the file's
2113
+ * PRESENCE without ever reading its RULES would run the project's file
2114
+ * through the stock `CodeFormatting` ruleset regardless of what it declared,
2115
+ * the same stock-style imposition #1144 banned for the other formatters.
2116
+ */
2117
+ export function findPSScriptAnalyzerConfigPath(cwd) {
2118
+ for (const dir of walkUpDirs(cwd)) {
2119
+ for (const name of PSSCRIPTANALYZER_SETTINGS_FILES) {
2120
+ const candidate = path.join(dir, name);
2121
+ if (fs.existsSync(candidate))
2122
+ return candidate;
2123
+ }
2124
+ }
2125
+ return undefined;
2126
+ }
2127
+ export function hasPSScriptAnalyzerConfig(cwd) {
2128
+ return findPSScriptAnalyzerConfigPath(cwd) !== undefined;
2129
+ }
2130
+ // #1595 sweep — 7 of the 8 formatters #1572 left unreachable (038cd1df flipped
2131
+ // defaultWhenUnconfigured to false for these without adding an explicit-config
2132
+ // check; see EXPLICIT_FORMATTER_CONFIG_CHECKS in formatters.ts). nixfmt is the
2133
+ // 8th and stays unreachable: it is deliberately unconfigurable (no rc file,
2134
+ // no CLI flag surface) and has no project-level manifest marker analogous to
2135
+ // `terraform init`'s lock file, so there is no honest "explicit opt-in" signal
2136
+ // to gate on — see the KNOWN_UNREACHABLE_FORMATTERS comment in
2137
+ // formatter-policy-consistency.test.ts.
2138
+ export function hasCsharpierConfig(cwd) {
2139
+ return (findNearestContaining(cwd, [
2140
+ ".csharpierrc",
2141
+ ".csharpierrc.json",
2142
+ ".csharpierrc.yaml",
2143
+ ".csharpierrc.yml",
2144
+ ]) !== undefined);
2145
+ }
2146
+ // Ormolu has no general settings file, but it does read a project `.ormolu`
2147
+ // file for custom operator fixity declarations (the only file-based config
2148
+ // surface Ormolu supports) — real, if narrow, per its own docs.
2149
+ export function hasOrmoluConfig(cwd) {
2150
+ return findNearestContaining(cwd, [".ormolu"]) !== undefined;
2151
+ }
2152
+ export function hasTaploConfig(cwd) {
2153
+ return findNearestContaining(cwd, ["taplo.toml", ".taplo.toml"]) !== undefined;
2154
+ }
2155
+ // `terraform fmt` itself is deliberately unconfigurable (no rc file, no
2156
+ // per-project options — HashiCorp's own docs call this out). The nearest
2157
+ // thing to an explicit per-project opt-in is `.terraform.lock.hcl`, written
2158
+ // only by `terraform init`: it marks a directory the user has deliberately
2159
+ // set up as a Terraform root, as opposed to a stray `.tf`/`.tfvars` file
2160
+ // dropped into an unrelated repo. A manifest marker, per #1595's own guidance
2161
+ // for formatters with no dedicated config-file convention.
2162
+ export function hasTerraformConfig(cwd) {
2163
+ return findNearestContaining(cwd, [".terraform.lock.hcl"]) !== undefined;
2164
+ }
2165
+ export function hasSwiftformatConfig(cwd) {
2166
+ return findNearestContaining(cwd, [".swiftformat"]) !== undefined;
2167
+ }
2168
+ // Fantomas has no dedicated rc file; its documented config surface is
2169
+ // `.editorconfig` (fsharp_*-prefixed keys) or a `.fantomasignore` file (the
2170
+ // one Fantomas-specific marker it does ship). Mirrors hasGoogleJavaFormatConfig's
2171
+ // precedent for formatters whose only config surface is .editorconfig.
2172
+ export function hasFantomasConfig(cwd) {
2173
+ return (findNearestContaining(cwd, [".fantomasignore", ".editorconfig"]) !==
2174
+ undefined);
2175
+ }
2176
+ // `.formatter.exs` is THE convention `mix format` reads project config from
2177
+ // (inputs, line_length, plugins) — universal in Elixir projects that use it.
2178
+ export function hasMixFormatConfig(cwd) {
2179
+ return findNearestContaining(cwd, [".formatter.exs"]) !== undefined;
2180
+ }
2080
2181
  export function hasPhpstanConfig(cwd) {
2081
2182
  return findNearestContaining(cwd, PHPSTAN_CONFIGS) !== undefined;
2082
2183
  }
@@ -2281,10 +2382,16 @@ const COMPILED_CLASSES_DIRS = [
2281
2382
  path.join("out", "production"),
2282
2383
  path.join("bin", "main"),
2283
2384
  ];
2284
- export function hasJavaBuildDescriptor(cwd) {
2385
+ export function hasJavaBuildDescriptor(cwd, ceiling) {
2386
+ const normalizedCeiling = ceiling
2387
+ ? normalizeMapKey(path.resolve(ceiling))
2388
+ : undefined;
2285
2389
  for (const dir of walkUpDirs(cwd)) {
2286
2390
  if (JAVA_BUILD_DESCRIPTORS.some((d) => fs.existsSync(path.join(dir, d))))
2287
2391
  return true;
2392
+ if (normalizedCeiling &&
2393
+ normalizeMapKey(path.resolve(dir)) === normalizedCeiling)
2394
+ break;
2288
2395
  }
2289
2396
  return false;
2290
2397
  }
@@ -0,0 +1,76 @@
1
+ import { logLatency } from "./latency-logger.js";
2
+ /**
3
+ * Whether the host will send this model deferred (searchable) tool
4
+ * definitions rather than the full inline list.
5
+ *
6
+ * Read the host's own decision off `ctx.model.compat` — pi resolves that
7
+ * flag from the model config (`core/model-config`, `compat.supportsToolReferences`)
8
+ * and it is the only capability signal a consumer can honestly observe.
9
+ * A missing flag means "unknown", which we report as false: this value only
10
+ * annotates the `tool_set_mutation` log line, so guessing high would make the
11
+ * log lie, while guessing low merely under-claims.
12
+ */
13
+ export function supportsDeferredTools(model) {
14
+ return model?.compat?.supportsToolReferences === true;
15
+ }
16
+ /**
17
+ * A fresh logical conversation — the only reasons that start with an empty
18
+ * activation memory. `undefined` is included because older hosts fire
19
+ * `session_start` with no `reason` at all.
20
+ *
21
+ * Every OTHER reason (fork/reload/resume) is a session REBUILD: the host
22
+ * constructs a brand-new AgentSession with `includeAllExtensionTools: true`
23
+ * (pi `core/agent-session.js`), so every registered pi-lens tool is active
24
+ * again by the time our handler runs, while pi-lens's own extension closure
25
+ * state survives. Those reasons must RESTORE the previous posture, not skip.
26
+ */
27
+ export function isFreshSessionStart(reason) {
28
+ return reason === undefined || reason === "startup" || reason === "new";
29
+ }
30
+ /**
31
+ * Compute the active-tool set pi-lens wants: everything currently active that
32
+ * is not a lazy tool, plus exactly the lazy tools the model activated in this
33
+ * logical session (`remembered`).
34
+ *
35
+ * On startup/new `remembered` is empty and this is the plain baseline shrink.
36
+ * On fork/reload/resume the host has just re-activated all registered tools,
37
+ * and this restores the parent's posture character-for-character — which both
38
+ * preserves the model's activations and keeps the advertised tool list equal
39
+ * to the one the prompt cache prefix was built from.
40
+ */
41
+ export function planToolSet(active, lazyNames, remembered) {
42
+ const desired = active.filter(
43
+ // Lazy tools are dropped here and re-appended below in REMEMBERED
44
+ // (= activation) order. Keeping them in the host's registration
45
+ // position would restore the right SET in the wrong ARRAY order, and
46
+ // the active-tools array is what serializes into the request's tool
47
+ // block — a transposition is a changed prefix, i.e. a cache miss.
48
+ (name) => !lazyNames.has(name));
49
+ // A remembered tool the host did not list as active still belongs in the
50
+ // set (defensive: the host controls what `getActiveTools` returns).
51
+ const desiredSet = new Set(desired);
52
+ for (const name of remembered) {
53
+ if (!desiredSet.has(name)) {
54
+ desired.push(name);
55
+ desiredSet.add(name);
56
+ }
57
+ }
58
+ const activeSet = new Set(active);
59
+ const removedCount = active.filter((name) => !desiredSet.has(name)).length;
60
+ const addedCount = desired.filter((name) => !activeSet.has(name)).length;
61
+ return {
62
+ desired,
63
+ addedCount,
64
+ removedCount,
65
+ changed: addedCount > 0 || removedCount > 0,
66
+ };
67
+ }
68
+ export function recordToolSetMutation(mutation) {
69
+ logLatency({
70
+ type: "phase",
71
+ filePath: "<pi-lens>",
72
+ phase: "tool_set_mutation",
73
+ durationMs: 0,
74
+ metadata: { ...mutation },
75
+ });
76
+ }
@@ -31,8 +31,56 @@ export const TREE_CACHE_COUNTER_KEYS = [
31
31
  "ghostHistoryDrops",
32
32
  ];
33
33
  export function createTreeCacheCounters() {
34
+ // SAFETY: `Object.fromEntries` returns `Record<string, number>` — it cannot
35
+ // prove the key set. `TREE_CACHE_COUNTER_KEYS` is declared `as const
36
+ // satisfies readonly (keyof TreeCacheCounters)[]`, so the compiler already
37
+ // rejects a key that is not a counter; every counter is a `number` and
38
+ // every key gets 0, so the result has the full shape. The `satisfies`
39
+ // clause does NOT check the reverse direction: add a counter to
40
+ // `TreeCacheCounters` without adding its key here and this cast becomes a
41
+ // lie. `tests/clients/tree-sitter-cache.test.ts` closes that direction with
42
+ // a compile-time `[Exclude<keyof TreeCacheCounters, …>] extends [never]`
43
+ // assertion, so a missing key fails `tsc`, not just the suite.
34
44
  return Object.fromEntries(TREE_CACHE_COUNTER_KEYS.map((key) => [key, 0]));
35
45
  }
46
+ /** Interactive-editing default: safe LRU footprint for per-edit locality. */
47
+ export const TREE_CACHE_DEFAULT_MAX_SIZE = 50;
48
+ /**
49
+ * Hard ceiling on how far a full-project scan may grow the tree cache
50
+ * (#1715). Entry count is not the resource that matters — WASM heap is
51
+ * (#417/#418, the leak this cache was fixed for once already) — so growing
52
+ * capacity to fit a scan's working set must still cap the heap's worst case,
53
+ * not just stop counting entries.
54
+ *
55
+ * Measured empirically on a fresh process (`heap-measure.mjs`, dropped from
56
+ * this PR — see the PR body): parsing 800 synthetic ~3.6KB TypeScript files
57
+ * with all 800 trees held resident (no eviction) grows `process.memoryUsage()
58
+ * .external` by ~254MB over the same run with only 1 tree resident at a
59
+ * time — about 330KB of non-V8 (WASM-backed) heap per resident tree on that
60
+ * sample. At the interactive default of 50 entries that is a ~16MB
61
+ * worst case; at this 500-entry ceiling it is a ~165MB worst case — bounded
62
+ * and stated, not unbounded growth.
63
+ */
64
+ export const TREE_CACHE_SCAN_CAPACITY_CEILING = 500;
65
+ /**
66
+ * Derive the capacity a full-project scan should grow the tree cache to
67
+ * (#1715): span the scan's file count so a second scan over the same files
68
+ * reuses every tree instead of re-parsing files the LRU evicted at the
69
+ * interactive default — bounded by `TREE_CACHE_SCAN_CAPACITY_CEILING` (or
70
+ * its `PI_LENS_TREE_SITTER_CACHE_SCAN_CAP` override) so the heap cost stated
71
+ * above stays a real ceiling. Never shrinks a capacity the cache already
72
+ * has — a later, smaller scan (or an unrelated caller) must not undo an
73
+ * earlier grow.
74
+ */
75
+ export function deriveScanTreeCacheCapacity(fileCount, currentMaxSize) {
76
+ const envRaw = process.env.PI_LENS_TREE_SITTER_CACHE_SCAN_CAP;
77
+ const envValue = envRaw !== undefined ? Number.parseInt(envRaw, 10) : Number.NaN;
78
+ const ceiling = Number.isSafeInteger(envValue) && envValue > 0
79
+ ? envValue
80
+ : TREE_CACHE_SCAN_CAPACITY_CEILING;
81
+ const target = Math.min(Math.max(fileCount, TREE_CACHE_DEFAULT_MAX_SIZE), ceiling);
82
+ return Math.max(currentMaxSize, target);
83
+ }
36
84
  export class TreeCache {
37
85
  cache = new Map();
38
86
  recentlyEvicted = new Map();
@@ -42,7 +90,7 @@ export class TreeCache {
42
90
  counters = createTreeCacheCounters();
43
91
  counterObserver;
44
92
  treeErrorObserver;
45
- constructor(maxSize = 50, debug = false, evictionHistoryMax = 4096, counterObserver, treeErrorObserver) {
93
+ constructor(maxSize = TREE_CACHE_DEFAULT_MAX_SIZE, debug = false, evictionHistoryMax = 4096, counterObserver, treeErrorObserver) {
46
94
  this.maxSize = maxSize;
47
95
  this.evictionHistoryMax = Math.max(1, Math.floor(evictionHistoryMax));
48
96
  this.counterObserver = counterObserver;
@@ -59,6 +107,32 @@ export class TreeCache {
59
107
  this.counters[key] += amount;
60
108
  this.counterObserver?.(key, amount);
61
109
  }
110
+ /** Current capacity ceiling (entry count, not bytes — see class docstring). */
111
+ getMaxSize() {
112
+ return this.maxSize;
113
+ }
114
+ /**
115
+ * Resize the capacity ceiling (#1715). Growing only changes the bound —
116
+ * existing entries are untouched. Shrinking evicts the LRU tail down to
117
+ * the new size through the same `removeEntry` path eviction uses, so a
118
+ * shrink still frees every dropped tree's WASM heap (#417) instead of
119
+ * silently orphaning it. `n` is floored at 1: a cache that can hold zero
120
+ * entries can never record a hit.
121
+ */
122
+ setMaxSize(n) {
123
+ const next = Math.max(1, Math.floor(n));
124
+ this.maxSize = next;
125
+ while (this.cache.size > this.maxSize) {
126
+ const firstKey = this.cache.keys().next().value;
127
+ if (firstKey === undefined)
128
+ break;
129
+ const evicted = this.cache.get(firstKey);
130
+ if (evicted)
131
+ this.rememberEviction(firstKey, evicted);
132
+ this.recordCounter("evictions");
133
+ this.removeEntry(firstKey);
134
+ }
135
+ }
62
136
  /**
63
137
  * Free a tree-sitter Tree's WASM-heap allocation.
64
138
  *