@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
@@ -213,11 +213,19 @@ Thanks goes to these wonderful people:
213
213
  </tr>
214
214
  <tr>
215
215
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/pppobear"><img src="https://avatars.githubusercontent.com/u/21952175?v=4" width="100px;" alt=""/><br /><sub><b>pppobear</b></sub></a><br /><a href="#bug-pppobear" title="Bug reports">🐛</a></td>
216
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/bcachet"><img src="https://avatars.githubusercontent.com/u/45542?v=4" width="100px;" alt=""/><br /><sub><b>Bertrand Cachet</b></sub></a><br /><a href="#code-bcachet" title="Code">💻</a></td>
217
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/EarthChen"><img src="https://avatars.githubusercontent.com/u/20179425?v=4" width="100px;" alt=""/><br /><sub><b>earthchen</b></sub></a><br /><a href="#code-EarthChen" title="Code">💻</a></td>
218
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/Don-Yin"><img src="https://avatars.githubusercontent.com/u/65135356?v=4" width="100px;" alt=""/><br /><sub><b>Don Yin</b></sub></a><br /><a href="#code-Don-Yin" title="Code">💻</a></td>
219
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/ELA718"><img src="https://avatars.githubusercontent.com/u/193304463?v=4" width="100px;" alt=""/><br /><sub><b>ELA718</b></sub></a><br /><a href="#doc-ELA718" title="Documentation">📖</a></td>
220
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/sujeito-operator/pilot"><img src="https://avatars.githubusercontent.com/u/313599463?v=4" width="100px;" alt=""/><br /><sub><b>Sujeito Operator</b></sub></a><br /><a href="#code-sujeito-operator" title="Code">💻</a></td>
221
+ <td align="center" valign="top" width="14.28%"><a href="http://www.blahs.life/"><img src="https://avatars.githubusercontent.com/u/620336?v=4" width="100px;" alt=""/><br /><sub><b>Dan Blah</b></sub></a><br /><a href="#bug-danblah" title="Bug reports">🐛</a></td>
222
+ </tr>
223
+ <tr>
216
224
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/3choBoomer"><img src="https://avatars.githubusercontent.com/u/521828?v=4" width="100px;" alt=""/><br /><sub><b>Nathan Cooke</b></sub></a><br /><a href="#code-3choBoomer" title="Code">💻</a></td>
217
225
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/white-hat"><img src="https://avatars.githubusercontent.com/u/922988?v=4" width="100px;" alt=""/><br /><sub><b>Eli Stark</b></sub></a><br /><a href="#code-white-hat" title="Code">💻</a></td>
218
- <td align="center" valign="top" width="14.28%"><a href="https://github.com/marvtub"><img src="https://avatars.githubusercontent.com/u/33159023?v=4" width="100px;" alt=""/><br /><sub><b>Marvin Aziz</b></sub></a><br /><a href="#code-marvtub" title="Code">💻</a></td>
219
- <td align="center" valign="top" width="14.28%"><a href="https://github.com/mjfaga"><img src="https://avatars.githubusercontent.com/u/7584015?v=4" width="100px;" alt=""/><br /><sub><b>Mark Faga</b></sub></a><br /><a href="#code-mjfaga" title="Code">💻</a></td>
220
- <td align="center" valign="top" width="14.28%"><a href="https://github.com/aeturnal"><img src="https://avatars.githubusercontent.com/u/219271200?v=4" width="100px;" alt=""/><br /><sub><b>aeturnal</b></sub></a><br /><a href="#code-aeturnal" title="Code">💻</a></td>
226
+ <td align="center" valign="top" width="14.28%"><a href="https://marvinaziz.de/"><img src="https://avatars.githubusercontent.com/u/33159023?v=4" width="100px;" alt=""/><br /><sub><b>Marvin Aziz</b></sub></a><br /><a href="#code-marvtub" title="Code">💻</a></td>
227
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/mjfaga"><img src="https://avatars.githubusercontent.com/u/7584015?v=4" width="100px;" alt=""/><br /><sub><b>Mark</b></sub></a><br /><a href="#code-mjfaga" title="Code">💻</a></td>
228
+ <td align="center" valign="top" width="14.28%"><a href="https://aeturnal.io/"><img src="https://avatars.githubusercontent.com/u/219271200?v=4" width="100px;" alt=""/><br /><sub><b>aeturnal</b></sub></a><br /><a href="#code-aeturnal" title="Code">💻</a></td>
221
229
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/floatGray"><img src="https://avatars.githubusercontent.com/u/44295302?v=4" width="100px;" alt=""/><br /><sub><b>floatGray</b></sub></a><br /><a href="#code-floatGray" title="Code">💻</a></td>
222
230
  </tr>
223
231
  </tbody>
@@ -16,10 +16,52 @@ select = [
16
16
  "SIM", # flake8-simplify (simplifiable constructs)
17
17
  "C4", # flake8-comprehensions (unnecessary comprehension patterns)
18
18
  "PIE", # flake8-pie (misc lints)
19
+ "S", # flake8-bandit (Bandit-equivalent security checks; refs #1757)
19
20
  ]
20
21
 
22
+ # C90 (mccabe cyclomatic complexity) — considered and NOT enabled (refs #1757).
23
+ # Measured against `requests` (mature, well-styled: 2 hits over the default
24
+ # threshold of 10, both genuinely complex) and `pandas` (379 hits) — the
25
+ # signal is real complexity, not false positives, but the volume on a large
26
+ # pre-existing codebase would drown the security signal `S` adds in the same
27
+ # pass. C90 is a maintainability metric, not a Bandit-equivalent security
28
+ # check, so it stays out of scope for this issue. Revisit as its own opt-in
29
+ # if pi-lens grows a "code health" ruleset.
30
+
31
+ # S sub-rules excluded below were triaged by running `ruff check --select S`
32
+ # against tests/fixtures/real-bugs/python/silent-and-security.py (this repo's
33
+ # own security fixture — 3/3 true positives: S110, S105, S307) and against the
34
+ # `requests` and `pip` packages installed under a local Python 3.11 (394
35
+ # combined S findings across two mature, widely-audited real-world
36
+ # codebases) — chosen as the "2-3 real fixtures" because pi-lens's own repo
37
+ # only has ~15 Python files, too small to expose over-firing sub-rules.
21
38
  ignore = [
22
39
  "E501", # line too long — formatter handles this
23
40
  "B008", # function call in default argument — common FastAPI/typer pattern
24
41
  "SIM108", # ternary operator — readability is subjective
42
+
43
+ # S101 assert: 354 of 394 S hits (90%) across requests+pip were bare
44
+ # `assert` statements — the risk `S101` warns about (asserts stripped under
45
+ # `python -O`) is real only for security-enforcement code, not general
46
+ # application or test code, where `assert` is idiomatic (pytest). Pure
47
+ # noise at this volume.
48
+ "S101",
49
+ # S311 suspicious-non-cryptographic-random-usage: every hit observed
50
+ # (e.g. pip/_internal/utils/filesystem.py building a temp-file suffix) was
51
+ # a non-security use of `random` — file names, jitter, sampling. Ruff
52
+ # cannot distinguish security-sensitive randomness from ordinary use.
53
+ "S311",
54
+ # S603 subprocess-without-shell-equals-true: fires on every list-argument
55
+ # `subprocess.run(...)`/`Popen(...)` call regardless of whether the
56
+ # arguments are attacker-controlled — this is the RECOMMENDED safe form
57
+ # (no shell=True), yet it was the rule's only trigger condition in every
58
+ # one of the 10 hits observed in pip. Bandit's own docs note this rule's
59
+ # high false-positive rate; excluded for the same reason upstream projects
60
+ # commonly disable it.
61
+ "S603",
62
+ # S607 start-process-with-partial-path: fires whenever a subprocess call
63
+ # names its executable by PATH lookup (`["rustc", "--version"]`) instead of
64
+ # an absolute path — standard practice for any CLI-wrapping code, and both
65
+ # observed hits in pip were exactly that pattern, not a real vulnerability.
66
+ "S607",
25
67
  ]
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import * as fs from "node:fs";
3
3
  import * as path from "node:path";
4
+ import { hashText, normalizeMessage, stableFindingId, } from "./finding-identity.js";
4
5
  import { applyWorkspaceEdit } from "./lsp/edits.js";
5
6
  import { getLSPService } from "./lsp/index.js";
6
7
  import { normalizeMapKey } from "./path-utils.js";
@@ -14,19 +15,47 @@ let beforeWarningStateLockForTests = null;
14
15
  export function _setBeforeWarningStateLockForTests(hook) {
15
16
  beforeWarningStateLockForTests = hook;
16
17
  }
17
- function normalizeMessage(message) {
18
- return message.replace(/\s+/g, " ").trim().toLowerCase();
19
- }
20
- function hashText(value, length = 10) {
21
- return createHash("sha256").update(value).digest("hex").slice(0, length);
22
- }
23
- function relativeFile(filePath, cwd) {
24
- const rel = path.relative(cwd, filePath).replace(/\\/g, "/");
25
- return rel && !rel.startsWith("..") ? rel : normalizeMapKey(filePath);
26
- }
18
+ /** #1816: was a local `relativeFile|tool|source|code|rule|normalizedMessage|
19
+ * line` hash, hand-rolled independently of `diagnostic-dispositions.ts`'s
20
+ * canonicalizing version — this is now the shared `finding-identity.js`
21
+ * builder (which DOES canonicalize both `cwd` and `filePath` through
22
+ * `normalizeMapKey` before relativizing, and hashes to 12 chars, matching
23
+ * dispositions). See `legacyActionableWarningId` below for the pre-#1816
24
+ * formula, kept only for on-disk suppression-store migration. */
27
25
  export function createActionableWarningId(args) {
26
+ return stableFindingId("aw:", {
27
+ cwd: args.cwd,
28
+ filePath: args.filePath,
29
+ parts: [
30
+ args.tool,
31
+ args.source,
32
+ args.code,
33
+ args.rule,
34
+ normalizeMessage(args.message),
35
+ args.line,
36
+ ],
37
+ });
38
+ }
39
+ /** PRE-#1816 id formula (raw, non-canonicalized `relativeFile`; 10-char
40
+ * hash). `actionable-warning-state.json` is a keyed, persisted store — a
41
+ * warning suppressed under the old formula must not silently reappear as
42
+ * unsuppressed just because this module unified onto the canonical,
43
+ * 12-char id. `suppressionFor`/`updateWarningState` use this ONLY to look up
44
+ * and migrate a still-pending old entry forward; nothing ever WRITES under
45
+ * this id. Do not canonicalize this function — that would make it identical
46
+ * to `createActionableWarningId` and silently defeat the migration lookup
47
+ * for every path that actually needed canonicalizing (the #533 class this
48
+ * whole item exists to fix). Review-round F3 (#1816): this guard is only
49
+ * provable under a MIS-CASED path fixture — a fixture whose raw and
50
+ * canonical forms coincide (a bare mkdtempSync path) makes canonicalizing
51
+ * this function a no-op, so the regression test must seed under a mis-cased
52
+ * segment (see `actionable-warnings.test.ts`'s migration describe block) or
53
+ * the guard passes vacuously either way. */
54
+ function legacyActionableWarningId(args) {
55
+ const rel = path.relative(args.cwd, args.filePath).replace(/\\/g, "/");
56
+ const legacyRelativeFile = rel && !rel.startsWith("..") ? rel : normalizeMapKey(args.filePath);
28
57
  const parts = [
29
- relativeFile(args.filePath, args.cwd),
58
+ legacyRelativeFile,
30
59
  args.tool ?? "",
31
60
  args.source ?? "",
32
61
  String(args.code ?? ""),
@@ -34,7 +63,7 @@ export function createActionableWarningId(args) {
34
63
  normalizeMessage(args.message),
35
64
  String(args.line ?? ""),
36
65
  ];
37
- return `aw:${hashText(parts.join("|"))}`;
66
+ return `aw:${hashText(parts.join("|"), 10)}`;
38
67
  }
39
68
  function actionSafety(action) {
40
69
  const kind = action.kind ?? "";
@@ -93,7 +122,28 @@ function updateWarningState(cwd, warnings) {
93
122
  const now = new Date().toISOString();
94
123
  state.warnings ??= {};
95
124
  for (const warning of warnings) {
96
- const existing = state.warnings[warning.id] ?? {};
125
+ // #1816 migration: this warning may still be recorded under the
126
+ // pre-#1816 id (raw relativeFile, 10-char hash) from before this
127
+ // store unified onto the canonical id. Fold that entry forward
128
+ // onto the current id and drop the stale key, so a warning
129
+ // suppressed before the migration stays suppressed, and repeated
130
+ // re-encounters converge the store onto one id per warning
131
+ // instead of accumulating both forever.
132
+ //
133
+ // Review-round F1: this MUST read `warning.legacyId` — the value
134
+ // `suppressionFor` already computed from the exact identity args
135
+ // used at lookup time — and must NEVER re-derive a legacy id from
136
+ // `warning.rule`/`tool`/`source`/`code`. Those fields hold
137
+ // DISPLAY values that diverge from the id-construction args for
138
+ // LSP-origin records (see `ActionableWarningRecord.legacyId`'s
139
+ // doc comment), so a re-derivation here would compute a
140
+ // different legacy id than the one `suppressionFor` checked,
141
+ // permanently bifurcating the store.
142
+ const legacyId = warning.legacyId;
143
+ const legacyEntry = legacyId && legacyId !== warning.id
144
+ ? state.warnings[legacyId]
145
+ : undefined;
146
+ const existing = state.warnings[warning.id] ?? legacyEntry ?? {};
97
147
  state.warnings[warning.id] = {
98
148
  ...existing,
99
149
  status: existing.status ?? "active",
@@ -101,6 +151,8 @@ function updateWarningState(cwd, warnings) {
101
151
  lastSeenAt: now,
102
152
  seenCount: (existing.seenCount ?? 0) + 1,
103
153
  };
154
+ if (legacyEntry && legacyId)
155
+ delete state.warnings[legacyId];
104
156
  }
105
157
  return state;
106
158
  },
@@ -115,36 +167,64 @@ function updateWarningState(cwd, warnings) {
115
167
  }),
116
168
  });
117
169
  }
118
- function suppressionFor(cwd, id) {
119
- const entry = readSuppressionState(cwd).warnings?.[id];
170
+ /** Looks up suppression under the current id, falling back to the pre-#1816
171
+ * id (see `legacyActionableWarningId`) so a warning suppressed before this
172
+ * migration doesn't silently reappear as unsuppressed. `args` is the exact
173
+ * identity shape both id builders take.
174
+ *
175
+ * Also RETURNS the `legacyId` it computed (review-round F1, #1816): the
176
+ * caller carries it onto the record's `legacyId` field so
177
+ * `updateWarningState` can migrate the SAME legacy id this lookup used,
178
+ * instead of re-deriving one from the record's own `rule`/`tool`/`source`/
179
+ * `code` fields later. Re-deriving is unsound for LSP-origin records —
180
+ * `recordFromLspDiagnostic` passes no `rule` into this function (LSP
181
+ * diagnostics don't have one), then sets `record.rule` afterward to
182
+ * `${source}:${code}` purely for display. Recomputing from that display
183
+ * value would silently compute a DIFFERENT legacy id than the one actually
184
+ * checked here, permanently bifurcating the store: a suppression written
185
+ * this turn under the current id would never be found again next turn. */
186
+ function suppressionFor(cwd, id, args) {
187
+ const state = readSuppressionState(cwd);
188
+ const legacyId = legacyActionableWarningId({ cwd, ...args });
189
+ const entry = state.warnings?.[id] ??
190
+ (legacyId !== id ? state.warnings?.[legacyId] : undefined);
120
191
  return {
121
192
  suppressed: entry?.status === "suppressed",
122
193
  reason: entry?.reason,
194
+ legacyId,
123
195
  };
124
196
  }
125
197
  export function recordFromDispatchDiagnostic(diagnostic, cwd) {
126
- if (diagnostic.semantic !== "warning" || diagnostic.severity !== "warning")
198
+ if (diagnostic.semantic !== "warning")
199
+ return undefined;
200
+ // #1777: the old gate demanded `severity === "warning"` exactly, which was
201
+ // invisible while the ast-grep runner collapsed every non-error tier to
202
+ // "warning". Now that hint and info survive the dispatch path, admit them:
203
+ // a fix is a fix, and the tier governs how loudly a finding renders, not
204
+ // whether its fix is worth offering. `error` still routes to the blocking
205
+ // path, so it stays out even when a runner leaves `semantic` at "warning".
206
+ if (diagnostic.severity === "error")
127
207
  return undefined;
128
208
  if (!diagnostic.fixable && !diagnostic.fixSuggestion)
129
209
  return undefined;
130
210
  const filePath = path.resolve(cwd, diagnostic.filePath);
131
- const id = createActionableWarningId({
132
- cwd,
211
+ const identityArgs = {
133
212
  filePath,
134
213
  tool: diagnostic.tool,
135
214
  code: diagnostic.code,
136
215
  rule: diagnostic.rule,
137
216
  message: diagnostic.message,
138
217
  line: diagnostic.line,
139
- });
140
- const suppression = suppressionFor(cwd, id);
218
+ };
219
+ const id = createActionableWarningId({ cwd, ...identityArgs });
220
+ const suppression = suppressionFor(cwd, id, identityArgs);
141
221
  return {
142
222
  id,
143
223
  filePath,
144
224
  displayPath: toRunnerDisplayPath(cwd, filePath),
145
225
  line: diagnostic.line,
146
226
  column: diagnostic.column,
147
- severity: "warning",
227
+ severity: diagnostic.severity,
148
228
  tool: diagnostic.tool,
149
229
  code: diagnostic.code,
150
230
  rule: diagnostic.rule,
@@ -155,6 +235,7 @@ export function recordFromDispatchDiagnostic(diagnostic, cwd) {
155
235
  actions: [],
156
236
  suppressed: suppression.suppressed,
157
237
  suppressionReason: suppression.reason,
238
+ legacyId: suppression.legacyId,
158
239
  origin: "dispatch",
159
240
  };
160
241
  }
@@ -170,16 +251,16 @@ function recordFromLspDiagnostic(diag, filePath, cwd) {
170
251
  const column = diag.range.start.character + 1;
171
252
  const source = diag.source ?? "lsp";
172
253
  const code = diag.code === undefined ? undefined : String(diag.code);
173
- const id = createActionableWarningId({
174
- cwd,
254
+ const identityArgs = {
175
255
  filePath,
176
256
  tool: "lsp",
177
257
  source,
178
258
  code,
179
259
  message: diag.message,
180
260
  line,
181
- });
182
- const suppression = suppressionFor(cwd, id);
261
+ };
262
+ const id = createActionableWarningId({ cwd, ...identityArgs });
263
+ const suppression = suppressionFor(cwd, id, identityArgs);
183
264
  return {
184
265
  id,
185
266
  filePath,
@@ -195,6 +276,7 @@ function recordFromLspDiagnostic(diag, filePath, cwd) {
195
276
  actions: [],
196
277
  suppressed: suppression.suppressed,
197
278
  suppressionReason: suppression.reason,
279
+ legacyId: suppression.legacyId,
198
280
  origin: "lsp",
199
281
  };
200
282
  }
@@ -329,8 +411,13 @@ export async function buildActionableWarningsReport(args) {
329
411
  }
330
412
  const merged = mergeWarnings(records);
331
413
  updateWarningState(cwd, merged);
414
+ // legacyId is #1816 migration bookkeeping for updateWarningState above —
415
+ // strip it before the report leaves this function, so it never lands in
416
+ // the `.pi-lens/cache/actionable-warnings.json` cache file or any
417
+ // agent-facing rendering of a warning record.
418
+ const reportWarnings = merged.map(({ legacyId: _legacyId, ...rest }) => rest);
332
419
  const byFile = new Map();
333
- for (const warning of merged) {
420
+ for (const warning of reportWarnings) {
334
421
  const arr = byFile.get(warning.filePath) ?? [];
335
422
  arr.push(warning);
336
423
  byFile.set(warning.filePath, arr);
@@ -342,9 +429,16 @@ export async function buildActionableWarningsReport(args) {
342
429
  warnings,
343
430
  }));
344
431
  const allActions = merged.flatMap((warning) => warning.actions);
432
+ const unsuppressed = merged.filter((warning) => !warning.suppressed);
433
+ const countTier = (tier) => unsuppressed.filter((warning) => warning.severity === tier).length;
345
434
  const summary = {
346
435
  warnings: merged.length,
347
- unsuppressed: merged.filter((warning) => !warning.suppressed).length,
436
+ unsuppressed: unsuppressed.length,
437
+ byTier: {
438
+ warning: countTier("warning"),
439
+ info: countTier("info"),
440
+ hint: countTier("hint"),
441
+ },
348
442
  suppressed: merged.filter((warning) => warning.suppressed).length,
349
443
  files: files.length,
350
444
  actions: allActions.length,
@@ -586,8 +680,17 @@ export function formatActionableWarningsAdvisory(report) {
586
680
  const safe = report.summary.autoFixEligible > 0
587
681
  ? ` ${report.summary.autoFixEligible} appear to have conservative preferred quickfixes.`
588
682
  : "";
683
+ // #1777: hint and info are style opinions, so say how much of the count is
684
+ // opinion. The line appears only when a quiet tier is actually present —
685
+ // an all-warning turn already says everything in the count above.
686
+ const byTier = report.summary.byTier;
687
+ const quiet = byTier ? byTier.hint + byTier.info : 0;
688
+ const tierLine = quiet > 0
689
+ ? `${quiet} of those are hint/info tier — style opinions, worth fixing only while you are already in that code.`
690
+ : undefined;
589
691
  return [
590
692
  `🟡 Fixable warnings introduced this turn: ${report.summary.unsuppressed}.${safe}`,
693
+ tierLine,
591
694
  `Details written to .pi-lens/cache/actionable-warnings.json`,
592
695
  fileList ? `Files:\n${fileList}${more}` : undefined,
593
696
  "If continuing in these files, read that JSON and resolve warnings that are safe and relevant. Do not apply broad refactors unless requested.",