lazycodex-ai 5.0.0-beta.4 → 5.0.0-beta.40

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 (538) hide show
  1. package/README.ja.md +25 -21
  2. package/README.ko.md +25 -21
  3. package/README.md +38 -23
  4. package/README.ru.md +24 -20
  5. package/README.zh-cn.md +25 -21
  6. package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
  7. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  8. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  9. package/dist/cli/index.js +66932 -64746
  10. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  11. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  12. package/dist/cli/runtime-commands.d.ts +1 -1
  13. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  14. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  15. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  16. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  17. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  18. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  19. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  20. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  21. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  22. package/dist/cli-node/index.js +66795 -64586
  23. package/package.json +9 -9
  24. package/packages/git-bash-mcp/dist/cli.js +6 -1
  25. package/packages/lsp-daemon/dist/cli.js +793 -323
  26. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  27. package/packages/lsp-daemon/dist/client.js +753 -280
  28. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  29. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  30. package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
  31. package/packages/lsp-daemon/dist/index.js +757 -289
  32. package/packages/lsp-daemon/dist/proxy.js +3 -0
  33. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  34. package/packages/lsp-daemon/package.json +1 -1
  35. package/packages/lsp-tools-mcp/dist/cli.js +712 -244
  36. package/packages/lsp-tools-mcp/dist/lsp/manager.js +248 -119
  37. package/packages/lsp-tools-mcp/dist/mcp.js +714 -246
  38. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  39. package/packages/lsp-tools-mcp/dist/tools.js +718 -254
  40. package/packages/lsp-tools-mcp/package.json +1 -1
  41. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -6
  42. package/packages/omo-codex/plugin/.mcp.json +0 -6
  43. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  44. package/packages/omo-codex/plugin/README.md +2 -2
  45. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +45 -49
  46. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  47. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  48. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  49. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  50. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  51. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  52. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  53. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  54. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  55. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  56. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  57. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  58. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  59. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  60. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  61. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  62. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
  63. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
  64. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  65. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  66. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
  67. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
  68. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +1 -1
  69. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  70. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  71. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  72. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +741 -294
  73. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  74. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  75. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  76. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  77. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  78. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  79. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  80. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  81. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  82. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  83. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  84. package/packages/omo-codex/plugin/components/rules/dist/cli.js +60 -45
  85. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  86. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  87. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  88. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  89. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +9 -5
  90. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  91. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  92. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  93. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  94. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  95. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  96. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  97. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  98. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  99. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  100. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  101. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  102. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  103. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
  104. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  105. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  106. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  107. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  108. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +5 -6
  109. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  110. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  111. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  112. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  113. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  114. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  115. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +4 -10
  116. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  117. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  118. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2463 -437
  119. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2467 -441
  120. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  121. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  122. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  123. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  124. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  125. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  126. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -4
  127. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  128. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +489 -4
  129. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  130. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -6
  131. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
  132. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -7
  133. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  134. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  135. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  136. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
  137. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
  138. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  139. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  140. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
  141. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
  142. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  143. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +2 -2
  144. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  145. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +5 -5
  146. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  147. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +6 -6
  148. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
  149. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
  150. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  151. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  152. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  153. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
  154. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  155. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  156. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  157. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
  158. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
  159. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +19 -0
  160. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  161. package/packages/omo-codex/plugin/components/ulw-loop/README.md +12 -1
  162. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  163. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +15 -3
  164. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +12 -0
  165. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +45 -0
  166. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +9 -0
  167. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +15 -0
  168. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +15 -1
  169. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +8 -0
  170. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +120 -0
  171. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +40 -39
  172. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +7 -2
  173. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  174. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +12 -1
  175. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +2 -0
  176. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +958 -342
  177. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  178. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +27 -6
  179. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +13 -0
  180. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +15 -1
  181. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
  182. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
  183. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +17 -2
  184. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +13 -0
  185. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +19 -0
  186. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +7 -0
  187. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +9 -0
  188. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +12 -0
  189. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +104 -0
  190. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  191. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +65 -9
  192. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  193. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  194. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +69 -111
  195. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +4 -2
  196. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +185 -14
  197. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +6 -0
  198. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +33 -0
  199. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
  200. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +18 -0
  201. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +65 -0
  202. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  203. package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
  204. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
  205. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  206. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +22 -1
  207. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +81 -0
  208. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +7 -0
  209. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +31 -1
  210. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +134 -0
  211. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +38 -71
  212. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +7 -2
  213. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +14 -1
  214. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +2 -0
  215. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +3 -5
  216. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +34 -5
  217. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +26 -1
  218. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  219. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
  220. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
  221. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +18 -3
  222. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +27 -0
  223. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +11 -0
  224. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +123 -0
  225. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +68 -15
  226. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  227. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +82 -131
  228. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +4 -2
  229. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +187 -12
  230. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
  231. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
  232. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +95 -0
  233. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  234. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +133 -1
  235. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +137 -0
  236. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
  237. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +26 -2
  238. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +183 -0
  239. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +37 -2
  240. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  241. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  242. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
  243. package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +105 -0
  244. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  245. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  246. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  247. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  248. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  249. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +46 -2
  250. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
  251. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  252. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +48 -3
  253. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +318 -1
  254. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  255. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  256. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  257. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +13 -8
  258. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  259. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  260. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  261. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  262. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  263. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  264. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  265. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  266. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  267. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  268. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  269. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  270. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  271. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  272. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  273. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  274. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  275. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +17 -0
  276. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  277. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  278. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  279. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  280. package/packages/omo-codex/plugin/model-catalog.json +3 -3
  281. package/packages/omo-codex/plugin/package-lock.json +676 -524
  282. package/packages/omo-codex/plugin/package.json +2 -3
  283. package/packages/omo-codex/plugin/scripts/AGENTS.md +39 -0
  284. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -2
  285. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  286. package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
  287. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  288. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
  289. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +36 -13
  290. package/packages/omo-codex/plugin/shared/package.json +3 -4
  291. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  292. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  293. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  294. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  295. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  296. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
  297. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  298. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
  299. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  300. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  301. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  302. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  303. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  304. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  305. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  306. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  307. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  308. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -0
  309. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  310. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  311. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  312. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  313. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  314. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  315. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  316. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  317. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  318. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  319. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  320. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +11 -7
  321. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  322. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  323. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  324. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  325. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  326. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  327. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  328. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  329. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  330. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +13 -13
  331. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
  332. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +4 -4
  333. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  334. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
  335. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  336. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  337. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  338. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  339. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +15 -3
  340. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +19 -26
  341. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  342. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -2
  343. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  344. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +22 -1
  345. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -7
  346. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  347. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  348. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  349. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -2
  350. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  351. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -2
  352. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  353. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  354. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +9 -48
  355. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -3
  356. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  357. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
  358. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  359. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  360. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  361. package/packages/omo-codex/plugin/test/auto-update.test.mjs +2 -27
  362. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  363. package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
  364. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  365. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -51
  366. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  367. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -5
  368. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  369. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  370. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
  371. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  372. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
  373. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +23 -13
  374. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +14 -119
  375. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  376. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  377. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  378. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  379. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  380. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -5
  381. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  382. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2817 -913
  383. package/packages/{omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md → prompts-core/prompts/ultrawork/codex.md} +15 -10
  384. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  385. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  386. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
  387. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  388. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
  389. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  390. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  391. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  392. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  393. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  394. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  395. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  396. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  397. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  398. package/packages/shared-skills/skills/debugging/SKILL.md +2 -0
  399. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  400. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  401. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  402. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  403. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  404. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  405. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  406. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  407. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  408. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  409. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  410. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  411. package/packages/shared-skills/skills/frontend/SKILL.md +11 -7
  412. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  413. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  414. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  415. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  416. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  417. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  418. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  419. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  420. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  421. package/packages/shared-skills/skills/init-deep/SKILL.md +13 -13
  422. package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
  423. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  424. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
  425. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  426. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  427. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  428. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  429. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +17 -16
  430. package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -7
  431. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  432. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  433. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  434. package/packages/shared-skills/skills/ulw-research/SKILL.md +4 -2
  435. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  436. package/packages/shared-skills/skills/visual-qa/SKILL.md +3 -2
  437. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  438. package/script/qa/xterm-live-terminal.mjs +18 -2
  439. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  440. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  441. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  442. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  443. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  444. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  445. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  446. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  447. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12136
  448. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9734
  449. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  450. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  451. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  452. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  453. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  454. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  455. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  456. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -309
  457. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -80
  458. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  459. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  460. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  461. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  462. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  463. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -21
  464. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  465. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  466. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  467. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  468. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  469. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  470. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  471. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  472. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  473. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  474. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  475. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  476. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  477. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  478. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  479. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  480. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  481. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  482. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  483. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  484. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  485. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  486. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  487. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  488. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  489. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  490. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  491. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  492. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  493. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  494. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  495. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  496. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  497. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  498. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  499. package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +0 -21
  500. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  501. package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -471
  502. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  503. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  504. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  505. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  506. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  507. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  508. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  509. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  510. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  511. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  512. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  513. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  514. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  515. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  516. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  517. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
  518. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  519. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  520. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  521. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  522. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  523. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  524. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  525. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  526. /package/packages/omo-codex/plugin/components/{codegraph → ulw-execute-continuation}/LICENSE +0 -0
  527. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  528. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
  529. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  530. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  531. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  532. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  533. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  534. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  535. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  536. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  537. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  538. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -8,11 +8,13 @@ import { argv, execPath as execPath2, stderr } from "node:process";
8
8
  import { stdin as processStdin } from "node:process";
9
9
 
10
10
  // src/codex-hook.ts
11
- import { readFileSync as readFileSync9, realpathSync as realpathSync6 } from "node:fs";
11
+ import { readFileSync as readFileSync10, realpathSync as realpathSync8 } from "node:fs";
12
12
  import { homedir as homedir3 } from "node:os";
13
- import { join as join11, resolve as resolve11 } from "node:path";
13
+ import { join as join12, resolve as resolve12 } from "node:path";
14
14
 
15
15
  // ../../../../lsp-daemon/dist/client.js
16
+ import { statSync as statSync5 } from "node:fs";
17
+ import { isAbsolute as isAbsolute6 } from "node:path";
16
18
  import { connect } from "node:net";
17
19
  import { AsyncLocalStorage } from "node:async_hooks";
18
20
  import { existsSync, realpathSync, statSync } from "node:fs";
@@ -42,8 +44,8 @@ import * as path from "node:path";
42
44
  import { fileURLToPath } from "node:url";
43
45
  import { statSync as statSync2 } from "node:fs";
44
46
  import { isAbsolute as isAbsolute2 } from "node:path";
45
- import { existsSync as existsSync10, statSync as statSync4 } from "node:fs";
46
- import { dirname as dirname8, join as join4, resolve as resolve7 } from "node:path";
47
+ import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync4 } from "node:fs";
48
+ import { basename as basename3, dirname as dirname10, join as join5, resolve as resolve8 } from "node:path";
47
49
  import { basename as basename2, extname } from "node:path";
48
50
  import { resolve as resolve6 } from "node:path";
49
51
  import { pathToFileURL as pathToFileURL3 } from "node:url";
@@ -62,32 +64,32 @@ import { createHash as createHash2 } from "node:crypto";
62
64
  import { dirname as dirname5, relative as relative4, resolve as resolve4 } from "node:path";
63
65
  import { existsSync as existsSync6, lstatSync as lstatSync4, readdirSync as readdirSync2 } from "node:fs";
64
66
  import { dirname as dirname6, resolve as resolve5 } from "node:path";
65
- import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
66
- import { dirname as dirname7 } from "node:path";
67
- import { existsSync as existsSync8, readFileSync as readFileSync5 } from "node:fs";
68
- import { existsSync as existsSync9 } from "node:fs";
69
- import { delimiter as delimiter3, join as join3 } from "node:path";
70
- import { existsSync as existsSync11, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
71
- import { join as join5, resolve as resolve8 } from "node:path";
67
+ import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
68
+ import { dirname as dirname7, join as join3 } from "node:path";
69
+ import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
70
+ import { dirname as dirname8 } from "node:path";
71
+ import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
72
+ import { existsSync as existsSync10 } from "node:fs";
73
+ import { delimiter as delimiter3, dirname as dirname9, isAbsolute as isAbsolute5, join as join4, resolve as resolve7 } from "node:path";
74
+ import { existsSync as existsSync12, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
75
+ import { join as join6, resolve as resolve9 } from "node:path";
72
76
  import { fileURLToPath as fileURLToPath3 } from "node:url";
73
77
  import { lstatSync as lstatSync6, readdirSync as readdirSync4 } from "node:fs";
74
- import { join as join6 } from "node:path";
75
- import { statSync as statSync5 } from "node:fs";
76
- import { isAbsolute as isAbsolute5 } from "node:path";
78
+ import { join as join7 } from "node:path";
79
+ import { readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
77
80
 
78
81
  class LspRequestContextParseError extends Error {
79
- code;
80
- name = "LspRequestContextParseError";
81
82
  constructor(code, message) {
82
83
  super(message);
83
84
  this.code = code;
85
+ this.name = "LspRequestContextParseError";
84
86
  }
85
87
  }
86
88
 
87
89
  class LspRequestContextUnavailableError extends Error {
88
- name = "LspRequestContextUnavailableError";
89
90
  constructor() {
90
91
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
92
+ this.name = "LspRequestContextUnavailableError";
91
93
  }
92
94
  }
93
95
  var storage = new AsyncLocalStorage;
@@ -214,7 +216,6 @@ function isPlainRecord(value) {
214
216
  }
215
217
 
216
218
  class DaemonRequestError extends Error {
217
- requestWritten;
218
219
  constructor(message, requestWritten) {
219
220
  super(message);
220
221
  this.name = "DaemonRequestError";
@@ -237,7 +238,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
237
238
  }
238
239
 
239
240
  class DaemonRequestTimedOutError extends DaemonRequestError {
240
- timeoutMs;
241
241
  constructor(requestWritten, timeoutMs) {
242
242
  super("daemon request timed out", requestWritten);
243
243
  this.name = "DaemonRequestTimedOutError";
@@ -314,20 +314,18 @@ var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
314
314
  var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
315
315
 
316
316
  class InvalidRuntimeOverrideError extends Error {
317
- code = "invalid_runtime_override";
318
- reason;
319
317
  constructor(reason, message) {
320
318
  super(message);
319
+ this.code = "invalid_runtime_override";
321
320
  this.name = "InvalidRuntimeOverrideError";
322
321
  this.reason = reason;
323
322
  }
324
323
  }
325
324
 
326
325
  class InvalidDaemonVersionError extends Error {
327
- code = "invalid_daemon_version";
328
- version;
329
326
  constructor(version) {
330
327
  super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
328
+ this.code = "invalid_daemon_version";
331
329
  this.name = "InvalidDaemonVersionError";
332
330
  this.version = version;
333
331
  }
@@ -371,10 +369,9 @@ var requireFromHere = createRequire(import.meta.url);
371
369
  var MAX_SOCKET_PATH_LENGTH = 100;
372
370
 
373
371
  class InvalidDaemonDirectoryError extends Error {
374
- code = "invalid_daemon_directory";
375
- directory;
376
372
  constructor(directory) {
377
373
  super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
374
+ this.code = "invalid_daemon_directory";
378
375
  this.name = "InvalidDaemonDirectoryError";
379
376
  this.directory = directory;
380
377
  }
@@ -565,7 +562,8 @@ function spawnDaemonProcess(paths) {
565
562
  try {
566
563
  const child = spawn(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
567
564
  detached: true,
568
- stdio: ["ignore", logFd, logFd]
565
+ stdio: ["ignore", logFd, logFd],
566
+ windowsHide: true
569
567
  });
570
568
  child.once("spawn", () => closeSync2(logFd));
571
569
  child.once("error", (error) => {
@@ -686,22 +684,15 @@ function effectiveExtension(filePath) {
686
684
  }
687
685
 
688
686
  class LspConnectionClosedError extends Error {
689
- serverId;
690
- root;
691
- name = "LspConnectionClosedError";
692
687
  constructor(serverId, root, message) {
693
688
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
694
689
  this.serverId = serverId;
695
690
  this.root = root;
691
+ this.name = "LspConnectionClosedError";
696
692
  }
697
693
  }
698
694
 
699
695
  class LspProcessExitedError extends Error {
700
- serverId;
701
- root;
702
- exitCode;
703
- stderrTail;
704
- name = "LspProcessExitedError";
705
696
  constructor(serverId, root, exitCode, stderrTail) {
706
697
  const stderrSuffix = stderrTail ? `
707
698
  stderr tail: ${stderrTail}` : "";
@@ -710,46 +701,59 @@ stderr tail: ${stderrTail}` : "";
710
701
  this.root = root;
711
702
  this.exitCode = exitCode;
712
703
  this.stderrTail = stderrTail;
704
+ this.name = "LspProcessExitedError";
713
705
  }
714
706
  }
715
707
 
716
708
  class LspRequestTimeoutError extends Error {
717
- method;
718
- stderrTail;
719
- name = "LspRequestTimeoutError";
720
709
  constructor(method, stderrTail) {
721
710
  const stderrSuffix = stderrTail ? `
722
711
  recent stderr: ${stderrTail}` : "";
723
712
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
724
713
  this.method = method;
725
714
  this.stderrTail = stderrTail;
715
+ this.name = "LspRequestTimeoutError";
726
716
  }
727
717
  }
728
718
 
729
719
  class LspInvalidPathError extends Error {
730
- name = "LspInvalidPathError";
720
+ constructor() {
721
+ super(...arguments);
722
+ this.name = "LspInvalidPathError";
723
+ }
731
724
  }
732
725
 
733
726
  class LspServerLookupError extends Error {
734
- lookup;
735
- name = "LspServerLookupError";
736
727
  constructor(message, lookup) {
737
728
  super(message);
738
729
  this.lookup = lookup;
730
+ this.name = "LspServerLookupError";
739
731
  }
740
732
  }
741
733
 
742
734
  class LspServerInitializingError extends Error {
743
- originalError;
744
- name = "LspServerInitializingError";
745
735
  constructor(originalError) {
746
736
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
747
737
  this.originalError = originalError;
738
+ this.name = "LspServerInitializingError";
748
739
  }
749
740
  }
750
741
 
751
742
  class LspProcessSpawnError extends Error {
752
- name = "LspProcessSpawnError";
743
+ constructor() {
744
+ super(...arguments);
745
+ this.name = "LspProcessSpawnError";
746
+ }
747
+ }
748
+
749
+ class LspClientRespawnBudgetExceededError extends Error {
750
+ constructor(serverId, root, retryLimit) {
751
+ super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
752
+ this.serverId = serverId;
753
+ this.root = root;
754
+ this.retryLimit = retryLimit;
755
+ this.name = "LspClientRespawnBudgetExceededError";
756
+ }
753
757
  }
754
758
  function isLspDeadConnectionError(err) {
755
759
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -762,6 +766,11 @@ function reportBestEffortCleanupError(operation, error, logger = writeCleanupErr
762
766
  const message = error instanceof Error ? error.message : String(error);
763
767
  logger(`[lsp] ignored ${operation} failure during cleanup: ${message}`);
764
768
  }
769
+ var realTimerProvider = {
770
+ now: () => Date.now(),
771
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
772
+ clearTimeout: (handle) => clearTimeout(handle)
773
+ };
765
774
  var DEFAULT_MAX_REFERENCES = 200;
766
775
  var DEFAULT_MAX_SYMBOLS = 200;
767
776
  var DEFAULT_MAX_DIAGNOSTICS = 200;
@@ -769,9 +778,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
769
778
  var REQUEST_TIMEOUT_MS = 15000;
770
779
  var INIT_TIMEOUT_MS = 60000;
771
780
  var IDLE_TIMEOUT_MS = 5 * 60000;
781
+ var MAX_RESIDENT_CLIENTS = 6;
772
782
  var REAPER_INTERVAL_MS = 60000;
773
783
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
774
784
  var STOP_SIGKILL_GRACE_MS = 1000;
785
+ var CLIENT_RESPAWN_RETRY_LIMIT = 2;
786
+ var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
775
787
  var HEADER_SEPARATOR2 = `\r
776
788
  \r
777
789
  `;
@@ -781,20 +793,31 @@ var METHOD_NOT_FOUND = -32601;
781
793
  var INTERNAL_ERROR = -32603;
782
794
 
783
795
  class JsonRpcConnection {
784
- reader;
785
- writer;
786
- pendingRequests = new Map;
787
- notificationHandlers = new Map;
788
- requestHandlers = new Map;
789
- closeHandlers = [];
790
- errorHandlers = [];
791
- inputBuffer = Buffer.alloc(0);
792
- nextRequestId = 1;
793
- listening = false;
794
- disposed = false;
795
796
  constructor(reader, writer) {
796
797
  this.reader = reader;
797
798
  this.writer = writer;
799
+ this.pendingRequests = new Map;
800
+ this.notificationHandlers = new Map;
801
+ this.requestHandlers = new Map;
802
+ this.closeHandlers = [];
803
+ this.errorHandlers = [];
804
+ this.inputBuffer = Buffer.alloc(0);
805
+ this.nextRequestId = 1;
806
+ this.listening = false;
807
+ this.disposed = false;
808
+ this.handleData = (chunk) => {
809
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
810
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
811
+ this.drainInputBuffer();
812
+ };
813
+ this.handleClose = () => {
814
+ for (const handler of this.closeHandlers) {
815
+ handler();
816
+ }
817
+ };
818
+ this.handleStreamError = (error) => {
819
+ this.emitError(error);
820
+ };
798
821
  }
799
822
  listen() {
800
823
  if (this.listening)
@@ -915,19 +938,6 @@ class JsonRpcConnection {
915
938
  this.notificationHandlers.clear();
916
939
  this.requestHandlers.clear();
917
940
  }
918
- handleData = (chunk) => {
919
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
920
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
921
- this.drainInputBuffer();
922
- };
923
- handleClose = () => {
924
- for (const handler of this.closeHandlers) {
925
- handler();
926
- }
927
- };
928
- handleStreamError = (error) => {
929
- this.emitError(error);
930
- };
931
941
  drainInputBuffer() {
932
942
  while (true) {
933
943
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
@@ -1267,33 +1277,29 @@ function isPosition(value) {
1267
1277
  }
1268
1278
 
1269
1279
  class LspClientNotStartedError extends Error {
1270
- serverId;
1271
- root;
1272
- name = "LspClientNotStartedError";
1273
1280
  constructor(serverId, root) {
1274
1281
  super("LSP client not started");
1275
1282
  this.serverId = serverId;
1276
1283
  this.root = root;
1284
+ this.name = "LspClientNotStartedError";
1277
1285
  }
1278
1286
  }
1279
1287
 
1280
1288
  class LspClientTransport {
1281
- root;
1282
- server;
1283
- proc = null;
1284
- connection = null;
1285
- stderrBuffer = [];
1286
- processExited = false;
1287
- diagnosticsStore = new Map;
1288
- requestTimeoutMs;
1289
- initializeTimeoutMs;
1290
- workspaceApplyEditHandler = null;
1291
- diagnosticPullSupported = false;
1292
1289
  constructor(root, server2, timeouts = {}) {
1293
1290
  this.root = root;
1294
1291
  this.server = server2;
1292
+ this.proc = null;
1293
+ this.connection = null;
1294
+ this.stderrBuffer = [];
1295
+ this.processExited = false;
1296
+ this.diagnosticsStore = new Map;
1297
+ this.workspaceApplyEditHandler = null;
1298
+ this.diagnosticPullSupported = false;
1299
+ this.documentFormattingSupported = false;
1295
1300
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
1296
1301
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
1302
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
1297
1303
  }
1298
1304
  pid() {
1299
1305
  return this.proc?.pid;
@@ -1313,6 +1319,12 @@ class LspClientTransport {
1313
1319
  isDiagnosticPullSupported() {
1314
1320
  return this.diagnosticPullSupported;
1315
1321
  }
1322
+ setDocumentFormattingSupported(supported) {
1323
+ this.documentFormattingSupported = supported;
1324
+ }
1325
+ isDocumentFormattingSupported() {
1326
+ return this.documentFormattingSupported;
1327
+ }
1316
1328
  handlePublishDiagnostics(params) {
1317
1329
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
1318
1330
  }
@@ -1388,7 +1400,7 @@ class LspClientTransport {
1388
1400
  const options = args[1];
1389
1401
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
1390
1402
  const timeoutController = new AbortController;
1391
- const timeoutHandle = setTimeout(() => {
1403
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
1392
1404
  const stderrTail = this.stderrBuffer.slice(-5).join(`
1393
1405
  `);
1394
1406
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -1407,7 +1419,7 @@ class LspClientTransport {
1407
1419
  }
1408
1420
  throw error;
1409
1421
  } finally {
1410
- clearTimeout(timeoutHandle);
1422
+ this.timerProvider.clearTimeout(timeoutHandle);
1411
1423
  combinedSignal.dispose();
1412
1424
  }
1413
1425
  }
@@ -1524,6 +1536,14 @@ function supportsDiagnosticPull(capabilities) {
1524
1536
  return false;
1525
1537
  return Object.hasOwn(capabilities, "diagnosticProvider");
1526
1538
  }
1539
+ function supportsDocumentFormatting(capabilities) {
1540
+ if (capabilities === undefined)
1541
+ return false;
1542
+ const provider = capabilities.documentFormattingProvider;
1543
+ if (provider === undefined || provider === null || provider === false)
1544
+ return false;
1545
+ return provider === true || typeof provider === "object";
1546
+ }
1527
1547
 
1528
1548
  class LspClientConnection extends LspClientTransport {
1529
1549
  async initialize() {
@@ -1540,6 +1560,7 @@ class LspClientConnection extends LspClientTransport {
1540
1560
  references: {},
1541
1561
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
1542
1562
  publishDiagnostics: {},
1563
+ formatting: { dynamicRegistration: false },
1543
1564
  rename: {
1544
1565
  prepareSupport: true,
1545
1566
  prepareSupportDefaultBehavior: 1
@@ -1581,6 +1602,7 @@ class LspClientConnection extends LspClientTransport {
1581
1602
  initializationOptions: this.server.initialization
1582
1603
  }, { timeoutMs: this.initializeTimeoutMs });
1583
1604
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
1605
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
1584
1606
  await this.sendNotification("initialized", {});
1585
1607
  await this.sendNotification("workspace/didChangeConfiguration", {
1586
1608
  settings: { json: { validate: { enable: true } } }
@@ -1767,6 +1789,17 @@ function canonicalPath(filePath) {
1767
1789
  return absolute;
1768
1790
  }
1769
1791
  }
1792
+ function normalizeDocumentUri(uri) {
1793
+ let decoded = uri;
1794
+ try {
1795
+ decoded = decodeURIComponent(uri);
1796
+ } catch {
1797
+ decoded = uri;
1798
+ }
1799
+ if (process.platform !== "win32")
1800
+ return decoded;
1801
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1802
+ }
1770
1803
  function isSameOrDescendant(candidate, parent) {
1771
1804
  const suffix = relative2(parent, candidate);
1772
1805
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1777,17 +1810,18 @@ function movedPath(candidate, oldPath, newPath) {
1777
1810
  }
1778
1811
 
1779
1812
  class WorkspaceDocumentState {
1780
- sendNotification;
1781
- clearDiagnostics;
1782
- openDocuments = new Map;
1783
- openByUri = new Map;
1784
- openPromises = new Map;
1785
- now;
1786
- versionlessPublishQuiescenceMs;
1787
1813
  constructor(sendNotification, clearDiagnostics, options = {}) {
1788
1814
  this.sendNotification = sendNotification;
1789
1815
  this.clearDiagnostics = clearDiagnostics;
1790
- this.now = options.now ?? (() => Date.now());
1816
+ this.openDocuments = new Map;
1817
+ this.openByUri = new Map;
1818
+ this.openPromises = new Map;
1819
+ this.timerProvider = options.timerProvider ?? {
1820
+ now: options.now ?? (() => Date.now()),
1821
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1822
+ clearTimeout: (handle) => clearTimeout(handle)
1823
+ };
1824
+ this.now = () => this.timerProvider.now();
1791
1825
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1792
1826
  }
1793
1827
  async openFile(filePath) {
@@ -1809,7 +1843,7 @@ class WorkspaceDocumentState {
1809
1843
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1810
1844
  }
1811
1845
  getStoredDiagnostics(uri) {
1812
- const state = this.openByUri.get(uri);
1846
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1813
1847
  if (!state)
1814
1848
  return [];
1815
1849
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1831,13 +1865,13 @@ class WorkspaceDocumentState {
1831
1865
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1832
1866
  }
1833
1867
  getPullCache(snapshot) {
1834
- const state = this.openByUri.get(snapshot.uri);
1868
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1835
1869
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1836
1870
  return null;
1837
1871
  return state.pullCache;
1838
1872
  }
1839
1873
  recordPullDiagnostics(snapshot, report) {
1840
- const state = this.openByUri.get(snapshot.uri);
1874
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1841
1875
  if (!state)
1842
1876
  return;
1843
1877
  state.pullCache = {
@@ -1847,7 +1881,7 @@ class WorkspaceDocumentState {
1847
1881
  };
1848
1882
  }
1849
1883
  recordPublishedDiagnostics(params) {
1850
- const state = this.openByUri.get(params.uri);
1884
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1851
1885
  if (!state)
1852
1886
  return;
1853
1887
  state.publishGeneration += 1;
@@ -1861,7 +1895,7 @@ class WorkspaceDocumentState {
1861
1895
  this.notifyWaiters(state);
1862
1896
  }
1863
1897
  resolvePushDiagnostics(snapshot) {
1864
- const state = this.openByUri.get(snapshot.uri);
1898
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1865
1899
  if (!state?.lastPublish)
1866
1900
  return { status: "missing" };
1867
1901
  const publish = state.lastPublish;
@@ -1875,7 +1909,7 @@ class WorkspaceDocumentState {
1875
1909
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1876
1910
  }
1877
1911
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1878
- const state = this.openByUri.get(snapshot.uri);
1912
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1879
1913
  if (!state || timeoutMs <= 0)
1880
1914
  return Promise.resolve();
1881
1915
  return new Promise((resolveActivity) => {
@@ -1884,11 +1918,11 @@ class WorkspaceDocumentState {
1884
1918
  if (settled)
1885
1919
  return;
1886
1920
  settled = true;
1887
- clearTimeout(timer);
1921
+ this.timerProvider.clearTimeout(timer);
1888
1922
  state.waiters.delete(finish);
1889
1923
  resolveActivity();
1890
1924
  };
1891
- const timer = setTimeout(finish, timeoutMs);
1925
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1892
1926
  if (typeof timer.unref === "function")
1893
1927
  timer.unref();
1894
1928
  state.waiters.add(finish);
@@ -1996,7 +2030,7 @@ class WorkspaceDocumentState {
1996
2030
  waiters: new Set
1997
2031
  };
1998
2032
  this.openDocuments.set(path2, state);
1999
- this.openByUri.set(state.uri, state);
2033
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
2000
2034
  this.notifyWaiters(state);
2001
2035
  await this.sendNotification("textDocument/didOpen", {
2002
2036
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -2021,7 +2055,7 @@ class WorkspaceDocumentState {
2021
2055
  }
2022
2056
  async closeDocument(state) {
2023
2057
  this.openDocuments.delete(state.path);
2024
- this.openByUri.delete(state.uri);
2058
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
2025
2059
  this.clearDiagnostics(state.uri);
2026
2060
  this.notifyWaiters(state);
2027
2061
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -2040,13 +2074,11 @@ function workspaceApplyEditConcurrentFailureReason(phase) {
2040
2074
  }
2041
2075
 
2042
2076
  class WorkspaceEditPathError extends Error {
2043
- path;
2044
- detail;
2045
- name = "WorkspaceEditPathError";
2046
2077
  constructor(path2, detail) {
2047
2078
  super(`${detail}: ${path2}`);
2048
2079
  this.path = path2;
2049
2080
  this.detail = detail;
2081
+ this.name = "WorkspaceEditPathError";
2050
2082
  }
2051
2083
  }
2052
2084
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -2332,13 +2364,11 @@ function canonicalFingerprint(operations) {
2332
2364
  }
2333
2365
 
2334
2366
  class WorkspaceEditValidationError extends Error {
2335
- changeIndex;
2336
- detail;
2337
- name = "WorkspaceEditValidationError";
2338
2367
  constructor(changeIndex, detail) {
2339
2368
  super(`change ${changeIndex}: ${detail}`);
2340
2369
  this.changeIndex = changeIndex;
2341
2370
  this.detail = detail;
2371
+ this.name = "WorkspaceEditValidationError";
2342
2372
  }
2343
2373
  }
2344
2374
  function isRecord3(value) {
@@ -2820,10 +2850,9 @@ function simulateDelete(operation, virtual) {
2820
2850
  }
2821
2851
 
2822
2852
  class WorkspaceSnapshotBuilder {
2823
- workspaceRoot;
2824
- snapshots = new Map;
2825
2853
  constructor(workspaceRoot) {
2826
2854
  this.workspaceRoot = workspaceRoot;
2855
+ this.snapshots = new Map;
2827
2856
  }
2828
2857
  build(operations) {
2829
2858
  this.add(this.workspaceRoot, false);
@@ -2866,8 +2895,10 @@ function snapshotOperations(operations, workspaceRoot) {
2866
2895
  }
2867
2896
 
2868
2897
  class PlanPathIndex {
2869
- firstChangeByPath = new Map;
2870
- reportedPathByCanonical = new Map;
2898
+ constructor() {
2899
+ this.firstChangeByPath = new Map;
2900
+ this.reportedPathByCanonical = new Map;
2901
+ }
2871
2902
  build(operations) {
2872
2903
  for (const operation of operations) {
2873
2904
  switch (operation.kind) {
@@ -2954,14 +2985,11 @@ function isRecord4(value) {
2954
2985
  }
2955
2986
 
2956
2987
  class WorkspaceMutationController {
2957
- workspaceRoot;
2958
- documents;
2959
- activeLease = null;
2960
- nextLeaseId = 1;
2961
- io;
2962
2988
  constructor(workspaceRoot, documents) {
2963
2989
  this.workspaceRoot = workspaceRoot;
2964
2990
  this.documents = documents;
2991
+ this.activeLease = null;
2992
+ this.nextLeaseId = 1;
2965
2993
  }
2966
2994
  setIo(io) {
2967
2995
  this.io = io;
@@ -3072,14 +3100,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
3072
3100
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
3073
3101
 
3074
3102
  class LspClient extends LspClientConnection {
3075
- diagnosticPullErrors = [];
3076
- documents;
3077
- workspaceMutations;
3078
- diagnosticsFreshnessTimeoutMs;
3079
3103
  constructor(root, server2, options = {}) {
3080
3104
  super(root, server2, options);
3105
+ this.diagnosticPullErrors = [];
3081
3106
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
3082
3107
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
3108
+ timerProvider: this.timerProvider,
3083
3109
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
3084
3110
  });
3085
3111
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -3132,6 +3158,18 @@ class LspClient extends LspClientConnection {
3132
3158
  textDocument: { uri: pathToFileURL3(absPath).href }
3133
3159
  }, options);
3134
3160
  }
3161
+ async formatDocument(filePath, options, signal) {
3162
+ if (!this.isDocumentFormattingSupported())
3163
+ return null;
3164
+ const absPath = this.resolveWorkspacePath(filePath);
3165
+ await this.openFile(absPath);
3166
+ const requestOptions = signal === undefined ? {} : { signal };
3167
+ const edits = await this.sendRequest("textDocument/formatting", {
3168
+ textDocument: { uri: pathToFileURL3(absPath).href },
3169
+ options
3170
+ }, requestOptions);
3171
+ return edits ?? [];
3172
+ }
3135
3173
  async workspaceSymbols(query, signal) {
3136
3174
  const options = signal === undefined ? {} : { signal };
3137
3175
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -3171,7 +3209,7 @@ class LspClient extends LspClientConnection {
3171
3209
  const absPath = this.resolveWorkspacePath(filePath);
3172
3210
  const uri = pathToFileURL3(absPath).href;
3173
3211
  await this.openFile(absPath);
3174
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
3212
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
3175
3213
  for (;; ) {
3176
3214
  signal?.throwIfAborted();
3177
3215
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -3184,7 +3222,7 @@ class LspClient extends LspClientConnection {
3184
3222
  if (!pushFallbackOnly) {
3185
3223
  const cached = this.documents.getPullCache(snapshot);
3186
3224
  try {
3187
- const remainingMs2 = deadlineAt - Date.now();
3225
+ const remainingMs2 = deadlineAt - this.timerProvider.now();
3188
3226
  if (remainingMs2 <= 0)
3189
3227
  return this.freshnessTimeout(absPath);
3190
3228
  const result = await this.sendRequest("textDocument/diagnostic", {
@@ -3219,7 +3257,7 @@ class LspClient extends LspClientConnection {
3219
3257
  }
3220
3258
  if (!pushFallbackOnly)
3221
3259
  continue;
3222
- const remainingMs = deadlineAt - Date.now();
3260
+ const remainingMs = deadlineAt - this.timerProvider.now();
3223
3261
  if (remainingMs <= 0) {
3224
3262
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
3225
3263
  const cached = this.documents.getPullCache(snapshot);
@@ -3373,18 +3411,16 @@ function awaitWithSignal2(promise, signal) {
3373
3411
  }
3374
3412
 
3375
3413
  class LspManager {
3376
- clients = new Map;
3377
- reaperHandle = null;
3378
- signalDisposer = null;
3379
- disposed = false;
3380
- idleTimeoutMs;
3381
- initTimeoutMs;
3382
- reaperIntervalMs;
3383
- clientFactory;
3384
- now;
3385
3414
  constructor(options = {}) {
3415
+ this.clients = new Map;
3416
+ this.pendingStops = new Map;
3417
+ this.respawnBudgets = new Map;
3418
+ this.reaperHandle = null;
3419
+ this.signalDisposer = null;
3420
+ this.disposed = false;
3386
3421
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
3387
3422
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
3423
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
3388
3424
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
3389
3425
  this.clientFactory = options.clientFactory ?? ((root, server2) => new LspClient(root, server2));
3390
3426
  this.now = options.now ?? (() => Date.now());
@@ -3404,24 +3440,79 @@ class LspManager {
3404
3440
  getKey(root, serverId) {
3405
3441
  return `${root}::${serverId}`;
3406
3442
  }
3443
+ tombstoneStop(key, client) {
3444
+ const stop = stopClientBestEffort(client);
3445
+ this.pendingStops.set(key, stop);
3446
+ stop.finally(() => {
3447
+ if (this.pendingStops.get(key) === stop) {
3448
+ this.pendingStops.delete(key);
3449
+ }
3450
+ });
3451
+ return stop;
3452
+ }
3453
+ recordDeadGeneration(key) {
3454
+ let budget = this.respawnBudgets.get(key);
3455
+ if (budget === undefined) {
3456
+ budget = { deadGenerations: 0, exhaustedAt: null };
3457
+ this.respawnBudgets.set(key, budget);
3458
+ }
3459
+ budget.deadGenerations += 1;
3460
+ }
3461
+ markHealthyGeneration(key) {
3462
+ this.respawnBudgets.delete(key);
3463
+ }
3464
+ ensureRespawnAllowed(key, root, serverId) {
3465
+ const budget = this.respawnBudgets.get(key);
3466
+ if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
3467
+ return;
3468
+ if (budget.exhaustedAt === null) {
3469
+ budget.exhaustedAt = this.now();
3470
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3471
+ }
3472
+ if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
3473
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3474
+ }
3475
+ budget.deadGenerations = 0;
3476
+ budget.exhaustedAt = null;
3477
+ }
3407
3478
  reapStale() {
3408
3479
  const t = this.now();
3409
3480
  for (const [key, managed] of this.clients) {
3410
3481
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3411
- stopClientBestEffort(managed.client);
3412
3482
  this.clients.delete(key);
3483
+ this.tombstoneStop(key, managed.client);
3413
3484
  continue;
3414
3485
  }
3415
3486
  if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
3416
- stopClientBestEffort(managed.client);
3417
3487
  this.clients.delete(key);
3488
+ this.tombstoneStop(key, managed.client);
3489
+ }
3490
+ }
3491
+ }
3492
+ evictForAdmission() {
3493
+ while (this.clients.size >= this.maxResidentClients) {
3494
+ const victim = this.leastRecentlyUsedIdleClient();
3495
+ if (!victim)
3496
+ return;
3497
+ this.clients.delete(victim.key);
3498
+ this.tombstoneStop(victim.key, victim.managed.client);
3499
+ }
3500
+ }
3501
+ leastRecentlyUsedIdleClient() {
3502
+ let candidate = null;
3503
+ for (const [key, managed] of this.clients) {
3504
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
3505
+ continue;
3506
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
3507
+ candidate = { key, managed };
3418
3508
  }
3419
3509
  }
3510
+ return candidate;
3420
3511
  }
3421
3512
  async tryDeleteIfOrphaned(key, managed) {
3422
3513
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
3423
3514
  this.clients.delete(key);
3424
- await stopClientBestEffort(managed.client);
3515
+ await this.tombstoneStop(key, managed.client);
3425
3516
  }
3426
3517
  }
3427
3518
  async getClient(root, server2, signal) {
@@ -3430,12 +3521,22 @@ class LspManager {
3430
3521
  }
3431
3522
  signal?.throwIfAborted();
3432
3523
  const key = this.getKey(root, server2.id);
3524
+ for (;; ) {
3525
+ const pendingStop = this.pendingStops.get(key);
3526
+ if (pendingStop === undefined)
3527
+ break;
3528
+ await awaitWithSignal2(pendingStop, signal);
3529
+ signal?.throwIfAborted();
3530
+ }
3531
+ if (this.disposed) {
3532
+ throw new Error("LspManager has been disposed");
3533
+ }
3433
3534
  let managed = this.clients.get(key);
3434
3535
  if (managed) {
3435
3536
  const t = this.now();
3436
3537
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3437
- await stopClientBestEffort(managed.client);
3438
3538
  this.clients.delete(key);
3539
+ await this.tombstoneStop(key, managed.client);
3439
3540
  managed = undefined;
3440
3541
  }
3441
3542
  }
@@ -3456,14 +3557,20 @@ class LspManager {
3456
3557
  signal.throwIfAborted();
3457
3558
  }
3458
3559
  if (!managed.client.isAlive()) {
3459
- await stopClientBestEffort(managed.client);
3460
- this.clients.delete(key);
3560
+ this.recordDeadGeneration(key);
3561
+ if (this.clients.get(key) === managed) {
3562
+ this.clients.delete(key);
3563
+ }
3564
+ await this.tombstoneStop(key, managed.client);
3461
3565
  return this.getClient(root, server2, signal);
3462
3566
  }
3567
+ this.markHealthyGeneration(key);
3463
3568
  managed.refCount++;
3464
3569
  managed.lastUsedAt = this.now();
3465
3570
  return managed.client;
3466
3571
  }
3572
+ this.evictForAdmission();
3573
+ this.ensureRespawnAllowed(key, root, server2.id);
3467
3574
  const client = this.clientFactory(root, server2);
3468
3575
  const initStartedAt = this.now();
3469
3576
  const initPromise = (async () => {
@@ -3487,7 +3594,7 @@ class LspManager {
3487
3594
  if (this.clients.get(key) === newManaged) {
3488
3595
  this.clients.delete(key);
3489
3596
  }
3490
- await stopClientBestEffort(client);
3597
+ await this.tombstoneStop(key, client);
3491
3598
  throw err;
3492
3599
  }
3493
3600
  newManaged.pendingWaiters--;
@@ -3498,6 +3605,15 @@ class LspManager {
3498
3605
  await this.tryDeleteIfOrphaned(key, newManaged);
3499
3606
  signal.throwIfAborted();
3500
3607
  }
3608
+ if (!client.isAlive()) {
3609
+ this.recordDeadGeneration(key);
3610
+ if (this.clients.get(key) === newManaged) {
3611
+ this.clients.delete(key);
3612
+ }
3613
+ await this.tombstoneStop(key, client);
3614
+ return this.getClient(root, server2, signal);
3615
+ }
3616
+ this.markHealthyGeneration(key);
3501
3617
  newManaged.refCount++;
3502
3618
  newManaged.lastUsedAt = this.now();
3503
3619
  return client;
@@ -3518,14 +3634,20 @@ class LspManager {
3518
3634
  if (client && managed.client !== client)
3519
3635
  return;
3520
3636
  this.clients.delete(key);
3521
- stopClientBestEffort(managed.client);
3637
+ this.tombstoneStop(key, managed.client);
3522
3638
  }
3523
3639
  warmupClient(root, server2) {
3524
3640
  if (this.disposed)
3525
3641
  return;
3526
3642
  const key = this.getKey(root, server2.id);
3527
- if (this.clients.has(key))
3643
+ if (this.clients.has(key) || this.pendingStops.has(key))
3644
+ return;
3645
+ this.evictForAdmission();
3646
+ try {
3647
+ this.ensureRespawnAllowed(key, root, server2.id);
3648
+ } catch {
3528
3649
  return;
3650
+ }
3529
3651
  const client = this.clientFactory(root, server2);
3530
3652
  const initStartedAt = this.now();
3531
3653
  const initPromise = (async () => {
@@ -3551,7 +3673,7 @@ class LspManager {
3551
3673
  if (this.clients.get(key) === managed) {
3552
3674
  this.clients.delete(key);
3553
3675
  }
3554
- stopClientBestEffort(client);
3676
+ this.tombstoneStop(key, client);
3555
3677
  });
3556
3678
  }
3557
3679
  isServerInitializing(root, serverId) {
@@ -3595,8 +3717,11 @@ class LspManager {
3595
3717
  for (const managed of this.clients.values()) {
3596
3718
  stopPromises.push(stopClientBestEffort(managed.client));
3597
3719
  }
3720
+ const tombstonedStops = [...this.pendingStops.values()];
3598
3721
  this.clients.clear();
3599
- await Promise.allSettled(stopPromises);
3722
+ this.respawnBudgets.clear();
3723
+ await Promise.allSettled([...stopPromises, ...tombstonedStops]);
3724
+ this.pendingStops.clear();
3600
3725
  }
3601
3726
  }
3602
3727
  var _defaultInstance = null;
@@ -3606,49 +3731,43 @@ function getLspManager() {
3606
3731
  }
3607
3732
  return _defaultInstance;
3608
3733
  }
3609
- function getInstallDecisionsPath() {
3610
- return lspRequestContext().installDecisionsPath;
3611
- }
3612
- function loadInstallDecisions() {
3613
- const path2 = getInstallDecisionsPath();
3614
- if (!existsSync7(path2))
3615
- return {};
3616
- try {
3617
- const parsed = JSON.parse(readFileSync4(path2, "utf8"));
3618
- return isInstallDecisions(parsed) ? parsed : {};
3619
- } catch {
3620
- return {};
3734
+ var GIT_WORKSPACE_MARKER = ".git";
3735
+ var PROJECT_WORKSPACE_MARKERS = [
3736
+ "package.json",
3737
+ "pyproject.toml",
3738
+ "Cargo.toml",
3739
+ "go.mod",
3740
+ "pom.xml",
3741
+ "build.gradle"
3742
+ ];
3743
+ var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
3744
+ function findWorkspaceRootOutsideContext(directory) {
3745
+ const marked = nearestMarkedAncestor(directory);
3746
+ if (marked !== undefined)
3747
+ return marked;
3748
+ return realpathSync4(nearestExistingAncestor(directory));
3749
+ }
3750
+ function nearestMarkedAncestor(directory) {
3751
+ let current = directory;
3752
+ for (;; ) {
3753
+ if (existsSync7(current) && WORKSPACE_MARKERS.some((marker) => existsSync7(join3(current, marker)))) {
3754
+ return realpathSync4(current);
3755
+ }
3756
+ const parent = dirname7(current);
3757
+ if (parent === current)
3758
+ return;
3759
+ current = parent;
3621
3760
  }
3622
3761
  }
3623
- function loadInstallDecision(serverId) {
3624
- return loadInstallDecisions()[serverId];
3625
- }
3626
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3627
- const decisions = loadInstallDecisions();
3628
- decisions[serverId] = { decision, decidedAt };
3629
- writeInstallDecisions(decisions);
3630
- }
3631
- function isInstallDecision(value) {
3632
- return value === "declined" || value === "allowed";
3633
- }
3634
- function writeInstallDecisions(decisions) {
3635
- const path2 = getInstallDecisionsPath();
3636
- mkdirSync3(dirname7(path2), { recursive: true });
3637
- const tmpPath = `${path2}.tmp`;
3638
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3639
- `, "utf8");
3640
- renameSync2(tmpPath, path2);
3641
- }
3642
- function isInstallDecisions(value) {
3643
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3644
- }
3645
- function isInstallDecisionRecord(value) {
3646
- if (!isRecord5(value))
3647
- return false;
3648
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3649
- }
3650
- function isRecord5(value) {
3651
- return typeof value === "object" && value !== null && !Array.isArray(value);
3762
+ function nearestExistingAncestor(directory) {
3763
+ let current = directory;
3764
+ while (!existsSync7(current)) {
3765
+ const parent = dirname7(current);
3766
+ if (parent === current)
3767
+ return current;
3768
+ current = parent;
3769
+ }
3770
+ return current;
3652
3771
  }
3653
3772
  var LSP_INSTALL_HINTS = {
3654
3773
  typescript: "npm install -g typescript-language-server typescript",
@@ -3694,6 +3813,26 @@ var LSP_INSTALL_HINTS = {
3694
3813
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
3695
3814
  razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
3696
3815
  };
3816
+ var LSP_LOCAL_INSTALL_HINTS = {
3817
+ typescript: "bun add -d typescript-language-server typescript",
3818
+ vue: "bun add -d @vue/language-server",
3819
+ eslint: "bun add -d vscode-langservers-extracted",
3820
+ oxlint: "bun add -d oxlint",
3821
+ biome: "bun add -d @biomejs/biome",
3822
+ svelte: "bun add -d svelte-language-server",
3823
+ astro: "bun add -d @astrojs/language-server",
3824
+ bash: "bun add -d bash-language-server",
3825
+ "bash-ls": "bun add -d bash-language-server",
3826
+ "yaml-ls": "bun add -d yaml-language-server",
3827
+ php: "bun add -d intelephense",
3828
+ prisma: "bun add -d prisma",
3829
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
3830
+ pyright: "uv add --dev pyright",
3831
+ basedpyright: "uv add --dev basedpyright",
3832
+ ruff: "uv add --dev ruff",
3833
+ ty: "uv add --dev ty",
3834
+ "ruby-lsp": "bundle add ruby-lsp --group development"
3835
+ };
3697
3836
  var BUILTIN_SERVERS = {
3698
3837
  typescript: {
3699
3838
  command: ["typescript-language-server", "--stdio"],
@@ -3795,6 +3934,50 @@ var BUILTIN_SERVERS = {
3795
3934
  extensions: [".razor", ".cshtml"]
3796
3935
  }
3797
3936
  };
3937
+ function getInstallDecisionsPath() {
3938
+ return lspRequestContext().installDecisionsPath;
3939
+ }
3940
+ function loadInstallDecisions() {
3941
+ const path2 = getInstallDecisionsPath();
3942
+ if (!existsSync8(path2))
3943
+ return {};
3944
+ try {
3945
+ const parsed = JSON.parse(readFileSync4(path2, "utf8"));
3946
+ return isInstallDecisions(parsed) ? parsed : {};
3947
+ } catch {
3948
+ return {};
3949
+ }
3950
+ }
3951
+ function loadInstallDecision(serverId) {
3952
+ return loadInstallDecisions()[serverId];
3953
+ }
3954
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3955
+ const decisions = loadInstallDecisions();
3956
+ decisions[serverId] = { decision, decidedAt };
3957
+ writeInstallDecisions(decisions);
3958
+ }
3959
+ function isInstallDecision(value) {
3960
+ return value === "declined" || value === "allowed";
3961
+ }
3962
+ function writeInstallDecisions(decisions) {
3963
+ const path2 = getInstallDecisionsPath();
3964
+ mkdirSync3(dirname8(path2), { recursive: true });
3965
+ const tmpPath = `${path2}.tmp`;
3966
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3967
+ `, "utf8");
3968
+ renameSync2(tmpPath, path2);
3969
+ }
3970
+ function isInstallDecisions(value) {
3971
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3972
+ }
3973
+ function isInstallDecisionRecord(value) {
3974
+ if (!isRecord5(value))
3975
+ return false;
3976
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3977
+ }
3978
+ function isRecord5(value) {
3979
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3980
+ }
3798
3981
  function getProjectConfigPaths() {
3799
3982
  return lspRequestContext().projectConfigPaths;
3800
3983
  }
@@ -3802,7 +3985,7 @@ function getUserConfigPath() {
3802
3985
  return lspRequestContext().userConfigPath;
3803
3986
  }
3804
3987
  function loadJsonFile(path2) {
3805
- if (!existsSync8(path2))
3988
+ if (!existsSync9(path2))
3806
3989
  return null;
3807
3990
  try {
3808
3991
  const parsed = JSON.parse(readFileSync5(path2, "utf-8"));
@@ -3988,50 +4171,151 @@ function getDisabledServerIds() {
3988
4171
  }
3989
4172
  return disabled;
3990
4173
  }
3991
- function isServerInstalled(command, _workingDirectory) {
3992
- if (command.length === 0)
3993
- return false;
3994
- const [cmd] = command;
3995
- if (!cmd)
3996
- return false;
3997
- if (cmd.includes("/") || cmd.includes("\\")) {
3998
- if (existsSync9(cmd))
3999
- return true;
4174
+ var LOCAL_BIN_RULES = [
4175
+ {
4176
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
4177
+ binDirs: [join4("node_modules", ".bin")]
4178
+ },
4179
+ {
4180
+ markers: [
4181
+ "pyproject.toml",
4182
+ "ty.toml",
4183
+ "requirements.txt",
4184
+ "setup.py",
4185
+ "setup.cfg",
4186
+ "Pipfile",
4187
+ "pyrightconfig.json",
4188
+ "ruff.toml",
4189
+ ".ruff.toml"
4190
+ ],
4191
+ binDirs: [
4192
+ join4(".venv", "bin"),
4193
+ join4(".venv", "Scripts"),
4194
+ join4("venv", "bin"),
4195
+ join4("venv", "Scripts"),
4196
+ join4(".env", "bin"),
4197
+ join4(".env", "Scripts")
4198
+ ]
4199
+ },
4200
+ {
4201
+ markers: ["Gemfile", "Gemfile.lock"],
4202
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4203
+ },
4204
+ {
4205
+ markers: ["go.mod", "go.sum", "go.work"],
4206
+ binDirs: ["bin"]
4207
+ }
4208
+ ];
4209
+ var resolutionCache = new Map;
4210
+ var probeCount = 0;
4211
+ function probe(path2) {
4212
+ probeCount += 1;
4213
+ return existsSync10(path2);
4214
+ }
4215
+ function executableSuffixes(platform, pathExt) {
4216
+ if (platform !== "win32")
4217
+ return [""];
4218
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4219
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4220
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4221
+ }
4222
+ function probeWithSuffixes(directory, command, suffixes) {
4223
+ for (const suffix of suffixes) {
4224
+ const candidate = join4(directory, command + suffix);
4225
+ if (probe(candidate))
4226
+ return candidate;
4000
4227
  }
4001
- const isWindows = process.platform === "win32";
4002
- let exts = [""];
4003
- if (isWindows) {
4004
- const pathExt = process.env["PATHEXT"] ?? "";
4005
- if (pathExt) {
4006
- const systemExts = pathExt.split(";").filter(Boolean);
4007
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4008
- } else {
4009
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4228
+ return null;
4229
+ }
4230
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4231
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4232
+ let current = resolve7(workingDirectory);
4233
+ while (true) {
4234
+ for (const rule of LOCAL_BIN_RULES) {
4235
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
4236
+ continue;
4237
+ for (const binDir of rule.binDirs) {
4238
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4239
+ if (found !== null)
4240
+ return found;
4241
+ }
4010
4242
  }
4243
+ if (probe(join4(current, ".git")))
4244
+ return null;
4245
+ if (boundary !== undefined && current === boundary)
4246
+ return null;
4247
+ const parent = dirname9(current);
4248
+ if (parent === current)
4249
+ return null;
4250
+ current = parent;
4011
4251
  }
4012
- let pathEnv = process.env["PATH"] ?? "";
4013
- if (isWindows && !pathEnv) {
4252
+ }
4253
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4254
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4255
+ if (platform === "win32" && !pathEnv) {
4014
4256
  pathEnv = process.env["Path"] ?? "";
4015
4257
  }
4016
- const paths = pathEnv.split(delimiter3);
4017
- for (const p of paths) {
4018
- for (const suffix of exts) {
4019
- if (existsSync9(join3(p, cmd + suffix))) {
4020
- return true;
4021
- }
4022
- }
4258
+ for (const entry of pathEnv.split(delimiter3)) {
4259
+ if (entry.length === 0)
4260
+ continue;
4261
+ const found = probeWithSuffixes(entry, command, suffixes);
4262
+ if (found !== null)
4263
+ return found;
4023
4264
  }
4024
- if (cmd === "node")
4025
- return true;
4026
- return false;
4265
+ return null;
4266
+ }
4267
+ function resolveServerBinary(command, workingDirectory, options = {}) {
4268
+ if (command.length === 0)
4269
+ return null;
4270
+ const [cmd] = command;
4271
+ if (cmd === undefined || cmd.length === 0)
4272
+ return null;
4273
+ const platform = options.platform ?? process.platform;
4274
+ const suffixes = executableSuffixes(platform, options.pathExt);
4275
+ if (cmd.includes("/") || cmd.includes("\\")) {
4276
+ const explicit = isAbsolute5(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4277
+ return probe(explicit) ? explicit : null;
4278
+ }
4279
+ const cacheKey = JSON.stringify([
4280
+ workingDirectory ?? "",
4281
+ cmd,
4282
+ platform,
4283
+ options.stopAt ?? "",
4284
+ options.pathExt ?? "",
4285
+ options.pathEnv ?? process.env["PATH"] ?? ""
4286
+ ]);
4287
+ const cached = resolutionCache.get(cacheKey);
4288
+ if (cached !== undefined)
4289
+ return cached;
4290
+ let resolved = null;
4291
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
4292
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4293
+ }
4294
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4295
+ if (resolved === null && cmd === "node")
4296
+ resolved = cmd;
4297
+ resolutionCache.set(cacheKey, resolved);
4298
+ return resolved;
4299
+ }
4300
+ function isServerInstalled(command, workingDirectory, options = {}) {
4301
+ if (command.length === 0)
4302
+ return false;
4303
+ return resolveServerBinary(command, workingDirectory, options) !== null;
4304
+ }
4305
+ function withResolvedCommand(command, binaryPath) {
4306
+ return [binaryPath, ...command.slice(1)];
4027
4307
  }
4028
4308
  function findServerForExtension(ext) {
4029
4309
  const servers = getMergedServers();
4310
+ const workingDirectory = contextCwd();
4030
4311
  for (const server2 of servers) {
4031
- if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4312
+ if (!server2.extensions.includes(ext))
4313
+ continue;
4314
+ const binaryPath = resolveServerBinary(server2.command, workingDirectory);
4315
+ if (binaryPath !== null) {
4032
4316
  const resolvedServer = {
4033
4317
  id: server2.id,
4034
- command: server2.command,
4318
+ command: withResolvedCommand(server2.command, binaryPath),
4035
4319
  extensions: server2.extensions,
4036
4320
  priority: server2.priority
4037
4321
  };
@@ -4078,6 +4362,7 @@ function findServerForExtension(ext) {
4078
4362
  function getAllServers() {
4079
4363
  const servers = getMergedServers();
4080
4364
  const disabled = getDisabledServerIds();
4365
+ const workingDirectory = contextCwd();
4081
4366
  const result = [];
4082
4367
  const seen = new Set;
4083
4368
  for (const server2 of servers) {
@@ -4085,7 +4370,7 @@ function getAllServers() {
4085
4370
  continue;
4086
4371
  result.push({
4087
4372
  id: server2.id,
4088
- installed: isServerInstalled(server2.command),
4373
+ installed: isServerInstalled(server2.command, workingDirectory),
4089
4374
  extensions: server2.extensions,
4090
4375
  disabled: false,
4091
4376
  source: server2.source,
@@ -4099,7 +4384,7 @@ function getAllServers() {
4099
4384
  const builtin = BUILTIN_SERVERS[id];
4100
4385
  result.push({
4101
4386
  id,
4102
- installed: builtin ? isServerInstalled(builtin.command) : false,
4387
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4103
4388
  extensions: builtin?.extensions ?? [],
4104
4389
  disabled: true,
4105
4390
  source: "disabled",
@@ -4108,7 +4393,6 @@ function getAllServers() {
4108
4393
  }
4109
4394
  return result;
4110
4395
  }
4111
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
4112
4396
  function isDirectoryPath(filePath) {
4113
4397
  try {
4114
4398
  return statSync4(filePath).isDirectory();
@@ -4117,32 +4401,90 @@ function isDirectoryPath(filePath) {
4117
4401
  }
4118
4402
  }
4119
4403
  function findWorkspaceRoot(filePath) {
4120
- const abs = resolvePathInsideContext(filePath);
4404
+ const cwd = contextCwd();
4405
+ const abs = resolveReadablePathInsideContext(filePath);
4121
4406
  let dir = abs;
4122
4407
  if (!isDirectoryPath(dir)) {
4123
- dir = dirname8(dir);
4124
- }
4125
- let prevDir = "";
4126
- while (dir !== prevDir) {
4127
- for (const marker of WORKSPACE_MARKERS) {
4128
- if (existsSync10(join4(dir, marker))) {
4129
- return dir;
4408
+ dir = dirname10(dir);
4409
+ }
4410
+ if (!isPathInside(cwd, abs))
4411
+ return findWorkspaceRootOutsideContext(dir);
4412
+ const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4413
+ let nearestPackageRoot;
4414
+ while (isPathInside(cwd, dir)) {
4415
+ const canonicalDir = existingDirectoryInsideContext(dir, cwd);
4416
+ if (canonicalDir !== undefined) {
4417
+ if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
4418
+ return canonicalDir;
4419
+ }
4420
+ if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
4421
+ nearestPackageRoot = canonicalDir;
4130
4422
  }
4131
4423
  }
4132
- prevDir = dir;
4133
- dir = dirname8(dir);
4424
+ if (dir === cwd)
4425
+ break;
4426
+ dir = dirname10(dir);
4134
4427
  }
4135
- return dirname8(abs);
4428
+ return nearestPackageRoot ?? fallbackRoot;
4429
+ }
4430
+ function hasProjectWorkspaceMarker(directory) {
4431
+ return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
4432
+ }
4433
+ function resolveReadablePathInsideContext(filePath) {
4434
+ const cwd = contextCwd();
4435
+ const abs = resolve8(cwd, filePath);
4436
+ if (isPathInside(cwd, abs))
4437
+ return abs;
4438
+ const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
4439
+ if (rebased !== undefined)
4440
+ return rebased;
4441
+ return canonicalizeExistingOrNearestAncestor(abs);
4136
4442
  }
4137
4443
  function resolvePathInsideContext(filePath) {
4138
4444
  const cwd = contextCwd();
4139
- const abs = resolve7(cwd, filePath);
4445
+ const abs = resolveReadablePathInsideContext(filePath);
4140
4446
  const canonical = canonicalizeExistingOrNearestAncestor(abs);
4141
4447
  if (!isPathInside(cwd, canonical)) {
4142
4448
  throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
4143
4449
  }
4144
4450
  return canonical;
4145
4451
  }
4452
+ function rebaseThroughCanonicalAncestor(path2, cwd) {
4453
+ let current = path2;
4454
+ const suffix = [];
4455
+ while (true) {
4456
+ if (existsSync11(current)) {
4457
+ const canonical = realpathSync5(current);
4458
+ if (isPathInside(cwd, canonical))
4459
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
4460
+ }
4461
+ const parent = dirname10(current);
4462
+ if (parent === current)
4463
+ return;
4464
+ suffix.unshift(basename3(current));
4465
+ current = parent;
4466
+ }
4467
+ }
4468
+ function existingDirectoryInsideContext(directory, cwd) {
4469
+ if (!existsSync11(directory))
4470
+ return;
4471
+ const canonical = realpathSync5(directory);
4472
+ if (!statSync4(canonical).isDirectory())
4473
+ return;
4474
+ return isPathInside(cwd, canonical) ? canonical : undefined;
4475
+ }
4476
+ function nearestExistingDirectoryInsideContext(directory, cwd) {
4477
+ let current = directory;
4478
+ while (isPathInside(cwd, current)) {
4479
+ const canonical = existingDirectoryInsideContext(current, cwd);
4480
+ if (canonical !== undefined)
4481
+ return canonical;
4482
+ if (current === cwd)
4483
+ return;
4484
+ current = dirname10(current);
4485
+ }
4486
+ return;
4487
+ }
4146
4488
  function formatServerLookupError(result) {
4147
4489
  if (result.status === "not_installed") {
4148
4490
  return formatNotInstalled(result);
@@ -4166,6 +4508,19 @@ function formatServerLookupError(result) {
4166
4508
  ].join(`
4167
4509
  `);
4168
4510
  }
4511
+ function formatInstallOptions(serverId, installHint) {
4512
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
4513
+ if (localHint === undefined) {
4514
+ return ["To install, run:", ` ${installHint}`];
4515
+ }
4516
+ return [
4517
+ "To install in THIS repository (preferred — no global install needed):",
4518
+ ` ${localHint}`,
4519
+ "",
4520
+ "Or install it globally:",
4521
+ ` ${installHint}`
4522
+ ];
4523
+ }
4169
4524
  function formatNotInstalled(result) {
4170
4525
  const { server: server2, installHint } = result;
4171
4526
  const extensions = server2.extensions.join(", ");
@@ -4180,19 +4535,19 @@ function formatNotInstalled(result) {
4180
4535
  `Command not found: ${server2.command[0]}`,
4181
4536
  ""
4182
4537
  ];
4538
+ const installOptions = formatInstallOptions(server2.id, installHint);
4183
4539
  if (decision === "allowed") {
4184
4540
  return [
4185
4541
  ...header,
4186
4542
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4187
- ` ${installHint}`
4543
+ ...installOptions.slice(1)
4188
4544
  ].join(`
4189
4545
  `);
4190
4546
  }
4191
4547
  if (!context.capabilities.installDecisionTool) {
4192
4548
  return [
4193
4549
  ...header,
4194
- "To install, run:",
4195
- ` ${installHint}`,
4550
+ ...installOptions,
4196
4551
  "",
4197
4552
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4198
4553
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4201,8 +4556,7 @@ function formatNotInstalled(result) {
4201
4556
  }
4202
4557
  return [
4203
4558
  ...header,
4204
- "To install, run:",
4205
- ` ${installHint}`,
4559
+ ...installOptions,
4206
4560
  "",
4207
4561
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4208
4562
  "- If the user agrees: run the install command above, then retry this tool.",
@@ -4213,7 +4567,7 @@ function formatNotInstalled(result) {
4213
4567
  ].join(`
4214
4568
  `);
4215
4569
  }
4216
- var READ_ONLY_RETRY_TOOLS = new Set([
4570
+ var READ_ONLY_TOOLS = new Set([
4217
4571
  "diagnostics",
4218
4572
  "definition",
4219
4573
  "references",
@@ -4222,7 +4576,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
4222
4576
  "prepareRename"
4223
4577
  ]);
4224
4578
  async function withLspClient(filePath, fn, toolName, options = {}) {
4225
- const absPath = resolvePathInsideContext(filePath);
4579
+ const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
4226
4580
  if (isDirectoryPath(absPath)) {
4227
4581
  throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
4228
4582
  }
@@ -4237,9 +4591,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4237
4591
  const acquireAndCall = async (allowRetry) => {
4238
4592
  const client = await manager.getClient(root, server2, options.signal);
4239
4593
  try {
4240
- return await fn(client, root);
4594
+ return await fn(client, root, absPath);
4241
4595
  } catch (err) {
4242
- if (allowRetry && READ_ONLY_RETRY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4596
+ if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4243
4597
  manager.invalidateClient(root, server2.id, client);
4244
4598
  return acquireAndCall(false);
4245
4599
  }
@@ -4379,7 +4733,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
4379
4733
  for (const entry of entries) {
4380
4734
  if (files.length >= maxFiles)
4381
4735
  return;
4382
- const fullPath = join5(currentDir, entry);
4736
+ const fullPath = join6(currentDir, entry);
4383
4737
  let stat;
4384
4738
  try {
4385
4739
  stat = lstatSync5(fullPath);
@@ -4404,8 +4758,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4404
4758
  if (!extension.startsWith(".")) {
4405
4759
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4406
4760
  }
4407
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4408
- if (!existsSync11(absDir)) {
4761
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
4762
+ if (!existsSync12(absDir)) {
4409
4763
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4410
4764
  }
4411
4765
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
@@ -4506,7 +4860,7 @@ function inferExtensionFromDirectory(directory) {
4506
4860
  for (const entry of entries) {
4507
4861
  if (scanned >= MAX_SCAN_ENTRIES)
4508
4862
  return;
4509
- const fullPath = join6(dir, entry);
4863
+ const fullPath = join7(dir, entry);
4510
4864
  let stat;
4511
4865
  try {
4512
4866
  stat = lstatSync6(fullPath);
@@ -4669,7 +5023,7 @@ async function executeLspDiagnostics(params, signal) {
4669
5023
  const filePath = requireString(params, "filePath");
4670
5024
  const severity = severityFilter(params);
4671
5025
  try {
4672
- const absPath = resolvePathInsideContext(filePath);
5026
+ const absPath = resolveReadablePathInsideContext(filePath);
4673
5027
  if (isDirectoryPath(absPath)) {
4674
5028
  const extension = inferExtensionFromDirectory(absPath);
4675
5029
  if (!extension) {
@@ -4698,7 +5052,7 @@ async function executeLspDiagnostics(params, signal) {
4698
5052
  };
4699
5053
  return text(output2.output, details2);
4700
5054
  }
4701
- const result = await withLspClient(filePath, async (client) => client.diagnostics(filePath, signal), "diagnostics", clientOptions(signal));
5055
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
4702
5056
  if (result.transientError) {
4703
5057
  const message = result.transientError.message;
4704
5058
  const details2 = {
@@ -4745,6 +5099,91 @@ async function executeLspDiagnostics(params, signal) {
4745
5099
  throw error;
4746
5100
  }
4747
5101
  }
5102
+ var DEFAULT_FORMATTING_OPTIONS = {
5103
+ tabSize: 4,
5104
+ insertSpaces: false,
5105
+ trimTrailingWhitespace: true,
5106
+ insertFinalNewline: true,
5107
+ trimFinalNewlines: true
5108
+ };
5109
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
5110
+ async function formatDocumentWithClient(client, filePath, options = {}) {
5111
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
5112
+ if (edits === null)
5113
+ return { status: "unavailable", reason: "capability_not_advertised" };
5114
+ if (edits.length === 0)
5115
+ return UNCHANGED;
5116
+ const before = readFileSync6(filePath, "utf-8");
5117
+ const normalized = normalizeTextEdits(before, edits, 0);
5118
+ if (normalized.text === before)
5119
+ return UNCHANGED;
5120
+ writeAtomically(filePath, normalized.text);
5121
+ await client.openFile(filePath);
5122
+ return {
5123
+ status: "formatted",
5124
+ ...lineDelta(normalized.edits)
5125
+ };
5126
+ }
5127
+ function lineDelta(edits) {
5128
+ let linesAdded = 0;
5129
+ let linesRemoved = 0;
5130
+ for (const edit of edits) {
5131
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
5132
+ linesAdded += edit.newText.split(`
5133
+ `).length;
5134
+ }
5135
+ return { linesAdded, linesRemoved };
5136
+ }
5137
+ function writeAtomically(filePath, content) {
5138
+ const tempPath = `${filePath}.omo-format.tmp`;
5139
+ writeFileSync3(tempPath, content, "utf-8");
5140
+ try {
5141
+ renameSync3(tempPath, filePath);
5142
+ } catch (error) {
5143
+ try {
5144
+ unlinkSync2(tempPath);
5145
+ } catch {}
5146
+ throw error;
5147
+ }
5148
+ }
5149
+ async function executeLspFormat(params, signal) {
5150
+ const filePath = requireString(params, "filePath");
5151
+ try {
5152
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
5153
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
5154
+ } catch (error) {
5155
+ const missingDependency = missingDependencyResult(error, {
5156
+ filePath,
5157
+ status: "unavailable",
5158
+ reason: "server_unavailable",
5159
+ linesAdded: 0,
5160
+ linesRemoved: 0
5161
+ });
5162
+ if (missingDependency)
5163
+ return missingDependency;
5164
+ throw error;
5165
+ }
5166
+ }
5167
+ function formatDetails(filePath, result) {
5168
+ if (result.status === "unavailable") {
5169
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5170
+ }
5171
+ return {
5172
+ filePath,
5173
+ status: result.status,
5174
+ linesAdded: result.linesAdded,
5175
+ linesRemoved: result.linesRemoved
5176
+ };
5177
+ }
5178
+ function describeResult(filePath, result) {
5179
+ if (result.status === "unavailable") {
5180
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5181
+ }
5182
+ if (result.status === "unchanged") {
5183
+ return `Already formatted: ${filePath}`;
5184
+ }
5185
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5186
+ }
4748
5187
  async function executeLspInstallDecision(params) {
4749
5188
  const serverId = requireString(params, "server_id");
4750
5189
  const decision = params["decision"];
@@ -4770,7 +5209,7 @@ async function executeLspGotoDefinition(params, signal) {
4770
5209
  const line = requireNumber(params, "line");
4771
5210
  const character = requireNumber(params, "character");
4772
5211
  try {
4773
- const result = await withLspClient(filePath, async (client) => client.definition(filePath, line, character, signal), "definition", clientOptions(signal));
5212
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
4774
5213
  const locations = !result ? [] : Array.isArray(result) ? result : [result];
4775
5214
  const details = { filePath, line, character, locations };
4776
5215
  if (locations.length === 0)
@@ -4795,7 +5234,7 @@ async function executeLspFindReferences(params, signal) {
4795
5234
  const character = requireNumber(params, "character");
4796
5235
  const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
4797
5236
  try {
4798
- const result = await withLspClient(filePath, async (client) => client.references(filePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
5237
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
4799
5238
  const references = Array.isArray(result) ? result : [];
4800
5239
  const total = references.length;
4801
5240
  const truncated = total > DEFAULT_MAX_REFERENCES;
@@ -4835,7 +5274,7 @@ async function executeLspPrepareRename(params, signal) {
4835
5274
  const line = requireNumber(params, "line");
4836
5275
  const character = requireNumber(params, "character");
4837
5276
  try {
4838
- const result = await withLspClient(filePath, async (client) => client.prepareRename(filePath, line, character, signal), "prepareRename", clientOptions(signal));
5277
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
4839
5278
  const details = { filePath, line, character, result };
4840
5279
  return text(formatPrepareRenameResult(result), details);
4841
5280
  } catch (error) {
@@ -4856,7 +5295,7 @@ async function executeLspRename(params, signal) {
4856
5295
  const character = requireNumber(params, "character");
4857
5296
  const newName = requireString(params, "newName");
4858
5297
  try {
4859
- const result = await withLspClient(filePath, async (client) => client.rename(filePath, line, character, newName, signal), "rename", clientOptions(signal));
5298
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
4860
5299
  const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
4861
5300
  return text(formatApplyResult(result.apply), details, !result.apply.success);
4862
5301
  } catch (error) {
@@ -4930,7 +5369,7 @@ async function executeLspSymbols(params, signal) {
4930
5369
  const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
4931
5370
  return formatSymbolsResult(filePath, scope, symbols2, limit, query);
4932
5371
  }
4933
- const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(filePath, signal), "documentSymbols", clientOptions(signal));
5372
+ const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
4934
5373
  return formatSymbolsResult(filePath, scope, symbols, limit);
4935
5374
  } catch (error) {
4936
5375
  const query = optionalString(params, "query");
@@ -5064,6 +5503,16 @@ var LSP_MCP_TOOLS = [
5064
5503
  }, ["filePath", "line", "character", "newName"]),
5065
5504
  execute: executeLspRename
5066
5505
  },
5506
+ {
5507
+ name: "format",
5508
+ aliases: ["lsp_format"],
5509
+ title: "LSP Format",
5510
+ description: "Format a source file with its language server and write the returned edits to disk.",
5511
+ inputSchema: objectSchema({
5512
+ filePath: { type: "string", description: "Source file path to format." }
5513
+ }, ["filePath"]),
5514
+ execute: executeLspFormat
5515
+ },
5067
5516
  {
5068
5517
  name: "install_decision",
5069
5518
  aliases: ["lsp_install_decision"],
@@ -5130,7 +5579,7 @@ function withContext(args, context) {
5130
5579
  function ensureDaemonAvailable(paths, ensure, signal) {
5131
5580
  if (!signal)
5132
5581
  return ensure(paths);
5133
- return new Promise((resolve9, reject) => {
5582
+ return new Promise((resolve10, reject) => {
5134
5583
  let settled = false;
5135
5584
  const finish = (run) => {
5136
5585
  if (settled)
@@ -5145,11 +5594,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
5145
5594
  return;
5146
5595
  }
5147
5596
  signal.addEventListener("abort", onAbort, { once: true });
5148
- Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve9()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
5597
+ Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve10()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
5149
5598
  });
5150
5599
  }
5151
5600
  function sendToolCall(paths, token, name, args, options) {
5152
- return new Promise((resolve9, reject) => {
5601
+ return new Promise((resolve10, reject) => {
5153
5602
  const socket = connect(paths.socket);
5154
5603
  const requestId = allocateProxyRequestId();
5155
5604
  let settled = false;
@@ -5202,7 +5651,7 @@ function sendToolCall(paths, token, name, args, options) {
5202
5651
  }
5203
5652
  const result = toToolResult(message, requestId);
5204
5653
  if (result)
5205
- finish(() => resolve9(result));
5654
+ finish(() => resolve10(result));
5206
5655
  else
5207
5656
  finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
5208
5657
  });
@@ -5251,10 +5700,9 @@ var OMO_LSP_DAEMON_VERSION2 = "OMO_LSP_DAEMON_VERSION";
5251
5700
  var DAEMON_VERSION_PATTERN2 = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
5252
5701
 
5253
5702
  class InvalidRuntimeOverrideError2 extends Error {
5254
- code = "invalid_runtime_override";
5255
- reason;
5256
5703
  constructor(reason, message) {
5257
5704
  super(message);
5705
+ this.code = "invalid_runtime_override";
5258
5706
  this.name = "InvalidRuntimeOverrideError";
5259
5707
  this.reason = reason;
5260
5708
  }
@@ -5274,12 +5722,12 @@ function resolveDaemonRuntime2(env, defaults) {
5274
5722
  throw new InvalidRuntimeOverrideError2("paired_values_required", `${OMO_LSP_DAEMON_CLI2} and ${OMO_LSP_DAEMON_VERSION2} must be set together`);
5275
5723
  }
5276
5724
  if (!hasCliOverride || !hasVersionOverride) {
5277
- if (!isAbsolute5(defaults.cliPath)) {
5725
+ if (!isAbsolute6(defaults.cliPath)) {
5278
5726
  throw new InvalidRuntimeOverrideError2("packaged_cli_must_be_absolute", "Packaged LSP daemon CLI path must be absolute");
5279
5727
  }
5280
5728
  return { cliPath: defaults.cliPath, version: validateDaemonVersion2(defaults.version) };
5281
5729
  }
5282
- if (!isAbsolute5(cliOverride)) {
5730
+ if (!isAbsolute6(cliOverride)) {
5283
5731
  throw new InvalidRuntimeOverrideError2("cli_must_be_absolute", `${OMO_LSP_DAEMON_CLI2} must be an absolute path to an existing regular file`);
5284
5732
  }
5285
5733
  const stat = statSync5(cliOverride, { throwIfNoEntry: false });
@@ -5400,15 +5848,14 @@ function extensionKey(filePath) {
5400
5848
  }
5401
5849
  // ../../../../lsp-core/src/request-context.ts
5402
5850
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
5403
- import { existsSync as existsSync12, realpathSync as realpathSync4, statSync as statSync6 } from "node:fs";
5404
- import { basename as basename3, delimiter as delimiter4, dirname as dirname2, isAbsolute as isAbsolute6, join as join7, relative as relative5, resolve as resolve9 } from "node:path";
5851
+ import { existsSync as existsSync13, realpathSync as realpathSync6, statSync as statSync6 } from "node:fs";
5852
+ import { basename as basename4, delimiter as delimiter4, dirname as dirname2, isAbsolute as isAbsolute7, join as join8, relative as relative5, resolve as resolve10 } from "node:path";
5405
5853
 
5406
5854
  class LspRequestContextParseError2 extends Error {
5407
- code;
5408
- name = "LspRequestContextParseError";
5409
5855
  constructor(code, message) {
5410
5856
  super(message);
5411
5857
  this.code = code;
5858
+ this.name = "LspRequestContextParseError";
5412
5859
  }
5413
5860
  }
5414
5861
  var storage2 = new AsyncLocalStorage2;
@@ -5443,26 +5890,26 @@ function parseLspRequestContext2(value) {
5443
5890
  };
5444
5891
  }
5445
5892
  function canonicalCwd2(cwd) {
5446
- const resolved = resolve9(cwd);
5447
- if (!existsSync12(resolved) || !statSync6(resolved).isDirectory()) {
5893
+ const resolved = resolve10(cwd);
5894
+ if (!existsSync13(resolved) || !statSync6(resolved).isDirectory()) {
5448
5895
  throw new LspRequestContextParseError2("invalid_cwd", `LSP request cwd must be an existing directory: ${cwd}`);
5449
5896
  }
5450
- return realpathSync4(resolved);
5897
+ return realpathSync6(resolved);
5451
5898
  }
5452
5899
  function canonicalizeExistingOrNearestAncestor2(path2) {
5453
- let current = resolve9(path2);
5900
+ let current = resolve10(path2);
5454
5901
  const suffix = [];
5455
5902
  while (true) {
5456
5903
  try {
5457
- const existing = realpathSync4(current);
5458
- return suffix.length === 0 ? existing : join7(existing, ...suffix);
5904
+ const existing = realpathSync6(current);
5905
+ return suffix.length === 0 ? existing : join8(existing, ...suffix);
5459
5906
  } catch (error) {
5460
5907
  if (!isMissingPathError2(error))
5461
5908
  throw error;
5462
5909
  const parent = dirname2(current);
5463
5910
  if (parent === current)
5464
5911
  throw error;
5465
- suffix.unshift(basename3(current));
5912
+ suffix.unshift(basename4(current));
5466
5913
  current = parent;
5467
5914
  }
5468
5915
  }
@@ -5493,14 +5940,14 @@ function stringArrayField2(value, field) {
5493
5940
  return fieldValue;
5494
5941
  }
5495
5942
  function requireAbsolutePath2(path2, field) {
5496
- if (!isAbsolute6(path2)) {
5943
+ if (!isAbsolute7(path2)) {
5497
5944
  throw new LspRequestContextParseError2("relative_path", `LSP request context.${field} must be absolute: ${path2}`);
5498
5945
  }
5499
5946
  }
5500
5947
  function isPathInside2(parent, child) {
5501
- const childPath = resolve9(child);
5948
+ const childPath = resolve10(child);
5502
5949
  const relativePath = relative5(parent, childPath);
5503
- return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute6(relativePath);
5950
+ return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute7(relativePath);
5504
5951
  }
5505
5952
  function isMissingPathError2(error) {
5506
5953
  const code = errorCode2(error);
@@ -5523,9 +5970,9 @@ function errorCode2(error) {
5523
5970
  }
5524
5971
 
5525
5972
  // src/daemon-cli-path.ts
5526
- import { existsSync as existsSync14, readFileSync as readFileSync6 } from "node:fs";
5973
+ import { existsSync as existsSync15, readFileSync as readFileSync7 } from "node:fs";
5527
5974
  import { createRequire as createRequire2 } from "node:module";
5528
- import { dirname as dirname9, join as join9 } from "node:path";
5975
+ import { dirname as dirname11, join as join10 } from "node:path";
5529
5976
  import { fileURLToPath as fileURLToPath4 } from "node:url";
5530
5977
  var requireFromHere2 = createRequire2(import.meta.url);
5531
5978
  var PACKAGE_LSP_DAEMON_CLI = "@code-yeongyu/lsp-daemon/cli";
@@ -5547,7 +5994,7 @@ function resolveLspDaemonCli() {
5547
5994
  if (packageCli !== null)
5548
5995
  return resolveConfiguredLspDaemonCli(packageCli);
5549
5996
  const bundledCli = fileURLToPath4(new URL("../../lsp-daemon/dist/cli.js", import.meta.url));
5550
- if (existsSync14(bundledCli))
5997
+ if (existsSync15(bundledCli))
5551
5998
  return resolveConfiguredLspDaemonCli(bundledCli);
5552
5999
  return resolveConfiguredLspDaemonCli(bundledCli);
5553
6000
  }
@@ -5572,7 +6019,7 @@ function resolveConfiguredLspDaemonCli(cliPath) {
5572
6019
  }
5573
6020
  function readDaemonPackageVersion(cliPath) {
5574
6021
  try {
5575
- const parsed = JSON.parse(readFileSync6(join9(dirname9(cliPath), "package.json"), "utf8"));
6022
+ const parsed = JSON.parse(readFileSync7(join10(dirname11(cliPath), "package.json"), "utf8"));
5576
6023
  if (isRecord9(parsed) && typeof parsed["version"] === "string" && parsed["version"].length > 0) {
5577
6024
  return parsed["version"];
5578
6025
  }
@@ -5587,9 +6034,9 @@ function isRecord9(value) {
5587
6034
  }
5588
6035
 
5589
6036
  // src/lsp-session-state.ts
5590
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "node:fs";
6037
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "node:fs";
5591
6038
  import { homedir } from "node:os";
5592
- import { dirname as dirname11, join as join10 } from "node:path";
6039
+ import { dirname as dirname13, join as join11 } from "node:path";
5593
6040
  function sessionIdFrom(input) {
5594
6041
  return typeof input.session_id === "string" && input.session_id.length > 0 ? input.session_id : undefined;
5595
6042
  }
@@ -5615,12 +6062,12 @@ function isLspDaemonUnreachableDiagnostics(diagnostics) {
5615
6062
  return diagnostics.includes("LSP daemon unreachable");
5616
6063
  }
5617
6064
  function sessionStatePath(sessionId) {
5618
- const root = process.env["PLUGIN_DATA"] ?? join10(homedir(), ".codex", "codex-lsp");
5619
- return join10(root, "sessions", `${safePathSegment(sessionId)}.json`);
6065
+ const root = process.env["PLUGIN_DATA"] ?? join11(homedir(), ".codex", "codex-lsp");
6066
+ return join11(root, "sessions", `${safePathSegment(sessionId)}.json`);
5620
6067
  }
5621
6068
  function readSessionState(path2) {
5622
6069
  try {
5623
- const parsed = JSON.parse(readFileSync8(path2, "utf8"));
6070
+ const parsed = JSON.parse(readFileSync9(path2, "utf8"));
5624
6071
  if (isRecord10(parsed) && isLspSessionState(parsed))
5625
6072
  return normalizeSessionState(parsed);
5626
6073
  return emptyState();
@@ -5631,8 +6078,8 @@ function readSessionState(path2) {
5631
6078
  }
5632
6079
  }
5633
6080
  function writeSessionState(path2, state) {
5634
- mkdirSync4(dirname11(path2), { recursive: true });
5635
- writeFileSync3(path2, `${JSON.stringify(state)}
6081
+ mkdirSync4(dirname13(path2), { recursive: true });
6082
+ writeFileSync4(path2, `${JSON.stringify(state)}
5636
6083
  `);
5637
6084
  }
5638
6085
  function emptyState() {
@@ -5775,13 +6222,13 @@ function notConfiguredAvailability(details) {
5775
6222
  return typeof extension === "string" && extension.length > 0 ? { extension } : undefined;
5776
6223
  }
5777
6224
  function codexLspRequestContext(env = process.env, cwd = process.cwd()) {
5778
- const canonicalCwd3 = realpathSync6(resolve11(cwd));
5779
- const codexHome = resolve11(env["CODEX_HOME"]?.trim() || join11(homedir3(), ".codex"));
6225
+ const canonicalCwd3 = realpathSync8(resolve12(cwd));
6226
+ const codexHome = resolve12(env["CODEX_HOME"]?.trim() || join12(homedir3(), ".codex"));
5780
6227
  return parseLspRequestContext2({
5781
6228
  cwd: canonicalCwd3,
5782
- projectConfigPaths: [join11(canonicalCwd3, ".codex", "lsp-client.json")],
5783
- userConfigPath: join11(codexHome, "lsp-client.json"),
5784
- installDecisionsPath: join11(codexHome, "lsp-install-decisions.json"),
6229
+ projectConfigPaths: [join12(canonicalCwd3, ".codex", "lsp-client.json")],
6230
+ userConfigPath: join12(codexHome, "lsp-client.json"),
6231
+ installDecisionsPath: join12(codexHome, "lsp-install-decisions.json"),
5785
6232
  capabilities: { installDecisionTool: true }
5786
6233
  });
5787
6234
  }
@@ -5875,7 +6322,7 @@ function isContextPressureTranscript(transcriptPath) {
5875
6322
  if (typeof transcriptPath !== "string")
5876
6323
  return false;
5877
6324
  try {
5878
- return hasContextPressureMarker(readFileSync9(transcriptPath, "utf8"));
6325
+ return hasContextPressureMarker(readFileSync10(transcriptPath, "utf8"));
5879
6326
  } catch (error) {
5880
6327
  if (error instanceof Error)
5881
6328
  return false;
@@ -5957,15 +6404,15 @@ main().catch((error) => {
5957
6404
  });
5958
6405
  async function runPackageLspMcpCli() {
5959
6406
  const cliPath = resolveLspDaemonCliPath();
5960
- const child = spawn3(execPath2, [cliPath, "mcp"], { stdio: "inherit" });
5961
- await new Promise((resolve10, reject) => {
6407
+ const child = spawn3(execPath2, [cliPath, "mcp"], { stdio: "inherit", windowsHide: true });
6408
+ await new Promise((resolve11, reject) => {
5962
6409
  child.once("error", reject);
5963
6410
  child.once("exit", (code, signal) => {
5964
6411
  if (code !== null && code !== 0)
5965
6412
  process.exitCode = code;
5966
6413
  if (code === null && signal !== null)
5967
6414
  process.exitCode = 1;
5968
- resolve10();
6415
+ resolve11();
5969
6416
  });
5970
6417
  });
5971
6418
  }