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
@@ -17,6 +17,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
17
17
  // ../lsp-core/src/lsp/connection.ts
18
18
  import { pathToFileURL } from "node:url";
19
19
 
20
+ // ../lsp-core/src/lsp/timer-provider.ts
21
+ var realTimerProvider = {
22
+ now: () => Date.now(),
23
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
24
+ clearTimeout: (handle) => clearTimeout(handle)
25
+ };
26
+
20
27
  // ../lsp-core/src/lsp/constants.ts
21
28
  var DEFAULT_MAX_REFERENCES = 200;
22
29
  var DEFAULT_MAX_SYMBOLS = 200;
@@ -25,28 +32,24 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
25
32
  var REQUEST_TIMEOUT_MS = 15000;
26
33
  var INIT_TIMEOUT_MS = 60000;
27
34
  var IDLE_TIMEOUT_MS = 5 * 60000;
35
+ var MAX_RESIDENT_CLIENTS = 6;
28
36
  var REAPER_INTERVAL_MS = 60000;
29
37
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
30
38
  var STOP_SIGKILL_GRACE_MS = 1000;
39
+ var CLIENT_RESPAWN_RETRY_LIMIT = 2;
40
+ var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
31
41
 
32
42
  // ../lsp-core/src/lsp/errors.ts
33
43
  class LspConnectionClosedError extends Error {
34
- serverId;
35
- root;
36
- name = "LspConnectionClosedError";
37
44
  constructor(serverId, root, message) {
38
45
  super(message ?? `LSP connection closed for ${serverId} at ${root}`);
39
46
  this.serverId = serverId;
40
47
  this.root = root;
48
+ this.name = "LspConnectionClosedError";
41
49
  }
42
50
  }
43
51
 
44
52
  class LspProcessExitedError extends Error {
45
- serverId;
46
- root;
47
- exitCode;
48
- stderrTail;
49
- name = "LspProcessExitedError";
50
53
  constructor(serverId, root, exitCode, stderrTail) {
51
54
  const stderrSuffix = stderrTail ? `
52
55
  stderr tail: ${stderrTail}` : "";
@@ -55,46 +58,59 @@ stderr tail: ${stderrTail}` : "";
55
58
  this.root = root;
56
59
  this.exitCode = exitCode;
57
60
  this.stderrTail = stderrTail;
61
+ this.name = "LspProcessExitedError";
58
62
  }
59
63
  }
60
64
 
61
65
  class LspRequestTimeoutError extends Error {
62
- method;
63
- stderrTail;
64
- name = "LspRequestTimeoutError";
65
66
  constructor(method, stderrTail) {
66
67
  const stderrSuffix = stderrTail ? `
67
68
  recent stderr: ${stderrTail}` : "";
68
69
  super(`LSP request timeout (method: ${method})${stderrSuffix}`);
69
70
  this.method = method;
70
71
  this.stderrTail = stderrTail;
72
+ this.name = "LspRequestTimeoutError";
71
73
  }
72
74
  }
73
75
 
74
76
  class LspInvalidPathError extends Error {
75
- name = "LspInvalidPathError";
77
+ constructor() {
78
+ super(...arguments);
79
+ this.name = "LspInvalidPathError";
80
+ }
76
81
  }
77
82
 
78
83
  class LspServerLookupError extends Error {
79
- lookup;
80
- name = "LspServerLookupError";
81
84
  constructor(message, lookup) {
82
85
  super(message);
83
86
  this.lookup = lookup;
87
+ this.name = "LspServerLookupError";
84
88
  }
85
89
  }
86
90
 
87
91
  class LspServerInitializingError extends Error {
88
- originalError;
89
- name = "LspServerInitializingError";
90
92
  constructor(originalError) {
91
93
  super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
92
94
  this.originalError = originalError;
95
+ this.name = "LspServerInitializingError";
93
96
  }
94
97
  }
95
98
 
96
99
  class LspProcessSpawnError extends Error {
97
- name = "LspProcessSpawnError";
100
+ constructor() {
101
+ super(...arguments);
102
+ this.name = "LspProcessSpawnError";
103
+ }
104
+ }
105
+
106
+ class LspClientRespawnBudgetExceededError extends Error {
107
+ constructor(serverId, root, retryLimit) {
108
+ super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
109
+ this.serverId = serverId;
110
+ this.root = root;
111
+ this.retryLimit = retryLimit;
112
+ this.name = "LspClientRespawnBudgetExceededError";
113
+ }
98
114
  }
99
115
  function isLspDeadConnectionError(err) {
100
116
  return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
@@ -110,20 +126,31 @@ var METHOD_NOT_FOUND = -32601;
110
126
  var INTERNAL_ERROR = -32603;
111
127
 
112
128
  class JsonRpcConnection {
113
- reader;
114
- writer;
115
- pendingRequests = new Map;
116
- notificationHandlers = new Map;
117
- requestHandlers = new Map;
118
- closeHandlers = [];
119
- errorHandlers = [];
120
- inputBuffer = Buffer.alloc(0);
121
- nextRequestId = 1;
122
- listening = false;
123
- disposed = false;
124
129
  constructor(reader, writer) {
125
130
  this.reader = reader;
126
131
  this.writer = writer;
132
+ this.pendingRequests = new Map;
133
+ this.notificationHandlers = new Map;
134
+ this.requestHandlers = new Map;
135
+ this.closeHandlers = [];
136
+ this.errorHandlers = [];
137
+ this.inputBuffer = Buffer.alloc(0);
138
+ this.nextRequestId = 1;
139
+ this.listening = false;
140
+ this.disposed = false;
141
+ this.handleData = (chunk) => {
142
+ const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
143
+ this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
144
+ this.drainInputBuffer();
145
+ };
146
+ this.handleClose = () => {
147
+ for (const handler of this.closeHandlers) {
148
+ handler();
149
+ }
150
+ };
151
+ this.handleStreamError = (error) => {
152
+ this.emitError(error);
153
+ };
127
154
  }
128
155
  listen() {
129
156
  if (this.listening)
@@ -158,6 +185,7 @@ class JsonRpcConnection {
158
185
  let cancelAfterWrite = false;
159
186
  let settled = false;
160
187
  const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
188
+ let rejectAfterCancelWrite;
161
189
  const responsePromise = new Promise((resolve, reject) => {
162
190
  const cleanup = () => {
163
191
  options.signal?.removeEventListener("abort", onAbort);
@@ -169,15 +197,19 @@ class JsonRpcConnection {
169
197
  this.pendingRequests.delete(key);
170
198
  cleanup();
171
199
  const rejectCancelled = () => reject(abortError(options.signal));
200
+ rejectAfterCancelWrite = async () => {
201
+ try {
202
+ await writeCancel();
203
+ } catch (error) {
204
+ this.emitError(toError(error));
205
+ }
206
+ rejectCancelled();
207
+ };
172
208
  if (!requestWritten) {
173
209
  cancelAfterWrite = true;
174
- rejectCancelled();
175
210
  return;
176
211
  }
177
- writeCancel().then(rejectCancelled, (error) => {
178
- this.emitError(toError(error));
179
- rejectCancelled();
180
- });
212
+ rejectAfterCancelWrite();
181
213
  };
182
214
  const onAbort = () => settleCancel();
183
215
  this.pendingRequests.set(key, {
@@ -205,7 +237,7 @@ class JsonRpcConnection {
205
237
  await this.writeMessage(message);
206
238
  requestWritten = true;
207
239
  if (cancelAfterWrite)
208
- await writeCancel();
240
+ await rejectAfterCancelWrite?.();
209
241
  } catch (error) {
210
242
  if (settled)
211
243
  return responsePromise;
@@ -244,19 +276,6 @@ class JsonRpcConnection {
244
276
  this.notificationHandlers.clear();
245
277
  this.requestHandlers.clear();
246
278
  }
247
- handleData = (chunk) => {
248
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
249
- this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
250
- this.drainInputBuffer();
251
- };
252
- handleClose = () => {
253
- for (const handler of this.closeHandlers) {
254
- handler();
255
- }
256
- };
257
- handleStreamError = (error) => {
258
- this.emitError(error);
259
- };
260
279
  drainInputBuffer() {
261
280
  while (true) {
262
281
  const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR);
@@ -604,33 +623,29 @@ function isPosition(value) {
604
623
 
605
624
  // ../lsp-core/src/lsp/transport.ts
606
625
  class LspClientNotStartedError extends Error {
607
- serverId;
608
- root;
609
- name = "LspClientNotStartedError";
610
626
  constructor(serverId, root) {
611
627
  super("LSP client not started");
612
628
  this.serverId = serverId;
613
629
  this.root = root;
630
+ this.name = "LspClientNotStartedError";
614
631
  }
615
632
  }
616
633
 
617
634
  class LspClientTransport {
618
- root;
619
- server;
620
- proc = null;
621
- connection = null;
622
- stderrBuffer = [];
623
- processExited = false;
624
- diagnosticsStore = new Map;
625
- requestTimeoutMs;
626
- initializeTimeoutMs;
627
- workspaceApplyEditHandler = null;
628
- diagnosticPullSupported = false;
629
635
  constructor(root, server, timeouts = {}) {
630
636
  this.root = root;
631
637
  this.server = server;
638
+ this.proc = null;
639
+ this.connection = null;
640
+ this.stderrBuffer = [];
641
+ this.processExited = false;
642
+ this.diagnosticsStore = new Map;
643
+ this.workspaceApplyEditHandler = null;
644
+ this.diagnosticPullSupported = false;
645
+ this.documentFormattingSupported = false;
632
646
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
633
647
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
648
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
634
649
  }
635
650
  pid() {
636
651
  return this.proc?.pid;
@@ -650,6 +665,12 @@ class LspClientTransport {
650
665
  isDiagnosticPullSupported() {
651
666
  return this.diagnosticPullSupported;
652
667
  }
668
+ setDocumentFormattingSupported(supported) {
669
+ this.documentFormattingSupported = supported;
670
+ }
671
+ isDocumentFormattingSupported() {
672
+ return this.documentFormattingSupported;
673
+ }
653
674
  handlePublishDiagnostics(params) {
654
675
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
655
676
  }
@@ -725,7 +746,7 @@ class LspClientTransport {
725
746
  const options = args[1];
726
747
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
727
748
  const timeoutController = new AbortController;
728
- const timeoutHandle = setTimeout(() => {
749
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
729
750
  const stderrTail = this.stderrBuffer.slice(-5).join(`
730
751
  `);
731
752
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -744,7 +765,7 @@ class LspClientTransport {
744
765
  }
745
766
  throw error;
746
767
  } finally {
747
- clearTimeout(timeoutHandle);
768
+ this.timerProvider.clearTimeout(timeoutHandle);
748
769
  combinedSignal.dispose();
749
770
  }
750
771
  }
@@ -863,6 +884,14 @@ function supportsDiagnosticPull(capabilities) {
863
884
  return false;
864
885
  return Object.hasOwn(capabilities, "diagnosticProvider");
865
886
  }
887
+ function supportsDocumentFormatting(capabilities) {
888
+ if (capabilities === undefined)
889
+ return false;
890
+ const provider = capabilities.documentFormattingProvider;
891
+ if (provider === undefined || provider === null || provider === false)
892
+ return false;
893
+ return provider === true || typeof provider === "object";
894
+ }
866
895
 
867
896
  class LspClientConnection extends LspClientTransport {
868
897
  async initialize() {
@@ -879,6 +908,7 @@ class LspClientConnection extends LspClientTransport {
879
908
  references: {},
880
909
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
881
910
  publishDiagnostics: {},
911
+ formatting: { dynamicRegistration: false },
882
912
  rename: {
883
913
  prepareSupport: true,
884
914
  prepareSupportDefaultBehavior: 1
@@ -920,6 +950,7 @@ class LspClientConnection extends LspClientTransport {
920
950
  initializationOptions: this.server.initialization
921
951
  }, { timeoutMs: this.initializeTimeoutMs });
922
952
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
953
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
923
954
  await this.sendNotification("initialized", {});
924
955
  await this.sendNotification("workspace/didChangeConfiguration", {
925
956
  settings: { json: { validate: { enable: true } } }
@@ -1125,6 +1156,17 @@ function canonicalPath(filePath) {
1125
1156
  return absolute;
1126
1157
  }
1127
1158
  }
1159
+ function normalizeDocumentUri(uri) {
1160
+ let decoded = uri;
1161
+ try {
1162
+ decoded = decodeURIComponent(uri);
1163
+ } catch {
1164
+ decoded = uri;
1165
+ }
1166
+ if (process.platform !== "win32")
1167
+ return decoded;
1168
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1169
+ }
1128
1170
  function isSameOrDescendant(candidate, parent) {
1129
1171
  const suffix = relative(parent, candidate);
1130
1172
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1135,17 +1177,18 @@ function movedPath(candidate, oldPath, newPath) {
1135
1177
  }
1136
1178
 
1137
1179
  class WorkspaceDocumentState {
1138
- sendNotification;
1139
- clearDiagnostics;
1140
- openDocuments = new Map;
1141
- openByUri = new Map;
1142
- openPromises = new Map;
1143
- now;
1144
- versionlessPublishQuiescenceMs;
1145
1180
  constructor(sendNotification, clearDiagnostics, options = {}) {
1146
1181
  this.sendNotification = sendNotification;
1147
1182
  this.clearDiagnostics = clearDiagnostics;
1148
- this.now = options.now ?? (() => Date.now());
1183
+ this.openDocuments = new Map;
1184
+ this.openByUri = new Map;
1185
+ this.openPromises = new Map;
1186
+ this.timerProvider = options.timerProvider ?? {
1187
+ now: options.now ?? (() => Date.now()),
1188
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1189
+ clearTimeout: (handle) => clearTimeout(handle)
1190
+ };
1191
+ this.now = () => this.timerProvider.now();
1149
1192
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1150
1193
  }
1151
1194
  async openFile(filePath) {
@@ -1167,7 +1210,7 @@ class WorkspaceDocumentState {
1167
1210
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1168
1211
  }
1169
1212
  getStoredDiagnostics(uri) {
1170
- const state = this.openByUri.get(uri);
1213
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1171
1214
  if (!state)
1172
1215
  return [];
1173
1216
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1189,13 +1232,13 @@ class WorkspaceDocumentState {
1189
1232
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1190
1233
  }
1191
1234
  getPullCache(snapshot) {
1192
- const state = this.openByUri.get(snapshot.uri);
1235
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1193
1236
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1194
1237
  return null;
1195
1238
  return state.pullCache;
1196
1239
  }
1197
1240
  recordPullDiagnostics(snapshot, report) {
1198
- const state = this.openByUri.get(snapshot.uri);
1241
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1199
1242
  if (!state)
1200
1243
  return;
1201
1244
  state.pullCache = {
@@ -1205,7 +1248,7 @@ class WorkspaceDocumentState {
1205
1248
  };
1206
1249
  }
1207
1250
  recordPublishedDiagnostics(params) {
1208
- const state = this.openByUri.get(params.uri);
1251
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1209
1252
  if (!state)
1210
1253
  return;
1211
1254
  state.publishGeneration += 1;
@@ -1219,7 +1262,7 @@ class WorkspaceDocumentState {
1219
1262
  this.notifyWaiters(state);
1220
1263
  }
1221
1264
  resolvePushDiagnostics(snapshot) {
1222
- const state = this.openByUri.get(snapshot.uri);
1265
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1223
1266
  if (!state?.lastPublish)
1224
1267
  return { status: "missing" };
1225
1268
  const publish = state.lastPublish;
@@ -1233,7 +1276,7 @@ class WorkspaceDocumentState {
1233
1276
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1234
1277
  }
1235
1278
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1236
- const state = this.openByUri.get(snapshot.uri);
1279
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1237
1280
  if (!state || timeoutMs <= 0)
1238
1281
  return Promise.resolve();
1239
1282
  return new Promise((resolveActivity) => {
@@ -1242,11 +1285,11 @@ class WorkspaceDocumentState {
1242
1285
  if (settled)
1243
1286
  return;
1244
1287
  settled = true;
1245
- clearTimeout(timer);
1288
+ this.timerProvider.clearTimeout(timer);
1246
1289
  state.waiters.delete(finish);
1247
1290
  resolveActivity();
1248
1291
  };
1249
- const timer = setTimeout(finish, timeoutMs);
1292
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1250
1293
  if (typeof timer.unref === "function")
1251
1294
  timer.unref();
1252
1295
  state.waiters.add(finish);
@@ -1354,7 +1397,7 @@ class WorkspaceDocumentState {
1354
1397
  waiters: new Set
1355
1398
  };
1356
1399
  this.openDocuments.set(path, state);
1357
- this.openByUri.set(state.uri, state);
1400
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
1358
1401
  this.notifyWaiters(state);
1359
1402
  await this.sendNotification("textDocument/didOpen", {
1360
1403
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -1379,7 +1422,7 @@ class WorkspaceDocumentState {
1379
1422
  }
1380
1423
  async closeDocument(state) {
1381
1424
  this.openDocuments.delete(state.path);
1382
- this.openByUri.delete(state.uri);
1425
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
1383
1426
  this.clearDiagnostics(state.uri);
1384
1427
  this.notifyWaiters(state);
1385
1428
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -1408,13 +1451,11 @@ import { dirname, isAbsolute, relative as relative2, resolve as resolve2 } from
1408
1451
  import { fileURLToPath } from "node:url";
1409
1452
 
1410
1453
  class WorkspaceEditPathError extends Error {
1411
- path;
1412
- detail;
1413
- name = "WorkspaceEditPathError";
1414
1454
  constructor(path, detail) {
1415
1455
  super(`${detail}: ${path}`);
1416
1456
  this.path = path;
1417
1457
  this.detail = detail;
1458
+ this.name = "WorkspaceEditPathError";
1418
1459
  }
1419
1460
  }
1420
1461
  function isPathInsideWorkspace(filePath, workspaceRoot) {
@@ -1706,13 +1747,11 @@ function canonicalFingerprint(operations) {
1706
1747
 
1707
1748
  // ../lsp-core/src/lsp/workspace-edit-types.ts
1708
1749
  class WorkspaceEditValidationError extends Error {
1709
- changeIndex;
1710
- detail;
1711
- name = "WorkspaceEditValidationError";
1712
1750
  constructor(changeIndex, detail) {
1713
1751
  super(`change ${changeIndex}: ${detail}`);
1714
1752
  this.changeIndex = changeIndex;
1715
1753
  this.detail = detail;
1754
+ this.name = "WorkspaceEditValidationError";
1716
1755
  }
1717
1756
  }
1718
1757
 
@@ -2210,10 +2249,9 @@ function simulateDelete(operation, virtual) {
2210
2249
  import { existsSync as existsSync4, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
2211
2250
  import { dirname as dirname3, resolve as resolve4 } from "node:path";
2212
2251
  class WorkspaceSnapshotBuilder {
2213
- workspaceRoot;
2214
- snapshots = new Map;
2215
2252
  constructor(workspaceRoot) {
2216
2253
  this.workspaceRoot = workspaceRoot;
2254
+ this.snapshots = new Map;
2217
2255
  }
2218
2256
  build(operations) {
2219
2257
  this.add(this.workspaceRoot, false);
@@ -2257,8 +2295,10 @@ function snapshotOperations(operations, workspaceRoot) {
2257
2295
 
2258
2296
  // ../lsp-core/src/lsp/workspace-edit-plan.ts
2259
2297
  class PlanPathIndex {
2260
- firstChangeByPath = new Map;
2261
- reportedPathByCanonical = new Map;
2298
+ constructor() {
2299
+ this.firstChangeByPath = new Map;
2300
+ this.reportedPathByCanonical = new Map;
2301
+ }
2262
2302
  build(operations) {
2263
2303
  for (const operation of operations) {
2264
2304
  switch (operation.kind) {
@@ -2347,14 +2387,11 @@ function isRecord3(value) {
2347
2387
  }
2348
2388
 
2349
2389
  class WorkspaceMutationController {
2350
- workspaceRoot;
2351
- documents;
2352
- activeLease = null;
2353
- nextLeaseId = 1;
2354
- io;
2355
2390
  constructor(workspaceRoot, documents) {
2356
2391
  this.workspaceRoot = workspaceRoot;
2357
2392
  this.documents = documents;
2393
+ this.activeLease = null;
2394
+ this.nextLeaseId = 1;
2358
2395
  }
2359
2396
  setIo(io) {
2360
2397
  this.io = io;
@@ -2467,14 +2504,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
2467
2504
  var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
2468
2505
 
2469
2506
  class LspClient extends LspClientConnection {
2470
- diagnosticPullErrors = [];
2471
- documents;
2472
- workspaceMutations;
2473
- diagnosticsFreshnessTimeoutMs;
2474
2507
  constructor(root, server, options = {}) {
2475
2508
  super(root, server, options);
2509
+ this.diagnosticPullErrors = [];
2476
2510
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2477
2511
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
2512
+ timerProvider: this.timerProvider,
2478
2513
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
2479
2514
  });
2480
2515
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -2527,6 +2562,18 @@ class LspClient extends LspClientConnection {
2527
2562
  textDocument: { uri: pathToFileURL3(absPath).href }
2528
2563
  }, options);
2529
2564
  }
2565
+ async formatDocument(filePath, options, signal) {
2566
+ if (!this.isDocumentFormattingSupported())
2567
+ return null;
2568
+ const absPath = this.resolveWorkspacePath(filePath);
2569
+ await this.openFile(absPath);
2570
+ const requestOptions = signal === undefined ? {} : { signal };
2571
+ const edits = await this.sendRequest("textDocument/formatting", {
2572
+ textDocument: { uri: pathToFileURL3(absPath).href },
2573
+ options
2574
+ }, requestOptions);
2575
+ return edits ?? [];
2576
+ }
2530
2577
  async workspaceSymbols(query, signal) {
2531
2578
  const options = signal === undefined ? {} : { signal };
2532
2579
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -2566,7 +2613,7 @@ class LspClient extends LspClientConnection {
2566
2613
  const absPath = this.resolveWorkspacePath(filePath);
2567
2614
  const uri = pathToFileURL3(absPath).href;
2568
2615
  await this.openFile(absPath);
2569
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
2616
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
2570
2617
  for (;; ) {
2571
2618
  signal?.throwIfAborted();
2572
2619
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -2579,7 +2626,7 @@ class LspClient extends LspClientConnection {
2579
2626
  if (!pushFallbackOnly) {
2580
2627
  const cached = this.documents.getPullCache(snapshot);
2581
2628
  try {
2582
- const remainingMs2 = deadlineAt - Date.now();
2629
+ const remainingMs2 = deadlineAt - this.timerProvider.now();
2583
2630
  if (remainingMs2 <= 0)
2584
2631
  return this.freshnessTimeout(absPath);
2585
2632
  const result = await this.sendRequest("textDocument/diagnostic", {
@@ -2614,7 +2661,7 @@ class LspClient extends LspClientConnection {
2614
2661
  }
2615
2662
  if (!pushFallbackOnly)
2616
2663
  continue;
2617
- const remainingMs = deadlineAt - Date.now();
2664
+ const remainingMs = deadlineAt - this.timerProvider.now();
2618
2665
  if (remainingMs <= 0) {
2619
2666
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
2620
2667
  const cached = this.documents.getPullCache(snapshot);
@@ -2772,18 +2819,16 @@ function awaitWithSignal(promise, signal) {
2772
2819
  }
2773
2820
 
2774
2821
  class LspManager {
2775
- clients = new Map;
2776
- reaperHandle = null;
2777
- signalDisposer = null;
2778
- disposed = false;
2779
- idleTimeoutMs;
2780
- initTimeoutMs;
2781
- reaperIntervalMs;
2782
- clientFactory;
2783
- now;
2784
2822
  constructor(options = {}) {
2823
+ this.clients = new Map;
2824
+ this.pendingStops = new Map;
2825
+ this.respawnBudgets = new Map;
2826
+ this.reaperHandle = null;
2827
+ this.signalDisposer = null;
2828
+ this.disposed = false;
2785
2829
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
2786
2830
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
2831
+ this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
2787
2832
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
2788
2833
  this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
2789
2834
  this.now = options.now ?? (() => Date.now());
@@ -2803,24 +2848,79 @@ class LspManager {
2803
2848
  getKey(root, serverId) {
2804
2849
  return `${root}::${serverId}`;
2805
2850
  }
2851
+ tombstoneStop(key, client) {
2852
+ const stop = stopClientBestEffort(client);
2853
+ this.pendingStops.set(key, stop);
2854
+ stop.finally(() => {
2855
+ if (this.pendingStops.get(key) === stop) {
2856
+ this.pendingStops.delete(key);
2857
+ }
2858
+ });
2859
+ return stop;
2860
+ }
2861
+ recordDeadGeneration(key) {
2862
+ let budget = this.respawnBudgets.get(key);
2863
+ if (budget === undefined) {
2864
+ budget = { deadGenerations: 0, exhaustedAt: null };
2865
+ this.respawnBudgets.set(key, budget);
2866
+ }
2867
+ budget.deadGenerations += 1;
2868
+ }
2869
+ markHealthyGeneration(key) {
2870
+ this.respawnBudgets.delete(key);
2871
+ }
2872
+ ensureRespawnAllowed(key, root, serverId) {
2873
+ const budget = this.respawnBudgets.get(key);
2874
+ if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
2875
+ return;
2876
+ if (budget.exhaustedAt === null) {
2877
+ budget.exhaustedAt = this.now();
2878
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
2879
+ }
2880
+ if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
2881
+ throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
2882
+ }
2883
+ budget.deadGenerations = 0;
2884
+ budget.exhaustedAt = null;
2885
+ }
2806
2886
  reapStale() {
2807
2887
  const t = this.now();
2808
2888
  for (const [key, managed] of this.clients) {
2809
2889
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
2810
- stopClientBestEffort(managed.client);
2811
2890
  this.clients.delete(key);
2891
+ this.tombstoneStop(key, managed.client);
2812
2892
  continue;
2813
2893
  }
2814
2894
  if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
2815
- stopClientBestEffort(managed.client);
2816
2895
  this.clients.delete(key);
2896
+ this.tombstoneStop(key, managed.client);
2817
2897
  }
2818
2898
  }
2819
2899
  }
2900
+ evictForAdmission() {
2901
+ while (this.clients.size >= this.maxResidentClients) {
2902
+ const victim = this.leastRecentlyUsedIdleClient();
2903
+ if (!victim)
2904
+ return;
2905
+ this.clients.delete(victim.key);
2906
+ this.tombstoneStop(victim.key, victim.managed.client);
2907
+ }
2908
+ }
2909
+ leastRecentlyUsedIdleClient() {
2910
+ let candidate = null;
2911
+ for (const [key, managed] of this.clients) {
2912
+ if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
2913
+ continue;
2914
+ if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
2915
+ candidate = { key, managed };
2916
+ }
2917
+ }
2918
+ return candidate;
2919
+ }
2820
2920
  async tryDeleteIfOrphaned(key, managed) {
2821
2921
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
2822
2922
  this.clients.delete(key);
2823
- await stopClientBestEffort(managed.client);
2923
+ await this.tombstoneStop(key, managed.client);
2824
2924
  }
2825
2925
  }
2826
2926
  async getClient(root, server, signal) {
@@ -2829,12 +2929,22 @@ class LspManager {
2829
2929
  }
2830
2930
  signal?.throwIfAborted();
2831
2931
  const key = this.getKey(root, server.id);
2932
+ for (;; ) {
2933
+ const pendingStop = this.pendingStops.get(key);
2934
+ if (pendingStop === undefined)
2935
+ break;
2936
+ await awaitWithSignal(pendingStop, signal);
2937
+ signal?.throwIfAborted();
2938
+ }
2939
+ if (this.disposed) {
2940
+ throw new Error("LspManager has been disposed");
2941
+ }
2832
2942
  let managed = this.clients.get(key);
2833
2943
  if (managed) {
2834
2944
  const t = this.now();
2835
2945
  if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
2836
- await stopClientBestEffort(managed.client);
2837
2946
  this.clients.delete(key);
2947
+ await this.tombstoneStop(key, managed.client);
2838
2948
  managed = undefined;
2839
2949
  }
2840
2950
  }
@@ -2855,14 +2965,20 @@ class LspManager {
2855
2965
  signal.throwIfAborted();
2856
2966
  }
2857
2967
  if (!managed.client.isAlive()) {
2858
- await stopClientBestEffort(managed.client);
2859
- this.clients.delete(key);
2968
+ this.recordDeadGeneration(key);
2969
+ if (this.clients.get(key) === managed) {
2970
+ this.clients.delete(key);
2971
+ }
2972
+ await this.tombstoneStop(key, managed.client);
2860
2973
  return this.getClient(root, server, signal);
2861
2974
  }
2975
+ this.markHealthyGeneration(key);
2862
2976
  managed.refCount++;
2863
2977
  managed.lastUsedAt = this.now();
2864
2978
  return managed.client;
2865
2979
  }
2980
+ this.evictForAdmission();
2981
+ this.ensureRespawnAllowed(key, root, server.id);
2866
2982
  const client = this.clientFactory(root, server);
2867
2983
  const initStartedAt = this.now();
2868
2984
  const initPromise = (async () => {
@@ -2886,7 +3002,7 @@ class LspManager {
2886
3002
  if (this.clients.get(key) === newManaged) {
2887
3003
  this.clients.delete(key);
2888
3004
  }
2889
- await stopClientBestEffort(client);
3005
+ await this.tombstoneStop(key, client);
2890
3006
  throw err;
2891
3007
  }
2892
3008
  newManaged.pendingWaiters--;
@@ -2897,6 +3013,15 @@ class LspManager {
2897
3013
  await this.tryDeleteIfOrphaned(key, newManaged);
2898
3014
  signal.throwIfAborted();
2899
3015
  }
3016
+ if (!client.isAlive()) {
3017
+ this.recordDeadGeneration(key);
3018
+ if (this.clients.get(key) === newManaged) {
3019
+ this.clients.delete(key);
3020
+ }
3021
+ await this.tombstoneStop(key, client);
3022
+ return this.getClient(root, server, signal);
3023
+ }
3024
+ this.markHealthyGeneration(key);
2900
3025
  newManaged.refCount++;
2901
3026
  newManaged.lastUsedAt = this.now();
2902
3027
  return client;
@@ -2917,14 +3042,20 @@ class LspManager {
2917
3042
  if (client && managed.client !== client)
2918
3043
  return;
2919
3044
  this.clients.delete(key);
2920
- stopClientBestEffort(managed.client);
3045
+ this.tombstoneStop(key, managed.client);
2921
3046
  }
2922
3047
  warmupClient(root, server) {
2923
3048
  if (this.disposed)
2924
3049
  return;
2925
3050
  const key = this.getKey(root, server.id);
2926
- if (this.clients.has(key))
3051
+ if (this.clients.has(key) || this.pendingStops.has(key))
3052
+ return;
3053
+ this.evictForAdmission();
3054
+ try {
3055
+ this.ensureRespawnAllowed(key, root, server.id);
3056
+ } catch {
2927
3057
  return;
3058
+ }
2928
3059
  const client = this.clientFactory(root, server);
2929
3060
  const initStartedAt = this.now();
2930
3061
  const initPromise = (async () => {
@@ -2950,7 +3081,7 @@ class LspManager {
2950
3081
  if (this.clients.get(key) === managed) {
2951
3082
  this.clients.delete(key);
2952
3083
  }
2953
- stopClientBestEffort(client);
3084
+ this.tombstoneStop(key, client);
2954
3085
  });
2955
3086
  }
2956
3087
  isServerInitializing(root, serverId) {
@@ -2994,8 +3125,11 @@ class LspManager {
2994
3125
  for (const managed of this.clients.values()) {
2995
3126
  stopPromises.push(stopClientBestEffort(managed.client));
2996
3127
  }
3128
+ const tombstonedStops = [...this.pendingStops.values()];
2997
3129
  this.clients.clear();
2998
- await Promise.allSettled(stopPromises);
3130
+ this.respawnBudgets.clear();
3131
+ await Promise.allSettled([...stopPromises, ...tombstonedStops]);
3132
+ this.pendingStops.clear();
2999
3133
  }
3000
3134
  }
3001
3135
  var _defaultInstance = null;
@@ -3189,6 +3323,7 @@ async function runJsonRpcStdioServer(config) {
3189
3323
  const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
3190
3324
  isClosed = true;
3191
3325
  config.onIdleTimeout?.();
3326
+ config.input.destroy();
3192
3327
  });
3193
3328
  const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
3194
3329
  isClosed = true;
@@ -3285,7 +3420,11 @@ function createParentWatchdog(config, onDeadParent) {
3285
3420
  const probeAlive = config.probeAlive ?? isProcessAlive;
3286
3421
  let fired = false;
3287
3422
  const timer = setInterval(() => {
3288
- if (fired || probeAlive(parentPid))
3423
+ if (fired)
3424
+ return;
3425
+ const alive = probeAlive(parentPid);
3426
+ config.onPoll?.(alive);
3427
+ if (alive)
3289
3428
  return;
3290
3429
  fired = true;
3291
3430
  onDeadParent(parentPid, pollIntervalMs);
@@ -3320,8 +3459,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
3320
3459
  };
3321
3460
  }
3322
3461
  // ../lsp-core/src/lsp/client-wrapper.ts
3323
- import { existsSync as existsSync9, statSync as statSync3 } from "node:fs";
3324
- import { dirname as dirname6, join as join4, resolve as resolve7 } from "node:path";
3462
+ import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
3463
+ import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
3325
3464
 
3326
3465
  // ../lsp-core/src/request-context.ts
3327
3466
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -3330,18 +3469,17 @@ import { homedir } from "node:os";
3330
3469
  import { basename as basename2, delimiter as delimiter2, dirname as dirname4, isAbsolute as isAbsolute2, join as join2, relative as relative4, resolve as resolve6 } from "node:path";
3331
3470
 
3332
3471
  class LspRequestContextParseError extends Error {
3333
- code;
3334
- name = "LspRequestContextParseError";
3335
3472
  constructor(code, message) {
3336
3473
  super(message);
3337
3474
  this.code = code;
3475
+ this.name = "LspRequestContextParseError";
3338
3476
  }
3339
3477
  }
3340
3478
 
3341
3479
  class LspRequestContextUnavailableError extends Error {
3342
- name = "LspRequestContextUnavailableError";
3343
3480
  constructor() {
3344
3481
  super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
3482
+ this.name = "LspRequestContextUnavailableError";
3345
3483
  }
3346
3484
  }
3347
3485
  var storage = new AsyncLocalStorage;
@@ -3371,7 +3509,7 @@ function contextEnv(key) {
3371
3509
  }
3372
3510
  function createStandaloneMcpRequestContext(input = {}) {
3373
3511
  const env = input.env ?? process.env;
3374
- const cwd = canonicalCwd(input.cwd ?? process.cwd());
3512
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
3375
3513
  const home = input.homeDir ?? homedir();
3376
3514
  const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
3377
3515
  const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
@@ -3502,57 +3640,52 @@ function errorCode(error) {
3502
3640
  return typeof code === "string" ? code : undefined;
3503
3641
  }
3504
3642
 
3505
- // ../lsp-core/src/lsp/server-install-state.ts
3506
- import { existsSync as existsSync6, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3507
- import { dirname as dirname5 } from "node:path";
3508
- function getInstallDecisionsPath() {
3509
- return lspRequestContext().installDecisionsPath;
3510
- }
3511
- function loadInstallDecisions() {
3512
- const path = getInstallDecisionsPath();
3513
- if (!existsSync6(path))
3514
- return {};
3515
- try {
3516
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
3517
- return isInstallDecisions(parsed) ? parsed : {};
3518
- } catch {
3519
- return {};
3643
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3644
+ import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
3645
+ import { dirname as dirname5, join as join3 } from "node:path";
3646
+
3647
+ // ../lsp-core/src/lsp/workspace-markers.ts
3648
+ var GIT_WORKSPACE_MARKER = ".git";
3649
+ var PROJECT_WORKSPACE_MARKERS = [
3650
+ "package.json",
3651
+ "pyproject.toml",
3652
+ "Cargo.toml",
3653
+ "go.mod",
3654
+ "pom.xml",
3655
+ "build.gradle"
3656
+ ];
3657
+ var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
3658
+
3659
+ // ../lsp-core/src/lsp/outside-context-workspace.ts
3660
+ function findWorkspaceRootOutsideContext(directory) {
3661
+ const marked = nearestMarkedAncestor(directory);
3662
+ if (marked !== undefined)
3663
+ return marked;
3664
+ return realpathSync4(nearestExistingAncestor(directory));
3665
+ }
3666
+ function nearestMarkedAncestor(directory) {
3667
+ let current = directory;
3668
+ for (;; ) {
3669
+ if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
3670
+ return realpathSync4(current);
3671
+ }
3672
+ const parent = dirname5(current);
3673
+ if (parent === current)
3674
+ return;
3675
+ current = parent;
3520
3676
  }
3521
3677
  }
3522
- function loadInstallDecision(serverId) {
3523
- return loadInstallDecisions()[serverId];
3524
- }
3525
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3526
- const decisions = loadInstallDecisions();
3527
- decisions[serverId] = { decision, decidedAt };
3528
- writeInstallDecisions(decisions);
3529
- }
3530
- function isInstallDecision(value) {
3531
- return value === "declined" || value === "allowed";
3532
- }
3533
- function writeInstallDecisions(decisions) {
3534
- const path = getInstallDecisionsPath();
3535
- mkdirSync(dirname5(path), { recursive: true });
3536
- const tmpPath = `${path}.tmp`;
3537
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3538
- `, "utf8");
3539
- renameSync2(tmpPath, path);
3540
- }
3541
- function isInstallDecisions(value) {
3542
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3543
- }
3544
- function isInstallDecisionRecord(value) {
3545
- if (!isRecord5(value))
3546
- return false;
3547
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3548
- }
3549
- function isRecord5(value) {
3550
- return typeof value === "object" && value !== null && !Array.isArray(value);
3678
+ function nearestExistingAncestor(directory) {
3679
+ let current = directory;
3680
+ while (!existsSync6(current)) {
3681
+ const parent = dirname5(current);
3682
+ if (parent === current)
3683
+ return current;
3684
+ current = parent;
3685
+ }
3686
+ return current;
3551
3687
  }
3552
3688
 
3553
- // ../lsp-core/src/lsp/config-loader.ts
3554
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
3555
-
3556
3689
  // ../lsp-core/src/lsp/server-definitions.ts
3557
3690
  var LSP_INSTALL_HINTS = {
3558
3691
  typescript: "npm install -g typescript-language-server typescript",
@@ -3598,6 +3731,26 @@ var LSP_INSTALL_HINTS = {
3598
3731
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
3599
3732
  razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
3600
3733
  };
3734
+ var LSP_LOCAL_INSTALL_HINTS = {
3735
+ typescript: "bun add -d typescript-language-server typescript",
3736
+ vue: "bun add -d @vue/language-server",
3737
+ eslint: "bun add -d vscode-langservers-extracted",
3738
+ oxlint: "bun add -d oxlint",
3739
+ biome: "bun add -d @biomejs/biome",
3740
+ svelte: "bun add -d svelte-language-server",
3741
+ astro: "bun add -d @astrojs/language-server",
3742
+ bash: "bun add -d bash-language-server",
3743
+ "bash-ls": "bun add -d bash-language-server",
3744
+ "yaml-ls": "bun add -d yaml-language-server",
3745
+ php: "bun add -d intelephense",
3746
+ prisma: "bun add -d prisma",
3747
+ dockerfile: "bun add -d dockerfile-language-server-nodejs",
3748
+ pyright: "uv add --dev pyright",
3749
+ basedpyright: "uv add --dev basedpyright",
3750
+ ruff: "uv add --dev ruff",
3751
+ ty: "uv add --dev ty",
3752
+ "ruby-lsp": "bundle add ruby-lsp --group development"
3753
+ };
3601
3754
  var BUILTIN_SERVERS = {
3602
3755
  typescript: {
3603
3756
  command: ["typescript-language-server", "--stdio"],
@@ -3700,7 +3853,56 @@ var BUILTIN_SERVERS = {
3700
3853
  }
3701
3854
  };
3702
3855
 
3856
+ // ../lsp-core/src/lsp/server-install-state.ts
3857
+ import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3858
+ import { dirname as dirname6 } from "node:path";
3859
+ function getInstallDecisionsPath() {
3860
+ return lspRequestContext().installDecisionsPath;
3861
+ }
3862
+ function loadInstallDecisions() {
3863
+ const path = getInstallDecisionsPath();
3864
+ if (!existsSync7(path))
3865
+ return {};
3866
+ try {
3867
+ const parsed = JSON.parse(readFileSync3(path, "utf8"));
3868
+ return isInstallDecisions(parsed) ? parsed : {};
3869
+ } catch {
3870
+ return {};
3871
+ }
3872
+ }
3873
+ function loadInstallDecision(serverId) {
3874
+ return loadInstallDecisions()[serverId];
3875
+ }
3876
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3877
+ const decisions = loadInstallDecisions();
3878
+ decisions[serverId] = { decision, decidedAt };
3879
+ writeInstallDecisions(decisions);
3880
+ }
3881
+ function isInstallDecision(value) {
3882
+ return value === "declined" || value === "allowed";
3883
+ }
3884
+ function writeInstallDecisions(decisions) {
3885
+ const path = getInstallDecisionsPath();
3886
+ mkdirSync(dirname6(path), { recursive: true });
3887
+ const tmpPath = `${path}.tmp`;
3888
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3889
+ `, "utf8");
3890
+ renameSync2(tmpPath, path);
3891
+ }
3892
+ function isInstallDecisions(value) {
3893
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3894
+ }
3895
+ function isInstallDecisionRecord(value) {
3896
+ if (!isRecord5(value))
3897
+ return false;
3898
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3899
+ }
3900
+ function isRecord5(value) {
3901
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3902
+ }
3903
+
3703
3904
  // ../lsp-core/src/lsp/config-loader.ts
3905
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
3704
3906
  function getProjectConfigPaths() {
3705
3907
  return lspRequestContext().projectConfigPaths;
3706
3908
  }
@@ -3708,7 +3910,7 @@ function getUserConfigPath() {
3708
3910
  return lspRequestContext().userConfigPath;
3709
3911
  }
3710
3912
  function loadJsonFile(path) {
3711
- if (!existsSync7(path))
3913
+ if (!existsSync8(path))
3712
3914
  return null;
3713
3915
  try {
3714
3916
  const parsed = JSON.parse(readFileSync4(path, "utf-8"));
@@ -3896,54 +4098,155 @@ function getDisabledServerIds() {
3896
4098
  }
3897
4099
 
3898
4100
  // ../lsp-core/src/lsp/server-installation.ts
3899
- import { existsSync as existsSync8 } from "node:fs";
3900
- import { delimiter as delimiter3, join as join3 } from "node:path";
3901
- function isServerInstalled(command, _workingDirectory) {
3902
- if (command.length === 0)
3903
- return false;
3904
- const [cmd] = command;
3905
- if (!cmd)
3906
- return false;
3907
- if (cmd.includes("/") || cmd.includes("\\")) {
3908
- if (existsSync8(cmd))
3909
- return true;
4101
+ import { existsSync as existsSync9 } from "node:fs";
4102
+ import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
4103
+ var LOCAL_BIN_RULES = [
4104
+ {
4105
+ markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
4106
+ binDirs: [join4("node_modules", ".bin")]
4107
+ },
4108
+ {
4109
+ markers: [
4110
+ "pyproject.toml",
4111
+ "ty.toml",
4112
+ "requirements.txt",
4113
+ "setup.py",
4114
+ "setup.cfg",
4115
+ "Pipfile",
4116
+ "pyrightconfig.json",
4117
+ "ruff.toml",
4118
+ ".ruff.toml"
4119
+ ],
4120
+ binDirs: [
4121
+ join4(".venv", "bin"),
4122
+ join4(".venv", "Scripts"),
4123
+ join4("venv", "bin"),
4124
+ join4("venv", "Scripts"),
4125
+ join4(".env", "bin"),
4126
+ join4(".env", "Scripts")
4127
+ ]
4128
+ },
4129
+ {
4130
+ markers: ["Gemfile", "Gemfile.lock"],
4131
+ binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4132
+ },
4133
+ {
4134
+ markers: ["go.mod", "go.sum", "go.work"],
4135
+ binDirs: ["bin"]
3910
4136
  }
3911
- const isWindows = process.platform === "win32";
3912
- let exts = [""];
3913
- if (isWindows) {
3914
- const pathExt = process.env["PATHEXT"] ?? "";
3915
- if (pathExt) {
3916
- const systemExts = pathExt.split(";").filter(Boolean);
3917
- exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
3918
- } else {
3919
- exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4137
+ ];
4138
+ var resolutionCache = new Map;
4139
+ var probeCount = 0;
4140
+ function probe(path) {
4141
+ probeCount += 1;
4142
+ return existsSync9(path);
4143
+ }
4144
+ function executableSuffixes(platform, pathExt) {
4145
+ if (platform !== "win32")
4146
+ return [""];
4147
+ const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4148
+ const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4149
+ return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4150
+ }
4151
+ function probeWithSuffixes(directory, command, suffixes) {
4152
+ for (const suffix of suffixes) {
4153
+ const candidate = join4(directory, command + suffix);
4154
+ if (probe(candidate))
4155
+ return candidate;
4156
+ }
4157
+ return null;
4158
+ }
4159
+ function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4160
+ const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4161
+ let current = resolve7(workingDirectory);
4162
+ while (true) {
4163
+ for (const rule of LOCAL_BIN_RULES) {
4164
+ if (!rule.markers.some((marker) => probe(join4(current, marker))))
4165
+ continue;
4166
+ for (const binDir of rule.binDirs) {
4167
+ const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4168
+ if (found !== null)
4169
+ return found;
4170
+ }
3920
4171
  }
4172
+ if (probe(join4(current, ".git")))
4173
+ return null;
4174
+ if (boundary !== undefined && current === boundary)
4175
+ return null;
4176
+ const parent = dirname7(current);
4177
+ if (parent === current)
4178
+ return null;
4179
+ current = parent;
3921
4180
  }
3922
- let pathEnv = process.env["PATH"] ?? "";
3923
- if (isWindows && !pathEnv) {
4181
+ }
4182
+ function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4183
+ let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4184
+ if (platform === "win32" && !pathEnv) {
3924
4185
  pathEnv = process.env["Path"] ?? "";
3925
4186
  }
3926
- const paths = pathEnv.split(delimiter3);
3927
- for (const p of paths) {
3928
- for (const suffix of exts) {
3929
- if (existsSync8(join3(p, cmd + suffix))) {
3930
- return true;
3931
- }
3932
- }
4187
+ for (const entry of pathEnv.split(delimiter3)) {
4188
+ if (entry.length === 0)
4189
+ continue;
4190
+ const found = probeWithSuffixes(entry, command, suffixes);
4191
+ if (found !== null)
4192
+ return found;
3933
4193
  }
3934
- if (cmd === "node")
3935
- return true;
3936
- return false;
4194
+ return null;
4195
+ }
4196
+ function resolveServerBinary(command, workingDirectory, options = {}) {
4197
+ if (command.length === 0)
4198
+ return null;
4199
+ const [cmd] = command;
4200
+ if (cmd === undefined || cmd.length === 0)
4201
+ return null;
4202
+ const platform = options.platform ?? process.platform;
4203
+ const suffixes = executableSuffixes(platform, options.pathExt);
4204
+ if (cmd.includes("/") || cmd.includes("\\")) {
4205
+ const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4206
+ return probe(explicit) ? explicit : null;
4207
+ }
4208
+ const cacheKey = JSON.stringify([
4209
+ workingDirectory ?? "",
4210
+ cmd,
4211
+ platform,
4212
+ options.stopAt ?? "",
4213
+ options.pathExt ?? "",
4214
+ options.pathEnv ?? process.env["PATH"] ?? ""
4215
+ ]);
4216
+ const cached = resolutionCache.get(cacheKey);
4217
+ if (cached !== undefined)
4218
+ return cached;
4219
+ let resolved = null;
4220
+ if (workingDirectory !== undefined && workingDirectory.length > 0) {
4221
+ resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4222
+ }
4223
+ resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4224
+ if (resolved === null && cmd === "node")
4225
+ resolved = cmd;
4226
+ resolutionCache.set(cacheKey, resolved);
4227
+ return resolved;
4228
+ }
4229
+ function isServerInstalled(command, workingDirectory, options = {}) {
4230
+ if (command.length === 0)
4231
+ return false;
4232
+ return resolveServerBinary(command, workingDirectory, options) !== null;
3937
4233
  }
3938
4234
 
3939
4235
  // ../lsp-core/src/lsp/server-resolution.ts
4236
+ function withResolvedCommand(command, binaryPath) {
4237
+ return [binaryPath, ...command.slice(1)];
4238
+ }
3940
4239
  function findServerForExtension(ext) {
3941
4240
  const servers = getMergedServers();
4241
+ const workingDirectory = contextCwd();
3942
4242
  for (const server2 of servers) {
3943
- if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4243
+ if (!server2.extensions.includes(ext))
4244
+ continue;
4245
+ const binaryPath = resolveServerBinary(server2.command, workingDirectory);
4246
+ if (binaryPath !== null) {
3944
4247
  const resolvedServer = {
3945
4248
  id: server2.id,
3946
- command: server2.command,
4249
+ command: withResolvedCommand(server2.command, binaryPath),
3947
4250
  extensions: server2.extensions,
3948
4251
  priority: server2.priority
3949
4252
  };
@@ -3990,6 +4293,7 @@ function findServerForExtension(ext) {
3990
4293
  function getAllServers() {
3991
4294
  const servers = getMergedServers();
3992
4295
  const disabled = getDisabledServerIds();
4296
+ const workingDirectory = contextCwd();
3993
4297
  const result = [];
3994
4298
  const seen = new Set;
3995
4299
  for (const server2 of servers) {
@@ -3997,7 +4301,7 @@ function getAllServers() {
3997
4301
  continue;
3998
4302
  result.push({
3999
4303
  id: server2.id,
4000
- installed: isServerInstalled(server2.command),
4304
+ installed: isServerInstalled(server2.command, workingDirectory),
4001
4305
  extensions: server2.extensions,
4002
4306
  disabled: false,
4003
4307
  source: server2.source,
@@ -4011,7 +4315,7 @@ function getAllServers() {
4011
4315
  const builtin = BUILTIN_SERVERS[id];
4012
4316
  result.push({
4013
4317
  id,
4014
- installed: builtin ? isServerInstalled(builtin.command) : false,
4318
+ installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4015
4319
  extensions: builtin?.extensions ?? [],
4016
4320
  disabled: true,
4017
4321
  source: "disabled",
@@ -4022,7 +4326,6 @@ function getAllServers() {
4022
4326
  }
4023
4327
 
4024
4328
  // ../lsp-core/src/lsp/client-wrapper.ts
4025
- var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
4026
4329
  function isDirectoryPath(filePath) {
4027
4330
  try {
4028
4331
  return statSync3(filePath).isDirectory();
@@ -4031,32 +4334,90 @@ function isDirectoryPath(filePath) {
4031
4334
  }
4032
4335
  }
4033
4336
  function findWorkspaceRoot(filePath) {
4034
- const abs = resolvePathInsideContext(filePath);
4337
+ const cwd = contextCwd();
4338
+ const abs = resolveReadablePathInsideContext(filePath);
4035
4339
  let dir = abs;
4036
4340
  if (!isDirectoryPath(dir)) {
4037
- dir = dirname6(dir);
4038
- }
4039
- let prevDir = "";
4040
- while (dir !== prevDir) {
4041
- for (const marker of WORKSPACE_MARKERS) {
4042
- if (existsSync9(join4(dir, marker))) {
4043
- return dir;
4341
+ dir = dirname8(dir);
4342
+ }
4343
+ if (!isPathInside(cwd, abs))
4344
+ return findWorkspaceRootOutsideContext(dir);
4345
+ const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
4346
+ let nearestPackageRoot;
4347
+ while (isPathInside(cwd, dir)) {
4348
+ const canonicalDir = existingDirectoryInsideContext(dir, cwd);
4349
+ if (canonicalDir !== undefined) {
4350
+ if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
4351
+ return canonicalDir;
4352
+ }
4353
+ if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
4354
+ nearestPackageRoot = canonicalDir;
4044
4355
  }
4045
4356
  }
4046
- prevDir = dir;
4047
- dir = dirname6(dir);
4357
+ if (dir === cwd)
4358
+ break;
4359
+ dir = dirname8(dir);
4048
4360
  }
4049
- return dirname6(abs);
4361
+ return nearestPackageRoot ?? fallbackRoot;
4362
+ }
4363
+ function hasProjectWorkspaceMarker(directory) {
4364
+ return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
4365
+ }
4366
+ function resolveReadablePathInsideContext(filePath) {
4367
+ const cwd = contextCwd();
4368
+ const abs = resolve8(cwd, filePath);
4369
+ if (isPathInside(cwd, abs))
4370
+ return abs;
4371
+ const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
4372
+ if (rebased !== undefined)
4373
+ return rebased;
4374
+ return canonicalizeExistingOrNearestAncestor(abs);
4050
4375
  }
4051
4376
  function resolvePathInsideContext(filePath) {
4052
4377
  const cwd = contextCwd();
4053
- const abs = resolve7(cwd, filePath);
4378
+ const abs = resolveReadablePathInsideContext(filePath);
4054
4379
  const canonical = canonicalizeExistingOrNearestAncestor(abs);
4055
4380
  if (!isPathInside(cwd, canonical)) {
4056
4381
  throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
4057
4382
  }
4058
4383
  return canonical;
4059
4384
  }
4385
+ function rebaseThroughCanonicalAncestor(path, cwd) {
4386
+ let current = path;
4387
+ const suffix = [];
4388
+ while (true) {
4389
+ if (existsSync10(current)) {
4390
+ const canonical = realpathSync5(current);
4391
+ if (isPathInside(cwd, canonical))
4392
+ return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
4393
+ }
4394
+ const parent = dirname8(current);
4395
+ if (parent === current)
4396
+ return;
4397
+ suffix.unshift(basename3(current));
4398
+ current = parent;
4399
+ }
4400
+ }
4401
+ function existingDirectoryInsideContext(directory, cwd) {
4402
+ if (!existsSync10(directory))
4403
+ return;
4404
+ const canonical = realpathSync5(directory);
4405
+ if (!statSync3(canonical).isDirectory())
4406
+ return;
4407
+ return isPathInside(cwd, canonical) ? canonical : undefined;
4408
+ }
4409
+ function nearestExistingDirectoryInsideContext(directory, cwd) {
4410
+ let current = directory;
4411
+ while (isPathInside(cwd, current)) {
4412
+ const canonical = existingDirectoryInsideContext(current, cwd);
4413
+ if (canonical !== undefined)
4414
+ return canonical;
4415
+ if (current === cwd)
4416
+ return;
4417
+ current = dirname8(current);
4418
+ }
4419
+ return;
4420
+ }
4060
4421
  function formatServerLookupError(result) {
4061
4422
  if (result.status === "not_installed") {
4062
4423
  return formatNotInstalled(result);
@@ -4080,6 +4441,19 @@ function formatServerLookupError(result) {
4080
4441
  ].join(`
4081
4442
  `);
4082
4443
  }
4444
+ function formatInstallOptions(serverId, installHint) {
4445
+ const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
4446
+ if (localHint === undefined) {
4447
+ return ["To install, run:", ` ${installHint}`];
4448
+ }
4449
+ return [
4450
+ "To install in THIS repository (preferred — no global install needed):",
4451
+ ` ${localHint}`,
4452
+ "",
4453
+ "Or install it globally:",
4454
+ ` ${installHint}`
4455
+ ];
4456
+ }
4083
4457
  function formatNotInstalled(result) {
4084
4458
  const { server: server2, installHint } = result;
4085
4459
  const extensions = server2.extensions.join(", ");
@@ -4094,19 +4468,19 @@ function formatNotInstalled(result) {
4094
4468
  `Command not found: ${server2.command[0]}`,
4095
4469
  ""
4096
4470
  ];
4471
+ const installOptions = formatInstallOptions(server2.id, installHint);
4097
4472
  if (decision === "allowed") {
4098
4473
  return [
4099
4474
  ...header,
4100
4475
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4101
- ` ${installHint}`
4476
+ ...installOptions.slice(1)
4102
4477
  ].join(`
4103
4478
  `);
4104
4479
  }
4105
4480
  if (!context.capabilities.installDecisionTool) {
4106
4481
  return [
4107
4482
  ...header,
4108
- "To install, run:",
4109
- ` ${installHint}`,
4483
+ ...installOptions,
4110
4484
  "",
4111
4485
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4112
4486
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4115,8 +4489,7 @@ function formatNotInstalled(result) {
4115
4489
  }
4116
4490
  return [
4117
4491
  ...header,
4118
- "To install, run:",
4119
- ` ${installHint}`,
4492
+ ...installOptions,
4120
4493
  "",
4121
4494
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4122
4495
  "- If the user agrees: run the install command above, then retry this tool.",
@@ -4127,7 +4500,7 @@ function formatNotInstalled(result) {
4127
4500
  ].join(`
4128
4501
  `);
4129
4502
  }
4130
- var READ_ONLY_RETRY_TOOLS = new Set([
4503
+ var READ_ONLY_TOOLS = new Set([
4131
4504
  "diagnostics",
4132
4505
  "definition",
4133
4506
  "references",
@@ -4136,7 +4509,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
4136
4509
  "prepareRename"
4137
4510
  ]);
4138
4511
  async function withLspClient(filePath, fn, toolName, options = {}) {
4139
- const absPath = resolvePathInsideContext(filePath);
4512
+ const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
4140
4513
  if (isDirectoryPath(absPath)) {
4141
4514
  throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
4142
4515
  }
@@ -4151,9 +4524,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4151
4524
  const acquireAndCall = async (allowRetry) => {
4152
4525
  const client = await manager2.getClient(root, server2, options.signal);
4153
4526
  try {
4154
- return await fn(client, root);
4527
+ return await fn(client, root, absPath);
4155
4528
  } catch (err) {
4156
- if (allowRetry && READ_ONLY_RETRY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4529
+ if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
4157
4530
  manager2.invalidateClient(root, server2.id, client);
4158
4531
  return acquireAndCall(false);
4159
4532
  }
@@ -4171,8 +4544,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4171
4544
  }
4172
4545
 
4173
4546
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4174
- import { existsSync as existsSync10, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4175
- import { join as join5, resolve as resolve8 } from "node:path";
4547
+ import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4548
+ import { join as join6, resolve as resolve9 } from "node:path";
4176
4549
 
4177
4550
  // ../lsp-core/src/lsp/formatters.ts
4178
4551
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -4302,7 +4675,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
4302
4675
  for (const entry of entries) {
4303
4676
  if (files.length >= maxFiles)
4304
4677
  return;
4305
- const fullPath = join5(currentDir, entry);
4678
+ const fullPath = join6(currentDir, entry);
4306
4679
  let stat;
4307
4680
  try {
4308
4681
  stat = lstatSync4(fullPath);
@@ -4327,8 +4700,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4327
4700
  if (!extension.startsWith(".")) {
4328
4701
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4329
4702
  }
4330
- const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4331
- if (!existsSync10(absDir)) {
4703
+ const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
4704
+ if (!existsSync11(absDir)) {
4332
4705
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4333
4706
  }
4334
4707
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
@@ -4415,7 +4788,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4415
4788
 
4416
4789
  // ../lsp-core/src/lsp/infer-extension.ts
4417
4790
  import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
4418
- import { join as join6 } from "node:path";
4791
+ import { join as join7 } from "node:path";
4419
4792
  var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
4420
4793
  var MAX_SCAN_ENTRIES = 500;
4421
4794
  function inferExtensionFromDirectory(directory) {
@@ -4433,7 +4806,7 @@ function inferExtensionFromDirectory(directory) {
4433
4806
  for (const entry of entries) {
4434
4807
  if (scanned >= MAX_SCAN_ENTRIES)
4435
4808
  return;
4436
- const fullPath = join6(dir, entry);
4809
+ const fullPath = join7(dir, entry);
4437
4810
  let stat;
4438
4811
  try {
4439
4812
  stat = lstatSync5(fullPath);
@@ -4608,7 +4981,7 @@ async function executeLspDiagnostics(params, signal) {
4608
4981
  const filePath = requireString(params, "filePath");
4609
4982
  const severity = severityFilter(params);
4610
4983
  try {
4611
- const absPath = resolvePathInsideContext(filePath);
4984
+ const absPath = resolveReadablePathInsideContext(filePath);
4612
4985
  if (isDirectoryPath(absPath)) {
4613
4986
  const extension = inferExtensionFromDirectory(absPath);
4614
4987
  if (!extension) {
@@ -4637,7 +5010,7 @@ async function executeLspDiagnostics(params, signal) {
4637
5010
  };
4638
5011
  return text(output2.output, details2);
4639
5012
  }
4640
- const result = await withLspClient(filePath, async (client) => client.diagnostics(filePath, signal), "diagnostics", clientOptions(signal));
5013
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
4641
5014
  if (result.transientError) {
4642
5015
  const message = result.transientError.message;
4643
5016
  const details2 = {
@@ -4684,6 +5057,96 @@ async function executeLspDiagnostics(params, signal) {
4684
5057
  throw error;
4685
5058
  }
4686
5059
  }
5060
+ // ../lsp-core/src/lsp/format-document.ts
5061
+ import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
5062
+ var DEFAULT_FORMATTING_OPTIONS = {
5063
+ tabSize: 4,
5064
+ insertSpaces: false,
5065
+ trimTrailingWhitespace: true,
5066
+ insertFinalNewline: true,
5067
+ trimFinalNewlines: true
5068
+ };
5069
+ var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
5070
+ async function formatDocumentWithClient(client, filePath, options = {}) {
5071
+ const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
5072
+ if (edits === null)
5073
+ return { status: "unavailable", reason: "capability_not_advertised" };
5074
+ if (edits.length === 0)
5075
+ return UNCHANGED;
5076
+ const before = readFileSync5(filePath, "utf-8");
5077
+ const normalized = normalizeTextEdits(before, edits, 0);
5078
+ if (normalized.text === before)
5079
+ return UNCHANGED;
5080
+ writeAtomically(filePath, normalized.text);
5081
+ await client.openFile(filePath);
5082
+ return {
5083
+ status: "formatted",
5084
+ ...lineDelta(normalized.edits)
5085
+ };
5086
+ }
5087
+ function lineDelta(edits) {
5088
+ let linesAdded = 0;
5089
+ let linesRemoved = 0;
5090
+ for (const edit of edits) {
5091
+ linesRemoved += edit.range.end.line - edit.range.start.line + 1;
5092
+ linesAdded += edit.newText.split(`
5093
+ `).length;
5094
+ }
5095
+ return { linesAdded, linesRemoved };
5096
+ }
5097
+ function writeAtomically(filePath, content) {
5098
+ const tempPath = `${filePath}.omo-format.tmp`;
5099
+ writeFileSync3(tempPath, content, "utf-8");
5100
+ try {
5101
+ renameSync3(tempPath, filePath);
5102
+ } catch (error) {
5103
+ try {
5104
+ unlinkSync(tempPath);
5105
+ } catch {}
5106
+ throw error;
5107
+ }
5108
+ }
5109
+
5110
+ // ../lsp-core/src/tools/format.ts
5111
+ async function executeLspFormat(params, signal) {
5112
+ const filePath = requireString(params, "filePath");
5113
+ try {
5114
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
5115
+ return text(describeResult(filePath, result), formatDetails(filePath, result));
5116
+ } catch (error) {
5117
+ const missingDependency = missingDependencyResult(error, {
5118
+ filePath,
5119
+ status: "unavailable",
5120
+ reason: "server_unavailable",
5121
+ linesAdded: 0,
5122
+ linesRemoved: 0
5123
+ });
5124
+ if (missingDependency)
5125
+ return missingDependency;
5126
+ throw error;
5127
+ }
5128
+ }
5129
+ function formatDetails(filePath, result) {
5130
+ if (result.status === "unavailable") {
5131
+ return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5132
+ }
5133
+ return {
5134
+ filePath,
5135
+ status: result.status,
5136
+ linesAdded: result.linesAdded,
5137
+ linesRemoved: result.linesRemoved
5138
+ };
5139
+ }
5140
+ function describeResult(filePath, result) {
5141
+ if (result.status === "unavailable") {
5142
+ return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5143
+ }
5144
+ if (result.status === "unchanged") {
5145
+ return `Already formatted: ${filePath}`;
5146
+ }
5147
+ return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5148
+ }
5149
+
4687
5150
  // ../lsp-core/src/tools/install-decision.ts
4688
5151
  async function executeLspInstallDecision(params) {
4689
5152
  const serverId = requireString(params, "server_id");
@@ -4712,7 +5175,7 @@ async function executeLspGotoDefinition(params, signal) {
4712
5175
  const line = requireNumber(params, "line");
4713
5176
  const character = requireNumber(params, "character");
4714
5177
  try {
4715
- const result = await withLspClient(filePath, async (client) => client.definition(filePath, line, character, signal), "definition", clientOptions(signal));
5178
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
4716
5179
  const locations = !result ? [] : Array.isArray(result) ? result : [result];
4717
5180
  const details = { filePath, line, character, locations };
4718
5181
  if (locations.length === 0)
@@ -4737,7 +5200,7 @@ async function executeLspFindReferences(params, signal) {
4737
5200
  const character = requireNumber(params, "character");
4738
5201
  const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
4739
5202
  try {
4740
- const result = await withLspClient(filePath, async (client) => client.references(filePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
5203
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
4741
5204
  const references = Array.isArray(result) ? result : [];
4742
5205
  const total = references.length;
4743
5206
  const truncated = total > DEFAULT_MAX_REFERENCES;
@@ -4779,7 +5242,7 @@ async function executeLspPrepareRename(params, signal) {
4779
5242
  const line = requireNumber(params, "line");
4780
5243
  const character = requireNumber(params, "character");
4781
5244
  try {
4782
- const result = await withLspClient(filePath, async (client) => client.prepareRename(filePath, line, character, signal), "prepareRename", clientOptions(signal));
5245
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
4783
5246
  const details = { filePath, line, character, result };
4784
5247
  return text(formatPrepareRenameResult(result), details);
4785
5248
  } catch (error) {
@@ -4800,7 +5263,7 @@ async function executeLspRename(params, signal) {
4800
5263
  const character = requireNumber(params, "character");
4801
5264
  const newName = requireString(params, "newName");
4802
5265
  try {
4803
- const result = await withLspClient(filePath, async (client) => client.rename(filePath, line, character, newName, signal), "rename", clientOptions(signal));
5266
+ const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
4804
5267
  const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
4805
5268
  return text(formatApplyResult(result.apply), details, !result.apply.success);
4806
5269
  } catch (error) {
@@ -4880,7 +5343,7 @@ async function executeLspSymbols(params, signal) {
4880
5343
  const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
4881
5344
  return formatSymbolsResult(filePath, scope, symbols2, limit, query);
4882
5345
  }
4883
- const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(filePath, signal), "documentSymbols", clientOptions(signal));
5346
+ const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
4884
5347
  return formatSymbolsResult(filePath, scope, symbols, limit);
4885
5348
  } catch (error) {
4886
5349
  const query = optionalString(params, "query");
@@ -5016,6 +5479,16 @@ var LSP_MCP_TOOLS = [
5016
5479
  }, ["filePath", "line", "character", "newName"]),
5017
5480
  execute: executeLspRename
5018
5481
  },
5482
+ {
5483
+ name: "format",
5484
+ aliases: ["lsp_format"],
5485
+ title: "LSP Format",
5486
+ description: "Format a source file with its language server and write the returned edits to disk.",
5487
+ inputSchema: objectSchema({
5488
+ filePath: { type: "string", description: "Source file path to format." }
5489
+ }, ["filePath"]),
5490
+ execute: executeLspFormat
5491
+ },
5019
5492
  {
5020
5493
  name: "install_decision",
5021
5494
  aliases: ["lsp_install_decision"],