@herbertgao/pi-extensions 2026.8.6 → 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 (343) hide show
  1. package/README.md +5 -5
  2. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +1 -1
  3. package/node_modules/@herbertgao/pi-cc-extensions/README.md +1 -1
  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/renderer/compact-mode.ts +94 -77
  8. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/message-display.ts +1 -1
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +14 -0
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +55 -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 +1 -0
  35. package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +26 -10
  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 +2 -1
  39. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/localization.md +3 -1
  40. package/node_modules/@juicesharp/rpiv-ask-user-question/locales/en.json +2 -2
  41. package/node_modules/@juicesharp/rpiv-ask-user-question/locales/zh.json +2 -2
  42. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +3 -2
  43. package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +10 -0
  44. package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +3 -1
  45. package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +30 -7
  46. package/node_modules/@juicesharp/rpiv-ask-user-question/state/state.ts +14 -6
  47. package/node_modules/@juicesharp/rpiv-ask-user-question/view/dialog-builder.ts +30 -4
  48. package/node_modules/@juicesharp/rpiv-ask-user-question/view/tab-content-strategy.ts +26 -5
  49. package/node_modules/@narumitw/pi-btw/README.md +120 -111
  50. package/node_modules/@narumitw/pi-btw/dist/index.ts +2898 -0
  51. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +7 -0
  52. package/node_modules/@narumitw/pi-btw/package.json +10 -6
  53. package/node_modules/@narumitw/pi-btw/src/btw.ts +36 -40
  54. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +55 -10
  55. package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +390 -0
  56. package/node_modules/@narumitw/pi-btw/src/menu.ts +45 -2
  57. package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +136 -45
  58. package/node_modules/pi-lens/CHANGELOG.md +909 -0
  59. package/node_modules/pi-lens/README.md +11 -3
  60. package/node_modules/pi-lens/config/ruff/core.toml +42 -0
  61. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +130 -27
  62. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +126 -13
  63. package/node_modules/pi-lens/dist/clients/agent-nudge.js +67 -11
  64. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +9 -3
  65. package/node_modules/pi-lens/dist/clients/atomic-write.js +9 -3
  66. package/node_modules/pi-lens/dist/clients/bash-file-access.js +285 -8
  67. package/node_modules/pi-lens/dist/clients/biome-client.js +61 -30
  68. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +428 -0
  69. package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +119 -0
  70. package/node_modules/pi-lens/dist/clients/bootstrap.js +12 -1
  71. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +12 -3
  72. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +192 -0
  73. package/node_modules/pi-lens/dist/clients/cascade-budget.js +196 -0
  74. package/node_modules/pi-lens/dist/clients/cascade-format.js +20 -1
  75. package/node_modules/pi-lens/dist/clients/cascade-types.js +9 -1
  76. package/node_modules/pi-lens/dist/clients/child-unref.js +54 -6
  77. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +76 -24
  78. package/node_modules/pi-lens/dist/clients/dead-code-client.js +123 -31
  79. package/node_modules/pi-lens/dist/clients/deadline-utils.js +8 -1
  80. package/node_modules/pi-lens/dist/clients/debug-handles.js +5 -0
  81. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +62 -13
  82. package/node_modules/pi-lens/dist/clients/dependency-checker.js +25 -3
  83. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +147 -33
  84. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +298 -0
  85. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +52 -2
  86. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +256 -88
  87. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +7 -4
  88. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +5 -0
  89. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +234 -18
  90. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +187 -19
  91. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +6 -3
  92. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +11 -9
  93. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +398 -0
  94. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +11 -3
  95. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +12 -7
  96. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +18 -0
  97. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +895 -0
  98. package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +4 -0
  99. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +16 -3
  100. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +60 -53
  101. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +16 -0
  102. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +23 -0
  103. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +331 -55
  104. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +38 -5
  105. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +97 -19
  106. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +14 -0
  107. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +20 -0
  108. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +22 -0
  109. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +10 -0
  110. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +18 -6
  111. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +73 -12
  112. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +275 -13
  113. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +21 -6
  114. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +260 -27
  115. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +734 -64
  116. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +86 -11
  117. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +72 -0
  118. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +9 -0
  119. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +9 -0
  120. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +18 -1
  121. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +4 -2
  122. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +28 -5
  123. package/node_modules/pi-lens/dist/clients/extension-log.js +22 -1
  124. package/node_modules/pi-lens/dist/clients/file-kinds.js +8 -2
  125. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +294 -0
  126. package/node_modules/pi-lens/dist/clients/finding-identity.js +88 -0
  127. package/node_modules/pi-lens/dist/clients/formatters-lazy.js +3 -2
  128. package/node_modules/pi-lens/dist/clients/formatters.js +500 -115
  129. package/node_modules/pi-lens/dist/clients/generation-guard.js +216 -0
  130. package/node_modules/pi-lens/dist/clients/git-guard.js +31 -0
  131. package/node_modules/pi-lens/dist/clients/gitleaks-client.js +181 -8
  132. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +109 -9
  133. package/node_modules/pi-lens/dist/clients/grammar-source.js +333 -10
  134. package/node_modules/pi-lens/dist/clients/host-ports.js +8 -0
  135. package/node_modules/pi-lens/dist/clients/installer/index.js +1114 -100
  136. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +58 -0
  137. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +715 -0
  138. package/node_modules/pi-lens/dist/clients/instance-reaper.js +643 -97
  139. package/node_modules/pi-lens/dist/clients/instance-registry.js +87 -17
  140. package/node_modules/pi-lens/dist/clients/jscpd-client.js +82 -6
  141. package/node_modules/pi-lens/dist/clients/knip-client.js +310 -10
  142. package/node_modules/pi-lens/dist/clients/language-policy.js +8 -2
  143. package/node_modules/pi-lens/dist/clients/language-profile.js +2 -0
  144. package/node_modules/pi-lens/dist/clients/latency-logger.js +440 -11
  145. package/node_modules/pi-lens/dist/clients/lazy-import.js +21 -0
  146. package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -0
  147. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
  148. package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +102 -7
  149. package/node_modules/pi-lens/dist/clients/lsp/client.js +1516 -159
  150. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +83 -1
  151. package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +389 -0
  152. package/node_modules/pi-lens/dist/clients/lsp/index.js +2274 -147
  153. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +215 -0
  154. package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +146 -14
  155. package/node_modules/pi-lens/dist/clients/lsp/language.js +48 -4
  156. package/node_modules/pi-lens/dist/clients/lsp/server.js +277 -16
  157. package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +22 -0
  158. package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +43 -0
  159. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +79 -3
  160. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +43 -0
  161. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +422 -28
  162. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +30 -0
  163. package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +175 -0
  164. package/node_modules/pi-lens/dist/clients/lsp-lazy.js +3 -2
  165. package/node_modules/pi-lens/dist/clients/mcp/session.js +10 -2
  166. package/node_modules/pi-lens/dist/clients/module-report.js +8 -0
  167. package/node_modules/pi-lens/dist/clients/opengrep-client.js +15 -1
  168. package/node_modules/pi-lens/dist/clients/package-manager.js +170 -14
  169. package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +27 -0
  170. package/node_modules/pi-lens/dist/clients/path-utils.js +160 -0
  171. package/node_modules/pi-lens/dist/clients/pipeline.js +154 -33
  172. package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +37 -0
  173. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +17 -3
  174. package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +89 -22
  175. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +84 -14
  176. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +15 -3
  177. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +50 -2
  178. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -0
  179. package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
  180. package/node_modules/pi-lens/dist/clients/project-snapshot.js +299 -0
  181. package/node_modules/pi-lens/dist/clients/quiet-window-config.js +47 -0
  182. package/node_modules/pi-lens/dist/clients/quiet-window.js +11 -25
  183. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +1 -1
  184. package/node_modules/pi-lens/dist/clients/read-guard.js +184 -10
  185. package/node_modules/pi-lens/dist/clients/resource-sampler.js +49 -17
  186. package/node_modules/pi-lens/dist/clients/reverse-deps.js +50 -11
  187. package/node_modules/pi-lens/dist/clients/review-graph/query.js +52 -4
  188. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +96 -7
  189. package/node_modules/pi-lens/dist/clients/runtime-context.js +8 -1
  190. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +308 -45
  191. package/node_modules/pi-lens/dist/clients/runtime-session.js +332 -9
  192. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +217 -22
  193. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +212 -79
  194. package/node_modules/pi-lens/dist/clients/runtime-turn.js +575 -67
  195. package/node_modules/pi-lens/dist/clients/safe-spawn.js +220 -7
  196. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +161 -0
  197. package/node_modules/pi-lens/dist/clients/search-read-registration.js +34 -6
  198. package/node_modules/pi-lens/dist/clients/security-scan-client.js +157 -24
  199. package/node_modules/pi-lens/dist/clients/sg-runner.js +116 -22
  200. package/node_modules/pi-lens/dist/clients/single-flight.js +158 -0
  201. package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
  202. package/node_modules/pi-lens/dist/clients/startup-timing.js +19 -1
  203. package/node_modules/pi-lens/dist/clients/test-runner-client.js +151 -16
  204. package/node_modules/pi-lens/dist/clients/tool-event.js +56 -5
  205. package/node_modules/pi-lens/dist/clients/tool-policy.js +125 -20
  206. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +75 -1
  207. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +769 -64
  208. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +11 -0
  209. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +90 -0
  210. package/node_modules/pi-lens/dist/clients/trivy-client.js +19 -1
  211. package/node_modules/pi-lens/dist/clients/widget-state.js +336 -36
  212. package/node_modules/pi-lens/dist/clients/zizmor-config.js +214 -14
  213. package/node_modules/pi-lens/dist/index.js +67738 -55739
  214. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +466 -54
  215. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +132 -43
  216. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -7
  217. package/node_modules/pi-lens/docs/agent-guide.md +6 -1
  218. package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +515 -506
  219. package/node_modules/pi-lens/docs/dispositions.md +21 -0
  220. package/node_modules/pi-lens/docs/features.md +19 -5
  221. package/node_modules/pi-lens/docs/globalconfig.md +3 -0
  222. package/node_modules/pi-lens/docs/language-coverage.md +71 -5
  223. package/node_modules/pi-lens/docs/mcp.md +2 -2
  224. package/node_modules/pi-lens/docs/servercapabilities.md +4 -1
  225. package/node_modules/pi-lens/docs/settings.md +19 -1
  226. package/node_modules/pi-lens/docs/usage.md +1 -0
  227. package/node_modules/pi-lens/package.json +10 -6
  228. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-js-snapshot.yml +23 -0
  229. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-snapshot.yml +23 -0
  230. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/ts-void-zero-snapshot.yml +23 -0
  231. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-object-param-test.yml +16 -0
  232. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +15 -1
  233. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-compile-call-test.yml +29 -1
  234. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-dupe-class-members-test.yml +33 -0
  235. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-js-test.yml +7 -1
  236. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-test.yml +7 -1
  237. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-known-value-widening-test.yml +9 -0
  238. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-non-null-assertion-test.yml +216 -0
  239. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +2 -0
  240. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +2 -0
  241. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +2 -1
  242. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +2 -1
  243. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-return-value-in-generator-test.yml +12 -0
  244. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-runtime-typeof-test.yml +33 -0
  245. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-server-bind-wildcard-test.yml +9 -0
  246. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-shape-in-symbol-names-test.yml +13 -0
  247. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-js-test.yml +5 -1
  248. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-test.yml +5 -1
  249. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-parameters-test.yml +12 -0
  250. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-returns-test.yml +16 -0
  251. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-any-test.yml +10 -0
  252. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-unknown-test.yml +8 -0
  253. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/redundant-unsafe-function-test.yml +35 -0
  254. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/require-safety-comment-for-as-unknown-as-test.yml +177 -0
  255. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/ts-void-zero-test.yml +1 -0
  256. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member-js.yml +13 -2
  257. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member.yml +13 -2
  258. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +2 -0
  259. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-object-param.yml +60 -0
  260. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +57 -12
  261. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-compile-call.yml +63 -5
  262. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-dupe-class-members.yml +52 -8
  263. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html-js.yml +27 -2
  264. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html.yml +27 -2
  265. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-known-value-widening.yml +71 -0
  266. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-non-null-assertion.yml +316 -0
  267. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +7 -0
  268. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +22 -2
  269. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +23 -2
  270. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +33 -5
  271. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +34 -8
  272. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-return-value-in-generator.yml +22 -5
  273. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-runtime-typeof.yml +121 -0
  274. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-server-bind-wildcard.yml +23 -7
  275. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-shape-in-symbol-names.yml +68 -0
  276. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code-js.yml +41 -2
  277. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code.yml +41 -2
  278. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +6 -1
  279. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-parameters.yml +67 -0
  280. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-returns.yml +106 -0
  281. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-any.yml +50 -0
  282. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-unknown.yml +56 -0
  283. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +2 -0
  284. package/node_modules/pi-lens/rules/ast-grep-rules/rules/redundant-unsafe-function.yml +32 -0
  285. package/node_modules/pi-lens/rules/ast-grep-rules/rules/require-safety-comment-for-as-unknown-as.yml +184 -0
  286. package/node_modules/pi-lens/rules/ast-grep-rules/rules/ts-void-zero.yml +5 -0
  287. package/node_modules/pi-lens/rules/ast-grep-rules/self-scan-baseline.json +5 -0
  288. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +53 -1
  289. package/node_modules/pi-lens/scripts/download-grammars.js +25 -0
  290. package/node_modules/pi-lens/scripts/grammars.lock.json +9 -0
  291. package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +2 -0
  292. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +80 -3
  293. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +41 -0
  294. package/node_modules/pi-lens/vendor/grammars/tree-sitter-cue.wasm +0 -0
  295. package/node_modules/pi-mcp-adapter/CHANGELOG.md +36 -0
  296. package/node_modules/pi-mcp-adapter/README.md +47 -5
  297. package/node_modules/pi-mcp-adapter/cli.js +163 -1
  298. package/node_modules/pi-mcp-adapter/commands.ts +128 -22
  299. package/node_modules/pi-mcp-adapter/config.ts +25 -7
  300. package/node_modules/pi-mcp-adapter/direct-tools.ts +5 -4
  301. package/node_modules/pi-mcp-adapter/index.ts +219 -32
  302. package/node_modules/pi-mcp-adapter/init.ts +36 -4
  303. package/node_modules/pi-mcp-adapter/lifecycle.ts +315 -24
  304. package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +39 -6
  305. package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +387 -0
  306. package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +27 -3
  307. package/node_modules/pi-mcp-adapter/mcp-code.ts +4 -0
  308. package/node_modules/pi-mcp-adapter/mcp-panel.ts +42 -13
  309. package/node_modules/pi-mcp-adapter/metadata-cache.ts +32 -21
  310. package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +168 -0
  311. package/node_modules/pi-mcp-adapter/package.json +3 -1
  312. package/node_modules/pi-mcp-adapter/proxy-modes.ts +5 -4
  313. package/node_modules/pi-mcp-adapter/request-headers-command.ts +31 -37
  314. package/node_modules/pi-mcp-adapter/search-ranking.ts +92 -22
  315. package/node_modules/pi-mcp-adapter/server-manager.ts +140 -2
  316. package/node_modules/pi-mcp-adapter/session-recovery.ts +7 -0
  317. package/node_modules/pi-mcp-adapter/tool-approval.ts +15 -2
  318. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +44 -4
  319. package/node_modules/pi-mcp-adapter/types.ts +2 -0
  320. package/node_modules/pi-mcp-adapter/ui-server.ts +18 -16
  321. package/node_modules/pi-mcp-adapter/utils.ts +70 -0
  322. package/node_modules/pi-web-access/CHANGELOG.md +23 -0
  323. package/node_modules/pi-web-access/README.md +27 -9
  324. package/node_modules/pi-web-access/anysearch.ts +4 -2
  325. package/node_modules/pi-web-access/brave.ts +16 -4
  326. package/node_modules/pi-web-access/curator-page.ts +6 -3
  327. package/node_modules/pi-web-access/curator-server.ts +4 -1
  328. package/node_modules/pi-web-access/exa.ts +18 -7
  329. package/node_modules/pi-web-access/extract.ts +28 -3
  330. package/node_modules/pi-web-access/gemini-search.ts +16 -4
  331. package/node_modules/pi-web-access/index.ts +41 -57
  332. package/node_modules/pi-web-access/package.json +1 -1
  333. package/node_modules/pi-web-access/page-query.ts +4 -2
  334. package/node_modules/pi-web-access/parallel-mcp.ts +249 -0
  335. package/node_modules/pi-web-access/parallel.ts +2 -2
  336. package/node_modules/pi-web-access/query-rewrite.ts +51 -0
  337. package/node_modules/pi-web-access/serper.ts +211 -0
  338. package/node_modules/pi-web-access/summary-model-scope.ts +12 -4
  339. package/node_modules/pi-web-access/summary-review.ts +44 -22
  340. package/node_modules/pi-web-access/tavily.ts +16 -4
  341. package/node_modules/pi-web-access/utils.ts +87 -0
  342. package/node_modules/pi-web-access/valyu.ts +199 -0
  343. package/package.json +13 -13
@@ -0,0 +1,398 @@
1
+ /**
2
+ * `cue vet` — CUE evaluation-error validation (#1522).
3
+ *
4
+ * `cue lsp serve` reports load and parse (syntax) errors as you type
5
+ * (`clients/lsp/wait-policy/strategies.ts`'s `cue` entry) but deliberately
6
+ * leaves conflicting concrete values and failed constraints to `cue vet` —
7
+ * per the CUE wiki, that class needs a full evaluation pass the language
8
+ * server does not run on every keystroke. This runner is the auxiliary that
9
+ * covers the gap, in the same "LSP covers syntax, a CLI covers the rest"
10
+ * shape as terraform's `lsp, tflint, trivy-config` group.
11
+ *
12
+ * `-c=false` (allow incomplete values) is deliberate, not a shortcut: CUE's
13
+ * default `cue vet` requires every regular field to be concrete, so an
14
+ * ordinary schema-only file — a `#Definition` library with no concrete data,
15
+ * a very common authoring pattern — fails vet's default gate with a generic
16
+ * "some instances are incomplete" message and nothing to point at. That is
17
+ * noise, not a defect. `-c=false` accepts incomplete values and still
18
+ * reports a genuine type conflict (verified: `a: int & "hello"` still fails
19
+ * with `-c=false`, an incomplete `a: int` no longer does) — see the fixture
20
+ * at tests/fixtures/tool-smoke/cue-vet/bad.cue.
21
+ *
22
+ * ## Package-scoped, not file-scoped (review round 1, F1)
23
+ *
24
+ * CUE packages are DIRECTORY-scoped: every `.cue` file in a directory
25
+ * sharing a `package` clause is unified into one value. Vetting only the
26
+ * touched file (`cue vet <file>`) was a false-positive machine on the
27
+ * normative split-schema/values authoring style — a `#Service` defined in
28
+ * `schema.cue` and referenced from `values.cue` vets clean as a package but
29
+ * fails `values.cue` alone with `reference "#Service" not found`, because
30
+ * the single-file invocation never loads the sibling that defines it.
31
+ * Verified: a valid two-file package vets clean as `cue vet -c=false .`
32
+ * (exit 0, empty output) but reports a blocking error for `values.cue` in
33
+ * isolation.
34
+ *
35
+ * The fix runs `cue vet -c=false .` from the touched file's directory (the
36
+ * whole package) and then filters the reported errors down to the ones
37
+ * whose location names the touched file — `cue vet`'s locations are
38
+ * `.\<file>:line:col` relative to the vet cwd, so the match is a plain
39
+ * basename compare, no path resolution needed.
40
+ *
41
+ * This is now an honest MISSED-finding tradeoff, not an invented-finding
42
+ * bug: an error whose ONLY location is a sibling file is filtered out here
43
+ * (it will surface when that sibling is itself touched), rather than a
44
+ * clean file being wrongly flagged. An error that names the touched file
45
+ * ANYWHERE in its location list — including as a secondary location on a
46
+ * conflict whose primary site is a sibling — is kept, using that location's
47
+ * line/col, because the touched file is a genuine contributor to it.
48
+ *
49
+ * ## Directory scope can itself be unavailable (review round 2, F5/F6)
50
+ *
51
+ * `cue vet .` is not always a valid unit. Two real, LEGAL directory shapes
52
+ * make it fail before it evaluates anything, with no per-file location at
53
+ * all:
54
+ *
55
+ * - a package-less standalone file (no `package` clause — the common
56
+ * single-file config style): `build constraints exclude all CUE files
57
+ * in .:\n .\standalone.cue: no package name`;
58
+ * - two or more DIFFERENT package names sharing one directory (legal CUE —
59
+ * each is its own independent unit): `found packages "alpha"
60
+ * (alpha.cue) and "beta" (beta.cue) in "."`.
61
+ *
62
+ * Both verified against cue v0.17.1 (exit 1, no `:line:col` anywhere in the
63
+ * output). Before F5/F6, this read as an unattributable whole-vet failure
64
+ * and blocked every edit to an otherwise-clean file of either shape — a
65
+ * regression the F1 fix introduced. The fix: on either signature, fall back
66
+ * to vetting the touched file ALONE (`cue vet -c=false <file>`), which is
67
+ * the CORRECT scope for a file that cannot be unified with anything in its
68
+ * directory — a package-less file is its own unit by definition, and a
69
+ * differently-packaged sibling is never part of the same value regardless of
70
+ * scope. The single-file result needs no further filtering: every location
71
+ * it reports already belongs to that one file.
72
+ *
73
+ * ## A package-less file can vet CLEAN by never being evaluated (review
74
+ * ## round 3, F8)
75
+ *
76
+ * The F5/F6 fallback above only fires when the DIRECTORY vet FAILS. But a
77
+ * directory holding both a packaged file and a package-less file is not a
78
+ * failure at all: `cue vet .` silently BUILDS ONLY THE PACKAGE, excludes the
79
+ * package-less file from evaluation, and exits 0. Verified against the real
80
+ * binary: a package-less `loose.cue` with a genuine conflicting value
81
+ * (`b: int & "x"`) sitting beside a valid packaged `packaged.cue` makes
82
+ * `cue vet -c=false .` exit 0 with empty output — the loose file's defect is
83
+ * never evaluated, and the F5/F6 fallback's `result.status !== 0` gate never
84
+ * triggers because there IS no failure to react to. This is shape 10 from
85
+ * the miss side: an empty result that does not distinguish "clean" from
86
+ * "never evaluated".
87
+ *
88
+ * The fix does not wait for a failure signal at all for this shape: before
89
+ * spawning anything, the touched file's own content is checked for a
90
+ * `package` clause (`hasPackageClause`). A package-less touched file goes
91
+ * straight to single-file scope — it is its own vet unit regardless of what
92
+ * shares its directory, so directory-scoped vet has nothing to add for ITS
93
+ * evaluation errors. Its SYNTAX errors are equally covered single-file
94
+ * (verified: `cue vet <file>` alone reports the identical syntax error a
95
+ * directory-wide parse would have caught for that file — parsing happens
96
+ * before the build-constraint exclusion, but a single-file invocation
97
+ * parses that file too), so nothing is lost by skipping the directory pass
98
+ * for this shape. The F5/F6 `directoryScopeUnavailable` fallback stays as a
99
+ * safety net for what the proactive check cannot see up front — the
100
+ * touched file's content is unreadable, or the touched file DOES declare a
101
+ * package but the directory as a whole still isn't a valid unit (F6's
102
+ * two-different-packages shape).
103
+ */
104
+ import * as fs from "node:fs";
105
+ import * as path from "node:path";
106
+ import { safeSpawnAsync } from "../../safe-spawn.js";
107
+ import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
108
+ import { spawnFailedWithNoOutput } from "./utils/spawn-outcome.js";
109
+ import { PRIORITY } from "../priorities.js";
110
+ const cue = createAvailabilityChecker("cue", ".exe", ["version"]);
111
+ /**
112
+ * `cue vet` reports each error as a header line (a field path or a bare
113
+ * message, ending in `:`) followed by zero or more indented location lines
114
+ * (` .\path:line:col`). A syntax error has no field-path prefix; a
115
+ * conflicting-value error carries one location per conflicting side, which
116
+ * can span DIFFERENT files in a multi-file package.
117
+ *
118
+ * Verified against cue v0.17.1:
119
+ * a: conflicting values int and "hello" (mismatched types int and string):
120
+ * .\bad.cue:3:4
121
+ * .\bad.cue:3:10
122
+ * expected '}', found 'EOF':
123
+ * .\syntax.cue:2:6
124
+ * badField.name: conflicting values 5 and string (mismatched types int and string):
125
+ * .\bad-values.cue:3:11
126
+ * .\bad-values.cue:4:8
127
+ * .\schema.cue:4:8
128
+ *
129
+ * A summary-only failure (no location lines at all — e.g. the "some
130
+ * instances are incomplete" message `-c=false` is meant to prevent, a
131
+ * directory-scope failure like `build constraints exclude all CUE files`
132
+ * (handled upstream of this parser — see `directoryScopeUnavailable`), or an
133
+ * unrecognized shape from a future cue version) is intentionally NOT
134
+ * silently dropped: `filterToTouchedFile` and the caller make sure a real
135
+ * vet failure can never present as zero findings (recurring defect shape
136
+ * 10) when nothing in the output could be file-attributed at all.
137
+ */
138
+ export function parseCueVetOutput(raw) {
139
+ const errors = [];
140
+ let current = null;
141
+ for (const rawLine of raw.split(/\r?\n/)) {
142
+ if (!rawLine.trim())
143
+ continue;
144
+ if (/^\s/.test(rawLine)) {
145
+ if (current) {
146
+ const loc = rawLine.trim().match(/^(.+):(\d+):(\d+)$/);
147
+ if (loc) {
148
+ current.locations.push({
149
+ file: loc[1],
150
+ line: Number.parseInt(loc[2], 10),
151
+ column: Number.parseInt(loc[3], 10),
152
+ });
153
+ }
154
+ }
155
+ continue;
156
+ }
157
+ if (current)
158
+ errors.push(current);
159
+ current = { message: rawLine.replace(/:\s*$/, "").trim(), locations: [] };
160
+ }
161
+ if (current)
162
+ errors.push(current);
163
+ return errors;
164
+ }
165
+ /**
166
+ * True when `cue vet .`'s failure means the DIRECTORY is not a valid vet
167
+ * unit at all — not a finding about any file's content (review round 2,
168
+ * F5/F6). Both signatures are verified against cue v0.17.1 and carry no
169
+ * `:line:col` anywhere in their output, which is exactly why they used to
170
+ * read as an unattributable whole-vet failure and block every edit.
171
+ */
172
+ export function directoryScopeUnavailable(raw) {
173
+ return (/build constraints exclude all CUE files/.test(raw) ||
174
+ // The trailing location cue reports (`in "."` vs `in "two-packages"`)
175
+ // depends on how it resolves the vet cwd, not on the shape of the
176
+ // failure — verified both forms against the real binary — so only the
177
+ // structural "found packages X and Y" part is matched.
178
+ /found packages ".+"\s*\(.+\)\s+and\s+".+"\s*\(.+\)\s+in\s+".*"/.test(raw));
179
+ }
180
+ /**
181
+ * True when `content` opens with a `package` clause (review round 3, F8).
182
+ * CUE requires the package clause, when present, to be the first
183
+ * declaration in the file — blank lines and `//` comments above it are
184
+ * fine, verified against the real binary — so the first non-blank,
185
+ * non-comment line is decisive: if it isn't `package <name>`, the file has
186
+ * none, and `cue vet .` will silently exclude it from directory-scoped
187
+ * evaluation (F8) rather than fail outright.
188
+ *
189
+ * File-level attributes (`@extern(embed)` is the documented real case) are
190
+ * ALSO legal before the package clause, and are skipped for the same reason
191
+ * comments are (review round 4, F10) — without this, a file opening with
192
+ * one reads as package-less, gets routed to single-file scope, and a
193
+ * cross-file reference into a sibling then false-positives as "reference
194
+ * not found" on an otherwise clean package (verified against the real
195
+ * binary). Field-level attributes never collide with this: they attach to
196
+ * a field and so always start with the field's name, never `@`.
197
+ */
198
+ export function hasPackageClause(content) {
199
+ for (const line of content.split(/\r?\n/)) {
200
+ const trimmed = line.trim();
201
+ if (!trimmed || trimmed.startsWith("//") || trimmed.startsWith("@"))
202
+ continue;
203
+ return /^package\s+[A-Za-z_]\w*\b/.test(trimmed);
204
+ }
205
+ return false;
206
+ }
207
+ /** `.\bad.cue`, `./bad.cue`, and `bad.cue` all name the same file. */
208
+ function locationMatchesFile(location, fileName) {
209
+ const normalized = location.file.replace(/\\/g, "/").replace(/^\.\//, "");
210
+ return path.posix.basename(normalized) === fileName;
211
+ }
212
+ function toDiagnostic(id, message, fileName, line, column) {
213
+ return {
214
+ id,
215
+ message: message || "cue vet reported an error",
216
+ filePath: fileName,
217
+ line,
218
+ column,
219
+ severity: "error",
220
+ semantic: "blocking",
221
+ tool: "cue-vet",
222
+ rule: "vet",
223
+ fixable: false,
224
+ };
225
+ }
226
+ /**
227
+ * Filter package-wide vet errors down to the ones that implicate the touched
228
+ * file, and resolve each to that file's own location (the first location
229
+ * line naming it — the field path can carry more than one, see the
230
+ * `badField.name` example above).
231
+ *
232
+ * Returns `undefined` (distinct from an empty array) only when NOTHING in
233
+ * the output could be file-attributed at all — every error lacked location
234
+ * lines entirely — so the caller can fall back to a whole-output diagnostic
235
+ * instead of reporting a false-clean result (shape 10).
236
+ *
237
+ * ## The mixed case (review round 2, F7)
238
+ *
239
+ * A package-wide vet run can return SEVERAL errors, some with locations and
240
+ * some without. The original rule only fell back to `undefined` when EVERY
241
+ * error lacked a location — so one sibling-located error alongside one
242
+ * genuinely unattributable error made `recognized.length` nonzero, and the
243
+ * unattributable error's diagnostic silently vanished (shape 10, from the
244
+ * filter side this time). There is no file this parser can safely charge an
245
+ * unattributable error to, and no file it can safely clear it from either
246
+ * — so the honest rule is: an unattributable error ALWAYS surfaces on the
247
+ * touched file's result, distinct from (never merged with) a real
248
+ * touched-file location match, and independent of whatever sibling-only
249
+ * errors get filtered out alongside it. Only the fully-uniform case (every
250
+ * error unattributable) still returns `undefined`, so the caller's richer
251
+ * whole-output fallback message is used instead of one row per parsed
252
+ * header.
253
+ */
254
+ export function filterToTouchedFile(errors, fileName) {
255
+ if (errors.length === 0)
256
+ return undefined;
257
+ const withLocation = errors.filter((error) => error.locations.length > 0);
258
+ const unattributable = errors.filter((error) => error.locations.length === 0);
259
+ if (withLocation.length === 0)
260
+ return undefined;
261
+ const diagnostics = [];
262
+ for (const error of withLocation) {
263
+ const match = error.locations.find((location) => locationMatchesFile(location, fileName));
264
+ if (!match)
265
+ continue; // sibling-only finding — surfaces when that file is touched
266
+ diagnostics.push(toDiagnostic(`cue-vet-${diagnostics.length + 1}-${match.line}`, error.message, fileName, match.line, match.column));
267
+ }
268
+ // F7: an error this parser could not pin to any file must never be
269
+ // silently dropped just because a SIBLING error happened to carry a
270
+ // location — surface it too, at line 1 since there is nowhere else to
271
+ // point.
272
+ for (const error of unattributable) {
273
+ diagnostics.push(toDiagnostic(`cue-vet-unattributed-${diagnostics.length + 1}`, error.message, fileName, 1, 1));
274
+ }
275
+ return diagnostics;
276
+ }
277
+ const cueVetRunner = {
278
+ id: "cue-vet",
279
+ appliesTo: ["cue"],
280
+ priority: PRIORITY.GENERAL_ANALYSIS,
281
+ enabledByDefault: true,
282
+ skipTestFiles: false,
283
+ timeoutMs: 30_000,
284
+ async run(ctx) {
285
+ const cwd = ctx.cwd || process.cwd();
286
+ let cmd = null;
287
+ if (await cue.isAvailableAsync(cwd)) {
288
+ cmd = cue.getCommand(cwd);
289
+ }
290
+ else {
291
+ cmd = await resolveAvailableOrInstall(cue, "cue", cwd);
292
+ }
293
+ // An unspawnable `cue` is never a durable "clean" verdict — skip, so the
294
+ // dispatcher's own absence handling reports the gap rather than this
295
+ // runner manufacturing a false "0 findings" (recurring defect shape 10).
296
+ // `createAvailabilityChecker`/`resolveAvailableOrInstall` already route
297
+ // through the shared classify/latch policy, so a probe timeout or host
298
+ // stall re-arms on its own cooldown instead of latching here.
299
+ if (!cmd)
300
+ return { status: "skipped", diagnostics: [], semantic: "none" };
301
+ const absPath = path.resolve(cwd, ctx.filePath);
302
+ const fileDir = path.dirname(absPath);
303
+ const fileName = path.basename(absPath);
304
+ const singleFileArgs = ["vet", "-c=false", `./${fileName}`];
305
+ // F8: read the touched file's OWN content before deciding scope. A
306
+ // package-less file is excluded from directory-scoped evaluation
307
+ // entirely (silently, exit 0) rather than causing a failure, so
308
+ // waiting for the directory vet to fail (the F5/F6 gate below) can
309
+ // never catch this shape — go straight to single-file scope instead.
310
+ // An unreadable file falls through to the directory-scoped path below;
311
+ // package-less-ness that can't be verified is never assumed.
312
+ let touchedContent = null;
313
+ try {
314
+ touchedContent = fs.readFileSync(absPath, "utf8");
315
+ }
316
+ catch {
317
+ touchedContent = null;
318
+ }
319
+ const touchedIsPackageLess = touchedContent !== null && !hasPackageClause(touchedContent);
320
+ let result;
321
+ if (touchedIsPackageLess) {
322
+ result = await safeSpawnAsync(cmd, [...singleFileArgs], {
323
+ cwd: fileDir,
324
+ timeout: 30_000,
325
+ });
326
+ }
327
+ else {
328
+ // Package-scoped (F1): vet the whole directory the touched file lives
329
+ // in, not the file alone — CUE packages unify every file that shares
330
+ // a package clause, so a single-file invocation cannot see a
331
+ // definition or value declared in a sibling.
332
+ result = await safeSpawnAsync(cmd, ["vet", "-c=false", "."], {
333
+ cwd: fileDir,
334
+ timeout: 30_000,
335
+ });
336
+ if (!spawnFailedWithNoOutput(result, `${result.stdout}${result.stderr}`) &&
337
+ result.status !== 0 &&
338
+ directoryScopeUnavailable(`${result.stdout || ""}${result.stderr || ""}`)) {
339
+ // F6: the directory holds two+ DIFFERENTLY-packaged files (the
340
+ // touched file has its own valid package, but the directory as a
341
+ // whole still isn't one unit) — fall back to the touched file
342
+ // alone, which IS a valid unit on its own.
343
+ result = await safeSpawnAsync(cmd, [...singleFileArgs], {
344
+ cwd: fileDir,
345
+ timeout: 30_000,
346
+ });
347
+ }
348
+ }
349
+ if (spawnFailedWithNoOutput(result, `${result.stdout}${result.stderr}`)) {
350
+ return { status: "skipped", diagnostics: [], semantic: "none" };
351
+ }
352
+ // `cue vet` is silent on success (empty stdout, exit 0) — that IS the
353
+ // clean signal, not an unavailable/errored one, so status 0 with no
354
+ // output reports succeeded/no-findings rather than falling through to
355
+ // the skip above.
356
+ if (result.status === 0) {
357
+ return { status: "succeeded", diagnostics: [], semantic: "none" };
358
+ }
359
+ const raw = `${result.stdout || ""}\n${result.stderr || ""}`.trim();
360
+ const errors = parseCueVetOutput(raw);
361
+ // The single-file path (F5/F6/F8) needs no special-casing: every
362
+ // location it reports already belongs to the one file it vetted, so it
363
+ // trivially matches `fileName` and flows through the same filter as
364
+ // the directory-scoped path — one code path, and a single-file run
365
+ // that somehow fails with no location at all still gets the same
366
+ // never-silently-clean `undefined` fallback as the directory path.
367
+ const filtered = filterToTouchedFile(errors, fileName);
368
+ if (filtered === undefined) {
369
+ // Nonzero exit, some output, but nothing in it could be attributed to
370
+ // ANY file — a real failure must not present as zero findings.
371
+ return {
372
+ status: "failed",
373
+ diagnostics: [
374
+ {
375
+ id: "cue-vet-unparsed",
376
+ message: raw.slice(0, 300) || "cue vet exited non-zero",
377
+ filePath: ctx.filePath,
378
+ line: 1,
379
+ column: 1,
380
+ severity: "error",
381
+ semantic: "blocking",
382
+ tool: "cue-vet",
383
+ rule: "vet",
384
+ fixable: false,
385
+ },
386
+ ],
387
+ semantic: "blocking",
388
+ };
389
+ }
390
+ if (filtered.length === 0) {
391
+ // The package has real errors, but none of them implicate the touched
392
+ // file — a sibling's problem, not this file's (the F1 tradeoff).
393
+ return { status: "succeeded", diagnostics: [], semantic: "none" };
394
+ }
395
+ return { status: "failed", diagnostics: filtered, semantic: "blocking" };
396
+ },
397
+ };
398
+ export default cueVetRunner;
@@ -165,7 +165,15 @@ const elixirCheckRunner = {
165
165
  return { status: "skipped", diagnostics: [], semantic: "none" };
166
166
  }
167
167
  const raw = `${result.stderr || ""}\n${result.stdout || ""}`;
168
- const diagnostics = parseElixirOutput(raw, ctx.filePath, cwd);
168
+ const hasProjectContext = command === "mix";
169
+ const diagnostics = parseElixirOutput(raw, ctx.filePath, cwd).map((d) => hasProjectContext
170
+ ? d
171
+ : {
172
+ ...d,
173
+ // A direct elixirc invocation cannot resolve Mix dependencies.
174
+ // Standalone findings inform the agent, but cannot block it.
175
+ semantic: "warning",
176
+ });
169
177
  if (diagnostics.length === 0) {
170
178
  if (result.status && result.status !== 0) {
171
179
  return {
@@ -177,13 +185,13 @@ const elixirCheckRunner = {
177
185
  `${command} exited non-zero without structured diagnostics`,
178
186
  filePath: ctx.filePath,
179
187
  severity: "error",
180
- semantic: "blocking",
188
+ semantic: hasProjectContext ? "blocking" : "warning",
181
189
  tool: "elixir-check",
182
190
  rule: command,
183
191
  fixable: false,
184
192
  },
185
193
  ],
186
- semantic: "blocking",
194
+ semantic: hasProjectContext ? "blocking" : "warning",
187
195
  };
188
196
  }
189
197
  return { status: "succeeded", diagnostics: [], semantic: "none" };
@@ -10,24 +10,29 @@ import { safeSpawnAsync } from "../../safe-spawn.js";
10
10
  import { getAutofixCapability, hasEslintConfig } from "../../tool-policy.js";
11
11
  import { PRIORITY } from "../priorities.js";
12
12
  import { createCwdCachedProbe, resolveToolCommand, } from "./utils/runner-helpers.js";
13
+ const ESLINT_PROBE_BUDGET_MS = 5000;
13
14
  // Per-cwd cached eslint `--version` verification (#120). Before this, every
14
15
  // dispatch invocation ran a fresh `safeSpawnAsync(cmd, ["--version"])` after
15
16
  // the local cmd resolution. The probe is cached per cwd because
16
17
  // `resolveToolCommand("eslint")` is deterministic from cwd; the underlying
17
18
  // cmd identity is captured inside the probe closure.
19
+ //
20
+ // The verdict is governed by the shared availability policy (#1494): the probe
21
+ // hands back the spawn result, so one stalled probe on the first JS/TS save
22
+ // expires on a cooldown instead of disabling eslint for the whole session.
18
23
  function makeEslintProbe(cmd) {
19
- return createCwdCachedProbe(async (cwd) => {
20
- const r = await safeSpawnAsync(cmd, ["--version"], { timeout: 5000, cwd });
21
- return !r.error && r.status === 0;
22
- });
24
+ return createCwdCachedProbe((cwd) => safeSpawnAsync(cmd, ["--version"], {
25
+ timeout: ESLINT_PROBE_BUDGET_MS,
26
+ cwd,
27
+ }), { tool: "eslint", budgetMs: ESLINT_PROBE_BUDGET_MS });
23
28
  }
24
- const eslintProbeByCmd = new Map();
29
+ const eslintAvailabilityByCmd = new Map();
25
30
  function getEslintProbe(cmd) {
26
- const existing = eslintProbeByCmd.get(cmd);
31
+ const existing = eslintAvailabilityByCmd.get(cmd);
27
32
  if (existing)
28
33
  return existing;
29
34
  const created = makeEslintProbe(cmd);
30
- eslintProbeByCmd.set(cmd, created);
35
+ eslintAvailabilityByCmd.set(cmd, created);
31
36
  return created;
32
37
  }
33
38
  function parseEslintJson(raw, filePath) {
@@ -7,6 +7,7 @@ import { relative, resolve, sep, posix } from "node:path";
7
7
  import { GoClient } from "../../go-client.js";
8
8
  import { safeSpawnAsync } from "../../safe-spawn.js";
9
9
  import { stripAnsi } from "../../sanitize.js";
10
+ import { skipUnlessToolRan } from "./utils/tool-failure.js";
10
11
  import { parseGoVetOutput } from "./utils/diagnostic-parsers.js";
11
12
  import { PRIORITY } from "../priorities.js";
12
13
  const goClient = new GoClient();
@@ -45,6 +46,23 @@ const goVetRunner = {
45
46
  cwd,
46
47
  });
47
48
  const raw = stripAnsi(result.stdout + result.stderr);
49
+ // #1816: `go vet` exits nonzero both for "found problems" and for a
50
+ // toolchain failure it never got past — `go.mod file not found in
51
+ // current directory or any parent directory` is the one that bit us
52
+ // (#263). That prose carries no `file:line:col:` prefix, so it parsed to
53
+ // zero diagnostics and the file was reported CLEAN by a vet that never
54
+ // ran. The exit code cannot separate the two cases; the presence of a
55
+ // parsable diagnostic line can, so that is what the gate is handed.
56
+ const parsableLines = raw
57
+ .split("\n")
58
+ .filter((line) => /^.+?:\d+:\d+:/.test(line))
59
+ .join("\n");
60
+ const skipped = skipUnlessToolRan("go-vet", {
61
+ result,
62
+ output: parsableLines,
63
+ });
64
+ if (skipped)
65
+ return skipped;
48
66
  if (result.status === 0 && !raw.trim()) {
49
67
  return { status: "succeeded", diagnostics: [], semantic: "none" };
50
68
  }