oh-my-opencode 5.0.0-beta.4 → 5.0.0-beta.42

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 (892) 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 +25 -21
  15. package/README.ko.md +25 -21
  16. package/README.md +38 -23
  17. package/README.ru.md +24 -20
  18. package/README.zh-cn.md +25 -21
  19. package/THIRD-PARTY-NOTICES.md +27 -99
  20. package/dist/agents/atlas/agent.d.ts +0 -1
  21. package/dist/agents/sisyphus/grok-4.d.ts +20 -0
  22. package/dist/agents/sisyphus/index.d.ts +2 -0
  23. package/dist/agents/sisyphus-agent-config.d.ts +6 -0
  24. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  25. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
  26. package/dist/agents/types.d.ts +2 -2
  27. package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
  28. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  29. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  30. package/dist/cli/index.js +67006 -64814
  31. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  32. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  33. package/dist/cli/runtime-commands.d.ts +1 -1
  34. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  35. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  36. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  37. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  38. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  39. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  40. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  41. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  42. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  43. package/dist/cli-node/index.js +67283 -65068
  44. package/dist/config/index.d.ts +1 -1
  45. package/dist/config/schema/background-task.d.ts +1 -0
  46. package/dist/config/schema/commands.d.ts +1 -1
  47. package/dist/config/schema/hooks.d.ts +1 -2
  48. package/dist/config/schema/oh-my-opencode-config.d.ts +5 -11
  49. package/dist/config/schema/ulw-execute.d.ts +5 -0
  50. package/dist/config/schema.d.ts +0 -1
  51. package/dist/config/validate.d.ts +2 -0
  52. package/dist/create-hooks.d.ts +3 -2
  53. package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +1 -0
  54. package/dist/features/background-agent/constants.d.ts +0 -7
  55. package/dist/features/background-agent/manager.d.ts +2 -1
  56. package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
  57. package/dist/features/background-agent/parent-wake-notifier-types.d.ts +1 -1
  58. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -1
  59. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -1
  60. package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
  61. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  62. package/dist/features/btw-side/context-injector.d.ts +15 -0
  63. package/dist/features/btw-side/index.d.ts +8 -0
  64. package/dist/features/btw-side/metadata.d.ts +15 -0
  65. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  66. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  67. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  68. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  69. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  70. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  71. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  72. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  73. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  74. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  75. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  76. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  77. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  78. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  79. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  80. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  81. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  82. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  83. package/dist/features/builtin-commands/types.d.ts +1 -1
  84. package/dist/features/monitor/manager-internals.d.ts +1 -1
  85. package/dist/features/monitor/output-injector-types.d.ts +1 -1
  86. package/dist/features/opengateway-provider/index.d.ts +13 -0
  87. package/dist/features/task-toast-manager/manager.d.ts +0 -24
  88. package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +15 -0
  89. package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +1 -0
  90. package/dist/features/team-mode/tools/messaging-runtime.d.ts +1 -0
  91. package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
  92. package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
  93. package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
  94. package/dist/hooks/anthropic-context-window-limit-recovery/tool-result-storage.d.ts +11 -0
  95. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  96. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  97. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  98. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  99. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  100. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  101. package/dist/hooks/atlas/types.d.ts +1 -0
  102. package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
  103. package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
  104. package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
  105. package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
  106. package/dist/hooks/compaction-context-injector/validated-model.d.ts +2 -0
  107. package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
  108. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
  109. package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
  110. package/dist/hooks/index.d.ts +1 -2
  111. package/dist/hooks/keyword-detector/hook.d.ts +7 -0
  112. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
  113. package/dist/hooks/model-fallback/hook.d.ts +1 -1
  114. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  115. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  116. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  117. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  118. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  119. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  120. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  121. package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
  122. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  123. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  124. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  125. package/dist/index.js +24677 -20710
  126. package/dist/mcp/index.d.ts +0 -4
  127. package/dist/mcp/types.d.ts +0 -1
  128. package/dist/oh-my-opencode.schema.json +21 -47
  129. package/dist/plugin/chat-message/types.d.ts +3 -3
  130. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  131. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  132. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -2
  133. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -3
  134. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  135. package/dist/plugin/messages-transform.d.ts +1 -0
  136. package/dist/plugin-dispose.d.ts +3 -0
  137. package/dist/shared/agent-tool-restrictions.d.ts +0 -1
  138. package/dist/shared/compaction-agent-config-checkpoint.d.ts +1 -0
  139. package/dist/shared/index.d.ts +2 -0
  140. package/dist/shared/legacy-plugin-warning.d.ts +2 -1
  141. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  142. package/dist/shared/omo-process-sweep.d.ts +2 -4
  143. package/dist/shared/plugin-entry-migrator.d.ts +4 -3
  144. package/dist/shared/plugin-entry-shape.d.ts +6 -0
  145. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  146. package/dist/shared/shell-env.d.ts +1 -1
  147. package/dist/skills/ast-grep/AGENTS.md +51 -0
  148. package/dist/skills/ast-grep/SKILL.md +1 -1
  149. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  150. package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
  151. package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  152. package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
  153. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  154. package/dist/skills/data-scientist/SKILL.md +99 -239
  155. package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
  156. package/dist/skills/data-scientist/references/placement.md +74 -0
  157. package/dist/skills/data-scientist/references/polars-lane.md +95 -0
  158. package/dist/skills/data-scientist/references/uv-setup.md +1 -1
  159. package/dist/skills/data-scientist/references/visualization.md +64 -0
  160. package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  161. package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  162. package/dist/skills/debugging/SKILL.md +3 -1
  163. package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
  164. package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
  165. package/dist/skills/debugging/references/runtimes/go.md +15 -1
  166. package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
  167. package/dist/skills/debugging/references/runtimes/node.md +25 -0
  168. package/dist/skills/debugging/references/runtimes/python.md +13 -0
  169. package/dist/skills/debugging/references/runtimes/rust.md +41 -0
  170. package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
  171. package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
  172. package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  173. package/dist/skills/debugging/references/tools/dap.md +103 -0
  174. package/dist/skills/debugging/references/tools/frida.md +193 -0
  175. package/dist/skills/frontend/SKILL.md +12 -8
  176. package/dist/skills/frontend/references/design/_INDEX.md +1 -0
  177. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  178. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  179. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  180. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  181. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  182. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  183. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  184. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  185. package/dist/skills/git-master/SKILL.md +1 -1
  186. package/dist/skills/init-deep/SKILL.md +14 -14
  187. package/dist/skills/lsp-setup/SKILL.md +1 -1
  188. package/dist/skills/programming/SKILL.md +1 -1
  189. package/dist/skills/refactor/SKILL.md +1 -1
  190. package/dist/skills/remove-ai-slops/SKILL.md +1 -1
  191. package/dist/skills/review-work/SKILL.md +100 -418
  192. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  193. package/dist/skills/ultimate-browsing/SKILL.md +26 -9
  194. package/dist/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  195. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  196. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  197. package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  198. package/dist/skills/{start-work → ulw-execute}/SKILL.md +17 -16
  199. package/dist/skills/ulw-plan/SKILL.md +7 -8
  200. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  201. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  202. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  203. package/dist/skills/ulw-research/SKILL.md +8 -3
  204. package/dist/skills/visual-qa/AGENTS.md +58 -0
  205. package/dist/skills/visual-qa/SKILL.md +4 -3
  206. package/dist/tools/delegate-task/builtin-categories.d.ts +1 -0
  207. package/dist/tools/delegate-task/builtin-category-definition.d.ts +1 -0
  208. package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
  209. package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
  210. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  211. package/dist/tools/delegate-task/types.d.ts +4 -0
  212. package/dist/tools/session-manager/directory-filter.d.ts +2 -0
  213. package/dist/tui.d.ts +12 -0
  214. package/dist/tui.js +49320 -49316
  215. package/package.json +44 -39
  216. package/packages/git-bash-mcp/dist/cli.js +6 -1
  217. package/packages/git-bash-mcp/package.json +1 -1
  218. package/packages/lsp-core/src/index.ts +1 -0
  219. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  220. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +47 -47
  221. package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
  222. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  223. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +163 -13
  224. package/packages/lsp-core/src/lsp/client-wrapper.ts +110 -23
  225. package/packages/lsp-core/src/lsp/client.ts +32 -3
  226. package/packages/lsp-core/src/lsp/connection.ts +16 -0
  227. package/packages/lsp-core/src/lsp/constants.ts +6 -0
  228. package/packages/lsp-core/src/lsp/controlled-clock-test-support.ts +61 -0
  229. package/packages/lsp-core/src/lsp/errors.ts +15 -0
  230. package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +10 -3
  231. package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
  232. package/packages/lsp-core/src/lsp/format-document.ts +90 -0
  233. package/packages/lsp-core/src/lsp/json-rpc-connection.ts +11 -6
  234. package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
  235. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
  236. package/packages/lsp-core/src/lsp/manager.ts +138 -12
  237. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  238. package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
  239. package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
  240. package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
  241. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
  242. package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
  243. package/packages/lsp-core/src/lsp/timer-provider.ts +13 -0
  244. package/packages/lsp-core/src/lsp/transport-request-timeout.test.ts +73 -0
  245. package/packages/lsp-core/src/lsp/transport.ts +16 -2
  246. package/packages/lsp-core/src/lsp/types.ts +8 -0
  247. package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +84 -1
  248. package/packages/lsp-core/src/lsp/workspace-document-state.ts +30 -11
  249. package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
  250. package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
  251. package/packages/lsp-core/src/mcp.ts +3 -0
  252. package/packages/lsp-core/src/request-context.test.ts +29 -0
  253. package/packages/lsp-core/src/request-context.ts +1 -1
  254. package/packages/lsp-core/src/tool-surface.test.ts +13 -1
  255. package/packages/lsp-core/src/tools/definitions.ts +14 -0
  256. package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
  257. package/packages/lsp-core/src/tools/format.test.ts +56 -0
  258. package/packages/lsp-core/src/tools/format.ts +56 -0
  259. package/packages/lsp-core/src/tools/index.ts +1 -0
  260. package/packages/lsp-core/src/tools/navigation.ts +4 -2
  261. package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
  262. package/packages/lsp-core/src/tools/rename.ts +4 -2
  263. package/packages/lsp-core/src/tools/symbols.ts +1 -1
  264. package/packages/lsp-core/src/tools/types.ts +10 -0
  265. package/packages/lsp-daemon/dist/cli.js +804 -329
  266. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  267. package/packages/lsp-daemon/dist/client.js +764 -286
  268. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  269. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  270. package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
  271. package/packages/lsp-daemon/dist/index.js +768 -295
  272. package/packages/lsp-daemon/dist/proxy.js +3 -0
  273. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  274. package/packages/lsp-daemon/package.json +1 -1
  275. package/packages/lsp-tools-mcp/dist/cli.js +723 -250
  276. package/packages/lsp-tools-mcp/dist/lsp/manager.js +259 -125
  277. package/packages/lsp-tools-mcp/dist/mcp.js +725 -252
  278. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  279. package/packages/lsp-tools-mcp/dist/tools.js +729 -260
  280. package/packages/lsp-tools-mcp/package.json +1 -1
  281. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -21
  282. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -6
  283. package/packages/omo-codex/plugin/.mcp.json +0 -6
  284. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  285. package/packages/omo-codex/plugin/README.md +2 -2
  286. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +45 -49
  287. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  288. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  289. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  290. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  291. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  292. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  293. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  294. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  295. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  296. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  297. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  298. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  299. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  300. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  301. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  302. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  303. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
  304. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
  305. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  306. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  307. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
  308. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
  309. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +1 -1
  310. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  311. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  312. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  313. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +752 -300
  314. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  315. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  316. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  317. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  318. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  319. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  320. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  321. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  322. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  323. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  324. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  325. package/packages/omo-codex/plugin/components/rules/dist/cli.js +60 -45
  326. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  327. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  328. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  329. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  330. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +9 -5
  331. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  332. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  333. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  334. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  335. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  336. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  337. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  338. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  339. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  340. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  341. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  342. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  343. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  344. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
  345. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  346. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  347. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  348. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  349. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +5 -6
  350. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  351. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  352. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  353. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  354. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  355. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  356. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +4 -10
  357. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  358. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  359. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2463 -437
  360. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2467 -441
  361. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  362. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  363. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  364. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  365. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  366. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  367. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -4
  368. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  369. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +489 -4
  370. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  371. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -6
  372. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
  373. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -7
  374. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  375. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  376. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  377. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
  378. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
  379. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  380. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  381. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
  382. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
  383. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  384. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +2 -2
  385. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  386. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +5 -5
  387. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  388. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +6 -6
  389. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
  390. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
  391. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  392. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  393. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  394. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
  395. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  396. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  397. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  398. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
  399. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
  400. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +19 -0
  401. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  402. package/packages/omo-codex/plugin/components/ulw-loop/README.md +12 -1
  403. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  404. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +15 -3
  405. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +12 -0
  406. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +45 -0
  407. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +9 -0
  408. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +15 -0
  409. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +15 -1
  410. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +8 -0
  411. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +120 -0
  412. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +40 -39
  413. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +7 -2
  414. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  415. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +12 -1
  416. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +2 -0
  417. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +958 -342
  418. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  419. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +27 -6
  420. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +13 -0
  421. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +15 -1
  422. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
  423. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
  424. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +17 -2
  425. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +13 -0
  426. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +19 -0
  427. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +7 -0
  428. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +9 -0
  429. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +12 -0
  430. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +104 -0
  431. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  432. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +65 -9
  433. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  434. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  435. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +69 -111
  436. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +4 -2
  437. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +185 -14
  438. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +6 -0
  439. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +33 -0
  440. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
  441. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +18 -0
  442. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +65 -0
  443. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  444. package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
  445. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +4 -3
  446. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  447. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +22 -1
  448. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +81 -0
  449. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +7 -0
  450. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +31 -1
  451. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +134 -0
  452. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +38 -71
  453. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +7 -2
  454. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +14 -1
  455. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +2 -0
  456. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +3 -5
  457. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +34 -5
  458. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +26 -1
  459. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  460. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
  461. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
  462. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +18 -3
  463. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +27 -0
  464. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +11 -0
  465. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +123 -0
  466. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +68 -15
  467. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  468. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +82 -131
  469. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +4 -2
  470. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +187 -12
  471. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
  472. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
  473. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +95 -0
  474. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  475. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +133 -1
  476. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +137 -0
  477. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
  478. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +26 -2
  479. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +183 -0
  480. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +37 -2
  481. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  482. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  483. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
  484. package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +105 -0
  485. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  486. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  487. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  488. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  489. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  490. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +46 -2
  491. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
  492. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  493. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +48 -3
  494. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +318 -1
  495. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  496. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  497. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  498. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +13 -8
  499. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  500. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  501. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  502. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  503. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  504. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  505. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  506. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  507. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  508. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  509. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  510. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  511. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  512. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  513. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  514. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  515. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  516. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +17 -0
  517. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  518. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  519. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  520. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  521. package/packages/omo-codex/plugin/model-catalog.json +3 -3
  522. package/packages/omo-codex/plugin/package-lock.json +676 -524
  523. package/packages/omo-codex/plugin/package.json +2 -3
  524. package/packages/omo-codex/plugin/scripts/AGENTS.md +39 -0
  525. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -2
  526. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  527. package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
  528. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  529. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
  530. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +42 -31
  531. package/packages/omo-codex/plugin/shared/package.json +3 -4
  532. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  533. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  534. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  535. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  536. package/packages/omo-codex/plugin/skills/ast-grep/SKILL.md +1 -1
  537. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  538. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
  539. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  540. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
  541. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  542. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  543. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  544. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  545. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  546. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  547. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  548. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  549. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  550. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +3 -1
  551. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  552. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  553. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  554. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  555. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  556. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  557. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  558. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  559. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  560. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  561. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  562. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +12 -8
  563. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  564. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  565. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  566. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  567. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  568. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  569. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  570. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  571. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  572. package/packages/omo-codex/plugin/skills/git-master/SKILL.md +1 -1
  573. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +14 -14
  574. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
  575. package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +1 -1
  576. package/packages/omo-codex/plugin/skills/programming/SKILL.md +1 -1
  577. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +1 -1
  578. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +1 -1
  579. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +101 -419
  580. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  581. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +26 -9
  582. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  583. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  584. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  585. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  586. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +15 -3
  587. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +19 -26
  588. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  589. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +4 -3
  590. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  591. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +22 -1
  592. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -7
  593. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  594. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  595. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  596. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +8 -3
  597. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  598. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +4 -3
  599. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  600. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  601. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +9 -48
  602. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -3
  603. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  604. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
  605. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  606. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  607. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  608. package/packages/omo-codex/plugin/test/auto-update.test.mjs +2 -27
  609. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  610. package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
  611. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  612. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -51
  613. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  614. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -5
  615. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  616. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  617. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
  618. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  619. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
  620. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +24 -14
  621. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +14 -119
  622. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  623. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  624. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  625. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  626. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  627. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -5
  628. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  629. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  630. package/packages/omo-codex/scripts/install-cache-copy.test.mjs +27 -1
  631. package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +1 -1
  632. package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +2 -1
  633. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
  634. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +2 -2
  635. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2818 -913
  636. package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
  637. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  638. package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
  639. package/packages/shared-skills/package.json +7 -1
  640. package/packages/shared-skills/skill-source-filter.d.ts +16 -0
  641. package/packages/shared-skills/skill-source-filter.mjs +44 -0
  642. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  643. package/packages/shared-skills/skills/ast-grep/SKILL.md +1 -1
  644. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  645. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
  646. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  647. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
  648. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  649. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  650. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  651. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  652. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  653. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  654. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  655. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  656. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  657. package/packages/shared-skills/skills/debugging/SKILL.md +3 -1
  658. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  659. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  660. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  661. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  662. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  663. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  664. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  665. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  666. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  667. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  668. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  669. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  670. package/packages/shared-skills/skills/frontend/SKILL.md +12 -8
  671. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  672. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  673. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  674. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  675. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  676. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  677. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  678. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  679. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  680. package/packages/shared-skills/skills/git-master/SKILL.md +1 -1
  681. package/packages/shared-skills/skills/init-deep/SKILL.md +14 -14
  682. package/packages/shared-skills/skills/lsp-setup/SKILL.md +1 -1
  683. package/packages/shared-skills/skills/programming/SKILL.md +1 -1
  684. package/packages/shared-skills/skills/refactor/SKILL.md +1 -1
  685. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
  686. package/packages/shared-skills/skills/review-work/SKILL.md +100 -418
  687. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  688. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +26 -9
  689. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  690. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  691. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  692. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  693. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +17 -16
  694. package/packages/shared-skills/skills/ulw-plan/SKILL.md +7 -8
  695. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  696. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  697. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  698. package/packages/shared-skills/skills/ulw-research/SKILL.md +8 -3
  699. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  700. package/packages/shared-skills/skills/visual-qa/SKILL.md +4 -3
  701. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  702. package/script/qa/xterm-live-terminal.mjs +18 -2
  703. package/dist/config/schema/codegraph.d.ts +0 -12
  704. package/dist/config/schema/start-work.d.ts +0 -5
  705. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  706. package/dist/features/builtin-skills/index.d.ts +0 -1
  707. package/dist/features/builtin-skills/skill-file-loader.d.ts +0 -1
  708. package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +0 -1
  709. package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +0 -1
  710. package/dist/features/builtin-skills/skills/debugging.d.ts +0 -1
  711. package/dist/features/builtin-skills/skills/dev-browser.d.ts +0 -1
  712. package/dist/features/builtin-skills/skills/frontend.d.ts +0 -1
  713. package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +0 -1
  714. package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +0 -1
  715. package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +0 -1
  716. package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +0 -1
  717. package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +0 -1
  718. package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +0 -1
  719. package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +0 -1
  720. package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +0 -1
  721. package/dist/features/builtin-skills/skills/git-master-skill-metadata.d.ts +0 -1
  722. package/dist/features/builtin-skills/skills/git-master.d.ts +0 -1
  723. package/dist/features/builtin-skills/skills/index.d.ts +0 -1
  724. package/dist/features/builtin-skills/skills/init-deep.d.ts +0 -1
  725. package/dist/features/builtin-skills/skills/playwright-cli.d.ts +0 -1
  726. package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +0 -1
  727. package/dist/features/builtin-skills/skills/playwright.d.ts +0 -1
  728. package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +0 -1
  729. package/dist/features/builtin-skills/skills/review-work.d.ts +0 -1
  730. package/dist/features/builtin-skills/skills/security-research.d.ts +0 -1
  731. package/dist/features/builtin-skills/skills/security-review.d.ts +0 -1
  732. package/dist/features/builtin-skills/skills/team-mode.d.ts +0 -1
  733. package/dist/features/builtin-skills/skills/visual-qa.d.ts +0 -1
  734. package/dist/features/builtin-skills/skills.d.ts +0 -1
  735. package/dist/features/builtin-skills/types.d.ts +0 -1
  736. package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +0 -1
  737. package/dist/features/claude-code-plugin-loader/command-loader.d.ts +0 -1
  738. package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +0 -1
  739. package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +0 -1
  740. package/dist/features/claude-code-plugin-loader/discovery.d.ts +0 -1
  741. package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +0 -1
  742. package/dist/features/claude-code-plugin-loader/index.d.ts +0 -1
  743. package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +0 -1
  744. package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +0 -1
  745. package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +0 -1
  746. package/dist/features/claude-code-plugin-loader/loader.d.ts +0 -1
  747. package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +0 -1
  748. package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +0 -1
  749. package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +0 -1
  750. package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +0 -1
  751. package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +0 -1
  752. package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +0 -1
  753. package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +0 -1
  754. package/dist/features/claude-code-plugin-loader/types.d.ts +0 -1
  755. package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +0 -17
  756. package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
  757. package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
  758. package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
  759. package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
  760. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
  761. package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
  762. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  763. package/dist/mcp/codegraph.d.ts +0 -16
  764. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  765. package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +0 -1
  766. package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +0 -1
  767. package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +0 -1
  768. package/dist/shared/prompt-async-gate/queue.d.ts +0 -1
  769. package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +0 -1
  770. package/dist/shared/prompt-async-gate/reservations.d.ts +0 -1
  771. package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +0 -1
  772. package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +0 -1
  773. package/dist/shared/prompt-async-gate/timing.d.ts +0 -1
  774. package/dist/shared/prompt-async-gate/types.d.ts +0 -1
  775. package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
  776. package/dist/skills/data-scientist/references/execution-templates.md +0 -197
  777. package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
  778. package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
  779. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  780. package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
  781. package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
  782. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  783. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  784. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  785. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  786. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  787. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  788. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  789. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  790. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12136
  791. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9734
  792. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  793. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  794. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  795. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  796. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  797. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  798. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  799. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -309
  800. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -80
  801. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  802. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  803. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  804. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  805. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  806. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -21
  807. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  808. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  809. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  810. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  811. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  812. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  813. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  814. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  815. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  816. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  817. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  818. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  819. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  820. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  821. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  822. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  823. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  824. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  825. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  826. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  827. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  828. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  829. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  830. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  831. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  832. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  833. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  834. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  835. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  836. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  837. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  838. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  839. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  840. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  841. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  842. package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +0 -21
  843. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  844. package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -471
  845. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +0 -478
  846. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  847. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  848. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  849. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  850. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  851. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  852. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  853. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  854. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  855. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  856. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  857. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  858. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  859. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  860. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  861. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
  862. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  863. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  864. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  865. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  866. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  867. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  868. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  869. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  870. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  871. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  872. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  873. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  874. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  875. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  876. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  877. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  878. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  879. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  880. /package/packages/omo-codex/plugin/components/{codegraph → ulw-execute-continuation}/LICENSE +0 -0
  881. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  882. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
  883. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  884. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  885. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  886. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  887. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  888. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  889. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  890. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  891. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  892. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -175,6 +175,7 @@ async function runJsonRpcStdioServer(config) {
175
175
  const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
176
176
  isClosed = true;
177
177
  config.onIdleTimeout?.();
178
+ config.input.destroy();
178
179
  });
179
180
  const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
180
181
  isClosed = true;
@@ -271,7 +272,11 @@ function createParentWatchdog(config, onDeadParent) {
271
272
  const probeAlive = config.probeAlive ?? isProcessAlive;
272
273
  let fired = false;
273
274
  const timer = setInterval(() => {
274
- if (fired || probeAlive(parentPid))
275
+ if (fired)
276
+ return;
277
+ const alive = probeAlive(parentPid);
278
+ config.onPoll?.(alive);
279
+ if (alive)
275
280
  return;
276
281
  fired = true;
277
282
  onDeadParent(parentPid, pollIntervalMs);
@@ -306,8 +311,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
306
311
  };
307
312
  }
308
313
  // ../lsp-core/src/lsp/client-wrapper.ts
309
- import { existsSync as existsSync9, statSync as statSync3 } from "node:fs";
310
- import { dirname as dirname6, join as join4, resolve as resolve7 } from "node:path";
314
+ import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
315
+ import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
311
316
 
312
317
  // ../lsp-core/src/request-context.ts
313
318
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -316,18 +321,17 @@ import { homedir } from "node:os";
316
321
  import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
317
322
 
318
323
  class LspRequestContextParseError extends Error {
319
- code;
320
- name = "LspRequestContextParseError";
321
324
  constructor(code, message) {
322
325
  super(message);
323
326
  this.code = code;
327
+ this.name = "LspRequestContextParseError";
324
328
  }
325
329
  }
326
330
 
327
331
  class LspRequestContextUnavailableError extends Error {
328
- name = "LspRequestContextUnavailableError";
329
332
  constructor() {
330
333
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
334
+ this.name = "LspRequestContextUnavailableError";
331
335
  }
332
336
  }
333
337
  var storage = new AsyncLocalStorage;
@@ -357,7 +361,7 @@ function contextEnv(key) {
357
361
  }
358
362
  function createStandaloneMcpRequestContext(input = {}) {
359
363
  const env = input.env ?? process.env;
360
- const cwd = canonicalCwd(input.cwd ?? process.cwd());
364
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
361
365
  const home = input.homeDir ?? homedir();
362
366
  const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
363
367
  const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
@@ -500,22 +504,15 @@ function effectiveExtension(filePath) {
500
504
 
501
505
  // ../lsp-core/src/lsp/errors.ts
502
506
  class LspConnectionClosedError extends Error {
503
- serverId;
504
- root;
505
- name = "LspConnectionClosedError";
506
507
  constructor(serverId, root, message) {
507
508
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
508
509
  this.serverId = serverId;
509
510
  this.root = root;
511
+ this.name = "LspConnectionClosedError";
510
512
  }
511
513
  }
512
514
 
513
515
  class LspProcessExitedError extends Error {
514
- serverId;
515
- root;
516
- exitCode;
517
- stderrTail;
518
- name = "LspProcessExitedError";
519
516
  constructor(serverId, root, exitCode, stderrTail) {
520
517
  const stderrSuffix = stderrTail ? `
521
518
  stderr tail: ${stderrTail}` : "";
@@ -524,46 +521,59 @@ stderr tail: ${stderrTail}` : "";
524
521
  this.root = root;
525
522
  this.exitCode = exitCode;
526
523
  this.stderrTail = stderrTail;
524
+ this.name = "LspProcessExitedError";
527
525
  }
528
526
  }
529
527
 
530
528
  class LspRequestTimeoutError extends Error {
531
- method;
532
- stderrTail;
533
- name = "LspRequestTimeoutError";
534
529
  constructor(method, stderrTail) {
535
530
  const stderrSuffix = stderrTail ? `
536
531
  recent stderr: ${stderrTail}` : "";
537
532
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
538
533
  this.method = method;
539
534
  this.stderrTail = stderrTail;
535
+ this.name = "LspRequestTimeoutError";
540
536
  }
541
537
  }
542
538
 
543
539
  class LspInvalidPathError extends Error {
544
- name = "LspInvalidPathError";
540
+ constructor() {
541
+ super(...arguments);
542
+ this.name = "LspInvalidPathError";
543
+ }
545
544
  }
546
545
 
547
546
  class LspServerLookupError extends Error {
548
- lookup;
549
- name = "LspServerLookupError";
550
547
  constructor(message, lookup) {
551
548
  super(message);
552
549
  this.lookup = lookup;
550
+ this.name = "LspServerLookupError";
553
551
  }
554
552
  }
555
553
 
556
554
  class LspServerInitializingError extends Error {
557
- originalError;
558
- name = "LspServerInitializingError";
559
555
  constructor(originalError) {
560
556
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
561
557
  this.originalError = originalError;
558
+ this.name = "LspServerInitializingError";
562
559
  }
563
560
  }
564
561
 
565
562
  class LspProcessSpawnError extends Error {
566
- name = "LspProcessSpawnError";
563
+ constructor() {
564
+ super(...arguments);
565
+ this.name = "LspProcessSpawnError";
566
+ }
567
+ }
568
+
569
+ class LspClientRespawnBudgetExceededError extends Error {
570
+ constructor(serverId, root, retryLimit) {
571
+ super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
572
+ this.serverId = serverId;
573
+ this.root = root;
574
+ this.retryLimit = retryLimit;
575
+ this.name = "LspClientRespawnBudgetExceededError";
576
+ }
567
577
  }
568
578
  function isLspDeadConnectionError(err) {
569
579
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -586,6 +596,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
586
596
  // ../lsp-core/src/lsp/connection.ts
587
597
  import { pathToFileURL } from "node:url";
588
598
 
599
+ // ../lsp-core/src/lsp/timer-provider.ts
600
+ var realTimerProvider = {
601
+ now: () => Date.now(),
602
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
603
+ clearTimeout: (handle) => clearTimeout(handle)
604
+ };
605
+
589
606
  // ../lsp-core/src/lsp/constants.ts
590
607
  var DEFAULT_MAX_REFERENCES = 200;
591
608
  var DEFAULT_MAX_SYMBOLS = 200;
@@ -594,9 +611,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
594
611
  var REQUEST_TIMEOUT_MS = 15000;
595
612
  var INIT_TIMEOUT_MS = 60000;
596
613
  var IDLE_TIMEOUT_MS = 5 * 60000;
614
+ var MAX_RESIDENT_CLIENTS = 6;
597
615
  var REAPER_INTERVAL_MS = 60000;
598
616
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
599
617
  var STOP_SIGKILL_GRACE_MS = 1000;
618
+ var CLIENT_RESPAWN_RETRY_LIMIT = 2;
619
+ var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
600
620
 
601
621
  // ../lsp-core/src/lsp/json-rpc-connection.ts
602
622
  var HEADER_SEPARATOR2 = `\r
@@ -608,20 +628,31 @@ var METHOD_NOT_FOUND = -32601;
608
628
  var INTERNAL_ERROR = -32603;
609
629
 
610
630
  class JsonRpcConnection {
611
- reader;
612
- writer;
613
- pendingRequests = new Map;
614
- notificationHandlers = new Map;
615
- requestHandlers = new Map;
616
- closeHandlers = [];
617
- errorHandlers = [];
618
- inputBuffer = Buffer.alloc(0);
619
- nextRequestId = 1;
620
- listening = false;
621
- disposed = false;
622
631
  constructor(reader, writer) {
623
632
  this.reader = reader;
624
633
  this.writer = writer;
634
+ this.pendingRequests = new Map;
635
+ this.notificationHandlers = new Map;
636
+ this.requestHandlers = new Map;
637
+ this.closeHandlers = [];
638
+ this.errorHandlers = [];
639
+ this.inputBuffer = Buffer.alloc(0);
640
+ this.nextRequestId = 1;
641
+ this.listening = false;
642
+ this.disposed = false;
643
+ this.handleData = (chunk) => {
644
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
645
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
646
+ this.drainInputBuffer();
647
+ };
648
+ this.handleClose = () => {
649
+ for (const handler of this.closeHandlers) {
650
+ handler();
651
+ }
652
+ };
653
+ this.handleStreamError = (error) => {
654
+ this.emitError(error);
655
+ };
625
656
  }
626
657
  listen() {
627
658
  if (this.listening)
@@ -656,6 +687,7 @@ class JsonRpcConnection {
656
687
  let cancelAfterWrite = false;
657
688
  let settled = false;
658
689
  const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
690
+ let rejectAfterCancelWrite;
659
691
  const responsePromise = new Promise((resolve2, reject) => {
660
692
  const cleanup = () => {
661
693
  options.signal?.removeEventListener("abort", onAbort);
@@ -667,15 +699,19 @@ class JsonRpcConnection {
667
699
  this.pendingRequests.delete(key);
668
700
  cleanup();
669
701
  const rejectCancelled = () => reject(abortError(options.signal));
702
+ rejectAfterCancelWrite = async () => {
703
+ try {
704
+ await writeCancel();
705
+ } catch (error) {
706
+ this.emitError(toError(error));
707
+ }
708
+ rejectCancelled();
709
+ };
670
710
  if (!requestWritten) {
671
711
  cancelAfterWrite = true;
672
- rejectCancelled();
673
712
  return;
674
713
  }
675
- writeCancel().then(rejectCancelled, (error) => {
676
- this.emitError(toError(error));
677
- rejectCancelled();
678
- });
714
+ rejectAfterCancelWrite();
679
715
  };
680
716
  const onAbort = () => settleCancel();
681
717
  this.pendingRequests.set(key, {
@@ -703,7 +739,7 @@ class JsonRpcConnection {
703
739
  await this.writeMessage(message);
704
740
  requestWritten = true;
705
741
  if (cancelAfterWrite)
706
- await writeCancel();
742
+ await rejectAfterCancelWrite?.();
707
743
  } catch (error) {
708
744
  if (settled)
709
745
  return responsePromise;
@@ -742,19 +778,6 @@ class JsonRpcConnection {
742
778
  this.notificationHandlers.clear();
743
779
  this.requestHandlers.clear();
744
780
  }
745
- handleData = (chunk) => {
746
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
747
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
748
- this.drainInputBuffer();
749
- };
750
- handleClose = () => {
751
- for (const handler of this.closeHandlers) {
752
- handler();
753
- }
754
- };
755
- handleStreamError = (error) => {
756
- this.emitError(error);
757
- };
758
781
  drainInputBuffer() {
759
782
  while (true) {
760
783
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
@@ -1102,33 +1125,29 @@ function isPosition(value) {
1102
1125
 
1103
1126
  // ../lsp-core/src/lsp/transport.ts
1104
1127
  class LspClientNotStartedError extends Error {
1105
- serverId;
1106
- root;
1107
- name = "LspClientNotStartedError";
1108
1128
  constructor(serverId, root) {
1109
1129
  super("LSP client not started");
1110
1130
  this.serverId = serverId;
1111
1131
  this.root = root;
1132
+ this.name = "LspClientNotStartedError";
1112
1133
  }
1113
1134
  }
1114
1135
 
1115
1136
  class LspClientTransport {
1116
- root;
1117
- server;
1118
- proc = null;
1119
- connection = null;
1120
- stderrBuffer = [];
1121
- processExited = false;
1122
- diagnosticsStore = new Map;
1123
- requestTimeoutMs;
1124
- initializeTimeoutMs;
1125
- workspaceApplyEditHandler = null;
1126
- diagnosticPullSupported = false;
1127
1137
  constructor(root, server2, timeouts = {}) {
1128
1138
  this.root = root;
1129
1139
  this.server = server2;
1140
+ this.proc = null;
1141
+ this.connection = null;
1142
+ this.stderrBuffer = [];
1143
+ this.processExited = false;
1144
+ this.diagnosticsStore = new Map;
1145
+ this.workspaceApplyEditHandler = null;
1146
+ this.diagnosticPullSupported = false;
1147
+ this.documentFormattingSupported = false;
1130
1148
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
1131
1149
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
1150
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
1132
1151
  }
1133
1152
  pid() {
1134
1153
  return this.proc?.pid;
@@ -1148,6 +1167,12 @@ class LspClientTransport {
1148
1167
  isDiagnosticPullSupported() {
1149
1168
  return this.diagnosticPullSupported;
1150
1169
  }
1170
+ setDocumentFormattingSupported(supported) {
1171
+ this.documentFormattingSupported = supported;
1172
+ }
1173
+ isDocumentFormattingSupported() {
1174
+ return this.documentFormattingSupported;
1175
+ }
1151
1176
  handlePublishDiagnostics(params) {
1152
1177
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
1153
1178
  }
@@ -1223,7 +1248,7 @@ class LspClientTransport {
1223
1248
  const options = args[1];
1224
1249
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
1225
1250
  const timeoutController = new AbortController;
1226
- const timeoutHandle = setTimeout(() => {
1251
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
1227
1252
  const stderrTail = this.stderrBuffer.slice(-5).join(`
1228
1253
  `);
1229
1254
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -1242,7 +1267,7 @@ class LspClientTransport {
1242
1267
  }
1243
1268
  throw error;
1244
1269
  } finally {
1245
- clearTimeout(timeoutHandle);
1270
+ this.timerProvider.clearTimeout(timeoutHandle);
1246
1271
  combinedSignal.dispose();
1247
1272
  }
1248
1273
  }
@@ -1361,6 +1386,14 @@ function supportsDiagnosticPull(capabilities) {
1361
1386
  return false;
1362
1387
  return Object.hasOwn(capabilities, "diagnosticProvider");
1363
1388
  }
1389
+ function supportsDocumentFormatting(capabilities) {
1390
+ if (capabilities === undefined)
1391
+ return false;
1392
+ const provider = capabilities.documentFormattingProvider;
1393
+ if (provider === undefined || provider === null || provider === false)
1394
+ return false;
1395
+ return provider === true || typeof provider === "object";
1396
+ }
1364
1397
 
1365
1398
  class LspClientConnection extends LspClientTransport {
1366
1399
  async initialize() {
@@ -1377,6 +1410,7 @@ class LspClientConnection extends LspClientTransport {
1377
1410
  references: {},
1378
1411
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
1379
1412
  publishDiagnostics: {},
1413
+ formatting: { dynamicRegistration: false },
1380
1414
  rename: {
1381
1415
  prepareSupport: true,
1382
1416
  prepareSupportDefaultBehavior: 1
@@ -1418,6 +1452,7 @@ class LspClientConnection extends LspClientTransport {
1418
1452
  initializationOptions: this.server.initialization
1419
1453
  }, { timeoutMs: this.initializeTimeoutMs });
1420
1454
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
1455
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
1421
1456
  await this.sendNotification("initialized", {});
1422
1457
  await this.sendNotification("workspace/didChangeConfiguration", {
1423
1458
  settings: { json: { validate: { enable: true } } }
@@ -1613,6 +1648,17 @@ function canonicalPath(filePath) {
1613
1648
  return absolute;
1614
1649
  }
1615
1650
  }
1651
+ function normalizeDocumentUri(uri) {
1652
+ let decoded = uri;
1653
+ try {
1654
+ decoded = decodeURIComponent(uri);
1655
+ } catch {
1656
+ decoded = uri;
1657
+ }
1658
+ if (process.platform !== "win32")
1659
+ return decoded;
1660
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1661
+ }
1616
1662
  function isSameOrDescendant(candidate, parent) {
1617
1663
  const suffix = relative2(parent, candidate);
1618
1664
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1623,17 +1669,18 @@ function movedPath(candidate, oldPath, newPath) {
1623
1669
  }
1624
1670
 
1625
1671
  class WorkspaceDocumentState {
1626
- sendNotification;
1627
- clearDiagnostics;
1628
- openDocuments = new Map;
1629
- openByUri = new Map;
1630
- openPromises = new Map;
1631
- now;
1632
- versionlessPublishQuiescenceMs;
1633
1672
  constructor(sendNotification, clearDiagnostics, options = {}) {
1634
1673
  this.sendNotification = sendNotification;
1635
1674
  this.clearDiagnostics = clearDiagnostics;
1636
- this.now = options.now ?? (() => Date.now());
1675
+ this.openDocuments = new Map;
1676
+ this.openByUri = new Map;
1677
+ this.openPromises = new Map;
1678
+ this.timerProvider = options.timerProvider ?? {
1679
+ now: options.now ?? (() => Date.now()),
1680
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1681
+ clearTimeout: (handle) => clearTimeout(handle)
1682
+ };
1683
+ this.now = () => this.timerProvider.now();
1637
1684
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1638
1685
  }
1639
1686
  async openFile(filePath) {
@@ -1655,7 +1702,7 @@ class WorkspaceDocumentState {
1655
1702
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1656
1703
  }
1657
1704
  getStoredDiagnostics(uri) {
1658
- const state = this.openByUri.get(uri);
1705
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1659
1706
  if (!state)
1660
1707
  return [];
1661
1708
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1677,13 +1724,13 @@ class WorkspaceDocumentState {
1677
1724
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1678
1725
  }
1679
1726
  getPullCache(snapshot) {
1680
- const state = this.openByUri.get(snapshot.uri);
1727
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1681
1728
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1682
1729
  return null;
1683
1730
  return state.pullCache;
1684
1731
  }
1685
1732
  recordPullDiagnostics(snapshot, report) {
1686
- const state = this.openByUri.get(snapshot.uri);
1733
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1687
1734
  if (!state)
1688
1735
  return;
1689
1736
  state.pullCache = {
@@ -1693,7 +1740,7 @@ class WorkspaceDocumentState {
1693
1740
  };
1694
1741
  }
1695
1742
  recordPublishedDiagnostics(params) {
1696
- const state = this.openByUri.get(params.uri);
1743
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1697
1744
  if (!state)
1698
1745
  return;
1699
1746
  state.publishGeneration += 1;
@@ -1707,7 +1754,7 @@ class WorkspaceDocumentState {
1707
1754
  this.notifyWaiters(state);
1708
1755
  }
1709
1756
  resolvePushDiagnostics(snapshot) {
1710
- const state = this.openByUri.get(snapshot.uri);
1757
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1711
1758
  if (!state?.lastPublish)
1712
1759
  return { status: "missing" };
1713
1760
  const publish = state.lastPublish;
@@ -1721,7 +1768,7 @@ class WorkspaceDocumentState {
1721
1768
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1722
1769
  }
1723
1770
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1724
- const state = this.openByUri.get(snapshot.uri);
1771
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1725
1772
  if (!state || timeoutMs <= 0)
1726
1773
  return Promise.resolve();
1727
1774
  return new Promise((resolveActivity) => {
@@ -1730,11 +1777,11 @@ class WorkspaceDocumentState {
1730
1777
  if (settled)
1731
1778
  return;
1732
1779
  settled = true;
1733
- clearTimeout(timer);
1780
+ this.timerProvider.clearTimeout(timer);
1734
1781
  state.waiters.delete(finish);
1735
1782
  resolveActivity();
1736
1783
  };
1737
- const timer = setTimeout(finish, timeoutMs);
1784
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1738
1785
  if (typeof timer.unref === "function")
1739
1786
  timer.unref();
1740
1787
  state.waiters.add(finish);
@@ -1842,7 +1889,7 @@ class WorkspaceDocumentState {
1842
1889
  waiters: new Set
1843
1890
  };
1844
1891
  this.openDocuments.set(path, state);
1845
- this.openByUri.set(state.uri, state);
1892
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
1846
1893
  this.notifyWaiters(state);
1847
1894
  await this.sendNotification("textDocument/didOpen", {
1848
1895
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -1867,7 +1914,7 @@ class WorkspaceDocumentState {
1867
1914
  }
1868
1915
  async closeDocument(state) {
1869
1916
  this.openDocuments.delete(state.path);
1870
- this.openByUri.delete(state.uri);
1917
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
1871
1918
  this.clearDiagnostics(state.uri);
1872
1919
  this.notifyWaiters(state);
1873
1920
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -1896,13 +1943,11 @@ import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3,
1896
1943
  import { fileURLToPath } from "node:url";
1897
1944
 
1898
1945
  class WorkspaceEditPathError extends Error {
1899
- path;
1900
- detail;
1901
- name = "WorkspaceEditPathError";
1902
1946
  constructor(path, detail) {
1903
1947
  super(`${detail}: ${path}`);
1904
1948
  this.path = path;
1905
1949
  this.detail = detail;
1950
+ this.name = "WorkspaceEditPathError";
1906
1951
  }
1907
1952
  }
1908
1953
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -2194,13 +2239,11 @@ function canonicalFingerprint(operations) {
2194
2239
 
2195
2240
  // ../lsp-core/src/lsp/workspace-edit-types.ts
2196
2241
  class WorkspaceEditValidationError extends Error {
2197
- changeIndex;
2198
- detail;
2199
- name = "WorkspaceEditValidationError";
2200
2242
  constructor(changeIndex, detail) {
2201
2243
  super(`change ${changeIndex}: ${detail}`);
2202
2244
  this.changeIndex = changeIndex;
2203
2245
  this.detail = detail;
2246
+ this.name = "WorkspaceEditValidationError";
2204
2247
  }
2205
2248
  }
2206
2249
 
@@ -2698,10 +2741,9 @@ function simulateDelete(operation, virtual) {
2698
2741
  import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
2699
2742
  import { dirname as dirname4, resolve as resolve5 } from "node:path";
2700
2743
  class WorkspaceSnapshotBuilder {
2701
- workspaceRoot;
2702
- snapshots = new Map;
2703
2744
  constructor(workspaceRoot) {
2704
2745
  this.workspaceRoot = workspaceRoot;
2746
+ this.snapshots = new Map;
2705
2747
  }
2706
2748
  build(operations) {
2707
2749
  this.add(this.workspaceRoot, false);
@@ -2745,8 +2787,10 @@ function snapshotOperations(operations, workspaceRoot) {
2745
2787
 
2746
2788
  // ../lsp-core/src/lsp/workspace-edit-plan.ts
2747
2789
  class PlanPathIndex {
2748
- firstChangeByPath = new Map;
2749
- reportedPathByCanonical = new Map;
2790
+ constructor() {
2791
+ this.firstChangeByPath = new Map;
2792
+ this.reportedPathByCanonical = new Map;
2793
+ }
2750
2794
  build(operations) {
2751
2795
  for (const operation of operations) {
2752
2796
  switch (operation.kind) {
@@ -2835,14 +2879,11 @@ function isRecord4(value) {
2835
2879
  }
2836
2880
 
2837
2881
  class WorkspaceMutationController {
2838
- workspaceRoot;
2839
- documents;
2840
- activeLease = null;
2841
- nextLeaseId = 1;
2842
- io;
2843
2882
  constructor(workspaceRoot, documents) {
2844
2883
  this.workspaceRoot = workspaceRoot;
2845
2884
  this.documents = documents;
2885
+ this.activeLease = null;
2886
+ this.nextLeaseId = 1;
2846
2887
  }
2847
2888
  setIo(io) {
2848
2889
  this.io = io;
@@ -2955,14 +2996,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
2955
2996
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
2956
2997
 
2957
2998
  class LspClient extends LspClientConnection {
2958
- diagnosticPullErrors = [];
2959
- documents;
2960
- workspaceMutations;
2961
- diagnosticsFreshnessTimeoutMs;
2962
2999
  constructor(root, server2, options = {}) {
2963
3000
  super(root, server2, options);
3001
+ this.diagnosticPullErrors = [];
2964
3002
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2965
3003
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
3004
+ timerProvider: this.timerProvider,
2966
3005
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
2967
3006
  });
2968
3007
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -3015,6 +3054,18 @@ class LspClient extends LspClientConnection {
3015
3054
  textDocument: { uri: pathToFileURL3(absPath).href }
3016
3055
  }, options);
3017
3056
  }
3057
+ async formatDocument(filePath, options, signal) {
3058
+ if (!this.isDocumentFormattingSupported())
3059
+ return null;
3060
+ const absPath = this.resolveWorkspacePath(filePath);
3061
+ await this.openFile(absPath);
3062
+ const requestOptions = signal === undefined ? {} : { signal };
3063
+ const edits = await this.sendRequest("textDocument/formatting", {
3064
+ textDocument: { uri: pathToFileURL3(absPath).href },
3065
+ options
3066
+ }, requestOptions);
3067
+ return edits ?? [];
3068
+ }
3018
3069
  async workspaceSymbols(query, signal) {
3019
3070
  const options = signal === undefined ? {} : { signal };
3020
3071
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -3054,7 +3105,7 @@ class LspClient extends LspClientConnection {
3054
3105
  const absPath = this.resolveWorkspacePath(filePath);
3055
3106
  const uri = pathToFileURL3(absPath).href;
3056
3107
  await this.openFile(absPath);
3057
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
3108
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
3058
3109
  for (;; ) {
3059
3110
  signal?.throwIfAborted();
3060
3111
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -3067,7 +3118,7 @@ class LspClient extends LspClientConnection {
3067
3118
  if (!pushFallbackOnly) {
3068
3119
  const cached = this.documents.getPullCache(snapshot);
3069
3120
  try {
3070
- const remainingMs2 = deadlineAt - Date.now();
3121
+ const remainingMs2 = deadlineAt - this.timerProvider.now();
3071
3122
  if (remainingMs2 <= 0)
3072
3123
  return this.freshnessTimeout(absPath);
3073
3124
  const result = await this.sendRequest("textDocument/diagnostic", {
@@ -3102,7 +3153,7 @@ class LspClient extends LspClientConnection {
3102
3153
  }
3103
3154
  if (!pushFallbackOnly)
3104
3155
  continue;
3105
- const remainingMs = deadlineAt - Date.now();
3156
+ const remainingMs = deadlineAt - this.timerProvider.now();
3106
3157
  if (remainingMs <= 0) {
3107
3158
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
3108
3159
  const cached = this.documents.getPullCache(snapshot);
@@ -3260,18 +3311,16 @@ function awaitWithSignal(promise, signal) {
3260
3311
  }
3261
3312
 
3262
3313
  class LspManager {
3263
- clients = new Map;
3264
- reaperHandle = null;
3265
- signalDisposer = null;
3266
- disposed = false;
3267
- idleTimeoutMs;
3268
- initTimeoutMs;
3269
- reaperIntervalMs;
3270
- clientFactory;
3271
- now;
3272
3314
  constructor(options = {}) {
3315
+ this.clients = new Map;
3316
+ this.pendingStops = new Map;
3317
+ this.respawnBudgets = new Map;
3318
+ this.reaperHandle = null;
3319
+ this.signalDisposer = null;
3320
+ this.disposed = false;
3273
3321
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
3274
3322
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
3323
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
3275
3324
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
3276
3325
  this.clientFactory = options.clientFactory ?? ((root, server2) => new LspClient(root, server2));
3277
3326
  this.now = options.now ?? (() => Date.now());
@@ -3291,24 +3340,79 @@ class LspManager {
3291
3340
  getKey(root, serverId) {
3292
3341
  return `${root}::${serverId}`;
3293
3342
  }
3343
+ tombstoneStop(key, client) {
3344
+ const stop = stopClientBestEffort(client);
3345
+ this.pendingStops.set(key, stop);
3346
+ stop.finally(() => {
3347
+ if (this.pendingStops.get(key) === stop) {
3348
+ this.pendingStops.delete(key);
3349
+ }
3350
+ });
3351
+ return stop;
3352
+ }
3353
+ recordDeadGeneration(key) {
3354
+ let budget = this.respawnBudgets.get(key);
3355
+ if (budget === undefined) {
3356
+ budget = { deadGenerations: 0, exhaustedAt: null };
3357
+ this.respawnBudgets.set(key, budget);
3358
+ }
3359
+ budget.deadGenerations += 1;
3360
+ }
3361
+ markHealthyGeneration(key) {
3362
+ this.respawnBudgets.delete(key);
3363
+ }
3364
+ ensureRespawnAllowed(key, root, serverId) {
3365
+ const budget = this.respawnBudgets.get(key);
3366
+ if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
3367
+ return;
3368
+ if (budget.exhaustedAt === null) {
3369
+ budget.exhaustedAt = this.now();
3370
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3371
+ }
3372
+ if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
3373
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
3374
+ }
3375
+ budget.deadGenerations = 0;
3376
+ budget.exhaustedAt = null;
3377
+ }
3294
3378
  reapStale() {
3295
3379
  const t = this.now();
3296
3380
  for (const [key, managed] of this.clients) {
3297
3381
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3298
- stopClientBestEffort(managed.client);
3299
3382
  this.clients.delete(key);
3383
+ this.tombstoneStop(key, managed.client);
3300
3384
  continue;
3301
3385
  }
3302
3386
  if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
3303
- stopClientBestEffort(managed.client);
3304
3387
  this.clients.delete(key);
3388
+ this.tombstoneStop(key, managed.client);
3305
3389
  }
3306
3390
  }
3307
3391
  }
3392
+ evictForAdmission() {
3393
+ while (this.clients.size >= this.maxResidentClients) {
3394
+ const victim = this.leastRecentlyUsedIdleClient();
3395
+ if (!victim)
3396
+ return;
3397
+ this.clients.delete(victim.key);
3398
+ this.tombstoneStop(victim.key, victim.managed.client);
3399
+ }
3400
+ }
3401
+ leastRecentlyUsedIdleClient() {
3402
+ let candidate = null;
3403
+ for (const [key, managed] of this.clients) {
3404
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
3405
+ continue;
3406
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
3407
+ candidate = { key, managed };
3408
+ }
3409
+ }
3410
+ return candidate;
3411
+ }
3308
3412
  async tryDeleteIfOrphaned(key, managed) {
3309
3413
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
3310
3414
  this.clients.delete(key);
3311
- await stopClientBestEffort(managed.client);
3415
+ await this.tombstoneStop(key, managed.client);
3312
3416
  }
3313
3417
  }
3314
3418
  async getClient(root, server2, signal) {
@@ -3317,12 +3421,22 @@ class LspManager {
3317
3421
  }
3318
3422
  signal?.throwIfAborted();
3319
3423
  const key = this.getKey(root, server2.id);
3424
+ for (;; ) {
3425
+ const pendingStop = this.pendingStops.get(key);
3426
+ if (pendingStop === undefined)
3427
+ break;
3428
+ await awaitWithSignal(pendingStop, signal);
3429
+ signal?.throwIfAborted();
3430
+ }
3431
+ if (this.disposed) {
3432
+ throw new Error("LspManager has been disposed");
3433
+ }
3320
3434
  let managed = this.clients.get(key);
3321
3435
  if (managed) {
3322
3436
  const t = this.now();
3323
3437
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
3324
- await stopClientBestEffort(managed.client);
3325
3438
  this.clients.delete(key);
3439
+ await this.tombstoneStop(key, managed.client);
3326
3440
  managed = undefined;
3327
3441
  }
3328
3442
  }
@@ -3343,14 +3457,20 @@ class LspManager {
3343
3457
  signal.throwIfAborted();
3344
3458
  }
3345
3459
  if (!managed.client.isAlive()) {
3346
- await stopClientBestEffort(managed.client);
3347
- this.clients.delete(key);
3460
+ this.recordDeadGeneration(key);
3461
+ if (this.clients.get(key) === managed) {
3462
+ this.clients.delete(key);
3463
+ }
3464
+ await this.tombstoneStop(key, managed.client);
3348
3465
  return this.getClient(root, server2, signal);
3349
3466
  }
3467
+ this.markHealthyGeneration(key);
3350
3468
  managed.refCount++;
3351
3469
  managed.lastUsedAt = this.now();
3352
3470
  return managed.client;
3353
3471
  }
3472
+ this.evictForAdmission();
3473
+ this.ensureRespawnAllowed(key, root, server2.id);
3354
3474
  const client = this.clientFactory(root, server2);
3355
3475
  const initStartedAt = this.now();
3356
3476
  const initPromise = (async () => {
@@ -3374,7 +3494,7 @@ class LspManager {
3374
3494
  if (this.clients.get(key) === newManaged) {
3375
3495
  this.clients.delete(key);
3376
3496
  }
3377
- await stopClientBestEffort(client);
3497
+ await this.tombstoneStop(key, client);
3378
3498
  throw err;
3379
3499
  }
3380
3500
  newManaged.pendingWaiters--;
@@ -3385,6 +3505,15 @@ class LspManager {
3385
3505
  await this.tryDeleteIfOrphaned(key, newManaged);
3386
3506
  signal.throwIfAborted();
3387
3507
  }
3508
+ if (!client.isAlive()) {
3509
+ this.recordDeadGeneration(key);
3510
+ if (this.clients.get(key) === newManaged) {
3511
+ this.clients.delete(key);
3512
+ }
3513
+ await this.tombstoneStop(key, client);
3514
+ return this.getClient(root, server2, signal);
3515
+ }
3516
+ this.markHealthyGeneration(key);
3388
3517
  newManaged.refCount++;
3389
3518
  newManaged.lastUsedAt = this.now();
3390
3519
  return client;
@@ -3405,14 +3534,20 @@ class LspManager {
3405
3534
  if (client && managed.client !== client)
3406
3535
  return;
3407
3536
  this.clients.delete(key);
3408
- stopClientBestEffort(managed.client);
3537
+ this.tombstoneStop(key, managed.client);
3409
3538
  }
3410
3539
  warmupClient(root, server2) {
3411
3540
  if (this.disposed)
3412
3541
  return;
3413
3542
  const key = this.getKey(root, server2.id);
3414
- if (this.clients.has(key))
3543
+ if (this.clients.has(key) || this.pendingStops.has(key))
3415
3544
  return;
3545
+ this.evictForAdmission();
3546
+ try {
3547
+ this.ensureRespawnAllowed(key, root, server2.id);
3548
+ } catch {
3549
+ return;
3550
+ }
3416
3551
  const client = this.clientFactory(root, server2);
3417
3552
  const initStartedAt = this.now();
3418
3553
  const initPromise = (async () => {
@@ -3438,7 +3573,7 @@ class LspManager {
3438
3573
  if (this.clients.get(key) === managed) {
3439
3574
  this.clients.delete(key);
3440
3575
  }
3441
- stopClientBestEffort(client);
3576
+ this.tombstoneStop(key, client);
3442
3577
  });
3443
3578
  }
3444
3579
  isServerInitializing(root, serverId) {
@@ -3482,8 +3617,11 @@ class LspManager {
3482
3617
  for (const managed of this.clients.values()) {
3483
3618
  stopPromises.push(stopClientBestEffort(managed.client));
3484
3619
  }
3620
+ const tombstonedStops = [...this.pendingStops.values()];
3485
3621
  this.clients.clear();
3486
- await Promise.allSettled(stopPromises);
3622
+ this.respawnBudgets.clear();
3623
+ await Promise.allSettled([...stopPromises, ...tombstonedStops]);
3624
+ this.pendingStops.clear();
3487
3625
  }
3488
3626
  }
3489
3627
  var _defaultInstance = null;
@@ -3501,57 +3639,52 @@ async function disposeDefaultLspManager() {
3501
3639
  }
3502
3640
  }
3503
3641
 
3504
- // ../lsp-core/src/lsp/server-install-state.ts
3505
- import { existsSync as existsSync6, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3506
- import { dirname as dirname5 } from "node:path";
3507
- function getInstallDecisionsPath() {
3508
- return lspRequestContext().installDecisionsPath;
3509
- }
3510
- function loadInstallDecisions() {
3511
- const path = getInstallDecisionsPath();
3512
- if (!existsSync6(path))
3513
- return {};
3514
- try {
3515
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
3516
- return isInstallDecisions(parsed) ? parsed : {};
3517
- } catch {
3518
- return {};
3642
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3643
+ import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
3644
+ import { dirname as dirname5, join as join3 } from "node:path";
3645
+
3646
+ // ../lsp-core/src/lsp/workspace-markers.ts
3647
+ var GIT_WORKSPACE_MARKER = ".git";
3648
+ var PROJECT_WORKSPACE_MARKERS = [
3649
+ "package.json",
3650
+ "pyproject.toml",
3651
+ "Cargo.toml",
3652
+ "go.mod",
3653
+ "pom.xml",
3654
+ "build.gradle"
3655
+ ];
3656
+ var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
3657
+
3658
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3659
+ function findWorkspaceRootOutsideContext(directory) {
3660
+ const marked = nearestMarkedAncestor(directory);
3661
+ if (marked !== undefined)
3662
+ return marked;
3663
+ return realpathSync4(nearestExistingAncestor(directory));
3664
+ }
3665
+ function nearestMarkedAncestor(directory) {
3666
+ let current = directory;
3667
+ for (;; ) {
3668
+ if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
3669
+ return realpathSync4(current);
3670
+ }
3671
+ const parent = dirname5(current);
3672
+ if (parent === current)
3673
+ return;
3674
+ current = parent;
3519
3675
  }
3520
3676
  }
3521
- function loadInstallDecision(serverId) {
3522
- return loadInstallDecisions()[serverId];
3523
- }
3524
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3525
- const decisions = loadInstallDecisions();
3526
- decisions[serverId] = { decision, decidedAt };
3527
- writeInstallDecisions(decisions);
3528
- }
3529
- function isInstallDecision(value) {
3530
- return value === "declined" || value === "allowed";
3531
- }
3532
- function writeInstallDecisions(decisions) {
3533
- const path = getInstallDecisionsPath();
3534
- mkdirSync(dirname5(path), { recursive: true });
3535
- const tmpPath = `${path}.tmp`;
3536
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3537
- `, "utf8");
3538
- renameSync2(tmpPath, path);
3539
- }
3540
- function isInstallDecisions(value) {
3541
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3542
- }
3543
- function isInstallDecisionRecord(value) {
3544
- if (!isRecord5(value))
3545
- return false;
3546
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3547
- }
3548
- function isRecord5(value) {
3549
- return typeof value === "object" && value !== null && !Array.isArray(value);
3677
+ function nearestExistingAncestor(directory) {
3678
+ let current = directory;
3679
+ while (!existsSync6(current)) {
3680
+ const parent = dirname5(current);
3681
+ if (parent === current)
3682
+ return current;
3683
+ current = parent;
3684
+ }
3685
+ return current;
3550
3686
  }
3551
3687
 
3552
- // ../lsp-core/src/lsp/config-loader.ts
3553
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
3554
-
3555
3688
  // ../lsp-core/src/lsp/server-definitions.ts
3556
3689
  var LSP_INSTALL_HINTS = {
3557
3690
  typescript: "npm install -g typescript-language-server typescript",
@@ -3597,6 +3730,26 @@ var LSP_INSTALL_HINTS = {
3597
3730
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
3598
3731
  razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
3599
3732
  };
3733
+ var LSP_LOCAL_INSTALL_HINTS = {
3734
+ typescript: "bun add -d typescript-language-server typescript",
3735
+ vue: "bun add -d @vue/language-server",
3736
+ eslint: "bun add -d vscode-langservers-extracted",
3737
+ oxlint: "bun add -d oxlint",
3738
+ biome: "bun add -d @biomejs/biome",
3739
+ svelte: "bun add -d svelte-language-server",
3740
+ astro: "bun add -d @astrojs/language-server",
3741
+ bash: "bun add -d bash-language-server",
3742
+ "bash-ls": "bun add -d bash-language-server",
3743
+ "yaml-ls": "bun add -d yaml-language-server",
3744
+ php: "bun add -d intelephense",
3745
+ prisma: "bun add -d prisma",
3746
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
3747
+ pyright: "uv add --dev pyright",
3748
+ basedpyright: "uv add --dev basedpyright",
3749
+ ruff: "uv add --dev ruff",
3750
+ ty: "uv add --dev ty",
3751
+ "ruby-lsp": "bundle add ruby-lsp --group development"
3752
+ };
3600
3753
  var BUILTIN_SERVERS = {
3601
3754
  typescript: {
3602
3755
  command: ["typescript-language-server", "--stdio"],
@@ -3699,7 +3852,56 @@ var BUILTIN_SERVERS = {
3699
3852
  }
3700
3853
  };
3701
3854
 
3855
+ // ../lsp-core/src/lsp/server-install-state.ts
3856
+ import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3857
+ import { dirname as dirname6 } from "node:path";
3858
+ function getInstallDecisionsPath() {
3859
+ return lspRequestContext().installDecisionsPath;
3860
+ }
3861
+ function loadInstallDecisions() {
3862
+ const path = getInstallDecisionsPath();
3863
+ if (!existsSync7(path))
3864
+ return {};
3865
+ try {
3866
+ const parsed = JSON.parse(readFileSync3(path, "utf8"));
3867
+ return isInstallDecisions(parsed) ? parsed : {};
3868
+ } catch {
3869
+ return {};
3870
+ }
3871
+ }
3872
+ function loadInstallDecision(serverId) {
3873
+ return loadInstallDecisions()[serverId];
3874
+ }
3875
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3876
+ const decisions = loadInstallDecisions();
3877
+ decisions[serverId] = { decision, decidedAt };
3878
+ writeInstallDecisions(decisions);
3879
+ }
3880
+ function isInstallDecision(value) {
3881
+ return value === "declined" || value === "allowed";
3882
+ }
3883
+ function writeInstallDecisions(decisions) {
3884
+ const path = getInstallDecisionsPath();
3885
+ mkdirSync(dirname6(path), { recursive: true });
3886
+ const tmpPath = `${path}.tmp`;
3887
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3888
+ `, "utf8");
3889
+ renameSync2(tmpPath, path);
3890
+ }
3891
+ function isInstallDecisions(value) {
3892
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3893
+ }
3894
+ function isInstallDecisionRecord(value) {
3895
+ if (!isRecord5(value))
3896
+ return false;
3897
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3898
+ }
3899
+ function isRecord5(value) {
3900
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3901
+ }
3902
+
3702
3903
  // ../lsp-core/src/lsp/config-loader.ts
3904
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
3703
3905
  function getProjectConfigPaths() {
3704
3906
  return lspRequestContext().projectConfigPaths;
3705
3907
  }
@@ -3707,7 +3909,7 @@ function getUserConfigPath() {
3707
3909
  return lspRequestContext().userConfigPath;
3708
3910
  }
3709
3911
  function loadJsonFile(path) {
3710
- if (!existsSync7(path))
3912
+ if (!existsSync8(path))
3711
3913
  return null;
3712
3914
  try {
3713
3915
  const parsed = JSON.parse(readFileSync4(path, "utf-8"));
@@ -3895,54 +4097,155 @@ function getDisabledServerIds() {
3895
4097
  }
3896
4098
 
3897
4099
  // ../lsp-core/src/lsp/server-installation.ts
3898
- import { existsSync as existsSync8 } from "node:fs";
3899
- import { delimiter as delimiter3, join as join3 } from "node:path";
3900
- function isServerInstalled(command, _workingDirectory) {
3901
- if (command.length === 0)
3902
- return false;
3903
- const [cmd] = command;
3904
- if (!cmd)
3905
- return false;
3906
- if (cmd.includes("/") || cmd.includes("\\")) {
3907
- if (existsSync8(cmd))
3908
- return true;
4100
+ import { existsSync as existsSync9 } from "node:fs";
4101
+ import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
4102
+ var LOCAL_BIN_RULES = [
4103
+ {
4104
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
4105
+ binDirs: [join4("node_modules", ".bin")]
4106
+ },
4107
+ {
4108
+ markers: [
4109
+ "pyproject.toml",
4110
+ "ty.toml",
4111
+ "requirements.txt",
4112
+ "setup.py",
4113
+ "setup.cfg",
4114
+ "Pipfile",
4115
+ "pyrightconfig.json",
4116
+ "ruff.toml",
4117
+ ".ruff.toml"
4118
+ ],
4119
+ binDirs: [
4120
+ join4(".venv", "bin"),
4121
+ join4(".venv", "Scripts"),
4122
+ join4("venv", "bin"),
4123
+ join4("venv", "Scripts"),
4124
+ join4(".env", "bin"),
4125
+ join4(".env", "Scripts")
4126
+ ]
4127
+ },
4128
+ {
4129
+ markers: ["Gemfile", "Gemfile.lock"],
4130
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4131
+ },
4132
+ {
4133
+ markers: ["go.mod", "go.sum", "go.work"],
4134
+ binDirs: ["bin"]
3909
4135
  }
3910
- const isWindows = process.platform === "win32";
3911
- let exts = [""];
3912
- if (isWindows) {
3913
- const pathExt = process.env["PATHEXT"] ?? "";
3914
- if (pathExt) {
3915
- const systemExts = pathExt.split(";").filter(Boolean);
3916
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
3917
- } else {
3918
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4136
+ ];
4137
+ var resolutionCache = new Map;
4138
+ var probeCount = 0;
4139
+ function probe(path) {
4140
+ probeCount += 1;
4141
+ return existsSync9(path);
4142
+ }
4143
+ function executableSuffixes(platform, pathExt) {
4144
+ if (platform !== "win32")
4145
+ return [""];
4146
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4147
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4148
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4149
+ }
4150
+ function probeWithSuffixes(directory, command, suffixes) {
4151
+ for (const suffix of suffixes) {
4152
+ const candidate = join4(directory, command + suffix);
4153
+ if (probe(candidate))
4154
+ return candidate;
4155
+ }
4156
+ return null;
4157
+ }
4158
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4159
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4160
+ let current = resolve7(workingDirectory);
4161
+ while (true) {
4162
+ for (const rule of LOCAL_BIN_RULES) {
4163
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
4164
+ continue;
4165
+ for (const binDir of rule.binDirs) {
4166
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4167
+ if (found !== null)
4168
+ return found;
4169
+ }
3919
4170
  }
4171
+ if (probe(join4(current, ".git")))
4172
+ return null;
4173
+ if (boundary !== undefined && current === boundary)
4174
+ return null;
4175
+ const parent = dirname7(current);
4176
+ if (parent === current)
4177
+ return null;
4178
+ current = parent;
3920
4179
  }
3921
- let pathEnv = process.env["PATH"] ?? "";
3922
- if (isWindows && !pathEnv) {
4180
+ }
4181
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4182
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4183
+ if (platform === "win32" && !pathEnv) {
3923
4184
  pathEnv = process.env["Path"] ?? "";
3924
4185
  }
3925
- const paths = pathEnv.split(delimiter3);
3926
- for (const p of paths) {
3927
- for (const suffix of exts) {
3928
- if (existsSync8(join3(p, cmd + suffix))) {
3929
- return true;
3930
- }
3931
- }
4186
+ for (const entry of pathEnv.split(delimiter3)) {
4187
+ if (entry.length === 0)
4188
+ continue;
4189
+ const found = probeWithSuffixes(entry, command, suffixes);
4190
+ if (found !== null)
4191
+ return found;
3932
4192
  }
3933
- if (cmd === "node")
3934
- return true;
3935
- return false;
4193
+ return null;
4194
+ }
4195
+ function resolveServerBinary(command, workingDirectory, options = {}) {
4196
+ if (command.length === 0)
4197
+ return null;
4198
+ const [cmd] = command;
4199
+ if (cmd === undefined || cmd.length === 0)
4200
+ return null;
4201
+ const platform = options.platform ?? process.platform;
4202
+ const suffixes = executableSuffixes(platform, options.pathExt);
4203
+ if (cmd.includes("/") || cmd.includes("\\")) {
4204
+ const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4205
+ return probe(explicit) ? explicit : null;
4206
+ }
4207
+ const cacheKey = JSON.stringify([
4208
+ workingDirectory ?? "",
4209
+ cmd,
4210
+ platform,
4211
+ options.stopAt ?? "",
4212
+ options.pathExt ?? "",
4213
+ options.pathEnv ?? process.env["PATH"] ?? ""
4214
+ ]);
4215
+ const cached = resolutionCache.get(cacheKey);
4216
+ if (cached !== undefined)
4217
+ return cached;
4218
+ let resolved = null;
4219
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
4220
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4221
+ }
4222
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4223
+ if (resolved === null && cmd === "node")
4224
+ resolved = cmd;
4225
+ resolutionCache.set(cacheKey, resolved);
4226
+ return resolved;
4227
+ }
4228
+ function isServerInstalled(command, workingDirectory, options = {}) {
4229
+ if (command.length === 0)
4230
+ return false;
4231
+ return resolveServerBinary(command, workingDirectory, options) !== null;
3936
4232
  }
3937
4233
 
3938
4234
  // ../lsp-core/src/lsp/server-resolution.ts
4235
+ function withResolvedCommand(command, binaryPath) {
4236
+ return [binaryPath, ...command.slice(1)];
4237
+ }
3939
4238
  function findServerForExtension(ext) {
3940
4239
  const servers = getMergedServers();
4240
+ const workingDirectory = contextCwd();
3941
4241
  for (const server2 of servers) {
3942
- if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4242
+ if (!server2.extensions.includes(ext))
4243
+ continue;
4244
+ const binaryPath = resolveServerBinary(server2.command, workingDirectory);
4245
+ if (binaryPath !== null) {
3943
4246
  const resolvedServer = {
3944
4247
  id: server2.id,
3945
- command: server2.command,
4248
+ command: withResolvedCommand(server2.command, binaryPath),
3946
4249
  extensions: server2.extensions,
3947
4250
  priority: server2.priority
3948
4251
  };
@@ -3989,6 +4292,7 @@ function findServerForExtension(ext) {
3989
4292
  function getAllServers() {
3990
4293
  const servers = getMergedServers();
3991
4294
  const disabled = getDisabledServerIds();
4295
+ const workingDirectory = contextCwd();
3992
4296
  const result = [];
3993
4297
  const seen = new Set;
3994
4298
  for (const server2 of servers) {
@@ -3996,7 +4300,7 @@ function getAllServers() {
3996
4300
  continue;
3997
4301
  result.push({
3998
4302
  id: server2.id,
3999
- installed: isServerInstalled(server2.command),
4303
+ installed: isServerInstalled(server2.command, workingDirectory),
4000
4304
  extensions: server2.extensions,
4001
4305
  disabled: false,
4002
4306
  source: server2.source,
@@ -4010,7 +4314,7 @@ function getAllServers() {
4010
4314
  const builtin = BUILTIN_SERVERS[id];
4011
4315
  result.push({
4012
4316
  id,
4013
- installed: builtin ? isServerInstalled(builtin.command) : false,
4317
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4014
4318
  extensions: builtin?.extensions ?? [],
4015
4319
  disabled: true,
4016
4320
  source: "disabled",
@@ -4021,7 +4325,6 @@ function getAllServers() {
4021
4325
  }
4022
4326
 
4023
4327
  // ../lsp-core/src/lsp/client-wrapper.ts
4024
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
4025
4328
  function isDirectoryPath(filePath) {
4026
4329
  try {
4027
4330
  return statSync3(filePath).isDirectory();
@@ -4030,32 +4333,90 @@ function isDirectoryPath(filePath) {
4030
4333
  }
4031
4334
  }
4032
4335
  function findWorkspaceRoot(filePath) {
4033
- const abs = resolvePathInsideContext(filePath);
4336
+ const cwd = contextCwd();
4337
+ const abs = resolveReadablePathInsideContext(filePath);
4034
4338
  let dir = abs;
4035
4339
  if (!isDirectoryPath(dir)) {
4036
- dir = dirname6(dir);
4037
- }
4038
- let prevDir = "";
4039
- while (dir !== prevDir) {
4040
- for (const marker of WORKSPACE_MARKERS) {
4041
- if (existsSync9(join4(dir, marker))) {
4042
- return dir;
4340
+ dir = dirname8(dir);
4341
+ }
4342
+ if (!isPathInside(cwd, abs))
4343
+ return findWorkspaceRootOutsideContext(dir);
4344
+ const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4345
+ let nearestPackageRoot;
4346
+ while (isPathInside(cwd, dir)) {
4347
+ const canonicalDir = existingDirectoryInsideContext(dir, cwd);
4348
+ if (canonicalDir !== undefined) {
4349
+ if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
4350
+ return canonicalDir;
4351
+ }
4352
+ if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
4353
+ nearestPackageRoot = canonicalDir;
4043
4354
  }
4044
4355
  }
4045
- prevDir = dir;
4046
- dir = dirname6(dir);
4356
+ if (dir === cwd)
4357
+ break;
4358
+ dir = dirname8(dir);
4047
4359
  }
4048
- return dirname6(abs);
4360
+ return nearestPackageRoot ?? fallbackRoot;
4361
+ }
4362
+ function hasProjectWorkspaceMarker(directory) {
4363
+ return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
4364
+ }
4365
+ function resolveReadablePathInsideContext(filePath) {
4366
+ const cwd = contextCwd();
4367
+ const abs = resolve8(cwd, filePath);
4368
+ if (isPathInside(cwd, abs))
4369
+ return abs;
4370
+ const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
4371
+ if (rebased !== undefined)
4372
+ return rebased;
4373
+ return canonicalizeExistingOrNearestAncestor(abs);
4049
4374
  }
4050
4375
  function resolvePathInsideContext(filePath) {
4051
4376
  const cwd = contextCwd();
4052
- const abs = resolve7(cwd, filePath);
4377
+ const abs = resolveReadablePathInsideContext(filePath);
4053
4378
  const canonical = canonicalizeExistingOrNearestAncestor(abs);
4054
4379
  if (!isPathInside(cwd, canonical)) {
4055
4380
  throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
4056
4381
  }
4057
4382
  return canonical;
4058
4383
  }
4384
+ function rebaseThroughCanonicalAncestor(path, cwd) {
4385
+ let current = path;
4386
+ const suffix = [];
4387
+ while (true) {
4388
+ if (existsSync10(current)) {
4389
+ const canonical = realpathSync5(current);
4390
+ if (isPathInside(cwd, canonical))
4391
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
4392
+ }
4393
+ const parent = dirname8(current);
4394
+ if (parent === current)
4395
+ return;
4396
+ suffix.unshift(basename3(current));
4397
+ current = parent;
4398
+ }
4399
+ }
4400
+ function existingDirectoryInsideContext(directory, cwd) {
4401
+ if (!existsSync10(directory))
4402
+ return;
4403
+ const canonical = realpathSync5(directory);
4404
+ if (!statSync3(canonical).isDirectory())
4405
+ return;
4406
+ return isPathInside(cwd, canonical) ? canonical : undefined;
4407
+ }
4408
+ function nearestExistingDirectoryInsideContext(directory, cwd) {
4409
+ let current = directory;
4410
+ while (isPathInside(cwd, current)) {
4411
+ const canonical = existingDirectoryInsideContext(current, cwd);
4412
+ if (canonical !== undefined)
4413
+ return canonical;
4414
+ if (current === cwd)
4415
+ return;
4416
+ current = dirname8(current);
4417
+ }
4418
+ return;
4419
+ }
4059
4420
  function formatServerLookupError(result) {
4060
4421
  if (result.status === "not_installed") {
4061
4422
  return formatNotInstalled(result);
@@ -4079,6 +4440,19 @@ function formatServerLookupError(result) {
4079
4440
  ].join(`
4080
4441
  `);
4081
4442
  }
4443
+ function formatInstallOptions(serverId, installHint) {
4444
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
4445
+ if (localHint === undefined) {
4446
+ return ["To install, run:", ` ${installHint}`];
4447
+ }
4448
+ return [
4449
+ "To install in THIS repository (preferred — no global install needed):",
4450
+ ` ${localHint}`,
4451
+ "",
4452
+ "Or install it globally:",
4453
+ ` ${installHint}`
4454
+ ];
4455
+ }
4082
4456
  function formatNotInstalled(result) {
4083
4457
  const { server: server2, installHint } = result;
4084
4458
  const extensions = server2.extensions.join(", ");
@@ -4093,19 +4467,19 @@ function formatNotInstalled(result) {
4093
4467
  `Command not found: ${server2.command[0]}`,
4094
4468
  ""
4095
4469
  ];
4470
+ const installOptions = formatInstallOptions(server2.id, installHint);
4096
4471
  if (decision === "allowed") {
4097
4472
  return [
4098
4473
  ...header,
4099
4474
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4100
- ` ${installHint}`
4475
+ ...installOptions.slice(1)
4101
4476
  ].join(`
4102
4477
  `);
4103
4478
  }
4104
4479
  if (!context.capabilities.installDecisionTool) {
4105
4480
  return [
4106
4481
  ...header,
4107
- "To install, run:",
4108
- ` ${installHint}`,
4482
+ ...installOptions,
4109
4483
  "",
4110
4484
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4111
4485
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4114,8 +4488,7 @@ function formatNotInstalled(result) {
4114
4488
  }
4115
4489
  return [
4116
4490
  ...header,
4117
- "To install, run:",
4118
- ` ${installHint}`,
4491
+ ...installOptions,
4119
4492
  "",
4120
4493
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4121
4494
  "- If the user agrees: run the install command above, then retry this tool.",
@@ -4126,7 +4499,7 @@ function formatNotInstalled(result) {
4126
4499
  ].join(`
4127
4500
  `);
4128
4501
  }
4129
- var READ_ONLY_RETRY_TOOLS = new Set([
4502
+ var READ_ONLY_TOOLS = new Set([
4130
4503
  "diagnostics",
4131
4504
  "definition",
4132
4505
  "references",
@@ -4135,7 +4508,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
4135
4508
  "prepareRename"
4136
4509
  ]);
4137
4510
  async function withLspClient(filePath, fn, toolName, options = {}) {
4138
- const absPath = resolvePathInsideContext(filePath);
4511
+ const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
4139
4512
  if (isDirectoryPath(absPath)) {
4140
4513
  throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
4141
4514
  }
@@ -4150,9 +4523,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4150
4523
  const acquireAndCall = async (allowRetry) => {
4151
4524
  const client = await manager.getClient(root, server2, options.signal);
4152
4525
  try {
4153
- return await fn(client, root);
4526
+ return await fn(client, root, absPath);
4154
4527
  } catch (err) {
4155
- if (allowRetry && READ_ONLY_RETRY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4528
+ if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4156
4529
  manager.invalidateClient(root, server2.id, client);
4157
4530
  return acquireAndCall(false);
4158
4531
  }
@@ -4170,8 +4543,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4170
4543
  }
4171
4544
 
4172
4545
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4173
- import { existsSync as existsSync10, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4174
- import { join as join5, resolve as resolve8 } from "node:path";
4546
+ import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4547
+ import { join as join6, resolve as resolve9 } from "node:path";
4175
4548
 
4176
4549
  // ../lsp-core/src/lsp/formatters.ts
4177
4550
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -4301,7 +4674,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
4301
4674
  for (const entry of entries) {
4302
4675
  if (files.length >= maxFiles)
4303
4676
  return;
4304
- const fullPath = join5(currentDir, entry);
4677
+ const fullPath = join6(currentDir, entry);
4305
4678
  let stat;
4306
4679
  try {
4307
4680
  stat = lstatSync4(fullPath);
@@ -4326,8 +4699,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4326
4699
  if (!extension.startsWith(".")) {
4327
4700
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4328
4701
  }
4329
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4330
- if (!existsSync10(absDir)) {
4702
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
4703
+ if (!existsSync11(absDir)) {
4331
4704
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4332
4705
  }
4333
4706
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
@@ -4414,7 +4787,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4414
4787
 
4415
4788
  // ../lsp-core/src/lsp/infer-extension.ts
4416
4789
  import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
4417
- import { join as join6 } from "node:path";
4790
+ import { join as join7 } from "node:path";
4418
4791
  var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
4419
4792
  var MAX_SCAN_ENTRIES = 500;
4420
4793
  function inferExtensionFromDirectory(directory) {
@@ -4432,7 +4805,7 @@ function inferExtensionFromDirectory(directory) {
4432
4805
  for (const entry of entries) {
4433
4806
  if (scanned >= MAX_SCAN_ENTRIES)
4434
4807
  return;
4435
- const fullPath = join6(dir, entry);
4808
+ const fullPath = join7(dir, entry);
4436
4809
  let stat;
4437
4810
  try {
4438
4811
  stat = lstatSync5(fullPath);
@@ -4607,7 +4980,7 @@ async function executeLspDiagnostics(params, signal) {
4607
4980
  const filePath = requireString(params, "filePath");
4608
4981
  const severity = severityFilter(params);
4609
4982
  try {
4610
- const absPath = resolvePathInsideContext(filePath);
4983
+ const absPath = resolveReadablePathInsideContext(filePath);
4611
4984
  if (isDirectoryPath(absPath)) {
4612
4985
  const extension = inferExtensionFromDirectory(absPath);
4613
4986
  if (!extension) {
@@ -4636,7 +5009,7 @@ async function executeLspDiagnostics(params, signal) {
4636
5009
  };
4637
5010
  return text(output2.output, details2);
4638
5011
  }
4639
- const result = await withLspClient(filePath, async (client) => client.diagnostics(filePath, signal), "diagnostics", clientOptions(signal));
5012
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
4640
5013
  if (result.transientError) {
4641
5014
  const message = result.transientError.message;
4642
5015
  const details2 = {
@@ -4683,6 +5056,96 @@ async function executeLspDiagnostics(params, signal) {
4683
5056
  throw error;
4684
5057
  }
4685
5058
  }
5059
+ // ../lsp-core/src/lsp/format-document.ts
5060
+ import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
5061
+ var DEFAULT_FORMATTING_OPTIONS = {
5062
+ tabSize: 4,
5063
+ insertSpaces: false,
5064
+ trimTrailingWhitespace: true,
5065
+ insertFinalNewline: true,
5066
+ trimFinalNewlines: true
5067
+ };
5068
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
5069
+ async function formatDocumentWithClient(client, filePath, options = {}) {
5070
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
5071
+ if (edits === null)
5072
+ return { status: "unavailable", reason: "capability_not_advertised" };
5073
+ if (edits.length === 0)
5074
+ return UNCHANGED;
5075
+ const before = readFileSync5(filePath, "utf-8");
5076
+ const normalized = normalizeTextEdits(before, edits, 0);
5077
+ if (normalized.text === before)
5078
+ return UNCHANGED;
5079
+ writeAtomically(filePath, normalized.text);
5080
+ await client.openFile(filePath);
5081
+ return {
5082
+ status: "formatted",
5083
+ ...lineDelta(normalized.edits)
5084
+ };
5085
+ }
5086
+ function lineDelta(edits) {
5087
+ let linesAdded = 0;
5088
+ let linesRemoved = 0;
5089
+ for (const edit of edits) {
5090
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
5091
+ linesAdded += edit.newText.split(`
5092
+ `).length;
5093
+ }
5094
+ return { linesAdded, linesRemoved };
5095
+ }
5096
+ function writeAtomically(filePath, content) {
5097
+ const tempPath = `${filePath}.omo-format.tmp`;
5098
+ writeFileSync3(tempPath, content, "utf-8");
5099
+ try {
5100
+ renameSync3(tempPath, filePath);
5101
+ } catch (error) {
5102
+ try {
5103
+ unlinkSync(tempPath);
5104
+ } catch {}
5105
+ throw error;
5106
+ }
5107
+ }
5108
+
5109
+ // ../lsp-core/src/tools/format.ts
5110
+ async function executeLspFormat(params, signal) {
5111
+ const filePath = requireString(params, "filePath");
5112
+ try {
5113
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
5114
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
5115
+ } catch (error) {
5116
+ const missingDependency = missingDependencyResult(error, {
5117
+ filePath,
5118
+ status: "unavailable",
5119
+ reason: "server_unavailable",
5120
+ linesAdded: 0,
5121
+ linesRemoved: 0
5122
+ });
5123
+ if (missingDependency)
5124
+ return missingDependency;
5125
+ throw error;
5126
+ }
5127
+ }
5128
+ function formatDetails(filePath, result) {
5129
+ if (result.status === "unavailable") {
5130
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5131
+ }
5132
+ return {
5133
+ filePath,
5134
+ status: result.status,
5135
+ linesAdded: result.linesAdded,
5136
+ linesRemoved: result.linesRemoved
5137
+ };
5138
+ }
5139
+ function describeResult(filePath, result) {
5140
+ if (result.status === "unavailable") {
5141
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5142
+ }
5143
+ if (result.status === "unchanged") {
5144
+ return `Already formatted: ${filePath}`;
5145
+ }
5146
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5147
+ }
5148
+
4686
5149
  // ../lsp-core/src/tools/install-decision.ts
4687
5150
  async function executeLspInstallDecision(params) {
4688
5151
  const serverId = requireString(params, "server_id");
@@ -4711,7 +5174,7 @@ async function executeLspGotoDefinition(params, signal) {
4711
5174
  const line = requireNumber(params, "line");
4712
5175
  const character = requireNumber(params, "character");
4713
5176
  try {
4714
- const result = await withLspClient(filePath, async (client) => client.definition(filePath, line, character, signal), "definition", clientOptions(signal));
5177
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
4715
5178
  const locations = !result ? [] : Array.isArray(result) ? result : [result];
4716
5179
  const details = { filePath, line, character, locations };
4717
5180
  if (locations.length === 0)
@@ -4736,7 +5199,7 @@ async function executeLspFindReferences(params, signal) {
4736
5199
  const character = requireNumber(params, "character");
4737
5200
  const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
4738
5201
  try {
4739
- const result = await withLspClient(filePath, async (client) => client.references(filePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
5202
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
4740
5203
  const references = Array.isArray(result) ? result : [];
4741
5204
  const total = references.length;
4742
5205
  const truncated = total > DEFAULT_MAX_REFERENCES;
@@ -4778,7 +5241,7 @@ async function executeLspPrepareRename(params, signal) {
4778
5241
  const line = requireNumber(params, "line");
4779
5242
  const character = requireNumber(params, "character");
4780
5243
  try {
4781
- const result = await withLspClient(filePath, async (client) => client.prepareRename(filePath, line, character, signal), "prepareRename", clientOptions(signal));
5244
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
4782
5245
  const details = { filePath, line, character, result };
4783
5246
  return text(formatPrepareRenameResult(result), details);
4784
5247
  } catch (error) {
@@ -4799,7 +5262,7 @@ async function executeLspRename(params, signal) {
4799
5262
  const character = requireNumber(params, "character");
4800
5263
  const newName = requireString(params, "newName");
4801
5264
  try {
4802
- const result = await withLspClient(filePath, async (client) => client.rename(filePath, line, character, newName, signal), "rename", clientOptions(signal));
5265
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
4803
5266
  const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
4804
5267
  return text(formatApplyResult(result.apply), details, !result.apply.success);
4805
5268
  } catch (error) {
@@ -4879,7 +5342,7 @@ async function executeLspSymbols(params, signal) {
4879
5342
  const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
4880
5343
  return formatSymbolsResult(filePath, scope, symbols2, limit, query);
4881
5344
  }
4882
- const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(filePath, signal), "documentSymbols", clientOptions(signal));
5345
+ const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
4883
5346
  return formatSymbolsResult(filePath, scope, symbols, limit);
4884
5347
  } catch (error) {
4885
5348
  const query = optionalString(params, "query");
@@ -5015,6 +5478,16 @@ var LSP_MCP_TOOLS = [
5015
5478
  }, ["filePath", "line", "character", "newName"]),
5016
5479
  execute: executeLspRename
5017
5480
  },
5481
+ {
5482
+ name: "format",
5483
+ aliases: ["lsp_format"],
5484
+ title: "LSP Format",
5485
+ description: "Format a source file with its language server and write the returned edits to disk.",
5486
+ inputSchema: objectSchema({
5487
+ filePath: { type: "string", description: "Source file path to format." }
5488
+ }, ["filePath"]),
5489
+ execute: executeLspFormat
5490
+ },
5018
5491
  {
5019
5492
  name: "install_decision",
5020
5493
  aliases: ["lsp_install_decision"],
@@ -5122,6 +5595,6 @@ function requestedProtocolVersion(params) {
5122
5595
  return params["protocolVersion"];
5123
5596
  }
5124
5597
  export {
5125
- runMcpStdioServer,
5126
- handleLspMcpRequest
5598
+ handleLspMcpRequest,
5599
+ runMcpStdioServer
5127
5600
  };