oh-my-opencode 5.0.0-beta.5 → 5.0.0-beta.51

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