@duckmind/dm-linux-x64 0.65.4 → 0.65.6

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 (1208) hide show
  1. package/README.md +0 -8
  2. package/dm +2 -2
  3. package/extensions/.dm-extensions.json +677 -44
  4. package/extensions/dm-lens/clients/actionable-warnings-logger.js +0 -6
  5. package/extensions/dm-lens/clients/actionable-warnings.js +42 -13
  6. package/extensions/dm-lens/clients/advisory-provenance.js +129 -41
  7. package/extensions/dm-lens/clients/agent-behavior-client.js +1 -0
  8. package/extensions/dm-lens/clients/analysed-root.js +0 -0
  9. package/extensions/dm-lens/clients/ast-grep-client.js +38 -3
  10. package/extensions/dm-lens/clients/ast-grep-rule-manager.js +37 -5
  11. package/extensions/dm-lens/clients/ast-grep-tool-logger.js +1 -7
  12. package/extensions/dm-lens/clients/bash-file-access.js +138 -1
  13. package/extensions/dm-lens/clients/biome-client.js +9 -2
  14. package/extensions/dm-lens/clients/blocker-freshness.js +171 -21
  15. package/extensions/dm-lens/clients/bootstrap.js +9 -5
  16. package/extensions/dm-lens/clients/bounded-pid-file-lock.js +1 -1
  17. package/extensions/dm-lens/clients/bounded-telemetry.js +1 -4
  18. package/extensions/dm-lens/clients/bundled-resource-health.js +43 -0
  19. package/extensions/dm-lens/clients/bus-events-logger.js +0 -6
  20. package/extensions/dm-lens/clients/cache/rule-cache.js +11 -3
  21. package/extensions/dm-lens/clients/cache-manager.js +29 -5
  22. package/extensions/dm-lens/clients/cache-observability.js +104 -4
  23. package/extensions/dm-lens/clients/cargo-manifest.js +6 -3
  24. package/extensions/dm-lens/clients/cascade-format.js +87 -5
  25. package/extensions/dm-lens/clients/cascade-logger.js +0 -6
  26. package/extensions/dm-lens/clients/child-unref.js +5 -9
  27. package/extensions/dm-lens/clients/code-quality-warnings.js +4 -2
  28. package/extensions/dm-lens/clients/complexity-client.js +5 -1
  29. package/extensions/dm-lens/clients/config-core/index.js +2 -68
  30. package/extensions/dm-lens/clients/config-core/process-spec.js +1 -1
  31. package/extensions/dm-lens/clients/config-core/provenance.js +1 -2
  32. package/extensions/dm-lens/clients/config-core/records.js +1 -1
  33. package/extensions/dm-lens/clients/config-core/schema.js +3 -6
  34. package/extensions/dm-lens/clients/config-diagnostic-codes.js +5 -3
  35. package/extensions/dm-lens/clients/config-locations.js +125 -5
  36. package/extensions/dm-lens/clients/config-resolve.js +12 -6
  37. package/extensions/dm-lens/clients/config-schema.js +56 -3
  38. package/extensions/dm-lens/clients/config-warn.js +3 -2
  39. package/extensions/dm-lens/clients/dead-code-client.js +4 -1
  40. package/extensions/dm-lens/clients/dead-code-logger.js +0 -3
  41. package/extensions/dm-lens/clients/degradation-ledger.js +29 -4
  42. package/extensions/dm-lens/clients/dependency-checker.js +29 -50
  43. package/extensions/dm-lens/clients/diagnostic-dispositions.js +23 -4
  44. package/extensions/dm-lens/clients/diagnostic-logger.js +1 -1
  45. package/extensions/dm-lens/clients/dispatch/ast-grep-catalog.js +19 -0
  46. package/extensions/dm-lens/clients/dispatch/auxiliary-lsp.js +9 -0
  47. package/extensions/dm-lens/clients/dispatch/collect-later-tier.js +0 -3
  48. package/extensions/dm-lens/clients/dispatch/dispatcher.js +30 -27
  49. package/extensions/dm-lens/clients/dispatch/facts/function-facts.js +1 -1
  50. package/extensions/dm-lens/clients/dispatch/facts/import-facts.js +4 -1
  51. package/extensions/dm-lens/clients/dispatch/finding-policy.js +163 -0
  52. package/extensions/dm-lens/clients/dispatch/indent-detect.js +213 -13
  53. package/extensions/dm-lens/clients/dispatch/inline-suppressions.js +20 -1
  54. package/extensions/dm-lens/clients/dispatch/integration.js +77 -13
  55. package/extensions/dm-lens/clients/dispatch/lazy.js +0 -3
  56. package/extensions/dm-lens/clients/dispatch/pending-runner-findings.js +1 -1
  57. package/extensions/dm-lens/clients/dispatch/plan.js +0 -3
  58. package/extensions/dm-lens/clients/dispatch/rule-ignores.js +21 -0
  59. package/extensions/dm-lens/clients/dispatch/rules/high-complexity.js +2 -2
  60. package/extensions/dm-lens/clients/dispatch/rules/high-fan-out.js +1 -1
  61. package/extensions/dm-lens/clients/dispatch/runners/actionlint.js +25 -29
  62. package/extensions/dm-lens/clients/dispatch/runners/ast-grep-napi.js +8 -32
  63. package/extensions/dm-lens/clients/dispatch/runners/biome-check.js +39 -23
  64. package/extensions/dm-lens/clients/dispatch/runners/cpp-check.js +29 -48
  65. package/extensions/dm-lens/clients/dispatch/runners/credo.js +17 -14
  66. package/extensions/dm-lens/clients/dispatch/runners/cue-vet.js +9 -7
  67. package/extensions/dm-lens/clients/dispatch/runners/dart-analyze.js +21 -43
  68. package/extensions/dm-lens/clients/dispatch/runners/detekt.js +11 -5
  69. package/extensions/dm-lens/clients/dispatch/runners/dotnet-build.js +27 -23
  70. package/extensions/dm-lens/clients/dispatch/runners/elixir-check.js +23 -38
  71. package/extensions/dm-lens/clients/dispatch/runners/eslint.js +22 -35
  72. package/extensions/dm-lens/clients/dispatch/runners/fish-indent.js +2 -1
  73. package/extensions/dm-lens/clients/dispatch/runners/gleam-check.js +35 -12
  74. package/extensions/dm-lens/clients/dispatch/runners/go-vet.js +5 -3
  75. package/extensions/dm-lens/clients/dispatch/runners/golangci-lint.js +21 -22
  76. package/extensions/dm-lens/clients/dispatch/runners/hadolint.js +26 -16
  77. package/extensions/dm-lens/clients/dispatch/runners/helm-lint.js +3 -1
  78. package/extensions/dm-lens/clients/dispatch/runners/helm-render.js +3 -2
  79. package/extensions/dm-lens/clients/dispatch/runners/htmlhint.js +18 -9
  80. package/extensions/dm-lens/clients/dispatch/runners/javac.js +24 -23
  81. package/extensions/dm-lens/clients/dispatch/runners/ktlint.js +23 -54
  82. package/extensions/dm-lens/clients/dispatch/runners/lsp.js +17 -7
  83. package/extensions/dm-lens/clients/dispatch/runners/markdownlint.js +12 -6
  84. package/extensions/dm-lens/clients/dispatch/runners/mypy.js +2 -1
  85. package/extensions/dm-lens/clients/dispatch/runners/oxlint.js +24 -7
  86. package/extensions/dm-lens/clients/dispatch/runners/php-lint.js +26 -17
  87. package/extensions/dm-lens/clients/dispatch/runners/phpstan.js +2 -1
  88. package/extensions/dm-lens/clients/dispatch/runners/prisma-validate.js +2 -1
  89. package/extensions/dm-lens/clients/dispatch/runners/psscriptanalyzer.js +10 -11
  90. package/extensions/dm-lens/clients/dispatch/runners/pyright.js +2 -1
  91. package/extensions/dm-lens/clients/dispatch/runners/rubocop.js +22 -18
  92. package/extensions/dm-lens/clients/dispatch/runners/ruff.js +17 -22
  93. package/extensions/dm-lens/clients/dispatch/runners/rust-clippy.js +8 -11
  94. package/extensions/dm-lens/clients/dispatch/runners/shellcheck.js +9 -4
  95. package/extensions/dm-lens/clients/dispatch/runners/shfmt.js +4 -13
  96. package/extensions/dm-lens/clients/dispatch/runners/spellcheck.js +15 -5
  97. package/extensions/dm-lens/clients/dispatch/runners/spotbugs.js +2 -1
  98. package/extensions/dm-lens/clients/dispatch/runners/sqlfluff.js +10 -4
  99. package/extensions/dm-lens/clients/dispatch/runners/stylelint.js +9 -4
  100. package/extensions/dm-lens/clients/dispatch/runners/swiftlint.js +11 -3
  101. package/extensions/dm-lens/clients/dispatch/runners/taplo.js +13 -7
  102. package/extensions/dm-lens/clients/dispatch/runners/terragrunt.js +2 -1
  103. package/extensions/dm-lens/clients/dispatch/runners/tflint.js +26 -16
  104. package/extensions/dm-lens/clients/dispatch/runners/tree-sitter.js +12 -13
  105. package/extensions/dm-lens/clients/dispatch/runners/trivy-config.js +9 -3
  106. package/extensions/dm-lens/clients/dispatch/runners/utils/availability-policy.js +5 -0
  107. package/extensions/dm-lens/clients/dispatch/runners/utils/candidate-probe.js +2 -2
  108. package/extensions/dm-lens/clients/dispatch/runners/utils/diagnostic-parsers.js +8 -52
  109. package/extensions/dm-lens/clients/dispatch/runners/utils/runner-helpers.js +35 -3
  110. package/extensions/dm-lens/clients/dispatch/runners/utils.js +0 -17
  111. package/extensions/dm-lens/clients/dispatch/runners/vale.js +12 -4
  112. package/extensions/dm-lens/clients/dispatch/runners/yaml-rule-parser.js +2 -20
  113. package/extensions/dm-lens/clients/dispatch/runners/yamllint.js +16 -4
  114. package/extensions/dm-lens/clients/dispatch/runners/zig-check.js +26 -38
  115. package/extensions/dm-lens/clients/dispatch/suppress-writer.js +13 -3
  116. package/extensions/dm-lens/clients/dispatch/types.js +4 -1
  117. package/extensions/dm-lens/clients/dispatch/utils/format-utils.js +2 -2
  118. package/extensions/dm-lens/clients/disposition-logger.js +0 -6
  119. package/extensions/dm-lens/clients/disposition-publish.js +2 -1
  120. package/extensions/dm-lens/clients/effective-config.js +14 -4
  121. package/extensions/dm-lens/clients/event-loop-hold.js +123 -0
  122. package/extensions/dm-lens/clients/event-loop-monitor.js +2 -2
  123. package/extensions/dm-lens/clients/extension-log.js +6 -1
  124. package/extensions/dm-lens/clients/feature-hints.js +2 -1
  125. package/extensions/dm-lens/clients/file-kinds.js +17 -21
  126. package/extensions/dm-lens/clients/file-role.js +11 -2
  127. package/extensions/dm-lens/clients/file-time.js +1 -1
  128. package/extensions/dm-lens/clients/file-utils.js +93 -6
  129. package/extensions/dm-lens/clients/finding-delivery-gate.js +22 -26
  130. package/extensions/dm-lens/clients/format-service.js +33 -16
  131. package/extensions/dm-lens/clients/formatters.js +129 -92
  132. package/extensions/dm-lens/clients/generated-artifacts.js +2 -2
  133. package/extensions/dm-lens/clients/generation-guard.js +4 -0
  134. package/extensions/dm-lens/clients/git-guard.js +80 -26
  135. package/extensions/dm-lens/clients/gitleaks-client.js +26 -0
  136. package/extensions/dm-lens/clients/govulncheck-client.js +34 -6
  137. package/extensions/dm-lens/clients/gradle-ktfmt-style.js +96 -13
  138. package/extensions/dm-lens/clients/grammar-source.js +3 -3
  139. package/extensions/dm-lens/clients/host-edit-normalize.js +1 -1
  140. package/extensions/dm-lens/clients/indent-retarget.js +35 -5
  141. package/extensions/dm-lens/clients/inline-blocker-dispositions.js +107 -0
  142. package/extensions/dm-lens/clients/install-diagnostics.js +8 -6
  143. package/extensions/dm-lens/clients/installer/index.js +695 -183
  144. package/extensions/dm-lens/clients/installer/managed-tool-refresh.js +85 -25
  145. package/extensions/dm-lens/clients/instance-reaper-state.js +3 -0
  146. package/extensions/dm-lens/clients/instance-reaper.js +23 -16
  147. package/extensions/dm-lens/clients/instance-registry.js +34 -2
  148. package/extensions/dm-lens/clients/jscpd-client.js +11 -1
  149. package/extensions/dm-lens/clients/knip-client.js +2 -1
  150. package/extensions/dm-lens/clients/language-profile.js +18 -12
  151. package/extensions/dm-lens/clients/language-registry.js +3 -1
  152. package/extensions/dm-lens/clients/latency-logger.js +14 -4
  153. package/extensions/dm-lens/clients/ledger-bounds.js +13 -1
  154. package/extensions/dm-lens/clients/lens-config.js +74 -7
  155. package/extensions/dm-lens/clients/lens-engine.js +9 -10
  156. package/extensions/dm-lens/clients/lens-events.js +1 -1
  157. package/extensions/dm-lens/clients/lens-flag-registry.js +47 -2
  158. package/extensions/dm-lens/clients/lens-map.js +1 -1
  159. package/extensions/dm-lens/clients/log-cleanup.js +0 -28
  160. package/extensions/dm-lens/clients/lsp/cascade-tier.js +2 -1
  161. package/extensions/dm-lens/clients/lsp/client.js +70 -30
  162. package/extensions/dm-lens/clients/lsp/config.js +41 -15
  163. package/extensions/dm-lens/clients/lsp/content-limits.js +21 -0
  164. package/extensions/dm-lens/clients/lsp/diagnostic-binding.js +8 -0
  165. package/extensions/dm-lens/clients/lsp/document-drift.js +72 -1
  166. package/extensions/dm-lens/clients/lsp/edits.js +3 -3
  167. package/extensions/dm-lens/clients/lsp/index.js +435 -62
  168. package/extensions/dm-lens/clients/lsp/inferred-project.js +1 -1
  169. package/extensions/dm-lens/clients/lsp/language.js +0 -3
  170. package/extensions/dm-lens/clients/lsp/launch.js +12 -5
  171. package/extensions/dm-lens/clients/lsp/path-utils.js +0 -2
  172. package/extensions/dm-lens/clients/lsp/pending-aux-coverage.js +0 -1
  173. package/extensions/dm-lens/clients/lsp/server.js +125 -60
  174. package/extensions/dm-lens/clients/lsp/session-roots.js +26 -5
  175. package/extensions/dm-lens/clients/lsp/sync-kind.js +14 -1
  176. package/extensions/dm-lens/clients/lsp/tsserver-sync.js +5 -7
  177. package/extensions/dm-lens/clients/lsp/wait-policy/classification.js +3 -0
  178. package/extensions/dm-lens/clients/lsp/wait-policy/strategies.js +31 -2
  179. package/extensions/dm-lens/clients/lsp/workspace-diagnostics-cache.js +26 -4
  180. package/extensions/dm-lens/clients/lsp-document-symbols.js +1 -1
  181. package/extensions/dm-lens/clients/map-with-concurrency.js +7 -3
  182. package/extensions/dm-lens/clients/mcp/analyze.js +1 -1
  183. package/extensions/dm-lens/clients/mcp/ipc.js +104 -40
  184. package/extensions/dm-lens/clients/mcp/review.js +39 -7
  185. package/extensions/dm-lens/clients/mcp/session.js +38 -4
  186. package/extensions/dm-lens/clients/metrics-history.js +19 -84
  187. package/extensions/dm-lens/clients/middle-man-analysis.js +2 -4
  188. package/extensions/dm-lens/clients/module-report.js +1 -1
  189. package/extensions/dm-lens/clients/mutating-tool.js +3 -3
  190. package/extensions/dm-lens/clients/mutation-attribution.js +3 -3
  191. package/extensions/dm-lens/clients/ndjson-logger.js +17 -9
  192. package/extensions/dm-lens/clients/observed-mutation.js +42 -11
  193. package/extensions/dm-lens/clients/opaque-mutation-scan.js +17 -7
  194. package/extensions/dm-lens/clients/opengrep-client.js +92 -10
  195. package/extensions/dm-lens/clients/opengrep-config.js +1 -1
  196. package/extensions/dm-lens/clients/package-manager.js +2 -1
  197. package/extensions/dm-lens/clients/path-utils.js +199 -3
  198. package/extensions/dm-lens/clients/performance-report.js +3 -3
  199. package/extensions/dm-lens/clients/persistent-reverify.js +167 -0
  200. package/extensions/dm-lens/clients/php-cs-fixer-config.js +9 -4
  201. package/extensions/dm-lens/clients/pipeline.js +124 -68
  202. package/extensions/dm-lens/clients/project-changes.js +1 -1
  203. package/extensions/dm-lens/clients/project-diagnostics/cache.js +19 -5
  204. package/extensions/dm-lens/clients/project-diagnostics/extractors.js +1 -1
  205. package/extensions/dm-lens/clients/project-diagnostics/fresh-fetch.js +150 -18
  206. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/dead-code.js +4 -1
  207. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/gitleaks.js +3 -3
  208. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/jscpd.js +1 -1
  209. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/knip.js +1 -1
  210. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/madge.js +1 -1
  211. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/opengrep.js +1 -1
  212. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/runner-findings.js +19 -2
  213. package/extensions/dm-lens/clients/project-diagnostics/scanner.js +35 -4
  214. package/extensions/dm-lens/clients/project-lens-config.js +58 -4
  215. package/extensions/dm-lens/clients/project-scan-policy.js +0 -46
  216. package/extensions/dm-lens/clients/python-environment.js +80 -4
  217. package/extensions/dm-lens/clients/python-provenance.js +551 -0
  218. package/extensions/dm-lens/clients/read-guard-logger.js +3 -1
  219. package/extensions/dm-lens/clients/read-guard.js +29 -6
  220. package/extensions/dm-lens/clients/recent-touches.js +2 -2
  221. package/extensions/dm-lens/clients/resource-sampler.js +59 -9
  222. package/extensions/dm-lens/clients/review-graph/builder.js +39 -34
  223. package/extensions/dm-lens/clients/review-graph/git-identity.js +11 -7
  224. package/extensions/dm-lens/clients/review-graph/import-resolvers.js +1 -1
  225. package/extensions/dm-lens/clients/review-graph-logger.js +3 -1
  226. package/extensions/dm-lens/clients/ruff-client.js +11 -10
  227. package/extensions/dm-lens/clients/runtime-agent-end.js +41 -5
  228. package/extensions/dm-lens/clients/runtime-context.js +5 -2
  229. package/extensions/dm-lens/clients/runtime-coordinator.js +60 -6
  230. package/extensions/dm-lens/clients/runtime-session.js +52 -8
  231. package/extensions/dm-lens/clients/runtime-tool-call.js +27 -15
  232. package/extensions/dm-lens/clients/runtime-tool-result.js +279 -63
  233. package/extensions/dm-lens/clients/runtime-turn.js +453 -185
  234. package/extensions/dm-lens/clients/safe-spawn.js +248 -62
  235. package/extensions/dm-lens/clients/sanitize.js +0 -4
  236. package/extensions/dm-lens/clients/scan-utils.js +1 -39
  237. package/extensions/dm-lens/clients/scratch-tree-policy.js +2 -3
  238. package/extensions/dm-lens/clients/security-scan-client.js +2 -2
  239. package/extensions/dm-lens/clients/session-event-guard.js +59 -2
  240. package/extensions/dm-lens/clients/session-summary.js +0 -25
  241. package/extensions/dm-lens/clients/sg-runner.js +24 -12
  242. package/extensions/dm-lens/clients/sgconfig.js +58 -6
  243. package/extensions/dm-lens/clients/shared-checkout-guard.js +1 -1
  244. package/extensions/dm-lens/clients/situational-tool-telemetry.js +85 -0
  245. package/extensions/dm-lens/clients/skills-resolver.js +42 -0
  246. package/extensions/dm-lens/clients/smells-rollup.js +2 -2
  247. package/extensions/dm-lens/clients/spawn-output-cap.js +29 -0
  248. package/extensions/dm-lens/clients/startup-scan.js +1 -2
  249. package/extensions/dm-lens/clients/string-utils.js +3 -0
  250. package/extensions/dm-lens/clients/test-runner-client.js +118 -57
  251. package/extensions/dm-lens/clients/test-runner-delivery.js +118 -66
  252. package/extensions/dm-lens/clients/tool-agreement.js +403 -0
  253. package/extensions/dm-lens/clients/tool-config.js +218 -0
  254. package/extensions/dm-lens/clients/tool-cwd.js +248 -0
  255. package/extensions/dm-lens/clients/tool-definition.js +18 -1
  256. package/extensions/dm-lens/clients/tool-policy.js +138 -10
  257. package/extensions/dm-lens/clients/tool-probe.js +5 -0
  258. package/extensions/dm-lens/clients/tool-set-policy.js +35 -0
  259. package/extensions/dm-lens/clients/tree-sitter-client.js +201 -80
  260. package/extensions/dm-lens/clients/tree-sitter-query-loader.js +78 -130
  261. package/extensions/dm-lens/clients/trivy-client.js +8 -1
  262. package/extensions/dm-lens/clients/tui-fit.js +0 -3
  263. package/extensions/dm-lens/clients/turn-context.js +48 -0
  264. package/extensions/dm-lens/clients/turn-end/lane.js +0 -0
  265. package/extensions/dm-lens/clients/turn-end/lanes/govulncheck.js +54 -0
  266. package/extensions/dm-lens/clients/turn-end/lanes/secrets.js +140 -0
  267. package/extensions/dm-lens/clients/user-notify.js +0 -3
  268. package/extensions/dm-lens/clients/warm-attach.js +25 -0
  269. package/extensions/dm-lens/clients/widget-state.js +203 -13
  270. package/extensions/dm-lens/clients/word-index-logger.js +0 -6
  271. package/extensions/dm-lens/clients/word-index-store.js +1 -4
  272. package/extensions/dm-lens/clients/word-index.js +9 -5
  273. package/extensions/dm-lens/clients/workspace-topology.js +20 -3
  274. package/extensions/dm-lens/clients/write-ordering-guard.js +6 -0
  275. package/extensions/dm-lens/clients/zizmor-config.js +15 -11
  276. package/extensions/dm-lens/config/dependency-cruiser-eager-allowlist.json +8 -2
  277. package/extensions/dm-lens/dist/clients/actionable-warnings-logger.js +24 -0
  278. package/extensions/dm-lens/dist/clients/actionable-warnings.js +1014 -0
  279. package/extensions/dm-lens/dist/clients/advisory-provenance.js +385 -0
  280. package/extensions/dm-lens/dist/clients/agent-behavior-client.js +94 -0
  281. package/extensions/dm-lens/dist/clients/agent-nudge.js +151 -0
  282. package/extensions/dm-lens/dist/clients/analysed-root.js +1 -0
  283. package/extensions/dm-lens/dist/clients/ast-grep-client.js +576 -0
  284. package/extensions/dm-lens/dist/clients/ast-grep-rule-manager.js +114 -0
  285. package/extensions/dm-lens/dist/clients/ast-grep-tool-logger.js +85 -0
  286. package/extensions/dm-lens/dist/clients/ast-grep-types.js +1 -0
  287. package/extensions/dm-lens/dist/clients/ast-grep-yaml-synth.js +109 -0
  288. package/extensions/dm-lens/dist/clients/atomic-write-staging.js +66 -0
  289. package/extensions/dm-lens/dist/clients/atomic-write.js +37 -0
  290. package/extensions/dm-lens/dist/clients/availability-probe-flight.js +11 -0
  291. package/extensions/dm-lens/dist/clients/bash-file-access.js +830 -0
  292. package/extensions/dm-lens/dist/clients/biome-client.js +221 -0
  293. package/extensions/dm-lens/dist/clients/blocker-freshness.js +385 -0
  294. package/extensions/dm-lens/dist/clients/blocker-past-eof.js +49 -0
  295. package/extensions/dm-lens/dist/clients/bootstrap.js +246 -0
  296. package/extensions/dm-lens/dist/clients/bounded-cache.js +105 -0
  297. package/extensions/dm-lens/dist/clients/bounded-pid-file-lock.js +173 -0
  298. package/extensions/dm-lens/dist/clients/bounded-telemetry.js +104 -0
  299. package/extensions/dm-lens/dist/clients/build-identity.js +45 -0
  300. package/extensions/dm-lens/dist/clients/bundled-resource-health.js +41 -0
  301. package/extensions/dm-lens/dist/clients/bus-events-logger.js +48 -0
  302. package/extensions/dm-lens/dist/clients/bus-publish.js +117 -0
  303. package/extensions/dm-lens/dist/clients/cache/rule-cache.js +103 -0
  304. package/extensions/dm-lens/dist/clients/cache-manager.js +340 -0
  305. package/extensions/dm-lens/dist/clients/cache-observability.js +847 -0
  306. package/extensions/dm-lens/dist/clients/call-graph.js +628 -0
  307. package/extensions/dm-lens/dist/clients/cargo-manifest.js +151 -0
  308. package/extensions/dm-lens/dist/clients/cascade-budget.js +52 -0
  309. package/extensions/dm-lens/dist/clients/cascade-format.js +160 -0
  310. package/extensions/dm-lens/dist/clients/cascade-logger.js +22 -0
  311. package/extensions/dm-lens/dist/clients/cascade-types.js +1 -0
  312. package/extensions/dm-lens/dist/clients/child-unref.js +59 -0
  313. package/extensions/dm-lens/dist/clients/code-quality-warnings.js +192 -0
  314. package/extensions/dm-lens/dist/clients/codebase-model.js +110 -0
  315. package/extensions/dm-lens/dist/clients/collateral-test-role.js +8 -0
  316. package/extensions/dm-lens/dist/clients/complexity-client.js +398 -0
  317. package/extensions/dm-lens/dist/clients/config-core/deny.js +117 -0
  318. package/extensions/dm-lens/dist/clients/config-core/index.js +2 -0
  319. package/extensions/dm-lens/dist/clients/config-core/merge.js +228 -0
  320. package/extensions/dm-lens/dist/clients/config-core/normalize.js +217 -0
  321. package/extensions/dm-lens/dist/clients/config-core/process-spec.js +147 -0
  322. package/extensions/dm-lens/dist/clients/config-core/provenance.js +54 -0
  323. package/extensions/dm-lens/dist/clients/config-core/records.js +79 -0
  324. package/extensions/dm-lens/dist/clients/config-core/resolve.js +48 -0
  325. package/extensions/dm-lens/dist/clients/config-core/safe-object.js +22 -0
  326. package/extensions/dm-lens/dist/clients/config-core/schema.js +90 -0
  327. package/extensions/dm-lens/dist/clients/config-diagnostic-codes.js +90 -0
  328. package/extensions/dm-lens/dist/clients/config-locations.js +175 -0
  329. package/extensions/dm-lens/dist/clients/config-resolve.js +359 -0
  330. package/extensions/dm-lens/dist/clients/config-schema.js +128 -0
  331. package/extensions/dm-lens/dist/clients/config-warn.js +146 -0
  332. package/extensions/dm-lens/dist/clients/console-guard-install.js +4 -0
  333. package/extensions/dm-lens/dist/clients/cooperative-budget.js +36 -0
  334. package/extensions/dm-lens/dist/clients/dead-code-client.js +342 -0
  335. package/extensions/dm-lens/dist/clients/dead-code-logger.js +18 -0
  336. package/extensions/dm-lens/dist/clients/deadline-utils.js +117 -0
  337. package/extensions/dm-lens/dist/clients/debug-handles.js +121 -0
  338. package/extensions/dm-lens/dist/clients/debug-heap.js +80 -0
  339. package/extensions/dm-lens/dist/clients/deferred-lsp-work.js +33 -0
  340. package/extensions/dm-lens/dist/clients/degradation-ledger.js +272 -0
  341. package/extensions/dm-lens/dist/clients/demoted-finding-render.js +61 -0
  342. package/extensions/dm-lens/dist/clients/dependency-checker.js +525 -0
  343. package/extensions/dm-lens/dist/clients/deps/ast-grep-napi.js +17 -0
  344. package/extensions/dm-lens/dist/clients/deps/dm-host-deps.js +10 -0
  345. package/extensions/dm-lens/dist/clients/deps/dm-tui-compat.js +58 -0
  346. package/extensions/dm-lens/dist/clients/deps/js-yaml.js +7 -0
  347. package/extensions/dm-lens/dist/clients/deps/minimatch.js +6 -0
  348. package/extensions/dm-lens/dist/clients/deps/pidusage.js +5 -0
  349. package/extensions/dm-lens/dist/clients/deps/typebox.js +5 -0
  350. package/extensions/dm-lens/dist/clients/deps/vscode-jsonrpc.js +8 -0
  351. package/extensions/dm-lens/dist/clients/deps/web-tree-sitter.js +11 -0
  352. package/extensions/dm-lens/dist/clients/diagnostic-dispositions.js +318 -0
  353. package/extensions/dm-lens/dist/clients/diagnostic-line-freshness.js +144 -0
  354. package/extensions/dm-lens/dist/clients/diagnostic-logger.js +60 -0
  355. package/extensions/dm-lens/dist/clients/diagnostic-tracker.js +89 -0
  356. package/extensions/dm-lens/dist/clients/diagnostics-publish.js +134 -0
  357. package/extensions/dm-lens/dist/clients/dispatch/ast-grep-catalog.js +16 -0
  358. package/extensions/dm-lens/dist/clients/dispatch/auxiliary-lsp.js +158 -0
  359. package/extensions/dm-lens/dist/clients/dispatch/collect-later-tier.js +25 -0
  360. package/extensions/dm-lens/dist/clients/dispatch/diagnostic-taxonomy.js +58 -0
  361. package/extensions/dm-lens/dist/clients/dispatch/dispatcher.js +953 -0
  362. package/extensions/dm-lens/dist/clients/dispatch/fact-provider-types.js +1 -0
  363. package/extensions/dm-lens/dist/clients/dispatch/fact-rule-runner.js +17 -0
  364. package/extensions/dm-lens/dist/clients/dispatch/fact-runner.js +18 -0
  365. package/extensions/dm-lens/dist/clients/dispatch/fact-scheduler.js +52 -0
  366. package/extensions/dm-lens/dist/clients/dispatch/fact-store.js +199 -0
  367. package/extensions/dm-lens/dist/clients/dispatch/facts/comment-facts.js +20 -0
  368. package/extensions/dm-lens/dist/clients/dispatch/facts/file-content.js +18 -0
  369. package/extensions/dm-lens/dist/clients/dispatch/facts/function-facts.js +281 -0
  370. package/extensions/dm-lens/dist/clients/dispatch/facts/import-facts.js +169 -0
  371. package/extensions/dm-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +19 -0
  372. package/extensions/dm-lens/dist/clients/dispatch/facts/try-catch-facts.js +95 -0
  373. package/extensions/dm-lens/dist/clients/dispatch/finding-policy.js +159 -0
  374. package/extensions/dm-lens/dist/clients/dispatch/indent-detect.js +227 -0
  375. package/extensions/dm-lens/dist/clients/dispatch/inline-suppressions.js +52 -0
  376. package/extensions/dm-lens/dist/clients/dispatch/integration.js +1463 -0
  377. package/extensions/dm-lens/dist/clients/dispatch/lazy.js +8 -0
  378. package/extensions/dm-lens/dist/clients/dispatch/pending-runner-findings.js +75 -0
  379. package/extensions/dm-lens/dist/clients/dispatch/plan.js +278 -0
  380. package/extensions/dm-lens/dist/clients/dispatch/priorities.js +14 -0
  381. package/extensions/dm-lens/dist/clients/dispatch/rule-id-normalize.js +42 -0
  382. package/extensions/dm-lens/dist/clients/dispatch/rule-ignores.js +21 -0
  383. package/extensions/dm-lens/dist/clients/dispatch/rule-policy.js +73 -0
  384. package/extensions/dm-lens/dist/clients/dispatch/rules/async-noise.js +31 -0
  385. package/extensions/dm-lens/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +27 -0
  386. package/extensions/dm-lens/dist/clients/dispatch/rules/cors-wildcard.js +35 -0
  387. package/extensions/dm-lens/dist/clients/dispatch/rules/error-obscuring.js +29 -0
  388. package/extensions/dm-lens/dist/clients/dispatch/rules/error-swallowing.js +29 -0
  389. package/extensions/dm-lens/dist/clients/dispatch/rules/framework-call-noise.js +31 -0
  390. package/extensions/dm-lens/dist/clients/dispatch/rules/high-complexity.js +56 -0
  391. package/extensions/dm-lens/dist/clients/dispatch/rules/high-fan-out.js +45 -0
  392. package/extensions/dm-lens/dist/clients/dispatch/rules/high-import-coupling.js +31 -0
  393. package/extensions/dm-lens/dist/clients/dispatch/rules/missing-error-propagation.js +45 -0
  394. package/extensions/dm-lens/dist/clients/dispatch/rules/no-commented-credentials.js +46 -0
  395. package/extensions/dm-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +38 -0
  396. package/extensions/dm-lens/dist/clients/dispatch/rules/placeholder-comments.js +40 -0
  397. package/extensions/dm-lens/dist/clients/dispatch/rules/unsafe-boundary.js +101 -0
  398. package/extensions/dm-lens/dist/clients/dispatch/runner-context.js +46 -0
  399. package/extensions/dm-lens/dist/clients/dispatch/runners/actionlint.js +98 -0
  400. package/extensions/dm-lens/dist/clients/dispatch/runners/ast-grep-napi.js +690 -0
  401. package/extensions/dm-lens/dist/clients/dispatch/runners/biome-check.js +202 -0
  402. package/extensions/dm-lens/dist/clients/dispatch/runners/cpp-check.js +190 -0
  403. package/extensions/dm-lens/dist/clients/dispatch/runners/credo.js +66 -0
  404. package/extensions/dm-lens/dist/clients/dispatch/runners/cue-vet.js +167 -0
  405. package/extensions/dm-lens/dist/clients/dispatch/runners/dart-analyze.js +151 -0
  406. package/extensions/dm-lens/dist/clients/dispatch/runners/detekt.js +157 -0
  407. package/extensions/dm-lens/dist/clients/dispatch/runners/dotnet-build.js +157 -0
  408. package/extensions/dm-lens/dist/clients/dispatch/runners/elixir-check.js +153 -0
  409. package/extensions/dm-lens/dist/clients/dispatch/runners/eslint.js +99 -0
  410. package/extensions/dm-lens/dist/clients/dispatch/runners/fact-rules.js +20 -0
  411. package/extensions/dm-lens/dist/clients/dispatch/runners/fish-indent.js +65 -0
  412. package/extensions/dm-lens/dist/clients/dispatch/runners/gleam-check.js +107 -0
  413. package/extensions/dm-lens/dist/clients/dispatch/runners/go-vet.js +51 -0
  414. package/extensions/dm-lens/dist/clients/dispatch/runners/golangci-lint.js +89 -0
  415. package/extensions/dm-lens/dist/clients/dispatch/runners/hadolint.js +83 -0
  416. package/extensions/dm-lens/dist/clients/dispatch/runners/helm-lint.js +144 -0
  417. package/extensions/dm-lens/dist/clients/dispatch/runners/helm-render.js +593 -0
  418. package/extensions/dm-lens/dist/clients/dispatch/runners/htmlhint.js +103 -0
  419. package/extensions/dm-lens/dist/clients/dispatch/runners/index.js +100 -0
  420. package/extensions/dm-lens/dist/clients/dispatch/runners/javac.js +82 -0
  421. package/extensions/dm-lens/dist/clients/dispatch/runners/ktlint.js +93 -0
  422. package/extensions/dm-lens/dist/clients/dispatch/runners/lsp.js +206 -0
  423. package/extensions/dm-lens/dist/clients/dispatch/runners/markdownlint.js +129 -0
  424. package/extensions/dm-lens/dist/clients/dispatch/runners/mypy.js +70 -0
  425. package/extensions/dm-lens/dist/clients/dispatch/runners/oxlint.js +305 -0
  426. package/extensions/dm-lens/dist/clients/dispatch/runners/php-lint.js +70 -0
  427. package/extensions/dm-lens/dist/clients/dispatch/runners/phpstan.js +90 -0
  428. package/extensions/dm-lens/dist/clients/dispatch/runners/prisma-validate.js +56 -0
  429. package/extensions/dm-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +307 -0
  430. package/extensions/dm-lens/dist/clients/dispatch/runners/pyright.js +118 -0
  431. package/extensions/dm-lens/dist/clients/dispatch/runners/rubocop.js +79 -0
  432. package/extensions/dm-lens/dist/clients/dispatch/runners/ruff.js +69 -0
  433. package/extensions/dm-lens/dist/clients/dispatch/runners/rust-clippy.js +147 -0
  434. package/extensions/dm-lens/dist/clients/dispatch/runners/shellcheck.js +111 -0
  435. package/extensions/dm-lens/dist/clients/dispatch/runners/shfmt.js +81 -0
  436. package/extensions/dm-lens/dist/clients/dispatch/runners/spellcheck.js +74 -0
  437. package/extensions/dm-lens/dist/clients/dispatch/runners/spotbugs.js +208 -0
  438. package/extensions/dm-lens/dist/clients/dispatch/runners/sqlfluff.js +136 -0
  439. package/extensions/dm-lens/dist/clients/dispatch/runners/stylelint.js +118 -0
  440. package/extensions/dm-lens/dist/clients/dispatch/runners/swiftlint.js +143 -0
  441. package/extensions/dm-lens/dist/clients/dispatch/runners/taplo.js +97 -0
  442. package/extensions/dm-lens/dist/clients/dispatch/runners/terragrunt.js +110 -0
  443. package/extensions/dm-lens/dist/clients/dispatch/runners/tflint.js +104 -0
  444. package/extensions/dm-lens/dist/clients/dispatch/runners/tree-sitter.js +516 -0
  445. package/extensions/dm-lens/dist/clients/dispatch/runners/trivy-config.js +155 -0
  446. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/availability-policy.js +285 -0
  447. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +61 -0
  448. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +61 -0
  449. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +130 -0
  450. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +1067 -0
  451. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +40 -0
  452. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/tool-failure.js +117 -0
  453. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +88 -0
  454. package/extensions/dm-lens/dist/clients/dispatch/runners/utils.js +8 -0
  455. package/extensions/dm-lens/dist/clients/dispatch/runners/vale.js +106 -0
  456. package/extensions/dm-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +163 -0
  457. package/extensions/dm-lens/dist/clients/dispatch/runners/yamllint.js +83 -0
  458. package/extensions/dm-lens/dist/clients/dispatch/runners/zig-check.js +72 -0
  459. package/extensions/dm-lens/dist/clients/dispatch/suppress-writer.js +57 -0
  460. package/extensions/dm-lens/dist/clients/dispatch/tool-profile.js +30 -0
  461. package/extensions/dm-lens/dist/clients/dispatch/types.js +7 -0
  462. package/extensions/dm-lens/dist/clients/dispatch/utils/format-utils.js +45 -0
  463. package/extensions/dm-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +31 -0
  464. package/extensions/dm-lens/dist/clients/disposition-logger.js +19 -0
  465. package/extensions/dm-lens/dist/clients/disposition-publish.js +88 -0
  466. package/extensions/dm-lens/dist/clients/durable-store.js +77 -0
  467. package/extensions/dm-lens/dist/clients/effective-config.js +160 -0
  468. package/extensions/dm-lens/dist/clients/env-utils.js +26 -0
  469. package/extensions/dm-lens/dist/clients/error-class.js +3 -0
  470. package/extensions/dm-lens/dist/clients/eval-timestamp.js +2 -0
  471. package/extensions/dm-lens/dist/clients/event-loop-hold.js +119 -0
  472. package/extensions/dm-lens/dist/clients/event-loop-monitor.js +84 -0
  473. package/extensions/dm-lens/dist/clients/extension-log.js +230 -0
  474. package/extensions/dm-lens/dist/clients/extension-mode.js +20 -0
  475. package/extensions/dm-lens/dist/clients/feature-hints.js +88 -0
  476. package/extensions/dm-lens/dist/clients/file-kinds.js +304 -0
  477. package/extensions/dm-lens/dist/clients/file-role.js +50 -0
  478. package/extensions/dm-lens/dist/clients/file-time.js +112 -0
  479. package/extensions/dm-lens/dist/clients/file-utils.js +630 -0
  480. package/extensions/dm-lens/dist/clients/finding-delivery-gate.js +129 -0
  481. package/extensions/dm-lens/dist/clients/finding-identity.js +23 -0
  482. package/extensions/dm-lens/dist/clients/fix-worklog.js +75 -0
  483. package/extensions/dm-lens/dist/clients/format-events-publish.js +230 -0
  484. package/extensions/dm-lens/dist/clients/format-service.js +154 -0
  485. package/extensions/dm-lens/dist/clients/formatters-lazy.js +8 -0
  486. package/extensions/dm-lens/dist/clients/formatters.js +1351 -0
  487. package/extensions/dm-lens/dist/clients/freshness-cadence.js +1 -0
  488. package/extensions/dm-lens/dist/clients/freshness.js +8 -0
  489. package/extensions/dm-lens/dist/clients/generated-artifacts.js +209 -0
  490. package/extensions/dm-lens/dist/clients/generation-guard.js +105 -0
  491. package/extensions/dm-lens/dist/clients/git-guard.js +770 -0
  492. package/extensions/dm-lens/dist/clients/git-tracked-ignore.js +120 -0
  493. package/extensions/dm-lens/dist/clients/gitleaks-client.js +282 -0
  494. package/extensions/dm-lens/dist/clients/go-client.js +47 -0
  495. package/extensions/dm-lens/dist/clients/govulncheck-client.js +411 -0
  496. package/extensions/dm-lens/dist/clients/gradle-ktfmt-style.js +177 -0
  497. package/extensions/dm-lens/dist/clients/grammar-source.js +224 -0
  498. package/extensions/dm-lens/dist/clients/gzip-stage-write.js +85 -0
  499. package/extensions/dm-lens/dist/clients/hashline-anchor.js +222 -0
  500. package/extensions/dm-lens/dist/clients/hook-budgets.js +16 -0
  501. package/extensions/dm-lens/dist/clients/host-edit-normalize.js +87 -0
  502. package/extensions/dm-lens/dist/clients/host-ports.js +35 -0
  503. package/extensions/dm-lens/dist/clients/indent-retarget.js +102 -0
  504. package/extensions/dm-lens/dist/clients/inline-blocker-dispositions.js +103 -0
  505. package/extensions/dm-lens/dist/clients/install-diagnostics.js +123 -0
  506. package/extensions/dm-lens/dist/clients/installer/index.js +3770 -0
  507. package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh-session.js +17 -0
  508. package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh.js +522 -0
  509. package/extensions/dm-lens/dist/clients/instance-reaper-state.js +3 -0
  510. package/extensions/dm-lens/dist/clients/instance-reaper.js +577 -0
  511. package/extensions/dm-lens/dist/clients/instance-registry-lock.js +131 -0
  512. package/extensions/dm-lens/dist/clients/instance-registry.js +452 -0
  513. package/extensions/dm-lens/dist/clients/jscpd-client.js +252 -0
  514. package/extensions/dm-lens/dist/clients/json-cache-read.js +25 -0
  515. package/extensions/dm-lens/dist/clients/knip-client.js +472 -0
  516. package/extensions/dm-lens/dist/clients/language-policy.js +242 -0
  517. package/extensions/dm-lens/dist/clients/language-profile.js +261 -0
  518. package/extensions/dm-lens/dist/clients/language-registry.js +424 -0
  519. package/extensions/dm-lens/dist/clients/latency-logger.js +192 -0
  520. package/extensions/dm-lens/dist/clients/lazy-import.js +14 -0
  521. package/extensions/dm-lens/dist/clients/ledger-bounds.js +21 -0
  522. package/extensions/dm-lens/dist/clients/lens-config.js +237 -0
  523. package/extensions/dm-lens/dist/clients/lens-engine.js +181 -0
  524. package/extensions/dm-lens/dist/clients/lens-events.js +105 -0
  525. package/extensions/dm-lens/dist/clients/lens-flag-registry.js +302 -0
  526. package/extensions/dm-lens/dist/clients/lens-map.js +980 -0
  527. package/extensions/dm-lens/dist/clients/live-bus-emitter.js +53 -0
  528. package/extensions/dm-lens/dist/clients/log-cleanup.js +138 -0
  529. package/extensions/dm-lens/dist/clients/lsp/aggregation.js +88 -0
  530. package/extensions/dm-lens/dist/clients/lsp/cascade-tier.js +203 -0
  531. package/extensions/dm-lens/dist/clients/lsp/client.js +2709 -0
  532. package/extensions/dm-lens/dist/clients/lsp/config.js +252 -0
  533. package/extensions/dm-lens/dist/clients/lsp/content-limits.js +21 -0
  534. package/extensions/dm-lens/dist/clients/lsp/diagnostic-binding.js +79 -0
  535. package/extensions/dm-lens/dist/clients/lsp/document-drift.js +312 -0
  536. package/extensions/dm-lens/dist/clients/lsp/edits.js +930 -0
  537. package/extensions/dm-lens/dist/clients/lsp/index.js +4448 -0
  538. package/extensions/dm-lens/dist/clients/lsp/inferred-project.js +121 -0
  539. package/extensions/dm-lens/dist/clients/lsp/jvm-runtime.js +194 -0
  540. package/extensions/dm-lens/dist/clients/lsp/language.js +23 -0
  541. package/extensions/dm-lens/dist/clients/lsp/launch.js +468 -0
  542. package/extensions/dm-lens/dist/clients/lsp/lombok.js +146 -0
  543. package/extensions/dm-lens/dist/clients/lsp/path-utils.js +1 -0
  544. package/extensions/dm-lens/dist/clients/lsp/pending-aux-coverage.js +90 -0
  545. package/extensions/dm-lens/dist/clients/lsp/position-encoding.js +28 -0
  546. package/extensions/dm-lens/dist/clients/lsp/ruby-drive-dirs.js +42 -0
  547. package/extensions/dm-lens/dist/clients/lsp/server.js +2422 -0
  548. package/extensions/dm-lens/dist/clients/lsp/session-roots.js +52 -0
  549. package/extensions/dm-lens/dist/clients/lsp/spawn-history.js +15 -0
  550. package/extensions/dm-lens/dist/clients/lsp/sync-kind.js +30 -0
  551. package/extensions/dm-lens/dist/clients/lsp/tsserver-sync.js +156 -0
  552. package/extensions/dm-lens/dist/clients/lsp/wait-policy/capability-snapshot.js +1 -0
  553. package/extensions/dm-lens/dist/clients/lsp/wait-policy/classification.js +36 -0
  554. package/extensions/dm-lens/dist/clients/lsp/wait-policy/index.js +3 -0
  555. package/extensions/dm-lens/dist/clients/lsp/wait-policy/strategies.js +175 -0
  556. package/extensions/dm-lens/dist/clients/lsp/watch-queue.js +40 -0
  557. package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-cache.js +267 -0
  558. package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-session.js +7 -0
  559. package/extensions/dm-lens/dist/clients/lsp/workspace-sweep-hold.js +93 -0
  560. package/extensions/dm-lens/dist/clients/lsp-budget.js +83 -0
  561. package/extensions/dm-lens/dist/clients/lsp-document-symbols.js +93 -0
  562. package/extensions/dm-lens/dist/clients/lsp-lazy.js +8 -0
  563. package/extensions/dm-lens/dist/clients/lsp-mutation.js +273 -0
  564. package/extensions/dm-lens/dist/clients/lsp-status.js +37 -0
  565. package/extensions/dm-lens/dist/clients/map-with-concurrency.js +20 -0
  566. package/extensions/dm-lens/dist/clients/mcp/analyze.js +251 -0
  567. package/extensions/dm-lens/dist/clients/mcp/host-shim.js +14 -0
  568. package/extensions/dm-lens/dist/clients/mcp/ipc.js +302 -0
  569. package/extensions/dm-lens/dist/clients/mcp/review.js +137 -0
  570. package/extensions/dm-lens/dist/clients/mcp/session.js +305 -0
  571. package/extensions/dm-lens/dist/clients/memory-sampler.js +107 -0
  572. package/extensions/dm-lens/dist/clients/message-end-attribution.js +18 -0
  573. package/extensions/dm-lens/dist/clients/metrics-client.js +80 -0
  574. package/extensions/dm-lens/dist/clients/metrics-history.js +255 -0
  575. package/extensions/dm-lens/dist/clients/middle-man-analysis.js +161 -0
  576. package/extensions/dm-lens/dist/clients/model-provider.js +31 -0
  577. package/extensions/dm-lens/dist/clients/module-report-lsp.js +140 -0
  578. package/extensions/dm-lens/dist/clients/module-report.js +1642 -0
  579. package/extensions/dm-lens/dist/clients/mutating-tool.js +377 -0
  580. package/extensions/dm-lens/dist/clients/mutation-attribution.js +168 -0
  581. package/extensions/dm-lens/dist/clients/mutation-bridge.js +102 -0
  582. package/extensions/dm-lens/dist/clients/ndjson-logger.js +471 -0
  583. package/extensions/dm-lens/dist/clients/observed-mutation-sources.js +43 -0
  584. package/extensions/dm-lens/dist/clients/observed-mutation.js +709 -0
  585. package/extensions/dm-lens/dist/clients/oldtext-autopatch.js +100 -0
  586. package/extensions/dm-lens/dist/clients/opaque-mutation-scan.js +313 -0
  587. package/extensions/dm-lens/dist/clients/opengrep-client.js +216 -0
  588. package/extensions/dm-lens/dist/clients/opengrep-config.js +52 -0
  589. package/extensions/dm-lens/dist/clients/package-manager.js +303 -0
  590. package/extensions/dm-lens/dist/clients/package-root.js +25 -0
  591. package/extensions/dm-lens/dist/clients/partial-edit-apply.js +337 -0
  592. package/extensions/dm-lens/dist/clients/path-attribution-telemetry.js +31 -0
  593. package/extensions/dm-lens/dist/clients/path-keyed-map.js +57 -0
  594. package/extensions/dm-lens/dist/clients/path-utils.js +476 -0
  595. package/extensions/dm-lens/dist/clients/performance-report.js +291 -0
  596. package/extensions/dm-lens/dist/clients/persist-debounce.js +37 -0
  597. package/extensions/dm-lens/dist/clients/persistent-reverify.js +165 -0
  598. package/extensions/dm-lens/dist/clients/php-cs-fixer-config.js +15 -0
  599. package/extensions/dm-lens/dist/clients/pipeline.js +1091 -0
  600. package/extensions/dm-lens/dist/clients/post-autofix-notice.js +19 -0
  601. package/extensions/dm-lens/dist/clients/print-mode.js +3 -0
  602. package/extensions/dm-lens/dist/clients/probe-home-state.js +62 -0
  603. package/extensions/dm-lens/dist/clients/process-bridge.js +20 -0
  604. package/extensions/dm-lens/dist/clients/process-singletons.js +69 -0
  605. package/extensions/dm-lens/dist/clients/process-snapshot.js +22 -0
  606. package/extensions/dm-lens/dist/clients/project-changes.js +112 -0
  607. package/extensions/dm-lens/dist/clients/project-conventions.js +152 -0
  608. package/extensions/dm-lens/dist/clients/project-diagnostics/cache.js +91 -0
  609. package/extensions/dm-lens/dist/clients/project-diagnostics/extractors.js +53 -0
  610. package/extensions/dm-lens/dist/clients/project-diagnostics/fresh-fetch.js +408 -0
  611. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +64 -0
  612. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +38 -0
  613. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +21 -0
  614. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +23 -0
  615. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +28 -0
  616. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +45 -0
  617. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +34 -0
  618. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +32 -0
  619. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +79 -0
  620. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +41 -0
  621. package/extensions/dm-lens/dist/clients/project-diagnostics/scanner.js +349 -0
  622. package/extensions/dm-lens/dist/clients/project-diagnostics/types.js +1 -0
  623. package/extensions/dm-lens/dist/clients/project-lens-config.js +437 -0
  624. package/extensions/dm-lens/dist/clients/project-report.js +527 -0
  625. package/extensions/dm-lens/dist/clients/project-scale.js +60 -0
  626. package/extensions/dm-lens/dist/clients/project-scan-policy.js +4 -0
  627. package/extensions/dm-lens/dist/clients/project-snapshot-fingerprint.js +39 -0
  628. package/extensions/dm-lens/dist/clients/project-snapshot-persist-worker.js +14 -0
  629. package/extensions/dm-lens/dist/clients/project-snapshot.js +1178 -0
  630. package/extensions/dm-lens/dist/clients/project-trust.js +104 -0
  631. package/extensions/dm-lens/dist/clients/python-environment.js +120 -0
  632. package/extensions/dm-lens/dist/clients/python-provenance.js +551 -0
  633. package/extensions/dm-lens/dist/clients/quiet-window-config.js +16 -0
  634. package/extensions/dm-lens/dist/clients/quiet-window.js +126 -0
  635. package/extensions/dm-lens/dist/clients/read-bridge.js +46 -0
  636. package/extensions/dm-lens/dist/clients/read-expansion.js +218 -0
  637. package/extensions/dm-lens/dist/clients/read-guard-logger.js +178 -0
  638. package/extensions/dm-lens/dist/clients/read-guard-tool-lines.js +1042 -0
  639. package/extensions/dm-lens/dist/clients/read-guard.js +1096 -0
  640. package/extensions/dm-lens/dist/clients/recent-touches.js +126 -0
  641. package/extensions/dm-lens/dist/clients/redact/secrets.js +386 -0
  642. package/extensions/dm-lens/dist/clients/resource-sampler.js +344 -0
  643. package/extensions/dm-lens/dist/clients/reverse-deps.js +227 -0
  644. package/extensions/dm-lens/dist/clients/review-graph/builder.js +3635 -0
  645. package/extensions/dm-lens/dist/clients/review-graph/format.js +30 -0
  646. package/extensions/dm-lens/dist/clients/review-graph/git-identity.js +115 -0
  647. package/extensions/dm-lens/dist/clients/review-graph/import-resolvers.js +325 -0
  648. package/extensions/dm-lens/dist/clients/review-graph/persist-worker.js +8 -0
  649. package/extensions/dm-lens/dist/clients/review-graph/query.js +195 -0
  650. package/extensions/dm-lens/dist/clients/review-graph/revision-drift.js +3 -0
  651. package/extensions/dm-lens/dist/clients/review-graph/service.js +60 -0
  652. package/extensions/dm-lens/dist/clients/review-graph/shared-extraction-ir.js +54 -0
  653. package/extensions/dm-lens/dist/clients/review-graph/symbol-id.js +29 -0
  654. package/extensions/dm-lens/dist/clients/review-graph/tsconfig-paths.js +253 -0
  655. package/extensions/dm-lens/dist/clients/review-graph/types.js +1 -0
  656. package/extensions/dm-lens/dist/clients/review-graph/workspace-modules.js +374 -0
  657. package/extensions/dm-lens/dist/clients/review-graph-logger.js +51 -0
  658. package/extensions/dm-lens/dist/clients/ruff-client.js +109 -0
  659. package/extensions/dm-lens/dist/clients/rules-scanner.js +113 -0
  660. package/extensions/dm-lens/dist/clients/run-duration.js +9 -0
  661. package/extensions/dm-lens/dist/clients/runtime-agent-end.js +608 -0
  662. package/extensions/dm-lens/dist/clients/runtime-config.js +39 -0
  663. package/extensions/dm-lens/dist/clients/runtime-context.js +155 -0
  664. package/extensions/dm-lens/dist/clients/runtime-coordinator.js +817 -0
  665. package/extensions/dm-lens/dist/clients/runtime-session.js +1625 -0
  666. package/extensions/dm-lens/dist/clients/runtime-tool-call.js +868 -0
  667. package/extensions/dm-lens/dist/clients/runtime-tool-result.js +1317 -0
  668. package/extensions/dm-lens/dist/clients/runtime-turn.js +2333 -0
  669. package/extensions/dm-lens/dist/clients/rust-client.js +48 -0
  670. package/extensions/dm-lens/dist/clients/safe-spawn.js +1267 -0
  671. package/extensions/dm-lens/dist/clients/sanitize.js +174 -0
  672. package/extensions/dm-lens/dist/clients/scan-utils.js +7 -0
  673. package/extensions/dm-lens/dist/clients/scratch-tree-policy.js +57 -0
  674. package/extensions/dm-lens/dist/clients/search-read-registration.js +59 -0
  675. package/extensions/dm-lens/dist/clients/secret-findings.js +69 -0
  676. package/extensions/dm-lens/dist/clients/security-scan-client.js +208 -0
  677. package/extensions/dm-lens/dist/clients/session-event-guard.js +111 -0
  678. package/extensions/dm-lens/dist/clients/session-lifecycle.js +173 -0
  679. package/extensions/dm-lens/dist/clients/session-start-observability.js +47 -0
  680. package/extensions/dm-lens/dist/clients/session-state-store.js +63 -0
  681. package/extensions/dm-lens/dist/clients/session-summary.js +8 -0
  682. package/extensions/dm-lens/dist/clients/sessionstart-logger.js +22 -0
  683. package/extensions/dm-lens/dist/clients/sg-runner.js +627 -0
  684. package/extensions/dm-lens/dist/clients/sgconfig.js +280 -0
  685. package/extensions/dm-lens/dist/clients/shared-checkout-guard.js +177 -0
  686. package/extensions/dm-lens/dist/clients/single-flight.js +52 -0
  687. package/extensions/dm-lens/dist/clients/situational-tool-telemetry.js +85 -0
  688. package/extensions/dm-lens/dist/clients/skills-resolver.js +38 -0
  689. package/extensions/dm-lens/dist/clients/slow-fs.js +77 -0
  690. package/extensions/dm-lens/dist/clients/smells-rollup.js +118 -0
  691. package/extensions/dm-lens/dist/clients/source-filter.js +320 -0
  692. package/extensions/dm-lens/dist/clients/source-walker.js +96 -0
  693. package/extensions/dm-lens/dist/clients/spawn-output-cap.js +35 -0
  694. package/extensions/dm-lens/dist/clients/spawn-timeout-cooldown.js +51 -0
  695. package/extensions/dm-lens/dist/clients/stale-marker.js +1 -0
  696. package/extensions/dm-lens/dist/clients/startup-scan.js +222 -0
  697. package/extensions/dm-lens/dist/clients/startup-timing.js +67 -0
  698. package/extensions/dm-lens/dist/clients/string-utils.js +6 -0
  699. package/extensions/dm-lens/dist/clients/subagent-mode.js +40 -0
  700. package/extensions/dm-lens/dist/clients/symbol-containment.js +16 -0
  701. package/extensions/dm-lens/dist/clients/symbol-types.js +1 -0
  702. package/extensions/dm-lens/dist/clients/test-runner-client.js +1504 -0
  703. package/extensions/dm-lens/dist/clients/test-runner-delivery.js +260 -0
  704. package/extensions/dm-lens/dist/clients/todo-scanner.js +164 -0
  705. package/extensions/dm-lens/dist/clients/tool-agreement.js +377 -0
  706. package/extensions/dm-lens/dist/clients/tool-config.js +218 -0
  707. package/extensions/dm-lens/dist/clients/tool-cwd.js +235 -0
  708. package/extensions/dm-lens/dist/clients/tool-definition.js +22 -0
  709. package/extensions/dm-lens/dist/clients/tool-event.js +18 -0
  710. package/extensions/dm-lens/dist/clients/tool-policy.js +2393 -0
  711. package/extensions/dm-lens/dist/clients/tool-probe.js +5 -0
  712. package/extensions/dm-lens/dist/clients/tool-render.js +79 -0
  713. package/extensions/dm-lens/dist/clients/tool-set-policy.js +70 -0
  714. package/extensions/dm-lens/dist/clients/tree-sitter-cache.js +206 -0
  715. package/extensions/dm-lens/dist/clients/tree-sitter-client.js +2787 -0
  716. package/extensions/dm-lens/dist/clients/tree-sitter-logger.js +77 -0
  717. package/extensions/dm-lens/dist/clients/tree-sitter-navigator.js +198 -0
  718. package/extensions/dm-lens/dist/clients/tree-sitter-query-loader.js +318 -0
  719. package/extensions/dm-lens/dist/clients/tree-sitter-shared.js +87 -0
  720. package/extensions/dm-lens/dist/clients/tree-sitter-symbol-extractor.js +957 -0
  721. package/extensions/dm-lens/dist/clients/trivy-client.js +305 -0
  722. package/extensions/dm-lens/dist/clients/tui-fit.js +26 -0
  723. package/extensions/dm-lens/dist/clients/turn-context.js +48 -0
  724. package/extensions/dm-lens/dist/clients/turn-end/lane.js +1 -0
  725. package/extensions/dm-lens/dist/clients/turn-end/lanes/govulncheck.js +54 -0
  726. package/extensions/dm-lens/dist/clients/turn-end/lanes/secrets.js +131 -0
  727. package/extensions/dm-lens/dist/clients/turn-summary-render.js +56 -0
  728. package/extensions/dm-lens/dist/clients/turn-summary.js +84 -0
  729. package/extensions/dm-lens/dist/clients/typos-config.js +9 -0
  730. package/extensions/dm-lens/dist/clients/user-notify.js +15 -0
  731. package/extensions/dm-lens/dist/clients/vanished-instance-marker.js +18 -0
  732. package/extensions/dm-lens/dist/clients/warm-attach.js +210 -0
  733. package/extensions/dm-lens/dist/clients/widget-state.js +963 -0
  734. package/extensions/dm-lens/dist/clients/word-index-logger.js +21 -0
  735. package/extensions/dm-lens/dist/clients/word-index-store.js +222 -0
  736. package/extensions/dm-lens/dist/clients/word-index.js +1426 -0
  737. package/extensions/dm-lens/dist/clients/workspace-topology.js +261 -0
  738. package/extensions/dm-lens/dist/clients/write-ordering-guard.js +24 -0
  739. package/extensions/dm-lens/dist/clients/zizmor-config.js +160 -0
  740. package/extensions/dm-lens/dist/i18n.js +67 -0
  741. package/extensions/dm-lens/dist/index.js +1782 -0
  742. package/extensions/dm-lens/dist/mcp/analyze-cli.js +178 -0
  743. package/extensions/dm-lens/dist/mcp/build-staleness.js +55 -0
  744. package/extensions/dm-lens/dist/mcp/cli.js +78 -0
  745. package/extensions/dm-lens/dist/mcp/server.js +1208 -0
  746. package/extensions/dm-lens/dist/mcp/worker.js +33 -0
  747. package/extensions/dm-lens/dist/scripts/lib/process-scan.mjs +256 -0
  748. package/extensions/dm-lens/dist/scripts/lib/skills-predicate.mjs +53 -0
  749. package/extensions/dm-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +45 -0
  750. package/extensions/dm-lens/dist/tools/activate-tools.js +61 -0
  751. package/extensions/dm-lens/dist/tools/ast-grep-outline.js +127 -0
  752. package/extensions/dm-lens/dist/tools/ast-grep-replace.js +226 -0
  753. package/extensions/dm-lens/dist/tools/ast-grep-search.js +687 -0
  754. package/extensions/dm-lens/dist/tools/effective-config.js +59 -0
  755. package/extensions/dm-lens/dist/tools/lens-diagnostic-mark.js +240 -0
  756. package/extensions/dm-lens/dist/tools/lens-diagnostics.js +1484 -0
  757. package/extensions/dm-lens/dist/tools/lsp-diagnostics.js +1088 -0
  758. package/extensions/dm-lens/dist/tools/lsp-navigation.js +1194 -0
  759. package/extensions/dm-lens/dist/tools/lsp-structured-output.js +277 -0
  760. package/extensions/dm-lens/dist/tools/module-report.js +332 -0
  761. package/extensions/dm-lens/dist/tools/project-report.js +72 -0
  762. package/extensions/dm-lens/dist/tools/render-compact.js +272 -0
  763. package/extensions/dm-lens/dist/tools/scan-progress.js +31 -0
  764. package/extensions/dm-lens/dist/tools/shared.js +26 -0
  765. package/extensions/dm-lens/dist/tools/symbol-search.js +133 -0
  766. package/extensions/dm-lens/index.js +278 -101
  767. package/extensions/dm-lens/mcp/analyze-cli.js +3 -2
  768. package/extensions/dm-lens/mcp/build-staleness.js +1 -1
  769. package/extensions/dm-lens/mcp/server.js +144 -73
  770. package/extensions/dm-lens/package.json +4 -4
  771. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/no-assert-tuple-test.yml +13 -0
  772. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/no-boolean-in-except-test.yml +26 -0
  773. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/no-http-headers-bracket-access-test.yml +10 -0
  774. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/unchecked-numeric-parse-python-test.yml +18 -0
  775. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/unchecked-throwing-call-python-test.yml +4 -3
  776. package/extensions/dm-lens/rules/ast-grep-rules/rules/go-no-fmt-println.yml +2 -2
  777. package/extensions/dm-lens/rules/ast-grep-rules/rules/no-assert-tuple.yml +23 -13
  778. package/extensions/dm-lens/rules/ast-grep-rules/rules/no-boolean-in-except.yml +7 -3
  779. package/extensions/dm-lens/rules/ast-grep-rules/rules/no-console-except-error-js.yml +2 -2
  780. package/extensions/dm-lens/rules/ast-grep-rules/rules/no-console-except-error.yml +2 -2
  781. package/extensions/dm-lens/rules/ast-grep-rules/rules/no-http-headers-bracket-access.yml +12 -7
  782. package/extensions/dm-lens/rules/ast-grep-rules/rules/unchecked-numeric-parse-python.yml +44 -0
  783. package/extensions/dm-lens/rules/ast-grep-rules/rules/unchecked-throwing-call-python.yml +5 -3
  784. package/extensions/dm-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
  785. package/extensions/dm-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
  786. package/extensions/dm-lens/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
  787. package/extensions/dm-lens/rules/tree-sitter-queries/typescript/console-statement.yml +2 -2
  788. package/extensions/dm-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +23 -7
  789. package/extensions/dm-lens/rules/typos/_typos.toml +4 -2
  790. package/extensions/dm-lens/scripts/lib/process-scan.mjs +1 -1
  791. package/extensions/dm-lens/scripts/lib/skills-predicate.mjs +53 -0
  792. package/extensions/dm-lens/scripts/lib/web-tree-sitter-dir.mjs +45 -0
  793. package/extensions/dm-lens/skills/pi-lens-ast-grep/SKILL.md +23 -6
  794. package/extensions/dm-lens/skills/pi-lens-lsp-navigation/SKILL.md +26 -9
  795. package/extensions/dm-lens/tools/activate-tools.js +10 -7
  796. package/extensions/dm-lens/tools/ast-grep-outline.js +2 -6
  797. package/extensions/dm-lens/tools/ast-grep-replace.js +5 -16
  798. package/extensions/dm-lens/tools/ast-grep-search.js +83 -38
  799. package/extensions/dm-lens/tools/effective-config.js +5 -4
  800. package/extensions/dm-lens/tools/lens-diagnostic-mark.js +5 -3
  801. package/extensions/dm-lens/tools/lens-diagnostics.js +478 -106
  802. package/extensions/dm-lens/tools/lsp-diagnostics.js +317 -172
  803. package/extensions/dm-lens/tools/lsp-navigation.js +26 -56
  804. package/extensions/dm-lens/tools/lsp-structured-output.js +3 -3
  805. package/extensions/dm-lens/tools/module-report.js +5 -5
  806. package/extensions/dm-lens/tools/project-report.js +9 -15
  807. package/extensions/dm-lens/tools/render-compact.js +220 -1
  808. package/extensions/dm-lens/tools/symbol-search.js +3 -5
  809. package/extensions/dm-mcp-adapter/OAUTH.md +368 -2
  810. package/extensions/dm-mcp-adapter/THIRD_PARTY_NOTICES.md +1 -1
  811. package/extensions/dm-mcp-adapter/agent-plugin-loader.js +73 -30
  812. package/extensions/dm-mcp-adapter/agent-plugin-provenance.js +26 -0
  813. package/extensions/dm-mcp-adapter/bearer-command-resolver.js +182 -0
  814. package/extensions/dm-mcp-adapter/claude-plugin-loader.js +350 -0
  815. package/extensions/dm-mcp-adapter/cli.js +82 -5
  816. package/extensions/dm-mcp-adapter/commands.js +89 -15
  817. package/extensions/dm-mcp-adapter/config.js +283 -33
  818. package/extensions/dm-mcp-adapter/consent-manager.js +32 -8
  819. package/extensions/dm-mcp-adapter/direct-tool-surface.js +223 -0
  820. package/extensions/dm-mcp-adapter/direct-tools.js +21 -216
  821. package/extensions/dm-mcp-adapter/dist/abort.js +35 -0
  822. package/extensions/dm-mcp-adapter/dist/agent-plugin-loader.js +73 -30
  823. package/extensions/dm-mcp-adapter/dist/agent-plugin-provenance.js +26 -0
  824. package/extensions/dm-mcp-adapter/dist/bearer-command-resolver.js +182 -0
  825. package/extensions/dm-mcp-adapter/dist/claude-plugin-loader.js +350 -0
  826. package/extensions/dm-mcp-adapter/dist/config.js +283 -33
  827. package/extensions/dm-mcp-adapter/dist/consent-manager.js +84 -0
  828. package/extensions/dm-mcp-adapter/dist/elicitation-handler.js +308 -0
  829. package/extensions/dm-mcp-adapter/dist/errors.js +225 -0
  830. package/extensions/dm-mcp-adapter/dist/http-ca.js +71 -0
  831. package/extensions/dm-mcp-adapter/dist/jev-client.js +359 -0
  832. package/extensions/dm-mcp-adapter/dist/jev-contracts.js +1 -0
  833. package/extensions/dm-mcp-adapter/dist/jev-key-store.js +176 -0
  834. package/extensions/dm-mcp-adapter/dist/json-schema-validator.js +70 -0
  835. package/extensions/dm-mcp-adapter/dist/lifecycle.js +387 -0
  836. package/extensions/dm-mcp-adapter/dist/logger.js +115 -0
  837. package/extensions/dm-mcp-adapter/dist/mcp-auth-fetch.js +86 -0
  838. package/extensions/dm-mcp-adapter/dist/mcp-auth-flow.js +949 -0
  839. package/extensions/dm-mcp-adapter/dist/mcp-auth.js +997 -0
  840. package/extensions/dm-mcp-adapter/dist/mcp-bearer-store.js +7 -136
  841. package/extensions/dm-mcp-adapter/dist/mcp-callback-server.js +381 -0
  842. package/extensions/dm-mcp-adapter/dist/mcp-oauth-provider.js +524 -0
  843. package/extensions/dm-mcp-adapter/dist/mcp-probe.js +151 -0
  844. package/extensions/dm-mcp-adapter/dist/mcp-tasks.js +300 -0
  845. package/extensions/dm-mcp-adapter/dist/mcp-trace.js +215 -0
  846. package/extensions/dm-mcp-adapter/dist/metadata-cache.js +10 -28
  847. package/extensions/dm-mcp-adapter/dist/npx-resolver.js +465 -0
  848. package/extensions/dm-mcp-adapter/dist/package-mcp-loader.js +5 -16
  849. package/extensions/dm-mcp-adapter/dist/request-headers-command.js +294 -0
  850. package/extensions/dm-mcp-adapter/dist/runtime-owner.js +94 -0
  851. package/extensions/dm-mcp-adapter/dist/sampling-handler.js +213 -0
  852. package/extensions/dm-mcp-adapter/dist/secure-keyring.js +191 -0
  853. package/extensions/dm-mcp-adapter/dist/server-manager.js +1514 -0
  854. package/extensions/dm-mcp-adapter/dist/session-approvals.js +127 -0
  855. package/extensions/dm-mcp-adapter/dist/session-recovery.js +82 -0
  856. package/extensions/dm-mcp-adapter/dist/state.js +1 -0
  857. package/extensions/dm-mcp-adapter/dist/types.js +39 -0
  858. package/extensions/dm-mcp-adapter/dist/ui-resource-handler.js +204 -0
  859. package/extensions/dm-mcp-adapter/dist/unix-socket-transport.js +83 -0
  860. package/extensions/dm-mcp-adapter/dist/utils.js +84 -9
  861. package/extensions/dm-mcp-adapter/elicitation-handler.js +27 -22
  862. package/extensions/dm-mcp-adapter/host-html-template.js +17 -18
  863. package/extensions/dm-mcp-adapter/http-ca.js +71 -0
  864. package/extensions/dm-mcp-adapter/index.js +904 -167
  865. package/extensions/dm-mcp-adapter/init.js +53 -42
  866. package/extensions/dm-mcp-adapter/jev-client.js +359 -0
  867. package/extensions/dm-mcp-adapter/jev-contracts.js +0 -0
  868. package/extensions/dm-mcp-adapter/jev-key-store.js +176 -0
  869. package/extensions/dm-mcp-adapter/json-schema-validator.js +19 -2
  870. package/extensions/dm-mcp-adapter/lazy-loader.js +7 -0
  871. package/extensions/dm-mcp-adapter/lifecycle.js +8 -3
  872. package/extensions/dm-mcp-adapter/mcp-auth-fetch.js +86 -0
  873. package/extensions/dm-mcp-adapter/mcp-auth-flow.js +228 -75
  874. package/extensions/dm-mcp-adapter/mcp-auth.js +312 -47
  875. package/extensions/dm-mcp-adapter/mcp-bearer-store.js +7 -136
  876. package/extensions/dm-mcp-adapter/mcp-code.js +151 -20
  877. package/extensions/dm-mcp-adapter/mcp-install.js +40 -0
  878. package/extensions/dm-mcp-adapter/mcp-oauth-provider.js +52 -8
  879. package/extensions/dm-mcp-adapter/mcp-output-guard.js +42 -43
  880. package/extensions/dm-mcp-adapter/mcp-panel-theme.js +79 -0
  881. package/extensions/dm-mcp-adapter/mcp-panel.js +294 -286
  882. package/extensions/dm-mcp-adapter/mcp-references.js +13 -18
  883. package/extensions/dm-mcp-adapter/mcp-script-worker.mjs +5 -1
  884. package/extensions/dm-mcp-adapter/mcp-setup-panel.js +317 -282
  885. package/extensions/dm-mcp-adapter/mcp-status.js +2 -0
  886. package/extensions/dm-mcp-adapter/mcp-tasks.js +309 -0
  887. package/extensions/dm-mcp-adapter/metadata-cache.js +11 -28
  888. package/extensions/dm-mcp-adapter/namespace-tools.js +43 -7
  889. package/extensions/dm-mcp-adapter/oauth.js +1 -1
  890. package/extensions/dm-mcp-adapter/package-mcp-loader.js +5 -16
  891. package/extensions/dm-mcp-adapter/package.json +4 -1
  892. package/extensions/dm-mcp-adapter/prompts.js +31 -4
  893. package/extensions/dm-mcp-adapter/proxy-modes.js +394 -199
  894. package/extensions/dm-mcp-adapter/request-headers-command.js +3 -2
  895. package/extensions/dm-mcp-adapter/runtime-owner.js +16 -1
  896. package/extensions/dm-mcp-adapter/sampling-handler.js +16 -25
  897. package/extensions/dm-mcp-adapter/sandbox-proxy-template.js +14 -90
  898. package/extensions/dm-mcp-adapter/search-ranking.js +31 -6
  899. package/extensions/dm-mcp-adapter/secure-keyring.js +191 -0
  900. package/extensions/dm-mcp-adapter/semantic-search.js +160 -0
  901. package/extensions/dm-mcp-adapter/server-manager.js +406 -117
  902. package/extensions/dm-mcp-adapter/session-approvals.js +127 -0
  903. package/extensions/dm-mcp-adapter/skills/mcp-scripting/SKILL.md +11 -1
  904. package/extensions/dm-mcp-adapter/test-runner.mjs +3 -4
  905. package/extensions/dm-mcp-adapter/tool-approval.js +32 -22
  906. package/extensions/dm-mcp-adapter/tool-metadata.js +18 -11
  907. package/extensions/dm-mcp-adapter/tool-registrar.js +7 -4
  908. package/extensions/dm-mcp-adapter/tool-result-renderer.js +4 -2
  909. package/extensions/dm-mcp-adapter/types.js +39 -0
  910. package/extensions/dm-mcp-adapter/ui-server.js +51 -36
  911. package/extensions/dm-mcp-adapter/ui-session.js +57 -25
  912. package/extensions/dm-mcp-adapter/utils.js +84 -9
  913. package/extensions/dm-ponytail/hooks/cursor-hooks.json +17 -0
  914. package/extensions/dm-ponytail/hooks/ponytail-activate.js +14 -2
  915. package/extensions/dm-ponytail/hooks/ponytail-mode-tracker.js +21 -2
  916. package/extensions/dm-ponytail/hooks/ponytail-runtime.js +23 -0
  917. package/extensions/dm-ponytail/package.json +1 -1
  918. package/extensions/dm-subagents/agents/claude-code-writer.md +1 -0
  919. package/extensions/dm-subagents/agents/codex-exec-writer.md +1 -0
  920. package/extensions/dm-subagents/agents/cursor-agent-writer.md +1 -0
  921. package/extensions/dm-subagents/agents/evidence-auditor.md +34 -0
  922. package/extensions/dm-subagents/agents/researcher.md +23 -13
  923. package/extensions/dm-subagents/agents/reviewer.md +6 -4
  924. package/extensions/dm-subagents/agents/scout.md +1 -1
  925. package/extensions/dm-subagents/agents/worker.md +3 -2
  926. package/extensions/dm-subagents/index.js +3 -2
  927. package/extensions/dm-subagents/inspector-runner.mjs +2 -2
  928. package/extensions/dm-subagents/install.mjs +1 -2
  929. package/extensions/dm-subagents/package.json +35 -1
  930. package/extensions/dm-subagents/prompts/council.md +6 -3
  931. package/extensions/dm-subagents/prompts/parallel-review.md +1 -1
  932. package/extensions/dm-subagents/runner-peer-loader.mjs +18 -0
  933. package/extensions/dm-subagents/runner-peer-preload.mjs +29 -0
  934. package/extensions/dm-subagents/skills/dm-subagents/SKILL.md +35 -22
  935. package/extensions/dm-subagents/skills/dm-subagents/references/constraints-and-recipes.md +9 -5
  936. package/extensions/dm-subagents/skills/dm-subagents/references/execution-controls.md +40 -19
  937. package/extensions/dm-subagents/skills/dm-subagents/references/management-authoring-rpc.md +6 -6
  938. package/extensions/dm-subagents/skills/dm-subagents/references/multi-lane-orchestration.md +11 -1
  939. package/extensions/dm-subagents/skills/dm-subagents/references/prompting-and-roles.md +35 -30
  940. package/extensions/dm-subagents/skills/dm-subagents/references/review-and-validation.md +3 -3
  941. package/extensions/dm-subagents/src/agents/advertised-agent-prompt.js +70 -0
  942. package/extensions/dm-subagents/src/agents/agent-management.js +276 -172
  943. package/extensions/dm-subagents/src/agents/agent-memory.js +92 -3
  944. package/extensions/dm-subagents/src/agents/agent-serializer.js +17 -8
  945. package/extensions/dm-subagents/src/agents/agents.js +389 -207
  946. package/extensions/dm-subagents/src/agents/builtin-names.js +1 -0
  947. package/extensions/dm-subagents/src/agents/chain-serializer.js +7 -0
  948. package/extensions/dm-subagents/src/agents/global-npm-root.js +47 -0
  949. package/extensions/dm-subagents/src/agents/proactive-skills.js +1 -1
  950. package/extensions/dm-subagents/src/agents/runtime-agent-registry.js +17 -13
  951. package/extensions/dm-subagents/src/agents/skills.js +36 -10
  952. package/extensions/dm-subagents/src/api/capability-ceiling.js +0 -1
  953. package/extensions/dm-subagents/src/api/child-tool-plan.js +3 -0
  954. package/extensions/dm-subagents/src/api/preflight.js +75 -64
  955. package/extensions/dm-subagents/src/api/required-child-extensions.js +3 -0
  956. package/extensions/dm-subagents/src/api/workflow-resources.js +1 -0
  957. package/extensions/dm-subagents/src/extension/config.js +27 -18
  958. package/extensions/dm-subagents/src/extension/doctor.js +10 -13
  959. package/extensions/dm-subagents/src/extension/fanout-child.js +91 -14
  960. package/extensions/dm-subagents/src/extension/herdr-dm-bridge.js +258 -0
  961. package/extensions/dm-subagents/src/extension/index.js +202 -66
  962. package/extensions/dm-subagents/src/extension/public-execution.js +55 -4
  963. package/extensions/dm-subagents/src/extension/rpc.js +18 -27
  964. package/extensions/dm-subagents/src/extension/schemas.js +99 -84
  965. package/extensions/dm-subagents/src/extension/subagent-guide.js +14 -3
  966. package/extensions/dm-subagents/src/extension/tool-activation.js +157 -0
  967. package/extensions/dm-subagents/src/extension/tool-description.js +30 -78
  968. package/extensions/dm-subagents/src/inspectors/actions.js +145 -0
  969. package/extensions/dm-subagents/src/inspectors/ghostty/actions.js +60 -0
  970. package/extensions/dm-subagents/src/inspectors/ghostty/plugin.js +17 -0
  971. package/extensions/dm-subagents/src/inspectors/herdr/actions.js +94 -179
  972. package/extensions/dm-subagents/src/inspectors/herdr/plugin.js +13 -0
  973. package/extensions/dm-subagents/src/inspectors/herdr/project-panes.js +1 -1
  974. package/extensions/dm-subagents/src/inspectors/{herdr/inspector-runner.js → inspector-runner.js} +31 -25
  975. package/extensions/dm-subagents/src/inspectors/plugins.js +5 -0
  976. package/extensions/dm-subagents/src/inspectors/{herdr/session-roots-codec.js → session-roots-codec.js} +1 -6
  977. package/extensions/dm-subagents/src/inspectors/types.js +1 -0
  978. package/extensions/dm-subagents/src/integrations/dm-web-session-liveness.js +50 -0
  979. package/extensions/dm-subagents/src/intercom/intercom-bridge.js +39 -5
  980. package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +256 -151
  981. package/extensions/dm-subagents/src/intercom/result-intercom.js +6 -0
  982. package/extensions/dm-subagents/src/intercom/supervisor-ui.js +199 -0
  983. package/extensions/dm-subagents/src/missions/workflow-state.js +30 -17
  984. package/extensions/dm-subagents/src/policy/authority.js +6 -2
  985. package/extensions/dm-subagents/src/profiles/profiles.js +10 -5
  986. package/extensions/dm-subagents/src/runs/background/active-async-capacity.js +28 -35
  987. package/extensions/dm-subagents/src/runs/background/active-run-index.js +17 -0
  988. package/extensions/dm-subagents/src/runs/background/async-execution.js +580 -389
  989. package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +71 -47
  990. package/extensions/dm-subagents/src/runs/background/async-resume.js +61 -26
  991. package/extensions/dm-subagents/src/runs/background/async-retention.js +8 -0
  992. package/extensions/dm-subagents/src/runs/background/async-status-snapshot.js +3 -4
  993. package/extensions/dm-subagents/src/runs/background/async-status.js +90 -13
  994. package/extensions/dm-subagents/src/runs/background/auto-drain.js +57 -33
  995. package/extensions/dm-subagents/src/runs/background/binary-bootstrap.js +54 -0
  996. package/extensions/dm-subagents/src/runs/background/chain-append.js +1 -1
  997. package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +11 -27
  998. package/extensions/dm-subagents/src/runs/background/control-channel.js +105 -256
  999. package/extensions/dm-subagents/src/runs/background/fleet-view.js +67 -10
  1000. package/extensions/dm-subagents/src/runs/background/notify.js +252 -17
  1001. package/extensions/dm-subagents/src/runs/background/owned-process-tree.js +33 -2
  1002. package/extensions/dm-subagents/src/runs/background/process-terminal-candidate.js +88 -0
  1003. package/extensions/dm-subagents/src/runs/background/process-terminal.js +29 -87
  1004. package/extensions/dm-subagents/src/runs/background/result-files.js +8 -4
  1005. package/extensions/dm-subagents/src/runs/background/result-watcher.js +15 -3
  1006. package/extensions/dm-subagents/src/runs/background/retained-children.js +3 -2
  1007. package/extensions/dm-subagents/src/runs/background/retained-nested-route-tracker.js +86 -0
  1008. package/extensions/dm-subagents/src/runs/background/run-child-session.js +574 -0
  1009. package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +9 -5
  1010. package/extensions/dm-subagents/src/runs/background/run-status.js +114 -11
  1011. package/extensions/dm-subagents/src/runs/background/runner-aliases.js +129 -0
  1012. package/extensions/dm-subagents/src/runs/background/runner-child-launch.js +62 -0
  1013. package/extensions/dm-subagents/src/runs/background/runner-child-sessions.js +16 -0
  1014. package/extensions/dm-subagents/src/runs/background/runner-http-dispatcher.js +84 -0
  1015. package/extensions/dm-subagents/src/runs/background/runner-startup-failure.js +43 -0
  1016. package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +119 -20
  1017. package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +33 -10
  1018. package/extensions/dm-subagents/src/runs/background/steering.js +24 -3
  1019. package/extensions/dm-subagents/src/runs/background/subagent-runner-bootstrap.js +238 -0
  1020. package/extensions/dm-subagents/src/runs/background/subagent-runner.js +1008 -1344
  1021. package/extensions/dm-subagents/src/runs/background/subagent-wait.js +156 -26
  1022. package/extensions/dm-subagents/src/runs/background/wait-completions.js +91 -23
  1023. package/extensions/dm-subagents/src/runs/background/wait-subscriptions.js +10 -3
  1024. package/extensions/dm-subagents/src/runs/background/wait-tool.js +8 -12
  1025. package/extensions/dm-subagents/src/runs/background/workflow-terminal-proof.js +60 -0
  1026. package/extensions/dm-subagents/src/runs/foreground/async-steering-action.js +29 -26
  1027. package/extensions/dm-subagents/src/runs/foreground/async-stop-action.js +94 -2
  1028. package/extensions/dm-subagents/src/runs/foreground/execution.js +446 -648
  1029. package/extensions/dm-subagents/src/runs/foreground/foreground-control.js +4 -0
  1030. package/extensions/dm-subagents/src/runs/foreground/foreground-history.js +5 -2
  1031. package/extensions/dm-subagents/src/runs/foreground/prompt-audit.js +8 -4
  1032. package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +1337 -445
  1033. package/extensions/dm-subagents/src/runs/foreground/workflow-detach-reconcile.js +10 -5
  1034. package/extensions/dm-subagents/src/runs/foreground/workflow-foreground-steering.js +65 -90
  1035. package/extensions/dm-subagents/src/runs/shared/acceptance.js +265 -68
  1036. package/extensions/dm-subagents/src/runs/shared/agent-contract.js +1 -1
  1037. package/extensions/dm-subagents/src/runs/shared/async-status-projection.js +133 -76
  1038. package/extensions/dm-subagents/src/runs/shared/capability-ceiling.js +4 -2
  1039. package/extensions/dm-subagents/src/runs/shared/child-hooks.js +166 -0
  1040. package/extensions/dm-subagents/src/runs/shared/child-identity.js +10 -2
  1041. package/extensions/dm-subagents/src/runs/shared/child-launch-plan.js +19 -2
  1042. package/extensions/dm-subagents/src/runs/shared/child-launch.js +212 -0
  1043. package/extensions/dm-subagents/src/runs/shared/child-lifecycle.js +22 -0
  1044. package/extensions/dm-subagents/src/runs/shared/child-runtime-config.js +31 -0
  1045. package/extensions/dm-subagents/src/runs/shared/child-session.js +378 -0
  1046. package/extensions/dm-subagents/src/runs/shared/child-tool-plan.js +299 -0
  1047. package/extensions/dm-subagents/src/runs/shared/claude-code-adapter.js +1 -1
  1048. package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +148 -32
  1049. package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +6 -4
  1050. package/extensions/dm-subagents/src/runs/shared/effective-system-prompt.js +19 -0
  1051. package/extensions/dm-subagents/src/runs/shared/external-cli-contract.js +6 -1
  1052. package/extensions/dm-subagents/src/runs/shared/external-cli-preflight.js +14 -2
  1053. package/extensions/dm-subagents/src/runs/shared/external-cli-runner.js +6 -7
  1054. package/extensions/dm-subagents/src/runs/shared/external-job-bridge.js +60 -0
  1055. package/extensions/dm-subagents/src/runs/shared/git-environment.js +25 -0
  1056. package/extensions/dm-subagents/src/runs/shared/herdr-connection.js +341 -0
  1057. package/extensions/dm-subagents/src/runs/shared/herdr-dm-protocol.js +60 -0
  1058. package/extensions/dm-subagents/src/runs/shared/herdr-external-adapters.js +555 -0
  1059. package/extensions/dm-subagents/src/runs/shared/herdr-machine.js +239 -0
  1060. package/extensions/dm-subagents/src/runs/shared/herdr-placed-run.js +987 -0
  1061. package/extensions/dm-subagents/src/runs/shared/host-step-status.js +2 -0
  1062. package/extensions/dm-subagents/src/runs/shared/lane-metadata.js +23 -3
  1063. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +4 -3
  1064. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-grant.js +15 -5
  1065. package/extensions/dm-subagents/src/runs/shared/model-resolution-diagnostic.js +43 -0
  1066. package/extensions/dm-subagents/src/runs/shared/{model-fallback.js → model-resolution.js} +44 -128
  1067. package/extensions/dm-subagents/src/runs/shared/nested-events.js +39 -49
  1068. package/extensions/dm-subagents/src/runs/shared/nested-path.js +0 -13
  1069. package/extensions/dm-subagents/src/runs/shared/orca-progress-tabs.js +22 -12
  1070. package/extensions/dm-subagents/src/runs/shared/parallel-handoff.js +78 -2
  1071. package/extensions/dm-subagents/src/runs/shared/permissions.js +1 -16
  1072. package/extensions/dm-subagents/src/runs/shared/process-signal.js +3 -0
  1073. package/extensions/dm-subagents/src/runs/shared/readonly-drain-observation.js +51 -0
  1074. package/extensions/dm-subagents/src/runs/shared/run-fanout-budget.js +0 -13
  1075. package/extensions/dm-subagents/src/runs/shared/runtime-acknowledged-extensions.js +0 -26
  1076. package/extensions/dm-subagents/src/runs/shared/single-output.js +20 -2
  1077. package/extensions/dm-subagents/src/runs/shared/structured-output.js +263 -10
  1078. package/extensions/dm-subagents/src/runs/shared/subagent-control.js +6 -14
  1079. package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +117 -370
  1080. package/extensions/dm-subagents/src/runs/shared/tool-availability.js +12 -50
  1081. package/extensions/dm-subagents/src/runs/shared/tool-budget.js +10 -13
  1082. package/extensions/dm-subagents/src/runs/shared/tool-timeout.js +1 -1
  1083. package/extensions/dm-subagents/src/runs/shared/usage-reconciliation.js +69 -0
  1084. package/extensions/dm-subagents/src/runs/shared/workflow-async-child-guidance.js +11 -0
  1085. package/extensions/dm-subagents/src/runs/shared/worktree-cleanup-plan.js +30 -10
  1086. package/extensions/dm-subagents/src/runs/shared/worktree-setup-command.js +195 -0
  1087. package/extensions/dm-subagents/src/runs/shared/worktree.js +814 -141
  1088. package/extensions/dm-subagents/src/shared/atomic-json.js +2 -1
  1089. package/extensions/dm-subagents/src/shared/child-cache-retention.js +19 -0
  1090. package/extensions/dm-subagents/src/shared/fork-context.js +40 -77
  1091. package/extensions/dm-subagents/src/shared/fork-session-cwd.js +24 -0
  1092. package/extensions/dm-subagents/src/shared/jsonl-writer.js +8 -0
  1093. package/extensions/dm-subagents/src/shared/launch-contract.js +37 -6
  1094. package/extensions/dm-subagents/src/shared/model-response-aliases.js +15 -0
  1095. package/extensions/dm-subagents/src/shared/opencode-session-headers.js +15 -0
  1096. package/extensions/dm-subagents/src/shared/pruned-fork.js +83 -76
  1097. package/extensions/dm-subagents/src/shared/required-child-extensions.js +72 -0
  1098. package/extensions/dm-subagents/src/shared/shortcuts.js +0 -2
  1099. package/extensions/dm-subagents/src/shared/thinking-ceiling.js +0 -6
  1100. package/extensions/dm-subagents/src/shared/types.js +16 -12
  1101. package/extensions/dm-subagents/src/shared/utils.js +22 -7
  1102. package/extensions/dm-subagents/src/shared/watch-strategy.js +2 -0
  1103. package/extensions/dm-subagents/src/shared/workflow-child-permit.js +70 -0
  1104. package/extensions/dm-subagents/src/slash/delegation-adapters.js +15 -1
  1105. package/extensions/dm-subagents/src/slash/delegation-request.js +13 -0
  1106. package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +28 -1
  1107. package/extensions/dm-subagents/src/slash/prompt-workflows.js +15 -2
  1108. package/extensions/dm-subagents/src/slash/slash-commands.js +12 -269
  1109. package/extensions/dm-subagents/src/slash/subagent-cost.js +255 -0
  1110. package/extensions/dm-subagents/src/slash/subagents-admin.js +49 -25
  1111. package/extensions/dm-subagents/src/tui/fleet-status.js +224 -23
  1112. package/extensions/dm-subagents/src/tui/fleet.js +38 -25
  1113. package/extensions/dm-subagents/src/tui/render.js +636 -63
  1114. package/extensions/dm-subagents/src/watchdog/child-status.js +42 -23
  1115. package/extensions/dm-subagents/src/watchdog/diff-tool.js +86 -0
  1116. package/extensions/dm-subagents/src/watchdog/emission-guard.js +4 -3
  1117. package/extensions/dm-subagents/src/watchdog/guidance.js +19 -0
  1118. package/extensions/dm-subagents/src/watchdog/lsp-diagnostics.js +1 -1
  1119. package/extensions/dm-subagents/src/watchdog/model-selection.js +18 -1
  1120. package/extensions/dm-subagents/src/watchdog/permission-arbiter.js +16 -10
  1121. package/extensions/dm-subagents/src/watchdog/register-child.js +39 -26
  1122. package/extensions/dm-subagents/src/watchdog/register-main.js +51 -43
  1123. package/extensions/dm-subagents/src/watchdog/render.js +5 -7
  1124. package/extensions/dm-subagents/src/watchdog/review.js +142 -67
  1125. package/extensions/dm-subagents/src/watchdog/rules.js +55 -0
  1126. package/extensions/dm-subagents/src/watchdog/runtime.js +167 -109
  1127. package/extensions/dm-subagents/src/watchdog/scope.js +1 -9
  1128. package/extensions/dm-subagents/src/watchdog/settings.js +55 -99
  1129. package/extensions/dm-subagents/src/watchdog/tool-actions.js +11 -12
  1130. package/extensions/dm-subagents/src/watchdog/turn-delta.js +30 -5
  1131. package/extensions/dm-subagents/src/watchdog/types.js +2 -4
  1132. package/extensions/dm-subagents/src/watchdog/warning-format.js +2 -3
  1133. package/extensions/dm-subagents/src/workflows/chat-progress.js +4 -4
  1134. package/extensions/dm-subagents/src/workflows/scripted-workflow.js +482 -36
  1135. package/extensions/dm-subagents/src/workflows/workflow-checklist.js +303 -0
  1136. package/extensions/dm-subagents/src/workflows/workflow-child-summary.js +57 -5
  1137. package/extensions/dm-subagents/src/workflows/workflow-preflight.js +27 -1
  1138. package/extensions/dm-subagents/src/workflows/workflow-receipt.js +51 -3
  1139. package/extensions/dm-subagents/src/workflows/workflow-resources.js +226 -0
  1140. package/extensions/dm-subagents/src/workflows/workflow-settlement.js +5 -0
  1141. package/extensions/dm-web-access/abortable.js +19 -0
  1142. package/extensions/dm-web-access/anysearch.js +4 -13
  1143. package/extensions/dm-web-access/baizhi.js +123 -0
  1144. package/extensions/dm-web-access/bocha.js +3 -24
  1145. package/extensions/dm-web-access/brave.js +3 -23
  1146. package/extensions/dm-web-access/brightdata.js +5 -30
  1147. package/extensions/dm-web-access/content-find.js +181 -47
  1148. package/extensions/dm-web-access/crawl4ai.js +166 -0
  1149. package/extensions/dm-web-access/credential-source.js +1 -0
  1150. package/extensions/dm-web-access/curator-page.js +27 -2
  1151. package/extensions/dm-web-access/curator-run.js +36 -0
  1152. package/extensions/dm-web-access/curator-server.js +11 -2
  1153. package/extensions/dm-web-access/domain-filter-normalization.js +17 -0
  1154. package/extensions/dm-web-access/duckduckgo.js +4 -24
  1155. package/extensions/dm-web-access/extract.js +54 -12
  1156. package/extensions/dm-web-access/fetch-params.js +1 -1
  1157. package/extensions/dm-web-access/firecrawl.js +7 -45
  1158. package/extensions/dm-web-access/gemini-search.js +101 -46
  1159. package/extensions/dm-web-access/github-extract.js +2 -11
  1160. package/extensions/dm-web-access/index.js +382 -247
  1161. package/extensions/dm-web-access/jina-search.js +4 -13
  1162. package/extensions/dm-web-access/kagi.js +4 -13
  1163. package/extensions/dm-web-access/kimi-search.js +5 -30
  1164. package/extensions/dm-web-access/mistral-search.js +251 -0
  1165. package/extensions/dm-web-access/ollama.js +2 -7
  1166. package/extensions/dm-web-access/openai-search.js +204 -46
  1167. package/extensions/dm-web-access/opencode-session-headers.js +15 -0
  1168. package/extensions/dm-web-access/package.json +1 -1
  1169. package/extensions/dm-web-access/page-query.js +14 -4
  1170. package/extensions/dm-web-access/parallel.js +1 -17
  1171. package/extensions/dm-web-access/pdf-extract.js +1 -0
  1172. package/extensions/dm-web-access/perplexity.js +10 -1
  1173. package/extensions/dm-web-access/querit.js +5 -34
  1174. package/extensions/dm-web-access/query-rewrite.js +6 -2
  1175. package/extensions/dm-web-access/search-answer-formatting.js +6 -0
  1176. package/extensions/dm-web-access/search-result-count-normalization.js +5 -0
  1177. package/extensions/dm-web-access/search1api.js +5 -34
  1178. package/extensions/dm-web-access/searchinfinity.js +5 -34
  1179. package/extensions/dm-web-access/searxng.js +3 -23
  1180. package/extensions/dm-web-access/serpapi.js +183 -0
  1181. package/extensions/dm-web-access/serpbase.js +3 -24
  1182. package/extensions/dm-web-access/serpdive.js +3 -23
  1183. package/extensions/dm-web-access/serper.js +5 -30
  1184. package/extensions/dm-web-access/serply.js +184 -0
  1185. package/extensions/dm-web-access/source-check.js +10 -46
  1186. package/extensions/dm-web-access/ssrf-protection.js +3 -1
  1187. package/extensions/dm-web-access/storage.js +9 -0
  1188. package/extensions/dm-web-access/summary-review.js +36 -25
  1189. package/extensions/dm-web-access/tavily.js +3 -23
  1190. package/extensions/dm-web-access/tinyfish.js +5 -34
  1191. package/extensions/dm-web-access/tool-activation.js +112 -0
  1192. package/extensions/dm-web-access/utils.js +27 -10
  1193. package/extensions/dm-web-access/valyu.js +5 -30
  1194. package/extensions/dm-web-access/xai-search.js +78 -42
  1195. package/extensions/dm-web-access/xcrawl.js +5 -30
  1196. package/package.json +7 -4
  1197. package/extensions/dm-lens/tools/ast-dump.js +0 -101
  1198. package/extensions/dm-subagents/src/api/dm-args.js +0 -3
  1199. package/extensions/dm-subagents/src/runs/shared/child-protocol.js +0 -447
  1200. package/extensions/dm-subagents/src/runs/shared/completion-evidence.js +0 -40
  1201. package/extensions/dm-subagents/src/runs/shared/completion-guard.js +0 -173
  1202. package/extensions/dm-subagents/src/runs/shared/dm-args.js +0 -581
  1203. package/extensions/dm-subagents/src/runs/shared/llm-intent-arbiter.js +0 -190
  1204. package/extensions/dm-subagents/src/runs/shared/model-exclusions.js +0 -207
  1205. package/extensions/dm-subagents/src/runs/shared/subagent-startup-retry.js +0 -50
  1206. package/extensions/dm-subagents/src/runs/shared/task-intent.js +0 -130
  1207. package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +0 -68
  1208. /package/extensions/dm-subagents/src/inspectors/{herdr/shell-command.js → shell-command.js} +0 -0
@@ -0,0 +1,2709 @@
1
+ import { spawn as nodeSpawn } from "node:child_process";
2
+ import { EventEmitter } from "node:events";
3
+ import { access, lstat, readFile } from "node:fs/promises";
4
+ import * as os from "node:os";
5
+ import { pathToFileURL } from "node:url";
6
+ import { emitBounded } from "../bounded-telemetry.js";
7
+ import { withTimeout } from "../deadline-utils.js";
8
+ import { minimatch } from "../deps/minimatch.js";
9
+ import { mapWithConcurrency } from "../map-with-concurrency.js";
10
+ import { incrementDegradationCount, recordDegradationOnce } from "../degradation-ledger.js";
11
+ import { CancellationTokenSource, createMessageConnection, StreamMessageReader, StreamMessageWriter } from "../deps/vscode-jsonrpc.js";
12
+ import { logExtension } from "../extension-log.js";
13
+ import { recordLspChild, removeLspChild } from "../instance-registry.js";
14
+ import { workspaceDiagnosticsCacheSessionStart } from "./workspace-diagnostics-session.js";
15
+ import { logLatency } from "../latency-logger.js";
16
+ import { newLspMutationCorrelationId } from "../lsp-mutation.js";
17
+ import { getProcessSingleton } from "../process-singletons.js";
18
+ import { getAmbientAbortSignal, isOwnLiveChild, releaseOwnChildPid } from "../safe-spawn.js";
19
+ import { raceToCompletion } from "./aggregation.js";
20
+ import { hashDiagnosticContent } from "./diagnostic-binding.js";
21
+ import { applyWorkspaceEdit, normalizeWorkspaceEditToUtf16 } from "./edits.js";
22
+ import { normalizeMapKey, uriToPath } from "./path-utils.js";
23
+ import { ADVERTISED_POSITION_ENCODINGS, convertCharacterOffset, lineTextAt, negotiatePositionEncoding } from "./position-encoding.js";
24
+ import { negotiateSaveOptions, negotiateSyncKind, TEXT_DOCUMENT_SYNC_KIND_FULL, TEXT_DOCUMENT_SYNC_KIND_INCREMENTAL } from "./sync-kind.js";
25
+ import { exceedsLspSyncLimits } from "./content-limits.js";
26
+ import { probeTsserverProjectIdentity } from "./tsserver-sync.js";
27
+ import { getStrategy } from "./wait-policy/index.js";
28
+ import { WatchedFilesQueue } from "./watch-queue.js";
29
+ import { clearAllWorkspaceDiagnosticsCaches, clearWorkspaceDiagnosticsCacheAtAndAbove } from "./workspace-diagnostics-cache.js";
30
+ const PUB_DEBUG = Boolean(process.env.PILENS_PUB_DEBUG);
31
+ function extractSpawnMarker(args) {
32
+ if (!args)
33
+ return;
34
+ const tmpDir = os.tmpdir();
35
+ for (let i = 0;i < args.length - 1; i++) {
36
+ const flag = args[i];
37
+ if (flag === "--config" || flag === "-c") {
38
+ const value = args[i + 1];
39
+ if (value?.startsWith(tmpDir))
40
+ return value;
41
+ }
42
+ }
43
+ return;
44
+ }
45
+ export const INITIALIZE_TIMEOUT_MS = positiveIntFromEnv("DM_LENS_LSP_INIT_TIMEOUT_MS", 15000);
46
+ export const CLIENT_CAPABILITIES = {
47
+ general: { positionEncodings: ADVERTISED_POSITION_ENCODINGS },
48
+ window: {},
49
+ workspace: {
50
+ workspaceFolders: true,
51
+ configuration: true,
52
+ didChangeWatchedFiles: { dynamicRegistration: true },
53
+ fileOperations: {
54
+ dynamicRegistration: false,
55
+ willRename: true,
56
+ didRename: true
57
+ }
58
+ },
59
+ textDocument: {
60
+ synchronization: {
61
+ dynamicRegistration: false,
62
+ willSave: false,
63
+ willSaveWaitUntil: false,
64
+ didSave: true
65
+ },
66
+ completion: {
67
+ dynamicRegistration: false,
68
+ completionItem: { snippetSupport: false }
69
+ },
70
+ hover: { dynamicRegistration: false },
71
+ signatureHelp: { dynamicRegistration: false },
72
+ definition: { dynamicRegistration: false },
73
+ typeDefinition: { dynamicRegistration: false },
74
+ implementation: { dynamicRegistration: false },
75
+ references: { dynamicRegistration: false },
76
+ documentSymbol: { dynamicRegistration: false },
77
+ codeAction: {
78
+ dynamicRegistration: false,
79
+ dataSupport: true,
80
+ resolveSupport: { properties: ["edit", "command"] },
81
+ codeActionLiteralSupport: {
82
+ codeActionKind: {
83
+ valueSet: [
84
+ "quickfix",
85
+ "refactor",
86
+ "refactor.extract",
87
+ "refactor.inline",
88
+ "refactor.rewrite",
89
+ "source",
90
+ "source.organizeImports"
91
+ ]
92
+ }
93
+ }
94
+ },
95
+ rename: { dynamicRegistration: false },
96
+ publishDiagnostics: {
97
+ relatedInformation: true,
98
+ versionSupport: true
99
+ }
100
+ }
101
+ };
102
+ const NAV_REQUEST_TIMEOUT_MS = positiveIntFromEnv("DM_LENS_LSP_NAV_REQUEST_TIMEOUT_MS", 1e4);
103
+ const DIAGNOSTICS_WAIT_TIMEOUT_MS = positiveIntFromEnv("DM_LENS_LSP_DIAGNOSTICS_WAIT_MS", 1e4);
104
+ const PULL_DIAGNOSTICS_RETRY_INTERVAL_MS = positiveIntFromEnv("DM_LENS_LSP_PULL_RETRY_INTERVAL_MS", 250);
105
+ const PULL_REQUEST_TIMEOUT_MS = positiveIntFromEnv("DM_LENS_LSP_PULL_REQUEST_TIMEOUT_MS", 1e4);
106
+ const PULL_MIN_USABLE_BUDGET_MS = 5;
107
+ const SHUTDOWN_REQUEST_TIMEOUT_MS = positiveIntFromEnv("DM_LENS_LSP_SHUTDOWN_TIMEOUT_MS", 1000);
108
+ const EXIT_NOTIFY_TIMEOUT_MS = positiveIntFromEnv("DM_LENS_LSP_EXIT_NOTIFY_TIMEOUT_MS", 1000);
109
+ const LIVENESS_PING_TIMEOUT_MS = positiveIntFromEnv("DM_LENS_LSP_LIVENESS_PING_TIMEOUT_MS", 300);
110
+ const LIVENESS_PING_QUERY = "__dm_lens_liveness_ping__";
111
+ const WORKSPACE_PULL_RESULT_CACHE_MAX = 4096;
112
+ const WORKSPACE_PULL_SCOPE = "*workspace*";
113
+ const REFRESH_REPULL_CONCURRENCY = 4;
114
+ const EXECUTE_COMMAND_TIMEOUT_MS = positiveIntFromEnv("DM_LENS_LSP_EXECUTE_COMMAND_TIMEOUT_MS", 30000);
115
+ const PROBE_COMMAND_TIMEOUT_MS = positiveIntFromEnv("DM_LENS_LSP_PROJECT_IDENTITY_PROBE_TIMEOUT_MS", 2500);
116
+ const LSP_CRASH_CODES = new Set([
117
+ "ERR_STREAM_DESTROYED",
118
+ "ERR_STREAM_WRITE_AFTER_END",
119
+ "EPIPE",
120
+ "ECONNRESET"
121
+ ]);
122
+ let crashGuardInstalled = false;
123
+ function isIgnorableLspRuntimeCrash(err) {
124
+ if (!(err instanceof Error))
125
+ return false;
126
+ const code = err.code;
127
+ if (code && LSP_CRASH_CODES.has(code))
128
+ return true;
129
+ const msg = err.message.toLowerCase();
130
+ const stack = (err.stack ?? "").toLowerCase();
131
+ return msg.includes("stream") || msg.includes("write after end") || stack.includes("vscode-jsonrpc/lib/node/ril.js");
132
+ }
133
+ function installCrashGuard() {
134
+ if (crashGuardInstalled)
135
+ return;
136
+ crashGuardInstalled = true;
137
+ process.on("uncaughtException", (err) => {
138
+ if (isIgnorableLspRuntimeCrash(err)) {
139
+ return;
140
+ }
141
+ throw err;
142
+ });
143
+ process.on("unhandledRejection", (reason) => {
144
+ if (isIgnorableLspRuntimeCrash(reason)) {
145
+ return;
146
+ }
147
+ throw reason instanceof Error ? reason : new Error(String(reason));
148
+ });
149
+ }
150
+ export const MAX_INCREMENTAL_TEXT_RETAINED_ENTRIES = 128;
151
+ export const MAX_INCREMENTAL_TEXT_RETAINED_BYTES = 64 * 1024 * 1024;
152
+ const ACTIVE_CLIENTS_FAMILY = "lsp-client.active-clients";
153
+ const ACTIVE_CLIENTS_VERSION = 1;
154
+ function activeLspClientSet() {
155
+ return getProcessSingleton(ACTIVE_CLIENTS_FAMILY, ACTIVE_CLIENTS_VERSION, () => new Set);
156
+ }
157
+ export function getLspDocumentTextRetentionSnapshot() {
158
+ let entries = 0;
159
+ let bytes = 0;
160
+ const roots = new Set;
161
+ const active = activeLspClientSet();
162
+ for (const state of active) {
163
+ entries += state.incrementalTextRetainedEntries ?? 0;
164
+ bytes += state.incrementalTextRetainedBytes ?? 0;
165
+ if (typeof state.root === "string" && state.root.length > 0) {
166
+ roots.add(state.root);
167
+ }
168
+ }
169
+ return { clients: active.size, entries, bytes, roots: roots.size };
170
+ }
171
+ function isClientAlive(state) {
172
+ return state.isConnected && !state.isDestroyed && !state.lspProcess.process.killed;
173
+ }
174
+ function disposeClientConnection(state) {
175
+ if (state.connectionDisposed)
176
+ return;
177
+ state.connectionDisposed = true;
178
+ activeLspClientSet().delete(state);
179
+ try {
180
+ state.connection.dispose();
181
+ } catch {}
182
+ }
183
+ export async function killProcessTree(proc, pid, options = {}) {
184
+ if ((proc.exitCode != null || proc.signalCode != null) && !options.processExiting) {
185
+ releaseOwnChildPid(pid);
186
+ proc.unref?.();
187
+ return;
188
+ }
189
+ if (process.platform === "win32" && pid > 0) {
190
+ if (options.processExiting) {
191
+ try {
192
+ proc.kill();
193
+ } catch {}
194
+ proc.unref?.();
195
+ return;
196
+ }
197
+ try {
198
+ const taskkill = `${process.env.SystemRoot ?? "C:\\Windows"}\\System32\\taskkill.exe`;
199
+ const killer = nodeSpawn(taskkill, ["/F", "/T", "/PID", String(pid)], {
200
+ shell: false,
201
+ windowsHide: true,
202
+ stdio: "ignore",
203
+ detached: !!options.fast
204
+ });
205
+ if (options.fast) {
206
+ killer.unref();
207
+ proc.unref?.();
208
+ return;
209
+ }
210
+ await new Promise((resolve) => {
211
+ killer.once("close", () => resolve());
212
+ killer.once("error", (err) => {
213
+ logLatency({
214
+ type: "phase",
215
+ phase: "lsp_kill_escalation",
216
+ filePath: "",
217
+ durationMs: 0,
218
+ metadata: { pid, platform: "win32", taskkillError: String(err) }
219
+ });
220
+ resolve();
221
+ });
222
+ });
223
+ } catch (err) {
224
+ logLatency({
225
+ type: "phase",
226
+ phase: "lsp_kill_escalation",
227
+ filePath: "",
228
+ durationMs: 0,
229
+ metadata: { pid, platform: "win32", taskkillSpawnError: String(err) }
230
+ });
231
+ }
232
+ return;
233
+ }
234
+ const killPosixProcessGroup = (signal) => {
235
+ if (!isOwnLiveChild(pid, "lsp-stop-posix-group"))
236
+ return false;
237
+ try {
238
+ process.kill(-pid, signal);
239
+ return true;
240
+ } catch {
241
+ return false;
242
+ }
243
+ };
244
+ const killDirectChild = (signal) => {
245
+ try {
246
+ proc.kill(signal);
247
+ } catch {}
248
+ };
249
+ try {
250
+ let exited = proc.exitCode != null || proc.signalCode != null;
251
+ proc.once?.("exit", () => {
252
+ exited = true;
253
+ });
254
+ if (!killPosixProcessGroup("SIGTERM")) {
255
+ killDirectChild("SIGTERM");
256
+ }
257
+ if (options.fast) {
258
+ const timer = setTimeout(() => {
259
+ if (!exited) {
260
+ logLatency({
261
+ type: "phase",
262
+ phase: "lsp_kill_escalation",
263
+ filePath: "",
264
+ durationMs: 1500,
265
+ metadata: { pid, platform: "posix", method: "SIGKILL", fast: true }
266
+ });
267
+ if (!killPosixProcessGroup("SIGKILL")) {
268
+ killDirectChild("SIGKILL");
269
+ }
270
+ }
271
+ releaseOwnChildPid(pid);
272
+ }, 1500);
273
+ timer.unref?.();
274
+ proc.unref?.();
275
+ return;
276
+ }
277
+ const exitedInTime = await new Promise((resolve) => {
278
+ if (proc.exitCode != null || proc.signalCode != null) {
279
+ resolve(true);
280
+ return;
281
+ }
282
+ const onExit = () => {
283
+ clearTimeout(timer);
284
+ resolve(true);
285
+ };
286
+ const timer = setTimeout(() => {
287
+ proc.off?.("exit", onExit);
288
+ resolve(false);
289
+ }, 1500);
290
+ proc.once?.("exit", onExit);
291
+ });
292
+ if (!exitedInTime && !exited) {
293
+ logLatency({
294
+ type: "phase",
295
+ phase: "lsp_kill_escalation",
296
+ filePath: "",
297
+ durationMs: 1500,
298
+ metadata: { pid, platform: "posix", method: "SIGKILL", fast: false }
299
+ });
300
+ if (!killPosixProcessGroup("SIGKILL")) {
301
+ killDirectChild("SIGKILL");
302
+ }
303
+ }
304
+ releaseOwnChildPid(pid);
305
+ } catch {}
306
+ }
307
+ export function stripDiagnosticNoiseLines(message) {
308
+ const cleaned = message.split(/\r?\n/).filter((line) => {
309
+ const trimmed = line.trim();
310
+ if (/^for further information visit\b/i.test(trimmed))
311
+ return false;
312
+ if (/^https?:\/\/\S+$/i.test(trimmed))
313
+ return false;
314
+ return true;
315
+ }).join(`
316
+ `).trim();
317
+ return cleaned || message.trim() || message;
318
+ }
319
+ function normalizeLspDiagnostic(diagnostic) {
320
+ const message = stripDiagnosticNoiseLines(diagnostic.message);
321
+ return message === diagnostic.message ? diagnostic : { ...diagnostic, message };
322
+ }
323
+ function normalizeLspDiagnostics(diagnostics) {
324
+ return diagnostics.map(normalizeLspDiagnostic);
325
+ }
326
+ function mergeDiagnosticLists(...lists) {
327
+ const merged = [];
328
+ const seen = new Set;
329
+ for (const diagnostic of lists.flatMap((list) => list ?? [])) {
330
+ const key = [
331
+ diagnostic.range.start.line,
332
+ diagnostic.range.start.character,
333
+ diagnostic.range.end.line,
334
+ diagnostic.range.end.character,
335
+ diagnostic.code ?? "",
336
+ diagnostic.source ?? "",
337
+ diagnostic.message
338
+ ].join(":");
339
+ if (seen.has(key))
340
+ continue;
341
+ seen.add(key);
342
+ merged.push(diagnostic);
343
+ }
344
+ return merged;
345
+ }
346
+ function getMergedDiagnosticsForPath(state, normalizedPath) {
347
+ const legacy = state;
348
+ return mergeDiagnosticLists(state.pushDiagnostics?.get(normalizedPath) ?? legacy.diagnostics?.get(normalizedPath), state.documentPullDiagnostics?.get(normalizedPath));
349
+ }
350
+ const PULL_SOURCE_KEY_SEPARATOR = "\x00";
351
+ const BARE_PULL_SOURCE = "";
352
+ function pullSourceKey(normalizedPath, identifier) {
353
+ return identifier === undefined ? normalizedPath : `${normalizedPath}${PULL_SOURCE_KEY_SEPARATOR}${identifier}`;
354
+ }
355
+ function pullSourceKeysForPath(state, normalizedPath) {
356
+ const prefix = `${normalizedPath}${PULL_SOURCE_KEY_SEPARATOR}`;
357
+ return [
358
+ normalizedPath,
359
+ ...[...state.pullResultIds?.keys() ?? []].filter((key) => key.startsWith(prefix))
360
+ ];
361
+ }
362
+ function pullSourcesFor(state, normalizedPath) {
363
+ if (!state.documentPullDiagnosticsBySource) {
364
+ state.documentPullDiagnosticsBySource = new Map;
365
+ }
366
+ let sources = state.documentPullDiagnosticsBySource.get(normalizedPath);
367
+ if (!sources) {
368
+ sources = new Map;
369
+ state.documentPullDiagnosticsBySource.set(normalizedPath, sources);
370
+ }
371
+ return sources;
372
+ }
373
+ function pullSourceDiagnostics(state, normalizedPath, identifier) {
374
+ const sources = state.documentPullDiagnosticsBySource?.get(normalizedPath);
375
+ const stored = sources?.get(identifier ?? BARE_PULL_SOURCE);
376
+ if (stored)
377
+ return stored;
378
+ return sources && sources.size > 0 ? [] : state.documentPullDiagnostics.get(normalizedPath) ?? [];
379
+ }
380
+ function storePullSourceDiagnostics(state, normalizedPath, identifier, diagnostics) {
381
+ const sources = pullSourcesFor(state, normalizedPath);
382
+ sources.set(identifier ?? BARE_PULL_SOURCE, diagnostics);
383
+ state.documentPullDiagnostics.set(normalizedPath, mergeDiagnosticLists(...sources.values()));
384
+ }
385
+ function pullGenerationFor(state, normalizedPath) {
386
+ return state.pullGenerations?.get(normalizedPath) ?? 0;
387
+ }
388
+ function bumpPullGeneration(state, normalizedPath) {
389
+ if (!state.pullGenerations)
390
+ state.pullGenerations = new Map;
391
+ state.pullGenerations.set(normalizedPath, (state.pullGenerations.get(normalizedPath) ?? 0) + 1);
392
+ }
393
+ function claimPullRequestSequence(state, sourceKey) {
394
+ if (!state.pullRequestSequences)
395
+ state.pullRequestSequences = new Map;
396
+ const next = (state.pullRequestSequences.get(sourceKey) ?? 0) + 1;
397
+ state.pullRequestSequences.set(sourceKey, next);
398
+ return next;
399
+ }
400
+ function isNewestPullRequest(state, sourceKey, sequence) {
401
+ return (state.pullRequestSequences?.get(sourceKey) ?? 0) === sequence;
402
+ }
403
+ function retirePullSource(state, identifier) {
404
+ const suffix = `${PULL_SOURCE_KEY_SEPARATOR}${identifier}`;
405
+ for (const source of [state.pullResultIds, state.pullRequestSequences]) {
406
+ if (!source)
407
+ continue;
408
+ for (const key of source.keys()) {
409
+ if (key.endsWith(suffix))
410
+ source.delete(key);
411
+ }
412
+ }
413
+ for (const [normalizedPath, sources] of state.documentPullDiagnosticsBySource ?? []) {
414
+ if (!sources.delete(identifier))
415
+ continue;
416
+ state.documentPullDiagnostics.set(normalizedPath, mergeDiagnosticLists(...sources.values()));
417
+ bumpDiagnosticsVersion(state, normalizedPath);
418
+ state.diagnosticEmitter.emit("diagnostics", normalizedPath);
419
+ }
420
+ }
421
+ export function pullDiagnosticSources(state) {
422
+ const identifiers = new Set;
423
+ for (const registration of state.dynamicRegistrations?.values() ?? []) {
424
+ if (registration.method !== "textDocument/diagnostic")
425
+ continue;
426
+ if (registration.identifier)
427
+ identifiers.add(registration.identifier);
428
+ }
429
+ return [undefined, ...[...identifiers].sort((a, b) => a.localeCompare(b))];
430
+ }
431
+ export function bumpDiagnosticsVersion(state, normalizedPath) {
432
+ state.diagnosticsVersion += 1;
433
+ state.diagnosticsVersionsByPath?.set(normalizedPath, state.diagnosticsVersion);
434
+ }
435
+ export function diagnosticsVersionForPath(state, normalizedPath) {
436
+ return state.diagnosticsVersionsByPath?.get(normalizedPath) ?? 0;
437
+ }
438
+ export function clearDiagnosticsForPath(state, normalizedPath) {
439
+ const legacy = state;
440
+ state.pushDiagnostics?.delete(normalizedPath);
441
+ const pending = state.pendingDiagnostics?.get(normalizedPath);
442
+ if (pending)
443
+ clearTimeout(pending);
444
+ state.pendingDiagnostics?.delete(normalizedPath);
445
+ state.pushDiagnosticTimestamps?.delete(normalizedPath);
446
+ state.documentPullDiagnostics?.delete(normalizedPath);
447
+ state.documentPullDiagnosticTimestamps?.delete(normalizedPath);
448
+ state.diagnosticDocVersions?.delete(normalizedPath);
449
+ state.diagnosticBindings?.delete(normalizedPath);
450
+ state.diagnosticsVersionsByPath?.delete(normalizedPath);
451
+ for (const key of pullSourceKeysForPath(state, normalizedPath)) {
452
+ state.pullResultIds?.delete(key);
453
+ }
454
+ state.documentPullDiagnosticsBySource?.delete(normalizedPath);
455
+ bumpPullGeneration(state, normalizedPath);
456
+ state.workspacePullResultCache?.delete(normalizedPath);
457
+ legacy.diagnostics?.delete(normalizedPath);
458
+ legacy.diagnosticTimestamps?.delete(normalizedPath);
459
+ }
460
+ function logTypeScriptPullSettle(state, normalizedPath, durationMs, pullSettleSource) {
461
+ if (state.serverId !== "typescript")
462
+ return;
463
+ const diagnostics = state.documentPullDiagnostics.get(normalizedPath) ?? [];
464
+ const elapsedSinceDidOpenMs = Math.max(0, Date.now() - (state.documentOpenedAt.get(normalizedPath) ?? Date.now()));
465
+ const diagnosticCodes = [
466
+ ...new Set(diagnostics.map((diagnostic) => diagnostic.code).filter((code) => code !== undefined).map(String))
467
+ ].slice(0, 8);
468
+ const trackedVersion = state.diagnosticsVersionsByPath?.get(normalizedPath);
469
+ logLatency({
470
+ type: "phase",
471
+ phase: "lsp_typescript_diagnostic_sequence",
472
+ filePath: normalizedPath,
473
+ durationMs,
474
+ metadata: {
475
+ serverId: state.serverId,
476
+ outcome: "settled",
477
+ launchVariant: state.launchVariant ?? "unknown",
478
+ publicationIndex: state.diagnosticPublicationCounts.get(normalizedPath) ?? 0,
479
+ version: trackedVersion ?? "pull-unversioned",
480
+ diagnosticCount: diagnostics.length,
481
+ diagnosticCodes,
482
+ elapsedSinceDidOpenMs,
483
+ settledReturn: true,
484
+ settleSource: pullSettleSource
485
+ }
486
+ });
487
+ }
488
+ function scanSentContent(content) {
489
+ let lfNewlineCount = 0;
490
+ let index = 0;
491
+ let start = 0;
492
+ for (let i = 0;i < content.length; i++) {
493
+ const code = content.charCodeAt(i);
494
+ if (code !== 10 && code !== 13)
495
+ continue;
496
+ if (code === 10) {
497
+ lfNewlineCount++;
498
+ } else if (content.charCodeAt(i + 1) === 10) {
499
+ lfNewlineCount++;
500
+ i++;
501
+ }
502
+ index++;
503
+ start = i + 1;
504
+ }
505
+ return { lfNewlineCount, lastLine: { index, start } };
506
+ }
507
+ function recordSentContent(state, normalizedPath, version, content, coalescedCount = 0) {
508
+ const scan = scanSentContent(content);
509
+ const previous = state.documentContentHashes.get(normalizedPath);
510
+ if (previous && previous.version > version) {
511
+ incrementDegradationCount({
512
+ kind: "lsp-document-send-order",
513
+ subject: `${state.serverId}:${normalizedPath}`,
514
+ reason: `recorded version ${version} after newer version ${previous.version}`
515
+ });
516
+ return;
517
+ }
518
+ if (previous?.text !== undefined) {
519
+ state.incrementalTextRetainedEntries = Math.max(0, (state.incrementalTextRetainedEntries ?? 1) - 1);
520
+ state.incrementalTextRetainedBytes = Math.max(0, (state.incrementalTextRetainedBytes ?? previous.text.length * 2) - previous.text.length * 2);
521
+ state.incrementalTextBearingPaths?.delete(normalizedPath);
522
+ }
523
+ state.documentContentHashes.delete(normalizedPath);
524
+ state.documentContentHashes.set(normalizedPath, {
525
+ version,
526
+ hash: hashDiagnosticContent(content),
527
+ ...state.syncKind === TEXT_DOCUMENT_SYNC_KIND_INCREMENTAL && {
528
+ text: content,
529
+ lastLine: scan.lastLine
530
+ }
531
+ });
532
+ if (state.syncKind === TEXT_DOCUMENT_SYNC_KIND_INCREMENTAL) {
533
+ state.incrementalTextRetainedEntries = (state.incrementalTextRetainedEntries ?? 0) + 1;
534
+ state.incrementalTextRetainedBytes = (state.incrementalTextRetainedBytes ?? 0) + content.length * 2;
535
+ if (!state.incrementalTextBearingPaths) {
536
+ state.incrementalTextBearingPaths = new Set;
537
+ }
538
+ state.incrementalTextBearingPaths.add(normalizedPath);
539
+ while ((state.incrementalTextRetainedEntries ?? 0) > MAX_INCREMENTAL_TEXT_RETAINED_ENTRIES || (state.incrementalTextRetainedBytes ?? 0) > MAX_INCREMENTAL_TEXT_RETAINED_BYTES) {
540
+ const oldestPath = state.incrementalTextBearingPaths?.values().next().value;
541
+ if (oldestPath === undefined)
542
+ break;
543
+ const binding = state.documentContentHashes.get(oldestPath);
544
+ state.incrementalTextBearingPaths.delete(oldestPath);
545
+ if (!binding || binding.text === undefined)
546
+ continue;
547
+ state.documentContentHashes.set(oldestPath, {
548
+ version: binding.version,
549
+ hash: binding.hash
550
+ });
551
+ state.incrementalTextRetainedEntries = Math.max(0, (state.incrementalTextRetainedEntries ?? 1) - 1);
552
+ state.incrementalTextRetainedBytes = Math.max(0, (state.incrementalTextRetainedBytes ?? 0) - binding.text.length * 2);
553
+ }
554
+ }
555
+ logLatency({
556
+ type: "phase",
557
+ phase: "lsp_document_send",
558
+ filePath: normalizedPath,
559
+ durationMs: 0,
560
+ metadata: {
561
+ version,
562
+ contentLength: content.length,
563
+ contentLineCount: scan.lfNewlineCount + 1,
564
+ ...coalescedCount > 0 && { coalescedCount }
565
+ }
566
+ });
567
+ }
568
+ function buildContentChanges(state, normalizedPath, content) {
569
+ if (state.syncKind !== TEXT_DOCUMENT_SYNC_KIND_INCREMENTAL) {
570
+ return [{ text: content }];
571
+ }
572
+ const previous = state.documentContentHashes.get(normalizedPath);
573
+ if (previous?.text === undefined) {
574
+ return [{ text: content }];
575
+ }
576
+ const previousText = previous.text;
577
+ const lastLine = previous.lastLine ?? scanSentContent(previousText).lastLine;
578
+ const lastLineText = previousText.slice(lastLine.start);
579
+ return [
580
+ {
581
+ range: {
582
+ start: { line: 0, character: 0 },
583
+ end: {
584
+ line: lastLine.index,
585
+ character: convertCharacterOffset(state.positionEncoding, lastLineText, lastLineText.length)
586
+ }
587
+ },
588
+ text: content
589
+ }
590
+ ];
591
+ }
592
+ const DYNAMIC_OPERATION_METHOD_MAP = {
593
+ "textDocument/definition": "definition",
594
+ "textDocument/typeDefinition": "typeDefinition",
595
+ "textDocument/declaration": "declaration",
596
+ "textDocument/references": "references",
597
+ "textDocument/hover": "hover",
598
+ "textDocument/signatureHelp": "signatureHelp",
599
+ "textDocument/documentSymbol": "documentSymbol",
600
+ "workspace/symbol": "workspaceSymbol",
601
+ "textDocument/codeAction": "codeAction",
602
+ "textDocument/rename": "rename",
603
+ "textDocument/implementation": "implementation",
604
+ "textDocument/prepareCallHierarchy": "callHierarchy"
605
+ };
606
+ export function applyDynamicCapabilities(state) {
607
+ const registrations = [...state.dynamicRegistrations.values()];
608
+ const registeredMethods = new Set(registrations.map((r) => r.method));
609
+ const hasDynamicPull = registeredMethods.has("textDocument/diagnostic") || registeredMethods.has("workspace/diagnostic");
610
+ if (hasDynamicPull) {
611
+ state.workspaceDiagnosticsSupport = {
612
+ advertised: true,
613
+ mode: "pull",
614
+ workspaceDiagnostics: registrations.some((r) => r.workspaceDiagnostics === true) || registeredMethods.has("workspace/diagnostic"),
615
+ diagnosticProviderKind: "dynamic"
616
+ };
617
+ } else if (state.staticDiagnosticsMode === "push-only" && state.workspaceDiagnosticsSupport.diagnosticProviderKind === "dynamic") {
618
+ state.workspaceDiagnosticsSupport = {
619
+ advertised: false,
620
+ mode: "push-only",
621
+ workspaceDiagnostics: false,
622
+ diagnosticProviderKind: "none"
623
+ };
624
+ }
625
+ for (const [method, key] of Object.entries(DYNAMIC_OPERATION_METHOD_MAP)) {
626
+ if (registeredMethods.has(method)) {
627
+ state.operationSupport[key] = true;
628
+ }
629
+ }
630
+ }
631
+ export function resolveConfigurationSection(initialization, section) {
632
+ if (!initialization)
633
+ return {};
634
+ if (!section)
635
+ return initialization;
636
+ let cur = initialization;
637
+ for (const part of section.split(".")) {
638
+ if (typeof cur !== "object" || cur === null || !Object.hasOwn(cur, part)) {
639
+ return {};
640
+ }
641
+ cur = cur[part];
642
+ }
643
+ return cur;
644
+ }
645
+ export function setupIncomingHandlers(state, initialization, onDiagnosticsPublished) {
646
+ state.connection.onNotification("textDocument/publishDiagnostics", (params) => {
647
+ const publishReceivedAt = Date.now();
648
+ const filePath = uriToPath(params.uri);
649
+ const normalizedPath = normalizeMapKey(filePath);
650
+ if (state.closedDocuments?.has(normalizedPath))
651
+ return;
652
+ onDiagnosticsPublished?.(state.serverId);
653
+ const newDiags = normalizeLspDiagnostics(params.diagnostics || []);
654
+ const docVersion = params.version;
655
+ if (PUB_DEBUG) {
656
+ logExtension({
657
+ subsystem: "lsp-pub",
658
+ level: "debug",
659
+ message: `server=${state.serverId} pubVersion=${docVersion} docVersion=${state.documentVersions?.get(normalizedPath)} diags=${newDiags.length}`
660
+ });
661
+ }
662
+ const strategy = getStrategy(state.serverId, state.launchVariant);
663
+ const isTypeScriptTelemetry = state.serverId === "typescript";
664
+ const publicationIndex = isTypeScriptTelemetry ? (state.diagnosticPublicationCounts.get(normalizedPath) ?? 0) + 1 : 0;
665
+ if (isTypeScriptTelemetry) {
666
+ state.diagnosticPublicationCounts.set(normalizedPath, publicationIndex);
667
+ }
668
+ const diagnosticCodes = isTypeScriptTelemetry ? [
669
+ ...new Set(newDiags.map((diagnostic) => diagnostic.code).filter((code) => code !== undefined).map(String))
670
+ ].slice(0, 8) : [];
671
+ const logSequence = (settledReturn, settleSource, durationMs) => {
672
+ if (state.serverId !== "typescript")
673
+ return;
674
+ const elapsedSinceDidOpenMs = Math.max(0, Date.now() - (state.documentOpenedAt.get(normalizedPath) ?? Date.now()));
675
+ logLatency({
676
+ type: "phase",
677
+ phase: "lsp_typescript_diagnostic_sequence",
678
+ filePath: normalizedPath,
679
+ durationMs,
680
+ metadata: {
681
+ serverId: state.serverId,
682
+ outcome: settledReturn ? "settled" : "published",
683
+ launchVariant: state.launchVariant ?? "unknown",
684
+ publicationIndex,
685
+ version: docVersion ?? "push-unversioned",
686
+ diagnosticCount: newDiags.length,
687
+ diagnosticCodes,
688
+ elapsedSinceDidOpenMs,
689
+ settledReturn,
690
+ settleSource
691
+ }
692
+ });
693
+ };
694
+ const recordDocVersion = () => {
695
+ if (docVersion !== undefined) {
696
+ state.diagnosticDocVersions.set(normalizedPath, docVersion);
697
+ }
698
+ recordBinding();
699
+ };
700
+ const recordBinding = () => {
701
+ if (docVersion === undefined) {
702
+ state.diagnosticBindings.delete(normalizedPath);
703
+ return;
704
+ }
705
+ const sent = state.documentContentHashes.get(normalizedPath);
706
+ state.diagnosticBindings.set(normalizedPath, {
707
+ version: docVersion,
708
+ contentHash: sent && sent.version === docVersion ? sent.hash : undefined
709
+ });
710
+ };
711
+ const isSupersededPush = () => {
712
+ if (docVersion === undefined)
713
+ return false;
714
+ const currentVersion = state.documentVersions.get(normalizedPath);
715
+ return currentVersion !== undefined && docVersion < currentVersion;
716
+ };
717
+ if (strategy.emptyFirstPublish === "indexing" && !state.emptyFirstPublishHoldSpent && newDiags.length === 0 && !state.pushDiagnostics.has(normalizedPath) && !state.pendingDiagnostics.has(normalizedPath)) {
718
+ state.emptyFirstPublishHoldSpent = true;
719
+ logLatency({
720
+ type: "phase",
721
+ phase: "lsp_empty_first_publish_held",
722
+ filePath: normalizedPath,
723
+ durationMs: Math.max(0, publishReceivedAt - (state.documentOpenedAt.get(normalizedPath) ?? publishReceivedAt)),
724
+ metadata: {
725
+ serverId: state.serverId,
726
+ emptyFirstPublish: strategy.emptyFirstPublish,
727
+ pubVersion: docVersion ?? "push-unversioned"
728
+ }
729
+ });
730
+ return;
731
+ }
732
+ if (strategy.seedFirstPush && !state.pushDiagnostics.has(normalizedPath)) {
733
+ if (isSupersededPush())
734
+ return;
735
+ state.pushDiagnostics.set(normalizedPath, newDiags);
736
+ state.pushDiagnosticTimestamps.set(normalizedPath, Date.now());
737
+ recordDocVersion();
738
+ bumpDiagnosticsVersion(state, normalizedPath);
739
+ state.diagnosticEmitter.emit("diagnostics", normalizedPath);
740
+ logSequence(true, "first-push", 0);
741
+ return;
742
+ }
743
+ logSequence(false, "publication", 0);
744
+ const existingTimer = state.pendingDiagnostics.get(normalizedPath);
745
+ if (existingTimer)
746
+ clearTimeout(existingTimer);
747
+ const timer = setTimeout(() => {
748
+ state.pendingDiagnostics.delete(normalizedPath);
749
+ if (isSupersededPush())
750
+ return;
751
+ state.pushDiagnostics.set(normalizedPath, newDiags);
752
+ state.pushDiagnosticTimestamps.set(normalizedPath, Date.now());
753
+ recordDocVersion();
754
+ bumpDiagnosticsVersion(state, normalizedPath);
755
+ state.diagnosticEmitter.emit("diagnostics", normalizedPath);
756
+ logSequence(true, "quiet-window", Date.now() - publishReceivedAt);
757
+ }, strategy.debounceMs);
758
+ state.pendingDiagnostics.set(normalizedPath, timer);
759
+ });
760
+ state.connection.onRequest("workspace/workspaceFolders", () => [
761
+ { name: "workspace", uri: pathToFileURL(state.root).href }
762
+ ]);
763
+ state.connection.onRequest("client/registerCapability", async (params) => {
764
+ for (const reg of params?.registrations ?? []) {
765
+ const options = reg.registerOptions;
766
+ const commands = Array.isArray(options?.commands) ? options.commands.filter((cmd) => typeof cmd === "string") : undefined;
767
+ if (reg.id && reg.method) {
768
+ state.dynamicRegistrations.set(reg.id, {
769
+ method: reg.method,
770
+ ...typeof options?.identifier === "string" && options.identifier ? { identifier: options.identifier } : {},
771
+ ...typeof options?.workspaceDiagnostics === "boolean" ? { workspaceDiagnostics: options.workspaceDiagnostics } : {},
772
+ ...commands ? { commands } : {}
773
+ });
774
+ }
775
+ if (reg.method === "workspace/executeCommand" && commands) {
776
+ for (const cmd of commands)
777
+ state.advertisedCommands.add(cmd);
778
+ }
779
+ }
780
+ applyDynamicCapabilities(state);
781
+ });
782
+ state.connection.onRequest("client/unregisterCapability", async (params) => {
783
+ const retiredIdentifiers = new Set;
784
+ for (const unreg of params?.unregisterations ?? []) {
785
+ if (!unreg.id)
786
+ continue;
787
+ const registration = state.dynamicRegistrations.get(unreg.id);
788
+ state.dynamicRegistrations.delete(unreg.id);
789
+ if (registration?.method === "textDocument/diagnostic" && registration.identifier) {
790
+ retiredIdentifiers.add(registration.identifier);
791
+ }
792
+ }
793
+ const stillRegistered = new Set([...state.dynamicRegistrations.values()].filter((r) => r.method === "textDocument/diagnostic").map((r) => r.identifier));
794
+ for (const identifier of retiredIdentifiers) {
795
+ if (!stillRegistered.has(identifier)) {
796
+ retirePullSource(state, identifier);
797
+ }
798
+ }
799
+ applyDynamicCapabilities(state);
800
+ });
801
+ state.connection.onRequest("workspace/applyEdit", async (params) => {
802
+ if (state.serverEditsAllowed <= 0 || !params?.edit) {
803
+ return { applied: false, failureReason: "edit not solicited" };
804
+ }
805
+ const context = state.activeMutationContext;
806
+ const telemetryContext = context ?? {
807
+ cwd: state.root,
808
+ correlationId: newLspMutationCorrelationId(),
809
+ tool: "lsp-workspace-applyEdit",
810
+ source: "lsp-execute-command"
811
+ };
812
+ try {
813
+ await applyWorkspaceEdit(params.edit, state.root, {
814
+ positionEncoding: state.positionEncoding,
815
+ documentVersions: state.documentVersions,
816
+ mutationContext: telemetryContext
817
+ });
818
+ return { applied: true };
819
+ } catch (err) {
820
+ return {
821
+ applied: false,
822
+ failureReason: err instanceof Error ? err.message : String(err)
823
+ };
824
+ }
825
+ });
826
+ state.connection.onRequest("workspace/configuration", async (params) => {
827
+ const items = params?.items ?? [];
828
+ return items.map((item) => resolveConfigurationSection(initialization, item?.section));
829
+ });
830
+ state.connection.onRequest("window/workDoneProgress/create", async () => {});
831
+ let refreshRepullRunning = false;
832
+ let refreshRepullRerunRequested = false;
833
+ const runRefreshRepullPool = async () => {
834
+ do {
835
+ refreshRepullRerunRequested = false;
836
+ const toRepull = state.workspaceDiagnosticsSupport.mode === "pull" ? [...state.openDocuments] : [];
837
+ if (toRepull.length > 0) {
838
+ try {
839
+ await mapWithConcurrency(toRepull, REFRESH_REPULL_CONCURRENCY, async (normalizedPath) => {
840
+ const uri = state.openDocumentUris?.get(normalizedPath);
841
+ const filePath = uri ? uriToPath(uri) : normalizedPath;
842
+ await clientRequestPullDiagnostics(state, filePath);
843
+ });
844
+ } catch (err) {
845
+ incrementDegradationCount({
846
+ kind: "lsp-pull-unconfirmed",
847
+ subject: state.serverId,
848
+ reason: `refresh re-pull threw: ${err instanceof Error ? err.message : String(err)}`
849
+ });
850
+ }
851
+ }
852
+ } while (refreshRepullRerunRequested);
853
+ refreshRepullRunning = false;
854
+ };
855
+ state.connection.onRequest("workspace/diagnostic/refresh", async () => {
856
+ state.workspacePullResultCache.clear();
857
+ clearAllWorkspaceDiagnosticsCaches();
858
+ clearWorkspaceDiagnosticsCacheAtAndAbove(state.root);
859
+ for (const normalizedPath of state.openDocuments) {
860
+ clearDiagnosticsForPath(state, normalizedPath);
861
+ }
862
+ if (state.workspaceDiagnosticsSupport.mode === "pull" && state.openDocuments.size > 0) {
863
+ if (refreshRepullRunning) {
864
+ refreshRepullRerunRequested = true;
865
+ } else {
866
+ refreshRepullRunning = true;
867
+ setImmediate(() => {
868
+ runRefreshRepullPool();
869
+ });
870
+ }
871
+ }
872
+ return null;
873
+ });
874
+ }
875
+ function markExitedIfUnset(state) {
876
+ if (state.exitedAt === undefined) {
877
+ state.exitedAt = Date.now();
878
+ }
879
+ }
880
+ function setupConnectionLifecycle(state, recentStderr) {
881
+ state.connection.onError(([error]) => {
882
+ state.lastError = error instanceof Error ? error : new Error(String(error));
883
+ state.isConnected = false;
884
+ state.isDestroyed = true;
885
+ markExitedIfUnset(state);
886
+ disposeClientConnection(state);
887
+ });
888
+ state.connection.onClose(() => {
889
+ state.isConnected = false;
890
+ state.isDestroyed = true;
891
+ markExitedIfUnset(state);
892
+ disposeClientConnection(state);
893
+ });
894
+ state.lspProcess.process.on("exit", (code, signal) => {
895
+ const wasIntentional = state.shutdownRequested;
896
+ state.isConnected = false;
897
+ state.isDestroyed = true;
898
+ markExitedIfUnset(state);
899
+ disposeClientConnection(state);
900
+ if (!wasIntentional) {
901
+ logLatency({
902
+ type: "phase",
903
+ phase: "lsp_server_unexpected_exit",
904
+ filePath: state.root,
905
+ durationMs: 0,
906
+ metadata: {
907
+ serverId: state.serverId,
908
+ pid: state.lspProcess.pid,
909
+ exitCode: code ?? null,
910
+ exitSignal: signal ?? null,
911
+ stderrTail: recentStderr(20)
912
+ }
913
+ });
914
+ }
915
+ });
916
+ state.lspProcess.process.on("close", (code, signal) => {
917
+ if (state.shutdownRequested)
918
+ return;
919
+ try {
920
+ const stderrTail = recentStderr(20);
921
+ incrementDegradationCount({
922
+ kind: "lsp-server-unexpected-close",
923
+ subject: state.serverId,
924
+ reason: `closed unprompted: code=${code ?? "none"} signal=${signal ?? "none"} ` + `stderr=${stderrTail.length > 0 ? `present(${stderrTail.length}b)` : "empty"} root=${state.root}`
925
+ });
926
+ } catch {}
927
+ });
928
+ }
929
+ const PULL_RACE_BACKSTOP_MARGIN_MS = 25;
930
+ async function clientRequestPullDiagnostics(state, filePath, budgetMs = PULL_REQUEST_TIMEOUT_MS) {
931
+ if (!isClientAlive(state))
932
+ return { status: "unavailable" };
933
+ const sources = pullDiagnosticSources(state);
934
+ if (sources.length === 1) {
935
+ return aggregatePullOutcomes(state, filePath, [
936
+ await pullDiagnosticSource(state, filePath, budgetMs, undefined)
937
+ ]);
938
+ }
939
+ const attempts = sources.map((identifier) => pullDiagnosticSource(state, filePath, budgetMs, identifier));
940
+ const settled = await raceToCompletion(attempts, (results) => results.some((r) => r.status === "found" && r.primaryCount > 0), {
941
+ timeoutMs: Math.max(1, Math.min(PULL_REQUEST_TIMEOUT_MS, budgetMs)) + PULL_RACE_BACKSTOP_MARGIN_MS
942
+ });
943
+ return aggregatePullOutcomes(state, filePath, settled);
944
+ }
945
+ function aggregatePullOutcomes(state, filePath, outcomes) {
946
+ const found = outcomes.filter((o) => o.status === "found");
947
+ if (found.length > 0) {
948
+ const normalizedPath = normalizeMapKey(filePath);
949
+ const unionCount = state.documentPullDiagnostics.get(normalizedPath)?.length ?? 0;
950
+ return {
951
+ status: "found",
952
+ count: Math.max(unionCount, ...found.map((o) => o.count))
953
+ };
954
+ }
955
+ if (outcomes.some((o) => o.status === "unavailable")) {
956
+ return { status: "unavailable" };
957
+ }
958
+ return outcomes.some((o) => o.status === "clean") ? { status: "clean" } : { status: "unavailable" };
959
+ }
960
+ async function pullDiagnosticSource(state, filePath, budgetMs, identifier) {
961
+ if (!isClientAlive(state))
962
+ return { status: "unavailable" };
963
+ const normalizedPath = normalizeMapKey(filePath);
964
+ if (budgetMs < PULL_MIN_USABLE_BUDGET_MS) {
965
+ emitBounded("lsp_pull_skipped_budget_exhausted", `${state.serverId}::${pullSourceKey(normalizedPath, identifier)}`, {
966
+ type: "phase",
967
+ filePath: normalizedPath,
968
+ durationMs: 0,
969
+ metadata: {
970
+ identifier: identifier ?? "bare",
971
+ remainingBudgetMs: budgetMs,
972
+ server: state.serverId
973
+ }
974
+ }, {
975
+ ledgerKind: "lsp-pull-skipped-budget-exhausted",
976
+ reason: `pull skipped on ${state.serverId}: budget already exhausted (${budgetMs}ms remaining)`
977
+ });
978
+ return { status: "unavailable" };
979
+ }
980
+ const uri = pathToFileURL(filePath).href;
981
+ const sourceKey = pullSourceKey(normalizedPath, identifier);
982
+ if (state.abandonedPullRequests?.has(sourceKey)) {
983
+ return { status: "unavailable" };
984
+ }
985
+ const previousResultId = state.pullResultIds.get(sourceKey);
986
+ const generation = pullGenerationFor(state, normalizedPath);
987
+ const requestSequence = claimPullRequestSequence(state, sourceKey);
988
+ const requestStartedAt = Date.now();
989
+ const effectiveTimeoutMs = Math.max(1, Math.min(PULL_REQUEST_TIMEOUT_MS, budgetMs));
990
+ const pullAbort = new AbortController;
991
+ const pullSettlement = { cancelled: false };
992
+ const requestPromise = safeSendRequest(state.connection, "textDocument/diagnostic", {
993
+ textDocument: { uri },
994
+ ...identifier !== undefined && { identifier },
995
+ ...previousResultId !== undefined && { previousResultId }
996
+ }, pullAbort.signal, pullSettlement);
997
+ try {
998
+ const report = await withTimeout(requestPromise, effectiveTimeoutMs);
999
+ if (!report) {
1000
+ recordPullFailure(state, "textDocument/diagnostic", new Error("empty response"));
1001
+ return { status: "unavailable" };
1002
+ }
1003
+ const now = Date.now();
1004
+ const sentHash = state.documentContentHashes.get(normalizedPath)?.hash;
1005
+ if (pullGenerationFor(state, normalizedPath) !== generation || !isNewestPullRequest(state, sourceKey, requestSequence)) {
1006
+ return { status: "unavailable" };
1007
+ }
1008
+ let primaryCount;
1009
+ if (report.kind === "unchanged") {
1010
+ primaryCount = pullSourceDiagnostics(state, normalizedPath, identifier).length;
1011
+ state.documentPullDiagnosticTimestamps.set(normalizedPath, now);
1012
+ } else {
1013
+ const primaryItems = normalizeLspDiagnostics(report.items ?? []);
1014
+ storePullSourceDiagnostics(state, normalizedPath, identifier, primaryItems);
1015
+ state.documentPullDiagnosticTimestamps.set(normalizedPath, now);
1016
+ bumpDiagnosticsVersion(state, normalizedPath);
1017
+ state.diagnosticBindings.set(normalizedPath, { contentHash: sentHash });
1018
+ primaryCount = primaryItems.length;
1019
+ }
1020
+ let totalCount = primaryCount;
1021
+ if (report.resultId !== undefined) {
1022
+ state.pullResultIds.set(sourceKey, report.resultId);
1023
+ } else {
1024
+ state.pullResultIds.delete(sourceKey);
1025
+ }
1026
+ if (report.relatedDocuments) {
1027
+ for (const [relatedUri, related] of Object.entries(report.relatedDocuments)) {
1028
+ const relatedPath = uriToPath(relatedUri);
1029
+ const relatedNormalized = normalizeMapKey(relatedPath);
1030
+ if (related?.kind === "unchanged") {
1031
+ totalCount += pullSourceDiagnostics(state, relatedNormalized, identifier).length;
1032
+ state.documentPullDiagnosticTimestamps.set(relatedNormalized, now);
1033
+ } else {
1034
+ const relatedItems = normalizeLspDiagnostics(related?.items ?? []);
1035
+ storePullSourceDiagnostics(state, relatedNormalized, identifier, relatedItems);
1036
+ state.documentPullDiagnosticTimestamps.set(relatedNormalized, now);
1037
+ state.diagnosticBindings.delete(relatedNormalized);
1038
+ totalCount += relatedItems.length;
1039
+ }
1040
+ if (related?.resultId !== undefined) {
1041
+ state.pullResultIds.set(pullSourceKey(relatedNormalized, identifier), related.resultId);
1042
+ }
1043
+ }
1044
+ }
1045
+ state.diagnosticEmitter.emit("diagnostics", normalizedPath);
1046
+ return totalCount > 0 ? { status: "found", count: totalCount, primaryCount } : { status: "clean" };
1047
+ } catch (err) {
1048
+ if (isPullTimeoutError(err, effectiveTimeoutMs)) {
1049
+ trackAbandonedPullRequest(state, sourceKey, requestPromise);
1050
+ pullAbort.abort();
1051
+ recordPullTimeoutTelemetry({
1052
+ scope: normalizedPath,
1053
+ identifier,
1054
+ effectiveBudgetMs: effectiveTimeoutMs,
1055
+ hadPreviousResultId: previousResultId !== undefined,
1056
+ elapsedMs: Date.now() - requestStartedAt,
1057
+ server: state.serverId
1058
+ });
1059
+ armLateAnswerTelemetry({
1060
+ requestPromise,
1061
+ scope: normalizedPath,
1062
+ identifier,
1063
+ subject: sourceKey,
1064
+ requestStartedAt,
1065
+ server: state.serverId,
1066
+ settlement: pullSettlement
1067
+ });
1068
+ }
1069
+ recordPullFailure(state, "textDocument/diagnostic", err);
1070
+ return { status: "unavailable" };
1071
+ }
1072
+ }
1073
+ function trackAbandonedPullRequest(state, sourceKey, requestPromise) {
1074
+ if (!state.abandonedPullRequests)
1075
+ state.abandonedPullRequests = new Map;
1076
+ state.abandonedPullRequests.set(sourceKey, requestPromise);
1077
+ const release = () => {
1078
+ if (state.abandonedPullRequests?.get(sourceKey) === requestPromise) {
1079
+ state.abandonedPullRequests.delete(sourceKey);
1080
+ }
1081
+ };
1082
+ requestPromise.then(release, release);
1083
+ }
1084
+ function isPullTimeoutError(err, timeoutMs) {
1085
+ return err instanceof Error && err.message === `Timeout after ${timeoutMs}ms`;
1086
+ }
1087
+ function recordPullTimeoutTelemetry(args) {
1088
+ emitBounded("lsp_pull_diagnostic_timeout", `${args.server}::${args.scope}::${args.identifier ?? "bare"}`, {
1089
+ type: "phase",
1090
+ filePath: args.scope,
1091
+ durationMs: args.elapsedMs,
1092
+ metadata: {
1093
+ identifier: args.identifier ?? "bare",
1094
+ effectiveBudgetMs: args.effectiveBudgetMs,
1095
+ hadPreviousResultId: args.hadPreviousResultId,
1096
+ server: args.server
1097
+ }
1098
+ }, {
1099
+ ledgerKind: "lsp-pull-diagnostic-timeout",
1100
+ reason: `pull timeout on ${args.server} after ${args.elapsedMs}ms (budget ${args.effectiveBudgetMs}ms)`
1101
+ });
1102
+ }
1103
+ function armLateAnswerTelemetry(args) {
1104
+ args.requestPromise.then(() => {
1105
+ if (args.settlement.cancelled)
1106
+ return;
1107
+ try {
1108
+ const elapsedMs = Date.now() - args.requestStartedAt;
1109
+ emitBounded("lsp_pull_late_answer_discarded", args.subject, {
1110
+ type: "phase",
1111
+ filePath: args.scope,
1112
+ durationMs: elapsedMs,
1113
+ metadata: { identifier: args.identifier ?? "bare" }
1114
+ }, {
1115
+ ledgerKind: "lsp-pull-late-answer",
1116
+ reason: `late pull answer discarded after ${elapsedMs}ms`
1117
+ });
1118
+ } catch {}
1119
+ }, (err) => {
1120
+ try {
1121
+ const elapsedMs = Date.now() - args.requestStartedAt;
1122
+ const candidate = err;
1123
+ const code = typeof candidate?.code === "number" || typeof candidate?.code === "string" ? candidate.code : undefined;
1124
+ emitBounded("lsp_pull_late_rejection", `${args.server}::${args.subject}`, {
1125
+ type: "phase",
1126
+ filePath: args.scope,
1127
+ durationMs: elapsedMs,
1128
+ metadata: {
1129
+ identifier: args.identifier ?? "bare",
1130
+ server: args.server,
1131
+ ...code !== undefined && { code }
1132
+ }
1133
+ }, {
1134
+ ledgerKind: "lsp-pull-late-rejection",
1135
+ reason: `late pull rejection ${elapsedMs}ms after timeout${code !== undefined ? ` (code ${code})` : ""}`
1136
+ });
1137
+ } catch {}
1138
+ });
1139
+ }
1140
+ const PULL_FAILURE_HISTORY_LIMIT = 10;
1141
+ function recordPullFailure(state, method, error) {
1142
+ const candidate = error;
1143
+ const message = typeof candidate.message === "string" ? candidate.message : "";
1144
+ const unsupportedMessage = /^(?:method not found|unknown method|unsupported method)(?::|$)/i;
1145
+ if (candidate.code === -32601 || candidate.code === "-32601" || unsupportedMessage.test(message.trim()))
1146
+ return;
1147
+ state.pullFailureHistory.push({
1148
+ timestamp: Date.now(),
1149
+ method,
1150
+ ...typeof candidate.code === "number" || typeof candidate.code === "string" ? { code: candidate.code } : {},
1151
+ message: typeof candidate.message === "string" ? candidate.message : String(error)
1152
+ });
1153
+ if (state.pullFailureHistory.length > PULL_FAILURE_HISTORY_LIMIT) {
1154
+ state.pullFailureHistory.splice(0, state.pullFailureHistory.length - PULL_FAILURE_HISTORY_LIMIT);
1155
+ }
1156
+ }
1157
+ export async function clientRequestWorkspaceDiagnostics(state, budgetMs) {
1158
+ if (!isClientAlive(state))
1159
+ return;
1160
+ if (!state.workspaceDiagnosticsSupport.workspaceDiagnostics)
1161
+ return;
1162
+ if (state.abandonedPullRequests?.has(WORKSPACE_PULL_SCOPE))
1163
+ return;
1164
+ const previousResultIds = Array.from(state.workspacePullResultCache.values()).map((entry) => ({ uri: entry.uri, value: entry.resultId }));
1165
+ if (budgetMs < PULL_MIN_USABLE_BUDGET_MS) {
1166
+ emitBounded("lsp_pull_skipped_budget_exhausted", `${state.serverId}::${WORKSPACE_PULL_SCOPE}`, {
1167
+ type: "phase",
1168
+ filePath: WORKSPACE_PULL_SCOPE,
1169
+ durationMs: 0,
1170
+ metadata: {
1171
+ identifier: "bare",
1172
+ remainingBudgetMs: budgetMs,
1173
+ server: state.serverId
1174
+ }
1175
+ }, {
1176
+ ledgerKind: "lsp-pull-skipped-budget-exhausted",
1177
+ reason: `workspace pull skipped on ${state.serverId}: budget already exhausted (${budgetMs}ms remaining)`
1178
+ });
1179
+ return;
1180
+ }
1181
+ const workspacePullStartedAt = Date.now();
1182
+ const workspacePullTimeoutMs = Math.max(1, budgetMs);
1183
+ const workspacePullAbort = new AbortController;
1184
+ const workspacePullSettlement = { cancelled: false };
1185
+ const workspaceRequestPromise = safeSendRequest(state.connection, "workspace/diagnostic", { previousResultIds }, workspacePullAbort.signal, workspacePullSettlement);
1186
+ try {
1187
+ const report = await withTimeout(workspaceRequestPromise, workspacePullTimeoutMs);
1188
+ if (!report || !Array.isArray(report.items))
1189
+ return;
1190
+ const out = [];
1191
+ const fallbackPullDeadline = Date.now() + Math.max(1, budgetMs);
1192
+ for (const item of report.items) {
1193
+ if (!item?.uri)
1194
+ continue;
1195
+ const filePath = uriToPath(item.uri);
1196
+ const normalizedPath = normalizeMapKey(filePath);
1197
+ if (item.kind === "unchanged") {
1198
+ const prior = state.workspacePullResultCache.get(normalizedPath);
1199
+ if (!prior) {
1200
+ const remainingMs = fallbackPullDeadline - Date.now();
1201
+ if (remainingMs <= 0) {
1202
+ incrementDegradationCount({
1203
+ kind: "lsp-pull-unconfirmed",
1204
+ subject: state.serverId,
1205
+ reason: "unchanged report with no workspacePullResultCache basis; the shared fallback-pull deadline was already exhausted by earlier files this sweep"
1206
+ });
1207
+ continue;
1208
+ }
1209
+ const outcome = await clientRequestPullDiagnostics(state, filePath, remainingMs);
1210
+ if (outcome.status === "found") {
1211
+ out.push({
1212
+ filePath,
1213
+ diagnostics: state.documentPullDiagnostics.get(normalizedPath) ?? [],
1214
+ contentHash: state.diagnosticBindings.get(normalizedPath)?.contentHash
1215
+ });
1216
+ } else if (outcome.status === "unavailable") {
1217
+ incrementDegradationCount({
1218
+ kind: "lsp-pull-unconfirmed",
1219
+ subject: state.serverId,
1220
+ reason: "unchanged report with no workspacePullResultCache basis, and the per-file fallback pull was unavailable"
1221
+ });
1222
+ }
1223
+ continue;
1224
+ }
1225
+ if (item.resultId !== undefined) {
1226
+ state.workspacePullResultCache.set(normalizedPath, {
1227
+ ...prior,
1228
+ resultId: item.resultId
1229
+ });
1230
+ }
1231
+ out.push({
1232
+ filePath,
1233
+ diagnostics: prior.diagnostics,
1234
+ contentHash: prior.contentHash
1235
+ });
1236
+ continue;
1237
+ }
1238
+ const diagnostics = normalizeLspDiagnostics(item.items ?? []);
1239
+ let contentHash;
1240
+ try {
1241
+ contentHash = hashDiagnosticContent(await readFile(filePath, "utf-8"));
1242
+ } catch {
1243
+ contentHash = undefined;
1244
+ }
1245
+ if (item.resultId !== undefined) {
1246
+ if (state.workspacePullResultCache.size >= WORKSPACE_PULL_RESULT_CACHE_MAX) {
1247
+ state.workspacePullResultCache.clear();
1248
+ }
1249
+ state.workspacePullResultCache.set(normalizedPath, {
1250
+ uri: item.uri,
1251
+ resultId: item.resultId,
1252
+ diagnostics,
1253
+ contentHash
1254
+ });
1255
+ } else {
1256
+ state.workspacePullResultCache.delete(normalizedPath);
1257
+ }
1258
+ out.push({ filePath, diagnostics, contentHash });
1259
+ }
1260
+ return out;
1261
+ } catch (err) {
1262
+ if (isPullTimeoutError(err, workspacePullTimeoutMs)) {
1263
+ trackAbandonedPullRequest(state, WORKSPACE_PULL_SCOPE, workspaceRequestPromise);
1264
+ workspacePullAbort.abort();
1265
+ recordPullTimeoutTelemetry({
1266
+ scope: WORKSPACE_PULL_SCOPE,
1267
+ identifier: undefined,
1268
+ effectiveBudgetMs: workspacePullTimeoutMs,
1269
+ hadPreviousResultId: previousResultIds.length > 0,
1270
+ elapsedMs: Date.now() - workspacePullStartedAt,
1271
+ server: state.serverId
1272
+ });
1273
+ armLateAnswerTelemetry({
1274
+ requestPromise: workspaceRequestPromise,
1275
+ scope: WORKSPACE_PULL_SCOPE,
1276
+ identifier: undefined,
1277
+ subject: WORKSPACE_PULL_SCOPE,
1278
+ requestStartedAt: workspacePullStartedAt,
1279
+ server: state.serverId,
1280
+ settlement: workspacePullSettlement
1281
+ });
1282
+ }
1283
+ recordPullFailure(state, "workspace/diagnostic", err);
1284
+ return;
1285
+ }
1286
+ }
1287
+ export async function clientWaitForDiagnostics(state, filePath, timeoutMs, options = {}) {
1288
+ const normalizedPath = normalizeMapKey(filePath);
1289
+ const minVersion = options.minVersion;
1290
+ const pullSettleSource = options.pullSettleSource ?? "pull";
1291
+ const hasFreshDiagnostics = () => minVersion === undefined || diagnosticsVersionForPath(state, normalizedPath) > minVersion;
1292
+ const isVersionStale = () => {
1293
+ const cachedVersion = state.diagnosticDocVersions?.get(normalizedPath);
1294
+ if (cachedVersion === undefined)
1295
+ return false;
1296
+ const currentVersion = state.documentVersions?.get(normalizedPath);
1297
+ return currentVersion !== undefined && cachedVersion < currentVersion;
1298
+ };
1299
+ if (state.workspaceDiagnosticsSupport.mode === "pull") {
1300
+ const pullSettleStartedAt = Date.now();
1301
+ let outcome = await clientRequestPullDiagnostics(state, filePath, timeoutMs);
1302
+ if (outcome.status === "found") {
1303
+ logTypeScriptPullSettle(state, normalizedPath, Date.now() - pullSettleStartedAt, pullSettleSource);
1304
+ return;
1305
+ }
1306
+ let sawClean = outcome.status === "clean";
1307
+ const strategy = getStrategy(state.serverId, state.launchVariant);
1308
+ const retryBudgetMs = strategy.pullRetryBudgetMs > 0 ? Math.min(timeoutMs, strategy.pullRetryBudgetMs) : 0;
1309
+ const startedAt = Date.now();
1310
+ while (outcome.status !== "found" && Date.now() - startedAt < retryBudgetMs) {
1311
+ await new Promise((resolve) => setTimeout(resolve, PULL_DIAGNOSTICS_RETRY_INTERVAL_MS));
1312
+ outcome = await clientRequestPullDiagnostics(state, filePath, Math.max(0, retryBudgetMs - (Date.now() - startedAt)));
1313
+ if (outcome.status === "clean")
1314
+ sawClean = true;
1315
+ }
1316
+ if (options.pullOnly) {
1317
+ if (outcome.status === "found" || sawClean) {
1318
+ logTypeScriptPullSettle(state, normalizedPath, Date.now() - pullSettleStartedAt, pullSettleSource);
1319
+ }
1320
+ return;
1321
+ }
1322
+ if (outcome.status === "found" || sawClean) {
1323
+ logTypeScriptPullSettle(state, normalizedPath, Date.now() - pullSettleStartedAt, pullSettleSource);
1324
+ return;
1325
+ }
1326
+ }
1327
+ if (hasFreshDiagnostics() && !isVersionStale() && getMergedDiagnosticsForPath(state, normalizedPath).length > 0) {
1328
+ return;
1329
+ }
1330
+ return new Promise((resolve) => {
1331
+ let debounceTimer;
1332
+ const onDiagnostics = (fp) => {
1333
+ if (normalizeMapKey(fp) !== normalizedPath)
1334
+ return;
1335
+ if (!hasFreshDiagnostics() || isVersionStale())
1336
+ return;
1337
+ if (debounceTimer)
1338
+ clearTimeout(debounceTimer);
1339
+ const strategy = getStrategy(state.serverId, state.launchVariant);
1340
+ const hit = state.pushDiagnosticTimestamps.get(normalizedPath);
1341
+ const timeSincePush = hit ? Date.now() - hit : 1 / 0;
1342
+ const remaining = Math.max(0, strategy.debounceMs - timeSincePush);
1343
+ debounceTimer = setTimeout(() => {
1344
+ state.diagnosticEmitter.off("diagnostics", onDiagnostics);
1345
+ clearTimeout(timeout);
1346
+ resolve();
1347
+ }, remaining);
1348
+ };
1349
+ state.diagnosticEmitter.on("diagnostics", onDiagnostics);
1350
+ const timeout = setTimeout(() => {
1351
+ if (debounceTimer)
1352
+ clearTimeout(debounceTimer);
1353
+ state.diagnosticEmitter.off("diagnostics", onDiagnostics);
1354
+ resolve();
1355
+ }, timeoutMs);
1356
+ });
1357
+ }
1358
+ export function handleNotifyExternalChange(state, filePath, type) {
1359
+ if (!isClientAlive(state))
1360
+ return;
1361
+ const normalizedPath = normalizeMapKey(filePath);
1362
+ const uri = state.openDocumentUris?.get(normalizedPath) ?? pathToFileURL(filePath).href;
1363
+ state.watchQueue.enqueue(uri, type);
1364
+ }
1365
+ async function sendDidSave(state, uri, content) {
1366
+ const save = state.saveOptions;
1367
+ if (!save)
1368
+ return;
1369
+ if (!isClientAlive(state))
1370
+ return;
1371
+ const limit = save.includeText ? exceedsLspSyncLimits(content) : { tooLarge: false, reason: "" };
1372
+ if (limit.tooLarge) {
1373
+ recordDegradationOnce({
1374
+ kind: "lsp-did-save-text-omitted",
1375
+ subject: state.serverId,
1376
+ reason: limit.reason
1377
+ });
1378
+ }
1379
+ await safeSendNotification(state.connection, "textDocument/didSave", {
1380
+ textDocument: { uri },
1381
+ ...save.includeText && !limit.tooLarge ? { text: content } : {}
1382
+ });
1383
+ }
1384
+ async function handleNotifyOpenOnce(state, filePath, content, languageId, preserveDiagnostics = false, silent = false, coalescedCount = 0, saved = false) {
1385
+ if (!isClientAlive(state))
1386
+ return;
1387
+ const normalizedPath = normalizeMapKey(filePath);
1388
+ const uri = state.openDocumentUris?.get(normalizedPath) ?? pathToFileURL(filePath).href;
1389
+ if (state.openDocuments.has(normalizedPath) || state.pendingOpens.has(normalizedPath)) {
1390
+ const version = (state.documentVersions.get(normalizedPath) ?? 0) + 1;
1391
+ state.documentVersions.set(normalizedPath, version);
1392
+ if (!preserveDiagnostics) {
1393
+ clearDiagnosticsForPath(state, normalizedPath);
1394
+ }
1395
+ if (getStrategy(state.serverId, state.launchVariant).reopenOnResync) {
1396
+ await safeSendNotification(state.connection, "textDocument/didClose", {
1397
+ textDocument: { uri }
1398
+ });
1399
+ state.openDocuments.delete(normalizedPath);
1400
+ state.openDocumentUris?.delete(normalizedPath);
1401
+ state.documentVersions.set(normalizedPath, version);
1402
+ state.documentOpenedAt.set(normalizedPath, Date.now());
1403
+ state.diagnosticPublicationCounts.set(normalizedPath, 0);
1404
+ if (!isClientAlive(state))
1405
+ return;
1406
+ const reopenSent = await safeSendNotification(state.connection, "textDocument/didOpen", { textDocument: { uri, languageId, version, text: content } });
1407
+ if (reopenSent)
1408
+ recordSentContent(state, normalizedPath, version, content, coalescedCount);
1409
+ state.openDocuments.add(normalizedPath);
1410
+ state.openDocumentUris?.set(normalizedPath, uri);
1411
+ if (saved && reopenSent)
1412
+ await sendDidSave(state, uri, content);
1413
+ return;
1414
+ }
1415
+ const changeSent = await safeSendNotification(state.connection, "textDocument/didChange", {
1416
+ textDocument: { uri, version },
1417
+ contentChanges: buildContentChanges(state, normalizedPath, content)
1418
+ });
1419
+ if (changeSent)
1420
+ recordSentContent(state, normalizedPath, version, content, coalescedCount);
1421
+ if (saved && changeSent)
1422
+ await sendDidSave(state, uri, content);
1423
+ return;
1424
+ }
1425
+ state.pendingOpens.add(normalizedPath);
1426
+ state.documentVersions.set(normalizedPath, 0);
1427
+ state.documentOpenedAt.set(normalizedPath, Date.now());
1428
+ state.diagnosticPublicationCounts.set(normalizedPath, 0);
1429
+ clearDiagnosticsForPath(state, normalizedPath);
1430
+ if (!silent) {
1431
+ let fileExists = true;
1432
+ try {
1433
+ await access(filePath);
1434
+ } catch {
1435
+ fileExists = false;
1436
+ }
1437
+ state.watchQueue.enqueue(uri, fileExists ? 2 : 1);
1438
+ }
1439
+ if (!isClientAlive(state))
1440
+ return;
1441
+ const openSent = await safeSendNotification(state.connection, "textDocument/didOpen", { textDocument: { uri, languageId, version: 0, text: content } });
1442
+ if (openSent)
1443
+ recordSentContent(state, normalizedPath, 0, content, coalescedCount);
1444
+ state.pendingOpens.delete(normalizedPath);
1445
+ state.openDocuments.add(normalizedPath);
1446
+ state.closedDocuments?.delete(normalizedPath);
1447
+ state.openDocumentUris?.set(normalizedPath, uri);
1448
+ if (saved && openSent)
1449
+ await sendDidSave(state, uri, content);
1450
+ probeTsserverProjectIdentity({
1451
+ serverId: state.serverId,
1452
+ launchVariant: state.launchVariant,
1453
+ clientRoot: state.root,
1454
+ file: filePath,
1455
+ normalizedFile: normalizedPath,
1456
+ probedFiles: state.projectIdentityProbedFiles ?? (state.projectIdentityProbedFiles = new Set),
1457
+ commandChannel: {
1458
+ executeCommand: (command, args) => runReadOnlyServerCommand(state, command, args)
1459
+ }
1460
+ });
1461
+ }
1462
+ function enqueueDocumentNotify(state, normalizedPath, run, saved = false) {
1463
+ let queue = state.notifyChangeQueues.get(normalizedPath);
1464
+ if (!queue) {
1465
+ queue = { running: false };
1466
+ state.notifyChangeQueues.set(normalizedPath, queue);
1467
+ }
1468
+ return new Promise((resolve, reject) => {
1469
+ const previous = queue?.pending;
1470
+ const waiters = previous?.waiters ?? [];
1471
+ waiters.push({ resolve, reject });
1472
+ queue.pending = {
1473
+ run,
1474
+ waiters,
1475
+ coalescedCount: (previous?.coalescedCount ?? 0) + (previous ? 1 : 0),
1476
+ saved: saved || previous?.saved === true
1477
+ };
1478
+ if (queue.running)
1479
+ return;
1480
+ queue.running = true;
1481
+ Promise.resolve().then(async () => {
1482
+ try {
1483
+ for (;; ) {
1484
+ const next = queue.pending;
1485
+ if (!next)
1486
+ break;
1487
+ queue.pending = undefined;
1488
+ try {
1489
+ await next.run(next.coalescedCount, next.saved);
1490
+ for (const waiter of next.waiters)
1491
+ waiter.resolve();
1492
+ } catch (error) {
1493
+ for (const waiter of next.waiters)
1494
+ waiter.reject(error);
1495
+ }
1496
+ }
1497
+ } finally {
1498
+ queue.running = false;
1499
+ if (!queue.pending && state.notifyChangeQueues.get(normalizedPath) === queue) {
1500
+ state.notifyChangeQueues.delete(normalizedPath);
1501
+ }
1502
+ }
1503
+ });
1504
+ });
1505
+ }
1506
+ function cancelDocumentNotifyQueues(state) {
1507
+ for (const queue of state.notifyChangeQueues.values()) {
1508
+ for (const waiter of queue.pending?.waiters ?? [])
1509
+ waiter.resolve();
1510
+ queue.pending = undefined;
1511
+ }
1512
+ state.notifyChangeQueues.clear();
1513
+ }
1514
+ export function handleNotifyOpen(state, filePath, content, languageId, preserveDiagnostics = false, silent = false, saved = false) {
1515
+ if (!isClientAlive(state))
1516
+ return Promise.resolve();
1517
+ const normalizedPath = normalizeMapKey(filePath);
1518
+ return enqueueDocumentNotify(state, normalizedPath, (coalescedCount, queuedSaved) => handleNotifyOpenOnce(state, filePath, content, languageId, preserveDiagnostics, silent, coalescedCount, queuedSaved), saved);
1519
+ }
1520
+ async function handleNotifyChangeOnce(state, filePath, content, normalizedPath, coalescedCount = 0) {
1521
+ if (!isClientAlive(state))
1522
+ return;
1523
+ const uri = state.openDocumentUris?.get(normalizedPath) ?? pathToFileURL(filePath).href;
1524
+ if (!state.openDocuments.has(normalizedPath)) {
1525
+ const fallbackOpenSent = await safeSendNotification(state.connection, "textDocument/didOpen", {
1526
+ textDocument: {
1527
+ uri,
1528
+ languageId: "plaintext",
1529
+ version: 0,
1530
+ text: content
1531
+ }
1532
+ });
1533
+ state.documentVersions.set(normalizedPath, 0);
1534
+ state.documentOpenedAt.set(normalizedPath, Date.now());
1535
+ state.diagnosticPublicationCounts.set(normalizedPath, 0);
1536
+ if (fallbackOpenSent)
1537
+ recordSentContent(state, normalizedPath, 0, content, coalescedCount);
1538
+ state.openDocuments.add(normalizedPath);
1539
+ state.openDocumentUris?.set(normalizedPath, uri);
1540
+ return;
1541
+ }
1542
+ const version = (state.documentVersions.get(normalizedPath) ?? 0) + 1;
1543
+ state.documentVersions.set(normalizedPath, version);
1544
+ clearDiagnosticsForPath(state, normalizedPath);
1545
+ const changeSent = await safeSendNotification(state.connection, "textDocument/didChange", {
1546
+ textDocument: { uri, version },
1547
+ contentChanges: buildContentChanges(state, normalizedPath, content)
1548
+ });
1549
+ if (changeSent)
1550
+ recordSentContent(state, normalizedPath, version, content, coalescedCount);
1551
+ }
1552
+ export function handleNotifyChange(state, filePath, content) {
1553
+ if (!isClientAlive(state))
1554
+ return Promise.resolve();
1555
+ const normalizedPath = normalizeMapKey(filePath);
1556
+ return enqueueDocumentNotify(state, normalizedPath, (coalescedCount) => handleNotifyChangeOnce(state, filePath, content, normalizedPath, coalescedCount));
1557
+ }
1558
+ export async function closeDocument(state, filePath) {
1559
+ if (!isClientAlive(state))
1560
+ return;
1561
+ const normalizedPath = normalizeMapKey(filePath);
1562
+ if (!state.openDocuments.has(normalizedPath))
1563
+ return;
1564
+ await safeSendNotification(state.connection, "textDocument/didClose", {
1565
+ textDocument: {
1566
+ uri: state.openDocumentUris?.get(normalizedPath) ?? pathToFileURL(filePath).href
1567
+ }
1568
+ });
1569
+ state.openDocuments.delete(normalizedPath);
1570
+ state.closedDocuments?.add(normalizedPath);
1571
+ state.openDocumentUris?.delete(normalizedPath);
1572
+ state.documentVersions.delete(normalizedPath);
1573
+ state.documentOpenedAt.delete(normalizedPath);
1574
+ state.diagnosticPublicationCounts.delete(normalizedPath);
1575
+ state.projectIdentityProbedFiles?.delete(normalizedPath);
1576
+ const retained = state.documentContentHashes.get(normalizedPath);
1577
+ if (retained?.text !== undefined) {
1578
+ state.incrementalTextRetainedEntries = Math.max(0, (state.incrementalTextRetainedEntries ?? 1) - 1);
1579
+ state.incrementalTextRetainedBytes = Math.max(0, (state.incrementalTextRetainedBytes ?? retained.text.length * 2) - retained.text.length * 2);
1580
+ state.incrementalTextBearingPaths?.delete(normalizedPath);
1581
+ }
1582
+ state.documentContentHashes.delete(normalizedPath);
1583
+ clearDiagnosticsForPath(state, normalizedPath);
1584
+ }
1585
+ function isAtLeastAsAggressiveShutdown(existing, requested) {
1586
+ return !!existing.fast >= !!requested.fast && !!existing.processExiting >= !!requested.processExiting;
1587
+ }
1588
+ export function clientShutdown(state, options = {}) {
1589
+ if (state.shutdownPromise && state.shutdownOptions && isAtLeastAsAggressiveShutdown(state.shutdownOptions, options)) {
1590
+ return state.shutdownPromise;
1591
+ }
1592
+ state.shutdownOptions = options;
1593
+ const attempt = clientShutdownOnce(state, options);
1594
+ state.shutdownPromise = attempt;
1595
+ attempt.catch(() => {
1596
+ if (state.shutdownPromise === attempt) {
1597
+ state.shutdownPromise = undefined;
1598
+ state.shutdownOptions = undefined;
1599
+ }
1600
+ });
1601
+ return attempt;
1602
+ }
1603
+ async function clientShutdownOnce(state, options) {
1604
+ const shutdownStart = Date.now();
1605
+ state.shutdownRequested = true;
1606
+ state.isConnected = false;
1607
+ state.isDestroyed = true;
1608
+ for (const timer of state.pendingDiagnostics.values()) {
1609
+ clearTimeout(timer);
1610
+ }
1611
+ state.pendingDiagnostics.clear();
1612
+ state.pendingOpens.clear();
1613
+ state.openDocuments.clear();
1614
+ state.openDocumentUris?.clear();
1615
+ cancelDocumentNotifyQueues(state);
1616
+ state.projectIdentityProbedFiles?.clear();
1617
+ state.watchQueue?.cancel();
1618
+ state.diagnosticEmitter.removeAllListeners();
1619
+ let shutdownRequestTimedOut = false;
1620
+ let exitNotifyTimedOut = false;
1621
+ let shutdownRequestUndelivered = false;
1622
+ let exitNotifyUndelivered = false;
1623
+ try {
1624
+ if (!options.fast) {
1625
+ try {
1626
+ const shutdownAck = await withTimeout(safeSendRequest(state.connection, "shutdown", {}), SHUTDOWN_REQUEST_TIMEOUT_MS);
1627
+ if (shutdownAck === undefined)
1628
+ shutdownRequestUndelivered = true;
1629
+ } catch (err) {
1630
+ if (isShutdownTimeoutError(err, SHUTDOWN_REQUEST_TIMEOUT_MS)) {
1631
+ shutdownRequestTimedOut = true;
1632
+ } else {
1633
+ shutdownRequestUndelivered = true;
1634
+ }
1635
+ }
1636
+ try {
1637
+ const exitSent = await withTimeout(safeSendNotification(state.connection, "exit", {}), EXIT_NOTIFY_TIMEOUT_MS);
1638
+ if (exitSent === false)
1639
+ exitNotifyUndelivered = true;
1640
+ } catch (err) {
1641
+ if (isShutdownTimeoutError(err, EXIT_NOTIFY_TIMEOUT_MS)) {
1642
+ exitNotifyTimedOut = true;
1643
+ } else {
1644
+ exitNotifyUndelivered = true;
1645
+ }
1646
+ }
1647
+ }
1648
+ } finally {
1649
+ disposeClientConnection(state);
1650
+ const pid = state.lspProcess.pid;
1651
+ logLatency({
1652
+ type: "phase",
1653
+ phase: "lsp_client_shutdown",
1654
+ filePath: state.root,
1655
+ durationMs: Date.now() - shutdownStart,
1656
+ metadata: {
1657
+ serverId: state.serverId,
1658
+ pid,
1659
+ fast: !!options.fast,
1660
+ processExiting: !!options.processExiting,
1661
+ shutdownRequestTimedOut,
1662
+ exitNotifyTimedOut,
1663
+ shutdownRequestUndelivered,
1664
+ exitNotifyUndelivered,
1665
+ shutdownOutcome: options.fast ? "fast" : shutdownRequestTimedOut || exitNotifyTimedOut || shutdownRequestUndelivered || exitNotifyUndelivered ? "forced" : "graceful"
1666
+ }
1667
+ });
1668
+ removeLspChild(pid, extractSpawnMarker(state.lspProcess.args)).catch((err) => {
1669
+ logLatency({
1670
+ type: "phase",
1671
+ phase: "lsp_registry_write_failed",
1672
+ filePath: "",
1673
+ durationMs: 0,
1674
+ metadata: { op: "remove", pid, error: String(err) }
1675
+ });
1676
+ });
1677
+ await killProcessTree(state.lspProcess.process, pid, options);
1678
+ }
1679
+ }
1680
+ async function toWirePosition(state, filePath, line, character) {
1681
+ if (state.positionEncoding === "utf-16")
1682
+ return { line, character };
1683
+ try {
1684
+ const content = await readFile(filePath, "utf8");
1685
+ return {
1686
+ line,
1687
+ character: convertCharacterOffset(state.positionEncoding, lineTextAt(content, line), character)
1688
+ };
1689
+ } catch {
1690
+ return { line, character };
1691
+ }
1692
+ }
1693
+ function navStaleDropEnabled() {
1694
+ return process.env.DM_LENS_LSP_NAV_STALE_DROP !== "0";
1695
+ }
1696
+ export async function navRequest(state, method, params, staleCheckPath, timeoutMs = NAV_REQUEST_TIMEOUT_MS, signal = getAmbientAbortSignal()) {
1697
+ if (!isClientAlive(state))
1698
+ return null;
1699
+ const normalizedPath = staleCheckPath !== undefined ? normalizeMapKey(staleCheckPath) : undefined;
1700
+ const requestVersion = normalizedPath !== undefined ? state.documentVersions.get(normalizedPath) : undefined;
1701
+ const requestStartedAt = Date.now();
1702
+ const requestPromise = safeSendRequest(state.connection, method, params, signal);
1703
+ const result = await withTimeout(requestPromise, timeoutMs).catch((err) => {
1704
+ if (isNavTimeoutError(err, timeoutMs)) {
1705
+ recordNavTimeoutTelemetry({
1706
+ method,
1707
+ scope: normalizedPath,
1708
+ budgetMs: timeoutMs,
1709
+ elapsedMs: Date.now() - requestStartedAt
1710
+ });
1711
+ armNavLateAnswerTelemetry({
1712
+ requestPromise,
1713
+ method,
1714
+ scope: normalizedPath,
1715
+ requestStartedAt
1716
+ });
1717
+ return;
1718
+ }
1719
+ if (err instanceof Error && err.message.startsWith("Timeout after")) {
1720
+ return;
1721
+ }
1722
+ throw err;
1723
+ });
1724
+ if (normalizedPath !== undefined && requestVersion !== undefined && navStaleDropEnabled()) {
1725
+ const currentVersion = state.documentVersions.get(normalizedPath);
1726
+ if (currentVersion !== undefined && currentVersion > requestVersion) {
1727
+ return;
1728
+ }
1729
+ }
1730
+ return result;
1731
+ }
1732
+ function isNavTimeoutError(err, timeoutMs) {
1733
+ return err instanceof Error && err.message === `Timeout after ${timeoutMs}ms`;
1734
+ }
1735
+ function isShutdownTimeoutError(err, timeoutMs) {
1736
+ return err instanceof Error && err.message === `Timeout after ${timeoutMs}ms`;
1737
+ }
1738
+ const NAV_REQUEST_NO_PATH_SCOPE = "*no-path*";
1739
+ function recordNavTimeoutTelemetry(args) {
1740
+ emitBounded("lsp_nav_request_timeout", `${args.method}:${args.scope ?? NAV_REQUEST_NO_PATH_SCOPE}`, {
1741
+ type: "phase",
1742
+ filePath: args.scope ?? NAV_REQUEST_NO_PATH_SCOPE,
1743
+ durationMs: args.elapsedMs,
1744
+ metadata: { method: args.method, effectiveBudgetMs: args.budgetMs }
1745
+ }, {
1746
+ ledgerKind: "lsp-nav-request-timeout",
1747
+ risingEdgePer: "identity",
1748
+ reason: `timeout budget=${args.budgetMs}ms elapsed=${args.elapsedMs}ms`
1749
+ });
1750
+ }
1751
+ function armNavLateAnswerTelemetry(args) {
1752
+ args.requestPromise.then(() => {
1753
+ try {
1754
+ const elapsedMs = Date.now() - args.requestStartedAt;
1755
+ emitBounded("lsp_nav_late_answer_discarded", `${args.method}:${args.scope ?? NAV_REQUEST_NO_PATH_SCOPE}`, {
1756
+ type: "phase",
1757
+ filePath: args.scope ?? NAV_REQUEST_NO_PATH_SCOPE,
1758
+ durationMs: elapsedMs,
1759
+ metadata: { method: args.method }
1760
+ }, {
1761
+ ledgerKind: "lsp-nav-late-answer",
1762
+ risingEdgePer: "identity",
1763
+ reason: `late nav answer discarded after ${elapsedMs}ms`
1764
+ });
1765
+ } catch {}
1766
+ }, () => {});
1767
+ }
1768
+ function chooseLivenessProbe(state) {
1769
+ if (state.operationSupport?.workspaceSymbol === true) {
1770
+ return {
1771
+ method: "workspace/symbol",
1772
+ params: { query: LIVENESS_PING_QUERY }
1773
+ };
1774
+ }
1775
+ const openUri = firstOpenDocumentUri(state);
1776
+ if (openUri === undefined)
1777
+ return;
1778
+ if (state.operationSupport?.documentSymbol === true) {
1779
+ return {
1780
+ method: "textDocument/documentSymbol",
1781
+ params: { textDocument: { uri: openUri } }
1782
+ };
1783
+ }
1784
+ if (state.operationSupport?.hover === true) {
1785
+ return {
1786
+ method: "textDocument/hover",
1787
+ params: {
1788
+ textDocument: { uri: openUri },
1789
+ position: { line: 0, character: 0 }
1790
+ }
1791
+ };
1792
+ }
1793
+ return;
1794
+ }
1795
+ function firstOpenDocumentUri(state) {
1796
+ for (const normalizedPath of state.openDocuments) {
1797
+ const uri = state.openDocumentUris?.get(normalizedPath);
1798
+ if (uri !== undefined)
1799
+ return uri;
1800
+ }
1801
+ return;
1802
+ }
1803
+ async function clientPingLiveness(state, timeoutMs = LIVENESS_PING_TIMEOUT_MS) {
1804
+ if (!isClientAlive(state))
1805
+ return false;
1806
+ const probe = chooseLivenessProbe(state);
1807
+ if (probe === undefined) {
1808
+ try {
1809
+ incrementDegradationCount({
1810
+ kind: "lsp-liveness-probe-unsupported",
1811
+ subject: state.serverId,
1812
+ reason: "no advertised request method to probe with (no " + "workspaceSymbolProvider, and no open document with " + "documentSymbolProvider or hoverProvider); liveness from " + "process and connection state only"
1813
+ });
1814
+ } catch {}
1815
+ return isClientAlive(state);
1816
+ }
1817
+ try {
1818
+ await withTimeout(safeSendRequest(state.connection, probe.method, probe.params), timeoutMs);
1819
+ } catch (err) {
1820
+ if (err instanceof Error && err.message.startsWith("Timeout after")) {
1821
+ return false;
1822
+ }
1823
+ }
1824
+ return isClientAlive(state);
1825
+ }
1826
+ function syncMutationContextSlot(state) {
1827
+ state.activeMutationContext = state.activeMutationDepth === 1 ? state.mutationContextOwner : undefined;
1828
+ }
1829
+ export async function runServerCommand(state, command, args, timeoutMs = EXECUTE_COMMAND_TIMEOUT_MS, mutationContext) {
1830
+ if (!isClientAlive(state)) {
1831
+ return { executed: false, reason: "lsp client not alive" };
1832
+ }
1833
+ if (!state.advertisedCommands.has(command)) {
1834
+ return {
1835
+ executed: false,
1836
+ reason: `command "${command}" is not advertised by the ${state.serverId} server`
1837
+ };
1838
+ }
1839
+ state.serverEditsAllowed += 1;
1840
+ state.activeMutationDepth = (state.activeMutationDepth ?? 0) + 1;
1841
+ const isMutationContextOwner = state.activeMutationDepth === 1;
1842
+ if (isMutationContextOwner) {
1843
+ state.mutationContextOwner = mutationContext;
1844
+ }
1845
+ syncMutationContextSlot(state);
1846
+ try {
1847
+ let result;
1848
+ try {
1849
+ result = await withTimeout(safeSendRequest(state.connection, "workspace/executeCommand", {
1850
+ command,
1851
+ arguments: args ?? []
1852
+ }), timeoutMs);
1853
+ } catch (err) {
1854
+ if (err instanceof Error && err.message.startsWith("Timeout after")) {
1855
+ return {
1856
+ executed: false,
1857
+ reason: `workspace/executeCommand timed out after ${timeoutMs}ms — the command may still be applying server-side`
1858
+ };
1859
+ }
1860
+ throw err;
1861
+ }
1862
+ return { executed: true, result };
1863
+ } finally {
1864
+ state.serverEditsAllowed -= 1;
1865
+ state.activeMutationDepth = Math.max(0, (state.activeMutationDepth ?? 0) - 1);
1866
+ if (isMutationContextOwner) {
1867
+ state.mutationContextOwner = undefined;
1868
+ }
1869
+ syncMutationContextSlot(state);
1870
+ }
1871
+ }
1872
+ export async function runReadOnlyServerCommand(state, command, args, timeoutMs = PROBE_COMMAND_TIMEOUT_MS) {
1873
+ if (!isClientAlive(state)) {
1874
+ return { executed: false, reason: "lsp client not alive" };
1875
+ }
1876
+ if (!state.advertisedCommands.has(command)) {
1877
+ return {
1878
+ executed: false,
1879
+ reason: `command "${command}" is not advertised by the ${state.serverId} server`
1880
+ };
1881
+ }
1882
+ try {
1883
+ const result = await withTimeout(safeSendRequest(state.connection, "workspace/executeCommand", {
1884
+ command,
1885
+ arguments: args ?? []
1886
+ }), timeoutMs);
1887
+ return { executed: true, result };
1888
+ } catch (err) {
1889
+ if (err instanceof Error && err.message.startsWith("Timeout after")) {
1890
+ return {
1891
+ executed: false,
1892
+ reason: `workspace/executeCommand timed out after ${timeoutMs}ms`
1893
+ };
1894
+ }
1895
+ throw err;
1896
+ }
1897
+ }
1898
+ function validateWorkspaceEditVersions(state, edit) {
1899
+ for (const change of edit.documentChanges ?? []) {
1900
+ if (typeof change !== "object" || change === null || !("textDocument" in change))
1901
+ continue;
1902
+ const textDocument = change.textDocument;
1903
+ if (!textDocument || typeof textDocument.uri !== "string" || textDocument.version == null)
1904
+ continue;
1905
+ const current = state.documentVersions.get(normalizeMapKey(uriToPath(textDocument.uri)));
1906
+ if (current === undefined || current !== textDocument.version) {
1907
+ throw new Error(`stale workspace edit document version for ${textDocument.uri}`);
1908
+ }
1909
+ }
1910
+ }
1911
+ function stripDocumentVersions(edit) {
1912
+ if (!Array.isArray(edit.documentChanges))
1913
+ return edit;
1914
+ const documentChanges = edit.documentChanges.map((change) => {
1915
+ if (typeof change === "object" && change !== null && "textDocument" in change && "edits" in change) {
1916
+ const textDocument = change.textDocument;
1917
+ if (textDocument && typeof textDocument.version === "number") {
1918
+ return {
1919
+ ...change,
1920
+ textDocument: { ...textDocument, version: null }
1921
+ };
1922
+ }
1923
+ }
1924
+ return change;
1925
+ });
1926
+ return { ...edit, documentChanges };
1927
+ }
1928
+ export async function normalizeClientWorkspaceEdit(state, edit) {
1929
+ validateWorkspaceEditVersions(state, edit);
1930
+ const normalized = await normalizeWorkspaceEditToUtf16(edit, state.positionEncoding, state.root);
1931
+ return stripDocumentVersions(normalized);
1932
+ }
1933
+ async function resolveCodeActionBestEffort(state, action) {
1934
+ if (!isClientAlive(state))
1935
+ return action;
1936
+ if (action.edit) {
1937
+ return {
1938
+ ...action,
1939
+ edit: await normalizeClientWorkspaceEdit(state, action.edit)
1940
+ };
1941
+ }
1942
+ if (!state.operationSupport.codeActionResolve) {
1943
+ recordDegradationOnce({
1944
+ kind: "lsp-capability-skip",
1945
+ subject: `${state.serverId}:codeAction/resolve`,
1946
+ reason: "server did not advertise codeActionProvider.resolveProvider"
1947
+ });
1948
+ return action;
1949
+ }
1950
+ let resolved;
1951
+ try {
1952
+ resolved = await withTimeout(safeSendRequest(state.connection, "codeAction/resolve", action), NAV_REQUEST_TIMEOUT_MS);
1953
+ } catch {
1954
+ return action;
1955
+ }
1956
+ if (!resolved || typeof resolved !== "object")
1957
+ return action;
1958
+ const merged = { ...action, ...resolved };
1959
+ return merged.edit ? {
1960
+ ...merged,
1961
+ edit: await normalizeClientWorkspaceEdit(state, merged.edit)
1962
+ } : merged;
1963
+ }
1964
+ export async function createLSPClient(options) {
1965
+ installCrashGuard();
1966
+ const { serverId, process: lspProcess, root, sessionCwd, initialization, initializeTimeoutMs = INITIALIZE_TIMEOUT_MS, launchVariant, onDiagnosticsPublished } = options;
1967
+ recordLspChild({
1968
+ pid: lspProcess.pid,
1969
+ serverId,
1970
+ command: lspProcess.command,
1971
+ marker: extractSpawnMarker(lspProcess.args),
1972
+ sessionIdentity: {
1973
+ projectRoot: sessionCwd ?? process.cwd(),
1974
+ rootSource: sessionCwd ? "service-cwd" : "lsp-fallback",
1975
+ startedAt: new Date(workspaceDiagnosticsCacheSessionStart()).toISOString()
1976
+ }
1977
+ }).catch((err) => {
1978
+ logLatency({
1979
+ type: "phase",
1980
+ phase: "lsp_registry_write_failed",
1981
+ filePath: "",
1982
+ durationMs: 0,
1983
+ metadata: { op: "record", pid: lspProcess.pid, error: String(err) }
1984
+ });
1985
+ });
1986
+ const startupState = {
1987
+ exitCode: null,
1988
+ exitSignal: null,
1989
+ closeCode: null,
1990
+ closeSignal: null,
1991
+ stderr: ""
1992
+ };
1993
+ const stderrRing = [];
1994
+ const MAX_STDERR_LINES = 100;
1995
+ const onStderr = (chunk) => {
1996
+ stderrRing.push(chunk.toString());
1997
+ if (stderrRing.length > MAX_STDERR_LINES)
1998
+ stderrRing.shift();
1999
+ if (startupState.stderr.length < 4096) {
2000
+ startupState.stderr += chunk.toString();
2001
+ }
2002
+ };
2003
+ const recentStderr = (lines = 10) => stderrRing.slice(-lines).join("").trim();
2004
+ const checkProcessAlive = () => {
2005
+ const exited = lspProcess.process.exitCode;
2006
+ if (exited !== null) {
2007
+ const tail = recentStderr(20);
2008
+ return `LSP server ${serverId} exited with code ${exited}${tail ? `. stderr: ${tail}` : ""}`;
2009
+ }
2010
+ if (lspProcess.process.killed) {
2011
+ return `LSP server ${serverId} was killed`;
2012
+ }
2013
+ return;
2014
+ };
2015
+ const onProcessExit = (code, signal) => {
2016
+ startupState.exitCode = code;
2017
+ startupState.exitSignal = signal;
2018
+ };
2019
+ const onProcessClose = (code, signal) => {
2020
+ startupState.closeCode = code;
2021
+ startupState.closeSignal = signal;
2022
+ };
2023
+ lspProcess.stderr.on("data", onStderr);
2024
+ lspProcess.process.on("exit", onProcessExit);
2025
+ lspProcess.process.on("close", onProcessClose);
2026
+ const streamErrorHandler = (_label) => (err) => {
2027
+ if (err.code === "ERR_STREAM_DESTROYED" || err.code === "ERR_STREAM_WRITE_AFTER_END" || err.code === "EPIPE" || err.code === "ECONNRESET")
2028
+ return;
2029
+ };
2030
+ lspProcess.stdin.on("error", streamErrorHandler("stdin"));
2031
+ lspProcess.stdout.on("error", streamErrorHandler("stdout"));
2032
+ lspProcess.stderr.on("error", streamErrorHandler("stderr"));
2033
+ const connection = createMessageConnection(new StreamMessageReader(lspProcess.stdout), new StreamMessageWriter(lspProcess.stdin));
2034
+ const diagnosticEmitter = new EventEmitter;
2035
+ diagnosticEmitter.setMaxListeners(50);
2036
+ const state = {
2037
+ isConnected: true,
2038
+ isDestroyed: false,
2039
+ shutdownRequested: false,
2040
+ shutdownPromise: undefined,
2041
+ shutdownOptions: undefined,
2042
+ exitedAt: undefined,
2043
+ connectionDisposed: false,
2044
+ lastError: undefined,
2045
+ connection,
2046
+ pushDiagnostics: new Map,
2047
+ pushDiagnosticTimestamps: new Map,
2048
+ documentPullDiagnostics: new Map,
2049
+ documentPullDiagnosticTimestamps: new Map,
2050
+ pullFailureHistory: [],
2051
+ pendingDiagnostics: new Map,
2052
+ diagnosticPublicationCounts: new Map,
2053
+ documentOpenedAt: new Map,
2054
+ diagnosticEmitter,
2055
+ diagnosticsVersion: 0,
2056
+ diagnosticsVersionsByPath: new Map,
2057
+ documentVersions: new Map,
2058
+ notifyChangeQueues: new Map,
2059
+ diagnosticDocVersions: new Map,
2060
+ documentContentHashes: new Map,
2061
+ incrementalTextRetainedEntries: 0,
2062
+ incrementalTextBearingPaths: new Set,
2063
+ incrementalTextRetainedBytes: 0,
2064
+ diagnosticBindings: new Map,
2065
+ pullResultIds: new Map,
2066
+ documentPullDiagnosticsBySource: new Map,
2067
+ pullGenerations: new Map,
2068
+ pullRequestSequences: new Map,
2069
+ workspacePullResultCache: new Map,
2070
+ openDocuments: new Set,
2071
+ emptyFirstPublishHoldSpent: false,
2072
+ closedDocuments: new Set,
2073
+ openDocumentUris: new Map,
2074
+ pendingOpens: new Set,
2075
+ projectIdentityProbedFiles: new Set,
2076
+ workspaceDiagnosticsSupport: undefined,
2077
+ operationSupport: undefined,
2078
+ staticDiagnosticsMode: "push-only",
2079
+ positionEncoding: "utf-16",
2080
+ syncKind: TEXT_DOCUMENT_SYNC_KIND_FULL,
2081
+ dynamicRegistrations: new Map,
2082
+ advertisedCommands: new Set,
2083
+ serverEditsAllowed: 0,
2084
+ activeMutationDepth: 0,
2085
+ serverId,
2086
+ launchVariant,
2087
+ root,
2088
+ lspProcess,
2089
+ watchQueue: undefined
2090
+ };
2091
+ activeLspClientSet().add(state);
2092
+ state.watchQueue = new WatchedFilesQueue((changes) => {
2093
+ if (!isClientAlive(state))
2094
+ return;
2095
+ safeSendNotification(state.connection, "workspace/didChangeWatchedFiles", { changes });
2096
+ });
2097
+ setupIncomingHandlers(state, initialization, onDiagnosticsPublished);
2098
+ connection.listen();
2099
+ setupConnectionLifecycle(state, recentStderr);
2100
+ let initResult;
2101
+ try {
2102
+ initResult = await withTimeout(safeSendRequest(connection, "initialize", {
2103
+ processId: process.pid,
2104
+ rootUri: pathToFileURL(root).href,
2105
+ workspaceFolders: [
2106
+ { name: "workspace", uri: pathToFileURL(root).href }
2107
+ ],
2108
+ capabilities: CLIENT_CAPABILITIES,
2109
+ initializationOptions: initialization
2110
+ }), initializeTimeoutMs);
2111
+ } catch (err) {
2112
+ state.shutdownRequested = true;
2113
+ const pid = lspProcess.pid;
2114
+ killProcessTree(lspProcess.process, pid);
2115
+ removeLspChild(pid, extractSpawnMarker(lspProcess.args)).catch((err) => {
2116
+ logLatency({
2117
+ type: "phase",
2118
+ phase: "lsp_registry_write_failed",
2119
+ filePath: "",
2120
+ durationMs: 0,
2121
+ metadata: { op: "remove", pid, error: String(err) }
2122
+ });
2123
+ });
2124
+ setTimeout(() => {
2125
+ if (lspProcess.process.exitCode === null && lspProcess.process.signalCode === null && process.platform !== "win32") {
2126
+ lspProcess.process.kill("SIGKILL");
2127
+ }
2128
+ }, 2000);
2129
+ throw err;
2130
+ } finally {
2131
+ lspProcess.stderr.off("data", onStderr);
2132
+ }
2133
+ if (initResult === undefined) {
2134
+ const compactStderr = startupState.stderr.replace(/\s+/g, " ").trim().slice(0, 320);
2135
+ const reinstallHint = serverId === "cpp" ? "Install clangd (LLVM/clang-tools) and ensure clangd.exe is on PATH." : `Try reinstalling: npm install -g ${serverId}-language-server.`;
2136
+ const telemetry = [
2137
+ `pid=${lspProcess.pid}`,
2138
+ `exitCode=${startupState.exitCode ?? "none"}`,
2139
+ `exitSignal=${startupState.exitSignal ?? "none"}`,
2140
+ `closeCode=${startupState.closeCode ?? "none"}`,
2141
+ `closeSignal=${startupState.closeSignal ?? "none"}`,
2142
+ `root=${root}`,
2143
+ compactStderr ? `stderr=${compactStderr}` : "stderr=<empty>"
2144
+ ].join(" ");
2145
+ throw new Error(`[lsp] ${serverId} failed to initialize - stream may have been destroyed. ` + `The server binary may be missing or crashed immediately. ${reinstallHint} ` + `telemetry: ${telemetry}`);
2146
+ }
2147
+ state.workspaceDiagnosticsSupport = detectWorkspaceDiagnosticsSupport(initResult);
2148
+ state.operationSupport = detectOperationSupport(initResult);
2149
+ const capabilities = initResult?.capabilities ?? {};
2150
+ const workspace = isCapabilityRecord(capabilities.workspace) ? capabilities.workspace : undefined;
2151
+ const fileOperations = isCapabilityRecord(workspace) ? workspace.fileOperations : undefined;
2152
+ const malformedFileOperationRegistrations = new Set;
2153
+ if (isCapabilityRecord(fileOperations)) {
2154
+ for (const operation of ["willRename", "didRename"]) {
2155
+ if (fileOperations[operation] !== undefined && parseFileOperationFilters(fileOperations[operation]) === undefined) {
2156
+ malformedFileOperationRegistrations.add(operation);
2157
+ }
2158
+ }
2159
+ }
2160
+ state.fileOperationMalformedRegistrations = malformedFileOperationRegistrations;
2161
+ if (isCapabilityRecord(fileOperations)) {
2162
+ state.fileOperationFilters = {
2163
+ willRename: parseFileOperationFilters(fileOperations.willRename),
2164
+ didRename: parseFileOperationFilters(fileOperations.didRename)
2165
+ };
2166
+ }
2167
+ state.positionEncoding = negotiatePositionEncoding(initResult?.capabilities);
2168
+ state.syncKind = negotiateSyncKind(initResult?.capabilities);
2169
+ state.saveOptions = negotiateSaveOptions(initResult?.capabilities);
2170
+ state.rawCapabilityKeys = Object.keys(initResult?.capabilities ?? {}).sort((a, b) => a.localeCompare(b));
2171
+ for (const cmd of detectExecuteCommands(initResult)) {
2172
+ state.advertisedCommands.add(cmd);
2173
+ }
2174
+ state.staticDiagnosticsMode = state.workspaceDiagnosticsSupport.mode;
2175
+ await safeSendNotification(connection, "initialized", {});
2176
+ if (initialization) {
2177
+ await safeSendNotification(connection, "workspace/didChangeConfiguration", {
2178
+ settings: initialization
2179
+ });
2180
+ }
2181
+ return {
2182
+ serverId,
2183
+ root,
2184
+ connection,
2185
+ isAlive: () => isClientAlive(state),
2186
+ processExited: () => lspProcess.process.exitCode !== null || lspProcess.process.killed === true,
2187
+ wasShutdownIntentional: () => state.shutdownRequested,
2188
+ getExitedAt: () => state.exitedAt,
2189
+ recentStderr: (lines) => recentStderr(lines),
2190
+ getPullFailureHistory: () => state.pullFailureHistory.map((entry) => ({
2191
+ ...entry,
2192
+ message: entry.message.slice(0, 200)
2193
+ })),
2194
+ checkAlive: () => checkProcessAlive(),
2195
+ pingLiveness: (timeoutMs) => clientPingLiveness(state, timeoutMs),
2196
+ getProcessPid: () => lspProcess.pid,
2197
+ notify: {
2198
+ async open(filePath, content, languageId, preserveDiagnostics, silent, saved) {
2199
+ return handleNotifyOpen(state, filePath, content, languageId, preserveDiagnostics, silent, saved);
2200
+ },
2201
+ async change(filePath, content) {
2202
+ return handleNotifyChange(state, filePath, content);
2203
+ },
2204
+ watchedFileChange(filePath, type) {
2205
+ handleNotifyExternalChange(state, filePath, type);
2206
+ }
2207
+ },
2208
+ getDiagnostics(filePath) {
2209
+ return getMergedDiagnosticsForPath(state, normalizeMapKey(filePath));
2210
+ },
2211
+ getDiagnosticBinding(filePath) {
2212
+ return state.diagnosticBindings.get(normalizeMapKey(filePath));
2213
+ },
2214
+ getDiagnosticsVersionForPath(filePath) {
2215
+ return diagnosticsVersionForPath(state, normalizeMapKey(filePath));
2216
+ },
2217
+ getAllDiagnostics() {
2218
+ const result = new Map;
2219
+ const keys = new Set([
2220
+ ...state.pushDiagnostics.keys(),
2221
+ ...state.documentPullDiagnostics.keys()
2222
+ ]);
2223
+ for (const key of keys) {
2224
+ result.set(key, {
2225
+ diags: getMergedDiagnosticsForPath(state, key),
2226
+ ts: Math.max(state.pushDiagnosticTimestamps.get(key) ?? 0, state.documentPullDiagnosticTimestamps.get(key) ?? 0),
2227
+ binding: state.diagnosticBindings.get(key)
2228
+ });
2229
+ }
2230
+ return result;
2231
+ },
2232
+ getTrackedDiagnosticPaths() {
2233
+ return [
2234
+ ...new Set([
2235
+ ...state.pushDiagnostics.keys(),
2236
+ ...state.documentPullDiagnostics.keys()
2237
+ ])
2238
+ ].map((filePath) => process.platform === "win32" ? filePath.replace(/\//g, "\\") : filePath);
2239
+ },
2240
+ pruneDiagnostics(predicate) {
2241
+ let removed = 0;
2242
+ const keys = new Set([
2243
+ ...state.pushDiagnostics.keys(),
2244
+ ...state.documentPullDiagnostics.keys()
2245
+ ]);
2246
+ for (const key of keys) {
2247
+ const diags = getMergedDiagnosticsForPath(state, key);
2248
+ const ts = Math.max(state.pushDiagnosticTimestamps.get(key) ?? 0, state.documentPullDiagnosticTimestamps.get(key) ?? 0);
2249
+ if (!predicate(key, ts, diags))
2250
+ continue;
2251
+ clearDiagnosticsForPath(state, key);
2252
+ removed++;
2253
+ }
2254
+ return removed;
2255
+ },
2256
+ getWorkspaceDiagnosticsSupport() {
2257
+ return state.workspaceDiagnosticsSupport;
2258
+ },
2259
+ requestWorkspaceDiagnostics(budgetMs) {
2260
+ return clientRequestWorkspaceDiagnostics(state, budgetMs);
2261
+ },
2262
+ getOperationSupport() {
2263
+ return state.operationSupport;
2264
+ },
2265
+ getMalformedFileOperationRegistrations() {
2266
+ return state.fileOperationMalformedRegistrations ?? new Set;
2267
+ },
2268
+ getAdvertisedCommands() {
2269
+ return [...state.advertisedCommands];
2270
+ },
2271
+ getRawCapabilityKeys() {
2272
+ return state.rawCapabilityKeys ?? [];
2273
+ },
2274
+ getLaunchVariant() {
2275
+ return state.launchVariant;
2276
+ },
2277
+ async executeCommand(command, args, mutationContext) {
2278
+ return runServerCommand(state, command, args, EXECUTE_COMMAND_TIMEOUT_MS, mutationContext);
2279
+ },
2280
+ async executeReadOnlyCommand(command, args) {
2281
+ return runReadOnlyServerCommand(state, command, args);
2282
+ },
2283
+ get diagnosticsVersion() {
2284
+ return state.diagnosticsVersion;
2285
+ },
2286
+ async waitForDiagnostics(filePath, timeoutMs = DIAGNOSTICS_WAIT_TIMEOUT_MS, options) {
2287
+ return clientWaitForDiagnostics(state, filePath, timeoutMs, options);
2288
+ },
2289
+ async definition(filePath, line, character) {
2290
+ const result = await navRequest(state, "textDocument/definition", {
2291
+ textDocument: { uri: pathToFileURL(filePath).href },
2292
+ position: await toWirePosition(state, filePath, line, character)
2293
+ }, filePath);
2294
+ if (!result)
2295
+ return [];
2296
+ return Array.isArray(result) ? result : [result];
2297
+ },
2298
+ async typeDefinition(filePath, line, character) {
2299
+ const result = await navRequest(state, "textDocument/typeDefinition", {
2300
+ textDocument: { uri: pathToFileURL(filePath).href },
2301
+ position: await toWirePosition(state, filePath, line, character)
2302
+ }, filePath);
2303
+ if (!result)
2304
+ return [];
2305
+ return Array.isArray(result) ? result : [result];
2306
+ },
2307
+ async declaration(filePath, line, character) {
2308
+ const result = await navRequest(state, "textDocument/declaration", {
2309
+ textDocument: { uri: pathToFileURL(filePath).href },
2310
+ position: await toWirePosition(state, filePath, line, character)
2311
+ }, filePath);
2312
+ if (!result)
2313
+ return [];
2314
+ return Array.isArray(result) ? result : [result];
2315
+ },
2316
+ async references(filePath, line, character, includeDeclaration = true) {
2317
+ const result = await navRequest(state, "textDocument/references", {
2318
+ textDocument: { uri: pathToFileURL(filePath).href },
2319
+ position: await toWirePosition(state, filePath, line, character),
2320
+ context: { includeDeclaration }
2321
+ }, filePath);
2322
+ return result ?? [];
2323
+ },
2324
+ async hover(filePath, line, character) {
2325
+ const result = await navRequest(state, "textDocument/hover", {
2326
+ textDocument: { uri: pathToFileURL(filePath).href },
2327
+ position: await toWirePosition(state, filePath, line, character)
2328
+ }, filePath);
2329
+ return result ?? null;
2330
+ },
2331
+ async signatureHelp(filePath, line, character) {
2332
+ const result = await navRequest(state, "textDocument/signatureHelp", {
2333
+ textDocument: { uri: pathToFileURL(filePath).href },
2334
+ position: await toWirePosition(state, filePath, line, character)
2335
+ }, filePath);
2336
+ return result ?? null;
2337
+ },
2338
+ async documentSymbol(filePath) {
2339
+ const result = await navRequest(state, "textDocument/documentSymbol", { textDocument: { uri: pathToFileURL(filePath).href } }, filePath);
2340
+ return result ?? [];
2341
+ },
2342
+ isDocumentOpen(filePath) {
2343
+ return state.openDocuments.has(normalizeMapKey(filePath));
2344
+ },
2345
+ openDocumentPaths() {
2346
+ return [...state.openDocuments];
2347
+ },
2348
+ isBusy() {
2349
+ return (activeRequestsByConnection.get(connection) ?? 0) > 0;
2350
+ },
2351
+ getDocumentUri(filePath) {
2352
+ return state.openDocumentUris?.get(normalizeMapKey(filePath));
2353
+ },
2354
+ async workspaceSymbol(query) {
2355
+ if (!isClientAlive(state))
2356
+ return [];
2357
+ const result = await navRequest(state, "workspace/symbol", {
2358
+ query
2359
+ });
2360
+ return result ?? [];
2361
+ },
2362
+ async codeAction(filePath, line, character, endLine, endCharacter) {
2363
+ if (!isClientAlive(state))
2364
+ return [];
2365
+ const uri = pathToFileURL(filePath).href;
2366
+ const result = await navRequest(state, "textDocument/codeAction", {
2367
+ textDocument: { uri },
2368
+ range: {
2369
+ start: await toWirePosition(state, filePath, line, character),
2370
+ end: await toWirePosition(state, filePath, endLine, endCharacter)
2371
+ },
2372
+ context: {
2373
+ diagnostics: getMergedDiagnosticsForPath(state, normalizeMapKey(filePath))
2374
+ }
2375
+ }, filePath);
2376
+ if (!result || !Array.isArray(result))
2377
+ return [];
2378
+ const actions = result.filter((item) => typeof item === "object" && item !== null && ("title" in item));
2379
+ return Promise.all(actions.map((action) => resolveCodeActionBestEffort(state, action)));
2380
+ },
2381
+ async rename(filePath, line, character, newName) {
2382
+ const result = await navRequest(state, "textDocument/rename", {
2383
+ textDocument: { uri: pathToFileURL(filePath).href },
2384
+ position: await toWirePosition(state, filePath, line, character),
2385
+ newName
2386
+ }, filePath);
2387
+ return result ? await normalizeClientWorkspaceEdit(state, result) : null;
2388
+ },
2389
+ closeDocument: (filePath) => closeDocument(state, filePath),
2390
+ async willRenameFiles(oldFilePath, newFilePath) {
2391
+ if (!isClientAlive(state))
2392
+ return null;
2393
+ const oldUri = pathToFileURL(oldFilePath).href;
2394
+ const newUri = pathToFileURL(newFilePath).href;
2395
+ if (!await fileOperationFiltersMatch(state.fileOperationFilters?.willRename, oldUri, newUri, oldFilePath, newFilePath)) {
2396
+ recordDegradationOnce({
2397
+ kind: "lsp-capability-skip",
2398
+ subject: `${state.serverId}:workspace/willRenameFiles:filter`,
2399
+ reason: "filter-mismatch"
2400
+ });
2401
+ return null;
2402
+ }
2403
+ const result = await navRequest(state, "workspace/willRenameFiles", {
2404
+ files: [
2405
+ {
2406
+ oldUri,
2407
+ newUri
2408
+ }
2409
+ ]
2410
+ });
2411
+ return result ? await normalizeClientWorkspaceEdit(state, result) : null;
2412
+ },
2413
+ async didRenameFiles(oldFilePath, newFilePath, oldUri, newUri) {
2414
+ if (!isClientAlive(state))
2415
+ return;
2416
+ const wireOldUri = oldUri ?? pathToFileURL(oldFilePath).href;
2417
+ const wireNewUri = newUri ?? pathToFileURL(newFilePath).href;
2418
+ if (!await fileOperationFiltersMatch(state.fileOperationFilters?.didRename, wireOldUri, wireNewUri, oldFilePath, newFilePath)) {
2419
+ recordDegradationOnce({
2420
+ kind: "lsp-capability-skip",
2421
+ subject: `${state.serverId}:workspace/didRenameFiles:filter`,
2422
+ reason: "filter-mismatch"
2423
+ });
2424
+ return;
2425
+ }
2426
+ await safeSendNotification(state.connection, "workspace/didRenameFiles", {
2427
+ files: [
2428
+ {
2429
+ oldUri: wireOldUri,
2430
+ newUri: wireNewUri
2431
+ }
2432
+ ]
2433
+ });
2434
+ },
2435
+ async implementation(filePath, line, character) {
2436
+ const result = await navRequest(state, "textDocument/implementation", {
2437
+ textDocument: { uri: pathToFileURL(filePath).href },
2438
+ position: await toWirePosition(state, filePath, line, character)
2439
+ }, filePath);
2440
+ if (!result)
2441
+ return [];
2442
+ return Array.isArray(result) ? result : [result];
2443
+ },
2444
+ async prepareCallHierarchy(filePath, line, character) {
2445
+ const result = await navRequest(state, "textDocument/prepareCallHierarchy", {
2446
+ textDocument: { uri: pathToFileURL(filePath).href },
2447
+ position: await toWirePosition(state, filePath, line, character)
2448
+ }, filePath);
2449
+ if (!result)
2450
+ return [];
2451
+ return Array.isArray(result) ? result : [result];
2452
+ },
2453
+ async incomingCalls(item) {
2454
+ const result = await navRequest(state, "callHierarchy/incomingCalls", { item });
2455
+ return result ?? [];
2456
+ },
2457
+ async outgoingCalls(item) {
2458
+ const result = await navRequest(state, "callHierarchy/outgoingCalls", { item });
2459
+ return result ?? [];
2460
+ },
2461
+ async shutdown(options) {
2462
+ return clientShutdown(state, options);
2463
+ }
2464
+ };
2465
+ }
2466
+ async function safeSendNotification(connection, method, params) {
2467
+ try {
2468
+ await connection.sendNotification(method, params);
2469
+ return true;
2470
+ } catch (err) {
2471
+ if (isStreamError(err)) {
2472
+ return false;
2473
+ }
2474
+ throw err;
2475
+ }
2476
+ }
2477
+ const activeRequestsByConnection = new WeakMap;
2478
+ async function safeSendRequest(connection, method, params, signal, settlement) {
2479
+ if (signal?.aborted)
2480
+ return;
2481
+ let tokenSource;
2482
+ let onAbort;
2483
+ if (signal) {
2484
+ tokenSource = new CancellationTokenSource;
2485
+ onAbort = () => tokenSource?.cancel();
2486
+ signal.addEventListener("abort", onAbort, { once: true });
2487
+ }
2488
+ const send = () => tokenSource ? connection.sendRequest(method, params, tokenSource.token) : connection.sendRequest(method, params);
2489
+ activeRequestsByConnection.set(connection, (activeRequestsByConnection.get(connection) ?? 0) + 1);
2490
+ try {
2491
+ const MAX_ATTEMPTS = 2;
2492
+ for (let attempt = 1;; attempt++) {
2493
+ try {
2494
+ return await send();
2495
+ } catch (err) {
2496
+ if (isCancellationError(err)) {
2497
+ if (settlement)
2498
+ settlement.cancelled = true;
2499
+ return;
2500
+ }
2501
+ if (isStreamError(err)) {
2502
+ return;
2503
+ }
2504
+ if (isContentModifiedError(err)) {
2505
+ if (attempt < MAX_ATTEMPTS && !signal?.aborted)
2506
+ continue;
2507
+ return;
2508
+ }
2509
+ throw err;
2510
+ }
2511
+ }
2512
+ } finally {
2513
+ const remaining = (activeRequestsByConnection.get(connection) ?? 1) - 1;
2514
+ if (remaining > 0)
2515
+ activeRequestsByConnection.set(connection, remaining);
2516
+ else
2517
+ activeRequestsByConnection.delete(connection);
2518
+ if (signal && onAbort)
2519
+ signal.removeEventListener("abort", onAbort);
2520
+ tokenSource?.dispose();
2521
+ }
2522
+ }
2523
+ function isCancellationError(err) {
2524
+ const code = err?.code;
2525
+ return code === -32800 || code === -32802;
2526
+ }
2527
+ function isContentModifiedError(err) {
2528
+ return err?.code === -32801;
2529
+ }
2530
+ function isStreamError(err) {
2531
+ if (!(err instanceof Error))
2532
+ return false;
2533
+ const msg = err.message.toLowerCase();
2534
+ return msg.includes("stream") || msg.includes("destroyed") || msg.includes("closed") || msg.includes("disposed") || msg.includes("cancelled") || err.code === "ERR_STREAM_DESTROYED" || err.code === "ERR_STREAM_WRITE_AFTER_END" || err.code === "EPIPE";
2535
+ }
2536
+ function positiveIntFromEnv(name, fallback) {
2537
+ const raw = process.env[name];
2538
+ if (!raw)
2539
+ return fallback;
2540
+ const parsed = Number.parseInt(raw, 10);
2541
+ if (!Number.isFinite(parsed) || parsed <= 0)
2542
+ return fallback;
2543
+ return parsed;
2544
+ }
2545
+ function detectWorkspaceDiagnosticsSupport(initResult) {
2546
+ const capabilities = typeof initResult === "object" && initResult !== null ? initResult.capabilities : undefined;
2547
+ const diagnosticProvider = capabilities?.diagnosticProvider;
2548
+ if (!diagnosticProvider) {
2549
+ return {
2550
+ advertised: false,
2551
+ mode: "push-only",
2552
+ workspaceDiagnostics: false,
2553
+ diagnosticProviderKind: "none"
2554
+ };
2555
+ }
2556
+ if (typeof diagnosticProvider === "boolean") {
2557
+ return {
2558
+ advertised: diagnosticProvider,
2559
+ mode: diagnosticProvider ? "pull" : "push-only",
2560
+ workspaceDiagnostics: false,
2561
+ diagnosticProviderKind: "boolean"
2562
+ };
2563
+ }
2564
+ if (typeof diagnosticProvider === "object") {
2565
+ return {
2566
+ advertised: true,
2567
+ mode: "pull",
2568
+ workspaceDiagnostics: diagnosticProvider.workspaceDiagnostics === true,
2569
+ diagnosticProviderKind: "object"
2570
+ };
2571
+ }
2572
+ return {
2573
+ advertised: false,
2574
+ mode: "push-only",
2575
+ workspaceDiagnostics: false,
2576
+ diagnosticProviderKind: typeof diagnosticProvider
2577
+ };
2578
+ }
2579
+ function detectExecuteCommands(initResult) {
2580
+ const capabilities = typeof initResult === "object" && initResult !== null ? initResult.capabilities : undefined;
2581
+ const provider = capabilities?.executeCommandProvider;
2582
+ if (typeof provider !== "object" || provider === null)
2583
+ return [];
2584
+ const commands = provider.commands;
2585
+ if (!Array.isArray(commands))
2586
+ return [];
2587
+ return commands.filter((cmd) => typeof cmd === "string");
2588
+ }
2589
+ function detectOperationSupport(initResult) {
2590
+ const capabilities = typeof initResult === "object" && initResult !== null ? initResult.capabilities : undefined;
2591
+ const hasProvider = (key) => {
2592
+ const value = capabilities?.[key];
2593
+ if (value === undefined || value === null)
2594
+ return false;
2595
+ if (typeof value === "boolean")
2596
+ return value;
2597
+ return isCapabilityRecord(value);
2598
+ };
2599
+ const codeActionProvider = capabilities?.codeActionProvider;
2600
+ const workspace = capabilities?.workspace;
2601
+ const fileOperations = isCapabilityRecord(workspace) ? workspace.fileOperations : undefined;
2602
+ return {
2603
+ definition: hasProvider("definitionProvider"),
2604
+ typeDefinition: hasProvider("typeDefinitionProvider"),
2605
+ declaration: hasProvider("declarationProvider"),
2606
+ references: hasProvider("referencesProvider"),
2607
+ hover: hasProvider("hoverProvider"),
2608
+ signatureHelp: hasProvider("signatureHelpProvider"),
2609
+ documentSymbol: hasProvider("documentSymbolProvider"),
2610
+ workspaceSymbol: hasProvider("workspaceSymbolProvider"),
2611
+ codeAction: hasProvider("codeActionProvider"),
2612
+ codeActionResolve: isCapabilityRecord(codeActionProvider) && codeActionProvider.resolveProvider === true,
2613
+ rename: hasProvider("renameProvider"),
2614
+ willRenameFiles: isCapabilityRecord(fileOperations) && isFileOperationRegistrationOptions(fileOperations.willRename),
2615
+ didRenameFiles: isCapabilityRecord(fileOperations) && isFileOperationRegistrationOptions(fileOperations.didRename),
2616
+ implementation: hasProvider("implementationProvider"),
2617
+ callHierarchy: hasProvider("callHierarchyProvider")
2618
+ };
2619
+ }
2620
+ function isCapabilityRecord(value) {
2621
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2622
+ }
2623
+ function isFileOperationRegistrationOptions(value) {
2624
+ return parseFileOperationFilters(value) !== undefined;
2625
+ }
2626
+ function parseFileOperationFilters(value) {
2627
+ if (!isCapabilityRecord(value) || !Array.isArray(value.filters)) {
2628
+ return;
2629
+ }
2630
+ const filters = [];
2631
+ for (const entry of value.filters) {
2632
+ if (!isCapabilityRecord(entry))
2633
+ return;
2634
+ const pattern = entry.pattern;
2635
+ if (!isCapabilityRecord(pattern) || typeof pattern.glob !== "string" || pattern.glob.trim() === "") {
2636
+ return;
2637
+ }
2638
+ if (entry.scheme !== undefined && (typeof entry.scheme !== "string" || entry.scheme.trim() === "" || !/^[A-Za-z][A-Za-z0-9+.-]*$/.test(entry.scheme))) {
2639
+ return;
2640
+ }
2641
+ const matches = pattern.matches;
2642
+ if (matches !== undefined && matches !== "file" && matches !== "folder") {
2643
+ return;
2644
+ }
2645
+ if (pattern.options !== undefined && !isCapabilityRecord(pattern.options)) {
2646
+ return;
2647
+ }
2648
+ const options = isCapabilityRecord(pattern.options) ? pattern.options : undefined;
2649
+ if (options?.ignoreCase !== undefined && typeof options.ignoreCase !== "boolean") {
2650
+ return;
2651
+ }
2652
+ filters.push({
2653
+ scheme: entry.scheme?.toLowerCase(),
2654
+ glob: pattern.glob,
2655
+ matches: matches === "file" || matches === "folder" ? matches : undefined,
2656
+ ignoreCase: options?.ignoreCase === true
2657
+ });
2658
+ }
2659
+ return filters;
2660
+ }
2661
+ async function fileOperationFiltersMatch(filters, oldUri, newUri, oldFilePath, newFilePath) {
2662
+ if (!filters || filters.length === 0)
2663
+ return false;
2664
+ const candidates = [oldUri, newUri].flatMap(fileOperationUriCandidates);
2665
+ const entityKind = filters.some((filter) => filter.matches !== undefined) ? await probeRenameEntityKind(oldFilePath, newFilePath) : undefined;
2666
+ for (const filter of filters) {
2667
+ if (filter.scheme !== undefined && filter.scheme !== "file")
2668
+ continue;
2669
+ if (filter.matches !== undefined && filter.matches !== entityKind)
2670
+ continue;
2671
+ for (const candidate of candidates) {
2672
+ try {
2673
+ if (minimatch(candidate, filter.glob, {
2674
+ nocase: filter.ignoreCase,
2675
+ dot: true
2676
+ })) {
2677
+ return true;
2678
+ }
2679
+ } catch {}
2680
+ }
2681
+ }
2682
+ return false;
2683
+ }
2684
+ function fileOperationUriCandidates(uri) {
2685
+ let parsed;
2686
+ try {
2687
+ parsed = new URL(uri);
2688
+ } catch {
2689
+ return [];
2690
+ }
2691
+ if (parsed.protocol.toLowerCase() !== "file:")
2692
+ return [];
2693
+ let uriPath;
2694
+ try {
2695
+ uriPath = decodeURIComponent(parsed.pathname).replace(/\\/g, "/");
2696
+ } catch {
2697
+ return [];
2698
+ }
2699
+ return [uriPath];
2700
+ }
2701
+ async function probeRenameEntityKind(oldFilePath, newFilePath) {
2702
+ for (const filePath of [oldFilePath, newFilePath]) {
2703
+ try {
2704
+ const info = await lstat(filePath);
2705
+ return info.isDirectory() ? "folder" : "file";
2706
+ } catch {}
2707
+ }
2708
+ return;
2709
+ }