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

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 (997) hide show
  1. package/.agents/command/publish.md +59 -23
  2. package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +1 -3
  3. package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +1 -1
  4. package/.agents/skills/pre-publish-review/SKILL.md +9 -12
  5. package/.agents/skills/publish/SKILL.md +59 -23
  6. package/.agents/skills/senpi-qa/SKILL.md +80 -0
  7. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
  8. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
  9. package/.agents/skills/tech-debt-audit/SKILL.md +6 -76
  10. package/.agents/skills/work-with-pr/SKILL.md +37 -23
  11. package/.opencode/command/publish.md +59 -23
  12. package/.opencode/skills/pre-publish-review/SKILL.md +9 -12
  13. package/.opencode/skills/work-with-pr/SKILL.md +37 -23
  14. package/README.ja.md +65 -60
  15. package/README.ko.md +66 -61
  16. package/README.md +65 -72
  17. package/README.ru.md +62 -60
  18. package/README.zh-cn.md +61 -60
  19. package/THIRD-PARTY-NOTICES.md +27 -99
  20. package/dist/agents/atlas/agent.d.ts +0 -1
  21. package/dist/agents/gpt-prompt-identity.d.ts +1 -1
  22. package/dist/agents/sisyphus/grok-4.d.ts +20 -0
  23. package/dist/agents/sisyphus/index.d.ts +2 -0
  24. package/dist/agents/sisyphus-agent-config.d.ts +6 -0
  25. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  26. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
  27. package/dist/agents/types.d.ts +4 -2
  28. package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
  29. package/dist/cli/doctor/checks/index.d.ts +2 -0
  30. package/dist/cli/doctor/checks/latest-version.d.ts +11 -0
  31. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  32. package/dist/cli/doctor/framework/constants.d.ts +5 -0
  33. package/dist/cli/doctor/framework/types.d.ts +2 -0
  34. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  35. package/dist/cli/index.js +52548 -60412
  36. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  37. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  38. package/dist/cli/runtime-commands.d.ts +1 -1
  39. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  40. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  41. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  42. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  43. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  44. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  45. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  46. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  47. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  48. package/dist/cli-node/index.js +51202 -59043
  49. package/dist/config/index.d.ts +1 -1
  50. package/dist/config/schema/background-task.d.ts +1 -0
  51. package/dist/config/schema/commands.d.ts +1 -1
  52. package/dist/config/schema/hooks.d.ts +1 -2
  53. package/dist/config/schema/oh-my-opencode-config.d.ts +5 -11
  54. package/dist/config/schema/ulw-execute.d.ts +5 -0
  55. package/dist/config/schema.d.ts +0 -1
  56. package/dist/config/validate.d.ts +2 -0
  57. package/dist/create-hooks.d.ts +3 -2
  58. package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +1 -0
  59. package/dist/features/background-agent/constants.d.ts +0 -7
  60. package/dist/features/background-agent/error-classifier.d.ts +1 -0
  61. package/dist/features/background-agent/manager.d.ts +9 -1
  62. package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
  63. package/dist/features/background-agent/parent-wake-notifier-types.d.ts +1 -1
  64. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -1
  65. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -1
  66. package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
  67. package/dist/features/background-agent/types.d.ts +4 -0
  68. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  69. package/dist/features/btw-side/context-injector.d.ts +15 -0
  70. package/dist/features/btw-side/index.d.ts +8 -0
  71. package/dist/features/btw-side/metadata.d.ts +15 -0
  72. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  73. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  74. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  75. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  76. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  77. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  78. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  79. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  80. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  81. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  82. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  83. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  84. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  85. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  86. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  87. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  88. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  89. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  90. package/dist/features/builtin-commands/types.d.ts +1 -1
  91. package/dist/features/claude-tasks/storage.d.ts +7 -2
  92. package/dist/features/hook-message-injector/index.d.ts +1 -0
  93. package/dist/features/hook-message-injector/sdk-message-lookup.d.ts +1 -0
  94. package/dist/features/monitor/manager-internals.d.ts +1 -1
  95. package/dist/features/monitor/output-injector-types.d.ts +1 -1
  96. package/dist/features/opengateway-provider/index.d.ts +13 -0
  97. package/dist/features/task-toast-manager/manager.d.ts +0 -24
  98. package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +17 -0
  99. package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +3 -0
  100. package/dist/features/team-mode/tools/messaging-runtime.d.ts +7 -0
  101. package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
  102. package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
  103. package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
  104. package/dist/hooks/anthropic-context-window-limit-recovery/tool-result-storage.d.ts +11 -0
  105. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  106. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  107. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  108. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  109. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  110. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  111. package/dist/hooks/atlas/types.d.ts +1 -0
  112. package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
  113. package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
  114. package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
  115. package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
  116. package/dist/hooks/compaction-context-injector/validated-model.d.ts +2 -0
  117. package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
  118. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
  119. package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
  120. package/dist/hooks/index.d.ts +1 -2
  121. package/dist/hooks/keyword-detector/hook.d.ts +9 -0
  122. package/dist/hooks/keyword-detector/ultrawork/index.d.ts +2 -0
  123. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
  124. package/dist/hooks/model-fallback/hook.d.ts +1 -1
  125. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  126. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  127. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  128. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  129. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  130. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  131. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  132. package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
  133. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  134. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  135. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  136. package/dist/hooks/unstable-agent-babysitter/task-message-analyzer.d.ts +1 -0
  137. package/dist/index.js +29256 -25391
  138. package/dist/mcp/index.d.ts +0 -4
  139. package/dist/mcp/types.d.ts +0 -1
  140. package/dist/oh-my-opencode.schema.json +21 -47
  141. package/dist/plugin/chat-message/types.d.ts +6 -4
  142. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  143. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  144. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -2
  145. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -3
  146. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  147. package/dist/plugin/messages-transform.d.ts +1 -0
  148. package/dist/plugin/stop-continuation.d.ts +3 -0
  149. package/dist/plugin/system-transform.d.ts +5 -1
  150. package/dist/plugin-dispose.d.ts +3 -0
  151. package/dist/shared/agent-tool-restrictions.d.ts +0 -1
  152. package/dist/shared/compaction-agent-config-checkpoint.d.ts +1 -0
  153. package/dist/shared/index.d.ts +2 -0
  154. package/dist/shared/legacy-plugin-warning.d.ts +2 -1
  155. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  156. package/dist/shared/omo-process-sweep.d.ts +2 -4
  157. package/dist/shared/plugin-entry-migrator.d.ts +4 -3
  158. package/dist/shared/plugin-entry-shape.d.ts +6 -0
  159. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  160. package/dist/shared/shell-env.d.ts +1 -1
  161. package/dist/skills/ast-grep/AGENTS.md +51 -0
  162. package/dist/skills/ast-grep/SKILL.md +1 -1
  163. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  164. package/dist/skills/coding-agent-sessions/SKILL.md +1 -1
  165. package/dist/skills/data-scientist/SKILL.md +99 -239
  166. package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
  167. package/dist/skills/data-scientist/references/placement.md +74 -0
  168. package/dist/skills/data-scientist/references/polars-lane.md +95 -0
  169. package/dist/skills/data-scientist/references/uv-setup.md +1 -1
  170. package/dist/skills/data-scientist/references/visualization.md +64 -0
  171. package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  172. package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  173. package/dist/skills/debugging/SKILL.md +3 -1
  174. package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
  175. package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
  176. package/dist/skills/debugging/references/runtimes/go.md +15 -1
  177. package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
  178. package/dist/skills/debugging/references/runtimes/node.md +25 -0
  179. package/dist/skills/debugging/references/runtimes/python.md +13 -0
  180. package/dist/skills/debugging/references/runtimes/rust.md +41 -0
  181. package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
  182. package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
  183. package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  184. package/dist/skills/debugging/references/tools/dap.md +103 -0
  185. package/dist/skills/debugging/references/tools/frida.md +193 -0
  186. package/dist/skills/frontend/ATTRIBUTION.md +10 -0
  187. package/dist/skills/frontend/SKILL.md +15 -8
  188. package/dist/skills/frontend/references/design/README.md +10 -2
  189. package/dist/skills/frontend/references/design/_INDEX.md +2 -0
  190. package/dist/skills/frontend/references/design/ambience-skill.md +145 -0
  191. package/dist/skills/frontend/references/design/interaction-skill.md +2 -0
  192. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  193. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  194. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  195. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  196. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  197. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  198. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  199. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  200. package/dist/skills/git-master/SKILL.md +1 -1
  201. package/dist/skills/init-deep/SKILL.md +14 -14
  202. package/dist/skills/lsp-setup/SKILL.md +1 -1
  203. package/dist/skills/programming/SKILL.md +1 -1
  204. package/dist/skills/refactor/SKILL.md +4 -4
  205. package/dist/skills/remove-ai-slops/SKILL.md +1 -1
  206. package/dist/skills/review-work/SKILL.md +101 -419
  207. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  208. package/dist/skills/ultimate-browsing/SKILL.md +26 -9
  209. package/dist/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  210. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  211. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  212. package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  213. package/dist/skills/{start-work → ulw-execute}/SKILL.md +20 -19
  214. package/dist/skills/ulw-plan/SKILL.md +7 -8
  215. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  216. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  217. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  218. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  219. package/dist/skills/ulw-research/SKILL.md +8 -3
  220. package/dist/skills/visual-qa/AGENTS.md +58 -0
  221. package/dist/skills/visual-qa/SKILL.md +4 -3
  222. package/dist/tools/delegate-task/builtin-categories.d.ts +3 -1
  223. package/dist/tools/delegate-task/builtin-category-definition.d.ts +2 -1
  224. package/dist/tools/delegate-task/constants.d.ts +2 -2
  225. package/dist/tools/delegate-task/openai-categories.d.ts +7 -2
  226. package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
  227. package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
  228. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  229. package/dist/tools/delegate-task/types.d.ts +4 -0
  230. package/dist/tools/session-manager/directory-filter.d.ts +2 -0
  231. package/dist/tui.d.ts +12 -0
  232. package/dist/tui.js +37048 -46599
  233. package/package.json +47 -41
  234. package/packages/git-bash-mcp/dist/cli.js +6 -1
  235. package/packages/git-bash-mcp/package.json +1 -1
  236. package/packages/lsp-core/src/index.ts +1 -0
  237. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  238. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +57 -48
  239. package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
  240. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  241. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +103 -6
  242. package/packages/lsp-core/src/lsp/client-wrapper.ts +50 -16
  243. package/packages/lsp-core/src/lsp/client.ts +32 -3
  244. package/packages/lsp-core/src/lsp/connection.ts +16 -0
  245. package/packages/lsp-core/src/lsp/constants.ts +6 -0
  246. package/packages/lsp-core/src/lsp/controlled-clock-test-support.ts +61 -0
  247. package/packages/lsp-core/src/lsp/errors.ts +15 -0
  248. package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +10 -3
  249. package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
  250. package/packages/lsp-core/src/lsp/format-document.ts +90 -0
  251. package/packages/lsp-core/src/lsp/json-rpc-connection.ts +11 -6
  252. package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
  253. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
  254. package/packages/lsp-core/src/lsp/manager.ts +138 -12
  255. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  256. package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
  257. package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
  258. package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
  259. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
  260. package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
  261. package/packages/lsp-core/src/lsp/timer-provider.ts +13 -0
  262. package/packages/lsp-core/src/lsp/transport-request-timeout.test.ts +73 -0
  263. package/packages/lsp-core/src/lsp/transport.ts +16 -2
  264. package/packages/lsp-core/src/lsp/types.ts +8 -0
  265. package/packages/lsp-core/src/lsp/workspace-apply-edit-test-support.ts +29 -1
  266. package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +84 -1
  267. package/packages/lsp-core/src/lsp/workspace-document-state.ts +30 -11
  268. package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
  269. package/packages/lsp-core/src/mcp.ts +3 -0
  270. package/packages/lsp-core/src/request-context.test.ts +29 -0
  271. package/packages/lsp-core/src/request-context.ts +1 -1
  272. package/packages/lsp-core/src/tool-surface.test.ts +13 -1
  273. package/packages/lsp-core/src/tools/definitions.ts +14 -0
  274. package/packages/lsp-core/src/tools/format.test.ts +56 -0
  275. package/packages/lsp-core/src/tools/format.ts +56 -0
  276. package/packages/lsp-core/src/tools/index.ts +1 -0
  277. package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
  278. package/packages/lsp-core/src/tools/types.ts +10 -0
  279. package/packages/lsp-daemon/dist/cli.js +902 -479
  280. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  281. package/packages/lsp-daemon/dist/client.js +920 -493
  282. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  283. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  284. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +6 -1
  285. package/packages/lsp-daemon/dist/ensure-daemon.js +10 -2
  286. package/packages/lsp-daemon/dist/index.js +824 -402
  287. package/packages/lsp-daemon/dist/ownership.js +2 -2
  288. package/packages/lsp-daemon/dist/proxy.js +3 -0
  289. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  290. package/packages/lsp-daemon/package.json +1 -1
  291. package/packages/lsp-tools-mcp/dist/cli.js +762 -341
  292. package/packages/lsp-tools-mcp/dist/lsp/manager.js +272 -138
  293. package/packages/lsp-tools-mcp/dist/mcp.js +787 -368
  294. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  295. package/packages/lsp-tools-mcp/dist/tools.js +717 -302
  296. package/packages/lsp-tools-mcp/package.json +1 -1
  297. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -21
  298. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -6
  299. package/packages/omo-codex/plugin/.mcp.json +0 -6
  300. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  301. package/packages/omo-codex/plugin/README.md +6 -2
  302. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +7093 -408
  303. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  304. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  305. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  306. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +7 -1
  307. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  308. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  309. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  310. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  311. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  312. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  313. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  314. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  315. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  316. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  317. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +1 -1
  318. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +2 -1
  319. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  320. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  321. package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +2 -1
  322. package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +6 -7
  323. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +2 -2
  324. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  325. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/directive.md +2 -0
  326. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +36 -29
  327. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +32 -26
  328. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/types.d.ts +3 -0
  329. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  330. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  331. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +32 -28
  332. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/types.ts +3 -0
  333. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +1 -1
  334. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +137 -28
  335. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +4 -2
  336. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  337. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  338. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  339. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +941 -540
  340. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  341. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  342. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  343. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  344. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  345. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  346. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  347. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  348. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  349. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  350. package/packages/omo-codex/plugin/components/rules/README.md +2 -0
  351. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  352. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +123 -0
  353. package/packages/omo-codex/plugin/components/rules/dist/cli.js +91 -68
  354. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  355. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  356. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  357. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  358. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +15 -5
  359. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  360. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  361. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  362. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  363. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  364. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  365. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  366. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  367. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  368. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  369. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  370. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  371. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  372. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +38 -3
  373. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  374. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  375. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  376. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  377. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +29 -6
  378. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  379. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  380. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  381. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  382. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  383. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  384. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +4 -10
  385. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  386. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  387. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2407 -684
  388. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2411 -689
  389. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  390. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  391. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  392. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  393. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  394. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  395. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -4
  396. package/packages/omo-codex/plugin/components/ultrawork/README.md +2 -0
  397. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
  398. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +1 -1
  399. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
  400. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  401. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
  402. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  403. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-low.toml +1 -1
  404. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +1 -1
  405. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +1 -1
  406. package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +1 -1
  407. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +1 -1
  408. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  409. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  410. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +499 -4
  411. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  412. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -6
  413. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
  414. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -7
  415. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  416. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  417. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  418. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
  419. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
  420. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  421. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  422. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
  423. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
  424. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  425. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +4 -4
  426. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  427. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +6 -6
  428. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  429. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +10 -10
  430. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +16 -16
  431. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +16 -0
  432. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  433. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  434. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  435. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +4 -4
  436. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  437. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  438. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +1 -1
  439. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  440. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +4 -11
  441. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +24 -22
  442. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +19 -0
  443. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +3 -1
  444. package/packages/omo-codex/plugin/components/ulw-loop/README.md +12 -1
  445. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  446. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +46 -24
  447. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +16 -0
  448. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +25 -0
  449. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +10 -4
  450. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +2 -5
  451. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +5 -78
  452. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +12 -0
  453. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +114 -0
  454. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.d.ts +7 -1
  455. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +50 -42
  456. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +2 -2
  457. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +21 -8
  458. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  459. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +12 -1
  460. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +1 -1
  461. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +40 -37
  462. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +1468 -535
  463. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  464. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +28 -8
  465. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +2 -5
  466. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +24 -20
  467. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -0
  468. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +1 -0
  469. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
  470. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +1 -0
  471. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +13 -4
  472. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +1 -0
  473. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +34 -4
  474. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +14 -0
  475. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +29 -0
  476. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +7 -0
  477. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +9 -0
  478. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +12 -0
  479. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +104 -0
  480. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  481. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +65 -9
  482. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  483. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  484. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +72 -117
  485. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.d.ts +2 -0
  486. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +16 -7
  487. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.d.ts +2 -0
  488. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.js +141 -0
  489. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.d.ts +46 -0
  490. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.js +28 -0
  491. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.d.ts +127 -0
  492. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.js +1 -0
  493. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.d.ts +3 -0
  494. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.js +3 -0
  495. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +7 -1
  496. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +216 -33
  497. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-role-guard.d.ts +2 -0
  498. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-role-guard.js +22 -0
  499. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.d.ts +9 -0
  500. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.js +227 -0
  501. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +6 -0
  502. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +33 -0
  503. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +20 -6
  504. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +19 -0
  505. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +75 -0
  506. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +18 -5
  507. package/packages/omo-codex/plugin/components/ulw-loop/package.json +6 -6
  508. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +10 -4
  509. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  510. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +32 -8
  511. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +40 -0
  512. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +8 -6
  513. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +5 -98
  514. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +134 -0
  515. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +52 -73
  516. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +10 -4
  517. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +24 -8
  518. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +14 -1
  519. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +52 -46
  520. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +8 -6
  521. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +35 -7
  522. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +34 -28
  523. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  524. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +1 -0
  525. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
  526. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +25 -4
  527. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +39 -4
  528. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +38 -0
  529. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +11 -0
  530. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +123 -0
  531. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +71 -15
  532. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  533. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +92 -136
  534. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +29 -8
  535. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/factory.ts +183 -0
  536. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/manifest.ts +42 -0
  537. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/types.ts +140 -0
  538. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk.ts +3 -0
  539. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +226 -31
  540. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-role-guard.ts +22 -0
  541. package/packages/omo-codex/plugin/components/ulw-loop/src/state-lock.ts +239 -0
  542. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
  543. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +19 -6
  544. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +107 -0
  545. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  546. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +131 -82
  547. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +147 -0
  548. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint.test.ts +16 -22
  549. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +4 -2
  550. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint.test.ts +31 -2
  551. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +2 -0
  552. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-complete-goals.test.ts +3 -1
  553. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +35 -8
  554. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +38 -4
  555. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-json-errors.test.ts +27 -0
  556. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-scope-required.test.ts +144 -0
  557. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +185 -0
  558. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +8 -3
  559. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +6 -0
  560. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +37 -2
  561. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +52 -11
  562. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  563. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/cli-session.ts +4 -0
  564. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +9 -4
  565. package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +67 -0
  566. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  567. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  568. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io-cross-process.test.ts +106 -0
  569. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +36 -2
  570. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  571. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  572. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-fields-messages.test.ts +98 -0
  573. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-lazycodex-surface.test.ts +93 -0
  574. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  575. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +51 -2
  576. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
  577. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  578. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +58 -3
  579. package/packages/omo-codex/plugin/components/ulw-loop/test/review-blockers.test.ts +9 -7
  580. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-contract.test.ts +137 -0
  581. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-driver-states.test.ts +145 -0
  582. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-session-context.test.ts +148 -0
  583. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +450 -7
  584. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-role-matrix.test.ts +113 -0
  585. package/packages/omo-codex/plugin/components/ulw-loop/test/state-lock.test.ts +218 -0
  586. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  587. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  588. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  589. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +13 -8
  590. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  591. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  592. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  593. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  594. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  595. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  596. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  597. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  598. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +18 -0
  599. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  600. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  601. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  602. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  603. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  604. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  605. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  606. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  607. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  608. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  609. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  610. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  611. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  612. package/packages/omo-codex/plugin/model-catalog.json +16 -7
  613. package/packages/omo-codex/plugin/package-lock.json +676 -524
  614. package/packages/omo-codex/plugin/package.json +2 -3
  615. package/packages/omo-codex/plugin/scripts/AGENTS.md +39 -0
  616. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -2
  617. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  618. package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
  619. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  620. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +16 -7
  621. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +8 -4
  622. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +19 -90
  623. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +1 -1
  624. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +96 -57
  625. package/packages/omo-codex/plugin/shared/package.json +3 -4
  626. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  627. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  628. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  629. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  630. package/packages/omo-codex/plugin/skills/ast-grep/SKILL.md +1 -1
  631. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  632. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +1 -1
  633. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  634. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  635. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  636. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  637. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  638. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  639. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  640. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  641. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +3 -1
  642. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  643. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  644. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  645. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  646. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  647. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  648. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  649. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  650. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  651. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  652. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  653. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +10 -0
  654. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +15 -8
  655. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +10 -2
  656. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +2 -0
  657. package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +145 -0
  658. package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +2 -0
  659. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  660. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  661. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  662. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  663. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  664. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  665. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  666. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  667. package/packages/omo-codex/plugin/skills/git-master/SKILL.md +1 -1
  668. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +20 -18
  669. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +4 -2
  670. package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +1 -1
  671. package/packages/omo-codex/plugin/skills/programming/SKILL.md +1 -1
  672. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +10 -8
  673. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +7 -5
  674. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +116 -424
  675. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  676. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +26 -9
  677. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  678. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  679. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  680. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  681. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +46 -24
  682. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +31 -33
  683. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  684. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +34 -4
  685. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  686. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +32 -8
  687. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -7
  688. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  689. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  690. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  691. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +14 -7
  692. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  693. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +10 -7
  694. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  695. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  696. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +16 -51
  697. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -3
  698. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  699. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +14 -4
  700. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  701. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  702. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  703. package/packages/omo-codex/plugin/test/auto-update.test.mjs +4 -29
  704. package/packages/omo-codex/plugin/test/bootstrap-default-role.test.mjs +66 -0
  705. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  706. package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
  707. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  708. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -51
  709. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +100 -2
  710. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +5 -6
  711. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  712. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  713. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +35 -35
  714. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +1 -1
  715. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  716. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +107 -15
  717. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +168 -0
  718. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +54 -24
  719. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +18 -119
  720. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  721. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  722. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  723. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  724. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  725. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -5
  726. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  727. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  728. package/packages/omo-codex/scripts/check-model-catalog-parity.mjs +42 -0
  729. package/packages/omo-codex/scripts/install-cache-copy.test.mjs +27 -1
  730. package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +1 -1
  731. package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +2 -1
  732. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
  733. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +5 -5
  734. package/packages/omo-codex/scripts/install-config.test.mjs +15 -17
  735. package/packages/omo-codex/scripts/install-dist/install-local.mjs +9652 -1394
  736. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +3 -4
  737. package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
  738. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  739. package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
  740. package/packages/omo-codex/scripts/install-packaged-local.test.mjs +1 -6
  741. package/packages/{omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md → prompts-core/prompts/ultrawork/codex.md} +46 -31
  742. package/packages/shared-skills/package.json +7 -1
  743. package/packages/shared-skills/skill-source-filter.d.ts +16 -0
  744. package/packages/shared-skills/skill-source-filter.mjs +44 -0
  745. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  746. package/packages/shared-skills/skills/ast-grep/SKILL.md +1 -1
  747. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  748. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +1 -1
  749. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  750. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  751. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  752. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  753. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  754. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  755. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  756. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  757. package/packages/shared-skills/skills/debugging/SKILL.md +3 -1
  758. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  759. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  760. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  761. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  762. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  763. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  764. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  765. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  766. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  767. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  768. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  769. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  770. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -0
  771. package/packages/shared-skills/skills/frontend/SKILL.md +15 -8
  772. package/packages/shared-skills/skills/frontend/references/design/README.md +10 -2
  773. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +2 -0
  774. package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +145 -0
  775. package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +2 -0
  776. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  777. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  778. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  779. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  780. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  781. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  782. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  783. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  784. package/packages/shared-skills/skills/git-master/SKILL.md +1 -1
  785. package/packages/shared-skills/skills/init-deep/SKILL.md +14 -14
  786. package/packages/shared-skills/skills/lsp-setup/SKILL.md +1 -1
  787. package/packages/shared-skills/skills/programming/SKILL.md +1 -1
  788. package/packages/shared-skills/skills/refactor/SKILL.md +4 -4
  789. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
  790. package/packages/shared-skills/skills/review-work/SKILL.md +101 -419
  791. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  792. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +26 -9
  793. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  794. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  795. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  796. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  797. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +20 -19
  798. package/packages/shared-skills/skills/ulw-plan/SKILL.md +7 -8
  799. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  800. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  801. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  802. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  803. package/packages/shared-skills/skills/ulw-research/SKILL.md +8 -3
  804. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  805. package/packages/shared-skills/skills/visual-qa/SKILL.md +4 -3
  806. package/postinstall.mjs +2 -0
  807. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  808. package/script/qa/xterm-live-terminal.mjs +18 -2
  809. package/dist/config/schema/codegraph.d.ts +0 -12
  810. package/dist/config/schema/start-work.d.ts +0 -5
  811. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  812. package/dist/features/builtin-skills/index.d.ts +0 -1
  813. package/dist/features/builtin-skills/skill-file-loader.d.ts +0 -1
  814. package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +0 -1
  815. package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +0 -1
  816. package/dist/features/builtin-skills/skills/debugging.d.ts +0 -1
  817. package/dist/features/builtin-skills/skills/dev-browser.d.ts +0 -1
  818. package/dist/features/builtin-skills/skills/frontend.d.ts +0 -1
  819. package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +0 -1
  820. package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +0 -1
  821. package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +0 -1
  822. package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +0 -1
  823. package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +0 -1
  824. package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +0 -1
  825. package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +0 -1
  826. package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +0 -1
  827. package/dist/features/builtin-skills/skills/git-master-skill-metadata.d.ts +0 -1
  828. package/dist/features/builtin-skills/skills/git-master.d.ts +0 -1
  829. package/dist/features/builtin-skills/skills/index.d.ts +0 -1
  830. package/dist/features/builtin-skills/skills/init-deep.d.ts +0 -1
  831. package/dist/features/builtin-skills/skills/playwright-cli.d.ts +0 -1
  832. package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +0 -1
  833. package/dist/features/builtin-skills/skills/playwright.d.ts +0 -1
  834. package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +0 -1
  835. package/dist/features/builtin-skills/skills/review-work.d.ts +0 -1
  836. package/dist/features/builtin-skills/skills/security-research.d.ts +0 -1
  837. package/dist/features/builtin-skills/skills/security-review.d.ts +0 -1
  838. package/dist/features/builtin-skills/skills/team-mode.d.ts +0 -1
  839. package/dist/features/builtin-skills/skills/visual-qa.d.ts +0 -1
  840. package/dist/features/builtin-skills/skills.d.ts +0 -1
  841. package/dist/features/builtin-skills/types.d.ts +0 -1
  842. package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +0 -1
  843. package/dist/features/claude-code-plugin-loader/command-loader.d.ts +0 -1
  844. package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +0 -1
  845. package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +0 -1
  846. package/dist/features/claude-code-plugin-loader/discovery.d.ts +0 -1
  847. package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +0 -1
  848. package/dist/features/claude-code-plugin-loader/index.d.ts +0 -1
  849. package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +0 -1
  850. package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +0 -1
  851. package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +0 -1
  852. package/dist/features/claude-code-plugin-loader/loader.d.ts +0 -1
  853. package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +0 -1
  854. package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +0 -1
  855. package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +0 -1
  856. package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +0 -1
  857. package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +0 -1
  858. package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +0 -1
  859. package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +0 -1
  860. package/dist/features/claude-code-plugin-loader/types.d.ts +0 -1
  861. package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +0 -17
  862. package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
  863. package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
  864. package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
  865. package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
  866. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
  867. package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
  868. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  869. package/dist/mcp/codegraph.d.ts +0 -16
  870. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  871. package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +0 -1
  872. package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +0 -1
  873. package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +0 -1
  874. package/dist/shared/prompt-async-gate/queue.d.ts +0 -1
  875. package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +0 -1
  876. package/dist/shared/prompt-async-gate/reservations.d.ts +0 -1
  877. package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +0 -1
  878. package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +0 -1
  879. package/dist/shared/prompt-async-gate/timing.d.ts +0 -1
  880. package/dist/shared/prompt-async-gate/types.d.ts +0 -1
  881. package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
  882. package/dist/skills/data-scientist/references/execution-templates.md +0 -197
  883. package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
  884. package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
  885. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  886. package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
  887. package/dist/tools/delegate-task/anthropic-categories.d.ts +0 -2
  888. package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
  889. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  890. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  891. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  892. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  893. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  894. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  895. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  896. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  897. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12149
  898. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9747
  899. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  900. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  901. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  902. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  903. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  904. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  905. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  906. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -309
  907. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -80
  908. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  909. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  910. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  911. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  912. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  913. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -21
  914. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  915. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  916. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  917. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  918. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  919. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  920. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  921. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  922. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  923. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  924. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  925. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  926. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  927. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  928. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  929. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  930. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  931. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  932. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  933. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  934. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  935. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  936. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  937. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  938. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  939. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  940. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  941. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  942. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  943. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  944. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  945. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  946. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  947. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  948. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  949. package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +0 -21
  950. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  951. package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -471
  952. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  953. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  954. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  955. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  956. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  957. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  958. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  959. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  960. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  961. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  962. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  963. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  964. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  965. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  966. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  967. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
  968. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  969. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  970. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  971. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  972. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  973. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  974. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  975. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  976. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  977. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  978. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  979. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  980. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  981. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  982. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  983. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  984. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  985. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  986. /package/packages/omo-codex/plugin/components/{codegraph → ulw-execute-continuation}/LICENSE +0 -0
  987. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  988. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  989. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  990. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  991. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  992. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  993. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  994. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  995. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  996. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  997. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -175,6 +175,7 @@ async function runJsonRpcStdioServer(config) {
175
175
  const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
176
176
  isClosed = true;
177
177
  config.onIdleTimeout?.();
178
+ config.input.destroy();
178
179
  });
179
180
  const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
180
181
  isClosed = true;
@@ -271,7 +272,11 @@ function createParentWatchdog(config, onDeadParent) {
271
272
  const probeAlive = config.probeAlive ?? isProcessAlive;
272
273
  let fired = false;
273
274
  const timer = setInterval(() => {
274
- if (fired || probeAlive(parentPid))
275
+ if (fired)
276
+ return;
277
+ const alive = probeAlive(parentPid);
278
+ config.onPoll?.(alive);
279
+ if (alive)
275
280
  return;
276
281
  fired = true;
277
282
  onDeadParent(parentPid, pollIntervalMs);
@@ -306,8 +311,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
306
311
  };
307
312
  }
308
313
  // ../lsp-core/src/lsp/client-wrapper.ts
309
- import { existsSync as existsSync9, realpathSync as realpathSync4, statSync as statSync3 } from "node:fs";
310
- import { basename as basename3, dirname as dirname6, join as join4, resolve as resolve7 } from "node:path";
314
+ import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
315
+ import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
311
316
 
312
317
  // ../lsp-core/src/request-context.ts
313
318
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -316,18 +321,17 @@ import { homedir } from "node:os";
316
321
  import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
317
322
 
318
323
  class LspRequestContextParseError extends Error {
319
- code;
320
- name = "LspRequestContextParseError";
321
324
  constructor(code, message) {
322
325
  super(message);
323
326
  this.code = code;
327
+ this.name = "LspRequestContextParseError";
324
328
  }
325
329
  }
326
330
 
327
331
  class LspRequestContextUnavailableError extends Error {
328
- name = "LspRequestContextUnavailableError";
329
332
  constructor() {
330
333
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
334
+ this.name = "LspRequestContextUnavailableError";
331
335
  }
332
336
  }
333
337
  var storage = new AsyncLocalStorage;
@@ -357,7 +361,7 @@ function contextEnv(key) {
357
361
  }
358
362
  function createStandaloneMcpRequestContext(input = {}) {
359
363
  const env = input.env ?? process.env;
360
- const cwd = canonicalCwd(input.cwd ?? process.cwd());
364
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
361
365
  const home = input.homeDir ?? homedir();
362
366
  const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
363
367
  const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
@@ -500,22 +504,15 @@ function effectiveExtension(filePath) {
500
504
 
501
505
  // ../lsp-core/src/lsp/errors.ts
502
506
  class LspConnectionClosedError extends Error {
503
- serverId;
504
- root;
505
- name = "LspConnectionClosedError";
506
507
  constructor(serverId, root, message) {
507
508
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
508
509
  this.serverId = serverId;
509
510
  this.root = root;
511
+ this.name = "LspConnectionClosedError";
510
512
  }
511
513
  }
512
514
 
513
515
  class LspProcessExitedError extends Error {
514
- serverId;
515
- root;
516
- exitCode;
517
- stderrTail;
518
- name = "LspProcessExitedError";
519
516
  constructor(serverId, root, exitCode, stderrTail) {
520
517
  const stderrSuffix = stderrTail ? `
521
518
  stderr tail: ${stderrTail}` : "";
@@ -524,46 +521,59 @@ stderr tail: ${stderrTail}` : "";
524
521
  this.root = root;
525
522
  this.exitCode = exitCode;
526
523
  this.stderrTail = stderrTail;
524
+ this.name = "LspProcessExitedError";
527
525
  }
528
526
  }
529
527
 
530
528
  class LspRequestTimeoutError extends Error {
531
- method;
532
- stderrTail;
533
- name = "LspRequestTimeoutError";
534
529
  constructor(method, stderrTail) {
535
530
  const stderrSuffix = stderrTail ? `
536
531
  recent stderr: ${stderrTail}` : "";
537
532
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
538
533
  this.method = method;
539
534
  this.stderrTail = stderrTail;
535
+ this.name = "LspRequestTimeoutError";
540
536
  }
541
537
  }
542
538
 
543
539
  class LspInvalidPathError extends Error {
544
- name = "LspInvalidPathError";
540
+ constructor() {
541
+ super(...arguments);
542
+ this.name = "LspInvalidPathError";
543
+ }
545
544
  }
546
545
 
547
546
  class LspServerLookupError extends Error {
548
- lookup;
549
- name = "LspServerLookupError";
550
547
  constructor(message, lookup) {
551
548
  super(message);
552
549
  this.lookup = lookup;
550
+ this.name = "LspServerLookupError";
553
551
  }
554
552
  }
555
553
 
556
554
  class LspServerInitializingError extends Error {
557
- originalError;
558
- name = "LspServerInitializingError";
559
555
  constructor(originalError) {
560
556
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
561
557
  this.originalError = originalError;
558
+ this.name = "LspServerInitializingError";
562
559
  }
563
560
  }
564
561
 
565
562
  class LspProcessSpawnError extends Error {
566
- name = "LspProcessSpawnError";
563
+ constructor() {
564
+ super(...arguments);
565
+ this.name = "LspProcessSpawnError";
566
+ }
567
+ }
568
+
569
+ class LspClientRespawnBudgetExceededError extends Error {
570
+ constructor(serverId, root, retryLimit) {
571
+ super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
572
+ this.serverId = serverId;
573
+ this.root = root;
574
+ this.retryLimit = retryLimit;
575
+ this.name = "LspClientRespawnBudgetExceededError";
576
+ }
567
577
  }
568
578
  function isLspDeadConnectionError(err) {
569
579
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -586,6 +596,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
586
596
  // ../lsp-core/src/lsp/connection.ts
587
597
  import { pathToFileURL } from "node:url";
588
598
 
599
+ // ../lsp-core/src/lsp/timer-provider.ts
600
+ var realTimerProvider = {
601
+ now: () => Date.now(),
602
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
603
+ clearTimeout: (handle) => clearTimeout(handle)
604
+ };
605
+
589
606
  // ../lsp-core/src/lsp/constants.ts
590
607
  var DEFAULT_MAX_REFERENCES = 200;
591
608
  var DEFAULT_MAX_SYMBOLS = 200;
@@ -594,9 +611,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
594
611
  var REQUEST_TIMEOUT_MS = 15000;
595
612
  var INIT_TIMEOUT_MS = 60000;
596
613
  var IDLE_TIMEOUT_MS = 5 * 60000;
614
+ var MAX_RESIDENT_CLIENTS = 6;
597
615
  var REAPER_INTERVAL_MS = 60000;
598
616
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
599
617
  var STOP_SIGKILL_GRACE_MS = 1000;
618
+ var CLIENT_RESPAWN_RETRY_LIMIT = 2;
619
+ var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
600
620
 
601
621
  // ../lsp-core/src/lsp/json-rpc-connection.ts
602
622
  var HEADER_SEPARATOR2 = `\r
@@ -608,20 +628,31 @@ var METHOD_NOT_FOUND = -32601;
608
628
  var INTERNAL_ERROR = -32603;
609
629
 
610
630
  class JsonRpcConnection {
611
- reader;
612
- writer;
613
- pendingRequests = new Map;
614
- notificationHandlers = new Map;
615
- requestHandlers = new Map;
616
- closeHandlers = [];
617
- errorHandlers = [];
618
- inputBuffer = Buffer.alloc(0);
619
- nextRequestId = 1;
620
- listening = false;
621
- disposed = false;
622
631
  constructor(reader, writer) {
623
632
  this.reader = reader;
624
633
  this.writer = writer;
634
+ this.pendingRequests = new Map;
635
+ this.notificationHandlers = new Map;
636
+ this.requestHandlers = new Map;
637
+ this.closeHandlers = [];
638
+ this.errorHandlers = [];
639
+ this.inputBuffer = Buffer.alloc(0);
640
+ this.nextRequestId = 1;
641
+ this.listening = false;
642
+ this.disposed = false;
643
+ this.handleData = (chunk) => {
644
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
645
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
646
+ this.drainInputBuffer();
647
+ };
648
+ this.handleClose = () => {
649
+ for (const handler of this.closeHandlers) {
650
+ handler();
651
+ }
652
+ };
653
+ this.handleStreamError = (error) => {
654
+ this.emitError(error);
655
+ };
625
656
  }
626
657
  listen() {
627
658
  if (this.listening)
@@ -656,7 +687,8 @@ class JsonRpcConnection {
656
687
  let cancelAfterWrite = false;
657
688
  let settled = false;
658
689
  const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
659
- const responsePromise = new Promise((resolve2, reject) => {
690
+ let rejectAfterCancelWrite;
691
+ const responsePromise = new Promise((resolve, reject) => {
660
692
  const cleanup = () => {
661
693
  options.signal?.removeEventListener("abort", onAbort);
662
694
  };
@@ -667,22 +699,26 @@ class JsonRpcConnection {
667
699
  this.pendingRequests.delete(key);
668
700
  cleanup();
669
701
  const rejectCancelled = () => reject(abortError(options.signal));
702
+ rejectAfterCancelWrite = async () => {
703
+ try {
704
+ await writeCancel();
705
+ } catch (error) {
706
+ this.emitError(toError(error));
707
+ }
708
+ rejectCancelled();
709
+ };
670
710
  if (!requestWritten) {
671
711
  cancelAfterWrite = true;
672
- rejectCancelled();
673
712
  return;
674
713
  }
675
- writeCancel().then(rejectCancelled, (error) => {
676
- this.emitError(toError(error));
677
- rejectCancelled();
678
- });
714
+ rejectAfterCancelWrite();
679
715
  };
680
716
  const onAbort = () => settleCancel();
681
717
  this.pendingRequests.set(key, {
682
718
  resolve(result) {
683
719
  settled = true;
684
720
  cleanup();
685
- resolve2(result);
721
+ resolve(result);
686
722
  },
687
723
  reject(error) {
688
724
  settled = true;
@@ -703,7 +739,7 @@ class JsonRpcConnection {
703
739
  await this.writeMessage(message);
704
740
  requestWritten = true;
705
741
  if (cancelAfterWrite)
706
- await writeCancel();
742
+ await rejectAfterCancelWrite?.();
707
743
  } catch (error) {
708
744
  if (settled)
709
745
  return responsePromise;
@@ -742,19 +778,6 @@ class JsonRpcConnection {
742
778
  this.notificationHandlers.clear();
743
779
  this.requestHandlers.clear();
744
780
  }
745
- handleData = (chunk) => {
746
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
747
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
748
- this.drainInputBuffer();
749
- };
750
- handleClose = () => {
751
- for (const handler of this.closeHandlers) {
752
- handler();
753
- }
754
- };
755
- handleStreamError = (error) => {
756
- this.emitError(error);
757
- };
758
781
  drainInputBuffer() {
759
782
  while (true) {
760
783
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
@@ -854,13 +877,13 @@ class JsonRpcConnection {
854
877
  const payload = `Content-Length: ${Buffer.byteLength(body, "utf8")}\r
855
878
  \r
856
879
  ${body}`;
857
- return new Promise((resolve2, reject) => {
880
+ return new Promise((resolve, reject) => {
858
881
  this.writer.write(payload, (error) => {
859
882
  if (error) {
860
883
  reject(error);
861
884
  return;
862
885
  }
863
- resolve2();
886
+ resolve();
864
887
  });
865
888
  });
866
889
  }
@@ -947,9 +970,9 @@ function validateCwd(cwd) {
947
970
  }
948
971
  }
949
972
  function wrap(proc) {
950
- const exitedPromise = new Promise((resolve2) => {
951
- proc.once("close", (code) => resolve2(code ?? 0));
952
- proc.once("error", () => resolve2(1));
973
+ const exitedPromise = new Promise((resolve) => {
974
+ proc.once("close", (code) => resolve(code ?? 0));
975
+ proc.once("error", () => resolve(1));
953
976
  });
954
977
  if (!proc.stdin || !proc.stdout || !proc.stderr) {
955
978
  throw new LspProcessSpawnError("Spawned process is missing one of stdin/stdout/stderr pipes");
@@ -1102,33 +1125,29 @@ function isPosition(value) {
1102
1125
 
1103
1126
  // ../lsp-core/src/lsp/transport.ts
1104
1127
  class LspClientNotStartedError extends Error {
1105
- serverId;
1106
- root;
1107
- name = "LspClientNotStartedError";
1108
1128
  constructor(serverId, root) {
1109
1129
  super("LSP client not started");
1110
1130
  this.serverId = serverId;
1111
1131
  this.root = root;
1132
+ this.name = "LspClientNotStartedError";
1112
1133
  }
1113
1134
  }
1114
1135
 
1115
1136
  class LspClientTransport {
1116
- root;
1117
- server;
1118
- proc = null;
1119
- connection = null;
1120
- stderrBuffer = [];
1121
- processExited = false;
1122
- diagnosticsStore = new Map;
1123
- requestTimeoutMs;
1124
- initializeTimeoutMs;
1125
- workspaceApplyEditHandler = null;
1126
- diagnosticPullSupported = false;
1127
- constructor(root, server2, timeouts = {}) {
1137
+ constructor(root, server, timeouts = {}) {
1128
1138
  this.root = root;
1129
- this.server = server2;
1139
+ this.server = server;
1140
+ this.proc = null;
1141
+ this.connection = null;
1142
+ this.stderrBuffer = [];
1143
+ this.processExited = false;
1144
+ this.diagnosticsStore = new Map;
1145
+ this.workspaceApplyEditHandler = null;
1146
+ this.diagnosticPullSupported = false;
1147
+ this.documentFormattingSupported = false;
1130
1148
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
1131
1149
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
1150
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
1132
1151
  }
1133
1152
  pid() {
1134
1153
  return this.proc?.pid;
@@ -1148,6 +1167,12 @@ class LspClientTransport {
1148
1167
  isDiagnosticPullSupported() {
1149
1168
  return this.diagnosticPullSupported;
1150
1169
  }
1170
+ setDocumentFormattingSupported(supported) {
1171
+ this.documentFormattingSupported = supported;
1172
+ }
1173
+ isDocumentFormattingSupported() {
1174
+ return this.documentFormattingSupported;
1175
+ }
1151
1176
  handlePublishDiagnostics(params) {
1152
1177
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
1153
1178
  }
@@ -1223,7 +1248,7 @@ class LspClientTransport {
1223
1248
  const options = args[1];
1224
1249
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
1225
1250
  const timeoutController = new AbortController;
1226
- const timeoutHandle = setTimeout(() => {
1251
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
1227
1252
  const stderrTail = this.stderrBuffer.slice(-5).join(`
1228
1253
  `);
1229
1254
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -1242,7 +1267,7 @@ class LspClientTransport {
1242
1267
  }
1243
1268
  throw error;
1244
1269
  } finally {
1245
- clearTimeout(timeoutHandle);
1270
+ this.timerProvider.clearTimeout(timeoutHandle);
1246
1271
  combinedSignal.dispose();
1247
1272
  }
1248
1273
  }
@@ -1293,8 +1318,8 @@ class LspClientTransport {
1293
1318
  try {
1294
1319
  proc.kill();
1295
1320
  let timeoutId;
1296
- const timeoutPromise = new Promise((resolve2) => {
1297
- timeoutId = setTimeout(resolve2, STOP_HARD_KILL_TIMEOUT_MS);
1321
+ const timeoutPromise = new Promise((resolve) => {
1322
+ timeoutId = setTimeout(resolve, STOP_HARD_KILL_TIMEOUT_MS);
1298
1323
  });
1299
1324
  await Promise.race([
1300
1325
  proc.exited.then(() => {
@@ -1310,7 +1335,7 @@ class LspClientTransport {
1310
1335
  proc.kill("SIGKILL");
1311
1336
  await Promise.race([
1312
1337
  proc.exited,
1313
- new Promise((resolve2) => setTimeout(resolve2, STOP_SIGKILL_GRACE_MS))
1338
+ new Promise((resolve) => setTimeout(resolve, STOP_SIGKILL_GRACE_MS))
1314
1339
  ]);
1315
1340
  } catch (error) {
1316
1341
  reportBestEffortCleanupError("hard process kill", error instanceof Error ? error : String(error));
@@ -1361,6 +1386,14 @@ function supportsDiagnosticPull(capabilities) {
1361
1386
  return false;
1362
1387
  return Object.hasOwn(capabilities, "diagnosticProvider");
1363
1388
  }
1389
+ function supportsDocumentFormatting(capabilities) {
1390
+ if (capabilities === undefined)
1391
+ return false;
1392
+ const provider = capabilities.documentFormattingProvider;
1393
+ if (provider === undefined || provider === null || provider === false)
1394
+ return false;
1395
+ return provider === true || typeof provider === "object";
1396
+ }
1364
1397
 
1365
1398
  class LspClientConnection extends LspClientTransport {
1366
1399
  async initialize() {
@@ -1377,6 +1410,7 @@ class LspClientConnection extends LspClientTransport {
1377
1410
  references: {},
1378
1411
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
1379
1412
  publishDiagnostics: {},
1413
+ formatting: { dynamicRegistration: false },
1380
1414
  rename: {
1381
1415
  prepareSupport: true,
1382
1416
  prepareSupportDefaultBehavior: 1
@@ -1418,6 +1452,7 @@ class LspClientConnection extends LspClientTransport {
1418
1452
  initializationOptions: this.server.initialization
1419
1453
  }, { timeoutMs: this.initializeTimeoutMs });
1420
1454
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
1455
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
1421
1456
  await this.sendNotification("initialized", {});
1422
1457
  await this.sendNotification("workspace/didChangeConfiguration", {
1423
1458
  settings: { json: { validate: { enable: true } } }
@@ -1613,6 +1648,17 @@ function canonicalPath(filePath) {
1613
1648
  return absolute;
1614
1649
  }
1615
1650
  }
1651
+ function normalizeDocumentUri(uri) {
1652
+ let decoded = uri;
1653
+ try {
1654
+ decoded = decodeURIComponent(uri);
1655
+ } catch {
1656
+ decoded = uri;
1657
+ }
1658
+ if (process.platform !== "win32")
1659
+ return decoded;
1660
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1661
+ }
1616
1662
  function isSameOrDescendant(candidate, parent) {
1617
1663
  const suffix = relative2(parent, candidate);
1618
1664
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1623,17 +1669,18 @@ function movedPath(candidate, oldPath, newPath) {
1623
1669
  }
1624
1670
 
1625
1671
  class WorkspaceDocumentState {
1626
- sendNotification;
1627
- clearDiagnostics;
1628
- openDocuments = new Map;
1629
- openByUri = new Map;
1630
- openPromises = new Map;
1631
- now;
1632
- versionlessPublishQuiescenceMs;
1633
1672
  constructor(sendNotification, clearDiagnostics, options = {}) {
1634
1673
  this.sendNotification = sendNotification;
1635
1674
  this.clearDiagnostics = clearDiagnostics;
1636
- this.now = options.now ?? (() => Date.now());
1675
+ this.openDocuments = new Map;
1676
+ this.openByUri = new Map;
1677
+ this.openPromises = new Map;
1678
+ this.timerProvider = options.timerProvider ?? {
1679
+ now: options.now ?? (() => Date.now()),
1680
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1681
+ clearTimeout: (handle) => clearTimeout(handle)
1682
+ };
1683
+ this.now = () => this.timerProvider.now();
1637
1684
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1638
1685
  }
1639
1686
  async openFile(filePath) {
@@ -1655,7 +1702,7 @@ class WorkspaceDocumentState {
1655
1702
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1656
1703
  }
1657
1704
  getStoredDiagnostics(uri) {
1658
- const state = this.openByUri.get(uri);
1705
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1659
1706
  if (!state)
1660
1707
  return [];
1661
1708
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1677,13 +1724,13 @@ class WorkspaceDocumentState {
1677
1724
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1678
1725
  }
1679
1726
  getPullCache(snapshot) {
1680
- const state = this.openByUri.get(snapshot.uri);
1727
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1681
1728
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1682
1729
  return null;
1683
1730
  return state.pullCache;
1684
1731
  }
1685
1732
  recordPullDiagnostics(snapshot, report) {
1686
- const state = this.openByUri.get(snapshot.uri);
1733
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1687
1734
  if (!state)
1688
1735
  return;
1689
1736
  state.pullCache = {
@@ -1693,7 +1740,7 @@ class WorkspaceDocumentState {
1693
1740
  };
1694
1741
  }
1695
1742
  recordPublishedDiagnostics(params) {
1696
- const state = this.openByUri.get(params.uri);
1743
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1697
1744
  if (!state)
1698
1745
  return;
1699
1746
  state.publishGeneration += 1;
@@ -1707,7 +1754,7 @@ class WorkspaceDocumentState {
1707
1754
  this.notifyWaiters(state);
1708
1755
  }
1709
1756
  resolvePushDiagnostics(snapshot) {
1710
- const state = this.openByUri.get(snapshot.uri);
1757
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1711
1758
  if (!state?.lastPublish)
1712
1759
  return { status: "missing" };
1713
1760
  const publish = state.lastPublish;
@@ -1721,7 +1768,7 @@ class WorkspaceDocumentState {
1721
1768
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1722
1769
  }
1723
1770
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1724
- const state = this.openByUri.get(snapshot.uri);
1771
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1725
1772
  if (!state || timeoutMs <= 0)
1726
1773
  return Promise.resolve();
1727
1774
  return new Promise((resolveActivity) => {
@@ -1730,11 +1777,11 @@ class WorkspaceDocumentState {
1730
1777
  if (settled)
1731
1778
  return;
1732
1779
  settled = true;
1733
- clearTimeout(timer);
1780
+ this.timerProvider.clearTimeout(timer);
1734
1781
  state.waiters.delete(finish);
1735
1782
  resolveActivity();
1736
1783
  };
1737
- const timer = setTimeout(finish, timeoutMs);
1784
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1738
1785
  if (typeof timer.unref === "function")
1739
1786
  timer.unref();
1740
1787
  state.waiters.add(finish);
@@ -1842,7 +1889,7 @@ class WorkspaceDocumentState {
1842
1889
  waiters: new Set
1843
1890
  };
1844
1891
  this.openDocuments.set(path, state);
1845
- this.openByUri.set(state.uri, state);
1892
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
1846
1893
  this.notifyWaiters(state);
1847
1894
  await this.sendNotification("textDocument/didOpen", {
1848
1895
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -1867,7 +1914,7 @@ class WorkspaceDocumentState {
1867
1914
  }
1868
1915
  async closeDocument(state) {
1869
1916
  this.openDocuments.delete(state.path);
1870
- this.openByUri.delete(state.uri);
1917
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
1871
1918
  this.clearDiagnostics(state.uri);
1872
1919
  this.notifyWaiters(state);
1873
1920
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -1896,13 +1943,11 @@ import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3,
1896
1943
  import { fileURLToPath } from "node:url";
1897
1944
 
1898
1945
  class WorkspaceEditPathError extends Error {
1899
- path;
1900
- detail;
1901
- name = "WorkspaceEditPathError";
1902
1946
  constructor(path, detail) {
1903
1947
  super(`${detail}: ${path}`);
1904
1948
  this.path = path;
1905
1949
  this.detail = detail;
1950
+ this.name = "WorkspaceEditPathError";
1906
1951
  }
1907
1952
  }
1908
1953
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -2194,13 +2239,11 @@ function canonicalFingerprint(operations) {
2194
2239
 
2195
2240
  // ../lsp-core/src/lsp/workspace-edit-types.ts
2196
2241
  class WorkspaceEditValidationError extends Error {
2197
- changeIndex;
2198
- detail;
2199
- name = "WorkspaceEditValidationError";
2200
2242
  constructor(changeIndex, detail) {
2201
2243
  super(`change ${changeIndex}: ${detail}`);
2202
2244
  this.changeIndex = changeIndex;
2203
2245
  this.detail = detail;
2246
+ this.name = "WorkspaceEditValidationError";
2204
2247
  }
2205
2248
  }
2206
2249
 
@@ -2286,14 +2329,14 @@ function parseSinglePathResource(input, kind) {
2286
2329
  return;
2287
2330
  }
2288
2331
  if (kind === "create") {
2289
- const options2 = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
2332
+ const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
2290
2333
  target.operations.push({
2291
2334
  kind,
2292
2335
  changeIndex,
2293
2336
  path: resolvedPath.path,
2294
2337
  reportedPath: resolvedPath.requestedPath,
2295
- overwrite: options2["overwrite"] ?? false,
2296
- ignoreIfExists: options2["ignoreIfExists"] ?? false,
2338
+ overwrite: options["overwrite"] ?? false,
2339
+ ignoreIfExists: options["ignoreIfExists"] ?? false,
2297
2340
  followedSymbolicLink: resolvedPath.followedSymbolicLink
2298
2341
  });
2299
2342
  return;
@@ -2698,10 +2741,9 @@ function simulateDelete(operation, virtual) {
2698
2741
  import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
2699
2742
  import { dirname as dirname4, resolve as resolve5 } from "node:path";
2700
2743
  class WorkspaceSnapshotBuilder {
2701
- workspaceRoot;
2702
- snapshots = new Map;
2703
2744
  constructor(workspaceRoot) {
2704
2745
  this.workspaceRoot = workspaceRoot;
2746
+ this.snapshots = new Map;
2705
2747
  }
2706
2748
  build(operations) {
2707
2749
  this.add(this.workspaceRoot, false);
@@ -2745,8 +2787,10 @@ function snapshotOperations(operations, workspaceRoot) {
2745
2787
 
2746
2788
  // ../lsp-core/src/lsp/workspace-edit-plan.ts
2747
2789
  class PlanPathIndex {
2748
- firstChangeByPath = new Map;
2749
- reportedPathByCanonical = new Map;
2790
+ constructor() {
2791
+ this.firstChangeByPath = new Map;
2792
+ this.reportedPathByCanonical = new Map;
2793
+ }
2750
2794
  build(operations) {
2751
2795
  for (const operation of operations) {
2752
2796
  switch (operation.kind) {
@@ -2762,11 +2806,11 @@ class PlanPathIndex {
2762
2806
  }
2763
2807
  }
2764
2808
  }
2765
- add(path, reportedPath2, changeIndex) {
2809
+ add(path, reportedPath, changeIndex) {
2766
2810
  if (!this.firstChangeByPath.has(path))
2767
2811
  this.firstChangeByPath.set(path, changeIndex);
2768
2812
  if (!this.reportedPathByCanonical.has(path))
2769
- this.reportedPathByCanonical.set(path, reportedPath2);
2813
+ this.reportedPathByCanonical.set(path, reportedPath);
2770
2814
  }
2771
2815
  }
2772
2816
  function fingerprintWorkspaceEdit(edit, workspaceRoot) {
@@ -2835,14 +2879,11 @@ function isRecord4(value) {
2835
2879
  }
2836
2880
 
2837
2881
  class WorkspaceMutationController {
2838
- workspaceRoot;
2839
- documents;
2840
- activeLease = null;
2841
- nextLeaseId = 1;
2842
- io;
2843
2882
  constructor(workspaceRoot, documents) {
2844
2883
  this.workspaceRoot = workspaceRoot;
2845
2884
  this.documents = documents;
2885
+ this.activeLease = null;
2886
+ this.nextLeaseId = 1;
2846
2887
  }
2847
2888
  setIo(io) {
2848
2889
  this.io = io;
@@ -2881,15 +2922,15 @@ class WorkspaceMutationController {
2881
2922
  };
2882
2923
  }
2883
2924
  lease.phase = "applying";
2884
- lease.applyCompletion = new Promise((resolve6) => {
2885
- lease.resolveApply = resolve6;
2925
+ lease.applyCompletion = new Promise((resolve) => {
2926
+ lease.resolveApply = resolve;
2886
2927
  });
2887
2928
  const edit = isRecord4(params) ? params["edit"] : undefined;
2888
- const record2 = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
2889
- lease.serverApply = record2;
2929
+ const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
2930
+ lease.serverApply = record;
2890
2931
  lease.phase = "settled";
2891
2932
  lease.resolveApply?.();
2892
- return responseFor(record2.result);
2933
+ return responseFor(record.result);
2893
2934
  }
2894
2935
  async reconcileRename(leaseToken, edit) {
2895
2936
  const lease = this.requireActiveLease(leaseToken);
@@ -2905,16 +2946,16 @@ class WorkspaceMutationController {
2905
2946
  const applied = await this.applyEdit(edit, lease);
2906
2947
  return { edit, apply: applied.result };
2907
2948
  }
2908
- reconcileServerApply(record2, edit) {
2949
+ reconcileServerApply(record, edit) {
2909
2950
  if (!edit)
2910
- return { edit, apply: record2.result };
2951
+ return { edit, apply: record.result };
2911
2952
  const fingerprint = fingerprintWorkspaceEdit(edit, this.workspaceRoot);
2912
- if (fingerprint.success && record2.fingerprint !== null && fingerprint.fingerprint === record2.fingerprint) {
2913
- return { edit, apply: record2.result };
2953
+ if (fingerprint.success && record.fingerprint !== null && fingerprint.fingerprint === record.fingerprint) {
2954
+ return { edit, apply: record.result };
2914
2955
  }
2915
2956
  return {
2916
2957
  edit,
2917
- apply: failure("rename result conflicts with server-applied workspace edit", 0, record2.result)
2958
+ apply: failure("rename result conflicts with server-applied workspace edit", 0, record.result)
2918
2959
  };
2919
2960
  }
2920
2961
  async applyEdit(edit, lease) {
@@ -2955,14 +2996,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
2955
2996
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
2956
2997
 
2957
2998
  class LspClient extends LspClientConnection {
2958
- diagnosticPullErrors = [];
2959
- documents;
2960
- workspaceMutations;
2961
- diagnosticsFreshnessTimeoutMs;
2962
- constructor(root, server2, options = {}) {
2963
- super(root, server2, options);
2999
+ constructor(root, server, options = {}) {
3000
+ super(root, server, options);
3001
+ this.diagnosticPullErrors = [];
2964
3002
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2965
3003
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
3004
+ timerProvider: this.timerProvider,
2966
3005
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
2967
3006
  });
2968
3007
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -3015,6 +3054,18 @@ class LspClient extends LspClientConnection {
3015
3054
  textDocument: { uri: pathToFileURL3(absPath).href }
3016
3055
  }, options);
3017
3056
  }
3057
+ async formatDocument(filePath, options, signal) {
3058
+ if (!this.isDocumentFormattingSupported())
3059
+ return null;
3060
+ const absPath = this.resolveWorkspacePath(filePath);
3061
+ await this.openFile(absPath);
3062
+ const requestOptions = signal === undefined ? {} : { signal };
3063
+ const edits = await this.sendRequest("textDocument/formatting", {
3064
+ textDocument: { uri: pathToFileURL3(absPath).href },
3065
+ options
3066
+ }, requestOptions);
3067
+ return edits ?? [];
3068
+ }
3018
3069
  async workspaceSymbols(query, signal) {
3019
3070
  const options = signal === undefined ? {} : { signal };
3020
3071
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -3054,7 +3105,7 @@ class LspClient extends LspClientConnection {
3054
3105
  const absPath = this.resolveWorkspacePath(filePath);
3055
3106
  const uri = pathToFileURL3(absPath).href;
3056
3107
  await this.openFile(absPath);
3057
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
3108
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
3058
3109
  for (;; ) {
3059
3110
  signal?.throwIfAborted();
3060
3111
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -3067,13 +3118,13 @@ class LspClient extends LspClientConnection {
3067
3118
  if (!pushFallbackOnly) {
3068
3119
  const cached = this.documents.getPullCache(snapshot);
3069
3120
  try {
3070
- const remainingMs2 = deadlineAt - Date.now();
3071
- if (remainingMs2 <= 0)
3121
+ const remainingMs = deadlineAt - this.timerProvider.now();
3122
+ if (remainingMs <= 0)
3072
3123
  return this.freshnessTimeout(absPath);
3073
3124
  const result = await this.sendRequest("textDocument/diagnostic", {
3074
3125
  textDocument: { uri },
3075
3126
  ...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
3076
- }, { timeoutMs: remainingMs2, ...signal === undefined ? {} : { signal } });
3127
+ }, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
3077
3128
  if (!this.documents.isCurrentSnapshot(snapshot))
3078
3129
  continue;
3079
3130
  const report = this.parseDiagnosticPullReport(result);
@@ -3102,7 +3153,7 @@ class LspClient extends LspClientConnection {
3102
3153
  }
3103
3154
  if (!pushFallbackOnly)
3104
3155
  continue;
3105
- const remainingMs = deadlineAt - Date.now();
3156
+ const remainingMs = deadlineAt - this.timerProvider.now();
3106
3157
  if (remainingMs <= 0) {
3107
3158
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
3108
3159
  const cached = this.documents.getPullCache(snapshot);
@@ -3154,7 +3205,7 @@ function waitForDiagnosticsActivity(wait, signal) {
3154
3205
  return wait;
3155
3206
  if (signal.aborted)
3156
3207
  return Promise.reject(abortError2(signal));
3157
- return new Promise((resolve7, reject) => {
3208
+ return new Promise((resolve, reject) => {
3158
3209
  const onAbort = () => {
3159
3210
  signal.removeEventListener("abort", onAbort);
3160
3211
  reject(abortError2(signal));
@@ -3162,7 +3213,7 @@ function waitForDiagnosticsActivity(wait, signal) {
3162
3213
  signal.addEventListener("abort", onAbort, { once: true });
3163
3214
  wait.then(() => {
3164
3215
  signal.removeEventListener("abort", onAbort);
3165
- resolve7();
3216
+ resolve();
3166
3217
  }, (error) => {
3167
3218
  signal.removeEventListener("abort", onAbort);
3168
3219
  reject(error);
@@ -3230,7 +3281,7 @@ async function stopClientBestEffort(client) {
3230
3281
  function awaitWithSignal(promise, signal) {
3231
3282
  if (!signal)
3232
3283
  return promise;
3233
- return new Promise((resolve7, reject) => {
3284
+ return new Promise((resolve, reject) => {
3234
3285
  let settled = false;
3235
3286
  const onAbort = () => {
3236
3287
  if (settled)
@@ -3248,7 +3299,7 @@ function awaitWithSignal(promise, signal) {
3248
3299
  return;
3249
3300
  settled = true;
3250
3301
  signal.removeEventListener("abort", onAbort);
3251
- resolve7(value);
3302
+ resolve(value);
3252
3303
  }, (err) => {
3253
3304
  if (settled)
3254
3305
  return;
@@ -3260,20 +3311,18 @@ function awaitWithSignal(promise, signal) {
3260
3311
  }
3261
3312
 
3262
3313
  class LspManager {
3263
- clients = new Map;
3264
- reaperHandle = null;
3265
- signalDisposer = null;
3266
- disposed = false;
3267
- idleTimeoutMs;
3268
- initTimeoutMs;
3269
- reaperIntervalMs;
3270
- clientFactory;
3271
- now;
3272
3314
  constructor(options = {}) {
3315
+ this.clients = new Map;
3316
+ this.pendingStops = new Map;
3317
+ this.respawnBudgets = new Map;
3318
+ this.reaperHandle = null;
3319
+ this.signalDisposer = null;
3320
+ this.disposed = false;
3273
3321
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
3274
3322
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
3323
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
3275
3324
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
3276
- this.clientFactory = options.clientFactory ?? ((root, server2) => new LspClient(root, server2));
3325
+ this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
3277
3326
  this.now = options.now ?? (() => Date.now());
3278
3327
  this.startReaper();
3279
3328
  this.signalDisposer = installProcessSignalCleanup(() => this.stopAll());
@@ -3291,38 +3340,103 @@ class LspManager {
3291
3340
  getKey(root, serverId) {
3292
3341
  return `${root}::${serverId}`;
3293
3342
  }
3343
+ tombstoneStop(key, client) {
3344
+ const stop = stopClientBestEffort(client);
3345
+ this.pendingStops.set(key, stop);
3346
+ stop.finally(() => {
3347
+ if (this.pendingStops.get(key) === stop) {
3348
+ this.pendingStops.delete(key);
3349
+ }
3350
+ });
3351
+ return stop;
3352
+ }
3353
+ recordDeadGeneration(key) {
3354
+ let budget = this.respawnBudgets.get(key);
3355
+ if (budget === undefined) {
3356
+ budget = { deadGenerations: 0, exhaustedAt: null };
3357
+ this.respawnBudgets.set(key, budget);
3358
+ }
3359
+ budget.deadGenerations += 1;
3360
+ }
3361
+ markHealthyGeneration(key) {
3362
+ this.respawnBudgets.delete(key);
3363
+ }
3364
+ ensureRespawnAllowed(key, root, serverId) {
3365
+ const budget = this.respawnBudgets.get(key);
3366
+ if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
3367
+ return;
3368
+ if (budget.exhaustedAt === null) {
3369
+ budget.exhaustedAt = this.now();
3370
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3371
+ }
3372
+ if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
3373
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3374
+ }
3375
+ budget.deadGenerations = 0;
3376
+ budget.exhaustedAt = null;
3377
+ }
3294
3378
  reapStale() {
3295
3379
  const t = this.now();
3296
3380
  for (const [key, managed] of this.clients) {
3297
3381
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3298
- stopClientBestEffort(managed.client);
3299
3382
  this.clients.delete(key);
3383
+ this.tombstoneStop(key, managed.client);
3300
3384
  continue;
3301
3385
  }
3302
3386
  if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
3303
- stopClientBestEffort(managed.client);
3304
3387
  this.clients.delete(key);
3388
+ this.tombstoneStop(key, managed.client);
3389
+ }
3390
+ }
3391
+ }
3392
+ evictForAdmission() {
3393
+ while (this.clients.size >= this.maxResidentClients) {
3394
+ const victim = this.leastRecentlyUsedIdleClient();
3395
+ if (!victim)
3396
+ return;
3397
+ this.clients.delete(victim.key);
3398
+ this.tombstoneStop(victim.key, victim.managed.client);
3399
+ }
3400
+ }
3401
+ leastRecentlyUsedIdleClient() {
3402
+ let candidate = null;
3403
+ for (const [key, managed] of this.clients) {
3404
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
3405
+ continue;
3406
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
3407
+ candidate = { key, managed };
3305
3408
  }
3306
3409
  }
3410
+ return candidate;
3307
3411
  }
3308
3412
  async tryDeleteIfOrphaned(key, managed) {
3309
3413
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
3310
3414
  this.clients.delete(key);
3311
- await stopClientBestEffort(managed.client);
3415
+ await this.tombstoneStop(key, managed.client);
3312
3416
  }
3313
3417
  }
3314
- async getClient(root, server2, signal) {
3418
+ async getClient(root, server, signal) {
3315
3419
  if (this.disposed) {
3316
3420
  throw new Error("LspManager has been disposed");
3317
3421
  }
3318
3422
  signal?.throwIfAborted();
3319
- const key = this.getKey(root, server2.id);
3423
+ const key = this.getKey(root, server.id);
3424
+ for (;; ) {
3425
+ const pendingStop = this.pendingStops.get(key);
3426
+ if (pendingStop === undefined)
3427
+ break;
3428
+ await awaitWithSignal(pendingStop, signal);
3429
+ signal?.throwIfAborted();
3430
+ }
3431
+ if (this.disposed) {
3432
+ throw new Error("LspManager has been disposed");
3433
+ }
3320
3434
  let managed = this.clients.get(key);
3321
3435
  if (managed) {
3322
3436
  const t = this.now();
3323
3437
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3324
- await stopClientBestEffort(managed.client);
3325
3438
  this.clients.delete(key);
3439
+ await this.tombstoneStop(key, managed.client);
3326
3440
  managed = undefined;
3327
3441
  }
3328
3442
  }
@@ -3343,15 +3457,21 @@ class LspManager {
3343
3457
  signal.throwIfAborted();
3344
3458
  }
3345
3459
  if (!managed.client.isAlive()) {
3346
- await stopClientBestEffort(managed.client);
3347
- this.clients.delete(key);
3348
- return this.getClient(root, server2, signal);
3460
+ this.recordDeadGeneration(key);
3461
+ if (this.clients.get(key) === managed) {
3462
+ this.clients.delete(key);
3463
+ }
3464
+ await this.tombstoneStop(key, managed.client);
3465
+ return this.getClient(root, server, signal);
3349
3466
  }
3467
+ this.markHealthyGeneration(key);
3350
3468
  managed.refCount++;
3351
3469
  managed.lastUsedAt = this.now();
3352
3470
  return managed.client;
3353
3471
  }
3354
- const client = this.clientFactory(root, server2);
3472
+ this.evictForAdmission();
3473
+ this.ensureRespawnAllowed(key, root, server.id);
3474
+ const client = this.clientFactory(root, server);
3355
3475
  const initStartedAt = this.now();
3356
3476
  const initPromise = (async () => {
3357
3477
  await client.start();
@@ -3374,7 +3494,7 @@ class LspManager {
3374
3494
  if (this.clients.get(key) === newManaged) {
3375
3495
  this.clients.delete(key);
3376
3496
  }
3377
- await stopClientBestEffort(client);
3497
+ await this.tombstoneStop(key, client);
3378
3498
  throw err;
3379
3499
  }
3380
3500
  newManaged.pendingWaiters--;
@@ -3385,6 +3505,15 @@ class LspManager {
3385
3505
  await this.tryDeleteIfOrphaned(key, newManaged);
3386
3506
  signal.throwIfAborted();
3387
3507
  }
3508
+ if (!client.isAlive()) {
3509
+ this.recordDeadGeneration(key);
3510
+ if (this.clients.get(key) === newManaged) {
3511
+ this.clients.delete(key);
3512
+ }
3513
+ await this.tombstoneStop(key, client);
3514
+ return this.getClient(root, server, signal);
3515
+ }
3516
+ this.markHealthyGeneration(key);
3388
3517
  newManaged.refCount++;
3389
3518
  newManaged.lastUsedAt = this.now();
3390
3519
  return client;
@@ -3405,15 +3534,21 @@ class LspManager {
3405
3534
  if (client && managed.client !== client)
3406
3535
  return;
3407
3536
  this.clients.delete(key);
3408
- stopClientBestEffort(managed.client);
3537
+ this.tombstoneStop(key, managed.client);
3409
3538
  }
3410
- warmupClient(root, server2) {
3539
+ warmupClient(root, server) {
3411
3540
  if (this.disposed)
3412
3541
  return;
3413
- const key = this.getKey(root, server2.id);
3414
- if (this.clients.has(key))
3542
+ const key = this.getKey(root, server.id);
3543
+ if (this.clients.has(key) || this.pendingStops.has(key))
3415
3544
  return;
3416
- const client = this.clientFactory(root, server2);
3545
+ this.evictForAdmission();
3546
+ try {
3547
+ this.ensureRespawnAllowed(key, root, server.id);
3548
+ } catch {
3549
+ return;
3550
+ }
3551
+ const client = this.clientFactory(root, server);
3417
3552
  const initStartedAt = this.now();
3418
3553
  const initPromise = (async () => {
3419
3554
  await client.start();
@@ -3438,7 +3573,7 @@ class LspManager {
3438
3573
  if (this.clients.get(key) === managed) {
3439
3574
  this.clients.delete(key);
3440
3575
  }
3441
- stopClientBestEffort(client);
3576
+ this.tombstoneStop(key, client);
3442
3577
  });
3443
3578
  }
3444
3579
  isServerInitializing(root, serverId) {
@@ -3482,8 +3617,11 @@ class LspManager {
3482
3617
  for (const managed of this.clients.values()) {
3483
3618
  stopPromises.push(stopClientBestEffort(managed.client));
3484
3619
  }
3620
+ const tombstonedStops = [...this.pendingStops.values()];
3485
3621
  this.clients.clear();
3486
- await Promise.allSettled(stopPromises);
3622
+ this.respawnBudgets.clear();
3623
+ await Promise.allSettled([...stopPromises, ...tombstonedStops]);
3624
+ this.pendingStops.clear();
3487
3625
  }
3488
3626
  }
3489
3627
  var _defaultInstance = null;
@@ -3501,57 +3639,52 @@ async function disposeDefaultLspManager() {
3501
3639
  }
3502
3640
  }
3503
3641
 
3504
- // ../lsp-core/src/lsp/server-install-state.ts
3505
- import { existsSync as existsSync6, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3506
- import { dirname as dirname5 } from "node:path";
3507
- function getInstallDecisionsPath() {
3508
- return lspRequestContext().installDecisionsPath;
3509
- }
3510
- function loadInstallDecisions() {
3511
- const path = getInstallDecisionsPath();
3512
- if (!existsSync6(path))
3513
- return {};
3514
- try {
3515
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
3516
- return isInstallDecisions(parsed) ? parsed : {};
3517
- } catch {
3518
- return {};
3642
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3643
+ import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
3644
+ import { dirname as dirname5, join as join3 } from "node:path";
3645
+
3646
+ // ../lsp-core/src/lsp/workspace-markers.ts
3647
+ var GIT_WORKSPACE_MARKER = ".git";
3648
+ var PROJECT_WORKSPACE_MARKERS = [
3649
+ "package.json",
3650
+ "pyproject.toml",
3651
+ "Cargo.toml",
3652
+ "go.mod",
3653
+ "pom.xml",
3654
+ "build.gradle"
3655
+ ];
3656
+ var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
3657
+
3658
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3659
+ function findWorkspaceRootOutsideContext(directory) {
3660
+ const marked = nearestMarkedAncestor(directory);
3661
+ if (marked !== undefined)
3662
+ return marked;
3663
+ return realpathSync4(nearestExistingAncestor(directory));
3664
+ }
3665
+ function nearestMarkedAncestor(directory) {
3666
+ let current = directory;
3667
+ for (;; ) {
3668
+ if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
3669
+ return realpathSync4(current);
3670
+ }
3671
+ const parent = dirname5(current);
3672
+ if (parent === current)
3673
+ return;
3674
+ current = parent;
3519
3675
  }
3520
3676
  }
3521
- function loadInstallDecision(serverId) {
3522
- return loadInstallDecisions()[serverId];
3523
- }
3524
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3525
- const decisions = loadInstallDecisions();
3526
- decisions[serverId] = { decision, decidedAt };
3527
- writeInstallDecisions(decisions);
3528
- }
3529
- function isInstallDecision(value) {
3530
- return value === "declined" || value === "allowed";
3531
- }
3532
- function writeInstallDecisions(decisions) {
3533
- const path = getInstallDecisionsPath();
3534
- mkdirSync(dirname5(path), { recursive: true });
3535
- const tmpPath = `${path}.tmp`;
3536
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3537
- `, "utf8");
3538
- renameSync2(tmpPath, path);
3539
- }
3540
- function isInstallDecisions(value) {
3541
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3542
- }
3543
- function isInstallDecisionRecord(value) {
3544
- if (!isRecord5(value))
3545
- return false;
3546
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3547
- }
3548
- function isRecord5(value) {
3549
- return typeof value === "object" && value !== null && !Array.isArray(value);
3677
+ function nearestExistingAncestor(directory) {
3678
+ let current = directory;
3679
+ while (!existsSync6(current)) {
3680
+ const parent = dirname5(current);
3681
+ if (parent === current)
3682
+ return current;
3683
+ current = parent;
3684
+ }
3685
+ return current;
3550
3686
  }
3551
3687
 
3552
- // ../lsp-core/src/lsp/config-loader.ts
3553
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
3554
-
3555
3688
  // ../lsp-core/src/lsp/server-definitions.ts
3556
3689
  var LSP_INSTALL_HINTS = {
3557
3690
  typescript: "npm install -g typescript-language-server typescript",
@@ -3597,6 +3730,26 @@ var LSP_INSTALL_HINTS = {
3597
3730
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
3598
3731
  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"
3599
3732
  };
3733
+ var LSP_LOCAL_INSTALL_HINTS = {
3734
+ typescript: "bun add -d typescript-language-server typescript",
3735
+ vue: "bun add -d @vue/language-server",
3736
+ eslint: "bun add -d vscode-langservers-extracted",
3737
+ oxlint: "bun add -d oxlint",
3738
+ biome: "bun add -d @biomejs/biome",
3739
+ svelte: "bun add -d svelte-language-server",
3740
+ astro: "bun add -d @astrojs/language-server",
3741
+ bash: "bun add -d bash-language-server",
3742
+ "bash-ls": "bun add -d bash-language-server",
3743
+ "yaml-ls": "bun add -d yaml-language-server",
3744
+ php: "bun add -d intelephense",
3745
+ prisma: "bun add -d prisma",
3746
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
3747
+ pyright: "uv add --dev pyright",
3748
+ basedpyright: "uv add --dev basedpyright",
3749
+ ruff: "uv add --dev ruff",
3750
+ ty: "uv add --dev ty",
3751
+ "ruby-lsp": "bundle add ruby-lsp --group development"
3752
+ };
3600
3753
  var BUILTIN_SERVERS = {
3601
3754
  typescript: {
3602
3755
  command: ["typescript-language-server", "--stdio"],
@@ -3699,7 +3852,56 @@ var BUILTIN_SERVERS = {
3699
3852
  }
3700
3853
  };
3701
3854
 
3855
+ // ../lsp-core/src/lsp/server-install-state.ts
3856
+ import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3857
+ import { dirname as dirname6 } from "node:path";
3858
+ function getInstallDecisionsPath() {
3859
+ return lspRequestContext().installDecisionsPath;
3860
+ }
3861
+ function loadInstallDecisions() {
3862
+ const path = getInstallDecisionsPath();
3863
+ if (!existsSync7(path))
3864
+ return {};
3865
+ try {
3866
+ const parsed = JSON.parse(readFileSync3(path, "utf8"));
3867
+ return isInstallDecisions(parsed) ? parsed : {};
3868
+ } catch {
3869
+ return {};
3870
+ }
3871
+ }
3872
+ function loadInstallDecision(serverId) {
3873
+ return loadInstallDecisions()[serverId];
3874
+ }
3875
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3876
+ const decisions = loadInstallDecisions();
3877
+ decisions[serverId] = { decision, decidedAt };
3878
+ writeInstallDecisions(decisions);
3879
+ }
3880
+ function isInstallDecision(value) {
3881
+ return value === "declined" || value === "allowed";
3882
+ }
3883
+ function writeInstallDecisions(decisions) {
3884
+ const path = getInstallDecisionsPath();
3885
+ mkdirSync(dirname6(path), { recursive: true });
3886
+ const tmpPath = `${path}.tmp`;
3887
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3888
+ `, "utf8");
3889
+ renameSync2(tmpPath, path);
3890
+ }
3891
+ function isInstallDecisions(value) {
3892
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3893
+ }
3894
+ function isInstallDecisionRecord(value) {
3895
+ if (!isRecord5(value))
3896
+ return false;
3897
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3898
+ }
3899
+ function isRecord5(value) {
3900
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3901
+ }
3902
+
3702
3903
  // ../lsp-core/src/lsp/config-loader.ts
3904
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
3703
3905
  function getProjectConfigPaths() {
3704
3906
  return lspRequestContext().projectConfigPaths;
3705
3907
  }
@@ -3707,7 +3909,7 @@ function getUserConfigPath() {
3707
3909
  return lspRequestContext().userConfigPath;
3708
3910
  }
3709
3911
  function loadJsonFile(path) {
3710
- if (!existsSync7(path))
3912
+ if (!existsSync8(path))
3711
3913
  return null;
3712
3914
  try {
3713
3915
  const parsed = JSON.parse(readFileSync4(path, "utf-8"));
@@ -3754,10 +3956,10 @@ function getMergedServers() {
3754
3956
  }
3755
3957
  if (seen.has(id))
3756
3958
  continue;
3757
- const server2 = createServerFromEntry(id, entry, source);
3758
- if (!server2)
3959
+ const server = createServerFromEntry(id, entry, source);
3960
+ if (!server)
3759
3961
  continue;
3760
- servers.push(server2);
3962
+ servers.push(server);
3761
3963
  seen.add(id);
3762
3964
  }
3763
3965
  }
@@ -3789,7 +3991,7 @@ function createServerFromEntry(id, entry, source) {
3789
3991
  if (source === "project") {
3790
3992
  if (!builtin)
3791
3993
  return null;
3792
- const server3 = createServer({
3994
+ const server = createServer({
3793
3995
  id,
3794
3996
  command: builtin.command,
3795
3997
  extensions: entry.extensions ?? builtin.extensions,
@@ -3797,35 +3999,35 @@ function createServerFromEntry(id, entry, source) {
3797
3999
  source
3798
4000
  });
3799
4001
  if (entry.initialization !== undefined) {
3800
- server3.initialization = entry.initialization;
4002
+ server.initialization = entry.initialization;
3801
4003
  }
3802
- return server3;
4004
+ return server;
3803
4005
  }
3804
4006
  if (entry.command && entry.extensions) {
3805
- const server3 = createServer({
4007
+ const server = createServer({
3806
4008
  id,
3807
4009
  command: entry.command,
3808
4010
  extensions: entry.extensions,
3809
4011
  priority: entry.priority ?? 0,
3810
4012
  source
3811
4013
  });
3812
- applyOptionalServerFields(server3, entry);
3813
- return server3;
4014
+ applyOptionalServerFields(server, entry);
4015
+ return server;
3814
4016
  }
3815
4017
  if (!builtin)
3816
4018
  return null;
3817
- const server2 = createServer({
4019
+ const server = createServer({
3818
4020
  id,
3819
4021
  command: entry.command ?? builtin.command,
3820
4022
  extensions: entry.extensions ?? builtin.extensions,
3821
4023
  priority: entry.priority ?? 0,
3822
4024
  source
3823
4025
  });
3824
- applyOptionalServerFields(server2, entry);
3825
- return server2;
4026
+ applyOptionalServerFields(server, entry);
4027
+ return server;
3826
4028
  }
3827
4029
  function createServer(input) {
3828
- const server2 = {
4030
+ const server = {
3829
4031
  id: input.id,
3830
4032
  command: input.command,
3831
4033
  extensions: input.extensions,
@@ -3833,19 +4035,19 @@ function createServer(input) {
3833
4035
  source: input.source
3834
4036
  };
3835
4037
  if (input.env !== undefined) {
3836
- server2.env = input.env;
4038
+ server.env = input.env;
3837
4039
  }
3838
4040
  if (input.initialization !== undefined) {
3839
- server2.initialization = input.initialization;
4041
+ server.initialization = input.initialization;
3840
4042
  }
3841
- return server2;
4043
+ return server;
3842
4044
  }
3843
- function applyOptionalServerFields(server2, entry) {
4045
+ function applyOptionalServerFields(server, entry) {
3844
4046
  if (entry.env !== undefined) {
3845
- server2.env = entry.env;
4047
+ server.env = entry.env;
3846
4048
  }
3847
4049
  if (entry.initialization !== undefined) {
3848
- server2.initialization = entry.initialization;
4050
+ server.initialization = entry.initialization;
3849
4051
  }
3850
4052
  }
3851
4053
  function isConfigJson(value) {
@@ -3895,64 +4097,165 @@ function getDisabledServerIds() {
3895
4097
  }
3896
4098
 
3897
4099
  // ../lsp-core/src/lsp/server-installation.ts
3898
- import { existsSync as existsSync8 } from "node:fs";
3899
- import { delimiter as delimiter3, join as join3 } from "node:path";
3900
- function isServerInstalled(command, _workingDirectory) {
3901
- if (command.length === 0)
3902
- return false;
3903
- const [cmd] = command;
3904
- if (!cmd)
3905
- return false;
3906
- if (cmd.includes("/") || cmd.includes("\\")) {
3907
- if (existsSync8(cmd))
3908
- return true;
4100
+ import { existsSync as existsSync9 } from "node:fs";
4101
+ import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
4102
+ var LOCAL_BIN_RULES = [
4103
+ {
4104
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
4105
+ binDirs: [join4("node_modules", ".bin")]
4106
+ },
4107
+ {
4108
+ markers: [
4109
+ "pyproject.toml",
4110
+ "ty.toml",
4111
+ "requirements.txt",
4112
+ "setup.py",
4113
+ "setup.cfg",
4114
+ "Pipfile",
4115
+ "pyrightconfig.json",
4116
+ "ruff.toml",
4117
+ ".ruff.toml"
4118
+ ],
4119
+ binDirs: [
4120
+ join4(".venv", "bin"),
4121
+ join4(".venv", "Scripts"),
4122
+ join4("venv", "bin"),
4123
+ join4("venv", "Scripts"),
4124
+ join4(".env", "bin"),
4125
+ join4(".env", "Scripts")
4126
+ ]
4127
+ },
4128
+ {
4129
+ markers: ["Gemfile", "Gemfile.lock"],
4130
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4131
+ },
4132
+ {
4133
+ markers: ["go.mod", "go.sum", "go.work"],
4134
+ binDirs: ["bin"]
4135
+ }
4136
+ ];
4137
+ var resolutionCache = new Map;
4138
+ var probeCount = 0;
4139
+ function probe(path) {
4140
+ probeCount += 1;
4141
+ return existsSync9(path);
4142
+ }
4143
+ function executableSuffixes(platform, pathExt) {
4144
+ if (platform !== "win32")
4145
+ return [""];
4146
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4147
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4148
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4149
+ }
4150
+ function probeWithSuffixes(directory, command, suffixes) {
4151
+ for (const suffix of suffixes) {
4152
+ const candidate = join4(directory, command + suffix);
4153
+ if (probe(candidate))
4154
+ return candidate;
3909
4155
  }
3910
- const isWindows = process.platform === "win32";
3911
- let exts = [""];
3912
- if (isWindows) {
3913
- const pathExt = process.env["PATHEXT"] ?? "";
3914
- if (pathExt) {
3915
- const systemExts = pathExt.split(";").filter(Boolean);
3916
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
3917
- } else {
3918
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4156
+ return null;
4157
+ }
4158
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4159
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4160
+ let current = resolve7(workingDirectory);
4161
+ while (true) {
4162
+ for (const rule of LOCAL_BIN_RULES) {
4163
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
4164
+ continue;
4165
+ for (const binDir of rule.binDirs) {
4166
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4167
+ if (found !== null)
4168
+ return found;
4169
+ }
3919
4170
  }
4171
+ if (probe(join4(current, ".git")))
4172
+ return null;
4173
+ if (boundary !== undefined && current === boundary)
4174
+ return null;
4175
+ const parent = dirname7(current);
4176
+ if (parent === current)
4177
+ return null;
4178
+ current = parent;
3920
4179
  }
3921
- let pathEnv = process.env["PATH"] ?? "";
3922
- if (isWindows && !pathEnv) {
4180
+ }
4181
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4182
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4183
+ if (platform === "win32" && !pathEnv) {
3923
4184
  pathEnv = process.env["Path"] ?? "";
3924
4185
  }
3925
- const paths = pathEnv.split(delimiter3);
3926
- for (const p of paths) {
3927
- for (const suffix of exts) {
3928
- if (existsSync8(join3(p, cmd + suffix))) {
3929
- return true;
3930
- }
3931
- }
4186
+ for (const entry of pathEnv.split(delimiter3)) {
4187
+ if (entry.length === 0)
4188
+ continue;
4189
+ const found = probeWithSuffixes(entry, command, suffixes);
4190
+ if (found !== null)
4191
+ return found;
3932
4192
  }
3933
- if (cmd === "node")
3934
- return true;
3935
- return false;
4193
+ return null;
4194
+ }
4195
+ function resolveServerBinary(command, workingDirectory, options = {}) {
4196
+ if (command.length === 0)
4197
+ return null;
4198
+ const [cmd] = command;
4199
+ if (cmd === undefined || cmd.length === 0)
4200
+ return null;
4201
+ const platform = options.platform ?? process.platform;
4202
+ const suffixes = executableSuffixes(platform, options.pathExt);
4203
+ if (cmd.includes("/") || cmd.includes("\\")) {
4204
+ const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4205
+ return probe(explicit) ? explicit : null;
4206
+ }
4207
+ const cacheKey = JSON.stringify([
4208
+ workingDirectory ?? "",
4209
+ cmd,
4210
+ platform,
4211
+ options.stopAt ?? "",
4212
+ options.pathExt ?? "",
4213
+ options.pathEnv ?? process.env["PATH"] ?? ""
4214
+ ]);
4215
+ const cached = resolutionCache.get(cacheKey);
4216
+ if (cached !== undefined)
4217
+ return cached;
4218
+ let resolved = null;
4219
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
4220
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4221
+ }
4222
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4223
+ if (resolved === null && cmd === "node")
4224
+ resolved = cmd;
4225
+ resolutionCache.set(cacheKey, resolved);
4226
+ return resolved;
4227
+ }
4228
+ function isServerInstalled(command, workingDirectory, options = {}) {
4229
+ if (command.length === 0)
4230
+ return false;
4231
+ return resolveServerBinary(command, workingDirectory, options) !== null;
3936
4232
  }
3937
4233
 
3938
4234
  // ../lsp-core/src/lsp/server-resolution.ts
4235
+ function withResolvedCommand(command, binaryPath) {
4236
+ return [binaryPath, ...command.slice(1)];
4237
+ }
3939
4238
  function findServerForExtension(ext) {
3940
4239
  const servers = getMergedServers();
3941
- for (const server2 of servers) {
3942
- if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4240
+ const workingDirectory = contextCwd();
4241
+ for (const server of servers) {
4242
+ if (!server.extensions.includes(ext))
4243
+ continue;
4244
+ const binaryPath = resolveServerBinary(server.command, workingDirectory);
4245
+ if (binaryPath !== null) {
3943
4246
  const resolvedServer = {
3944
- id: server2.id,
3945
- command: server2.command,
3946
- extensions: server2.extensions,
3947
- priority: server2.priority
4247
+ id: server.id,
4248
+ command: withResolvedCommand(server.command, binaryPath),
4249
+ extensions: server.extensions,
4250
+ priority: server.priority
3948
4251
  };
3949
- if (server2.env !== undefined) {
4252
+ if (server.env !== undefined) {
3950
4253
  return {
3951
4254
  status: "found",
3952
4255
  server: {
3953
4256
  ...resolvedServer,
3954
- env: server2.env,
3955
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4257
+ env: server.env,
4258
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
3956
4259
  }
3957
4260
  };
3958
4261
  }
@@ -3960,20 +4263,20 @@ function findServerForExtension(ext) {
3960
4263
  status: "found",
3961
4264
  server: {
3962
4265
  ...resolvedServer,
3963
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4266
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
3964
4267
  }
3965
4268
  };
3966
4269
  }
3967
4270
  }
3968
- for (const server2 of servers) {
3969
- if (server2.extensions.includes(ext)) {
3970
- const installHint = LSP_INSTALL_HINTS[server2.id] ?? `Install '${server2.command[0]}' and ensure it's in your PATH`;
4271
+ for (const server of servers) {
4272
+ if (server.extensions.includes(ext)) {
4273
+ const installHint = LSP_INSTALL_HINTS[server.id] ?? `Install '${server.command[0]}' and ensure it's in your PATH`;
3971
4274
  return {
3972
4275
  status: "not_installed",
3973
4276
  server: {
3974
- id: server2.id,
3975
- command: server2.command,
3976
- extensions: server2.extensions
4277
+ id: server.id,
4278
+ command: server.command,
4279
+ extensions: server.extensions
3977
4280
  },
3978
4281
  installHint
3979
4282
  };
@@ -3989,20 +4292,21 @@ function findServerForExtension(ext) {
3989
4292
  function getAllServers() {
3990
4293
  const servers = getMergedServers();
3991
4294
  const disabled = getDisabledServerIds();
4295
+ const workingDirectory = contextCwd();
3992
4296
  const result = [];
3993
4297
  const seen = new Set;
3994
- for (const server2 of servers) {
3995
- if (seen.has(server2.id))
4298
+ for (const server of servers) {
4299
+ if (seen.has(server.id))
3996
4300
  continue;
3997
4301
  result.push({
3998
- id: server2.id,
3999
- installed: isServerInstalled(server2.command),
4000
- extensions: server2.extensions,
4302
+ id: server.id,
4303
+ installed: isServerInstalled(server.command, workingDirectory),
4304
+ extensions: server.extensions,
4001
4305
  disabled: false,
4002
- source: server2.source,
4003
- priority: server2.priority
4306
+ source: server.source,
4307
+ priority: server.priority
4004
4308
  });
4005
- seen.add(server2.id);
4309
+ seen.add(server.id);
4006
4310
  }
4007
4311
  for (const id of disabled) {
4008
4312
  if (seen.has(id))
@@ -4010,7 +4314,7 @@ function getAllServers() {
4010
4314
  const builtin = BUILTIN_SERVERS[id];
4011
4315
  result.push({
4012
4316
  id,
4013
- installed: builtin ? isServerInstalled(builtin.command) : false,
4317
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4014
4318
  extensions: builtin?.extensions ?? [],
4015
4319
  disabled: true,
4016
4320
  source: "disabled",
@@ -4021,7 +4325,6 @@ function getAllServers() {
4021
4325
  }
4022
4326
 
4023
4327
  // ../lsp-core/src/lsp/client-wrapper.ts
4024
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
4025
4328
  function isDirectoryPath(filePath) {
4026
4329
  try {
4027
4330
  return statSync3(filePath).isDirectory();
@@ -4034,36 +4337,40 @@ function findWorkspaceRoot(filePath) {
4034
4337
  const abs = resolveReadablePathInsideContext(filePath);
4035
4338
  let dir = abs;
4036
4339
  if (!isDirectoryPath(dir)) {
4037
- dir = dirname6(dir);
4340
+ dir = dirname8(dir);
4038
4341
  }
4342
+ if (!isPathInside(cwd, abs))
4343
+ return findWorkspaceRootOutsideContext(dir);
4039
4344
  const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4345
+ let nearestPackageRoot;
4040
4346
  while (isPathInside(cwd, dir)) {
4041
4347
  const canonicalDir = existingDirectoryInsideContext(dir, cwd);
4042
4348
  if (canonicalDir !== undefined) {
4043
- for (const marker of WORKSPACE_MARKERS) {
4044
- if (existsSync9(join4(dir, marker))) {
4045
- return canonicalDir;
4046
- }
4349
+ if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
4350
+ return canonicalDir;
4351
+ }
4352
+ if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
4353
+ nearestPackageRoot = canonicalDir;
4047
4354
  }
4048
4355
  }
4049
4356
  if (dir === cwd)
4050
4357
  break;
4051
- dir = dirname6(dir);
4358
+ dir = dirname8(dir);
4052
4359
  }
4053
- return fallbackRoot;
4360
+ return nearestPackageRoot ?? fallbackRoot;
4361
+ }
4362
+ function hasProjectWorkspaceMarker(directory) {
4363
+ return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
4054
4364
  }
4055
4365
  function resolveReadablePathInsideContext(filePath) {
4056
4366
  const cwd = contextCwd();
4057
- const abs = resolve7(cwd, filePath);
4367
+ const abs = resolve8(cwd, filePath);
4058
4368
  if (isPathInside(cwd, abs))
4059
4369
  return abs;
4060
4370
  const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
4061
4371
  if (rebased !== undefined)
4062
4372
  return rebased;
4063
- const canonical = canonicalizeExistingOrNearestAncestor(abs);
4064
- if (isPathInside(cwd, canonical))
4065
- return canonical;
4066
- throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
4373
+ return canonicalizeExistingOrNearestAncestor(abs);
4067
4374
  }
4068
4375
  function resolvePathInsideContext(filePath) {
4069
4376
  const cwd = contextCwd();
@@ -4078,12 +4385,12 @@ function rebaseThroughCanonicalAncestor(path, cwd) {
4078
4385
  let current = path;
4079
4386
  const suffix = [];
4080
4387
  while (true) {
4081
- if (existsSync9(current)) {
4082
- const canonical = realpathSync4(current);
4388
+ if (existsSync10(current)) {
4389
+ const canonical = realpathSync5(current);
4083
4390
  if (isPathInside(cwd, canonical))
4084
- return suffix.length === 0 ? canonical : join4(canonical, ...suffix);
4391
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
4085
4392
  }
4086
- const parent = dirname6(current);
4393
+ const parent = dirname8(current);
4087
4394
  if (parent === current)
4088
4395
  return;
4089
4396
  suffix.unshift(basename3(current));
@@ -4091,9 +4398,9 @@ function rebaseThroughCanonicalAncestor(path, cwd) {
4091
4398
  }
4092
4399
  }
4093
4400
  function existingDirectoryInsideContext(directory, cwd) {
4094
- if (!existsSync9(directory))
4401
+ if (!existsSync10(directory))
4095
4402
  return;
4096
- const canonical = realpathSync4(directory);
4403
+ const canonical = realpathSync5(directory);
4097
4404
  if (!statSync3(canonical).isDirectory())
4098
4405
  return;
4099
4406
  return isPathInside(cwd, canonical) ? canonical : undefined;
@@ -4106,7 +4413,7 @@ function nearestExistingDirectoryInsideContext(directory, cwd) {
4106
4413
  return canonical;
4107
4414
  if (current === cwd)
4108
4415
  return;
4109
- current = dirname6(current);
4416
+ current = dirname8(current);
4110
4417
  }
4111
4418
  return;
4112
4419
  }
@@ -4133,33 +4440,46 @@ function formatServerLookupError(result) {
4133
4440
  ].join(`
4134
4441
  `);
4135
4442
  }
4443
+ function formatInstallOptions(serverId, installHint) {
4444
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
4445
+ if (localHint === undefined) {
4446
+ return ["To install, run:", ` ${installHint}`];
4447
+ }
4448
+ return [
4449
+ "To install in THIS repository (preferred — no global install needed):",
4450
+ ` ${localHint}`,
4451
+ "",
4452
+ "Or install it globally:",
4453
+ ` ${installHint}`
4454
+ ];
4455
+ }
4136
4456
  function formatNotInstalled(result) {
4137
- const { server: server2, installHint } = result;
4138
- const extensions = server2.extensions.join(", ");
4139
- const decision = loadInstallDecision(server2.id)?.decision;
4457
+ const { server, installHint } = result;
4458
+ const extensions = server.extensions.join(", ");
4459
+ const decision = loadInstallDecision(server.id)?.decision;
4140
4460
  const context = lspRequestContext();
4141
4461
  if (decision === "declined") {
4142
- return `LSP server '${server2.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
4462
+ return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
4143
4463
  }
4144
4464
  const header = [
4145
- `LSP server '${server2.id}' for ${extensions} is NOT INSTALLED.`,
4465
+ `LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
4146
4466
  "",
4147
- `Command not found: ${server2.command[0]}`,
4467
+ `Command not found: ${server.command[0]}`,
4148
4468
  ""
4149
4469
  ];
4470
+ const installOptions = formatInstallOptions(server.id, installHint);
4150
4471
  if (decision === "allowed") {
4151
4472
  return [
4152
4473
  ...header,
4153
4474
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4154
- ` ${installHint}`
4475
+ ...installOptions.slice(1)
4155
4476
  ].join(`
4156
4477
  `);
4157
4478
  }
4158
4479
  if (!context.capabilities.installDecisionTool) {
4159
4480
  return [
4160
4481
  ...header,
4161
- "To install, run:",
4162
- ` ${installHint}`,
4482
+ ...installOptions,
4163
4483
  "",
4164
4484
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4165
4485
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4168,13 +4488,12 @@ function formatNotInstalled(result) {
4168
4488
  }
4169
4489
  return [
4170
4490
  ...header,
4171
- "To install, run:",
4172
- ` ${installHint}`,
4491
+ ...installOptions,
4173
4492
  "",
4174
4493
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4175
4494
  "- If the user agrees: run the install command above, then retry this tool.",
4176
4495
  "- If the user declines, OR has NOT explicitly asked for LSP installation:",
4177
- ` call lsp_install_decision { server_id: "${server2.id}", decision: "declined" },`,
4496
+ ` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
4178
4497
  ` which writes to ${context.installDecisionsPath},`,
4179
4498
  " then ignore this message and proceed WITHOUT LSP."
4180
4499
  ].join(`
@@ -4198,34 +4517,34 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4198
4517
  if (result.status !== "found") {
4199
4518
  throw new LspServerLookupError(formatServerLookupError(result), result);
4200
4519
  }
4201
- const server2 = result.server;
4520
+ const server = result.server;
4202
4521
  const root = findWorkspaceRoot(absPath);
4203
4522
  const manager = options.manager ?? getLspManager();
4204
4523
  const acquireAndCall = async (allowRetry) => {
4205
- const client = await manager.getClient(root, server2, options.signal);
4524
+ const client = await manager.getClient(root, server, options.signal);
4206
4525
  try {
4207
4526
  return await fn(client, root, absPath);
4208
4527
  } catch (err) {
4209
4528
  if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4210
- manager.invalidateClient(root, server2.id, client);
4529
+ manager.invalidateClient(root, server.id, client);
4211
4530
  return acquireAndCall(false);
4212
4531
  }
4213
4532
  if (err instanceof LspRequestTimeoutError) {
4214
- if (manager.isServerInitializing(root, server2.id)) {
4533
+ if (manager.isServerInitializing(root, server.id)) {
4215
4534
  throw new LspServerInitializingError(err);
4216
4535
  }
4217
4536
  }
4218
4537
  throw err;
4219
4538
  } finally {
4220
- manager.releaseClient(root, server2.id);
4539
+ manager.releaseClient(root, server.id);
4221
4540
  }
4222
4541
  };
4223
4542
  return acquireAndCall(true);
4224
4543
  }
4225
4544
 
4226
4545
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4227
- import { existsSync as existsSync10, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4228
- import { join as join5, resolve as resolve8 } from "node:path";
4546
+ import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4547
+ import { join as join6, resolve as resolve9 } from "node:path";
4229
4548
 
4230
4549
  // ../lsp-core/src/lsp/formatters.ts
4231
4550
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -4240,10 +4559,10 @@ function uriToPath(uri) {
4240
4559
  }
4241
4560
  function formatLocation(loc) {
4242
4561
  if ("targetUri" in loc) {
4243
- const uri2 = uriToPath(loc.targetUri);
4244
- const line2 = loc.targetRange.start.line + 1;
4245
- const char2 = loc.targetRange.start.character;
4246
- return `${uri2}:${line2}:${char2}`;
4562
+ const uri = uriToPath(loc.targetUri);
4563
+ const line = loc.targetRange.start.line + 1;
4564
+ const char = loc.targetRange.start.character;
4565
+ return `${uri}:${line}:${char}`;
4247
4566
  }
4248
4567
  const uri = uriToPath(loc.uri);
4249
4568
  const line = loc.range.start.line + 1;
@@ -4355,7 +4674,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
4355
4674
  for (const entry of entries) {
4356
4675
  if (files.length >= maxFiles)
4357
4676
  return;
4358
- const fullPath = join5(currentDir, entry);
4677
+ const fullPath = join6(currentDir, entry);
4359
4678
  let stat;
4360
4679
  try {
4361
4680
  stat = lstatSync4(fullPath);
@@ -4380,15 +4699,15 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4380
4699
  if (!extension.startsWith(".")) {
4381
4700
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4382
4701
  }
4383
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4384
- if (!existsSync10(absDir)) {
4702
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
4703
+ if (!existsSync11(absDir)) {
4385
4704
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4386
4705
  }
4387
4706
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
4388
4707
  if (serverResult.status !== "found") {
4389
4708
  throw new LspServerLookupError(formatServerLookupError(serverResult));
4390
4709
  }
4391
- const server2 = serverResult.server;
4710
+ const server = serverResult.server;
4392
4711
  const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
4393
4712
  const wasCapped = allFiles.length > maxFiles;
4394
4713
  const filesToProcess = allFiles.slice(0, maxFiles);
@@ -4408,7 +4727,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4408
4727
  const fileErrors = [];
4409
4728
  const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
4410
4729
  options.signal?.throwIfAborted();
4411
- const client = await manager.getClient(root, server2, options.signal);
4730
+ const client = await manager.getClient(root, server, options.signal);
4412
4731
  try {
4413
4732
  let nextIndex = 0;
4414
4733
  const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
@@ -4436,7 +4755,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4436
4755
  });
4437
4756
  await Promise.all(workers);
4438
4757
  } finally {
4439
- manager.releaseClient(root, server2.id);
4758
+ manager.releaseClient(root, server.id);
4440
4759
  }
4441
4760
  const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
4442
4761
  const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
@@ -4468,7 +4787,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4468
4787
 
4469
4788
  // ../lsp-core/src/lsp/infer-extension.ts
4470
4789
  import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
4471
- import { join as join6 } from "node:path";
4790
+ import { join as join7 } from "node:path";
4472
4791
  var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
4473
4792
  var MAX_SCAN_ENTRIES = 500;
4474
4793
  function inferExtensionFromDirectory(directory) {
@@ -4486,7 +4805,7 @@ function inferExtensionFromDirectory(directory) {
4486
4805
  for (const entry of entries) {
4487
4806
  if (scanned >= MAX_SCAN_ENTRIES)
4488
4807
  return;
4489
- const fullPath = join6(dir, entry);
4808
+ const fullPath = join7(dir, entry);
4490
4809
  let stat;
4491
4810
  try {
4492
4811
  stat = lstatSync5(fullPath);
@@ -4645,8 +4964,8 @@ function clientOptions(signal) {
4645
4964
  }
4646
4965
 
4647
4966
  // ../lsp-core/src/tools/result.ts
4648
- function text(text2, details, isError = false) {
4649
- return { content: [{ type: "text", text: text2 }], details, isError };
4967
+ function text(text, details, isError = false) {
4968
+ return { content: [{ type: "text", text }], details, isError };
4650
4969
  }
4651
4970
 
4652
4971
  // ../lsp-core/src/tools/diagnostics.ts
@@ -4666,7 +4985,7 @@ async function executeLspDiagnostics(params, signal) {
4666
4985
  const extension = inferExtensionFromDirectory(absPath);
4667
4986
  if (!extension) {
4668
4987
  const message = `No supported source files found in directory: ${absPath}`;
4669
- const details3 = {
4988
+ const details = {
4670
4989
  filePath,
4671
4990
  severity,
4672
4991
  mode: "directory",
@@ -4676,24 +4995,24 @@ async function executeLspDiagnostics(params, signal) {
4676
4995
  error: message,
4677
4996
  errorKind: "no_files"
4678
4997
  };
4679
- return text(message, details3);
4998
+ return text(message, details);
4680
4999
  }
4681
- const output2 = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
4682
- const details2 = {
5000
+ const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
5001
+ const details = {
4683
5002
  filePath,
4684
5003
  severity,
4685
5004
  mode: "directory",
4686
5005
  diagnostics: [],
4687
- totalDiagnostics: output2.totalDiagnostics,
5006
+ totalDiagnostics: output.totalDiagnostics,
4688
5007
  truncated: false,
4689
- fileFailures: [...output2.fileFailures]
5008
+ fileFailures: [...output.fileFailures]
4690
5009
  };
4691
- return text(output2.output, details2);
5010
+ return text(output.output, details);
4692
5011
  }
4693
5012
  const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
4694
5013
  if (result.transientError) {
4695
5014
  const message = result.transientError.message;
4696
- const details2 = {
5015
+ const details = {
4697
5016
  filePath,
4698
5017
  severity,
4699
5018
  mode: "file",
@@ -4703,7 +5022,7 @@ async function executeLspDiagnostics(params, signal) {
4703
5022
  error: message,
4704
5023
  errorKind: result.transientError.kind
4705
5024
  };
4706
- return text(message, details2, true);
5025
+ return text(message, details, true);
4707
5026
  }
4708
5027
  const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
4709
5028
  const total = diagnostics.length;
@@ -4737,6 +5056,96 @@ async function executeLspDiagnostics(params, signal) {
4737
5056
  throw error;
4738
5057
  }
4739
5058
  }
5059
+ // ../lsp-core/src/lsp/format-document.ts
5060
+ import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
5061
+ var DEFAULT_FORMATTING_OPTIONS = {
5062
+ tabSize: 4,
5063
+ insertSpaces: false,
5064
+ trimTrailingWhitespace: true,
5065
+ insertFinalNewline: true,
5066
+ trimFinalNewlines: true
5067
+ };
5068
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
5069
+ async function formatDocumentWithClient(client, filePath, options = {}) {
5070
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
5071
+ if (edits === null)
5072
+ return { status: "unavailable", reason: "capability_not_advertised" };
5073
+ if (edits.length === 0)
5074
+ return UNCHANGED;
5075
+ const before = readFileSync5(filePath, "utf-8");
5076
+ const normalized = normalizeTextEdits(before, edits, 0);
5077
+ if (normalized.text === before)
5078
+ return UNCHANGED;
5079
+ writeAtomically(filePath, normalized.text);
5080
+ await client.openFile(filePath);
5081
+ return {
5082
+ status: "formatted",
5083
+ ...lineDelta(normalized.edits)
5084
+ };
5085
+ }
5086
+ function lineDelta(edits) {
5087
+ let linesAdded = 0;
5088
+ let linesRemoved = 0;
5089
+ for (const edit of edits) {
5090
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
5091
+ linesAdded += edit.newText.split(`
5092
+ `).length;
5093
+ }
5094
+ return { linesAdded, linesRemoved };
5095
+ }
5096
+ function writeAtomically(filePath, content) {
5097
+ const tempPath = `${filePath}.omo-format.tmp`;
5098
+ writeFileSync3(tempPath, content, "utf-8");
5099
+ try {
5100
+ renameSync3(tempPath, filePath);
5101
+ } catch (error) {
5102
+ try {
5103
+ unlinkSync(tempPath);
5104
+ } catch {}
5105
+ throw error;
5106
+ }
5107
+ }
5108
+
5109
+ // ../lsp-core/src/tools/format.ts
5110
+ async function executeLspFormat(params, signal) {
5111
+ const filePath = requireString(params, "filePath");
5112
+ try {
5113
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
5114
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
5115
+ } catch (error) {
5116
+ const missingDependency = missingDependencyResult(error, {
5117
+ filePath,
5118
+ status: "unavailable",
5119
+ reason: "server_unavailable",
5120
+ linesAdded: 0,
5121
+ linesRemoved: 0
5122
+ });
5123
+ if (missingDependency)
5124
+ return missingDependency;
5125
+ throw error;
5126
+ }
5127
+ }
5128
+ function formatDetails(filePath, result) {
5129
+ if (result.status === "unavailable") {
5130
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5131
+ }
5132
+ return {
5133
+ filePath,
5134
+ status: result.status,
5135
+ linesAdded: result.linesAdded,
5136
+ linesRemoved: result.linesRemoved
5137
+ };
5138
+ }
5139
+ function describeResult(filePath, result) {
5140
+ if (result.status === "unavailable") {
5141
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5142
+ }
5143
+ if (result.status === "unchanged") {
5144
+ return `Already formatted: ${filePath}`;
5145
+ }
5146
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5147
+ }
5148
+
4740
5149
  // ../lsp-core/src/tools/install-decision.ts
4741
5150
  async function executeLspInstallDecision(params) {
4742
5151
  const serverId = requireString(params, "server_id");
@@ -4744,7 +5153,7 @@ async function executeLspInstallDecision(params) {
4744
5153
  if (!isInstallDecision(decision)) {
4745
5154
  return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
4746
5155
  }
4747
- const serverIds = [...new Set(getMergedServers().map((server2) => server2.id))];
5156
+ const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
4748
5157
  if (!serverIds.includes(serverId)) {
4749
5158
  const preview = serverIds.slice(0, 20).join(", ");
4750
5159
  return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
@@ -4884,10 +5293,10 @@ function objectSchema(properties, required = []) {
4884
5293
  async function executeLspStatus() {
4885
5294
  const servers = getAllServers();
4886
5295
  const snapshots = getLspManager().getSnapshot();
4887
- const installed = servers.filter((server2) => server2.installed && !server2.disabled);
4888
- const configuredLines = servers.map((server2) => {
4889
- const state = server2.disabled ? "disabled" : server2.installed ? "installed" : "missing";
4890
- return `- ${server2.id}: ${state}; source=${server2.source}; extensions=${server2.extensions.join(", ")}`;
5296
+ const installed = servers.filter((server) => server.installed && !server.disabled);
5297
+ const configuredLines = servers.map((server) => {
5298
+ const state = server.disabled ? "disabled" : server.installed ? "installed" : "missing";
5299
+ return `- ${server.id}: ${state}; source=${server.source}; extensions=${server.extensions.join(", ")}`;
4891
5300
  });
4892
5301
  const activeLines = snapshots.map((snapshot) => {
4893
5302
  const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
@@ -4930,8 +5339,8 @@ async function executeLspSymbols(params, signal) {
4930
5339
  errorKind: "missing_query"
4931
5340
  });
4932
5341
  }
4933
- const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
4934
- return formatSymbolsResult(filePath, scope, symbols2, limit, query);
5342
+ const symbols = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
5343
+ return formatSymbolsResult(filePath, scope, symbols, limit, query);
4935
5344
  }
4936
5345
  const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
4937
5346
  return formatSymbolsResult(filePath, scope, symbols, limit);
@@ -5069,6 +5478,16 @@ var LSP_MCP_TOOLS = [
5069
5478
  }, ["filePath", "line", "character", "newName"]),
5070
5479
  execute: executeLspRename
5071
5480
  },
5481
+ {
5482
+ name: "format",
5483
+ aliases: ["lsp_format"],
5484
+ title: "LSP Format",
5485
+ description: "Format a source file with its language server and write the returned edits to disk.",
5486
+ inputSchema: objectSchema({
5487
+ filePath: { type: "string", description: "Source file path to format." }
5488
+ }, ["filePath"]),
5489
+ execute: executeLspFormat
5490
+ },
5072
5491
  {
5073
5492
  name: "install_decision",
5074
5493
  aliases: ["lsp_install_decision"],
@@ -5176,6 +5595,6 @@ function requestedProtocolVersion(params) {
5176
5595
  return params["protocolVersion"];
5177
5596
  }
5178
5597
  export {
5179
- runMcpStdioServer,
5180
- handleLspMcpRequest
5598
+ handleLspMcpRequest,
5599
+ runMcpStdioServer
5181
5600
  };