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

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 +51536 -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 +51554 -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 +193 -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 +1264 -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 +189 -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 +200 -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 +423 -6
  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 +18 -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 +3028 -1392
  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
@@ -15,6 +15,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
15
15
  // ../lsp-core/src/lsp/connection.ts
16
16
  import { pathToFileURL } from "node:url";
17
17
 
18
+ // ../lsp-core/src/lsp/timer-provider.ts
19
+ var realTimerProvider = {
20
+ now: () => Date.now(),
21
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
22
+ clearTimeout: (handle) => clearTimeout(handle)
23
+ };
24
+
18
25
  // ../lsp-core/src/lsp/constants.ts
19
26
  var DEFAULT_MAX_REFERENCES = 200;
20
27
  var DEFAULT_MAX_SYMBOLS = 200;
@@ -23,28 +30,24 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
23
30
  var REQUEST_TIMEOUT_MS = 15000;
24
31
  var INIT_TIMEOUT_MS = 60000;
25
32
  var IDLE_TIMEOUT_MS = 5 * 60000;
33
+ var MAX_RESIDENT_CLIENTS = 6;
26
34
  var REAPER_INTERVAL_MS = 60000;
27
35
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
28
36
  var STOP_SIGKILL_GRACE_MS = 1000;
37
+ var CLIENT_RESPAWN_RETRY_LIMIT = 2;
38
+ var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
29
39
 
30
40
  // ../lsp-core/src/lsp/errors.ts
31
41
  class LspConnectionClosedError extends Error {
32
- serverId;
33
- root;
34
- name = "LspConnectionClosedError";
35
42
  constructor(serverId, root, message) {
36
43
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
37
44
  this.serverId = serverId;
38
45
  this.root = root;
46
+ this.name = "LspConnectionClosedError";
39
47
  }
40
48
  }
41
49
 
42
50
  class LspProcessExitedError extends Error {
43
- serverId;
44
- root;
45
- exitCode;
46
- stderrTail;
47
- name = "LspProcessExitedError";
48
51
  constructor(serverId, root, exitCode, stderrTail) {
49
52
  const stderrSuffix = stderrTail ? `
50
53
  stderr tail: ${stderrTail}` : "";
@@ -53,46 +56,59 @@ stderr tail: ${stderrTail}` : "";
53
56
  this.root = root;
54
57
  this.exitCode = exitCode;
55
58
  this.stderrTail = stderrTail;
59
+ this.name = "LspProcessExitedError";
56
60
  }
57
61
  }
58
62
 
59
63
  class LspRequestTimeoutError extends Error {
60
- method;
61
- stderrTail;
62
- name = "LspRequestTimeoutError";
63
64
  constructor(method, stderrTail) {
64
65
  const stderrSuffix = stderrTail ? `
65
66
  recent stderr: ${stderrTail}` : "";
66
67
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
67
68
  this.method = method;
68
69
  this.stderrTail = stderrTail;
70
+ this.name = "LspRequestTimeoutError";
69
71
  }
70
72
  }
71
73
 
72
74
  class LspInvalidPathError extends Error {
73
- name = "LspInvalidPathError";
75
+ constructor() {
76
+ super(...arguments);
77
+ this.name = "LspInvalidPathError";
78
+ }
74
79
  }
75
80
 
76
81
  class LspServerLookupError extends Error {
77
- lookup;
78
- name = "LspServerLookupError";
79
82
  constructor(message, lookup) {
80
83
  super(message);
81
84
  this.lookup = lookup;
85
+ this.name = "LspServerLookupError";
82
86
  }
83
87
  }
84
88
 
85
89
  class LspServerInitializingError extends Error {
86
- originalError;
87
- name = "LspServerInitializingError";
88
90
  constructor(originalError) {
89
91
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
90
92
  this.originalError = originalError;
93
+ this.name = "LspServerInitializingError";
91
94
  }
92
95
  }
93
96
 
94
97
  class LspProcessSpawnError extends Error {
95
- name = "LspProcessSpawnError";
98
+ constructor() {
99
+ super(...arguments);
100
+ this.name = "LspProcessSpawnError";
101
+ }
102
+ }
103
+
104
+ class LspClientRespawnBudgetExceededError extends Error {
105
+ constructor(serverId, root, retryLimit) {
106
+ super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
107
+ this.serverId = serverId;
108
+ this.root = root;
109
+ this.retryLimit = retryLimit;
110
+ this.name = "LspClientRespawnBudgetExceededError";
111
+ }
96
112
  }
97
113
  function isLspDeadConnectionError(err) {
98
114
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -108,20 +124,31 @@ var METHOD_NOT_FOUND = -32601;
108
124
  var INTERNAL_ERROR = -32603;
109
125
 
110
126
  class JsonRpcConnection {
111
- reader;
112
- writer;
113
- pendingRequests = new Map;
114
- notificationHandlers = new Map;
115
- requestHandlers = new Map;
116
- closeHandlers = [];
117
- errorHandlers = [];
118
- inputBuffer = Buffer.alloc(0);
119
- nextRequestId = 1;
120
- listening = false;
121
- disposed = false;
122
127
  constructor(reader, writer) {
123
128
  this.reader = reader;
124
129
  this.writer = writer;
130
+ this.pendingRequests = new Map;
131
+ this.notificationHandlers = new Map;
132
+ this.requestHandlers = new Map;
133
+ this.closeHandlers = [];
134
+ this.errorHandlers = [];
135
+ this.inputBuffer = Buffer.alloc(0);
136
+ this.nextRequestId = 1;
137
+ this.listening = false;
138
+ this.disposed = false;
139
+ this.handleData = (chunk) => {
140
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
141
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
142
+ this.drainInputBuffer();
143
+ };
144
+ this.handleClose = () => {
145
+ for (const handler of this.closeHandlers) {
146
+ handler();
147
+ }
148
+ };
149
+ this.handleStreamError = (error) => {
150
+ this.emitError(error);
151
+ };
125
152
  }
126
153
  listen() {
127
154
  if (this.listening)
@@ -156,6 +183,7 @@ class JsonRpcConnection {
156
183
  let cancelAfterWrite = false;
157
184
  let settled = false;
158
185
  const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
186
+ let rejectAfterCancelWrite;
159
187
  const responsePromise = new Promise((resolve, reject) => {
160
188
  const cleanup = () => {
161
189
  options.signal?.removeEventListener("abort", onAbort);
@@ -167,15 +195,19 @@ class JsonRpcConnection {
167
195
  this.pendingRequests.delete(key);
168
196
  cleanup();
169
197
  const rejectCancelled = () => reject(abortError(options.signal));
198
+ rejectAfterCancelWrite = async () => {
199
+ try {
200
+ await writeCancel();
201
+ } catch (error) {
202
+ this.emitError(toError(error));
203
+ }
204
+ rejectCancelled();
205
+ };
170
206
  if (!requestWritten) {
171
207
  cancelAfterWrite = true;
172
- rejectCancelled();
173
208
  return;
174
209
  }
175
- writeCancel().then(rejectCancelled, (error) => {
176
- this.emitError(toError(error));
177
- rejectCancelled();
178
- });
210
+ rejectAfterCancelWrite();
179
211
  };
180
212
  const onAbort = () => settleCancel();
181
213
  this.pendingRequests.set(key, {
@@ -203,7 +235,7 @@ class JsonRpcConnection {
203
235
  await this.writeMessage(message);
204
236
  requestWritten = true;
205
237
  if (cancelAfterWrite)
206
- await writeCancel();
238
+ await rejectAfterCancelWrite?.();
207
239
  } catch (error) {
208
240
  if (settled)
209
241
  return responsePromise;
@@ -242,19 +274,6 @@ class JsonRpcConnection {
242
274
  this.notificationHandlers.clear();
243
275
  this.requestHandlers.clear();
244
276
  }
245
- handleData = (chunk) => {
246
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
247
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
248
- this.drainInputBuffer();
249
- };
250
- handleClose = () => {
251
- for (const handler of this.closeHandlers) {
252
- handler();
253
- }
254
- };
255
- handleStreamError = (error) => {
256
- this.emitError(error);
257
- };
258
277
  drainInputBuffer() {
259
278
  while (true) {
260
279
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR);
@@ -602,33 +621,29 @@ function isPosition(value) {
602
621
 
603
622
  // ../lsp-core/src/lsp/transport.ts
604
623
  class LspClientNotStartedError extends Error {
605
- serverId;
606
- root;
607
- name = "LspClientNotStartedError";
608
624
  constructor(serverId, root) {
609
625
  super("LSP client not started");
610
626
  this.serverId = serverId;
611
627
  this.root = root;
628
+ this.name = "LspClientNotStartedError";
612
629
  }
613
630
  }
614
631
 
615
632
  class LspClientTransport {
616
- root;
617
- server;
618
- proc = null;
619
- connection = null;
620
- stderrBuffer = [];
621
- processExited = false;
622
- diagnosticsStore = new Map;
623
- requestTimeoutMs;
624
- initializeTimeoutMs;
625
- workspaceApplyEditHandler = null;
626
- diagnosticPullSupported = false;
627
633
  constructor(root, server, timeouts = {}) {
628
634
  this.root = root;
629
635
  this.server = server;
636
+ this.proc = null;
637
+ this.connection = null;
638
+ this.stderrBuffer = [];
639
+ this.processExited = false;
640
+ this.diagnosticsStore = new Map;
641
+ this.workspaceApplyEditHandler = null;
642
+ this.diagnosticPullSupported = false;
643
+ this.documentFormattingSupported = false;
630
644
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
631
645
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
646
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
632
647
  }
633
648
  pid() {
634
649
  return this.proc?.pid;
@@ -648,6 +663,12 @@ class LspClientTransport {
648
663
  isDiagnosticPullSupported() {
649
664
  return this.diagnosticPullSupported;
650
665
  }
666
+ setDocumentFormattingSupported(supported) {
667
+ this.documentFormattingSupported = supported;
668
+ }
669
+ isDocumentFormattingSupported() {
670
+ return this.documentFormattingSupported;
671
+ }
651
672
  handlePublishDiagnostics(params) {
652
673
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
653
674
  }
@@ -723,7 +744,7 @@ class LspClientTransport {
723
744
  const options = args[1];
724
745
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
725
746
  const timeoutController = new AbortController;
726
- const timeoutHandle = setTimeout(() => {
747
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
727
748
  const stderrTail = this.stderrBuffer.slice(-5).join(`
728
749
  `);
729
750
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -742,7 +763,7 @@ class LspClientTransport {
742
763
  }
743
764
  throw error;
744
765
  } finally {
745
- clearTimeout(timeoutHandle);
766
+ this.timerProvider.clearTimeout(timeoutHandle);
746
767
  combinedSignal.dispose();
747
768
  }
748
769
  }
@@ -861,6 +882,14 @@ function supportsDiagnosticPull(capabilities) {
861
882
  return false;
862
883
  return Object.hasOwn(capabilities, "diagnosticProvider");
863
884
  }
885
+ function supportsDocumentFormatting(capabilities) {
886
+ if (capabilities === undefined)
887
+ return false;
888
+ const provider = capabilities.documentFormattingProvider;
889
+ if (provider === undefined || provider === null || provider === false)
890
+ return false;
891
+ return provider === true || typeof provider === "object";
892
+ }
864
893
 
865
894
  class LspClientConnection extends LspClientTransport {
866
895
  async initialize() {
@@ -877,6 +906,7 @@ class LspClientConnection extends LspClientTransport {
877
906
  references: {},
878
907
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
879
908
  publishDiagnostics: {},
909
+ formatting: { dynamicRegistration: false },
880
910
  rename: {
881
911
  prepareSupport: true,
882
912
  prepareSupportDefaultBehavior: 1
@@ -918,6 +948,7 @@ class LspClientConnection extends LspClientTransport {
918
948
  initializationOptions: this.server.initialization
919
949
  }, { timeoutMs: this.initializeTimeoutMs });
920
950
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
951
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
921
952
  await this.sendNotification("initialized", {});
922
953
  await this.sendNotification("workspace/didChangeConfiguration", {
923
954
  settings: { json: { validate: { enable: true } } }
@@ -1123,6 +1154,17 @@ function canonicalPath(filePath) {
1123
1154
  return absolute;
1124
1155
  }
1125
1156
  }
1157
+ function normalizeDocumentUri(uri) {
1158
+ let decoded = uri;
1159
+ try {
1160
+ decoded = decodeURIComponent(uri);
1161
+ } catch {
1162
+ decoded = uri;
1163
+ }
1164
+ if (process.platform !== "win32")
1165
+ return decoded;
1166
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1167
+ }
1126
1168
  function isSameOrDescendant(candidate, parent) {
1127
1169
  const suffix = relative(parent, candidate);
1128
1170
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1133,17 +1175,18 @@ function movedPath(candidate, oldPath, newPath) {
1133
1175
  }
1134
1176
 
1135
1177
  class WorkspaceDocumentState {
1136
- sendNotification;
1137
- clearDiagnostics;
1138
- openDocuments = new Map;
1139
- openByUri = new Map;
1140
- openPromises = new Map;
1141
- now;
1142
- versionlessPublishQuiescenceMs;
1143
1178
  constructor(sendNotification, clearDiagnostics, options = {}) {
1144
1179
  this.sendNotification = sendNotification;
1145
1180
  this.clearDiagnostics = clearDiagnostics;
1146
- this.now = options.now ?? (() => Date.now());
1181
+ this.openDocuments = new Map;
1182
+ this.openByUri = new Map;
1183
+ this.openPromises = new Map;
1184
+ this.timerProvider = options.timerProvider ?? {
1185
+ now: options.now ?? (() => Date.now()),
1186
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1187
+ clearTimeout: (handle) => clearTimeout(handle)
1188
+ };
1189
+ this.now = () => this.timerProvider.now();
1147
1190
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1148
1191
  }
1149
1192
  async openFile(filePath) {
@@ -1165,7 +1208,7 @@ class WorkspaceDocumentState {
1165
1208
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1166
1209
  }
1167
1210
  getStoredDiagnostics(uri) {
1168
- const state = this.openByUri.get(uri);
1211
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1169
1212
  if (!state)
1170
1213
  return [];
1171
1214
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1187,13 +1230,13 @@ class WorkspaceDocumentState {
1187
1230
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1188
1231
  }
1189
1232
  getPullCache(snapshot) {
1190
- const state = this.openByUri.get(snapshot.uri);
1233
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1191
1234
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1192
1235
  return null;
1193
1236
  return state.pullCache;
1194
1237
  }
1195
1238
  recordPullDiagnostics(snapshot, report) {
1196
- const state = this.openByUri.get(snapshot.uri);
1239
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1197
1240
  if (!state)
1198
1241
  return;
1199
1242
  state.pullCache = {
@@ -1203,7 +1246,7 @@ class WorkspaceDocumentState {
1203
1246
  };
1204
1247
  }
1205
1248
  recordPublishedDiagnostics(params) {
1206
- const state = this.openByUri.get(params.uri);
1249
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1207
1250
  if (!state)
1208
1251
  return;
1209
1252
  state.publishGeneration += 1;
@@ -1217,7 +1260,7 @@ class WorkspaceDocumentState {
1217
1260
  this.notifyWaiters(state);
1218
1261
  }
1219
1262
  resolvePushDiagnostics(snapshot) {
1220
- const state = this.openByUri.get(snapshot.uri);
1263
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1221
1264
  if (!state?.lastPublish)
1222
1265
  return { status: "missing" };
1223
1266
  const publish = state.lastPublish;
@@ -1231,7 +1274,7 @@ class WorkspaceDocumentState {
1231
1274
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1232
1275
  }
1233
1276
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1234
- const state = this.openByUri.get(snapshot.uri);
1277
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1235
1278
  if (!state || timeoutMs <= 0)
1236
1279
  return Promise.resolve();
1237
1280
  return new Promise((resolveActivity) => {
@@ -1240,11 +1283,11 @@ class WorkspaceDocumentState {
1240
1283
  if (settled)
1241
1284
  return;
1242
1285
  settled = true;
1243
- clearTimeout(timer);
1286
+ this.timerProvider.clearTimeout(timer);
1244
1287
  state.waiters.delete(finish);
1245
1288
  resolveActivity();
1246
1289
  };
1247
- const timer = setTimeout(finish, timeoutMs);
1290
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1248
1291
  if (typeof timer.unref === "function")
1249
1292
  timer.unref();
1250
1293
  state.waiters.add(finish);
@@ -1352,7 +1395,7 @@ class WorkspaceDocumentState {
1352
1395
  waiters: new Set
1353
1396
  };
1354
1397
  this.openDocuments.set(path, state);
1355
- this.openByUri.set(state.uri, state);
1398
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
1356
1399
  this.notifyWaiters(state);
1357
1400
  await this.sendNotification("textDocument/didOpen", {
1358
1401
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -1377,7 +1420,7 @@ class WorkspaceDocumentState {
1377
1420
  }
1378
1421
  async closeDocument(state) {
1379
1422
  this.openDocuments.delete(state.path);
1380
- this.openByUri.delete(state.uri);
1423
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
1381
1424
  this.clearDiagnostics(state.uri);
1382
1425
  this.notifyWaiters(state);
1383
1426
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -1406,13 +1449,11 @@ import { dirname, isAbsolute, relative as relative2, resolve as resolve2 } from
1406
1449
  import { fileURLToPath } from "node:url";
1407
1450
 
1408
1451
  class WorkspaceEditPathError extends Error {
1409
- path;
1410
- detail;
1411
- name = "WorkspaceEditPathError";
1412
1452
  constructor(path, detail) {
1413
1453
  super(`${detail}: ${path}`);
1414
1454
  this.path = path;
1415
1455
  this.detail = detail;
1456
+ this.name = "WorkspaceEditPathError";
1416
1457
  }
1417
1458
  }
1418
1459
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -1704,13 +1745,11 @@ function canonicalFingerprint(operations) {
1704
1745
 
1705
1746
  // ../lsp-core/src/lsp/workspace-edit-types.ts
1706
1747
  class WorkspaceEditValidationError extends Error {
1707
- changeIndex;
1708
- detail;
1709
- name = "WorkspaceEditValidationError";
1710
1748
  constructor(changeIndex, detail) {
1711
1749
  super(`change ${changeIndex}: ${detail}`);
1712
1750
  this.changeIndex = changeIndex;
1713
1751
  this.detail = detail;
1752
+ this.name = "WorkspaceEditValidationError";
1714
1753
  }
1715
1754
  }
1716
1755
 
@@ -1796,14 +1835,14 @@ function parseSinglePathResource(input, kind) {
1796
1835
  return;
1797
1836
  }
1798
1837
  if (kind === "create") {
1799
- const options2 = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
1838
+ const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
1800
1839
  target.operations.push({
1801
1840
  kind,
1802
1841
  changeIndex,
1803
1842
  path: resolvedPath.path,
1804
1843
  reportedPath: resolvedPath.requestedPath,
1805
- overwrite: options2["overwrite"] ?? false,
1806
- ignoreIfExists: options2["ignoreIfExists"] ?? false,
1844
+ overwrite: options["overwrite"] ?? false,
1845
+ ignoreIfExists: options["ignoreIfExists"] ?? false,
1807
1846
  followedSymbolicLink: resolvedPath.followedSymbolicLink
1808
1847
  });
1809
1848
  return;
@@ -2208,10 +2247,9 @@ function simulateDelete(operation, virtual) {
2208
2247
  import { existsSync as existsSync4, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
2209
2248
  import { dirname as dirname3, resolve as resolve4 } from "node:path";
2210
2249
  class WorkspaceSnapshotBuilder {
2211
- workspaceRoot;
2212
- snapshots = new Map;
2213
2250
  constructor(workspaceRoot) {
2214
2251
  this.workspaceRoot = workspaceRoot;
2252
+ this.snapshots = new Map;
2215
2253
  }
2216
2254
  build(operations) {
2217
2255
  this.add(this.workspaceRoot, false);
@@ -2255,8 +2293,10 @@ function snapshotOperations(operations, workspaceRoot) {
2255
2293
 
2256
2294
  // ../lsp-core/src/lsp/workspace-edit-plan.ts
2257
2295
  class PlanPathIndex {
2258
- firstChangeByPath = new Map;
2259
- reportedPathByCanonical = new Map;
2296
+ constructor() {
2297
+ this.firstChangeByPath = new Map;
2298
+ this.reportedPathByCanonical = new Map;
2299
+ }
2260
2300
  build(operations) {
2261
2301
  for (const operation of operations) {
2262
2302
  switch (operation.kind) {
@@ -2272,11 +2312,11 @@ class PlanPathIndex {
2272
2312
  }
2273
2313
  }
2274
2314
  }
2275
- add(path, reportedPath2, changeIndex) {
2315
+ add(path, reportedPath, changeIndex) {
2276
2316
  if (!this.firstChangeByPath.has(path))
2277
2317
  this.firstChangeByPath.set(path, changeIndex);
2278
2318
  if (!this.reportedPathByCanonical.has(path))
2279
- this.reportedPathByCanonical.set(path, reportedPath2);
2319
+ this.reportedPathByCanonical.set(path, reportedPath);
2280
2320
  }
2281
2321
  }
2282
2322
  function fingerprintWorkspaceEdit(edit, workspaceRoot) {
@@ -2345,14 +2385,11 @@ function isRecord3(value) {
2345
2385
  }
2346
2386
 
2347
2387
  class WorkspaceMutationController {
2348
- workspaceRoot;
2349
- documents;
2350
- activeLease = null;
2351
- nextLeaseId = 1;
2352
- io;
2353
2388
  constructor(workspaceRoot, documents) {
2354
2389
  this.workspaceRoot = workspaceRoot;
2355
2390
  this.documents = documents;
2391
+ this.activeLease = null;
2392
+ this.nextLeaseId = 1;
2356
2393
  }
2357
2394
  setIo(io) {
2358
2395
  this.io = io;
@@ -2391,8 +2428,8 @@ class WorkspaceMutationController {
2391
2428
  };
2392
2429
  }
2393
2430
  lease.phase = "applying";
2394
- lease.applyCompletion = new Promise((resolve5) => {
2395
- lease.resolveApply = resolve5;
2431
+ lease.applyCompletion = new Promise((resolve) => {
2432
+ lease.resolveApply = resolve;
2396
2433
  });
2397
2434
  const edit = isRecord3(params) ? params["edit"] : undefined;
2398
2435
  const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
@@ -2465,14 +2502,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
2465
2502
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
2466
2503
 
2467
2504
  class LspClient extends LspClientConnection {
2468
- diagnosticPullErrors = [];
2469
- documents;
2470
- workspaceMutations;
2471
- diagnosticsFreshnessTimeoutMs;
2472
2505
  constructor(root, server, options = {}) {
2473
2506
  super(root, server, options);
2507
+ this.diagnosticPullErrors = [];
2474
2508
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2475
2509
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
2510
+ timerProvider: this.timerProvider,
2476
2511
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
2477
2512
  });
2478
2513
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -2525,6 +2560,18 @@ class LspClient extends LspClientConnection {
2525
2560
  textDocument: { uri: pathToFileURL3(absPath).href }
2526
2561
  }, options);
2527
2562
  }
2563
+ async formatDocument(filePath, options, signal) {
2564
+ if (!this.isDocumentFormattingSupported())
2565
+ return null;
2566
+ const absPath = this.resolveWorkspacePath(filePath);
2567
+ await this.openFile(absPath);
2568
+ const requestOptions = signal === undefined ? {} : { signal };
2569
+ const edits = await this.sendRequest("textDocument/formatting", {
2570
+ textDocument: { uri: pathToFileURL3(absPath).href },
2571
+ options
2572
+ }, requestOptions);
2573
+ return edits ?? [];
2574
+ }
2528
2575
  async workspaceSymbols(query, signal) {
2529
2576
  const options = signal === undefined ? {} : { signal };
2530
2577
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -2564,7 +2611,7 @@ class LspClient extends LspClientConnection {
2564
2611
  const absPath = this.resolveWorkspacePath(filePath);
2565
2612
  const uri = pathToFileURL3(absPath).href;
2566
2613
  await this.openFile(absPath);
2567
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
2614
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
2568
2615
  for (;; ) {
2569
2616
  signal?.throwIfAborted();
2570
2617
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -2577,13 +2624,13 @@ class LspClient extends LspClientConnection {
2577
2624
  if (!pushFallbackOnly) {
2578
2625
  const cached = this.documents.getPullCache(snapshot);
2579
2626
  try {
2580
- const remainingMs2 = deadlineAt - Date.now();
2581
- if (remainingMs2 <= 0)
2627
+ const remainingMs = deadlineAt - this.timerProvider.now();
2628
+ if (remainingMs <= 0)
2582
2629
  return this.freshnessTimeout(absPath);
2583
2630
  const result = await this.sendRequest("textDocument/diagnostic", {
2584
2631
  textDocument: { uri },
2585
2632
  ...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
2586
- }, { timeoutMs: remainingMs2, ...signal === undefined ? {} : { signal } });
2633
+ }, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
2587
2634
  if (!this.documents.isCurrentSnapshot(snapshot))
2588
2635
  continue;
2589
2636
  const report = this.parseDiagnosticPullReport(result);
@@ -2612,7 +2659,7 @@ class LspClient extends LspClientConnection {
2612
2659
  }
2613
2660
  if (!pushFallbackOnly)
2614
2661
  continue;
2615
- const remainingMs = deadlineAt - Date.now();
2662
+ const remainingMs = deadlineAt - this.timerProvider.now();
2616
2663
  if (remainingMs <= 0) {
2617
2664
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
2618
2665
  const cached = this.documents.getPullCache(snapshot);
@@ -2664,7 +2711,7 @@ function waitForDiagnosticsActivity(wait, signal) {
2664
2711
  return wait;
2665
2712
  if (signal.aborted)
2666
2713
  return Promise.reject(abortError2(signal));
2667
- return new Promise((resolve6, reject) => {
2714
+ return new Promise((resolve, reject) => {
2668
2715
  const onAbort = () => {
2669
2716
  signal.removeEventListener("abort", onAbort);
2670
2717
  reject(abortError2(signal));
@@ -2672,7 +2719,7 @@ function waitForDiagnosticsActivity(wait, signal) {
2672
2719
  signal.addEventListener("abort", onAbort, { once: true });
2673
2720
  wait.then(() => {
2674
2721
  signal.removeEventListener("abort", onAbort);
2675
- resolve6();
2722
+ resolve();
2676
2723
  }, (error) => {
2677
2724
  signal.removeEventListener("abort", onAbort);
2678
2725
  reject(error);
@@ -2740,7 +2787,7 @@ async function stopClientBestEffort(client) {
2740
2787
  function awaitWithSignal(promise, signal) {
2741
2788
  if (!signal)
2742
2789
  return promise;
2743
- return new Promise((resolve6, reject) => {
2790
+ return new Promise((resolve, reject) => {
2744
2791
  let settled = false;
2745
2792
  const onAbort = () => {
2746
2793
  if (settled)
@@ -2758,7 +2805,7 @@ function awaitWithSignal(promise, signal) {
2758
2805
  return;
2759
2806
  settled = true;
2760
2807
  signal.removeEventListener("abort", onAbort);
2761
- resolve6(value);
2808
+ resolve(value);
2762
2809
  }, (err) => {
2763
2810
  if (settled)
2764
2811
  return;
@@ -2770,18 +2817,16 @@ function awaitWithSignal(promise, signal) {
2770
2817
  }
2771
2818
 
2772
2819
  class LspManager {
2773
- clients = new Map;
2774
- reaperHandle = null;
2775
- signalDisposer = null;
2776
- disposed = false;
2777
- idleTimeoutMs;
2778
- initTimeoutMs;
2779
- reaperIntervalMs;
2780
- clientFactory;
2781
- now;
2782
2820
  constructor(options = {}) {
2821
+ this.clients = new Map;
2822
+ this.pendingStops = new Map;
2823
+ this.respawnBudgets = new Map;
2824
+ this.reaperHandle = null;
2825
+ this.signalDisposer = null;
2826
+ this.disposed = false;
2783
2827
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
2784
2828
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
2829
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
2785
2830
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
2786
2831
  this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
2787
2832
  this.now = options.now ?? (() => Date.now());
@@ -2801,24 +2846,79 @@ class LspManager {
2801
2846
  getKey(root, serverId) {
2802
2847
  return `${root}::${serverId}`;
2803
2848
  }
2849
+ tombstoneStop(key, client) {
2850
+ const stop = stopClientBestEffort(client);
2851
+ this.pendingStops.set(key, stop);
2852
+ stop.finally(() => {
2853
+ if (this.pendingStops.get(key) === stop) {
2854
+ this.pendingStops.delete(key);
2855
+ }
2856
+ });
2857
+ return stop;
2858
+ }
2859
+ recordDeadGeneration(key) {
2860
+ let budget = this.respawnBudgets.get(key);
2861
+ if (budget === undefined) {
2862
+ budget = { deadGenerations: 0, exhaustedAt: null };
2863
+ this.respawnBudgets.set(key, budget);
2864
+ }
2865
+ budget.deadGenerations += 1;
2866
+ }
2867
+ markHealthyGeneration(key) {
2868
+ this.respawnBudgets.delete(key);
2869
+ }
2870
+ ensureRespawnAllowed(key, root, serverId) {
2871
+ const budget = this.respawnBudgets.get(key);
2872
+ if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
2873
+ return;
2874
+ if (budget.exhaustedAt === null) {
2875
+ budget.exhaustedAt = this.now();
2876
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
2877
+ }
2878
+ if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
2879
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
2880
+ }
2881
+ budget.deadGenerations = 0;
2882
+ budget.exhaustedAt = null;
2883
+ }
2804
2884
  reapStale() {
2805
2885
  const t = this.now();
2806
2886
  for (const [key, managed] of this.clients) {
2807
2887
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
2808
- stopClientBestEffort(managed.client);
2809
2888
  this.clients.delete(key);
2889
+ this.tombstoneStop(key, managed.client);
2810
2890
  continue;
2811
2891
  }
2812
2892
  if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
2813
- stopClientBestEffort(managed.client);
2814
2893
  this.clients.delete(key);
2894
+ this.tombstoneStop(key, managed.client);
2895
+ }
2896
+ }
2897
+ }
2898
+ evictForAdmission() {
2899
+ while (this.clients.size >= this.maxResidentClients) {
2900
+ const victim = this.leastRecentlyUsedIdleClient();
2901
+ if (!victim)
2902
+ return;
2903
+ this.clients.delete(victim.key);
2904
+ this.tombstoneStop(victim.key, victim.managed.client);
2905
+ }
2906
+ }
2907
+ leastRecentlyUsedIdleClient() {
2908
+ let candidate = null;
2909
+ for (const [key, managed] of this.clients) {
2910
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
2911
+ continue;
2912
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
2913
+ candidate = { key, managed };
2815
2914
  }
2816
2915
  }
2916
+ return candidate;
2817
2917
  }
2818
2918
  async tryDeleteIfOrphaned(key, managed) {
2819
2919
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
2820
2920
  this.clients.delete(key);
2821
- await stopClientBestEffort(managed.client);
2921
+ await this.tombstoneStop(key, managed.client);
2822
2922
  }
2823
2923
  }
2824
2924
  async getClient(root, server, signal) {
@@ -2827,12 +2927,22 @@ class LspManager {
2827
2927
  }
2828
2928
  signal?.throwIfAborted();
2829
2929
  const key = this.getKey(root, server.id);
2930
+ for (;; ) {
2931
+ const pendingStop = this.pendingStops.get(key);
2932
+ if (pendingStop === undefined)
2933
+ break;
2934
+ await awaitWithSignal(pendingStop, signal);
2935
+ signal?.throwIfAborted();
2936
+ }
2937
+ if (this.disposed) {
2938
+ throw new Error("LspManager has been disposed");
2939
+ }
2830
2940
  let managed = this.clients.get(key);
2831
2941
  if (managed) {
2832
2942
  const t = this.now();
2833
2943
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
2834
- await stopClientBestEffort(managed.client);
2835
2944
  this.clients.delete(key);
2945
+ await this.tombstoneStop(key, managed.client);
2836
2946
  managed = undefined;
2837
2947
  }
2838
2948
  }
@@ -2853,14 +2963,20 @@ class LspManager {
2853
2963
  signal.throwIfAborted();
2854
2964
  }
2855
2965
  if (!managed.client.isAlive()) {
2856
- await stopClientBestEffort(managed.client);
2857
- this.clients.delete(key);
2966
+ this.recordDeadGeneration(key);
2967
+ if (this.clients.get(key) === managed) {
2968
+ this.clients.delete(key);
2969
+ }
2970
+ await this.tombstoneStop(key, managed.client);
2858
2971
  return this.getClient(root, server, signal);
2859
2972
  }
2973
+ this.markHealthyGeneration(key);
2860
2974
  managed.refCount++;
2861
2975
  managed.lastUsedAt = this.now();
2862
2976
  return managed.client;
2863
2977
  }
2978
+ this.evictForAdmission();
2979
+ this.ensureRespawnAllowed(key, root, server.id);
2864
2980
  const client = this.clientFactory(root, server);
2865
2981
  const initStartedAt = this.now();
2866
2982
  const initPromise = (async () => {
@@ -2884,7 +3000,7 @@ class LspManager {
2884
3000
  if (this.clients.get(key) === newManaged) {
2885
3001
  this.clients.delete(key);
2886
3002
  }
2887
- await stopClientBestEffort(client);
3003
+ await this.tombstoneStop(key, client);
2888
3004
  throw err;
2889
3005
  }
2890
3006
  newManaged.pendingWaiters--;
@@ -2895,6 +3011,15 @@ class LspManager {
2895
3011
  await this.tryDeleteIfOrphaned(key, newManaged);
2896
3012
  signal.throwIfAborted();
2897
3013
  }
3014
+ if (!client.isAlive()) {
3015
+ this.recordDeadGeneration(key);
3016
+ if (this.clients.get(key) === newManaged) {
3017
+ this.clients.delete(key);
3018
+ }
3019
+ await this.tombstoneStop(key, client);
3020
+ return this.getClient(root, server, signal);
3021
+ }
3022
+ this.markHealthyGeneration(key);
2898
3023
  newManaged.refCount++;
2899
3024
  newManaged.lastUsedAt = this.now();
2900
3025
  return client;
@@ -2915,14 +3040,20 @@ class LspManager {
2915
3040
  if (client && managed.client !== client)
2916
3041
  return;
2917
3042
  this.clients.delete(key);
2918
- stopClientBestEffort(managed.client);
3043
+ this.tombstoneStop(key, managed.client);
2919
3044
  }
2920
3045
  warmupClient(root, server) {
2921
3046
  if (this.disposed)
2922
3047
  return;
2923
3048
  const key = this.getKey(root, server.id);
2924
- if (this.clients.has(key))
3049
+ if (this.clients.has(key) || this.pendingStops.has(key))
3050
+ return;
3051
+ this.evictForAdmission();
3052
+ try {
3053
+ this.ensureRespawnAllowed(key, root, server.id);
3054
+ } catch {
2925
3055
  return;
3056
+ }
2926
3057
  const client = this.clientFactory(root, server);
2927
3058
  const initStartedAt = this.now();
2928
3059
  const initPromise = (async () => {
@@ -2948,7 +3079,7 @@ class LspManager {
2948
3079
  if (this.clients.get(key) === managed) {
2949
3080
  this.clients.delete(key);
2950
3081
  }
2951
- stopClientBestEffort(client);
3082
+ this.tombstoneStop(key, client);
2952
3083
  });
2953
3084
  }
2954
3085
  isServerInitializing(root, serverId) {
@@ -2992,8 +3123,11 @@ class LspManager {
2992
3123
  for (const managed of this.clients.values()) {
2993
3124
  stopPromises.push(stopClientBestEffort(managed.client));
2994
3125
  }
3126
+ const tombstonedStops = [...this.pendingStops.values()];
2995
3127
  this.clients.clear();
2996
- await Promise.allSettled(stopPromises);
3128
+ this.respawnBudgets.clear();
3129
+ await Promise.allSettled([...stopPromises, ...tombstonedStops]);
3130
+ this.pendingStops.clear();
2997
3131
  }
2998
3132
  }
2999
3133
  var _defaultInstance = null;
@@ -3013,7 +3147,7 @@ async function disposeDefaultLspManager() {
3013
3147
  // src/daemon-client.ts
3014
3148
  import { connect } from "node:net";
3015
3149
  import { homedir as homedir3 } from "node:os";
3016
- import { join as join7 } from "node:path";
3150
+ import { join as join8 } from "node:path";
3017
3151
 
3018
3152
  // ../lsp-core/src/request-context.ts
3019
3153
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -3022,18 +3156,17 @@ import { homedir } from "node:os";
3022
3156
  import { basename as basename2, delimiter as delimiter2, dirname as dirname4, isAbsolute as isAbsolute2, join as join2, relative as relative4, resolve as resolve6 } from "node:path";
3023
3157
 
3024
3158
  class LspRequestContextParseError extends Error {
3025
- code;
3026
- name = "LspRequestContextParseError";
3027
3159
  constructor(code, message) {
3028
3160
  super(message);
3029
3161
  this.code = code;
3162
+ this.name = "LspRequestContextParseError";
3030
3163
  }
3031
3164
  }
3032
3165
 
3033
3166
  class LspRequestContextUnavailableError extends Error {
3034
- name = "LspRequestContextUnavailableError";
3035
3167
  constructor() {
3036
3168
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
3169
+ this.name = "LspRequestContextUnavailableError";
3037
3170
  }
3038
3171
  }
3039
3172
  var storage = new AsyncLocalStorage;
@@ -3053,7 +3186,7 @@ function contextCwd() {
3053
3186
  }
3054
3187
  function createStandaloneMcpRequestContext(input = {}) {
3055
3188
  const env = input.env ?? process.env;
3056
- const cwd = canonicalCwd(input.cwd ?? process.cwd());
3189
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
3057
3190
  const home = input.homeDir ?? homedir();
3058
3191
  const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
3059
3192
  const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
@@ -3191,7 +3324,6 @@ function isPlainRecord(value) {
3191
3324
 
3192
3325
  // src/daemon-request-error.ts
3193
3326
  class DaemonRequestError extends Error {
3194
- requestWritten;
3195
3327
  constructor(message, requestWritten) {
3196
3328
  super(message);
3197
3329
  this.name = "DaemonRequestError";
@@ -3214,7 +3346,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
3214
3346
  }
3215
3347
 
3216
3348
  class DaemonRequestTimedOutError extends DaemonRequestError {
3217
- timeoutMs;
3218
3349
  constructor(requestWritten, timeoutMs) {
3219
3350
  super("daemon request timed out", requestWritten);
3220
3351
  this.name = "DaemonRequestTimedOutError";
@@ -3293,14 +3424,12 @@ var PROTOCOL_ERROR_CODE = -32002;
3293
3424
  var AUTH_TOKEN_BYTES = 32;
3294
3425
 
3295
3426
  class UnsafePrivateDirectoryError extends Error {
3296
- path;
3297
- reason;
3298
- name = "UnsafePrivateDirectoryError";
3299
- code = "unsafe_private_directory";
3300
3427
  constructor(path, reason) {
3301
3428
  super(`unsafe private directory ${path}: ${reason}`);
3302
3429
  this.path = path;
3303
3430
  this.reason = reason;
3431
+ this.name = "UnsafePrivateDirectoryError";
3432
+ this.code = "unsafe_private_directory";
3304
3433
  }
3305
3434
  }
3306
3435
  function authEnvelope(token) {
@@ -3484,20 +3613,18 @@ var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
3484
3613
  var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
3485
3614
 
3486
3615
  class InvalidRuntimeOverrideError extends Error {
3487
- code = "invalid_runtime_override";
3488
- reason;
3489
3616
  constructor(reason, message) {
3490
3617
  super(message);
3618
+ this.code = "invalid_runtime_override";
3491
3619
  this.name = "InvalidRuntimeOverrideError";
3492
3620
  this.reason = reason;
3493
3621
  }
3494
3622
  }
3495
3623
 
3496
3624
  class InvalidDaemonVersionError extends Error {
3497
- code = "invalid_daemon_version";
3498
- version;
3499
3625
  constructor(version) {
3500
3626
  super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
3627
+ this.code = "invalid_daemon_version";
3501
3628
  this.name = "InvalidDaemonVersionError";
3502
3629
  this.version = version;
3503
3630
  }
@@ -3543,10 +3670,9 @@ var requireFromHere = createRequire(import.meta.url);
3543
3670
  var MAX_SOCKET_PATH_LENGTH = 100;
3544
3671
 
3545
3672
  class InvalidDaemonDirectoryError extends Error {
3546
- code = "invalid_daemon_directory";
3547
- directory;
3548
3673
  constructor(directory) {
3549
3674
  super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
3675
+ this.code = "invalid_daemon_directory";
3550
3676
  this.name = "InvalidDaemonDirectoryError";
3551
3677
  this.directory = directory;
3552
3678
  }
@@ -3700,7 +3826,7 @@ async function probeDaemon(paths, timeoutMs = PROBE_TIMEOUT_MS, signal) {
3700
3826
  return await pingDaemon(paths, token, timeoutMs, signal) !== null;
3701
3827
  }
3702
3828
  function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
3703
- return new Promise((resolve7) => {
3829
+ return new Promise((resolve) => {
3704
3830
  const socket = new Socket;
3705
3831
  let settled = false;
3706
3832
  let timer;
@@ -3712,7 +3838,7 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
3712
3838
  clearTimeout(timer);
3713
3839
  signal?.removeEventListener("abort", onAbort);
3714
3840
  socket.destroy();
3715
- resolve7(value);
3841
+ resolve(value);
3716
3842
  };
3717
3843
  const onAbort = () => finish(null);
3718
3844
  const decoder = createLineDecoder((message) => {
@@ -3735,13 +3861,17 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
3735
3861
  socket.connect(paths.socket);
3736
3862
  });
3737
3863
  }
3738
- function spawnDaemonProcess(paths) {
3864
+ function spawnDaemonProcess(paths, deps = {}) {
3739
3865
  mkdirSync2(dirname6(paths.log), { recursive: true });
3740
3866
  const logFd = openSync2(paths.log, "a");
3741
3867
  try {
3742
- const child = spawn2(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
3868
+ const spawnDaemonChild = deps.spawn ?? spawn2;
3869
+ const executable = deps.resolveExecutable?.() ?? resolveDaemonNodeExecutable();
3870
+ const child = spawnDaemonChild(executable, [paths.cliPath, "daemon"], {
3743
3871
  detached: true,
3744
- stdio: ["ignore", logFd, logFd]
3872
+ stdio: ["ignore", logFd, logFd],
3873
+ windowsHide: true,
3874
+ env: { ...process.env, BUN_BE_BUN: "1" }
3745
3875
  });
3746
3876
  child.once("spawn", () => closeSync2(logFd));
3747
3877
  child.once("error", (error) => {
@@ -3771,7 +3901,7 @@ function defaultEnsureDaemonDeps() {
3771
3901
  };
3772
3902
  }
3773
3903
  function sleepWithSignal(ms, signal) {
3774
- return new Promise((resolve7) => {
3904
+ return new Promise((resolve) => {
3775
3905
  let settled = false;
3776
3906
  const finish = () => {
3777
3907
  if (settled)
@@ -3779,7 +3909,7 @@ function sleepWithSignal(ms, signal) {
3779
3909
  settled = true;
3780
3910
  clearTimeout(timer);
3781
3911
  signal?.removeEventListener("abort", finish);
3782
- resolve7();
3912
+ resolve();
3783
3913
  };
3784
3914
  const timer = setTimeout(finish, ms);
3785
3915
  if (signal?.aborted) {
@@ -3794,7 +3924,7 @@ function awaitWithSignal2(promise, signal) {
3794
3924
  return promise;
3795
3925
  if (signal.aborted)
3796
3926
  return Promise.reject(abortError3(signal));
3797
- return new Promise((resolve7, reject) => {
3927
+ return new Promise((resolve, reject) => {
3798
3928
  let settled = false;
3799
3929
  const finish = (run) => {
3800
3930
  if (settled)
@@ -3805,7 +3935,7 @@ function awaitWithSignal2(promise, signal) {
3805
3935
  };
3806
3936
  const onAbort = () => finish(() => reject(abortError3(signal)));
3807
3937
  signal.addEventListener("abort", onAbort, { once: true });
3808
- promise.then((value) => finish(() => resolve7(value)), (error) => finish(() => reject(error)));
3938
+ promise.then((value) => finish(() => resolve(value)), (error) => finish(() => reject(error)));
3809
3939
  });
3810
3940
  }
3811
3941
  function throwIfAborted(signal) {
@@ -3834,18 +3964,18 @@ function parsePingResponse(message) {
3834
3964
  return null;
3835
3965
  if (!endpoint || typeof endpoint !== "object" || Array.isArray(endpoint))
3836
3966
  return null;
3837
- const path2 = Reflect.get(endpoint, "path");
3967
+ const path = Reflect.get(endpoint, "path");
3838
3968
  const kind = Reflect.get(endpoint, "kind");
3839
- if (typeof path2 !== "string")
3969
+ if (typeof path !== "string")
3840
3970
  return null;
3841
3971
  if (kind === "windows")
3842
- return { pid, nonce, startedAt, endpoint: { kind, path: path2 } };
3972
+ return { pid, nonce, startedAt, endpoint: { kind, path } };
3843
3973
  if (kind === "missing")
3844
- return { pid, nonce, startedAt, endpoint: { kind, path: path2 } };
3974
+ return { pid, nonce, startedAt, endpoint: { kind, path } };
3845
3975
  const dev = Reflect.get(endpoint, "dev");
3846
3976
  const ino = Reflect.get(endpoint, "ino");
3847
3977
  if (kind === "unix" && typeof dev === "number" && typeof ino === "number") {
3848
- return { pid, nonce, startedAt, endpoint: { kind, path: path2, dev, ino } };
3978
+ return { pid, nonce, startedAt, endpoint: { kind, path, dev, ino } };
3849
3979
  }
3850
3980
  return null;
3851
3981
  }
@@ -3893,7 +4023,7 @@ ${body}` : `${body}
3893
4023
  await writeChunk(output, payload);
3894
4024
  }
3895
4025
  function writeChunk(output, chunk) {
3896
- return new Promise((resolve7, reject) => {
4026
+ return new Promise((resolve, reject) => {
3897
4027
  let settled = false;
3898
4028
  const onError = (error) => {
3899
4029
  if (settled)
@@ -3913,7 +4043,7 @@ function writeChunk(output, chunk) {
3913
4043
  return;
3914
4044
  }
3915
4045
  output.removeListener("error", onError);
3916
- resolve7();
4046
+ resolve();
3917
4047
  });
3918
4048
  } catch (error) {
3919
4049
  output.removeListener("error", onError);
@@ -4022,6 +4152,7 @@ async function runJsonRpcStdioServer(config) {
4022
4152
  const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
4023
4153
  isClosed = true;
4024
4154
  config.onIdleTimeout?.();
4155
+ config.input.destroy();
4025
4156
  });
4026
4157
  const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
4027
4158
  isClosed = true;
@@ -4118,7 +4249,11 @@ function createParentWatchdog(config, onDeadParent) {
4118
4249
  const probeAlive = config.probeAlive ?? isProcessAlive;
4119
4250
  let fired = false;
4120
4251
  const timer = setInterval(() => {
4121
- if (fired || probeAlive(parentPid))
4252
+ if (fired)
4253
+ return;
4254
+ const alive = probeAlive(parentPid);
4255
+ config.onPoll?.(alive);
4256
+ if (alive)
4122
4257
  return;
4123
4258
  fired = true;
4124
4259
  onDeadParent(parentPid, pollIntervalMs);
@@ -4153,60 +4288,55 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
4153
4288
  };
4154
4289
  }
4155
4290
  // ../lsp-core/src/lsp/client-wrapper.ts
4156
- import { existsSync as existsSync10, statSync as statSync4 } from "node:fs";
4157
- import { dirname as dirname8, join as join4, resolve as resolve7 } from "node:path";
4291
+ import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync4 } from "node:fs";
4292
+ import { basename as basename3, dirname as dirname10, join as join5, resolve as resolve8 } from "node:path";
4158
4293
 
4159
- // ../lsp-core/src/lsp/server-install-state.ts
4160
- import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
4161
- import { dirname as dirname7 } from "node:path";
4162
- function getInstallDecisionsPath() {
4163
- return lspRequestContext().installDecisionsPath;
4164
- }
4165
- function loadInstallDecisions() {
4166
- const path2 = getInstallDecisionsPath();
4167
- if (!existsSync7(path2))
4168
- return {};
4169
- try {
4170
- const parsed = JSON.parse(readFileSync4(path2, "utf8"));
4171
- return isInstallDecisions(parsed) ? parsed : {};
4172
- } catch {
4173
- return {};
4294
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
4295
+ import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
4296
+ import { dirname as dirname7, join as join3 } from "node:path";
4297
+
4298
+ // ../lsp-core/src/lsp/workspace-markers.ts
4299
+ var GIT_WORKSPACE_MARKER = ".git";
4300
+ var PROJECT_WORKSPACE_MARKERS = [
4301
+ "package.json",
4302
+ "pyproject.toml",
4303
+ "Cargo.toml",
4304
+ "go.mod",
4305
+ "pom.xml",
4306
+ "build.gradle"
4307
+ ];
4308
+ var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
4309
+
4310
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
4311
+ function findWorkspaceRootOutsideContext(directory) {
4312
+ const marked = nearestMarkedAncestor(directory);
4313
+ if (marked !== undefined)
4314
+ return marked;
4315
+ return realpathSync4(nearestExistingAncestor(directory));
4316
+ }
4317
+ function nearestMarkedAncestor(directory) {
4318
+ let current = directory;
4319
+ for (;; ) {
4320
+ if (existsSync7(current) && WORKSPACE_MARKERS.some((marker) => existsSync7(join3(current, marker)))) {
4321
+ return realpathSync4(current);
4322
+ }
4323
+ const parent = dirname7(current);
4324
+ if (parent === current)
4325
+ return;
4326
+ current = parent;
4174
4327
  }
4175
4328
  }
4176
- function loadInstallDecision(serverId) {
4177
- return loadInstallDecisions()[serverId];
4178
- }
4179
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
4180
- const decisions = loadInstallDecisions();
4181
- decisions[serverId] = { decision, decidedAt };
4182
- writeInstallDecisions(decisions);
4183
- }
4184
- function isInstallDecision(value) {
4185
- return value === "declined" || value === "allowed";
4186
- }
4187
- function writeInstallDecisions(decisions) {
4188
- const path2 = getInstallDecisionsPath();
4189
- mkdirSync3(dirname7(path2), { recursive: true });
4190
- const tmpPath = `${path2}.tmp`;
4191
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
4192
- `, "utf8");
4193
- renameSync2(tmpPath, path2);
4194
- }
4195
- function isInstallDecisions(value) {
4196
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
4197
- }
4198
- function isInstallDecisionRecord(value) {
4199
- if (!isRecord5(value))
4200
- return false;
4201
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
4202
- }
4203
- function isRecord5(value) {
4204
- return typeof value === "object" && value !== null && !Array.isArray(value);
4329
+ function nearestExistingAncestor(directory) {
4330
+ let current = directory;
4331
+ while (!existsSync7(current)) {
4332
+ const parent = dirname7(current);
4333
+ if (parent === current)
4334
+ return current;
4335
+ current = parent;
4336
+ }
4337
+ return current;
4205
4338
  }
4206
4339
 
4207
- // ../lsp-core/src/lsp/config-loader.ts
4208
- import { existsSync as existsSync8, readFileSync as readFileSync5 } from "node:fs";
4209
-
4210
4340
  // ../lsp-core/src/lsp/server-definitions.ts
4211
4341
  var LSP_INSTALL_HINTS = {
4212
4342
  typescript: "npm install -g typescript-language-server typescript",
@@ -4252,6 +4382,26 @@ var LSP_INSTALL_HINTS = {
4252
4382
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
4253
4383
  razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
4254
4384
  };
4385
+ var LSP_LOCAL_INSTALL_HINTS = {
4386
+ typescript: "bun add -d typescript-language-server typescript",
4387
+ vue: "bun add -d @vue/language-server",
4388
+ eslint: "bun add -d vscode-langservers-extracted",
4389
+ oxlint: "bun add -d oxlint",
4390
+ biome: "bun add -d @biomejs/biome",
4391
+ svelte: "bun add -d svelte-language-server",
4392
+ astro: "bun add -d @astrojs/language-server",
4393
+ bash: "bun add -d bash-language-server",
4394
+ "bash-ls": "bun add -d bash-language-server",
4395
+ "yaml-ls": "bun add -d yaml-language-server",
4396
+ php: "bun add -d intelephense",
4397
+ prisma: "bun add -d prisma",
4398
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
4399
+ pyright: "uv add --dev pyright",
4400
+ basedpyright: "uv add --dev basedpyright",
4401
+ ruff: "uv add --dev ruff",
4402
+ ty: "uv add --dev ty",
4403
+ "ruby-lsp": "bundle add ruby-lsp --group development"
4404
+ };
4255
4405
  var BUILTIN_SERVERS = {
4256
4406
  typescript: {
4257
4407
  command: ["typescript-language-server", "--stdio"],
@@ -4354,18 +4504,67 @@ var BUILTIN_SERVERS = {
4354
4504
  }
4355
4505
  };
4356
4506
 
4507
+ // ../lsp-core/src/lsp/server-install-state.ts
4508
+ import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
4509
+ import { dirname as dirname8 } from "node:path";
4510
+ function getInstallDecisionsPath() {
4511
+ return lspRequestContext().installDecisionsPath;
4512
+ }
4513
+ function loadInstallDecisions() {
4514
+ const path = getInstallDecisionsPath();
4515
+ if (!existsSync8(path))
4516
+ return {};
4517
+ try {
4518
+ const parsed = JSON.parse(readFileSync4(path, "utf8"));
4519
+ return isInstallDecisions(parsed) ? parsed : {};
4520
+ } catch {
4521
+ return {};
4522
+ }
4523
+ }
4524
+ function loadInstallDecision(serverId) {
4525
+ return loadInstallDecisions()[serverId];
4526
+ }
4527
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
4528
+ const decisions = loadInstallDecisions();
4529
+ decisions[serverId] = { decision, decidedAt };
4530
+ writeInstallDecisions(decisions);
4531
+ }
4532
+ function isInstallDecision(value) {
4533
+ return value === "declined" || value === "allowed";
4534
+ }
4535
+ function writeInstallDecisions(decisions) {
4536
+ const path = getInstallDecisionsPath();
4537
+ mkdirSync3(dirname8(path), { recursive: true });
4538
+ const tmpPath = `${path}.tmp`;
4539
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
4540
+ `, "utf8");
4541
+ renameSync2(tmpPath, path);
4542
+ }
4543
+ function isInstallDecisions(value) {
4544
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
4545
+ }
4546
+ function isInstallDecisionRecord(value) {
4547
+ if (!isRecord5(value))
4548
+ return false;
4549
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
4550
+ }
4551
+ function isRecord5(value) {
4552
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4553
+ }
4554
+
4357
4555
  // ../lsp-core/src/lsp/config-loader.ts
4556
+ import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
4358
4557
  function getProjectConfigPaths() {
4359
4558
  return lspRequestContext().projectConfigPaths;
4360
4559
  }
4361
4560
  function getUserConfigPath() {
4362
4561
  return lspRequestContext().userConfigPath;
4363
4562
  }
4364
- function loadJsonFile(path2) {
4365
- if (!existsSync8(path2))
4563
+ function loadJsonFile(path) {
4564
+ if (!existsSync9(path))
4366
4565
  return null;
4367
4566
  try {
4368
- const parsed = JSON.parse(readFileSync5(path2, "utf-8"));
4567
+ const parsed = JSON.parse(readFileSync5(path, "utf-8"));
4369
4568
  return isConfigJson(parsed) ? parsed : null;
4370
4569
  } catch {
4371
4570
  return null;
@@ -4382,8 +4581,8 @@ function loadAllConfigs() {
4382
4581
  return configs;
4383
4582
  }
4384
4583
  function loadFirstJsonFile(paths) {
4385
- for (const path2 of paths) {
4386
- const config = loadJsonFile(path2);
4584
+ for (const path of paths) {
4585
+ const config = loadJsonFile(path);
4387
4586
  if (config)
4388
4587
  return config;
4389
4588
  }
@@ -4409,10 +4608,10 @@ function getMergedServers() {
4409
4608
  }
4410
4609
  if (seen.has(id))
4411
4610
  continue;
4412
- const server2 = createServerFromEntry(id, entry, source);
4413
- if (!server2)
4611
+ const server = createServerFromEntry(id, entry, source);
4612
+ if (!server)
4414
4613
  continue;
4415
- servers.push(server2);
4614
+ servers.push(server);
4416
4615
  seen.add(id);
4417
4616
  }
4418
4617
  }
@@ -4444,7 +4643,7 @@ function createServerFromEntry(id, entry, source) {
4444
4643
  if (source === "project") {
4445
4644
  if (!builtin)
4446
4645
  return null;
4447
- const server3 = createServer({
4646
+ const server = createServer({
4448
4647
  id,
4449
4648
  command: builtin.command,
4450
4649
  extensions: entry.extensions ?? builtin.extensions,
@@ -4452,35 +4651,35 @@ function createServerFromEntry(id, entry, source) {
4452
4651
  source
4453
4652
  });
4454
4653
  if (entry.initialization !== undefined) {
4455
- server3.initialization = entry.initialization;
4654
+ server.initialization = entry.initialization;
4456
4655
  }
4457
- return server3;
4656
+ return server;
4458
4657
  }
4459
4658
  if (entry.command && entry.extensions) {
4460
- const server3 = createServer({
4659
+ const server = createServer({
4461
4660
  id,
4462
4661
  command: entry.command,
4463
4662
  extensions: entry.extensions,
4464
4663
  priority: entry.priority ?? 0,
4465
4664
  source
4466
4665
  });
4467
- applyOptionalServerFields(server3, entry);
4468
- return server3;
4666
+ applyOptionalServerFields(server, entry);
4667
+ return server;
4469
4668
  }
4470
4669
  if (!builtin)
4471
4670
  return null;
4472
- const server2 = createServer({
4671
+ const server = createServer({
4473
4672
  id,
4474
4673
  command: entry.command ?? builtin.command,
4475
4674
  extensions: entry.extensions ?? builtin.extensions,
4476
4675
  priority: entry.priority ?? 0,
4477
4676
  source
4478
4677
  });
4479
- applyOptionalServerFields(server2, entry);
4480
- return server2;
4678
+ applyOptionalServerFields(server, entry);
4679
+ return server;
4481
4680
  }
4482
4681
  function createServer(input) {
4483
- const server2 = {
4682
+ const server = {
4484
4683
  id: input.id,
4485
4684
  command: input.command,
4486
4685
  extensions: input.extensions,
@@ -4488,19 +4687,19 @@ function createServer(input) {
4488
4687
  source: input.source
4489
4688
  };
4490
4689
  if (input.env !== undefined) {
4491
- server2.env = input.env;
4690
+ server.env = input.env;
4492
4691
  }
4493
4692
  if (input.initialization !== undefined) {
4494
- server2.initialization = input.initialization;
4693
+ server.initialization = input.initialization;
4495
4694
  }
4496
- return server2;
4695
+ return server;
4497
4696
  }
4498
- function applyOptionalServerFields(server2, entry) {
4697
+ function applyOptionalServerFields(server, entry) {
4499
4698
  if (entry.env !== undefined) {
4500
- server2.env = entry.env;
4699
+ server.env = entry.env;
4501
4700
  }
4502
4701
  if (entry.initialization !== undefined) {
4503
- server2.initialization = entry.initialization;
4702
+ server.initialization = entry.initialization;
4504
4703
  }
4505
4704
  }
4506
4705
  function isConfigJson(value) {
@@ -4550,64 +4749,165 @@ function getDisabledServerIds() {
4550
4749
  }
4551
4750
 
4552
4751
  // ../lsp-core/src/lsp/server-installation.ts
4553
- import { existsSync as existsSync9 } from "node:fs";
4554
- import { delimiter as delimiter3, join as join3 } from "node:path";
4555
- function isServerInstalled(command, _workingDirectory) {
4556
- if (command.length === 0)
4557
- return false;
4558
- const [cmd] = command;
4559
- if (!cmd)
4560
- return false;
4561
- if (cmd.includes("/") || cmd.includes("\\")) {
4562
- if (existsSync9(cmd))
4563
- return true;
4752
+ import { existsSync as existsSync10 } from "node:fs";
4753
+ import { delimiter as delimiter3, dirname as dirname9, isAbsolute as isAbsolute5, join as join4, resolve as resolve7 } from "node:path";
4754
+ var LOCAL_BIN_RULES = [
4755
+ {
4756
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
4757
+ binDirs: [join4("node_modules", ".bin")]
4758
+ },
4759
+ {
4760
+ markers: [
4761
+ "pyproject.toml",
4762
+ "ty.toml",
4763
+ "requirements.txt",
4764
+ "setup.py",
4765
+ "setup.cfg",
4766
+ "Pipfile",
4767
+ "pyrightconfig.json",
4768
+ "ruff.toml",
4769
+ ".ruff.toml"
4770
+ ],
4771
+ binDirs: [
4772
+ join4(".venv", "bin"),
4773
+ join4(".venv", "Scripts"),
4774
+ join4("venv", "bin"),
4775
+ join4("venv", "Scripts"),
4776
+ join4(".env", "bin"),
4777
+ join4(".env", "Scripts")
4778
+ ]
4779
+ },
4780
+ {
4781
+ markers: ["Gemfile", "Gemfile.lock"],
4782
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4783
+ },
4784
+ {
4785
+ markers: ["go.mod", "go.sum", "go.work"],
4786
+ binDirs: ["bin"]
4564
4787
  }
4565
- const isWindows = process.platform === "win32";
4566
- let exts = [""];
4567
- if (isWindows) {
4568
- const pathExt = process.env["PATHEXT"] ?? "";
4569
- if (pathExt) {
4570
- const systemExts = pathExt.split(";").filter(Boolean);
4571
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4572
- } else {
4573
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4788
+ ];
4789
+ var resolutionCache = new Map;
4790
+ var probeCount = 0;
4791
+ function probe(path) {
4792
+ probeCount += 1;
4793
+ return existsSync10(path);
4794
+ }
4795
+ function executableSuffixes(platform, pathExt) {
4796
+ if (platform !== "win32")
4797
+ return [""];
4798
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4799
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4800
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4801
+ }
4802
+ function probeWithSuffixes(directory, command, suffixes) {
4803
+ for (const suffix of suffixes) {
4804
+ const candidate = join4(directory, command + suffix);
4805
+ if (probe(candidate))
4806
+ return candidate;
4807
+ }
4808
+ return null;
4809
+ }
4810
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4811
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4812
+ let current = resolve7(workingDirectory);
4813
+ while (true) {
4814
+ for (const rule of LOCAL_BIN_RULES) {
4815
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
4816
+ continue;
4817
+ for (const binDir of rule.binDirs) {
4818
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4819
+ if (found !== null)
4820
+ return found;
4821
+ }
4574
4822
  }
4823
+ if (probe(join4(current, ".git")))
4824
+ return null;
4825
+ if (boundary !== undefined && current === boundary)
4826
+ return null;
4827
+ const parent = dirname9(current);
4828
+ if (parent === current)
4829
+ return null;
4830
+ current = parent;
4575
4831
  }
4576
- let pathEnv = process.env["PATH"] ?? "";
4577
- if (isWindows && !pathEnv) {
4832
+ }
4833
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4834
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4835
+ if (platform === "win32" && !pathEnv) {
4578
4836
  pathEnv = process.env["Path"] ?? "";
4579
4837
  }
4580
- const paths = pathEnv.split(delimiter3);
4581
- for (const p of paths) {
4582
- for (const suffix of exts) {
4583
- if (existsSync9(join3(p, cmd + suffix))) {
4584
- return true;
4585
- }
4586
- }
4838
+ for (const entry of pathEnv.split(delimiter3)) {
4839
+ if (entry.length === 0)
4840
+ continue;
4841
+ const found = probeWithSuffixes(entry, command, suffixes);
4842
+ if (found !== null)
4843
+ return found;
4587
4844
  }
4588
- if (cmd === "node")
4589
- return true;
4590
- return false;
4845
+ return null;
4846
+ }
4847
+ function resolveServerBinary(command, workingDirectory, options = {}) {
4848
+ if (command.length === 0)
4849
+ return null;
4850
+ const [cmd] = command;
4851
+ if (cmd === undefined || cmd.length === 0)
4852
+ return null;
4853
+ const platform = options.platform ?? process.platform;
4854
+ const suffixes = executableSuffixes(platform, options.pathExt);
4855
+ if (cmd.includes("/") || cmd.includes("\\")) {
4856
+ const explicit = isAbsolute5(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4857
+ return probe(explicit) ? explicit : null;
4858
+ }
4859
+ const cacheKey = JSON.stringify([
4860
+ workingDirectory ?? "",
4861
+ cmd,
4862
+ platform,
4863
+ options.stopAt ?? "",
4864
+ options.pathExt ?? "",
4865
+ options.pathEnv ?? process.env["PATH"] ?? ""
4866
+ ]);
4867
+ const cached = resolutionCache.get(cacheKey);
4868
+ if (cached !== undefined)
4869
+ return cached;
4870
+ let resolved = null;
4871
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
4872
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4873
+ }
4874
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4875
+ if (resolved === null && cmd === "node")
4876
+ resolved = cmd;
4877
+ resolutionCache.set(cacheKey, resolved);
4878
+ return resolved;
4879
+ }
4880
+ function isServerInstalled(command, workingDirectory, options = {}) {
4881
+ if (command.length === 0)
4882
+ return false;
4883
+ return resolveServerBinary(command, workingDirectory, options) !== null;
4591
4884
  }
4592
4885
 
4593
4886
  // ../lsp-core/src/lsp/server-resolution.ts
4887
+ function withResolvedCommand(command, binaryPath) {
4888
+ return [binaryPath, ...command.slice(1)];
4889
+ }
4594
4890
  function findServerForExtension(ext) {
4595
4891
  const servers = getMergedServers();
4596
- for (const server2 of servers) {
4597
- if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4892
+ const workingDirectory = contextCwd();
4893
+ for (const server of servers) {
4894
+ if (!server.extensions.includes(ext))
4895
+ continue;
4896
+ const binaryPath = resolveServerBinary(server.command, workingDirectory);
4897
+ if (binaryPath !== null) {
4598
4898
  const resolvedServer = {
4599
- id: server2.id,
4600
- command: server2.command,
4601
- extensions: server2.extensions,
4602
- priority: server2.priority
4899
+ id: server.id,
4900
+ command: withResolvedCommand(server.command, binaryPath),
4901
+ extensions: server.extensions,
4902
+ priority: server.priority
4603
4903
  };
4604
- if (server2.env !== undefined) {
4904
+ if (server.env !== undefined) {
4605
4905
  return {
4606
4906
  status: "found",
4607
4907
  server: {
4608
4908
  ...resolvedServer,
4609
- env: server2.env,
4610
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4909
+ env: server.env,
4910
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
4611
4911
  }
4612
4912
  };
4613
4913
  }
@@ -4615,20 +4915,20 @@ function findServerForExtension(ext) {
4615
4915
  status: "found",
4616
4916
  server: {
4617
4917
  ...resolvedServer,
4618
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4918
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
4619
4919
  }
4620
4920
  };
4621
4921
  }
4622
4922
  }
4623
- for (const server2 of servers) {
4624
- if (server2.extensions.includes(ext)) {
4625
- const installHint = LSP_INSTALL_HINTS[server2.id] ?? `Install '${server2.command[0]}' and ensure it's in your PATH`;
4923
+ for (const server of servers) {
4924
+ if (server.extensions.includes(ext)) {
4925
+ const installHint = LSP_INSTALL_HINTS[server.id] ?? `Install '${server.command[0]}' and ensure it's in your PATH`;
4626
4926
  return {
4627
4927
  status: "not_installed",
4628
4928
  server: {
4629
- id: server2.id,
4630
- command: server2.command,
4631
- extensions: server2.extensions
4929
+ id: server.id,
4930
+ command: server.command,
4931
+ extensions: server.extensions
4632
4932
  },
4633
4933
  installHint
4634
4934
  };
@@ -4644,20 +4944,21 @@ function findServerForExtension(ext) {
4644
4944
  function getAllServers() {
4645
4945
  const servers = getMergedServers();
4646
4946
  const disabled = getDisabledServerIds();
4947
+ const workingDirectory = contextCwd();
4647
4948
  const result = [];
4648
4949
  const seen = new Set;
4649
- for (const server2 of servers) {
4650
- if (seen.has(server2.id))
4950
+ for (const server of servers) {
4951
+ if (seen.has(server.id))
4651
4952
  continue;
4652
4953
  result.push({
4653
- id: server2.id,
4654
- installed: isServerInstalled(server2.command),
4655
- extensions: server2.extensions,
4954
+ id: server.id,
4955
+ installed: isServerInstalled(server.command, workingDirectory),
4956
+ extensions: server.extensions,
4656
4957
  disabled: false,
4657
- source: server2.source,
4658
- priority: server2.priority
4958
+ source: server.source,
4959
+ priority: server.priority
4659
4960
  });
4660
- seen.add(server2.id);
4961
+ seen.add(server.id);
4661
4962
  }
4662
4963
  for (const id of disabled) {
4663
4964
  if (seen.has(id))
@@ -4665,7 +4966,7 @@ function getAllServers() {
4665
4966
  const builtin = BUILTIN_SERVERS[id];
4666
4967
  result.push({
4667
4968
  id,
4668
- installed: builtin ? isServerInstalled(builtin.command) : false,
4969
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4669
4970
  extensions: builtin?.extensions ?? [],
4670
4971
  disabled: true,
4671
4972
  source: "disabled",
@@ -4676,7 +4977,6 @@ function getAllServers() {
4676
4977
  }
4677
4978
 
4678
4979
  // ../lsp-core/src/lsp/client-wrapper.ts
4679
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
4680
4980
  function isDirectoryPath(filePath) {
4681
4981
  try {
4682
4982
  return statSync4(filePath).isDirectory();
@@ -4685,32 +4985,90 @@ function isDirectoryPath(filePath) {
4685
4985
  }
4686
4986
  }
4687
4987
  function findWorkspaceRoot(filePath) {
4688
- const abs = resolvePathInsideContext(filePath);
4988
+ const cwd = contextCwd();
4989
+ const abs = resolveReadablePathInsideContext(filePath);
4689
4990
  let dir = abs;
4690
4991
  if (!isDirectoryPath(dir)) {
4691
- dir = dirname8(dir);
4692
- }
4693
- let prevDir = "";
4694
- while (dir !== prevDir) {
4695
- for (const marker of WORKSPACE_MARKERS) {
4696
- if (existsSync10(join4(dir, marker))) {
4697
- return dir;
4992
+ dir = dirname10(dir);
4993
+ }
4994
+ if (!isPathInside(cwd, abs))
4995
+ return findWorkspaceRootOutsideContext(dir);
4996
+ const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4997
+ let nearestPackageRoot;
4998
+ while (isPathInside(cwd, dir)) {
4999
+ const canonicalDir = existingDirectoryInsideContext(dir, cwd);
5000
+ if (canonicalDir !== undefined) {
5001
+ if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
5002
+ return canonicalDir;
5003
+ }
5004
+ if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
5005
+ nearestPackageRoot = canonicalDir;
4698
5006
  }
4699
5007
  }
4700
- prevDir = dir;
4701
- dir = dirname8(dir);
5008
+ if (dir === cwd)
5009
+ break;
5010
+ dir = dirname10(dir);
4702
5011
  }
4703
- return dirname8(abs);
5012
+ return nearestPackageRoot ?? fallbackRoot;
5013
+ }
5014
+ function hasProjectWorkspaceMarker(directory) {
5015
+ return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
5016
+ }
5017
+ function resolveReadablePathInsideContext(filePath) {
5018
+ const cwd = contextCwd();
5019
+ const abs = resolve8(cwd, filePath);
5020
+ if (isPathInside(cwd, abs))
5021
+ return abs;
5022
+ const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
5023
+ if (rebased !== undefined)
5024
+ return rebased;
5025
+ return canonicalizeExistingOrNearestAncestor(abs);
4704
5026
  }
4705
5027
  function resolvePathInsideContext(filePath) {
4706
5028
  const cwd = contextCwd();
4707
- const abs = resolve7(cwd, filePath);
5029
+ const abs = resolveReadablePathInsideContext(filePath);
4708
5030
  const canonical = canonicalizeExistingOrNearestAncestor(abs);
4709
5031
  if (!isPathInside(cwd, canonical)) {
4710
5032
  throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
4711
5033
  }
4712
5034
  return canonical;
4713
5035
  }
5036
+ function rebaseThroughCanonicalAncestor(path, cwd) {
5037
+ let current = path;
5038
+ const suffix = [];
5039
+ while (true) {
5040
+ if (existsSync11(current)) {
5041
+ const canonical = realpathSync5(current);
5042
+ if (isPathInside(cwd, canonical))
5043
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
5044
+ }
5045
+ const parent = dirname10(current);
5046
+ if (parent === current)
5047
+ return;
5048
+ suffix.unshift(basename3(current));
5049
+ current = parent;
5050
+ }
5051
+ }
5052
+ function existingDirectoryInsideContext(directory, cwd) {
5053
+ if (!existsSync11(directory))
5054
+ return;
5055
+ const canonical = realpathSync5(directory);
5056
+ if (!statSync4(canonical).isDirectory())
5057
+ return;
5058
+ return isPathInside(cwd, canonical) ? canonical : undefined;
5059
+ }
5060
+ function nearestExistingDirectoryInsideContext(directory, cwd) {
5061
+ let current = directory;
5062
+ while (isPathInside(cwd, current)) {
5063
+ const canonical = existingDirectoryInsideContext(current, cwd);
5064
+ if (canonical !== undefined)
5065
+ return canonical;
5066
+ if (current === cwd)
5067
+ return;
5068
+ current = dirname10(current);
5069
+ }
5070
+ return;
5071
+ }
4714
5072
  function formatServerLookupError(result) {
4715
5073
  if (result.status === "not_installed") {
4716
5074
  return formatNotInstalled(result);
@@ -4734,33 +5092,46 @@ function formatServerLookupError(result) {
4734
5092
  ].join(`
4735
5093
  `);
4736
5094
  }
5095
+ function formatInstallOptions(serverId, installHint) {
5096
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
5097
+ if (localHint === undefined) {
5098
+ return ["To install, run:", ` ${installHint}`];
5099
+ }
5100
+ return [
5101
+ "To install in THIS repository (preferred — no global install needed):",
5102
+ ` ${localHint}`,
5103
+ "",
5104
+ "Or install it globally:",
5105
+ ` ${installHint}`
5106
+ ];
5107
+ }
4737
5108
  function formatNotInstalled(result) {
4738
- const { server: server2, installHint } = result;
4739
- const extensions = server2.extensions.join(", ");
4740
- const decision = loadInstallDecision(server2.id)?.decision;
5109
+ const { server, installHint } = result;
5110
+ const extensions = server.extensions.join(", ");
5111
+ const decision = loadInstallDecision(server.id)?.decision;
4741
5112
  const context = lspRequestContext();
4742
5113
  if (decision === "declined") {
4743
- return `LSP server '${server2.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
5114
+ return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
4744
5115
  }
4745
5116
  const header = [
4746
- `LSP server '${server2.id}' for ${extensions} is NOT INSTALLED.`,
5117
+ `LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
4747
5118
  "",
4748
- `Command not found: ${server2.command[0]}`,
5119
+ `Command not found: ${server.command[0]}`,
4749
5120
  ""
4750
5121
  ];
5122
+ const installOptions = formatInstallOptions(server.id, installHint);
4751
5123
  if (decision === "allowed") {
4752
5124
  return [
4753
5125
  ...header,
4754
5126
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4755
- ` ${installHint}`
5127
+ ...installOptions.slice(1)
4756
5128
  ].join(`
4757
5129
  `);
4758
5130
  }
4759
5131
  if (!context.capabilities.installDecisionTool) {
4760
5132
  return [
4761
5133
  ...header,
4762
- "To install, run:",
4763
- ` ${installHint}`,
5134
+ ...installOptions,
4764
5135
  "",
4765
5136
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4766
5137
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4769,19 +5140,18 @@ function formatNotInstalled(result) {
4769
5140
  }
4770
5141
  return [
4771
5142
  ...header,
4772
- "To install, run:",
4773
- ` ${installHint}`,
5143
+ ...installOptions,
4774
5144
  "",
4775
5145
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4776
5146
  "- If the user agrees: run the install command above, then retry this tool.",
4777
5147
  "- If the user declines, OR has NOT explicitly asked for LSP installation:",
4778
- ` call lsp_install_decision { server_id: "${server2.id}", decision: "declined" },`,
5148
+ ` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
4779
5149
  ` which writes to ${context.installDecisionsPath},`,
4780
5150
  " then ignore this message and proceed WITHOUT LSP."
4781
5151
  ].join(`
4782
5152
  `);
4783
5153
  }
4784
- var READ_ONLY_RETRY_TOOLS = new Set([
5154
+ var READ_ONLY_TOOLS = new Set([
4785
5155
  "diagnostics",
4786
5156
  "definition",
4787
5157
  "references",
@@ -4790,7 +5160,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
4790
5160
  "prepareRename"
4791
5161
  ]);
4792
5162
  async function withLspClient(filePath, fn, toolName, options = {}) {
4793
- const absPath = resolvePathInsideContext(filePath);
5163
+ const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
4794
5164
  if (isDirectoryPath(absPath)) {
4795
5165
  throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
4796
5166
  }
@@ -4799,34 +5169,34 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4799
5169
  if (result.status !== "found") {
4800
5170
  throw new LspServerLookupError(formatServerLookupError(result), result);
4801
5171
  }
4802
- const server2 = result.server;
5172
+ const server = result.server;
4803
5173
  const root = findWorkspaceRoot(absPath);
4804
5174
  const manager = options.manager ?? getLspManager();
4805
5175
  const acquireAndCall = async (allowRetry) => {
4806
- const client = await manager.getClient(root, server2, options.signal);
5176
+ const client = await manager.getClient(root, server, options.signal);
4807
5177
  try {
4808
- return await fn(client, root);
5178
+ return await fn(client, root, absPath);
4809
5179
  } catch (err) {
4810
- if (allowRetry && READ_ONLY_RETRY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4811
- manager.invalidateClient(root, server2.id, client);
5180
+ if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
5181
+ manager.invalidateClient(root, server.id, client);
4812
5182
  return acquireAndCall(false);
4813
5183
  }
4814
5184
  if (err instanceof LspRequestTimeoutError) {
4815
- if (manager.isServerInitializing(root, server2.id)) {
5185
+ if (manager.isServerInitializing(root, server.id)) {
4816
5186
  throw new LspServerInitializingError(err);
4817
5187
  }
4818
5188
  }
4819
5189
  throw err;
4820
5190
  } finally {
4821
- manager.releaseClient(root, server2.id);
5191
+ manager.releaseClient(root, server.id);
4822
5192
  }
4823
5193
  };
4824
5194
  return acquireAndCall(true);
4825
5195
  }
4826
5196
 
4827
5197
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4828
- import { existsSync as existsSync11, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
4829
- import { join as join5, resolve as resolve8 } from "node:path";
5198
+ import { existsSync as existsSync12, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
5199
+ import { join as join6, resolve as resolve9 } from "node:path";
4830
5200
 
4831
5201
  // ../lsp-core/src/lsp/formatters.ts
4832
5202
  import { fileURLToPath as fileURLToPath3 } from "node:url";
@@ -4841,10 +5211,10 @@ function uriToPath(uri) {
4841
5211
  }
4842
5212
  function formatLocation(loc) {
4843
5213
  if ("targetUri" in loc) {
4844
- const uri2 = uriToPath(loc.targetUri);
4845
- const line2 = loc.targetRange.start.line + 1;
4846
- const char2 = loc.targetRange.start.character;
4847
- return `${uri2}:${line2}:${char2}`;
5214
+ const uri = uriToPath(loc.targetUri);
5215
+ const line = loc.targetRange.start.line + 1;
5216
+ const char = loc.targetRange.start.character;
5217
+ return `${uri}:${line}:${char}`;
4848
5218
  }
4849
5219
  const uri = uriToPath(loc.uri);
4850
5220
  const line = loc.range.start.line + 1;
@@ -4956,7 +5326,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
4956
5326
  for (const entry of entries) {
4957
5327
  if (files.length >= maxFiles)
4958
5328
  return;
4959
- const fullPath = join5(currentDir, entry);
5329
+ const fullPath = join6(currentDir, entry);
4960
5330
  let stat;
4961
5331
  try {
4962
5332
  stat = lstatSync5(fullPath);
@@ -4981,15 +5351,15 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4981
5351
  if (!extension.startsWith(".")) {
4982
5352
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4983
5353
  }
4984
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4985
- if (!existsSync11(absDir)) {
5354
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
5355
+ if (!existsSync12(absDir)) {
4986
5356
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4987
5357
  }
4988
5358
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
4989
5359
  if (serverResult.status !== "found") {
4990
5360
  throw new LspServerLookupError(formatServerLookupError(serverResult));
4991
5361
  }
4992
- const server2 = serverResult.server;
5362
+ const server = serverResult.server;
4993
5363
  const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
4994
5364
  const wasCapped = allFiles.length > maxFiles;
4995
5365
  const filesToProcess = allFiles.slice(0, maxFiles);
@@ -5009,7 +5379,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
5009
5379
  const fileErrors = [];
5010
5380
  const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
5011
5381
  options.signal?.throwIfAborted();
5012
- const client = await manager.getClient(root, server2, options.signal);
5382
+ const client = await manager.getClient(root, server, options.signal);
5013
5383
  try {
5014
5384
  let nextIndex = 0;
5015
5385
  const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
@@ -5037,7 +5407,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
5037
5407
  });
5038
5408
  await Promise.all(workers);
5039
5409
  } finally {
5040
- manager.releaseClient(root, server2.id);
5410
+ manager.releaseClient(root, server.id);
5041
5411
  }
5042
5412
  const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
5043
5413
  const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
@@ -5069,7 +5439,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
5069
5439
 
5070
5440
  // ../lsp-core/src/lsp/infer-extension.ts
5071
5441
  import { lstatSync as lstatSync6, readdirSync as readdirSync4 } from "node:fs";
5072
- import { join as join6 } from "node:path";
5442
+ import { join as join7 } from "node:path";
5073
5443
  var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
5074
5444
  var MAX_SCAN_ENTRIES = 500;
5075
5445
  function inferExtensionFromDirectory(directory) {
@@ -5087,7 +5457,7 @@ function inferExtensionFromDirectory(directory) {
5087
5457
  for (const entry of entries) {
5088
5458
  if (scanned >= MAX_SCAN_ENTRIES)
5089
5459
  return;
5090
- const fullPath = join6(dir, entry);
5460
+ const fullPath = join7(dir, entry);
5091
5461
  let stat;
5092
5462
  try {
5093
5463
  stat = lstatSync6(fullPath);
@@ -5246,8 +5616,8 @@ function clientOptions(signal) {
5246
5616
  }
5247
5617
 
5248
5618
  // ../lsp-core/src/tools/result.ts
5249
- function text(text2, details, isError = false) {
5250
- return { content: [{ type: "text", text: text2 }], details, isError };
5619
+ function text(text, details, isError = false) {
5620
+ return { content: [{ type: "text", text }], details, isError };
5251
5621
  }
5252
5622
 
5253
5623
  // ../lsp-core/src/tools/diagnostics.ts
@@ -5262,12 +5632,12 @@ async function executeLspDiagnostics(params, signal) {
5262
5632
  const filePath = requireString(params, "filePath");
5263
5633
  const severity = severityFilter(params);
5264
5634
  try {
5265
- const absPath = resolvePathInsideContext(filePath);
5635
+ const absPath = resolveReadablePathInsideContext(filePath);
5266
5636
  if (isDirectoryPath(absPath)) {
5267
5637
  const extension = inferExtensionFromDirectory(absPath);
5268
5638
  if (!extension) {
5269
5639
  const message = `No supported source files found in directory: ${absPath}`;
5270
- const details3 = {
5640
+ const details = {
5271
5641
  filePath,
5272
5642
  severity,
5273
5643
  mode: "directory",
@@ -5277,24 +5647,24 @@ async function executeLspDiagnostics(params, signal) {
5277
5647
  error: message,
5278
5648
  errorKind: "no_files"
5279
5649
  };
5280
- return text(message, details3);
5650
+ return text(message, details);
5281
5651
  }
5282
- const output2 = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
5283
- const details2 = {
5652
+ const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
5653
+ const details = {
5284
5654
  filePath,
5285
5655
  severity,
5286
5656
  mode: "directory",
5287
5657
  diagnostics: [],
5288
- totalDiagnostics: output2.totalDiagnostics,
5658
+ totalDiagnostics: output.totalDiagnostics,
5289
5659
  truncated: false,
5290
- fileFailures: [...output2.fileFailures]
5660
+ fileFailures: [...output.fileFailures]
5291
5661
  };
5292
- return text(output2.output, details2);
5662
+ return text(output.output, details);
5293
5663
  }
5294
- const result = await withLspClient(filePath, async (client) => client.diagnostics(filePath, signal), "diagnostics", clientOptions(signal));
5664
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
5295
5665
  if (result.transientError) {
5296
5666
  const message = result.transientError.message;
5297
- const details2 = {
5667
+ const details = {
5298
5668
  filePath,
5299
5669
  severity,
5300
5670
  mode: "file",
@@ -5304,7 +5674,7 @@ async function executeLspDiagnostics(params, signal) {
5304
5674
  error: message,
5305
5675
  errorKind: result.transientError.kind
5306
5676
  };
5307
- return text(message, details2, true);
5677
+ return text(message, details, true);
5308
5678
  }
5309
5679
  const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
5310
5680
  const total = diagnostics.length;
@@ -5338,6 +5708,96 @@ async function executeLspDiagnostics(params, signal) {
5338
5708
  throw error;
5339
5709
  }
5340
5710
  }
5711
+ // ../lsp-core/src/lsp/format-document.ts
5712
+ import { readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
5713
+ var DEFAULT_FORMATTING_OPTIONS = {
5714
+ tabSize: 4,
5715
+ insertSpaces: false,
5716
+ trimTrailingWhitespace: true,
5717
+ insertFinalNewline: true,
5718
+ trimFinalNewlines: true
5719
+ };
5720
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
5721
+ async function formatDocumentWithClient(client, filePath, options = {}) {
5722
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
5723
+ if (edits === null)
5724
+ return { status: "unavailable", reason: "capability_not_advertised" };
5725
+ if (edits.length === 0)
5726
+ return UNCHANGED;
5727
+ const before = readFileSync6(filePath, "utf-8");
5728
+ const normalized = normalizeTextEdits(before, edits, 0);
5729
+ if (normalized.text === before)
5730
+ return UNCHANGED;
5731
+ writeAtomically(filePath, normalized.text);
5732
+ await client.openFile(filePath);
5733
+ return {
5734
+ status: "formatted",
5735
+ ...lineDelta(normalized.edits)
5736
+ };
5737
+ }
5738
+ function lineDelta(edits) {
5739
+ let linesAdded = 0;
5740
+ let linesRemoved = 0;
5741
+ for (const edit of edits) {
5742
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
5743
+ linesAdded += edit.newText.split(`
5744
+ `).length;
5745
+ }
5746
+ return { linesAdded, linesRemoved };
5747
+ }
5748
+ function writeAtomically(filePath, content) {
5749
+ const tempPath = `${filePath}.omo-format.tmp`;
5750
+ writeFileSync3(tempPath, content, "utf-8");
5751
+ try {
5752
+ renameSync3(tempPath, filePath);
5753
+ } catch (error) {
5754
+ try {
5755
+ unlinkSync2(tempPath);
5756
+ } catch {}
5757
+ throw error;
5758
+ }
5759
+ }
5760
+
5761
+ // ../lsp-core/src/tools/format.ts
5762
+ async function executeLspFormat(params, signal) {
5763
+ const filePath = requireString(params, "filePath");
5764
+ try {
5765
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
5766
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
5767
+ } catch (error) {
5768
+ const missingDependency = missingDependencyResult(error, {
5769
+ filePath,
5770
+ status: "unavailable",
5771
+ reason: "server_unavailable",
5772
+ linesAdded: 0,
5773
+ linesRemoved: 0
5774
+ });
5775
+ if (missingDependency)
5776
+ return missingDependency;
5777
+ throw error;
5778
+ }
5779
+ }
5780
+ function formatDetails(filePath, result) {
5781
+ if (result.status === "unavailable") {
5782
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5783
+ }
5784
+ return {
5785
+ filePath,
5786
+ status: result.status,
5787
+ linesAdded: result.linesAdded,
5788
+ linesRemoved: result.linesRemoved
5789
+ };
5790
+ }
5791
+ function describeResult(filePath, result) {
5792
+ if (result.status === "unavailable") {
5793
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5794
+ }
5795
+ if (result.status === "unchanged") {
5796
+ return `Already formatted: ${filePath}`;
5797
+ }
5798
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5799
+ }
5800
+
5341
5801
  // ../lsp-core/src/tools/install-decision.ts
5342
5802
  async function executeLspInstallDecision(params) {
5343
5803
  const serverId = requireString(params, "server_id");
@@ -5345,7 +5805,7 @@ async function executeLspInstallDecision(params) {
5345
5805
  if (!isInstallDecision(decision)) {
5346
5806
  return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
5347
5807
  }
5348
- const serverIds = [...new Set(getMergedServers().map((server2) => server2.id))];
5808
+ const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
5349
5809
  if (!serverIds.includes(serverId)) {
5350
5810
  const preview = serverIds.slice(0, 20).join(", ");
5351
5811
  return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
@@ -5366,7 +5826,7 @@ async function executeLspGotoDefinition(params, signal) {
5366
5826
  const line = requireNumber(params, "line");
5367
5827
  const character = requireNumber(params, "character");
5368
5828
  try {
5369
- const result = await withLspClient(filePath, async (client) => client.definition(filePath, line, character, signal), "definition", clientOptions(signal));
5829
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
5370
5830
  const locations = !result ? [] : Array.isArray(result) ? result : [result];
5371
5831
  const details = { filePath, line, character, locations };
5372
5832
  if (locations.length === 0)
@@ -5391,7 +5851,7 @@ async function executeLspFindReferences(params, signal) {
5391
5851
  const character = requireNumber(params, "character");
5392
5852
  const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
5393
5853
  try {
5394
- const result = await withLspClient(filePath, async (client) => client.references(filePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
5854
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
5395
5855
  const references = Array.isArray(result) ? result : [];
5396
5856
  const total = references.length;
5397
5857
  const truncated = total > DEFAULT_MAX_REFERENCES;
@@ -5433,7 +5893,7 @@ async function executeLspPrepareRename(params, signal) {
5433
5893
  const line = requireNumber(params, "line");
5434
5894
  const character = requireNumber(params, "character");
5435
5895
  try {
5436
- const result = await withLspClient(filePath, async (client) => client.prepareRename(filePath, line, character, signal), "prepareRename", clientOptions(signal));
5896
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
5437
5897
  const details = { filePath, line, character, result };
5438
5898
  return text(formatPrepareRenameResult(result), details);
5439
5899
  } catch (error) {
@@ -5454,7 +5914,7 @@ async function executeLspRename(params, signal) {
5454
5914
  const character = requireNumber(params, "character");
5455
5915
  const newName = requireString(params, "newName");
5456
5916
  try {
5457
- const result = await withLspClient(filePath, async (client) => client.rename(filePath, line, character, newName, signal), "rename", clientOptions(signal));
5917
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
5458
5918
  const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
5459
5919
  return text(formatApplyResult(result.apply), details, !result.apply.success);
5460
5920
  } catch (error) {
@@ -5485,10 +5945,10 @@ function objectSchema(properties, required = []) {
5485
5945
  async function executeLspStatus() {
5486
5946
  const servers = getAllServers();
5487
5947
  const snapshots = getLspManager().getSnapshot();
5488
- const installed = servers.filter((server2) => server2.installed && !server2.disabled);
5489
- const configuredLines = servers.map((server2) => {
5490
- const state = server2.disabled ? "disabled" : server2.installed ? "installed" : "missing";
5491
- return `- ${server2.id}: ${state}; source=${server2.source}; extensions=${server2.extensions.join(", ")}`;
5948
+ const installed = servers.filter((server) => server.installed && !server.disabled);
5949
+ const configuredLines = servers.map((server) => {
5950
+ const state = server.disabled ? "disabled" : server.installed ? "installed" : "missing";
5951
+ return `- ${server.id}: ${state}; source=${server.source}; extensions=${server.extensions.join(", ")}`;
5492
5952
  });
5493
5953
  const activeLines = snapshots.map((snapshot) => {
5494
5954
  const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
@@ -5531,10 +5991,10 @@ async function executeLspSymbols(params, signal) {
5531
5991
  errorKind: "missing_query"
5532
5992
  });
5533
5993
  }
5534
- const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
5535
- return formatSymbolsResult(filePath, scope, symbols2, limit, query);
5994
+ const symbols = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
5995
+ return formatSymbolsResult(filePath, scope, symbols, limit, query);
5536
5996
  }
5537
- const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(filePath, signal), "documentSymbols", clientOptions(signal));
5997
+ const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
5538
5998
  return formatSymbolsResult(filePath, scope, symbols, limit);
5539
5999
  } catch (error) {
5540
6000
  const query = optionalString(params, "query");
@@ -5670,6 +6130,16 @@ var LSP_MCP_TOOLS = [
5670
6130
  }, ["filePath", "line", "character", "newName"]),
5671
6131
  execute: executeLspRename
5672
6132
  },
6133
+ {
6134
+ name: "format",
6135
+ aliases: ["lsp_format"],
6136
+ title: "LSP Format",
6137
+ description: "Format a source file with its language server and write the returned edits to disk.",
6138
+ inputSchema: objectSchema({
6139
+ filePath: { type: "string", description: "Source file path to format." }
6140
+ }, ["filePath"]),
6141
+ execute: executeLspFormat
6142
+ },
5673
6143
  {
5674
6144
  name: "install_decision",
5675
6145
  aliases: ["lsp_install_decision"],
@@ -5770,7 +6240,10 @@ function requestedProtocolVersion(params) {
5770
6240
  var CONTEXT_KEY = "_context";
5771
6241
 
5772
6242
  class InvalidDaemonRequestError extends Error {
5773
- name = "InvalidDaemonRequestError";
6243
+ constructor() {
6244
+ super(...arguments);
6245
+ this.name = "InvalidDaemonRequestError";
6246
+ }
5774
6247
  }
5775
6248
  function extractRequestContext(raw) {
5776
6249
  if (!isPlainRecord(raw) || raw["method"] !== "tools/call")
@@ -5886,14 +6359,17 @@ async function callToolViaDaemon(name, args, options) {
5886
6359
  function callDiagnosticsViaDaemon(filePath, options) {
5887
6360
  return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
5888
6361
  }
6362
+ function callFormatViaDaemon(filePath, options) {
6363
+ return callToolViaDaemon("format", { filePath }, options);
6364
+ }
5889
6365
  function currentRequestContext(env = process.env) {
5890
6366
  const cwd = process.cwd();
5891
6367
  const home = env["HOME"] ?? homedir3();
5892
6368
  return parseLspRequestContext({
5893
6369
  cwd,
5894
- projectConfigPaths: [join7(cwd, ".codex", "lsp-client.json")],
5895
- userConfigPath: join7(home, ".codex", "lsp-client.json"),
5896
- installDecisionsPath: join7(home, ".codex", "lsp-install-decisions.json"),
6370
+ projectConfigPaths: [join8(cwd, ".codex", "lsp-client.json")],
6371
+ userConfigPath: join8(home, ".codex", "lsp-client.json"),
6372
+ installDecisionsPath: join8(home, ".codex", "lsp-install-decisions.json"),
5897
6373
  capabilities: { installDecisionTool: true }
5898
6374
  });
5899
6375
  }
@@ -5908,7 +6384,7 @@ function withContext(args, context) {
5908
6384
  function ensureDaemonAvailable(paths, ensure, signal) {
5909
6385
  if (!signal)
5910
6386
  return ensure(paths);
5911
- return new Promise((resolve9, reject) => {
6387
+ return new Promise((resolve, reject) => {
5912
6388
  let settled = false;
5913
6389
  const finish = (run) => {
5914
6390
  if (settled)
@@ -5923,11 +6399,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
5923
6399
  return;
5924
6400
  }
5925
6401
  signal.addEventListener("abort", onAbort, { once: true });
5926
- Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve9()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
6402
+ Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
5927
6403
  });
5928
6404
  }
5929
6405
  function sendToolCall(paths, token, name, args, options) {
5930
- return new Promise((resolve9, reject) => {
6406
+ return new Promise((resolve, reject) => {
5931
6407
  const socket = connect(paths.socket);
5932
6408
  const requestId = allocateProxyRequestId();
5933
6409
  let settled = false;
@@ -5980,7 +6456,7 @@ function sendToolCall(paths, token, name, args, options) {
5980
6456
  }
5981
6457
  const result = toToolResult(message, requestId);
5982
6458
  if (result)
5983
- finish(() => resolve9(result));
6459
+ finish(() => resolve(result));
5984
6460
  else
5985
6461
  finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
5986
6462
  });
@@ -6025,8 +6501,8 @@ function isRetryableTool(name) {
6025
6501
  return name !== "rename" && name !== "lsp_rename";
6026
6502
  }
6027
6503
  // src/proxy.ts
6028
- import { existsSync as existsSync12, realpathSync as realpathSync4 } from "node:fs";
6029
- import { basename as basename3, delimiter as delimiter4, dirname as dirname9, isAbsolute as isAbsolute5 } from "node:path";
6504
+ import { existsSync as existsSync13, realpathSync as realpathSync6 } from "node:fs";
6505
+ import { basename as basename4, delimiter as delimiter4, dirname as dirname11, isAbsolute as isAbsolute6 } from "node:path";
6030
6506
  var DEFAULT_STARTUP_TIMEOUT_MS = 1e4;
6031
6507
  async function runMcpStdioProxy(options = {}) {
6032
6508
  const input = options.input ?? process.stdin;
@@ -6149,34 +6625,34 @@ function canonicalizePathList(value) {
6149
6625
  return value.split(delimiter4).map((entry) => canonicalizePath(entry) ?? entry).join(delimiter4);
6150
6626
  }
6151
6627
  function canonicalizePath(value) {
6152
- if (value === undefined || !isAbsolute5(value) || !existsSync12(value))
6628
+ if (value === undefined || !isAbsolute6(value) || !existsSync13(value))
6153
6629
  return value;
6154
- return realpathSync4(value);
6630
+ return realpathSync6(value);
6155
6631
  }
6156
- function projectRootFromOpenCodeConfigPath(path2) {
6157
- if (basename3(path2) !== "lsp.json" && basename3(path2) !== "lsp-client.json")
6632
+ function projectRootFromOpenCodeConfigPath(path) {
6633
+ if (basename4(path) !== "lsp.json" && basename4(path) !== "lsp-client.json")
6158
6634
  return;
6159
- const configDir = dirname9(path2);
6160
- const configDirName = basename3(configDir);
6635
+ const configDir = dirname11(path);
6636
+ const configDirName = basename4(configDir);
6161
6637
  if (configDirName !== ".opencode" && configDirName !== ".omo")
6162
6638
  return;
6163
- return dirname9(configDir);
6639
+ return dirname11(configDir);
6164
6640
  }
6165
6641
  export {
6166
- validateDaemonVersion,
6167
- runMcpStdioProxy,
6168
- resolveDaemonRuntime,
6169
- probeDaemon,
6170
- ensureDaemonRunning,
6171
- disposeDefaultLspManager,
6172
- daemonPaths,
6173
- currentRequestContext,
6174
- callToolViaDaemon,
6175
- callDiagnosticsViaDaemon,
6176
- OMO_LSP_DAEMON_VERSION,
6177
- OMO_LSP_DAEMON_DIR,
6178
- OMO_LSP_DAEMON_CLI,
6179
- InvalidRuntimeOverrideError,
6642
+ InvalidDaemonDirectoryError,
6180
6643
  InvalidDaemonVersionError,
6181
- InvalidDaemonDirectoryError
6644
+ InvalidRuntimeOverrideError,
6645
+ OMO_LSP_DAEMON_CLI,
6646
+ OMO_LSP_DAEMON_DIR,
6647
+ OMO_LSP_DAEMON_VERSION,
6648
+ callDiagnosticsViaDaemon,
6649
+ callToolViaDaemon,
6650
+ currentRequestContext,
6651
+ daemonPaths,
6652
+ disposeDefaultLspManager,
6653
+ ensureDaemonRunning,
6654
+ probeDaemon,
6655
+ resolveDaemonRuntime,
6656
+ runMcpStdioProxy,
6657
+ validateDaemonVersion
6182
6658
  };