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
@@ -15,6 +15,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
15
15
  // ../lsp-core/src/lsp/connection.ts
16
16
  import { pathToFileURL } from "node:url";
17
17
 
18
+ // ../lsp-core/src/lsp/timer-provider.ts
19
+ var realTimerProvider = {
20
+ now: () => Date.now(),
21
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
22
+ clearTimeout: (handle) => clearTimeout(handle)
23
+ };
24
+
18
25
  // ../lsp-core/src/lsp/constants.ts
19
26
  var DEFAULT_MAX_REFERENCES = 200;
20
27
  var DEFAULT_MAX_SYMBOLS = 200;
@@ -23,28 +30,24 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
23
30
  var REQUEST_TIMEOUT_MS = 15000;
24
31
  var INIT_TIMEOUT_MS = 60000;
25
32
  var IDLE_TIMEOUT_MS = 5 * 60000;
33
+ var MAX_RESIDENT_CLIENTS = 6;
26
34
  var REAPER_INTERVAL_MS = 60000;
27
35
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
28
36
  var STOP_SIGKILL_GRACE_MS = 1000;
37
+ var CLIENT_RESPAWN_RETRY_LIMIT = 2;
38
+ var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
29
39
 
30
40
  // ../lsp-core/src/lsp/errors.ts
31
41
  class LspConnectionClosedError extends Error {
32
- serverId;
33
- root;
34
- name = "LspConnectionClosedError";
35
42
  constructor(serverId, root, message) {
36
43
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
37
44
  this.serverId = serverId;
38
45
  this.root = root;
46
+ this.name = "LspConnectionClosedError";
39
47
  }
40
48
  }
41
49
 
42
50
  class LspProcessExitedError extends Error {
43
- serverId;
44
- root;
45
- exitCode;
46
- stderrTail;
47
- name = "LspProcessExitedError";
48
51
  constructor(serverId, root, exitCode, stderrTail) {
49
52
  const stderrSuffix = stderrTail ? `
50
53
  stderr tail: ${stderrTail}` : "";
@@ -53,46 +56,59 @@ stderr tail: ${stderrTail}` : "";
53
56
  this.root = root;
54
57
  this.exitCode = exitCode;
55
58
  this.stderrTail = stderrTail;
59
+ this.name = "LspProcessExitedError";
56
60
  }
57
61
  }
58
62
 
59
63
  class LspRequestTimeoutError extends Error {
60
- method;
61
- stderrTail;
62
- name = "LspRequestTimeoutError";
63
64
  constructor(method, stderrTail) {
64
65
  const stderrSuffix = stderrTail ? `
65
66
  recent stderr: ${stderrTail}` : "";
66
67
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
67
68
  this.method = method;
68
69
  this.stderrTail = stderrTail;
70
+ this.name = "LspRequestTimeoutError";
69
71
  }
70
72
  }
71
73
 
72
74
  class LspInvalidPathError extends Error {
73
- name = "LspInvalidPathError";
75
+ constructor() {
76
+ super(...arguments);
77
+ this.name = "LspInvalidPathError";
78
+ }
74
79
  }
75
80
 
76
81
  class LspServerLookupError extends Error {
77
- lookup;
78
- name = "LspServerLookupError";
79
82
  constructor(message, lookup) {
80
83
  super(message);
81
84
  this.lookup = lookup;
85
+ this.name = "LspServerLookupError";
82
86
  }
83
87
  }
84
88
 
85
89
  class LspServerInitializingError extends Error {
86
- originalError;
87
- name = "LspServerInitializingError";
88
90
  constructor(originalError) {
89
91
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
90
92
  this.originalError = originalError;
93
+ this.name = "LspServerInitializingError";
91
94
  }
92
95
  }
93
96
 
94
97
  class LspProcessSpawnError extends Error {
95
- name = "LspProcessSpawnError";
98
+ constructor() {
99
+ super(...arguments);
100
+ this.name = "LspProcessSpawnError";
101
+ }
102
+ }
103
+
104
+ class LspClientRespawnBudgetExceededError extends Error {
105
+ constructor(serverId, root, retryLimit) {
106
+ super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
107
+ this.serverId = serverId;
108
+ this.root = root;
109
+ this.retryLimit = retryLimit;
110
+ this.name = "LspClientRespawnBudgetExceededError";
111
+ }
96
112
  }
97
113
  function isLspDeadConnectionError(err) {
98
114
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -108,20 +124,31 @@ var METHOD_NOT_FOUND = -32601;
108
124
  var INTERNAL_ERROR = -32603;
109
125
 
110
126
  class JsonRpcConnection {
111
- reader;
112
- writer;
113
- pendingRequests = new Map;
114
- notificationHandlers = new Map;
115
- requestHandlers = new Map;
116
- closeHandlers = [];
117
- errorHandlers = [];
118
- inputBuffer = Buffer.alloc(0);
119
- nextRequestId = 1;
120
- listening = false;
121
- disposed = false;
122
127
  constructor(reader, writer) {
123
128
  this.reader = reader;
124
129
  this.writer = writer;
130
+ this.pendingRequests = new Map;
131
+ this.notificationHandlers = new Map;
132
+ this.requestHandlers = new Map;
133
+ this.closeHandlers = [];
134
+ this.errorHandlers = [];
135
+ this.inputBuffer = Buffer.alloc(0);
136
+ this.nextRequestId = 1;
137
+ this.listening = false;
138
+ this.disposed = false;
139
+ this.handleData = (chunk) => {
140
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
141
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
142
+ this.drainInputBuffer();
143
+ };
144
+ this.handleClose = () => {
145
+ for (const handler of this.closeHandlers) {
146
+ handler();
147
+ }
148
+ };
149
+ this.handleStreamError = (error) => {
150
+ this.emitError(error);
151
+ };
125
152
  }
126
153
  listen() {
127
154
  if (this.listening)
@@ -242,19 +269,6 @@ class JsonRpcConnection {
242
269
  this.notificationHandlers.clear();
243
270
  this.requestHandlers.clear();
244
271
  }
245
- handleData = (chunk) => {
246
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
247
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
248
- this.drainInputBuffer();
249
- };
250
- handleClose = () => {
251
- for (const handler of this.closeHandlers) {
252
- handler();
253
- }
254
- };
255
- handleStreamError = (error) => {
256
- this.emitError(error);
257
- };
258
272
  drainInputBuffer() {
259
273
  while (true) {
260
274
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR);
@@ -602,33 +616,29 @@ function isPosition(value) {
602
616
 
603
617
  // ../lsp-core/src/lsp/transport.ts
604
618
  class LspClientNotStartedError extends Error {
605
- serverId;
606
- root;
607
- name = "LspClientNotStartedError";
608
619
  constructor(serverId, root) {
609
620
  super("LSP client not started");
610
621
  this.serverId = serverId;
611
622
  this.root = root;
623
+ this.name = "LspClientNotStartedError";
612
624
  }
613
625
  }
614
626
 
615
627
  class LspClientTransport {
616
- root;
617
- server;
618
- proc = null;
619
- connection = null;
620
- stderrBuffer = [];
621
- processExited = false;
622
- diagnosticsStore = new Map;
623
- requestTimeoutMs;
624
- initializeTimeoutMs;
625
- workspaceApplyEditHandler = null;
626
- diagnosticPullSupported = false;
627
628
  constructor(root, server, timeouts = {}) {
628
629
  this.root = root;
629
630
  this.server = server;
631
+ this.proc = null;
632
+ this.connection = null;
633
+ this.stderrBuffer = [];
634
+ this.processExited = false;
635
+ this.diagnosticsStore = new Map;
636
+ this.workspaceApplyEditHandler = null;
637
+ this.diagnosticPullSupported = false;
638
+ this.documentFormattingSupported = false;
630
639
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
631
640
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
641
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
632
642
  }
633
643
  pid() {
634
644
  return this.proc?.pid;
@@ -648,6 +658,12 @@ class LspClientTransport {
648
658
  isDiagnosticPullSupported() {
649
659
  return this.diagnosticPullSupported;
650
660
  }
661
+ setDocumentFormattingSupported(supported) {
662
+ this.documentFormattingSupported = supported;
663
+ }
664
+ isDocumentFormattingSupported() {
665
+ return this.documentFormattingSupported;
666
+ }
651
667
  handlePublishDiagnostics(params) {
652
668
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
653
669
  }
@@ -723,7 +739,7 @@ class LspClientTransport {
723
739
  const options = args[1];
724
740
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
725
741
  const timeoutController = new AbortController;
726
- const timeoutHandle = setTimeout(() => {
742
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
727
743
  const stderrTail = this.stderrBuffer.slice(-5).join(`
728
744
  `);
729
745
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -742,7 +758,7 @@ class LspClientTransport {
742
758
  }
743
759
  throw error;
744
760
  } finally {
745
- clearTimeout(timeoutHandle);
761
+ this.timerProvider.clearTimeout(timeoutHandle);
746
762
  combinedSignal.dispose();
747
763
  }
748
764
  }
@@ -861,6 +877,14 @@ function supportsDiagnosticPull(capabilities) {
861
877
  return false;
862
878
  return Object.hasOwn(capabilities, "diagnosticProvider");
863
879
  }
880
+ function supportsDocumentFormatting(capabilities) {
881
+ if (capabilities === undefined)
882
+ return false;
883
+ const provider = capabilities.documentFormattingProvider;
884
+ if (provider === undefined || provider === null || provider === false)
885
+ return false;
886
+ return provider === true || typeof provider === "object";
887
+ }
864
888
 
865
889
  class LspClientConnection extends LspClientTransport {
866
890
  async initialize() {
@@ -877,6 +901,7 @@ class LspClientConnection extends LspClientTransport {
877
901
  references: {},
878
902
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
879
903
  publishDiagnostics: {},
904
+ formatting: { dynamicRegistration: false },
880
905
  rename: {
881
906
  prepareSupport: true,
882
907
  prepareSupportDefaultBehavior: 1
@@ -918,6 +943,7 @@ class LspClientConnection extends LspClientTransport {
918
943
  initializationOptions: this.server.initialization
919
944
  }, { timeoutMs: this.initializeTimeoutMs });
920
945
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
946
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
921
947
  await this.sendNotification("initialized", {});
922
948
  await this.sendNotification("workspace/didChangeConfiguration", {
923
949
  settings: { json: { validate: { enable: true } } }
@@ -1123,6 +1149,17 @@ function canonicalPath(filePath) {
1123
1149
  return absolute;
1124
1150
  }
1125
1151
  }
1152
+ function normalizeDocumentUri(uri) {
1153
+ let decoded = uri;
1154
+ try {
1155
+ decoded = decodeURIComponent(uri);
1156
+ } catch {
1157
+ decoded = uri;
1158
+ }
1159
+ if (process.platform !== "win32")
1160
+ return decoded;
1161
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1162
+ }
1126
1163
  function isSameOrDescendant(candidate, parent) {
1127
1164
  const suffix = relative(parent, candidate);
1128
1165
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1133,17 +1170,18 @@ function movedPath(candidate, oldPath, newPath) {
1133
1170
  }
1134
1171
 
1135
1172
  class WorkspaceDocumentState {
1136
- sendNotification;
1137
- clearDiagnostics;
1138
- openDocuments = new Map;
1139
- openByUri = new Map;
1140
- openPromises = new Map;
1141
- now;
1142
- versionlessPublishQuiescenceMs;
1143
1173
  constructor(sendNotification, clearDiagnostics, options = {}) {
1144
1174
  this.sendNotification = sendNotification;
1145
1175
  this.clearDiagnostics = clearDiagnostics;
1146
- this.now = options.now ?? (() => Date.now());
1176
+ this.openDocuments = new Map;
1177
+ this.openByUri = new Map;
1178
+ this.openPromises = new Map;
1179
+ this.timerProvider = options.timerProvider ?? {
1180
+ now: options.now ?? (() => Date.now()),
1181
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1182
+ clearTimeout: (handle) => clearTimeout(handle)
1183
+ };
1184
+ this.now = () => this.timerProvider.now();
1147
1185
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1148
1186
  }
1149
1187
  async openFile(filePath) {
@@ -1165,7 +1203,7 @@ class WorkspaceDocumentState {
1165
1203
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1166
1204
  }
1167
1205
  getStoredDiagnostics(uri) {
1168
- const state = this.openByUri.get(uri);
1206
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1169
1207
  if (!state)
1170
1208
  return [];
1171
1209
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1187,13 +1225,13 @@ class WorkspaceDocumentState {
1187
1225
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1188
1226
  }
1189
1227
  getPullCache(snapshot) {
1190
- const state = this.openByUri.get(snapshot.uri);
1228
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1191
1229
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1192
1230
  return null;
1193
1231
  return state.pullCache;
1194
1232
  }
1195
1233
  recordPullDiagnostics(snapshot, report) {
1196
- const state = this.openByUri.get(snapshot.uri);
1234
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1197
1235
  if (!state)
1198
1236
  return;
1199
1237
  state.pullCache = {
@@ -1203,7 +1241,7 @@ class WorkspaceDocumentState {
1203
1241
  };
1204
1242
  }
1205
1243
  recordPublishedDiagnostics(params) {
1206
- const state = this.openByUri.get(params.uri);
1244
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1207
1245
  if (!state)
1208
1246
  return;
1209
1247
  state.publishGeneration += 1;
@@ -1217,7 +1255,7 @@ class WorkspaceDocumentState {
1217
1255
  this.notifyWaiters(state);
1218
1256
  }
1219
1257
  resolvePushDiagnostics(snapshot) {
1220
- const state = this.openByUri.get(snapshot.uri);
1258
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1221
1259
  if (!state?.lastPublish)
1222
1260
  return { status: "missing" };
1223
1261
  const publish = state.lastPublish;
@@ -1231,7 +1269,7 @@ class WorkspaceDocumentState {
1231
1269
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1232
1270
  }
1233
1271
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1234
- const state = this.openByUri.get(snapshot.uri);
1272
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1235
1273
  if (!state || timeoutMs <= 0)
1236
1274
  return Promise.resolve();
1237
1275
  return new Promise((resolveActivity) => {
@@ -1240,11 +1278,11 @@ class WorkspaceDocumentState {
1240
1278
  if (settled)
1241
1279
  return;
1242
1280
  settled = true;
1243
- clearTimeout(timer);
1281
+ this.timerProvider.clearTimeout(timer);
1244
1282
  state.waiters.delete(finish);
1245
1283
  resolveActivity();
1246
1284
  };
1247
- const timer = setTimeout(finish, timeoutMs);
1285
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1248
1286
  if (typeof timer.unref === "function")
1249
1287
  timer.unref();
1250
1288
  state.waiters.add(finish);
@@ -1352,7 +1390,7 @@ class WorkspaceDocumentState {
1352
1390
  waiters: new Set
1353
1391
  };
1354
1392
  this.openDocuments.set(path, state);
1355
- this.openByUri.set(state.uri, state);
1393
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
1356
1394
  this.notifyWaiters(state);
1357
1395
  await this.sendNotification("textDocument/didOpen", {
1358
1396
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -1377,7 +1415,7 @@ class WorkspaceDocumentState {
1377
1415
  }
1378
1416
  async closeDocument(state) {
1379
1417
  this.openDocuments.delete(state.path);
1380
- this.openByUri.delete(state.uri);
1418
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
1381
1419
  this.clearDiagnostics(state.uri);
1382
1420
  this.notifyWaiters(state);
1383
1421
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -1406,13 +1444,11 @@ import { dirname, isAbsolute, relative as relative2, resolve as resolve2 } from
1406
1444
  import { fileURLToPath } from "node:url";
1407
1445
 
1408
1446
  class WorkspaceEditPathError extends Error {
1409
- path;
1410
- detail;
1411
- name = "WorkspaceEditPathError";
1412
1447
  constructor(path, detail) {
1413
1448
  super(`${detail}: ${path}`);
1414
1449
  this.path = path;
1415
1450
  this.detail = detail;
1451
+ this.name = "WorkspaceEditPathError";
1416
1452
  }
1417
1453
  }
1418
1454
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -1704,13 +1740,11 @@ function canonicalFingerprint(operations) {
1704
1740
 
1705
1741
  // ../lsp-core/src/lsp/workspace-edit-types.ts
1706
1742
  class WorkspaceEditValidationError extends Error {
1707
- changeIndex;
1708
- detail;
1709
- name = "WorkspaceEditValidationError";
1710
1743
  constructor(changeIndex, detail) {
1711
1744
  super(`change ${changeIndex}: ${detail}`);
1712
1745
  this.changeIndex = changeIndex;
1713
1746
  this.detail = detail;
1747
+ this.name = "WorkspaceEditValidationError";
1714
1748
  }
1715
1749
  }
1716
1750
 
@@ -2208,10 +2242,9 @@ function simulateDelete(operation, virtual) {
2208
2242
  import { existsSync as existsSync4, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
2209
2243
  import { dirname as dirname3, resolve as resolve4 } from "node:path";
2210
2244
  class WorkspaceSnapshotBuilder {
2211
- workspaceRoot;
2212
- snapshots = new Map;
2213
2245
  constructor(workspaceRoot) {
2214
2246
  this.workspaceRoot = workspaceRoot;
2247
+ this.snapshots = new Map;
2215
2248
  }
2216
2249
  build(operations) {
2217
2250
  this.add(this.workspaceRoot, false);
@@ -2255,8 +2288,10 @@ function snapshotOperations(operations, workspaceRoot) {
2255
2288
 
2256
2289
  // ../lsp-core/src/lsp/workspace-edit-plan.ts
2257
2290
  class PlanPathIndex {
2258
- firstChangeByPath = new Map;
2259
- reportedPathByCanonical = new Map;
2291
+ constructor() {
2292
+ this.firstChangeByPath = new Map;
2293
+ this.reportedPathByCanonical = new Map;
2294
+ }
2260
2295
  build(operations) {
2261
2296
  for (const operation of operations) {
2262
2297
  switch (operation.kind) {
@@ -2345,14 +2380,11 @@ function isRecord3(value) {
2345
2380
  }
2346
2381
 
2347
2382
  class WorkspaceMutationController {
2348
- workspaceRoot;
2349
- documents;
2350
- activeLease = null;
2351
- nextLeaseId = 1;
2352
- io;
2353
2383
  constructor(workspaceRoot, documents) {
2354
2384
  this.workspaceRoot = workspaceRoot;
2355
2385
  this.documents = documents;
2386
+ this.activeLease = null;
2387
+ this.nextLeaseId = 1;
2356
2388
  }
2357
2389
  setIo(io) {
2358
2390
  this.io = io;
@@ -2465,14 +2497,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
2465
2497
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
2466
2498
 
2467
2499
  class LspClient extends LspClientConnection {
2468
- diagnosticPullErrors = [];
2469
- documents;
2470
- workspaceMutations;
2471
- diagnosticsFreshnessTimeoutMs;
2472
2500
  constructor(root, server, options = {}) {
2473
2501
  super(root, server, options);
2502
+ this.diagnosticPullErrors = [];
2474
2503
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2475
2504
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
2505
+ timerProvider: this.timerProvider,
2476
2506
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
2477
2507
  });
2478
2508
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -2525,6 +2555,18 @@ class LspClient extends LspClientConnection {
2525
2555
  textDocument: { uri: pathToFileURL3(absPath).href }
2526
2556
  }, options);
2527
2557
  }
2558
+ async formatDocument(filePath, options, signal) {
2559
+ if (!this.isDocumentFormattingSupported())
2560
+ return null;
2561
+ const absPath = this.resolveWorkspacePath(filePath);
2562
+ await this.openFile(absPath);
2563
+ const requestOptions = signal === undefined ? {} : { signal };
2564
+ const edits = await this.sendRequest("textDocument/formatting", {
2565
+ textDocument: { uri: pathToFileURL3(absPath).href },
2566
+ options
2567
+ }, requestOptions);
2568
+ return edits ?? [];
2569
+ }
2528
2570
  async workspaceSymbols(query, signal) {
2529
2571
  const options = signal === undefined ? {} : { signal };
2530
2572
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -2564,7 +2606,7 @@ class LspClient extends LspClientConnection {
2564
2606
  const absPath = this.resolveWorkspacePath(filePath);
2565
2607
  const uri = pathToFileURL3(absPath).href;
2566
2608
  await this.openFile(absPath);
2567
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
2609
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
2568
2610
  for (;; ) {
2569
2611
  signal?.throwIfAborted();
2570
2612
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -2577,7 +2619,7 @@ class LspClient extends LspClientConnection {
2577
2619
  if (!pushFallbackOnly) {
2578
2620
  const cached = this.documents.getPullCache(snapshot);
2579
2621
  try {
2580
- const remainingMs2 = deadlineAt - Date.now();
2622
+ const remainingMs2 = deadlineAt - this.timerProvider.now();
2581
2623
  if (remainingMs2 <= 0)
2582
2624
  return this.freshnessTimeout(absPath);
2583
2625
  const result = await this.sendRequest("textDocument/diagnostic", {
@@ -2612,7 +2654,7 @@ class LspClient extends LspClientConnection {
2612
2654
  }
2613
2655
  if (!pushFallbackOnly)
2614
2656
  continue;
2615
- const remainingMs = deadlineAt - Date.now();
2657
+ const remainingMs = deadlineAt - this.timerProvider.now();
2616
2658
  if (remainingMs <= 0) {
2617
2659
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
2618
2660
  const cached = this.documents.getPullCache(snapshot);
@@ -2770,18 +2812,16 @@ function awaitWithSignal(promise, signal) {
2770
2812
  }
2771
2813
 
2772
2814
  class LspManager {
2773
- clients = new Map;
2774
- reaperHandle = null;
2775
- signalDisposer = null;
2776
- disposed = false;
2777
- idleTimeoutMs;
2778
- initTimeoutMs;
2779
- reaperIntervalMs;
2780
- clientFactory;
2781
- now;
2782
2815
  constructor(options = {}) {
2816
+ this.clients = new Map;
2817
+ this.pendingStops = new Map;
2818
+ this.respawnBudgets = new Map;
2819
+ this.reaperHandle = null;
2820
+ this.signalDisposer = null;
2821
+ this.disposed = false;
2783
2822
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
2784
2823
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
2824
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
2785
2825
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
2786
2826
  this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
2787
2827
  this.now = options.now ?? (() => Date.now());
@@ -2801,24 +2841,79 @@ class LspManager {
2801
2841
  getKey(root, serverId) {
2802
2842
  return `${root}::${serverId}`;
2803
2843
  }
2844
+ tombstoneStop(key, client) {
2845
+ const stop = stopClientBestEffort(client);
2846
+ this.pendingStops.set(key, stop);
2847
+ stop.finally(() => {
2848
+ if (this.pendingStops.get(key) === stop) {
2849
+ this.pendingStops.delete(key);
2850
+ }
2851
+ });
2852
+ return stop;
2853
+ }
2854
+ recordDeadGeneration(key) {
2855
+ let budget = this.respawnBudgets.get(key);
2856
+ if (budget === undefined) {
2857
+ budget = { deadGenerations: 0, exhaustedAt: null };
2858
+ this.respawnBudgets.set(key, budget);
2859
+ }
2860
+ budget.deadGenerations += 1;
2861
+ }
2862
+ markHealthyGeneration(key) {
2863
+ this.respawnBudgets.delete(key);
2864
+ }
2865
+ ensureRespawnAllowed(key, root, serverId) {
2866
+ const budget = this.respawnBudgets.get(key);
2867
+ if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
2868
+ return;
2869
+ if (budget.exhaustedAt === null) {
2870
+ budget.exhaustedAt = this.now();
2871
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
2872
+ }
2873
+ if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
2874
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
2875
+ }
2876
+ budget.deadGenerations = 0;
2877
+ budget.exhaustedAt = null;
2878
+ }
2804
2879
  reapStale() {
2805
2880
  const t = this.now();
2806
2881
  for (const [key, managed] of this.clients) {
2807
2882
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
2808
- stopClientBestEffort(managed.client);
2809
2883
  this.clients.delete(key);
2884
+ this.tombstoneStop(key, managed.client);
2810
2885
  continue;
2811
2886
  }
2812
2887
  if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
2813
- stopClientBestEffort(managed.client);
2814
2888
  this.clients.delete(key);
2889
+ this.tombstoneStop(key, managed.client);
2890
+ }
2891
+ }
2892
+ }
2893
+ evictForAdmission() {
2894
+ while (this.clients.size >= this.maxResidentClients) {
2895
+ const victim = this.leastRecentlyUsedIdleClient();
2896
+ if (!victim)
2897
+ return;
2898
+ this.clients.delete(victim.key);
2899
+ this.tombstoneStop(victim.key, victim.managed.client);
2900
+ }
2901
+ }
2902
+ leastRecentlyUsedIdleClient() {
2903
+ let candidate = null;
2904
+ for (const [key, managed] of this.clients) {
2905
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
2906
+ continue;
2907
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
2908
+ candidate = { key, managed };
2815
2909
  }
2816
2910
  }
2911
+ return candidate;
2817
2912
  }
2818
2913
  async tryDeleteIfOrphaned(key, managed) {
2819
2914
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
2820
2915
  this.clients.delete(key);
2821
- await stopClientBestEffort(managed.client);
2916
+ await this.tombstoneStop(key, managed.client);
2822
2917
  }
2823
2918
  }
2824
2919
  async getClient(root, server, signal) {
@@ -2827,12 +2922,22 @@ class LspManager {
2827
2922
  }
2828
2923
  signal?.throwIfAborted();
2829
2924
  const key = this.getKey(root, server.id);
2925
+ for (;; ) {
2926
+ const pendingStop = this.pendingStops.get(key);
2927
+ if (pendingStop === undefined)
2928
+ break;
2929
+ await awaitWithSignal(pendingStop, signal);
2930
+ signal?.throwIfAborted();
2931
+ }
2932
+ if (this.disposed) {
2933
+ throw new Error("LspManager has been disposed");
2934
+ }
2830
2935
  let managed = this.clients.get(key);
2831
2936
  if (managed) {
2832
2937
  const t = this.now();
2833
2938
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
2834
- await stopClientBestEffort(managed.client);
2835
2939
  this.clients.delete(key);
2940
+ await this.tombstoneStop(key, managed.client);
2836
2941
  managed = undefined;
2837
2942
  }
2838
2943
  }
@@ -2853,14 +2958,20 @@ class LspManager {
2853
2958
  signal.throwIfAborted();
2854
2959
  }
2855
2960
  if (!managed.client.isAlive()) {
2856
- await stopClientBestEffort(managed.client);
2857
- this.clients.delete(key);
2961
+ this.recordDeadGeneration(key);
2962
+ if (this.clients.get(key) === managed) {
2963
+ this.clients.delete(key);
2964
+ }
2965
+ await this.tombstoneStop(key, managed.client);
2858
2966
  return this.getClient(root, server, signal);
2859
2967
  }
2968
+ this.markHealthyGeneration(key);
2860
2969
  managed.refCount++;
2861
2970
  managed.lastUsedAt = this.now();
2862
2971
  return managed.client;
2863
2972
  }
2973
+ this.evictForAdmission();
2974
+ this.ensureRespawnAllowed(key, root, server.id);
2864
2975
  const client = this.clientFactory(root, server);
2865
2976
  const initStartedAt = this.now();
2866
2977
  const initPromise = (async () => {
@@ -2884,7 +2995,7 @@ class LspManager {
2884
2995
  if (this.clients.get(key) === newManaged) {
2885
2996
  this.clients.delete(key);
2886
2997
  }
2887
- await stopClientBestEffort(client);
2998
+ await this.tombstoneStop(key, client);
2888
2999
  throw err;
2889
3000
  }
2890
3001
  newManaged.pendingWaiters--;
@@ -2895,6 +3006,15 @@ class LspManager {
2895
3006
  await this.tryDeleteIfOrphaned(key, newManaged);
2896
3007
  signal.throwIfAborted();
2897
3008
  }
3009
+ if (!client.isAlive()) {
3010
+ this.recordDeadGeneration(key);
3011
+ if (this.clients.get(key) === newManaged) {
3012
+ this.clients.delete(key);
3013
+ }
3014
+ await this.tombstoneStop(key, client);
3015
+ return this.getClient(root, server, signal);
3016
+ }
3017
+ this.markHealthyGeneration(key);
2898
3018
  newManaged.refCount++;
2899
3019
  newManaged.lastUsedAt = this.now();
2900
3020
  return client;
@@ -2915,14 +3035,20 @@ class LspManager {
2915
3035
  if (client && managed.client !== client)
2916
3036
  return;
2917
3037
  this.clients.delete(key);
2918
- stopClientBestEffort(managed.client);
3038
+ this.tombstoneStop(key, managed.client);
2919
3039
  }
2920
3040
  warmupClient(root, server) {
2921
3041
  if (this.disposed)
2922
3042
  return;
2923
3043
  const key = this.getKey(root, server.id);
2924
- if (this.clients.has(key))
3044
+ if (this.clients.has(key) || this.pendingStops.has(key))
2925
3045
  return;
3046
+ this.evictForAdmission();
3047
+ try {
3048
+ this.ensureRespawnAllowed(key, root, server.id);
3049
+ } catch {
3050
+ return;
3051
+ }
2926
3052
  const client = this.clientFactory(root, server);
2927
3053
  const initStartedAt = this.now();
2928
3054
  const initPromise = (async () => {
@@ -2948,7 +3074,7 @@ class LspManager {
2948
3074
  if (this.clients.get(key) === managed) {
2949
3075
  this.clients.delete(key);
2950
3076
  }
2951
- stopClientBestEffort(client);
3077
+ this.tombstoneStop(key, client);
2952
3078
  });
2953
3079
  }
2954
3080
  isServerInitializing(root, serverId) {
@@ -2992,8 +3118,11 @@ class LspManager {
2992
3118
  for (const managed of this.clients.values()) {
2993
3119
  stopPromises.push(stopClientBestEffort(managed.client));
2994
3120
  }
3121
+ const tombstonedStops = [...this.pendingStops.values()];
2995
3122
  this.clients.clear();
2996
- await Promise.allSettled(stopPromises);
3123
+ this.respawnBudgets.clear();
3124
+ await Promise.allSettled([...stopPromises, ...tombstonedStops]);
3125
+ this.pendingStops.clear();
2997
3126
  }
2998
3127
  }
2999
3128
  var _defaultInstance = null;
@@ -3013,7 +3142,7 @@ async function disposeDefaultLspManager() {
3013
3142
  // src/daemon-client.ts
3014
3143
  import { connect } from "node:net";
3015
3144
  import { homedir as homedir3 } from "node:os";
3016
- import { join as join7 } from "node:path";
3145
+ import { join as join8 } from "node:path";
3017
3146
 
3018
3147
  // ../lsp-core/src/request-context.ts
3019
3148
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -3022,18 +3151,17 @@ import { homedir } from "node:os";
3022
3151
  import { basename as basename2, delimiter as delimiter2, dirname as dirname4, isAbsolute as isAbsolute2, join as join2, relative as relative4, resolve as resolve6 } from "node:path";
3023
3152
 
3024
3153
  class LspRequestContextParseError extends Error {
3025
- code;
3026
- name = "LspRequestContextParseError";
3027
3154
  constructor(code, message) {
3028
3155
  super(message);
3029
3156
  this.code = code;
3157
+ this.name = "LspRequestContextParseError";
3030
3158
  }
3031
3159
  }
3032
3160
 
3033
3161
  class LspRequestContextUnavailableError extends Error {
3034
- name = "LspRequestContextUnavailableError";
3035
3162
  constructor() {
3036
3163
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
3164
+ this.name = "LspRequestContextUnavailableError";
3037
3165
  }
3038
3166
  }
3039
3167
  var storage = new AsyncLocalStorage;
@@ -3053,7 +3181,7 @@ function contextCwd() {
3053
3181
  }
3054
3182
  function createStandaloneMcpRequestContext(input = {}) {
3055
3183
  const env = input.env ?? process.env;
3056
- const cwd = canonicalCwd(input.cwd ?? process.cwd());
3184
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
3057
3185
  const home = input.homeDir ?? homedir();
3058
3186
  const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
3059
3187
  const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
@@ -3191,7 +3319,6 @@ function isPlainRecord(value) {
3191
3319
 
3192
3320
  // src/daemon-request-error.ts
3193
3321
  class DaemonRequestError extends Error {
3194
- requestWritten;
3195
3322
  constructor(message, requestWritten) {
3196
3323
  super(message);
3197
3324
  this.name = "DaemonRequestError";
@@ -3214,7 +3341,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
3214
3341
  }
3215
3342
 
3216
3343
  class DaemonRequestTimedOutError extends DaemonRequestError {
3217
- timeoutMs;
3218
3344
  constructor(requestWritten, timeoutMs) {
3219
3345
  super("daemon request timed out", requestWritten);
3220
3346
  this.name = "DaemonRequestTimedOutError";
@@ -3293,14 +3419,12 @@ var PROTOCOL_ERROR_CODE = -32002;
3293
3419
  var AUTH_TOKEN_BYTES = 32;
3294
3420
 
3295
3421
  class UnsafePrivateDirectoryError extends Error {
3296
- path;
3297
- reason;
3298
- name = "UnsafePrivateDirectoryError";
3299
- code = "unsafe_private_directory";
3300
3422
  constructor(path, reason) {
3301
3423
  super(`unsafe private directory ${path}: ${reason}`);
3302
3424
  this.path = path;
3303
3425
  this.reason = reason;
3426
+ this.name = "UnsafePrivateDirectoryError";
3427
+ this.code = "unsafe_private_directory";
3304
3428
  }
3305
3429
  }
3306
3430
  function authEnvelope(token) {
@@ -3484,20 +3608,18 @@ var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
3484
3608
  var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
3485
3609
 
3486
3610
  class InvalidRuntimeOverrideError extends Error {
3487
- code = "invalid_runtime_override";
3488
- reason;
3489
3611
  constructor(reason, message) {
3490
3612
  super(message);
3613
+ this.code = "invalid_runtime_override";
3491
3614
  this.name = "InvalidRuntimeOverrideError";
3492
3615
  this.reason = reason;
3493
3616
  }
3494
3617
  }
3495
3618
 
3496
3619
  class InvalidDaemonVersionError extends Error {
3497
- code = "invalid_daemon_version";
3498
- version;
3499
3620
  constructor(version) {
3500
3621
  super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
3622
+ this.code = "invalid_daemon_version";
3501
3623
  this.name = "InvalidDaemonVersionError";
3502
3624
  this.version = version;
3503
3625
  }
@@ -3543,10 +3665,9 @@ var requireFromHere = createRequire(import.meta.url);
3543
3665
  var MAX_SOCKET_PATH_LENGTH = 100;
3544
3666
 
3545
3667
  class InvalidDaemonDirectoryError extends Error {
3546
- code = "invalid_daemon_directory";
3547
- directory;
3548
3668
  constructor(directory) {
3549
3669
  super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
3670
+ this.code = "invalid_daemon_directory";
3550
3671
  this.name = "InvalidDaemonDirectoryError";
3551
3672
  this.directory = directory;
3552
3673
  }
@@ -3741,7 +3862,8 @@ function spawnDaemonProcess(paths) {
3741
3862
  try {
3742
3863
  const child = spawn2(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
3743
3864
  detached: true,
3744
- stdio: ["ignore", logFd, logFd]
3865
+ stdio: ["ignore", logFd, logFd],
3866
+ windowsHide: true
3745
3867
  });
3746
3868
  child.once("spawn", () => closeSync2(logFd));
3747
3869
  child.once("error", (error) => {
@@ -4022,6 +4144,7 @@ async function runJsonRpcStdioServer(config) {
4022
4144
  const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
4023
4145
  isClosed = true;
4024
4146
  config.onIdleTimeout?.();
4147
+ config.input.destroy();
4025
4148
  });
4026
4149
  const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
4027
4150
  isClosed = true;
@@ -4118,7 +4241,11 @@ function createParentWatchdog(config, onDeadParent) {
4118
4241
  const probeAlive = config.probeAlive ?? isProcessAlive;
4119
4242
  let fired = false;
4120
4243
  const timer = setInterval(() => {
4121
- if (fired || probeAlive(parentPid))
4244
+ if (fired)
4245
+ return;
4246
+ const alive = probeAlive(parentPid);
4247
+ config.onPoll?.(alive);
4248
+ if (alive)
4122
4249
  return;
4123
4250
  fired = true;
4124
4251
  onDeadParent(parentPid, pollIntervalMs);
@@ -4153,60 +4280,55 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
4153
4280
  };
4154
4281
  }
4155
4282
  // ../lsp-core/src/lsp/client-wrapper.ts
4156
- import { existsSync as existsSync10, statSync as statSync4 } from "node:fs";
4157
- import { dirname as dirname8, join as join4, resolve as resolve7 } from "node:path";
4283
+ import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync4 } from "node:fs";
4284
+ import { basename as basename3, dirname as dirname10, join as join5, resolve as resolve8 } from "node:path";
4158
4285
 
4159
- // ../lsp-core/src/lsp/server-install-state.ts
4160
- import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
4161
- import { dirname as dirname7 } from "node:path";
4162
- function getInstallDecisionsPath() {
4163
- return lspRequestContext().installDecisionsPath;
4164
- }
4165
- function loadInstallDecisions() {
4166
- const path2 = getInstallDecisionsPath();
4167
- if (!existsSync7(path2))
4168
- return {};
4169
- try {
4170
- const parsed = JSON.parse(readFileSync4(path2, "utf8"));
4171
- return isInstallDecisions(parsed) ? parsed : {};
4172
- } catch {
4173
- return {};
4286
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
4287
+ import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
4288
+ import { dirname as dirname7, join as join3 } from "node:path";
4289
+
4290
+ // ../lsp-core/src/lsp/workspace-markers.ts
4291
+ var GIT_WORKSPACE_MARKER = ".git";
4292
+ var PROJECT_WORKSPACE_MARKERS = [
4293
+ "package.json",
4294
+ "pyproject.toml",
4295
+ "Cargo.toml",
4296
+ "go.mod",
4297
+ "pom.xml",
4298
+ "build.gradle"
4299
+ ];
4300
+ var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
4301
+
4302
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
4303
+ function findWorkspaceRootOutsideContext(directory) {
4304
+ const marked = nearestMarkedAncestor(directory);
4305
+ if (marked !== undefined)
4306
+ return marked;
4307
+ return realpathSync4(nearestExistingAncestor(directory));
4308
+ }
4309
+ function nearestMarkedAncestor(directory) {
4310
+ let current = directory;
4311
+ for (;; ) {
4312
+ if (existsSync7(current) && WORKSPACE_MARKERS.some((marker) => existsSync7(join3(current, marker)))) {
4313
+ return realpathSync4(current);
4314
+ }
4315
+ const parent = dirname7(current);
4316
+ if (parent === current)
4317
+ return;
4318
+ current = parent;
4174
4319
  }
4175
4320
  }
4176
- function loadInstallDecision(serverId) {
4177
- return loadInstallDecisions()[serverId];
4178
- }
4179
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
4180
- const decisions = loadInstallDecisions();
4181
- decisions[serverId] = { decision, decidedAt };
4182
- writeInstallDecisions(decisions);
4183
- }
4184
- function isInstallDecision(value) {
4185
- return value === "declined" || value === "allowed";
4186
- }
4187
- function writeInstallDecisions(decisions) {
4188
- const path2 = getInstallDecisionsPath();
4189
- mkdirSync3(dirname7(path2), { recursive: true });
4190
- const tmpPath = `${path2}.tmp`;
4191
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
4192
- `, "utf8");
4193
- renameSync2(tmpPath, path2);
4194
- }
4195
- function isInstallDecisions(value) {
4196
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
4197
- }
4198
- function isInstallDecisionRecord(value) {
4199
- if (!isRecord5(value))
4200
- return false;
4201
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
4202
- }
4203
- function isRecord5(value) {
4204
- return typeof value === "object" && value !== null && !Array.isArray(value);
4321
+ function nearestExistingAncestor(directory) {
4322
+ let current = directory;
4323
+ while (!existsSync7(current)) {
4324
+ const parent = dirname7(current);
4325
+ if (parent === current)
4326
+ return current;
4327
+ current = parent;
4328
+ }
4329
+ return current;
4205
4330
  }
4206
4331
 
4207
- // ../lsp-core/src/lsp/config-loader.ts
4208
- import { existsSync as existsSync8, readFileSync as readFileSync5 } from "node:fs";
4209
-
4210
4332
  // ../lsp-core/src/lsp/server-definitions.ts
4211
4333
  var LSP_INSTALL_HINTS = {
4212
4334
  typescript: "npm install -g typescript-language-server typescript",
@@ -4252,6 +4374,26 @@ var LSP_INSTALL_HINTS = {
4252
4374
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
4253
4375
  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"
4254
4376
  };
4377
+ var LSP_LOCAL_INSTALL_HINTS = {
4378
+ typescript: "bun add -d typescript-language-server typescript",
4379
+ vue: "bun add -d @vue/language-server",
4380
+ eslint: "bun add -d vscode-langservers-extracted",
4381
+ oxlint: "bun add -d oxlint",
4382
+ biome: "bun add -d @biomejs/biome",
4383
+ svelte: "bun add -d svelte-language-server",
4384
+ astro: "bun add -d @astrojs/language-server",
4385
+ bash: "bun add -d bash-language-server",
4386
+ "bash-ls": "bun add -d bash-language-server",
4387
+ "yaml-ls": "bun add -d yaml-language-server",
4388
+ php: "bun add -d intelephense",
4389
+ prisma: "bun add -d prisma",
4390
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
4391
+ pyright: "uv add --dev pyright",
4392
+ basedpyright: "uv add --dev basedpyright",
4393
+ ruff: "uv add --dev ruff",
4394
+ ty: "uv add --dev ty",
4395
+ "ruby-lsp": "bundle add ruby-lsp --group development"
4396
+ };
4255
4397
  var BUILTIN_SERVERS = {
4256
4398
  typescript: {
4257
4399
  command: ["typescript-language-server", "--stdio"],
@@ -4354,7 +4496,56 @@ var BUILTIN_SERVERS = {
4354
4496
  }
4355
4497
  };
4356
4498
 
4499
+ // ../lsp-core/src/lsp/server-install-state.ts
4500
+ import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
4501
+ import { dirname as dirname8 } from "node:path";
4502
+ function getInstallDecisionsPath() {
4503
+ return lspRequestContext().installDecisionsPath;
4504
+ }
4505
+ function loadInstallDecisions() {
4506
+ const path2 = getInstallDecisionsPath();
4507
+ if (!existsSync8(path2))
4508
+ return {};
4509
+ try {
4510
+ const parsed = JSON.parse(readFileSync4(path2, "utf8"));
4511
+ return isInstallDecisions(parsed) ? parsed : {};
4512
+ } catch {
4513
+ return {};
4514
+ }
4515
+ }
4516
+ function loadInstallDecision(serverId) {
4517
+ return loadInstallDecisions()[serverId];
4518
+ }
4519
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
4520
+ const decisions = loadInstallDecisions();
4521
+ decisions[serverId] = { decision, decidedAt };
4522
+ writeInstallDecisions(decisions);
4523
+ }
4524
+ function isInstallDecision(value) {
4525
+ return value === "declined" || value === "allowed";
4526
+ }
4527
+ function writeInstallDecisions(decisions) {
4528
+ const path2 = getInstallDecisionsPath();
4529
+ mkdirSync3(dirname8(path2), { recursive: true });
4530
+ const tmpPath = `${path2}.tmp`;
4531
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
4532
+ `, "utf8");
4533
+ renameSync2(tmpPath, path2);
4534
+ }
4535
+ function isInstallDecisions(value) {
4536
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
4537
+ }
4538
+ function isInstallDecisionRecord(value) {
4539
+ if (!isRecord5(value))
4540
+ return false;
4541
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
4542
+ }
4543
+ function isRecord5(value) {
4544
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4545
+ }
4546
+
4357
4547
  // ../lsp-core/src/lsp/config-loader.ts
4548
+ import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
4358
4549
  function getProjectConfigPaths() {
4359
4550
  return lspRequestContext().projectConfigPaths;
4360
4551
  }
@@ -4362,7 +4553,7 @@ function getUserConfigPath() {
4362
4553
  return lspRequestContext().userConfigPath;
4363
4554
  }
4364
4555
  function loadJsonFile(path2) {
4365
- if (!existsSync8(path2))
4556
+ if (!existsSync9(path2))
4366
4557
  return null;
4367
4558
  try {
4368
4559
  const parsed = JSON.parse(readFileSync5(path2, "utf-8"));
@@ -4550,54 +4741,155 @@ function getDisabledServerIds() {
4550
4741
  }
4551
4742
 
4552
4743
  // ../lsp-core/src/lsp/server-installation.ts
4553
- import { existsSync as existsSync9 } from "node:fs";
4554
- import { delimiter as delimiter3, join as join3 } from "node:path";
4555
- function isServerInstalled(command, _workingDirectory) {
4556
- if (command.length === 0)
4557
- return false;
4558
- const [cmd] = command;
4559
- if (!cmd)
4560
- return false;
4561
- if (cmd.includes("/") || cmd.includes("\\")) {
4562
- if (existsSync9(cmd))
4563
- return true;
4744
+ import { existsSync as existsSync10 } from "node:fs";
4745
+ import { delimiter as delimiter3, dirname as dirname9, isAbsolute as isAbsolute5, join as join4, resolve as resolve7 } from "node:path";
4746
+ var LOCAL_BIN_RULES = [
4747
+ {
4748
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
4749
+ binDirs: [join4("node_modules", ".bin")]
4750
+ },
4751
+ {
4752
+ markers: [
4753
+ "pyproject.toml",
4754
+ "ty.toml",
4755
+ "requirements.txt",
4756
+ "setup.py",
4757
+ "setup.cfg",
4758
+ "Pipfile",
4759
+ "pyrightconfig.json",
4760
+ "ruff.toml",
4761
+ ".ruff.toml"
4762
+ ],
4763
+ binDirs: [
4764
+ join4(".venv", "bin"),
4765
+ join4(".venv", "Scripts"),
4766
+ join4("venv", "bin"),
4767
+ join4("venv", "Scripts"),
4768
+ join4(".env", "bin"),
4769
+ join4(".env", "Scripts")
4770
+ ]
4771
+ },
4772
+ {
4773
+ markers: ["Gemfile", "Gemfile.lock"],
4774
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4775
+ },
4776
+ {
4777
+ markers: ["go.mod", "go.sum", "go.work"],
4778
+ binDirs: ["bin"]
4779
+ }
4780
+ ];
4781
+ var resolutionCache = new Map;
4782
+ var probeCount = 0;
4783
+ function probe(path2) {
4784
+ probeCount += 1;
4785
+ return existsSync10(path2);
4786
+ }
4787
+ function executableSuffixes(platform, pathExt) {
4788
+ if (platform !== "win32")
4789
+ return [""];
4790
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4791
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4792
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4793
+ }
4794
+ function probeWithSuffixes(directory, command, suffixes) {
4795
+ for (const suffix of suffixes) {
4796
+ const candidate = join4(directory, command + suffix);
4797
+ if (probe(candidate))
4798
+ return candidate;
4564
4799
  }
4565
- const isWindows = process.platform === "win32";
4566
- let exts = [""];
4567
- if (isWindows) {
4568
- const pathExt = process.env["PATHEXT"] ?? "";
4569
- if (pathExt) {
4570
- const systemExts = pathExt.split(";").filter(Boolean);
4571
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4572
- } else {
4573
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4800
+ return null;
4801
+ }
4802
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4803
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4804
+ let current = resolve7(workingDirectory);
4805
+ while (true) {
4806
+ for (const rule of LOCAL_BIN_RULES) {
4807
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
4808
+ continue;
4809
+ for (const binDir of rule.binDirs) {
4810
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4811
+ if (found !== null)
4812
+ return found;
4813
+ }
4574
4814
  }
4815
+ if (probe(join4(current, ".git")))
4816
+ return null;
4817
+ if (boundary !== undefined && current === boundary)
4818
+ return null;
4819
+ const parent = dirname9(current);
4820
+ if (parent === current)
4821
+ return null;
4822
+ current = parent;
4575
4823
  }
4576
- let pathEnv = process.env["PATH"] ?? "";
4577
- if (isWindows && !pathEnv) {
4824
+ }
4825
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4826
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4827
+ if (platform === "win32" && !pathEnv) {
4578
4828
  pathEnv = process.env["Path"] ?? "";
4579
4829
  }
4580
- const paths = pathEnv.split(delimiter3);
4581
- for (const p of paths) {
4582
- for (const suffix of exts) {
4583
- if (existsSync9(join3(p, cmd + suffix))) {
4584
- return true;
4585
- }
4586
- }
4830
+ for (const entry of pathEnv.split(delimiter3)) {
4831
+ if (entry.length === 0)
4832
+ continue;
4833
+ const found = probeWithSuffixes(entry, command, suffixes);
4834
+ if (found !== null)
4835
+ return found;
4587
4836
  }
4588
- if (cmd === "node")
4589
- return true;
4590
- return false;
4837
+ return null;
4838
+ }
4839
+ function resolveServerBinary(command, workingDirectory, options = {}) {
4840
+ if (command.length === 0)
4841
+ return null;
4842
+ const [cmd] = command;
4843
+ if (cmd === undefined || cmd.length === 0)
4844
+ return null;
4845
+ const platform = options.platform ?? process.platform;
4846
+ const suffixes = executableSuffixes(platform, options.pathExt);
4847
+ if (cmd.includes("/") || cmd.includes("\\")) {
4848
+ const explicit = isAbsolute5(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4849
+ return probe(explicit) ? explicit : null;
4850
+ }
4851
+ const cacheKey = JSON.stringify([
4852
+ workingDirectory ?? "",
4853
+ cmd,
4854
+ platform,
4855
+ options.stopAt ?? "",
4856
+ options.pathExt ?? "",
4857
+ options.pathEnv ?? process.env["PATH"] ?? ""
4858
+ ]);
4859
+ const cached = resolutionCache.get(cacheKey);
4860
+ if (cached !== undefined)
4861
+ return cached;
4862
+ let resolved = null;
4863
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
4864
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4865
+ }
4866
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4867
+ if (resolved === null && cmd === "node")
4868
+ resolved = cmd;
4869
+ resolutionCache.set(cacheKey, resolved);
4870
+ return resolved;
4871
+ }
4872
+ function isServerInstalled(command, workingDirectory, options = {}) {
4873
+ if (command.length === 0)
4874
+ return false;
4875
+ return resolveServerBinary(command, workingDirectory, options) !== null;
4591
4876
  }
4592
4877
 
4593
4878
  // ../lsp-core/src/lsp/server-resolution.ts
4879
+ function withResolvedCommand(command, binaryPath) {
4880
+ return [binaryPath, ...command.slice(1)];
4881
+ }
4594
4882
  function findServerForExtension(ext) {
4595
4883
  const servers = getMergedServers();
4884
+ const workingDirectory = contextCwd();
4596
4885
  for (const server2 of servers) {
4597
- if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4886
+ if (!server2.extensions.includes(ext))
4887
+ continue;
4888
+ const binaryPath = resolveServerBinary(server2.command, workingDirectory);
4889
+ if (binaryPath !== null) {
4598
4890
  const resolvedServer = {
4599
4891
  id: server2.id,
4600
- command: server2.command,
4892
+ command: withResolvedCommand(server2.command, binaryPath),
4601
4893
  extensions: server2.extensions,
4602
4894
  priority: server2.priority
4603
4895
  };
@@ -4644,6 +4936,7 @@ function findServerForExtension(ext) {
4644
4936
  function getAllServers() {
4645
4937
  const servers = getMergedServers();
4646
4938
  const disabled = getDisabledServerIds();
4939
+ const workingDirectory = contextCwd();
4647
4940
  const result = [];
4648
4941
  const seen = new Set;
4649
4942
  for (const server2 of servers) {
@@ -4651,7 +4944,7 @@ function getAllServers() {
4651
4944
  continue;
4652
4945
  result.push({
4653
4946
  id: server2.id,
4654
- installed: isServerInstalled(server2.command),
4947
+ installed: isServerInstalled(server2.command, workingDirectory),
4655
4948
  extensions: server2.extensions,
4656
4949
  disabled: false,
4657
4950
  source: server2.source,
@@ -4665,7 +4958,7 @@ function getAllServers() {
4665
4958
  const builtin = BUILTIN_SERVERS[id];
4666
4959
  result.push({
4667
4960
  id,
4668
- installed: builtin ? isServerInstalled(builtin.command) : false,
4961
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4669
4962
  extensions: builtin?.extensions ?? [],
4670
4963
  disabled: true,
4671
4964
  source: "disabled",
@@ -4676,7 +4969,6 @@ function getAllServers() {
4676
4969
  }
4677
4970
 
4678
4971
  // ../lsp-core/src/lsp/client-wrapper.ts
4679
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
4680
4972
  function isDirectoryPath(filePath) {
4681
4973
  try {
4682
4974
  return statSync4(filePath).isDirectory();
@@ -4685,32 +4977,90 @@ function isDirectoryPath(filePath) {
4685
4977
  }
4686
4978
  }
4687
4979
  function findWorkspaceRoot(filePath) {
4688
- const abs = resolvePathInsideContext(filePath);
4980
+ const cwd = contextCwd();
4981
+ const abs = resolveReadablePathInsideContext(filePath);
4689
4982
  let dir = abs;
4690
4983
  if (!isDirectoryPath(dir)) {
4691
- dir = dirname8(dir);
4692
- }
4693
- let prevDir = "";
4694
- while (dir !== prevDir) {
4695
- for (const marker of WORKSPACE_MARKERS) {
4696
- if (existsSync10(join4(dir, marker))) {
4697
- return dir;
4984
+ dir = dirname10(dir);
4985
+ }
4986
+ if (!isPathInside(cwd, abs))
4987
+ return findWorkspaceRootOutsideContext(dir);
4988
+ const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4989
+ let nearestPackageRoot;
4990
+ while (isPathInside(cwd, dir)) {
4991
+ const canonicalDir = existingDirectoryInsideContext(dir, cwd);
4992
+ if (canonicalDir !== undefined) {
4993
+ if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
4994
+ return canonicalDir;
4995
+ }
4996
+ if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
4997
+ nearestPackageRoot = canonicalDir;
4698
4998
  }
4699
4999
  }
4700
- prevDir = dir;
4701
- dir = dirname8(dir);
5000
+ if (dir === cwd)
5001
+ break;
5002
+ dir = dirname10(dir);
4702
5003
  }
4703
- return dirname8(abs);
5004
+ return nearestPackageRoot ?? fallbackRoot;
5005
+ }
5006
+ function hasProjectWorkspaceMarker(directory) {
5007
+ return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
5008
+ }
5009
+ function resolveReadablePathInsideContext(filePath) {
5010
+ const cwd = contextCwd();
5011
+ const abs = resolve8(cwd, filePath);
5012
+ if (isPathInside(cwd, abs))
5013
+ return abs;
5014
+ const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
5015
+ if (rebased !== undefined)
5016
+ return rebased;
5017
+ return canonicalizeExistingOrNearestAncestor(abs);
4704
5018
  }
4705
5019
  function resolvePathInsideContext(filePath) {
4706
5020
  const cwd = contextCwd();
4707
- const abs = resolve7(cwd, filePath);
5021
+ const abs = resolveReadablePathInsideContext(filePath);
4708
5022
  const canonical = canonicalizeExistingOrNearestAncestor(abs);
4709
5023
  if (!isPathInside(cwd, canonical)) {
4710
5024
  throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
4711
5025
  }
4712
5026
  return canonical;
4713
5027
  }
5028
+ function rebaseThroughCanonicalAncestor(path2, cwd) {
5029
+ let current = path2;
5030
+ const suffix = [];
5031
+ while (true) {
5032
+ if (existsSync11(current)) {
5033
+ const canonical = realpathSync5(current);
5034
+ if (isPathInside(cwd, canonical))
5035
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
5036
+ }
5037
+ const parent = dirname10(current);
5038
+ if (parent === current)
5039
+ return;
5040
+ suffix.unshift(basename3(current));
5041
+ current = parent;
5042
+ }
5043
+ }
5044
+ function existingDirectoryInsideContext(directory, cwd) {
5045
+ if (!existsSync11(directory))
5046
+ return;
5047
+ const canonical = realpathSync5(directory);
5048
+ if (!statSync4(canonical).isDirectory())
5049
+ return;
5050
+ return isPathInside(cwd, canonical) ? canonical : undefined;
5051
+ }
5052
+ function nearestExistingDirectoryInsideContext(directory, cwd) {
5053
+ let current = directory;
5054
+ while (isPathInside(cwd, current)) {
5055
+ const canonical = existingDirectoryInsideContext(current, cwd);
5056
+ if (canonical !== undefined)
5057
+ return canonical;
5058
+ if (current === cwd)
5059
+ return;
5060
+ current = dirname10(current);
5061
+ }
5062
+ return;
5063
+ }
4714
5064
  function formatServerLookupError(result) {
4715
5065
  if (result.status === "not_installed") {
4716
5066
  return formatNotInstalled(result);
@@ -4734,6 +5084,19 @@ function formatServerLookupError(result) {
4734
5084
  ].join(`
4735
5085
  `);
4736
5086
  }
5087
+ function formatInstallOptions(serverId, installHint) {
5088
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
5089
+ if (localHint === undefined) {
5090
+ return ["To install, run:", ` ${installHint}`];
5091
+ }
5092
+ return [
5093
+ "To install in THIS repository (preferred — no global install needed):",
5094
+ ` ${localHint}`,
5095
+ "",
5096
+ "Or install it globally:",
5097
+ ` ${installHint}`
5098
+ ];
5099
+ }
4737
5100
  function formatNotInstalled(result) {
4738
5101
  const { server: server2, installHint } = result;
4739
5102
  const extensions = server2.extensions.join(", ");
@@ -4748,19 +5111,19 @@ function formatNotInstalled(result) {
4748
5111
  `Command not found: ${server2.command[0]}`,
4749
5112
  ""
4750
5113
  ];
5114
+ const installOptions = formatInstallOptions(server2.id, installHint);
4751
5115
  if (decision === "allowed") {
4752
5116
  return [
4753
5117
  ...header,
4754
5118
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4755
- ` ${installHint}`
5119
+ ...installOptions.slice(1)
4756
5120
  ].join(`
4757
5121
  `);
4758
5122
  }
4759
5123
  if (!context.capabilities.installDecisionTool) {
4760
5124
  return [
4761
5125
  ...header,
4762
- "To install, run:",
4763
- ` ${installHint}`,
5126
+ ...installOptions,
4764
5127
  "",
4765
5128
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4766
5129
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4769,8 +5132,7 @@ function formatNotInstalled(result) {
4769
5132
  }
4770
5133
  return [
4771
5134
  ...header,
4772
- "To install, run:",
4773
- ` ${installHint}`,
5135
+ ...installOptions,
4774
5136
  "",
4775
5137
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4776
5138
  "- If the user agrees: run the install command above, then retry this tool.",
@@ -4781,7 +5143,7 @@ function formatNotInstalled(result) {
4781
5143
  ].join(`
4782
5144
  `);
4783
5145
  }
4784
- var READ_ONLY_RETRY_TOOLS = new Set([
5146
+ var READ_ONLY_TOOLS = new Set([
4785
5147
  "diagnostics",
4786
5148
  "definition",
4787
5149
  "references",
@@ -4790,7 +5152,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
4790
5152
  "prepareRename"
4791
5153
  ]);
4792
5154
  async function withLspClient(filePath, fn, toolName, options = {}) {
4793
- const absPath = resolvePathInsideContext(filePath);
5155
+ const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
4794
5156
  if (isDirectoryPath(absPath)) {
4795
5157
  throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
4796
5158
  }
@@ -4805,9 +5167,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4805
5167
  const acquireAndCall = async (allowRetry) => {
4806
5168
  const client = await manager.getClient(root, server2, options.signal);
4807
5169
  try {
4808
- return await fn(client, root);
5170
+ return await fn(client, root, absPath);
4809
5171
  } catch (err) {
4810
- if (allowRetry && READ_ONLY_RETRY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
5172
+ if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4811
5173
  manager.invalidateClient(root, server2.id, client);
4812
5174
  return acquireAndCall(false);
4813
5175
  }
@@ -4825,8 +5187,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4825
5187
  }
4826
5188
 
4827
5189
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4828
- import { existsSync as existsSync11, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
4829
- import { join as join5, resolve as resolve8 } from "node:path";
5190
+ import { existsSync as existsSync12, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
5191
+ import { join as join6, resolve as resolve9 } from "node:path";
4830
5192
 
4831
5193
  // ../lsp-core/src/lsp/formatters.ts
4832
5194
  import { fileURLToPath as fileURLToPath3 } from "node:url";
@@ -4956,7 +5318,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
4956
5318
  for (const entry of entries) {
4957
5319
  if (files.length >= maxFiles)
4958
5320
  return;
4959
- const fullPath = join5(currentDir, entry);
5321
+ const fullPath = join6(currentDir, entry);
4960
5322
  let stat;
4961
5323
  try {
4962
5324
  stat = lstatSync5(fullPath);
@@ -4981,8 +5343,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4981
5343
  if (!extension.startsWith(".")) {
4982
5344
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4983
5345
  }
4984
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4985
- if (!existsSync11(absDir)) {
5346
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
5347
+ if (!existsSync12(absDir)) {
4986
5348
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4987
5349
  }
4988
5350
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
@@ -5069,7 +5431,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
5069
5431
 
5070
5432
  // ../lsp-core/src/lsp/infer-extension.ts
5071
5433
  import { lstatSync as lstatSync6, readdirSync as readdirSync4 } from "node:fs";
5072
- import { join as join6 } from "node:path";
5434
+ import { join as join7 } from "node:path";
5073
5435
  var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
5074
5436
  var MAX_SCAN_ENTRIES = 500;
5075
5437
  function inferExtensionFromDirectory(directory) {
@@ -5087,7 +5449,7 @@ function inferExtensionFromDirectory(directory) {
5087
5449
  for (const entry of entries) {
5088
5450
  if (scanned >= MAX_SCAN_ENTRIES)
5089
5451
  return;
5090
- const fullPath = join6(dir, entry);
5452
+ const fullPath = join7(dir, entry);
5091
5453
  let stat;
5092
5454
  try {
5093
5455
  stat = lstatSync6(fullPath);
@@ -5262,7 +5624,7 @@ async function executeLspDiagnostics(params, signal) {
5262
5624
  const filePath = requireString(params, "filePath");
5263
5625
  const severity = severityFilter(params);
5264
5626
  try {
5265
- const absPath = resolvePathInsideContext(filePath);
5627
+ const absPath = resolveReadablePathInsideContext(filePath);
5266
5628
  if (isDirectoryPath(absPath)) {
5267
5629
  const extension = inferExtensionFromDirectory(absPath);
5268
5630
  if (!extension) {
@@ -5291,7 +5653,7 @@ async function executeLspDiagnostics(params, signal) {
5291
5653
  };
5292
5654
  return text(output2.output, details2);
5293
5655
  }
5294
- const result = await withLspClient(filePath, async (client) => client.diagnostics(filePath, signal), "diagnostics", clientOptions(signal));
5656
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
5295
5657
  if (result.transientError) {
5296
5658
  const message = result.transientError.message;
5297
5659
  const details2 = {
@@ -5338,6 +5700,96 @@ async function executeLspDiagnostics(params, signal) {
5338
5700
  throw error;
5339
5701
  }
5340
5702
  }
5703
+ // ../lsp-core/src/lsp/format-document.ts
5704
+ import { readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
5705
+ var DEFAULT_FORMATTING_OPTIONS = {
5706
+ tabSize: 4,
5707
+ insertSpaces: false,
5708
+ trimTrailingWhitespace: true,
5709
+ insertFinalNewline: true,
5710
+ trimFinalNewlines: true
5711
+ };
5712
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
5713
+ async function formatDocumentWithClient(client, filePath, options = {}) {
5714
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
5715
+ if (edits === null)
5716
+ return { status: "unavailable", reason: "capability_not_advertised" };
5717
+ if (edits.length === 0)
5718
+ return UNCHANGED;
5719
+ const before = readFileSync6(filePath, "utf-8");
5720
+ const normalized = normalizeTextEdits(before, edits, 0);
5721
+ if (normalized.text === before)
5722
+ return UNCHANGED;
5723
+ writeAtomically(filePath, normalized.text);
5724
+ await client.openFile(filePath);
5725
+ return {
5726
+ status: "formatted",
5727
+ ...lineDelta(normalized.edits)
5728
+ };
5729
+ }
5730
+ function lineDelta(edits) {
5731
+ let linesAdded = 0;
5732
+ let linesRemoved = 0;
5733
+ for (const edit of edits) {
5734
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
5735
+ linesAdded += edit.newText.split(`
5736
+ `).length;
5737
+ }
5738
+ return { linesAdded, linesRemoved };
5739
+ }
5740
+ function writeAtomically(filePath, content) {
5741
+ const tempPath = `${filePath}.omo-format.tmp`;
5742
+ writeFileSync3(tempPath, content, "utf-8");
5743
+ try {
5744
+ renameSync3(tempPath, filePath);
5745
+ } catch (error) {
5746
+ try {
5747
+ unlinkSync2(tempPath);
5748
+ } catch {}
5749
+ throw error;
5750
+ }
5751
+ }
5752
+
5753
+ // ../lsp-core/src/tools/format.ts
5754
+ async function executeLspFormat(params, signal) {
5755
+ const filePath = requireString(params, "filePath");
5756
+ try {
5757
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
5758
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
5759
+ } catch (error) {
5760
+ const missingDependency = missingDependencyResult(error, {
5761
+ filePath,
5762
+ status: "unavailable",
5763
+ reason: "server_unavailable",
5764
+ linesAdded: 0,
5765
+ linesRemoved: 0
5766
+ });
5767
+ if (missingDependency)
5768
+ return missingDependency;
5769
+ throw error;
5770
+ }
5771
+ }
5772
+ function formatDetails(filePath, result) {
5773
+ if (result.status === "unavailable") {
5774
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5775
+ }
5776
+ return {
5777
+ filePath,
5778
+ status: result.status,
5779
+ linesAdded: result.linesAdded,
5780
+ linesRemoved: result.linesRemoved
5781
+ };
5782
+ }
5783
+ function describeResult(filePath, result) {
5784
+ if (result.status === "unavailable") {
5785
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5786
+ }
5787
+ if (result.status === "unchanged") {
5788
+ return `Already formatted: ${filePath}`;
5789
+ }
5790
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5791
+ }
5792
+
5341
5793
  // ../lsp-core/src/tools/install-decision.ts
5342
5794
  async function executeLspInstallDecision(params) {
5343
5795
  const serverId = requireString(params, "server_id");
@@ -5366,7 +5818,7 @@ async function executeLspGotoDefinition(params, signal) {
5366
5818
  const line = requireNumber(params, "line");
5367
5819
  const character = requireNumber(params, "character");
5368
5820
  try {
5369
- const result = await withLspClient(filePath, async (client) => client.definition(filePath, line, character, signal), "definition", clientOptions(signal));
5821
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
5370
5822
  const locations = !result ? [] : Array.isArray(result) ? result : [result];
5371
5823
  const details = { filePath, line, character, locations };
5372
5824
  if (locations.length === 0)
@@ -5391,7 +5843,7 @@ async function executeLspFindReferences(params, signal) {
5391
5843
  const character = requireNumber(params, "character");
5392
5844
  const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
5393
5845
  try {
5394
- const result = await withLspClient(filePath, async (client) => client.references(filePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
5846
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
5395
5847
  const references = Array.isArray(result) ? result : [];
5396
5848
  const total = references.length;
5397
5849
  const truncated = total > DEFAULT_MAX_REFERENCES;
@@ -5433,7 +5885,7 @@ async function executeLspPrepareRename(params, signal) {
5433
5885
  const line = requireNumber(params, "line");
5434
5886
  const character = requireNumber(params, "character");
5435
5887
  try {
5436
- const result = await withLspClient(filePath, async (client) => client.prepareRename(filePath, line, character, signal), "prepareRename", clientOptions(signal));
5888
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
5437
5889
  const details = { filePath, line, character, result };
5438
5890
  return text(formatPrepareRenameResult(result), details);
5439
5891
  } catch (error) {
@@ -5454,7 +5906,7 @@ async function executeLspRename(params, signal) {
5454
5906
  const character = requireNumber(params, "character");
5455
5907
  const newName = requireString(params, "newName");
5456
5908
  try {
5457
- const result = await withLspClient(filePath, async (client) => client.rename(filePath, line, character, newName, signal), "rename", clientOptions(signal));
5909
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
5458
5910
  const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
5459
5911
  return text(formatApplyResult(result.apply), details, !result.apply.success);
5460
5912
  } catch (error) {
@@ -5534,7 +5986,7 @@ async function executeLspSymbols(params, signal) {
5534
5986
  const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
5535
5987
  return formatSymbolsResult(filePath, scope, symbols2, limit, query);
5536
5988
  }
5537
- const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(filePath, signal), "documentSymbols", clientOptions(signal));
5989
+ const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
5538
5990
  return formatSymbolsResult(filePath, scope, symbols, limit);
5539
5991
  } catch (error) {
5540
5992
  const query = optionalString(params, "query");
@@ -5670,6 +6122,16 @@ var LSP_MCP_TOOLS = [
5670
6122
  }, ["filePath", "line", "character", "newName"]),
5671
6123
  execute: executeLspRename
5672
6124
  },
6125
+ {
6126
+ name: "format",
6127
+ aliases: ["lsp_format"],
6128
+ title: "LSP Format",
6129
+ description: "Format a source file with its language server and write the returned edits to disk.",
6130
+ inputSchema: objectSchema({
6131
+ filePath: { type: "string", description: "Source file path to format." }
6132
+ }, ["filePath"]),
6133
+ execute: executeLspFormat
6134
+ },
5673
6135
  {
5674
6136
  name: "install_decision",
5675
6137
  aliases: ["lsp_install_decision"],
@@ -5770,7 +6232,10 @@ function requestedProtocolVersion(params) {
5770
6232
  var CONTEXT_KEY = "_context";
5771
6233
 
5772
6234
  class InvalidDaemonRequestError extends Error {
5773
- name = "InvalidDaemonRequestError";
6235
+ constructor() {
6236
+ super(...arguments);
6237
+ this.name = "InvalidDaemonRequestError";
6238
+ }
5774
6239
  }
5775
6240
  function extractRequestContext(raw) {
5776
6241
  if (!isPlainRecord(raw) || raw["method"] !== "tools/call")
@@ -5886,14 +6351,17 @@ async function callToolViaDaemon(name, args, options) {
5886
6351
  function callDiagnosticsViaDaemon(filePath, options) {
5887
6352
  return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
5888
6353
  }
6354
+ function callFormatViaDaemon(filePath, options) {
6355
+ return callToolViaDaemon("format", { filePath }, options);
6356
+ }
5889
6357
  function currentRequestContext(env = process.env) {
5890
6358
  const cwd = process.cwd();
5891
6359
  const home = env["HOME"] ?? homedir3();
5892
6360
  return parseLspRequestContext({
5893
6361
  cwd,
5894
- projectConfigPaths: [join7(cwd, ".codex", "lsp-client.json")],
5895
- userConfigPath: join7(home, ".codex", "lsp-client.json"),
5896
- installDecisionsPath: join7(home, ".codex", "lsp-install-decisions.json"),
6362
+ projectConfigPaths: [join8(cwd, ".codex", "lsp-client.json")],
6363
+ userConfigPath: join8(home, ".codex", "lsp-client.json"),
6364
+ installDecisionsPath: join8(home, ".codex", "lsp-install-decisions.json"),
5897
6365
  capabilities: { installDecisionTool: true }
5898
6366
  });
5899
6367
  }
@@ -5908,7 +6376,7 @@ function withContext(args, context) {
5908
6376
  function ensureDaemonAvailable(paths, ensure, signal) {
5909
6377
  if (!signal)
5910
6378
  return ensure(paths);
5911
- return new Promise((resolve9, reject) => {
6379
+ return new Promise((resolve10, reject) => {
5912
6380
  let settled = false;
5913
6381
  const finish = (run) => {
5914
6382
  if (settled)
@@ -5923,11 +6391,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
5923
6391
  return;
5924
6392
  }
5925
6393
  signal.addEventListener("abort", onAbort, { once: true });
5926
- Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve9()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
6394
+ Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve10()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
5927
6395
  });
5928
6396
  }
5929
6397
  function sendToolCall(paths, token, name, args, options) {
5930
- return new Promise((resolve9, reject) => {
6398
+ return new Promise((resolve10, reject) => {
5931
6399
  const socket = connect(paths.socket);
5932
6400
  const requestId = allocateProxyRequestId();
5933
6401
  let settled = false;
@@ -5980,7 +6448,7 @@ function sendToolCall(paths, token, name, args, options) {
5980
6448
  }
5981
6449
  const result = toToolResult(message, requestId);
5982
6450
  if (result)
5983
- finish(() => resolve9(result));
6451
+ finish(() => resolve10(result));
5984
6452
  else
5985
6453
  finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
5986
6454
  });
@@ -6025,8 +6493,8 @@ function isRetryableTool(name) {
6025
6493
  return name !== "rename" && name !== "lsp_rename";
6026
6494
  }
6027
6495
  // src/proxy.ts
6028
- import { existsSync as existsSync12, realpathSync as realpathSync4 } from "node:fs";
6029
- import { basename as basename3, delimiter as delimiter4, dirname as dirname9, isAbsolute as isAbsolute5 } from "node:path";
6496
+ import { existsSync as existsSync13, realpathSync as realpathSync6 } from "node:fs";
6497
+ import { basename as basename4, delimiter as delimiter4, dirname as dirname11, isAbsolute as isAbsolute6 } from "node:path";
6030
6498
  var DEFAULT_STARTUP_TIMEOUT_MS = 1e4;
6031
6499
  async function runMcpStdioProxy(options = {}) {
6032
6500
  const input = options.input ?? process.stdin;
@@ -6149,34 +6617,34 @@ function canonicalizePathList(value) {
6149
6617
  return value.split(delimiter4).map((entry) => canonicalizePath(entry) ?? entry).join(delimiter4);
6150
6618
  }
6151
6619
  function canonicalizePath(value) {
6152
- if (value === undefined || !isAbsolute5(value) || !existsSync12(value))
6620
+ if (value === undefined || !isAbsolute6(value) || !existsSync13(value))
6153
6621
  return value;
6154
- return realpathSync4(value);
6622
+ return realpathSync6(value);
6155
6623
  }
6156
6624
  function projectRootFromOpenCodeConfigPath(path2) {
6157
- if (basename3(path2) !== "lsp.json" && basename3(path2) !== "lsp-client.json")
6625
+ if (basename4(path2) !== "lsp.json" && basename4(path2) !== "lsp-client.json")
6158
6626
  return;
6159
- const configDir = dirname9(path2);
6160
- const configDirName = basename3(configDir);
6627
+ const configDir = dirname11(path2);
6628
+ const configDirName = basename4(configDir);
6161
6629
  if (configDirName !== ".opencode" && configDirName !== ".omo")
6162
6630
  return;
6163
- return dirname9(configDir);
6631
+ return dirname11(configDir);
6164
6632
  }
6165
6633
  export {
6166
- validateDaemonVersion,
6167
- runMcpStdioProxy,
6168
- resolveDaemonRuntime,
6169
- probeDaemon,
6170
- ensureDaemonRunning,
6171
- disposeDefaultLspManager,
6172
- daemonPaths,
6173
- currentRequestContext,
6174
- callToolViaDaemon,
6175
- callDiagnosticsViaDaemon,
6176
- OMO_LSP_DAEMON_VERSION,
6177
- OMO_LSP_DAEMON_DIR,
6178
- OMO_LSP_DAEMON_CLI,
6179
- InvalidRuntimeOverrideError,
6634
+ InvalidDaemonDirectoryError,
6180
6635
  InvalidDaemonVersionError,
6181
- InvalidDaemonDirectoryError
6636
+ InvalidRuntimeOverrideError,
6637
+ OMO_LSP_DAEMON_CLI,
6638
+ OMO_LSP_DAEMON_DIR,
6639
+ OMO_LSP_DAEMON_VERSION,
6640
+ callDiagnosticsViaDaemon,
6641
+ callToolViaDaemon,
6642
+ currentRequestContext,
6643
+ daemonPaths,
6644
+ disposeDefaultLspManager,
6645
+ ensureDaemonRunning,
6646
+ probeDaemon,
6647
+ resolveDaemonRuntime,
6648
+ runMcpStdioProxy,
6649
+ validateDaemonVersion
6182
6650
  };