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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (952) hide show
  1. package/.agents/command/publish.md +44 -16
  2. package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +1 -3
  3. package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +1 -1
  4. package/.agents/skills/pre-publish-review/SKILL.md +9 -12
  5. package/.agents/skills/publish/SKILL.md +44 -16
  6. package/.agents/skills/senpi-qa/SKILL.md +80 -0
  7. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
  8. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
  9. package/.agents/skills/tech-debt-audit/SKILL.md +6 -76
  10. package/.agents/skills/work-with-pr/SKILL.md +37 -23
  11. package/.opencode/command/publish.md +44 -16
  12. package/.opencode/skills/pre-publish-review/SKILL.md +9 -12
  13. package/.opencode/skills/work-with-pr/SKILL.md +37 -23
  14. package/README.ja.md +58 -46
  15. package/README.ko.md +60 -48
  16. package/README.md +58 -58
  17. package/README.ru.md +55 -46
  18. package/README.zh-cn.md +54 -46
  19. package/THIRD-PARTY-NOTICES.md +27 -99
  20. package/dist/agents/atlas/agent.d.ts +0 -1
  21. package/dist/agents/gpt-prompt-identity.d.ts +1 -1
  22. package/dist/agents/sisyphus/grok-4.d.ts +20 -0
  23. package/dist/agents/sisyphus/index.d.ts +2 -0
  24. package/dist/agents/sisyphus-agent-config.d.ts +6 -0
  25. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  26. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
  27. package/dist/agents/types.d.ts +4 -2
  28. package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
  29. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  30. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  31. package/dist/cli/index.js +51551 -59608
  32. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  33. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  34. package/dist/cli/runtime-commands.d.ts +1 -1
  35. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  36. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  37. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  38. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  39. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  40. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  41. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  42. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  43. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  44. package/dist/cli-node/index.js +51569 -59603
  45. package/dist/config/index.d.ts +1 -1
  46. package/dist/config/schema/background-task.d.ts +1 -0
  47. package/dist/config/schema/commands.d.ts +1 -1
  48. package/dist/config/schema/hooks.d.ts +1 -2
  49. package/dist/config/schema/oh-my-opencode-config.d.ts +5 -11
  50. package/dist/config/schema/ulw-execute.d.ts +5 -0
  51. package/dist/config/schema.d.ts +0 -1
  52. package/dist/config/validate.d.ts +2 -0
  53. package/dist/create-hooks.d.ts +3 -2
  54. package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +1 -0
  55. package/dist/features/background-agent/constants.d.ts +0 -7
  56. package/dist/features/background-agent/error-classifier.d.ts +1 -0
  57. package/dist/features/background-agent/manager.d.ts +2 -1
  58. package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
  59. package/dist/features/background-agent/parent-wake-notifier-types.d.ts +1 -1
  60. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -1
  61. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -1
  62. package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
  63. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  64. package/dist/features/btw-side/context-injector.d.ts +15 -0
  65. package/dist/features/btw-side/index.d.ts +8 -0
  66. package/dist/features/btw-side/metadata.d.ts +15 -0
  67. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  68. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  69. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  70. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  71. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  72. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  73. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  74. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  75. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  76. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  77. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  78. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  79. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  80. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  81. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  82. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  83. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  84. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  85. package/dist/features/builtin-commands/types.d.ts +1 -1
  86. package/dist/features/monitor/manager-internals.d.ts +1 -1
  87. package/dist/features/monitor/output-injector-types.d.ts +1 -1
  88. package/dist/features/opengateway-provider/index.d.ts +13 -0
  89. package/dist/features/task-toast-manager/manager.d.ts +0 -24
  90. package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +17 -0
  91. package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +3 -0
  92. package/dist/features/team-mode/tools/messaging-runtime.d.ts +7 -0
  93. package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
  94. package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
  95. package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
  96. package/dist/hooks/anthropic-context-window-limit-recovery/tool-result-storage.d.ts +11 -0
  97. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  98. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  99. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  100. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  101. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  102. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  103. package/dist/hooks/atlas/types.d.ts +1 -0
  104. package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
  105. package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
  106. package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
  107. package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
  108. package/dist/hooks/compaction-context-injector/validated-model.d.ts +2 -0
  109. package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
  110. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
  111. package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
  112. package/dist/hooks/index.d.ts +1 -2
  113. package/dist/hooks/keyword-detector/hook.d.ts +7 -0
  114. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
  115. package/dist/hooks/model-fallback/hook.d.ts +1 -1
  116. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  117. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  118. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  119. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  120. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  121. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  122. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  123. package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
  124. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  125. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  126. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  127. package/dist/index.js +28955 -25346
  128. package/dist/mcp/index.d.ts +0 -4
  129. package/dist/mcp/types.d.ts +0 -1
  130. package/dist/oh-my-opencode.schema.json +21 -47
  131. package/dist/plugin/chat-message/types.d.ts +3 -3
  132. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  133. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  134. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -2
  135. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -3
  136. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  137. package/dist/plugin/messages-transform.d.ts +1 -0
  138. package/dist/plugin-dispose.d.ts +3 -0
  139. package/dist/shared/agent-tool-restrictions.d.ts +0 -1
  140. package/dist/shared/compaction-agent-config-checkpoint.d.ts +1 -0
  141. package/dist/shared/index.d.ts +2 -0
  142. package/dist/shared/legacy-plugin-warning.d.ts +2 -1
  143. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  144. package/dist/shared/omo-process-sweep.d.ts +2 -4
  145. package/dist/shared/plugin-entry-migrator.d.ts +4 -3
  146. package/dist/shared/plugin-entry-shape.d.ts +6 -0
  147. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  148. package/dist/shared/shell-env.d.ts +1 -1
  149. package/dist/skills/ast-grep/AGENTS.md +51 -0
  150. package/dist/skills/ast-grep/SKILL.md +1 -1
  151. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  152. package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
  153. package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  154. package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
  155. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  156. package/dist/skills/data-scientist/SKILL.md +99 -239
  157. package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
  158. package/dist/skills/data-scientist/references/placement.md +74 -0
  159. package/dist/skills/data-scientist/references/polars-lane.md +95 -0
  160. package/dist/skills/data-scientist/references/uv-setup.md +1 -1
  161. package/dist/skills/data-scientist/references/visualization.md +64 -0
  162. package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  163. package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  164. package/dist/skills/debugging/SKILL.md +3 -1
  165. package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
  166. package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
  167. package/dist/skills/debugging/references/runtimes/go.md +15 -1
  168. package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
  169. package/dist/skills/debugging/references/runtimes/node.md +25 -0
  170. package/dist/skills/debugging/references/runtimes/python.md +13 -0
  171. package/dist/skills/debugging/references/runtimes/rust.md +41 -0
  172. package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
  173. package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
  174. package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  175. package/dist/skills/debugging/references/tools/dap.md +103 -0
  176. package/dist/skills/debugging/references/tools/frida.md +193 -0
  177. package/dist/skills/frontend/SKILL.md +12 -8
  178. package/dist/skills/frontend/references/design/_INDEX.md +1 -0
  179. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  180. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  181. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  182. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  183. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  184. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  185. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  186. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  187. package/dist/skills/git-master/SKILL.md +1 -1
  188. package/dist/skills/init-deep/SKILL.md +14 -14
  189. package/dist/skills/lsp-setup/SKILL.md +1 -1
  190. package/dist/skills/programming/SKILL.md +1 -1
  191. package/dist/skills/refactor/SKILL.md +1 -1
  192. package/dist/skills/remove-ai-slops/SKILL.md +1 -1
  193. package/dist/skills/review-work/SKILL.md +100 -418
  194. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  195. package/dist/skills/ultimate-browsing/SKILL.md +26 -9
  196. package/dist/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  197. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  198. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  199. package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  200. package/dist/skills/{start-work → ulw-execute}/SKILL.md +17 -16
  201. package/dist/skills/ulw-plan/SKILL.md +7 -8
  202. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  203. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  204. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  205. package/dist/skills/ulw-research/SKILL.md +8 -3
  206. package/dist/skills/visual-qa/AGENTS.md +58 -0
  207. package/dist/skills/visual-qa/SKILL.md +4 -3
  208. package/dist/tools/delegate-task/builtin-categories.d.ts +3 -1
  209. package/dist/tools/delegate-task/builtin-category-definition.d.ts +2 -1
  210. package/dist/tools/delegate-task/constants.d.ts +2 -2
  211. package/dist/tools/delegate-task/openai-categories.d.ts +7 -2
  212. package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
  213. package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
  214. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  215. package/dist/tools/delegate-task/types.d.ts +4 -0
  216. package/dist/tools/session-manager/directory-filter.d.ts +2 -0
  217. package/dist/tui.d.ts +12 -0
  218. package/dist/tui.js +37066 -46704
  219. package/package.json +47 -41
  220. package/packages/git-bash-mcp/dist/cli.js +6 -1
  221. package/packages/git-bash-mcp/package.json +1 -1
  222. package/packages/lsp-core/src/index.ts +1 -0
  223. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  224. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +57 -48
  225. package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
  226. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  227. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +163 -13
  228. package/packages/lsp-core/src/lsp/client-wrapper.ts +110 -23
  229. package/packages/lsp-core/src/lsp/client.ts +32 -3
  230. package/packages/lsp-core/src/lsp/connection.ts +16 -0
  231. package/packages/lsp-core/src/lsp/constants.ts +6 -0
  232. package/packages/lsp-core/src/lsp/controlled-clock-test-support.ts +61 -0
  233. package/packages/lsp-core/src/lsp/errors.ts +15 -0
  234. package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +10 -3
  235. package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
  236. package/packages/lsp-core/src/lsp/format-document.ts +90 -0
  237. package/packages/lsp-core/src/lsp/json-rpc-connection.ts +11 -6
  238. package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
  239. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
  240. package/packages/lsp-core/src/lsp/manager.ts +138 -12
  241. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  242. package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
  243. package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
  244. package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
  245. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
  246. package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
  247. package/packages/lsp-core/src/lsp/timer-provider.ts +13 -0
  248. package/packages/lsp-core/src/lsp/transport-request-timeout.test.ts +73 -0
  249. package/packages/lsp-core/src/lsp/transport.ts +16 -2
  250. package/packages/lsp-core/src/lsp/types.ts +8 -0
  251. package/packages/lsp-core/src/lsp/workspace-apply-edit-test-support.ts +29 -1
  252. package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +84 -1
  253. package/packages/lsp-core/src/lsp/workspace-document-state.ts +30 -11
  254. package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
  255. package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
  256. package/packages/lsp-core/src/mcp.ts +3 -0
  257. package/packages/lsp-core/src/request-context.test.ts +29 -0
  258. package/packages/lsp-core/src/request-context.ts +1 -1
  259. package/packages/lsp-core/src/tool-surface.test.ts +13 -1
  260. package/packages/lsp-core/src/tools/definitions.ts +14 -0
  261. package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
  262. package/packages/lsp-core/src/tools/format.test.ts +56 -0
  263. package/packages/lsp-core/src/tools/format.ts +56 -0
  264. package/packages/lsp-core/src/tools/index.ts +1 -0
  265. package/packages/lsp-core/src/tools/navigation.ts +4 -2
  266. package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
  267. package/packages/lsp-core/src/tools/rename.ts +4 -2
  268. package/packages/lsp-core/src/tools/symbols.ts +1 -1
  269. package/packages/lsp-core/src/tools/types.ts +10 -0
  270. package/packages/lsp-daemon/dist/cli.js +961 -483
  271. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  272. package/packages/lsp-daemon/dist/client.js +976 -495
  273. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  274. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  275. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +6 -1
  276. package/packages/lsp-daemon/dist/ensure-daemon.js +10 -2
  277. package/packages/lsp-daemon/dist/index.js +881 -405
  278. package/packages/lsp-daemon/dist/proxy.js +3 -0
  279. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  280. package/packages/lsp-daemon/package.json +1 -1
  281. package/packages/lsp-tools-mcp/dist/cli.js +820 -345
  282. package/packages/lsp-tools-mcp/dist/lsp/manager.js +272 -138
  283. package/packages/lsp-tools-mcp/dist/mcp.js +845 -372
  284. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  285. package/packages/lsp-tools-mcp/dist/tools.js +775 -306
  286. package/packages/lsp-tools-mcp/package.json +1 -1
  287. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -21
  288. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -6
  289. package/packages/omo-codex/plugin/.mcp.json +0 -6
  290. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  291. package/packages/omo-codex/plugin/README.md +6 -2
  292. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +197 -148
  293. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  294. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  295. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  296. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  297. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  298. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  299. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  300. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  301. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  302. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  303. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  304. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  305. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  306. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  307. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  308. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +2 -2
  309. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  310. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/directive.md +2 -0
  311. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +36 -29
  312. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +32 -26
  313. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/types.d.ts +3 -0
  314. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  315. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  316. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +32 -28
  317. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/types.ts +3 -0
  318. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +1 -1
  319. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +137 -28
  320. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +4 -2
  321. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  322. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  323. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  324. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +999 -544
  325. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  326. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  327. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  328. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  329. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  330. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  331. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  332. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  333. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  334. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  335. package/packages/omo-codex/plugin/components/rules/README.md +2 -0
  336. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  337. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +123 -0
  338. package/packages/omo-codex/plugin/components/rules/dist/cli.js +91 -68
  339. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  340. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  341. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  342. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  343. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +15 -5
  344. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  345. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  346. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  347. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  348. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  349. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  350. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  351. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  352. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  353. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  354. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  355. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  356. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  357. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +38 -3
  358. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  359. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  360. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  361. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  362. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +29 -6
  363. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  364. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  365. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  366. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  367. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  368. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  369. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +4 -10
  370. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  371. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  372. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2435 -700
  373. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2439 -705
  374. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  375. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  376. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  377. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  378. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  379. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  380. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -4
  381. package/packages/omo-codex/plugin/components/ultrawork/README.md +2 -0
  382. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
  383. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +1 -1
  384. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
  385. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  386. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
  387. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  388. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-low.toml +1 -1
  389. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +1 -1
  390. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +1 -1
  391. package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +1 -1
  392. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +1 -1
  393. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  394. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  395. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +490 -4
  396. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  397. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -6
  398. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
  399. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -7
  400. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  401. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  402. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  403. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
  404. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
  405. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  406. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  407. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
  408. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
  409. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  410. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +4 -4
  411. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  412. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +6 -6
  413. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  414. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +10 -10
  415. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +16 -16
  416. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +16 -0
  417. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  418. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  419. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  420. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +4 -4
  421. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  422. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  423. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +1 -1
  424. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  425. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +4 -11
  426. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +24 -22
  427. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +19 -0
  428. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  429. package/packages/omo-codex/plugin/components/ulw-loop/README.md +12 -1
  430. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  431. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +26 -13
  432. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +12 -0
  433. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +45 -0
  434. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +9 -0
  435. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +15 -0
  436. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +15 -1
  437. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +8 -0
  438. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +113 -0
  439. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +40 -39
  440. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +21 -8
  441. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  442. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +12 -1
  443. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +2 -0
  444. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +1270 -429
  445. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  446. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +28 -8
  447. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +13 -0
  448. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +15 -1
  449. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -0
  450. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +1 -0
  451. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
  452. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +1 -0
  453. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +13 -4
  454. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +1 -0
  455. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +34 -4
  456. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +14 -0
  457. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +29 -0
  458. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +7 -0
  459. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +9 -0
  460. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +12 -0
  461. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +104 -0
  462. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  463. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +65 -9
  464. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  465. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  466. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +72 -117
  467. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +4 -2
  468. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +6 -1
  469. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +195 -29
  470. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.d.ts +9 -0
  471. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.js +227 -0
  472. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +6 -0
  473. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +33 -0
  474. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +20 -6
  475. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +19 -0
  476. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +75 -0
  477. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +17 -4
  478. package/packages/omo-codex/plugin/components/ulw-loop/package.json +6 -6
  479. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +6 -4
  480. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  481. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +32 -8
  482. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +81 -0
  483. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +7 -0
  484. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +31 -1
  485. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +128 -0
  486. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +38 -71
  487. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +24 -8
  488. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +14 -1
  489. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +2 -0
  490. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +8 -6
  491. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +35 -7
  492. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +26 -1
  493. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  494. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +1 -0
  495. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
  496. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +25 -4
  497. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +39 -4
  498. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +38 -0
  499. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +11 -0
  500. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +123 -0
  501. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +71 -15
  502. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  503. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +92 -136
  504. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +4 -2
  505. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +205 -28
  506. package/packages/omo-codex/plugin/components/ulw-loop/src/state-lock.ts +239 -0
  507. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
  508. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +19 -6
  509. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +107 -0
  510. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  511. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +132 -1
  512. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +147 -0
  513. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +4 -2
  514. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint.test.ts +4 -2
  515. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +2 -0
  516. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-complete-goals.test.ts +3 -1
  517. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +35 -8
  518. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +38 -4
  519. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-json-errors.test.ts +2 -0
  520. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-scope-required.test.ts +144 -0
  521. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +185 -0
  522. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +8 -3
  523. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +6 -0
  524. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +37 -2
  525. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  526. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  527. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/cli-session.ts +4 -0
  528. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +9 -4
  529. package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +105 -0
  530. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  531. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  532. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io-cross-process.test.ts +106 -0
  533. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +36 -2
  534. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  535. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  536. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-fields-messages.test.ts +98 -0
  537. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-lazycodex-surface.test.ts +93 -0
  538. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  539. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +51 -2
  540. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
  541. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  542. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +58 -3
  543. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +444 -7
  544. package/packages/omo-codex/plugin/components/ulw-loop/test/state-lock.test.ts +218 -0
  545. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  546. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  547. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  548. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +13 -8
  549. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  550. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  551. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  552. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  553. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  554. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  555. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  556. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  557. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +18 -0
  558. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  559. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  560. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  561. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  562. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  563. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  564. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  565. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  566. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  567. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  568. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  569. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  570. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  571. package/packages/omo-codex/plugin/model-catalog.json +16 -7
  572. package/packages/omo-codex/plugin/package-lock.json +676 -524
  573. package/packages/omo-codex/plugin/package.json +2 -3
  574. package/packages/omo-codex/plugin/scripts/AGENTS.md +39 -0
  575. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -2
  576. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  577. package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
  578. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  579. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +16 -7
  580. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +8 -4
  581. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +19 -90
  582. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +1 -1
  583. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +94 -55
  584. package/packages/omo-codex/plugin/shared/package.json +3 -4
  585. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  586. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  587. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  588. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  589. package/packages/omo-codex/plugin/skills/ast-grep/SKILL.md +1 -1
  590. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  591. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
  592. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  593. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
  594. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  595. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  596. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  597. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  598. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  599. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  600. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  601. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  602. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  603. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +3 -1
  604. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  605. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  606. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  607. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  608. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  609. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  610. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  611. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  612. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  613. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  614. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  615. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +12 -8
  616. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  617. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  618. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  619. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  620. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  621. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  622. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  623. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  624. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  625. package/packages/omo-codex/plugin/skills/git-master/SKILL.md +1 -1
  626. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +18 -16
  627. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +4 -2
  628. package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +1 -1
  629. package/packages/omo-codex/plugin/skills/programming/SKILL.md +1 -1
  630. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +5 -3
  631. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +5 -3
  632. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +114 -422
  633. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  634. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +26 -9
  635. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  636. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  637. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  638. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  639. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +26 -13
  640. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +26 -28
  641. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  642. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +30 -4
  643. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  644. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +32 -8
  645. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -7
  646. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  647. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  648. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  649. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +12 -5
  650. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  651. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +8 -5
  652. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  653. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  654. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +16 -51
  655. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -3
  656. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  657. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +14 -4
  658. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  659. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  660. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  661. package/packages/omo-codex/plugin/test/auto-update.test.mjs +4 -29
  662. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  663. package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
  664. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  665. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -51
  666. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +88 -2
  667. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +5 -6
  668. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  669. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  670. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +35 -35
  671. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +1 -1
  672. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  673. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +107 -15
  674. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +168 -0
  675. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +54 -24
  676. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +18 -119
  677. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  678. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  679. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  680. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  681. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  682. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -5
  683. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  684. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  685. package/packages/omo-codex/scripts/check-model-catalog-parity.mjs +42 -0
  686. package/packages/omo-codex/scripts/install-cache-copy.test.mjs +27 -1
  687. package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +1 -1
  688. package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +2 -1
  689. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
  690. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +5 -5
  691. package/packages/omo-codex/scripts/install-config.test.mjs +15 -17
  692. package/packages/omo-codex/scripts/install-dist/install-local.mjs +3035 -1395
  693. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +3 -4
  694. package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
  695. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  696. package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
  697. package/packages/omo-codex/scripts/install-packaged-local.test.mjs +1 -6
  698. package/packages/{omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md → prompts-core/prompts/ultrawork/codex.md} +26 -20
  699. package/packages/shared-skills/package.json +7 -1
  700. package/packages/shared-skills/skill-source-filter.d.ts +16 -0
  701. package/packages/shared-skills/skill-source-filter.mjs +44 -0
  702. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  703. package/packages/shared-skills/skills/ast-grep/SKILL.md +1 -1
  704. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  705. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
  706. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  707. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
  708. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  709. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  710. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  711. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  712. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  713. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  714. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  715. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  716. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  717. package/packages/shared-skills/skills/debugging/SKILL.md +3 -1
  718. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  719. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  720. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  721. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  722. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  723. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  724. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  725. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  726. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  727. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  728. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  729. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  730. package/packages/shared-skills/skills/frontend/SKILL.md +12 -8
  731. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  732. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  733. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  734. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  735. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  736. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  737. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  738. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  739. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  740. package/packages/shared-skills/skills/git-master/SKILL.md +1 -1
  741. package/packages/shared-skills/skills/init-deep/SKILL.md +14 -14
  742. package/packages/shared-skills/skills/lsp-setup/SKILL.md +1 -1
  743. package/packages/shared-skills/skills/programming/SKILL.md +1 -1
  744. package/packages/shared-skills/skills/refactor/SKILL.md +1 -1
  745. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
  746. package/packages/shared-skills/skills/review-work/SKILL.md +100 -418
  747. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  748. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +26 -9
  749. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  750. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  751. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  752. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  753. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +17 -16
  754. package/packages/shared-skills/skills/ulw-plan/SKILL.md +7 -8
  755. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  756. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  757. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  758. package/packages/shared-skills/skills/ulw-research/SKILL.md +8 -3
  759. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  760. package/packages/shared-skills/skills/visual-qa/SKILL.md +4 -3
  761. package/postinstall.mjs +2 -0
  762. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  763. package/script/qa/xterm-live-terminal.mjs +18 -2
  764. package/dist/config/schema/codegraph.d.ts +0 -12
  765. package/dist/config/schema/start-work.d.ts +0 -5
  766. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  767. package/dist/features/builtin-skills/index.d.ts +0 -1
  768. package/dist/features/builtin-skills/skill-file-loader.d.ts +0 -1
  769. package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +0 -1
  770. package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +0 -1
  771. package/dist/features/builtin-skills/skills/debugging.d.ts +0 -1
  772. package/dist/features/builtin-skills/skills/dev-browser.d.ts +0 -1
  773. package/dist/features/builtin-skills/skills/frontend.d.ts +0 -1
  774. package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +0 -1
  775. package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +0 -1
  776. package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +0 -1
  777. package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +0 -1
  778. package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +0 -1
  779. package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +0 -1
  780. package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +0 -1
  781. package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +0 -1
  782. package/dist/features/builtin-skills/skills/git-master-skill-metadata.d.ts +0 -1
  783. package/dist/features/builtin-skills/skills/git-master.d.ts +0 -1
  784. package/dist/features/builtin-skills/skills/index.d.ts +0 -1
  785. package/dist/features/builtin-skills/skills/init-deep.d.ts +0 -1
  786. package/dist/features/builtin-skills/skills/playwright-cli.d.ts +0 -1
  787. package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +0 -1
  788. package/dist/features/builtin-skills/skills/playwright.d.ts +0 -1
  789. package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +0 -1
  790. package/dist/features/builtin-skills/skills/review-work.d.ts +0 -1
  791. package/dist/features/builtin-skills/skills/security-research.d.ts +0 -1
  792. package/dist/features/builtin-skills/skills/security-review.d.ts +0 -1
  793. package/dist/features/builtin-skills/skills/team-mode.d.ts +0 -1
  794. package/dist/features/builtin-skills/skills/visual-qa.d.ts +0 -1
  795. package/dist/features/builtin-skills/skills.d.ts +0 -1
  796. package/dist/features/builtin-skills/types.d.ts +0 -1
  797. package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +0 -1
  798. package/dist/features/claude-code-plugin-loader/command-loader.d.ts +0 -1
  799. package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +0 -1
  800. package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +0 -1
  801. package/dist/features/claude-code-plugin-loader/discovery.d.ts +0 -1
  802. package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +0 -1
  803. package/dist/features/claude-code-plugin-loader/index.d.ts +0 -1
  804. package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +0 -1
  805. package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +0 -1
  806. package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +0 -1
  807. package/dist/features/claude-code-plugin-loader/loader.d.ts +0 -1
  808. package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +0 -1
  809. package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +0 -1
  810. package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +0 -1
  811. package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +0 -1
  812. package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +0 -1
  813. package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +0 -1
  814. package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +0 -1
  815. package/dist/features/claude-code-plugin-loader/types.d.ts +0 -1
  816. package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +0 -17
  817. package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
  818. package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
  819. package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
  820. package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
  821. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
  822. package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
  823. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  824. package/dist/mcp/codegraph.d.ts +0 -16
  825. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  826. package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +0 -1
  827. package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +0 -1
  828. package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +0 -1
  829. package/dist/shared/prompt-async-gate/queue.d.ts +0 -1
  830. package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +0 -1
  831. package/dist/shared/prompt-async-gate/reservations.d.ts +0 -1
  832. package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +0 -1
  833. package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +0 -1
  834. package/dist/shared/prompt-async-gate/timing.d.ts +0 -1
  835. package/dist/shared/prompt-async-gate/types.d.ts +0 -1
  836. package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
  837. package/dist/skills/data-scientist/references/execution-templates.md +0 -197
  838. package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
  839. package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
  840. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  841. package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
  842. package/dist/tools/delegate-task/anthropic-categories.d.ts +0 -2
  843. package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
  844. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  845. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  846. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  847. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  848. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  849. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  850. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  851. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  852. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12136
  853. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9734
  854. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  855. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  856. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  857. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  858. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  859. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  860. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  861. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -309
  862. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -80
  863. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  864. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  865. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  866. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  867. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  868. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -21
  869. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  870. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  871. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  872. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  873. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  874. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  875. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  876. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  877. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  878. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  879. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  880. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  881. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  882. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  883. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  884. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  885. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  886. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  887. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  888. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  889. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  890. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  891. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  892. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  893. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  894. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  895. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  896. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  897. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  898. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  899. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  900. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  901. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  902. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  903. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  904. package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +0 -21
  905. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  906. package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -471
  907. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  908. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  909. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  910. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  911. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  912. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  913. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  914. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  915. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  916. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  917. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  918. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  919. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  920. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  921. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  922. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
  923. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  924. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  925. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  926. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  927. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  928. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  929. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  930. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  931. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  932. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  933. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  934. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  935. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  936. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  937. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  938. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  939. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  940. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  941. /package/packages/omo-codex/plugin/components/{codegraph → ulw-execute-continuation}/LICENSE +0 -0
  942. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  943. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  944. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  945. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  946. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  947. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  948. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  949. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  950. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  951. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  952. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // src/cli.ts
4
+ import { argv, stderr } from "node:process";
5
+
3
6
  // ../lsp-core/src/lsp/cleanup-errors.ts
4
7
  function writeCleanupError(message) {
5
8
  process.stderr.write(`${message}
@@ -17,6 +20,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
17
20
  // ../lsp-core/src/lsp/connection.ts
18
21
  import { pathToFileURL } from "node:url";
19
22
 
23
+ // ../lsp-core/src/lsp/timer-provider.ts
24
+ var realTimerProvider = {
25
+ now: () => Date.now(),
26
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
27
+ clearTimeout: (handle) => clearTimeout(handle)
28
+ };
29
+
20
30
  // ../lsp-core/src/lsp/constants.ts
21
31
  var DEFAULT_MAX_REFERENCES = 200;
22
32
  var DEFAULT_MAX_SYMBOLS = 200;
@@ -25,28 +35,24 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
25
35
  var REQUEST_TIMEOUT_MS = 15000;
26
36
  var INIT_TIMEOUT_MS = 60000;
27
37
  var IDLE_TIMEOUT_MS = 5 * 60000;
38
+ var MAX_RESIDENT_CLIENTS = 6;
28
39
  var REAPER_INTERVAL_MS = 60000;
29
40
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
30
41
  var STOP_SIGKILL_GRACE_MS = 1000;
42
+ var CLIENT_RESPAWN_RETRY_LIMIT = 2;
43
+ var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
31
44
 
32
45
  // ../lsp-core/src/lsp/errors.ts
33
46
  class LspConnectionClosedError extends Error {
34
- serverId;
35
- root;
36
- name = "LspConnectionClosedError";
37
47
  constructor(serverId, root, message) {
38
48
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
39
49
  this.serverId = serverId;
40
50
  this.root = root;
51
+ this.name = "LspConnectionClosedError";
41
52
  }
42
53
  }
43
54
 
44
55
  class LspProcessExitedError extends Error {
45
- serverId;
46
- root;
47
- exitCode;
48
- stderrTail;
49
- name = "LspProcessExitedError";
50
56
  constructor(serverId, root, exitCode, stderrTail) {
51
57
  const stderrSuffix = stderrTail ? `
52
58
  stderr tail: ${stderrTail}` : "";
@@ -55,46 +61,59 @@ stderr tail: ${stderrTail}` : "";
55
61
  this.root = root;
56
62
  this.exitCode = exitCode;
57
63
  this.stderrTail = stderrTail;
64
+ this.name = "LspProcessExitedError";
58
65
  }
59
66
  }
60
67
 
61
68
  class LspRequestTimeoutError extends Error {
62
- method;
63
- stderrTail;
64
- name = "LspRequestTimeoutError";
65
69
  constructor(method, stderrTail) {
66
70
  const stderrSuffix = stderrTail ? `
67
71
  recent stderr: ${stderrTail}` : "";
68
72
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
69
73
  this.method = method;
70
74
  this.stderrTail = stderrTail;
75
+ this.name = "LspRequestTimeoutError";
71
76
  }
72
77
  }
73
78
 
74
79
  class LspInvalidPathError extends Error {
75
- name = "LspInvalidPathError";
80
+ constructor() {
81
+ super(...arguments);
82
+ this.name = "LspInvalidPathError";
83
+ }
76
84
  }
77
85
 
78
86
  class LspServerLookupError extends Error {
79
- lookup;
80
- name = "LspServerLookupError";
81
87
  constructor(message, lookup) {
82
88
  super(message);
83
89
  this.lookup = lookup;
90
+ this.name = "LspServerLookupError";
84
91
  }
85
92
  }
86
93
 
87
94
  class LspServerInitializingError extends Error {
88
- originalError;
89
- name = "LspServerInitializingError";
90
95
  constructor(originalError) {
91
96
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
92
97
  this.originalError = originalError;
98
+ this.name = "LspServerInitializingError";
93
99
  }
94
100
  }
95
101
 
96
102
  class LspProcessSpawnError extends Error {
97
- name = "LspProcessSpawnError";
103
+ constructor() {
104
+ super(...arguments);
105
+ this.name = "LspProcessSpawnError";
106
+ }
107
+ }
108
+
109
+ class LspClientRespawnBudgetExceededError extends Error {
110
+ constructor(serverId, root, retryLimit) {
111
+ super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
112
+ this.serverId = serverId;
113
+ this.root = root;
114
+ this.retryLimit = retryLimit;
115
+ this.name = "LspClientRespawnBudgetExceededError";
116
+ }
98
117
  }
99
118
  function isLspDeadConnectionError(err) {
100
119
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -110,20 +129,31 @@ var METHOD_NOT_FOUND = -32601;
110
129
  var INTERNAL_ERROR = -32603;
111
130
 
112
131
  class JsonRpcConnection {
113
- reader;
114
- writer;
115
- pendingRequests = new Map;
116
- notificationHandlers = new Map;
117
- requestHandlers = new Map;
118
- closeHandlers = [];
119
- errorHandlers = [];
120
- inputBuffer = Buffer.alloc(0);
121
- nextRequestId = 1;
122
- listening = false;
123
- disposed = false;
124
132
  constructor(reader, writer) {
125
133
  this.reader = reader;
126
134
  this.writer = writer;
135
+ this.pendingRequests = new Map;
136
+ this.notificationHandlers = new Map;
137
+ this.requestHandlers = new Map;
138
+ this.closeHandlers = [];
139
+ this.errorHandlers = [];
140
+ this.inputBuffer = Buffer.alloc(0);
141
+ this.nextRequestId = 1;
142
+ this.listening = false;
143
+ this.disposed = false;
144
+ this.handleData = (chunk) => {
145
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
146
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
147
+ this.drainInputBuffer();
148
+ };
149
+ this.handleClose = () => {
150
+ for (const handler of this.closeHandlers) {
151
+ handler();
152
+ }
153
+ };
154
+ this.handleStreamError = (error) => {
155
+ this.emitError(error);
156
+ };
127
157
  }
128
158
  listen() {
129
159
  if (this.listening)
@@ -158,6 +188,7 @@ class JsonRpcConnection {
158
188
  let cancelAfterWrite = false;
159
189
  let settled = false;
160
190
  const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
191
+ let rejectAfterCancelWrite;
161
192
  const responsePromise = new Promise((resolve, reject) => {
162
193
  const cleanup = () => {
163
194
  options.signal?.removeEventListener("abort", onAbort);
@@ -169,15 +200,19 @@ class JsonRpcConnection {
169
200
  this.pendingRequests.delete(key);
170
201
  cleanup();
171
202
  const rejectCancelled = () => reject(abortError(options.signal));
203
+ rejectAfterCancelWrite = async () => {
204
+ try {
205
+ await writeCancel();
206
+ } catch (error) {
207
+ this.emitError(toError(error));
208
+ }
209
+ rejectCancelled();
210
+ };
172
211
  if (!requestWritten) {
173
212
  cancelAfterWrite = true;
174
- rejectCancelled();
175
213
  return;
176
214
  }
177
- writeCancel().then(rejectCancelled, (error) => {
178
- this.emitError(toError(error));
179
- rejectCancelled();
180
- });
215
+ rejectAfterCancelWrite();
181
216
  };
182
217
  const onAbort = () => settleCancel();
183
218
  this.pendingRequests.set(key, {
@@ -205,7 +240,7 @@ class JsonRpcConnection {
205
240
  await this.writeMessage(message);
206
241
  requestWritten = true;
207
242
  if (cancelAfterWrite)
208
- await writeCancel();
243
+ await rejectAfterCancelWrite?.();
209
244
  } catch (error) {
210
245
  if (settled)
211
246
  return responsePromise;
@@ -244,19 +279,6 @@ class JsonRpcConnection {
244
279
  this.notificationHandlers.clear();
245
280
  this.requestHandlers.clear();
246
281
  }
247
- handleData = (chunk) => {
248
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
249
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
250
- this.drainInputBuffer();
251
- };
252
- handleClose = () => {
253
- for (const handler of this.closeHandlers) {
254
- handler();
255
- }
256
- };
257
- handleStreamError = (error) => {
258
- this.emitError(error);
259
- };
260
282
  drainInputBuffer() {
261
283
  while (true) {
262
284
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR);
@@ -604,33 +626,29 @@ function isPosition(value) {
604
626
 
605
627
  // ../lsp-core/src/lsp/transport.ts
606
628
  class LspClientNotStartedError extends Error {
607
- serverId;
608
- root;
609
- name = "LspClientNotStartedError";
610
629
  constructor(serverId, root) {
611
630
  super("LSP client not started");
612
631
  this.serverId = serverId;
613
632
  this.root = root;
633
+ this.name = "LspClientNotStartedError";
614
634
  }
615
635
  }
616
636
 
617
637
  class LspClientTransport {
618
- root;
619
- server;
620
- proc = null;
621
- connection = null;
622
- stderrBuffer = [];
623
- processExited = false;
624
- diagnosticsStore = new Map;
625
- requestTimeoutMs;
626
- initializeTimeoutMs;
627
- workspaceApplyEditHandler = null;
628
- diagnosticPullSupported = false;
629
638
  constructor(root, server, timeouts = {}) {
630
639
  this.root = root;
631
640
  this.server = server;
641
+ this.proc = null;
642
+ this.connection = null;
643
+ this.stderrBuffer = [];
644
+ this.processExited = false;
645
+ this.diagnosticsStore = new Map;
646
+ this.workspaceApplyEditHandler = null;
647
+ this.diagnosticPullSupported = false;
648
+ this.documentFormattingSupported = false;
632
649
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
633
650
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
651
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
634
652
  }
635
653
  pid() {
636
654
  return this.proc?.pid;
@@ -650,6 +668,12 @@ class LspClientTransport {
650
668
  isDiagnosticPullSupported() {
651
669
  return this.diagnosticPullSupported;
652
670
  }
671
+ setDocumentFormattingSupported(supported) {
672
+ this.documentFormattingSupported = supported;
673
+ }
674
+ isDocumentFormattingSupported() {
675
+ return this.documentFormattingSupported;
676
+ }
653
677
  handlePublishDiagnostics(params) {
654
678
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
655
679
  }
@@ -725,7 +749,7 @@ class LspClientTransport {
725
749
  const options = args[1];
726
750
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
727
751
  const timeoutController = new AbortController;
728
- const timeoutHandle = setTimeout(() => {
752
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
729
753
  const stderrTail = this.stderrBuffer.slice(-5).join(`
730
754
  `);
731
755
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -744,7 +768,7 @@ class LspClientTransport {
744
768
  }
745
769
  throw error;
746
770
  } finally {
747
- clearTimeout(timeoutHandle);
771
+ this.timerProvider.clearTimeout(timeoutHandle);
748
772
  combinedSignal.dispose();
749
773
  }
750
774
  }
@@ -863,6 +887,14 @@ function supportsDiagnosticPull(capabilities) {
863
887
  return false;
864
888
  return Object.hasOwn(capabilities, "diagnosticProvider");
865
889
  }
890
+ function supportsDocumentFormatting(capabilities) {
891
+ if (capabilities === undefined)
892
+ return false;
893
+ const provider = capabilities.documentFormattingProvider;
894
+ if (provider === undefined || provider === null || provider === false)
895
+ return false;
896
+ return provider === true || typeof provider === "object";
897
+ }
866
898
 
867
899
  class LspClientConnection extends LspClientTransport {
868
900
  async initialize() {
@@ -879,6 +911,7 @@ class LspClientConnection extends LspClientTransport {
879
911
  references: {},
880
912
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
881
913
  publishDiagnostics: {},
914
+ formatting: { dynamicRegistration: false },
882
915
  rename: {
883
916
  prepareSupport: true,
884
917
  prepareSupportDefaultBehavior: 1
@@ -920,6 +953,7 @@ class LspClientConnection extends LspClientTransport {
920
953
  initializationOptions: this.server.initialization
921
954
  }, { timeoutMs: this.initializeTimeoutMs });
922
955
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
956
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
923
957
  await this.sendNotification("initialized", {});
924
958
  await this.sendNotification("workspace/didChangeConfiguration", {
925
959
  settings: { json: { validate: { enable: true } } }
@@ -1125,6 +1159,17 @@ function canonicalPath(filePath) {
1125
1159
  return absolute;
1126
1160
  }
1127
1161
  }
1162
+ function normalizeDocumentUri(uri) {
1163
+ let decoded = uri;
1164
+ try {
1165
+ decoded = decodeURIComponent(uri);
1166
+ } catch {
1167
+ decoded = uri;
1168
+ }
1169
+ if (process.platform !== "win32")
1170
+ return decoded;
1171
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1172
+ }
1128
1173
  function isSameOrDescendant(candidate, parent) {
1129
1174
  const suffix = relative(parent, candidate);
1130
1175
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1135,17 +1180,18 @@ function movedPath(candidate, oldPath, newPath) {
1135
1180
  }
1136
1181
 
1137
1182
  class WorkspaceDocumentState {
1138
- sendNotification;
1139
- clearDiagnostics;
1140
- openDocuments = new Map;
1141
- openByUri = new Map;
1142
- openPromises = new Map;
1143
- now;
1144
- versionlessPublishQuiescenceMs;
1145
1183
  constructor(sendNotification, clearDiagnostics, options = {}) {
1146
1184
  this.sendNotification = sendNotification;
1147
1185
  this.clearDiagnostics = clearDiagnostics;
1148
- this.now = options.now ?? (() => Date.now());
1186
+ this.openDocuments = new Map;
1187
+ this.openByUri = new Map;
1188
+ this.openPromises = new Map;
1189
+ this.timerProvider = options.timerProvider ?? {
1190
+ now: options.now ?? (() => Date.now()),
1191
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1192
+ clearTimeout: (handle) => clearTimeout(handle)
1193
+ };
1194
+ this.now = () => this.timerProvider.now();
1149
1195
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1150
1196
  }
1151
1197
  async openFile(filePath) {
@@ -1167,7 +1213,7 @@ class WorkspaceDocumentState {
1167
1213
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1168
1214
  }
1169
1215
  getStoredDiagnostics(uri) {
1170
- const state = this.openByUri.get(uri);
1216
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1171
1217
  if (!state)
1172
1218
  return [];
1173
1219
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1189,13 +1235,13 @@ class WorkspaceDocumentState {
1189
1235
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1190
1236
  }
1191
1237
  getPullCache(snapshot) {
1192
- const state = this.openByUri.get(snapshot.uri);
1238
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1193
1239
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1194
1240
  return null;
1195
1241
  return state.pullCache;
1196
1242
  }
1197
1243
  recordPullDiagnostics(snapshot, report) {
1198
- const state = this.openByUri.get(snapshot.uri);
1244
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1199
1245
  if (!state)
1200
1246
  return;
1201
1247
  state.pullCache = {
@@ -1205,7 +1251,7 @@ class WorkspaceDocumentState {
1205
1251
  };
1206
1252
  }
1207
1253
  recordPublishedDiagnostics(params) {
1208
- const state = this.openByUri.get(params.uri);
1254
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1209
1255
  if (!state)
1210
1256
  return;
1211
1257
  state.publishGeneration += 1;
@@ -1219,7 +1265,7 @@ class WorkspaceDocumentState {
1219
1265
  this.notifyWaiters(state);
1220
1266
  }
1221
1267
  resolvePushDiagnostics(snapshot) {
1222
- const state = this.openByUri.get(snapshot.uri);
1268
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1223
1269
  if (!state?.lastPublish)
1224
1270
  return { status: "missing" };
1225
1271
  const publish = state.lastPublish;
@@ -1233,7 +1279,7 @@ class WorkspaceDocumentState {
1233
1279
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1234
1280
  }
1235
1281
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1236
- const state = this.openByUri.get(snapshot.uri);
1282
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1237
1283
  if (!state || timeoutMs <= 0)
1238
1284
  return Promise.resolve();
1239
1285
  return new Promise((resolveActivity) => {
@@ -1242,11 +1288,11 @@ class WorkspaceDocumentState {
1242
1288
  if (settled)
1243
1289
  return;
1244
1290
  settled = true;
1245
- clearTimeout(timer);
1291
+ this.timerProvider.clearTimeout(timer);
1246
1292
  state.waiters.delete(finish);
1247
1293
  resolveActivity();
1248
1294
  };
1249
- const timer = setTimeout(finish, timeoutMs);
1295
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1250
1296
  if (typeof timer.unref === "function")
1251
1297
  timer.unref();
1252
1298
  state.waiters.add(finish);
@@ -1354,7 +1400,7 @@ class WorkspaceDocumentState {
1354
1400
  waiters: new Set
1355
1401
  };
1356
1402
  this.openDocuments.set(path, state);
1357
- this.openByUri.set(state.uri, state);
1403
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
1358
1404
  this.notifyWaiters(state);
1359
1405
  await this.sendNotification("textDocument/didOpen", {
1360
1406
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -1379,7 +1425,7 @@ class WorkspaceDocumentState {
1379
1425
  }
1380
1426
  async closeDocument(state) {
1381
1427
  this.openDocuments.delete(state.path);
1382
- this.openByUri.delete(state.uri);
1428
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
1383
1429
  this.clearDiagnostics(state.uri);
1384
1430
  this.notifyWaiters(state);
1385
1431
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -1408,13 +1454,11 @@ import { dirname, isAbsolute, relative as relative2, resolve as resolve2 } from
1408
1454
  import { fileURLToPath } from "node:url";
1409
1455
 
1410
1456
  class WorkspaceEditPathError extends Error {
1411
- path;
1412
- detail;
1413
- name = "WorkspaceEditPathError";
1414
1457
  constructor(path, detail) {
1415
1458
  super(`${detail}: ${path}`);
1416
1459
  this.path = path;
1417
1460
  this.detail = detail;
1461
+ this.name = "WorkspaceEditPathError";
1418
1462
  }
1419
1463
  }
1420
1464
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -1706,13 +1750,11 @@ function canonicalFingerprint(operations) {
1706
1750
 
1707
1751
  // ../lsp-core/src/lsp/workspace-edit-types.ts
1708
1752
  class WorkspaceEditValidationError extends Error {
1709
- changeIndex;
1710
- detail;
1711
- name = "WorkspaceEditValidationError";
1712
1753
  constructor(changeIndex, detail) {
1713
1754
  super(`change ${changeIndex}: ${detail}`);
1714
1755
  this.changeIndex = changeIndex;
1715
1756
  this.detail = detail;
1757
+ this.name = "WorkspaceEditValidationError";
1716
1758
  }
1717
1759
  }
1718
1760
 
@@ -1798,14 +1840,14 @@ function parseSinglePathResource(input, kind) {
1798
1840
  return;
1799
1841
  }
1800
1842
  if (kind === "create") {
1801
- const options2 = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
1843
+ const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
1802
1844
  target.operations.push({
1803
1845
  kind,
1804
1846
  changeIndex,
1805
1847
  path: resolvedPath.path,
1806
1848
  reportedPath: resolvedPath.requestedPath,
1807
- overwrite: options2["overwrite"] ?? false,
1808
- ignoreIfExists: options2["ignoreIfExists"] ?? false,
1849
+ overwrite: options["overwrite"] ?? false,
1850
+ ignoreIfExists: options["ignoreIfExists"] ?? false,
1809
1851
  followedSymbolicLink: resolvedPath.followedSymbolicLink
1810
1852
  });
1811
1853
  return;
@@ -2210,10 +2252,9 @@ function simulateDelete(operation, virtual) {
2210
2252
  import { existsSync as existsSync4, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
2211
2253
  import { dirname as dirname3, resolve as resolve4 } from "node:path";
2212
2254
  class WorkspaceSnapshotBuilder {
2213
- workspaceRoot;
2214
- snapshots = new Map;
2215
2255
  constructor(workspaceRoot) {
2216
2256
  this.workspaceRoot = workspaceRoot;
2257
+ this.snapshots = new Map;
2217
2258
  }
2218
2259
  build(operations) {
2219
2260
  this.add(this.workspaceRoot, false);
@@ -2257,8 +2298,10 @@ function snapshotOperations(operations, workspaceRoot) {
2257
2298
 
2258
2299
  // ../lsp-core/src/lsp/workspace-edit-plan.ts
2259
2300
  class PlanPathIndex {
2260
- firstChangeByPath = new Map;
2261
- reportedPathByCanonical = new Map;
2301
+ constructor() {
2302
+ this.firstChangeByPath = new Map;
2303
+ this.reportedPathByCanonical = new Map;
2304
+ }
2262
2305
  build(operations) {
2263
2306
  for (const operation of operations) {
2264
2307
  switch (operation.kind) {
@@ -2274,11 +2317,11 @@ class PlanPathIndex {
2274
2317
  }
2275
2318
  }
2276
2319
  }
2277
- add(path, reportedPath2, changeIndex) {
2320
+ add(path, reportedPath, changeIndex) {
2278
2321
  if (!this.firstChangeByPath.has(path))
2279
2322
  this.firstChangeByPath.set(path, changeIndex);
2280
2323
  if (!this.reportedPathByCanonical.has(path))
2281
- this.reportedPathByCanonical.set(path, reportedPath2);
2324
+ this.reportedPathByCanonical.set(path, reportedPath);
2282
2325
  }
2283
2326
  }
2284
2327
  function fingerprintWorkspaceEdit(edit, workspaceRoot) {
@@ -2347,14 +2390,11 @@ function isRecord3(value) {
2347
2390
  }
2348
2391
 
2349
2392
  class WorkspaceMutationController {
2350
- workspaceRoot;
2351
- documents;
2352
- activeLease = null;
2353
- nextLeaseId = 1;
2354
- io;
2355
2393
  constructor(workspaceRoot, documents) {
2356
2394
  this.workspaceRoot = workspaceRoot;
2357
2395
  this.documents = documents;
2396
+ this.activeLease = null;
2397
+ this.nextLeaseId = 1;
2358
2398
  }
2359
2399
  setIo(io) {
2360
2400
  this.io = io;
@@ -2393,8 +2433,8 @@ class WorkspaceMutationController {
2393
2433
  };
2394
2434
  }
2395
2435
  lease.phase = "applying";
2396
- lease.applyCompletion = new Promise((resolve5) => {
2397
- lease.resolveApply = resolve5;
2436
+ lease.applyCompletion = new Promise((resolve) => {
2437
+ lease.resolveApply = resolve;
2398
2438
  });
2399
2439
  const edit = isRecord3(params) ? params["edit"] : undefined;
2400
2440
  const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
@@ -2467,14 +2507,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
2467
2507
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
2468
2508
 
2469
2509
  class LspClient extends LspClientConnection {
2470
- diagnosticPullErrors = [];
2471
- documents;
2472
- workspaceMutations;
2473
- diagnosticsFreshnessTimeoutMs;
2474
2510
  constructor(root, server, options = {}) {
2475
2511
  super(root, server, options);
2512
+ this.diagnosticPullErrors = [];
2476
2513
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2477
2514
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
2515
+ timerProvider: this.timerProvider,
2478
2516
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
2479
2517
  });
2480
2518
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -2527,6 +2565,18 @@ class LspClient extends LspClientConnection {
2527
2565
  textDocument: { uri: pathToFileURL3(absPath).href }
2528
2566
  }, options);
2529
2567
  }
2568
+ async formatDocument(filePath, options, signal) {
2569
+ if (!this.isDocumentFormattingSupported())
2570
+ return null;
2571
+ const absPath = this.resolveWorkspacePath(filePath);
2572
+ await this.openFile(absPath);
2573
+ const requestOptions = signal === undefined ? {} : { signal };
2574
+ const edits = await this.sendRequest("textDocument/formatting", {
2575
+ textDocument: { uri: pathToFileURL3(absPath).href },
2576
+ options
2577
+ }, requestOptions);
2578
+ return edits ?? [];
2579
+ }
2530
2580
  async workspaceSymbols(query, signal) {
2531
2581
  const options = signal === undefined ? {} : { signal };
2532
2582
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -2566,7 +2616,7 @@ class LspClient extends LspClientConnection {
2566
2616
  const absPath = this.resolveWorkspacePath(filePath);
2567
2617
  const uri = pathToFileURL3(absPath).href;
2568
2618
  await this.openFile(absPath);
2569
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
2619
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
2570
2620
  for (;; ) {
2571
2621
  signal?.throwIfAborted();
2572
2622
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -2579,13 +2629,13 @@ class LspClient extends LspClientConnection {
2579
2629
  if (!pushFallbackOnly) {
2580
2630
  const cached = this.documents.getPullCache(snapshot);
2581
2631
  try {
2582
- const remainingMs2 = deadlineAt - Date.now();
2583
- if (remainingMs2 <= 0)
2632
+ const remainingMs = deadlineAt - this.timerProvider.now();
2633
+ if (remainingMs <= 0)
2584
2634
  return this.freshnessTimeout(absPath);
2585
2635
  const result = await this.sendRequest("textDocument/diagnostic", {
2586
2636
  textDocument: { uri },
2587
2637
  ...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
2588
- }, { timeoutMs: remainingMs2, ...signal === undefined ? {} : { signal } });
2638
+ }, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
2589
2639
  if (!this.documents.isCurrentSnapshot(snapshot))
2590
2640
  continue;
2591
2641
  const report = this.parseDiagnosticPullReport(result);
@@ -2614,7 +2664,7 @@ class LspClient extends LspClientConnection {
2614
2664
  }
2615
2665
  if (!pushFallbackOnly)
2616
2666
  continue;
2617
- const remainingMs = deadlineAt - Date.now();
2667
+ const remainingMs = deadlineAt - this.timerProvider.now();
2618
2668
  if (remainingMs <= 0) {
2619
2669
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
2620
2670
  const cached = this.documents.getPullCache(snapshot);
@@ -2666,7 +2716,7 @@ function waitForDiagnosticsActivity(wait, signal) {
2666
2716
  return wait;
2667
2717
  if (signal.aborted)
2668
2718
  return Promise.reject(abortError2(signal));
2669
- return new Promise((resolve6, reject) => {
2719
+ return new Promise((resolve, reject) => {
2670
2720
  const onAbort = () => {
2671
2721
  signal.removeEventListener("abort", onAbort);
2672
2722
  reject(abortError2(signal));
@@ -2674,7 +2724,7 @@ function waitForDiagnosticsActivity(wait, signal) {
2674
2724
  signal.addEventListener("abort", onAbort, { once: true });
2675
2725
  wait.then(() => {
2676
2726
  signal.removeEventListener("abort", onAbort);
2677
- resolve6();
2727
+ resolve();
2678
2728
  }, (error) => {
2679
2729
  signal.removeEventListener("abort", onAbort);
2680
2730
  reject(error);
@@ -2742,7 +2792,7 @@ async function stopClientBestEffort(client) {
2742
2792
  function awaitWithSignal(promise, signal) {
2743
2793
  if (!signal)
2744
2794
  return promise;
2745
- return new Promise((resolve6, reject) => {
2795
+ return new Promise((resolve, reject) => {
2746
2796
  let settled = false;
2747
2797
  const onAbort = () => {
2748
2798
  if (settled)
@@ -2760,7 +2810,7 @@ function awaitWithSignal(promise, signal) {
2760
2810
  return;
2761
2811
  settled = true;
2762
2812
  signal.removeEventListener("abort", onAbort);
2763
- resolve6(value);
2813
+ resolve(value);
2764
2814
  }, (err) => {
2765
2815
  if (settled)
2766
2816
  return;
@@ -2772,18 +2822,16 @@ function awaitWithSignal(promise, signal) {
2772
2822
  }
2773
2823
 
2774
2824
  class LspManager {
2775
- clients = new Map;
2776
- reaperHandle = null;
2777
- signalDisposer = null;
2778
- disposed = false;
2779
- idleTimeoutMs;
2780
- initTimeoutMs;
2781
- reaperIntervalMs;
2782
- clientFactory;
2783
- now;
2784
2825
  constructor(options = {}) {
2826
+ this.clients = new Map;
2827
+ this.pendingStops = new Map;
2828
+ this.respawnBudgets = new Map;
2829
+ this.reaperHandle = null;
2830
+ this.signalDisposer = null;
2831
+ this.disposed = false;
2785
2832
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
2786
2833
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
2834
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
2787
2835
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
2788
2836
  this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
2789
2837
  this.now = options.now ?? (() => Date.now());
@@ -2803,24 +2851,79 @@ class LspManager {
2803
2851
  getKey(root, serverId) {
2804
2852
  return `${root}::${serverId}`;
2805
2853
  }
2854
+ tombstoneStop(key, client) {
2855
+ const stop = stopClientBestEffort(client);
2856
+ this.pendingStops.set(key, stop);
2857
+ stop.finally(() => {
2858
+ if (this.pendingStops.get(key) === stop) {
2859
+ this.pendingStops.delete(key);
2860
+ }
2861
+ });
2862
+ return stop;
2863
+ }
2864
+ recordDeadGeneration(key) {
2865
+ let budget = this.respawnBudgets.get(key);
2866
+ if (budget === undefined) {
2867
+ budget = { deadGenerations: 0, exhaustedAt: null };
2868
+ this.respawnBudgets.set(key, budget);
2869
+ }
2870
+ budget.deadGenerations += 1;
2871
+ }
2872
+ markHealthyGeneration(key) {
2873
+ this.respawnBudgets.delete(key);
2874
+ }
2875
+ ensureRespawnAllowed(key, root, serverId) {
2876
+ const budget = this.respawnBudgets.get(key);
2877
+ if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
2878
+ return;
2879
+ if (budget.exhaustedAt === null) {
2880
+ budget.exhaustedAt = this.now();
2881
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
2882
+ }
2883
+ if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
2884
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
2885
+ }
2886
+ budget.deadGenerations = 0;
2887
+ budget.exhaustedAt = null;
2888
+ }
2806
2889
  reapStale() {
2807
2890
  const t = this.now();
2808
2891
  for (const [key, managed] of this.clients) {
2809
2892
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
2810
- stopClientBestEffort(managed.client);
2811
2893
  this.clients.delete(key);
2894
+ this.tombstoneStop(key, managed.client);
2812
2895
  continue;
2813
2896
  }
2814
2897
  if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
2815
- stopClientBestEffort(managed.client);
2816
2898
  this.clients.delete(key);
2899
+ this.tombstoneStop(key, managed.client);
2900
+ }
2901
+ }
2902
+ }
2903
+ evictForAdmission() {
2904
+ while (this.clients.size >= this.maxResidentClients) {
2905
+ const victim = this.leastRecentlyUsedIdleClient();
2906
+ if (!victim)
2907
+ return;
2908
+ this.clients.delete(victim.key);
2909
+ this.tombstoneStop(victim.key, victim.managed.client);
2910
+ }
2911
+ }
2912
+ leastRecentlyUsedIdleClient() {
2913
+ let candidate = null;
2914
+ for (const [key, managed] of this.clients) {
2915
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
2916
+ continue;
2917
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
2918
+ candidate = { key, managed };
2817
2919
  }
2818
2920
  }
2921
+ return candidate;
2819
2922
  }
2820
2923
  async tryDeleteIfOrphaned(key, managed) {
2821
2924
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
2822
2925
  this.clients.delete(key);
2823
- await stopClientBestEffort(managed.client);
2926
+ await this.tombstoneStop(key, managed.client);
2824
2927
  }
2825
2928
  }
2826
2929
  async getClient(root, server, signal) {
@@ -2829,12 +2932,22 @@ class LspManager {
2829
2932
  }
2830
2933
  signal?.throwIfAborted();
2831
2934
  const key = this.getKey(root, server.id);
2935
+ for (;; ) {
2936
+ const pendingStop = this.pendingStops.get(key);
2937
+ if (pendingStop === undefined)
2938
+ break;
2939
+ await awaitWithSignal(pendingStop, signal);
2940
+ signal?.throwIfAborted();
2941
+ }
2942
+ if (this.disposed) {
2943
+ throw new Error("LspManager has been disposed");
2944
+ }
2832
2945
  let managed = this.clients.get(key);
2833
2946
  if (managed) {
2834
2947
  const t = this.now();
2835
2948
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
2836
- await stopClientBestEffort(managed.client);
2837
2949
  this.clients.delete(key);
2950
+ await this.tombstoneStop(key, managed.client);
2838
2951
  managed = undefined;
2839
2952
  }
2840
2953
  }
@@ -2855,14 +2968,20 @@ class LspManager {
2855
2968
  signal.throwIfAborted();
2856
2969
  }
2857
2970
  if (!managed.client.isAlive()) {
2858
- await stopClientBestEffort(managed.client);
2859
- this.clients.delete(key);
2971
+ this.recordDeadGeneration(key);
2972
+ if (this.clients.get(key) === managed) {
2973
+ this.clients.delete(key);
2974
+ }
2975
+ await this.tombstoneStop(key, managed.client);
2860
2976
  return this.getClient(root, server, signal);
2861
2977
  }
2978
+ this.markHealthyGeneration(key);
2862
2979
  managed.refCount++;
2863
2980
  managed.lastUsedAt = this.now();
2864
2981
  return managed.client;
2865
2982
  }
2983
+ this.evictForAdmission();
2984
+ this.ensureRespawnAllowed(key, root, server.id);
2866
2985
  const client = this.clientFactory(root, server);
2867
2986
  const initStartedAt = this.now();
2868
2987
  const initPromise = (async () => {
@@ -2886,7 +3005,7 @@ class LspManager {
2886
3005
  if (this.clients.get(key) === newManaged) {
2887
3006
  this.clients.delete(key);
2888
3007
  }
2889
- await stopClientBestEffort(client);
3008
+ await this.tombstoneStop(key, client);
2890
3009
  throw err;
2891
3010
  }
2892
3011
  newManaged.pendingWaiters--;
@@ -2897,6 +3016,15 @@ class LspManager {
2897
3016
  await this.tryDeleteIfOrphaned(key, newManaged);
2898
3017
  signal.throwIfAborted();
2899
3018
  }
3019
+ if (!client.isAlive()) {
3020
+ this.recordDeadGeneration(key);
3021
+ if (this.clients.get(key) === newManaged) {
3022
+ this.clients.delete(key);
3023
+ }
3024
+ await this.tombstoneStop(key, client);
3025
+ return this.getClient(root, server, signal);
3026
+ }
3027
+ this.markHealthyGeneration(key);
2900
3028
  newManaged.refCount++;
2901
3029
  newManaged.lastUsedAt = this.now();
2902
3030
  return client;
@@ -2917,14 +3045,20 @@ class LspManager {
2917
3045
  if (client && managed.client !== client)
2918
3046
  return;
2919
3047
  this.clients.delete(key);
2920
- stopClientBestEffort(managed.client);
3048
+ this.tombstoneStop(key, managed.client);
2921
3049
  }
2922
3050
  warmupClient(root, server) {
2923
3051
  if (this.disposed)
2924
3052
  return;
2925
3053
  const key = this.getKey(root, server.id);
2926
- if (this.clients.has(key))
3054
+ if (this.clients.has(key) || this.pendingStops.has(key))
2927
3055
  return;
3056
+ this.evictForAdmission();
3057
+ try {
3058
+ this.ensureRespawnAllowed(key, root, server.id);
3059
+ } catch {
3060
+ return;
3061
+ }
2928
3062
  const client = this.clientFactory(root, server);
2929
3063
  const initStartedAt = this.now();
2930
3064
  const initPromise = (async () => {
@@ -2950,7 +3084,7 @@ class LspManager {
2950
3084
  if (this.clients.get(key) === managed) {
2951
3085
  this.clients.delete(key);
2952
3086
  }
2953
- stopClientBestEffort(client);
3087
+ this.tombstoneStop(key, client);
2954
3088
  });
2955
3089
  }
2956
3090
  isServerInitializing(root, serverId) {
@@ -2994,8 +3128,11 @@ class LspManager {
2994
3128
  for (const managed of this.clients.values()) {
2995
3129
  stopPromises.push(stopClientBestEffort(managed.client));
2996
3130
  }
3131
+ const tombstonedStops = [...this.pendingStops.values()];
2997
3132
  this.clients.clear();
2998
- await Promise.allSettled(stopPromises);
3133
+ this.respawnBudgets.clear();
3134
+ await Promise.allSettled([...stopPromises, ...tombstonedStops]);
3135
+ this.pendingStops.clear();
2999
3136
  }
3000
3137
  }
3001
3138
  var _defaultInstance = null;
@@ -3060,7 +3197,7 @@ ${body}` : `${body}
3060
3197
  await writeChunk(output, payload);
3061
3198
  }
3062
3199
  function writeChunk(output, chunk) {
3063
- return new Promise((resolve6, reject) => {
3200
+ return new Promise((resolve, reject) => {
3064
3201
  let settled = false;
3065
3202
  const onError = (error) => {
3066
3203
  if (settled)
@@ -3080,7 +3217,7 @@ function writeChunk(output, chunk) {
3080
3217
  return;
3081
3218
  }
3082
3219
  output.removeListener("error", onError);
3083
- resolve6();
3220
+ resolve();
3084
3221
  });
3085
3222
  } catch (error) {
3086
3223
  output.removeListener("error", onError);
@@ -3189,6 +3326,7 @@ async function runJsonRpcStdioServer(config) {
3189
3326
  const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
3190
3327
  isClosed = true;
3191
3328
  config.onIdleTimeout?.();
3329
+ config.input.destroy();
3192
3330
  });
3193
3331
  const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
3194
3332
  isClosed = true;
@@ -3285,7 +3423,11 @@ function createParentWatchdog(config, onDeadParent) {
3285
3423
  const probeAlive = config.probeAlive ?? isProcessAlive;
3286
3424
  let fired = false;
3287
3425
  const timer = setInterval(() => {
3288
- if (fired || probeAlive(parentPid))
3426
+ if (fired)
3427
+ return;
3428
+ const alive = probeAlive(parentPid);
3429
+ config.onPoll?.(alive);
3430
+ if (alive)
3289
3431
  return;
3290
3432
  fired = true;
3291
3433
  onDeadParent(parentPid, pollIntervalMs);
@@ -3320,8 +3462,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
3320
3462
  };
3321
3463
  }
3322
3464
  // ../lsp-core/src/lsp/client-wrapper.ts
3323
- import { existsSync as existsSync9, statSync as statSync3 } from "node:fs";
3324
- import { dirname as dirname6, join as join4, resolve as resolve7 } from "node:path";
3465
+ import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
3466
+ import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
3325
3467
 
3326
3468
  // ../lsp-core/src/request-context.ts
3327
3469
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -3330,18 +3472,17 @@ import { homedir } from "node:os";
3330
3472
  import { basename as basename2, delimiter as delimiter2, dirname as dirname4, isAbsolute as isAbsolute2, join as join2, relative as relative4, resolve as resolve6 } from "node:path";
3331
3473
 
3332
3474
  class LspRequestContextParseError extends Error {
3333
- code;
3334
- name = "LspRequestContextParseError";
3335
3475
  constructor(code, message) {
3336
3476
  super(message);
3337
3477
  this.code = code;
3478
+ this.name = "LspRequestContextParseError";
3338
3479
  }
3339
3480
  }
3340
3481
 
3341
3482
  class LspRequestContextUnavailableError extends Error {
3342
- name = "LspRequestContextUnavailableError";
3343
3483
  constructor() {
3344
3484
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
3485
+ this.name = "LspRequestContextUnavailableError";
3345
3486
  }
3346
3487
  }
3347
3488
  var storage = new AsyncLocalStorage;
@@ -3371,7 +3512,7 @@ function contextEnv(key) {
3371
3512
  }
3372
3513
  function createStandaloneMcpRequestContext(input = {}) {
3373
3514
  const env = input.env ?? process.env;
3374
- const cwd = canonicalCwd(input.cwd ?? process.cwd());
3515
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
3375
3516
  const home = input.homeDir ?? homedir();
3376
3517
  const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
3377
3518
  const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
@@ -3502,57 +3643,52 @@ function errorCode(error) {
3502
3643
  return typeof code === "string" ? code : undefined;
3503
3644
  }
3504
3645
 
3505
- // ../lsp-core/src/lsp/server-install-state.ts
3506
- import { existsSync as existsSync6, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3507
- import { dirname as dirname5 } from "node:path";
3508
- function getInstallDecisionsPath() {
3509
- return lspRequestContext().installDecisionsPath;
3510
- }
3511
- function loadInstallDecisions() {
3512
- const path = getInstallDecisionsPath();
3513
- if (!existsSync6(path))
3514
- return {};
3515
- try {
3516
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
3517
- return isInstallDecisions(parsed) ? parsed : {};
3518
- } catch {
3519
- return {};
3646
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3647
+ import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
3648
+ import { dirname as dirname5, join as join3 } from "node:path";
3649
+
3650
+ // ../lsp-core/src/lsp/workspace-markers.ts
3651
+ var GIT_WORKSPACE_MARKER = ".git";
3652
+ var PROJECT_WORKSPACE_MARKERS = [
3653
+ "package.json",
3654
+ "pyproject.toml",
3655
+ "Cargo.toml",
3656
+ "go.mod",
3657
+ "pom.xml",
3658
+ "build.gradle"
3659
+ ];
3660
+ var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
3661
+
3662
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3663
+ function findWorkspaceRootOutsideContext(directory) {
3664
+ const marked = nearestMarkedAncestor(directory);
3665
+ if (marked !== undefined)
3666
+ return marked;
3667
+ return realpathSync4(nearestExistingAncestor(directory));
3668
+ }
3669
+ function nearestMarkedAncestor(directory) {
3670
+ let current = directory;
3671
+ for (;; ) {
3672
+ if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
3673
+ return realpathSync4(current);
3674
+ }
3675
+ const parent = dirname5(current);
3676
+ if (parent === current)
3677
+ return;
3678
+ current = parent;
3520
3679
  }
3521
3680
  }
3522
- function loadInstallDecision(serverId) {
3523
- return loadInstallDecisions()[serverId];
3524
- }
3525
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3526
- const decisions = loadInstallDecisions();
3527
- decisions[serverId] = { decision, decidedAt };
3528
- writeInstallDecisions(decisions);
3529
- }
3530
- function isInstallDecision(value) {
3531
- return value === "declined" || value === "allowed";
3532
- }
3533
- function writeInstallDecisions(decisions) {
3534
- const path = getInstallDecisionsPath();
3535
- mkdirSync(dirname5(path), { recursive: true });
3536
- const tmpPath = `${path}.tmp`;
3537
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3538
- `, "utf8");
3539
- renameSync2(tmpPath, path);
3540
- }
3541
- function isInstallDecisions(value) {
3542
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3543
- }
3544
- function isInstallDecisionRecord(value) {
3545
- if (!isRecord5(value))
3546
- return false;
3547
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3548
- }
3549
- function isRecord5(value) {
3550
- return typeof value === "object" && value !== null && !Array.isArray(value);
3681
+ function nearestExistingAncestor(directory) {
3682
+ let current = directory;
3683
+ while (!existsSync6(current)) {
3684
+ const parent = dirname5(current);
3685
+ if (parent === current)
3686
+ return current;
3687
+ current = parent;
3688
+ }
3689
+ return current;
3551
3690
  }
3552
3691
 
3553
- // ../lsp-core/src/lsp/config-loader.ts
3554
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
3555
-
3556
3692
  // ../lsp-core/src/lsp/server-definitions.ts
3557
3693
  var LSP_INSTALL_HINTS = {
3558
3694
  typescript: "npm install -g typescript-language-server typescript",
@@ -3598,6 +3734,26 @@ var LSP_INSTALL_HINTS = {
3598
3734
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
3599
3735
  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"
3600
3736
  };
3737
+ var LSP_LOCAL_INSTALL_HINTS = {
3738
+ typescript: "bun add -d typescript-language-server typescript",
3739
+ vue: "bun add -d @vue/language-server",
3740
+ eslint: "bun add -d vscode-langservers-extracted",
3741
+ oxlint: "bun add -d oxlint",
3742
+ biome: "bun add -d @biomejs/biome",
3743
+ svelte: "bun add -d svelte-language-server",
3744
+ astro: "bun add -d @astrojs/language-server",
3745
+ bash: "bun add -d bash-language-server",
3746
+ "bash-ls": "bun add -d bash-language-server",
3747
+ "yaml-ls": "bun add -d yaml-language-server",
3748
+ php: "bun add -d intelephense",
3749
+ prisma: "bun add -d prisma",
3750
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
3751
+ pyright: "uv add --dev pyright",
3752
+ basedpyright: "uv add --dev basedpyright",
3753
+ ruff: "uv add --dev ruff",
3754
+ ty: "uv add --dev ty",
3755
+ "ruby-lsp": "bundle add ruby-lsp --group development"
3756
+ };
3601
3757
  var BUILTIN_SERVERS = {
3602
3758
  typescript: {
3603
3759
  command: ["typescript-language-server", "--stdio"],
@@ -3700,7 +3856,56 @@ var BUILTIN_SERVERS = {
3700
3856
  }
3701
3857
  };
3702
3858
 
3859
+ // ../lsp-core/src/lsp/server-install-state.ts
3860
+ import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3861
+ import { dirname as dirname6 } from "node:path";
3862
+ function getInstallDecisionsPath() {
3863
+ return lspRequestContext().installDecisionsPath;
3864
+ }
3865
+ function loadInstallDecisions() {
3866
+ const path = getInstallDecisionsPath();
3867
+ if (!existsSync7(path))
3868
+ return {};
3869
+ try {
3870
+ const parsed = JSON.parse(readFileSync3(path, "utf8"));
3871
+ return isInstallDecisions(parsed) ? parsed : {};
3872
+ } catch {
3873
+ return {};
3874
+ }
3875
+ }
3876
+ function loadInstallDecision(serverId) {
3877
+ return loadInstallDecisions()[serverId];
3878
+ }
3879
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3880
+ const decisions = loadInstallDecisions();
3881
+ decisions[serverId] = { decision, decidedAt };
3882
+ writeInstallDecisions(decisions);
3883
+ }
3884
+ function isInstallDecision(value) {
3885
+ return value === "declined" || value === "allowed";
3886
+ }
3887
+ function writeInstallDecisions(decisions) {
3888
+ const path = getInstallDecisionsPath();
3889
+ mkdirSync(dirname6(path), { recursive: true });
3890
+ const tmpPath = `${path}.tmp`;
3891
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3892
+ `, "utf8");
3893
+ renameSync2(tmpPath, path);
3894
+ }
3895
+ function isInstallDecisions(value) {
3896
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3897
+ }
3898
+ function isInstallDecisionRecord(value) {
3899
+ if (!isRecord5(value))
3900
+ return false;
3901
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3902
+ }
3903
+ function isRecord5(value) {
3904
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3905
+ }
3906
+
3703
3907
  // ../lsp-core/src/lsp/config-loader.ts
3908
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
3704
3909
  function getProjectConfigPaths() {
3705
3910
  return lspRequestContext().projectConfigPaths;
3706
3911
  }
@@ -3708,7 +3913,7 @@ function getUserConfigPath() {
3708
3913
  return lspRequestContext().userConfigPath;
3709
3914
  }
3710
3915
  function loadJsonFile(path) {
3711
- if (!existsSync7(path))
3916
+ if (!existsSync8(path))
3712
3917
  return null;
3713
3918
  try {
3714
3919
  const parsed = JSON.parse(readFileSync4(path, "utf-8"));
@@ -3755,10 +3960,10 @@ function getMergedServers() {
3755
3960
  }
3756
3961
  if (seen.has(id))
3757
3962
  continue;
3758
- const server2 = createServerFromEntry(id, entry, source);
3759
- if (!server2)
3963
+ const server = createServerFromEntry(id, entry, source);
3964
+ if (!server)
3760
3965
  continue;
3761
- servers.push(server2);
3966
+ servers.push(server);
3762
3967
  seen.add(id);
3763
3968
  }
3764
3969
  }
@@ -3790,7 +3995,7 @@ function createServerFromEntry(id, entry, source) {
3790
3995
  if (source === "project") {
3791
3996
  if (!builtin)
3792
3997
  return null;
3793
- const server3 = createServer({
3998
+ const server = createServer({
3794
3999
  id,
3795
4000
  command: builtin.command,
3796
4001
  extensions: entry.extensions ?? builtin.extensions,
@@ -3798,35 +4003,35 @@ function createServerFromEntry(id, entry, source) {
3798
4003
  source
3799
4004
  });
3800
4005
  if (entry.initialization !== undefined) {
3801
- server3.initialization = entry.initialization;
4006
+ server.initialization = entry.initialization;
3802
4007
  }
3803
- return server3;
4008
+ return server;
3804
4009
  }
3805
4010
  if (entry.command && entry.extensions) {
3806
- const server3 = createServer({
4011
+ const server = createServer({
3807
4012
  id,
3808
4013
  command: entry.command,
3809
4014
  extensions: entry.extensions,
3810
4015
  priority: entry.priority ?? 0,
3811
4016
  source
3812
4017
  });
3813
- applyOptionalServerFields(server3, entry);
3814
- return server3;
4018
+ applyOptionalServerFields(server, entry);
4019
+ return server;
3815
4020
  }
3816
4021
  if (!builtin)
3817
4022
  return null;
3818
- const server2 = createServer({
4023
+ const server = createServer({
3819
4024
  id,
3820
4025
  command: entry.command ?? builtin.command,
3821
4026
  extensions: entry.extensions ?? builtin.extensions,
3822
4027
  priority: entry.priority ?? 0,
3823
4028
  source
3824
4029
  });
3825
- applyOptionalServerFields(server2, entry);
3826
- return server2;
4030
+ applyOptionalServerFields(server, entry);
4031
+ return server;
3827
4032
  }
3828
4033
  function createServer(input) {
3829
- const server2 = {
4034
+ const server = {
3830
4035
  id: input.id,
3831
4036
  command: input.command,
3832
4037
  extensions: input.extensions,
@@ -3834,19 +4039,19 @@ function createServer(input) {
3834
4039
  source: input.source
3835
4040
  };
3836
4041
  if (input.env !== undefined) {
3837
- server2.env = input.env;
4042
+ server.env = input.env;
3838
4043
  }
3839
4044
  if (input.initialization !== undefined) {
3840
- server2.initialization = input.initialization;
4045
+ server.initialization = input.initialization;
3841
4046
  }
3842
- return server2;
4047
+ return server;
3843
4048
  }
3844
- function applyOptionalServerFields(server2, entry) {
4049
+ function applyOptionalServerFields(server, entry) {
3845
4050
  if (entry.env !== undefined) {
3846
- server2.env = entry.env;
4051
+ server.env = entry.env;
3847
4052
  }
3848
4053
  if (entry.initialization !== undefined) {
3849
- server2.initialization = entry.initialization;
4054
+ server.initialization = entry.initialization;
3850
4055
  }
3851
4056
  }
3852
4057
  function isConfigJson(value) {
@@ -3896,64 +4101,165 @@ function getDisabledServerIds() {
3896
4101
  }
3897
4102
 
3898
4103
  // ../lsp-core/src/lsp/server-installation.ts
3899
- import { existsSync as existsSync8 } from "node:fs";
3900
- import { delimiter as delimiter3, join as join3 } from "node:path";
3901
- function isServerInstalled(command, _workingDirectory) {
3902
- if (command.length === 0)
3903
- return false;
3904
- const [cmd] = command;
3905
- if (!cmd)
3906
- return false;
3907
- if (cmd.includes("/") || cmd.includes("\\")) {
3908
- if (existsSync8(cmd))
3909
- return true;
4104
+ import { existsSync as existsSync9 } from "node:fs";
4105
+ import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
4106
+ var LOCAL_BIN_RULES = [
4107
+ {
4108
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
4109
+ binDirs: [join4("node_modules", ".bin")]
4110
+ },
4111
+ {
4112
+ markers: [
4113
+ "pyproject.toml",
4114
+ "ty.toml",
4115
+ "requirements.txt",
4116
+ "setup.py",
4117
+ "setup.cfg",
4118
+ "Pipfile",
4119
+ "pyrightconfig.json",
4120
+ "ruff.toml",
4121
+ ".ruff.toml"
4122
+ ],
4123
+ binDirs: [
4124
+ join4(".venv", "bin"),
4125
+ join4(".venv", "Scripts"),
4126
+ join4("venv", "bin"),
4127
+ join4("venv", "Scripts"),
4128
+ join4(".env", "bin"),
4129
+ join4(".env", "Scripts")
4130
+ ]
4131
+ },
4132
+ {
4133
+ markers: ["Gemfile", "Gemfile.lock"],
4134
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4135
+ },
4136
+ {
4137
+ markers: ["go.mod", "go.sum", "go.work"],
4138
+ binDirs: ["bin"]
3910
4139
  }
3911
- const isWindows = process.platform === "win32";
3912
- let exts = [""];
3913
- if (isWindows) {
3914
- const pathExt = process.env["PATHEXT"] ?? "";
3915
- if (pathExt) {
3916
- const systemExts = pathExt.split(";").filter(Boolean);
3917
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
3918
- } else {
3919
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4140
+ ];
4141
+ var resolutionCache = new Map;
4142
+ var probeCount = 0;
4143
+ function probe(path) {
4144
+ probeCount += 1;
4145
+ return existsSync9(path);
4146
+ }
4147
+ function executableSuffixes(platform, pathExt) {
4148
+ if (platform !== "win32")
4149
+ return [""];
4150
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4151
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4152
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4153
+ }
4154
+ function probeWithSuffixes(directory, command, suffixes) {
4155
+ for (const suffix of suffixes) {
4156
+ const candidate = join4(directory, command + suffix);
4157
+ if (probe(candidate))
4158
+ return candidate;
4159
+ }
4160
+ return null;
4161
+ }
4162
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4163
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4164
+ let current = resolve7(workingDirectory);
4165
+ while (true) {
4166
+ for (const rule of LOCAL_BIN_RULES) {
4167
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
4168
+ continue;
4169
+ for (const binDir of rule.binDirs) {
4170
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4171
+ if (found !== null)
4172
+ return found;
4173
+ }
3920
4174
  }
4175
+ if (probe(join4(current, ".git")))
4176
+ return null;
4177
+ if (boundary !== undefined && current === boundary)
4178
+ return null;
4179
+ const parent = dirname7(current);
4180
+ if (parent === current)
4181
+ return null;
4182
+ current = parent;
3921
4183
  }
3922
- let pathEnv = process.env["PATH"] ?? "";
3923
- if (isWindows && !pathEnv) {
4184
+ }
4185
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4186
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4187
+ if (platform === "win32" && !pathEnv) {
3924
4188
  pathEnv = process.env["Path"] ?? "";
3925
4189
  }
3926
- const paths = pathEnv.split(delimiter3);
3927
- for (const p of paths) {
3928
- for (const suffix of exts) {
3929
- if (existsSync8(join3(p, cmd + suffix))) {
3930
- return true;
3931
- }
3932
- }
4190
+ for (const entry of pathEnv.split(delimiter3)) {
4191
+ if (entry.length === 0)
4192
+ continue;
4193
+ const found = probeWithSuffixes(entry, command, suffixes);
4194
+ if (found !== null)
4195
+ return found;
3933
4196
  }
3934
- if (cmd === "node")
3935
- return true;
3936
- return false;
4197
+ return null;
4198
+ }
4199
+ function resolveServerBinary(command, workingDirectory, options = {}) {
4200
+ if (command.length === 0)
4201
+ return null;
4202
+ const [cmd] = command;
4203
+ if (cmd === undefined || cmd.length === 0)
4204
+ return null;
4205
+ const platform = options.platform ?? process.platform;
4206
+ const suffixes = executableSuffixes(platform, options.pathExt);
4207
+ if (cmd.includes("/") || cmd.includes("\\")) {
4208
+ const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4209
+ return probe(explicit) ? explicit : null;
4210
+ }
4211
+ const cacheKey = JSON.stringify([
4212
+ workingDirectory ?? "",
4213
+ cmd,
4214
+ platform,
4215
+ options.stopAt ?? "",
4216
+ options.pathExt ?? "",
4217
+ options.pathEnv ?? process.env["PATH"] ?? ""
4218
+ ]);
4219
+ const cached = resolutionCache.get(cacheKey);
4220
+ if (cached !== undefined)
4221
+ return cached;
4222
+ let resolved = null;
4223
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
4224
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4225
+ }
4226
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4227
+ if (resolved === null && cmd === "node")
4228
+ resolved = cmd;
4229
+ resolutionCache.set(cacheKey, resolved);
4230
+ return resolved;
4231
+ }
4232
+ function isServerInstalled(command, workingDirectory, options = {}) {
4233
+ if (command.length === 0)
4234
+ return false;
4235
+ return resolveServerBinary(command, workingDirectory, options) !== null;
3937
4236
  }
3938
4237
 
3939
4238
  // ../lsp-core/src/lsp/server-resolution.ts
4239
+ function withResolvedCommand(command, binaryPath) {
4240
+ return [binaryPath, ...command.slice(1)];
4241
+ }
3940
4242
  function findServerForExtension(ext) {
3941
4243
  const servers = getMergedServers();
3942
- for (const server2 of servers) {
3943
- if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4244
+ const workingDirectory = contextCwd();
4245
+ for (const server of servers) {
4246
+ if (!server.extensions.includes(ext))
4247
+ continue;
4248
+ const binaryPath = resolveServerBinary(server.command, workingDirectory);
4249
+ if (binaryPath !== null) {
3944
4250
  const resolvedServer = {
3945
- id: server2.id,
3946
- command: server2.command,
3947
- extensions: server2.extensions,
3948
- priority: server2.priority
4251
+ id: server.id,
4252
+ command: withResolvedCommand(server.command, binaryPath),
4253
+ extensions: server.extensions,
4254
+ priority: server.priority
3949
4255
  };
3950
- if (server2.env !== undefined) {
4256
+ if (server.env !== undefined) {
3951
4257
  return {
3952
4258
  status: "found",
3953
4259
  server: {
3954
4260
  ...resolvedServer,
3955
- env: server2.env,
3956
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4261
+ env: server.env,
4262
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
3957
4263
  }
3958
4264
  };
3959
4265
  }
@@ -3961,20 +4267,20 @@ function findServerForExtension(ext) {
3961
4267
  status: "found",
3962
4268
  server: {
3963
4269
  ...resolvedServer,
3964
- ...server2.initialization === undefined ? {} : { initialization: server2.initialization }
4270
+ ...server.initialization === undefined ? {} : { initialization: server.initialization }
3965
4271
  }
3966
4272
  };
3967
4273
  }
3968
4274
  }
3969
- for (const server2 of servers) {
3970
- if (server2.extensions.includes(ext)) {
3971
- const installHint = LSP_INSTALL_HINTS[server2.id] ?? `Install '${server2.command[0]}' and ensure it's in your PATH`;
4275
+ for (const server of servers) {
4276
+ if (server.extensions.includes(ext)) {
4277
+ const installHint = LSP_INSTALL_HINTS[server.id] ?? `Install '${server.command[0]}' and ensure it's in your PATH`;
3972
4278
  return {
3973
4279
  status: "not_installed",
3974
4280
  server: {
3975
- id: server2.id,
3976
- command: server2.command,
3977
- extensions: server2.extensions
4281
+ id: server.id,
4282
+ command: server.command,
4283
+ extensions: server.extensions
3978
4284
  },
3979
4285
  installHint
3980
4286
  };
@@ -3990,20 +4296,21 @@ function findServerForExtension(ext) {
3990
4296
  function getAllServers() {
3991
4297
  const servers = getMergedServers();
3992
4298
  const disabled = getDisabledServerIds();
4299
+ const workingDirectory = contextCwd();
3993
4300
  const result = [];
3994
4301
  const seen = new Set;
3995
- for (const server2 of servers) {
3996
- if (seen.has(server2.id))
4302
+ for (const server of servers) {
4303
+ if (seen.has(server.id))
3997
4304
  continue;
3998
4305
  result.push({
3999
- id: server2.id,
4000
- installed: isServerInstalled(server2.command),
4001
- extensions: server2.extensions,
4306
+ id: server.id,
4307
+ installed: isServerInstalled(server.command, workingDirectory),
4308
+ extensions: server.extensions,
4002
4309
  disabled: false,
4003
- source: server2.source,
4004
- priority: server2.priority
4310
+ source: server.source,
4311
+ priority: server.priority
4005
4312
  });
4006
- seen.add(server2.id);
4313
+ seen.add(server.id);
4007
4314
  }
4008
4315
  for (const id of disabled) {
4009
4316
  if (seen.has(id))
@@ -4011,7 +4318,7 @@ function getAllServers() {
4011
4318
  const builtin = BUILTIN_SERVERS[id];
4012
4319
  result.push({
4013
4320
  id,
4014
- installed: builtin ? isServerInstalled(builtin.command) : false,
4321
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4015
4322
  extensions: builtin?.extensions ?? [],
4016
4323
  disabled: true,
4017
4324
  source: "disabled",
@@ -4022,7 +4329,6 @@ function getAllServers() {
4022
4329
  }
4023
4330
 
4024
4331
  // ../lsp-core/src/lsp/client-wrapper.ts
4025
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
4026
4332
  function isDirectoryPath(filePath) {
4027
4333
  try {
4028
4334
  return statSync3(filePath).isDirectory();
@@ -4031,32 +4337,90 @@ function isDirectoryPath(filePath) {
4031
4337
  }
4032
4338
  }
4033
4339
  function findWorkspaceRoot(filePath) {
4034
- const abs = resolvePathInsideContext(filePath);
4340
+ const cwd = contextCwd();
4341
+ const abs = resolveReadablePathInsideContext(filePath);
4035
4342
  let dir = abs;
4036
4343
  if (!isDirectoryPath(dir)) {
4037
- dir = dirname6(dir);
4038
- }
4039
- let prevDir = "";
4040
- while (dir !== prevDir) {
4041
- for (const marker of WORKSPACE_MARKERS) {
4042
- if (existsSync9(join4(dir, marker))) {
4043
- return dir;
4344
+ dir = dirname8(dir);
4345
+ }
4346
+ if (!isPathInside(cwd, abs))
4347
+ return findWorkspaceRootOutsideContext(dir);
4348
+ const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4349
+ let nearestPackageRoot;
4350
+ while (isPathInside(cwd, dir)) {
4351
+ const canonicalDir = existingDirectoryInsideContext(dir, cwd);
4352
+ if (canonicalDir !== undefined) {
4353
+ if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
4354
+ return canonicalDir;
4355
+ }
4356
+ if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
4357
+ nearestPackageRoot = canonicalDir;
4044
4358
  }
4045
4359
  }
4046
- prevDir = dir;
4047
- dir = dirname6(dir);
4360
+ if (dir === cwd)
4361
+ break;
4362
+ dir = dirname8(dir);
4048
4363
  }
4049
- return dirname6(abs);
4364
+ return nearestPackageRoot ?? fallbackRoot;
4365
+ }
4366
+ function hasProjectWorkspaceMarker(directory) {
4367
+ return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
4368
+ }
4369
+ function resolveReadablePathInsideContext(filePath) {
4370
+ const cwd = contextCwd();
4371
+ const abs = resolve8(cwd, filePath);
4372
+ if (isPathInside(cwd, abs))
4373
+ return abs;
4374
+ const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
4375
+ if (rebased !== undefined)
4376
+ return rebased;
4377
+ return canonicalizeExistingOrNearestAncestor(abs);
4050
4378
  }
4051
4379
  function resolvePathInsideContext(filePath) {
4052
4380
  const cwd = contextCwd();
4053
- const abs = resolve7(cwd, filePath);
4381
+ const abs = resolveReadablePathInsideContext(filePath);
4054
4382
  const canonical = canonicalizeExistingOrNearestAncestor(abs);
4055
4383
  if (!isPathInside(cwd, canonical)) {
4056
4384
  throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
4057
4385
  }
4058
4386
  return canonical;
4059
4387
  }
4388
+ function rebaseThroughCanonicalAncestor(path, cwd) {
4389
+ let current = path;
4390
+ const suffix = [];
4391
+ while (true) {
4392
+ if (existsSync10(current)) {
4393
+ const canonical = realpathSync5(current);
4394
+ if (isPathInside(cwd, canonical))
4395
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
4396
+ }
4397
+ const parent = dirname8(current);
4398
+ if (parent === current)
4399
+ return;
4400
+ suffix.unshift(basename3(current));
4401
+ current = parent;
4402
+ }
4403
+ }
4404
+ function existingDirectoryInsideContext(directory, cwd) {
4405
+ if (!existsSync10(directory))
4406
+ return;
4407
+ const canonical = realpathSync5(directory);
4408
+ if (!statSync3(canonical).isDirectory())
4409
+ return;
4410
+ return isPathInside(cwd, canonical) ? canonical : undefined;
4411
+ }
4412
+ function nearestExistingDirectoryInsideContext(directory, cwd) {
4413
+ let current = directory;
4414
+ while (isPathInside(cwd, current)) {
4415
+ const canonical = existingDirectoryInsideContext(current, cwd);
4416
+ if (canonical !== undefined)
4417
+ return canonical;
4418
+ if (current === cwd)
4419
+ return;
4420
+ current = dirname8(current);
4421
+ }
4422
+ return;
4423
+ }
4060
4424
  function formatServerLookupError(result) {
4061
4425
  if (result.status === "not_installed") {
4062
4426
  return formatNotInstalled(result);
@@ -4080,33 +4444,46 @@ function formatServerLookupError(result) {
4080
4444
  ].join(`
4081
4445
  `);
4082
4446
  }
4447
+ function formatInstallOptions(serverId, installHint) {
4448
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
4449
+ if (localHint === undefined) {
4450
+ return ["To install, run:", ` ${installHint}`];
4451
+ }
4452
+ return [
4453
+ "To install in THIS repository (preferred — no global install needed):",
4454
+ ` ${localHint}`,
4455
+ "",
4456
+ "Or install it globally:",
4457
+ ` ${installHint}`
4458
+ ];
4459
+ }
4083
4460
  function formatNotInstalled(result) {
4084
- const { server: server2, installHint } = result;
4085
- const extensions = server2.extensions.join(", ");
4086
- const decision = loadInstallDecision(server2.id)?.decision;
4461
+ const { server, installHint } = result;
4462
+ const extensions = server.extensions.join(", ");
4463
+ const decision = loadInstallDecision(server.id)?.decision;
4087
4464
  const context = lspRequestContext();
4088
4465
  if (decision === "declined") {
4089
- return `LSP server '${server2.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
4466
+ return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
4090
4467
  }
4091
4468
  const header = [
4092
- `LSP server '${server2.id}' for ${extensions} is NOT INSTALLED.`,
4469
+ `LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
4093
4470
  "",
4094
- `Command not found: ${server2.command[0]}`,
4471
+ `Command not found: ${server.command[0]}`,
4095
4472
  ""
4096
4473
  ];
4474
+ const installOptions = formatInstallOptions(server.id, installHint);
4097
4475
  if (decision === "allowed") {
4098
4476
  return [
4099
4477
  ...header,
4100
4478
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4101
- ` ${installHint}`
4479
+ ...installOptions.slice(1)
4102
4480
  ].join(`
4103
4481
  `);
4104
4482
  }
4105
4483
  if (!context.capabilities.installDecisionTool) {
4106
4484
  return [
4107
4485
  ...header,
4108
- "To install, run:",
4109
- ` ${installHint}`,
4486
+ ...installOptions,
4110
4487
  "",
4111
4488
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4112
4489
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4115,19 +4492,18 @@ function formatNotInstalled(result) {
4115
4492
  }
4116
4493
  return [
4117
4494
  ...header,
4118
- "To install, run:",
4119
- ` ${installHint}`,
4495
+ ...installOptions,
4120
4496
  "",
4121
4497
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4122
4498
  "- If the user agrees: run the install command above, then retry this tool.",
4123
4499
  "- If the user declines, OR has NOT explicitly asked for LSP installation:",
4124
- ` call lsp_install_decision { server_id: "${server2.id}", decision: "declined" },`,
4500
+ ` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
4125
4501
  ` which writes to ${context.installDecisionsPath},`,
4126
4502
  " then ignore this message and proceed WITHOUT LSP."
4127
4503
  ].join(`
4128
4504
  `);
4129
4505
  }
4130
- var READ_ONLY_RETRY_TOOLS = new Set([
4506
+ var READ_ONLY_TOOLS = new Set([
4131
4507
  "diagnostics",
4132
4508
  "definition",
4133
4509
  "references",
@@ -4136,7 +4512,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
4136
4512
  "prepareRename"
4137
4513
  ]);
4138
4514
  async function withLspClient(filePath, fn, toolName, options = {}) {
4139
- const absPath = resolvePathInsideContext(filePath);
4515
+ const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
4140
4516
  if (isDirectoryPath(absPath)) {
4141
4517
  throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
4142
4518
  }
@@ -4145,34 +4521,34 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4145
4521
  if (result.status !== "found") {
4146
4522
  throw new LspServerLookupError(formatServerLookupError(result), result);
4147
4523
  }
4148
- const server2 = result.server;
4524
+ const server = result.server;
4149
4525
  const root = findWorkspaceRoot(absPath);
4150
- const manager2 = options.manager ?? getLspManager();
4526
+ const manager = options.manager ?? getLspManager();
4151
4527
  const acquireAndCall = async (allowRetry) => {
4152
- const client = await manager2.getClient(root, server2, options.signal);
4528
+ const client = await manager.getClient(root, server, options.signal);
4153
4529
  try {
4154
- return await fn(client, root);
4530
+ return await fn(client, root, absPath);
4155
4531
  } catch (err) {
4156
- if (allowRetry && READ_ONLY_RETRY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4157
- manager2.invalidateClient(root, server2.id, client);
4532
+ if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4533
+ manager.invalidateClient(root, server.id, client);
4158
4534
  return acquireAndCall(false);
4159
4535
  }
4160
4536
  if (err instanceof LspRequestTimeoutError) {
4161
- if (manager2.isServerInitializing(root, server2.id)) {
4537
+ if (manager.isServerInitializing(root, server.id)) {
4162
4538
  throw new LspServerInitializingError(err);
4163
4539
  }
4164
4540
  }
4165
4541
  throw err;
4166
4542
  } finally {
4167
- manager2.releaseClient(root, server2.id);
4543
+ manager.releaseClient(root, server.id);
4168
4544
  }
4169
4545
  };
4170
4546
  return acquireAndCall(true);
4171
4547
  }
4172
4548
 
4173
4549
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4174
- import { existsSync as existsSync10, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4175
- import { join as join5, resolve as resolve8 } from "node:path";
4550
+ import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4551
+ import { join as join6, resolve as resolve9 } from "node:path";
4176
4552
 
4177
4553
  // ../lsp-core/src/lsp/formatters.ts
4178
4554
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -4187,10 +4563,10 @@ function uriToPath(uri) {
4187
4563
  }
4188
4564
  function formatLocation(loc) {
4189
4565
  if ("targetUri" in loc) {
4190
- const uri2 = uriToPath(loc.targetUri);
4191
- const line2 = loc.targetRange.start.line + 1;
4192
- const char2 = loc.targetRange.start.character;
4193
- return `${uri2}:${line2}:${char2}`;
4566
+ const uri = uriToPath(loc.targetUri);
4567
+ const line = loc.targetRange.start.line + 1;
4568
+ const char = loc.targetRange.start.character;
4569
+ return `${uri}:${line}:${char}`;
4194
4570
  }
4195
4571
  const uri = uriToPath(loc.uri);
4196
4572
  const line = loc.range.start.line + 1;
@@ -4302,7 +4678,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
4302
4678
  for (const entry of entries) {
4303
4679
  if (files.length >= maxFiles)
4304
4680
  return;
4305
- const fullPath = join5(currentDir, entry);
4681
+ const fullPath = join6(currentDir, entry);
4306
4682
  let stat;
4307
4683
  try {
4308
4684
  stat = lstatSync4(fullPath);
@@ -4327,15 +4703,15 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4327
4703
  if (!extension.startsWith(".")) {
4328
4704
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4329
4705
  }
4330
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4331
- if (!existsSync10(absDir)) {
4706
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
4707
+ if (!existsSync11(absDir)) {
4332
4708
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4333
4709
  }
4334
4710
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
4335
4711
  if (serverResult.status !== "found") {
4336
4712
  throw new LspServerLookupError(formatServerLookupError(serverResult));
4337
4713
  }
4338
- const server2 = serverResult.server;
4714
+ const server = serverResult.server;
4339
4715
  const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
4340
4716
  const wasCapped = allFiles.length > maxFiles;
4341
4717
  const filesToProcess = allFiles.slice(0, maxFiles);
@@ -4350,12 +4726,12 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4350
4726
  return { output, totalDiagnostics: 0, fileFailures: [] };
4351
4727
  }
4352
4728
  const root = options.workspaceRoot ?? findWorkspaceRoot(absDir);
4353
- const manager2 = options.manager ?? getLspManager();
4729
+ const manager = options.manager ?? getLspManager();
4354
4730
  const allDiagnostics = [];
4355
4731
  const fileErrors = [];
4356
4732
  const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
4357
4733
  options.signal?.throwIfAborted();
4358
- const client = await manager2.getClient(root, server2, options.signal);
4734
+ const client = await manager.getClient(root, server, options.signal);
4359
4735
  try {
4360
4736
  let nextIndex = 0;
4361
4737
  const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
@@ -4383,7 +4759,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4383
4759
  });
4384
4760
  await Promise.all(workers);
4385
4761
  } finally {
4386
- manager2.releaseClient(root, server2.id);
4762
+ manager.releaseClient(root, server.id);
4387
4763
  }
4388
4764
  const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
4389
4765
  const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
@@ -4415,7 +4791,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4415
4791
 
4416
4792
  // ../lsp-core/src/lsp/infer-extension.ts
4417
4793
  import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
4418
- import { join as join6 } from "node:path";
4794
+ import { join as join7 } from "node:path";
4419
4795
  var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
4420
4796
  var MAX_SCAN_ENTRIES = 500;
4421
4797
  function inferExtensionFromDirectory(directory) {
@@ -4433,7 +4809,7 @@ function inferExtensionFromDirectory(directory) {
4433
4809
  for (const entry of entries) {
4434
4810
  if (scanned >= MAX_SCAN_ENTRIES)
4435
4811
  return;
4436
- const fullPath = join6(dir, entry);
4812
+ const fullPath = join7(dir, entry);
4437
4813
  let stat;
4438
4814
  try {
4439
4815
  stat = lstatSync5(fullPath);
@@ -4592,8 +4968,8 @@ function clientOptions(signal) {
4592
4968
  }
4593
4969
 
4594
4970
  // ../lsp-core/src/tools/result.ts
4595
- function text(text2, details, isError = false) {
4596
- return { content: [{ type: "text", text: text2 }], details, isError };
4971
+ function text(text, details, isError = false) {
4972
+ return { content: [{ type: "text", text }], details, isError };
4597
4973
  }
4598
4974
 
4599
4975
  // ../lsp-core/src/tools/diagnostics.ts
@@ -4608,12 +4984,12 @@ async function executeLspDiagnostics(params, signal) {
4608
4984
  const filePath = requireString(params, "filePath");
4609
4985
  const severity = severityFilter(params);
4610
4986
  try {
4611
- const absPath = resolvePathInsideContext(filePath);
4987
+ const absPath = resolveReadablePathInsideContext(filePath);
4612
4988
  if (isDirectoryPath(absPath)) {
4613
4989
  const extension = inferExtensionFromDirectory(absPath);
4614
4990
  if (!extension) {
4615
4991
  const message = `No supported source files found in directory: ${absPath}`;
4616
- const details3 = {
4992
+ const details = {
4617
4993
  filePath,
4618
4994
  severity,
4619
4995
  mode: "directory",
@@ -4623,24 +4999,24 @@ async function executeLspDiagnostics(params, signal) {
4623
4999
  error: message,
4624
5000
  errorKind: "no_files"
4625
5001
  };
4626
- return text(message, details3);
5002
+ return text(message, details);
4627
5003
  }
4628
- const output2 = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
4629
- const details2 = {
5004
+ const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
5005
+ const details = {
4630
5006
  filePath,
4631
5007
  severity,
4632
5008
  mode: "directory",
4633
5009
  diagnostics: [],
4634
- totalDiagnostics: output2.totalDiagnostics,
5010
+ totalDiagnostics: output.totalDiagnostics,
4635
5011
  truncated: false,
4636
- fileFailures: [...output2.fileFailures]
5012
+ fileFailures: [...output.fileFailures]
4637
5013
  };
4638
- return text(output2.output, details2);
5014
+ return text(output.output, details);
4639
5015
  }
4640
- const result = await withLspClient(filePath, async (client) => client.diagnostics(filePath, signal), "diagnostics", clientOptions(signal));
5016
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
4641
5017
  if (result.transientError) {
4642
5018
  const message = result.transientError.message;
4643
- const details2 = {
5019
+ const details = {
4644
5020
  filePath,
4645
5021
  severity,
4646
5022
  mode: "file",
@@ -4650,7 +5026,7 @@ async function executeLspDiagnostics(params, signal) {
4650
5026
  error: message,
4651
5027
  errorKind: result.transientError.kind
4652
5028
  };
4653
- return text(message, details2, true);
5029
+ return text(message, details, true);
4654
5030
  }
4655
5031
  const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
4656
5032
  const total = diagnostics.length;
@@ -4684,6 +5060,96 @@ async function executeLspDiagnostics(params, signal) {
4684
5060
  throw error;
4685
5061
  }
4686
5062
  }
5063
+ // ../lsp-core/src/lsp/format-document.ts
5064
+ import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
5065
+ var DEFAULT_FORMATTING_OPTIONS = {
5066
+ tabSize: 4,
5067
+ insertSpaces: false,
5068
+ trimTrailingWhitespace: true,
5069
+ insertFinalNewline: true,
5070
+ trimFinalNewlines: true
5071
+ };
5072
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
5073
+ async function formatDocumentWithClient(client, filePath, options = {}) {
5074
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
5075
+ if (edits === null)
5076
+ return { status: "unavailable", reason: "capability_not_advertised" };
5077
+ if (edits.length === 0)
5078
+ return UNCHANGED;
5079
+ const before = readFileSync5(filePath, "utf-8");
5080
+ const normalized = normalizeTextEdits(before, edits, 0);
5081
+ if (normalized.text === before)
5082
+ return UNCHANGED;
5083
+ writeAtomically(filePath, normalized.text);
5084
+ await client.openFile(filePath);
5085
+ return {
5086
+ status: "formatted",
5087
+ ...lineDelta(normalized.edits)
5088
+ };
5089
+ }
5090
+ function lineDelta(edits) {
5091
+ let linesAdded = 0;
5092
+ let linesRemoved = 0;
5093
+ for (const edit of edits) {
5094
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
5095
+ linesAdded += edit.newText.split(`
5096
+ `).length;
5097
+ }
5098
+ return { linesAdded, linesRemoved };
5099
+ }
5100
+ function writeAtomically(filePath, content) {
5101
+ const tempPath = `${filePath}.omo-format.tmp`;
5102
+ writeFileSync3(tempPath, content, "utf-8");
5103
+ try {
5104
+ renameSync3(tempPath, filePath);
5105
+ } catch (error) {
5106
+ try {
5107
+ unlinkSync(tempPath);
5108
+ } catch {}
5109
+ throw error;
5110
+ }
5111
+ }
5112
+
5113
+ // ../lsp-core/src/tools/format.ts
5114
+ async function executeLspFormat(params, signal) {
5115
+ const filePath = requireString(params, "filePath");
5116
+ try {
5117
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
5118
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
5119
+ } catch (error) {
5120
+ const missingDependency = missingDependencyResult(error, {
5121
+ filePath,
5122
+ status: "unavailable",
5123
+ reason: "server_unavailable",
5124
+ linesAdded: 0,
5125
+ linesRemoved: 0
5126
+ });
5127
+ if (missingDependency)
5128
+ return missingDependency;
5129
+ throw error;
5130
+ }
5131
+ }
5132
+ function formatDetails(filePath, result) {
5133
+ if (result.status === "unavailable") {
5134
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5135
+ }
5136
+ return {
5137
+ filePath,
5138
+ status: result.status,
5139
+ linesAdded: result.linesAdded,
5140
+ linesRemoved: result.linesRemoved
5141
+ };
5142
+ }
5143
+ function describeResult(filePath, result) {
5144
+ if (result.status === "unavailable") {
5145
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5146
+ }
5147
+ if (result.status === "unchanged") {
5148
+ return `Already formatted: ${filePath}`;
5149
+ }
5150
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5151
+ }
5152
+
4687
5153
  // ../lsp-core/src/tools/install-decision.ts
4688
5154
  async function executeLspInstallDecision(params) {
4689
5155
  const serverId = requireString(params, "server_id");
@@ -4691,7 +5157,7 @@ async function executeLspInstallDecision(params) {
4691
5157
  if (!isInstallDecision(decision)) {
4692
5158
  return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
4693
5159
  }
4694
- const serverIds = [...new Set(getMergedServers().map((server2) => server2.id))];
5160
+ const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
4695
5161
  if (!serverIds.includes(serverId)) {
4696
5162
  const preview = serverIds.slice(0, 20).join(", ");
4697
5163
  return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
@@ -4712,7 +5178,7 @@ async function executeLspGotoDefinition(params, signal) {
4712
5178
  const line = requireNumber(params, "line");
4713
5179
  const character = requireNumber(params, "character");
4714
5180
  try {
4715
- const result = await withLspClient(filePath, async (client) => client.definition(filePath, line, character, signal), "definition", clientOptions(signal));
5181
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
4716
5182
  const locations = !result ? [] : Array.isArray(result) ? result : [result];
4717
5183
  const details = { filePath, line, character, locations };
4718
5184
  if (locations.length === 0)
@@ -4737,7 +5203,7 @@ async function executeLspFindReferences(params, signal) {
4737
5203
  const character = requireNumber(params, "character");
4738
5204
  const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
4739
5205
  try {
4740
- const result = await withLspClient(filePath, async (client) => client.references(filePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
5206
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
4741
5207
  const references = Array.isArray(result) ? result : [];
4742
5208
  const total = references.length;
4743
5209
  const truncated = total > DEFAULT_MAX_REFERENCES;
@@ -4779,7 +5245,7 @@ async function executeLspPrepareRename(params, signal) {
4779
5245
  const line = requireNumber(params, "line");
4780
5246
  const character = requireNumber(params, "character");
4781
5247
  try {
4782
- const result = await withLspClient(filePath, async (client) => client.prepareRename(filePath, line, character, signal), "prepareRename", clientOptions(signal));
5248
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
4783
5249
  const details = { filePath, line, character, result };
4784
5250
  return text(formatPrepareRenameResult(result), details);
4785
5251
  } catch (error) {
@@ -4800,7 +5266,7 @@ async function executeLspRename(params, signal) {
4800
5266
  const character = requireNumber(params, "character");
4801
5267
  const newName = requireString(params, "newName");
4802
5268
  try {
4803
- const result = await withLspClient(filePath, async (client) => client.rename(filePath, line, character, newName, signal), "rename", clientOptions(signal));
5269
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
4804
5270
  const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
4805
5271
  return text(formatApplyResult(result.apply), details, !result.apply.success);
4806
5272
  } catch (error) {
@@ -4831,10 +5297,10 @@ function objectSchema(properties, required = []) {
4831
5297
  async function executeLspStatus() {
4832
5298
  const servers = getAllServers();
4833
5299
  const snapshots = getLspManager().getSnapshot();
4834
- const installed = servers.filter((server2) => server2.installed && !server2.disabled);
4835
- const configuredLines = servers.map((server2) => {
4836
- const state = server2.disabled ? "disabled" : server2.installed ? "installed" : "missing";
4837
- return `- ${server2.id}: ${state}; source=${server2.source}; extensions=${server2.extensions.join(", ")}`;
5300
+ const installed = servers.filter((server) => server.installed && !server.disabled);
5301
+ const configuredLines = servers.map((server) => {
5302
+ const state = server.disabled ? "disabled" : server.installed ? "installed" : "missing";
5303
+ return `- ${server.id}: ${state}; source=${server.source}; extensions=${server.extensions.join(", ")}`;
4838
5304
  });
4839
5305
  const activeLines = snapshots.map((snapshot) => {
4840
5306
  const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
@@ -4877,10 +5343,10 @@ async function executeLspSymbols(params, signal) {
4877
5343
  errorKind: "missing_query"
4878
5344
  });
4879
5345
  }
4880
- const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
4881
- return formatSymbolsResult(filePath, scope, symbols2, limit, query);
5346
+ const symbols = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
5347
+ return formatSymbolsResult(filePath, scope, symbols, limit, query);
4882
5348
  }
4883
- const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(filePath, signal), "documentSymbols", clientOptions(signal));
5349
+ const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
4884
5350
  return formatSymbolsResult(filePath, scope, symbols, limit);
4885
5351
  } catch (error) {
4886
5352
  const query = optionalString(params, "query");
@@ -5016,6 +5482,16 @@ var LSP_MCP_TOOLS = [
5016
5482
  }, ["filePath", "line", "character", "newName"]),
5017
5483
  execute: executeLspRename
5018
5484
  },
5485
+ {
5486
+ name: "format",
5487
+ aliases: ["lsp_format"],
5488
+ title: "LSP Format",
5489
+ description: "Format a source file with its language server and write the returned edits to disk.",
5490
+ inputSchema: objectSchema({
5491
+ filePath: { type: "string", description: "Source file path to format." }
5492
+ }, ["filePath"]),
5493
+ execute: executeLspFormat
5494
+ },
5019
5495
  {
5020
5496
  name: "install_decision",
5021
5497
  aliases: ["lsp_install_decision"],
@@ -5123,7 +5599,6 @@ function requestedProtocolVersion(params) {
5123
5599
  return params["protocolVersion"];
5124
5600
  }
5125
5601
  // src/cli.ts
5126
- import { argv, stderr } from "node:process";
5127
5602
  async function main() {
5128
5603
  const [command = "mcp"] = argv.slice(2);
5129
5604
  try {