@duckmind/dm-linux-x64 0.66.0 → 0.66.2

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 (546) hide show
  1. package/dm +2 -2
  2. package/extensions/.dm-extensions.json +12 -546
  3. package/extensions/dm-lens/clients/dispatch/runners/utils/runner-helpers.js +1 -1
  4. package/extensions/dm-mcp-adapter/mcp-keyring-helper.cjs +1 -1
  5. package/extensions/dm-ponytail/hooks/ponytail-activate.js +1 -1
  6. package/extensions/dm-ponytail/hooks/ponytail-instructions.js +1 -1
  7. package/extensions/dm-subagents/src/runs/background/runner-aliases.js +2 -2
  8. package/extensions/dm-subagents/src/runs/foreground/prompt-audit.js +4 -1
  9. package/extensions/dm-subagents/src/runs/shared/child-session.js +8 -6
  10. package/extensions/dm-subagents/src/watchdog/permission-arbiter.js +9 -1
  11. package/extensions/dm-subagents/src/watchdog/review.js +4 -1
  12. package/package.json +1 -1
  13. package/extensions/dm-lens/dist/clients/actionable-warnings-logger.js +0 -24
  14. package/extensions/dm-lens/dist/clients/actionable-warnings.js +0 -1014
  15. package/extensions/dm-lens/dist/clients/advisory-provenance.js +0 -385
  16. package/extensions/dm-lens/dist/clients/agent-behavior-client.js +0 -94
  17. package/extensions/dm-lens/dist/clients/agent-nudge.js +0 -151
  18. package/extensions/dm-lens/dist/clients/analysed-root.js +0 -1
  19. package/extensions/dm-lens/dist/clients/ast-grep-client.js +0 -576
  20. package/extensions/dm-lens/dist/clients/ast-grep-rule-manager.js +0 -114
  21. package/extensions/dm-lens/dist/clients/ast-grep-tool-logger.js +0 -85
  22. package/extensions/dm-lens/dist/clients/ast-grep-types.js +0 -1
  23. package/extensions/dm-lens/dist/clients/ast-grep-yaml-synth.js +0 -109
  24. package/extensions/dm-lens/dist/clients/atomic-write-staging.js +0 -66
  25. package/extensions/dm-lens/dist/clients/atomic-write.js +0 -37
  26. package/extensions/dm-lens/dist/clients/availability-probe-flight.js +0 -11
  27. package/extensions/dm-lens/dist/clients/bash-file-access.js +0 -830
  28. package/extensions/dm-lens/dist/clients/biome-client.js +0 -221
  29. package/extensions/dm-lens/dist/clients/blocker-freshness.js +0 -385
  30. package/extensions/dm-lens/dist/clients/blocker-past-eof.js +0 -49
  31. package/extensions/dm-lens/dist/clients/bootstrap.js +0 -246
  32. package/extensions/dm-lens/dist/clients/bounded-cache.js +0 -105
  33. package/extensions/dm-lens/dist/clients/bounded-pid-file-lock.js +0 -173
  34. package/extensions/dm-lens/dist/clients/bounded-telemetry.js +0 -104
  35. package/extensions/dm-lens/dist/clients/build-identity.js +0 -45
  36. package/extensions/dm-lens/dist/clients/bundled-resource-health.js +0 -41
  37. package/extensions/dm-lens/dist/clients/bus-events-logger.js +0 -48
  38. package/extensions/dm-lens/dist/clients/bus-publish.js +0 -117
  39. package/extensions/dm-lens/dist/clients/cache/rule-cache.js +0 -103
  40. package/extensions/dm-lens/dist/clients/cache-manager.js +0 -340
  41. package/extensions/dm-lens/dist/clients/cache-observability.js +0 -847
  42. package/extensions/dm-lens/dist/clients/call-graph.js +0 -628
  43. package/extensions/dm-lens/dist/clients/cargo-manifest.js +0 -151
  44. package/extensions/dm-lens/dist/clients/cascade-budget.js +0 -52
  45. package/extensions/dm-lens/dist/clients/cascade-format.js +0 -160
  46. package/extensions/dm-lens/dist/clients/cascade-logger.js +0 -22
  47. package/extensions/dm-lens/dist/clients/cascade-types.js +0 -1
  48. package/extensions/dm-lens/dist/clients/child-unref.js +0 -59
  49. package/extensions/dm-lens/dist/clients/code-quality-warnings.js +0 -192
  50. package/extensions/dm-lens/dist/clients/codebase-model.js +0 -110
  51. package/extensions/dm-lens/dist/clients/collateral-test-role.js +0 -8
  52. package/extensions/dm-lens/dist/clients/complexity-client.js +0 -398
  53. package/extensions/dm-lens/dist/clients/config-core/deny.js +0 -117
  54. package/extensions/dm-lens/dist/clients/config-core/index.js +0 -2
  55. package/extensions/dm-lens/dist/clients/config-core/merge.js +0 -228
  56. package/extensions/dm-lens/dist/clients/config-core/normalize.js +0 -217
  57. package/extensions/dm-lens/dist/clients/config-core/process-spec.js +0 -147
  58. package/extensions/dm-lens/dist/clients/config-core/provenance.js +0 -54
  59. package/extensions/dm-lens/dist/clients/config-core/records.js +0 -79
  60. package/extensions/dm-lens/dist/clients/config-core/resolve.js +0 -48
  61. package/extensions/dm-lens/dist/clients/config-core/safe-object.js +0 -22
  62. package/extensions/dm-lens/dist/clients/config-core/schema.js +0 -90
  63. package/extensions/dm-lens/dist/clients/config-diagnostic-codes.js +0 -90
  64. package/extensions/dm-lens/dist/clients/config-locations.js +0 -175
  65. package/extensions/dm-lens/dist/clients/config-resolve.js +0 -359
  66. package/extensions/dm-lens/dist/clients/config-schema.js +0 -128
  67. package/extensions/dm-lens/dist/clients/config-warn.js +0 -146
  68. package/extensions/dm-lens/dist/clients/console-guard-install.js +0 -4
  69. package/extensions/dm-lens/dist/clients/cooperative-budget.js +0 -36
  70. package/extensions/dm-lens/dist/clients/dead-code-client.js +0 -342
  71. package/extensions/dm-lens/dist/clients/dead-code-logger.js +0 -18
  72. package/extensions/dm-lens/dist/clients/deadline-utils.js +0 -117
  73. package/extensions/dm-lens/dist/clients/debug-handles.js +0 -121
  74. package/extensions/dm-lens/dist/clients/debug-heap.js +0 -80
  75. package/extensions/dm-lens/dist/clients/deferred-lsp-work.js +0 -33
  76. package/extensions/dm-lens/dist/clients/degradation-ledger.js +0 -272
  77. package/extensions/dm-lens/dist/clients/demoted-finding-render.js +0 -61
  78. package/extensions/dm-lens/dist/clients/dependency-checker.js +0 -525
  79. package/extensions/dm-lens/dist/clients/deps/ast-grep-napi.js +0 -17
  80. package/extensions/dm-lens/dist/clients/deps/dm-host-deps.js +0 -10
  81. package/extensions/dm-lens/dist/clients/deps/dm-tui-compat.js +0 -58
  82. package/extensions/dm-lens/dist/clients/deps/js-yaml.js +0 -7
  83. package/extensions/dm-lens/dist/clients/deps/minimatch.js +0 -6
  84. package/extensions/dm-lens/dist/clients/deps/pidusage.js +0 -5
  85. package/extensions/dm-lens/dist/clients/deps/typebox.js +0 -5
  86. package/extensions/dm-lens/dist/clients/deps/vscode-jsonrpc.js +0 -8
  87. package/extensions/dm-lens/dist/clients/deps/web-tree-sitter.js +0 -11
  88. package/extensions/dm-lens/dist/clients/diagnostic-dispositions.js +0 -318
  89. package/extensions/dm-lens/dist/clients/diagnostic-line-freshness.js +0 -144
  90. package/extensions/dm-lens/dist/clients/diagnostic-logger.js +0 -60
  91. package/extensions/dm-lens/dist/clients/diagnostic-tracker.js +0 -89
  92. package/extensions/dm-lens/dist/clients/diagnostics-publish.js +0 -134
  93. package/extensions/dm-lens/dist/clients/dispatch/ast-grep-catalog.js +0 -16
  94. package/extensions/dm-lens/dist/clients/dispatch/auxiliary-lsp.js +0 -158
  95. package/extensions/dm-lens/dist/clients/dispatch/collect-later-tier.js +0 -25
  96. package/extensions/dm-lens/dist/clients/dispatch/diagnostic-taxonomy.js +0 -58
  97. package/extensions/dm-lens/dist/clients/dispatch/dispatcher.js +0 -953
  98. package/extensions/dm-lens/dist/clients/dispatch/fact-provider-types.js +0 -1
  99. package/extensions/dm-lens/dist/clients/dispatch/fact-rule-runner.js +0 -17
  100. package/extensions/dm-lens/dist/clients/dispatch/fact-runner.js +0 -18
  101. package/extensions/dm-lens/dist/clients/dispatch/fact-scheduler.js +0 -52
  102. package/extensions/dm-lens/dist/clients/dispatch/fact-store.js +0 -199
  103. package/extensions/dm-lens/dist/clients/dispatch/facts/comment-facts.js +0 -20
  104. package/extensions/dm-lens/dist/clients/dispatch/facts/file-content.js +0 -18
  105. package/extensions/dm-lens/dist/clients/dispatch/facts/function-facts.js +0 -281
  106. package/extensions/dm-lens/dist/clients/dispatch/facts/import-facts.js +0 -169
  107. package/extensions/dm-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -19
  108. package/extensions/dm-lens/dist/clients/dispatch/facts/try-catch-facts.js +0 -95
  109. package/extensions/dm-lens/dist/clients/dispatch/finding-policy.js +0 -159
  110. package/extensions/dm-lens/dist/clients/dispatch/indent-detect.js +0 -227
  111. package/extensions/dm-lens/dist/clients/dispatch/inline-suppressions.js +0 -52
  112. package/extensions/dm-lens/dist/clients/dispatch/integration.js +0 -1463
  113. package/extensions/dm-lens/dist/clients/dispatch/lazy.js +0 -8
  114. package/extensions/dm-lens/dist/clients/dispatch/pending-runner-findings.js +0 -75
  115. package/extensions/dm-lens/dist/clients/dispatch/plan.js +0 -278
  116. package/extensions/dm-lens/dist/clients/dispatch/priorities.js +0 -14
  117. package/extensions/dm-lens/dist/clients/dispatch/rule-id-normalize.js +0 -42
  118. package/extensions/dm-lens/dist/clients/dispatch/rule-ignores.js +0 -21
  119. package/extensions/dm-lens/dist/clients/dispatch/rule-policy.js +0 -73
  120. package/extensions/dm-lens/dist/clients/dispatch/rules/async-noise.js +0 -31
  121. package/extensions/dm-lens/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
  122. package/extensions/dm-lens/dist/clients/dispatch/rules/cors-wildcard.js +0 -35
  123. package/extensions/dm-lens/dist/clients/dispatch/rules/error-obscuring.js +0 -29
  124. package/extensions/dm-lens/dist/clients/dispatch/rules/error-swallowing.js +0 -29
  125. package/extensions/dm-lens/dist/clients/dispatch/rules/framework-call-noise.js +0 -31
  126. package/extensions/dm-lens/dist/clients/dispatch/rules/high-complexity.js +0 -56
  127. package/extensions/dm-lens/dist/clients/dispatch/rules/high-fan-out.js +0 -45
  128. package/extensions/dm-lens/dist/clients/dispatch/rules/high-import-coupling.js +0 -31
  129. package/extensions/dm-lens/dist/clients/dispatch/rules/missing-error-propagation.js +0 -45
  130. package/extensions/dm-lens/dist/clients/dispatch/rules/no-commented-credentials.js +0 -46
  131. package/extensions/dm-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -38
  132. package/extensions/dm-lens/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
  133. package/extensions/dm-lens/dist/clients/dispatch/rules/unsafe-boundary.js +0 -101
  134. package/extensions/dm-lens/dist/clients/dispatch/runner-context.js +0 -46
  135. package/extensions/dm-lens/dist/clients/dispatch/runners/actionlint.js +0 -98
  136. package/extensions/dm-lens/dist/clients/dispatch/runners/ast-grep-napi.js +0 -690
  137. package/extensions/dm-lens/dist/clients/dispatch/runners/biome-check.js +0 -202
  138. package/extensions/dm-lens/dist/clients/dispatch/runners/cpp-check.js +0 -190
  139. package/extensions/dm-lens/dist/clients/dispatch/runners/credo.js +0 -66
  140. package/extensions/dm-lens/dist/clients/dispatch/runners/cue-vet.js +0 -167
  141. package/extensions/dm-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -151
  142. package/extensions/dm-lens/dist/clients/dispatch/runners/detekt.js +0 -157
  143. package/extensions/dm-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -157
  144. package/extensions/dm-lens/dist/clients/dispatch/runners/elixir-check.js +0 -153
  145. package/extensions/dm-lens/dist/clients/dispatch/runners/eslint.js +0 -99
  146. package/extensions/dm-lens/dist/clients/dispatch/runners/fact-rules.js +0 -20
  147. package/extensions/dm-lens/dist/clients/dispatch/runners/fish-indent.js +0 -65
  148. package/extensions/dm-lens/dist/clients/dispatch/runners/gleam-check.js +0 -107
  149. package/extensions/dm-lens/dist/clients/dispatch/runners/go-vet.js +0 -51
  150. package/extensions/dm-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -89
  151. package/extensions/dm-lens/dist/clients/dispatch/runners/hadolint.js +0 -83
  152. package/extensions/dm-lens/dist/clients/dispatch/runners/helm-lint.js +0 -144
  153. package/extensions/dm-lens/dist/clients/dispatch/runners/helm-render.js +0 -593
  154. package/extensions/dm-lens/dist/clients/dispatch/runners/htmlhint.js +0 -103
  155. package/extensions/dm-lens/dist/clients/dispatch/runners/index.js +0 -100
  156. package/extensions/dm-lens/dist/clients/dispatch/runners/javac.js +0 -82
  157. package/extensions/dm-lens/dist/clients/dispatch/runners/ktlint.js +0 -93
  158. package/extensions/dm-lens/dist/clients/dispatch/runners/lsp.js +0 -206
  159. package/extensions/dm-lens/dist/clients/dispatch/runners/markdownlint.js +0 -129
  160. package/extensions/dm-lens/dist/clients/dispatch/runners/mypy.js +0 -70
  161. package/extensions/dm-lens/dist/clients/dispatch/runners/oxlint.js +0 -305
  162. package/extensions/dm-lens/dist/clients/dispatch/runners/php-lint.js +0 -70
  163. package/extensions/dm-lens/dist/clients/dispatch/runners/phpstan.js +0 -90
  164. package/extensions/dm-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -56
  165. package/extensions/dm-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -307
  166. package/extensions/dm-lens/dist/clients/dispatch/runners/pyright.js +0 -118
  167. package/extensions/dm-lens/dist/clients/dispatch/runners/rubocop.js +0 -79
  168. package/extensions/dm-lens/dist/clients/dispatch/runners/ruff.js +0 -69
  169. package/extensions/dm-lens/dist/clients/dispatch/runners/rust-clippy.js +0 -147
  170. package/extensions/dm-lens/dist/clients/dispatch/runners/shellcheck.js +0 -111
  171. package/extensions/dm-lens/dist/clients/dispatch/runners/shfmt.js +0 -81
  172. package/extensions/dm-lens/dist/clients/dispatch/runners/spellcheck.js +0 -74
  173. package/extensions/dm-lens/dist/clients/dispatch/runners/spotbugs.js +0 -208
  174. package/extensions/dm-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -136
  175. package/extensions/dm-lens/dist/clients/dispatch/runners/stylelint.js +0 -118
  176. package/extensions/dm-lens/dist/clients/dispatch/runners/swiftlint.js +0 -143
  177. package/extensions/dm-lens/dist/clients/dispatch/runners/taplo.js +0 -97
  178. package/extensions/dm-lens/dist/clients/dispatch/runners/terragrunt.js +0 -110
  179. package/extensions/dm-lens/dist/clients/dispatch/runners/tflint.js +0 -104
  180. package/extensions/dm-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -516
  181. package/extensions/dm-lens/dist/clients/dispatch/runners/trivy-config.js +0 -155
  182. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/availability-policy.js +0 -285
  183. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -61
  184. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -61
  185. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -130
  186. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1067
  187. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -40
  188. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/tool-failure.js +0 -117
  189. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -88
  190. package/extensions/dm-lens/dist/clients/dispatch/runners/utils.js +0 -8
  191. package/extensions/dm-lens/dist/clients/dispatch/runners/vale.js +0 -106
  192. package/extensions/dm-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -163
  193. package/extensions/dm-lens/dist/clients/dispatch/runners/yamllint.js +0 -83
  194. package/extensions/dm-lens/dist/clients/dispatch/runners/zig-check.js +0 -72
  195. package/extensions/dm-lens/dist/clients/dispatch/suppress-writer.js +0 -57
  196. package/extensions/dm-lens/dist/clients/dispatch/tool-profile.js +0 -30
  197. package/extensions/dm-lens/dist/clients/dispatch/types.js +0 -7
  198. package/extensions/dm-lens/dist/clients/dispatch/utils/format-utils.js +0 -45
  199. package/extensions/dm-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -31
  200. package/extensions/dm-lens/dist/clients/disposition-logger.js +0 -19
  201. package/extensions/dm-lens/dist/clients/disposition-publish.js +0 -88
  202. package/extensions/dm-lens/dist/clients/durable-store.js +0 -77
  203. package/extensions/dm-lens/dist/clients/effective-config.js +0 -160
  204. package/extensions/dm-lens/dist/clients/env-utils.js +0 -26
  205. package/extensions/dm-lens/dist/clients/error-class.js +0 -3
  206. package/extensions/dm-lens/dist/clients/eval-timestamp.js +0 -2
  207. package/extensions/dm-lens/dist/clients/event-loop-hold.js +0 -119
  208. package/extensions/dm-lens/dist/clients/event-loop-monitor.js +0 -84
  209. package/extensions/dm-lens/dist/clients/extension-log.js +0 -230
  210. package/extensions/dm-lens/dist/clients/extension-mode.js +0 -20
  211. package/extensions/dm-lens/dist/clients/feature-hints.js +0 -88
  212. package/extensions/dm-lens/dist/clients/file-kinds.js +0 -304
  213. package/extensions/dm-lens/dist/clients/file-role.js +0 -50
  214. package/extensions/dm-lens/dist/clients/file-time.js +0 -112
  215. package/extensions/dm-lens/dist/clients/file-utils.js +0 -630
  216. package/extensions/dm-lens/dist/clients/finding-delivery-gate.js +0 -129
  217. package/extensions/dm-lens/dist/clients/finding-identity.js +0 -23
  218. package/extensions/dm-lens/dist/clients/fix-worklog.js +0 -75
  219. package/extensions/dm-lens/dist/clients/format-events-publish.js +0 -230
  220. package/extensions/dm-lens/dist/clients/format-service.js +0 -154
  221. package/extensions/dm-lens/dist/clients/formatters-lazy.js +0 -8
  222. package/extensions/dm-lens/dist/clients/formatters.js +0 -1351
  223. package/extensions/dm-lens/dist/clients/freshness-cadence.js +0 -1
  224. package/extensions/dm-lens/dist/clients/freshness.js +0 -8
  225. package/extensions/dm-lens/dist/clients/generated-artifacts.js +0 -209
  226. package/extensions/dm-lens/dist/clients/generation-guard.js +0 -105
  227. package/extensions/dm-lens/dist/clients/git-guard.js +0 -770
  228. package/extensions/dm-lens/dist/clients/git-tracked-ignore.js +0 -120
  229. package/extensions/dm-lens/dist/clients/gitleaks-client.js +0 -282
  230. package/extensions/dm-lens/dist/clients/go-client.js +0 -47
  231. package/extensions/dm-lens/dist/clients/govulncheck-client.js +0 -411
  232. package/extensions/dm-lens/dist/clients/gradle-ktfmt-style.js +0 -177
  233. package/extensions/dm-lens/dist/clients/grammar-source.js +0 -224
  234. package/extensions/dm-lens/dist/clients/gzip-stage-write.js +0 -85
  235. package/extensions/dm-lens/dist/clients/hashline-anchor.js +0 -222
  236. package/extensions/dm-lens/dist/clients/hook-budgets.js +0 -16
  237. package/extensions/dm-lens/dist/clients/host-edit-normalize.js +0 -87
  238. package/extensions/dm-lens/dist/clients/host-ports.js +0 -35
  239. package/extensions/dm-lens/dist/clients/indent-retarget.js +0 -102
  240. package/extensions/dm-lens/dist/clients/inline-blocker-dispositions.js +0 -103
  241. package/extensions/dm-lens/dist/clients/install-diagnostics.js +0 -123
  242. package/extensions/dm-lens/dist/clients/installer/index.js +0 -3770
  243. package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh-session.js +0 -17
  244. package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh.js +0 -522
  245. package/extensions/dm-lens/dist/clients/instance-reaper-state.js +0 -3
  246. package/extensions/dm-lens/dist/clients/instance-reaper.js +0 -577
  247. package/extensions/dm-lens/dist/clients/instance-registry-lock.js +0 -131
  248. package/extensions/dm-lens/dist/clients/instance-registry.js +0 -452
  249. package/extensions/dm-lens/dist/clients/jscpd-client.js +0 -252
  250. package/extensions/dm-lens/dist/clients/json-cache-read.js +0 -25
  251. package/extensions/dm-lens/dist/clients/knip-client.js +0 -472
  252. package/extensions/dm-lens/dist/clients/language-policy.js +0 -242
  253. package/extensions/dm-lens/dist/clients/language-profile.js +0 -261
  254. package/extensions/dm-lens/dist/clients/language-registry.js +0 -424
  255. package/extensions/dm-lens/dist/clients/latency-logger.js +0 -192
  256. package/extensions/dm-lens/dist/clients/lazy-import.js +0 -14
  257. package/extensions/dm-lens/dist/clients/ledger-bounds.js +0 -21
  258. package/extensions/dm-lens/dist/clients/lens-config.js +0 -237
  259. package/extensions/dm-lens/dist/clients/lens-engine.js +0 -181
  260. package/extensions/dm-lens/dist/clients/lens-events.js +0 -105
  261. package/extensions/dm-lens/dist/clients/lens-flag-registry.js +0 -302
  262. package/extensions/dm-lens/dist/clients/lens-map.js +0 -980
  263. package/extensions/dm-lens/dist/clients/live-bus-emitter.js +0 -53
  264. package/extensions/dm-lens/dist/clients/log-cleanup.js +0 -138
  265. package/extensions/dm-lens/dist/clients/lsp/aggregation.js +0 -88
  266. package/extensions/dm-lens/dist/clients/lsp/cascade-tier.js +0 -203
  267. package/extensions/dm-lens/dist/clients/lsp/client.js +0 -2709
  268. package/extensions/dm-lens/dist/clients/lsp/config.js +0 -252
  269. package/extensions/dm-lens/dist/clients/lsp/content-limits.js +0 -21
  270. package/extensions/dm-lens/dist/clients/lsp/diagnostic-binding.js +0 -79
  271. package/extensions/dm-lens/dist/clients/lsp/document-drift.js +0 -312
  272. package/extensions/dm-lens/dist/clients/lsp/edits.js +0 -930
  273. package/extensions/dm-lens/dist/clients/lsp/index.js +0 -4448
  274. package/extensions/dm-lens/dist/clients/lsp/inferred-project.js +0 -121
  275. package/extensions/dm-lens/dist/clients/lsp/jvm-runtime.js +0 -194
  276. package/extensions/dm-lens/dist/clients/lsp/language.js +0 -23
  277. package/extensions/dm-lens/dist/clients/lsp/launch.js +0 -468
  278. package/extensions/dm-lens/dist/clients/lsp/lombok.js +0 -146
  279. package/extensions/dm-lens/dist/clients/lsp/path-utils.js +0 -1
  280. package/extensions/dm-lens/dist/clients/lsp/pending-aux-coverage.js +0 -90
  281. package/extensions/dm-lens/dist/clients/lsp/position-encoding.js +0 -28
  282. package/extensions/dm-lens/dist/clients/lsp/ruby-drive-dirs.js +0 -42
  283. package/extensions/dm-lens/dist/clients/lsp/server.js +0 -2422
  284. package/extensions/dm-lens/dist/clients/lsp/session-roots.js +0 -52
  285. package/extensions/dm-lens/dist/clients/lsp/spawn-history.js +0 -15
  286. package/extensions/dm-lens/dist/clients/lsp/sync-kind.js +0 -30
  287. package/extensions/dm-lens/dist/clients/lsp/tsserver-sync.js +0 -156
  288. package/extensions/dm-lens/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
  289. package/extensions/dm-lens/dist/clients/lsp/wait-policy/classification.js +0 -36
  290. package/extensions/dm-lens/dist/clients/lsp/wait-policy/index.js +0 -3
  291. package/extensions/dm-lens/dist/clients/lsp/wait-policy/strategies.js +0 -175
  292. package/extensions/dm-lens/dist/clients/lsp/watch-queue.js +0 -40
  293. package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-cache.js +0 -267
  294. package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-session.js +0 -7
  295. package/extensions/dm-lens/dist/clients/lsp/workspace-sweep-hold.js +0 -93
  296. package/extensions/dm-lens/dist/clients/lsp-budget.js +0 -83
  297. package/extensions/dm-lens/dist/clients/lsp-document-symbols.js +0 -93
  298. package/extensions/dm-lens/dist/clients/lsp-lazy.js +0 -8
  299. package/extensions/dm-lens/dist/clients/lsp-mutation.js +0 -273
  300. package/extensions/dm-lens/dist/clients/lsp-status.js +0 -37
  301. package/extensions/dm-lens/dist/clients/map-with-concurrency.js +0 -20
  302. package/extensions/dm-lens/dist/clients/mcp/analyze.js +0 -251
  303. package/extensions/dm-lens/dist/clients/mcp/host-shim.js +0 -14
  304. package/extensions/dm-lens/dist/clients/mcp/ipc.js +0 -302
  305. package/extensions/dm-lens/dist/clients/mcp/review.js +0 -137
  306. package/extensions/dm-lens/dist/clients/mcp/session.js +0 -305
  307. package/extensions/dm-lens/dist/clients/memory-sampler.js +0 -107
  308. package/extensions/dm-lens/dist/clients/message-end-attribution.js +0 -18
  309. package/extensions/dm-lens/dist/clients/metrics-client.js +0 -80
  310. package/extensions/dm-lens/dist/clients/metrics-history.js +0 -255
  311. package/extensions/dm-lens/dist/clients/middle-man-analysis.js +0 -161
  312. package/extensions/dm-lens/dist/clients/model-provider.js +0 -31
  313. package/extensions/dm-lens/dist/clients/module-report-lsp.js +0 -140
  314. package/extensions/dm-lens/dist/clients/module-report.js +0 -1642
  315. package/extensions/dm-lens/dist/clients/mutating-tool.js +0 -377
  316. package/extensions/dm-lens/dist/clients/mutation-attribution.js +0 -168
  317. package/extensions/dm-lens/dist/clients/mutation-bridge.js +0 -102
  318. package/extensions/dm-lens/dist/clients/ndjson-logger.js +0 -471
  319. package/extensions/dm-lens/dist/clients/observed-mutation-sources.js +0 -43
  320. package/extensions/dm-lens/dist/clients/observed-mutation.js +0 -709
  321. package/extensions/dm-lens/dist/clients/oldtext-autopatch.js +0 -100
  322. package/extensions/dm-lens/dist/clients/opaque-mutation-scan.js +0 -313
  323. package/extensions/dm-lens/dist/clients/opengrep-client.js +0 -216
  324. package/extensions/dm-lens/dist/clients/opengrep-config.js +0 -52
  325. package/extensions/dm-lens/dist/clients/package-manager.js +0 -303
  326. package/extensions/dm-lens/dist/clients/package-root.js +0 -25
  327. package/extensions/dm-lens/dist/clients/partial-edit-apply.js +0 -337
  328. package/extensions/dm-lens/dist/clients/path-attribution-telemetry.js +0 -31
  329. package/extensions/dm-lens/dist/clients/path-keyed-map.js +0 -57
  330. package/extensions/dm-lens/dist/clients/path-utils.js +0 -476
  331. package/extensions/dm-lens/dist/clients/performance-report.js +0 -291
  332. package/extensions/dm-lens/dist/clients/persist-debounce.js +0 -37
  333. package/extensions/dm-lens/dist/clients/persistent-reverify.js +0 -165
  334. package/extensions/dm-lens/dist/clients/php-cs-fixer-config.js +0 -15
  335. package/extensions/dm-lens/dist/clients/pipeline.js +0 -1091
  336. package/extensions/dm-lens/dist/clients/post-autofix-notice.js +0 -19
  337. package/extensions/dm-lens/dist/clients/print-mode.js +0 -3
  338. package/extensions/dm-lens/dist/clients/probe-home-state.js +0 -62
  339. package/extensions/dm-lens/dist/clients/process-bridge.js +0 -20
  340. package/extensions/dm-lens/dist/clients/process-singletons.js +0 -69
  341. package/extensions/dm-lens/dist/clients/process-snapshot.js +0 -22
  342. package/extensions/dm-lens/dist/clients/project-changes.js +0 -112
  343. package/extensions/dm-lens/dist/clients/project-conventions.js +0 -152
  344. package/extensions/dm-lens/dist/clients/project-diagnostics/cache.js +0 -91
  345. package/extensions/dm-lens/dist/clients/project-diagnostics/extractors.js +0 -53
  346. package/extensions/dm-lens/dist/clients/project-diagnostics/fresh-fetch.js +0 -408
  347. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -64
  348. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -38
  349. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -21
  350. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -23
  351. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -28
  352. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -45
  353. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -34
  354. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -32
  355. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -79
  356. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -41
  357. package/extensions/dm-lens/dist/clients/project-diagnostics/scanner.js +0 -349
  358. package/extensions/dm-lens/dist/clients/project-diagnostics/types.js +0 -1
  359. package/extensions/dm-lens/dist/clients/project-lens-config.js +0 -437
  360. package/extensions/dm-lens/dist/clients/project-report.js +0 -527
  361. package/extensions/dm-lens/dist/clients/project-scale.js +0 -60
  362. package/extensions/dm-lens/dist/clients/project-scan-policy.js +0 -4
  363. package/extensions/dm-lens/dist/clients/project-snapshot-fingerprint.js +0 -39
  364. package/extensions/dm-lens/dist/clients/project-snapshot-persist-worker.js +0 -14
  365. package/extensions/dm-lens/dist/clients/project-snapshot.js +0 -1178
  366. package/extensions/dm-lens/dist/clients/project-trust.js +0 -104
  367. package/extensions/dm-lens/dist/clients/python-environment.js +0 -120
  368. package/extensions/dm-lens/dist/clients/python-provenance.js +0 -551
  369. package/extensions/dm-lens/dist/clients/quiet-window-config.js +0 -16
  370. package/extensions/dm-lens/dist/clients/quiet-window.js +0 -126
  371. package/extensions/dm-lens/dist/clients/read-bridge.js +0 -46
  372. package/extensions/dm-lens/dist/clients/read-expansion.js +0 -218
  373. package/extensions/dm-lens/dist/clients/read-guard-logger.js +0 -178
  374. package/extensions/dm-lens/dist/clients/read-guard-tool-lines.js +0 -1042
  375. package/extensions/dm-lens/dist/clients/read-guard.js +0 -1096
  376. package/extensions/dm-lens/dist/clients/recent-touches.js +0 -126
  377. package/extensions/dm-lens/dist/clients/redact/secrets.js +0 -386
  378. package/extensions/dm-lens/dist/clients/resource-sampler.js +0 -344
  379. package/extensions/dm-lens/dist/clients/reverse-deps.js +0 -227
  380. package/extensions/dm-lens/dist/clients/review-graph/builder.js +0 -3635
  381. package/extensions/dm-lens/dist/clients/review-graph/format.js +0 -30
  382. package/extensions/dm-lens/dist/clients/review-graph/git-identity.js +0 -115
  383. package/extensions/dm-lens/dist/clients/review-graph/import-resolvers.js +0 -325
  384. package/extensions/dm-lens/dist/clients/review-graph/persist-worker.js +0 -8
  385. package/extensions/dm-lens/dist/clients/review-graph/query.js +0 -195
  386. package/extensions/dm-lens/dist/clients/review-graph/revision-drift.js +0 -3
  387. package/extensions/dm-lens/dist/clients/review-graph/service.js +0 -60
  388. package/extensions/dm-lens/dist/clients/review-graph/shared-extraction-ir.js +0 -54
  389. package/extensions/dm-lens/dist/clients/review-graph/symbol-id.js +0 -29
  390. package/extensions/dm-lens/dist/clients/review-graph/tsconfig-paths.js +0 -253
  391. package/extensions/dm-lens/dist/clients/review-graph/types.js +0 -1
  392. package/extensions/dm-lens/dist/clients/review-graph/workspace-modules.js +0 -374
  393. package/extensions/dm-lens/dist/clients/review-graph-logger.js +0 -51
  394. package/extensions/dm-lens/dist/clients/ruff-client.js +0 -109
  395. package/extensions/dm-lens/dist/clients/rules-scanner.js +0 -113
  396. package/extensions/dm-lens/dist/clients/run-duration.js +0 -9
  397. package/extensions/dm-lens/dist/clients/runtime-agent-end.js +0 -608
  398. package/extensions/dm-lens/dist/clients/runtime-config.js +0 -39
  399. package/extensions/dm-lens/dist/clients/runtime-context.js +0 -155
  400. package/extensions/dm-lens/dist/clients/runtime-coordinator.js +0 -817
  401. package/extensions/dm-lens/dist/clients/runtime-session.js +0 -1625
  402. package/extensions/dm-lens/dist/clients/runtime-tool-call.js +0 -868
  403. package/extensions/dm-lens/dist/clients/runtime-tool-result.js +0 -1317
  404. package/extensions/dm-lens/dist/clients/runtime-turn.js +0 -2333
  405. package/extensions/dm-lens/dist/clients/rust-client.js +0 -48
  406. package/extensions/dm-lens/dist/clients/safe-spawn.js +0 -1267
  407. package/extensions/dm-lens/dist/clients/sanitize.js +0 -174
  408. package/extensions/dm-lens/dist/clients/scan-utils.js +0 -7
  409. package/extensions/dm-lens/dist/clients/scratch-tree-policy.js +0 -57
  410. package/extensions/dm-lens/dist/clients/search-read-registration.js +0 -59
  411. package/extensions/dm-lens/dist/clients/secret-findings.js +0 -69
  412. package/extensions/dm-lens/dist/clients/security-scan-client.js +0 -208
  413. package/extensions/dm-lens/dist/clients/session-event-guard.js +0 -111
  414. package/extensions/dm-lens/dist/clients/session-lifecycle.js +0 -173
  415. package/extensions/dm-lens/dist/clients/session-start-observability.js +0 -47
  416. package/extensions/dm-lens/dist/clients/session-state-store.js +0 -63
  417. package/extensions/dm-lens/dist/clients/session-summary.js +0 -8
  418. package/extensions/dm-lens/dist/clients/sessionstart-logger.js +0 -22
  419. package/extensions/dm-lens/dist/clients/sg-runner.js +0 -627
  420. package/extensions/dm-lens/dist/clients/sgconfig.js +0 -280
  421. package/extensions/dm-lens/dist/clients/shared-checkout-guard.js +0 -177
  422. package/extensions/dm-lens/dist/clients/single-flight.js +0 -52
  423. package/extensions/dm-lens/dist/clients/situational-tool-telemetry.js +0 -85
  424. package/extensions/dm-lens/dist/clients/skills-resolver.js +0 -38
  425. package/extensions/dm-lens/dist/clients/slow-fs.js +0 -77
  426. package/extensions/dm-lens/dist/clients/smells-rollup.js +0 -118
  427. package/extensions/dm-lens/dist/clients/source-filter.js +0 -320
  428. package/extensions/dm-lens/dist/clients/source-walker.js +0 -96
  429. package/extensions/dm-lens/dist/clients/spawn-output-cap.js +0 -35
  430. package/extensions/dm-lens/dist/clients/spawn-timeout-cooldown.js +0 -51
  431. package/extensions/dm-lens/dist/clients/stale-marker.js +0 -1
  432. package/extensions/dm-lens/dist/clients/startup-scan.js +0 -222
  433. package/extensions/dm-lens/dist/clients/startup-timing.js +0 -67
  434. package/extensions/dm-lens/dist/clients/string-utils.js +0 -6
  435. package/extensions/dm-lens/dist/clients/subagent-mode.js +0 -40
  436. package/extensions/dm-lens/dist/clients/symbol-containment.js +0 -16
  437. package/extensions/dm-lens/dist/clients/symbol-types.js +0 -1
  438. package/extensions/dm-lens/dist/clients/test-runner-client.js +0 -1504
  439. package/extensions/dm-lens/dist/clients/test-runner-delivery.js +0 -260
  440. package/extensions/dm-lens/dist/clients/todo-scanner.js +0 -164
  441. package/extensions/dm-lens/dist/clients/tool-agreement.js +0 -377
  442. package/extensions/dm-lens/dist/clients/tool-config.js +0 -218
  443. package/extensions/dm-lens/dist/clients/tool-cwd.js +0 -235
  444. package/extensions/dm-lens/dist/clients/tool-definition.js +0 -22
  445. package/extensions/dm-lens/dist/clients/tool-event.js +0 -18
  446. package/extensions/dm-lens/dist/clients/tool-policy.js +0 -2393
  447. package/extensions/dm-lens/dist/clients/tool-probe.js +0 -5
  448. package/extensions/dm-lens/dist/clients/tool-render.js +0 -79
  449. package/extensions/dm-lens/dist/clients/tool-set-policy.js +0 -70
  450. package/extensions/dm-lens/dist/clients/tree-sitter-cache.js +0 -206
  451. package/extensions/dm-lens/dist/clients/tree-sitter-client.js +0 -2787
  452. package/extensions/dm-lens/dist/clients/tree-sitter-logger.js +0 -77
  453. package/extensions/dm-lens/dist/clients/tree-sitter-navigator.js +0 -198
  454. package/extensions/dm-lens/dist/clients/tree-sitter-query-loader.js +0 -318
  455. package/extensions/dm-lens/dist/clients/tree-sitter-shared.js +0 -87
  456. package/extensions/dm-lens/dist/clients/tree-sitter-symbol-extractor.js +0 -957
  457. package/extensions/dm-lens/dist/clients/trivy-client.js +0 -305
  458. package/extensions/dm-lens/dist/clients/tui-fit.js +0 -26
  459. package/extensions/dm-lens/dist/clients/turn-context.js +0 -48
  460. package/extensions/dm-lens/dist/clients/turn-end/lane.js +0 -1
  461. package/extensions/dm-lens/dist/clients/turn-end/lanes/govulncheck.js +0 -54
  462. package/extensions/dm-lens/dist/clients/turn-end/lanes/secrets.js +0 -131
  463. package/extensions/dm-lens/dist/clients/turn-summary-render.js +0 -56
  464. package/extensions/dm-lens/dist/clients/turn-summary.js +0 -84
  465. package/extensions/dm-lens/dist/clients/typos-config.js +0 -9
  466. package/extensions/dm-lens/dist/clients/user-notify.js +0 -15
  467. package/extensions/dm-lens/dist/clients/vanished-instance-marker.js +0 -18
  468. package/extensions/dm-lens/dist/clients/warm-attach.js +0 -210
  469. package/extensions/dm-lens/dist/clients/widget-state.js +0 -963
  470. package/extensions/dm-lens/dist/clients/word-index-logger.js +0 -21
  471. package/extensions/dm-lens/dist/clients/word-index-store.js +0 -222
  472. package/extensions/dm-lens/dist/clients/word-index.js +0 -1426
  473. package/extensions/dm-lens/dist/clients/workspace-topology.js +0 -261
  474. package/extensions/dm-lens/dist/clients/write-ordering-guard.js +0 -24
  475. package/extensions/dm-lens/dist/clients/zizmor-config.js +0 -160
  476. package/extensions/dm-lens/dist/i18n.js +0 -67
  477. package/extensions/dm-lens/dist/index.js +0 -1782
  478. package/extensions/dm-lens/dist/mcp/analyze-cli.js +0 -178
  479. package/extensions/dm-lens/dist/mcp/build-staleness.js +0 -55
  480. package/extensions/dm-lens/dist/mcp/cli.js +0 -78
  481. package/extensions/dm-lens/dist/mcp/server.js +0 -1208
  482. package/extensions/dm-lens/dist/mcp/worker.js +0 -33
  483. package/extensions/dm-lens/dist/scripts/lib/process-scan.mjs +0 -256
  484. package/extensions/dm-lens/dist/scripts/lib/skills-predicate.mjs +0 -53
  485. package/extensions/dm-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -45
  486. package/extensions/dm-lens/dist/tools/activate-tools.js +0 -61
  487. package/extensions/dm-lens/dist/tools/ast-grep-outline.js +0 -127
  488. package/extensions/dm-lens/dist/tools/ast-grep-replace.js +0 -226
  489. package/extensions/dm-lens/dist/tools/ast-grep-search.js +0 -687
  490. package/extensions/dm-lens/dist/tools/effective-config.js +0 -59
  491. package/extensions/dm-lens/dist/tools/lens-diagnostic-mark.js +0 -240
  492. package/extensions/dm-lens/dist/tools/lens-diagnostics.js +0 -1484
  493. package/extensions/dm-lens/dist/tools/lsp-diagnostics.js +0 -1088
  494. package/extensions/dm-lens/dist/tools/lsp-navigation.js +0 -1194
  495. package/extensions/dm-lens/dist/tools/lsp-structured-output.js +0 -277
  496. package/extensions/dm-lens/dist/tools/module-report.js +0 -332
  497. package/extensions/dm-lens/dist/tools/project-report.js +0 -72
  498. package/extensions/dm-lens/dist/tools/render-compact.js +0 -272
  499. package/extensions/dm-lens/dist/tools/scan-progress.js +0 -31
  500. package/extensions/dm-lens/dist/tools/shared.js +0 -26
  501. package/extensions/dm-lens/dist/tools/symbol-search.js +0 -133
  502. package/extensions/dm-mcp-adapter/dist/abort.js +0 -35
  503. package/extensions/dm-mcp-adapter/dist/agent-dir.js +0 -45
  504. package/extensions/dm-mcp-adapter/dist/agent-plugin-loader.js +0 -392
  505. package/extensions/dm-mcp-adapter/dist/agent-plugin-provenance.js +0 -26
  506. package/extensions/dm-mcp-adapter/dist/bearer-command-resolver.js +0 -182
  507. package/extensions/dm-mcp-adapter/dist/claude-plugin-loader.js +0 -350
  508. package/extensions/dm-mcp-adapter/dist/config.js +0 -1310
  509. package/extensions/dm-mcp-adapter/dist/consent-manager.js +0 -84
  510. package/extensions/dm-mcp-adapter/dist/elicitation-handler.js +0 -308
  511. package/extensions/dm-mcp-adapter/dist/errors.js +0 -225
  512. package/extensions/dm-mcp-adapter/dist/http-ca.js +0 -71
  513. package/extensions/dm-mcp-adapter/dist/jev-client.js +0 -359
  514. package/extensions/dm-mcp-adapter/dist/jev-contracts.js +0 -1
  515. package/extensions/dm-mcp-adapter/dist/jev-key-store.js +0 -176
  516. package/extensions/dm-mcp-adapter/dist/json-schema-validator.js +0 -70
  517. package/extensions/dm-mcp-adapter/dist/lifecycle.js +0 -387
  518. package/extensions/dm-mcp-adapter/dist/logger.js +0 -115
  519. package/extensions/dm-mcp-adapter/dist/mcp-auth-fetch.js +0 -86
  520. package/extensions/dm-mcp-adapter/dist/mcp-auth-flow.js +0 -949
  521. package/extensions/dm-mcp-adapter/dist/mcp-auth.js +0 -997
  522. package/extensions/dm-mcp-adapter/dist/mcp-bearer-store.js +0 -182
  523. package/extensions/dm-mcp-adapter/dist/mcp-callback-server.js +0 -381
  524. package/extensions/dm-mcp-adapter/dist/mcp-oauth-provider.js +0 -524
  525. package/extensions/dm-mcp-adapter/dist/mcp-probe.js +0 -151
  526. package/extensions/dm-mcp-adapter/dist/mcp-tasks.js +0 -300
  527. package/extensions/dm-mcp-adapter/dist/mcp-trace.js +0 -215
  528. package/extensions/dm-mcp-adapter/dist/metadata-cache.js +0 -267
  529. package/extensions/dm-mcp-adapter/dist/npx-resolver.js +0 -465
  530. package/extensions/dm-mcp-adapter/dist/package-mcp-loader.js +0 -135
  531. package/extensions/dm-mcp-adapter/dist/request-headers-command.js +0 -294
  532. package/extensions/dm-mcp-adapter/dist/resource-tools.js +0 -7
  533. package/extensions/dm-mcp-adapter/dist/runtime-owner.js +0 -94
  534. package/extensions/dm-mcp-adapter/dist/sampling-handler.js +0 -213
  535. package/extensions/dm-mcp-adapter/dist/secure-keyring.js +0 -191
  536. package/extensions/dm-mcp-adapter/dist/server-manager.js +0 -1514
  537. package/extensions/dm-mcp-adapter/dist/session-approvals.js +0 -127
  538. package/extensions/dm-mcp-adapter/dist/session-recovery.js +0 -82
  539. package/extensions/dm-mcp-adapter/dist/state.js +0 -1
  540. package/extensions/dm-mcp-adapter/dist/types.js +0 -286
  541. package/extensions/dm-mcp-adapter/dist/ui-app-bridge-helpers.js +0 -36
  542. package/extensions/dm-mcp-adapter/dist/ui-resource-handler.js +0 -204
  543. package/extensions/dm-mcp-adapter/dist/ui-stream-types.js +0 -58
  544. package/extensions/dm-mcp-adapter/dist/ui-tool-visibility.js +0 -26
  545. package/extensions/dm-mcp-adapter/dist/unix-socket-transport.js +0 -83
  546. package/extensions/dm-mcp-adapter/dist/utils.js +0 -382
@@ -1,1484 +0,0 @@
1
- import { promises as fs } from "node:fs";
2
- import * as fsSync from "node:fs";
3
- import * as path from "node:path";
4
- import { BoundedLruCache } from "../clients/bounded-cache.js";
5
- import { Type } from "../clients/deps/typebox.js";
6
- import { anchorsForDiagnostic, applyDispositions, applyWeakDispositions, hasAnyDispositionMarks, hasStrictDispositionMarks, getDisposition } from "../clients/diagnostic-dispositions.js";
7
- import { DEPENDENCY_DRIFT_MAX_DELIVERIES } from "../clients/blocker-freshness.js";
8
- import { freshnessFromMtime } from "../clients/freshness.js";
9
- import { applyFindingPolicy, loadProjectRulePolicyMap } from "../clients/dispatch/finding-policy.js";
10
- import { gateFindingsByPathFreshness } from "../clients/advisory-provenance.js";
11
- import { formatCacheAgeLabel, markUnreconciledFindings } from "../clients/finding-delivery-gate.js";
12
- import { normalizeRuleId } from "../clients/dispatch/rule-id-normalize.js";
13
- import { applyRulePolicy } from "../clients/dispatch/rule-policy.js";
14
- import { compactRenderResult } from "./render-compact.js";
15
- import { combineAbortSignals } from "../clients/deadline-utils.js";
16
- import { getProjectIgnoreMatcher } from "../clients/file-utils.js";
17
- import { isAtOrAboveHomeDir, normalizeEphemeralMapKey, normalizeFilePath, normalizeMapKey, realpathOrResolve } from "../clients/path-utils.js";
18
- import { getLSPService } from "../clients/lsp/index.js";
19
- import { retireInlineBlockerAndResyncGuard } from "../clients/git-guard.js";
20
- import { primaryServerId, resolveLspCwdForFile } from "../clients/lsp/config.js";
21
- import { getFullScanWallClockMs } from "../clients/lsp/workspace-sweep-hold.js";
22
- import { demoteInferredProjectSweepResults } from "../clients/lsp/inferred-project.js";
23
- import { hashDiagnosticContent } from "../clients/lsp/diagnostic-binding.js";
24
- import { loadProjectDiagnosticsDeltaReport, loadProjectDiagnosticsSnapshot, PROJECT_DIAGNOSTICS_CACHE_VERSION, reconcileProjectDiagnosticsSnapshot } from "../clients/project-diagnostics/cache.js";
25
- import { formatCacheAgeOld, formatNotRunEntry } from "../clients/project-diagnostics/extractors.js";
26
- import { ANALYZER_IDS, fetchFreshProjectDiagnostics } from "../clients/project-diagnostics/fresh-fetch.js";
27
- import { loadBootstrapClients } from "../clients/bootstrap.js";
28
- import { resolveLensToolName } from "../clients/tool-config.js";
29
- import { generatedSkipNotice, scanTruncationNotice } from "../clients/lens-engine.js";
30
- import { scanProjectDiagnostics } from "../clients/project-diagnostics/scanner.js";
31
- import { classifyDiagnosticTier, getFileDiagnosticSummaries, reconcileCorrelatedScanDiagnostics, reconcileScanDiagnostics, reconcileStaleWidgetDependencyBlockers, reconcileStaleWidgetFiles, widgetDiagnosticUri } from "../clients/widget-state.js";
32
- import { claimPhaseOncePerSession, logLatency } from "../clients/latency-logger.js";
33
- import { logExtension } from "../clients/extension-log.js";
34
- import { recordDegradationOnce } from "../clients/degradation-ledger.js";
35
- import { convertLspDiagnostics } from "../clients/dispatch/utils/lsp-diagnostics.js";
36
- import { findAuxiliaryProfileForSource, retagAuxiliaryDiagnostics } from "../clients/dispatch/auxiliary-lsp.js";
37
- import { detectFileRole } from "../clients/file-role.js";
38
- import { STALE_LINE_MARKER } from "../clients/stale-marker.js";
39
- import { makeProgressReporter, scanningSummaryLine } from "./scan-progress.js";
40
- import { createLspDiagnosticsTool, LSP_SEVERITY_FILTERS, MAX_BATCH_FILES, renderBatchOutcomeLines } from "./lsp-diagnostics.js";
41
- import { demotePastEofDiagnostics, PAST_EOF_STALE_MARKER, resyncDocumentOnPastEof } from "../clients/diagnostic-line-freshness.js";
42
- const MAX_DIAGNOSTICS_PER_FILE = 50;
43
- const MAX_PATHS_ENTRIES = MAX_BATCH_FILES;
44
- function notRequestedReason(host) {
45
- return "refreshRunners not requested this call (quick mode) — pass " + `refreshRunners=cheap/all/cached to ${resolveLensToolName("lens_diagnostics", host) ?? "diagnostics"} mode=full to run it`;
46
- }
47
- const FULL_SCAN_WALL_CLOCK_MS = getFullScanWallClockMs();
48
- const FULL_SCAN_BINDING_YIELD_EVERY = 16;
49
- async function findFullScanBindingMismatches(results) {
50
- const mismatched = new WeakSet;
51
- let sinceYield = 0;
52
- for (const result of results) {
53
- if (result.boundToCurrentDisk === false) {
54
- mismatched.add(result);
55
- } else if (result.boundToCurrentDisk !== true && result.contentHash !== undefined) {
56
- try {
57
- const content = await fs.readFile(result.filePath, "utf-8");
58
- if (hashDiagnosticContent(content) !== result.contentHash) {
59
- mismatched.add(result);
60
- }
61
- } catch {}
62
- }
63
- sinceYield += 1;
64
- if (sinceYield >= FULL_SCAN_BINDING_YIELD_EVERY) {
65
- sinceYield = 0;
66
- await new Promise((resolve) => setImmediate(resolve));
67
- }
68
- }
69
- return mismatched;
70
- }
71
- export function createLensDiagnosticsTool(cacheManager, getCwd, getLspService = getLSPService, flushPending = async () => {}, nextWriteIndex, captureLspStatusRepaint, getRuntime, isLensGuardEnabled = () => true) {
72
- const lspProbe = createLspDiagnosticsTool(nextWriteIndex, (info) => {
73
- const runtime = getRuntime?.();
74
- if (!runtime)
75
- return;
76
- const retired = retireInlineBlockerAndResyncGuard({
77
- runtime,
78
- cacheManager,
79
- cwd: info.cwd,
80
- filePath: info.filePath,
81
- ...info.writeIndex === undefined ? {} : { writeIndex: info.writeIndex },
82
- coveredSources: info.coveredSources,
83
- lensGuardEnabled: isLensGuardEnabled()
84
- });
85
- if (retired) {
86
- logExtension({
87
- subsystem: "git-guard",
88
- level: "debug",
89
- message: `inline_blocker: retired for ${info.filePath}`
90
- });
91
- }
92
- }, getLspService);
93
- return {
94
- name: "lens_diagnostics",
95
- label: "Project Diagnostics",
96
- description: 'Query dm-lens diagnostics from the session cache or an active LSP probe, at paths or workspace scope. Empty cache is not proof of clean; probe changed paths when findings are absent or stale. Example: `{source: "lsp", scope: "paths", paths: ["src/app.ts"]}`.',
97
- promptSnippet: "lens_diagnostics source=session reads the session cache and an empty cache is not proof of a clean file; use source=lsp scope=paths for changed files when cached findings are absent or stale",
98
- renderResult: compactRenderResult(({ details, args, isError, text }) => {
99
- if (details?.source === "lsp") {
100
- const count = details.totalDiagnostics ?? 0;
101
- const files = details.filesChecked ?? details.filesScanned ?? 0;
102
- const noun = count === 1 ? "diagnostic" : "diagnostics";
103
- const filePath = typeof details?.filePath === "string" ? details.filePath : Array.isArray(args?.paths) && args.paths.length === 1 && typeof args.paths[0] === "string" ? args.paths[0] : undefined;
104
- const singleFile = (details?.mode === "file" || files === 1) && typeof filePath === "string" ? ` ${path.basename(filePath)}` : "";
105
- const scope = files > 1 ? ` across ${files} files` : singleFile;
106
- if (isError)
107
- return `lens_diagnostics lsp — ${text.split(`
108
- `)[0] ?? "error"}`;
109
- if ((details.navigationOnlyFiles ?? 0) > 0)
110
- return `lens_diagnostics${scope} — ${count} ${noun} · ${details.cleanFiles ?? 0} clean · ${details.navigationOnlyFiles} navigation-only`;
111
- if ((details.unconfirmedFiles ?? 0) > 0)
112
- return `lens_diagnostics${scope} — ${count} ${noun} · ${details.cleanFiles ?? 0} clean · ${details.unconfirmedFiles} unconfirmed${details.timedOutFiles ? ` (${details.timedOutFiles} timed out)` : ""}`;
113
- const outcomeCounts = details.outcomeCounts;
114
- const tooLargeLines = renderBatchOutcomeLines(details.outcomes ?? []);
115
- if (tooLargeLines.length > 0)
116
- return `lens_diagnostics${scope} — too large: ${tooLargeLines.join("; ")}`;
117
- const notConfirmed = outcomeCounts ? (outcomeCounts.inconclusive ?? 0) + (outcomeCounts.unavailable ?? 0) + (outcomeCounts.unsupported ?? 0) + (outcomeCounts.failed ?? 0) + (outcomeCounts.too_large ?? 0) : 0;
118
- if (notConfirmed > 0)
119
- return `lens_diagnostics${scope} — ${count} ${noun} · ${notConfirmed} checks not confirmed`;
120
- if ((details.incompleteFiles ?? 0) > 0)
121
- return `lens_diagnostics${scope} — incomplete (${details.incompleteFiles} files not confirmed)`;
122
- if (count === 0 && details.unconfirmed)
123
- return details.timedOut ? `lens_diagnostics${scope} — timed out (result may be incomplete)` : `lens_diagnostics${scope} — unconfirmed (server cannot confirm clean)`;
124
- return `lens_diagnostics${scope} — ${count} ${noun}`;
125
- }
126
- const scanning = scanningSummaryLine(details, text);
127
- if (scanning)
128
- return scanning;
129
- const mode = details?.mode ?? (typeof args.mode === "string" ? args.mode : "delta");
130
- if (isError) {
131
- return `lens_diagnostics ${mode} — ${text.split(`
132
- `)[0] ?? "error"}`;
133
- }
134
- const coldSuffix = details?.coldRunners && details.coldRunners.length > 0 ? ` (${details.coldRunners.length} cold: ${details.coldRunners.join(", ")})` : "";
135
- const failedSuffix = details?.failedAnalyzers && details.failedAnalyzers.length > 0 ? ` (${details.failedAnalyzers.length} failed: ${details.failedAnalyzers.map((item) => item.id).join(", ")})` : "";
136
- if (mode === "delta") {
137
- const aw = details?.actionableWarnings ?? 0;
138
- const cq = details?.qualityIssues ?? 0;
139
- const pd = details?.projectDiagnostics ?? 0;
140
- if (aw + cq + pd === 0)
141
- return `lens_diagnostics delta — clean${coldSuffix}${failedSuffix}`;
142
- return `lens_diagnostics delta — ${aw} actionable · ${cq} quality · ${pd} project${coldSuffix}${failedSuffix}`;
143
- }
144
- const b = details?.totalBlocking ?? 0;
145
- const e = details?.totalErrors ?? 0;
146
- const w = details?.totalWarnings ?? 0;
147
- const adv = details?.totalAdvisories ?? 0;
148
- const files = details?.filesWithIssues ?? details?.filesChecked ?? 0;
149
- if (b + e + w === 0) {
150
- const advisorySuffix = adv > 0 ? `, ${adv} hint${adv === 1 ? "" : "s"}` : "";
151
- return `lens_diagnostics ${mode} — clean${advisorySuffix} (${files} files)${coldSuffix}${failedSuffix}`;
152
- }
153
- const parts = [`${b} blocking`];
154
- if (b === 0 && e > 0)
155
- parts.push(`${e} errors`);
156
- parts.push(`${w} warnings`);
157
- return `lens_diagnostics ${mode} — ${parts.join(" · ")} (${files} files)${coldSuffix}${failedSuffix}`;
158
- }),
159
- parameters: Type.Object({
160
- source: Type.Optional(Type.String({
161
- enum: ["session", "lsp"],
162
- description: "Evidence source: session cache (empty cache is not proof of a " + "clean file — use source=lsp for changed files) or an active LSP probe."
163
- })),
164
- scope: Type.Optional(Type.String({
165
- enum: ["paths", "workspace"],
166
- description: "Coverage scope: explicit paths, or workspace (default: current turn's delta for source=session)."
167
- })),
168
- mode: Type.Optional(Type.String({
169
- enum: ["delta", "all", "full"],
170
- description: "delta = current turn; all = cache-only; full = active LSP scan of paths. Empty cache is not proof of clean."
171
- })),
172
- path: Type.Optional(Type.String({
173
- description: "One file or directory for source=lsp checks."
174
- })),
175
- concurrency: Type.Optional(Type.Number({
176
- description: "Source=lsp batch concurrency (maximum 16)."
177
- })),
178
- waitMs: Type.Optional(Type.Number({
179
- description: "Source=lsp per-file wait budget in milliseconds."
180
- })),
181
- serverScope: Type.Optional(Type.String({
182
- enum: ["primary", "all"],
183
- description: "Source=lsp server coverage: primary or all."
184
- })),
185
- refreshRunners: Type.Optional(Type.Union([
186
- Type.Boolean(),
187
- Type.String({ enum: ["cached", "cheap", "all", "none"] })
188
- ], {
189
- description: "Analyzer refresh mode for full view."
190
- })),
191
- maxProjectFiles: Type.Optional(Type.Number({
192
- description: "Project-file limit for cheap runners."
193
- })),
194
- maxLspFiles: Type.Optional(Type.Number({
195
- description: "File limit for the LSP sweep."
196
- })),
197
- includeGenerated: Type.Optional(Type.Boolean({
198
- description: "Include generated-name paths in full scans."
199
- })),
200
- analysisRoot: Type.Optional(Type.String({
201
- description: "Explicit project directory for heavyweight analyzers; it must exist and resolve strictly below the home directory."
202
- })),
203
- severity: Type.Optional(Type.String({
204
- enum: [...LSP_SEVERITY_FILTERS],
205
- description: "Filter by severity threshold (default: all): error shows errors; warning includes errors and warnings; information includes errors, warnings, and information; hint and all show every known tier."
206
- })),
207
- paths: Type.Optional(Type.Array(Type.String(), {
208
- maxItems: MAX_PATHS_ENTRIES,
209
- description: "Files or directories to filter."
210
- }))
211
- }),
212
- async execute(_toolCallId, params, signal, onUpdate, ctx) {
213
- const requestedSource = params.source;
214
- const requestedScope = params.scope;
215
- const legacyMode = params.mode;
216
- const source = requestedSource ?? "session";
217
- const scope = requestedScope ?? (legacyMode === "delta" || legacyMode === undefined ? source === "lsp" ? "paths" : "delta" : "workspace");
218
- const cwd = ctx.cwd ?? getCwd();
219
- if (source === "lsp") {
220
- const lspParams = { ...params };
221
- delete lspParams.source;
222
- delete lspParams.scope;
223
- const hasExplicitPath = typeof lspParams.path === "string" && lspParams.path.length > 0;
224
- const hasExplicitPaths = Array.isArray(lspParams.paths) && lspParams.paths.length > 0;
225
- if (scope === "workspace" && !hasExplicitPath && !hasExplicitPaths) {
226
- lspParams.path = cwd;
227
- }
228
- const lspStart = Date.now();
229
- const result = await lspProbe.execute(_toolCallId, lspParams, signal, onUpdate, ctx.signal ? { cwd, signal: ctx.signal } : { cwd });
230
- logLatency({
231
- type: "phase",
232
- toolName: "lens_diagnostics",
233
- filePath: cwd,
234
- phase: "lens_diagnostics_lsp_route",
235
- durationMs: Date.now() - lspStart,
236
- metadata: {
237
- scope,
238
- isError: result.isError === true,
239
- totalDiagnostics: result.details?.totalDiagnostics ?? 0,
240
- cleanFiles: result.details?.cleanFiles ?? 0,
241
- unconfirmedFiles: result.details?.unconfirmedFiles ?? 0,
242
- timedOutFiles: result.details?.timedOutFiles ?? 0
243
- }
244
- });
245
- return {
246
- ...result,
247
- isError: result.isError === true,
248
- details: { ...result.details, source, scope }
249
- };
250
- }
251
- if (requestedSource !== undefined) {
252
- const effectiveMode = legacyMode ?? (scope === "workspace" ? "all" : scope === "paths" ? "all" : "delta");
253
- params = { ...params, mode: effectiveMode };
254
- }
255
- const repaintLspStatus = captureLspStatusRepaint?.(ctx);
256
- const mode = params.mode ?? "delta";
257
- const severity = params.severity ?? "all";
258
- const refreshRunners = params.refreshRunners;
259
- const parsePositiveInt = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : undefined;
260
- const maxProjectFiles = parsePositiveInt(params.maxProjectFiles);
261
- const maxLspFiles = parsePositiveInt(params.maxLspFiles);
262
- const includeGenerated = params.includeGenerated === true;
263
- let pathsScope;
264
- try {
265
- pathsScope = resolvePathsScope(cwd, params.paths);
266
- } catch (err) {
267
- return {
268
- content: [
269
- {
270
- type: "text",
271
- text: err instanceof Error ? err.message : String(err)
272
- }
273
- ],
274
- isError: true,
275
- details: { mode, pathsError: true }
276
- };
277
- }
278
- const abortSignal = combineAbortSignals(signal, ctx.signal);
279
- await flushPending();
280
- const staleDropped = await reconcileStaleWidgetFiles();
281
- if (mode === "all") {
282
- const dependencyGateStart = Date.now();
283
- const { demoted: dependencyDemoted, truncatedImports } = await reconcileStaleWidgetDependencyBlockers(cwd, getRuntime?.()?.turnIndex);
284
- logLatency({
285
- type: "phase",
286
- toolName: "lens_diagnostics",
287
- filePath: cwd,
288
- phase: "blocker_freshness_widget_gate",
289
- durationMs: Date.now() - dependencyGateStart,
290
- metadata: {
291
- demoted: dependencyDemoted,
292
- truncatedImports,
293
- surface: "mode=all"
294
- }
295
- });
296
- return formatAllMode(cwd, severity, undefined, undefined, staleDropped, pathsScope, dependencyDemoted);
297
- }
298
- if (mode === "full") {
299
- const ceiling = AbortSignal.timeout(FULL_SCAN_WALL_CLOCK_MS);
300
- const fullSignal = combineAbortSignals(abortSignal, ceiling);
301
- const onProgress = makeProgressReporter(onUpdate);
302
- return formatFullMode(cwd, severity, getLspService(), cacheManager, {
303
- refreshRunners,
304
- maxProjectFiles,
305
- maxLspFiles,
306
- includeGenerated,
307
- signal: fullSignal,
308
- wallClockMs: FULL_SCAN_WALL_CLOCK_MS,
309
- onProgress,
310
- onServerReady: repaintLspStatus,
311
- pathsScope,
312
- nextWriteIndex,
313
- runtime: getRuntime?.(),
314
- analysisRoot: typeof params.analysisRoot === "string" ? params.analysisRoot : undefined,
315
- host: ctx.host ?? "pi"
316
- });
317
- }
318
- return formatDeltaMode(cacheManager, cwd, severity, pathsScope);
319
- }
320
- };
321
- }
322
- function formatProjectDeltaDiagnostic(diagnostic, stale) {
323
- const marker = stale ? "○" : diagnostic.semantic === "blocking" || diagnostic.severity === "error" ? "\uD83D\uDD34" : "ℹ";
324
- const rule = diagnostic.rule ?? diagnostic.code ?? diagnostic.runner;
325
- const where = stale ? STALE_LINE_MARKER : `L${diagnostic.line ?? "?"}`;
326
- return ` ${marker} ${where} ${rule} ${diagnostic.message}`;
327
- }
328
- function appendProjectDiagnosticsDeltaLines(groups, cwd, report, severity, includeFile) {
329
- const scoped = (report?.diagnostics ?? []).filter((diagnostic) => includeFile(diagnostic.filePath) && matchesSeverity(projectDiagnosticToWidget(diagnostic, diagnostic.filePath), severity));
330
- const { "lens-diagnostics-delta-project": gated } = gateFindingsByPathFreshness({
331
- cwd,
332
- sources: {
333
- "lens-diagnostics-delta-project": {
334
- findings: scoped,
335
- scannedAt: report?.generatedAt,
336
- citedPath: (d) => d.filePath,
337
- onMissing: "drop"
338
- }
339
- }
340
- });
341
- const staleSet = new Set(gated.stale);
342
- const diagnostics = [...gated.live, ...gated.stale];
343
- const byFile = new Map;
344
- for (const diagnostic of diagnostics) {
345
- const filePath = path.resolve(diagnostic.filePath);
346
- const bucket = byFile.get(filePath) ?? [];
347
- bucket.push(diagnostic);
348
- byFile.set(filePath, bucket);
349
- }
350
- for (const [filePath, fileDiagnostics] of byFile) {
351
- const group = getDeltaFileGroup(groups, cwd, filePath);
352
- for (const diagnostic of fileDiagnostics) {
353
- group.projectLines.push(formatProjectDeltaDiagnostic(diagnostic, staleSet.has(diagnostic)));
354
- }
355
- }
356
- return diagnostics.length;
357
- }
358
- export const CACHED_CONTENT_MEMO_CAP = 64;
359
- const cachedContentMemo = new BoundedLruCache(CACHED_CONTENT_MEMO_CAP);
360
- function readContentForAnchors(filePath, stat) {
361
- const key = normalizeEphemeralMapKey(filePath);
362
- const hit = cachedContentMemo.get(key);
363
- if (hit && hit.mtimeMs === stat.mtimeMs && hit.size === stat.size) {
364
- return hit.content;
365
- }
366
- let content;
367
- try {
368
- content = fsSync.readFileSync(filePath, "utf-8");
369
- } catch {
370
- return;
371
- }
372
- cachedContentMemo.set(key, {
373
- mtimeMs: stat.mtimeMs,
374
- size: stat.size,
375
- content
376
- });
377
- return content;
378
- }
379
- export function _readContentForAnchorsForTests(filePath, stat) {
380
- return readContentForAnchors(filePath, stat);
381
- }
382
- function applyCachedDispositions(cachedDiagnostics, cwd, filePath) {
383
- if (!hasAnyDispositionMarks(cwd))
384
- return cachedDiagnostics;
385
- if (!hasStrictDispositionMarks(cwd)) {
386
- return applyWeakDispositions(cachedDiagnostics, cwd, filePath);
387
- }
388
- let stat;
389
- try {
390
- stat = fsSync.statSync(filePath);
391
- } catch {
392
- return applyWeakDispositions(cachedDiagnostics, cwd, filePath);
393
- }
394
- const referenceMs = cachedDiagnostics.reduce((latest, d) => Math.max(latest, d.observedAt ?? 0), 0);
395
- if (referenceMs > 0 && freshnessFromMtime({ mtimeMs: stat.mtimeMs, referenceMs }).verdict === "stale") {
396
- return applyWeakDispositions(cachedDiagnostics, cwd, filePath);
397
- }
398
- const content = readContentForAnchors(filePath, stat);
399
- if (content === undefined) {
400
- return applyWeakDispositions(cachedDiagnostics, cwd, filePath);
401
- }
402
- return applyDispositions(cachedDiagnostics, cwd, filePath, content);
403
- }
404
- function filterDeltaReportDispositions(report, cwd, policyMap) {
405
- if (!report?.diagnostics.length)
406
- return report;
407
- const kept = report.diagnostics.filter((d) => applyCachedDispositions([projectDiagnosticToWidget(d, d.filePath)], cwd, d.filePath).length === 1);
408
- const policyKept = applyRulePolicy(kept, policyMap);
409
- if (policyKept.length === report.diagnostics.length)
410
- return report;
411
- return { ...report, diagnostics: policyKept };
412
- }
413
- function applyDeltaFreshnessGate(files, cwd, generatedAt) {
414
- const stamps = new Set(files.map((file) => file.generatedAt ?? generatedAt ?? ""));
415
- if (stamps.size > 1) {
416
- const gatedByPath = new Map;
417
- for (const stamp of stamps) {
418
- const group = files.filter((file) => (file.generatedAt ?? generatedAt ?? "") === stamp);
419
- for (const gated of applyDeltaFreshnessGate(group.map((file) => ({
420
- filePath: file.filePath,
421
- warnings: file.warnings
422
- })), cwd, stamp === "" ? undefined : stamp)) {
423
- gatedByPath.set(gated.filePath, gated);
424
- }
425
- }
426
- return files.map((file) => gatedByPath.get(file.filePath)).filter((entry) => entry !== undefined);
427
- }
428
- const stampedAt = [...stamps][0];
429
- const effectiveAt = stampedAt !== undefined && stampedAt !== "" ? stampedAt : generatedAt;
430
- if (!effectiveAt)
431
- return files;
432
- const flat = [];
433
- for (const file of files) {
434
- for (const warning of file.warnings)
435
- flat.push({ filePath: file.filePath, warning });
436
- }
437
- if (flat.length === 0)
438
- return files;
439
- const { "lens-diagnostics-delta": gated } = gateFindingsByPathFreshness({
440
- cwd,
441
- sources: {
442
- "lens-diagnostics-delta": {
443
- findings: flat,
444
- scannedAt: effectiveAt,
445
- citedPath: (f) => f.filePath,
446
- onMissing: "drop"
447
- }
448
- }
449
- });
450
- const byFile = new Map;
451
- for (const f of gated.live) {
452
- const arr = byFile.get(f.filePath) ?? [];
453
- arr.push(f.warning);
454
- byFile.set(f.filePath, arr);
455
- }
456
- for (const f of gated.stale) {
457
- const arr = byFile.get(f.filePath) ?? [];
458
- arr.push({
459
- ...f.warning,
460
- stale: true,
461
- line: undefined,
462
- staleAsOf: effectiveAt
463
- });
464
- byFile.set(f.filePath, arr);
465
- }
466
- return files.map((file) => ({
467
- filePath: file.filePath,
468
- warnings: byFile.get(file.filePath) ?? []
469
- })).filter((file) => file.warnings.length > 0);
470
- }
471
- function getDeltaFileGroup(groups, cwd, filePath) {
472
- const rel = path.relative(cwd, filePath);
473
- let group = groups.get(rel);
474
- if (!group) {
475
- group = {
476
- rel,
477
- actionableLines: [],
478
- qualityLines: [],
479
- projectLines: [],
480
- incomplete: false
481
- };
482
- groups.set(rel, group);
483
- }
484
- return group;
485
- }
486
- function formatDeltaMode(cacheManager, cwd, severity, pathsScope) {
487
- const actionableEntry = cacheManager.readCache("actionable-warnings", cwd);
488
- const qualityEntry = cacheManager.readCache("code-quality-warnings", cwd);
489
- const reverifyIncompletePaths = new Set((actionableEntry?.data?.files ?? []).filter((file) => file.reVerifyIncomplete).map((file) => normalizeMapKey(file.filePath)));
490
- const actionable = actionableEntry?.data;
491
- const quality = qualityEntry?.data;
492
- const policyMap = loadProjectRulePolicyMap(cwd);
493
- const projectDelta = filterDeltaReportDispositions(loadProjectDiagnosticsDeltaReport(cwd), cwd, policyMap);
494
- const includeFile = createScopedFileFilter(cwd, pathsScope);
495
- const visibleWarningFiles = (files) => (files ?? []).filter((file) => includeFile(file.filePath)).map((file) => ({
496
- filePath: file.filePath,
497
- generatedAt: file.generatedAt,
498
- warnings: applyRulePolicy(applyCachedDispositions(file.warnings ?? [], cwd, file.filePath), policyMap)
499
- })).filter((file) => file.warnings.length > 0);
500
- const actionableFiles = applyDeltaFreshnessGate(visibleWarningFiles(actionable?.files), cwd, actionable?.generatedAt);
501
- const qualityFiles = applyDeltaFreshnessGate(visibleWarningFiles(quality?.files), cwd, quality?.generatedAt);
502
- const matchingWarnings = (warnings) => warnings.filter((warning) => matchesRecordSeverity(warning.severity, severity));
503
- const filteredActionableFiles = actionableFiles.map((file) => ({
504
- ...file,
505
- warnings: matchingWarnings(file.warnings)
506
- })).filter((file) => file.warnings.length > 0);
507
- const filteredQualityFiles = qualityFiles.map((file) => ({
508
- ...file,
509
- warnings: matchingWarnings(file.warnings)
510
- })).filter((file) => file.warnings.length > 0);
511
- const groups = new Map;
512
- if (filteredActionableFiles.length > 0) {
513
- for (const file of filteredActionableFiles) {
514
- const group = getDeltaFileGroup(groups, cwd, file.filePath);
515
- for (const w of file.warnings) {
516
- const where = w.stale ? STALE_LINE_MARKER : `L${w.line ?? "?"}`;
517
- group.actionableLines.push(` ⚠ ${where} ${w.rule ?? w.code ?? w.tool} ${w.message}`);
518
- }
519
- const key = normalizeMapKey(file.filePath);
520
- if (reverifyIncompletePaths.has(key))
521
- group.incomplete = true;
522
- if (!group.staleRow) {
523
- const staleWarning = file.warnings.find((w) => w.stale);
524
- if (staleWarning)
525
- group.staleRow = { staleAsOf: staleWarning.staleAsOf };
526
- }
527
- }
528
- }
529
- if (filteredQualityFiles.length > 0) {
530
- for (const file of filteredQualityFiles) {
531
- const group = getDeltaFileGroup(groups, cwd, file.filePath);
532
- for (const w of file.warnings) {
533
- const where = w.stale ? STALE_LINE_MARKER : `L${w.line ?? "?"}`;
534
- group.qualityLines.push(` ℹ ${where} ${w.rule ?? w.code ?? w.tool} ${w.message}`);
535
- }
536
- const key = normalizeMapKey(file.filePath);
537
- if (reverifyIncompletePaths.has(key))
538
- group.incomplete = true;
539
- if (!group.staleRow) {
540
- const staleWarning = file.warnings.find((w) => w.stale);
541
- if (staleWarning)
542
- group.staleRow = { staleAsOf: staleWarning.staleAsOf };
543
- }
544
- }
545
- }
546
- const projectDeltaCount = appendProjectDiagnosticsDeltaLines(groups, cwd, projectDelta, severity, includeFile);
547
- const lines = [];
548
- for (const group of groups.values()) {
549
- lines.push(group.rel);
550
- lines.push(...group.actionableLines);
551
- lines.push(...group.qualityLines);
552
- lines.push(...group.projectLines);
553
- if (group.staleRow) {
554
- lines.push(` (${formatCacheAgeLabel(group.staleRow.staleAsOf)})`);
555
- }
556
- if (group.incomplete)
557
- lines.push(" (re-verify incomplete)");
558
- }
559
- const selectedActionableFiles = filteredActionableFiles;
560
- const selectedQualityFiles = filteredQualityFiles;
561
- const aw = selectedActionableFiles.reduce((count, file) => count + file.warnings.length, 0);
562
- const cq = selectedQualityFiles.reduce((count, file) => count + file.warnings.length, 0);
563
- if (lines.length === 0) {
564
- let text = `No ${severity === "all" ? "" : severity + " "}issues in the current turn delta.`;
565
- const carried = getFileDiagnosticSummaries().filter((f) => includeFile(f.filePath)).map((f) => ({
566
- ...f,
567
- diagnostics: applyRulePolicy(applyCachedDispositions(f.diagnostics, cwd, f.filePath), policyMap)
568
- })).filter((f) => f.diagnostics.length > 0);
569
- const carriedIssues = carried.reduce((n, f) => n + f.diagnostics.length, 0);
570
- if (carried.length > 0) {
571
- text += ` ${carriedIssues} finding${carriedIssues === 1 ? "" : "s"} across ${carried.length} file${carried.length === 1 ? "" : "s"} carried over from earlier this session — use mode=all to see them.`;
572
- }
573
- text += pathsScopeCacheOnlyNote(pathsScope);
574
- return {
575
- content: [{ type: "text", text }],
576
- details: { mode: "delta", warnings: 0, carriedOverFiles: carried.length }
577
- };
578
- }
579
- const summary = `
580
- Summary (turn delta): ${aw} actionable warning${aw === 1 ? "" : "s"} · ${cq} quality issue${cq === 1 ? "" : "s"} · ${projectDeltaCount} project diagnostic${projectDeltaCount === 1 ? "" : "s"}`;
581
- return {
582
- content: [{ type: "text", text: lines.join(`
583
- `) + summary }],
584
- details: {
585
- mode: "delta",
586
- actionableWarnings: aw,
587
- qualityIssues: cq,
588
- projectDiagnostics: projectDeltaCount
589
- }
590
- };
591
- }
592
- function createCurrentIgnoreFilter(cwd) {
593
- try {
594
- const matcher = getProjectIgnoreMatcher(cwd);
595
- return (filePath) => !matcher.isIgnored(path.resolve(filePath), false);
596
- } catch {
597
- return () => true;
598
- }
599
- }
600
- function resolvePathsScope(cwd, rawPaths) {
601
- if (!Array.isArray(rawPaths) || rawPaths.length === 0)
602
- return;
603
- if (rawPaths.length > MAX_PATHS_ENTRIES) {
604
- throw new Error(`paths has ${rawPaths.length} entries, over the ${MAX_PATHS_ENTRIES} cap. ` + "Narrow the list or omit paths to scan without a restriction.");
605
- }
606
- const entries = rawPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0).map((entry) => path.resolve(path.isAbsolute(entry) ? entry : path.resolve(cwd, entry)));
607
- const missing = [];
608
- const fileEntries = [];
609
- const existingEntries = [];
610
- const dirEntries = [];
611
- for (const entry of entries) {
612
- let stat;
613
- try {
614
- stat = fsSync.statSync(entry);
615
- } catch {
616
- missing.push(entry);
617
- fileEntries.push(entry);
618
- continue;
619
- }
620
- if (stat.isDirectory()) {
621
- dirEntries.push(entry);
622
- } else {
623
- fileEntries.push(entry);
624
- existingEntries.push(entry);
625
- }
626
- }
627
- const fileKeys = new Set(fileEntries.map((f) => normalizeFilePath(f)));
628
- const dirPrefixes = dirEntries.map((d) => normalizeFilePath(d));
629
- const includeExplicitFile = (filePath) => fileKeys.has(normalizeFilePath(path.resolve(filePath)));
630
- const includeFile = (filePath) => {
631
- const key = normalizeFilePath(path.resolve(filePath));
632
- if (fileKeys.has(key))
633
- return true;
634
- return dirPrefixes.some((prefix) => key === prefix || key.startsWith(`${prefix}/`));
635
- };
636
- return {
637
- includeFile,
638
- includeExplicitFile,
639
- missing,
640
- existingEntries,
641
- hasDirectoryEntries: dirEntries.length > 0
642
- };
643
- }
644
- function pathsScopeCacheOnlyNote(scope) {
645
- if (!scope)
646
- return "";
647
- return `
648
-
649
- Note: paths restricts this to cached findings for files dm-lens has ` + "already dispatched this session — mode=delta/all can't see files it " + "hasn't touched. Use mode=full to actively scan exactly these paths.";
650
- }
651
- function pathsScopeMissingNote(scope) {
652
- if (!scope || scope.missing.length === 0)
653
- return "";
654
- const shown = scope.missing.slice(0, 10).map((p) => path.basename(p));
655
- const more = scope.missing.length > shown.length ? ` (+${scope.missing.length - shown.length} more)` : "";
656
- return `
657
-
658
- ⚠ Skipped ${scope.missing.length} path(s) not found on disk: ${shown.join(", ")}${more}`;
659
- }
660
- function createScopedFileFilter(cwd, pathsScope) {
661
- const ignoreFile = createCurrentIgnoreFilter(cwd);
662
- return (filePath) => {
663
- if (!pathsScope)
664
- return ignoreFile(filePath);
665
- if (!pathsScope.includeFile(filePath))
666
- return false;
667
- return pathsScope.includeExplicitFile(filePath) || ignoreFile(filePath);
668
- };
669
- }
670
- function filterProjectDiagnosticsSnapshot(snapshot, includeFile) {
671
- if (!snapshot)
672
- return;
673
- return {
674
- ...snapshot,
675
- diagnostics: snapshot.diagnostics.filter((d) => includeFile(d.filePath))
676
- };
677
- }
678
- function filterProjectDiagnosticsDeltaReport(report, includeFile) {
679
- if (!report)
680
- return;
681
- return {
682
- ...report,
683
- diagnostics: report.diagnostics.filter((d) => includeFile(d.filePath))
684
- };
685
- }
686
- function applyProjectRulePolicy(value, policyMap) {
687
- if (!value)
688
- return;
689
- return {
690
- ...value,
691
- diagnostics: applyRulePolicy(value.diagnostics, policyMap)
692
- };
693
- }
694
- function isErrorLike(d) {
695
- if (d.stale)
696
- return false;
697
- return d.semantic === "blocking" || d.severity === "error";
698
- }
699
- function matchesSeverity(d, severity) {
700
- return matchesRecordSeverity(isErrorLike(d) ? "error" : d.severity, severity);
701
- }
702
- function matchesRecordSeverity(recordSeverity, requested) {
703
- if (requested === "all")
704
- return true;
705
- if (requested === "error")
706
- return recordSeverity === "error";
707
- if (requested === "warning")
708
- return recordSeverity === "error" || recordSeverity === "warning";
709
- if (requested === "information")
710
- return recordSeverity === "error" || recordSeverity === "warning" || recordSeverity === "info" || recordSeverity === "note" || recordSeverity === "help";
711
- if (requested === "hint")
712
- return recordSeverity === "error" || recordSeverity === "warning" || recordSeverity === "info" || recordSeverity === "note" || recordSeverity === "help" || recordSeverity === "hint";
713
- return true;
714
- }
715
- function severityRank(d) {
716
- if (d.semantic === "blocking")
717
- return 0;
718
- if (d.severity === "error")
719
- return 1;
720
- if (d.severity === "warning")
721
- return 2;
722
- return 3;
723
- }
724
- function bySeverityThenLine(a, b) {
725
- return severityRank(a) - severityRank(b) || (a.line ?? 0) - (b.line ?? 0);
726
- }
727
- function lspSeverityName(severity) {
728
- if (severity === 1)
729
- return "error";
730
- if (severity === 2)
731
- return "warning";
732
- if (severity === 3)
733
- return "info";
734
- return "hint";
735
- }
736
- function lspRuleId(diagnostic) {
737
- const code = diagnostic.code === undefined ? undefined : String(diagnostic.code);
738
- if (diagnostic.source && code)
739
- return `${diagnostic.source}:${code}`;
740
- return diagnostic.source ?? code ?? "lsp";
741
- }
742
- function lspDiagnosticToWidget(diagnostic) {
743
- const severity = lspSeverityName(diagnostic.severity);
744
- const rule = lspRuleId(diagnostic);
745
- return {
746
- severity,
747
- semantic: diagnostic.severity === 1 ? "blocking" : "warning",
748
- message: diagnostic.message,
749
- line: diagnostic.range.start.line + 1,
750
- col: diagnostic.range.start.character + 1,
751
- rule,
752
- tool: findAuxiliaryProfileForSource(diagnostic.source)?.tool ?? "lsp"
753
- };
754
- }
755
- function projectDiagnosticToWidget(diagnostic, filePath) {
756
- return {
757
- severity: diagnostic.severity,
758
- semantic: diagnostic.semantic,
759
- message: diagnostic.message,
760
- line: diagnostic.line,
761
- col: diagnostic.column,
762
- rule: diagnostic.rule ?? diagnostic.code,
763
- tool: diagnostic.runner || diagnostic.tool,
764
- uri: widgetDiagnosticUri(filePath, diagnostic.line, diagnostic.column)
765
- };
766
- }
767
- function diagnosticDedupKey(filePath, diagnostic) {
768
- const ruleId = normalizeRuleId(diagnostic.rule ?? diagnostic.tool ?? "");
769
- return [path.resolve(filePath), diagnostic.line ?? "?", ruleId].join(":");
770
- }
771
- function runnerIdOf(diagnostic) {
772
- return diagnostic.tool ?? diagnostic.rule?.split(":", 1)[0] ?? "";
773
- }
774
- export function runnerRetirementDecision(diagnostic, filePath, authoritativeRunnerIds, authoritativeCoverage) {
775
- const runnerId = runnerIdOf(diagnostic);
776
- const coverage = (authoritativeCoverage ?? []).filter((entry) => entry.runnerId === runnerId);
777
- if (coverage.length === 0) {
778
- return authoritativeRunnerIds?.has(runnerId) ? "retire" : "keep";
779
- }
780
- const realFilePath = realpathOrResolve(filePath);
781
- for (const entry of coverage) {
782
- const root = entry.root;
783
- const relative = path.relative(root, realFilePath);
784
- const underRoot = relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative);
785
- if (!underRoot)
786
- continue;
787
- if (entry.files.has(realFilePath)) {
788
- return "retire";
789
- }
790
- }
791
- return "keep";
792
- }
793
- function summarizeDiagnostics(filePath, diagnostics, hasFinalSnapshot) {
794
- let blocking = 0;
795
- let errors = 0;
796
- let warnings = 0;
797
- let advisories = 0;
798
- for (const diagnostic of diagnostics) {
799
- if (diagnostic.stale)
800
- continue;
801
- if (diagnostic.semantic === "blocking")
802
- blocking++;
803
- const tier = classifyDiagnosticTier(diagnostic);
804
- if (tier === "error")
805
- errors++;
806
- else if (tier === "warning")
807
- warnings++;
808
- else if (tier === "advisory")
809
- advisories++;
810
- }
811
- return {
812
- filePath,
813
- blocking,
814
- errors,
815
- warnings,
816
- advisories,
817
- hasFinalSnapshot,
818
- diagnostics
819
- };
820
- }
821
- const UNCONFIRMED_REASON_SENTENCE = {
822
- budget: "check didn't complete within budget",
823
- inconclusive: "check was inconclusive (notify-write or diagnostics wait timed out)",
824
- coverage_gap: "an auxiliary scanner coverage gap",
825
- service_destroyed: "the LSP service was reset mid-sweep",
826
- error: "check errored",
827
- binding_mismatch: "the file changed on disk since this result was computed",
828
- outside_project_root: "the file is outside every initialized session project root, so no language server was asked"
829
- };
830
- const UNCONFIRMED_REASON_COUNT_LABEL = {
831
- budget: "timed out",
832
- inconclusive: "inconclusive",
833
- coverage_gap: "coverage gap",
834
- service_destroyed: "service reset mid-sweep",
835
- error: "errored",
836
- binding_mismatch: "stale binding",
837
- outside_project_root: "outside project root"
838
- };
839
- function classifyUnconfirmedReason(result, mismatched) {
840
- if (mismatched.has(result))
841
- return "binding_mismatch";
842
- return result.unconfirmedReason ?? (result.error ? "error" : "budget");
843
- }
844
- function tallyUnconfirmedReasons(results, mismatched) {
845
- const tally = new Map;
846
- for (const result of results) {
847
- const reason = classifyUnconfirmedReason(result, mismatched);
848
- tally.set(reason, (tally.get(reason) ?? 0) + 1);
849
- }
850
- return tally;
851
- }
852
- function formatUnconfirmedReasonClause(tally) {
853
- const entries = [...tally.entries()].filter(([, count]) => count > 0);
854
- if (entries.length === 0)
855
- return "";
856
- if (entries.length === 1) {
857
- return UNCONFIRMED_REASON_SENTENCE[entries[0][0]];
858
- }
859
- return entries.map(([reason, count]) => `${count} ${UNCONFIRMED_REASON_COUNT_LABEL[reason]}`).join(", ");
860
- }
861
- function tallyLspByPrimaryServer(confirmed, unconfirmed) {
862
- const byServer = new Map;
863
- const bump = (filePath, wasConfirmed) => {
864
- const id = primaryServerId(filePath) ?? "unknown";
865
- const entry = byServer.get(id) ?? { confirmed: 0, total: 0 };
866
- entry.total += 1;
867
- if (wasConfirmed)
868
- entry.confirmed += 1;
869
- byServer.set(id, entry);
870
- };
871
- for (const result of confirmed)
872
- bump(result.filePath, true);
873
- for (const result of unconfirmed)
874
- bump(result.filePath, false);
875
- return byServer;
876
- }
877
- function formatLspServerBreakdown(byServer) {
878
- return [...byServer.entries()].sort((a, b) => {
879
- const rateA = a[1].confirmed / a[1].total;
880
- const rateB = b[1].confirmed / b[1].total;
881
- return rateA - rateB;
882
- }).map(([id, { confirmed, total }]) => `${id}: ${confirmed}/${total}`).join(", ");
883
- }
884
- function tallyLspPrimaryVsAuxiliary(results) {
885
- let primary = 0;
886
- let auxiliary = 0;
887
- for (const result of results) {
888
- const primaryId = primaryServerId(result.filePath);
889
- for (const diagnostic of result.diagnostics ?? []) {
890
- if (diagnostic.serverId === primaryId)
891
- primary += 1;
892
- else
893
- auxiliary += 1;
894
- }
895
- }
896
- return { primary, auxiliary };
897
- }
898
- function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projectSnapshot, projectDelta, authoritativeLspFiles, authoritativeRunnerIds, authoritativeRunnerCoverage) {
899
- const byFile = new Map;
900
- const seen = new Set;
901
- for (const summary of widgetSummaries) {
902
- const filePath = path.resolve(summary.filePath);
903
- if (authoritativeLspFiles?.has(filePath))
904
- continue;
905
- const retained = summary.diagnostics ?? [];
906
- const diagnostics = retained.filter((diagnostic) => runnerRetirementDecision(diagnostic, filePath, authoritativeRunnerIds, authoritativeRunnerCoverage) !== "retire").map((d) => ({ ...d }));
907
- byFile.set(filePath, diagnostics.length === retained.length ? { ...summary, filePath, diagnostics } : summarizeDiagnostics(filePath, diagnostics, summary.hasFinalSnapshot ?? true));
908
- for (const diagnostic of diagnostics) {
909
- seen.add(diagnosticDedupKey(filePath, diagnostic));
910
- }
911
- }
912
- const addDiagnostic = (filePath, widgetDiagnostic) => {
913
- const existing = byFile.get(filePath);
914
- const diagnostics = existing ? [...existing.diagnostics] : [];
915
- const key = diagnosticDedupKey(filePath, widgetDiagnostic);
916
- if (seen.has(key))
917
- return;
918
- seen.add(key);
919
- diagnostics.push(widgetDiagnostic);
920
- byFile.set(filePath, summarizeDiagnostics(filePath, diagnostics, existing?.hasFinalSnapshot ?? true));
921
- };
922
- for (const result of lspResults) {
923
- const filePath = path.resolve(result.filePath);
924
- for (const diagnostic of result.diagnostics ?? []) {
925
- addDiagnostic(filePath, lspDiagnosticToWidget(diagnostic));
926
- }
927
- }
928
- for (const diagnostic of projectSnapshot?.diagnostics ?? []) {
929
- addDiagnostic(path.resolve(diagnostic.filePath), projectDiagnosticToWidget(diagnostic, diagnostic.filePath));
930
- }
931
- for (const diagnostic of projectDelta?.diagnostics ?? []) {
932
- addDiagnostic(path.resolve(diagnostic.filePath), projectDiagnosticToWidget(diagnostic, diagnostic.filePath));
933
- }
934
- return [...byFile.values()];
935
- }
936
- async function applyInlineSuppressionsToSummaries(summaries, cwd, policyMap) {
937
- return Promise.all(summaries.map(async (summary) => {
938
- if (!summary.diagnostics.length)
939
- return summary;
940
- let content;
941
- try {
942
- content = await fs.readFile(summary.filePath, "utf8");
943
- } catch {
944
- const policyKept = applyRulePolicy(summary.diagnostics, policyMap);
945
- return policyKept.length === summary.diagnostics.length ? summary : summarizeDiagnostics(summary.filePath, policyKept, summary.hasFinalSnapshot);
946
- }
947
- const { kept: policyKept } = applyFindingPolicy(summary.diagnostics, {
948
- cwd,
949
- filePath: summary.filePath,
950
- content,
951
- policyMap
952
- });
953
- for (const d of policyKept) {
954
- const { weak } = anchorsForDiagnostic(cwd, summary.filePath, d, content);
955
- if (getDisposition(cwd, weak)?.disposition === "flagged") {
956
- d.flagged = true;
957
- }
958
- }
959
- if (policyKept.length === summary.diagnostics.length)
960
- return summary;
961
- return summarizeDiagnostics(summary.filePath, policyKept, summary.hasFinalSnapshot);
962
- }));
963
- }
964
- function shouldUseCachedProjectDiagnostics(value) {
965
- return value === "cached";
966
- }
967
- function shouldRefreshProjectDiagnostics(value) {
968
- return value === "cheap" || value === "all";
969
- }
970
- function shouldIncludeProjectRunners(value) {
971
- return shouldRefreshProjectDiagnostics(value) || value === "cached";
972
- }
973
- function foldExtraDiagnosticsIntoSnapshot(snapshot, extra, runners, cwd) {
974
- if (extra.length === 0)
975
- return snapshot;
976
- if (snapshot) {
977
- const merged = new Set([...snapshot.runners, ...runners]);
978
- return {
979
- ...snapshot,
980
- diagnostics: [...snapshot.diagnostics, ...extra],
981
- runners: [...merged]
982
- };
983
- }
984
- return {
985
- version: PROJECT_DIAGNOSTICS_CACHE_VERSION,
986
- cwd,
987
- tier: "all",
988
- scannedAt: new Date().toISOString(),
989
- diagnostics: extra,
990
- filesScanned: 0,
991
- runners
992
- };
993
- }
994
- async function getProjectDiagnosticsSnapshotForFullMode(cwd, options) {
995
- if (shouldRefreshProjectDiagnostics(options.refreshRunners)) {
996
- return scanProjectDiagnostics({
997
- cwd,
998
- tier: "cheap",
999
- maxFiles: options.maxProjectFiles,
1000
- signal: options.signal,
1001
- files: options.files,
1002
- includeGenerated: options.includeGenerated
1003
- });
1004
- }
1005
- if (shouldUseCachedProjectDiagnostics(options.refreshRunners)) {
1006
- const cached = loadProjectDiagnosticsSnapshot(cwd);
1007
- if (!cached)
1008
- return;
1009
- const reconciled = reconcileProjectDiagnosticsSnapshot(cached);
1010
- if (reconciled.staleDropped > 0) {
1011
- logLatency({
1012
- type: "phase",
1013
- toolName: "lens_diagnostics",
1014
- filePath: cwd,
1015
- phase: "project_snapshot_rows_retired",
1016
- durationMs: 0,
1017
- metadata: {
1018
- files: reconciled.staleDropped,
1019
- rows: cached.diagnostics.length - reconciled.snapshot.diagnostics.length,
1020
- scannedAt: cached.scannedAt
1021
- }
1022
- });
1023
- }
1024
- return reconciled.snapshot;
1025
- }
1026
- return;
1027
- }
1028
- async function formatFullMode(cwd, severity, lspService, cacheManager, options = {}) {
1029
- const runWorkspaceDiagnostics = lspService.runWorkspaceDiagnostics;
1030
- if (typeof runWorkspaceDiagnostics !== "function") {
1031
- return {
1032
- content: [
1033
- {
1034
- type: "text",
1035
- text: "LSP service does not support project-wide workspace diagnostics."
1036
- }
1037
- ],
1038
- details: { mode: "full", filesChecked: 0, lspUnavailable: true }
1039
- };
1040
- }
1041
- const { signal, pathsScope, nextWriteIndex } = options;
1042
- const host = options.host ?? "pi";
1043
- const includeFile = createScopedFileFilter(cwd, pathsScope);
1044
- const explicitFiles = pathsScope && !pathsScope.hasDirectoryEntries ? pathsScope.existingEntries : undefined;
1045
- const projectRunnersRequested = shouldIncludeProjectRunners(options.refreshRunners);
1046
- const analyzersPromise = projectRunnersRequested ? loadBootstrapClients().then((clients) => fetchFreshProjectDiagnostics(cacheManager, cwd, clients, signal, {
1047
- runtime: options.runtime,
1048
- analysisRoot: options.analysisRoot
1049
- })) : Promise.resolve({
1050
- diagnostics: [],
1051
- runners: [],
1052
- analyzed: [],
1053
- authoritativeCoverage: [],
1054
- cold: [...ANALYZER_IDS],
1055
- coldReasons: Object.fromEntries(ANALYZER_IDS.map((id) => [id, notRequestedReason(host)])),
1056
- failed: [],
1057
- timings: {}
1058
- });
1059
- const [rawLspResults, rawProjectSnapshot, extracted] = await Promise.all([
1060
- runWorkspaceDiagnostics.call(lspService, cwd, {
1061
- maxFiles: options.maxLspFiles,
1062
- signal,
1063
- onProgress: options.onProgress,
1064
- onServerReady: options.onServerReady,
1065
- nextWriteIndex: options.nextWriteIndex,
1066
- files: explicitFiles
1067
- }),
1068
- getProjectDiagnosticsSnapshotForFullMode(cwd, {
1069
- ...options,
1070
- files: explicitFiles
1071
- }),
1072
- analyzersPromise
1073
- ]);
1074
- if (extracted.analysisRootError) {
1075
- return {
1076
- content: [{ type: "text", text: extracted.analysisRootError }],
1077
- isError: true,
1078
- details: {
1079
- mode: "full",
1080
- analysisRootError: extracted.analysisRootError,
1081
- analysisRootValidation: extracted.analysisRootValidation
1082
- }
1083
- };
1084
- }
1085
- const aborted = signal?.aborted ?? false;
1086
- const lspResults = await demoteInferredProjectSweepResults(rawLspResults.filter((result) => includeFile(result.filePath)), cwd, lspService, signal);
1087
- const mismatchedLspResults = await findFullScanBindingMismatches(lspResults);
1088
- const confirmedLspResults = lspResults.filter((result) => !result.timedOut && !result.error && !mismatchedLspResults.has(result));
1089
- const fullyCoveredLspResults = confirmedLspResults.filter((result) => (result.unconfirmedServerIds?.length ?? 0) === 0);
1090
- const partiallyCoveredLspResults = confirmedLspResults.filter((result) => (result.unconfirmedServerIds?.length ?? 0) > 0);
1091
- const unconfirmedLspResults = lspResults.filter((result) => result.timedOut || result.error || mismatchedLspResults.has(result));
1092
- const authoritativeLspFiles = new Set;
1093
- const unreconciledFiles = new Set;
1094
- for (const result of fullyCoveredLspResults) {
1095
- try {
1096
- const diagnostics = convertLspDiagnostics(result.diagnostics, result.filePath, { scanOrigin: "lens_diagnostics_full" });
1097
- const retagged = retagAuxiliaryDiagnostics(diagnostics, result.diagnostics, "", { cwd, fileRole: detectFileRole(result.filePath) });
1098
- const retired = reconcileScanDiagnostics(result.filePath, retagged, true, result.writeIndex ?? nextWriteIndex?.(), result.observedAt);
1099
- if (retired === true) {
1100
- authoritativeLspFiles.add(path.resolve(result.filePath));
1101
- } else {
1102
- unreconciledFiles.add(path.resolve(result.filePath));
1103
- recordDegradationOnce({
1104
- kind: "diagnostic-retained-unreconciled",
1105
- subject: `${path.resolve(result.filePath)}:lsp`,
1106
- reason: "confirmed diagnostic result could not replace retained widget state"
1107
- });
1108
- }
1109
- } catch {
1110
- unreconciledFiles.add(path.resolve(result.filePath));
1111
- recordDegradationOnce({
1112
- kind: "diagnostic-retained-unreconciled",
1113
- subject: `${path.resolve(result.filePath)}:lsp`,
1114
- reason: "confirmed diagnostic result failed during widget reconciliation"
1115
- });
1116
- }
1117
- }
1118
- const policyMap = loadProjectRulePolicyMap(cwd);
1119
- const scannedSnapshot = filterProjectDiagnosticsSnapshot(rawProjectSnapshot, includeFile);
1120
- const authoritativeRunnerIds = new Set(extracted.analyzed ?? []);
1121
- const authoritativeRunnerCoverage = extracted.authoritativeCoverage ?? [];
1122
- const foldedProjectSnapshot = foldExtraDiagnosticsIntoSnapshot(scannedSnapshot, extracted.diagnostics.filter((d) => includeFile(d.filePath)), extracted.runners, cwd);
1123
- const projectSnapshot = applyProjectRulePolicy(foldedProjectSnapshot, policyMap);
1124
- const projectDelta = applyProjectRulePolicy(filterProjectDiagnosticsDeltaReport(loadProjectDiagnosticsDeltaReport(cwd), includeFile), policyMap);
1125
- const authoritativeRetiredCount = getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath) && authoritativeLspFiles.has(path.resolve(summary.filePath)) && (summary.diagnostics?.length ?? 0) > 0).length;
1126
- if (authoritativeRetiredCount > 0) {
1127
- logLatency({
1128
- type: "phase",
1129
- phase: "lsp_authoritative_widget_retire",
1130
- filePath: "",
1131
- durationMs: 0,
1132
- metadata: { files: authoritativeRetiredCount }
1133
- });
1134
- }
1135
- const retiredRunnerCounts = new Map;
1136
- const runnerRetiredRows = getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath)).reduce((total, summary) => total + (summary.diagnostics ?? []).filter((diagnostic) => {
1137
- const retired = runnerRetirementDecision(diagnostic, summary.filePath, authoritativeRunnerIds, authoritativeRunnerCoverage) === "retire";
1138
- if (retired) {
1139
- const runnerId = runnerIdOf(diagnostic);
1140
- retiredRunnerCounts.set(runnerId, (retiredRunnerCounts.get(runnerId) ?? 0) + 1);
1141
- }
1142
- return retired;
1143
- }).length, 0);
1144
- if (runnerRetiredRows > 0) {
1145
- logLatency({
1146
- type: "phase",
1147
- phase: "runner_authoritative_widget_retire",
1148
- filePath: "",
1149
- durationMs: 0,
1150
- metadata: {
1151
- rows: runnerRetiredRows,
1152
- runners: [...retiredRunnerCounts.keys()].join(","),
1153
- coverage: authoritativeRunnerCoverage.map((entry) => ({
1154
- runnerId: entry.runnerId,
1155
- root: entry.root,
1156
- files: entry.files.size
1157
- }))
1158
- }
1159
- });
1160
- }
1161
- for (const entry of authoritativeRunnerCoverage) {
1162
- if (entry.files.size === 0)
1163
- continue;
1164
- if (!claimPhaseOncePerSession("runner_coverage_retired", entry.runnerId)) {
1165
- continue;
1166
- }
1167
- logLatency({
1168
- type: "phase",
1169
- phase: "runner_coverage_retired",
1170
- filePath: "",
1171
- durationMs: 0,
1172
- metadata: {
1173
- runnerId: entry.runnerId,
1174
- count: retiredRunnerCounts.get(entry.runnerId) ?? 0
1175
- }
1176
- });
1177
- }
1178
- let summaries = await applyInlineSuppressionsToSummaries(mergeDiagnosticsWithWidgetSummaries(getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath)), confirmedLspResults, projectSnapshot, projectDelta, authoritativeLspFiles, authoritativeRunnerIds, authoritativeRunnerCoverage), cwd, policyMap);
1179
- if (unreconciledFiles.size > 0) {
1180
- summaries = summaries.map((summary) => unreconciledFiles.has(path.resolve(summary.filePath)) ? summarizeDiagnostics(summary.filePath, markUnreconciledFindings(summary.diagnostics), summary.hasFinalSnapshot) : summary);
1181
- }
1182
- const parsedProjectScanObservedAt = projectSnapshot?.scannedAt ? Date.parse(projectSnapshot.scannedAt) : undefined;
1183
- const projectScanObservedAt = parsedProjectScanObservedAt !== undefined && Number.isFinite(parsedProjectScanObservedAt) ? parsedProjectScanObservedAt : undefined;
1184
- for (const summary of summaries) {
1185
- reconcileCorrelatedScanDiagnostics(summary.filePath, summary.diagnostics, nextWriteIndex?.(), projectScanObservedAt);
1186
- }
1187
- const result = await formatAllMode(cwd, severity, summaries, {
1188
- mode: "full",
1189
- lspFilesChecked: rawLspResults.length,
1190
- partial: aborted,
1191
- projectDiagnostics: projectSnapshot === undefined ? undefined : {
1192
- tier: projectSnapshot.tier,
1193
- filesScanned: projectSnapshot.filesScanned,
1194
- diagnostics: projectSnapshot.diagnostics.length,
1195
- runners: projectSnapshot.runners
1196
- },
1197
- projectDiagnosticsDelta: projectDelta === undefined ? undefined : {
1198
- diagnostics: projectDelta.diagnostics.length,
1199
- sources: projectDelta.sources,
1200
- turnIndex: projectDelta.turnIndex
1201
- }
1202
- }, 0, pathsScope);
1203
- const missingNote = pathsScopeMissingNote(pathsScope);
1204
- const unconfirmedByReason = tallyUnconfirmedReasons(unconfirmedLspResults, mismatchedLspResults);
1205
- const lspServerBreakdown = tallyLspByPrimaryServer(confirmedLspResults, unconfirmedLspResults);
1206
- const serverBreakdownClause = lspServerBreakdown.size > 1 ? ` — by server: ${formatLspServerBreakdown(lspServerBreakdown)}.` : "";
1207
- const unconfirmedLspNote = unconfirmedLspResults.length > 0 ? `
1208
-
1209
- ⚠ LSP sweep: ${confirmedLspResults.length} file(s) confirmed via LSP, ` + `${unconfirmedLspResults.length} unconfirmed (${formatUnconfirmedReasonClause(unconfirmedByReason)})${serverBreakdownClause} — NOT the same as 0 diagnostics for: ${unconfirmedLspResults.slice(0, 20).map((result) => result.filePath).join(", ")}${unconfirmedLspResults.length > 20 ? ", …" : ""}. These files' LSP contribution is excluded from this result; re-run mode=full to retry them (they may still show findings above from cached/project-runner state).` : "";
1210
- const uncoveredScannerIds = [
1211
- ...new Set(partiallyCoveredLspResults.flatMap((result) => result.unconfirmedServerIds ?? []))
1212
- ].sort((a, b) => Number(a > b) - Number(a < b));
1213
- const auxiliaryCoverageNote = uncoveredScannerIds.length > 0 ? `
1214
-
1215
- ⚠ Auxiliary coverage incomplete: ${uncoveredScannerIds.join(", ")} did not answer for ${partiallyCoveredLspResults.length} file(s). Findings from answering servers are included; this is not a clean verdict for the named scanner lane(s).` : "";
1216
- const lspPrimaryVsAuxiliary = tallyLspPrimaryVsAuxiliary(confirmedLspResults);
1217
- logExtension({
1218
- subsystem: "lsp-diagnostics",
1219
- message: "lens_diagnostics verdict",
1220
- metadata: {
1221
- server: [
1222
- ...new Set(confirmedLspResults.map((result) => primaryServerId(result.filePath) ?? "unknown"))
1223
- ].join(","),
1224
- primary: lspPrimaryVsAuxiliary.primary,
1225
- auxiliary: lspPrimaryVsAuxiliary.auxiliary,
1226
- total: lspPrimaryVsAuxiliary.primary + lspPrimaryVsAuxiliary.auxiliary,
1227
- sources: [
1228
- ...new Set(confirmedLspResults.flatMap((result) => (result.diagnostics ?? []).map((diagnostic) => diagnostic.source ?? "unknown")))
1229
- ].slice(0, 5)
1230
- }
1231
- });
1232
- const lspPrimaryVsAuxiliaryNote = lspPrimaryVsAuxiliary.primary + lspPrimaryVsAuxiliary.auxiliary > 0 ? `
1233
-
1234
- LSP sweep findings: ${lspPrimaryVsAuxiliary.primary} primary (language server), ` + `${lspPrimaryVsAuxiliary.auxiliary} auxiliary (ast-grep/opengrep/zizmor/typos/marksman/...).` : "";
1235
- const abortedIds = new Set(extracted.abortedIds ?? []);
1236
- const genuinelyColdIds = extracted.cold.filter((id) => !abortedIds.has(id));
1237
- const partialIds = extracted.partial ?? [];
1238
- const coldNote = extracted.unsafeRoot ? `
1239
-
1240
- heavyweight analyzers skipped: the analysis root resolves at or above the home directory, so a fresh knip/jscpd/madge/gitleaks/govulncheck/trivy/dead-code scan would walk every unrelated tree under it. Supply a project directory below the home ceiling. Absence of their findings is NOT a clean verdict.` : extracted.analysisRootError ? `
1241
-
1242
- heavyweight analyzers skipped: ${extracted.analysisRootError}. Supply an existing project directory below the home ceiling. Absence of their findings is NOT a clean verdict.` : !projectRunnersRequested && genuinelyColdIds.length > 0 ? `
1243
-
1244
- not run this call (quick mode): ${genuinelyColdIds.join(", ")}. ${notRequestedReason(host)}. Absence of their findings is NOT a clean verdict.` : genuinelyColdIds.length > 0 ? `
1245
-
1246
- cold (not applicable / unavailable this run): ${genuinelyColdIds.map((id) => formatNotRunEntry(id, extracted.coldReasons)).join(", ")}. These analyzers have not contributed to this result — absence of their findings is NOT a clean verdict.` : "";
1247
- const partialNote = partialIds.length > 0 ? `
1248
-
1249
- ⚠ partial coverage (findings included): ${partialIds.map((id) => `${id} — ${extracted.partialReasons?.[id] ?? "coverage is incomplete"}`).join(", ")}. Coverage is incomplete, so absence of findings is NOT a clean verdict.` : "";
1250
- const testRunnerEditScopedNote = extracted.runners.includes("test-runner") ? `
1251
-
1252
- test-runner coverage is edit-scoped, NOT a full-project run: its findings only reflect the test file(s) touched by the most recent edit's turn_end fire, not a fresh whole-project test suite run (mode=full never re-runs the suite — see fresh-fetch.ts). Absence of test-runner findings elsewhere in the project is NOT a clean verdict, and presence here does not mean "just checked" — it may be from several turns ago.` : "";
1253
- const failedAnalyzers = extracted.failed ?? [];
1254
- const failedNote = failedAnalyzers.length > 0 ? `
1255
-
1256
- failed (ran, but no trustworthy result): ${failedAnalyzers.map(({ id, summary }) => `${id} — ${summary}`).join(", ")}. These analyzers were not cached and will be retried; absence of their findings is NOT a clean verdict.` : "";
1257
- const dispositionSuppressedByLaneText = Object.entries(extracted.dispositionSuppressedByLane ?? {}).map(([id, count]) => `${id} ${count}`).join(", ");
1258
- const dispositionSuppressedNote = (extracted.dispositionSuppressed ?? 0) > 0 ? `
1259
-
1260
- suppressed by disposition: ${extracted.dispositionSuppressed} finding(s) dropped from this result because they're marked false-positive or won't-fix (${dispositionSuppressedByLaneText}). Not a clean verdict for those locations — they were found, then intentionally hidden.` : "";
1261
- const walkUnsafeRoot = explicitFiles === undefined && isAtOrAboveHomeDir(cwd);
1262
- const walkUnsafeRootNote = walkUnsafeRoot ? `
1263
-
1264
- project file walk skipped: the working directory resolves at or above the home directory, so the cheap project scan and the LSP workspace sweep would each enumerate every unrelated tree under it. Re-run from inside a project directory. Absence of their findings is NOT a clean verdict.` : "";
1265
- const scanTruncatedNoticeText = projectSnapshot ? scanTruncationNotice(projectSnapshot) : undefined;
1266
- const scanTruncatedNote = scanTruncatedNoticeText ? `
1267
-
1268
- ${scanTruncatedNoticeText}` : "";
1269
- const generatedSkipNoticeText = projectSnapshot ? generatedSkipNotice(projectSnapshot, host) : undefined;
1270
- const generatedSkipNote = generatedSkipNoticeText ? `
1271
-
1272
- ${generatedSkipNoticeText}` : "";
1273
- const cheapScanScannedAtMs = rawProjectSnapshot?.scannedAt ? Date.parse(rawProjectSnapshot.scannedAt) : undefined;
1274
- const cheapScanStatusNote = !projectRunnersRequested ? `
1275
-
1276
- cheap project scan (tree-sitter/fact-rules/ast-grep): not run this call (${notRequestedReason(host)}).` : options.refreshRunners === "cached" ? cheapScanScannedAtMs !== undefined && Number.isFinite(cheapScanScannedAtMs) ? `
1277
-
1278
- cheap project scan (tree-sitter/fact-rules/ast-grep): served from cache, ${formatCacheAgeOld(Date.now() - cheapScanScannedAtMs)} — not re-run this call.` : `
1279
-
1280
- cheap project scan (tree-sitter/fact-rules/ast-grep): not run (no cached scan; refresh with refreshRunners=cheap/all to populate).` : "";
1281
- const abortedNote = abortedIds.size > 0 ? `
1282
-
1283
- stopped mid-scan (still running in the background, not reflected in this result): ${[
1284
- ...abortedIds
1285
- ].join(", ")}. Not a clean verdict for these — re-run mode=full to pick up their result once it's cached.` : "";
1286
- const cachedAgeMs = extracted.cachedAgeMs ?? {};
1287
- const timingEntries = Object.entries(extracted.timings ?? {}).filter(([id]) => !(id in cachedAgeMs));
1288
- const freshNote = timingEntries.length > 0 ? `
1289
-
1290
- fetched fresh this call: ${timingEntries.map(([id, ms]) => `${id} (${Math.round(ms)}ms)`).join(", ")}.` : "";
1291
- const cachedAgeEntries = Object.entries(cachedAgeMs);
1292
- const cachedAgeNote = cachedAgeEntries.length > 0 ? `
1293
-
1294
- served from cache this call (not re-run): ${cachedAgeEntries.map(([id, ms]) => `${id} (${formatCacheAgeOld(ms)})`).join(", ")}.` : "";
1295
- const resultWithCold = {
1296
- ...result,
1297
- details: {
1298
- ...result.details,
1299
- coldRunners: extracted.cold,
1300
- partialRunners: partialIds,
1301
- coldReasons: extracted.coldReasons ?? {},
1302
- failedAnalyzers,
1303
- analyzerTimingsMs: extracted.timings,
1304
- dispositionSuppressed: extracted.dispositionSuppressed ?? 0,
1305
- dispositionSuppressedByLane: extracted.dispositionSuppressedByLane ?? {},
1306
- analyzersCachedAgeMs: cachedAgeMs,
1307
- analyzersAborted: extracted.aborted ?? false,
1308
- analyzersAbortedIds: extracted.abortedIds ?? [],
1309
- analyzersUnsafeRoot: extracted.analysisRootValidation?.state === "unsafe" || extracted.unsafeRoot === true,
1310
- analysisRootValidation: extracted.analysisRootValidation,
1311
- projectWalkUnsafeRoot: walkUnsafeRoot,
1312
- lspFilesConfirmed: confirmedLspResults.length,
1313
- lspFilesUnconfirmed: unconfirmedLspResults.length,
1314
- lspFilesPartiallyCovered: partiallyCoveredLspResults.length,
1315
- unconfirmedLspServerIds: uncoveredScannerIds,
1316
- unconfirmedLspFiles: unconfirmedLspResults.map((result) => result.filePath),
1317
- lspServerBreakdown: Object.fromEntries(lspServerBreakdown),
1318
- lspPrimaryDiagnosticsCount: lspPrimaryVsAuxiliary.primary,
1319
- lspAuxiliaryDiagnosticsCount: lspPrimaryVsAuxiliary.auxiliary,
1320
- projectScanTruncated: projectSnapshot?.scanTruncated ?? false,
1321
- ...projectSnapshot?.generatedFileSkips ? { projectGeneratedFileSkips: projectSnapshot.generatedFileSkips } : {},
1322
- ...projectSnapshot?.generatedNameOnlySkips ? {
1323
- projectGeneratedNameOnlySkips: projectSnapshot.generatedNameOnlySkips
1324
- } : {},
1325
- ...projectSnapshot?.generatedDirSkips ? { projectGeneratedDirSkips: projectSnapshot.generatedDirSkips } : {}
1326
- }
1327
- };
1328
- if (aborted) {
1329
- const timedOut = signal?.reason?.name === "TimeoutError";
1330
- const note = timedOut ? `
1331
-
1332
- ⚠ Scan exceeded its ${Math.round((options.wallClockMs ?? 0) / 1000)}s time budget and was stopped — results are partial. ` + "Narrow it with maxLspFiles, or raise DM_LENS_LENS_DIAGNOSTICS_FULL_TIMEOUT_MS." : `
1333
-
1334
- ⚠ Scan cancelled before completion — results are partial. ` + "Re-run with a smaller maxLspFiles to finish within budget.";
1335
- return {
1336
- content: [
1337
- {
1338
- type: "text",
1339
- text: result.content[0].text + note + unconfirmedLspNote + auxiliaryCoverageNote + lspPrimaryVsAuxiliaryNote + partialNote + coldNote + testRunnerEditScopedNote + failedNote + dispositionSuppressedNote + walkUnsafeRootNote + scanTruncatedNote + generatedSkipNote + abortedNote + freshNote + cachedAgeNote + cheapScanStatusNote + missingNote
1340
- }
1341
- ],
1342
- details: { ...resultWithCold.details, timedOut }
1343
- };
1344
- }
1345
- if (missingNote || coldNote || partialNote || testRunnerEditScopedNote || failedNote || dispositionSuppressedNote || walkUnsafeRootNote || scanTruncatedNote || generatedSkipNote || abortedNote || freshNote || cachedAgeNote || cheapScanStatusNote || unconfirmedLspNote || auxiliaryCoverageNote || lspPrimaryVsAuxiliaryNote) {
1346
- return {
1347
- content: [
1348
- {
1349
- type: "text",
1350
- text: result.content[0].text + unconfirmedLspNote + auxiliaryCoverageNote + lspPrimaryVsAuxiliaryNote + partialNote + coldNote + testRunnerEditScopedNote + failedNote + dispositionSuppressedNote + walkUnsafeRootNote + scanTruncatedNote + generatedSkipNote + abortedNote + freshNote + cachedAgeNote + cheapScanStatusNote + missingNote
1351
- }
1352
- ],
1353
- details: resultWithCold.details
1354
- };
1355
- }
1356
- return resultWithCold;
1357
- }
1358
- async function projectResolvedCwd(summary, cwd) {
1359
- const resolvedCwd = await resolveLspCwdForFile(summary.filePath, cwd);
1360
- return {
1361
- ...summary,
1362
- ...resolvedCwd === undefined ? {} : { resolvedCwd },
1363
- diagnostics: summary.diagnostics ?? []
1364
- };
1365
- }
1366
- async function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummaries(), detailOverrides = { mode: "all" }, staleDropped = 0, pathsScope, dependencyDemoted = 0) {
1367
- const footerCapped = summaries.reduce((n, s) => n + (s.diagnostics ?? []).filter((d) => d.footerRetired === true).length, 0);
1368
- const staleNote = (staleDropped > 0 ? ` (${staleDropped} changed file${staleDropped === 1 ? "" : "s"} omitted as stale — use mode=full to rescan)` : "") + (dependencyDemoted > 0 ? ` (${dependencyDemoted} blocking finding${dependencyDemoted === 1 ? "" : "s"} demoted to [stale] — an imported file changed since; re-run to confirm)` : "") + (footerCapped > 0 ? ` (${footerCapped} demoted finding${footerCapped === 1 ? "" : "s"} capped after ${DEPENDENCY_DRIFT_MAX_DELIVERIES} unconfirmed deliveries — no longer shown in the dm-lens footer, still listed here; re-run to confirm)` : "");
1369
- const isFullMode = detailOverrides.mode === "full";
1370
- const includeFile = createScopedFileFilter(cwd, pathsScope);
1371
- const policyMap = loadProjectRulePolicyMap(cwd);
1372
- const dispositioned = isFullMode ? summaries : summaries.map((s) => {
1373
- const diagnostics = s.diagnostics ?? [];
1374
- const kept = applyCachedDispositions(diagnostics, cwd, s.filePath);
1375
- const policyKept = applyRulePolicy(kept, policyMap);
1376
- if (policyKept.length === kept.length && kept.length === diagnostics.length)
1377
- return s;
1378
- return summarizeDiagnostics(s.filePath, policyKept, s.hasFinalSnapshot);
1379
- });
1380
- const eofGated = dispositioned.map((s) => {
1381
- const { diagnostics, demotedCount } = demotePastEofDiagnostics({
1382
- store: "lens_diagnostics",
1383
- cwd,
1384
- filePath: s.filePath,
1385
- diagnostics: s.diagnostics ?? [],
1386
- resync: resyncDocumentOnPastEof
1387
- });
1388
- if (demotedCount === 0)
1389
- return s;
1390
- return summarizeDiagnostics(s.filePath, diagnostics, s.hasFinalSnapshot);
1391
- });
1392
- const visibleSummaries = eofGated.filter((s) => includeFile(s.filePath));
1393
- const withIssues = visibleSummaries.filter((s) => {
1394
- if (severity === "error")
1395
- return s.blocking > 0 || s.errors > 0;
1396
- if (severity === "warning")
1397
- return s.blocking > 0 || s.errors > 0 || s.warnings > 0;
1398
- return s.blocking > 0 || s.errors > 0 || s.warnings > 0 || s.advisories > 0 || (s.diagnostics ?? []).some((d) => d.stale);
1399
- });
1400
- const pathsNote = isFullMode ? "" : pathsScopeCacheOnlyNote(pathsScope);
1401
- if (withIssues.length === 0) {
1402
- const text = (visibleSummaries.length === 0 ? "No files diagnosed yet this session." : `No ${severity === "all" ? "" : severity + " "}issues across ${visibleSummaries.length} file${visibleSummaries.length === 1 ? "" : "s"} diagnosed this session. ✓`) + staleNote + pathsNote;
1403
- return {
1404
- content: [{ type: "text", text }],
1405
- details: {
1406
- ...detailOverrides,
1407
- filesChecked: visibleSummaries.length,
1408
- staleDropped
1409
- }
1410
- };
1411
- }
1412
- const sorted = withIssues.sort((a, b) => b.blocking - a.blocking || b.errors - a.errors || b.warnings - a.warnings);
1413
- const rendered = await Promise.all(sorted.map((summary) => projectResolvedCwd(summary, cwd)));
1414
- const lines = [];
1415
- let totalBlocking = 0;
1416
- let totalErrors = 0;
1417
- let totalWarnings = 0;
1418
- let totalAdvisories = 0;
1419
- for (const s of rendered) {
1420
- const rel = path.relative(cwd, s.filePath);
1421
- const parts = [];
1422
- if (s.blocking > 0)
1423
- parts.push(`\uD83D\uDD34 ${s.blocking} blocking`);
1424
- if (s.errors > 0 && s.blocking === 0)
1425
- parts.push(`${s.errors}E`);
1426
- if (s.warnings > 0)
1427
- parts.push(`${s.warnings}W`);
1428
- if (s.advisories > 0)
1429
- parts.push(`${s.advisories} hint${s.advisories === 1 ? "" : "s"}`);
1430
- if (!s.hasFinalSnapshot)
1431
- parts.push(`(pending)`);
1432
- const staleCount = (s.diagnostics ?? []).filter((d) => d.stale).length;
1433
- if (staleCount > 0) {
1434
- parts.push(`${staleCount} stale — re-run to confirm`);
1435
- }
1436
- if (s.resolvedCwd !== undefined)
1437
- parts.push(`cwd=${s.resolvedCwd}`);
1438
- lines.push(`${rel} ${parts.join(" ")}`);
1439
- const matching = (s.diagnostics ?? []).filter((d) => matchesSeverity(d, severity)).sort(bySeverityThenLine);
1440
- const shown = matching.slice(0, MAX_DIAGNOSTICS_PER_FILE);
1441
- for (const d of shown) {
1442
- const marker = d.stale ? "" : isErrorLike(d) ? d.semantic === "blocking" ? "\uD83D\uDD34 " : "" : "";
1443
- const label = d.rule ?? d.tool;
1444
- const tag = label ? ` [${label}]` : "";
1445
- const flaggedTag = d.flagged ? " \uD83D\uDCCC flagged-to-fix" : "";
1446
- const msg = d.message.replace(/\s+/g, " ").trim();
1447
- const pastEof = d.stale && (d.staleReason ?? "past-eof") === "past-eof";
1448
- const loc = pastEof ? PAST_EOF_STALE_MARKER : `L${d.line ?? "?"}`;
1449
- const staleTag = d.stale && !pastEof ? ` ${STALE_LINE_MARKER}` : "";
1450
- lines.push(` ${marker}${loc}: ${msg}${tag}${flaggedTag}${staleTag}`);
1451
- }
1452
- if (matching.length > shown.length) {
1453
- lines.push(` … ${matching.length - shown.length} more in this file (showing ${shown.length} of ${matching.length})`);
1454
- }
1455
- totalBlocking += s.blocking;
1456
- totalErrors += s.errors;
1457
- totalWarnings += s.warnings;
1458
- totalAdvisories += s.advisories;
1459
- }
1460
- const summary = [
1461
- `
1462
- Summary (${visibleSummaries.length} files diagnosed this session):`,
1463
- totalBlocking > 0 ? ` \uD83D\uDD34 ${totalBlocking} blocking error${totalBlocking === 1 ? "" : "s"}` : null,
1464
- totalBlocking === 0 && totalErrors > 0 ? ` ${totalErrors} error${totalErrors === 1 ? "" : "s"}` : null,
1465
- totalWarnings > 0 ? ` ${totalWarnings} warning${totalWarnings === 1 ? "" : "s"}` : null,
1466
- totalAdvisories > 0 ? ` ${totalAdvisories} hint/info (style — not counted as warnings)` : null
1467
- ].filter(Boolean).join(`
1468
- `);
1469
- return {
1470
- content: [
1471
- { type: "text", text: lines.join(`
1472
- `) + summary + staleNote }
1473
- ],
1474
- details: {
1475
- ...detailOverrides,
1476
- filesWithIssues: withIssues.length,
1477
- totalBlocking,
1478
- totalErrors,
1479
- totalWarnings,
1480
- totalAdvisories,
1481
- staleDropped
1482
- }
1483
- };
1484
- }