oh-my-opencode 5.0.0-beta.8 → 5.0.0-beta.81

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 (1236) hide show
  1. package/.agents/command/publish.md +59 -23
  2. package/.agents/command/remove-deadcode.md +1 -1
  3. package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +1 -3
  4. package/.agents/skills/hyperplan/SKILL.md +5 -5
  5. package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +1 -1
  6. package/.agents/skills/pre-publish-review/SKILL.md +9 -12
  7. package/.agents/skills/publish/SKILL.md +59 -23
  8. package/.agents/skills/remove-deadcode/SKILL.md +1 -1
  9. package/.agents/skills/security-research/SKILL.md +4 -4
  10. package/.agents/skills/senpi-qa/SKILL.md +80 -0
  11. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
  12. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
  13. package/.agents/skills/tech-debt-audit/SKILL.md +6 -76
  14. package/.opencode/command/publish.md +59 -23
  15. package/.opencode/skills/pre-publish-review/SKILL.md +9 -12
  16. package/README.ja.md +66 -61
  17. package/README.ko.md +67 -62
  18. package/README.md +108 -182
  19. package/README.ru.md +63 -61
  20. package/README.zh-cn.md +62 -61
  21. package/THIRD-PARTY-NOTICES.md +35 -105
  22. package/dist/agents/atlas/agent.d.ts +0 -1
  23. package/dist/agents/gpt-prompt-identity.d.ts +1 -1
  24. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
  25. package/dist/agents/types.d.ts +4 -2
  26. package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
  27. package/dist/cli/doctor/checks/browser-provider.d.ts +2 -0
  28. package/dist/cli/doctor/checks/index.d.ts +2 -0
  29. package/dist/cli/doctor/checks/latest-version.d.ts +11 -0
  30. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  31. package/dist/cli/doctor/framework/constants.d.ts +5 -0
  32. package/dist/cli/doctor/framework/types.d.ts +2 -0
  33. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  34. package/dist/cli/index.js +59118 -63486
  35. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  36. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  37. package/dist/cli/runtime-commands.d.ts +1 -1
  38. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  39. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  40. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  41. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  42. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  43. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  44. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  45. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  46. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  47. package/dist/cli-node/index.js +58841 -63186
  48. package/dist/config/index.d.ts +1 -1
  49. package/dist/config/schema/agent-names.d.ts +0 -1
  50. package/dist/config/schema/background-task.d.ts +1 -0
  51. package/dist/config/schema/browser-automation.d.ts +0 -2
  52. package/dist/config/schema/commands.d.ts +1 -1
  53. package/dist/config/schema/hooks.d.ts +1 -2
  54. package/dist/config/schema/oh-my-opencode-config.d.ts +5 -12
  55. package/dist/config/schema/ulw-execute.d.ts +5 -0
  56. package/dist/config/schema.d.ts +0 -1
  57. package/dist/config/validate.d.ts +2 -0
  58. package/dist/config-migration/category-deep-split.d.ts +3 -0
  59. package/dist/config-migration/migration-plans.d.ts +1 -0
  60. package/dist/create-hooks.d.ts +3 -2
  61. package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +1 -0
  62. package/dist/features/background-agent/constants.d.ts +0 -7
  63. package/dist/features/background-agent/error-classifier.d.ts +1 -0
  64. package/dist/features/background-agent/manager.d.ts +9 -1
  65. package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
  66. package/dist/features/background-agent/parent-wake-notifier-types.d.ts +1 -1
  67. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -1
  68. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -1
  69. package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
  70. package/dist/features/background-agent/types.d.ts +4 -0
  71. package/dist/features/boulder-state/storage.d.ts +1 -1
  72. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  73. package/dist/features/btw-side/context-injector.d.ts +15 -0
  74. package/dist/features/btw-side/index.d.ts +8 -0
  75. package/dist/features/btw-side/metadata.d.ts +15 -0
  76. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  77. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  78. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  79. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  80. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  81. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  82. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  83. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  84. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  85. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  86. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  87. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  88. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  89. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  90. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  91. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  92. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  93. package/dist/features/builtin-commands/templates/hyperplan.d.ts +1 -1
  94. package/dist/features/builtin-commands/templates/refactor-sections/team-mode-addendum.d.ts +1 -1
  95. package/dist/features/builtin-commands/templates/remove-ai-slops.d.ts +1 -1
  96. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  97. package/dist/features/builtin-commands/types.d.ts +1 -1
  98. package/dist/features/claude-tasks/storage.d.ts +7 -2
  99. package/dist/features/hook-message-injector/index.d.ts +1 -0
  100. package/dist/features/hook-message-injector/sdk-message-lookup.d.ts +1 -0
  101. package/dist/features/monitor/manager-internals.d.ts +1 -1
  102. package/dist/features/monitor/output-injector-types.d.ts +1 -1
  103. package/dist/features/opengateway-provider/index.d.ts +13 -0
  104. package/dist/features/task-toast-manager/manager.d.ts +0 -24
  105. package/dist/features/team-mode/tools/lifecycle-inline-spec.d.ts +1 -1
  106. package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +17 -0
  107. package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +3 -0
  108. package/dist/features/team-mode/tools/messaging-runtime.d.ts +7 -0
  109. package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
  110. package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
  111. package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
  112. package/dist/hooks/anthropic-context-window-limit-recovery/tool-result-storage.d.ts +11 -0
  113. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  114. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  115. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  116. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  117. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  118. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  119. package/dist/hooks/atlas/types.d.ts +1 -0
  120. package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
  121. package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
  122. package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
  123. package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
  124. package/dist/hooks/comment-checker/__fixtures__/download-probe.fixture.d.ts +1 -0
  125. package/dist/hooks/compaction-context-injector/validated-model.d.ts +2 -0
  126. package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
  127. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
  128. package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
  129. package/dist/hooks/index.d.ts +1 -2
  130. package/dist/hooks/keyword-detector/hook.d.ts +9 -0
  131. package/dist/hooks/keyword-detector/ultrawork/index.d.ts +2 -0
  132. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
  133. package/dist/hooks/model-fallback/hook.d.ts +1 -1
  134. package/dist/hooks/plan-format-validator/hook.d.ts +19 -0
  135. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  136. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  137. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  138. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  139. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  140. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  141. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  142. package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
  143. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  144. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  145. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  146. package/dist/hooks/unstable-agent-babysitter/task-message-analyzer.d.ts +1 -0
  147. package/dist/index.js +34199 -28037
  148. package/dist/mcp/index.d.ts +0 -4
  149. package/dist/mcp/types.d.ts +0 -1
  150. package/dist/oh-my-opencode.schema.json +28 -59
  151. package/dist/plugin/chat-message/types.d.ts +6 -4
  152. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  153. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  154. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -2
  155. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -3
  156. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  157. package/dist/plugin/messages-transform.d.ts +1 -0
  158. package/dist/plugin/stop-continuation.d.ts +3 -0
  159. package/dist/plugin/system-transform.d.ts +5 -1
  160. package/dist/plugin-config/omo-config-chain.d.ts +1 -0
  161. package/dist/plugin-dispose.d.ts +3 -0
  162. package/dist/shared/agent-tool-restrictions.d.ts +0 -1
  163. package/dist/shared/compaction-agent-config-checkpoint.d.ts +1 -0
  164. package/dist/shared/index.d.ts +2 -0
  165. package/dist/shared/legacy-plugin-warning.d.ts +2 -1
  166. package/dist/shared/omo-process-sweep.d.ts +2 -4
  167. package/dist/shared/plugin-entry-migrator.d.ts +4 -3
  168. package/dist/shared/plugin-entry-shape.d.ts +6 -0
  169. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  170. package/dist/shared/shell-env.d.ts +1 -1
  171. package/dist/skills/ast-grep/AGENTS.md +51 -0
  172. package/dist/skills/ast-grep/SKILL.md +13 -1
  173. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  174. package/dist/skills/coding-agent-sessions/SKILL.md +1 -1
  175. package/dist/skills/data-scientist/SKILL.md +99 -239
  176. package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
  177. package/dist/skills/data-scientist/references/placement.md +74 -0
  178. package/dist/skills/data-scientist/references/polars-lane.md +95 -0
  179. package/dist/skills/data-scientist/references/uv-setup.md +1 -1
  180. package/dist/skills/data-scientist/references/visualization.md +64 -0
  181. package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  182. package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  183. package/dist/skills/debugging/SKILL.md +3 -1
  184. package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
  185. package/dist/skills/debugging/references/methodology/02-investigate.md +26 -5
  186. package/dist/skills/debugging/references/runtimes/go.md +15 -1
  187. package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
  188. package/dist/skills/debugging/references/runtimes/node.md +25 -0
  189. package/dist/skills/debugging/references/runtimes/python.md +13 -0
  190. package/dist/skills/debugging/references/runtimes/rust.md +41 -0
  191. package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
  192. package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
  193. package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  194. package/dist/skills/debugging/references/tools/dap.md +103 -0
  195. package/dist/skills/debugging/references/tools/frida.md +193 -0
  196. package/dist/skills/debugging/references/tools/playwright-cli.md +79 -161
  197. package/dist/skills/frontend/ATTRIBUTION.md +10 -0
  198. package/dist/skills/frontend/SKILL.md +8 -3
  199. package/dist/skills/frontend/references/design/README.md +13 -4
  200. package/dist/skills/frontend/references/design/_INDEX.md +1 -0
  201. package/dist/skills/frontend/references/design/ambience-skill.md +145 -0
  202. package/dist/skills/frontend/references/design/aside.md +1 -1
  203. package/dist/skills/frontend/references/design/clone-from-url.md +1 -1
  204. package/dist/skills/frontend/references/design/design-system-architecture.md +1 -0
  205. package/dist/skills/frontend/references/design/interaction-skill.md +2 -0
  206. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  207. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  208. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  209. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  210. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  211. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  212. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  213. package/dist/skills/frontend/references/perfection/README.md +1 -0
  214. package/dist/skills/frontend/scripts/perfection/lighthouse-audit.py +2 -2
  215. package/dist/skills/git-master/SKILL.md +1 -1
  216. package/dist/skills/init-deep/SKILL.md +14 -14
  217. package/dist/skills/lsp-setup/SKILL.md +1 -1
  218. package/dist/skills/programming/SKILL.md +1 -1
  219. package/dist/skills/refactor/SKILL.md +5 -5
  220. package/dist/skills/remove-ai-slops/SKILL.md +5 -5
  221. package/dist/skills/review-work/SKILL.md +101 -419
  222. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +32 -86
  223. package/dist/skills/ultimate-browsing/SKILL.md +32 -27
  224. package/dist/skills/ultimate-browsing/engine/AGENTS.md +111 -0
  225. package/dist/skills/ultimate-browsing/engine/templates/package.json +2 -2
  226. package/dist/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +5 -2
  227. package/dist/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +8 -6
  228. package/dist/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +86 -0
  229. package/dist/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +4 -7
  230. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +86 -95
  231. package/dist/skills/ultimate-browsing/references/insane-search/README.md +18 -5
  232. package/dist/skills/ultimate-browsing/references/insane-search/playwright.md +16 -13
  233. package/dist/skills/ultimate-browsing/scripts/extract_cookies.py +3 -3
  234. package/dist/skills/{start-work → ulw-execute}/SKILL.md +24 -22
  235. package/dist/skills/ulw-plan/SKILL.md +5 -6
  236. package/dist/skills/ulw-plan/references/full-workflow.md +6 -5
  237. package/dist/skills/ulw-plan/references/intent-unclear.md +2 -2
  238. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -1
  239. package/dist/skills/ulw-research/SKILL.md +10 -5
  240. package/dist/skills/visual-qa/AGENTS.md +58 -0
  241. package/dist/skills/visual-qa/SKILL.md +4 -3
  242. package/dist/skills/visual-qa/references/browser-setup.md +75 -0
  243. package/dist/tools/delegate-task/builtin-categories.d.ts +3 -1
  244. package/dist/tools/delegate-task/builtin-category-definition.d.ts +2 -1
  245. package/dist/tools/delegate-task/constants.d.ts +2 -2
  246. package/dist/tools/delegate-task/openai-categories.d.ts +10 -3
  247. package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
  248. package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
  249. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  250. package/dist/tools/delegate-task/types.d.ts +4 -0
  251. package/dist/tools/session-manager/directory-filter.d.ts +2 -0
  252. package/dist/tui.d.ts +12 -0
  253. package/dist/tui.js +22186 -30577
  254. package/package.json +51 -50
  255. package/packages/git-bash-mcp/dist/cli.js +6 -1
  256. package/packages/git-bash-mcp/package.json +1 -1
  257. package/packages/lsp-core/src/index.ts +1 -0
  258. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +9 -1
  259. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +100 -28
  260. package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
  261. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  262. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +103 -6
  263. package/packages/lsp-core/src/lsp/client-wrapper.ts +50 -16
  264. package/packages/lsp-core/src/lsp/client.ts +32 -3
  265. package/packages/lsp-core/src/lsp/connection.ts +16 -0
  266. package/packages/lsp-core/src/lsp/constants.ts +6 -0
  267. package/packages/lsp-core/src/lsp/controlled-clock-test-support.ts +90 -0
  268. package/packages/lsp-core/src/lsp/errors.ts +15 -0
  269. package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +10 -3
  270. package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
  271. package/packages/lsp-core/src/lsp/format-document.ts +90 -0
  272. package/packages/lsp-core/src/lsp/json-rpc-connection.ts +11 -6
  273. package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
  274. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
  275. package/packages/lsp-core/src/lsp/manager.ts +138 -12
  276. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  277. package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
  278. package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
  279. package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
  280. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
  281. package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
  282. package/packages/lsp-core/src/lsp/timer-provider.ts +13 -0
  283. package/packages/lsp-core/src/lsp/transport-request-timeout.test.ts +73 -0
  284. package/packages/lsp-core/src/lsp/transport.ts +16 -2
  285. package/packages/lsp-core/src/lsp/types.ts +8 -0
  286. package/packages/lsp-core/src/lsp/workspace-apply-edit-test-support.ts +29 -1
  287. package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +84 -1
  288. package/packages/lsp-core/src/lsp/workspace-document-state.ts +35 -11
  289. package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
  290. package/packages/lsp-core/src/mcp.ts +3 -0
  291. package/packages/lsp-core/src/request-context.test.ts +29 -0
  292. package/packages/lsp-core/src/request-context.ts +1 -1
  293. package/packages/lsp-core/src/tool-surface.test.ts +13 -1
  294. package/packages/lsp-core/src/tools/definitions.ts +14 -0
  295. package/packages/lsp-core/src/tools/format.test.ts +56 -0
  296. package/packages/lsp-core/src/tools/format.ts +56 -0
  297. package/packages/lsp-core/src/tools/index.ts +1 -0
  298. package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
  299. package/packages/lsp-core/src/tools/types.ts +10 -0
  300. package/packages/lsp-daemon/dist/cli.js +1421 -960
  301. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  302. package/packages/lsp-daemon/dist/client.js +956 -498
  303. package/packages/lsp-daemon/dist/daemon-client.d.ts +3 -0
  304. package/packages/lsp-daemon/dist/daemon-client.js +23 -3
  305. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +6 -1
  306. package/packages/lsp-daemon/dist/ensure-daemon.js +27 -5
  307. package/packages/lsp-daemon/dist/index.js +860 -407
  308. package/packages/lsp-daemon/dist/ownership.js +2 -2
  309. package/packages/lsp-daemon/dist/proxy.js +3 -0
  310. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  311. package/packages/lsp-daemon/package.json +5 -4
  312. package/packages/lsp-tools-mcp/dist/cli.js +764 -341
  313. package/packages/lsp-tools-mcp/dist/lsp/manager.js +274 -138
  314. package/packages/lsp-tools-mcp/dist/mcp.js +789 -368
  315. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  316. package/packages/lsp-tools-mcp/dist/tools.js +719 -302
  317. package/packages/lsp-tools-mcp/package.json +5 -4
  318. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -21
  319. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -6
  320. package/packages/omo-codex/plugin/.mcp.json +0 -6
  321. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  322. package/packages/omo-codex/plugin/README.md +6 -2
  323. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +8402 -408
  324. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  325. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  326. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  327. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +7 -1
  328. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  329. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  330. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  331. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  332. package/packages/omo-codex/plugin/components/comment-checker/package.json +6 -5
  333. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  334. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  335. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  336. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  337. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  338. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +1 -1
  339. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +2 -1
  340. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  341. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  342. package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +2 -1
  343. package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +6 -7
  344. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +2 -2
  345. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  346. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/directive.md +2 -0
  347. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +36 -29
  348. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +32 -26
  349. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/types.d.ts +3 -0
  350. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  351. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +6 -5
  352. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +32 -28
  353. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/types.ts +3 -0
  354. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +1 -1
  355. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +137 -28
  356. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +4 -2
  357. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  358. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  359. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  360. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +977 -545
  361. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  362. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  363. package/packages/omo-codex/plugin/components/lsp/package.json +6 -5
  364. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  365. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  366. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  367. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  368. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  369. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  370. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  371. package/packages/omo-codex/plugin/components/rules/README.md +2 -0
  372. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  373. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +123 -0
  374. package/packages/omo-codex/plugin/components/rules/dist/cli.js +91 -68
  375. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  376. package/packages/omo-codex/plugin/components/rules/package.json +8 -7
  377. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  378. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  379. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +15 -5
  380. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  381. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  382. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  383. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  384. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  385. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  386. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  387. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  388. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  389. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  390. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  391. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  392. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  393. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +38 -3
  394. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  395. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  396. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  397. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  398. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +29 -6
  399. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  400. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  401. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  402. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  403. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  404. package/packages/omo-codex/plugin/components/teammode/package.json +6 -5
  405. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +4 -10
  406. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  407. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  408. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +5328 -1382
  409. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +5524 -1579
  410. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  411. package/packages/omo-codex/plugin/components/telemetry/package.json +6 -5
  412. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  413. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  414. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  415. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  416. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -4
  417. package/packages/omo-codex/plugin/components/ultrawork/README.md +2 -0
  418. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
  419. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +1 -1
  420. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
  421. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  422. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
  423. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  424. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-low.toml +1 -1
  425. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +1 -1
  426. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +1 -1
  427. package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +1 -1
  428. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +1 -1
  429. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +4 -4
  430. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  431. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +500 -4
  432. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  433. package/packages/omo-codex/plugin/components/ultrawork/package.json +6 -6
  434. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
  435. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +4 -5
  436. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +5 -5
  437. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +2 -2
  438. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -0
  439. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
  440. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
  441. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  442. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  443. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
  444. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
  445. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  446. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +4 -4
  447. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  448. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +6 -6
  449. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  450. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +11 -11
  451. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +16 -16
  452. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +16 -0
  453. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +13 -12
  454. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  455. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  456. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +4 -4
  457. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  458. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  459. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +1 -1
  460. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  461. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +4 -11
  462. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +24 -22
  463. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +19 -0
  464. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +17 -1
  465. package/packages/omo-codex/plugin/components/ulw-loop/README.md +12 -1
  466. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  467. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +44 -27
  468. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +18 -0
  469. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +30 -0
  470. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +10 -4
  471. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +2 -5
  472. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +5 -78
  473. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +12 -0
  474. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +114 -0
  475. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.d.ts +7 -1
  476. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +57 -46
  477. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +2 -2
  478. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +21 -8
  479. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  480. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +12 -1
  481. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +1 -1
  482. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +40 -37
  483. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +2191 -737
  484. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  485. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +28 -8
  486. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +8 -5
  487. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +35 -23
  488. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -0
  489. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +1 -0
  490. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +25 -9
  491. package/packages/omo-codex/plugin/components/ulw-loop/dist/driver-objective-ack.d.ts +4 -0
  492. package/packages/omo-codex/plugin/components/ulw-loop/dist/driver-objective-ack.js +18 -0
  493. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence-artifacts.d.ts +1 -0
  494. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence-artifacts.js +37 -0
  495. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.d.ts +1 -0
  496. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.js +24 -12
  497. package/packages/omo-codex/plugin/components/ulw-loop/dist/ledger.d.ts +4 -0
  498. package/packages/omo-codex/plugin/components/ulw-loop/dist/ledger.js +39 -0
  499. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +2 -0
  500. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +19 -4
  501. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-commit.d.ts +19 -0
  502. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-commit.js +108 -0
  503. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +6 -2
  504. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +54 -25
  505. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-goal-factory.d.ts +10 -3
  506. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-goal-factory.js +38 -31
  507. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +10 -7
  508. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +121 -100
  509. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-log.d.ts +16 -0
  510. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-log.js +115 -0
  511. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +18 -0
  512. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +41 -0
  513. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +7 -0
  514. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +9 -0
  515. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +12 -0
  516. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +104 -0
  517. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  518. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +65 -9
  519. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  520. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  521. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +72 -117
  522. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.d.ts +2 -0
  523. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +25 -13
  524. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.d.ts +2 -0
  525. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.js +157 -0
  526. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.d.ts +381 -0
  527. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.js +127 -0
  528. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.d.ts +130 -0
  529. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.js +1 -0
  530. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.d.ts +3 -0
  531. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.js +3 -0
  532. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-budget-io.d.ts +5 -0
  533. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-budget-io.js +67 -0
  534. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +7 -1
  535. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +188 -59
  536. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-role-guard.d.ts +2 -0
  537. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-role-guard.js +22 -0
  538. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.d.ts +19 -0
  539. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.js +259 -0
  540. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +7 -0
  541. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +41 -0
  542. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.js +4 -4
  543. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.d.ts +3 -2
  544. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.js +4 -4
  545. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.d.ts +9 -1
  546. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.d.ts +3 -2
  547. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +11 -11
  548. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +28 -23
  549. package/packages/omo-codex/plugin/components/ulw-loop/dist/success-criteria-input.d.ts +9 -0
  550. package/packages/omo-codex/plugin/components/ulw-loop/dist/success-criteria-input.js +41 -0
  551. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +19 -0
  552. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +83 -0
  553. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +18 -5
  554. package/packages/omo-codex/plugin/components/ulw-loop/package.json +7 -6
  555. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +7 -2
  556. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +33 -10
  557. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +52 -0
  558. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +8 -6
  559. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +5 -98
  560. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +134 -0
  561. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +59 -77
  562. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +10 -4
  563. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +24 -8
  564. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +14 -1
  565. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +52 -46
  566. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +8 -6
  567. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +35 -7
  568. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +51 -33
  569. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  570. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +1 -0
  571. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +27 -9
  572. package/packages/omo-codex/plugin/components/ulw-loop/src/driver-objective-ack.ts +20 -0
  573. package/packages/omo-codex/plugin/components/ulw-loop/src/evidence-artifacts.ts +45 -0
  574. package/packages/omo-codex/plugin/components/ulw-loop/src/evidence.ts +23 -16
  575. package/packages/omo-codex/plugin/components/ulw-loop/src/ledger.ts +38 -0
  576. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +32 -4
  577. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-commit.ts +132 -0
  578. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +67 -54
  579. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-goal-factory.ts +63 -31
  580. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +140 -119
  581. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-log.ts +112 -0
  582. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +61 -0
  583. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +11 -0
  584. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +123 -0
  585. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +71 -15
  586. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  587. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +92 -136
  588. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +38 -13
  589. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/factory.ts +218 -0
  590. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/manifest.ts +156 -0
  591. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/types.ts +143 -0
  592. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk.ts +3 -0
  593. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-budget-io.ts +59 -0
  594. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +196 -52
  595. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-role-guard.ts +22 -0
  596. package/packages/omo-codex/plugin/components/ulw-loop/src/state-lock.ts +257 -0
  597. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +45 -0
  598. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-batch.ts +4 -4
  599. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-mutations.ts +5 -4
  600. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-types.ts +13 -1
  601. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +12 -10
  602. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +27 -22
  603. package/packages/omo-codex/plugin/components/ulw-loop/src/success-criteria-input.ts +56 -0
  604. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +115 -0
  605. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  606. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +131 -82
  607. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +147 -0
  608. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint.test.ts +16 -22
  609. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +4 -2
  610. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint.test.ts +31 -2
  611. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +2 -0
  612. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-complete-goals.test.ts +3 -1
  613. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +35 -8
  614. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +38 -4
  615. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-json-errors.test.ts +27 -0
  616. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-scope-required.test.ts +144 -0
  617. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +185 -0
  618. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +8 -3
  619. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +6 -0
  620. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +37 -2
  621. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +88 -11
  622. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  623. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/barrier.ts +13 -0
  624. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/cli-session.ts +4 -0
  625. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-child.ts +65 -0
  626. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-cli-qa.mjs +76 -0
  627. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-crash.ts +23 -0
  628. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-mutations.mjs +58 -0
  629. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-writer.ts +65 -0
  630. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/lease-clock.ts +23 -0
  631. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +9 -4
  632. package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +67 -0
  633. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  634. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  635. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-commit-log.test.ts +252 -0
  636. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-commit-recovery.test.ts +190 -0
  637. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io-cross-process.test.ts +106 -0
  638. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +74 -25
  639. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-log-legacy-projection.test.ts +228 -0
  640. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-log-newest.test.ts +72 -0
  641. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  642. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  643. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-fields-messages.test.ts +98 -0
  644. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-lazycodex-surface.test.ts +93 -0
  645. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  646. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +51 -2
  647. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
  648. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  649. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +58 -3
  650. package/packages/omo-codex/plugin/components/ulw-loop/test/review-blockers.test.ts +9 -7
  651. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-completed-plan.test.ts +43 -0
  652. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-contract.test.ts +137 -0
  653. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-driver-states.test.ts +174 -0
  654. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-dx.test.ts +219 -0
  655. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-session-context.test.ts +169 -0
  656. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +450 -7
  657. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-role-matrix.test.ts +113 -0
  658. package/packages/omo-codex/plugin/components/ulw-loop/test/state-lock.test.ts +310 -0
  659. package/packages/omo-codex/plugin/components/ulw-loop/test/status-next-actions-surface.test.ts +133 -0
  660. package/packages/omo-codex/plugin/components/ulw-loop/test/steering-batch.test.ts +12 -12
  661. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +12 -6
  662. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  663. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  664. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +13 -8
  665. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  666. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  667. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  668. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  669. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  670. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  671. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  672. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  673. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +18 -0
  674. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  675. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  676. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  677. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  678. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  679. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  680. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  681. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  682. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  683. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  684. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  685. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  686. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  687. package/packages/omo-codex/plugin/model-catalog.json +16 -7
  688. package/packages/omo-codex/plugin/package-lock.json +992 -681
  689. package/packages/omo-codex/plugin/package.json +6 -3
  690. package/packages/omo-codex/plugin/scripts/AGENTS.md +39 -0
  691. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -2
  692. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  693. package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
  694. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  695. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +16 -7
  696. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +8 -4
  697. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +19 -90
  698. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +1 -1
  699. package/packages/omo-codex/plugin/scripts/sync-skills.d.mts +4 -0
  700. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +111 -64
  701. package/packages/omo-codex/plugin/shared/package.json +3 -4
  702. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  703. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  704. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  705. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  706. package/packages/omo-codex/plugin/skills/ast-grep/SKILL.md +13 -1
  707. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  708. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +1 -1
  709. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  710. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  711. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  712. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  713. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  714. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  715. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  716. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  717. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +3 -1
  718. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  719. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +26 -5
  720. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  721. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  722. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  723. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  724. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  725. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  726. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  727. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  728. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  729. package/packages/omo-codex/plugin/skills/debugging/references/tools/playwright-cli.md +79 -161
  730. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +10 -0
  731. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +8 -3
  732. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +13 -4
  733. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  734. package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +145 -0
  735. package/packages/omo-codex/plugin/skills/frontend/references/design/aside.md +1 -1
  736. package/packages/omo-codex/plugin/skills/frontend/references/design/clone-from-url.md +1 -1
  737. package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +1 -0
  738. package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +2 -0
  739. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  740. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  741. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  742. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  743. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  744. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  745. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  746. package/packages/omo-codex/plugin/skills/frontend/references/perfection/README.md +1 -0
  747. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/lighthouse-audit.py +2 -2
  748. package/packages/omo-codex/plugin/skills/git-master/SKILL.md +1 -1
  749. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +20 -18
  750. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +4 -2
  751. package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +1 -1
  752. package/packages/omo-codex/plugin/skills/programming/SKILL.md +1 -1
  753. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +11 -9
  754. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +11 -9
  755. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +116 -424
  756. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +32 -86
  757. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +32 -27
  758. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +111 -0
  759. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +2 -2
  760. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +5 -2
  761. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +8 -6
  762. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +86 -0
  763. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +4 -7
  764. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +86 -95
  765. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +18 -5
  766. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/playwright.md +16 -13
  767. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/extract_cookies.py +3 -3
  768. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +44 -27
  769. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +35 -36
  770. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  771. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +31 -2
  772. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +33 -10
  773. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +4 -5
  774. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +5 -5
  775. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +2 -2
  776. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -0
  777. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +16 -9
  778. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  779. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +10 -7
  780. package/packages/omo-codex/plugin/skills/visual-qa/references/browser-setup.md +75 -0
  781. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  782. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  783. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +16 -51
  784. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -3
  785. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  786. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +14 -4
  787. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  788. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  789. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  790. package/packages/omo-codex/plugin/test/auto-update.test.mjs +4 -29
  791. package/packages/omo-codex/plugin/test/bootstrap-default-role.test.mjs +66 -0
  792. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  793. package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
  794. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  795. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -51
  796. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +100 -2
  797. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +5 -6
  798. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  799. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  800. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +35 -35
  801. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +1 -1
  802. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  803. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +107 -15
  804. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +168 -0
  805. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +54 -24
  806. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +18 -119
  807. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  808. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  809. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  810. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  811. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  812. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -5
  813. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  814. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  815. package/packages/omo-codex/scripts/check-model-catalog-parity.mjs +42 -0
  816. package/packages/omo-codex/scripts/install-cache-copy.test.mjs +27 -1
  817. package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +1 -1
  818. package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +2 -1
  819. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
  820. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +5 -5
  821. package/packages/omo-codex/scripts/install-config.test.mjs +15 -17
  822. package/packages/omo-codex/scripts/install-dist/install-local.mjs +16149 -4304
  823. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +3 -4
  824. package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
  825. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  826. package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
  827. package/packages/omo-codex/scripts/install-packaged-local.test.mjs +1 -6
  828. package/packages/{omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md → prompts-core/prompts/ultrawork/codex.md} +44 -34
  829. package/packages/shared-skills/package.json +7 -1
  830. package/packages/shared-skills/skill-source-filter.d.ts +16 -0
  831. package/packages/shared-skills/skill-source-filter.mjs +44 -0
  832. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  833. package/packages/shared-skills/skills/ast-grep/SKILL.md +13 -1
  834. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  835. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +1 -1
  836. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  837. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  838. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  839. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  840. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  841. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  842. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  843. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  844. package/packages/shared-skills/skills/debugging/SKILL.md +3 -1
  845. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  846. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +26 -5
  847. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  848. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  849. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  850. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  851. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  852. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  853. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  854. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  855. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  856. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  857. package/packages/shared-skills/skills/debugging/references/tools/playwright-cli.md +79 -161
  858. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -0
  859. package/packages/shared-skills/skills/frontend/SKILL.md +8 -3
  860. package/packages/shared-skills/skills/frontend/references/design/README.md +13 -4
  861. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  862. package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +145 -0
  863. package/packages/shared-skills/skills/frontend/references/design/aside.md +1 -1
  864. package/packages/shared-skills/skills/frontend/references/design/clone-from-url.md +1 -1
  865. package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +1 -0
  866. package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +2 -0
  867. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  868. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  869. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  870. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  871. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  872. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  873. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  874. package/packages/shared-skills/skills/frontend/references/perfection/README.md +1 -0
  875. package/packages/shared-skills/skills/frontend/scripts/perfection/lighthouse-audit.py +2 -2
  876. package/packages/shared-skills/skills/git-master/SKILL.md +1 -1
  877. package/packages/shared-skills/skills/init-deep/SKILL.md +14 -14
  878. package/packages/shared-skills/skills/lsp-setup/SKILL.md +1 -1
  879. package/packages/shared-skills/skills/programming/SKILL.md +1 -1
  880. package/packages/shared-skills/skills/refactor/SKILL.md +5 -5
  881. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +5 -5
  882. package/packages/shared-skills/skills/review-work/SKILL.md +101 -419
  883. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +32 -86
  884. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +32 -27
  885. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +111 -0
  886. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +2 -2
  887. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +5 -2
  888. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +8 -6
  889. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +86 -0
  890. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +4 -7
  891. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +86 -95
  892. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +18 -5
  893. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/playwright.md +16 -13
  894. package/packages/shared-skills/skills/ultimate-browsing/scripts/extract_cookies.py +3 -3
  895. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +24 -22
  896. package/packages/shared-skills/skills/ulw-plan/SKILL.md +5 -6
  897. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +6 -5
  898. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +2 -2
  899. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -1
  900. package/packages/shared-skills/skills/ulw-research/SKILL.md +10 -5
  901. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  902. package/packages/shared-skills/skills/visual-qa/SKILL.md +4 -3
  903. package/packages/shared-skills/skills/visual-qa/references/browser-setup.md +75 -0
  904. package/postinstall.mjs +2 -0
  905. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  906. package/script/qa/xterm-live-terminal.mjs +18 -2
  907. package/.agents/skills/work-with-pr-workspace/evals/evals.json +0 -76
  908. package/.agents/skills/work-with-pr-workspace/iteration-1/benchmark.json +0 -138
  909. package/.agents/skills/work-with-pr-workspace/iteration-1/benchmark.md +0 -42
  910. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/eval_metadata.json +0 -57
  911. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/grading.json +0 -15
  912. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/code-changes.md +0 -454
  913. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/execution-plan.md +0 -136
  914. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/pr-description.md +0 -47
  915. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/verification-strategy.md +0 -163
  916. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/timing.json +0 -1
  917. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/grading.json +0 -15
  918. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/code-changes.md +0 -615
  919. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/execution-plan.md +0 -99
  920. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/pr-description.md +0 -50
  921. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/verification-strategy.md +0 -111
  922. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/timing.json +0 -1
  923. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/eval_metadata.json +0 -37
  924. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/grading.json +0 -11
  925. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/code-changes.md +0 -205
  926. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/execution-plan.md +0 -78
  927. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/pr-description.md +0 -42
  928. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/verification-strategy.md +0 -87
  929. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/timing.json +0 -1
  930. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/grading.json +0 -11
  931. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/code-changes.md +0 -334
  932. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/execution-plan.md +0 -86
  933. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/pr-description.md +0 -23
  934. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/verification-strategy.md +0 -119
  935. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/timing.json +0 -1
  936. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/eval_metadata.json +0 -32
  937. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/grading.json +0 -10
  938. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/code-changes.md +0 -221
  939. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/execution-plan.md +0 -104
  940. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/pr-description.md +0 -41
  941. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/verification-strategy.md +0 -84
  942. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/timing.json +0 -1
  943. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/grading.json +0 -10
  944. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/code-changes.md +0 -342
  945. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/execution-plan.md +0 -131
  946. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/pr-description.md +0 -39
  947. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/verification-strategy.md +0 -128
  948. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/timing.json +0 -1
  949. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/eval_metadata.json +0 -32
  950. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/grading.json +0 -10
  951. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/code-changes.md +0 -143
  952. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/execution-plan.md +0 -82
  953. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/pr-description.md +0 -51
  954. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/verification-strategy.md +0 -69
  955. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/timing.json +0 -1
  956. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/grading.json +0 -10
  957. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/code-changes.md +0 -252
  958. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/execution-plan.md +0 -83
  959. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/pr-description.md +0 -33
  960. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/verification-strategy.md +0 -101
  961. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/timing.json +0 -1
  962. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/eval_metadata.json +0 -32
  963. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/grading.json +0 -10
  964. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/code-changes.md +0 -387
  965. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/execution-plan.md +0 -112
  966. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/pr-description.md +0 -51
  967. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/verification-strategy.md +0 -75
  968. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/timing.json +0 -1
  969. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/grading.json +0 -10
  970. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/code-changes.md +0 -529
  971. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/execution-plan.md +0 -127
  972. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/pr-description.md +0 -42
  973. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/verification-strategy.md +0 -120
  974. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/timing.json +0 -1
  975. package/.agents/skills/work-with-pr-workspace/iteration-1/review.html +0 -1326
  976. package/.opencode/skills/work-with-pr-workspace/evals/evals.json +0 -76
  977. package/.opencode/skills/work-with-pr-workspace/iteration-1/benchmark.json +0 -138
  978. package/.opencode/skills/work-with-pr-workspace/iteration-1/benchmark.md +0 -42
  979. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/eval_metadata.json +0 -57
  980. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/grading.json +0 -15
  981. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/code-changes.md +0 -454
  982. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/execution-plan.md +0 -136
  983. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/pr-description.md +0 -47
  984. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/verification-strategy.md +0 -163
  985. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/timing.json +0 -1
  986. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/grading.json +0 -15
  987. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/code-changes.md +0 -615
  988. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/execution-plan.md +0 -99
  989. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/pr-description.md +0 -50
  990. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/verification-strategy.md +0 -111
  991. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/timing.json +0 -1
  992. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/eval_metadata.json +0 -37
  993. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/grading.json +0 -11
  994. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/code-changes.md +0 -205
  995. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/execution-plan.md +0 -78
  996. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/pr-description.md +0 -42
  997. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/verification-strategy.md +0 -87
  998. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/timing.json +0 -1
  999. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/grading.json +0 -11
  1000. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/code-changes.md +0 -334
  1001. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/execution-plan.md +0 -86
  1002. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/pr-description.md +0 -23
  1003. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/verification-strategy.md +0 -119
  1004. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/timing.json +0 -1
  1005. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/eval_metadata.json +0 -32
  1006. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/grading.json +0 -10
  1007. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/code-changes.md +0 -221
  1008. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/execution-plan.md +0 -104
  1009. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/pr-description.md +0 -41
  1010. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/verification-strategy.md +0 -84
  1011. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/timing.json +0 -1
  1012. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/grading.json +0 -10
  1013. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/code-changes.md +0 -342
  1014. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/execution-plan.md +0 -131
  1015. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/pr-description.md +0 -39
  1016. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/verification-strategy.md +0 -128
  1017. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/timing.json +0 -1
  1018. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/eval_metadata.json +0 -32
  1019. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/grading.json +0 -10
  1020. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/code-changes.md +0 -143
  1021. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/execution-plan.md +0 -82
  1022. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/pr-description.md +0 -51
  1023. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/verification-strategy.md +0 -69
  1024. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/timing.json +0 -1
  1025. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/grading.json +0 -10
  1026. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/code-changes.md +0 -252
  1027. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/execution-plan.md +0 -83
  1028. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/pr-description.md +0 -33
  1029. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/verification-strategy.md +0 -101
  1030. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/timing.json +0 -1
  1031. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/eval_metadata.json +0 -32
  1032. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/grading.json +0 -10
  1033. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/code-changes.md +0 -387
  1034. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/execution-plan.md +0 -112
  1035. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/pr-description.md +0 -51
  1036. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/verification-strategy.md +0 -75
  1037. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/timing.json +0 -1
  1038. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/grading.json +0 -10
  1039. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/code-changes.md +0 -529
  1040. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/execution-plan.md +0 -127
  1041. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/pr-description.md +0 -42
  1042. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/verification-strategy.md +0 -120
  1043. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/timing.json +0 -1
  1044. package/.opencode/skills/work-with-pr-workspace/iteration-1/review.html +0 -1326
  1045. package/dist/config/schema/codegraph.d.ts +0 -12
  1046. package/dist/config/schema/start-work.d.ts +0 -5
  1047. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  1048. package/dist/features/builtin-skills/index.d.ts +0 -1
  1049. package/dist/features/builtin-skills/skill-file-loader.d.ts +0 -1
  1050. package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +0 -1
  1051. package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +0 -1
  1052. package/dist/features/builtin-skills/skills/debugging.d.ts +0 -1
  1053. package/dist/features/builtin-skills/skills/dev-browser.d.ts +0 -1
  1054. package/dist/features/builtin-skills/skills/frontend.d.ts +0 -1
  1055. package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +0 -1
  1056. package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +0 -1
  1057. package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +0 -1
  1058. package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +0 -1
  1059. package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +0 -1
  1060. package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +0 -1
  1061. package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +0 -1
  1062. package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +0 -1
  1063. package/dist/features/builtin-skills/skills/git-master-skill-metadata.d.ts +0 -1
  1064. package/dist/features/builtin-skills/skills/git-master.d.ts +0 -1
  1065. package/dist/features/builtin-skills/skills/index.d.ts +0 -1
  1066. package/dist/features/builtin-skills/skills/init-deep.d.ts +0 -1
  1067. package/dist/features/builtin-skills/skills/playwright-cli.d.ts +0 -1
  1068. package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +0 -1
  1069. package/dist/features/builtin-skills/skills/playwright.d.ts +0 -1
  1070. package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +0 -1
  1071. package/dist/features/builtin-skills/skills/review-work.d.ts +0 -1
  1072. package/dist/features/builtin-skills/skills/security-research.d.ts +0 -1
  1073. package/dist/features/builtin-skills/skills/security-review.d.ts +0 -1
  1074. package/dist/features/builtin-skills/skills/team-mode.d.ts +0 -1
  1075. package/dist/features/builtin-skills/skills/visual-qa.d.ts +0 -1
  1076. package/dist/features/builtin-skills/skills.d.ts +0 -1
  1077. package/dist/features/builtin-skills/types.d.ts +0 -1
  1078. package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +0 -1
  1079. package/dist/features/claude-code-plugin-loader/command-loader.d.ts +0 -1
  1080. package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +0 -1
  1081. package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +0 -1
  1082. package/dist/features/claude-code-plugin-loader/discovery.d.ts +0 -1
  1083. package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +0 -1
  1084. package/dist/features/claude-code-plugin-loader/index.d.ts +0 -1
  1085. package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +0 -1
  1086. package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +0 -1
  1087. package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +0 -1
  1088. package/dist/features/claude-code-plugin-loader/loader.d.ts +0 -1
  1089. package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +0 -1
  1090. package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +0 -1
  1091. package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +0 -1
  1092. package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +0 -1
  1093. package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +0 -1
  1094. package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +0 -1
  1095. package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +0 -1
  1096. package/dist/features/claude-code-plugin-loader/types.d.ts +0 -1
  1097. package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +0 -17
  1098. package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
  1099. package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
  1100. package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
  1101. package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
  1102. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
  1103. package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
  1104. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  1105. package/dist/mcp/codegraph.d.ts +0 -16
  1106. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  1107. package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +0 -1
  1108. package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +0 -1
  1109. package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +0 -1
  1110. package/dist/shared/prompt-async-gate/queue.d.ts +0 -1
  1111. package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +0 -1
  1112. package/dist/shared/prompt-async-gate/reservations.d.ts +0 -1
  1113. package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +0 -1
  1114. package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +0 -1
  1115. package/dist/shared/prompt-async-gate/timing.d.ts +0 -1
  1116. package/dist/shared/prompt-async-gate/types.d.ts +0 -1
  1117. package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
  1118. package/dist/skills/data-scientist/references/execution-templates.md +0 -197
  1119. package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
  1120. package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
  1121. package/dist/skills/visual-qa/references/agent-browser-setup.md +0 -45
  1122. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  1123. package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
  1124. package/dist/tools/delegate-task/anthropic-categories.d.ts +0 -2
  1125. package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
  1126. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  1127. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  1128. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  1129. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  1130. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  1131. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  1132. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  1133. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  1134. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12244
  1135. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9842
  1136. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  1137. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  1138. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  1139. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  1140. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  1141. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  1142. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  1143. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -309
  1144. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -80
  1145. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  1146. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  1147. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  1148. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  1149. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  1150. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -21
  1151. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  1152. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  1153. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  1154. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  1155. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  1156. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  1157. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  1158. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  1159. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  1160. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  1161. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  1162. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  1163. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  1164. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  1165. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  1166. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  1167. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  1168. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  1169. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  1170. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  1171. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  1172. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  1173. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  1174. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  1175. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  1176. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  1177. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  1178. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  1179. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  1180. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  1181. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  1182. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  1183. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  1184. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  1185. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  1186. package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +0 -21
  1187. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  1188. package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -477
  1189. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  1190. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  1191. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  1192. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  1193. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  1194. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  1195. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  1196. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  1197. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  1198. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  1199. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  1200. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  1201. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  1202. package/packages/omo-codex/plugin/skills/visual-qa/references/agent-browser-setup.md +0 -45
  1203. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  1204. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  1205. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
  1206. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  1207. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  1208. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  1209. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  1210. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  1211. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  1212. package/packages/shared-skills/skills/visual-qa/references/agent-browser-setup.md +0 -45
  1213. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  1214. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  1215. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  1216. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  1217. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  1218. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  1219. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  1220. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  1221. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  1222. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  1223. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  1224. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  1225. /package/packages/omo-codex/plugin/components/{codegraph → ulw-execute-continuation}/LICENSE +0 -0
  1226. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  1227. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  1228. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  1229. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  1230. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  1231. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  1232. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  1233. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  1234. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  1235. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  1236. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -3,14 +3,450 @@
3
3
  // src/cli.ts
4
4
  import { argv, stderr } from "node:process";
5
5
 
6
- // src/proxy.ts
7
- import { existsSync as existsSync12, realpathSync as realpathSync5 } from "node:fs";
8
- import { basename as basename4, delimiter as delimiter4, dirname as dirname9, isAbsolute as isAbsolute5 } from "node:path";
6
+ // src/ownership.ts
7
+ import { randomUUID } from "node:crypto";
8
+ import { existsSync, lstatSync as lstatSync2, readFileSync as readFileSync3, statSync, unlinkSync as unlinkSync3 } from "node:fs";
9
+ import { dirname as dirname3 } from "node:path";
10
+
11
+ // src/lock.ts
12
+ import { closeSync, mkdirSync, openSync, readFileSync, unlinkSync, writeSync } from "node:fs";
13
+ import { dirname } from "node:path";
14
+ function isProcessAlive(pid) {
15
+ if (!Number.isInteger(pid) || pid <= 0)
16
+ return false;
17
+ try {
18
+ process.kill(pid, 0);
19
+ return true;
20
+ } catch (error) {
21
+ if (error instanceof Error)
22
+ return errorCode(error) === "EPERM";
23
+ throw error;
24
+ }
25
+ }
26
+ function readLockPid(lockPath) {
27
+ try {
28
+ const pid = Number.parseInt(readFileSync(lockPath, "utf8").trim(), 10);
29
+ return Number.isInteger(pid) ? pid : null;
30
+ } catch {
31
+ return null;
32
+ }
33
+ }
34
+ function tryAcquireLock(lockPath, ownerPid = process.pid) {
35
+ mkdirSync(dirname(lockPath), { recursive: true });
36
+ for (let attempt = 0;attempt < 2; attempt += 1) {
37
+ const handle = writeLockFile(lockPath, ownerPid);
38
+ if (handle)
39
+ return handle;
40
+ if (!reapStaleLock(lockPath))
41
+ return null;
42
+ }
43
+ return null;
44
+ }
45
+ function writeLockFile(lockPath, ownerPid) {
46
+ try {
47
+ const fd = openSync(lockPath, "wx", 384);
48
+ writeSync(fd, `${ownerPid}
49
+ `);
50
+ closeSync(fd);
51
+ return { release: () => unlinkQuietly(lockPath) };
52
+ } catch (error) {
53
+ if (errorCode(error) === "EEXIST")
54
+ return null;
55
+ throw error;
56
+ }
57
+ }
58
+ function reapStaleLock(lockPath) {
59
+ const pid = readLockPid(lockPath);
60
+ if (pid !== null && isProcessAlive(pid))
61
+ return false;
62
+ unlinkQuietly(lockPath);
63
+ return true;
64
+ }
65
+ function unlinkQuietly(path) {
66
+ try {
67
+ unlinkSync(path);
68
+ } catch (error) {
69
+ if (error instanceof Error)
70
+ return;
71
+ throw error;
72
+ }
73
+ }
74
+ function errorCode(error) {
75
+ if (!error || typeof error !== "object" || !("code" in error))
76
+ return;
77
+ const code = Reflect.get(error, "code");
78
+ return typeof code === "string" ? code : undefined;
79
+ }
80
+
81
+ // src/ipc-protocol.ts
82
+ import { randomBytes, timingSafeEqual } from "node:crypto";
83
+ import {
84
+ chmodSync,
85
+ closeSync as closeSync2,
86
+ constants,
87
+ fchmodSync,
88
+ fstatSync,
89
+ lstatSync,
90
+ mkdirSync as mkdirSync2,
91
+ openSync as openSync2,
92
+ readFileSync as readFileSync2,
93
+ unlinkSync as unlinkSync2,
94
+ writeSync as writeSync2
95
+ } from "node:fs";
96
+ import { dirname as dirname2 } from "node:path";
9
97
 
10
98
  // ../mcp-stdio-core/src/record.ts
11
99
  function isPlainRecord(value) {
12
100
  return typeof value === "object" && value !== null && !Array.isArray(value);
13
101
  }
102
+
103
+ // src/ipc-protocol.ts
104
+ var OMO_DAEMON_PROTOCOL_VERSION = 1;
105
+ var AUTH_ERROR_CODE = -32001;
106
+ var PROTOCOL_ERROR_CODE = -32002;
107
+ var AUTH_TOKEN_BYTES = 32;
108
+
109
+ class UnsafePrivateDirectoryError extends Error {
110
+ constructor(path, reason) {
111
+ super(`unsafe private directory ${path}: ${reason}`);
112
+ this.path = path;
113
+ this.reason = reason;
114
+ this.name = "UnsafePrivateDirectoryError";
115
+ this.code = "unsafe_private_directory";
116
+ }
117
+ }
118
+ function authEnvelope(token) {
119
+ return { protocolVersion: OMO_DAEMON_PROTOCOL_VERSION, token };
120
+ }
121
+ function readAuthToken(paths) {
122
+ try {
123
+ const token = readFileSync2(paths.auth, "utf8").trim();
124
+ return token.length > 0 ? token : null;
125
+ } catch (error) {
126
+ if (error instanceof Error)
127
+ return null;
128
+ throw error;
129
+ }
130
+ }
131
+ function readOrCreateAuthToken(paths) {
132
+ const existing = readAuthToken(paths);
133
+ if (existing)
134
+ return existing;
135
+ return createAuthToken(paths);
136
+ }
137
+ function rotateAuthToken(paths) {
138
+ try {
139
+ unlinkSync2(paths.auth);
140
+ } catch (error) {
141
+ if (!(error instanceof Error))
142
+ throw error;
143
+ }
144
+ return createAuthToken(paths);
145
+ }
146
+ function authenticateMessage(raw, expectedToken) {
147
+ const id = jsonRpcId(raw);
148
+ if (!isPlainRecord(raw))
149
+ return authError(id);
150
+ const params = raw["params"];
151
+ if (!isPlainRecord(params))
152
+ return authError(id);
153
+ const envelope = params["_omo"];
154
+ if (!isPlainRecord(envelope))
155
+ return authError(id);
156
+ const protocolVersion = envelope["protocolVersion"];
157
+ if (protocolVersion !== OMO_DAEMON_PROTOCOL_VERSION)
158
+ return protocolError(id);
159
+ const token = envelope["token"];
160
+ if (typeof token !== "string" || !tokenMatches(token, expectedToken))
161
+ return authError(id);
162
+ const cleanParams = { ...params };
163
+ delete cleanParams["_omo"];
164
+ return { input: { ...raw, params: cleanParams }, id, method: typeof raw["method"] === "string" ? raw["method"] : undefined };
165
+ }
166
+ function isAuthErrorResponse(message) {
167
+ if (!isPlainRecord(message))
168
+ return false;
169
+ const error = message["error"];
170
+ if (!isPlainRecord(error))
171
+ return false;
172
+ const data = error["data"];
173
+ return error["code"] === AUTH_ERROR_CODE && isPlainRecord(data) && data["code"] === "daemon_authentication_failed";
174
+ }
175
+ function writePrivateFile(path, data) {
176
+ const fd = openSync2(path, "w", 384);
177
+ try {
178
+ writeSync2(fd, data);
179
+ } finally {
180
+ closeSync2(fd);
181
+ }
182
+ setPrivateFileMode(path);
183
+ }
184
+ function ensurePrivateDirectory(path, options = {}) {
185
+ try {
186
+ mkdirSync2(path, { recursive: true, mode: 448 });
187
+ } catch (error) {
188
+ if (errorCode2(error) !== "EEXIST")
189
+ throw error;
190
+ }
191
+ if (process.platform === "win32")
192
+ return;
193
+ const before = validatePrivateDirectory(path, options);
194
+ const fd = openSync2(path, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
195
+ try {
196
+ fchmodSync(fd, 448);
197
+ const after = validatePrivateDirectory(path, options);
198
+ const openStats = fstatSync(fd);
199
+ if (!sameDirectory(before, after) || !sameDirectory(before, openStats)) {
200
+ throw new UnsafePrivateDirectoryError(path, "changed_during_chmod");
201
+ }
202
+ } finally {
203
+ closeSync2(fd);
204
+ }
205
+ }
206
+ function setPrivateFileMode(path) {
207
+ if (process.platform !== "win32")
208
+ chmodSync(path, 384);
209
+ }
210
+ function createAuthToken(paths) {
211
+ ensurePrivateDirectory(dirname2(paths.auth));
212
+ const token = randomBytes(AUTH_TOKEN_BYTES).toString("base64url");
213
+ let fd;
214
+ try {
215
+ fd = openSync2(paths.auth, "wx", 384);
216
+ } catch (error) {
217
+ if (errorCode2(error) === "EEXIST") {
218
+ const existing = readAuthToken(paths);
219
+ if (existing)
220
+ return existing;
221
+ }
222
+ throw error;
223
+ }
224
+ try {
225
+ writeSync2(fd, `${token}
226
+ `);
227
+ } finally {
228
+ closeSync2(fd);
229
+ }
230
+ setPrivateFileMode(paths.auth);
231
+ return token;
232
+ }
233
+ function errorCode2(error) {
234
+ if (!error || typeof error !== "object" || !("code" in error))
235
+ return;
236
+ const code = Reflect.get(error, "code");
237
+ return typeof code === "string" ? code : undefined;
238
+ }
239
+ function validatePrivateDirectory(path, options) {
240
+ const stats = options.lstat ? options.lstat(path) : lstatPrivateDirectory(path);
241
+ if (stats.isSymbolicLink())
242
+ throw new UnsafePrivateDirectoryError(path, "symlink");
243
+ if (!stats.isDirectory())
244
+ throw new UnsafePrivateDirectoryError(path, "not_directory");
245
+ const currentUid = options.currentUid ? options.currentUid() : process.getuid?.();
246
+ if (currentUid !== undefined && stats.uid !== currentUid) {
247
+ throw new UnsafePrivateDirectoryError(path, "wrong_owner");
248
+ }
249
+ return stats;
250
+ }
251
+ function lstatPrivateDirectory(path) {
252
+ return lstatSync(path);
253
+ }
254
+ function sameDirectory(a, b) {
255
+ return a.dev === b.dev && a.ino === b.ino;
256
+ }
257
+ function tokenMatches(candidate, expected) {
258
+ const candidateBytes = Buffer.from(candidate);
259
+ const expectedBytes = Buffer.from(expected);
260
+ return candidateBytes.length === expectedBytes.length && timingSafeEqual(candidateBytes, expectedBytes);
261
+ }
262
+ function jsonRpcId(raw) {
263
+ if (!isPlainRecord(raw))
264
+ return null;
265
+ const id = raw["id"];
266
+ return typeof id === "string" || typeof id === "number" || id === null ? id : null;
267
+ }
268
+ function authError(id) {
269
+ return {
270
+ jsonrpc: "2.0",
271
+ id,
272
+ error: { code: AUTH_ERROR_CODE, message: "daemon authentication failed", data: { code: "daemon_authentication_failed" } }
273
+ };
274
+ }
275
+ function protocolError(id) {
276
+ return {
277
+ jsonrpc: "2.0",
278
+ id,
279
+ error: { code: PROTOCOL_ERROR_CODE, message: "daemon protocol mismatch", data: { code: "daemon_protocol_mismatch" } }
280
+ };
281
+ }
282
+
283
+ // src/ownership.ts
284
+ class DaemonAlreadyRunningError extends Error {
285
+ constructor() {
286
+ super(...arguments);
287
+ this.name = "DaemonAlreadyRunningError";
288
+ this.code = "daemon_already_running";
289
+ }
290
+ }
291
+
292
+ class DaemonStartupDeferredError extends Error {
293
+ constructor(reason) {
294
+ super(`LSP daemon startup deferred: ${reason}`);
295
+ this.reason = reason;
296
+ this.name = "DaemonStartupDeferredError";
297
+ this.code = "daemon_startup_deferred";
298
+ }
299
+ }
300
+ async function acquireStartupLease(paths, pingOwner) {
301
+ ensureDaemonDirectories(paths);
302
+ const lock = tryAcquireLock(paths.lock);
303
+ if (!lock) {
304
+ const token = readAuthToken(paths);
305
+ if (token && await pingOwner(token))
306
+ throw new DaemonAlreadyRunningError("LSP daemon already running");
307
+ throw new DaemonStartupDeferredError("startup_lock_busy");
308
+ }
309
+ try {
310
+ const token = await validateExistingOwner(paths, pingOwner);
311
+ return { lock, token, owner: newOwner(paths) };
312
+ } catch (error) {
313
+ lock.release();
314
+ throw error;
315
+ }
316
+ }
317
+ function ensureDaemonDirectories(paths) {
318
+ ensurePrivateDirectory(paths.dir);
319
+ if (process.platform !== "win32")
320
+ ensurePrivateDirectory(dirname3(paths.socket));
321
+ }
322
+ function readDaemonOwner(paths) {
323
+ try {
324
+ return parseOwner(JSON.parse(readFileSync3(paths.owner, "utf8")));
325
+ } catch (error) {
326
+ if (error instanceof Error)
327
+ return null;
328
+ throw error;
329
+ }
330
+ }
331
+ function writeDaemonOwner(paths, owner) {
332
+ writePrivateFile(paths.pid, `${owner.pid}
333
+ `);
334
+ writePrivateFile(paths.endpoint, owner.endpoint.path);
335
+ writePrivateFile(paths.owner, `${JSON.stringify(owner)}
336
+ `);
337
+ }
338
+ function removeDaemonMetadataForOwner(paths, owner) {
339
+ const current = readDaemonOwner(paths);
340
+ if (!current || !sameOwner(current, owner))
341
+ return;
342
+ unlinkQuietly(paths.socket);
343
+ unlinkQuietly(paths.pid);
344
+ unlinkQuietly(paths.endpoint);
345
+ unlinkQuietly(paths.owner);
346
+ }
347
+ function endpointIdentity(endpointPath) {
348
+ if (process.platform === "win32")
349
+ return { kind: "windows", path: endpointPath };
350
+ try {
351
+ const stats = statSync(endpointPath);
352
+ return { kind: "unix", path: endpointPath, dev: stats.dev, ino: stats.ino };
353
+ } catch (error) {
354
+ if (error instanceof Error)
355
+ return { kind: "missing", path: endpointPath };
356
+ throw error;
357
+ }
358
+ }
359
+ function sameEndpoint(a, b) {
360
+ if (a.kind !== b.kind || a.path !== b.path)
361
+ return false;
362
+ switch (a.kind) {
363
+ case "unix":
364
+ return b.kind === "unix" && a.dev === b.dev && a.ino === b.ino;
365
+ case "windows":
366
+ return true;
367
+ case "missing":
368
+ return true;
369
+ }
370
+ }
371
+ function sameOwner(a, b) {
372
+ return a.pid === b.pid && a.nonce === b.nonce && sameEndpoint(a.endpoint, b.endpoint);
373
+ }
374
+ async function validateExistingOwner(paths, pingOwner) {
375
+ let token = readOrCreateAuthToken(paths);
376
+ for (let attempt = 0;attempt < 2; attempt += 1) {
377
+ const owner = readDaemonOwner(paths);
378
+ if (!owner)
379
+ return token;
380
+ const ping = await pingOwner(token);
381
+ if (ping && owner.nonce === ping.nonce && sameEndpoint(owner.endpoint, ping.endpoint)) {
382
+ throw new DaemonAlreadyRunningError("LSP daemon already running");
383
+ }
384
+ if (ping)
385
+ continue;
386
+ if (isProcessAlive(owner.pid))
387
+ throw new DaemonStartupDeferredError("owner_pid_live_unreachable");
388
+ const reread = readDaemonOwner(paths);
389
+ if (!reread || !sameOwner(reread, owner)) {
390
+ throw new DaemonStartupDeferredError("owner_changed_during_cleanup");
391
+ }
392
+ cleanupDeadOwner(paths, owner);
393
+ token = rotateAuthToken(paths);
394
+ return token;
395
+ }
396
+ throw new DaemonStartupDeferredError("reachable_owner_mismatch");
397
+ }
398
+ function cleanupDeadOwner(paths, owner) {
399
+ if (process.platform !== "win32" && existsSync(owner.endpoint.path)) {
400
+ const stat = lstatSync2(owner.endpoint.path);
401
+ if (stat.isSocket())
402
+ unlinkSync3(owner.endpoint.path);
403
+ }
404
+ unlinkQuietly(paths.pid);
405
+ unlinkQuietly(paths.endpoint);
406
+ unlinkQuietly(paths.owner);
407
+ }
408
+ function newOwner(paths) {
409
+ return {
410
+ pid: process.pid,
411
+ nonce: randomUUID(),
412
+ startedAt: new Date().toISOString(),
413
+ endpoint: endpointIdentity(paths.socket)
414
+ };
415
+ }
416
+ function parseOwner(value) {
417
+ if (!value || typeof value !== "object" || Array.isArray(value))
418
+ return null;
419
+ const pid = Reflect.get(value, "pid");
420
+ const nonce = Reflect.get(value, "nonce");
421
+ const startedAt = Reflect.get(value, "startedAt");
422
+ const endpoint = parseEndpoint(Reflect.get(value, "endpoint"));
423
+ if (typeof pid !== "number" || typeof nonce !== "string" || typeof startedAt !== "string" || !endpoint)
424
+ return null;
425
+ return { pid, nonce, startedAt, endpoint };
426
+ }
427
+ function parseEndpoint(value) {
428
+ if (!value || typeof value !== "object" || Array.isArray(value))
429
+ return null;
430
+ const kind = Reflect.get(value, "kind");
431
+ const path = Reflect.get(value, "path");
432
+ if (typeof path !== "string")
433
+ return null;
434
+ if (kind === undefined)
435
+ return endpointIdentity(path);
436
+ if (kind === "windows")
437
+ return { kind, path };
438
+ if (kind === "missing")
439
+ return { kind, path };
440
+ const dev = Reflect.get(value, "dev");
441
+ const ino = Reflect.get(value, "ino");
442
+ if (kind === "unix" && typeof dev === "number" && typeof ino === "number")
443
+ return { kind, path, dev, ino };
444
+ return null;
445
+ }
446
+
447
+ // src/proxy.ts
448
+ import { existsSync as existsSync14, realpathSync as realpathSync6 } from "node:fs";
449
+ import { basename as basename4, delimiter as delimiter4, dirname as dirname13, isAbsolute as isAbsolute6 } from "node:path";
14
450
  // ../mcp-stdio-core/src/responses.ts
15
451
  function successResponse(id, result) {
16
452
  return { jsonrpc: "2.0", id, result };
@@ -18,7 +454,7 @@ function successResponse(id, result) {
18
454
  function errorResponse(id, code, message, data) {
19
455
  return { jsonrpc: "2.0", id, error: data === undefined ? { code, message } : { code, message, data } };
20
456
  }
21
- function jsonRpcId(value) {
457
+ function jsonRpcId2(value) {
22
458
  return typeof value === "string" || typeof value === "number" || value === null ? value : null;
23
459
  }
24
460
  function messageFromError(error) {
@@ -169,7 +605,7 @@ function bufferFromChunk(chunk) {
169
605
  var DEFAULT_IDLE_TIMEOUT_MS = 10 * 60000;
170
606
  var DEFAULT_PARENT_POLL_INTERVAL_MS = 30000;
171
607
  var noopLog = () => {};
172
- function isProcessAlive(pid) {
608
+ function isProcessAlive2(pid) {
173
609
  try {
174
610
  process.kill(pid, 0);
175
611
  return true;
@@ -184,6 +620,7 @@ async function runJsonRpcStdioServer(config) {
184
620
  const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
185
621
  isClosed = true;
186
622
  config.onIdleTimeout?.();
623
+ config.input.destroy();
187
624
  });
188
625
  const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
189
626
  isClosed = true;
@@ -228,7 +665,7 @@ async function handleParseError(message, config, log) {
228
665
  }
229
666
  async function handleRequest(message, config, log) {
230
667
  const parsed = message.payload;
231
- const id = isPlainRecord(parsed) ? jsonRpcId(parsed["id"]) : null;
668
+ const id = isPlainRecord(parsed) ? jsonRpcId2(parsed["id"]) : null;
232
669
  const method = isPlainRecord(parsed) && typeof parsed["method"] === "string" ? parsed["method"] : null;
233
670
  log("request", { id: id === null ? null : String(id), method });
234
671
  let response;
@@ -277,10 +714,14 @@ function createParentWatchdog(config, onDeadParent) {
277
714
  if (pollIntervalMs <= 0)
278
715
  return { clear: () => {} };
279
716
  const parentPid = config.parentPid ?? process.ppid;
280
- const probeAlive = config.probeAlive ?? isProcessAlive;
717
+ const probeAlive = config.probeAlive ?? isProcessAlive2;
281
718
  let fired = false;
282
719
  const timer = setInterval(() => {
283
- if (fired || probeAlive(parentPid))
720
+ if (fired)
721
+ return;
722
+ const alive = probeAlive(parentPid);
723
+ config.onPoll?.(alive);
724
+ if (alive)
284
725
  return;
285
726
  fired = true;
286
727
  onDeadParent(parentPid, pollIntervalMs);
@@ -315,28 +756,27 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
315
756
  };
316
757
  }
317
758
  // ../lsp-core/src/lsp/client-wrapper.ts
318
- import { existsSync as existsSync9, realpathSync as realpathSync4, statSync as statSync3 } from "node:fs";
319
- import { basename as basename3, dirname as dirname6, join as join4, resolve as resolve7 } from "node:path";
759
+ import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync4 } from "node:fs";
760
+ import { basename as basename3, dirname as dirname11, join as join5, resolve as resolve8 } from "node:path";
320
761
 
321
762
  // ../lsp-core/src/request-context.ts
322
763
  import { AsyncLocalStorage } from "node:async_hooks";
323
- import { existsSync, realpathSync, statSync } from "node:fs";
764
+ import { existsSync as existsSync2, realpathSync, statSync as statSync2 } from "node:fs";
324
765
  import { homedir } from "node:os";
325
- import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
766
+ import { basename, delimiter, dirname as dirname4, isAbsolute, join, relative, resolve } from "node:path";
326
767
 
327
768
  class LspRequestContextParseError extends Error {
328
- code;
329
- name = "LspRequestContextParseError";
330
769
  constructor(code, message) {
331
770
  super(message);
332
771
  this.code = code;
772
+ this.name = "LspRequestContextParseError";
333
773
  }
334
774
  }
335
775
 
336
776
  class LspRequestContextUnavailableError extends Error {
337
- name = "LspRequestContextUnavailableError";
338
777
  constructor() {
339
778
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
779
+ this.name = "LspRequestContextUnavailableError";
340
780
  }
341
781
  }
342
782
  var storage = new AsyncLocalStorage;
@@ -356,7 +796,7 @@ function contextCwd() {
356
796
  }
357
797
  function createStandaloneMcpRequestContext(input = {}) {
358
798
  const env = input.env ?? process.env;
359
- const cwd = canonicalCwd(input.cwd ?? process.cwd());
799
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
360
800
  const home = input.homeDir ?? homedir();
361
801
  const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
362
802
  const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
@@ -409,7 +849,7 @@ function translateHomeConfigEnv(value, home, fallback) {
409
849
  }
410
850
  function canonicalCwd(cwd) {
411
851
  const resolved = resolve(cwd);
412
- if (!existsSync(resolved) || !statSync(resolved).isDirectory()) {
852
+ if (!existsSync2(resolved) || !statSync2(resolved).isDirectory()) {
413
853
  throw new LspRequestContextParseError("invalid_cwd", `LSP request cwd must be an existing directory: ${cwd}`);
414
854
  }
415
855
  return realpathSync(resolved);
@@ -424,7 +864,7 @@ function canonicalizeExistingOrNearestAncestor(path) {
424
864
  } catch (error) {
425
865
  if (!isMissingPathError(error))
426
866
  throw error;
427
- const parent = dirname(current);
867
+ const parent = dirname4(current);
428
868
  if (parent === current)
429
869
  throw error;
430
870
  suffix.unshift(basename(current));
@@ -468,7 +908,7 @@ function isPathInside(parent, child) {
468
908
  return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute(relativePath);
469
909
  }
470
910
  function isMissingPathError(error) {
471
- const code = errorCode(error);
911
+ const code = errorCode3(error);
472
912
  return code === "ENOENT" || code === "ENOTDIR";
473
913
  }
474
914
  function rejectUnknownFields(value, allowed, scope) {
@@ -480,7 +920,7 @@ function rejectUnknownFields(value, allowed, scope) {
480
920
  function isRecord(value) {
481
921
  return typeof value === "object" && value !== null && !Array.isArray(value);
482
922
  }
483
- function errorCode(error) {
923
+ function errorCode3(error) {
484
924
  if (!error || typeof error !== "object" || !("code" in error))
485
925
  return;
486
926
  const code = Reflect.get(error, "code");
@@ -499,22 +939,15 @@ function effectiveExtension(filePath) {
499
939
 
500
940
  // ../lsp-core/src/lsp/errors.ts
501
941
  class LspConnectionClosedError extends Error {
502
- serverId;
503
- root;
504
- name = "LspConnectionClosedError";
505
942
  constructor(serverId, root, message) {
506
943
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
507
944
  this.serverId = serverId;
508
945
  this.root = root;
946
+ this.name = "LspConnectionClosedError";
509
947
  }
510
948
  }
511
949
 
512
950
  class LspProcessExitedError extends Error {
513
- serverId;
514
- root;
515
- exitCode;
516
- stderrTail;
517
- name = "LspProcessExitedError";
518
951
  constructor(serverId, root, exitCode, stderrTail) {
519
952
  const stderrSuffix = stderrTail ? `
520
953
  stderr tail: ${stderrTail}` : "";
@@ -523,46 +956,59 @@ stderr tail: ${stderrTail}` : "";
523
956
  this.root = root;
524
957
  this.exitCode = exitCode;
525
958
  this.stderrTail = stderrTail;
959
+ this.name = "LspProcessExitedError";
526
960
  }
527
961
  }
528
962
 
529
963
  class LspRequestTimeoutError extends Error {
530
- method;
531
- stderrTail;
532
- name = "LspRequestTimeoutError";
533
964
  constructor(method, stderrTail) {
534
965
  const stderrSuffix = stderrTail ? `
535
966
  recent stderr: ${stderrTail}` : "";
536
967
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
537
968
  this.method = method;
538
969
  this.stderrTail = stderrTail;
970
+ this.name = "LspRequestTimeoutError";
539
971
  }
540
972
  }
541
973
 
542
974
  class LspInvalidPathError extends Error {
543
- name = "LspInvalidPathError";
975
+ constructor() {
976
+ super(...arguments);
977
+ this.name = "LspInvalidPathError";
978
+ }
544
979
  }
545
980
 
546
981
  class LspServerLookupError extends Error {
547
- lookup;
548
- name = "LspServerLookupError";
549
982
  constructor(message, lookup) {
550
983
  super(message);
551
984
  this.lookup = lookup;
985
+ this.name = "LspServerLookupError";
552
986
  }
553
987
  }
554
988
 
555
989
  class LspServerInitializingError extends Error {
556
- originalError;
557
- name = "LspServerInitializingError";
558
990
  constructor(originalError) {
559
991
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
560
992
  this.originalError = originalError;
993
+ this.name = "LspServerInitializingError";
561
994
  }
562
995
  }
563
996
 
564
997
  class LspProcessSpawnError extends Error {
565
- name = "LspProcessSpawnError";
998
+ constructor() {
999
+ super(...arguments);
1000
+ this.name = "LspProcessSpawnError";
1001
+ }
1002
+ }
1003
+
1004
+ class LspClientRespawnBudgetExceededError extends Error {
1005
+ constructor(serverId, root, retryLimit) {
1006
+ super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
1007
+ this.serverId = serverId;
1008
+ this.root = root;
1009
+ this.retryLimit = retryLimit;
1010
+ this.name = "LspClientRespawnBudgetExceededError";
1011
+ }
566
1012
  }
567
1013
  function isLspDeadConnectionError(err) {
568
1014
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -585,6 +1031,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
585
1031
  // ../lsp-core/src/lsp/connection.ts
586
1032
  import { pathToFileURL } from "node:url";
587
1033
 
1034
+ // ../lsp-core/src/lsp/timer-provider.ts
1035
+ var realTimerProvider = {
1036
+ now: () => Date.now(),
1037
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1038
+ clearTimeout: (handle) => clearTimeout(handle)
1039
+ };
1040
+
588
1041
  // ../lsp-core/src/lsp/constants.ts
589
1042
  var DEFAULT_MAX_REFERENCES = 200;
590
1043
  var DEFAULT_MAX_SYMBOLS = 200;
@@ -593,9 +1046,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
593
1046
  var REQUEST_TIMEOUT_MS = 15000;
594
1047
  var INIT_TIMEOUT_MS = 60000;
595
1048
  var IDLE_TIMEOUT_MS = 5 * 60000;
1049
+ var MAX_RESIDENT_CLIENTS = 6;
596
1050
  var REAPER_INTERVAL_MS = 60000;
597
1051
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
598
1052
  var STOP_SIGKILL_GRACE_MS = 1000;
1053
+ var CLIENT_RESPAWN_RETRY_LIMIT = 2;
1054
+ var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
599
1055
 
600
1056
  // ../lsp-core/src/lsp/json-rpc-connection.ts
601
1057
  var HEADER_SEPARATOR2 = `\r
@@ -607,20 +1063,31 @@ var METHOD_NOT_FOUND = -32601;
607
1063
  var INTERNAL_ERROR = -32603;
608
1064
 
609
1065
  class JsonRpcConnection {
610
- reader;
611
- writer;
612
- pendingRequests = new Map;
613
- notificationHandlers = new Map;
614
- requestHandlers = new Map;
615
- closeHandlers = [];
616
- errorHandlers = [];
617
- inputBuffer = Buffer.alloc(0);
618
- nextRequestId = 1;
619
- listening = false;
620
- disposed = false;
621
1066
  constructor(reader, writer) {
622
1067
  this.reader = reader;
623
1068
  this.writer = writer;
1069
+ this.pendingRequests = new Map;
1070
+ this.notificationHandlers = new Map;
1071
+ this.requestHandlers = new Map;
1072
+ this.closeHandlers = [];
1073
+ this.errorHandlers = [];
1074
+ this.inputBuffer = Buffer.alloc(0);
1075
+ this.nextRequestId = 1;
1076
+ this.listening = false;
1077
+ this.disposed = false;
1078
+ this.handleData = (chunk) => {
1079
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
1080
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
1081
+ this.drainInputBuffer();
1082
+ };
1083
+ this.handleClose = () => {
1084
+ for (const handler of this.closeHandlers) {
1085
+ handler();
1086
+ }
1087
+ };
1088
+ this.handleStreamError = (error) => {
1089
+ this.emitError(error);
1090
+ };
624
1091
  }
625
1092
  listen() {
626
1093
  if (this.listening)
@@ -655,7 +1122,8 @@ class JsonRpcConnection {
655
1122
  let cancelAfterWrite = false;
656
1123
  let settled = false;
657
1124
  const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
658
- const responsePromise = new Promise((resolve2, reject) => {
1125
+ let rejectAfterCancelWrite;
1126
+ const responsePromise = new Promise((resolve, reject) => {
659
1127
  const cleanup = () => {
660
1128
  options.signal?.removeEventListener("abort", onAbort);
661
1129
  };
@@ -666,22 +1134,26 @@ class JsonRpcConnection {
666
1134
  this.pendingRequests.delete(key);
667
1135
  cleanup();
668
1136
  const rejectCancelled = () => reject(abortError(options.signal));
1137
+ rejectAfterCancelWrite = async () => {
1138
+ try {
1139
+ await writeCancel();
1140
+ } catch (error) {
1141
+ this.emitError(toError(error));
1142
+ }
1143
+ rejectCancelled();
1144
+ };
669
1145
  if (!requestWritten) {
670
1146
  cancelAfterWrite = true;
671
- rejectCancelled();
672
1147
  return;
673
1148
  }
674
- writeCancel().then(rejectCancelled, (error) => {
675
- this.emitError(toError(error));
676
- rejectCancelled();
677
- });
1149
+ rejectAfterCancelWrite();
678
1150
  };
679
1151
  const onAbort = () => settleCancel();
680
1152
  this.pendingRequests.set(key, {
681
1153
  resolve(result) {
682
1154
  settled = true;
683
1155
  cleanup();
684
- resolve2(result);
1156
+ resolve(result);
685
1157
  },
686
1158
  reject(error) {
687
1159
  settled = true;
@@ -702,7 +1174,7 @@ class JsonRpcConnection {
702
1174
  await this.writeMessage(message);
703
1175
  requestWritten = true;
704
1176
  if (cancelAfterWrite)
705
- await writeCancel();
1177
+ await rejectAfterCancelWrite?.();
706
1178
  } catch (error) {
707
1179
  if (settled)
708
1180
  return responsePromise;
@@ -741,19 +1213,6 @@ class JsonRpcConnection {
741
1213
  this.notificationHandlers.clear();
742
1214
  this.requestHandlers.clear();
743
1215
  }
744
- handleData = (chunk) => {
745
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
746
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
747
- this.drainInputBuffer();
748
- };
749
- handleClose = () => {
750
- for (const handler of this.closeHandlers) {
751
- handler();
752
- }
753
- };
754
- handleStreamError = (error) => {
755
- this.emitError(error);
756
- };
757
1216
  drainInputBuffer() {
758
1217
  while (true) {
759
1218
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
@@ -853,13 +1312,13 @@ class JsonRpcConnection {
853
1312
  const payload = `Content-Length: ${Buffer.byteLength(body, "utf8")}\r
854
1313
  \r
855
1314
  ${body}`;
856
- return new Promise((resolve2, reject) => {
1315
+ return new Promise((resolve, reject) => {
857
1316
  this.writer.write(payload, (error) => {
858
1317
  if (error) {
859
1318
  reject(error);
860
1319
  return;
861
1320
  }
862
- resolve2();
1321
+ resolve();
863
1322
  });
864
1323
  });
865
1324
  }
@@ -916,7 +1375,7 @@ function toError(error) {
916
1375
 
917
1376
  // ../lsp-core/src/lsp/process.ts
918
1377
  import { spawn, spawnSync } from "node:child_process";
919
- import { existsSync as existsSync2, statSync as statSync2 } from "node:fs";
1378
+ import { existsSync as existsSync3, statSync as statSync3 } from "node:fs";
920
1379
  import { delimiter as delimiter2, join as join2 } from "node:path";
921
1380
  function isMissingProcessError(error) {
922
1381
  if (!(error instanceof Error) || !("code" in error))
@@ -930,10 +1389,10 @@ function reportKillError(context, error) {
930
1389
  }
931
1390
  function validateCwd(cwd) {
932
1391
  try {
933
- if (!existsSync2(cwd)) {
1392
+ if (!existsSync3(cwd)) {
934
1393
  return { valid: false, error: `Working directory does not exist: ${cwd}` };
935
1394
  }
936
- const stats = statSync2(cwd);
1395
+ const stats = statSync3(cwd);
937
1396
  if (!stats.isDirectory()) {
938
1397
  return { valid: false, error: `Path is not a directory: ${cwd}` };
939
1398
  }
@@ -946,9 +1405,9 @@ function validateCwd(cwd) {
946
1405
  }
947
1406
  }
948
1407
  function wrap(proc) {
949
- const exitedPromise = new Promise((resolve2) => {
950
- proc.once("close", (code) => resolve2(code ?? 0));
951
- proc.once("error", () => resolve2(1));
1408
+ const exitedPromise = new Promise((resolve) => {
1409
+ proc.once("close", (code) => resolve(code ?? 0));
1410
+ proc.once("error", () => resolve(1));
952
1411
  });
953
1412
  if (!proc.stdin || !proc.stdout || !proc.stderr) {
954
1413
  throw new LspProcessSpawnError("Spawned process is missing one of stdin/stdout/stderr pipes");
@@ -1018,7 +1477,7 @@ function resolveWindowsCommand(command, env) {
1018
1477
  for (const baseDirectory of baseDirectories) {
1019
1478
  for (const extension of extensions) {
1020
1479
  const candidate = baseDirectory ? join2(baseDirectory, `${command}${extension}`) : `${command}${extension}`;
1021
- if (existsSync2(candidate))
1480
+ if (existsSync3(candidate))
1022
1481
  return candidate;
1023
1482
  }
1024
1483
  }
@@ -1101,33 +1560,29 @@ function isPosition(value) {
1101
1560
 
1102
1561
  // ../lsp-core/src/lsp/transport.ts
1103
1562
  class LspClientNotStartedError extends Error {
1104
- serverId;
1105
- root;
1106
- name = "LspClientNotStartedError";
1107
1563
  constructor(serverId, root) {
1108
1564
  super("LSP client not started");
1109
1565
  this.serverId = serverId;
1110
1566
  this.root = root;
1567
+ this.name = "LspClientNotStartedError";
1111
1568
  }
1112
1569
  }
1113
1570
 
1114
1571
  class LspClientTransport {
1115
- root;
1116
- server;
1117
- proc = null;
1118
- connection = null;
1119
- stderrBuffer = [];
1120
- processExited = false;
1121
- diagnosticsStore = new Map;
1122
- requestTimeoutMs;
1123
- initializeTimeoutMs;
1124
- workspaceApplyEditHandler = null;
1125
- diagnosticPullSupported = false;
1126
- constructor(root, server2, timeouts = {}) {
1572
+ constructor(root, server, timeouts = {}) {
1127
1573
  this.root = root;
1128
- this.server = server2;
1574
+ this.server = server;
1575
+ this.proc = null;
1576
+ this.connection = null;
1577
+ this.stderrBuffer = [];
1578
+ this.processExited = false;
1579
+ this.diagnosticsStore = new Map;
1580
+ this.workspaceApplyEditHandler = null;
1581
+ this.diagnosticPullSupported = false;
1582
+ this.documentFormattingSupported = false;
1129
1583
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
1130
1584
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
1585
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
1131
1586
  }
1132
1587
  pid() {
1133
1588
  return this.proc?.pid;
@@ -1147,6 +1602,12 @@ class LspClientTransport {
1147
1602
  isDiagnosticPullSupported() {
1148
1603
  return this.diagnosticPullSupported;
1149
1604
  }
1605
+ setDocumentFormattingSupported(supported) {
1606
+ this.documentFormattingSupported = supported;
1607
+ }
1608
+ isDocumentFormattingSupported() {
1609
+ return this.documentFormattingSupported;
1610
+ }
1150
1611
  handlePublishDiagnostics(params) {
1151
1612
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
1152
1613
  }
@@ -1222,7 +1683,7 @@ class LspClientTransport {
1222
1683
  const options = args[1];
1223
1684
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
1224
1685
  const timeoutController = new AbortController;
1225
- const timeoutHandle = setTimeout(() => {
1686
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
1226
1687
  const stderrTail = this.stderrBuffer.slice(-5).join(`
1227
1688
  `);
1228
1689
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -1241,7 +1702,7 @@ class LspClientTransport {
1241
1702
  }
1242
1703
  throw error;
1243
1704
  } finally {
1244
- clearTimeout(timeoutHandle);
1705
+ this.timerProvider.clearTimeout(timeoutHandle);
1245
1706
  combinedSignal.dispose();
1246
1707
  }
1247
1708
  }
@@ -1292,8 +1753,8 @@ class LspClientTransport {
1292
1753
  try {
1293
1754
  proc.kill();
1294
1755
  let timeoutId;
1295
- const timeoutPromise = new Promise((resolve2) => {
1296
- timeoutId = setTimeout(resolve2, STOP_HARD_KILL_TIMEOUT_MS);
1756
+ const timeoutPromise = new Promise((resolve) => {
1757
+ timeoutId = setTimeout(resolve, STOP_HARD_KILL_TIMEOUT_MS);
1297
1758
  });
1298
1759
  await Promise.race([
1299
1760
  proc.exited.then(() => {
@@ -1309,7 +1770,7 @@ class LspClientTransport {
1309
1770
  proc.kill("SIGKILL");
1310
1771
  await Promise.race([
1311
1772
  proc.exited,
1312
- new Promise((resolve2) => setTimeout(resolve2, STOP_SIGKILL_GRACE_MS))
1773
+ new Promise((resolve) => setTimeout(resolve, STOP_SIGKILL_GRACE_MS))
1313
1774
  ]);
1314
1775
  } catch (error) {
1315
1776
  reportBestEffortCleanupError("hard process kill", error instanceof Error ? error : String(error));
@@ -1360,6 +1821,14 @@ function supportsDiagnosticPull(capabilities) {
1360
1821
  return false;
1361
1822
  return Object.hasOwn(capabilities, "diagnosticProvider");
1362
1823
  }
1824
+ function supportsDocumentFormatting(capabilities) {
1825
+ if (capabilities === undefined)
1826
+ return false;
1827
+ const provider = capabilities.documentFormattingProvider;
1828
+ if (provider === undefined || provider === null || provider === false)
1829
+ return false;
1830
+ return provider === true || typeof provider === "object";
1831
+ }
1363
1832
 
1364
1833
  class LspClientConnection extends LspClientTransport {
1365
1834
  async initialize() {
@@ -1376,6 +1845,7 @@ class LspClientConnection extends LspClientTransport {
1376
1845
  references: {},
1377
1846
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
1378
1847
  publishDiagnostics: {},
1848
+ formatting: { dynamicRegistration: false },
1379
1849
  rename: {
1380
1850
  prepareSupport: true,
1381
1851
  prepareSupportDefaultBehavior: 1
@@ -1417,6 +1887,7 @@ class LspClientConnection extends LspClientTransport {
1417
1887
  initializationOptions: this.server.initialization
1418
1888
  }, { timeoutMs: this.initializeTimeoutMs });
1419
1889
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
1890
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
1420
1891
  await this.sendNotification("initialized", {});
1421
1892
  await this.sendNotification("workspace/didChangeConfiguration", {
1422
1893
  settings: { json: { validate: { enable: true } } }
@@ -1425,7 +1896,7 @@ class LspClientConnection extends LspClientTransport {
1425
1896
  }
1426
1897
 
1427
1898
  // ../lsp-core/src/lsp/workspace-document-state.ts
1428
- import { readFileSync, realpathSync as realpathSync2 } from "node:fs";
1899
+ import { readFileSync as readFileSync4, realpathSync as realpathSync2 } from "node:fs";
1429
1900
  import { relative as relative2, resolve as resolve2 } from "node:path";
1430
1901
  import { pathToFileURL as pathToFileURL2 } from "node:url";
1431
1902
 
@@ -1612,6 +2083,17 @@ function canonicalPath(filePath) {
1612
2083
  return absolute;
1613
2084
  }
1614
2085
  }
2086
+ function normalizeDocumentUri(uri) {
2087
+ let decoded = uri;
2088
+ try {
2089
+ decoded = decodeURIComponent(uri);
2090
+ } catch {
2091
+ decoded = uri;
2092
+ }
2093
+ if (process.platform !== "win32")
2094
+ return decoded;
2095
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
2096
+ }
1615
2097
  function isSameOrDescendant(candidate, parent) {
1616
2098
  const suffix = relative2(parent, candidate);
1617
2099
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1622,17 +2104,18 @@ function movedPath(candidate, oldPath, newPath) {
1622
2104
  }
1623
2105
 
1624
2106
  class WorkspaceDocumentState {
1625
- sendNotification;
1626
- clearDiagnostics;
1627
- openDocuments = new Map;
1628
- openByUri = new Map;
1629
- openPromises = new Map;
1630
- now;
1631
- versionlessPublishQuiescenceMs;
1632
2107
  constructor(sendNotification, clearDiagnostics, options = {}) {
1633
2108
  this.sendNotification = sendNotification;
1634
2109
  this.clearDiagnostics = clearDiagnostics;
1635
- this.now = options.now ?? (() => Date.now());
2110
+ this.openDocuments = new Map;
2111
+ this.openByUri = new Map;
2112
+ this.openPromises = new Map;
2113
+ this.timerProvider = options.timerProvider ?? {
2114
+ now: options.now ?? (() => Date.now()),
2115
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
2116
+ clearTimeout: (handle) => clearTimeout(handle)
2117
+ };
2118
+ this.now = () => this.timerProvider.now();
1636
2119
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1637
2120
  }
1638
2121
  async openFile(filePath) {
@@ -1642,7 +2125,7 @@ class WorkspaceDocumentState {
1642
2125
  await existingOpen;
1643
2126
  return this.openFile(path);
1644
2127
  }
1645
- const text = readFileSync(path, "utf-8");
2128
+ const text = readFileSync4(path, "utf-8");
1646
2129
  const existing = this.openDocuments.get(path);
1647
2130
  if (!existing)
1648
2131
  return this.openDocumentSingleFlight(path, text);
@@ -1654,7 +2137,7 @@ class WorkspaceDocumentState {
1654
2137
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1655
2138
  }
1656
2139
  getStoredDiagnostics(uri) {
1657
- const state = this.openByUri.get(uri);
2140
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1658
2141
  if (!state)
1659
2142
  return [];
1660
2143
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1676,13 +2159,13 @@ class WorkspaceDocumentState {
1676
2159
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1677
2160
  }
1678
2161
  getPullCache(snapshot) {
1679
- const state = this.openByUri.get(snapshot.uri);
2162
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1680
2163
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1681
2164
  return null;
1682
2165
  return state.pullCache;
1683
2166
  }
1684
2167
  recordPullDiagnostics(snapshot, report) {
1685
- const state = this.openByUri.get(snapshot.uri);
2168
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1686
2169
  if (!state)
1687
2170
  return;
1688
2171
  state.pullCache = {
@@ -1692,7 +2175,7 @@ class WorkspaceDocumentState {
1692
2175
  };
1693
2176
  }
1694
2177
  recordPublishedDiagnostics(params) {
1695
- const state = this.openByUri.get(params.uri);
2178
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1696
2179
  if (!state)
1697
2180
  return;
1698
2181
  state.publishGeneration += 1;
@@ -1706,7 +2189,7 @@ class WorkspaceDocumentState {
1706
2189
  this.notifyWaiters(state);
1707
2190
  }
1708
2191
  resolvePushDiagnostics(snapshot) {
1709
- const state = this.openByUri.get(snapshot.uri);
2192
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1710
2193
  if (!state?.lastPublish)
1711
2194
  return { status: "missing" };
1712
2195
  const publish = state.lastPublish;
@@ -1720,20 +2203,22 @@ class WorkspaceDocumentState {
1720
2203
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1721
2204
  }
1722
2205
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1723
- const state = this.openByUri.get(snapshot.uri);
2206
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1724
2207
  if (!state || timeoutMs <= 0)
1725
2208
  return Promise.resolve();
2209
+ if (state.publishGeneration !== snapshot.publishGeneration)
2210
+ return Promise.resolve();
1726
2211
  return new Promise((resolveActivity) => {
1727
2212
  let settled = false;
1728
2213
  const finish = () => {
1729
2214
  if (settled)
1730
2215
  return;
1731
2216
  settled = true;
1732
- clearTimeout(timer);
2217
+ this.timerProvider.clearTimeout(timer);
1733
2218
  state.waiters.delete(finish);
1734
2219
  resolveActivity();
1735
2220
  };
1736
- const timer = setTimeout(finish, timeoutMs);
2221
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1737
2222
  if (typeof timer.unref === "function")
1738
2223
  timer.unref();
1739
2224
  state.waiters.add(finish);
@@ -1799,7 +2284,7 @@ class WorkspaceDocumentState {
1799
2284
  const state = this.openDocuments.get(mutation.path);
1800
2285
  if (state) {
1801
2286
  await this.closeDocument(state);
1802
- await this.openDocumentSingleFlight(mutation.path, readFileSync(mutation.path, "utf-8"));
2287
+ await this.openDocumentSingleFlight(mutation.path, readFileSync4(mutation.path, "utf-8"));
1803
2288
  } else {
1804
2289
  watched.push({ uri: pathToFileURL2(mutation.path).href, type: mutation.replaced ? 2 : 1 });
1805
2290
  }
@@ -1811,7 +2296,7 @@ class WorkspaceDocumentState {
1811
2296
  await this.closeDocument(state);
1812
2297
  for (const state of moved) {
1813
2298
  const path = movedPath(state.path, mutation.oldPath, mutation.newPath);
1814
- await this.openDocumentSingleFlight(path, readFileSync(path, "utf-8"));
2299
+ await this.openDocumentSingleFlight(path, readFileSync4(path, "utf-8"));
1815
2300
  }
1816
2301
  if (moved.length === 0) {
1817
2302
  watched.push({ uri: pathToFileURL2(mutation.oldPath).href, type: 3 });
@@ -1841,7 +2326,7 @@ class WorkspaceDocumentState {
1841
2326
  waiters: new Set
1842
2327
  };
1843
2328
  this.openDocuments.set(path, state);
1844
- this.openByUri.set(state.uri, state);
2329
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
1845
2330
  this.notifyWaiters(state);
1846
2331
  await this.sendNotification("textDocument/didOpen", {
1847
2332
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -1866,7 +2351,7 @@ class WorkspaceDocumentState {
1866
2351
  }
1867
2352
  async closeDocument(state) {
1868
2353
  this.openDocuments.delete(state.path);
1869
- this.openByUri.delete(state.uri);
2354
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
1870
2355
  this.clearDiagnostics(state.uri);
1871
2356
  this.notifyWaiters(state);
1872
2357
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -1887,21 +2372,19 @@ function workspaceApplyEditConcurrentFailureReason(phase) {
1887
2372
  }
1888
2373
 
1889
2374
  // ../lsp-core/src/lsp/workspace-edit-commit.ts
1890
- import { existsSync as existsSync4, lstatSync as lstatSync2, renameSync, rmSync, writeFileSync } from "node:fs";
2375
+ import { existsSync as existsSync5, lstatSync as lstatSync4, renameSync, rmSync, writeFileSync } from "node:fs";
1891
2376
 
1892
2377
  // ../lsp-core/src/lsp/workspace-edit-path.ts
1893
- import { existsSync as existsSync3, lstatSync, readFileSync as readFileSync2, readdirSync, realpathSync as realpathSync3 } from "node:fs";
1894
- import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3, resolve as resolve3 } from "node:path";
2378
+ import { existsSync as existsSync4, lstatSync as lstatSync3, readFileSync as readFileSync5, readdirSync, realpathSync as realpathSync3 } from "node:fs";
2379
+ import { dirname as dirname5, isAbsolute as isAbsolute2, relative as relative3, resolve as resolve3 } from "node:path";
1895
2380
  import { fileURLToPath } from "node:url";
1896
2381
 
1897
2382
  class WorkspaceEditPathError extends Error {
1898
- path;
1899
- detail;
1900
- name = "WorkspaceEditPathError";
1901
2383
  constructor(path, detail) {
1902
2384
  super(`${detail}: ${path}`);
1903
2385
  this.path = path;
1904
2386
  this.detail = detail;
2387
+ this.name = "WorkspaceEditPathError";
1905
2388
  }
1906
2389
  }
1907
2390
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -1910,8 +2393,8 @@ function isPathInsideWorkspace(filePath, workspaceRoot) {
1910
2393
  }
1911
2394
  function canonicalizeMissingPath(filePath) {
1912
2395
  let ancestor = filePath;
1913
- while (!existsSync3(ancestor)) {
1914
- const parent = dirname2(ancestor);
2396
+ while (!existsSync4(ancestor)) {
2397
+ const parent = dirname5(ancestor);
1915
2398
  if (parent === ancestor)
1916
2399
  throw new WorkspaceEditPathError(filePath, "no existing ancestor");
1917
2400
  ancestor = parent;
@@ -1921,14 +2404,14 @@ function canonicalizeMissingPath(filePath) {
1921
2404
  function canonicalWorkspaceRoot(workspaceRoot) {
1922
2405
  try {
1923
2406
  const canonical = realpathSync3(resolve3(workspaceRoot));
1924
- if (!lstatSync(canonical).isDirectory()) {
2407
+ if (!lstatSync3(canonical).isDirectory()) {
1925
2408
  return { success: false, error: `workspace root is not a directory: ${workspaceRoot}` };
1926
2409
  }
1927
2410
  return {
1928
2411
  success: true,
1929
2412
  path: canonical,
1930
2413
  requestedPath: resolve3(workspaceRoot),
1931
- followedSymbolicLink: existsSync3(resolve3(workspaceRoot)) && lstatSync(resolve3(workspaceRoot)).isSymbolicLink()
2414
+ followedSymbolicLink: existsSync4(resolve3(workspaceRoot)) && lstatSync3(resolve3(workspaceRoot)).isSymbolicLink()
1932
2415
  };
1933
2416
  } catch (error) {
1934
2417
  const detail = error instanceof Error ? error.message : String(error);
@@ -1948,7 +2431,7 @@ function uriToCanonicalWorkspacePath(uri, workspaceRoot) {
1948
2431
  return { success: false, error: `non-file URI ${uri}: ${detail}` };
1949
2432
  }
1950
2433
  try {
1951
- const canonical = existsSync3(requestedPath) ? realpathSync3(requestedPath) : canonicalizeMissingPath(requestedPath);
2434
+ const canonical = existsSync4(requestedPath) ? realpathSync3(requestedPath) : canonicalizeMissingPath(requestedPath);
1952
2435
  if (!isPathInsideWorkspace(canonical, workspaceRoot)) {
1953
2436
  return { success: false, error: `${requestedPath}: outside workspace ${workspaceRoot}` };
1954
2437
  }
@@ -1956,7 +2439,7 @@ function uriToCanonicalWorkspacePath(uri, workspaceRoot) {
1956
2439
  success: true,
1957
2440
  path: canonical,
1958
2441
  requestedPath,
1959
- followedSymbolicLink: existsSync3(requestedPath) && lstatSync(requestedPath).isSymbolicLink()
2442
+ followedSymbolicLink: existsSync4(requestedPath) && lstatSync3(requestedPath).isSymbolicLink()
1960
2443
  };
1961
2444
  } catch (error) {
1962
2445
  const detail = error instanceof Error ? error.message : String(error);
@@ -1964,11 +2447,11 @@ function uriToCanonicalWorkspacePath(uri, workspaceRoot) {
1964
2447
  }
1965
2448
  }
1966
2449
  function snapshotPath(path, includeChildren) {
1967
- if (!existsSync3(path))
2450
+ if (!existsSync4(path))
1968
2451
  return { kind: "missing" };
1969
- const stats = lstatSync(path);
2452
+ const stats = lstatSync3(path);
1970
2453
  if (stats.isFile())
1971
- return { kind: "file", content: readFileSync2(path, "utf-8") };
2454
+ return { kind: "file", content: readFileSync5(path, "utf-8") };
1972
2455
  if (stats.isDirectory()) {
1973
2456
  return includeChildren ? { kind: "directory", children: readdirSync(path).sort() } : { kind: "directory" };
1974
2457
  }
@@ -2084,7 +2567,7 @@ function commitOperation(context, operation) {
2084
2567
  }
2085
2568
  if (operation.kind === "rename") {
2086
2569
  if (operation.replaceDestination) {
2087
- const targetKind = existsSync4(operation.newPath) && lstatSync2(operation.newPath).isDirectory() ? "directory" : "file";
2570
+ const targetKind = existsSync5(operation.newPath) && lstatSync4(operation.newPath).isDirectory() ? "directory" : "file";
2088
2571
  io.remove(operation.newPath, targetKind === "directory");
2089
2572
  accumulator.mutations.push({ kind: "delete", path: operation.newPath, targetKind });
2090
2573
  addModifiedPath(accumulator.filesModified, reportedPath(plan, operation.newPath));
@@ -2193,13 +2676,11 @@ function canonicalFingerprint(operations) {
2193
2676
 
2194
2677
  // ../lsp-core/src/lsp/workspace-edit-types.ts
2195
2678
  class WorkspaceEditValidationError extends Error {
2196
- changeIndex;
2197
- detail;
2198
- name = "WorkspaceEditValidationError";
2199
2679
  constructor(changeIndex, detail) {
2200
2680
  super(`change ${changeIndex}: ${detail}`);
2201
2681
  this.changeIndex = changeIndex;
2202
2682
  this.detail = detail;
2683
+ this.name = "WorkspaceEditValidationError";
2203
2684
  }
2204
2685
  }
2205
2686
 
@@ -2285,14 +2766,14 @@ function parseSinglePathResource(input, kind) {
2285
2766
  return;
2286
2767
  }
2287
2768
  if (kind === "create") {
2288
- const options2 = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
2769
+ const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
2289
2770
  target.operations.push({
2290
2771
  kind,
2291
2772
  changeIndex,
2292
2773
  path: resolvedPath.path,
2293
2774
  reportedPath: resolvedPath.requestedPath,
2294
- overwrite: options2["overwrite"] ?? false,
2295
- ignoreIfExists: options2["ignoreIfExists"] ?? false,
2775
+ overwrite: options["overwrite"] ?? false,
2776
+ ignoreIfExists: options["ignoreIfExists"] ?? false,
2296
2777
  followedSymbolicLink: resolvedPath.followedSymbolicLink
2297
2778
  });
2298
2779
  return;
@@ -2450,7 +2931,7 @@ function parseDocumentChange(input) {
2450
2931
  }
2451
2932
 
2452
2933
  // ../lsp-core/src/lsp/workspace-edit-simulation.ts
2453
- import { dirname as dirname3, relative as relative4, resolve as resolve4 } from "node:path";
2934
+ import { dirname as dirname6, relative as relative4, resolve as resolve4 } from "node:path";
2454
2935
 
2455
2936
  // ../lsp-core/src/lsp/workspace-edit-text.ts
2456
2937
  function comparePosition(left, right) {
@@ -2574,7 +3055,7 @@ function virtualDirectoryHasChildren(virtual, path) {
2574
3055
  return false;
2575
3056
  }
2576
3057
  function requireVirtualParent(virtual, path, changeIndex) {
2577
- if (virtual.get(dirname3(path))?.kind !== "directory") {
3058
+ if (virtual.get(dirname6(path))?.kind !== "directory") {
2578
3059
  throw new WorkspaceEditValidationError(changeIndex, `parent directory does not exist for ${path}`);
2579
3060
  }
2580
3061
  }
@@ -2694,13 +3175,12 @@ function simulateDelete(operation, virtual) {
2694
3175
  }
2695
3176
 
2696
3177
  // ../lsp-core/src/lsp/workspace-edit-snapshot.ts
2697
- import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
2698
- import { dirname as dirname4, resolve as resolve5 } from "node:path";
3178
+ import { existsSync as existsSync6, lstatSync as lstatSync5, readdirSync as readdirSync2 } from "node:fs";
3179
+ import { dirname as dirname7, resolve as resolve5 } from "node:path";
2699
3180
  class WorkspaceSnapshotBuilder {
2700
- workspaceRoot;
2701
- snapshots = new Map;
2702
3181
  constructor(workspaceRoot) {
2703
3182
  this.workspaceRoot = workspaceRoot;
3183
+ this.snapshots = new Map;
2704
3184
  }
2705
3185
  build(operations) {
2706
3186
  this.add(this.workspaceRoot, false);
@@ -2730,9 +3210,9 @@ class WorkspaceSnapshotBuilder {
2730
3210
  }
2731
3211
  if (candidate === this.workspaceRoot)
2732
3212
  break;
2733
- candidate = dirname4(candidate);
3213
+ candidate = dirname7(candidate);
2734
3214
  }
2735
- if (!includeChildren || !existsSync5(path) || !lstatSync3(path).isDirectory())
3215
+ if (!includeChildren || !existsSync6(path) || !lstatSync5(path).isDirectory())
2736
3216
  return;
2737
3217
  for (const child of readdirSync2(path))
2738
3218
  this.add(resolve5(path, child), true);
@@ -2744,8 +3224,10 @@ function snapshotOperations(operations, workspaceRoot) {
2744
3224
 
2745
3225
  // ../lsp-core/src/lsp/workspace-edit-plan.ts
2746
3226
  class PlanPathIndex {
2747
- firstChangeByPath = new Map;
2748
- reportedPathByCanonical = new Map;
3227
+ constructor() {
3228
+ this.firstChangeByPath = new Map;
3229
+ this.reportedPathByCanonical = new Map;
3230
+ }
2749
3231
  build(operations) {
2750
3232
  for (const operation of operations) {
2751
3233
  switch (operation.kind) {
@@ -2761,11 +3243,11 @@ class PlanPathIndex {
2761
3243
  }
2762
3244
  }
2763
3245
  }
2764
- add(path, reportedPath2, changeIndex) {
3246
+ add(path, reportedPath, changeIndex) {
2765
3247
  if (!this.firstChangeByPath.has(path))
2766
3248
  this.firstChangeByPath.set(path, changeIndex);
2767
3249
  if (!this.reportedPathByCanonical.has(path))
2768
- this.reportedPathByCanonical.set(path, reportedPath2);
3250
+ this.reportedPathByCanonical.set(path, reportedPath);
2769
3251
  }
2770
3252
  }
2771
3253
  function fingerprintWorkspaceEdit(edit, workspaceRoot) {
@@ -2834,14 +3316,11 @@ function isRecord4(value) {
2834
3316
  }
2835
3317
 
2836
3318
  class WorkspaceMutationController {
2837
- workspaceRoot;
2838
- documents;
2839
- activeLease = null;
2840
- nextLeaseId = 1;
2841
- io;
2842
3319
  constructor(workspaceRoot, documents) {
2843
3320
  this.workspaceRoot = workspaceRoot;
2844
3321
  this.documents = documents;
3322
+ this.activeLease = null;
3323
+ this.nextLeaseId = 1;
2845
3324
  }
2846
3325
  setIo(io) {
2847
3326
  this.io = io;
@@ -2880,15 +3359,15 @@ class WorkspaceMutationController {
2880
3359
  };
2881
3360
  }
2882
3361
  lease.phase = "applying";
2883
- lease.applyCompletion = new Promise((resolve6) => {
2884
- lease.resolveApply = resolve6;
3362
+ lease.applyCompletion = new Promise((resolve) => {
3363
+ lease.resolveApply = resolve;
2885
3364
  });
2886
3365
  const edit = isRecord4(params) ? params["edit"] : undefined;
2887
- const record2 = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
2888
- lease.serverApply = record2;
3366
+ const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
3367
+ lease.serverApply = record;
2889
3368
  lease.phase = "settled";
2890
3369
  lease.resolveApply?.();
2891
- return responseFor(record2.result);
3370
+ return responseFor(record.result);
2892
3371
  }
2893
3372
  async reconcileRename(leaseToken, edit) {
2894
3373
  const lease = this.requireActiveLease(leaseToken);
@@ -2904,16 +3383,16 @@ class WorkspaceMutationController {
2904
3383
  const applied = await this.applyEdit(edit, lease);
2905
3384
  return { edit, apply: applied.result };
2906
3385
  }
2907
- reconcileServerApply(record2, edit) {
3386
+ reconcileServerApply(record, edit) {
2908
3387
  if (!edit)
2909
- return { edit, apply: record2.result };
3388
+ return { edit, apply: record.result };
2910
3389
  const fingerprint = fingerprintWorkspaceEdit(edit, this.workspaceRoot);
2911
- if (fingerprint.success && record2.fingerprint !== null && fingerprint.fingerprint === record2.fingerprint) {
2912
- return { edit, apply: record2.result };
3390
+ if (fingerprint.success && record.fingerprint !== null && fingerprint.fingerprint === record.fingerprint) {
3391
+ return { edit, apply: record.result };
2913
3392
  }
2914
3393
  return {
2915
3394
  edit,
2916
- apply: failure("rename result conflicts with server-applied workspace edit", 0, record2.result)
3395
+ apply: failure("rename result conflicts with server-applied workspace edit", 0, record.result)
2917
3396
  };
2918
3397
  }
2919
3398
  async applyEdit(edit, lease) {
@@ -2954,14 +3433,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
2954
3433
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
2955
3434
 
2956
3435
  class LspClient extends LspClientConnection {
2957
- diagnosticPullErrors = [];
2958
- documents;
2959
- workspaceMutations;
2960
- diagnosticsFreshnessTimeoutMs;
2961
- constructor(root, server2, options = {}) {
2962
- super(root, server2, options);
3436
+ constructor(root, server, options = {}) {
3437
+ super(root, server, options);
3438
+ this.diagnosticPullErrors = [];
2963
3439
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2964
3440
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
3441
+ timerProvider: this.timerProvider,
2965
3442
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
2966
3443
  });
2967
3444
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -3014,6 +3491,18 @@ class LspClient extends LspClientConnection {
3014
3491
  textDocument: { uri: pathToFileURL3(absPath).href }
3015
3492
  }, options);
3016
3493
  }
3494
+ async formatDocument(filePath, options, signal) {
3495
+ if (!this.isDocumentFormattingSupported())
3496
+ return null;
3497
+ const absPath = this.resolveWorkspacePath(filePath);
3498
+ await this.openFile(absPath);
3499
+ const requestOptions = signal === undefined ? {} : { signal };
3500
+ const edits = await this.sendRequest("textDocument/formatting", {
3501
+ textDocument: { uri: pathToFileURL3(absPath).href },
3502
+ options
3503
+ }, requestOptions);
3504
+ return edits ?? [];
3505
+ }
3017
3506
  async workspaceSymbols(query, signal) {
3018
3507
  const options = signal === undefined ? {} : { signal };
3019
3508
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -3053,7 +3542,7 @@ class LspClient extends LspClientConnection {
3053
3542
  const absPath = this.resolveWorkspacePath(filePath);
3054
3543
  const uri = pathToFileURL3(absPath).href;
3055
3544
  await this.openFile(absPath);
3056
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
3545
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
3057
3546
  for (;; ) {
3058
3547
  signal?.throwIfAborted();
3059
3548
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -3066,13 +3555,13 @@ class LspClient extends LspClientConnection {
3066
3555
  if (!pushFallbackOnly) {
3067
3556
  const cached = this.documents.getPullCache(snapshot);
3068
3557
  try {
3069
- const remainingMs2 = deadlineAt - Date.now();
3070
- if (remainingMs2 <= 0)
3558
+ const remainingMs = deadlineAt - this.timerProvider.now();
3559
+ if (remainingMs <= 0)
3071
3560
  return this.freshnessTimeout(absPath);
3072
3561
  const result = await this.sendRequest("textDocument/diagnostic", {
3073
3562
  textDocument: { uri },
3074
3563
  ...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
3075
- }, { timeoutMs: remainingMs2, ...signal === undefined ? {} : { signal } });
3564
+ }, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
3076
3565
  if (!this.documents.isCurrentSnapshot(snapshot))
3077
3566
  continue;
3078
3567
  const report = this.parseDiagnosticPullReport(result);
@@ -3101,7 +3590,7 @@ class LspClient extends LspClientConnection {
3101
3590
  }
3102
3591
  if (!pushFallbackOnly)
3103
3592
  continue;
3104
- const remainingMs = deadlineAt - Date.now();
3593
+ const remainingMs = deadlineAt - this.timerProvider.now();
3105
3594
  if (remainingMs <= 0) {
3106
3595
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
3107
3596
  const cached = this.documents.getPullCache(snapshot);
@@ -3153,7 +3642,7 @@ function waitForDiagnosticsActivity(wait, signal) {
3153
3642
  return wait;
3154
3643
  if (signal.aborted)
3155
3644
  return Promise.reject(abortError2(signal));
3156
- return new Promise((resolve7, reject) => {
3645
+ return new Promise((resolve, reject) => {
3157
3646
  const onAbort = () => {
3158
3647
  signal.removeEventListener("abort", onAbort);
3159
3648
  reject(abortError2(signal));
@@ -3161,7 +3650,7 @@ function waitForDiagnosticsActivity(wait, signal) {
3161
3650
  signal.addEventListener("abort", onAbort, { once: true });
3162
3651
  wait.then(() => {
3163
3652
  signal.removeEventListener("abort", onAbort);
3164
- resolve7();
3653
+ resolve();
3165
3654
  }, (error) => {
3166
3655
  signal.removeEventListener("abort", onAbort);
3167
3656
  reject(error);
@@ -3229,7 +3718,7 @@ async function stopClientBestEffort(client) {
3229
3718
  function awaitWithSignal(promise, signal) {
3230
3719
  if (!signal)
3231
3720
  return promise;
3232
- return new Promise((resolve7, reject) => {
3721
+ return new Promise((resolve, reject) => {
3233
3722
  let settled = false;
3234
3723
  const onAbort = () => {
3235
3724
  if (settled)
@@ -3247,7 +3736,7 @@ function awaitWithSignal(promise, signal) {
3247
3736
  return;
3248
3737
  settled = true;
3249
3738
  signal.removeEventListener("abort", onAbort);
3250
- resolve7(value);
3739
+ resolve(value);
3251
3740
  }, (err) => {
3252
3741
  if (settled)
3253
3742
  return;
@@ -3259,20 +3748,18 @@ function awaitWithSignal(promise, signal) {
3259
3748
  }
3260
3749
 
3261
3750
  class LspManager {
3262
- clients = new Map;
3263
- reaperHandle = null;
3264
- signalDisposer = null;
3265
- disposed = false;
3266
- idleTimeoutMs;
3267
- initTimeoutMs;
3268
- reaperIntervalMs;
3269
- clientFactory;
3270
- now;
3271
3751
  constructor(options = {}) {
3752
+ this.clients = new Map;
3753
+ this.pendingStops = new Map;
3754
+ this.respawnBudgets = new Map;
3755
+ this.reaperHandle = null;
3756
+ this.signalDisposer = null;
3757
+ this.disposed = false;
3272
3758
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
3273
3759
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
3760
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
3274
3761
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
3275
- this.clientFactory = options.clientFactory ?? ((root, server2) => new LspClient(root, server2));
3762
+ this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
3276
3763
  this.now = options.now ?? (() => Date.now());
3277
3764
  this.startReaper();
3278
3765
  this.signalDisposer = installProcessSignalCleanup(() => this.stopAll());
@@ -3290,38 +3777,103 @@ class LspManager {
3290
3777
  getKey(root, serverId) {
3291
3778
  return `${root}::${serverId}`;
3292
3779
  }
3780
+ tombstoneStop(key, client) {
3781
+ const stop = stopClientBestEffort(client);
3782
+ this.pendingStops.set(key, stop);
3783
+ stop.finally(() => {
3784
+ if (this.pendingStops.get(key) === stop) {
3785
+ this.pendingStops.delete(key);
3786
+ }
3787
+ });
3788
+ return stop;
3789
+ }
3790
+ recordDeadGeneration(key) {
3791
+ let budget = this.respawnBudgets.get(key);
3792
+ if (budget === undefined) {
3793
+ budget = { deadGenerations: 0, exhaustedAt: null };
3794
+ this.respawnBudgets.set(key, budget);
3795
+ }
3796
+ budget.deadGenerations += 1;
3797
+ }
3798
+ markHealthyGeneration(key) {
3799
+ this.respawnBudgets.delete(key);
3800
+ }
3801
+ ensureRespawnAllowed(key, root, serverId) {
3802
+ const budget = this.respawnBudgets.get(key);
3803
+ if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
3804
+ return;
3805
+ if (budget.exhaustedAt === null) {
3806
+ budget.exhaustedAt = this.now();
3807
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3808
+ }
3809
+ if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
3810
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3811
+ }
3812
+ budget.deadGenerations = 0;
3813
+ budget.exhaustedAt = null;
3814
+ }
3293
3815
  reapStale() {
3294
3816
  const t = this.now();
3295
3817
  for (const [key, managed] of this.clients) {
3296
3818
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3297
- stopClientBestEffort(managed.client);
3298
3819
  this.clients.delete(key);
3820
+ this.tombstoneStop(key, managed.client);
3299
3821
  continue;
3300
3822
  }
3301
3823
  if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
3302
- stopClientBestEffort(managed.client);
3303
3824
  this.clients.delete(key);
3825
+ this.tombstoneStop(key, managed.client);
3826
+ }
3827
+ }
3828
+ }
3829
+ evictForAdmission() {
3830
+ while (this.clients.size >= this.maxResidentClients) {
3831
+ const victim = this.leastRecentlyUsedIdleClient();
3832
+ if (!victim)
3833
+ return;
3834
+ this.clients.delete(victim.key);
3835
+ this.tombstoneStop(victim.key, victim.managed.client);
3836
+ }
3837
+ }
3838
+ leastRecentlyUsedIdleClient() {
3839
+ let candidate = null;
3840
+ for (const [key, managed] of this.clients) {
3841
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
3842
+ continue;
3843
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
3844
+ candidate = { key, managed };
3304
3845
  }
3305
3846
  }
3847
+ return candidate;
3306
3848
  }
3307
3849
  async tryDeleteIfOrphaned(key, managed) {
3308
3850
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
3309
3851
  this.clients.delete(key);
3310
- await stopClientBestEffort(managed.client);
3852
+ await this.tombstoneStop(key, managed.client);
3311
3853
  }
3312
3854
  }
3313
- async getClient(root, server2, signal) {
3855
+ async getClient(root, server, signal) {
3314
3856
  if (this.disposed) {
3315
3857
  throw new Error("LspManager has been disposed");
3316
3858
  }
3317
3859
  signal?.throwIfAborted();
3318
- const key = this.getKey(root, server2.id);
3860
+ const key = this.getKey(root, server.id);
3861
+ for (;; ) {
3862
+ const pendingStop = this.pendingStops.get(key);
3863
+ if (pendingStop === undefined)
3864
+ break;
3865
+ await awaitWithSignal(pendingStop, signal);
3866
+ signal?.throwIfAborted();
3867
+ }
3868
+ if (this.disposed) {
3869
+ throw new Error("LspManager has been disposed");
3870
+ }
3319
3871
  let managed = this.clients.get(key);
3320
3872
  if (managed) {
3321
3873
  const t = this.now();
3322
3874
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3323
- await stopClientBestEffort(managed.client);
3324
3875
  this.clients.delete(key);
3876
+ await this.tombstoneStop(key, managed.client);
3325
3877
  managed = undefined;
3326
3878
  }
3327
3879
  }
@@ -3342,15 +3894,21 @@ class LspManager {
3342
3894
  signal.throwIfAborted();
3343
3895
  }
3344
3896
  if (!managed.client.isAlive()) {
3345
- await stopClientBestEffort(managed.client);
3346
- this.clients.delete(key);
3347
- return this.getClient(root, server2, signal);
3897
+ this.recordDeadGeneration(key);
3898
+ if (this.clients.get(key) === managed) {
3899
+ this.clients.delete(key);
3900
+ }
3901
+ await this.tombstoneStop(key, managed.client);
3902
+ return this.getClient(root, server, signal);
3348
3903
  }
3904
+ this.markHealthyGeneration(key);
3349
3905
  managed.refCount++;
3350
3906
  managed.lastUsedAt = this.now();
3351
3907
  return managed.client;
3352
3908
  }
3353
- const client = this.clientFactory(root, server2);
3909
+ this.evictForAdmission();
3910
+ this.ensureRespawnAllowed(key, root, server.id);
3911
+ const client = this.clientFactory(root, server);
3354
3912
  const initStartedAt = this.now();
3355
3913
  const initPromise = (async () => {
3356
3914
  await client.start();
@@ -3373,7 +3931,7 @@ class LspManager {
3373
3931
  if (this.clients.get(key) === newManaged) {
3374
3932
  this.clients.delete(key);
3375
3933
  }
3376
- await stopClientBestEffort(client);
3934
+ await this.tombstoneStop(key, client);
3377
3935
  throw err;
3378
3936
  }
3379
3937
  newManaged.pendingWaiters--;
@@ -3384,6 +3942,15 @@ class LspManager {
3384
3942
  await this.tryDeleteIfOrphaned(key, newManaged);
3385
3943
  signal.throwIfAborted();
3386
3944
  }
3945
+ if (!client.isAlive()) {
3946
+ this.recordDeadGeneration(key);
3947
+ if (this.clients.get(key) === newManaged) {
3948
+ this.clients.delete(key);
3949
+ }
3950
+ await this.tombstoneStop(key, client);
3951
+ return this.getClient(root, server, signal);
3952
+ }
3953
+ this.markHealthyGeneration(key);
3387
3954
  newManaged.refCount++;
3388
3955
  newManaged.lastUsedAt = this.now();
3389
3956
  return client;
@@ -3404,15 +3971,21 @@ class LspManager {
3404
3971
  if (client && managed.client !== client)
3405
3972
  return;
3406
3973
  this.clients.delete(key);
3407
- stopClientBestEffort(managed.client);
3974
+ this.tombstoneStop(key, managed.client);
3408
3975
  }
3409
- warmupClient(root, server2) {
3976
+ warmupClient(root, server) {
3410
3977
  if (this.disposed)
3411
3978
  return;
3412
- const key = this.getKey(root, server2.id);
3413
- if (this.clients.has(key))
3979
+ const key = this.getKey(root, server.id);
3980
+ if (this.clients.has(key) || this.pendingStops.has(key))
3981
+ return;
3982
+ this.evictForAdmission();
3983
+ try {
3984
+ this.ensureRespawnAllowed(key, root, server.id);
3985
+ } catch {
3414
3986
  return;
3415
- const client = this.clientFactory(root, server2);
3987
+ }
3988
+ const client = this.clientFactory(root, server);
3416
3989
  const initStartedAt = this.now();
3417
3990
  const initPromise = (async () => {
3418
3991
  await client.start();
@@ -3437,7 +4010,7 @@ class LspManager {
3437
4010
  if (this.clients.get(key) === managed) {
3438
4011
  this.clients.delete(key);
3439
4012
  }
3440
- stopClientBestEffort(client);
4013
+ this.tombstoneStop(key, client);
3441
4014
  });
3442
4015
  }
3443
4016
  isServerInitializing(root, serverId) {
@@ -3481,8 +4054,11 @@ class LspManager {
3481
4054
  for (const managed of this.clients.values()) {
3482
4055
  stopPromises.push(stopClientBestEffort(managed.client));
3483
4056
  }
4057
+ const tombstonedStops = [...this.pendingStops.values()];
3484
4058
  this.clients.clear();
3485
- await Promise.allSettled(stopPromises);
4059
+ this.respawnBudgets.clear();
4060
+ await Promise.allSettled([...stopPromises, ...tombstonedStops]);
4061
+ this.pendingStops.clear();
3486
4062
  }
3487
4063
  }
3488
4064
  var _defaultInstance = null;
@@ -3500,57 +4076,52 @@ async function disposeDefaultLspManager() {
3500
4076
  }
3501
4077
  }
3502
4078
 
3503
- // ../lsp-core/src/lsp/server-install-state.ts
3504
- import { existsSync as existsSync6, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3505
- import { dirname as dirname5 } from "node:path";
3506
- function getInstallDecisionsPath() {
3507
- return lspRequestContext().installDecisionsPath;
3508
- }
3509
- function loadInstallDecisions() {
3510
- const path = getInstallDecisionsPath();
3511
- if (!existsSync6(path))
3512
- return {};
3513
- try {
3514
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
3515
- return isInstallDecisions(parsed) ? parsed : {};
3516
- } catch {
3517
- return {};
4079
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
4080
+ import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
4081
+ import { dirname as dirname8, join as join3 } from "node:path";
4082
+
4083
+ // ../lsp-core/src/lsp/workspace-markers.ts
4084
+ var GIT_WORKSPACE_MARKER = ".git";
4085
+ var PROJECT_WORKSPACE_MARKERS = [
4086
+ "package.json",
4087
+ "pyproject.toml",
4088
+ "Cargo.toml",
4089
+ "go.mod",
4090
+ "pom.xml",
4091
+ "build.gradle"
4092
+ ];
4093
+ var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
4094
+
4095
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
4096
+ function findWorkspaceRootOutsideContext(directory) {
4097
+ const marked = nearestMarkedAncestor(directory);
4098
+ if (marked !== undefined)
4099
+ return marked;
4100
+ return realpathSync4(nearestExistingAncestor(directory));
4101
+ }
4102
+ function nearestMarkedAncestor(directory) {
4103
+ let current = directory;
4104
+ for (;; ) {
4105
+ if (existsSync7(current) && WORKSPACE_MARKERS.some((marker) => existsSync7(join3(current, marker)))) {
4106
+ return realpathSync4(current);
4107
+ }
4108
+ const parent = dirname8(current);
4109
+ if (parent === current)
4110
+ return;
4111
+ current = parent;
3518
4112
  }
3519
4113
  }
3520
- function loadInstallDecision(serverId) {
3521
- return loadInstallDecisions()[serverId];
3522
- }
3523
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3524
- const decisions = loadInstallDecisions();
3525
- decisions[serverId] = { decision, decidedAt };
3526
- writeInstallDecisions(decisions);
3527
- }
3528
- function isInstallDecision(value) {
3529
- return value === "declined" || value === "allowed";
3530
- }
3531
- function writeInstallDecisions(decisions) {
3532
- const path = getInstallDecisionsPath();
3533
- mkdirSync(dirname5(path), { recursive: true });
3534
- const tmpPath = `${path}.tmp`;
3535
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3536
- `, "utf8");
3537
- renameSync2(tmpPath, path);
3538
- }
3539
- function isInstallDecisions(value) {
3540
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3541
- }
3542
- function isInstallDecisionRecord(value) {
3543
- if (!isRecord5(value))
3544
- return false;
3545
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3546
- }
3547
- function isRecord5(value) {
3548
- return typeof value === "object" && value !== null && !Array.isArray(value);
4114
+ function nearestExistingAncestor(directory) {
4115
+ let current = directory;
4116
+ while (!existsSync7(current)) {
4117
+ const parent = dirname8(current);
4118
+ if (parent === current)
4119
+ return current;
4120
+ current = parent;
4121
+ }
4122
+ return current;
3549
4123
  }
3550
4124
 
3551
- // ../lsp-core/src/lsp/config-loader.ts
3552
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
3553
-
3554
4125
  // ../lsp-core/src/lsp/server-definitions.ts
3555
4126
  var LSP_INSTALL_HINTS = {
3556
4127
  typescript: "npm install -g typescript-language-server typescript",
@@ -3596,6 +4167,26 @@ var LSP_INSTALL_HINTS = {
3596
4167
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
3597
4168
  razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
3598
4169
  };
4170
+ var LSP_LOCAL_INSTALL_HINTS = {
4171
+ typescript: "bun add -d typescript-language-server typescript",
4172
+ vue: "bun add -d @vue/language-server",
4173
+ eslint: "bun add -d vscode-langservers-extracted",
4174
+ oxlint: "bun add -d oxlint",
4175
+ biome: "bun add -d @biomejs/biome",
4176
+ svelte: "bun add -d svelte-language-server",
4177
+ astro: "bun add -d @astrojs/language-server",
4178
+ bash: "bun add -d bash-language-server",
4179
+ "bash-ls": "bun add -d bash-language-server",
4180
+ "yaml-ls": "bun add -d yaml-language-server",
4181
+ php: "bun add -d intelephense",
4182
+ prisma: "bun add -d prisma",
4183
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
4184
+ pyright: "uv add --dev pyright",
4185
+ basedpyright: "uv add --dev basedpyright",
4186
+ ruff: "uv add --dev ruff",
4187
+ ty: "uv add --dev ty",
4188
+ "ruby-lsp": "bundle add ruby-lsp --group development"
4189
+ };
3599
4190
  var BUILTIN_SERVERS = {
3600
4191
  typescript: {
3601
4192
  command: ["typescript-language-server", "--stdio"],
@@ -3698,7 +4289,56 @@ var BUILTIN_SERVERS = {
3698
4289
  }
3699
4290
  };
3700
4291
 
4292
+ // ../lsp-core/src/lsp/server-install-state.ts
4293
+ import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync6, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
4294
+ import { dirname as dirname9 } from "node:path";
4295
+ function getInstallDecisionsPath() {
4296
+ return lspRequestContext().installDecisionsPath;
4297
+ }
4298
+ function loadInstallDecisions() {
4299
+ const path = getInstallDecisionsPath();
4300
+ if (!existsSync8(path))
4301
+ return {};
4302
+ try {
4303
+ const parsed = JSON.parse(readFileSync6(path, "utf8"));
4304
+ return isInstallDecisions(parsed) ? parsed : {};
4305
+ } catch {
4306
+ return {};
4307
+ }
4308
+ }
4309
+ function loadInstallDecision(serverId) {
4310
+ return loadInstallDecisions()[serverId];
4311
+ }
4312
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
4313
+ const decisions = loadInstallDecisions();
4314
+ decisions[serverId] = { decision, decidedAt };
4315
+ writeInstallDecisions(decisions);
4316
+ }
4317
+ function isInstallDecision(value) {
4318
+ return value === "declined" || value === "allowed";
4319
+ }
4320
+ function writeInstallDecisions(decisions) {
4321
+ const path = getInstallDecisionsPath();
4322
+ mkdirSync3(dirname9(path), { recursive: true });
4323
+ const tmpPath = `${path}.tmp`;
4324
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
4325
+ `, "utf8");
4326
+ renameSync2(tmpPath, path);
4327
+ }
4328
+ function isInstallDecisions(value) {
4329
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
4330
+ }
4331
+ function isInstallDecisionRecord(value) {
4332
+ if (!isRecord5(value))
4333
+ return false;
4334
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
4335
+ }
4336
+ function isRecord5(value) {
4337
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4338
+ }
4339
+
3701
4340
  // ../lsp-core/src/lsp/config-loader.ts
4341
+ import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
3702
4342
  function getProjectConfigPaths() {
3703
4343
  return lspRequestContext().projectConfigPaths;
3704
4344
  }
@@ -3706,10 +4346,10 @@ function getUserConfigPath() {
3706
4346
  return lspRequestContext().userConfigPath;
3707
4347
  }
3708
4348
  function loadJsonFile(path) {
3709
- if (!existsSync7(path))
4349
+ if (!existsSync9(path))
3710
4350
  return null;
3711
4351
  try {
3712
- const parsed = JSON.parse(readFileSync4(path, "utf-8"));
4352
+ const parsed = JSON.parse(readFileSync7(path, "utf-8"));
3713
4353
  return isConfigJson(parsed) ? parsed : null;
3714
4354
  } catch {
3715
4355
  return null;
@@ -3753,10 +4393,10 @@ function getMergedServers() {
3753
4393
  }
3754
4394
  if (seen.has(id))
3755
4395
  continue;
3756
- const server2 = createServerFromEntry(id, entry, source);
3757
- if (!server2)
4396
+ const server = createServerFromEntry(id, entry, source);
4397
+ if (!server)
3758
4398
  continue;
3759
- servers.push(server2);
4399
+ servers.push(server);
3760
4400
  seen.add(id);
3761
4401
  }
3762
4402
  }
@@ -3788,7 +4428,7 @@ function createServerFromEntry(id, entry, source) {
3788
4428
  if (source === "project") {
3789
4429
  if (!builtin)
3790
4430
  return null;
3791
- const server3 = createServer({
4431
+ const server = createServer({
3792
4432
  id,
3793
4433
  command: builtin.command,
3794
4434
  extensions: entry.extensions ?? builtin.extensions,
@@ -3796,35 +4436,35 @@ function createServerFromEntry(id, entry, source) {
3796
4436
  source
3797
4437
  });
3798
4438
  if (entry.initialization !== undefined) {
3799
- server3.initialization = entry.initialization;
4439
+ server.initialization = entry.initialization;
3800
4440
  }
3801
- return server3;
4441
+ return server;
3802
4442
  }
3803
4443
  if (entry.command && entry.extensions) {
3804
- const server3 = createServer({
4444
+ const server = createServer({
3805
4445
  id,
3806
4446
  command: entry.command,
3807
4447
  extensions: entry.extensions,
3808
4448
  priority: entry.priority ?? 0,
3809
4449
  source
3810
4450
  });
3811
- applyOptionalServerFields(server3, entry);
3812
- return server3;
4451
+ applyOptionalServerFields(server, entry);
4452
+ return server;
3813
4453
  }
3814
4454
  if (!builtin)
3815
4455
  return null;
3816
- const server2 = createServer({
4456
+ const server = createServer({
3817
4457
  id,
3818
4458
  command: entry.command ?? builtin.command,
3819
4459
  extensions: entry.extensions ?? builtin.extensions,
3820
4460
  priority: entry.priority ?? 0,
3821
4461
  source
3822
4462
  });
3823
- applyOptionalServerFields(server2, entry);
3824
- return server2;
4463
+ applyOptionalServerFields(server, entry);
4464
+ return server;
3825
4465
  }
3826
4466
  function createServer(input) {
3827
- const server2 = {
4467
+ const server = {
3828
4468
  id: input.id,
3829
4469
  command: input.command,
3830
4470
  extensions: input.extensions,
@@ -3832,19 +4472,19 @@ function createServer(input) {
3832
4472
  source: input.source
3833
4473
  };
3834
4474
  if (input.env !== undefined) {
3835
- server2.env = input.env;
4475
+ server.env = input.env;
3836
4476
  }
3837
4477
  if (input.initialization !== undefined) {
3838
- server2.initialization = input.initialization;
4478
+ server.initialization = input.initialization;
3839
4479
  }
3840
- return server2;
4480
+ return server;
3841
4481
  }
3842
- function applyOptionalServerFields(server2, entry) {
4482
+ function applyOptionalServerFields(server, entry) {
3843
4483
  if (entry.env !== undefined) {
3844
- server2.env = entry.env;
4484
+ server.env = entry.env;
3845
4485
  }
3846
4486
  if (entry.initialization !== undefined) {
3847
- server2.initialization = entry.initialization;
4487
+ server.initialization = entry.initialization;
3848
4488
  }
3849
4489
  }
3850
4490
  function isConfigJson(value) {
@@ -3894,64 +4534,165 @@ function getDisabledServerIds() {
3894
4534
  }
3895
4535
 
3896
4536
  // ../lsp-core/src/lsp/server-installation.ts
3897
- import { existsSync as existsSync8 } from "node:fs";
3898
- import { delimiter as delimiter3, join as join3 } from "node:path";
3899
- function isServerInstalled(command, _workingDirectory) {
3900
- if (command.length === 0)
3901
- return false;
3902
- const [cmd] = command;
3903
- if (!cmd)
3904
- return false;
3905
- if (cmd.includes("/") || cmd.includes("\\")) {
3906
- if (existsSync8(cmd))
3907
- return true;
4537
+ import { existsSync as existsSync10 } from "node:fs";
4538
+ import { delimiter as delimiter3, dirname as dirname10, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
4539
+ var LOCAL_BIN_RULES = [
4540
+ {
4541
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
4542
+ binDirs: [join4("node_modules", ".bin")]
4543
+ },
4544
+ {
4545
+ markers: [
4546
+ "pyproject.toml",
4547
+ "ty.toml",
4548
+ "requirements.txt",
4549
+ "setup.py",
4550
+ "setup.cfg",
4551
+ "Pipfile",
4552
+ "pyrightconfig.json",
4553
+ "ruff.toml",
4554
+ ".ruff.toml"
4555
+ ],
4556
+ binDirs: [
4557
+ join4(".venv", "bin"),
4558
+ join4(".venv", "Scripts"),
4559
+ join4("venv", "bin"),
4560
+ join4("venv", "Scripts"),
4561
+ join4(".env", "bin"),
4562
+ join4(".env", "Scripts")
4563
+ ]
4564
+ },
4565
+ {
4566
+ markers: ["Gemfile", "Gemfile.lock"],
4567
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4568
+ },
4569
+ {
4570
+ markers: ["go.mod", "go.sum", "go.work"],
4571
+ binDirs: ["bin"]
4572
+ }
4573
+ ];
4574
+ var resolutionCache = new Map;
4575
+ var probeCount = 0;
4576
+ function probe(path) {
4577
+ probeCount += 1;
4578
+ return existsSync10(path);
4579
+ }
4580
+ function executableSuffixes(platform, pathExt) {
4581
+ if (platform !== "win32")
4582
+ return [""];
4583
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4584
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4585
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4586
+ }
4587
+ function probeWithSuffixes(directory, command, suffixes) {
4588
+ for (const suffix of suffixes) {
4589
+ const candidate = join4(directory, command + suffix);
4590
+ if (probe(candidate))
4591
+ return candidate;
3908
4592
  }
3909
- const isWindows = process.platform === "win32";
3910
- let exts = [""];
3911
- if (isWindows) {
3912
- const pathExt = process.env["PATHEXT"] ?? "";
3913
- if (pathExt) {
3914
- const systemExts = pathExt.split(";").filter(Boolean);
3915
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
3916
- } else {
3917
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4593
+ return null;
4594
+ }
4595
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4596
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4597
+ let current = resolve7(workingDirectory);
4598
+ while (true) {
4599
+ for (const rule of LOCAL_BIN_RULES) {
4600
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
4601
+ continue;
4602
+ for (const binDir of rule.binDirs) {
4603
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4604
+ if (found !== null)
4605
+ return found;
4606
+ }
3918
4607
  }
4608
+ if (probe(join4(current, ".git")))
4609
+ return null;
4610
+ if (boundary !== undefined && current === boundary)
4611
+ return null;
4612
+ const parent = dirname10(current);
4613
+ if (parent === current)
4614
+ return null;
4615
+ current = parent;
3919
4616
  }
3920
- let pathEnv = process.env["PATH"] ?? "";
3921
- if (isWindows && !pathEnv) {
4617
+ }
4618
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4619
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4620
+ if (platform === "win32" && !pathEnv) {
3922
4621
  pathEnv = process.env["Path"] ?? "";
3923
4622
  }
3924
- const paths = pathEnv.split(delimiter3);
3925
- for (const p of paths) {
3926
- for (const suffix of exts) {
3927
- if (existsSync8(join3(p, cmd + suffix))) {
3928
- return true;
3929
- }
3930
- }
4623
+ for (const entry of pathEnv.split(delimiter3)) {
4624
+ if (entry.length === 0)
4625
+ continue;
4626
+ const found = probeWithSuffixes(entry, command, suffixes);
4627
+ if (found !== null)
4628
+ return found;
3931
4629
  }
3932
- if (cmd === "node")
3933
- return true;
3934
- return false;
4630
+ return null;
4631
+ }
4632
+ function resolveServerBinary(command, workingDirectory, options = {}) {
4633
+ if (command.length === 0)
4634
+ return null;
4635
+ const [cmd] = command;
4636
+ if (cmd === undefined || cmd.length === 0)
4637
+ return null;
4638
+ const platform = options.platform ?? process.platform;
4639
+ const suffixes = executableSuffixes(platform, options.pathExt);
4640
+ if (cmd.includes("/") || cmd.includes("\\")) {
4641
+ const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4642
+ return probe(explicit) ? explicit : null;
4643
+ }
4644
+ const cacheKey = JSON.stringify([
4645
+ workingDirectory ?? "",
4646
+ cmd,
4647
+ platform,
4648
+ options.stopAt ?? "",
4649
+ options.pathExt ?? "",
4650
+ options.pathEnv ?? process.env["PATH"] ?? ""
4651
+ ]);
4652
+ const cached = resolutionCache.get(cacheKey);
4653
+ if (cached !== undefined)
4654
+ return cached;
4655
+ let resolved = null;
4656
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
4657
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4658
+ }
4659
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4660
+ if (resolved === null && cmd === "node")
4661
+ resolved = cmd;
4662
+ resolutionCache.set(cacheKey, resolved);
4663
+ return resolved;
4664
+ }
4665
+ function isServerInstalled(command, workingDirectory, options = {}) {
4666
+ if (command.length === 0)
4667
+ return false;
4668
+ return resolveServerBinary(command, workingDirectory, options) !== null;
3935
4669
  }
3936
4670
 
3937
4671
  // ../lsp-core/src/lsp/server-resolution.ts
4672
+ function withResolvedCommand(command, binaryPath) {
4673
+ return [binaryPath, ...command.slice(1)];
4674
+ }
3938
4675
  function findServerForExtension(ext) {
3939
4676
  const servers = getMergedServers();
3940
- for (const server2 of servers) {
3941
- if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4677
+ const workingDirectory = contextCwd();
4678
+ for (const server of servers) {
4679
+ if (!server.extensions.includes(ext))
4680
+ continue;
4681
+ const binaryPath = resolveServerBinary(server.command, workingDirectory);
4682
+ if (binaryPath !== null) {
3942
4683
  const resolvedServer = {
3943
- id: server2.id,
3944
- command: server2.command,
3945
- extensions: server2.extensions,
3946
- priority: server2.priority
4684
+ id: server.id,
4685
+ command: withResolvedCommand(server.command, binaryPath),
4686
+ extensions: server.extensions,
4687
+ priority: server.priority
3947
4688
  };
3948
- if (server2.env !== undefined) {
4689
+ if (server.env !== undefined) {
3949
4690
  return {
3950
4691
  status: "found",
3951
4692
  server: {
3952
4693
  ...resolvedServer,
3953
- env: server2.env,
3954
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4694
+ env: server.env,
4695
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
3955
4696
  }
3956
4697
  };
3957
4698
  }
@@ -3959,20 +4700,20 @@ function findServerForExtension(ext) {
3959
4700
  status: "found",
3960
4701
  server: {
3961
4702
  ...resolvedServer,
3962
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4703
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
3963
4704
  }
3964
4705
  };
3965
4706
  }
3966
4707
  }
3967
- for (const server2 of servers) {
3968
- if (server2.extensions.includes(ext)) {
3969
- const installHint = LSP_INSTALL_HINTS[server2.id] ?? `Install '${server2.command[0]}' and ensure it's in your PATH`;
4708
+ for (const server of servers) {
4709
+ if (server.extensions.includes(ext)) {
4710
+ const installHint = LSP_INSTALL_HINTS[server.id] ?? `Install '${server.command[0]}' and ensure it's in your PATH`;
3970
4711
  return {
3971
4712
  status: "not_installed",
3972
4713
  server: {
3973
- id: server2.id,
3974
- command: server2.command,
3975
- extensions: server2.extensions
4714
+ id: server.id,
4715
+ command: server.command,
4716
+ extensions: server.extensions
3976
4717
  },
3977
4718
  installHint
3978
4719
  };
@@ -3988,20 +4729,21 @@ function findServerForExtension(ext) {
3988
4729
  function getAllServers() {
3989
4730
  const servers = getMergedServers();
3990
4731
  const disabled = getDisabledServerIds();
4732
+ const workingDirectory = contextCwd();
3991
4733
  const result = [];
3992
4734
  const seen = new Set;
3993
- for (const server2 of servers) {
3994
- if (seen.has(server2.id))
4735
+ for (const server of servers) {
4736
+ if (seen.has(server.id))
3995
4737
  continue;
3996
4738
  result.push({
3997
- id: server2.id,
3998
- installed: isServerInstalled(server2.command),
3999
- extensions: server2.extensions,
4739
+ id: server.id,
4740
+ installed: isServerInstalled(server.command, workingDirectory),
4741
+ extensions: server.extensions,
4000
4742
  disabled: false,
4001
- source: server2.source,
4002
- priority: server2.priority
4743
+ source: server.source,
4744
+ priority: server.priority
4003
4745
  });
4004
- seen.add(server2.id);
4746
+ seen.add(server.id);
4005
4747
  }
4006
4748
  for (const id of disabled) {
4007
4749
  if (seen.has(id))
@@ -4009,7 +4751,7 @@ function getAllServers() {
4009
4751
  const builtin = BUILTIN_SERVERS[id];
4010
4752
  result.push({
4011
4753
  id,
4012
- installed: builtin ? isServerInstalled(builtin.command) : false,
4754
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4013
4755
  extensions: builtin?.extensions ?? [],
4014
4756
  disabled: true,
4015
4757
  source: "disabled",
@@ -4020,10 +4762,9 @@ function getAllServers() {
4020
4762
  }
4021
4763
 
4022
4764
  // ../lsp-core/src/lsp/client-wrapper.ts
4023
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
4024
4765
  function isDirectoryPath(filePath) {
4025
4766
  try {
4026
- return statSync3(filePath).isDirectory();
4767
+ return statSync4(filePath).isDirectory();
4027
4768
  } catch {
4028
4769
  return false;
4029
4770
  }
@@ -4033,36 +4774,40 @@ function findWorkspaceRoot(filePath) {
4033
4774
  const abs = resolveReadablePathInsideContext(filePath);
4034
4775
  let dir = abs;
4035
4776
  if (!isDirectoryPath(dir)) {
4036
- dir = dirname6(dir);
4777
+ dir = dirname11(dir);
4037
4778
  }
4779
+ if (!isPathInside(cwd, abs))
4780
+ return findWorkspaceRootOutsideContext(dir);
4038
4781
  const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4782
+ let nearestPackageRoot;
4039
4783
  while (isPathInside(cwd, dir)) {
4040
4784
  const canonicalDir = existingDirectoryInsideContext(dir, cwd);
4041
4785
  if (canonicalDir !== undefined) {
4042
- for (const marker of WORKSPACE_MARKERS) {
4043
- if (existsSync9(join4(dir, marker))) {
4044
- return canonicalDir;
4045
- }
4786
+ if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
4787
+ return canonicalDir;
4788
+ }
4789
+ if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
4790
+ nearestPackageRoot = canonicalDir;
4046
4791
  }
4047
4792
  }
4048
4793
  if (dir === cwd)
4049
4794
  break;
4050
- dir = dirname6(dir);
4795
+ dir = dirname11(dir);
4051
4796
  }
4052
- return fallbackRoot;
4797
+ return nearestPackageRoot ?? fallbackRoot;
4798
+ }
4799
+ function hasProjectWorkspaceMarker(directory) {
4800
+ return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
4053
4801
  }
4054
4802
  function resolveReadablePathInsideContext(filePath) {
4055
4803
  const cwd = contextCwd();
4056
- const abs = resolve7(cwd, filePath);
4804
+ const abs = resolve8(cwd, filePath);
4057
4805
  if (isPathInside(cwd, abs))
4058
4806
  return abs;
4059
4807
  const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
4060
4808
  if (rebased !== undefined)
4061
4809
  return rebased;
4062
- const canonical = canonicalizeExistingOrNearestAncestor(abs);
4063
- if (isPathInside(cwd, canonical))
4064
- return canonical;
4065
- throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
4810
+ return canonicalizeExistingOrNearestAncestor(abs);
4066
4811
  }
4067
4812
  function resolvePathInsideContext(filePath) {
4068
4813
  const cwd = contextCwd();
@@ -4077,12 +4822,12 @@ function rebaseThroughCanonicalAncestor(path, cwd) {
4077
4822
  let current = path;
4078
4823
  const suffix = [];
4079
4824
  while (true) {
4080
- if (existsSync9(current)) {
4081
- const canonical = realpathSync4(current);
4825
+ if (existsSync11(current)) {
4826
+ const canonical = realpathSync5(current);
4082
4827
  if (isPathInside(cwd, canonical))
4083
- return suffix.length === 0 ? canonical : join4(canonical, ...suffix);
4828
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
4084
4829
  }
4085
- const parent = dirname6(current);
4830
+ const parent = dirname11(current);
4086
4831
  if (parent === current)
4087
4832
  return;
4088
4833
  suffix.unshift(basename3(current));
@@ -4090,10 +4835,10 @@ function rebaseThroughCanonicalAncestor(path, cwd) {
4090
4835
  }
4091
4836
  }
4092
4837
  function existingDirectoryInsideContext(directory, cwd) {
4093
- if (!existsSync9(directory))
4838
+ if (!existsSync11(directory))
4094
4839
  return;
4095
- const canonical = realpathSync4(directory);
4096
- if (!statSync3(canonical).isDirectory())
4840
+ const canonical = realpathSync5(directory);
4841
+ if (!statSync4(canonical).isDirectory())
4097
4842
  return;
4098
4843
  return isPathInside(cwd, canonical) ? canonical : undefined;
4099
4844
  }
@@ -4105,7 +4850,7 @@ function nearestExistingDirectoryInsideContext(directory, cwd) {
4105
4850
  return canonical;
4106
4851
  if (current === cwd)
4107
4852
  return;
4108
- current = dirname6(current);
4853
+ current = dirname11(current);
4109
4854
  }
4110
4855
  return;
4111
4856
  }
@@ -4132,33 +4877,46 @@ function formatServerLookupError(result) {
4132
4877
  ].join(`
4133
4878
  `);
4134
4879
  }
4880
+ function formatInstallOptions(serverId, installHint) {
4881
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
4882
+ if (localHint === undefined) {
4883
+ return ["To install, run:", ` ${installHint}`];
4884
+ }
4885
+ return [
4886
+ "To install in THIS repository (preferred — no global install needed):",
4887
+ ` ${localHint}`,
4888
+ "",
4889
+ "Or install it globally:",
4890
+ ` ${installHint}`
4891
+ ];
4892
+ }
4135
4893
  function formatNotInstalled(result) {
4136
- const { server: server2, installHint } = result;
4137
- const extensions = server2.extensions.join(", ");
4138
- const decision = loadInstallDecision(server2.id)?.decision;
4894
+ const { server, installHint } = result;
4895
+ const extensions = server.extensions.join(", ");
4896
+ const decision = loadInstallDecision(server.id)?.decision;
4139
4897
  const context = lspRequestContext();
4140
4898
  if (decision === "declined") {
4141
- return `LSP server '${server2.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
4899
+ return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
4142
4900
  }
4143
4901
  const header = [
4144
- `LSP server '${server2.id}' for ${extensions} is NOT INSTALLED.`,
4902
+ `LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
4145
4903
  "",
4146
- `Command not found: ${server2.command[0]}`,
4904
+ `Command not found: ${server.command[0]}`,
4147
4905
  ""
4148
4906
  ];
4907
+ const installOptions = formatInstallOptions(server.id, installHint);
4149
4908
  if (decision === "allowed") {
4150
4909
  return [
4151
4910
  ...header,
4152
4911
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4153
- ` ${installHint}`
4912
+ ...installOptions.slice(1)
4154
4913
  ].join(`
4155
4914
  `);
4156
4915
  }
4157
4916
  if (!context.capabilities.installDecisionTool) {
4158
4917
  return [
4159
4918
  ...header,
4160
- "To install, run:",
4161
- ` ${installHint}`,
4919
+ ...installOptions,
4162
4920
  "",
4163
4921
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4164
4922
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4167,13 +4925,12 @@ function formatNotInstalled(result) {
4167
4925
  }
4168
4926
  return [
4169
4927
  ...header,
4170
- "To install, run:",
4171
- ` ${installHint}`,
4928
+ ...installOptions,
4172
4929
  "",
4173
4930
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4174
4931
  "- If the user agrees: run the install command above, then retry this tool.",
4175
4932
  "- If the user declines, OR has NOT explicitly asked for LSP installation:",
4176
- ` call lsp_install_decision { server_id: "${server2.id}", decision: "declined" },`,
4933
+ ` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
4177
4934
  ` which writes to ${context.installDecisionsPath},`,
4178
4935
  " then ignore this message and proceed WITHOUT LSP."
4179
4936
  ].join(`
@@ -4197,34 +4954,34 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4197
4954
  if (result.status !== "found") {
4198
4955
  throw new LspServerLookupError(formatServerLookupError(result), result);
4199
4956
  }
4200
- const server2 = result.server;
4957
+ const server = result.server;
4201
4958
  const root = findWorkspaceRoot(absPath);
4202
4959
  const manager = options.manager ?? getLspManager();
4203
4960
  const acquireAndCall = async (allowRetry) => {
4204
- const client = await manager.getClient(root, server2, options.signal);
4961
+ const client = await manager.getClient(root, server, options.signal);
4205
4962
  try {
4206
4963
  return await fn(client, root, absPath);
4207
4964
  } catch (err) {
4208
4965
  if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4209
- manager.invalidateClient(root, server2.id, client);
4966
+ manager.invalidateClient(root, server.id, client);
4210
4967
  return acquireAndCall(false);
4211
4968
  }
4212
4969
  if (err instanceof LspRequestTimeoutError) {
4213
- if (manager.isServerInitializing(root, server2.id)) {
4970
+ if (manager.isServerInitializing(root, server.id)) {
4214
4971
  throw new LspServerInitializingError(err);
4215
4972
  }
4216
4973
  }
4217
4974
  throw err;
4218
4975
  } finally {
4219
- manager.releaseClient(root, server2.id);
4976
+ manager.releaseClient(root, server.id);
4220
4977
  }
4221
4978
  };
4222
4979
  return acquireAndCall(true);
4223
4980
  }
4224
4981
 
4225
4982
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4226
- import { existsSync as existsSync10, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4227
- import { join as join5, resolve as resolve8 } from "node:path";
4983
+ import { existsSync as existsSync12, lstatSync as lstatSync6, readdirSync as readdirSync3 } from "node:fs";
4984
+ import { join as join6, resolve as resolve9 } from "node:path";
4228
4985
 
4229
4986
  // ../lsp-core/src/lsp/formatters.ts
4230
4987
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -4239,10 +4996,10 @@ function uriToPath(uri) {
4239
4996
  }
4240
4997
  function formatLocation(loc) {
4241
4998
  if ("targetUri" in loc) {
4242
- const uri2 = uriToPath(loc.targetUri);
4243
- const line2 = loc.targetRange.start.line + 1;
4244
- const char2 = loc.targetRange.start.character;
4245
- return `${uri2}:${line2}:${char2}`;
4999
+ const uri = uriToPath(loc.targetUri);
5000
+ const line = loc.targetRange.start.line + 1;
5001
+ const char = loc.targetRange.start.character;
5002
+ return `${uri}:${line}:${char}`;
4246
5003
  }
4247
5004
  const uri = uriToPath(loc.uri);
4248
5005
  const line = loc.range.start.line + 1;
@@ -4354,10 +5111,10 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
4354
5111
  for (const entry of entries) {
4355
5112
  if (files.length >= maxFiles)
4356
5113
  return;
4357
- const fullPath = join5(currentDir, entry);
5114
+ const fullPath = join6(currentDir, entry);
4358
5115
  let stat;
4359
5116
  try {
4360
- stat = lstatSync4(fullPath);
5117
+ stat = lstatSync6(fullPath);
4361
5118
  } catch {
4362
5119
  continue;
4363
5120
  }
@@ -4379,15 +5136,15 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4379
5136
  if (!extension.startsWith(".")) {
4380
5137
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4381
5138
  }
4382
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4383
- if (!existsSync10(absDir)) {
5139
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
5140
+ if (!existsSync12(absDir)) {
4384
5141
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4385
5142
  }
4386
5143
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
4387
5144
  if (serverResult.status !== "found") {
4388
5145
  throw new LspServerLookupError(formatServerLookupError(serverResult));
4389
5146
  }
4390
- const server2 = serverResult.server;
5147
+ const server = serverResult.server;
4391
5148
  const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
4392
5149
  const wasCapped = allFiles.length > maxFiles;
4393
5150
  const filesToProcess = allFiles.slice(0, maxFiles);
@@ -4407,7 +5164,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4407
5164
  const fileErrors = [];
4408
5165
  const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
4409
5166
  options.signal?.throwIfAborted();
4410
- const client = await manager.getClient(root, server2, options.signal);
5167
+ const client = await manager.getClient(root, server, options.signal);
4411
5168
  try {
4412
5169
  let nextIndex = 0;
4413
5170
  const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
@@ -4435,7 +5192,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4435
5192
  });
4436
5193
  await Promise.all(workers);
4437
5194
  } finally {
4438
- manager.releaseClient(root, server2.id);
5195
+ manager.releaseClient(root, server.id);
4439
5196
  }
4440
5197
  const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
4441
5198
  const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
@@ -4466,8 +5223,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4466
5223
  }
4467
5224
 
4468
5225
  // ../lsp-core/src/lsp/infer-extension.ts
4469
- import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
4470
- import { join as join6 } from "node:path";
5226
+ import { lstatSync as lstatSync7, readdirSync as readdirSync4 } from "node:fs";
5227
+ import { join as join7 } from "node:path";
4471
5228
  var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
4472
5229
  var MAX_SCAN_ENTRIES = 500;
4473
5230
  function inferExtensionFromDirectory(directory) {
@@ -4485,10 +5242,10 @@ function inferExtensionFromDirectory(directory) {
4485
5242
  for (const entry of entries) {
4486
5243
  if (scanned >= MAX_SCAN_ENTRIES)
4487
5244
  return;
4488
- const fullPath = join6(dir, entry);
5245
+ const fullPath = join7(dir, entry);
4489
5246
  let stat;
4490
5247
  try {
4491
- stat = lstatSync5(fullPath);
5248
+ stat = lstatSync7(fullPath);
4492
5249
  } catch {
4493
5250
  continue;
4494
5251
  }
@@ -4644,8 +5401,8 @@ function clientOptions(signal) {
4644
5401
  }
4645
5402
 
4646
5403
  // ../lsp-core/src/tools/result.ts
4647
- function text(text2, details, isError = false) {
4648
- return { content: [{ type: "text", text: text2 }], details, isError };
5404
+ function text(text, details, isError = false) {
5405
+ return { content: [{ type: "text", text }], details, isError };
4649
5406
  }
4650
5407
 
4651
5408
  // ../lsp-core/src/tools/diagnostics.ts
@@ -4665,7 +5422,7 @@ async function executeLspDiagnostics(params, signal) {
4665
5422
  const extension = inferExtensionFromDirectory(absPath);
4666
5423
  if (!extension) {
4667
5424
  const message = `No supported source files found in directory: ${absPath}`;
4668
- const details3 = {
5425
+ const details = {
4669
5426
  filePath,
4670
5427
  severity,
4671
5428
  mode: "directory",
@@ -4675,24 +5432,24 @@ async function executeLspDiagnostics(params, signal) {
4675
5432
  error: message,
4676
5433
  errorKind: "no_files"
4677
5434
  };
4678
- return text(message, details3);
5435
+ return text(message, details);
4679
5436
  }
4680
- const output2 = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
4681
- const details2 = {
5437
+ const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
5438
+ const details = {
4682
5439
  filePath,
4683
5440
  severity,
4684
5441
  mode: "directory",
4685
5442
  diagnostics: [],
4686
- totalDiagnostics: output2.totalDiagnostics,
5443
+ totalDiagnostics: output.totalDiagnostics,
4687
5444
  truncated: false,
4688
- fileFailures: [...output2.fileFailures]
5445
+ fileFailures: [...output.fileFailures]
4689
5446
  };
4690
- return text(output2.output, details2);
5447
+ return text(output.output, details);
4691
5448
  }
4692
5449
  const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
4693
5450
  if (result.transientError) {
4694
5451
  const message = result.transientError.message;
4695
- const details2 = {
5452
+ const details = {
4696
5453
  filePath,
4697
5454
  severity,
4698
5455
  mode: "file",
@@ -4702,7 +5459,7 @@ async function executeLspDiagnostics(params, signal) {
4702
5459
  error: message,
4703
5460
  errorKind: result.transientError.kind
4704
5461
  };
4705
- return text(message, details2, true);
5462
+ return text(message, details, true);
4706
5463
  }
4707
5464
  const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
4708
5465
  const total = diagnostics.length;
@@ -4736,6 +5493,96 @@ async function executeLspDiagnostics(params, signal) {
4736
5493
  throw error;
4737
5494
  }
4738
5495
  }
5496
+ // ../lsp-core/src/lsp/format-document.ts
5497
+ import { readFileSync as readFileSync8, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
5498
+ var DEFAULT_FORMATTING_OPTIONS = {
5499
+ tabSize: 4,
5500
+ insertSpaces: false,
5501
+ trimTrailingWhitespace: true,
5502
+ insertFinalNewline: true,
5503
+ trimFinalNewlines: true
5504
+ };
5505
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
5506
+ async function formatDocumentWithClient(client, filePath, options = {}) {
5507
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
5508
+ if (edits === null)
5509
+ return { status: "unavailable", reason: "capability_not_advertised" };
5510
+ if (edits.length === 0)
5511
+ return UNCHANGED;
5512
+ const before = readFileSync8(filePath, "utf-8");
5513
+ const normalized = normalizeTextEdits(before, edits, 0);
5514
+ if (normalized.text === before)
5515
+ return UNCHANGED;
5516
+ writeAtomically(filePath, normalized.text);
5517
+ await client.openFile(filePath);
5518
+ return {
5519
+ status: "formatted",
5520
+ ...lineDelta(normalized.edits)
5521
+ };
5522
+ }
5523
+ function lineDelta(edits) {
5524
+ let linesAdded = 0;
5525
+ let linesRemoved = 0;
5526
+ for (const edit of edits) {
5527
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
5528
+ linesAdded += edit.newText.split(`
5529
+ `).length;
5530
+ }
5531
+ return { linesAdded, linesRemoved };
5532
+ }
5533
+ function writeAtomically(filePath, content) {
5534
+ const tempPath = `${filePath}.omo-format.tmp`;
5535
+ writeFileSync3(tempPath, content, "utf-8");
5536
+ try {
5537
+ renameSync3(tempPath, filePath);
5538
+ } catch (error) {
5539
+ try {
5540
+ unlinkSync4(tempPath);
5541
+ } catch {}
5542
+ throw error;
5543
+ }
5544
+ }
5545
+
5546
+ // ../lsp-core/src/tools/format.ts
5547
+ async function executeLspFormat(params, signal) {
5548
+ const filePath = requireString(params, "filePath");
5549
+ try {
5550
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
5551
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
5552
+ } catch (error) {
5553
+ const missingDependency = missingDependencyResult(error, {
5554
+ filePath,
5555
+ status: "unavailable",
5556
+ reason: "server_unavailable",
5557
+ linesAdded: 0,
5558
+ linesRemoved: 0
5559
+ });
5560
+ if (missingDependency)
5561
+ return missingDependency;
5562
+ throw error;
5563
+ }
5564
+ }
5565
+ function formatDetails(filePath, result) {
5566
+ if (result.status === "unavailable") {
5567
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5568
+ }
5569
+ return {
5570
+ filePath,
5571
+ status: result.status,
5572
+ linesAdded: result.linesAdded,
5573
+ linesRemoved: result.linesRemoved
5574
+ };
5575
+ }
5576
+ function describeResult(filePath, result) {
5577
+ if (result.status === "unavailable") {
5578
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5579
+ }
5580
+ if (result.status === "unchanged") {
5581
+ return `Already formatted: ${filePath}`;
5582
+ }
5583
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5584
+ }
5585
+
4739
5586
  // ../lsp-core/src/tools/install-decision.ts
4740
5587
  async function executeLspInstallDecision(params) {
4741
5588
  const serverId = requireString(params, "server_id");
@@ -4743,7 +5590,7 @@ async function executeLspInstallDecision(params) {
4743
5590
  if (!isInstallDecision(decision)) {
4744
5591
  return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
4745
5592
  }
4746
- const serverIds = [...new Set(getMergedServers().map((server2) => server2.id))];
5593
+ const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
4747
5594
  if (!serverIds.includes(serverId)) {
4748
5595
  const preview = serverIds.slice(0, 20).join(", ");
4749
5596
  return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
@@ -4883,10 +5730,10 @@ function objectSchema(properties, required = []) {
4883
5730
  async function executeLspStatus() {
4884
5731
  const servers = getAllServers();
4885
5732
  const snapshots = getLspManager().getSnapshot();
4886
- const installed = servers.filter((server2) => server2.installed && !server2.disabled);
4887
- const configuredLines = servers.map((server2) => {
4888
- const state = server2.disabled ? "disabled" : server2.installed ? "installed" : "missing";
4889
- return `- ${server2.id}: ${state}; source=${server2.source}; extensions=${server2.extensions.join(", ")}`;
5733
+ const installed = servers.filter((server) => server.installed && !server.disabled);
5734
+ const configuredLines = servers.map((server) => {
5735
+ const state = server.disabled ? "disabled" : server.installed ? "installed" : "missing";
5736
+ return `- ${server.id}: ${state}; source=${server.source}; extensions=${server.extensions.join(", ")}`;
4890
5737
  });
4891
5738
  const activeLines = snapshots.map((snapshot) => {
4892
5739
  const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
@@ -4929,8 +5776,8 @@ async function executeLspSymbols(params, signal) {
4929
5776
  errorKind: "missing_query"
4930
5777
  });
4931
5778
  }
4932
- const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
4933
- return formatSymbolsResult(filePath, scope, symbols2, limit, query);
5779
+ const symbols = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
5780
+ return formatSymbolsResult(filePath, scope, symbols, limit, query);
4934
5781
  }
4935
5782
  const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
4936
5783
  return formatSymbolsResult(filePath, scope, symbols, limit);
@@ -5068,6 +5915,16 @@ var LSP_MCP_TOOLS = [
5068
5915
  }, ["filePath", "line", "character", "newName"]),
5069
5916
  execute: executeLspRename
5070
5917
  },
5918
+ {
5919
+ name: "format",
5920
+ aliases: ["lsp_format"],
5921
+ title: "LSP Format",
5922
+ description: "Format a source file with its language server and write the returned edits to disk.",
5923
+ inputSchema: objectSchema({
5924
+ filePath: { type: "string", description: "Source file path to format." }
5925
+ }, ["filePath"]),
5926
+ execute: executeLspFormat
5927
+ },
5071
5928
  {
5072
5929
  name: "install_decision",
5073
5930
  aliases: ["lsp_install_decision"],
@@ -5107,7 +5964,7 @@ async function handleLspMcpRequest(input, options = {}) {
5107
5964
  if (!isPlainRecord(input)) {
5108
5965
  return errorResponse(null, -32600, "Invalid Request");
5109
5966
  }
5110
- const id = jsonRpcId(input["id"]);
5967
+ const id = jsonRpcId2(input["id"]);
5111
5968
  const method = input["method"];
5112
5969
  if (method === "notifications/initialized")
5113
5970
  return;
@@ -5167,11 +6024,11 @@ function requestedProtocolVersion(params) {
5167
6024
  // src/daemon-client.ts
5168
6025
  import { connect } from "node:net";
5169
6026
  import { homedir as homedir3 } from "node:os";
5170
- import { join as join7 } from "node:path";
6027
+ import { join as join8 } from "node:path";
6028
+ import { setTimeout as delay } from "node:timers/promises";
5171
6029
 
5172
6030
  // src/daemon-request-error.ts
5173
6031
  class DaemonRequestError extends Error {
5174
- requestWritten;
5175
6032
  constructor(message, requestWritten) {
5176
6033
  super(message);
5177
6034
  this.name = "DaemonRequestError";
@@ -5194,7 +6051,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
5194
6051
  }
5195
6052
 
5196
6053
  class DaemonRequestTimedOutError extends DaemonRequestError {
5197
- timeoutMs;
5198
6054
  constructor(requestWritten, timeoutMs) {
5199
6055
  super("daemon request timed out", requestWritten);
5200
6056
  this.name = "DaemonRequestTimedOutError";
@@ -5211,243 +6067,46 @@ function daemonFailureResult(paths, error) {
5211
6067
  return daemonUnreachableResult(paths, error);
5212
6068
  }
5213
6069
  function daemonCancelledResult(paths) {
5214
- const text2 = [
6070
+ const text = [
5215
6071
  "LSP daemon request cancelled: the caller aborted this request (for example, the turn was interrupted).",
5216
6072
  "The daemon stays available; no LSP work was applied. Retry when you are ready.",
5217
6073
  `Socket: ${paths.socket}`
5218
6074
  ].join(`
5219
6075
  `);
5220
- return { content: [{ type: "text", text: text2 }], isError: true };
6076
+ return { content: [{ type: "text", text }], isError: true };
5221
6077
  }
5222
6078
  function daemonTimedOutResult(paths, timeoutMs) {
5223
- const text2 = [
6079
+ const text = [
5224
6080
  `LSP daemon request timed out after ${timeoutMs}ms: the daemon did not respond in time.`,
5225
- "The daemon stays available but may be busy. Retry when you are ready.",
5226
- `Socket: ${paths.socket}`,
5227
- `Logs: ${paths.log}`
5228
- ].join(`
5229
- `);
5230
- return { content: [{ type: "text", text: text2 }], isError: true };
5231
- }
5232
- function daemonUnreachableResult(paths, error) {
5233
- const text2 = [
5234
- `LSP daemon unreachable: ${errorText(error)}.`,
5235
- "The MCP server is a thin proxy and never runs language servers in-process.",
5236
- `Socket: ${paths.socket}`,
5237
- `Logs: ${paths.log}`,
5238
- "The daemon is auto-started on demand and will be retried on the next request."
5239
- ].join(`
5240
- `);
5241
- return { content: [{ type: "text", text: text2 }], isError: true };
5242
- }
5243
- function errorText(error) {
5244
- return error instanceof Error ? error.message : String(error);
5245
- }
5246
-
5247
- // src/ensure-daemon.ts
5248
- import { spawn as spawn2 } from "node:child_process";
5249
- import { closeSync as closeSync2, existsSync as existsSync11, mkdirSync as mkdirSync3, openSync as openSync2, writeSync as writeSync2 } from "node:fs";
5250
- import { Socket } from "node:net";
5251
- import { dirname as dirname8, isAbsolute as isAbsolute4 } from "node:path";
5252
- import { argv0, execPath } from "node:process";
5253
-
5254
- // src/ipc-protocol.ts
5255
- import { randomBytes, timingSafeEqual } from "node:crypto";
5256
- import {
5257
- chmodSync,
5258
- closeSync,
5259
- constants,
5260
- fchmodSync,
5261
- fstatSync,
5262
- lstatSync as lstatSync6,
5263
- mkdirSync as mkdirSync2,
5264
- openSync,
5265
- readFileSync as readFileSync5,
5266
- unlinkSync,
5267
- writeSync
5268
- } from "node:fs";
5269
- import { dirname as dirname7 } from "node:path";
5270
- var OMO_DAEMON_PROTOCOL_VERSION = 1;
5271
- var AUTH_ERROR_CODE = -32001;
5272
- var PROTOCOL_ERROR_CODE = -32002;
5273
- var AUTH_TOKEN_BYTES = 32;
5274
-
5275
- class UnsafePrivateDirectoryError extends Error {
5276
- path;
5277
- reason;
5278
- name = "UnsafePrivateDirectoryError";
5279
- code = "unsafe_private_directory";
5280
- constructor(path, reason) {
5281
- super(`unsafe private directory ${path}: ${reason}`);
5282
- this.path = path;
5283
- this.reason = reason;
5284
- }
5285
- }
5286
- function authEnvelope(token) {
5287
- return { protocolVersion: OMO_DAEMON_PROTOCOL_VERSION, token };
5288
- }
5289
- function readAuthToken(paths) {
5290
- try {
5291
- const token = readFileSync5(paths.auth, "utf8").trim();
5292
- return token.length > 0 ? token : null;
5293
- } catch (error) {
5294
- if (error instanceof Error)
5295
- return null;
5296
- throw error;
5297
- }
5298
- }
5299
- function readOrCreateAuthToken(paths) {
5300
- const existing = readAuthToken(paths);
5301
- if (existing)
5302
- return existing;
5303
- return createAuthToken(paths);
5304
- }
5305
- function rotateAuthToken(paths) {
5306
- try {
5307
- unlinkSync(paths.auth);
5308
- } catch (error) {
5309
- if (!(error instanceof Error))
5310
- throw error;
5311
- }
5312
- return createAuthToken(paths);
5313
- }
5314
- function authenticateMessage(raw, expectedToken) {
5315
- const id = jsonRpcId2(raw);
5316
- if (!isPlainRecord(raw))
5317
- return authError(id);
5318
- const params = raw["params"];
5319
- if (!isPlainRecord(params))
5320
- return authError(id);
5321
- const envelope = params["_omo"];
5322
- if (!isPlainRecord(envelope))
5323
- return authError(id);
5324
- const protocolVersion = envelope["protocolVersion"];
5325
- if (protocolVersion !== OMO_DAEMON_PROTOCOL_VERSION)
5326
- return protocolError(id);
5327
- const token = envelope["token"];
5328
- if (typeof token !== "string" || !tokenMatches(token, expectedToken))
5329
- return authError(id);
5330
- const cleanParams = { ...params };
5331
- delete cleanParams["_omo"];
5332
- return { input: { ...raw, params: cleanParams }, id, method: typeof raw["method"] === "string" ? raw["method"] : undefined };
5333
- }
5334
- function isAuthErrorResponse(message) {
5335
- if (!isPlainRecord(message))
5336
- return false;
5337
- const error = message["error"];
5338
- if (!isPlainRecord(error))
5339
- return false;
5340
- const data = error["data"];
5341
- return error["code"] === AUTH_ERROR_CODE && isPlainRecord(data) && data["code"] === "daemon_authentication_failed";
5342
- }
5343
- function writePrivateFile(path, data) {
5344
- const fd = openSync(path, "w", 384);
5345
- try {
5346
- writeSync(fd, data);
5347
- } finally {
5348
- closeSync(fd);
5349
- }
5350
- setPrivateFileMode(path);
5351
- }
5352
- function ensurePrivateDirectory(path, options = {}) {
5353
- try {
5354
- mkdirSync2(path, { recursive: true, mode: 448 });
5355
- } catch (error) {
5356
- if (errorCode2(error) !== "EEXIST")
5357
- throw error;
5358
- }
5359
- if (process.platform === "win32")
5360
- return;
5361
- const before = validatePrivateDirectory(path, options);
5362
- const fd = openSync(path, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
5363
- try {
5364
- fchmodSync(fd, 448);
5365
- const after = validatePrivateDirectory(path, options);
5366
- const openStats = fstatSync(fd);
5367
- if (!sameDirectory(before, after) || !sameDirectory(before, openStats)) {
5368
- throw new UnsafePrivateDirectoryError(path, "changed_during_chmod");
5369
- }
5370
- } finally {
5371
- closeSync(fd);
5372
- }
5373
- }
5374
- function setPrivateFileMode(path) {
5375
- if (process.platform !== "win32")
5376
- chmodSync(path, 384);
5377
- }
5378
- function createAuthToken(paths) {
5379
- ensurePrivateDirectory(dirname7(paths.auth));
5380
- const token = randomBytes(AUTH_TOKEN_BYTES).toString("base64url");
5381
- let fd;
5382
- try {
5383
- fd = openSync(paths.auth, "wx", 384);
5384
- } catch (error) {
5385
- if (errorCode2(error) === "EEXIST") {
5386
- const existing = readAuthToken(paths);
5387
- if (existing)
5388
- return existing;
5389
- }
5390
- throw error;
5391
- }
5392
- try {
5393
- writeSync(fd, `${token}
5394
- `);
5395
- } finally {
5396
- closeSync(fd);
5397
- }
5398
- setPrivateFileMode(paths.auth);
5399
- return token;
5400
- }
5401
- function errorCode2(error) {
5402
- if (!error || typeof error !== "object" || !("code" in error))
5403
- return;
5404
- const code = Reflect.get(error, "code");
5405
- return typeof code === "string" ? code : undefined;
5406
- }
5407
- function validatePrivateDirectory(path, options) {
5408
- const stats = options.lstat ? options.lstat(path) : lstatPrivateDirectory(path);
5409
- if (stats.isSymbolicLink())
5410
- throw new UnsafePrivateDirectoryError(path, "symlink");
5411
- if (!stats.isDirectory())
5412
- throw new UnsafePrivateDirectoryError(path, "not_directory");
5413
- const currentUid = options.currentUid ? options.currentUid() : process.getuid?.();
5414
- if (currentUid !== undefined && stats.uid !== currentUid) {
5415
- throw new UnsafePrivateDirectoryError(path, "wrong_owner");
5416
- }
5417
- return stats;
5418
- }
5419
- function lstatPrivateDirectory(path) {
5420
- return lstatSync6(path);
5421
- }
5422
- function sameDirectory(a, b) {
5423
- return a.dev === b.dev && a.ino === b.ino;
5424
- }
5425
- function tokenMatches(candidate, expected) {
5426
- const candidateBytes = Buffer.from(candidate);
5427
- const expectedBytes = Buffer.from(expected);
5428
- return candidateBytes.length === expectedBytes.length && timingSafeEqual(candidateBytes, expectedBytes);
5429
- }
5430
- function jsonRpcId2(raw) {
5431
- if (!isPlainRecord(raw))
5432
- return null;
5433
- const id = raw["id"];
5434
- return typeof id === "string" || typeof id === "number" || id === null ? id : null;
6081
+ "The daemon stays available but may be busy. Retry when you are ready.",
6082
+ `Socket: ${paths.socket}`,
6083
+ `Logs: ${paths.log}`
6084
+ ].join(`
6085
+ `);
6086
+ return { content: [{ type: "text", text }], isError: true };
5435
6087
  }
5436
- function authError(id) {
5437
- return {
5438
- jsonrpc: "2.0",
5439
- id,
5440
- error: { code: AUTH_ERROR_CODE, message: "daemon authentication failed", data: { code: "daemon_authentication_failed" } }
5441
- };
6088
+ function daemonUnreachableResult(paths, error) {
6089
+ const text = [
6090
+ `LSP daemon unreachable: ${errorText(error)}.`,
6091
+ "The MCP server is a thin proxy and never runs language servers in-process.",
6092
+ `Socket: ${paths.socket}`,
6093
+ `Logs: ${paths.log}`,
6094
+ "The daemon is auto-started on demand and will be retried on the next request."
6095
+ ].join(`
6096
+ `);
6097
+ return { content: [{ type: "text", text }], isError: true };
5442
6098
  }
5443
- function protocolError(id) {
5444
- return {
5445
- jsonrpc: "2.0",
5446
- id,
5447
- error: { code: PROTOCOL_ERROR_CODE, message: "daemon protocol mismatch", data: { code: "daemon_protocol_mismatch" } }
5448
- };
6099
+ function errorText(error) {
6100
+ return error instanceof Error ? error.message : String(error);
5449
6101
  }
5450
6102
 
6103
+ // src/ensure-daemon.ts
6104
+ import { spawn as spawn2 } from "node:child_process";
6105
+ import { closeSync as closeSync3, existsSync as existsSync13, mkdirSync as mkdirSync4, openSync as openSync3, writeSync as writeSync3 } from "node:fs";
6106
+ import { Socket } from "node:net";
6107
+ import { dirname as dirname12, isAbsolute as isAbsolute5 } from "node:path";
6108
+ import { argv0, execPath } from "node:process";
6109
+
5451
6110
  // src/paths.ts
5452
6111
  import { createHash as createHash2 } from "node:crypto";
5453
6112
  import { createRequire } from "node:module";
@@ -5456,28 +6115,26 @@ import * as path from "node:path";
5456
6115
  import { fileURLToPath as fileURLToPath3 } from "node:url";
5457
6116
 
5458
6117
  // src/runtime-contract.ts
5459
- import { statSync as statSync4 } from "node:fs";
5460
- import { isAbsolute as isAbsolute3 } from "node:path";
6118
+ import { statSync as statSync5 } from "node:fs";
6119
+ import { isAbsolute as isAbsolute4 } from "node:path";
5461
6120
  var OMO_LSP_DAEMON_DIR = "OMO_LSP_DAEMON_DIR";
5462
6121
  var OMO_LSP_DAEMON_CLI = "OMO_LSP_DAEMON_CLI";
5463
6122
  var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
5464
6123
  var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
5465
6124
 
5466
6125
  class InvalidRuntimeOverrideError extends Error {
5467
- code = "invalid_runtime_override";
5468
- reason;
5469
6126
  constructor(reason, message) {
5470
6127
  super(message);
6128
+ this.code = "invalid_runtime_override";
5471
6129
  this.name = "InvalidRuntimeOverrideError";
5472
6130
  this.reason = reason;
5473
6131
  }
5474
6132
  }
5475
6133
 
5476
6134
  class InvalidDaemonVersionError extends Error {
5477
- code = "invalid_daemon_version";
5478
- version;
5479
6135
  constructor(version) {
5480
6136
  super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
6137
+ this.code = "invalid_daemon_version";
5481
6138
  this.name = "InvalidDaemonVersionError";
5482
6139
  this.version = version;
5483
6140
  }
@@ -5496,17 +6153,17 @@ function resolveDaemonRuntime(env, defaults) {
5496
6153
  throw new InvalidRuntimeOverrideError("paired_values_required", `${OMO_LSP_DAEMON_CLI} and ${OMO_LSP_DAEMON_VERSION} must be set together`);
5497
6154
  }
5498
6155
  if (!hasCliOverride || !hasVersionOverride) {
5499
- if (!isAbsolute3(defaults.cliPath)) {
6156
+ if (!isAbsolute4(defaults.cliPath)) {
5500
6157
  throw new InvalidRuntimeOverrideError("packaged_cli_must_be_absolute", "Packaged LSP daemon CLI path must be absolute");
5501
6158
  }
5502
6159
  return { cliPath: defaults.cliPath, version: validateDaemonVersion(defaults.version) };
5503
6160
  }
5504
- if (!isAbsolute3(cliOverride)) {
6161
+ if (!isAbsolute4(cliOverride)) {
5505
6162
  throw new InvalidRuntimeOverrideError("cli_must_be_absolute", `${OMO_LSP_DAEMON_CLI} must be an absolute path to an existing regular file`);
5506
6163
  }
5507
6164
  let cliStats;
5508
6165
  try {
5509
- cliStats = statSync4(cliOverride);
6166
+ cliStats = statSync5(cliOverride);
5510
6167
  } catch (error) {
5511
6168
  if (!(error instanceof Error))
5512
6169
  throw error;
@@ -5523,10 +6180,9 @@ var requireFromHere = createRequire(import.meta.url);
5523
6180
  var MAX_SOCKET_PATH_LENGTH = 100;
5524
6181
 
5525
6182
  class InvalidDaemonDirectoryError extends Error {
5526
- code = "invalid_daemon_directory";
5527
- directory;
5528
6183
  constructor(directory) {
5529
6184
  super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
6185
+ this.code = "invalid_daemon_directory";
5530
6186
  this.name = "InvalidDaemonDirectoryError";
5531
6187
  this.directory = directory;
5532
6188
  }
@@ -5641,9 +6297,11 @@ function createLineDecoder(onMessage, onParseError) {
5641
6297
  }
5642
6298
 
5643
6299
  // src/ensure-daemon.ts
5644
- var PROBE_TIMEOUT_MS = 500;
6300
+ var PROBE_TIMEOUT_MS = 2000;
5645
6301
  var DEFAULT_READY_TIMEOUT_MS = 5000;
5646
6302
  var DEFAULT_POLL_INTERVAL_MS = 100;
6303
+ var FAILED_SPAWN_COOLDOWN_MS = 5000;
6304
+ var failedSpawnUntil = new Map;
5647
6305
 
5648
6306
  class DaemonUnreachableError extends Error {
5649
6307
  constructor(socketPath) {
@@ -5656,11 +6314,22 @@ async function ensureDaemonRunning(paths, deps = defaultEnsureDaemonDeps(), opti
5656
6314
  const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
5657
6315
  const signal = options.signal;
5658
6316
  throwIfAborted(signal);
5659
- if (await awaitWithSignal2(deps.probe(paths, signal), signal))
6317
+ if (await awaitWithSignal2(deps.probe(paths, signal), signal)) {
6318
+ failedSpawnUntil.delete(paths.socket);
5660
6319
  return;
6320
+ }
5661
6321
  throwIfAborted(signal);
6322
+ const retryAt = failedSpawnUntil.get(paths.socket);
6323
+ if (retryAt !== undefined && deps.now() < retryAt)
6324
+ throw new DaemonUnreachableError(paths.socket);
6325
+ failedSpawnUntil.delete(paths.socket);
5662
6326
  deps.spawnDaemon(paths);
5663
- await waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal);
6327
+ try {
6328
+ await waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal);
6329
+ } catch (error) {
6330
+ failedSpawnUntil.set(paths.socket, deps.now() + FAILED_SPAWN_COOLDOWN_MS);
6331
+ throw error;
6332
+ }
5664
6333
  }
5665
6334
  async function waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal) {
5666
6335
  const deadline = deps.now() + readyTimeoutMs;
@@ -5680,7 +6349,7 @@ async function probeDaemon(paths, timeoutMs = PROBE_TIMEOUT_MS, signal) {
5680
6349
  return await pingDaemon(paths, token, timeoutMs, signal) !== null;
5681
6350
  }
5682
6351
  function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
5683
- return new Promise((resolve9) => {
6352
+ return new Promise((resolve) => {
5684
6353
  const socket = new Socket;
5685
6354
  let settled = false;
5686
6355
  let timer;
@@ -5692,7 +6361,7 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
5692
6361
  clearTimeout(timer);
5693
6362
  signal?.removeEventListener("abort", onAbort);
5694
6363
  socket.destroy();
5695
- resolve9(value);
6364
+ resolve(value);
5696
6365
  };
5697
6366
  const onAbort = () => finish(null);
5698
6367
  const decoder = createLineDecoder((message) => {
@@ -5715,30 +6384,34 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
5715
6384
  socket.connect(paths.socket);
5716
6385
  });
5717
6386
  }
5718
- function spawnDaemonProcess(paths) {
5719
- mkdirSync3(dirname8(paths.log), { recursive: true });
5720
- const logFd = openSync2(paths.log, "a");
6387
+ function spawnDaemonProcess(paths, deps = {}) {
6388
+ mkdirSync4(dirname12(paths.log), { recursive: true });
6389
+ const logFd = openSync3(paths.log, "a");
5721
6390
  try {
5722
- const child = spawn2(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
6391
+ const spawnDaemonChild = deps.spawn ?? spawn2;
6392
+ const executable = deps.resolveExecutable?.() ?? resolveDaemonNodeExecutable();
6393
+ const child = spawnDaemonChild(executable, [paths.cliPath, "daemon"], {
5723
6394
  detached: true,
5724
- stdio: ["ignore", logFd, logFd]
6395
+ stdio: ["ignore", logFd, logFd],
6396
+ windowsHide: true,
6397
+ env: { ...process.env, BUN_BE_BUN: "1" }
5725
6398
  });
5726
- child.once("spawn", () => closeSync2(logFd));
6399
+ child.once("spawn", () => closeSync3(logFd));
5727
6400
  child.once("error", (error) => {
5728
- writeSync2(logFd, `[lsp-daemon] failed to spawn daemon: ${error.message}
6401
+ writeSync3(logFd, `[lsp-daemon] failed to spawn daemon: ${error.message}
5729
6402
  `);
5730
- closeSync2(logFd);
6403
+ closeSync3(logFd);
5731
6404
  });
5732
6405
  child.unref();
5733
6406
  } catch (error) {
5734
- closeSync2(logFd);
6407
+ closeSync3(logFd);
5735
6408
  throw error;
5736
6409
  }
5737
6410
  }
5738
- function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists = existsSync11) {
6411
+ function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists = existsSync13) {
5739
6412
  if (pathExists(cachedExecPath))
5740
6413
  return cachedExecPath;
5741
- if (isAbsolute4(originalArgv0) && pathExists(originalArgv0))
6414
+ if (isAbsolute5(originalArgv0) && pathExists(originalArgv0))
5742
6415
  return originalArgv0;
5743
6416
  return "node";
5744
6417
  }
@@ -5751,7 +6424,7 @@ function defaultEnsureDaemonDeps() {
5751
6424
  };
5752
6425
  }
5753
6426
  function sleepWithSignal(ms, signal) {
5754
- return new Promise((resolve9) => {
6427
+ return new Promise((resolve) => {
5755
6428
  let settled = false;
5756
6429
  const finish = () => {
5757
6430
  if (settled)
@@ -5759,7 +6432,7 @@ function sleepWithSignal(ms, signal) {
5759
6432
  settled = true;
5760
6433
  clearTimeout(timer);
5761
6434
  signal?.removeEventListener("abort", finish);
5762
- resolve9();
6435
+ resolve();
5763
6436
  };
5764
6437
  const timer = setTimeout(finish, ms);
5765
6438
  if (signal?.aborted) {
@@ -5774,7 +6447,7 @@ function awaitWithSignal2(promise, signal) {
5774
6447
  return promise;
5775
6448
  if (signal.aborted)
5776
6449
  return Promise.reject(abortError3(signal));
5777
- return new Promise((resolve9, reject) => {
6450
+ return new Promise((resolve, reject) => {
5778
6451
  let settled = false;
5779
6452
  const finish = (run) => {
5780
6453
  if (settled)
@@ -5785,7 +6458,7 @@ function awaitWithSignal2(promise, signal) {
5785
6458
  };
5786
6459
  const onAbort = () => finish(() => reject(abortError3(signal)));
5787
6460
  signal.addEventListener("abort", onAbort, { once: true });
5788
- promise.then((value) => finish(() => resolve9(value)), (error) => finish(() => reject(error)));
6461
+ promise.then((value) => finish(() => resolve(value)), (error) => finish(() => reject(error)));
5789
6462
  });
5790
6463
  }
5791
6464
  function throwIfAborted(signal) {
@@ -5814,18 +6487,18 @@ function parsePingResponse(message) {
5814
6487
  return null;
5815
6488
  if (!endpoint || typeof endpoint !== "object" || Array.isArray(endpoint))
5816
6489
  return null;
5817
- const path2 = Reflect.get(endpoint, "path");
6490
+ const path = Reflect.get(endpoint, "path");
5818
6491
  const kind = Reflect.get(endpoint, "kind");
5819
- if (typeof path2 !== "string")
6492
+ if (typeof path !== "string")
5820
6493
  return null;
5821
6494
  if (kind === "windows")
5822
- return { pid, nonce, startedAt, endpoint: { kind, path: path2 } };
6495
+ return { pid, nonce, startedAt, endpoint: { kind, path } };
5823
6496
  if (kind === "missing")
5824
- return { pid, nonce, startedAt, endpoint: { kind, path: path2 } };
6497
+ return { pid, nonce, startedAt, endpoint: { kind, path } };
5825
6498
  const dev = Reflect.get(endpoint, "dev");
5826
6499
  const ino = Reflect.get(endpoint, "ino");
5827
6500
  if (kind === "unix" && typeof dev === "number" && typeof ino === "number") {
5828
- return { pid, nonce, startedAt, endpoint: { kind, path: path2, dev, ino } };
6501
+ return { pid, nonce, startedAt, endpoint: { kind, path, dev, ino } };
5829
6502
  }
5830
6503
  return null;
5831
6504
  }
@@ -5834,7 +6507,10 @@ function parsePingResponse(message) {
5834
6507
  var CONTEXT_KEY = "_context";
5835
6508
 
5836
6509
  class InvalidDaemonRequestError extends Error {
5837
- name = "InvalidDaemonRequestError";
6510
+ constructor() {
6511
+ super(...arguments);
6512
+ this.name = "InvalidDaemonRequestError";
6513
+ }
5838
6514
  }
5839
6515
  function extractRequestContext(raw) {
5840
6516
  if (!isPlainRecord(raw) || raw["method"] !== "tools/call")
@@ -5916,6 +6592,7 @@ function parseContext(value) {
5916
6592
 
5917
6593
  // src/daemon-client.ts
5918
6594
  var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
6595
+ var STARTUP_BACKOFF_MS = [0, 100, 300];
5919
6596
  var nextProxyRequestId = 1;
5920
6597
  async function callToolViaDaemon(name, args, options) {
5921
6598
  const context = requireContext(options.context);
@@ -5923,17 +6600,31 @@ async function callToolViaDaemon(name, args, options) {
5923
6600
  const ensure = options.ensure ?? ((ensurePaths, signal) => ensureDaemonRunning(ensurePaths, undefined, signal === undefined ? {} : { signal }));
5924
6601
  const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
5925
6602
  const requestArgs = withContext(args, context);
6603
+ const probe = options.probe ?? ((probePaths, signal) => probeDaemon(probePaths, undefined, signal));
6604
+ const sleep = options.sleep ?? ((ms, signal) => delay(ms, undefined, { signal }));
5926
6605
  let lastError;
5927
6606
  let authRefreshUsed = false;
5928
- for (let attempt = 0;attempt < 3; attempt += 1) {
6607
+ for (const [attempt, backoffMs] of STARTUP_BACKOFF_MS.entries()) {
5929
6608
  try {
5930
- await ensureDaemonAvailable(paths, ensure, options.signal);
6609
+ if (backoffMs > 0)
6610
+ await sleep(backoffMs, options.signal);
6611
+ if (options.signal?.aborted)
6612
+ throw new DaemonRequestCancelledError(false);
6613
+ if (attempt === 0) {
6614
+ await ensureDaemonAvailable(paths, ensure, options.signal);
6615
+ } else if (!await probe(paths, options.signal)) {
6616
+ throw new DaemonUnreachableError(paths.socket);
6617
+ }
5931
6618
  const token = readAuthToken(paths);
5932
6619
  if (!token)
5933
6620
  throw new DaemonRequestError("daemon auth token missing", false);
5934
6621
  const sendOptions = options.signal === undefined ? { timeoutMs } : { timeoutMs, signal: options.signal };
5935
6622
  return await sendToolCall(paths, token, name, requestArgs, sendOptions);
5936
6623
  } catch (error) {
6624
+ if (options.signal?.aborted) {
6625
+ lastError = new DaemonRequestCancelledError(false);
6626
+ break;
6627
+ }
5937
6628
  lastError = error;
5938
6629
  if (error instanceof DaemonAuthenticationRejectedError && !authRefreshUsed) {
5939
6630
  authRefreshUsed = true;
@@ -5950,14 +6641,17 @@ async function callToolViaDaemon(name, args, options) {
5950
6641
  function callDiagnosticsViaDaemon(filePath, options) {
5951
6642
  return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
5952
6643
  }
6644
+ function callFormatViaDaemon(filePath, options) {
6645
+ return callToolViaDaemon("format", { filePath }, options);
6646
+ }
5953
6647
  function currentRequestContext(env = process.env) {
5954
6648
  const cwd = process.cwd();
5955
6649
  const home = env["HOME"] ?? homedir3();
5956
6650
  return parseLspRequestContext({
5957
6651
  cwd,
5958
- projectConfigPaths: [join7(cwd, ".codex", "lsp-client.json")],
5959
- userConfigPath: join7(home, ".codex", "lsp-client.json"),
5960
- installDecisionsPath: join7(home, ".codex", "lsp-install-decisions.json"),
6652
+ projectConfigPaths: [join8(cwd, ".codex", "lsp-client.json")],
6653
+ userConfigPath: join8(home, ".codex", "lsp-client.json"),
6654
+ installDecisionsPath: join8(home, ".codex", "lsp-install-decisions.json"),
5961
6655
  capabilities: { installDecisionTool: true }
5962
6656
  });
5963
6657
  }
@@ -5972,7 +6666,7 @@ function withContext(args, context) {
5972
6666
  function ensureDaemonAvailable(paths, ensure, signal) {
5973
6667
  if (!signal)
5974
6668
  return ensure(paths);
5975
- return new Promise((resolve9, reject) => {
6669
+ return new Promise((resolve, reject) => {
5976
6670
  let settled = false;
5977
6671
  const finish = (run) => {
5978
6672
  if (settled)
@@ -5987,11 +6681,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
5987
6681
  return;
5988
6682
  }
5989
6683
  signal.addEventListener("abort", onAbort, { once: true });
5990
- Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve9()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
6684
+ Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
5991
6685
  });
5992
6686
  }
5993
6687
  function sendToolCall(paths, token, name, args, options) {
5994
- return new Promise((resolve9, reject) => {
6688
+ return new Promise((resolve, reject) => {
5995
6689
  const socket = connect(paths.socket);
5996
6690
  const requestId = allocateProxyRequestId();
5997
6691
  let settled = false;
@@ -6044,7 +6738,7 @@ function sendToolCall(paths, token, name, args, options) {
6044
6738
  }
6045
6739
  const result = toToolResult(message, requestId);
6046
6740
  if (result)
6047
- finish(() => resolve9(result));
6741
+ finish(() => resolve(result));
6048
6742
  else
6049
6743
  finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
6050
6744
  });
@@ -6186,7 +6880,7 @@ function asToolCall(parsed) {
6186
6880
  if (!isPlainRecord(params) || typeof params["name"] !== "string")
6187
6881
  return null;
6188
6882
  const args = params["arguments"];
6189
- return { id: jsonRpcId(parsed["id"]), name: params["name"], args: isPlainRecord(args) ? args : {} };
6883
+ return { id: jsonRpcId2(parsed["id"]), name: params["name"], args: isPlainRecord(args) ? args : {} };
6190
6884
  }
6191
6885
  function inferOpenCodeProjectCwd(projectConfigEnv) {
6192
6886
  if (!projectConfigEnv)
@@ -6212,266 +6906,28 @@ function canonicalizePathList(value) {
6212
6906
  return value.split(delimiter4).map((entry) => canonicalizePath(entry) ?? entry).join(delimiter4);
6213
6907
  }
6214
6908
  function canonicalizePath(value) {
6215
- if (value === undefined || !isAbsolute5(value) || !existsSync12(value))
6909
+ if (value === undefined || !isAbsolute6(value) || !existsSync14(value))
6216
6910
  return value;
6217
- return realpathSync5(value);
6911
+ return realpathSync6(value);
6218
6912
  }
6219
- function projectRootFromOpenCodeConfigPath(path2) {
6220
- if (basename4(path2) !== "lsp.json" && basename4(path2) !== "lsp-client.json")
6913
+ function projectRootFromOpenCodeConfigPath(path) {
6914
+ if (basename4(path) !== "lsp.json" && basename4(path) !== "lsp-client.json")
6221
6915
  return;
6222
- const configDir = dirname9(path2);
6916
+ const configDir = dirname13(path);
6223
6917
  const configDirName = basename4(configDir);
6224
6918
  if (configDirName !== ".opencode" && configDirName !== ".omo")
6225
6919
  return;
6226
- return dirname9(configDir);
6920
+ return dirname13(configDir);
6227
6921
  }
6228
6922
 
6229
6923
  // src/daemon-server.ts
6230
6924
  import { chmodSync as chmodSync2 } from "node:fs";
6231
6925
  import { createServer as createServer2 } from "node:net";
6232
6926
 
6233
- // src/ownership.ts
6234
- import { randomUUID } from "node:crypto";
6235
- import { existsSync as existsSync13, lstatSync as lstatSync7, readFileSync as readFileSync7, statSync as statSync5, unlinkSync as unlinkSync3 } from "node:fs";
6236
- import { dirname as dirname11 } from "node:path";
6237
-
6238
- // src/lock.ts
6239
- import { closeSync as closeSync3, mkdirSync as mkdirSync4, openSync as openSync3, readFileSync as readFileSync6, unlinkSync as unlinkSync2, writeSync as writeSync3 } from "node:fs";
6240
- import { dirname as dirname10 } from "node:path";
6241
- function isProcessAlive2(pid) {
6242
- if (!Number.isInteger(pid) || pid <= 0)
6243
- return false;
6244
- try {
6245
- process.kill(pid, 0);
6246
- return true;
6247
- } catch (error) {
6248
- if (error instanceof Error)
6249
- return errorCode3(error) === "EPERM";
6250
- throw error;
6251
- }
6252
- }
6253
- function readLockPid(lockPath) {
6254
- try {
6255
- const pid = Number.parseInt(readFileSync6(lockPath, "utf8").trim(), 10);
6256
- return Number.isInteger(pid) ? pid : null;
6257
- } catch {
6258
- return null;
6259
- }
6260
- }
6261
- function tryAcquireLock(lockPath, ownerPid = process.pid) {
6262
- mkdirSync4(dirname10(lockPath), { recursive: true });
6263
- for (let attempt = 0;attempt < 2; attempt += 1) {
6264
- const handle = writeLockFile(lockPath, ownerPid);
6265
- if (handle)
6266
- return handle;
6267
- if (!reapStaleLock(lockPath))
6268
- return null;
6269
- }
6270
- return null;
6271
- }
6272
- function writeLockFile(lockPath, ownerPid) {
6273
- try {
6274
- const fd = openSync3(lockPath, "wx", 384);
6275
- writeSync3(fd, `${ownerPid}
6276
- `);
6277
- closeSync3(fd);
6278
- return { release: () => unlinkQuietly(lockPath) };
6279
- } catch (error) {
6280
- if (errorCode3(error) === "EEXIST")
6281
- return null;
6282
- throw error;
6283
- }
6284
- }
6285
- function reapStaleLock(lockPath) {
6286
- const pid = readLockPid(lockPath);
6287
- if (pid !== null && isProcessAlive2(pid))
6288
- return false;
6289
- unlinkQuietly(lockPath);
6290
- return true;
6291
- }
6292
- function unlinkQuietly(path2) {
6293
- try {
6294
- unlinkSync2(path2);
6295
- } catch (error) {
6296
- if (error instanceof Error)
6297
- return;
6298
- throw error;
6299
- }
6300
- }
6301
- function errorCode3(error) {
6302
- if (!error || typeof error !== "object" || !("code" in error))
6303
- return;
6304
- const code = Reflect.get(error, "code");
6305
- return typeof code === "string" ? code : undefined;
6306
- }
6307
-
6308
- // src/ownership.ts
6309
- class DaemonAlreadyRunningError extends Error {
6310
- name = "DaemonAlreadyRunningError";
6311
- code = "daemon_already_running";
6312
- }
6313
-
6314
- class DaemonStartupDeferredError extends Error {
6315
- reason;
6316
- name = "DaemonStartupDeferredError";
6317
- code = "daemon_startup_deferred";
6318
- constructor(reason) {
6319
- super(`LSP daemon startup deferred: ${reason}`);
6320
- this.reason = reason;
6321
- }
6322
- }
6323
- async function acquireStartupLease(paths, pingOwner) {
6324
- ensureDaemonDirectories(paths);
6325
- const lock = tryAcquireLock(paths.lock);
6326
- if (!lock) {
6327
- const token = readAuthToken(paths);
6328
- if (token && await pingOwner(token))
6329
- throw new DaemonAlreadyRunningError("LSP daemon already running");
6330
- throw new DaemonStartupDeferredError("startup_lock_busy");
6331
- }
6332
- try {
6333
- const token = await validateExistingOwner(paths, pingOwner);
6334
- return { lock, token, owner: newOwner(paths) };
6335
- } catch (error) {
6336
- lock.release();
6337
- throw error;
6338
- }
6339
- }
6340
- function ensureDaemonDirectories(paths) {
6341
- ensurePrivateDirectory(paths.dir);
6342
- if (process.platform !== "win32")
6343
- ensurePrivateDirectory(dirname11(paths.socket));
6344
- }
6345
- function readDaemonOwner(paths) {
6346
- try {
6347
- return parseOwner(JSON.parse(readFileSync7(paths.owner, "utf8")));
6348
- } catch (error) {
6349
- if (error instanceof Error)
6350
- return null;
6351
- throw error;
6352
- }
6353
- }
6354
- function writeDaemonOwner(paths, owner) {
6355
- writePrivateFile(paths.pid, `${owner.pid}
6356
- `);
6357
- writePrivateFile(paths.endpoint, owner.endpoint.path);
6358
- writePrivateFile(paths.owner, `${JSON.stringify(owner)}
6359
- `);
6360
- }
6361
- function removeDaemonMetadataForOwner(paths, owner) {
6362
- const current = readDaemonOwner(paths);
6363
- if (!current || !sameOwner(current, owner))
6364
- return;
6365
- unlinkQuietly(paths.socket);
6366
- unlinkQuietly(paths.pid);
6367
- unlinkQuietly(paths.endpoint);
6368
- unlinkQuietly(paths.owner);
6369
- }
6370
- function endpointIdentity(endpointPath) {
6371
- if (process.platform === "win32")
6372
- return { kind: "windows", path: endpointPath };
6373
- try {
6374
- const stats = statSync5(endpointPath);
6375
- return { kind: "unix", path: endpointPath, dev: stats.dev, ino: stats.ino };
6376
- } catch (error) {
6377
- if (error instanceof Error)
6378
- return { kind: "missing", path: endpointPath };
6379
- throw error;
6380
- }
6381
- }
6382
- function sameEndpoint(a, b) {
6383
- if (a.kind !== b.kind || a.path !== b.path)
6384
- return false;
6385
- switch (a.kind) {
6386
- case "unix":
6387
- return b.kind === "unix" && a.dev === b.dev && a.ino === b.ino;
6388
- case "windows":
6389
- return true;
6390
- case "missing":
6391
- return true;
6392
- }
6393
- }
6394
- function sameOwner(a, b) {
6395
- return a.pid === b.pid && a.nonce === b.nonce && sameEndpoint(a.endpoint, b.endpoint);
6396
- }
6397
- async function validateExistingOwner(paths, pingOwner) {
6398
- let token = readOrCreateAuthToken(paths);
6399
- for (let attempt = 0;attempt < 2; attempt += 1) {
6400
- const owner = readDaemonOwner(paths);
6401
- if (!owner)
6402
- return token;
6403
- const ping = await pingOwner(token);
6404
- if (ping && owner.nonce === ping.nonce && sameEndpoint(owner.endpoint, ping.endpoint)) {
6405
- throw new DaemonAlreadyRunningError("LSP daemon already running");
6406
- }
6407
- if (ping)
6408
- continue;
6409
- if (isProcessAlive2(owner.pid))
6410
- throw new DaemonStartupDeferredError("owner_pid_live_unreachable");
6411
- const reread = readDaemonOwner(paths);
6412
- const endpoint = endpointIdentity(owner.endpoint.path);
6413
- if (!reread || reread.nonce !== owner.nonce || !sameEndpoint(endpoint, owner.endpoint)) {
6414
- throw new DaemonStartupDeferredError("owner_changed_during_cleanup");
6415
- }
6416
- cleanupDeadOwner(paths, owner);
6417
- token = rotateAuthToken(paths);
6418
- return token;
6419
- }
6420
- throw new DaemonStartupDeferredError("reachable_owner_mismatch");
6421
- }
6422
- function cleanupDeadOwner(paths, owner) {
6423
- if (process.platform !== "win32" && existsSync13(owner.endpoint.path)) {
6424
- const stat = lstatSync7(owner.endpoint.path);
6425
- if (stat.isSocket())
6426
- unlinkSync3(owner.endpoint.path);
6427
- }
6428
- unlinkQuietly(paths.pid);
6429
- unlinkQuietly(paths.endpoint);
6430
- unlinkQuietly(paths.owner);
6431
- }
6432
- function newOwner(paths) {
6433
- return {
6434
- pid: process.pid,
6435
- nonce: randomUUID(),
6436
- startedAt: new Date().toISOString(),
6437
- endpoint: endpointIdentity(paths.socket)
6438
- };
6439
- }
6440
- function parseOwner(value) {
6441
- if (!value || typeof value !== "object" || Array.isArray(value))
6442
- return null;
6443
- const pid = Reflect.get(value, "pid");
6444
- const nonce = Reflect.get(value, "nonce");
6445
- const startedAt = Reflect.get(value, "startedAt");
6446
- const endpoint = parseEndpoint(Reflect.get(value, "endpoint"));
6447
- if (typeof pid !== "number" || typeof nonce !== "string" || typeof startedAt !== "string" || !endpoint)
6448
- return null;
6449
- return { pid, nonce, startedAt, endpoint };
6450
- }
6451
- function parseEndpoint(value) {
6452
- if (!value || typeof value !== "object" || Array.isArray(value))
6453
- return null;
6454
- const kind = Reflect.get(value, "kind");
6455
- const path2 = Reflect.get(value, "path");
6456
- if (typeof path2 !== "string")
6457
- return null;
6458
- if (kind === undefined)
6459
- return endpointIdentity(path2);
6460
- if (kind === "windows")
6461
- return { kind, path: path2 };
6462
- if (kind === "missing")
6463
- return { kind, path: path2 };
6464
- const dev = Reflect.get(value, "dev");
6465
- const ino = Reflect.get(value, "ino");
6466
- if (kind === "unix" && typeof dev === "number" && typeof ino === "number")
6467
- return { kind, path: path2, dev, ino };
6468
- return null;
6469
- }
6470
-
6471
6927
  // src/version-reap.ts
6472
6928
  import { execFile } from "node:child_process";
6473
6929
  import { readdir, readFile, rm } from "node:fs/promises";
6474
- import { basename as basename5, dirname as dirname12, join as join8 } from "node:path";
6930
+ import { basename as basename5, dirname as dirname14, join as join9 } from "node:path";
6475
6931
  var TERM_GRACE_MS = 5000;
6476
6932
  var KILL_GRACE_MS = 1000;
6477
6933
  var VERSION_ENTRY_PATTERN = /^v([A-Za-z0-9][A-Za-z0-9._+-]{0,127})$/;
@@ -6492,13 +6948,13 @@ async function attestDaemonCliProcess(pid, platform, deps = {}) {
6492
6948
  return isNodeCliDaemonCommand(command.trim());
6493
6949
  }
6494
6950
  async function reapStaleDaemonVersions(ownPaths, deps = {}) {
6495
- const baseDir = dirname12(ownPaths.dir);
6951
+ const baseDir = dirname14(ownPaths.dir);
6496
6952
  const platform = deps.platform ?? process.platform;
6497
- const isAlive = deps.isAlive ?? isProcessAlive2;
6953
+ const isAlive = deps.isAlive ?? isProcessAlive;
6498
6954
  const attest = deps.attest ?? ((pid) => attestDaemonCliProcess(pid, platform));
6499
6955
  const sendSignal = deps.sendSignal ?? defaultSendSignal;
6500
6956
  const waitForExit = deps.waitForExit ?? defaultWaitForExit;
6501
- const removeDir = deps.removeDir ?? ((path2) => rm(path2, { recursive: true, force: true }));
6957
+ const removeDir = deps.removeDir ?? ((path) => rm(path, { recursive: true, force: true }));
6502
6958
  const readOwner = deps.readOwner ?? readDaemonOwner;
6503
6959
  const log = deps.log ?? defaultLog;
6504
6960
  const termGraceMs = deps.termGraceMs ?? TERM_GRACE_MS;
@@ -6511,7 +6967,7 @@ async function reapStaleDaemonVersions(ownPaths, deps = {}) {
6511
6967
  const version = parseVersionEntry(entry.name);
6512
6968
  if (version === null || !entry.isDirectory())
6513
6969
  continue;
6514
- const versionDir = join8(baseDir, entry.name);
6970
+ const versionDir = join9(baseDir, entry.name);
6515
6971
  const siblingPaths = daemonPaths({ [OMO_LSP_DAEMON_DIR]: baseDir }, { cliPath: ownPaths.cliPath, version });
6516
6972
  results.push(await reapOneVersion({
6517
6973
  version,
@@ -6535,7 +6991,7 @@ async function reapOneVersion(context) {
6535
6991
  const { version, versionDir } = context;
6536
6992
  const owner = context.readOwner(context.siblingPaths);
6537
6993
  if (!owner) {
6538
- const lockPid = readLockPid(join8(versionDir, "daemon.lock"));
6994
+ const lockPid = readLockPid(join9(versionDir, "daemon.lock"));
6539
6995
  if (lockPid !== null && context.isAlive(lockPid)) {
6540
6996
  context.log(`reap: sparing v${version}: owner metadata missing but daemon.lock is held by live pid ${lockPid}`);
6541
6997
  return { version, status: "spared", reason: `owner metadata missing but lock held by live pid ${lockPid}` };
@@ -6609,17 +7065,17 @@ function isNodeCliDaemonArgv(argv) {
6609
7065
  function isNodeCliDaemonCommand(command) {
6610
7066
  return /\bnode(?:\.exe)?\b/i.test(command) && /\bcli\.js\b/.test(command) && /\bdaemon\b/.test(command);
6611
7067
  }
6612
- function defaultReadProcFile(path2) {
6613
- return readFile(path2);
7068
+ function defaultReadProcFile(path) {
7069
+ return readFile(path);
6614
7070
  }
6615
7071
  function defaultExecuteForStdout(file, args) {
6616
- return new Promise((resolve9) => {
6617
- execFile(file, [...args], { encoding: "utf8", maxBuffer: 1024 * 1024, timeout: 1000 }, (error, stdout) => {
7072
+ return new Promise((resolve) => {
7073
+ execFile(file, [...args], { encoding: "utf8", maxBuffer: 1024 * 1024, timeout: 1000, windowsHide: true }, (error, stdout) => {
6618
7074
  if (error !== null) {
6619
- resolve9(null);
7075
+ resolve(null);
6620
7076
  return;
6621
7077
  }
6622
- resolve9(stdout);
7078
+ resolve(stdout);
6623
7079
  });
6624
7080
  });
6625
7081
  }
@@ -6634,11 +7090,11 @@ function defaultSendSignal(pid, signal) {
6634
7090
  async function defaultWaitForExit(pid, timeoutMs) {
6635
7091
  const deadline = Date.now() + timeoutMs;
6636
7092
  for (;; ) {
6637
- if (!isProcessAlive2(pid))
7093
+ if (!isProcessAlive(pid))
6638
7094
  return true;
6639
7095
  if (Date.now() >= deadline)
6640
7096
  return false;
6641
- await new Promise((resolve9) => setTimeout(resolve9, 100));
7097
+ await new Promise((resolve) => setTimeout(resolve, 100));
6642
7098
  }
6643
7099
  }
6644
7100
  function defaultLog(message) {
@@ -6659,7 +7115,7 @@ async function startDaemonServer(paths, options = {}) {
6659
7115
  lastActiveAt = Date.now();
6660
7116
  };
6661
7117
  let routeOwner = lease.owner;
6662
- const server2 = createServer2((socket) => {
7118
+ const server = createServer2((socket) => {
6663
7119
  connections.add(socket);
6664
7120
  const activeRequests = new Map;
6665
7121
  touch();
@@ -6677,10 +7133,10 @@ async function startDaemonServer(paths, options = {}) {
6677
7133
  touch();
6678
7134
  });
6679
7135
  });
6680
- server2.on("error", (error) => logServerError(error));
7136
+ server.on("error", (error) => logServerError(error));
6681
7137
  let owner;
6682
7138
  try {
6683
- await listen(server2, paths.socket);
7139
+ await listen(server, paths.socket);
6684
7140
  if (process.platform !== "win32")
6685
7141
  chmodSync2(paths.socket, 384);
6686
7142
  owner = { ...lease.owner, endpoint: endpointIdentity(paths.socket) };
@@ -6702,7 +7158,7 @@ async function startDaemonServer(paths, options = {}) {
6702
7158
  for (const socket of connections)
6703
7159
  socket.destroy();
6704
7160
  connections.clear();
6705
- await closeServer(server2);
7161
+ await closeServer(server);
6706
7162
  removeDaemonMetadataForOwner(paths, owner);
6707
7163
  await disposeDefaultLspManager();
6708
7164
  };
@@ -6723,7 +7179,7 @@ async function startDaemonServer(paths, options = {}) {
6723
7179
  }, idleCheckIntervalMs);
6724
7180
  idleTimer.unref();
6725
7181
  installSignalHandlers(close);
6726
- return { server: server2, close };
7182
+ return { server, close };
6727
7183
  }
6728
7184
  async function respond(socket, message, token, owner, activeRequests) {
6729
7185
  try {
@@ -6744,18 +7200,18 @@ async function assertSelfProbe(paths, token, owner) {
6744
7200
  if (!ping || ping.nonce !== owner.nonce)
6745
7201
  throw new DaemonStartupDeferredError("self_probe_failed");
6746
7202
  }
6747
- function listen(server2, socketPath) {
6748
- return new Promise((resolve9, reject) => {
7203
+ function listen(server, socketPath) {
7204
+ return new Promise((resolve, reject) => {
6749
7205
  const onError = (error) => reject(error);
6750
- server2.once("error", onError);
6751
- server2.listen(socketPath, () => {
6752
- server2.removeListener("error", onError);
6753
- resolve9();
7206
+ server.once("error", onError);
7207
+ server.listen(socketPath, () => {
7208
+ server.removeListener("error", onError);
7209
+ resolve();
6754
7210
  });
6755
7211
  });
6756
7212
  }
6757
- function closeServer(server2) {
6758
- return new Promise((resolve9) => server2.close(() => resolve9()));
7213
+ function closeServer(server) {
7214
+ return new Promise((resolve) => server.close(() => resolve()));
6759
7215
  }
6760
7216
  function installSignalHandlers(close) {
6761
7217
  const handler = () => {
@@ -6804,7 +7260,12 @@ async function main() {
6804
7260
  process.exitCode = 2;
6805
7261
  }
6806
7262
  main().catch((error) => {
6807
- stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}
7263
+ if (error instanceof DaemonStartupDeferredError) {
7264
+ stderr.write(`[lsp-daemon] startup deferred: ${error.reason}
7265
+ `);
7266
+ } else {
7267
+ stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}
6808
7268
  `);
7269
+ }
6809
7270
  process.exitCode = 1;
6810
7271
  });