lazycodex-ai 5.0.0-beta.7 → 5.0.0-beta.71

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 (725) hide show
  1. package/README.ja.md +66 -61
  2. package/README.ko.md +67 -62
  3. package/README.md +108 -182
  4. package/README.ru.md +63 -61
  5. package/README.zh-cn.md +62 -61
  6. package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
  7. package/dist/cli/doctor/checks/browser-provider.d.ts +2 -0
  8. package/dist/cli/doctor/checks/index.d.ts +2 -0
  9. package/dist/cli/doctor/checks/latest-version.d.ts +11 -0
  10. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  11. package/dist/cli/doctor/framework/constants.d.ts +5 -0
  12. package/dist/cli/doctor/framework/types.d.ts +2 -0
  13. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  14. package/dist/cli/index.js +51933 -59845
  15. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  16. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  17. package/dist/cli/runtime-commands.d.ts +1 -1
  18. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  19. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  20. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  21. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  22. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  23. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  24. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  25. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  26. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  27. package/dist/cli-node/index.js +51915 -59804
  28. package/package.json +12 -14
  29. package/packages/git-bash-mcp/dist/cli.js +6 -1
  30. package/packages/lsp-daemon/dist/cli.js +904 -479
  31. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  32. package/packages/lsp-daemon/dist/client.js +922 -493
  33. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  34. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  35. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +6 -1
  36. package/packages/lsp-daemon/dist/ensure-daemon.js +10 -2
  37. package/packages/lsp-daemon/dist/index.js +826 -402
  38. package/packages/lsp-daemon/dist/ownership.js +2 -2
  39. package/packages/lsp-daemon/dist/proxy.js +3 -0
  40. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  41. package/packages/lsp-daemon/package.json +1 -1
  42. package/packages/lsp-tools-mcp/dist/cli.js +764 -341
  43. package/packages/lsp-tools-mcp/dist/lsp/manager.js +274 -138
  44. package/packages/lsp-tools-mcp/dist/mcp.js +789 -368
  45. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  46. package/packages/lsp-tools-mcp/dist/tools.js +719 -302
  47. package/packages/lsp-tools-mcp/package.json +1 -1
  48. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -6
  49. package/packages/omo-codex/plugin/.mcp.json +0 -6
  50. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  51. package/packages/omo-codex/plugin/README.md +6 -2
  52. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +7100 -408
  53. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  54. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  55. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  56. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +7 -1
  57. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  58. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  59. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  60. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  61. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  62. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  63. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  64. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  65. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  66. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  67. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +1 -1
  68. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +2 -1
  69. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  70. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  71. package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +2 -1
  72. package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +6 -7
  73. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +2 -2
  74. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  75. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/directive.md +2 -0
  76. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +36 -29
  77. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +32 -26
  78. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/types.d.ts +3 -0
  79. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  80. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  81. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +32 -28
  82. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/types.ts +3 -0
  83. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +1 -1
  84. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +137 -28
  85. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +4 -2
  86. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  87. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  88. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  89. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +943 -540
  90. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  91. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  92. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  93. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  94. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  95. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  96. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  97. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  98. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  99. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  100. package/packages/omo-codex/plugin/components/rules/README.md +2 -0
  101. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  102. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +123 -0
  103. package/packages/omo-codex/plugin/components/rules/dist/cli.js +91 -68
  104. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  105. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  106. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  107. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  108. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +15 -5
  109. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  110. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  111. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  112. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  113. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  114. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  115. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  116. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  117. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  118. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  119. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  120. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  121. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  122. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +38 -3
  123. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  124. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  125. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  126. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  127. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +29 -6
  128. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  129. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  130. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  131. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  132. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  133. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  134. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +4 -10
  135. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  136. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  137. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2407 -684
  138. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2411 -689
  139. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  140. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  141. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  142. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  143. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  144. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  145. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -4
  146. package/packages/omo-codex/plugin/components/ultrawork/README.md +2 -0
  147. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
  148. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +1 -1
  149. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
  150. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  151. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
  152. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  153. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-low.toml +1 -1
  154. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +1 -1
  155. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +1 -1
  156. package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +1 -1
  157. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +1 -1
  158. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +4 -4
  159. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  160. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +500 -4
  161. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  162. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -6
  163. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
  164. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -7
  165. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  166. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  167. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  168. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -0
  169. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
  170. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
  171. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  172. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  173. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
  174. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
  175. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  176. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +4 -4
  177. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  178. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +6 -6
  179. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  180. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +11 -11
  181. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +16 -16
  182. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +16 -0
  183. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  184. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  185. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  186. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +4 -4
  187. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  188. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  189. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +1 -1
  190. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  191. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +4 -11
  192. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +24 -22
  193. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +19 -0
  194. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +17 -1
  195. package/packages/omo-codex/plugin/components/ulw-loop/README.md +12 -1
  196. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  197. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +44 -27
  198. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +18 -0
  199. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +30 -0
  200. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +10 -4
  201. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +2 -5
  202. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +5 -78
  203. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +12 -0
  204. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +114 -0
  205. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.d.ts +7 -1
  206. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +57 -46
  207. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +2 -2
  208. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +21 -8
  209. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  210. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +12 -1
  211. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +1 -1
  212. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +40 -37
  213. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +2183 -737
  214. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  215. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +28 -8
  216. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +8 -5
  217. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +35 -23
  218. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -0
  219. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +1 -0
  220. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +25 -9
  221. package/packages/omo-codex/plugin/components/ulw-loop/dist/driver-objective-ack.d.ts +4 -0
  222. package/packages/omo-codex/plugin/components/ulw-loop/dist/driver-objective-ack.js +18 -0
  223. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence-artifacts.d.ts +1 -0
  224. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence-artifacts.js +37 -0
  225. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.d.ts +1 -0
  226. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.js +24 -12
  227. package/packages/omo-codex/plugin/components/ulw-loop/dist/ledger.d.ts +4 -0
  228. package/packages/omo-codex/plugin/components/ulw-loop/dist/ledger.js +39 -0
  229. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +2 -0
  230. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +19 -4
  231. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-commit.d.ts +19 -0
  232. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-commit.js +108 -0
  233. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +6 -2
  234. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +54 -25
  235. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-goal-factory.d.ts +10 -3
  236. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-goal-factory.js +38 -31
  237. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +10 -7
  238. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +121 -100
  239. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-log.d.ts +16 -0
  240. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-log.js +115 -0
  241. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +18 -0
  242. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +41 -0
  243. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +7 -0
  244. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +9 -0
  245. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +12 -0
  246. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +104 -0
  247. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  248. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +65 -9
  249. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  250. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  251. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +72 -117
  252. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.d.ts +2 -0
  253. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +25 -13
  254. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.d.ts +2 -0
  255. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.js +157 -0
  256. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.d.ts +381 -0
  257. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.js +127 -0
  258. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.d.ts +130 -0
  259. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.js +1 -0
  260. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.d.ts +3 -0
  261. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.js +3 -0
  262. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-budget-io.d.ts +5 -0
  263. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-budget-io.js +67 -0
  264. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +7 -1
  265. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +188 -59
  266. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-role-guard.d.ts +2 -0
  267. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-role-guard.js +22 -0
  268. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.d.ts +19 -0
  269. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.js +259 -0
  270. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +7 -0
  271. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +41 -0
  272. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.js +4 -4
  273. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.d.ts +3 -2
  274. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.js +4 -4
  275. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.d.ts +9 -1
  276. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.d.ts +3 -2
  277. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +11 -11
  278. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +28 -23
  279. package/packages/omo-codex/plugin/components/ulw-loop/dist/success-criteria-input.d.ts +9 -0
  280. package/packages/omo-codex/plugin/components/ulw-loop/dist/success-criteria-input.js +41 -0
  281. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +19 -0
  282. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +75 -0
  283. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +18 -5
  284. package/packages/omo-codex/plugin/components/ulw-loop/package.json +6 -6
  285. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +7 -2
  286. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +5 -3
  287. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +34 -11
  288. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +52 -0
  289. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +8 -6
  290. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +5 -98
  291. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +134 -0
  292. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +59 -77
  293. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +10 -4
  294. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +24 -8
  295. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +14 -1
  296. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +52 -46
  297. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +8 -6
  298. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +35 -7
  299. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +51 -33
  300. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  301. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +1 -0
  302. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +27 -9
  303. package/packages/omo-codex/plugin/components/ulw-loop/src/driver-objective-ack.ts +20 -0
  304. package/packages/omo-codex/plugin/components/ulw-loop/src/evidence-artifacts.ts +45 -0
  305. package/packages/omo-codex/plugin/components/ulw-loop/src/evidence.ts +23 -16
  306. package/packages/omo-codex/plugin/components/ulw-loop/src/ledger.ts +38 -0
  307. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +32 -4
  308. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-commit.ts +132 -0
  309. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +67 -54
  310. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-goal-factory.ts +63 -31
  311. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +140 -119
  312. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-log.ts +112 -0
  313. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +61 -0
  314. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +11 -0
  315. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +123 -0
  316. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +71 -15
  317. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  318. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +92 -136
  319. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +38 -13
  320. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/factory.ts +218 -0
  321. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/manifest.ts +156 -0
  322. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/types.ts +143 -0
  323. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk.ts +3 -0
  324. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-budget-io.ts +59 -0
  325. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +196 -52
  326. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-role-guard.ts +22 -0
  327. package/packages/omo-codex/plugin/components/ulw-loop/src/state-lock.ts +257 -0
  328. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +45 -0
  329. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-batch.ts +4 -4
  330. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-mutations.ts +5 -4
  331. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-types.ts +13 -1
  332. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +12 -10
  333. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +27 -22
  334. package/packages/omo-codex/plugin/components/ulw-loop/src/success-criteria-input.ts +56 -0
  335. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +107 -0
  336. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  337. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +131 -82
  338. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +147 -0
  339. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint.test.ts +16 -22
  340. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +4 -2
  341. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint.test.ts +31 -2
  342. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +2 -0
  343. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-complete-goals.test.ts +3 -1
  344. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +35 -8
  345. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +38 -4
  346. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-json-errors.test.ts +27 -0
  347. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-scope-required.test.ts +144 -0
  348. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +185 -0
  349. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +8 -3
  350. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +6 -0
  351. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +37 -2
  352. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +88 -11
  353. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  354. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/barrier.ts +13 -0
  355. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/cli-session.ts +4 -0
  356. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-child.ts +65 -0
  357. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-cli-qa.mjs +76 -0
  358. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-crash.ts +23 -0
  359. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-mutations.mjs +58 -0
  360. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-writer.ts +65 -0
  361. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/lease-clock.ts +23 -0
  362. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +9 -4
  363. package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +67 -0
  364. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  365. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  366. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-commit-log.test.ts +252 -0
  367. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-commit-recovery.test.ts +190 -0
  368. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io-cross-process.test.ts +106 -0
  369. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +74 -25
  370. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-log-legacy-projection.test.ts +228 -0
  371. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-log-newest.test.ts +72 -0
  372. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  373. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  374. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-fields-messages.test.ts +98 -0
  375. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-lazycodex-surface.test.ts +93 -0
  376. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  377. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +51 -2
  378. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
  379. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  380. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +58 -3
  381. package/packages/omo-codex/plugin/components/ulw-loop/test/review-blockers.test.ts +9 -7
  382. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-completed-plan.test.ts +43 -0
  383. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-contract.test.ts +137 -0
  384. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-driver-states.test.ts +174 -0
  385. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-dx.test.ts +219 -0
  386. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-session-context.test.ts +169 -0
  387. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +450 -7
  388. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-role-matrix.test.ts +113 -0
  389. package/packages/omo-codex/plugin/components/ulw-loop/test/state-lock.test.ts +310 -0
  390. package/packages/omo-codex/plugin/components/ulw-loop/test/status-next-actions-surface.test.ts +133 -0
  391. package/packages/omo-codex/plugin/components/ulw-loop/test/steering-batch.test.ts +12 -12
  392. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +12 -6
  393. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  394. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  395. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +13 -8
  396. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  397. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  398. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  399. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  400. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  401. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  402. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  403. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  404. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +18 -0
  405. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  406. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  407. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  408. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  409. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  410. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  411. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  412. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  413. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  414. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  415. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  416. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  417. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  418. package/packages/omo-codex/plugin/model-catalog.json +16 -7
  419. package/packages/omo-codex/plugin/package-lock.json +676 -524
  420. package/packages/omo-codex/plugin/package.json +2 -3
  421. package/packages/omo-codex/plugin/scripts/AGENTS.md +39 -0
  422. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -2
  423. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  424. package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
  425. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  426. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +16 -7
  427. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +8 -4
  428. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +19 -90
  429. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +1 -1
  430. package/packages/omo-codex/plugin/scripts/sync-skills.d.mts +4 -0
  431. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +111 -64
  432. package/packages/omo-codex/plugin/shared/package.json +3 -4
  433. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  434. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  435. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  436. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  437. package/packages/omo-codex/plugin/skills/ast-grep/SKILL.md +13 -1
  438. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  439. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +1 -1
  440. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  441. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  442. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  443. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  444. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  445. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  446. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  447. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  448. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +3 -1
  449. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  450. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  451. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  452. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  453. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  454. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  455. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  456. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  457. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  458. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  459. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  460. package/packages/omo-codex/plugin/skills/debugging/references/tools/playwright-cli.md +79 -161
  461. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +10 -0
  462. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +16 -9
  463. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +10 -2
  464. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +2 -0
  465. package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +145 -0
  466. package/packages/omo-codex/plugin/skills/frontend/references/design/aside.md +1 -1
  467. package/packages/omo-codex/plugin/skills/frontend/references/design/clone-from-url.md +1 -1
  468. package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +2 -0
  469. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  470. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  471. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  472. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  473. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  474. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  475. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  476. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  477. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/lighthouse-audit.py +2 -2
  478. package/packages/omo-codex/plugin/skills/git-master/SKILL.md +1 -1
  479. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +20 -18
  480. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +4 -2
  481. package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +1 -1
  482. package/packages/omo-codex/plugin/skills/programming/SKILL.md +1 -1
  483. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +10 -8
  484. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +7 -5
  485. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +116 -424
  486. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +32 -86
  487. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +32 -27
  488. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +111 -0
  489. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +2 -2
  490. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +5 -2
  491. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +8 -6
  492. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +86 -0
  493. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +4 -7
  494. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +86 -95
  495. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +18 -5
  496. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/playwright.md +16 -13
  497. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/extract_cookies.py +3 -3
  498. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +44 -27
  499. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +32 -34
  500. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  501. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +31 -2
  502. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +5 -3
  503. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +34 -11
  504. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -7
  505. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  506. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  507. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  508. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -0
  509. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +14 -7
  510. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  511. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +10 -7
  512. package/packages/omo-codex/plugin/skills/visual-qa/references/browser-setup.md +75 -0
  513. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  514. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  515. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +16 -51
  516. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -3
  517. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  518. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +14 -4
  519. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  520. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  521. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  522. package/packages/omo-codex/plugin/test/auto-update.test.mjs +4 -29
  523. package/packages/omo-codex/plugin/test/bootstrap-default-role.test.mjs +66 -0
  524. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  525. package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
  526. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  527. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -51
  528. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +100 -2
  529. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +5 -6
  530. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  531. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  532. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +35 -35
  533. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +1 -1
  534. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  535. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +107 -15
  536. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +168 -0
  537. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +54 -24
  538. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +18 -119
  539. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  540. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  541. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  542. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  543. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  544. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -5
  545. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  546. package/packages/omo-codex/scripts/install-dist/install-local.mjs +9659 -1394
  547. package/packages/{omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md → prompts-core/prompts/ultrawork/codex.md} +44 -34
  548. package/packages/shared-skills/package.json +7 -1
  549. package/packages/shared-skills/skill-source-filter.d.ts +16 -0
  550. package/packages/shared-skills/skill-source-filter.mjs +44 -0
  551. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  552. package/packages/shared-skills/skills/ast-grep/SKILL.md +13 -1
  553. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  554. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +1 -1
  555. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  556. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  557. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  558. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  559. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  560. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  561. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  562. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  563. package/packages/shared-skills/skills/debugging/SKILL.md +3 -1
  564. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  565. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  566. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  567. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  568. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  569. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  570. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  571. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  572. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  573. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  574. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  575. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  576. package/packages/shared-skills/skills/debugging/references/tools/playwright-cli.md +79 -161
  577. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -0
  578. package/packages/shared-skills/skills/frontend/SKILL.md +16 -9
  579. package/packages/shared-skills/skills/frontend/references/design/README.md +10 -2
  580. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +2 -0
  581. package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +145 -0
  582. package/packages/shared-skills/skills/frontend/references/design/aside.md +1 -1
  583. package/packages/shared-skills/skills/frontend/references/design/clone-from-url.md +1 -1
  584. package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +2 -0
  585. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  586. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  587. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  588. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  589. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  590. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  591. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  592. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  593. package/packages/shared-skills/skills/frontend/scripts/perfection/lighthouse-audit.py +2 -2
  594. package/packages/shared-skills/skills/git-master/SKILL.md +1 -1
  595. package/packages/shared-skills/skills/init-deep/SKILL.md +14 -14
  596. package/packages/shared-skills/skills/lsp-setup/SKILL.md +1 -1
  597. package/packages/shared-skills/skills/programming/SKILL.md +1 -1
  598. package/packages/shared-skills/skills/refactor/SKILL.md +4 -4
  599. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
  600. package/packages/shared-skills/skills/review-work/SKILL.md +101 -419
  601. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +32 -86
  602. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +32 -27
  603. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +111 -0
  604. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +2 -2
  605. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +5 -2
  606. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +8 -6
  607. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +86 -0
  608. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +4 -7
  609. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +86 -95
  610. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +18 -5
  611. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/playwright.md +16 -13
  612. package/packages/shared-skills/skills/ultimate-browsing/scripts/extract_cookies.py +3 -3
  613. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +21 -20
  614. package/packages/shared-skills/skills/ulw-plan/SKILL.md +7 -8
  615. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +32 -7
  616. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  617. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  618. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -1
  619. package/packages/shared-skills/skills/ulw-research/SKILL.md +8 -3
  620. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  621. package/packages/shared-skills/skills/visual-qa/SKILL.md +4 -3
  622. package/packages/shared-skills/skills/visual-qa/references/browser-setup.md +75 -0
  623. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  624. package/script/qa/xterm-live-terminal.mjs +18 -2
  625. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  626. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  627. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  628. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  629. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  630. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  631. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  632. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  633. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12222
  634. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9820
  635. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  636. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  637. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  638. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  639. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  640. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  641. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  642. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -309
  643. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -80
  644. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  645. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  646. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  647. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  648. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  649. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -21
  650. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  651. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  652. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  653. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  654. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  655. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  656. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  657. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  658. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  659. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  660. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  661. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  662. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  663. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  664. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  665. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  666. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  667. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  668. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  669. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  670. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  671. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  672. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  673. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  674. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  675. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  676. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  677. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  678. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  679. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  680. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  681. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  682. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  683. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  684. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  685. package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +0 -21
  686. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  687. package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -477
  688. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  689. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  690. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  691. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  692. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  693. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  694. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  695. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  696. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  697. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  698. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  699. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  700. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  701. package/packages/omo-codex/plugin/skills/visual-qa/references/agent-browser-setup.md +0 -45
  702. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  703. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  704. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
  705. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  706. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  707. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  708. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  709. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  710. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  711. package/packages/shared-skills/skills/visual-qa/references/agent-browser-setup.md +0 -45
  712. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  713. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  714. /package/packages/omo-codex/plugin/components/{codegraph → ulw-execute-continuation}/LICENSE +0 -0
  715. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  716. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  717. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  718. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  719. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  720. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  721. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  722. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  723. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  724. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  725. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -13,6 +13,8 @@ import { homedir as homedir3 } from "node:os";
13
13
  import { join as join11, resolve as resolve11 } from "node:path";
14
14
 
15
15
  // ../../../../lsp-daemon/dist/client.js
16
+ import { statSync as statSync5 } from "node:fs";
17
+ import { isAbsolute as isAbsolute6 } from "node:path";
16
18
  import { connect } from "node:net";
17
19
  import { AsyncLocalStorage } from "node:async_hooks";
18
20
  import { existsSync, realpathSync, statSync } from "node:fs";
@@ -42,8 +44,8 @@ import * as path from "node:path";
42
44
  import { fileURLToPath } from "node:url";
43
45
  import { statSync as statSync2 } from "node:fs";
44
46
  import { isAbsolute as isAbsolute2 } from "node:path";
45
- import { existsSync as existsSync10, realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
46
- import { basename as basename3, dirname as dirname8, join as join4, resolve as resolve7 } from "node:path";
47
+ import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync4 } from "node:fs";
48
+ import { basename as basename3, dirname as dirname10, join as join5, resolve as resolve8 } from "node:path";
47
49
  import { basename as basename2, extname } from "node:path";
48
50
  import { resolve as resolve6 } from "node:path";
49
51
  import { pathToFileURL as pathToFileURL3 } from "node:url";
@@ -62,32 +64,32 @@ import { createHash as createHash2 } from "node:crypto";
62
64
  import { dirname as dirname5, relative as relative4, resolve as resolve4 } from "node:path";
63
65
  import { existsSync as existsSync6, lstatSync as lstatSync4, readdirSync as readdirSync2 } from "node:fs";
64
66
  import { dirname as dirname6, resolve as resolve5 } from "node:path";
65
- import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
66
- import { dirname as dirname7 } from "node:path";
67
- import { existsSync as existsSync8, readFileSync as readFileSync5 } from "node:fs";
68
- import { existsSync as existsSync9 } from "node:fs";
69
- import { delimiter as delimiter3, join as join3 } from "node:path";
70
- import { existsSync as existsSync11, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
71
- import { join as join5, resolve as resolve8 } from "node:path";
67
+ import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
68
+ import { dirname as dirname7, join as join3 } from "node:path";
69
+ import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
70
+ import { dirname as dirname8 } from "node:path";
71
+ import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
72
+ import { existsSync as existsSync10 } from "node:fs";
73
+ import { delimiter as delimiter3, dirname as dirname9, isAbsolute as isAbsolute5, join as join4, resolve as resolve7 } from "node:path";
74
+ import { existsSync as existsSync12, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
75
+ import { join as join6, resolve as resolve9 } from "node:path";
72
76
  import { fileURLToPath as fileURLToPath3 } from "node:url";
73
77
  import { lstatSync as lstatSync6, readdirSync as readdirSync4 } from "node:fs";
74
- import { join as join6 } from "node:path";
75
- import { statSync as statSync5 } from "node:fs";
76
- import { isAbsolute as isAbsolute5 } from "node:path";
78
+ import { join as join7 } from "node:path";
79
+ import { readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
77
80
 
78
81
  class LspRequestContextParseError extends Error {
79
- code;
80
- name = "LspRequestContextParseError";
81
82
  constructor(code, message) {
82
83
  super(message);
83
84
  this.code = code;
85
+ this.name = "LspRequestContextParseError";
84
86
  }
85
87
  }
86
88
 
87
89
  class LspRequestContextUnavailableError extends Error {
88
- name = "LspRequestContextUnavailableError";
89
90
  constructor() {
90
91
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
92
+ this.name = "LspRequestContextUnavailableError";
91
93
  }
92
94
  }
93
95
  var storage = new AsyncLocalStorage;
@@ -113,18 +115,18 @@ function parseLspRequestContext(value) {
113
115
  const installDecisionsPath = stringField(value, "installDecisionsPath");
114
116
  const capabilities = capabilitiesField(value["capabilities"]);
115
117
  const canonical = canonicalCwd(cwd);
116
- for (const path2 of projectConfigPaths) {
117
- requireAbsolutePath(path2, "projectConfigPaths");
118
- const projectPath = canonicalizeExistingOrNearestAncestor(path2);
118
+ for (const path of projectConfigPaths) {
119
+ requireAbsolutePath(path, "projectConfigPaths");
120
+ const projectPath = canonicalizeExistingOrNearestAncestor(path);
119
121
  if (!isPathInside(canonical, projectPath)) {
120
- throw new LspRequestContextParseError("project_config_outside_cwd", `Project LSP config path must be inside cwd: ${path2}`);
122
+ throw new LspRequestContextParseError("project_config_outside_cwd", `Project LSP config path must be inside cwd: ${path}`);
121
123
  }
122
124
  }
123
125
  requireAbsolutePath(userConfigPath, "userConfigPath");
124
126
  requireAbsolutePath(installDecisionsPath, "installDecisionsPath");
125
127
  return {
126
128
  cwd: canonical,
127
- projectConfigPaths: projectConfigPaths.map((path2) => canonicalizeExistingOrNearestAncestor(path2)),
129
+ projectConfigPaths: projectConfigPaths.map((path) => canonicalizeExistingOrNearestAncestor(path)),
128
130
  userConfigPath,
129
131
  installDecisionsPath,
130
132
  capabilities
@@ -137,8 +139,8 @@ function canonicalCwd(cwd) {
137
139
  }
138
140
  return realpathSync(resolved);
139
141
  }
140
- function canonicalizeExistingOrNearestAncestor(path2) {
141
- let current = resolve(path2);
142
+ function canonicalizeExistingOrNearestAncestor(path) {
143
+ let current = resolve(path);
142
144
  const suffix = [];
143
145
  while (true) {
144
146
  try {
@@ -180,9 +182,9 @@ function stringArrayField(value, field) {
180
182
  }
181
183
  return fieldValue;
182
184
  }
183
- function requireAbsolutePath(path2, field) {
184
- if (!isAbsolute(path2)) {
185
- throw new LspRequestContextParseError("relative_path", `LSP request context.${field} must be absolute: ${path2}`);
185
+ function requireAbsolutePath(path, field) {
186
+ if (!isAbsolute(path)) {
187
+ throw new LspRequestContextParseError("relative_path", `LSP request context.${field} must be absolute: ${path}`);
186
188
  }
187
189
  }
188
190
  function isPathInside(parent, child) {
@@ -214,7 +216,6 @@ function isPlainRecord(value) {
214
216
  }
215
217
 
216
218
  class DaemonRequestError extends Error {
217
- requestWritten;
218
219
  constructor(message, requestWritten) {
219
220
  super(message);
220
221
  this.name = "DaemonRequestError";
@@ -237,7 +238,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
237
238
  }
238
239
 
239
240
  class DaemonRequestTimedOutError extends DaemonRequestError {
240
- timeoutMs;
241
241
  constructor(requestWritten, timeoutMs) {
242
242
  super("daemon request timed out", requestWritten);
243
243
  this.name = "DaemonRequestTimedOutError";
@@ -314,20 +314,18 @@ var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
314
314
  var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
315
315
 
316
316
  class InvalidRuntimeOverrideError extends Error {
317
- code = "invalid_runtime_override";
318
- reason;
319
317
  constructor(reason, message) {
320
318
  super(message);
319
+ this.code = "invalid_runtime_override";
321
320
  this.name = "InvalidRuntimeOverrideError";
322
321
  this.reason = reason;
323
322
  }
324
323
  }
325
324
 
326
325
  class InvalidDaemonVersionError extends Error {
327
- code = "invalid_daemon_version";
328
- version;
329
326
  constructor(version) {
330
327
  super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
328
+ this.code = "invalid_daemon_version";
331
329
  this.name = "InvalidDaemonVersionError";
332
330
  this.version = version;
333
331
  }
@@ -371,10 +369,9 @@ var requireFromHere = createRequire(import.meta.url);
371
369
  var MAX_SOCKET_PATH_LENGTH = 100;
372
370
 
373
371
  class InvalidDaemonDirectoryError extends Error {
374
- code = "invalid_daemon_directory";
375
- directory;
376
372
  constructor(directory) {
377
373
  super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
374
+ this.code = "invalid_daemon_directory";
378
375
  this.name = "InvalidDaemonDirectoryError";
379
376
  this.directory = directory;
380
377
  }
@@ -524,7 +521,7 @@ async function probeDaemon(paths, timeoutMs = PROBE_TIMEOUT_MS, signal) {
524
521
  return await pingDaemon(paths, token, timeoutMs, signal) !== null;
525
522
  }
526
523
  function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
527
- return new Promise((resolve22) => {
524
+ return new Promise((resolve) => {
528
525
  const socket = new Socket;
529
526
  let settled = false;
530
527
  let timer;
@@ -536,7 +533,7 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
536
533
  clearTimeout(timer);
537
534
  signal?.removeEventListener("abort", onAbort);
538
535
  socket.destroy();
539
- resolve22(value);
536
+ resolve(value);
540
537
  };
541
538
  const onAbort = () => finish(null);
542
539
  const decoder = createLineDecoder((message) => {
@@ -559,13 +556,17 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
559
556
  socket.connect(paths.socket);
560
557
  });
561
558
  }
562
- function spawnDaemonProcess(paths) {
559
+ function spawnDaemonProcess(paths, deps = {}) {
563
560
  mkdirSync2(dirname3(paths.log), { recursive: true });
564
561
  const logFd = openSync2(paths.log, "a");
565
562
  try {
566
- const child = spawn(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
563
+ const spawnDaemonChild = deps.spawn ?? spawn;
564
+ const executable = deps.resolveExecutable?.() ?? resolveDaemonNodeExecutable();
565
+ const child = spawnDaemonChild(executable, [paths.cliPath, "daemon"], {
567
566
  detached: true,
568
- stdio: ["ignore", logFd, logFd]
567
+ stdio: ["ignore", logFd, logFd],
568
+ windowsHide: true,
569
+ env: { ...process.env, BUN_BE_BUN: "1" }
569
570
  });
570
571
  child.once("spawn", () => closeSync2(logFd));
571
572
  child.once("error", (error) => {
@@ -595,7 +596,7 @@ function defaultEnsureDaemonDeps() {
595
596
  };
596
597
  }
597
598
  function sleepWithSignal(ms, signal) {
598
- return new Promise((resolve22) => {
599
+ return new Promise((resolve) => {
599
600
  let settled = false;
600
601
  const finish = () => {
601
602
  if (settled)
@@ -603,7 +604,7 @@ function sleepWithSignal(ms, signal) {
603
604
  settled = true;
604
605
  clearTimeout(timer);
605
606
  signal?.removeEventListener("abort", finish);
606
- resolve22();
607
+ resolve();
607
608
  };
608
609
  const timer = setTimeout(finish, ms);
609
610
  if (signal?.aborted) {
@@ -618,7 +619,7 @@ function awaitWithSignal(promise, signal) {
618
619
  return promise;
619
620
  if (signal.aborted)
620
621
  return Promise.reject(abortError(signal));
621
- return new Promise((resolve22, reject) => {
622
+ return new Promise((resolve, reject) => {
622
623
  let settled = false;
623
624
  const finish = (run) => {
624
625
  if (settled)
@@ -629,7 +630,7 @@ function awaitWithSignal(promise, signal) {
629
630
  };
630
631
  const onAbort = () => finish(() => reject(abortError(signal)));
631
632
  signal.addEventListener("abort", onAbort, { once: true });
632
- promise.then((value) => finish(() => resolve22(value)), (error) => finish(() => reject(error)));
633
+ promise.then((value) => finish(() => resolve(value)), (error) => finish(() => reject(error)));
633
634
  });
634
635
  }
635
636
  function throwIfAborted(signal) {
@@ -658,18 +659,18 @@ function parsePingResponse(message) {
658
659
  return null;
659
660
  if (!endpoint || typeof endpoint !== "object" || Array.isArray(endpoint))
660
661
  return null;
661
- const path2 = Reflect.get(endpoint, "path");
662
+ const path = Reflect.get(endpoint, "path");
662
663
  const kind = Reflect.get(endpoint, "kind");
663
- if (typeof path2 !== "string")
664
+ if (typeof path !== "string")
664
665
  return null;
665
666
  if (kind === "windows")
666
- return { pid, nonce, startedAt, endpoint: { kind, path: path2 } };
667
+ return { pid, nonce, startedAt, endpoint: { kind, path } };
667
668
  if (kind === "missing")
668
- return { pid, nonce, startedAt, endpoint: { kind, path: path2 } };
669
+ return { pid, nonce, startedAt, endpoint: { kind, path } };
669
670
  const dev = Reflect.get(endpoint, "dev");
670
671
  const ino = Reflect.get(endpoint, "ino");
671
672
  if (kind === "unix" && typeof dev === "number" && typeof ino === "number") {
672
- return { pid, nonce, startedAt, endpoint: { kind, path: path2, dev, ino } };
673
+ return { pid, nonce, startedAt, endpoint: { kind, path, dev, ino } };
673
674
  }
674
675
  return null;
675
676
  }
@@ -686,22 +687,15 @@ function effectiveExtension(filePath) {
686
687
  }
687
688
 
688
689
  class LspConnectionClosedError extends Error {
689
- serverId;
690
- root;
691
- name = "LspConnectionClosedError";
692
690
  constructor(serverId, root, message) {
693
691
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
694
692
  this.serverId = serverId;
695
693
  this.root = root;
694
+ this.name = "LspConnectionClosedError";
696
695
  }
697
696
  }
698
697
 
699
698
  class LspProcessExitedError extends Error {
700
- serverId;
701
- root;
702
- exitCode;
703
- stderrTail;
704
- name = "LspProcessExitedError";
705
699
  constructor(serverId, root, exitCode, stderrTail) {
706
700
  const stderrSuffix = stderrTail ? `
707
701
  stderr tail: ${stderrTail}` : "";
@@ -710,46 +704,59 @@ stderr tail: ${stderrTail}` : "";
710
704
  this.root = root;
711
705
  this.exitCode = exitCode;
712
706
  this.stderrTail = stderrTail;
707
+ this.name = "LspProcessExitedError";
713
708
  }
714
709
  }
715
710
 
716
711
  class LspRequestTimeoutError extends Error {
717
- method;
718
- stderrTail;
719
- name = "LspRequestTimeoutError";
720
712
  constructor(method, stderrTail) {
721
713
  const stderrSuffix = stderrTail ? `
722
714
  recent stderr: ${stderrTail}` : "";
723
715
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
724
716
  this.method = method;
725
717
  this.stderrTail = stderrTail;
718
+ this.name = "LspRequestTimeoutError";
726
719
  }
727
720
  }
728
721
 
729
722
  class LspInvalidPathError extends Error {
730
- name = "LspInvalidPathError";
723
+ constructor() {
724
+ super(...arguments);
725
+ this.name = "LspInvalidPathError";
726
+ }
731
727
  }
732
728
 
733
729
  class LspServerLookupError extends Error {
734
- lookup;
735
- name = "LspServerLookupError";
736
730
  constructor(message, lookup) {
737
731
  super(message);
738
732
  this.lookup = lookup;
733
+ this.name = "LspServerLookupError";
739
734
  }
740
735
  }
741
736
 
742
737
  class LspServerInitializingError extends Error {
743
- originalError;
744
- name = "LspServerInitializingError";
745
738
  constructor(originalError) {
746
739
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
747
740
  this.originalError = originalError;
741
+ this.name = "LspServerInitializingError";
748
742
  }
749
743
  }
750
744
 
751
745
  class LspProcessSpawnError extends Error {
752
- name = "LspProcessSpawnError";
746
+ constructor() {
747
+ super(...arguments);
748
+ this.name = "LspProcessSpawnError";
749
+ }
750
+ }
751
+
752
+ class LspClientRespawnBudgetExceededError extends Error {
753
+ constructor(serverId, root, retryLimit) {
754
+ super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
755
+ this.serverId = serverId;
756
+ this.root = root;
757
+ this.retryLimit = retryLimit;
758
+ this.name = "LspClientRespawnBudgetExceededError";
759
+ }
753
760
  }
754
761
  function isLspDeadConnectionError(err) {
755
762
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -762,6 +769,11 @@ function reportBestEffortCleanupError(operation, error, logger = writeCleanupErr
762
769
  const message = error instanceof Error ? error.message : String(error);
763
770
  logger(`[lsp] ignored ${operation} failure during cleanup: ${message}`);
764
771
  }
772
+ var realTimerProvider = {
773
+ now: () => Date.now(),
774
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
775
+ clearTimeout: (handle) => clearTimeout(handle)
776
+ };
765
777
  var DEFAULT_MAX_REFERENCES = 200;
766
778
  var DEFAULT_MAX_SYMBOLS = 200;
767
779
  var DEFAULT_MAX_DIAGNOSTICS = 200;
@@ -769,9 +781,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
769
781
  var REQUEST_TIMEOUT_MS = 15000;
770
782
  var INIT_TIMEOUT_MS = 60000;
771
783
  var IDLE_TIMEOUT_MS = 5 * 60000;
784
+ var MAX_RESIDENT_CLIENTS = 6;
772
785
  var REAPER_INTERVAL_MS = 60000;
773
786
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
774
787
  var STOP_SIGKILL_GRACE_MS = 1000;
788
+ var CLIENT_RESPAWN_RETRY_LIMIT = 2;
789
+ var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
775
790
  var HEADER_SEPARATOR2 = `\r
776
791
  \r
777
792
  `;
@@ -781,20 +796,31 @@ var METHOD_NOT_FOUND = -32601;
781
796
  var INTERNAL_ERROR = -32603;
782
797
 
783
798
  class JsonRpcConnection {
784
- reader;
785
- writer;
786
- pendingRequests = new Map;
787
- notificationHandlers = new Map;
788
- requestHandlers = new Map;
789
- closeHandlers = [];
790
- errorHandlers = [];
791
- inputBuffer = Buffer.alloc(0);
792
- nextRequestId = 1;
793
- listening = false;
794
- disposed = false;
795
799
  constructor(reader, writer) {
796
800
  this.reader = reader;
797
801
  this.writer = writer;
802
+ this.pendingRequests = new Map;
803
+ this.notificationHandlers = new Map;
804
+ this.requestHandlers = new Map;
805
+ this.closeHandlers = [];
806
+ this.errorHandlers = [];
807
+ this.inputBuffer = Buffer.alloc(0);
808
+ this.nextRequestId = 1;
809
+ this.listening = false;
810
+ this.disposed = false;
811
+ this.handleData = (chunk) => {
812
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
813
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
814
+ this.drainInputBuffer();
815
+ };
816
+ this.handleClose = () => {
817
+ for (const handler of this.closeHandlers) {
818
+ handler();
819
+ }
820
+ };
821
+ this.handleStreamError = (error) => {
822
+ this.emitError(error);
823
+ };
798
824
  }
799
825
  listen() {
800
826
  if (this.listening)
@@ -829,7 +855,8 @@ class JsonRpcConnection {
829
855
  let cancelAfterWrite = false;
830
856
  let settled = false;
831
857
  const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
832
- const responsePromise = new Promise((resolve22, reject) => {
858
+ let rejectAfterCancelWrite;
859
+ const responsePromise = new Promise((resolve, reject) => {
833
860
  const cleanup = () => {
834
861
  options.signal?.removeEventListener("abort", onAbort);
835
862
  };
@@ -840,22 +867,26 @@ class JsonRpcConnection {
840
867
  this.pendingRequests.delete(key);
841
868
  cleanup();
842
869
  const rejectCancelled = () => reject(abortError2(options.signal));
870
+ rejectAfterCancelWrite = async () => {
871
+ try {
872
+ await writeCancel();
873
+ } catch (error) {
874
+ this.emitError(toError(error));
875
+ }
876
+ rejectCancelled();
877
+ };
843
878
  if (!requestWritten) {
844
879
  cancelAfterWrite = true;
845
- rejectCancelled();
846
880
  return;
847
881
  }
848
- writeCancel().then(rejectCancelled, (error) => {
849
- this.emitError(toError(error));
850
- rejectCancelled();
851
- });
882
+ rejectAfterCancelWrite();
852
883
  };
853
884
  const onAbort = () => settleCancel();
854
885
  this.pendingRequests.set(key, {
855
886
  resolve(result) {
856
887
  settled = true;
857
888
  cleanup();
858
- resolve22(result);
889
+ resolve(result);
859
890
  },
860
891
  reject(error) {
861
892
  settled = true;
@@ -876,7 +907,7 @@ class JsonRpcConnection {
876
907
  await this.writeMessage(message);
877
908
  requestWritten = true;
878
909
  if (cancelAfterWrite)
879
- await writeCancel();
910
+ await rejectAfterCancelWrite?.();
880
911
  } catch (error) {
881
912
  if (settled)
882
913
  return responsePromise;
@@ -915,19 +946,6 @@ class JsonRpcConnection {
915
946
  this.notificationHandlers.clear();
916
947
  this.requestHandlers.clear();
917
948
  }
918
- handleData = (chunk) => {
919
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
920
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
921
- this.drainInputBuffer();
922
- };
923
- handleClose = () => {
924
- for (const handler of this.closeHandlers) {
925
- handler();
926
- }
927
- };
928
- handleStreamError = (error) => {
929
- this.emitError(error);
930
- };
931
949
  drainInputBuffer() {
932
950
  while (true) {
933
951
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
@@ -1027,13 +1045,13 @@ class JsonRpcConnection {
1027
1045
  const payload = `Content-Length: ${Buffer.byteLength(body, "utf8")}\r
1028
1046
  \r
1029
1047
  ${body}`;
1030
- return new Promise((resolve22, reject) => {
1048
+ return new Promise((resolve, reject) => {
1031
1049
  this.writer.write(payload, (error) => {
1032
1050
  if (error) {
1033
1051
  reject(error);
1034
1052
  return;
1035
1053
  }
1036
- resolve22();
1054
+ resolve();
1037
1055
  });
1038
1056
  });
1039
1057
  }
@@ -1115,9 +1133,9 @@ function validateCwd(cwd) {
1115
1133
  }
1116
1134
  }
1117
1135
  function wrap(proc) {
1118
- const exitedPromise = new Promise((resolve22) => {
1119
- proc.once("close", (code) => resolve22(code ?? 0));
1120
- proc.once("error", () => resolve22(1));
1136
+ const exitedPromise = new Promise((resolve) => {
1137
+ proc.once("close", (code) => resolve(code ?? 0));
1138
+ proc.once("error", () => resolve(1));
1121
1139
  });
1122
1140
  if (!proc.stdin || !proc.stdout || !proc.stderr) {
1123
1141
  throw new LspProcessSpawnError("Spawned process is missing one of stdin/stdout/stderr pipes");
@@ -1267,33 +1285,29 @@ function isPosition(value) {
1267
1285
  }
1268
1286
 
1269
1287
  class LspClientNotStartedError extends Error {
1270
- serverId;
1271
- root;
1272
- name = "LspClientNotStartedError";
1273
1288
  constructor(serverId, root) {
1274
1289
  super("LSP client not started");
1275
1290
  this.serverId = serverId;
1276
1291
  this.root = root;
1292
+ this.name = "LspClientNotStartedError";
1277
1293
  }
1278
1294
  }
1279
1295
 
1280
1296
  class LspClientTransport {
1281
- root;
1282
- server;
1283
- proc = null;
1284
- connection = null;
1285
- stderrBuffer = [];
1286
- processExited = false;
1287
- diagnosticsStore = new Map;
1288
- requestTimeoutMs;
1289
- initializeTimeoutMs;
1290
- workspaceApplyEditHandler = null;
1291
- diagnosticPullSupported = false;
1292
- constructor(root, server2, timeouts = {}) {
1297
+ constructor(root, server, timeouts = {}) {
1293
1298
  this.root = root;
1294
- this.server = server2;
1299
+ this.server = server;
1300
+ this.proc = null;
1301
+ this.connection = null;
1302
+ this.stderrBuffer = [];
1303
+ this.processExited = false;
1304
+ this.diagnosticsStore = new Map;
1305
+ this.workspaceApplyEditHandler = null;
1306
+ this.diagnosticPullSupported = false;
1307
+ this.documentFormattingSupported = false;
1295
1308
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
1296
1309
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
1310
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
1297
1311
  }
1298
1312
  pid() {
1299
1313
  return this.proc?.pid;
@@ -1313,6 +1327,12 @@ class LspClientTransport {
1313
1327
  isDiagnosticPullSupported() {
1314
1328
  return this.diagnosticPullSupported;
1315
1329
  }
1330
+ setDocumentFormattingSupported(supported) {
1331
+ this.documentFormattingSupported = supported;
1332
+ }
1333
+ isDocumentFormattingSupported() {
1334
+ return this.documentFormattingSupported;
1335
+ }
1316
1336
  handlePublishDiagnostics(params) {
1317
1337
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
1318
1338
  }
@@ -1388,7 +1408,7 @@ class LspClientTransport {
1388
1408
  const options = args[1];
1389
1409
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
1390
1410
  const timeoutController = new AbortController;
1391
- const timeoutHandle = setTimeout(() => {
1411
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
1392
1412
  const stderrTail = this.stderrBuffer.slice(-5).join(`
1393
1413
  `);
1394
1414
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -1407,7 +1427,7 @@ class LspClientTransport {
1407
1427
  }
1408
1428
  throw error;
1409
1429
  } finally {
1410
- clearTimeout(timeoutHandle);
1430
+ this.timerProvider.clearTimeout(timeoutHandle);
1411
1431
  combinedSignal.dispose();
1412
1432
  }
1413
1433
  }
@@ -1458,8 +1478,8 @@ class LspClientTransport {
1458
1478
  try {
1459
1479
  proc.kill();
1460
1480
  let timeoutId;
1461
- const timeoutPromise = new Promise((resolve22) => {
1462
- timeoutId = setTimeout(resolve22, STOP_HARD_KILL_TIMEOUT_MS);
1481
+ const timeoutPromise = new Promise((resolve) => {
1482
+ timeoutId = setTimeout(resolve, STOP_HARD_KILL_TIMEOUT_MS);
1463
1483
  });
1464
1484
  await Promise.race([
1465
1485
  proc.exited.then(() => {
@@ -1475,7 +1495,7 @@ class LspClientTransport {
1475
1495
  proc.kill("SIGKILL");
1476
1496
  await Promise.race([
1477
1497
  proc.exited,
1478
- new Promise((resolve22) => setTimeout(resolve22, STOP_SIGKILL_GRACE_MS))
1498
+ new Promise((resolve) => setTimeout(resolve, STOP_SIGKILL_GRACE_MS))
1479
1499
  ]);
1480
1500
  } catch (error) {
1481
1501
  reportBestEffortCleanupError("hard process kill", error instanceof Error ? error : String(error));
@@ -1524,6 +1544,14 @@ function supportsDiagnosticPull(capabilities) {
1524
1544
  return false;
1525
1545
  return Object.hasOwn(capabilities, "diagnosticProvider");
1526
1546
  }
1547
+ function supportsDocumentFormatting(capabilities) {
1548
+ if (capabilities === undefined)
1549
+ return false;
1550
+ const provider = capabilities.documentFormattingProvider;
1551
+ if (provider === undefined || provider === null || provider === false)
1552
+ return false;
1553
+ return provider === true || typeof provider === "object";
1554
+ }
1527
1555
 
1528
1556
  class LspClientConnection extends LspClientTransport {
1529
1557
  async initialize() {
@@ -1540,6 +1568,7 @@ class LspClientConnection extends LspClientTransport {
1540
1568
  references: {},
1541
1569
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
1542
1570
  publishDiagnostics: {},
1571
+ formatting: { dynamicRegistration: false },
1543
1572
  rename: {
1544
1573
  prepareSupport: true,
1545
1574
  prepareSupportDefaultBehavior: 1
@@ -1581,6 +1610,7 @@ class LspClientConnection extends LspClientTransport {
1581
1610
  initializationOptions: this.server.initialization
1582
1611
  }, { timeoutMs: this.initializeTimeoutMs });
1583
1612
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
1613
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
1584
1614
  await this.sendNotification("initialized", {});
1585
1615
  await this.sendNotification("workspace/didChangeConfiguration", {
1586
1616
  settings: { json: { validate: { enable: true } } }
@@ -1767,6 +1797,17 @@ function canonicalPath(filePath) {
1767
1797
  return absolute;
1768
1798
  }
1769
1799
  }
1800
+ function normalizeDocumentUri(uri) {
1801
+ let decoded = uri;
1802
+ try {
1803
+ decoded = decodeURIComponent(uri);
1804
+ } catch {
1805
+ decoded = uri;
1806
+ }
1807
+ if (process.platform !== "win32")
1808
+ return decoded;
1809
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1810
+ }
1770
1811
  function isSameOrDescendant(candidate, parent) {
1771
1812
  const suffix = relative2(parent, candidate);
1772
1813
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1777,30 +1818,31 @@ function movedPath(candidate, oldPath, newPath) {
1777
1818
  }
1778
1819
 
1779
1820
  class WorkspaceDocumentState {
1780
- sendNotification;
1781
- clearDiagnostics;
1782
- openDocuments = new Map;
1783
- openByUri = new Map;
1784
- openPromises = new Map;
1785
- now;
1786
- versionlessPublishQuiescenceMs;
1787
1821
  constructor(sendNotification, clearDiagnostics, options = {}) {
1788
1822
  this.sendNotification = sendNotification;
1789
1823
  this.clearDiagnostics = clearDiagnostics;
1790
- this.now = options.now ?? (() => Date.now());
1824
+ this.openDocuments = new Map;
1825
+ this.openByUri = new Map;
1826
+ this.openPromises = new Map;
1827
+ this.timerProvider = options.timerProvider ?? {
1828
+ now: options.now ?? (() => Date.now()),
1829
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1830
+ clearTimeout: (handle) => clearTimeout(handle)
1831
+ };
1832
+ this.now = () => this.timerProvider.now();
1791
1833
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1792
1834
  }
1793
1835
  async openFile(filePath) {
1794
- const path2 = canonicalPath(filePath);
1795
- const existingOpen = this.openPromises.get(path2);
1836
+ const path = canonicalPath(filePath);
1837
+ const existingOpen = this.openPromises.get(path);
1796
1838
  if (existingOpen) {
1797
1839
  await existingOpen;
1798
- return this.openFile(path2);
1840
+ return this.openFile(path);
1799
1841
  }
1800
- const text = readFileSync2(path2, "utf-8");
1801
- const existing = this.openDocuments.get(path2);
1842
+ const text = readFileSync2(path, "utf-8");
1843
+ const existing = this.openDocuments.get(path);
1802
1844
  if (!existing)
1803
- return this.openDocumentSingleFlight(path2, text);
1845
+ return this.openDocumentSingleFlight(path, text);
1804
1846
  if (existing.text === text)
1805
1847
  return;
1806
1848
  await this.changeDocument(existing, text);
@@ -1809,7 +1851,7 @@ class WorkspaceDocumentState {
1809
1851
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1810
1852
  }
1811
1853
  getStoredDiagnostics(uri) {
1812
- const state = this.openByUri.get(uri);
1854
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1813
1855
  if (!state)
1814
1856
  return [];
1815
1857
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1831,13 +1873,13 @@ class WorkspaceDocumentState {
1831
1873
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1832
1874
  }
1833
1875
  getPullCache(snapshot) {
1834
- const state = this.openByUri.get(snapshot.uri);
1876
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1835
1877
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1836
1878
  return null;
1837
1879
  return state.pullCache;
1838
1880
  }
1839
1881
  recordPullDiagnostics(snapshot, report) {
1840
- const state = this.openByUri.get(snapshot.uri);
1882
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1841
1883
  if (!state)
1842
1884
  return;
1843
1885
  state.pullCache = {
@@ -1847,7 +1889,7 @@ class WorkspaceDocumentState {
1847
1889
  };
1848
1890
  }
1849
1891
  recordPublishedDiagnostics(params) {
1850
- const state = this.openByUri.get(params.uri);
1892
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1851
1893
  if (!state)
1852
1894
  return;
1853
1895
  state.publishGeneration += 1;
@@ -1861,7 +1903,7 @@ class WorkspaceDocumentState {
1861
1903
  this.notifyWaiters(state);
1862
1904
  }
1863
1905
  resolvePushDiagnostics(snapshot) {
1864
- const state = this.openByUri.get(snapshot.uri);
1906
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1865
1907
  if (!state?.lastPublish)
1866
1908
  return { status: "missing" };
1867
1909
  const publish = state.lastPublish;
@@ -1875,27 +1917,29 @@ class WorkspaceDocumentState {
1875
1917
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1876
1918
  }
1877
1919
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1878
- const state = this.openByUri.get(snapshot.uri);
1920
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1879
1921
  if (!state || timeoutMs <= 0)
1880
1922
  return Promise.resolve();
1923
+ if (state.publishGeneration !== snapshot.publishGeneration)
1924
+ return Promise.resolve();
1881
1925
  return new Promise((resolveActivity) => {
1882
1926
  let settled = false;
1883
1927
  const finish = () => {
1884
1928
  if (settled)
1885
1929
  return;
1886
1930
  settled = true;
1887
- clearTimeout(timer);
1931
+ this.timerProvider.clearTimeout(timer);
1888
1932
  state.waiters.delete(finish);
1889
1933
  resolveActivity();
1890
1934
  };
1891
- const timer = setTimeout(finish, timeoutMs);
1935
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1892
1936
  if (typeof timer.unref === "function")
1893
1937
  timer.unref();
1894
1938
  state.waiters.add(finish);
1895
1939
  });
1896
1940
  }
1897
1941
  validateVersions(operations) {
1898
- const versions = new Map([...this.openDocuments].map(([path2, state]) => [path2, state.version]));
1942
+ const versions = new Map([...this.openDocuments].map(([path, state]) => [path, state.version]));
1899
1943
  for (const operation of operations) {
1900
1944
  if (operation.kind === "text") {
1901
1945
  const current = versions.get(operation.path);
@@ -1911,17 +1955,17 @@ class WorkspaceDocumentState {
1911
1955
  continue;
1912
1956
  }
1913
1957
  if (operation.kind === "rename") {
1914
- const moved = [...versions].filter(([path2]) => isSameOrDescendant(path2, operation.oldPath));
1915
- for (const [path2] of moved)
1916
- versions.delete(path2);
1917
- for (const [path2] of moved)
1918
- versions.set(movedPath(path2, operation.oldPath, operation.newPath), 1);
1958
+ const moved = [...versions].filter(([path]) => isSameOrDescendant(path, operation.oldPath));
1959
+ for (const [path] of moved)
1960
+ versions.delete(path);
1961
+ for (const [path] of moved)
1962
+ versions.set(movedPath(path, operation.oldPath, operation.newPath), 1);
1919
1963
  continue;
1920
1964
  }
1921
1965
  if (operation.kind === "delete") {
1922
- for (const path2 of [...versions.keys()]) {
1923
- if (isSameOrDescendant(path2, operation.path))
1924
- versions.delete(path2);
1966
+ for (const path of [...versions.keys()]) {
1967
+ if (isSameOrDescendant(path, operation.path))
1968
+ versions.delete(path);
1925
1969
  }
1926
1970
  continue;
1927
1971
  }
@@ -1965,8 +2009,8 @@ class WorkspaceDocumentState {
1965
2009
  for (const state of moved)
1966
2010
  await this.closeDocument(state);
1967
2011
  for (const state of moved) {
1968
- const path2 = movedPath(state.path, mutation.oldPath, mutation.newPath);
1969
- await this.openDocumentSingleFlight(path2, readFileSync2(path2, "utf-8"));
2012
+ const path = movedPath(state.path, mutation.oldPath, mutation.newPath);
2013
+ await this.openDocumentSingleFlight(path, readFileSync2(path, "utf-8"));
1970
2014
  }
1971
2015
  if (moved.length === 0) {
1972
2016
  watched.push({ uri: pathToFileURL2(mutation.oldPath).href, type: 3 });
@@ -1980,31 +2024,31 @@ class WorkspaceDocumentState {
1980
2024
  if (removed.length === 0)
1981
2025
  watched.push({ uri: pathToFileURL2(mutation.path).href, type: 3 });
1982
2026
  }
1983
- async openDocumentSingleFlight(path2, text) {
1984
- const existing = this.openPromises.get(path2);
2027
+ async openDocumentSingleFlight(path, text) {
2028
+ const existing = this.openPromises.get(path);
1985
2029
  if (existing)
1986
2030
  return existing;
1987
2031
  const open = (async () => {
1988
2032
  const state = {
1989
- path: path2,
1990
- uri: pathToFileURL2(path2).href,
1991
- languageId: getLanguageId(effectiveExtension(path2)),
2033
+ path,
2034
+ uri: pathToFileURL2(path).href,
2035
+ languageId: getLanguageId(effectiveExtension(path)),
1992
2036
  text,
1993
2037
  version: 1,
1994
2038
  generation: 1,
1995
2039
  publishGeneration: 0,
1996
2040
  waiters: new Set
1997
2041
  };
1998
- this.openDocuments.set(path2, state);
1999
- this.openByUri.set(state.uri, state);
2042
+ this.openDocuments.set(path, state);
2043
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
2000
2044
  this.notifyWaiters(state);
2001
2045
  await this.sendNotification("textDocument/didOpen", {
2002
2046
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
2003
2047
  });
2004
2048
  })().finally(() => {
2005
- this.openPromises.delete(path2);
2049
+ this.openPromises.delete(path);
2006
2050
  });
2007
- this.openPromises.set(path2, open);
2051
+ this.openPromises.set(path, open);
2008
2052
  return open;
2009
2053
  }
2010
2054
  async changeDocument(state, text) {
@@ -2021,7 +2065,7 @@ class WorkspaceDocumentState {
2021
2065
  }
2022
2066
  async closeDocument(state) {
2023
2067
  this.openDocuments.delete(state.path);
2024
- this.openByUri.delete(state.uri);
2068
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
2025
2069
  this.clearDiagnostics(state.uri);
2026
2070
  this.notifyWaiters(state);
2027
2071
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -2040,13 +2084,11 @@ function workspaceApplyEditConcurrentFailureReason(phase) {
2040
2084
  }
2041
2085
 
2042
2086
  class WorkspaceEditPathError extends Error {
2043
- path;
2044
- detail;
2045
- name = "WorkspaceEditPathError";
2046
- constructor(path2, detail) {
2047
- super(`${detail}: ${path2}`);
2048
- this.path = path2;
2087
+ constructor(path, detail) {
2088
+ super(`${detail}: ${path}`);
2089
+ this.path = path;
2049
2090
  this.detail = detail;
2091
+ this.name = "WorkspaceEditPathError";
2050
2092
  }
2051
2093
  }
2052
2094
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -2108,26 +2150,26 @@ function uriToCanonicalWorkspacePath(uri, workspaceRoot) {
2108
2150
  return { success: false, error: `${requestedPath}: ${detail}` };
2109
2151
  }
2110
2152
  }
2111
- function snapshotPath(path2, includeChildren) {
2112
- if (!existsSync4(path2))
2153
+ function snapshotPath(path, includeChildren) {
2154
+ if (!existsSync4(path))
2113
2155
  return { kind: "missing" };
2114
- const stats = lstatSync2(path2);
2156
+ const stats = lstatSync2(path);
2115
2157
  if (stats.isFile())
2116
- return { kind: "file", content: readFileSync3(path2, "utf-8") };
2158
+ return { kind: "file", content: readFileSync3(path, "utf-8") };
2117
2159
  if (stats.isDirectory()) {
2118
- return includeChildren ? { kind: "directory", children: readdirSync(path2).sort() } : { kind: "directory" };
2160
+ return includeChildren ? { kind: "directory", children: readdirSync(path).sort() } : { kind: "directory" };
2119
2161
  }
2120
- throw new WorkspaceEditPathError(path2, "unsupported filesystem entry");
2162
+ throw new WorkspaceEditPathError(path, "unsupported filesystem entry");
2121
2163
  }
2122
2164
  var DEFAULT_IO = {
2123
- writeFile(path2, content) {
2124
- writeFileSync(path2, content, "utf-8");
2165
+ writeFile(path, content) {
2166
+ writeFileSync(path, content, "utf-8");
2125
2167
  },
2126
2168
  rename(oldPath, newPath) {
2127
2169
  renameSync(oldPath, newPath);
2128
2170
  },
2129
- remove(path2, recursive) {
2130
- rmSync(path2, { recursive, force: false });
2171
+ remove(path, recursive) {
2172
+ rmSync(path, { recursive, force: false });
2131
2173
  }
2132
2174
  };
2133
2175
  function snapshotsEqual(expected, actual) {
@@ -2140,8 +2182,8 @@ function snapshotsEqual(expected, actual) {
2140
2182
  }
2141
2183
  return true;
2142
2184
  }
2143
- function liveSnapshot(path2, expected) {
2144
- return snapshotPath(path2, expected.kind === "directory" && expected.children !== undefined);
2185
+ function liveSnapshot(path, expected) {
2186
+ return snapshotPath(path, expected.kind === "directory" && expected.children !== undefined);
2145
2187
  }
2146
2188
  function firstOperationIndex(plan) {
2147
2189
  return plan.operations[0]?.changeIndex ?? 0;
@@ -2162,28 +2204,28 @@ function failedCommit(plan, failure) {
2162
2204
  };
2163
2205
  }
2164
2206
  function verifySnapshots(plan) {
2165
- for (const [path2, expected] of plan.snapshots) {
2207
+ for (const [path, expected] of plan.snapshots) {
2166
2208
  let actual;
2167
2209
  try {
2168
- actual = liveSnapshot(path2, expected);
2210
+ actual = liveSnapshot(path, expected);
2169
2211
  } catch (error) {
2170
- const changeIndex = plan.firstChangeByPath.get(path2) ?? firstOperationIndex(plan);
2212
+ const changeIndex = plan.firstChangeByPath.get(path) ?? firstOperationIndex(plan);
2171
2213
  const detail = error instanceof Error ? error.message : String(error);
2172
- return failedCommit(plan, { message: `cannot verify snapshot for ${path2}: ${detail}`, changeIndex });
2214
+ return failedCommit(plan, { message: `cannot verify snapshot for ${path}: ${detail}`, changeIndex });
2173
2215
  }
2174
2216
  if (!snapshotsEqual(expected, actual)) {
2175
- const changeIndex = plan.firstChangeByPath.get(path2) ?? firstOperationIndex(plan);
2176
- return failedCommit(plan, { message: `workspace state changed before commit: ${path2}`, changeIndex });
2217
+ const changeIndex = plan.firstChangeByPath.get(path) ?? firstOperationIndex(plan);
2218
+ return failedCommit(plan, { message: `workspace state changed before commit: ${path}`, changeIndex });
2177
2219
  }
2178
2220
  }
2179
2221
  return null;
2180
2222
  }
2181
- function addModifiedPath(paths, path2) {
2182
- if (!paths.includes(path2))
2183
- paths.push(path2);
2223
+ function addModifiedPath(paths, path) {
2224
+ if (!paths.includes(path))
2225
+ paths.push(path);
2184
2226
  }
2185
- function reportedPath(plan, path2) {
2186
- return plan.reportedPathByCanonical.get(path2) ?? path2;
2227
+ function reportedPath(plan, path) {
2228
+ return plan.reportedPathByCanonical.get(path) ?? path;
2187
2229
  }
2188
2230
  function changedPathsForMutation(mutation) {
2189
2231
  return mutation.kind === "rename" ? [mutation.oldPath, mutation.newPath] : [mutation.path];
@@ -2191,8 +2233,8 @@ function changedPathsForMutation(mutation) {
2191
2233
  function mutationDelta(operations) {
2192
2234
  const changedPaths = new Set;
2193
2235
  for (const operation of operations) {
2194
- for (const path2 of changedPathsForMutation(operation))
2195
- changedPaths.add(path2);
2236
+ for (const path of changedPathsForMutation(operation))
2237
+ changedPaths.add(path);
2196
2238
  }
2197
2239
  return { operations, changedPaths: [...changedPaths].sort() };
2198
2240
  }
@@ -2332,13 +2374,11 @@ function canonicalFingerprint(operations) {
2332
2374
  }
2333
2375
 
2334
2376
  class WorkspaceEditValidationError extends Error {
2335
- changeIndex;
2336
- detail;
2337
- name = "WorkspaceEditValidationError";
2338
2377
  constructor(changeIndex, detail) {
2339
2378
  super(`change ${changeIndex}: ${detail}`);
2340
2379
  this.changeIndex = changeIndex;
2341
2380
  this.detail = detail;
2381
+ this.name = "WorkspaceEditValidationError";
2342
2382
  }
2343
2383
  }
2344
2384
  function isRecord3(value) {
@@ -2420,14 +2460,14 @@ function parseSinglePathResource(input, kind) {
2420
2460
  return;
2421
2461
  }
2422
2462
  if (kind === "create") {
2423
- const options2 = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
2463
+ const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
2424
2464
  target.operations.push({
2425
2465
  kind,
2426
2466
  changeIndex,
2427
2467
  path: resolvedPath.path,
2428
2468
  reportedPath: resolvedPath.requestedPath,
2429
- overwrite: options2["overwrite"] ?? false,
2430
- ignoreIfExists: options2["ignoreIfExists"] ?? false,
2469
+ overwrite: options["overwrite"] ?? false,
2470
+ ignoreIfExists: options["ignoreIfExists"] ?? false,
2431
2471
  followedSymbolicLink: resolvedPath.followedSymbolicLink
2432
2472
  });
2433
2473
  return;
@@ -2676,12 +2716,12 @@ function isSameOrDescendant2(candidate, parent) {
2676
2716
  const relativePath = relative4(parent, candidate);
2677
2717
  return relativePath === "" || !relativePath.startsWith("..") && relativePath !== "..";
2678
2718
  }
2679
- function removeVirtualSubtree(virtual, path2) {
2719
+ function removeVirtualSubtree(virtual, path) {
2680
2720
  for (const candidate of [...virtual.keys()]) {
2681
- if (isSameOrDescendant2(candidate, path2))
2721
+ if (isSameOrDescendant2(candidate, path))
2682
2722
  virtual.delete(candidate);
2683
2723
  }
2684
- virtual.set(path2, { kind: "missing" });
2724
+ virtual.set(path, { kind: "missing" });
2685
2725
  }
2686
2726
  function moveVirtualSubtree(virtual, oldPath, newPath) {
2687
2727
  const moved = [...virtual.entries()].filter(([candidate]) => isSameOrDescendant2(candidate, oldPath));
@@ -2692,16 +2732,16 @@ function moveVirtualSubtree(virtual, oldPath, newPath) {
2692
2732
  virtual.set(suffix === "" ? newPath : resolve4(newPath, suffix), entry);
2693
2733
  }
2694
2734
  }
2695
- function virtualDirectoryHasChildren(virtual, path2) {
2735
+ function virtualDirectoryHasChildren(virtual, path) {
2696
2736
  for (const [candidate, entry] of virtual) {
2697
- if (candidate !== path2 && entry.kind !== "missing" && isSameOrDescendant2(candidate, path2))
2737
+ if (candidate !== path && entry.kind !== "missing" && isSameOrDescendant2(candidate, path))
2698
2738
  return true;
2699
2739
  }
2700
2740
  return false;
2701
2741
  }
2702
- function requireVirtualParent(virtual, path2, changeIndex) {
2703
- if (virtual.get(dirname5(path2))?.kind !== "directory") {
2704
- throw new WorkspaceEditValidationError(changeIndex, `parent directory does not exist for ${path2}`);
2742
+ function requireVirtualParent(virtual, path, changeIndex) {
2743
+ if (virtual.get(dirname5(path))?.kind !== "directory") {
2744
+ throw new WorkspaceEditValidationError(changeIndex, `parent directory does not exist for ${path}`);
2705
2745
  }
2706
2746
  }
2707
2747
  function simulateOperations(parsed, snapshots) {
@@ -2820,10 +2860,9 @@ function simulateDelete(operation, virtual) {
2820
2860
  }
2821
2861
 
2822
2862
  class WorkspaceSnapshotBuilder {
2823
- workspaceRoot;
2824
- snapshots = new Map;
2825
2863
  constructor(workspaceRoot) {
2826
2864
  this.workspaceRoot = workspaceRoot;
2865
+ this.snapshots = new Map;
2827
2866
  }
2828
2867
  build(operations) {
2829
2868
  this.add(this.workspaceRoot, false);
@@ -2844,21 +2883,21 @@ class WorkspaceSnapshotBuilder {
2844
2883
  }
2845
2884
  return this.snapshots;
2846
2885
  }
2847
- add(path2, includeChildren) {
2848
- let candidate = path2;
2886
+ add(path, includeChildren) {
2887
+ let candidate = path;
2849
2888
  while (true) {
2850
2889
  const existing = this.snapshots.get(candidate);
2851
2890
  if (existing === undefined || includeChildren && existing.kind === "directory" && existing.children === undefined) {
2852
- this.snapshots.set(candidate, snapshotPath(candidate, includeChildren && candidate === path2));
2891
+ this.snapshots.set(candidate, snapshotPath(candidate, includeChildren && candidate === path));
2853
2892
  }
2854
2893
  if (candidate === this.workspaceRoot)
2855
2894
  break;
2856
2895
  candidate = dirname6(candidate);
2857
2896
  }
2858
- if (!includeChildren || !existsSync6(path2) || !lstatSync4(path2).isDirectory())
2897
+ if (!includeChildren || !existsSync6(path) || !lstatSync4(path).isDirectory())
2859
2898
  return;
2860
- for (const child of readdirSync2(path2))
2861
- this.add(resolve5(path2, child), true);
2899
+ for (const child of readdirSync2(path))
2900
+ this.add(resolve5(path, child), true);
2862
2901
  }
2863
2902
  }
2864
2903
  function snapshotOperations(operations, workspaceRoot) {
@@ -2866,8 +2905,10 @@ function snapshotOperations(operations, workspaceRoot) {
2866
2905
  }
2867
2906
 
2868
2907
  class PlanPathIndex {
2869
- firstChangeByPath = new Map;
2870
- reportedPathByCanonical = new Map;
2908
+ constructor() {
2909
+ this.firstChangeByPath = new Map;
2910
+ this.reportedPathByCanonical = new Map;
2911
+ }
2871
2912
  build(operations) {
2872
2913
  for (const operation of operations) {
2873
2914
  switch (operation.kind) {
@@ -2883,11 +2924,11 @@ class PlanPathIndex {
2883
2924
  }
2884
2925
  }
2885
2926
  }
2886
- add(path2, reportedPath2, changeIndex) {
2887
- if (!this.firstChangeByPath.has(path2))
2888
- this.firstChangeByPath.set(path2, changeIndex);
2889
- if (!this.reportedPathByCanonical.has(path2))
2890
- this.reportedPathByCanonical.set(path2, reportedPath2);
2927
+ add(path, reportedPath, changeIndex) {
2928
+ if (!this.firstChangeByPath.has(path))
2929
+ this.firstChangeByPath.set(path, changeIndex);
2930
+ if (!this.reportedPathByCanonical.has(path))
2931
+ this.reportedPathByCanonical.set(path, reportedPath);
2891
2932
  }
2892
2933
  }
2893
2934
  function fingerprintWorkspaceEdit(edit, workspaceRoot) {
@@ -2954,14 +2995,11 @@ function isRecord4(value) {
2954
2995
  }
2955
2996
 
2956
2997
  class WorkspaceMutationController {
2957
- workspaceRoot;
2958
- documents;
2959
- activeLease = null;
2960
- nextLeaseId = 1;
2961
- io;
2962
2998
  constructor(workspaceRoot, documents) {
2963
2999
  this.workspaceRoot = workspaceRoot;
2964
3000
  this.documents = documents;
3001
+ this.activeLease = null;
3002
+ this.nextLeaseId = 1;
2965
3003
  }
2966
3004
  setIo(io) {
2967
3005
  this.io = io;
@@ -3000,15 +3038,15 @@ class WorkspaceMutationController {
3000
3038
  };
3001
3039
  }
3002
3040
  lease.phase = "applying";
3003
- lease.applyCompletion = new Promise((resolve62) => {
3004
- lease.resolveApply = resolve62;
3041
+ lease.applyCompletion = new Promise((resolve) => {
3042
+ lease.resolveApply = resolve;
3005
3043
  });
3006
3044
  const edit = isRecord4(params) ? params["edit"] : undefined;
3007
- const record2 = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
3008
- lease.serverApply = record2;
3045
+ const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
3046
+ lease.serverApply = record;
3009
3047
  lease.phase = "settled";
3010
3048
  lease.resolveApply?.();
3011
- return responseFor(record2.result);
3049
+ return responseFor(record.result);
3012
3050
  }
3013
3051
  async reconcileRename(leaseToken, edit) {
3014
3052
  const lease = this.requireActiveLease(leaseToken);
@@ -3024,16 +3062,16 @@ class WorkspaceMutationController {
3024
3062
  const applied = await this.applyEdit(edit, lease);
3025
3063
  return { edit, apply: applied.result };
3026
3064
  }
3027
- reconcileServerApply(record2, edit) {
3065
+ reconcileServerApply(record, edit) {
3028
3066
  if (!edit)
3029
- return { edit, apply: record2.result };
3067
+ return { edit, apply: record.result };
3030
3068
  const fingerprint = fingerprintWorkspaceEdit(edit, this.workspaceRoot);
3031
- if (fingerprint.success && record2.fingerprint !== null && fingerprint.fingerprint === record2.fingerprint) {
3032
- return { edit, apply: record2.result };
3069
+ if (fingerprint.success && record.fingerprint !== null && fingerprint.fingerprint === record.fingerprint) {
3070
+ return { edit, apply: record.result };
3033
3071
  }
3034
3072
  return {
3035
3073
  edit,
3036
- apply: failure("rename result conflicts with server-applied workspace edit", 0, record2.result)
3074
+ apply: failure("rename result conflicts with server-applied workspace edit", 0, record.result)
3037
3075
  };
3038
3076
  }
3039
3077
  async applyEdit(edit, lease) {
@@ -3072,14 +3110,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
3072
3110
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
3073
3111
 
3074
3112
  class LspClient extends LspClientConnection {
3075
- diagnosticPullErrors = [];
3076
- documents;
3077
- workspaceMutations;
3078
- diagnosticsFreshnessTimeoutMs;
3079
- constructor(root, server2, options = {}) {
3080
- super(root, server2, options);
3113
+ constructor(root, server, options = {}) {
3114
+ super(root, server, options);
3115
+ this.diagnosticPullErrors = [];
3081
3116
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
3082
3117
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
3118
+ timerProvider: this.timerProvider,
3083
3119
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
3084
3120
  });
3085
3121
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -3132,6 +3168,18 @@ class LspClient extends LspClientConnection {
3132
3168
  textDocument: { uri: pathToFileURL3(absPath).href }
3133
3169
  }, options);
3134
3170
  }
3171
+ async formatDocument(filePath, options, signal) {
3172
+ if (!this.isDocumentFormattingSupported())
3173
+ return null;
3174
+ const absPath = this.resolveWorkspacePath(filePath);
3175
+ await this.openFile(absPath);
3176
+ const requestOptions = signal === undefined ? {} : { signal };
3177
+ const edits = await this.sendRequest("textDocument/formatting", {
3178
+ textDocument: { uri: pathToFileURL3(absPath).href },
3179
+ options
3180
+ }, requestOptions);
3181
+ return edits ?? [];
3182
+ }
3135
3183
  async workspaceSymbols(query, signal) {
3136
3184
  const options = signal === undefined ? {} : { signal };
3137
3185
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -3171,7 +3219,7 @@ class LspClient extends LspClientConnection {
3171
3219
  const absPath = this.resolveWorkspacePath(filePath);
3172
3220
  const uri = pathToFileURL3(absPath).href;
3173
3221
  await this.openFile(absPath);
3174
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
3222
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
3175
3223
  for (;; ) {
3176
3224
  signal?.throwIfAborted();
3177
3225
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -3184,13 +3232,13 @@ class LspClient extends LspClientConnection {
3184
3232
  if (!pushFallbackOnly) {
3185
3233
  const cached = this.documents.getPullCache(snapshot);
3186
3234
  try {
3187
- const remainingMs2 = deadlineAt - Date.now();
3188
- if (remainingMs2 <= 0)
3235
+ const remainingMs = deadlineAt - this.timerProvider.now();
3236
+ if (remainingMs <= 0)
3189
3237
  return this.freshnessTimeout(absPath);
3190
3238
  const result = await this.sendRequest("textDocument/diagnostic", {
3191
3239
  textDocument: { uri },
3192
3240
  ...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
3193
- }, { timeoutMs: remainingMs2, ...signal === undefined ? {} : { signal } });
3241
+ }, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
3194
3242
  if (!this.documents.isCurrentSnapshot(snapshot))
3195
3243
  continue;
3196
3244
  const report = this.parseDiagnosticPullReport(result);
@@ -3219,7 +3267,7 @@ class LspClient extends LspClientConnection {
3219
3267
  }
3220
3268
  if (!pushFallbackOnly)
3221
3269
  continue;
3222
- const remainingMs = deadlineAt - Date.now();
3270
+ const remainingMs = deadlineAt - this.timerProvider.now();
3223
3271
  if (remainingMs <= 0) {
3224
3272
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
3225
3273
  const cached = this.documents.getPullCache(snapshot);
@@ -3271,7 +3319,7 @@ function waitForDiagnosticsActivity(wait, signal) {
3271
3319
  return wait;
3272
3320
  if (signal.aborted)
3273
3321
  return Promise.reject(abortError3(signal));
3274
- return new Promise((resolve72, reject) => {
3322
+ return new Promise((resolve, reject) => {
3275
3323
  const onAbort = () => {
3276
3324
  signal.removeEventListener("abort", onAbort);
3277
3325
  reject(abortError3(signal));
@@ -3279,7 +3327,7 @@ function waitForDiagnosticsActivity(wait, signal) {
3279
3327
  signal.addEventListener("abort", onAbort, { once: true });
3280
3328
  wait.then(() => {
3281
3329
  signal.removeEventListener("abort", onAbort);
3282
- resolve72();
3330
+ resolve();
3283
3331
  }, (error) => {
3284
3332
  signal.removeEventListener("abort", onAbort);
3285
3333
  reject(error);
@@ -3343,7 +3391,7 @@ async function stopClientBestEffort(client) {
3343
3391
  function awaitWithSignal2(promise, signal) {
3344
3392
  if (!signal)
3345
3393
  return promise;
3346
- return new Promise((resolve72, reject) => {
3394
+ return new Promise((resolve, reject) => {
3347
3395
  let settled = false;
3348
3396
  const onAbort = () => {
3349
3397
  if (settled)
@@ -3361,7 +3409,7 @@ function awaitWithSignal2(promise, signal) {
3361
3409
  return;
3362
3410
  settled = true;
3363
3411
  signal.removeEventListener("abort", onAbort);
3364
- resolve72(value);
3412
+ resolve(value);
3365
3413
  }, (err) => {
3366
3414
  if (settled)
3367
3415
  return;
@@ -3373,20 +3421,18 @@ function awaitWithSignal2(promise, signal) {
3373
3421
  }
3374
3422
 
3375
3423
  class LspManager {
3376
- clients = new Map;
3377
- reaperHandle = null;
3378
- signalDisposer = null;
3379
- disposed = false;
3380
- idleTimeoutMs;
3381
- initTimeoutMs;
3382
- reaperIntervalMs;
3383
- clientFactory;
3384
- now;
3385
3424
  constructor(options = {}) {
3425
+ this.clients = new Map;
3426
+ this.pendingStops = new Map;
3427
+ this.respawnBudgets = new Map;
3428
+ this.reaperHandle = null;
3429
+ this.signalDisposer = null;
3430
+ this.disposed = false;
3386
3431
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
3387
3432
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
3433
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
3388
3434
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
3389
- this.clientFactory = options.clientFactory ?? ((root, server2) => new LspClient(root, server2));
3435
+ this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
3390
3436
  this.now = options.now ?? (() => Date.now());
3391
3437
  this.startReaper();
3392
3438
  this.signalDisposer = installProcessSignalCleanup(() => this.stopAll());
@@ -3404,38 +3450,103 @@ class LspManager {
3404
3450
  getKey(root, serverId) {
3405
3451
  return `${root}::${serverId}`;
3406
3452
  }
3453
+ tombstoneStop(key, client) {
3454
+ const stop = stopClientBestEffort(client);
3455
+ this.pendingStops.set(key, stop);
3456
+ stop.finally(() => {
3457
+ if (this.pendingStops.get(key) === stop) {
3458
+ this.pendingStops.delete(key);
3459
+ }
3460
+ });
3461
+ return stop;
3462
+ }
3463
+ recordDeadGeneration(key) {
3464
+ let budget = this.respawnBudgets.get(key);
3465
+ if (budget === undefined) {
3466
+ budget = { deadGenerations: 0, exhaustedAt: null };
3467
+ this.respawnBudgets.set(key, budget);
3468
+ }
3469
+ budget.deadGenerations += 1;
3470
+ }
3471
+ markHealthyGeneration(key) {
3472
+ this.respawnBudgets.delete(key);
3473
+ }
3474
+ ensureRespawnAllowed(key, root, serverId) {
3475
+ const budget = this.respawnBudgets.get(key);
3476
+ if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
3477
+ return;
3478
+ if (budget.exhaustedAt === null) {
3479
+ budget.exhaustedAt = this.now();
3480
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3481
+ }
3482
+ if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
3483
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3484
+ }
3485
+ budget.deadGenerations = 0;
3486
+ budget.exhaustedAt = null;
3487
+ }
3407
3488
  reapStale() {
3408
3489
  const t = this.now();
3409
3490
  for (const [key, managed] of this.clients) {
3410
3491
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3411
- stopClientBestEffort(managed.client);
3412
3492
  this.clients.delete(key);
3493
+ this.tombstoneStop(key, managed.client);
3413
3494
  continue;
3414
3495
  }
3415
3496
  if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
3416
- stopClientBestEffort(managed.client);
3417
3497
  this.clients.delete(key);
3498
+ this.tombstoneStop(key, managed.client);
3418
3499
  }
3419
3500
  }
3420
3501
  }
3502
+ evictForAdmission() {
3503
+ while (this.clients.size >= this.maxResidentClients) {
3504
+ const victim = this.leastRecentlyUsedIdleClient();
3505
+ if (!victim)
3506
+ return;
3507
+ this.clients.delete(victim.key);
3508
+ this.tombstoneStop(victim.key, victim.managed.client);
3509
+ }
3510
+ }
3511
+ leastRecentlyUsedIdleClient() {
3512
+ let candidate = null;
3513
+ for (const [key, managed] of this.clients) {
3514
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
3515
+ continue;
3516
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
3517
+ candidate = { key, managed };
3518
+ }
3519
+ }
3520
+ return candidate;
3521
+ }
3421
3522
  async tryDeleteIfOrphaned(key, managed) {
3422
3523
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
3423
3524
  this.clients.delete(key);
3424
- await stopClientBestEffort(managed.client);
3525
+ await this.tombstoneStop(key, managed.client);
3425
3526
  }
3426
3527
  }
3427
- async getClient(root, server2, signal) {
3528
+ async getClient(root, server, signal) {
3428
3529
  if (this.disposed) {
3429
3530
  throw new Error("LspManager has been disposed");
3430
3531
  }
3431
3532
  signal?.throwIfAborted();
3432
- const key = this.getKey(root, server2.id);
3533
+ const key = this.getKey(root, server.id);
3534
+ for (;; ) {
3535
+ const pendingStop = this.pendingStops.get(key);
3536
+ if (pendingStop === undefined)
3537
+ break;
3538
+ await awaitWithSignal2(pendingStop, signal);
3539
+ signal?.throwIfAborted();
3540
+ }
3541
+ if (this.disposed) {
3542
+ throw new Error("LspManager has been disposed");
3543
+ }
3433
3544
  let managed = this.clients.get(key);
3434
3545
  if (managed) {
3435
3546
  const t = this.now();
3436
3547
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3437
- await stopClientBestEffort(managed.client);
3438
3548
  this.clients.delete(key);
3549
+ await this.tombstoneStop(key, managed.client);
3439
3550
  managed = undefined;
3440
3551
  }
3441
3552
  }
@@ -3456,15 +3567,21 @@ class LspManager {
3456
3567
  signal.throwIfAborted();
3457
3568
  }
3458
3569
  if (!managed.client.isAlive()) {
3459
- await stopClientBestEffort(managed.client);
3460
- this.clients.delete(key);
3461
- return this.getClient(root, server2, signal);
3570
+ this.recordDeadGeneration(key);
3571
+ if (this.clients.get(key) === managed) {
3572
+ this.clients.delete(key);
3573
+ }
3574
+ await this.tombstoneStop(key, managed.client);
3575
+ return this.getClient(root, server, signal);
3462
3576
  }
3577
+ this.markHealthyGeneration(key);
3463
3578
  managed.refCount++;
3464
3579
  managed.lastUsedAt = this.now();
3465
3580
  return managed.client;
3466
3581
  }
3467
- const client = this.clientFactory(root, server2);
3582
+ this.evictForAdmission();
3583
+ this.ensureRespawnAllowed(key, root, server.id);
3584
+ const client = this.clientFactory(root, server);
3468
3585
  const initStartedAt = this.now();
3469
3586
  const initPromise = (async () => {
3470
3587
  await client.start();
@@ -3487,7 +3604,7 @@ class LspManager {
3487
3604
  if (this.clients.get(key) === newManaged) {
3488
3605
  this.clients.delete(key);
3489
3606
  }
3490
- await stopClientBestEffort(client);
3607
+ await this.tombstoneStop(key, client);
3491
3608
  throw err;
3492
3609
  }
3493
3610
  newManaged.pendingWaiters--;
@@ -3498,6 +3615,15 @@ class LspManager {
3498
3615
  await this.tryDeleteIfOrphaned(key, newManaged);
3499
3616
  signal.throwIfAborted();
3500
3617
  }
3618
+ if (!client.isAlive()) {
3619
+ this.recordDeadGeneration(key);
3620
+ if (this.clients.get(key) === newManaged) {
3621
+ this.clients.delete(key);
3622
+ }
3623
+ await this.tombstoneStop(key, client);
3624
+ return this.getClient(root, server, signal);
3625
+ }
3626
+ this.markHealthyGeneration(key);
3501
3627
  newManaged.refCount++;
3502
3628
  newManaged.lastUsedAt = this.now();
3503
3629
  return client;
@@ -3518,15 +3644,21 @@ class LspManager {
3518
3644
  if (client && managed.client !== client)
3519
3645
  return;
3520
3646
  this.clients.delete(key);
3521
- stopClientBestEffort(managed.client);
3647
+ this.tombstoneStop(key, managed.client);
3522
3648
  }
3523
- warmupClient(root, server2) {
3649
+ warmupClient(root, server) {
3524
3650
  if (this.disposed)
3525
3651
  return;
3526
- const key = this.getKey(root, server2.id);
3527
- if (this.clients.has(key))
3652
+ const key = this.getKey(root, server.id);
3653
+ if (this.clients.has(key) || this.pendingStops.has(key))
3528
3654
  return;
3529
- const client = this.clientFactory(root, server2);
3655
+ this.evictForAdmission();
3656
+ try {
3657
+ this.ensureRespawnAllowed(key, root, server.id);
3658
+ } catch {
3659
+ return;
3660
+ }
3661
+ const client = this.clientFactory(root, server);
3530
3662
  const initStartedAt = this.now();
3531
3663
  const initPromise = (async () => {
3532
3664
  await client.start();
@@ -3551,7 +3683,7 @@ class LspManager {
3551
3683
  if (this.clients.get(key) === managed) {
3552
3684
  this.clients.delete(key);
3553
3685
  }
3554
- stopClientBestEffort(client);
3686
+ this.tombstoneStop(key, client);
3555
3687
  });
3556
3688
  }
3557
3689
  isServerInitializing(root, serverId) {
@@ -3595,8 +3727,11 @@ class LspManager {
3595
3727
  for (const managed of this.clients.values()) {
3596
3728
  stopPromises.push(stopClientBestEffort(managed.client));
3597
3729
  }
3730
+ const tombstonedStops = [...this.pendingStops.values()];
3598
3731
  this.clients.clear();
3599
- await Promise.allSettled(stopPromises);
3732
+ this.respawnBudgets.clear();
3733
+ await Promise.allSettled([...stopPromises, ...tombstonedStops]);
3734
+ this.pendingStops.clear();
3600
3735
  }
3601
3736
  }
3602
3737
  var _defaultInstance = null;
@@ -3606,49 +3741,43 @@ function getLspManager() {
3606
3741
  }
3607
3742
  return _defaultInstance;
3608
3743
  }
3609
- function getInstallDecisionsPath() {
3610
- return lspRequestContext().installDecisionsPath;
3611
- }
3612
- function loadInstallDecisions() {
3613
- const path2 = getInstallDecisionsPath();
3614
- if (!existsSync7(path2))
3615
- return {};
3616
- try {
3617
- const parsed = JSON.parse(readFileSync4(path2, "utf8"));
3618
- return isInstallDecisions(parsed) ? parsed : {};
3619
- } catch {
3620
- return {};
3744
+ var GIT_WORKSPACE_MARKER = ".git";
3745
+ var PROJECT_WORKSPACE_MARKERS = [
3746
+ "package.json",
3747
+ "pyproject.toml",
3748
+ "Cargo.toml",
3749
+ "go.mod",
3750
+ "pom.xml",
3751
+ "build.gradle"
3752
+ ];
3753
+ var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
3754
+ function findWorkspaceRootOutsideContext(directory) {
3755
+ const marked = nearestMarkedAncestor(directory);
3756
+ if (marked !== undefined)
3757
+ return marked;
3758
+ return realpathSync4(nearestExistingAncestor(directory));
3759
+ }
3760
+ function nearestMarkedAncestor(directory) {
3761
+ let current = directory;
3762
+ for (;; ) {
3763
+ if (existsSync7(current) && WORKSPACE_MARKERS.some((marker) => existsSync7(join3(current, marker)))) {
3764
+ return realpathSync4(current);
3765
+ }
3766
+ const parent = dirname7(current);
3767
+ if (parent === current)
3768
+ return;
3769
+ current = parent;
3621
3770
  }
3622
3771
  }
3623
- function loadInstallDecision(serverId) {
3624
- return loadInstallDecisions()[serverId];
3625
- }
3626
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3627
- const decisions = loadInstallDecisions();
3628
- decisions[serverId] = { decision, decidedAt };
3629
- writeInstallDecisions(decisions);
3630
- }
3631
- function isInstallDecision(value) {
3632
- return value === "declined" || value === "allowed";
3633
- }
3634
- function writeInstallDecisions(decisions) {
3635
- const path2 = getInstallDecisionsPath();
3636
- mkdirSync3(dirname7(path2), { recursive: true });
3637
- const tmpPath = `${path2}.tmp`;
3638
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3639
- `, "utf8");
3640
- renameSync2(tmpPath, path2);
3641
- }
3642
- function isInstallDecisions(value) {
3643
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3644
- }
3645
- function isInstallDecisionRecord(value) {
3646
- if (!isRecord5(value))
3647
- return false;
3648
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3649
- }
3650
- function isRecord5(value) {
3651
- return typeof value === "object" && value !== null && !Array.isArray(value);
3772
+ function nearestExistingAncestor(directory) {
3773
+ let current = directory;
3774
+ while (!existsSync7(current)) {
3775
+ const parent = dirname7(current);
3776
+ if (parent === current)
3777
+ return current;
3778
+ current = parent;
3779
+ }
3780
+ return current;
3652
3781
  }
3653
3782
  var LSP_INSTALL_HINTS = {
3654
3783
  typescript: "npm install -g typescript-language-server typescript",
@@ -3694,6 +3823,26 @@ var LSP_INSTALL_HINTS = {
3694
3823
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
3695
3824
  razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
3696
3825
  };
3826
+ var LSP_LOCAL_INSTALL_HINTS = {
3827
+ typescript: "bun add -d typescript-language-server typescript",
3828
+ vue: "bun add -d @vue/language-server",
3829
+ eslint: "bun add -d vscode-langservers-extracted",
3830
+ oxlint: "bun add -d oxlint",
3831
+ biome: "bun add -d @biomejs/biome",
3832
+ svelte: "bun add -d svelte-language-server",
3833
+ astro: "bun add -d @astrojs/language-server",
3834
+ bash: "bun add -d bash-language-server",
3835
+ "bash-ls": "bun add -d bash-language-server",
3836
+ "yaml-ls": "bun add -d yaml-language-server",
3837
+ php: "bun add -d intelephense",
3838
+ prisma: "bun add -d prisma",
3839
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
3840
+ pyright: "uv add --dev pyright",
3841
+ basedpyright: "uv add --dev basedpyright",
3842
+ ruff: "uv add --dev ruff",
3843
+ ty: "uv add --dev ty",
3844
+ "ruby-lsp": "bundle add ruby-lsp --group development"
3845
+ };
3697
3846
  var BUILTIN_SERVERS = {
3698
3847
  typescript: {
3699
3848
  command: ["typescript-language-server", "--stdio"],
@@ -3795,17 +3944,61 @@ var BUILTIN_SERVERS = {
3795
3944
  extensions: [".razor", ".cshtml"]
3796
3945
  }
3797
3946
  };
3947
+ function getInstallDecisionsPath() {
3948
+ return lspRequestContext().installDecisionsPath;
3949
+ }
3950
+ function loadInstallDecisions() {
3951
+ const path = getInstallDecisionsPath();
3952
+ if (!existsSync8(path))
3953
+ return {};
3954
+ try {
3955
+ const parsed = JSON.parse(readFileSync4(path, "utf8"));
3956
+ return isInstallDecisions(parsed) ? parsed : {};
3957
+ } catch {
3958
+ return {};
3959
+ }
3960
+ }
3961
+ function loadInstallDecision(serverId) {
3962
+ return loadInstallDecisions()[serverId];
3963
+ }
3964
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3965
+ const decisions = loadInstallDecisions();
3966
+ decisions[serverId] = { decision, decidedAt };
3967
+ writeInstallDecisions(decisions);
3968
+ }
3969
+ function isInstallDecision(value) {
3970
+ return value === "declined" || value === "allowed";
3971
+ }
3972
+ function writeInstallDecisions(decisions) {
3973
+ const path = getInstallDecisionsPath();
3974
+ mkdirSync3(dirname8(path), { recursive: true });
3975
+ const tmpPath = `${path}.tmp`;
3976
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3977
+ `, "utf8");
3978
+ renameSync2(tmpPath, path);
3979
+ }
3980
+ function isInstallDecisions(value) {
3981
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3982
+ }
3983
+ function isInstallDecisionRecord(value) {
3984
+ if (!isRecord5(value))
3985
+ return false;
3986
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3987
+ }
3988
+ function isRecord5(value) {
3989
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3990
+ }
3798
3991
  function getProjectConfigPaths() {
3799
3992
  return lspRequestContext().projectConfigPaths;
3800
3993
  }
3801
3994
  function getUserConfigPath() {
3802
3995
  return lspRequestContext().userConfigPath;
3803
3996
  }
3804
- function loadJsonFile(path2) {
3805
- if (!existsSync8(path2))
3997
+ function loadJsonFile(path) {
3998
+ if (!existsSync9(path))
3806
3999
  return null;
3807
4000
  try {
3808
- const parsed = JSON.parse(readFileSync5(path2, "utf-8"));
4001
+ const parsed = JSON.parse(readFileSync5(path, "utf-8"));
3809
4002
  return isConfigJson(parsed) ? parsed : null;
3810
4003
  } catch {
3811
4004
  return null;
@@ -3822,8 +4015,8 @@ function loadAllConfigs() {
3822
4015
  return configs;
3823
4016
  }
3824
4017
  function loadFirstJsonFile(paths) {
3825
- for (const path2 of paths) {
3826
- const config = loadJsonFile(path2);
4018
+ for (const path of paths) {
4019
+ const config = loadJsonFile(path);
3827
4020
  if (config)
3828
4021
  return config;
3829
4022
  }
@@ -3849,10 +4042,10 @@ function getMergedServers() {
3849
4042
  }
3850
4043
  if (seen.has(id))
3851
4044
  continue;
3852
- const server2 = createServerFromEntry(id, entry, source);
3853
- if (!server2)
4045
+ const server = createServerFromEntry(id, entry, source);
4046
+ if (!server)
3854
4047
  continue;
3855
- servers.push(server2);
4048
+ servers.push(server);
3856
4049
  seen.add(id);
3857
4050
  }
3858
4051
  }
@@ -3884,7 +4077,7 @@ function createServerFromEntry(id, entry, source) {
3884
4077
  if (source === "project") {
3885
4078
  if (!builtin)
3886
4079
  return null;
3887
- const server3 = createServer({
4080
+ const server = createServer({
3888
4081
  id,
3889
4082
  command: builtin.command,
3890
4083
  extensions: entry.extensions ?? builtin.extensions,
@@ -3892,35 +4085,35 @@ function createServerFromEntry(id, entry, source) {
3892
4085
  source
3893
4086
  });
3894
4087
  if (entry.initialization !== undefined) {
3895
- server3.initialization = entry.initialization;
4088
+ server.initialization = entry.initialization;
3896
4089
  }
3897
- return server3;
4090
+ return server;
3898
4091
  }
3899
4092
  if (entry.command && entry.extensions) {
3900
- const server3 = createServer({
4093
+ const server = createServer({
3901
4094
  id,
3902
4095
  command: entry.command,
3903
4096
  extensions: entry.extensions,
3904
4097
  priority: entry.priority ?? 0,
3905
4098
  source
3906
4099
  });
3907
- applyOptionalServerFields(server3, entry);
3908
- return server3;
4100
+ applyOptionalServerFields(server, entry);
4101
+ return server;
3909
4102
  }
3910
4103
  if (!builtin)
3911
4104
  return null;
3912
- const server2 = createServer({
4105
+ const server = createServer({
3913
4106
  id,
3914
4107
  command: entry.command ?? builtin.command,
3915
4108
  extensions: entry.extensions ?? builtin.extensions,
3916
4109
  priority: entry.priority ?? 0,
3917
4110
  source
3918
4111
  });
3919
- applyOptionalServerFields(server2, entry);
3920
- return server2;
4112
+ applyOptionalServerFields(server, entry);
4113
+ return server;
3921
4114
  }
3922
4115
  function createServer(input) {
3923
- const server2 = {
4116
+ const server = {
3924
4117
  id: input.id,
3925
4118
  command: input.command,
3926
4119
  extensions: input.extensions,
@@ -3928,19 +4121,19 @@ function createServer(input) {
3928
4121
  source: input.source
3929
4122
  };
3930
4123
  if (input.env !== undefined) {
3931
- server2.env = input.env;
4124
+ server.env = input.env;
3932
4125
  }
3933
4126
  if (input.initialization !== undefined) {
3934
- server2.initialization = input.initialization;
4127
+ server.initialization = input.initialization;
3935
4128
  }
3936
- return server2;
4129
+ return server;
3937
4130
  }
3938
- function applyOptionalServerFields(server2, entry) {
4131
+ function applyOptionalServerFields(server, entry) {
3939
4132
  if (entry.env !== undefined) {
3940
- server2.env = entry.env;
4133
+ server.env = entry.env;
3941
4134
  }
3942
4135
  if (entry.initialization !== undefined) {
3943
- server2.initialization = entry.initialization;
4136
+ server.initialization = entry.initialization;
3944
4137
  }
3945
4138
  }
3946
4139
  function isConfigJson(value) {
@@ -3988,60 +4181,161 @@ function getDisabledServerIds() {
3988
4181
  }
3989
4182
  return disabled;
3990
4183
  }
3991
- function isServerInstalled(command, _workingDirectory) {
3992
- if (command.length === 0)
3993
- return false;
3994
- const [cmd] = command;
3995
- if (!cmd)
3996
- return false;
3997
- if (cmd.includes("/") || cmd.includes("\\")) {
3998
- if (existsSync9(cmd))
3999
- return true;
4184
+ var LOCAL_BIN_RULES = [
4185
+ {
4186
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
4187
+ binDirs: [join4("node_modules", ".bin")]
4188
+ },
4189
+ {
4190
+ markers: [
4191
+ "pyproject.toml",
4192
+ "ty.toml",
4193
+ "requirements.txt",
4194
+ "setup.py",
4195
+ "setup.cfg",
4196
+ "Pipfile",
4197
+ "pyrightconfig.json",
4198
+ "ruff.toml",
4199
+ ".ruff.toml"
4200
+ ],
4201
+ binDirs: [
4202
+ join4(".venv", "bin"),
4203
+ join4(".venv", "Scripts"),
4204
+ join4("venv", "bin"),
4205
+ join4("venv", "Scripts"),
4206
+ join4(".env", "bin"),
4207
+ join4(".env", "Scripts")
4208
+ ]
4209
+ },
4210
+ {
4211
+ markers: ["Gemfile", "Gemfile.lock"],
4212
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4213
+ },
4214
+ {
4215
+ markers: ["go.mod", "go.sum", "go.work"],
4216
+ binDirs: ["bin"]
4217
+ }
4218
+ ];
4219
+ var resolutionCache = new Map;
4220
+ var probeCount = 0;
4221
+ function probe(path) {
4222
+ probeCount += 1;
4223
+ return existsSync10(path);
4224
+ }
4225
+ function executableSuffixes(platform, pathExt) {
4226
+ if (platform !== "win32")
4227
+ return [""];
4228
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4229
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4230
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4231
+ }
4232
+ function probeWithSuffixes(directory, command, suffixes) {
4233
+ for (const suffix of suffixes) {
4234
+ const candidate = join4(directory, command + suffix);
4235
+ if (probe(candidate))
4236
+ return candidate;
4000
4237
  }
4001
- const isWindows = process.platform === "win32";
4002
- let exts = [""];
4003
- if (isWindows) {
4004
- const pathExt = process.env["PATHEXT"] ?? "";
4005
- if (pathExt) {
4006
- const systemExts = pathExt.split(";").filter(Boolean);
4007
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4008
- } else {
4009
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4238
+ return null;
4239
+ }
4240
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4241
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4242
+ let current = resolve7(workingDirectory);
4243
+ while (true) {
4244
+ for (const rule of LOCAL_BIN_RULES) {
4245
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
4246
+ continue;
4247
+ for (const binDir of rule.binDirs) {
4248
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4249
+ if (found !== null)
4250
+ return found;
4251
+ }
4010
4252
  }
4253
+ if (probe(join4(current, ".git")))
4254
+ return null;
4255
+ if (boundary !== undefined && current === boundary)
4256
+ return null;
4257
+ const parent = dirname9(current);
4258
+ if (parent === current)
4259
+ return null;
4260
+ current = parent;
4011
4261
  }
4012
- let pathEnv = process.env["PATH"] ?? "";
4013
- if (isWindows && !pathEnv) {
4262
+ }
4263
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4264
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4265
+ if (platform === "win32" && !pathEnv) {
4014
4266
  pathEnv = process.env["Path"] ?? "";
4015
4267
  }
4016
- const paths = pathEnv.split(delimiter3);
4017
- for (const p of paths) {
4018
- for (const suffix of exts) {
4019
- if (existsSync9(join3(p, cmd + suffix))) {
4020
- return true;
4021
- }
4022
- }
4268
+ for (const entry of pathEnv.split(delimiter3)) {
4269
+ if (entry.length === 0)
4270
+ continue;
4271
+ const found = probeWithSuffixes(entry, command, suffixes);
4272
+ if (found !== null)
4273
+ return found;
4023
4274
  }
4024
- if (cmd === "node")
4025
- return true;
4026
- return false;
4275
+ return null;
4276
+ }
4277
+ function resolveServerBinary(command, workingDirectory, options = {}) {
4278
+ if (command.length === 0)
4279
+ return null;
4280
+ const [cmd] = command;
4281
+ if (cmd === undefined || cmd.length === 0)
4282
+ return null;
4283
+ const platform = options.platform ?? process.platform;
4284
+ const suffixes = executableSuffixes(platform, options.pathExt);
4285
+ if (cmd.includes("/") || cmd.includes("\\")) {
4286
+ const explicit = isAbsolute5(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4287
+ return probe(explicit) ? explicit : null;
4288
+ }
4289
+ const cacheKey = JSON.stringify([
4290
+ workingDirectory ?? "",
4291
+ cmd,
4292
+ platform,
4293
+ options.stopAt ?? "",
4294
+ options.pathExt ?? "",
4295
+ options.pathEnv ?? process.env["PATH"] ?? ""
4296
+ ]);
4297
+ const cached = resolutionCache.get(cacheKey);
4298
+ if (cached !== undefined)
4299
+ return cached;
4300
+ let resolved = null;
4301
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
4302
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4303
+ }
4304
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4305
+ if (resolved === null && cmd === "node")
4306
+ resolved = cmd;
4307
+ resolutionCache.set(cacheKey, resolved);
4308
+ return resolved;
4309
+ }
4310
+ function isServerInstalled(command, workingDirectory, options = {}) {
4311
+ if (command.length === 0)
4312
+ return false;
4313
+ return resolveServerBinary(command, workingDirectory, options) !== null;
4314
+ }
4315
+ function withResolvedCommand(command, binaryPath) {
4316
+ return [binaryPath, ...command.slice(1)];
4027
4317
  }
4028
4318
  function findServerForExtension(ext) {
4029
4319
  const servers = getMergedServers();
4030
- for (const server2 of servers) {
4031
- if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4320
+ const workingDirectory = contextCwd();
4321
+ for (const server of servers) {
4322
+ if (!server.extensions.includes(ext))
4323
+ continue;
4324
+ const binaryPath = resolveServerBinary(server.command, workingDirectory);
4325
+ if (binaryPath !== null) {
4032
4326
  const resolvedServer = {
4033
- id: server2.id,
4034
- command: server2.command,
4035
- extensions: server2.extensions,
4036
- priority: server2.priority
4327
+ id: server.id,
4328
+ command: withResolvedCommand(server.command, binaryPath),
4329
+ extensions: server.extensions,
4330
+ priority: server.priority
4037
4331
  };
4038
- if (server2.env !== undefined) {
4332
+ if (server.env !== undefined) {
4039
4333
  return {
4040
4334
  status: "found",
4041
4335
  server: {
4042
4336
  ...resolvedServer,
4043
- env: server2.env,
4044
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4337
+ env: server.env,
4338
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
4045
4339
  }
4046
4340
  };
4047
4341
  }
@@ -4049,20 +4343,20 @@ function findServerForExtension(ext) {
4049
4343
  status: "found",
4050
4344
  server: {
4051
4345
  ...resolvedServer,
4052
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4346
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
4053
4347
  }
4054
4348
  };
4055
4349
  }
4056
4350
  }
4057
- for (const server2 of servers) {
4058
- if (server2.extensions.includes(ext)) {
4059
- const installHint = LSP_INSTALL_HINTS[server2.id] ?? `Install '${server2.command[0]}' and ensure it's in your PATH`;
4351
+ for (const server of servers) {
4352
+ if (server.extensions.includes(ext)) {
4353
+ const installHint = LSP_INSTALL_HINTS[server.id] ?? `Install '${server.command[0]}' and ensure it's in your PATH`;
4060
4354
  return {
4061
4355
  status: "not_installed",
4062
4356
  server: {
4063
- id: server2.id,
4064
- command: server2.command,
4065
- extensions: server2.extensions
4357
+ id: server.id,
4358
+ command: server.command,
4359
+ extensions: server.extensions
4066
4360
  },
4067
4361
  installHint
4068
4362
  };
@@ -4078,20 +4372,21 @@ function findServerForExtension(ext) {
4078
4372
  function getAllServers() {
4079
4373
  const servers = getMergedServers();
4080
4374
  const disabled = getDisabledServerIds();
4375
+ const workingDirectory = contextCwd();
4081
4376
  const result = [];
4082
4377
  const seen = new Set;
4083
- for (const server2 of servers) {
4084
- if (seen.has(server2.id))
4378
+ for (const server of servers) {
4379
+ if (seen.has(server.id))
4085
4380
  continue;
4086
4381
  result.push({
4087
- id: server2.id,
4088
- installed: isServerInstalled(server2.command),
4089
- extensions: server2.extensions,
4382
+ id: server.id,
4383
+ installed: isServerInstalled(server.command, workingDirectory),
4384
+ extensions: server.extensions,
4090
4385
  disabled: false,
4091
- source: server2.source,
4092
- priority: server2.priority
4386
+ source: server.source,
4387
+ priority: server.priority
4093
4388
  });
4094
- seen.add(server2.id);
4389
+ seen.add(server.id);
4095
4390
  }
4096
4391
  for (const id of disabled) {
4097
4392
  if (seen.has(id))
@@ -4099,7 +4394,7 @@ function getAllServers() {
4099
4394
  const builtin = BUILTIN_SERVERS[id];
4100
4395
  result.push({
4101
4396
  id,
4102
- installed: builtin ? isServerInstalled(builtin.command) : false,
4397
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4103
4398
  extensions: builtin?.extensions ?? [],
4104
4399
  disabled: true,
4105
4400
  source: "disabled",
@@ -4108,7 +4403,6 @@ function getAllServers() {
4108
4403
  }
4109
4404
  return result;
4110
4405
  }
4111
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
4112
4406
  function isDirectoryPath(filePath) {
4113
4407
  try {
4114
4408
  return statSync4(filePath).isDirectory();
@@ -4121,36 +4415,40 @@ function findWorkspaceRoot(filePath) {
4121
4415
  const abs = resolveReadablePathInsideContext(filePath);
4122
4416
  let dir = abs;
4123
4417
  if (!isDirectoryPath(dir)) {
4124
- dir = dirname8(dir);
4418
+ dir = dirname10(dir);
4125
4419
  }
4420
+ if (!isPathInside(cwd, abs))
4421
+ return findWorkspaceRootOutsideContext(dir);
4126
4422
  const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4423
+ let nearestPackageRoot;
4127
4424
  while (isPathInside(cwd, dir)) {
4128
4425
  const canonicalDir = existingDirectoryInsideContext(dir, cwd);
4129
4426
  if (canonicalDir !== undefined) {
4130
- for (const marker of WORKSPACE_MARKERS) {
4131
- if (existsSync10(join4(dir, marker))) {
4132
- return canonicalDir;
4133
- }
4427
+ if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
4428
+ return canonicalDir;
4429
+ }
4430
+ if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
4431
+ nearestPackageRoot = canonicalDir;
4134
4432
  }
4135
4433
  }
4136
4434
  if (dir === cwd)
4137
4435
  break;
4138
- dir = dirname8(dir);
4436
+ dir = dirname10(dir);
4139
4437
  }
4140
- return fallbackRoot;
4438
+ return nearestPackageRoot ?? fallbackRoot;
4439
+ }
4440
+ function hasProjectWorkspaceMarker(directory) {
4441
+ return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
4141
4442
  }
4142
4443
  function resolveReadablePathInsideContext(filePath) {
4143
4444
  const cwd = contextCwd();
4144
- const abs = resolve7(cwd, filePath);
4445
+ const abs = resolve8(cwd, filePath);
4145
4446
  if (isPathInside(cwd, abs))
4146
4447
  return abs;
4147
4448
  const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
4148
4449
  if (rebased !== undefined)
4149
4450
  return rebased;
4150
- const canonical = canonicalizeExistingOrNearestAncestor(abs);
4151
- if (isPathInside(cwd, canonical))
4152
- return canonical;
4153
- throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
4451
+ return canonicalizeExistingOrNearestAncestor(abs);
4154
4452
  }
4155
4453
  function resolvePathInsideContext(filePath) {
4156
4454
  const cwd = contextCwd();
@@ -4161,16 +4459,16 @@ function resolvePathInsideContext(filePath) {
4161
4459
  }
4162
4460
  return canonical;
4163
4461
  }
4164
- function rebaseThroughCanonicalAncestor(path2, cwd) {
4165
- let current = path2;
4462
+ function rebaseThroughCanonicalAncestor(path, cwd) {
4463
+ let current = path;
4166
4464
  const suffix = [];
4167
4465
  while (true) {
4168
- if (existsSync10(current)) {
4169
- const canonical = realpathSync4(current);
4466
+ if (existsSync11(current)) {
4467
+ const canonical = realpathSync5(current);
4170
4468
  if (isPathInside(cwd, canonical))
4171
- return suffix.length === 0 ? canonical : join4(canonical, ...suffix);
4469
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
4172
4470
  }
4173
- const parent = dirname8(current);
4471
+ const parent = dirname10(current);
4174
4472
  if (parent === current)
4175
4473
  return;
4176
4474
  suffix.unshift(basename3(current));
@@ -4178,9 +4476,9 @@ function rebaseThroughCanonicalAncestor(path2, cwd) {
4178
4476
  }
4179
4477
  }
4180
4478
  function existingDirectoryInsideContext(directory, cwd) {
4181
- if (!existsSync10(directory))
4479
+ if (!existsSync11(directory))
4182
4480
  return;
4183
- const canonical = realpathSync4(directory);
4481
+ const canonical = realpathSync5(directory);
4184
4482
  if (!statSync4(canonical).isDirectory())
4185
4483
  return;
4186
4484
  return isPathInside(cwd, canonical) ? canonical : undefined;
@@ -4193,7 +4491,7 @@ function nearestExistingDirectoryInsideContext(directory, cwd) {
4193
4491
  return canonical;
4194
4492
  if (current === cwd)
4195
4493
  return;
4196
- current = dirname8(current);
4494
+ current = dirname10(current);
4197
4495
  }
4198
4496
  return;
4199
4497
  }
@@ -4220,33 +4518,46 @@ function formatServerLookupError(result) {
4220
4518
  ].join(`
4221
4519
  `);
4222
4520
  }
4521
+ function formatInstallOptions(serverId, installHint) {
4522
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
4523
+ if (localHint === undefined) {
4524
+ return ["To install, run:", ` ${installHint}`];
4525
+ }
4526
+ return [
4527
+ "To install in THIS repository (preferred — no global install needed):",
4528
+ ` ${localHint}`,
4529
+ "",
4530
+ "Or install it globally:",
4531
+ ` ${installHint}`
4532
+ ];
4533
+ }
4223
4534
  function formatNotInstalled(result) {
4224
- const { server: server2, installHint } = result;
4225
- const extensions = server2.extensions.join(", ");
4226
- const decision = loadInstallDecision(server2.id)?.decision;
4535
+ const { server, installHint } = result;
4536
+ const extensions = server.extensions.join(", ");
4537
+ const decision = loadInstallDecision(server.id)?.decision;
4227
4538
  const context = lspRequestContext();
4228
4539
  if (decision === "declined") {
4229
- return `LSP server '${server2.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
4540
+ return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
4230
4541
  }
4231
4542
  const header = [
4232
- `LSP server '${server2.id}' for ${extensions} is NOT INSTALLED.`,
4543
+ `LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
4233
4544
  "",
4234
- `Command not found: ${server2.command[0]}`,
4545
+ `Command not found: ${server.command[0]}`,
4235
4546
  ""
4236
4547
  ];
4548
+ const installOptions = formatInstallOptions(server.id, installHint);
4237
4549
  if (decision === "allowed") {
4238
4550
  return [
4239
4551
  ...header,
4240
4552
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4241
- ` ${installHint}`
4553
+ ...installOptions.slice(1)
4242
4554
  ].join(`
4243
4555
  `);
4244
4556
  }
4245
4557
  if (!context.capabilities.installDecisionTool) {
4246
4558
  return [
4247
4559
  ...header,
4248
- "To install, run:",
4249
- ` ${installHint}`,
4560
+ ...installOptions,
4250
4561
  "",
4251
4562
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4252
4563
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4255,13 +4566,12 @@ function formatNotInstalled(result) {
4255
4566
  }
4256
4567
  return [
4257
4568
  ...header,
4258
- "To install, run:",
4259
- ` ${installHint}`,
4569
+ ...installOptions,
4260
4570
  "",
4261
4571
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4262
4572
  "- If the user agrees: run the install command above, then retry this tool.",
4263
4573
  "- If the user declines, OR has NOT explicitly asked for LSP installation:",
4264
- ` call lsp_install_decision { server_id: "${server2.id}", decision: "declined" },`,
4574
+ ` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
4265
4575
  ` which writes to ${context.installDecisionsPath},`,
4266
4576
  " then ignore this message and proceed WITHOUT LSP."
4267
4577
  ].join(`
@@ -4285,26 +4595,26 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4285
4595
  if (result.status !== "found") {
4286
4596
  throw new LspServerLookupError(formatServerLookupError(result), result);
4287
4597
  }
4288
- const server2 = result.server;
4598
+ const server = result.server;
4289
4599
  const root = findWorkspaceRoot(absPath);
4290
4600
  const manager = options.manager ?? getLspManager();
4291
4601
  const acquireAndCall = async (allowRetry) => {
4292
- const client = await manager.getClient(root, server2, options.signal);
4602
+ const client = await manager.getClient(root, server, options.signal);
4293
4603
  try {
4294
4604
  return await fn(client, root, absPath);
4295
4605
  } catch (err) {
4296
4606
  if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4297
- manager.invalidateClient(root, server2.id, client);
4607
+ manager.invalidateClient(root, server.id, client);
4298
4608
  return acquireAndCall(false);
4299
4609
  }
4300
4610
  if (err instanceof LspRequestTimeoutError) {
4301
- if (manager.isServerInitializing(root, server2.id)) {
4611
+ if (manager.isServerInitializing(root, server.id)) {
4302
4612
  throw new LspServerInitializingError(err);
4303
4613
  }
4304
4614
  }
4305
4615
  throw err;
4306
4616
  } finally {
4307
- manager.releaseClient(root, server2.id);
4617
+ manager.releaseClient(root, server.id);
4308
4618
  }
4309
4619
  };
4310
4620
  return acquireAndCall(true);
@@ -4320,10 +4630,10 @@ function uriToPath(uri) {
4320
4630
  }
4321
4631
  function formatLocation(loc) {
4322
4632
  if ("targetUri" in loc) {
4323
- const uri2 = uriToPath(loc.targetUri);
4324
- const line2 = loc.targetRange.start.line + 1;
4325
- const char2 = loc.targetRange.start.character;
4326
- return `${uri2}:${line2}:${char2}`;
4633
+ const uri = uriToPath(loc.targetUri);
4634
+ const line = loc.targetRange.start.line + 1;
4635
+ const char = loc.targetRange.start.character;
4636
+ return `${uri}:${line}:${char}`;
4327
4637
  }
4328
4638
  const uri = uriToPath(loc.uri);
4329
4639
  const line = loc.range.start.line + 1;
@@ -4433,7 +4743,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
4433
4743
  for (const entry of entries) {
4434
4744
  if (files.length >= maxFiles)
4435
4745
  return;
4436
- const fullPath = join5(currentDir, entry);
4746
+ const fullPath = join6(currentDir, entry);
4437
4747
  let stat;
4438
4748
  try {
4439
4749
  stat = lstatSync5(fullPath);
@@ -4458,15 +4768,15 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4458
4768
  if (!extension.startsWith(".")) {
4459
4769
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4460
4770
  }
4461
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4462
- if (!existsSync11(absDir)) {
4771
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
4772
+ if (!existsSync12(absDir)) {
4463
4773
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4464
4774
  }
4465
4775
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
4466
4776
  if (serverResult.status !== "found") {
4467
4777
  throw new LspServerLookupError(formatServerLookupError(serverResult));
4468
4778
  }
4469
- const server2 = serverResult.server;
4779
+ const server = serverResult.server;
4470
4780
  const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
4471
4781
  const wasCapped = allFiles.length > maxFiles;
4472
4782
  const filesToProcess = allFiles.slice(0, maxFiles);
@@ -4486,7 +4796,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4486
4796
  const fileErrors = [];
4487
4797
  const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
4488
4798
  options.signal?.throwIfAborted();
4489
- const client = await manager.getClient(root, server2, options.signal);
4799
+ const client = await manager.getClient(root, server, options.signal);
4490
4800
  try {
4491
4801
  let nextIndex = 0;
4492
4802
  const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
@@ -4514,7 +4824,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4514
4824
  });
4515
4825
  await Promise.all(workers);
4516
4826
  } finally {
4517
- manager.releaseClient(root, server2.id);
4827
+ manager.releaseClient(root, server.id);
4518
4828
  }
4519
4829
  const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
4520
4830
  const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
@@ -4560,7 +4870,7 @@ function inferExtensionFromDirectory(directory) {
4560
4870
  for (const entry of entries) {
4561
4871
  if (scanned >= MAX_SCAN_ENTRIES)
4562
4872
  return;
4563
- const fullPath = join6(dir, entry);
4873
+ const fullPath = join7(dir, entry);
4564
4874
  let stat;
4565
4875
  try {
4566
4876
  stat = lstatSync6(fullPath);
@@ -4709,8 +5019,8 @@ function severityFilter(params) {
4709
5019
  function clientOptions(signal) {
4710
5020
  return signal === undefined ? {} : { signal };
4711
5021
  }
4712
- function text(text2, details, isError = false) {
4713
- return { content: [{ type: "text", text: text2 }], details, isError };
5022
+ function text(text, details, isError = false) {
5023
+ return { content: [{ type: "text", text }], details, isError };
4714
5024
  }
4715
5025
  function asDiagnosticArray(result) {
4716
5026
  if (!result)
@@ -4728,7 +5038,7 @@ async function executeLspDiagnostics(params, signal) {
4728
5038
  const extension = inferExtensionFromDirectory(absPath);
4729
5039
  if (!extension) {
4730
5040
  const message = `No supported source files found in directory: ${absPath}`;
4731
- const details3 = {
5041
+ const details = {
4732
5042
  filePath,
4733
5043
  severity,
4734
5044
  mode: "directory",
@@ -4738,24 +5048,24 @@ async function executeLspDiagnostics(params, signal) {
4738
5048
  error: message,
4739
5049
  errorKind: "no_files"
4740
5050
  };
4741
- return text(message, details3);
5051
+ return text(message, details);
4742
5052
  }
4743
- const output2 = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
4744
- const details2 = {
5053
+ const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
5054
+ const details = {
4745
5055
  filePath,
4746
5056
  severity,
4747
5057
  mode: "directory",
4748
5058
  diagnostics: [],
4749
- totalDiagnostics: output2.totalDiagnostics,
5059
+ totalDiagnostics: output.totalDiagnostics,
4750
5060
  truncated: false,
4751
- fileFailures: [...output2.fileFailures]
5061
+ fileFailures: [...output.fileFailures]
4752
5062
  };
4753
- return text(output2.output, details2);
5063
+ return text(output.output, details);
4754
5064
  }
4755
5065
  const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
4756
5066
  if (result.transientError) {
4757
5067
  const message = result.transientError.message;
4758
- const details2 = {
5068
+ const details = {
4759
5069
  filePath,
4760
5070
  severity,
4761
5071
  mode: "file",
@@ -4765,7 +5075,7 @@ async function executeLspDiagnostics(params, signal) {
4765
5075
  error: message,
4766
5076
  errorKind: result.transientError.kind
4767
5077
  };
4768
- return text(message, details2, true);
5078
+ return text(message, details, true);
4769
5079
  }
4770
5080
  const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
4771
5081
  const total = diagnostics.length;
@@ -4799,13 +5109,98 @@ async function executeLspDiagnostics(params, signal) {
4799
5109
  throw error;
4800
5110
  }
4801
5111
  }
5112
+ var DEFAULT_FORMATTING_OPTIONS = {
5113
+ tabSize: 4,
5114
+ insertSpaces: false,
5115
+ trimTrailingWhitespace: true,
5116
+ insertFinalNewline: true,
5117
+ trimFinalNewlines: true
5118
+ };
5119
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
5120
+ async function formatDocumentWithClient(client, filePath, options = {}) {
5121
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
5122
+ if (edits === null)
5123
+ return { status: "unavailable", reason: "capability_not_advertised" };
5124
+ if (edits.length === 0)
5125
+ return UNCHANGED;
5126
+ const before = readFileSync6(filePath, "utf-8");
5127
+ const normalized = normalizeTextEdits(before, edits, 0);
5128
+ if (normalized.text === before)
5129
+ return UNCHANGED;
5130
+ writeAtomically(filePath, normalized.text);
5131
+ await client.openFile(filePath);
5132
+ return {
5133
+ status: "formatted",
5134
+ ...lineDelta(normalized.edits)
5135
+ };
5136
+ }
5137
+ function lineDelta(edits) {
5138
+ let linesAdded = 0;
5139
+ let linesRemoved = 0;
5140
+ for (const edit of edits) {
5141
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
5142
+ linesAdded += edit.newText.split(`
5143
+ `).length;
5144
+ }
5145
+ return { linesAdded, linesRemoved };
5146
+ }
5147
+ function writeAtomically(filePath, content) {
5148
+ const tempPath = `${filePath}.omo-format.tmp`;
5149
+ writeFileSync3(tempPath, content, "utf-8");
5150
+ try {
5151
+ renameSync3(tempPath, filePath);
5152
+ } catch (error) {
5153
+ try {
5154
+ unlinkSync2(tempPath);
5155
+ } catch {}
5156
+ throw error;
5157
+ }
5158
+ }
5159
+ async function executeLspFormat(params, signal) {
5160
+ const filePath = requireString(params, "filePath");
5161
+ try {
5162
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
5163
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
5164
+ } catch (error) {
5165
+ const missingDependency = missingDependencyResult(error, {
5166
+ filePath,
5167
+ status: "unavailable",
5168
+ reason: "server_unavailable",
5169
+ linesAdded: 0,
5170
+ linesRemoved: 0
5171
+ });
5172
+ if (missingDependency)
5173
+ return missingDependency;
5174
+ throw error;
5175
+ }
5176
+ }
5177
+ function formatDetails(filePath, result) {
5178
+ if (result.status === "unavailable") {
5179
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5180
+ }
5181
+ return {
5182
+ filePath,
5183
+ status: result.status,
5184
+ linesAdded: result.linesAdded,
5185
+ linesRemoved: result.linesRemoved
5186
+ };
5187
+ }
5188
+ function describeResult(filePath, result) {
5189
+ if (result.status === "unavailable") {
5190
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5191
+ }
5192
+ if (result.status === "unchanged") {
5193
+ return `Already formatted: ${filePath}`;
5194
+ }
5195
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5196
+ }
4802
5197
  async function executeLspInstallDecision(params) {
4803
5198
  const serverId = requireString(params, "server_id");
4804
5199
  const decision = params["decision"];
4805
5200
  if (!isInstallDecision(decision)) {
4806
5201
  return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
4807
5202
  }
4808
- const serverIds = [...new Set(getMergedServers().map((server2) => server2.id))];
5203
+ const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
4809
5204
  if (!serverIds.includes(serverId)) {
4810
5205
  const preview = serverIds.slice(0, 20).join(", ");
4811
5206
  return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
@@ -4937,10 +5332,10 @@ function objectSchema(properties, required = []) {
4937
5332
  async function executeLspStatus() {
4938
5333
  const servers = getAllServers();
4939
5334
  const snapshots = getLspManager().getSnapshot();
4940
- const installed = servers.filter((server2) => server2.installed && !server2.disabled);
4941
- const configuredLines = servers.map((server2) => {
4942
- const state = server2.disabled ? "disabled" : server2.installed ? "installed" : "missing";
4943
- return `- ${server2.id}: ${state}; source=${server2.source}; extensions=${server2.extensions.join(", ")}`;
5335
+ const installed = servers.filter((server) => server.installed && !server.disabled);
5336
+ const configuredLines = servers.map((server) => {
5337
+ const state = server.disabled ? "disabled" : server.installed ? "installed" : "missing";
5338
+ return `- ${server.id}: ${state}; source=${server.source}; extensions=${server.extensions.join(", ")}`;
4944
5339
  });
4945
5340
  const activeLines = snapshots.map((snapshot) => {
4946
5341
  const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
@@ -4981,8 +5376,8 @@ async function executeLspSymbols(params, signal) {
4981
5376
  errorKind: "missing_query"
4982
5377
  });
4983
5378
  }
4984
- const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
4985
- return formatSymbolsResult(filePath, scope, symbols2, limit, query);
5379
+ const symbols = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
5380
+ return formatSymbolsResult(filePath, scope, symbols, limit, query);
4986
5381
  }
4987
5382
  const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
4988
5383
  return formatSymbolsResult(filePath, scope, symbols, limit);
@@ -5118,6 +5513,16 @@ var LSP_MCP_TOOLS = [
5118
5513
  }, ["filePath", "line", "character", "newName"]),
5119
5514
  execute: executeLspRename
5120
5515
  },
5516
+ {
5517
+ name: "format",
5518
+ aliases: ["lsp_format"],
5519
+ title: "LSP Format",
5520
+ description: "Format a source file with its language server and write the returned edits to disk.",
5521
+ inputSchema: objectSchema({
5522
+ filePath: { type: "string", description: "Source file path to format." }
5523
+ }, ["filePath"]),
5524
+ execute: executeLspFormat
5525
+ },
5121
5526
  {
5122
5527
  name: "install_decision",
5123
5528
  aliases: ["lsp_install_decision"],
@@ -5184,7 +5589,7 @@ function withContext(args, context) {
5184
5589
  function ensureDaemonAvailable(paths, ensure, signal) {
5185
5590
  if (!signal)
5186
5591
  return ensure(paths);
5187
- return new Promise((resolve9, reject) => {
5592
+ return new Promise((resolve, reject) => {
5188
5593
  let settled = false;
5189
5594
  const finish = (run) => {
5190
5595
  if (settled)
@@ -5199,11 +5604,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
5199
5604
  return;
5200
5605
  }
5201
5606
  signal.addEventListener("abort", onAbort, { once: true });
5202
- Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve9()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
5607
+ Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
5203
5608
  });
5204
5609
  }
5205
5610
  function sendToolCall(paths, token, name, args, options) {
5206
- return new Promise((resolve9, reject) => {
5611
+ return new Promise((resolve, reject) => {
5207
5612
  const socket = connect(paths.socket);
5208
5613
  const requestId = allocateProxyRequestId();
5209
5614
  let settled = false;
@@ -5256,7 +5661,7 @@ function sendToolCall(paths, token, name, args, options) {
5256
5661
  }
5257
5662
  const result = toToolResult(message, requestId);
5258
5663
  if (result)
5259
- finish(() => resolve9(result));
5664
+ finish(() => resolve(result));
5260
5665
  else
5261
5666
  finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
5262
5667
  });
@@ -5305,10 +5710,9 @@ var OMO_LSP_DAEMON_VERSION2 = "OMO_LSP_DAEMON_VERSION";
5305
5710
  var DAEMON_VERSION_PATTERN2 = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
5306
5711
 
5307
5712
  class InvalidRuntimeOverrideError2 extends Error {
5308
- code = "invalid_runtime_override";
5309
- reason;
5310
5713
  constructor(reason, message) {
5311
5714
  super(message);
5715
+ this.code = "invalid_runtime_override";
5312
5716
  this.name = "InvalidRuntimeOverrideError";
5313
5717
  this.reason = reason;
5314
5718
  }
@@ -5328,12 +5732,12 @@ function resolveDaemonRuntime2(env, defaults) {
5328
5732
  throw new InvalidRuntimeOverrideError2("paired_values_required", `${OMO_LSP_DAEMON_CLI2} and ${OMO_LSP_DAEMON_VERSION2} must be set together`);
5329
5733
  }
5330
5734
  if (!hasCliOverride || !hasVersionOverride) {
5331
- if (!isAbsolute5(defaults.cliPath)) {
5735
+ if (!isAbsolute6(defaults.cliPath)) {
5332
5736
  throw new InvalidRuntimeOverrideError2("packaged_cli_must_be_absolute", "Packaged LSP daemon CLI path must be absolute");
5333
5737
  }
5334
5738
  return { cliPath: defaults.cliPath, version: validateDaemonVersion2(defaults.version) };
5335
5739
  }
5336
- if (!isAbsolute5(cliOverride)) {
5740
+ if (!isAbsolute6(cliOverride)) {
5337
5741
  throw new InvalidRuntimeOverrideError2("cli_must_be_absolute", `${OMO_LSP_DAEMON_CLI2} must be an absolute path to an existing regular file`);
5338
5742
  }
5339
5743
  const stat = statSync5(cliOverride, { throwIfNoEntry: false });
@@ -5432,8 +5836,8 @@ function normalizeDiagnosticsOutcome(outcome) {
5432
5836
  return normalizeDiagnosticsText(outcome);
5433
5837
  return outcome;
5434
5838
  }
5435
- function normalizeDiagnosticsText(text2) {
5436
- return text2.trim();
5839
+ function normalizeDiagnosticsText(text) {
5840
+ return text.trim();
5437
5841
  }
5438
5842
  function formatDiagnosticsError(error) {
5439
5843
  const message = normalizeDiagnosticsText(error.message);
@@ -5454,15 +5858,14 @@ function extensionKey(filePath) {
5454
5858
  }
5455
5859
  // ../../../../lsp-core/src/request-context.ts
5456
5860
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
5457
- import { existsSync as existsSync12, realpathSync as realpathSync5, statSync as statSync6 } from "node:fs";
5458
- import { basename as basename4, delimiter as delimiter4, dirname as dirname2, isAbsolute as isAbsolute6, join as join7, relative as relative5, resolve as resolve9 } from "node:path";
5861
+ import { existsSync as existsSync13, realpathSync as realpathSync6, statSync as statSync6 } from "node:fs";
5862
+ import { basename as basename4, delimiter as delimiter4, dirname as dirname2, isAbsolute as isAbsolute7, join as join8, relative as relative5, resolve as resolve10 } from "node:path";
5459
5863
 
5460
5864
  class LspRequestContextParseError2 extends Error {
5461
- code;
5462
- name = "LspRequestContextParseError";
5463
5865
  constructor(code, message) {
5464
5866
  super(message);
5465
5867
  this.code = code;
5868
+ this.name = "LspRequestContextParseError";
5466
5869
  }
5467
5870
  }
5468
5871
  var storage2 = new AsyncLocalStorage2;
@@ -5479,37 +5882,37 @@ function parseLspRequestContext2(value) {
5479
5882
  const installDecisionsPath = stringField2(value, "installDecisionsPath");
5480
5883
  const capabilities = capabilitiesField2(value["capabilities"]);
5481
5884
  const canonical = canonicalCwd2(cwd);
5482
- for (const path2 of projectConfigPaths) {
5483
- requireAbsolutePath2(path2, "projectConfigPaths");
5484
- const projectPath = canonicalizeExistingOrNearestAncestor2(path2);
5885
+ for (const path of projectConfigPaths) {
5886
+ requireAbsolutePath2(path, "projectConfigPaths");
5887
+ const projectPath = canonicalizeExistingOrNearestAncestor2(path);
5485
5888
  if (!isPathInside2(canonical, projectPath)) {
5486
- throw new LspRequestContextParseError2("project_config_outside_cwd", `Project LSP config path must be inside cwd: ${path2}`);
5889
+ throw new LspRequestContextParseError2("project_config_outside_cwd", `Project LSP config path must be inside cwd: ${path}`);
5487
5890
  }
5488
5891
  }
5489
5892
  requireAbsolutePath2(userConfigPath, "userConfigPath");
5490
5893
  requireAbsolutePath2(installDecisionsPath, "installDecisionsPath");
5491
5894
  return {
5492
5895
  cwd: canonical,
5493
- projectConfigPaths: projectConfigPaths.map((path2) => canonicalizeExistingOrNearestAncestor2(path2)),
5896
+ projectConfigPaths: projectConfigPaths.map((path) => canonicalizeExistingOrNearestAncestor2(path)),
5494
5897
  userConfigPath,
5495
5898
  installDecisionsPath,
5496
5899
  capabilities
5497
5900
  };
5498
5901
  }
5499
5902
  function canonicalCwd2(cwd) {
5500
- const resolved = resolve9(cwd);
5501
- if (!existsSync12(resolved) || !statSync6(resolved).isDirectory()) {
5903
+ const resolved = resolve10(cwd);
5904
+ if (!existsSync13(resolved) || !statSync6(resolved).isDirectory()) {
5502
5905
  throw new LspRequestContextParseError2("invalid_cwd", `LSP request cwd must be an existing directory: ${cwd}`);
5503
5906
  }
5504
- return realpathSync5(resolved);
5907
+ return realpathSync6(resolved);
5505
5908
  }
5506
- function canonicalizeExistingOrNearestAncestor2(path2) {
5507
- let current = resolve9(path2);
5909
+ function canonicalizeExistingOrNearestAncestor2(path) {
5910
+ let current = resolve10(path);
5508
5911
  const suffix = [];
5509
5912
  while (true) {
5510
5913
  try {
5511
- const existing = realpathSync5(current);
5512
- return suffix.length === 0 ? existing : join7(existing, ...suffix);
5914
+ const existing = realpathSync6(current);
5915
+ return suffix.length === 0 ? existing : join8(existing, ...suffix);
5513
5916
  } catch (error) {
5514
5917
  if (!isMissingPathError2(error))
5515
5918
  throw error;
@@ -5546,15 +5949,15 @@ function stringArrayField2(value, field) {
5546
5949
  }
5547
5950
  return fieldValue;
5548
5951
  }
5549
- function requireAbsolutePath2(path2, field) {
5550
- if (!isAbsolute6(path2)) {
5551
- throw new LspRequestContextParseError2("relative_path", `LSP request context.${field} must be absolute: ${path2}`);
5952
+ function requireAbsolutePath2(path, field) {
5953
+ if (!isAbsolute7(path)) {
5954
+ throw new LspRequestContextParseError2("relative_path", `LSP request context.${field} must be absolute: ${path}`);
5552
5955
  }
5553
5956
  }
5554
5957
  function isPathInside2(parent, child) {
5555
- const childPath = resolve9(child);
5958
+ const childPath = resolve10(child);
5556
5959
  const relativePath = relative5(parent, childPath);
5557
- return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute6(relativePath);
5960
+ return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute7(relativePath);
5558
5961
  }
5559
5962
  function isMissingPathError2(error) {
5560
5963
  const code = errorCode2(error);
@@ -5577,9 +5980,9 @@ function errorCode2(error) {
5577
5980
  }
5578
5981
 
5579
5982
  // src/daemon-cli-path.ts
5580
- import { existsSync as existsSync14, readFileSync as readFileSync6 } from "node:fs";
5983
+ import { existsSync as existsSync14, readFileSync as readFileSync7 } from "node:fs";
5581
5984
  import { createRequire as createRequire2 } from "node:module";
5582
- import { dirname as dirname9, join as join9 } from "node:path";
5985
+ import { dirname as dirname11, join as join9 } from "node:path";
5583
5986
  import { fileURLToPath as fileURLToPath4 } from "node:url";
5584
5987
  var requireFromHere2 = createRequire2(import.meta.url);
5585
5988
  var PACKAGE_LSP_DAEMON_CLI = "@code-yeongyu/lsp-daemon/cli";
@@ -5626,8 +6029,8 @@ function resolveConfiguredLspDaemonCli(cliPath) {
5626
6029
  }
5627
6030
  function readDaemonPackageVersion(cliPath) {
5628
6031
  try {
5629
- const parsed = JSON.parse(readFileSync6(join9(dirname9(cliPath), "package.json"), "utf8"));
5630
- if (isRecord9(parsed) && typeof parsed["version"] === "string" && parsed["version"].length > 0) {
6032
+ const parsed = JSON.parse(readFileSync7(join9(dirname11(cliPath), "package.json"), "utf8"));
6033
+ if (isRecord8(parsed) && typeof parsed["version"] === "string" && parsed["version"].length > 0) {
5631
6034
  return parsed["version"];
5632
6035
  }
5633
6036
  } catch (error) {
@@ -5636,14 +6039,14 @@ function readDaemonPackageVersion(cliPath) {
5636
6039
  }
5637
6040
  return null;
5638
6041
  }
5639
- function isRecord9(value) {
6042
+ function isRecord8(value) {
5640
6043
  return typeof value === "object" && value !== null && !Array.isArray(value);
5641
6044
  }
5642
6045
 
5643
6046
  // src/lsp-session-state.ts
5644
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "node:fs";
6047
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "node:fs";
5645
6048
  import { homedir } from "node:os";
5646
- import { dirname as dirname11, join as join10 } from "node:path";
6049
+ import { dirname as dirname12, join as join10 } from "node:path";
5647
6050
  function sessionIdFrom(input) {
5648
6051
  return typeof input.session_id === "string" && input.session_id.length > 0 ? input.session_id : undefined;
5649
6052
  }
@@ -5672,21 +6075,21 @@ function sessionStatePath(sessionId) {
5672
6075
  const root = process.env["PLUGIN_DATA"] ?? join10(homedir(), ".codex", "codex-lsp");
5673
6076
  return join10(root, "sessions", `${safePathSegment(sessionId)}.json`);
5674
6077
  }
5675
- function readSessionState(path2) {
6078
+ function readSessionState(path) {
5676
6079
  try {
5677
- const parsed = JSON.parse(readFileSync8(path2, "utf8"));
5678
- if (isRecord10(parsed) && isLspSessionState(parsed))
6080
+ const parsed = JSON.parse(readFileSync8(path, "utf8"));
6081
+ if (isRecord9(parsed) && isLspSessionState(parsed))
5679
6082
  return normalizeSessionState(parsed);
5680
6083
  return emptyState();
5681
6084
  } catch (error) {
5682
- if (error instanceof SyntaxError || isRecord10(error) && error["code"] === "ENOENT")
6085
+ if (error instanceof SyntaxError || isRecord9(error) && error["code"] === "ENOENT")
5683
6086
  return emptyState();
5684
6087
  throw error;
5685
6088
  }
5686
6089
  }
5687
- function writeSessionState(path2, state) {
5688
- mkdirSync4(dirname11(path2), { recursive: true });
5689
- writeFileSync3(path2, `${JSON.stringify(state)}
6090
+ function writeSessionState(path, state) {
6091
+ mkdirSync4(dirname12(path), { recursive: true });
6092
+ writeFileSync4(path, `${JSON.stringify(state)}
5690
6093
  `);
5691
6094
  }
5692
6095
  function emptyState() {
@@ -5705,7 +6108,7 @@ function normalizeSessionState(value) {
5705
6108
  notConfiguredExtensions: Array.isArray(notConfiguredExtensions) ? notConfiguredExtensions.filter((item) => typeof item === "string").sort() : []
5706
6109
  };
5707
6110
  }
5708
- function isRecord10(value) {
6111
+ function isRecord9(value) {
5709
6112
  return typeof value === "object" && value !== null && !Array.isArray(value);
5710
6113
  }
5711
6114
 
@@ -5716,7 +6119,7 @@ function extractMutatedFilePaths(input) {
5716
6119
  return [];
5717
6120
  if (isFailedToolResponse(input.tool_response))
5718
6121
  return [];
5719
- const toolInput = isRecord11(input.tool_input) ? input.tool_input : {};
6122
+ const toolInput = isRecord10(input.tool_input) ? input.tool_input : {};
5720
6123
  const paths = new Set;
5721
6124
  addStringValue(paths, toolInput["path"]);
5722
6125
  addStringValue(paths, toolInput["filePath"]);
@@ -5735,7 +6138,7 @@ function isMutationTool(value) {
5735
6138
  return MUTATION_TOOL_NAMES.has(value.toLowerCase());
5736
6139
  }
5737
6140
  function isFailedToolResponse(value) {
5738
- if (!isRecord11(value))
6141
+ if (!isRecord10(value))
5739
6142
  return false;
5740
6143
  return value["isError"] === true || value["is_error"] === true || value["error"] === true || value["status"] === "error";
5741
6144
  }
@@ -5761,9 +6164,9 @@ function addPatchInput(paths, value) {
5761
6164
  return;
5762
6165
  for (const line of value.split(`
5763
6166
  `)) {
5764
- const path2 = extractPatchHeaderPath(line);
5765
- if (path2 !== undefined)
5766
- paths.add(path2);
6167
+ const path = extractPatchHeaderPath(line);
6168
+ if (path !== undefined)
6169
+ paths.add(path);
5767
6170
  }
5768
6171
  }
5769
6172
  function extractPatchHeaderPath(line) {
@@ -5778,7 +6181,7 @@ function addPatchFiles(paths, value) {
5778
6181
  if (!Array.isArray(value))
5779
6182
  return;
5780
6183
  for (const item of value) {
5781
- if (!isRecord11(item))
6184
+ if (!isRecord10(item))
5782
6185
  continue;
5783
6186
  addStringValue(paths, item["path"]);
5784
6187
  addStringValue(paths, item["filePath"]);
@@ -5787,7 +6190,7 @@ function addPatchFiles(paths, value) {
5787
6190
  addStringValue(paths, item["move_path"]);
5788
6191
  }
5789
6192
  }
5790
- function isRecord11(value) {
6193
+ function isRecord10(value) {
5791
6194
  return typeof value === "object" && value !== null && !Array.isArray(value);
5792
6195
  }
5793
6196
 
@@ -5818,10 +6221,10 @@ function postEditOutcomeFromDaemonResult(result) {
5818
6221
  `);
5819
6222
  }
5820
6223
  function notConfiguredAvailability(details) {
5821
- if (!isRecord12(details))
6224
+ if (!isRecord11(details))
5822
6225
  return;
5823
6226
  const availability = details["availability"];
5824
- if (!isRecord12(availability))
6227
+ if (!isRecord11(availability))
5825
6228
  return;
5826
6229
  if (availability["kind"] !== "not_configured")
5827
6230
  return;
@@ -5829,11 +6232,11 @@ function notConfiguredAvailability(details) {
5829
6232
  return typeof extension === "string" && extension.length > 0 ? { extension } : undefined;
5830
6233
  }
5831
6234
  function codexLspRequestContext(env = process.env, cwd = process.cwd()) {
5832
- const canonicalCwd3 = realpathSync7(resolve11(cwd));
6235
+ const canonicalCwd = realpathSync7(resolve11(cwd));
5833
6236
  const codexHome = resolve11(env["CODEX_HOME"]?.trim() || join11(homedir3(), ".codex"));
5834
6237
  return parseLspRequestContext2({
5835
- cwd: canonicalCwd3,
5836
- projectConfigPaths: [join11(canonicalCwd3, ".codex", "lsp-client.json")],
6238
+ cwd: canonicalCwd,
6239
+ projectConfigPaths: [join11(canonicalCwd, ".codex", "lsp-client.json")],
5837
6240
  userConfigPath: join11(codexHome, "lsp-client.json"),
5838
6241
  installDecisionsPath: join11(codexHome, "lsp-install-decisions.json"),
5839
6242
  capabilities: { installDecisionTool: true }
@@ -5936,22 +6339,22 @@ function isContextPressureTranscript(transcriptPath) {
5936
6339
  throw error;
5937
6340
  }
5938
6341
  }
5939
- function hasContextPressureMarker(text2) {
5940
- const normalizedText = text2.toLowerCase();
6342
+ function hasContextPressureMarker(text) {
6343
+ const normalizedText = text.toLowerCase();
5941
6344
  return CONTEXT_PRESSURE_MARKERS.some((marker) => normalizedText.includes(marker));
5942
6345
  }
5943
- function limitHookText(text2, maxChars) {
5944
- if (text2.length <= maxChars)
5945
- return text2;
6346
+ function limitHookText(text, maxChars) {
6347
+ if (text.length <= maxChars)
6348
+ return text;
5946
6349
  const marker = `
5947
6350
 
5948
6351
  [Truncated hook output to ${maxChars} chars to avoid Codex context overflow.]`;
5949
6352
  if (marker.length >= maxChars)
5950
6353
  return marker.slice(0, maxChars);
5951
- const head = text2.slice(0, maxChars - marker.length).replace(/[ \t\r\n]+$/, "");
6354
+ const head = text.slice(0, maxChars - marker.length).replace(/[ \t\r\n]+$/, "");
5952
6355
  return `${head}${marker}`;
5953
6356
  }
5954
- function isRecord12(value) {
6357
+ function isRecord11(value) {
5955
6358
  return typeof value === "object" && value !== null && !Array.isArray(value);
5956
6359
  }
5957
6360
 
@@ -5968,7 +6371,7 @@ async function runHookCli(runHook, stdin) {
5968
6371
  if (!raw.trim())
5969
6372
  return;
5970
6373
  const parsed = JSON.parse(raw);
5971
- const input = isRecord12(parsed) ? parsed : {};
6374
+ const input = isRecord11(parsed) ? parsed : {};
5972
6375
  const output = await runHook(input);
5973
6376
  if (output)
5974
6377
  process.stdout.write(output);
@@ -6011,15 +6414,15 @@ main().catch((error) => {
6011
6414
  });
6012
6415
  async function runPackageLspMcpCli() {
6013
6416
  const cliPath = resolveLspDaemonCliPath();
6014
- const child = spawn3(execPath2, [cliPath, "mcp"], { stdio: "inherit" });
6015
- await new Promise((resolve10, reject) => {
6417
+ const child = spawn3(execPath2, [cliPath, "mcp"], { stdio: "inherit", windowsHide: true });
6418
+ await new Promise((resolve, reject) => {
6016
6419
  child.once("error", reject);
6017
6420
  child.once("exit", (code, signal) => {
6018
6421
  if (code !== null && code !== 0)
6019
6422
  process.exitCode = code;
6020
6423
  if (code === null && signal !== null)
6021
6424
  process.exitCode = 1;
6022
- resolve10();
6425
+ resolve();
6023
6426
  });
6024
6427
  });
6025
6428
  }