oh-my-opencode 5.0.0-beta.6 → 5.0.0-beta.60

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 (990) hide show
  1. package/.agents/command/publish.md +59 -23
  2. package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +1 -3
  3. package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +1 -1
  4. package/.agents/skills/pre-publish-review/SKILL.md +9 -12
  5. package/.agents/skills/publish/SKILL.md +59 -23
  6. package/.agents/skills/senpi-qa/SKILL.md +80 -0
  7. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
  8. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
  9. package/.agents/skills/tech-debt-audit/SKILL.md +6 -76
  10. package/.agents/skills/work-with-pr/SKILL.md +37 -23
  11. package/.opencode/command/publish.md +59 -23
  12. package/.opencode/skills/pre-publish-review/SKILL.md +9 -12
  13. package/.opencode/skills/work-with-pr/SKILL.md +37 -23
  14. package/README.ja.md +65 -60
  15. package/README.ko.md +66 -61
  16. package/README.md +65 -72
  17. package/README.ru.md +62 -60
  18. package/README.zh-cn.md +61 -60
  19. package/THIRD-PARTY-NOTICES.md +27 -99
  20. package/dist/agents/atlas/agent.d.ts +0 -1
  21. package/dist/agents/gpt-prompt-identity.d.ts +1 -1
  22. package/dist/agents/sisyphus/grok-4.d.ts +20 -0
  23. package/dist/agents/sisyphus/index.d.ts +2 -0
  24. package/dist/agents/sisyphus-agent-config.d.ts +6 -0
  25. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  26. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
  27. package/dist/agents/types.d.ts +4 -2
  28. package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
  29. package/dist/cli/doctor/checks/index.d.ts +2 -0
  30. package/dist/cli/doctor/checks/latest-version.d.ts +11 -0
  31. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  32. package/dist/cli/doctor/framework/constants.d.ts +5 -0
  33. package/dist/cli/doctor/framework/types.d.ts +2 -0
  34. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  35. package/dist/cli/index.js +51738 -59690
  36. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  37. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  38. package/dist/cli/runtime-commands.d.ts +1 -1
  39. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  40. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  41. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  42. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  43. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  44. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  45. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  46. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  47. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  48. package/dist/cli-node/index.js +50900 -58829
  49. package/dist/config/index.d.ts +1 -1
  50. package/dist/config/schema/background-task.d.ts +1 -0
  51. package/dist/config/schema/commands.d.ts +1 -1
  52. package/dist/config/schema/hooks.d.ts +1 -2
  53. package/dist/config/schema/oh-my-opencode-config.d.ts +5 -11
  54. package/dist/config/schema/ulw-execute.d.ts +5 -0
  55. package/dist/config/schema.d.ts +0 -1
  56. package/dist/config/validate.d.ts +2 -0
  57. package/dist/create-hooks.d.ts +3 -2
  58. package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +1 -0
  59. package/dist/features/background-agent/constants.d.ts +0 -7
  60. package/dist/features/background-agent/error-classifier.d.ts +1 -0
  61. package/dist/features/background-agent/manager.d.ts +9 -1
  62. package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
  63. package/dist/features/background-agent/parent-wake-notifier-types.d.ts +1 -1
  64. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -1
  65. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -1
  66. package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
  67. package/dist/features/background-agent/types.d.ts +4 -0
  68. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  69. package/dist/features/btw-side/context-injector.d.ts +15 -0
  70. package/dist/features/btw-side/index.d.ts +8 -0
  71. package/dist/features/btw-side/metadata.d.ts +15 -0
  72. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  73. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  74. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  75. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  76. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  77. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  78. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  79. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  80. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  81. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  82. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  83. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  84. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  85. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  86. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  87. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  88. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  89. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  90. package/dist/features/builtin-commands/types.d.ts +1 -1
  91. package/dist/features/claude-tasks/storage.d.ts +7 -2
  92. package/dist/features/hook-message-injector/index.d.ts +1 -0
  93. package/dist/features/hook-message-injector/sdk-message-lookup.d.ts +1 -0
  94. package/dist/features/monitor/manager-internals.d.ts +1 -1
  95. package/dist/features/monitor/output-injector-types.d.ts +1 -1
  96. package/dist/features/opengateway-provider/index.d.ts +13 -0
  97. package/dist/features/task-toast-manager/manager.d.ts +0 -24
  98. package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +17 -0
  99. package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +3 -0
  100. package/dist/features/team-mode/tools/messaging-runtime.d.ts +7 -0
  101. package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
  102. package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
  103. package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
  104. package/dist/hooks/anthropic-context-window-limit-recovery/tool-result-storage.d.ts +11 -0
  105. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  106. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  107. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  108. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  109. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  110. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  111. package/dist/hooks/atlas/types.d.ts +1 -0
  112. package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
  113. package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
  114. package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
  115. package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
  116. package/dist/hooks/compaction-context-injector/validated-model.d.ts +2 -0
  117. package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
  118. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
  119. package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
  120. package/dist/hooks/index.d.ts +1 -2
  121. package/dist/hooks/keyword-detector/hook.d.ts +9 -0
  122. package/dist/hooks/keyword-detector/ultrawork/index.d.ts +2 -0
  123. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
  124. package/dist/hooks/model-fallback/hook.d.ts +1 -1
  125. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  126. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  127. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  128. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  129. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  130. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  131. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  132. package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
  133. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  134. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  135. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  136. package/dist/hooks/unstable-agent-babysitter/task-message-analyzer.d.ts +1 -0
  137. package/dist/index.js +29256 -25391
  138. package/dist/mcp/index.d.ts +0 -4
  139. package/dist/mcp/types.d.ts +0 -1
  140. package/dist/oh-my-opencode.schema.json +21 -47
  141. package/dist/plugin/chat-message/types.d.ts +6 -4
  142. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  143. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  144. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -2
  145. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -3
  146. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  147. package/dist/plugin/messages-transform.d.ts +1 -0
  148. package/dist/plugin/stop-continuation.d.ts +3 -0
  149. package/dist/plugin/system-transform.d.ts +5 -1
  150. package/dist/plugin-dispose.d.ts +3 -0
  151. package/dist/shared/agent-tool-restrictions.d.ts +0 -1
  152. package/dist/shared/compaction-agent-config-checkpoint.d.ts +1 -0
  153. package/dist/shared/index.d.ts +2 -0
  154. package/dist/shared/legacy-plugin-warning.d.ts +2 -1
  155. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  156. package/dist/shared/omo-process-sweep.d.ts +2 -4
  157. package/dist/shared/plugin-entry-migrator.d.ts +4 -3
  158. package/dist/shared/plugin-entry-shape.d.ts +6 -0
  159. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  160. package/dist/shared/shell-env.d.ts +1 -1
  161. package/dist/skills/ast-grep/AGENTS.md +51 -0
  162. package/dist/skills/ast-grep/SKILL.md +1 -1
  163. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  164. package/dist/skills/coding-agent-sessions/SKILL.md +1 -1
  165. package/dist/skills/data-scientist/SKILL.md +99 -239
  166. package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
  167. package/dist/skills/data-scientist/references/placement.md +74 -0
  168. package/dist/skills/data-scientist/references/polars-lane.md +95 -0
  169. package/dist/skills/data-scientist/references/uv-setup.md +1 -1
  170. package/dist/skills/data-scientist/references/visualization.md +64 -0
  171. package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  172. package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  173. package/dist/skills/debugging/SKILL.md +3 -1
  174. package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
  175. package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
  176. package/dist/skills/debugging/references/runtimes/go.md +15 -1
  177. package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
  178. package/dist/skills/debugging/references/runtimes/node.md +25 -0
  179. package/dist/skills/debugging/references/runtimes/python.md +13 -0
  180. package/dist/skills/debugging/references/runtimes/rust.md +41 -0
  181. package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
  182. package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
  183. package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  184. package/dist/skills/debugging/references/tools/dap.md +103 -0
  185. package/dist/skills/debugging/references/tools/frida.md +193 -0
  186. package/dist/skills/frontend/ATTRIBUTION.md +10 -0
  187. package/dist/skills/frontend/SKILL.md +15 -8
  188. package/dist/skills/frontend/references/design/README.md +10 -2
  189. package/dist/skills/frontend/references/design/_INDEX.md +2 -0
  190. package/dist/skills/frontend/references/design/ambience-skill.md +145 -0
  191. package/dist/skills/frontend/references/design/interaction-skill.md +2 -0
  192. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  193. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  194. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  195. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  196. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  197. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  198. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  199. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  200. package/dist/skills/git-master/SKILL.md +1 -1
  201. package/dist/skills/init-deep/SKILL.md +14 -14
  202. package/dist/skills/lsp-setup/SKILL.md +1 -1
  203. package/dist/skills/programming/SKILL.md +1 -1
  204. package/dist/skills/refactor/SKILL.md +4 -4
  205. package/dist/skills/remove-ai-slops/SKILL.md +1 -1
  206. package/dist/skills/review-work/SKILL.md +101 -419
  207. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  208. package/dist/skills/ultimate-browsing/SKILL.md +26 -9
  209. package/dist/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  210. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  211. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  212. package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  213. package/dist/skills/{start-work → ulw-execute}/SKILL.md +20 -19
  214. package/dist/skills/ulw-plan/SKILL.md +7 -8
  215. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  216. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  217. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  218. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  219. package/dist/skills/ulw-research/SKILL.md +8 -3
  220. package/dist/skills/visual-qa/AGENTS.md +58 -0
  221. package/dist/skills/visual-qa/SKILL.md +4 -3
  222. package/dist/tools/delegate-task/builtin-categories.d.ts +3 -1
  223. package/dist/tools/delegate-task/builtin-category-definition.d.ts +2 -1
  224. package/dist/tools/delegate-task/constants.d.ts +2 -2
  225. package/dist/tools/delegate-task/openai-categories.d.ts +7 -2
  226. package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
  227. package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
  228. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  229. package/dist/tools/delegate-task/types.d.ts +4 -0
  230. package/dist/tools/session-manager/directory-filter.d.ts +2 -0
  231. package/dist/tui.d.ts +12 -0
  232. package/dist/tui.js +37048 -46599
  233. package/package.json +47 -41
  234. package/packages/git-bash-mcp/dist/cli.js +6 -1
  235. package/packages/git-bash-mcp/package.json +1 -1
  236. package/packages/lsp-core/src/index.ts +1 -0
  237. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  238. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +57 -48
  239. package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
  240. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  241. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +103 -6
  242. package/packages/lsp-core/src/lsp/client-wrapper.ts +50 -16
  243. package/packages/lsp-core/src/lsp/client.ts +32 -3
  244. package/packages/lsp-core/src/lsp/connection.ts +16 -0
  245. package/packages/lsp-core/src/lsp/constants.ts +6 -0
  246. package/packages/lsp-core/src/lsp/controlled-clock-test-support.ts +61 -0
  247. package/packages/lsp-core/src/lsp/errors.ts +15 -0
  248. package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +10 -3
  249. package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
  250. package/packages/lsp-core/src/lsp/format-document.ts +90 -0
  251. package/packages/lsp-core/src/lsp/json-rpc-connection.ts +11 -6
  252. package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
  253. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
  254. package/packages/lsp-core/src/lsp/manager.ts +138 -12
  255. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  256. package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
  257. package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
  258. package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
  259. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
  260. package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
  261. package/packages/lsp-core/src/lsp/timer-provider.ts +13 -0
  262. package/packages/lsp-core/src/lsp/transport-request-timeout.test.ts +73 -0
  263. package/packages/lsp-core/src/lsp/transport.ts +16 -2
  264. package/packages/lsp-core/src/lsp/types.ts +8 -0
  265. package/packages/lsp-core/src/lsp/workspace-apply-edit-test-support.ts +29 -1
  266. package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +84 -1
  267. package/packages/lsp-core/src/lsp/workspace-document-state.ts +30 -11
  268. package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
  269. package/packages/lsp-core/src/mcp.ts +3 -0
  270. package/packages/lsp-core/src/request-context.test.ts +29 -0
  271. package/packages/lsp-core/src/request-context.ts +1 -1
  272. package/packages/lsp-core/src/tool-surface.test.ts +13 -1
  273. package/packages/lsp-core/src/tools/definitions.ts +14 -0
  274. package/packages/lsp-core/src/tools/format.test.ts +56 -0
  275. package/packages/lsp-core/src/tools/format.ts +56 -0
  276. package/packages/lsp-core/src/tools/index.ts +1 -0
  277. package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
  278. package/packages/lsp-core/src/tools/types.ts +10 -0
  279. package/packages/lsp-daemon/dist/cli.js +902 -479
  280. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  281. package/packages/lsp-daemon/dist/client.js +920 -493
  282. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  283. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  284. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +6 -1
  285. package/packages/lsp-daemon/dist/ensure-daemon.js +10 -2
  286. package/packages/lsp-daemon/dist/index.js +824 -402
  287. package/packages/lsp-daemon/dist/ownership.js +2 -2
  288. package/packages/lsp-daemon/dist/proxy.js +3 -0
  289. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  290. package/packages/lsp-daemon/package.json +1 -1
  291. package/packages/lsp-tools-mcp/dist/cli.js +762 -341
  292. package/packages/lsp-tools-mcp/dist/lsp/manager.js +272 -138
  293. package/packages/lsp-tools-mcp/dist/mcp.js +787 -368
  294. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  295. package/packages/lsp-tools-mcp/dist/tools.js +717 -302
  296. package/packages/lsp-tools-mcp/package.json +1 -1
  297. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -21
  298. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -6
  299. package/packages/omo-codex/plugin/.mcp.json +0 -6
  300. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  301. package/packages/omo-codex/plugin/README.md +6 -2
  302. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +197 -148
  303. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  304. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  305. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  306. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  307. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  308. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  309. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  310. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  311. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  312. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  313. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  314. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  315. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  316. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +1 -1
  317. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +2 -1
  318. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  319. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  320. package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +2 -1
  321. package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +6 -7
  322. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +2 -2
  323. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  324. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/directive.md +2 -0
  325. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +36 -29
  326. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +32 -26
  327. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/types.d.ts +3 -0
  328. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  329. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  330. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +32 -28
  331. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/types.ts +3 -0
  332. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +1 -1
  333. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +137 -28
  334. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +4 -2
  335. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  336. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  337. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  338. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +941 -540
  339. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  340. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  341. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  342. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  343. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  344. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  345. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  346. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  347. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  348. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  349. package/packages/omo-codex/plugin/components/rules/README.md +2 -0
  350. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  351. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +123 -0
  352. package/packages/omo-codex/plugin/components/rules/dist/cli.js +91 -68
  353. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  354. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  355. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  356. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  357. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +15 -5
  358. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  359. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  360. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  361. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  362. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  363. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  364. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  365. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  366. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  367. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  368. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  369. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  370. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  371. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +38 -3
  372. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  373. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  374. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  375. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  376. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +29 -6
  377. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  378. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  379. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  380. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  381. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  382. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  383. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +4 -10
  384. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  385. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  386. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2407 -684
  387. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2411 -689
  388. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  389. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  390. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  391. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  392. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  393. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  394. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -4
  395. package/packages/omo-codex/plugin/components/ultrawork/README.md +2 -0
  396. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
  397. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +1 -1
  398. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
  399. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  400. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
  401. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  402. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-low.toml +1 -1
  403. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +1 -1
  404. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +1 -1
  405. package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +1 -1
  406. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +1 -1
  407. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  408. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  409. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +490 -4
  410. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  411. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -6
  412. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
  413. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -7
  414. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  415. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  416. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  417. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
  418. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
  419. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  420. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  421. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
  422. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
  423. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  424. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +4 -4
  425. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  426. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +6 -6
  427. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  428. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +10 -10
  429. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +16 -16
  430. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +16 -0
  431. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  432. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  433. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  434. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +4 -4
  435. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  436. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  437. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +1 -1
  438. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  439. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +4 -11
  440. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +24 -22
  441. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +19 -0
  442. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  443. package/packages/omo-codex/plugin/components/ulw-loop/README.md +12 -1
  444. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  445. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +26 -13
  446. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +16 -0
  447. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +25 -0
  448. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +10 -4
  449. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +2 -5
  450. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +5 -78
  451. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +12 -0
  452. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +114 -0
  453. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.d.ts +7 -1
  454. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +50 -42
  455. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +2 -2
  456. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +21 -8
  457. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  458. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +12 -1
  459. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +1 -1
  460. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +40 -37
  461. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +1396 -516
  462. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  463. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +28 -8
  464. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +2 -5
  465. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +24 -20
  466. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -0
  467. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +1 -0
  468. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
  469. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +1 -0
  470. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +13 -4
  471. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +1 -0
  472. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +34 -4
  473. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +14 -0
  474. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +29 -0
  475. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +7 -0
  476. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +9 -0
  477. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +12 -0
  478. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +104 -0
  479. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  480. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +65 -9
  481. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  482. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  483. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +72 -117
  484. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.d.ts +2 -0
  485. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +16 -7
  486. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.d.ts +2 -0
  487. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.js +125 -0
  488. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.d.ts +46 -0
  489. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.js +28 -0
  490. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.d.ts +127 -0
  491. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.js +1 -0
  492. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.d.ts +3 -0
  493. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.js +3 -0
  494. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +6 -1
  495. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +195 -29
  496. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.d.ts +9 -0
  497. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.js +227 -0
  498. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +6 -0
  499. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +33 -0
  500. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +20 -6
  501. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +19 -0
  502. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +75 -0
  503. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +17 -4
  504. package/packages/omo-codex/plugin/components/ulw-loop/package.json +6 -6
  505. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +10 -4
  506. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  507. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +32 -8
  508. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +40 -0
  509. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +8 -6
  510. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +5 -98
  511. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +134 -0
  512. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +52 -73
  513. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +10 -4
  514. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +24 -8
  515. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +14 -1
  516. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +52 -46
  517. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +8 -6
  518. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +35 -7
  519. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +34 -28
  520. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  521. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +1 -0
  522. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
  523. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +25 -4
  524. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +39 -4
  525. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +38 -0
  526. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +11 -0
  527. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +123 -0
  528. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +71 -15
  529. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  530. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +92 -136
  531. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +29 -8
  532. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/factory.ts +159 -0
  533. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/manifest.ts +42 -0
  534. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/types.ts +140 -0
  535. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk.ts +3 -0
  536. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +205 -28
  537. package/packages/omo-codex/plugin/components/ulw-loop/src/state-lock.ts +239 -0
  538. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
  539. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +19 -6
  540. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +107 -0
  541. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  542. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +131 -82
  543. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +147 -0
  544. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint.test.ts +16 -22
  545. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +4 -2
  546. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint.test.ts +31 -2
  547. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +2 -0
  548. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-complete-goals.test.ts +3 -1
  549. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +35 -8
  550. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +38 -4
  551. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-json-errors.test.ts +27 -0
  552. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-scope-required.test.ts +144 -0
  553. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +185 -0
  554. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +8 -3
  555. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +6 -0
  556. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +37 -2
  557. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +52 -11
  558. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  559. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/cli-session.ts +4 -0
  560. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +9 -4
  561. package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +67 -0
  562. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  563. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  564. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io-cross-process.test.ts +106 -0
  565. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +36 -2
  566. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  567. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  568. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-fields-messages.test.ts +98 -0
  569. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-lazycodex-surface.test.ts +93 -0
  570. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  571. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +51 -2
  572. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
  573. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  574. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +58 -3
  575. package/packages/omo-codex/plugin/components/ulw-loop/test/review-blockers.test.ts +9 -7
  576. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-contract.test.ts +137 -0
  577. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-session-context.test.ts +148 -0
  578. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +444 -7
  579. package/packages/omo-codex/plugin/components/ulw-loop/test/state-lock.test.ts +218 -0
  580. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  581. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  582. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  583. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +13 -8
  584. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  585. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  586. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  587. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  588. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  589. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  590. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  591. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  592. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +18 -0
  593. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  594. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  595. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  596. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  597. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  598. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  599. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  600. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  601. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  602. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  603. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  604. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  605. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  606. package/packages/omo-codex/plugin/model-catalog.json +16 -7
  607. package/packages/omo-codex/plugin/package-lock.json +676 -524
  608. package/packages/omo-codex/plugin/package.json +2 -3
  609. package/packages/omo-codex/plugin/scripts/AGENTS.md +39 -0
  610. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -2
  611. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  612. package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
  613. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  614. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +16 -7
  615. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +8 -4
  616. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +19 -90
  617. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +1 -1
  618. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +94 -55
  619. package/packages/omo-codex/plugin/shared/package.json +3 -4
  620. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  621. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  622. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  623. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  624. package/packages/omo-codex/plugin/skills/ast-grep/SKILL.md +1 -1
  625. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  626. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +1 -1
  627. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  628. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  629. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  630. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  631. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  632. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  633. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  634. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  635. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +3 -1
  636. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  637. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  638. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  639. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  640. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  641. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  642. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  643. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  644. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  645. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  646. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  647. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +10 -0
  648. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +15 -8
  649. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +10 -2
  650. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +2 -0
  651. package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +145 -0
  652. package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +2 -0
  653. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  654. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  655. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  656. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  657. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  658. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  659. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  660. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  661. package/packages/omo-codex/plugin/skills/git-master/SKILL.md +1 -1
  662. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +18 -16
  663. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +4 -2
  664. package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +1 -1
  665. package/packages/omo-codex/plugin/skills/programming/SKILL.md +1 -1
  666. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +8 -6
  667. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +5 -3
  668. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +114 -422
  669. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  670. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +26 -9
  671. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  672. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  673. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  674. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  675. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +26 -13
  676. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +29 -31
  677. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  678. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +34 -4
  679. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  680. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +32 -8
  681. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -7
  682. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  683. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  684. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  685. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +12 -5
  686. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  687. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +8 -5
  688. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  689. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  690. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +16 -51
  691. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -3
  692. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  693. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +14 -4
  694. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  695. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  696. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  697. package/packages/omo-codex/plugin/test/auto-update.test.mjs +4 -29
  698. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  699. package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
  700. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  701. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -51
  702. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +88 -2
  703. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +5 -6
  704. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  705. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  706. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +35 -35
  707. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +1 -1
  708. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  709. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +107 -15
  710. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +168 -0
  711. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +54 -24
  712. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +18 -119
  713. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  714. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  715. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  716. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  717. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  718. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -5
  719. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  720. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  721. package/packages/omo-codex/scripts/check-model-catalog-parity.mjs +42 -0
  722. package/packages/omo-codex/scripts/install-cache-copy.test.mjs +27 -1
  723. package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +1 -1
  724. package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +2 -1
  725. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
  726. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +5 -5
  727. package/packages/omo-codex/scripts/install-config.test.mjs +15 -17
  728. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2987 -1370
  729. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +3 -4
  730. package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
  731. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  732. package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
  733. package/packages/omo-codex/scripts/install-packaged-local.test.mjs +1 -6
  734. package/packages/{omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md → prompts-core/prompts/ultrawork/codex.md} +26 -20
  735. package/packages/shared-skills/package.json +7 -1
  736. package/packages/shared-skills/skill-source-filter.d.ts +16 -0
  737. package/packages/shared-skills/skill-source-filter.mjs +44 -0
  738. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  739. package/packages/shared-skills/skills/ast-grep/SKILL.md +1 -1
  740. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  741. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +1 -1
  742. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  743. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  744. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  745. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  746. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  747. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  748. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  749. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  750. package/packages/shared-skills/skills/debugging/SKILL.md +3 -1
  751. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  752. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  753. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  754. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  755. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  756. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  757. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  758. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  759. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  760. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  761. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  762. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  763. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -0
  764. package/packages/shared-skills/skills/frontend/SKILL.md +15 -8
  765. package/packages/shared-skills/skills/frontend/references/design/README.md +10 -2
  766. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +2 -0
  767. package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +145 -0
  768. package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +2 -0
  769. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  770. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  771. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  772. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  773. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  774. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  775. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  776. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  777. package/packages/shared-skills/skills/git-master/SKILL.md +1 -1
  778. package/packages/shared-skills/skills/init-deep/SKILL.md +14 -14
  779. package/packages/shared-skills/skills/lsp-setup/SKILL.md +1 -1
  780. package/packages/shared-skills/skills/programming/SKILL.md +1 -1
  781. package/packages/shared-skills/skills/refactor/SKILL.md +4 -4
  782. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
  783. package/packages/shared-skills/skills/review-work/SKILL.md +101 -419
  784. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  785. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +26 -9
  786. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  787. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  788. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  789. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  790. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +20 -19
  791. package/packages/shared-skills/skills/ulw-plan/SKILL.md +7 -8
  792. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  793. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  794. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  795. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  796. package/packages/shared-skills/skills/ulw-research/SKILL.md +8 -3
  797. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  798. package/packages/shared-skills/skills/visual-qa/SKILL.md +4 -3
  799. package/postinstall.mjs +2 -0
  800. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  801. package/script/qa/xterm-live-terminal.mjs +18 -2
  802. package/dist/config/schema/codegraph.d.ts +0 -12
  803. package/dist/config/schema/start-work.d.ts +0 -5
  804. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  805. package/dist/features/builtin-skills/index.d.ts +0 -1
  806. package/dist/features/builtin-skills/skill-file-loader.d.ts +0 -1
  807. package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +0 -1
  808. package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +0 -1
  809. package/dist/features/builtin-skills/skills/debugging.d.ts +0 -1
  810. package/dist/features/builtin-skills/skills/dev-browser.d.ts +0 -1
  811. package/dist/features/builtin-skills/skills/frontend.d.ts +0 -1
  812. package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +0 -1
  813. package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +0 -1
  814. package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +0 -1
  815. package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +0 -1
  816. package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +0 -1
  817. package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +0 -1
  818. package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +0 -1
  819. package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +0 -1
  820. package/dist/features/builtin-skills/skills/git-master-skill-metadata.d.ts +0 -1
  821. package/dist/features/builtin-skills/skills/git-master.d.ts +0 -1
  822. package/dist/features/builtin-skills/skills/index.d.ts +0 -1
  823. package/dist/features/builtin-skills/skills/init-deep.d.ts +0 -1
  824. package/dist/features/builtin-skills/skills/playwright-cli.d.ts +0 -1
  825. package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +0 -1
  826. package/dist/features/builtin-skills/skills/playwright.d.ts +0 -1
  827. package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +0 -1
  828. package/dist/features/builtin-skills/skills/review-work.d.ts +0 -1
  829. package/dist/features/builtin-skills/skills/security-research.d.ts +0 -1
  830. package/dist/features/builtin-skills/skills/security-review.d.ts +0 -1
  831. package/dist/features/builtin-skills/skills/team-mode.d.ts +0 -1
  832. package/dist/features/builtin-skills/skills/visual-qa.d.ts +0 -1
  833. package/dist/features/builtin-skills/skills.d.ts +0 -1
  834. package/dist/features/builtin-skills/types.d.ts +0 -1
  835. package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +0 -1
  836. package/dist/features/claude-code-plugin-loader/command-loader.d.ts +0 -1
  837. package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +0 -1
  838. package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +0 -1
  839. package/dist/features/claude-code-plugin-loader/discovery.d.ts +0 -1
  840. package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +0 -1
  841. package/dist/features/claude-code-plugin-loader/index.d.ts +0 -1
  842. package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +0 -1
  843. package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +0 -1
  844. package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +0 -1
  845. package/dist/features/claude-code-plugin-loader/loader.d.ts +0 -1
  846. package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +0 -1
  847. package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +0 -1
  848. package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +0 -1
  849. package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +0 -1
  850. package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +0 -1
  851. package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +0 -1
  852. package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +0 -1
  853. package/dist/features/claude-code-plugin-loader/types.d.ts +0 -1
  854. package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +0 -17
  855. package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
  856. package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
  857. package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
  858. package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
  859. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
  860. package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
  861. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  862. package/dist/mcp/codegraph.d.ts +0 -16
  863. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  864. package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +0 -1
  865. package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +0 -1
  866. package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +0 -1
  867. package/dist/shared/prompt-async-gate/queue.d.ts +0 -1
  868. package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +0 -1
  869. package/dist/shared/prompt-async-gate/reservations.d.ts +0 -1
  870. package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +0 -1
  871. package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +0 -1
  872. package/dist/shared/prompt-async-gate/timing.d.ts +0 -1
  873. package/dist/shared/prompt-async-gate/types.d.ts +0 -1
  874. package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
  875. package/dist/skills/data-scientist/references/execution-templates.md +0 -197
  876. package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
  877. package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
  878. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  879. package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
  880. package/dist/tools/delegate-task/anthropic-categories.d.ts +0 -2
  881. package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
  882. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  883. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  884. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  885. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  886. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  887. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  888. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  889. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  890. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12149
  891. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9747
  892. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  893. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  894. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  895. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  896. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  897. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  898. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  899. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -309
  900. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -80
  901. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  902. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  903. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  904. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  905. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  906. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -21
  907. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  908. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  909. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  910. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  911. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  912. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  913. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  914. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  915. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  916. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  917. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  918. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  919. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  920. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  921. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  922. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  923. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  924. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  925. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  926. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  927. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  928. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  929. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  930. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  931. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  932. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  933. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  934. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  935. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  936. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  937. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  938. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  939. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  940. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  941. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  942. package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +0 -21
  943. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  944. package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -471
  945. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  946. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  947. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  948. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  949. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  950. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  951. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  952. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  953. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  954. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  955. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  956. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  957. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  958. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  959. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  960. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
  961. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  962. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  963. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  964. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  965. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  966. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  967. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  968. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  969. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  970. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  971. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  972. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  973. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  974. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  975. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  976. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  977. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  978. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  979. /package/packages/omo-codex/plugin/components/{codegraph → ulw-execute-continuation}/LICENSE +0 -0
  980. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  981. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  982. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  983. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  984. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  985. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  986. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  987. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  988. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  989. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  990. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -4,8 +4,8 @@
4
4
  import { argv, stderr } from "node:process";
5
5
 
6
6
  // src/proxy.ts
7
- import { existsSync as existsSync12, realpathSync as realpathSync5 } from "node:fs";
8
- import { basename as basename4, delimiter as delimiter4, dirname as dirname9, isAbsolute as isAbsolute5 } from "node:path";
7
+ import { existsSync as existsSync13, realpathSync as realpathSync6 } from "node:fs";
8
+ import { basename as basename4, delimiter as delimiter4, dirname as dirname11, isAbsolute as isAbsolute6 } from "node:path";
9
9
 
10
10
  // ../mcp-stdio-core/src/record.ts
11
11
  function isPlainRecord(value) {
@@ -184,6 +184,7 @@ async function runJsonRpcStdioServer(config) {
184
184
  const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
185
185
  isClosed = true;
186
186
  config.onIdleTimeout?.();
187
+ config.input.destroy();
187
188
  });
188
189
  const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
189
190
  isClosed = true;
@@ -280,7 +281,11 @@ function createParentWatchdog(config, onDeadParent) {
280
281
  const probeAlive = config.probeAlive ?? isProcessAlive;
281
282
  let fired = false;
282
283
  const timer = setInterval(() => {
283
- if (fired || probeAlive(parentPid))
284
+ if (fired)
285
+ return;
286
+ const alive = probeAlive(parentPid);
287
+ config.onPoll?.(alive);
288
+ if (alive)
284
289
  return;
285
290
  fired = true;
286
291
  onDeadParent(parentPid, pollIntervalMs);
@@ -315,8 +320,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
315
320
  };
316
321
  }
317
322
  // ../lsp-core/src/lsp/client-wrapper.ts
318
- import { existsSync as existsSync9, realpathSync as realpathSync4, statSync as statSync3 } from "node:fs";
319
- import { basename as basename3, dirname as dirname6, join as join4, resolve as resolve7 } from "node:path";
323
+ import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
324
+ import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
320
325
 
321
326
  // ../lsp-core/src/request-context.ts
322
327
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -325,18 +330,17 @@ import { homedir } from "node:os";
325
330
  import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
326
331
 
327
332
  class LspRequestContextParseError extends Error {
328
- code;
329
- name = "LspRequestContextParseError";
330
333
  constructor(code, message) {
331
334
  super(message);
332
335
  this.code = code;
336
+ this.name = "LspRequestContextParseError";
333
337
  }
334
338
  }
335
339
 
336
340
  class LspRequestContextUnavailableError extends Error {
337
- name = "LspRequestContextUnavailableError";
338
341
  constructor() {
339
342
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
343
+ this.name = "LspRequestContextUnavailableError";
340
344
  }
341
345
  }
342
346
  var storage = new AsyncLocalStorage;
@@ -356,7 +360,7 @@ function contextCwd() {
356
360
  }
357
361
  function createStandaloneMcpRequestContext(input = {}) {
358
362
  const env = input.env ?? process.env;
359
- const cwd = canonicalCwd(input.cwd ?? process.cwd());
363
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
360
364
  const home = input.homeDir ?? homedir();
361
365
  const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
362
366
  const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
@@ -499,22 +503,15 @@ function effectiveExtension(filePath) {
499
503
 
500
504
  // ../lsp-core/src/lsp/errors.ts
501
505
  class LspConnectionClosedError extends Error {
502
- serverId;
503
- root;
504
- name = "LspConnectionClosedError";
505
506
  constructor(serverId, root, message) {
506
507
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
507
508
  this.serverId = serverId;
508
509
  this.root = root;
510
+ this.name = "LspConnectionClosedError";
509
511
  }
510
512
  }
511
513
 
512
514
  class LspProcessExitedError extends Error {
513
- serverId;
514
- root;
515
- exitCode;
516
- stderrTail;
517
- name = "LspProcessExitedError";
518
515
  constructor(serverId, root, exitCode, stderrTail) {
519
516
  const stderrSuffix = stderrTail ? `
520
517
  stderr tail: ${stderrTail}` : "";
@@ -523,46 +520,59 @@ stderr tail: ${stderrTail}` : "";
523
520
  this.root = root;
524
521
  this.exitCode = exitCode;
525
522
  this.stderrTail = stderrTail;
523
+ this.name = "LspProcessExitedError";
526
524
  }
527
525
  }
528
526
 
529
527
  class LspRequestTimeoutError extends Error {
530
- method;
531
- stderrTail;
532
- name = "LspRequestTimeoutError";
533
528
  constructor(method, stderrTail) {
534
529
  const stderrSuffix = stderrTail ? `
535
530
  recent stderr: ${stderrTail}` : "";
536
531
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
537
532
  this.method = method;
538
533
  this.stderrTail = stderrTail;
534
+ this.name = "LspRequestTimeoutError";
539
535
  }
540
536
  }
541
537
 
542
538
  class LspInvalidPathError extends Error {
543
- name = "LspInvalidPathError";
539
+ constructor() {
540
+ super(...arguments);
541
+ this.name = "LspInvalidPathError";
542
+ }
544
543
  }
545
544
 
546
545
  class LspServerLookupError extends Error {
547
- lookup;
548
- name = "LspServerLookupError";
549
546
  constructor(message, lookup) {
550
547
  super(message);
551
548
  this.lookup = lookup;
549
+ this.name = "LspServerLookupError";
552
550
  }
553
551
  }
554
552
 
555
553
  class LspServerInitializingError extends Error {
556
- originalError;
557
- name = "LspServerInitializingError";
558
554
  constructor(originalError) {
559
555
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
560
556
  this.originalError = originalError;
557
+ this.name = "LspServerInitializingError";
561
558
  }
562
559
  }
563
560
 
564
561
  class LspProcessSpawnError extends Error {
565
- name = "LspProcessSpawnError";
562
+ constructor() {
563
+ super(...arguments);
564
+ this.name = "LspProcessSpawnError";
565
+ }
566
+ }
567
+
568
+ class LspClientRespawnBudgetExceededError extends Error {
569
+ constructor(serverId, root, retryLimit) {
570
+ super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
571
+ this.serverId = serverId;
572
+ this.root = root;
573
+ this.retryLimit = retryLimit;
574
+ this.name = "LspClientRespawnBudgetExceededError";
575
+ }
566
576
  }
567
577
  function isLspDeadConnectionError(err) {
568
578
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -585,6 +595,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
585
595
  // ../lsp-core/src/lsp/connection.ts
586
596
  import { pathToFileURL } from "node:url";
587
597
 
598
+ // ../lsp-core/src/lsp/timer-provider.ts
599
+ var realTimerProvider = {
600
+ now: () => Date.now(),
601
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
602
+ clearTimeout: (handle) => clearTimeout(handle)
603
+ };
604
+
588
605
  // ../lsp-core/src/lsp/constants.ts
589
606
  var DEFAULT_MAX_REFERENCES = 200;
590
607
  var DEFAULT_MAX_SYMBOLS = 200;
@@ -593,9 +610,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
593
610
  var REQUEST_TIMEOUT_MS = 15000;
594
611
  var INIT_TIMEOUT_MS = 60000;
595
612
  var IDLE_TIMEOUT_MS = 5 * 60000;
613
+ var MAX_RESIDENT_CLIENTS = 6;
596
614
  var REAPER_INTERVAL_MS = 60000;
597
615
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
598
616
  var STOP_SIGKILL_GRACE_MS = 1000;
617
+ var CLIENT_RESPAWN_RETRY_LIMIT = 2;
618
+ var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
599
619
 
600
620
  // ../lsp-core/src/lsp/json-rpc-connection.ts
601
621
  var HEADER_SEPARATOR2 = `\r
@@ -607,20 +627,31 @@ var METHOD_NOT_FOUND = -32601;
607
627
  var INTERNAL_ERROR = -32603;
608
628
 
609
629
  class JsonRpcConnection {
610
- reader;
611
- writer;
612
- pendingRequests = new Map;
613
- notificationHandlers = new Map;
614
- requestHandlers = new Map;
615
- closeHandlers = [];
616
- errorHandlers = [];
617
- inputBuffer = Buffer.alloc(0);
618
- nextRequestId = 1;
619
- listening = false;
620
- disposed = false;
621
630
  constructor(reader, writer) {
622
631
  this.reader = reader;
623
632
  this.writer = writer;
633
+ this.pendingRequests = new Map;
634
+ this.notificationHandlers = new Map;
635
+ this.requestHandlers = new Map;
636
+ this.closeHandlers = [];
637
+ this.errorHandlers = [];
638
+ this.inputBuffer = Buffer.alloc(0);
639
+ this.nextRequestId = 1;
640
+ this.listening = false;
641
+ this.disposed = false;
642
+ this.handleData = (chunk) => {
643
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
644
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
645
+ this.drainInputBuffer();
646
+ };
647
+ this.handleClose = () => {
648
+ for (const handler of this.closeHandlers) {
649
+ handler();
650
+ }
651
+ };
652
+ this.handleStreamError = (error) => {
653
+ this.emitError(error);
654
+ };
624
655
  }
625
656
  listen() {
626
657
  if (this.listening)
@@ -655,7 +686,8 @@ class JsonRpcConnection {
655
686
  let cancelAfterWrite = false;
656
687
  let settled = false;
657
688
  const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
658
- const responsePromise = new Promise((resolve2, reject) => {
689
+ let rejectAfterCancelWrite;
690
+ const responsePromise = new Promise((resolve, reject) => {
659
691
  const cleanup = () => {
660
692
  options.signal?.removeEventListener("abort", onAbort);
661
693
  };
@@ -666,22 +698,26 @@ class JsonRpcConnection {
666
698
  this.pendingRequests.delete(key);
667
699
  cleanup();
668
700
  const rejectCancelled = () => reject(abortError(options.signal));
701
+ rejectAfterCancelWrite = async () => {
702
+ try {
703
+ await writeCancel();
704
+ } catch (error) {
705
+ this.emitError(toError(error));
706
+ }
707
+ rejectCancelled();
708
+ };
669
709
  if (!requestWritten) {
670
710
  cancelAfterWrite = true;
671
- rejectCancelled();
672
711
  return;
673
712
  }
674
- writeCancel().then(rejectCancelled, (error) => {
675
- this.emitError(toError(error));
676
- rejectCancelled();
677
- });
713
+ rejectAfterCancelWrite();
678
714
  };
679
715
  const onAbort = () => settleCancel();
680
716
  this.pendingRequests.set(key, {
681
717
  resolve(result) {
682
718
  settled = true;
683
719
  cleanup();
684
- resolve2(result);
720
+ resolve(result);
685
721
  },
686
722
  reject(error) {
687
723
  settled = true;
@@ -702,7 +738,7 @@ class JsonRpcConnection {
702
738
  await this.writeMessage(message);
703
739
  requestWritten = true;
704
740
  if (cancelAfterWrite)
705
- await writeCancel();
741
+ await rejectAfterCancelWrite?.();
706
742
  } catch (error) {
707
743
  if (settled)
708
744
  return responsePromise;
@@ -741,19 +777,6 @@ class JsonRpcConnection {
741
777
  this.notificationHandlers.clear();
742
778
  this.requestHandlers.clear();
743
779
  }
744
- handleData = (chunk) => {
745
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
746
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
747
- this.drainInputBuffer();
748
- };
749
- handleClose = () => {
750
- for (const handler of this.closeHandlers) {
751
- handler();
752
- }
753
- };
754
- handleStreamError = (error) => {
755
- this.emitError(error);
756
- };
757
780
  drainInputBuffer() {
758
781
  while (true) {
759
782
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
@@ -853,13 +876,13 @@ class JsonRpcConnection {
853
876
  const payload = `Content-Length: ${Buffer.byteLength(body, "utf8")}\r
854
877
  \r
855
878
  ${body}`;
856
- return new Promise((resolve2, reject) => {
879
+ return new Promise((resolve, reject) => {
857
880
  this.writer.write(payload, (error) => {
858
881
  if (error) {
859
882
  reject(error);
860
883
  return;
861
884
  }
862
- resolve2();
885
+ resolve();
863
886
  });
864
887
  });
865
888
  }
@@ -946,9 +969,9 @@ function validateCwd(cwd) {
946
969
  }
947
970
  }
948
971
  function wrap(proc) {
949
- const exitedPromise = new Promise((resolve2) => {
950
- proc.once("close", (code) => resolve2(code ?? 0));
951
- proc.once("error", () => resolve2(1));
972
+ const exitedPromise = new Promise((resolve) => {
973
+ proc.once("close", (code) => resolve(code ?? 0));
974
+ proc.once("error", () => resolve(1));
952
975
  });
953
976
  if (!proc.stdin || !proc.stdout || !proc.stderr) {
954
977
  throw new LspProcessSpawnError("Spawned process is missing one of stdin/stdout/stderr pipes");
@@ -1101,33 +1124,29 @@ function isPosition(value) {
1101
1124
 
1102
1125
  // ../lsp-core/src/lsp/transport.ts
1103
1126
  class LspClientNotStartedError extends Error {
1104
- serverId;
1105
- root;
1106
- name = "LspClientNotStartedError";
1107
1127
  constructor(serverId, root) {
1108
1128
  super("LSP client not started");
1109
1129
  this.serverId = serverId;
1110
1130
  this.root = root;
1131
+ this.name = "LspClientNotStartedError";
1111
1132
  }
1112
1133
  }
1113
1134
 
1114
1135
  class LspClientTransport {
1115
- root;
1116
- server;
1117
- proc = null;
1118
- connection = null;
1119
- stderrBuffer = [];
1120
- processExited = false;
1121
- diagnosticsStore = new Map;
1122
- requestTimeoutMs;
1123
- initializeTimeoutMs;
1124
- workspaceApplyEditHandler = null;
1125
- diagnosticPullSupported = false;
1126
- constructor(root, server2, timeouts = {}) {
1136
+ constructor(root, server, timeouts = {}) {
1127
1137
  this.root = root;
1128
- this.server = server2;
1138
+ this.server = server;
1139
+ this.proc = null;
1140
+ this.connection = null;
1141
+ this.stderrBuffer = [];
1142
+ this.processExited = false;
1143
+ this.diagnosticsStore = new Map;
1144
+ this.workspaceApplyEditHandler = null;
1145
+ this.diagnosticPullSupported = false;
1146
+ this.documentFormattingSupported = false;
1129
1147
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
1130
1148
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
1149
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
1131
1150
  }
1132
1151
  pid() {
1133
1152
  return this.proc?.pid;
@@ -1147,6 +1166,12 @@ class LspClientTransport {
1147
1166
  isDiagnosticPullSupported() {
1148
1167
  return this.diagnosticPullSupported;
1149
1168
  }
1169
+ setDocumentFormattingSupported(supported) {
1170
+ this.documentFormattingSupported = supported;
1171
+ }
1172
+ isDocumentFormattingSupported() {
1173
+ return this.documentFormattingSupported;
1174
+ }
1150
1175
  handlePublishDiagnostics(params) {
1151
1176
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
1152
1177
  }
@@ -1222,7 +1247,7 @@ class LspClientTransport {
1222
1247
  const options = args[1];
1223
1248
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
1224
1249
  const timeoutController = new AbortController;
1225
- const timeoutHandle = setTimeout(() => {
1250
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
1226
1251
  const stderrTail = this.stderrBuffer.slice(-5).join(`
1227
1252
  `);
1228
1253
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -1241,7 +1266,7 @@ class LspClientTransport {
1241
1266
  }
1242
1267
  throw error;
1243
1268
  } finally {
1244
- clearTimeout(timeoutHandle);
1269
+ this.timerProvider.clearTimeout(timeoutHandle);
1245
1270
  combinedSignal.dispose();
1246
1271
  }
1247
1272
  }
@@ -1292,8 +1317,8 @@ class LspClientTransport {
1292
1317
  try {
1293
1318
  proc.kill();
1294
1319
  let timeoutId;
1295
- const timeoutPromise = new Promise((resolve2) => {
1296
- timeoutId = setTimeout(resolve2, STOP_HARD_KILL_TIMEOUT_MS);
1320
+ const timeoutPromise = new Promise((resolve) => {
1321
+ timeoutId = setTimeout(resolve, STOP_HARD_KILL_TIMEOUT_MS);
1297
1322
  });
1298
1323
  await Promise.race([
1299
1324
  proc.exited.then(() => {
@@ -1309,7 +1334,7 @@ class LspClientTransport {
1309
1334
  proc.kill("SIGKILL");
1310
1335
  await Promise.race([
1311
1336
  proc.exited,
1312
- new Promise((resolve2) => setTimeout(resolve2, STOP_SIGKILL_GRACE_MS))
1337
+ new Promise((resolve) => setTimeout(resolve, STOP_SIGKILL_GRACE_MS))
1313
1338
  ]);
1314
1339
  } catch (error) {
1315
1340
  reportBestEffortCleanupError("hard process kill", error instanceof Error ? error : String(error));
@@ -1360,6 +1385,14 @@ function supportsDiagnosticPull(capabilities) {
1360
1385
  return false;
1361
1386
  return Object.hasOwn(capabilities, "diagnosticProvider");
1362
1387
  }
1388
+ function supportsDocumentFormatting(capabilities) {
1389
+ if (capabilities === undefined)
1390
+ return false;
1391
+ const provider = capabilities.documentFormattingProvider;
1392
+ if (provider === undefined || provider === null || provider === false)
1393
+ return false;
1394
+ return provider === true || typeof provider === "object";
1395
+ }
1363
1396
 
1364
1397
  class LspClientConnection extends LspClientTransport {
1365
1398
  async initialize() {
@@ -1376,6 +1409,7 @@ class LspClientConnection extends LspClientTransport {
1376
1409
  references: {},
1377
1410
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
1378
1411
  publishDiagnostics: {},
1412
+ formatting: { dynamicRegistration: false },
1379
1413
  rename: {
1380
1414
  prepareSupport: true,
1381
1415
  prepareSupportDefaultBehavior: 1
@@ -1417,6 +1451,7 @@ class LspClientConnection extends LspClientTransport {
1417
1451
  initializationOptions: this.server.initialization
1418
1452
  }, { timeoutMs: this.initializeTimeoutMs });
1419
1453
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
1454
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
1420
1455
  await this.sendNotification("initialized", {});
1421
1456
  await this.sendNotification("workspace/didChangeConfiguration", {
1422
1457
  settings: { json: { validate: { enable: true } } }
@@ -1612,6 +1647,17 @@ function canonicalPath(filePath) {
1612
1647
  return absolute;
1613
1648
  }
1614
1649
  }
1650
+ function normalizeDocumentUri(uri) {
1651
+ let decoded = uri;
1652
+ try {
1653
+ decoded = decodeURIComponent(uri);
1654
+ } catch {
1655
+ decoded = uri;
1656
+ }
1657
+ if (process.platform !== "win32")
1658
+ return decoded;
1659
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1660
+ }
1615
1661
  function isSameOrDescendant(candidate, parent) {
1616
1662
  const suffix = relative2(parent, candidate);
1617
1663
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1622,17 +1668,18 @@ function movedPath(candidate, oldPath, newPath) {
1622
1668
  }
1623
1669
 
1624
1670
  class WorkspaceDocumentState {
1625
- sendNotification;
1626
- clearDiagnostics;
1627
- openDocuments = new Map;
1628
- openByUri = new Map;
1629
- openPromises = new Map;
1630
- now;
1631
- versionlessPublishQuiescenceMs;
1632
1671
  constructor(sendNotification, clearDiagnostics, options = {}) {
1633
1672
  this.sendNotification = sendNotification;
1634
1673
  this.clearDiagnostics = clearDiagnostics;
1635
- this.now = options.now ?? (() => Date.now());
1674
+ this.openDocuments = new Map;
1675
+ this.openByUri = new Map;
1676
+ this.openPromises = new Map;
1677
+ this.timerProvider = options.timerProvider ?? {
1678
+ now: options.now ?? (() => Date.now()),
1679
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1680
+ clearTimeout: (handle) => clearTimeout(handle)
1681
+ };
1682
+ this.now = () => this.timerProvider.now();
1636
1683
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1637
1684
  }
1638
1685
  async openFile(filePath) {
@@ -1654,7 +1701,7 @@ class WorkspaceDocumentState {
1654
1701
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1655
1702
  }
1656
1703
  getStoredDiagnostics(uri) {
1657
- const state = this.openByUri.get(uri);
1704
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1658
1705
  if (!state)
1659
1706
  return [];
1660
1707
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1676,13 +1723,13 @@ class WorkspaceDocumentState {
1676
1723
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1677
1724
  }
1678
1725
  getPullCache(snapshot) {
1679
- const state = this.openByUri.get(snapshot.uri);
1726
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1680
1727
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1681
1728
  return null;
1682
1729
  return state.pullCache;
1683
1730
  }
1684
1731
  recordPullDiagnostics(snapshot, report) {
1685
- const state = this.openByUri.get(snapshot.uri);
1732
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1686
1733
  if (!state)
1687
1734
  return;
1688
1735
  state.pullCache = {
@@ -1692,7 +1739,7 @@ class WorkspaceDocumentState {
1692
1739
  };
1693
1740
  }
1694
1741
  recordPublishedDiagnostics(params) {
1695
- const state = this.openByUri.get(params.uri);
1742
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1696
1743
  if (!state)
1697
1744
  return;
1698
1745
  state.publishGeneration += 1;
@@ -1706,7 +1753,7 @@ class WorkspaceDocumentState {
1706
1753
  this.notifyWaiters(state);
1707
1754
  }
1708
1755
  resolvePushDiagnostics(snapshot) {
1709
- const state = this.openByUri.get(snapshot.uri);
1756
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1710
1757
  if (!state?.lastPublish)
1711
1758
  return { status: "missing" };
1712
1759
  const publish = state.lastPublish;
@@ -1720,7 +1767,7 @@ class WorkspaceDocumentState {
1720
1767
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1721
1768
  }
1722
1769
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1723
- const state = this.openByUri.get(snapshot.uri);
1770
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1724
1771
  if (!state || timeoutMs <= 0)
1725
1772
  return Promise.resolve();
1726
1773
  return new Promise((resolveActivity) => {
@@ -1729,11 +1776,11 @@ class WorkspaceDocumentState {
1729
1776
  if (settled)
1730
1777
  return;
1731
1778
  settled = true;
1732
- clearTimeout(timer);
1779
+ this.timerProvider.clearTimeout(timer);
1733
1780
  state.waiters.delete(finish);
1734
1781
  resolveActivity();
1735
1782
  };
1736
- const timer = setTimeout(finish, timeoutMs);
1783
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1737
1784
  if (typeof timer.unref === "function")
1738
1785
  timer.unref();
1739
1786
  state.waiters.add(finish);
@@ -1841,7 +1888,7 @@ class WorkspaceDocumentState {
1841
1888
  waiters: new Set
1842
1889
  };
1843
1890
  this.openDocuments.set(path, state);
1844
- this.openByUri.set(state.uri, state);
1891
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
1845
1892
  this.notifyWaiters(state);
1846
1893
  await this.sendNotification("textDocument/didOpen", {
1847
1894
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -1866,7 +1913,7 @@ class WorkspaceDocumentState {
1866
1913
  }
1867
1914
  async closeDocument(state) {
1868
1915
  this.openDocuments.delete(state.path);
1869
- this.openByUri.delete(state.uri);
1916
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
1870
1917
  this.clearDiagnostics(state.uri);
1871
1918
  this.notifyWaiters(state);
1872
1919
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -1895,13 +1942,11 @@ import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3,
1895
1942
  import { fileURLToPath } from "node:url";
1896
1943
 
1897
1944
  class WorkspaceEditPathError extends Error {
1898
- path;
1899
- detail;
1900
- name = "WorkspaceEditPathError";
1901
1945
  constructor(path, detail) {
1902
1946
  super(`${detail}: ${path}`);
1903
1947
  this.path = path;
1904
1948
  this.detail = detail;
1949
+ this.name = "WorkspaceEditPathError";
1905
1950
  }
1906
1951
  }
1907
1952
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -2193,13 +2238,11 @@ function canonicalFingerprint(operations) {
2193
2238
 
2194
2239
  // ../lsp-core/src/lsp/workspace-edit-types.ts
2195
2240
  class WorkspaceEditValidationError extends Error {
2196
- changeIndex;
2197
- detail;
2198
- name = "WorkspaceEditValidationError";
2199
2241
  constructor(changeIndex, detail) {
2200
2242
  super(`change ${changeIndex}: ${detail}`);
2201
2243
  this.changeIndex = changeIndex;
2202
2244
  this.detail = detail;
2245
+ this.name = "WorkspaceEditValidationError";
2203
2246
  }
2204
2247
  }
2205
2248
 
@@ -2285,14 +2328,14 @@ function parseSinglePathResource(input, kind) {
2285
2328
  return;
2286
2329
  }
2287
2330
  if (kind === "create") {
2288
- const options2 = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
2331
+ const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
2289
2332
  target.operations.push({
2290
2333
  kind,
2291
2334
  changeIndex,
2292
2335
  path: resolvedPath.path,
2293
2336
  reportedPath: resolvedPath.requestedPath,
2294
- overwrite: options2["overwrite"] ?? false,
2295
- ignoreIfExists: options2["ignoreIfExists"] ?? false,
2337
+ overwrite: options["overwrite"] ?? false,
2338
+ ignoreIfExists: options["ignoreIfExists"] ?? false,
2296
2339
  followedSymbolicLink: resolvedPath.followedSymbolicLink
2297
2340
  });
2298
2341
  return;
@@ -2697,10 +2740,9 @@ function simulateDelete(operation, virtual) {
2697
2740
  import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
2698
2741
  import { dirname as dirname4, resolve as resolve5 } from "node:path";
2699
2742
  class WorkspaceSnapshotBuilder {
2700
- workspaceRoot;
2701
- snapshots = new Map;
2702
2743
  constructor(workspaceRoot) {
2703
2744
  this.workspaceRoot = workspaceRoot;
2745
+ this.snapshots = new Map;
2704
2746
  }
2705
2747
  build(operations) {
2706
2748
  this.add(this.workspaceRoot, false);
@@ -2744,8 +2786,10 @@ function snapshotOperations(operations, workspaceRoot) {
2744
2786
 
2745
2787
  // ../lsp-core/src/lsp/workspace-edit-plan.ts
2746
2788
  class PlanPathIndex {
2747
- firstChangeByPath = new Map;
2748
- reportedPathByCanonical = new Map;
2789
+ constructor() {
2790
+ this.firstChangeByPath = new Map;
2791
+ this.reportedPathByCanonical = new Map;
2792
+ }
2749
2793
  build(operations) {
2750
2794
  for (const operation of operations) {
2751
2795
  switch (operation.kind) {
@@ -2761,11 +2805,11 @@ class PlanPathIndex {
2761
2805
  }
2762
2806
  }
2763
2807
  }
2764
- add(path, reportedPath2, changeIndex) {
2808
+ add(path, reportedPath, changeIndex) {
2765
2809
  if (!this.firstChangeByPath.has(path))
2766
2810
  this.firstChangeByPath.set(path, changeIndex);
2767
2811
  if (!this.reportedPathByCanonical.has(path))
2768
- this.reportedPathByCanonical.set(path, reportedPath2);
2812
+ this.reportedPathByCanonical.set(path, reportedPath);
2769
2813
  }
2770
2814
  }
2771
2815
  function fingerprintWorkspaceEdit(edit, workspaceRoot) {
@@ -2834,14 +2878,11 @@ function isRecord4(value) {
2834
2878
  }
2835
2879
 
2836
2880
  class WorkspaceMutationController {
2837
- workspaceRoot;
2838
- documents;
2839
- activeLease = null;
2840
- nextLeaseId = 1;
2841
- io;
2842
2881
  constructor(workspaceRoot, documents) {
2843
2882
  this.workspaceRoot = workspaceRoot;
2844
2883
  this.documents = documents;
2884
+ this.activeLease = null;
2885
+ this.nextLeaseId = 1;
2845
2886
  }
2846
2887
  setIo(io) {
2847
2888
  this.io = io;
@@ -2880,15 +2921,15 @@ class WorkspaceMutationController {
2880
2921
  };
2881
2922
  }
2882
2923
  lease.phase = "applying";
2883
- lease.applyCompletion = new Promise((resolve6) => {
2884
- lease.resolveApply = resolve6;
2924
+ lease.applyCompletion = new Promise((resolve) => {
2925
+ lease.resolveApply = resolve;
2885
2926
  });
2886
2927
  const edit = isRecord4(params) ? params["edit"] : undefined;
2887
- const record2 = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
2888
- lease.serverApply = record2;
2928
+ const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
2929
+ lease.serverApply = record;
2889
2930
  lease.phase = "settled";
2890
2931
  lease.resolveApply?.();
2891
- return responseFor(record2.result);
2932
+ return responseFor(record.result);
2892
2933
  }
2893
2934
  async reconcileRename(leaseToken, edit) {
2894
2935
  const lease = this.requireActiveLease(leaseToken);
@@ -2904,16 +2945,16 @@ class WorkspaceMutationController {
2904
2945
  const applied = await this.applyEdit(edit, lease);
2905
2946
  return { edit, apply: applied.result };
2906
2947
  }
2907
- reconcileServerApply(record2, edit) {
2948
+ reconcileServerApply(record, edit) {
2908
2949
  if (!edit)
2909
- return { edit, apply: record2.result };
2950
+ return { edit, apply: record.result };
2910
2951
  const fingerprint = fingerprintWorkspaceEdit(edit, this.workspaceRoot);
2911
- if (fingerprint.success && record2.fingerprint !== null && fingerprint.fingerprint === record2.fingerprint) {
2912
- return { edit, apply: record2.result };
2952
+ if (fingerprint.success && record.fingerprint !== null && fingerprint.fingerprint === record.fingerprint) {
2953
+ return { edit, apply: record.result };
2913
2954
  }
2914
2955
  return {
2915
2956
  edit,
2916
- apply: failure("rename result conflicts with server-applied workspace edit", 0, record2.result)
2957
+ apply: failure("rename result conflicts with server-applied workspace edit", 0, record.result)
2917
2958
  };
2918
2959
  }
2919
2960
  async applyEdit(edit, lease) {
@@ -2954,14 +2995,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
2954
2995
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
2955
2996
 
2956
2997
  class LspClient extends LspClientConnection {
2957
- diagnosticPullErrors = [];
2958
- documents;
2959
- workspaceMutations;
2960
- diagnosticsFreshnessTimeoutMs;
2961
- constructor(root, server2, options = {}) {
2962
- super(root, server2, options);
2998
+ constructor(root, server, options = {}) {
2999
+ super(root, server, options);
3000
+ this.diagnosticPullErrors = [];
2963
3001
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2964
3002
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
3003
+ timerProvider: this.timerProvider,
2965
3004
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
2966
3005
  });
2967
3006
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -3014,6 +3053,18 @@ class LspClient extends LspClientConnection {
3014
3053
  textDocument: { uri: pathToFileURL3(absPath).href }
3015
3054
  }, options);
3016
3055
  }
3056
+ async formatDocument(filePath, options, signal) {
3057
+ if (!this.isDocumentFormattingSupported())
3058
+ return null;
3059
+ const absPath = this.resolveWorkspacePath(filePath);
3060
+ await this.openFile(absPath);
3061
+ const requestOptions = signal === undefined ? {} : { signal };
3062
+ const edits = await this.sendRequest("textDocument/formatting", {
3063
+ textDocument: { uri: pathToFileURL3(absPath).href },
3064
+ options
3065
+ }, requestOptions);
3066
+ return edits ?? [];
3067
+ }
3017
3068
  async workspaceSymbols(query, signal) {
3018
3069
  const options = signal === undefined ? {} : { signal };
3019
3070
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -3053,7 +3104,7 @@ class LspClient extends LspClientConnection {
3053
3104
  const absPath = this.resolveWorkspacePath(filePath);
3054
3105
  const uri = pathToFileURL3(absPath).href;
3055
3106
  await this.openFile(absPath);
3056
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
3107
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
3057
3108
  for (;; ) {
3058
3109
  signal?.throwIfAborted();
3059
3110
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -3066,13 +3117,13 @@ class LspClient extends LspClientConnection {
3066
3117
  if (!pushFallbackOnly) {
3067
3118
  const cached = this.documents.getPullCache(snapshot);
3068
3119
  try {
3069
- const remainingMs2 = deadlineAt - Date.now();
3070
- if (remainingMs2 <= 0)
3120
+ const remainingMs = deadlineAt - this.timerProvider.now();
3121
+ if (remainingMs <= 0)
3071
3122
  return this.freshnessTimeout(absPath);
3072
3123
  const result = await this.sendRequest("textDocument/diagnostic", {
3073
3124
  textDocument: { uri },
3074
3125
  ...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
3075
- }, { timeoutMs: remainingMs2, ...signal === undefined ? {} : { signal } });
3126
+ }, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
3076
3127
  if (!this.documents.isCurrentSnapshot(snapshot))
3077
3128
  continue;
3078
3129
  const report = this.parseDiagnosticPullReport(result);
@@ -3101,7 +3152,7 @@ class LspClient extends LspClientConnection {
3101
3152
  }
3102
3153
  if (!pushFallbackOnly)
3103
3154
  continue;
3104
- const remainingMs = deadlineAt - Date.now();
3155
+ const remainingMs = deadlineAt - this.timerProvider.now();
3105
3156
  if (remainingMs <= 0) {
3106
3157
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
3107
3158
  const cached = this.documents.getPullCache(snapshot);
@@ -3153,7 +3204,7 @@ function waitForDiagnosticsActivity(wait, signal) {
3153
3204
  return wait;
3154
3205
  if (signal.aborted)
3155
3206
  return Promise.reject(abortError2(signal));
3156
- return new Promise((resolve7, reject) => {
3207
+ return new Promise((resolve, reject) => {
3157
3208
  const onAbort = () => {
3158
3209
  signal.removeEventListener("abort", onAbort);
3159
3210
  reject(abortError2(signal));
@@ -3161,7 +3212,7 @@ function waitForDiagnosticsActivity(wait, signal) {
3161
3212
  signal.addEventListener("abort", onAbort, { once: true });
3162
3213
  wait.then(() => {
3163
3214
  signal.removeEventListener("abort", onAbort);
3164
- resolve7();
3215
+ resolve();
3165
3216
  }, (error) => {
3166
3217
  signal.removeEventListener("abort", onAbort);
3167
3218
  reject(error);
@@ -3229,7 +3280,7 @@ async function stopClientBestEffort(client) {
3229
3280
  function awaitWithSignal(promise, signal) {
3230
3281
  if (!signal)
3231
3282
  return promise;
3232
- return new Promise((resolve7, reject) => {
3283
+ return new Promise((resolve, reject) => {
3233
3284
  let settled = false;
3234
3285
  const onAbort = () => {
3235
3286
  if (settled)
@@ -3247,7 +3298,7 @@ function awaitWithSignal(promise, signal) {
3247
3298
  return;
3248
3299
  settled = true;
3249
3300
  signal.removeEventListener("abort", onAbort);
3250
- resolve7(value);
3301
+ resolve(value);
3251
3302
  }, (err) => {
3252
3303
  if (settled)
3253
3304
  return;
@@ -3259,20 +3310,18 @@ function awaitWithSignal(promise, signal) {
3259
3310
  }
3260
3311
 
3261
3312
  class LspManager {
3262
- clients = new Map;
3263
- reaperHandle = null;
3264
- signalDisposer = null;
3265
- disposed = false;
3266
- idleTimeoutMs;
3267
- initTimeoutMs;
3268
- reaperIntervalMs;
3269
- clientFactory;
3270
- now;
3271
3313
  constructor(options = {}) {
3314
+ this.clients = new Map;
3315
+ this.pendingStops = new Map;
3316
+ this.respawnBudgets = new Map;
3317
+ this.reaperHandle = null;
3318
+ this.signalDisposer = null;
3319
+ this.disposed = false;
3272
3320
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
3273
3321
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
3322
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
3274
3323
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
3275
- this.clientFactory = options.clientFactory ?? ((root, server2) => new LspClient(root, server2));
3324
+ this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
3276
3325
  this.now = options.now ?? (() => Date.now());
3277
3326
  this.startReaper();
3278
3327
  this.signalDisposer = installProcessSignalCleanup(() => this.stopAll());
@@ -3290,38 +3339,103 @@ class LspManager {
3290
3339
  getKey(root, serverId) {
3291
3340
  return `${root}::${serverId}`;
3292
3341
  }
3342
+ tombstoneStop(key, client) {
3343
+ const stop = stopClientBestEffort(client);
3344
+ this.pendingStops.set(key, stop);
3345
+ stop.finally(() => {
3346
+ if (this.pendingStops.get(key) === stop) {
3347
+ this.pendingStops.delete(key);
3348
+ }
3349
+ });
3350
+ return stop;
3351
+ }
3352
+ recordDeadGeneration(key) {
3353
+ let budget = this.respawnBudgets.get(key);
3354
+ if (budget === undefined) {
3355
+ budget = { deadGenerations: 0, exhaustedAt: null };
3356
+ this.respawnBudgets.set(key, budget);
3357
+ }
3358
+ budget.deadGenerations += 1;
3359
+ }
3360
+ markHealthyGeneration(key) {
3361
+ this.respawnBudgets.delete(key);
3362
+ }
3363
+ ensureRespawnAllowed(key, root, serverId) {
3364
+ const budget = this.respawnBudgets.get(key);
3365
+ if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
3366
+ return;
3367
+ if (budget.exhaustedAt === null) {
3368
+ budget.exhaustedAt = this.now();
3369
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3370
+ }
3371
+ if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
3372
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3373
+ }
3374
+ budget.deadGenerations = 0;
3375
+ budget.exhaustedAt = null;
3376
+ }
3293
3377
  reapStale() {
3294
3378
  const t = this.now();
3295
3379
  for (const [key, managed] of this.clients) {
3296
3380
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3297
- stopClientBestEffort(managed.client);
3298
3381
  this.clients.delete(key);
3382
+ this.tombstoneStop(key, managed.client);
3299
3383
  continue;
3300
3384
  }
3301
3385
  if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
3302
- stopClientBestEffort(managed.client);
3303
3386
  this.clients.delete(key);
3387
+ this.tombstoneStop(key, managed.client);
3304
3388
  }
3305
3389
  }
3306
3390
  }
3391
+ evictForAdmission() {
3392
+ while (this.clients.size >= this.maxResidentClients) {
3393
+ const victim = this.leastRecentlyUsedIdleClient();
3394
+ if (!victim)
3395
+ return;
3396
+ this.clients.delete(victim.key);
3397
+ this.tombstoneStop(victim.key, victim.managed.client);
3398
+ }
3399
+ }
3400
+ leastRecentlyUsedIdleClient() {
3401
+ let candidate = null;
3402
+ for (const [key, managed] of this.clients) {
3403
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
3404
+ continue;
3405
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
3406
+ candidate = { key, managed };
3407
+ }
3408
+ }
3409
+ return candidate;
3410
+ }
3307
3411
  async tryDeleteIfOrphaned(key, managed) {
3308
3412
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
3309
3413
  this.clients.delete(key);
3310
- await stopClientBestEffort(managed.client);
3414
+ await this.tombstoneStop(key, managed.client);
3311
3415
  }
3312
3416
  }
3313
- async getClient(root, server2, signal) {
3417
+ async getClient(root, server, signal) {
3314
3418
  if (this.disposed) {
3315
3419
  throw new Error("LspManager has been disposed");
3316
3420
  }
3317
3421
  signal?.throwIfAborted();
3318
- const key = this.getKey(root, server2.id);
3422
+ const key = this.getKey(root, server.id);
3423
+ for (;; ) {
3424
+ const pendingStop = this.pendingStops.get(key);
3425
+ if (pendingStop === undefined)
3426
+ break;
3427
+ await awaitWithSignal(pendingStop, signal);
3428
+ signal?.throwIfAborted();
3429
+ }
3430
+ if (this.disposed) {
3431
+ throw new Error("LspManager has been disposed");
3432
+ }
3319
3433
  let managed = this.clients.get(key);
3320
3434
  if (managed) {
3321
3435
  const t = this.now();
3322
3436
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3323
- await stopClientBestEffort(managed.client);
3324
3437
  this.clients.delete(key);
3438
+ await this.tombstoneStop(key, managed.client);
3325
3439
  managed = undefined;
3326
3440
  }
3327
3441
  }
@@ -3342,15 +3456,21 @@ class LspManager {
3342
3456
  signal.throwIfAborted();
3343
3457
  }
3344
3458
  if (!managed.client.isAlive()) {
3345
- await stopClientBestEffort(managed.client);
3346
- this.clients.delete(key);
3347
- return this.getClient(root, server2, signal);
3459
+ this.recordDeadGeneration(key);
3460
+ if (this.clients.get(key) === managed) {
3461
+ this.clients.delete(key);
3462
+ }
3463
+ await this.tombstoneStop(key, managed.client);
3464
+ return this.getClient(root, server, signal);
3348
3465
  }
3466
+ this.markHealthyGeneration(key);
3349
3467
  managed.refCount++;
3350
3468
  managed.lastUsedAt = this.now();
3351
3469
  return managed.client;
3352
3470
  }
3353
- const client = this.clientFactory(root, server2);
3471
+ this.evictForAdmission();
3472
+ this.ensureRespawnAllowed(key, root, server.id);
3473
+ const client = this.clientFactory(root, server);
3354
3474
  const initStartedAt = this.now();
3355
3475
  const initPromise = (async () => {
3356
3476
  await client.start();
@@ -3373,7 +3493,7 @@ class LspManager {
3373
3493
  if (this.clients.get(key) === newManaged) {
3374
3494
  this.clients.delete(key);
3375
3495
  }
3376
- await stopClientBestEffort(client);
3496
+ await this.tombstoneStop(key, client);
3377
3497
  throw err;
3378
3498
  }
3379
3499
  newManaged.pendingWaiters--;
@@ -3384,6 +3504,15 @@ class LspManager {
3384
3504
  await this.tryDeleteIfOrphaned(key, newManaged);
3385
3505
  signal.throwIfAborted();
3386
3506
  }
3507
+ if (!client.isAlive()) {
3508
+ this.recordDeadGeneration(key);
3509
+ if (this.clients.get(key) === newManaged) {
3510
+ this.clients.delete(key);
3511
+ }
3512
+ await this.tombstoneStop(key, client);
3513
+ return this.getClient(root, server, signal);
3514
+ }
3515
+ this.markHealthyGeneration(key);
3387
3516
  newManaged.refCount++;
3388
3517
  newManaged.lastUsedAt = this.now();
3389
3518
  return client;
@@ -3404,15 +3533,21 @@ class LspManager {
3404
3533
  if (client && managed.client !== client)
3405
3534
  return;
3406
3535
  this.clients.delete(key);
3407
- stopClientBestEffort(managed.client);
3536
+ this.tombstoneStop(key, managed.client);
3408
3537
  }
3409
- warmupClient(root, server2) {
3538
+ warmupClient(root, server) {
3410
3539
  if (this.disposed)
3411
3540
  return;
3412
- const key = this.getKey(root, server2.id);
3413
- if (this.clients.has(key))
3541
+ const key = this.getKey(root, server.id);
3542
+ if (this.clients.has(key) || this.pendingStops.has(key))
3543
+ return;
3544
+ this.evictForAdmission();
3545
+ try {
3546
+ this.ensureRespawnAllowed(key, root, server.id);
3547
+ } catch {
3414
3548
  return;
3415
- const client = this.clientFactory(root, server2);
3549
+ }
3550
+ const client = this.clientFactory(root, server);
3416
3551
  const initStartedAt = this.now();
3417
3552
  const initPromise = (async () => {
3418
3553
  await client.start();
@@ -3437,7 +3572,7 @@ class LspManager {
3437
3572
  if (this.clients.get(key) === managed) {
3438
3573
  this.clients.delete(key);
3439
3574
  }
3440
- stopClientBestEffort(client);
3575
+ this.tombstoneStop(key, client);
3441
3576
  });
3442
3577
  }
3443
3578
  isServerInitializing(root, serverId) {
@@ -3481,8 +3616,11 @@ class LspManager {
3481
3616
  for (const managed of this.clients.values()) {
3482
3617
  stopPromises.push(stopClientBestEffort(managed.client));
3483
3618
  }
3619
+ const tombstonedStops = [...this.pendingStops.values()];
3484
3620
  this.clients.clear();
3485
- await Promise.allSettled(stopPromises);
3621
+ this.respawnBudgets.clear();
3622
+ await Promise.allSettled([...stopPromises, ...tombstonedStops]);
3623
+ this.pendingStops.clear();
3486
3624
  }
3487
3625
  }
3488
3626
  var _defaultInstance = null;
@@ -3500,57 +3638,52 @@ async function disposeDefaultLspManager() {
3500
3638
  }
3501
3639
  }
3502
3640
 
3503
- // ../lsp-core/src/lsp/server-install-state.ts
3504
- import { existsSync as existsSync6, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3505
- import { dirname as dirname5 } from "node:path";
3506
- function getInstallDecisionsPath() {
3507
- return lspRequestContext().installDecisionsPath;
3508
- }
3509
- function loadInstallDecisions() {
3510
- const path = getInstallDecisionsPath();
3511
- if (!existsSync6(path))
3512
- return {};
3513
- try {
3514
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
3515
- return isInstallDecisions(parsed) ? parsed : {};
3516
- } catch {
3517
- return {};
3641
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3642
+ import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
3643
+ import { dirname as dirname5, join as join3 } from "node:path";
3644
+
3645
+ // ../lsp-core/src/lsp/workspace-markers.ts
3646
+ var GIT_WORKSPACE_MARKER = ".git";
3647
+ var PROJECT_WORKSPACE_MARKERS = [
3648
+ "package.json",
3649
+ "pyproject.toml",
3650
+ "Cargo.toml",
3651
+ "go.mod",
3652
+ "pom.xml",
3653
+ "build.gradle"
3654
+ ];
3655
+ var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
3656
+
3657
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3658
+ function findWorkspaceRootOutsideContext(directory) {
3659
+ const marked = nearestMarkedAncestor(directory);
3660
+ if (marked !== undefined)
3661
+ return marked;
3662
+ return realpathSync4(nearestExistingAncestor(directory));
3663
+ }
3664
+ function nearestMarkedAncestor(directory) {
3665
+ let current = directory;
3666
+ for (;; ) {
3667
+ if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
3668
+ return realpathSync4(current);
3669
+ }
3670
+ const parent = dirname5(current);
3671
+ if (parent === current)
3672
+ return;
3673
+ current = parent;
3518
3674
  }
3519
3675
  }
3520
- function loadInstallDecision(serverId) {
3521
- return loadInstallDecisions()[serverId];
3522
- }
3523
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3524
- const decisions = loadInstallDecisions();
3525
- decisions[serverId] = { decision, decidedAt };
3526
- writeInstallDecisions(decisions);
3527
- }
3528
- function isInstallDecision(value) {
3529
- return value === "declined" || value === "allowed";
3530
- }
3531
- function writeInstallDecisions(decisions) {
3532
- const path = getInstallDecisionsPath();
3533
- mkdirSync(dirname5(path), { recursive: true });
3534
- const tmpPath = `${path}.tmp`;
3535
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3536
- `, "utf8");
3537
- renameSync2(tmpPath, path);
3538
- }
3539
- function isInstallDecisions(value) {
3540
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3541
- }
3542
- function isInstallDecisionRecord(value) {
3543
- if (!isRecord5(value))
3544
- return false;
3545
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3546
- }
3547
- function isRecord5(value) {
3548
- return typeof value === "object" && value !== null && !Array.isArray(value);
3676
+ function nearestExistingAncestor(directory) {
3677
+ let current = directory;
3678
+ while (!existsSync6(current)) {
3679
+ const parent = dirname5(current);
3680
+ if (parent === current)
3681
+ return current;
3682
+ current = parent;
3683
+ }
3684
+ return current;
3549
3685
  }
3550
3686
 
3551
- // ../lsp-core/src/lsp/config-loader.ts
3552
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
3553
-
3554
3687
  // ../lsp-core/src/lsp/server-definitions.ts
3555
3688
  var LSP_INSTALL_HINTS = {
3556
3689
  typescript: "npm install -g typescript-language-server typescript",
@@ -3596,6 +3729,26 @@ var LSP_INSTALL_HINTS = {
3596
3729
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
3597
3730
  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"
3598
3731
  };
3732
+ var LSP_LOCAL_INSTALL_HINTS = {
3733
+ typescript: "bun add -d typescript-language-server typescript",
3734
+ vue: "bun add -d @vue/language-server",
3735
+ eslint: "bun add -d vscode-langservers-extracted",
3736
+ oxlint: "bun add -d oxlint",
3737
+ biome: "bun add -d @biomejs/biome",
3738
+ svelte: "bun add -d svelte-language-server",
3739
+ astro: "bun add -d @astrojs/language-server",
3740
+ bash: "bun add -d bash-language-server",
3741
+ "bash-ls": "bun add -d bash-language-server",
3742
+ "yaml-ls": "bun add -d yaml-language-server",
3743
+ php: "bun add -d intelephense",
3744
+ prisma: "bun add -d prisma",
3745
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
3746
+ pyright: "uv add --dev pyright",
3747
+ basedpyright: "uv add --dev basedpyright",
3748
+ ruff: "uv add --dev ruff",
3749
+ ty: "uv add --dev ty",
3750
+ "ruby-lsp": "bundle add ruby-lsp --group development"
3751
+ };
3599
3752
  var BUILTIN_SERVERS = {
3600
3753
  typescript: {
3601
3754
  command: ["typescript-language-server", "--stdio"],
@@ -3698,7 +3851,56 @@ var BUILTIN_SERVERS = {
3698
3851
  }
3699
3852
  };
3700
3853
 
3854
+ // ../lsp-core/src/lsp/server-install-state.ts
3855
+ import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3856
+ import { dirname as dirname6 } from "node:path";
3857
+ function getInstallDecisionsPath() {
3858
+ return lspRequestContext().installDecisionsPath;
3859
+ }
3860
+ function loadInstallDecisions() {
3861
+ const path = getInstallDecisionsPath();
3862
+ if (!existsSync7(path))
3863
+ return {};
3864
+ try {
3865
+ const parsed = JSON.parse(readFileSync3(path, "utf8"));
3866
+ return isInstallDecisions(parsed) ? parsed : {};
3867
+ } catch {
3868
+ return {};
3869
+ }
3870
+ }
3871
+ function loadInstallDecision(serverId) {
3872
+ return loadInstallDecisions()[serverId];
3873
+ }
3874
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3875
+ const decisions = loadInstallDecisions();
3876
+ decisions[serverId] = { decision, decidedAt };
3877
+ writeInstallDecisions(decisions);
3878
+ }
3879
+ function isInstallDecision(value) {
3880
+ return value === "declined" || value === "allowed";
3881
+ }
3882
+ function writeInstallDecisions(decisions) {
3883
+ const path = getInstallDecisionsPath();
3884
+ mkdirSync(dirname6(path), { recursive: true });
3885
+ const tmpPath = `${path}.tmp`;
3886
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3887
+ `, "utf8");
3888
+ renameSync2(tmpPath, path);
3889
+ }
3890
+ function isInstallDecisions(value) {
3891
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3892
+ }
3893
+ function isInstallDecisionRecord(value) {
3894
+ if (!isRecord5(value))
3895
+ return false;
3896
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3897
+ }
3898
+ function isRecord5(value) {
3899
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3900
+ }
3901
+
3701
3902
  // ../lsp-core/src/lsp/config-loader.ts
3903
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
3702
3904
  function getProjectConfigPaths() {
3703
3905
  return lspRequestContext().projectConfigPaths;
3704
3906
  }
@@ -3706,7 +3908,7 @@ function getUserConfigPath() {
3706
3908
  return lspRequestContext().userConfigPath;
3707
3909
  }
3708
3910
  function loadJsonFile(path) {
3709
- if (!existsSync7(path))
3911
+ if (!existsSync8(path))
3710
3912
  return null;
3711
3913
  try {
3712
3914
  const parsed = JSON.parse(readFileSync4(path, "utf-8"));
@@ -3753,10 +3955,10 @@ function getMergedServers() {
3753
3955
  }
3754
3956
  if (seen.has(id))
3755
3957
  continue;
3756
- const server2 = createServerFromEntry(id, entry, source);
3757
- if (!server2)
3958
+ const server = createServerFromEntry(id, entry, source);
3959
+ if (!server)
3758
3960
  continue;
3759
- servers.push(server2);
3961
+ servers.push(server);
3760
3962
  seen.add(id);
3761
3963
  }
3762
3964
  }
@@ -3788,7 +3990,7 @@ function createServerFromEntry(id, entry, source) {
3788
3990
  if (source === "project") {
3789
3991
  if (!builtin)
3790
3992
  return null;
3791
- const server3 = createServer({
3993
+ const server = createServer({
3792
3994
  id,
3793
3995
  command: builtin.command,
3794
3996
  extensions: entry.extensions ?? builtin.extensions,
@@ -3796,35 +3998,35 @@ function createServerFromEntry(id, entry, source) {
3796
3998
  source
3797
3999
  });
3798
4000
  if (entry.initialization !== undefined) {
3799
- server3.initialization = entry.initialization;
4001
+ server.initialization = entry.initialization;
3800
4002
  }
3801
- return server3;
4003
+ return server;
3802
4004
  }
3803
4005
  if (entry.command && entry.extensions) {
3804
- const server3 = createServer({
4006
+ const server = createServer({
3805
4007
  id,
3806
4008
  command: entry.command,
3807
4009
  extensions: entry.extensions,
3808
4010
  priority: entry.priority ?? 0,
3809
4011
  source
3810
4012
  });
3811
- applyOptionalServerFields(server3, entry);
3812
- return server3;
4013
+ applyOptionalServerFields(server, entry);
4014
+ return server;
3813
4015
  }
3814
4016
  if (!builtin)
3815
4017
  return null;
3816
- const server2 = createServer({
4018
+ const server = createServer({
3817
4019
  id,
3818
4020
  command: entry.command ?? builtin.command,
3819
4021
  extensions: entry.extensions ?? builtin.extensions,
3820
4022
  priority: entry.priority ?? 0,
3821
4023
  source
3822
4024
  });
3823
- applyOptionalServerFields(server2, entry);
3824
- return server2;
4025
+ applyOptionalServerFields(server, entry);
4026
+ return server;
3825
4027
  }
3826
4028
  function createServer(input) {
3827
- const server2 = {
4029
+ const server = {
3828
4030
  id: input.id,
3829
4031
  command: input.command,
3830
4032
  extensions: input.extensions,
@@ -3832,19 +4034,19 @@ function createServer(input) {
3832
4034
  source: input.source
3833
4035
  };
3834
4036
  if (input.env !== undefined) {
3835
- server2.env = input.env;
4037
+ server.env = input.env;
3836
4038
  }
3837
4039
  if (input.initialization !== undefined) {
3838
- server2.initialization = input.initialization;
4040
+ server.initialization = input.initialization;
3839
4041
  }
3840
- return server2;
4042
+ return server;
3841
4043
  }
3842
- function applyOptionalServerFields(server2, entry) {
4044
+ function applyOptionalServerFields(server, entry) {
3843
4045
  if (entry.env !== undefined) {
3844
- server2.env = entry.env;
4046
+ server.env = entry.env;
3845
4047
  }
3846
4048
  if (entry.initialization !== undefined) {
3847
- server2.initialization = entry.initialization;
4049
+ server.initialization = entry.initialization;
3848
4050
  }
3849
4051
  }
3850
4052
  function isConfigJson(value) {
@@ -3894,64 +4096,165 @@ function getDisabledServerIds() {
3894
4096
  }
3895
4097
 
3896
4098
  // ../lsp-core/src/lsp/server-installation.ts
3897
- import { existsSync as existsSync8 } from "node:fs";
3898
- import { delimiter as delimiter3, join as join3 } from "node:path";
3899
- function isServerInstalled(command, _workingDirectory) {
3900
- if (command.length === 0)
3901
- return false;
3902
- const [cmd] = command;
3903
- if (!cmd)
3904
- return false;
3905
- if (cmd.includes("/") || cmd.includes("\\")) {
3906
- if (existsSync8(cmd))
3907
- return true;
4099
+ import { existsSync as existsSync9 } from "node:fs";
4100
+ import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
4101
+ var LOCAL_BIN_RULES = [
4102
+ {
4103
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
4104
+ binDirs: [join4("node_modules", ".bin")]
4105
+ },
4106
+ {
4107
+ markers: [
4108
+ "pyproject.toml",
4109
+ "ty.toml",
4110
+ "requirements.txt",
4111
+ "setup.py",
4112
+ "setup.cfg",
4113
+ "Pipfile",
4114
+ "pyrightconfig.json",
4115
+ "ruff.toml",
4116
+ ".ruff.toml"
4117
+ ],
4118
+ binDirs: [
4119
+ join4(".venv", "bin"),
4120
+ join4(".venv", "Scripts"),
4121
+ join4("venv", "bin"),
4122
+ join4("venv", "Scripts"),
4123
+ join4(".env", "bin"),
4124
+ join4(".env", "Scripts")
4125
+ ]
4126
+ },
4127
+ {
4128
+ markers: ["Gemfile", "Gemfile.lock"],
4129
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4130
+ },
4131
+ {
4132
+ markers: ["go.mod", "go.sum", "go.work"],
4133
+ binDirs: ["bin"]
3908
4134
  }
3909
- const isWindows = process.platform === "win32";
3910
- let exts = [""];
3911
- if (isWindows) {
3912
- const pathExt = process.env["PATHEXT"] ?? "";
3913
- if (pathExt) {
3914
- const systemExts = pathExt.split(";").filter(Boolean);
3915
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
3916
- } else {
3917
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4135
+ ];
4136
+ var resolutionCache = new Map;
4137
+ var probeCount = 0;
4138
+ function probe(path) {
4139
+ probeCount += 1;
4140
+ return existsSync9(path);
4141
+ }
4142
+ function executableSuffixes(platform, pathExt) {
4143
+ if (platform !== "win32")
4144
+ return [""];
4145
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4146
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4147
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4148
+ }
4149
+ function probeWithSuffixes(directory, command, suffixes) {
4150
+ for (const suffix of suffixes) {
4151
+ const candidate = join4(directory, command + suffix);
4152
+ if (probe(candidate))
4153
+ return candidate;
4154
+ }
4155
+ return null;
4156
+ }
4157
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4158
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4159
+ let current = resolve7(workingDirectory);
4160
+ while (true) {
4161
+ for (const rule of LOCAL_BIN_RULES) {
4162
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
4163
+ continue;
4164
+ for (const binDir of rule.binDirs) {
4165
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4166
+ if (found !== null)
4167
+ return found;
4168
+ }
3918
4169
  }
4170
+ if (probe(join4(current, ".git")))
4171
+ return null;
4172
+ if (boundary !== undefined && current === boundary)
4173
+ return null;
4174
+ const parent = dirname7(current);
4175
+ if (parent === current)
4176
+ return null;
4177
+ current = parent;
3919
4178
  }
3920
- let pathEnv = process.env["PATH"] ?? "";
3921
- if (isWindows && !pathEnv) {
4179
+ }
4180
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4181
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4182
+ if (platform === "win32" && !pathEnv) {
3922
4183
  pathEnv = process.env["Path"] ?? "";
3923
4184
  }
3924
- const paths = pathEnv.split(delimiter3);
3925
- for (const p of paths) {
3926
- for (const suffix of exts) {
3927
- if (existsSync8(join3(p, cmd + suffix))) {
3928
- return true;
3929
- }
3930
- }
4185
+ for (const entry of pathEnv.split(delimiter3)) {
4186
+ if (entry.length === 0)
4187
+ continue;
4188
+ const found = probeWithSuffixes(entry, command, suffixes);
4189
+ if (found !== null)
4190
+ return found;
3931
4191
  }
3932
- if (cmd === "node")
3933
- return true;
3934
- return false;
4192
+ return null;
4193
+ }
4194
+ function resolveServerBinary(command, workingDirectory, options = {}) {
4195
+ if (command.length === 0)
4196
+ return null;
4197
+ const [cmd] = command;
4198
+ if (cmd === undefined || cmd.length === 0)
4199
+ return null;
4200
+ const platform = options.platform ?? process.platform;
4201
+ const suffixes = executableSuffixes(platform, options.pathExt);
4202
+ if (cmd.includes("/") || cmd.includes("\\")) {
4203
+ const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4204
+ return probe(explicit) ? explicit : null;
4205
+ }
4206
+ const cacheKey = JSON.stringify([
4207
+ workingDirectory ?? "",
4208
+ cmd,
4209
+ platform,
4210
+ options.stopAt ?? "",
4211
+ options.pathExt ?? "",
4212
+ options.pathEnv ?? process.env["PATH"] ?? ""
4213
+ ]);
4214
+ const cached = resolutionCache.get(cacheKey);
4215
+ if (cached !== undefined)
4216
+ return cached;
4217
+ let resolved = null;
4218
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
4219
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4220
+ }
4221
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4222
+ if (resolved === null && cmd === "node")
4223
+ resolved = cmd;
4224
+ resolutionCache.set(cacheKey, resolved);
4225
+ return resolved;
4226
+ }
4227
+ function isServerInstalled(command, workingDirectory, options = {}) {
4228
+ if (command.length === 0)
4229
+ return false;
4230
+ return resolveServerBinary(command, workingDirectory, options) !== null;
3935
4231
  }
3936
4232
 
3937
4233
  // ../lsp-core/src/lsp/server-resolution.ts
4234
+ function withResolvedCommand(command, binaryPath) {
4235
+ return [binaryPath, ...command.slice(1)];
4236
+ }
3938
4237
  function findServerForExtension(ext) {
3939
4238
  const servers = getMergedServers();
3940
- for (const server2 of servers) {
3941
- if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4239
+ const workingDirectory = contextCwd();
4240
+ for (const server of servers) {
4241
+ if (!server.extensions.includes(ext))
4242
+ continue;
4243
+ const binaryPath = resolveServerBinary(server.command, workingDirectory);
4244
+ if (binaryPath !== null) {
3942
4245
  const resolvedServer = {
3943
- id: server2.id,
3944
- command: server2.command,
3945
- extensions: server2.extensions,
3946
- priority: server2.priority
4246
+ id: server.id,
4247
+ command: withResolvedCommand(server.command, binaryPath),
4248
+ extensions: server.extensions,
4249
+ priority: server.priority
3947
4250
  };
3948
- if (server2.env !== undefined) {
4251
+ if (server.env !== undefined) {
3949
4252
  return {
3950
4253
  status: "found",
3951
4254
  server: {
3952
4255
  ...resolvedServer,
3953
- env: server2.env,
3954
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4256
+ env: server.env,
4257
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
3955
4258
  }
3956
4259
  };
3957
4260
  }
@@ -3959,20 +4262,20 @@ function findServerForExtension(ext) {
3959
4262
  status: "found",
3960
4263
  server: {
3961
4264
  ...resolvedServer,
3962
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4265
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
3963
4266
  }
3964
4267
  };
3965
4268
  }
3966
4269
  }
3967
- for (const server2 of servers) {
3968
- if (server2.extensions.includes(ext)) {
3969
- const installHint = LSP_INSTALL_HINTS[server2.id] ?? `Install '${server2.command[0]}' and ensure it's in your PATH`;
4270
+ for (const server of servers) {
4271
+ if (server.extensions.includes(ext)) {
4272
+ const installHint = LSP_INSTALL_HINTS[server.id] ?? `Install '${server.command[0]}' and ensure it's in your PATH`;
3970
4273
  return {
3971
4274
  status: "not_installed",
3972
4275
  server: {
3973
- id: server2.id,
3974
- command: server2.command,
3975
- extensions: server2.extensions
4276
+ id: server.id,
4277
+ command: server.command,
4278
+ extensions: server.extensions
3976
4279
  },
3977
4280
  installHint
3978
4281
  };
@@ -3988,20 +4291,21 @@ function findServerForExtension(ext) {
3988
4291
  function getAllServers() {
3989
4292
  const servers = getMergedServers();
3990
4293
  const disabled = getDisabledServerIds();
4294
+ const workingDirectory = contextCwd();
3991
4295
  const result = [];
3992
4296
  const seen = new Set;
3993
- for (const server2 of servers) {
3994
- if (seen.has(server2.id))
4297
+ for (const server of servers) {
4298
+ if (seen.has(server.id))
3995
4299
  continue;
3996
4300
  result.push({
3997
- id: server2.id,
3998
- installed: isServerInstalled(server2.command),
3999
- extensions: server2.extensions,
4301
+ id: server.id,
4302
+ installed: isServerInstalled(server.command, workingDirectory),
4303
+ extensions: server.extensions,
4000
4304
  disabled: false,
4001
- source: server2.source,
4002
- priority: server2.priority
4305
+ source: server.source,
4306
+ priority: server.priority
4003
4307
  });
4004
- seen.add(server2.id);
4308
+ seen.add(server.id);
4005
4309
  }
4006
4310
  for (const id of disabled) {
4007
4311
  if (seen.has(id))
@@ -4009,7 +4313,7 @@ function getAllServers() {
4009
4313
  const builtin = BUILTIN_SERVERS[id];
4010
4314
  result.push({
4011
4315
  id,
4012
- installed: builtin ? isServerInstalled(builtin.command) : false,
4316
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4013
4317
  extensions: builtin?.extensions ?? [],
4014
4318
  disabled: true,
4015
4319
  source: "disabled",
@@ -4020,7 +4324,6 @@ function getAllServers() {
4020
4324
  }
4021
4325
 
4022
4326
  // ../lsp-core/src/lsp/client-wrapper.ts
4023
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
4024
4327
  function isDirectoryPath(filePath) {
4025
4328
  try {
4026
4329
  return statSync3(filePath).isDirectory();
@@ -4033,36 +4336,40 @@ function findWorkspaceRoot(filePath) {
4033
4336
  const abs = resolveReadablePathInsideContext(filePath);
4034
4337
  let dir = abs;
4035
4338
  if (!isDirectoryPath(dir)) {
4036
- dir = dirname6(dir);
4339
+ dir = dirname8(dir);
4037
4340
  }
4341
+ if (!isPathInside(cwd, abs))
4342
+ return findWorkspaceRootOutsideContext(dir);
4038
4343
  const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4344
+ let nearestPackageRoot;
4039
4345
  while (isPathInside(cwd, dir)) {
4040
4346
  const canonicalDir = existingDirectoryInsideContext(dir, cwd);
4041
4347
  if (canonicalDir !== undefined) {
4042
- for (const marker of WORKSPACE_MARKERS) {
4043
- if (existsSync9(join4(dir, marker))) {
4044
- return canonicalDir;
4045
- }
4348
+ if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
4349
+ return canonicalDir;
4350
+ }
4351
+ if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
4352
+ nearestPackageRoot = canonicalDir;
4046
4353
  }
4047
4354
  }
4048
4355
  if (dir === cwd)
4049
4356
  break;
4050
- dir = dirname6(dir);
4357
+ dir = dirname8(dir);
4051
4358
  }
4052
- return fallbackRoot;
4359
+ return nearestPackageRoot ?? fallbackRoot;
4360
+ }
4361
+ function hasProjectWorkspaceMarker(directory) {
4362
+ return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
4053
4363
  }
4054
4364
  function resolveReadablePathInsideContext(filePath) {
4055
4365
  const cwd = contextCwd();
4056
- const abs = resolve7(cwd, filePath);
4366
+ const abs = resolve8(cwd, filePath);
4057
4367
  if (isPathInside(cwd, abs))
4058
4368
  return abs;
4059
4369
  const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
4060
4370
  if (rebased !== undefined)
4061
4371
  return rebased;
4062
- const canonical = canonicalizeExistingOrNearestAncestor(abs);
4063
- if (isPathInside(cwd, canonical))
4064
- return canonical;
4065
- throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
4372
+ return canonicalizeExistingOrNearestAncestor(abs);
4066
4373
  }
4067
4374
  function resolvePathInsideContext(filePath) {
4068
4375
  const cwd = contextCwd();
@@ -4077,12 +4384,12 @@ function rebaseThroughCanonicalAncestor(path, cwd) {
4077
4384
  let current = path;
4078
4385
  const suffix = [];
4079
4386
  while (true) {
4080
- if (existsSync9(current)) {
4081
- const canonical = realpathSync4(current);
4387
+ if (existsSync10(current)) {
4388
+ const canonical = realpathSync5(current);
4082
4389
  if (isPathInside(cwd, canonical))
4083
- return suffix.length === 0 ? canonical : join4(canonical, ...suffix);
4390
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
4084
4391
  }
4085
- const parent = dirname6(current);
4392
+ const parent = dirname8(current);
4086
4393
  if (parent === current)
4087
4394
  return;
4088
4395
  suffix.unshift(basename3(current));
@@ -4090,9 +4397,9 @@ function rebaseThroughCanonicalAncestor(path, cwd) {
4090
4397
  }
4091
4398
  }
4092
4399
  function existingDirectoryInsideContext(directory, cwd) {
4093
- if (!existsSync9(directory))
4400
+ if (!existsSync10(directory))
4094
4401
  return;
4095
- const canonical = realpathSync4(directory);
4402
+ const canonical = realpathSync5(directory);
4096
4403
  if (!statSync3(canonical).isDirectory())
4097
4404
  return;
4098
4405
  return isPathInside(cwd, canonical) ? canonical : undefined;
@@ -4105,7 +4412,7 @@ function nearestExistingDirectoryInsideContext(directory, cwd) {
4105
4412
  return canonical;
4106
4413
  if (current === cwd)
4107
4414
  return;
4108
- current = dirname6(current);
4415
+ current = dirname8(current);
4109
4416
  }
4110
4417
  return;
4111
4418
  }
@@ -4132,33 +4439,46 @@ function formatServerLookupError(result) {
4132
4439
  ].join(`
4133
4440
  `);
4134
4441
  }
4442
+ function formatInstallOptions(serverId, installHint) {
4443
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
4444
+ if (localHint === undefined) {
4445
+ return ["To install, run:", ` ${installHint}`];
4446
+ }
4447
+ return [
4448
+ "To install in THIS repository (preferred — no global install needed):",
4449
+ ` ${localHint}`,
4450
+ "",
4451
+ "Or install it globally:",
4452
+ ` ${installHint}`
4453
+ ];
4454
+ }
4135
4455
  function formatNotInstalled(result) {
4136
- const { server: server2, installHint } = result;
4137
- const extensions = server2.extensions.join(", ");
4138
- const decision = loadInstallDecision(server2.id)?.decision;
4456
+ const { server, installHint } = result;
4457
+ const extensions = server.extensions.join(", ");
4458
+ const decision = loadInstallDecision(server.id)?.decision;
4139
4459
  const context = lspRequestContext();
4140
4460
  if (decision === "declined") {
4141
- return `LSP server '${server2.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
4461
+ return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
4142
4462
  }
4143
4463
  const header = [
4144
- `LSP server '${server2.id}' for ${extensions} is NOT INSTALLED.`,
4464
+ `LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
4145
4465
  "",
4146
- `Command not found: ${server2.command[0]}`,
4466
+ `Command not found: ${server.command[0]}`,
4147
4467
  ""
4148
4468
  ];
4469
+ const installOptions = formatInstallOptions(server.id, installHint);
4149
4470
  if (decision === "allowed") {
4150
4471
  return [
4151
4472
  ...header,
4152
4473
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4153
- ` ${installHint}`
4474
+ ...installOptions.slice(1)
4154
4475
  ].join(`
4155
4476
  `);
4156
4477
  }
4157
4478
  if (!context.capabilities.installDecisionTool) {
4158
4479
  return [
4159
4480
  ...header,
4160
- "To install, run:",
4161
- ` ${installHint}`,
4481
+ ...installOptions,
4162
4482
  "",
4163
4483
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4164
4484
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4167,13 +4487,12 @@ function formatNotInstalled(result) {
4167
4487
  }
4168
4488
  return [
4169
4489
  ...header,
4170
- "To install, run:",
4171
- ` ${installHint}`,
4490
+ ...installOptions,
4172
4491
  "",
4173
4492
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4174
4493
  "- If the user agrees: run the install command above, then retry this tool.",
4175
4494
  "- If the user declines, OR has NOT explicitly asked for LSP installation:",
4176
- ` call lsp_install_decision { server_id: "${server2.id}", decision: "declined" },`,
4495
+ ` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
4177
4496
  ` which writes to ${context.installDecisionsPath},`,
4178
4497
  " then ignore this message and proceed WITHOUT LSP."
4179
4498
  ].join(`
@@ -4197,34 +4516,34 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4197
4516
  if (result.status !== "found") {
4198
4517
  throw new LspServerLookupError(formatServerLookupError(result), result);
4199
4518
  }
4200
- const server2 = result.server;
4519
+ const server = result.server;
4201
4520
  const root = findWorkspaceRoot(absPath);
4202
4521
  const manager = options.manager ?? getLspManager();
4203
4522
  const acquireAndCall = async (allowRetry) => {
4204
- const client = await manager.getClient(root, server2, options.signal);
4523
+ const client = await manager.getClient(root, server, options.signal);
4205
4524
  try {
4206
4525
  return await fn(client, root, absPath);
4207
4526
  } catch (err) {
4208
4527
  if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4209
- manager.invalidateClient(root, server2.id, client);
4528
+ manager.invalidateClient(root, server.id, client);
4210
4529
  return acquireAndCall(false);
4211
4530
  }
4212
4531
  if (err instanceof LspRequestTimeoutError) {
4213
- if (manager.isServerInitializing(root, server2.id)) {
4532
+ if (manager.isServerInitializing(root, server.id)) {
4214
4533
  throw new LspServerInitializingError(err);
4215
4534
  }
4216
4535
  }
4217
4536
  throw err;
4218
4537
  } finally {
4219
- manager.releaseClient(root, server2.id);
4538
+ manager.releaseClient(root, server.id);
4220
4539
  }
4221
4540
  };
4222
4541
  return acquireAndCall(true);
4223
4542
  }
4224
4543
 
4225
4544
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4226
- import { existsSync as existsSync10, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4227
- import { join as join5, resolve as resolve8 } from "node:path";
4545
+ import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4546
+ import { join as join6, resolve as resolve9 } from "node:path";
4228
4547
 
4229
4548
  // ../lsp-core/src/lsp/formatters.ts
4230
4549
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -4239,10 +4558,10 @@ function uriToPath(uri) {
4239
4558
  }
4240
4559
  function formatLocation(loc) {
4241
4560
  if ("targetUri" in loc) {
4242
- const uri2 = uriToPath(loc.targetUri);
4243
- const line2 = loc.targetRange.start.line + 1;
4244
- const char2 = loc.targetRange.start.character;
4245
- return `${uri2}:${line2}:${char2}`;
4561
+ const uri = uriToPath(loc.targetUri);
4562
+ const line = loc.targetRange.start.line + 1;
4563
+ const char = loc.targetRange.start.character;
4564
+ return `${uri}:${line}:${char}`;
4246
4565
  }
4247
4566
  const uri = uriToPath(loc.uri);
4248
4567
  const line = loc.range.start.line + 1;
@@ -4354,7 +4673,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
4354
4673
  for (const entry of entries) {
4355
4674
  if (files.length >= maxFiles)
4356
4675
  return;
4357
- const fullPath = join5(currentDir, entry);
4676
+ const fullPath = join6(currentDir, entry);
4358
4677
  let stat;
4359
4678
  try {
4360
4679
  stat = lstatSync4(fullPath);
@@ -4379,15 +4698,15 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4379
4698
  if (!extension.startsWith(".")) {
4380
4699
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4381
4700
  }
4382
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4383
- if (!existsSync10(absDir)) {
4701
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
4702
+ if (!existsSync11(absDir)) {
4384
4703
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4385
4704
  }
4386
4705
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
4387
4706
  if (serverResult.status !== "found") {
4388
4707
  throw new LspServerLookupError(formatServerLookupError(serverResult));
4389
4708
  }
4390
- const server2 = serverResult.server;
4709
+ const server = serverResult.server;
4391
4710
  const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
4392
4711
  const wasCapped = allFiles.length > maxFiles;
4393
4712
  const filesToProcess = allFiles.slice(0, maxFiles);
@@ -4407,7 +4726,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4407
4726
  const fileErrors = [];
4408
4727
  const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
4409
4728
  options.signal?.throwIfAborted();
4410
- const client = await manager.getClient(root, server2, options.signal);
4729
+ const client = await manager.getClient(root, server, options.signal);
4411
4730
  try {
4412
4731
  let nextIndex = 0;
4413
4732
  const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
@@ -4435,7 +4754,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4435
4754
  });
4436
4755
  await Promise.all(workers);
4437
4756
  } finally {
4438
- manager.releaseClient(root, server2.id);
4757
+ manager.releaseClient(root, server.id);
4439
4758
  }
4440
4759
  const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
4441
4760
  const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
@@ -4467,7 +4786,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4467
4786
 
4468
4787
  // ../lsp-core/src/lsp/infer-extension.ts
4469
4788
  import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
4470
- import { join as join6 } from "node:path";
4789
+ import { join as join7 } from "node:path";
4471
4790
  var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
4472
4791
  var MAX_SCAN_ENTRIES = 500;
4473
4792
  function inferExtensionFromDirectory(directory) {
@@ -4485,7 +4804,7 @@ function inferExtensionFromDirectory(directory) {
4485
4804
  for (const entry of entries) {
4486
4805
  if (scanned >= MAX_SCAN_ENTRIES)
4487
4806
  return;
4488
- const fullPath = join6(dir, entry);
4807
+ const fullPath = join7(dir, entry);
4489
4808
  let stat;
4490
4809
  try {
4491
4810
  stat = lstatSync5(fullPath);
@@ -4644,8 +4963,8 @@ function clientOptions(signal) {
4644
4963
  }
4645
4964
 
4646
4965
  // ../lsp-core/src/tools/result.ts
4647
- function text(text2, details, isError = false) {
4648
- return { content: [{ type: "text", text: text2 }], details, isError };
4966
+ function text(text, details, isError = false) {
4967
+ return { content: [{ type: "text", text }], details, isError };
4649
4968
  }
4650
4969
 
4651
4970
  // ../lsp-core/src/tools/diagnostics.ts
@@ -4665,7 +4984,7 @@ async function executeLspDiagnostics(params, signal) {
4665
4984
  const extension = inferExtensionFromDirectory(absPath);
4666
4985
  if (!extension) {
4667
4986
  const message = `No supported source files found in directory: ${absPath}`;
4668
- const details3 = {
4987
+ const details = {
4669
4988
  filePath,
4670
4989
  severity,
4671
4990
  mode: "directory",
@@ -4675,24 +4994,24 @@ async function executeLspDiagnostics(params, signal) {
4675
4994
  error: message,
4676
4995
  errorKind: "no_files"
4677
4996
  };
4678
- return text(message, details3);
4997
+ return text(message, details);
4679
4998
  }
4680
- const output2 = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
4681
- const details2 = {
4999
+ const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
5000
+ const details = {
4682
5001
  filePath,
4683
5002
  severity,
4684
5003
  mode: "directory",
4685
5004
  diagnostics: [],
4686
- totalDiagnostics: output2.totalDiagnostics,
5005
+ totalDiagnostics: output.totalDiagnostics,
4687
5006
  truncated: false,
4688
- fileFailures: [...output2.fileFailures]
5007
+ fileFailures: [...output.fileFailures]
4689
5008
  };
4690
- return text(output2.output, details2);
5009
+ return text(output.output, details);
4691
5010
  }
4692
5011
  const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
4693
5012
  if (result.transientError) {
4694
5013
  const message = result.transientError.message;
4695
- const details2 = {
5014
+ const details = {
4696
5015
  filePath,
4697
5016
  severity,
4698
5017
  mode: "file",
@@ -4702,7 +5021,7 @@ async function executeLspDiagnostics(params, signal) {
4702
5021
  error: message,
4703
5022
  errorKind: result.transientError.kind
4704
5023
  };
4705
- return text(message, details2, true);
5024
+ return text(message, details, true);
4706
5025
  }
4707
5026
  const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
4708
5027
  const total = diagnostics.length;
@@ -4736,6 +5055,96 @@ async function executeLspDiagnostics(params, signal) {
4736
5055
  throw error;
4737
5056
  }
4738
5057
  }
5058
+ // ../lsp-core/src/lsp/format-document.ts
5059
+ import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
5060
+ var DEFAULT_FORMATTING_OPTIONS = {
5061
+ tabSize: 4,
5062
+ insertSpaces: false,
5063
+ trimTrailingWhitespace: true,
5064
+ insertFinalNewline: true,
5065
+ trimFinalNewlines: true
5066
+ };
5067
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
5068
+ async function formatDocumentWithClient(client, filePath, options = {}) {
5069
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
5070
+ if (edits === null)
5071
+ return { status: "unavailable", reason: "capability_not_advertised" };
5072
+ if (edits.length === 0)
5073
+ return UNCHANGED;
5074
+ const before = readFileSync5(filePath, "utf-8");
5075
+ const normalized = normalizeTextEdits(before, edits, 0);
5076
+ if (normalized.text === before)
5077
+ return UNCHANGED;
5078
+ writeAtomically(filePath, normalized.text);
5079
+ await client.openFile(filePath);
5080
+ return {
5081
+ status: "formatted",
5082
+ ...lineDelta(normalized.edits)
5083
+ };
5084
+ }
5085
+ function lineDelta(edits) {
5086
+ let linesAdded = 0;
5087
+ let linesRemoved = 0;
5088
+ for (const edit of edits) {
5089
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
5090
+ linesAdded += edit.newText.split(`
5091
+ `).length;
5092
+ }
5093
+ return { linesAdded, linesRemoved };
5094
+ }
5095
+ function writeAtomically(filePath, content) {
5096
+ const tempPath = `${filePath}.omo-format.tmp`;
5097
+ writeFileSync3(tempPath, content, "utf-8");
5098
+ try {
5099
+ renameSync3(tempPath, filePath);
5100
+ } catch (error) {
5101
+ try {
5102
+ unlinkSync(tempPath);
5103
+ } catch {}
5104
+ throw error;
5105
+ }
5106
+ }
5107
+
5108
+ // ../lsp-core/src/tools/format.ts
5109
+ async function executeLspFormat(params, signal) {
5110
+ const filePath = requireString(params, "filePath");
5111
+ try {
5112
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
5113
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
5114
+ } catch (error) {
5115
+ const missingDependency = missingDependencyResult(error, {
5116
+ filePath,
5117
+ status: "unavailable",
5118
+ reason: "server_unavailable",
5119
+ linesAdded: 0,
5120
+ linesRemoved: 0
5121
+ });
5122
+ if (missingDependency)
5123
+ return missingDependency;
5124
+ throw error;
5125
+ }
5126
+ }
5127
+ function formatDetails(filePath, result) {
5128
+ if (result.status === "unavailable") {
5129
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5130
+ }
5131
+ return {
5132
+ filePath,
5133
+ status: result.status,
5134
+ linesAdded: result.linesAdded,
5135
+ linesRemoved: result.linesRemoved
5136
+ };
5137
+ }
5138
+ function describeResult(filePath, result) {
5139
+ if (result.status === "unavailable") {
5140
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5141
+ }
5142
+ if (result.status === "unchanged") {
5143
+ return `Already formatted: ${filePath}`;
5144
+ }
5145
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5146
+ }
5147
+
4739
5148
  // ../lsp-core/src/tools/install-decision.ts
4740
5149
  async function executeLspInstallDecision(params) {
4741
5150
  const serverId = requireString(params, "server_id");
@@ -4743,7 +5152,7 @@ async function executeLspInstallDecision(params) {
4743
5152
  if (!isInstallDecision(decision)) {
4744
5153
  return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
4745
5154
  }
4746
- const serverIds = [...new Set(getMergedServers().map((server2) => server2.id))];
5155
+ const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
4747
5156
  if (!serverIds.includes(serverId)) {
4748
5157
  const preview = serverIds.slice(0, 20).join(", ");
4749
5158
  return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
@@ -4883,10 +5292,10 @@ function objectSchema(properties, required = []) {
4883
5292
  async function executeLspStatus() {
4884
5293
  const servers = getAllServers();
4885
5294
  const snapshots = getLspManager().getSnapshot();
4886
- const installed = servers.filter((server2) => server2.installed && !server2.disabled);
4887
- const configuredLines = servers.map((server2) => {
4888
- const state = server2.disabled ? "disabled" : server2.installed ? "installed" : "missing";
4889
- return `- ${server2.id}: ${state}; source=${server2.source}; extensions=${server2.extensions.join(", ")}`;
5295
+ const installed = servers.filter((server) => server.installed && !server.disabled);
5296
+ const configuredLines = servers.map((server) => {
5297
+ const state = server.disabled ? "disabled" : server.installed ? "installed" : "missing";
5298
+ return `- ${server.id}: ${state}; source=${server.source}; extensions=${server.extensions.join(", ")}`;
4890
5299
  });
4891
5300
  const activeLines = snapshots.map((snapshot) => {
4892
5301
  const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
@@ -4929,8 +5338,8 @@ async function executeLspSymbols(params, signal) {
4929
5338
  errorKind: "missing_query"
4930
5339
  });
4931
5340
  }
4932
- const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
4933
- return formatSymbolsResult(filePath, scope, symbols2, limit, query);
5341
+ const symbols = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
5342
+ return formatSymbolsResult(filePath, scope, symbols, limit, query);
4934
5343
  }
4935
5344
  const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
4936
5345
  return formatSymbolsResult(filePath, scope, symbols, limit);
@@ -5068,6 +5477,16 @@ var LSP_MCP_TOOLS = [
5068
5477
  }, ["filePath", "line", "character", "newName"]),
5069
5478
  execute: executeLspRename
5070
5479
  },
5480
+ {
5481
+ name: "format",
5482
+ aliases: ["lsp_format"],
5483
+ title: "LSP Format",
5484
+ description: "Format a source file with its language server and write the returned edits to disk.",
5485
+ inputSchema: objectSchema({
5486
+ filePath: { type: "string", description: "Source file path to format." }
5487
+ }, ["filePath"]),
5488
+ execute: executeLspFormat
5489
+ },
5071
5490
  {
5072
5491
  name: "install_decision",
5073
5492
  aliases: ["lsp_install_decision"],
@@ -5167,11 +5586,10 @@ function requestedProtocolVersion(params) {
5167
5586
  // src/daemon-client.ts
5168
5587
  import { connect } from "node:net";
5169
5588
  import { homedir as homedir3 } from "node:os";
5170
- import { join as join7 } from "node:path";
5589
+ import { join as join8 } from "node:path";
5171
5590
 
5172
5591
  // src/daemon-request-error.ts
5173
5592
  class DaemonRequestError extends Error {
5174
- requestWritten;
5175
5593
  constructor(message, requestWritten) {
5176
5594
  super(message);
5177
5595
  this.name = "DaemonRequestError";
@@ -5194,7 +5612,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
5194
5612
  }
5195
5613
 
5196
5614
  class DaemonRequestTimedOutError extends DaemonRequestError {
5197
- timeoutMs;
5198
5615
  constructor(requestWritten, timeoutMs) {
5199
5616
  super("daemon request timed out", requestWritten);
5200
5617
  this.name = "DaemonRequestTimedOutError";
@@ -5211,26 +5628,26 @@ function daemonFailureResult(paths, error) {
5211
5628
  return daemonUnreachableResult(paths, error);
5212
5629
  }
5213
5630
  function daemonCancelledResult(paths) {
5214
- const text2 = [
5631
+ const text = [
5215
5632
  "LSP daemon request cancelled: the caller aborted this request (for example, the turn was interrupted).",
5216
5633
  "The daemon stays available; no LSP work was applied. Retry when you are ready.",
5217
5634
  `Socket: ${paths.socket}`
5218
5635
  ].join(`
5219
5636
  `);
5220
- return { content: [{ type: "text", text: text2 }], isError: true };
5637
+ return { content: [{ type: "text", text }], isError: true };
5221
5638
  }
5222
5639
  function daemonTimedOutResult(paths, timeoutMs) {
5223
- const text2 = [
5640
+ const text = [
5224
5641
  `LSP daemon request timed out after ${timeoutMs}ms: the daemon did not respond in time.`,
5225
5642
  "The daemon stays available but may be busy. Retry when you are ready.",
5226
5643
  `Socket: ${paths.socket}`,
5227
5644
  `Logs: ${paths.log}`
5228
5645
  ].join(`
5229
5646
  `);
5230
- return { content: [{ type: "text", text: text2 }], isError: true };
5647
+ return { content: [{ type: "text", text }], isError: true };
5231
5648
  }
5232
5649
  function daemonUnreachableResult(paths, error) {
5233
- const text2 = [
5650
+ const text = [
5234
5651
  `LSP daemon unreachable: ${errorText(error)}.`,
5235
5652
  "The MCP server is a thin proxy and never runs language servers in-process.",
5236
5653
  `Socket: ${paths.socket}`,
@@ -5238,7 +5655,7 @@ function daemonUnreachableResult(paths, error) {
5238
5655
  "The daemon is auto-started on demand and will be retried on the next request."
5239
5656
  ].join(`
5240
5657
  `);
5241
- return { content: [{ type: "text", text: text2 }], isError: true };
5658
+ return { content: [{ type: "text", text }], isError: true };
5242
5659
  }
5243
5660
  function errorText(error) {
5244
5661
  return error instanceof Error ? error.message : String(error);
@@ -5246,9 +5663,9 @@ function errorText(error) {
5246
5663
 
5247
5664
  // src/ensure-daemon.ts
5248
5665
  import { spawn as spawn2 } from "node:child_process";
5249
- import { closeSync as closeSync2, existsSync as existsSync11, mkdirSync as mkdirSync3, openSync as openSync2, writeSync as writeSync2 } from "node:fs";
5666
+ import { closeSync as closeSync2, existsSync as existsSync12, mkdirSync as mkdirSync3, openSync as openSync2, writeSync as writeSync2 } from "node:fs";
5250
5667
  import { Socket } from "node:net";
5251
- import { dirname as dirname8, isAbsolute as isAbsolute4 } from "node:path";
5668
+ import { dirname as dirname10, isAbsolute as isAbsolute5 } from "node:path";
5252
5669
  import { argv0, execPath } from "node:process";
5253
5670
 
5254
5671
  // src/ipc-protocol.ts
@@ -5262,25 +5679,23 @@ import {
5262
5679
  lstatSync as lstatSync6,
5263
5680
  mkdirSync as mkdirSync2,
5264
5681
  openSync,
5265
- readFileSync as readFileSync5,
5266
- unlinkSync,
5682
+ readFileSync as readFileSync6,
5683
+ unlinkSync as unlinkSync2,
5267
5684
  writeSync
5268
5685
  } from "node:fs";
5269
- import { dirname as dirname7 } from "node:path";
5686
+ import { dirname as dirname9 } from "node:path";
5270
5687
  var OMO_DAEMON_PROTOCOL_VERSION = 1;
5271
5688
  var AUTH_ERROR_CODE = -32001;
5272
5689
  var PROTOCOL_ERROR_CODE = -32002;
5273
5690
  var AUTH_TOKEN_BYTES = 32;
5274
5691
 
5275
5692
  class UnsafePrivateDirectoryError extends Error {
5276
- path;
5277
- reason;
5278
- name = "UnsafePrivateDirectoryError";
5279
- code = "unsafe_private_directory";
5280
5693
  constructor(path, reason) {
5281
5694
  super(`unsafe private directory ${path}: ${reason}`);
5282
5695
  this.path = path;
5283
5696
  this.reason = reason;
5697
+ this.name = "UnsafePrivateDirectoryError";
5698
+ this.code = "unsafe_private_directory";
5284
5699
  }
5285
5700
  }
5286
5701
  function authEnvelope(token) {
@@ -5288,7 +5703,7 @@ function authEnvelope(token) {
5288
5703
  }
5289
5704
  function readAuthToken(paths) {
5290
5705
  try {
5291
- const token = readFileSync5(paths.auth, "utf8").trim();
5706
+ const token = readFileSync6(paths.auth, "utf8").trim();
5292
5707
  return token.length > 0 ? token : null;
5293
5708
  } catch (error) {
5294
5709
  if (error instanceof Error)
@@ -5304,7 +5719,7 @@ function readOrCreateAuthToken(paths) {
5304
5719
  }
5305
5720
  function rotateAuthToken(paths) {
5306
5721
  try {
5307
- unlinkSync(paths.auth);
5722
+ unlinkSync2(paths.auth);
5308
5723
  } catch (error) {
5309
5724
  if (!(error instanceof Error))
5310
5725
  throw error;
@@ -5376,7 +5791,7 @@ function setPrivateFileMode(path) {
5376
5791
  chmodSync(path, 384);
5377
5792
  }
5378
5793
  function createAuthToken(paths) {
5379
- ensurePrivateDirectory(dirname7(paths.auth));
5794
+ ensurePrivateDirectory(dirname9(paths.auth));
5380
5795
  const token = randomBytes(AUTH_TOKEN_BYTES).toString("base64url");
5381
5796
  let fd;
5382
5797
  try {
@@ -5457,27 +5872,25 @@ import { fileURLToPath as fileURLToPath3 } from "node:url";
5457
5872
 
5458
5873
  // src/runtime-contract.ts
5459
5874
  import { statSync as statSync4 } from "node:fs";
5460
- import { isAbsolute as isAbsolute3 } from "node:path";
5875
+ import { isAbsolute as isAbsolute4 } from "node:path";
5461
5876
  var OMO_LSP_DAEMON_DIR = "OMO_LSP_DAEMON_DIR";
5462
5877
  var OMO_LSP_DAEMON_CLI = "OMO_LSP_DAEMON_CLI";
5463
5878
  var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
5464
5879
  var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
5465
5880
 
5466
5881
  class InvalidRuntimeOverrideError extends Error {
5467
- code = "invalid_runtime_override";
5468
- reason;
5469
5882
  constructor(reason, message) {
5470
5883
  super(message);
5884
+ this.code = "invalid_runtime_override";
5471
5885
  this.name = "InvalidRuntimeOverrideError";
5472
5886
  this.reason = reason;
5473
5887
  }
5474
5888
  }
5475
5889
 
5476
5890
  class InvalidDaemonVersionError extends Error {
5477
- code = "invalid_daemon_version";
5478
- version;
5479
5891
  constructor(version) {
5480
5892
  super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
5893
+ this.code = "invalid_daemon_version";
5481
5894
  this.name = "InvalidDaemonVersionError";
5482
5895
  this.version = version;
5483
5896
  }
@@ -5496,12 +5909,12 @@ function resolveDaemonRuntime(env, defaults) {
5496
5909
  throw new InvalidRuntimeOverrideError("paired_values_required", `${OMO_LSP_DAEMON_CLI} and ${OMO_LSP_DAEMON_VERSION} must be set together`);
5497
5910
  }
5498
5911
  if (!hasCliOverride || !hasVersionOverride) {
5499
- if (!isAbsolute3(defaults.cliPath)) {
5912
+ if (!isAbsolute4(defaults.cliPath)) {
5500
5913
  throw new InvalidRuntimeOverrideError("packaged_cli_must_be_absolute", "Packaged LSP daemon CLI path must be absolute");
5501
5914
  }
5502
5915
  return { cliPath: defaults.cliPath, version: validateDaemonVersion(defaults.version) };
5503
5916
  }
5504
- if (!isAbsolute3(cliOverride)) {
5917
+ if (!isAbsolute4(cliOverride)) {
5505
5918
  throw new InvalidRuntimeOverrideError("cli_must_be_absolute", `${OMO_LSP_DAEMON_CLI} must be an absolute path to an existing regular file`);
5506
5919
  }
5507
5920
  let cliStats;
@@ -5523,10 +5936,9 @@ var requireFromHere = createRequire(import.meta.url);
5523
5936
  var MAX_SOCKET_PATH_LENGTH = 100;
5524
5937
 
5525
5938
  class InvalidDaemonDirectoryError extends Error {
5526
- code = "invalid_daemon_directory";
5527
- directory;
5528
5939
  constructor(directory) {
5529
5940
  super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
5941
+ this.code = "invalid_daemon_directory";
5530
5942
  this.name = "InvalidDaemonDirectoryError";
5531
5943
  this.directory = directory;
5532
5944
  }
@@ -5680,7 +6092,7 @@ async function probeDaemon(paths, timeoutMs = PROBE_TIMEOUT_MS, signal) {
5680
6092
  return await pingDaemon(paths, token, timeoutMs, signal) !== null;
5681
6093
  }
5682
6094
  function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
5683
- return new Promise((resolve9) => {
6095
+ return new Promise((resolve) => {
5684
6096
  const socket = new Socket;
5685
6097
  let settled = false;
5686
6098
  let timer;
@@ -5692,7 +6104,7 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
5692
6104
  clearTimeout(timer);
5693
6105
  signal?.removeEventListener("abort", onAbort);
5694
6106
  socket.destroy();
5695
- resolve9(value);
6107
+ resolve(value);
5696
6108
  };
5697
6109
  const onAbort = () => finish(null);
5698
6110
  const decoder = createLineDecoder((message) => {
@@ -5715,13 +6127,17 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
5715
6127
  socket.connect(paths.socket);
5716
6128
  });
5717
6129
  }
5718
- function spawnDaemonProcess(paths) {
5719
- mkdirSync3(dirname8(paths.log), { recursive: true });
6130
+ function spawnDaemonProcess(paths, deps = {}) {
6131
+ mkdirSync3(dirname10(paths.log), { recursive: true });
5720
6132
  const logFd = openSync2(paths.log, "a");
5721
6133
  try {
5722
- const child = spawn2(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
6134
+ const spawnDaemonChild = deps.spawn ?? spawn2;
6135
+ const executable = deps.resolveExecutable?.() ?? resolveDaemonNodeExecutable();
6136
+ const child = spawnDaemonChild(executable, [paths.cliPath, "daemon"], {
5723
6137
  detached: true,
5724
- stdio: ["ignore", logFd, logFd]
6138
+ stdio: ["ignore", logFd, logFd],
6139
+ windowsHide: true,
6140
+ env: { ...process.env, BUN_BE_BUN: "1" }
5725
6141
  });
5726
6142
  child.once("spawn", () => closeSync2(logFd));
5727
6143
  child.once("error", (error) => {
@@ -5735,10 +6151,10 @@ function spawnDaemonProcess(paths) {
5735
6151
  throw error;
5736
6152
  }
5737
6153
  }
5738
- function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists = existsSync11) {
6154
+ function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists = existsSync12) {
5739
6155
  if (pathExists(cachedExecPath))
5740
6156
  return cachedExecPath;
5741
- if (isAbsolute4(originalArgv0) && pathExists(originalArgv0))
6157
+ if (isAbsolute5(originalArgv0) && pathExists(originalArgv0))
5742
6158
  return originalArgv0;
5743
6159
  return "node";
5744
6160
  }
@@ -5751,7 +6167,7 @@ function defaultEnsureDaemonDeps() {
5751
6167
  };
5752
6168
  }
5753
6169
  function sleepWithSignal(ms, signal) {
5754
- return new Promise((resolve9) => {
6170
+ return new Promise((resolve) => {
5755
6171
  let settled = false;
5756
6172
  const finish = () => {
5757
6173
  if (settled)
@@ -5759,7 +6175,7 @@ function sleepWithSignal(ms, signal) {
5759
6175
  settled = true;
5760
6176
  clearTimeout(timer);
5761
6177
  signal?.removeEventListener("abort", finish);
5762
- resolve9();
6178
+ resolve();
5763
6179
  };
5764
6180
  const timer = setTimeout(finish, ms);
5765
6181
  if (signal?.aborted) {
@@ -5774,7 +6190,7 @@ function awaitWithSignal2(promise, signal) {
5774
6190
  return promise;
5775
6191
  if (signal.aborted)
5776
6192
  return Promise.reject(abortError3(signal));
5777
- return new Promise((resolve9, reject) => {
6193
+ return new Promise((resolve, reject) => {
5778
6194
  let settled = false;
5779
6195
  const finish = (run) => {
5780
6196
  if (settled)
@@ -5785,7 +6201,7 @@ function awaitWithSignal2(promise, signal) {
5785
6201
  };
5786
6202
  const onAbort = () => finish(() => reject(abortError3(signal)));
5787
6203
  signal.addEventListener("abort", onAbort, { once: true });
5788
- promise.then((value) => finish(() => resolve9(value)), (error) => finish(() => reject(error)));
6204
+ promise.then((value) => finish(() => resolve(value)), (error) => finish(() => reject(error)));
5789
6205
  });
5790
6206
  }
5791
6207
  function throwIfAborted(signal) {
@@ -5814,18 +6230,18 @@ function parsePingResponse(message) {
5814
6230
  return null;
5815
6231
  if (!endpoint || typeof endpoint !== "object" || Array.isArray(endpoint))
5816
6232
  return null;
5817
- const path2 = Reflect.get(endpoint, "path");
6233
+ const path = Reflect.get(endpoint, "path");
5818
6234
  const kind = Reflect.get(endpoint, "kind");
5819
- if (typeof path2 !== "string")
6235
+ if (typeof path !== "string")
5820
6236
  return null;
5821
6237
  if (kind === "windows")
5822
- return { pid, nonce, startedAt, endpoint: { kind, path: path2 } };
6238
+ return { pid, nonce, startedAt, endpoint: { kind, path } };
5823
6239
  if (kind === "missing")
5824
- return { pid, nonce, startedAt, endpoint: { kind, path: path2 } };
6240
+ return { pid, nonce, startedAt, endpoint: { kind, path } };
5825
6241
  const dev = Reflect.get(endpoint, "dev");
5826
6242
  const ino = Reflect.get(endpoint, "ino");
5827
6243
  if (kind === "unix" && typeof dev === "number" && typeof ino === "number") {
5828
- return { pid, nonce, startedAt, endpoint: { kind, path: path2, dev, ino } };
6244
+ return { pid, nonce, startedAt, endpoint: { kind, path, dev, ino } };
5829
6245
  }
5830
6246
  return null;
5831
6247
  }
@@ -5834,7 +6250,10 @@ function parsePingResponse(message) {
5834
6250
  var CONTEXT_KEY = "_context";
5835
6251
 
5836
6252
  class InvalidDaemonRequestError extends Error {
5837
- name = "InvalidDaemonRequestError";
6253
+ constructor() {
6254
+ super(...arguments);
6255
+ this.name = "InvalidDaemonRequestError";
6256
+ }
5838
6257
  }
5839
6258
  function extractRequestContext(raw) {
5840
6259
  if (!isPlainRecord(raw) || raw["method"] !== "tools/call")
@@ -5950,14 +6369,17 @@ async function callToolViaDaemon(name, args, options) {
5950
6369
  function callDiagnosticsViaDaemon(filePath, options) {
5951
6370
  return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
5952
6371
  }
6372
+ function callFormatViaDaemon(filePath, options) {
6373
+ return callToolViaDaemon("format", { filePath }, options);
6374
+ }
5953
6375
  function currentRequestContext(env = process.env) {
5954
6376
  const cwd = process.cwd();
5955
6377
  const home = env["HOME"] ?? homedir3();
5956
6378
  return parseLspRequestContext({
5957
6379
  cwd,
5958
- projectConfigPaths: [join7(cwd, ".codex", "lsp-client.json")],
5959
- userConfigPath: join7(home, ".codex", "lsp-client.json"),
5960
- installDecisionsPath: join7(home, ".codex", "lsp-install-decisions.json"),
6380
+ projectConfigPaths: [join8(cwd, ".codex", "lsp-client.json")],
6381
+ userConfigPath: join8(home, ".codex", "lsp-client.json"),
6382
+ installDecisionsPath: join8(home, ".codex", "lsp-install-decisions.json"),
5961
6383
  capabilities: { installDecisionTool: true }
5962
6384
  });
5963
6385
  }
@@ -5972,7 +6394,7 @@ function withContext(args, context) {
5972
6394
  function ensureDaemonAvailable(paths, ensure, signal) {
5973
6395
  if (!signal)
5974
6396
  return ensure(paths);
5975
- return new Promise((resolve9, reject) => {
6397
+ return new Promise((resolve, reject) => {
5976
6398
  let settled = false;
5977
6399
  const finish = (run) => {
5978
6400
  if (settled)
@@ -5987,11 +6409,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
5987
6409
  return;
5988
6410
  }
5989
6411
  signal.addEventListener("abort", onAbort, { once: true });
5990
- Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve9()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
6412
+ Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
5991
6413
  });
5992
6414
  }
5993
6415
  function sendToolCall(paths, token, name, args, options) {
5994
- return new Promise((resolve9, reject) => {
6416
+ return new Promise((resolve, reject) => {
5995
6417
  const socket = connect(paths.socket);
5996
6418
  const requestId = allocateProxyRequestId();
5997
6419
  let settled = false;
@@ -6044,7 +6466,7 @@ function sendToolCall(paths, token, name, args, options) {
6044
6466
  }
6045
6467
  const result = toToolResult(message, requestId);
6046
6468
  if (result)
6047
- finish(() => resolve9(result));
6469
+ finish(() => resolve(result));
6048
6470
  else
6049
6471
  finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
6050
6472
  });
@@ -6212,18 +6634,18 @@ function canonicalizePathList(value) {
6212
6634
  return value.split(delimiter4).map((entry) => canonicalizePath(entry) ?? entry).join(delimiter4);
6213
6635
  }
6214
6636
  function canonicalizePath(value) {
6215
- if (value === undefined || !isAbsolute5(value) || !existsSync12(value))
6637
+ if (value === undefined || !isAbsolute6(value) || !existsSync13(value))
6216
6638
  return value;
6217
- return realpathSync5(value);
6639
+ return realpathSync6(value);
6218
6640
  }
6219
- function projectRootFromOpenCodeConfigPath(path2) {
6220
- if (basename4(path2) !== "lsp.json" && basename4(path2) !== "lsp-client.json")
6641
+ function projectRootFromOpenCodeConfigPath(path) {
6642
+ if (basename4(path) !== "lsp.json" && basename4(path) !== "lsp-client.json")
6221
6643
  return;
6222
- const configDir = dirname9(path2);
6644
+ const configDir = dirname11(path);
6223
6645
  const configDirName = basename4(configDir);
6224
6646
  if (configDirName !== ".opencode" && configDirName !== ".omo")
6225
6647
  return;
6226
- return dirname9(configDir);
6648
+ return dirname11(configDir);
6227
6649
  }
6228
6650
 
6229
6651
  // src/daemon-server.ts
@@ -6232,12 +6654,12 @@ import { createServer as createServer2 } from "node:net";
6232
6654
 
6233
6655
  // src/ownership.ts
6234
6656
  import { randomUUID } from "node:crypto";
6235
- import { existsSync as existsSync13, lstatSync as lstatSync7, readFileSync as readFileSync7, statSync as statSync5, unlinkSync as unlinkSync3 } from "node:fs";
6236
- import { dirname as dirname11 } from "node:path";
6657
+ import { existsSync as existsSync14, lstatSync as lstatSync7, readFileSync as readFileSync8, statSync as statSync5, unlinkSync as unlinkSync4 } from "node:fs";
6658
+ import { dirname as dirname13 } from "node:path";
6237
6659
 
6238
6660
  // src/lock.ts
6239
- import { closeSync as closeSync3, mkdirSync as mkdirSync4, openSync as openSync3, readFileSync as readFileSync6, unlinkSync as unlinkSync2, writeSync as writeSync3 } from "node:fs";
6240
- import { dirname as dirname10 } from "node:path";
6661
+ import { closeSync as closeSync3, mkdirSync as mkdirSync4, openSync as openSync3, readFileSync as readFileSync7, unlinkSync as unlinkSync3, writeSync as writeSync3 } from "node:fs";
6662
+ import { dirname as dirname12 } from "node:path";
6241
6663
  function isProcessAlive2(pid) {
6242
6664
  if (!Number.isInteger(pid) || pid <= 0)
6243
6665
  return false;
@@ -6252,14 +6674,14 @@ function isProcessAlive2(pid) {
6252
6674
  }
6253
6675
  function readLockPid(lockPath) {
6254
6676
  try {
6255
- const pid = Number.parseInt(readFileSync6(lockPath, "utf8").trim(), 10);
6677
+ const pid = Number.parseInt(readFileSync7(lockPath, "utf8").trim(), 10);
6256
6678
  return Number.isInteger(pid) ? pid : null;
6257
6679
  } catch {
6258
6680
  return null;
6259
6681
  }
6260
6682
  }
6261
6683
  function tryAcquireLock(lockPath, ownerPid = process.pid) {
6262
- mkdirSync4(dirname10(lockPath), { recursive: true });
6684
+ mkdirSync4(dirname12(lockPath), { recursive: true });
6263
6685
  for (let attempt = 0;attempt < 2; attempt += 1) {
6264
6686
  const handle = writeLockFile(lockPath, ownerPid);
6265
6687
  if (handle)
@@ -6289,9 +6711,9 @@ function reapStaleLock(lockPath) {
6289
6711
  unlinkQuietly(lockPath);
6290
6712
  return true;
6291
6713
  }
6292
- function unlinkQuietly(path2) {
6714
+ function unlinkQuietly(path) {
6293
6715
  try {
6294
- unlinkSync2(path2);
6716
+ unlinkSync3(path);
6295
6717
  } catch (error) {
6296
6718
  if (error instanceof Error)
6297
6719
  return;
@@ -6307,17 +6729,19 @@ function errorCode3(error) {
6307
6729
 
6308
6730
  // src/ownership.ts
6309
6731
  class DaemonAlreadyRunningError extends Error {
6310
- name = "DaemonAlreadyRunningError";
6311
- code = "daemon_already_running";
6732
+ constructor() {
6733
+ super(...arguments);
6734
+ this.name = "DaemonAlreadyRunningError";
6735
+ this.code = "daemon_already_running";
6736
+ }
6312
6737
  }
6313
6738
 
6314
6739
  class DaemonStartupDeferredError extends Error {
6315
- reason;
6316
- name = "DaemonStartupDeferredError";
6317
- code = "daemon_startup_deferred";
6318
6740
  constructor(reason) {
6319
6741
  super(`LSP daemon startup deferred: ${reason}`);
6320
6742
  this.reason = reason;
6743
+ this.name = "DaemonStartupDeferredError";
6744
+ this.code = "daemon_startup_deferred";
6321
6745
  }
6322
6746
  }
6323
6747
  async function acquireStartupLease(paths, pingOwner) {
@@ -6340,11 +6764,11 @@ async function acquireStartupLease(paths, pingOwner) {
6340
6764
  function ensureDaemonDirectories(paths) {
6341
6765
  ensurePrivateDirectory(paths.dir);
6342
6766
  if (process.platform !== "win32")
6343
- ensurePrivateDirectory(dirname11(paths.socket));
6767
+ ensurePrivateDirectory(dirname13(paths.socket));
6344
6768
  }
6345
6769
  function readDaemonOwner(paths) {
6346
6770
  try {
6347
- return parseOwner(JSON.parse(readFileSync7(paths.owner, "utf8")));
6771
+ return parseOwner(JSON.parse(readFileSync8(paths.owner, "utf8")));
6348
6772
  } catch (error) {
6349
6773
  if (error instanceof Error)
6350
6774
  return null;
@@ -6409,8 +6833,7 @@ async function validateExistingOwner(paths, pingOwner) {
6409
6833
  if (isProcessAlive2(owner.pid))
6410
6834
  throw new DaemonStartupDeferredError("owner_pid_live_unreachable");
6411
6835
  const reread = readDaemonOwner(paths);
6412
- const endpoint = endpointIdentity(owner.endpoint.path);
6413
- if (!reread || reread.nonce !== owner.nonce || !sameEndpoint(endpoint, owner.endpoint)) {
6836
+ if (!reread || !sameOwner(reread, owner)) {
6414
6837
  throw new DaemonStartupDeferredError("owner_changed_during_cleanup");
6415
6838
  }
6416
6839
  cleanupDeadOwner(paths, owner);
@@ -6420,10 +6843,10 @@ async function validateExistingOwner(paths, pingOwner) {
6420
6843
  throw new DaemonStartupDeferredError("reachable_owner_mismatch");
6421
6844
  }
6422
6845
  function cleanupDeadOwner(paths, owner) {
6423
- if (process.platform !== "win32" && existsSync13(owner.endpoint.path)) {
6846
+ if (process.platform !== "win32" && existsSync14(owner.endpoint.path)) {
6424
6847
  const stat = lstatSync7(owner.endpoint.path);
6425
6848
  if (stat.isSocket())
6426
- unlinkSync3(owner.endpoint.path);
6849
+ unlinkSync4(owner.endpoint.path);
6427
6850
  }
6428
6851
  unlinkQuietly(paths.pid);
6429
6852
  unlinkQuietly(paths.endpoint);
@@ -6452,26 +6875,26 @@ function parseEndpoint(value) {
6452
6875
  if (!value || typeof value !== "object" || Array.isArray(value))
6453
6876
  return null;
6454
6877
  const kind = Reflect.get(value, "kind");
6455
- const path2 = Reflect.get(value, "path");
6456
- if (typeof path2 !== "string")
6878
+ const path = Reflect.get(value, "path");
6879
+ if (typeof path !== "string")
6457
6880
  return null;
6458
6881
  if (kind === undefined)
6459
- return endpointIdentity(path2);
6882
+ return endpointIdentity(path);
6460
6883
  if (kind === "windows")
6461
- return { kind, path: path2 };
6884
+ return { kind, path };
6462
6885
  if (kind === "missing")
6463
- return { kind, path: path2 };
6886
+ return { kind, path };
6464
6887
  const dev = Reflect.get(value, "dev");
6465
6888
  const ino = Reflect.get(value, "ino");
6466
6889
  if (kind === "unix" && typeof dev === "number" && typeof ino === "number")
6467
- return { kind, path: path2, dev, ino };
6890
+ return { kind, path, dev, ino };
6468
6891
  return null;
6469
6892
  }
6470
6893
 
6471
6894
  // src/version-reap.ts
6472
6895
  import { execFile } from "node:child_process";
6473
6896
  import { readdir, readFile, rm } from "node:fs/promises";
6474
- import { basename as basename5, dirname as dirname12, join as join8 } from "node:path";
6897
+ import { basename as basename5, dirname as dirname14, join as join9 } from "node:path";
6475
6898
  var TERM_GRACE_MS = 5000;
6476
6899
  var KILL_GRACE_MS = 1000;
6477
6900
  var VERSION_ENTRY_PATTERN = /^v([A-Za-z0-9][A-Za-z0-9._+-]{0,127})$/;
@@ -6492,13 +6915,13 @@ async function attestDaemonCliProcess(pid, platform, deps = {}) {
6492
6915
  return isNodeCliDaemonCommand(command.trim());
6493
6916
  }
6494
6917
  async function reapStaleDaemonVersions(ownPaths, deps = {}) {
6495
- const baseDir = dirname12(ownPaths.dir);
6918
+ const baseDir = dirname14(ownPaths.dir);
6496
6919
  const platform = deps.platform ?? process.platform;
6497
6920
  const isAlive = deps.isAlive ?? isProcessAlive2;
6498
6921
  const attest = deps.attest ?? ((pid) => attestDaemonCliProcess(pid, platform));
6499
6922
  const sendSignal = deps.sendSignal ?? defaultSendSignal;
6500
6923
  const waitForExit = deps.waitForExit ?? defaultWaitForExit;
6501
- const removeDir = deps.removeDir ?? ((path2) => rm(path2, { recursive: true, force: true }));
6924
+ const removeDir = deps.removeDir ?? ((path) => rm(path, { recursive: true, force: true }));
6502
6925
  const readOwner = deps.readOwner ?? readDaemonOwner;
6503
6926
  const log = deps.log ?? defaultLog;
6504
6927
  const termGraceMs = deps.termGraceMs ?? TERM_GRACE_MS;
@@ -6511,7 +6934,7 @@ async function reapStaleDaemonVersions(ownPaths, deps = {}) {
6511
6934
  const version = parseVersionEntry(entry.name);
6512
6935
  if (version === null || !entry.isDirectory())
6513
6936
  continue;
6514
- const versionDir = join8(baseDir, entry.name);
6937
+ const versionDir = join9(baseDir, entry.name);
6515
6938
  const siblingPaths = daemonPaths({ [OMO_LSP_DAEMON_DIR]: baseDir }, { cliPath: ownPaths.cliPath, version });
6516
6939
  results.push(await reapOneVersion({
6517
6940
  version,
@@ -6535,7 +6958,7 @@ async function reapOneVersion(context) {
6535
6958
  const { version, versionDir } = context;
6536
6959
  const owner = context.readOwner(context.siblingPaths);
6537
6960
  if (!owner) {
6538
- const lockPid = readLockPid(join8(versionDir, "daemon.lock"));
6961
+ const lockPid = readLockPid(join9(versionDir, "daemon.lock"));
6539
6962
  if (lockPid !== null && context.isAlive(lockPid)) {
6540
6963
  context.log(`reap: sparing v${version}: owner metadata missing but daemon.lock is held by live pid ${lockPid}`);
6541
6964
  return { version, status: "spared", reason: `owner metadata missing but lock held by live pid ${lockPid}` };
@@ -6609,17 +7032,17 @@ function isNodeCliDaemonArgv(argv) {
6609
7032
  function isNodeCliDaemonCommand(command) {
6610
7033
  return /\bnode(?:\.exe)?\b/i.test(command) && /\bcli\.js\b/.test(command) && /\bdaemon\b/.test(command);
6611
7034
  }
6612
- function defaultReadProcFile(path2) {
6613
- return readFile(path2);
7035
+ function defaultReadProcFile(path) {
7036
+ return readFile(path);
6614
7037
  }
6615
7038
  function defaultExecuteForStdout(file, args) {
6616
- return new Promise((resolve9) => {
6617
- execFile(file, [...args], { encoding: "utf8", maxBuffer: 1024 * 1024, timeout: 1000 }, (error, stdout) => {
7039
+ return new Promise((resolve) => {
7040
+ execFile(file, [...args], { encoding: "utf8", maxBuffer: 1024 * 1024, timeout: 1000, windowsHide: true }, (error, stdout) => {
6618
7041
  if (error !== null) {
6619
- resolve9(null);
7042
+ resolve(null);
6620
7043
  return;
6621
7044
  }
6622
- resolve9(stdout);
7045
+ resolve(stdout);
6623
7046
  });
6624
7047
  });
6625
7048
  }
@@ -6638,7 +7061,7 @@ async function defaultWaitForExit(pid, timeoutMs) {
6638
7061
  return true;
6639
7062
  if (Date.now() >= deadline)
6640
7063
  return false;
6641
- await new Promise((resolve9) => setTimeout(resolve9, 100));
7064
+ await new Promise((resolve) => setTimeout(resolve, 100));
6642
7065
  }
6643
7066
  }
6644
7067
  function defaultLog(message) {
@@ -6659,7 +7082,7 @@ async function startDaemonServer(paths, options = {}) {
6659
7082
  lastActiveAt = Date.now();
6660
7083
  };
6661
7084
  let routeOwner = lease.owner;
6662
- const server2 = createServer2((socket) => {
7085
+ const server = createServer2((socket) => {
6663
7086
  connections.add(socket);
6664
7087
  const activeRequests = new Map;
6665
7088
  touch();
@@ -6677,10 +7100,10 @@ async function startDaemonServer(paths, options = {}) {
6677
7100
  touch();
6678
7101
  });
6679
7102
  });
6680
- server2.on("error", (error) => logServerError(error));
7103
+ server.on("error", (error) => logServerError(error));
6681
7104
  let owner;
6682
7105
  try {
6683
- await listen(server2, paths.socket);
7106
+ await listen(server, paths.socket);
6684
7107
  if (process.platform !== "win32")
6685
7108
  chmodSync2(paths.socket, 384);
6686
7109
  owner = { ...lease.owner, endpoint: endpointIdentity(paths.socket) };
@@ -6702,7 +7125,7 @@ async function startDaemonServer(paths, options = {}) {
6702
7125
  for (const socket of connections)
6703
7126
  socket.destroy();
6704
7127
  connections.clear();
6705
- await closeServer(server2);
7128
+ await closeServer(server);
6706
7129
  removeDaemonMetadataForOwner(paths, owner);
6707
7130
  await disposeDefaultLspManager();
6708
7131
  };
@@ -6723,7 +7146,7 @@ async function startDaemonServer(paths, options = {}) {
6723
7146
  }, idleCheckIntervalMs);
6724
7147
  idleTimer.unref();
6725
7148
  installSignalHandlers(close);
6726
- return { server: server2, close };
7149
+ return { server, close };
6727
7150
  }
6728
7151
  async function respond(socket, message, token, owner, activeRequests) {
6729
7152
  try {
@@ -6744,18 +7167,18 @@ async function assertSelfProbe(paths, token, owner) {
6744
7167
  if (!ping || ping.nonce !== owner.nonce)
6745
7168
  throw new DaemonStartupDeferredError("self_probe_failed");
6746
7169
  }
6747
- function listen(server2, socketPath) {
6748
- return new Promise((resolve9, reject) => {
7170
+ function listen(server, socketPath) {
7171
+ return new Promise((resolve, reject) => {
6749
7172
  const onError = (error) => reject(error);
6750
- server2.once("error", onError);
6751
- server2.listen(socketPath, () => {
6752
- server2.removeListener("error", onError);
6753
- resolve9();
7173
+ server.once("error", onError);
7174
+ server.listen(socketPath, () => {
7175
+ server.removeListener("error", onError);
7176
+ resolve();
6754
7177
  });
6755
7178
  });
6756
7179
  }
6757
- function closeServer(server2) {
6758
- return new Promise((resolve9) => server2.close(() => resolve9()));
7180
+ function closeServer(server) {
7181
+ return new Promise((resolve) => server.close(() => resolve()));
6759
7182
  }
6760
7183
  function installSignalHandlers(close) {
6761
7184
  const handler = () => {