@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
@@ -1390,8 +1390,17 @@ export class TestRunnerClient {
1390
1390
  const output = `${stdout}\n${stderr}`;
1391
1391
  const lower = output.toLowerCase();
1392
1392
  let passed = 0;
1393
- let failed = exitCode === 0 ? 0 : 1;
1393
+ // #1487: NOT `exitCode === 0 ? 0 : 1`. Pre-seeding `failed` to 1 on a
1394
+ // non-zero exit made the runner-error branch below unreachable — it
1395
+ // requires `failed === 0`, which a spawn/config/load failure (no
1396
+ // counts to parse) could never reach once this had already claimed
1397
+ // the slot. `matched` tracks whether a count parser actually found
1398
+ // real counts; the exit-code-distrust fallback further down uses it
1399
+ // to tell "a runner that never ran" from "a runner whose summary
1400
+ // legitimately parsed to zero failures".
1401
+ let failed = 0;
1394
1402
  let skipped = 0;
1403
+ let matched = false;
1395
1404
  // #1480: `number | undefined`, and sourced per runner. This used to be
1396
1405
  // `let duration = 0` with only go's probe able to move it, so every
1397
1406
  // other runner reported a zero it never measured.
@@ -1401,12 +1410,14 @@ export class TestRunnerClient {
1401
1410
  passed = Number.parseInt(cargoSummary[1], 10);
1402
1411
  failed = Number.parseInt(cargoSummary[2], 10);
1403
1412
  skipped = Number.parseInt(cargoSummary[3], 10);
1413
+ matched = true;
1404
1414
  }
1405
1415
  const dotnetSummary = output.match(/Failed:\s*(\d+),\s*Passed:\s*(\d+),\s*Skipped:\s*(\d+)/i);
1406
1416
  if (dotnetSummary) {
1407
1417
  failed = Number.parseInt(dotnetSummary[1], 10);
1408
1418
  passed = Number.parseInt(dotnetSummary[2], 10);
1409
1419
  skipped = Number.parseInt(dotnetSummary[3], 10);
1420
+ matched = true;
1410
1421
  }
1411
1422
  // #1480 (adjacent, duration-independent): surefire prints one
1412
1423
  // `Tests run:` line PER TEST CLASS (those carry `Time elapsed:`) and
@@ -1444,12 +1455,14 @@ export class TestRunnerClient {
1444
1455
  failed = mavenFailed;
1445
1456
  skipped = mavenSkipped;
1446
1457
  passed = Math.max(0, total - failed - skipped);
1458
+ matched = true;
1447
1459
  }
1448
1460
  const rspecSummary = output.match(/(\d+)\s+examples?,\s+(\d+)\s+failures?/i);
1449
1461
  if (rspecSummary) {
1450
1462
  const total = Number.parseInt(rspecSummary[1], 10);
1451
1463
  failed = Number.parseInt(rspecSummary[2], 10);
1452
1464
  passed = Math.max(0, total - failed);
1465
+ matched = true;
1453
1466
  }
1454
1467
  const minitestSummary = output.match(/(\d+)\s+runs?,\s+\d+\s+assertions?,\s+(\d+)\s+failures?,\s+(\d+)\s+errors?/i);
1455
1468
  if (minitestSummary) {
@@ -1458,41 +1471,160 @@ export class TestRunnerClient {
1458
1471
  const errors = Number.parseInt(minitestSummary[3], 10);
1459
1472
  failed = failures + errors;
1460
1473
  passed = Math.max(0, total - failed);
1474
+ matched = true;
1461
1475
  }
1462
1476
  const gradleSummary = output.match(/(\d+)\s+tests? completed,\s+(\d+)\s+failed/i);
1463
1477
  if (gradleSummary) {
1464
1478
  const total = Number.parseInt(gradleSummary[1], 10);
1465
1479
  failed = Number.parseInt(gradleSummary[2], 10);
1466
1480
  passed = Math.max(0, total - failed);
1481
+ matched = true;
1482
+ }
1483
+ // #1487/#1524/#1524-r3: `--- FAIL: TestName` is extracted first and
1484
+ // separately from the other two name patterns, because it is the
1485
+ // ONLY one of the three that is unambiguous evidence a real go test
1486
+ // ran — see the `runnerError` comment below for why the other two
1487
+ // may no longer veto on their own. go otherwise has no count parser
1488
+ // at all (only a duration probe), so without this go's `matched`
1489
+ // stayed false even on a real failure.
1490
+ //
1491
+ // #1524-r3: go ALSO gets a real count parser here, not just a name
1492
+ // extractor. A panic inside `TestMain`/package `init` (exit 2) never
1493
+ // prints a `--- FAIL:` line — there is no test to name, the process
1494
+ // died before any test ran — so `goFailNames` alone left `matched`
1495
+ // false and such a panic hit the same runner-error branch as a
1496
+ // spawn failure, even though `go test` DID run and DID fail. `FAIL
1497
+ // \t<pkg>` is go's own per-package verdict line and is printed for
1498
+ // exactly this case; `ok <pkg> <n>s` is its pass counterpart.
1499
+ // Package-line counts, like the go duration probe above, take the
1500
+ // FIRST package summary only — the same known limit already
1501
+ // documented on `parseGenericRunnerDuration`.
1502
+ const goFailNames = [
1503
+ ...output.matchAll(/--- FAIL:[^\S\n]+([^\s(]+)/g),
1504
+ ];
1505
+ // #1524-r4: only COUNT unparented failures. go prints a `--- FAIL:`
1506
+ // line for every level of a failing subtest tree — `TestA` AND
1507
+ // `TestA/sub` each get their own line for what is really one
1508
+ // underlying failure — so counting every line inflated `failed`
1509
+ // (two lines here read as two failures for one broken test). A name
1510
+ // containing "/" whose prefix up to that "/" is itself in the list
1511
+ // is a subtest of an already-counted parent; only names that are
1512
+ // NOT such a subtest count. `goFailNames` itself (all lines) is
1513
+ // still what decides `matched`/the runner-error veto below and
1514
+ // what's listed in `failures` — subtest names are still useful
1515
+ // detail there, just not double-counted.
1516
+ const goFailNameSet = new Set(goFailNames.map((m) => m[1].trim()));
1517
+ const goTopLevelFailCount = goFailNames.filter((m) => {
1518
+ const name = m[1].trim();
1519
+ const slash = name.indexOf("/");
1520
+ return slash === -1 || !goFailNameSet.has(name.slice(0, slash));
1521
+ }).length;
1522
+ if (runner === "go") {
1523
+ // #1524-r4: `(?![^\n]*\[(?:build|setup) failed\])` rejects go's
1524
+ // INFRASTRUCTURE verdict lines — `FAIL <pkg> [build failed]` (a
1525
+ // compile error) and `FAIL <pkg> [setup failed]` (no packages to
1526
+ // test) — which matched the same shape as a real `FAIL <pkg>
1527
+ // <duration>` test verdict line. Neither ran a single test; both
1528
+ // were rendering as `✗ 1/1 failed ✗ go failure` instead of the
1529
+ // runner error they are.
1530
+ const goFailPackage = /^FAIL(?![^\n]*\[(?:build|setup) failed\])[^\S\n]+\S+/m.test(output);
1531
+ const goOkPackages = [
1532
+ ...output.matchAll(/^ok[^\S\n]+\S+[^\S\n]+[\d.]+s/gm),
1533
+ ];
1534
+ if (goFailNames.length > 0 || goFailPackage) {
1535
+ failed = Math.max(failed, goTopLevelFailCount || 1);
1536
+ matched = true;
1537
+ }
1538
+ // #1524-r4: unconditional, not `else if`. A multi-package run
1539
+ // can have BOTH a real failure and packages that passed clean —
1540
+ // `ok a` / `--- FAIL: TestB` / `ok c` is 2 passed AND 1 failed,
1541
+ // not "1 failed, 0 passed" with the green packages silently
1542
+ // dropped because the fail branch above already ran.
1543
+ if (goOkPackages.length > 0) {
1544
+ passed = Math.max(passed, goOkPackages.length);
1545
+ matched = true;
1546
+ }
1467
1547
  }
1468
- // Captured BEFORE the guard below, which rewrites `failed` out of the
1469
- // state this condition reads. Without this the runner-error string
1470
- // silently became unreachable.
1471
- const runnerError = exitCode !== 0 && failed === 0 && lower.includes("error")
1548
+ // #1524-r3: anchored to line START (`^`), and `[^\S\n]` (horizontal
1549
+ // whitespace only) in place of `\s` between the keyword and the
1550
+ // name. The prior `\bFAILED\s+([^\n]+)` and `Failure:\s+([^\n]+)`
1551
+ // let their OWN `\s+` gap cross the newline: a bare `FAILED` at the
1552
+ // end of a line has nothing after it on that line, so `\s+` ate the
1553
+ // newline itself and `([^\n]+)` captured the FIRST TOKEN OF THE
1554
+ // NEXT LINE as the "test name" — proven on a gradle compile failure
1555
+ // (`> Task :compileJava FAILED` followed by
1556
+ // `FAILURE: Build failed with an exception.`, which then rendered
1557
+ // as the invented failure name) and the newline-spanning shape in
1558
+ // general (`FAILED\n\nsome trailing note` → name "some trailing
1559
+ // note"). Requiring `(\S.*)$` on the SAME line makes a keyword with
1560
+ // nothing following it on that line simply not match, rather than
1561
+ // reaching across for content that was never the name.
1562
+ const failures = [];
1563
+ for (const m of goFailNames.slice(0, 5)) {
1564
+ failures.push({ name: m[1].trim(), message: m[1].trim() });
1565
+ }
1566
+ const otherNames = [
1567
+ ...output.matchAll(/^[^\S\n]*FAILED[^\S\n]+(\S.*)$/gm),
1568
+ ...output.matchAll(/^[^\S\n]*Failure:[^\S\n]+(\S.*)$/gm),
1569
+ ];
1570
+ for (const m of otherNames) {
1571
+ if (failures.length >= 5)
1572
+ break;
1573
+ failures.push({ name: m[1].trim(), message: m[1].trim() });
1574
+ }
1575
+ // #1487: gated on `!matched`, not on `failed === 0`. A non-zero exit
1576
+ // with NO count parser match — a spawn/config/load failure, nothing
1577
+ // ran — is infrastructure, not a test verdict: report it as a runner
1578
+ // error. A non-zero exit a count parser DID match (even to a
1579
+ // legitimate `failed === 0`, e.g. a green last module of a red
1580
+ // reactor) is a real run that produced real counts, so it is never a
1581
+ // runner error, and the exit-code-distrust guard below still forces
1582
+ // at least one failure so it can't render as PASS.
1583
+ //
1584
+ // #1524-r3: the veto is `goFailNames.length === 0`, NOT
1585
+ // `failures.length === 0`. Only `--- FAIL:` is a marker a test
1586
+ // runner emits SPECIFICALLY for a failed test; `FAILED`/`Failure:`
1587
+ // are generic words a build tool prints for reasons that have
1588
+ // nothing to do with a test — a gradle task failing to compile, a
1589
+ // maven goal failing before surefire ever runs, an rspec file that
1590
+ // never loaded. Letting those two veto the runner-error branch on
1591
+ // their own reintroduced #1487's exact symptom for the commonest
1592
+ // gradle/maven/rspec failure shapes (proven: `[ERROR] Failed to
1593
+ // execute goal ... FAILED` and rspec's `Failure: cannot load such
1594
+ // file` both rendered as a fabricated test failure instead of the
1595
+ // runner error they actually are). They still label a name onto
1596
+ // `failures` above when `matched` or `goFailNames` already settled
1597
+ // the question some other way, but they no longer settle it alone.
1598
+ const runnerError = exitCode !== 0 && !matched && goFailNames.length === 0 && lower.includes("error")
1472
1599
  ? `Runner ${runner} exited with ${exitCode}`
1473
1600
  : undefined;
1601
+ // #1524-r4 (tidy): a runner-error result reports through
1602
+ // `formatResult`'s runner-error branch, not the failed-tests
1603
+ // branch, so any name `otherNames` picked up before this was
1604
+ // decided (e.g. a same-line `Failure: cannot load such file`)
1605
+ // would sit in `failures` unused but visible to anything reading
1606
+ // the raw `TestResult` — an error result with a non-empty
1607
+ // `failures` list is a self-contradiction. Clear it here so the
1608
+ // result is one or the other, never both.
1609
+ if (runnerError) {
1610
+ failures.length = 0;
1611
+ }
1474
1612
  // #1480 (adjacent): a non-zero exit is the runner saying the run
1475
1613
  // failed. Every count parser above can legitimately arrive at
1476
1614
  // `failed === 0` — a summary that only covers part of the run, a green
1477
1615
  // module of a red reactor build, a failure outside any test — and the
1478
1616
  // turn-end log would then print PASS over a build the runner rejected.
1479
1617
  // Trust the exit code: no parse of the text may talk it out of at least
1480
- // one failure.
1481
- if (exitCode !== 0 && failed === 0) {
1618
+ // one failure. Skipped when `runnerError` is set — that case already
1619
+ // reports through `formatResult`'s runner-error branch, which requires
1620
+ // `passed === 0 && failed === 0` to stay reachable, and forcing
1621
+ // `failed` to 1 here would make it unreachable again (#1487).
1622
+ if (exitCode !== 0 && failed === 0 && !runnerError) {
1482
1623
  failed = 1;
1483
1624
  }
1484
1625
  if (passed === 0 && failed === 0 && skipped === 0 && exitCode === 0) {
1485
1626
  passed = 1;
1486
1627
  }
1487
- const failures = [];
1488
- const names = [
1489
- ...output.matchAll(/--- FAIL:\s+([^\s(]+)/g),
1490
- ...output.matchAll(/\bFAILED\s+([^\n]+)/g),
1491
- ...output.matchAll(/Failure:\s+([^\n]+)/g),
1492
- ];
1493
- for (const m of names.slice(0, 5)) {
1494
- failures.push({ name: m[1].trim(), message: m[1].trim() });
1495
- }
1496
1628
  if (failures.length === 0 && failed > 0) {
1497
1629
  const firstLine = output
1498
1630
  .split("\n")
@@ -1501,6 +1633,9 @@ export class TestRunnerClient {
1501
1633
  .slice(0, 300) || `Tests failed for runner ${runner}`;
1502
1634
  failures.push({ name: `${runner} failure`, message: firstLine });
1503
1635
  }
1636
+ this.log(runnerError
1637
+ ? `Generic runner ${runner}: never started (${runnerError})`
1638
+ : `Generic runner ${runner}: ran (matched=${matched}, passed=${passed}, failed=${failed}, failures=${failures.length})`);
1504
1639
  return {
1505
1640
  file: testFile,
1506
1641
  sourceFile: "",
@@ -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
@@ -2025,10 +2034,17 @@ export function ruffConfigArgs(cwd) {
2025
2034
  * `config/biome/core.jsonc` fallback — applies on `lint --write` too.
2026
2035
  */
2027
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 [];
2028
2046
  return [
2029
- "--config-path=" +
2030
- (getBiomeConfigPath(cwd) ??
2031
- resolvePackagePath(import.meta.url, "config/biome/core.jsonc")),
2047
+ "--config-path=" + resolvePackagePath(import.meta.url, "config/biome/core.jsonc"),
2032
2048
  ];
2033
2049
  }
2034
2050
  export function hasGolangciConfig(cwd) {
@@ -2079,6 +2095,89 @@ export function hasCmakeFormatConfig(cwd) {
2079
2095
  "cmake-format.yml",
2080
2096
  ]) !== undefined);
2081
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
+ }
2082
2181
  export function hasPhpstanConfig(cwd) {
2083
2182
  return findNearestContaining(cwd, PHPSTAN_CONFIGS) !== undefined;
2084
2183
  }
@@ -2283,10 +2382,16 @@ const COMPILED_CLASSES_DIRS = [
2283
2382
  path.join("out", "production"),
2284
2383
  path.join("bin", "main"),
2285
2384
  ];
2286
- export function hasJavaBuildDescriptor(cwd) {
2385
+ export function hasJavaBuildDescriptor(cwd, ceiling) {
2386
+ const normalizedCeiling = ceiling
2387
+ ? normalizeMapKey(path.resolve(ceiling))
2388
+ : undefined;
2287
2389
  for (const dir of walkUpDirs(cwd)) {
2288
2390
  if (JAVA_BUILD_DESCRIPTORS.some((d) => fs.existsSync(path.join(dir, d))))
2289
2391
  return true;
2392
+ if (normalizedCeiling &&
2393
+ normalizeMapKey(path.resolve(dir)) === normalizedCeiling)
2394
+ break;
2290
2395
  }
2291
2396
  return false;
2292
2397
  }